UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

121 lines (120 loc) 4.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.encode = void 0; const tslib_1 = require("tslib"); const operations = tslib_1.__importStar(require("../../operations")); const constants_1 = require("../../constants"); const toBase64_1 = require("@jsonjoy.com/base64/lib/toBase64"); const clock_1 = require("../../clock"); const encodeTimestamp = (ts) => ts.sid === constants_1.SESSION.SERVER ? ts.time : [ts.sid, ts.time]; /** * Encodes a patch into a JSON CRDT Patch "verbose" format. * * @param patch The {@link Patch} to encode. * @returns A JavaScript POJO object in JSON CRDT Patch "verbose" format. */ const encode = (patch) => { const id = patch.getId(); if (!id) throw new Error('PATCH_EMPTY'); const ops = []; const res = { id: [id.sid, id.time], ops, }; if (patch.meta !== undefined) res.meta = patch.meta; for (const op of patch.ops) { if (op instanceof operations.NewConOp) { const val = op.val; if (val instanceof clock_1.Timestamp) { ops.push({ op: 'new_con', timestamp: true, value: encodeTimestamp(val) }); } else { ops.push({ op: 'new_con', value: val }); } } else if (op instanceof operations.NewObjOp) { ops.push({ op: 'new_obj' }); } else if (op instanceof operations.NewVecOp) { ops.push({ op: 'new_vec' }); } else if (op instanceof operations.NewArrOp) { ops.push({ op: 'new_arr' }); } else if (op instanceof operations.NewStrOp) { ops.push({ op: 'new_str' }); } else if (op instanceof operations.NewBinOp) { ops.push({ op: 'new_bin' }); } else if (op instanceof operations.NewValOp) { ops.push({ op: 'new_val' }); } else if (op instanceof operations.InsObjOp) { ops.push({ op: 'ins_obj', obj: encodeTimestamp(op.obj), value: op.data.map(([key, value]) => [key, encodeTimestamp(value)]), }); } else if (op instanceof operations.InsVecOp) { ops.push({ op: 'ins_vec', obj: encodeTimestamp(op.obj), value: op.data.map(([key, value]) => [key, encodeTimestamp(value)]), }); } else if (op instanceof operations.InsValOp) { ops.push({ op: 'ins_val', obj: encodeTimestamp(op.obj), value: encodeTimestamp(op.val), }); } else if (op instanceof operations.InsStrOp) { ops.push({ op: 'ins_str', obj: encodeTimestamp(op.obj), after: encodeTimestamp(op.ref), value: op.data, }); } else if (op instanceof operations.InsBinOp) { ops.push({ op: 'ins_bin', obj: encodeTimestamp(op.obj), after: encodeTimestamp(op.ref), value: (0, toBase64_1.toBase64)(op.data), }); } else if (op instanceof operations.InsArrOp) { ops.push({ op: 'ins_arr', obj: encodeTimestamp(op.obj), after: encodeTimestamp(op.ref), values: op.data.map(encodeTimestamp), }); } else if (op instanceof operations.DelOp) { const encoded = { op: 'del', obj: encodeTimestamp(op.obj), what: op.what.map((span) => [span.sid, span.time, span.span]), }; ops.push(encoded); } else if (op instanceof operations.NopOp) { const encoded = { op: 'nop', }; const length = op.len; if (length > 1) encoded.len = length; ops.push(encoded); } } return res; }; exports.encode = encode;