@nlozgachev/pipelined 0.24.0 → 0.26.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.
@@ -84,50 +84,18 @@ type TimeoutOptions<E> = {
84
84
  readonly ms: number;
85
85
  readonly onTimeout: () => E;
86
86
  };
87
- type WithRetry<E> = {
88
- readonly retry: RetryOptions<E>;
89
- };
90
87
  type WithTimeout<E> = {
91
88
  readonly timeout?: TimeoutOptions<E>;
92
89
  };
93
90
  type WithMs = {
94
91
  readonly ms: number;
95
92
  };
96
- /** For `throttled`: also fire on the trailing edge after the cooldown. */
97
- type WithTrailing = {
98
- readonly trailing: true;
99
- };
100
- /** For `debounced`: also fire on the leading edge (first call). */
101
- type WithLeading = {
102
- readonly leading: true;
103
- };
104
- /** For `debounced`: maximum ms before the trailing call fires regardless of continued activity. */
105
- type WithMaxWait = {
106
- readonly maxWait: number;
107
- };
108
93
  type WithN = {
109
94
  readonly n: number;
110
95
  };
111
- /**
112
- * `O` is a string literal (or union of literals) representing the overflow value.
113
- * The generic lets overload signatures discriminate on the specific value:
114
- * `WithOverflow<"drop">` → `{ overflow: "drop" }`
115
- * `WithOverflow<"replace-last">` → `{ overflow: "replace-last" }`
116
- * Used by both `concurrent` (`"drop" | "queue"`) and `queue` (`"drop" | "replace-last"`).
117
- * `extends string` prevents `WithOverflow<42>` from being valid.
118
- */
119
- type WithOverflow<O extends string> = {
120
- readonly overflow: O;
121
- };
122
- type WithMaxSize = {
123
- readonly maxSize: number;
124
- };
125
96
  type WithConcurrency = {
126
97
  readonly concurrency?: number;
127
98
  };
128
- type WithDedupe<I> = {
129
- readonly dedupe: (a: I, b: I) => boolean;
130
- };
131
99
  type WithSize = {
132
100
  readonly size?: number;
133
101
  };
@@ -137,12 +105,6 @@ type WithCooldown = {
137
105
  type WithMinInterval = {
138
106
  readonly minInterval?: number;
139
107
  };
140
- type WithKey<I, K> = {
141
- readonly key: (input: I) => K;
142
- };
143
- type WithPerKey<S extends string> = {
144
- readonly perKey: S;
145
- };
146
108
 
147
109
  type Ok<A> = WithKind<"Ok"> & WithValue<A>;
148
110
  type Err<E> = WithKind<"Error"> & WithError<E>;
@@ -287,6 +249,20 @@ declare namespace Result {
287
249
  * ```
288
250
  */
289
251
  const tap: <E, A>(f: (a: A) => void) => (data: Result<E, A>) => Result<E, A>;
252
+ /**
253
+ * Executes a side effect on the error value without changing the Result.
254
+ * Useful for logging or reporting errors.
255
+ *
256
+ * @example
257
+ * ```ts
258
+ * pipe(
259
+ * Result.err("not found"),
260
+ * Result.tapError(e => console.error("validation failed:", e)),
261
+ * Result.chain(save),
262
+ * )
263
+ * ```
264
+ */
265
+ const tapError: <E, A>(f: (e: E) => void) => (data: Result<E, A>) => Result<E, A>;
290
266
  /**
291
267
  * Recovers from an error by providing a fallback Result.
292
268
  * The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
@@ -384,6 +360,20 @@ declare namespace Maybe {
384
360
  * Returns None if undefined, Some otherwise.
385
361
  */
386
362
  const fromUndefined: <A>(value: A | undefined) => Maybe<A>;
363
+ /**
364
+ * Creates a Maybe from a predicate applied to a value.
365
+ * Returns Some if the predicate passes, None otherwise.
366
+ *
367
+ * @example
368
+ * ```ts
369
+ * Maybe.fromPredicate((n: number) => n >= 18)(21); // Some(21)
370
+ * Maybe.fromPredicate((n: number) => n >= 18)(15); // None
371
+ *
372
+ * pipe("hello", Maybe.fromPredicate((s: string) => s.length > 0)); // Some("hello")
373
+ * pipe("", Maybe.fromPredicate((s: string) => s.length > 0)); // None
374
+ * ```
375
+ */
376
+ const fromPredicate: <A>(pred: (a: A) => boolean) => (a: A) => Maybe<A>;
387
377
  /**
388
378
  * Converts an Maybe to a Result.
389
379
  * Some becomes Ok, None becomes Err with the provided error.
@@ -777,4 +767,4 @@ declare namespace Task {
777
767
  };
778
768
  }
779
769
 
780
- export { Deferred as D, type Err as E, Maybe as M, type None as N, type Ok as O, Result as R, type Some as S, Task as T, type WithValue as W, type WithLog as a, type WithKind as b, type WithError as c, type RetryOptions as d, type TimeoutOptions as e, type WithMs as f, type WithTrailing as g, type WithRetry as h, type WithTimeout as i, type WithLeading as j, type WithMaxWait as k, type WithN as l, type WithOverflow as m, type WithKey as n, type WithPerKey as o, type WithMinInterval as p, type WithCooldown as q, type WithMaxSize as r, type WithDedupe as s, type WithConcurrency as t, type WithSize as u, type WithErrors as v, type WithFirst as w, type WithSecond as x };
770
+ export { Deferred as D, type Err as E, Maybe as M, type None as N, type Ok as O, Result as R, type Some as S, Task as T, type WithValue as W, type WithLog as a, type WithKind as b, type WithError as c, type RetryOptions as d, type TimeoutOptions as e, type WithTimeout as f, type WithMinInterval as g, type WithCooldown as h, type WithConcurrency as i, type WithSize as j, type WithMs as k, type WithN as l, type WithErrors as m, type WithFirst as n, type WithSecond as o };
@@ -84,50 +84,18 @@ type TimeoutOptions<E> = {
84
84
  readonly ms: number;
85
85
  readonly onTimeout: () => E;
86
86
  };
87
- type WithRetry<E> = {
88
- readonly retry: RetryOptions<E>;
89
- };
90
87
  type WithTimeout<E> = {
91
88
  readonly timeout?: TimeoutOptions<E>;
92
89
  };
93
90
  type WithMs = {
94
91
  readonly ms: number;
95
92
  };
96
- /** For `throttled`: also fire on the trailing edge after the cooldown. */
97
- type WithTrailing = {
98
- readonly trailing: true;
99
- };
100
- /** For `debounced`: also fire on the leading edge (first call). */
101
- type WithLeading = {
102
- readonly leading: true;
103
- };
104
- /** For `debounced`: maximum ms before the trailing call fires regardless of continued activity. */
105
- type WithMaxWait = {
106
- readonly maxWait: number;
107
- };
108
93
  type WithN = {
109
94
  readonly n: number;
110
95
  };
111
- /**
112
- * `O` is a string literal (or union of literals) representing the overflow value.
113
- * The generic lets overload signatures discriminate on the specific value:
114
- * `WithOverflow<"drop">` → `{ overflow: "drop" }`
115
- * `WithOverflow<"replace-last">` → `{ overflow: "replace-last" }`
116
- * Used by both `concurrent` (`"drop" | "queue"`) and `queue` (`"drop" | "replace-last"`).
117
- * `extends string` prevents `WithOverflow<42>` from being valid.
118
- */
119
- type WithOverflow<O extends string> = {
120
- readonly overflow: O;
121
- };
122
- type WithMaxSize = {
123
- readonly maxSize: number;
124
- };
125
96
  type WithConcurrency = {
126
97
  readonly concurrency?: number;
127
98
  };
128
- type WithDedupe<I> = {
129
- readonly dedupe: (a: I, b: I) => boolean;
130
- };
131
99
  type WithSize = {
132
100
  readonly size?: number;
133
101
  };
@@ -137,12 +105,6 @@ type WithCooldown = {
137
105
  type WithMinInterval = {
138
106
  readonly minInterval?: number;
139
107
  };
140
- type WithKey<I, K> = {
141
- readonly key: (input: I) => K;
142
- };
143
- type WithPerKey<S extends string> = {
144
- readonly perKey: S;
145
- };
146
108
 
147
109
  type Ok<A> = WithKind<"Ok"> & WithValue<A>;
148
110
  type Err<E> = WithKind<"Error"> & WithError<E>;
@@ -287,6 +249,20 @@ declare namespace Result {
287
249
  * ```
288
250
  */
289
251
  const tap: <E, A>(f: (a: A) => void) => (data: Result<E, A>) => Result<E, A>;
252
+ /**
253
+ * Executes a side effect on the error value without changing the Result.
254
+ * Useful for logging or reporting errors.
255
+ *
256
+ * @example
257
+ * ```ts
258
+ * pipe(
259
+ * Result.err("not found"),
260
+ * Result.tapError(e => console.error("validation failed:", e)),
261
+ * Result.chain(save),
262
+ * )
263
+ * ```
264
+ */
265
+ const tapError: <E, A>(f: (e: E) => void) => (data: Result<E, A>) => Result<E, A>;
290
266
  /**
291
267
  * Recovers from an error by providing a fallback Result.
292
268
  * The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
@@ -384,6 +360,20 @@ declare namespace Maybe {
384
360
  * Returns None if undefined, Some otherwise.
385
361
  */
386
362
  const fromUndefined: <A>(value: A | undefined) => Maybe<A>;
363
+ /**
364
+ * Creates a Maybe from a predicate applied to a value.
365
+ * Returns Some if the predicate passes, None otherwise.
366
+ *
367
+ * @example
368
+ * ```ts
369
+ * Maybe.fromPredicate((n: number) => n >= 18)(21); // Some(21)
370
+ * Maybe.fromPredicate((n: number) => n >= 18)(15); // None
371
+ *
372
+ * pipe("hello", Maybe.fromPredicate((s: string) => s.length > 0)); // Some("hello")
373
+ * pipe("", Maybe.fromPredicate((s: string) => s.length > 0)); // None
374
+ * ```
375
+ */
376
+ const fromPredicate: <A>(pred: (a: A) => boolean) => (a: A) => Maybe<A>;
387
377
  /**
388
378
  * Converts an Maybe to a Result.
389
379
  * Some becomes Ok, None becomes Err with the provided error.
@@ -777,4 +767,4 @@ declare namespace Task {
777
767
  };
778
768
  }
779
769
 
780
- export { Deferred as D, type Err as E, Maybe as M, type None as N, type Ok as O, Result as R, type Some as S, Task as T, type WithValue as W, type WithLog as a, type WithKind as b, type WithError as c, type RetryOptions as d, type TimeoutOptions as e, type WithMs as f, type WithTrailing as g, type WithRetry as h, type WithTimeout as i, type WithLeading as j, type WithMaxWait as k, type WithN as l, type WithOverflow as m, type WithKey as n, type WithPerKey as o, type WithMinInterval as p, type WithCooldown as q, type WithMaxSize as r, type WithDedupe as s, type WithConcurrency as t, type WithSize as u, type WithErrors as v, type WithFirst as w, type WithSecond as x };
770
+ export { Deferred as D, type Err as E, Maybe as M, type None as N, type Ok as O, Result as R, type Some as S, Task as T, type WithValue as W, type WithLog as a, type WithKind as b, type WithError as c, type RetryOptions as d, type TimeoutOptions as e, type WithTimeout as f, type WithMinInterval as g, type WithCooldown as h, type WithConcurrency as i, type WithSize as j, type WithMs as k, type WithN as l, type WithErrors as m, type WithFirst as n, type WithSecond as o };
@@ -3,7 +3,7 @@ import {
3
3
  Maybe,
4
4
  Result,
5
5
  Task
6
- } from "./chunk-2DPG2RDB.mjs";
6
+ } from "./chunk-Z3DYYR43.mjs";
7
7
  import {
8
8
  isNonEmptyList
9
9
  } from "./chunk-DBIC62UV.mjs";
@@ -43,6 +43,14 @@ var Arr;
43
43
  }
44
44
  return result;
45
45
  };
46
+ Arr2.filterMap = (f) => (data) => {
47
+ const result = [];
48
+ for (let i = 0; i < data.length; i++) {
49
+ const mapped = f(data[i]);
50
+ if (mapped.kind === "Some") result.push(mapped.value);
51
+ }
52
+ return result;
53
+ };
46
54
  Arr2.partition = (predicate) => (data) => {
47
55
  const pass = [];
48
56
  const fail = [];
@@ -471,6 +479,8 @@ var Str;
471
479
  Str2.split = (separator) => (s) => s.split(separator);
472
480
  Str2.trim = (s) => s.trim();
473
481
  Str2.includes = (substring) => (s) => s.includes(substring);
482
+ Str2.replace = (pattern, replacement) => (s) => s.replace(pattern, replacement);
483
+ Str2.replaceAll = (pattern, replacement) => (s) => s.replaceAll(pattern, replacement);
474
484
  Str2.startsWith = (prefix) => (s) => s.startsWith(prefix);
475
485
  Str2.endsWith = (suffix) => (s) => s.endsWith(suffix);
476
486
  Str2.toUpperCase = (s) => s.toUpperCase();
@@ -3,7 +3,7 @@ import {
3
3
  Maybe,
4
4
  Result,
5
5
  Task
6
- } from "./chunk-2DPG2RDB.mjs";
6
+ } from "./chunk-Z3DYYR43.mjs";
7
7
 
8
8
  // src/Core/Lens.ts
9
9
  var Lens;
@@ -1092,6 +1092,7 @@ var RemoteData;
1092
1092
  RemoteData2.recover = (fallback) => (data) => (0, RemoteData2.isFailure)(data) ? fallback(data.error) : data;
1093
1093
  RemoteData2.toMaybe = (data) => (0, RemoteData2.isSuccess)(data) ? Maybe.some(data.value) : Maybe.none();
1094
1094
  RemoteData2.toResult = (onNotReady) => (data) => (0, RemoteData2.isSuccess)(data) ? Result.ok(data.value) : Result.err((0, RemoteData2.isFailure)(data) ? data.error : onNotReady());
1095
+ RemoteData2.fromResult = (data) => Result.isOk(data) ? (0, RemoteData2.success)(data.value) : (0, RemoteData2.failure)(data.error);
1095
1096
  })(RemoteData || (RemoteData = {}));
1096
1097
 
1097
1098
  // src/Core/Resource.ts
@@ -1205,6 +1206,7 @@ var TaskResult;
1205
1206
  )(data);
1206
1207
  TaskResult2.getOrElse = (defaultValue) => (data) => Task.map(Result.getOrElse(defaultValue))(data);
1207
1208
  TaskResult2.tap = (f) => (data) => Task.map(Result.tap(f))(data);
1209
+ TaskResult2.tapError = (f) => (data) => Task.map(Result.tapError(f))(data);
1208
1210
  })(TaskResult || (TaskResult = {}));
1209
1211
 
1210
1212
  // src/Core/Validation.ts
@@ -20,6 +20,7 @@ var Maybe;
20
20
  Maybe2.toNullable = (data) => (0, Maybe2.isSome)(data) ? data.value : null;
21
21
  Maybe2.toUndefined = (data) => (0, Maybe2.isSome)(data) ? data.value : void 0;
22
22
  Maybe2.fromUndefined = (value) => value === void 0 ? (0, Maybe2.none)() : (0, Maybe2.some)(value);
23
+ Maybe2.fromPredicate = (pred) => (a) => pred(a) ? (0, Maybe2.some)(a) : (0, Maybe2.none)();
23
24
  Maybe2.toResult = (onNone) => (data) => (0, Maybe2.isSome)(data) ? Result.ok(data.value) : Result.err(onNone());
24
25
  Maybe2.fromResult = (data) => Result.isOk(data) ? (0, Maybe2.some)(data.value) : (0, Maybe2.none)();
25
26
  Maybe2.map = (f) => (data) => (0, Maybe2.isSome)(data) ? (0, Maybe2.some)(f(data.value)) : data;
@@ -60,6 +61,10 @@ var Result;
60
61
  if ((0, Result2.isOk)(data)) f(data.value);
61
62
  return data;
62
63
  };
64
+ Result2.tapError = (f) => (data) => {
65
+ if ((0, Result2.isErr)(data)) f(data.error);
66
+ return data;
67
+ };
63
68
  Result2.recover = (fallback) => (data) => (0, Result2.isOk)(data) ? data : fallback(data.error);
64
69
  Result2.recoverUnless = (blockedErr, fallback) => (data) => (0, Result2.isErr)(data) && data.error !== blockedErr ? fallback() : data;
65
70
  Result2.toMaybe = (data) => (0, Result2.isOk)(data) ? Maybe.some(data.value) : Maybe.none();
package/dist/core.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as Maybe, W as WithValue, a as WithLog, D as Deferred, R as Result, b as WithKind, c as WithError, d as RetryOptions, e as TimeoutOptions, f as WithMs, g as WithTrailing, h as WithRetry, i as WithTimeout, j as WithLeading, k as WithMaxWait, l as WithN, m as WithOverflow, n as WithKey, o as WithPerKey, p as WithMinInterval, q as WithCooldown, r as WithMaxSize, s as WithDedupe, t as WithConcurrency, u as WithSize, T as Task, v as WithErrors, w as WithFirst, x as WithSecond } from './Task-CT8iwwuB.mjs';
2
- export { E as Err, N as None, O as Ok, S as Some } from './Task-CT8iwwuB.mjs';
1
+ import { M as Maybe, W as WithValue, a as WithLog, D as Deferred, R as Result, b as WithKind, c as WithError, d as RetryOptions, e as TimeoutOptions, f as WithTimeout, g as WithMinInterval, h as WithCooldown, i as WithConcurrency, j as WithSize, k as WithMs, l as WithN, T as Task, m as WithErrors, n as WithFirst, o as WithSecond } from './Task-BoqaFsUR.mjs';
2
+ export { E as Err, N as None, O as Ok, S as Some } from './Task-BoqaFsUR.mjs';
3
3
  import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.mjs';
4
4
 
5
5
  /** Keys of T for which undefined is assignable (i.e. optional fields). */
@@ -399,6 +399,89 @@ declare namespace Logged {
399
399
  const run: <W, A>(data: Logged<W, A>) => readonly [A, ReadonlyArray<W>];
400
400
  }
401
401
 
402
+ type MaybeRetry<E, O> = O extends {
403
+ retry: RetryOptions<E>;
404
+ } ? Op.Retrying<E> : never;
405
+ type AllInterpretOptions<I, E> = ({
406
+ strategy: "once";
407
+ retry?: RetryOptions<E>;
408
+ } & WithTimeout<E>) | ({
409
+ strategy: "restartable";
410
+ retry?: RetryOptions<E>;
411
+ } & WithMinInterval & WithTimeout<E>) | ({
412
+ strategy: "exclusive";
413
+ retry?: RetryOptions<E>;
414
+ } & WithCooldown & WithTimeout<E>) | ({
415
+ strategy: "queue";
416
+ retry?: RetryOptions<E>;
417
+ maxSize?: number;
418
+ overflow?: "drop" | "replace-last";
419
+ dedupe?: (a: I, b: I) => boolean;
420
+ } & WithConcurrency & WithTimeout<E>) | ({
421
+ strategy: "buffered";
422
+ retry?: RetryOptions<E>;
423
+ } & WithSize & WithTimeout<E>) | ({
424
+ strategy: "debounced";
425
+ retry?: RetryOptions<E>;
426
+ leading?: true;
427
+ maxWait?: number;
428
+ } & WithMs & WithTimeout<E>) | ({
429
+ strategy: "throttled";
430
+ retry?: RetryOptions<E>;
431
+ trailing?: true;
432
+ } & WithMs & WithTimeout<E>) | ({
433
+ strategy: "concurrent";
434
+ retry?: RetryOptions<E>;
435
+ overflow?: "queue" | "drop";
436
+ } & WithN & WithTimeout<E>) | ({
437
+ strategy: "keyed";
438
+ perKey?: "exclusive" | "restartable";
439
+ key: (input: I) => unknown;
440
+ } & WithTimeout<E>);
441
+ type KeyType<I, O> = O extends {
442
+ key: (input: I) => infer K;
443
+ } ? K : unknown;
444
+ type InterpretResult<I, E, A, O> = [O] extends [{
445
+ strategy: "throttled";
446
+ trailing: true;
447
+ }] ? Op.Manager<I, E, A, Op.ThrottledTrailingState<E, A> | MaybeRetry<E, O>> : [O] extends [{
448
+ strategy: "throttled";
449
+ }] ? Op.Manager<I, E, A, Op.ThrottledState<E, A> | MaybeRetry<E, O>> : [O] extends [{
450
+ strategy: "debounced";
451
+ }] ? Op.Manager<I, E, A, Op.DebouncedState<E, A> | MaybeRetry<E, O>> : [O] extends [{
452
+ strategy: "concurrent";
453
+ overflow: "queue";
454
+ }] ? Op.Manager<I, E, A, Op.ConcurrentQueueState<E, A> | MaybeRetry<E, O>> : [O] extends [{
455
+ strategy: "concurrent";
456
+ }] ? Op.Manager<I, E, A, Op.ConcurrentDropState<E, A> | MaybeRetry<E, O>> : [O] extends [{
457
+ strategy: "keyed";
458
+ perKey: "restartable";
459
+ }] ? Op.KeyedManager<I, KeyType<I, O>, E, Op.KeyedRestartablePerKey<E, A>> : [O] extends [{
460
+ strategy: "keyed";
461
+ }] ? Op.KeyedManager<I, KeyType<I, O>, E, Op.KeyedExclusivePerKey<E, A>> : [O] extends [{
462
+ strategy: "once";
463
+ }] ? Op.Manager<I, E, A, Op.OnceState<E, A> | MaybeRetry<E, O>> : [O] extends [{
464
+ strategy: "restartable";
465
+ }] ? Op.Manager<I, E, A, Op.RestartableState<E, A> | MaybeRetry<E, O>> : [O] extends [{
466
+ strategy: "exclusive";
467
+ }] ? Op.Manager<I, E, A, Op.ExclusiveState<E, A> | MaybeRetry<E, O>> : [O] extends [{
468
+ strategy: "queue";
469
+ overflow: "replace-last";
470
+ dedupe: (a: I, b: I) => boolean;
471
+ }] ? Op.Manager<I, E, A, Op.QueueDropAndReplaceState<E, A> | MaybeRetry<E, O>> : [O] extends [{
472
+ strategy: "queue";
473
+ overflow: "replace-last";
474
+ }] ? Op.Manager<I, E, A, Op.QueueReplaceState<E, A> | MaybeRetry<E, O>> : [O] extends [{
475
+ strategy: "queue";
476
+ maxSize: number;
477
+ }] ? Op.Manager<I, E, A, Op.QueueDropState<E, A> | MaybeRetry<E, O>> : [O] extends [{
478
+ strategy: "queue";
479
+ dedupe: (a: I, b: I) => boolean;
480
+ }] ? Op.Manager<I, E, A, Op.QueueDropState<E, A> | MaybeRetry<E, O>> : [O] extends [{
481
+ strategy: "queue";
482
+ }] ? Op.Manager<I, E, A, Op.QueueState<E, A> | MaybeRetry<E, O>> : [O] extends [{
483
+ strategy: "buffered";
484
+ }] ? Op.Manager<I, E, A, Op.BufferedState<E, A> | MaybeRetry<E, O>> : never;
402
485
  /**
403
486
  * A reusable description of async work — decoupled from execution strategy and lifetime.
404
487
  *
@@ -412,7 +495,11 @@ declare namespace Logged {
412
495
  * @example
413
496
  * ```ts
414
497
  * const fetchUser = Op.create(
415
- * (signal) => (id: string) => fetch(`/users/${id}`, { signal }).then(r => r.json()),
498
+ * (signal) => (id: string) =>
499
+ * fetch(`/users/${id}`, { signal }).then(r => {
500
+ * if (!r.ok) throw new Error(`${r.status} ${r.statusText}`);
501
+ * return r.json() as Promise<User>;
502
+ * }),
416
503
  * (e) => new ApiError(e),
417
504
  * );
418
505
  *
@@ -655,22 +742,42 @@ declare namespace Op {
655
742
  /**
656
743
  * Creates an `Op` from an async factory and an error mapper.
657
744
  *
658
- * The factory receives an `AbortSignal` and returns a function that takes the input.
659
- * Operations that support cancellation (like `fetch`) should capture the signal in the
660
- * outer closure. The error mapper converts any thrown value into a typed error; it is
661
- * never called for aborts.
745
+ * The factory receives an `AbortSignal` and returns a function that takes the input. Capture
746
+ * the signal in the outer closure and pass it to cancellable APIs like `fetch`. The error
747
+ * mapper converts any thrown value into a typed error; it is never called for aborts.
748
+ *
749
+ * **If the factory ignores the signal**, cancellation silently stops working: the operation
750
+ * runs to completion and emits `Ok` even after the strategy has aborted it. This is harmless
751
+ * for `exclusive` and `once` (which do not abort in-flight work), but causes stale `Ok`
752
+ * emissions on `restartable`, `debounced`, `throttled`, `buffered`, and `queue` strategies
753
+ * where in-flight runs are regularly replaced or dropped.
662
754
  *
663
755
  * @example
664
756
  * ```ts
757
+ * // With cancellation — fetch is aborted when the Op is replaced or aborted
665
758
  * const saveProfile = Op.create(
666
759
  * (signal) => (data: ProfileData) =>
667
760
  * fetch("/profile", { method: "POST", body: JSON.stringify(data), signal })
668
- * .then(r => r.json()),
761
+ * .then(r => {
762
+ * if (!r.ok) throw new Error(`${r.status} ${r.statusText}`);
763
+ * return r.json() as Promise<ProfileData>;
764
+ * }),
669
765
  * (e) => new ApiError(e),
670
766
  * );
767
+ *
768
+ * // No input — fetches the current user; manager.run() takes no arguments
769
+ * const fetchCurrentUser = Op.create(
770
+ * (signal) => () => fetch("/me", { signal }).then(r => {
771
+ * if (!r.ok) throw new Error(`${r.status} ${r.statusText}`);
772
+ * return r.json() as Promise<User>;
773
+ * }),
774
+ * (e) => new ApiError(e),
775
+ * );
776
+ * const manager = Op.interpret(fetchCurrentUser, { strategy: "once" });
777
+ * manager.run(); // no argument needed
671
778
  * ```
672
779
  */
673
- const create: <I, E, A>(factory: (signal: AbortSignal) => (input: I) => Promise<A>, onError: (e: unknown) => E) => Op<I, E, A>;
780
+ const create: <E, A, I = void>(factory: (signal: AbortSignal) => (input: I) => Promise<A>, onError: (e: unknown) => E) => Op<I, E, A>;
674
781
  /**
675
782
  * Creates a successful Outcome.
676
783
  *
@@ -890,108 +997,7 @@ declare namespace Op {
890
997
  * const save = Op.interpret(saveOp, { strategy: "buffered" });
891
998
  * ```
892
999
  */
893
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
894
- strategy: "throttled";
895
- } & WithMs & WithTrailing & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableThrottledTrailingState<E, A>>;
896
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
897
- strategy: "throttled";
898
- } & WithMs & WithTrailing & WithTimeout<E>): Manager<I, E, A, ThrottledTrailingState<E, A>>;
899
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
900
- strategy: "throttled";
901
- } & WithMs & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableThrottledState<E, A>>;
902
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
903
- strategy: "throttled";
904
- } & WithMs & WithTimeout<E>): Manager<I, E, A, ThrottledState<E, A>>;
905
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
906
- strategy: "debounced";
907
- } & WithMs & WithLeading & WithMaxWait & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableDebouncedState<E, A>>;
908
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
909
- strategy: "debounced";
910
- } & WithMs & WithLeading & WithMaxWait & WithTimeout<E>): Manager<I, E, A, DebouncedState<E, A>>;
911
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
912
- strategy: "debounced";
913
- } & WithMs & WithLeading & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableDebouncedState<E, A>>;
914
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
915
- strategy: "debounced";
916
- } & WithMs & WithLeading & WithTimeout<E>): Manager<I, E, A, DebouncedState<E, A>>;
917
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
918
- strategy: "debounced";
919
- } & WithMs & WithMaxWait & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableDebouncedState<E, A>>;
920
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
921
- strategy: "debounced";
922
- } & WithMs & WithMaxWait & WithTimeout<E>): Manager<I, E, A, DebouncedState<E, A>>;
923
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
924
- strategy: "debounced";
925
- } & WithMs & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableDebouncedState<E, A>>;
926
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
927
- strategy: "debounced";
928
- } & WithMs & WithTimeout<E>): Manager<I, E, A, DebouncedState<E, A>>;
929
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
930
- strategy: "concurrent";
931
- } & WithN & WithOverflow<"queue"> & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableConcurrentQueueState<E, A>>;
932
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
933
- strategy: "concurrent";
934
- } & WithN & WithOverflow<"queue"> & WithTimeout<E>): Manager<I, E, A, ConcurrentQueueState<E, A>>;
935
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
936
- strategy: "concurrent";
937
- } & WithN & WithOverflow<"drop"> & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableConcurrentDropState<E, A>>;
938
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
939
- strategy: "concurrent";
940
- } & WithN & WithOverflow<"drop"> & WithTimeout<E>): Manager<I, E, A, ConcurrentDropState<E, A>>;
941
- function interpret<I, K, E, A>(op: Op<I, E, A>, options: {
942
- strategy: "keyed";
943
- } & WithKey<I, K> & WithPerKey<"exclusive"> & WithTimeout<E>): KeyedManager<I, K, E, KeyedExclusivePerKey<E, A>>;
944
- function interpret<I, K, E, A>(op: Op<I, E, A>, options: {
945
- strategy: "keyed";
946
- } & WithKey<I, K> & WithPerKey<"restartable"> & WithTimeout<E>): KeyedManager<I, K, E, KeyedRestartablePerKey<E, A>>;
947
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
948
- strategy: "once";
949
- } & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableOnceState<E, A>>;
950
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
951
- strategy: "once";
952
- } & WithTimeout<E>): Manager<I, E, A, OnceState<E, A>>;
953
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
954
- strategy: "restartable";
955
- } & WithMinInterval & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableRestartableState<E, A>>;
956
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
957
- strategy: "restartable";
958
- } & WithMinInterval & WithTimeout<E>): Manager<I, E, A, RestartableState<E, A>>;
959
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
960
- strategy: "exclusive";
961
- } & WithCooldown & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableExclusiveState<E, A>>;
962
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
963
- strategy: "exclusive";
964
- } & WithCooldown & WithTimeout<E>): Manager<I, E, A, ExclusiveState<E, A>>;
965
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
966
- strategy: "queue";
967
- } & WithMaxSize & WithOverflow<"replace-last"> & WithDedupe<I> & WithRetry<E> & WithConcurrency & WithTimeout<E>): Manager<I, E, A, RetryableQueueDropAndReplaceState<E, A>>;
968
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
969
- strategy: "queue";
970
- } & WithMaxSize & WithOverflow<"replace-last"> & WithDedupe<I> & WithConcurrency & WithTimeout<E>): Manager<I, E, A, QueueDropAndReplaceState<E, A>>;
971
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
972
- strategy: "queue";
973
- } & WithMaxSize & WithOverflow<"replace-last"> & WithRetry<E> & WithConcurrency & WithTimeout<E>): Manager<I, E, A, RetryableQueueReplaceState<E, A>>;
974
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
975
- strategy: "queue";
976
- } & WithMaxSize & WithOverflow<"replace-last"> & WithConcurrency & WithTimeout<E>): Manager<I, E, A, QueueReplaceState<E, A>>;
977
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
978
- strategy: "queue";
979
- } & (WithMaxSize | WithDedupe<I>) & WithRetry<E> & WithConcurrency & WithTimeout<E>): Manager<I, E, A, RetryableQueueDropState<E, A>>;
980
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
981
- strategy: "queue";
982
- } & (WithMaxSize | WithDedupe<I>) & WithConcurrency & WithTimeout<E>): Manager<I, E, A, QueueDropState<E, A>>;
983
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
984
- strategy: "queue";
985
- } & WithRetry<E> & WithConcurrency & WithTimeout<E>): Manager<I, E, A, RetryableQueueState<E, A>>;
986
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
987
- strategy: "queue";
988
- } & WithConcurrency & WithTimeout<E>): Manager<I, E, A, QueueState<E, A>>;
989
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
990
- strategy: "buffered";
991
- } & WithSize & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableBufferedState<E, A>>;
992
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
993
- strategy: "buffered";
994
- } & WithSize & WithTimeout<E>): Manager<I, E, A, BufferedState<E, A>>;
1000
+ function interpret<I, E, A, O extends AllInterpretOptions<I, E>>(op: Op<I, E, A>, options: O): InterpretResult<I, E, A, O>;
995
1001
  }
996
1002
 
997
1003
  /**
@@ -1638,6 +1644,17 @@ declare namespace RemoteData {
1638
1644
  * ```
1639
1645
  */
1640
1646
  const toResult: <E>(onNotReady: () => E) => <A>(data: RemoteData<E, A>) => Result<E, A>;
1647
+ /**
1648
+ * Converts a Result to a RemoteData.
1649
+ * Ok becomes Success, Err becomes Failure.
1650
+ *
1651
+ * @example
1652
+ * ```ts
1653
+ * const result = await TaskResult.tryCatch(fetchUser, String)();
1654
+ * setState(RemoteData.fromResult(result)); // Success(user) or Failure(msg)
1655
+ * ```
1656
+ */
1657
+ const fromResult: <E, A>(data: Result<E, A>) => RemoteData<E, A>;
1641
1658
  }
1642
1659
 
1643
1660
  /**
@@ -1717,6 +1734,20 @@ declare namespace TaskResult {
1717
1734
  * Useful for logging or debugging.
1718
1735
  */
1719
1736
  const tap: <E, A>(f: (a: A) => void) => (data: TaskResult<E, A>) => TaskResult<E, A>;
1737
+ /**
1738
+ * Executes a side effect on the error value without changing the TaskResult.
1739
+ * Useful for logging or reporting async errors.
1740
+ *
1741
+ * @example
1742
+ * ```ts
1743
+ * pipe(
1744
+ * fetchUser(id),
1745
+ * TaskResult.tapError(e => console.error("fetch failed:", e)),
1746
+ * TaskResult.chain(saveToCache),
1747
+ * )
1748
+ * ```
1749
+ */
1750
+ const tapError: <E, A>(f: (e: E) => void) => (data: TaskResult<E, A>) => TaskResult<E, A>;
1720
1751
  }
1721
1752
 
1722
1753
  /**
package/dist/core.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as Maybe, W as WithValue, a as WithLog, D as Deferred, R as Result, b as WithKind, c as WithError, d as RetryOptions, e as TimeoutOptions, f as WithMs, g as WithTrailing, h as WithRetry, i as WithTimeout, j as WithLeading, k as WithMaxWait, l as WithN, m as WithOverflow, n as WithKey, o as WithPerKey, p as WithMinInterval, q as WithCooldown, r as WithMaxSize, s as WithDedupe, t as WithConcurrency, u as WithSize, T as Task, v as WithErrors, w as WithFirst, x as WithSecond } from './Task-GSGtQO1m.js';
2
- export { E as Err, N as None, O as Ok, S as Some } from './Task-GSGtQO1m.js';
1
+ import { M as Maybe, W as WithValue, a as WithLog, D as Deferred, R as Result, b as WithKind, c as WithError, d as RetryOptions, e as TimeoutOptions, f as WithTimeout, g as WithMinInterval, h as WithCooldown, i as WithConcurrency, j as WithSize, k as WithMs, l as WithN, T as Task, m as WithErrors, n as WithFirst, o as WithSecond } from './Task-7brqoQrb.js';
2
+ export { E as Err, N as None, O as Ok, S as Some } from './Task-7brqoQrb.js';
3
3
  import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.js';
4
4
 
5
5
  /** Keys of T for which undefined is assignable (i.e. optional fields). */
@@ -399,6 +399,89 @@ declare namespace Logged {
399
399
  const run: <W, A>(data: Logged<W, A>) => readonly [A, ReadonlyArray<W>];
400
400
  }
401
401
 
402
+ type MaybeRetry<E, O> = O extends {
403
+ retry: RetryOptions<E>;
404
+ } ? Op.Retrying<E> : never;
405
+ type AllInterpretOptions<I, E> = ({
406
+ strategy: "once";
407
+ retry?: RetryOptions<E>;
408
+ } & WithTimeout<E>) | ({
409
+ strategy: "restartable";
410
+ retry?: RetryOptions<E>;
411
+ } & WithMinInterval & WithTimeout<E>) | ({
412
+ strategy: "exclusive";
413
+ retry?: RetryOptions<E>;
414
+ } & WithCooldown & WithTimeout<E>) | ({
415
+ strategy: "queue";
416
+ retry?: RetryOptions<E>;
417
+ maxSize?: number;
418
+ overflow?: "drop" | "replace-last";
419
+ dedupe?: (a: I, b: I) => boolean;
420
+ } & WithConcurrency & WithTimeout<E>) | ({
421
+ strategy: "buffered";
422
+ retry?: RetryOptions<E>;
423
+ } & WithSize & WithTimeout<E>) | ({
424
+ strategy: "debounced";
425
+ retry?: RetryOptions<E>;
426
+ leading?: true;
427
+ maxWait?: number;
428
+ } & WithMs & WithTimeout<E>) | ({
429
+ strategy: "throttled";
430
+ retry?: RetryOptions<E>;
431
+ trailing?: true;
432
+ } & WithMs & WithTimeout<E>) | ({
433
+ strategy: "concurrent";
434
+ retry?: RetryOptions<E>;
435
+ overflow?: "queue" | "drop";
436
+ } & WithN & WithTimeout<E>) | ({
437
+ strategy: "keyed";
438
+ perKey?: "exclusive" | "restartable";
439
+ key: (input: I) => unknown;
440
+ } & WithTimeout<E>);
441
+ type KeyType<I, O> = O extends {
442
+ key: (input: I) => infer K;
443
+ } ? K : unknown;
444
+ type InterpretResult<I, E, A, O> = [O] extends [{
445
+ strategy: "throttled";
446
+ trailing: true;
447
+ }] ? Op.Manager<I, E, A, Op.ThrottledTrailingState<E, A> | MaybeRetry<E, O>> : [O] extends [{
448
+ strategy: "throttled";
449
+ }] ? Op.Manager<I, E, A, Op.ThrottledState<E, A> | MaybeRetry<E, O>> : [O] extends [{
450
+ strategy: "debounced";
451
+ }] ? Op.Manager<I, E, A, Op.DebouncedState<E, A> | MaybeRetry<E, O>> : [O] extends [{
452
+ strategy: "concurrent";
453
+ overflow: "queue";
454
+ }] ? Op.Manager<I, E, A, Op.ConcurrentQueueState<E, A> | MaybeRetry<E, O>> : [O] extends [{
455
+ strategy: "concurrent";
456
+ }] ? Op.Manager<I, E, A, Op.ConcurrentDropState<E, A> | MaybeRetry<E, O>> : [O] extends [{
457
+ strategy: "keyed";
458
+ perKey: "restartable";
459
+ }] ? Op.KeyedManager<I, KeyType<I, O>, E, Op.KeyedRestartablePerKey<E, A>> : [O] extends [{
460
+ strategy: "keyed";
461
+ }] ? Op.KeyedManager<I, KeyType<I, O>, E, Op.KeyedExclusivePerKey<E, A>> : [O] extends [{
462
+ strategy: "once";
463
+ }] ? Op.Manager<I, E, A, Op.OnceState<E, A> | MaybeRetry<E, O>> : [O] extends [{
464
+ strategy: "restartable";
465
+ }] ? Op.Manager<I, E, A, Op.RestartableState<E, A> | MaybeRetry<E, O>> : [O] extends [{
466
+ strategy: "exclusive";
467
+ }] ? Op.Manager<I, E, A, Op.ExclusiveState<E, A> | MaybeRetry<E, O>> : [O] extends [{
468
+ strategy: "queue";
469
+ overflow: "replace-last";
470
+ dedupe: (a: I, b: I) => boolean;
471
+ }] ? Op.Manager<I, E, A, Op.QueueDropAndReplaceState<E, A> | MaybeRetry<E, O>> : [O] extends [{
472
+ strategy: "queue";
473
+ overflow: "replace-last";
474
+ }] ? Op.Manager<I, E, A, Op.QueueReplaceState<E, A> | MaybeRetry<E, O>> : [O] extends [{
475
+ strategy: "queue";
476
+ maxSize: number;
477
+ }] ? Op.Manager<I, E, A, Op.QueueDropState<E, A> | MaybeRetry<E, O>> : [O] extends [{
478
+ strategy: "queue";
479
+ dedupe: (a: I, b: I) => boolean;
480
+ }] ? Op.Manager<I, E, A, Op.QueueDropState<E, A> | MaybeRetry<E, O>> : [O] extends [{
481
+ strategy: "queue";
482
+ }] ? Op.Manager<I, E, A, Op.QueueState<E, A> | MaybeRetry<E, O>> : [O] extends [{
483
+ strategy: "buffered";
484
+ }] ? Op.Manager<I, E, A, Op.BufferedState<E, A> | MaybeRetry<E, O>> : never;
402
485
  /**
403
486
  * A reusable description of async work — decoupled from execution strategy and lifetime.
404
487
  *
@@ -412,7 +495,11 @@ declare namespace Logged {
412
495
  * @example
413
496
  * ```ts
414
497
  * const fetchUser = Op.create(
415
- * (signal) => (id: string) => fetch(`/users/${id}`, { signal }).then(r => r.json()),
498
+ * (signal) => (id: string) =>
499
+ * fetch(`/users/${id}`, { signal }).then(r => {
500
+ * if (!r.ok) throw new Error(`${r.status} ${r.statusText}`);
501
+ * return r.json() as Promise<User>;
502
+ * }),
416
503
  * (e) => new ApiError(e),
417
504
  * );
418
505
  *
@@ -655,22 +742,42 @@ declare namespace Op {
655
742
  /**
656
743
  * Creates an `Op` from an async factory and an error mapper.
657
744
  *
658
- * The factory receives an `AbortSignal` and returns a function that takes the input.
659
- * Operations that support cancellation (like `fetch`) should capture the signal in the
660
- * outer closure. The error mapper converts any thrown value into a typed error; it is
661
- * never called for aborts.
745
+ * The factory receives an `AbortSignal` and returns a function that takes the input. Capture
746
+ * the signal in the outer closure and pass it to cancellable APIs like `fetch`. The error
747
+ * mapper converts any thrown value into a typed error; it is never called for aborts.
748
+ *
749
+ * **If the factory ignores the signal**, cancellation silently stops working: the operation
750
+ * runs to completion and emits `Ok` even after the strategy has aborted it. This is harmless
751
+ * for `exclusive` and `once` (which do not abort in-flight work), but causes stale `Ok`
752
+ * emissions on `restartable`, `debounced`, `throttled`, `buffered`, and `queue` strategies
753
+ * where in-flight runs are regularly replaced or dropped.
662
754
  *
663
755
  * @example
664
756
  * ```ts
757
+ * // With cancellation — fetch is aborted when the Op is replaced or aborted
665
758
  * const saveProfile = Op.create(
666
759
  * (signal) => (data: ProfileData) =>
667
760
  * fetch("/profile", { method: "POST", body: JSON.stringify(data), signal })
668
- * .then(r => r.json()),
761
+ * .then(r => {
762
+ * if (!r.ok) throw new Error(`${r.status} ${r.statusText}`);
763
+ * return r.json() as Promise<ProfileData>;
764
+ * }),
669
765
  * (e) => new ApiError(e),
670
766
  * );
767
+ *
768
+ * // No input — fetches the current user; manager.run() takes no arguments
769
+ * const fetchCurrentUser = Op.create(
770
+ * (signal) => () => fetch("/me", { signal }).then(r => {
771
+ * if (!r.ok) throw new Error(`${r.status} ${r.statusText}`);
772
+ * return r.json() as Promise<User>;
773
+ * }),
774
+ * (e) => new ApiError(e),
775
+ * );
776
+ * const manager = Op.interpret(fetchCurrentUser, { strategy: "once" });
777
+ * manager.run(); // no argument needed
671
778
  * ```
672
779
  */
673
- const create: <I, E, A>(factory: (signal: AbortSignal) => (input: I) => Promise<A>, onError: (e: unknown) => E) => Op<I, E, A>;
780
+ const create: <E, A, I = void>(factory: (signal: AbortSignal) => (input: I) => Promise<A>, onError: (e: unknown) => E) => Op<I, E, A>;
674
781
  /**
675
782
  * Creates a successful Outcome.
676
783
  *
@@ -890,108 +997,7 @@ declare namespace Op {
890
997
  * const save = Op.interpret(saveOp, { strategy: "buffered" });
891
998
  * ```
892
999
  */
893
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
894
- strategy: "throttled";
895
- } & WithMs & WithTrailing & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableThrottledTrailingState<E, A>>;
896
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
897
- strategy: "throttled";
898
- } & WithMs & WithTrailing & WithTimeout<E>): Manager<I, E, A, ThrottledTrailingState<E, A>>;
899
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
900
- strategy: "throttled";
901
- } & WithMs & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableThrottledState<E, A>>;
902
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
903
- strategy: "throttled";
904
- } & WithMs & WithTimeout<E>): Manager<I, E, A, ThrottledState<E, A>>;
905
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
906
- strategy: "debounced";
907
- } & WithMs & WithLeading & WithMaxWait & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableDebouncedState<E, A>>;
908
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
909
- strategy: "debounced";
910
- } & WithMs & WithLeading & WithMaxWait & WithTimeout<E>): Manager<I, E, A, DebouncedState<E, A>>;
911
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
912
- strategy: "debounced";
913
- } & WithMs & WithLeading & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableDebouncedState<E, A>>;
914
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
915
- strategy: "debounced";
916
- } & WithMs & WithLeading & WithTimeout<E>): Manager<I, E, A, DebouncedState<E, A>>;
917
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
918
- strategy: "debounced";
919
- } & WithMs & WithMaxWait & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableDebouncedState<E, A>>;
920
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
921
- strategy: "debounced";
922
- } & WithMs & WithMaxWait & WithTimeout<E>): Manager<I, E, A, DebouncedState<E, A>>;
923
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
924
- strategy: "debounced";
925
- } & WithMs & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableDebouncedState<E, A>>;
926
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
927
- strategy: "debounced";
928
- } & WithMs & WithTimeout<E>): Manager<I, E, A, DebouncedState<E, A>>;
929
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
930
- strategy: "concurrent";
931
- } & WithN & WithOverflow<"queue"> & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableConcurrentQueueState<E, A>>;
932
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
933
- strategy: "concurrent";
934
- } & WithN & WithOverflow<"queue"> & WithTimeout<E>): Manager<I, E, A, ConcurrentQueueState<E, A>>;
935
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
936
- strategy: "concurrent";
937
- } & WithN & WithOverflow<"drop"> & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableConcurrentDropState<E, A>>;
938
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
939
- strategy: "concurrent";
940
- } & WithN & WithOverflow<"drop"> & WithTimeout<E>): Manager<I, E, A, ConcurrentDropState<E, A>>;
941
- function interpret<I, K, E, A>(op: Op<I, E, A>, options: {
942
- strategy: "keyed";
943
- } & WithKey<I, K> & WithPerKey<"exclusive"> & WithTimeout<E>): KeyedManager<I, K, E, KeyedExclusivePerKey<E, A>>;
944
- function interpret<I, K, E, A>(op: Op<I, E, A>, options: {
945
- strategy: "keyed";
946
- } & WithKey<I, K> & WithPerKey<"restartable"> & WithTimeout<E>): KeyedManager<I, K, E, KeyedRestartablePerKey<E, A>>;
947
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
948
- strategy: "once";
949
- } & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableOnceState<E, A>>;
950
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
951
- strategy: "once";
952
- } & WithTimeout<E>): Manager<I, E, A, OnceState<E, A>>;
953
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
954
- strategy: "restartable";
955
- } & WithMinInterval & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableRestartableState<E, A>>;
956
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
957
- strategy: "restartable";
958
- } & WithMinInterval & WithTimeout<E>): Manager<I, E, A, RestartableState<E, A>>;
959
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
960
- strategy: "exclusive";
961
- } & WithCooldown & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableExclusiveState<E, A>>;
962
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
963
- strategy: "exclusive";
964
- } & WithCooldown & WithTimeout<E>): Manager<I, E, A, ExclusiveState<E, A>>;
965
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
966
- strategy: "queue";
967
- } & WithMaxSize & WithOverflow<"replace-last"> & WithDedupe<I> & WithRetry<E> & WithConcurrency & WithTimeout<E>): Manager<I, E, A, RetryableQueueDropAndReplaceState<E, A>>;
968
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
969
- strategy: "queue";
970
- } & WithMaxSize & WithOverflow<"replace-last"> & WithDedupe<I> & WithConcurrency & WithTimeout<E>): Manager<I, E, A, QueueDropAndReplaceState<E, A>>;
971
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
972
- strategy: "queue";
973
- } & WithMaxSize & WithOverflow<"replace-last"> & WithRetry<E> & WithConcurrency & WithTimeout<E>): Manager<I, E, A, RetryableQueueReplaceState<E, A>>;
974
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
975
- strategy: "queue";
976
- } & WithMaxSize & WithOverflow<"replace-last"> & WithConcurrency & WithTimeout<E>): Manager<I, E, A, QueueReplaceState<E, A>>;
977
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
978
- strategy: "queue";
979
- } & (WithMaxSize | WithDedupe<I>) & WithRetry<E> & WithConcurrency & WithTimeout<E>): Manager<I, E, A, RetryableQueueDropState<E, A>>;
980
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
981
- strategy: "queue";
982
- } & (WithMaxSize | WithDedupe<I>) & WithConcurrency & WithTimeout<E>): Manager<I, E, A, QueueDropState<E, A>>;
983
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
984
- strategy: "queue";
985
- } & WithRetry<E> & WithConcurrency & WithTimeout<E>): Manager<I, E, A, RetryableQueueState<E, A>>;
986
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
987
- strategy: "queue";
988
- } & WithConcurrency & WithTimeout<E>): Manager<I, E, A, QueueState<E, A>>;
989
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
990
- strategy: "buffered";
991
- } & WithSize & WithRetry<E> & WithTimeout<E>): Manager<I, E, A, RetryableBufferedState<E, A>>;
992
- function interpret<I, E, A>(op: Op<I, E, A>, options: {
993
- strategy: "buffered";
994
- } & WithSize & WithTimeout<E>): Manager<I, E, A, BufferedState<E, A>>;
1000
+ function interpret<I, E, A, O extends AllInterpretOptions<I, E>>(op: Op<I, E, A>, options: O): InterpretResult<I, E, A, O>;
995
1001
  }
996
1002
 
997
1003
  /**
@@ -1638,6 +1644,17 @@ declare namespace RemoteData {
1638
1644
  * ```
1639
1645
  */
1640
1646
  const toResult: <E>(onNotReady: () => E) => <A>(data: RemoteData<E, A>) => Result<E, A>;
1647
+ /**
1648
+ * Converts a Result to a RemoteData.
1649
+ * Ok becomes Success, Err becomes Failure.
1650
+ *
1651
+ * @example
1652
+ * ```ts
1653
+ * const result = await TaskResult.tryCatch(fetchUser, String)();
1654
+ * setState(RemoteData.fromResult(result)); // Success(user) or Failure(msg)
1655
+ * ```
1656
+ */
1657
+ const fromResult: <E, A>(data: Result<E, A>) => RemoteData<E, A>;
1641
1658
  }
1642
1659
 
1643
1660
  /**
@@ -1717,6 +1734,20 @@ declare namespace TaskResult {
1717
1734
  * Useful for logging or debugging.
1718
1735
  */
1719
1736
  const tap: <E, A>(f: (a: A) => void) => (data: TaskResult<E, A>) => TaskResult<E, A>;
1737
+ /**
1738
+ * Executes a side effect on the error value without changing the TaskResult.
1739
+ * Useful for logging or reporting async errors.
1740
+ *
1741
+ * @example
1742
+ * ```ts
1743
+ * pipe(
1744
+ * fetchUser(id),
1745
+ * TaskResult.tapError(e => console.error("fetch failed:", e)),
1746
+ * TaskResult.chain(saveToCache),
1747
+ * )
1748
+ * ```
1749
+ */
1750
+ const tapError: <E, A>(f: (e: E) => void) => (data: TaskResult<E, A>) => TaskResult<E, A>;
1720
1751
  }
1721
1752
 
1722
1753
  /**
package/dist/core.js CHANGED
@@ -126,6 +126,10 @@ var Result;
126
126
  if ((0, Result2.isOk)(data)) f(data.value);
127
127
  return data;
128
128
  };
129
+ Result2.tapError = (f) => (data) => {
130
+ if ((0, Result2.isErr)(data)) f(data.error);
131
+ return data;
132
+ };
129
133
  Result2.recover = (fallback) => (data) => (0, Result2.isOk)(data) ? data : fallback(data.error);
130
134
  Result2.recoverUnless = (blockedErr, fallback) => (data) => (0, Result2.isErr)(data) && data.error !== blockedErr ? fallback() : data;
131
135
  Result2.toMaybe = (data) => (0, Result2.isOk)(data) ? Maybe.some(data.value) : Maybe.none();
@@ -144,6 +148,7 @@ var Maybe;
144
148
  Maybe2.toNullable = (data) => (0, Maybe2.isSome)(data) ? data.value : null;
145
149
  Maybe2.toUndefined = (data) => (0, Maybe2.isSome)(data) ? data.value : void 0;
146
150
  Maybe2.fromUndefined = (value) => value === void 0 ? (0, Maybe2.none)() : (0, Maybe2.some)(value);
151
+ Maybe2.fromPredicate = (pred) => (a) => pred(a) ? (0, Maybe2.some)(a) : (0, Maybe2.none)();
147
152
  Maybe2.toResult = (onNone) => (data) => (0, Maybe2.isSome)(data) ? Result.ok(data.value) : Result.err(onNone());
148
153
  Maybe2.fromResult = (data) => Result.isOk(data) ? (0, Maybe2.some)(data.value) : (0, Maybe2.none)();
149
154
  Maybe2.map = (f) => (data) => (0, Maybe2.isSome)(data) ? (0, Maybe2.some)(f(data.value)) : data;
@@ -1198,6 +1203,7 @@ var RemoteData;
1198
1203
  RemoteData2.recover = (fallback) => (data) => (0, RemoteData2.isFailure)(data) ? fallback(data.error) : data;
1199
1204
  RemoteData2.toMaybe = (data) => (0, RemoteData2.isSuccess)(data) ? Maybe.some(data.value) : Maybe.none();
1200
1205
  RemoteData2.toResult = (onNotReady) => (data) => (0, RemoteData2.isSuccess)(data) ? Result.ok(data.value) : Result.err((0, RemoteData2.isFailure)(data) ? data.error : onNotReady());
1206
+ RemoteData2.fromResult = (data) => Result.isOk(data) ? (0, RemoteData2.success)(data.value) : (0, RemoteData2.failure)(data.error);
1201
1207
  })(RemoteData || (RemoteData = {}));
1202
1208
 
1203
1209
  // src/Core/Task.ts
@@ -1407,6 +1413,7 @@ var TaskResult;
1407
1413
  )(data);
1408
1414
  TaskResult2.getOrElse = (defaultValue) => (data) => Task.map(Result.getOrElse(defaultValue))(data);
1409
1415
  TaskResult2.tap = (f) => (data) => Task.map(Result.tap(f))(data);
1416
+ TaskResult2.tapError = (f) => (data) => Task.map(Result.tapError(f))(data);
1410
1417
  })(TaskResult || (TaskResult = {}));
1411
1418
 
1412
1419
  // src/Core/Validation.ts
package/dist/core.mjs CHANGED
@@ -15,13 +15,13 @@ import {
15
15
  These,
16
16
  Tuple,
17
17
  Validation
18
- } from "./chunk-UFQE2J63.mjs";
18
+ } from "./chunk-NTISCH7Z.mjs";
19
19
  import {
20
20
  Deferred,
21
21
  Maybe,
22
22
  Result,
23
23
  Task
24
- } from "./chunk-2DPG2RDB.mjs";
24
+ } from "./chunk-Z3DYYR43.mjs";
25
25
  export {
26
26
  Deferred,
27
27
  Lens,
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { and, compose, constFalse, constNull, constTrue, constUndefined, constVoid, constant, converge, curry, curry3, curry4, flip, flow, identity, juxt, memoize, memoizeWeak, not, on, once, or, pipe, tap, uncurry, uncurry3, uncurry4 } from './composition.mjs';
2
- export { D as Deferred, E as Err, M as Maybe, N as None, O as Ok, R as Result, S as Some, T as Task } from './Task-CT8iwwuB.mjs';
2
+ export { D as Deferred, E as Err, M as Maybe, N as None, O as Ok, R as Result, S as Some, T as Task } from './Task-BoqaFsUR.mjs';
3
3
  export { Failure, Invalid, Lens, Loading, Logged, NotAsked, Op, Optional, Predicate, Reader, Refinement, RemoteData, Resource, State, Success, TaskMaybe, TaskResult, TaskValidation, These, TheseBoth, TheseFirst, TheseSecond, Tuple, Valid, Validation } from './core.mjs';
4
4
  export { Brand } from './types.mjs';
5
5
  export { N as NonEmptyList, i as isNonEmptyList } from './NonEmptyList-BlGFjor5.mjs';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { and, compose, constFalse, constNull, constTrue, constUndefined, constVoid, constant, converge, curry, curry3, curry4, flip, flow, identity, juxt, memoize, memoizeWeak, not, on, once, or, pipe, tap, uncurry, uncurry3, uncurry4 } from './composition.js';
2
- export { D as Deferred, E as Err, M as Maybe, N as None, O as Ok, R as Result, S as Some, T as Task } from './Task-GSGtQO1m.js';
2
+ export { D as Deferred, E as Err, M as Maybe, N as None, O as Ok, R as Result, S as Some, T as Task } from './Task-7brqoQrb.js';
3
3
  export { Failure, Invalid, Lens, Loading, Logged, NotAsked, Op, Optional, Predicate, Reader, Refinement, RemoteData, Resource, State, Success, TaskMaybe, TaskResult, TaskValidation, These, TheseBoth, TheseFirst, TheseSecond, Tuple, Valid, Validation } from './core.js';
4
4
  export { Brand } from './types.js';
5
5
  export { N as NonEmptyList, i as isNonEmptyList } from './NonEmptyList-BlGFjor5.js';
package/dist/index.js CHANGED
@@ -371,6 +371,10 @@ var Result;
371
371
  if ((0, Result2.isOk)(data)) f(data.value);
372
372
  return data;
373
373
  };
374
+ Result2.tapError = (f) => (data) => {
375
+ if ((0, Result2.isErr)(data)) f(data.error);
376
+ return data;
377
+ };
374
378
  Result2.recover = (fallback) => (data) => (0, Result2.isOk)(data) ? data : fallback(data.error);
375
379
  Result2.recoverUnless = (blockedErr, fallback) => (data) => (0, Result2.isErr)(data) && data.error !== blockedErr ? fallback() : data;
376
380
  Result2.toMaybe = (data) => (0, Result2.isOk)(data) ? Maybe.some(data.value) : Maybe.none();
@@ -389,6 +393,7 @@ var Maybe;
389
393
  Maybe2.toNullable = (data) => (0, Maybe2.isSome)(data) ? data.value : null;
390
394
  Maybe2.toUndefined = (data) => (0, Maybe2.isSome)(data) ? data.value : void 0;
391
395
  Maybe2.fromUndefined = (value) => value === void 0 ? (0, Maybe2.none)() : (0, Maybe2.some)(value);
396
+ Maybe2.fromPredicate = (pred) => (a) => pred(a) ? (0, Maybe2.some)(a) : (0, Maybe2.none)();
392
397
  Maybe2.toResult = (onNone) => (data) => (0, Maybe2.isSome)(data) ? Result.ok(data.value) : Result.err(onNone());
393
398
  Maybe2.fromResult = (data) => Result.isOk(data) ? (0, Maybe2.some)(data.value) : (0, Maybe2.none)();
394
399
  Maybe2.map = (f) => (data) => (0, Maybe2.isSome)(data) ? (0, Maybe2.some)(f(data.value)) : data;
@@ -1443,6 +1448,7 @@ var RemoteData;
1443
1448
  RemoteData2.recover = (fallback) => (data) => (0, RemoteData2.isFailure)(data) ? fallback(data.error) : data;
1444
1449
  RemoteData2.toMaybe = (data) => (0, RemoteData2.isSuccess)(data) ? Maybe.some(data.value) : Maybe.none();
1445
1450
  RemoteData2.toResult = (onNotReady) => (data) => (0, RemoteData2.isSuccess)(data) ? Result.ok(data.value) : Result.err((0, RemoteData2.isFailure)(data) ? data.error : onNotReady());
1451
+ RemoteData2.fromResult = (data) => Result.isOk(data) ? (0, RemoteData2.success)(data.value) : (0, RemoteData2.failure)(data.error);
1446
1452
  })(RemoteData || (RemoteData = {}));
1447
1453
 
1448
1454
  // src/Core/Task.ts
@@ -1652,6 +1658,7 @@ var TaskResult;
1652
1658
  )(data);
1653
1659
  TaskResult2.getOrElse = (defaultValue) => (data) => Task.map(Result.getOrElse(defaultValue))(data);
1654
1660
  TaskResult2.tap = (f) => (data) => Task.map(Result.tap(f))(data);
1661
+ TaskResult2.tapError = (f) => (data) => Task.map(Result.tapError(f))(data);
1655
1662
  })(TaskResult || (TaskResult = {}));
1656
1663
 
1657
1664
  // src/Core/Validation.ts
@@ -1870,6 +1877,14 @@ var Arr;
1870
1877
  }
1871
1878
  return result;
1872
1879
  };
1880
+ Arr2.filterMap = (f) => (data) => {
1881
+ const result = [];
1882
+ for (let i = 0; i < data.length; i++) {
1883
+ const mapped = f(data[i]);
1884
+ if (mapped.kind === "Some") result.push(mapped.value);
1885
+ }
1886
+ return result;
1887
+ };
1873
1888
  Arr2.partition = (predicate) => (data) => {
1874
1889
  const pass = [];
1875
1890
  const fail = [];
@@ -2298,6 +2313,8 @@ var Str;
2298
2313
  Str2.split = (separator) => (s) => s.split(separator);
2299
2314
  Str2.trim = (s) => s.trim();
2300
2315
  Str2.includes = (substring) => (s) => s.includes(substring);
2316
+ Str2.replace = (pattern, replacement) => (s) => s.replace(pattern, replacement);
2317
+ Str2.replaceAll = (pattern, replacement) => (s) => s.replaceAll(pattern, replacement);
2301
2318
  Str2.startsWith = (prefix) => (s) => s.startsWith(prefix);
2302
2319
  Str2.endsWith = (suffix) => (s) => s.endsWith(suffix);
2303
2320
  Str2.toUpperCase = (s) => s.toUpperCase();
package/dist/index.mjs CHANGED
@@ -44,7 +44,7 @@ import {
44
44
  These,
45
45
  Tuple,
46
46
  Validation
47
- } from "./chunk-UFQE2J63.mjs";
47
+ } from "./chunk-NTISCH7Z.mjs";
48
48
  import {
49
49
  Arr,
50
50
  Dict,
@@ -52,13 +52,13 @@ import {
52
52
  Rec,
53
53
  Str,
54
54
  Uniq
55
- } from "./chunk-C3Z56PCR.mjs";
55
+ } from "./chunk-6H373E63.mjs";
56
56
  import {
57
57
  Deferred,
58
58
  Maybe,
59
59
  Result,
60
60
  Task
61
- } from "./chunk-2DPG2RDB.mjs";
61
+ } from "./chunk-Z3DYYR43.mjs";
62
62
  import {
63
63
  Brand
64
64
  } from "./chunk-BYWKZLHM.mjs";
package/dist/utils.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { M as Maybe, R as Result, T as Task } from './Task-CT8iwwuB.mjs';
1
+ import { M as Maybe, R as Result, T as Task } from './Task-BoqaFsUR.mjs';
2
2
  import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.mjs';
3
3
 
4
4
  /**
@@ -102,6 +102,21 @@ declare namespace Arr {
102
102
  * ```
103
103
  */
104
104
  const filter: <A>(predicate: (a: A) => boolean) => (data: readonly A[]) => readonly A[];
105
+ /**
106
+ * Maps each element to a Maybe and collects only the Some values.
107
+ * Combines map and filter in a single pass.
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * const parseNum = (s: string): Maybe<number> => {
112
+ * const n = Number(s);
113
+ * return isNaN(n) ? Maybe.none() : Maybe.some(n);
114
+ * };
115
+ *
116
+ * pipe(["1", "abc", "3"], Arr.filterMap(parseNum)); // [1, 3]
117
+ * ```
118
+ */
119
+ const filterMap: <A, B>(f: (a: A) => Maybe<B>) => (data: readonly A[]) => readonly B[];
105
120
  /**
106
121
  * Splits an array into two groups based on a predicate.
107
122
  * First group contains elements that satisfy the predicate,
@@ -1041,6 +1056,26 @@ declare namespace Str {
1041
1056
  * ```
1042
1057
  */
1043
1058
  const includes: (substring: string) => (s: string) => boolean;
1059
+ /**
1060
+ * Replaces the first occurrence of a pattern in a string. Data-last: use in `pipe`.
1061
+ *
1062
+ * @example
1063
+ * ```ts
1064
+ * pipe("foo foo foo", Str.replace("foo", "bar")); // "bar foo foo"
1065
+ * pipe("Hello World", Str.replace(/world/i, "Earth")); // "Hello Earth"
1066
+ * ```
1067
+ */
1068
+ const replace: (pattern: string | RegExp, replacement: string) => (s: string) => string;
1069
+ /**
1070
+ * Replaces all occurrences of a pattern in a string. Data-last: use in `pipe`.
1071
+ *
1072
+ * @example
1073
+ * ```ts
1074
+ * pipe("foo foo foo", Str.replaceAll("foo", "bar")); // "bar bar bar"
1075
+ * pipe("aAbBaA", Str.replaceAll(/a/gi, "x")); // "xxBBxx"
1076
+ * ```
1077
+ */
1078
+ const replaceAll: (pattern: string | RegExp, replacement: string) => (s: string) => string;
1044
1079
  /**
1045
1080
  * Returns `true` when the string starts with the given prefix.
1046
1081
  *
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { M as Maybe, R as Result, T as Task } from './Task-GSGtQO1m.js';
1
+ import { M as Maybe, R as Result, T as Task } from './Task-7brqoQrb.js';
2
2
  import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.js';
3
3
 
4
4
  /**
@@ -102,6 +102,21 @@ declare namespace Arr {
102
102
  * ```
103
103
  */
104
104
  const filter: <A>(predicate: (a: A) => boolean) => (data: readonly A[]) => readonly A[];
105
+ /**
106
+ * Maps each element to a Maybe and collects only the Some values.
107
+ * Combines map and filter in a single pass.
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * const parseNum = (s: string): Maybe<number> => {
112
+ * const n = Number(s);
113
+ * return isNaN(n) ? Maybe.none() : Maybe.some(n);
114
+ * };
115
+ *
116
+ * pipe(["1", "abc", "3"], Arr.filterMap(parseNum)); // [1, 3]
117
+ * ```
118
+ */
119
+ const filterMap: <A, B>(f: (a: A) => Maybe<B>) => (data: readonly A[]) => readonly B[];
105
120
  /**
106
121
  * Splits an array into two groups based on a predicate.
107
122
  * First group contains elements that satisfy the predicate,
@@ -1041,6 +1056,26 @@ declare namespace Str {
1041
1056
  * ```
1042
1057
  */
1043
1058
  const includes: (substring: string) => (s: string) => boolean;
1059
+ /**
1060
+ * Replaces the first occurrence of a pattern in a string. Data-last: use in `pipe`.
1061
+ *
1062
+ * @example
1063
+ * ```ts
1064
+ * pipe("foo foo foo", Str.replace("foo", "bar")); // "bar foo foo"
1065
+ * pipe("Hello World", Str.replace(/world/i, "Earth")); // "Hello Earth"
1066
+ * ```
1067
+ */
1068
+ const replace: (pattern: string | RegExp, replacement: string) => (s: string) => string;
1069
+ /**
1070
+ * Replaces all occurrences of a pattern in a string. Data-last: use in `pipe`.
1071
+ *
1072
+ * @example
1073
+ * ```ts
1074
+ * pipe("foo foo foo", Str.replaceAll("foo", "bar")); // "bar bar bar"
1075
+ * pipe("aAbBaA", Str.replaceAll(/a/gi, "x")); // "xxBBxx"
1076
+ * ```
1077
+ */
1078
+ const replaceAll: (pattern: string | RegExp, replacement: string) => (s: string) => string;
1044
1079
  /**
1045
1080
  * Returns `true` when the string starts with the given prefix.
1046
1081
  *
package/dist/utils.js CHANGED
@@ -63,6 +63,10 @@ var Result;
63
63
  if ((0, Result2.isOk)(data)) f(data.value);
64
64
  return data;
65
65
  };
66
+ Result2.tapError = (f) => (data) => {
67
+ if ((0, Result2.isErr)(data)) f(data.error);
68
+ return data;
69
+ };
66
70
  Result2.recover = (fallback) => (data) => (0, Result2.isOk)(data) ? data : fallback(data.error);
67
71
  Result2.recoverUnless = (blockedErr, fallback) => (data) => (0, Result2.isErr)(data) && data.error !== blockedErr ? fallback() : data;
68
72
  Result2.toMaybe = (data) => (0, Result2.isOk)(data) ? Maybe.some(data.value) : Maybe.none();
@@ -81,6 +85,7 @@ var Maybe;
81
85
  Maybe2.toNullable = (data) => (0, Maybe2.isSome)(data) ? data.value : null;
82
86
  Maybe2.toUndefined = (data) => (0, Maybe2.isSome)(data) ? data.value : void 0;
83
87
  Maybe2.fromUndefined = (value) => value === void 0 ? (0, Maybe2.none)() : (0, Maybe2.some)(value);
88
+ Maybe2.fromPredicate = (pred) => (a) => pred(a) ? (0, Maybe2.some)(a) : (0, Maybe2.none)();
84
89
  Maybe2.toResult = (onNone) => (data) => (0, Maybe2.isSome)(data) ? Result.ok(data.value) : Result.err(onNone());
85
90
  Maybe2.fromResult = (data) => Result.isOk(data) ? (0, Maybe2.some)(data.value) : (0, Maybe2.none)();
86
91
  Maybe2.map = (f) => (data) => (0, Maybe2.isSome)(data) ? (0, Maybe2.some)(f(data.value)) : data;
@@ -231,6 +236,14 @@ var Arr;
231
236
  }
232
237
  return result;
233
238
  };
239
+ Arr2.filterMap = (f) => (data) => {
240
+ const result = [];
241
+ for (let i = 0; i < data.length; i++) {
242
+ const mapped = f(data[i]);
243
+ if (mapped.kind === "Some") result.push(mapped.value);
244
+ }
245
+ return result;
246
+ };
234
247
  Arr2.partition = (predicate) => (data) => {
235
248
  const pass = [];
236
249
  const fail = [];
@@ -659,6 +672,8 @@ var Str;
659
672
  Str2.split = (separator) => (s) => s.split(separator);
660
673
  Str2.trim = (s) => s.trim();
661
674
  Str2.includes = (substring) => (s) => s.includes(substring);
675
+ Str2.replace = (pattern, replacement) => (s) => s.replace(pattern, replacement);
676
+ Str2.replaceAll = (pattern, replacement) => (s) => s.replaceAll(pattern, replacement);
662
677
  Str2.startsWith = (prefix) => (s) => s.startsWith(prefix);
663
678
  Str2.endsWith = (suffix) => (s) => s.endsWith(suffix);
664
679
  Str2.toUpperCase = (s) => s.toUpperCase();
package/dist/utils.mjs CHANGED
@@ -5,8 +5,8 @@ import {
5
5
  Rec,
6
6
  Str,
7
7
  Uniq
8
- } from "./chunk-C3Z56PCR.mjs";
9
- import "./chunk-2DPG2RDB.mjs";
8
+ } from "./chunk-6H373E63.mjs";
9
+ import "./chunk-Z3DYYR43.mjs";
10
10
  import "./chunk-DBIC62UV.mjs";
11
11
  export {
12
12
  Arr,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nlozgachev/pipelined",
3
- "version": "0.24.0",
3
+ "version": "0.26.0",
4
4
  "description": "Opinionated functional abstractions for TypeScript",
5
5
  "license": "BSD-3-Clause",
6
6
  "homepage": "https://pipelined.lozgachev.dev",