lib0 0.2.112 → 0.2.115-0

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 (331) hide show
  1. package/README.md +1 -1
  2. package/broadcastchannel.js +1 -1
  3. package/buffer.d.ts +3 -3
  4. package/buffer.d.ts.map +1 -1
  5. package/buffer.js +1 -1
  6. package/coverage/tmp/coverage-27667-1761218530660-0.json +1 -0
  7. package/coverage/tmp/{coverage-20055-1752683207886-0.json → coverage-27668-1761218485882-0.json} +1 -1
  8. package/crypto/aes-gcm.d.ts +4 -4
  9. package/crypto/aes-gcm.d.ts.map +1 -1
  10. package/crypto/aes-gcm.js +6 -6
  11. package/crypto/common.d.ts +1 -1
  12. package/crypto/common.d.ts.map +1 -1
  13. package/crypto/common.js +1 -1
  14. package/crypto/ecdsa.d.ts +2 -2
  15. package/crypto/ecdsa.d.ts.map +1 -1
  16. package/crypto/ecdsa.js +4 -4
  17. package/crypto/rsa-oaep.d.ts +2 -2
  18. package/crypto/rsa-oaep.d.ts.map +1 -1
  19. package/crypto/rsa-oaep.js +3 -3
  20. package/decoding.d.ts +27 -14
  21. package/decoding.d.ts.map +1 -1
  22. package/decoding.js +12 -8
  23. package/delta/abstract-array.d.ts +166 -0
  24. package/delta/abstract-array.d.ts.map +1 -0
  25. package/delta/abstract-array.js +421 -0
  26. package/delta/abstract.d.ts +69 -0
  27. package/delta/abstract.d.ts.map +1 -0
  28. package/delta/abstract.js +102 -0
  29. package/delta/array.d.ts +23 -0
  30. package/delta/array.d.ts.map +1 -0
  31. package/delta/array.js +45 -0
  32. package/delta/array.test.d.ts +2 -0
  33. package/delta/array.test.d.ts.map +1 -0
  34. package/delta/binding.d.ts +105 -0
  35. package/delta/binding.d.ts.map +1 -0
  36. package/delta/binding.js +369 -0
  37. package/delta/binding.test.d.ts +5 -0
  38. package/delta/binding.test.d.ts.map +1 -0
  39. package/delta/d2.d.ts +705 -0
  40. package/delta/d2.d.ts.map +1 -0
  41. package/delta/d2.js +1309 -0
  42. package/delta/d2.test.d.ts +15 -0
  43. package/delta/d2.test.d.ts.map +1 -0
  44. package/delta/index.d.ts +14 -0
  45. package/delta/index.d.ts.map +1 -0
  46. package/delta/index.js +79 -0
  47. package/delta/map.d.ts +230 -0
  48. package/delta/map.d.ts.map +1 -0
  49. package/delta/map.js +304 -0
  50. package/delta/node.d.ts +119 -0
  51. package/delta/node.d.ts.map +1 -0
  52. package/delta/node.js +183 -0
  53. package/delta/node.test.d.ts +4 -0
  54. package/delta/node.test.d.ts.map +1 -0
  55. package/delta/ops.d.ts +466 -0
  56. package/delta/ops.d.ts.map +1 -0
  57. package/delta/ops.js +544 -0
  58. package/delta/readme.md +129 -0
  59. package/delta/text.d.ts +43 -0
  60. package/delta/text.d.ts.map +1 -0
  61. package/delta/text.js +54 -0
  62. package/delta/text.test.d.ts +6 -0
  63. package/delta/text.test.d.ts.map +1 -0
  64. package/delta/transformer.d.ts +164 -0
  65. package/delta/transformer.d.ts.map +1 -0
  66. package/delta/transformer.js +888 -0
  67. package/delta/transformer.test.d.ts +13 -0
  68. package/delta/transformer.test.d.ts.map +1 -0
  69. package/delta/value.d.ts +84 -0
  70. package/delta/value.d.ts.map +1 -0
  71. package/delta/value.js +168 -0
  72. package/dist/abstract-array.cjs +433 -0
  73. package/dist/abstract-array.cjs.map +1 -0
  74. package/dist/abstract.cjs +122 -0
  75. package/dist/abstract.cjs.map +1 -0
  76. package/dist/aes-gcm.cjs +12 -12
  77. package/dist/aes-gcm.cjs.map +1 -1
  78. package/dist/array.cjs +60 -17
  79. package/dist/array.cjs.map +1 -1
  80. package/dist/array2.cjs +26 -0
  81. package/dist/array2.cjs.map +1 -0
  82. package/dist/binding.cjs +398 -0
  83. package/dist/binding.cjs.map +1 -0
  84. package/dist/{broadcastchannel-2c4b0a1c.cjs → broadcastchannel-b4eaea6e.cjs} +4 -4
  85. package/dist/broadcastchannel-b4eaea6e.cjs.map +1 -0
  86. package/dist/broadcastchannel.cjs +12 -12
  87. package/dist/{buffer-a74f7330.cjs → buffer-adc4e6ea.cjs} +7 -7
  88. package/dist/buffer-adc4e6ea.cjs.map +1 -0
  89. package/dist/buffer.cjs +11 -11
  90. package/dist/buffer.d.ts +3 -3
  91. package/dist/buffer.d.ts.map +1 -1
  92. package/dist/cache.cjs +6 -6
  93. package/dist/common.cjs +1 -1
  94. package/dist/common.cjs.map +1 -1
  95. package/dist/component.cjs +14 -9
  96. package/dist/component.cjs.map +1 -1
  97. package/dist/crypto/aes-gcm.d.ts +4 -4
  98. package/dist/crypto/aes-gcm.d.ts.map +1 -1
  99. package/dist/crypto/common.d.ts +1 -1
  100. package/dist/crypto/common.d.ts.map +1 -1
  101. package/dist/crypto/ecdsa.d.ts +2 -2
  102. package/dist/crypto/ecdsa.d.ts.map +1 -1
  103. package/dist/crypto/rsa-oaep.d.ts +2 -2
  104. package/dist/crypto/rsa-oaep.d.ts.map +1 -1
  105. package/dist/d2.cjs +1347 -0
  106. package/dist/d2.cjs.map +1 -0
  107. package/dist/{decoding-2b136346.cjs → decoding-50b9ce38.cjs} +18 -14
  108. package/dist/decoding-50b9ce38.cjs.map +1 -0
  109. package/dist/decoding.cjs +6 -6
  110. package/dist/decoding.d.ts +27 -14
  111. package/dist/decoding.d.ts.map +1 -1
  112. package/dist/delta/abstract-array.d.ts +166 -0
  113. package/dist/delta/abstract-array.d.ts.map +1 -0
  114. package/dist/delta/abstract.d.ts +69 -0
  115. package/dist/delta/abstract.d.ts.map +1 -0
  116. package/dist/delta/array.d.ts +23 -0
  117. package/dist/delta/array.d.ts.map +1 -0
  118. package/dist/delta/array.test.d.ts +2 -0
  119. package/dist/delta/array.test.d.ts.map +1 -0
  120. package/dist/delta/binding.d.ts +105 -0
  121. package/dist/delta/binding.d.ts.map +1 -0
  122. package/dist/delta/binding.test.d.ts +5 -0
  123. package/dist/delta/binding.test.d.ts.map +1 -0
  124. package/dist/delta/d2.d.ts +705 -0
  125. package/dist/delta/d2.d.ts.map +1 -0
  126. package/dist/delta/d2.test.d.ts +15 -0
  127. package/dist/delta/d2.test.d.ts.map +1 -0
  128. package/dist/delta/index.d.ts +14 -0
  129. package/dist/delta/index.d.ts.map +1 -0
  130. package/dist/delta/map.d.ts +230 -0
  131. package/dist/delta/map.d.ts.map +1 -0
  132. package/dist/delta/node.d.ts +119 -0
  133. package/dist/delta/node.d.ts.map +1 -0
  134. package/dist/delta/node.test.d.ts +4 -0
  135. package/dist/delta/node.test.d.ts.map +1 -0
  136. package/dist/delta/ops.d.ts +466 -0
  137. package/dist/delta/ops.d.ts.map +1 -0
  138. package/dist/delta/text.d.ts +43 -0
  139. package/dist/delta/text.d.ts.map +1 -0
  140. package/dist/delta/text.test.d.ts +6 -0
  141. package/dist/delta/text.test.d.ts.map +1 -0
  142. package/dist/delta/transformer.d.ts +164 -0
  143. package/dist/delta/transformer.d.ts.map +1 -0
  144. package/dist/delta/transformer.test.d.ts +13 -0
  145. package/dist/delta/transformer.test.d.ts.map +1 -0
  146. package/dist/delta/value.d.ts +84 -0
  147. package/dist/delta/value.d.ts.map +1 -0
  148. package/dist/{diff-77c4cf8e.cjs → diff-f0776c15.cjs} +2 -2
  149. package/dist/{diff-77c4cf8e.cjs.map → diff-f0776c15.cjs.map} +1 -1
  150. package/dist/diff.cjs +3 -3
  151. package/dist/{dom-16daf1a0.cjs → dom-2b123630.cjs} +31 -2
  152. package/dist/dom-2b123630.cjs.map +1 -0
  153. package/dist/dom.cjs +17 -2
  154. package/dist/dom.cjs.map +1 -1
  155. package/dist/dom.d.ts +17 -0
  156. package/dist/dom.d.ts.map +1 -1
  157. package/dist/ecdsa.cjs +4 -4
  158. package/dist/ecdsa.cjs.map +1 -1
  159. package/dist/{encoding-1acb59c4.cjs → encoding-7f85922c.cjs} +5 -5
  160. package/dist/encoding-7f85922c.cjs.map +1 -0
  161. package/dist/encoding.cjs +4 -4
  162. package/dist/encoding.d.ts +6 -6
  163. package/dist/encoding.d.ts.map +1 -1
  164. package/dist/{environment-2de08e0e.cjs → environment-90227ead.cjs} +4 -4
  165. package/dist/{environment-2de08e0e.cjs.map → environment-90227ead.cjs.map} +1 -1
  166. package/dist/environment.cjs +5 -5
  167. package/dist/{error-8582d695.cjs → error-0c1f634f.cjs} +10 -2
  168. package/dist/error-0c1f634f.cjs.map +1 -0
  169. package/dist/error.cjs +2 -1
  170. package/dist/error.cjs.map +1 -1
  171. package/dist/error.d.ts +1 -0
  172. package/dist/error.d.ts.map +1 -1
  173. package/dist/{eventloop-b299a889.cjs → eventloop-a0168106.cjs} +2 -2
  174. package/dist/{eventloop-b299a889.cjs.map → eventloop-a0168106.cjs.map} +1 -1
  175. package/dist/eventloop.cjs +3 -3
  176. package/dist/{function-09b8292c.cjs → function-e7d18feb.cjs} +2 -2
  177. package/dist/{function-09b8292c.cjs.map → function-e7d18feb.cjs.map} +1 -1
  178. package/dist/function.cjs +2 -2
  179. package/dist/index.cjs +23 -22
  180. package/dist/index.cjs.map +1 -1
  181. package/dist/index2.cjs +71 -0
  182. package/dist/index2.cjs.map +1 -0
  183. package/dist/{indexeddb-0cbb4d6f.cjs → indexeddb-46d1e737.cjs} +3 -3
  184. package/dist/{indexeddb-0cbb4d6f.cjs.map → indexeddb-46d1e737.cjs.map} +1 -1
  185. package/dist/indexeddb.cjs +5 -5
  186. package/dist/indexeddbV2.cjs +2 -1
  187. package/dist/indexeddbV2.cjs.map +1 -1
  188. package/dist/jwt.cjs +12 -12
  189. package/dist/list.cjs +39 -12
  190. package/dist/list.cjs.map +1 -1
  191. package/dist/list.d.ts +13 -3
  192. package/dist/list.d.ts.map +1 -1
  193. package/dist/logging.cjs +11 -9
  194. package/dist/logging.cjs.map +1 -1
  195. package/dist/logging.common.cjs +7 -7
  196. package/dist/logging.node.cjs +7 -7
  197. package/dist/{map-0dabcc55.cjs → map-24d263c0.cjs} +7 -1
  198. package/dist/map-24d263c0.cjs.map +1 -0
  199. package/dist/map.cjs +314 -7
  200. package/dist/map.cjs.map +1 -1
  201. package/dist/map.d.ts +1 -0
  202. package/dist/map.d.ts.map +1 -1
  203. package/dist/map2.cjs +15 -0
  204. package/dist/map2.cjs.map +1 -0
  205. package/dist/{math-08e068f9.cjs → math-96d5e8c4.cjs} +4 -2
  206. package/dist/math-96d5e8c4.cjs.map +1 -0
  207. package/dist/math.cjs +1 -1
  208. package/dist/math.d.ts.map +1 -1
  209. package/dist/metric.cjs +1 -1
  210. package/dist/node.cjs +206 -0
  211. package/dist/node.cjs.map +1 -0
  212. package/dist/{number-466d8922.cjs → number-1fb57bba.cjs} +2 -2
  213. package/dist/{number-466d8922.cjs.map → number-1fb57bba.cjs.map} +1 -1
  214. package/dist/number.cjs +2 -2
  215. package/dist/{object-491858d1.cjs → object-18980796.cjs} +12 -2
  216. package/dist/object-18980796.cjs.map +1 -0
  217. package/dist/object.cjs +3 -1
  218. package/dist/object.cjs.map +1 -1
  219. package/dist/object.d.ts +3 -0
  220. package/dist/object.d.ts.map +1 -1
  221. package/dist/observable.cjs +1 -1
  222. package/dist/ops.cjs +575 -0
  223. package/dist/ops.cjs.map +1 -0
  224. package/dist/patience.cjs +2 -2
  225. package/dist/performance.node.cjs +4 -4
  226. package/dist/pledge.cjs +2 -1
  227. package/dist/pledge.cjs.map +1 -1
  228. package/dist/{prng-24dfe0bf.cjs → prng-004c76e8.cjs} +5 -5
  229. package/dist/{prng-24dfe0bf.cjs.map → prng-004c76e8.cjs.map} +1 -1
  230. package/dist/prng.cjs +12 -12
  231. package/dist/prng.d.ts +1 -1
  232. package/dist/prng.d.ts.map +1 -1
  233. package/dist/{promise-7d13a97c.cjs → promise-cda7b9bb.cjs} +2 -2
  234. package/dist/{promise-7d13a97c.cjs.map → promise-cda7b9bb.cjs.map} +1 -1
  235. package/dist/promise.cjs +3 -3
  236. package/dist/rabin-gf2-polynomial.cjs +11 -11
  237. package/dist/rabin-uncached.cjs +11 -11
  238. package/dist/rabin.cjs +11 -11
  239. package/dist/random.cjs +1 -1
  240. package/dist/rsa-oaep.cjs +3 -3
  241. package/dist/rsa-oaep.cjs.map +1 -1
  242. package/dist/schema.cjs +572 -167
  243. package/dist/schema.cjs.map +1 -1
  244. package/dist/schema.d.ts +326 -122
  245. package/dist/schema.d.ts.map +1 -1
  246. package/dist/schema.test.d.ts +5 -0
  247. package/dist/schema.test.d.ts.map +1 -1
  248. package/dist/{sort-b8702761.cjs → sort-812cc211.cjs} +2 -2
  249. package/dist/{sort-b8702761.cjs.map → sort-812cc211.cjs.map} +1 -1
  250. package/dist/sort.cjs +2 -2
  251. package/dist/{statistics-c2316dca.cjs → statistics-65f6114b.cjs} +2 -2
  252. package/dist/{statistics-c2316dca.cjs.map → statistics-65f6114b.cjs.map} +1 -1
  253. package/dist/statistics.cjs +2 -2
  254. package/dist/{string-b2827a90.cjs → string-fddc5f8b.cjs} +3 -3
  255. package/dist/string-fddc5f8b.cjs.map +1 -0
  256. package/dist/string.cjs +1 -1
  257. package/dist/string.d.ts +3 -3
  258. package/dist/string.d.ts.map +1 -1
  259. package/dist/testing.cjs +16 -16
  260. package/dist/text.cjs +79 -0
  261. package/dist/text.cjs.map +1 -0
  262. package/dist/{time-bc2081b9.cjs → time-d8438852.cjs} +2 -2
  263. package/dist/{time-bc2081b9.cjs.map → time-d8438852.cjs.map} +1 -1
  264. package/dist/time.cjs +2 -2
  265. package/dist/traits.cjs +22 -0
  266. package/dist/traits.cjs.map +1 -1
  267. package/dist/traits.d.ts +1 -0
  268. package/dist/traits.d.ts.map +1 -1
  269. package/dist/traits.test.d.ts.map +1 -1
  270. package/dist/transformer.cjs +930 -0
  271. package/dist/transformer.cjs.map +1 -0
  272. package/dist/url.cjs +2 -1
  273. package/dist/url.cjs.map +1 -1
  274. package/dist/value.cjs +187 -0
  275. package/dist/value.cjs.map +1 -0
  276. package/dist/webcrypto.d.ts +1 -1
  277. package/dist/webcrypto.d.ts.map +1 -1
  278. package/dist/{websocket-40a601d4.cjs → websocket-b073d0fc.cjs} +3 -3
  279. package/dist/{websocket-40a601d4.cjs.map → websocket-b073d0fc.cjs.map} +1 -1
  280. package/dist/websocket.cjs +4 -4
  281. package/dom.d.ts +17 -0
  282. package/dom.d.ts.map +1 -1
  283. package/dom.js +21 -0
  284. package/encoding.d.ts +6 -6
  285. package/encoding.d.ts.map +1 -1
  286. package/encoding.js +1 -1
  287. package/error.d.ts +1 -0
  288. package/error.d.ts.map +1 -1
  289. package/error.js +6 -0
  290. package/list.d.ts +13 -3
  291. package/list.d.ts.map +1 -1
  292. package/list.js +36 -8
  293. package/map.d.ts +1 -0
  294. package/map.d.ts.map +1 -1
  295. package/map.js +6 -0
  296. package/math.d.ts.map +1 -1
  297. package/math.js +3 -1
  298. package/object.d.ts +3 -0
  299. package/object.d.ts.map +1 -1
  300. package/object.js +9 -1
  301. package/package.json +9 -3
  302. package/prng.d.ts +1 -1
  303. package/prng.d.ts.map +1 -1
  304. package/prng.js +1 -1
  305. package/schema.d.ts +326 -122
  306. package/schema.d.ts.map +1 -1
  307. package/schema.js +513 -141
  308. package/schema.test.d.ts +5 -0
  309. package/schema.test.d.ts.map +1 -1
  310. package/string.d.ts +3 -3
  311. package/string.d.ts.map +1 -1
  312. package/string.js +2 -2
  313. package/test.html +1 -0
  314. package/test.js +13 -1
  315. package/traits.d.ts +1 -0
  316. package/traits.d.ts.map +1 -1
  317. package/traits.js +21 -0
  318. package/traits.test.d.ts.map +1 -1
  319. package/webcrypto.d.ts +1 -1
  320. package/webcrypto.d.ts.map +1 -1
  321. package/coverage/tmp/coverage-20054-1752683240888-0.json +0 -1
  322. package/dist/broadcastchannel-2c4b0a1c.cjs.map +0 -1
  323. package/dist/buffer-a74f7330.cjs.map +0 -1
  324. package/dist/decoding-2b136346.cjs.map +0 -1
  325. package/dist/dom-16daf1a0.cjs.map +0 -1
  326. package/dist/encoding-1acb59c4.cjs.map +0 -1
  327. package/dist/error-8582d695.cjs.map +0 -1
  328. package/dist/map-0dabcc55.cjs.map +0 -1
  329. package/dist/math-08e068f9.cjs.map +0 -1
  330. package/dist/object-491858d1.cjs.map +0 -1
  331. package/dist/string-b2827a90.cjs.map +0 -1
@@ -0,0 +1,888 @@
1
+ import * as error from '../error.js'
2
+ import * as delta from './index.js'
3
+ import * as s from '../schema.js'
4
+
5
+ /**
6
+ * Creates a transformer template after receiving schema for DeltaA.
7
+ *
8
+ * @template {delta.AbstractDelta} DeltaA
9
+ * @typedef {<DA extends DeltaA> ($deltaA: s.Schema<DA>) => Template<any,DA,any>} TransformerFactory
10
+ */
11
+
12
+ /**
13
+ * @template {TransformerFactory<any>} T
14
+ * @template {delta.AbstractDelta} DeltaA
15
+ * @typedef {T extends (($deltaA: s.Schema<DeltaA>) => Template<any,DeltaA,infer DeltaB>) ? DeltaB : never } DeltaBFromTransformerFactory
16
+ */
17
+
18
+ /**
19
+ * @template {s.Unwrap<delta.$delta>|null} [DeltaA=s.Unwrap<delta.$delta>|null]
20
+ * @template {s.Unwrap<delta.$delta>|null} [DeltaB=s.Unwrap<delta.$delta>|null]
21
+ * @typedef {{ a: DeltaA, b: DeltaB }} TransformResult
22
+ */
23
+
24
+ /**
25
+ * @template {s.Unwrap<delta.$delta>|null} DeltaA
26
+ * @template {s.Unwrap<delta.$delta>|null} DeltaB
27
+ * @param {DeltaA} a
28
+ * @param {DeltaB} b
29
+ * @return {TransformResult<DeltaA,DeltaB>}
30
+ */
31
+ export const transformResult = (a, b) => ({ a, b })
32
+ export const transformResultEmpty = transformResult(null, null)
33
+
34
+ /**
35
+ * @template {any} State
36
+ * @template {s.Unwrap<delta.$delta>} DeltaA
37
+ * @template {s.Unwrap<delta.$delta>} DeltaB
38
+ * @typedef {object} TransformerDef
39
+ * @property {s.Schema<DeltaA>} TransformerDef.$in
40
+ * @property {s.Schema<DeltaB>} TransformerDef.$out
41
+ * @property {function (this: Template<State,DeltaA,DeltaB>): State} TransformerDef.state
42
+ * @property {(deltaIn:NoInfer<DeltaA>,s:NoInfer<State>) => TransformResult<NoInfer<DeltaA>?,NoInfer<DeltaB>?>} TransformerDef.applyA
43
+ * @property {(deltaOut:NoInfer<DeltaB>,s:NoInfer<State>) => TransformResult<NoInfer<DeltaA>?,NoInfer<DeltaB>?>} TransformerDef.applyB
44
+ */
45
+
46
+ /**
47
+ * A Delta Transformer ensures that it keeps two sources A and B in-sync, even if they use a
48
+ * different update format.
49
+ *
50
+ * @template {any} State
51
+ * @template {s.Unwrap<typeof delta.$delta>} DeltaA
52
+ * @template {s.Unwrap<typeof delta.$delta>} DeltaB
53
+ */
54
+ export class Transformer {
55
+ /**
56
+ * @param {Template<State,DeltaA,DeltaB>} t
57
+ * @param {State} s
58
+ */
59
+ constructor (t, s) {
60
+ this.t = t
61
+ this._state = s
62
+ /**
63
+ * Pending a op, for internal use only
64
+ * @type {DeltaA?}
65
+ */
66
+ this._pa = null
67
+ /**
68
+ * Pending a op, for internal use only
69
+ * @type {DeltaB?}
70
+ */
71
+ this._pb = null
72
+ /**
73
+ * Whether this transformer value has been initially consumebd by the parent transformer.
74
+ */
75
+ this._init = false
76
+ /**
77
+ * @type {Transformer<any,any,any>?}
78
+ */
79
+ this.parent = null
80
+ }
81
+
82
+ /**
83
+ * @param {DeltaA} deltaA
84
+ * @return {TransformResult<DeltaA?,DeltaB?>}
85
+ */
86
+ applyA (deltaA) {
87
+ return this.t._applyA(deltaA, this._state)
88
+ }
89
+
90
+ /**
91
+ * @param {DeltaB} deltaB
92
+ * @return {TransformResult<DeltaA?,DeltaB?>}
93
+ */
94
+ applyB (deltaB) {
95
+ return this.t._applyB(deltaB, this._state)
96
+ }
97
+ }
98
+
99
+ /**
100
+ * @param {Array<Transformer<any,delta.AbstractDelta,delta.AbstractDelta>>} trs
101
+ * @param {TransformResult} output
102
+ * @return {boolean}
103
+ */
104
+ const _forwardPipe = (trs, output) => {
105
+ let again = false
106
+ for (let i = 0; i < trs.length; i++) {
107
+ const tr = trs[i]
108
+ if (tr._pa === null) continue
109
+ const { a, b } = tr.applyA(tr._pa)
110
+ tr._pa = null
111
+ if (a !== null) {
112
+ if (i === 0) {
113
+ output.a = delta.mergeDeltas(output.a, a)
114
+ } else {
115
+ // need to interate back to integrate the produced backwards-change
116
+ again = true
117
+ trs[i - 1]._pb = a
118
+ }
119
+ }
120
+ if (b !== null) {
121
+ if (i === trs.length - 1) {
122
+ output.b = delta.mergeDeltas(output.b, b)
123
+ } else {
124
+ trs[i + 1]._pa = b
125
+ }
126
+ }
127
+ }
128
+ return again
129
+ }
130
+
131
+ /**
132
+ * @param {Array<Transformer<any,delta.AbstractDelta,delta.AbstractDelta>>} trs
133
+ * @param {TransformResult} output
134
+ * @return {boolean}
135
+ */
136
+ const _backwardPipe = (trs, output) => {
137
+ let again = false
138
+ for (let i = trs.length - 1; i >= 0; i--) {
139
+ const tr = trs[i]
140
+ if (tr._pb === null) continue
141
+ const { a, b } = tr.applyA(tr._pb)
142
+ tr._pb = null
143
+ if (a !== null) {
144
+ if (i === 0) {
145
+ output.a = delta.mergeDeltas(output.a, a)
146
+ } else {
147
+ // need to interate back to integrate the produced backwards-change
148
+ trs[i - 1]._pb = a
149
+ }
150
+ }
151
+ if (b !== null) {
152
+ if (i === trs.length - 1) {
153
+ output.b = delta.mergeDeltas(output.b, b)
154
+ } else {
155
+ // need to interate back to integrate the produced backwards-change
156
+ again = true
157
+ trs[i + 1]._pa = a
158
+ }
159
+ }
160
+ }
161
+ return again
162
+ }
163
+
164
+ /**
165
+ * @template State
166
+ * @template {s.Unwrap<typeof delta.$delta>} DeltaA
167
+ * @template {s.Unwrap<typeof delta.$delta>} DeltaB
168
+ */
169
+ export class Template {
170
+ /**
171
+ * @param {TransformerDef<State,DeltaA,DeltaB>} def
172
+ */
173
+ constructor ({ $in, $out, state, applyA, applyB }) {
174
+ /**
175
+ * @type {s.Schema<DeltaA>}
176
+ */
177
+ this.$in = $in
178
+ /**
179
+ * @type {s.Schema<DeltaB>}
180
+ */
181
+ this.$out = $out
182
+ /**
183
+ * @type {() => State}
184
+ */
185
+ this._state = state
186
+ /**
187
+ * @type {typeof applyA}
188
+ */
189
+ this._applyA = applyA
190
+ /**
191
+ * @type {typeof applyB}
192
+ */
193
+ this._applyB = applyB
194
+ /**
195
+ * Cache for stateless transformers.
196
+ *
197
+ * @type {Transformer<State,DeltaA,DeltaB>?}
198
+ */
199
+ this._tr = null
200
+ }
201
+
202
+ /**
203
+ * @template {delta.AbstractDelta} R
204
+ * @param {($d: s.Schema<DeltaB>) => Template<any,DeltaB,R>} t
205
+ * @return {Template<any,DeltaA,R>}
206
+ */
207
+ pipe (t) {
208
+ /**
209
+ * @type {TransformerPipeTemplate<any,any>}
210
+ */
211
+ const tpipe = new TransformerPipeTemplate()
212
+ tpipe.templates.push(this, t(this.$out))
213
+ return tpipe
214
+ }
215
+
216
+ init () {
217
+ if (this._tr != null) return this._tr
218
+ // reuse stateless transformers
219
+ const s = this._state()
220
+ if (s === null) {
221
+ return (this._tr = new Transformer(this, s))
222
+ }
223
+ return new Transformer(this, s)
224
+ }
225
+ }
226
+
227
+ /**
228
+ * @template {delta.AbstractDelta} DeltaA
229
+ * @template {delta.AbstractDelta} DeltaB
230
+ * @param {s.Schema<DeltaA>} $deltaA
231
+ * @param {s.Schema<DeltaB>} $deltaB
232
+ * @return {s.Schema<Template<any,DeltaA,DeltaB>>}
233
+ */
234
+ export const $template = ($deltaA, $deltaB) => /** @type {s.Schema<Template<any,any,any>>} */ (s.$instanceOf(Template, o => o.$in.extends($deltaA) && o.$out.extends($deltaB)))
235
+ export const $templateAny = /** @type {s.Schema<Template<any,any,any>>} */ (s.$instanceOf(Template))
236
+
237
+ /**
238
+ * @template {delta.AbstractDelta} DeltaA
239
+ * @template {delta.AbstractDelta} DeltaB
240
+ * @typedef {Template<any,DeltaA,DeltaB>|(
241
+ * DeltaB extends delta.Map<infer MKV>
242
+ * ? (MKV|DeltaB)
243
+ * : (DeltaB extends delta.Array<infer MArr> ? (MArr|DeltaB) : DeltaB))
244
+ * } MaybeFixedTemplate
245
+ */
246
+
247
+ /**
248
+ * @template X
249
+ * @typedef {X extends Template<any,any,infer D> ? (D extends delta.Value<infer V> ? V : D) : X} UnwrapTemplateForArray
250
+ */
251
+
252
+ /**
253
+ * @template {any} MaybeFixed
254
+ * @typedef {MaybeFixed extends Template<any,any,any>
255
+ * ? MaybeFixed
256
+ * : Template<any,any,
257
+ * MaybeFixed extends delta.AbstractDelta
258
+ * ? MaybeFixed
259
+ * : (MaybeFixed extends Array<any>
260
+ * ? delta.Array<UnwrapTemplateForArray<MaybeFixed[number]>>
261
+ * : (MaybeFixed extends {[key:string]:any} ? delta.Map<MaybeFixed> : never))
262
+ * >
263
+ * } MaybeFixedTemplateToTemplate
264
+ */
265
+
266
+ /**
267
+ * @template MaybeFixed
268
+ * @param {MaybeFixed} maybeFixed
269
+ * @return {MaybeFixed extends Template<any,any,delta.Delta> ? (Extract<MaybeFixed,Template<any,any,any>>) : Template<any,any,MaybeFixed extends delta.Delta ? Extract<MaybeFixed,delta.Delta> : delta.Array<MaybeFixed[keyof MaybeFixed]>>}
270
+ */
271
+ export const maybeFixedToTemplate = maybeFixed => $templateAny.check(maybeFixed)
272
+ ? /** @type {any} */ (maybeFixed)
273
+ : (delta.$delta.check(maybeFixed)
274
+ ? /** @type {any} */ (fixed(maybeFixed))
275
+ : (s.$arrayAny.check(maybeFixed)
276
+ ? /** @type {any} */ (fixed(delta.array().insert(maybeFixed).done()))
277
+ : (s.$objectAny.check(maybeFixed) ? /** @type {any} */ (fixed(delta.map().setMany(maybeFixed).done())) : error.unexpectedCase())
278
+ )
279
+ )
280
+
281
+ /**
282
+ * @template {delta.AbstractDelta} DeltaA
283
+ * @template {Template<any,DeltaA,any>} Tr
284
+ * @param {s.Schema<DeltaA>} _$deltaA
285
+ * @param {Tr} transformer
286
+ * @return {<DA extends DeltaA>($d:s.Schema<DA>) => Tr extends Template<any,any,infer DeltaB> ? Template<any,DA,DeltaB> : never}
287
+ */
288
+ export const transformStatic = (_$deltaA, transformer) => () => /** @type {any} */ (transformer)
289
+
290
+ /**
291
+ * @template {delta.AbstractDelta} DeltaA
292
+ * @template {<DA extends DeltaA> ($deltaA: s.Schema<DA>) => Template<any,DA,any>} TF
293
+ * @param {s.Schema<DeltaA>} _$deltaA
294
+ * @param {TF} transformerFactory
295
+ * @return {TF}
296
+ */
297
+ export const transform = (_$deltaA, transformerFactory) => transformerFactory
298
+
299
+ /**
300
+ * @type {TransformerDef<any,any,any>}
301
+ */
302
+ const pipeTemplateDef = {
303
+ $in: s.$any,
304
+ $out: s.$any,
305
+ state: function () { return /** @type {TransformerPipeTemplate<any,any>} */ (/** @type {unknown} */ (this)).templates.map(t => t.init()) },
306
+ applyA: (dchange, trs) => {
307
+ const output = transformResult(null, null)
308
+ let again = true
309
+ trs[0]._pa = dchange
310
+ while (again) {
311
+ // apply forwards
312
+ again = _forwardPipe(trs, output)
313
+ // iterate back
314
+ if (again) {
315
+ again = _backwardPipe(trs, output)
316
+ }
317
+ }
318
+ return output
319
+ },
320
+ applyB: (dchange, trs) => {
321
+ const output = transformResult(null, null)
322
+ let again = true
323
+ trs[trs.length - 1]._pb = dchange
324
+ while (again) {
325
+ // iterate back
326
+ again = _backwardPipe(trs, output)
327
+ // apply forwards
328
+ if (again) {
329
+ again = _forwardPipe(trs, output)
330
+ }
331
+ }
332
+ return output
333
+ }
334
+ }
335
+
336
+ /**
337
+ * @todo just have something like "previousTemplate" to implement pipe. This can be assembled when
338
+ * init the template.
339
+ * @template {s.Unwrap<typeof delta.$delta>} DeltaA
340
+ * @template {s.Unwrap<typeof delta.$delta>} DeltaB
341
+ * @extends {Template<any,DeltaA,DeltaB>}
342
+ */
343
+ class TransformerPipeTemplate extends Template {
344
+ constructor () {
345
+ super(pipeTemplateDef)
346
+ /**
347
+ * @type {Array<Template<any,DeltaA,DeltaB>>}
348
+ */
349
+ this.templates = []
350
+ }
351
+
352
+ /**
353
+ * @template {delta.AbstractDelta} R
354
+ * @param {($d: s.Schema<DeltaB>) => Template<any,DeltaB,R>} t
355
+ * @return {Template<any,DeltaA,R>}
356
+ */
357
+ pipe (t) {
358
+ /**
359
+ * @type {TransformerPipeTemplate<any,any>}
360
+ */
361
+ const tpipe = new TransformerPipeTemplate()
362
+ tpipe.templates = this.templates.slice()
363
+ tpipe.templates.push(t(this.$out))
364
+ return /** @type {any} */ (tpipe)
365
+ }
366
+ }
367
+
368
+ /**
369
+ * @template {delta.AbstractDelta} DeltaA
370
+ * @template {delta.AbstractDelta} DeltaB
371
+ * @template {delta.AbstractDelta} DeltaC
372
+ * @param {($s: s.Schema<DeltaA>) => Template<any,DeltaA,DeltaB>} t1
373
+ * @param {($s: s.Schema<DeltaB>) => Template<any,DeltaB,DeltaC>} t2
374
+ * @return {($d: s.Schema<DeltaA>) => Template<any,DeltaA,DeltaC>}
375
+ */
376
+ export const pipe = (t1, t2) => ($d) => {
377
+ /**
378
+ * @type {TransformerPipeTemplate<any,any>}
379
+ */
380
+ const tpipe = new TransformerPipeTemplate()
381
+ const t1t = t1($d)
382
+ tpipe.templates.push(t1t, t2(t1t.$out))
383
+ return tpipe
384
+ }
385
+
386
+ /**
387
+ * @template {any} State
388
+ * @template {s.Unwrap<typeof delta.$delta>} DeltaIn
389
+ * @template {s.Unwrap<typeof delta.$delta>} DeltaOut
390
+ * @param {TransformerDef<State,DeltaIn,DeltaOut>} def
391
+ * @return {Template<State,DeltaIn,DeltaOut>}
392
+ */
393
+ export const template = def => new Template(/** @type {any} */ (def))
394
+
395
+ /**
396
+ * @template FixedContent
397
+ * @param {FixedContent} fixedContent
398
+ * @return {Template<any,any,FixedContent extends delta.AbstractDelta ? FixedContent : delta.Value<FixedContent>>}
399
+ */
400
+ export const fixed = fixedContent => {
401
+ const staticDelta = delta.$delta.check(fixedContent) ? fixedContent : delta.value().set(fixedContent).done()
402
+ return template({
403
+ $in: s.$any,
404
+ $out: s.$any,
405
+ state: () => ({ e: false }),
406
+ applyA: (_d, s) => {
407
+ if (!s.e) {
408
+ s.e = true
409
+ return transformResult(null, staticDelta)
410
+ }
411
+ return transformResultEmpty
412
+ },
413
+ applyB: () => {
414
+ // @todo should reverse the change and give back
415
+ error.unexpectedCase()
416
+ }
417
+ })
418
+ }
419
+
420
+ /**
421
+ * @template MaybeTemplate
422
+ * @typedef {[MaybeTemplate] extends [Template<any,any,any>] ? MaybeTemplate : Template<any,any,
423
+ * [MaybeTemplate] extends [delta.AbstractDelta] ? MaybeTemplate : delta.Value<MaybeTemplate>
424
+ * >} AnyToTemplate
425
+ */
426
+
427
+ /**
428
+ * @template {{ [key: string]: any }} MaybeTemplateMap
429
+ * @typedef {{ [K in keyof MaybeTemplateMap]: AnyToTemplate<MaybeTemplateMap[K]> }} AnyMapToTemplate
430
+ */
431
+
432
+ /**
433
+ * @template {Array<any>} MaybeTemplateArray
434
+ * @typedef {{ [K in keyof MaybeTemplateArray]: AnyToTemplate<MaybeTemplateArray[K]> }} AnyArrayToTemplate
435
+ */
436
+
437
+ /**
438
+ * @template {{ [key:string]: any }} T
439
+ * @typedef {Template<
440
+ * any,
441
+ * AnyMapToTemplate<T>[keyof T] extends Template<any, infer DeltaA,any> ? DeltaA : never,
442
+ * delta.Map<{ [K in keyof T]: AnyToTemplate<T[K]> extends Template<any, any, infer DeltaB>
443
+ * ? (DeltaB extends delta.Value<infer V> ? V : DeltaB) : AnyToTemplate<T[K]> }>
444
+ * >} MapDefToTemplate
445
+ */
446
+
447
+ /**
448
+ * @template {{ [key:string]: any }} T
449
+ * @param {T} definition
450
+ * @return {MapDefToTemplate<T> extends Template<any,infer A,infer B> ? Template<any,A,B> : never}
451
+ */
452
+ export const map = (definition) => {
453
+ /**
454
+ * @type {{ [key:string]: Template<any,any,any> }}
455
+ */
456
+ const def = {}
457
+ for (const key in definition) {
458
+ const d = definition[key]
459
+ def[key] = $templateAny.check(d) ? d : fixed(d)
460
+ }
461
+ return template({
462
+ $in: s.$any,
463
+ $out: s.$any,
464
+ state: () => {
465
+ const mapState = /** @type {{ [key: string]: Transformer<any,any,any> }} */ ({})
466
+ for (const key in def) {
467
+ mapState[key] = def[key].init()
468
+ }
469
+ return /** @type {{ [key in keyof T]: T extends Template<any,infer SDIn, infer SDOut> ? Transformer<any, SDIn, SDOut>: never }} */ (mapState)
470
+ },
471
+ applyA: (d, state) => {
472
+ return _applyMapOpHelper(state, [{ d, src: null }])
473
+ },
474
+ applyB: (d, state) => {
475
+ s.assert(d, delta.$mapAny)
476
+ /**
477
+ * @type {Array<{ d: delta.AbstractDelta, src: Transformer<any,any,any>? }>}
478
+ */
479
+ const reverseAChanges = []
480
+ d.forEach(op => {
481
+ if (delta.$deleteOp.check(op)) {
482
+ error.unexpectedCase()
483
+ }
484
+ const src = state[op.key]
485
+ // src expects a delta value
486
+ const res = src.applyB(delta.$modifyOp.check(op) ? delta.value().modify(op.value) : delta.value().set(op.value))
487
+ src._pa = res.a
488
+ src._pb = res.b
489
+ if (res.a != null) {
490
+ reverseAChanges.push({ d: res.a, src })
491
+ }
492
+ })
493
+ return _applyMapOpHelper(state, reverseAChanges)
494
+ }
495
+ })
496
+ }
497
+
498
+ /**
499
+ * @param {{ [key: string]: Transformer<any, any, any> }} state
500
+ * @param {Array<{ d: delta.AbstractDelta, src: Transformer<any,any,any>? }>} reverseAChanges
501
+ * @return {TransformResult<delta.AbstractDelta?,delta.Map<any>?>}
502
+ */
503
+ const _applyMapOpHelper = (state, reverseAChanges) => {
504
+ /**
505
+ * @type {TransformResult<delta.AbstractDelta?,delta.Map<any>?>}
506
+ */
507
+ const applyResult = transformResult(null, null)
508
+ while (reverseAChanges.length > 0) {
509
+ /**
510
+ * @type {Array<{ d: delta.AbstractDelta, src: Transformer<any,any,any>? }>}
511
+ */
512
+ let nextReverseAChanges = []
513
+ for (const key in state) {
514
+ const s = state[key]
515
+ let transformPriority = false // false until own is found
516
+ for (let i = 0; i < reverseAChanges.length; i++) {
517
+ // changes are applied in reverseAChanges order.
518
+ // rebase against all concurrent (the op stored on transformer), then apply
519
+ const r = reverseAChanges[i]
520
+ if (r.src === s) {
521
+ transformPriority = true // own has less priority, concurrent is applied with higher prio
522
+ continue // don't apply own
523
+ }
524
+ let rd = r.d
525
+ if (s._pa != null) {
526
+ rd = rd.clone()
527
+ rd.rebase(s._pa, transformPriority)
528
+ }
529
+ const res = s.applyA(rd)
530
+ s._pa = res.a
531
+ s._pb = delta.mergeDeltas(s._pb, res.b)
532
+ if (res.a != null) {
533
+ nextReverseAChanges.push({ d: res.a, src: s })
534
+ }
535
+ }
536
+ }
537
+ // merge changes for output
538
+ for (let i = 0; i < reverseAChanges.length; i++) {
539
+ const rc = reverseAChanges[i]
540
+ if (rc.src != null) { // don't apply received deltas
541
+ applyResult.a = delta.mergeDeltas(applyResult.a, rc.d)
542
+ }
543
+ }
544
+ reverseAChanges = nextReverseAChanges
545
+ nextReverseAChanges = []
546
+ }
547
+ // accumulate b changes stored on transformers
548
+ const bRes = delta.map()
549
+ for (const key in state) {
550
+ const s = state[key]
551
+ if (s._pb) {
552
+ if (s._init) {
553
+ bRes.modify(key, s._pb)
554
+ } else {
555
+ s._init = true
556
+ bRes.set(key, s._pb)
557
+ }
558
+ }
559
+ }
560
+ if (bRes._changes.size > 0) {
561
+ // opt values (iff delta is of type DeltaValue, map the change to the map)
562
+ bRes._changes.forEach((change, key) => {
563
+ if (delta.$valueAny.check(change.value)) {
564
+ const changeOp = change.value.change
565
+ if (delta.$insertOp.check(changeOp) || delta.$modifyOp.check(changeOp)) {
566
+ bRes.set(key, changeOp.value)
567
+ } else if (delta.$deleteOp.check(changeOp)) {
568
+ bRes.delete(key)
569
+ } else {
570
+ error.unexpectedCase()
571
+ }
572
+ }
573
+ })
574
+ applyResult.b = bRes
575
+ }
576
+ return applyResult
577
+ }
578
+
579
+ /**
580
+ * @todo This is similar to dt.map. Consider the similarities and try to merge them.
581
+ *
582
+ * @template {Array<any>} T
583
+ * @param {T} definition
584
+ * @return {Template<
585
+ * any,
586
+ * AnyArrayToTemplate<T>[number] extends Template<any, infer DeltaA, any> ? DeltaA : never,
587
+ * delta.Array<AnyArrayToTemplate<T>[number] extends Template<any, any, infer DeltaB> ? delta.ValueUnwrap<DeltaB> : never>
588
+ * >}
589
+ */
590
+ export const array = (definition) => {
591
+ /**
592
+ * @type {Array<Template<any,any,any>>}
593
+ */
594
+ const def = []
595
+ for (let i = 0; i < definition.length; i++) {
596
+ const d = definition[i]
597
+ def[i] = $templateAny.check(d) ? d : fixed(d)
598
+ }
599
+ return /** @type {any} */ (template({
600
+ $in: s.$any,
601
+ $out: delta.$arrayAny,
602
+ state: () => {
603
+ const arrState = /** @type {Transformer<any,any,any>[]} */ ([])
604
+ for (let i = 0; i < def.length; i++) {
605
+ arrState[i] = def[i].init()
606
+ }
607
+ return /** @type {(T extends Template<any,infer SDIn, infer SDOut> ? Transformer<any, SDIn, SDOut>: never)[]} */ (arrState)
608
+ },
609
+ applyA: (d, state) => {
610
+ return _applyArrayOpHelper(state, [{ d, src: null }])
611
+ },
612
+ applyB: (d, state) => {
613
+ s.assert(d, delta.$arrayAny)
614
+ /**
615
+ * @type {Array<{ d: delta.AbstractDelta, src: Transformer<any,any,any>? }>}
616
+ */
617
+ const reverseAChanges = []
618
+ d.forEach((op, index) => {
619
+ if (delta.$deleteOp.check(op) || delta.$insertOp.check(op)) {
620
+ error.unexpectedCase()
621
+ } else if (delta.$modifyOp.check(op)) {
622
+ const src = state[index]
623
+ const res = src.applyB(op.modify)
624
+ src._pa = res.a
625
+ src._pb = res.b
626
+ if (res.a != null) {
627
+ reverseAChanges.push({ d: res.a, src })
628
+ }
629
+ }
630
+ })
631
+ return _applyArrayOpHelper(state, reverseAChanges)
632
+ }
633
+ }))
634
+ }
635
+
636
+ /**
637
+ * @param {Transformer<any, any, any>[]} state
638
+ * @param {Array<{ d: delta.AbstractDelta, src: Transformer<any,any,any>? }>} reverseAChanges
639
+ * @return {TransformResult<delta.AbstractDelta?,delta.Array<any>?>}
640
+ */
641
+ const _applyArrayOpHelper = (state, reverseAChanges) => {
642
+ /**
643
+ * @type {TransformResult<delta.AbstractDelta?,delta.Array<any>?>}
644
+ */
645
+ const applyResult = transformResult(null, null)
646
+ while (reverseAChanges.length > 0) {
647
+ /**
648
+ * @type {Array<{ d: delta.AbstractDelta, src: Transformer<any,any,any>? }>}
649
+ */
650
+ let nextReverseAChanges = []
651
+ for (let i = 0; i < state.length; i++) {
652
+ const s = state[i]
653
+ let transformPriority = false // false until own is found
654
+ for (let i = 0; i < reverseAChanges.length; i++) {
655
+ // changes are applied in reverseAChanges order.
656
+ // rebase against all concurrent (the op stored on transformer), then apply
657
+ const r = reverseAChanges[i]
658
+ if (r.src === s) {
659
+ transformPriority = true // own has less priority, concurrent is applied with higher prio
660
+ continue // don't apply own
661
+ }
662
+ let rd = r.d
663
+ if (s._pa != null) {
664
+ rd = rd.clone()
665
+ rd.rebase(s._pa, transformPriority)
666
+ }
667
+ const res = s.applyA(rd)
668
+ s._pa = res.a
669
+ s._pb = delta.mergeDeltas(s._pb, res.b)
670
+ if (res.a != null) {
671
+ nextReverseAChanges.push({ d: res.a, src: s })
672
+ }
673
+ }
674
+ }
675
+ // merge changes for output
676
+ for (let i = 0; i < nextReverseAChanges.length; i++) {
677
+ applyResult.a = delta.mergeDeltas(applyResult.a, nextReverseAChanges[i].d)
678
+ }
679
+ reverseAChanges = nextReverseAChanges
680
+ nextReverseAChanges = []
681
+ }
682
+ // accumulate b changes stored on transformers
683
+ const bRes = delta.array()
684
+ let performedChange = false
685
+ for (let i = 0; i < state.length; i++) {
686
+ const s = state[i]
687
+ let spb = s._pb
688
+ if (spb) {
689
+ if (delta.$valueAny.check(spb)) {
690
+ spb = spb.get()
691
+ }
692
+ if (s._init) {
693
+ bRes.modify(spb)
694
+ } else {
695
+ s._init = true
696
+ bRes.insert([spb])
697
+ }
698
+ performedChange = true
699
+ } else {
700
+ bRes.retain(1)
701
+ }
702
+ }
703
+ if (performedChange) {
704
+ applyResult.b = bRes.done()
705
+ }
706
+ return applyResult
707
+ }
708
+
709
+ /**
710
+ * @param {TransformResult<delta.AbstractDelta?, delta.Node<any,any,any>>} res
711
+ * @param {{ attrs: Transformer<any,any,any>, children: Transformer<any,any,any> }} state
712
+ * @param {delta.AbstractDelta?} nextAAttrs apply this in reverse!
713
+ * @param {delta.AbstractDelta?} nextAChildren
714
+ */
715
+ const _nodeApplyA = (res, state, nextAAttrs, nextAChildren) => {
716
+ while (nextAAttrs != null || nextAChildren != null) {
717
+ const resChildren = nextAChildren && state.children.applyA(nextAChildren)
718
+ const resAttrs = (nextAAttrs || resChildren?.a) ? state.attrs.applyA(delta.mergeDeltas(nextAAttrs, resChildren?.a)) : null
719
+ nextAChildren = resAttrs?.a
720
+ nextAAttrs = null
721
+ res.a = delta.mergeDeltas(delta.mergeDeltas(res.a, resChildren?.a), resAttrs?.a)
722
+ resChildren?.b && res.b.children.apply(resChildren.b)
723
+ resAttrs?.b && res.b.attributes.apply(resAttrs.b)
724
+ }
725
+ }
726
+
727
+ /**
728
+ * @template {{ [key:string]: any } | Template<any,any,delta.Map<any>>} T
729
+ * @typedef {T extends Template<any,any,any> ? T : MapDefToTemplate<T>} MapOrMapDefToTemplate
730
+ */
731
+
732
+ /**
733
+ * @template {string} NodeName
734
+ * @template {{ [key:string]:any } | Template<any,any,delta.Map<{[key:string]:any}>>} Attrs - accepts map or map definition
735
+ * @template {Template<any,any,delta.Array<any,any>> | Array<any>} Children
736
+ * @param {NodeName} name
737
+ * @param {Attrs} attributes
738
+ * @param {Children} children
739
+ * @return {Template<
740
+ * any,
741
+ * MapOrMapDefToTemplate<Attrs> extends Template<any, infer A, any> ? A : never,
742
+ * delta.Node<
743
+ * NodeName,
744
+ * MapOrMapDefToTemplate<Attrs> extends Template<any,any,delta.Map<infer M>> ? M : never,
745
+ * MaybeFixedTemplateToTemplate<Children> extends Template<any,any,delta.Array<infer BChildren,any>> ? BChildren : never,
746
+ * any
747
+ * >
748
+ * >}
749
+ */
750
+ export const node = (name, attributes, children) => {
751
+ const attrs = /** @type {Template<any,any,delta.Map<any>>} */ ($templateAny.check(attributes) ? attributes : map(attributes))
752
+ const childs = /** @type {Template<any,any,delta.Array<any>>} */ (maybeFixedToTemplate(children))
753
+ // @todo this should be properly inferred
754
+ return /** @type {any} */ (template({
755
+ $in: s.$any,
756
+ $out: delta.$node(s.$literal(name), s.$any, s.$any),
757
+ state: () => ({
758
+ attrs: attrs.init(),
759
+ children: childs.init()
760
+ }),
761
+ applyA: (d, state) => {
762
+ const res = transformResult(null, /** @type {delta.Node<NodeName,any,any,any>} */ (delta.node(name)))
763
+ _nodeApplyA(res, state, d, d)
764
+ return res
765
+ },
766
+ applyB: (d, state) => {
767
+ s.assert(d, delta.$nodeAny)
768
+ const res = transformResult(null, /** @type {delta.Node<NodeName,any,any,any>} */ (delta.node(name)))
769
+ const childrenRes = d.children.ops.length === 0 ? transformResultEmpty : state.children.applyB(/** @type {delta.Array<any,any>} */(d.children))
770
+ const attrsRes = d.attributes._changes.size === 0 ? transformResultEmpty : state.attrs.applyB(d.attributes)
771
+ attrsRes.b && res.b.attributes.apply(attrsRes.b)
772
+ childrenRes.b && res.b.children.apply(/** @type {delta.Array<any,false>} */ (childrenRes.b))
773
+ res.a = delta.mergeDeltas(attrsRes.a, childrenRes.a)
774
+ _nodeApplyA(res, state, childrenRes.a, attrsRes.a)
775
+ return res
776
+ }
777
+ }))
778
+ }
779
+
780
+ /**
781
+ * @template {{[k:string]:any}} KV
782
+ * @typedef {delta.Map<KV> | delta.Node<any,KV,any,any>} _FollowPath
783
+ */
784
+
785
+ /**
786
+ * @template {any} D
787
+ * @template {string[]} Path
788
+ * @typedef {Path extends []
789
+ * ? D
790
+ * : Path extends [infer P, ...infer PRest]
791
+ * ? (
792
+ * P extends string ? (D extends _AttrDeltaType<{ [K in P]: infer V }> ? QueryFollowPath<V,PRest extends string[] ? PRest : never> : never) : never
793
+ * )
794
+ * : never
795
+ * } QueryFollowPath
796
+ */
797
+
798
+ /**
799
+ * @template {{[k:string]:any}} Attrs
800
+ * @typedef {delta.Map<Partial<Attrs>> | delta.Node<any,Partial<Attrs>,any,any>} _AttrDeltaType
801
+ */
802
+
803
+ /**
804
+ * @template {Array<string>} Path
805
+ * @typedef {Path extends [infer P, ...infer PRest] ? (_AttrDeltaType<{ [K in (P extends string ? P : any)]: PathToDelta<PRest extends Array<string> ? PRest : any> }>) : any} PathToDelta
806
+ */
807
+
808
+ /**
809
+ * @template {Array<string>} Path
810
+ * @param {Path} path
811
+ * @return {<DA extends PathToDelta<Path>>($in: s.Schema<DA>) => Template<any, DA, delta.Value<QueryFollowPath<DA,Path>>>}
812
+ */
813
+ export const query = (...path) => transformStatic(s.$any, template({
814
+ $in: delta.$delta,
815
+ $out: delta.$valueAny,
816
+ state: () => null,
817
+ applyA: d => {
818
+ d = delta.$nodeAny.check(d) ? d.attributes : d
819
+ let cd = /** @type {delta.Map<any>?} */ (delta.$mapAny.cast(d))
820
+ let overwritten = false
821
+ for (let i = 0; i < path.length && cd != null; i++) {
822
+ if (delta.$mapAny.check(cd)) {
823
+ const c = cd.get(path[i])
824
+ if (delta.$insertOp.check(c)) {
825
+ overwritten = true
826
+ cd = c.value
827
+ } else if (delta.$deleteOp.check(c)) {
828
+ overwritten = true
829
+ cd = null
830
+ break
831
+ } else if (delta.$modifyOp.check(c)) {
832
+ cd = c.value
833
+ }
834
+ } else {
835
+ cd = null
836
+ }
837
+ }
838
+ const dv = delta.value()
839
+ if (overwritten) {
840
+ // @todo implement some kind of "ValueDelta" with insert, delete, modify ops. dmap is supposed
841
+ // to automatically translate this.
842
+ if (cd == null) {
843
+ dv.delete()
844
+ } else {
845
+ dv.set(cd)
846
+ }
847
+ } else {
848
+ dv.modify(cd)
849
+ }
850
+ return transformResult(null, dv)
851
+ },
852
+ applyB: (d) => {
853
+ const dop = d.change
854
+ let resD = delta.map()
855
+ let i = path.length - 1
856
+ const p = path[i]
857
+ if (delta.$modifyOp.check(dop)) {
858
+ resD.modify(p, dop.value)
859
+ } else if (delta.$insertOp.check(dop)) {
860
+ resD.set(p, dop.value)
861
+ } else if (delta.$deleteOp.check(dop)) {
862
+ resD.delete(p)
863
+ }
864
+ for (i--; i >= 0; i--) {
865
+ const tmpDmap = delta.map()
866
+ tmpDmap.modify(p, resD)
867
+ resD = tmpDmap
868
+ }
869
+ return /** @type {TransformResult<any,null>} */ (transformResult(resD, null))
870
+ }
871
+ }))
872
+
873
+ /**
874
+ * @template {delta.AbstractDelta} Delta
875
+ * @param {s.Schema<Delta>} $in
876
+ * @return {Template<null,Delta,Delta>}
877
+ */
878
+ export const id = $in => template({
879
+ $in,
880
+ $out: $in,
881
+ state: () => null,
882
+ applyA: d => {
883
+ return transformResult(null, d)
884
+ },
885
+ applyB: d => {
886
+ return transformResult(d, null)
887
+ }
888
+ })