@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
@@ -0,0 +1,1285 @@
1
+ import { a as Option, R as Result, T as Task } from './Task-BjAkkD6t.js';
2
+ import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.js';
3
+
4
+ /**
5
+ * Functional array utilities that compose well with pipe.
6
+ * All functions are data-last and curried where applicable.
7
+ * Safe access functions return Option instead of throwing or returning undefined.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * pipe(
12
+ * [1, 2, 3, 4, 5],
13
+ * Arr.filter(n => n > 2),
14
+ * Arr.map(n => n * 10),
15
+ * Arr.head
16
+ * ); // Some(30)
17
+ * ```
18
+ */
19
+ declare namespace Arr {
20
+ /**
21
+ * Returns the first element of an array, or None if the array is empty.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * Arr.head([1, 2, 3]); // Some(1)
26
+ * Arr.head([]); // None
27
+ * ```
28
+ */
29
+ const head: <A>(data: readonly A[]) => Option<A>;
30
+ /**
31
+ * Returns the last element of an array, or None if the array is empty.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * Arr.last([1, 2, 3]); // Some(3)
36
+ * Arr.last([]); // None
37
+ * ```
38
+ */
39
+ const last: <A>(data: readonly A[]) => Option<A>;
40
+ /**
41
+ * Returns all elements except the first, or None if the array is empty.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * Arr.tail([1, 2, 3]); // Some([2, 3])
46
+ * Arr.tail([]); // None
47
+ * ```
48
+ */
49
+ const tail: <A>(data: readonly A[]) => Option<readonly A[]>;
50
+ /**
51
+ * Returns all elements except the last, or None if the array is empty.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * Arr.init([1, 2, 3]); // Some([1, 2])
56
+ * Arr.init([]); // None
57
+ * ```
58
+ */
59
+ const init: <A>(data: readonly A[]) => Option<readonly A[]>;
60
+ /**
61
+ * Returns the first element matching the predicate, or None.
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * pipe([1, 2, 3, 4], Arr.findFirst(n => n > 2)); // Some(3)
66
+ * ```
67
+ */
68
+ const findFirst: <A>(predicate: (a: A) => boolean) => (data: readonly A[]) => Option<A>;
69
+ /**
70
+ * Returns the last element matching the predicate, or None.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * pipe([1, 2, 3, 4], Arr.findLast(n => n > 2)); // Some(4)
75
+ * ```
76
+ */
77
+ const findLast: <A>(predicate: (a: A) => boolean) => (data: readonly A[]) => Option<A>;
78
+ /**
79
+ * Returns the index of the first element matching the predicate, or None.
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * pipe([1, 2, 3, 4], Arr.findIndex(n => n > 2)); // Some(2)
84
+ * ```
85
+ */
86
+ const findIndex: <A>(predicate: (a: A) => boolean) => (data: readonly A[]) => Option<number>;
87
+ /**
88
+ * Transforms each element of an array.
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * pipe([1, 2, 3], Arr.map(n => n * 2)); // [2, 4, 6]
93
+ * ```
94
+ */
95
+ const map: <A, B>(f: (a: A) => B) => (data: readonly A[]) => readonly B[];
96
+ /**
97
+ * Filters elements that satisfy the predicate.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * pipe([1, 2, 3, 4], Arr.filter(n => n % 2 === 0)); // [2, 4]
102
+ * ```
103
+ */
104
+ const filter: <A>(predicate: (a: A) => boolean) => (data: readonly A[]) => readonly A[];
105
+ /**
106
+ * Splits an array into two groups based on a predicate.
107
+ * First group contains elements that satisfy the predicate,
108
+ * second group contains the rest.
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * pipe([1, 2, 3, 4], Arr.partition(n => n % 2 === 0)); // [[2, 4], [1, 3]]
113
+ * ```
114
+ */
115
+ const partition: <A>(predicate: (a: A) => boolean) => (data: readonly A[]) => readonly [readonly A[], readonly A[]];
116
+ /**
117
+ * Groups elements by a key function.
118
+ *
119
+ * @example
120
+ * ```ts
121
+ * pipe(
122
+ * ["apple", "avocado", "banana"],
123
+ * Arr.groupBy(s => s[0])
124
+ * ); // { a: ["apple", "avocado"], b: ["banana"] }
125
+ * ```
126
+ */
127
+ const groupBy: <A>(f: (a: A) => string) => (data: readonly A[]) => Record<string, NonEmptyList<A>>;
128
+ /**
129
+ * Removes duplicate elements using strict equality.
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * Arr.uniq([1, 2, 2, 3, 1]); // [1, 2, 3]
134
+ * ```
135
+ */
136
+ const uniq: <A>(data: readonly A[]) => readonly A[];
137
+ /**
138
+ * Removes duplicate elements by comparing the result of a key function.
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * pipe(
143
+ * [{id: 1, name: "a"}, {id: 1, name: "b"}, {id: 2, name: "c"}],
144
+ * Arr.uniqBy(x => x.id)
145
+ * ); // [{id: 1, name: "a"}, {id: 2, name: "c"}]
146
+ * ```
147
+ */
148
+ const uniqBy: <A, B>(f: (a: A) => B) => (data: readonly A[]) => readonly A[];
149
+ /**
150
+ * Sorts an array using a comparison function. Returns a new array.
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * pipe([3, 1, 2], Arr.sortBy((a, b) => a - b)); // [1, 2, 3]
155
+ * ```
156
+ */
157
+ const sortBy: <A>(compare: (a: A, b: A) => number) => (data: readonly A[]) => readonly A[];
158
+ /**
159
+ * Pairs up elements from two arrays. Stops at the shorter array.
160
+ *
161
+ * @example
162
+ * ```ts
163
+ * pipe([1, 2, 3], Arr.zip(["a", "b"])); // [[1, "a"], [2, "b"]]
164
+ * ```
165
+ */
166
+ const zip: <B>(other: readonly B[]) => <A>(data: readonly A[]) => readonly (readonly [A, B])[];
167
+ /**
168
+ * Combines elements from two arrays using a function. Stops at the shorter array.
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * pipe([1, 2], Arr.zipWith((a, b) => a + b, ["a", "b"])); // ["1a", "2b"]
173
+ * ```
174
+ */
175
+ const zipWith: <A, B, C>(f: (a: A, b: B) => C) => (other: readonly B[]) => (data: readonly A[]) => readonly C[];
176
+ /**
177
+ * Inserts a separator between every element.
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * pipe([1, 2, 3], Arr.intersperse(0)); // [1, 0, 2, 0, 3]
182
+ * ```
183
+ */
184
+ const intersperse: <A>(sep: A) => (data: readonly A[]) => readonly A[];
185
+ /**
186
+ * Splits an array into chunks of the given size.
187
+ *
188
+ * @example
189
+ * ```ts
190
+ * pipe([1, 2, 3, 4, 5], Arr.chunksOf(2)); // [[1, 2], [3, 4], [5]]
191
+ * ```
192
+ */
193
+ const chunksOf: (n: number) => <A>(data: readonly A[]) => readonly (readonly A[])[];
194
+ /**
195
+ * Flattens a nested array by one level.
196
+ *
197
+ * @example
198
+ * ```ts
199
+ * Arr.flatten([[1, 2], [3], [4, 5]]); // [1, 2, 3, 4, 5]
200
+ * ```
201
+ */
202
+ const flatten: <A>(data: readonly (readonly A[])[]) => readonly A[];
203
+ /**
204
+ * Maps each element to an array and flattens the result.
205
+ *
206
+ * @example
207
+ * ```ts
208
+ * pipe([1, 2, 3], Arr.flatMap(n => [n, n * 10])); // [1, 10, 2, 20, 3, 30]
209
+ * ```
210
+ */
211
+ const flatMap: <A, B>(f: (a: A) => readonly B[]) => (data: readonly A[]) => readonly B[];
212
+ /**
213
+ * Reduces an array from the left.
214
+ *
215
+ * @example
216
+ * ```ts
217
+ * pipe([1, 2, 3], Arr.reduce(0, (acc, n) => acc + n)); // 6
218
+ * ```
219
+ */
220
+ const reduce: <A, B>(initial: B, f: (acc: B, a: A) => B) => (data: readonly A[]) => B;
221
+ /**
222
+ * Maps each element to an Option and collects the results.
223
+ * Returns None if any mapping returns None.
224
+ *
225
+ * @example
226
+ * ```ts
227
+ * const parseNum = (s: string): Option<number> => {
228
+ * const n = Number(s);
229
+ * return isNaN(n) ? Option.none() : Option.some(n);
230
+ * };
231
+ *
232
+ * pipe(["1", "2", "3"], Arr.traverse(parseNum)); // Some([1, 2, 3])
233
+ * pipe(["1", "x", "3"], Arr.traverse(parseNum)); // None
234
+ * ```
235
+ */
236
+ const traverse: <A, B>(f: (a: A) => Option<B>) => (data: readonly A[]) => Option<readonly B[]>;
237
+ /**
238
+ * Maps each element to a Result and collects the results.
239
+ * Returns the first Err if any mapping fails.
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * pipe(
244
+ * [1, 2, 3],
245
+ * Arr.traverseResult(n => n > 0 ? Result.ok(n) : Result.err("negative"))
246
+ * ); // Ok([1, 2, 3])
247
+ * ```
248
+ */
249
+ const traverseResult: <E, A, B>(f: (a: A) => Result<E, B>) => (data: readonly A[]) => Result<E, readonly B[]>;
250
+ /**
251
+ * Maps each element to a Task and runs all in parallel.
252
+ *
253
+ * @example
254
+ * ```ts
255
+ * pipe(
256
+ * [1, 2, 3],
257
+ * Arr.traverseTask(n => Task.resolve(n * 2))
258
+ * )(); // Promise<[2, 4, 6]>
259
+ * ```
260
+ */
261
+ const traverseTask: <A, B>(f: (a: A) => Task<B>) => (data: readonly A[]) => Task<readonly B[]>;
262
+ /**
263
+ * Collects an array of Options into an Option of array.
264
+ * Returns None if any element is None.
265
+ *
266
+ * @example
267
+ * ```ts
268
+ * Arr.sequence([Option.some(1), Option.some(2)]); // Some([1, 2])
269
+ * Arr.sequence([Option.some(1), Option.none()]); // None
270
+ * ```
271
+ */
272
+ const sequence: <A>(data: readonly Option<A>[]) => Option<readonly A[]>;
273
+ /**
274
+ * Collects an array of Results into a Result of array.
275
+ * Returns the first Err if any element is Err.
276
+ */
277
+ const sequenceResult: <E, A>(data: readonly Result<E, A>[]) => Result<E, readonly A[]>;
278
+ /**
279
+ * Collects an array of Tasks into a Task of array. Runs in parallel.
280
+ */
281
+ const sequenceTask: <A>(data: readonly Task<A>[]) => Task<readonly A[]>;
282
+ /**
283
+ * Maps each element to a TaskResult and runs them sequentially.
284
+ * Returns the first Err encountered, or Ok of all results if all succeed.
285
+ *
286
+ * @example
287
+ * ```ts
288
+ * const validate = (n: number): TaskResult<string, number> =>
289
+ * n > 0 ? TaskResult.ok(n) : TaskResult.err("non-positive");
290
+ *
291
+ * pipe(
292
+ * [1, 2, 3],
293
+ * Arr.traverseTaskResult(validate)
294
+ * )(); // Deferred<Ok([1, 2, 3])>
295
+ *
296
+ * pipe(
297
+ * [1, -1, 3],
298
+ * Arr.traverseTaskResult(validate)
299
+ * )(); // Deferred<Err("non-positive")>
300
+ * ```
301
+ */
302
+ const traverseTaskResult: <E, A, B>(f: (a: A) => Task<Result<E, B>>) => (data: readonly A[]) => Task<Result<E, readonly B[]>>;
303
+ /**
304
+ * Collects an array of TaskResults into a TaskResult of array.
305
+ * Returns the first Err if any element is Err, runs sequentially.
306
+ */
307
+ const sequenceTaskResult: <E, A>(data: readonly Task<Result<E, A>>[]) => Task<Result<E, readonly A[]>>;
308
+ /**
309
+ * Returns true if the array is non-empty (type guard).
310
+ */
311
+ const isNonEmpty: <A>(data: readonly A[]) => data is NonEmptyList<A>;
312
+ /**
313
+ * Returns the length of an array.
314
+ */
315
+ const size: <A>(data: readonly A[]) => number;
316
+ /**
317
+ * Returns true if any element satisfies the predicate.
318
+ *
319
+ * @example
320
+ * ```ts
321
+ * pipe([1, 2, 3], Arr.some(n => n > 2)); // true
322
+ * ```
323
+ */
324
+ const some: <A>(predicate: (a: A) => boolean) => (data: readonly A[]) => boolean;
325
+ /**
326
+ * Returns true if all elements satisfy the predicate.
327
+ *
328
+ * @example
329
+ * ```ts
330
+ * pipe([1, 2, 3], Arr.every(n => n > 0)); // true
331
+ * ```
332
+ */
333
+ const every: <A>(predicate: (a: A) => boolean) => (data: readonly A[]) => boolean;
334
+ /**
335
+ * Reverses an array. Returns a new array.
336
+ *
337
+ * @example
338
+ * ```ts
339
+ * Arr.reverse([1, 2, 3]); // [3, 2, 1]
340
+ * ```
341
+ */
342
+ const reverse: <A>(data: readonly A[]) => readonly A[];
343
+ /**
344
+ * Takes the first n elements from an array.
345
+ *
346
+ * @example
347
+ * ```ts
348
+ * pipe([1, 2, 3, 4], Arr.take(2)); // [1, 2]
349
+ * ```
350
+ */
351
+ const take: (n: number) => <A>(data: readonly A[]) => readonly A[];
352
+ /**
353
+ * Drops the first n elements from an array.
354
+ *
355
+ * @example
356
+ * ```ts
357
+ * pipe([1, 2, 3, 4], Arr.drop(2)); // [3, 4]
358
+ * ```
359
+ */
360
+ const drop: (n: number) => <A>(data: readonly A[]) => readonly A[];
361
+ /**
362
+ * Takes elements from the start while the predicate holds.
363
+ *
364
+ * @example
365
+ * ```ts
366
+ * pipe([1, 2, 3, 1], Arr.takeWhile(n => n < 3)); // [1, 2]
367
+ * ```
368
+ */
369
+ const takeWhile: <A>(predicate: (a: A) => boolean) => (data: readonly A[]) => readonly A[];
370
+ /**
371
+ * Drops elements from the start while the predicate holds.
372
+ *
373
+ * @example
374
+ * ```ts
375
+ * pipe([1, 2, 3, 1], Arr.dropWhile(n => n < 3)); // [3, 1]
376
+ * ```
377
+ */
378
+ const dropWhile: <A>(predicate: (a: A) => boolean) => (data: readonly A[]) => readonly A[];
379
+ /**
380
+ * Like `reduce`, but returns every intermediate accumulator as an array.
381
+ * The initial value is not included — the output has the same length as the input.
382
+ *
383
+ * @example
384
+ * ```ts
385
+ * pipe([1, 2, 3], Arr.scan(0, (acc, n) => acc + n)); // [1, 3, 6]
386
+ * ```
387
+ */
388
+ const scan: <A, B>(initial: B, f: (acc: B, a: A) => B) => (data: readonly A[]) => readonly B[];
389
+ /**
390
+ * Splits an array at an index into a `[before, after]` tuple.
391
+ * Negative indices clamp to 0; indices beyond the array length clamp to the end.
392
+ *
393
+ * @example
394
+ * ```ts
395
+ * pipe([1, 2, 3, 4], Arr.splitAt(2)); // [[1, 2], [3, 4]]
396
+ * pipe([1, 2, 3], Arr.splitAt(0)); // [[], [1, 2, 3]]
397
+ * pipe([1, 2, 3], Arr.splitAt(10)); // [[1, 2, 3], []]
398
+ * ```
399
+ */
400
+ const splitAt: (index: number) => <A>(data: readonly A[]) => readonly [readonly A[], readonly A[]];
401
+ }
402
+
403
+ /**
404
+ * Functional utilities for key-value dictionaries (`ReadonlyMap<K, V>`). All functions are pure
405
+ * and data-last — they compose naturally with `pipe`.
406
+ *
407
+ * Unlike plain objects (`Rec`), dictionaries support any key type, preserve insertion order, and
408
+ * make membership checks explicit via `lookup` returning `Option`.
409
+ *
410
+ * @example
411
+ * ```ts
412
+ * import { Dict } from "@nlozgachev/pipelined/utils";
413
+ * import { pipe } from "@nlozgachev/pipelined/composition";
414
+ *
415
+ * const scores = pipe(
416
+ * Dict.fromEntries([["alice", 10], ["bob", 8], ["carol", 10]] as const),
417
+ * Dict.filter(n => n >= 10),
418
+ * Dict.map(n => `${n} points`),
419
+ * );
420
+ * // ReadonlyMap { "alice" => "10 points", "carol" => "10 points" }
421
+ * ```
422
+ */
423
+ declare namespace Dict {
424
+ /**
425
+ * Creates an empty dictionary.
426
+ *
427
+ * @example
428
+ * ```ts
429
+ * Dict.empty<string, number>(); // ReadonlyMap {}
430
+ * ```
431
+ */
432
+ const empty: <K, V>() => ReadonlyMap<K, V>;
433
+ /**
434
+ * Creates a dictionary with a single entry.
435
+ *
436
+ * @example
437
+ * ```ts
438
+ * Dict.singleton("name", "Alice"); // ReadonlyMap { "name" => "Alice" }
439
+ * ```
440
+ */
441
+ const singleton: <K, V>(key: K, value: V) => ReadonlyMap<K, V>;
442
+ /**
443
+ * Creates a dictionary from an array of key-value pairs.
444
+ *
445
+ * @example
446
+ * ```ts
447
+ * Dict.fromEntries([["a", 1], ["b", 2]]); // ReadonlyMap { "a" => 1, "b" => 2 }
448
+ * ```
449
+ */
450
+ const fromEntries: <K, V>(entries: readonly (readonly [K, V])[]) => ReadonlyMap<K, V>;
451
+ /**
452
+ * Creates a dictionary from a plain object. Keys are always strings.
453
+ *
454
+ * @example
455
+ * ```ts
456
+ * Dict.fromRecord({ a: 1, b: 2 }); // ReadonlyMap { "a" => 1, "b" => 2 }
457
+ * ```
458
+ */
459
+ const fromRecord: <V>(rec: Readonly<Record<string, V>>) => ReadonlyMap<string, V>;
460
+ /**
461
+ * Groups elements of an array into a dictionary keyed by the result of `keyFn`. Each key maps
462
+ * to the array of elements that produced it, in insertion order. Uses the native `Map.groupBy`
463
+ * when available, falling back to a manual loop in older environments.
464
+ *
465
+ * @example
466
+ * ```ts
467
+ * pipe(
468
+ * [{ name: "alice", role: "admin" }, { name: "bob", role: "viewer" }, { name: "carol", role: "admin" }],
469
+ * Dict.groupBy(user => user.role),
470
+ * );
471
+ * // ReadonlyMap { "admin" => [alice, carol], "viewer" => [bob] }
472
+ * ```
473
+ */
474
+ const groupBy: <K, A>(keyFn: (a: A) => K) => (items: readonly A[]) => ReadonlyMap<K, readonly A[]>;
475
+ /**
476
+ * Returns `true` if the dictionary contains the given key.
477
+ *
478
+ * @example
479
+ * ```ts
480
+ * pipe(Dict.fromEntries([["a", 1]]), Dict.has("a")); // true
481
+ * pipe(Dict.fromEntries([["a", 1]]), Dict.has("b")); // false
482
+ * ```
483
+ */
484
+ const has: <K>(key: K) => <V>(m: ReadonlyMap<K, V>) => boolean;
485
+ /**
486
+ * Looks up a value by key, returning `Some(value)` if found and `None` if not.
487
+ *
488
+ * @example
489
+ * ```ts
490
+ * pipe(Dict.fromEntries([["a", 1]]), Dict.lookup("a")); // Some(1)
491
+ * pipe(Dict.fromEntries([["a", 1]]), Dict.lookup("b")); // None
492
+ * ```
493
+ */
494
+ const lookup: <K>(key: K) => <V>(m: ReadonlyMap<K, V>) => Option<V>;
495
+ /**
496
+ * Returns the number of entries in the dictionary.
497
+ *
498
+ * @example
499
+ * ```ts
500
+ * Dict.size(Dict.fromEntries([["a", 1], ["b", 2]])); // 2
501
+ * ```
502
+ */
503
+ const size: <K, V>(m: ReadonlyMap<K, V>) => number;
504
+ /**
505
+ * Returns `true` if the dictionary has no entries.
506
+ *
507
+ * @example
508
+ * ```ts
509
+ * Dict.isEmpty(Dict.empty()); // true
510
+ * ```
511
+ */
512
+ const isEmpty: <K, V>(m: ReadonlyMap<K, V>) => boolean;
513
+ /**
514
+ * Returns all keys as a readonly array, in insertion order.
515
+ *
516
+ * @example
517
+ * ```ts
518
+ * Dict.keys(Dict.fromEntries([["a", 1], ["b", 2]])); // ["a", "b"]
519
+ * ```
520
+ */
521
+ const keys: <K, V>(m: ReadonlyMap<K, V>) => readonly K[];
522
+ /**
523
+ * Returns all values as a readonly array, in insertion order.
524
+ *
525
+ * @example
526
+ * ```ts
527
+ * Dict.values(Dict.fromEntries([["a", 1], ["b", 2]])); // [1, 2]
528
+ * ```
529
+ */
530
+ const values: <K, V>(m: ReadonlyMap<K, V>) => readonly V[];
531
+ /**
532
+ * Returns all key-value pairs as a readonly array of tuples, in insertion order.
533
+ *
534
+ * @example
535
+ * ```ts
536
+ * Dict.entries(Dict.fromEntries([["a", 1], ["b", 2]])); // [["a", 1], ["b", 2]]
537
+ * ```
538
+ */
539
+ const entries: <K, V>(m: ReadonlyMap<K, V>) => readonly (readonly [K, V])[];
540
+ /**
541
+ * Returns a new dictionary with the given key set to the given value.
542
+ * If the key already exists, its value is replaced.
543
+ *
544
+ * @example
545
+ * ```ts
546
+ * pipe(Dict.fromEntries([["a", 1]]), Dict.insert("b", 2));
547
+ * // ReadonlyMap { "a" => 1, "b" => 2 }
548
+ * ```
549
+ */
550
+ const insert: <K, V>(key: K, value: V) => (m: ReadonlyMap<K, V>) => ReadonlyMap<K, V>;
551
+ /**
552
+ * Returns a new dictionary with the given key removed.
553
+ * If the key does not exist, the dictionary is returned unchanged.
554
+ *
555
+ * @example
556
+ * ```ts
557
+ * pipe(Dict.fromEntries([["a", 1], ["b", 2]]), Dict.remove("a"));
558
+ * // ReadonlyMap { "b" => 2 }
559
+ * ```
560
+ */
561
+ const remove: <K, V>(key: K) => (m: ReadonlyMap<K, V>) => ReadonlyMap<K, V>;
562
+ /**
563
+ * Returns a new dictionary with the value at `key` set by `f`. If the key does not exist,
564
+ * `f` receives `None`. If the key exists, `f` receives `Some(currentValue)`.
565
+ *
566
+ * Useful for incrementing counters, initialising defaults, or conditional updates.
567
+ *
568
+ * @example
569
+ * ```ts
570
+ * import { Option } from "@nlozgachev/pipelined/core";
571
+ *
572
+ * const increment = (opt: Option<number>) => Option.getOrElse(() => 0)(opt) + 1;
573
+ * pipe(Dict.fromEntries([["views", 5]]), Dict.upsert("views", increment)); // { views: 6 }
574
+ * pipe(Dict.fromEntries([["views", 5]]), Dict.upsert("likes", increment)); // { views: 5, likes: 1 }
575
+ * ```
576
+ */
577
+ const upsert: <K, V>(key: K, f: (existing: Option<V>) => V) => (m: ReadonlyMap<K, V>) => ReadonlyMap<K, V>;
578
+ /**
579
+ * Transforms each value in the dictionary.
580
+ *
581
+ * @example
582
+ * ```ts
583
+ * pipe(Dict.fromEntries([["a", 1], ["b", 2]]), Dict.map(n => n * 2));
584
+ * // ReadonlyMap { "a" => 2, "b" => 4 }
585
+ * ```
586
+ */
587
+ const map: <A, B>(f: (a: A) => B) => <K>(m: ReadonlyMap<K, A>) => ReadonlyMap<K, B>;
588
+ /**
589
+ * Transforms each value in the dictionary, also receiving the key.
590
+ *
591
+ * @example
592
+ * ```ts
593
+ * pipe(Dict.fromEntries([["a", 1], ["b", 2]]), Dict.mapWithKey((k, v) => `${k}:${v}`));
594
+ * // ReadonlyMap { "a" => "a:1", "b" => "b:2" }
595
+ * ```
596
+ */
597
+ const mapWithKey: <K, A, B>(f: (key: K, a: A) => B) => (m: ReadonlyMap<K, A>) => ReadonlyMap<K, B>;
598
+ /**
599
+ * Returns a new dictionary containing only the entries for which the predicate returns `true`.
600
+ *
601
+ * @example
602
+ * ```ts
603
+ * pipe(Dict.fromEntries([["a", 1], ["b", 3], ["c", 0]]), Dict.filter(n => n > 0));
604
+ * // ReadonlyMap { "a" => 1, "b" => 3 }
605
+ * ```
606
+ */
607
+ const filter: <A>(predicate: (a: A) => boolean) => <K>(m: ReadonlyMap<K, A>) => ReadonlyMap<K, A>;
608
+ /**
609
+ * Returns a new dictionary containing only the entries for which the predicate returns `true`.
610
+ * The predicate also receives the key.
611
+ *
612
+ * @example
613
+ * ```ts
614
+ * pipe(Dict.fromEntries([["a", 1], ["b", 2]]), Dict.filterWithKey((k, v) => k !== "a" && v > 0));
615
+ * // ReadonlyMap { "b" => 2 }
616
+ * ```
617
+ */
618
+ const filterWithKey: <K, A>(predicate: (key: K, a: A) => boolean) => (m: ReadonlyMap<K, A>) => ReadonlyMap<K, A>;
619
+ /**
620
+ * Removes all `None` values from a `ReadonlyMap<K, Option<A>>`, returning a plain
621
+ * `ReadonlyMap<K, A>`. Useful when building dictionaries from fallible lookups.
622
+ *
623
+ * @example
624
+ * ```ts
625
+ * import { Option } from "@nlozgachev/pipelined/core";
626
+ *
627
+ * Dict.compact(Dict.fromEntries([
628
+ * ["a", Option.some(1)],
629
+ * ["b", Option.none()],
630
+ * ["c", Option.some(3)],
631
+ * ]));
632
+ * // ReadonlyMap { "a" => 1, "c" => 3 }
633
+ * ```
634
+ */
635
+ const compact: <K, A>(m: ReadonlyMap<K, Option<A>>) => ReadonlyMap<K, A>;
636
+ /**
637
+ * Merges two dictionaries. When both contain the same key, the value from `other` takes
638
+ * precedence.
639
+ *
640
+ * @example
641
+ * ```ts
642
+ * pipe(
643
+ * Dict.fromEntries([["a", 1], ["b", 2]]),
644
+ * Dict.union(Dict.fromEntries([["b", 3], ["c", 4]])),
645
+ * );
646
+ * // ReadonlyMap { "a" => 1, "b" => 3, "c" => 4 }
647
+ * ```
648
+ */
649
+ const union: <K, V>(other: ReadonlyMap<K, V>) => (m: ReadonlyMap<K, V>) => ReadonlyMap<K, V>;
650
+ /**
651
+ * Returns a new dictionary containing only the entries whose keys appear in both dictionaries.
652
+ * Values are taken from the left (base) dictionary.
653
+ *
654
+ * @example
655
+ * ```ts
656
+ * pipe(
657
+ * Dict.fromEntries([["a", 1], ["b", 2], ["c", 3]]),
658
+ * Dict.intersection(Dict.fromEntries([["b", 99], ["c", 0]])),
659
+ * );
660
+ * // ReadonlyMap { "b" => 2, "c" => 3 }
661
+ * ```
662
+ */
663
+ const intersection: <K, V>(other: ReadonlyMap<K, unknown>) => (m: ReadonlyMap<K, V>) => ReadonlyMap<K, V>;
664
+ /**
665
+ * Returns a new dictionary containing only the entries whose keys do not appear in `other`.
666
+ *
667
+ * @example
668
+ * ```ts
669
+ * pipe(
670
+ * Dict.fromEntries([["a", 1], ["b", 2], ["c", 3]]),
671
+ * Dict.difference(Dict.fromEntries([["b", 0]])),
672
+ * );
673
+ * // ReadonlyMap { "a" => 1, "c" => 3 }
674
+ * ```
675
+ */
676
+ const difference: <K, V>(other: ReadonlyMap<K, unknown>) => (m: ReadonlyMap<K, V>) => ReadonlyMap<K, V>;
677
+ /**
678
+ * Folds the dictionary into a single value by applying `f` to each value in insertion order.
679
+ * When you also need the key, use `reduceWithKey`.
680
+ *
681
+ * @example
682
+ * ```ts
683
+ * Dict.reduce(0, (acc, value) => acc + value)(
684
+ * Dict.fromEntries([["a", 1], ["b", 2], ["c", 3]])
685
+ * ); // 6
686
+ * ```
687
+ */
688
+ const reduce: <A, B>(init: B, f: (acc: B, value: A) => B) => <K>(m: ReadonlyMap<K, A>) => B;
689
+ /**
690
+ * Folds the dictionary into a single value by applying `f` to each key-value pair in insertion
691
+ * order.
692
+ *
693
+ * @example
694
+ * ```ts
695
+ * Dict.reduceWithKey("", (acc, value, key) => acc + key + ":" + value + " ")(
696
+ * Dict.fromEntries([["a", 1], ["b", 2]])
697
+ * ); // "a:1 b:2 "
698
+ * ```
699
+ */
700
+ const reduceWithKey: <K, A, B>(init: B, f: (acc: B, value: A, key: K) => B) => (m: ReadonlyMap<K, A>) => B;
701
+ /**
702
+ * Converts a `ReadonlyMap<string, V>` to a plain object. Only meaningful when keys are strings.
703
+ *
704
+ * @example
705
+ * ```ts
706
+ * Dict.toRecord(Dict.fromEntries([["a", 1], ["b", 2]])); // { a: 1, b: 2 }
707
+ * ```
708
+ */
709
+ const toRecord: <V>(m: ReadonlyMap<string, V>) => Readonly<Record<string, V>>;
710
+ }
711
+
712
+ /**
713
+ * Number utilities for common operations. All transformation functions are data-last
714
+ * and curried so they compose naturally with `pipe` and `Arr.map`.
715
+ *
716
+ * @example
717
+ * ```ts
718
+ * import { Num } from "@nlozgachev/pipelined/utils";
719
+ * import { pipe } from "@nlozgachev/pipelined/composition";
720
+ *
721
+ * pipe(
722
+ * Num.range(1, 6),
723
+ * Arr.map(Num.multiply(2)),
724
+ * Arr.filter(Num.between(4, 8))
725
+ * ); // [4, 6, 8]
726
+ * ```
727
+ */
728
+ declare namespace Num {
729
+ /**
730
+ * Generates an array of numbers from `from` to `to` (both inclusive),
731
+ * stepping by `step` (default `1`). If `step` is negative or zero, or `from > to`,
732
+ * returns an empty array. When `step` does not land exactly on `to`, the last value
733
+ * is the largest reachable value that does not exceed `to`.
734
+ *
735
+ * @example
736
+ * ```ts
737
+ * Num.range(0, 5); // [0, 1, 2, 3, 4, 5]
738
+ * Num.range(0, 10, 2); // [0, 2, 4, 6, 8, 10]
739
+ * Num.range(0, 9, 2); // [0, 2, 4, 6, 8]
740
+ * Num.range(5, 0); // []
741
+ * Num.range(3, 3); // [3]
742
+ * ```
743
+ */
744
+ const range: (from: number, to: number, step?: number) => readonly number[];
745
+ /**
746
+ * Clamps a number between `min` and `max` (both inclusive).
747
+ *
748
+ * @example
749
+ * ```ts
750
+ * pipe(150, Num.clamp(0, 100)); // 100
751
+ * pipe(-5, Num.clamp(0, 100)); // 0
752
+ * pipe(42, Num.clamp(0, 100)); // 42
753
+ * ```
754
+ */
755
+ const clamp: (min: number, max: number) => (n: number) => number;
756
+ /**
757
+ * Returns `true` when the number is between `min` and `max` (both inclusive).
758
+ *
759
+ * @example
760
+ * ```ts
761
+ * pipe(5, Num.between(1, 10)); // true
762
+ * pipe(0, Num.between(1, 10)); // false
763
+ * pipe(10, Num.between(1, 10)); // true
764
+ * ```
765
+ */
766
+ const between: (min: number, max: number) => (n: number) => boolean;
767
+ /**
768
+ * Parses a string as a number. Returns `None` when the result is `NaN`.
769
+ *
770
+ * @example
771
+ * ```ts
772
+ * Num.parse("42"); // Some(42)
773
+ * Num.parse("3.14"); // Some(3.14)
774
+ * Num.parse("abc"); // None
775
+ * Num.parse(""); // None
776
+ * ```
777
+ */
778
+ const parse: (s: string) => Option<number>;
779
+ /**
780
+ * Adds `b` to a number. Data-last: use in `pipe` or `Arr.map`.
781
+ *
782
+ * @example
783
+ * ```ts
784
+ * pipe(5, Num.add(3)); // 8
785
+ * pipe([1, 2, 3], Arr.map(Num.add(10))); // [11, 12, 13]
786
+ * ```
787
+ */
788
+ const add: (b: number) => (a: number) => number;
789
+ /**
790
+ * Subtracts `b` from a number. Data-last: `subtract(b)(a)` = `a - b`.
791
+ *
792
+ * @example
793
+ * ```ts
794
+ * pipe(10, Num.subtract(3)); // 7
795
+ * pipe([5, 10, 15], Arr.map(Num.subtract(2))); // [3, 8, 13]
796
+ * ```
797
+ */
798
+ const subtract: (b: number) => (a: number) => number;
799
+ /**
800
+ * Multiplies a number by `b`. Data-last: use in `pipe` or `Arr.map`.
801
+ *
802
+ * @example
803
+ * ```ts
804
+ * pipe(6, Num.multiply(7)); // 42
805
+ * pipe([1, 2, 3], Arr.map(Num.multiply(100))); // [100, 200, 300]
806
+ * ```
807
+ */
808
+ const multiply: (b: number) => (a: number) => number;
809
+ /**
810
+ * Divides a number by `b`. Data-last: `divide(b)(a)` = `a / b`.
811
+ *
812
+ * @example
813
+ * ```ts
814
+ * pipe(20, Num.divide(4)); // 5
815
+ * pipe([10, 20, 30], Arr.map(Num.divide(10))); // [1, 2, 3]
816
+ * ```
817
+ */
818
+ const divide: (b: number) => (a: number) => number;
819
+ }
820
+
821
+ /**
822
+ * Functional record/object utilities that compose well with pipe.
823
+ * All functions are data-last and curried where applicable.
824
+ *
825
+ * @example
826
+ * ```ts
827
+ * pipe(
828
+ * { a: 1, b: 2, c: 3 },
829
+ * Rec.filter(n => n > 1),
830
+ * Rec.map(n => n * 10)
831
+ * ); // { b: 20, c: 30 }
832
+ * ```
833
+ */
834
+ declare namespace Rec {
835
+ /**
836
+ * Transforms each value in a record.
837
+ *
838
+ * @example
839
+ * ```ts
840
+ * pipe({ a: 1, b: 2 }, Rec.map(n => n * 2)); // { a: 2, b: 4 }
841
+ * ```
842
+ */
843
+ const map: <A, B>(f: (a: A) => B) => (data: Readonly<Record<string, A>>) => Readonly<Record<string, B>>;
844
+ /**
845
+ * Transforms each value in a record, also receiving the key.
846
+ *
847
+ * @example
848
+ * ```ts
849
+ * pipe({ a: 1, b: 2 }, Rec.mapWithKey((k, v) => `${k}:${v}`));
850
+ * // { a: "a:1", b: "b:2" }
851
+ * ```
852
+ */
853
+ const mapWithKey: <A, B>(f: (key: string, a: A) => B) => (data: Readonly<Record<string, A>>) => Readonly<Record<string, B>>;
854
+ /**
855
+ * Filters values in a record by a predicate.
856
+ *
857
+ * @example
858
+ * ```ts
859
+ * pipe({ a: 1, b: 2, c: 3 }, Rec.filter(n => n > 1)); // { b: 2, c: 3 }
860
+ * ```
861
+ */
862
+ const filter: <A>(predicate: (a: A) => boolean) => (data: Readonly<Record<string, A>>) => Readonly<Record<string, A>>;
863
+ /**
864
+ * Filters values in a record by a predicate that also receives the key.
865
+ *
866
+ * @example
867
+ * ```ts
868
+ * pipe({ a: 1, b: 2 }, Rec.filterWithKey((k, v) => k !== "a" && v > 0));
869
+ * // { b: 2 }
870
+ * ```
871
+ */
872
+ const filterWithKey: <A>(predicate: (key: string, a: A) => boolean) => (data: Readonly<Record<string, A>>) => Readonly<Record<string, A>>;
873
+ /**
874
+ * Looks up a value by key, returning Option.
875
+ *
876
+ * @example
877
+ * ```ts
878
+ * pipe({ a: 1, b: 2 }, Rec.lookup("a")); // Some(1)
879
+ * pipe({ a: 1, b: 2 }, Rec.lookup("c")); // None
880
+ * ```
881
+ */
882
+ const lookup: (key: string) => <A>(data: Readonly<Record<string, A>>) => Option<A>;
883
+ /**
884
+ * Returns all keys of a record.
885
+ */
886
+ const keys: <A>(data: Readonly<Record<string, A>>) => readonly string[];
887
+ /**
888
+ * Returns all values of a record.
889
+ */
890
+ const values: <A>(data: Readonly<Record<string, A>>) => readonly A[];
891
+ /**
892
+ * Returns all key-value pairs of a record.
893
+ */
894
+ const entries: <A>(data: Readonly<Record<string, A>>) => readonly (readonly [string, A])[];
895
+ /**
896
+ * Creates a record from key-value pairs.
897
+ *
898
+ * @example
899
+ * ```ts
900
+ * Rec.fromEntries([["a", 1], ["b", 2]]); // { a: 1, b: 2 }
901
+ * ```
902
+ */
903
+ const fromEntries: <A>(data: readonly (readonly [string, A])[]) => Readonly<Record<string, A>>;
904
+ /**
905
+ * Groups elements of an array into a record keyed by the result of `keyFn`. Each key maps to
906
+ * the array of elements that produced it, in insertion order.
907
+ *
908
+ * Unlike `Dict.groupBy`, keys are always strings. Use `Dict.groupBy` when you need non-string
909
+ * keys or want to avoid the plain-object prototype chain.
910
+ *
911
+ * @example
912
+ * ```ts
913
+ * pipe(
914
+ * ["apple", "avocado", "banana", "blueberry"],
915
+ * Rec.groupBy(s => s[0]),
916
+ * ); // { a: ["apple", "avocado"], b: ["banana", "blueberry"] }
917
+ * ```
918
+ */
919
+ const groupBy: <A>(keyFn: (a: A) => string) => (items: readonly A[]) => Readonly<Record<string, readonly A[]>>;
920
+ /**
921
+ * Picks specific keys from a record.
922
+ *
923
+ * @example
924
+ * ```ts
925
+ * pipe({ a: 1, b: 2, c: 3 }, Rec.pick("a", "c")); // { a: 1, c: 3 }
926
+ * ```
927
+ */
928
+ const pick: <K extends string>(...pickedKeys: K[]) => <A extends Record<K, unknown>>(data: A) => Pick<A, K>;
929
+ /**
930
+ * Omits specific keys from a record.
931
+ *
932
+ * @example
933
+ * ```ts
934
+ * pipe({ a: 1, b: 2, c: 3 }, Rec.omit("b")); // { a: 1, c: 3 }
935
+ * ```
936
+ */
937
+ const omit: <K extends string>(...omittedKeys: K[]) => <A extends Record<K, unknown>>(data: A) => Omit<A, K>;
938
+ /**
939
+ * Merges two records. Values from the second record take precedence.
940
+ *
941
+ * @example
942
+ * ```ts
943
+ * pipe({ a: 1, b: 2 }, Rec.merge({ b: 3, c: 4 })); // { a: 1, b: 3, c: 4 }
944
+ * ```
945
+ */
946
+ const merge: <A>(other: Readonly<Record<string, A>>) => (data: Readonly<Record<string, A>>) => Readonly<Record<string, A>>;
947
+ /**
948
+ * Returns true if the record has no keys.
949
+ */
950
+ const isEmpty: <A>(data: Readonly<Record<string, A>>) => boolean;
951
+ /**
952
+ * Returns the number of keys in a record.
953
+ */
954
+ const size: <A>(data: Readonly<Record<string, A>>) => number;
955
+ /**
956
+ * Transforms each key while preserving values.
957
+ * If two keys map to the same new key, the last one wins.
958
+ *
959
+ * @example
960
+ * ```ts
961
+ * pipe({ firstName: "Alice", lastName: "Smith" }, Rec.mapKeys(k => k.toUpperCase()));
962
+ * // { FIRSTNAME: "Alice", LASTNAME: "Smith" }
963
+ * ```
964
+ */
965
+ const mapKeys: (f: (key: string) => string) => <A>(data: Readonly<Record<string, A>>) => Readonly<Record<string, A>>;
966
+ /**
967
+ * Removes all `None` values from a `Record<string, Option<A>>`, returning a plain `Record<string, A>`.
968
+ * Useful when building records from fallible lookups.
969
+ *
970
+ * @example
971
+ * ```ts
972
+ * Rec.compact({ a: Option.some(1), b: Option.none(), c: Option.some(3) });
973
+ * // { a: 1, c: 3 }
974
+ * ```
975
+ */
976
+ const compact: <A>(data: Readonly<Record<string, Option<A>>>) => Readonly<Record<string, A>>;
977
+ }
978
+
979
+ /**
980
+ * String utilities. All transformation functions are data-last and curried so they
981
+ * compose naturally with `pipe`. Safe parsers return `Option` instead of `NaN`.
982
+ *
983
+ * @example
984
+ * ```ts
985
+ * import { Str } from "@nlozgachev/pipelined/utils";
986
+ * import { pipe } from "@nlozgachev/pipelined/composition";
987
+ *
988
+ * pipe(" Hello, World! ", Str.trim, Str.toLowerCase); // "hello, world!"
989
+ * ```
990
+ */
991
+ declare namespace Str {
992
+ /**
993
+ * Splits a string by a separator. Data-last: use in `pipe`.
994
+ *
995
+ * @example
996
+ * ```ts
997
+ * pipe("a,b,c", Str.split(",")); // ["a", "b", "c"]
998
+ * ```
999
+ */
1000
+ const split: (separator: string | RegExp) => (s: string) => readonly string[];
1001
+ /**
1002
+ * Removes leading and trailing whitespace from a string.
1003
+ *
1004
+ * @example
1005
+ * ```ts
1006
+ * pipe(" hello ", Str.trim); // "hello"
1007
+ * ```
1008
+ */
1009
+ const trim: (s: string) => string;
1010
+ /**
1011
+ * Returns `true` when the string contains the given substring.
1012
+ *
1013
+ * @example
1014
+ * ```ts
1015
+ * pipe("hello world", Str.includes("world")); // true
1016
+ * pipe("hello world", Str.includes("xyz")); // false
1017
+ * ```
1018
+ */
1019
+ const includes: (substring: string) => (s: string) => boolean;
1020
+ /**
1021
+ * Returns `true` when the string starts with the given prefix.
1022
+ *
1023
+ * @example
1024
+ * ```ts
1025
+ * pipe("hello world", Str.startsWith("hello")); // true
1026
+ * pipe("hello world", Str.startsWith("world")); // false
1027
+ * ```
1028
+ */
1029
+ const startsWith: (prefix: string) => (s: string) => boolean;
1030
+ /**
1031
+ * Returns `true` when the string ends with the given suffix.
1032
+ *
1033
+ * @example
1034
+ * ```ts
1035
+ * pipe("hello world", Str.endsWith("world")); // true
1036
+ * pipe("hello world", Str.endsWith("hello")); // false
1037
+ * ```
1038
+ */
1039
+ const endsWith: (suffix: string) => (s: string) => boolean;
1040
+ /**
1041
+ * Converts a string to uppercase.
1042
+ *
1043
+ * @example
1044
+ * ```ts
1045
+ * pipe("hello", Str.toUpperCase); // "HELLO"
1046
+ * ```
1047
+ */
1048
+ const toUpperCase: (s: string) => string;
1049
+ /**
1050
+ * Converts a string to lowercase.
1051
+ *
1052
+ * @example
1053
+ * ```ts
1054
+ * pipe("HELLO", Str.toLowerCase); // "hello"
1055
+ * ```
1056
+ */
1057
+ const toLowerCase: (s: string) => string;
1058
+ /**
1059
+ * Splits a string into lines, normalising `\r\n` and `\r` line endings.
1060
+ *
1061
+ * @example
1062
+ * ```ts
1063
+ * Str.lines("one\ntwo\nthree"); // ["one", "two", "three"]
1064
+ * Str.lines("a\r\nb"); // ["a", "b"]
1065
+ * ```
1066
+ */
1067
+ const lines: (s: string) => readonly string[];
1068
+ /**
1069
+ * Splits a string into words on any whitespace boundary, filtering out empty strings.
1070
+ *
1071
+ * @example
1072
+ * ```ts
1073
+ * Str.words(" hello world "); // ["hello", "world"]
1074
+ * ```
1075
+ */
1076
+ const words: (s: string) => readonly string[];
1077
+ /**
1078
+ * Safe number parsers that return `Option` instead of `NaN`.
1079
+ */
1080
+ const parse: {
1081
+ /**
1082
+ * Parses a string as an integer (base 10). Returns `None` if the result is `NaN`.
1083
+ *
1084
+ * @example
1085
+ * ```ts
1086
+ * Str.parse.int("42"); // Some(42)
1087
+ * Str.parse.int("3.7"); // Some(3)
1088
+ * Str.parse.int("abc"); // None
1089
+ * ```
1090
+ */
1091
+ int: (s: string) => Option<number>;
1092
+ /**
1093
+ * Parses a string as a floating-point number. Returns `None` if the result is `NaN`.
1094
+ *
1095
+ * @example
1096
+ * ```ts
1097
+ * Str.parse.float("3.14"); // Some(3.14)
1098
+ * Str.parse.float("42"); // Some(42)
1099
+ * Str.parse.float("abc"); // None
1100
+ * ```
1101
+ */
1102
+ float: (s: string) => Option<number>;
1103
+ };
1104
+ }
1105
+
1106
+ /**
1107
+ * Functional utilities for unique-value collections (`ReadonlySet<A>`). All functions are pure
1108
+ * and data-last — they compose naturally with `pipe`.
1109
+ *
1110
+ * Every "mutating" operation returns a new set; the original is never changed.
1111
+ *
1112
+ * @example
1113
+ * ```ts
1114
+ * import { Uniq } from "@nlozgachev/pipelined/utils";
1115
+ * import { pipe } from "@nlozgachev/pipelined/composition";
1116
+ *
1117
+ * const active = pipe(
1118
+ * Uniq.fromArray(["alice", "bob", "alice", "carol"]),
1119
+ * Uniq.remove("bob"),
1120
+ * Uniq.map(name => name.toUpperCase()),
1121
+ * );
1122
+ * // ReadonlySet { "ALICE", "CAROL" }
1123
+ * ```
1124
+ */
1125
+ declare namespace Uniq {
1126
+ /**
1127
+ * Creates an empty unique collection.
1128
+ *
1129
+ * @example
1130
+ * ```ts
1131
+ * Uniq.empty<number>(); // ReadonlySet {}
1132
+ * ```
1133
+ */
1134
+ const empty: <A>() => ReadonlySet<A>;
1135
+ /**
1136
+ * Creates a unique collection containing a single item.
1137
+ *
1138
+ * @example
1139
+ * ```ts
1140
+ * Uniq.singleton(42); // ReadonlySet { 42 }
1141
+ * ```
1142
+ */
1143
+ const singleton: <A>(item: A) => ReadonlySet<A>;
1144
+ /**
1145
+ * Creates a unique collection from an array, automatically discarding duplicates.
1146
+ *
1147
+ * @example
1148
+ * ```ts
1149
+ * Uniq.fromArray([1, 2, 2, 3, 3, 3]); // ReadonlySet { 1, 2, 3 }
1150
+ * Uniq.fromArray([]); // ReadonlySet {}
1151
+ * ```
1152
+ */
1153
+ const fromArray: <A>(arr: readonly A[]) => ReadonlySet<A>;
1154
+ /**
1155
+ * Returns `true` if the collection contains the given item.
1156
+ *
1157
+ * @example
1158
+ * ```ts
1159
+ * pipe(Uniq.fromArray([1, 2, 3]), Uniq.has(2)); // true
1160
+ * pipe(Uniq.fromArray([1, 2, 3]), Uniq.has(4)); // false
1161
+ * ```
1162
+ */
1163
+ const has: <A>(item: A) => (s: ReadonlySet<A>) => boolean;
1164
+ /**
1165
+ * Returns the number of items in the collection.
1166
+ *
1167
+ * @example
1168
+ * ```ts
1169
+ * Uniq.size(Uniq.fromArray([1, 2, 3])); // 3
1170
+ * ```
1171
+ */
1172
+ const size: <A>(s: ReadonlySet<A>) => number;
1173
+ /**
1174
+ * Returns `true` if the collection has no items.
1175
+ *
1176
+ * @example
1177
+ * ```ts
1178
+ * Uniq.isEmpty(Uniq.empty()); // true
1179
+ * ```
1180
+ */
1181
+ const isEmpty: <A>(s: ReadonlySet<A>) => boolean;
1182
+ /**
1183
+ * Returns `true` if every item in `set` also exists in `other`.
1184
+ *
1185
+ * @example
1186
+ * ```ts
1187
+ * pipe(Uniq.fromArray([1, 2]), Uniq.isSubsetOf(Uniq.fromArray([1, 2, 3]))); // true
1188
+ * pipe(Uniq.fromArray([1, 4]), Uniq.isSubsetOf(Uniq.fromArray([1, 2, 3]))); // false
1189
+ * pipe(Uniq.empty<number>(), Uniq.isSubsetOf(Uniq.fromArray([1, 2, 3]))); // true
1190
+ * ```
1191
+ */
1192
+ const isSubsetOf: <A>(other: ReadonlySet<A>) => (s: ReadonlySet<A>) => boolean;
1193
+ /**
1194
+ * Returns a new collection with the item added. If the item is already present, returns the
1195
+ * original collection unchanged.
1196
+ *
1197
+ * @example
1198
+ * ```ts
1199
+ * pipe(Uniq.fromArray([1, 2]), Uniq.insert(3)); // ReadonlySet { 1, 2, 3 }
1200
+ * pipe(Uniq.fromArray([1, 2]), Uniq.insert(2)); // ReadonlySet { 1, 2 } — unchanged
1201
+ * ```
1202
+ */
1203
+ const insert: <A>(item: A) => (s: ReadonlySet<A>) => ReadonlySet<A>;
1204
+ /**
1205
+ * Returns a new collection with the item removed. If the item is not present, returns the
1206
+ * original collection unchanged.
1207
+ *
1208
+ * @example
1209
+ * ```ts
1210
+ * pipe(Uniq.fromArray([1, 2, 3]), Uniq.remove(2)); // ReadonlySet { 1, 3 }
1211
+ * pipe(Uniq.fromArray([1, 2, 3]), Uniq.remove(4)); // ReadonlySet { 1, 2, 3 } — unchanged
1212
+ * ```
1213
+ */
1214
+ const remove: <A>(item: A) => (s: ReadonlySet<A>) => ReadonlySet<A>;
1215
+ /**
1216
+ * Applies `f` to each item, returning a new collection of the results. Duplicate results are
1217
+ * automatically merged.
1218
+ *
1219
+ * @example
1220
+ * ```ts
1221
+ * pipe(Uniq.fromArray([1, 2, 3, 4]), Uniq.map(n => n % 3)); // ReadonlySet { 1, 2, 0 }
1222
+ * ```
1223
+ */
1224
+ const map: <A, B>(f: (a: A) => B) => (s: ReadonlySet<A>) => ReadonlySet<B>;
1225
+ /**
1226
+ * Returns a new collection containing only the items for which the predicate returns `true`.
1227
+ *
1228
+ * @example
1229
+ * ```ts
1230
+ * pipe(Uniq.fromArray([1, 2, 3, 4, 5]), Uniq.filter(n => n % 2 === 0));
1231
+ * // ReadonlySet { 2, 4 }
1232
+ * ```
1233
+ */
1234
+ const filter: <A>(predicate: (a: A) => boolean) => (s: ReadonlySet<A>) => ReadonlySet<A>;
1235
+ /**
1236
+ * Returns a new collection containing all items from both collections.
1237
+ *
1238
+ * @example
1239
+ * ```ts
1240
+ * pipe(Uniq.fromArray([1, 2, 3]), Uniq.union(Uniq.fromArray([2, 3, 4])));
1241
+ * // ReadonlySet { 1, 2, 3, 4 }
1242
+ * ```
1243
+ */
1244
+ const union: <A>(other: ReadonlySet<A>) => (s: ReadonlySet<A>) => ReadonlySet<A>;
1245
+ /**
1246
+ * Returns a new collection containing only the items that appear in both collections.
1247
+ *
1248
+ * @example
1249
+ * ```ts
1250
+ * pipe(Uniq.fromArray([1, 2, 3]), Uniq.intersection(Uniq.fromArray([2, 3, 4])));
1251
+ * // ReadonlySet { 2, 3 }
1252
+ * ```
1253
+ */
1254
+ const intersection: <A>(other: ReadonlySet<A>) => (s: ReadonlySet<A>) => ReadonlySet<A>;
1255
+ /**
1256
+ * Returns a new collection containing only the items from `set` that do not appear in `other`.
1257
+ *
1258
+ * @example
1259
+ * ```ts
1260
+ * pipe(Uniq.fromArray([1, 2, 3, 4]), Uniq.difference(Uniq.fromArray([2, 4])));
1261
+ * // ReadonlySet { 1, 3 }
1262
+ * ```
1263
+ */
1264
+ const difference: <A>(other: ReadonlySet<A>) => (s: ReadonlySet<A>) => ReadonlySet<A>;
1265
+ /**
1266
+ * Folds the collection into a single value by applying `f` to each item in insertion order.
1267
+ *
1268
+ * @example
1269
+ * ```ts
1270
+ * Uniq.reduce(0, (acc, n) => acc + n)(Uniq.fromArray([1, 2, 3])); // 6
1271
+ * ```
1272
+ */
1273
+ const reduce: <A, B>(init: B, f: (acc: B, a: A) => B) => (s: ReadonlySet<A>) => B;
1274
+ /**
1275
+ * Converts the collection to a readonly array in insertion order.
1276
+ *
1277
+ * @example
1278
+ * ```ts
1279
+ * Uniq.toArray(Uniq.fromArray([3, 1, 2])); // [3, 1, 2]
1280
+ * ```
1281
+ */
1282
+ const toArray: <A>(s: ReadonlySet<A>) => readonly A[];
1283
+ }
1284
+
1285
+ export { Arr, Dict, Num, Rec, Str, Uniq };