json-joy
Version:
Collection of libraries for building collaborative editing apps.
302 lines • 13.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Encoder = void 0;
const MsgPackEncoderFast_1 = require("@jsonjoy.com/json-pack/lib/msgpack/MsgPackEncoderFast");
const constants_1 = require("../../constants");
class Encoder extends MsgPackEncoderFast_1.MsgPackEncoderFast {
encode(patch) {
this.writer.reset();
this.encodeArrayHeader(patch.length);
const length = patch.length;
for (let i = 0; i < length; i++)
this.encodeOp(patch[i]);
return this.writer.flush();
}
encodeOp(op, parent) {
switch (op.code()) {
case constants_1.OPCODE.add: {
const addOp = op;
this.encodeArrayHeader(3);
this.writer.u8(constants_1.OPCODE.add);
this.encodeArray(addOp.path);
this.encodeAny(addOp.value);
break;
}
case constants_1.OPCODE.remove: {
const removeOp = op;
const hasOldValue = removeOp.oldValue !== undefined;
this.encodeArrayHeader(hasOldValue ? 3 : 2);
this.writer.u8(constants_1.OPCODE.remove);
this.encodeArray(removeOp.path);
if (hasOldValue)
this.encodeAny(removeOp.oldValue);
break;
}
case constants_1.OPCODE.replace: {
const replaceOp = op;
const hasOldValue = replaceOp.oldValue !== undefined;
this.encodeArrayHeader(hasOldValue ? 4 : 3);
this.writer.u8(constants_1.OPCODE.replace);
this.encodeArray(replaceOp.path);
this.encodeAny(replaceOp.value);
if (hasOldValue)
this.encodeAny(replaceOp.oldValue);
break;
}
case constants_1.OPCODE.copy: {
const copyOp = op;
this.encodeArrayHeader(3);
this.writer.u8(constants_1.OPCODE.copy);
this.encodeArray(copyOp.path);
this.encodeArray(copyOp.from);
break;
}
case constants_1.OPCODE.move: {
const moveOp = op;
this.encodeArrayHeader(3);
this.writer.u8(constants_1.OPCODE.move);
this.encodeArray(moveOp.path);
this.encodeArray(moveOp.from);
break;
}
case constants_1.OPCODE.test: {
const testOp = op;
this.encodeArrayHeader(testOp.not ? 4 : 3);
this.writer.u8(constants_1.OPCODE.test);
this.encodeArray(parent ? testOp.path.slice(parent.path.length) : testOp.path);
this.encodeAny(testOp.value);
if (testOp.not)
this.writer.u8(1);
break;
}
case constants_1.OPCODE.str_ins: {
const strInsOp = op;
this.encodeArrayHeader(4);
this.writer.u8(constants_1.OPCODE.str_ins);
this.encodeArray(strInsOp.path);
this.encodeNumber(strInsOp.pos);
this.encodeString(strInsOp.str);
break;
}
case constants_1.OPCODE.str_del: {
const strDelOp = op;
const hasStr = typeof strDelOp.str === 'string';
this.encodeArrayHeader(hasStr ? 4 : 5);
this.writer.u8(constants_1.OPCODE.str_del);
this.encodeArray(strDelOp.path);
this.encodeNumber(strDelOp.pos);
if (hasStr) {
this.encodeString(strDelOp.str);
}
else {
this.writer.u8(0);
this.encodeNumber(strDelOp.len);
}
break;
}
case constants_1.OPCODE.flip: {
const flipOp = op;
this.encodeArrayHeader(2);
this.writer.u8(constants_1.OPCODE.flip);
this.encodeArray(flipOp.path);
break;
}
case constants_1.OPCODE.inc: {
const incOp = op;
this.encodeArrayHeader(3);
this.writer.u8(constants_1.OPCODE.inc);
this.encodeArray(incOp.path);
this.encodeNumber(incOp.inc);
break;
}
case constants_1.OPCODE.split: {
const splitOp = op;
this.encodeArrayHeader(splitOp.props ? 4 : 3);
this.writer.u8(constants_1.OPCODE.split);
this.encodeArray(splitOp.path);
this.encodeNumber(splitOp.pos);
if (splitOp.props)
this.encodeObject(splitOp.props);
break;
}
case constants_1.OPCODE.merge: {
const mergeOp = op;
this.encodeArrayHeader(mergeOp.props ? 4 : 3);
this.writer.u8(constants_1.OPCODE.merge);
this.encodeArray(mergeOp.path);
this.encodeNumber(mergeOp.pos);
if (mergeOp.props)
this.encodeAny(mergeOp.props);
break;
}
case constants_1.OPCODE.extend: {
const extendOp = op;
const { deleteNull } = extendOp;
this.encodeArrayHeader(deleteNull ? 4 : 3);
this.writer.u8(constants_1.OPCODE.extend);
this.encodeArray(extendOp.path);
this.encodeObject(extendOp.props);
if (deleteNull)
this.writer.u8(1);
break;
}
case constants_1.OPCODE.contains: {
const containsOp = op;
const ignoreCase = containsOp.ignore_case;
this.encodeArrayHeader(ignoreCase ? 4 : 3);
this.writer.u8(constants_1.OPCODE.contains);
this.encodeArray(parent ? containsOp.path.slice(parent.path.length) : containsOp.path);
this.encodeString(containsOp.value);
if (ignoreCase)
this.writer.u8(1);
break;
}
case constants_1.OPCODE.defined: {
const definedOp = op;
this.encodeArrayHeader(2);
this.writer.u8(constants_1.OPCODE.defined);
this.encodeArray(parent ? definedOp.path.slice(parent.path.length) : definedOp.path);
break;
}
case constants_1.OPCODE.ends: {
const endsOp = op;
const ignoreCase = endsOp.ignore_case;
this.encodeArrayHeader(ignoreCase ? 4 : 3);
this.writer.u8(constants_1.OPCODE.ends);
this.encodeArray(parent ? endsOp.path.slice(parent.path.length) : endsOp.path);
this.encodeString(endsOp.value);
if (ignoreCase)
this.writer.u8(1);
break;
}
case constants_1.OPCODE.in: {
const inOp = op;
this.encodeArrayHeader(3);
this.writer.u8(constants_1.OPCODE.in);
this.encodeArray(parent ? inOp.path.slice(parent.path.length) : inOp.path);
this.encodeArray(inOp.value);
break;
}
case constants_1.OPCODE.less: {
const lessOp = op;
this.encodeArrayHeader(3);
this.writer.u8(constants_1.OPCODE.less);
this.encodeArray(parent ? lessOp.path.slice(parent.path.length) : lessOp.path);
this.encodeNumber(lessOp.value);
break;
}
case constants_1.OPCODE.matches: {
const matchesOp = op;
const ignoreCase = matchesOp.ignore_case;
this.encodeArrayHeader(ignoreCase ? 4 : 3);
this.writer.u8(constants_1.OPCODE.matches);
this.encodeArray(parent ? matchesOp.path.slice(parent.path.length) : matchesOp.path);
this.encodeString(matchesOp.value);
if (ignoreCase)
this.writer.u8(1);
break;
}
case constants_1.OPCODE.more: {
const moreOp = op;
this.encodeArrayHeader(3);
this.writer.u8(constants_1.OPCODE.more);
this.encodeArray(parent ? moreOp.path.slice(parent.path.length) : moreOp.path);
this.encodeNumber(moreOp.value);
break;
}
case constants_1.OPCODE.starts: {
const startsOp = op;
const ignoreCase = startsOp.ignore_case;
this.encodeArrayHeader(ignoreCase ? 4 : 3);
this.writer.u8(constants_1.OPCODE.starts);
this.encodeArray(parent ? startsOp.path.slice(parent.path.length) : startsOp.path);
this.encodeString(startsOp.value);
if (ignoreCase)
this.writer.u8(1);
break;
}
case constants_1.OPCODE.test_type: {
const testTypeOp = op;
this.encodeArrayHeader(3);
this.writer.u8(constants_1.OPCODE.test_type);
this.encodeArray(parent ? testTypeOp.path.slice(parent.path.length) : testTypeOp.path);
this.encodeArray(testTypeOp.type);
break;
}
case constants_1.OPCODE.test_string: {
const testStringOp = op;
this.encodeArrayHeader(testStringOp.not ? 5 : 4);
this.writer.u8(constants_1.OPCODE.test_string);
this.encodeArray(parent ? testStringOp.path.slice(parent.path.length) : testStringOp.path);
this.encodeNumber(testStringOp.pos);
this.encodeString(testStringOp.str);
if (testStringOp.not)
this.writer.u8(1);
break;
}
case constants_1.OPCODE.test_string_len: {
const testStringLenOp = op;
this.encodeArrayHeader(testStringLenOp.not ? 4 : 3);
this.writer.u8(constants_1.OPCODE.test_string_len);
this.encodeArray(parent ? testStringLenOp.path.slice(parent.path.length) : testStringLenOp.path);
this.encodeNumber(testStringLenOp.len);
if (testStringLenOp.not)
this.writer.u8(1);
break;
}
case constants_1.OPCODE.type: {
const typeOp = op;
this.encodeArrayHeader(3);
this.writer.u8(constants_1.OPCODE.type);
this.encodeArray(parent ? typeOp.path.slice(parent.path.length) : typeOp.path);
this.encodeString(typeOp.value);
break;
}
case constants_1.OPCODE.undefined: {
const undefinedOp = op;
this.encodeArrayHeader(2);
this.writer.u8(constants_1.OPCODE.undefined);
this.encodeArray(parent ? undefinedOp.path.slice(parent.path.length) : undefinedOp.path);
break;
}
case constants_1.OPCODE.and: {
const andOp = op;
const path = parent ? andOp.path.slice(parent.path.length) : andOp.path;
this.encodeArrayHeader(3);
this.writer.u8(constants_1.OPCODE.and);
this.encodeArray(path);
const length = andOp.ops.length;
this.encodeArrayHeader(length);
for (let i = 0; i < length; i++)
this.encodeOp(andOp.ops[i], andOp);
break;
}
case constants_1.OPCODE.not: {
const notOp = op;
this.encodeArrayHeader(3);
this.writer.u8(constants_1.OPCODE.not);
this.encodeArray(parent ? notOp.path.slice(parent.path.length) : notOp.path);
const length = notOp.ops.length;
this.encodeArrayHeader(length);
for (let i = 0; i < length; i++)
this.encodeOp(notOp.ops[i], notOp);
break;
}
case constants_1.OPCODE.or: {
const orOp = op;
this.encodeArrayHeader(3);
this.writer.u8(constants_1.OPCODE.or);
this.encodeArray(parent ? orOp.path.slice(parent.path.length) : orOp.path);
const length = orOp.ops.length;
this.encodeArrayHeader(length);
for (let i = 0; i < length; i++)
this.encodeOp(orOp.ops[i], orOp);
break;
}
default:
throw new Error(`Unknown operation code: ${op.code()}`);
}
}
}
exports.Encoder = Encoder;
//# sourceMappingURL=Encoder.js.map