Skip to content

Commit d1c2dc3

Browse files
committed
✨ Add support for invertWithDoc for subtypes
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
1 parent 90a3ae2 commit d1c2dc3

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

lib/json0.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,22 @@ json.create = function(data) {
6565
return data === undefined ? null : clone(data);
6666
};
6767

68-
json.invertComponent = function(c) {
68+
json.invertComponent = function(c, doc) {
6969
var c_ = {p: c.p};
7070

71+
var hasDoc = typeof doc !== 'undefined';
72+
for (var i = 0; i < c.p.length; i++) {
73+
var key = c.p[i];
74+
doc = doc && doc[key];
75+
}
76+
7177
// handle subtype ops
7278
if (c.t && subtypes[c.t]) {
7379
c_.t = c.t;
74-
c_.o = subtypes[c.t].invert(c.o);
80+
var subtype = subtypes[c.t];
81+
if (hasDoc && typeof subtype.invertWithDoc === 'function') c_.o = subtype.invertWithDoc(c.o, doc);
82+
else if (typeof subtype.invert === 'function') c_.o = subtype.invert(c.o);
83+
else throw new Error("Subtype '" + c.t + "' is not invertible");
7584
}
7685

7786
if (c.si !== void 0) c_.sd = c.si;
@@ -99,6 +108,15 @@ json.invert = function(op) {
99108
return iop;
100109
};
101110

111+
json.invertWithDoc = function(op, doc) {
112+
var op_ = op.slice().reverse();
113+
var iop = [];
114+
for (var i = 0; i < op_.length; i++) {
115+
iop.push(json.invertComponent(op_[i], doc));
116+
}
117+
return iop;
118+
}
119+
102120
json.checkValidOp = function(op) {
103121
for (var i = 0; i < op.length; i++) {
104122
if (!isArray(op[i].p)) throw new Error('Missing path');

test/json0.coffee

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,27 @@ genTests = (type) ->
222222
assert.deepEqual [{p:[100], si:'hi'}], type.compose [{p:[100], si:'h'}], [{p:[101], si:'i'}]
223223
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'}]}]
224224

225+
describe '#invertWithDoc()', ->
226+
it 'passes the doc to the subtype', ->
227+
op = null
228+
doc = null
229+
230+
type.registerSubtype
231+
name: 'invertible'
232+
invertWithDoc: (o, d) ->
233+
op = o
234+
doc = d
235+
236+
type.invertWithDoc [{p: ['foo', 'bar'], t: 'invertible', o: [{increment: 1}]}], {foo: {bar: 5}}
237+
assert.deepEqual [{increment: 1}], op
238+
assert.deepEqual 5, doc
239+
240+
it 'throws if the subtype does not support inversion', ->
241+
type.registerSubtype
242+
name: 'not-invertible'
243+
244+
assert.throws -> type.invertWithDoc [{p: ['foo'], t: 'not-invertible', o: [{increment: 1}]}], {foo: 5}
245+
225246
it 'moves ops on a moved element with the element', ->
226247
assert.deepEqual [{p:[10], ld:'x'}], type.transform [{p:[4], ld:'x'}], [{p:[4], lm:10}], 'left'
227248
assert.deepEqual [{p:[10, 1], si:'a'}], type.transform [{p:[4, 1], si:'a'}], [{p:[4], lm:10}], 'left'

0 commit comments

Comments
 (0)