UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

185 lines 6.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Decoder = void 0; const CrdtReader_1 = require("../../util/binary/CrdtReader"); const clock_1 = require("../../clock"); const PatchBuilder_1 = require("../../PatchBuilder"); const CborDecoder_1 = require("@jsonjoy.com/json-pack/lib/cbor/CborDecoder"); /** * JSON CRDT Patch "binary" codec decoder. */ class Decoder extends CborDecoder_1.CborDecoder { /** * Creates a new JSON CRDT patch decoder. * * @param reader An optional custom implementation of a CRDT decoder. */ constructor(reader = new CrdtReader_1.CrdtReader()) { super(reader); } /** * Decodes a JSON CRDT patch from a binary blob. * * @param data Binary data to decode. * @returns A JSON CRDT patch. */ decode(data) { this.reader.reset(data); return this.readPatch(); } readPatch() { const reader = this.reader; const sid = reader.vu57(); const time = reader.vu57(); const isServerClock = sid === 1 /* SESSION.SERVER */; const clock = isServerClock ? new clock_1.ServerClockVector(1 /* SESSION.SERVER */, time) : new clock_1.ClockVector(sid, time); this.patchSid = clock.sid; const builder = (this.builder = new PatchBuilder_1.PatchBuilder(clock)); const map = this.val(); if (Array.isArray(map)) builder.patch.meta = map[0]; this.decodeOperations(); return builder.patch; } decodeId() { const reader = this.reader; const [isSessionDifferent, x] = reader.b1vu56(); return isSessionDifferent ? new clock_1.Timestamp(reader.vu57(), x) : new clock_1.Timestamp(this.patchSid, x); } decodeTss() { const id = this.decodeId(); const span = this.reader.vu57(); return (0, clock_1.interval)(id, 0, span); } decodeOperations() { const reader = this.reader; const length = reader.vu57(); for (let i = 0; i < length; i++) this.decodeOperation(); } decodeOperation() { const builder = this.builder; const reader = this.reader; const octet = reader.u8(); const opcode = octet >> 3; switch (opcode) { case 0 /* JsonCrdtPatchOpcode.new_con */: { const length = octet & 0b111; builder.con(!length ? this.val() : this.decodeId()); break; } case 1 /* JsonCrdtPatchOpcode.new_val */: { builder.val(); break; } case 2 /* JsonCrdtPatchOpcode.new_obj */: { builder.obj(); break; } case 3 /* JsonCrdtPatchOpcode.new_vec */: { builder.vec(); break; } case 4 /* JsonCrdtPatchOpcode.new_str */: { builder.str(); break; } case 5 /* JsonCrdtPatchOpcode.new_bin */: { builder.bin(); break; } case 6 /* JsonCrdtPatchOpcode.new_arr */: { builder.arr(); break; } case 9 /* JsonCrdtPatchOpcode.ins_val */: { const obj = this.decodeId(); const val = this.decodeId(); builder.setVal(obj, val); break; } case 10 /* JsonCrdtPatchOpcode.ins_obj */: { const length = octet & 0b111 || reader.vu57(); const obj = this.decodeId(); const tuples = []; for (let i = 0; i < length; i++) { const key = this.val(); if (typeof key !== 'string') continue; const value = this.decodeId(); tuples.push([key, value]); } builder.insObj(obj, tuples); break; } case 11 /* JsonCrdtPatchOpcode.ins_vec */: { const length = octet & 0b111 || reader.vu57(); const obj = this.decodeId(); const tuples = []; for (let i = 0; i < length; i++) { const index = this.val(); if (typeof index !== 'number') continue; const value = this.decodeId(); tuples.push([index, value]); } builder.insVec(obj, tuples); break; } case 12 /* JsonCrdtPatchOpcode.ins_str */: { const length = octet & 0b111 || reader.vu57(); const obj = this.decodeId(); const after = this.decodeId(); const str = reader.utf8(length); builder.insStr(obj, after, str); break; } case 13 /* JsonCrdtPatchOpcode.ins_bin */: { const length = octet & 0b111 || reader.vu57(); const obj = this.decodeId(); const after = this.decodeId(); const buf = reader.buf(length); if (!(buf instanceof Uint8Array)) return; builder.insBin(obj, after, buf); break; } case 14 /* JsonCrdtPatchOpcode.ins_arr */: { const length = octet & 0b111 || reader.vu57(); const obj = this.decodeId(); const after = this.decodeId(); const elements = []; for (let i = 0; i < length; i++) elements.push(this.decodeId()); builder.insArr(obj, after, elements); break; } case 15 /* JsonCrdtPatchOpcode.upd_arr */: { const obj = this.decodeId(); const ref = this.decodeId(); const val = this.decodeId(); builder.updArr(obj, ref, val); break; } case 16 /* JsonCrdtPatchOpcode.del */: { const length = octet & 0b111 || reader.vu57(); const obj = this.decodeId(); const what = []; for (let i = 0; i < length; i++) what.push(this.decodeTss()); builder.del(obj, what); break; } case 17 /* JsonCrdtPatchOpcode.nop */: { const length = octet & 0b111 || reader.vu57(); builder.nop(length); break; } default: { throw new Error('UNKNOWN_OP'); } } } } exports.Decoder = Decoder; //# sourceMappingURL=Decoder.js.map