@evolu/common 6.0.1-preview.9 → 7.1.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 +27 -29
- package/dist/src/Array.d.ts +317 -12
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +219 -9
- package/dist/src/Assert.d.ts +0 -13
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +0 -15
- package/dist/src/Brand.d.ts +75 -0
- package/dist/src/Brand.d.ts.map +1 -0
- package/dist/src/Brand.js +1 -0
- package/dist/src/Buffer.d.ts +1 -1
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Buffer.js +8 -7
- package/dist/src/Cache.d.ts +39 -0
- package/dist/src/Cache.d.ts.map +1 -0
- package/dist/src/Cache.js +47 -0
- package/dist/src/Callbacks.d.ts +45 -12
- package/dist/src/Callbacks.d.ts.map +1 -1
- package/dist/src/Callbacks.js +14 -7
- package/dist/src/Console.d.ts +32 -7
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +73 -10
- package/dist/src/Crypto.d.ts +56 -42
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +45 -54
- package/dist/src/Evolu/Db.d.ts +162 -74
- package/dist/src/Evolu/Db.d.ts.map +1 -1
- package/dist/src/Evolu/Db.js +284 -702
- package/dist/src/Evolu/Diff.d.ts +3 -3
- package/dist/src/Evolu/Diff.d.ts.map +1 -1
- package/dist/src/Evolu/Diff.js +7 -5
- package/dist/src/Evolu/Evolu.d.ts +213 -133
- package/dist/src/Evolu/Evolu.d.ts.map +1 -1
- package/dist/src/Evolu/Evolu.js +189 -180
- package/dist/src/Evolu/Internal.d.ts +2 -4
- package/dist/src/Evolu/Internal.d.ts.map +1 -1
- package/dist/src/Evolu/Internal.js +2 -4
- package/dist/src/Evolu/LocalAuth.d.ts +150 -0
- package/dist/src/Evolu/LocalAuth.d.ts.map +1 -0
- package/dist/src/Evolu/LocalAuth.js +174 -0
- package/dist/src/Evolu/Owner.d.ts +273 -120
- package/dist/src/Evolu/Owner.d.ts.map +1 -1
- package/dist/src/Evolu/Owner.js +130 -104
- package/dist/src/Evolu/Platform.d.ts +9 -7
- package/dist/src/Evolu/Platform.d.ts.map +1 -1
- package/dist/src/Evolu/Protocol.d.ts +268 -240
- package/dist/src/Evolu/Protocol.d.ts.map +1 -1
- package/dist/src/Evolu/Protocol.js +595 -447
- package/dist/src/Evolu/Public.d.ts +7 -9
- package/dist/src/Evolu/Public.d.ts.map +1 -1
- package/dist/src/Evolu/Public.js +3 -4
- package/dist/src/Evolu/PublicKysely.d.ts.map +1 -1
- package/dist/src/Evolu/PublicKysely.js +3 -4
- package/dist/src/Evolu/Query.d.ts +2 -1
- package/dist/src/Evolu/Query.d.ts.map +1 -1
- package/dist/src/Evolu/Query.js +1 -1
- package/dist/src/Evolu/Relay.d.ts +91 -8
- package/dist/src/Evolu/Relay.d.ts.map +1 -1
- package/dist/src/Evolu/Relay.js +214 -88
- package/dist/src/Evolu/Schema.d.ts +125 -47
- package/dist/src/Evolu/Schema.d.ts.map +1 -1
- package/dist/src/Evolu/Schema.js +175 -31
- package/dist/src/Evolu/Storage.d.ts +249 -27
- package/dist/src/Evolu/Storage.d.ts.map +1 -1
- package/dist/src/Evolu/Storage.js +198 -92
- package/dist/src/Evolu/Sync.d.ts +68 -13
- package/dist/src/Evolu/Sync.d.ts.map +1 -1
- package/dist/src/Evolu/Sync.js +469 -20
- package/dist/src/Evolu/Timestamp.d.ts +83 -30
- package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
- package/dist/src/Evolu/Timestamp.js +79 -34
- package/dist/src/Identicon.d.ts +35 -0
- package/dist/src/Identicon.d.ts.map +1 -0
- package/dist/src/Identicon.js +143 -0
- package/dist/src/Instances.d.ts +34 -0
- package/dist/src/Instances.d.ts.map +1 -0
- package/dist/src/Instances.js +44 -0
- package/dist/src/Number.d.ts +4 -3
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Number.js +5 -4
- package/dist/src/Object.d.ts +10 -4
- package/dist/src/Object.d.ts.map +1 -1
- package/dist/src/Object.js +9 -3
- package/dist/src/Order.d.ts +0 -5
- package/dist/src/Order.d.ts.map +1 -1
- package/dist/src/Order.js +0 -5
- package/dist/src/Platform.d.ts +15 -0
- package/dist/src/Platform.d.ts.map +1 -0
- package/dist/src/Platform.js +17 -0
- package/dist/src/Random.d.ts +3 -7
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/Random.js +0 -5
- package/dist/src/Ref.d.ts.map +1 -1
- package/dist/src/Relation.d.ts +79 -0
- package/dist/src/Relation.d.ts.map +1 -0
- package/dist/src/Relation.js +127 -0
- package/dist/src/Resources.d.ts +118 -0
- package/dist/src/Resources.d.ts.map +1 -0
- package/dist/src/Resources.js +197 -0
- package/dist/src/Result.d.ts +189 -59
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +30 -241
- package/dist/src/Skiplist.js +2 -1
- package/dist/src/Sqlite.d.ts +89 -5
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +136 -9
- package/dist/src/Store.d.ts +0 -5
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Store.js +0 -5
- package/dist/src/Task.d.ts +580 -0
- package/dist/src/Task.d.ts.map +1 -0
- package/dist/src/Task.js +464 -0
- package/dist/src/Time.d.ts +66 -6
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +96 -7
- package/dist/src/Type.d.ts +677 -344
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +718 -467
- package/dist/src/Types.d.ts +38 -75
- package/dist/src/Types.d.ts.map +1 -1
- package/dist/src/WebSocket.d.ts +5 -7
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +12 -23
- package/dist/src/Worker.d.ts +39 -16
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +22 -9
- package/dist/src/index.d.ts +8 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +8 -3
- package/package.json +14 -13
- package/src/Array.ts +396 -19
- package/src/Assert.ts +0 -35
- package/src/Brand.ts +75 -0
- package/src/Buffer.ts +7 -7
- package/src/Cache.ts +79 -0
- package/src/Callbacks.ts +62 -22
- package/src/Console.ts +92 -12
- package/src/Crypto.ts +99 -91
- package/src/Evolu/Db.ts +519 -1026
- package/src/Evolu/Diff.ts +7 -5
- package/src/Evolu/Evolu.ts +476 -360
- package/src/Evolu/Internal.ts +2 -4
- package/src/Evolu/LocalAuth.ts +463 -0
- package/src/Evolu/Owner.ts +355 -228
- package/src/Evolu/Platform.ts +9 -9
- package/src/Evolu/Protocol.ts +846 -742
- package/src/Evolu/Public.ts +8 -15
- package/src/Evolu/PublicKysely.ts +4 -5
- package/src/Evolu/Query.ts +3 -2
- package/src/Evolu/Relay.ts +406 -103
- package/src/Evolu/Schema.ts +323 -91
- package/src/Evolu/Storage.ts +559 -137
- package/src/Evolu/Sync.ts +819 -36
- package/src/Evolu/Timestamp.ts +90 -58
- package/src/Identicon.ts +197 -0
- package/src/Instances.ts +90 -0
- package/src/Number.ts +6 -10
- package/src/Object.ts +13 -5
- package/src/Order.ts +0 -6
- package/src/Platform.ts +20 -0
- package/src/Random.ts +3 -8
- package/src/Ref.ts +0 -5
- package/src/Relation.ts +234 -0
- package/src/Resources.ts +367 -0
- package/src/Result.ts +196 -61
- package/src/Skiplist.ts +1 -1
- package/src/Sqlite.ts +152 -17
- package/src/Store.ts +0 -5
- package/src/Task.ts +894 -0
- package/src/Time.ts +179 -10
- package/src/Type.ts +1136 -731
- package/src/Types.ts +43 -77
- package/src/WebSocket.ts +27 -31
- package/src/Worker.ts +72 -29
- package/src/index.ts +8 -3
- package/dist/src/Evolu/Config.d.ts +0 -69
- package/dist/src/Evolu/Config.d.ts.map +0 -1
- package/dist/src/Evolu/Config.js +0 -9
- package/dist/src/Evolu/Kysely.d.ts +0 -6
- package/dist/src/Evolu/Kysely.d.ts.map +0 -1
- package/dist/src/Evolu/Kysely.js +0 -21
- package/dist/src/ManyToManyMap.d.ts +0 -26
- package/dist/src/ManyToManyMap.d.ts.map +0 -1
- package/dist/src/ManyToManyMap.js +0 -92
- package/dist/src/NanoId.d.ts +0 -27
- package/dist/src/NanoId.d.ts.map +0 -1
- package/dist/src/NanoId.js +0 -6
- package/dist/src/Promise.d.ts +0 -180
- package/dist/src/Promise.d.ts.map +0 -1
- package/dist/src/Promise.js +0 -176
- package/src/Evolu/Config.ts +0 -83
- package/src/Evolu/Kysely.ts +0 -38
- package/src/ManyToManyMap.ts +0 -140
- package/src/NanoId.ts +0 -39
- package/src/Promise.ts +0 -295
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Evolu
|
|
2
2
|
|
|
3
|
-
Evolu is TypeScript library and local-first
|
|
3
|
+
Evolu is a TypeScript library and local-first platform.
|
|
4
4
|
|
|
5
5
|
## Documentation
|
|
6
6
|
|
|
@@ -20,11 +20,11 @@ To chat with other community members, you can join the [Evolu Discord](https://d
|
|
|
20
20
|
|
|
21
21
|
We provide a free relay `free.evoluhq.com` for testing and personal usage.
|
|
22
22
|
|
|
23
|
-
The Evolu Relay source
|
|
23
|
+
The Evolu Relay source and Docker files are in the [/apps/relay](/apps/relay) directory.
|
|
24
24
|
|
|
25
25
|
Alternatively, a pre-built image `evoluhq/relay:latest` is hosted on [Docker Hub](https://hub.docker.com/r/evoluhq/relay).
|
|
26
26
|
|
|
27
|
-
For more information, reference the [Evolu Relay](https://www.evolu.dev/docs/
|
|
27
|
+
For more information, reference the [Evolu Relay](https://www.evolu.dev/docs/relay) documentation.
|
|
28
28
|
|
|
29
29
|
## Developing
|
|
30
30
|
|
|
@@ -36,39 +36,37 @@ Install dependencies:
|
|
|
36
36
|
pnpm install
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
Build
|
|
39
|
+
Build scripts
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
pnpm build
|
|
43
|
-
pnpm build
|
|
44
|
-
```
|
|
41
|
+
- `pnpm build` - Build packages
|
|
42
|
+
- `pnpm build:web` - Build web
|
|
43
|
+
- `pnpm examples:build` - Build all examples
|
|
45
44
|
|
|
46
|
-
Start dev
|
|
45
|
+
Start dev
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
# web
|
|
50
|
-
pnpm dev
|
|
47
|
+
> **Warning**: Run `pnpm build` before running dev. Packages must be built first.
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
pnpm ios
|
|
54
|
-
pnpm android
|
|
55
|
-
|
|
49
|
+
- `pnpm dev` - Dev server for web
|
|
50
|
+
- `pnpm ios` - Run iOS example (requires `pnpm dev` running)
|
|
51
|
+
- `pnpm android` - Run Android example (requires `pnpm dev` running)
|
|
52
|
+
- `pnpm examples:react-nextjs:dev` - Dev server for React Next.js example
|
|
53
|
+
- `pnpm examples:react-vite-pwa:dev` - Dev server for React Vite PWA example
|
|
54
|
+
- `pnpm examples:svelte-vite-pwa:dev` - Dev server for Svelte Vite PWA example
|
|
55
|
+
- `pnpm examples:vue-vite-pwa:dev` - Dev server for Vue Vite PWA example
|
|
56
56
|
|
|
57
|
-
Linting
|
|
57
|
+
Linting
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
pnpm lint
|
|
61
|
-
pnpm lint-monorepo
|
|
62
|
-
```
|
|
59
|
+
- `pnpm lint` - Lint code
|
|
60
|
+
- `pnpm lint-monorepo` - Lint monorepo structure
|
|
63
61
|
|
|
64
|
-
|
|
62
|
+
Testing
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
pnpm test
|
|
68
|
-
```
|
|
64
|
+
- `pnpm test` - Run tests
|
|
69
65
|
|
|
70
|
-
|
|
66
|
+
Release
|
|
71
67
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
- `pnpm changeset` - Describe changes for release log
|
|
69
|
+
|
|
70
|
+
Verify
|
|
71
|
+
|
|
72
|
+
- `pnpm verify` - Run all checks (build, lint, test) before commit
|
package/dist/src/Array.d.ts
CHANGED
|
@@ -1,17 +1,322 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Array types, type guards, operations, transformations, accessors, and
|
|
3
|
+
* mutations
|
|
4
|
+
*
|
|
5
|
+
* ### Example
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* // Types - compile-time guarantee of at least one element
|
|
9
|
+
* const _valid: NonEmptyReadonlyArray<number> = [1, 2, 3];
|
|
10
|
+
* // ts-expect-error - empty array is not a valid NonEmptyReadonlyArray
|
|
11
|
+
* const _invalid: NonEmptyReadonlyArray<number> = [];
|
|
12
|
+
*
|
|
13
|
+
* // Type guards
|
|
14
|
+
* const arr: ReadonlyArray<number> = [1, 2, 3];
|
|
15
|
+
* if (isNonEmptyReadonlyArray(arr)) {
|
|
16
|
+
* firstInArray(arr);
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* // Operations
|
|
20
|
+
* const appended = appendToArray([1, 2, 3], 4); // [1, 2, 3, 4]
|
|
21
|
+
* const prepended = prependToArray([2, 3], 1); // [1, 2, 3]
|
|
22
|
+
*
|
|
23
|
+
* // Transformations
|
|
24
|
+
* const readonly: ReadonlyArray<number> = [1, 2, 3];
|
|
25
|
+
* const mapped = mapArray(readonly, (x) => x * 2); // [2, 4, 6]
|
|
26
|
+
* const filtered = filterArray(readonly, (x) => x > 1); // [2, 3]
|
|
27
|
+
* const deduped = dedupeArray([1, 2, 1, 3, 2]); // [1, 2, 3]
|
|
28
|
+
* const [evens, odds] = partitionArray(
|
|
29
|
+
* [1, 2, 3, 4, 5],
|
|
30
|
+
* (x) => x % 2 === 0,
|
|
31
|
+
* ); // [[2, 4], [1, 3, 5]]
|
|
32
|
+
*
|
|
33
|
+
* // Accessors
|
|
34
|
+
* const first = firstInArray(["a", "b", "c"]); // "a"
|
|
35
|
+
* const last = lastInArray(["a", "b", "c"]); // "c"
|
|
36
|
+
*
|
|
37
|
+
* // Mutations
|
|
38
|
+
* const mutable: NonEmptyArray<number> = [1, 2, 3];
|
|
39
|
+
* shiftArray(mutable); // 1 (guaranteed to exist)
|
|
40
|
+
* mutable; // [2, 3]
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* Functions are intentionally data-first to be prepared for the upcoming
|
|
44
|
+
* JavaScript pipe operator.
|
|
45
|
+
*
|
|
46
|
+
* ```ts
|
|
47
|
+
* // Data-first is natural for single operations.
|
|
48
|
+
* const timestamps = mapArray(messages, (m) => m.timestamp);
|
|
49
|
+
*
|
|
50
|
+
* // But data-first can be hard to read for nested calls.
|
|
51
|
+
* const result = firstInArray(
|
|
52
|
+
* mapArray(dedupeArray(appendToArray(value, 2)), (x) => x * 2),
|
|
53
|
+
* );
|
|
54
|
+
*
|
|
55
|
+
* // With the upcoming pipe operator, it's clear.
|
|
56
|
+
* // const result = value
|
|
57
|
+
* // |> appendToArray(%, 2)
|
|
58
|
+
* // |> dedupeArray(%)
|
|
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);
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* ### Why data-first?
|
|
70
|
+
*
|
|
71
|
+
* Evolu optimizes for consistent code style. We can't have both data-first
|
|
72
|
+
* single operations and curried data-last helpers without sacrificing
|
|
73
|
+
* consistency. We chose data-first because:
|
|
74
|
+
*
|
|
75
|
+
* - It's natural for single operations (for example `mapArray(messages, (m) =>
|
|
76
|
+
* m.timestamp)`).
|
|
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.).
|
|
81
|
+
*
|
|
82
|
+
* @module
|
|
83
|
+
*/
|
|
84
|
+
import { PredicateWithIndex, RefinementWithIndex } from "./Types.js";
|
|
85
|
+
/**
|
|
86
|
+
* An array with at least one element.
|
|
87
|
+
*
|
|
88
|
+
* @category Types
|
|
89
|
+
*/
|
|
2
90
|
export type NonEmptyArray<T> = [T, ...Array<T>];
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
|
|
91
|
+
/**
|
|
92
|
+
* A readonly array with at least one element.
|
|
93
|
+
*
|
|
94
|
+
* @category Types
|
|
95
|
+
*/
|
|
6
96
|
export type NonEmptyReadonlyArray<T> = readonly [T, ...ReadonlyArray<T>];
|
|
7
|
-
/**
|
|
97
|
+
/**
|
|
98
|
+
* Checks if an array is non-empty and narrows its type to {@link NonEmptyArray}.
|
|
99
|
+
*
|
|
100
|
+
* Use `if (!isNonEmptyArray(arr))` for empty checks.
|
|
101
|
+
*
|
|
102
|
+
* ### Example
|
|
103
|
+
*
|
|
104
|
+
* ```ts
|
|
105
|
+
* const arr: Array<number> = [1, 2, 3];
|
|
106
|
+
* if (isNonEmptyArray(arr)) {
|
|
107
|
+
* firstInArray(arr); // arr is NonEmptyArray<number>
|
|
108
|
+
* }
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* @category Type Guards
|
|
112
|
+
*/
|
|
113
|
+
export declare const isNonEmptyArray: <T>(array: Array<T>) => array is NonEmptyArray<T>;
|
|
114
|
+
/**
|
|
115
|
+
* Checks if a readonly array is non-empty and narrows its type to
|
|
116
|
+
* {@link NonEmptyReadonlyArray}.
|
|
117
|
+
*
|
|
118
|
+
* Use `if (!isNonEmptyReadonlyArray(arr))` for empty checks.
|
|
119
|
+
*
|
|
120
|
+
* ### Example
|
|
121
|
+
*
|
|
122
|
+
* ```ts
|
|
123
|
+
* const arr: ReadonlyArray<number> = [1, 2, 3];
|
|
124
|
+
* if (isNonEmptyReadonlyArray(arr)) {
|
|
125
|
+
* firstInArray(arr); // arr is NonEmptyReadonlyArray<number>
|
|
126
|
+
* }
|
|
127
|
+
* ```
|
|
128
|
+
*
|
|
129
|
+
* @category Type Guards
|
|
130
|
+
*/
|
|
8
131
|
export declare const isNonEmptyReadonlyArray: <T>(array: ReadonlyArray<T>) => array is NonEmptyReadonlyArray<T>;
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
132
|
+
/**
|
|
133
|
+
* Appends an item to an array, returning a new non-empty readonly array.
|
|
134
|
+
*
|
|
135
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
136
|
+
*
|
|
137
|
+
* ### Example
|
|
138
|
+
*
|
|
139
|
+
* ```ts
|
|
140
|
+
* appendToArray([1, 2, 3], 4); // [1, 2, 3, 4]
|
|
141
|
+
* ```
|
|
142
|
+
*
|
|
143
|
+
* @category Operations
|
|
144
|
+
*/
|
|
145
|
+
export declare const appendToArray: <T>(array: ReadonlyArray<T>, item: T) => NonEmptyReadonlyArray<T>;
|
|
146
|
+
/**
|
|
147
|
+
* Prepends an item to an array, returning a new non-empty readonly array.
|
|
148
|
+
*
|
|
149
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
150
|
+
*
|
|
151
|
+
* ### Example
|
|
152
|
+
*
|
|
153
|
+
* ```ts
|
|
154
|
+
* prependToArray([2, 3], 1); // [1, 2, 3]
|
|
155
|
+
* ```
|
|
156
|
+
*
|
|
157
|
+
* @category Operations
|
|
158
|
+
*/
|
|
159
|
+
export declare const prependToArray: <T>(array: ReadonlyArray<T>, item: T) => NonEmptyReadonlyArray<T>;
|
|
160
|
+
/**
|
|
161
|
+
* Maps an array using a mapper function.
|
|
162
|
+
*
|
|
163
|
+
* Accepts both mutable and readonly arrays. Preserves non-empty type.
|
|
164
|
+
*
|
|
165
|
+
* ### Example
|
|
166
|
+
*
|
|
167
|
+
* ```ts
|
|
168
|
+
* mapArray([1, 2, 3], (x) => x * 2); // [2, 4, 6]
|
|
169
|
+
* ```
|
|
170
|
+
*
|
|
171
|
+
* @category Transformations
|
|
172
|
+
*/
|
|
173
|
+
export declare function mapArray<T, U>(array: NonEmptyReadonlyArray<T> | NonEmptyArray<T>, mapper: (item: T, index: number) => U): NonEmptyReadonlyArray<U>;
|
|
174
|
+
export declare function mapArray<T, U>(array: ReadonlyArray<T> | Array<T>, mapper: (item: T, index: number) => U): ReadonlyArray<U>;
|
|
175
|
+
/**
|
|
176
|
+
* Filters an array using a predicate or refinement function, returning a new
|
|
177
|
+
* readonly array.
|
|
178
|
+
*
|
|
179
|
+
* Accepts both mutable and readonly arrays. When used with a refinement
|
|
180
|
+
* function (with `value is Type` syntax), TypeScript will narrow the result
|
|
181
|
+
* type to the narrowed type, making it useful for filtering with Evolu Types
|
|
182
|
+
* like `PositiveInt.is`.
|
|
183
|
+
*
|
|
184
|
+
* ### Examples
|
|
185
|
+
*
|
|
186
|
+
* #### With predicate
|
|
187
|
+
*
|
|
188
|
+
* ```ts
|
|
189
|
+
* filterArray([1, 2, 3, 4, 5], (x) => x % 2 === 0); // [2, 4]
|
|
190
|
+
* ```
|
|
191
|
+
*
|
|
192
|
+
* #### With refinement
|
|
193
|
+
*
|
|
194
|
+
* ```ts
|
|
195
|
+
* const mixed: ReadonlyArray<NonEmptyString | PositiveInt> = [
|
|
196
|
+
* NonEmptyString.orThrow("hello"),
|
|
197
|
+
* PositiveInt.orThrow(42),
|
|
198
|
+
* ];
|
|
199
|
+
* const positiveInts = filterArray(mixed, PositiveInt.is);
|
|
200
|
+
* // positiveInts: ReadonlyArray<PositiveInt> (narrowed type)
|
|
201
|
+
* ```
|
|
202
|
+
*
|
|
203
|
+
* @category Transformations
|
|
204
|
+
*/
|
|
205
|
+
export declare function filterArray<T, S extends T>(array: ReadonlyArray<T>, refinement: RefinementWithIndex<T, S>): ReadonlyArray<S>;
|
|
206
|
+
export declare function filterArray<T>(array: ReadonlyArray<T>, predicate: PredicateWithIndex<T>): ReadonlyArray<T>;
|
|
207
|
+
/**
|
|
208
|
+
* Returns a new readonly array with duplicate items removed. If `by` is
|
|
209
|
+
* provided, it will be used to derive the key for uniqueness; otherwise values
|
|
210
|
+
* are used directly. Dedupes by reference equality of values (or extracted keys
|
|
211
|
+
* when `by` is used).
|
|
212
|
+
*
|
|
213
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
214
|
+
* Preserves non-empty type.
|
|
215
|
+
*
|
|
216
|
+
* ### Example
|
|
217
|
+
*
|
|
218
|
+
* ```ts
|
|
219
|
+
* // Dedupe primitives by value
|
|
220
|
+
* dedupeArray([1, 2, 1, 3, 2]); // [1, 2, 3]
|
|
221
|
+
*
|
|
222
|
+
* // Dedupe objects by property
|
|
223
|
+
* dedupeArray(
|
|
224
|
+
* [
|
|
225
|
+
* { id: 1, name: "Alice" },
|
|
226
|
+
* { id: 2, name: "Bob" },
|
|
227
|
+
* { id: 1, name: "Alice 2" },
|
|
228
|
+
* ],
|
|
229
|
+
* (item) => item.id,
|
|
230
|
+
* ); // [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }]
|
|
231
|
+
* ```
|
|
232
|
+
*
|
|
233
|
+
* @category Transformations
|
|
234
|
+
*/
|
|
235
|
+
export declare function dedupeArray<T>(array: NonEmptyReadonlyArray<T> | NonEmptyArray<T>, by?: (item: T) => unknown): NonEmptyReadonlyArray<T>;
|
|
236
|
+
export declare function dedupeArray<T>(array: ReadonlyArray<T> | Array<T>, by?: (item: T) => unknown): ReadonlyArray<T>;
|
|
237
|
+
/**
|
|
238
|
+
* Partitions an array into two arrays based on a predicate or refinement
|
|
239
|
+
* function.
|
|
240
|
+
*
|
|
241
|
+
* Returns a tuple where the first array contains elements that satisfy the
|
|
242
|
+
* predicate, and the second array contains elements that do not. Accepts both
|
|
243
|
+
* mutable and readonly arrays.
|
|
244
|
+
*
|
|
245
|
+
* When used with a refinement function (with `value is Type` syntax),
|
|
246
|
+
* TypeScript will narrow the first array to the narrowed type, making it useful
|
|
247
|
+
* for filtering with Evolu Types like `PositiveInt.is`.
|
|
248
|
+
*
|
|
249
|
+
* ### Examples
|
|
250
|
+
*
|
|
251
|
+
* #### With predicate
|
|
252
|
+
*
|
|
253
|
+
* ```ts
|
|
254
|
+
* const [evens, odds] = partitionArray(
|
|
255
|
+
* [1, 2, 3, 4, 5],
|
|
256
|
+
* (x) => x % 2 === 0,
|
|
257
|
+
* );
|
|
258
|
+
* evens; // [2, 4]
|
|
259
|
+
* odds; // [1, 3, 5]
|
|
260
|
+
* ```
|
|
261
|
+
*
|
|
262
|
+
* #### With refinement
|
|
263
|
+
*
|
|
264
|
+
* ```ts
|
|
265
|
+
* const mixed: ReadonlyArray<NonEmptyString | PositiveInt> = [
|
|
266
|
+
* NonEmptyString.orThrow("hello"),
|
|
267
|
+
* PositiveInt.orThrow(42),
|
|
268
|
+
* ];
|
|
269
|
+
* const [positiveInts, strings] = partitionArray(mixed, PositiveInt.is);
|
|
270
|
+
* // positiveInts: ReadonlyArray<PositiveInt> (narrowed type)
|
|
271
|
+
* // strings: ReadonlyArray<NonEmptyString> (Exclude<T, PositiveInt>)
|
|
272
|
+
* ```
|
|
273
|
+
*
|
|
274
|
+
* @category Transformations
|
|
275
|
+
*/
|
|
276
|
+
export declare function partitionArray<T, S extends T>(array: ReadonlyArray<T>, refinement: RefinementWithIndex<T, S>): readonly [ReadonlyArray<S>, ReadonlyArray<Exclude<T, S>>];
|
|
277
|
+
export declare function partitionArray<T>(array: ReadonlyArray<T>, predicate: PredicateWithIndex<T>): readonly [ReadonlyArray<T>, ReadonlyArray<T>];
|
|
278
|
+
/**
|
|
279
|
+
* Returns the first element of a non-empty array.
|
|
280
|
+
*
|
|
281
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
282
|
+
*
|
|
283
|
+
* ### Example
|
|
284
|
+
*
|
|
285
|
+
* ```ts
|
|
286
|
+
* firstInArray(["a", "b", "c"]); // "a"
|
|
287
|
+
* ```
|
|
288
|
+
*
|
|
289
|
+
* @category Accessors
|
|
290
|
+
*/
|
|
291
|
+
export declare const firstInArray: <T>(array: NonEmptyReadonlyArray<T>) => T;
|
|
292
|
+
/**
|
|
293
|
+
* Returns the last element of a non-empty array.
|
|
294
|
+
*
|
|
295
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
296
|
+
*
|
|
297
|
+
* ### Example
|
|
298
|
+
*
|
|
299
|
+
* ```ts
|
|
300
|
+
* lastInArray(["a", "b", "c"]); // "c"
|
|
301
|
+
* ```
|
|
302
|
+
*
|
|
303
|
+
* @category Accessors
|
|
304
|
+
*/
|
|
305
|
+
export declare const lastInArray: <T>(array: NonEmptyReadonlyArray<T>) => T;
|
|
306
|
+
/**
|
|
307
|
+
* Shifts an item from a non-empty mutable array, guaranteed to return T.
|
|
308
|
+
*
|
|
309
|
+
* **Mutates** the original array.
|
|
310
|
+
*
|
|
311
|
+
* ### Example
|
|
312
|
+
*
|
|
313
|
+
* ```ts
|
|
314
|
+
* const arr: NonEmptyArray<number> = [1, 2, 3];
|
|
315
|
+
* shiftArray(arr); // 1
|
|
316
|
+
* arr; // [2, 3]
|
|
317
|
+
* ```
|
|
318
|
+
*
|
|
319
|
+
* @category Mutations
|
|
320
|
+
*/
|
|
16
321
|
export declare const shiftArray: <T>(array: NonEmptyArray<T>) => T;
|
|
17
322
|
//# sourceMappingURL=Array.d.ts.map
|
package/dist/src/Array.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Array.d.ts","sourceRoot":"","sources":["../../src/Array.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"Array.d.ts","sourceRoot":"","sources":["../../src/Array.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AAEH,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAErE;;;;GAIG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhD;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,EAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,KACd,KAAK,IAAI,aAAa,CAAC,CAAC,CAAqB,CAAC;AAEjD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,EACvC,OAAO,aAAa,CAAC,CAAC,CAAC,KACtB,KAAK,IAAI,qBAAqB,CAAC,CAAC,CAAqB,CAAC;AAEzD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,EAC7B,OAAO,aAAa,CAAC,CAAC,CAAC,EACvB,MAAM,CAAC,KACN,qBAAqB,CAAC,CAAC,CACwC,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,EAC9B,OAAO,aAAa,CAAC,CAAC,CAAC,EACvB,MAAM,CAAC,KACN,qBAAqB,CAAC,CAAC,CAAiD,CAAC;AAE5E;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAC3B,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,EAClD,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,GACpC,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAC5B,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAC3B,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAClC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,GACpC,aAAa,CAAC,CAAC,CAAC,CAAC;AAQpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EACxC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EACvB,UAAU,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,GACpC,aAAa,CAAC,CAAC,CAAC,CAAC;AACpB,wBAAgB,WAAW,CAAC,CAAC,EAC3B,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EACvB,SAAS,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC/B,aAAa,CAAC,CAAC,CAAC,CAAC;AAQpB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,EAClD,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,GACxB,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAC5B,wBAAgB,WAAW,CAAC,CAAC,EAC3B,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAClC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,GACxB,aAAa,CAAC,CAAC,CAAC,CAAC;AAkBpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAC3C,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EACvB,UAAU,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,GACpC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,wBAAgB,cAAc,CAAC,CAAC,EAC9B,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EACvB,SAAS,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC/B,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAmBjD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,OAAO,qBAAqB,CAAC,CAAC,CAAC,KAAG,CAAa,CAAC;AAEhF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,OAAO,qBAAqB,CAAC,CAAC,CAAC,KAAG,CACxC,CAAC;AAE1B;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,KAAG,CAAuB,CAAC"}
|
package/dist/src/Array.js
CHANGED
|
@@ -1,12 +1,222 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Array types, type guards, operations, transformations, accessors, and
|
|
3
|
+
* mutations
|
|
4
|
+
*
|
|
5
|
+
* ### Example
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* // Types - compile-time guarantee of at least one element
|
|
9
|
+
* const _valid: NonEmptyReadonlyArray<number> = [1, 2, 3];
|
|
10
|
+
* // ts-expect-error - empty array is not a valid NonEmptyReadonlyArray
|
|
11
|
+
* const _invalid: NonEmptyReadonlyArray<number> = [];
|
|
12
|
+
*
|
|
13
|
+
* // Type guards
|
|
14
|
+
* const arr: ReadonlyArray<number> = [1, 2, 3];
|
|
15
|
+
* if (isNonEmptyReadonlyArray(arr)) {
|
|
16
|
+
* firstInArray(arr);
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* // Operations
|
|
20
|
+
* const appended = appendToArray([1, 2, 3], 4); // [1, 2, 3, 4]
|
|
21
|
+
* const prepended = prependToArray([2, 3], 1); // [1, 2, 3]
|
|
22
|
+
*
|
|
23
|
+
* // Transformations
|
|
24
|
+
* const readonly: ReadonlyArray<number> = [1, 2, 3];
|
|
25
|
+
* const mapped = mapArray(readonly, (x) => x * 2); // [2, 4, 6]
|
|
26
|
+
* const filtered = filterArray(readonly, (x) => x > 1); // [2, 3]
|
|
27
|
+
* const deduped = dedupeArray([1, 2, 1, 3, 2]); // [1, 2, 3]
|
|
28
|
+
* const [evens, odds] = partitionArray(
|
|
29
|
+
* [1, 2, 3, 4, 5],
|
|
30
|
+
* (x) => x % 2 === 0,
|
|
31
|
+
* ); // [[2, 4], [1, 3, 5]]
|
|
32
|
+
*
|
|
33
|
+
* // Accessors
|
|
34
|
+
* const first = firstInArray(["a", "b", "c"]); // "a"
|
|
35
|
+
* const last = lastInArray(["a", "b", "c"]); // "c"
|
|
36
|
+
*
|
|
37
|
+
* // Mutations
|
|
38
|
+
* const mutable: NonEmptyArray<number> = [1, 2, 3];
|
|
39
|
+
* shiftArray(mutable); // 1 (guaranteed to exist)
|
|
40
|
+
* mutable; // [2, 3]
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* Functions are intentionally data-first to be prepared for the upcoming
|
|
44
|
+
* JavaScript pipe operator.
|
|
45
|
+
*
|
|
46
|
+
* ```ts
|
|
47
|
+
* // Data-first is natural for single operations.
|
|
48
|
+
* const timestamps = mapArray(messages, (m) => m.timestamp);
|
|
49
|
+
*
|
|
50
|
+
* // But data-first can be hard to read for nested calls.
|
|
51
|
+
* const result = firstInArray(
|
|
52
|
+
* mapArray(dedupeArray(appendToArray(value, 2)), (x) => x * 2),
|
|
53
|
+
* );
|
|
54
|
+
*
|
|
55
|
+
* // With the upcoming pipe operator, it's clear.
|
|
56
|
+
* // const result = value
|
|
57
|
+
* // |> appendToArray(%, 2)
|
|
58
|
+
* // |> dedupeArray(%)
|
|
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);
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* ### Why data-first?
|
|
70
|
+
*
|
|
71
|
+
* Evolu optimizes for consistent code style. We can't have both data-first
|
|
72
|
+
* single operations and curried data-last helpers without sacrificing
|
|
73
|
+
* consistency. We chose data-first because:
|
|
74
|
+
*
|
|
75
|
+
* - It's natural for single operations (for example `mapArray(messages, (m) =>
|
|
76
|
+
* m.timestamp)`).
|
|
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.).
|
|
81
|
+
*
|
|
82
|
+
* @module
|
|
83
|
+
*/
|
|
84
|
+
/**
|
|
85
|
+
* Checks if an array is non-empty and narrows its type to {@link NonEmptyArray}.
|
|
86
|
+
*
|
|
87
|
+
* Use `if (!isNonEmptyArray(arr))` for empty checks.
|
|
88
|
+
*
|
|
89
|
+
* ### Example
|
|
90
|
+
*
|
|
91
|
+
* ```ts
|
|
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
|
|
99
|
+
*/
|
|
2
100
|
export const isNonEmptyArray = (array) => array.length > 0;
|
|
3
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* Checks if a readonly array is non-empty and narrows its type to
|
|
103
|
+
* {@link NonEmptyReadonlyArray}.
|
|
104
|
+
*
|
|
105
|
+
* Use `if (!isNonEmptyReadonlyArray(arr))` for empty checks.
|
|
106
|
+
*
|
|
107
|
+
* ### Example
|
|
108
|
+
*
|
|
109
|
+
* ```ts
|
|
110
|
+
* const arr: ReadonlyArray<number> = [1, 2, 3];
|
|
111
|
+
* if (isNonEmptyReadonlyArray(arr)) {
|
|
112
|
+
* firstInArray(arr); // arr is NonEmptyReadonlyArray<number>
|
|
113
|
+
* }
|
|
114
|
+
* ```
|
|
115
|
+
*
|
|
116
|
+
* @category Type Guards
|
|
117
|
+
*/
|
|
4
118
|
export const isNonEmptyReadonlyArray = (array) => array.length > 0;
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Appends an item to an array, returning a new non-empty readonly array.
|
|
121
|
+
*
|
|
122
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
123
|
+
*
|
|
124
|
+
* ### Example
|
|
125
|
+
*
|
|
126
|
+
* ```ts
|
|
127
|
+
* appendToArray([1, 2, 3], 4); // [1, 2, 3, 4]
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* @category Operations
|
|
131
|
+
*/
|
|
132
|
+
export const appendToArray = (array, item) => [...array, item];
|
|
133
|
+
/**
|
|
134
|
+
* Prepends an item to an array, returning a new non-empty readonly array.
|
|
135
|
+
*
|
|
136
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
137
|
+
*
|
|
138
|
+
* ### Example
|
|
139
|
+
*
|
|
140
|
+
* ```ts
|
|
141
|
+
* prependToArray([2, 3], 1); // [1, 2, 3]
|
|
142
|
+
* ```
|
|
143
|
+
*
|
|
144
|
+
* @category Operations
|
|
145
|
+
*/
|
|
146
|
+
export const prependToArray = (array, item) => [item, ...array];
|
|
147
|
+
export function mapArray(array, mapper) {
|
|
148
|
+
return array.map(mapper);
|
|
149
|
+
}
|
|
150
|
+
export function filterArray(array, predicate) {
|
|
151
|
+
return array.filter(predicate);
|
|
152
|
+
}
|
|
153
|
+
export function dedupeArray(array, by) {
|
|
154
|
+
if (by == null) {
|
|
155
|
+
return Array.from(new Set(array));
|
|
156
|
+
}
|
|
157
|
+
const seen = new Set();
|
|
158
|
+
return array.filter((item) => {
|
|
159
|
+
const key = by(item);
|
|
160
|
+
if (seen.has(key))
|
|
161
|
+
return false;
|
|
162
|
+
seen.add(key);
|
|
163
|
+
return true;
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
export function partitionArray(array, predicate) {
|
|
167
|
+
const trueArray = [];
|
|
168
|
+
const falseArray = [];
|
|
169
|
+
for (let i = 0; i < array.length; i++) {
|
|
170
|
+
if (predicate(array[i], i)) {
|
|
171
|
+
trueArray.push(array[i]);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
falseArray.push(array[i]);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return [trueArray, falseArray];
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Returns the first element of a non-empty array.
|
|
181
|
+
*
|
|
182
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
183
|
+
*
|
|
184
|
+
* ### Example
|
|
185
|
+
*
|
|
186
|
+
* ```ts
|
|
187
|
+
* firstInArray(["a", "b", "c"]); // "a"
|
|
188
|
+
* ```
|
|
189
|
+
*
|
|
190
|
+
* @category Accessors
|
|
191
|
+
*/
|
|
192
|
+
export const firstInArray = (array) => array[0];
|
|
193
|
+
/**
|
|
194
|
+
* Returns the last element of a non-empty array.
|
|
195
|
+
*
|
|
196
|
+
* Accepts both mutable and readonly arrays. Does not mutate the original array.
|
|
197
|
+
*
|
|
198
|
+
* ### Example
|
|
199
|
+
*
|
|
200
|
+
* ```ts
|
|
201
|
+
* lastInArray(["a", "b", "c"]); // "c"
|
|
202
|
+
* ```
|
|
203
|
+
*
|
|
204
|
+
* @category Accessors
|
|
205
|
+
*/
|
|
206
|
+
export const lastInArray = (array) => array[array.length - 1];
|
|
207
|
+
/**
|
|
208
|
+
* Shifts an item from a non-empty mutable array, guaranteed to return T.
|
|
209
|
+
*
|
|
210
|
+
* **Mutates** the original array.
|
|
211
|
+
*
|
|
212
|
+
* ### Example
|
|
213
|
+
*
|
|
214
|
+
* ```ts
|
|
215
|
+
* const arr: NonEmptyArray<number> = [1, 2, 3];
|
|
216
|
+
* shiftArray(arr); // 1
|
|
217
|
+
* arr; // [2, 3]
|
|
218
|
+
* ```
|
|
219
|
+
*
|
|
220
|
+
* @category Mutations
|
|
221
|
+
*/
|
|
12
222
|
export const shiftArray = (array) => array.shift();
|
package/dist/src/Assert.d.ts
CHANGED
|
@@ -55,17 +55,4 @@ 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
|
-
* Asserts no error reaches a `.catch` block, throwing a developer error if it
|
|
60
|
-
* does. Used in Promise chains where errors indicate bugs to be fixed.
|
|
61
|
-
*
|
|
62
|
-
* ### Example
|
|
63
|
-
*
|
|
64
|
-
* ```ts
|
|
65
|
-
* Promise.reject("test").catch((e) =>
|
|
66
|
-
* assertNoErrorInCatch("WebSocket retry", e),
|
|
67
|
-
* );
|
|
68
|
-
* ```
|
|
69
|
-
*/
|
|
70
|
-
export declare function assertNoErrorInCatch(context: string, error: unknown): never;
|
|
71
58
|
//# 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":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;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"}
|