@evolu/common 7.4.1 → 8.0.0-next.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 +4 -61
- package/dist/src/Array.d.ts +343 -102
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +181 -85
- package/dist/src/Assert.d.ts +57 -11
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +47 -11
- package/dist/src/BigInt.d.ts +6 -1
- package/dist/src/BigInt.d.ts.map +1 -1
- package/dist/src/BigInt.js +5 -0
- package/dist/src/Brand.d.ts +40 -12
- package/dist/src/Brand.d.ts.map +1 -1
- package/dist/src/Brand.js +5 -0
- package/dist/src/Buffer.d.ts +6 -1
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Buffer.js +7 -2
- package/dist/src/Cache.d.ts +10 -2
- package/dist/src/Cache.d.ts.map +1 -1
- package/dist/src/Cache.js +6 -0
- package/dist/src/Callbacks.d.ts +10 -7
- package/dist/src/Callbacks.d.ts.map +1 -1
- package/dist/src/Callbacks.js +23 -13
- package/dist/src/Console.d.ts +361 -69
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +217 -117
- package/dist/src/Crypto.d.ts +70 -21
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +72 -27
- package/dist/src/Eq.d.ts +22 -2
- package/dist/src/Eq.d.ts.map +1 -1
- package/dist/src/Eq.js +21 -1
- package/dist/src/Error.d.ts +23 -12
- package/dist/src/Error.d.ts.map +1 -1
- package/dist/src/Error.js +27 -11
- package/dist/src/Function.d.ts +128 -56
- package/dist/src/Function.d.ts.map +1 -1
- package/dist/src/Function.js +118 -14
- package/dist/src/Identicon.d.ts +5 -0
- package/dist/src/Identicon.d.ts.map +1 -1
- package/dist/src/Identicon.js +6 -1
- package/dist/src/Lookup.d.ts +160 -0
- package/dist/src/Lookup.d.ts.map +1 -0
- package/dist/src/Lookup.js +192 -0
- package/dist/src/Microtask.d.ts +21 -0
- package/dist/src/Microtask.d.ts.map +1 -0
- package/dist/src/Microtask.js +37 -0
- package/dist/src/Number.d.ts +18 -4
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Number.js +23 -1
- package/dist/src/Object.d.ts +110 -5
- package/dist/src/Object.d.ts.map +1 -1
- package/dist/src/Object.js +108 -5
- package/dist/src/Option.d.ts +58 -0
- package/dist/src/Option.d.ts.map +1 -0
- package/dist/src/Option.js +43 -0
- package/dist/src/Order.d.ts +5 -0
- package/dist/src/Order.d.ts.map +1 -1
- package/dist/src/Order.js +8 -3
- package/dist/src/Platform.d.ts +36 -2
- package/dist/src/Platform.d.ts.map +1 -1
- package/dist/src/Platform.js +10 -6
- package/dist/src/Polyfills.d.ts +27 -0
- package/dist/src/Polyfills.d.ts.map +1 -0
- package/dist/src/Polyfills.js +299 -0
- package/dist/src/Random.d.ts +18 -7
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/Random.js +9 -7
- package/dist/src/Redacted.d.ts +7 -4
- package/dist/src/Redacted.d.ts.map +1 -1
- package/dist/src/Redacted.js +5 -0
- package/dist/src/Ref.d.ts +31 -16
- package/dist/src/Ref.d.ts.map +1 -1
- package/dist/src/Ref.js +35 -7
- package/dist/src/RefCount.d.ts +62 -0
- package/dist/src/RefCount.d.ts.map +1 -0
- package/dist/src/RefCount.js +83 -0
- package/dist/src/Relation.d.ts +84 -29
- package/dist/src/Relation.d.ts.map +1 -1
- package/dist/src/Relation.js +83 -105
- package/dist/src/Resource.d.ts +263 -0
- package/dist/src/Resource.d.ts.map +1 -0
- package/dist/src/Resource.js +389 -0
- package/dist/src/Result.d.ts +390 -374
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +142 -70
- package/dist/src/Schedule.d.ts +953 -0
- package/dist/src/Schedule.d.ts.map +1 -0
- package/dist/src/Schedule.js +1199 -0
- package/dist/src/Set.d.ts +181 -0
- package/dist/src/Set.d.ts.map +1 -0
- package/dist/src/Set.js +137 -0
- package/dist/src/Skiplist.d.ts +6 -1
- package/dist/src/Skiplist.d.ts.map +1 -1
- package/dist/src/Skiplist.js +5 -0
- package/dist/src/Sqlite.d.ts +160 -60
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +290 -190
- package/dist/src/Store.d.ts +36 -28
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Store.js +55 -15
- package/dist/src/String.d.ts +5 -0
- package/dist/src/String.d.ts.map +1 -1
- package/dist/src/String.js +5 -0
- package/dist/src/Task.d.ts +2263 -423
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +1488 -348
- package/dist/src/Test.d.ts +122 -0
- package/dist/src/Test.d.ts.map +1 -0
- package/dist/src/Test.js +66 -0
- package/dist/src/Time.d.ts +201 -48
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +190 -86
- package/dist/src/Tracer.d.ts +48 -0
- package/dist/src/Tracer.d.ts.map +1 -0
- package/dist/src/Tracer.js +6 -0
- package/dist/src/Type.d.ts +582 -209
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +362 -240
- package/dist/src/Types.d.ts +160 -6
- package/dist/src/Types.d.ts.map +1 -1
- package/dist/src/Types.js +22 -2
- package/dist/src/WebSocket.d.ts +113 -58
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +210 -118
- package/dist/src/Worker.d.ts +245 -60
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +220 -64
- package/dist/src/index.d.ts +25 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +19 -3
- package/dist/src/local-first/Db.d.ts +24 -213
- package/dist/src/local-first/Db.d.ts.map +1 -1
- package/dist/src/local-first/Db.js +622 -293
- package/dist/src/local-first/Error.d.ts +12 -0
- package/dist/src/local-first/Error.d.ts.map +1 -0
- package/dist/src/local-first/Error.js +6 -0
- package/dist/src/local-first/Evolu.d.ts +330 -285
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Evolu.js +472 -402
- package/dist/src/local-first/LocalAuth.d.ts +10 -10
- package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
- package/dist/src/local-first/LocalAuth.js +6 -1
- package/dist/src/local-first/Owner.d.ts +70 -27
- package/dist/src/local-first/Owner.d.ts.map +1 -1
- package/dist/src/local-first/Owner.js +27 -14
- package/dist/src/local-first/Protocol.d.ts +58 -50
- package/dist/src/local-first/Protocol.d.ts.map +1 -1
- package/dist/src/local-first/Protocol.js +253 -155
- package/dist/src/local-first/Query.d.ts +133 -43
- package/dist/src/local-first/Query.d.ts.map +1 -1
- package/dist/src/local-first/Query.js +139 -90
- package/dist/src/local-first/Relay.d.ts +18 -38
- package/dist/src/local-first/Relay.d.ts.map +1 -1
- package/dist/src/local-first/Relay.js +59 -171
- package/dist/src/local-first/Schema.d.ts +139 -144
- package/dist/src/local-first/Schema.d.ts.map +1 -1
- package/dist/src/local-first/Schema.js +78 -163
- package/dist/src/local-first/Shared.d.ts +125 -0
- package/dist/src/local-first/Shared.d.ts.map +1 -0
- package/dist/src/local-first/Shared.js +569 -0
- package/dist/src/local-first/Storage.d.ts +50 -53
- package/dist/src/local-first/Storage.d.ts.map +1 -1
- package/dist/src/local-first/Storage.js +121 -173
- package/dist/src/local-first/Timestamp.d.ts +28 -35
- package/dist/src/local-first/Timestamp.d.ts.map +1 -1
- package/dist/src/local-first/Timestamp.js +24 -25
- package/dist/src/local-first/index.d.ts +2 -15
- package/dist/src/local-first/index.d.ts.map +1 -1
- package/dist/src/local-first/index.js +2 -15
- package/package.json +36 -26
- package/src/Array.ts +467 -106
- package/src/Assert.ts +87 -12
- package/src/BigInt.ts +7 -1
- package/src/Brand.ts +41 -12
- package/src/Buffer.ts +10 -4
- package/src/Cache.ts +11 -2
- package/src/Callbacks.ts +33 -23
- package/src/Console.ts +567 -178
- package/src/Crypto.ts +111 -62
- package/src/Eq.ts +30 -3
- package/src/Error.ts +50 -34
- package/src/Function.ts +140 -68
- package/src/Identicon.ts +7 -1
- package/src/Lookup.ts +415 -0
- package/src/Microtask.ts +58 -0
- package/src/Number.ts +40 -7
- package/src/Object.ts +155 -16
- package/src/Option.ts +74 -0
- package/src/Order.ts +11 -3
- package/src/Platform.ts +43 -7
- package/src/Polyfills.ts +465 -0
- package/src/Random.ts +25 -11
- package/src/Redacted.ts +8 -4
- package/src/Ref.ts +72 -21
- package/src/RefCount.ts +170 -0
- package/src/Relation.ts +188 -136
- package/src/Resource.ts +864 -0
- package/src/Result.ts +548 -381
- package/src/Schedule.ts +1471 -0
- package/src/Set.ts +247 -0
- package/src/Skiplist.ts +7 -1
- package/src/Sqlite.ts +409 -304
- package/src/Store.ts +94 -48
- package/src/String.ts +6 -0
- package/src/Task.ts +3685 -740
- package/src/Test.ts +162 -0
- package/src/Time.ts +348 -145
- package/src/Tracer.ts +54 -0
- package/src/Type.ts +851 -430
- package/src/Types.ts +202 -7
- package/src/WebSocket.ts +311 -178
- package/src/Worker.ts +527 -147
- package/src/index.ts +74 -3
- package/src/local-first/Db.ts +871 -597
- package/src/local-first/Error.ts +17 -0
- package/src/local-first/Evolu.ts +884 -824
- package/src/local-first/LocalAuth.ts +10 -10
- package/src/local-first/Owner.ts +94 -42
- package/src/local-first/Protocol.ts +440 -303
- package/src/local-first/Query.ts +243 -194
- package/src/local-first/Relay.ts +91 -252
- package/src/local-first/Schema.ts +284 -394
- package/src/local-first/Shared.ts +932 -0
- package/src/local-first/Storage.ts +206 -277
- package/src/local-first/Timestamp.ts +38 -45
- package/src/local-first/index.ts +2 -16
- package/LICENSE +0 -21
- package/dist/src/Instances.d.ts +0 -34
- package/dist/src/Instances.d.ts.map +0 -1
- package/dist/src/Instances.js +0 -44
- package/dist/src/Resources.d.ts +0 -118
- package/dist/src/Resources.d.ts.map +0 -1
- package/dist/src/Resources.js +0 -197
- package/dist/src/local-first/Platform.d.ts +0 -25
- package/dist/src/local-first/Platform.d.ts.map +0 -1
- package/dist/src/local-first/Platform.js +0 -1
- package/dist/src/local-first/Public.d.ts +0 -22
- package/dist/src/local-first/Public.d.ts.map +0 -1
- package/dist/src/local-first/Public.js +0 -15
- package/dist/src/local-first/PublicKysely.d.ts +0 -148
- package/dist/src/local-first/PublicKysely.d.ts.map +0 -1
- package/dist/src/local-first/PublicKysely.js +0 -184
- package/dist/src/local-first/Sync.d.ts +0 -112
- package/dist/src/local-first/Sync.d.ts.map +0 -1
- package/dist/src/local-first/Sync.js +0 -526
- package/src/Instances.ts +0 -92
- package/src/Resources.ts +0 -367
- package/src/local-first/Platform.ts +0 -27
- package/src/local-first/Public.ts +0 -42
- package/src/local-first/PublicKysely.ts +0 -239
- package/src/local-first/Sync.ts +0 -949
package/dist/src/Array.js
CHANGED
|
@@ -1,8 +1,67 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Array
|
|
3
|
-
* mutations
|
|
2
|
+
* Array helpers that help TypeScript help you.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
4
|
+
* - **Non-empty arrays**: compile-time guarantee of at least one element
|
|
5
|
+
* - **Readonly arrays**: prevents accidental mutation
|
|
6
|
+
*
|
|
7
|
+
* Instead of checking array length at runtime, use {@link NonEmptyReadonlyArray}
|
|
8
|
+
* so TypeScript rejects empty arrays at compile time. Functions like
|
|
9
|
+
* {@link firstInArray} require a non-empty array — TypeScript won't let us pass
|
|
10
|
+
* an empty one. {@link mapArray} preserves non-emptiness (native `map` doesn't),
|
|
11
|
+
* while {@link appendToArray} and {@link prependToArray} guarantee the result is
|
|
12
|
+
* non-empty.
|
|
13
|
+
*
|
|
14
|
+
* All helpers return readonly arrays for safety. Consider how dangerous native
|
|
15
|
+
* `sort()` is — it mutates the original array and returns it, making bugs hard
|
|
16
|
+
* to track:
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* const sortScores = (arr: number[]) => arr.sort((a, b) => a - b);
|
|
20
|
+
*
|
|
21
|
+
* const scores = [3, 1, 2];
|
|
22
|
+
* const leaderboard = sortScores(scores);
|
|
23
|
+
* leaderboard; // [1, 2, 3]
|
|
24
|
+
* scores; // [1, 2, 3] — original order lost!
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* Imagine every method doing that.
|
|
28
|
+
*
|
|
29
|
+
* On a `ReadonlyArray`, `.sort()` doesn't even exist. Use {@link sortArray}
|
|
30
|
+
* instead:
|
|
31
|
+
*
|
|
32
|
+
* ```ts
|
|
33
|
+
* const sortScores = (arr: ReadonlyArray<number>) =>
|
|
34
|
+
* sortArray(arr, (a, b) => a - b);
|
|
35
|
+
*
|
|
36
|
+
* const scores: ReadonlyArray<number> = [3, 1, 2];
|
|
37
|
+
* const leaderboard = sortScores(scores);
|
|
38
|
+
* leaderboard; // [1, 2, 3]
|
|
39
|
+
* scores; // [3, 1, 2] — safe!
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* Even better, require a {@link NonEmptyReadonlyArray} — there's nothing to sort
|
|
43
|
+
* if the array is empty anyway:
|
|
44
|
+
*
|
|
45
|
+
* ```ts
|
|
46
|
+
* const sortScores = (arr: NonEmptyReadonlyArray<number>) =>
|
|
47
|
+
* sortArray(arr, (a, b) => a - b);
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* Sorting an empty array isn't expensive, but functions can have side effects
|
|
51
|
+
* like database queries or network requests. Using non-empty arrays whenever
|
|
52
|
+
* possible is a good convention.
|
|
53
|
+
*
|
|
54
|
+
* For performance-critical cases where mutation is needed, Evolu provides
|
|
55
|
+
* {@link shiftFromArray} and {@link popFromArray} — but only because they improve
|
|
56
|
+
* type safety by returning a guaranteed `T` rather than an optional value.
|
|
57
|
+
*
|
|
58
|
+
* ### When to use native methods
|
|
59
|
+
*
|
|
60
|
+
* These helpers only exist where they add type-level value. Native methods like
|
|
61
|
+
* `find`, `some`, `every`, `includes`, `indexOf`, and `findIndex` work well on
|
|
62
|
+
* readonly arrays without mutation — use them directly.
|
|
63
|
+
*
|
|
64
|
+
* ## Examples
|
|
6
65
|
*
|
|
7
66
|
* ```ts
|
|
8
67
|
* // Types - compile-time guarantee of at least one element
|
|
@@ -12,15 +71,13 @@
|
|
|
12
71
|
*
|
|
13
72
|
* // Type guards
|
|
14
73
|
* const arr: ReadonlyArray<number> = [1, 2, 3];
|
|
15
|
-
* if (
|
|
74
|
+
* if (isNonEmptyArray(arr)) {
|
|
16
75
|
* firstInArray(arr);
|
|
17
76
|
* }
|
|
18
77
|
*
|
|
19
|
-
* //
|
|
78
|
+
* // Transformations
|
|
20
79
|
* const appended = appendToArray([1, 2, 3], 4); // [1, 2, 3, 4]
|
|
21
80
|
* const prepended = prependToArray([2, 3], 1); // [1, 2, 3]
|
|
22
|
-
*
|
|
23
|
-
* // Transformations
|
|
24
81
|
* const readonly: ReadonlyArray<number> = [1, 2, 3];
|
|
25
82
|
* const mapped = mapArray(readonly, (x) => x * 2); // [2, 4, 6]
|
|
26
83
|
* const filtered = filterArray(readonly, (x) => x > 1); // [2, 3]
|
|
@@ -28,7 +85,7 @@
|
|
|
28
85
|
* const [evens, odds] = partitionArray(
|
|
29
86
|
* [1, 2, 3, 4, 5],
|
|
30
87
|
* (x) => x % 2 === 0,
|
|
31
|
-
* );
|
|
88
|
+
* );
|
|
32
89
|
*
|
|
33
90
|
* // Accessors
|
|
34
91
|
* const first = firstInArray(["a", "b", "c"]); // "a"
|
|
@@ -36,116 +93,123 @@
|
|
|
36
93
|
*
|
|
37
94
|
* // Mutations
|
|
38
95
|
* const mutable: NonEmptyArray<number> = [1, 2, 3];
|
|
39
|
-
*
|
|
96
|
+
* shiftFromArray(mutable); // 1 (guaranteed to exist)
|
|
40
97
|
* mutable; // [2, 3]
|
|
41
98
|
* ```
|
|
42
99
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
100
|
+
* ## Composition
|
|
101
|
+
*
|
|
102
|
+
* All array helpers use a data-first style (the array is the first argument)
|
|
103
|
+
* because it's natural for single operations:
|
|
45
104
|
*
|
|
46
105
|
* ```ts
|
|
47
|
-
* // Data-first is natural for single operations.
|
|
48
106
|
* const timestamps = mapArray(messages, (m) => m.timestamp);
|
|
107
|
+
* ```
|
|
49
108
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* mapArray(dedupeArray(appendToArray(value, 2)), (x) => x * 2),
|
|
53
|
-
* );
|
|
109
|
+
* Data-first style also reads well for a few operations, often fitting on a
|
|
110
|
+
* line:
|
|
54
111
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* // |> mapArray(%, (x) => x * 2)
|
|
60
|
-
* // |> firstInArray(%);
|
|
61
|
-
*
|
|
62
|
-
* // Until the pipe operator lands, use nested calls or name each step:
|
|
63
|
-
* const appended = appendToArray(value, 2);
|
|
64
|
-
* const deduped = dedupeArray(appended);
|
|
65
|
-
* const mapped = mapArray(deduped, (x) => x * 2);
|
|
66
|
-
* const result = firstInArray(mapped);
|
|
112
|
+
* ```ts
|
|
113
|
+
* const cheapest = firstInArray(sortArray(prices, orderNumber));
|
|
114
|
+
* const uniqueNames = dedupeArray(mapArray(users, (u) => u.name));
|
|
115
|
+
* const latestDone = lastInArray(filterArray(jobs, isCompletedJob));
|
|
67
116
|
* ```
|
|
68
117
|
*
|
|
69
|
-
*
|
|
118
|
+
* For more operations, create a function like `getOldestActiveUser` or a
|
|
119
|
+
* generic helper.
|
|
70
120
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
121
|
+
* Some libraries provide dual APIs with data-last for pipe-based composition.
|
|
122
|
+
* Evolu prefers simplicity (in Latin, simplex means "one") so we don't have to
|
|
123
|
+
* choose between seemingly equivalent options (Buridan's ass dilemma).
|
|
74
124
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* - It aligns with the upcoming JavaScript pipe operator.
|
|
78
|
-
*
|
|
79
|
-
* **Note**: Feel free to use Array instance methods (mutation) if you think
|
|
80
|
-
* it's better (performance, local scope, etc.).
|
|
125
|
+
* Evolu doesn't provide `pipe` because few operations compose well without it,
|
|
126
|
+
* and for more operations, well-named functions communicate intent better.
|
|
81
127
|
*
|
|
82
128
|
* @module
|
|
83
129
|
*/
|
|
130
|
+
import { identity } from "./Function.js";
|
|
84
131
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* Use `if (!isNonEmptyArray(arr))` for empty checks.
|
|
132
|
+
* An empty readonly array.
|
|
88
133
|
*
|
|
89
|
-
*
|
|
134
|
+
* Use as a default or initial value to avoid allocating new empty arrays.
|
|
90
135
|
*
|
|
91
|
-
*
|
|
92
|
-
* const arr: Array<number> = [1, 2, 3];
|
|
93
|
-
* if (isNonEmptyArray(arr)) {
|
|
94
|
-
* firstInArray(arr); // arr is NonEmptyArray<number>
|
|
95
|
-
* }
|
|
96
|
-
* ```
|
|
97
|
-
*
|
|
98
|
-
* @category Type Guards
|
|
136
|
+
* @group Constants
|
|
99
137
|
*/
|
|
100
|
-
export const
|
|
138
|
+
export const emptyArray = [];
|
|
139
|
+
export function arrayFrom(iterableOrLength, map) {
|
|
140
|
+
if (typeof iterableOrLength === "number") {
|
|
141
|
+
return Array.from({ length: iterableOrLength }, (_, i) => map(i));
|
|
142
|
+
}
|
|
143
|
+
return Array.isArray(iterableOrLength)
|
|
144
|
+
? iterableOrLength
|
|
145
|
+
: [...iterableOrLength];
|
|
146
|
+
}
|
|
101
147
|
/**
|
|
102
|
-
*
|
|
103
|
-
* {@link NonEmptyReadonlyArray}.
|
|
148
|
+
* Better `Array.fromAsync`.
|
|
104
149
|
*
|
|
105
|
-
*
|
|
150
|
+
* Returns a readonly array and awaits promised items from sync or async
|
|
151
|
+
* iterables.
|
|
106
152
|
*
|
|
107
153
|
* ### Example
|
|
108
154
|
*
|
|
109
155
|
* ```ts
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
156
|
+
* await arrayFromAsync(new Set([1, 2, 3])); // ReadonlyArray<number>
|
|
157
|
+
* await arrayFromAsync(
|
|
158
|
+
* (async function* () {
|
|
159
|
+
* yield Promise.resolve(1);
|
|
160
|
+
* yield Promise.resolve(2);
|
|
161
|
+
* })(),
|
|
162
|
+
* ); // [1, 2]
|
|
114
163
|
* ```
|
|
115
164
|
*
|
|
116
|
-
*
|
|
165
|
+
* Unlike `Array.fromAsync`, there's no map parameter — map the result with
|
|
166
|
+
* {@link mapArray} or use
|
|
167
|
+
* {@link https://web.dev/blog/baseline-iterator-helpers | iterator helpers}
|
|
168
|
+
* directly on iterables.
|
|
169
|
+
*
|
|
170
|
+
* @group Constructors
|
|
117
171
|
*/
|
|
118
|
-
export const
|
|
172
|
+
export const arrayFromAsync = async (iterable) => Array.fromAsync(iterable);
|
|
173
|
+
export function isNonEmptyArray(array) {
|
|
174
|
+
return array.length > 0;
|
|
175
|
+
}
|
|
119
176
|
/**
|
|
120
177
|
* Appends an item to an array, returning a new non-empty readonly array.
|
|
121
178
|
*
|
|
122
|
-
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
123
|
-
*
|
|
124
179
|
* ### Example
|
|
125
180
|
*
|
|
126
181
|
* ```ts
|
|
127
182
|
* appendToArray([1, 2, 3], 4); // [1, 2, 3, 4]
|
|
128
183
|
* ```
|
|
129
184
|
*
|
|
130
|
-
* @
|
|
185
|
+
* @group Transformations
|
|
131
186
|
*/
|
|
132
187
|
export const appendToArray = (array, item) => [...array, item];
|
|
133
188
|
/**
|
|
134
189
|
* Prepends an item to an array, returning a new non-empty readonly array.
|
|
135
190
|
*
|
|
136
|
-
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
137
|
-
*
|
|
138
191
|
* ### Example
|
|
139
192
|
*
|
|
140
193
|
* ```ts
|
|
141
194
|
* prependToArray([2, 3], 1); // [1, 2, 3]
|
|
142
195
|
* ```
|
|
143
196
|
*
|
|
144
|
-
* @
|
|
197
|
+
* @group Transformations
|
|
145
198
|
*/
|
|
146
199
|
export const prependToArray = (array, item) => [item, ...array];
|
|
147
200
|
export function mapArray(array, mapper) {
|
|
148
|
-
|
|
201
|
+
// For loop is faster than array.map.
|
|
202
|
+
const length = array.length;
|
|
203
|
+
const result = new Array(length);
|
|
204
|
+
for (let i = 0; i < length; i++)
|
|
205
|
+
result[i] = mapper(array[i], i);
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
export function flatMapArray(array, mapper = identity) {
|
|
209
|
+
return array.flatMap(mapper);
|
|
210
|
+
}
|
|
211
|
+
export function concatArrays(first, second) {
|
|
212
|
+
return [...first, ...second];
|
|
149
213
|
}
|
|
150
214
|
export function filterArray(array, predicate) {
|
|
151
215
|
return array.filter(predicate);
|
|
@@ -176,10 +240,39 @@ export function partitionArray(array, predicate) {
|
|
|
176
240
|
}
|
|
177
241
|
return [trueArray, falseArray];
|
|
178
242
|
}
|
|
243
|
+
export function sortArray(array, compareFn) {
|
|
244
|
+
return array.toSorted(compareFn);
|
|
245
|
+
}
|
|
246
|
+
export function reverseArray(array) {
|
|
247
|
+
return array.toReversed();
|
|
248
|
+
}
|
|
179
249
|
/**
|
|
180
|
-
* Returns
|
|
250
|
+
* Returns a new readonly array with elements removed and/or replaced.
|
|
251
|
+
*
|
|
252
|
+
* Wraps native `toSpliced`.
|
|
253
|
+
*
|
|
254
|
+
* ### Example
|
|
255
|
+
*
|
|
256
|
+
* ```ts
|
|
257
|
+
* spliceArray([1, 2, 3, 4], 1, 2); // [1, 4]
|
|
258
|
+
* spliceArray([1, 2, 3], 1, 1, 10, 11); // [1, 10, 11, 3]
|
|
259
|
+
* ```
|
|
181
260
|
*
|
|
182
|
-
*
|
|
261
|
+
* @group Transformations
|
|
262
|
+
*/
|
|
263
|
+
export const spliceArray = (array, start, deleteCount, ...items) => array.toSpliced(start, deleteCount, ...items);
|
|
264
|
+
export function zipArray(arrays) {
|
|
265
|
+
if (arrays.length === 0)
|
|
266
|
+
return emptyArray;
|
|
267
|
+
const minLength = Math.min(...mapArray(arrays, (a) => a.length));
|
|
268
|
+
const result = new Array(minLength);
|
|
269
|
+
for (let i = 0; i < minLength; i++) {
|
|
270
|
+
result[i] = mapArray(arrays, (a) => a[i]);
|
|
271
|
+
}
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Returns the first element of a non-empty array.
|
|
183
276
|
*
|
|
184
277
|
* ### Example
|
|
185
278
|
*
|
|
@@ -187,52 +280,55 @@ export function partitionArray(array, predicate) {
|
|
|
187
280
|
* firstInArray(["a", "b", "c"]); // "a"
|
|
188
281
|
* ```
|
|
189
282
|
*
|
|
190
|
-
* @
|
|
283
|
+
* @group Accessors
|
|
191
284
|
*/
|
|
192
285
|
export const firstInArray = (array) => array[0];
|
|
193
286
|
/**
|
|
194
287
|
* Returns the last element of a non-empty array.
|
|
195
288
|
*
|
|
196
|
-
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
197
|
-
*
|
|
198
289
|
* ### Example
|
|
199
290
|
*
|
|
200
291
|
* ```ts
|
|
201
292
|
* lastInArray(["a", "b", "c"]); // "c"
|
|
202
293
|
* ```
|
|
203
294
|
*
|
|
204
|
-
* @
|
|
295
|
+
* @group Accessors
|
|
205
296
|
*/
|
|
206
297
|
export const lastInArray = (array) => array[array.length - 1];
|
|
207
298
|
/**
|
|
208
|
-
* Shifts
|
|
299
|
+
* Shifts (removes and returns) the first element from a non-empty mutable
|
|
300
|
+
* array.
|
|
209
301
|
*
|
|
210
302
|
* **Mutates** the original array.
|
|
211
303
|
*
|
|
212
304
|
* ### Example
|
|
213
305
|
*
|
|
214
306
|
* ```ts
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
307
|
+
* // Process a queue of callbacks
|
|
308
|
+
* const waitingQueue: Array<() => void> = [callback1, callback2];
|
|
309
|
+
* if (isNonEmptyArray(waitingQueue)) {
|
|
310
|
+
* shiftFromArray(waitingQueue)(); // Remove and immediately invoke
|
|
311
|
+
* }
|
|
218
312
|
* ```
|
|
219
313
|
*
|
|
220
|
-
* @
|
|
314
|
+
* @group Mutations
|
|
221
315
|
*/
|
|
222
|
-
export const
|
|
316
|
+
export const shiftFromArray = (array) => array.shift();
|
|
223
317
|
/**
|
|
224
|
-
* Pops
|
|
318
|
+
* Pops (removes and returns) the last element from a non-empty mutable array.
|
|
225
319
|
*
|
|
226
320
|
* **Mutates** the original array.
|
|
227
321
|
*
|
|
228
322
|
* ### Example
|
|
229
323
|
*
|
|
230
324
|
* ```ts
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
325
|
+
* // Process a stack of callbacks (LIFO)
|
|
326
|
+
* const callbackStack: Array<() => void> = [callback1, callback2];
|
|
327
|
+
* if (isNonEmptyArray(callbackStack)) {
|
|
328
|
+
* popFromArray(callbackStack)(); // Remove and immediately invoke
|
|
329
|
+
* }
|
|
234
330
|
* ```
|
|
235
331
|
*
|
|
236
|
-
* @
|
|
332
|
+
* @group Mutations
|
|
237
333
|
*/
|
|
238
|
-
export const
|
|
334
|
+
export const popFromArray = (array) => array.pop();
|
package/dist/src/Assert.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime assertions for invariant checking.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { Ok, Result } from "./Result.js";
|
|
7
|
+
import type { AbortError } from "./Task.js";
|
|
8
|
+
import type { AnyType, InferType } from "./Type.js";
|
|
1
9
|
/**
|
|
2
10
|
* Ensures a condition is true, throwing an error with the provided message if
|
|
3
11
|
* not.
|
|
@@ -5,23 +13,15 @@
|
|
|
5
13
|
* Prevents invalid states from propagating through the system by halting
|
|
6
14
|
* execution when a condition fails, improving reliability and debuggability.
|
|
7
15
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* TypeScript, or for catching and signaling developer mistakes eagerly
|
|
11
|
-
* invalid configuration).
|
|
16
|
+
* Do not use this instead of {@link Type}. Assertions are intended for
|
|
17
|
+
* conditions that are logically guaranteed but not statically known by
|
|
18
|
+
* TypeScript, or for catching and signaling developer mistakes eagerly.
|
|
12
19
|
*
|
|
13
20
|
* ### Example
|
|
14
21
|
*
|
|
15
22
|
* ```ts
|
|
16
23
|
* assert(true, "true is not true"); // no-op
|
|
17
24
|
* assert(false, "true is not true"); // throws Error
|
|
18
|
-
*
|
|
19
|
-
* const length = buffer.getLength();
|
|
20
|
-
* // We know length is logically non-negative, but TypeScript doesn't
|
|
21
|
-
* assert(
|
|
22
|
-
* NonNegativeInt.is(length),
|
|
23
|
-
* "buffer length should be non-negative",
|
|
24
|
-
* );
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
27
|
export declare const assert: (condition: unknown, message: string) => asserts condition;
|
|
@@ -55,4 +55,50 @@ export declare const assertNonEmptyArray: <T>(arr: Array<T>, message?: string) =
|
|
|
55
55
|
* ```
|
|
56
56
|
*/
|
|
57
57
|
export declare const assertNonEmptyReadonlyArray: <T>(arr: ReadonlyArray<T>, message?: string) => asserts arr is readonly [T, ...Array<T>];
|
|
58
|
+
/**
|
|
59
|
+
* Ensures a value conforms to a {@link Type}.
|
|
60
|
+
*
|
|
61
|
+
* Uses the Type name for the default error message.
|
|
62
|
+
*
|
|
63
|
+
* ### Example
|
|
64
|
+
*
|
|
65
|
+
* ```ts
|
|
66
|
+
* const length = buffer.getLength();
|
|
67
|
+
*
|
|
68
|
+
* // We know length is logically non-negative, but TypeScript doesn't.
|
|
69
|
+
* assertType(NonNegativeInt, length);
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare const assertType: <T extends AnyType>(type: T, value: unknown, message?: string) => asserts value is InferType<T>;
|
|
73
|
+
/**
|
|
74
|
+
* Asserts that a {@link Result} did not fail with `AbortError`.
|
|
75
|
+
*
|
|
76
|
+
* Use when abort would indicate a programmer error rather than ordinary control
|
|
77
|
+
* flow.
|
|
78
|
+
*
|
|
79
|
+
* In general, abort is normal control flow. Stopping work and returning
|
|
80
|
+
* `AbortError` is the correct behavior when a `Run` or `Fiber` is cancelled.
|
|
81
|
+
*
|
|
82
|
+
* Use `assertNotAborted` only to protect invariants in code that has already
|
|
83
|
+
* decided abort must not happen, such as resource helpers built on
|
|
84
|
+
* `unabortable`. In those places it helps fail fast on mistakes, because
|
|
85
|
+
* TypeScript cannot fully enforce that lifecycle logic is correct.
|
|
86
|
+
*/
|
|
87
|
+
export declare function assertNotAborted<T>(result: Result<T, AbortError>, message?: string): asserts result is Ok<T>;
|
|
88
|
+
export declare function assertNotAborted<T, E>(result: Result<T, E | AbortError>, message?: string): asserts result is Result<T, E>;
|
|
89
|
+
/**
|
|
90
|
+
* Guards synchronous methods on objects that may be called after disposal.
|
|
91
|
+
*
|
|
92
|
+
* Use when an API must fail fast before touching already-disposed state.
|
|
93
|
+
*
|
|
94
|
+
* ### Example
|
|
95
|
+
*
|
|
96
|
+
* ```ts
|
|
97
|
+
* const stack = new globalThis.AsyncDisposableStack();
|
|
98
|
+
* assertNotDisposed(stack); // no-op
|
|
99
|
+
* await stack.disposeAsync();
|
|
100
|
+
* assertNotDisposed(stack); // throws Error
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export declare const assertNotDisposed: (value: globalThis.DisposableStack | globalThis.AsyncDisposableStack) => void;
|
|
58
104
|
//# sourceMappingURL=Assert.d.ts.map
|
package/dist/src/Assert.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Assert.d.ts","sourceRoot":"","sources":["../../src/Assert.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Assert.d.ts","sourceRoot":"","sources":["../../src/Assert.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAQ,MAAM,WAAW,CAAC;AAE1D;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,MAAM,EAAE,CACnB,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,SAIZ,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,EAAE,CAAC,CAAC,EAClC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,EACb,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAKlC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,2BAA2B,EAAE,CAAC,CAAC,EAC1C,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,EACrB,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAK3C,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,UAAU,EAAE,CAAC,CAAC,SAAS,OAAO,EACzC,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC,CAEhC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,EAC7B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3B,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,CAAC,EACnC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,EACjC,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAYlC;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,GAC5B,OAAO,UAAU,CAAC,eAAe,GAAG,UAAU,CAAC,oBAAoB,KAClE,IAEF,CAAC"}
|
package/dist/src/Assert.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime assertions for invariant checking.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
1
6
|
/**
|
|
2
7
|
* Ensures a condition is true, throwing an error with the provided message if
|
|
3
8
|
* not.
|
|
@@ -5,23 +10,15 @@
|
|
|
5
10
|
* Prevents invalid states from propagating through the system by halting
|
|
6
11
|
* execution when a condition fails, improving reliability and debuggability.
|
|
7
12
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* TypeScript, or for catching and signaling developer mistakes eagerly
|
|
11
|
-
* invalid configuration).
|
|
13
|
+
* Do not use this instead of {@link Type}. Assertions are intended for
|
|
14
|
+
* conditions that are logically guaranteed but not statically known by
|
|
15
|
+
* TypeScript, or for catching and signaling developer mistakes eagerly.
|
|
12
16
|
*
|
|
13
17
|
* ### Example
|
|
14
18
|
*
|
|
15
19
|
* ```ts
|
|
16
20
|
* assert(true, "true is not true"); // no-op
|
|
17
21
|
* assert(false, "true is not true"); // throws Error
|
|
18
|
-
*
|
|
19
|
-
* const length = buffer.getLength();
|
|
20
|
-
* // We know length is logically non-negative, but TypeScript doesn't
|
|
21
|
-
* assert(
|
|
22
|
-
* NonNegativeInt.is(length),
|
|
23
|
-
* "buffer length should be non-negative",
|
|
24
|
-
* );
|
|
25
22
|
* ```
|
|
26
23
|
*/
|
|
27
24
|
export const assert = (condition, message) => {
|
|
@@ -63,3 +60,42 @@ export const assertNonEmptyArray = (arr, message = "Expected a non-empty array."
|
|
|
63
60
|
export const assertNonEmptyReadonlyArray = (arr, message = "Expected a non-empty readonly array.") => {
|
|
64
61
|
assert(arr.length > 0, message);
|
|
65
62
|
};
|
|
63
|
+
/**
|
|
64
|
+
* Ensures a value conforms to a {@link Type}.
|
|
65
|
+
*
|
|
66
|
+
* Uses the Type name for the default error message.
|
|
67
|
+
*
|
|
68
|
+
* ### Example
|
|
69
|
+
*
|
|
70
|
+
* ```ts
|
|
71
|
+
* const length = buffer.getLength();
|
|
72
|
+
*
|
|
73
|
+
* // We know length is logically non-negative, but TypeScript doesn't.
|
|
74
|
+
* assertType(NonNegativeInt, length);
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export const assertType = (type, value, message) => {
|
|
78
|
+
assert(type.is(value), message ?? `Expected ${type.name}.`);
|
|
79
|
+
};
|
|
80
|
+
export function assertNotAborted(result, message = "Expected result to not be aborted.") {
|
|
81
|
+
const isAbortError = !result.ok &&
|
|
82
|
+
result.error.type === "AbortError";
|
|
83
|
+
assert(!isAbortError, message);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Guards synchronous methods on objects that may be called after disposal.
|
|
87
|
+
*
|
|
88
|
+
* Use when an API must fail fast before touching already-disposed state.
|
|
89
|
+
*
|
|
90
|
+
* ### Example
|
|
91
|
+
*
|
|
92
|
+
* ```ts
|
|
93
|
+
* const stack = new globalThis.AsyncDisposableStack();
|
|
94
|
+
* assertNotDisposed(stack); // no-op
|
|
95
|
+
* await stack.disposeAsync();
|
|
96
|
+
* assertNotDisposed(stack); // throws Error
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
export const assertNotDisposed = (value) => {
|
|
100
|
+
assert(!value.disposed, "Expected value to not be disposed.");
|
|
101
|
+
};
|
package/dist/src/BigInt.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* BigInt arithmetic and comparison utilities.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { Predicate } from "./Types.js";
|
|
2
7
|
/** Increments a bigint by 1. */
|
|
3
8
|
export declare const incrementBigInt: (n: bigint) => bigint;
|
|
4
9
|
/** Decrements a bigint by 1. */
|
package/dist/src/BigInt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BigInt.d.ts","sourceRoot":"","sources":["../../src/BigInt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"BigInt.d.ts","sourceRoot":"","sources":["../../src/BigInt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,gCAAgC;AAChC,eAAO,MAAM,eAAe,GAAI,GAAG,MAAM,KAAG,MAAgB,CAAC;AAE7D,gCAAgC;AAChC,eAAO,MAAM,eAAe,GAAI,GAAG,MAAM,KAAG,MAAgB,CAAC;AAE7D,4CAA4C;AAC5C,eAAO,MAAM,WAAW,GACrB,KAAK,MAAM,EAAE,KAAK,MAAM,MACxB,GAAG,MAAM,KAAG,MACsB,CAAC;AAEtC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GACzB,KAAK,MAAM,EAAE,KAAK,MAAM,KAAG,SAAS,CAAC,MAAM,CAEd,CAAC"}
|
package/dist/src/BigInt.js
CHANGED
package/dist/src/Brand.d.ts
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A utility interface for creating branded types.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* An interface for creating branded types.
|
|
8
|
+
*
|
|
9
|
+
* Branded types enhance type safety by distinguishing otherwise identical
|
|
10
|
+
* types, such as `number` or `string`, to enforce stricter type checks. For
|
|
11
|
+
* example, instead of a plain `number`, use `PositiveInt`. Instead of a plain
|
|
12
|
+
* `string`, use `TrimmedString`.
|
|
6
13
|
*
|
|
7
|
-
*
|
|
14
|
+
* Avoid primitive types in domain code—brand everything. Evolu Type provides
|
|
15
|
+
* many brand helpers.
|
|
8
16
|
*
|
|
9
|
-
* ###
|
|
17
|
+
* ### Single Brand
|
|
10
18
|
*
|
|
11
19
|
* ```ts
|
|
12
20
|
* // A branded type definition
|
|
@@ -25,12 +33,12 @@
|
|
|
25
33
|
* // Implementation
|
|
26
34
|
* };
|
|
27
35
|
*
|
|
28
|
-
* getUser(userId); //
|
|
29
|
-
* getUser(123); //
|
|
30
|
-
* getUser("123"); //
|
|
36
|
+
* getUser(userId); // Valid
|
|
37
|
+
* getUser(123); // TypeScript error
|
|
38
|
+
* getUser("123"); // TypeScript error
|
|
31
39
|
* ```
|
|
32
40
|
*
|
|
33
|
-
* ###
|
|
41
|
+
* ### Multiple Brands (to act like flags)
|
|
34
42
|
*
|
|
35
43
|
* ```ts
|
|
36
44
|
* // Define branded types
|
|
@@ -50,10 +58,30 @@
|
|
|
50
58
|
* const min1Max100Value: Min1Max100 = "typescript" as Min1Max100;
|
|
51
59
|
*
|
|
52
60
|
* // Valid cases
|
|
53
|
-
* requiresMin1(min1Value); //
|
|
54
|
-
* requiresMax100(max100Value); //
|
|
55
|
-
* requiresMin1(min1Max100Value); //
|
|
56
|
-
* requiresMax100(min1Max100Value); //
|
|
61
|
+
* requiresMin1(min1Value); // Valid
|
|
62
|
+
* requiresMax100(max100Value); // Valid
|
|
63
|
+
* requiresMin1(min1Max100Value); // Valid: Min1Max100 satisfies Min1
|
|
64
|
+
* requiresMax100(min1Max100Value); // Valid: Min1Max100 satisfies Max100
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* ### Standalone Brand
|
|
68
|
+
*
|
|
69
|
+
* Brand can be used alone without a base type for purely nominal typing. This
|
|
70
|
+
* is useful for opaque values where the internal structure is hidden and type
|
|
71
|
+
* identity is based on name only. For example, platform-specific handles can be
|
|
72
|
+
* branded to prevent accidental mixing of implementations while keeping common
|
|
73
|
+
* code platform-agnostic.
|
|
74
|
+
*
|
|
75
|
+
* ```ts
|
|
76
|
+
* // A nominal type with no underlying structure exposed
|
|
77
|
+
* type NativePort = Brand<"NativePort">;
|
|
78
|
+
*
|
|
79
|
+
* // Only values explicitly cast to NativePort are accepted
|
|
80
|
+
* const requiresNativePort = (port: NativePort): void => {};
|
|
81
|
+
*
|
|
82
|
+
* const port: NativePort = nativeValue as NativePort;
|
|
83
|
+
* requiresNativePort(port); // Valid
|
|
84
|
+
* requiresNativePort(nativeValue); // TypeScript error
|
|
57
85
|
* ```
|
|
58
86
|
*/
|
|
59
87
|
export interface Brand<B extends string> {
|
package/dist/src/Brand.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Brand.d.ts","sourceRoot":"","sources":["../../src/Brand.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"Brand.d.ts","sourceRoot":"","sources":["../../src/Brand.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AACH,MAAM,WAAW,KAAK,CAAC,CAAC,SAAS,MAAM;IACrC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;CAC/C;AAED,OAAO,CAAC,MAAM,OAAO,EAAE,OAAO,MAAM,CAAC;AAErC;;;;;;;;;GASG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC"}
|