UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

93 lines (92 loc) 3.22 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.decode = void 0; const fromBase64_1 = require("@jsonjoy.com/base64/lib/fromBase64"); const clock_1 = require("../../clock"); const constants_1 = require("../../constants"); const PatchBuilder_1 = require("../../PatchBuilder"); const decodeId = (time) => typeof time === 'number' ? (0, clock_1.ts)(constants_1.SESSION.SERVER, time) : (0, clock_1.ts)(time[0], time[1]); /** * Decodes a JSON CRDT patch from a JavaScript POJO into a {@link Patch} instance. * * @param data A JavaScript POJO representing a JSON CRDT patch in "verbose" format. * @returns A decoded {@link Patch} instance. */ const decode = (data) => { const { id, ops } = data; const clock = typeof id === 'number' ? new clock_1.ServerClockVector(constants_1.SESSION.SERVER, id) : new clock_1.ClockVector(id[0], id[1]); const builder = new PatchBuilder_1.PatchBuilder(clock); for (const op of ops) { switch (op.op) { case 'new_con': { if (op.timestamp) { builder.const(decodeId(op.value)); } else { builder.const(op.value); } break; } case 'new_val': { builder.val(); break; } case 'new_obj': { builder.obj(); break; } case 'new_vec': { builder.vec(); break; } case 'new_str': { builder.str(); break; } case 'new_bin': { builder.bin(); break; } case 'new_arr': { builder.arr(); break; } case 'ins_val': { builder.setVal(decodeId(op.obj), decodeId(op.value)); break; } case 'ins_obj': { builder.insObj(decodeId(op.obj), op.value.map(([key, id]) => [key, decodeId(id)])); break; } case 'ins_vec': { builder.insVec(decodeId(op.obj), op.value.map(([key, id]) => [key, decodeId(id)])); break; } case 'ins_str': { builder.insStr(decodeId(op.obj), decodeId(op.after || op.obj), op.value); break; } case 'ins_bin': { builder.insBin(decodeId(op.obj), decodeId(op.after || op.obj), (0, fromBase64_1.fromBase64)(op.value)); break; } case 'ins_arr': { builder.insArr(decodeId(op.obj), decodeId(op.after || op.obj), op.values.map(decodeId)); break; } case 'del': { builder.del(decodeId(op.obj), op.what.map((spans) => (0, clock_1.tss)(...spans))); break; } case 'nop': { builder.nop(op.len || 1); break; } } } const patch = builder.patch; patch.meta = data.meta; return patch; }; exports.decode = decode;