From 7235c8fe72c36f0beb8defba8bbec51a886ae181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stian=20H=C3=A5klev?= Date: Thu, 4 Apr 2019 13:52:55 +0200 Subject: [PATCH 1/6] Presence changes --- lib/json0.js | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/lib/json0.js b/lib/json0.js index dc3a405..ed603e8 100644 --- a/lib/json0.js +++ b/lib/json0.js @@ -133,6 +133,87 @@ function convertToText(c) { delete c.o; } +function isValidPresence(presence) { + if ( + presence == null || + typeof presence.u !== 'string' || + typeof presence.c !== 'number' || + !isFinite(presence.c) || + Math.floor(presence.c) !== presence.c || + !Array.isArray(presence.s) + ) { + return false; + } + + var selections = presence.s; + + for (var i = 0, l = selections.length; i < l; ++i) { + var selection = selections[i]; + + if ( + !Array.isArray(selection) || + selection.length !== 2 || + selection[0] !== (selection[0] | 0) || + selection[1] !== (selection[1] | 0) + ) { + return false; + } + } + + return true; +} + +json.createPresence = function(presence) { + return presence; +}; + +json.comparePresence = function(pres1, pres2) { + if (!pres1 || !pres2) { + return false; + } + if (!pres1.p || !pres2.p) { + return false; + } + if (pres1.t !== pres2.t) { + return false; + } + if (pres1.t && subtypes[pres1.t]) { + if (pres1.p[0] === pres2.p[0]) { + return subtypes[pres1.t].comparePresence(pres1, pres2); + } + } else return pres1 === pres2; +}; + +json.transformPresence = function(presence, op, isOwn) { + console.group('json transform', presence, op); + if (op.length < 1) { + return presence; + } + const exOp = op[0]; + const opT = op[0].t; + console.log('exop', exOp, opT, exOp.p); + if (opT && subtypes[opT] && exOp.p) { + if (!presence.p || !presence.p[0] || presence.p[0] !== exOp.p[0]) { + console.log('creating presence', presence, exOp.p[0]); + presence = { + ...subtypes[opT].createPresence(), + p: op[0].p, + u: presence.u, + t: op[0].t + }; + console.log(presence); + } + presence = { + ...subtypes[opT].transformPresence(presence, op, isOwn), + p: op[0].p, + t: op[0].t + }; + console.log('result', presence); + console.groupEnd() + } + return presence; +}; + json.apply = function(snapshot, op) { json.checkValidOp(op); From 7023ee3560fae10b6e8c61baf7b3422121449c32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stian=20H=C3=A5klev?= Date: Thu, 4 Apr 2019 14:01:17 +0200 Subject: [PATCH 2/6] WIP --- lib/json0.js | 66 +++++++++++++++++----------------------------------- package.json | 6 ++--- 2 files changed, 24 insertions(+), 48 deletions(-) diff --git a/lib/json0.js b/lib/json0.js index ed603e8..31152e8 100644 --- a/lib/json0.js +++ b/lib/json0.js @@ -133,40 +133,15 @@ function convertToText(c) { delete c.o; } -function isValidPresence(presence) { - if ( - presence == null || - typeof presence.u !== 'string' || - typeof presence.c !== 'number' || - !isFinite(presence.c) || - Math.floor(presence.c) !== presence.c || - !Array.isArray(presence.s) - ) { - return false; - } - - var selections = presence.s; - - for (var i = 0, l = selections.length; i < l; ++i) { - var selection = selections[i]; - - if ( - !Array.isArray(selection) || - selection.length !== 2 || - selection[0] !== (selection[0] | 0) || - selection[1] !== (selection[1] | 0) - ) { - return false; - } - } - - return true; -} - +// not checking anything here, we should probably check that u: exists +// (only thing we care about at json0 top level), and then delegate +// to any subtypes if there is already subtype presence data json.createPresence = function(presence) { return presence; }; +// this needs more thinking/testing, looking a bit more carefully at +// how this is implemented in ot-rich-text, etc. json.comparePresence = function(pres1, pres2) { if (!pres1 || !pres2) { return false; @@ -184,32 +159,33 @@ json.comparePresence = function(pres1, pres2) { } else return pres1 === pres2; }; +// this is the key function, always run client-side, both on +// the client that creates a text-change, and on the clients +// that receive text-changes (ops). if there are no ops, just +// return presence, if there are ops, delegate to the subtype +// responsible for those ops (currently only ot-rich-text). +// I am making assumptions many places that all ops will be +// of the same subtype, not sure if this is a given. +// We're only concerned about the first level of object/array, +// not sure if the spec allows nesting of subtypes. json.transformPresence = function(presence, op, isOwn) { - console.group('json transform', presence, op); if (op.length < 1) { return presence; } - const exOp = op[0]; - const opT = op[0].t; - console.log('exop', exOp, opT, exOp.p); - if (opT && subtypes[opT] && exOp.p) { + const representativeOp = op[0]; + const opTtype = op[0].t; + const path = representativeOp.p && representativeOp.p[0] + if (opType && subtypes[opType] && path) { if (!presence.p || !presence.p[0] || presence.p[0] !== exOp.p[0]) { - console.log('creating presence', presence, exOp.p[0]); - presence = { - ...subtypes[opT].createPresence(), - p: op[0].p, - u: presence.u, - t: op[0].t - }; - console.log(presence); + return presence } + // return result of running the subtype's transformPresence, + // but add path and type, which the subtype will not include presence = { ...subtypes[opT].transformPresence(presence, op, isOwn), p: op[0].p, t: op[0].t }; - console.log('result', presence); - console.groupEnd() } return presence; }; diff --git a/package.json b/package.json index b6c9df6..3d98220 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "ot-json0", - "version": "1.1.0", + "name": "@houshuang/ot-json0", + "version": "1.2.0", "description": "JSON OT type", "main": "lib/index.js", "directories": { @@ -17,7 +17,7 @@ }, "repository": { "type": "git", - "url": "git://github.com/ottypes/json0" + "url": "git://github.com/houshuang/json0" }, "keywords": [ "ot", From 22c5bd477bb8951c93f5cc38b33dc382dd5a8fb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stian=20H=C3=A5klev?= Date: Thu, 4 Apr 2019 14:10:26 +0200 Subject: [PATCH 3/6] WIP --- lib/json0.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/json0.js b/lib/json0.js index 31152e8..4b562e7 100644 --- a/lib/json0.js +++ b/lib/json0.js @@ -173,16 +173,16 @@ json.transformPresence = function(presence, op, isOwn) { return presence; } const representativeOp = op[0]; - const opTtype = op[0].t; + const opType = op[0].t; const path = representativeOp.p && representativeOp.p[0] if (opType && subtypes[opType] && path) { - if (!presence.p || !presence.p[0] || presence.p[0] !== exOp.p[0]) { + if (!presence.p || !presence.p[0] || presence.p[0] !== path) { return presence } // return result of running the subtype's transformPresence, // but add path and type, which the subtype will not include presence = { - ...subtypes[opT].transformPresence(presence, op, isOwn), + ...subtypes[opType].transformPresence(presence, op, isOwn), p: op[0].p, t: op[0].t }; From b25c3a7627eb7ee217771c4ca8cfff77311a4490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stian=20H=C3=A5klev?= Date: Sat, 6 Apr 2019 10:51:06 +0200 Subject: [PATCH 4/6] WIP --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 3d98220..c7d133e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "@houshuang/ot-json0", - "version": "1.2.0", - "description": "JSON OT type", + "name": "@minervaproject/ot-json0", + "version": "1.3.0", + "description": "JSON OT type, fork of sharedb/ot-json0@1.2.0", "main": "lib/index.js", "directories": { "test": "test" From beb947cd69f6d802a1ca75df1a4b0538d29521f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stian=20H=C3=A5klev?= Date: Thu, 11 Apr 2019 11:46:09 +0200 Subject: [PATCH 5/6] WIP --- lib/json0.js | 290 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 202 insertions(+), 88 deletions(-) diff --git a/lib/json0.js b/lib/json0.js index 4b562e7..36b21d9 100644 --- a/lib/json0.js +++ b/lib/json0.js @@ -29,7 +29,7 @@ var isArray = function(obj) { * @returns {boolean} */ var isObject = function(obj) { - return (!!obj) && (obj.constructor === Object); + return !!obj && obj.constructor === Object; }; /** @@ -66,7 +66,7 @@ json.create = function(data) { }; json.invertComponent = function(c) { - var c_ = {p: c.p}; + var c_ = { p: c.p }; // handle subtype ops if (c.t && subtypes[c.t]) { @@ -83,8 +83,8 @@ json.invertComponent = function(c) { if (c.na !== void 0) c_.na = -c.na; if (c.lm !== void 0) { - c_.lm = c.p[c.p.length-1]; - c_.p = c.p.slice(0,c.p.length-1).concat([c.lm]); + c_.lm = c.p[c.p.length - 1]; + c_.p = c.p.slice(0, c.p.length - 1).concat([c.lm]); } return c_; @@ -106,20 +106,21 @@ json.checkValidOp = function(op) { }; json.checkList = function(elem) { - if (!isArray(elem)) - throw new Error('Referenced element not a list'); + if (!isArray(elem)) throw new Error('Referenced element not a list'); }; json.checkObj = function(elem) { if (!isObject(elem)) { - throw new Error("Referenced element not an object (it was " + JSON.stringify(elem) + ")"); + throw new Error( + 'Referenced element not an object (it was ' + JSON.stringify(elem) + ')' + ); } }; // helper functions to convert old string ops to and from subtype ops function convertFromText(c) { c.t = 'text0'; - var o = {p: c.p.pop()}; + var o = { p: c.p.pop() }; if (c.si != null) o.i = c.si; if (c.sd != null) o.d = c.sd; c.o = [o]; @@ -159,6 +160,100 @@ json.comparePresence = function(pres1, pres2) { } else return pres1 === pres2; }; +var transformPosition = function(cursor, op, isOwnOp) { + var cursor = clone(cursor); + + var opIsAncestor = cursor.length >= op.p.length; // true also if op is self + var opIsSibling = cursor.length === op.p.length; // true also if op is self + var opIsAncestorSibling = cursor.length >= op.p.length; // true also if op is self or sibling of self + var equalUpTo = -1; + for (var i = 0; i < op.p.length; i++) { + if (op.p[i] !== cursor[i]) { + opIsAncestor = false; + if (i < op.p.length - 1) { + opIsSibling = false; + opIsAncestorSibling = false; + } + } + if (equalUpTo === i - 1 && op.p[i] === cursor[i]) { + equalUpTo += 1; + } + } + + if (opIsSibling) { + if (op.sd) { + cursor[cursor.length - 1] = text.transformCursor( + cursor[cursor.length - 1], + [{ p: op.p[op.p.length - 1], d: op.sd }], + isOwnOp ? 'right' : 'left' + ); + } + if (op.si) { + cursor[cursor.length - 1] = text.transformCursor( + cursor[cursor.length - 1], + [{ p: op.p[op.p.length - 1], i: op.si }], + isOwnOp ? 'right' : 'left' + ); + } + } + + if (opIsAncestor) { + if (op.lm !== undefined) { + cursor[equalUpTo] = op.lm; + } + if (op.od && op.oi) { + cursor = op.p.slice(0, op.p.length); + } else if (op.od) { + cursor = op.p.slice(0, op.p.length - 1); + } else if (op.ld && op.li) { + cursor = op.p.slice(0, op.p.length); + } else if (op.ld) { + cursor = op.p.slice(0, op.p.length - 1); + } + } + + if (opIsAncestorSibling) { + var lastPathIdx = op.p.length - 1; + if ( + !opIsAncestor && + op.ld && + !op.li && + op.p[lastPathIdx] < cursor[lastPathIdx] + ) { + cursor[lastPathIdx] -= 1; + } else if (!op.ld && op.li && op.p[lastPathIdx] <= cursor[lastPathIdx]) { + cursor[lastPathIdx] += 1; + } + + // if move item in list from after to before + if ( + !opIsAncestor && + op.lm !== undefined && + op.p[lastPathIdx] > cursor[lastPathIdx] && + op.lm <= cursor[lastPathIdx] + ) { + cursor[lastPathIdx] += 1; + // if move item in list from before to after + } else if ( + !opIsAncestor && + op.lm !== undefined && + op.p[lastPathIdx] < cursor[lastPathIdx] && + op.lm >= cursor[lastPathIdx] + ) { + cursor[lastPathIdx] -= 1; + } + } + + return cursor; +}; + +json.transformCursor = function(cursor, op, isOwnOp) { + for (var i = 0; i < op.length; i++) { + cursor = transformPosition(cursor, op[i], isOwnOp); + } + return cursor; +}; + // this is the key function, always run client-side, both on // the client that creates a text-change, and on the clients // that receive text-changes (ops). if there are no ops, just @@ -168,25 +263,28 @@ json.comparePresence = function(pres1, pres2) { // of the same subtype, not sure if this is a given. // We're only concerned about the first level of object/array, // not sure if the spec allows nesting of subtypes. -json.transformPresence = function(presence, op, isOwn) { +json.transformPresence = function(presence, ops, isOwn) { if (op.length < 1) { return presence; } - const representativeOp = op[0]; - const opType = op[0].t; - const path = representativeOp.p && representativeOp.p[0] - if (opType && subtypes[opType] && path) { - if (!presence.p || !presence.p[0] || presence.p[0] !== path) { - return presence + ops.forEach(op => { + const opType = op.t; + const path = op.p && op.p[0]; + if (opType && subtypes[opType] && path) { + // No path given, or path does not match path in presence -- + // no need to transform path since no conflict + if (!presence.p || !presence.p[0] || presence.p[0] !== path) { + return presence; + } + // return result of running the subtype's transformPresence, + // but add path and type, which the subtype will not include + presence.cursor = subtypes[opType].transformCursor( + presence, + op, + isOwn + ).cursor; } - // return result of running the subtype's transformPresence, - // but add path and type, which the subtype will not include - presence = { - ...subtypes[opType].transformPresence(presence, op, isOwn), - p: op[0].p, - t: op[0].t - }; - } + }); return presence; }; @@ -203,8 +301,7 @@ json.apply = function(snapshot, op) { var c = op[i]; // convert old string ops to use subtype for backwards compatibility - if (c.si != null || c.sd != null) - convertFromText(c); + if (c.si != null || c.sd != null) convertFromText(c); var parent = null; var parentKey = null; @@ -219,15 +316,14 @@ json.apply = function(snapshot, op) { elem = elem[key]; key = p; - if (parent == null) - throw new Error('Path invalid'); + if (parent == null) throw new Error('Path invalid'); } // handle subtype ops if (c.t && c.o !== void 0 && subtypes[c.t]) { elem[key] = subtypes[c.t].apply(elem[key], c.o); - // Number add + // Number add } else if (c.na !== void 0) { if (typeof elem[key] != 'number') throw new Error('Referenced element not a number'); @@ -245,14 +341,14 @@ json.apply = function(snapshot, op) { // List insert else if (c.li !== void 0) { json.checkList(elem); - elem.splice(key,0, c.li); + elem.splice(key, 0, c.li); } // List delete else if (c.ld !== void 0) { json.checkList(elem); // Should check the list element matches c.ld here too. - elem.splice(key,1); + elem.splice(key, 1); } // List move @@ -261,9 +357,9 @@ json.apply = function(snapshot, op) { if (c.lm != key) { var e = elem[key]; // Remove it... - elem.splice(key,1); + elem.splice(key, 1); // And insert it back. - elem.splice(c.lm,0,e); + elem.splice(c.lm, 0, e); } } @@ -281,9 +377,7 @@ json.apply = function(snapshot, op) { // Should check that elem[key] == c.od delete elem[key]; - } - - else { + } else { throw new Error('invalid / missing instruction in op'); } } @@ -314,19 +408,17 @@ json.incrementalApply = function(snapshot, op, _yield) { }; // Checks if two paths, p1 and p2 match. -var pathMatches = json.pathMatches = function(p1, p2, ignoreLast) { - if (p1.length != p2.length) - return false; +var pathMatches = (json.pathMatches = function(p1, p2, ignoreLast) { + if (p1.length != p2.length) return false; for (var i = 0; i < p1.length; i++) { - if (p1[i] !== p2[i] && (!ignoreLast || i !== p1.length - 1)) - return false; + if (p1[i] !== p2[i] && (!ignoreLast || i !== p1.length - 1)) return false; } return true; -}; +}); -json.append = function(dest,c) { +json.append = function(dest, c) { c = clone(c); if (dest.length === 0) { @@ -345,7 +437,10 @@ json.append = function(dest,c) { if (pathMatches(c.p, last.p)) { // handle subtype ops if (c.t && last.t && c.t === last.t && subtypes[c.t]) { - last.o = subtypes[c.t].compose(last.o, c.o); + last.o = subtypes[c.t].compose( + last.o, + c.o + ); // convert back to old string ops if (c.si != null || c.sd != null) { @@ -360,8 +455,12 @@ json.append = function(dest,c) { convertToText(last); } } else if (last.na != null && c.na != null) { - dest[dest.length - 1] = {p: last.p, na: last.na + c.na}; - } else if (last.li !== undefined && c.li === undefined && c.ld === last.li) { + dest[dest.length - 1] = { p: last.p, na: last.na + c.na }; + } else if ( + last.li !== undefined && + c.li === undefined && + c.ld === last.li + ) { // insert immediately followed by delete becomes a noop. if (last.ld !== undefined) { // leave the delete part of the replace @@ -369,7 +468,12 @@ json.append = function(dest,c) { } else { dest.pop(); } - } else if (last.od !== undefined && last.oi === undefined && c.oi !== undefined && c.od === undefined) { + } else if ( + last.od !== undefined && + last.oi === undefined && + c.oi !== undefined && + c.od === undefined + ) { last.oi = c.oi; } else if (last.oi !== undefined && c.od !== undefined) { // The last path component inserted something that the new component deletes (or replaces). @@ -389,7 +493,10 @@ json.append = function(dest,c) { } } else { // convert string ops back - if ((c.si != null || c.sd != null) && (last.si != null || last.sd != null)) { + if ( + (c.si != null || c.sd != null) && + (last.si != null || last.sd != null) + ) { convertToText(c); convertToText(last); } @@ -398,14 +505,14 @@ json.append = function(dest,c) { } }; -json.compose = function(op1,op2) { +json.compose = function(op1, op2) { json.checkValidOp(op1); json.checkValidOp(op2); var newOp = clone(op1); for (var i = 0; i < op2.length; i++) { - json.append(newOp,op2[i]); + json.append(newOp, op2[i]); } return newOp; @@ -420,7 +527,7 @@ json.normalize = function(op) { var c = op[i]; if (c.p == null) c.p = []; - json.append(newOp,c); + json.append(newOp, c); } return newOp; @@ -430,11 +537,9 @@ json.normalize = function(op) { json.commonLengthForOps = function(a, b) { var alen = a.p.length; var blen = b.p.length; - if (a.na != null || a.t) - alen++; + if (a.na != null || a.t) alen++; - if (b.na != null || b.t) - blen++; + if (b.na != null || b.t) blen++; if (alen === 0) return -1; if (blen === 0) return null; @@ -444,8 +549,7 @@ json.commonLengthForOps = function(a, b) { for (var i = 0; i < alen; i++) { var p = a.p[i]; - if (i >= blen || p !== b.p[i]) - return null; + if (i >= blen || p !== b.p[i]) return null; } return alen; @@ -453,7 +557,7 @@ json.commonLengthForOps = function(a, b) { // Returns true if an op can affect the given path json.canOpAffectPath = function(op, path) { - return json.commonLengthForOps({p:path}, op) != null; + return json.commonLengthForOps({ p: path }, op) != null; }; // transform c so it applies to a document with otherC applied. @@ -465,23 +569,25 @@ json.transformComponent = function(dest, c, otherC, type) { var cplength = c.p.length; var otherCplength = otherC.p.length; - if (c.na != null || c.t) - cplength++; + if (c.na != null || c.t) cplength++; - if (otherC.na != null || otherC.t) - otherCplength++; + if (otherC.na != null || otherC.t) otherCplength++; // if c is deleting something, and that thing is changed by otherC, we need to // update c to reflect that change for invertibility. - if (common2 != null && otherCplength > cplength && c.p[common2] == otherC.p[common2]) { + if ( + common2 != null && + otherCplength > cplength && + c.p[common2] == otherC.p[common2] + ) { if (c.ld !== void 0) { var oc = clone(otherC); oc.p = oc.p.slice(cplength); - c.ld = json.apply(clone(c.ld),[oc]); + c.ld = json.apply(clone(c.ld), [oc]); } else if (c.od !== void 0) { var oc = clone(otherC); oc.p = oc.p.slice(cplength); - c.od = json.apply(clone(c.od),[oc]); + c.od = json.apply(clone(c.od), [oc]); } } @@ -490,7 +596,10 @@ json.transformComponent = function(dest, c, otherC, type) { // backward compatibility for old string ops var oc = otherC; - if ((c.si != null || c.sd != null) && (otherC.si != null || otherC.sd != null)) { + if ( + (c.si != null || c.sd != null) && + (otherC.si != null || otherC.sd != null) + ) { convertFromText(c); oc = clone(otherC); convertFromText(oc); @@ -539,10 +648,14 @@ json.transformComponent = function(dest, c, otherC, type) { } } } else if (otherC.li !== void 0) { - if (c.li !== void 0 && c.ld === undefined && commonOperand && c.p[common] === otherC.p[common]) { + if ( + c.li !== void 0 && + c.ld === undefined && + commonOperand && + c.p[common] === otherC.p[common] + ) { // in li vs. li, left wins. - if (type === 'right') - c.p[common]++; + if (type === 'right') c.p[common]++; } else if (otherC.p[common] <= c.p[common]) { c.p[common]++; } @@ -550,8 +663,7 @@ json.transformComponent = function(dest, c, otherC, type) { if (c.lm !== void 0) { if (commonOperand) { // otherC edits the same list we edit - if (otherC.p[common] <= c.lm) - c.lm++; + if (otherC.p[common] <= c.lm) c.lm++; // changing c.from is handled above. } } @@ -566,9 +678,7 @@ json.transformComponent = function(dest, c, otherC, type) { var p = otherC.p[common]; var from = c.p[common]; var to = c.lm; - if (p < to || (p === to && from < to)) - c.lm--; - + if (p < to || (p === to && from < to)) c.lm--; } } @@ -588,7 +698,6 @@ json.transformComponent = function(dest, c, otherC, type) { } } } - } else if (otherC.lm !== void 0) { if (c.lm !== void 0 && cplength === otherCplength) { // lm vs lm, here we go! @@ -604,7 +713,8 @@ json.transformComponent = function(dest, c, otherC, type) { // they moved it! tie break. if (type === 'left') { c.p[common] = otherTo; - if (from === to) // ugh + if (from === to) + // ugh c.lm = otherTo; } else { return dest; @@ -616,7 +726,8 @@ json.transformComponent = function(dest, c, otherC, type) { else if (from === otherTo) { if (otherFrom > otherTo) { c.p[common]++; - if (from === to) // ugh, again + if (from === to) + // ugh, again c.lm++; } } @@ -625,15 +736,16 @@ json.transformComponent = function(dest, c, otherC, type) { if (to > otherFrom) { c.lm--; } else if (to === otherFrom) { - if (to > from) - c.lm--; + if (to > from) c.lm--; } if (to > otherTo) { c.lm++; } else if (to === otherTo) { // if we're both moving in the same direction, tie break - if ((otherTo > otherFrom && to > from) || - (otherTo < otherFrom && to < from)) { + if ( + (otherTo > otherFrom && to > from) || + (otherTo < otherFrom && to < from) + ) { if (type === 'right') c.lm++; } else { if (to > from) c.lm++; @@ -665,8 +777,7 @@ json.transformComponent = function(dest, c, otherC, type) { else if (p === to && from > to) c.p[common]++; } } - } - else if (otherC.oi !== void 0 && otherC.od !== void 0) { + } else if (otherC.oi !== void 0 && otherC.od !== void 0) { if (c.p[common] === otherC.p[common]) { if (c.oi !== void 0 && commonOperand) { // we inserted where someone else replaced @@ -686,15 +797,14 @@ json.transformComponent = function(dest, c, otherC, type) { if (c.oi !== void 0 && c.p[common] === otherC.p[common]) { // left wins if we try to insert at the same place if (type === 'left') { - json.append(dest,{p: c.p, od:otherC.oi}); + json.append(dest, { p: c.p, od: otherC.oi }); } else { return dest; } } } else if (otherC.od !== void 0) { if (c.p[common] == otherC.p[common]) { - if (!commonOperand) - return dest; + if (!commonOperand) return dest; if (c.oi !== void 0) { delete c.od; } else { @@ -704,11 +814,16 @@ json.transformComponent = function(dest, c, otherC, type) { } } - json.append(dest,c); + json.append(dest, c); return dest; }; -require('./bootstrapTransform')(json, json.transformComponent, json.checkValidOp, json.append); +require('./bootstrapTransform')( + json, + json.transformComponent, + json.checkValidOp, + json.append +); /** * Register a subtype for string operations, using the text0 type. @@ -717,4 +832,3 @@ var text = require('./text0'); json.registerSubtype(text); module.exports = json; - From aadf1ef61f445cce872c94a039863d05e3c4e4d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stian=20H=C3=A5klev?= Date: Thu, 11 Apr 2019 13:52:34 +0200 Subject: [PATCH 6/6] WIP --- yarn.lock | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 yarn.lock diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..e13b328 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,172 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +cli-progress@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-2.1.1.tgz#45ee1b143487c19043a3262131ccb4676f87f032" + integrity sha512-TSJw3LY9ZRSis7yYzQ7flIdtQMbacd9oYoiFphJhI4SzgmqF0zErO+uNv0lbUjk1L4AGfHQJ4OVYYzW+JV66KA== + dependencies: + colors "^1.1.2" + string-width "^2.1.1" + +coffee-script@^1.7.1: + version "1.12.7" + resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.7.tgz#c05dae0cb79591d05b3070a8433a98c9a89ccc53" + integrity sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw== + +colors@^1.1.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" + integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== + +commander@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" + integrity sha1-+mihT2qUXVTbvlDYzbMyDp47GgY= + +commander@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" + integrity sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM= + +debug@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.0.0.tgz#89bd9df6732b51256bc6705342bba02ed12131ef" + integrity sha1-ib2d9nMrUSVrxnBTQrugLtEhMe8= + dependencies: + ms "0.6.2" + +diff@1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/diff/-/diff-1.0.8.tgz#343276308ec991b7bc82267ed55bc1411f971666" + integrity sha1-NDJ2MI7Jkbe8giZ+1VvBQR+XFmY= + +escape-string-regexp@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" + integrity sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE= + +glob@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.3.tgz#e313eeb249c7affaa5c475286b0e115b59839467" + integrity sha1-4xPusknHr/qlxHUoaw4RW1mDlGc= + dependencies: + graceful-fs "~2.0.0" + inherits "2" + minimatch "~0.2.11" + +graceful-fs@~2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-2.0.3.tgz#7cd2cdb228a4a3f36e95efa6cc142de7d1a136d0" + integrity sha1-fNLNsiiko/Nule+mzBQt59GhNtA= + +growl@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.8.1.tgz#4b2dec8d907e93db336624dcec0183502f8c9428" + integrity sha1-Sy3sjZB+k9szZiTc7AGDUC+MlCg= + +inherits@2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +jade@0.26.3: + version "0.26.3" + resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" + integrity sha1-jxDXl32NefL2/4YqgbBRPMslaGw= + dependencies: + commander "0.6.1" + mkdirp "0.3.0" + +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI= + +minimatch@~0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" + integrity sha1-x054BXT2PG+aCQ6Q775u9TpqdWo= + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +mkdirp@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" + integrity sha1-G79asbqCevI1dRQ0kEJkVfSB/h4= + +mkdirp@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" + integrity sha1-HXMHam35hs2TROFecfzAWkyavxI= + dependencies: + minimist "0.0.8" + +mocha@^1.20.1: + version "1.21.5" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-1.21.5.tgz#7c58b09174df976e434a23b1e8d639873fc529e9" + integrity sha1-fFiwkXTfl25DSiOx6NY5hz/FKek= + dependencies: + commander "2.3.0" + debug "2.0.0" + diff "1.0.8" + escape-string-regexp "1.0.2" + glob "3.2.3" + growl "1.8.1" + jade "0.26.3" + mkdirp "0.5.0" + +ms@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.6.2.tgz#d89c2124c6fdc1353d65a8b77bf1aac4b193708c" + integrity sha1-2JwhJMb9wTU9Zai3e/GqxLGTcIw= + +ot-fuzzer@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ot-fuzzer/-/ot-fuzzer-1.2.1.tgz#41f70305fdd1d55268f6cc169c14c0eb9e5fb31c" + integrity sha512-dOm+Wb1Mqrw8ql5ksiZFf3Bdsruj5r4mHaa3COqtbg0ClkGjxZXwMGgMLjWslq/b0maeiw5yvYwIdH6As4svHg== + dependencies: + cli-progress "^2.1.1" + seedrandom "^2.4.4" + +seedrandom@^2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-2.4.4.tgz#b25ea98632c73e45f58b77cfaa931678df01f9ba" + integrity sha512-9A+PDmgm+2du77B5i0Ip2cxOqqHjgNxnBgglxLcX78A2D6c2rTo61z4jnVABpF4cKeDMDG+cmXXvdnqse2VqMA== + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + +string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0"