UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

129 lines (128 loc) 4.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.decode = void 0; const constants_1 = require("../../constants"); const fromBase64_1 = require("@jsonjoy.com/base64/lib/fromBase64"); const clock_1 = require("../../clock"); const PatchBuilder_1 = require("../../PatchBuilder"); const constants_2 = require("../../constants"); const timestamp = (sid, x) => { return Array.isArray(x) ? new clock_1.Timestamp(x[0], x[1]) : new clock_1.Timestamp(sid, x); }; const timespan = (sid, span) => { return span.length === 3 ? new clock_1.Timespan(span[0], span[1], span[2]) : new clock_1.Timespan(sid, span[0], span[1]); }; /** * Decodes a JSON CRDT Patch from a "compact" POJO into a {@link Patch} instance. * * @param data A JavaScript POJO array in the compact codec format. * @returns A decoded patch. */ const decode = (data) => { const header = data[0]; const x = header[0]; const clock = Array.isArray(x) ? new clock_1.ClockVector(x[0], x[1]) : new clock_1.ServerClockVector(constants_2.SESSION.SERVER, x); const sid = clock.sid; const time = clock.time; const builder = new PatchBuilder_1.PatchBuilder(clock); const length = data.length; for (let i = 1; i < length; i++) { const op = data[i]; switch (op[0]) { case constants_1.JsonCrdtPatchOpcode.new_con: { const [, value, isTimestamp] = op; builder.const(isTimestamp ? timestamp(sid, value) : value); break; } case constants_1.JsonCrdtPatchOpcode.new_val: { builder.val(); break; } case constants_1.JsonCrdtPatchOpcode.new_obj: { builder.obj(); break; } case constants_1.JsonCrdtPatchOpcode.new_vec: { builder.vec(); break; } case constants_1.JsonCrdtPatchOpcode.new_str: { builder.str(); break; } case constants_1.JsonCrdtPatchOpcode.new_bin: { builder.bin(); break; } case constants_1.JsonCrdtPatchOpcode.new_arr: { builder.arr(); break; } case constants_1.JsonCrdtPatchOpcode.ins_val: { builder.setVal(timestamp(sid, op[1]), timestamp(sid, op[2])); break; } case constants_1.JsonCrdtPatchOpcode.ins_obj: { const obj = timestamp(sid, op[1]); const tuples = []; const value = op[2]; const length = value.length; for (let j = 0; j < length; j++) { const [key, x] = value[j]; tuples.push([key, timestamp(sid, x)]); } builder.insObj(obj, tuples); break; } case constants_1.JsonCrdtPatchOpcode.ins_vec: { const obj = timestamp(sid, op[1]); const tuples = []; const value = op[2]; const length = value.length; for (let j = 0; j < length; j++) { const [key, x] = value[j]; tuples.push([key, timestamp(sid, x)]); } builder.insVec(obj, tuples); break; } case constants_1.JsonCrdtPatchOpcode.ins_str: { builder.insStr(timestamp(sid, op[1]), timestamp(sid, op[2]), op[3]); break; } case constants_1.JsonCrdtPatchOpcode.ins_bin: { builder.insBin(timestamp(sid, op[1]), timestamp(sid, op[2]), (0, fromBase64_1.fromBase64)(op[3])); break; } case constants_1.JsonCrdtPatchOpcode.ins_arr: { const obj = timestamp(sid, op[1]); const ref = timestamp(sid, op[2]); const value = op[3]; const elements = []; const length = value.length; for (let j = 0; j < length; j++) elements.push(timestamp(sid, value[j])); builder.insArr(obj, ref, elements); break; } case constants_1.JsonCrdtPatchOpcode.del: { const obj = timestamp(sid, op[1]); const spans = op[2]; const what = []; const length = spans.length; for (let i = 0; i < length; i++) what.push(timespan(sid, spans[i])); builder.del(obj, what); break; } case constants_1.JsonCrdtPatchOpcode.nop: { builder.nop(op[1] || 1); break; } } } const patch = builder.patch; patch.meta = header[1]; return patch; }; exports.decode = decode;