Skip to content

Commit

Permalink
feat(json-crdt): 🎸 add support for "bin" type in sidecar encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Nov 7, 2023
1 parent c85255a commit eaaf05e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 16 deletions.
21 changes: 19 additions & 2 deletions src/json-crdt/codec/sidecar/binary/Decoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ export class Decoder {
return this.cVec(view, id, length);
case CRDT_MAJOR.STR:
return this.cStr(view, id, length);
// case CRDT_MAJOR.BIN:
// return this.cBin(id, length);
case CRDT_MAJOR.BIN:
return this.cBin(view, id, length);
// case CRDT_MAJOR.ARR:
// return this.cArr(id, length);
}
Expand Down Expand Up @@ -155,6 +155,23 @@ export class Decoder {
return node;
}

protected cBin(view: unknown, id: ITimestampStruct, length: number): BinNode {
if (!(view instanceof Uint8Array)) throw new Error('INVALID_BIN');
const node = new BinNode(id);
const reader = this.decoder.reader;
let offset = 0;
node.ingest(length, (): BinChunk => {
const id = this.ts();
const span = reader.vu39();
if (!span) return new BinChunk(id, length, undefined);
const slice = view.slice(offset, offset + span);
offset += span;
return new BinChunk(id, slice.length, slice);
});
this.doc.index.set(id, node);
return node;
}

// protected cBin(id: ITimestampStruct, length: number): BinNode {
// const node = new BinNode(id);
// if (length) node.ingest(length, this.cBinChunk);
Expand Down
23 changes: 9 additions & 14 deletions src/json-crdt/codec/sidecar/binary/Encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,20 +140,15 @@ export class Encoder {
}

protected cBin(node: nodes.BinNode): void {
// const ts = this.ts;
// const writer = this.writer;
// ts(node.id);
// this.writeTL(CRDT_MAJOR_OVERLAY.BIN, node.count);
// for (let chunk = node.first(); chunk; chunk = node.next(chunk)) {
// // TODO: Encode ID first
// // TODO: Use b1vu56
// const length = chunk.span;
// const deleted = chunk.del;
// writer.b1vu28(chunk.del, length);
// ts(chunk.id);
// if (deleted) continue;
// // TODO: REFERENCE
// }
const ts = this.ts;
ts(node.id);
this.writeTL(CRDT_MAJOR_OVERLAY.BIN, node.count);
this.viewEncoder.writeBin(node.view());
const writer = this.metaEncoder.writer;
for (let chunk = node.first(); chunk; chunk = node.next(chunk)) {
ts(chunk.id);
writer.vu39(chunk.span);
}
}

protected cArr(node: nodes.ArrNode): void {
Expand Down
17 changes: 17 additions & 0 deletions src/json-crdt/codec/sidecar/binary/__tests__/Encoder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,20 @@ test('str', () => {
expect(decoded.clock.sid).toBe(model.clock.sid);
expect(decoded.clock.time).toBe(model.clock.time);
});

test('bin', () => {
const model = Model.withLogicalClock();
const encoder = new Encoder();
const decoder = new Decoder();
const cborDecoder = new CborDecoder();
model.api.root(new Uint8Array([1, 2, 3]));
model.api.bin([]).ins(3, new Uint8Array([4, 5, 6]));
const [view, meta] = encoder.encode(model);
const viewDecoded = cborDecoder.decode(view);
const decoded = decoder.decode(viewDecoded, meta);
expect(model.view()).toEqual(decoded.view());
expect(model.view()).toEqual(viewDecoded);
expect(decoded.clock.sid).toBe(model.clock.sid);
expect(decoded.clock.time).toBe(model.clock.time);
});

0 comments on commit eaaf05e

Please sign in to comment.