@nlozgachev/pipelined 0.36.0 → 0.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -7
- package/dist/{Task-DXsuurnc.d.mts → Task-DcXhCZYg.d.mts} +472 -380
- package/dist/{Task-zAY4kSVB.d.ts → Task-uupX7xd9.d.ts} +472 -380
- package/dist/{chunk-VWVPHDZO.mjs → chunk-5AFEEFE4.mjs} +5 -1
- package/dist/{chunk-IJFFWBKW.mjs → chunk-E7YI5PVW.mjs} +2 -2
- package/dist/{chunk-4QMYKCWE.mjs → chunk-M2X7TFKN.mjs} +500 -100
- package/dist/core.d.mts +743 -605
- package/dist/core.d.ts +743 -605
- package/dist/core.js +336 -246
- package/dist/core.mjs +6 -8
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +353 -263
- package/dist/index.mjs +16 -21
- package/dist/types.d.mts +29 -29
- package/dist/types.d.ts +29 -29
- package/dist/types.mjs +3 -6
- package/dist/utils.d.mts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +89 -51
- package/dist/utils.mjs +3 -4
- package/package.json +17 -5
- package/dist/chunk-DBIC62UV.mjs +0 -6
- package/dist/chunk-DLBHVYII.mjs +0 -322
- package/dist/chunk-IPP4XFYH.mjs +0 -0
|
@@ -1,311 +1,198 @@
|
|
|
1
1
|
import { NonEmptyList, Duration } from './types.mjs';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
readonly kind: K;
|
|
5
|
-
};
|
|
6
|
-
type WithValue<T> = {
|
|
7
|
-
readonly value: T;
|
|
8
|
-
};
|
|
9
|
-
type WithError<T> = {
|
|
10
|
-
readonly error: T;
|
|
11
|
-
};
|
|
12
|
-
type WithErrors<T> = {
|
|
13
|
-
readonly errors: NonEmptyList<T>;
|
|
14
|
-
};
|
|
15
|
-
type WithFirst<T> = {
|
|
16
|
-
readonly first: T;
|
|
17
|
-
};
|
|
18
|
-
type WithSecond<T> = {
|
|
19
|
-
readonly second: T;
|
|
20
|
-
};
|
|
21
|
-
type WithLog<T> = {
|
|
22
|
-
readonly log: ReadonlyArray<T>;
|
|
23
|
-
};
|
|
24
|
-
/** Retry policy for `Op.interpret`. */
|
|
25
|
-
type RetryOptions<E> = {
|
|
26
|
-
readonly attempts: number;
|
|
27
|
-
readonly backoff?: Duration | ((attempt: number) => Duration);
|
|
28
|
-
readonly when?: (error: E) => boolean;
|
|
29
|
-
};
|
|
30
|
-
/** Timeout policy for `Op.interpret`. Wraps the entire retry sequence. */
|
|
31
|
-
type TimeoutOptions<E> = {
|
|
32
|
-
readonly duration: Duration;
|
|
33
|
-
readonly onTimeout: () => E;
|
|
34
|
-
};
|
|
35
|
-
type WithTimeout<E> = {
|
|
36
|
-
readonly timeout?: TimeoutOptions<E>;
|
|
37
|
-
};
|
|
38
|
-
type WithDuration = {
|
|
39
|
-
readonly duration: Duration;
|
|
40
|
-
};
|
|
41
|
-
type WithN = {
|
|
42
|
-
readonly n: number;
|
|
43
|
-
};
|
|
44
|
-
type WithConcurrency = {
|
|
45
|
-
readonly concurrency?: number;
|
|
46
|
-
};
|
|
47
|
-
type WithSize = {
|
|
48
|
-
readonly size?: number;
|
|
49
|
-
};
|
|
50
|
-
type WithCooldown = {
|
|
51
|
-
readonly cooldown?: Duration;
|
|
52
|
-
};
|
|
53
|
-
type WithMinInterval = {
|
|
54
|
-
readonly minInterval?: Duration;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
type Ok<A> = WithKind<"Ok"> & WithValue<A>;
|
|
58
|
-
type Err<E> = WithKind<"Err"> & WithError<E>;
|
|
3
|
+
declare const _deferred: unique symbol;
|
|
59
4
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
5
|
+
* A nominally typed, one-shot async value that supports `await` but enforces infallibility.
|
|
6
|
+
*
|
|
7
|
+
* Two design choices work together to make the guarantee structural rather than documentary:
|
|
8
|
+
*
|
|
9
|
+
* - The phantom `[_deferred]` symbol makes the type **nominal**: only values produced by
|
|
10
|
+
* `Deferred.fromPromise` satisfy it. A plain object `{ then: ... }` does not.
|
|
11
|
+
* - The single-parameter `.then()` **excludes rejection handlers** by construction. There is
|
|
12
|
+
* no second argument to pass, so chaining and `.catch()` are impossible.
|
|
13
|
+
*
|
|
14
|
+
* This makes `Deferred<A>` the natural return type for `Task<A>`, which is guaranteed to
|
|
15
|
+
* never reject.
|
|
62
16
|
*
|
|
63
17
|
* @example
|
|
64
18
|
* ```ts
|
|
65
|
-
* const
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* pipe(
|
|
69
|
-
* divide(10, 2),
|
|
70
|
-
* Result.map(n => n * 2),
|
|
71
|
-
* Result.getOrElse(() => 0)
|
|
72
|
-
* ); // 10
|
|
19
|
+
* const value = await Deferred.fromPromise(Promise.resolve(42));
|
|
20
|
+
* // value === 42
|
|
73
21
|
* ```
|
|
74
22
|
*/
|
|
75
|
-
type
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const ok: <A>(value: A) => Ok<A>;
|
|
81
|
-
/**
|
|
82
|
-
* Creates a failed Result with the given error.
|
|
83
|
-
*/
|
|
84
|
-
const err: <E>(e: E) => Err<E>;
|
|
85
|
-
/**
|
|
86
|
-
* Type guard that checks if a Result is Ok.
|
|
87
|
-
*/
|
|
88
|
-
const isOk: <E, A>(data: Result<E, A>) => data is Ok<A>;
|
|
89
|
-
/**
|
|
90
|
-
* Type guard that checks if a Result is Err.
|
|
91
|
-
*/
|
|
92
|
-
const isErr: <E, A>(data: Result<E, A>) => data is Err<E>;
|
|
93
|
-
/**
|
|
94
|
-
* Creates a Result from a function that may throw.
|
|
95
|
-
* Catches any errors and transforms them using the onError function.
|
|
96
|
-
*
|
|
97
|
-
* @example
|
|
98
|
-
* ```ts
|
|
99
|
-
* const parseJson = (s: string): Result<string, unknown> =>
|
|
100
|
-
* Result.tryCatch(
|
|
101
|
-
* () => JSON.parse(s),
|
|
102
|
-
* (e) => `Parse error: ${e}`
|
|
103
|
-
* );
|
|
104
|
-
* ```
|
|
105
|
-
*/
|
|
106
|
-
const tryCatch: <E, A>(f: () => A, onError: (e: unknown) => E) => Result<E, A>;
|
|
107
|
-
/**
|
|
108
|
-
* Transforms the success value inside a Result.
|
|
109
|
-
*
|
|
110
|
-
* @example
|
|
111
|
-
* ```ts
|
|
112
|
-
* pipe(Result.ok(5), Result.map(n => n * 2)); // Ok(10)
|
|
113
|
-
* pipe(Result.err("error"), Result.map(n => n * 2)); // Err("error")
|
|
114
|
-
* ```
|
|
115
|
-
*/
|
|
116
|
-
const map: <E, A, B>(f: (a: A) => B) => (data: Result<E, A>) => Result<E, B>;
|
|
117
|
-
/**
|
|
118
|
-
* Transforms the error value inside a Result.
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* ```ts
|
|
122
|
-
* pipe(Result.err("oops"), Result.mapError(e => e.toUpperCase())); // Err("OOPS")
|
|
123
|
-
* ```
|
|
124
|
-
*/
|
|
125
|
-
const mapError: <E, F, A>(f: (e: E) => F) => (data: Result<E, A>) => Result<F, A>;
|
|
126
|
-
/**
|
|
127
|
-
* Chains Result computations. If the first is Ok, passes the value to f.
|
|
128
|
-
* If the first is Err, propagates the error.
|
|
129
|
-
*
|
|
130
|
-
* @example
|
|
131
|
-
* ```ts
|
|
132
|
-
* const validatePositive = (n: number): Result<string, number> =>
|
|
133
|
-
* n > 0 ? Result.ok(n) : Result.err("Must be positive");
|
|
134
|
-
*
|
|
135
|
-
* pipe(Result.ok(5), Result.chain(validatePositive)); // Ok(5)
|
|
136
|
-
* pipe(Result.ok(-1), Result.chain(validatePositive)); // Err("Must be positive")
|
|
137
|
-
* ```
|
|
138
|
-
*/
|
|
139
|
-
const chain: <E, A, B>(f: (a: A) => Result<E, B>) => (data: Result<E, A>) => Result<E, B>;
|
|
140
|
-
/**
|
|
141
|
-
* Extracts the value from a Result by providing handlers for both cases.
|
|
142
|
-
*
|
|
143
|
-
* @example
|
|
144
|
-
* ```ts
|
|
145
|
-
* pipe(
|
|
146
|
-
* Result.ok(5),
|
|
147
|
-
* Result.fold(
|
|
148
|
-
* e => `Error: ${e}`,
|
|
149
|
-
* n => `Value: ${n}`
|
|
150
|
-
* )
|
|
151
|
-
* ); // "Value: 5"
|
|
152
|
-
* ```
|
|
153
|
-
*/
|
|
154
|
-
const fold: <E, A, B>(onErr: (e: E) => B, onOk: (a: A) => B) => (data: Result<E, A>) => B;
|
|
155
|
-
/**
|
|
156
|
-
* Pattern matches on a Result, returning the result of the matching case.
|
|
157
|
-
*
|
|
158
|
-
* @example
|
|
159
|
-
* ```ts
|
|
160
|
-
* pipe(
|
|
161
|
-
* result,
|
|
162
|
-
* Result.match({
|
|
163
|
-
* ok: value => `Got ${value}`,
|
|
164
|
-
* err: error => `Failed: ${error}`
|
|
165
|
-
* })
|
|
166
|
-
* );
|
|
167
|
-
* ```
|
|
168
|
-
*/
|
|
169
|
-
const match: <E, A, B>(cases: {
|
|
170
|
-
ok: (a: A) => B;
|
|
171
|
-
err: (e: E) => B;
|
|
172
|
-
}) => (data: Result<E, A>) => B;
|
|
23
|
+
type Deferred<A> = {
|
|
24
|
+
readonly [_deferred]: A;
|
|
25
|
+
readonly then: (onfulfilled: (value: A) => unknown) => void;
|
|
26
|
+
};
|
|
27
|
+
declare namespace Deferred {
|
|
173
28
|
/**
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
* The default can be a different type, widening the result to `A | B`.
|
|
29
|
+
* Wraps a `Promise` into a `Deferred`, structurally excluding rejection handlers,
|
|
30
|
+
* `.catch()`, `.finally()`, and chainable `.then()`.
|
|
177
31
|
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* pipe(Result.err("error"), Result.getOrElse(() => 0)); // 0
|
|
182
|
-
* pipe(Result.err("error"), Result.getOrElse(() => null)); // null — typed as number | null
|
|
183
|
-
* ```
|
|
184
|
-
*/
|
|
185
|
-
const getOrElse: <E, A, B>(defaultValue: () => B) => (data: Result<E, A>) => A | B;
|
|
186
|
-
/**
|
|
187
|
-
* Executes a side effect on the success value without changing the Result.
|
|
188
|
-
* Useful for logging or debugging.
|
|
32
|
+
* **Precondition**: `p` must never reject. If `p` rejects, the returned `Deferred` will
|
|
33
|
+
* never resolve — `await`-ing it will hang indefinitely. Use `TaskResult.tryCatch` to
|
|
34
|
+
* handle operations that may fail before converting to a `Deferred`.
|
|
189
35
|
*
|
|
190
36
|
* @example
|
|
191
37
|
* ```ts
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* Result.tap(n => console.log("Value:", n)),
|
|
195
|
-
* Result.map(n => n * 2)
|
|
196
|
-
* );
|
|
38
|
+
* const d = Deferred.fromPromise(Promise.resolve("hello"));
|
|
39
|
+
* const value = await d; // "hello"
|
|
197
40
|
* ```
|
|
198
41
|
*/
|
|
199
|
-
const
|
|
42
|
+
const fromPromise: <A>(p: Promise<A>) => Deferred<A>;
|
|
200
43
|
/**
|
|
201
|
-
*
|
|
202
|
-
* Useful for logging or reporting errors.
|
|
44
|
+
* Converts a `Deferred` back into a `Promise`.
|
|
203
45
|
*
|
|
204
46
|
* @example
|
|
205
47
|
* ```ts
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
* Result.tapError(e => console.error("validation failed:", e)),
|
|
209
|
-
* Result.chain(save),
|
|
210
|
-
* )
|
|
48
|
+
* const p = Deferred.toPromise(Deferred.fromPromise(Promise.resolve(42)));
|
|
49
|
+
* // p is Promise<42>
|
|
211
50
|
* ```
|
|
212
51
|
*/
|
|
213
|
-
const
|
|
52
|
+
const toPromise: <A>(d: Deferred<A>) => Promise<A>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* A function that checks whether two values of type `A` are equal.
|
|
57
|
+
* Use built-in instances (`Equality.string`, `Equality.number`, etc.) as starting points,
|
|
58
|
+
* then adapt them with `Equality.by` and combine them with `Equality.and`.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* type User = { id: string; name: string };
|
|
63
|
+
* const byId = pipe(Equality.string, Equality.by((u: User) => u.id));
|
|
64
|
+
*
|
|
65
|
+
* pipe(users, Arr.uniqWith(byId));
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
type Equality<A> = (a: A, b: A) => boolean;
|
|
69
|
+
declare namespace Equality {
|
|
214
70
|
/**
|
|
215
|
-
*
|
|
216
|
-
* Returns Ok if the predicate passes, Err from onFalse otherwise.
|
|
71
|
+
* Equality for strings. Case-sensitive.
|
|
217
72
|
*
|
|
218
73
|
* @example
|
|
219
74
|
* ```ts
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
* pipe("", Result.fromPredicate(s => s.length > 0, () => "empty string")); // Err("empty string")
|
|
75
|
+
* Equality.string("hello", "hello"); // true
|
|
76
|
+
* Equality.string("hello", "Hello"); // false
|
|
223
77
|
* ```
|
|
224
78
|
*/
|
|
225
|
-
const
|
|
79
|
+
const string: Equality<string>;
|
|
226
80
|
/**
|
|
227
|
-
*
|
|
228
|
-
* Returns Ok if the value is not null or undefined, error from onNull otherwise.
|
|
81
|
+
* Equality for numbers. Uses strict equality.
|
|
229
82
|
*
|
|
230
83
|
* @example
|
|
231
84
|
* ```ts
|
|
232
|
-
*
|
|
233
|
-
* pipe(42, Result.fromNullable(() => "is null")); // Ok(42)
|
|
85
|
+
* Equality.number(42, 42); // true
|
|
234
86
|
* ```
|
|
235
87
|
*/
|
|
236
|
-
const
|
|
88
|
+
const number: Equality<number>;
|
|
237
89
|
/**
|
|
238
|
-
*
|
|
239
|
-
* Some becomes Ok, None becomes error from onNone.
|
|
90
|
+
* Equality for booleans.
|
|
240
91
|
*
|
|
241
92
|
* @example
|
|
242
93
|
* ```ts
|
|
243
|
-
*
|
|
244
|
-
* pipe(Maybe.some(42), Result.fromMaybe(() => "is none")); // Ok(42)
|
|
94
|
+
* Equality.boolean(true, true); // true
|
|
245
95
|
* ```
|
|
246
96
|
*/
|
|
247
|
-
const
|
|
97
|
+
const boolean: Equality<boolean>;
|
|
248
98
|
/**
|
|
249
|
-
*
|
|
250
|
-
* that catches errors and returns a Result.
|
|
99
|
+
* Equality for `Date` values. Compares by numeric time value.
|
|
251
100
|
*
|
|
252
101
|
* @example
|
|
253
102
|
* ```ts
|
|
254
|
-
*
|
|
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)
|
|
103
|
+
* Equality.date(new Date("2024-01-01"), new Date("2024-01-01")); // true
|
|
261
104
|
* ```
|
|
262
105
|
*/
|
|
263
|
-
const
|
|
264
|
-
/**
|
|
265
|
-
* Recovers from an error by providing a fallback Result.
|
|
266
|
-
* The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
|
|
267
|
-
*/
|
|
268
|
-
const recover: <E, A, B>(fallback: (e: E) => Result<E, B>) => (data: Result<E, A>) => Result<E, A | B>;
|
|
106
|
+
const date: Equality<Date>;
|
|
269
107
|
/**
|
|
270
|
-
*
|
|
271
|
-
*
|
|
108
|
+
* Lifts an element equality into an array equality. Two arrays are equal if they have the
|
|
109
|
+
* same length and every element pair is equal under `eq`.
|
|
272
110
|
*
|
|
273
111
|
* @example
|
|
274
112
|
* ```ts
|
|
275
|
-
*
|
|
276
|
-
* Result.err(new Error("not found")),
|
|
277
|
-
* Result.recoverUnless(e => e.message === "fatal", () => Result.ok(0))
|
|
278
|
-
* ); // Ok(0)
|
|
113
|
+
* Equality.array(Equality.number)([1, 2, 3], [1, 2, 3]); // true
|
|
279
114
|
* ```
|
|
280
115
|
*/
|
|
281
|
-
const
|
|
116
|
+
const array: <A>(eq: Equality<A>) => Equality<readonly A[]>;
|
|
282
117
|
/**
|
|
283
|
-
*
|
|
284
|
-
*
|
|
118
|
+
* Adapts an equality for type `A` into an equality for type `B` by extracting a field.
|
|
119
|
+
* Read as "equality by this field": `pipe(Equality.string, Equality.by(u => u.name))`.
|
|
285
120
|
*
|
|
286
121
|
* @example
|
|
287
122
|
* ```ts
|
|
288
|
-
*
|
|
289
|
-
*
|
|
123
|
+
* type Product = { id: string; price: number };
|
|
124
|
+
* const byId = pipe(Equality.string, Equality.by((p: Product) => p.id));
|
|
125
|
+
* byId({ id: "p1", price: 9 }, { id: "p1", price: 12 }); // true
|
|
290
126
|
* ```
|
|
291
127
|
*/
|
|
292
|
-
const
|
|
128
|
+
const by: <A, B>(f: (b: B) => A) => (eq: Equality<A>) => Equality<B>;
|
|
293
129
|
/**
|
|
294
|
-
*
|
|
130
|
+
* Combines two equalities with logical AND. Both must pass for two values to be considered equal.
|
|
131
|
+
* Data-last: the first equality is the data being piped.
|
|
295
132
|
*
|
|
296
133
|
* @example
|
|
297
134
|
* ```ts
|
|
298
|
-
* const
|
|
299
|
-
*
|
|
300
|
-
* Result.ok(add),
|
|
301
|
-
* Result.ap(Result.ok(5)),
|
|
302
|
-
* Result.ap(Result.ok(3))
|
|
303
|
-
* ); // Ok(8)
|
|
135
|
+
* const exact = pipe(byName, Equality.and(byRole));
|
|
136
|
+
* exact(userA, userB); // true only if name AND role match
|
|
304
137
|
* ```
|
|
305
138
|
*/
|
|
306
|
-
const
|
|
139
|
+
const and: <A>(eq2: Equality<A>) => (eq1: Equality<A>) => Equality<A>;
|
|
307
140
|
}
|
|
308
141
|
|
|
142
|
+
type WithKind<K extends string> = {
|
|
143
|
+
readonly kind: K;
|
|
144
|
+
};
|
|
145
|
+
type WithValue<T> = {
|
|
146
|
+
readonly value: T;
|
|
147
|
+
};
|
|
148
|
+
type WithError<T> = {
|
|
149
|
+
readonly error: T;
|
|
150
|
+
};
|
|
151
|
+
type WithErrors<T> = {
|
|
152
|
+
readonly errors: NonEmptyList<T>;
|
|
153
|
+
};
|
|
154
|
+
type WithFirst<T> = {
|
|
155
|
+
readonly first: T;
|
|
156
|
+
};
|
|
157
|
+
type WithSecond<T> = {
|
|
158
|
+
readonly second: T;
|
|
159
|
+
};
|
|
160
|
+
type WithLog<T> = {
|
|
161
|
+
readonly log: ReadonlyArray<T>;
|
|
162
|
+
};
|
|
163
|
+
/** Retry policy for `Op.interpret`. */
|
|
164
|
+
type RetryOptions<E> = {
|
|
165
|
+
readonly attempts: number;
|
|
166
|
+
readonly backoff?: Duration | ((attempt: number) => Duration);
|
|
167
|
+
readonly when?: (error: E) => boolean;
|
|
168
|
+
};
|
|
169
|
+
/** Timeout policy for `Op.interpret`. Wraps the entire retry sequence. */
|
|
170
|
+
type TimeoutOptions<E> = {
|
|
171
|
+
readonly duration: Duration;
|
|
172
|
+
readonly onTimeout: () => E;
|
|
173
|
+
};
|
|
174
|
+
type WithTimeout<E> = {
|
|
175
|
+
readonly timeout?: TimeoutOptions<E>;
|
|
176
|
+
};
|
|
177
|
+
type WithDuration = {
|
|
178
|
+
readonly duration: Duration;
|
|
179
|
+
};
|
|
180
|
+
type WithN = {
|
|
181
|
+
readonly n: number;
|
|
182
|
+
};
|
|
183
|
+
type WithConcurrency = {
|
|
184
|
+
readonly concurrency?: number;
|
|
185
|
+
};
|
|
186
|
+
type WithSize = {
|
|
187
|
+
readonly size?: number;
|
|
188
|
+
};
|
|
189
|
+
type WithCooldown = {
|
|
190
|
+
readonly cooldown?: Duration;
|
|
191
|
+
};
|
|
192
|
+
type WithMinInterval = {
|
|
193
|
+
readonly minInterval?: Duration;
|
|
194
|
+
};
|
|
195
|
+
|
|
309
196
|
type Some<A> = WithKind<"Some"> & WithValue<A>;
|
|
310
197
|
type None = WithKind<"None">;
|
|
311
198
|
/**
|
|
@@ -504,238 +391,421 @@ declare namespace Maybe {
|
|
|
504
391
|
* Recovers from a None by providing a fallback Maybe.
|
|
505
392
|
* The fallback can produce a different type, widening the result to `Maybe<A | B>`.
|
|
506
393
|
*/
|
|
507
|
-
const recover: <A, B>(fallback: () => Maybe<B>) => (data: Maybe<A>) => Maybe<A | B>;
|
|
394
|
+
const recover: <A, B>(fallback: () => Maybe<B>) => (data: Maybe<A>) => Maybe<A | B>;
|
|
395
|
+
/**
|
|
396
|
+
* Applies a function wrapped in a Maybe to a value wrapped in a Maybe.
|
|
397
|
+
*
|
|
398
|
+
* @example
|
|
399
|
+
* ```ts
|
|
400
|
+
* const add = (a: number) => (b: number) => a + b;
|
|
401
|
+
* pipe(
|
|
402
|
+
* Maybe.some(add),
|
|
403
|
+
* Maybe.ap(Maybe.some(5)),
|
|
404
|
+
* Maybe.ap(Maybe.some(3))
|
|
405
|
+
* ); // Some(8)
|
|
406
|
+
* ```
|
|
407
|
+
*/
|
|
408
|
+
const ap: <A>(arg: Maybe<A>) => <B>(data: Maybe<(a: A) => B>) => Maybe<B>;
|
|
409
|
+
/**
|
|
410
|
+
* Converts a Maybe value into an object containing a single property.
|
|
411
|
+
* Initiates the pipeline accumulator record.
|
|
412
|
+
*
|
|
413
|
+
* @example
|
|
414
|
+
* ```ts
|
|
415
|
+
* pipe(Maybe.some(42), Maybe.bindTo("value")); // Some({ value: 42 })
|
|
416
|
+
* ```
|
|
417
|
+
*/
|
|
418
|
+
const bindTo: <K extends string>(key: K) => <A>(data: Maybe<A>) => Maybe<{ [P in K]: A; }>;
|
|
419
|
+
/**
|
|
420
|
+
* Evaluates a new Maybe using the current accumulator and attaches the output to a new key.
|
|
421
|
+
*
|
|
422
|
+
* @example
|
|
423
|
+
* ```ts
|
|
424
|
+
* pipe(
|
|
425
|
+
* Maybe.some({ a: 1 }),
|
|
426
|
+
* Maybe.bind("b", ({ a }) => Maybe.some(a + 1))
|
|
427
|
+
* ); // Some({ a: 1, b: 2 })
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
const bind: <K extends string, A, B>(key: K, f: (a: A) => Maybe<B>) => (data: Maybe<A>) => Maybe<A & { [P in K]: B; }>;
|
|
431
|
+
/**
|
|
432
|
+
* Combines a record of Maybes into a single Maybe of a record.
|
|
433
|
+
* Evaluates fields in key order and short-circuits on the first None.
|
|
434
|
+
*
|
|
435
|
+
* @example
|
|
436
|
+
* ```ts
|
|
437
|
+
* Maybe.struct({
|
|
438
|
+
* name: Maybe.some("Alice"),
|
|
439
|
+
* age: Maybe.some(30)
|
|
440
|
+
* }); // Some({ name: "Alice", age: 30 })
|
|
441
|
+
* ```
|
|
442
|
+
*/
|
|
443
|
+
const struct: <R extends Record<string, any>>(fields: { [K in keyof R]: Maybe<R[K]>; }) => Maybe<R>;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* A function that orders two values of type `A`. Returns a negative number when `a` comes before
|
|
448
|
+
* `b`, a positive number when `a` comes after `b`, and `0` when they are equal.
|
|
449
|
+
*
|
|
450
|
+
* Compatible with `Array.prototype.sort` and `Arr.sortWith`.
|
|
451
|
+
*
|
|
452
|
+
* @example
|
|
453
|
+
* ```ts
|
|
454
|
+
* type Employee = { name: string; salary: number };
|
|
455
|
+
*
|
|
456
|
+
* const byName = pipe(Ordering.string, Ordering.by((e: Employee) => e.name));
|
|
457
|
+
* const bySalary = pipe(Ordering.number, Ordering.by((e: Employee) => e.salary));
|
|
458
|
+
*
|
|
459
|
+
* pipe(employees, Arr.sortWith(pipe(byName, Ordering.thenBy(bySalary))));
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
type Ordering<A> = (a: A, b: A) => number;
|
|
463
|
+
declare namespace Ordering {
|
|
464
|
+
/**
|
|
465
|
+
* Alphabetical ordering for strings.
|
|
466
|
+
*
|
|
467
|
+
* @example
|
|
468
|
+
* ```ts
|
|
469
|
+
* Ordering.string("apple", "banana"); // negative
|
|
470
|
+
* ```
|
|
471
|
+
*/
|
|
472
|
+
const string: Ordering<string>;
|
|
473
|
+
/**
|
|
474
|
+
* Numeric ordering. Equivalent to `(a, b) => a - b`.
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```ts
|
|
478
|
+
* pipe([3, 1, 2], Arr.sortWith(Ordering.number)); // [1, 2, 3]
|
|
479
|
+
* ```
|
|
480
|
+
*/
|
|
481
|
+
const number: Ordering<number>;
|
|
482
|
+
/**
|
|
483
|
+
* Ordering for `Date` values by numeric time value.
|
|
484
|
+
*
|
|
485
|
+
* @example
|
|
486
|
+
* ```ts
|
|
487
|
+
* pipe(dates, Arr.sortWith(Ordering.date)); // earliest first
|
|
488
|
+
* ```
|
|
489
|
+
*/
|
|
490
|
+
const date: Ordering<Date>;
|
|
491
|
+
/**
|
|
492
|
+
* Flips the direction of an ordering.
|
|
493
|
+
*
|
|
494
|
+
* @example
|
|
495
|
+
* ```ts
|
|
496
|
+
* pipe([3, 1, 2], Arr.sortWith(Ordering.reverse(Ordering.number))); // [3, 2, 1]
|
|
497
|
+
* ```
|
|
498
|
+
*/
|
|
499
|
+
const reverse: <A>(ord: Ordering<A>) => Ordering<A>;
|
|
500
|
+
/**
|
|
501
|
+
* Chains two orderings: the second is used only when the first returns `0`.
|
|
502
|
+
* Data-last: the first ordering is the data being piped.
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* ```ts
|
|
506
|
+
* const byDeptThenSalary = pipe(byDept, Ordering.thenBy(bySalary));
|
|
507
|
+
* ```
|
|
508
|
+
*/
|
|
509
|
+
const thenBy: <A>(ord2: Ordering<A>) => (ord1: Ordering<A>) => Ordering<A>;
|
|
510
|
+
/**
|
|
511
|
+
* Adapts an ordering for type `A` into an ordering for type `B` by extracting a field.
|
|
512
|
+
* Read as "ordering by this field": `pipe(Ordering.number, Ordering.by(p => p.price))`.
|
|
513
|
+
*
|
|
514
|
+
* @example
|
|
515
|
+
* ```ts
|
|
516
|
+
* type Product = { name: string; price: number };
|
|
517
|
+
* const byPrice = pipe(Ordering.number, Ordering.by((p: Product) => p.price));
|
|
518
|
+
* pipe(products, Arr.sortWith(byPrice));
|
|
519
|
+
* ```
|
|
520
|
+
*/
|
|
521
|
+
const by: <A, B>(f: (b: B) => A) => (ord: Ordering<A>) => Ordering<B>;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
type Ok<A> = WithKind<"Ok"> & WithValue<A>;
|
|
525
|
+
type Err<E> = WithKind<"Err"> & WithError<E>;
|
|
526
|
+
/**
|
|
527
|
+
* Result represents a value that can be one of two types: a success (Ok) or a failure (Err).
|
|
528
|
+
* Use Result when an operation can fail with a meaningful error value.
|
|
529
|
+
*
|
|
530
|
+
* @example
|
|
531
|
+
* ```ts
|
|
532
|
+
* const divide = (a: number, b: number): Result<string, number> =>
|
|
533
|
+
* b === 0 ? Result.err("Division by zero") : Result.ok(a / b);
|
|
534
|
+
*
|
|
535
|
+
* pipe(
|
|
536
|
+
* divide(10, 2),
|
|
537
|
+
* Result.map(n => n * 2),
|
|
538
|
+
* Result.getOrElse(() => 0)
|
|
539
|
+
* ); // 10
|
|
540
|
+
* ```
|
|
541
|
+
*/
|
|
542
|
+
type Result<E, A> = Ok<A> | Err<E>;
|
|
543
|
+
declare namespace Result {
|
|
544
|
+
/**
|
|
545
|
+
* Creates a successful Result with the given value.
|
|
546
|
+
*/
|
|
547
|
+
const ok: <A>(value: A) => Ok<A>;
|
|
548
|
+
/**
|
|
549
|
+
* Creates a failed Result with the given error.
|
|
550
|
+
*/
|
|
551
|
+
const err: <E>(e: E) => Err<E>;
|
|
552
|
+
/**
|
|
553
|
+
* Type guard that checks if a Result is Ok.
|
|
554
|
+
*/
|
|
555
|
+
const isOk: <E, A>(data: Result<E, A>) => data is Ok<A>;
|
|
556
|
+
/**
|
|
557
|
+
* Type guard that checks if a Result is Err.
|
|
558
|
+
*/
|
|
559
|
+
const isErr: <E, A>(data: Result<E, A>) => data is Err<E>;
|
|
560
|
+
/**
|
|
561
|
+
* Creates a Result from a function that may throw.
|
|
562
|
+
* Catches any errors and transforms them using the onError function.
|
|
563
|
+
*
|
|
564
|
+
* @example
|
|
565
|
+
* ```ts
|
|
566
|
+
* const parseJson = (s: string): Result<string, unknown> =>
|
|
567
|
+
* Result.tryCatch(
|
|
568
|
+
* () => JSON.parse(s),
|
|
569
|
+
* (e) => `Parse error: ${e}`
|
|
570
|
+
* );
|
|
571
|
+
* ```
|
|
572
|
+
*/
|
|
573
|
+
const tryCatch: <E, A>(f: () => A, onError: (e: unknown) => E) => Result<E, A>;
|
|
574
|
+
/**
|
|
575
|
+
* Transforms the success value inside a Result.
|
|
576
|
+
*
|
|
577
|
+
* @example
|
|
578
|
+
* ```ts
|
|
579
|
+
* pipe(Result.ok(5), Result.map(n => n * 2)); // Ok(10)
|
|
580
|
+
* pipe(Result.err("error"), Result.map(n => n * 2)); // Err("error")
|
|
581
|
+
* ```
|
|
582
|
+
*/
|
|
583
|
+
const map: <E, A, B>(f: (a: A) => B) => (data: Result<E, A>) => Result<E, B>;
|
|
584
|
+
/**
|
|
585
|
+
* Transforms the error value inside a Result.
|
|
586
|
+
*
|
|
587
|
+
* @example
|
|
588
|
+
* ```ts
|
|
589
|
+
* pipe(Result.err("oops"), Result.mapError(e => e.toUpperCase())); // Err("OOPS")
|
|
590
|
+
* ```
|
|
591
|
+
*/
|
|
592
|
+
const mapError: <E, F, A>(f: (e: E) => F) => (data: Result<E, A>) => Result<F, A>;
|
|
508
593
|
/**
|
|
509
|
-
*
|
|
594
|
+
* Chains Result computations. If the first is Ok, passes the value to f.
|
|
595
|
+
* If the first is Err, propagates the error.
|
|
510
596
|
*
|
|
511
597
|
* @example
|
|
512
598
|
* ```ts
|
|
513
|
-
* const
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
*
|
|
517
|
-
*
|
|
518
|
-
* ); // Some(8)
|
|
599
|
+
* const validatePositive = (n: number): Result<string, number> =>
|
|
600
|
+
* n > 0 ? Result.ok(n) : Result.err("Must be positive");
|
|
601
|
+
*
|
|
602
|
+
* pipe(Result.ok(5), Result.chain(validatePositive)); // Ok(5)
|
|
603
|
+
* pipe(Result.ok(-1), Result.chain(validatePositive)); // Err("Must be positive")
|
|
519
604
|
* ```
|
|
520
605
|
*/
|
|
521
|
-
const
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
declare const _deferred: unique symbol;
|
|
525
|
-
/**
|
|
526
|
-
* A nominally typed, one-shot async value that supports `await` but enforces infallibility.
|
|
527
|
-
*
|
|
528
|
-
* Two design choices work together to make the guarantee structural rather than documentary:
|
|
529
|
-
*
|
|
530
|
-
* - The phantom `[_deferred]` symbol makes the type **nominal**: only values produced by
|
|
531
|
-
* `Deferred.fromPromise` satisfy it. A plain object `{ then: ... }` does not.
|
|
532
|
-
* - The single-parameter `.then()` **excludes rejection handlers** by construction. There is
|
|
533
|
-
* no second argument to pass, so chaining and `.catch()` are impossible.
|
|
534
|
-
*
|
|
535
|
-
* This makes `Deferred<A>` the natural return type for `Task<A>`, which is guaranteed to
|
|
536
|
-
* never reject.
|
|
537
|
-
*
|
|
538
|
-
* @example
|
|
539
|
-
* ```ts
|
|
540
|
-
* const value = await Deferred.fromPromise(Promise.resolve(42));
|
|
541
|
-
* // value === 42
|
|
542
|
-
* ```
|
|
543
|
-
*/
|
|
544
|
-
type Deferred<A> = {
|
|
545
|
-
readonly [_deferred]: A;
|
|
546
|
-
readonly then: (onfulfilled: (value: A) => unknown) => void;
|
|
547
|
-
};
|
|
548
|
-
declare namespace Deferred {
|
|
606
|
+
const chain: <E, A, B>(f: (a: A) => Result<E, B>) => (data: Result<E, A>) => Result<E, B>;
|
|
549
607
|
/**
|
|
550
|
-
*
|
|
551
|
-
* `.catch()`, `.finally()`, and chainable `.then()`.
|
|
552
|
-
*
|
|
553
|
-
* **Precondition**: `p` must never reject. If `p` rejects, the returned `Deferred` will
|
|
554
|
-
* never resolve — `await`-ing it will hang indefinitely. Use `TaskResult.tryCatch` to
|
|
555
|
-
* handle operations that may fail before converting to a `Deferred`.
|
|
608
|
+
* Extracts the value from a Result by providing handlers for both cases.
|
|
556
609
|
*
|
|
557
610
|
* @example
|
|
558
611
|
* ```ts
|
|
559
|
-
*
|
|
560
|
-
*
|
|
612
|
+
* pipe(
|
|
613
|
+
* Result.ok(5),
|
|
614
|
+
* Result.fold(
|
|
615
|
+
* e => `Error: ${e}`,
|
|
616
|
+
* n => `Value: ${n}`
|
|
617
|
+
* )
|
|
618
|
+
* ); // "Value: 5"
|
|
561
619
|
* ```
|
|
562
620
|
*/
|
|
563
|
-
const
|
|
621
|
+
const fold: <E, A, B>(onErr: (e: E) => B, onOk: (a: A) => B) => (data: Result<E, A>) => B;
|
|
564
622
|
/**
|
|
565
|
-
*
|
|
623
|
+
* Pattern matches on a Result, returning the result of the matching case.
|
|
566
624
|
*
|
|
567
625
|
* @example
|
|
568
626
|
* ```ts
|
|
569
|
-
*
|
|
570
|
-
*
|
|
627
|
+
* pipe(
|
|
628
|
+
* result,
|
|
629
|
+
* Result.match({
|
|
630
|
+
* ok: value => `Got ${value}`,
|
|
631
|
+
* err: error => `Failed: ${error}`
|
|
632
|
+
* })
|
|
633
|
+
* );
|
|
571
634
|
* ```
|
|
572
635
|
*/
|
|
573
|
-
const
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
* A function that checks whether two values of type `A` are equal.
|
|
578
|
-
* Use built-in instances (`Equality.string`, `Equality.number`, etc.) as starting points,
|
|
579
|
-
* then adapt them with `Equality.by` and combine them with `Equality.and`.
|
|
580
|
-
*
|
|
581
|
-
* @example
|
|
582
|
-
* ```ts
|
|
583
|
-
* type User = { id: string; name: string };
|
|
584
|
-
* const byId = pipe(Equality.string, Equality.by((u: User) => u.id));
|
|
585
|
-
*
|
|
586
|
-
* pipe(users, Arr.uniqWith(byId));
|
|
587
|
-
* ```
|
|
588
|
-
*/
|
|
589
|
-
type Equality<A> = (a: A, b: A) => boolean;
|
|
590
|
-
declare namespace Equality {
|
|
636
|
+
const match: <E, A, B>(cases: {
|
|
637
|
+
ok: (a: A) => B;
|
|
638
|
+
err: (e: E) => B;
|
|
639
|
+
}) => (data: Result<E, A>) => B;
|
|
591
640
|
/**
|
|
592
|
-
*
|
|
641
|
+
* Returns the success value or a default value if the Result is an error.
|
|
642
|
+
* The default is a thunk `() => B` — evaluated only when the Result is Err.
|
|
643
|
+
* The default can be a different type, widening the result to `A | B`.
|
|
593
644
|
*
|
|
594
645
|
* @example
|
|
595
646
|
* ```ts
|
|
596
|
-
*
|
|
597
|
-
*
|
|
647
|
+
* pipe(Result.ok(5), Result.getOrElse(() => 0)); // 5
|
|
648
|
+
* pipe(Result.err("error"), Result.getOrElse(() => 0)); // 0
|
|
649
|
+
* pipe(Result.err("error"), Result.getOrElse(() => null)); // null — typed as number | null
|
|
598
650
|
* ```
|
|
599
651
|
*/
|
|
600
|
-
const
|
|
652
|
+
const getOrElse: <E, A, B>(defaultValue: () => B) => (data: Result<E, A>) => A | B;
|
|
601
653
|
/**
|
|
602
|
-
*
|
|
654
|
+
* Executes a side effect on the success value without changing the Result.
|
|
655
|
+
* Useful for logging or debugging.
|
|
603
656
|
*
|
|
604
657
|
* @example
|
|
605
658
|
* ```ts
|
|
606
|
-
*
|
|
659
|
+
* pipe(
|
|
660
|
+
* Result.ok(5),
|
|
661
|
+
* Result.tap(n => console.log("Value:", n)),
|
|
662
|
+
* Result.map(n => n * 2)
|
|
663
|
+
* );
|
|
607
664
|
* ```
|
|
608
665
|
*/
|
|
609
|
-
const
|
|
666
|
+
const tap: <E, A>(f: (a: A) => void) => (data: Result<E, A>) => Result<E, A>;
|
|
610
667
|
/**
|
|
611
|
-
*
|
|
668
|
+
* Executes a side effect on the error value without changing the Result.
|
|
669
|
+
* Useful for logging or reporting errors.
|
|
612
670
|
*
|
|
613
671
|
* @example
|
|
614
672
|
* ```ts
|
|
615
|
-
*
|
|
673
|
+
* pipe(
|
|
674
|
+
* Result.err("not found"),
|
|
675
|
+
* Result.tapError(e => console.error("validation failed:", e)),
|
|
676
|
+
* Result.chain(save),
|
|
677
|
+
* )
|
|
616
678
|
* ```
|
|
617
679
|
*/
|
|
618
|
-
const
|
|
680
|
+
const tapError: <E, A>(f: (e: E) => void) => (data: Result<E, A>) => Result<E, A>;
|
|
619
681
|
/**
|
|
620
|
-
*
|
|
682
|
+
* Creates a Result from a predicate applied to a value.
|
|
683
|
+
* Returns Ok if the predicate passes, Err from onFalse otherwise.
|
|
621
684
|
*
|
|
622
685
|
* @example
|
|
623
686
|
* ```ts
|
|
624
|
-
*
|
|
687
|
+
* pipe(5, Result.fromPredicate(n => n > 0, n => `${n} is not positive`)); // Ok(5)
|
|
688
|
+
* pipe(-1, Result.fromPredicate(n => n > 0, n => `${n} is not positive`)); // Err("-1 is not positive")
|
|
689
|
+
* pipe("", Result.fromPredicate(s => s.length > 0, () => "empty string")); // Err("empty string")
|
|
625
690
|
* ```
|
|
626
691
|
*/
|
|
627
|
-
const
|
|
692
|
+
const fromPredicate: <E, A>(pred: (a: A) => boolean, onFalse: (a: A) => E) => (a: A) => Result<E, A>;
|
|
628
693
|
/**
|
|
629
|
-
*
|
|
630
|
-
*
|
|
694
|
+
* Creates a Result from a nullable value.
|
|
695
|
+
* Returns Ok if the value is not null or undefined, error from onNull otherwise.
|
|
631
696
|
*
|
|
632
697
|
* @example
|
|
633
698
|
* ```ts
|
|
634
|
-
*
|
|
699
|
+
* pipe(null, Result.fromNullable(() => "is null")); // Err("is null")
|
|
700
|
+
* pipe(42, Result.fromNullable(() => "is null")); // Ok(42)
|
|
635
701
|
* ```
|
|
636
702
|
*/
|
|
637
|
-
const
|
|
703
|
+
const fromNullable: <E>(onNull: () => E) => <A>(value: A | null | undefined) => Result<E, A>;
|
|
638
704
|
/**
|
|
639
|
-
*
|
|
640
|
-
*
|
|
705
|
+
* Creates a Result from a Maybe.
|
|
706
|
+
* Some becomes Ok, None becomes error from onNone.
|
|
641
707
|
*
|
|
642
708
|
* @example
|
|
643
709
|
* ```ts
|
|
644
|
-
*
|
|
645
|
-
*
|
|
646
|
-
* byId({ id: "p1", price: 9 }, { id: "p1", price: 12 }); // true
|
|
710
|
+
* pipe(Maybe.none(), Result.fromMaybe(() => "is none")); // Err("is none")
|
|
711
|
+
* pipe(Maybe.some(42), Result.fromMaybe(() => "is none")); // Ok(42)
|
|
647
712
|
* ```
|
|
648
713
|
*/
|
|
649
|
-
const
|
|
714
|
+
const fromMaybe: <E>(onNone: () => E) => <A>(maybe: Maybe<A>) => Result<E, A>;
|
|
650
715
|
/**
|
|
651
|
-
*
|
|
652
|
-
*
|
|
716
|
+
* Wraps a throwing function of any arguments, returning a new function
|
|
717
|
+
* that catches errors and returns a Result.
|
|
653
718
|
*
|
|
654
719
|
* @example
|
|
655
720
|
* ```ts
|
|
656
|
-
* const
|
|
657
|
-
*
|
|
721
|
+
* const safeParse = Result.fromThrowable(
|
|
722
|
+
* (s: string) => JSON.parse(s),
|
|
723
|
+
* (e) => new Error(`Parse error: ${e}`)
|
|
724
|
+
* );
|
|
725
|
+
*
|
|
726
|
+
* safeParse('{"a":1}'); // Ok({ a: 1 })
|
|
727
|
+
* safeParse('invalid'); // Err(Error)
|
|
658
728
|
* ```
|
|
659
729
|
*/
|
|
660
|
-
const
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
/**
|
|
664
|
-
* A function that orders two values of type `A`. Returns a negative number when `a` comes before
|
|
665
|
-
* `b`, a positive number when `a` comes after `b`, and `0` when they are equal.
|
|
666
|
-
*
|
|
667
|
-
* Compatible with `Array.prototype.sort` and `Arr.sortWith`.
|
|
668
|
-
*
|
|
669
|
-
* @example
|
|
670
|
-
* ```ts
|
|
671
|
-
* type Employee = { name: string; salary: number };
|
|
672
|
-
*
|
|
673
|
-
* const byName = pipe(Ordering.string, Ordering.by((e: Employee) => e.name));
|
|
674
|
-
* const bySalary = pipe(Ordering.number, Ordering.by((e: Employee) => e.salary));
|
|
675
|
-
*
|
|
676
|
-
* pipe(employees, Arr.sortWith(pipe(byName, Ordering.thenBy(bySalary))));
|
|
677
|
-
* ```
|
|
678
|
-
*/
|
|
679
|
-
type Ordering<A> = (a: A, b: A) => number;
|
|
680
|
-
declare namespace Ordering {
|
|
730
|
+
const fromThrowable: <Args extends readonly unknown[], A, E>(f: (...args: Args) => A, onError: (e: unknown) => E) => (...args: Args) => Result<E, A>;
|
|
681
731
|
/**
|
|
682
|
-
*
|
|
732
|
+
* Recovers from an error by providing a fallback Result.
|
|
733
|
+
* The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
|
|
734
|
+
*/
|
|
735
|
+
const recover: <E, A, B>(fallback: (e: E) => Result<E, B>) => (data: Result<E, A>) => Result<E, A | B>;
|
|
736
|
+
/**
|
|
737
|
+
* Recovers from an error unless the predicate `isBlocked` returns true for that error.
|
|
738
|
+
* The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
|
|
683
739
|
*
|
|
684
740
|
* @example
|
|
685
741
|
* ```ts
|
|
686
|
-
*
|
|
742
|
+
* pipe(
|
|
743
|
+
* Result.err(new Error("not found")),
|
|
744
|
+
* Result.recoverUnless(e => e.message === "fatal", () => Result.ok(0))
|
|
745
|
+
* ); // Ok(0)
|
|
687
746
|
* ```
|
|
688
747
|
*/
|
|
689
|
-
const
|
|
748
|
+
const recoverUnless: <E, A, B>(isBlocked: (e: E) => boolean, fallback: () => Result<E, B>) => (data: Result<E, A>) => Result<E, A | B>;
|
|
690
749
|
/**
|
|
691
|
-
*
|
|
750
|
+
* Converts a Result to a Maybe.
|
|
751
|
+
* Ok becomes Some, Err becomes None (the error is discarded).
|
|
692
752
|
*
|
|
693
753
|
* @example
|
|
694
754
|
* ```ts
|
|
695
|
-
*
|
|
755
|
+
* Result.toMaybe(Result.ok(42)); // Some(42)
|
|
756
|
+
* Result.toMaybe(Result.err("oops")); // None
|
|
696
757
|
* ```
|
|
697
758
|
*/
|
|
698
|
-
const
|
|
759
|
+
const toMaybe: <E, A>(data: Result<E, A>) => Maybe<A>;
|
|
699
760
|
/**
|
|
700
|
-
*
|
|
761
|
+
* Applies a function wrapped in a Result to a value wrapped in a Result.
|
|
701
762
|
*
|
|
702
763
|
* @example
|
|
703
764
|
* ```ts
|
|
704
|
-
*
|
|
765
|
+
* const add = (a: number) => (b: number) => a + b;
|
|
766
|
+
* pipe(
|
|
767
|
+
* Result.ok(add),
|
|
768
|
+
* Result.ap(Result.ok(5)),
|
|
769
|
+
* Result.ap(Result.ok(3))
|
|
770
|
+
* ); // Ok(8)
|
|
705
771
|
* ```
|
|
706
772
|
*/
|
|
707
|
-
const
|
|
773
|
+
const ap: <E, A>(arg: Result<E, A>) => <B>(data: Result<E, (a: A) => B>) => Result<E, B>;
|
|
708
774
|
/**
|
|
709
|
-
*
|
|
775
|
+
* Converts a Result value into an object containing a single property.
|
|
776
|
+
* Initiates the pipeline accumulator record.
|
|
710
777
|
*
|
|
711
778
|
* @example
|
|
712
779
|
* ```ts
|
|
713
|
-
* pipe(
|
|
780
|
+
* pipe(Result.ok(42), Result.bindTo("value")); // Ok({ value: 42 })
|
|
714
781
|
* ```
|
|
715
782
|
*/
|
|
716
|
-
const
|
|
783
|
+
const bindTo: <K extends string>(key: K) => <E, A>(data: Result<E, A>) => Result<E, { [P in K]: A; }>;
|
|
717
784
|
/**
|
|
718
|
-
*
|
|
719
|
-
* Data-last: the first ordering is the data being piped.
|
|
785
|
+
* Evaluates a new Result using the current accumulator and attaches the output to a new key.
|
|
720
786
|
*
|
|
721
787
|
* @example
|
|
722
788
|
* ```ts
|
|
723
|
-
*
|
|
789
|
+
* pipe(
|
|
790
|
+
* Result.ok({ a: 1 }),
|
|
791
|
+
* Result.bind("b", ({ a }) => Result.ok(a + 1))
|
|
792
|
+
* ); // Ok({ a: 1, b: 2 })
|
|
724
793
|
* ```
|
|
725
794
|
*/
|
|
726
|
-
const
|
|
795
|
+
const 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; }>;
|
|
727
796
|
/**
|
|
728
|
-
*
|
|
729
|
-
*
|
|
797
|
+
* Combines a record of Results into a single Result of a record.
|
|
798
|
+
* Evaluates fields in key order and short-circuits on the first failure.
|
|
730
799
|
*
|
|
731
800
|
* @example
|
|
732
801
|
* ```ts
|
|
733
|
-
*
|
|
734
|
-
*
|
|
735
|
-
*
|
|
802
|
+
* Result.struct({
|
|
803
|
+
* name: Result.ok("Alice"),
|
|
804
|
+
* age: Result.ok(30)
|
|
805
|
+
* }); // Ok({ name: "Alice", age: 30 })
|
|
736
806
|
* ```
|
|
737
807
|
*/
|
|
738
|
-
const
|
|
808
|
+
const struct: <E, R extends Record<string, any>>(fields: { [K in keyof R]: Result<E, R[K]>; }) => Result<E, R>;
|
|
739
809
|
}
|
|
740
810
|
|
|
741
811
|
/**
|
|
@@ -1024,6 +1094,28 @@ declare namespace Task {
|
|
|
1024
1094
|
* ```
|
|
1025
1095
|
*/
|
|
1026
1096
|
const run: (signal?: AbortSignal) => <A>(task: Task<A>) => Promise<A>;
|
|
1097
|
+
/**
|
|
1098
|
+
* Converts a Task value into an object containing a single property.
|
|
1099
|
+
* Initiates the pipeline accumulator record.
|
|
1100
|
+
*
|
|
1101
|
+
* @example
|
|
1102
|
+
* ```ts
|
|
1103
|
+
* pipe(Task.resolve(42), Task.bindTo("value")); // Task({ value: 42 })
|
|
1104
|
+
* ```
|
|
1105
|
+
*/
|
|
1106
|
+
const bindTo: <K extends string>(key: K) => <A>(data: Task<A>) => Task<{ [P in K]: A; }>;
|
|
1107
|
+
/**
|
|
1108
|
+
* Evaluates a new Task using the current accumulator and attaches the output to a new key.
|
|
1109
|
+
*
|
|
1110
|
+
* @example
|
|
1111
|
+
* ```ts
|
|
1112
|
+
* pipe(
|
|
1113
|
+
* Task.resolve({ a: 1 }),
|
|
1114
|
+
* Task.bind("b", ({ a }) => Task.resolve(a + 1))
|
|
1115
|
+
* ); // Task({ a: 1, b: 2 })
|
|
1116
|
+
* ```
|
|
1117
|
+
*/
|
|
1118
|
+
const bind: <K extends string, A, B>(key: K, f: (a: A) => Task<B>) => (data: Task<A>) => Task<A & { [P in K]: B; }>;
|
|
1027
1119
|
}
|
|
1028
1120
|
|
|
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
|
|
1121
|
+
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 WithConcurrency as W, type Err as a, Ordering as b, type RetryOptions as c, type TimeoutOptions as d, type WithCooldown as e, type WithDuration as f, type WithError as g, type WithErrors as h, type WithFirst as i, type WithKind as j, type WithLog as k, type WithMinInterval as l, type WithN as m, type WithSecond as n, type WithSize as o, type WithTimeout as p, type WithValue as q };
|