@evolu/common 8.4.0 → 8.6.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/dist/src/Array.d.ts +191 -94
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +91 -40
- package/dist/src/Assert.d.ts +233 -30
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +151 -30
- package/dist/src/BigInt.d.ts +3 -3
- package/dist/src/BigInt.js +3 -3
- package/dist/src/Brand.d.ts +7 -7
- package/dist/src/Buffer.d.ts +12 -4
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Cache.d.ts +8 -3
- package/dist/src/Cache.d.ts.map +1 -1
- package/dist/src/Cache.js +8 -3
- package/dist/src/Callbacks.d.ts +8 -4
- package/dist/src/Callbacks.d.ts.map +1 -1
- package/dist/src/Console.d.ts +45 -30
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +32 -21
- package/dist/src/Crypto.d.ts +13 -8
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +6 -3
- package/dist/src/Eq.d.ts +107 -58
- package/dist/src/Eq.d.ts.map +1 -1
- package/dist/src/Eq.js +308 -112
- package/dist/src/Function.d.ts +54 -24
- package/dist/src/Function.d.ts.map +1 -1
- package/dist/src/Function.js +34 -17
- package/dist/src/Http.d.ts +52 -19
- package/dist/src/Http.d.ts.map +1 -1
- package/dist/src/Identicon.d.ts +9 -4
- package/dist/src/Identicon.d.ts.map +1 -1
- package/dist/src/Identicon.js +9 -4
- package/dist/src/LeakDetector.d.ts.map +1 -1
- package/dist/src/LeakDetector.js +4 -1
- package/dist/src/LockManager.d.ts +12 -10
- package/dist/src/LockManager.d.ts.map +1 -1
- package/dist/src/Lookup.d.ts +4 -2
- package/dist/src/Lookup.d.ts.map +1 -1
- package/dist/src/Lookup.js +5 -2
- package/dist/src/Number.d.ts +28 -24
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Number.js +16 -17
- package/dist/src/Object.d.ts +89 -47
- package/dist/src/Object.d.ts.map +1 -1
- package/dist/src/Object.js +88 -41
- package/dist/src/Option.d.ts +14 -5
- package/dist/src/Option.d.ts.map +1 -1
- package/dist/src/Option.js +14 -5
- package/dist/src/Order.d.ts +12 -12
- package/dist/src/Order.js +12 -12
- package/dist/src/Platform.d.ts +2 -2
- package/dist/src/Platform.js +1 -0
- package/dist/src/Random.d.ts +7 -4
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/Redacted.d.ts +13 -6
- package/dist/src/Redacted.d.ts.map +1 -1
- package/dist/src/Redacted.js +4 -2
- package/dist/src/Ref.d.ts +4 -4
- package/dist/src/Relation.d.ts +5 -7
- package/dist/src/Relation.d.ts.map +1 -1
- package/dist/src/Relation.js +3 -3
- package/dist/src/Resource.d.ts +27 -12
- package/dist/src/Resource.d.ts.map +1 -1
- package/dist/src/Resource.js +9 -3
- package/dist/src/Result.d.ts +258 -114
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +74 -39
- package/dist/src/Schedule.d.ts +233 -116
- package/dist/src/Schedule.d.ts.map +1 -1
- package/dist/src/Schedule.js +204 -110
- package/dist/src/Set.d.ts +43 -24
- package/dist/src/Set.d.ts.map +1 -1
- package/dist/src/Set.js +25 -13
- package/dist/src/Sqlite.d.ts +4 -4
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +18 -15
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Store.js +3 -1
- package/dist/src/String.d.ts.map +1 -1
- package/dist/src/String.js +1 -1
- package/dist/src/Task.d.ts +555 -264
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +278 -168
- package/dist/src/Test.d.ts +10 -4
- package/dist/src/Test.d.ts.map +1 -1
- package/dist/src/Test.js +11 -4
- package/dist/src/Time.d.ts +27 -17
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +25 -8
- package/dist/src/Type.d.ts +1218 -372
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +1056 -379
- package/dist/src/Types.d.ts +95 -40
- package/dist/src/Types.d.ts.map +1 -1
- package/dist/src/Types.js +13 -4
- package/dist/src/WebSocket.d.ts +14 -6
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +8 -0
- package/dist/src/Worker.d.ts +10 -6
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +1 -1
- package/dist/src/intl/_en.d.ts +3 -1
- package/dist/src/intl/_en.d.ts.map +1 -1
- package/dist/src/intl/_en.js +17 -3
- package/dist/src/intl/ar.d.ts +3 -1
- package/dist/src/intl/ar.d.ts.map +1 -1
- package/dist/src/intl/ar.js +15 -2
- package/dist/src/intl/bn.d.ts +3 -1
- package/dist/src/intl/bn.d.ts.map +1 -1
- package/dist/src/intl/bn.js +16 -3
- package/dist/src/intl/ca.d.ts +3 -1
- package/dist/src/intl/ca.d.ts.map +1 -1
- package/dist/src/intl/ca.js +16 -3
- package/dist/src/intl/cs.d.ts +3 -1
- package/dist/src/intl/cs.d.ts.map +1 -1
- package/dist/src/intl/cs.js +16 -3
- package/dist/src/intl/da.d.ts +3 -1
- package/dist/src/intl/da.d.ts.map +1 -1
- package/dist/src/intl/da.js +16 -3
- package/dist/src/intl/de.d.ts +3 -1
- package/dist/src/intl/de.d.ts.map +1 -1
- package/dist/src/intl/de.js +16 -3
- package/dist/src/intl/el.d.ts +3 -1
- package/dist/src/intl/el.d.ts.map +1 -1
- package/dist/src/intl/el.js +16 -3
- package/dist/src/intl/es.d.ts +3 -1
- package/dist/src/intl/es.d.ts.map +1 -1
- package/dist/src/intl/es.js +16 -3
- package/dist/src/intl/fa.d.ts +3 -1
- package/dist/src/intl/fa.d.ts.map +1 -1
- package/dist/src/intl/fa.js +16 -3
- package/dist/src/intl/fi.d.ts +3 -1
- package/dist/src/intl/fi.d.ts.map +1 -1
- package/dist/src/intl/fi.js +16 -3
- package/dist/src/intl/fil.d.ts +3 -1
- package/dist/src/intl/fil.d.ts.map +1 -1
- package/dist/src/intl/fil.js +16 -3
- package/dist/src/intl/fr.d.ts +3 -1
- package/dist/src/intl/fr.d.ts.map +1 -1
- package/dist/src/intl/fr.js +16 -3
- package/dist/src/intl/he.d.ts +3 -1
- package/dist/src/intl/he.d.ts.map +1 -1
- package/dist/src/intl/he.js +16 -3
- package/dist/src/intl/hi.d.ts +3 -1
- package/dist/src/intl/hi.d.ts.map +1 -1
- package/dist/src/intl/hi.js +16 -3
- package/dist/src/intl/hr.d.ts +3 -1
- package/dist/src/intl/hr.d.ts.map +1 -1
- package/dist/src/intl/hr.js +16 -3
- package/dist/src/intl/hu.d.ts +2 -1
- package/dist/src/intl/hu.d.ts.map +1 -1
- package/dist/src/intl/hu.js +15 -3
- package/dist/src/intl/id.d.ts +3 -1
- package/dist/src/intl/id.d.ts.map +1 -1
- package/dist/src/intl/id.js +16 -3
- package/dist/src/intl/it.d.ts +3 -1
- package/dist/src/intl/it.d.ts.map +1 -1
- package/dist/src/intl/it.js +16 -3
- package/dist/src/intl/ja.d.ts +3 -1
- package/dist/src/intl/ja.d.ts.map +1 -1
- package/dist/src/intl/ja.js +16 -3
- package/dist/src/intl/ko.d.ts +3 -1
- package/dist/src/intl/ko.d.ts.map +1 -1
- package/dist/src/intl/ko.js +16 -3
- package/dist/src/intl/ml.d.ts +3 -1
- package/dist/src/intl/ml.d.ts.map +1 -1
- package/dist/src/intl/ml.js +16 -3
- package/dist/src/intl/mr.d.ts +3 -1
- package/dist/src/intl/mr.d.ts.map +1 -1
- package/dist/src/intl/mr.js +16 -3
- package/dist/src/intl/ms.d.ts +3 -1
- package/dist/src/intl/ms.d.ts.map +1 -1
- package/dist/src/intl/ms.js +15 -2
- package/dist/src/intl/nb.d.ts +2 -1
- package/dist/src/intl/nb.d.ts.map +1 -1
- package/dist/src/intl/nb.js +14 -2
- package/dist/src/intl/nl.d.ts +3 -1
- package/dist/src/intl/nl.d.ts.map +1 -1
- package/dist/src/intl/nl.js +16 -3
- package/dist/src/intl/pa.d.ts +3 -1
- package/dist/src/intl/pa.d.ts.map +1 -1
- package/dist/src/intl/pa.js +16 -3
- package/dist/src/intl/pl.d.ts +2 -0
- package/dist/src/intl/pl.d.ts.map +1 -1
- package/dist/src/intl/pl.js +15 -2
- package/dist/src/intl/pt-BR.d.ts +3 -1
- package/dist/src/intl/pt-BR.d.ts.map +1 -1
- package/dist/src/intl/pt-BR.js +16 -3
- package/dist/src/intl/pt.d.ts +3 -1
- package/dist/src/intl/pt.d.ts.map +1 -1
- package/dist/src/intl/pt.js +15 -2
- package/dist/src/intl/ro.d.ts +3 -1
- package/dist/src/intl/ro.d.ts.map +1 -1
- package/dist/src/intl/ro.js +16 -3
- package/dist/src/intl/sk.d.ts +3 -1
- package/dist/src/intl/sk.d.ts.map +1 -1
- package/dist/src/intl/sk.js +15 -2
- package/dist/src/intl/sl.d.ts +3 -1
- package/dist/src/intl/sl.d.ts.map +1 -1
- package/dist/src/intl/sl.js +16 -3
- package/dist/src/intl/sv.d.ts +3 -1
- package/dist/src/intl/sv.d.ts.map +1 -1
- package/dist/src/intl/sv.js +16 -3
- package/dist/src/intl/sw.d.ts +1 -0
- package/dist/src/intl/sw.d.ts.map +1 -1
- package/dist/src/intl/sw.js +14 -2
- package/dist/src/intl/ta.d.ts +3 -1
- package/dist/src/intl/ta.d.ts.map +1 -1
- package/dist/src/intl/ta.js +16 -3
- package/dist/src/intl/te.d.ts +3 -1
- package/dist/src/intl/te.d.ts.map +1 -1
- package/dist/src/intl/te.js +16 -3
- package/dist/src/intl/th.d.ts +3 -1
- package/dist/src/intl/th.d.ts.map +1 -1
- package/dist/src/intl/th.js +16 -3
- package/dist/src/intl/tr.d.ts +3 -1
- package/dist/src/intl/tr.d.ts.map +1 -1
- package/dist/src/intl/tr.js +16 -3
- package/dist/src/intl/uk.d.ts +3 -1
- package/dist/src/intl/uk.d.ts.map +1 -1
- package/dist/src/intl/uk.js +16 -3
- package/dist/src/intl/ur.d.ts +3 -1
- package/dist/src/intl/ur.d.ts.map +1 -1
- package/dist/src/intl/ur.js +15 -2
- package/dist/src/intl/vi.d.ts +3 -1
- package/dist/src/intl/vi.d.ts.map +1 -1
- package/dist/src/intl/vi.js +16 -3
- package/dist/src/intl/zh-CN.d.ts +3 -1
- package/dist/src/intl/zh-CN.d.ts.map +1 -1
- package/dist/src/intl/zh-CN.js +16 -3
- package/dist/src/intl/zh-TW.d.ts +3 -1
- package/dist/src/intl/zh-TW.d.ts.map +1 -1
- package/dist/src/intl/zh-TW.js +16 -3
- package/dist/src/local-first/Db.js +3 -2
- package/dist/src/local-first/Evolu.d.ts +47 -24
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Evolu.js +1 -0
- package/dist/src/local-first/Owner.d.ts +18 -14
- package/dist/src/local-first/Owner.d.ts.map +1 -1
- package/dist/src/local-first/Owner.js +14 -11
- package/dist/src/local-first/Protocol.d.ts +5 -5
- package/dist/src/local-first/Protocol.d.ts.map +1 -1
- package/dist/src/local-first/Protocol.js +35 -29
- package/dist/src/local-first/Query.d.ts +34 -21
- package/dist/src/local-first/Query.d.ts.map +1 -1
- package/dist/src/local-first/Query.js +27 -14
- package/dist/src/local-first/Relay.d.ts +12 -5
- package/dist/src/local-first/Relay.d.ts.map +1 -1
- package/dist/src/local-first/Relay.js +1 -1
- package/dist/src/local-first/Schema.d.ts +19 -11
- package/dist/src/local-first/Schema.d.ts.map +1 -1
- package/dist/src/local-first/Schema.js +11 -6
- package/dist/src/local-first/Shared.d.ts.map +1 -1
- package/dist/src/local-first/Shared.js +4 -2
- package/dist/src/local-first/Storage.d.ts +4 -2
- package/dist/src/local-first/Storage.d.ts.map +1 -1
- package/dist/src/local-first/Timestamp.d.ts.map +1 -1
- package/dist/src/local-first/Timestamp.js +1 -1
- package/package.json +3 -4
- package/src/Array.ts +195 -95
- package/src/Assert.ts +337 -31
- package/src/BigInt.ts +3 -3
- package/src/Brand.ts +7 -7
- package/src/Buffer.ts +12 -4
- package/src/Cache.ts +8 -3
- package/src/Callbacks.ts +8 -4
- package/src/Console.ts +45 -30
- package/src/Crypto.ts +13 -8
- package/src/Eq.ts +450 -122
- package/src/Function.ts +54 -24
- package/src/Http.ts +52 -19
- package/src/Identicon.ts +9 -4
- package/src/LeakDetector.ts +4 -3
- package/src/LockManager.ts +12 -10
- package/src/Lookup.ts +5 -2
- package/src/Number.ts +28 -24
- package/src/Object.ts +115 -49
- package/src/Option.ts +14 -5
- package/src/Order.ts +12 -12
- package/src/Platform.ts +3 -2
- package/src/Random.ts +7 -4
- package/src/Redacted.ts +13 -6
- package/src/Ref.ts +4 -4
- package/src/Relation.ts +8 -10
- package/src/Resource.ts +36 -15
- package/src/Result.ts +263 -119
- package/src/Schedule.ts +233 -116
- package/src/Set.ts +43 -24
- package/src/Sqlite.ts +18 -15
- package/src/Store.ts +3 -1
- package/src/String.ts +1 -1
- package/src/Task.ts +566 -286
- package/src/Test.ts +11 -4
- package/src/Time.ts +36 -19
- package/src/Type.ts +2191 -590
- package/src/Types.ts +108 -40
- package/src/WebSocket.ts +22 -6
- package/src/Worker.ts +11 -7
- package/src/intl/_en.ts +20 -4
- package/src/intl/ar.ts +17 -2
- package/src/intl/bn.ts +19 -4
- package/src/intl/ca.ts +19 -4
- package/src/intl/cs.ts +19 -4
- package/src/intl/da.ts +19 -4
- package/src/intl/de.ts +19 -4
- package/src/intl/el.ts +19 -4
- package/src/intl/es.ts +19 -4
- package/src/intl/fa.ts +19 -4
- package/src/intl/fi.ts +19 -4
- package/src/intl/fil.ts +19 -4
- package/src/intl/fr.ts +19 -4
- package/src/intl/he.ts +19 -4
- package/src/intl/hi.ts +19 -4
- package/src/intl/hr.ts +19 -4
- package/src/intl/hu.ts +18 -4
- package/src/intl/id.ts +19 -4
- package/src/intl/it.ts +19 -4
- package/src/intl/ja.ts +19 -4
- package/src/intl/ko.ts +19 -4
- package/src/intl/ml.ts +19 -4
- package/src/intl/mr.ts +19 -4
- package/src/intl/ms.ts +17 -2
- package/src/intl/nb.ts +16 -2
- package/src/intl/nl.ts +19 -4
- package/src/intl/pa.ts +19 -4
- package/src/intl/pl.ts +18 -2
- package/src/intl/pt-BR.ts +19 -4
- package/src/intl/pt.ts +17 -2
- package/src/intl/ro.ts +19 -4
- package/src/intl/sk.ts +17 -2
- package/src/intl/sl.ts +19 -4
- package/src/intl/sv.ts +19 -4
- package/src/intl/sw.ts +15 -2
- package/src/intl/ta.ts +19 -4
- package/src/intl/te.ts +19 -4
- package/src/intl/th.ts +19 -4
- package/src/intl/tr.ts +19 -4
- package/src/intl/uk.ts +19 -4
- package/src/intl/ur.ts +17 -2
- package/src/intl/vi.ts +19 -3
- package/src/intl/zh-CN.ts +19 -4
- package/src/intl/zh-TW.ts +19 -4
- package/src/local-first/Db.ts +2 -1
- package/src/local-first/Evolu.ts +48 -24
- package/src/local-first/Owner.ts +18 -14
- package/src/local-first/Protocol.ts +45 -35
- package/src/local-first/Query.ts +40 -24
- package/src/local-first/Relay.ts +13 -6
- package/src/local-first/Schema.ts +19 -11
- package/src/local-first/Shared.ts +4 -2
- package/src/local-first/Storage.ts +4 -2
- package/src/local-first/Timestamp.ts +1 -1
package/dist/src/Eq.js
CHANGED
|
@@ -3,38 +3,48 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
+
import { getObjectKind } from "./Object.js";
|
|
6
7
|
/**
|
|
7
|
-
* Compares two values
|
|
8
|
+
* Compares two values using SameValue equality (`Object.is`).
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* SameValue considers `NaN` equal to itself, distinguishes `0` from `-0`, and
|
|
11
|
+
* compares objects by reference identity.
|
|
12
|
+
*
|
|
13
|
+
* ### Example
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { assertFalse, assertTrue, eqStrict } from "@evolu/common";
|
|
17
|
+
*
|
|
18
|
+
* assertTrue(eqStrict(NaN, NaN));
|
|
19
|
+
* assertFalse(eqStrict(0, -0));
|
|
20
|
+
* ```
|
|
11
21
|
*/
|
|
12
|
-
export const eqStrict = (x, y) => x
|
|
22
|
+
export const eqStrict = (x, y) => Object.is(x, y);
|
|
13
23
|
/**
|
|
14
24
|
* Compares two values using SameValueZero equality.
|
|
15
25
|
*
|
|
16
26
|
* SameValueZero is the standard equality algorithm used by `Map`, `Set`, and
|
|
17
|
-
* `Array.prototype.includes`.
|
|
18
|
-
*
|
|
27
|
+
* `Array.prototype.includes`. Like SameValue, it considers `NaN` equal to
|
|
28
|
+
* itself, but unlike SameValue, it considers `0` and `-0` equal.
|
|
19
29
|
*
|
|
20
30
|
* ### Example
|
|
21
31
|
*
|
|
22
32
|
* ```ts
|
|
23
|
-
* import { eqSameValueZero } from "@evolu/common";
|
|
33
|
+
* import { assertFalse, assertTrue, eqSameValueZero } from "@evolu/common";
|
|
24
34
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
35
|
+
* assertTrue(eqSameValueZero(NaN, NaN));
|
|
36
|
+
* assertTrue(eqSameValueZero(0, -0));
|
|
37
|
+
* assertFalse(eqSameValueZero({}, {}));
|
|
28
38
|
* ```
|
|
29
39
|
*/
|
|
30
40
|
export const eqSameValueZero = (x, y) => x === y || Object.is(x, y);
|
|
31
|
-
/** An {@link Eq} for strings using
|
|
41
|
+
/** An {@link Eq} for strings using {@link eqStrict}. */
|
|
32
42
|
export const eqString = eqStrict;
|
|
33
43
|
/** An {@link Eq} for numbers using {@link eqSameValueZero}. */
|
|
34
44
|
export const eqNumber = eqSameValueZero;
|
|
35
|
-
/** An {@link Eq} for bigints using
|
|
45
|
+
/** An {@link Eq} for bigints using {@link eqStrict}. */
|
|
36
46
|
export const eqBigInt = eqStrict;
|
|
37
|
-
/** An {@link Eq} for booleans using
|
|
47
|
+
/** An {@link Eq} for booleans using {@link eqStrict}. */
|
|
38
48
|
export const eqBoolean = eqStrict;
|
|
39
49
|
/** An {@link Eq} for `undefined`. */
|
|
40
50
|
export const eqUndefined = eqStrict;
|
|
@@ -49,15 +59,20 @@ export const eqFromOrder = (order) => (x, y) => order(x, y) === 0;
|
|
|
49
59
|
* ### Example
|
|
50
60
|
*
|
|
51
61
|
* ```ts
|
|
52
|
-
* import {
|
|
62
|
+
* import {
|
|
63
|
+
* assertFalse,
|
|
64
|
+
* assertTrue,
|
|
65
|
+
* createEqArrayLike,
|
|
66
|
+
* eqNumber,
|
|
67
|
+
* } from "@evolu/common";
|
|
53
68
|
*
|
|
54
69
|
* const eqArrayNumber = createEqArrayLike(eqNumber);
|
|
55
70
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
71
|
+
* assertTrue(eqArrayNumber([1, 2, 3], [1, 2, 3]));
|
|
72
|
+
* assertTrue(
|
|
58
73
|
* eqArrayNumber(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3])),
|
|
59
|
-
* )
|
|
60
|
-
*
|
|
74
|
+
* );
|
|
75
|
+
* assertFalse(eqArrayNumber([1, 2, 3], [1, 2, 4]));
|
|
61
76
|
* ```
|
|
62
77
|
*/
|
|
63
78
|
export const createEqArrayLike = (item) => (x, y) => {
|
|
@@ -72,19 +87,20 @@ export const createEqArrayLike = (item) => (x, y) => {
|
|
|
72
87
|
return true;
|
|
73
88
|
};
|
|
74
89
|
/**
|
|
75
|
-
* Compares two array-like structures by
|
|
90
|
+
* Compares two array-like structures element by element using {@link eqStrict}.
|
|
76
91
|
*
|
|
77
|
-
* Useful for structural sharing checks where
|
|
92
|
+
* Useful for structural sharing checks where objects are compared by reference
|
|
93
|
+
* identity. `NaN` elements are equal, while `0` and `-0` elements differ.
|
|
78
94
|
*
|
|
79
95
|
* ### Example
|
|
80
96
|
*
|
|
81
97
|
* ```ts
|
|
82
|
-
* import { eqArrayStrict } from "@evolu/common";
|
|
98
|
+
* import { assertFalse, assertTrue, eqArrayStrict } from "@evolu/common";
|
|
83
99
|
*
|
|
84
100
|
* const a = { x: 1 };
|
|
85
101
|
* const b = { x: 1 };
|
|
86
|
-
*
|
|
87
|
-
*
|
|
102
|
+
* assertTrue(eqArrayStrict([a, a], [a, a]));
|
|
103
|
+
* assertFalse(eqArrayStrict([a], [b]));
|
|
88
104
|
* ```
|
|
89
105
|
*/
|
|
90
106
|
export const eqArrayStrict = /*#__PURE__*/ createEqArrayLike(eqStrict);
|
|
@@ -94,12 +110,27 @@ export const eqArrayStrict = /*#__PURE__*/ createEqArrayLike(eqStrict);
|
|
|
94
110
|
* ### Example
|
|
95
111
|
*
|
|
96
112
|
* ```ts
|
|
97
|
-
* import { eqArrayNumber } from "@evolu/common";
|
|
113
|
+
* import { assertTrue, eqArrayNumber } from "@evolu/common";
|
|
98
114
|
*
|
|
99
|
-
*
|
|
115
|
+
* assertTrue(eqArrayNumber([1, NaN], [1, NaN]));
|
|
100
116
|
* ```
|
|
101
117
|
*/
|
|
102
118
|
export const eqArrayNumber = /*#__PURE__*/ createEqArrayLike(eqNumber);
|
|
119
|
+
/**
|
|
120
|
+
* Compares two Uint8Arrays by byte value.
|
|
121
|
+
*
|
|
122
|
+
* ### Example
|
|
123
|
+
*
|
|
124
|
+
* ```ts
|
|
125
|
+
* import { assertFalse, assertTrue, eqUint8Array } from "@evolu/common";
|
|
126
|
+
*
|
|
127
|
+
* assertTrue(eqUint8Array(new Uint8Array([1, 2]), new Uint8Array([1, 2])));
|
|
128
|
+
* assertFalse(
|
|
129
|
+
* eqUint8Array(new Uint8Array([1, 2]), new Uint8Array([1, 3])),
|
|
130
|
+
* );
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
export const eqUint8Array = eqArrayNumber;
|
|
103
134
|
/**
|
|
104
135
|
* Creates an equivalence function for objects based on an equivalence for their
|
|
105
136
|
* fields.
|
|
@@ -107,12 +138,17 @@ export const eqArrayNumber = /*#__PURE__*/ createEqArrayLike(eqNumber);
|
|
|
107
138
|
* ### Example
|
|
108
139
|
*
|
|
109
140
|
* ```ts
|
|
110
|
-
* import {
|
|
141
|
+
* import {
|
|
142
|
+
* assertFalse,
|
|
143
|
+
* assertTrue,
|
|
144
|
+
* createEqObject,
|
|
145
|
+
* eqNumber,
|
|
146
|
+
* } from "@evolu/common";
|
|
111
147
|
*
|
|
112
148
|
* const eqObjectNumber = createEqObject({ a: eqNumber });
|
|
113
149
|
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
150
|
+
* assertTrue(eqObjectNumber({ a: 1 }, { a: 1 }));
|
|
151
|
+
* assertFalse(eqObjectNumber({ a: 1 }, { a: 2 }));
|
|
116
152
|
* ```
|
|
117
153
|
*/
|
|
118
154
|
export const createEqObject = (eqs) => (x, y) => {
|
|
@@ -125,111 +161,271 @@ export const createEqObject = (eqs) => (x, y) => {
|
|
|
125
161
|
}
|
|
126
162
|
return true;
|
|
127
163
|
};
|
|
164
|
+
export function eqData(actual, expected) {
|
|
165
|
+
return eqDataInternal(actual, expected, {
|
|
166
|
+
pairs: [],
|
|
167
|
+
rightsByLeft: new Map(),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
128
170
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* - Uses an iterative approach with a stack to handle large or deeply nested
|
|
132
|
-
* objects without risking stack overflow.
|
|
133
|
-
* - Defensively handles circular references in runtime values without looping,
|
|
134
|
-
* although cyclic values are not valid JSON.
|
|
135
|
-
* - Unlike JSON.stringify, this function directly compares values, avoiding
|
|
136
|
-
* serialization overhead and leveraging short-circuit evaluation for faster
|
|
137
|
-
* failure on mismatched structures.
|
|
171
|
+
* Compares two {@link JsonValue} values using {@link eqData}.
|
|
138
172
|
*
|
|
139
173
|
* ### Example
|
|
140
174
|
*
|
|
141
175
|
* ```ts
|
|
142
|
-
* import { eqJsonValue, type JsonValue } from "@evolu/common";
|
|
176
|
+
* import { assertTrue, eqJsonValue, type JsonValue } from "@evolu/common";
|
|
143
177
|
*
|
|
144
178
|
* const first: JsonValue = { profile: { name: "Ada" } };
|
|
145
179
|
* const second: JsonValue = { profile: { name: "Ada" } };
|
|
146
180
|
*
|
|
147
|
-
*
|
|
181
|
+
* assertTrue(eqJsonValue(first, second));
|
|
148
182
|
* ```
|
|
149
183
|
*/
|
|
150
|
-
export const eqJsonValue =
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
if (typeX !== typeY || x === null || y === null)
|
|
184
|
+
export const eqJsonValue = eqData;
|
|
185
|
+
/** Compares two {@link JsonValueInput} values using {@link eqData}. */
|
|
186
|
+
export const eqJsonValueInput = eqData;
|
|
187
|
+
const eqDataInternal = (actual, expected, context) => {
|
|
188
|
+
const frames = [{ kind: "Compare", actual, expected }];
|
|
189
|
+
const attempts = [];
|
|
190
|
+
const retryFailedCandidate = (_frame) => {
|
|
191
|
+
const attempt = attempts.pop();
|
|
192
|
+
if (attempt === undefined)
|
|
160
193
|
return false;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const
|
|
170
|
-
const
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
194
|
+
rollbackEqDataContext(context, attempt.contextCheckpoint);
|
|
195
|
+
frames.length = attempt.frameCheckpoint;
|
|
196
|
+
frames.push(attempt.retry);
|
|
197
|
+
return true;
|
|
198
|
+
};
|
|
199
|
+
while (frames.length > 0) {
|
|
200
|
+
const frame = frames.pop();
|
|
201
|
+
if (frame.kind === "Compare") {
|
|
202
|
+
const x = frame.actual;
|
|
203
|
+
const y = frame.expected;
|
|
204
|
+
if (eqSameValueZero(x, y))
|
|
205
|
+
continue;
|
|
206
|
+
if (typeof x !== typeof y) {
|
|
207
|
+
frames.push({ kind: "Fail" });
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if (typeof x !== "object" ||
|
|
211
|
+
x === null ||
|
|
212
|
+
typeof y !== "object" ||
|
|
213
|
+
y === null) {
|
|
214
|
+
frames.push({ kind: "Fail" });
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
const rights = context.rightsByLeft.get(x);
|
|
218
|
+
if (rights?.has(y))
|
|
219
|
+
continue;
|
|
220
|
+
if (rights === undefined) {
|
|
221
|
+
context.rightsByLeft.set(x, new Set([y]));
|
|
177
222
|
}
|
|
178
223
|
else {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
224
|
+
rights.add(y);
|
|
225
|
+
}
|
|
226
|
+
context.pairs.push([x, y]);
|
|
227
|
+
const xKind = getObjectKind(x);
|
|
228
|
+
const yKind = getObjectKind(y);
|
|
229
|
+
if (xKind !== yKind) {
|
|
230
|
+
frames.push({ kind: "Fail" });
|
|
231
|
+
continue;
|
|
182
232
|
}
|
|
183
|
-
if (
|
|
184
|
-
const
|
|
185
|
-
const
|
|
186
|
-
if (
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
233
|
+
if (xKind === "Array") {
|
|
234
|
+
const xArray = x;
|
|
235
|
+
const yArray = y;
|
|
236
|
+
if (xArray.length !== yArray.length ||
|
|
237
|
+
Reflect.ownKeys(xArray).length !== xArray.length + 1 ||
|
|
238
|
+
Reflect.ownKeys(yArray).length !== yArray.length + 1) {
|
|
239
|
+
frames.push({ kind: "Fail" });
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
let valid = true;
|
|
243
|
+
for (let index = 0; index < xArray.length; index++) {
|
|
244
|
+
const xDescriptor = Object.getOwnPropertyDescriptor(xArray, index);
|
|
245
|
+
const yDescriptor = Object.getOwnPropertyDescriptor(yArray, index);
|
|
246
|
+
if (xDescriptor === undefined ||
|
|
247
|
+
yDescriptor === undefined ||
|
|
248
|
+
!("value" in xDescriptor) ||
|
|
249
|
+
!("value" in yDescriptor)) {
|
|
250
|
+
valid = false;
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
frames.push({
|
|
254
|
+
kind: "Compare",
|
|
255
|
+
actual: xDescriptor.value,
|
|
256
|
+
expected: yDescriptor.value,
|
|
257
|
+
});
|
|
190
258
|
}
|
|
259
|
+
if (!valid)
|
|
260
|
+
frames.push({ kind: "Fail" });
|
|
261
|
+
continue;
|
|
191
262
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
263
|
+
switch (xKind) {
|
|
264
|
+
case "Date":
|
|
265
|
+
if (!Object.is(Date.prototype.getTime.call(x), Date.prototype.getTime.call(y))) {
|
|
266
|
+
frames.push({ kind: "Fail" });
|
|
267
|
+
}
|
|
268
|
+
continue;
|
|
269
|
+
case "Uint8Array":
|
|
270
|
+
if (!eqUint8Array(x, y)) {
|
|
271
|
+
frames.push({ kind: "Fail" });
|
|
272
|
+
}
|
|
273
|
+
continue;
|
|
274
|
+
case "Set": {
|
|
275
|
+
const xSet = x;
|
|
276
|
+
const ySet = y;
|
|
277
|
+
if (Reflect.ownKeys(x).length !== 0 ||
|
|
278
|
+
Reflect.ownKeys(y).length !== 0 ||
|
|
279
|
+
xSet.size !== ySet.size) {
|
|
280
|
+
frames.push({ kind: "Fail" });
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
frames.push({
|
|
284
|
+
kind: "Set",
|
|
285
|
+
actual: Array.from(xSet),
|
|
286
|
+
actualIndex: 0,
|
|
287
|
+
unmatched: Array.from(ySet),
|
|
288
|
+
candidateIndex: 0,
|
|
289
|
+
});
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
case "Map": {
|
|
293
|
+
const xMap = x;
|
|
294
|
+
const yMap = y;
|
|
295
|
+
if (Reflect.ownKeys(x).length !== 0 ||
|
|
296
|
+
Reflect.ownKeys(y).length !== 0 ||
|
|
297
|
+
xMap.size !== yMap.size) {
|
|
298
|
+
frames.push({ kind: "Fail" });
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
frames.push({
|
|
302
|
+
kind: "Map",
|
|
303
|
+
actual: Array.from(xMap),
|
|
304
|
+
actualIndex: 0,
|
|
305
|
+
unmatched: Array.from(yMap),
|
|
306
|
+
candidateIndex: 0,
|
|
307
|
+
});
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
case "Object": {
|
|
311
|
+
const xKeys = Reflect.ownKeys(x);
|
|
312
|
+
const yKeys = Reflect.ownKeys(y);
|
|
313
|
+
if (xKeys.length !== yKeys.length) {
|
|
314
|
+
frames.push({ kind: "Fail" });
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
let valid = true;
|
|
318
|
+
for (const key of xKeys) {
|
|
319
|
+
if (typeof key !== "string") {
|
|
320
|
+
valid = false;
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
const xDescriptor = Object.getOwnPropertyDescriptor(x, key);
|
|
324
|
+
const yDescriptor = Object.getOwnPropertyDescriptor(y, key);
|
|
325
|
+
if (xDescriptor === undefined ||
|
|
326
|
+
yDescriptor === undefined ||
|
|
327
|
+
!("value" in xDescriptor) ||
|
|
328
|
+
!("value" in yDescriptor) ||
|
|
329
|
+
!xDescriptor.enumerable ||
|
|
330
|
+
!yDescriptor.enumerable) {
|
|
331
|
+
valid = false;
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
frames.push({
|
|
335
|
+
kind: "Compare",
|
|
336
|
+
actual: xDescriptor.value,
|
|
337
|
+
expected: yDescriptor.value,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
if (!valid)
|
|
341
|
+
frames.push({ kind: "Fail" });
|
|
342
|
+
continue;
|
|
204
343
|
}
|
|
344
|
+
case "Unsupported":
|
|
345
|
+
frames.push({ kind: "Fail" });
|
|
346
|
+
continue;
|
|
205
347
|
}
|
|
206
348
|
}
|
|
207
|
-
|
|
208
|
-
|
|
349
|
+
if (frame.kind === "Set") {
|
|
350
|
+
if (frame.actualIndex === frame.actual.length)
|
|
351
|
+
continue;
|
|
352
|
+
if (frame.candidateIndex === frame.unmatched.length) {
|
|
353
|
+
frames.push({ kind: "Fail" });
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
const attempt = {
|
|
357
|
+
contextCheckpoint: context.pairs.length,
|
|
358
|
+
frameCheckpoint: frames.length,
|
|
359
|
+
retry: { ...frame, candidateIndex: frame.candidateIndex + 1 },
|
|
360
|
+
};
|
|
361
|
+
attempts.push(attempt);
|
|
362
|
+
frames.push({ kind: "CommitSet", match: frame });
|
|
363
|
+
frames.push({
|
|
364
|
+
kind: "Compare",
|
|
365
|
+
actual: frame.actual[frame.actualIndex],
|
|
366
|
+
expected: frame.unmatched[frame.candidateIndex],
|
|
367
|
+
});
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
if (frame.kind === "Map") {
|
|
371
|
+
if (frame.actualIndex === frame.actual.length)
|
|
372
|
+
continue;
|
|
373
|
+
if (frame.candidateIndex === frame.unmatched.length) {
|
|
374
|
+
frames.push({ kind: "Fail" });
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
const [actualKey, actualValue] = frame.actual[frame.actualIndex];
|
|
378
|
+
const [expectedKey, expectedValue] = frame.unmatched[frame.candidateIndex];
|
|
379
|
+
const attempt = {
|
|
380
|
+
contextCheckpoint: context.pairs.length,
|
|
381
|
+
frameCheckpoint: frames.length,
|
|
382
|
+
retry: { ...frame, candidateIndex: frame.candidateIndex + 1 },
|
|
383
|
+
};
|
|
384
|
+
attempts.push(attempt);
|
|
385
|
+
frames.push({ kind: "CommitMap", match: frame });
|
|
386
|
+
frames.push({
|
|
387
|
+
kind: "Compare",
|
|
388
|
+
actual: actualValue,
|
|
389
|
+
expected: expectedValue,
|
|
390
|
+
});
|
|
391
|
+
frames.push({
|
|
392
|
+
kind: "Compare",
|
|
393
|
+
actual: actualKey,
|
|
394
|
+
expected: expectedKey,
|
|
395
|
+
});
|
|
396
|
+
continue;
|
|
209
397
|
}
|
|
398
|
+
if (frame.kind === "CommitSet") {
|
|
399
|
+
attempts.pop();
|
|
400
|
+
frame.match.unmatched.splice(frame.match.candidateIndex, 1);
|
|
401
|
+
frames.push({
|
|
402
|
+
...frame.match,
|
|
403
|
+
actualIndex: frame.match.actualIndex + 1,
|
|
404
|
+
candidateIndex: 0,
|
|
405
|
+
});
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
408
|
+
if (frame.kind === "CommitMap") {
|
|
409
|
+
attempts.pop();
|
|
410
|
+
frame.match.unmatched.splice(frame.match.candidateIndex, 1);
|
|
411
|
+
frames.push({
|
|
412
|
+
...frame.match,
|
|
413
|
+
actualIndex: frame.match.actualIndex + 1,
|
|
414
|
+
candidateIndex: 0,
|
|
415
|
+
});
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
if (!retryFailedCandidate(frame))
|
|
419
|
+
return false;
|
|
210
420
|
}
|
|
211
421
|
return true;
|
|
212
422
|
};
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
* failure on mismatched structures.
|
|
223
|
-
*
|
|
224
|
-
* ### Example
|
|
225
|
-
*
|
|
226
|
-
* ```ts
|
|
227
|
-
* import { eqJsonValueInput, type JsonValueInput } from "@evolu/common";
|
|
228
|
-
*
|
|
229
|
-
* const first: JsonValueInput = { profile: { name: "Ada" } };
|
|
230
|
-
* const second: JsonValueInput = { profile: { name: "Ada" } };
|
|
231
|
-
*
|
|
232
|
-
* expect(eqJsonValueInput(first, second)).toBe(true);
|
|
233
|
-
* ```
|
|
234
|
-
*/
|
|
235
|
-
export const eqJsonValueInput = (a, b) => eqJsonValue(a, b);
|
|
423
|
+
const rollbackEqDataContext = (context, checkpoint) => {
|
|
424
|
+
while (context.pairs.length > checkpoint) {
|
|
425
|
+
const [left, right] = context.pairs.pop();
|
|
426
|
+
const rights = context.rightsByLeft.get(left);
|
|
427
|
+
rights.delete(right);
|
|
428
|
+
if (rights.size === 0)
|
|
429
|
+
context.rightsByLeft.delete(left);
|
|
430
|
+
}
|
|
431
|
+
};
|