lib0 0.2.115-1 → 0.2.115-3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/coverage/tmp/{coverage-27668-1761218485882-0.json → coverage-32703-1763495370274-0.json} +1 -1
- package/delta/abstract.d.ts +2 -2
- package/delta/abstract.d.ts.map +1 -1
- package/delta/d2.d.ts +318 -112
- package/delta/d2.d.ts.map +1 -1
- package/delta/d2.js +837 -155
- package/delta/d2.test.d.ts +6 -1
- package/delta/d2.test.d.ts.map +1 -1
- package/delta/map.d.ts +19 -23
- package/delta/map.d.ts.map +1 -1
- package/delta/map.js +1 -1
- package/delta/node.d.ts +8 -10
- package/delta/node.d.ts.map +1 -1
- package/delta/ops.d.ts +26 -28
- package/delta/ops.d.ts.map +1 -1
- package/delta/t2.d.ts +184 -0
- package/delta/t2.d.ts.map +1 -0
- package/delta/t2.js +890 -0
- package/delta/t3.test.d.ts +19 -0
- package/delta/t3.test.d.ts.map +1 -0
- package/dist/aes-gcm.cjs +2 -2
- package/dist/binding.cjs +1 -1
- package/dist/{broadcastchannel-b4eaea6e.cjs → broadcastchannel-d0c108a2.cjs} +2 -2
- package/dist/{broadcastchannel-b4eaea6e.cjs.map → broadcastchannel-d0c108a2.cjs.map} +1 -1
- package/dist/broadcastchannel.cjs +4 -4
- package/dist/{buffer-adc4e6ea.cjs → buffer-7f6fa8fa.cjs} +3 -3
- package/dist/{buffer-adc4e6ea.cjs.map → buffer-7f6fa8fa.cjs.map} +1 -1
- package/dist/buffer.cjs +3 -3
- package/dist/component.cjs +1 -1
- package/dist/d2.cjs +845 -159
- package/dist/d2.cjs.map +1 -1
- package/dist/{decoding-50b9ce38.cjs → decoding-76e75827.cjs} +2 -2
- package/dist/{decoding-50b9ce38.cjs.map → decoding-76e75827.cjs.map} +1 -1
- package/dist/decoding.cjs +2 -2
- package/dist/delta/abstract.d.ts +2 -2
- package/dist/delta/abstract.d.ts.map +1 -1
- package/dist/delta/d2.d.ts +318 -112
- package/dist/delta/d2.d.ts.map +1 -1
- package/dist/delta/d2.test.d.ts +6 -1
- package/dist/delta/d2.test.d.ts.map +1 -1
- package/dist/delta/map.d.ts +19 -23
- package/dist/delta/map.d.ts.map +1 -1
- package/dist/delta/node.d.ts +8 -10
- package/dist/delta/node.d.ts.map +1 -1
- package/dist/delta/ops.d.ts +26 -28
- package/dist/delta/ops.d.ts.map +1 -1
- package/dist/delta/t2.d.ts +184 -0
- package/dist/delta/t2.d.ts.map +1 -0
- package/dist/delta/t3.test.d.ts +19 -0
- package/dist/delta/t3.test.d.ts.map +1 -0
- package/dist/{dom-2b123630.cjs → dom-f5047a64.cjs} +1 -1
- package/dist/{dom-2b123630.cjs.map → dom-f5047a64.cjs.map} +1 -1
- package/dist/dom.cjs +1 -1
- package/dist/{encoding-7f85922c.cjs → encoding-1a745c43.cjs} +10 -2
- package/dist/encoding-1a745c43.cjs.map +1 -0
- package/dist/encoding.cjs +1 -1
- package/dist/encoding.d.ts +5 -3
- package/dist/encoding.d.ts.map +1 -1
- package/dist/encoding.test.d.ts.map +1 -1
- package/dist/index.cjs +6 -6
- package/dist/jwt.cjs +3 -3
- package/dist/list.test.d.ts +1 -0
- package/dist/list.test.d.ts.map +1 -1
- package/dist/logging.cjs +1 -1
- package/dist/map.cjs +1 -1
- package/dist/map.cjs.map +1 -1
- package/dist/mutex.test.d.ts +3 -0
- package/dist/mutex.test.d.ts.map +1 -0
- package/dist/{prng-004c76e8.cjs → prng-99204216.cjs} +2 -2
- package/dist/{prng-004c76e8.cjs.map → prng-99204216.cjs.map} +1 -1
- package/dist/prng.cjs +4 -4
- package/dist/rabin-gf2-polynomial.cjs +3 -3
- package/dist/rabin-uncached.cjs +3 -3
- package/dist/rabin.cjs +3 -3
- package/dist/schema.cjs +72 -11
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.ts +21 -13
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.test.d.ts +2 -0
- package/dist/schema.test.d.ts.map +1 -1
- package/dist/t2.cjs +932 -0
- package/dist/t2.cjs.map +1 -0
- package/dist/testing.cjs +4 -4
- package/encoding.d.ts +5 -3
- package/encoding.d.ts.map +1 -1
- package/encoding.js +9 -1
- package/encoding.test.d.ts.map +1 -1
- package/list.test.d.ts +1 -0
- package/list.test.d.ts.map +1 -1
- package/mutex.test.d.ts +3 -0
- package/mutex.test.d.ts.map +1 -0
- package/package.json +1 -1
- package/schema.d.ts +21 -13
- package/schema.d.ts.map +1 -1
- package/schema.js +68 -11
- package/schema.test.d.ts +2 -0
- package/schema.test.d.ts.map +1 -1
- package/test.js +3 -1
- package/coverage/tmp/coverage-27667-1761218530660-0.json +0 -1
- package/dist/encoding-7f85922c.cjs.map +0 -1
package/dist/d2.cjs
CHANGED
|
@@ -10,15 +10,28 @@ var _function = require('./function-e7d18feb.cjs');
|
|
|
10
10
|
var schema = require('./schema.cjs');
|
|
11
11
|
var error = require('./error-0c1f634f.cjs');
|
|
12
12
|
var math = require('./math-96d5e8c4.cjs');
|
|
13
|
+
var rabin = require('./rabin.cjs');
|
|
14
|
+
var encoding = require('./encoding-1a745c43.cjs');
|
|
15
|
+
var buffer = require('./buffer-7f6fa8fa.cjs');
|
|
16
|
+
var patience = require('./patience.cjs');
|
|
13
17
|
require('./set-5b47859e.cjs');
|
|
14
18
|
require('./environment-90227ead.cjs');
|
|
15
19
|
require('./map-24d263c0.cjs');
|
|
16
20
|
require('./string-fddc5f8b.cjs');
|
|
17
21
|
require('./conditions-f5c0c102.cjs');
|
|
18
22
|
require('./storage.cjs');
|
|
23
|
+
require('./number-1fb57bba.cjs');
|
|
24
|
+
require('./binary-ac8e39e2.cjs');
|
|
25
|
+
require('./decoding-76e75827.cjs');
|
|
19
26
|
|
|
20
27
|
/**
|
|
21
28
|
* @beta this API is about to change
|
|
29
|
+
*
|
|
30
|
+
* ## Mutability
|
|
31
|
+
*
|
|
32
|
+
* Deltas are mutable by default. But references are often shared, by marking a Delta as "done". You
|
|
33
|
+
* may only modify deltas by applying other deltas to them. Casting a Delta to a DeltaBuilder
|
|
34
|
+
* manually, will likely modify "shared" state.
|
|
22
35
|
*/
|
|
23
36
|
|
|
24
37
|
/**
|
|
@@ -54,8 +67,9 @@ const $attribution = schema.$object({
|
|
|
54
67
|
|
|
55
68
|
/**
|
|
56
69
|
* @typedef {{
|
|
57
|
-
*
|
|
58
|
-
*
|
|
70
|
+
* type: 'delta',
|
|
71
|
+
* name?: string,
|
|
72
|
+
* attrs?: { [Key in string|number]: DeltaAttrOpJSON },
|
|
59
73
|
* children?: Array<DeltaListOpJSON>
|
|
60
74
|
* }} DeltaJSON
|
|
61
75
|
*/
|
|
@@ -68,6 +82,18 @@ const $attribution = schema.$object({
|
|
|
68
82
|
* @typedef {{ type: 'insert', value: any, prevValue?: any, attribution?: Attribution } | { type: 'delete', prevValue?: any, attribution?: Attribution } | { type: 'modify', value: DeltaJSON }} DeltaAttrOpJSON
|
|
69
83
|
*/
|
|
70
84
|
|
|
85
|
+
/**
|
|
86
|
+
* @typedef {TextOp|InsertOp<any>|DeleteOp|RetainOp|ModifyOp<any>} ChildrenOpAny
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @typedef {AttrInsertOp<any>|AttrDeleteOp<any>|AttrModifyOp} AttrOpAny
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @typedef {ChildrenOpAny|AttrOpAny} _OpAny
|
|
95
|
+
*/
|
|
96
|
+
|
|
71
97
|
/**
|
|
72
98
|
* @type {s.Schema<DeltaAttrOpJSON>}
|
|
73
99
|
*/
|
|
@@ -88,7 +114,11 @@ const _cloneAttrs = attrs => attrs == null ? attrs : { ...attrs };
|
|
|
88
114
|
* @param {MaybeDelta} maybeDelta
|
|
89
115
|
* @return {MaybeDelta}
|
|
90
116
|
*/
|
|
91
|
-
const
|
|
117
|
+
const _markMaybeDeltaAsDone = maybeDelta => $deltaAny.check(maybeDelta) ? /** @type {MaybeDelta} */ (maybeDelta.done()) : maybeDelta;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @typedef {unknown & DeltaAny} Q
|
|
121
|
+
*/
|
|
92
122
|
|
|
93
123
|
class TextOp extends list.ListNode {
|
|
94
124
|
/**
|
|
@@ -98,9 +128,31 @@ class TextOp extends list.ListNode {
|
|
|
98
128
|
*/
|
|
99
129
|
constructor (insert, format, attribution) {
|
|
100
130
|
super();
|
|
131
|
+
// Whenever this is modified, make sure to clear _fingerprint
|
|
132
|
+
/**
|
|
133
|
+
* @readonly
|
|
134
|
+
* @type {string}
|
|
135
|
+
*/
|
|
101
136
|
this.insert = insert;
|
|
137
|
+
/**
|
|
138
|
+
* @readonly
|
|
139
|
+
* @type {FormattingAttributes|null}
|
|
140
|
+
*/
|
|
102
141
|
this.format = format;
|
|
103
142
|
this.attribution = attribution;
|
|
143
|
+
/**
|
|
144
|
+
* @type {string?}
|
|
145
|
+
*/
|
|
146
|
+
this._fingerprint = null;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @param {string} newVal
|
|
151
|
+
*/
|
|
152
|
+
_updateInsert (newVal) {
|
|
153
|
+
// @ts-ignore
|
|
154
|
+
this.insert = newVal;
|
|
155
|
+
this._fingerprint = null;
|
|
104
156
|
}
|
|
105
157
|
|
|
106
158
|
/**
|
|
@@ -114,6 +166,14 @@ class TextOp extends list.ListNode {
|
|
|
114
166
|
return this.insert.length
|
|
115
167
|
}
|
|
116
168
|
|
|
169
|
+
get fingerprint () {
|
|
170
|
+
return this._fingerprint || (this._fingerprint = buffer.toBase64(encoding.encode(encoder => {
|
|
171
|
+
encoding.writeVarUint(encoder, 0); // textOp type: 0
|
|
172
|
+
encoding.writeVarString(encoder, this.insert);
|
|
173
|
+
encoding.writeAny(encoder, this.format);
|
|
174
|
+
})))
|
|
175
|
+
}
|
|
176
|
+
|
|
117
177
|
/**
|
|
118
178
|
* Remove a part of the operation (similar to Array.splice)
|
|
119
179
|
*
|
|
@@ -121,7 +181,10 @@ class TextOp extends list.ListNode {
|
|
|
121
181
|
* @param {number} len
|
|
122
182
|
*/
|
|
123
183
|
_splice (offset, len) {
|
|
184
|
+
this._fingerprint = null;
|
|
185
|
+
// @ts-ignore
|
|
124
186
|
this.insert = this.insert.slice(0, offset) + this.insert.slice(offset + len);
|
|
187
|
+
return this
|
|
125
188
|
}
|
|
126
189
|
|
|
127
190
|
/**
|
|
@@ -142,13 +205,13 @@ class TextOp extends list.ListNode {
|
|
|
142
205
|
/**
|
|
143
206
|
* @return {TextOp}
|
|
144
207
|
*/
|
|
145
|
-
clone () {
|
|
146
|
-
return new TextOp(this.insert, _cloneAttrs(this.format), _cloneAttrs(this.attribution))
|
|
208
|
+
clone (start = 0, end = this.length) {
|
|
209
|
+
return new TextOp(this.insert.slice(start, end), _cloneAttrs(this.format), _cloneAttrs(this.attribution))
|
|
147
210
|
}
|
|
148
211
|
}
|
|
149
212
|
|
|
150
213
|
/**
|
|
151
|
-
* @template ArrayContent
|
|
214
|
+
* @template {encoding.AnyEncodable|DeltaAny} ArrayContent
|
|
152
215
|
*/
|
|
153
216
|
class InsertOp extends list.ListNode {
|
|
154
217
|
/**
|
|
@@ -158,9 +221,34 @@ class InsertOp extends list.ListNode {
|
|
|
158
221
|
*/
|
|
159
222
|
constructor (insert, format, attribution) {
|
|
160
223
|
super();
|
|
224
|
+
/**
|
|
225
|
+
* @readonly
|
|
226
|
+
* @type {Array<ArrayContent>}
|
|
227
|
+
*/
|
|
161
228
|
this.insert = insert;
|
|
229
|
+
/**
|
|
230
|
+
* @readonly
|
|
231
|
+
* @type {FormattingAttributes?}
|
|
232
|
+
*/
|
|
162
233
|
this.format = format;
|
|
234
|
+
/**
|
|
235
|
+
* @readonly
|
|
236
|
+
* @type {Attribution?}
|
|
237
|
+
*/
|
|
163
238
|
this.attribution = attribution;
|
|
239
|
+
/**
|
|
240
|
+
* @type {string?}
|
|
241
|
+
*/
|
|
242
|
+
this._fingerprint = null;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* @param {ArrayContent} newVal
|
|
247
|
+
*/
|
|
248
|
+
_updateInsert (newVal) {
|
|
249
|
+
// @ts-ignore
|
|
250
|
+
this.insert = newVal;
|
|
251
|
+
this._fingerprint = null;
|
|
164
252
|
}
|
|
165
253
|
|
|
166
254
|
/**
|
|
@@ -174,6 +262,42 @@ class InsertOp extends list.ListNode {
|
|
|
174
262
|
return this.insert.length
|
|
175
263
|
}
|
|
176
264
|
|
|
265
|
+
/**
|
|
266
|
+
* @param {number} i
|
|
267
|
+
* @return {Extract<ArrayContent,DeltaAny>}
|
|
268
|
+
*/
|
|
269
|
+
_modValue (i) {
|
|
270
|
+
/**
|
|
271
|
+
* @type {any}
|
|
272
|
+
*/
|
|
273
|
+
let d = this.insert[i];
|
|
274
|
+
this._fingerprint = null;
|
|
275
|
+
$deltaAny.expect(d);
|
|
276
|
+
if (d.isDone) {
|
|
277
|
+
// @ts-ignore
|
|
278
|
+
this.insert[i] = (d = clone(d));
|
|
279
|
+
return d
|
|
280
|
+
}
|
|
281
|
+
return d
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
get fingerprint () {
|
|
285
|
+
return this._fingerprint || (this._fingerprint = buffer.toBase64(encoding.encode(encoder => {
|
|
286
|
+
encoding.writeVarUint(encoder, 1); // insertOp type: 1
|
|
287
|
+
encoding.writeVarUint(encoder, this.insert.length);
|
|
288
|
+
this.insert.forEach(ins => {
|
|
289
|
+
if ($deltaAny.check(ins)) {
|
|
290
|
+
encoding.writeUint8(encoder, 0);
|
|
291
|
+
encoding.writeVarString(encoder, ins.fingerprint);
|
|
292
|
+
} else {
|
|
293
|
+
encoding.writeUint8(encoder, 1);
|
|
294
|
+
encoding.writeAny(encoder, ins);
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
encoding.writeAny(encoder, this.format);
|
|
298
|
+
})))
|
|
299
|
+
}
|
|
300
|
+
|
|
177
301
|
/**
|
|
178
302
|
* Remove a part of the operation (similar to Array.splice)
|
|
179
303
|
*
|
|
@@ -181,7 +305,9 @@ class InsertOp extends list.ListNode {
|
|
|
181
305
|
* @param {number} len
|
|
182
306
|
*/
|
|
183
307
|
_splice (offset, len) {
|
|
308
|
+
this._fingerprint = null;
|
|
184
309
|
this.insert.splice(offset, len);
|
|
310
|
+
return this
|
|
185
311
|
}
|
|
186
312
|
|
|
187
313
|
/**
|
|
@@ -202,11 +328,15 @@ class InsertOp extends list.ListNode {
|
|
|
202
328
|
/**
|
|
203
329
|
* @return {InsertOp<ArrayContent>}
|
|
204
330
|
*/
|
|
205
|
-
clone () {
|
|
206
|
-
return new InsertOp(this.insert.slice(), _cloneAttrs(this.format), _cloneAttrs(this.attribution))
|
|
331
|
+
clone (start = 0, end = this.length) {
|
|
332
|
+
return new InsertOp(this.insert.slice(start, end).map(_markMaybeDeltaAsDone), _cloneAttrs(this.format), _cloneAttrs(this.attribution))
|
|
207
333
|
}
|
|
208
334
|
}
|
|
209
335
|
|
|
336
|
+
/**
|
|
337
|
+
* @template {encoding.AnyEncodable|DeltaAny} [Children=never]
|
|
338
|
+
* @template {string} [Text=never]
|
|
339
|
+
*/
|
|
210
340
|
class DeleteOp extends list.ListNode {
|
|
211
341
|
/**
|
|
212
342
|
* @param {number} len
|
|
@@ -214,6 +344,14 @@ class DeleteOp extends list.ListNode {
|
|
|
214
344
|
constructor (len) {
|
|
215
345
|
super();
|
|
216
346
|
this.delete = len;
|
|
347
|
+
/**
|
|
348
|
+
* @type {(Children|Text) extends never ? null : (Delta<any,{},Children,Text>?)}
|
|
349
|
+
*/
|
|
350
|
+
this.prevValue = null;
|
|
351
|
+
/**
|
|
352
|
+
* @type {string|null}
|
|
353
|
+
*/
|
|
354
|
+
this._fingerprint = null;
|
|
217
355
|
}
|
|
218
356
|
|
|
219
357
|
/**
|
|
@@ -227,6 +365,13 @@ class DeleteOp extends list.ListNode {
|
|
|
227
365
|
return 0
|
|
228
366
|
}
|
|
229
367
|
|
|
368
|
+
get fingerprint () {
|
|
369
|
+
return this._fingerprint || (this._fingerprint = buffer.toBase64(encoding.encode(encoder => {
|
|
370
|
+
encoding.writeVarUint(encoder, 2); // deleteOp type: 2
|
|
371
|
+
encoding.writeVarUint(encoder, this.delete);
|
|
372
|
+
})))
|
|
373
|
+
}
|
|
374
|
+
|
|
230
375
|
/**
|
|
231
376
|
* Remove a part of the operation (similar to Array.splice)
|
|
232
377
|
*
|
|
@@ -234,7 +379,10 @@ class DeleteOp extends list.ListNode {
|
|
|
234
379
|
* @param {number} len
|
|
235
380
|
*/
|
|
236
381
|
_splice (_offset, len) {
|
|
382
|
+
this.prevValue = /** @type {any} */ (this.prevValue?.slice(_offset, len) || null);
|
|
383
|
+
this._fingerprint = null;
|
|
237
384
|
this.delete -= len;
|
|
385
|
+
return this
|
|
238
386
|
}
|
|
239
387
|
|
|
240
388
|
/**
|
|
@@ -251,8 +399,8 @@ class DeleteOp extends list.ListNode {
|
|
|
251
399
|
return this.delete === other.delete
|
|
252
400
|
}
|
|
253
401
|
|
|
254
|
-
clone () {
|
|
255
|
-
return new DeleteOp(
|
|
402
|
+
clone (start = 0, end = this.delete) {
|
|
403
|
+
return new DeleteOp(end - start)
|
|
256
404
|
}
|
|
257
405
|
}
|
|
258
406
|
|
|
@@ -264,9 +412,25 @@ class RetainOp extends list.ListNode {
|
|
|
264
412
|
*/
|
|
265
413
|
constructor (retain, format, attribution) {
|
|
266
414
|
super();
|
|
415
|
+
/**
|
|
416
|
+
* @readonly
|
|
417
|
+
* @type {number}
|
|
418
|
+
*/
|
|
267
419
|
this.retain = retain;
|
|
420
|
+
/**
|
|
421
|
+
* @readonly
|
|
422
|
+
* @type {FormattingAttributes?}
|
|
423
|
+
*/
|
|
268
424
|
this.format = format;
|
|
425
|
+
/**
|
|
426
|
+
* @readonly
|
|
427
|
+
* @type {Attribution?}
|
|
428
|
+
*/
|
|
269
429
|
this.attribution = attribution;
|
|
430
|
+
/**
|
|
431
|
+
* @type {string|null}
|
|
432
|
+
*/
|
|
433
|
+
this._fingerprint = null;
|
|
270
434
|
}
|
|
271
435
|
|
|
272
436
|
/**
|
|
@@ -280,6 +444,14 @@ class RetainOp extends list.ListNode {
|
|
|
280
444
|
return this.retain
|
|
281
445
|
}
|
|
282
446
|
|
|
447
|
+
get fingerprint () {
|
|
448
|
+
return this._fingerprint || (this._fingerprint = buffer.toBase64(encoding.encode(encoder => {
|
|
449
|
+
encoding.writeVarUint(encoder, 3); // retainOp type: 3
|
|
450
|
+
encoding.writeVarUint(encoder, this.retain);
|
|
451
|
+
encoding.writeAny(encoder, this.format);
|
|
452
|
+
})))
|
|
453
|
+
}
|
|
454
|
+
|
|
283
455
|
/**
|
|
284
456
|
* Remove a part of the operation (similar to Array.splice)
|
|
285
457
|
*
|
|
@@ -287,7 +459,10 @@ class RetainOp extends list.ListNode {
|
|
|
287
459
|
* @param {number} len
|
|
288
460
|
*/
|
|
289
461
|
_splice (_offset, len) {
|
|
462
|
+
// @ts-ignore
|
|
290
463
|
this.retain -= len;
|
|
464
|
+
this._fingerprint = null;
|
|
465
|
+
return this
|
|
291
466
|
}
|
|
292
467
|
|
|
293
468
|
/**
|
|
@@ -305,15 +480,15 @@ class RetainOp extends list.ListNode {
|
|
|
305
480
|
return this.retain === other.retain && _function.equalityDeep(this.format, other.format) && _function.equalityDeep(this.attribution, other.attribution)
|
|
306
481
|
}
|
|
307
482
|
|
|
308
|
-
clone () {
|
|
309
|
-
return new RetainOp(
|
|
483
|
+
clone (start = 0, end = this.retain) {
|
|
484
|
+
return new RetainOp(end - start, _cloneAttrs(this.format), _cloneAttrs(this.attribution))
|
|
310
485
|
}
|
|
311
486
|
}
|
|
312
487
|
|
|
313
488
|
/**
|
|
314
489
|
* Delta that can be applied on a YType Embed
|
|
315
490
|
*
|
|
316
|
-
* @template {
|
|
491
|
+
* @template {DeltaAny} [DTypes=DeltaAny]
|
|
317
492
|
*/
|
|
318
493
|
class ModifyOp extends list.ListNode {
|
|
319
494
|
/**
|
|
@@ -323,9 +498,25 @@ class ModifyOp extends list.ListNode {
|
|
|
323
498
|
*/
|
|
324
499
|
constructor (delta, format, attribution) {
|
|
325
500
|
super();
|
|
501
|
+
/**
|
|
502
|
+
* @readonly
|
|
503
|
+
* @type {DTypes}
|
|
504
|
+
*/
|
|
326
505
|
this.value = delta;
|
|
506
|
+
/**
|
|
507
|
+
* @readonly
|
|
508
|
+
* @type {FormattingAttributes?}
|
|
509
|
+
*/
|
|
327
510
|
this.format = format;
|
|
511
|
+
/**
|
|
512
|
+
* @readonly
|
|
513
|
+
* @type {Attribution?}
|
|
514
|
+
*/
|
|
328
515
|
this.attribution = attribution;
|
|
516
|
+
/**
|
|
517
|
+
* @type {string|null}
|
|
518
|
+
*/
|
|
519
|
+
this._fingerprint = null;
|
|
329
520
|
}
|
|
330
521
|
|
|
331
522
|
/**
|
|
@@ -339,6 +530,31 @@ class ModifyOp extends list.ListNode {
|
|
|
339
530
|
return 1
|
|
340
531
|
}
|
|
341
532
|
|
|
533
|
+
/**
|
|
534
|
+
* @type {DeltaBuilderAny}
|
|
535
|
+
*/
|
|
536
|
+
get _modValue () {
|
|
537
|
+
/**
|
|
538
|
+
* @type {any}
|
|
539
|
+
*/
|
|
540
|
+
const d = this.value;
|
|
541
|
+
this._fingerprint = null;
|
|
542
|
+
if (d.isDone) {
|
|
543
|
+
// @ts-ignore
|
|
544
|
+
return (this.value = clone(d))
|
|
545
|
+
}
|
|
546
|
+
return d
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
get fingerprint () {
|
|
550
|
+
// don't cache fingerprint because we don't know when delta changes
|
|
551
|
+
return this._fingerprint || (this._fingerprint = buffer.toBase64(encoding.encode(encoder => {
|
|
552
|
+
encoding.writeVarUint(encoder, 4); // modifyOp type: 4
|
|
553
|
+
encoding.writeVarString(encoder, this.value.fingerprint);
|
|
554
|
+
encoding.writeAny(encoder, this.format);
|
|
555
|
+
})))
|
|
556
|
+
}
|
|
557
|
+
|
|
342
558
|
/**
|
|
343
559
|
* Remove a part of the operation (similar to Array.splice)
|
|
344
560
|
*
|
|
@@ -346,6 +562,7 @@ class ModifyOp extends list.ListNode {
|
|
|
346
562
|
* @param {number} _len
|
|
347
563
|
*/
|
|
348
564
|
_splice (_offset, _len) {
|
|
565
|
+
return this
|
|
349
566
|
}
|
|
350
567
|
|
|
351
568
|
/**
|
|
@@ -367,15 +584,15 @@ class ModifyOp extends list.ListNode {
|
|
|
367
584
|
* @return {ModifyOp<DTypes>}
|
|
368
585
|
*/
|
|
369
586
|
clone () {
|
|
370
|
-
return new ModifyOp(this.value.
|
|
587
|
+
return new ModifyOp(/** @type {DTypes} */ (this.value.done()), _cloneAttrs(this.format), _cloneAttrs(this.attribution))
|
|
371
588
|
}
|
|
372
589
|
}
|
|
373
590
|
|
|
374
591
|
/**
|
|
375
|
-
* @template V
|
|
376
|
-
* @template {string|number
|
|
592
|
+
* @template {encoding.AnyEncodable|DeltaAny} V
|
|
593
|
+
* @template {string|number} [K=any]
|
|
377
594
|
*/
|
|
378
|
-
class
|
|
595
|
+
class AttrInsertOp {
|
|
379
596
|
/**
|
|
380
597
|
* @param {K} key
|
|
381
598
|
* @param {V} value
|
|
@@ -384,18 +601,29 @@ class MapInsertOp {
|
|
|
384
601
|
*/
|
|
385
602
|
constructor (key, value, prevValue, attribution) {
|
|
386
603
|
/**
|
|
604
|
+
* @readonly
|
|
387
605
|
* @type {K}
|
|
388
606
|
*/
|
|
389
607
|
this.key = key;
|
|
390
608
|
/**
|
|
609
|
+
* @readonly
|
|
391
610
|
* @type {V}
|
|
392
611
|
*/
|
|
393
612
|
this.value = value;
|
|
394
613
|
/**
|
|
614
|
+
* @readonly
|
|
395
615
|
* @type {V|undefined}
|
|
396
616
|
*/
|
|
397
617
|
this.prevValue = prevValue;
|
|
618
|
+
/**
|
|
619
|
+
* @readonly
|
|
620
|
+
* @type {Attribution?}
|
|
621
|
+
*/
|
|
398
622
|
this.attribution = attribution;
|
|
623
|
+
/**
|
|
624
|
+
* @type {string|null}
|
|
625
|
+
*/
|
|
626
|
+
this._fingerprint = null;
|
|
399
627
|
}
|
|
400
628
|
|
|
401
629
|
/**
|
|
@@ -403,6 +631,36 @@ class MapInsertOp {
|
|
|
403
631
|
*/
|
|
404
632
|
get type () { return 'insert' }
|
|
405
633
|
|
|
634
|
+
/**
|
|
635
|
+
* @type {DeltaBuilderAny}
|
|
636
|
+
*/
|
|
637
|
+
get _modValue () {
|
|
638
|
+
/**
|
|
639
|
+
* @type {any}
|
|
640
|
+
*/
|
|
641
|
+
const v = this.value;
|
|
642
|
+
this._fingerprint = null;
|
|
643
|
+
if ($deltaAny.check(v) && v.isDone) {
|
|
644
|
+
// @ts-ignore
|
|
645
|
+
return (this.value = clone(v))
|
|
646
|
+
}
|
|
647
|
+
return v
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
get fingerprint () {
|
|
651
|
+
return this._fingerprint || (this._fingerprint = buffer.toBase64(encoding.encode(encoder => {
|
|
652
|
+
encoding.writeVarUint(encoder, 5); // map insert type: 5
|
|
653
|
+
encoding.writeAny(encoder, this.key);
|
|
654
|
+
if ($deltaAny.check(this.value)) {
|
|
655
|
+
encoding.writeUint8(encoder, 0);
|
|
656
|
+
encoding.writeVarString(encoder, this.value.fingerprint);
|
|
657
|
+
} else {
|
|
658
|
+
encoding.writeUint8(encoder, 1);
|
|
659
|
+
encoding.writeAny(encoder, this.value);
|
|
660
|
+
}
|
|
661
|
+
})))
|
|
662
|
+
}
|
|
663
|
+
|
|
406
664
|
toJSON () {
|
|
407
665
|
const v = this.value;
|
|
408
666
|
const prevValue = this.prevValue;
|
|
@@ -414,25 +672,25 @@ class MapInsertOp {
|
|
|
414
672
|
}
|
|
415
673
|
|
|
416
674
|
/**
|
|
417
|
-
* @param {
|
|
675
|
+
* @param {AttrInsertOp<V>} other
|
|
418
676
|
*/
|
|
419
677
|
[traits.EqualityTraitSymbol] (other) {
|
|
420
678
|
return this.key === other.key && _function.equalityDeep(this.value, other.value) && _function.equalityDeep(this.attribution, other.attribution)
|
|
421
679
|
}
|
|
422
680
|
|
|
423
681
|
/**
|
|
424
|
-
* @return {
|
|
682
|
+
* @return {AttrInsertOp<V,K>}
|
|
425
683
|
*/
|
|
426
684
|
clone () {
|
|
427
|
-
return new
|
|
685
|
+
return new AttrInsertOp(this.key, _markMaybeDeltaAsDone(this.value), _markMaybeDeltaAsDone(this.prevValue), _cloneAttrs(this.attribution))
|
|
428
686
|
}
|
|
429
687
|
}
|
|
430
688
|
|
|
431
689
|
/**
|
|
432
690
|
* @template V
|
|
433
|
-
* @template [K=string]
|
|
691
|
+
* @template {string|number} [K=string]
|
|
434
692
|
*/
|
|
435
|
-
class
|
|
693
|
+
class AttrDeleteOp {
|
|
436
694
|
/**
|
|
437
695
|
* @param {K} key
|
|
438
696
|
* @param {V|undefined} prevValue
|
|
@@ -448,6 +706,10 @@ class MapDeleteOp {
|
|
|
448
706
|
*/
|
|
449
707
|
this.prevValue = prevValue;
|
|
450
708
|
this.attribution = attribution;
|
|
709
|
+
/**
|
|
710
|
+
* @type {string|null}
|
|
711
|
+
*/
|
|
712
|
+
this._fingerprint = null;
|
|
451
713
|
}
|
|
452
714
|
|
|
453
715
|
get value () { return undefined }
|
|
@@ -457,6 +719,13 @@ class MapDeleteOp {
|
|
|
457
719
|
*/
|
|
458
720
|
get type () { return 'delete' }
|
|
459
721
|
|
|
722
|
+
get fingerprint () {
|
|
723
|
+
return this._fingerprint || (this._fingerprint = buffer.toBase64(encoding.encode(encoder => {
|
|
724
|
+
encoding.writeVarUint(encoder, 6); // map delete type: 6
|
|
725
|
+
encoding.writeAny(encoder, this.key);
|
|
726
|
+
})))
|
|
727
|
+
}
|
|
728
|
+
|
|
460
729
|
/**
|
|
461
730
|
* @return {DeltaAttrOpJSON}
|
|
462
731
|
*/
|
|
@@ -468,35 +737,41 @@ class MapDeleteOp {
|
|
|
468
737
|
}
|
|
469
738
|
|
|
470
739
|
/**
|
|
471
|
-
* @param {
|
|
740
|
+
* @param {AttrDeleteOp<V>} other
|
|
472
741
|
*/
|
|
473
742
|
[traits.EqualityTraitSymbol] (other) {
|
|
474
743
|
return this.key === other.key && _function.equalityDeep(this.attribution, other.attribution)
|
|
475
744
|
}
|
|
476
745
|
|
|
477
746
|
clone () {
|
|
478
|
-
return new
|
|
747
|
+
return new AttrDeleteOp(this.key, _markMaybeDeltaAsDone(this.prevValue), _cloneAttrs(this.attribution))
|
|
479
748
|
}
|
|
480
749
|
}
|
|
481
750
|
|
|
482
751
|
/**
|
|
483
|
-
* @template {DeltaAny} Modifier
|
|
484
|
-
* @template [K=string]
|
|
752
|
+
* @template {DeltaAny} [Modifier=DeltaAny]
|
|
753
|
+
* @template {string|number} [K=string]
|
|
485
754
|
*/
|
|
486
|
-
class
|
|
755
|
+
class AttrModifyOp {
|
|
487
756
|
/**
|
|
488
757
|
* @param {K} key
|
|
489
758
|
* @param {Modifier} delta
|
|
490
759
|
*/
|
|
491
760
|
constructor (key, delta) {
|
|
492
761
|
/**
|
|
762
|
+
* @readonly
|
|
493
763
|
* @type {K}
|
|
494
764
|
*/
|
|
495
765
|
this.key = key;
|
|
496
766
|
/**
|
|
767
|
+
* @readonly
|
|
497
768
|
* @type {Modifier}
|
|
498
769
|
*/
|
|
499
770
|
this.value = delta;
|
|
771
|
+
/**
|
|
772
|
+
* @type {string|null}
|
|
773
|
+
*/
|
|
774
|
+
this._fingerprint = null;
|
|
500
775
|
}
|
|
501
776
|
|
|
502
777
|
/**
|
|
@@ -504,6 +779,27 @@ class MapModifyOp {
|
|
|
504
779
|
*/
|
|
505
780
|
get type () { return 'modify' }
|
|
506
781
|
|
|
782
|
+
get fingerprint () {
|
|
783
|
+
return this._fingerprint || (this._fingerprint = buffer.toBase64(encoding.encode(encoder => {
|
|
784
|
+
encoding.writeVarUint(encoder, 7); // map modify type: 7
|
|
785
|
+
encoding.writeAny(encoder, this.key);
|
|
786
|
+
encoding.writeVarString(encoder, this.value.fingerprint);
|
|
787
|
+
})))
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
/**
|
|
791
|
+
* @return {DeltaBuilder}
|
|
792
|
+
*/
|
|
793
|
+
get _modValue () {
|
|
794
|
+
this._fingerprint = null;
|
|
795
|
+
if (this.value.isDone) {
|
|
796
|
+
// @ts-ignore
|
|
797
|
+
this.value = /** @type {any} */ (clone(this.value));
|
|
798
|
+
}
|
|
799
|
+
// @ts-ignore
|
|
800
|
+
return this.value
|
|
801
|
+
}
|
|
802
|
+
|
|
507
803
|
/**
|
|
508
804
|
* @return {DeltaAttrOpJSON}
|
|
509
805
|
*/
|
|
@@ -515,38 +811,38 @@ class MapModifyOp {
|
|
|
515
811
|
}
|
|
516
812
|
|
|
517
813
|
/**
|
|
518
|
-
* @param {
|
|
814
|
+
* @param {AttrModifyOp<Modifier>} other
|
|
519
815
|
*/
|
|
520
816
|
[traits.EqualityTraitSymbol] (other) {
|
|
521
817
|
return this.key === other.key && this.value[traits.EqualityTraitSymbol](other.value)
|
|
522
818
|
}
|
|
523
819
|
|
|
524
820
|
/**
|
|
525
|
-
* @return {
|
|
821
|
+
* @return {AttrModifyOp<Modifier,K>}
|
|
526
822
|
*/
|
|
527
823
|
clone () {
|
|
528
|
-
return new
|
|
824
|
+
return new AttrModifyOp(this.key, /** @type {Modifier} */ (this.value.done()))
|
|
529
825
|
}
|
|
530
826
|
}
|
|
531
827
|
|
|
532
828
|
/**
|
|
533
|
-
* @type {s.Schema<
|
|
829
|
+
* @type {s.Schema<AttrDeleteOp<any> | DeleteOp>}
|
|
534
830
|
*/
|
|
535
|
-
const $deleteOp = schema.$custom(o => o != null && (o.constructor === DeleteOp || o.constructor ===
|
|
831
|
+
const $deleteOp = schema.$custom(o => o != null && (o.constructor === DeleteOp || o.constructor === AttrDeleteOp));
|
|
536
832
|
|
|
537
833
|
/**
|
|
538
|
-
* @type {s.Schema<
|
|
834
|
+
* @type {s.Schema<AttrInsertOp<any> | InsertOp<any>>}
|
|
539
835
|
*/
|
|
540
|
-
const $insertOp = schema.$custom(o => o != null && (o.constructor ===
|
|
836
|
+
const $insertOp = schema.$custom(o => o != null && (o.constructor === AttrInsertOp || o.constructor === InsertOp));
|
|
541
837
|
|
|
542
838
|
/**
|
|
543
|
-
* @template Content
|
|
839
|
+
* @template {encoding.AnyEncodable|DeltaAny} Content
|
|
544
840
|
* @param {s.Schema<Content>} $content
|
|
545
|
-
* @return {s.Schema<
|
|
841
|
+
* @return {s.Schema<AttrInsertOp<Content> | InsertOp<Content>>}
|
|
546
842
|
*/
|
|
547
843
|
const $insertOpWith = $content => schema.$custom(o =>
|
|
548
844
|
o != null && (
|
|
549
|
-
(o.constructor ===
|
|
845
|
+
(o.constructor === AttrInsertOp && $content.check(/** @type {AttrInsertOp<Content>} */ (o).value)) ||
|
|
550
846
|
(o.constructor === InsertOp && /** @type {InsertOp<Content>} */ (o).insert.every(ins => $content.check(ins)))
|
|
551
847
|
)
|
|
552
848
|
);
|
|
@@ -562,18 +858,18 @@ const $textOp = schema.$constructedBy(TextOp);
|
|
|
562
858
|
const $retainOp = schema.$constructedBy(RetainOp);
|
|
563
859
|
|
|
564
860
|
/**
|
|
565
|
-
* @type {s.Schema<
|
|
861
|
+
* @type {s.Schema<AttrModifyOp | ModifyOp>}
|
|
566
862
|
*/
|
|
567
|
-
const $modifyOp = schema.$custom(o => o != null && (o.constructor ===
|
|
863
|
+
const $modifyOp = schema.$custom(o => o != null && (o.constructor === AttrModifyOp || o.constructor === ModifyOp));
|
|
568
864
|
|
|
569
865
|
/**
|
|
570
866
|
* @template {DeltaAny} Modify
|
|
571
867
|
* @param {s.Schema<Modify>} $content
|
|
572
|
-
* @return {s.Schema<
|
|
868
|
+
* @return {s.Schema<AttrModifyOp<Modify> | ModifyOp<Modify>>}
|
|
573
869
|
*/
|
|
574
870
|
const $modifyOpWith = $content => schema.$custom(o =>
|
|
575
871
|
o != null && (
|
|
576
|
-
(o.constructor ===
|
|
872
|
+
(o.constructor === AttrModifyOp && $content.check(/** @type {AttrModifyOp<Modify>} */ (o).value)) ||
|
|
577
873
|
(o.constructor === ModifyOp && $content.check(/** @type {ModifyOp<Modify>} */ (o).value))
|
|
578
874
|
)
|
|
579
875
|
);
|
|
@@ -589,8 +885,8 @@ const $anyOp = schema.$union($insertOp, $deleteOp, $textOp, $modifyOp);
|
|
|
589
885
|
*/
|
|
590
886
|
|
|
591
887
|
/**
|
|
592
|
-
* @template {{[Key in string|number
|
|
593
|
-
* @template {string|number
|
|
888
|
+
* @template {{[Key in string|number]: any}} Attrs
|
|
889
|
+
* @template {string|number} Key
|
|
594
890
|
* @template {any} Val
|
|
595
891
|
* @typedef {{ [K in (Key | keyof Attrs)]: (unknown extends Attrs[K] ? never : Attrs[K]) | (Key extends K ? Val : never) }} AddToAttrs
|
|
596
892
|
*/
|
|
@@ -608,29 +904,20 @@ const $anyOp = schema.$union($insertOp, $deleteOp, $textOp, $modifyOp);
|
|
|
608
904
|
|
|
609
905
|
/**
|
|
610
906
|
* @template {s.Schema<Delta<any,any,any,any,any>>|null} Schema
|
|
611
|
-
* @typedef {_AnyToNull<Schema> extends null ? Delta<any,{[key:string|number
|
|
907
|
+
* @typedef {_AnyToNull<Schema> extends null ? Delta<any,{[key:string|number]:any},any,string> : (Schema extends s.Schema<infer D> ? D : never)} AllowedDeltaFromSchema
|
|
612
908
|
*/
|
|
613
909
|
|
|
614
910
|
/**
|
|
615
|
-
* @typedef {Delta<any,{ [k:string]: any },any,any,any>} DeltaAny
|
|
911
|
+
* @typedef {Delta<any,{ [k:string|number]: any },any,any,any>} DeltaAny
|
|
616
912
|
*/
|
|
617
|
-
|
|
618
|
-
// note: simply copy the values from Delta.attrs as the parameter of the function
|
|
619
913
|
/**
|
|
620
|
-
* @
|
|
621
|
-
* @param {Delta<any,Attrs,any,any,any>} d
|
|
622
|
-
* @param {(v:{ [K in keyof Attrs]: MapInsertOp<Attrs[K],K>|MapDeleteOp<Attrs[K],K>|(Delta extends Attrs[K] ? MapModifyOp<Extract<Attrs[K],Delta>,K> : never) }[keyof Attrs])=>any} handler
|
|
914
|
+
* @typedef {DeltaBuilder<any,{ [k:string|number]: any },any,any,any>} DeltaBuilderAny
|
|
623
915
|
*/
|
|
624
|
-
const forEachAttr = (d, handler) => {
|
|
625
|
-
for (const k in d.attrs) {
|
|
626
|
-
handler(/** @type {any} */ (d.attrs[k]));
|
|
627
|
-
}
|
|
628
|
-
};
|
|
629
916
|
|
|
630
917
|
/**
|
|
631
918
|
* @template {string} [NodeName=any]
|
|
632
|
-
* @template {{[
|
|
633
|
-
* @template {
|
|
919
|
+
* @template {{[k:string|number]:any}} [Attrs={}]
|
|
920
|
+
* @template {encoding.AnyEncodable|DeltaAny|never} [Children=never]
|
|
634
921
|
* @template {string|never} [Text=never]
|
|
635
922
|
* @template {s.Schema<Delta<any,any,any,any,any>>|null} [Schema=any]
|
|
636
923
|
*/
|
|
@@ -643,7 +930,9 @@ class Delta {
|
|
|
643
930
|
this.name = name || null;
|
|
644
931
|
this.$schema = $schema || null;
|
|
645
932
|
/**
|
|
646
|
-
* @type {{ [K in keyof Attrs]?:
|
|
933
|
+
* @type {{ [K in keyof Attrs]?: K extends string|number ? (AttrInsertOp<Attrs[K],K>|AttrDeleteOp<Attrs[K],K>|(Delta extends Attrs[K] ? AttrModifyOp<Extract<Attrs[K],DeltaAny>,K> : never)) : never }
|
|
934
|
+
* & { [Symbol.iterator]: () => Iterator<{ [K in keyof Attrs]: K extends string|number ? (AttrInsertOp<Attrs[K],K>|AttrDeleteOp<Attrs[K],K>|(Delta extends Attrs[K] ? AttrModifyOp<Extract<Attrs[K],DeltaAny>,K> : never)) : never }[keyof Attrs]> }
|
|
935
|
+
* }
|
|
647
936
|
*/
|
|
648
937
|
this.attrs = /** @type {any} */ ({
|
|
649
938
|
* [Symbol.iterator] () {
|
|
@@ -663,10 +952,50 @@ class Delta {
|
|
|
663
952
|
* >}
|
|
664
953
|
*/
|
|
665
954
|
this.children = /** @type {any} */ (list.create());
|
|
955
|
+
this.childCnt = 0;
|
|
666
956
|
/**
|
|
667
957
|
* @type {any}
|
|
668
958
|
*/
|
|
669
959
|
this.origin = null;
|
|
960
|
+
/**
|
|
961
|
+
* @type {string|null}
|
|
962
|
+
*/
|
|
963
|
+
this._fingerprint = null;
|
|
964
|
+
this.isDone = false;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
/**
|
|
968
|
+
* @type {string}
|
|
969
|
+
*/
|
|
970
|
+
get fingerprint () {
|
|
971
|
+
return this._fingerprint || (this._fingerprint = buffer.toBase64(encoding.encode(encoder => {
|
|
972
|
+
encoding.writeAny(encoder, this.name);
|
|
973
|
+
/**
|
|
974
|
+
* @type {Array<number|string>}
|
|
975
|
+
*/
|
|
976
|
+
const keys = [];
|
|
977
|
+
for (const attr of this.attrs) {
|
|
978
|
+
keys.push(attr.key);
|
|
979
|
+
}
|
|
980
|
+
keys.sort((a, b) => {
|
|
981
|
+
const aIsString = schema.$string.check(a);
|
|
982
|
+
const bIsString = schema.$string.check(b);
|
|
983
|
+
// numbers first
|
|
984
|
+
// in ascending order
|
|
985
|
+
return (aIsString && bIsString)
|
|
986
|
+
? a.localeCompare(b)
|
|
987
|
+
: (aIsString ? 1 : (bIsString ? -1 : (a - b)))
|
|
988
|
+
});
|
|
989
|
+
encoding.writeVarUint(encoder, keys.length);
|
|
990
|
+
for (const key of keys) {
|
|
991
|
+
encoding.writeVarString(encoder, /** @type {any} */ (this.attrs[/** @type {keyof Attrs} */ (key)]).fingerprint);
|
|
992
|
+
}
|
|
993
|
+
encoding.writeVarUint(encoder, this.children.len);
|
|
994
|
+
for (const child of this.children) {
|
|
995
|
+
encoding.writeVarString(encoder, child.fingerprint);
|
|
996
|
+
}
|
|
997
|
+
return buffer.toBase64(rabin.fingerprint(rabin.StandardIrreducible128, encoding.toUint8Array(encoder)))
|
|
998
|
+
})))
|
|
670
999
|
}
|
|
671
1000
|
|
|
672
1001
|
isEmpty () {
|
|
@@ -677,6 +1006,7 @@ class Delta {
|
|
|
677
1006
|
* @return {DeltaJSON}
|
|
678
1007
|
*/
|
|
679
1008
|
toJSON () {
|
|
1009
|
+
const name = this.name;
|
|
680
1010
|
/**
|
|
681
1011
|
* @type {any}
|
|
682
1012
|
*/
|
|
@@ -685,14 +1015,15 @@ class Delta {
|
|
|
685
1015
|
* @type {any}
|
|
686
1016
|
*/
|
|
687
1017
|
const children = [];
|
|
688
|
-
|
|
1018
|
+
for (const attr of this.attrs) {
|
|
689
1019
|
attrs[attr.key] = attr.toJSON();
|
|
690
|
-
}
|
|
1020
|
+
}
|
|
691
1021
|
this.children.forEach(val => {
|
|
692
1022
|
children.push(val.toJSON());
|
|
693
1023
|
});
|
|
694
1024
|
return object.assign(
|
|
695
|
-
|
|
1025
|
+
{ type: /** @type {'delta'} */ ('delta') },
|
|
1026
|
+
(name != null ? { name } : {}),
|
|
696
1027
|
(object.isEmpty(attrs) ? {} : { attrs }),
|
|
697
1028
|
(children.length > 0 ? { children } : {})
|
|
698
1029
|
)
|
|
@@ -707,36 +1038,139 @@ class Delta {
|
|
|
707
1038
|
}
|
|
708
1039
|
|
|
709
1040
|
/**
|
|
710
|
-
* @
|
|
1041
|
+
* @param {any} other
|
|
1042
|
+
* @return {boolean}
|
|
711
1043
|
*/
|
|
712
|
-
|
|
1044
|
+
[traits.EqualityTraitSymbol] (other) {
|
|
1045
|
+
// @todo it is only necessary to compare finrerprints OR do a deep equality check
|
|
1046
|
+
return this.name === other.name && _function.equalityDeep(this.attrs, other.attrs) && _function.equalityDeep(this.children, other.children) && this.childCnt === other.childCnt && this.fingerprint === other.fingerprint
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
/**
|
|
1050
|
+
* @param {number} start
|
|
1051
|
+
* @param {number} end
|
|
1052
|
+
* @return {Delta<NodeName,Attrs,Children,Text,Schema>}
|
|
1053
|
+
*/
|
|
1054
|
+
slice (start = 0, end = this.childCnt) {
|
|
1055
|
+
const cpy = /** @type {DeltaAny} */ (new DeltaBuilder(/** @type {any} */ (this.name), this.$schema));
|
|
1056
|
+
cpy.origin = this.origin;
|
|
1057
|
+
// copy attrs
|
|
1058
|
+
for (const op of this.attrs) {
|
|
1059
|
+
cpy.attrs[op.key] = /** @type {any} */ (op.clone());
|
|
1060
|
+
}
|
|
1061
|
+
// copy children
|
|
1062
|
+
const slicedLen = end - start;
|
|
1063
|
+
let remainingLen = slicedLen;
|
|
713
1064
|
/**
|
|
714
|
-
* @type {
|
|
1065
|
+
* @type {ChildrenOpAny?}
|
|
715
1066
|
*/
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
1067
|
+
let currNode = this.children.start;
|
|
1068
|
+
let currNodeOffset = 0;
|
|
1069
|
+
while (start > 0 && currNode != null) {
|
|
1070
|
+
if (currNode.length <= start) {
|
|
1071
|
+
start -= currNode.length;
|
|
1072
|
+
currNode = currNode.next;
|
|
1073
|
+
} else {
|
|
1074
|
+
currNodeOffset = start;
|
|
1075
|
+
start = 0;
|
|
1076
|
+
}
|
|
720
1077
|
}
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
1078
|
+
if (currNodeOffset > 0 && currNode) {
|
|
1079
|
+
const ncpy = currNode.clone(currNodeOffset, currNodeOffset + math.min(remainingLen, currNode.length - currNodeOffset));
|
|
1080
|
+
list.pushEnd(cpy.children, ncpy);
|
|
1081
|
+
remainingLen -= ncpy.length;
|
|
1082
|
+
currNode = currNode.next;
|
|
1083
|
+
}
|
|
1084
|
+
while (currNode != null && currNode.length <= remainingLen) {
|
|
1085
|
+
list.pushEnd(cpy.children, currNode.clone());
|
|
1086
|
+
currNode = currNode.next;
|
|
1087
|
+
}
|
|
1088
|
+
if (currNode != null && remainingLen > 0) {
|
|
1089
|
+
list.pushEnd(cpy.children, currNode.clone(0, remainingLen));
|
|
1090
|
+
}
|
|
1091
|
+
cpy.childCnt = slicedLen - remainingLen;
|
|
1092
|
+
// @ts-ignore
|
|
1093
|
+
return cpy
|
|
725
1094
|
}
|
|
726
1095
|
|
|
727
1096
|
/**
|
|
728
|
-
*
|
|
729
|
-
*
|
|
1097
|
+
* Mark this delta as done and perform some cleanup (e.g. remove appended retains without
|
|
1098
|
+
* formats&attributions). In the future, there might be additional merge operations that can be
|
|
1099
|
+
* performed to result in smaller deltas. Set `markAsDone=false` to only perform the cleanup.
|
|
1100
|
+
*
|
|
1101
|
+
* @return {Delta<NodeName,Attrs,Children,Text,Schema>}
|
|
730
1102
|
*/
|
|
731
|
-
|
|
732
|
-
|
|
1103
|
+
done (markAsDone = true) {
|
|
1104
|
+
if (!this.isDone) {
|
|
1105
|
+
this.isDone = markAsDone;
|
|
1106
|
+
const cs = this.children;
|
|
1107
|
+
for (let end = cs.end; end !== null && $retainOp.check(end) && end.format == null && end.attribution == null; end = cs.end) {
|
|
1108
|
+
this.childCnt -= end.length;
|
|
1109
|
+
list.popEnd(cs);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
return this
|
|
733
1113
|
}
|
|
734
1114
|
}
|
|
735
1115
|
|
|
1116
|
+
/**
|
|
1117
|
+
* @template {DeltaAny} D
|
|
1118
|
+
* @param {D} d
|
|
1119
|
+
* @return {D extends Delta<infer NodeName,infer Attrs,infer Children,infer Text,infer Schema> ? DeltaBuilder<NodeName,Attrs,Children,Text,Schema> : never}
|
|
1120
|
+
*/
|
|
1121
|
+
const clone = d => /** @type {any} */ (d.slice(0, d.childCnt));
|
|
1122
|
+
|
|
1123
|
+
/**
|
|
1124
|
+
* Try merging this op with the previous op
|
|
1125
|
+
* @param {list.List<any>} parent
|
|
1126
|
+
* @param {InsertOp<any>|RetainOp|DeleteOp|TextOp|ModifyOp<any>} op
|
|
1127
|
+
*/
|
|
1128
|
+
const tryMergeWithPrev = (parent, op) => {
|
|
1129
|
+
const prevOp = op.prev;
|
|
1130
|
+
if (
|
|
1131
|
+
prevOp?.constructor !== op.constructor ||
|
|
1132
|
+
(
|
|
1133
|
+
(!$deleteOp.check(op) && !$modifyOp.check(op)) && (!_function.equalityDeep(op.format, /** @type {InsertOp<any>} */ (prevOp).format) || !_function.equalityDeep(op.attribution, /** @type {InsertOp<any>} */ (prevOp).attribution))
|
|
1134
|
+
)
|
|
1135
|
+
) {
|
|
1136
|
+
// constructor mismatch or format/attribution mismatch
|
|
1137
|
+
return
|
|
1138
|
+
}
|
|
1139
|
+
// can be merged
|
|
1140
|
+
if ($insertOp.check(op)) {
|
|
1141
|
+
/** @type {InsertOp<any>} */ (prevOp).insert.push(...op.insert);
|
|
1142
|
+
} else if ($retainOp.check(op)) {
|
|
1143
|
+
// @ts-ignore
|
|
1144
|
+
/** @type {RetainOp} */ (prevOp).retain += op.retain;
|
|
1145
|
+
} else if ($deleteOp.check(op)) {
|
|
1146
|
+
/** @type {DeleteOp} */ (prevOp).delete += op.delete;
|
|
1147
|
+
} else if ($textOp.check(op)) {
|
|
1148
|
+
/** @type {TextOp} */ (prevOp)._updateInsert(/** @type {TextOp} */ (prevOp).insert + op.insert);
|
|
1149
|
+
} else {
|
|
1150
|
+
error.unexpectedCase();
|
|
1151
|
+
}
|
|
1152
|
+
list.remove(parent, op);
|
|
1153
|
+
};
|
|
1154
|
+
|
|
1155
|
+
/**
|
|
1156
|
+
* Ensures that the delta can be edited. clears _fingerprint cache.
|
|
1157
|
+
*
|
|
1158
|
+
* @param {any} d
|
|
1159
|
+
*/
|
|
1160
|
+
const modDeltaCheck = d => {
|
|
1161
|
+
if (d.isDone) {
|
|
1162
|
+
/**
|
|
1163
|
+
* You tried to modify a delta after it has been marked as "done".
|
|
1164
|
+
*/
|
|
1165
|
+
throw error.create("Readonly Delta can't be modified")
|
|
1166
|
+
}
|
|
1167
|
+
d._fingerprint = null;
|
|
1168
|
+
};
|
|
1169
|
+
|
|
736
1170
|
/**
|
|
737
1171
|
* @template {string} [NodeName=any]
|
|
738
|
-
* @template {{[key:string|number
|
|
739
|
-
* @template {
|
|
1172
|
+
* @template {{[key:string|number]:any}} [Attrs={}]
|
|
1173
|
+
* @template {encoding.AnyEncodable|DeltaAny|never} [Children=never]
|
|
740
1174
|
* @template {string|never} [Text=never]
|
|
741
1175
|
* @template {s.Schema<Delta<any,any,any,any,any>>|null} [Schema=any]
|
|
742
1176
|
* @extends {Delta<NodeName,Attrs,Children,Text,Schema>}
|
|
@@ -762,6 +1196,7 @@ class DeltaBuilder extends Delta {
|
|
|
762
1196
|
* @param {Attribution?} attribution
|
|
763
1197
|
*/
|
|
764
1198
|
useAttribution (attribution) {
|
|
1199
|
+
modDeltaCheck(this);
|
|
765
1200
|
this.usedAttribution = attribution;
|
|
766
1201
|
return this
|
|
767
1202
|
}
|
|
@@ -771,6 +1206,7 @@ class DeltaBuilder extends Delta {
|
|
|
771
1206
|
* @return {this}
|
|
772
1207
|
*/
|
|
773
1208
|
useAttributes (attributes) {
|
|
1209
|
+
modDeltaCheck(this);
|
|
774
1210
|
this.usedAttributes = attributes;
|
|
775
1211
|
return this
|
|
776
1212
|
}
|
|
@@ -780,6 +1216,7 @@ class DeltaBuilder extends Delta {
|
|
|
780
1216
|
* @param {any} value
|
|
781
1217
|
*/
|
|
782
1218
|
updateUsedAttributes (name, value) {
|
|
1219
|
+
modDeltaCheck(this);
|
|
783
1220
|
if (value == null) {
|
|
784
1221
|
this.usedAttributes = object.assign({}, this.usedAttributes);
|
|
785
1222
|
delete this.usedAttributes?.[name];
|
|
@@ -799,6 +1236,7 @@ class DeltaBuilder extends Delta {
|
|
|
799
1236
|
* @param {Attribution[NAME]?} value
|
|
800
1237
|
*/
|
|
801
1238
|
updateUsedAttribution (name, value) {
|
|
1239
|
+
modDeltaCheck(this);
|
|
802
1240
|
if (value == null) {
|
|
803
1241
|
this.usedAttribution = object.assign({}, this.usedAttribution);
|
|
804
1242
|
delete this.usedAttribution?.[name];
|
|
@@ -821,11 +1259,12 @@ class DeltaBuilder extends Delta {
|
|
|
821
1259
|
* NodeName,
|
|
822
1260
|
* Attrs,
|
|
823
1261
|
* Exclude<NewContent,string>[number]|Children,
|
|
824
|
-
* (Extract<NewContent,string>|Text) extends
|
|
1262
|
+
* (Extract<NewContent,string>|Text) extends never ? never : string,
|
|
825
1263
|
* Schema
|
|
826
1264
|
* >}
|
|
827
1265
|
*/
|
|
828
1266
|
insert (insert, formatting = null, attribution = null) {
|
|
1267
|
+
modDeltaCheck(this);
|
|
829
1268
|
const mergedAttributes = mergeAttrs(this.usedAttributes, formatting);
|
|
830
1269
|
const mergedAttribution = mergeAttrs(this.usedAttribution, attribution);
|
|
831
1270
|
/**
|
|
@@ -835,16 +1274,20 @@ class DeltaBuilder extends Delta {
|
|
|
835
1274
|
const end = this.children.end;
|
|
836
1275
|
if (schema.$string.check(insert)) {
|
|
837
1276
|
if ($textOp.check(end) && checkMergedEquals(end)) {
|
|
838
|
-
end.insert
|
|
1277
|
+
end._updateInsert(end.insert + insert);
|
|
839
1278
|
} else if (insert.length > 0) {
|
|
840
1279
|
list.pushEnd(this.children, new TextOp(insert, object.isEmpty(mergedAttributes) ? null : mergedAttributes, object.isEmpty(mergedAttribution) ? null : mergedAttribution));
|
|
841
1280
|
}
|
|
1281
|
+
this.childCnt += insert.length;
|
|
842
1282
|
} else if (array$1.isArray(insert)) {
|
|
843
1283
|
if ($insertOp.check(end) && checkMergedEquals(end)) {
|
|
1284
|
+
// @ts-ignore
|
|
844
1285
|
end.insert.push(...insert);
|
|
1286
|
+
end._fingerprint = null;
|
|
845
1287
|
} else if (insert.length > 0) {
|
|
846
1288
|
list.pushEnd(this.children, new InsertOp(insert, object.isEmpty(mergedAttributes) ? null : mergedAttributes, object.isEmpty(mergedAttribution) ? null : mergedAttribution));
|
|
847
1289
|
}
|
|
1290
|
+
this.childCnt += insert.length;
|
|
848
1291
|
}
|
|
849
1292
|
return /** @type {any} */ (this)
|
|
850
1293
|
}
|
|
@@ -863,9 +1306,11 @@ class DeltaBuilder extends Delta {
|
|
|
863
1306
|
* >}
|
|
864
1307
|
*/
|
|
865
1308
|
modify (modify, formatting = null, attribution = null) {
|
|
1309
|
+
modDeltaCheck(this);
|
|
866
1310
|
const mergedAttributes = mergeAttrs(this.usedAttributes, formatting);
|
|
867
1311
|
const mergedAttribution = mergeAttrs(this.usedAttribution, attribution);
|
|
868
1312
|
list.pushEnd(this.children, new ModifyOp(modify, object.isEmpty(mergedAttributes) ? null : mergedAttributes, object.isEmpty(mergedAttribution) ? null : mergedAttribution));
|
|
1313
|
+
this.childCnt += 1;
|
|
869
1314
|
return /** @type {any} */ (this)
|
|
870
1315
|
}
|
|
871
1316
|
|
|
@@ -875,14 +1320,17 @@ class DeltaBuilder extends Delta {
|
|
|
875
1320
|
* @param {Attribution?} [attribution]
|
|
876
1321
|
*/
|
|
877
1322
|
retain (len, format = null, attribution = null) {
|
|
1323
|
+
modDeltaCheck(this);
|
|
878
1324
|
const mergedFormats = mergeAttrs(this.usedAttributes, format);
|
|
879
1325
|
const mergedAttribution = mergeAttrs(this.usedAttribution, attribution);
|
|
880
1326
|
const lastOp = /** @type {RetainOp|InsertOp<any>} */ (this.children.end);
|
|
881
1327
|
if (lastOp instanceof RetainOp && _function.equalityDeep(mergedFormats, lastOp.format) && _function.equalityDeep(mergedAttribution, lastOp.attribution)) {
|
|
1328
|
+
// @ts-ignore
|
|
882
1329
|
lastOp.retain += len;
|
|
883
1330
|
} else if (len > 0) {
|
|
884
1331
|
list.pushEnd(this.children, new RetainOp(len, mergedFormats, mergedAttribution));
|
|
885
1332
|
}
|
|
1333
|
+
this.childCnt += len;
|
|
886
1334
|
return this
|
|
887
1335
|
}
|
|
888
1336
|
|
|
@@ -890,12 +1338,14 @@ class DeltaBuilder extends Delta {
|
|
|
890
1338
|
* @param {number} len
|
|
891
1339
|
*/
|
|
892
1340
|
delete (len) {
|
|
1341
|
+
modDeltaCheck(this);
|
|
893
1342
|
const lastOp = /** @type {DeleteOp|InsertOp<any>} */ (this.children.end);
|
|
894
1343
|
if (lastOp instanceof DeleteOp) {
|
|
895
1344
|
lastOp.delete += len;
|
|
896
1345
|
} else if (len > 0) {
|
|
897
1346
|
list.pushEnd(this.children, new DeleteOp(len));
|
|
898
1347
|
}
|
|
1348
|
+
this.childCnt += len;
|
|
899
1349
|
return this
|
|
900
1350
|
}
|
|
901
1351
|
|
|
@@ -915,7 +1365,8 @@ class DeltaBuilder extends Delta {
|
|
|
915
1365
|
* >}
|
|
916
1366
|
*/
|
|
917
1367
|
set (key, val, attribution = null, prevValue) {
|
|
918
|
-
|
|
1368
|
+
modDeltaCheck(this);
|
|
1369
|
+
this.attrs[key] = /** @type {any} */ (new AttrInsertOp(key, val, prevValue, mergeAttrs(this.usedAttribution, attribution)));
|
|
919
1370
|
return /** @type {any} */ (this)
|
|
920
1371
|
}
|
|
921
1372
|
|
|
@@ -932,6 +1383,7 @@ class DeltaBuilder extends Delta {
|
|
|
932
1383
|
* >}
|
|
933
1384
|
*/
|
|
934
1385
|
setMany (attrs, attribution = null) {
|
|
1386
|
+
modDeltaCheck(this);
|
|
935
1387
|
for (const k in attrs) {
|
|
936
1388
|
this.set(/** @type {any} */ (k), attrs[k], attribution);
|
|
937
1389
|
}
|
|
@@ -952,7 +1404,8 @@ class DeltaBuilder extends Delta {
|
|
|
952
1404
|
* >}
|
|
953
1405
|
*/
|
|
954
1406
|
unset (key, attribution = null, prevValue) {
|
|
955
|
-
|
|
1407
|
+
modDeltaCheck(this);
|
|
1408
|
+
this.attrs[key] = /** @type {any} */ (new AttrDeleteOp(key, prevValue, mergeAttrs(this.usedAttribution, attribution)));
|
|
956
1409
|
return /** @type {any} */ (this)
|
|
957
1410
|
}
|
|
958
1411
|
|
|
@@ -970,7 +1423,8 @@ class DeltaBuilder extends Delta {
|
|
|
970
1423
|
* >}
|
|
971
1424
|
*/
|
|
972
1425
|
update (key, modify) {
|
|
973
|
-
this
|
|
1426
|
+
modDeltaCheck(this);
|
|
1427
|
+
this.attrs[key] = /** @type {any} */ (new AttrModifyOp(key, modify));
|
|
974
1428
|
return /** @type {any} */ (this)
|
|
975
1429
|
}
|
|
976
1430
|
|
|
@@ -978,37 +1432,64 @@ class DeltaBuilder extends Delta {
|
|
|
978
1432
|
* @param {Delta<NodeName,Attrs,Children,Text,any>} other
|
|
979
1433
|
*/
|
|
980
1434
|
apply (other) {
|
|
1435
|
+
modDeltaCheck(this);
|
|
981
1436
|
this.$schema?.expect(other);
|
|
982
|
-
|
|
983
|
-
|
|
1437
|
+
// apply attrs
|
|
1438
|
+
for (let op of other.attrs) {
|
|
1439
|
+
const c = /** @type {AttrInsertOp<any,any>|AttrDeleteOp<any>|AttrModifyOp<any,any>} */ (this.attrs[op.key]);
|
|
984
1440
|
if ($modifyOp.check(op)) {
|
|
985
1441
|
if ($deltaAny.check(c?.value)) {
|
|
986
|
-
|
|
1442
|
+
c._modValue.apply(op.value);
|
|
987
1443
|
} else {
|
|
988
1444
|
// then this is a simple modify
|
|
989
|
-
|
|
1445
|
+
// @ts-ignore
|
|
1446
|
+
this.attrs[op.key] = op.clone();
|
|
990
1447
|
}
|
|
991
1448
|
} else {
|
|
992
|
-
/** @type {
|
|
993
|
-
|
|
1449
|
+
op = /** @type {any} */ (op.clone());
|
|
1450
|
+
// @ts-ignore
|
|
1451
|
+
op.prevValue = c?.value;
|
|
1452
|
+
// @ts-ignore
|
|
1453
|
+
this.attrs[op.key] = op;
|
|
994
1454
|
}
|
|
995
|
-
}
|
|
1455
|
+
}
|
|
996
1456
|
// apply children
|
|
1457
|
+
/**
|
|
1458
|
+
* @type {ChildrenOpAny?}
|
|
1459
|
+
*/
|
|
997
1460
|
let opsI = this.children.start;
|
|
998
1461
|
let offset = 0;
|
|
1462
|
+
/**
|
|
1463
|
+
* At the end, we will try to merge this op, and op.next op with their respective previous op.
|
|
1464
|
+
*
|
|
1465
|
+
* Hence, anytime an op is cloned, deleted, or inserted (anytime list.* api is used) we must add
|
|
1466
|
+
* an op to maybeMergeable.
|
|
1467
|
+
*
|
|
1468
|
+
* @type {Array<InsertOp<any>|RetainOp|DeleteOp|TextOp|ModifyOp<any>>}
|
|
1469
|
+
*/
|
|
1470
|
+
const maybeMergeable = [];
|
|
1471
|
+
/**
|
|
1472
|
+
* @template {InsertOp<any>|RetainOp|DeleteOp|TextOp|ModifyOp<any>|null} OP
|
|
1473
|
+
* @param {OP} op
|
|
1474
|
+
* @return {OP}
|
|
1475
|
+
*/
|
|
1476
|
+
const scheduleForMerge = op => {
|
|
1477
|
+
op && maybeMergeable.push(op);
|
|
1478
|
+
return op
|
|
1479
|
+
};
|
|
999
1480
|
other.children.forEach(op => {
|
|
1000
1481
|
if ($textOp.check(op) || $insertOp.check(op)) {
|
|
1001
1482
|
if (offset === 0) {
|
|
1002
|
-
list.insertBetween(this.children, opsI == null ? this.children.end : opsI.prev, opsI, op.clone());
|
|
1483
|
+
list.insertBetween(this.children, opsI == null ? this.children.end : opsI.prev, opsI, scheduleForMerge(op.clone()));
|
|
1003
1484
|
} else {
|
|
1004
1485
|
if (opsI == null) error.unexpectedCase();
|
|
1005
|
-
const cpy = opsI.clone();
|
|
1006
|
-
cpy._splice(0, offset);
|
|
1486
|
+
const cpy = scheduleForMerge(opsI.clone(offset));
|
|
1007
1487
|
opsI._splice(offset, opsI.length - offset);
|
|
1008
1488
|
list.insertBetween(this.children, opsI, opsI.next || null, cpy);
|
|
1009
|
-
list.insertBetween(this.children, opsI, cpy || null, op);
|
|
1489
|
+
list.insertBetween(this.children, opsI, cpy || null, scheduleForMerge(op.clone()));
|
|
1010
1490
|
offset = 0;
|
|
1011
1491
|
}
|
|
1492
|
+
this.childCnt += op.insert.length;
|
|
1012
1493
|
} else if ($retainOp.check(op)) {
|
|
1013
1494
|
let skipLen = op.length;
|
|
1014
1495
|
while (opsI != null && opsI.length - offset <= skipLen) {
|
|
@@ -1019,13 +1500,15 @@ class DeltaBuilder extends Delta {
|
|
|
1019
1500
|
if (opsI != null) {
|
|
1020
1501
|
offset += skipLen;
|
|
1021
1502
|
} else {
|
|
1022
|
-
list.pushEnd(this.children, new RetainOp(skipLen, op.format, op.attribution));
|
|
1503
|
+
list.pushEnd(this.children, scheduleForMerge(new RetainOp(skipLen, op.format, op.attribution)));
|
|
1504
|
+
this.childCnt += skipLen;
|
|
1023
1505
|
}
|
|
1024
1506
|
} else if ($deleteOp.check(op)) {
|
|
1025
1507
|
let remainingLen = op.delete;
|
|
1026
1508
|
while (remainingLen > 0) {
|
|
1027
1509
|
if (opsI == null) {
|
|
1028
|
-
list.pushEnd(this.children, new DeleteOp(remainingLen));
|
|
1510
|
+
list.pushEnd(this.children, scheduleForMerge(new DeleteOp(remainingLen)));
|
|
1511
|
+
this.childCnt += remainingLen;
|
|
1029
1512
|
break
|
|
1030
1513
|
} else if (opsI instanceof DeleteOp) {
|
|
1031
1514
|
const delLen = opsI.length - offset;
|
|
@@ -1043,9 +1526,11 @@ class DeltaBuilder extends Delta {
|
|
|
1043
1526
|
// case3: delete some part of end
|
|
1044
1527
|
// case4: delete some part of center
|
|
1045
1528
|
const delLen = math.min(opsI.length - offset, remainingLen);
|
|
1529
|
+
this.childCnt -= delLen;
|
|
1046
1530
|
if (opsI.length === delLen) {
|
|
1047
1531
|
// case 1
|
|
1048
1532
|
offset = 0;
|
|
1533
|
+
scheduleForMerge(opsI.next);
|
|
1049
1534
|
list.remove(this.children, opsI);
|
|
1050
1535
|
} else if (offset === 0) {
|
|
1051
1536
|
// case 2
|
|
@@ -1066,32 +1551,26 @@ class DeltaBuilder extends Delta {
|
|
|
1066
1551
|
} else if ($modifyOp.check(op)) {
|
|
1067
1552
|
if (opsI == null) {
|
|
1068
1553
|
list.pushEnd(this.children, op.clone());
|
|
1554
|
+
this.childCnt += 1;
|
|
1069
1555
|
return
|
|
1070
1556
|
}
|
|
1071
1557
|
if ($modifyOp.check(opsI)) {
|
|
1072
|
-
|
|
1073
|
-
} else if ($
|
|
1074
|
-
|
|
1075
|
-
if (!$deltaAny.check(d)) {
|
|
1076
|
-
// probably incompatible delta. can only modify deltas
|
|
1077
|
-
error.unexpectedCase();
|
|
1078
|
-
}
|
|
1079
|
-
/** @type {any} */ (d).apply(op.value);
|
|
1558
|
+
opsI._modValue.apply(op.value);
|
|
1559
|
+
} else if ($insertOp.check(opsI)) {
|
|
1560
|
+
opsI._modValue(offset).apply(op.value);
|
|
1080
1561
|
} else if ($retainOp.check(opsI)) {
|
|
1081
1562
|
if (offset > 0) {
|
|
1082
|
-
const cpy = opsI.clone();
|
|
1083
|
-
cpy._splice(offset, opsI.length - offset); // skipped len
|
|
1563
|
+
const cpy = scheduleForMerge(opsI.clone(0, offset)); // skipped len
|
|
1084
1564
|
opsI._splice(0, offset); // new remainder
|
|
1085
1565
|
list.insertBetween(this.children, opsI.prev, opsI, cpy); // insert skipped len
|
|
1086
1566
|
offset = 0;
|
|
1087
1567
|
}
|
|
1088
|
-
|
|
1089
|
-
// advance content
|
|
1090
|
-
list.insertBetween(this.children, opsI.prev, opsI, op.clone()); // insert skipped len
|
|
1568
|
+
list.insertBetween(this.children, opsI.prev, opsI, scheduleForMerge(op.clone())); // insert skipped len
|
|
1091
1569
|
if (opsI.length === 1) {
|
|
1092
1570
|
list.remove(this.children, opsI);
|
|
1093
1571
|
} else {
|
|
1094
1572
|
opsI._splice(0, 1);
|
|
1573
|
+
scheduleForMerge(opsI);
|
|
1095
1574
|
}
|
|
1096
1575
|
} else if ($deleteOp.check(opsI)) ; else {
|
|
1097
1576
|
error.unexpectedCase();
|
|
@@ -1100,15 +1579,22 @@ class DeltaBuilder extends Delta {
|
|
|
1100
1579
|
error.unexpectedCase();
|
|
1101
1580
|
}
|
|
1102
1581
|
});
|
|
1582
|
+
maybeMergeable.forEach(op => {
|
|
1583
|
+
// check if this is still integrated
|
|
1584
|
+
if (op.prev?.next === op) {
|
|
1585
|
+
tryMergeWithPrev(this.children, op);
|
|
1586
|
+
op.next && tryMergeWithPrev(this.children, op.next);
|
|
1587
|
+
}
|
|
1588
|
+
});
|
|
1103
1589
|
return this
|
|
1104
1590
|
}
|
|
1105
1591
|
|
|
1106
1592
|
/**
|
|
1107
|
-
* @param {
|
|
1593
|
+
* @param {DeltaAny} other
|
|
1108
1594
|
* @param {boolean} priority
|
|
1109
1595
|
*/
|
|
1110
1596
|
rebase (other, priority) {
|
|
1111
|
-
|
|
1597
|
+
modDeltaCheck(this);
|
|
1112
1598
|
/**
|
|
1113
1599
|
* Rebase attributes
|
|
1114
1600
|
*
|
|
@@ -1119,7 +1605,7 @@ class DeltaBuilder extends Delta {
|
|
|
1119
1605
|
* - delete vs delete ⇒ current delete op is removed because item has already been deleted
|
|
1120
1606
|
* - modify vs modify ⇒ rebase using priority
|
|
1121
1607
|
*/
|
|
1122
|
-
|
|
1608
|
+
for (const op of this.attrs) {
|
|
1123
1609
|
if ($insertOp.check(op)) {
|
|
1124
1610
|
if ($insertOp.check(other.attrs[op.key]) && !priority) {
|
|
1125
1611
|
delete this.attrs[op.key];
|
|
@@ -1132,77 +1618,182 @@ class DeltaBuilder extends Delta {
|
|
|
1132
1618
|
} else if ($modifyOp.check(op)) {
|
|
1133
1619
|
const otherOp = other.attrs[/** @type {any} */ (op.key)];
|
|
1134
1620
|
if (otherOp == null) ; else if ($modifyOp.check(otherOp)) {
|
|
1135
|
-
op.
|
|
1621
|
+
op._modValue.rebase(otherOp.value, priority);
|
|
1136
1622
|
} else {
|
|
1137
1623
|
delete this.attrs[otherOp.key];
|
|
1138
1624
|
}
|
|
1139
1625
|
}
|
|
1140
|
-
}
|
|
1626
|
+
}
|
|
1627
|
+
/**
|
|
1628
|
+
* Rebase children.
|
|
1629
|
+
*
|
|
1630
|
+
* Precedence: insert with higher priority comes first. Op with less priority is transformed to
|
|
1631
|
+
* be inserted later.
|
|
1632
|
+
*
|
|
1633
|
+
* @todo always check if inser OR text
|
|
1634
|
+
*/
|
|
1635
|
+
/**
|
|
1636
|
+
* @type {ChildrenOpAny?}
|
|
1637
|
+
*/
|
|
1638
|
+
let currChild = this.children.start;
|
|
1639
|
+
let currOffset = 0;
|
|
1640
|
+
/**
|
|
1641
|
+
* @type {ChildrenOpAny?}
|
|
1642
|
+
*/
|
|
1643
|
+
let otherChild = other.children.start;
|
|
1644
|
+
let otherOffset = 0;
|
|
1645
|
+
while (currChild != null && otherChild != null) {
|
|
1646
|
+
if ($insertOp.check(currChild) || $textOp.check(currChild)) {
|
|
1647
|
+
/**
|
|
1648
|
+
* Transforming *insert*. If other is..
|
|
1649
|
+
* - insert: transform based on priority
|
|
1650
|
+
* - retain/delete/modify: transform next op against other
|
|
1651
|
+
*/
|
|
1652
|
+
if ($insertOp.check(otherChild) || $modifyOp.check(otherChild) || $textOp.check(otherChild)) {
|
|
1653
|
+
if (!priority) {
|
|
1654
|
+
list.insertBetween(this.children, currChild.prev, currChild, new RetainOp(otherChild.length, null, null));
|
|
1655
|
+
this.childCnt += otherChild.length;
|
|
1656
|
+
// curr is transformed against other, transform curr against next
|
|
1657
|
+
otherOffset = otherChild.length;
|
|
1658
|
+
} else {
|
|
1659
|
+
// curr stays as is, transform next op
|
|
1660
|
+
currOffset = currChild.length;
|
|
1661
|
+
}
|
|
1662
|
+
} else { // otherChild = delete | retain | modify - curr stays as is, transform next op
|
|
1663
|
+
currOffset = currChild.length;
|
|
1664
|
+
}
|
|
1665
|
+
} else if ($modifyOp.check(currChild)) {
|
|
1666
|
+
/**
|
|
1667
|
+
* Transforming *modify*. If other is..
|
|
1668
|
+
* - insert: adjust position
|
|
1669
|
+
* - modify: rebase curr modify on other modify
|
|
1670
|
+
* - delete: remove modify
|
|
1671
|
+
* - retain: adjust offset
|
|
1672
|
+
*/
|
|
1673
|
+
if ($insertOp.check(otherChild) || $textOp.check(otherChild)) {
|
|
1674
|
+
// @todo: with all list changes (retain insertions, removal), try to merge the surrounding
|
|
1675
|
+
// ops later
|
|
1676
|
+
list.insertBetween(this.children, currChild.prev, currChild, new RetainOp(otherChild.length, null, null));
|
|
1677
|
+
this.childCnt += otherChild.length;
|
|
1678
|
+
// curr is transformed against other, transform curr against next
|
|
1679
|
+
otherOffset = otherChild.length;
|
|
1680
|
+
} else {
|
|
1681
|
+
if ($modifyOp.check(otherChild)) {
|
|
1682
|
+
/** @type {any} */ (currChild.value).rebase(otherChild, priority);
|
|
1683
|
+
} else if ($deleteOp.check(otherChild)) {
|
|
1684
|
+
list.remove(this.children, currChild);
|
|
1685
|
+
this.childCnt -= 1;
|
|
1686
|
+
}
|
|
1687
|
+
currOffset += 1;
|
|
1688
|
+
otherOffset += 1;
|
|
1689
|
+
}
|
|
1690
|
+
} else { // DeleteOp | RetainOp
|
|
1691
|
+
const maxCommonLen = math.min(currChild.length - currOffset, otherChild.length - otherOffset);
|
|
1692
|
+
/**
|
|
1693
|
+
* Transforming *retain* OR *delete*. If other is..
|
|
1694
|
+
* - retain / modify: adjust offsets
|
|
1695
|
+
* - delete: shorten curr op
|
|
1696
|
+
* - insert: split curr op and insert retain
|
|
1697
|
+
*/
|
|
1698
|
+
if ($retainOp.check(otherChild) || $modifyOp.check(otherChild)) {
|
|
1699
|
+
currOffset += maxCommonLen;
|
|
1700
|
+
otherOffset += maxCommonLen;
|
|
1701
|
+
} else if ($deleteOp.check(otherChild)) {
|
|
1702
|
+
if ($retainOp.check(currChild)) {
|
|
1703
|
+
// @ts-ignore
|
|
1704
|
+
currChild.retain -= maxCommonLen;
|
|
1705
|
+
} else if ($deleteOp.check(currChild)) {
|
|
1706
|
+
currChild.delete -= maxCommonLen;
|
|
1707
|
+
}
|
|
1708
|
+
this.childCnt -= maxCommonLen;
|
|
1709
|
+
} else { // insert/text.check(currOp)
|
|
1710
|
+
if (currOffset > 0) {
|
|
1711
|
+
const leftPart = currChild.clone(currOffset);
|
|
1712
|
+
list.insertBetween(this.children, currChild.prev, currChild, leftPart);
|
|
1713
|
+
currChild._splice(currOffset, currChild.length - currOffset);
|
|
1714
|
+
currOffset = 0;
|
|
1715
|
+
}
|
|
1716
|
+
list.insertBetween(this.children, currChild.prev, currChild, new RetainOp(otherChild.length, null, null));
|
|
1717
|
+
this.childCnt += otherChild.length;
|
|
1718
|
+
otherOffset = otherChild.length;
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
if (currOffset >= currChild.length) {
|
|
1722
|
+
currChild = currChild.next;
|
|
1723
|
+
currOffset = 0;
|
|
1724
|
+
}
|
|
1725
|
+
if (otherOffset >= otherChild.length) {
|
|
1726
|
+
otherChild = otherChild.next;
|
|
1727
|
+
otherOffset = 0;
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1141
1730
|
return this
|
|
1142
1731
|
}
|
|
1143
1732
|
|
|
1144
1733
|
/**
|
|
1145
|
-
*
|
|
1734
|
+
* Same as doing `delta.rebase(other.inverse())`, without creating a temporary delta.
|
|
1735
|
+
*
|
|
1736
|
+
* @param {DeltaAny} other
|
|
1737
|
+
* @param {boolean} priority
|
|
1146
1738
|
*/
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
}
|
|
1739
|
+
rebaseOnInverse (other, priority) {
|
|
1740
|
+
modDeltaCheck(this);
|
|
1741
|
+
// @todo
|
|
1742
|
+
console.info('method rebaseOnInverse unimplemented');
|
|
1152
1743
|
return this
|
|
1153
1744
|
}
|
|
1154
1745
|
}
|
|
1155
1746
|
|
|
1156
1747
|
/**
|
|
1157
1748
|
* @template {string} NodeName
|
|
1158
|
-
* @template {{ [key: string|number
|
|
1159
|
-
* @template {
|
|
1749
|
+
* @template {{ [key: string|number]: any }} [Attrs={}]
|
|
1750
|
+
* @template {encoding.AnyEncodable|DeltaAny|never} [Children=never]
|
|
1160
1751
|
* @template {string|never} [Text=never]
|
|
1161
1752
|
* @typedef {Delta<NodeName,Attrs,Children|Delta<NodeName,Attrs,Children,Text>|RecursiveDelta<NodeName,Attrs,Children,Text>,Text>} RecursiveDelta
|
|
1162
1753
|
*/
|
|
1163
1754
|
|
|
1164
1755
|
/**
|
|
1165
|
-
* @template {string} [
|
|
1166
|
-
* @template {{ [key: string|number
|
|
1167
|
-
* @template {any} [
|
|
1756
|
+
* @template {s.Schema<string>|string|Array<string>} [NodeNameSchema=s.Schema<any>]
|
|
1757
|
+
* @template {s.Schema<{ [key: string|number]: any }>|{ [key:string|number]:any }} [AttrsSchema=s.Schema<{}>]
|
|
1758
|
+
* @template {any} [ChildrenSchema=s.Schema<never>]
|
|
1168
1759
|
* @template {boolean} [HasText=false]
|
|
1169
1760
|
* @template {boolean} [Recursive=false]
|
|
1170
1761
|
* @param {object} opts
|
|
1171
|
-
* @param {
|
|
1172
|
-
* @param {
|
|
1173
|
-
* @param {
|
|
1174
|
-
* @param {HasText} [opts.
|
|
1762
|
+
* @param {NodeNameSchema?} [opts.name]
|
|
1763
|
+
* @param {AttrsSchema?} [opts.attrs]
|
|
1764
|
+
* @param {ChildrenSchema?} [opts.children]
|
|
1765
|
+
* @param {HasText} [opts.text]
|
|
1175
1766
|
* @param {Recursive} [opts.recursive]
|
|
1176
|
-
* @return {s.Schema<Delta<
|
|
1767
|
+
* @return {[s.Unwrap<s.ReadSchema<NodeNameSchema>>,s.Unwrap<s.ReadSchema<AttrsSchema>>,s.Unwrap<s.ReadSchema<ChildrenSchema>>] extends [infer NodeName, infer Attrs, infer Children] ? s.Schema<Delta<
|
|
1177
1768
|
* NodeName,
|
|
1178
1769
|
* Attrs,
|
|
1179
1770
|
* Children|(Recursive extends true ? RecursiveDelta<NodeName,Attrs,Children,HasText extends true ? string : never> : never),
|
|
1180
1771
|
* HasText extends true ? string : never
|
|
1181
|
-
* >>}
|
|
1772
|
+
* >> : never}
|
|
1182
1773
|
*/
|
|
1183
|
-
const $delta = ({ name, attrs, children,
|
|
1184
|
-
name = name == null ? schema.$any : name;
|
|
1774
|
+
const $delta = ({ name, attrs, children, text, recursive }) => {
|
|
1185
1775
|
/**
|
|
1186
1776
|
* @type {s.Schema<Array<any>>}
|
|
1187
1777
|
*/
|
|
1188
|
-
let $arrContent = children == null ? schema.$never : schema.$array(children);
|
|
1189
|
-
const $
|
|
1778
|
+
let $arrContent = children == null ? schema.$never : schema.$array(schema.$(children));
|
|
1779
|
+
const $name = name == null ? schema.$any : schema.$(name);
|
|
1780
|
+
const $attrsPartial = attrs == null ? schema.$object({}) : (schema.$$record.check(attrs) ? attrs : /** @type {any} */ (schema.$(attrs)).partial);
|
|
1190
1781
|
const $d = schema.$instanceOf(Delta, /** @param {Delta<any,any,any,any,any>} d */ d => {
|
|
1191
1782
|
if (
|
|
1192
|
-
|
|
1783
|
+
!$name.check(d.name) ||
|
|
1193
1784
|
object.some(d.attrs,
|
|
1194
1785
|
(op, k) => $insertOp.check(op) && !$attrsPartial.check({ [k]: op.value })
|
|
1195
1786
|
)
|
|
1196
1787
|
) return false
|
|
1197
1788
|
for (const op of d.children) {
|
|
1198
|
-
if ((!
|
|
1789
|
+
if ((!text && $textOp.check(op)) || ($insertOp.check(op) && !$arrContent.check(op.insert))) {
|
|
1199
1790
|
return false
|
|
1200
1791
|
}
|
|
1201
1792
|
}
|
|
1202
1793
|
return true
|
|
1203
1794
|
});
|
|
1204
1795
|
if (recursive) {
|
|
1205
|
-
$arrContent = children == null ? schema.$array($d) : schema.$array(children, $d);
|
|
1796
|
+
$arrContent = children == null ? schema.$array($d) : schema.$array(schema.$(children), $d);
|
|
1206
1797
|
}
|
|
1207
1798
|
return /** @type {any} */ ($d)
|
|
1208
1799
|
};
|
|
@@ -1222,16 +1813,16 @@ const $deltaAny = /** @type {any} */ (schema.$instanceOf(Delta));
|
|
|
1222
1813
|
const mergeAttrs = (a, b) => object.isEmpty(a) ? b : (object.isEmpty(b) ? a : object.assign({}, a, b));
|
|
1223
1814
|
|
|
1224
1815
|
/**
|
|
1225
|
-
* @template {
|
|
1816
|
+
* @template {DeltaAny|null} D
|
|
1226
1817
|
* @param {D} a
|
|
1227
1818
|
* @param {D} b
|
|
1228
1819
|
* @return {D}
|
|
1229
1820
|
*/
|
|
1230
1821
|
const mergeDeltas = (a, b) => {
|
|
1231
1822
|
if (a != null && b != null) {
|
|
1232
|
-
const c =
|
|
1823
|
+
const c = clone(a);
|
|
1233
1824
|
c.apply(b);
|
|
1234
|
-
return c
|
|
1825
|
+
return /** @type {any} */ (c)
|
|
1235
1826
|
}
|
|
1236
1827
|
return a == null ? b : (a || null)
|
|
1237
1828
|
};
|
|
@@ -1262,8 +1853,8 @@ const mergeDeltas = (a, b) => {
|
|
|
1262
1853
|
*/
|
|
1263
1854
|
/**
|
|
1264
1855
|
* @template {string|null} NodeName
|
|
1265
|
-
* @template {{[k:string|number
|
|
1266
|
-
* @template {Array<any>|string} Children
|
|
1856
|
+
* @template {{[k:string|number]:any}|null} Attrs
|
|
1857
|
+
* @template {Array<any>|string} [Children=never]
|
|
1267
1858
|
* @overload
|
|
1268
1859
|
* @param {NodeName} nodeName
|
|
1269
1860
|
* @param {Attrs} attrs
|
|
@@ -1278,7 +1869,7 @@ const mergeDeltas = (a, b) => {
|
|
|
1278
1869
|
*/
|
|
1279
1870
|
/**
|
|
1280
1871
|
* @param {string|s.Schema<DeltaAny>} [nodeNameOrSchema]
|
|
1281
|
-
* @param {{[K:string|number
|
|
1872
|
+
* @param {{[K:string|number]:any}|s.Schema<DeltaAny>} [attrsOrSchema]
|
|
1282
1873
|
* @param {(Array<any>|string)} [children]
|
|
1283
1874
|
* @return {DeltaBuilder<any,any,any,any,any>}
|
|
1284
1875
|
*/
|
|
@@ -1296,12 +1887,12 @@ const create = (nodeNameOrSchema, attrsOrSchema, children) => {
|
|
|
1296
1887
|
// DELTA TEXT
|
|
1297
1888
|
|
|
1298
1889
|
/**
|
|
1299
|
-
* @template [Embeds=never]
|
|
1890
|
+
* @template {encoding.AnyEncodable|DeltaAny} [Embeds=never]
|
|
1300
1891
|
* @typedef {Delta<any,{},Embeds,string>} TextDelta
|
|
1301
1892
|
*/
|
|
1302
1893
|
|
|
1303
1894
|
/**
|
|
1304
|
-
* @template [Embeds=never]
|
|
1895
|
+
* @template {encoding.AnyEncodable|DeltaAny} [Embeds=never]
|
|
1305
1896
|
* @typedef {DeltaBuilder<any,{},Embeds,string>} TextDeltaBuilder
|
|
1306
1897
|
*/
|
|
1307
1898
|
|
|
@@ -1310,7 +1901,7 @@ const create = (nodeNameOrSchema, attrsOrSchema, children) => {
|
|
|
1310
1901
|
* @param {$Embeds} $embeds
|
|
1311
1902
|
* @return {s.Schema<TextDelta<_AnyToNull<$Embeds> extends null ? never : ($Embeds extends Array<s.Schema<infer $C>> ? $C : never)>>}
|
|
1312
1903
|
*/
|
|
1313
|
-
const $text = (...$embeds) => /** @type {any} */ ($delta({ children: schema.$union(...$embeds),
|
|
1904
|
+
const $text = (...$embeds) => /** @type {any} */ ($delta({ children: schema.$union(...$embeds), text: true }));
|
|
1314
1905
|
const $textOnly = $text();
|
|
1315
1906
|
|
|
1316
1907
|
/**
|
|
@@ -1321,21 +1912,21 @@ const $textOnly = $text();
|
|
|
1321
1912
|
const text = $schema => /** @type {any} */ (create($schema || $textOnly));
|
|
1322
1913
|
|
|
1323
1914
|
/**
|
|
1324
|
-
* @template {
|
|
1915
|
+
* @template {encoding.AnyEncodable|DeltaAny} Children
|
|
1325
1916
|
* @typedef {Delta<any,{},Children,never>} ArrayDelta
|
|
1326
1917
|
*/
|
|
1327
1918
|
|
|
1328
1919
|
/**
|
|
1329
|
-
* @template {
|
|
1920
|
+
* @template {encoding.AnyEncodable|DeltaAny} Children
|
|
1330
1921
|
* @typedef {DeltaBuilder<any,{},Children,never>} ArrayDeltaBuilder
|
|
1331
1922
|
*/
|
|
1332
1923
|
|
|
1333
1924
|
/**
|
|
1334
|
-
* @template {s.Schema<any>} $Children
|
|
1925
|
+
* @template {any|s.Schema<any>} $Children
|
|
1335
1926
|
* @param {$Children} [$children]
|
|
1336
|
-
* @return {s.Schema<ArrayDelta<$Children
|
|
1927
|
+
* @return {s.Schema<ArrayDelta<s.Unwrap<s.ReadSchema<$Children>>>>}
|
|
1337
1928
|
*/
|
|
1338
|
-
const $array = $children => $delta({ children: $children });
|
|
1929
|
+
const $array = $children => /** @type {any} */ ($delta({ children: $children }));
|
|
1339
1930
|
|
|
1340
1931
|
/**
|
|
1341
1932
|
* @template {s.Schema<ArrayDelta<any>>} [$Schema=never]
|
|
@@ -1345,17 +1936,17 @@ const $array = $children => $delta({ children: $children });
|
|
|
1345
1936
|
const array = $schema => /** @type {any} */ ($schema ? create($schema) : create());
|
|
1346
1937
|
|
|
1347
1938
|
/**
|
|
1348
|
-
* @template {{ [K: string|number
|
|
1939
|
+
* @template {{ [K: string|number]: any }} Attrs
|
|
1349
1940
|
* @typedef {Delta<any,Attrs,never,never>} MapDelta
|
|
1350
1941
|
*/
|
|
1351
1942
|
|
|
1352
1943
|
/**
|
|
1353
|
-
* @template {{ [K: string|number
|
|
1944
|
+
* @template {{ [K: string|number]: any }} Attrs
|
|
1354
1945
|
* @typedef {DeltaBuilder<any,Attrs,never,never>} MapDeltaBuilder
|
|
1355
1946
|
*/
|
|
1356
1947
|
|
|
1357
1948
|
/**
|
|
1358
|
-
* @template {{ [K: string|number
|
|
1949
|
+
* @template {{ [K: string|number]: any }} $Attrs
|
|
1359
1950
|
* @param {s.Schema<$Attrs>} $attrs
|
|
1360
1951
|
* @return {s.Schema<MapDelta<$Attrs>>}
|
|
1361
1952
|
*/
|
|
@@ -1368,6 +1959,100 @@ const $map = $attrs => /** @type {any} */ ($delta({ attrs: $attrs }));
|
|
|
1368
1959
|
*/
|
|
1369
1960
|
const map = $schema => /** @type {any} */ (create(/** @type {any} */ ($schema)));
|
|
1370
1961
|
|
|
1962
|
+
/**
|
|
1963
|
+
* @template {DeltaAny} D
|
|
1964
|
+
* @param {D} d1
|
|
1965
|
+
* @param {NoInfer<D>} d2
|
|
1966
|
+
* @return {D}
|
|
1967
|
+
*/
|
|
1968
|
+
const diff = (d1, d2) => {
|
|
1969
|
+
/**
|
|
1970
|
+
* @type {DeltaBuilderAny}
|
|
1971
|
+
*/
|
|
1972
|
+
const d = create();
|
|
1973
|
+
if (d1.fingerprint !== d2.fingerprint) {
|
|
1974
|
+
let left1 = d1.children.start;
|
|
1975
|
+
let left2 = d2.children.start;
|
|
1976
|
+
let right1 = d1.children.end;
|
|
1977
|
+
let right2 = d2.children.end;
|
|
1978
|
+
let commonPrefixOffset = 0;
|
|
1979
|
+
// perform a patience sort
|
|
1980
|
+
// 1) remove common prefix and suffix
|
|
1981
|
+
while (left1 != null && left1.fingerprint === left2?.fingerprint) {
|
|
1982
|
+
if (!$deleteOp.check(left1)) {
|
|
1983
|
+
commonPrefixOffset += left1.length;
|
|
1984
|
+
}
|
|
1985
|
+
left1 = left1.next;
|
|
1986
|
+
left2 = left2.next;
|
|
1987
|
+
}
|
|
1988
|
+
while (right1 !== null && right1 !== left1 && right1.fingerprint === right2?.fingerprint) {
|
|
1989
|
+
right1 = right1.prev;
|
|
1990
|
+
right2 = right2.prev;
|
|
1991
|
+
}
|
|
1992
|
+
/**
|
|
1993
|
+
* @type {Array<ChildrenOpAny>}
|
|
1994
|
+
*/
|
|
1995
|
+
const ops1 = [];
|
|
1996
|
+
/**
|
|
1997
|
+
* @type {Array<ChildrenOpAny>}
|
|
1998
|
+
*/
|
|
1999
|
+
const ops2 = [];
|
|
2000
|
+
while (left1 !== null && left1 !== right1?.next) {
|
|
2001
|
+
ops1.push(left1);
|
|
2002
|
+
left1 = left1.next;
|
|
2003
|
+
}
|
|
2004
|
+
while (left2 !== null && left2 !== right2?.next) {
|
|
2005
|
+
ops2.push(left2);
|
|
2006
|
+
left2 = left2.next;
|
|
2007
|
+
}
|
|
2008
|
+
const fprints1 = ops1.map(op => op.fingerprint);
|
|
2009
|
+
const fprints2 = ops2.map(op => op.fingerprint);
|
|
2010
|
+
const changeset = patience.diff(fprints1, fprints2);
|
|
2011
|
+
d.retain(commonPrefixOffset);
|
|
2012
|
+
for (let i = 0, lastIndex1 = 0, currIndexOffset2 = 0; i < changeset.length; i++) {
|
|
2013
|
+
const change = changeset[i];
|
|
2014
|
+
d.retain(change.index - lastIndex1);
|
|
2015
|
+
// insert minimal diff at curred position in d
|
|
2016
|
+
/**
|
|
2017
|
+
* @param {DeltaBuilderAny} d
|
|
2018
|
+
* @param {ChildrenOpAny[]} opsIs
|
|
2019
|
+
* @param {ChildrenOpAny[]} opsShould
|
|
2020
|
+
*
|
|
2021
|
+
*/
|
|
2022
|
+
const diffAndApply = (d, opsIs, opsShould) => {
|
|
2023
|
+
// naive implementation
|
|
2024
|
+
d.delete(opsIs.reduce((currLen, op) => currLen + op.length, 0));
|
|
2025
|
+
opsShould.forEach(newIns => {
|
|
2026
|
+
if ($insertOp.check(newIns) || $textOp.check(newIns)) {
|
|
2027
|
+
d.insert(newIns.insert);
|
|
2028
|
+
} else {
|
|
2029
|
+
error.unexpectedCase();
|
|
2030
|
+
}
|
|
2031
|
+
});
|
|
2032
|
+
};
|
|
2033
|
+
diffAndApply(d, ops1.slice(change.index, change.index + change.remove.length), ops2.slice(change.index + currIndexOffset2, change.insert.length));
|
|
2034
|
+
lastIndex1 = change.index + change.remove.length;
|
|
2035
|
+
currIndexOffset2 += change.insert.length - change.remove.length;
|
|
2036
|
+
}
|
|
2037
|
+
for (const attr2 of d2.attrs) {
|
|
2038
|
+
const attr1 = d1.attrs[attr2.key];
|
|
2039
|
+
if (attr1 == null || (attr1.fingerprint !== attr2.fingerprint)) {
|
|
2040
|
+
if ($insertOp.check(attr2)) {
|
|
2041
|
+
d.set(attr2.key, attr2.value);
|
|
2042
|
+
} else {
|
|
2043
|
+
error.unexpectedCase();
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
for (const attr1 of d1.attrs) {
|
|
2048
|
+
if (d2.attrs[attr1.key] == null) {
|
|
2049
|
+
d.unset(attr1.key);
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
return /** @type {D} */ (d.done())
|
|
2054
|
+
};
|
|
2055
|
+
|
|
1371
2056
|
exports.$anyOp = $anyOp;
|
|
1372
2057
|
exports.$array = $array;
|
|
1373
2058
|
exports.$attribution = $attribution;
|
|
@@ -1384,19 +2069,20 @@ exports.$retainOp = $retainOp;
|
|
|
1384
2069
|
exports.$text = $text;
|
|
1385
2070
|
exports.$textOnly = $textOnly;
|
|
1386
2071
|
exports.$textOp = $textOp;
|
|
2072
|
+
exports.AttrDeleteOp = AttrDeleteOp;
|
|
2073
|
+
exports.AttrInsertOp = AttrInsertOp;
|
|
2074
|
+
exports.AttrModifyOp = AttrModifyOp;
|
|
1387
2075
|
exports.DeleteOp = DeleteOp;
|
|
1388
2076
|
exports.Delta = Delta;
|
|
1389
2077
|
exports.DeltaBuilder = DeltaBuilder;
|
|
1390
2078
|
exports.InsertOp = InsertOp;
|
|
1391
|
-
exports.MapDeleteOp = MapDeleteOp;
|
|
1392
|
-
exports.MapInsertOp = MapInsertOp;
|
|
1393
|
-
exports.MapModifyOp = MapModifyOp;
|
|
1394
2079
|
exports.ModifyOp = ModifyOp;
|
|
1395
2080
|
exports.RetainOp = RetainOp;
|
|
1396
2081
|
exports.TextOp = TextOp;
|
|
1397
2082
|
exports.array = array;
|
|
2083
|
+
exports.clone = clone;
|
|
1398
2084
|
exports.create = create;
|
|
1399
|
-
exports.
|
|
2085
|
+
exports.diff = diff;
|
|
1400
2086
|
exports.map = map;
|
|
1401
2087
|
exports.mergeAttrs = mergeAttrs;
|
|
1402
2088
|
exports.mergeDeltas = mergeDeltas;
|