UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

117 lines (116 loc) 4.93 kB
import { OpAdd } from '../../op/OpAdd'; import { OpRemove } from '../../op/OpRemove'; import { OpReplace } from '../../op/OpReplace'; import { OpMove } from '../../op/OpMove'; import { OpCopy } from '../../op/OpCopy'; import { OpTest } from '../../op/OpTest'; import { OpFlip } from '../../op/OpFlip'; import { OpInc } from '../../op/OpInc'; import { OpStrIns } from '../../op/OpStrIns'; import { OpStrDel } from '../../op/OpStrDel'; import { OpSplit } from '../../op/OpSplit'; import { OpMerge } from '../../op/OpMerge'; import { OpExtend } from '../../op/OpExtend'; import { OpDefined } from '../../op/OpDefined'; import { OpUndefined } from '../../op/OpUndefined'; import { OpTestType } from '../../op/OpTestType'; import { OpTestString } from '../../op/OpTestString'; import { OpTestStringLen } from '../../op/OpTestStringLen'; import { OpContains } from '../../op/OpContains'; import { OpEnds } from '../../op/OpEnds'; import { OpStarts } from '../../op/OpStarts'; import { OpIn } from '../../op/OpIn'; import { OpLess } from '../../op/OpLess'; import { OpMore } from '../../op/OpMore'; import { OpAnd } from '../../op/OpAnd'; import { OpOr } from '../../op/OpOr'; import { OpNot } from '../../op/OpNot'; import { OpMatches } from '../../op/OpMatches'; import { OpType } from '../../op/OpType'; import { toPath } from '@jsonjoy.com/json-pointer'; import { createMatcherDefault } from '../../util'; export const operationToOp = (op, options) => { switch (op.op) { case 'add': return new OpAdd(toPath(op.path), op.value); case 'remove': return new OpRemove(toPath(op.path), op.oldValue); case 'replace': return new OpReplace(toPath(op.path), op.value, op.oldValue); case 'move': return new OpMove(toPath(op.path), toPath(op.from)); case 'copy': return new OpCopy(toPath(op.path), toPath(op.from)); case 'flip': return new OpFlip(toPath(op.path)); case 'inc': return new OpInc(toPath(op.path), op.inc); case 'str_ins': return new OpStrIns(toPath(op.path), op.pos, op.str); case 'str_del': return new OpStrDel(toPath(op.path), op.pos, op.str, op.len); case 'split': return new OpSplit(toPath(op.path), op.pos, op.props || null); case 'merge': return new OpMerge(toPath(op.path), op.pos, op.props || null); case 'extend': return new OpExtend(toPath(op.path), op.props, !!op.deleteNull); default: return operationToPredicateOp(op, options); } }; export const operationToPredicateOp = (op, options) => { switch (op.op) { case 'test': return new OpTest(toPath(op.path), op.value, !!op.not); case 'defined': return new OpDefined(toPath(op.path)); case 'undefined': return new OpUndefined(toPath(op.path)); case 'type': return new OpType(toPath(op.path), op.value); case 'test_type': return new OpTestType(toPath(op.path), op.type); case 'test_string': return new OpTestString(toPath(op.path), op.pos, op.str, !!op.not); case 'test_string_len': return new OpTestStringLen(toPath(op.path), op.len, !!op.not); case 'contains': return new OpContains(toPath(op.path), op.value, !!op.ignore_case); case 'ends': return new OpEnds(toPath(op.path), op.value, !!op.ignore_case); case 'starts': return new OpStarts(toPath(op.path), op.value, !!op.ignore_case); case 'matches': return new OpMatches(toPath(op.path), op.value, !!op.ignore_case, options.createMatcher || createMatcherDefault); case 'in': return new OpIn(toPath(op.path), op.value); case 'less': return new OpLess(toPath(op.path), op.value); case 'more': return new OpMore(toPath(op.path), op.value); case 'and': { const path = toPath(op.path); return new OpAnd(path, op.apply.map((x) => operationToPredicateOp({ ...x, path: [...path, ...toPath(x.path)] }, options))); } case 'or': { const path = toPath(op.path); return new OpOr(path, op.apply.map((x) => operationToPredicateOp({ ...x, path: [...path, ...toPath(x.path)] }, options))); } case 'not': { const path = toPath(op.path); return new OpNot(path, op.apply.map((x) => operationToPredicateOp({ ...x, path: [...path, ...toPath(x.path)] }, options))); } default: throw new Error('OP_UNKNOWN'); } }; export function decode(patch, options) { const ops = []; const length = patch.length; for (let i = 0; i < length; i++) { const op = operationToOp(patch[i], options); ops.push(op); } return ops; }