@nlozgachev/pipelined 0.37.0 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -7
- package/dist/{Task-fn1n--6H.d.mts → Task-DcXhCZYg.d.mts} +429 -403
- package/dist/{Task-DIgwvoIb.d.ts → Task-uupX7xd9.d.ts} +429 -403
- package/dist/{chunk-VWVPHDZO.mjs → chunk-5AFEEFE4.mjs} +5 -1
- package/dist/{chunk-72BGUEQM.mjs → chunk-E7YI5PVW.mjs} +2 -2
- package/dist/{chunk-SHO53CQC.mjs → chunk-M2X7TFKN.mjs} +483 -103
- package/dist/core.d.mts +683 -651
- package/dist/core.d.ts +683 -651
- package/dist/core.js +319 -261
- package/dist/core.mjs +6 -8
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +336 -278
- 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 +81 -55
- package/dist/utils.mjs +3 -4
- package/package.json +10 -3
- package/dist/chunk-DBIC62UV.mjs +0 -6
- package/dist/chunk-IPP4XFYH.mjs +0 -0
- package/dist/chunk-PUMSVZB4.mjs +0 -334
|
@@ -1,333 +1,198 @@
|
|
|
1
1
|
import { NonEmptyList, Duration } from './types.js';
|
|
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;
|
|
173
|
-
/**
|
|
174
|
-
* Returns the success value or a default value if the Result is an error.
|
|
175
|
-
* The default is a thunk `() => B` — evaluated only when the Result is Err.
|
|
176
|
-
* The default can be a different type, widening the result to `A | B`.
|
|
177
|
-
*
|
|
178
|
-
* @example
|
|
179
|
-
* ```ts
|
|
180
|
-
* pipe(Result.ok(5), Result.getOrElse(() => 0)); // 5
|
|
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.
|
|
189
|
-
*
|
|
190
|
-
* @example
|
|
191
|
-
* ```ts
|
|
192
|
-
* pipe(
|
|
193
|
-
* Result.ok(5),
|
|
194
|
-
* Result.tap(n => console.log("Value:", n)),
|
|
195
|
-
* Result.map(n => n * 2)
|
|
196
|
-
* );
|
|
197
|
-
* ```
|
|
198
|
-
*/
|
|
199
|
-
const tap: <E, A>(f: (a: A) => void) => (data: Result<E, A>) => Result<E, A>;
|
|
23
|
+
type Deferred<A> = {
|
|
24
|
+
readonly [_deferred]: A;
|
|
25
|
+
readonly then: (onfulfilled: (value: A) => unknown) => void;
|
|
26
|
+
};
|
|
27
|
+
declare namespace Deferred {
|
|
200
28
|
/**
|
|
201
|
-
*
|
|
202
|
-
*
|
|
29
|
+
* Wraps a `Promise` into a `Deferred`, structurally excluding rejection handlers,
|
|
30
|
+
* `.catch()`, `.finally()`, and chainable `.then()`.
|
|
203
31
|
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
* Result.err("not found"),
|
|
208
|
-
* Result.tapError(e => console.error("validation failed:", e)),
|
|
209
|
-
* Result.chain(save),
|
|
210
|
-
* )
|
|
211
|
-
* ```
|
|
212
|
-
*/
|
|
213
|
-
const tapError: <E, A>(f: (e: E) => void) => (data: Result<E, A>) => Result<E, A>;
|
|
214
|
-
/**
|
|
215
|
-
* Creates a Result from a predicate applied to a value.
|
|
216
|
-
* Returns Ok if the predicate passes, Err from onFalse otherwise.
|
|
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`.
|
|
217
35
|
*
|
|
218
36
|
* @example
|
|
219
37
|
* ```ts
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
* pipe("", Result.fromPredicate(s => s.length > 0, () => "empty string")); // Err("empty string")
|
|
38
|
+
* const d = Deferred.fromPromise(Promise.resolve("hello"));
|
|
39
|
+
* const value = await d; // "hello"
|
|
223
40
|
* ```
|
|
224
41
|
*/
|
|
225
|
-
const
|
|
42
|
+
const fromPromise: <A>(p: Promise<A>) => Deferred<A>;
|
|
226
43
|
/**
|
|
227
|
-
*
|
|
228
|
-
* Returns Ok if the value is not null or undefined, error from onNull otherwise.
|
|
44
|
+
* Converts a `Deferred` back into a `Promise`.
|
|
229
45
|
*
|
|
230
46
|
* @example
|
|
231
47
|
* ```ts
|
|
232
|
-
*
|
|
233
|
-
*
|
|
48
|
+
* const p = Deferred.toPromise(Deferred.fromPromise(Promise.resolve(42)));
|
|
49
|
+
* // p is Promise<42>
|
|
234
50
|
* ```
|
|
235
51
|
*/
|
|
236
|
-
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 {
|
|
237
70
|
/**
|
|
238
|
-
*
|
|
239
|
-
* Some becomes Ok, None becomes error from onNone.
|
|
71
|
+
* Equality for strings. Case-sensitive.
|
|
240
72
|
*
|
|
241
73
|
* @example
|
|
242
74
|
* ```ts
|
|
243
|
-
*
|
|
244
|
-
*
|
|
75
|
+
* Equality.string("hello", "hello"); // true
|
|
76
|
+
* Equality.string("hello", "Hello"); // false
|
|
245
77
|
* ```
|
|
246
78
|
*/
|
|
247
|
-
const
|
|
79
|
+
const string: Equality<string>;
|
|
248
80
|
/**
|
|
249
|
-
*
|
|
250
|
-
* that catches errors and returns a Result.
|
|
81
|
+
* Equality for numbers. Uses strict equality.
|
|
251
82
|
*
|
|
252
83
|
* @example
|
|
253
84
|
* ```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)
|
|
85
|
+
* Equality.number(42, 42); // true
|
|
261
86
|
* ```
|
|
262
87
|
*/
|
|
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>;
|
|
88
|
+
const number: Equality<number>;
|
|
269
89
|
/**
|
|
270
|
-
*
|
|
271
|
-
* The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
|
|
90
|
+
* Equality for booleans.
|
|
272
91
|
*
|
|
273
92
|
* @example
|
|
274
93
|
* ```ts
|
|
275
|
-
*
|
|
276
|
-
* Result.err(new Error("not found")),
|
|
277
|
-
* Result.recoverUnless(e => e.message === "fatal", () => Result.ok(0))
|
|
278
|
-
* ); // Ok(0)
|
|
94
|
+
* Equality.boolean(true, true); // true
|
|
279
95
|
* ```
|
|
280
96
|
*/
|
|
281
|
-
const
|
|
97
|
+
const boolean: Equality<boolean>;
|
|
282
98
|
/**
|
|
283
|
-
*
|
|
284
|
-
* Ok becomes Some, Err becomes None (the error is discarded).
|
|
99
|
+
* Equality for `Date` values. Compares by numeric time value.
|
|
285
100
|
*
|
|
286
101
|
* @example
|
|
287
102
|
* ```ts
|
|
288
|
-
*
|
|
289
|
-
* Result.toMaybe(Result.err("oops")); // None
|
|
103
|
+
* Equality.date(new Date("2024-01-01"), new Date("2024-01-01")); // true
|
|
290
104
|
* ```
|
|
291
105
|
*/
|
|
292
|
-
const
|
|
106
|
+
const date: Equality<Date>;
|
|
293
107
|
/**
|
|
294
|
-
*
|
|
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`.
|
|
295
110
|
*
|
|
296
111
|
* @example
|
|
297
112
|
* ```ts
|
|
298
|
-
*
|
|
299
|
-
* pipe(
|
|
300
|
-
* Result.ok(add),
|
|
301
|
-
* Result.ap(Result.ok(5)),
|
|
302
|
-
* Result.ap(Result.ok(3))
|
|
303
|
-
* ); // Ok(8)
|
|
113
|
+
* Equality.array(Equality.number)([1, 2, 3], [1, 2, 3]); // true
|
|
304
114
|
* ```
|
|
305
115
|
*/
|
|
306
|
-
const
|
|
116
|
+
const array: <A>(eq: Equality<A>) => Equality<readonly A[]>;
|
|
307
117
|
/**
|
|
308
|
-
*
|
|
309
|
-
*
|
|
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))`.
|
|
310
120
|
*
|
|
311
121
|
* @example
|
|
312
122
|
* ```ts
|
|
313
|
-
*
|
|
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
|
|
314
126
|
* ```
|
|
315
127
|
*/
|
|
316
|
-
const
|
|
128
|
+
const by: <A, B>(f: (b: B) => A) => (eq: Equality<A>) => Equality<B>;
|
|
317
129
|
/**
|
|
318
|
-
*
|
|
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.
|
|
319
132
|
*
|
|
320
133
|
* @example
|
|
321
134
|
* ```ts
|
|
322
|
-
* pipe(
|
|
323
|
-
*
|
|
324
|
-
* Result.bind("b", ({ a }) => Result.ok(a + 1))
|
|
325
|
-
* ); // Ok({ a: 1, b: 2 })
|
|
135
|
+
* const exact = pipe(byName, Equality.and(byRole));
|
|
136
|
+
* exact(userA, userB); // true only if name AND role match
|
|
326
137
|
* ```
|
|
327
138
|
*/
|
|
328
|
-
const
|
|
139
|
+
const and: <A>(eq2: Equality<A>) => (eq1: Equality<A>) => Equality<A>;
|
|
329
140
|
}
|
|
330
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
|
+
|
|
331
196
|
type Some<A> = WithKind<"Some"> & WithValue<A>;
|
|
332
197
|
type None = WithKind<"None">;
|
|
333
198
|
/**
|
|
@@ -540,246 +405,407 @@ declare namespace Maybe {
|
|
|
540
405
|
* ); // Some(8)
|
|
541
406
|
* ```
|
|
542
407
|
*/
|
|
543
|
-
const ap: <A>(arg: Maybe<A>) => <B>(data: Maybe<(a: A) => B>) => Maybe<B>;
|
|
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>;
|
|
544
584
|
/**
|
|
545
|
-
*
|
|
546
|
-
* Initiates the pipeline accumulator record.
|
|
585
|
+
* Transforms the error value inside a Result.
|
|
547
586
|
*
|
|
548
587
|
* @example
|
|
549
588
|
* ```ts
|
|
550
|
-
* pipe(
|
|
589
|
+
* pipe(Result.err("oops"), Result.mapError(e => e.toUpperCase())); // Err("OOPS")
|
|
551
590
|
* ```
|
|
552
591
|
*/
|
|
553
|
-
const
|
|
592
|
+
const mapError: <E, F, A>(f: (e: E) => F) => (data: Result<E, A>) => Result<F, A>;
|
|
554
593
|
/**
|
|
555
|
-
*
|
|
594
|
+
* Chains Result computations. If the first is Ok, passes the value to f.
|
|
595
|
+
* If the first is Err, propagates the error.
|
|
556
596
|
*
|
|
557
597
|
* @example
|
|
558
598
|
* ```ts
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
562
|
-
* ); //
|
|
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")
|
|
563
604
|
* ```
|
|
564
605
|
*/
|
|
565
|
-
const
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
declare const _deferred: unique symbol;
|
|
569
|
-
/**
|
|
570
|
-
* A nominally typed, one-shot async value that supports `await` but enforces infallibility.
|
|
571
|
-
*
|
|
572
|
-
* Two design choices work together to make the guarantee structural rather than documentary:
|
|
573
|
-
*
|
|
574
|
-
* - The phantom `[_deferred]` symbol makes the type **nominal**: only values produced by
|
|
575
|
-
* `Deferred.fromPromise` satisfy it. A plain object `{ then: ... }` does not.
|
|
576
|
-
* - The single-parameter `.then()` **excludes rejection handlers** by construction. There is
|
|
577
|
-
* no second argument to pass, so chaining and `.catch()` are impossible.
|
|
578
|
-
*
|
|
579
|
-
* This makes `Deferred<A>` the natural return type for `Task<A>`, which is guaranteed to
|
|
580
|
-
* never reject.
|
|
581
|
-
*
|
|
582
|
-
* @example
|
|
583
|
-
* ```ts
|
|
584
|
-
* const value = await Deferred.fromPromise(Promise.resolve(42));
|
|
585
|
-
* // value === 42
|
|
586
|
-
* ```
|
|
587
|
-
*/
|
|
588
|
-
type Deferred<A> = {
|
|
589
|
-
readonly [_deferred]: A;
|
|
590
|
-
readonly then: (onfulfilled: (value: A) => unknown) => void;
|
|
591
|
-
};
|
|
592
|
-
declare namespace Deferred {
|
|
606
|
+
const chain: <E, A, B>(f: (a: A) => Result<E, B>) => (data: Result<E, A>) => Result<E, B>;
|
|
593
607
|
/**
|
|
594
|
-
*
|
|
595
|
-
* `.catch()`, `.finally()`, and chainable `.then()`.
|
|
596
|
-
*
|
|
597
|
-
* **Precondition**: `p` must never reject. If `p` rejects, the returned `Deferred` will
|
|
598
|
-
* never resolve — `await`-ing it will hang indefinitely. Use `TaskResult.tryCatch` to
|
|
599
|
-
* handle operations that may fail before converting to a `Deferred`.
|
|
608
|
+
* Extracts the value from a Result by providing handlers for both cases.
|
|
600
609
|
*
|
|
601
610
|
* @example
|
|
602
611
|
* ```ts
|
|
603
|
-
*
|
|
604
|
-
*
|
|
612
|
+
* pipe(
|
|
613
|
+
* Result.ok(5),
|
|
614
|
+
* Result.fold(
|
|
615
|
+
* e => `Error: ${e}`,
|
|
616
|
+
* n => `Value: ${n}`
|
|
617
|
+
* )
|
|
618
|
+
* ); // "Value: 5"
|
|
605
619
|
* ```
|
|
606
620
|
*/
|
|
607
|
-
const
|
|
621
|
+
const fold: <E, A, B>(onErr: (e: E) => B, onOk: (a: A) => B) => (data: Result<E, A>) => B;
|
|
608
622
|
/**
|
|
609
|
-
*
|
|
623
|
+
* Pattern matches on a Result, returning the result of the matching case.
|
|
610
624
|
*
|
|
611
625
|
* @example
|
|
612
626
|
* ```ts
|
|
613
|
-
*
|
|
614
|
-
*
|
|
627
|
+
* pipe(
|
|
628
|
+
* result,
|
|
629
|
+
* Result.match({
|
|
630
|
+
* ok: value => `Got ${value}`,
|
|
631
|
+
* err: error => `Failed: ${error}`
|
|
632
|
+
* })
|
|
633
|
+
* );
|
|
615
634
|
* ```
|
|
616
635
|
*/
|
|
617
|
-
const
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
* A function that checks whether two values of type `A` are equal.
|
|
622
|
-
* Use built-in instances (`Equality.string`, `Equality.number`, etc.) as starting points,
|
|
623
|
-
* then adapt them with `Equality.by` and combine them with `Equality.and`.
|
|
624
|
-
*
|
|
625
|
-
* @example
|
|
626
|
-
* ```ts
|
|
627
|
-
* type User = { id: string; name: string };
|
|
628
|
-
* const byId = pipe(Equality.string, Equality.by((u: User) => u.id));
|
|
629
|
-
*
|
|
630
|
-
* pipe(users, Arr.uniqWith(byId));
|
|
631
|
-
* ```
|
|
632
|
-
*/
|
|
633
|
-
type Equality<A> = (a: A, b: A) => boolean;
|
|
634
|
-
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;
|
|
635
640
|
/**
|
|
636
|
-
*
|
|
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`.
|
|
637
644
|
*
|
|
638
645
|
* @example
|
|
639
646
|
* ```ts
|
|
640
|
-
*
|
|
641
|
-
*
|
|
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
|
|
642
650
|
* ```
|
|
643
651
|
*/
|
|
644
|
-
const
|
|
652
|
+
const getOrElse: <E, A, B>(defaultValue: () => B) => (data: Result<E, A>) => A | B;
|
|
645
653
|
/**
|
|
646
|
-
*
|
|
654
|
+
* Executes a side effect on the success value without changing the Result.
|
|
655
|
+
* Useful for logging or debugging.
|
|
647
656
|
*
|
|
648
657
|
* @example
|
|
649
658
|
* ```ts
|
|
650
|
-
*
|
|
659
|
+
* pipe(
|
|
660
|
+
* Result.ok(5),
|
|
661
|
+
* Result.tap(n => console.log("Value:", n)),
|
|
662
|
+
* Result.map(n => n * 2)
|
|
663
|
+
* );
|
|
651
664
|
* ```
|
|
652
665
|
*/
|
|
653
|
-
const
|
|
666
|
+
const tap: <E, A>(f: (a: A) => void) => (data: Result<E, A>) => Result<E, A>;
|
|
654
667
|
/**
|
|
655
|
-
*
|
|
668
|
+
* Executes a side effect on the error value without changing the Result.
|
|
669
|
+
* Useful for logging or reporting errors.
|
|
656
670
|
*
|
|
657
671
|
* @example
|
|
658
672
|
* ```ts
|
|
659
|
-
*
|
|
673
|
+
* pipe(
|
|
674
|
+
* Result.err("not found"),
|
|
675
|
+
* Result.tapError(e => console.error("validation failed:", e)),
|
|
676
|
+
* Result.chain(save),
|
|
677
|
+
* )
|
|
660
678
|
* ```
|
|
661
679
|
*/
|
|
662
|
-
const
|
|
680
|
+
const tapError: <E, A>(f: (e: E) => void) => (data: Result<E, A>) => Result<E, A>;
|
|
663
681
|
/**
|
|
664
|
-
*
|
|
682
|
+
* Creates a Result from a predicate applied to a value.
|
|
683
|
+
* Returns Ok if the predicate passes, Err from onFalse otherwise.
|
|
665
684
|
*
|
|
666
685
|
* @example
|
|
667
686
|
* ```ts
|
|
668
|
-
*
|
|
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")
|
|
669
690
|
* ```
|
|
670
691
|
*/
|
|
671
|
-
const
|
|
692
|
+
const fromPredicate: <E, A>(pred: (a: A) => boolean, onFalse: (a: A) => E) => (a: A) => Result<E, A>;
|
|
672
693
|
/**
|
|
673
|
-
*
|
|
674
|
-
*
|
|
694
|
+
* Creates a Result from a nullable value.
|
|
695
|
+
* Returns Ok if the value is not null or undefined, error from onNull otherwise.
|
|
675
696
|
*
|
|
676
697
|
* @example
|
|
677
698
|
* ```ts
|
|
678
|
-
*
|
|
699
|
+
* pipe(null, Result.fromNullable(() => "is null")); // Err("is null")
|
|
700
|
+
* pipe(42, Result.fromNullable(() => "is null")); // Ok(42)
|
|
679
701
|
* ```
|
|
680
702
|
*/
|
|
681
|
-
const
|
|
703
|
+
const fromNullable: <E>(onNull: () => E) => <A>(value: A | null | undefined) => Result<E, A>;
|
|
682
704
|
/**
|
|
683
|
-
*
|
|
684
|
-
*
|
|
705
|
+
* Creates a Result from a Maybe.
|
|
706
|
+
* Some becomes Ok, None becomes error from onNone.
|
|
685
707
|
*
|
|
686
708
|
* @example
|
|
687
709
|
* ```ts
|
|
688
|
-
*
|
|
689
|
-
*
|
|
690
|
-
* 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)
|
|
691
712
|
* ```
|
|
692
713
|
*/
|
|
693
|
-
const
|
|
714
|
+
const fromMaybe: <E>(onNone: () => E) => <A>(maybe: Maybe<A>) => Result<E, A>;
|
|
694
715
|
/**
|
|
695
|
-
*
|
|
696
|
-
*
|
|
716
|
+
* Wraps a throwing function of any arguments, returning a new function
|
|
717
|
+
* that catches errors and returns a Result.
|
|
697
718
|
*
|
|
698
719
|
* @example
|
|
699
720
|
* ```ts
|
|
700
|
-
* const
|
|
701
|
-
*
|
|
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)
|
|
702
728
|
* ```
|
|
703
729
|
*/
|
|
704
|
-
const
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
/**
|
|
708
|
-
* A function that orders two values of type `A`. Returns a negative number when `a` comes before
|
|
709
|
-
* `b`, a positive number when `a` comes after `b`, and `0` when they are equal.
|
|
710
|
-
*
|
|
711
|
-
* Compatible with `Array.prototype.sort` and `Arr.sortWith`.
|
|
712
|
-
*
|
|
713
|
-
* @example
|
|
714
|
-
* ```ts
|
|
715
|
-
* type Employee = { name: string; salary: number };
|
|
716
|
-
*
|
|
717
|
-
* const byName = pipe(Ordering.string, Ordering.by((e: Employee) => e.name));
|
|
718
|
-
* const bySalary = pipe(Ordering.number, Ordering.by((e: Employee) => e.salary));
|
|
719
|
-
*
|
|
720
|
-
* pipe(employees, Arr.sortWith(pipe(byName, Ordering.thenBy(bySalary))));
|
|
721
|
-
* ```
|
|
722
|
-
*/
|
|
723
|
-
type Ordering<A> = (a: A, b: A) => number;
|
|
724
|
-
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>;
|
|
725
731
|
/**
|
|
726
|
-
*
|
|
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>`.
|
|
727
739
|
*
|
|
728
740
|
* @example
|
|
729
741
|
* ```ts
|
|
730
|
-
*
|
|
742
|
+
* pipe(
|
|
743
|
+
* Result.err(new Error("not found")),
|
|
744
|
+
* Result.recoverUnless(e => e.message === "fatal", () => Result.ok(0))
|
|
745
|
+
* ); // Ok(0)
|
|
731
746
|
* ```
|
|
732
747
|
*/
|
|
733
|
-
const
|
|
748
|
+
const recoverUnless: <E, A, B>(isBlocked: (e: E) => boolean, fallback: () => Result<E, B>) => (data: Result<E, A>) => Result<E, A | B>;
|
|
734
749
|
/**
|
|
735
|
-
*
|
|
750
|
+
* Converts a Result to a Maybe.
|
|
751
|
+
* Ok becomes Some, Err becomes None (the error is discarded).
|
|
736
752
|
*
|
|
737
753
|
* @example
|
|
738
754
|
* ```ts
|
|
739
|
-
*
|
|
755
|
+
* Result.toMaybe(Result.ok(42)); // Some(42)
|
|
756
|
+
* Result.toMaybe(Result.err("oops")); // None
|
|
740
757
|
* ```
|
|
741
758
|
*/
|
|
742
|
-
const
|
|
759
|
+
const toMaybe: <E, A>(data: Result<E, A>) => Maybe<A>;
|
|
743
760
|
/**
|
|
744
|
-
*
|
|
761
|
+
* Applies a function wrapped in a Result to a value wrapped in a Result.
|
|
745
762
|
*
|
|
746
763
|
* @example
|
|
747
764
|
* ```ts
|
|
748
|
-
*
|
|
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)
|
|
749
771
|
* ```
|
|
750
772
|
*/
|
|
751
|
-
const
|
|
773
|
+
const ap: <E, A>(arg: Result<E, A>) => <B>(data: Result<E, (a: A) => B>) => Result<E, B>;
|
|
752
774
|
/**
|
|
753
|
-
*
|
|
775
|
+
* Converts a Result value into an object containing a single property.
|
|
776
|
+
* Initiates the pipeline accumulator record.
|
|
754
777
|
*
|
|
755
778
|
* @example
|
|
756
779
|
* ```ts
|
|
757
|
-
* pipe(
|
|
780
|
+
* pipe(Result.ok(42), Result.bindTo("value")); // Ok({ value: 42 })
|
|
758
781
|
* ```
|
|
759
782
|
*/
|
|
760
|
-
const
|
|
783
|
+
const bindTo: <K extends string>(key: K) => <E, A>(data: Result<E, A>) => Result<E, { [P in K]: A; }>;
|
|
761
784
|
/**
|
|
762
|
-
*
|
|
763
|
-
* 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.
|
|
764
786
|
*
|
|
765
787
|
* @example
|
|
766
788
|
* ```ts
|
|
767
|
-
*
|
|
789
|
+
* pipe(
|
|
790
|
+
* Result.ok({ a: 1 }),
|
|
791
|
+
* Result.bind("b", ({ a }) => Result.ok(a + 1))
|
|
792
|
+
* ); // Ok({ a: 1, b: 2 })
|
|
768
793
|
* ```
|
|
769
794
|
*/
|
|
770
|
-
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; }>;
|
|
771
796
|
/**
|
|
772
|
-
*
|
|
773
|
-
*
|
|
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.
|
|
774
799
|
*
|
|
775
800
|
* @example
|
|
776
801
|
* ```ts
|
|
777
|
-
*
|
|
778
|
-
*
|
|
779
|
-
*
|
|
802
|
+
* Result.struct({
|
|
803
|
+
* name: Result.ok("Alice"),
|
|
804
|
+
* age: Result.ok(30)
|
|
805
|
+
* }); // Ok({ name: "Alice", age: 30 })
|
|
780
806
|
* ```
|
|
781
807
|
*/
|
|
782
|
-
const
|
|
808
|
+
const struct: <E, R extends Record<string, any>>(fields: { [K in keyof R]: Result<E, R[K]>; }) => Result<E, R>;
|
|
783
809
|
}
|
|
784
810
|
|
|
785
811
|
/**
|