lib0 0.2.115-4 → 0.2.115-6

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.
Files changed (236) hide show
  1. package/coverage/tmp/{coverage-32703-1763495370274-0.json → coverage-5242-1765032816888-0.json} +1 -1
  2. package/delta/binding.d.ts +11 -9
  3. package/delta/binding.d.ts.map +1 -1
  4. package/delta/binding.js +5 -2
  5. package/delta/binding.test.d.ts.map +1 -1
  6. package/delta/delta-pitch.test.d.ts +5 -0
  7. package/delta/delta-pitch.test.d.ts.map +1 -0
  8. package/delta/{d2.d.ts → delta.d.ts} +129 -38
  9. package/delta/delta.d.ts.map +1 -0
  10. package/delta/{d2.js → delta.js} +379 -66
  11. package/delta/{d2.test.d.ts → delta.test.d.ts} +8 -1
  12. package/delta/delta.test.d.ts.map +1 -0
  13. package/delta/t3.test.d.ts +1 -1
  14. package/delta/t3.test.d.ts.map +1 -1
  15. package/dist/array.cjs +17 -60
  16. package/dist/array.cjs.map +1 -1
  17. package/dist/binding.cjs +114 -28
  18. package/dist/binding.cjs.map +1 -1
  19. package/dist/{broadcastchannel-d0c108a2.cjs → broadcastchannel-42bbe6e0.cjs} +2 -2
  20. package/dist/{broadcastchannel-d0c108a2.cjs.map → broadcastchannel-42bbe6e0.cjs.map} +1 -1
  21. package/dist/broadcastchannel.cjs +6 -6
  22. package/dist/{buffer-7f6fa8fa.cjs → buffer-54360f21.cjs} +2 -2
  23. package/dist/{buffer-7f6fa8fa.cjs.map → buffer-54360f21.cjs.map} +1 -1
  24. package/dist/buffer.cjs +5 -5
  25. package/dist/cache.cjs +3 -3
  26. package/dist/component.cjs +12 -8
  27. package/dist/component.cjs.map +1 -1
  28. package/dist/delta/binding.d.ts +11 -9
  29. package/dist/delta/binding.d.ts.map +1 -1
  30. package/dist/delta/binding.test.d.ts.map +1 -1
  31. package/dist/delta/delta-pitch.test.d.ts +5 -0
  32. package/dist/delta/delta-pitch.test.d.ts.map +1 -0
  33. package/dist/delta/{d2.d.ts → delta.d.ts} +129 -38
  34. package/dist/delta/delta.d.ts.map +1 -0
  35. package/dist/delta/{d2.test.d.ts → delta.test.d.ts} +8 -1
  36. package/dist/delta/delta.test.d.ts.map +1 -0
  37. package/dist/delta/t3.test.d.ts +1 -1
  38. package/dist/delta/t3.test.d.ts.map +1 -1
  39. package/dist/{d2.cjs → delta.cjs} +389 -71
  40. package/dist/delta.cjs.map +1 -0
  41. package/dist/{diff-1832cb43.cjs → diff-fab14ea6.cjs} +2 -2
  42. package/dist/{diff-1832cb43.cjs.map → diff-fab14ea6.cjs.map} +1 -1
  43. package/dist/diff.cjs +4 -4
  44. package/dist/{dom-f5047a64.cjs → dom-4c4b4c68.cjs} +1 -1
  45. package/dist/{dom-f5047a64.cjs.map → dom-4c4b4c68.cjs.map} +1 -1
  46. package/dist/dom.cjs +12 -5
  47. package/dist/dom.cjs.map +1 -1
  48. package/dist/{environment-90227ead.cjs → environment-ae4f6f15.cjs} +2 -2
  49. package/dist/{environment-90227ead.cjs.map → environment-ae4f6f15.cjs.map} +1 -1
  50. package/dist/environment.cjs +4 -4
  51. package/dist/equality.cjs +34 -0
  52. package/dist/equality.cjs.map +1 -0
  53. package/dist/fingerprint.cjs +44 -0
  54. package/dist/fingerprint.cjs.map +1 -0
  55. package/dist/{function-e7d18feb.cjs → function-618aa640.cjs} +8 -7
  56. package/dist/function-618aa640.cjs.map +1 -0
  57. package/dist/function.cjs +3 -3
  58. package/dist/function.d.ts.map +1 -1
  59. package/dist/index.cjs +9 -9
  60. package/dist/indexeddbV2.cjs +2 -2
  61. package/dist/jwt.cjs +5 -5
  62. package/dist/list.cjs +18 -5
  63. package/dist/list.cjs.map +1 -1
  64. package/dist/list.d.ts +9 -2
  65. package/dist/list.d.ts.map +1 -1
  66. package/dist/list.test.d.ts.map +1 -1
  67. package/dist/logging.cjs +11 -5
  68. package/dist/logging.cjs.map +1 -1
  69. package/dist/logging.common.cjs +4 -4
  70. package/dist/logging.node.cjs +4 -4
  71. package/dist/map.cjs +7 -314
  72. package/dist/map.cjs.map +1 -1
  73. package/dist/{object-18980796.cjs → object-dec41ef9.cjs} +3 -3
  74. package/dist/object-dec41ef9.cjs.map +1 -0
  75. package/dist/object.cjs +2 -2
  76. package/dist/object.d.ts.map +1 -1
  77. package/dist/performance.node.cjs +3 -3
  78. package/dist/pledge.cjs +2 -2
  79. package/dist/{prng-99204216.cjs → prng-96eef52a.cjs} +2 -2
  80. package/dist/{prng-99204216.cjs.map → prng-96eef52a.cjs.map} +1 -1
  81. package/dist/prng.cjs +6 -6
  82. package/dist/rabin-gf2-polynomial.cjs +5 -5
  83. package/dist/rabin-uncached.cjs +5 -5
  84. package/dist/rabin.cjs +5 -5
  85. package/dist/schema.cjs +202 -22
  86. package/dist/schema.cjs.map +1 -1
  87. package/dist/schema.d.ts +86 -29
  88. package/dist/schema.d.ts.map +1 -1
  89. package/dist/schema.test.d.ts +4 -0
  90. package/dist/schema.test.d.ts.map +1 -1
  91. package/dist/testing.cjs +9 -9
  92. package/dist/testing.cjs.map +1 -1
  93. package/dist/{traits.d.ts → trait/equality.d.ts} +1 -1
  94. package/dist/trait/equality.d.ts.map +1 -0
  95. package/dist/trait/fingerprint.d.ts +13 -0
  96. package/dist/trait/fingerprint.d.ts.map +1 -0
  97. package/dist/trait/traits.d.ts +3 -0
  98. package/dist/trait/traits.d.ts.map +1 -0
  99. package/dist/trait/traits.test.d.ts +5 -0
  100. package/dist/trait/traits.test.d.ts.map +1 -0
  101. package/dist/traits.cjs +23 -26
  102. package/dist/traits.cjs.map +1 -1
  103. package/dist/url.cjs +2 -2
  104. package/function.d.ts.map +1 -1
  105. package/function.js +6 -5
  106. package/list.d.ts +9 -2
  107. package/list.d.ts.map +1 -1
  108. package/list.js +17 -3
  109. package/list.test.d.ts.map +1 -1
  110. package/object.d.ts.map +1 -1
  111. package/object.js +2 -2
  112. package/package.json +8 -10
  113. package/schema.d.ts +86 -29
  114. package/schema.d.ts.map +1 -1
  115. package/schema.js +191 -20
  116. package/schema.test.d.ts +4 -0
  117. package/schema.test.d.ts.map +1 -1
  118. package/test.html +2 -4
  119. package/test.js +7 -13
  120. package/testing.js +3 -3
  121. package/{traits.d.ts → trait/equality.d.ts} +1 -1
  122. package/trait/equality.d.ts.map +1 -0
  123. package/trait/fingerprint.d.ts +13 -0
  124. package/trait/fingerprint.d.ts.map +1 -0
  125. package/trait/fingerprint.js +21 -0
  126. package/trait/traits.d.ts +3 -0
  127. package/trait/traits.d.ts.map +1 -0
  128. package/trait/traits.js +2 -0
  129. package/trait/traits.test.d.ts +5 -0
  130. package/{traits.test.d.ts.map → trait/traits.test.d.ts.map} +1 -1
  131. package/delta/abstract-array.d.ts +0 -166
  132. package/delta/abstract-array.d.ts.map +0 -1
  133. package/delta/abstract-array.js +0 -421
  134. package/delta/abstract.d.ts +0 -69
  135. package/delta/abstract.d.ts.map +0 -1
  136. package/delta/abstract.js +0 -102
  137. package/delta/array.d.ts +0 -23
  138. package/delta/array.d.ts.map +0 -1
  139. package/delta/array.js +0 -45
  140. package/delta/array.test.d.ts +0 -2
  141. package/delta/array.test.d.ts.map +0 -1
  142. package/delta/d2.d.ts.map +0 -1
  143. package/delta/d2.test.d.ts.map +0 -1
  144. package/delta/index.d.ts +0 -14
  145. package/delta/index.d.ts.map +0 -1
  146. package/delta/index.js +0 -79
  147. package/delta/map.d.ts +0 -226
  148. package/delta/map.d.ts.map +0 -1
  149. package/delta/map.js +0 -304
  150. package/delta/node.d.ts +0 -117
  151. package/delta/node.d.ts.map +0 -1
  152. package/delta/node.js +0 -183
  153. package/delta/node.test.d.ts +0 -4
  154. package/delta/node.test.d.ts.map +0 -1
  155. package/delta/ops.d.ts +0 -464
  156. package/delta/ops.d.ts.map +0 -1
  157. package/delta/ops.js +0 -544
  158. package/delta/t2.d.ts +0 -184
  159. package/delta/t2.d.ts.map +0 -1
  160. package/delta/t2.js +0 -890
  161. package/delta/text.d.ts +0 -43
  162. package/delta/text.d.ts.map +0 -1
  163. package/delta/text.js +0 -54
  164. package/delta/text.test.d.ts +0 -6
  165. package/delta/text.test.d.ts.map +0 -1
  166. package/delta/transformer.d.ts +0 -164
  167. package/delta/transformer.d.ts.map +0 -1
  168. package/delta/transformer.js +0 -888
  169. package/delta/transformer.test.d.ts +0 -13
  170. package/delta/transformer.test.d.ts.map +0 -1
  171. package/delta/value.d.ts +0 -84
  172. package/delta/value.d.ts.map +0 -1
  173. package/delta/value.js +0 -168
  174. package/dist/abstract-array.cjs +0 -433
  175. package/dist/abstract-array.cjs.map +0 -1
  176. package/dist/abstract.cjs +0 -122
  177. package/dist/abstract.cjs.map +0 -1
  178. package/dist/array2.cjs +0 -26
  179. package/dist/array2.cjs.map +0 -1
  180. package/dist/d2.cjs.map +0 -1
  181. package/dist/delta/abstract-array.d.ts +0 -166
  182. package/dist/delta/abstract-array.d.ts.map +0 -1
  183. package/dist/delta/abstract.d.ts +0 -69
  184. package/dist/delta/abstract.d.ts.map +0 -1
  185. package/dist/delta/array.d.ts +0 -23
  186. package/dist/delta/array.d.ts.map +0 -1
  187. package/dist/delta/array.test.d.ts +0 -2
  188. package/dist/delta/array.test.d.ts.map +0 -1
  189. package/dist/delta/d2.d.ts.map +0 -1
  190. package/dist/delta/d2.test.d.ts.map +0 -1
  191. package/dist/delta/index.d.ts +0 -14
  192. package/dist/delta/index.d.ts.map +0 -1
  193. package/dist/delta/map.d.ts +0 -226
  194. package/dist/delta/map.d.ts.map +0 -1
  195. package/dist/delta/node.d.ts +0 -117
  196. package/dist/delta/node.d.ts.map +0 -1
  197. package/dist/delta/node.test.d.ts +0 -4
  198. package/dist/delta/node.test.d.ts.map +0 -1
  199. package/dist/delta/ops.d.ts +0 -464
  200. package/dist/delta/ops.d.ts.map +0 -1
  201. package/dist/delta/t2.d.ts +0 -184
  202. package/dist/delta/t2.d.ts.map +0 -1
  203. package/dist/delta/text.d.ts +0 -43
  204. package/dist/delta/text.d.ts.map +0 -1
  205. package/dist/delta/text.test.d.ts +0 -6
  206. package/dist/delta/text.test.d.ts.map +0 -1
  207. package/dist/delta/transformer.d.ts +0 -164
  208. package/dist/delta/transformer.d.ts.map +0 -1
  209. package/dist/delta/transformer.test.d.ts +0 -13
  210. package/dist/delta/transformer.test.d.ts.map +0 -1
  211. package/dist/delta/value.d.ts +0 -84
  212. package/dist/delta/value.d.ts.map +0 -1
  213. package/dist/function-e7d18feb.cjs.map +0 -1
  214. package/dist/index2.cjs +0 -71
  215. package/dist/index2.cjs.map +0 -1
  216. package/dist/map2.cjs +0 -15
  217. package/dist/map2.cjs.map +0 -1
  218. package/dist/node.cjs +0 -206
  219. package/dist/node.cjs.map +0 -1
  220. package/dist/object-18980796.cjs.map +0 -1
  221. package/dist/ops.cjs +0 -575
  222. package/dist/ops.cjs.map +0 -1
  223. package/dist/t2.cjs +0 -932
  224. package/dist/t2.cjs.map +0 -1
  225. package/dist/text.cjs +0 -79
  226. package/dist/text.cjs.map +0 -1
  227. package/dist/traits.d.ts.map +0 -1
  228. package/dist/traits.test.d.ts +0 -4
  229. package/dist/traits.test.d.ts.map +0 -1
  230. package/dist/transformer.cjs +0 -930
  231. package/dist/transformer.cjs.map +0 -1
  232. package/dist/value.cjs +0 -187
  233. package/dist/value.cjs.map +0 -1
  234. package/traits.d.ts.map +0 -1
  235. package/traits.test.d.ts +0 -4
  236. /package/{traits.js → trait/equality.js} +0 -0
@@ -10,7 +10,8 @@
10
10
 
11
11
  import * as list from '../list.js'
12
12
  import * as object from '../object.js'
13
- import * as traits from '../traits.js'
13
+ import * as equalityTrait from '../trait/equality.js'
14
+ import * as fingerprintTrait from '../trait/fingerprint.js'
14
15
  import * as arr from '../array.js'
15
16
  import * as fun from '../function.js'
16
17
  import * as s from '../schema.js'
@@ -20,6 +21,7 @@ import * as rabin from '../hash/rabin.js'
20
21
  import * as encoding from '../encoding.js'
21
22
  import * as buffer from '../buffer.js'
22
23
  import * as patience from '../diff/patience.js'
24
+ import * as prng from '../prng.js'
23
25
 
24
26
  /**
25
27
  * @typedef {{
@@ -103,10 +105,6 @@ const _cloneAttrs = attrs => attrs == null ? attrs : { ...attrs }
103
105
  */
104
106
  const _markMaybeDeltaAsDone = maybeDelta => $deltaAny.check(maybeDelta) ? /** @type {MaybeDelta} */ (maybeDelta.done()) : maybeDelta
105
107
 
106
- /**
107
- * @typedef {unknown & DeltaAny} Q
108
- */
109
-
110
108
  export class TextOp extends list.ListNode {
111
109
  /**
112
110
  * @param {string} insert
@@ -185,7 +183,7 @@ export class TextOp extends list.ListNode {
185
183
  /**
186
184
  * @param {TextOp} other
187
185
  */
188
- [traits.EqualityTraitSymbol] (other) {
186
+ [equalityTrait.EqualityTraitSymbol] (other) {
189
187
  return fun.equalityDeep(this.insert, other.insert) && fun.equalityDeep(this.format, other.format) && fun.equalityDeep(this.attribution, other.attribution)
190
188
  }
191
189
 
@@ -198,7 +196,7 @@ export class TextOp extends list.ListNode {
198
196
  }
199
197
 
200
198
  /**
201
- * @template {encoding.AnyEncodable|DeltaAny} ArrayContent
199
+ * @template {fingerprintTrait.Fingerprintable} ArrayContent
202
200
  */
203
201
  export class InsertOp extends list.ListNode {
204
202
  /**
@@ -273,13 +271,7 @@ export class InsertOp extends list.ListNode {
273
271
  encoding.writeVarUint(encoder, 1) // insertOp type: 1
274
272
  encoding.writeVarUint(encoder, this.insert.length)
275
273
  this.insert.forEach(ins => {
276
- if ($deltaAny.check(ins)) {
277
- encoding.writeUint8(encoder, 0)
278
- encoding.writeVarString(encoder, ins.fingerprint)
279
- } else {
280
- encoding.writeUint8(encoder, 1)
281
- encoding.writeAny(encoder, ins)
282
- }
274
+ encoding.writeVarString(encoder, fingerprintTrait.fingerprint(ins))
283
275
  })
284
276
  encoding.writeAny(encoder, this.format)
285
277
  })))
@@ -308,7 +300,7 @@ export class InsertOp extends list.ListNode {
308
300
  /**
309
301
  * @param {InsertOp<ArrayContent>} other
310
302
  */
311
- [traits.EqualityTraitSymbol] (other) {
303
+ [equalityTrait.EqualityTraitSymbol] (other) {
312
304
  return fun.equalityDeep(this.insert, other.insert) && fun.equalityDeep(this.format, other.format) && fun.equalityDeep(this.attribution, other.attribution)
313
305
  }
314
306
 
@@ -321,7 +313,7 @@ export class InsertOp extends list.ListNode {
321
313
  }
322
314
 
323
315
  /**
324
- * @template {encoding.AnyEncodable|DeltaAny} [Children=never]
316
+ * @template {fingerprintTrait.Fingerprintable} [Children=never]
325
317
  * @template {string} [Text=never]
326
318
  */
327
319
  export class DeleteOp extends list.ListNode {
@@ -382,7 +374,7 @@ export class DeleteOp extends list.ListNode {
382
374
  /**
383
375
  * @param {DeleteOp} other
384
376
  */
385
- [traits.EqualityTraitSymbol] (other) {
377
+ [equalityTrait.EqualityTraitSymbol] (other) {
386
378
  return this.delete === other.delete
387
379
  }
388
380
 
@@ -463,7 +455,7 @@ export class RetainOp extends list.ListNode {
463
455
  /**
464
456
  * @param {RetainOp} other
465
457
  */
466
- [traits.EqualityTraitSymbol] (other) {
458
+ [equalityTrait.EqualityTraitSymbol] (other) {
467
459
  return this.retain === other.retain && fun.equalityDeep(this.format, other.format) && fun.equalityDeep(this.attribution, other.attribution)
468
460
  }
469
461
 
@@ -563,8 +555,8 @@ export class ModifyOp extends list.ListNode {
563
555
  /**
564
556
  * @param {ModifyOp<any>} other
565
557
  */
566
- [traits.EqualityTraitSymbol] (other) {
567
- return this.value[traits.EqualityTraitSymbol](other.value) && fun.equalityDeep(this.format, other.format) && fun.equalityDeep(this.attribution, other.attribution)
558
+ [equalityTrait.EqualityTraitSymbol] (other) {
559
+ return this.value[equalityTrait.EqualityTraitSymbol](other.value) && fun.equalityDeep(this.format, other.format) && fun.equalityDeep(this.attribution, other.attribution)
568
560
  }
569
561
 
570
562
  /**
@@ -576,7 +568,7 @@ export class ModifyOp extends list.ListNode {
576
568
  }
577
569
 
578
570
  /**
579
- * @template {encoding.AnyEncodable|DeltaAny} V
571
+ * @template {fingerprintTrait.Fingerprintable} V
580
572
  * @template {string|number} [K=any]
581
573
  */
582
574
  export class AttrInsertOp {
@@ -661,7 +653,7 @@ export class AttrInsertOp {
661
653
  /**
662
654
  * @param {AttrInsertOp<V>} other
663
655
  */
664
- [traits.EqualityTraitSymbol] (other) {
656
+ [equalityTrait.EqualityTraitSymbol] (other) {
665
657
  return this.key === other.key && fun.equalityDeep(this.value, other.value) && fun.equalityDeep(this.attribution, other.attribution)
666
658
  }
667
659
 
@@ -726,7 +718,7 @@ export class AttrDeleteOp {
726
718
  /**
727
719
  * @param {AttrDeleteOp<V>} other
728
720
  */
729
- [traits.EqualityTraitSymbol] (other) {
721
+ [equalityTrait.EqualityTraitSymbol] (other) {
730
722
  return this.key === other.key && fun.equalityDeep(this.attribution, other.attribution)
731
723
  }
732
724
 
@@ -800,8 +792,8 @@ export class AttrModifyOp {
800
792
  /**
801
793
  * @param {AttrModifyOp<Modifier>} other
802
794
  */
803
- [traits.EqualityTraitSymbol] (other) {
804
- return this.key === other.key && this.value[traits.EqualityTraitSymbol](other.value)
795
+ [equalityTrait.EqualityTraitSymbol] (other) {
796
+ return this.key === other.key && this.value[equalityTrait.EqualityTraitSymbol](other.value)
805
797
  }
806
798
 
807
799
  /**
@@ -823,7 +815,7 @@ export const $deleteOp = s.$custom(o => o != null && (o.constructor === DeleteOp
823
815
  export const $insertOp = s.$custom(o => o != null && (o.constructor === AttrInsertOp || o.constructor === InsertOp))
824
816
 
825
817
  /**
826
- * @template {encoding.AnyEncodable|DeltaAny} Content
818
+ * @template {fingerprintTrait.Fingerprintable} Content
827
819
  * @param {s.Schema<Content>} $content
828
820
  * @return {s.Schema<AttrInsertOp<Content> | InsertOp<Content>>}
829
821
  */
@@ -904,8 +896,8 @@ export const $anyOp = s.$union($insertOp, $deleteOp, $textOp, $modifyOp)
904
896
  /**
905
897
  * @template {string} [NodeName=any]
906
898
  * @template {{[k:string|number]:any}} [Attrs={}]
907
- * @template {encoding.AnyEncodable|DeltaAny|never} [Children=never]
908
- * @template {string|never} [Text=never]
899
+ * @template {fingerprintTrait.Fingerprintable} [Children=never]
900
+ * @template {string} [Text=never]
909
901
  * @template {s.Schema<Delta<any,any,any,any,any>>|null} [Schema=any]
910
902
  */
911
903
  export class Delta {
@@ -956,6 +948,7 @@ export class Delta {
956
948
  */
957
949
  get fingerprint () {
958
950
  return this._fingerprint || (this._fingerprint = buffer.toBase64(encoding.encode(encoder => {
951
+ encoding.writeUint32(encoder, 0xf2ae5680) // "magic number" that ensures that different types of content don't yield the same fingerprint
959
952
  encoding.writeAny(encoder, this.name)
960
953
  /**
961
954
  * @type {Array<number|string>}
@@ -985,6 +978,10 @@ export class Delta {
985
978
  })))
986
979
  }
987
980
 
981
+ [fingerprintTrait.FingerprintTraitSymbol] () {
982
+ return this.fingerprint
983
+ }
984
+
988
985
  isEmpty () {
989
986
  return object.isEmpty(this.attrs) && list.isEmpty(this.children)
990
987
  }
@@ -1021,23 +1018,30 @@ export class Delta {
1021
1018
  * @return {boolean}
1022
1019
  */
1023
1020
  equals (other) {
1024
- return this[traits.EqualityTraitSymbol](other)
1021
+ return this[equalityTrait.EqualityTraitSymbol](other)
1025
1022
  }
1026
1023
 
1027
1024
  /**
1028
1025
  * @param {any} other
1029
1026
  * @return {boolean}
1030
1027
  */
1031
- [traits.EqualityTraitSymbol] (other) {
1028
+ [equalityTrait.EqualityTraitSymbol] (other) {
1032
1029
  // @todo it is only necessary to compare finrerprints OR do a deep equality check (remove
1033
1030
  // childCnt as well)
1034
1031
  return this.name === other.name && fun.equalityDeep(this.attrs, other.attrs) && fun.equalityDeep(this.children, other.children) && this.childCnt === other.childCnt
1035
1032
  }
1036
1033
 
1034
+ /**
1035
+ * @return {DeltaBuilder<NodeName,Attrs,Children,Text,Schema>}
1036
+ */
1037
+ clone () {
1038
+ return this.slice(0, this.childCnt)
1039
+ }
1040
+
1037
1041
  /**
1038
1042
  * @param {number} start
1039
1043
  * @param {number} end
1040
- * @return {Delta<NodeName,Attrs,Children,Text,Schema>}
1044
+ * @return {DeltaBuilder<NodeName,Attrs,Children,Text,Schema>}
1041
1045
  */
1042
1046
  slice (start = 0, end = this.childCnt) {
1043
1047
  const cpy = /** @type {DeltaAny} */ (new DeltaBuilder(/** @type {any} */ (this.name), this.$schema))
@@ -1104,7 +1108,7 @@ export class Delta {
1104
1108
  /**
1105
1109
  * @template {DeltaAny} D
1106
1110
  * @param {D} d
1107
- * @return {D extends Delta<infer NodeName,infer Attrs,infer Children,infer Text,infer Schema> ? DeltaBuilder<NodeName,Attrs,Children,Text,Schema> : never}
1111
+ * @return {D extends DeltaBuilder<infer NodeName,infer Attrs,infer Children,infer Text,infer Schema> ? DeltaBuilder<NodeName,Attrs,Children,Text,Schema> : never}
1108
1112
  */
1109
1113
  export const clone = d => /** @type {any} */ (d.slice(0, d.childCnt))
1110
1114
 
@@ -1158,8 +1162,8 @@ const modDeltaCheck = d => {
1158
1162
  /**
1159
1163
  * @template {string} [NodeName=any]
1160
1164
  * @template {{[key:string|number]:any}} [Attrs={}]
1161
- * @template {encoding.AnyEncodable|DeltaAny|never} [Children=never]
1162
- * @template {string|never} [Text=never]
1165
+ * @template {fingerprintTrait.Fingerprintable} [Children=never]
1166
+ * @template {string} [Text=never]
1163
1167
  * @template {s.Schema<Delta<any,any,any,any,any>>|null} [Schema=any]
1164
1168
  * @extends {Delta<NodeName,Attrs,Children,Text,Schema>}
1165
1169
  */
@@ -1423,7 +1427,7 @@ export class DeltaBuilder extends Delta {
1423
1427
  modDeltaCheck(this)
1424
1428
  this.$schema?.expect(other)
1425
1429
  // apply attrs
1426
- for (let op of other.attrs) {
1430
+ for (const op of other.attrs) {
1427
1431
  const c = /** @type {AttrInsertOp<any,any>|AttrDeleteOp<any>|AttrModifyOp<any,any>} */ (this.attrs[op.key])
1428
1432
  if ($modifyOp.check(op)) {
1429
1433
  if ($deltaAny.check(c?.value)) {
@@ -1433,12 +1437,14 @@ export class DeltaBuilder extends Delta {
1433
1437
  // @ts-ignore
1434
1438
  this.attrs[op.key] = op.clone()
1435
1439
  }
1436
- } else {
1437
- op = /** @type {any} */ (op.clone())
1440
+ } else if ($insertOp.check(op)) {
1438
1441
  // @ts-ignore
1439
1442
  op.prevValue = c?.value
1440
1443
  // @ts-ignore
1441
- this.attrs[op.key] = op
1444
+ this.attrs[op.key] = op.clone()
1445
+ } else if ($deleteOp.check(op)) {
1446
+ op.prevValue = c?.value
1447
+ delete this.attrs[op.key]
1442
1448
  }
1443
1449
  }
1444
1450
  // apply children
@@ -1470,26 +1476,50 @@ export class DeltaBuilder extends Delta {
1470
1476
  if (offset === 0) {
1471
1477
  list.insertBetween(this.children, opsI == null ? this.children.end : opsI.prev, opsI, scheduleForMerge(op.clone()))
1472
1478
  } else {
1479
+ // @todo inmplement "splitHelper" and "insertHelper" - I'm splitting all the time and
1480
+ // forget to update opsI
1473
1481
  if (opsI == null) error.unexpectedCase()
1474
1482
  const cpy = scheduleForMerge(opsI.clone(offset))
1475
1483
  opsI._splice(offset, opsI.length - offset)
1476
1484
  list.insertBetween(this.children, opsI, opsI.next || null, cpy)
1477
1485
  list.insertBetween(this.children, opsI, cpy || null, scheduleForMerge(op.clone()))
1486
+ opsI = cpy
1478
1487
  offset = 0
1479
1488
  }
1480
1489
  this.childCnt += op.insert.length
1481
1490
  } else if ($retainOp.check(op)) {
1482
- let skipLen = op.length
1483
- while (opsI != null && opsI.length - offset <= skipLen) {
1484
- skipLen -= opsI.length - offset
1491
+ let retainLen = op.length
1492
+
1493
+ if (offset > 0 && opsI != null && op.format != null && !$deleteOp.check(opsI) && !object.every(op.format, (v, k) => fun.equalityDeep(v, /** @type {InsertOp<any>|RetainOp|ModifyOp} */ (opsI).format?.[k] || null))) {
1494
+ // need to split current op
1495
+ const cpy = scheduleForMerge(opsI.clone(offset))
1496
+ opsI._splice(offset, opsI.length - offset)
1497
+ list.insertBetween(this.children, opsI, opsI.next || null, cpy)
1498
+ opsI = cpy
1499
+ offset = 0
1500
+ }
1501
+
1502
+ while (opsI != null && opsI.length - offset <= retainLen) {
1503
+ op.format != null && updateOpFormat(opsI, op.format)
1504
+ retainLen -= opsI.length - offset
1485
1505
  opsI = opsI?.next || null
1486
1506
  offset = 0
1487
1507
  }
1508
+
1488
1509
  if (opsI != null) {
1489
- offset += skipLen
1490
- } else {
1491
- list.pushEnd(this.children, scheduleForMerge(new RetainOp(skipLen, op.format, op.attribution)))
1492
- this.childCnt += skipLen
1510
+ if (op.format != null && retainLen > 0) {
1511
+ // split current op and apply format
1512
+ const cpy = scheduleForMerge(opsI.clone(retainLen))
1513
+ opsI._splice(retainLen, opsI.length - retainLen)
1514
+ list.insertBetween(this.children, opsI, opsI.next || null, cpy)
1515
+ updateOpFormat(opsI, op.format)
1516
+ opsI = cpy
1517
+ } else {
1518
+ offset += retainLen
1519
+ }
1520
+ } else if (retainLen > 0) {
1521
+ list.pushEnd(this.children, scheduleForMerge(new RetainOp(retainLen, op.format, op.attribution)))
1522
+ this.childCnt += retainLen
1493
1523
  }
1494
1524
  } else if ($deleteOp.check(op)) {
1495
1525
  let remainingLen = op.delete
@@ -1520,6 +1550,7 @@ export class DeltaBuilder extends Delta {
1520
1550
  offset = 0
1521
1551
  scheduleForMerge(opsI.next)
1522
1552
  list.remove(this.children, opsI)
1553
+ opsI = opsI.next
1523
1554
  } else if (offset === 0) {
1524
1555
  // case 2
1525
1556
  offset = 0
@@ -1734,17 +1765,159 @@ export class DeltaBuilder extends Delta {
1734
1765
  console.info('method rebaseOnInverse unimplemented')
1735
1766
  return this
1736
1767
  }
1768
+
1769
+ /**
1770
+ * Append child ops from one op to the other.
1771
+ *
1772
+ * delta.create().insert('a').append(delta.create().insert('b')) // => insert "ab"
1773
+ *
1774
+ * @template {DeltaAny} OtherDelta
1775
+ * @param {OtherDelta} other
1776
+ * @return {CastToDelta<OtherDelta> extends Delta<any,any,infer OtherChildren,infer OtherText,any> ? DeltaBuilder<NodeName,Attrs,Children|OtherChildren,Text|OtherText,Schema> : never}
1777
+ */
1778
+ append (other) {
1779
+ const children = this.children
1780
+ const prevLast = children.end
1781
+ // @todo Investigate. Above is a typescript issue. It is necessary to cast OtherDelta to a Delta first before
1782
+ // inferring type, otherwise Children will contain Text.
1783
+ for (const child of other.children) {
1784
+ list.pushEnd(children, child.clone())
1785
+ }
1786
+ this.childCnt += other.childCnt
1787
+ prevLast?.next && tryMergeWithPrev(children, prevLast.next)
1788
+ // @ts-ignore
1789
+ return this
1790
+ }
1737
1791
  }
1738
1792
 
1793
+ /**
1794
+ * @param {ChildrenOpAny} op
1795
+ * @param {{[k:string]:any}} formatUpdate
1796
+ */
1797
+ const updateOpFormat = (op, formatUpdate) => {
1798
+ if (!$deleteOp.check(op)) {
1799
+ // apply formatting attributes
1800
+ for (const k in formatUpdate) {
1801
+ const v = formatUpdate[k]
1802
+ if (v != null || $retainOp.check(op)) {
1803
+ // never modify formats
1804
+ /** @type {any} */ (op).format = object.assign({}, op.format, { [k]: v })
1805
+ } else if (op.format != null) {
1806
+ const { [k]: _, ...rest } = op.format
1807
+ ;/** @type {any} */ (op).format = rest
1808
+ }
1809
+ }
1810
+ }
1811
+ }
1812
+
1813
+ /**
1814
+ * @template {DeltaAny} D
1815
+ * @typedef {D extends DeltaBuilder<infer N,infer Attrs,infer Children,infer Text,infer Schema> ? Delta<N,Attrs,Children,Text,Schema> : D} CastToDelta
1816
+ */
1817
+
1739
1818
  /**
1740
1819
  * @template {string} NodeName
1741
1820
  * @template {{ [key: string|number]: any }} [Attrs={}]
1742
- * @template {encoding.AnyEncodable|DeltaAny|never} [Children=never]
1821
+ * @template {fingerprintTrait.Fingerprintable|never} [Children=never]
1743
1822
  * @template {string|never} [Text=never]
1744
1823
  * @typedef {Delta<NodeName,Attrs,Children|Delta<NodeName,Attrs,Children,Text>|RecursiveDelta<NodeName,Attrs,Children,Text>,Text>} RecursiveDelta
1745
1824
  */
1746
1825
 
1747
1826
  /**
1827
+ * @template {string} Name
1828
+ * @template {{[k:string|number]:any}} Attrs
1829
+ * @template {fingerprintTrait.Fingerprintable} Children
1830
+ * @template {boolean} HasText
1831
+ * @template {{ [k:string]:any }} Formats
1832
+ * @template {boolean} Recursive
1833
+ * @extends {s.Schema<Delta<
1834
+ * Name,
1835
+ * Attrs,
1836
+ * Children|(Recursive extends true ? RecursiveDelta<Name,Attrs,Children,HasText extends true ? string : never> : never),
1837
+ * HasText extends true ? string : never,
1838
+ * any>>}
1839
+ */
1840
+ export class $Delta extends s.Schema {
1841
+ /**
1842
+ * @param {s.Schema<Name>} $name
1843
+ * @param {s.Schema<Attrs>} $attrs
1844
+ * @param {s.Schema<Children>} $children
1845
+ * @param {HasText} hasText
1846
+ * @param {s.Schema<Formats>} $formats
1847
+ * @param {Recursive} recursive
1848
+ */
1849
+ constructor ($name, $attrs, $children, hasText, $formats, recursive) {
1850
+ super()
1851
+ const $attrsPartial = s.$$object.check($attrs) ? $attrs.partial : $attrs
1852
+ if (recursive) {
1853
+ // @ts-ignore
1854
+ $children = s.$union($children, this)
1855
+ }
1856
+ this.shape = { $name, $attrs: $attrsPartial, $children, hasText, $formats }
1857
+ }
1858
+
1859
+ /**
1860
+ * @param {any} o
1861
+ * @param {s.ValidationError} [err]
1862
+ * @return {o is Delta<
1863
+ * Name,
1864
+ * Attrs,
1865
+ * Children|(Recursive extends true ? RecursiveDelta<Name,Attrs,Children,HasText extends true ? string : never> : never),
1866
+ * HasText extends true ? string : never,
1867
+ * any>}
1868
+ */
1869
+ check (o, err = undefined) {
1870
+ const { $name, $attrs, $children, hasText, $formats } = this.shape
1871
+ if (!(o instanceof Delta)) {
1872
+ err?.extend(null, 'Delta', o?.constructor.name, 'Constructor match failed')
1873
+ } else if (o.name != null && !$name.check(o.name, err)) {
1874
+ err?.extend('Delta.name', $name.toString(), o.name, 'Unexpected node name')
1875
+ } else if (list.toArray(o.children).some(c => (!hasText && $textOp.check(c)) || (hasText && $textOp.check(c) && c.format != null && !$formats.check(c.format)) || ($insertOp.check(c) && !c.insert.every(ins => $children.check(ins))))) {
1876
+ err?.extend('Delta.children', '', '', 'Children don\'t match the schema')
1877
+ } else if (object.some(o.attrs, (op, k) => $insertOp.check(op) && !$attrs.check({ [k]: op.value }, err))) {
1878
+ err?.extend('Delta.attrs', '', '', 'Attrs don\'t match the schema')
1879
+ } else {
1880
+ return true
1881
+ }
1882
+ return false
1883
+ }
1884
+ }
1885
+
1886
+ /**
1887
+ * @template {s.Schema<string>|string|Array<string>} [NodeNameSchema=s.Schema<any>]
1888
+ * @template {s.Schema<{ [key: string|number]: any }>|{ [key:string|number]:any }} [AttrsSchema=s.Schema<{}>]
1889
+ * @template {any} [ChildrenSchema=s.Schema<never>]
1890
+ * @template {boolean} [HasText=false]
1891
+ * @template {boolean} [Recursive=false]
1892
+ * @template {{ [k:string]:any }} [Formats={[k:string]:any}]
1893
+ * @param {object} opts
1894
+ * @param {NodeNameSchema?} [opts.name]
1895
+ * @param {AttrsSchema?} [opts.attrs] What key-value pairs are included.
1896
+ * @param {ChildrenSchema?} [opts.children] The type of content in `insertOp`
1897
+ * @param {HasText} [opts.text] Whether this delta contains text using `textOp`
1898
+ * @param {Formats} [opts.formats]
1899
+ * @param {Recursive} [opts.recursive]
1900
+ * @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<
1901
+ * NodeName,
1902
+ * Attrs,
1903
+ * Children|(Recursive extends true ? RecursiveDelta<NodeName,Attrs,Children,HasText extends true ? string : never> : never),
1904
+ * HasText extends true ? string : never
1905
+ * >> : never}
1906
+ */
1907
+ export const $delta = ({ name, attrs, children, text, formats, recursive }) => /** @type {any} */ (new $Delta(
1908
+ name == null ? s.$any : s.$(name),
1909
+ /** @type {any} */ (attrs == null ? s.$object({}) : s.$(attrs)),
1910
+ /** @type {any} */ (children == null ? s.$never : s.$(children)),
1911
+ text ?? false,
1912
+ formats == null ? s.$any : s.$(formats),
1913
+ recursive ?? false
1914
+ ))
1915
+
1916
+ export const $$delta = s.$constructedBy($Delta)
1917
+
1918
+ /**
1919
+ * @todo remove this
1920
+ *
1748
1921
  * @template {s.Schema<string>|string|Array<string>} [NodeNameSchema=s.Schema<any>]
1749
1922
  * @template {s.Schema<{ [key: string|number]: any }>|{ [key:string|number]:any }} [AttrsSchema=s.Schema<{}>]
1750
1923
  * @template {any} [ChildrenSchema=s.Schema<never>]
@@ -1763,7 +1936,7 @@ export class DeltaBuilder extends Delta {
1763
1936
  * HasText extends true ? string : never
1764
1937
  * >> : never}
1765
1938
  */
1766
- export const $delta = ({ name, attrs, children, text, recursive }) => {
1939
+ export const _$delta = ({ name, attrs, children, text, recursive }) => {
1767
1940
  /**
1768
1941
  * @type {s.Schema<Array<any>>}
1769
1942
  */
@@ -1795,6 +1968,11 @@ export const $delta = ({ name, attrs, children, text, recursive }) => {
1795
1968
  */
1796
1969
  export const $deltaAny = /** @type {any} */ (s.$instanceOf(Delta))
1797
1970
 
1971
+ /**
1972
+ * @type {s.Schema<DeltaBuilderAny>}
1973
+ */
1974
+ export const $deltaBuilderAny = /** @type {any} */ (s.$instanceOf(DeltaBuilder))
1975
+
1798
1976
  /**
1799
1977
  * Helper function to merge attribution and attributes. The latter input "wins".
1800
1978
  *
@@ -1802,7 +1980,9 @@ export const $deltaAny = /** @type {any} */ (s.$instanceOf(Delta))
1802
1980
  * @param {T | null} a
1803
1981
  * @param {T | null} b
1804
1982
  */
1805
- export const mergeAttrs = (a, b) => object.isEmpty(a) ? b : (object.isEmpty(b) ? a : object.assign({}, a, b))
1983
+ export const mergeAttrs = (a, b) => object.isEmpty(a)
1984
+ ? (object.isEmpty(b) ? null : b)
1985
+ : (object.isEmpty(b) ? a : object.assign({}, a, b))
1806
1986
 
1807
1987
  /**
1808
1988
  * @template {DeltaAny|null} D
@@ -1819,6 +1999,35 @@ export const mergeDeltas = (a, b) => {
1819
1999
  return a == null ? b : (a || null)
1820
2000
  }
1821
2001
 
2002
+ /**
2003
+ * @template {DeltaAny} D
2004
+ * @param {prng.PRNG} gen
2005
+ * @param {s.Schema<D>} $d
2006
+ * @return {D extends Delta<infer NodeName,infer Attrs,infer Children,infer Text,infer Schema> ? DeltaBuilder<NodeName,Attrs,Children,Text,Schema> : never}
2007
+ */
2008
+ export const random = (gen, $d) => {
2009
+ const { $name, $attrs, $children, hasText, $formats: $formats_ } = /** @type {$Delta<any,any,any,boolean,any,any>} */ (/** @type {any} */ ($d)).shape
2010
+ const d = s.$$any.check($name) ? create($deltaAny) : create(s.random(gen, $name), $deltaAny)
2011
+ const $formats = s.$$any.check($formats_) ? s.$null : $formats_
2012
+ prng.bool(gen) && d.setMany(s.random(gen, $attrs))
2013
+ for (let i = prng.uint32(gen, 0, 5); i > 0; i--) {
2014
+ if (hasText && prng.bool(gen)) {
2015
+ d.insert(prng.word(gen), s.random(gen, $formats))
2016
+ } else if (!s.$$never.check($children)) {
2017
+ /**
2018
+ * @type {Array<any>}
2019
+ */
2020
+ const ins = []
2021
+ let insN = prng.int32(gen, 0, 5)
2022
+ while (insN--) {
2023
+ ins.push(s.random(gen, $children))
2024
+ }
2025
+ d.insert(ins, s.random(gen, $formats))
2026
+ }
2027
+ }
2028
+ return /** @type {any} */ (d)
2029
+ }
2030
+
1822
2031
  /**
1823
2032
  * @overload
1824
2033
  * @return {DeltaBuilder<any,{},never,never,null>}
@@ -1879,12 +2088,12 @@ export const create = (nodeNameOrSchema, attrsOrSchema, children) => {
1879
2088
  // DELTA TEXT
1880
2089
 
1881
2090
  /**
1882
- * @template {encoding.AnyEncodable|DeltaAny} [Embeds=never]
2091
+ * @template {fingerprintTrait.Fingerprintable} [Embeds=never]
1883
2092
  * @typedef {Delta<any,{},Embeds,string>} TextDelta
1884
2093
  */
1885
2094
 
1886
2095
  /**
1887
- * @template {encoding.AnyEncodable|DeltaAny} [Embeds=never]
2096
+ * @template {fingerprintTrait.Fingerprintable} [Embeds=never]
1888
2097
  * @typedef {DeltaBuilder<any,{},Embeds,string>} TextDeltaBuilder
1889
2098
  */
1890
2099
 
@@ -1904,12 +2113,12 @@ export const $textOnly = $text()
1904
2113
  export const text = $schema => /** @type {any} */ (create($schema || $textOnly))
1905
2114
 
1906
2115
  /**
1907
- * @template {encoding.AnyEncodable|DeltaAny} Children
2116
+ * @template {fingerprintTrait.Fingerprintable} Children
1908
2117
  * @typedef {Delta<any,{},Children,never>} ArrayDelta
1909
2118
  */
1910
2119
 
1911
2120
  /**
1912
- * @template {encoding.AnyEncodable|DeltaAny} Children
2121
+ * @template {fingerprintTrait.Fingerprintable} Children
1913
2122
  * @typedef {DeltaBuilder<any,{},Children,never>} ArrayDeltaBuilder
1914
2123
  */
1915
2124
 
@@ -1955,7 +2164,7 @@ export const map = $schema => /** @type {any} */ (create(/** @type {any} */ ($sc
1955
2164
  * @template {DeltaAny} D
1956
2165
  * @param {D} d1
1957
2166
  * @param {NoInfer<D>} d2
1958
- * @return {D}
2167
+ * @return {D extends Delta<infer N,infer Attrs,infer Children,infer Text,any> ? DeltaBuilder<N,Attrs,Children,Text,null> : never}
1959
2168
  */
1960
2169
  export const diff = (d1, d2) => {
1961
2170
  /**
@@ -2006,32 +2215,136 @@ export const diff = (d1, d2) => {
2006
2215
  d.retain(change.index - lastIndex1)
2007
2216
  // insert minimal diff at curred position in d
2008
2217
  /**
2009
- * @param {DeltaBuilderAny} d
2218
+ *
2219
+ * @todo it would be better if these would be slices of delta (an actual delta)
2220
+ *
2010
2221
  * @param {ChildrenOpAny[]} opsIs
2011
2222
  * @param {ChildrenOpAny[]} opsShould
2012
- *
2013
2223
  */
2014
- const diffAndApply = (d, opsIs, opsShould) => {
2015
- // naive implementation
2016
- d.delete(opsIs.reduce((currLen, op) => currLen + op.length, 0))
2017
- opsShould.forEach(newIns => {
2018
- if ($insertOp.check(newIns) || $textOp.check(newIns)) {
2019
- d.insert(newIns.insert)
2020
- } else {
2021
- error.unexpectedCase()
2224
+ const diffAndApply = (opsIs, opsShould) => {
2225
+ const d = create()
2226
+ // @todo unoptimized implementation. Convert content to array and diff that based on
2227
+ // generated fingerprints. We probably could do better and cache more information.
2228
+ // - benchmark
2229
+ // - cache fingerprints in ops
2230
+ /**
2231
+ * @type {Array<string|DeltaAny|fingerprintTrait.Fingerprintable>}
2232
+ */
2233
+ const isContent = opsIs.flatMap(op => $insertOp.check(op) ? op.insert : ($textOp.check(op) ? op.insert.split('') : error.unexpectedCase()))
2234
+ /**
2235
+ * @type {Array<string|DeltaAny|fingerprintTrait.Fingerprintable>}
2236
+ */
2237
+ const shouldContent = opsShould.flatMap(op => $insertOp.check(op) ? op.insert : ($textOp.check(op) ? op.insert.split('') : error.unexpectedCase()))
2238
+ const isContentFingerprinted = isContent.map(c => s.$string.check(c) ? c : fingerprintTrait.fingerprint(c))
2239
+ const shouldContentFingerprinted = shouldContent.map(c => s.$string.check(c) ? c : fingerprintTrait.fingerprint(c))
2240
+ const hasFormatting = opsIs.some(op => !$deleteOp.check(op) && op.format != null) || opsShould.some(op => !$deleteOp.check(op) && op.format != null)
2241
+ /**
2242
+ * @type {{ index: number, insert: Array<string|DeltaAny|fingerprintTrait.Fingerprintable>, remove: Array<string|DeltaAny|fingerprintTrait.Fingerprintable> }[]}
2243
+ */
2244
+ const cdiff = patience.diff(isContentFingerprinted, shouldContentFingerprinted)
2245
+ // overwrite fingerprinted content with actual content
2246
+ for (let i = 0, adj = 0; i < cdiff.length; i++) {
2247
+ const cd = cdiff[i]
2248
+ cd.remove = isContent.slice(cd.index, cd.index + cd.remove.length)
2249
+ cd.insert = shouldContent.slice(cd.index + adj, cd.index + adj + cd.insert.length)
2250
+ adj += cd.remove.length - cd.insert.length
2251
+ }
2252
+ for (let i = 0, lastIndex = 0; i < cdiff.length; i++) {
2253
+ const cd = cdiff[i]
2254
+ d.retain(cd.index - lastIndex)
2255
+ let cdii = 0
2256
+ let cdri = 0
2257
+ // try to match as much content as possible, preferring to skip over non-deltas
2258
+ for (; cdii < cd.insert.length && cdri < cd.remove.length;) {
2259
+ const a = cd.insert[cdii]
2260
+ const b = cd.remove[cdri]
2261
+ if ($deltaAny.check(a) && $deltaAny.check(b) && a.name === b.name) {
2262
+ d.modify(diff(b, a))
2263
+ cdii++
2264
+ cdri++
2265
+ } else if ($deltaAny.check(b)) {
2266
+ d.insert(s.$string.check(a) ? a : [a])
2267
+ cdii++
2268
+ } else {
2269
+ d.delete(1)
2270
+ cdri++
2271
+ }
2022
2272
  }
2023
- })
2273
+ for (; cdii < cd.insert.length; cdii++) {
2274
+ const a = cd.insert[cdii]
2275
+ d.insert(s.$string.check(a) ? a : [a])
2276
+ }
2277
+ d.delete(cd.remove.length - cdri)
2278
+ }
2279
+ // create the diff for formatting
2280
+ if (hasFormatting) {
2281
+ const formattingDiff = create()
2282
+ // update opsIs with content diff. then we can figure out the formatting diff.
2283
+ const isUpdated = create()
2284
+ // copy opsIs to fresh delta
2285
+ opsIs.forEach(op => {
2286
+ isUpdated.childCnt += op.length
2287
+ list.pushEnd(isUpdated.children, op.clone())
2288
+ })
2289
+ isUpdated.apply(d)
2290
+ let shouldI = 0
2291
+ let shouldOffset = 0
2292
+ let isOp = isUpdated.children.start
2293
+ let isOffset = 0
2294
+ while (shouldI < opsShould.length && isOp != null) {
2295
+ const shouldOp = opsShould[shouldI]
2296
+ if (!$deleteOp.check(shouldOp) && !$deleteOp.check(isOp)) {
2297
+ const isFormat = isOp.format
2298
+ const minForward = math.min(shouldOp.length - shouldOffset, isOp.length - isOffset)
2299
+ shouldOffset += minForward
2300
+ isOffset += minForward
2301
+ if (fun.equalityDeep(shouldOp.format, isFormat)) {
2302
+ formattingDiff.retain(minForward)
2303
+ } else {
2304
+ /**
2305
+ * @type {FormattingAttributes}
2306
+ */
2307
+ const fupdate = {}
2308
+ shouldOp.format != null && object.forEach(shouldOp.format, (v, k) => {
2309
+ if (!fun.equalityDeep(v, isFormat?.[k] || null)) {
2310
+ fupdate[k] = v
2311
+ }
2312
+ })
2313
+ isFormat && object.forEach(isFormat, (_, k) => {
2314
+ if (shouldOp?.format?.[k] === undefined) {
2315
+ fupdate[k] = null
2316
+ }
2317
+ })
2318
+ formattingDiff.retain(minForward, fupdate)
2319
+ }
2320
+ // update offset and iterators
2321
+ if (shouldOffset >= shouldOp.length) {
2322
+ shouldI++
2323
+ shouldOffset = 0
2324
+ }
2325
+ if (isOffset >= isOp.length) {
2326
+ isOp = isOp.next
2327
+ isOffset = 0
2328
+ }
2329
+ }
2330
+ }
2331
+ d.apply(formattingDiff)
2332
+ }
2333
+ return d
2024
2334
  }
2025
- diffAndApply(d, ops1.slice(change.index, change.index + change.remove.length), ops2.slice(change.index + currIndexOffset2, change.insert.length))
2335
+ const subd = diffAndApply(ops1.slice(change.index, change.index + change.remove.length), ops2.slice(change.index + currIndexOffset2, change.index + currIndexOffset2 + change.insert.length))
2336
+ d.append(subd)
2026
2337
  lastIndex1 = change.index + change.remove.length
2027
2338
  currIndexOffset2 += change.insert.length - change.remove.length
2028
2339
  }
2029
2340
  for (const attr2 of d2.attrs) {
2030
2341
  const attr1 = d1.attrs[attr2.key]
2031
2342
  if (attr1 == null || (attr1.fingerprint !== attr2.fingerprint)) {
2343
+ /* c8 ignore else */
2032
2344
  if ($insertOp.check(attr2)) {
2033
2345
  d.set(attr2.key, attr2.value)
2034
2346
  } else {
2347
+ /* c8 ignore next 2 */
2035
2348
  error.unexpectedCase()
2036
2349
  }
2037
2350
  }
@@ -2042,5 +2355,5 @@ export const diff = (d1, d2) => {
2042
2355
  }
2043
2356
  }
2044
2357
  }
2045
- return /** @type {D} */ (d.done())
2358
+ return /** @type {any} */ (d.done(false))
2046
2359
  }