Skip to content

Commit 5905bfd

Browse files
committed
feat(json-crdt): 🎸 implement .prevId() utility
1 parent 80603ae commit 5905bfd

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

src/json-crdt/nodes/rga/AbstractRga.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ export abstract class AbstractRga<T> {
755755
this.count--;
756756
}
757757

758-
public findById(after: ITimestampStruct): undefined | Chunk<T> {
758+
public findById(after: ITimestampStruct): Chunk<T> | undefined {
759759
const afterSid = after.sid;
760760
const afterTime = after.time;
761761
let curr: Chunk<T> | undefined = this.ids;
@@ -793,6 +793,18 @@ export abstract class AbstractRga<T> {
793793
return chunk;
794794
}
795795

796+
public prevId(id: ITimestampStruct): ITimestampStruct | undefined {
797+
let chunk = this.findById(id);
798+
if (!chunk) return;
799+
const time = id.time;
800+
if (chunk.id.time < time) return new Timestamp(id.sid, time - 1);
801+
chunk = prev(chunk);
802+
if (!chunk) return;
803+
const prevId = chunk.id;
804+
const span = chunk.span;
805+
return span > 1 ? new Timestamp(prevId.sid, prevId.time + chunk.span - 1) : prevId;
806+
}
807+
796808
public spanView(span: ITimespanStruct): T[] {
797809
const view: T[] = [];
798810
let remaining = span.span;

src/json-crdt/nodes/str/__tests__/StrNode.spec.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,46 @@ describe('StrNode', () => {
13541354
});
13551355
});
13561356

1357+
describe('.prevId()', () => {
1358+
test('can iterate through IDs in reverse', () => {
1359+
const type = new StrNode(ts(1, 1));
1360+
type.ins(ts(1, 1), ts(1, 2), '123456789');
1361+
type.ins(ts(1, 4), ts(2, 5), 'xxx');
1362+
type.ins(ts(1, 7), ts(3, 5), 'yyy');
1363+
let id = ts(1, 10);
1364+
id = type.prevId(id)!;
1365+
expect(id).toStrictEqual(ts(1, 9));
1366+
id = type.prevId(id)!;
1367+
expect(id).toStrictEqual(ts(1, 8));
1368+
id = type.prevId(id)!;
1369+
expect(id).toStrictEqual(ts(3, 7));
1370+
id = type.prevId(id)!;
1371+
expect(id).toStrictEqual(ts(3, 6));
1372+
id = type.prevId(id)!;
1373+
expect(id).toStrictEqual(ts(3, 5));
1374+
id = type.prevId(id)!;
1375+
expect(id).toStrictEqual(ts(1, 7));
1376+
id = type.prevId(id)!;
1377+
expect(id).toStrictEqual(ts(1, 6));
1378+
id = type.prevId(id)!;
1379+
expect(id).toStrictEqual(ts(1, 5));
1380+
id = type.prevId(id)!;
1381+
expect(id).toStrictEqual(ts(2, 7));
1382+
id = type.prevId(id)!;
1383+
expect(id).toStrictEqual(ts(2, 6));
1384+
id = type.prevId(id)!;
1385+
expect(id).toStrictEqual(ts(2, 5));
1386+
id = type.prevId(id)!;
1387+
expect(id).toStrictEqual(ts(1, 4));
1388+
id = type.prevId(id)!;
1389+
expect(id).toStrictEqual(ts(1, 3));
1390+
id = type.prevId(id)!;
1391+
expect(id).toStrictEqual(ts(1, 2));
1392+
id = type.prevId(id)!;
1393+
expect(id).toBe(undefined);
1394+
});
1395+
});
1396+
13571397
describe('export / import', () => {
13581398
type Entry = [ITimestampStruct, number, string];
13591399
const exp = (type: StrNode) => {

0 commit comments

Comments
 (0)