@nlozgachev/pipelined 0.62.0 → 0.64.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/data.mjs CHANGED
@@ -1,264 +1,1185 @@
1
1
  // src/Core/Deferred.ts
2
- var Deferred;
3
- ((Deferred2) => {
4
- let from;
5
- ((from2) => {
6
- from2.Promise = (p) => (
7
- // eslint-disable-next-line unicorn/no-thenable -- Deferred is intentionally thenable; it is the mechanism that makes Task awaitable
8
- { then: ((f) => p.then(f)) }
9
- );
10
- })(from = Deferred2.from || (Deferred2.from = {}));
11
- let to;
12
- ((to2) => {
13
- to2.Promise = (d) => new globalThis.Promise((resolve) => d.then(resolve));
14
- })(to = Deferred2.to || (Deferred2.to = {}));
15
- Deferred2.all = (deferreds) => from.Promise(globalThis.Promise.all(deferreds.map((d) => to.Promise(d))));
16
- Deferred2.race = (deferreds) => from.Promise(globalThis.Promise.race(deferreds.map((d) => to.Promise(d))));
17
- })(Deferred || (Deferred = {}));
2
+ var fromPromise = (p) => ({ then: ((f) => p.then(f)) });
3
+ var toPromise = (d) => new globalThis.Promise((resolve) => d.then(resolve));
4
+ var Deferred = {
5
+ // --- from ---
6
+ from: {
7
+ /**
8
+ * Wraps a `Promise` or `Deferred` into a `Deferred`, structurally excluding rejection handlers,
9
+ * `.catch()`, `.finally()`, and chainable `.then()`.
10
+ *
11
+ * **Precondition**: `p` must never reject. If `p` rejects, the returned `Deferred` will
12
+ * never resolve — `await`-ing it will hang indefinitely. Use `Task.Result.tryCatch` to
13
+ * handle operations that may fail before converting to a `Deferred`.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const d = Deferred.from.Promise(Promise.resolve("hello"));
18
+ * const value = await d; // "hello"
19
+ * ```
20
+ */
21
+ Promise: fromPromise
22
+ },
23
+ // --- to ---
24
+ to: {
25
+ /**
26
+ * Converts a `Deferred` back into a `Promise`.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * const p = Deferred.to.Promise(Deferred.from.Promise(Promise.resolve(42)));
31
+ * // p is Promise<42>
32
+ * ```
33
+ */
34
+ Promise: toPromise
35
+ },
36
+ /**
37
+ * Combines an array or tuple of `Deferred` values into a single `Deferred` of a tuple.
38
+ * Resolves when all input `Deferred`s resolve.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * const [a, b] = await Deferred.all([d1, d2]);
43
+ * ```
44
+ */
45
+ all: (deferreds) => fromPromise(globalThis.Promise.all(deferreds.map((d) => toPromise(d)))),
46
+ /**
47
+ * Races multiple `Deferred` values and resolves with the first one to settle.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * const winner = await Deferred.race([d1, d2]);
52
+ * ```
53
+ */
54
+ race: (deferreds) => fromPromise(globalThis.Promise.race(deferreds.map((d) => toPromise(d))))
55
+ };
18
56
 
19
57
  // src/Core/Maybe.ts
20
58
  var _none = { kind: "None" };
21
- var Maybe;
22
- ((Maybe2) => {
23
- let make;
24
- ((make2) => {
25
- make2.some = (value) => ({ kind: "Some", value });
26
- make2.none = () => _none;
27
- })(make = Maybe2.make || (Maybe2.make = {}));
28
- let is;
29
- ((is2) => {
30
- is2.some = (data) => data.kind === "Some";
31
- is2.none = (data) => data.kind === "None";
32
- })(is = Maybe2.is || (Maybe2.is = {}));
33
- let to;
34
- ((to2) => {
35
- to2.nullable = (data) => is.some(data) ? data.value : null;
36
- to2.undefined = (data) => is.some(data) ? data.value : globalThis.undefined;
37
- to2.Result = (onNone) => (data) => is.some(data) ? Result.make.ok(data.value) : Result.make.err(onNone());
38
- })(to = Maybe2.to || (Maybe2.to = {}));
39
- let from;
40
- ((from2) => {
41
- from2.nullable = (value) => value === null || value === void 0 ? make.none() : make.some(value);
42
- from2.Predicate = (pred) => (a) => pred(a) ? make.some(a) : make.none();
43
- from2.Result = (data) => Result.is.ok(data) ? make.some(data.value) : make.none();
44
- })(from = Maybe2.from || (Maybe2.from = {}));
45
- Maybe2.map = (f) => (data) => is.some(data) ? make.some(f(data.value)) : data;
46
- Maybe2.chain = (f) => (data) => is.some(data) ? f(data.value) : data;
47
- Maybe2.fold = (onNone, onSome) => (data) => is.some(data) ? onSome(data.value) : onNone();
48
- Maybe2.match = (cases) => (data) => is.some(data) ? cases.some(data.value) : cases.none();
49
- Maybe2.getOrElse = (defaultValue) => (data) => is.some(data) ? data.value : defaultValue();
50
- Maybe2.tap = (f) => (data) => {
51
- if (is.some(data)) {
59
+ var makeSome = (value) => ({ kind: "Some", value });
60
+ var makeNone = () => _none;
61
+ var isSome = (data) => data.kind === "Some";
62
+ var isNone = (data) => data.kind === "None";
63
+ var Maybe = {
64
+ make: {
65
+ /**
66
+ * Creates a Some containing the given value.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * Maybe.make.some(42); // Some(42)
71
+ * ```
72
+ */
73
+ some: makeSome,
74
+ /**
75
+ * Creates a None (empty Maybe).
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * Maybe.make.none(); // None
80
+ * ```
81
+ */
82
+ none: makeNone
83
+ },
84
+ is: {
85
+ /**
86
+ * Type guard that checks if a Maybe is Some.
87
+ *
88
+ * @example
89
+ * ```ts
90
+ * const value = Maybe.make.some(42);
91
+ * if (Maybe.is.some(value)) {
92
+ * console.log(value.value); // 42
93
+ * }
94
+ * ```
95
+ */
96
+ some: isSome,
97
+ /**
98
+ * Type guard that checks if a Maybe is None.
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * const value = Maybe.make.none();
103
+ * if (Maybe.is.none(value)) {
104
+ * console.log("No value present");
105
+ * }
106
+ * ```
107
+ */
108
+ none: isNone
109
+ },
110
+ // --- to ---
111
+ to: {
112
+ /**
113
+ * Extracts the value from a Maybe, returning null if None.
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * Maybe.to.nullable(Maybe.make.some(42)); // 42
118
+ * Maybe.to.nullable(Maybe.make.none()); // null
119
+ * ```
120
+ */
121
+ nullable: (data) => isSome(data) ? data.value : null,
122
+ /**
123
+ * Extracts the value from a Maybe, returning undefined if None.
124
+ *
125
+ * @example
126
+ * ```ts
127
+ * Maybe.to.undefined(Maybe.make.some(42)); // 42
128
+ * Maybe.to.undefined(Maybe.make.none()); // undefined
129
+ * ```
130
+ */
131
+ undefined: (data) => isSome(data) ? data.value : globalThis.undefined,
132
+ /**
133
+ * Converts a Maybe to a Result.
134
+ * Some becomes Ok, None becomes Err with the provided error.
135
+ *
136
+ * @example
137
+ * ```ts
138
+ * pipe(
139
+ * Maybe.make.some(42),
140
+ * Maybe.to.Result(() => "Value was missing")
141
+ * ); // Ok(42)
142
+ *
143
+ * pipe(
144
+ * Maybe.make.none(),
145
+ * Maybe.to.Result(() => "Value was missing")
146
+ * ); // Err("Value was missing")
147
+ * ```
148
+ */
149
+ Result: (onNone) => (data) => isSome(data) ? Result.make.ok(data.value) : Result.make.err(onNone())
150
+ },
151
+ // --- from ---
152
+ from: {
153
+ /**
154
+ * Creates a Maybe from a nullable value.
155
+ * Returns None if the value is null or undefined, Some otherwise.
156
+ *
157
+ * @example
158
+ * ```ts
159
+ * Maybe.from.nullable(null); // None
160
+ * Maybe.from.nullable(42); // Some(42)
161
+ * ```
162
+ */
163
+ nullable: (value) => value === null || value === void 0 ? makeNone() : makeSome(value),
164
+ /**
165
+ * Creates a Maybe from a predicate applied to a value.
166
+ * Returns Some if the predicate passes, None otherwise.
167
+ *
168
+ * @example
169
+ * ```ts
170
+ * Maybe.from.Predicate((n: number) => n >= 18)(21); // Some(21)
171
+ * Maybe.from.Predicate((n: number) => n >= 18)(15); // None
172
+ *
173
+ * pipe("hello", Maybe.from.Predicate((s: string) => s.length > 0)); // Some("hello")
174
+ * pipe("", Maybe.from.Predicate((s: string) => s.length > 0)); // None
175
+ * ```
176
+ */
177
+ Predicate: (pred) => (a) => pred(a) ? makeSome(a) : makeNone(),
178
+ /**
179
+ * Creates a Maybe from a Result.
180
+ * Ok becomes Some, Err becomes None (the error is discarded).
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * Maybe.from.Result(Result.make.ok(42)); // Some(42)
185
+ * Maybe.from.Result(Result.make.err("oops")); // None
186
+ * ```
187
+ */
188
+ Result: (data) => Result.is.ok(data) ? makeSome(data.value) : makeNone()
189
+ },
190
+ /**
191
+ * Transforms the value inside a Maybe if it exists.
192
+ *
193
+ * @example
194
+ * ```ts
195
+ * pipe(Maybe.make.some(5), Maybe.map(n => n * 2)); // Some(10)
196
+ * pipe(Maybe.make.none(), Maybe.map(n => n * 2)); // None
197
+ * ```
198
+ */
199
+ map: (f) => (data) => isSome(data) ? makeSome(f(data.value)) : data,
200
+ /**
201
+ * Chains Maybe computations. If the first is Some, passes the value to f.
202
+ * If the first is None, propagates None.
203
+ *
204
+ * @example
205
+ * ```ts
206
+ * const parseNumber = (s: string): Maybe<number> => {
207
+ * const n = parseInt(s, 10);
208
+ * return isNaN(n) ? Maybe.make.none() : Maybe.make.some(n);
209
+ * };
210
+ *
211
+ * pipe(Maybe.make.some("42"), Maybe.chain(parseNumber)); // Some(42)
212
+ * pipe(Maybe.make.some("abc"), Maybe.chain(parseNumber)); // None
213
+ * ```
214
+ */
215
+ chain: (f) => (data) => isSome(data) ? f(data.value) : data,
216
+ /**
217
+ * Extracts the value from a Maybe by providing handlers for both cases.
218
+ *
219
+ * @example
220
+ * ```ts
221
+ * pipe(
222
+ * Maybe.make.some(5),
223
+ * Maybe.fold(
224
+ * () => "No value",
225
+ * n => `Value: ${n}`
226
+ * )
227
+ * ); // "Value: 5"
228
+ * ```
229
+ */
230
+ fold: (onNone, onSome) => (data) => isSome(data) ? onSome(data.value) : onNone(),
231
+ /**
232
+ * Pattern matches on a Maybe, returning the result of the matching case.
233
+ *
234
+ * @example
235
+ * ```ts
236
+ * pipe(
237
+ * optionUser,
238
+ * Maybe.match({
239
+ * some: user => `Hello, ${user.name}`,
240
+ * none: () => "Hello, stranger"
241
+ * })
242
+ * );
243
+ * ```
244
+ */
245
+ match: (cases) => (data) => isSome(data) ? cases.some(data.value) : cases.none(),
246
+ /**
247
+ * Returns the value inside a Maybe, or a default value if None.
248
+ * The default is a thunk `() => B` — evaluated only when the Maybe is None.
249
+ * The default can be a different type, widening the result to `A | B`.
250
+ *
251
+ * @example
252
+ * ```ts
253
+ * pipe(Maybe.make.some(5), Maybe.getOrElse(() => 0)); // 5
254
+ * pipe(Maybe.make.none(), Maybe.getOrElse(() => 0)); // 0
255
+ * pipe(Maybe.make.none<string>(), Maybe.getOrElse(() => null)); // null — typed as string | null
256
+ * ```
257
+ */
258
+ getOrElse: (defaultValue) => (data) => isSome(data) ? data.value : defaultValue(),
259
+ /**
260
+ * Executes a side effect on the value without changing the Maybe.
261
+ * Useful for logging or debugging.
262
+ *
263
+ * @example
264
+ * ```ts
265
+ * pipe(
266
+ * Maybe.make.some(5),
267
+ * Maybe.tap(n => console.log("Value:", n)),
268
+ * Maybe.map(n => n * 2)
269
+ * );
270
+ * ```
271
+ */
272
+ tap: (f) => (data) => {
273
+ if (isSome(data)) {
52
274
  f(data.value);
53
275
  }
54
276
  return data;
55
- };
56
- Maybe2.filter = (predicate) => (data) => is.some(data) ? predicate(data.value) ? data : make.none() : data;
57
- Maybe2.recover = (fallback) => (data) => is.some(data) ? data : fallback();
58
- Maybe2.ap = (arg) => (data) => is.some(data) && is.some(arg) ? make.some(data.value(arg.value)) : make.none();
59
- Maybe2.bindTo = (key) => (data) => (0, Maybe2.map)((a) => ({ [key]: a }))(data);
60
- Maybe2.bind = (key, f) => (data) => (0, Maybe2.chain)(
61
- (a) => (0, Maybe2.map)((b) => ({ ...a, [key]: b }))(f(a))
62
- )(data);
63
- Maybe2.struct = (fields) => {
277
+ },
278
+ /**
279
+ * Filters a Maybe based on a predicate.
280
+ * Returns None if the predicate returns false or if the Maybe is already None.
281
+ *
282
+ * @example
283
+ * ```ts
284
+ * pipe(Maybe.make.some(5), Maybe.filter(n => n > 3)); // Some(5)
285
+ * pipe(Maybe.make.some(2), Maybe.filter(n => n > 3)); // None
286
+ * ```
287
+ */
288
+ filter: (predicate) => (data) => isSome(data) ? predicate(data.value) ? data : makeNone() : data,
289
+ /**
290
+ * Recovers from a None by providing a fallback Maybe.
291
+ * The fallback can produce a different type, widening the result to `Maybe<A | B>`.
292
+ *
293
+ * @example
294
+ * ```ts
295
+ * pipe(Maybe.make.none(), Maybe.recover(() => Maybe.make.some(42))); // Some(42)
296
+ * pipe(Maybe.make.some(10), Maybe.recover(() => Maybe.make.some(42))); // Some(10)
297
+ * ```
298
+ */
299
+ recover: (fallback) => (data) => isSome(data) ? data : fallback(),
300
+ /**
301
+ * Applies a function wrapped in a Maybe to a value wrapped in a Maybe.
302
+ *
303
+ * @example
304
+ * ```ts
305
+ * const add = (a: number) => (b: number) => a + b;
306
+ * pipe(
307
+ * Maybe.make.some(add),
308
+ * Maybe.ap(Maybe.make.some(5)),
309
+ * Maybe.ap(Maybe.make.some(3))
310
+ * ); // Some(8)
311
+ * ```
312
+ */
313
+ ap: (arg) => (data) => isSome(data) && isSome(arg) ? makeSome(data.value(arg.value)) : makeNone(),
314
+ /**
315
+ * Converts a Maybe value into an object containing a single property.
316
+ * Initiates the pipeline accumulator record.
317
+ *
318
+ * @example
319
+ * ```ts
320
+ * pipe(Maybe.make.some(42), Maybe.bindTo("value")); // Some({ value: 42 })
321
+ * ```
322
+ */
323
+ bindTo: (key) => (data) => isSome(data) ? makeSome({ [key]: data.value }) : data,
324
+ /**
325
+ * Evaluates a new Maybe using the current accumulator and attaches the output to a new key.
326
+ *
327
+ * @example
328
+ * ```ts
329
+ * pipe(
330
+ * Maybe.make.some({ a: 1 }),
331
+ * Maybe.bind("b", ({ a }) => Maybe.make.some(a + 1))
332
+ * ); // Some({ a: 1, b: 2 })
333
+ * ```
334
+ */
335
+ bind: (key, f) => (data) => {
336
+ if (!isSome(data)) {
337
+ return data;
338
+ }
339
+ const mb = f(data.value);
340
+ return isSome(mb) ? makeSome({ ...data.value, [key]: mb.value }) : mb;
341
+ },
342
+ /**
343
+ * Combines a record of Maybes into a single Maybe of a record.
344
+ * Evaluates fields in key order and short-circuits on the first None.
345
+ *
346
+ * @example
347
+ * ```ts
348
+ * Maybe.struct({
349
+ * name: Maybe.make.some("Alice"),
350
+ * age: Maybe.make.some(30)
351
+ * }); // Some({ name: "Alice", age: 30 })
352
+ * ```
353
+ */
354
+ struct: (fields) => {
64
355
  const result = {};
65
356
  for (const key in fields) {
66
357
  if (Object.hasOwn(fields, key)) {
67
358
  const res = fields[key];
68
- if (is.none(res)) {
359
+ if (isNone(res)) {
69
360
  return res;
70
361
  }
71
362
  result[key] = res.value;
72
363
  }
73
364
  }
74
- return make.some(result);
75
- };
76
- Maybe2.transposeResult = (data) => is.none(data) ? Result.make.ok(make.none()) : Result.is.ok(data.value) ? Result.make.ok(make.some(data.value.value)) : Result.make.err(data.value.error);
77
- })(Maybe || (Maybe = {}));
365
+ return makeSome(result);
366
+ },
367
+ /**
368
+ * Swaps the outer `Maybe` and inner `Result` context.
369
+ * `Some(Ok(a))` becomes `Ok(Some(a))`, `Some(Err(e))` becomes `Err(e)`, and `None` becomes `Ok(None)`.
370
+ *
371
+ * @example
372
+ * ```ts
373
+ * Maybe.transposeResult(Maybe.make.some(Result.make.ok(42))); // Ok(Some(42))
374
+ * Maybe.transposeResult(Maybe.make.some(Result.make.err("e"))); // Err("e")
375
+ * Maybe.transposeResult(Maybe.make.none()); // Ok(None)
376
+ * ```
377
+ */
378
+ transposeResult: (data) => isNone(data) ? Result.make.ok(makeNone()) : Result.is.ok(data.value) ? Result.make.ok(makeSome(data.value.value)) : Result.make.err(data.value.error)
379
+ };
78
380
 
79
381
  // src/Core/Result.ts
80
- var Result;
81
- ((Result2) => {
82
- let make;
83
- ((make2) => {
84
- make2.ok = (value) => ({ kind: "Ok", value });
85
- make2.err = (e) => ({ kind: "Err", error: e });
86
- })(make = Result2.make || (Result2.make = {}));
87
- let is;
88
- ((is2) => {
89
- is2.ok = (data) => data.kind === "Ok";
90
- is2.err = (data) => data.kind === "Err";
91
- })(is = Result2.is || (Result2.is = {}));
92
- Result2.tryCatch = (f, options) => {
382
+ var makeOk = (value) => ({ kind: "Ok", value });
383
+ var makeErr = (e) => ({ kind: "Err", error: e });
384
+ var isOk = (data) => data.kind === "Ok";
385
+ var isErr = (data) => data.kind === "Err";
386
+ var Result = {
387
+ make: {
388
+ /**
389
+ * Creates a successful Result with the given value.
390
+ *
391
+ * @example
392
+ * ```ts
393
+ * Result.make.ok(42); // Ok(42)
394
+ * ```
395
+ */
396
+ ok: makeOk,
397
+ /**
398
+ * Creates a failed Result with the given error.
399
+ *
400
+ * @example
401
+ * ```ts
402
+ * Result.make.err("Error message"); // Err("Error message")
403
+ * ```
404
+ */
405
+ err: makeErr
406
+ },
407
+ is: {
408
+ /**
409
+ * Type guard that checks if a Result is Ok.
410
+ *
411
+ * @example
412
+ * ```ts
413
+ * const res = Result.make.ok(42);
414
+ * if (Result.is.ok(res)) {
415
+ * console.log(res.value); // 42
416
+ * }
417
+ * ```
418
+ */
419
+ ok: isOk,
420
+ /**
421
+ * Type guard that checks if a Result is Err.
422
+ *
423
+ * @example
424
+ * ```ts
425
+ * const res = Result.make.err("failed");
426
+ * if (Result.is.err(res)) {
427
+ * console.log(res.error); // "failed"
428
+ * }
429
+ * ```
430
+ */
431
+ err: isErr
432
+ },
433
+ /**
434
+ * Creates a Result from a synchronous thunk that may throw.
435
+ * Catches any errors and transforms them using the `onError` function.
436
+ *
437
+ * @example
438
+ * ```ts
439
+ * const result = Result.tryCatch(
440
+ * () => JSON.parse(rawString),
441
+ * { onError: (e) => `Parse error: ${e}` }
442
+ * );
443
+ * ```
444
+ */
445
+ tryCatch: (f, options) => {
93
446
  try {
94
- return make.ok(f());
447
+ return makeOk(f());
95
448
  } catch (error) {
96
- return make.err(options.onError(error));
97
- }
98
- };
99
- Result2.map = (f) => (data) => is.ok(data) ? make.ok(f(data.value)) : data;
100
- Result2.mapError = (f) => (data) => is.err(data) ? make.err(f(data.error)) : data;
101
- Result2.chain = (f) => (data) => is.ok(data) ? f(data.value) : data;
102
- Result2.fold = (onErr, onOk) => (data) => is.ok(data) ? onOk(data.value) : onErr(data.error);
103
- Result2.match = (cases) => (data) => is.ok(data) ? cases.ok(data.value) : cases.err(data.error);
104
- Result2.getOrElse = (defaultValue) => (data) => is.ok(data) ? data.value : defaultValue();
105
- Result2.tap = (f) => (data) => {
106
- if (is.ok(data)) {
449
+ return makeErr(options.onError(error));
450
+ }
451
+ },
452
+ /**
453
+ * Transforms the success value inside a Result.
454
+ *
455
+ * @example
456
+ * ```ts
457
+ * pipe(Result.make.ok(5), Result.map(n => n * 2)); // Ok(10)
458
+ * pipe(Result.make.err("error"), Result.map(n => n * 2)); // Err("error")
459
+ * ```
460
+ */
461
+ map: (f) => (data) => isOk(data) ? makeOk(f(data.value)) : data,
462
+ /**
463
+ * Transforms the error value inside a Result.
464
+ *
465
+ * @example
466
+ * ```ts
467
+ * pipe(Result.make.err("oops"), Result.mapError(e => e.toUpperCase())); // Err("OOPS")
468
+ * ```
469
+ */
470
+ mapError: (f) => (data) => isErr(data) ? makeErr(f(data.error)) : data,
471
+ /**
472
+ * Chains Result computations. If the first is Ok, passes the value to f.
473
+ * If the first is Err, propagates the error.
474
+ *
475
+ * @example
476
+ * ```ts
477
+ * const validatePositive = (n: number): Result<string, number> =>
478
+ * n > 0 ? Result.make.ok(n) : Result.make.err("Must be positive");
479
+ *
480
+ * pipe(Result.make.ok(5), Result.chain(validatePositive)); // Ok(5)
481
+ * pipe(Result.make.ok(-1), Result.chain(validatePositive)); // Err("Must be positive")
482
+ * ```
483
+ */
484
+ chain: (f) => (data) => isOk(data) ? f(data.value) : data,
485
+ /**
486
+ * Extracts the value from a Result by providing handlers for both cases.
487
+ *
488
+ * @example
489
+ * ```ts
490
+ * pipe(
491
+ * Result.make.ok(5),
492
+ * Result.fold(
493
+ * e => `Error: ${e}`,
494
+ * n => `Value: ${n}`
495
+ * )
496
+ * ); // "Value: 5"
497
+ * ```
498
+ */
499
+ fold: (onErr, onOk) => (data) => isOk(data) ? onOk(data.value) : onErr(data.error),
500
+ /**
501
+ * Pattern matches on a Result, returning the result of the matching case.
502
+ *
503
+ * @example
504
+ * ```ts
505
+ * pipe(
506
+ * result,
507
+ * Result.match({
508
+ * ok: value => `Got ${value}`,
509
+ * err: error => `Failed: ${error}`
510
+ * })
511
+ * );
512
+ * ```
513
+ */
514
+ match: (cases) => (data) => isOk(data) ? cases.ok(data.value) : cases.err(data.error),
515
+ /**
516
+ * Returns the success value or a default value if the Result is an error.
517
+ * The default is a thunk `() => B` — evaluated only when the Result is Err.
518
+ * The default can be a different type, widening the result to `A | B`.
519
+ *
520
+ * @example
521
+ * ```ts
522
+ * pipe(Result.make.ok(5), Result.getOrElse(() => 0)); // 5
523
+ * pipe(Result.make.err("error"), Result.getOrElse(() => 0)); // 0
524
+ * pipe(Result.make.err("error"), Result.getOrElse(() => null)); // null — typed as number | null
525
+ * ```
526
+ */
527
+ getOrElse: (defaultValue) => (data) => isOk(data) ? data.value : defaultValue(),
528
+ /**
529
+ * Executes a side effect on the success value without changing the Result.
530
+ * Useful for logging or debugging.
531
+ *
532
+ * @example
533
+ * ```ts
534
+ * pipe(
535
+ * Result.make.ok(5),
536
+ * Result.tap(n => console.log("Value:", n)),
537
+ * Result.map(n => n * 2)
538
+ * );
539
+ * ```
540
+ */
541
+ tap: (f) => (data) => {
542
+ if (isOk(data)) {
107
543
  f(data.value);
108
544
  }
109
545
  return data;
110
- };
111
- Result2.tapError = (f) => (data) => {
112
- if (is.err(data)) {
546
+ },
547
+ /**
548
+ * Executes a side effect on the error value without changing the Result.
549
+ * Useful for logging or reporting errors.
550
+ *
551
+ * @example
552
+ * ```ts
553
+ * pipe(
554
+ * Result.make.err("not found"),
555
+ * Result.tapError(e => console.error("validation failed:", e)),
556
+ * Result.chain(save),
557
+ * )
558
+ * ```
559
+ */
560
+ tapError: (f) => (data) => {
561
+ if (isErr(data)) {
113
562
  f(data.error);
114
563
  }
115
564
  return data;
116
- };
117
- let from;
118
- ((from2) => {
119
- from2.Predicate = (pred, onFalse) => (a) => pred(a) ? make.ok(a) : make.err(onFalse(a));
120
- from2.nullable = (onNull) => (value) => value === null || value === void 0 ? make.err(onNull()) : make.ok(value);
121
- from2.Maybe = (onNone) => (maybe) => Maybe.is.none(maybe) ? make.err(onNone()) : make.ok(maybe.value);
122
- from2.Validation = (combineErrors) => (val) => Validation.is.passed(val) ? make.ok(val.value) : make.err(combineErrors(val.errors));
123
- })(from = Result2.from || (Result2.from = {}));
124
- Result2.recover = (fallback) => (data) => is.ok(data) ? data : fallback(data.error);
125
- Result2.recoverUnless = (isBlocked, fallback) => (data) => is.err(data) && !isBlocked(data.error) ? fallback() : data;
126
- let to;
127
- ((to2) => {
128
- to2.Maybe = (data) => is.ok(data) ? Maybe.make.some(data.value) : Maybe.make.none();
129
- to2.Validation = (data) => Validation.from.Result(data);
130
- })(to = Result2.to || (Result2.to = {}));
131
- Result2.transposeMaybe = (data) => is.err(data) ? Maybe.make.some(data) : Maybe.is.some(data.value) ? Maybe.make.some(make.ok(data.value.value)) : Maybe.make.none();
132
- Result2.ap = (arg) => (data) => is.ok(data) && is.ok(arg) ? make.ok(data.value(arg.value)) : is.err(data) ? data : arg;
133
- Result2.bindTo = (key) => (data) => (0, Result2.map)((a) => ({ [key]: a }))(data);
134
- Result2.bind = (key, f) => (data) => (0, Result2.chain)(
135
- (a) => (0, Result2.map)((b) => ({ ...a, [key]: b }))(f(a))
136
- )(data);
137
- Result2.struct = (fields) => {
565
+ },
566
+ // --- from ---
567
+ from: {
568
+ /**
569
+ * Creates a Result from a predicate applied to a value.
570
+ * Returns Ok if the predicate passes, Err from onFalse otherwise.
571
+ *
572
+ * @example
573
+ * ```ts
574
+ * pipe(5, Result.from.Predicate(n => n > 0, n => `${n} is not positive`)); // Ok(5)
575
+ * pipe(-1, Result.from.Predicate(n => n > 0, n => `${n} is not positive`)); // Err("-1 is not positive")
576
+ * pipe("", Result.from.Predicate(s => s.length > 0, () => "empty string")); // Err("empty string")
577
+ * ```
578
+ */
579
+ Predicate: (pred, onFalse) => (a) => pred(a) ? makeOk(a) : makeErr(onFalse(a)),
580
+ /**
581
+ * Creates a Result from a nullable value.
582
+ * Returns Ok if the value is not null or undefined, error from onNull otherwise.
583
+ *
584
+ * @example
585
+ * ```ts
586
+ * pipe(null, Result.from.nullable(() => "is null")); // Err("is null")
587
+ * pipe(42, Result.from.nullable(() => "is null")); // Ok(42)
588
+ * ```
589
+ */
590
+ nullable: (onNull) => (value) => value === null || value === void 0 ? makeErr(onNull()) : makeOk(value),
591
+ /**
592
+ * Creates a Result from a Maybe.
593
+ * Some becomes Ok, None becomes error from onNone.
594
+ *
595
+ * @example
596
+ * ```ts
597
+ * pipe(Maybe.make.none(), Result.from.Maybe(() => "is none")); // Err("is none")
598
+ * pipe(Maybe.make.some(42), Result.from.Maybe(() => "is none")); // Ok(42)
599
+ * ```
600
+ */
601
+ Maybe: (onNone) => (maybe) => Maybe.is.none(maybe) ? makeErr(onNone()) : makeOk(maybe.value),
602
+ /**
603
+ * Converts a `Validation` to a `Result`, combining accumulated errors using `combineErrors`.
604
+ * `Passed(a)` becomes `Ok(a)`; `Failed(errors)` becomes `Err(combineErrors(errors))`.
605
+ *
606
+ * @example
607
+ * ```ts
608
+ * Result.from.Validation((errors) => errors.join(", "))(Validation.make.failed("error1")); // Err("error1")
609
+ * ```
610
+ */
611
+ Validation: (combineErrors) => (val) => Validation.is.passed(val) ? makeOk(val.value) : makeErr(combineErrors(val.errors))
612
+ },
613
+ /**
614
+ * Recovers from an error by providing a fallback Result.
615
+ * The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
616
+ */
617
+ recover: (fallback) => (data) => isOk(data) ? data : fallback(data.error),
618
+ /**
619
+ * Recovers from an error unless the predicate `isBlocked` returns true for that error.
620
+ * The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
621
+ *
622
+ * @example
623
+ * ```ts
624
+ * pipe(
625
+ * Result.make.err(new Error("not found")),
626
+ * Result.recoverUnless(e => e.message === "fatal", () => Result.make.ok(0))
627
+ * ); // Ok(0)
628
+ * ```
629
+ */
630
+ recoverUnless: (isBlocked, fallback) => (data) => isErr(data) && !isBlocked(data.error) ? fallback() : data,
631
+ // --- to ---
632
+ to: {
633
+ /**
634
+ * Converts a Result to a Maybe.
635
+ * Ok becomes Some, Err becomes None (the error is discarded).
636
+ *
637
+ * @example
638
+ * ```ts
639
+ * Result.to.Maybe(Result.make.ok(42)); // Some(42)
640
+ * Result.to.Maybe(Result.make.err("oops")); // None
641
+ * ```
642
+ */
643
+ Maybe: (data) => isOk(data) ? Maybe.make.some(data.value) : Maybe.make.none(),
644
+ /**
645
+ * Converts a `Result` to a `Validation`. `Ok(a)` becomes `Passed(a)`; `Err(e)` becomes `Failed([e])`.
646
+ *
647
+ * @example
648
+ * ```ts
649
+ * Result.to.Validation(Result.make.ok(42)); // Passed(42)
650
+ * Result.to.Validation(Result.make.err("bad")); // Failed(["bad"])
651
+ * ```
652
+ */
653
+ Validation: (data) => Validation.from.Result(data)
654
+ },
655
+ /**
656
+ * Swaps the outer `Result` and inner `Maybe` context.
657
+ * `Ok(Some(a))` becomes `Some(Ok(a))`, `Ok(None)` becomes `None`, and `Err(e)` becomes `Some(Err(e))`.
658
+ *
659
+ * @example
660
+ * ```ts
661
+ * Result.transposeMaybe(Result.make.ok(Maybe.make.some(42))); // Some(Ok(42))
662
+ * Result.transposeMaybe(Result.make.ok(Maybe.make.none())); // None
663
+ * Result.transposeMaybe(Result.make.err("error")); // Some(Err("error"))
664
+ * ```
665
+ */
666
+ transposeMaybe: (data) => isErr(data) ? Maybe.make.some(data) : Maybe.is.some(data.value) ? Maybe.make.some(makeOk(data.value.value)) : Maybe.make.none(),
667
+ /**
668
+ * Applies a function wrapped in a Result to a value wrapped in a Result.
669
+ *
670
+ * @example
671
+ * ```ts
672
+ * const add = (a: number) => (b: number) => a + b;
673
+ * pipe(
674
+ * Result.make.ok(add),
675
+ * Result.ap(Result.make.ok(5)),
676
+ * Result.ap(Result.make.ok(3))
677
+ * ); // Ok(8)
678
+ * ```
679
+ */
680
+ ap: (arg) => (data) => isOk(data) && isOk(arg) ? makeOk(data.value(arg.value)) : isErr(data) ? data : arg,
681
+ /**
682
+ * Converts a Result value into an object containing a single property.
683
+ * Initiates the pipeline accumulator record.
684
+ *
685
+ * @example
686
+ * ```ts
687
+ * pipe(Result.make.ok(42), Result.bindTo("value")); // Ok({ value: 42 })
688
+ * ```
689
+ */
690
+ bindTo: (key) => (data) => isOk(data) ? makeOk({ [key]: data.value }) : data,
691
+ /**
692
+ * Evaluates a new Result using the current accumulator and attaches the output to a new key.
693
+ *
694
+ * @example
695
+ * ```ts
696
+ * pipe(
697
+ * Result.make.ok({ a: 1 }),
698
+ * Result.bind("b", ({ a }) => Result.make.ok(a + 1))
699
+ * ); // Ok({ a: 1, b: 2 })
700
+ * ```
701
+ */
702
+ bind: (key, f) => (data) => {
703
+ if (!isOk(data)) {
704
+ return data;
705
+ }
706
+ const res = f(data.value);
707
+ return isOk(res) ? makeOk({ ...data.value, [key]: res.value }) : res;
708
+ },
709
+ /**
710
+ * Combines a record of Results into a single Result of a record.
711
+ * Evaluates fields in key order and short-circuits on the first failure.
712
+ *
713
+ * @example
714
+ * ```ts
715
+ * Result.struct({
716
+ * name: Result.make.ok("Alice"),
717
+ * age: Result.make.ok(30)
718
+ * }); // Ok({ name: "Alice", age: 30 })
719
+ * ```
720
+ */
721
+ struct: (fields) => {
138
722
  const result = {};
139
723
  for (const key in fields) {
140
724
  if (Object.hasOwn(fields, key)) {
141
725
  const res = fields[key];
142
- if (is.err(res)) {
726
+ if (isErr(res)) {
143
727
  return res;
144
728
  }
145
729
  result[key] = res.value;
146
730
  }
147
731
  }
148
- return make.ok(result);
149
- };
150
- Result2.ensure = (predicate, onFail) => (data) => is.err(data) ? data : predicate(data.value) ? data : make.err(onFail(data.value));
151
- Result2.bimap = (onErr, onOk) => (data) => is.ok(data) ? make.ok(onOk(data.value)) : make.err(onErr(data.error));
152
- })(Result || (Result = {}));
732
+ return makeOk(result);
733
+ },
734
+ /**
735
+ * Narrows an `Ok` value with a predicate, converting to `Err(onFail(a))` if the predicate returns false.
736
+ *
737
+ * @example
738
+ * ```ts
739
+ * pipe(
740
+ * Result.make.ok(15),
741
+ * Result.ensure((n) => n >= 18, (n) => `Age ${n} is below 18`)
742
+ * ); // Err("Age 15 is below 18")
743
+ * ```
744
+ */
745
+ ensure: (predicate, onFail) => (data) => isErr(data) ? data : predicate(data.value) ? data : makeErr(onFail(data.value)),
746
+ /**
747
+ * Transforms both branches of a Result simultaneously.
748
+ * Applies `onErr` to `Err` values and `onOk` to `Ok` values.
749
+ *
750
+ * @example
751
+ * ```ts
752
+ * pipe(
753
+ * Result.make.ok(5),
754
+ * Result.bimap(
755
+ * (e) => `Error: ${e}`,
756
+ * (n) => n * 2
757
+ * )
758
+ * ); // Ok(10)
759
+ * ```
760
+ */
761
+ bimap: (onErr, onOk) => (data) => isOk(data) ? makeOk(onOk(data.value)) : makeErr(onErr(data.error))
762
+ };
153
763
 
154
764
  // src/internal/InternalTypes.ts
155
765
  var isNonEmptyArr = (list) => list.length > 0;
156
766
 
157
767
  // src/Core/Validation.ts
158
- var Validation;
159
- ((Validation2) => {
160
- let make;
161
- ((make2) => {
162
- make2.passed = (value) => ({ kind: "Passed", value });
163
- make2.failed = (error) => ({ kind: "Failed", errors: [error] });
164
- make2.failedAll = (errors) => ({ kind: "Failed", errors });
165
- })(make = Validation2.make || (Validation2.make = {}));
166
- let is;
167
- ((is2) => {
168
- is2.passed = (data) => data.kind === "Passed";
169
- is2.failed = (data) => data.kind === "Failed";
170
- })(is = Validation2.is || (Validation2.is = {}));
171
- Validation2.tryCatch = (f, options) => {
768
+ var makePassed = (value) => ({ kind: "Passed", value });
769
+ var makeFailed = (error) => ({ kind: "Failed", errors: [error] });
770
+ var makeFailedAll = (errors) => ({ kind: "Failed", errors });
771
+ var isPassed = (data) => data.kind === "Passed";
772
+ var isFailed = (data) => data.kind === "Failed";
773
+ function toResult(arg) {
774
+ if (typeof arg === "function") {
775
+ const combine = arg;
776
+ return (val) => isPassed(val) ? Result.make.ok(val.value) : Result.make.err(combine(val.errors));
777
+ }
778
+ return isPassed(arg) ? Result.make.ok(arg.value) : Result.make.err(arg.errors);
779
+ }
780
+ var Validation = {
781
+ make: {
782
+ /**
783
+ * Wraps a value in a passed Validation.
784
+ *
785
+ * @example
786
+ * ```ts
787
+ * Validation.make.passed(42); // Passed(42)
788
+ * ```
789
+ */
790
+ passed: makePassed,
791
+ /**
792
+ * Creates a failed Validation from a single error.
793
+ *
794
+ * @example
795
+ * ```ts
796
+ * Validation.make.failed("Invalid input");
797
+ * ```
798
+ */
799
+ failed: makeFailed,
800
+ /**
801
+ * Creates a failed Validation from multiple errors.
802
+ *
803
+ * @example
804
+ * ```ts
805
+ * Validation.make.failedAll(["Invalid input"]);
806
+ * ```
807
+ */
808
+ failedAll: makeFailedAll
809
+ },
810
+ is: {
811
+ /**
812
+ * Type guard that checks if a Validation is passed.
813
+ *
814
+ * @example
815
+ * ```ts
816
+ * const v = Validation.make.passed(42);
817
+ * if (Validation.is.passed(v)) {
818
+ * console.log(v.value); // 42
819
+ * }
820
+ * ```
821
+ */
822
+ passed: isPassed,
823
+ /**
824
+ * Type guard that checks if a Validation is failed.
825
+ *
826
+ * @example
827
+ * ```ts
828
+ * const v = Validation.make.failed("invalid");
829
+ * if (Validation.is.failed(v)) {
830
+ * console.log(v.errors); // ["invalid"]
831
+ * }
832
+ * ```
833
+ */
834
+ failed: isFailed
835
+ },
836
+ /**
837
+ * Creates a Validation from a synchronous thunk that may throw.
838
+ * Catches any errors and transforms them using the `onError` function into a Failed validation.
839
+ *
840
+ * @example
841
+ * ```ts
842
+ * const result = Validation.tryCatch(
843
+ * () => JSON.parse(rawString),
844
+ * { onError: (e) => `Parse error: ${e}` }
845
+ * );
846
+ * ```
847
+ */
848
+ tryCatch: (f, options) => {
172
849
  try {
173
- return make.passed(f());
850
+ return makePassed(f());
174
851
  } catch (error) {
175
- return make.failed(options.onError(error));
852
+ return makeFailed(options.onError(error));
176
853
  }
177
- };
178
- let from;
179
- ((from2) => {
180
- from2.Predicate = (pred, onFalse) => (a) => pred(a) ? make.passed(a) : make.failed(onFalse(a));
181
- from2.nullable = (onNull) => (value) => value === null || value === void 0 ? make.failed(onNull()) : make.passed(value);
182
- from2.Maybe = (onNone) => (maybe) => Maybe.is.none(maybe) ? make.failed(onNone()) : make.passed(maybe.value);
183
- from2.Result = (data) => data.kind === "Ok" ? make.passed(data.value) : make.failed(data.error);
184
- })(from = Validation2.from || (Validation2.from = {}));
185
- Validation2.map = (f) => (data) => is.passed(data) ? make.passed(f(data.value)) : data;
186
- Validation2.mapError = (f) => (data) => is.failed(data) ? make.failedAll(data.errors.map(f)) : data;
187
- Validation2.ap = (arg) => (data) => {
188
- if (is.passed(data)) {
189
- return is.passed(arg) ? make.passed(data.value(arg.value)) : make.failedAll(arg.errors);
190
- }
191
- return is.passed(arg) ? make.failedAll(data.errors) : make.failedAll([...data.errors, ...arg.errors]);
192
- };
193
- Validation2.apCustom = (concat) => (arg) => (data) => {
194
- if (is.passed(data)) {
195
- return is.passed(arg) ? make.passed(data.value(arg.value)) : make.failedAll(arg.errors);
196
- }
197
- return is.passed(arg) ? make.failedAll(data.errors) : make.failedAll(concat(data.errors, arg.errors));
198
- };
199
- Validation2.fold = (onFailed, onPassed) => (data) => is.passed(data) ? onPassed(data.value) : onFailed(data.errors);
200
- Validation2.match = (cases) => (data) => is.passed(data) ? cases.passed(data.value) : cases.failed(data.errors);
201
- Validation2.getOrElse = (defaultValue) => (data) => is.passed(data) ? data.value : defaultValue();
202
- Validation2.tap = (f) => (data) => {
203
- if (is.passed(data)) {
854
+ },
855
+ // --- from ---
856
+ from: {
857
+ /**
858
+ * Creates a Validation from a predicate applied to a value.
859
+ * Returns Passed if the predicate passes, Failed from `onFalse` otherwise.
860
+ *
861
+ * @example
862
+ * ```ts
863
+ * const validateName = Validation.from.Predicate(
864
+ * (s: string) => s.length > 0,
865
+ * () => "Name is required"
866
+ * );
867
+ *
868
+ * validateName("Alice"); // Passed("Alice")
869
+ * validateName(""); // Failed(["Name is required"])
870
+ * ```
871
+ */
872
+ Predicate: (pred, onFalse) => (a) => pred(a) ? makePassed(a) : makeFailed(onFalse(a)),
873
+ /**
874
+ * Creates a Validation from a nullable value.
875
+ * If the value is null or undefined, returns Failed with the error from onNull.
876
+ * Otherwise, returns Passed.
877
+ *
878
+ * @example
879
+ * ```ts
880
+ * pipe(null, Validation.from.nullable(() => "is null")); // Failed(["is null"])
881
+ * pipe(42, Validation.from.nullable(() => "is null")); // Passed(42)
882
+ * ```
883
+ */
884
+ nullable: (onNull) => (value) => value === null || value === void 0 ? makeFailed(onNull()) : makePassed(value),
885
+ /**
886
+ * Creates a Validation from a Maybe.
887
+ * If the Maybe is None, returns Failed with the error from onNone.
888
+ * Otherwise, returns Passed.
889
+ *
890
+ * @example
891
+ * ```ts
892
+ * pipe(Maybe.make.none(), Validation.from.Maybe(() => "is none")); // Failed(["is none"])
893
+ * pipe(Maybe.make.some(42), Validation.from.Maybe(() => "is none")); // Passed(42)
894
+ * ```
895
+ */
896
+ Maybe: (onNone) => (maybe) => Maybe.is.none(maybe) ? makeFailed(onNone()) : makePassed(maybe.value),
897
+ /**
898
+ * Converts a `Result` to a `Validation`. `Ok` becomes `Passed`; `Err(e)` becomes `Failed([e])`.
899
+ *
900
+ * Useful when bridging from error-short-circuiting `Result` pipelines into
901
+ * error-accumulating `Validation` pipelines.
902
+ *
903
+ * @example
904
+ * ```ts
905
+ * Validation.from.Result(Result.make.ok(42)); // Passed(42)
906
+ * Validation.from.Result(Result.make.err("bad")); // Failed(["bad"])
907
+ * ```
908
+ */
909
+ Result: (data) => data.kind === "Ok" ? makePassed(data.value) : makeFailed(data.error)
910
+ },
911
+ /**
912
+ * Transforms the success value inside a Validation.
913
+ *
914
+ * @example
915
+ * ```ts
916
+ * pipe(Validation.make.passed(5), Validation.map(n => n * 2)); // Passed(10)
917
+ * pipe(Validation.make.failed("oops"), Validation.map(n => n * 2)); // Failed(["oops"])
918
+ * ```
919
+ */
920
+ map: (f) => (data) => isPassed(data) ? makePassed(f(data.value)) : data,
921
+ /**
922
+ * Transforms the error list inside a Validation.
923
+ *
924
+ * @example
925
+ * ```ts
926
+ * pipe(Validation.make.failed("oops"), Validation.mapError(e => e.toUpperCase())); // Failed(["OOPS"])
927
+ * ```
928
+ */
929
+ mapError: (f) => (data) => isFailed(data) ? makeFailedAll(data.errors.map(f)) : data,
930
+ /**
931
+ * Applies a function wrapped in a Validation to a value wrapped in a Validation.
932
+ * Accumulates errors from both sides.
933
+ *
934
+ * @example
935
+ * ```ts
936
+ * const add = (a: number) => (b: number) => a + b;
937
+ * pipe(
938
+ * Validation.make.passed(add),
939
+ * Validation.ap(Validation.make.passed(5)),
940
+ * Validation.ap(Validation.make.passed(3))
941
+ * ); // Passed(8)
942
+ *
943
+ * pipe(
944
+ * Validation.make.passed(add),
945
+ * Validation.ap(Validation.make.failed<string>("bad a")),
946
+ * Validation.ap(Validation.make.failed<string>("bad b"))
947
+ * ); // Failed(["bad a", "bad b"])
948
+ * ```
949
+ */
950
+ ap: (arg) => (data) => {
951
+ if (isPassed(data)) {
952
+ return isPassed(arg) ? makePassed(data.value(arg.value)) : makeFailedAll(arg.errors);
953
+ }
954
+ return isPassed(arg) ? makeFailedAll(data.errors) : makeFailedAll([...data.errors, ...arg.errors]);
955
+ },
956
+ /**
957
+ * Applies a function wrapped in a Validation to a value wrapped in a Validation,
958
+ * using a custom error concatenator function when both sides fail.
959
+ *
960
+ * @example
961
+ * ```ts
962
+ * const concat = (e1: NonEmptyArr<string>, e2: NonEmptyArr<string>): NonEmptyArr<string> =>
963
+ * [...e1, ...e2];
964
+ * pipe(fnVal, Validation.apCustom(concat)(argVal));
965
+ * ```
966
+ */
967
+ apCustom: (concat2) => (arg) => (data) => {
968
+ if (isPassed(data)) {
969
+ return isPassed(arg) ? makePassed(data.value(arg.value)) : makeFailedAll(arg.errors);
970
+ }
971
+ return isPassed(arg) ? makeFailedAll(data.errors) : makeFailedAll(concat2(data.errors, arg.errors));
972
+ },
973
+ /**
974
+ * Extracts the value from a Validation by providing handlers for both cases.
975
+ *
976
+ * @example
977
+ * ```ts
978
+ * pipe(
979
+ * Validation.make.passed(42),
980
+ * Validation.fold(
981
+ * errors => `Errors: ${errors.join(", ")}`,
982
+ * value => `Value: ${value}`
983
+ * )
984
+ * );
985
+ * ```
986
+ */
987
+ fold: (onFailed, onPassed) => (data) => isPassed(data) ? onPassed(data.value) : onFailed(data.errors),
988
+ /**
989
+ * Pattern matches on a Validation, returning the result of the matching case.
990
+ *
991
+ * @example
992
+ * ```ts
993
+ * pipe(
994
+ * validation,
995
+ * Validation.match({
996
+ * passed: value => `Got ${value}`,
997
+ * failed: errors => `Failed: ${errors.join(", ")}`
998
+ * })
999
+ * );
1000
+ * ```
1001
+ */
1002
+ match: (cases) => (data) => isPassed(data) ? cases.passed(data.value) : cases.failed(data.errors),
1003
+ /**
1004
+ * Returns the success value or a default value if the Validation is failed.
1005
+ * The default can be a different type, widening the result to `A | B`.
1006
+ *
1007
+ * @example
1008
+ * ```ts
1009
+ * pipe(Validation.make.passed(5), Validation.getOrElse(() => 0)); // 5
1010
+ * pipe(Validation.make.failed("oops"), Validation.getOrElse(() => 0)); // 0
1011
+ * pipe(Validation.make.failed("oops"), Validation.getOrElse(() => null)); // null — typed as number | null
1012
+ * ```
1013
+ */
1014
+ getOrElse: (defaultValue) => (data) => isPassed(data) ? data.value : defaultValue(),
1015
+ /**
1016
+ * Executes a side effect on the success value without changing the Validation.
1017
+ *
1018
+ * @example
1019
+ * ```ts
1020
+ * pipe(
1021
+ * Validation.make.passed(5),
1022
+ * Validation.tap(n => console.log("Value:", n)),
1023
+ * Validation.map(n => n * 2)
1024
+ * );
1025
+ * ```
1026
+ */
1027
+ tap: (f) => (data) => {
1028
+ if (isPassed(data)) {
204
1029
  f(data.value);
205
1030
  }
206
1031
  return data;
207
- };
208
- Validation2.tapError = (f) => (data) => {
209
- if (is.failed(data)) {
1032
+ },
1033
+ /**
1034
+ * Executes a side effect on the accumulated errors without changing the Validation.
1035
+ * Useful for logging or reporting validation failures.
1036
+ *
1037
+ * @example
1038
+ * ```ts
1039
+ * pipe(
1040
+ * Validation.make.failed("Name required"),
1041
+ * Validation.tapError(errors => console.error("validation failed:", errors)),
1042
+ * Validation.map(toUser)
1043
+ * );
1044
+ * ```
1045
+ */
1046
+ tapError: (f) => (data) => {
1047
+ if (isFailed(data)) {
210
1048
  f(data.errors);
211
1049
  }
212
1050
  return data;
213
- };
214
- Validation2.recover = (fallback) => (data) => is.passed(data) ? data : fallback(data.errors);
215
- Validation2.recoverUnless = (isBlocked, fallback) => (data) => is.failed(data) && !data.errors.some(isBlocked) ? fallback() : data;
216
- let to;
217
- ((to2) => {
218
- function Result2(arg) {
219
- if (typeof arg === "function") {
220
- const combine = arg;
221
- return (val) => is.passed(val) ? Result.make.ok(val.value) : Result.make.err(combine(val.errors));
222
- }
223
- return is.passed(arg) ? Result.make.ok(arg.value) : Result.make.err(arg.errors);
224
- }
225
- to2.Result = Result2;
226
- to2.Maybe = (data) => is.passed(data) ? Maybe.make.some(data.value) : Maybe.make.none();
227
- })(to = Validation2.to || (Validation2.to = {}));
228
- Validation2.product = (first, second) => {
229
- if (is.passed(first)) {
230
- return is.passed(second) ? make.passed([first.value, second.value]) : make.failedAll(second.errors);
231
- }
232
- return is.passed(second) ? make.failedAll(first.errors) : make.failedAll([...first.errors, ...second.errors]);
233
- };
234
- Validation2.productAll = (data) => {
235
- const values = [];
1051
+ },
1052
+ /**
1053
+ * Recovers from a Failed state by providing a fallback Validation.
1054
+ * The fallback receives the accumulated error list so callers can inspect which errors occurred.
1055
+ * The fallback can produce a different success type, widening the result to `Validation<E, A | B>`.
1056
+ */
1057
+ recover: (fallback) => (data) => isPassed(data) ? data : fallback(data.errors),
1058
+ /**
1059
+ * Recovers from a Failed state unless `isBlocked` returns true for any of the accumulated errors.
1060
+ * The fallback can produce a different success type, widening the result to `Validation<E, A | B>`.
1061
+ *
1062
+ * @example
1063
+ * ```ts
1064
+ * pipe(
1065
+ * Validation.make.failed("field-error"),
1066
+ * Validation.recoverUnless(e => e === "fatal", () => Validation.make.passed(0))
1067
+ * ); // Passed(0)
1068
+ * ```
1069
+ */
1070
+ recoverUnless: (isBlocked, fallback) => (data) => isFailed(data) && !data.errors.some(isBlocked) ? fallback() : data,
1071
+ // --- to ---
1072
+ to: {
1073
+ /**
1074
+ * Converts a Validation to a Result.
1075
+ * Passed becomes Ok.
1076
+ * Direct call converts Failed to Err with accumulated error list `NonEmptyArr<E>`.
1077
+ * Curried call converts Failed to Err with combined error `E2` via `combineErrors`.
1078
+ *
1079
+ * @example
1080
+ * ```ts
1081
+ * Validation.to.Result(Validation.make.passed(42)); // Ok(42)
1082
+ * Validation.to.Result(Validation.make.failed("oops")); // Err(["oops"])
1083
+ * pipe(Validation.make.failed("oops"), Validation.to.Result(errors => errors.join(", "))); // Err("oops")
1084
+ * ```
1085
+ */
1086
+ Result: toResult,
1087
+ /**
1088
+ * Converts a Validation to a Maybe. `Passed` becomes `Some`; `Failed` becomes `None`
1089
+ * (errors are discarded).
1090
+ *
1091
+ * @example
1092
+ * ```ts
1093
+ * Validation.to.Maybe(Validation.make.passed(42)); // Some(42)
1094
+ * Validation.to.Maybe(Validation.make.failed("bad")); // None
1095
+ * ```
1096
+ */
1097
+ Maybe: (data) => isPassed(data) ? Maybe.make.some(data.value) : Maybe.make.none()
1098
+ },
1099
+ /**
1100
+ * Combines two independent Validation instances into a tuple.
1101
+ * If both are Passed, returns Passed with both values as a tuple.
1102
+ * If either is Failed, accumulates errors from both sides.
1103
+ *
1104
+ * @example
1105
+ * ```ts
1106
+ * Validation.product(
1107
+ * Validation.make.passed("alice"),
1108
+ * Validation.make.passed(30)
1109
+ * ); // Passed(["alice", 30])
1110
+ *
1111
+ * Validation.product(
1112
+ * Validation.make.failed("Name required"),
1113
+ * Validation.make.failed("Age must be >= 0")
1114
+ * ); // Failed(["Name required", "Age must be >= 0"])
1115
+ * ```
1116
+ */
1117
+ product: (first, second) => {
1118
+ if (isPassed(first)) {
1119
+ return isPassed(second) ? makePassed([first.value, second.value]) : makeFailedAll(second.errors);
1120
+ }
1121
+ return isPassed(second) ? makeFailedAll(first.errors) : makeFailedAll([...first.errors, ...second.errors]);
1122
+ },
1123
+ /**
1124
+ * Combines a non-empty list of Validation instances, accumulating all errors.
1125
+ * If all are Passed, returns Passed with all values collected into an array.
1126
+ * If any are Failed, returns Failed with all accumulated errors.
1127
+ *
1128
+ * @example
1129
+ * ```ts
1130
+ * Validation.productAll([
1131
+ * validateName(name),
1132
+ * validateEmail(email),
1133
+ * validateAge(age)
1134
+ * ]);
1135
+ * // Passed([name, email, age]) or Failed([...all errors])
1136
+ * ```
1137
+ */
1138
+ productAll: (data) => {
1139
+ const values3 = [];
236
1140
  const errors = [];
237
1141
  for (const v of data) {
238
- if (is.passed(v)) {
239
- values.push(v.value);
1142
+ if (isPassed(v)) {
1143
+ values3.push(v.value);
240
1144
  } else {
241
1145
  errors.push(...v.errors);
242
1146
  }
243
1147
  }
244
- return isNonEmptyArr(errors) ? make.failedAll(errors) : make.passed(values);
245
- };
246
- Validation2.struct = (fields) => {
1148
+ return isNonEmptyArr(errors) ? makeFailedAll(errors) : makePassed(values3);
1149
+ },
1150
+ /**
1151
+ * Combines a record of Validations into a single Validation of a record.
1152
+ * Accumulates all failed branches' errors.
1153
+ *
1154
+ * @example
1155
+ * ```ts
1156
+ * Validation.struct({
1157
+ * name: Validation.make.passed("Alice"),
1158
+ * age: Validation.make.passed(30)
1159
+ * }); // Passed({ name: "Alice", age: 30 })
1160
+ *
1161
+ * Validation.struct({
1162
+ * name: Validation.make.failed("Name required"),
1163
+ * age: Validation.make.failed("Age must be >= 0")
1164
+ * }); // Failed(["Name required", "Age must be >= 0"])
1165
+ * ```
1166
+ */
1167
+ struct: (fields) => {
247
1168
  const record = {};
248
1169
  const errors = [];
249
1170
  for (const key in fields) {
250
1171
  if (Object.hasOwn(fields, key)) {
251
1172
  const val = fields[key];
252
- if (is.passed(val)) {
1173
+ if (isPassed(val)) {
253
1174
  record[key] = val.value;
254
1175
  } else {
255
1176
  errors.push(...val.errors);
256
1177
  }
257
1178
  }
258
1179
  }
259
- return isNonEmptyArr(errors) ? make.failedAll(errors) : make.passed(record);
260
- };
261
- })(Validation || (Validation = {}));
1180
+ return isNonEmptyArr(errors) ? makeFailedAll(errors) : makePassed(record);
1181
+ }
1182
+ };
262
1183
 
263
1184
  // src/Data/Arr.ts
264
1185
  var ArrMaybe;
@@ -314,448 +1235,553 @@ var ArrTask;
314
1235
  ArrTask2.sequence = (data) => (0, ArrTask2.traverse)((a) => a)(data);
315
1236
  ArrTask2.Result = ArrTaskResult;
316
1237
  })(ArrTask || (ArrTask = {}));
317
- var ArrNonEmpty;
318
- ((ArrNonEmpty2) => {
319
- ArrNonEmpty2.singleton = (value) => [value];
320
- let from;
321
- ((from2) => {
322
- from2.Array = (data) => isNonEmptyArr(data) ? Maybe.make.some(data) : Maybe.make.none();
323
- })(from = ArrNonEmpty2.from || (ArrNonEmpty2.from = {}));
324
- ArrNonEmpty2.head = (data) => data[0];
325
- ArrNonEmpty2.last = (data) => data[data.length - 1];
326
- ArrNonEmpty2.tail = (data) => data.slice(1);
327
- ArrNonEmpty2.reduce = (f) => (data) => data.reduce(f);
328
- ArrNonEmpty2.map = (f) => (data) => Arr.map(f)(data);
329
- ArrNonEmpty2.mapWithIndex = (f) => (data) => Arr.mapWithIndex(f)(data);
330
- ArrNonEmpty2.intersperse = (sep) => (data) => Arr.intersperse(sep)(data);
331
- ArrNonEmpty2.concat = (other) => (data) => Arr.concat(other)(data);
332
- ArrNonEmpty2.reverse = (data) => Arr.reverse(data);
333
- })(ArrNonEmpty || (ArrNonEmpty = {}));
334
- var Arr;
335
- ((Arr2) => {
336
- Arr2.head = (data) => data.length > 0 ? Maybe.make.some(data[0]) : Maybe.make.none();
337
- Arr2.last = (data) => data.length > 0 ? Maybe.make.some(data[data.length - 1]) : Maybe.make.none();
338
- Arr2.tail = (data) => data.length > 0 ? Maybe.make.some(data.slice(1)) : Maybe.make.none();
339
- Arr2.init = (data) => data.length > 0 ? Maybe.make.some(data.slice(0, -1)) : Maybe.make.none();
340
- Arr2.findFirst = (predicate) => (data) => {
341
- const idx = data.findIndex(predicate);
342
- return idx !== -1 ? Maybe.make.some(data[idx]) : Maybe.make.none();
343
- };
344
- Arr2.findLast = (predicate) => (data) => {
345
- for (let i = data.length - 1; i >= 0; i--) {
346
- if (predicate(data[i])) {
347
- return Maybe.make.some(data[i]);
348
- }
1238
+ var head = (data) => data.length > 0 ? Maybe.make.some(data[0]) : Maybe.make.none();
1239
+ var last = (data) => data.length > 0 ? Maybe.make.some(data[data.length - 1]) : Maybe.make.none();
1240
+ var tail = (data) => data.length > 0 ? Maybe.make.some(data.slice(1)) : Maybe.make.none();
1241
+ var init = (data) => data.length > 0 ? Maybe.make.some(data.slice(0, -1)) : Maybe.make.none();
1242
+ var findFirst = (predicate) => (data) => {
1243
+ const idx = data.findIndex(predicate);
1244
+ return idx !== -1 ? Maybe.make.some(data[idx]) : Maybe.make.none();
1245
+ };
1246
+ var findLast = (predicate) => (data) => {
1247
+ for (let i = data.length - 1; i >= 0; i--) {
1248
+ if (predicate(data[i])) {
1249
+ return Maybe.make.some(data[i]);
349
1250
  }
350
- return Maybe.make.none();
351
- };
352
- Arr2.findIndex = (predicate) => (data) => {
353
- const idx = data.findIndex(predicate);
354
- return idx !== -1 ? Maybe.make.some(idx) : Maybe.make.none();
355
- };
356
- Arr2.map = (f) => (data) => {
357
- const n = data.length;
358
- const result = new Array(n);
359
- for (let i = 0; i < n; i++) {
360
- result[i] = f(data[i]);
1251
+ }
1252
+ return Maybe.make.none();
1253
+ };
1254
+ var findIndex = (predicate) => (data) => {
1255
+ const idx = data.findIndex(predicate);
1256
+ return idx !== -1 ? Maybe.make.some(idx) : Maybe.make.none();
1257
+ };
1258
+ var map = (f) => (data) => {
1259
+ const n = data.length;
1260
+ const result = new Array(n);
1261
+ for (let i = 0; i < n; i++) {
1262
+ result[i] = f(data[i]);
1263
+ }
1264
+ return result;
1265
+ };
1266
+ var mapWithIndex = (f) => (data) => {
1267
+ const n = data.length;
1268
+ const result = new Array(n);
1269
+ for (let i = 0; i < n; i++) {
1270
+ result[i] = f(i, data[i]);
1271
+ }
1272
+ return result;
1273
+ };
1274
+ var filter = (predicate) => (data) => {
1275
+ const n = data.length;
1276
+ const result = [];
1277
+ for (let i = 0; i < n; i++) {
1278
+ if (predicate(data[i])) {
1279
+ result.push(data[i]);
361
1280
  }
362
- return result;
363
- };
364
- Arr2.mapWithIndex = (f) => (data) => {
365
- const n = data.length;
366
- const result = new Array(n);
367
- for (let i = 0; i < n; i++) {
368
- result[i] = f(i, data[i]);
1281
+ }
1282
+ return result;
1283
+ };
1284
+ var filterMap = (f) => (data) => {
1285
+ const result = [];
1286
+ for (let i = 0; i < data.length; i++) {
1287
+ const mapped = f(data[i]);
1288
+ if (mapped.kind === "Some") {
1289
+ result.push(mapped.value);
369
1290
  }
370
- return result;
371
- };
372
- Arr2.filter = (predicate) => (data) => {
373
- const n = data.length;
374
- const result = [];
375
- for (let i = 0; i < n; i++) {
376
- if (predicate(data[i])) {
377
- result.push(data[i]);
378
- }
379
- }
380
- return result;
381
- };
382
- Arr2.filterMap = (f) => (data) => {
383
- const result = [];
384
- for (let i = 0; i < data.length; i++) {
385
- const mapped = f(data[i]);
386
- if (mapped.kind === "Some") {
387
- result.push(mapped.value);
388
- }
389
- }
390
- return result;
391
- };
392
- Arr2.partition = (predicate) => (data) => {
393
- const pass = [];
394
- const fail = [];
395
- for (const a of data) {
396
- (predicate(a) ? pass : fail).push(a);
397
- }
398
- return [pass, fail];
399
- };
400
- Arr2.compact = (data) => {
401
- const result = [];
402
- for (const item of data) {
403
- if (item.kind === "Some") {
404
- result.push(item.value);
405
- }
406
- }
407
- return result;
408
- };
409
- Arr2.separate = (data) => {
410
- const errors = [];
411
- const successes = [];
412
- for (const item of data) {
413
- if (item.kind === "Ok") {
414
- successes.push(item.value);
415
- } else {
416
- errors.push(item.error);
417
- }
418
- }
419
- return [errors, successes];
420
- };
421
- Arr2.partitionMap = (f) => (data) => {
422
- const errors = [];
423
- const successes = [];
424
- for (const item of data) {
425
- const mapped = f(item);
426
- if (mapped.kind === "Ok") {
427
- successes.push(mapped.value);
428
- } else {
429
- errors.push(mapped.error);
430
- }
431
- }
432
- return [errors, successes];
433
- };
434
- Arr2.groupBy = (f) => (data) => {
435
- const result = {};
436
- for (const a of data) {
437
- const key = f(a);
438
- if (!result[key]) {
439
- result[key] = [];
440
- }
441
- result[key].push(a);
442
- }
443
- return result;
444
- };
445
- Arr2.uniq = (data) => data.length <= 1 ? data : [...new Set(data)];
446
- Arr2.uniqBy = (f) => (data) => {
447
- const seen = /* @__PURE__ */ new Set();
448
- const result = [];
449
- for (const a of data) {
450
- const key = f(a);
451
- if (!seen.has(key)) {
452
- seen.add(key);
453
- result.push(a);
454
- }
455
- }
456
- return result;
457
- };
458
- Arr2.uniqWith = (eq) => (data) => {
459
- const result = [];
460
- for (const a of data) {
461
- if (!result.some((x) => eq(x, a))) {
462
- result.push(a);
463
- }
464
- }
465
- return result;
466
- };
467
- Arr2.sortBy = (compare) => (data) => {
468
- const arr = data;
469
- if (typeof arr.toSorted === "function") {
470
- return arr.toSorted(compare);
471
- }
472
- return [...data].sort(compare);
473
- };
474
- Arr2.sortWith = (ord) => (data) => {
475
- const arr = data;
476
- if (typeof arr.toSorted === "function") {
477
- return arr.toSorted(ord);
478
- }
479
- return [...data].sort(ord);
480
- };
481
- Arr2.zip = (other) => (data) => {
482
- const len = Math.min(data.length, other.length);
483
- const result = new Array(len);
484
- for (let i = 0; i < len; i++) {
485
- result[i] = [data[i], other[i]];
486
- }
487
- return result;
488
- };
489
- Arr2.zipWith = (f) => (other) => (data) => {
490
- const len = Math.min(data.length, other.length);
491
- const result = new Array(len);
492
- for (let i = 0; i < len; i++) {
493
- result[i] = f(data[i], other[i]);
494
- }
495
- return result;
496
- };
497
- Arr2.intersperse = (sep) => (data) => {
498
- if (data.length <= 1) {
499
- return data;
500
- }
501
- const result = [data[0]];
502
- for (let i = 1; i < data.length; i++) {
503
- result.push(sep, data[i]);
504
- }
505
- return result;
506
- };
507
- Arr2.concat = (other) => (data) => [...data, ...other];
508
- Arr2.chunksOf = (n) => (data) => {
509
- if (n <= 0) {
510
- return [];
511
- }
512
- const result = [];
513
- for (let i = 0; i < data.length; i += n) {
514
- result.push(data.slice(i, i + n));
515
- }
516
- return result;
517
- };
518
- Arr2.flatten = (data) => {
519
- let totalLen = 0;
520
- const outerLen = data.length;
521
- for (let i = 0; i < outerLen; i++) {
522
- totalLen += data[i].length;
523
- }
524
- const result = new Array(totalLen);
525
- let idx = 0;
526
- for (let i = 0; i < outerLen; i++) {
527
- const chunk = data[i];
528
- const innerLen = chunk.length;
529
- for (let j = 0; j < innerLen; j++) {
530
- result[idx++] = chunk[j];
531
- }
532
- }
533
- return result;
534
- };
535
- Arr2.flatMap = (f) => (data) => {
536
- const n = data.length;
537
- const result = [];
538
- for (let i = 0; i < n; i++) {
539
- const chunk = f(data[i]);
540
- const m = chunk.length;
541
- for (let j = 0; j < m; j++) {
542
- result.push(chunk[j]);
543
- }
544
- }
545
- return result;
546
- };
547
- Arr2.reduce = (initial, f) => (data) => data.reduce(f, initial);
548
- const _traverseTask = Object.assign((f) => ArrTask.traverse(f), {
549
- Result: ArrTaskResult.traverse
550
- });
551
- const _sequenceTask = Object.assign((data) => ArrTask.sequence(data), {
552
- Result: ArrTaskResult.sequence
553
- });
554
- let traverse;
555
- ((traverse2) => {
556
- traverse2.Maybe = ArrMaybe.traverse;
557
- traverse2.Result = ArrResult.traverse;
558
- traverse2.Task = _traverseTask;
559
- })(traverse = Arr2.traverse || (Arr2.traverse = {}));
560
- let sequence;
561
- ((sequence2) => {
562
- sequence2.Maybe = ArrMaybe.sequence;
563
- sequence2.Result = ArrResult.sequence;
564
- sequence2.Task = _sequenceTask;
565
- })(sequence = Arr2.sequence || (Arr2.sequence = {}));
566
- let is;
567
- ((is2) => {
568
- is2.empty = (data) => data.length === 0;
569
- is2.nonEmpty = (data) => isNonEmptyArr(data);
570
- })(is = Arr2.is || (Arr2.is = {}));
571
- Arr2.prepend = (value) => (data) => [value, ...data];
572
- Arr2.append = (value) => (data) => [...data, value];
573
- Arr2.size = (data) => data.length;
574
- Arr2.some = (predicate) => (data) => {
575
- const n = data.length;
576
- for (let i = 0; i < n; i++) {
577
- if (predicate(data[i])) {
578
- return true;
579
- }
1291
+ }
1292
+ return result;
1293
+ };
1294
+ var partition = (predicate) => (data) => {
1295
+ const pass = [];
1296
+ const fail = [];
1297
+ for (const a of data) {
1298
+ (predicate(a) ? pass : fail).push(a);
1299
+ }
1300
+ return [pass, fail];
1301
+ };
1302
+ var compact = (data) => {
1303
+ const result = [];
1304
+ for (const item of data) {
1305
+ if (item.kind === "Some") {
1306
+ result.push(item.value);
580
1307
  }
581
- return false;
582
- };
583
- Arr2.every = (predicate) => (data) => {
584
- const n = data.length;
585
- for (let i = 0; i < n; i++) {
586
- if (!predicate(data[i])) {
587
- return false;
588
- }
1308
+ }
1309
+ return result;
1310
+ };
1311
+ var separate = (data) => {
1312
+ const errors = [];
1313
+ const successes = [];
1314
+ for (const item of data) {
1315
+ if (item.kind === "Ok") {
1316
+ successes.push(item.value);
1317
+ } else {
1318
+ errors.push(item.error);
589
1319
  }
590
- return true;
591
- };
592
- Arr2.reverse = (data) => [...data].toReversed();
593
- Arr2.insertAt = (index, item) => (data) => {
594
- const i = Math.max(0, Math.min(index, data.length));
595
- const arr = data;
596
- if (typeof arr.toSpliced === "function") {
597
- return arr.toSpliced(i, 0, item);
598
- }
599
- const result = [...data];
600
- result.splice(i, 0, item);
601
- return result;
602
- };
603
- Arr2.removeAt = (index) => (data) => {
604
- if (index < 0 || index >= data.length) {
605
- return data;
1320
+ }
1321
+ return [errors, successes];
1322
+ };
1323
+ var partitionMap = (f) => (data) => {
1324
+ const errors = [];
1325
+ const successes = [];
1326
+ for (const item of data) {
1327
+ const mapped = f(item);
1328
+ if (mapped.kind === "Ok") {
1329
+ successes.push(mapped.value);
1330
+ } else {
1331
+ errors.push(mapped.error);
606
1332
  }
607
- const arr = data;
608
- if (typeof arr.toSpliced === "function") {
609
- return arr.toSpliced(index, 1);
1333
+ }
1334
+ return [errors, successes];
1335
+ };
1336
+ var groupBy = (f) => (data) => {
1337
+ const result = {};
1338
+ for (const a of data) {
1339
+ const key = f(a);
1340
+ if (!result[key]) {
1341
+ result[key] = [];
1342
+ }
1343
+ result[key].push(a);
1344
+ }
1345
+ return result;
1346
+ };
1347
+ var uniq = (data) => data.length <= 1 ? data : [...new Set(data)];
1348
+ var uniqBy = (f) => (data) => {
1349
+ const seen = /* @__PURE__ */ new Set();
1350
+ const result = [];
1351
+ for (const a of data) {
1352
+ const key = f(a);
1353
+ if (!seen.has(key)) {
1354
+ seen.add(key);
1355
+ result.push(a);
610
1356
  }
611
- const result = [...data];
612
- result.splice(index, 1);
613
- return result;
614
- };
615
- Arr2.take = (n) => (data) => n <= 0 ? [] : data.slice(0, n);
616
- Arr2.drop = (n) => (data) => data.slice(n);
617
- Arr2.takeWhile = (predicate) => (data) => {
618
- const result = [];
619
- for (const a of data) {
620
- if (!predicate(a)) {
621
- break;
622
- }
1357
+ }
1358
+ return result;
1359
+ };
1360
+ var uniqWith = (eq) => (data) => {
1361
+ const result = [];
1362
+ for (const a of data) {
1363
+ if (!result.some((x) => eq(x, a))) {
623
1364
  result.push(a);
624
1365
  }
625
- return result;
626
- };
627
- Arr2.dropWhile = (predicate) => (data) => {
628
- let i = 0;
629
- while (i < data.length && predicate(data[i])) {
630
- i++;
1366
+ }
1367
+ return result;
1368
+ };
1369
+ var sortBy = (compare) => (data) => {
1370
+ const arr = data;
1371
+ if (typeof arr.toSorted === "function") {
1372
+ return arr.toSorted(compare);
1373
+ }
1374
+ return [...data].sort(compare);
1375
+ };
1376
+ var sortWith = (ord) => (data) => {
1377
+ const arr = data;
1378
+ if (typeof arr.toSorted === "function") {
1379
+ return arr.toSorted(ord);
1380
+ }
1381
+ return [...data].sort(ord);
1382
+ };
1383
+ var zip = (other) => (data) => {
1384
+ const len = Math.min(data.length, other.length);
1385
+ const result = new Array(len);
1386
+ for (let i = 0; i < len; i++) {
1387
+ result[i] = [data[i], other[i]];
1388
+ }
1389
+ return result;
1390
+ };
1391
+ var zipWith = (f) => (other) => (data) => {
1392
+ const len = Math.min(data.length, other.length);
1393
+ const result = new Array(len);
1394
+ for (let i = 0; i < len; i++) {
1395
+ result[i] = f(data[i], other[i]);
1396
+ }
1397
+ return result;
1398
+ };
1399
+ var intersperse = (sep) => (data) => {
1400
+ if (data.length <= 1) {
1401
+ return data;
1402
+ }
1403
+ const result = [data[0]];
1404
+ for (let i = 1; i < data.length; i++) {
1405
+ result.push(sep, data[i]);
1406
+ }
1407
+ return result;
1408
+ };
1409
+ var concat = (other) => (data) => [...data, ...other];
1410
+ var chunksOf = (n) => (data) => {
1411
+ if (n <= 0) {
1412
+ return [];
1413
+ }
1414
+ const result = [];
1415
+ for (let i = 0; i < data.length; i += n) {
1416
+ result.push(data.slice(i, i + n));
1417
+ }
1418
+ return result;
1419
+ };
1420
+ var flatten = (data) => {
1421
+ let totalLen = 0;
1422
+ const outerLen = data.length;
1423
+ for (let i = 0; i < outerLen; i++) {
1424
+ totalLen += data[i].length;
1425
+ }
1426
+ const result = new Array(totalLen);
1427
+ let idx = 0;
1428
+ for (let i = 0; i < outerLen; i++) {
1429
+ const chunk = data[i];
1430
+ const innerLen = chunk.length;
1431
+ for (let j = 0; j < innerLen; j++) {
1432
+ result[idx++] = chunk[j];
631
1433
  }
632
- return data.slice(i);
633
- };
634
- Arr2.scan = (initial, f) => (data) => {
635
- const n = data.length;
636
- const result = new Array(n);
637
- let acc = initial;
638
- for (let i = 0; i < n; i++) {
639
- acc = f(acc, data[i]);
640
- result[i] = acc;
1434
+ }
1435
+ return result;
1436
+ };
1437
+ var flatMap = (f) => (data) => {
1438
+ const n = data.length;
1439
+ const result = [];
1440
+ for (let i = 0; i < n; i++) {
1441
+ const chunk = f(data[i]);
1442
+ const m = chunk.length;
1443
+ for (let j = 0; j < m; j++) {
1444
+ result.push(chunk[j]);
641
1445
  }
642
- return result;
643
- };
644
- Arr2.splitAt = (index) => (data) => {
645
- const i = Math.max(0, index);
646
- return [data.slice(0, i), data.slice(i)];
647
- };
648
- Arr2.partitionMaybe = (f) => (data) => {
649
- const failures = [];
650
- const successes = [];
651
- for (let i = 0; i < data.length; i++) {
652
- const res = f(data[i]);
653
- if (res.kind === "Some") {
654
- successes.push(res.value);
655
- } else {
656
- failures.push(data[i]);
657
- }
1446
+ }
1447
+ return result;
1448
+ };
1449
+ var reduce = (initial, f) => (data) => data.reduce(f, initial);
1450
+ var _traverseTask = Object.assign((f) => ArrTask.traverse(f), {
1451
+ Result: ArrTaskResult.traverse
1452
+ });
1453
+ var _sequenceTask = Object.assign((data) => ArrTask.sequence(data), {
1454
+ Result: ArrTaskResult.sequence
1455
+ });
1456
+ var prepend = (value) => (data) => [value, ...data];
1457
+ var append = (value) => (data) => [...data, value];
1458
+ var size = (data) => data.length;
1459
+ var some = (predicate) => (data) => {
1460
+ const n = data.length;
1461
+ for (let i = 0; i < n; i++) {
1462
+ if (predicate(data[i])) {
1463
+ return true;
658
1464
  }
659
- return [failures, successes];
660
- };
661
- Arr2.at = (index) => (data) => {
662
- const targetIndex = index < 0 ? data.length + index : index;
663
- if (targetIndex < 0 || targetIndex >= data.length) {
664
- return Maybe.make.none();
1465
+ }
1466
+ return false;
1467
+ };
1468
+ var every = (predicate) => (data) => {
1469
+ const n = data.length;
1470
+ for (let i = 0; i < n; i++) {
1471
+ if (!predicate(data[i])) {
1472
+ return false;
665
1473
  }
666
- return Maybe.make.some(data[targetIndex]);
667
- };
668
- Arr2.findMap = (f) => (data) => {
669
- for (let i = 0; i < data.length; i++) {
670
- const res = f(data[i]);
671
- if (res.kind === "Some") {
672
- return res;
673
- }
1474
+ }
1475
+ return true;
1476
+ };
1477
+ var reverse = (data) => [...data].toReversed();
1478
+ var insertAt = (index, item) => (data) => {
1479
+ const i = Math.max(0, Math.min(index, data.length));
1480
+ const arr = data;
1481
+ if (typeof arr.toSpliced === "function") {
1482
+ return arr.toSpliced(i, 0, item);
1483
+ }
1484
+ const result = [...data];
1485
+ result.splice(i, 0, item);
1486
+ return result;
1487
+ };
1488
+ var removeAt = (index) => (data) => {
1489
+ if (index < 0 || index >= data.length) {
1490
+ return data;
1491
+ }
1492
+ const arr = data;
1493
+ if (typeof arr.toSpliced === "function") {
1494
+ return arr.toSpliced(index, 1);
1495
+ }
1496
+ const result = [...data];
1497
+ result.splice(index, 1);
1498
+ return result;
1499
+ };
1500
+ var take = (n) => (data) => n <= 0 ? [] : data.slice(0, n);
1501
+ var drop = (n) => (data) => data.slice(n);
1502
+ var takeWhile = (predicate) => (data) => {
1503
+ const result = [];
1504
+ for (const a of data) {
1505
+ if (!predicate(a)) {
1506
+ break;
1507
+ }
1508
+ result.push(a);
1509
+ }
1510
+ return result;
1511
+ };
1512
+ var dropWhile = (predicate) => (data) => {
1513
+ let i = 0;
1514
+ while (i < data.length && predicate(data[i])) {
1515
+ i++;
1516
+ }
1517
+ return data.slice(i);
1518
+ };
1519
+ var scan = (initial, f) => (data) => {
1520
+ const n = data.length;
1521
+ const result = new Array(n);
1522
+ let acc = initial;
1523
+ for (let i = 0; i < n; i++) {
1524
+ acc = f(acc, data[i]);
1525
+ result[i] = acc;
1526
+ }
1527
+ return result;
1528
+ };
1529
+ var splitAt = (index) => (data) => {
1530
+ const i = Math.max(0, index);
1531
+ return [data.slice(0, i), data.slice(i)];
1532
+ };
1533
+ var partitionMaybe = (f) => (data) => {
1534
+ const failures = [];
1535
+ const successes = [];
1536
+ for (let i = 0; i < data.length; i++) {
1537
+ const res = f(data[i]);
1538
+ if (res.kind === "Some") {
1539
+ successes.push(res.value);
1540
+ } else {
1541
+ failures.push(data[i]);
674
1542
  }
1543
+ }
1544
+ return [failures, successes];
1545
+ };
1546
+ var at = (index) => (data) => {
1547
+ const targetIndex = index < 0 ? data.length + index : index;
1548
+ if (targetIndex < 0 || targetIndex >= data.length) {
675
1549
  return Maybe.make.none();
676
- };
677
- Arr2.indexBy = (keyFn) => (data) => {
678
- const map2 = new globalThis.Map();
679
- for (let i = 0; i < data.length; i++) {
680
- map2.set(keyFn(data[i]), data[i]);
681
- }
682
- return map2;
683
- };
684
- Arr2.frequencies = (data) => {
685
- const map2 = new globalThis.Map();
686
- for (let i = 0; i < data.length; i++) {
687
- const item = data[i];
688
- map2.set(item, (map2.get(item) ?? 0) + 1);
689
- }
690
- return map2;
691
- };
692
- Arr2.chunkBy = (keyFn) => (data) => {
693
- if (data.length === 0) {
694
- return [];
695
- }
696
- const result = [];
697
- let currentChunk = [data[0]];
698
- let currentKey = keyFn(data[0]);
699
- for (let i = 1; i < data.length; i++) {
700
- const item = data[i];
701
- const key = keyFn(item);
702
- if (Object.is(key, currentKey)) {
703
- currentChunk.push(item);
704
- } else {
705
- result.push(currentChunk);
706
- currentChunk = [item];
707
- currentKey = key;
708
- }
709
- }
710
- result.push(currentChunk);
711
- return result;
712
- };
713
- Arr2.dedupeAdjacent = (eq = (a, b) => Object.is(a, b)) => (data) => {
714
- if (data.length === 0) {
715
- return [];
716
- }
717
- const result = [data[0]];
718
- for (let i = 1; i < data.length; i++) {
719
- if (!eq(data[i], result[result.length - 1])) {
720
- result.push(data[i]);
721
- }
722
- }
723
- return result;
724
- };
725
- Arr2.windowed = (size2, options) => (data) => {
726
- const step = options?.step ?? 1;
727
- if (size2 <= 0 || step <= 0 || data.length < size2) {
728
- return [];
1550
+ }
1551
+ return Maybe.make.some(data[targetIndex]);
1552
+ };
1553
+ var findMap = (f) => (data) => {
1554
+ for (let i = 0; i < data.length; i++) {
1555
+ const res = f(data[i]);
1556
+ if (res.kind === "Some") {
1557
+ return res;
729
1558
  }
730
- const result = [];
731
- for (let i = 0; i <= data.length - size2; i += step) {
732
- result.push(data.slice(i, i + size2));
1559
+ }
1560
+ return Maybe.make.none();
1561
+ };
1562
+ var indexBy = (keyFn) => (data) => {
1563
+ const resultMap = new globalThis.Map();
1564
+ for (let i = 0; i < data.length; i++) {
1565
+ resultMap.set(keyFn(data[i]), data[i]);
1566
+ }
1567
+ return resultMap;
1568
+ };
1569
+ var frequencies = (data) => {
1570
+ const resultMap = new globalThis.Map();
1571
+ for (let i = 0; i < data.length; i++) {
1572
+ const item = data[i];
1573
+ resultMap.set(item, (resultMap.get(item) ?? 0) + 1);
1574
+ }
1575
+ return resultMap;
1576
+ };
1577
+ var chunkBy = (keyFn) => (data) => {
1578
+ if (data.length === 0) {
1579
+ return [];
1580
+ }
1581
+ const result = [];
1582
+ let currentChunk = [data[0]];
1583
+ let currentKey = keyFn(data[0]);
1584
+ for (let i = 1; i < data.length; i++) {
1585
+ const item = data[i];
1586
+ const key = keyFn(item);
1587
+ if (Object.is(key, currentKey)) {
1588
+ currentChunk.push(item);
1589
+ } else {
1590
+ result.push(currentChunk);
1591
+ currentChunk = [item];
1592
+ currentKey = key;
733
1593
  }
734
- return result;
735
- };
736
- Arr2.unfold = (initial, f) => {
737
- const result = [];
738
- let currentState = initial;
739
- while (true) {
740
- const next = f(currentState);
741
- if (next.kind === "None") {
742
- break;
743
- }
744
- const [item, nextState] = next.value;
745
- result.push(item);
746
- currentState = nextState;
1594
+ }
1595
+ result.push(currentChunk);
1596
+ return result;
1597
+ };
1598
+ var dedupeAdjacent = (eq = (a, b) => Object.is(a, b)) => (data) => {
1599
+ if (data.length === 0) {
1600
+ return [];
1601
+ }
1602
+ const result = [data[0]];
1603
+ for (let i = 1; i < data.length; i++) {
1604
+ if (!eq(data[i], result[result.length - 1])) {
1605
+ result.push(data[i]);
747
1606
  }
748
- return result;
749
- };
750
- Arr2.NonEmpty = ArrNonEmpty;
751
- })(Arr || (Arr = {}));
1607
+ }
1608
+ return result;
1609
+ };
1610
+ var windowed = (windowSize, options) => (data) => {
1611
+ const step = options?.step ?? 1;
1612
+ if (windowSize <= 0 || step <= 0 || data.length < windowSize) {
1613
+ return [];
1614
+ }
1615
+ const result = [];
1616
+ for (let i = 0; i <= data.length - windowSize; i += step) {
1617
+ result.push(data.slice(i, i + windowSize));
1618
+ }
1619
+ return result;
1620
+ };
1621
+ var unfold = (initial, f) => {
1622
+ const result = [];
1623
+ let currentState = initial;
1624
+ while (true) {
1625
+ const next = f(currentState);
1626
+ if (next.kind === "None") {
1627
+ break;
1628
+ }
1629
+ const [item, nextState] = next.value;
1630
+ result.push(item);
1631
+ currentState = nextState;
1632
+ }
1633
+ return result;
1634
+ };
1635
+ var ArrFrom = {
1636
+ Array: (data) => data.length > 0 ? Maybe.make.some(data) : Maybe.make.none()
1637
+ };
1638
+ var ArrIs = {
1639
+ empty: (data) => data.length === 0,
1640
+ nonEmpty: (data) => isNonEmptyArr(data)
1641
+ };
1642
+ var ArrNonEmpty = {
1643
+ singleton: (value) => [value],
1644
+ from: {
1645
+ Array: (data) => isNonEmptyArr(data) ? Maybe.make.some(data) : Maybe.make.none()
1646
+ },
1647
+ head: (data) => data[0],
1648
+ last: (data) => data[data.length - 1],
1649
+ tail: (data) => data.slice(1),
1650
+ reduce: (f) => (data) => data.reduce(f),
1651
+ map: (f) => (data) => map(f)(data),
1652
+ mapWithIndex: (f) => (data) => mapWithIndex(f)(data),
1653
+ intersperse: (sep) => (data) => intersperse(sep)(data),
1654
+ concat: (other) => (data) => concat(other)(data),
1655
+ reverse: (data) => reverse(data)
1656
+ };
1657
+ var Arr = {
1658
+ head,
1659
+ last,
1660
+ tail,
1661
+ init,
1662
+ findFirst,
1663
+ findLast,
1664
+ findIndex,
1665
+ map,
1666
+ mapWithIndex,
1667
+ filter,
1668
+ filterMap,
1669
+ partition,
1670
+ compact,
1671
+ separate,
1672
+ partitionMap,
1673
+ groupBy,
1674
+ uniq,
1675
+ uniqBy,
1676
+ uniqWith,
1677
+ sortBy,
1678
+ sortWith,
1679
+ zip,
1680
+ zipWith,
1681
+ intersperse,
1682
+ concat,
1683
+ chunksOf,
1684
+ flatten,
1685
+ flatMap,
1686
+ reduce,
1687
+ prepend,
1688
+ append,
1689
+ size,
1690
+ some,
1691
+ every,
1692
+ reverse,
1693
+ insertAt,
1694
+ removeAt,
1695
+ take,
1696
+ drop,
1697
+ takeWhile,
1698
+ dropWhile,
1699
+ scan,
1700
+ splitAt,
1701
+ partitionMaybe,
1702
+ at,
1703
+ findMap,
1704
+ indexBy,
1705
+ frequencies,
1706
+ chunkBy,
1707
+ dedupeAdjacent,
1708
+ windowed,
1709
+ unfold,
1710
+ from: ArrFrom,
1711
+ is: ArrIs,
1712
+ traverse: { Maybe: ArrMaybe.traverse, Result: ArrResult.traverse, Task: _traverseTask },
1713
+ sequence: { Maybe: ArrMaybe.sequence, Result: ArrResult.sequence, Task: _sequenceTask },
1714
+ NonEmpty: ArrNonEmpty
1715
+ };
752
1716
 
753
1717
  // src/Data/BigNum.ts
754
- var BigNum;
755
- ((BigNum2) => {
756
- let from;
757
- ((from2) => {
758
- from2.string = (s) => {
1718
+ var BigNum = {
1719
+ is: {
1720
+ /**
1721
+ * Returns `true` when the bigint is equal to zero (`0n`).
1722
+ *
1723
+ * @example
1724
+ * ```ts
1725
+ * BigNum.is.zero(0n); // true
1726
+ * BigNum.is.zero(5n); // false
1727
+ * ```
1728
+ */
1729
+ zero: (b) => b === 0n,
1730
+ /**
1731
+ * Returns `true` when the bigint is an even integer.
1732
+ *
1733
+ * @example
1734
+ * ```ts
1735
+ * BigNum.is.even(4n); // true
1736
+ * BigNum.is.even(3n); // false
1737
+ * ```
1738
+ */
1739
+ even: (b) => b % 2n === 0n,
1740
+ /**
1741
+ * Returns `true` when the bigint is an odd integer.
1742
+ *
1743
+ * @example
1744
+ * ```ts
1745
+ * BigNum.is.odd(3n); // true
1746
+ * BigNum.is.odd(4n); // false
1747
+ * ```
1748
+ */
1749
+ odd: (b) => b % 2n !== 0n,
1750
+ /**
1751
+ * Returns `true` when the bigint is strictly greater than zero (`0n`).
1752
+ *
1753
+ * @example
1754
+ * ```ts
1755
+ * BigNum.is.positive(5n); // true
1756
+ * BigNum.is.positive(0n); // false
1757
+ * BigNum.is.positive(-5n); // false
1758
+ * ```
1759
+ */
1760
+ positive: (b) => b > 0n,
1761
+ /**
1762
+ * Returns `true` when the bigint is strictly less than zero (`0n`).
1763
+ *
1764
+ * @example
1765
+ * ```ts
1766
+ * BigNum.is.negative(-5n); // true
1767
+ * BigNum.is.negative(0n); // false
1768
+ * BigNum.is.negative(5n); // false
1769
+ * ```
1770
+ */
1771
+ negative: (b) => b < 0n
1772
+ },
1773
+ // --- from ---
1774
+ from: {
1775
+ /**
1776
+ * Safely parses a string into a `bigint`. Returns `None` if parsing fails.
1777
+ *
1778
+ * @example
1779
+ * ```ts
1780
+ * BigNum.from.string("123"); // Some(123n)
1781
+ * BigNum.from.string("abc"); // None
1782
+ * ```
1783
+ */
1784
+ string: (s) => {
759
1785
  try {
760
1786
  if (s.trim() === "") {
761
1787
  return Maybe.make.none();
@@ -764,272 +1790,881 @@ var BigNum;
764
1790
  } catch {
765
1791
  return Maybe.make.none();
766
1792
  }
767
- };
768
- from2.number = (n) => {
1793
+ },
1794
+ /**
1795
+ * Safely converts a number into a `bigint`. Returns `None` for floats, `NaN`, or non-safe integers.
1796
+ *
1797
+ * @example
1798
+ * ```ts
1799
+ * BigNum.from.number(42); // Some(42n)
1800
+ * BigNum.from.number(3.14); // None
1801
+ * ```
1802
+ */
1803
+ number: (n) => {
769
1804
  if (!Number.isInteger(n) || n < Number.MIN_SAFE_INTEGER || n > Number.MAX_SAFE_INTEGER) {
770
1805
  return Maybe.make.none();
771
1806
  }
772
1807
  return Maybe.make.some(BigInt(n));
773
- };
774
- })(from = BigNum2.from || (BigNum2.from = {}));
775
- let to;
776
- ((to2) => {
777
- to2.number = (b) => {
1808
+ }
1809
+ },
1810
+ // --- to ---
1811
+ to: {
1812
+ /**
1813
+ * Safely converts a `bigint` to a `number`. Returns `None` if the value is outside JavaScript's safe integer range.
1814
+ *
1815
+ * @example
1816
+ * ```ts
1817
+ * BigNum.to.number(42n); // Some(42)
1818
+ * BigNum.to.number(9007199254740993n); // None
1819
+ * ```
1820
+ */
1821
+ number: (b) => {
778
1822
  if (b < BigInt(Number.MIN_SAFE_INTEGER) || b > BigInt(Number.MAX_SAFE_INTEGER)) {
779
1823
  return Maybe.make.none();
780
1824
  }
781
1825
  return Maybe.make.some(Number(b));
782
- };
783
- })(to = BigNum2.to || (BigNum2.to = {}));
784
- BigNum2.add = (b) => (a) => a + b;
785
- BigNum2.sub = (b) => (a) => a - b;
786
- BigNum2.mul = (b) => (a) => a * b;
787
- BigNum2.div = (b) => (a) => b === 0n ? Maybe.make.none() : Maybe.make.some(a / b);
788
- BigNum2.mod = (b) => (a) => b === 0n ? Maybe.make.none() : Maybe.make.some(a % b);
789
- BigNum2.clamp = (min2, max2) => (a) => a < min2 ? min2 : a > max2 ? max2 : a;
790
- BigNum2.inRange = (start, end) => (a) => a >= start && a < end;
791
- BigNum2.abs = (a) => a < 0n ? -a : a;
792
- BigNum2.min = (b) => (a) => a < b ? a : b;
793
- BigNum2.max = (b) => (a) => a > b ? a : b;
794
- })(BigNum || (BigNum = {}));
795
-
796
- // src/Data/Dict.ts
797
- var DictNonEmpty;
798
- ((DictNonEmpty2) => {
799
- DictNonEmpty2.singleton = (key, value) => new globalThis.Map([[key, value]]);
800
- let from;
801
- ((from2) => {
802
- from2.Map = (m) => m.size > 0 ? Maybe.make.some(m) : Maybe.make.none();
803
- })(from = DictNonEmpty2.from || (DictNonEmpty2.from = {}));
804
- DictNonEmpty2.keys = (m) => Dict.keys(m);
805
- DictNonEmpty2.values = (m) => Dict.values(m);
806
- DictNonEmpty2.entries = (m) => Dict.entries(m);
807
- DictNonEmpty2.reduce = (f) => (m) => (0, DictNonEmpty2.values)(m).reduce(f);
808
- DictNonEmpty2.map = (f) => (m) => Dict.map(f)(m);
809
- DictNonEmpty2.mapWithKey = (f) => (m) => Dict.mapWithKey(f)(m);
810
- })(DictNonEmpty || (DictNonEmpty = {}));
811
- var Dict;
812
- ((Dict2) => {
813
- let is;
814
- ((is2) => {
815
- is2.empty = (m) => m.size === 0;
816
- is2.nonEmpty = (m) => m.size > 0;
817
- })(is = Dict2.is || (Dict2.is = {}));
818
- Dict2.empty = () => new globalThis.Map();
819
- Dict2.singleton = (key, value) => new globalThis.Map([[key, value]]);
820
- let from;
821
- ((from2) => {
822
- from2.entries = (entries3) => new globalThis.Map(entries3);
823
- from2.Record = (rec) => new globalThis.Map(Object.entries(rec));
824
- })(from = Dict2.from || (Dict2.from = {}));
825
- Dict2.groupBy = (keyFn) => (items) => {
826
- const result = new globalThis.Map();
827
- for (const item of items) {
828
- const key = keyFn(item);
829
- const arr = result.get(key);
830
- if (arr !== void 0) {
831
- arr.push(item);
832
- } else {
833
- result.set(key, [item]);
834
- }
835
- }
836
- return result;
837
- };
838
- Dict2.has = (key) => (m) => m.has(key);
839
- Dict2.lookup = (key) => (m) => m.has(key) ? Maybe.make.some(m.get(key)) : Maybe.make.none();
840
- Dict2.size = (m) => m.size;
841
- Dict2.keys = (m) => [...m.keys()];
842
- Dict2.values = (m) => [...m.values()];
843
- Dict2.entries = (m) => [...m.entries()];
844
- Dict2.insert = (key, value) => (m) => {
845
- const result = new globalThis.Map(m);
846
- result.set(key, value);
847
- return result;
848
- };
849
- Dict2.remove = (key) => (m) => {
850
- if (!m.has(key)) {
851
- return m;
852
- }
853
- const result = new globalThis.Map(m);
854
- result.delete(key);
855
- return result;
856
- };
857
- Dict2.upsert = (key, f) => (m) => {
858
- const result = new globalThis.Map(m);
859
- result.set(key, f((0, Dict2.lookup)(key)(m)));
860
- return result;
861
- };
862
- Dict2.map = (f) => (m) => {
863
- const result = new globalThis.Map();
864
- for (const [k, v] of m) {
865
- result.set(k, f(v));
866
1826
  }
867
- return result;
868
- };
869
- Dict2.mapWithKey = (f) => (m) => {
870
- const result = new globalThis.Map();
871
- for (const [k, v] of m) {
872
- result.set(k, f(k, v));
1827
+ },
1828
+ /**
1829
+ * Adds `b` to `a`. Data-last curried signature: `add(b)(a)` = `a + b`.
1830
+ *
1831
+ * @example
1832
+ * ```ts
1833
+ * pipe(10n, BigNum.add(5n)); // 15n
1834
+ * ```
1835
+ */
1836
+ add: (b) => (a) => a + b,
1837
+ /**
1838
+ * Subtracts `b` from `a`. Data-last curried signature: `sub(b)(a)` = `a - b`.
1839
+ *
1840
+ * @example
1841
+ * ```ts
1842
+ * pipe(10n, BigNum.sub(3n)); // 7n
1843
+ * ```
1844
+ */
1845
+ sub: (b) => (a) => a - b,
1846
+ /**
1847
+ * Multiplies `a` by `b`. Data-last curried signature: `mul(b)(a)` = `a * b`.
1848
+ *
1849
+ * @example
1850
+ * ```ts
1851
+ * pipe(6n, BigNum.mul(7n)); // 42n
1852
+ * ```
1853
+ */
1854
+ mul: (b) => (a) => a * b,
1855
+ /**
1856
+ * Divides `a` by `b`. Returns `None` if `b` is `0n`.
1857
+ *
1858
+ * @example
1859
+ * ```ts
1860
+ * pipe(20n, BigNum.div(4n)); // Some(5n)
1861
+ * pipe(5n, BigNum.div(0n)); // None
1862
+ * ```
1863
+ */
1864
+ div: (b) => (a) => b === 0n ? Maybe.make.none() : Maybe.make.some(a / b),
1865
+ /**
1866
+ * Computes remainder of `a / b`. Returns `None` if `b` is `0n`.
1867
+ *
1868
+ * @example
1869
+ * ```ts
1870
+ * pipe(10n, BigNum.mod(3n)); // Some(1n)
1871
+ * pipe(5n, BigNum.mod(0n)); // None
1872
+ * ```
1873
+ */
1874
+ mod: (b) => (a) => b === 0n ? Maybe.make.none() : Maybe.make.some(a % b),
1875
+ /**
1876
+ * Clamps `a` between `min` and `max` (inclusive).
1877
+ *
1878
+ * @example
1879
+ * ```ts
1880
+ * pipe(150n, BigNum.clamp(0n, 100n)); // 100n
1881
+ * ```
1882
+ */
1883
+ clamp: (min, max) => (a) => a < min ? min : a > max ? max : a,
1884
+ /**
1885
+ * Returns `true` if `a` is in the range `[start, end)` (inclusive start, exclusive end).
1886
+ *
1887
+ * @example
1888
+ * ```ts
1889
+ * pipe(5n, BigNum.inRange(1n, 10n)); // true
1890
+ * ```
1891
+ */
1892
+ inRange: (start, end) => (a) => a >= start && a < end,
1893
+ /**
1894
+ * Returns absolute value of a `bigint`.
1895
+ *
1896
+ * @example
1897
+ * ```ts
1898
+ * BigNum.abs(-42n); // 42n
1899
+ * ```
1900
+ */
1901
+ abs: (a) => a < 0n ? -a : a,
1902
+ /**
1903
+ * Returns the minimum of `a` and `b`.
1904
+ *
1905
+ * @example
1906
+ * ```ts
1907
+ * pipe(10n, BigNum.min(5n)); // 5n
1908
+ * ```
1909
+ */
1910
+ min: (b) => (a) => a < b ? a : b,
1911
+ /**
1912
+ * Returns the maximum of `a` and `b`.
1913
+ *
1914
+ * @example
1915
+ * ```ts
1916
+ * pipe(10n, BigNum.max(5n)); // 10n
1917
+ * ```
1918
+ */
1919
+ max: (b) => (a) => a > b ? a : b
1920
+ };
1921
+
1922
+ // src/Data/Bool.ts
1923
+ var isBoolean = (u) => typeof u === "boolean";
1924
+ var isTrue = (u) => u === true;
1925
+ var isFalse = (u) => u === false;
1926
+ var isTruthy = (u) => Boolean(u);
1927
+ var isFalsy = (u) => !u;
1928
+ var not = (b) => !b;
1929
+ var and = (that) => (self) => self && that;
1930
+ var or = (that) => (self) => self || that;
1931
+ var xor = (that) => (self) => self !== that;
1932
+ var andLazy = (that) => (self) => self && that();
1933
+ var orLazy = (that) => (self) => self || that();
1934
+ var all = (booleans) => {
1935
+ for (let i = 0; i < booleans.length; i++) {
1936
+ if (!booleans[i]) {
1937
+ return false;
873
1938
  }
874
- return result;
875
- };
876
- Dict2.filter = (predicate) => (m) => {
877
- const result = new globalThis.Map();
878
- for (const [k, v] of m) {
879
- if (predicate(v)) {
880
- result.set(k, v);
881
- }
1939
+ }
1940
+ return true;
1941
+ };
1942
+ var any = (booleans) => {
1943
+ for (let i = 0; i < booleans.length; i++) {
1944
+ if (booleans[i]) {
1945
+ return true;
882
1946
  }
883
- return result;
884
- };
885
- Dict2.filterWithKey = (predicate) => (m) => {
886
- const result = new globalThis.Map();
887
- for (const [k, v] of m) {
888
- if (predicate(k, v)) {
889
- result.set(k, v);
890
- }
1947
+ }
1948
+ return false;
1949
+ };
1950
+ var fold = (onFalse, onTrue) => (b) => b ? onTrue() : onFalse();
1951
+ var match = (cases) => (b) => b ? cases.true() : cases.false();
1952
+ var fromString = (s) => {
1953
+ const trimmed = s.trim().toLowerCase();
1954
+ if (trimmed === "true") {
1955
+ return Maybe.make.some(true);
1956
+ }
1957
+ if (trimmed === "false") {
1958
+ return Maybe.make.some(false);
1959
+ }
1960
+ return Maybe.make.none();
1961
+ };
1962
+ var fromNumber = (n) => {
1963
+ if (n === 1) {
1964
+ return Maybe.make.some(true);
1965
+ }
1966
+ if (n === 0) {
1967
+ return Maybe.make.some(false);
1968
+ }
1969
+ return Maybe.make.none();
1970
+ };
1971
+ var fromTruthy = (value) => Boolean(value);
1972
+ var toMaybe = (onTrue) => (b) => b ? Maybe.make.some(onTrue()) : Maybe.make.none();
1973
+ var toResult2 = (onErr, onOk) => (b) => b ? Result.make.ok(onOk()) : Result.make.err(onErr());
1974
+ var toNumber = (b) => b ? 1 : 0;
1975
+ var toString = (b) => b ? "true" : "false";
1976
+ var Bool = {
1977
+ is: {
1978
+ /**
1979
+ * Type guard — checks if a value is a primitive boolean.
1980
+ *
1981
+ * @example
1982
+ * ```ts
1983
+ * Bool.is.boolean(true); // true
1984
+ * Bool.is.boolean(false); // true
1985
+ * Bool.is.boolean("true"); // false
1986
+ * Bool.is.boolean(null); // false
1987
+ * ```
1988
+ */
1989
+ boolean: isBoolean,
1990
+ /**
1991
+ * Narrowing guard — checks if a value is strictly `true`.
1992
+ *
1993
+ * @example
1994
+ * ```ts
1995
+ * Bool.is.true(true); // true
1996
+ * Bool.is.true(false); // false
1997
+ * ```
1998
+ */
1999
+ true: isTrue,
2000
+ /**
2001
+ * Narrowing guard — checks if a value is strictly `false`.
2002
+ *
2003
+ * @example
2004
+ * ```ts
2005
+ * Bool.is.false(false); // true
2006
+ * Bool.is.false(true); // false
2007
+ * ```
2008
+ */
2009
+ false: isFalse,
2010
+ /**
2011
+ * Type guard — checks if a value is truthy (not `false`, `0`, `0n`, `""`, `null`, `undefined`, or `NaN`).
2012
+ *
2013
+ * @example
2014
+ * ```ts
2015
+ * Bool.is.truthy("hello"); // true
2016
+ * Bool.is.truthy(42); // true
2017
+ * Bool.is.truthy(0); // false
2018
+ * Bool.is.truthy(null); // false
2019
+ * ```
2020
+ */
2021
+ truthy: isTruthy,
2022
+ /**
2023
+ * Type guard — checks if a value is falsy (`false`, `0`, `0n`, `""`, `null`, `undefined`, or `NaN`).
2024
+ *
2025
+ * @example
2026
+ * ```ts
2027
+ * Bool.is.falsy(""); // true
2028
+ * Bool.is.falsy(null); // true
2029
+ * Bool.is.falsy("content"); // false
2030
+ * ```
2031
+ */
2032
+ falsy: isFalsy
2033
+ },
2034
+ /**
2035
+ * Unary boolean negation: inverts the given boolean value.
2036
+ *
2037
+ * @example
2038
+ * ```ts
2039
+ * Bool.not(true); // false
2040
+ * Bool.not(false); // true
2041
+ * ```
2042
+ */
2043
+ not,
2044
+ /**
2045
+ * Logical AND combinator. Returns `true` only if both `self` and `that` are `true`.
2046
+ *
2047
+ * Data-last: `pipe(self, Bool.and(that))`.
2048
+ *
2049
+ * @example
2050
+ * ```ts
2051
+ * pipe(true, Bool.and(true)); // true
2052
+ * pipe(true, Bool.and(false)); // false
2053
+ * ```
2054
+ */
2055
+ and,
2056
+ /**
2057
+ * Logical OR combinator. Returns `true` if either `self` or `that` is `true`.
2058
+ *
2059
+ * Data-last: `pipe(self, Bool.or(that))`.
2060
+ *
2061
+ * @example
2062
+ * ```ts
2063
+ * pipe(false, Bool.or(true)); // true
2064
+ * pipe(false, Bool.or(false)); // false
2065
+ * ```
2066
+ */
2067
+ or,
2068
+ /**
2069
+ * Logical XOR (exclusive OR) combinator. Returns `true` if exactly one of `self` and `that` is `true`.
2070
+ *
2071
+ * Data-last: `pipe(self, Bool.xor(that))`.
2072
+ *
2073
+ * @example
2074
+ * ```ts
2075
+ * pipe(true, Bool.xor(false)); // true
2076
+ * pipe(true, Bool.xor(true)); // false
2077
+ * ```
2078
+ */
2079
+ xor,
2080
+ /**
2081
+ * Lazy logical AND combinator.
2082
+ * If `self` is `false`, the `that` computation is never evaluated.
2083
+ *
2084
+ * Data-last: `pipe(self, Bool.andLazy(that))`.
2085
+ *
2086
+ * @example
2087
+ * ```ts
2088
+ * pipe(
2089
+ * isCached,
2090
+ * Bool.andLazy(() => checkPermissions())
2091
+ * );
2092
+ * ```
2093
+ */
2094
+ andLazy,
2095
+ /**
2096
+ * Lazy logical OR combinator.
2097
+ * If `self` is `true`, the `that` computation is never evaluated.
2098
+ *
2099
+ * Data-last: `pipe(self, Bool.orLazy(that))`.
2100
+ *
2101
+ * @example
2102
+ * ```ts
2103
+ * pipe(
2104
+ * isAdmin,
2105
+ * Bool.orLazy(() => hasAccess(userId))
2106
+ * );
2107
+ * ```
2108
+ */
2109
+ orLazy,
2110
+ /**
2111
+ * N-ary AND aggregation across an array of booleans.
2112
+ * Returns `true` if every boolean is `true`, or for an empty array (vacuous truth).
2113
+ * Short-circuits on the first `false`.
2114
+ *
2115
+ * @example
2116
+ * ```ts
2117
+ * Bool.all([true, true, true]); // true
2118
+ * Bool.all([true, false, true]); // false
2119
+ * Bool.all([]); // true
2120
+ * ```
2121
+ */
2122
+ all,
2123
+ /**
2124
+ * N-ary OR aggregation across an array of booleans.
2125
+ * Returns `true` if at least one boolean is `true`. Returns `false` for an empty array.
2126
+ * Short-circuits on the first `true`.
2127
+ *
2128
+ * @example
2129
+ * ```ts
2130
+ * Bool.any([false, true, false]); // true
2131
+ * Bool.any([false, false]); // false
2132
+ * Bool.any([]); // false
2133
+ * ```
2134
+ */
2135
+ any,
2136
+ /**
2137
+ * Catamorphism for boolean: evaluates `onFalse()` when `false` and `onTrue()` when `true`.
2138
+ *
2139
+ * Positional ordering: `onFalse` first, `onTrue` second.
2140
+ * Aligned with `Result.fold(onErr, onOk)` and `Maybe.fold(onNone, onSome)`.
2141
+ *
2142
+ * @example
2143
+ * ```ts
2144
+ * pipe(
2145
+ * isDarkMode,
2146
+ * Bool.fold(
2147
+ * () => "light-theme",
2148
+ * () => "dark-theme"
2149
+ * )
2150
+ * );
2151
+ * ```
2152
+ */
2153
+ fold,
2154
+ /**
2155
+ * Pattern matching on boolean using named cases `{ true, false }`.
2156
+ *
2157
+ * @example
2158
+ * ```ts
2159
+ * pipe(
2160
+ * isEnabled,
2161
+ * Bool.match({
2162
+ * true: () => "Feature Active",
2163
+ * false: () => "Feature Disabled",
2164
+ * })
2165
+ * );
2166
+ * ```
2167
+ */
2168
+ match,
2169
+ // --- from ---
2170
+ from: {
2171
+ /**
2172
+ * Parses a string into a `Maybe<boolean>`.
2173
+ * Returns `Some(true)` for `"true"`, `Some(false)` for `"false"` (case-insensitive & trimmed),
2174
+ * and `None` for any other string.
2175
+ *
2176
+ * @example
2177
+ * ```ts
2178
+ * Bool.from.string("true"); // Some(true)
2179
+ * Bool.from.string("FALSE"); // Some(false)
2180
+ * Bool.from.string("yes"); // None
2181
+ * ```
2182
+ */
2183
+ string: fromString,
2184
+ /**
2185
+ * Converts a number into a `Maybe<boolean>`.
2186
+ * Returns `Some(true)` for `1`, `Some(false)` for `0`, and `None` for any other number.
2187
+ *
2188
+ * @example
2189
+ * ```ts
2190
+ * Bool.from.number(1); // Some(true)
2191
+ * Bool.from.number(0); // Some(false)
2192
+ * Bool.from.number(42); // None
2193
+ * ```
2194
+ */
2195
+ number: fromNumber,
2196
+ /**
2197
+ * Coerces any unknown value into a boolean via standard JS `Boolean(value)`.
2198
+ *
2199
+ * @example
2200
+ * ```ts
2201
+ * Bool.from.truthy("hello"); // true
2202
+ * Bool.from.truthy(0); // false
2203
+ * ```
2204
+ */
2205
+ truthy: fromTruthy
2206
+ },
2207
+ // --- to ---
2208
+ to: {
2209
+ /**
2210
+ * Lifts a boolean condition into a `Maybe`.
2211
+ * Returns `Some(onTrue())` when `true`, and `None` when `false`.
2212
+ *
2213
+ * @example
2214
+ * ```ts
2215
+ * pipe(
2216
+ * user.isVerified,
2217
+ * Bool.to.Maybe(() => user.profile)
2218
+ * ); // Some(profile) or None
2219
+ * ```
2220
+ */
2221
+ Maybe: toMaybe,
2222
+ /**
2223
+ * Lifts a boolean condition into a `Result`.
2224
+ * Returns `Ok(onOk())` when `true`, and `Err(onErr())` when `false`.
2225
+ *
2226
+ * @example
2227
+ * ```ts
2228
+ * pipe(
2229
+ * hasPermission,
2230
+ * Bool.to.Result(
2231
+ * () => "Permission denied",
2232
+ * () => sessionData
2233
+ * )
2234
+ * ); // Ok(sessionData) or Err("Permission denied")
2235
+ * ```
2236
+ */
2237
+ Result: toResult2,
2238
+ /**
2239
+ * Converts a boolean to numeric `1` or `0`.
2240
+ *
2241
+ * @example
2242
+ * ```ts
2243
+ * Bool.to.number(true); // 1
2244
+ * Bool.to.number(false); // 0
2245
+ * ```
2246
+ */
2247
+ number: toNumber,
2248
+ /**
2249
+ * Converts a boolean to literal string `"true"` or `"false"`.
2250
+ *
2251
+ * @example
2252
+ * ```ts
2253
+ * Bool.to.string(true); // "true"
2254
+ * Bool.to.string(false); // "false"
2255
+ * ```
2256
+ */
2257
+ string: toString
2258
+ }
2259
+ };
2260
+
2261
+ // src/Data/Dict.ts
2262
+ var DictIs = {
2263
+ empty: (m) => m.size === 0,
2264
+ nonEmpty: (m) => m.size > 0
2265
+ };
2266
+ var empty = () => new globalThis.Map();
2267
+ var singleton = (key, value) => new globalThis.Map([[key, value]]);
2268
+ var DictFrom = {
2269
+ entries: (entries3) => new globalThis.Map(entries3),
2270
+ Record: (record) => new globalThis.Map(Object.entries(record)),
2271
+ Array: (data) => new globalThis.Map(data),
2272
+ nullable: (data) => data === null || data === void 0 ? Maybe.make.none() : Maybe.make.some(data)
2273
+ };
2274
+ var DictTo = {
2275
+ Record: (map5) => {
2276
+ const result = {};
2277
+ for (const [k, v] of map5) {
2278
+ result[k] = v;
891
2279
  }
892
2280
  return result;
893
- };
894
- Dict2.compact = (m) => {
895
- const result = new globalThis.Map();
896
- for (const [k, v] of m) {
897
- if (v.kind === "Some") {
898
- result.set(k, v.value);
899
- }
2281
+ }
2282
+ };
2283
+ var groupBy2 = (f) => (as) => {
2284
+ const result = new globalThis.Map();
2285
+ for (const a of as) {
2286
+ const k = f(a);
2287
+ const existing = result.get(k);
2288
+ if (existing !== void 0) {
2289
+ existing.push(a);
2290
+ } else {
2291
+ result.set(k, [a]);
900
2292
  }
901
- return result;
902
- };
903
- Dict2.filterMap = (f) => (m) => {
904
- const result = new globalThis.Map();
905
- for (const [key, value] of m) {
906
- const mapped = f(value);
907
- if (mapped.kind === "Some") {
908
- result.set(key, mapped.value);
909
- }
2293
+ }
2294
+ return result;
2295
+ };
2296
+ var has = (key) => (data) => data.has(key);
2297
+ var lookup = (key) => (data) => {
2298
+ const val = data.get(key);
2299
+ return val !== void 0 || data.has(key) ? Maybe.make.some(val) : Maybe.make.none();
2300
+ };
2301
+ var size2 = (data) => data.size;
2302
+ var keys = (data) => Array.from(data.keys());
2303
+ var values = (data) => Array.from(data.values());
2304
+ var entries = (data) => Array.from(data.entries());
2305
+ var insert = (key, value) => (data) => {
2306
+ const res = new globalThis.Map(data);
2307
+ res.set(key, value);
2308
+ return res;
2309
+ };
2310
+ var remove = (key) => (data) => {
2311
+ if (!data.has(key)) {
2312
+ return data;
2313
+ }
2314
+ const res = new globalThis.Map(data);
2315
+ res.delete(key);
2316
+ return res;
2317
+ };
2318
+ var upsert = (key, f) => (data) => {
2319
+ const res = new globalThis.Map(data);
2320
+ const existing = data.has(key) ? Maybe.make.some(data.get(key)) : Maybe.make.none();
2321
+ res.set(key, f(existing));
2322
+ return res;
2323
+ };
2324
+ var map2 = (f) => (data) => {
2325
+ const res = new globalThis.Map();
2326
+ for (const [k, v] of data) {
2327
+ res.set(k, f(v));
2328
+ }
2329
+ return res;
2330
+ };
2331
+ var mapWithKey = (f) => (data) => {
2332
+ const res = new globalThis.Map();
2333
+ for (const [k, v] of data) {
2334
+ res.set(k, f(k, v));
2335
+ }
2336
+ return res;
2337
+ };
2338
+ var filter2 = (predicate) => (data) => {
2339
+ const res = new globalThis.Map();
2340
+ for (const [k, v] of data) {
2341
+ if (predicate(v)) {
2342
+ res.set(k, v);
910
2343
  }
911
- return result;
912
- };
913
- Dict2.union = (other) => (m) => {
914
- const result = new globalThis.Map(m);
915
- for (const [k, v] of other) {
916
- result.set(k, v);
2344
+ }
2345
+ return res;
2346
+ };
2347
+ var filterWithKey = (predicate) => (data) => {
2348
+ const res = new globalThis.Map();
2349
+ for (const [k, v] of data) {
2350
+ if (predicate(k, v)) {
2351
+ res.set(k, v);
917
2352
  }
918
- return result;
919
- };
920
- Dict2.intersection = (other) => (m) => {
921
- const result = new globalThis.Map();
922
- for (const [k, v] of m) {
923
- if (other.has(k)) {
924
- result.set(k, v);
925
- }
2353
+ }
2354
+ return res;
2355
+ };
2356
+ var compact2 = (data) => {
2357
+ const res = new globalThis.Map();
2358
+ for (const [k, v] of data) {
2359
+ if (v.kind === "Some") {
2360
+ res.set(k, v.value);
926
2361
  }
927
- return result;
928
- };
929
- Dict2.difference = (other) => (m) => {
930
- const result = new globalThis.Map();
931
- for (const [k, v] of m) {
932
- if (!other.has(k)) {
933
- result.set(k, v);
934
- }
2362
+ }
2363
+ return res;
2364
+ };
2365
+ var filterMap2 = (f) => (data) => {
2366
+ const res = new globalThis.Map();
2367
+ for (const [k, v] of data) {
2368
+ const mb = f(v);
2369
+ if (mb.kind === "Some") {
2370
+ res.set(k, mb.value);
935
2371
  }
936
- return result;
937
- };
938
- Dict2.reduce = (init, f) => (m) => {
939
- let acc = init;
940
- for (const v of m.values()) {
941
- acc = f(acc, v);
2372
+ }
2373
+ return res;
2374
+ };
2375
+ var union = (other) => (data) => {
2376
+ if (data.size === 0) {
2377
+ return other;
2378
+ }
2379
+ if (other.size === 0) {
2380
+ return data;
2381
+ }
2382
+ const res = new globalThis.Map(data);
2383
+ for (const [k, v] of other) {
2384
+ res.set(k, v);
2385
+ }
2386
+ return res;
2387
+ };
2388
+ var intersection = (other) => (data) => {
2389
+ const res = new globalThis.Map();
2390
+ for (const [k, v] of data) {
2391
+ if (other.has(k)) {
2392
+ res.set(k, v);
942
2393
  }
943
- return acc;
944
- };
945
- Dict2.reduceWithKey = (init, f) => (m) => {
946
- let acc = init;
947
- for (const [k, v] of m) {
948
- acc = f(acc, v, k);
2394
+ }
2395
+ return res;
2396
+ };
2397
+ var difference = (other) => (data) => {
2398
+ if (other.size === 0) {
2399
+ return data;
2400
+ }
2401
+ const res = new globalThis.Map();
2402
+ for (const [k, v] of data) {
2403
+ if (!other.has(k)) {
2404
+ res.set(k, v);
949
2405
  }
950
- return acc;
951
- };
952
- function mergeWith(combine) {
953
- return (arg1, arg2) => {
954
- if (arg2 !== void 0) {
955
- const first = arg1;
956
- const second2 = arg2;
957
- const res = new globalThis.Map(first);
958
- for (const [k, v] of second2) {
959
- if (res.has(k)) {
960
- res.set(k, combine(res.get(k), v));
961
- } else {
962
- res.set(k, v);
963
- }
2406
+ }
2407
+ return res;
2408
+ };
2409
+ var reduce2 = (init2, f) => (data) => {
2410
+ let acc = init2;
2411
+ for (const [, v] of data) {
2412
+ acc = f(acc, v);
2413
+ }
2414
+ return acc;
2415
+ };
2416
+ var reduceWithKey = (init2, f) => (data) => {
2417
+ let acc = init2;
2418
+ for (const [k, v] of data) {
2419
+ acc = f(acc, v, k);
2420
+ }
2421
+ return acc;
2422
+ };
2423
+ function mergeWith(combine) {
2424
+ return ((arg1, arg2) => {
2425
+ if (arg2 !== void 0) {
2426
+ const res = new globalThis.Map(arg1);
2427
+ for (const [k, v] of arg2) {
2428
+ if (res.has(k)) {
2429
+ res.set(k, combine(res.get(k), v));
2430
+ } else {
2431
+ res.set(k, v);
964
2432
  }
965
- return res;
966
2433
  }
2434
+ return res;
2435
+ }
2436
+ return (first) => {
967
2437
  const second = arg1;
968
- return (first) => {
969
- const res = new globalThis.Map(first);
970
- for (const [k, v] of second) {
971
- if (res.has(k)) {
972
- res.set(k, combine(res.get(k), v));
973
- } else {
974
- res.set(k, v);
975
- }
2438
+ const res = new globalThis.Map(first);
2439
+ for (const [k, v] of second) {
2440
+ if (res.has(k)) {
2441
+ res.set(k, combine(res.get(k), v));
2442
+ } else {
2443
+ res.set(k, v);
976
2444
  }
977
- return res;
978
- };
2445
+ }
2446
+ return res;
979
2447
  };
2448
+ });
2449
+ }
2450
+ var mapEntries = (f) => (data) => {
2451
+ const res = new globalThis.Map();
2452
+ for (const [k, v] of data) {
2453
+ const [nk, nv] = f(k, v);
2454
+ res.set(nk, nv);
980
2455
  }
981
- Dict2.mergeWith = mergeWith;
982
- let to;
983
- ((to2) => {
984
- to2.Record = (m) => Object.fromEntries(m);
985
- })(to = Dict2.to || (Dict2.to = {}));
986
- Dict2.mapEntries = (f) => (data) => {
987
- const res = new globalThis.Map();
988
- for (const [k, v] of data) {
989
- const [nk, nv] = f(k, v);
990
- res.set(nk, nv);
991
- }
992
- return res;
993
- };
994
- Dict2.mapKeys = (f) => (data) => {
995
- const res = new globalThis.Map();
996
- for (const [k, v] of data) {
997
- res.set(f(k), v);
998
- }
999
- return res;
1000
- };
1001
- Dict2.NonEmpty = DictNonEmpty;
1002
- })(Dict || (Dict = {}));
2456
+ return res;
2457
+ };
2458
+ var mapKeys = (f) => (data) => {
2459
+ const res = new globalThis.Map();
2460
+ for (const [k, v] of data) {
2461
+ res.set(f(k), v);
2462
+ }
2463
+ return res;
2464
+ };
2465
+ var _nonEmptySingleton = (key, value) => new globalThis.Map([[key, value]]);
2466
+ var _nonEmptyFromMap = (m) => m.size > 0 ? Maybe.make.some(m) : Maybe.make.none();
2467
+ var _nonEmptyKeys = (m) => keys(m);
2468
+ var _nonEmptyValues = (m) => values(m);
2469
+ var _nonEmptyEntries = (m) => entries(m);
2470
+ var _nonEmptyReduce = (f) => (m) => _nonEmptyValues(m).reduce(f);
2471
+ var _nonEmptyMap = (f) => (m) => map2(f)(m);
2472
+ var _nonEmptyMapWithKey = (f) => (m) => mapWithKey(f)(m);
2473
+ var DictNonEmptyConst = {
2474
+ singleton: _nonEmptySingleton,
2475
+ from: { Map: _nonEmptyFromMap },
2476
+ keys: _nonEmptyKeys,
2477
+ values: _nonEmptyValues,
2478
+ entries: _nonEmptyEntries,
2479
+ reduce: _nonEmptyReduce,
2480
+ map: _nonEmptyMap,
2481
+ mapWithKey: _nonEmptyMapWithKey
2482
+ };
2483
+ var Dict = {
2484
+ is: DictIs,
2485
+ empty,
2486
+ singleton,
2487
+ from: DictFrom,
2488
+ to: DictTo,
2489
+ groupBy: groupBy2,
2490
+ has,
2491
+ lookup,
2492
+ size: size2,
2493
+ keys,
2494
+ values,
2495
+ entries,
2496
+ insert,
2497
+ remove,
2498
+ upsert,
2499
+ map: map2,
2500
+ mapWithKey,
2501
+ filter: filter2,
2502
+ filterWithKey,
2503
+ compact: compact2,
2504
+ filterMap: filterMap2,
2505
+ union,
2506
+ intersection,
2507
+ difference,
2508
+ reduce: reduce2,
2509
+ reduceWithKey,
2510
+ mergeWith,
2511
+ mapEntries,
2512
+ mapKeys,
2513
+ NonEmpty: DictNonEmptyConst
2514
+ };
1003
2515
 
1004
2516
  // src/Data/Json.ts
1005
2517
  var isSyntaxError = (err) => typeof err === "object" && err !== null && "name" in err && err.name === "SyntaxError";
1006
2518
  var isTypeError = (err) => typeof err === "object" && err !== null && "name" in err && err.name === "TypeError";
1007
- var Json;
1008
- ((Json2) => {
1009
- Json2.parse = (text) => Result.tryCatch(() => JSON.parse(text), {
2519
+ var Json = {
2520
+ /**
2521
+ * Safely parses a JSON string into `unknown`.
2522
+ * Converts thrown exceptions into a `Result<SyntaxError, unknown>`.
2523
+ *
2524
+ * @example
2525
+ * ```ts
2526
+ * Json.parse('{"a": 1}'); // Ok({ a: 1 })
2527
+ * Json.parse('{invalid}'); // Err(SyntaxError)
2528
+ * ```
2529
+ */
2530
+ parse: (text) => Result.tryCatch(() => JSON.parse(text), {
1010
2531
  onError: (err) => isSyntaxError(err) ? err : new SyntaxError(String(err))
1011
- });
1012
- Json2.stringify = (value, replacer, space) => Result.tryCatch(() => JSON.stringify(value, replacer, space), {
2532
+ }),
2533
+ /**
2534
+ * Safely stringifies a value into a JSON string.
2535
+ * Converts thrown exceptions (e.g. circular references) into a `Result<TypeError, string>`.
2536
+ *
2537
+ * @example
2538
+ * ```ts
2539
+ * Json.stringify({ a: 1 }); // Ok('{"a":1}')
2540
+ * ```
2541
+ */
2542
+ stringify: (value, replacer, space) => Result.tryCatch(() => JSON.stringify(value, replacer, space), {
1013
2543
  onError: (err) => isTypeError(err) ? err : new TypeError(String(err))
1014
- });
1015
- })(Json || (Json = {}));
2544
+ })
2545
+ };
1016
2546
 
1017
2547
  // src/Data/Num.ts
1018
- var Num;
1019
- ((Num2) => {
1020
- let is;
1021
- ((is2) => {
1022
- is2.zero = (n) => n === 0;
1023
- is2.integer = (n) => Number.isInteger(n);
1024
- is2.float = (n) => Number.isFinite(n) && !Number.isInteger(n);
1025
- is2.finite = (n) => Number.isFinite(n);
1026
- is2.nan = (n) => Number.isNaN(n);
1027
- is2.even = (n) => Number.isInteger(n) && n % 2 === 0;
1028
- is2.odd = (n) => Number.isInteger(n) && n % 2 !== 0;
1029
- is2.positive = (n) => n > 0;
1030
- is2.negative = (n) => n < 0;
1031
- })(is = Num2.is || (Num2.is = {}));
1032
- Num2.range = (from, to, step = 1) => {
2548
+ var sumFn = (ns) => {
2549
+ let result = 0;
2550
+ for (let i = 0; i < ns.length; i++) {
2551
+ result += ns[i];
2552
+ }
2553
+ return result;
2554
+ };
2555
+ var Num = {
2556
+ is: {
2557
+ /**
2558
+ * Returns `true` when the number is equal to zero.
2559
+ *
2560
+ * @example
2561
+ * ```ts
2562
+ * Num.is.zero(0); // true
2563
+ * Num.is.zero(5); // false
2564
+ * ```
2565
+ */
2566
+ zero: (n) => n === 0,
2567
+ /**
2568
+ * Returns `true` when the number is a whole integer.
2569
+ *
2570
+ * @example
2571
+ * ```ts
2572
+ * Num.is.integer(5); // true
2573
+ * Num.is.integer(3.14); // false
2574
+ * ```
2575
+ */
2576
+ integer: (n) => Number.isInteger(n),
2577
+ /**
2578
+ * Returns `true` when the number is a finite float (fractional number).
2579
+ *
2580
+ * @example
2581
+ * ```ts
2582
+ * Num.is.float(3.14); // true
2583
+ * Num.is.float(5); // false
2584
+ * ```
2585
+ */
2586
+ float: (n) => Number.isFinite(n) && !Number.isInteger(n),
2587
+ /**
2588
+ * Returns `true` when the number is finite (not `Infinity`, `-Infinity`, or `NaN`).
2589
+ *
2590
+ * @example
2591
+ * ```ts
2592
+ * Num.is.finite(42); // true
2593
+ * Num.is.finite(Infinity); // false
2594
+ * ```
2595
+ */
2596
+ finite: (n) => Number.isFinite(n),
2597
+ /**
2598
+ * Returns `true` when the value is `NaN`.
2599
+ *
2600
+ * @example
2601
+ * ```ts
2602
+ * Num.is.nan(NaN); // true
2603
+ * Num.is.nan(42); // false
2604
+ * ```
2605
+ */
2606
+ nan: (n) => Number.isNaN(n),
2607
+ /**
2608
+ * Returns `true` when the number is an even integer.
2609
+ *
2610
+ * @example
2611
+ * ```ts
2612
+ * Num.is.even(4); // true
2613
+ * Num.is.even(3); // false
2614
+ * Num.is.even(2.5); // false
2615
+ * ```
2616
+ */
2617
+ even: (n) => Number.isInteger(n) && n % 2 === 0,
2618
+ /**
2619
+ * Returns `true` when the number is an odd integer.
2620
+ *
2621
+ * @example
2622
+ * ```ts
2623
+ * Num.is.odd(3); // true
2624
+ * Num.is.odd(4); // false
2625
+ * Num.is.odd(2.5); // false
2626
+ * ```
2627
+ */
2628
+ odd: (n) => Number.isInteger(n) && n % 2 !== 0,
2629
+ /**
2630
+ * Returns `true` when the number is strictly greater than zero.
2631
+ *
2632
+ * @example
2633
+ * ```ts
2634
+ * Num.is.positive(5); // true
2635
+ * Num.is.positive(0); // false
2636
+ * Num.is.positive(-5); // false
2637
+ * ```
2638
+ */
2639
+ positive: (n) => n > 0,
2640
+ /**
2641
+ * Returns `true` when the number is strictly less than zero.
2642
+ *
2643
+ * @example
2644
+ * ```ts
2645
+ * Num.is.negative(-5); // true
2646
+ * Num.is.negative(0); // false
2647
+ * Num.is.negative(5); // false
2648
+ * ```
2649
+ */
2650
+ negative: (n) => n < 0
2651
+ },
2652
+ /**
2653
+ * Generates an array of numbers from `from` to `to` (both inclusive),
2654
+ * stepping by `step` (default `1`). If `step` is negative or zero, or `from > to`,
2655
+ * returns an empty array. When `step` does not land exactly on `to`, the last value
2656
+ * is the largest reachable value that does not exceed `to`.
2657
+ *
2658
+ * @example
2659
+ * ```ts
2660
+ * Num.range(0, 5); // [0, 1, 2, 3, 4, 5]
2661
+ * Num.range(0, 10, 2); // [0, 2, 4, 6, 8, 10]
2662
+ * Num.range(0, 9, 2); // [0, 2, 4, 6, 8]
2663
+ * Num.range(5, 0); // []
2664
+ * Num.range(3, 3); // [3]
2665
+ * ```
2666
+ */
2667
+ range: (from, to, step = 1) => {
1033
2668
  if (step <= 0 || from > to) {
1034
2669
  return [];
1035
2670
  }
@@ -1039,36 +2674,191 @@ var Num;
1039
2674
  result[i] = from + i * step;
1040
2675
  }
1041
2676
  return result;
1042
- };
1043
- Num2.clamp = (min2, max2) => (n) => Math.min(Math.max(n, min2), max2);
1044
- Num2.between = (min2, max2) => (n) => n >= min2 && n <= max2;
1045
- Num2.inRange = (start, end) => (n) => n >= start && n < end;
1046
- Num2.parse = (s) => {
2677
+ },
2678
+ /**
2679
+ * Clamps a number between `min` and `max` (both inclusive).
2680
+ *
2681
+ * @example
2682
+ * ```ts
2683
+ * pipe(150, Num.clamp(0, 100)); // 100
2684
+ * pipe(-5, Num.clamp(0, 100)); // 0
2685
+ * pipe(42, Num.clamp(0, 100)); // 42
2686
+ * ```
2687
+ */
2688
+ clamp: (min, max) => (n) => Math.min(Math.max(n, min), max),
2689
+ /**
2690
+ * Returns `true` when the number is between `min` and `max` (both inclusive).
2691
+ *
2692
+ * @example
2693
+ * ```ts
2694
+ * pipe(5, Num.between(1, 10)); // true
2695
+ * pipe(0, Num.between(1, 10)); // false
2696
+ * pipe(10, Num.between(1, 10)); // true
2697
+ * ```
2698
+ */
2699
+ between: (min, max) => (n) => n >= min && n <= max,
2700
+ /**
2701
+ * Returns `true` when the number is in the range `[start, end)` (inclusive of `start`, exclusive of `end`).
2702
+ *
2703
+ * @example
2704
+ * ```ts
2705
+ * pipe(5, Num.inRange(1, 10)); // true
2706
+ * pipe(1, Num.inRange(1, 10)); // true
2707
+ * pipe(10, Num.inRange(1, 10)); // false
2708
+ * ```
2709
+ */
2710
+ inRange: (start, end) => (n) => n >= start && n < end,
2711
+ /**
2712
+ * Parses a string as a number. Returns `None` when the result is `NaN`.
2713
+ *
2714
+ * @example
2715
+ * ```ts
2716
+ * Num.parse("42"); // Some(42)
2717
+ * Num.parse("3.14"); // Some(3.14)
2718
+ * Num.parse("abc"); // None
2719
+ * Num.parse(""); // None
2720
+ * ```
2721
+ */
2722
+ parse: (s) => {
1047
2723
  if (s.trim() === "") {
1048
2724
  return Maybe.make.none();
1049
2725
  }
1050
2726
  const n = Number(s);
1051
2727
  return isNaN(n) ? Maybe.make.none() : Maybe.make.some(n);
1052
- };
1053
- Num2.add = (b) => (a) => a + b;
1054
- Num2.subtract = (b) => (a) => a - b;
1055
- Num2.multiply = (b) => (a) => a * b;
1056
- Num2.divide = (b) => (a) => b === 0 ? Maybe.make.none() : Maybe.make.some(a / b);
1057
- Num2.abs = (n) => Math.abs(n);
1058
- Num2.negate = (n) => -n;
1059
- Num2.round = (n) => Math.round(n);
1060
- Num2.floor = (n) => Math.floor(n);
1061
- Num2.ceil = (n) => Math.ceil(n);
1062
- Num2.remainder = (divisor) => (n) => divisor === 0 ? Maybe.make.none() : Maybe.make.some(n % divisor);
1063
- Num2.sum = (ns) => {
1064
- let result = 0;
1065
- for (let i = 0; i < ns.length; i++) {
1066
- result += ns[i];
1067
- }
1068
- return result;
1069
- };
1070
- Num2.mean = (ns) => ns.length === 0 ? Maybe.make.none() : Maybe.make.some((0, Num2.sum)(ns) / ns.length);
1071
- Num2.min = (ns) => {
2728
+ },
2729
+ /**
2730
+ * Adds `b` to a number. Data-last: use in `pipe` or `Arr.map`.
2731
+ *
2732
+ * @example
2733
+ * ```ts
2734
+ * pipe(5, Num.add(3)); // 8
2735
+ * pipe([1, 2, 3], Arr.map(Num.add(10))); // [11, 12, 13]
2736
+ * ```
2737
+ */
2738
+ add: (b) => (a) => a + b,
2739
+ /**
2740
+ * Subtracts `b` from a number. Data-last: `subtract(b)(a)` = `a - b`.
2741
+ *
2742
+ * @example
2743
+ * ```ts
2744
+ * pipe(10, Num.subtract(3)); // 7
2745
+ * pipe([5, 10, 15], Arr.map(Num.subtract(2))); // [3, 8, 13]
2746
+ * ```
2747
+ */
2748
+ subtract: (b) => (a) => a - b,
2749
+ /**
2750
+ * Multiplies a number by `b`. Data-last: use in `pipe` or `Arr.map`.
2751
+ *
2752
+ * @example
2753
+ * ```ts
2754
+ * pipe(6, Num.multiply(7)); // 42
2755
+ * pipe([1, 2, 3], Arr.map(Num.multiply(100))); // [100, 200, 300]
2756
+ * ```
2757
+ */
2758
+ multiply: (b) => (a) => a * b,
2759
+ /**
2760
+ * Divides a number by `b`. Returns `None` when `b` is zero. Data-last: `divide(b)(a)` = `a / b`.
2761
+ *
2762
+ * @example
2763
+ * ```ts
2764
+ * pipe(20, Num.divide(4)); // Some(5)
2765
+ * pipe(5, Num.divide(0)); // None
2766
+ * pipe([10, 20, 30], Arr.filterMap(Num.divide(10))); // [1, 2, 3]
2767
+ * ```
2768
+ */
2769
+ divide: (b) => (a) => b === 0 ? Maybe.make.none() : Maybe.make.some(a / b),
2770
+ /**
2771
+ * Returns the absolute value of a number.
2772
+ *
2773
+ * @example
2774
+ * ```ts
2775
+ * pipe(-5, Num.abs); // 5
2776
+ * pipe(5, Num.abs); // 5
2777
+ * ```
2778
+ */
2779
+ abs: (n) => Math.abs(n),
2780
+ /**
2781
+ * Negates a number (arithmetic negation).
2782
+ *
2783
+ * @example
2784
+ * ```ts
2785
+ * pipe(5, Num.negate); // -5
2786
+ * pipe(-5, Num.negate); // 5
2787
+ * ```
2788
+ */
2789
+ negate: (n) => -n,
2790
+ /**
2791
+ * Rounds a number to the nearest integer.
2792
+ *
2793
+ * @example
2794
+ * ```ts
2795
+ * pipe(3.5, Num.round); // 4
2796
+ * pipe(3.4, Num.round); // 3
2797
+ * ```
2798
+ */
2799
+ round: (n) => Math.round(n),
2800
+ /**
2801
+ * Rounds a number down to the nearest integer.
2802
+ *
2803
+ * @example
2804
+ * ```ts
2805
+ * pipe(3.9, Num.floor); // 3
2806
+ * pipe(-3.2, Num.floor); // -4
2807
+ * ```
2808
+ */
2809
+ floor: (n) => Math.floor(n),
2810
+ /**
2811
+ * Rounds a number up to the nearest integer.
2812
+ *
2813
+ * @example
2814
+ * ```ts
2815
+ * pipe(3.1, Num.ceil); // 4
2816
+ * pipe(-3.9, Num.ceil); // -3
2817
+ * ```
2818
+ */
2819
+ ceil: (n) => Math.ceil(n),
2820
+ /**
2821
+ * Returns the remainder of dividing a number by `divisor`. Returns `None` when `divisor` is zero.
2822
+ * Data-last: `remainder(divisor)(a)` = `a % divisor`.
2823
+ *
2824
+ * @example
2825
+ * ```ts
2826
+ * pipe(10, Num.remainder(3)); // Some(1)
2827
+ * pipe(5, Num.remainder(0)); // None
2828
+ * pipe([10, 11, 12], Arr.filterMap(Num.remainder(3))); // [1, 2, 0]
2829
+ * ```
2830
+ */
2831
+ remainder: (divisor) => (n) => divisor === 0 ? Maybe.make.none() : Maybe.make.some(n % divisor),
2832
+ /**
2833
+ * Computes the sum of a list of numbers. Returns `0` if the list is empty.
2834
+ *
2835
+ * @example
2836
+ * ```ts
2837
+ * Num.sum([1, 2, 3]); // 6
2838
+ * Num.sum([]); // 0
2839
+ * ```
2840
+ */
2841
+ sum: sumFn,
2842
+ /**
2843
+ * Computes the mean of a list of numbers. Returns `None` if the list is empty.
2844
+ *
2845
+ * @example
2846
+ * ```ts
2847
+ * Num.mean([1, 2, 3]); // Some(2)
2848
+ * Num.mean([]); // None
2849
+ * ```
2850
+ */
2851
+ mean: (ns) => ns.length === 0 ? Maybe.make.none() : Maybe.make.some(sumFn(ns) / ns.length),
2852
+ /**
2853
+ * Computes the minimum of a list of numbers. Returns `None` if the list is empty.
2854
+ *
2855
+ * @example
2856
+ * ```ts
2857
+ * Num.min([5, 1, 3]); // Some(1)
2858
+ * Num.min([]); // None
2859
+ * ```
2860
+ */
2861
+ min: (ns) => {
1072
2862
  if (ns.length === 0) {
1073
2863
  return Maybe.make.none();
1074
2864
  }
@@ -1079,8 +2869,17 @@ var Num;
1079
2869
  }
1080
2870
  }
1081
2871
  return Maybe.make.some(result);
1082
- };
1083
- Num2.max = (ns) => {
2872
+ },
2873
+ /**
2874
+ * Computes the maximum of a list of numbers. Returns `None` if the list is empty.
2875
+ *
2876
+ * @example
2877
+ * ```ts
2878
+ * Num.max([1, 5, 3]); // Some(5)
2879
+ * Num.max([]); // None
2880
+ * ```
2881
+ */
2882
+ max: (ns) => {
1084
2883
  if (ns.length === 0) {
1085
2884
  return Maybe.make.none();
1086
2885
  }
@@ -1091,9 +2890,20 @@ var Num;
1091
2890
  }
1092
2891
  }
1093
2892
  return Maybe.make.some(result);
1094
- };
1095
- Num2.format = (options, locales) => (n) => !Number.isFinite(n) ? Maybe.make.none() : Maybe.make.some(new Intl.NumberFormat(locales, options).format(n));
1096
- })(Num || (Num = {}));
2893
+ },
2894
+ /**
2895
+ * Formats a number using `Intl.NumberFormat`. Returns `None` when `n` is `NaN` or non-finite.
2896
+ * Data-last curried signature.
2897
+ *
2898
+ * @example
2899
+ * ```ts
2900
+ * const formatCurrency = Num.format({ style: "currency", currency: "USD" }, "en-US");
2901
+ * pipe(1234.5, formatCurrency); // Some("$1,234.50")
2902
+ * pipe(NaN, formatCurrency); // None
2903
+ * ```
2904
+ */
2905
+ format: (options, locales) => (n) => !Number.isFinite(n) ? Maybe.make.none() : Maybe.make.some(new Intl.NumberFormat(locales, options).format(n))
2906
+ };
1097
2907
 
1098
2908
  // src/Data/Rec.ts
1099
2909
  var _isNonEmpty = (data) => Object.keys(data).length > 0;
@@ -1141,259 +2951,466 @@ var RecResult;
1141
2951
  };
1142
2952
  RecResult2.sequence = (data) => (0, RecResult2.traverse)((a) => a)(data);
1143
2953
  })(RecResult || (RecResult = {}));
1144
- var RecNonEmpty;
1145
- ((RecNonEmpty2) => {
1146
- RecNonEmpty2.singleton = (key, value) => ({ [key]: value });
1147
- let from;
1148
- ((from2) => {
1149
- from2.Record = (data) => _isNonEmpty(data) ? Maybe.make.some(data) : Maybe.make.none();
1150
- })(from = RecNonEmpty2.from || (RecNonEmpty2.from = {}));
1151
- RecNonEmpty2.keys = (data) => Rec.keys(data);
1152
- RecNonEmpty2.values = (data) => Rec.values(data);
1153
- RecNonEmpty2.entries = (data) => Rec.entries(data);
1154
- RecNonEmpty2.reduce = (f) => (data) => (0, RecNonEmpty2.values)(data).reduce(f);
1155
- RecNonEmpty2.map = (f) => (data) => Rec.map(f)(data);
1156
- RecNonEmpty2.mapWithKey = (f) => (data) => Rec.mapWithKey(f)(data);
1157
- })(RecNonEmpty || (RecNonEmpty = {}));
1158
- var Rec;
1159
- ((Rec2) => {
1160
- let is;
1161
- ((is2) => {
1162
- is2.empty = (data) => Object.keys(data).length === 0;
1163
- is2.nonEmpty = _isNonEmpty;
1164
- })(is = Rec2.is || (Rec2.is = {}));
1165
- Rec2.map = (f) => (data) => {
1166
- const recordKeys = Object.keys(data);
1167
- const recordValues = Object.values(data);
1168
- const result = Object.create(Object.getPrototypeOf(data));
1169
- for (let i = 0; i < recordKeys.length; i++) {
1170
- const key = recordKeys[i];
1171
- if (key === "__proto__") {
1172
- Object.defineProperty(result, "__proto__", {
1173
- value: f(recordValues[i]),
1174
- writable: true,
1175
- enumerable: true,
1176
- configurable: true
1177
- });
1178
- } else {
1179
- result[key] = f(recordValues[i]);
1180
- }
1181
- }
1182
- return result;
1183
- };
1184
- Rec2.filterMap = (f) => (data) => {
1185
- const recordKeys = Object.keys(data);
1186
- const recordValues = Object.values(data);
1187
- const result = Object.create(Object.getPrototypeOf(data));
1188
- for (let i = 0; i < recordKeys.length; i++) {
1189
- const maybeVal = f(recordValues[i]);
1190
- if (maybeVal.kind === "Some") {
1191
- _setKey(result, recordKeys[i], maybeVal.value);
1192
- }
2954
+ var RecIs = {
2955
+ /**
2956
+ * Returns true if the record has no keys.
2957
+ *
2958
+ * @example
2959
+ * ```ts
2960
+ * Rec.is.empty({}); // true
2961
+ * Rec.is.empty({ a: 1 }); // false
2962
+ * ```
2963
+ */
2964
+ empty: (data) => Object.keys(data).length === 0,
2965
+ /**
2966
+ * Type guard to check if a record is non-empty.
2967
+ *
2968
+ * @example
2969
+ * ```ts
2970
+ * Rec.is.nonEmpty({ a: 1 }); // true
2971
+ * Rec.is.nonEmpty({}); // false
2972
+ * ```
2973
+ */
2974
+ nonEmpty: _isNonEmpty
2975
+ };
2976
+ var map3 = (f) => (data) => {
2977
+ const recordKeys = Object.keys(data);
2978
+ const recordValues = Object.values(data);
2979
+ const result = Object.create(Object.getPrototypeOf(data));
2980
+ for (let i = 0; i < recordKeys.length; i++) {
2981
+ const key = recordKeys[i];
2982
+ if (key === "__proto__") {
2983
+ Object.defineProperty(result, "__proto__", {
2984
+ value: f(recordValues[i]),
2985
+ writable: true,
2986
+ enumerable: true,
2987
+ configurable: true
2988
+ });
2989
+ } else {
2990
+ result[key] = f(recordValues[i]);
1193
2991
  }
1194
- return result;
1195
- };
1196
- Rec2.mapWithKey = (f) => (data) => {
1197
- const recordKeys = Object.keys(data);
1198
- const recordValues = Object.values(data);
1199
- const result = Object.create(Object.getPrototypeOf(data));
1200
- for (let i = 0; i < recordKeys.length; i++) {
1201
- const key = recordKeys[i];
1202
- _setKey(result, key, f(key, recordValues[i]));
2992
+ }
2993
+ return result;
2994
+ };
2995
+ var filterMap3 = (f) => (data) => {
2996
+ const recordKeys = Object.keys(data);
2997
+ const recordValues = Object.values(data);
2998
+ const result = Object.create(Object.getPrototypeOf(data));
2999
+ for (let i = 0; i < recordKeys.length; i++) {
3000
+ const maybeVal = f(recordValues[i]);
3001
+ if (maybeVal.kind === "Some") {
3002
+ _setKey(result, recordKeys[i], maybeVal.value);
1203
3003
  }
1204
- return result;
1205
- };
1206
- Rec2.filter = (predicate) => (data) => {
1207
- const recordKeys = Object.keys(data);
1208
- const recordValues = Object.values(data);
1209
- const result = Object.create(Object.getPrototypeOf(data));
1210
- for (let i = 0; i < recordKeys.length; i++) {
1211
- if (predicate(recordValues[i])) {
1212
- _setKey(result, recordKeys[i], recordValues[i]);
1213
- }
3004
+ }
3005
+ return result;
3006
+ };
3007
+ var mapWithKey2 = (f) => (data) => {
3008
+ const recordKeys = Object.keys(data);
3009
+ const recordValues = Object.values(data);
3010
+ const result = Object.create(Object.getPrototypeOf(data));
3011
+ for (let i = 0; i < recordKeys.length; i++) {
3012
+ const key = recordKeys[i];
3013
+ _setKey(result, key, f(key, recordValues[i]));
3014
+ }
3015
+ return result;
3016
+ };
3017
+ var filter3 = (predicate) => (data) => {
3018
+ const recordKeys = Object.keys(data);
3019
+ const recordValues = Object.values(data);
3020
+ const result = Object.create(Object.getPrototypeOf(data));
3021
+ for (let i = 0; i < recordKeys.length; i++) {
3022
+ if (predicate(recordValues[i])) {
3023
+ _setKey(result, recordKeys[i], recordValues[i]);
1214
3024
  }
1215
- return result;
1216
- };
1217
- Rec2.filterWithKey = (predicate) => (data) => {
1218
- const result = {};
1219
- for (const [k, v] of Object.entries(data)) {
1220
- if (predicate(k, v)) {
1221
- _setKey(result, k, v);
1222
- }
3025
+ }
3026
+ return result;
3027
+ };
3028
+ var filterWithKey2 = (predicate) => (data) => {
3029
+ const result = {};
3030
+ for (const [k, v] of Object.entries(data)) {
3031
+ if (predicate(k, v)) {
3032
+ _setKey(result, k, v);
1223
3033
  }
1224
- return result;
1225
- };
1226
- Rec2.lookup = (key) => (data) => Object.hasOwn(data, key) ? { kind: "Some", value: data[key] } : { kind: "None" };
1227
- Rec2.keys = (data) => Object.keys(data);
1228
- Rec2.values = (data) => Object.values(data);
1229
- Rec2.entries = (data) => Object.entries(data);
1230
- let from;
1231
- ((from2) => {
1232
- from2.entries = (data) => Object.fromEntries(data);
1233
- })(from = Rec2.from || (Rec2.from = {}));
1234
- Rec2.groupBy = (keyFn) => (items) => {
1235
- const result = {};
1236
- for (const item of items) {
1237
- const key = keyFn(item);
1238
- if (Object.hasOwn(result, key)) {
1239
- result[key].push(item);
1240
- } else {
1241
- _setKey(result, key, [item]);
1242
- }
3034
+ }
3035
+ return result;
3036
+ };
3037
+ var lookup2 = (key) => (data) => Object.hasOwn(data, key) ? { kind: "Some", value: data[key] } : { kind: "None" };
3038
+ var keys2 = (data) => Object.keys(data);
3039
+ var values2 = (data) => Object.values(data);
3040
+ var entries2 = (data) => Object.entries(data);
3041
+ var RecFrom = {
3042
+ /**
3043
+ * Creates a record from key-value pairs.
3044
+ *
3045
+ * @example
3046
+ * ```ts
3047
+ * Rec.from.entries([["a", 1], ["b", 2]]); // { a: 1, b: 2 }
3048
+ * ```
3049
+ */
3050
+ entries: (data) => Object.fromEntries(data)
3051
+ };
3052
+ var groupBy3 = (keyFn) => (items) => {
3053
+ const result = {};
3054
+ for (const item of items) {
3055
+ const key = keyFn(item);
3056
+ if (Object.hasOwn(result, key)) {
3057
+ result[key].push(item);
3058
+ } else {
3059
+ _setKey(result, key, [item]);
1243
3060
  }
1244
- return result;
1245
- };
1246
- Rec2.pick = (...pickedKeys) => (data) => {
1247
- const result = {};
1248
- for (const key of pickedKeys) {
1249
- if (Object.hasOwn(data, key)) {
1250
- _setKey(result, key, data[key]);
1251
- }
3061
+ }
3062
+ return result;
3063
+ };
3064
+ var pick = (...pickedKeys) => (data) => {
3065
+ const result = {};
3066
+ for (const key of pickedKeys) {
3067
+ if (Object.hasOwn(data, key)) {
3068
+ _setKey(result, key, data[key]);
1252
3069
  }
1253
- return result;
1254
- };
1255
- Rec2.omit = (...omittedKeys) => (data) => {
1256
- const omitSet = new Set(omittedKeys);
1257
- const result = {};
1258
- for (const key of Object.keys(data)) {
1259
- if (!omitSet.has(key)) {
1260
- _setKey(result, key, data[key]);
1261
- }
3070
+ }
3071
+ return result;
3072
+ };
3073
+ var omit = (...omittedKeys) => (data) => {
3074
+ const omitSet = new Set(omittedKeys);
3075
+ const result = {};
3076
+ for (const key of Object.keys(data)) {
3077
+ if (!omitSet.has(key)) {
3078
+ _setKey(result, key, data[key]);
1262
3079
  }
1263
- return result;
1264
- };
1265
- Rec2.merge = (other) => (data) => ({
1266
- ...data,
1267
- ...other
1268
- });
1269
- function mergeWith(combine) {
1270
- return (arg1, arg2) => {
1271
- if (arg2 !== void 0) {
1272
- const first = arg1;
1273
- const second2 = arg2;
1274
- const result = { ...first };
1275
- for (const [k, v] of Object.entries(second2)) {
1276
- if (Object.hasOwn(result, k)) {
1277
- result[k] = combine(result[k], v);
1278
- } else {
1279
- result[k] = v;
1280
- }
3080
+ }
3081
+ return result;
3082
+ };
3083
+ var merge = (other) => (data) => ({
3084
+ ...data,
3085
+ ...other
3086
+ });
3087
+ function mergeWith2(combine) {
3088
+ return (arg1, arg2) => {
3089
+ if (arg2 !== void 0) {
3090
+ const first = arg1;
3091
+ const second2 = arg2;
3092
+ const result = { ...first };
3093
+ for (const [k, v] of Object.entries(second2)) {
3094
+ if (Object.hasOwn(result, k)) {
3095
+ result[k] = combine(result[k], v);
3096
+ } else {
3097
+ result[k] = v;
1281
3098
  }
1282
- return result;
1283
3099
  }
1284
- const second = arg1;
1285
- return (first) => {
1286
- const result = { ...first };
1287
- for (const [k, v] of Object.entries(second)) {
1288
- if (Object.hasOwn(result, k)) {
1289
- result[k] = combine(result[k], v);
1290
- } else {
1291
- result[k] = v;
1292
- }
3100
+ return result;
3101
+ }
3102
+ const second = arg1;
3103
+ return (first) => {
3104
+ const result = { ...first };
3105
+ for (const [k, v] of Object.entries(second)) {
3106
+ if (Object.hasOwn(result, k)) {
3107
+ result[k] = combine(result[k], v);
3108
+ } else {
3109
+ result[k] = v;
1293
3110
  }
1294
- return result;
1295
- };
1296
- };
1297
- }
1298
- Rec2.mergeWith = mergeWith;
1299
- Rec2.size = (data) => Object.keys(data).length;
1300
- Rec2.mapKeys = (f) => (data) => {
1301
- const keys2 = Object.keys(data);
1302
- if (keys2.length === 0) {
1303
- return data;
1304
- }
1305
- const result = {};
1306
- for (let i = 0; i < keys2.length; i++) {
1307
- const k = keys2[i];
1308
- _setKey(result, f(k), data[k]);
1309
- }
1310
- return result;
1311
- };
1312
- Rec2.compact = (data) => {
1313
- const keys2 = Object.keys(data);
1314
- if (keys2.length === 0) {
1315
- return {};
1316
- }
1317
- const result = {};
1318
- for (let i = 0; i < keys2.length; i++) {
1319
- const k = keys2[i];
1320
- const v = data[k];
1321
- if (v.kind === "Some") {
1322
- _setKey(result, k, v.value);
1323
3111
  }
1324
- }
1325
- return result;
3112
+ return result;
3113
+ };
1326
3114
  };
1327
- Rec2.mapEntries = (f) => (data) => {
1328
- const keys2 = Object.keys(data);
1329
- if (keys2.length === 0) {
1330
- return {};
3115
+ }
3116
+ var size3 = (data) => Object.keys(data).length;
3117
+ var mapKeys2 = (f) => (data) => {
3118
+ const recKeys = Object.keys(data);
3119
+ if (recKeys.length === 0) {
3120
+ return data;
3121
+ }
3122
+ const result = {};
3123
+ for (let i = 0; i < recKeys.length; i++) {
3124
+ const k = recKeys[i];
3125
+ _setKey(result, f(k), data[k]);
3126
+ }
3127
+ return result;
3128
+ };
3129
+ var compact3 = (data) => {
3130
+ const recKeys = Object.keys(data);
3131
+ if (recKeys.length === 0) {
3132
+ return {};
3133
+ }
3134
+ const result = {};
3135
+ for (let i = 0; i < recKeys.length; i++) {
3136
+ const k = recKeys[i];
3137
+ const v = data[k];
3138
+ if (v.kind === "Some") {
3139
+ _setKey(result, k, v.value);
1331
3140
  }
1332
- const result = {};
1333
- for (let i = 0; i < keys2.length; i++) {
1334
- const k = keys2[i];
1335
- const [newKey, newVal] = f(k, data[k]);
1336
- _setKey(result, newKey, newVal);
3141
+ }
3142
+ return result;
3143
+ };
3144
+ var mapEntries2 = (f) => (data) => {
3145
+ const recKeys = Object.keys(data);
3146
+ if (recKeys.length === 0) {
3147
+ return {};
3148
+ }
3149
+ const result = {};
3150
+ for (let i = 0; i < recKeys.length; i++) {
3151
+ const k = recKeys[i];
3152
+ const [newKey, newVal] = f(k, data[k]);
3153
+ _setKey(result, newKey, newVal);
3154
+ }
3155
+ return result;
3156
+ };
3157
+ var updateIn = (path, f) => (data) => {
3158
+ const updateNode = (obj, pathKeys) => {
3159
+ const [head2, ...tail2] = pathKeys;
3160
+ if (tail2.length === 0) {
3161
+ return { ...obj, [head2]: f(obj?.[head2]) };
1337
3162
  }
1338
- return result;
3163
+ const child = obj && typeof obj === "object" && head2 in obj ? obj[head2] : {};
3164
+ return { ...obj, [head2]: updateNode(child, tail2) };
1339
3165
  };
1340
- Rec2.updateIn = (path, f) => (data) => {
1341
- const updateNode = (obj, keys2) => {
1342
- const [head, ...tail] = keys2;
1343
- if (tail.length === 0) {
1344
- return { ...obj, [head]: f(obj?.[head]) };
1345
- }
1346
- const child = obj && typeof obj === "object" && head in obj ? obj[head] : {};
1347
- return { ...obj, [head]: updateNode(child, tail) };
1348
- };
1349
- return updateNode(data, path);
1350
- };
1351
- let traverse;
1352
- ((traverse2) => {
1353
- traverse2.Maybe = RecMaybe.traverse;
1354
- traverse2.Result = RecResult.traverse;
1355
- })(traverse = Rec2.traverse || (Rec2.traverse = {}));
1356
- let sequence;
1357
- ((sequence2) => {
1358
- sequence2.Maybe = RecMaybe.sequence;
1359
- sequence2.Result = RecResult.sequence;
1360
- })(sequence = Rec2.sequence || (Rec2.sequence = {}));
1361
- Rec2.NonEmpty = RecNonEmpty;
1362
- })(Rec || (Rec = {}));
3166
+ return updateNode(data, path);
3167
+ };
3168
+ var RecTo = {
3169
+ Dict: (data) => new globalThis.Map(Object.entries(data))
3170
+ };
3171
+ var RecNonEmpty = {
3172
+ singleton: (key, value) => ({ [key]: value }),
3173
+ from: {
3174
+ Record: (data) => _isNonEmpty(data) ? Maybe.make.some(data) : Maybe.make.none()
3175
+ },
3176
+ keys: (data) => keys2(data),
3177
+ values: (data) => values2(data),
3178
+ entries: (data) => entries2(data),
3179
+ reduce: (f) => (data) => values2(data).reduce(f),
3180
+ map: (f) => (data) => map3(f)(data),
3181
+ mapWithKey: (f) => (data) => mapWithKey2(f)(data)
3182
+ };
3183
+ var Rec = {
3184
+ is: RecIs,
3185
+ from: RecFrom,
3186
+ to: RecTo,
3187
+ map: map3,
3188
+ filterMap: filterMap3,
3189
+ mapWithKey: mapWithKey2,
3190
+ filter: filter3,
3191
+ filterWithKey: filterWithKey2,
3192
+ lookup: lookup2,
3193
+ keys: keys2,
3194
+ values: values2,
3195
+ entries: entries2,
3196
+ groupBy: groupBy3,
3197
+ pick,
3198
+ omit,
3199
+ merge,
3200
+ mergeWith: mergeWith2,
3201
+ size: size3,
3202
+ mapKeys: mapKeys2,
3203
+ compact: compact3,
3204
+ mapEntries: mapEntries2,
3205
+ updateIn,
3206
+ traverse: { Maybe: RecMaybe.traverse, Result: RecResult.traverse },
3207
+ sequence: { Maybe: RecMaybe.sequence, Result: RecResult.sequence },
3208
+ NonEmpty: RecNonEmpty
3209
+ };
1363
3210
 
1364
3211
  // src/Data/Str.ts
1365
- var StrNonEmpty;
1366
- ((StrNonEmpty2) => {
1367
- let from;
1368
- ((from2) => {
1369
- from2.String = (s) => s.length > 0 ? Maybe.make.some(s) : Maybe.make.none();
1370
- })(from = StrNonEmpty2.from || (StrNonEmpty2.from = {}));
1371
- })(StrNonEmpty || (StrNonEmpty = {}));
1372
- var Str;
1373
- ((Str2) => {
1374
- let is;
1375
- ((is2) => {
1376
- is2.empty = (s) => s.length === 0;
1377
- is2.nonEmpty = (s) => s.length > 0;
1378
- })(is = Str2.is || (Str2.is = {}));
1379
- Str2.split = (separator) => (s) => s.split(separator);
1380
- Str2.trim = (s) => s.trim();
1381
- Str2.includes = (substring) => (s) => s.includes(substring);
1382
- Str2.replace = (pattern, replacement) => (s) => s.replace(pattern, replacement);
1383
- Str2.replaceAll = (pattern, replacement) => (s) => s.replaceAll(pattern, replacement);
1384
- Str2.startsWith = (prefix) => (s) => s.startsWith(prefix);
1385
- Str2.endsWith = (suffix) => (s) => s.endsWith(suffix);
1386
- Str2.toUpperCase = (s) => s.toUpperCase();
1387
- Str2.toLowerCase = (s) => s.toLowerCase();
1388
- Str2.capitalize = (s) => s.length === 0 ? "" : s.charAt(0).toUpperCase() + s.slice(1);
1389
- Str2.lines = (s) => s.split(/\r?\n|\r/);
1390
- Str2.words = (s) => s.trim().split(/\s+/).filter(Boolean);
1391
- Str2.isBlank = (s) => s.trim().length === 0;
1392
- Str2.length = (s) => s.length;
1393
- Str2.slice = (start, end) => (s) => s.slice(start, end);
1394
- Str2.padStart = (maxLength, fillString) => (s) => s.padStart(maxLength, fillString);
1395
- Str2.padEnd = (maxLength, fillString) => (s) => s.padEnd(maxLength, fillString);
1396
- Str2.parse = {
3212
+ var StrNonEmptyConst = {
3213
+ // --- from ---
3214
+ from: {
3215
+ /**
3216
+ * Returns Some containing NonEmptyString if the string is not empty, None otherwise.
3217
+ *
3218
+ * @example
3219
+ * ```ts
3220
+ * Str.NonEmpty.from.String("hello"); // Some("hello")
3221
+ * Str.NonEmpty.from.String(""); // None
3222
+ * ```
3223
+ */
3224
+ String: (s) => s.length > 0 ? Maybe.make.some(s) : Maybe.make.none()
3225
+ }
3226
+ };
3227
+ var isEmpty = (s) => s.length === 0;
3228
+ var isNonEmpty = (s) => s.length > 0;
3229
+ var Str = {
3230
+ is: {
3231
+ /**
3232
+ * Returns `true` when the string is empty.
3233
+ *
3234
+ * @example
3235
+ * ```ts
3236
+ * pipe("", Str.is.empty); // true
3237
+ * pipe("hi", Str.is.empty); // false
3238
+ * ```
3239
+ */
3240
+ empty: isEmpty,
3241
+ /**
3242
+ * Type guard to check if a string is non-empty.
3243
+ */
3244
+ nonEmpty: isNonEmpty
3245
+ },
3246
+ /**
3247
+ * Splits a string by a separator. Data-last: use in `pipe`.
3248
+ *
3249
+ * @example
3250
+ * ```ts
3251
+ * pipe("a,b,c", Str.split(",")); // ["a", "b", "c"]
3252
+ * ```
3253
+ */
3254
+ split: (separator) => (s) => s.split(separator),
3255
+ /**
3256
+ * Removes leading and trailing whitespace from a string.
3257
+ *
3258
+ * @example
3259
+ * ```ts
3260
+ * pipe(" hello ", Str.trim); // "hello"
3261
+ * ```
3262
+ */
3263
+ trim: (s) => s.trim(),
3264
+ /**
3265
+ * Returns `true` when the string contains the given substring.
3266
+ *
3267
+ * @example
3268
+ * ```ts
3269
+ * pipe("hello world", Str.includes("world")); // true
3270
+ * pipe("hello world", Str.includes("xyz")); // false
3271
+ * ```
3272
+ */
3273
+ includes: (substring) => (s) => s.includes(substring),
3274
+ /**
3275
+ * Replaces the first occurrence of a pattern in a string. Data-last: use in `pipe`.
3276
+ *
3277
+ * @example
3278
+ * ```ts
3279
+ * pipe("foo foo foo", Str.replace("foo", "bar")); // "bar foo foo"
3280
+ * pipe("Hello World", Str.replace(/world/i, "Earth")); // "Hello Earth"
3281
+ * ```
3282
+ */
3283
+ replace: (pattern, replacement) => (s) => s.replace(pattern, replacement),
3284
+ /**
3285
+ * Replaces all occurrences of a pattern in a string. Data-last: use in `pipe`.
3286
+ *
3287
+ * @example
3288
+ * ```ts
3289
+ * pipe("foo foo foo", Str.replaceAll("foo", "bar")); // "bar bar bar"
3290
+ * pipe("aAbBaA", Str.replaceAll(/a/gi, "x")); // "xxBBxx"
3291
+ * ```
3292
+ */
3293
+ replaceAll: (pattern, replacement) => (s) => s.replaceAll(pattern, replacement),
3294
+ /**
3295
+ * Returns `true` when the string starts with the given prefix.
3296
+ *
3297
+ * @example
3298
+ * ```ts
3299
+ * pipe("hello world", Str.startsWith("hello")); // true
3300
+ * pipe("hello world", Str.startsWith("world")); // false
3301
+ * ```
3302
+ */
3303
+ startsWith: (prefix) => (s) => s.startsWith(prefix),
3304
+ /**
3305
+ * Returns `true` when the string ends with the given suffix.
3306
+ *
3307
+ * @example
3308
+ * ```ts
3309
+ * pipe("hello world", Str.endsWith("world")); // true
3310
+ * pipe("hello world", Str.endsWith("hello")); // false
3311
+ * ```
3312
+ */
3313
+ endsWith: (suffix) => (s) => s.endsWith(suffix),
3314
+ /**
3315
+ * Converts a string to uppercase.
3316
+ *
3317
+ * @example
3318
+ * ```ts
3319
+ * pipe("hello", Str.toUpperCase); // "HELLO"
3320
+ * ```
3321
+ */
3322
+ toUpperCase: (s) => s.toUpperCase(),
3323
+ /**
3324
+ * Converts a string to lowercase.
3325
+ *
3326
+ * @example
3327
+ * ```ts
3328
+ * pipe("HELLO", Str.toLowerCase); // "hello"
3329
+ * ```
3330
+ */
3331
+ toLowerCase: (s) => s.toLowerCase(),
3332
+ /**
3333
+ * Converts the first character of a string to uppercase.
3334
+ *
3335
+ * @example
3336
+ * ```ts
3337
+ * pipe("hello", Str.capitalize); // "Hello"
3338
+ * ```
3339
+ */
3340
+ capitalize: (s) => s.length === 0 ? "" : s.charAt(0).toUpperCase() + s.slice(1),
3341
+ /**
3342
+ * Splits a string into lines, normalising `\r\n` and `\r` line endings.
3343
+ *
3344
+ * @example
3345
+ * ```ts
3346
+ * Str.lines("one\ntwo\nthree"); // ["one", "two", "three"]
3347
+ * Str.lines("a\r\nb"); // ["a", "b"]
3348
+ * ```
3349
+ */
3350
+ lines: (s) => s.split(/\r?\n|\r/),
3351
+ /**
3352
+ * Splits a string into words on any whitespace boundary, filtering out empty strings.
3353
+ *
3354
+ * @example
3355
+ * ```ts
3356
+ * Str.words(" hello world "); // ["hello", "world"]
3357
+ * ```
3358
+ */
3359
+ words: (s) => s.trim().split(/\s+/).filter(Boolean),
3360
+ /**
3361
+ * Returns `true` when the string is empty or contains only whitespace.
3362
+ *
3363
+ * @example
3364
+ * ```ts
3365
+ * pipe(" ", Str.isBlank); // true
3366
+ * pipe("hi", Str.isBlank); // false
3367
+ * ```
3368
+ */
3369
+ isBlank: (s) => s.trim().length === 0,
3370
+ /**
3371
+ * Returns the length of the string.
3372
+ *
3373
+ * @example
3374
+ * ```ts
3375
+ * pipe("hello", Str.length); // 5
3376
+ * pipe("", Str.length); // 0
3377
+ * ```
3378
+ */
3379
+ length: (s) => s.length,
3380
+ /**
3381
+ * Extracts a substring between two indices. Data-last: use in `pipe`.
3382
+ *
3383
+ * @example
3384
+ * ```ts
3385
+ * pipe("hello", Str.slice(1, 3)); // "el"
3386
+ * pipe("hello", Str.slice(2)); // "llo"
3387
+ * ```
3388
+ */
3389
+ slice: (start, end) => (s) => s.slice(start, end),
3390
+ /**
3391
+ * Pads the start of a string to a specified length. Data-last: use in `pipe`.
3392
+ *
3393
+ * @example
3394
+ * ```ts
3395
+ * pipe("5", Str.padStart(3, "0")); // "005"
3396
+ * pipe("hi", Str.padStart(5)); // " hi"
3397
+ * ```
3398
+ */
3399
+ padStart: (maxLength, fillString) => (s) => s.padStart(maxLength, fillString),
3400
+ /**
3401
+ * Pads the end of a string to a specified length. Data-last: use in `pipe`.
3402
+ *
3403
+ * @example
3404
+ * ```ts
3405
+ * pipe("hi", Str.padEnd(5, ".")); // "hi..."
3406
+ * pipe("hi", Str.padEnd(5)); // "hi "
3407
+ * ```
3408
+ */
3409
+ padEnd: (maxLength, fillString) => (s) => s.padEnd(maxLength, fillString),
3410
+ /**
3411
+ * Safe number parsers that return `Maybe` instead of `NaN`.
3412
+ */
3413
+ parse: {
1397
3414
  /**
1398
3415
  * Parses a string as an integer (base 10). Returns `None` if the result is `NaN`.
1399
3416
  *
@@ -1428,16 +3445,45 @@ var Str;
1428
3445
  const n = Number.parseFloat(s);
1429
3446
  return Number.isNaN(n) ? Maybe.make.none() : Maybe.make.some(n);
1430
3447
  }
1431
- };
1432
- Str2.parseJson = (s) => {
3448
+ },
3449
+ /**
3450
+ * Safely parses a JSON string, returning a `Result<SyntaxError, unknown>`.
3451
+ *
3452
+ * @example
3453
+ * ```ts
3454
+ * Str.parseJson('{"a": 1}'); // Ok({ a: 1 })
3455
+ * Str.parseJson('invalid'); // Err(SyntaxError)
3456
+ * ```
3457
+ */
3458
+ parseJson: (s) => {
1433
3459
  try {
1434
3460
  return Result.make.ok(JSON.parse(s));
1435
3461
  } catch (error) {
1436
3462
  return Result.make.err(error);
1437
3463
  }
1438
- };
1439
- Str2.uncapitalize = (s) => s.length === 0 ? "" : s.charAt(0).toLowerCase() + s.slice(1);
1440
- Str2.truncate = (options) => (s) => {
3464
+ },
3465
+ /**
3466
+ * Converts the first character of a string to lower case.
3467
+ *
3468
+ * @example
3469
+ * ```ts
3470
+ * Str.uncapitalize("Hello"); // "hello"
3471
+ * Str.uncapitalize(""); // ""
3472
+ * ```
3473
+ */
3474
+ uncapitalize: (s) => s.length === 0 ? "" : s.charAt(0).toLowerCase() + s.slice(1),
3475
+ /**
3476
+ * Truncates a string to a maximum length, appending an optional suffix (default `"..."`).
3477
+ * Data-last curried signature.
3478
+ *
3479
+ * @example
3480
+ * ```ts
3481
+ * pipe("Hello, world!", Str.truncate({ length: 8 })); // "Hello..."
3482
+ * pipe("Hello", Str.truncate({ length: 10 })); // "Hello"
3483
+ * pipe("Hello, world!", Str.truncate({ length: 8, suffix: "…" })); // "Hello, w…"
3484
+ * ```
3485
+ */
3486
+ truncate: (options) => (s) => {
1441
3487
  const { length: targetLength, suffix = "..." } = options;
1442
3488
  if (s.length <= targetLength) {
1443
3489
  return s;
@@ -1446,137 +3492,161 @@ var Str;
1446
3492
  return suffix.slice(0, targetLength);
1447
3493
  }
1448
3494
  return s.slice(0, targetLength - suffix.length) + suffix;
1449
- };
1450
- Str2.NonEmpty = StrNonEmpty;
1451
- })(Str || (Str = {}));
3495
+ },
3496
+ NonEmpty: StrNonEmptyConst
3497
+ };
1452
3498
 
1453
3499
  // src/Data/Uniq.ts
1454
- var UniqNonEmpty;
1455
- ((UniqNonEmpty2) => {
1456
- UniqNonEmpty2.singleton = (item) => new globalThis.Set([item]);
1457
- let from;
1458
- ((from2) => {
1459
- from2.Set = (s) => s.size > 0 ? Maybe.make.some(s) : Maybe.make.none();
1460
- })(from = UniqNonEmpty2.from || (UniqNonEmpty2.from = {}));
1461
- UniqNonEmpty2.reduce = (f) => (s) => to.Array(s).reduce(f);
1462
- UniqNonEmpty2.map = (f) => (s) => Uniq.map(f)(s);
1463
- let to;
1464
- ((to2) => {
1465
- to2.Array = (s) => Uniq.to.Array(s);
1466
- })(to = UniqNonEmpty2.to || (UniqNonEmpty2.to = {}));
1467
- })(UniqNonEmpty || (UniqNonEmpty = {}));
1468
- var Uniq;
1469
- ((Uniq2) => {
1470
- let is;
1471
- ((is2) => {
1472
- is2.empty = (s) => s.size === 0;
1473
- is2.nonEmpty = (s) => s.size > 0;
1474
- })(is = Uniq2.is || (Uniq2.is = {}));
1475
- Uniq2.empty = () => new globalThis.Set();
1476
- Uniq2.singleton = (item) => new globalThis.Set([item]);
1477
- let from;
1478
- ((from2) => {
1479
- from2.Array = (arr) => new globalThis.Set(arr);
1480
- })(from = Uniq2.from || (Uniq2.from = {}));
1481
- Uniq2.has = (item) => (s) => s.has(item);
1482
- Uniq2.size = (s) => s.size;
1483
- Uniq2.isSubsetOf = (other) => (s) => {
1484
- const set = s;
1485
- if (typeof set.isSubsetOf === "function") {
1486
- return set.isSubsetOf(other);
1487
- }
1488
- for (const item of s) {
1489
- if (!other.has(item)) {
1490
- return false;
1491
- }
1492
- }
1493
- return true;
1494
- };
1495
- Uniq2.insert = (item) => (s) => {
1496
- if (s.has(item)) {
1497
- return s;
1498
- }
1499
- const result = new globalThis.Set(s);
1500
- result.add(item);
1501
- return result;
1502
- };
1503
- Uniq2.remove = (item) => (s) => {
1504
- if (!s.has(item)) {
1505
- return s;
1506
- }
1507
- const result = new globalThis.Set(s);
3500
+ var isEmpty2 = (s) => s.size === 0;
3501
+ var isNonEmpty2 = (s) => s.size > 0;
3502
+ var empty2 = () => new globalThis.Set();
3503
+ var singleton2 = (item) => new globalThis.Set([item]);
3504
+ var fromArray = (arr) => new globalThis.Set(arr);
3505
+ var has2 = (item) => (s) => s.has(item);
3506
+ var size4 = (s) => s.size;
3507
+ var add = (item) => (s) => {
3508
+ if (s.has(item)) {
3509
+ return s;
3510
+ }
3511
+ const result = new globalThis.Set(s);
3512
+ result.add(item);
3513
+ return result;
3514
+ };
3515
+ var remove2 = (item) => (s) => {
3516
+ if (!s.has(item)) {
3517
+ return s;
3518
+ }
3519
+ const result = new globalThis.Set(s);
3520
+ result.delete(item);
3521
+ return result;
3522
+ };
3523
+ var toggle = (item) => (s) => {
3524
+ const result = new globalThis.Set(s);
3525
+ if (result.has(item)) {
1508
3526
  result.delete(item);
1509
- return result;
1510
- };
1511
- Uniq2.map = (f) => (s) => {
1512
- const result = new globalThis.Set();
1513
- for (const item of s) {
1514
- result.add(f(item));
1515
- }
1516
- return result;
1517
- };
1518
- Uniq2.filter = (predicate) => (s) => {
1519
- const result = new globalThis.Set();
1520
- for (const item of s) {
1521
- if (predicate(item)) {
1522
- result.add(item);
1523
- }
3527
+ } else {
3528
+ result.add(item);
3529
+ }
3530
+ return result;
3531
+ };
3532
+ var map4 = (f) => (s) => {
3533
+ const result = new globalThis.Set();
3534
+ for (const item of s) {
3535
+ result.add(f(item));
3536
+ }
3537
+ return result;
3538
+ };
3539
+ var filter4 = (predicate) => (s) => {
3540
+ const result = new globalThis.Set();
3541
+ for (const item of s) {
3542
+ if (predicate(item)) {
3543
+ result.add(item);
1524
3544
  }
1525
- return result;
1526
- };
1527
- Uniq2.union = (other) => (s) => {
1528
- const set = s;
1529
- if (typeof set.union === "function") {
1530
- return set.union(other);
3545
+ }
3546
+ return result;
3547
+ };
3548
+ var filterMap4 = (f) => (s) => {
3549
+ const result = new globalThis.Set();
3550
+ for (const item of s) {
3551
+ const mb = f(item);
3552
+ if (mb.kind === "Some") {
3553
+ result.add(mb.value);
1531
3554
  }
1532
- const result = new globalThis.Set(s);
1533
- for (const item of other) {
3555
+ }
3556
+ return result;
3557
+ };
3558
+ var union2 = (other) => (s) => {
3559
+ const set = s;
3560
+ if (typeof set.union === "function") {
3561
+ return set.union(other);
3562
+ }
3563
+ const result = new globalThis.Set(s);
3564
+ for (const item of other) {
3565
+ result.add(item);
3566
+ }
3567
+ return result;
3568
+ };
3569
+ var intersection2 = (other) => (s) => {
3570
+ const set = s;
3571
+ if (typeof set.intersection === "function") {
3572
+ return set.intersection(other);
3573
+ }
3574
+ const result = new globalThis.Set();
3575
+ for (const item of s) {
3576
+ if (other.has(item)) {
1534
3577
  result.add(item);
1535
3578
  }
1536
- return result;
1537
- };
1538
- Uniq2.intersection = (other) => (s) => {
1539
- const set = s;
1540
- if (typeof set.intersection === "function") {
1541
- return set.intersection(other);
1542
- }
1543
- const result = new globalThis.Set();
1544
- for (const item of s) {
1545
- if (other.has(item)) {
1546
- result.add(item);
1547
- }
1548
- }
1549
- return result;
1550
- };
1551
- Uniq2.difference = (other) => (s) => {
1552
- const set = s;
1553
- if (typeof set.difference === "function") {
1554
- return set.difference(other);
1555
- }
1556
- const result = new globalThis.Set();
1557
- for (const item of s) {
1558
- if (!other.has(item)) {
1559
- result.add(item);
1560
- }
3579
+ }
3580
+ return result;
3581
+ };
3582
+ var difference2 = (other) => (s) => {
3583
+ const set = s;
3584
+ if (typeof set.difference === "function") {
3585
+ return set.difference(other);
3586
+ }
3587
+ const result = new globalThis.Set();
3588
+ for (const item of s) {
3589
+ if (!other.has(item)) {
3590
+ result.add(item);
1561
3591
  }
1562
- return result;
1563
- };
1564
- Uniq2.reduce = (init, f) => (s) => {
1565
- let acc = init;
1566
- for (const item of s) {
1567
- acc = f(acc, item);
3592
+ }
3593
+ return result;
3594
+ };
3595
+ var isSubsetOf = (other) => (s) => {
3596
+ const set = s;
3597
+ if (typeof set.isSubsetOf === "function") {
3598
+ return set.isSubsetOf(other);
3599
+ }
3600
+ for (const item of s) {
3601
+ if (!other.has(item)) {
3602
+ return false;
1568
3603
  }
1569
- return acc;
1570
- };
1571
- let to;
1572
- ((to2) => {
1573
- to2.Array = (s) => [...s];
1574
- })(to = Uniq2.to || (Uniq2.to = {}));
1575
- Uniq2.NonEmpty = UniqNonEmpty;
1576
- })(Uniq || (Uniq = {}));
3604
+ }
3605
+ return true;
3606
+ };
3607
+ var reduce3 = (init2, f) => (s) => {
3608
+ let acc = init2;
3609
+ for (const item of s) {
3610
+ acc = f(acc, item);
3611
+ }
3612
+ return acc;
3613
+ };
3614
+ var toArray = (s) => [...s];
3615
+ var UniqNonEmptyConst = {
3616
+ singleton: (item) => new globalThis.Set([item]),
3617
+ from: {
3618
+ Set: (s) => s.size > 0 ? Maybe.make.some(s) : Maybe.make.none()
3619
+ },
3620
+ reduce: (f) => (s) => toArray(s).reduce(f),
3621
+ map: (f) => (s) => map4(f)(s),
3622
+ to: { Array: (s) => toArray(s) }
3623
+ };
3624
+ var Uniq = {
3625
+ is: { empty: isEmpty2, nonEmpty: isNonEmpty2 },
3626
+ empty: empty2,
3627
+ singleton: singleton2,
3628
+ from: { Array: fromArray },
3629
+ has: has2,
3630
+ size: size4,
3631
+ add,
3632
+ insert: add,
3633
+ remove: remove2,
3634
+ toggle,
3635
+ map: map4,
3636
+ filter: filter4,
3637
+ filterMap: filterMap4,
3638
+ union: union2,
3639
+ intersection: intersection2,
3640
+ difference: difference2,
3641
+ isSubsetOf,
3642
+ reduce: reduce3,
3643
+ to: { Array: toArray },
3644
+ NonEmpty: UniqNonEmptyConst
3645
+ };
1577
3646
  export {
1578
3647
  Arr,
1579
3648
  BigNum,
3649
+ Bool,
1580
3650
  Dict,
1581
3651
  Json,
1582
3652
  Num,