@nlozgachev/pipelined 0.32.0 → 0.34.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.
@@ -1,4 +1,4 @@
1
- import { N as NonEmptyList } from './NonEmptyList-BlGFjor5.mjs';
1
+ import { NonEmptyList, Duration } from './types.js';
2
2
 
3
3
  type WithKind<K extends string> = {
4
4
  readonly kind: K;
@@ -24,19 +24,19 @@ type WithLog<T> = {
24
24
  /** Retry policy for `Op.interpret`. */
25
25
  type RetryOptions<E> = {
26
26
  readonly attempts: number;
27
- readonly backoff?: number | ((attempt: number) => number);
27
+ readonly backoff?: Duration | ((attempt: number) => Duration);
28
28
  readonly when?: (error: E) => boolean;
29
29
  };
30
30
  /** Timeout policy for `Op.interpret`. Wraps the entire retry sequence. */
31
31
  type TimeoutOptions<E> = {
32
- readonly ms: number;
32
+ readonly duration: Duration;
33
33
  readonly onTimeout: () => E;
34
34
  };
35
35
  type WithTimeout<E> = {
36
36
  readonly timeout?: TimeoutOptions<E>;
37
37
  };
38
- type WithMs = {
39
- readonly ms: number;
38
+ type WithDuration = {
39
+ readonly duration: Duration;
40
40
  };
41
41
  type WithN = {
42
42
  readonly n: number;
@@ -48,22 +48,22 @@ type WithSize = {
48
48
  readonly size?: number;
49
49
  };
50
50
  type WithCooldown = {
51
- readonly cooldown?: number;
51
+ readonly cooldown?: Duration;
52
52
  };
53
53
  type WithMinInterval = {
54
- readonly minInterval?: number;
54
+ readonly minInterval?: Duration;
55
55
  };
56
56
 
57
57
  type Ok<A> = WithKind<"Ok"> & WithValue<A>;
58
- type Error<E> = WithKind<"Error"> & WithError<E>;
58
+ type Err<E> = WithKind<"Err"> & WithError<E>;
59
59
  /**
60
- * Result represents a value that can be one of two types: a success (Ok) or a failure (Error).
60
+ * Result represents a value that can be one of two types: a success (Ok) or a failure (Err).
61
61
  * Use Result when an operation can fail with a meaningful error value.
62
62
  *
63
63
  * @example
64
64
  * ```ts
65
65
  * const divide = (a: number, b: number): Result<string, number> =>
66
- * b === 0 ? Result.error("Division by zero") : Result.ok(a / b);
66
+ * b === 0 ? Result.err("Division by zero") : Result.ok(a / b);
67
67
  *
68
68
  * pipe(
69
69
  * divide(10, 2),
@@ -72,7 +72,7 @@ type Error<E> = WithKind<"Error"> & WithError<E>;
72
72
  * ); // 10
73
73
  * ```
74
74
  */
75
- type Result<E, A> = Ok<A> | Error<E>;
75
+ type Result<E, A> = Ok<A> | Err<E>;
76
76
  declare namespace Result {
77
77
  /**
78
78
  * Creates a successful Result with the given value.
@@ -81,17 +81,17 @@ declare namespace Result {
81
81
  /**
82
82
  * Creates a failed Result with the given error.
83
83
  */
84
- const error: <E>(e: E) => Error<E>;
84
+ const err: <E>(e: E) => Err<E>;
85
85
  /**
86
- * Type guard that checks if an Result is Ok.
86
+ * Type guard that checks if a Result is Ok.
87
87
  */
88
88
  const isOk: <E, A>(data: Result<E, A>) => data is Ok<A>;
89
89
  /**
90
- * Type guard that checks if an Result is Error.
90
+ * Type guard that checks if a Result is Err.
91
91
  */
92
- const isError: <E, A>(data: Result<E, A>) => data is Error<E>;
92
+ const isErr: <E, A>(data: Result<E, A>) => data is Err<E>;
93
93
  /**
94
- * Creates an Result from a function that may throw.
94
+ * Creates a Result from a function that may throw.
95
95
  * Catches any errors and transforms them using the onError function.
96
96
  *
97
97
  * @example
@@ -105,21 +105,21 @@ declare namespace Result {
105
105
  */
106
106
  const tryCatch: <E, A>(f: () => A, onError: (e: unknown) => E) => Result<E, A>;
107
107
  /**
108
- * Transforms the success value inside an Result.
108
+ * Transforms the success value inside a Result.
109
109
  *
110
110
  * @example
111
111
  * ```ts
112
112
  * pipe(Result.ok(5), Result.map(n => n * 2)); // Ok(10)
113
- * pipe(Result.error("error"), Result.map(n => n * 2)); // Error("error")
113
+ * pipe(Result.err("error"), Result.map(n => n * 2)); // Err("error")
114
114
  * ```
115
115
  */
116
116
  const map: <E, A, B>(f: (a: A) => B) => (data: Result<E, A>) => Result<E, B>;
117
117
  /**
118
- * Transforms the error value inside an Result.
118
+ * Transforms the error value inside a Result.
119
119
  *
120
120
  * @example
121
121
  * ```ts
122
- * pipe(Result.error("oops"), Result.mapError(e => e.toUpperCase())); // Error("OOPS")
122
+ * pipe(Result.err("oops"), Result.mapError(e => e.toUpperCase())); // Err("OOPS")
123
123
  * ```
124
124
  */
125
125
  const mapError: <E, F, A>(f: (e: E) => F) => (data: Result<E, A>) => Result<F, A>;
@@ -130,15 +130,15 @@ declare namespace Result {
130
130
  * @example
131
131
  * ```ts
132
132
  * const validatePositive = (n: number): Result<string, number> =>
133
- * n > 0 ? Result.ok(n) : Result.error("Must be positive");
133
+ * n > 0 ? Result.ok(n) : Result.err("Must be positive");
134
134
  *
135
135
  * pipe(Result.ok(5), Result.chain(validatePositive)); // Ok(5)
136
- * pipe(Result.ok(-1), Result.chain(validatePositive)); // Error("Must be positive")
136
+ * pipe(Result.ok(-1), Result.chain(validatePositive)); // Err("Must be positive")
137
137
  * ```
138
138
  */
139
139
  const chain: <E, A, B>(f: (a: A) => Result<E, B>) => (data: Result<E, A>) => Result<E, B>;
140
140
  /**
141
- * Extracts the value from an Result by providing handlers for both cases.
141
+ * Extracts the value from a Result by providing handlers for both cases.
142
142
  *
143
143
  * @example
144
144
  * ```ts
@@ -178,8 +178,8 @@ declare namespace Result {
178
178
  * @example
179
179
  * ```ts
180
180
  * pipe(Result.ok(5), Result.getOrElse(() => 0)); // 5
181
- * pipe(Result.error("error"), Result.getOrElse(() => 0)); // 0
182
- * pipe(Result.error("error"), Result.getOrElse(() => null)); // null — typed as number | null
181
+ * pipe(Result.err("error"), Result.getOrElse(() => 0)); // 0
182
+ * pipe(Result.err("error"), Result.getOrElse(() => null)); // null — typed as number | null
183
183
  * ```
184
184
  */
185
185
  const getOrElse: <E, A, B>(defaultValue: () => B) => (data: Result<E, A>) => A | B;
@@ -204,7 +204,7 @@ declare namespace Result {
204
204
  * @example
205
205
  * ```ts
206
206
  * pipe(
207
- * Result.error("not found"),
207
+ * Result.err("not found"),
208
208
  * Result.tapError(e => console.error("validation failed:", e)),
209
209
  * Result.chain(save),
210
210
  * )
@@ -218,11 +218,49 @@ declare namespace Result {
218
218
  * @example
219
219
  * ```ts
220
220
  * pipe(5, Result.fromPredicate(n => n > 0, n => `${n} is not positive`)); // Ok(5)
221
- * pipe(-1, Result.fromPredicate(n => n > 0, n => `${n} is not positive`)); // Error("-1 is not positive")
222
- * pipe("", Result.fromPredicate(s => s.length > 0, () => "empty string")); // Error("empty string")
221
+ * pipe(-1, Result.fromPredicate(n => n > 0, n => `${n} is not positive`)); // Err("-1 is not positive")
222
+ * pipe("", Result.fromPredicate(s => s.length > 0, () => "empty string")); // Err("empty string")
223
223
  * ```
224
224
  */
225
225
  const fromPredicate: <E, A>(pred: (a: A) => boolean, onFalse: (a: A) => E) => (a: A) => Result<E, A>;
226
+ /**
227
+ * Creates a Result from a nullable value.
228
+ * Returns Ok if the value is not null or undefined, error from onNull otherwise.
229
+ *
230
+ * @example
231
+ * ```ts
232
+ * pipe(null, Result.fromNullable(() => "is null")); // Err("is null")
233
+ * pipe(42, Result.fromNullable(() => "is null")); // Ok(42)
234
+ * ```
235
+ */
236
+ const fromNullable: <E>(onNull: () => E) => <A>(value: A | null | undefined) => Result<E, A>;
237
+ /**
238
+ * Creates a Result from a Maybe.
239
+ * Some becomes Ok, None becomes error from onNone.
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * pipe(Maybe.none(), Result.fromMaybe(() => "is none")); // Err("is none")
244
+ * pipe(Maybe.some(42), Result.fromMaybe(() => "is none")); // Ok(42)
245
+ * ```
246
+ */
247
+ const fromMaybe: <E>(onNone: () => E) => <A>(maybe: Maybe<A>) => Result<E, A>;
248
+ /**
249
+ * Wraps a throwing function of any arguments, returning a new function
250
+ * that catches errors and returns a Result.
251
+ *
252
+ * @example
253
+ * ```ts
254
+ * const safeParse = Result.fromThrowable(
255
+ * (s: string) => JSON.parse(s),
256
+ * (e) => new Error(`Parse error: ${e}`)
257
+ * );
258
+ *
259
+ * safeParse('{"a":1}'); // Ok({ a: 1 })
260
+ * safeParse('invalid'); // Err(Error)
261
+ * ```
262
+ */
263
+ const fromThrowable: <Args extends readonly unknown[], A, E>(f: (...args: Args) => A, onError: (e: unknown) => E) => (...args: Args) => Result<E, A>;
226
264
  /**
227
265
  * Recovers from an error by providing a fallback Result.
228
266
  * The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
@@ -235,25 +273,25 @@ declare namespace Result {
235
273
  * @example
236
274
  * ```ts
237
275
  * pipe(
238
- * Result.error(new Error("not found")),
276
+ * Result.err(new Error("not found")),
239
277
  * Result.recoverUnless(e => e.message === "fatal", () => Result.ok(0))
240
278
  * ); // Ok(0)
241
279
  * ```
242
280
  */
243
281
  const recoverUnless: <E, A, B>(isBlocked: (e: E) => boolean, fallback: () => Result<E, B>) => (data: Result<E, A>) => Result<E, A | B>;
244
282
  /**
245
- * Converts a Result to an Maybe.
283
+ * Converts a Result to a Maybe.
246
284
  * Ok becomes Some, Err becomes None (the error is discarded).
247
285
  *
248
286
  * @example
249
287
  * ```ts
250
288
  * Result.toMaybe(Result.ok(42)); // Some(42)
251
- * Result.toMaybe(Result.error("oops")); // None
289
+ * Result.toMaybe(Result.err("oops")); // None
252
290
  * ```
253
291
  */
254
292
  const toMaybe: <E, A>(data: Result<E, A>) => Maybe<A>;
255
293
  /**
256
- * Applies a function wrapped in an Result to a value wrapped in an Result.
294
+ * Applies a function wrapped in a Result to a value wrapped in a Result.
257
295
  *
258
296
  * @example
259
297
  * ```ts
@@ -276,14 +314,13 @@ type None = WithKind<"None">;
276
314
  *
277
315
  * @example
278
316
  * ```ts
279
- * const findUser = (id: string): Maybe<User> =>
280
- * users.has(id) ? Maybe.some(users.get(id)!) : Maybe.none();
317
+ * const user = { name: "Alice", email: Maybe.some("alice@example.com") };
281
318
  *
282
319
  * pipe(
283
- * findUser("123"),
284
- * Maybe.map(user => user.name),
285
- * Maybe.getOrElse(() => "Unknown")
286
- * );
320
+ * user.email,
321
+ * Maybe.map(email => email.toUpperCase()),
322
+ * Maybe.getOrElse(() => "NO EMAIL")
323
+ * ); // "ALICE@EXAMPLE.COM"
287
324
  * ```
288
325
  */
289
326
  type Maybe<T> = Some<T> | None;
@@ -338,7 +375,7 @@ declare namespace Maybe {
338
375
  */
339
376
  const fromPredicate: <A>(pred: (a: A) => boolean) => (a: A) => Maybe<A>;
340
377
  /**
341
- * Converts an Maybe to a Result.
378
+ * Converts a Maybe to a Result.
342
379
  * Some becomes Ok, None becomes Err with the provided error.
343
380
  *
344
381
  * @example
@@ -356,13 +393,13 @@ declare namespace Maybe {
356
393
  */
357
394
  const toResult: <E>(onNone: () => E) => <A>(data: Maybe<A>) => Result<E, A>;
358
395
  /**
359
- * Creates an Maybe from a Result.
396
+ * Creates a Maybe from a Result.
360
397
  * Ok becomes Some, Err becomes None (the error is discarded).
361
398
  *
362
399
  * @example
363
400
  * ```ts
364
401
  * Maybe.fromResult(Result.ok(42)); // Some(42)
365
- * Maybe.fromResult(Result.error("oops")); // None
402
+ * Maybe.fromResult(Result.err("oops")); // None
366
403
  * ```
367
404
  */
368
405
  const fromResult: <E, A>(data: Result<E, A>) => Maybe<A>;
@@ -426,7 +463,7 @@ declare namespace Maybe {
426
463
  some: (a: A) => B;
427
464
  }) => (data: Maybe<A>) => B;
428
465
  /**
429
- * Returns the value inside an Maybe, or a default value if None.
466
+ * Returns the value inside a Maybe, or a default value if None.
430
467
  * The default is a thunk `() => B` — evaluated only when the Maybe is None.
431
468
  * The default can be a different type, widening the result to `A | B`.
432
469
  *
@@ -844,37 +881,37 @@ declare namespace Task {
844
881
  */
845
882
  const all: <T extends readonly Task<unknown>[]>(tasks: T) => Task<{ [K in keyof T]: T[K] extends Task<infer A> ? A : never; }>;
846
883
  /**
847
- * Delays the execution of a Task by the specified milliseconds.
884
+ * Delays the execution of a Task by the specified duration.
848
885
  * Useful for debouncing or rate limiting.
849
886
  *
850
887
  * @example
851
888
  * ```ts
852
889
  * pipe(
853
890
  * Task.resolve(42),
854
- * Task.delay(1000)
891
+ * Task.delay(Duration.seconds(1))
855
892
  * )(); // Resolves after 1 second
856
893
  * ```
857
894
  */
858
- const delay: (ms: number) => <A>(data: Task<A>) => Task<A>;
895
+ const delay: (duration: Duration) => <A>(data: Task<A>) => Task<A>;
859
896
  /**
860
897
  * Runs a Task a fixed number of times sequentially, collecting all results into an array.
861
- * An optional delay (ms) can be inserted between runs.
898
+ * An optional delay duration can be inserted between runs.
862
899
  *
863
900
  * @example
864
901
  * ```ts
865
902
  * pipe(
866
903
  * pollSensor,
867
- * Task.repeat({ times: 5, delay: 1000 })
904
+ * Task.repeat({ times: 5, delay: Duration.seconds(1) })
868
905
  * )(); // Task<Reading[]> — 5 readings, one per second
869
906
  * ```
870
907
  */
871
908
  const repeat: (options: {
872
909
  times: number;
873
- delay?: number;
910
+ delay?: Duration;
874
911
  }) => <A>(task: Task<A>) => Task<readonly A[]>;
875
912
  /**
876
913
  * Runs a Task repeatedly until the result satisfies a predicate, returning that result.
877
- * An optional delay (ms) can be inserted between runs.
914
+ * An optional delay duration can be inserted between runs.
878
915
  * An optional `maxAttempts` cap stops the loop after N calls — the last value is returned
879
916
  * regardless of whether the predicate was satisfied.
880
917
  *
@@ -882,18 +919,19 @@ declare namespace Task {
882
919
  * ```ts
883
920
  * pipe(
884
921
  * checkStatus,
885
- * Task.repeatUntil({ when: (s) => s === "ready", delay: 500 })
922
+ * Task.repeatUntil({ when: (s) => s === "ready", delay: Duration.milliseconds(500) })
886
923
  * )(); // polls every 500ms until status is "ready"
887
924
  * ```
888
925
  */
889
926
  const repeatUntil: <A>(options: {
890
927
  when: (a: A) => boolean;
891
- delay?: number;
928
+ delay?: Duration;
892
929
  maxAttempts?: number;
893
930
  }) => (task: Task<A>) => Task<A>;
894
931
  /**
895
932
  * Resolves with the value of the first Task to complete. All Tasks start
896
- * immediately; the rest are abandoned once one resolves.
933
+ * immediately. When one resolves, the other tasks are cancelled (aborted)
934
+ * downstream.
897
935
  *
898
936
  * @example
899
937
  * ```ts
@@ -904,6 +942,17 @@ declare namespace Task {
904
942
  * ```
905
943
  */
906
944
  const race: <A>(tasks: ReadonlyArray<Task<A>>) => Task<A>;
945
+ /**
946
+ * Runs an array of Tasks concurrently and collects their results in an array.
947
+ * Forward-propagates the call site's AbortSignal to all subtasks concurrently.
948
+ *
949
+ * @example
950
+ * ```ts
951
+ * Task.sequence([loadConfig, detectLocale, loadTheme])();
952
+ * // Deferred<[Config, string, Theme]>
953
+ * ```
954
+ */
955
+ const sequence: <A>(tasks: ReadonlyArray<Task<A>>) => Task<ReadonlyArray<A>>;
907
956
  /**
908
957
  * Runs an array of Tasks one at a time in order, collecting all results.
909
958
  * Each Task starts only after the previous one resolves.
@@ -923,20 +972,20 @@ declare namespace Task {
923
972
  const sequential: <A>(tasks: ReadonlyArray<Task<A>>) => Task<ReadonlyArray<A>>;
924
973
  /**
925
974
  * Converts a `Task<A>` into a `Task<Result<E, A>>`, resolving to `Err` if the
926
- * Task does not complete within the given time. The inner Task receives an
927
- * `AbortSignal` that fires when the deadline passes, so operations like `fetch`
975
+ * Task does not complete within the given duration. The inner Task receives an
976
+ * `AbortSignal` that fires when the deadline passes, so asynchronous operations
928
977
  * that accept a signal are cancelled rather than left dangling.
929
978
  *
930
979
  * @example
931
980
  * ```ts
932
981
  * pipe(
933
982
  * heavyComputation,
934
- * Task.timeout(5000, () => "timed out"),
983
+ * Task.timeout(Duration.seconds(5), () => "timed out"),
935
984
  * TaskResult.chain(processResult)
936
985
  * );
937
986
  * ```
938
987
  */
939
- const timeout: <E>(ms: number, onTimeout: () => E) => <A>(task: Task<A>) => Task<Result<E, A>>;
988
+ const timeout: <E>(duration: Duration, onTimeout: () => E) => <A>(task: Task<A>) => Task<Result<E, A>>;
940
989
  /**
941
990
  * Creates a Task paired with an `abort` handle. Calling `abort()` cancels the
942
991
  * current in-flight call immediately. Unlike a one-shot abort, calling `task()`
@@ -968,7 +1017,7 @@ declare namespace Task {
968
1017
  * @example
969
1018
  * ```ts
970
1019
  * const name = await pipe(
971
- * fetchConfig,
1020
+ * loadConfig,
972
1021
  * Task.map(config => config.name),
973
1022
  * Task.run(),
974
1023
  * );
@@ -977,4 +1026,4 @@ declare namespace Task {
977
1026
  const run: (signal?: AbortSignal) => <A>(task: Task<A>) => Promise<A>;
978
1027
  }
979
1028
 
980
- export { Deferred as D, Equality 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 Error as a, Ordering as b, type WithLog as c, type WithKind as d, type WithError as e, type RetryOptions as f, type TimeoutOptions as g, type WithTimeout as h, type WithMinInterval as i, type WithCooldown as j, type WithConcurrency as k, type WithSize as l, type WithMs as m, type WithN as n, type WithErrors as o, type WithFirst as p, type WithSecond as q };
1029
+ export { Deferred as D, Equality 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 Err as a, Ordering as b, type WithLog as c, type WithKind as d, type WithError as e, type RetryOptions as f, type TimeoutOptions as g, type WithTimeout as h, type WithMinInterval as i, type WithCooldown as j, type WithConcurrency as k, type WithSize as l, type WithDuration as m, type WithN as n, type WithErrors as o, type WithFirst as p, type WithSecond as q };