Skip to content

Commit 27cbe50

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 27cbe50

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

lib/json0.js

+19-2
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,21 @@ 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+
for (var i = 0; i < c.p.length; i++) {
72+
var key = c.p[i];
73+
doc = doc && doc[key];
74+
}
75+
7176
// handle subtype ops
7277
if (c.t && subtypes[c.t]) {
7378
c_.t = c.t;
74-
c_.o = subtypes[c.t].invert(c.o);
79+
var subtype = subtypes[c.t];
80+
if (doc && typeof subtype.invertWithDoc === 'function') c_.o = subtype.invertWithDoc(c.o, doc);
81+
else if (typeof subtype.invert === 'function') c_.o = subtype.invert(c.o);
82+
else throw new Error("Subtype '" + c.t + "' is not invertible");
7583
}
7684

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

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

test/json0.coffee

+21
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)