@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.
Files changed (213) hide show
  1. package/LICENCE +28 -0
  2. package/README.md +1 -1
  3. package/{types/src/Types/NonEmptyList.d.ts → dist/NonEmptyList-BlGFjor5.d.mts} +4 -3
  4. package/dist/NonEmptyList-BlGFjor5.d.ts +30 -0
  5. package/dist/Task-Bd3gXPRQ.d.mts +677 -0
  6. package/dist/Task-BjAkkD6t.d.ts +677 -0
  7. package/dist/chunk-4TXC322E.mjs +136 -0
  8. package/dist/chunk-BYWKZLHM.mjs +10 -0
  9. package/dist/chunk-DBIC62UV.mjs +6 -0
  10. package/dist/chunk-FAZN3IWZ.mjs +554 -0
  11. package/dist/chunk-QPTGO5AS.mjs +150 -0
  12. package/dist/chunk-UV2HMF2A.mjs +514 -0
  13. package/dist/composition.d.mts +495 -0
  14. package/dist/composition.d.ts +495 -0
  15. package/dist/composition.js +188 -0
  16. package/dist/composition.mjs +58 -0
  17. package/dist/core.d.mts +2170 -0
  18. package/dist/core.d.ts +2170 -0
  19. package/dist/core.js +698 -0
  20. package/dist/core.mjs +42 -0
  21. package/dist/index.d.mts +6 -0
  22. package/dist/index.d.ts +6 -0
  23. package/dist/index.js +1421 -0
  24. package/dist/index.mjs +120 -0
  25. package/dist/types.d.mts +54 -0
  26. package/{types/src/Types/Brand.d.ts → dist/types.d.ts} +6 -4
  27. package/dist/types.js +41 -0
  28. package/dist/types.mjs +10 -0
  29. package/dist/utils.d.mts +1285 -0
  30. package/dist/utils.d.ts +1285 -0
  31. package/dist/utils.js +722 -0
  32. package/dist/utils.mjs +18 -0
  33. package/package.json +64 -69
  34. package/esm/mod.js +0 -3
  35. package/esm/package.json +0 -3
  36. package/esm/src/Composition/compose.js +0 -3
  37. package/esm/src/Composition/converge.js +0 -3
  38. package/esm/src/Composition/curry.js +0 -42
  39. package/esm/src/Composition/flip.js +0 -20
  40. package/esm/src/Composition/flow.js +0 -8
  41. package/esm/src/Composition/fn.js +0 -85
  42. package/esm/src/Composition/index.js +0 -13
  43. package/esm/src/Composition/juxt.js +0 -3
  44. package/esm/src/Composition/memoize.js +0 -66
  45. package/esm/src/Composition/not.js +0 -25
  46. package/esm/src/Composition/on.js +0 -12
  47. package/esm/src/Composition/pipe.js +0 -3
  48. package/esm/src/Composition/tap.js +0 -33
  49. package/esm/src/Composition/uncurry.js +0 -32
  50. package/esm/src/Core/Deferred.js +0 -30
  51. package/esm/src/Core/InternalTypes.js +0 -1
  52. package/esm/src/Core/Lens.js +0 -98
  53. package/esm/src/Core/Logged.js +0 -111
  54. package/esm/src/Core/Option.js +0 -191
  55. package/esm/src/Core/Optional.js +0 -160
  56. package/esm/src/Core/Predicate.js +0 -133
  57. package/esm/src/Core/Reader.js +0 -134
  58. package/esm/src/Core/Refinement.js +0 -115
  59. package/esm/src/Core/RemoteData.js +0 -211
  60. package/esm/src/Core/Result.js +0 -170
  61. package/esm/src/Core/State.js +0 -181
  62. package/esm/src/Core/Task.js +0 -223
  63. package/esm/src/Core/TaskOption.js +0 -106
  64. package/esm/src/Core/TaskResult.js +0 -127
  65. package/esm/src/Core/TaskValidation.js +0 -128
  66. package/esm/src/Core/These.js +0 -245
  67. package/esm/src/Core/Tuple.js +0 -112
  68. package/esm/src/Core/Validation.js +0 -212
  69. package/esm/src/Core/index.js +0 -18
  70. package/esm/src/Types/Brand.js +0 -28
  71. package/esm/src/Types/NonEmptyList.js +0 -14
  72. package/esm/src/Types/index.js +0 -2
  73. package/esm/src/Utils/Arr.js +0 -570
  74. package/esm/src/Utils/Dict.js +0 -421
  75. package/esm/src/Utils/Num.js +0 -124
  76. package/esm/src/Utils/Rec.js +0 -241
  77. package/esm/src/Utils/Str.js +0 -134
  78. package/esm/src/Utils/Uniq.js +0 -265
  79. package/esm/src/Utils/index.js +0 -6
  80. package/script/mod.js +0 -19
  81. package/script/package.json +0 -3
  82. package/script/src/Composition/compose.js +0 -6
  83. package/script/src/Composition/converge.js +0 -6
  84. package/script/src/Composition/curry.js +0 -48
  85. package/script/src/Composition/flip.js +0 -24
  86. package/script/src/Composition/flow.js +0 -11
  87. package/script/src/Composition/fn.js +0 -98
  88. package/script/src/Composition/index.js +0 -29
  89. package/script/src/Composition/juxt.js +0 -6
  90. package/script/src/Composition/memoize.js +0 -71
  91. package/script/src/Composition/not.js +0 -29
  92. package/script/src/Composition/on.js +0 -16
  93. package/script/src/Composition/pipe.js +0 -6
  94. package/script/src/Composition/tap.js +0 -37
  95. package/script/src/Composition/uncurry.js +0 -38
  96. package/script/src/Core/Deferred.js +0 -33
  97. package/script/src/Core/InternalTypes.js +0 -2
  98. package/script/src/Core/Lens.js +0 -101
  99. package/script/src/Core/Logged.js +0 -114
  100. package/script/src/Core/Option.js +0 -194
  101. package/script/src/Core/Optional.js +0 -163
  102. package/script/src/Core/Predicate.js +0 -136
  103. package/script/src/Core/Reader.js +0 -137
  104. package/script/src/Core/Refinement.js +0 -118
  105. package/script/src/Core/RemoteData.js +0 -214
  106. package/script/src/Core/Result.js +0 -173
  107. package/script/src/Core/State.js +0 -184
  108. package/script/src/Core/Task.js +0 -226
  109. package/script/src/Core/TaskOption.js +0 -109
  110. package/script/src/Core/TaskResult.js +0 -130
  111. package/script/src/Core/TaskValidation.js +0 -131
  112. package/script/src/Core/These.js +0 -248
  113. package/script/src/Core/Tuple.js +0 -115
  114. package/script/src/Core/Validation.js +0 -215
  115. package/script/src/Core/index.js +0 -34
  116. package/script/src/Types/Brand.js +0 -31
  117. package/script/src/Types/NonEmptyList.js +0 -18
  118. package/script/src/Types/index.js +0 -18
  119. package/script/src/Utils/Arr.js +0 -573
  120. package/script/src/Utils/Dict.js +0 -424
  121. package/script/src/Utils/Num.js +0 -127
  122. package/script/src/Utils/Rec.js +0 -244
  123. package/script/src/Utils/Str.js +0 -137
  124. package/script/src/Utils/Uniq.js +0 -268
  125. package/script/src/Utils/index.js +0 -22
  126. package/types/mod.d.ts +0 -4
  127. package/types/mod.d.ts.map +0 -1
  128. package/types/src/Composition/compose.d.ts +0 -33
  129. package/types/src/Composition/compose.d.ts.map +0 -1
  130. package/types/src/Composition/converge.d.ts +0 -21
  131. package/types/src/Composition/converge.d.ts.map +0 -1
  132. package/types/src/Composition/curry.d.ts +0 -43
  133. package/types/src/Composition/curry.d.ts.map +0 -1
  134. package/types/src/Composition/flip.d.ts +0 -21
  135. package/types/src/Composition/flip.d.ts.map +0 -1
  136. package/types/src/Composition/flow.d.ts +0 -56
  137. package/types/src/Composition/flow.d.ts.map +0 -1
  138. package/types/src/Composition/fn.d.ts +0 -76
  139. package/types/src/Composition/fn.d.ts.map +0 -1
  140. package/types/src/Composition/index.d.ts +0 -14
  141. package/types/src/Composition/index.d.ts.map +0 -1
  142. package/types/src/Composition/juxt.d.ts +0 -18
  143. package/types/src/Composition/juxt.d.ts.map +0 -1
  144. package/types/src/Composition/memoize.d.ts +0 -46
  145. package/types/src/Composition/memoize.d.ts.map +0 -1
  146. package/types/src/Composition/not.d.ts +0 -26
  147. package/types/src/Composition/not.d.ts.map +0 -1
  148. package/types/src/Composition/on.d.ts +0 -13
  149. package/types/src/Composition/on.d.ts.map +0 -1
  150. package/types/src/Composition/pipe.d.ts +0 -56
  151. package/types/src/Composition/pipe.d.ts.map +0 -1
  152. package/types/src/Composition/tap.d.ts +0 -31
  153. package/types/src/Composition/tap.d.ts.map +0 -1
  154. package/types/src/Composition/uncurry.d.ts +0 -54
  155. package/types/src/Composition/uncurry.d.ts.map +0 -1
  156. package/types/src/Core/Deferred.d.ts +0 -49
  157. package/types/src/Core/Deferred.d.ts.map +0 -1
  158. package/types/src/Core/InternalTypes.d.ts +0 -23
  159. package/types/src/Core/InternalTypes.d.ts.map +0 -1
  160. package/types/src/Core/Lens.d.ts +0 -118
  161. package/types/src/Core/Lens.d.ts.map +0 -1
  162. package/types/src/Core/Logged.d.ts +0 -126
  163. package/types/src/Core/Logged.d.ts.map +0 -1
  164. package/types/src/Core/Option.d.ts +0 -209
  165. package/types/src/Core/Option.d.ts.map +0 -1
  166. package/types/src/Core/Optional.d.ts +0 -158
  167. package/types/src/Core/Optional.d.ts.map +0 -1
  168. package/types/src/Core/Predicate.d.ts +0 -161
  169. package/types/src/Core/Predicate.d.ts.map +0 -1
  170. package/types/src/Core/Reader.d.ts +0 -156
  171. package/types/src/Core/Reader.d.ts.map +0 -1
  172. package/types/src/Core/Refinement.d.ts +0 -138
  173. package/types/src/Core/Refinement.d.ts.map +0 -1
  174. package/types/src/Core/RemoteData.d.ts +0 -197
  175. package/types/src/Core/RemoteData.d.ts.map +0 -1
  176. package/types/src/Core/Result.d.ts +0 -182
  177. package/types/src/Core/Result.d.ts.map +0 -1
  178. package/types/src/Core/State.d.ts +0 -192
  179. package/types/src/Core/State.d.ts.map +0 -1
  180. package/types/src/Core/Task.d.ts +0 -219
  181. package/types/src/Core/Task.d.ts.map +0 -1
  182. package/types/src/Core/TaskOption.d.ts +0 -121
  183. package/types/src/Core/TaskOption.d.ts.map +0 -1
  184. package/types/src/Core/TaskResult.d.ts +0 -119
  185. package/types/src/Core/TaskResult.d.ts.map +0 -1
  186. package/types/src/Core/TaskValidation.d.ts +0 -144
  187. package/types/src/Core/TaskValidation.d.ts.map +0 -1
  188. package/types/src/Core/These.d.ts +0 -225
  189. package/types/src/Core/These.d.ts.map +0 -1
  190. package/types/src/Core/Tuple.d.ts +0 -129
  191. package/types/src/Core/Tuple.d.ts.map +0 -1
  192. package/types/src/Core/Validation.d.ts +0 -203
  193. package/types/src/Core/Validation.d.ts.map +0 -1
  194. package/types/src/Core/index.d.ts +0 -19
  195. package/types/src/Core/index.d.ts.map +0 -1
  196. package/types/src/Types/Brand.d.ts.map +0 -1
  197. package/types/src/Types/NonEmptyList.d.ts.map +0 -1
  198. package/types/src/Types/index.d.ts +0 -3
  199. package/types/src/Types/index.d.ts.map +0 -1
  200. package/types/src/Utils/Arr.d.ts +0 -403
  201. package/types/src/Utils/Arr.d.ts.map +0 -1
  202. package/types/src/Utils/Dict.d.ts +0 -310
  203. package/types/src/Utils/Dict.d.ts.map +0 -1
  204. package/types/src/Utils/Num.d.ts +0 -110
  205. package/types/src/Utils/Num.d.ts.map +0 -1
  206. package/types/src/Utils/Rec.d.ts +0 -159
  207. package/types/src/Utils/Rec.d.ts.map +0 -1
  208. package/types/src/Utils/Str.d.ts +0 -128
  209. package/types/src/Utils/Str.d.ts.map +0 -1
  210. package/types/src/Utils/Uniq.d.ts +0 -179
  211. package/types/src/Utils/Uniq.d.ts.map +0 -1
  212. package/types/src/Utils/index.d.ts +0 -7
  213. package/types/src/Utils/index.d.ts.map +0 -1
@@ -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";
@@ -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;
@@ -1,2 +0,0 @@
1
- export * from "./Brand.js";
2
- export * from "./NonEmptyList.js";
@@ -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 = {}));