@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/src/Array.ts
CHANGED
|
@@ -16,13 +16,16 @@
|
|
|
16
16
|
* to track:
|
|
17
17
|
*
|
|
18
18
|
* ```ts
|
|
19
|
-
*
|
|
19
|
+
* import { assertEqual, assertSame } from "@evolu/common";
|
|
20
|
+
*
|
|
21
|
+
* // oxlint-disable-next-line unicorn/no-array-sort -- This example intentionally demonstrates mutating Array.sort.
|
|
22
|
+
* const sortScores = (arr: Array<number>) => arr.sort((a, b) => a - b);
|
|
20
23
|
*
|
|
21
24
|
* const scores = [3, 1, 2];
|
|
22
25
|
* const leaderboard = sortScores(scores);
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
+
* assertEqual(leaderboard, [1, 2, 3]);
|
|
27
|
+
* assertEqual(scores, [1, 2, 3]);
|
|
28
|
+
* assertSame(leaderboard, scores);
|
|
26
29
|
* ```
|
|
27
30
|
*
|
|
28
31
|
* Imagine every method doing that.
|
|
@@ -31,30 +34,35 @@
|
|
|
31
34
|
* instead:
|
|
32
35
|
*
|
|
33
36
|
* ```ts
|
|
34
|
-
* import { sortArray } from "@evolu/common";
|
|
37
|
+
* import { assertEqual, assertTrue, sortArray } from "@evolu/common";
|
|
35
38
|
*
|
|
36
39
|
* const sortScores = (arr: ReadonlyArray<number>) =>
|
|
37
40
|
* sortArray(arr, (a, b) => a - b);
|
|
38
41
|
*
|
|
39
42
|
* const scores: ReadonlyArray<number> = [3, 1, 2];
|
|
40
43
|
* const leaderboard = sortScores(scores);
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
+
* assertEqual(leaderboard, [1, 2, 3]);
|
|
45
|
+
* assertEqual(scores, [3, 1, 2]);
|
|
46
|
+
* assertTrue(leaderboard !== scores);
|
|
44
47
|
* ```
|
|
45
48
|
*
|
|
46
49
|
* Even better, require a {@link NonEmptyReadonlyArray} — there's nothing to sort
|
|
47
50
|
* if the array is empty anyway:
|
|
48
51
|
*
|
|
49
52
|
* ```ts
|
|
50
|
-
* import {
|
|
53
|
+
* import {
|
|
54
|
+
* assertEqual,
|
|
55
|
+
* assertType,
|
|
56
|
+
* sortArray,
|
|
57
|
+
* type NonEmptyReadonlyArray,
|
|
58
|
+
* } from "@evolu/common";
|
|
51
59
|
*
|
|
52
60
|
* const sortScores = (arr: NonEmptyReadonlyArray<number>) =>
|
|
53
61
|
* sortArray(arr, (a, b) => a - b);
|
|
54
62
|
*
|
|
55
63
|
* const leaderboard = sortScores([3, 1, 2]);
|
|
56
|
-
*
|
|
57
|
-
*
|
|
64
|
+
* assertEqual(leaderboard, [1, 2, 3]);
|
|
65
|
+
* assertType<NonEmptyReadonlyArray<number>, typeof leaderboard>();
|
|
58
66
|
* ```
|
|
59
67
|
*
|
|
60
68
|
* Sorting an empty array isn't expensive, but functions can have side effects
|
|
@@ -68,13 +76,16 @@
|
|
|
68
76
|
* readonly arrays without mutation — use them directly.
|
|
69
77
|
*
|
|
70
78
|
* ```ts
|
|
71
|
-
* import { type NonEmptyReadonlyArray } from "@evolu/common";
|
|
79
|
+
* import { assertEqual, type NonEmptyReadonlyArray } from "@evolu/common";
|
|
72
80
|
*
|
|
73
81
|
* const valid: NonEmptyReadonlyArray<number> = [1, 2, 3];
|
|
74
82
|
* // @ts-expect-error An empty array is not non-empty.
|
|
75
|
-
* const
|
|
83
|
+
* const _invalid: NonEmptyReadonlyArray<number> = [];
|
|
76
84
|
*
|
|
77
|
-
*
|
|
85
|
+
* assertEqual(
|
|
86
|
+
* valid.find((value) => value === 2),
|
|
87
|
+
* 2,
|
|
88
|
+
* );
|
|
78
89
|
* ```
|
|
79
90
|
*
|
|
80
91
|
* ## Composition
|
|
@@ -83,7 +94,7 @@
|
|
|
83
94
|
* because it's natural for single operations:
|
|
84
95
|
*
|
|
85
96
|
* ```ts
|
|
86
|
-
* import { mapArray } from "@evolu/common";
|
|
97
|
+
* import { assertEqual, mapArray } from "@evolu/common";
|
|
87
98
|
*
|
|
88
99
|
* interface Message {
|
|
89
100
|
* readonly timestamp: number;
|
|
@@ -94,7 +105,7 @@
|
|
|
94
105
|
* { timestamp: 20 },
|
|
95
106
|
* ];
|
|
96
107
|
* const timestamps = mapArray(messages, (m) => m.timestamp);
|
|
97
|
-
*
|
|
108
|
+
* assertEqual(timestamps, [10, 20]);
|
|
98
109
|
* ```
|
|
99
110
|
*
|
|
100
111
|
* Data-first style also reads well for a few operations, often fitting on a
|
|
@@ -102,6 +113,7 @@
|
|
|
102
113
|
*
|
|
103
114
|
* ```ts
|
|
104
115
|
* import {
|
|
116
|
+
* assertEqual,
|
|
105
117
|
* dedupeArray,
|
|
106
118
|
* filterArray,
|
|
107
119
|
* firstInArray,
|
|
@@ -113,11 +125,11 @@
|
|
|
113
125
|
* } from "@evolu/common";
|
|
114
126
|
*
|
|
115
127
|
* const cheapest = firstInArray(sortArray([30, 10, 20], orderNumber));
|
|
116
|
-
*
|
|
128
|
+
* assertEqual(cheapest, 10);
|
|
117
129
|
*
|
|
118
130
|
* const users = [{ name: "Ada" }, { name: "Linus" }, { name: "Ada" }];
|
|
119
131
|
* const uniqueNames = dedupeArray(mapArray(users, (u) => u.name));
|
|
120
|
-
*
|
|
132
|
+
* assertEqual(uniqueNames, ["Ada", "Linus"]);
|
|
121
133
|
*
|
|
122
134
|
* const jobs = [
|
|
123
135
|
* { id: 1, done: false },
|
|
@@ -127,7 +139,7 @@
|
|
|
127
139
|
* if (!isNonEmptyArray(completedJobs)) throw new Error("Expected a job");
|
|
128
140
|
* const latestDone = lastInArray(completedJobs);
|
|
129
141
|
*
|
|
130
|
-
*
|
|
142
|
+
* assertEqual(latestDone, { id: 2, done: true });
|
|
131
143
|
* ```
|
|
132
144
|
*
|
|
133
145
|
* For more operations, create a function like `getOldestActiveUser` or a
|
|
@@ -175,6 +187,37 @@ export type AtLeastTwoReadonlyArray<T> = readonly [T, T, ...ReadonlyArray<T>];
|
|
|
175
187
|
*/
|
|
176
188
|
export const emptyArray: ReadonlyArray<never> = [];
|
|
177
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Creates a mutable sparse Array with the specified length.
|
|
192
|
+
*
|
|
193
|
+
* Use it to build an Array with indexed writes when its final length is known.
|
|
194
|
+
* Assign every index before exposing the completed Array as readonly.
|
|
195
|
+
*
|
|
196
|
+
* ### Example
|
|
197
|
+
*
|
|
198
|
+
* ```ts
|
|
199
|
+
* import {
|
|
200
|
+
* assertEqual,
|
|
201
|
+
* assertType,
|
|
202
|
+
* createMutableArray,
|
|
203
|
+
* } from "@evolu/common";
|
|
204
|
+
*
|
|
205
|
+
* const values = createMutableArray<number>(3);
|
|
206
|
+
*
|
|
207
|
+
* for (let index = 0; index < values.length; index++) {
|
|
208
|
+
* values[index] = index * 10;
|
|
209
|
+
* }
|
|
210
|
+
*
|
|
211
|
+
* assertEqual(values, [0, 10, 20]);
|
|
212
|
+
* assertType<Array<number>, typeof values>();
|
|
213
|
+
* ```
|
|
214
|
+
*
|
|
215
|
+
* @group Constructors
|
|
216
|
+
*/
|
|
217
|
+
export const createMutableArray = <T>(length: number): Array<T> =>
|
|
218
|
+
// oxlint-disable-next-line unicorn/no-new-array -- Intentionally preallocates a sparse mutable Array.
|
|
219
|
+
new Array<T>(length);
|
|
220
|
+
|
|
178
221
|
/**
|
|
179
222
|
* Better `Array.from`.
|
|
180
223
|
*
|
|
@@ -186,16 +229,24 @@ export const emptyArray: ReadonlyArray<never> = [];
|
|
|
186
229
|
* ### Creating from iterables and lengths
|
|
187
230
|
*
|
|
188
231
|
* ```ts
|
|
189
|
-
* import {
|
|
232
|
+
* import {
|
|
233
|
+
* assertEqual,
|
|
234
|
+
* assertSame,
|
|
235
|
+
* assertType,
|
|
236
|
+
* arrayFrom,
|
|
237
|
+
* } from "@evolu/common";
|
|
190
238
|
*
|
|
191
239
|
* const fromSet = arrayFrom(new Set([1, 2, 3]));
|
|
192
|
-
*
|
|
193
|
-
*
|
|
240
|
+
* assertEqual(fromSet, [1, 2, 3]);
|
|
241
|
+
* assertType<ReadonlyArray<number>, typeof fromSet>();
|
|
194
242
|
*
|
|
195
|
-
*
|
|
243
|
+
* assertEqual(
|
|
244
|
+
* arrayFrom(3, (i) => i * 10),
|
|
245
|
+
* [0, 10, 20],
|
|
246
|
+
* );
|
|
196
247
|
*
|
|
197
248
|
* const existing: ReadonlyArray<number> = [1, 2, 3];
|
|
198
|
-
*
|
|
249
|
+
* assertSame(arrayFrom(existing), existing);
|
|
199
250
|
* ```
|
|
200
251
|
*
|
|
201
252
|
* Unlike `Array.from`, there's no map parameter for iterables — use
|
|
@@ -234,19 +285,24 @@ export function arrayFrom<T>(
|
|
|
234
285
|
* ### Awaiting sync and async iterables
|
|
235
286
|
*
|
|
236
287
|
* ```ts
|
|
237
|
-
* import { arrayFromAsync } from "@evolu/common";
|
|
288
|
+
* import { assertEqual, assertType, arrayFromAsync } from "@evolu/common";
|
|
238
289
|
*
|
|
239
|
-
* const fromIterable = await arrayFromAsync(
|
|
240
|
-
*
|
|
290
|
+
* const fromIterable = await arrayFromAsync([
|
|
291
|
+
* Promise.resolve(1),
|
|
292
|
+
* Promise.resolve(2),
|
|
293
|
+
* Promise.resolve(3),
|
|
294
|
+
* ]);
|
|
295
|
+
* assertEqual(fromIterable, [1, 2, 3]);
|
|
241
296
|
*
|
|
242
297
|
* const fromAsyncIterable = await arrayFromAsync(
|
|
243
|
-
* (async function* () {
|
|
244
|
-
*
|
|
245
|
-
* yield
|
|
298
|
+
* (async function* (): AsyncGenerator<number> {
|
|
299
|
+
* await Promise.resolve();
|
|
300
|
+
* yield 1;
|
|
301
|
+
* yield 2;
|
|
246
302
|
* })(),
|
|
247
303
|
* );
|
|
248
|
-
*
|
|
249
|
-
*
|
|
304
|
+
* assertEqual(fromAsyncIterable, [1, 2]);
|
|
305
|
+
* assertType<ReadonlyArray<number>, typeof fromAsyncIterable>();
|
|
250
306
|
* ```
|
|
251
307
|
*
|
|
252
308
|
* Unlike `Array.fromAsync`, there's no map parameter — map the result with
|
|
@@ -272,6 +328,8 @@ export const arrayFromAsync = async <T>(
|
|
|
272
328
|
*
|
|
273
329
|
* ```ts
|
|
274
330
|
* import {
|
|
331
|
+
* assertEqual,
|
|
332
|
+
* assertType,
|
|
275
333
|
* firstInArray,
|
|
276
334
|
* isNonEmptyArray,
|
|
277
335
|
* type NonEmptyArray,
|
|
@@ -284,9 +342,9 @@ export const arrayFromAsync = async <T>(
|
|
|
284
342
|
* throw new Error("Expected values");
|
|
285
343
|
* }
|
|
286
344
|
*
|
|
287
|
-
*
|
|
288
|
-
*
|
|
289
|
-
*
|
|
345
|
+
* assertType<NonEmptyArray<number>, typeof mutable>();
|
|
346
|
+
* assertType<NonEmptyReadonlyArray<number>, typeof readonly>();
|
|
347
|
+
* assertEqual(firstInArray(readonly), 1);
|
|
290
348
|
* ```
|
|
291
349
|
*
|
|
292
350
|
* @group Types
|
|
@@ -309,13 +367,15 @@ export function isNonEmptyArray<T>(
|
|
|
309
367
|
*
|
|
310
368
|
* ```ts
|
|
311
369
|
* import {
|
|
370
|
+
* assertEqual,
|
|
371
|
+
* assertType,
|
|
312
372
|
* appendToArray,
|
|
313
373
|
* type NonEmptyReadonlyArray,
|
|
314
374
|
* } from "@evolu/common";
|
|
315
375
|
*
|
|
316
376
|
* const values = appendToArray([1, 2, 3], 4);
|
|
317
|
-
*
|
|
318
|
-
*
|
|
377
|
+
* assertEqual(values, [1, 2, 3, 4]);
|
|
378
|
+
* assertType<NonEmptyReadonlyArray<number>, typeof values>();
|
|
319
379
|
* ```
|
|
320
380
|
*
|
|
321
381
|
* @group Transformations
|
|
@@ -335,13 +395,15 @@ export const appendToArray = <T>(
|
|
|
335
395
|
*
|
|
336
396
|
* ```ts
|
|
337
397
|
* import {
|
|
398
|
+
* assertEqual,
|
|
399
|
+
* assertType,
|
|
338
400
|
* prependToArray,
|
|
339
401
|
* type NonEmptyReadonlyArray,
|
|
340
402
|
* } from "@evolu/common";
|
|
341
403
|
*
|
|
342
404
|
* const values = prependToArray([2, 3], 1);
|
|
343
|
-
*
|
|
344
|
-
*
|
|
405
|
+
* assertEqual(values, [1, 2, 3]);
|
|
406
|
+
* assertType<NonEmptyReadonlyArray<number>, typeof values>();
|
|
345
407
|
* ```
|
|
346
408
|
*
|
|
347
409
|
* @group Transformations
|
|
@@ -359,17 +421,21 @@ export const prependToArray = <T>(
|
|
|
359
421
|
* ### Mapping with indexes while preserving non-emptiness
|
|
360
422
|
*
|
|
361
423
|
* ```ts
|
|
362
|
-
* import {
|
|
424
|
+
* import {
|
|
425
|
+
* assertEqual,
|
|
426
|
+
* assertType,
|
|
427
|
+
* mapArray,
|
|
428
|
+
* type NonEmptyReadonlyArray,
|
|
429
|
+
* } from "@evolu/common";
|
|
363
430
|
*
|
|
364
431
|
* const values: ReadonlyArray<number> = [1, 2, 3];
|
|
365
432
|
* const indexed = mapArray(values, (value, index) => value + index);
|
|
366
|
-
*
|
|
367
|
-
*
|
|
433
|
+
* assertEqual(indexed, [1, 3, 5]);
|
|
434
|
+
* assertType<ReadonlyArray<number>, typeof indexed>();
|
|
368
435
|
*
|
|
369
436
|
* const nonEmpty: NonEmptyReadonlyArray<number> = [1, 2, 3];
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
* >();
|
|
437
|
+
* const doubled = mapArray(nonEmpty, (x) => x * 2);
|
|
438
|
+
* assertType<NonEmptyReadonlyArray<number>, typeof doubled>();
|
|
373
439
|
* ```
|
|
374
440
|
*
|
|
375
441
|
* The mapper receives `(item, index, array)`, matching native `Array.map`.
|
|
@@ -402,7 +468,12 @@ export function mapArray<T, U>(
|
|
|
402
468
|
* ### Flattening and expanding values
|
|
403
469
|
*
|
|
404
470
|
* ```ts
|
|
405
|
-
* import {
|
|
471
|
+
* import {
|
|
472
|
+
* assertEqual,
|
|
473
|
+
* assertType,
|
|
474
|
+
* flatMapArray,
|
|
475
|
+
* type NonEmptyReadonlyArray,
|
|
476
|
+
* } from "@evolu/common";
|
|
406
477
|
*
|
|
407
478
|
* const flattened = flatMapArray([
|
|
408
479
|
* [1, 2],
|
|
@@ -413,9 +484,9 @@ export function mapArray<T, U>(
|
|
|
413
484
|
* values,
|
|
414
485
|
* (value, index): NonEmptyReadonlyArray<number> => [value, index],
|
|
415
486
|
* );
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
487
|
+
* assertEqual(flattened, [1, 2, 3, 4]);
|
|
488
|
+
* assertType<NonEmptyReadonlyArray<number>, typeof expanded>();
|
|
489
|
+
* assertEqual(expanded, [1, 0, 2, 1, 3, 2]);
|
|
419
490
|
* ```
|
|
420
491
|
*
|
|
421
492
|
* ### Filter and map in one pass
|
|
@@ -423,7 +494,7 @@ export function mapArray<T, U>(
|
|
|
423
494
|
* Return `[]` to filter out, `[value]` to keep:
|
|
424
495
|
*
|
|
425
496
|
* ```ts
|
|
426
|
-
* import { err, flatMapArray, ok } from "@evolu/common";
|
|
497
|
+
* import { assertEqual, err, flatMapArray, ok } from "@evolu/common";
|
|
427
498
|
*
|
|
428
499
|
* const validate = (value: number) =>
|
|
429
500
|
* value > 0 ? ok(value) : err(`${value} is not positive`);
|
|
@@ -432,7 +503,7 @@ export function mapArray<T, U>(
|
|
|
432
503
|
* const result = validate(f);
|
|
433
504
|
* return result.ok ? [] : [result.error];
|
|
434
505
|
* });
|
|
435
|
-
*
|
|
506
|
+
* assertEqual(errors, ["-2 is not positive", "-4 is not positive"]);
|
|
436
507
|
* ```
|
|
437
508
|
*
|
|
438
509
|
* The mapper receives `(item, index, array)`, matching native `Array.flatMap`.
|
|
@@ -483,16 +554,21 @@ export function flatMapArray<T, U>(
|
|
|
483
554
|
* ### Concatenating non-empty inputs
|
|
484
555
|
*
|
|
485
556
|
* ```ts
|
|
486
|
-
* import {
|
|
557
|
+
* import {
|
|
558
|
+
* assertEqual,
|
|
559
|
+
* assertType,
|
|
560
|
+
* concatArrays,
|
|
561
|
+
* type NonEmptyReadonlyArray,
|
|
562
|
+
* } from "@evolu/common";
|
|
487
563
|
*
|
|
488
564
|
* const nonEmpty: NonEmptyReadonlyArray<number> = [1];
|
|
489
565
|
* const joined = concatArrays([1, 2], [3, 4]);
|
|
490
566
|
* const fromLeft = concatArrays(nonEmpty, []);
|
|
491
567
|
* const fromRight = concatArrays([], nonEmpty);
|
|
492
568
|
*
|
|
493
|
-
*
|
|
494
|
-
*
|
|
495
|
-
*
|
|
569
|
+
* assertEqual(joined, [1, 2, 3, 4]);
|
|
570
|
+
* assertType<NonEmptyReadonlyArray<number>, typeof fromLeft>();
|
|
571
|
+
* assertType<NonEmptyReadonlyArray<number>, typeof fromRight>();
|
|
496
572
|
* ```
|
|
497
573
|
*
|
|
498
574
|
* @group Transformations
|
|
@@ -529,16 +605,18 @@ export function concatArrays<T>(
|
|
|
529
605
|
* ### With predicate
|
|
530
606
|
*
|
|
531
607
|
* ```ts
|
|
532
|
-
* import { filterArray } from "@evolu/common";
|
|
608
|
+
* import { assertEqual, filterArray } from "@evolu/common";
|
|
533
609
|
*
|
|
534
610
|
* const evens = filterArray([1, 2, 3, 4, 5], (x) => x % 2 === 0);
|
|
535
|
-
*
|
|
611
|
+
* assertEqual(evens, [2, 4]);
|
|
536
612
|
* ```
|
|
537
613
|
*
|
|
538
614
|
* ### With refinement
|
|
539
615
|
*
|
|
540
616
|
* ```ts
|
|
541
617
|
* import {
|
|
618
|
+
* assertEqual,
|
|
619
|
+
* assertType,
|
|
542
620
|
* filterArray,
|
|
543
621
|
* NonEmptyTrimmedString,
|
|
544
622
|
* PositiveInt,
|
|
@@ -549,8 +627,8 @@ export function concatArrays<T>(
|
|
|
549
627
|
* PositiveInt.orThrow(42),
|
|
550
628
|
* ];
|
|
551
629
|
* const positiveInts = filterArray(mixed, PositiveInt.is);
|
|
552
|
-
*
|
|
553
|
-
*
|
|
630
|
+
* assertEqual(positiveInts, [42]);
|
|
631
|
+
* assertType<ReadonlyArray<PositiveInt>, typeof positiveInts>();
|
|
554
632
|
* ```
|
|
555
633
|
*
|
|
556
634
|
* The predicate receives `(item, index, array)`, matching native
|
|
@@ -584,7 +662,12 @@ export function filterArray<T>(
|
|
|
584
662
|
* ### Deduplicating by value or key
|
|
585
663
|
*
|
|
586
664
|
* ```ts
|
|
587
|
-
* import {
|
|
665
|
+
* import {
|
|
666
|
+
* assertEqual,
|
|
667
|
+
* assertType,
|
|
668
|
+
* dedupeArray,
|
|
669
|
+
* type NonEmptyReadonlyArray,
|
|
670
|
+
* } from "@evolu/common";
|
|
588
671
|
*
|
|
589
672
|
* const numbers = dedupeArray([1, 2, 1, 3, 2]);
|
|
590
673
|
* const people = dedupeArray(
|
|
@@ -595,9 +678,9 @@ export function filterArray<T>(
|
|
|
595
678
|
* ],
|
|
596
679
|
* (item) => item.id,
|
|
597
680
|
* );
|
|
598
|
-
*
|
|
599
|
-
*
|
|
600
|
-
*
|
|
681
|
+
* assertType<NonEmptyReadonlyArray<number>, typeof numbers>();
|
|
682
|
+
* assertEqual(numbers, [1, 2, 3]);
|
|
683
|
+
* assertEqual(people, [
|
|
601
684
|
* { id: 1, name: "Alice" },
|
|
602
685
|
* { id: 2, name: "Bob" },
|
|
603
686
|
* ]);
|
|
@@ -645,20 +728,22 @@ export function dedupeArray<T>(
|
|
|
645
728
|
* ### With predicate
|
|
646
729
|
*
|
|
647
730
|
* ```ts
|
|
648
|
-
* import { partitionArray } from "@evolu/common";
|
|
731
|
+
* import { assertEqual, partitionArray } from "@evolu/common";
|
|
649
732
|
*
|
|
650
733
|
* const [evens, odds] = partitionArray(
|
|
651
734
|
* [1, 2, 3, 4, 5],
|
|
652
735
|
* (x) => x % 2 === 0,
|
|
653
736
|
* );
|
|
654
|
-
*
|
|
655
|
-
*
|
|
737
|
+
* assertEqual(evens, [2, 4]);
|
|
738
|
+
* assertEqual(odds, [1, 3, 5]);
|
|
656
739
|
* ```
|
|
657
740
|
*
|
|
658
741
|
* ### With refinement
|
|
659
742
|
*
|
|
660
743
|
* ```ts
|
|
661
744
|
* import {
|
|
745
|
+
* assertEqual,
|
|
746
|
+
* assertType,
|
|
662
747
|
* NonEmptyTrimmedString,
|
|
663
748
|
* partitionArray,
|
|
664
749
|
* PositiveInt,
|
|
@@ -669,11 +754,9 @@ export function dedupeArray<T>(
|
|
|
669
754
|
* PositiveInt.orThrow(42),
|
|
670
755
|
* ];
|
|
671
756
|
* const [positiveInts, strings] = partitionArray(mixed, PositiveInt.is);
|
|
672
|
-
*
|
|
673
|
-
*
|
|
674
|
-
*
|
|
675
|
-
* ReadonlyArray<NonEmptyTrimmedString>
|
|
676
|
-
* >();
|
|
757
|
+
* assertEqual(positiveInts, [42]);
|
|
758
|
+
* assertType<ReadonlyArray<PositiveInt>, typeof positiveInts>();
|
|
759
|
+
* assertType<ReadonlyArray<NonEmptyTrimmedString>, typeof strings>();
|
|
677
760
|
* ```
|
|
678
761
|
*
|
|
679
762
|
* The predicate receives `(item, index, array)`.
|
|
@@ -715,12 +798,17 @@ export function partitionArray<T>(
|
|
|
715
798
|
* ### Sorting without mutation
|
|
716
799
|
*
|
|
717
800
|
* ```ts
|
|
718
|
-
* import {
|
|
801
|
+
* import {
|
|
802
|
+
* assertEqual,
|
|
803
|
+
* assertType,
|
|
804
|
+
* sortArray,
|
|
805
|
+
* type NonEmptyReadonlyArray,
|
|
806
|
+
* } from "@evolu/common";
|
|
719
807
|
*
|
|
720
808
|
* const values: NonEmptyReadonlyArray<number> = [3, 1, 2];
|
|
721
809
|
* const sorted = sortArray(values, (a, b) => a - b);
|
|
722
|
-
*
|
|
723
|
-
*
|
|
810
|
+
* assertEqual(sorted, [1, 2, 3]);
|
|
811
|
+
* assertType<NonEmptyReadonlyArray<number>, typeof sorted>();
|
|
724
812
|
* ```
|
|
725
813
|
*
|
|
726
814
|
* @group Transformations
|
|
@@ -749,12 +837,17 @@ export function sortArray<T>(
|
|
|
749
837
|
* ### Reversing without mutation
|
|
750
838
|
*
|
|
751
839
|
* ```ts
|
|
752
|
-
* import {
|
|
840
|
+
* import {
|
|
841
|
+
* assertEqual,
|
|
842
|
+
* assertType,
|
|
843
|
+
* reverseArray,
|
|
844
|
+
* type NonEmptyReadonlyArray,
|
|
845
|
+
* } from "@evolu/common";
|
|
753
846
|
*
|
|
754
847
|
* const values: NonEmptyReadonlyArray<number> = [1, 2, 3];
|
|
755
848
|
* const reversed = reverseArray(values);
|
|
756
|
-
*
|
|
757
|
-
*
|
|
849
|
+
* assertEqual(reversed, [3, 2, 1]);
|
|
850
|
+
* assertType<NonEmptyReadonlyArray<number>, typeof reversed>();
|
|
758
851
|
* ```
|
|
759
852
|
*
|
|
760
853
|
* @group Transformations
|
|
@@ -776,12 +869,12 @@ export function reverseArray<T>(array: ReadonlyArray<T>): ReadonlyArray<T> {
|
|
|
776
869
|
* ### Removing and replacing values
|
|
777
870
|
*
|
|
778
871
|
* ```ts
|
|
779
|
-
* import { spliceArray } from "@evolu/common";
|
|
872
|
+
* import { assertEqual, spliceArray } from "@evolu/common";
|
|
780
873
|
*
|
|
781
874
|
* const values: ReadonlyArray<number> = [1, 2, 3, 4];
|
|
782
|
-
*
|
|
783
|
-
*
|
|
784
|
-
*
|
|
875
|
+
* assertEqual(spliceArray(values, 1, 2), [1, 4]);
|
|
876
|
+
* assertEqual(spliceArray([1, 2, 3], 1, 1, 10, 11), [1, 10, 11, 3]);
|
|
877
|
+
* assertEqual(values, [1, 2, 3, 4]);
|
|
785
878
|
* ```
|
|
786
879
|
*
|
|
787
880
|
* @group Transformations
|
|
@@ -813,29 +906,36 @@ export type ZipArrayResult<T extends ReadonlyArray<ReadonlyArray<unknown>>> = {
|
|
|
813
906
|
* ### Zipping to the shortest input
|
|
814
907
|
*
|
|
815
908
|
* ```ts
|
|
816
|
-
* import {
|
|
909
|
+
* import {
|
|
910
|
+
* assertEqual,
|
|
911
|
+
* assertType,
|
|
912
|
+
* zipArray,
|
|
913
|
+
* type NonEmptyReadonlyArray,
|
|
914
|
+
* } from "@evolu/common";
|
|
817
915
|
*
|
|
818
916
|
* const pairs = zipArray([
|
|
819
917
|
* [1, 2, 3],
|
|
820
918
|
* ["a", "b", "c"],
|
|
821
919
|
* ]);
|
|
822
|
-
*
|
|
920
|
+
* assertEqual(pairs, [
|
|
823
921
|
* [1, "a"],
|
|
824
922
|
* [2, "b"],
|
|
825
923
|
* [3, "c"],
|
|
826
924
|
* ]);
|
|
827
|
-
*
|
|
925
|
+
* assertEqual(
|
|
828
926
|
* zipArray([
|
|
829
927
|
* [1, 2],
|
|
830
928
|
* ["a", "b", "c"],
|
|
831
929
|
* [true, false],
|
|
832
930
|
* ]),
|
|
833
|
-
*
|
|
834
|
-
*
|
|
835
|
-
*
|
|
836
|
-
*
|
|
837
|
-
*
|
|
838
|
-
*
|
|
931
|
+
* [
|
|
932
|
+
* [1, "a", true],
|
|
933
|
+
* [2, "b", false],
|
|
934
|
+
* ],
|
|
935
|
+
* );
|
|
936
|
+
* assertType<
|
|
937
|
+
* NonEmptyReadonlyArray<Readonly<[number, string]>>,
|
|
938
|
+
* typeof pairs
|
|
839
939
|
* >();
|
|
840
940
|
* ```
|
|
841
941
|
*
|
|
@@ -854,7 +954,7 @@ export function zipArray<T extends ReadonlyArray<ReadonlyArray<unknown>>>(
|
|
|
854
954
|
if (arrays.length === 0) return emptyArray;
|
|
855
955
|
|
|
856
956
|
const minLength = Math.min(...mapArray(arrays, (a) => a.length));
|
|
857
|
-
const result =
|
|
957
|
+
const result = createMutableArray<unknown>(minLength);
|
|
858
958
|
|
|
859
959
|
for (let i = 0; i < minLength; i++) {
|
|
860
960
|
result[i] = mapArray(arrays, (a) => a[i]);
|
|
@@ -869,9 +969,9 @@ export function zipArray<T extends ReadonlyArray<ReadonlyArray<unknown>>>(
|
|
|
869
969
|
* ### Reading the first value
|
|
870
970
|
*
|
|
871
971
|
* ```ts
|
|
872
|
-
* import { firstInArray } from "@evolu/common";
|
|
972
|
+
* import { assertEqual, firstInArray } from "@evolu/common";
|
|
873
973
|
*
|
|
874
|
-
*
|
|
974
|
+
* assertEqual(firstInArray(["a", "b", "c"]), "a");
|
|
875
975
|
* ```
|
|
876
976
|
*
|
|
877
977
|
* @group Accessors
|
|
@@ -884,9 +984,9 @@ export const firstInArray = <T>(array: NonEmptyReadonlyArray<T>): T => array[0];
|
|
|
884
984
|
* ### Reading the last value
|
|
885
985
|
*
|
|
886
986
|
* ```ts
|
|
887
|
-
* import { lastInArray } from "@evolu/common";
|
|
987
|
+
* import { assertEqual, lastInArray } from "@evolu/common";
|
|
888
988
|
*
|
|
889
|
-
*
|
|
989
|
+
* assertEqual(lastInArray(["a", "b", "c"]), "c");
|
|
890
990
|
* ```
|
|
891
991
|
*
|
|
892
992
|
* @group Accessors
|