Skip to content

Commit 0f95026

Browse files
committed
refactor(json-crdt-extensions): 💡 improve .leftChar() and .rightChar() methods
1 parent cefd3c5 commit 0f95026

File tree

2 files changed

+41
-42
lines changed

2 files changed

+41
-42
lines changed

‎src/json-crdt-extensions/peritext/point/Point.ts‎

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -240,55 +240,33 @@ export class Point implements Pick<Stateful, 'refresh'>, Printable {
240240
public leftChar(): ChunkSlice | undefined {
241241
const str = this.txt.str;
242242
if (this.isAbsEnd()) {
243-
let chunk = str.last();
244-
while (chunk && chunk.del) chunk = str.prev(chunk);
245-
return chunk ? new ChunkSlice(chunk, chunk.span - 1, 1) : undefined;
243+
const res = str.findChunk(str.length() - 1);
244+
if (!res) return;
245+
return new ChunkSlice(res[0], res[1], 1);
246246
}
247-
let chunk = this.chunk();
248-
if (!chunk) return;
249-
if (chunk.del) {
250-
const prevId = this.prevId();
251-
if (!prevId) return;
252-
const tmp = new Point(this.txt, prevId, Anchor.After);
253-
return tmp.leftChar();
254-
}
255-
if (this.anchor === Anchor.After) {
256-
const off = this.id.time - chunk.id.time;
257-
return new ChunkSlice(chunk, off, 1);
258-
}
259-
const off = this.id.time - chunk.id.time - 1;
260-
if (off >= 0) return new ChunkSlice(chunk, off, 1);
261-
chunk = str.prev(chunk);
262-
while (chunk && chunk.del) chunk = str.prev(chunk);
263-
if (!chunk) return;
264-
return new ChunkSlice(chunk, chunk.span - 1, 1);
247+
const tmp = this.clone();
248+
tmp.refAfter();
249+
if (tmp.isAbsStart()) return;
250+
const chunk = tmp.chunk();
251+
if (!chunk || chunk.del) return;
252+
const off = tmp.id.time - chunk.id.time;
253+
return new ChunkSlice(chunk, off, 1);
265254
}
266255

267256
public rightChar(): ChunkSlice | undefined {
268257
const str = this.txt.str;
269258
if (this.isAbsStart()) {
270-
let chunk = str.first();
271-
while (chunk && chunk.del) chunk = str.next(chunk);
272-
return chunk ? new ChunkSlice(chunk, 0, 1) : undefined;
259+
const res = str.findChunk(0);
260+
if (!res) return;
261+
return new ChunkSlice(res[0], res[1], 1);
273262
}
274-
let chunk = this.chunk();
275-
if (!chunk) return;
276-
if (chunk.del) {
277-
const nextId = this.nextId();
278-
if (!nextId) return;
279-
const tmp = new Point(this.txt, nextId, Anchor.Before);
280-
return tmp.rightChar();
281-
}
282-
if (this.anchor === Anchor.Before) {
283-
const off = this.id.time - chunk.id.time;
284-
return new ChunkSlice(chunk, off, 1);
285-
}
286-
const off = this.id.time - chunk.id.time + 1;
287-
if (off < chunk.span) return new ChunkSlice(chunk, off, 1);
288-
chunk = str.next(chunk);
289-
while (chunk && chunk.del) chunk = str.next(chunk);
290-
if (!chunk) return;
291-
return new ChunkSlice(chunk, 0, 1);
263+
const tmp = this.clone();
264+
tmp.refBefore();
265+
if (tmp.isAbsEnd()) return;
266+
const chunk = tmp.chunk();
267+
if (!chunk || chunk.del) return;
268+
const off = tmp.id.time - chunk.id.time;
269+
return new ChunkSlice(chunk, off, 1);
292270
}
293271

294272
/**

‎src/json-crdt-extensions/peritext/point/__tests__/Point.spec.ts‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,27 @@ describe('.compareSpatial()', () => {
224224
});
225225
});
226226

227+
describe('.chunk()', () => {
228+
test('returns correct chunk when chunk is split', () => {
229+
const {peritext} = setup();
230+
const p1 = peritext.pointAt(0, Anchor.Before);
231+
const p2 = peritext.pointAt(1, Anchor.Before);
232+
const p3 = peritext.pointAt(2, Anchor.Before);
233+
expect(p1.rightChar()!.view()).toBe('a');
234+
expect(p2.rightChar()!.view()).toBe('b');
235+
expect(p3.rightChar()!.view()).toBe('c');
236+
expect(p1.chunk()!.id.time).toBe(p1.id.time);
237+
expect(p2.chunk()!.id.time + 1).toBe(p2.id.time);
238+
expect(p3.chunk()!.id.time + 2).toBe(p3.id.time);
239+
peritext.strApi().del(1, 1);
240+
expect(p1.rightChar()!.view()).toBe('a');
241+
expect(p3.rightChar()!.view()).toBe('c');
242+
expect(p1.chunk()!.id.time).toBe(p1.id.time);
243+
expect(p2.chunk()!.id.time).toBe(p2.id.time);
244+
expect(p3.chunk()!.id.time).toBe(p3.id.time);
245+
});
246+
});
247+
227248
const setupWithText = () => {
228249
const model = Model.withLogicalClock(123456);
229250
model.api.root({

0 commit comments

Comments
 (0)