@nlozgachev/pipelined 0.12.0 → 0.14.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/LICENCE +28 -0
- package/README.md +1 -1
- package/{types/src/Types/NonEmptyList.d.ts → dist/NonEmptyList-BlGFjor5.d.mts} +4 -3
- package/dist/NonEmptyList-BlGFjor5.d.ts +30 -0
- package/dist/Task-Bd3gXPRQ.d.mts +677 -0
- package/dist/Task-BjAkkD6t.d.ts +677 -0
- package/dist/chunk-4TXC322E.mjs +136 -0
- package/dist/chunk-BYWKZLHM.mjs +10 -0
- package/dist/chunk-DBIC62UV.mjs +6 -0
- package/dist/chunk-FAZN3IWZ.mjs +554 -0
- package/dist/chunk-QPTGO5AS.mjs +150 -0
- package/dist/chunk-UV2HMF2A.mjs +514 -0
- package/dist/composition.d.mts +495 -0
- package/dist/composition.d.ts +495 -0
- package/dist/composition.js +188 -0
- package/dist/composition.mjs +58 -0
- package/dist/core.d.mts +2170 -0
- package/dist/core.d.ts +2170 -0
- package/dist/core.js +698 -0
- package/dist/core.mjs +42 -0
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +1421 -0
- package/dist/index.mjs +120 -0
- package/dist/types.d.mts +54 -0
- package/{types/src/Types/Brand.d.ts → dist/types.d.ts} +6 -4
- package/dist/types.js +41 -0
- package/dist/types.mjs +10 -0
- package/dist/utils.d.mts +1285 -0
- package/dist/utils.d.ts +1285 -0
- package/dist/utils.js +722 -0
- package/dist/utils.mjs +18 -0
- package/package.json +64 -69
- package/esm/mod.js +0 -3
- package/esm/package.json +0 -3
- package/esm/src/Composition/compose.js +0 -3
- package/esm/src/Composition/converge.js +0 -3
- package/esm/src/Composition/curry.js +0 -42
- package/esm/src/Composition/flip.js +0 -20
- package/esm/src/Composition/flow.js +0 -8
- package/esm/src/Composition/fn.js +0 -85
- package/esm/src/Composition/index.js +0 -13
- package/esm/src/Composition/juxt.js +0 -3
- package/esm/src/Composition/memoize.js +0 -66
- package/esm/src/Composition/not.js +0 -25
- package/esm/src/Composition/on.js +0 -12
- package/esm/src/Composition/pipe.js +0 -3
- package/esm/src/Composition/tap.js +0 -33
- package/esm/src/Composition/uncurry.js +0 -32
- package/esm/src/Core/Deferred.js +0 -30
- package/esm/src/Core/InternalTypes.js +0 -1
- package/esm/src/Core/Lens.js +0 -98
- package/esm/src/Core/Logged.js +0 -111
- package/esm/src/Core/Option.js +0 -191
- package/esm/src/Core/Optional.js +0 -160
- package/esm/src/Core/Predicate.js +0 -133
- package/esm/src/Core/Reader.js +0 -134
- package/esm/src/Core/Refinement.js +0 -115
- package/esm/src/Core/RemoteData.js +0 -211
- package/esm/src/Core/Result.js +0 -170
- package/esm/src/Core/State.js +0 -181
- package/esm/src/Core/Task.js +0 -223
- package/esm/src/Core/TaskOption.js +0 -106
- package/esm/src/Core/TaskResult.js +0 -127
- package/esm/src/Core/TaskValidation.js +0 -128
- package/esm/src/Core/These.js +0 -245
- package/esm/src/Core/Tuple.js +0 -112
- package/esm/src/Core/Validation.js +0 -212
- package/esm/src/Core/index.js +0 -18
- package/esm/src/Types/Brand.js +0 -28
- package/esm/src/Types/NonEmptyList.js +0 -14
- package/esm/src/Types/index.js +0 -2
- package/esm/src/Utils/Arr.js +0 -570
- package/esm/src/Utils/Dict.js +0 -421
- package/esm/src/Utils/Num.js +0 -124
- package/esm/src/Utils/Rec.js +0 -241
- package/esm/src/Utils/Str.js +0 -134
- package/esm/src/Utils/Uniq.js +0 -265
- package/esm/src/Utils/index.js +0 -6
- package/script/mod.js +0 -19
- package/script/package.json +0 -3
- package/script/src/Composition/compose.js +0 -6
- package/script/src/Composition/converge.js +0 -6
- package/script/src/Composition/curry.js +0 -48
- package/script/src/Composition/flip.js +0 -24
- package/script/src/Composition/flow.js +0 -11
- package/script/src/Composition/fn.js +0 -98
- package/script/src/Composition/index.js +0 -29
- package/script/src/Composition/juxt.js +0 -6
- package/script/src/Composition/memoize.js +0 -71
- package/script/src/Composition/not.js +0 -29
- package/script/src/Composition/on.js +0 -16
- package/script/src/Composition/pipe.js +0 -6
- package/script/src/Composition/tap.js +0 -37
- package/script/src/Composition/uncurry.js +0 -38
- package/script/src/Core/Deferred.js +0 -33
- package/script/src/Core/InternalTypes.js +0 -2
- package/script/src/Core/Lens.js +0 -101
- package/script/src/Core/Logged.js +0 -114
- package/script/src/Core/Option.js +0 -194
- package/script/src/Core/Optional.js +0 -163
- package/script/src/Core/Predicate.js +0 -136
- package/script/src/Core/Reader.js +0 -137
- package/script/src/Core/Refinement.js +0 -118
- package/script/src/Core/RemoteData.js +0 -214
- package/script/src/Core/Result.js +0 -173
- package/script/src/Core/State.js +0 -184
- package/script/src/Core/Task.js +0 -226
- package/script/src/Core/TaskOption.js +0 -109
- package/script/src/Core/TaskResult.js +0 -130
- package/script/src/Core/TaskValidation.js +0 -131
- package/script/src/Core/These.js +0 -248
- package/script/src/Core/Tuple.js +0 -115
- package/script/src/Core/Validation.js +0 -215
- package/script/src/Core/index.js +0 -34
- package/script/src/Types/Brand.js +0 -31
- package/script/src/Types/NonEmptyList.js +0 -18
- package/script/src/Types/index.js +0 -18
- package/script/src/Utils/Arr.js +0 -573
- package/script/src/Utils/Dict.js +0 -424
- package/script/src/Utils/Num.js +0 -127
- package/script/src/Utils/Rec.js +0 -244
- package/script/src/Utils/Str.js +0 -137
- package/script/src/Utils/Uniq.js +0 -268
- package/script/src/Utils/index.js +0 -22
- package/types/mod.d.ts +0 -4
- package/types/mod.d.ts.map +0 -1
- package/types/src/Composition/compose.d.ts +0 -33
- package/types/src/Composition/compose.d.ts.map +0 -1
- package/types/src/Composition/converge.d.ts +0 -21
- package/types/src/Composition/converge.d.ts.map +0 -1
- package/types/src/Composition/curry.d.ts +0 -43
- package/types/src/Composition/curry.d.ts.map +0 -1
- package/types/src/Composition/flip.d.ts +0 -21
- package/types/src/Composition/flip.d.ts.map +0 -1
- package/types/src/Composition/flow.d.ts +0 -56
- package/types/src/Composition/flow.d.ts.map +0 -1
- package/types/src/Composition/fn.d.ts +0 -76
- package/types/src/Composition/fn.d.ts.map +0 -1
- package/types/src/Composition/index.d.ts +0 -14
- package/types/src/Composition/index.d.ts.map +0 -1
- package/types/src/Composition/juxt.d.ts +0 -18
- package/types/src/Composition/juxt.d.ts.map +0 -1
- package/types/src/Composition/memoize.d.ts +0 -46
- package/types/src/Composition/memoize.d.ts.map +0 -1
- package/types/src/Composition/not.d.ts +0 -26
- package/types/src/Composition/not.d.ts.map +0 -1
- package/types/src/Composition/on.d.ts +0 -13
- package/types/src/Composition/on.d.ts.map +0 -1
- package/types/src/Composition/pipe.d.ts +0 -56
- package/types/src/Composition/pipe.d.ts.map +0 -1
- package/types/src/Composition/tap.d.ts +0 -31
- package/types/src/Composition/tap.d.ts.map +0 -1
- package/types/src/Composition/uncurry.d.ts +0 -54
- package/types/src/Composition/uncurry.d.ts.map +0 -1
- package/types/src/Core/Deferred.d.ts +0 -49
- package/types/src/Core/Deferred.d.ts.map +0 -1
- package/types/src/Core/InternalTypes.d.ts +0 -23
- package/types/src/Core/InternalTypes.d.ts.map +0 -1
- package/types/src/Core/Lens.d.ts +0 -118
- package/types/src/Core/Lens.d.ts.map +0 -1
- package/types/src/Core/Logged.d.ts +0 -126
- package/types/src/Core/Logged.d.ts.map +0 -1
- package/types/src/Core/Option.d.ts +0 -209
- package/types/src/Core/Option.d.ts.map +0 -1
- package/types/src/Core/Optional.d.ts +0 -158
- package/types/src/Core/Optional.d.ts.map +0 -1
- package/types/src/Core/Predicate.d.ts +0 -161
- package/types/src/Core/Predicate.d.ts.map +0 -1
- package/types/src/Core/Reader.d.ts +0 -156
- package/types/src/Core/Reader.d.ts.map +0 -1
- package/types/src/Core/Refinement.d.ts +0 -138
- package/types/src/Core/Refinement.d.ts.map +0 -1
- package/types/src/Core/RemoteData.d.ts +0 -197
- package/types/src/Core/RemoteData.d.ts.map +0 -1
- package/types/src/Core/Result.d.ts +0 -182
- package/types/src/Core/Result.d.ts.map +0 -1
- package/types/src/Core/State.d.ts +0 -192
- package/types/src/Core/State.d.ts.map +0 -1
- package/types/src/Core/Task.d.ts +0 -219
- package/types/src/Core/Task.d.ts.map +0 -1
- package/types/src/Core/TaskOption.d.ts +0 -121
- package/types/src/Core/TaskOption.d.ts.map +0 -1
- package/types/src/Core/TaskResult.d.ts +0 -119
- package/types/src/Core/TaskResult.d.ts.map +0 -1
- package/types/src/Core/TaskValidation.d.ts +0 -144
- package/types/src/Core/TaskValidation.d.ts.map +0 -1
- package/types/src/Core/These.d.ts +0 -225
- package/types/src/Core/These.d.ts.map +0 -1
- package/types/src/Core/Tuple.d.ts +0 -129
- package/types/src/Core/Tuple.d.ts.map +0 -1
- package/types/src/Core/Validation.d.ts +0 -203
- package/types/src/Core/Validation.d.ts.map +0 -1
- package/types/src/Core/index.d.ts +0 -19
- package/types/src/Core/index.d.ts.map +0 -1
- package/types/src/Types/Brand.d.ts.map +0 -1
- package/types/src/Types/NonEmptyList.d.ts.map +0 -1
- package/types/src/Types/index.d.ts +0 -3
- package/types/src/Types/index.d.ts.map +0 -1
- package/types/src/Utils/Arr.d.ts +0 -403
- package/types/src/Utils/Arr.d.ts.map +0 -1
- package/types/src/Utils/Dict.d.ts +0 -310
- package/types/src/Utils/Dict.d.ts.map +0 -1
- package/types/src/Utils/Num.d.ts +0 -110
- package/types/src/Utils/Num.d.ts.map +0 -1
- package/types/src/Utils/Rec.d.ts +0 -159
- package/types/src/Utils/Rec.d.ts.map +0 -1
- package/types/src/Utils/Str.d.ts +0 -128
- package/types/src/Utils/Str.d.ts.map +0 -1
- package/types/src/Utils/Uniq.d.ts +0 -179
- package/types/src/Utils/Uniq.d.ts.map +0 -1
- package/types/src/Utils/index.d.ts +0 -7
- package/types/src/Utils/index.d.ts.map +0 -1
package/esm/src/Core/index.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export * from "./Deferred.js";
|
|
2
|
-
export * from "./Lens.js";
|
|
3
|
-
export * from "./Logged.js";
|
|
4
|
-
export * from "./Option.js";
|
|
5
|
-
export * from "./Optional.js";
|
|
6
|
-
export * from "./Predicate.js";
|
|
7
|
-
export * from "./Reader.js";
|
|
8
|
-
export * from "./Refinement.js";
|
|
9
|
-
export * from "./RemoteData.js";
|
|
10
|
-
export * from "./Result.js";
|
|
11
|
-
export * from "./State.js";
|
|
12
|
-
export * from "./Task.js";
|
|
13
|
-
export * from "./TaskOption.js";
|
|
14
|
-
export * from "./TaskResult.js";
|
|
15
|
-
export * from "./TaskValidation.js";
|
|
16
|
-
export * from "./These.js";
|
|
17
|
-
export * from "./Tuple.js";
|
|
18
|
-
export * from "./Validation.js";
|
package/esm/src/Types/Brand.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export var Brand;
|
|
2
|
-
(function (Brand) {
|
|
3
|
-
/**
|
|
4
|
-
* Returns a constructor that wraps a value of type T in brand K.
|
|
5
|
-
* The resulting function performs an unchecked cast — only use when the raw
|
|
6
|
-
* value is known to satisfy the brand's invariants.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```ts
|
|
10
|
-
* type PositiveNumber = Brand<"PositiveNumber", number>;
|
|
11
|
-
* const toPositiveNumber = Brand.wrap<"PositiveNumber", number>();
|
|
12
|
-
*
|
|
13
|
-
* const n: PositiveNumber = toPositiveNumber(42);
|
|
14
|
-
* ```
|
|
15
|
-
*/
|
|
16
|
-
Brand.wrap = () => (value) => value;
|
|
17
|
-
/**
|
|
18
|
-
* Strips the brand and returns the underlying value.
|
|
19
|
-
* Since Brand<K, T> extends T this is rarely needed, but can improve readability.
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```ts
|
|
23
|
-
* const userId: UserId = toUserId("user-123");
|
|
24
|
-
* const raw: string = Brand.unwrap(userId); // "user-123"
|
|
25
|
-
* ```
|
|
26
|
-
*/
|
|
27
|
-
Brand.unwrap = (branded) => branded;
|
|
28
|
-
})(Brand || (Brand = {}));
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type guard that checks if an array is non-empty.
|
|
3
|
-
*
|
|
4
|
-
* @example
|
|
5
|
-
* ```ts
|
|
6
|
-
* const items: string[] = getItems();
|
|
7
|
-
*
|
|
8
|
-
* if (isNonEmptyList(items)) {
|
|
9
|
-
* // TypeScript knows items has at least one element
|
|
10
|
-
* const first = items[0]; // string, not string | undefined
|
|
11
|
-
* }
|
|
12
|
-
* ```
|
|
13
|
-
*/
|
|
14
|
-
export const isNonEmptyList = (list) => list.length > 0;
|
package/esm/src/Types/index.js
DELETED
package/esm/src/Utils/Arr.js
DELETED
|
@@ -1,570 +0,0 @@
|
|
|
1
|
-
import { Deferred } from "../Core/Deferred.js";
|
|
2
|
-
import { Option } from "../Core/Option.js";
|
|
3
|
-
import { Result } from "../Core/Result.js";
|
|
4
|
-
import { Task } from "../Core/Task.js";
|
|
5
|
-
import { isNonEmptyList } from "../Types/NonEmptyList.js";
|
|
6
|
-
/**
|
|
7
|
-
* Functional array utilities that compose well with pipe.
|
|
8
|
-
* All functions are data-last and curried where applicable.
|
|
9
|
-
* Safe access functions return Option instead of throwing or returning undefined.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```ts
|
|
13
|
-
* pipe(
|
|
14
|
-
* [1, 2, 3, 4, 5],
|
|
15
|
-
* Arr.filter(n => n > 2),
|
|
16
|
-
* Arr.map(n => n * 10),
|
|
17
|
-
* Arr.head
|
|
18
|
-
* ); // Some(30)
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
export var Arr;
|
|
22
|
-
(function (Arr) {
|
|
23
|
-
// --- Safe access ---
|
|
24
|
-
/**
|
|
25
|
-
* Returns the first element of an array, or None if the array is empty.
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```ts
|
|
29
|
-
* Arr.head([1, 2, 3]); // Some(1)
|
|
30
|
-
* Arr.head([]); // None
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
Arr.head = (data) => data.length > 0 ? Option.some(data[0]) : Option.none();
|
|
34
|
-
/**
|
|
35
|
-
* Returns the last element of an array, or None if the array is empty.
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* ```ts
|
|
39
|
-
* Arr.last([1, 2, 3]); // Some(3)
|
|
40
|
-
* Arr.last([]); // None
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
Arr.last = (data) => data.length > 0 ? Option.some(data[data.length - 1]) : Option.none();
|
|
44
|
-
/**
|
|
45
|
-
* Returns all elements except the first, or None if the array is empty.
|
|
46
|
-
*
|
|
47
|
-
* @example
|
|
48
|
-
* ```ts
|
|
49
|
-
* Arr.tail([1, 2, 3]); // Some([2, 3])
|
|
50
|
-
* Arr.tail([]); // None
|
|
51
|
-
* ```
|
|
52
|
-
*/
|
|
53
|
-
Arr.tail = (data) => data.length > 0 ? Option.some(data.slice(1)) : Option.none();
|
|
54
|
-
/**
|
|
55
|
-
* Returns all elements except the last, or None if the array is empty.
|
|
56
|
-
*
|
|
57
|
-
* @example
|
|
58
|
-
* ```ts
|
|
59
|
-
* Arr.init([1, 2, 3]); // Some([1, 2])
|
|
60
|
-
* Arr.init([]); // None
|
|
61
|
-
* ```
|
|
62
|
-
*/
|
|
63
|
-
Arr.init = (data) => data.length > 0 ? Option.some(data.slice(0, -1)) : Option.none();
|
|
64
|
-
// --- Search ---
|
|
65
|
-
/**
|
|
66
|
-
* Returns the first element matching the predicate, or None.
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
* ```ts
|
|
70
|
-
* pipe([1, 2, 3, 4], Arr.findFirst(n => n > 2)); // Some(3)
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
73
|
-
Arr.findFirst = (predicate) => (data) => {
|
|
74
|
-
const idx = data.findIndex(predicate);
|
|
75
|
-
return idx >= 0 ? Option.some(data[idx]) : Option.none();
|
|
76
|
-
};
|
|
77
|
-
/**
|
|
78
|
-
* Returns the last element matching the predicate, or None.
|
|
79
|
-
*
|
|
80
|
-
* @example
|
|
81
|
-
* ```ts
|
|
82
|
-
* pipe([1, 2, 3, 4], Arr.findLast(n => n > 2)); // Some(4)
|
|
83
|
-
* ```
|
|
84
|
-
*/
|
|
85
|
-
Arr.findLast = (predicate) => (data) => {
|
|
86
|
-
for (let i = data.length - 1; i >= 0; i--) {
|
|
87
|
-
if (predicate(data[i]))
|
|
88
|
-
return Option.some(data[i]);
|
|
89
|
-
}
|
|
90
|
-
return Option.none();
|
|
91
|
-
};
|
|
92
|
-
/**
|
|
93
|
-
* Returns the index of the first element matching the predicate, or None.
|
|
94
|
-
*
|
|
95
|
-
* @example
|
|
96
|
-
* ```ts
|
|
97
|
-
* pipe([1, 2, 3, 4], Arr.findIndex(n => n > 2)); // Some(2)
|
|
98
|
-
* ```
|
|
99
|
-
*/
|
|
100
|
-
Arr.findIndex = (predicate) => (data) => {
|
|
101
|
-
const idx = data.findIndex(predicate);
|
|
102
|
-
return idx >= 0 ? Option.some(idx) : Option.none();
|
|
103
|
-
};
|
|
104
|
-
// --- Transform ---
|
|
105
|
-
/**
|
|
106
|
-
* Transforms each element of an array.
|
|
107
|
-
*
|
|
108
|
-
* @example
|
|
109
|
-
* ```ts
|
|
110
|
-
* pipe([1, 2, 3], Arr.map(n => n * 2)); // [2, 4, 6]
|
|
111
|
-
* ```
|
|
112
|
-
*/
|
|
113
|
-
Arr.map = (f) => (data) => {
|
|
114
|
-
const n = data.length;
|
|
115
|
-
const result = new Array(n);
|
|
116
|
-
for (let i = 0; i < n; i++)
|
|
117
|
-
result[i] = f(data[i]);
|
|
118
|
-
return result;
|
|
119
|
-
};
|
|
120
|
-
/**
|
|
121
|
-
* Filters elements that satisfy the predicate.
|
|
122
|
-
*
|
|
123
|
-
* @example
|
|
124
|
-
* ```ts
|
|
125
|
-
* pipe([1, 2, 3, 4], Arr.filter(n => n % 2 === 0)); // [2, 4]
|
|
126
|
-
* ```
|
|
127
|
-
*/
|
|
128
|
-
Arr.filter = (predicate) => (data) => {
|
|
129
|
-
const n = data.length;
|
|
130
|
-
const result = [];
|
|
131
|
-
for (let i = 0; i < n; i++) {
|
|
132
|
-
if (predicate(data[i]))
|
|
133
|
-
result.push(data[i]);
|
|
134
|
-
}
|
|
135
|
-
return result;
|
|
136
|
-
};
|
|
137
|
-
/**
|
|
138
|
-
* Splits an array into two groups based on a predicate.
|
|
139
|
-
* First group contains elements that satisfy the predicate,
|
|
140
|
-
* second group contains the rest.
|
|
141
|
-
*
|
|
142
|
-
* @example
|
|
143
|
-
* ```ts
|
|
144
|
-
* pipe([1, 2, 3, 4], Arr.partition(n => n % 2 === 0)); // [[2, 4], [1, 3]]
|
|
145
|
-
* ```
|
|
146
|
-
*/
|
|
147
|
-
Arr.partition = (predicate) => (data) => {
|
|
148
|
-
const pass = [];
|
|
149
|
-
const fail = [];
|
|
150
|
-
for (const a of data) {
|
|
151
|
-
(predicate(a) ? pass : fail).push(a);
|
|
152
|
-
}
|
|
153
|
-
return [pass, fail];
|
|
154
|
-
};
|
|
155
|
-
/**
|
|
156
|
-
* Groups elements by a key function.
|
|
157
|
-
*
|
|
158
|
-
* @example
|
|
159
|
-
* ```ts
|
|
160
|
-
* pipe(
|
|
161
|
-
* ["apple", "avocado", "banana"],
|
|
162
|
-
* Arr.groupBy(s => s[0])
|
|
163
|
-
* ); // { a: ["apple", "avocado"], b: ["banana"] }
|
|
164
|
-
* ```
|
|
165
|
-
*/
|
|
166
|
-
Arr.groupBy = (f) => (data) => {
|
|
167
|
-
const result = {};
|
|
168
|
-
for (const a of data) {
|
|
169
|
-
const key = f(a);
|
|
170
|
-
if (!result[key])
|
|
171
|
-
result[key] = [];
|
|
172
|
-
result[key].push(a);
|
|
173
|
-
}
|
|
174
|
-
return result;
|
|
175
|
-
};
|
|
176
|
-
/**
|
|
177
|
-
* Removes duplicate elements using strict equality.
|
|
178
|
-
*
|
|
179
|
-
* @example
|
|
180
|
-
* ```ts
|
|
181
|
-
* Arr.uniq([1, 2, 2, 3, 1]); // [1, 2, 3]
|
|
182
|
-
* ```
|
|
183
|
-
*/
|
|
184
|
-
Arr.uniq = (data) => [
|
|
185
|
-
...new Set(data),
|
|
186
|
-
];
|
|
187
|
-
/**
|
|
188
|
-
* Removes duplicate elements by comparing the result of a key function.
|
|
189
|
-
*
|
|
190
|
-
* @example
|
|
191
|
-
* ```ts
|
|
192
|
-
* pipe(
|
|
193
|
-
* [{id: 1, name: "a"}, {id: 1, name: "b"}, {id: 2, name: "c"}],
|
|
194
|
-
* Arr.uniqBy(x => x.id)
|
|
195
|
-
* ); // [{id: 1, name: "a"}, {id: 2, name: "c"}]
|
|
196
|
-
* ```
|
|
197
|
-
*/
|
|
198
|
-
Arr.uniqBy = (f) => (data) => {
|
|
199
|
-
const seen = new Set();
|
|
200
|
-
const result = [];
|
|
201
|
-
for (const a of data) {
|
|
202
|
-
const key = f(a);
|
|
203
|
-
if (!seen.has(key)) {
|
|
204
|
-
seen.add(key);
|
|
205
|
-
result.push(a);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return result;
|
|
209
|
-
};
|
|
210
|
-
/**
|
|
211
|
-
* Sorts an array using a comparison function. Returns a new array.
|
|
212
|
-
*
|
|
213
|
-
* @example
|
|
214
|
-
* ```ts
|
|
215
|
-
* pipe([3, 1, 2], Arr.sortBy((a, b) => a - b)); // [1, 2, 3]
|
|
216
|
-
* ```
|
|
217
|
-
*/
|
|
218
|
-
Arr.sortBy = (compare) => (data) => [...data].sort(compare);
|
|
219
|
-
// --- Combine ---
|
|
220
|
-
/**
|
|
221
|
-
* Pairs up elements from two arrays. Stops at the shorter array.
|
|
222
|
-
*
|
|
223
|
-
* @example
|
|
224
|
-
* ```ts
|
|
225
|
-
* pipe([1, 2, 3], Arr.zip(["a", "b"])); // [[1, "a"], [2, "b"]]
|
|
226
|
-
* ```
|
|
227
|
-
*/
|
|
228
|
-
Arr.zip = (other) => (data) => {
|
|
229
|
-
const len = Math.min(data.length, other.length);
|
|
230
|
-
const result = new Array(len);
|
|
231
|
-
for (let i = 0; i < len; i++) {
|
|
232
|
-
result[i] = [data[i], other[i]];
|
|
233
|
-
}
|
|
234
|
-
return result;
|
|
235
|
-
};
|
|
236
|
-
/**
|
|
237
|
-
* Combines elements from two arrays using a function. Stops at the shorter array.
|
|
238
|
-
*
|
|
239
|
-
* @example
|
|
240
|
-
* ```ts
|
|
241
|
-
* pipe([1, 2], Arr.zipWith((a, b) => a + b, ["a", "b"])); // ["1a", "2b"]
|
|
242
|
-
* ```
|
|
243
|
-
*/
|
|
244
|
-
Arr.zipWith = (f) => (other) => (data) => {
|
|
245
|
-
const len = Math.min(data.length, other.length);
|
|
246
|
-
const result = new Array(len);
|
|
247
|
-
for (let i = 0; i < len; i++) {
|
|
248
|
-
result[i] = f(data[i], other[i]);
|
|
249
|
-
}
|
|
250
|
-
return result;
|
|
251
|
-
};
|
|
252
|
-
/**
|
|
253
|
-
* Inserts a separator between every element.
|
|
254
|
-
*
|
|
255
|
-
* @example
|
|
256
|
-
* ```ts
|
|
257
|
-
* pipe([1, 2, 3], Arr.intersperse(0)); // [1, 0, 2, 0, 3]
|
|
258
|
-
* ```
|
|
259
|
-
*/
|
|
260
|
-
Arr.intersperse = (sep) => (data) => {
|
|
261
|
-
if (data.length <= 1)
|
|
262
|
-
return data;
|
|
263
|
-
const result = [data[0]];
|
|
264
|
-
for (let i = 1; i < data.length; i++) {
|
|
265
|
-
result.push(sep, data[i]);
|
|
266
|
-
}
|
|
267
|
-
return result;
|
|
268
|
-
};
|
|
269
|
-
/**
|
|
270
|
-
* Splits an array into chunks of the given size.
|
|
271
|
-
*
|
|
272
|
-
* @example
|
|
273
|
-
* ```ts
|
|
274
|
-
* pipe([1, 2, 3, 4, 5], Arr.chunksOf(2)); // [[1, 2], [3, 4], [5]]
|
|
275
|
-
* ```
|
|
276
|
-
*/
|
|
277
|
-
Arr.chunksOf = (n) => (data) => {
|
|
278
|
-
if (n <= 0)
|
|
279
|
-
return [];
|
|
280
|
-
const result = [];
|
|
281
|
-
for (let i = 0; i < data.length; i += n) {
|
|
282
|
-
result.push(data.slice(i, i + n));
|
|
283
|
-
}
|
|
284
|
-
return result;
|
|
285
|
-
};
|
|
286
|
-
/**
|
|
287
|
-
* Flattens a nested array by one level.
|
|
288
|
-
*
|
|
289
|
-
* @example
|
|
290
|
-
* ```ts
|
|
291
|
-
* Arr.flatten([[1, 2], [3], [4, 5]]); // [1, 2, 3, 4, 5]
|
|
292
|
-
* ```
|
|
293
|
-
*/
|
|
294
|
-
Arr.flatten = (data) => [].concat(...data);
|
|
295
|
-
/**
|
|
296
|
-
* Maps each element to an array and flattens the result.
|
|
297
|
-
*
|
|
298
|
-
* @example
|
|
299
|
-
* ```ts
|
|
300
|
-
* pipe([1, 2, 3], Arr.flatMap(n => [n, n * 10])); // [1, 10, 2, 20, 3, 30]
|
|
301
|
-
* ```
|
|
302
|
-
*/
|
|
303
|
-
Arr.flatMap = (f) => (data) => {
|
|
304
|
-
const n = data.length;
|
|
305
|
-
const result = [];
|
|
306
|
-
for (let i = 0; i < n; i++) {
|
|
307
|
-
const chunk = f(data[i]);
|
|
308
|
-
const m = chunk.length;
|
|
309
|
-
for (let j = 0; j < m; j++)
|
|
310
|
-
result.push(chunk[j]);
|
|
311
|
-
}
|
|
312
|
-
return result;
|
|
313
|
-
};
|
|
314
|
-
/**
|
|
315
|
-
* Reduces an array from the left.
|
|
316
|
-
*
|
|
317
|
-
* @example
|
|
318
|
-
* ```ts
|
|
319
|
-
* pipe([1, 2, 3], Arr.reduce(0, (acc, n) => acc + n)); // 6
|
|
320
|
-
* ```
|
|
321
|
-
*/
|
|
322
|
-
Arr.reduce = (initial, f) => (data) => data.reduce(f, initial);
|
|
323
|
-
// --- Traverse / Sequence ---
|
|
324
|
-
/**
|
|
325
|
-
* Maps each element to an Option and collects the results.
|
|
326
|
-
* Returns None if any mapping returns None.
|
|
327
|
-
*
|
|
328
|
-
* @example
|
|
329
|
-
* ```ts
|
|
330
|
-
* const parseNum = (s: string): Option<number> => {
|
|
331
|
-
* const n = Number(s);
|
|
332
|
-
* return isNaN(n) ? Option.none() : Option.some(n);
|
|
333
|
-
* };
|
|
334
|
-
*
|
|
335
|
-
* pipe(["1", "2", "3"], Arr.traverse(parseNum)); // Some([1, 2, 3])
|
|
336
|
-
* pipe(["1", "x", "3"], Arr.traverse(parseNum)); // None
|
|
337
|
-
* ```
|
|
338
|
-
*/
|
|
339
|
-
Arr.traverse = (f) => (data) => {
|
|
340
|
-
const n = data.length;
|
|
341
|
-
const result = new Array(n);
|
|
342
|
-
for (let i = 0; i < n; i++) {
|
|
343
|
-
const mapped = f(data[i]);
|
|
344
|
-
if (mapped.kind === "None")
|
|
345
|
-
return Option.none();
|
|
346
|
-
result[i] = mapped.value;
|
|
347
|
-
}
|
|
348
|
-
return Option.some(result);
|
|
349
|
-
};
|
|
350
|
-
/**
|
|
351
|
-
* Maps each element to a Result and collects the results.
|
|
352
|
-
* Returns the first Err if any mapping fails.
|
|
353
|
-
*
|
|
354
|
-
* @example
|
|
355
|
-
* ```ts
|
|
356
|
-
* pipe(
|
|
357
|
-
* [1, 2, 3],
|
|
358
|
-
* Arr.traverseResult(n => n > 0 ? Result.ok(n) : Result.err("negative"))
|
|
359
|
-
* ); // Ok([1, 2, 3])
|
|
360
|
-
* ```
|
|
361
|
-
*/
|
|
362
|
-
Arr.traverseResult = (f) => (data) => {
|
|
363
|
-
const n = data.length;
|
|
364
|
-
const result = new Array(n);
|
|
365
|
-
for (let i = 0; i < n; i++) {
|
|
366
|
-
const mapped = f(data[i]);
|
|
367
|
-
if (mapped.kind === "Error")
|
|
368
|
-
return mapped;
|
|
369
|
-
result[i] = mapped.value;
|
|
370
|
-
}
|
|
371
|
-
return Result.ok(result);
|
|
372
|
-
};
|
|
373
|
-
/**
|
|
374
|
-
* Maps each element to a Task and runs all in parallel.
|
|
375
|
-
*
|
|
376
|
-
* @example
|
|
377
|
-
* ```ts
|
|
378
|
-
* pipe(
|
|
379
|
-
* [1, 2, 3],
|
|
380
|
-
* Arr.traverseTask(n => Task.resolve(n * 2))
|
|
381
|
-
* )(); // Promise<[2, 4, 6]>
|
|
382
|
-
* ```
|
|
383
|
-
*/
|
|
384
|
-
Arr.traverseTask = (f) => (data) => Task.from(() => Promise.all(data.map((a) => Deferred.toPromise(f(a)()))));
|
|
385
|
-
/**
|
|
386
|
-
* Collects an array of Options into an Option of array.
|
|
387
|
-
* Returns None if any element is None.
|
|
388
|
-
*
|
|
389
|
-
* @example
|
|
390
|
-
* ```ts
|
|
391
|
-
* Arr.sequence([Option.some(1), Option.some(2)]); // Some([1, 2])
|
|
392
|
-
* Arr.sequence([Option.some(1), Option.none()]); // None
|
|
393
|
-
* ```
|
|
394
|
-
*/
|
|
395
|
-
Arr.sequence = (data) => Arr.traverse((a) => a)(data);
|
|
396
|
-
/**
|
|
397
|
-
* Collects an array of Results into a Result of array.
|
|
398
|
-
* Returns the first Err if any element is Err.
|
|
399
|
-
*/
|
|
400
|
-
Arr.sequenceResult = (data) => Arr.traverseResult((a) => a)(data);
|
|
401
|
-
/**
|
|
402
|
-
* Collects an array of Tasks into a Task of array. Runs in parallel.
|
|
403
|
-
*/
|
|
404
|
-
Arr.sequenceTask = (data) => Arr.traverseTask((a) => a)(data);
|
|
405
|
-
/**
|
|
406
|
-
* Maps each element to a TaskResult and runs them sequentially.
|
|
407
|
-
* Returns the first Err encountered, or Ok of all results if all succeed.
|
|
408
|
-
*
|
|
409
|
-
* @example
|
|
410
|
-
* ```ts
|
|
411
|
-
* const validate = (n: number): TaskResult<string, number> =>
|
|
412
|
-
* n > 0 ? TaskResult.ok(n) : TaskResult.err("non-positive");
|
|
413
|
-
*
|
|
414
|
-
* pipe(
|
|
415
|
-
* [1, 2, 3],
|
|
416
|
-
* Arr.traverseTaskResult(validate)
|
|
417
|
-
* )(); // Deferred<Ok([1, 2, 3])>
|
|
418
|
-
*
|
|
419
|
-
* pipe(
|
|
420
|
-
* [1, -1, 3],
|
|
421
|
-
* Arr.traverseTaskResult(validate)
|
|
422
|
-
* )(); // Deferred<Err("non-positive")>
|
|
423
|
-
* ```
|
|
424
|
-
*/
|
|
425
|
-
Arr.traverseTaskResult = (f) => (data) => Task.from(async () => {
|
|
426
|
-
const result = [];
|
|
427
|
-
for (const a of data) {
|
|
428
|
-
const r = await Deferred.toPromise(f(a)());
|
|
429
|
-
if (Result.isErr(r))
|
|
430
|
-
return r;
|
|
431
|
-
result.push(r.value);
|
|
432
|
-
}
|
|
433
|
-
return Result.ok(result);
|
|
434
|
-
});
|
|
435
|
-
/**
|
|
436
|
-
* Collects an array of TaskResults into a TaskResult of array.
|
|
437
|
-
* Returns the first Err if any element is Err, runs sequentially.
|
|
438
|
-
*/
|
|
439
|
-
Arr.sequenceTaskResult = (data) => Arr.traverseTaskResult((a) => a)(data);
|
|
440
|
-
/**
|
|
441
|
-
* Returns true if the array is non-empty (type guard).
|
|
442
|
-
*/
|
|
443
|
-
Arr.isNonEmpty = (data) => isNonEmptyList(data);
|
|
444
|
-
/**
|
|
445
|
-
* Returns the length of an array.
|
|
446
|
-
*/
|
|
447
|
-
Arr.size = (data) => data.length;
|
|
448
|
-
/**
|
|
449
|
-
* Returns true if any element satisfies the predicate.
|
|
450
|
-
*
|
|
451
|
-
* @example
|
|
452
|
-
* ```ts
|
|
453
|
-
* pipe([1, 2, 3], Arr.some(n => n > 2)); // true
|
|
454
|
-
* ```
|
|
455
|
-
*/
|
|
456
|
-
Arr.some = (predicate) => (data) => {
|
|
457
|
-
const n = data.length;
|
|
458
|
-
for (let i = 0; i < n; i++)
|
|
459
|
-
if (predicate(data[i]))
|
|
460
|
-
return true;
|
|
461
|
-
return false;
|
|
462
|
-
};
|
|
463
|
-
/**
|
|
464
|
-
* Returns true if all elements satisfy the predicate.
|
|
465
|
-
*
|
|
466
|
-
* @example
|
|
467
|
-
* ```ts
|
|
468
|
-
* pipe([1, 2, 3], Arr.every(n => n > 0)); // true
|
|
469
|
-
* ```
|
|
470
|
-
*/
|
|
471
|
-
Arr.every = (predicate) => (data) => {
|
|
472
|
-
const n = data.length;
|
|
473
|
-
for (let i = 0; i < n; i++)
|
|
474
|
-
if (!predicate(data[i]))
|
|
475
|
-
return false;
|
|
476
|
-
return true;
|
|
477
|
-
};
|
|
478
|
-
/**
|
|
479
|
-
* Reverses an array. Returns a new array.
|
|
480
|
-
*
|
|
481
|
-
* @example
|
|
482
|
-
* ```ts
|
|
483
|
-
* Arr.reverse([1, 2, 3]); // [3, 2, 1]
|
|
484
|
-
* ```
|
|
485
|
-
*/
|
|
486
|
-
Arr.reverse = (data) => [...data].reverse();
|
|
487
|
-
/**
|
|
488
|
-
* Takes the first n elements from an array.
|
|
489
|
-
*
|
|
490
|
-
* @example
|
|
491
|
-
* ```ts
|
|
492
|
-
* pipe([1, 2, 3, 4], Arr.take(2)); // [1, 2]
|
|
493
|
-
* ```
|
|
494
|
-
*/
|
|
495
|
-
Arr.take = (n) => (data) => n <= 0 ? [] : data.slice(0, n);
|
|
496
|
-
/**
|
|
497
|
-
* Drops the first n elements from an array.
|
|
498
|
-
*
|
|
499
|
-
* @example
|
|
500
|
-
* ```ts
|
|
501
|
-
* pipe([1, 2, 3, 4], Arr.drop(2)); // [3, 4]
|
|
502
|
-
* ```
|
|
503
|
-
*/
|
|
504
|
-
Arr.drop = (n) => (data) => data.slice(n);
|
|
505
|
-
/**
|
|
506
|
-
* Takes elements from the start while the predicate holds.
|
|
507
|
-
*
|
|
508
|
-
* @example
|
|
509
|
-
* ```ts
|
|
510
|
-
* pipe([1, 2, 3, 1], Arr.takeWhile(n => n < 3)); // [1, 2]
|
|
511
|
-
* ```
|
|
512
|
-
*/
|
|
513
|
-
Arr.takeWhile = (predicate) => (data) => {
|
|
514
|
-
const result = [];
|
|
515
|
-
for (const a of data) {
|
|
516
|
-
if (!predicate(a))
|
|
517
|
-
break;
|
|
518
|
-
result.push(a);
|
|
519
|
-
}
|
|
520
|
-
return result;
|
|
521
|
-
};
|
|
522
|
-
/**
|
|
523
|
-
* Drops elements from the start while the predicate holds.
|
|
524
|
-
*
|
|
525
|
-
* @example
|
|
526
|
-
* ```ts
|
|
527
|
-
* pipe([1, 2, 3, 1], Arr.dropWhile(n => n < 3)); // [3, 1]
|
|
528
|
-
* ```
|
|
529
|
-
*/
|
|
530
|
-
Arr.dropWhile = (predicate) => (data) => {
|
|
531
|
-
let i = 0;
|
|
532
|
-
while (i < data.length && predicate(data[i]))
|
|
533
|
-
i++;
|
|
534
|
-
return data.slice(i);
|
|
535
|
-
};
|
|
536
|
-
/**
|
|
537
|
-
* Like `reduce`, but returns every intermediate accumulator as an array.
|
|
538
|
-
* The initial value is not included — the output has the same length as the input.
|
|
539
|
-
*
|
|
540
|
-
* @example
|
|
541
|
-
* ```ts
|
|
542
|
-
* pipe([1, 2, 3], Arr.scan(0, (acc, n) => acc + n)); // [1, 3, 6]
|
|
543
|
-
* ```
|
|
544
|
-
*/
|
|
545
|
-
Arr.scan = (initial, f) => (data) => {
|
|
546
|
-
const n = data.length;
|
|
547
|
-
const result = new Array(n);
|
|
548
|
-
let acc = initial;
|
|
549
|
-
for (let i = 0; i < n; i++) {
|
|
550
|
-
acc = f(acc, data[i]);
|
|
551
|
-
result[i] = acc;
|
|
552
|
-
}
|
|
553
|
-
return result;
|
|
554
|
-
};
|
|
555
|
-
/**
|
|
556
|
-
* Splits an array at an index into a `[before, after]` tuple.
|
|
557
|
-
* Negative indices clamp to 0; indices beyond the array length clamp to the end.
|
|
558
|
-
*
|
|
559
|
-
* @example
|
|
560
|
-
* ```ts
|
|
561
|
-
* pipe([1, 2, 3, 4], Arr.splitAt(2)); // [[1, 2], [3, 4]]
|
|
562
|
-
* pipe([1, 2, 3], Arr.splitAt(0)); // [[], [1, 2, 3]]
|
|
563
|
-
* pipe([1, 2, 3], Arr.splitAt(10)); // [[1, 2, 3], []]
|
|
564
|
-
* ```
|
|
565
|
-
*/
|
|
566
|
-
Arr.splitAt = (index) => (data) => {
|
|
567
|
-
const i = Math.max(0, index);
|
|
568
|
-
return [data.slice(0, i), data.slice(i)];
|
|
569
|
-
};
|
|
570
|
-
})(Arr || (Arr = {}));
|