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.
- package/README.md +1 -1
- package/broadcastchannel.js +1 -1
- package/buffer.d.ts +3 -3
- package/buffer.d.ts.map +1 -1
- package/buffer.js +1 -1
- package/coverage/tmp/coverage-27667-1761218530660-0.json +1 -0
- package/coverage/tmp/{coverage-20055-1752683207886-0.json → coverage-27668-1761218485882-0.json} +1 -1
- package/crypto/aes-gcm.d.ts +4 -4
- package/crypto/aes-gcm.d.ts.map +1 -1
- package/crypto/aes-gcm.js +6 -6
- package/crypto/common.d.ts +1 -1
- package/crypto/common.d.ts.map +1 -1
- package/crypto/common.js +1 -1
- package/crypto/ecdsa.d.ts +2 -2
- package/crypto/ecdsa.d.ts.map +1 -1
- package/crypto/ecdsa.js +4 -4
- package/crypto/rsa-oaep.d.ts +2 -2
- package/crypto/rsa-oaep.d.ts.map +1 -1
- package/crypto/rsa-oaep.js +3 -3
- package/decoding.d.ts +27 -14
- package/decoding.d.ts.map +1 -1
- package/decoding.js +12 -8
- package/delta/abstract-array.d.ts +166 -0
- package/delta/abstract-array.d.ts.map +1 -0
- package/delta/abstract-array.js +421 -0
- package/delta/abstract.d.ts +69 -0
- package/delta/abstract.d.ts.map +1 -0
- package/delta/abstract.js +102 -0
- package/delta/array.d.ts +23 -0
- package/delta/array.d.ts.map +1 -0
- package/delta/array.js +45 -0
- package/delta/array.test.d.ts +2 -0
- package/delta/array.test.d.ts.map +1 -0
- package/delta/binding.d.ts +105 -0
- package/delta/binding.d.ts.map +1 -0
- package/delta/binding.js +369 -0
- package/delta/binding.test.d.ts +5 -0
- package/delta/binding.test.d.ts.map +1 -0
- package/delta/d2.d.ts +705 -0
- package/delta/d2.d.ts.map +1 -0
- package/delta/d2.js +1309 -0
- package/delta/d2.test.d.ts +15 -0
- package/delta/d2.test.d.ts.map +1 -0
- package/delta/index.d.ts +14 -0
- package/delta/index.d.ts.map +1 -0
- package/delta/index.js +79 -0
- package/delta/map.d.ts +230 -0
- package/delta/map.d.ts.map +1 -0
- package/delta/map.js +304 -0
- package/delta/node.d.ts +119 -0
- package/delta/node.d.ts.map +1 -0
- package/delta/node.js +183 -0
- package/delta/node.test.d.ts +4 -0
- package/delta/node.test.d.ts.map +1 -0
- package/delta/ops.d.ts +466 -0
- package/delta/ops.d.ts.map +1 -0
- package/delta/ops.js +544 -0
- package/delta/readme.md +129 -0
- package/delta/text.d.ts +43 -0
- package/delta/text.d.ts.map +1 -0
- package/delta/text.js +54 -0
- package/delta/text.test.d.ts +6 -0
- package/delta/text.test.d.ts.map +1 -0
- package/delta/transformer.d.ts +164 -0
- package/delta/transformer.d.ts.map +1 -0
- package/delta/transformer.js +888 -0
- package/delta/transformer.test.d.ts +13 -0
- package/delta/transformer.test.d.ts.map +1 -0
- package/delta/value.d.ts +84 -0
- package/delta/value.d.ts.map +1 -0
- package/delta/value.js +168 -0
- package/dist/abstract-array.cjs +433 -0
- package/dist/abstract-array.cjs.map +1 -0
- package/dist/abstract.cjs +122 -0
- package/dist/abstract.cjs.map +1 -0
- package/dist/aes-gcm.cjs +12 -12
- package/dist/aes-gcm.cjs.map +1 -1
- package/dist/array.cjs +60 -17
- package/dist/array.cjs.map +1 -1
- package/dist/array2.cjs +26 -0
- package/dist/array2.cjs.map +1 -0
- package/dist/binding.cjs +398 -0
- package/dist/binding.cjs.map +1 -0
- package/dist/{broadcastchannel-2c4b0a1c.cjs → broadcastchannel-b4eaea6e.cjs} +4 -4
- package/dist/broadcastchannel-b4eaea6e.cjs.map +1 -0
- package/dist/broadcastchannel.cjs +12 -12
- package/dist/{buffer-a74f7330.cjs → buffer-adc4e6ea.cjs} +7 -7
- package/dist/buffer-adc4e6ea.cjs.map +1 -0
- package/dist/buffer.cjs +11 -11
- package/dist/buffer.d.ts +3 -3
- package/dist/buffer.d.ts.map +1 -1
- package/dist/cache.cjs +6 -6
- package/dist/common.cjs +1 -1
- package/dist/common.cjs.map +1 -1
- package/dist/component.cjs +14 -9
- package/dist/component.cjs.map +1 -1
- package/dist/crypto/aes-gcm.d.ts +4 -4
- package/dist/crypto/aes-gcm.d.ts.map +1 -1
- package/dist/crypto/common.d.ts +1 -1
- package/dist/crypto/common.d.ts.map +1 -1
- package/dist/crypto/ecdsa.d.ts +2 -2
- package/dist/crypto/ecdsa.d.ts.map +1 -1
- package/dist/crypto/rsa-oaep.d.ts +2 -2
- package/dist/crypto/rsa-oaep.d.ts.map +1 -1
- package/dist/d2.cjs +1347 -0
- package/dist/d2.cjs.map +1 -0
- package/dist/{decoding-2b136346.cjs → decoding-50b9ce38.cjs} +18 -14
- package/dist/decoding-50b9ce38.cjs.map +1 -0
- package/dist/decoding.cjs +6 -6
- package/dist/decoding.d.ts +27 -14
- package/dist/decoding.d.ts.map +1 -1
- package/dist/delta/abstract-array.d.ts +166 -0
- package/dist/delta/abstract-array.d.ts.map +1 -0
- package/dist/delta/abstract.d.ts +69 -0
- package/dist/delta/abstract.d.ts.map +1 -0
- package/dist/delta/array.d.ts +23 -0
- package/dist/delta/array.d.ts.map +1 -0
- package/dist/delta/array.test.d.ts +2 -0
- package/dist/delta/array.test.d.ts.map +1 -0
- package/dist/delta/binding.d.ts +105 -0
- package/dist/delta/binding.d.ts.map +1 -0
- package/dist/delta/binding.test.d.ts +5 -0
- package/dist/delta/binding.test.d.ts.map +1 -0
- package/dist/delta/d2.d.ts +705 -0
- package/dist/delta/d2.d.ts.map +1 -0
- package/dist/delta/d2.test.d.ts +15 -0
- package/dist/delta/d2.test.d.ts.map +1 -0
- package/dist/delta/index.d.ts +14 -0
- package/dist/delta/index.d.ts.map +1 -0
- package/dist/delta/map.d.ts +230 -0
- package/dist/delta/map.d.ts.map +1 -0
- package/dist/delta/node.d.ts +119 -0
- package/dist/delta/node.d.ts.map +1 -0
- package/dist/delta/node.test.d.ts +4 -0
- package/dist/delta/node.test.d.ts.map +1 -0
- package/dist/delta/ops.d.ts +466 -0
- package/dist/delta/ops.d.ts.map +1 -0
- package/dist/delta/text.d.ts +43 -0
- package/dist/delta/text.d.ts.map +1 -0
- package/dist/delta/text.test.d.ts +6 -0
- package/dist/delta/text.test.d.ts.map +1 -0
- package/dist/delta/transformer.d.ts +164 -0
- package/dist/delta/transformer.d.ts.map +1 -0
- package/dist/delta/transformer.test.d.ts +13 -0
- package/dist/delta/transformer.test.d.ts.map +1 -0
- package/dist/delta/value.d.ts +84 -0
- package/dist/delta/value.d.ts.map +1 -0
- package/dist/{diff-77c4cf8e.cjs → diff-f0776c15.cjs} +2 -2
- package/dist/{diff-77c4cf8e.cjs.map → diff-f0776c15.cjs.map} +1 -1
- package/dist/diff.cjs +3 -3
- package/dist/{dom-16daf1a0.cjs → dom-2b123630.cjs} +31 -2
- package/dist/dom-2b123630.cjs.map +1 -0
- package/dist/dom.cjs +17 -2
- package/dist/dom.cjs.map +1 -1
- package/dist/dom.d.ts +17 -0
- package/dist/dom.d.ts.map +1 -1
- package/dist/ecdsa.cjs +4 -4
- package/dist/ecdsa.cjs.map +1 -1
- package/dist/{encoding-1acb59c4.cjs → encoding-7f85922c.cjs} +5 -5
- package/dist/encoding-7f85922c.cjs.map +1 -0
- package/dist/encoding.cjs +4 -4
- package/dist/encoding.d.ts +6 -6
- package/dist/encoding.d.ts.map +1 -1
- package/dist/{environment-2de08e0e.cjs → environment-90227ead.cjs} +4 -4
- package/dist/{environment-2de08e0e.cjs.map → environment-90227ead.cjs.map} +1 -1
- package/dist/environment.cjs +5 -5
- package/dist/{error-8582d695.cjs → error-0c1f634f.cjs} +10 -2
- package/dist/error-0c1f634f.cjs.map +1 -0
- package/dist/error.cjs +2 -1
- package/dist/error.cjs.map +1 -1
- package/dist/error.d.ts +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/{eventloop-b299a889.cjs → eventloop-a0168106.cjs} +2 -2
- package/dist/{eventloop-b299a889.cjs.map → eventloop-a0168106.cjs.map} +1 -1
- package/dist/eventloop.cjs +3 -3
- package/dist/{function-09b8292c.cjs → function-e7d18feb.cjs} +2 -2
- package/dist/{function-09b8292c.cjs.map → function-e7d18feb.cjs.map} +1 -1
- package/dist/function.cjs +2 -2
- package/dist/index.cjs +23 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index2.cjs +71 -0
- package/dist/index2.cjs.map +1 -0
- package/dist/{indexeddb-0cbb4d6f.cjs → indexeddb-46d1e737.cjs} +3 -3
- package/dist/{indexeddb-0cbb4d6f.cjs.map → indexeddb-46d1e737.cjs.map} +1 -1
- package/dist/indexeddb.cjs +5 -5
- package/dist/indexeddbV2.cjs +2 -1
- package/dist/indexeddbV2.cjs.map +1 -1
- package/dist/jwt.cjs +12 -12
- package/dist/list.cjs +39 -12
- package/dist/list.cjs.map +1 -1
- package/dist/list.d.ts +13 -3
- package/dist/list.d.ts.map +1 -1
- package/dist/logging.cjs +11 -9
- package/dist/logging.cjs.map +1 -1
- package/dist/logging.common.cjs +7 -7
- package/dist/logging.node.cjs +7 -7
- package/dist/{map-0dabcc55.cjs → map-24d263c0.cjs} +7 -1
- package/dist/map-24d263c0.cjs.map +1 -0
- package/dist/map.cjs +314 -7
- package/dist/map.cjs.map +1 -1
- package/dist/map.d.ts +1 -0
- package/dist/map.d.ts.map +1 -1
- package/dist/map2.cjs +15 -0
- package/dist/map2.cjs.map +1 -0
- package/dist/{math-08e068f9.cjs → math-96d5e8c4.cjs} +4 -2
- package/dist/math-96d5e8c4.cjs.map +1 -0
- package/dist/math.cjs +1 -1
- package/dist/math.d.ts.map +1 -1
- package/dist/metric.cjs +1 -1
- package/dist/node.cjs +206 -0
- package/dist/node.cjs.map +1 -0
- package/dist/{number-466d8922.cjs → number-1fb57bba.cjs} +2 -2
- package/dist/{number-466d8922.cjs.map → number-1fb57bba.cjs.map} +1 -1
- package/dist/number.cjs +2 -2
- package/dist/{object-491858d1.cjs → object-18980796.cjs} +12 -2
- package/dist/object-18980796.cjs.map +1 -0
- package/dist/object.cjs +3 -1
- package/dist/object.cjs.map +1 -1
- package/dist/object.d.ts +3 -0
- package/dist/object.d.ts.map +1 -1
- package/dist/observable.cjs +1 -1
- package/dist/ops.cjs +575 -0
- package/dist/ops.cjs.map +1 -0
- package/dist/patience.cjs +2 -2
- package/dist/performance.node.cjs +4 -4
- package/dist/pledge.cjs +2 -1
- package/dist/pledge.cjs.map +1 -1
- package/dist/{prng-24dfe0bf.cjs → prng-004c76e8.cjs} +5 -5
- package/dist/{prng-24dfe0bf.cjs.map → prng-004c76e8.cjs.map} +1 -1
- package/dist/prng.cjs +12 -12
- package/dist/prng.d.ts +1 -1
- package/dist/prng.d.ts.map +1 -1
- package/dist/{promise-7d13a97c.cjs → promise-cda7b9bb.cjs} +2 -2
- package/dist/{promise-7d13a97c.cjs.map → promise-cda7b9bb.cjs.map} +1 -1
- package/dist/promise.cjs +3 -3
- package/dist/rabin-gf2-polynomial.cjs +11 -11
- package/dist/rabin-uncached.cjs +11 -11
- package/dist/rabin.cjs +11 -11
- package/dist/random.cjs +1 -1
- package/dist/rsa-oaep.cjs +3 -3
- package/dist/rsa-oaep.cjs.map +1 -1
- package/dist/schema.cjs +572 -167
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.ts +326 -122
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.test.d.ts +5 -0
- package/dist/schema.test.d.ts.map +1 -1
- package/dist/{sort-b8702761.cjs → sort-812cc211.cjs} +2 -2
- package/dist/{sort-b8702761.cjs.map → sort-812cc211.cjs.map} +1 -1
- package/dist/sort.cjs +2 -2
- package/dist/{statistics-c2316dca.cjs → statistics-65f6114b.cjs} +2 -2
- package/dist/{statistics-c2316dca.cjs.map → statistics-65f6114b.cjs.map} +1 -1
- package/dist/statistics.cjs +2 -2
- package/dist/{string-b2827a90.cjs → string-fddc5f8b.cjs} +3 -3
- package/dist/string-fddc5f8b.cjs.map +1 -0
- package/dist/string.cjs +1 -1
- package/dist/string.d.ts +3 -3
- package/dist/string.d.ts.map +1 -1
- package/dist/testing.cjs +16 -16
- package/dist/text.cjs +79 -0
- package/dist/text.cjs.map +1 -0
- package/dist/{time-bc2081b9.cjs → time-d8438852.cjs} +2 -2
- package/dist/{time-bc2081b9.cjs.map → time-d8438852.cjs.map} +1 -1
- package/dist/time.cjs +2 -2
- package/dist/traits.cjs +22 -0
- package/dist/traits.cjs.map +1 -1
- package/dist/traits.d.ts +1 -0
- package/dist/traits.d.ts.map +1 -1
- package/dist/traits.test.d.ts.map +1 -1
- package/dist/transformer.cjs +930 -0
- package/dist/transformer.cjs.map +1 -0
- package/dist/url.cjs +2 -1
- package/dist/url.cjs.map +1 -1
- package/dist/value.cjs +187 -0
- package/dist/value.cjs.map +1 -0
- package/dist/webcrypto.d.ts +1 -1
- package/dist/webcrypto.d.ts.map +1 -1
- package/dist/{websocket-40a601d4.cjs → websocket-b073d0fc.cjs} +3 -3
- package/dist/{websocket-40a601d4.cjs.map → websocket-b073d0fc.cjs.map} +1 -1
- package/dist/websocket.cjs +4 -4
- package/dom.d.ts +17 -0
- package/dom.d.ts.map +1 -1
- package/dom.js +21 -0
- package/encoding.d.ts +6 -6
- package/encoding.d.ts.map +1 -1
- package/encoding.js +1 -1
- package/error.d.ts +1 -0
- package/error.d.ts.map +1 -1
- package/error.js +6 -0
- package/list.d.ts +13 -3
- package/list.d.ts.map +1 -1
- package/list.js +36 -8
- package/map.d.ts +1 -0
- package/map.d.ts.map +1 -1
- package/map.js +6 -0
- package/math.d.ts.map +1 -1
- package/math.js +3 -1
- package/object.d.ts +3 -0
- package/object.d.ts.map +1 -1
- package/object.js +9 -1
- package/package.json +9 -3
- package/prng.d.ts +1 -1
- package/prng.d.ts.map +1 -1
- package/prng.js +1 -1
- package/schema.d.ts +326 -122
- package/schema.d.ts.map +1 -1
- package/schema.js +513 -141
- package/schema.test.d.ts +5 -0
- package/schema.test.d.ts.map +1 -1
- package/string.d.ts +3 -3
- package/string.d.ts.map +1 -1
- package/string.js +2 -2
- package/test.html +1 -0
- package/test.js +13 -1
- package/traits.d.ts +1 -0
- package/traits.d.ts.map +1 -1
- package/traits.js +21 -0
- package/traits.test.d.ts.map +1 -1
- package/webcrypto.d.ts +1 -1
- package/webcrypto.d.ts.map +1 -1
- package/coverage/tmp/coverage-20054-1752683240888-0.json +0 -1
- package/dist/broadcastchannel-2c4b0a1c.cjs.map +0 -1
- package/dist/buffer-a74f7330.cjs.map +0 -1
- package/dist/decoding-2b136346.cjs.map +0 -1
- package/dist/dom-16daf1a0.cjs.map +0 -1
- package/dist/encoding-1acb59c4.cjs.map +0 -1
- package/dist/error-8582d695.cjs.map +0 -1
- package/dist/map-0dabcc55.cjs.map +0 -1
- package/dist/math-08e068f9.cjs.map +0 -1
- package/dist/object-491858d1.cjs.map +0 -1
- 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
|
+
})
|