Skip to content

Commit

Permalink
✨ Add support for invertWithDoc for subtypes
Browse files Browse the repository at this point in the history
This change adds support for the [optional, but recommended][1]
`invertWithDoc(op, doc) -> op'` method.

`json0` itself already inverts fine without the doc, just using the
`invert()` method, but this change adds support for subtypes, which only
implement `invertWithDoc()`.

[1]: https://github.com/ottypes/docs#optional-properties
  • Loading branch information
alecgibson committed Dec 16, 2021
1 parent 90a3ae2 commit 27cbe50
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
21 changes: 19 additions & 2 deletions lib/json0.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,21 @@ json.create = function(data) {
return data === undefined ? null : clone(data);
};

json.invertComponent = function(c) {
json.invertComponent = function(c, doc) {
var c_ = {p: c.p};

for (var i = 0; i < c.p.length; i++) {
var key = c.p[i];
doc = doc && doc[key];
}

// handle subtype ops
if (c.t && subtypes[c.t]) {
c_.t = c.t;
c_.o = subtypes[c.t].invert(c.o);
var subtype = subtypes[c.t];
if (doc && typeof subtype.invertWithDoc === 'function') c_.o = subtype.invertWithDoc(c.o, doc);
else if (typeof subtype.invert === 'function') c_.o = subtype.invert(c.o);
else throw new Error("Subtype '" + c.t + "' is not invertible");
}

if (c.si !== void 0) c_.sd = c.si;
Expand Down Expand Up @@ -99,6 +107,15 @@ json.invert = function(op) {
return iop;
};

json.invertWithDoc = function(op, doc) {
var op_ = op.slice().reverse();
var iop = [];
for (var i = 0; i < op_.length; i++) {
iop.push(json.invertComponent(op_[i], doc));
}
return iop;
}

json.checkValidOp = function(op) {
for (var i = 0; i < op.length; i++) {
if (!isArray(op[i].p)) throw new Error('Missing path');
Expand Down
21 changes: 21 additions & 0 deletions test/json0.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,27 @@ genTests = (type) ->
assert.deepEqual [{p:[100], si:'hi'}], type.compose [{p:[100], si:'h'}], [{p:[101], si:'i'}]
assert.deepEqual [{p:[], t:'text0', o:[{p:100, i:'hi'}]}], type.compose [{p:[], t:'text0', o:[{p:100, i:'h'}]}], [{p:[], t:'text0', o:[{p:101, i:'i'}]}]

describe '#invertWithDoc()', ->
it 'passes the doc to the subtype', ->
op = null
doc = null

type.registerSubtype
name: 'invertible'
invertWithDoc: (o, d) ->
op = o
doc = d

type.invertWithDoc [{p: ['foo', 'bar'], t: 'invertible', o: [{increment: 1}]}], {foo: {bar: 5}}
assert.deepEqual [{increment: 1}], op
assert.deepEqual 5, doc

it 'throws if the subtype does not support inversion', ->
type.registerSubtype
name: 'not-invertible'

assert.throws -> type.invertWithDoc [{p: ['foo'], t: 'not-invertible', o: [{increment: 1}]}], {foo: 5}

it 'moves ops on a moved element with the element', ->
assert.deepEqual [{p:[10], ld:'x'}], type.transform [{p:[4], ld:'x'}], [{p:[4], lm:10}], 'left'
assert.deepEqual [{p:[10, 1], si:'a'}], type.transform [{p:[4, 1], si:'a'}], [{p:[4], lm:10}], 'left'
Expand Down

0 comments on commit 27cbe50

Please sign in to comment.