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