Skip to content

Commit 28359d3

Browse files
committed
feat: 🎸 add .findMax() utility
1 parent c6a0ab6 commit 28359d3

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

src/json-crdt/log/Log.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {AvlMap} from 'sonic-forest/lib/avl/AvlMap';
2-
import {first, next} from 'sonic-forest/lib/util';
2+
import {first, next, prev} from 'sonic-forest/lib/util';
33
import {printTree} from 'tree-dump/lib/printTree';
44
import {listToUint8} from '@jsonjoy.com/util/lib/buffers/concat';
55
import {Model} from '../model';
@@ -160,6 +160,22 @@ export class Log<N extends JsonNode = JsonNode<any>, Metadata extends Record<str
160160
return clone;
161161
}
162162

163+
/**
164+
* Finds the latest patch for a given session ID.
165+
*
166+
* @param sid Session ID to find the latest patch for.
167+
* @return The latest patch for the given session ID, or `undefined` if no
168+
* such patch exists.
169+
*/
170+
public findMax(sid: number): Patch | undefined {
171+
let curr = this.patches.max;
172+
while (curr) {
173+
if (curr.k.sid === sid) return curr.v;
174+
curr = prev(curr);
175+
}
176+
return;
177+
}
178+
163179
/**
164180
* Advance the start of the log to a specified timestamp, excluding the patch
165181
* at the given timestamp. This method removes all patches from the log that

src/json-crdt/log/__tests__/Log.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,30 @@ describe('.advanceTo()', () => {
119119
});
120120
});
121121

122+
describe('.findMax()', () => {
123+
test('can advance the log from start', () => {
124+
const model = Model.create();
125+
const sid0 = model.clock.sid;
126+
const sid1 = Model.sid();
127+
model.api.set({foo: 'bar'});
128+
const log = Log.fromNewModel(model);
129+
log.end.api.obj([]).set({x: 1});
130+
const patch1 = log.end.api.flush();
131+
log.end.setSid(sid1);
132+
log.end.api.obj([]).set({y: 2});
133+
const patch2 = log.end.api.flush();
134+
log.end.setSid(sid0);
135+
log.end.api.obj([]).set({foo: 'baz'});
136+
const patch3 = log.end.api.flush();
137+
const found0 = log.findMax(sid0);
138+
const found1 = log.findMax(sid1);
139+
const found2 = log.findMax(12345);
140+
expect(found0).toBe(patch3);
141+
expect(found1).toBe(patch2);
142+
expect(found2).toBe(void 0);
143+
});
144+
});
145+
122146
describe('.undo()', () => {
123147
describe('RGA', () => {
124148
describe('str', () => {

0 commit comments

Comments
 (0)