@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,424 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Dict = void 0;
4
- const Option_js_1 = require("../Core/Option.js");
5
- /**
6
- * Functional utilities for key-value dictionaries (`ReadonlyMap<K, V>`). All functions are pure
7
- * and data-last — they compose naturally with `pipe`.
8
- *
9
- * Unlike plain objects (`Rec`), dictionaries support any key type, preserve insertion order, and
10
- * make membership checks explicit via `lookup` returning `Option`.
11
- *
12
- * @example
13
- * ```ts
14
- * import { Dict } from "@nlozgachev/pipelined/utils";
15
- * import { pipe } from "@nlozgachev/pipelined/composition";
16
- *
17
- * const scores = pipe(
18
- * Dict.fromEntries([["alice", 10], ["bob", 8], ["carol", 10]] as const),
19
- * Dict.filter(n => n >= 10),
20
- * Dict.map(n => `${n} points`),
21
- * );
22
- * // ReadonlyMap { "alice" => "10 points", "carol" => "10 points" }
23
- * ```
24
- */
25
- var Dict;
26
- (function (Dict) {
27
- // ---------------------------------------------------------------------------
28
- // Constructors
29
- // ---------------------------------------------------------------------------
30
- /**
31
- * Creates an empty dictionary.
32
- *
33
- * @example
34
- * ```ts
35
- * Dict.empty<string, number>(); // ReadonlyMap {}
36
- * ```
37
- */
38
- Dict.empty = () => new globalThis.Map();
39
- /**
40
- * Creates a dictionary with a single entry.
41
- *
42
- * @example
43
- * ```ts
44
- * Dict.singleton("name", "Alice"); // ReadonlyMap { "name" => "Alice" }
45
- * ```
46
- */
47
- Dict.singleton = (key, value) => new globalThis.Map([[key, value]]);
48
- /**
49
- * Creates a dictionary from an array of key-value pairs.
50
- *
51
- * @example
52
- * ```ts
53
- * Dict.fromEntries([["a", 1], ["b", 2]]); // ReadonlyMap { "a" => 1, "b" => 2 }
54
- * ```
55
- */
56
- Dict.fromEntries = (entries) => new globalThis.Map(entries);
57
- /**
58
- * Creates a dictionary from a plain object. Keys are always strings.
59
- *
60
- * @example
61
- * ```ts
62
- * Dict.fromRecord({ a: 1, b: 2 }); // ReadonlyMap { "a" => 1, "b" => 2 }
63
- * ```
64
- */
65
- Dict.fromRecord = (rec) => new globalThis.Map(Object.entries(rec));
66
- /**
67
- * Groups elements of an array into a dictionary keyed by the result of `keyFn`. Each key maps
68
- * to the array of elements that produced it, in insertion order. Uses the native `Map.groupBy`
69
- * when available, falling back to a manual loop in older environments.
70
- *
71
- * @example
72
- * ```ts
73
- * pipe(
74
- * [{ name: "alice", role: "admin" }, { name: "bob", role: "viewer" }, { name: "carol", role: "admin" }],
75
- * Dict.groupBy(user => user.role),
76
- * );
77
- * // ReadonlyMap { "admin" => [alice, carol], "viewer" => [bob] }
78
- * ```
79
- */
80
- Dict.groupBy = (keyFn) => (items) => {
81
- const result = new globalThis.Map();
82
- for (const item of items) {
83
- const key = keyFn(item);
84
- const arr = result.get(key);
85
- if (arr !== undefined)
86
- arr.push(item);
87
- else
88
- result.set(key, [item]);
89
- }
90
- return result;
91
- };
92
- // ---------------------------------------------------------------------------
93
- // Query
94
- // ---------------------------------------------------------------------------
95
- /**
96
- * Returns `true` if the dictionary contains the given key.
97
- *
98
- * @example
99
- * ```ts
100
- * pipe(Dict.fromEntries([["a", 1]]), Dict.has("a")); // true
101
- * pipe(Dict.fromEntries([["a", 1]]), Dict.has("b")); // false
102
- * ```
103
- */
104
- Dict.has = (key) => (m) => m.has(key);
105
- /**
106
- * Looks up a value by key, returning `Some(value)` if found and `None` if not.
107
- *
108
- * @example
109
- * ```ts
110
- * pipe(Dict.fromEntries([["a", 1]]), Dict.lookup("a")); // Some(1)
111
- * pipe(Dict.fromEntries([["a", 1]]), Dict.lookup("b")); // None
112
- * ```
113
- */
114
- Dict.lookup = (key) => (m) => m.has(key) ? Option_js_1.Option.some(m.get(key)) : Option_js_1.Option.none();
115
- /**
116
- * Returns the number of entries in the dictionary.
117
- *
118
- * @example
119
- * ```ts
120
- * Dict.size(Dict.fromEntries([["a", 1], ["b", 2]])); // 2
121
- * ```
122
- */
123
- Dict.size = (m) => m.size;
124
- /**
125
- * Returns `true` if the dictionary has no entries.
126
- *
127
- * @example
128
- * ```ts
129
- * Dict.isEmpty(Dict.empty()); // true
130
- * ```
131
- */
132
- Dict.isEmpty = (m) => m.size === 0;
133
- /**
134
- * Returns all keys as a readonly array, in insertion order.
135
- *
136
- * @example
137
- * ```ts
138
- * Dict.keys(Dict.fromEntries([["a", 1], ["b", 2]])); // ["a", "b"]
139
- * ```
140
- */
141
- Dict.keys = (m) => [...m.keys()];
142
- /**
143
- * Returns all values as a readonly array, in insertion order.
144
- *
145
- * @example
146
- * ```ts
147
- * Dict.values(Dict.fromEntries([["a", 1], ["b", 2]])); // [1, 2]
148
- * ```
149
- */
150
- Dict.values = (m) => [...m.values()];
151
- /**
152
- * Returns all key-value pairs as a readonly array of tuples, in insertion order.
153
- *
154
- * @example
155
- * ```ts
156
- * Dict.entries(Dict.fromEntries([["a", 1], ["b", 2]])); // [["a", 1], ["b", 2]]
157
- * ```
158
- */
159
- Dict.entries = (m) => [...m.entries()];
160
- // ---------------------------------------------------------------------------
161
- // Modification
162
- // ---------------------------------------------------------------------------
163
- /**
164
- * Returns a new dictionary with the given key set to the given value.
165
- * If the key already exists, its value is replaced.
166
- *
167
- * @example
168
- * ```ts
169
- * pipe(Dict.fromEntries([["a", 1]]), Dict.insert("b", 2));
170
- * // ReadonlyMap { "a" => 1, "b" => 2 }
171
- * ```
172
- */
173
- Dict.insert = (key, value) => (m) => {
174
- const result = new globalThis.Map(m);
175
- result.set(key, value);
176
- return result;
177
- };
178
- /**
179
- * Returns a new dictionary with the given key removed.
180
- * If the key does not exist, the dictionary is returned unchanged.
181
- *
182
- * @example
183
- * ```ts
184
- * pipe(Dict.fromEntries([["a", 1], ["b", 2]]), Dict.remove("a"));
185
- * // ReadonlyMap { "b" => 2 }
186
- * ```
187
- */
188
- Dict.remove = (key) => (m) => {
189
- if (!m.has(key))
190
- return m;
191
- const result = new globalThis.Map(m);
192
- result.delete(key);
193
- return result;
194
- };
195
- /**
196
- * Returns a new dictionary with the value at `key` set by `f`. If the key does not exist,
197
- * `f` receives `None`. If the key exists, `f` receives `Some(currentValue)`.
198
- *
199
- * Useful for incrementing counters, initialising defaults, or conditional updates.
200
- *
201
- * @example
202
- * ```ts
203
- * import { Option } from "@nlozgachev/pipelined/core";
204
- *
205
- * const increment = (opt: Option<number>) => Option.getOrElse(() => 0)(opt) + 1;
206
- * pipe(Dict.fromEntries([["views", 5]]), Dict.upsert("views", increment)); // { views: 6 }
207
- * pipe(Dict.fromEntries([["views", 5]]), Dict.upsert("likes", increment)); // { views: 5, likes: 1 }
208
- * ```
209
- */
210
- Dict.upsert = (key, f) => (m) => {
211
- const result = new globalThis.Map(m);
212
- result.set(key, f(Dict.lookup(key)(m)));
213
- return result;
214
- };
215
- // ---------------------------------------------------------------------------
216
- // Transform
217
- // ---------------------------------------------------------------------------
218
- /**
219
- * Transforms each value in the dictionary.
220
- *
221
- * @example
222
- * ```ts
223
- * pipe(Dict.fromEntries([["a", 1], ["b", 2]]), Dict.map(n => n * 2));
224
- * // ReadonlyMap { "a" => 2, "b" => 4 }
225
- * ```
226
- */
227
- Dict.map = (f) => (m) => {
228
- const result = new globalThis.Map();
229
- for (const [k, v] of m) {
230
- result.set(k, f(v));
231
- }
232
- return result;
233
- };
234
- /**
235
- * Transforms each value in the dictionary, also receiving the key.
236
- *
237
- * @example
238
- * ```ts
239
- * pipe(Dict.fromEntries([["a", 1], ["b", 2]]), Dict.mapWithKey((k, v) => `${k}:${v}`));
240
- * // ReadonlyMap { "a" => "a:1", "b" => "b:2" }
241
- * ```
242
- */
243
- Dict.mapWithKey = (f) => (m) => {
244
- const result = new globalThis.Map();
245
- for (const [k, v] of m) {
246
- result.set(k, f(k, v));
247
- }
248
- return result;
249
- };
250
- /**
251
- * Returns a new dictionary containing only the entries for which the predicate returns `true`.
252
- *
253
- * @example
254
- * ```ts
255
- * pipe(Dict.fromEntries([["a", 1], ["b", 3], ["c", 0]]), Dict.filter(n => n > 0));
256
- * // ReadonlyMap { "a" => 1, "b" => 3 }
257
- * ```
258
- */
259
- Dict.filter = (predicate) => (m) => {
260
- const result = new globalThis.Map();
261
- for (const [k, v] of m) {
262
- if (predicate(v))
263
- result.set(k, v);
264
- }
265
- return result;
266
- };
267
- /**
268
- * Returns a new dictionary containing only the entries for which the predicate returns `true`.
269
- * The predicate also receives the key.
270
- *
271
- * @example
272
- * ```ts
273
- * pipe(Dict.fromEntries([["a", 1], ["b", 2]]), Dict.filterWithKey((k, v) => k !== "a" && v > 0));
274
- * // ReadonlyMap { "b" => 2 }
275
- * ```
276
- */
277
- Dict.filterWithKey = (predicate) => (m) => {
278
- const result = new globalThis.Map();
279
- for (const [k, v] of m) {
280
- if (predicate(k, v))
281
- result.set(k, v);
282
- }
283
- return result;
284
- };
285
- /**
286
- * Removes all `None` values from a `ReadonlyMap<K, Option<A>>`, returning a plain
287
- * `ReadonlyMap<K, A>`. Useful when building dictionaries from fallible lookups.
288
- *
289
- * @example
290
- * ```ts
291
- * import { Option } from "@nlozgachev/pipelined/core";
292
- *
293
- * Dict.compact(Dict.fromEntries([
294
- * ["a", Option.some(1)],
295
- * ["b", Option.none()],
296
- * ["c", Option.some(3)],
297
- * ]));
298
- * // ReadonlyMap { "a" => 1, "c" => 3 }
299
- * ```
300
- */
301
- Dict.compact = (m) => {
302
- const result = new globalThis.Map();
303
- for (const [k, v] of m) {
304
- if (v.kind === "Some")
305
- result.set(k, v.value);
306
- }
307
- return result;
308
- };
309
- // ---------------------------------------------------------------------------
310
- // Combine
311
- // ---------------------------------------------------------------------------
312
- /**
313
- * Merges two dictionaries. When both contain the same key, the value from `other` takes
314
- * precedence.
315
- *
316
- * @example
317
- * ```ts
318
- * pipe(
319
- * Dict.fromEntries([["a", 1], ["b", 2]]),
320
- * Dict.union(Dict.fromEntries([["b", 3], ["c", 4]])),
321
- * );
322
- * // ReadonlyMap { "a" => 1, "b" => 3, "c" => 4 }
323
- * ```
324
- */
325
- Dict.union = (other) => (m) => {
326
- const result = new globalThis.Map(m);
327
- for (const [k, v] of other) {
328
- result.set(k, v);
329
- }
330
- return result;
331
- };
332
- /**
333
- * Returns a new dictionary containing only the entries whose keys appear in both dictionaries.
334
- * Values are taken from the left (base) dictionary.
335
- *
336
- * @example
337
- * ```ts
338
- * pipe(
339
- * Dict.fromEntries([["a", 1], ["b", 2], ["c", 3]]),
340
- * Dict.intersection(Dict.fromEntries([["b", 99], ["c", 0]])),
341
- * );
342
- * // ReadonlyMap { "b" => 2, "c" => 3 }
343
- * ```
344
- */
345
- Dict.intersection = (other) => (m) => {
346
- const result = new globalThis.Map();
347
- for (const [k, v] of m) {
348
- if (other.has(k))
349
- result.set(k, v);
350
- }
351
- return result;
352
- };
353
- /**
354
- * Returns a new dictionary containing only the entries whose keys do not appear in `other`.
355
- *
356
- * @example
357
- * ```ts
358
- * pipe(
359
- * Dict.fromEntries([["a", 1], ["b", 2], ["c", 3]]),
360
- * Dict.difference(Dict.fromEntries([["b", 0]])),
361
- * );
362
- * // ReadonlyMap { "a" => 1, "c" => 3 }
363
- * ```
364
- */
365
- Dict.difference = (other) => (m) => {
366
- const result = new globalThis.Map();
367
- for (const [k, v] of m) {
368
- if (!other.has(k))
369
- result.set(k, v);
370
- }
371
- return result;
372
- };
373
- // ---------------------------------------------------------------------------
374
- // Fold
375
- // ---------------------------------------------------------------------------
376
- /**
377
- * Folds the dictionary into a single value by applying `f` to each value in insertion order.
378
- * When you also need the key, use `reduceWithKey`.
379
- *
380
- * @example
381
- * ```ts
382
- * Dict.reduce(0, (acc, value) => acc + value)(
383
- * Dict.fromEntries([["a", 1], ["b", 2], ["c", 3]])
384
- * ); // 6
385
- * ```
386
- */
387
- Dict.reduce = (init, f) => (m) => {
388
- let acc = init;
389
- for (const v of m.values()) {
390
- acc = f(acc, v);
391
- }
392
- return acc;
393
- };
394
- /**
395
- * Folds the dictionary into a single value by applying `f` to each key-value pair in insertion
396
- * order.
397
- *
398
- * @example
399
- * ```ts
400
- * Dict.reduceWithKey("", (acc, value, key) => acc + key + ":" + value + " ")(
401
- * Dict.fromEntries([["a", 1], ["b", 2]])
402
- * ); // "a:1 b:2 "
403
- * ```
404
- */
405
- Dict.reduceWithKey = (init, f) => (m) => {
406
- let acc = init;
407
- for (const [k, v] of m) {
408
- acc = f(acc, v, k);
409
- }
410
- return acc;
411
- };
412
- // ---------------------------------------------------------------------------
413
- // Convert
414
- // ---------------------------------------------------------------------------
415
- /**
416
- * Converts a `ReadonlyMap<string, V>` to a plain object. Only meaningful when keys are strings.
417
- *
418
- * @example
419
- * ```ts
420
- * Dict.toRecord(Dict.fromEntries([["a", 1], ["b", 2]])); // { a: 1, b: 2 }
421
- * ```
422
- */
423
- Dict.toRecord = (m) => Object.fromEntries(m);
424
- })(Dict || (exports.Dict = Dict = {}));
@@ -1,127 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Num = void 0;
4
- const Option_js_1 = require("../Core/Option.js");
5
- /**
6
- * Number utilities for common operations. All transformation functions are data-last
7
- * and curried so they compose naturally with `pipe` and `Arr.map`.
8
- *
9
- * @example
10
- * ```ts
11
- * import { Num } from "@nlozgachev/pipelined/utils";
12
- * import { pipe } from "@nlozgachev/pipelined/composition";
13
- *
14
- * pipe(
15
- * Num.range(1, 6),
16
- * Arr.map(Num.multiply(2)),
17
- * Arr.filter(Num.between(4, 8))
18
- * ); // [4, 6, 8]
19
- * ```
20
- */
21
- var Num;
22
- (function (Num) {
23
- /**
24
- * Generates an array of numbers from `from` to `to` (both inclusive),
25
- * stepping by `step` (default `1`). If `step` is negative or zero, or `from > to`,
26
- * returns an empty array. When `step` does not land exactly on `to`, the last value
27
- * is the largest reachable value that does not exceed `to`.
28
- *
29
- * @example
30
- * ```ts
31
- * Num.range(0, 5); // [0, 1, 2, 3, 4, 5]
32
- * Num.range(0, 10, 2); // [0, 2, 4, 6, 8, 10]
33
- * Num.range(0, 9, 2); // [0, 2, 4, 6, 8]
34
- * Num.range(5, 0); // []
35
- * Num.range(3, 3); // [3]
36
- * ```
37
- */
38
- Num.range = (from, to, step = 1) => {
39
- if (step <= 0 || from > to)
40
- return [];
41
- const count = Math.floor((to - from) / step) + 1;
42
- const result = new Array(count);
43
- for (let i = 0; i < count; i++) {
44
- result[i] = from + i * step;
45
- }
46
- return result;
47
- };
48
- /**
49
- * Clamps a number between `min` and `max` (both inclusive).
50
- *
51
- * @example
52
- * ```ts
53
- * pipe(150, Num.clamp(0, 100)); // 100
54
- * pipe(-5, Num.clamp(0, 100)); // 0
55
- * pipe(42, Num.clamp(0, 100)); // 42
56
- * ```
57
- */
58
- Num.clamp = (min, max) => (n) => Math.min(Math.max(n, min), max);
59
- /**
60
- * Returns `true` when the number is between `min` and `max` (both inclusive).
61
- *
62
- * @example
63
- * ```ts
64
- * pipe(5, Num.between(1, 10)); // true
65
- * pipe(0, Num.between(1, 10)); // false
66
- * pipe(10, Num.between(1, 10)); // true
67
- * ```
68
- */
69
- Num.between = (min, max) => (n) => n >= min && n <= max;
70
- /**
71
- * Parses a string as a number. Returns `None` when the result is `NaN`.
72
- *
73
- * @example
74
- * ```ts
75
- * Num.parse("42"); // Some(42)
76
- * Num.parse("3.14"); // Some(3.14)
77
- * Num.parse("abc"); // None
78
- * Num.parse(""); // None
79
- * ```
80
- */
81
- Num.parse = (s) => {
82
- if (s.trim() === "")
83
- return Option_js_1.Option.none();
84
- const n = Number(s);
85
- return isNaN(n) ? Option_js_1.Option.none() : Option_js_1.Option.some(n);
86
- };
87
- /**
88
- * Adds `b` to a number. Data-last: use in `pipe` or `Arr.map`.
89
- *
90
- * @example
91
- * ```ts
92
- * pipe(5, Num.add(3)); // 8
93
- * pipe([1, 2, 3], Arr.map(Num.add(10))); // [11, 12, 13]
94
- * ```
95
- */
96
- Num.add = (b) => (a) => a + b;
97
- /**
98
- * Subtracts `b` from a number. Data-last: `subtract(b)(a)` = `a - b`.
99
- *
100
- * @example
101
- * ```ts
102
- * pipe(10, Num.subtract(3)); // 7
103
- * pipe([5, 10, 15], Arr.map(Num.subtract(2))); // [3, 8, 13]
104
- * ```
105
- */
106
- Num.subtract = (b) => (a) => a - b;
107
- /**
108
- * Multiplies a number by `b`. Data-last: use in `pipe` or `Arr.map`.
109
- *
110
- * @example
111
- * ```ts
112
- * pipe(6, Num.multiply(7)); // 42
113
- * pipe([1, 2, 3], Arr.map(Num.multiply(100))); // [100, 200, 300]
114
- * ```
115
- */
116
- Num.multiply = (b) => (a) => a * b;
117
- /**
118
- * Divides a number by `b`. Data-last: `divide(b)(a)` = `a / b`.
119
- *
120
- * @example
121
- * ```ts
122
- * pipe(20, Num.divide(4)); // 5
123
- * pipe([10, 20, 30], Arr.map(Num.divide(10))); // [1, 2, 3]
124
- * ```
125
- */
126
- Num.divide = (b) => (a) => a / b;
127
- })(Num || (exports.Num = Num = {}));