@evolu/common 8.5.0 → 8.6.1
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 +170 -97
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +67 -42
- package/dist/src/Assert.d.ts +233 -30
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +150 -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/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 +4 -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/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/Resource.d.ts +27 -12
- package/dist/src/Resource.d.ts.map +1 -1
- package/dist/src/Result.d.ts +258 -114
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +71 -34
- 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 +9 -8
- package/dist/src/Task.d.ts +441 -212
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +238 -115
- package/dist/src/Test.d.ts +10 -4
- package/dist/src/Test.d.ts.map +1 -1
- package/dist/src/Test.js +10 -4
- package/dist/src/Time.d.ts +27 -17
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +16 -6
- package/dist/src/Type.d.ts +1096 -387
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +1046 -372
- 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/Worker.d.ts +10 -6
- package/dist/src/Worker.d.ts.map +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/Evolu.d.ts +47 -24
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Owner.d.ts +10 -7
- package/dist/src/local-first/Owner.d.ts.map +1 -1
- package/dist/src/local-first/Owner.js +10 -7
- package/dist/src/local-first/Protocol.d.ts +5 -5
- package/dist/src/local-first/Protocol.js +7 -7
- 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 +25 -13
- 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/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/Storage.d.ts +4 -2
- package/dist/src/local-first/Storage.d.ts.map +1 -1
- package/package.json +3 -4
- package/src/Array.ts +170 -97
- package/src/Assert.ts +336 -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/LockManager.ts +12 -10
- package/src/Lookup.ts +4 -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 +2 -2
- package/src/Random.ts +7 -4
- package/src/Redacted.ts +13 -6
- package/src/Ref.ts +4 -4
- package/src/Relation.ts +5 -7
- package/src/Resource.ts +27 -12
- package/src/Result.ts +258 -114
- package/src/Schedule.ts +233 -116
- package/src/Set.ts +43 -24
- package/src/Sqlite.ts +9 -8
- package/src/Task.ts +441 -212
- package/src/Test.ts +10 -4
- package/src/Time.ts +27 -17
- package/src/Type.ts +2077 -620
- package/src/Types.ts +108 -40
- package/src/WebSocket.ts +14 -6
- package/src/Worker.ts +10 -6
- 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/Evolu.ts +47 -24
- package/src/local-first/Owner.ts +10 -7
- package/src/local-first/Protocol.ts +7 -7
- package/src/local-first/Query.ts +34 -21
- package/src/local-first/Relay.ts +12 -5
- package/src/local-first/Schema.ts +19 -11
- package/src/local-first/Storage.ts +4 -2
package/src/Assert.ts
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Runtime assertions for
|
|
2
|
+
* Runtime assertions for invariants and value checks.
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { NonEmptyArray, NonEmptyReadonlyArray } from "./Array.ts";
|
|
8
|
-
import type
|
|
8
|
+
import { eqData, eqStrict, type Eq } from "./Eq.ts";
|
|
9
|
+
import type {
|
|
10
|
+
AnyResult,
|
|
11
|
+
Err,
|
|
12
|
+
InferErr,
|
|
13
|
+
InferOk,
|
|
14
|
+
Ok,
|
|
15
|
+
Result,
|
|
16
|
+
} from "./Result.ts";
|
|
17
|
+
import type { Data, IsData, Type } from "./Type.ts";
|
|
18
|
+
import type { CompileTimeError } from "./Types.ts";
|
|
9
19
|
|
|
10
20
|
/**
|
|
11
21
|
* Ensures a condition is true, throwing an error with the provided message if
|
|
@@ -21,12 +31,13 @@ import type { Type } from "./Type.ts";
|
|
|
21
31
|
* ### Example
|
|
22
32
|
*
|
|
23
33
|
* ```ts
|
|
24
|
-
* import { assert
|
|
34
|
+
* import { assert, assertEqual, assertErr, trySync } from "@evolu/common";
|
|
25
35
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* );
|
|
36
|
+
* assert(true, "Expected true.");
|
|
37
|
+
* const result = trySync(() => assert(false, "Expected true."));
|
|
38
|
+
* assertErr(result);
|
|
39
|
+
* assert(result.error instanceof Error, "Expected an Error.");
|
|
40
|
+
* assertEqual(result.error.message, "Expected true.");
|
|
30
41
|
* ```
|
|
31
42
|
*/
|
|
32
43
|
export const assert: (
|
|
@@ -39,6 +50,264 @@ export const assert: (
|
|
|
39
50
|
}
|
|
40
51
|
};
|
|
41
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Asserts that two values are the same according to {@link eqStrict}.
|
|
55
|
+
*
|
|
56
|
+
* `eqStrict` uses SameValue equality: it considers `NaN` the same as itself,
|
|
57
|
+
* distinguishes `0` from `-0`, and compares objects by reference identity.
|
|
58
|
+
*
|
|
59
|
+
* ### Example
|
|
60
|
+
*
|
|
61
|
+
* ```ts
|
|
62
|
+
* import { assertSame, assertType } from "@evolu/common";
|
|
63
|
+
*
|
|
64
|
+
* interface User {
|
|
65
|
+
* readonly name: string;
|
|
66
|
+
* }
|
|
67
|
+
*
|
|
68
|
+
* const user: User = { name: "Ada" };
|
|
69
|
+
* const value: unknown = user;
|
|
70
|
+
*
|
|
71
|
+
* assertSame(value, user);
|
|
72
|
+
* assertType<User, typeof value>();
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export const assertSame: <Expected>(
|
|
76
|
+
actual: unknown,
|
|
77
|
+
expected: Expected,
|
|
78
|
+
) => asserts actual is Expected = (actual, expected) => {
|
|
79
|
+
assert(eqStrict(actual, expected), "Expected values to be the same.");
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Asserts that a value is exactly `true` and narrows it to `true`.
|
|
84
|
+
*
|
|
85
|
+
* Unlike {@link assert}, this checks an exact boolean value instead of
|
|
86
|
+
* truthiness and does not require a custom message.
|
|
87
|
+
*
|
|
88
|
+
* ### Example
|
|
89
|
+
*
|
|
90
|
+
* ```ts
|
|
91
|
+
* import { assertTrue, assertType } from "@evolu/common";
|
|
92
|
+
*
|
|
93
|
+
* const value: unknown = true;
|
|
94
|
+
* assertTrue(value);
|
|
95
|
+
* assertType<true, typeof value>();
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export const assertTrue: (value: unknown) => asserts value is true = (
|
|
99
|
+
value,
|
|
100
|
+
) => {
|
|
101
|
+
assert(value === true, "Expected true.");
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Asserts that a value is exactly `false` and narrows it to `false`.
|
|
106
|
+
*
|
|
107
|
+
* Unlike {@link assert}, this checks an exact boolean value instead of falsiness
|
|
108
|
+
* and does not require a custom message.
|
|
109
|
+
*
|
|
110
|
+
* ### Example
|
|
111
|
+
*
|
|
112
|
+
* ```ts
|
|
113
|
+
* import { assertFalse, assertType } from "@evolu/common";
|
|
114
|
+
*
|
|
115
|
+
* const value: unknown = false;
|
|
116
|
+
* assertFalse(value);
|
|
117
|
+
* assertType<false, typeof value>();
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export const assertFalse: (value: unknown) => asserts value is false = (
|
|
121
|
+
value,
|
|
122
|
+
) => {
|
|
123
|
+
assert(value === false, "Expected false.");
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Asserts that two {@link Data} values are equal according to {@link eqData}.
|
|
128
|
+
*
|
|
129
|
+
* Use this for concise value checks in platform-independent examples. Use
|
|
130
|
+
* {@link assert} with a descriptive message for application invariants.
|
|
131
|
+
*
|
|
132
|
+
* ### Example
|
|
133
|
+
*
|
|
134
|
+
* ```ts
|
|
135
|
+
* import { assertEqual } from "@evolu/common";
|
|
136
|
+
*
|
|
137
|
+
* const actual = new Map([["roles", new Set(["admin", "author"])]]);
|
|
138
|
+
* const expected = new Map([["roles", new Set(["author", "admin"])]]);
|
|
139
|
+
*
|
|
140
|
+
* assertEqual(actual, expected);
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
export function assertEqual<Actual, Expected>(
|
|
144
|
+
actual: Actual,
|
|
145
|
+
expected: Expected,
|
|
146
|
+
...dataError: AssertEqualError<Actual | Expected>
|
|
147
|
+
): void;
|
|
148
|
+
export function assertEqual(actual: Data, expected: Data): void {
|
|
149
|
+
assert(eqData(actual, expected), "Expected values to be equal.");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
type AssertEqualError<Value> =
|
|
153
|
+
IsData<Value> extends true
|
|
154
|
+
? []
|
|
155
|
+
: [
|
|
156
|
+
error: CompileTimeError<
|
|
157
|
+
"assertEqual",
|
|
158
|
+
"Actual and expected values must consist only of Data."
|
|
159
|
+
>,
|
|
160
|
+
];
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Asserts that a {@link Result} is an {@link Ok}, optionally compares its value,
|
|
164
|
+
* and narrows the Result.
|
|
165
|
+
*
|
|
166
|
+
* With only a Result, this checks the variant without inspecting the value.
|
|
167
|
+
* When an expected value is provided, it uses {@link eqData}; its Data type is
|
|
168
|
+
* inferred independently, so an unbranded literal can compare a branded
|
|
169
|
+
* primitive or collection. Pass a custom {@link Eq} when either value is outside
|
|
170
|
+
* {@link Data} or needs domain-specific equality.
|
|
171
|
+
*
|
|
172
|
+
* ### Example
|
|
173
|
+
*
|
|
174
|
+
* ```ts
|
|
175
|
+
* import {
|
|
176
|
+
* assertEqual,
|
|
177
|
+
* assertOk,
|
|
178
|
+
* assertType,
|
|
179
|
+
* ok,
|
|
180
|
+
* type Ok,
|
|
181
|
+
* type Result,
|
|
182
|
+
* type Typed,
|
|
183
|
+
* } from "@evolu/common";
|
|
184
|
+
*
|
|
185
|
+
* interface User {
|
|
186
|
+
* readonly id: string;
|
|
187
|
+
* }
|
|
188
|
+
*
|
|
189
|
+
* interface UserNotFoundError extends Typed<"UserNotFound"> {}
|
|
190
|
+
*
|
|
191
|
+
* const result: Result<User, UserNotFoundError> = ok({ id: "user-1" });
|
|
192
|
+
*
|
|
193
|
+
* assertOk(result);
|
|
194
|
+
* assertType<Ok<User>, typeof result>();
|
|
195
|
+
* assertEqual(result.value.id, "user-1");
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
export function assertOk<R extends Result<unknown, unknown>>(
|
|
199
|
+
result: R,
|
|
200
|
+
): asserts result is Extract<R, Ok<unknown>>;
|
|
201
|
+
export function assertOk<R extends Result<unknown, unknown>>(
|
|
202
|
+
result: R,
|
|
203
|
+
expectedValue: InferOk<R>,
|
|
204
|
+
eq: Eq<InferOk<R>>,
|
|
205
|
+
): asserts result is Extract<R, Ok<unknown>>;
|
|
206
|
+
// Constrain the argument tuple so any cannot absorb the CompileTimeError.
|
|
207
|
+
export function assertOk<R extends Result<unknown, unknown>, ExpectedValue>(
|
|
208
|
+
result: R,
|
|
209
|
+
...comparison: [expectedValue: ExpectedValue] &
|
|
210
|
+
(IsData<InferOk<R> | ExpectedValue> extends true
|
|
211
|
+
? unknown
|
|
212
|
+
: {
|
|
213
|
+
readonly [
|
|
214
|
+
Error in CompileTimeError<
|
|
215
|
+
"assertOk",
|
|
216
|
+
"Result value and expected value must consist only of Data when no custom Eq is provided."
|
|
217
|
+
>
|
|
218
|
+
]: never;
|
|
219
|
+
})
|
|
220
|
+
): asserts result is Extract<R, Ok<unknown>>;
|
|
221
|
+
export function assertOk(
|
|
222
|
+
result: AnyResult,
|
|
223
|
+
...comparison: [] | [expectedValue: unknown, eq?: Eq<any>]
|
|
224
|
+
): asserts result is Ok<unknown> {
|
|
225
|
+
assert(result.ok, "Expected an Ok result.");
|
|
226
|
+
if (comparison.length === 0) return;
|
|
227
|
+
|
|
228
|
+
const expectedValue = comparison[0];
|
|
229
|
+
const eq: Eq<any> = comparison[1] ?? eqData;
|
|
230
|
+
assert(
|
|
231
|
+
eq(result.value, expectedValue),
|
|
232
|
+
"Expected the value to equal the expected value.",
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Asserts that a {@link Result} is an {@link Err}, optionally compares its error,
|
|
238
|
+
* and narrows the Result.
|
|
239
|
+
*
|
|
240
|
+
* With only a Result, this checks the variant without inspecting the error.
|
|
241
|
+
* When an expected error is provided, it uses {@link eqData}; its Data type is
|
|
242
|
+
* inferred independently, so an unbranded literal can compare a branded
|
|
243
|
+
* primitive or collection. Pass a custom {@link Eq} when either value is outside
|
|
244
|
+
* {@link Data} or needs domain-specific equality.
|
|
245
|
+
*
|
|
246
|
+
* ### Example
|
|
247
|
+
*
|
|
248
|
+
* ```ts
|
|
249
|
+
* import {
|
|
250
|
+
* assertEqual,
|
|
251
|
+
* assertErr,
|
|
252
|
+
* assertType,
|
|
253
|
+
* err,
|
|
254
|
+
* type Err,
|
|
255
|
+
* type Result,
|
|
256
|
+
* type Typed,
|
|
257
|
+
* } from "@evolu/common";
|
|
258
|
+
*
|
|
259
|
+
* interface UserNotFoundError extends Typed<"UserNotFound"> {
|
|
260
|
+
* readonly id: string;
|
|
261
|
+
* }
|
|
262
|
+
*
|
|
263
|
+
* const result: Result<string, UserNotFoundError> = err({
|
|
264
|
+
* type: "UserNotFound",
|
|
265
|
+
* id: "user-1",
|
|
266
|
+
* });
|
|
267
|
+
*
|
|
268
|
+
* assertErr(result);
|
|
269
|
+
* assertType<Err<UserNotFoundError>, typeof result>();
|
|
270
|
+
* assertEqual(result.error.id, "user-1");
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
export function assertErr<R extends Result<unknown, unknown>>(
|
|
274
|
+
result: R,
|
|
275
|
+
): asserts result is Extract<R, Err<unknown>>;
|
|
276
|
+
export function assertErr<R extends Result<unknown, unknown>>(
|
|
277
|
+
result: R,
|
|
278
|
+
expectedError: InferErr<R>,
|
|
279
|
+
eq: Eq<InferErr<R>>,
|
|
280
|
+
): asserts result is Extract<R, Err<unknown>>;
|
|
281
|
+
// Constrain the argument tuple so any cannot absorb the CompileTimeError.
|
|
282
|
+
export function assertErr<R extends Result<unknown, unknown>, ExpectedError>(
|
|
283
|
+
result: R,
|
|
284
|
+
...comparison: [expectedError: ExpectedError] &
|
|
285
|
+
(IsData<InferErr<R> | ExpectedError> extends true
|
|
286
|
+
? unknown
|
|
287
|
+
: {
|
|
288
|
+
readonly [
|
|
289
|
+
Error in CompileTimeError<
|
|
290
|
+
"assertErr",
|
|
291
|
+
"Result error and expected error must consist only of Data when no custom Eq is provided."
|
|
292
|
+
>
|
|
293
|
+
]: never;
|
|
294
|
+
})
|
|
295
|
+
): asserts result is Extract<R, Err<unknown>>;
|
|
296
|
+
export function assertErr(
|
|
297
|
+
result: AnyResult,
|
|
298
|
+
...comparison: [] | [expectedError: unknown, eq?: Eq<any>]
|
|
299
|
+
): asserts result is Err<unknown> {
|
|
300
|
+
assert(!result.ok, "Expected an Err result.");
|
|
301
|
+
if (comparison.length === 0) return;
|
|
302
|
+
|
|
303
|
+
const expectedError = comparison[0];
|
|
304
|
+
const eq: Eq<any> = comparison[1] ?? eqData;
|
|
305
|
+
assert(
|
|
306
|
+
eq(result.error, expectedError),
|
|
307
|
+
"Expected the error to equal the expected error.",
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
42
311
|
/**
|
|
43
312
|
* Asserts that a value is non-nullable.
|
|
44
313
|
*
|
|
@@ -65,15 +334,23 @@ export const assertNonNullable: <T>(
|
|
|
65
334
|
* ### Example
|
|
66
335
|
*
|
|
67
336
|
* ```ts
|
|
68
|
-
* import {
|
|
337
|
+
* import {
|
|
338
|
+
* assert,
|
|
339
|
+
* assertEqual,
|
|
340
|
+
* assertErr,
|
|
341
|
+
* assertNotNull,
|
|
342
|
+
* assertType,
|
|
343
|
+
* trySync,
|
|
344
|
+
* } from "@evolu/common";
|
|
69
345
|
*
|
|
70
346
|
* const value = undefined as string | null | undefined;
|
|
71
347
|
* assertNotNull(value);
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* );
|
|
348
|
+
* assertType<string | undefined, typeof value>();
|
|
349
|
+
* assertEqual(value, undefined);
|
|
350
|
+
* const result = trySync(() => assertNotNull(null));
|
|
351
|
+
* assertErr(result);
|
|
352
|
+
* assert(result.error instanceof Error, "Expected an Error.");
|
|
353
|
+
* assertEqual(result.error.message, "Expected value not to be null.");
|
|
77
354
|
* ```
|
|
78
355
|
*/
|
|
79
356
|
export const assertNotNull: <T>(
|
|
@@ -95,15 +372,23 @@ export const assertNotNull: <T>(
|
|
|
95
372
|
* ### Example
|
|
96
373
|
*
|
|
97
374
|
* ```ts
|
|
98
|
-
* import {
|
|
375
|
+
* import {
|
|
376
|
+
* assert,
|
|
377
|
+
* assertEqual,
|
|
378
|
+
* assertErr,
|
|
379
|
+
* assertNotUndefined,
|
|
380
|
+
* assertType,
|
|
381
|
+
* trySync,
|
|
382
|
+
* } from "@evolu/common";
|
|
99
383
|
*
|
|
100
384
|
* const value = null as string | null | undefined;
|
|
101
385
|
* assertNotUndefined(value);
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* );
|
|
386
|
+
* assertType<string | null, typeof value>();
|
|
387
|
+
* assertEqual(value, null);
|
|
388
|
+
* const result = trySync(() => assertNotUndefined(undefined));
|
|
389
|
+
* assertErr(result);
|
|
390
|
+
* assert(result.error instanceof Error, "Expected an Error.");
|
|
391
|
+
* assertEqual(result.error.message, "Expected value not to be undefined.");
|
|
107
392
|
* ```
|
|
108
393
|
*/
|
|
109
394
|
export const assertNotUndefined: <T>(
|
|
@@ -125,13 +410,21 @@ export const assertNotUndefined: <T>(
|
|
|
125
410
|
* ### Example
|
|
126
411
|
*
|
|
127
412
|
* ```ts
|
|
128
|
-
* import {
|
|
413
|
+
* import {
|
|
414
|
+
* assertEqual,
|
|
415
|
+
* assertErr,
|
|
416
|
+
* assertNonEmptyArray,
|
|
417
|
+
* assertType,
|
|
418
|
+
* trySync,
|
|
419
|
+
* type NonEmptyArray,
|
|
420
|
+
* } from "@evolu/common";
|
|
129
421
|
*
|
|
130
422
|
* const values = [1, 2, 3];
|
|
131
423
|
* assertNonEmptyArray(values);
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
424
|
+
* assertType<NonEmptyArray<number>, typeof values>();
|
|
425
|
+
* assertEqual(values[0], 1);
|
|
426
|
+
* const result = trySync(() => assertNonEmptyArray([]));
|
|
427
|
+
* assertErr(result);
|
|
135
428
|
* ```
|
|
136
429
|
*/
|
|
137
430
|
export const assertNonEmptyArray: <T>(
|
|
@@ -154,15 +447,20 @@ export const assertNonEmptyArray: <T>(
|
|
|
154
447
|
*
|
|
155
448
|
* ```ts
|
|
156
449
|
* import {
|
|
450
|
+
* assertEqual,
|
|
451
|
+
* assertErr,
|
|
157
452
|
* assertNonEmptyReadonlyArray,
|
|
453
|
+
* assertType,
|
|
454
|
+
* trySync,
|
|
158
455
|
* type NonEmptyReadonlyArray,
|
|
159
456
|
* } from "@evolu/common";
|
|
160
457
|
*
|
|
161
458
|
* const values: ReadonlyArray<number> = [1, 2, 3];
|
|
162
459
|
* assertNonEmptyReadonlyArray(values);
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
460
|
+
* assertType<NonEmptyReadonlyArray<number>, typeof values>();
|
|
461
|
+
* assertEqual(values[0], 1);
|
|
462
|
+
* const result = trySync(() => assertNonEmptyReadonlyArray([]));
|
|
463
|
+
* assertErr(result);
|
|
166
464
|
* ```
|
|
167
465
|
*/
|
|
168
466
|
export const assertNonEmptyReadonlyArray: <T>(
|
|
@@ -183,14 +481,21 @@ export const assertNonEmptyReadonlyArray: <T>(
|
|
|
183
481
|
* ### Example
|
|
184
482
|
*
|
|
185
483
|
* ```ts
|
|
186
|
-
* import {
|
|
484
|
+
* import {
|
|
485
|
+
* assert,
|
|
486
|
+
* assertEqual,
|
|
487
|
+
* assertErr,
|
|
488
|
+
* assertNotDisposed,
|
|
489
|
+
* trySync,
|
|
490
|
+
* } from "@evolu/common";
|
|
187
491
|
*
|
|
188
492
|
* await using disposer = new globalThis.AsyncDisposableStack();
|
|
189
|
-
*
|
|
493
|
+
* assertNotDisposed(disposer);
|
|
190
494
|
* await disposer.disposeAsync();
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
* );
|
|
495
|
+
* const result = trySync(() => assertNotDisposed(disposer));
|
|
496
|
+
* assertErr(result);
|
|
497
|
+
* assert(result.error instanceof Error, "Expected an Error.");
|
|
498
|
+
* assertEqual(result.error.message, "Cannot use a disposed object.");
|
|
194
499
|
* ```
|
|
195
500
|
*
|
|
196
501
|
* This is the JavaScript equivalent of the .NET `ObjectDisposedException`
|
package/src/BigInt.ts
CHANGED
|
@@ -24,12 +24,12 @@ export const clampBigInt =
|
|
|
24
24
|
* ### Example
|
|
25
25
|
*
|
|
26
26
|
* ```ts
|
|
27
|
-
* import { isBetweenBigInt } from "@evolu/common";
|
|
27
|
+
* import { assertFalse, assertTrue, isBetweenBigInt } from "@evolu/common";
|
|
28
28
|
*
|
|
29
29
|
* const isBetween10And20 = isBetweenBigInt(10n, 20n);
|
|
30
30
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
* assertTrue(isBetween10And20(20n));
|
|
32
|
+
* assertFalse(isBetween10And20(25n));
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
35
|
export const isBetweenBigInt =
|
package/src/Brand.ts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* ### Single brand
|
|
19
19
|
*
|
|
20
20
|
* ```ts
|
|
21
|
-
* import type
|
|
21
|
+
* import { assertEqual, type Brand } from "@evolu/common";
|
|
22
22
|
*
|
|
23
23
|
* type UserId = number & Brand<"UserId">;
|
|
24
24
|
*
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* const createUserId = (value: number): UserId => value as UserId;
|
|
28
28
|
* const getUser = (id: UserId): number => id;
|
|
29
29
|
* const userId = createUserId(123);
|
|
30
|
-
*
|
|
30
|
+
* assertEqual(getUser(userId), 123);
|
|
31
31
|
* // @ts-expect-error A plain number is not a UserId.
|
|
32
32
|
* getUser(123);
|
|
33
33
|
* ```
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* ### Multiple brands
|
|
36
36
|
*
|
|
37
37
|
* ```ts
|
|
38
|
-
* import type
|
|
38
|
+
* import { assertEqual, type Brand } from "@evolu/common";
|
|
39
39
|
*
|
|
40
40
|
* type Min1 = string & Brand<"Min1">;
|
|
41
41
|
* type Max100 = string & Brand<"Max100">;
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
*
|
|
47
47
|
* const min1Max100Value: Min1Max100 = "typescript" as Min1Max100;
|
|
48
48
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
49
|
+
* assertEqual(requiresMin1(min1Max100Value), "typescript");
|
|
50
|
+
* assertEqual(requiresMax100(min1Max100Value), "typescript");
|
|
51
51
|
* ```
|
|
52
52
|
*
|
|
53
53
|
* ### Standalone brand
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
* code platform-agnostic.
|
|
60
60
|
*
|
|
61
61
|
* ```ts
|
|
62
|
-
* import type
|
|
62
|
+
* import { assertSame, type Brand } from "@evolu/common";
|
|
63
63
|
*
|
|
64
64
|
* type NativePort = Brand<"NativePort">;
|
|
65
65
|
*
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
*
|
|
68
68
|
* const nativeValue: unknown = { id: 1 };
|
|
69
69
|
* const port = nativeValue as NativePort;
|
|
70
|
-
*
|
|
70
|
+
* assertSame(requiresNativePort(port), nativeValue);
|
|
71
71
|
* // @ts-expect-error An unknown value is not a NativePort.
|
|
72
72
|
* requiresNativePort(nativeValue);
|
|
73
73
|
* ```
|
package/src/Buffer.ts
CHANGED
|
@@ -52,6 +52,9 @@ export class BufferError extends Error {
|
|
|
52
52
|
*
|
|
53
53
|
* ```ts
|
|
54
54
|
* import {
|
|
55
|
+
* assert,
|
|
56
|
+
* assertEqual,
|
|
57
|
+
* assertErr,
|
|
55
58
|
* createBuffer,
|
|
56
59
|
* createIdFromString,
|
|
57
60
|
* IdBytes,
|
|
@@ -59,6 +62,7 @@ export class BufferError extends Error {
|
|
|
59
62
|
* idBytesTypeValueLength,
|
|
60
63
|
* idToIdBytes,
|
|
61
64
|
* NonNegativeInt,
|
|
65
|
+
* trySync,
|
|
62
66
|
* } from "@evolu/common";
|
|
63
67
|
* import {
|
|
64
68
|
* decodeNonNegativeInt,
|
|
@@ -71,13 +75,17 @@ export class BufferError extends Error {
|
|
|
71
75
|
* buffer.extend(idToIdBytes(id));
|
|
72
76
|
*
|
|
73
77
|
* const decoder = createBuffer(buffer.unwrap());
|
|
74
|
-
*
|
|
78
|
+
* assertEqual(decodeNonNegativeInt(decoder), 300);
|
|
75
79
|
* const decodedId = idBytesToId(
|
|
76
80
|
* IdBytes.orThrow(decoder.shiftN(idBytesTypeValueLength)),
|
|
77
81
|
* );
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
82
|
+
* assertEqual(decodedId, id);
|
|
83
|
+
* const result = trySync(() => decodeNonNegativeInt(decoder));
|
|
84
|
+
* assertErr(result);
|
|
85
|
+
* assert(
|
|
86
|
+
* result.error instanceof Error &&
|
|
87
|
+
* result.error.message === "Buffer parse ended prematurely",
|
|
88
|
+
* "Expected the premature-buffer-end error.",
|
|
81
89
|
* );
|
|
82
90
|
* ```
|
|
83
91
|
*
|
package/src/Cache.ts
CHANGED
|
@@ -43,16 +43,21 @@ export interface Cache<K, V> {
|
|
|
43
43
|
* ### Example
|
|
44
44
|
*
|
|
45
45
|
* ```ts
|
|
46
|
-
* import {
|
|
46
|
+
* import {
|
|
47
|
+
* assertEqual,
|
|
48
|
+
* assertFalse,
|
|
49
|
+
* createLruCache,
|
|
50
|
+
* PositiveInt,
|
|
51
|
+
* } from "@evolu/common";
|
|
47
52
|
*
|
|
48
53
|
* const cache = createLruCache<string, number>(PositiveInt.orThrow(2));
|
|
49
54
|
* cache.set("a", 1);
|
|
50
55
|
* cache.set("b", 2);
|
|
51
56
|
* // Reading "a" makes "b" the least recently used entry.
|
|
52
|
-
*
|
|
57
|
+
* assertEqual(cache.get("a"), 1);
|
|
53
58
|
* cache.set("c", 3);
|
|
54
59
|
*
|
|
55
|
-
*
|
|
60
|
+
* assertFalse(cache.has("b"));
|
|
56
61
|
* ```
|
|
57
62
|
*/
|
|
58
63
|
export const createLruCache = <K, V>(capacity: PositiveInt): Cache<K, V> => {
|
package/src/Callbacks.ts
CHANGED
|
@@ -25,7 +25,11 @@ import type { Callback } from "./Types.ts";
|
|
|
25
25
|
* ### Correlating callback responses
|
|
26
26
|
*
|
|
27
27
|
* ```ts
|
|
28
|
-
* import {
|
|
28
|
+
* import {
|
|
29
|
+
* assertEqual,
|
|
30
|
+
* createCallbacks,
|
|
31
|
+
* testCreateDeps,
|
|
32
|
+
* } from "@evolu/common";
|
|
29
33
|
*
|
|
30
34
|
* const deps = testCreateDeps();
|
|
31
35
|
*
|
|
@@ -37,7 +41,7 @@ import type { Callback } from "./Types.ts";
|
|
|
37
41
|
* });
|
|
38
42
|
* callbacks.execute(noArgumentId);
|
|
39
43
|
* callbacks.execute(noArgumentId);
|
|
40
|
-
*
|
|
44
|
+
* assertEqual(noArgumentCalls, 1);
|
|
41
45
|
*
|
|
42
46
|
* // Typed callback
|
|
43
47
|
* using stringCallbacks = createCallbacks<string>(deps);
|
|
@@ -46,14 +50,14 @@ import type { Callback } from "./Types.ts";
|
|
|
46
50
|
* received = value;
|
|
47
51
|
* });
|
|
48
52
|
* stringCallbacks.execute(stringCallbackId, "hello");
|
|
49
|
-
*
|
|
53
|
+
* assertEqual(received, "hello");
|
|
50
54
|
*
|
|
51
55
|
* // Promise.withResolvers
|
|
52
56
|
* using promiseCallbacks = createCallbacks<string>(deps);
|
|
53
57
|
* const { promise, resolve } = Promise.withResolvers<string>();
|
|
54
58
|
* const promiseCallbackId = promiseCallbacks.register(resolve);
|
|
55
59
|
* promiseCallbacks.execute(promiseCallbackId, "resolved value");
|
|
56
|
-
*
|
|
60
|
+
* assertEqual(await promise, "resolved value");
|
|
57
61
|
* ```
|
|
58
62
|
*
|
|
59
63
|
* @template T - The type of argument passed to callbacks (defaults to undefined
|