json-joy
Version:
Collection of libraries for building collaborative editing apps.
146 lines • 5.19 kB
JavaScript
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