@nlozgachev/pipelined 0.64.0 → 0.66.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.
@@ -0,0 +1,4420 @@
1
+ import { n as Duration, t as RetryPolicy } from "./index-Bs8En5LJ.cjs";
2
+ import { _ as WithSecond, a as Thenable, b as WithValue, c as WithCooldown, d as WithErrors, f as WithFirst, g as WithN, h as WithMinInterval, i as RetryOptions, l as WithDuration, m as WithLog, o as TimeoutOptions, p as WithKind, r as NonEmptyArr, s as WithConcurrency, u as WithError, v as WithSize, x as Deferred, y as WithTimeout } from "./InternalTypes-B1Lh9uw_.cjs";
3
+ //#region src/Core/Combinable.d.ts
4
+ /**
5
+ * A type that can combine two values of type `A` into one, with a neutral starting value.
6
+ * `empty` is the identity: `combine(empty)(a) === a` and `combine(a)(empty) === a`.
7
+ * `combine(b)(a)` appends `b` onto `a` — `a` is the accumulated value, `b` is the new element.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * pipe(["hello", ", ", "world"], Combinable.fold(Combinable.string)); // "hello, world"
12
+ * pipe([1, 2, 3, 4, 5], Combinable.fold(Combinable.sum)); // 15
13
+ * ```
14
+ */
15
+ type Combinable<A> = {
16
+ readonly empty: A;
17
+ readonly combine: (b: A) => (a: A) => A;
18
+ };
19
+ declare const Combinable: {
20
+ /**
21
+ * Combines strings by concatenation. Empty string is the neutral element.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * pipe(["a", "b", "c"], Combinable.fold(Combinable.string)); // "abc"
26
+ * ```
27
+ */
28
+ string: Combinable<string>;
29
+ /**
30
+ * Combines numbers by addition. `0` is the neutral element.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * pipe([1, 2, 3], Combinable.fold(Combinable.sum)); // 6
35
+ * ```
36
+ */
37
+ sum: Combinable<number>;
38
+ /**
39
+ * Combines numbers by multiplication. `1` is the neutral element.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * pipe([2, 3, 4], Combinable.fold(Combinable.product)); // 24
44
+ * ```
45
+ */
46
+ product: Combinable<number>;
47
+ /**
48
+ * Combines booleans with logical AND. `true` is the neutral element.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * pipe([true, true, false], Combinable.fold(Combinable.all)); // false
53
+ * ```
54
+ */
55
+ all: Combinable<boolean>;
56
+ /**
57
+ * Combines booleans with logical OR. `false` is the neutral element.
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * pipe([false, false, true], Combinable.fold(Combinable.any)); // true
62
+ * ```
63
+ */
64
+ any: Combinable<boolean>;
65
+ /**
66
+ * Combines arrays by concatenation. Empty array is the neutral element.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * pipe([[1, 2], [3], [4, 5]], Combinable.fold(Combinable.array<number>())); // [1, 2, 3, 4, 5]
71
+ * ```
72
+ */
73
+ array: <A>() => Combinable<readonly A[]>;
74
+ /**
75
+ * Lifts a `Combinable<A>` to `Combinable<Maybe<A>>`. `None` is the neutral element —
76
+ * combining with `None` on either side returns the other value unchanged.
77
+ * Two `Some` values combine their inner values using the inner `Combinable`.
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * const c = Combinable.maybe(Combinable.sum);
82
+ * c.combine(Maybe.make.some(3))(Maybe.make.some(2)); // Some(5)
83
+ * c.combine(Maybe.make.none())(Maybe.make.some(5)); // Some(5)
84
+ * ```
85
+ */
86
+ maybe: <A>(inner: Combinable<A>) => Combinable<Maybe<A>>;
87
+ /**
88
+ * Folds an array into a single value using the `Combinable`'s `empty` as the starting point.
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * pipe([1, 2, 3, 4, 5], Combinable.fold(Combinable.sum)); // 15
93
+ * pipe([], Combinable.fold(Combinable.sum)); // 0
94
+ * ```
95
+ */
96
+ fold: <A>(c: Combinable<A>) => (data: readonly A[]) => A;
97
+ /**
98
+ * Derives a `Combinable` for a record of fields from field-level `Combinable` instances.
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * const StatsCombinable = Combinable.struct({
103
+ * count: Combinable.sum,
104
+ * tags: Combinable.array<string>(),
105
+ * });
106
+ * ```
107
+ */
108
+ struct: <R extends Record<string, unknown>>(fields: { [K in keyof R]: Combinable<R[K]>; }) => Combinable<R>;
109
+ };
110
+ //#endregion
111
+ //#region src/Core/Equality.d.ts
112
+ /**
113
+ * A function that checks whether two values of type `A` are equal.
114
+ * Use built-in instances (`Equality.string`, `Equality.number`, etc.) as starting points,
115
+ * then adapt them with `Equality.by` and combine them with `Equality.and`.
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * type User = { id: string; name: string };
120
+ * const byId = pipe(Equality.string, Equality.by((u: User) => u.id));
121
+ *
122
+ * pipe(users, Arr.uniqWith(byId));
123
+ * ```
124
+ */
125
+ type Equality<A> = (a: A, b: A) => boolean;
126
+ declare const Equality: {
127
+ /**
128
+ * Equality for strings. Case-sensitive.
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * Equality.string("hello", "hello"); // true
133
+ * Equality.string("hello", "Hello"); // false
134
+ * ```
135
+ */
136
+ string: Equality<string>;
137
+ /**
138
+ * Equality for numbers. Uses strict equality.
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * Equality.number(42, 42); // true
143
+ * ```
144
+ */
145
+ number: Equality<number>;
146
+ /**
147
+ * Equality for booleans.
148
+ *
149
+ * @example
150
+ * ```ts
151
+ * Equality.boolean(true, true); // true
152
+ * ```
153
+ */
154
+ boolean: Equality<boolean>;
155
+ /**
156
+ * Equality for `Date` values. Compares by numeric time value.
157
+ *
158
+ * @example
159
+ * ```ts
160
+ * Equality.date(new Date("2024-01-01"), new Date("2024-01-01")); // true
161
+ * ```
162
+ */
163
+ date: Equality<Date>;
164
+ /**
165
+ * Lifts an element equality into an array equality. Two arrays are equal if they have the
166
+ * same length and every element pair is equal under `eq`.
167
+ *
168
+ * @example
169
+ * ```ts
170
+ * Equality.array(Equality.number)([1, 2, 3], [1, 2, 3]); // true
171
+ * ```
172
+ */
173
+ array: <A>(eq: Equality<A>) => Equality<readonly A[]>;
174
+ /**
175
+ * Adapts an equality for type `A` into an equality for type `B` by extracting a field.
176
+ * Read as "equality by this field": `pipe(Equality.string, Equality.by(u => u.name))`.
177
+ *
178
+ * @example
179
+ * ```ts
180
+ * type Product = { id: string; price: number };
181
+ * const byId = pipe(Equality.string, Equality.by((p: Product) => p.id));
182
+ * byId({ id: "p1", price: 9 }, { id: "p1", price: 12 }); // true
183
+ * ```
184
+ */
185
+ by: <A, B>(f: (b: B) => A) => (eq: Equality<A>) => Equality<B>;
186
+ /**
187
+ * Combines two equalities with logical AND. Both must pass for two values to be considered equal.
188
+ * Data-last: the first equality is the data being piped.
189
+ *
190
+ * @example
191
+ * ```ts
192
+ * const exact = pipe(byName, Equality.and(byRole));
193
+ * exact(userA, userB); // true only if name AND role match
194
+ * ```
195
+ */
196
+ and: <A>(eq2: Equality<A>) => (eq1: Equality<A>) => Equality<A>;
197
+ /**
198
+ * Derives deep equality for a record from field-level `Equality` checkers.
199
+ *
200
+ * @example
201
+ * ```ts
202
+ * const userEq = Equality.struct({
203
+ * id: Equality.string,
204
+ * age: Equality.number,
205
+ * });
206
+ * ```
207
+ */
208
+ struct: <R extends Record<string, unknown>>(fields: { [K in keyof R]: Equality<R[K]>; }) => Equality<R>;
209
+ /**
210
+ * Derives element-wise equality for a tuple from positional `Equality` checkers.
211
+ *
212
+ * @example
213
+ * ```ts
214
+ * const pairEq = Equality.tuple(Equality.string, Equality.number);
215
+ * pairEq(["a", 1], ["a", 1]); // true
216
+ * ```
217
+ */
218
+ tuple: <T extends readonly unknown[]>(...equalities: { [K in keyof T]: Equality<T[K]>; }) => Equality<T>;
219
+ };
220
+ //#endregion
221
+ //#region src/Core/EventBus.d.ts
222
+ /**
223
+ * An event bus pipeline for a typed message schema `S`.
224
+ *
225
+ * `EventBus` provides typed event emission, sequence matching, state reduction,
226
+ * and structural event bus forwarding.
227
+ *
228
+ * @example
229
+ * ```ts
230
+ * type AppMessages = {
231
+ * userLoggedIn: { userId: string };
232
+ * checkoutStarted: { amount: number };
233
+ * };
234
+ *
235
+ * const appBus = EventBus.make<AppMessages>();
236
+ *
237
+ * const subscription = EventBus.listen(
238
+ * appBus,
239
+ * ["userLoggedIn", "checkoutStarted"],
240
+ * { ordered: true }
241
+ * ).reduce(
242
+ * (msg, state) => {
243
+ * if (msg.kind === "checkoutStarted") {
244
+ * return { count: state.count + 1 };
245
+ * }
246
+ * return state;
247
+ * },
248
+ * { count: 0 }
249
+ * );
250
+ *
251
+ * EventBus.emit(appBus, {
252
+ * kind: "userLoggedIn",
253
+ * value: { userId: "user-1" },
254
+ * });
255
+ * ```
256
+ */
257
+ type EventBus<S extends Record<string, unknown>> = {
258
+ readonly options?: EventBus.Options;
259
+ /** @internal */
260
+ readonly _listeners: Set<(msg: EventBus.Message<S>) => void>;
261
+ /**
262
+ * @internal
263
+ * Lazy array snapshot of `_listeners`. Avoids allocating new array objects on every `emit` call
264
+ * (2.98x emission speedup, 0 heap allocations). Rebuilt whenever `_listeners` is mutated,
265
+ * guaranteeing reentrancy safety and preventing listeners subscribed mid-emission from executing early.
266
+ */
267
+ _listenerArray: Array<(msg: EventBus.Message<S>) => void> | null;
268
+ /** @internal */
269
+ readonly _queue: Array<EventBus.Message<S>>;
270
+ /** @internal */
271
+ _isEmitting: boolean;
272
+ };
273
+ declare const EventBus: {
274
+ /**
275
+ * Constructs a new `EventBus` instance.
276
+ *
277
+ * @example
278
+ * ```ts
279
+ * const bus = EventBus.make<AppMessages>({ name: "app" });
280
+ * ```
281
+ */
282
+ make: <S extends Record<string, unknown>>(options?: EventBus.Options) => EventBus<S>;
283
+ /**
284
+ * Emits a message payload to one or more target event buses.
285
+ *
286
+ * Uses a synchronous breadth-first trampoline queue to handle re-entrant emissions deterministically.
287
+ *
288
+ * @example
289
+ * ```ts
290
+ * EventBus.emit(busA, {
291
+ * kind: "userLoggedIn",
292
+ * value: { userId: "user-1" },
293
+ * });
294
+ *
295
+ * EventBus.emit([busA, busB], {
296
+ * kind: "userLoggedIn",
297
+ * value: { userId: "user-1" },
298
+ * });
299
+ * ```
300
+ */
301
+ emit: <S extends Record<string, unknown>, K extends keyof S & string>(target: EventBus<S> | ReadonlyArray<EventBus<S>>, message: WithKind<K> & WithValue<S[K]>) => void;
302
+ /**
303
+ * Forwards messages from one event bus to another (or multiple).
304
+ *
305
+ * @example
306
+ * ```ts
307
+ * const stop = EventBus.forward({
308
+ * from: authBus,
309
+ * to: analyticsBus,
310
+ * only: ["userLoggedIn"],
311
+ * });
312
+ * ```
313
+ */
314
+ forward: <S extends Record<string, unknown>>(options: EventBus.ForwardOptions<S>) => () => void;
315
+ /**
316
+ * Initiates listener registration on an event bus for specific event kind(s) or sequence.
317
+ *
318
+ * @example
319
+ * ```ts
320
+ * const sub = EventBus.listen(
321
+ * appBus,
322
+ * ["userLoggedIn", "checkoutStarted"],
323
+ * { ordered: true }
324
+ * ).reduce(
325
+ * (msg, state) => ({ count: state.count + 1 }),
326
+ * { count: 0 }
327
+ * );
328
+ * ```
329
+ */
330
+ listen: <S extends Record<string, unknown>, K extends keyof S & string>(bus: EventBus<S>, events: K | ReadonlyArray<K>, options?: EventBus.SequenceOptions<S>) => EventBus.ListenerBuilder<S>;
331
+ };
332
+ declare namespace EventBus {
333
+ type Message<S extends Record<string, unknown>> = { [K in keyof S & string]: WithKind<K> & WithValue<S[K]>; }[keyof S & string];
334
+ type Options = {
335
+ readonly name?: string;
336
+ readonly onError?: (error: unknown) => void;
337
+ };
338
+ type SequenceOptions<S extends Record<string, unknown>> = {
339
+ readonly ordered?: boolean;
340
+ readonly strict?: boolean;
341
+ readonly once?: boolean;
342
+ readonly reset?: (keyof S & string) | ReadonlyArray<keyof S & string>;
343
+ readonly optional?: (keyof S & string) | ReadonlyArray<keyof S & string>;
344
+ };
345
+ type Subscription<State> = {
346
+ readonly unsubscribe: () => void;
347
+ readonly getState: () => State;
348
+ };
349
+ type ForwardOptions<S extends Record<string, unknown>> = {
350
+ readonly from: EventBus<S>;
351
+ readonly to: EventBus<S> | ReadonlyArray<EventBus<S>>;
352
+ readonly only?: ReadonlyArray<keyof S & string>;
353
+ };
354
+ type ListenerBuilder<S extends Record<string, unknown>> = {
355
+ readonly reduce: <State>(reducer: (msg: Message<S>, state: State) => State, initialState: State) => Subscription<State>;
356
+ readonly tap: (effect: (msg: Message<S>) => void) => () => void;
357
+ };
358
+ }
359
+ //#endregion
360
+ //#region src/Core/Lazy.d.ts
361
+ /**
362
+ * A synchronous memoized computation. The factory function runs exactly once —
363
+ * on the first call to `Lazy.evaluate` — and the result is cached for all subsequent calls.
364
+ *
365
+ * @example
366
+ * ```ts
367
+ * const config = Lazy.from(() => parseConfig(rawInput));
368
+ *
369
+ * pipe(
370
+ * config,
371
+ * Lazy.map(cfg => cfg.port),
372
+ * Lazy.evaluate,
373
+ * ); // parseConfig ran once; cfg.port returned
374
+ * ```
375
+ */
376
+ type Lazy<A> = {
377
+ readonly get: () => A;
378
+ };
379
+ declare const Lazy: {
380
+ /**
381
+ * Wraps a thunk in a `Lazy`. The thunk runs exactly once, on first `evaluate`.
382
+ *
383
+ * @example
384
+ * ```ts
385
+ * const expensive = Lazy.from(() => computeExpensiveValue(input));
386
+ * ```
387
+ */
388
+ from: <A>(f: () => A) => Lazy<A>;
389
+ /**
390
+ * Forces evaluation and returns the cached result. Safe to call multiple times.
391
+ *
392
+ * @example
393
+ * ```ts
394
+ * const value = Lazy.evaluate(Lazy.from(() => 42)); // 42
395
+ * ```
396
+ */
397
+ evaluate: <A>(lazy: Lazy<A>) => A;
398
+ /**
399
+ * Transforms the result of a `Lazy` without triggering evaluation.
400
+ *
401
+ * @example
402
+ * ```ts
403
+ * pipe(Lazy.from(() => loadConfig()), Lazy.map(cfg => cfg.port));
404
+ * ```
405
+ */
406
+ map: <A, B>(f: (a: A) => B) => (lazy: Lazy<A>) => Lazy<B>;
407
+ /**
408
+ * Chains a `Lazy`-returning transformation without triggering evaluation.
409
+ *
410
+ * @example
411
+ * ```ts
412
+ * pipe(
413
+ * Lazy.from(() => loadConfig()),
414
+ * Lazy.chain(cfg => Lazy.from(() => openConnection(cfg.dbUrl))),
415
+ * );
416
+ * ```
417
+ */
418
+ chain: <A, B>(f: (a: A) => Lazy<B>) => (lazy: Lazy<A>) => Lazy<B>;
419
+ /**
420
+ * Runs a side effect on the value without changing it. Fires once, on first `evaluate`.
421
+ *
422
+ * @example
423
+ * ```ts
424
+ * pipe(Lazy.from(() => compute()), Lazy.tap(v => console.log("computed:", v)));
425
+ * ```
426
+ */
427
+ tap: <A>(f: (a: A) => void) => (lazy: Lazy<A>) => Lazy<A>;
428
+ };
429
+ //#endregion
430
+ //#region src/Core/Lens.d.ts
431
+ /**
432
+ * Lens<S, A> focuses on a single value A inside a structure S, providing
433
+ * a composable way to read and immutably update nested data.
434
+ *
435
+ * A Lens always succeeds: the focused value is guaranteed to exist.
436
+ * For optional or indexed focuses, use Optional<S, A>.
437
+ *
438
+ * @example
439
+ * ```ts
440
+ * type Address = { city: string; zip: string };
441
+ * type User = { name: string; address: Address };
442
+ *
443
+ * const addressLens = Lens.from.property<User>()("address");
444
+ * const cityLens = Lens.from.property<Address>()("city");
445
+ * const userCityLens = pipe(addressLens, Lens.andThen(cityLens));
446
+ *
447
+ * pipe(user, Lens.get(userCityLens)); // "Berlin"
448
+ * pipe(user, Lens.set(userCityLens)("Hamburg")); // new User with city updated
449
+ * pipe(user, Lens.modify(userCityLens)(c => c.toUpperCase())); // "BERLIN"
450
+ * ```
451
+ */
452
+ type Lens<S, A> = {
453
+ readonly get: (s: S) => A;
454
+ readonly set: (a: A) => (s: S) => S;
455
+ };
456
+ declare const Lens: {
457
+ from: {
458
+ /**
459
+ * Constructs a Lens from a getter and a setter.
460
+ *
461
+ * @example
462
+ * ```ts
463
+ * const nameLens = Lens.from.accessors(
464
+ * (user: User) => user.name,
465
+ * (name) => (user) => ({ ...user, name }),
466
+ * );
467
+ * ```
468
+ */
469
+ accessors: <S, A>(get: (s: S) => A, set: (a: A) => (s: S) => S) => Lens<S, A>;
470
+ /**
471
+ * Creates a Lens that focuses on a property of an object.
472
+ * Call with the structure type first, then the key.
473
+ *
474
+ * @example
475
+ * ```ts
476
+ * const nameLens = Lens.from.property<User>()("name");
477
+ * ```
478
+ */
479
+ property: <S>() => <K extends keyof S>(key: K) => Lens<S, S[K]>;
480
+ };
481
+ /**
482
+ * Reads the focused value from a structure.
483
+ *
484
+ * @example
485
+ * ```ts
486
+ * pipe(user, Lens.get(nameLens)); // "Alice"
487
+ * ```
488
+ */
489
+ get: <S, A>(lens: Lens<S, A>) => (s: S) => A;
490
+ /**
491
+ * Replaces the focused value within a structure, returning a new structure.
492
+ *
493
+ * @example
494
+ * ```ts
495
+ * pipe(user, Lens.set(nameLens)("Bob")); // new User with name "Bob"
496
+ * ```
497
+ */
498
+ set: <S, A>(lens: Lens<S, A>) => (a: A) => (s: S) => S;
499
+ /**
500
+ * Applies a function to the focused value, returning a new structure.
501
+ *
502
+ * @example
503
+ * ```ts
504
+ * pipe(user, Lens.modify(nameLens)(n => n.toUpperCase())); // "ALICE"
505
+ * ```
506
+ */
507
+ modify: <S, A>(lens: Lens<S, A>) => (f: (a: A) => A) => (s: S) => S;
508
+ /**
509
+ * Composes two Lenses: focuses through the outer, then through the inner.
510
+ * Use in a pipe chain to build up a deep focus step by step.
511
+ *
512
+ * @example
513
+ * ```ts
514
+ * const userCityLens = pipe(
515
+ * Lens.from.property<User>()("address"),
516
+ * Lens.andThen(Lens.from.property<Address>()("city")),
517
+ * );
518
+ * ```
519
+ */
520
+ andThen: <A, B>(inner: Lens<A, B>) => <S>(outer: Lens<S, A>) => Lens<S, B>;
521
+ /**
522
+ * Composes a Lens with an Optional, producing an Optional.
523
+ * Use when the next step in the focus is optional (may be absent).
524
+ *
525
+ * @example
526
+ * ```ts
527
+ * const userBioOpt = pipe(
528
+ * Lens.from.property<User>()("profile"),
529
+ * Lens.andThenOptional(Optional.from.property<Profile>()("bio")),
530
+ * );
531
+ * ```
532
+ */
533
+ andThenOptional: <A, B>(inner: Optional<A, B>) => <S>(outer: Lens<S, A>) => Optional<S, B>;
534
+ /**
535
+ * Converts a Lens to an Optional. Every Lens is a valid Optional
536
+ * whose get always returns Some.
537
+ *
538
+ * @example
539
+ * ```ts
540
+ * pipe(
541
+ * Lens.from.property<User>()("address"),
542
+ * Lens.toOptional,
543
+ * Optional.andThen(Optional.from.property<Address>()("landmark")),
544
+ * );
545
+ * ```
546
+ */
547
+ toOptional: <S, A>(lens: Lens<S, A>) => Optional<S, A>;
548
+ };
549
+ //#endregion
550
+ //#region src/Core/Logged.d.ts
551
+ /**
552
+ * A value paired with an accumulated log.
553
+ *
554
+ * `Logged<W, A>` pairs a result `A` with a sequence of log entries `W`. When
555
+ * you sequence two `Logged` computations with `chain`, the logs are
556
+ * automatically concatenated — you never have to thread the log array through
557
+ * your code manually.
558
+ *
559
+ * @example
560
+ * ```ts
561
+ * const program = pipe(
562
+ * Logged.from.value<string, number>(0),
563
+ * Logged.chain(n => pipe(
564
+ * Logged.from.entry("start"),
565
+ * Logged.map(() => n + 1),
566
+ * )),
567
+ * Logged.chain(n => pipe(
568
+ * Logged.from.entry("done"),
569
+ * Logged.map(() => n * 10),
570
+ * )),
571
+ * );
572
+ *
573
+ * Logged.run(program); // [10, ["start", "done"]]
574
+ * ```
575
+ */
576
+ type Logged<L, A> = WithValue<A> & WithLog<L>;
577
+ declare const Logged: {
578
+ from: {
579
+ /**
580
+ * Wraps a pure value into a `Logged` with an empty log.
581
+ *
582
+ * @example
583
+ * ```ts
584
+ * Logged.from.value<string, number>(42); // { value: 42, log: [] }
585
+ * ```
586
+ */
587
+ value: <W, A>(val: A) => Logged<W, A>;
588
+ /**
589
+ * Creates a `Logged` that records a single log entry and produces no
590
+ * meaningful value. Use this to append to the log inside a `chain`.
591
+ *
592
+ * @example
593
+ * ```ts
594
+ * Logged.from.entry("operation completed"); // { value: undefined, log: ["operation completed"] }
595
+ * ```
596
+ */
597
+ entry: <W>(logEntry: W) => Logged<W, undefined>;
598
+ };
599
+ /**
600
+ * Transforms the value inside a `Logged` without affecting the log.
601
+ *
602
+ * @example
603
+ * ```ts
604
+ * pipe(
605
+ * Logged.from.value<string, number>(5),
606
+ * Logged.map(n => n * 2),
607
+ * ); // { value: 10, log: [] }
608
+ * ```
609
+ */
610
+ map: <W, A, B>(f: (a: A) => B) => (data: Logged<W, A>) => Logged<W, B>;
611
+ /**
612
+ * Sequences two `Logged` computations, concatenating their logs.
613
+ * The value from the first is passed to `f`; the resulting log entries are
614
+ * appended after the entries from the first.
615
+ *
616
+ * Data-last — the first computation is the data being piped.
617
+ *
618
+ * @example
619
+ * ```ts
620
+ * const result = pipe(
621
+ * Logged.from.value<string, number>(1),
622
+ * Logged.chain(n => pipe(Logged.from.entry("step"), Logged.map(() => n + 1))),
623
+ * Logged.chain(n => pipe(Logged.from.entry("done"), Logged.map(() => n * 10))),
624
+ * );
625
+ *
626
+ * Logged.run(result); // [20, ["step", "done"]]
627
+ * ```
628
+ */
629
+ chain: <W, A, B>(f: (a: A) => Logged<W, B>) => (data: Logged<W, A>) => Logged<W, B>;
630
+ /**
631
+ * Applies a function wrapped in a `Logged` to a value wrapped in a `Logged`,
632
+ * concatenating both logs.
633
+ *
634
+ * @example
635
+ * ```ts
636
+ * const fn: Logged<string, (n: number) => number> = {
637
+ * value: n => n * 2,
638
+ * log: ["fn-loaded"],
639
+ * };
640
+ * const arg: Logged<string, number> = { value: 5, log: ["arg-loaded"] };
641
+ *
642
+ * const result = pipe(fn, Logged.ap(arg));
643
+ * Logged.run(result); // [10, ["fn-loaded", "arg-loaded"]]
644
+ * ```
645
+ */
646
+ ap: <W, A>(arg: Logged<W, A>) => <B>(data: Logged<W, (a: A) => B>) => Logged<W, B>;
647
+ /**
648
+ * Runs a side effect on the value without changing the `Logged`.
649
+ * Useful for debugging or inspecting intermediate values.
650
+ *
651
+ * @example
652
+ * ```ts
653
+ * pipe(
654
+ * Logged.from.value<string, number>(42),
655
+ * Logged.tap(n => console.log("value:", n)),
656
+ * );
657
+ * ```
658
+ */
659
+ tap: <W, A>(f: (a: A) => void) => (data: Logged<W, A>) => Logged<W, A>;
660
+ /**
661
+ * Extracts the value and log as a `readonly [A, ReadonlyArray<W>]` tuple.
662
+ * Use this at the boundary where you need to consume both.
663
+ *
664
+ * @example
665
+ * ```ts
666
+ * const result = pipe(
667
+ * Logged.from.value<string, number>(1),
668
+ * Logged.chain(n => pipe(Logged.from.entry("incremented"), Logged.map(() => n + 1))),
669
+ * );
670
+ *
671
+ * const [value, log] = Logged.run(result);
672
+ * // value = 2, log = ["incremented"]
673
+ * ```
674
+ */
675
+ run: <W, A>(data: Logged<W, A>) => readonly [A, ReadonlyArray<W>];
676
+ /**
677
+ * Lifts a Logged value into an accumulator object.
678
+ *
679
+ * @example
680
+ * ```ts
681
+ * pipe(Logged.from.value<string, number>(42), Logged.bindTo("value")); // Logged({ value: 42 })
682
+ * ```
683
+ */
684
+ bindTo: <K extends string>(key: K) => <W, A>(data: Logged<W, A>) => Logged<W, { [P in K]: A; }>;
685
+ /**
686
+ * Evaluates a new Logged using the current accumulator and attaches the output to a new key.
687
+ *
688
+ * @example
689
+ * ```ts
690
+ * pipe(
691
+ * Logged.from.value<string, { a: number }>({ a: 1 }),
692
+ * Logged.bind("b", ({ a }) => Logged.from.value<string, number>(a + 1))
693
+ * ); // Logged({ value: { a: 1, b: 2 } })
694
+ * ```
695
+ */
696
+ bind: <K extends string, W, A, B>(key: K, f: (a: A) => Logged<W, B>) => (data: Logged<W, A>) => Logged<W, A & { [P in K]: B; }>;
697
+ /**
698
+ * Focuses a Logged computation's value transformation using a Lens.
699
+ *
700
+ * @example
701
+ * ```ts
702
+ * const nameLens = Lens.from.property<{ name: string }>()("name");
703
+ * const logged = Logged.from.value<string, { name: string }>({ name: "alice" });
704
+ * pipe(logged, Logged.focus(nameLens)(s => s.toUpperCase()));
705
+ * ```
706
+ */
707
+ focus: <S, A>(lens: Lens<S, A>) => <W>(f: (a: A) => A) => (data: Logged<W, S>) => Logged<W, S>;
708
+ };
709
+ //#endregion
710
+ //#region src/Core/Maybe.d.ts
711
+ /**
712
+ * Maybe represents an optional value: every Maybe is either Some (contains a value) or None (empty).
713
+ * Use Maybe instead of null/undefined to make optionality explicit and composable.
714
+ *
715
+ * @example
716
+ * ```ts
717
+ * const user = { name: "Alice", email: Maybe.make.some("alice@example.com") };
718
+ *
719
+ * pipe(
720
+ * user.email,
721
+ * Maybe.map(email => email.toUpperCase()),
722
+ * Maybe.getOrElse(() => "NO EMAIL")
723
+ * ); // "ALICE@EXAMPLE.COM"
724
+ * ```
725
+ */
726
+ type Maybe<T> = Some<T> | None;
727
+ type Some<A> = WithKind<"Some"> & WithValue<A>;
728
+ type None = WithKind<"None">;
729
+ declare const Maybe: {
730
+ make: {
731
+ /**
732
+ * Creates a Some containing the given value.
733
+ *
734
+ * @example
735
+ * ```ts
736
+ * Maybe.make.some(42); // Some(42)
737
+ * ```
738
+ */
739
+ some: <A>(value: A) => Some<A>;
740
+ /**
741
+ * Creates a None (empty Maybe).
742
+ *
743
+ * @example
744
+ * ```ts
745
+ * Maybe.make.none(); // None
746
+ * ```
747
+ */
748
+ none: () => None;
749
+ };
750
+ is: {
751
+ /**
752
+ * Type guard that checks if a Maybe is Some.
753
+ *
754
+ * @example
755
+ * ```ts
756
+ * const value = Maybe.make.some(42);
757
+ * if (Maybe.is.some(value)) {
758
+ * console.log(value.value); // 42
759
+ * }
760
+ * ```
761
+ */
762
+ some: <A>(data: Maybe<A>) => data is Some<A>;
763
+ /**
764
+ * Type guard that checks if a Maybe is None.
765
+ *
766
+ * @example
767
+ * ```ts
768
+ * const value = Maybe.make.none();
769
+ * if (Maybe.is.none(value)) {
770
+ * console.log("No value present");
771
+ * }
772
+ * ```
773
+ */
774
+ none: <A>(data: Maybe<A>) => data is None;
775
+ };
776
+ to: {
777
+ /**
778
+ * Extracts the value from a Maybe, returning null if None.
779
+ *
780
+ * @example
781
+ * ```ts
782
+ * Maybe.to.nullable(Maybe.make.some(42)); // 42
783
+ * Maybe.to.nullable(Maybe.make.none()); // null
784
+ * ```
785
+ */
786
+ nullable: <A>(data: Maybe<A>) => A | null;
787
+ /**
788
+ * Extracts the value from a Maybe, returning undefined if None.
789
+ *
790
+ * @example
791
+ * ```ts
792
+ * Maybe.to.undefined(Maybe.make.some(42)); // 42
793
+ * Maybe.to.undefined(Maybe.make.none()); // undefined
794
+ * ```
795
+ */
796
+ undefined: <A>(data: Maybe<A>) => A | undefined;
797
+ /**
798
+ * Converts a Maybe to a Result.
799
+ * Some becomes Ok, None becomes Err with the provided error.
800
+ *
801
+ * @example
802
+ * ```ts
803
+ * pipe(
804
+ * Maybe.make.some(42),
805
+ * Maybe.to.Result(() => "Value was missing")
806
+ * ); // Ok(42)
807
+ *
808
+ * pipe(
809
+ * Maybe.make.none(),
810
+ * Maybe.to.Result(() => "Value was missing")
811
+ * ); // Err("Value was missing")
812
+ * ```
813
+ */
814
+ Result: <E>(onNone: () => E) => <A>(data: Maybe<A>) => Result<E, A>;
815
+ };
816
+ from: {
817
+ /**
818
+ * Creates a Maybe from a nullable value.
819
+ * Returns None if the value is null or undefined, Some otherwise.
820
+ *
821
+ * @example
822
+ * ```ts
823
+ * Maybe.from.nullable(null); // None
824
+ * Maybe.from.nullable(42); // Some(42)
825
+ * ```
826
+ */
827
+ nullable: <A>(value: A | null | undefined) => Maybe<A>;
828
+ /**
829
+ * Creates a Maybe from a predicate applied to a value.
830
+ * Returns Some if the predicate passes, None otherwise.
831
+ *
832
+ * @example
833
+ * ```ts
834
+ * Maybe.from.Predicate((n: number) => n >= 18)(21); // Some(21)
835
+ * Maybe.from.Predicate((n: number) => n >= 18)(15); // None
836
+ *
837
+ * pipe("hello", Maybe.from.Predicate((s: string) => s.length > 0)); // Some("hello")
838
+ * pipe("", Maybe.from.Predicate((s: string) => s.length > 0)); // None
839
+ * ```
840
+ */
841
+ Predicate: <A>(pred: (a: A) => boolean) => (a: A) => Maybe<A>;
842
+ /**
843
+ * Creates a Maybe from a Result.
844
+ * Ok becomes Some, Err becomes None (the error is discarded).
845
+ *
846
+ * @example
847
+ * ```ts
848
+ * Maybe.from.Result(Result.make.ok(42)); // Some(42)
849
+ * Maybe.from.Result(Result.make.err("oops")); // None
850
+ * ```
851
+ */
852
+ Result: <E, A>(data: Result<E, A>) => Maybe<A>;
853
+ };
854
+ /**
855
+ * Wraps a synchronous operation that may throw, returning a `Maybe<A>`.
856
+ * Returns `Some(value)` if successful, or `None` if an exception is thrown.
857
+ *
858
+ * @example
859
+ * ```ts
860
+ * const safeParse = (s: string) => Maybe.tryCatch(() => JSON.parse(s));
861
+ * safeParse('{"a": 1}'); // Some({ a: 1 })
862
+ * safeParse('invalid'); // None
863
+ * ```
864
+ */
865
+ tryCatch: <A>(f: () => A) => Maybe<A>;
866
+ /**
867
+ * Transforms the value inside a Maybe if it exists.
868
+ *
869
+ * @example
870
+ * ```ts
871
+ * pipe(Maybe.make.some(5), Maybe.map(n => n * 2)); // Some(10)
872
+ * pipe(Maybe.make.none(), Maybe.map(n => n * 2)); // None
873
+ * ```
874
+ */
875
+ map: <A, B>(f: (a: A) => B) => (data: Maybe<A>) => Maybe<B>;
876
+ /**
877
+ * Chains Maybe computations. If the first is Some, passes the value to f.
878
+ * If the first is None, propagates None.
879
+ *
880
+ * @example
881
+ * ```ts
882
+ * const parseNumber = (s: string): Maybe<number> => {
883
+ * const n = parseInt(s, 10);
884
+ * return isNaN(n) ? Maybe.make.none() : Maybe.make.some(n);
885
+ * };
886
+ *
887
+ * pipe(Maybe.make.some("42"), Maybe.chain(parseNumber)); // Some(42)
888
+ * pipe(Maybe.make.some("abc"), Maybe.chain(parseNumber)); // None
889
+ * ```
890
+ */
891
+ chain: <A, B>(f: (a: A) => Maybe<B>) => (data: Maybe<A>) => Maybe<B>;
892
+ /**
893
+ * Extracts the value from a Maybe by providing handlers for both cases.
894
+ *
895
+ * @example
896
+ * ```ts
897
+ * pipe(
898
+ * Maybe.make.some(5),
899
+ * Maybe.fold(
900
+ * () => "No value",
901
+ * n => `Value: ${n}`
902
+ * )
903
+ * ); // "Value: 5"
904
+ * ```
905
+ */
906
+ fold: <A, B>(onNone: () => B, onSome: (a: A) => B) => (data: Maybe<A>) => B;
907
+ /**
908
+ * Pattern matches on a Maybe, returning the result of the matching case.
909
+ *
910
+ * @example
911
+ * ```ts
912
+ * pipe(
913
+ * optionUser,
914
+ * Maybe.match({
915
+ * some: user => `Hello, ${user.name}`,
916
+ * none: () => "Hello, stranger"
917
+ * })
918
+ * );
919
+ * ```
920
+ */
921
+ match: <A, B>(cases: {
922
+ none: () => B;
923
+ some: (a: A) => B;
924
+ }) => (data: Maybe<A>) => B;
925
+ /**
926
+ * Returns the value inside a Maybe, or a default value if None.
927
+ * The default is a thunk `() => B` — evaluated only when the Maybe is None.
928
+ * The default can be a different type, widening the result to `A | B`.
929
+ *
930
+ * @example
931
+ * ```ts
932
+ * pipe(Maybe.make.some(5), Maybe.getOrElse(() => 0)); // 5
933
+ * pipe(Maybe.make.none(), Maybe.getOrElse(() => 0)); // 0
934
+ * pipe(Maybe.make.none<string>(), Maybe.getOrElse(() => null)); // null — typed as string | null
935
+ * ```
936
+ */
937
+ getOrElse: <B>(defaultValue: () => B) => <A>(data: Maybe<A>) => A | B;
938
+ /**
939
+ * Executes a side effect on the value without changing the Maybe.
940
+ * Useful for logging or debugging.
941
+ *
942
+ * @example
943
+ * ```ts
944
+ * pipe(
945
+ * Maybe.make.some(5),
946
+ * Maybe.tap(n => console.log("Value:", n)),
947
+ * Maybe.map(n => n * 2)
948
+ * );
949
+ * ```
950
+ */
951
+ tap: <A>(f: (a: A) => void) => (data: Maybe<A>) => Maybe<A>;
952
+ /**
953
+ * Executes a side effect when the Maybe is None, without changing the Maybe.
954
+ *
955
+ * @example
956
+ * ```ts
957
+ * pipe(
958
+ * Maybe.make.none(),
959
+ * Maybe.tapNone(() => console.log("Value missing")),
960
+ * );
961
+ * ```
962
+ */
963
+ tapNone: (f: () => void) => <A>(data: Maybe<A>) => Maybe<A>;
964
+ /**
965
+ * Filters a Maybe based on a predicate or type guard.
966
+ * Returns None if the predicate returns false or if the Maybe is already None.
967
+ *
968
+ * @example
969
+ * ```ts
970
+ * pipe(Maybe.make.some(5), Maybe.filter(n => n > 3)); // Some(5)
971
+ * pipe(Maybe.make.some(2), Maybe.filter(n => n > 3)); // None
972
+ * pipe(Maybe.make.some("hi"), Maybe.filter((x): x is string => typeof x === "string")); // Some("hi")
973
+ * ```
974
+ */
975
+ filter: {
976
+ <A, B extends A>(refinement: (a: A) => a is B): (data: Maybe<A>) => Maybe<B>;
977
+ <A>(predicate: (a: A) => boolean): (data: Maybe<A>) => Maybe<A>;
978
+ };
979
+ /**
980
+ * Recovers from a None by providing a fallback Maybe.
981
+ * The fallback can produce a different type, widening the result to `Maybe<A | B>`.
982
+ *
983
+ * @example
984
+ * ```ts
985
+ * pipe(Maybe.make.none(), Maybe.recover(() => Maybe.make.some(42))); // Some(42)
986
+ * pipe(Maybe.make.some(10), Maybe.recover(() => Maybe.make.some(42))); // Some(10)
987
+ * ```
988
+ */
989
+ recover: <B>(fallback: () => Maybe<B>) => <A>(data: Maybe<A>) => Maybe<A | B>;
990
+ /**
991
+ * Applies a function wrapped in a Maybe to a value wrapped in a Maybe.
992
+ *
993
+ * @example
994
+ * ```ts
995
+ * const add = (a: number) => (b: number) => a + b;
996
+ * pipe(
997
+ * Maybe.make.some(add),
998
+ * Maybe.ap(Maybe.make.some(5)),
999
+ * Maybe.ap(Maybe.make.some(3))
1000
+ * ); // Some(8)
1001
+ * ```
1002
+ */
1003
+ ap: <A>(arg: Maybe<A>) => <B>(data: Maybe<(a: A) => B>) => Maybe<B>;
1004
+ /**
1005
+ * Converts a Maybe value into an object containing a single property.
1006
+ * Initiates the pipeline accumulator record.
1007
+ *
1008
+ * @example
1009
+ * ```ts
1010
+ * pipe(Maybe.make.some(42), Maybe.bindTo("value")); // Some({ value: 42 })
1011
+ * ```
1012
+ */
1013
+ bindTo: <K extends string>(key: K) => <A>(data: Maybe<A>) => Maybe<{ [P in K]: A; }>;
1014
+ /**
1015
+ * Evaluates a new Maybe using the current accumulator and attaches the output to a new key.
1016
+ *
1017
+ * @example
1018
+ * ```ts
1019
+ * pipe(
1020
+ * Maybe.make.some({ a: 1 }),
1021
+ * Maybe.bind("b", ({ a }) => Maybe.make.some(a + 1))
1022
+ * ); // Some({ a: 1, b: 2 })
1023
+ * ```
1024
+ */
1025
+ bind: <K extends string, A, B>(key: K, f: (a: A) => Maybe<B>) => (data: Maybe<A>) => Maybe<A & { [P in K]: B; }>;
1026
+ /**
1027
+ * Combines a record of Maybes into a single Maybe of a record.
1028
+ * Evaluates fields in key order and short-circuits on the first None.
1029
+ *
1030
+ * @example
1031
+ * ```ts
1032
+ * Maybe.struct({
1033
+ * name: Maybe.make.some("Alice"),
1034
+ * age: Maybe.make.some(30)
1035
+ * }); // Some({ name: "Alice", age: 30 })
1036
+ * ```
1037
+ */
1038
+ struct: <R extends Record<string, any>>(fields: { [K in keyof R]: Maybe<R[K]>; }) => Maybe<R>;
1039
+ /**
1040
+ * Swaps the outer `Maybe` and inner `Result` context.
1041
+ * `Some(Ok(a))` becomes `Ok(Some(a))`, `Some(Err(e))` becomes `Err(e)`, and `None` becomes `Ok(None)`.
1042
+ *
1043
+ * @example
1044
+ * ```ts
1045
+ * Maybe.transposeResult(Maybe.make.some(Result.make.ok(42))); // Ok(Some(42))
1046
+ * Maybe.transposeResult(Maybe.make.some(Result.make.err("e"))); // Err("e")
1047
+ * Maybe.transposeResult(Maybe.make.none()); // Ok(None)
1048
+ * ```
1049
+ */
1050
+ transposeResult: <E, A>(data: Maybe<Result<E, A>>) => Result<E, Maybe<A>>;
1051
+ };
1052
+ //#endregion
1053
+ //#region src/Core/Op.d.ts
1054
+ /**
1055
+ * A reusable description of async work — decoupled from execution strategy and lifetime.
1056
+ *
1057
+ * Separate concerns:
1058
+ * - **What** to do: encoded in the `Op` via `Op.create`
1059
+ * - **How** to execute: chosen at `Op.interpret` time (restartable, exclusive, queue, etc.)
1060
+ *
1061
+ * An `Op` never runs on its own. It only executes when passed to `Op.interpret`, which
1062
+ * attaches a concurrency strategy and returns a `Manager` that owns the execution.
1063
+ *
1064
+ * @example
1065
+ * ```ts
1066
+ * const fetchUser = Op.create(
1067
+ * (signal) => (id: string) =>
1068
+ * fetch(`/users/${id}`, { signal }).then(r => {
1069
+ * if (!r.ok) throw new Error(`${r.status} ${r.statusText}`);
1070
+ * return r.json() as Promise<User>;
1071
+ * }),
1072
+ * (e) => new ApiError(e),
1073
+ * );
1074
+ *
1075
+ * const manager = Op.interpret(fetchUser, { strategy: "restartable" });
1076
+ * manager.subscribe(state => {
1077
+ * if (Op.is.pending(state)) showSpinner();
1078
+ * if (Op.is.ok(state)) render(state.value);
1079
+ * if (Op.is.err(state)) showError(state.error);
1080
+ * if (Op.is.nil(state)) resetUI();
1081
+ * });
1082
+ * manager.run(userId);
1083
+ * ```
1084
+ */
1085
+ type Op<I, E, A> = {
1086
+ /**
1087
+ * @internal — Used by `Op.interpret`. Do not call directly.
1088
+ * Returns `null` when the operation was aborted (signal fired before factory resolved).
1089
+ */
1090
+ readonly _factory: (input: I, signal: AbortSignal) => Deferred<Result<E, A> | null>;
1091
+ };
1092
+ type MaybeRetry<E, O> = O extends {
1093
+ retry: RetryOptions<E>;
1094
+ } ? Op.Retrying<E> : never;
1095
+ type AllInterpretOptions<I, E> = ({
1096
+ strategy: "once";
1097
+ retry?: RetryOptions<E>;
1098
+ } & WithTimeout<E>) | ({
1099
+ strategy: "restartable";
1100
+ retry?: RetryOptions<E>;
1101
+ } & WithMinInterval & WithTimeout<E>) | ({
1102
+ strategy: "exclusive";
1103
+ retry?: RetryOptions<E>;
1104
+ } & WithCooldown & WithTimeout<E>) | ({
1105
+ strategy: "queue";
1106
+ retry?: RetryOptions<E>;
1107
+ maxSize?: number;
1108
+ overflow?: "drop" | "replace-last";
1109
+ dedupe?: (a: I, b: I) => boolean;
1110
+ } & WithConcurrency & WithTimeout<E>) | ({
1111
+ strategy: "buffered";
1112
+ retry?: RetryOptions<E>;
1113
+ } & WithSize & WithTimeout<E>) | ({
1114
+ strategy: "debounced";
1115
+ retry?: RetryOptions<E>;
1116
+ leading?: true;
1117
+ maxWait?: Duration;
1118
+ } & WithDuration & WithTimeout<E>) | ({
1119
+ strategy: "throttled";
1120
+ retry?: RetryOptions<E>;
1121
+ trailing?: true;
1122
+ } & WithDuration & WithTimeout<E>) | ({
1123
+ strategy: "concurrent";
1124
+ retry?: RetryOptions<E>;
1125
+ overflow?: "queue" | "drop";
1126
+ } & WithN & WithTimeout<E>) | ({
1127
+ strategy: "keyed";
1128
+ perKey?: "exclusive" | "restartable";
1129
+ key: (input: I) => unknown;
1130
+ } & WithTimeout<E>);
1131
+ type KeyType<I, O> = O extends {
1132
+ key: (input: I) => infer K;
1133
+ } ? K : unknown;
1134
+ type InterpretResult<I, E, A, O> = [O] extends [{
1135
+ strategy: "throttled";
1136
+ trailing: true;
1137
+ }] ? Op.Manager<I, E, A, Op.ThrottledTrailingState<E, A> | MaybeRetry<E, O>> : [O] extends [{
1138
+ strategy: "throttled";
1139
+ }] ? Op.Manager<I, E, A, Op.ThrottledState<E, A> | MaybeRetry<E, O>> : [O] extends [{
1140
+ strategy: "debounced";
1141
+ }] ? Op.Manager<I, E, A, Op.DebouncedState<E, A> | MaybeRetry<E, O>> : [O] extends [{
1142
+ strategy: "concurrent";
1143
+ overflow: "queue";
1144
+ }] ? Op.Manager<I, E, A, Op.ConcurrentQueueState<E, A> | MaybeRetry<E, O>> : [O] extends [{
1145
+ strategy: "concurrent";
1146
+ }] ? Op.Manager<I, E, A, Op.ConcurrentDropState<E, A> | MaybeRetry<E, O>> : [O] extends [{
1147
+ strategy: "keyed";
1148
+ perKey: "restartable";
1149
+ }] ? Op.KeyedManager<I, KeyType<I, O>, E, Op.KeyedRestartablePerKey<E, A>> : [O] extends [{
1150
+ strategy: "keyed";
1151
+ }] ? Op.KeyedManager<I, KeyType<I, O>, E, Op.KeyedExclusivePerKey<E, A>> : [O] extends [{
1152
+ strategy: "once";
1153
+ }] ? Op.Manager<I, E, A, Op.OnceState<E, A> | MaybeRetry<E, O>> : [O] extends [{
1154
+ strategy: "restartable";
1155
+ }] ? Op.Manager<I, E, A, Op.RestartableState<E, A> | MaybeRetry<E, O>> : [O] extends [{
1156
+ strategy: "exclusive";
1157
+ }] ? Op.Manager<I, E, A, Op.ExclusiveState<E, A> | MaybeRetry<E, O>> : [O] extends [{
1158
+ strategy: "queue";
1159
+ overflow: "replace-last";
1160
+ dedupe: (a: I, b: I) => boolean;
1161
+ }] ? Op.Manager<I, E, A, Op.QueueDropAndReplaceState<E, A> | MaybeRetry<E, O>> : [O] extends [{
1162
+ strategy: "queue";
1163
+ overflow: "replace-last";
1164
+ }] ? Op.Manager<I, E, A, Op.QueueReplaceState<E, A> | MaybeRetry<E, O>> : [O] extends [{
1165
+ strategy: "queue";
1166
+ maxSize: number;
1167
+ }] ? Op.Manager<I, E, A, Op.QueueDropState<E, A> | MaybeRetry<E, O>> : [O] extends [{
1168
+ strategy: "queue";
1169
+ dedupe: (a: I, b: I) => boolean;
1170
+ }] ? Op.Manager<I, E, A, Op.QueueDropState<E, A> | MaybeRetry<E, O>> : [O] extends [{
1171
+ strategy: "queue";
1172
+ }] ? Op.Manager<I, E, A, Op.QueueState<E, A> | MaybeRetry<E, O>> : [O] extends [{
1173
+ strategy: "buffered";
1174
+ }] ? Op.Manager<I, E, A, Op.BufferedState<E, A> | MaybeRetry<E, O>> : never;
1175
+ declare function interpretFn<I, E, A, O extends AllInterpretOptions<I, E>>(op: Op<I, E, A>, options: O): InterpretResult<I, E, A, O>;
1176
+ declare const Op: {
1177
+ make: {
1178
+ /**
1179
+ * Creates an Ok outcome with the given value.
1180
+ *
1181
+ * @example
1182
+ * ```ts
1183
+ * Op.make.ok(42); // { kind: "OpOk", value: 42 }
1184
+ * ```
1185
+ */
1186
+ ok: <A>(value: A) => Op.Ok<A>;
1187
+ /**
1188
+ * Creates an Err outcome with the given error.
1189
+ *
1190
+ * @example
1191
+ * ```ts
1192
+ * Op.make.err("Something went wrong"); // { kind: "OpErr", error: "Something went wrong" }
1193
+ * ```
1194
+ */
1195
+ err: <E>(error: E) => Op.Err<E>;
1196
+ /**
1197
+ * Creates a Nil outcome with the given cancellation/drop reason.
1198
+ *
1199
+ * @example
1200
+ * ```ts
1201
+ * Op.make.nil("aborted"); // { kind: "OpNil", reason: "aborted" }
1202
+ * ```
1203
+ */
1204
+ nil: (reason: Op.NilReason) => Op.Nil;
1205
+ };
1206
+ is: {
1207
+ /**
1208
+ * Type guard that checks if an Op state is Idle.
1209
+ *
1210
+ * @example
1211
+ * ```ts
1212
+ * if (Op.is.idle(manager.state)) {
1213
+ * console.log("Ready to execute");
1214
+ * }
1215
+ * ```
1216
+ */
1217
+ idle: <E, A>(state: Op.State<E, A>) => state is Op.Idle;
1218
+ /**
1219
+ * Type guard that checks if an Op state is Pending (actively executing).
1220
+ *
1221
+ * @example
1222
+ * ```ts
1223
+ * if (Op.is.pending(manager.state)) {
1224
+ * showSpinner();
1225
+ * }
1226
+ * ```
1227
+ */
1228
+ pending: <E, A>(state: Op.State<E, A>) => state is Op.Pending;
1229
+ /**
1230
+ * Type guard that checks if an Op state is Queued (waiting in a concurrency queue).
1231
+ *
1232
+ * @example
1233
+ * ```ts
1234
+ * if (Op.is.queued(manager.state)) {
1235
+ * console.log("Position in queue:", manager.state.position);
1236
+ * }
1237
+ * ```
1238
+ */
1239
+ queued: <E, A>(state: Op.State<E, A>) => state is Op.Queued;
1240
+ /**
1241
+ * Type guard that checks if an Op state is Retrying after a failure.
1242
+ *
1243
+ * @example
1244
+ * ```ts
1245
+ * if (Op.is.retrying(manager.state)) {
1246
+ * console.log("Retry attempt:", manager.state.attempt);
1247
+ * }
1248
+ * ```
1249
+ */
1250
+ retrying: <E, A>(state: Op.State<E, A>) => state is Op.Retrying<E>;
1251
+ /**
1252
+ * Type guard that checks if an Op state or outcome is Ok.
1253
+ *
1254
+ * @example
1255
+ * ```ts
1256
+ * if (Op.is.ok(outcome)) {
1257
+ * render(outcome.value);
1258
+ * }
1259
+ * ```
1260
+ */
1261
+ ok: <E, A>(state: Op.State<E, A>) => state is Op.Ok<A>;
1262
+ /**
1263
+ * Type guard that checks if an Op state or outcome is Err.
1264
+ *
1265
+ * @example
1266
+ * ```ts
1267
+ * if (Op.is.err(outcome)) {
1268
+ * showError(outcome.error);
1269
+ * }
1270
+ * ```
1271
+ */
1272
+ err: <E, A>(state: Op.State<E, A>) => state is Op.Err<E>;
1273
+ /**
1274
+ * Type guard that checks if an Op state or outcome is Nil.
1275
+ *
1276
+ * @example
1277
+ * ```ts
1278
+ * if (Op.is.nil(outcome)) {
1279
+ * console.log("Skipped due to:", outcome.reason);
1280
+ * }
1281
+ * ```
1282
+ */
1283
+ nil: <E, A>(state: Op.State<E, A>) => state is Op.Nil;
1284
+ };
1285
+ create: <E, A, I = void>(factory: (signal: AbortSignal) => (input: I) => Promise<A>, onError: (e: unknown) => E) => Op<I, E, A>;
1286
+ lift: <I, A>(f: (input: I, signal: AbortSignal) => Promise<A>) => Op<I, unknown, A>;
1287
+ match: <E, A, B>(cases: {
1288
+ ok: (a: A) => B;
1289
+ err: (e: E) => B;
1290
+ nil: () => B;
1291
+ }) => (outcome: Op.Outcome<E, A>) => B;
1292
+ fold: <E, A, B>(onErr: (e: E) => B, onNil: () => B, onOk: (a: A) => B) => (outcome: Op.Outcome<E, A>) => B;
1293
+ getOrElse: <E, A, B>(defaultValue: () => B) => (outcome: Op.Outcome<E, A>) => A | B;
1294
+ map: <E, A, B>(f: (a: A) => B) => (outcome: Op.Outcome<E, A>) => Op.Outcome<E, B>;
1295
+ mapError: <E, F, A>(f: (e: E) => F) => (outcome: Op.Outcome<E, A>) => Op.Outcome<F, A>;
1296
+ chain: <E, A, B>(f: (a: A) => Op.Outcome<E, B>) => (outcome: Op.Outcome<E, A>) => Op.Outcome<E, B>;
1297
+ tap: <E, A>(f: (a: A) => void) => (outcome: Op.Outcome<E, A>) => Op.Outcome<E, A>;
1298
+ recover: <E, A, B>(f: (e: E) => Op.Outcome<E, B>) => (outcome: Op.Outcome<E, A>) => Op.Outcome<E, A | B>;
1299
+ to: {
1300
+ Result: <E, A>(onNil: () => E) => (outcome: Op.Outcome<E, A>) => Result<E, A>;
1301
+ Maybe: <E, A>(outcome: Op.Outcome<E, A>) => Maybe<A>;
1302
+ };
1303
+ all: <E, A>(invocations: ReadonlyArray<Deferred<Op.Outcome<E, A>>>) => Deferred<ReadonlyArray<Op.Outcome<E, A>>>;
1304
+ race: <E, A>(invocations: ReadonlyArray<Deferred<Op.Outcome<E, A>>>) => Deferred<Op.Outcome<E, A>>;
1305
+ wire: <I, E, A, S extends Op.State<E, A>>(source: Op.Manager<I, E, A, S>, f: (a: A) => void) => () => void;
1306
+ interpret: typeof interpretFn;
1307
+ };
1308
+ declare namespace Op {
1309
+ type Outcome<E, A> = Ok<A> | Err<E> | Nil;
1310
+ type Ok<A> = WithKind<"OpOk"> & WithValue<A>;
1311
+ type Err<E> = WithKind<"OpErr"> & WithError<E>;
1312
+ type Nil = WithKind<"OpNil"> & {
1313
+ readonly reason: NilReason;
1314
+ };
1315
+ type NilReason = "aborted" | "dropped" | "replaced" | "evicted";
1316
+ type AbortedNil = Nil & {
1317
+ readonly reason: "aborted";
1318
+ };
1319
+ type DroppedNil = Nil & {
1320
+ readonly reason: "dropped";
1321
+ };
1322
+ type ReplacedNil = Nil & {
1323
+ readonly reason: "replaced";
1324
+ };
1325
+ type EvictedNil = Nil & {
1326
+ readonly reason: "evicted";
1327
+ };
1328
+ type State<E, A> = Idle | Pending | Queued | Retrying<E> | Outcome<E, A>;
1329
+ type Idle = WithKind<"Idle">;
1330
+ type Pending = WithKind<"Pending">;
1331
+ type Queued = WithKind<"Queued"> & {
1332
+ readonly position: number;
1333
+ };
1334
+ type Retrying<E> = WithKind<"Retrying"> & {
1335
+ readonly attempt: number;
1336
+ readonly lastError: E;
1337
+ readonly nextRetryIn?: number;
1338
+ };
1339
+ type Manager<I, E, A, S extends State<E, A>> = {
1340
+ readonly state: S;
1341
+ run: (input: I) => Deferred<Exclude<S, Idle | Pending | Queued | Retrying<E>>>;
1342
+ abort: () => void;
1343
+ subscribe: (cb: (state: S) => void) => () => void;
1344
+ reset: () => void;
1345
+ poll: (input: I, options: {
1346
+ interval: Duration;
1347
+ }) => () => void;
1348
+ };
1349
+ type KeyedManager<I, K, E, PerKeyS> = {
1350
+ readonly state: ReadonlyMap<K, PerKeyS>;
1351
+ run: (input: I) => Deferred<Exclude<PerKeyS, Pending | Retrying<E>>>;
1352
+ abort: (key?: K) => void;
1353
+ subscribe: (cb: (state: ReadonlyMap<K, PerKeyS>) => void) => () => void;
1354
+ reset: () => void;
1355
+ poll: (input: I, options: {
1356
+ interval: Duration;
1357
+ }) => () => void;
1358
+ };
1359
+ type OnceState<E, A> = Idle | Pending | Ok<A> | Err<E> | AbortedNil | DroppedNil;
1360
+ type RetryableOnceState<E, A> = Idle | Pending | Retrying<E> | Ok<A> | Err<E> | AbortedNil | DroppedNil;
1361
+ type RestartableState<E, A> = Idle | Pending | Ok<A> | Err<E> | AbortedNil | ReplacedNil;
1362
+ type RetryableRestartableState<E, A> = Idle | Pending | Retrying<E> | Ok<A> | Err<E> | AbortedNil | ReplacedNil;
1363
+ type ExclusiveState<E, A> = Idle | Pending | Ok<A> | Err<E> | AbortedNil | DroppedNil;
1364
+ type RetryableExclusiveState<E, A> = Idle | Pending | Retrying<E> | Ok<A> | Err<E> | AbortedNil | DroppedNil;
1365
+ type QueueState<E, A> = Idle | Pending | Queued | Ok<A> | Err<E> | AbortedNil;
1366
+ type RetryableQueueState<E, A> = Idle | Pending | Queued | Retrying<E> | Ok<A> | Err<E> | AbortedNil;
1367
+ type QueueDropState<E, A> = Idle | Pending | Queued | Ok<A> | Err<E> | AbortedNil | DroppedNil;
1368
+ type RetryableQueueDropState<E, A> = Idle | Pending | Queued | Retrying<E> | Ok<A> | Err<E> | AbortedNil | DroppedNil;
1369
+ type QueueReplaceState<E, A> = Idle | Pending | Queued | Ok<A> | Err<E> | AbortedNil | EvictedNil;
1370
+ type RetryableQueueReplaceState<E, A> = Idle | Pending | Queued | Retrying<E> | Ok<A> | Err<E> | AbortedNil | EvictedNil;
1371
+ type QueueDropAndReplaceState<E, A> = Idle | Pending | Queued | Ok<A> | Err<E> | AbortedNil | DroppedNil | EvictedNil;
1372
+ type RetryableQueueDropAndReplaceState<E, A> = Idle | Pending | Queued | Retrying<E> | Ok<A> | Err<E> | AbortedNil | DroppedNil | EvictedNil;
1373
+ type BufferedState<E, A> = Idle | Pending | Queued | Ok<A> | Err<E> | AbortedNil | EvictedNil;
1374
+ type RetryableBufferedState<E, A> = Idle | Pending | Queued | Retrying<E> | Ok<A> | Err<E> | AbortedNil | EvictedNil;
1375
+ type DebouncedState<E, A> = Idle | Pending | Ok<A> | Err<E> | AbortedNil | EvictedNil;
1376
+ type RetryableDebouncedState<E, A> = Idle | Pending | Retrying<E> | Ok<A> | Err<E> | AbortedNil | EvictedNil;
1377
+ type ThrottledState<E, A> = Idle | Pending | Ok<A> | Err<E> | AbortedNil | DroppedNil;
1378
+ type RetryableThrottledState<E, A> = Idle | Pending | Retrying<E> | Ok<A> | Err<E> | AbortedNil | DroppedNil;
1379
+ type ThrottledTrailingState<E, A> = Idle | Pending | Ok<A> | Err<E> | AbortedNil | EvictedNil;
1380
+ type RetryableThrottledTrailingState<E, A> = Idle | Pending | Retrying<E> | Ok<A> | Err<E> | AbortedNil | EvictedNil;
1381
+ type ConcurrentQueueState<E, A> = Idle | Pending | Queued | Ok<A> | Err<E> | AbortedNil;
1382
+ type RetryableConcurrentQueueState<E, A> = Idle | Pending | Queued | Retrying<E> | Ok<A> | Err<E> | AbortedNil;
1383
+ type ConcurrentDropState<E, A> = Idle | Pending | Ok<A> | Err<E> | AbortedNil | DroppedNil;
1384
+ type RetryableConcurrentDropState<E, A> = Idle | Pending | Retrying<E> | Ok<A> | Err<E> | AbortedNil | DroppedNil;
1385
+ type KeyedExclusivePerKey<E, A> = Pending | Ok<A> | Err<E> | AbortedNil | DroppedNil;
1386
+ type KeyedRestartablePerKey<E, A> = Pending | Ok<A> | Err<E> | AbortedNil | ReplacedNil;
1387
+ type RetryOptions<E> = RetryOptions<E>;
1388
+ type TimeoutOptions<E> = TimeoutOptions<E>;
1389
+ }
1390
+ //#endregion
1391
+ //#region src/Core/Optional.d.ts
1392
+ /** Keys of T for which undefined is assignable (i.e. optional fields). */
1393
+ type OptionalKeys<T> = { [K in keyof T]-?: undefined extends T[K] ? K : never; }[keyof T];
1394
+ /**
1395
+ * Optional<S, A> focuses on a value A inside a structure S that may or may
1396
+ * not be present. Like a Lens, but get returns Maybe<A>.
1397
+ *
1398
+ * Compose with other Optionals via `andThen`, or with a Lens via `andThenLens`.
1399
+ * Convert a Lens to an Optional with `Lens.toOptional`.
1400
+ *
1401
+ * @example
1402
+ * ```ts
1403
+ * type Profile = { username: string; bio?: string };
1404
+ *
1405
+ * const bioOpt = Optional.from.property<Profile>()("bio");
1406
+ *
1407
+ * pipe(profile, Optional.get(bioOpt)); // Some("hello") or None
1408
+ * pipe(profile, Optional.set(bioOpt)("hello")); // new Profile with bio set
1409
+ * pipe(profile, Optional.modify(bioOpt)(s => s + "!")); // appends if present
1410
+ * ```
1411
+ */
1412
+ type Optional<S, A> = {
1413
+ readonly get: (s: S) => Maybe<A>;
1414
+ readonly set: (a: A) => (s: S) => S;
1415
+ };
1416
+ declare const Optional: {
1417
+ from: {
1418
+ /**
1419
+ * Constructs an Optional from a getter (returning Maybe<A>) and a setter.
1420
+ *
1421
+ * @example
1422
+ * ```ts
1423
+ * const firstChar = Optional.from.accessors(
1424
+ * (s: string) => s.length > 0 ? Maybe.make.some(s[0]) : Maybe.make.none(),
1425
+ * (c) => (s) => s.length > 0 ? c + s.slice(1) : s,
1426
+ * );
1427
+ * ```
1428
+ */
1429
+ accessors: <S, A>(get: (s: S) => Maybe<A>, set: (a: A) => (s: S) => S) => Optional<S, A>;
1430
+ /**
1431
+ * Creates an Optional that focuses on an optional property of an object.
1432
+ * Only keys whose type includes undefined (i.e. `field?: T`) are accepted.
1433
+ * Call with the structure type first, then the key.
1434
+ *
1435
+ * @example
1436
+ * ```ts
1437
+ * type Profile = { username: string; bio?: string };
1438
+ * const bioOpt = Optional.from.property<Profile>()("bio");
1439
+ * ```
1440
+ */
1441
+ property: <S>() => <K extends OptionalKeys<S>>(key: K) => Optional<S, NonNullable<S[K]>>;
1442
+ };
1443
+ /**
1444
+ * Creates an Optional that focuses on an element at a given index in an array.
1445
+ * Returns None when the index is out of bounds; set is a no-op when out of bounds.
1446
+ *
1447
+ * @example
1448
+ * ```ts
1449
+ * const firstItem = Optional.index<string>(0);
1450
+ *
1451
+ * pipe(["a", "b"], Optional.get(firstItem)); // Some("a")
1452
+ * pipe([], Optional.get(firstItem)); // None
1453
+ * ```
1454
+ */
1455
+ index: <A>(i: number) => Optional<A[], A>;
1456
+ /**
1457
+ * Reads the focused value from a structure, returning Maybe<A>.
1458
+ *
1459
+ * @example
1460
+ * ```ts
1461
+ * pipe(profile, Optional.get(bioOpt)); // Some("...") or None
1462
+ * ```
1463
+ */
1464
+ get: <S, A>(opt: Optional<S, A>) => (s: S) => Maybe<A>;
1465
+ /**
1466
+ * Replaces the focused value within a structure.
1467
+ * For indexed focuses, this is a no-op when the index is out of bounds.
1468
+ *
1469
+ * @example
1470
+ * ```ts
1471
+ * pipe(profile, Optional.set(bioOpt)("hello"));
1472
+ * ```
1473
+ */
1474
+ set: <S, A>(opt: Optional<S, A>) => (a: A) => (s: S) => S;
1475
+ /**
1476
+ * Applies a function to the focused value if it is present; returns the
1477
+ * structure unchanged if the focus is absent.
1478
+ *
1479
+ * @example
1480
+ * ```ts
1481
+ * pipe(profile, Optional.modify(bioOpt)(s => s.toUpperCase()));
1482
+ * ```
1483
+ */
1484
+ modify: <S, A>(opt: Optional<S, A>) => (f: (a: A) => A) => (s: S) => S;
1485
+ /**
1486
+ * Returns the focused value or a default when the focus is absent.
1487
+ *
1488
+ * @example
1489
+ * ```ts
1490
+ * pipe(profile, Optional.getOrElse(bioOpt)(() => "no bio"));
1491
+ * ```
1492
+ */
1493
+ getOrElse: <S, A>(opt: Optional<S, A>) => (defaultValue: () => A) => (s: S) => A;
1494
+ /**
1495
+ * Extracts a value from an Optional focus using handlers for the present
1496
+ * and absent cases.
1497
+ *
1498
+ * @example
1499
+ * ```ts
1500
+ * pipe(profile, Optional.fold(bioOpt)(() => "no bio", (bio) => bio.toUpperCase()));
1501
+ * ```
1502
+ */
1503
+ fold: <S, A>(opt: Optional<S, A>) => <B>(onNone: () => B, onSome: (a: A) => B) => (s: S) => B;
1504
+ /**
1505
+ * Pattern matches on an Optional focus using a named-case object.
1506
+ *
1507
+ * @example
1508
+ * ```ts
1509
+ * pipe(
1510
+ * profile,
1511
+ * Optional.match(bioOpt)({ none: () => "no bio", some: (bio) => bio }),
1512
+ * );
1513
+ * ```
1514
+ */
1515
+ match: <S, A>(opt: Optional<S, A>) => <B>(cases: {
1516
+ none: () => B;
1517
+ some: (a: A) => B;
1518
+ }) => (s: S) => B;
1519
+ /**
1520
+ * Composes two Optionals: focuses through the outer, then through the inner.
1521
+ * Returns None if either focus is absent.
1522
+ *
1523
+ * @example
1524
+ * ```ts
1525
+ * const deepOpt = pipe(
1526
+ * Optional.from.property<User>()("address"),
1527
+ * Optional.andThen(Optional.from.property<Address>()("landmark")),
1528
+ * );
1529
+ * ```
1530
+ */
1531
+ andThen: <A, B>(inner: Optional<A, B>) => <S>(outer: Optional<S, A>) => Optional<S, B>;
1532
+ /**
1533
+ * Composes an Optional with a Lens, producing an Optional.
1534
+ * The Lens focuses within the value found by the Optional.
1535
+ *
1536
+ * @example
1537
+ * ```ts
1538
+ * const cityOpt = pipe(
1539
+ * Optional.from.property<User>()("address"),
1540
+ * Optional.andThenLens(Lens.from.property<Address>()("city")),
1541
+ * );
1542
+ * ```
1543
+ */
1544
+ andThenLens: <A, B>(inner: Lens<A, B>) => <S>(outer: Optional<S, A>) => Optional<S, B>;
1545
+ };
1546
+ //#endregion
1547
+ //#region src/Core/Ordering.d.ts
1548
+ /**
1549
+ * A function that orders two values of type `A`. Returns a negative number when `a` comes before
1550
+ * `b`, a positive number when `a` comes after `b`, and `0` when they are equal.
1551
+ *
1552
+ * Compatible with `Array.prototype.sort` and `Arr.sortWith`.
1553
+ *
1554
+ * @example
1555
+ * ```ts
1556
+ * type Employee = { name: string; salary: number };
1557
+ *
1558
+ * const byName = pipe(Ordering.string, Ordering.by((e: Employee) => e.name));
1559
+ * const bySalary = pipe(Ordering.number, Ordering.by((e: Employee) => e.salary));
1560
+ *
1561
+ * pipe(employees, Arr.sortWith(pipe(byName, Ordering.thenBy(bySalary))));
1562
+ * ```
1563
+ */
1564
+ type Ordering<A> = (a: A, b: A) => number;
1565
+ declare const Ordering: {
1566
+ /**
1567
+ * Alphabetical ordering for strings.
1568
+ *
1569
+ * @example
1570
+ * ```ts
1571
+ * Ordering.string("apple", "banana"); // negative
1572
+ * ```
1573
+ */
1574
+ string: Ordering<string>;
1575
+ /**
1576
+ * Numeric ordering. Equivalent to `(a, b) => a - b`.
1577
+ *
1578
+ * @example
1579
+ * ```ts
1580
+ * pipe([3, 1, 2], Arr.sortWith(Ordering.number)); // [1, 2, 3]
1581
+ * ```
1582
+ */
1583
+ number: Ordering<number>;
1584
+ /**
1585
+ * Ordering for `Date` values by numeric time value.
1586
+ *
1587
+ * @example
1588
+ * ```ts
1589
+ * pipe(dates, Arr.sortWith(Ordering.date)); // earliest first
1590
+ * ```
1591
+ */
1592
+ date: Ordering<Date>;
1593
+ /**
1594
+ * Flips the direction of an ordering.
1595
+ *
1596
+ * @example
1597
+ * ```ts
1598
+ * pipe([3, 1, 2], Arr.sortWith(Ordering.reverse(Ordering.number))); // [3, 2, 1]
1599
+ * ```
1600
+ */
1601
+ reverse: <A>(ord: Ordering<A>) => Ordering<A>;
1602
+ /**
1603
+ * Chains two orderings: the second is used only when the first returns `0`.
1604
+ * Data-last: the first ordering is the data being piped.
1605
+ *
1606
+ * @example
1607
+ * ```ts
1608
+ * const byDeptThenSalary = pipe(byDept, Ordering.thenBy(bySalary));
1609
+ * ```
1610
+ */
1611
+ thenBy: <A>(ord2: Ordering<A>) => (ord1: Ordering<A>) => Ordering<A>;
1612
+ /**
1613
+ * Adapts an ordering for type `A` into an ordering for type `B` by extracting a field.
1614
+ * Read as "ordering by this field": `pipe(Ordering.number, Ordering.by(p => p.price))`.
1615
+ *
1616
+ * @example
1617
+ * ```ts
1618
+ * type Product = { name: string; price: number };
1619
+ * const byPrice = pipe(Ordering.number, Ordering.by((p: Product) => p.price));
1620
+ * pipe(products, Arr.sortWith(byPrice));
1621
+ * ```
1622
+ */
1623
+ by: <A, B>(f: (b: B) => A) => (ord: Ordering<A>) => Ordering<B>;
1624
+ /**
1625
+ * Combines a list of orderings into a single composite comparator.
1626
+ * Evaluates each ordering in sequence until a non-zero comparison result is found.
1627
+ *
1628
+ * @example
1629
+ * ```ts
1630
+ * const byName = pipe(Ordering.string, Ordering.by((u: User) => u.name));
1631
+ * const byAge = pipe(Ordering.number, Ordering.by((u: User) => u.age));
1632
+ * const sortUsers = Ordering.byFields([byName, byAge]);
1633
+ * ```
1634
+ */
1635
+ byFields: <A>(orderings: ReadonlyArray<Ordering<A>>) => Ordering<A>;
1636
+ /**
1637
+ * Derives a lexicographical tuple ordering from positional `Ordering` comparators.
1638
+ *
1639
+ * @example
1640
+ * ```ts
1641
+ * const pairOrd = Ordering.tuple(Ordering.string, Ordering.number);
1642
+ * pairOrd(["a", 1], ["a", 2]); // negative
1643
+ * ```
1644
+ */
1645
+ tuple: <T extends readonly unknown[]>(...orderings: { [K in keyof T]: Ordering<T[K]>; }) => Ordering<T>;
1646
+ };
1647
+ //#endregion
1648
+ //#region src/Core/Pair.d.ts
1649
+ /**
1650
+ * Pair<A, B> represents a pair of two values that are always both present.
1651
+ * It is a typed alias for `readonly [A, B]`.
1652
+ *
1653
+ * Use Pair when two values always travel together through a pipeline and you
1654
+ * want to transform either or both sides without destructuring.
1655
+ *
1656
+ * @example
1657
+ * ```ts
1658
+ * import { Pair } from "@nlozgachev/pipelined/core";
1659
+ * import { pipe } from "@nlozgachev/pipelined/composition";
1660
+ *
1661
+ * const entry = Pair.from.pair("alice", 42);
1662
+ *
1663
+ * pipe(
1664
+ * entry,
1665
+ * Pair.mapFirst((name) => name.toUpperCase()),
1666
+ * Pair.mapSecond((score) => score * 2),
1667
+ * Pair.fold((name, score) => `${name}: ${score}`),
1668
+ * ); // "ALICE: 84"
1669
+ * ```
1670
+ */
1671
+ type Pair<A, B> = readonly [A, B];
1672
+ declare const Pair: {
1673
+ from: {
1674
+ /**
1675
+ * Creates a Pair from two values.
1676
+ *
1677
+ * @example
1678
+ * ```ts
1679
+ * Pair.from.pair("Paris", 2_161_000); // ["Paris", 2161000]
1680
+ * ```
1681
+ */
1682
+ pair: <A, B>(first: A, second: B) => Pair<A, B>;
1683
+ /**
1684
+ * Creates a Pair from a two-element array.
1685
+ *
1686
+ * @example
1687
+ * ```ts
1688
+ * Pair.from.array(["Paris", 2_161_000] as const); // ["Paris", 2161000]
1689
+ * ```
1690
+ */
1691
+ array: <A, B>(arr: readonly [A, B]) => Pair<A, B>;
1692
+ };
1693
+ /**
1694
+ * Returns the first value from the pair.
1695
+ *
1696
+ * @example
1697
+ * ```ts
1698
+ * Pair.first(Pair.from.pair("Paris", 2_161_000)); // "Paris"
1699
+ * ```
1700
+ */
1701
+ first: <A, B>(p: Pair<A, B>) => A;
1702
+ /**
1703
+ * Returns the second value from the pair.
1704
+ *
1705
+ * @example
1706
+ * ```ts
1707
+ * Pair.second(Pair.from.pair("Paris", 2_161_000)); // 2161000
1708
+ * ```
1709
+ */
1710
+ second: <A, B>(p: Pair<A, B>) => B;
1711
+ /**
1712
+ * Transforms the first value, leaving the second unchanged.
1713
+ *
1714
+ * @example
1715
+ * ```ts
1716
+ * pipe(Pair.from.pair("alice", 42), Pair.mapFirst((s) => s.toUpperCase())); // ["ALICE", 42]
1717
+ * ```
1718
+ */
1719
+ mapFirst: <A, C>(f: (a: A) => C) => <B>(p: Pair<A, B>) => Pair<C, B>;
1720
+ /**
1721
+ * Transforms the second value, leaving the first unchanged.
1722
+ *
1723
+ * @example
1724
+ * ```ts
1725
+ * pipe(Pair.from.pair("alice", 42), Pair.mapSecond((n) => n * 2)); // ["alice", 84]
1726
+ * ```
1727
+ */
1728
+ mapSecond: <B, D>(f: (b: B) => D) => <A>(p: Pair<A, B>) => Pair<A, D>;
1729
+ /**
1730
+ * Transforms both values independently in a single step.
1731
+ *
1732
+ * @example
1733
+ * ```ts
1734
+ * pipe(
1735
+ * Pair.from.pair("alice", 42),
1736
+ * Pair.mapBoth(
1737
+ * (name) => name.toUpperCase(),
1738
+ * (score) => score * 2,
1739
+ * ),
1740
+ * ); // ["ALICE", 84]
1741
+ * ```
1742
+ */
1743
+ mapBoth: <A, C, B, D>(onFirst: (a: A) => C, onSecond: (b: B) => D) => (p: Pair<A, B>) => Pair<C, D>;
1744
+ /**
1745
+ * Applies a binary function to both values, collapsing the pair into a single value.
1746
+ * Useful as the final step when consuming a pair in a pipeline.
1747
+ *
1748
+ * @example
1749
+ * ```ts
1750
+ * pipe(Pair.from.pair("Alice", 100), Pair.fold((name, score) => `${name}: ${score}`));
1751
+ * // "Alice: 100"
1752
+ * ```
1753
+ */
1754
+ fold: <A, B, C>(f: (a: A, b: B) => C) => (p: Pair<A, B>) => C;
1755
+ /**
1756
+ * Swaps the two values: `[A, B]` becomes `[B, A]`.
1757
+ *
1758
+ * @example
1759
+ * ```ts
1760
+ * Pair.swap(Pair.from.pair("key", 1)); // [1, "key"]
1761
+ * ```
1762
+ */
1763
+ swap: <A, B>(p: Pair<A, B>) => Pair<B, A>;
1764
+ to: {
1765
+ /**
1766
+ * Converts the pair to a heterogeneous readonly array `readonly (A | B)[]`.
1767
+ *
1768
+ * @example
1769
+ * ```ts
1770
+ * Pair.to.Array(Pair.from.pair("hello", 42)); // ["hello", 42]
1771
+ * ```
1772
+ */
1773
+ Array: <A, B>(p: Pair<A, B>) => readonly (A | B)[];
1774
+ };
1775
+ /**
1776
+ * Runs a side effect with both values without changing the pair.
1777
+ * Useful for logging or debugging in the middle of a pipeline.
1778
+ *
1779
+ * @example
1780
+ * ```ts
1781
+ * pipe(
1782
+ * Pair.from.pair("Paris", 2_161_000),
1783
+ * Pair.tap((city, pop) => console.log(`${city}: ${pop}`)),
1784
+ * Pair.mapSecond((n) => n / 1_000_000),
1785
+ * ); // logs "Paris: 2161000", returns ["Paris", 2.161]
1786
+ * ```
1787
+ */
1788
+ tap: <A, B>(f: (a: A, b: B) => void) => (p: Pair<A, B>) => Pair<A, B>;
1789
+ };
1790
+ //#endregion
1791
+ //#region src/Core/Predicate.d.ts
1792
+ /**
1793
+ * A boolean-valued function over a type `A`.
1794
+ *
1795
+ * A `Predicate<A>` is the simpler sibling of `Refinement<A, B>`: it tests whether a
1796
+ * value satisfies a condition at runtime but carries no compile-time narrowing guarantee.
1797
+ * Use it when you need to combine, negate, or adapt boolean checks as first-class values
1798
+ * and do not require the extra type information that a `Refinement` provides.
1799
+ *
1800
+ * Every `Refinement<A, B>` is a `Predicate<A>` — convert with `Predicate.from.Refinement`
1801
+ * when you want to compose a narrowing check alongside plain predicates.
1802
+ *
1803
+ * @example
1804
+ * ```ts
1805
+ * const isAdult: Predicate<number> = n => n >= 18;
1806
+ * const isRetired: Predicate<number> = n => n >= 65;
1807
+ *
1808
+ * const isWorkingAge: Predicate<number> = pipe(
1809
+ * isAdult,
1810
+ * Predicate.and(Predicate.not(isRetired))
1811
+ * );
1812
+ *
1813
+ * isWorkingAge(30); // true
1814
+ * isWorkingAge(15); // false
1815
+ * isWorkingAge(70); // false
1816
+ * ```
1817
+ */
1818
+ type Predicate<A> = (a: A) => boolean;
1819
+ declare const Predicate: {
1820
+ /**
1821
+ * Negates a predicate: the result passes exactly when the original fails.
1822
+ *
1823
+ * @example
1824
+ * ```ts
1825
+ * const isBlank: Predicate<string> = s => s.trim().length === 0;
1826
+ * const isNotBlank = Predicate.not(isBlank);
1827
+ *
1828
+ * isNotBlank("hello"); // true
1829
+ * isNotBlank(" "); // false
1830
+ * ```
1831
+ */
1832
+ not: <A>(p: Predicate<A>) => Predicate<A>;
1833
+ /**
1834
+ * Combines two predicates with logical AND: passes only when both hold.
1835
+ *
1836
+ * Data-last — the first predicate is the data being piped.
1837
+ *
1838
+ * @example
1839
+ * ```ts
1840
+ * const isPositive: Predicate<number> = n => n > 0;
1841
+ * const isEven: Predicate<number> = n => n % 2 === 0;
1842
+ *
1843
+ * const isPositiveEven: Predicate<number> = pipe(isPositive, Predicate.and(isEven));
1844
+ *
1845
+ * isPositiveEven(4); // true
1846
+ * isPositiveEven(3); // false — positive but odd
1847
+ * isPositiveEven(-2); // false — even but not positive
1848
+ * ```
1849
+ */
1850
+ and: <A>(second: Predicate<A>) => (first: Predicate<A>) => Predicate<A>;
1851
+ /**
1852
+ * Combines two predicates with logical OR: passes when either holds.
1853
+ *
1854
+ * Data-last — the first predicate is the data being piped.
1855
+ *
1856
+ * @example
1857
+ * ```ts
1858
+ * const isChild: Predicate<number> = n => n < 13;
1859
+ * const isSenior: Predicate<number> = n => n >= 65;
1860
+ *
1861
+ * const getsDiscount: Predicate<number> = pipe(isChild, Predicate.or(isSenior));
1862
+ *
1863
+ * getsDiscount(8); // true
1864
+ * getsDiscount(70); // true
1865
+ * getsDiscount(30); // false
1866
+ * ```
1867
+ */
1868
+ or: <A>(second: Predicate<A>) => (first: Predicate<A>) => Predicate<A>;
1869
+ /**
1870
+ * Adapts a `Predicate<A>` to work on a different input type `B` by applying `f`
1871
+ * to extract the relevant `A` from a `B` before running the check.
1872
+ *
1873
+ * Data-last — the predicate is the data being piped; `f` is the extractor.
1874
+ *
1875
+ * @example
1876
+ * ```ts
1877
+ * type User = { name: string; age: number };
1878
+ *
1879
+ * const isAdult: Predicate<number> = n => n >= 18;
1880
+ *
1881
+ * // Lift isAdult to work on Users by extracting the age field
1882
+ * const isAdultUser: Predicate<User> = pipe(
1883
+ * isAdult,
1884
+ * Predicate.using((u: User) => u.age)
1885
+ * );
1886
+ *
1887
+ * isAdultUser({ name: "Alice", age: 30 }); // true
1888
+ * isAdultUser({ name: "Bob", age: 15 }); // false
1889
+ * ```
1890
+ */
1891
+ using: <A, B>(f: (b: B) => A) => (p: Predicate<A>) => Predicate<B>;
1892
+ /**
1893
+ * Combines an array of predicates with AND: passes only when every predicate holds.
1894
+ * Returns `true` for an empty array (vacuous truth).
1895
+ *
1896
+ * @example
1897
+ * ```ts
1898
+ * const checks: Predicate<string>[] = [
1899
+ * s => s.length > 0,
1900
+ * s => s.length <= 100,
1901
+ * s => !s.includes("<"),
1902
+ * ];
1903
+ *
1904
+ * Predicate.all(checks)("hello"); // true
1905
+ * Predicate.all(checks)(""); // false — too short
1906
+ * Predicate.all(checks)("<b>"); // false — contains "<"
1907
+ * Predicate.all([])("anything"); // true
1908
+ * ```
1909
+ */
1910
+ all: <A>(predicates: ReadonlyArray<Predicate<A>>) => Predicate<A>;
1911
+ /**
1912
+ * Combines an array of predicates with OR: passes when at least one holds.
1913
+ * Returns `false` for an empty array.
1914
+ *
1915
+ * @example
1916
+ * ```ts
1917
+ * const acceptedFormats: Predicate<string>[] = [
1918
+ * s => s.endsWith(".jpg"),
1919
+ * s => s.endsWith(".png"),
1920
+ * s => s.endsWith(".webp"),
1921
+ * ];
1922
+ *
1923
+ * Predicate.any(acceptedFormats)("photo.jpg"); // true
1924
+ * Predicate.any(acceptedFormats)("photo.gif"); // false
1925
+ * Predicate.any([])("anything"); // false
1926
+ * ```
1927
+ */
1928
+ any: <A>(predicates: ReadonlyArray<Predicate<A>>) => Predicate<A>;
1929
+ from: {
1930
+ /**
1931
+ * Converts a `Refinement<A, B>` into a `Predicate<A>`, discarding the compile-time
1932
+ * narrowing. Use this when you want to combine a type guard with plain predicates
1933
+ * using `and`, `or`, or `all`.
1934
+ *
1935
+ * This is a zero-cost runtime type cast.
1936
+ *
1937
+ * @example
1938
+ * ```ts
1939
+ * const isString: Refinement<unknown, string> =
1940
+ * Refinement.from.predicate(x => typeof x === "string");
1941
+ *
1942
+ * const isShortString: Predicate<unknown> = pipe(
1943
+ * Predicate.from.Refinement(isString),
1944
+ * Predicate.and(x => (x as string).length < 10)
1945
+ * );
1946
+ *
1947
+ * isShortString("hi"); // true
1948
+ * isShortString("a very long string that exceeds ten characters"); // false
1949
+ * isShortString(42); // false
1950
+ * ```
1951
+ */
1952
+ Refinement: <A, B extends A>(r: Refinement<A, B>) => Predicate<A>;
1953
+ };
1954
+ /**
1955
+ * Performs declarative conditional branching over `[predicate, handler]` pairs,
1956
+ * returning the handler result of the first matching predicate or evaluating the fallback.
1957
+ *
1958
+ * @example
1959
+ * ```ts
1960
+ * const classifyNumber = Predicate.match(
1961
+ * [
1962
+ * [(n: number) => n < 0, () => "negative"],
1963
+ * [(n: number) => n === 0, () => "zero"],
1964
+ * ],
1965
+ * () => "positive",
1966
+ * );
1967
+ * classifyNumber(-5); // "negative"
1968
+ * ```
1969
+ */
1970
+ match: <A, B>(branches: ReadonlyArray<readonly [Predicate<A>, (a: A) => B]>, fallback: (a: A) => B) => (a: A) => B;
1971
+ };
1972
+ //#endregion
1973
+ //#region src/Core/Reader.d.ts
1974
+ /**
1975
+ * A computation that reads from a shared environment `R` and produces a value `A`.
1976
+ * Use Reader to thread a dependency (config, logger, DB pool) through a pipeline
1977
+ * without passing it explicitly to every function.
1978
+ *
1979
+ * @example
1980
+ * ```ts
1981
+ * type Config = { baseUrl: string; apiKey: string };
1982
+ *
1983
+ * const buildUrl = (path: string): Reader<Config, string> =>
1984
+ * (config) => `${config.baseUrl}${path}`;
1985
+ *
1986
+ * const withAuth = (url: string): Reader<Config, string> =>
1987
+ * (config) => `${url}?key=${config.apiKey}`;
1988
+ *
1989
+ * const fetchEndpoint = (path: string): Reader<Config, string> =>
1990
+ * pipe(
1991
+ * buildUrl(path),
1992
+ * Reader.chain(withAuth)
1993
+ * );
1994
+ *
1995
+ * // Inject the config once at the edge
1996
+ * fetchEndpoint("/users")(appConfig); // "https://api.example.com/users?key=secret"
1997
+ * ```
1998
+ */
1999
+ type Reader<R, A> = (env: R) => A;
2000
+ declare const Reader: {
2001
+ /**
2002
+ * Lifts a pure value into a Reader. The environment is ignored.
2003
+ *
2004
+ * @example
2005
+ * ```ts
2006
+ * const always42: Reader<Config, number> = Reader.resolve(42);
2007
+ * always42(anyConfig); // 42
2008
+ * ```
2009
+ */
2010
+ resolve: <R, A>(value: A) => Reader<R, A>;
2011
+ /**
2012
+ * Returns the full environment as the result.
2013
+ * The fundamental way to access the environment in a pipeline.
2014
+ *
2015
+ * @example
2016
+ * ```ts
2017
+ * pipe(
2018
+ * Reader.ask<Config>(),
2019
+ * Reader.map(config => config.baseUrl)
2020
+ * )(appConfig); // "https://api.example.com"
2021
+ * ```
2022
+ */
2023
+ ask: <R>() => Reader<R, R>;
2024
+ /**
2025
+ * Projects a value from the environment using a selector function.
2026
+ * Equivalent to `pipe(Reader.ask(), Reader.map(f))` but more direct.
2027
+ *
2028
+ * @example
2029
+ * ```ts
2030
+ * const getBaseUrl: Reader<Config, string> = Reader.asks(c => c.baseUrl);
2031
+ * getBaseUrl(appConfig); // "https://api.example.com"
2032
+ * ```
2033
+ */
2034
+ asks: <R, A>(f: (env: R) => A) => Reader<R, A>;
2035
+ /**
2036
+ * Transforms the value produced by a Reader.
2037
+ *
2038
+ * @example
2039
+ * ```ts
2040
+ * pipe(
2041
+ * Reader.asks((c: Config) => c.baseUrl),
2042
+ * Reader.map(url => url.toUpperCase())
2043
+ * )(appConfig); // "HTTPS://API.EXAMPLE.COM"
2044
+ * ```
2045
+ */
2046
+ map: <R, A, B>(f: (a: A) => B) => (data: Reader<R, A>) => Reader<R, B>;
2047
+ /**
2048
+ * Sequences two Readers. Both see the same environment.
2049
+ * The output of the first is passed to `f`, which returns the next Reader.
2050
+ *
2051
+ * @example
2052
+ * ```ts
2053
+ * const buildUrl = (path: string): Reader<Config, string> =>
2054
+ * Reader.asks(c => `${c.baseUrl}${path}`);
2055
+ *
2056
+ * const addAuth = (url: string): Reader<Config, string> =>
2057
+ * Reader.asks(c => `${url}?key=${c.apiKey}`);
2058
+ *
2059
+ * pipe(
2060
+ * buildUrl("/items"),
2061
+ * Reader.chain(addAuth)
2062
+ * )(appConfig); // "https://api.example.com/items?key=secret"
2063
+ * ```
2064
+ */
2065
+ chain: <R, A, B>(f: (a: A) => Reader<R, B>) => (data: Reader<R, A>) => Reader<R, B>;
2066
+ /**
2067
+ * Applies a function wrapped in a Reader to a value wrapped in a Reader.
2068
+ * Both Readers see the same environment.
2069
+ *
2070
+ * @example
2071
+ * ```ts
2072
+ * const add = (a: number) => (b: number) => a + b;
2073
+ * pipe(
2074
+ * Reader.resolve<Config, typeof add>(add),
2075
+ * Reader.ap(Reader.asks(c => c.timeout)),
2076
+ * Reader.ap(Reader.resolve(5))
2077
+ * )(appConfig);
2078
+ * ```
2079
+ */
2080
+ ap: <R, A>(arg: Reader<R, A>) => <B>(data: Reader<R, (a: A) => B>) => Reader<R, B>;
2081
+ /**
2082
+ * Executes a side effect on the produced value without changing the Reader.
2083
+ * Useful for logging or debugging inside a pipeline.
2084
+ *
2085
+ * @example
2086
+ * ```ts
2087
+ * pipe(
2088
+ * buildUrl("/users"),
2089
+ * Reader.tap(url => console.log("Requesting:", url)),
2090
+ * Reader.chain(addAuth)
2091
+ * )(appConfig);
2092
+ * ```
2093
+ */
2094
+ tap: <R, A>(f: (a: A) => void) => (data: Reader<R, A>) => Reader<R, A>;
2095
+ /**
2096
+ * Adapts a Reader to work with a different (typically wider) environment
2097
+ * by transforming the environment before passing it to the Reader.
2098
+ * This lets you compose Readers that expect different environments.
2099
+ *
2100
+ * @example
2101
+ * ```ts
2102
+ * type AppEnv = { db: DbPool; config: Config; logger: Logger };
2103
+ *
2104
+ * // buildUrl only needs Config
2105
+ * const buildUrl: Reader<Config, string> = Reader.asks(c => c.baseUrl);
2106
+ *
2107
+ * // Zoom in from AppEnv to Config
2108
+ * const buildUrlFromApp: Reader<AppEnv, string> =
2109
+ * pipe(buildUrl, Reader.local((env: AppEnv) => env.config));
2110
+ *
2111
+ * buildUrlFromApp(appEnv); // works with the full AppEnv
2112
+ * ```
2113
+ */
2114
+ local: <R2, R>(f: (env: R2) => R) => <A>(data: Reader<R, A>) => Reader<R2, A>;
2115
+ /**
2116
+ * Runs a Reader by supplying the environment. Use this at the edge of your
2117
+ * program where the environment is available.
2118
+ *
2119
+ * @example
2120
+ * ```ts
2121
+ * pipe(
2122
+ * buildEndpoint("/users"),
2123
+ * Reader.run(appConfig)
2124
+ * ); // "https://api.example.com/users?key=secret"
2125
+ * ```
2126
+ */
2127
+ run: <R>(env: R) => <A>(data: Reader<R, A>) => A;
2128
+ /**
2129
+ * Lifts a Reader value into an accumulator object.
2130
+ *
2131
+ * @example
2132
+ * ```ts
2133
+ * pipe(Reader.resolve(42), Reader.bindTo("value")); // Reader({ value: 42 })
2134
+ * ```
2135
+ */
2136
+ bindTo: <K extends string>(key: K) => <R, A>(data: Reader<R, A>) => Reader<R, { [P in K]: A; }>;
2137
+ /**
2138
+ * Evaluates a new Reader using the current accumulator and attaches the output to a new key.
2139
+ *
2140
+ * @example
2141
+ * ```ts
2142
+ * pipe(
2143
+ * Reader.resolve({ a: 1 }),
2144
+ * Reader.bind("b", ({ a }) => Reader.resolve(a + 1))
2145
+ * ); // Reader({ a: 1, b: 2 })
2146
+ * ```
2147
+ */
2148
+ bind: <K extends string, R, A, B>(key: K, f: (a: A) => Reader<R, B>) => (data: Reader<R, A>) => Reader<R, A & { [P in K]: B; }>;
2149
+ };
2150
+ //#endregion
2151
+ //#region src/Core/Refinement.d.ts
2152
+ /**
2153
+ * A function from `A` to `A is B` — a type predicate paired with a runtime check.
2154
+ *
2155
+ * A `Refinement<A, B>` proves at compile time that a value of type `A` is actually
2156
+ * the narrower type `B extends A`, backed by a runtime boolean test. Use it to
2157
+ * express domain invariants (non-empty strings, positive numbers, valid emails) as
2158
+ * first-class, composable values rather than one-off type guards scattered across
2159
+ * the codebase.
2160
+ *
2161
+ * @example
2162
+ * ```ts
2163
+ * type NonEmptyString = string & { readonly _tag: "NonEmptyString" };
2164
+ *
2165
+ * const isNonEmpty: Refinement<string, NonEmptyString> =
2166
+ * Refinement.from.predicate(s => s.length > 0);
2167
+ *
2168
+ * pipe(
2169
+ * "hello",
2170
+ * Refinement.to.Maybe(isNonEmpty)
2171
+ * ); // Some("hello")
2172
+ * ```
2173
+ */
2174
+ type Refinement<A, B extends A> = (a: A) => a is B;
2175
+ declare const Refinement: {
2176
+ from: {
2177
+ /**
2178
+ * Creates a `Refinement<A, B>` from a plain boolean predicate.
2179
+ *
2180
+ * This is an unsafe cast — the caller is responsible for ensuring that the
2181
+ * predicate truly characterises values of type `B`. Use this only when
2182
+ * bootstrapping a new refinement; prefer `compose`, `and`, or `or` to build
2183
+ * derived refinements from existing ones.
2184
+ *
2185
+ * @example
2186
+ * ```ts
2187
+ * type PositiveNumber = number & { readonly _tag: "PositiveNumber" };
2188
+ *
2189
+ * const isPositive: Refinement<number, PositiveNumber> =
2190
+ * Refinement.from.predicate(n => n > 0);
2191
+ * ```
2192
+ */
2193
+ predicate: <A, B extends A>(f: (a: A) => boolean) => Refinement<A, B>;
2194
+ };
2195
+ /**
2196
+ * Chains two refinements: if `ab` narrows `A` to `B` and `bc` narrows `B` to `C`,
2197
+ * the result narrows `A` directly to `C`.
2198
+ *
2199
+ * Data-last — the first refinement `ab` is the data being piped.
2200
+ *
2201
+ * @example
2202
+ * ```ts
2203
+ * type NonEmptyString = string & { readonly _tag: "NonEmpty" };
2204
+ * type TrimmedString = NonEmptyString & { readonly _tag: "Trimmed" };
2205
+ *
2206
+ * const isNonEmpty: Refinement<string, NonEmptyString> =
2207
+ * Refinement.from.predicate(s => s.length > 0);
2208
+ * const isTrimmed: Refinement<NonEmptyString, TrimmedString> =
2209
+ * Refinement.from.predicate(s => s === s.trim());
2210
+ *
2211
+ * const isNonEmptyTrimmed: Refinement<string, TrimmedString> = pipe(
2212
+ * isNonEmpty,
2213
+ * Refinement.compose(isTrimmed)
2214
+ * );
2215
+ * ```
2216
+ */
2217
+ compose: <A, B extends A, C extends B>(bc: Refinement<B, C>) => (ab: Refinement<A, B>) => Refinement<A, C>;
2218
+ /**
2219
+ * Intersects two refinements: the result narrows `A` to `B & C`, passing only
2220
+ * when both refinements hold simultaneously.
2221
+ *
2222
+ * Data-last — the first refinement is the data being piped.
2223
+ *
2224
+ * @example
2225
+ * ```ts
2226
+ * const isString: Refinement<unknown, string> = Refinement.from.predicate(x => typeof x === "string");
2227
+ * const isNonEmpty: Refinement<unknown, { length: number }> =
2228
+ * Refinement.from.predicate(x => (x as any).length > 0);
2229
+ *
2230
+ * const isNonEmptyString = pipe(isString, Refinement.and(isNonEmpty));
2231
+ * isNonEmptyString("hi"); // true
2232
+ * isNonEmptyString(""); // false
2233
+ * ```
2234
+ */
2235
+ and: <A, C extends A>(second: Refinement<A, C>) => <B extends A>(first: Refinement<A, B>) => Refinement<A, B & C>;
2236
+ /**
2237
+ * Unions two refinements: the result narrows `A` to `B | C`, passing when either
2238
+ * refinement holds.
2239
+ *
2240
+ * Data-last — the first refinement is the data being piped.
2241
+ *
2242
+ * @example
2243
+ * ```ts
2244
+ * const isString: Refinement<unknown, string> = Refinement.from.predicate(x => typeof x === "string");
2245
+ * const isNumber: Refinement<unknown, number> = Refinement.from.predicate(x => typeof x === "number");
2246
+ *
2247
+ * const isStringOrNumber = pipe(isString, Refinement.or(isNumber));
2248
+ * isStringOrNumber("hi"); // true
2249
+ * isStringOrNumber(42); // true
2250
+ * isStringOrNumber(true); // false
2251
+ * ```
2252
+ */
2253
+ or: <A, C extends A>(second: Refinement<A, C>) => <B extends A>(first: Refinement<A, B>) => Refinement<A, B | C>;
2254
+ to: {
2255
+ /**
2256
+ * Converts a `Refinement<A, B>` into a function `(a: A) => Maybe<B>`.
2257
+ *
2258
+ * Returns `Some(a)` when the refinement holds, `None` otherwise. Useful for
2259
+ * integrating runtime validation into a `Maybe`-based pipeline.
2260
+ *
2261
+ * @example
2262
+ * ```ts
2263
+ * type PositiveNumber = number & { readonly _tag: "Positive" };
2264
+ * const isPositive: Refinement<number, PositiveNumber> =
2265
+ * Refinement.from.predicate(n => n > 0);
2266
+ *
2267
+ * pipe(-1, Refinement.to.Maybe(isPositive)); // None
2268
+ * pipe(42, Refinement.to.Maybe(isPositive)); // Some(42)
2269
+ * ```
2270
+ */
2271
+ Maybe: <A, B extends A>(r: Refinement<A, B>) => (a: A) => Maybe<B>;
2272
+ /**
2273
+ * Converts a `Refinement<A, B>` into a function `(a: A) => Result<E, B>`.
2274
+ *
2275
+ * Returns `Ok(a)` when the refinement holds, `Err(onFail(a))` otherwise. Use
2276
+ * this to surface validation failures as typed errors inside a `Result` pipeline.
2277
+ *
2278
+ * @example
2279
+ * ```ts
2280
+ * type NonEmptyString = string & { readonly _tag: "NonEmpty" };
2281
+ * const isNonEmpty: Refinement<string, NonEmptyString> =
2282
+ * Refinement.from.predicate(s => s.length > 0);
2283
+ *
2284
+ * pipe("", Refinement.to.Result(isNonEmpty, () => "must not be empty")); // Err(...)
2285
+ * pipe("hi", Refinement.to.Result(isNonEmpty, () => "must not be empty")); // Ok("hi")
2286
+ * ```
2287
+ */
2288
+ Result: <A, B extends A, E>(r: Refinement<A, B>, onFail: (a: A) => E) => (a: A) => Result<E, B>;
2289
+ };
2290
+ };
2291
+ //#endregion
2292
+ //#region src/Core/RemoteData.d.ts
2293
+ /**
2294
+ * RemoteData represents the state of an async data fetch.
2295
+ * It has four states: NotAsked, Loading, Failure, and Success.
2296
+ *
2297
+ * Use RemoteData to model data fetching states explicitly,
2298
+ * replacing the common `{ data: T | null; loading: boolean; error: Error | null }` pattern.
2299
+ *
2300
+ * @example
2301
+ * ```ts
2302
+ * const renderUser = pipe(
2303
+ * userData,
2304
+ * RemoteData.match({
2305
+ * notAsked: () => "Click to load",
2306
+ * loading: () => "Loading...",
2307
+ * failure: e => `Error: ${e.message}`,
2308
+ * success: user => `Hello, ${user.name}!`
2309
+ * })
2310
+ * );
2311
+ * ```
2312
+ */
2313
+ type RemoteData<E, A> = NotAsked | Loading | Failure<E> | Success<A>;
2314
+ type NotAsked = WithKind<"NotAsked">;
2315
+ type Loading = WithKind<"Loading">;
2316
+ type Failure<E> = WithKind<"Failure"> & WithError<E>;
2317
+ type Success<A> = WithKind<"Success"> & WithValue<A>;
2318
+ declare const RemoteData: {
2319
+ make: {
2320
+ /**
2321
+ * Creates a NotAsked RemoteData.
2322
+ *
2323
+ * @example
2324
+ * ```ts
2325
+ * RemoteData.make.notAsked(); // NotAsked
2326
+ * ```
2327
+ */
2328
+ notAsked: () => NotAsked;
2329
+ /**
2330
+ * Creates a Loading RemoteData.
2331
+ *
2332
+ * @example
2333
+ * ```ts
2334
+ * RemoteData.make.loading(); // Loading
2335
+ * ```
2336
+ */
2337
+ loading: () => Loading;
2338
+ /**
2339
+ * Creates a Failure RemoteData with the given error.
2340
+ *
2341
+ * @example
2342
+ * ```ts
2343
+ * RemoteData.make.failure("Network error"); // Failure("Network error")
2344
+ * ```
2345
+ */
2346
+ failure: <E>(error: E) => Failure<E>;
2347
+ /**
2348
+ * Creates a Success RemoteData with the given value.
2349
+ *
2350
+ * @example
2351
+ * ```ts
2352
+ * RemoteData.make.success(42); // Success(42)
2353
+ * ```
2354
+ */
2355
+ success: <A>(value: A) => Success<A>;
2356
+ };
2357
+ is: {
2358
+ /**
2359
+ * Type guard that checks if a RemoteData is NotAsked.
2360
+ *
2361
+ * @example
2362
+ * ```ts
2363
+ * const data = RemoteData.make.notAsked();
2364
+ * if (RemoteData.is.notAsked(data)) {
2365
+ * console.log("Data fetch not initiated");
2366
+ * }
2367
+ * ```
2368
+ */
2369
+ notAsked: <E, A>(data: RemoteData<E, A>) => data is NotAsked;
2370
+ /**
2371
+ * Type guard that checks if a RemoteData is Loading.
2372
+ *
2373
+ * @example
2374
+ * ```ts
2375
+ * const data = RemoteData.make.loading();
2376
+ * if (RemoteData.is.loading(data)) {
2377
+ * console.log("Data is loading");
2378
+ * }
2379
+ * ```
2380
+ */
2381
+ loading: <E, A>(data: RemoteData<E, A>) => data is Loading;
2382
+ /**
2383
+ * Type guard that checks if a RemoteData is Failure.
2384
+ *
2385
+ * @example
2386
+ * ```ts
2387
+ * const data = RemoteData.make.failure("Failed");
2388
+ * if (RemoteData.is.failure(data)) {
2389
+ * console.log(data.error); // "Failed"
2390
+ * }
2391
+ * ```
2392
+ */
2393
+ failure: <E, A>(data: RemoteData<E, A>) => data is Failure<E>;
2394
+ /**
2395
+ * Type guard that checks if a RemoteData is Success.
2396
+ *
2397
+ * @example
2398
+ * ```ts
2399
+ * const data = RemoteData.make.success(42);
2400
+ * if (RemoteData.is.success(data)) {
2401
+ * console.log(data.value); // 42
2402
+ * }
2403
+ * ```
2404
+ */
2405
+ success: <E, A>(data: RemoteData<E, A>) => data is Success<A>;
2406
+ };
2407
+ /**
2408
+ * Transforms the success value inside a RemoteData.
2409
+ *
2410
+ * @example
2411
+ * ```ts
2412
+ * pipe(RemoteData.make.success(5), RemoteData.map(n => n * 2)); // Success(10)
2413
+ * pipe(RemoteData.make.loading(), RemoteData.map(n => n * 2)); // Loading
2414
+ * ```
2415
+ */
2416
+ map: <A, B>(f: (a: A) => B) => <E>(data: RemoteData<E, A>) => RemoteData<E, B>;
2417
+ /**
2418
+ * Transforms the error value inside a RemoteData.
2419
+ *
2420
+ * @example
2421
+ * ```ts
2422
+ * pipe(RemoteData.make.failure("oops"), RemoteData.mapError(e => e.toUpperCase())); // Failure("OOPS")
2423
+ * ```
2424
+ */
2425
+ mapError: <E, F>(f: (e: E) => F) => <A>(data: RemoteData<E, A>) => RemoteData<F, A>;
2426
+ /**
2427
+ * Chains RemoteData computations. If the input is Success, passes the value to f.
2428
+ * Otherwise, propagates the current state.
2429
+ *
2430
+ * @example
2431
+ * ```ts
2432
+ * pipe(
2433
+ * RemoteData.make.success(5),
2434
+ * RemoteData.chain(n => n > 0 ? RemoteData.make.success(n) : RemoteData.make.failure("negative"))
2435
+ * );
2436
+ * ```
2437
+ */
2438
+ chain: <E2, A, B>(f: (a: A) => RemoteData<E2, B>) => <E1 = never>(data: RemoteData<E1, A>) => RemoteData<E1 | E2, B>;
2439
+ /**
2440
+ * Applies a function wrapped in a RemoteData to a value wrapped in a RemoteData.
2441
+ *
2442
+ * @example
2443
+ * ```ts
2444
+ * const add = (a: number) => (b: number) => a + b;
2445
+ * pipe(
2446
+ * RemoteData.make.success(add),
2447
+ * RemoteData.ap(RemoteData.make.success(5)),
2448
+ * RemoteData.ap(RemoteData.make.success(3))
2449
+ * ); // Success(8)
2450
+ * ```
2451
+ */
2452
+ ap: <E, A>(arg: RemoteData<E, A>) => <B>(data: RemoteData<E, (a: A) => B>) => RemoteData<E, B>;
2453
+ /**
2454
+ * Extracts the value from a RemoteData by providing handlers for all four cases.
2455
+ *
2456
+ * @example
2457
+ * ```ts
2458
+ * pipe(
2459
+ * userData,
2460
+ * RemoteData.fold(
2461
+ * e => `Error: ${e}`,
2462
+ * () => "Not asked",
2463
+ * () => "Loading...",
2464
+ * value => `Got: ${value}`
2465
+ * )
2466
+ * );
2467
+ * ```
2468
+ */
2469
+ fold: <E, A, B>(onFailure: (e: E) => B, onNotAsked: () => B, onLoading: () => B, onSuccess: (a: A) => B) => (data: RemoteData<E, A>) => B;
2470
+ /**
2471
+ * Pattern matches on a RemoteData, returning the result of the matching case.
2472
+ *
2473
+ * @example
2474
+ * ```ts
2475
+ * pipe(
2476
+ * userData,
2477
+ * RemoteData.match({
2478
+ * notAsked: () => "Click to load",
2479
+ * loading: () => "Loading...",
2480
+ * failure: e => `Error: ${e}`,
2481
+ * success: user => `Hello, ${user.name}!`
2482
+ * })
2483
+ * );
2484
+ * ```
2485
+ */
2486
+ match: <E, A, B>(cases: {
2487
+ notAsked: () => B;
2488
+ loading: () => B;
2489
+ failure: (e: E) => B;
2490
+ success: (a: A) => B;
2491
+ }) => (data: RemoteData<E, A>) => B;
2492
+ /**
2493
+ * Returns the success value or a default value if the RemoteData is not Success.
2494
+ * The default can be a different type, widening the result to `A | B`.
2495
+ *
2496
+ * @example
2497
+ * ```ts
2498
+ * pipe(RemoteData.make.success(5), RemoteData.getOrElse(() => 0)); // 5
2499
+ * pipe(RemoteData.make.loading(), RemoteData.getOrElse(() => 0)); // 0
2500
+ * pipe(RemoteData.make.loading<string, number>(), RemoteData.getOrElse(() => null)); // null — typed as number | null
2501
+ * ```
2502
+ */
2503
+ getOrElse: <B>(defaultValue: () => B) => <E, A>(data: RemoteData<E, A>) => A | B;
2504
+ /**
2505
+ * Executes a side effect on the success value without changing the RemoteData.
2506
+ *
2507
+ * @example
2508
+ * ```ts
2509
+ * pipe(
2510
+ * RemoteData.make.success(5),
2511
+ * RemoteData.tap(n => console.log("Value:", n)),
2512
+ * RemoteData.map(n => n * 2)
2513
+ * );
2514
+ * ```
2515
+ */
2516
+ tap: <E, A>(f: (a: A) => void) => (data: RemoteData<E, A>) => RemoteData<E, A>;
2517
+ /**
2518
+ * Executes a side effect on the failure error without changing the RemoteData.
2519
+ * Useful for logging errors.
2520
+ *
2521
+ * @example
2522
+ * ```ts
2523
+ * pipe(
2524
+ * RemoteData.make.failure("not found"),
2525
+ * RemoteData.tapError(e => console.error("fetch failed:", e)),
2526
+ * RemoteData.map(render)
2527
+ * );
2528
+ * ```
2529
+ */
2530
+ tapError: <E, A>(f: (e: E) => void) => (data: RemoteData<E, A>) => RemoteData<E, A>;
2531
+ /**
2532
+ * Recovers from a Failure state by providing a fallback RemoteData.
2533
+ * The fallback can produce a different success type, widening the result to `RemoteData<E, A | B>`.
2534
+ */
2535
+ recover: <E, B>(fallback: (e: E) => RemoteData<E, B>) => <A>(data: RemoteData<E, A>) => RemoteData<E, A | B>;
2536
+ to: {
2537
+ /**
2538
+ * Converts a RemoteData to a Maybe.
2539
+ * Success becomes Some, all other states become None.
2540
+ */
2541
+ Maybe: <E, A>(data: RemoteData<E, A>) => Maybe<A>;
2542
+ /**
2543
+ * Converts a RemoteData to a Result.
2544
+ * Success becomes Ok, Failure becomes Err.
2545
+ * NotAsked and Loading become Err with the provided fallback error.
2546
+ *
2547
+ * @example
2548
+ * ```ts
2549
+ * pipe(
2550
+ * RemoteData.make.success(42),
2551
+ * RemoteData.to.Result(() => "not loaded")
2552
+ * ); // Ok(42)
2553
+ * ```
2554
+ */
2555
+ Result: <E>(onNotReady: () => E) => <A>(data: RemoteData<E, A>) => Result<E, A>;
2556
+ };
2557
+ from: {
2558
+ /**
2559
+ * Converts a Result to a RemoteData.
2560
+ * Ok becomes Success, Err becomes Failure.
2561
+ *
2562
+ * @example
2563
+ * ```ts
2564
+ * const result = await Task.Result.tryCatch(() => loadUser(), { onError: String })();
2565
+ * setState(RemoteData.from.Result(result)); // Success(user) or Failure(msg)
2566
+ * ```
2567
+ */
2568
+ Result: <E, A>(data: Result<E, A>) => RemoteData<E, A>;
2569
+ /**
2570
+ * Converts a Maybe to a RemoteData.
2571
+ * Some becomes Success, None becomes Failure using the onNone error producer.
2572
+ *
2573
+ * @example
2574
+ * ```ts
2575
+ * pipe(Maybe.make.some(user), RemoteData.from.Maybe(() => "not found")); // Success(user)
2576
+ * pipe(Maybe.make.none(), RemoteData.from.Maybe(() => "not found")); // Failure("not found")
2577
+ * ```
2578
+ */
2579
+ Maybe: <E>(onNone: () => E) => <A>(data: Maybe<A>) => RemoteData<E, A>;
2580
+ };
2581
+ /**
2582
+ * Filters a `Success` value. When the predicate passes, the value is kept. When it fails,
2583
+ * `Success` becomes `Failure` using the error produced by `onFalse`. All other states pass through unchanged.
2584
+ *
2585
+ * @example
2586
+ * ```ts
2587
+ * RemoteData.filter(n => n > 0, n => `${n} is not a valid price`)(RemoteData.make.success(9.99));
2588
+ * // Success(9.99)
2589
+ * RemoteData.filter(n => n > 0, n => `${n} is not a valid price`)(RemoteData.make.success(-1));
2590
+ * // Failure("-1 is not a valid price")
2591
+ * RemoteData.filter(n => n > 0, () => "error")(RemoteData.make.loading()); // Loading
2592
+ * ```
2593
+ */
2594
+ filter: <E, A>(pred: (a: A) => boolean, onFalse: (a: A) => E) => (data: RemoteData<E, A>) => RemoteData<E, A>;
2595
+ };
2596
+ //#endregion
2597
+ //#region src/Core/Resource.d.ts
2598
+ /**
2599
+ * A Resource pairs an async acquisition step with a guaranteed cleanup step.
2600
+ *
2601
+ * Use it whenever something must be explicitly closed, released, or torn down
2602
+ * after you are done with it — database connections, file handles, locks,
2603
+ * temporary directories, or any object with a lifecycle.
2604
+ *
2605
+ * The key guarantee: `release` always runs after `Resource.use`, even when
2606
+ * the work function returns an error. If `acquire` itself fails, `release` is
2607
+ * skipped — there is nothing to clean up.
2608
+ *
2609
+ * Build a Resource with `Resource.from.handlers` or `Resource.from.Task`, then run it
2610
+ * with `Resource.use`.
2611
+ *
2612
+ * @example
2613
+ * ```ts
2614
+ * const dbResource = Resource.from.handlers(
2615
+ * Task.Result.tryCatch(() => openConnection(config), { onError: (e) => new DbError(e) }),
2616
+ * (conn) => Task.tryCatch(() => conn.close(), { onError: () => {} })
2617
+ * );
2618
+ *
2619
+ * const result = await pipe(
2620
+ * dbResource,
2621
+ * Resource.use((conn) => queryUser(conn, userId))
2622
+ * )();
2623
+ * // conn.close() is called whether queryUser succeeds or fails
2624
+ * ```
2625
+ */
2626
+ type Resource<E, A> = {
2627
+ readonly acquire: Task.Result<E, A>;
2628
+ readonly release: (a: A) => Task<void>;
2629
+ };
2630
+ declare const Resource: {
2631
+ from: {
2632
+ /**
2633
+ * Creates a Resource from an acquire operation that may fail and a release function.
2634
+ *
2635
+ * @example
2636
+ * ```ts
2637
+ * const fileResource = Resource.from.handlers(
2638
+ * Task.Result.tryCatch(() => fs.promises.open("data.csv", "r"), { onError: toFileError }),
2639
+ * (handle) => Task.tryCatch(() => handle.close(), { onError: () => {} })
2640
+ * );
2641
+ * ```
2642
+ */
2643
+ handlers: <E, A>(acquire: Task.Result<E, A>, release: (a: A) => Task<void>) => Resource<E, A>;
2644
+ /**
2645
+ * Creates a Resource from an acquire operation that cannot fail.
2646
+ * Use this when opening the resource is guaranteed to succeed, such as
2647
+ * in-memory locks, counters, or timers.
2648
+ *
2649
+ * @example
2650
+ * ```ts
2651
+ * const timerResource = Resource.from.Task<never, Timer>(
2652
+ * Task.tryCatch(() => Promise.resolve(startTimer()), { onError: () => defaultTimer }),
2653
+ * (timer) => Task.tryCatch(() => Promise.resolve(timer.stop()), { onError: () => {} })
2654
+ * );
2655
+ * ```
2656
+ */
2657
+ Task: <E, A>(acquire: Task<A>, release: (a: A) => Task<void>) => Resource<E, A>;
2658
+ };
2659
+ /**
2660
+ * Acquires the resource, runs `f` with it, then releases it.
2661
+ *
2662
+ * Release always runs, even when `f` returns an error.
2663
+ * If acquire fails, `f` and release are both skipped and the error is returned.
2664
+ *
2665
+ * @example
2666
+ * ```ts
2667
+ * const rows = await pipe(
2668
+ * dbResource,
2669
+ * Resource.use((conn) => runQuery(conn, "SELECT * FROM users"))
2670
+ * )();
2671
+ * // conn is closed whether the query succeeds or fails
2672
+ * ```
2673
+ */
2674
+ use: <E, A, B>(f: (a: A) => Task.Result<E, B>) => (resource: Resource<E, A>) => Task.Result<E, B>;
2675
+ /**
2676
+ * Acquires two resources in sequence and presents them as a tuple.
2677
+ * Resources are released in reverse order: the second is released before the first.
2678
+ *
2679
+ * If the second resource fails to acquire, the first is released immediately
2680
+ * before returning the error.
2681
+ *
2682
+ * @example
2683
+ * ```ts
2684
+ * const combined = Resource.combine(dbResource, cacheResource);
2685
+ *
2686
+ * const result = await pipe(
2687
+ * combined,
2688
+ * Resource.use(([conn, cache]) => lookupWithFallback(conn, cache, userId))
2689
+ * )();
2690
+ * ```
2691
+ */
2692
+ combine: <E, A, B>(resourceA: Resource<E, A>, resourceB: Resource<E, B>) => Resource<E, readonly [A, B]>;
2693
+ };
2694
+ //#endregion
2695
+ //#region src/Core/Result.d.ts
2696
+ /**
2697
+ * Result represents a value that can be one of two types: a success (Ok) or a failure (Err).
2698
+ * Use Result when an operation can fail with a meaningful error value.
2699
+ *
2700
+ * @example
2701
+ * ```ts
2702
+ * const divide = (a: number, b: number): Result<string, number> =>
2703
+ * b === 0 ? Result.make.err("Division by zero") : Result.make.ok(a / b);
2704
+ *
2705
+ * pipe(
2706
+ * divide(10, 2),
2707
+ * Result.map(n => n * 2),
2708
+ * Result.getOrElse(() => 0)
2709
+ * ); // 10
2710
+ * ```
2711
+ */
2712
+ type Result<E, A> = Ok$1<A> | Err$1<E>;
2713
+ type Ok$1<A> = WithKind<"Ok"> & WithValue<A>;
2714
+ type Err$1<E> = WithKind<"Err"> & WithError<E>;
2715
+ declare const Result: {
2716
+ make: {
2717
+ /**
2718
+ * Creates a successful Result with the given value.
2719
+ *
2720
+ * @example
2721
+ * ```ts
2722
+ * Result.make.ok(42); // Ok(42)
2723
+ * ```
2724
+ */
2725
+ ok: <A>(value: A) => Ok$1<A>;
2726
+ /**
2727
+ * Creates a failed Result with the given error.
2728
+ *
2729
+ * @example
2730
+ * ```ts
2731
+ * Result.make.err("Error message"); // Err("Error message")
2732
+ * ```
2733
+ */
2734
+ err: <E>(e: E) => Err$1<E>;
2735
+ };
2736
+ is: {
2737
+ /**
2738
+ * Type guard that checks if a Result is Ok.
2739
+ *
2740
+ * @example
2741
+ * ```ts
2742
+ * const res = Result.make.ok(42);
2743
+ * if (Result.is.ok(res)) {
2744
+ * console.log(res.value); // 42
2745
+ * }
2746
+ * ```
2747
+ */
2748
+ ok: <E, A>(data: Result<E, A>) => data is Ok$1<A>;
2749
+ /**
2750
+ * Type guard that checks if a Result is Err.
2751
+ *
2752
+ * @example
2753
+ * ```ts
2754
+ * const res = Result.make.err("failed");
2755
+ * if (Result.is.err(res)) {
2756
+ * console.log(res.error); // "failed"
2757
+ * }
2758
+ * ```
2759
+ */
2760
+ err: <E, A>(data: Result<E, A>) => data is Err$1<E>;
2761
+ };
2762
+ /**
2763
+ * Creates a Result from a synchronous thunk that may throw.
2764
+ * Catches any errors and transforms them using the `onError` function.
2765
+ *
2766
+ * @example
2767
+ * ```ts
2768
+ * const result = Result.tryCatch(
2769
+ * () => JSON.parse(rawString),
2770
+ * { onError: (e) => `Parse error: ${e}` }
2771
+ * );
2772
+ * ```
2773
+ */
2774
+ tryCatch: <E, A>(f: () => A, options: {
2775
+ onError: (e: unknown) => E;
2776
+ }) => Result<E, A>;
2777
+ /**
2778
+ * Transforms the success value inside a Result.
2779
+ *
2780
+ * @example
2781
+ * ```ts
2782
+ * pipe(Result.make.ok(5), Result.map(n => n * 2)); // Ok(10)
2783
+ * pipe(Result.make.err("error"), Result.map(n => n * 2)); // Err("error")
2784
+ * ```
2785
+ */
2786
+ map: <E, A, B>(f: (a: A) => B) => (data: Result<E, A>) => Result<E, B>;
2787
+ /**
2788
+ * Transforms the error value inside a Result.
2789
+ *
2790
+ * @example
2791
+ * ```ts
2792
+ * pipe(Result.make.err("oops"), Result.mapError(e => e.toUpperCase())); // Err("OOPS")
2793
+ * ```
2794
+ */
2795
+ mapError: <E, F, A>(f: (e: E) => F) => (data: Result<E, A>) => Result<F, A>;
2796
+ /**
2797
+ * Chains Result computations. If the first is Ok, passes the value to f.
2798
+ * If the first is Err, propagates the error.
2799
+ *
2800
+ * @example
2801
+ * ```ts
2802
+ * const validatePositive = (n: number): Result<string, number> =>
2803
+ * n > 0 ? Result.make.ok(n) : Result.make.err("Must be positive");
2804
+ *
2805
+ * pipe(Result.make.ok(5), Result.chain(validatePositive)); // Ok(5)
2806
+ * pipe(Result.make.ok(-1), Result.chain(validatePositive)); // Err("Must be positive")
2807
+ * ```
2808
+ */
2809
+ chain: <E2, A, B>(f: (a: A) => Result<E2, B>) => <E1 = never>(data: Result<E1, A>) => Result<E1 | E2, B>;
2810
+ /**
2811
+ * Extracts the value from a Result by providing handlers for both cases.
2812
+ *
2813
+ * @example
2814
+ * ```ts
2815
+ * pipe(
2816
+ * Result.make.ok(5),
2817
+ * Result.fold(
2818
+ * e => `Error: ${e}`,
2819
+ * n => `Value: ${n}`
2820
+ * )
2821
+ * ); // "Value: 5"
2822
+ * ```
2823
+ */
2824
+ fold: <E, A, B>(onErr: (e: E) => B, onOk: (a: A) => B) => (data: Result<E, A>) => B;
2825
+ /**
2826
+ * Pattern matches on a Result, returning the result of the matching case.
2827
+ *
2828
+ * @example
2829
+ * ```ts
2830
+ * pipe(
2831
+ * result,
2832
+ * Result.match({
2833
+ * ok: value => `Got ${value}`,
2834
+ * err: error => `Failed: ${error}`
2835
+ * })
2836
+ * );
2837
+ * ```
2838
+ */
2839
+ match: <E, A, B>(cases: {
2840
+ ok: (a: A) => B;
2841
+ err: (e: E) => B;
2842
+ }) => (data: Result<E, A>) => B;
2843
+ /**
2844
+ * Returns the success value or a default value if the Result is an error.
2845
+ * The default is a thunk `() => B` — evaluated only when the Result is Err.
2846
+ * The default can be a different type, widening the result to `A | B`.
2847
+ *
2848
+ * @example
2849
+ * ```ts
2850
+ * pipe(Result.make.ok(5), Result.getOrElse(() => 0)); // 5
2851
+ * pipe(Result.make.err("error"), Result.getOrElse(() => 0)); // 0
2852
+ * pipe(Result.make.err("error"), Result.getOrElse(() => null)); // null — typed as number | null
2853
+ * ```
2854
+ */
2855
+ getOrElse: <B>(defaultValue: () => B) => <E, A>(data: Result<E, A>) => A | B;
2856
+ /**
2857
+ * Executes a side effect on the success value without changing the Result.
2858
+ * Useful for logging or debugging.
2859
+ *
2860
+ * @example
2861
+ * ```ts
2862
+ * pipe(
2863
+ * Result.make.ok(5),
2864
+ * Result.tap(n => console.log("Value:", n)),
2865
+ * Result.map(n => n * 2)
2866
+ * );
2867
+ * ```
2868
+ */
2869
+ tap: <E, A>(f: (a: A) => void) => (data: Result<E, A>) => Result<E, A>;
2870
+ /**
2871
+ * Executes a side effect on the error value without changing the Result.
2872
+ * Useful for logging or reporting errors.
2873
+ *
2874
+ * @example
2875
+ * ```ts
2876
+ * pipe(
2877
+ * Result.make.err("not found"),
2878
+ * Result.tapError(e => console.error("validation failed:", e)),
2879
+ * Result.chain(save),
2880
+ * )
2881
+ * ```
2882
+ */
2883
+ tapError: <E, A>(f: (e: E) => void) => (data: Result<E, A>) => Result<E, A>;
2884
+ from: {
2885
+ /**
2886
+ * Creates a Result from a predicate applied to a value.
2887
+ * Returns Ok if the predicate passes, Err from onFalse otherwise.
2888
+ *
2889
+ * @example
2890
+ * ```ts
2891
+ * pipe(5, Result.from.Predicate(n => n > 0, n => `${n} is not positive`)); // Ok(5)
2892
+ * pipe(-1, Result.from.Predicate(n => n > 0, n => `${n} is not positive`)); // Err("-1 is not positive")
2893
+ * pipe("", Result.from.Predicate(s => s.length > 0, () => "empty string")); // Err("empty string")
2894
+ * ```
2895
+ */
2896
+ Predicate: <E, A>(pred: (a: A) => boolean, onFalse: (a: A) => E) => (a: A) => Result<E, A>;
2897
+ /**
2898
+ * Creates a Result from a nullable value.
2899
+ * Returns Ok if the value is not null or undefined, error from onNull otherwise.
2900
+ *
2901
+ * @example
2902
+ * ```ts
2903
+ * pipe(null, Result.from.nullable(() => "is null")); // Err("is null")
2904
+ * pipe(42, Result.from.nullable(() => "is null")); // Ok(42)
2905
+ * ```
2906
+ */
2907
+ nullable: <E>(onNull: () => E) => <A>(value: A | null | undefined) => Result<E, A>;
2908
+ /**
2909
+ * Creates a Result from a Maybe.
2910
+ * Some becomes Ok, None becomes error from onNone.
2911
+ *
2912
+ * @example
2913
+ * ```ts
2914
+ * pipe(Maybe.make.none(), Result.from.Maybe(() => "is none")); // Err("is none")
2915
+ * pipe(Maybe.make.some(42), Result.from.Maybe(() => "is none")); // Ok(42)
2916
+ * ```
2917
+ */
2918
+ Maybe: <E>(onNone: () => E) => <A>(maybe: Maybe<A>) => Result<E, A>;
2919
+ /**
2920
+ * Converts a `Validation` to a `Result`, combining accumulated errors using `combineErrors`.
2921
+ * `Passed(a)` becomes `Ok(a)`; `Failed(errors)` becomes `Err(combineErrors(errors))`.
2922
+ *
2923
+ * @example
2924
+ * ```ts
2925
+ * Result.from.Validation((errors) => errors.join(", "))(Validation.make.failed("error1")); // Err("error1")
2926
+ * ```
2927
+ */
2928
+ Validation: <E1, E2, A>(combineErrors: (errors: NonEmptyArr<E1>) => E2) => (val: Validation<E1, A>) => Result<E2, A>;
2929
+ };
2930
+ /**
2931
+ * Recovers from an error by providing a fallback Result.
2932
+ * The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
2933
+ */
2934
+ recover: <E, B>(fallback: (e: E) => Result<E, B>) => <A>(data: Result<E, A>) => Result<E, A | B>;
2935
+ /**
2936
+ * Recovers from an error unless the predicate `isBlocked` returns true for that error.
2937
+ * The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
2938
+ *
2939
+ * @example
2940
+ * ```ts
2941
+ * pipe(
2942
+ * Result.make.err(new Error("not found")),
2943
+ * Result.recoverUnless(e => e.message === "fatal", () => Result.make.ok(0))
2944
+ * ); // Ok(0)
2945
+ * ```
2946
+ */
2947
+ recoverUnless: <E, B>(isBlocked: (e: E) => boolean, fallback: () => Result<E, B>) => <A>(data: Result<E, A>) => Result<E, A | B>;
2948
+ to: {
2949
+ /**
2950
+ * Converts a Result to a Maybe.
2951
+ * Ok becomes Some, Err becomes None (the error is discarded).
2952
+ *
2953
+ * @example
2954
+ * ```ts
2955
+ * Result.to.Maybe(Result.make.ok(42)); // Some(42)
2956
+ * Result.to.Maybe(Result.make.err("oops")); // None
2957
+ * ```
2958
+ */
2959
+ Maybe: <E, A>(data: Result<E, A>) => Maybe<A>;
2960
+ /**
2961
+ * Converts a `Result` to a `Validation`. `Ok(a)` becomes `Passed(a)`; `Err(e)` becomes `Failed([e])`.
2962
+ *
2963
+ * @example
2964
+ * ```ts
2965
+ * Result.to.Validation(Result.make.ok(42)); // Passed(42)
2966
+ * Result.to.Validation(Result.make.err("bad")); // Failed(["bad"])
2967
+ * ```
2968
+ */
2969
+ Validation: <E, A>(data: Result<E, A>) => Validation<E, A>;
2970
+ };
2971
+ /**
2972
+ * Swaps the outer `Result` and inner `Maybe` context.
2973
+ * `Ok(Some(a))` becomes `Some(Ok(a))`, `Ok(None)` becomes `None`, and `Err(e)` becomes `Some(Err(e))`.
2974
+ *
2975
+ * @example
2976
+ * ```ts
2977
+ * Result.transposeMaybe(Result.make.ok(Maybe.make.some(42))); // Some(Ok(42))
2978
+ * Result.transposeMaybe(Result.make.ok(Maybe.make.none())); // None
2979
+ * Result.transposeMaybe(Result.make.err("error")); // Some(Err("error"))
2980
+ * ```
2981
+ */
2982
+ transposeMaybe: <E, A>(data: Result<E, Maybe<A>>) => Maybe<Result<E, A>>;
2983
+ /**
2984
+ * Applies a function wrapped in a Result to a value wrapped in a Result.
2985
+ *
2986
+ * @example
2987
+ * ```ts
2988
+ * const add = (a: number) => (b: number) => a + b;
2989
+ * pipe(
2990
+ * Result.make.ok(add),
2991
+ * Result.ap(Result.make.ok(5)),
2992
+ * Result.ap(Result.make.ok(3))
2993
+ * ); // Ok(8)
2994
+ * ```
2995
+ */
2996
+ ap: <E, A>(arg: Result<E, A>) => <B>(data: Result<E, (a: A) => B>) => Result<E, B>;
2997
+ /**
2998
+ * Converts a Result value into an object containing a single property.
2999
+ * Initiates the pipeline accumulator record.
3000
+ *
3001
+ * @example
3002
+ * ```ts
3003
+ * pipe(Result.make.ok(42), Result.bindTo("value")); // Ok({ value: 42 })
3004
+ * ```
3005
+ */
3006
+ bindTo: <K extends string>(key: K) => <E, A>(data: Result<E, A>) => Result<E, { [P in K]: A; }>;
3007
+ /**
3008
+ * Evaluates a new Result using the current accumulator and attaches the output to a new key.
3009
+ *
3010
+ * @example
3011
+ * ```ts
3012
+ * pipe(
3013
+ * Result.make.ok({ a: 1 }),
3014
+ * Result.bind("b", ({ a }) => Result.make.ok(a + 1))
3015
+ * ); // Ok({ a: 1, b: 2 })
3016
+ * ```
3017
+ */
3018
+ bind: <K extends string, E, A, B>(key: K, f: (a: A) => Result<E, B>) => (data: Result<E, A>) => Result<E, A & { [P in K]: B; }>;
3019
+ /**
3020
+ * Combines a record of Results into a single Result of a record.
3021
+ * Evaluates fields in key order and short-circuits on the first failure.
3022
+ *
3023
+ * @example
3024
+ * ```ts
3025
+ * Result.struct({
3026
+ * name: Result.make.ok("Alice"),
3027
+ * age: Result.make.ok(30)
3028
+ * }); // Ok({ name: "Alice", age: 30 })
3029
+ * ```
3030
+ */
3031
+ struct: <E, R extends Record<string, any>>(fields: { [K in keyof R]: Result<E, R[K]>; }) => Result<E, R>;
3032
+ /**
3033
+ * Narrows an `Ok` value with a predicate, converting to `Err(onFail(a))` if the predicate returns false.
3034
+ *
3035
+ * @example
3036
+ * ```ts
3037
+ * pipe(
3038
+ * Result.make.ok(15),
3039
+ * Result.ensure((n) => n >= 18, (n) => `Age ${n} is below 18`)
3040
+ * ); // Err("Age 15 is below 18")
3041
+ * ```
3042
+ */
3043
+ ensure: <A, E2>(predicate: (a: A) => boolean, onFail: (a: A) => E2) => <E1 = never>(data: Result<E1, A>) => Result<E1 | E2, A>;
3044
+ /**
3045
+ * Transforms both branches of a Result simultaneously.
3046
+ * Applies `onErr` to `Err` values and `onOk` to `Ok` values.
3047
+ *
3048
+ * @example
3049
+ * ```ts
3050
+ * pipe(
3051
+ * Result.make.ok(5),
3052
+ * Result.bimap(
3053
+ * (e) => `Error: ${e}`,
3054
+ * (n) => n * 2
3055
+ * )
3056
+ * ); // Ok(10)
3057
+ * ```
3058
+ */
3059
+ bimap: <E1, E2, A, B>(onErr: (e: E1) => E2, onOk: (a: A) => B) => (data: Result<E1, A>) => Result<E2, B>;
3060
+ };
3061
+ //#endregion
3062
+ //#region src/Core/State.d.ts
3063
+ /**
3064
+ * A synchronous computation that threads a piece of mutable state `S` through
3065
+ * a pipeline without exposing mutation at call sites.
3066
+ *
3067
+ * At runtime a `State<S, A>` is just a function from an initial state to a pair
3068
+ * `[value, nextState]`. Nothing runs until you supply the initial state with
3069
+ * `State.run`, `State.evaluate`, or `State.execute`.
3070
+ *
3071
+ * @example
3072
+ * ```ts
3073
+ * type Counter = number;
3074
+ *
3075
+ * const increment: State<Counter, undefined> = State.modify(n => n + 1);
3076
+ * const getCount: State<Counter, Counter> = State.get();
3077
+ *
3078
+ * const program = pipe(
3079
+ * increment,
3080
+ * State.chain(() => increment),
3081
+ * State.chain(() => getCount),
3082
+ * );
3083
+ *
3084
+ * State.run(0)(program); // [2, 2] — value is 2, final state is 2
3085
+ * ```
3086
+ */
3087
+ type State$1<S, A> = (s: S) => readonly [A, S];
3088
+ declare const State$1: {
3089
+ /**
3090
+ * Lifts a pure value into a State computation. The state passes through unchanged.
3091
+ *
3092
+ * @example
3093
+ * ```ts
3094
+ * State.run(10)(State.resolve(42)); // [42, 10] — value 42, state unchanged
3095
+ * ```
3096
+ */
3097
+ resolve: <S, A>(value: A) => State$1<S, A>;
3098
+ /**
3099
+ * Produces the current state as the value, without modifying it.
3100
+ *
3101
+ * @example
3102
+ * ```ts
3103
+ * const readStack: State<string[], string[]> = State.get();
3104
+ * State.run(["a", "b"])(readStack); // [["a", "b"], ["a", "b"]]
3105
+ * ```
3106
+ */
3107
+ get: <S>() => State$1<S, S>;
3108
+ /**
3109
+ * Reads a projection of the state without modifying it.
3110
+ * Equivalent to `pipe(State.get(), State.map(f))` but more direct.
3111
+ *
3112
+ * @example
3113
+ * ```ts
3114
+ * type AppState = { count: number; label: string };
3115
+ * const readCount: State<AppState, number> = State.gets(s => s.count);
3116
+ * State.run({ count: 5, label: "x" })(readCount); // [5, { count: 5, label: "x" }]
3117
+ * ```
3118
+ */
3119
+ gets: <S, A>(f: (s: S) => A) => State$1<S, A>;
3120
+ /**
3121
+ * Replaces the current state with a new value. Produces no meaningful value.
3122
+ *
3123
+ * @example
3124
+ * ```ts
3125
+ * const reset: State<number, undefined> = State.put(0);
3126
+ * State.run(99)(reset); // [undefined, 0]
3127
+ * ```
3128
+ */
3129
+ put: <S>(newState: S) => State$1<S, undefined>;
3130
+ /**
3131
+ * Applies a function to the current state to produce the next state.
3132
+ * Produces no meaningful value.
3133
+ *
3134
+ * @example
3135
+ * ```ts
3136
+ * const push = (item: string): State<string[], undefined> =>
3137
+ * State.modify(stack => [...stack, item]);
3138
+ *
3139
+ * State.run(["a"])(push("b")); // [undefined, ["a", "b"]]
3140
+ * ```
3141
+ */
3142
+ modify: <S>(f: (s: S) => S) => State$1<S, undefined>;
3143
+ /**
3144
+ * Transforms the value produced by a State computation.
3145
+ * The state transformation is unchanged.
3146
+ *
3147
+ * @example
3148
+ * ```ts
3149
+ * const readLength: State<string[], number> = pipe(
3150
+ * State.get<string[]>(),
3151
+ * State.map(stack => stack.length),
3152
+ * );
3153
+ *
3154
+ * State.run(["a", "b", "c"])(readLength); // [3, ["a", "b", "c"]]
3155
+ * ```
3156
+ */
3157
+ map: <S, A, B>(f: (a: A) => B) => (st: State$1<S, A>) => State$1<S, B>;
3158
+ /**
3159
+ * Sequences two State computations. The state output of the first is passed
3160
+ * as the state input to the second.
3161
+ *
3162
+ * Data-last — the first computation is the data being piped.
3163
+ *
3164
+ * @example
3165
+ * ```ts
3166
+ * const push = (item: string): State<string[], undefined> =>
3167
+ * State.modify(stack => [...stack, item]);
3168
+ *
3169
+ * const program = pipe(
3170
+ * push("a"),
3171
+ * State.chain(() => push("b")),
3172
+ * State.chain(() => State.get<string[]>()),
3173
+ * );
3174
+ *
3175
+ * State.evaluate([])(program); // ["a", "b"]
3176
+ * ```
3177
+ */
3178
+ chain: <S, A, B>(f: (a: A) => State$1<S, B>) => (st: State$1<S, A>) => State$1<S, B>;
3179
+ /**
3180
+ * Applies a function wrapped in a State to a value wrapped in a State.
3181
+ * The function computation runs first; its output state is the input to the
3182
+ * argument computation.
3183
+ *
3184
+ * @example
3185
+ * ```ts
3186
+ * const addCounted = (n: number) => (m: number) => n + m;
3187
+ * const program = pipe(
3188
+ * State.resolve<number, typeof addCounted>(addCounted),
3189
+ * State.ap(State.gets((s: number) => s * 2)),
3190
+ * State.ap(State.gets((s: number) => s)),
3191
+ * );
3192
+ *
3193
+ * State.evaluate(3)(program); // 6 + 3 = 9
3194
+ * ```
3195
+ */
3196
+ ap: <S, A>(arg: State$1<S, A>) => <B>(fn: State$1<S, (a: A) => B>) => State$1<S, B>;
3197
+ /**
3198
+ * Runs a side effect on the produced value without changing the State computation.
3199
+ *
3200
+ * @example
3201
+ * ```ts
3202
+ * pipe(
3203
+ * State.get<number>(),
3204
+ * State.tap(n => console.log("current:", n)),
3205
+ * State.chain(() => State.modify(n => n + 1)),
3206
+ * );
3207
+ * ```
3208
+ */
3209
+ tap: <S, A>(f: (a: A) => void) => (st: State$1<S, A>) => State$1<S, A>;
3210
+ /**
3211
+ * Runs a State computation with an initial state, returning both the
3212
+ * produced value and the final state as a pair.
3213
+ *
3214
+ * Data-last — the computation is the data being piped.
3215
+ *
3216
+ * @example
3217
+ * ```ts
3218
+ * const program = pipe(
3219
+ * State.modify<number>(n => n + 1),
3220
+ * State.chain(() => State.get<number>()),
3221
+ * );
3222
+ *
3223
+ * State.run(0)(program); // [1, 1]
3224
+ * ```
3225
+ */
3226
+ run: <S>(initialState: S) => <A>(st: State$1<S, A>) => readonly [A, S];
3227
+ /**
3228
+ * Runs a State computation with an initial state, returning only the
3229
+ * produced value (discarding the final state).
3230
+ *
3231
+ * @example
3232
+ * ```ts
3233
+ * State.evaluate([])(pipe(
3234
+ * State.modify<string[]>(s => [...s, "x"]),
3235
+ * State.chain(() => State.get<string[]>()),
3236
+ * )); // ["x"]
3237
+ * ```
3238
+ */
3239
+ evaluate: <S>(initialState: S) => <A>(st: State$1<S, A>) => A;
3240
+ /**
3241
+ * Runs a State computation with an initial state, returning only the
3242
+ * final state (discarding the produced value).
3243
+ *
3244
+ * @example
3245
+ * ```ts
3246
+ * State.execute(0)(pipe(
3247
+ * State.modify<number>(n => n + 10),
3248
+ * State.chain(() => State.modify<number>(n => n * 2)),
3249
+ * )); // 20
3250
+ * ```
3251
+ */
3252
+ execute: <S>(initialState: S) => <A>(st: State$1<S, A>) => S;
3253
+ /**
3254
+ * Lifts a State value into an accumulator object.
3255
+ *
3256
+ * @example
3257
+ * ```ts
3258
+ * pipe(State.resolve(42), State.bindTo("value")); // State({ value: 42 })
3259
+ * ```
3260
+ */
3261
+ bindTo: <K extends string>(key: K) => <S, A>(data: State$1<S, A>) => State$1<S, { [P in K]: A; }>;
3262
+ /**
3263
+ * Evaluates a new State using the current accumulator and attaches the output to a new key.
3264
+ *
3265
+ * @example
3266
+ * ```ts
3267
+ * pipe(
3268
+ * State.resolve({ a: 1 }),
3269
+ * State.bind("b", ({ a }) => State.resolve(a + 1))
3270
+ * ); // State({ a: 1, b: 2 })
3271
+ * ```
3272
+ */
3273
+ bind: <K extends string, S, A, B>(key: K, f: (a: A) => State$1<S, B>) => (data: State$1<S, A>) => State$1<S, A & { [P in K]: B; }>;
3274
+ /**
3275
+ * Focuses a State computation on a sub-state using a Lens.
3276
+ *
3277
+ * @example
3278
+ * ```ts
3279
+ * type AppState = { count: number; name: string };
3280
+ * const countLens = Lens.from.property<AppState>()("count");
3281
+ * const increment = State.modify((c: number) => c + 1);
3282
+ * const focusedProgram = pipe(increment, State.focus(countLens));
3283
+ * ```
3284
+ */
3285
+ focus: <S, A>(lens: Lens<S, A>) => <B>(stateOp: State$1<A, B>) => State$1<S, B>;
3286
+ };
3287
+ //#endregion
3288
+ //#region src/Core/Validation.d.ts
3289
+ /**
3290
+ * Validation represents a value that is either passed with a success value,
3291
+ * or failed with accumulated errors.
3292
+ * Unlike Result, Validation can accumulate multiple errors instead of short-circuiting.
3293
+ *
3294
+ * Use Validation when you need to collect all errors (e.g., form validation).
3295
+ * Use Result when you want to fail fast on the first error.
3296
+ *
3297
+ * @example
3298
+ * ```ts
3299
+ * const validateName = (name: string): Validation<string, string> =>
3300
+ * name.length > 0 ? Validation.make.passed(name) : Validation.make.failed("Name is required");
3301
+ *
3302
+ * const validateAge = (age: number): Validation<string, number> =>
3303
+ * age >= 0 ? Validation.make.passed(age) : Validation.make.failed("Age must be positive");
3304
+ *
3305
+ * // Accumulates all errors using ap
3306
+ * pipe(
3307
+ * Validation.make.passed((name: string) => (age: number) => ({ name, age })),
3308
+ * Validation.ap(validateName("")),
3309
+ * Validation.ap(validateAge(-1))
3310
+ * );
3311
+ * // Failed(["Name is required", "Age must be positive"])
3312
+ * ```
3313
+ */
3314
+ type Validation<E, A> = Passed<A> | Failed<E>;
3315
+ type Passed<A> = WithKind<"Passed"> & WithValue<A>;
3316
+ type Failed<E> = WithKind<"Failed"> & WithErrors<E>;
3317
+ declare function toResult<E1, E2, A>(combineErrors: (errors: NonEmptyArr<E1>) => E2): (val: Validation<E1, A>) => Result<E2, A>;
3318
+ declare function toResult<E, A>(data: Validation<E, A>): Result<NonEmptyArr<E>, A>;
3319
+ declare const Validation: {
3320
+ make: {
3321
+ /**
3322
+ * Wraps a value in a passed Validation.
3323
+ *
3324
+ * @example
3325
+ * ```ts
3326
+ * Validation.make.passed(42); // Passed(42)
3327
+ * ```
3328
+ */
3329
+ passed: <E, A>(value: A) => Validation<E, A>;
3330
+ /**
3331
+ * Creates a failed Validation from a single error.
3332
+ *
3333
+ * @example
3334
+ * ```ts
3335
+ * Validation.make.failed("Invalid input");
3336
+ * ```
3337
+ */
3338
+ failed: <E>(error: E) => Failed<E>;
3339
+ /**
3340
+ * Creates a failed Validation from multiple errors.
3341
+ *
3342
+ * @example
3343
+ * ```ts
3344
+ * Validation.make.failedAll(["Invalid input"]);
3345
+ * ```
3346
+ */
3347
+ failedAll: <E>(errors: NonEmptyArr<E>) => Failed<E>;
3348
+ };
3349
+ is: {
3350
+ /**
3351
+ * Type guard that checks if a Validation is passed.
3352
+ *
3353
+ * @example
3354
+ * ```ts
3355
+ * const v = Validation.make.passed(42);
3356
+ * if (Validation.is.passed(v)) {
3357
+ * console.log(v.value); // 42
3358
+ * }
3359
+ * ```
3360
+ */
3361
+ passed: <E, A>(data: Validation<E, A>) => data is Passed<A>;
3362
+ /**
3363
+ * Type guard that checks if a Validation is failed.
3364
+ *
3365
+ * @example
3366
+ * ```ts
3367
+ * const v = Validation.make.failed("invalid");
3368
+ * if (Validation.is.failed(v)) {
3369
+ * console.log(v.errors); // ["invalid"]
3370
+ * }
3371
+ * ```
3372
+ */
3373
+ failed: <E, A>(data: Validation<E, A>) => data is Failed<E>;
3374
+ };
3375
+ /**
3376
+ * Creates a Validation from a synchronous thunk that may throw.
3377
+ * Catches any errors and transforms them using the `onError` function into a Failed validation.
3378
+ *
3379
+ * @example
3380
+ * ```ts
3381
+ * const result = Validation.tryCatch(
3382
+ * () => JSON.parse(rawString),
3383
+ * { onError: (e) => `Parse error: ${e}` }
3384
+ * );
3385
+ * ```
3386
+ */
3387
+ tryCatch: <E, A>(f: () => A, options: {
3388
+ onError: (e: unknown) => E;
3389
+ }) => Validation<E, A>;
3390
+ from: {
3391
+ /**
3392
+ * Creates a Validation from a predicate applied to a value.
3393
+ * Returns Passed if the predicate passes, Failed from `onFalse` otherwise.
3394
+ *
3395
+ * @example
3396
+ * ```ts
3397
+ * const validateName = Validation.from.Predicate(
3398
+ * (s: string) => s.length > 0,
3399
+ * () => "Name is required"
3400
+ * );
3401
+ *
3402
+ * validateName("Alice"); // Passed("Alice")
3403
+ * validateName(""); // Failed(["Name is required"])
3404
+ * ```
3405
+ */
3406
+ Predicate: <E, A>(pred: (a: A) => boolean, onFalse: (a: A) => E) => (a: A) => Validation<E, A>;
3407
+ /**
3408
+ * Creates a Validation from a nullable value.
3409
+ * If the value is null or undefined, returns Failed with the error from onNull.
3410
+ * Otherwise, returns Passed.
3411
+ *
3412
+ * @example
3413
+ * ```ts
3414
+ * pipe(null, Validation.from.nullable(() => "is null")); // Failed(["is null"])
3415
+ * pipe(42, Validation.from.nullable(() => "is null")); // Passed(42)
3416
+ * ```
3417
+ */
3418
+ nullable: <E>(onNull: () => E) => <A>(value: A | null | undefined) => Validation<E, A>;
3419
+ /**
3420
+ * Creates a Validation from a Maybe.
3421
+ * If the Maybe is None, returns Failed with the error from onNone.
3422
+ * Otherwise, returns Passed.
3423
+ *
3424
+ * @example
3425
+ * ```ts
3426
+ * pipe(Maybe.make.none(), Validation.from.Maybe(() => "is none")); // Failed(["is none"])
3427
+ * pipe(Maybe.make.some(42), Validation.from.Maybe(() => "is none")); // Passed(42)
3428
+ * ```
3429
+ */
3430
+ Maybe: <E>(onNone: () => E) => <A>(maybe: Maybe<A>) => Validation<E, A>;
3431
+ /**
3432
+ * Converts a `Result` to a `Validation`. `Ok` becomes `Passed`; `Err(e)` becomes `Failed([e])`.
3433
+ *
3434
+ * Useful when bridging from error-short-circuiting `Result` pipelines into
3435
+ * error-accumulating `Validation` pipelines.
3436
+ *
3437
+ * @example
3438
+ * ```ts
3439
+ * Validation.from.Result(Result.make.ok(42)); // Passed(42)
3440
+ * Validation.from.Result(Result.make.err("bad")); // Failed(["bad"])
3441
+ * ```
3442
+ */
3443
+ Result: <E, A>(data: Result<E, A>) => Validation<E, A>;
3444
+ };
3445
+ /**
3446
+ * Transforms the success value inside a Validation.
3447
+ *
3448
+ * @example
3449
+ * ```ts
3450
+ * pipe(Validation.make.passed(5), Validation.map(n => n * 2)); // Passed(10)
3451
+ * pipe(Validation.make.failed("oops"), Validation.map(n => n * 2)); // Failed(["oops"])
3452
+ * ```
3453
+ */
3454
+ map: <A, B>(f: (a: A) => B) => <E>(data: Validation<E, A>) => Validation<E, B>;
3455
+ /**
3456
+ * Transforms the error list inside a Validation.
3457
+ *
3458
+ * @example
3459
+ * ```ts
3460
+ * pipe(Validation.make.failed("oops"), Validation.mapError(e => e.toUpperCase())); // Failed(["OOPS"])
3461
+ * ```
3462
+ */
3463
+ mapError: <E, F, A>(f: (e: E) => F) => (data: Validation<E, A>) => Validation<F, A>;
3464
+ /**
3465
+ * Applies a function wrapped in a Validation to a value wrapped in a Validation.
3466
+ * Accumulates errors from both sides.
3467
+ *
3468
+ * @example
3469
+ * ```ts
3470
+ * const add = (a: number) => (b: number) => a + b;
3471
+ * pipe(
3472
+ * Validation.make.passed(add),
3473
+ * Validation.ap(Validation.make.passed(5)),
3474
+ * Validation.ap(Validation.make.passed(3))
3475
+ * ); // Passed(8)
3476
+ *
3477
+ * pipe(
3478
+ * Validation.make.passed(add),
3479
+ * Validation.ap(Validation.make.failed<string>("bad a")),
3480
+ * Validation.ap(Validation.make.failed<string>("bad b"))
3481
+ * ); // Failed(["bad a", "bad b"])
3482
+ * ```
3483
+ */
3484
+ ap: <E, A>(arg: Validation<E, A>) => <B>(data: Validation<E, (a: A) => B>) => Validation<E, B>;
3485
+ /**
3486
+ * Applies a function wrapped in a Validation to a value wrapped in a Validation,
3487
+ * using a custom error concatenator function when both sides fail.
3488
+ *
3489
+ * @example
3490
+ * ```ts
3491
+ * const concat = (e1: NonEmptyArr<string>, e2: NonEmptyArr<string>): NonEmptyArr<string> =>
3492
+ * [...e1, ...e2];
3493
+ * pipe(fnVal, Validation.apCustom(concat)(argVal));
3494
+ * ```
3495
+ */
3496
+ apCustom: <E1, E2, E3>(concat: (e1: NonEmptyArr<E1>, e2: NonEmptyArr<E2>) => NonEmptyArr<E3>) => <A>(arg: Validation<E2, A>) => <B>(data: Validation<E1, (a: A) => B>) => Validation<E3, B>;
3497
+ /**
3498
+ * Extracts the value from a Validation by providing handlers for both cases.
3499
+ *
3500
+ * @example
3501
+ * ```ts
3502
+ * pipe(
3503
+ * Validation.make.passed(42),
3504
+ * Validation.fold(
3505
+ * errors => `Errors: ${errors.join(", ")}`,
3506
+ * value => `Value: ${value}`
3507
+ * )
3508
+ * );
3509
+ * ```
3510
+ */
3511
+ fold: <E, A, B>(onFailed: (errors: NonEmptyArr<E>) => B, onPassed: (a: A) => B) => (data: Validation<E, A>) => B;
3512
+ /**
3513
+ * Pattern matches on a Validation, returning the result of the matching case.
3514
+ *
3515
+ * @example
3516
+ * ```ts
3517
+ * pipe(
3518
+ * validation,
3519
+ * Validation.match({
3520
+ * passed: value => `Got ${value}`,
3521
+ * failed: errors => `Failed: ${errors.join(", ")}`
3522
+ * })
3523
+ * );
3524
+ * ```
3525
+ */
3526
+ match: <E, A, B>(cases: {
3527
+ passed: (a: A) => B;
3528
+ failed: (errors: NonEmptyArr<E>) => B;
3529
+ }) => (data: Validation<E, A>) => B;
3530
+ /**
3531
+ * Returns the success value or a default value if the Validation is failed.
3532
+ * The default can be a different type, widening the result to `A | B`.
3533
+ *
3534
+ * @example
3535
+ * ```ts
3536
+ * pipe(Validation.make.passed(5), Validation.getOrElse(() => 0)); // 5
3537
+ * pipe(Validation.make.failed("oops"), Validation.getOrElse(() => 0)); // 0
3538
+ * pipe(Validation.make.failed("oops"), Validation.getOrElse(() => null)); // null — typed as number | null
3539
+ * ```
3540
+ */
3541
+ getOrElse: <B>(defaultValue: () => B) => <E, A>(data: Validation<E, A>) => A | B;
3542
+ /**
3543
+ * Executes a side effect on the success value without changing the Validation.
3544
+ *
3545
+ * @example
3546
+ * ```ts
3547
+ * pipe(
3548
+ * Validation.make.passed(5),
3549
+ * Validation.tap(n => console.log("Value:", n)),
3550
+ * Validation.map(n => n * 2)
3551
+ * );
3552
+ * ```
3553
+ */
3554
+ tap: <E, A>(f: (a: A) => void) => (data: Validation<E, A>) => Validation<E, A>;
3555
+ /**
3556
+ * Executes a side effect on the accumulated errors without changing the Validation.
3557
+ * Useful for logging or reporting validation failures.
3558
+ *
3559
+ * @example
3560
+ * ```ts
3561
+ * pipe(
3562
+ * Validation.make.failed("Name required"),
3563
+ * Validation.tapError(errors => console.error("validation failed:", errors)),
3564
+ * Validation.map(toUser)
3565
+ * );
3566
+ * ```
3567
+ */
3568
+ tapError: <E, A>(f: (errors: NonEmptyArr<E>) => void) => (data: Validation<E, A>) => Validation<E, A>;
3569
+ /**
3570
+ * Recovers from a Failed state by providing a fallback Validation.
3571
+ * The fallback receives the accumulated error list so callers can inspect which errors occurred.
3572
+ * The fallback can produce a different success type, widening the result to `Validation<E, A | B>`.
3573
+ */
3574
+ recover: <E, B>(fallback: (errors: NonEmptyArr<E>) => Validation<E, B>) => <A>(data: Validation<E, A>) => Validation<E, A | B>;
3575
+ /**
3576
+ * Recovers from a Failed state unless `isBlocked` returns true for any of the accumulated errors.
3577
+ * The fallback can produce a different success type, widening the result to `Validation<E, A | B>`.
3578
+ *
3579
+ * @example
3580
+ * ```ts
3581
+ * pipe(
3582
+ * Validation.make.failed("field-error"),
3583
+ * Validation.recoverUnless(e => e === "fatal", () => Validation.make.passed(0))
3584
+ * ); // Passed(0)
3585
+ * ```
3586
+ */
3587
+ recoverUnless: <E, B>(isBlocked: (e: E) => boolean, fallback: () => Validation<E, B>) => <A>(data: Validation<E, A>) => Validation<E, A | B>;
3588
+ to: {
3589
+ /**
3590
+ * Converts a Validation to a Result.
3591
+ * Passed becomes Ok.
3592
+ * Direct call converts Failed to Err with accumulated error list `NonEmptyArr<E>`.
3593
+ * Curried call converts Failed to Err with combined error `E2` via `combineErrors`.
3594
+ *
3595
+ * @example
3596
+ * ```ts
3597
+ * Validation.to.Result(Validation.make.passed(42)); // Ok(42)
3598
+ * Validation.to.Result(Validation.make.failed("oops")); // Err(["oops"])
3599
+ * pipe(Validation.make.failed("oops"), Validation.to.Result(errors => errors.join(", "))); // Err("oops")
3600
+ * ```
3601
+ */
3602
+ Result: typeof toResult;
3603
+ /**
3604
+ * Converts a Validation to a Maybe. `Passed` becomes `Some`; `Failed` becomes `None`
3605
+ * (errors are discarded).
3606
+ *
3607
+ * @example
3608
+ * ```ts
3609
+ * Validation.to.Maybe(Validation.make.passed(42)); // Some(42)
3610
+ * Validation.to.Maybe(Validation.make.failed("bad")); // None
3611
+ * ```
3612
+ */
3613
+ Maybe: <E, A>(data: Validation<E, A>) => Maybe<A>;
3614
+ };
3615
+ /**
3616
+ * Combines two independent Validation instances into a tuple.
3617
+ * If both are Passed, returns Passed with both values as a tuple.
3618
+ * If either is Failed, accumulates errors from both sides.
3619
+ *
3620
+ * @example
3621
+ * ```ts
3622
+ * Validation.product(
3623
+ * Validation.make.passed("alice"),
3624
+ * Validation.make.passed(30)
3625
+ * ); // Passed(["alice", 30])
3626
+ *
3627
+ * Validation.product(
3628
+ * Validation.make.failed("Name required"),
3629
+ * Validation.make.failed("Age must be >= 0")
3630
+ * ); // Failed(["Name required", "Age must be >= 0"])
3631
+ * ```
3632
+ */
3633
+ product: <E, A, B>(first: Validation<E, A>, second: Validation<E, B>) => Validation<E, readonly [A, B]>;
3634
+ /**
3635
+ * Combines a non-empty list of Validation instances, accumulating all errors.
3636
+ * If all are Passed, returns Passed with all values collected into an array.
3637
+ * If any are Failed, returns Failed with all accumulated errors.
3638
+ *
3639
+ * @example
3640
+ * ```ts
3641
+ * Validation.productAll([
3642
+ * validateName(name),
3643
+ * validateEmail(email),
3644
+ * validateAge(age)
3645
+ * ]);
3646
+ * // Passed([name, email, age]) or Failed([...all errors])
3647
+ * ```
3648
+ */
3649
+ productAll: <E, A>(data: NonEmptyArr<Validation<E, A>>) => Validation<E, readonly A[]>;
3650
+ /**
3651
+ * Combines a record of Validations into a single Validation of a record.
3652
+ * Accumulates all failed branches' errors.
3653
+ *
3654
+ * @example
3655
+ * ```ts
3656
+ * Validation.struct({
3657
+ * name: Validation.make.passed("Alice"),
3658
+ * age: Validation.make.passed(30)
3659
+ * }); // Passed({ name: "Alice", age: 30 })
3660
+ *
3661
+ * Validation.struct({
3662
+ * name: Validation.make.failed("Name required"),
3663
+ * age: Validation.make.failed("Age must be >= 0")
3664
+ * }); // Failed(["Name required", "Age must be >= 0"])
3665
+ * ```
3666
+ */
3667
+ struct: <E, R extends Record<string, any>>(fields: { [K in keyof R]: Validation<E, R[K]>; }) => Validation<E, R>;
3668
+ };
3669
+ //#endregion
3670
+ //#region src/Core/Task.d.ts
3671
+ /**
3672
+ * A lazy async computation that always resolves.
3673
+ *
3674
+ * Two guarantees:
3675
+ * - **Lazy** — nothing starts until you call it.
3676
+ * - **Infallible** — it never rejects. If failure is possible, encode it in the
3677
+ * return type using `Task.Result<E, A>` instead.
3678
+ *
3679
+ * An optional `AbortSignal` can be passed at the call site. Combinators like
3680
+ * `retry`, `poll`, and `timeout` thread it automatically to every inner
3681
+ * operation. Existing tasks that ignore the signal continue to work unchanged.
3682
+ *
3683
+ * Calling a Task returns a `Deferred<A>` — a one-shot async value that supports
3684
+ * `await` but has no `.catch()`, `.finally()`, or chainable `.then()`.
3685
+ *
3686
+ * **Consuming a Task:**
3687
+ *
3688
+ * Use `await task()` to run it and get the value directly:
3689
+ * ```ts
3690
+ * const value: number = await task();
3691
+ * ```
3692
+ *
3693
+ * When you need an explicit `Promise<A>` (e.g. for a third-party API), convert
3694
+ * the `Deferred` with `Deferred.to.Promise`:
3695
+ * ```ts
3696
+ * const p: Promise<number> = Deferred.to.Promise(task());
3697
+ * ```
3698
+ *
3699
+ * @example
3700
+ * ```ts
3701
+ * const getTimestamp: Task<number> = Task.resolve(Date.now());
3702
+ *
3703
+ * // Nothing runs yet — getTimestamp is just a description
3704
+ * const formatted = pipe(
3705
+ * getTimestamp,
3706
+ * Task.map(ts => new Date(ts).toISOString())
3707
+ * );
3708
+ *
3709
+ * // Execute when ready
3710
+ * const result = await formatted();
3711
+ * ```
3712
+ */
3713
+ type Task<A> = (signal?: AbortSignal) => Deferred<A>;
3714
+ declare const Task: {
3715
+ /**
3716
+ * Creates a Task that immediately resolves to the given value.
3717
+ *
3718
+ * @example
3719
+ * ```ts
3720
+ * const task = Task.resolve(42);
3721
+ * const value = await task(); // 42
3722
+ * ```
3723
+ */
3724
+ resolve: <A>(value: A) => Task<A>;
3725
+ from: {
3726
+ /**
3727
+ * Creates a Task from a lazy synchronous thunk.
3728
+ * Unlike `Task.resolve(f())`, `from.sync` does not evaluate `f` until the Task is called.
3729
+ *
3730
+ * @example
3731
+ * ```ts
3732
+ * const t = Task.from.sync(() => Date.now()); // Date.now() not called yet
3733
+ * const ts = await t(); // called here, every time
3734
+ * ```
3735
+ */
3736
+ sync: <A>(f: () => A) => Task<A>;
3737
+ };
3738
+ /**
3739
+ * Wraps a Promise-returning thunk that may throw or reject,
3740
+ * trapping errors with a fallback function and returning a guaranteed `Task<A>`.
3741
+ *
3742
+ * @example
3743
+ * ```ts
3744
+ * const loadConfig = Task.tryCatch(
3745
+ * () => configStore.get("default"),
3746
+ * { onError: () => DEFAULT_CONFIG }
3747
+ * );
3748
+ * ```
3749
+ */
3750
+ tryCatch: <A>(f: (signal?: AbortSignal) => globalThis.Promise<A>, options: {
3751
+ onError: (error: unknown) => A;
3752
+ }) => Task<A>;
3753
+ /**
3754
+ * Transforms the value inside a Task.
3755
+ *
3756
+ * @example
3757
+ * ```ts
3758
+ * pipe(
3759
+ * Task.resolve(5),
3760
+ * Task.map(n => n * 2)
3761
+ * )(); // Deferred<10>
3762
+ * ```
3763
+ */
3764
+ map: <A, B>(f: (a: A) => B) => (data: Task<A>) => Task<B>;
3765
+ /**
3766
+ * Chains Task computations. Passes the resolved value of the first Task to f.
3767
+ *
3768
+ * @example
3769
+ * ```ts
3770
+ * const readUserId: Task<string> = Task.resolve(session.userId);
3771
+ * const loadPrefs = (id: string): Task<Preferences> =>
3772
+ * Task.resolve(prefsCache.get(id));
3773
+ *
3774
+ * pipe(
3775
+ * readUserId,
3776
+ * Task.chain(loadPrefs)
3777
+ * )(); // Deferred<Preferences>
3778
+ * ```
3779
+ */
3780
+ chain: <A, B>(f: (a: A) => Task<B>) => (data: Task<A>) => Task<B>;
3781
+ /**
3782
+ * Applies a function wrapped in a Task to a value wrapped in a Task.
3783
+ * Both Tasks run in parallel.
3784
+ *
3785
+ * @example
3786
+ * ```ts
3787
+ * const add = (a: number) => (b: number) => a + b;
3788
+ * pipe(
3789
+ * Task.resolve(add),
3790
+ * Task.ap(Task.resolve(5)),
3791
+ * Task.ap(Task.resolve(3))
3792
+ * )(); // Deferred<8>
3793
+ * ```
3794
+ */
3795
+ ap: <A>(arg: Task<A>) => <B>(data: Task<(a: A) => B>) => Task<B>;
3796
+ /**
3797
+ * Executes a side effect on the value without changing the Task.
3798
+ * Useful for logging or debugging.
3799
+ *
3800
+ * @example
3801
+ * ```ts
3802
+ * pipe(
3803
+ * loadConfig,
3804
+ * Task.tap(cfg => console.log("Config:", cfg)),
3805
+ * Task.map(buildReport)
3806
+ * );
3807
+ * ```
3808
+ */
3809
+ tap: <A>(f: (a: A) => void) => (data: Task<A>) => Task<A>;
3810
+ /**
3811
+ * Runs multiple Tasks in parallel and collects their results.
3812
+ * An optional `concurrency` option limits the number of tasks executing at any given time.
3813
+ *
3814
+ * @example
3815
+ * ```ts
3816
+ * Task.all([loadConfig, detectLocale, loadTheme])();
3817
+ * // Deferred<[Config, string, Theme]>
3818
+ *
3819
+ * Task.all([loadConfig, detectLocale, loadTheme], { concurrency: 2 })();
3820
+ * ```
3821
+ */
3822
+ all: <T extends readonly Task<unknown>[]>(tasks: T, options?: {
3823
+ concurrency?: number;
3824
+ }) => Task<{ [K in keyof T]: T[K] extends Task<infer A> ? A : never; }>;
3825
+ /**
3826
+ * Delays the execution of a Task by the specified duration.
3827
+ * Useful for debouncing or rate limiting.
3828
+ *
3829
+ * @example
3830
+ * ```ts
3831
+ * pipe(
3832
+ * Task.resolve(42),
3833
+ * Task.delay(Duration.seconds(1))
3834
+ * )(); // Resolves after 1 second
3835
+ * ```
3836
+ */
3837
+ delay: (duration: Duration) => <A>(data: Task<A>) => Task<A>;
3838
+ /**
3839
+ * Runs a Task a fixed number of times sequentially, collecting all results into an array.
3840
+ * An optional delay duration can be inserted between runs.
3841
+ *
3842
+ * @example
3843
+ * ```ts
3844
+ * pipe(
3845
+ * pollSensor,
3846
+ * Task.repeat({ times: 5, delay: Duration.seconds(1) })
3847
+ * )(); // Task<Reading[]> — 5 readings, one per second
3848
+ * ```
3849
+ */
3850
+ repeat: (options: {
3851
+ times: number;
3852
+ delay?: Duration;
3853
+ }) => <A>(task: Task<A>) => Task<readonly A[]>;
3854
+ /**
3855
+ * Polls a Task repeatedly until the result satisfies a predicate, returning that result.
3856
+ * An optional delay duration can be inserted between polling runs.
3857
+ * An optional `attempts` cap stops the loop after N calls — the last value is returned
3858
+ * regardless of whether the predicate was satisfied.
3859
+ *
3860
+ * @example
3861
+ * ```ts
3862
+ * pipe(
3863
+ * checkStatus,
3864
+ * Task.poll({ until: (s) => s === "ready", delay: Duration.milliseconds(500) })
3865
+ * )(); // polls every 500ms until status is "ready"
3866
+ * ```
3867
+ */
3868
+ poll: <A>(options: {
3869
+ until: (a: A) => boolean;
3870
+ delay?: Duration;
3871
+ attempts?: number;
3872
+ }) => (task: Task<A>) => Task<A>;
3873
+ /**
3874
+ * Resolves with the value of the first Task to complete. All Tasks start
3875
+ * immediately. When one resolves, the other tasks are cancelled (aborted)
3876
+ * downstream.
3877
+ *
3878
+ * @example
3879
+ * ```ts
3880
+ * const fast = Task.resolve("fast");
3881
+ * const slow = Task.delay(Duration.milliseconds(200))(Task.resolve("slow"));
3882
+ *
3883
+ * await Task.race([fast, slow])(); // "fast"
3884
+ * ```
3885
+ */
3886
+ race: <A>(tasks: ReadonlyArray<Task<A>>) => Task<A>;
3887
+ /**
3888
+ * Runs an array of Tasks concurrently and collects their results in an array.
3889
+ * Forward-propagates the call site's AbortSignal to all subtasks concurrently.
3890
+ *
3891
+ * @example
3892
+ * ```ts
3893
+ * Task.sequence([loadConfig, detectLocale, loadTheme])();
3894
+ * // Deferred<[Config, string, Theme]>
3895
+ * ```
3896
+ */
3897
+ sequence: <A>(tasks: ReadonlyArray<Task<A>>) => Task<ReadonlyArray<A>>;
3898
+ /**
3899
+ * Runs an array of Tasks one at a time in order, collecting all results.
3900
+ * Each Task starts only after the previous one resolves.
3901
+ *
3902
+ * @example
3903
+ * ```ts
3904
+ * let log: number[] = [];
3905
+ * const makeTask = (n: number) => Task.resolve(n);
3906
+ *
3907
+ * await Task.sequential([makeTask(1), makeTask(2), makeTask(3)])();
3908
+ * // log = [1, 2, 3] — tasks ran in order
3909
+ * ```
3910
+ */
3911
+ sequential: <A>(tasks: ReadonlyArray<Task<A>>) => Task<ReadonlyArray<A>>;
3912
+ /**
3913
+ * Converts a `Task<A>` into a `Task<Result<E, A>>`, resolving to `Err` if the
3914
+ * Task does not complete within the given duration. The inner Task receives an
3915
+ * `AbortSignal` that fires when the deadline passes, so asynchronous operations
3916
+ * that accept a signal are cancelled rather than left dangling.
3917
+ *
3918
+ * @example
3919
+ * ```ts
3920
+ * pipe(
3921
+ * heavyComputation,
3922
+ * Task.timeout({ duration: Duration.seconds(5), onTimeout: () => "timed out" }),
3923
+ * Task.Result.chain(processResult)
3924
+ * );
3925
+ * ```
3926
+ */
3927
+ timeout: <E>(options: {
3928
+ duration: Duration;
3929
+ onTimeout: () => E;
3930
+ }) => <A>(task: Task<A>) => Task<Result<E, A>>;
3931
+ /**
3932
+ * Creates a Task paired with an `abort` handle. Calling `abort()` cancels the
3933
+ * current in-flight call immediately. Unlike a one-shot abort, calling `task()`
3934
+ * again after `abort()` starts a fresh call with a new signal.
3935
+ *
3936
+ * Each invocation of `task()` automatically cancels the previous in-flight call,
3937
+ * making it safe to call repeatedly (e.g. on user input) without leaking promises.
3938
+ *
3939
+ * If an outer signal is also present (passed at the call site), aborting it
3940
+ * propagates into the internal controller.
3941
+ *
3942
+ * @example
3943
+ * ```ts
3944
+ * const { task: poll, abort } = Task.abortable(
3945
+ * (signal) => waitForEvent(bus, "ready", { signal }),
3946
+ * );
3947
+ *
3948
+ * onUnmount(abort);
3949
+ * await poll();
3950
+ * ```
3951
+ */
3952
+ abortable: <A>(factory: (signal: AbortSignal) => Thenable<A>) => {
3953
+ task: Task<A>;
3954
+ abort: () => void;
3955
+ };
3956
+ /**
3957
+ * Executes a task with an optional signal. Use as a terminal step in a `pipe` chain.
3958
+ *
3959
+ * @example
3960
+ * ```ts
3961
+ * const name = await pipe(
3962
+ * loadConfig,
3963
+ * Task.map(config => config.name),
3964
+ * Task.run(),
3965
+ * );
3966
+ * ```
3967
+ */
3968
+ run: (signal?: AbortSignal) => <A>(task: Task<A>) => Deferred<A>;
3969
+ /**
3970
+ * Converts a Task value into an object containing a single property.
3971
+ * Initiates the pipeline accumulator record.
3972
+ *
3973
+ * @example
3974
+ * ```ts
3975
+ * pipe(Task.resolve(42), Task.bindTo("value")); // Task({ value: 42 })
3976
+ * ```
3977
+ */
3978
+ bindTo: <K extends string>(key: K) => <A>(data: Task<A>) => Task<{ [P in K]: A; }>;
3979
+ /**
3980
+ * Evaluates a new Task using the current accumulator and attaches the output to a new key.
3981
+ *
3982
+ * @example
3983
+ * ```ts
3984
+ * pipe(
3985
+ * Task.resolve({ a: 1 }),
3986
+ * Task.bind("b", ({ a }) => Task.resolve(a + 1))
3987
+ * ); // Task({ a: 1, b: 2 })
3988
+ * ```
3989
+ */
3990
+ bind: <K extends string, A, B>(key: K, f: (a: A) => Task<B>) => (data: Task<A>) => Task<A & { [P in K]: B; }>;
3991
+ /**
3992
+ * Creates a memoized version of a Task. The task is executed at most once on first call,
3993
+ * and its resolved value is cached for all subsequent calls.
3994
+ *
3995
+ * @example
3996
+ * ```ts
3997
+ * const loadToken = Task.memoize(loadAuthToken);
3998
+ * const token1 = await loadToken(); // loads token
3999
+ * const token2 = await loadToken(); // returns cached token immediately
4000
+ * ```
4001
+ */
4002
+ memoize: <A>(task: Task<A>) => Task<A>;
4003
+ /**
4004
+ * Monitors progress of a Task by calling `onProgress(0)` before execution and `onProgress(1)` upon completion.
4005
+ *
4006
+ * @example
4007
+ * ```ts
4008
+ * const taskWithProgress = pipe(
4009
+ * readTask,
4010
+ * Task.withProgress((ratio) => console.log(`Progress: ${ratio * 100}%`))
4011
+ * );
4012
+ * ```
4013
+ */
4014
+ withProgress: <A>(onProgress: (ratio: number) => void) => (task: Task<A>) => Task<A>;
4015
+ /**
4016
+ * Attaches a read-only `.label` property to a Task, preserving the literal string generic type for IDE tooltips.
4017
+ *
4018
+ * @example
4019
+ * ```ts
4020
+ * const labeledTask = pipe(readTask, Task.withLabel("readUser"));
4021
+ * console.log(labeledTask.label); // "readUser"
4022
+ * ```
4023
+ */
4024
+ withLabel: <L extends string>(label: L) => <A>(task: Task<A>) => Task.LabeledTask<L, A>;
4025
+ Maybe: {
4026
+ make: {
4027
+ some: <A>(value: A) => Task.Maybe<A>;
4028
+ none: <A = never>() => Task.Maybe<A>;
4029
+ };
4030
+ from: {
4031
+ Maybe: <A>(option: Maybe<A>) => Task.Maybe<A>;
4032
+ nullable: <A>(value: A | null | undefined) => Task.Maybe<A>;
4033
+ Result: <E, A>(result: Result<E, A>) => Task.Maybe<A>;
4034
+ Task: <A>(task: Task<A>) => Task.Maybe<A>;
4035
+ };
4036
+ tryCatch: <A>(f: (signal?: AbortSignal) => Thenable<A>) => Task.Maybe<A>;
4037
+ map: <A, B>(f: (a: A) => B) => (data: Task.Maybe<A>) => Task.Maybe<B>;
4038
+ chain: <A, B>(f: (a: A) => Task.Maybe<B>) => (data: Task.Maybe<A>) => Task.Maybe<B>;
4039
+ ap: <A>(arg: Task.Maybe<A>) => <B>(data: Task.Maybe<(a: A) => B>) => Task.Maybe<B>;
4040
+ fold: <A, B>(onNone: () => B, onSome: (a: A) => B) => (data: Task.Maybe<A>) => Task<B>;
4041
+ match: <A, B>(cases: {
4042
+ none: () => B;
4043
+ some: (a: A) => B;
4044
+ }) => (data: Task.Maybe<A>) => Task<B>;
4045
+ getOrElse: <B>(defaultValue: () => B) => <A>(data: Task.Maybe<A>) => Task<A | B>;
4046
+ tap: <A>(f: (a: A) => void) => (data: Task.Maybe<A>) => Task.Maybe<A>;
4047
+ filter: <A>(predicate: (a: A) => boolean) => (data: Task.Maybe<A>) => Task.Maybe<A>;
4048
+ to: {
4049
+ Result: <E>(onNone: () => E) => <A>(data: Task.Maybe<A>) => Task.Result<E, A>;
4050
+ };
4051
+ bindTo: <K extends string>(key: K) => <A>(data: Task.Maybe<A>) => Task.Maybe<{ [P in K]: A; }>;
4052
+ bind: <K extends string, A, B>(key: K, f: (a: A) => Task.Maybe<B>) => (data: Task.Maybe<A>) => Task.Maybe<A & { [P in K]: B; }>;
4053
+ recover: <B>(fallback: () => Task.Maybe<B>) => <A>(data: Task.Maybe<A>) => Task.Maybe<A | B>;
4054
+ struct: <R extends Record<string, any>>(fields: { [K in keyof R]: Task.Maybe<R[K]>; }) => Task.Maybe<R>;
4055
+ memoize: <A>(task: Task.Maybe<A>) => Task.Maybe<A>;
4056
+ };
4057
+ Result: {
4058
+ make: {
4059
+ ok: <E = never, A = unknown>(value: A) => Task.Result<E, A>;
4060
+ err: <E, A = never>(error: E) => Task.Result<E, A>;
4061
+ };
4062
+ from: {
4063
+ nullable: <E>(onNull: () => E) => <A>(value: A | null | undefined) => Task.Result<E, A>;
4064
+ Maybe: <E>(onNone: () => E) => <A>(maybe: Maybe<A>) => Task.Result<E, A>;
4065
+ Result: <E, A>(result: Result<E, A>) => Task.Result<E, A>;
4066
+ };
4067
+ to: {
4068
+ Maybe: <E, A>(data: Task.Result<E, A>) => Task.Maybe<A>;
4069
+ };
4070
+ tryCatch: <E, A>(f: (signal?: AbortSignal) => Thenable<A>, options: {
4071
+ onError: (error: unknown) => E;
4072
+ }) => Task.Result<E, A>;
4073
+ map: <E, A, B>(f: (a: A) => B) => (data: Task.Result<E, A>) => Task.Result<E, B>;
4074
+ mapError: <E, F, A>(f: (e: E) => F) => (data: Task.Result<E, A>) => Task.Result<F, A>;
4075
+ chain: <E2, A, B>(f: (a: A) => Task.Result<E2, B>) => <E1 = never>(data: Task.Result<E1, A>) => Task.Result<E1 | E2, B>;
4076
+ fold: <E, A, B>(onErr: (e: E) => B, onOk: (a: A) => B) => (data: Task.Result<E, A>) => Task<B>;
4077
+ match: <E, A, B>(cases: {
4078
+ err: (e: E) => B;
4079
+ ok: (a: A) => B;
4080
+ }) => (data: Task.Result<E, A>) => Task<B>;
4081
+ recover: <E, B>(fallback: (e: E) => Task.Result<E, B>) => <A>(data: Task.Result<E, A>) => Task.Result<E, A | B>;
4082
+ recoverUnless: <E, B>(isBlocked: (e: E) => boolean, fallback: (e: E) => Task.Result<E, B>) => <A>(data: Task.Result<E, A>) => Task.Result<E, A | B>;
4083
+ getOrElse: <B>(defaultValue: () => B) => <E, A>(data: Task.Result<E, A>) => Task<A | B>;
4084
+ tap: <E, A>(f: (a: A) => void) => (data: Task.Result<E, A>) => Task.Result<E, A>;
4085
+ tapError: <E, A>(f: (e: E) => void) => (data: Task.Result<E, A>) => Task.Result<E, A>;
4086
+ ap: <E, A>(arg: Task.Result<E, A>) => <B>(data: Task.Result<E, (a: A) => B>) => Task.Result<E, B>;
4087
+ run: (signal?: AbortSignal) => <E, A>(task: Task.Result<E, A>) => Deferred<Result<E, A>>;
4088
+ bindTo: <K extends string>(key: K) => <E, A>(data: Task.Result<E, A>) => Task.Result<E, { [P in K]: A; }>;
4089
+ bind: <K extends string, E, A, B>(key: K, f: (a: A) => Task.Result<E, B>) => (data: Task.Result<E, A>) => Task.Result<E, A & { [P in K]: B; }>;
4090
+ struct: <E, R extends Record<string, any>>(fields: { [K in keyof R]: Task.Result<E, R[K]>; }) => Task.Result<E, R>;
4091
+ retry: (policy: RetryPolicy, options?: {
4092
+ when?: (error: unknown) => boolean;
4093
+ }) => <E, A>(task: Task.Result<E, A>) => Task.Result<E, A>;
4094
+ memoize: <E, A>(task: Task.Result<E, A>) => Task.Result<E, A>;
4095
+ timeout: <E2>(options: {
4096
+ duration: Duration;
4097
+ onTimeout: () => E2;
4098
+ }) => <E1 = never, A = unknown>(task: Task.Result<E1, A>) => Task.Result<E1 | E2, A>;
4099
+ allSettled: <E, A>(tasks: ReadonlyArray<Task.Result<E, A>>) => Task<ReadonlyArray<Result<E, A>>>;
4100
+ ensure: <A, E2>(predicate: (a: A) => boolean, onFail: (a: A) => E2) => <E1 = never>(task: Task.Result<E1, A>) => Task.Result<E1 | E2, A>;
4101
+ bimap: <E1, E2, A, B>(onErr: (e: E1) => E2, onOk: (a: A) => B) => (task: Task.Result<E1, A>) => Task.Result<E2, B>;
4102
+ };
4103
+ Validation: {
4104
+ make: {
4105
+ passed: <E = never, A = unknown>(value: A) => Task.Validation<E, A>;
4106
+ failed: <E, A = never>(error: E) => Task.Validation<E, A>;
4107
+ failedAll: <E, A = never>(errors: NonEmptyArr<E>) => Task.Validation<E, A>;
4108
+ };
4109
+ from: {
4110
+ Validation: <E, A>(validation: Validation<E, A>) => Task.Validation<E, A>;
4111
+ nullable: <E>(onNull: () => E) => <A>(value: A | null | undefined) => Task.Validation<E, A>;
4112
+ Maybe: <E>(onNone: () => E) => <A>(maybe: Maybe<A>) => Task.Validation<E, A>;
4113
+ Result: <E, A>(result: Result<E, A>) => Task.Validation<E, A>;
4114
+ };
4115
+ to: {
4116
+ Result: <E1, E2, A>(combineErrors: (errors: NonEmptyArr<E1>) => E2) => (data: Task.Validation<E1, A>) => Task.Result<E2, A>;
4117
+ Maybe: <E, A>(data: Task.Validation<E, A>) => Task.Maybe<A>;
4118
+ };
4119
+ tryCatch: <E, A>(f: (signal?: AbortSignal) => Thenable<A>, options: {
4120
+ onError: (error: unknown) => E;
4121
+ }) => Task.Validation<E, A>;
4122
+ map: <E, A, B>(f: (a: A) => B) => (data: Task.Validation<E, A>) => Task.Validation<E, B>;
4123
+ ap: <E, A>(arg: Task.Validation<E, A>) => <B>(data: Task.Validation<E, (a: A) => B>) => Task.Validation<E, B>;
4124
+ fold: <E, A, B>(onFailed: (errors: NonEmptyArr<E>) => B, onPassed: (a: A) => B) => (data: Task.Validation<E, A>) => Task<B>;
4125
+ match: <E, A, B>(cases: {
4126
+ passed: (a: A) => B;
4127
+ failed: (errors: NonEmptyArr<E>) => B;
4128
+ }) => (data: Task.Validation<E, A>) => Task<B>;
4129
+ getOrElse: <B>(defaultValue: () => B) => <E, A>(data: Task.Validation<E, A>) => Task<A | B>;
4130
+ tap: <E, A>(f: (a: A) => void) => (data: Task.Validation<E, A>) => Task.Validation<E, A>;
4131
+ recover: <E, B>(fallback: (errors: NonEmptyArr<E>) => Task.Validation<E, B>) => <A>(data: Task.Validation<E, A>) => Task.Validation<E, A | B>;
4132
+ recoverUnless: <E, B>(isBlocked: (errors: NonEmptyArr<E>) => boolean, fallback: (errors: NonEmptyArr<E>) => Task.Validation<E, B>) => <A>(data: Task.Validation<E, A>) => Task.Validation<E, A | B>;
4133
+ product: <E, A, B>(first: Task.Validation<E, A>, second: Task.Validation<E, B>) => Task.Validation<E, readonly [A, B]>;
4134
+ productAll: <E, A>(data: NonEmptyArr<Task.Validation<E, A>>) => Task.Validation<E, readonly A[]>;
4135
+ mapError: <E, F, A>(f: (e: E) => F) => (data: Task.Validation<E, A>) => Task.Validation<F, A>;
4136
+ tapError: <E, A>(f: (errors: NonEmptyArr<E>) => void) => (data: Task.Validation<E, A>) => Task.Validation<E, A>;
4137
+ struct: <E, R extends Record<string, any>>(fields: { [K in keyof R]: Task.Validation<E, R[K]>; }) => Task.Validation<E, R>;
4138
+ memoize: <E, A>(task: Task.Validation<E, A>) => Task.Validation<E, A>;
4139
+ };
4140
+ };
4141
+ type _CoreMaybe<A> = Maybe<A>;
4142
+ type _CoreResult<E, A> = Result<E, A>;
4143
+ type _CoreValidation<E, A> = Validation<E, A>;
4144
+ declare namespace Task {
4145
+ type LabeledTask<L extends string, A> = Task<A> & {
4146
+ readonly label: L;
4147
+ };
4148
+ type Maybe<A> = Task<_CoreMaybe<A>>;
4149
+ type Result<E, A> = Task<_CoreResult<E, A>>;
4150
+ type Validation<E, A> = Task<_CoreValidation<E, A>>;
4151
+ }
4152
+ //#endregion
4153
+ //#region src/Core/These.d.ts
4154
+ /**
4155
+ * These<A, B> is an inclusive-OR type: it holds a first value (A), a second
4156
+ * value (B), or both simultaneously. Neither side carries a success/failure
4157
+ * connotation — it is a neutral pair where any combination is valid.
4158
+ *
4159
+ * - First(a) — only a first value
4160
+ * - Second(b) — only a second value
4161
+ * - Both(a, b) — first and second values simultaneously
4162
+ *
4163
+ * A common use: lenient parsers or processors that carry a diagnostic note
4164
+ * alongside a result, without losing either piece of information.
4165
+ *
4166
+ * @example
4167
+ * ```ts
4168
+ * const parse = (s: string): These<number, string> => {
4169
+ * const trimmed = s.trim();
4170
+ * const n = parseFloat(trimmed);
4171
+ * if (isNaN(n)) return These.make.second("Not a number");
4172
+ * if (s !== trimmed) return These.make.both(n, "Leading/trailing whitespace trimmed");
4173
+ * return These.make.first(n);
4174
+ * };
4175
+ * ```
4176
+ */
4177
+ type These<A, B> = TheseFirst<A> | TheseSecond<B> | TheseBoth<A, B>;
4178
+ type TheseFirst<T> = WithKind<"First"> & WithFirst<T>;
4179
+ type TheseSecond<T> = WithKind<"Second"> & WithSecond<T>;
4180
+ type TheseBoth<First, Second> = WithKind<"Both"> & WithFirst<First> & WithSecond<Second>;
4181
+ declare const These: {
4182
+ make: {
4183
+ /**
4184
+ * Creates a These holding only a first value.
4185
+ *
4186
+ * @example
4187
+ * ```ts
4188
+ * These.make.first(42); // { kind: "First", first: 42 }
4189
+ * ```
4190
+ */
4191
+ first: <A>(value: A) => TheseFirst<A>;
4192
+ /**
4193
+ * Creates a These holding only a second value.
4194
+ *
4195
+ * @example
4196
+ * ```ts
4197
+ * These.make.second("warning"); // { kind: "Second", second: "warning" }
4198
+ * ```
4199
+ */
4200
+ second: <B>(value: B) => TheseSecond<B>;
4201
+ /**
4202
+ * Creates a These holding both a first and a second value simultaneously.
4203
+ *
4204
+ * @example
4205
+ * ```ts
4206
+ * These.make.both(42, "Deprecated API used"); // { kind: "Both", first: 42, second: "Deprecated API used" }
4207
+ * ```
4208
+ */
4209
+ both: <A, B>(f: A, s: B) => TheseBoth<A, B>;
4210
+ };
4211
+ is: {
4212
+ /**
4213
+ * Type guard — checks if a These holds only a first value.
4214
+ *
4215
+ * @example
4216
+ * ```ts
4217
+ * const val = These.make.first(42);
4218
+ * if (These.is.first(val)) {
4219
+ * console.log(val.first); // 42
4220
+ * }
4221
+ * ```
4222
+ */
4223
+ first: <A, B>(data: These<A, B>) => data is TheseFirst<A>;
4224
+ /**
4225
+ * Type guard — checks if a These holds only a second value.
4226
+ *
4227
+ * @example
4228
+ * ```ts
4229
+ * const val = These.make.second("warning");
4230
+ * if (These.is.second(val)) {
4231
+ * console.log(val.second); // "warning"
4232
+ * }
4233
+ * ```
4234
+ */
4235
+ second: <A, B>(data: These<A, B>) => data is TheseSecond<B>;
4236
+ /**
4237
+ * Type guard — checks if a These holds both values simultaneously.
4238
+ *
4239
+ * @example
4240
+ * ```ts
4241
+ * const val = These.make.both(42, "warning");
4242
+ * if (These.is.both(val)) {
4243
+ * console.log(val.first, val.second); // 42 "warning"
4244
+ * }
4245
+ * ```
4246
+ */
4247
+ both: <A, B>(data: These<A, B>) => data is TheseBoth<A, B>;
4248
+ };
4249
+ /**
4250
+ * Returns true if the These contains a first value (First or Both).
4251
+ *
4252
+ * @example
4253
+ * ```ts
4254
+ * These.hasFirst(These.make.first(42)); // true
4255
+ * These.hasFirst(These.make.both(42, "warn"));// true
4256
+ * These.hasFirst(These.make.second("warn")); // false
4257
+ * ```
4258
+ */
4259
+ hasFirst: <A, B>(data: These<A, B>) => data is TheseFirst<A> | TheseBoth<A, B>;
4260
+ /**
4261
+ * Returns true if the These contains a second value (Second or Both).
4262
+ *
4263
+ * @example
4264
+ * ```ts
4265
+ * These.hasSecond(These.make.second("warn")); // true
4266
+ * These.hasSecond(These.make.both(42, "warn"));// true
4267
+ * These.hasSecond(These.make.first(42)); // false
4268
+ * ```
4269
+ */
4270
+ hasSecond: <A, B>(data: These<A, B>) => data is TheseSecond<B> | TheseBoth<A, B>;
4271
+ /**
4272
+ * Transforms the first value, leaving the second unchanged.
4273
+ *
4274
+ * @example
4275
+ * ```ts
4276
+ * pipe(These.make.first(5), These.mapFirst(n => n * 2)); // First(10)
4277
+ * pipe(These.make.both(5, "warn"), These.mapFirst(n => n * 2)); // Both(10, "warn")
4278
+ * pipe(These.make.second("warn"), These.mapFirst(n => n * 2)); // Second("warn")
4279
+ * ```
4280
+ */
4281
+ mapFirst: <A, C>(f: (a: A) => C) => <B>(data: These<A, B>) => These<C, B>;
4282
+ /**
4283
+ * Transforms the second value, leaving the first unchanged.
4284
+ *
4285
+ * @example
4286
+ * ```ts
4287
+ * pipe(These.make.second("warn"), These.mapSecond(e => e.toUpperCase())); // Second("WARN")
4288
+ * pipe(These.make.both(5, "warn"), These.mapSecond(e => e.toUpperCase())); // Both(5, "WARN")
4289
+ * ```
4290
+ */
4291
+ mapSecond: <B, D>(f: (b: B) => D) => <A>(data: These<A, B>) => These<A, D>;
4292
+ /**
4293
+ * Transforms both the first and second values independently.
4294
+ *
4295
+ * @example
4296
+ * ```ts
4297
+ * pipe(
4298
+ * These.make.both(5, "warn"),
4299
+ * These.mapBoth(n => n * 2, e => e.toUpperCase())
4300
+ * ); // Both(10, "WARN")
4301
+ * ```
4302
+ */
4303
+ mapBoth: <A, C, B, D>(onFirst: (a: A) => C, onSecond: (b: B) => D) => (data: These<A, B>) => These<C, D>;
4304
+ /**
4305
+ * Chains These computations by passing the first value to f.
4306
+ * Second propagates unchanged; First and Both apply f to the first value.
4307
+ *
4308
+ * @example
4309
+ * ```ts
4310
+ * const double = (n: number): These<number, string> => These.make.first(n * 2);
4311
+ *
4312
+ * pipe(These.make.first(5), These.chainFirst(double)); // First(10)
4313
+ * pipe(These.make.both(5, "warn"), These.chainFirst(double)); // First(10)
4314
+ * pipe(These.make.second("warn"), These.chainFirst(double)); // Second("warn")
4315
+ * ```
4316
+ */
4317
+ chainFirst: <A, B, C>(f: (a: A) => These<C, B>) => (data: These<A, B>) => These<C, B>;
4318
+ /**
4319
+ * Chains These computations by passing the second value to f.
4320
+ * First propagates unchanged; Second and Both apply f to the second value.
4321
+ *
4322
+ * @example
4323
+ * ```ts
4324
+ * const shout = (s: string): These<number, string> => These.make.second(s.toUpperCase());
4325
+ *
4326
+ * pipe(These.make.second("warn"), These.chainSecond(shout)); // Second("WARN")
4327
+ * pipe(These.make.both(5, "warn"), These.chainSecond(shout)); // Second("WARN")
4328
+ * pipe(These.make.first(5), These.chainSecond(shout)); // First(5)
4329
+ * ```
4330
+ */
4331
+ chainSecond: <A, B, D>(f: (b: B) => These<A, D>) => (data: These<A, B>) => These<A, D>;
4332
+ /**
4333
+ * Extracts a value from a These by providing handlers for all three cases.
4334
+ *
4335
+ * @example
4336
+ * ```ts
4337
+ * pipe(
4338
+ * these,
4339
+ * These.fold(
4340
+ * a => `First: ${a}`,
4341
+ * b => `Second: ${b}`,
4342
+ * (a, b) => `Both: ${a} / ${b}`
4343
+ * )
4344
+ * );
4345
+ * ```
4346
+ */
4347
+ fold: <A, B, C>(onFirst: (a: A) => C, onSecond: (b: B) => C, onBoth: (a: A, b: B) => C) => (data: These<A, B>) => C;
4348
+ /**
4349
+ * Pattern matches on a These, returning the result of the matching case.
4350
+ *
4351
+ * @example
4352
+ * ```ts
4353
+ * pipe(
4354
+ * these,
4355
+ * These.match({
4356
+ * first: a => `First: ${a}`,
4357
+ * second: b => `Second: ${b}`,
4358
+ * both: (a, b) => `Both: ${a} / ${b}`
4359
+ * })
4360
+ * );
4361
+ * ```
4362
+ */
4363
+ match: <A, B, C>(cases: {
4364
+ first: (a: A) => C;
4365
+ second: (b: B) => C;
4366
+ both: (a: A, b: B) => C;
4367
+ }) => (data: These<A, B>) => C;
4368
+ /**
4369
+ * Returns the first value, or a default if the These has no first value.
4370
+ * The default can be a different type, widening the result to `A | C`.
4371
+ *
4372
+ * @example
4373
+ * ```ts
4374
+ * pipe(These.make.first(5), These.getFirstOrElse(() => 0)); // 5
4375
+ * pipe(These.make.both(5, "warn"), These.getFirstOrElse(() => 0)); // 5
4376
+ * pipe(These.make.second("warn"), These.getFirstOrElse(() => 0)); // 0
4377
+ * pipe(These.make.second("warn"), These.getFirstOrElse(() => null)); // null — typed as number | null
4378
+ * ```
4379
+ */
4380
+ getFirstOrElse: <A, C>(defaultValue: () => C) => <B>(data: These<A, B>) => A | C;
4381
+ /**
4382
+ * Returns the second value, or a default if the These has no second value.
4383
+ * The default can be a different type, widening the result to `B | D`.
4384
+ *
4385
+ * @example
4386
+ * ```ts
4387
+ * pipe(These.make.second("warn"), These.getSecondOrElse(() => "none")); // "warn"
4388
+ * pipe(These.make.both(5, "warn"), These.getSecondOrElse(() => "none")); // "warn"
4389
+ * pipe(These.make.first(5), These.getSecondOrElse(() => "none")); // "none"
4390
+ * pipe(These.make.first(5), These.getSecondOrElse(() => null)); // null — typed as string | null
4391
+ * ```
4392
+ */
4393
+ getSecondOrElse: <B, D>(defaultValue: () => D) => <A>(data: These<A, B>) => B | D;
4394
+ /**
4395
+ * Runs a side effect on the first value without changing the These.
4396
+ * Useful for logging or debugging.
4397
+ *
4398
+ * @example
4399
+ * ```ts
4400
+ * pipe(These.make.first(5), These.tap(console.log)); // logs 5, returns First(5)
4401
+ * ```
4402
+ */
4403
+ tap: <A>(f: (a: A) => void) => <B>(data: These<A, B>) => These<A, B>;
4404
+ /**
4405
+ * Swaps the roles of first and second values.
4406
+ * - First(a) → Second(a)
4407
+ * - Second(b) → First(b)
4408
+ * - Both(a, b) → Both(b, a)
4409
+ *
4410
+ * @example
4411
+ * ```ts
4412
+ * These.swap(These.make.first(5)); // Second(5)
4413
+ * These.swap(These.make.second("warn")); // First("warn")
4414
+ * These.swap(These.make.both(5, "warn")); // Both("warn", 5)
4415
+ * ```
4416
+ */
4417
+ swap: <A, B>(data: These<A, B>) => These<B, A>;
4418
+ };
4419
+ //#endregion
4420
+ export { Lens as A, Ordering as C, None as D, Maybe as E, EventBus as M, Equality as N, Some as O, Combinable as P, Pair as S, Op as T, RemoteData as _, Task as a, Reader as b, Validation as c, Ok$1 as d, Result as f, NotAsked as g, Loading as h, TheseSecond as i, Lazy as j, Logged as k, State$1 as l, Failure as m, TheseBoth as n, Failed as o, Resource as p, TheseFirst as r, Passed as s, These as t, Err$1 as u, Success as v, Optional as w, Predicate as x, Refinement as y };