json-joy
Version:
Collection of libraries for building collaborative editing apps.
93 lines (92 loc) • 3.22 kB
JavaScript
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;
;