UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

146 lines 5.19 kB
import * as operations from '../../operations'; import { Timestamp } from '../../clock'; import { toBase64 } from '@jsonjoy.com/base64/lib/toBase64'; const timestamp = (sid, ts) => { const tsSessionId = ts.sid; return tsSessionId === sid ? ts.time : [tsSessionId, ts.time]; }; const timespan = (sid, span) => { const ts = timestamp(sid, span); if (Array.isArray(ts)) { ts.push(span.span); return ts; } return [ts, span.span]; }; /** * Encodes a patch into a compact binary format into a JavaScript array. * * @param patch The patch to encode. * @returns The encoded patch as a JavaScript POJO. */ export const encode = (patch) => { const id = patch.getId(); if (!id) throw new Error('PATCH_EMPTY'); const sid = id.sid; const time = id.time; const header = sid === 1 /* SESSION.SERVER */ ? [time] : [[sid, time]]; const meta = patch.meta; if (meta !== undefined) header.push(meta); const res = [header]; for (const op of patch.ops) { if (op instanceof operations.NewConOp) { const val = op.val; if (val instanceof Timestamp) { res.push([0 /* JsonCrdtPatchOpcode.new_con */, timestamp(sid, val), true]); } else if (val === undefined) { res.push([0 /* JsonCrdtPatchOpcode.new_con */]); } else { res.push([0 /* JsonCrdtPatchOpcode.new_con */, val]); } } else if (op instanceof operations.NewValOp) { res.push([1 /* JsonCrdtPatchOpcode.new_val */]); } else if (op instanceof operations.NewObjOp) { res.push([2 /* JsonCrdtPatchOpcode.new_obj */]); } else if (op instanceof operations.NewVecOp) { res.push([3 /* JsonCrdtPatchOpcode.new_vec */]); } else if (op instanceof operations.NewStrOp) { res.push([4 /* JsonCrdtPatchOpcode.new_str */]); } else if (op instanceof operations.NewBinOp) { res.push([5 /* JsonCrdtPatchOpcode.new_bin */]); } else if (op instanceof operations.NewArrOp) { res.push([6 /* JsonCrdtPatchOpcode.new_arr */]); } else if (op instanceof operations.InsValOp) { res.push([9 /* JsonCrdtPatchOpcode.ins_val */, timestamp(sid, op.obj), timestamp(sid, op.val)]); } else if (op instanceof operations.InsObjOp) { const tuples = []; for (const [key, value] of op.data) tuples.push([key, timestamp(sid, value)]); const operation = [ 10 /* JsonCrdtPatchOpcode.ins_obj */, timestamp(sid, op.obj), tuples, ]; res.push(operation); } else if (op instanceof operations.InsVecOp) { const tuples = []; for (const [key, value] of op.data) tuples.push([key, timestamp(sid, value)]); const operation = [ 11 /* JsonCrdtPatchOpcode.ins_vec */, timestamp(sid, op.obj), tuples, ]; res.push(operation); } else if (op instanceof operations.InsStrOp) { const operation = [ 12 /* JsonCrdtPatchOpcode.ins_str */, timestamp(sid, op.obj), timestamp(sid, op.ref), op.data, ]; res.push(operation); } else if (op instanceof operations.InsBinOp) { const operation = [ 13 /* JsonCrdtPatchOpcode.ins_bin */, timestamp(sid, op.obj), timestamp(sid, op.ref), toBase64(op.data), ]; res.push(operation); } else if (op instanceof operations.InsArrOp) { const elements = []; for (const element of op.data) elements.push(timestamp(sid, element)); const operation = [ 14 /* JsonCrdtPatchOpcode.ins_arr */, timestamp(sid, op.obj), timestamp(sid, op.ref), elements, ]; res.push(operation); } else if (op instanceof operations.UpdArrOp) { const operation = [ 15 /* JsonCrdtPatchOpcode.upd_arr */, timestamp(sid, op.obj), timestamp(sid, op.ref), timestamp(sid, op.val), ]; res.push(operation); } else if (op instanceof operations.DelOp) { const operation = [ 16 /* JsonCrdtPatchOpcode.del */, timestamp(sid, op.obj), op.what.map((span) => timespan(sid, span)), ]; res.push(operation); } else if (op instanceof operations.NopOp) { const operation = [17 /* JsonCrdtPatchOpcode.nop */]; const len = op.len; if (len > 1) operation.push(len); res.push(operation); } } return res; }; //# sourceMappingURL=encode.js.map