@backendkit-labs/result 0.1.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 +1121 -0
- package/dist/index.cjs +340 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +281 -0
- package/dist/index.d.ts +281 -0
- package/dist/index.js +298 -0
- package/dist/index.js.map +1 -0
- package/dist/nestjs/index.cjs +117 -0
- package/dist/nestjs/index.cjs.map +1 -0
- package/dist/nestjs/index.d.cts +61 -0
- package/dist/nestjs/index.d.ts +61 -0
- package/dist/nestjs/index.js +114 -0
- package/dist/nestjs/index.js.map +1 -0
- package/dist/types-b-fNbJBy.d.cts +33 -0
- package/dist/types-b-fNbJBy.d.ts +33 -0
- package/package.json +70 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { R as Result, a as RichResult, T as TrackOptions } from './types-b-fNbJBy.cjs';
|
|
2
|
+
|
|
3
|
+
/** Creates a successful Result. */
|
|
4
|
+
declare const ok: <T, E = never>(value: T) => Result<T, E>;
|
|
5
|
+
/** Creates a failed Result. */
|
|
6
|
+
declare const fail: <T = never, E = Error>(error: E) => Result<T, E>;
|
|
7
|
+
/**
|
|
8
|
+
* Wraps a synchronous throwable function. Catches any thrown value and
|
|
9
|
+
* passes it through `errorTransform` (defaults to identity cast).
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const result = fromThrowable(() => JSON.parse(raw), (e) => new ParseError(e));
|
|
13
|
+
*/
|
|
14
|
+
declare function fromThrowable<T, E = Error>(fn: () => T, errorTransform?: (caught: unknown) => E): Result<T, E>;
|
|
15
|
+
/**
|
|
16
|
+
* Converts a Promise to a `Promise<Result<T, E>>`, catching rejections.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const result = await fromPromise(fetch(url), (e) => new NetworkError(e));
|
|
20
|
+
*/
|
|
21
|
+
declare function fromPromise<T, E = Error>(promise: Promise<T>, errorTransform?: (caught: unknown) => E): Promise<Result<T, E>>;
|
|
22
|
+
/**
|
|
23
|
+
* Converts a nullable value to a Result.
|
|
24
|
+
* Returns `ok(value)` if non-null/undefined, `fail(error)` otherwise.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const result = fromNullable(user, new NotFoundError('user'));
|
|
28
|
+
*/
|
|
29
|
+
declare function fromNullable<T, E>(value: T | null | undefined, error: E): Result<T, E>;
|
|
30
|
+
|
|
31
|
+
type OkResult<T, E> = Extract<Result<T, E>, {
|
|
32
|
+
ok: true;
|
|
33
|
+
}>;
|
|
34
|
+
type FailResult<T, E> = Extract<Result<T, E>, {
|
|
35
|
+
ok: false;
|
|
36
|
+
}>;
|
|
37
|
+
/** Narrows a `Result<T, E>` to its success branch. */
|
|
38
|
+
declare function isOk<T, E>(result: Result<T, E>): result is OkResult<T, E>;
|
|
39
|
+
/** Narrows a `Result<T, E>` to its failure branch. */
|
|
40
|
+
declare function isFail<T, E>(result: Result<T, E>): result is FailResult<T, E>;
|
|
41
|
+
/** Returns `true` if the result carries observability metadata (`track()` output). */
|
|
42
|
+
declare function isRich<T, E>(result: Result<T, E>): result is RichResult<T, E>;
|
|
43
|
+
|
|
44
|
+
/** Maps the success value. Passes failures through unchanged. */
|
|
45
|
+
declare function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;
|
|
46
|
+
/** Maps the error value. Passes successes through unchanged. */
|
|
47
|
+
declare function mapError<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;
|
|
48
|
+
/** Monadic bind — chains a Result-returning function on success. */
|
|
49
|
+
declare function flatMap<T, U, E>(result: Result<T, E>, fn: (value: T) => Result<U, E>): Result<U, E>;
|
|
50
|
+
/** Async variant of `flatMap`. */
|
|
51
|
+
declare function flatMapAsync<T, U, E>(result: Result<T, E>, fn: (value: T) => Promise<Result<U, E>>): Promise<Result<U, E>>;
|
|
52
|
+
/** Async variant of `map`. */
|
|
53
|
+
declare function mapAsync<T, U, E>(result: Result<T, E>, fn: (value: T) => Promise<U>): Promise<Result<U, E>>;
|
|
54
|
+
/**
|
|
55
|
+
* Exhaustive pattern match over both branches.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const msg = match(result, {
|
|
59
|
+
* ok: (user) => `Welcome, ${user.name}`,
|
|
60
|
+
* fail: (error) => `Error: ${error.message}`,
|
|
61
|
+
* });
|
|
62
|
+
*/
|
|
63
|
+
declare function match<T, E, R>(result: Result<T, E>, handlers: {
|
|
64
|
+
ok: (value: T) => R;
|
|
65
|
+
fail: (error: E) => R;
|
|
66
|
+
}): R;
|
|
67
|
+
/** Alias for `match` — familiar to fp-ts / Scala users. */
|
|
68
|
+
declare const fold: typeof match;
|
|
69
|
+
/** Runs a side effect on the success value; returns the result unchanged. */
|
|
70
|
+
declare function tap<T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E>;
|
|
71
|
+
/** Runs a side effect on the error value; returns the result unchanged. */
|
|
72
|
+
declare function tapError<T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E>;
|
|
73
|
+
/** Extracts the value or throws the error (re-thrown as-is if it's an Error, wrapped otherwise). */
|
|
74
|
+
declare function unwrap<T, E>(result: Result<T, E>): T;
|
|
75
|
+
/** Extracts the error or throws if the result is Ok. */
|
|
76
|
+
declare function unwrapError<T, E>(result: Result<T, E>): E;
|
|
77
|
+
/** Extracts the value or returns `defaultValue` on failure. */
|
|
78
|
+
declare function unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T;
|
|
79
|
+
/** Extracts the value or computes a fallback from the error. */
|
|
80
|
+
declare function unwrapOrElse<T, E>(result: Result<T, E>, fn: (error: E) => T): T;
|
|
81
|
+
/** Extracts the value or throws with a custom `message`. */
|
|
82
|
+
declare function expect<T, E>(result: Result<T, E>, message: string): T;
|
|
83
|
+
/** Converts to a Promise — resolves on Ok, rejects on Fail. */
|
|
84
|
+
declare function toPromise<T, E>(result: Result<T, E>): Promise<T>;
|
|
85
|
+
/** Returns the value or `null` on failure. */
|
|
86
|
+
declare function toNullable<T, E>(result: Result<T, E>): T | null;
|
|
87
|
+
/** Returns the value or `undefined` on failure. */
|
|
88
|
+
declare function toUndefined<T, E>(result: Result<T, E>): T | undefined;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Executes an async (or sync) function and captures any thrown exception,
|
|
92
|
+
* returning a `Result<T, E>` instead of propagating the error.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* const result = await run(() => fetchUser(id));
|
|
96
|
+
* const result = await run(() => fetchUser(id), (e) => new UserError(e));
|
|
97
|
+
*/
|
|
98
|
+
declare function run<T, E = Error>(fn: () => T | Promise<T>, errorTransform?: (caught: unknown) => E): Promise<Result<T, E>>;
|
|
99
|
+
/**
|
|
100
|
+
* Like `run()` but also captures timing and metadata, returning a `RichResult<T, E>`.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* const result = await track(() => fetchUser(id), { operation: 'user.fetch', tags: ['db'] });
|
|
104
|
+
*/
|
|
105
|
+
declare function track<T, E = Error>(fn: () => T | Promise<T>, options?: TrackOptions & {
|
|
106
|
+
errorTransform?: (caught: unknown) => E;
|
|
107
|
+
}): Promise<RichResult<T, E>>;
|
|
108
|
+
/**
|
|
109
|
+
* Promotes a plain `Result<T, E>` to a `RichResult<T, E>` with a zero-duration snapshot.
|
|
110
|
+
* Useful when you already have a Result and want to attach metadata.
|
|
111
|
+
*/
|
|
112
|
+
declare function enrich<T, E>(result: Result<T, E>, options?: TrackOptions): RichResult<T, E>;
|
|
113
|
+
/**
|
|
114
|
+
* Strips observability metadata from a `RichResult`, returning a plain `Result<T, E>`.
|
|
115
|
+
*/
|
|
116
|
+
declare function simplify<T, E>(rich: RichResult<T, E>): Result<T, E>;
|
|
117
|
+
|
|
118
|
+
interface RetryOptions<E> {
|
|
119
|
+
/** Maximum number of attempts (including the first). */
|
|
120
|
+
attempts: number;
|
|
121
|
+
/** Fixed delay in ms between attempts. Default: 0 */
|
|
122
|
+
delayMs?: number;
|
|
123
|
+
/** Return false to stop retrying early based on the error. */
|
|
124
|
+
shouldRetry?: (error: E, attempt: number) => boolean;
|
|
125
|
+
/** Called before each retry with the previous error and attempt number. */
|
|
126
|
+
onRetry?: (error: E, attempt: number) => void;
|
|
127
|
+
}
|
|
128
|
+
interface BackoffOptions<E> extends RetryOptions<E> {
|
|
129
|
+
/** Cap for the computed backoff delay. Default: 30_000 */
|
|
130
|
+
maxDelayMs?: number;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Retries a Result-returning function up to `options.attempts` times with
|
|
134
|
+
* an optional fixed delay between attempts.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* const result = await retry(() => run(() => callApi()), {
|
|
138
|
+
* attempts: 3,
|
|
139
|
+
* delayMs: 500,
|
|
140
|
+
* shouldRetry: (err) => err.code === 'ECONNRESET',
|
|
141
|
+
* });
|
|
142
|
+
*/
|
|
143
|
+
declare function retry<T, E = Error>(fn: () => Promise<Result<T, E>>, options: RetryOptions<E>): Promise<Result<T, E>>;
|
|
144
|
+
/**
|
|
145
|
+
* Like `retry()` but uses exponential backoff: delay doubles on each attempt,
|
|
146
|
+
* capped at `maxDelayMs`.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* const result = await retryWithBackoff(() => run(() => callApi()), {
|
|
150
|
+
* attempts: 4,
|
|
151
|
+
* delayMs: 100, // 100ms → 200ms → 400ms
|
|
152
|
+
* maxDelayMs: 1_000,
|
|
153
|
+
* });
|
|
154
|
+
*/
|
|
155
|
+
declare function retryWithBackoff<T, E = Error>(fn: () => Promise<Result<T, E>>, options: BackoffOptions<E>): Promise<Result<T, E>>;
|
|
156
|
+
/**
|
|
157
|
+
* Races a Result-returning function against a timeout.
|
|
158
|
+
* Returns `fail(timeoutError)` if `ms` elapses before the function resolves.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* const result = await withTimeout(
|
|
162
|
+
* () => run(() => fetchData()),
|
|
163
|
+
* 5_000,
|
|
164
|
+
* new TimeoutError('fetchData timed out'),
|
|
165
|
+
* );
|
|
166
|
+
*/
|
|
167
|
+
declare function withTimeout<T, E>(fn: () => Promise<Result<T, E>>, ms: number, timeoutError: E): Promise<Result<T, E>>;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Returns `ok([...values])` if every result succeeds, or the first `fail` encountered.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* const result = all([findUser(id), findAccount(id)]);
|
|
174
|
+
* // Result<[User, Account], Error>
|
|
175
|
+
*/
|
|
176
|
+
declare function all<T, E>(results: Result<T, E>[]): Result<T[], E>;
|
|
177
|
+
/**
|
|
178
|
+
* Returns the first successful result from a list of async operations,
|
|
179
|
+
* tried sequentially. Returns the last failure if all fail.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* const result = await any([
|
|
183
|
+
* () => run(() => primaryCache.get(key)),
|
|
184
|
+
* () => run(() => database.find(key)),
|
|
185
|
+
* ]);
|
|
186
|
+
*/
|
|
187
|
+
declare function any<T, E>(operations: (() => Promise<Result<T, E>>)[]): Promise<Result<T, E>>;
|
|
188
|
+
interface ParallelOptions {
|
|
189
|
+
/** Max number of operations running concurrently. Default: all at once. */
|
|
190
|
+
concurrency?: number;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Runs operations concurrently (optionally throttled by `concurrency`).
|
|
194
|
+
* Returns `ok([...values])` if all succeed, or the first failure.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* const result = await parallel(
|
|
198
|
+
* userIds.map(id => () => run(() => fetchUser(id))),
|
|
199
|
+
* { concurrency: 5 },
|
|
200
|
+
* );
|
|
201
|
+
*/
|
|
202
|
+
declare function parallel<T, E>(operations: (() => Promise<Result<T, E>>)[], options?: ParallelOptions): Promise<Result<T[], E>>;
|
|
203
|
+
/**
|
|
204
|
+
* Splits an array of Results into `[successValues, errorValues]`.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* const [users, errors] = partition(results);
|
|
208
|
+
*/
|
|
209
|
+
declare function partition<T, E>(results: Result<T, E>[]): [T[], E[]];
|
|
210
|
+
/**
|
|
211
|
+
* Extracts only the success values, silently discarding failures.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* const users = collect(results); // User[]
|
|
215
|
+
*/
|
|
216
|
+
declare function collect<T, E>(results: Result<T, E>[]): T[];
|
|
217
|
+
/**
|
|
218
|
+
* Maps each item through a Result-returning function, collecting all successes
|
|
219
|
+
* into an array or short-circuiting on the first failure.
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* const result = traverse(ids, id => fromNullable(cache.get(id), 'not-found'));
|
|
223
|
+
*/
|
|
224
|
+
declare function traverse<T, U, E>(items: T[], fn: (item: T) => Result<U, E>): Result<U[], E>;
|
|
225
|
+
/** Combines two Results into a tuple. Short-circuits on first failure. */
|
|
226
|
+
declare function combine2<A, B, E>(r1: Result<A, E>, r2: Result<B, E>): Result<[A, B], E>;
|
|
227
|
+
/** Combines three Results into a typed tuple. Short-circuits on first failure. */
|
|
228
|
+
declare function combine3<A, B, C, E>(r1: Result<A, E>, r2: Result<B, E>, r3: Result<C, E>): Result<[A, B, C], E>;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Fluent pipeline wrapper around `Result<T, E>`.
|
|
232
|
+
* Operations short-circuit on failure — subsequent transforms are skipped.
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* const price = Flow.from(findProduct(id))
|
|
236
|
+
* .map(p => p.price)
|
|
237
|
+
* .filter(price => price > 0, new Error('Price must be positive'))
|
|
238
|
+
* .map(price => price * taxRate)
|
|
239
|
+
* .getResult();
|
|
240
|
+
*/
|
|
241
|
+
declare class Flow<T, E = Error> {
|
|
242
|
+
private readonly _result;
|
|
243
|
+
private constructor();
|
|
244
|
+
/** Start a pipeline from an existing Result. */
|
|
245
|
+
static from<T, E>(result: Result<T, E>): Flow<T, E>;
|
|
246
|
+
/** Start an empty pipeline (value is `undefined`). */
|
|
247
|
+
static start(): Flow<void, never>;
|
|
248
|
+
/** Maps the success value. Skipped on failure. */
|
|
249
|
+
map<U>(fn: (value: T) => U): Flow<U, E>;
|
|
250
|
+
/** Maps the error value. Skipped on success. */
|
|
251
|
+
mapError<F>(fn: (error: E) => F): Flow<T, F>;
|
|
252
|
+
/** Chains a Result-returning function. Skipped on failure. */
|
|
253
|
+
flatMap<U>(fn: (value: T) => Result<U, E>): Flow<U, E>;
|
|
254
|
+
/** Filters the success value. Becomes `fail(error)` if predicate is false. */
|
|
255
|
+
filter(pred: (value: T) => boolean, error: E): Flow<T, E>;
|
|
256
|
+
/** Runs a side effect on success; returns `this` unchanged. */
|
|
257
|
+
tap(fn: (value: T) => void): this;
|
|
258
|
+
/** Runs a side effect on failure; returns `this` unchanged. */
|
|
259
|
+
tapError(fn: (error: E) => void): this;
|
|
260
|
+
/**
|
|
261
|
+
* Recovers from a failure by computing a new success value.
|
|
262
|
+
* Skipped if already Ok.
|
|
263
|
+
*/
|
|
264
|
+
recover(fn: (error: E) => T): Flow<T, never>;
|
|
265
|
+
/** Exhaustive pattern match — always produces a value. */
|
|
266
|
+
match<R>(handlers: {
|
|
267
|
+
ok: (value: T) => R;
|
|
268
|
+
fail: (error: E) => R;
|
|
269
|
+
}): R;
|
|
270
|
+
/** Returns the underlying `Result<T, E>`. */
|
|
271
|
+
getResult(): Result<T, E>;
|
|
272
|
+
/**
|
|
273
|
+
* Returns the underlying result as `RichResult<T, E>` if it was created by `track()`.
|
|
274
|
+
* Throws if the result has no observability metadata.
|
|
275
|
+
*/
|
|
276
|
+
getRichResult(): RichResult<T, E>;
|
|
277
|
+
isOk(): boolean;
|
|
278
|
+
isFail(): boolean;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export { type BackoffOptions, Flow, type ParallelOptions, Result, type RetryOptions, RichResult, TrackOptions, all, any, collect, combine2, combine3, enrich, expect, fail, flatMap, flatMapAsync, fold, fromNullable, fromPromise, fromThrowable, isFail, isOk, isRich, map, mapAsync, mapError, match, ok, parallel, partition, retry, retryWithBackoff, run, simplify, tap, tapError, toNullable, toPromise, toUndefined, track, traverse, unwrap, unwrapError, unwrapOr, unwrapOrElse, withTimeout };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { R as Result, a as RichResult, T as TrackOptions } from './types-b-fNbJBy.js';
|
|
2
|
+
|
|
3
|
+
/** Creates a successful Result. */
|
|
4
|
+
declare const ok: <T, E = never>(value: T) => Result<T, E>;
|
|
5
|
+
/** Creates a failed Result. */
|
|
6
|
+
declare const fail: <T = never, E = Error>(error: E) => Result<T, E>;
|
|
7
|
+
/**
|
|
8
|
+
* Wraps a synchronous throwable function. Catches any thrown value and
|
|
9
|
+
* passes it through `errorTransform` (defaults to identity cast).
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const result = fromThrowable(() => JSON.parse(raw), (e) => new ParseError(e));
|
|
13
|
+
*/
|
|
14
|
+
declare function fromThrowable<T, E = Error>(fn: () => T, errorTransform?: (caught: unknown) => E): Result<T, E>;
|
|
15
|
+
/**
|
|
16
|
+
* Converts a Promise to a `Promise<Result<T, E>>`, catching rejections.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const result = await fromPromise(fetch(url), (e) => new NetworkError(e));
|
|
20
|
+
*/
|
|
21
|
+
declare function fromPromise<T, E = Error>(promise: Promise<T>, errorTransform?: (caught: unknown) => E): Promise<Result<T, E>>;
|
|
22
|
+
/**
|
|
23
|
+
* Converts a nullable value to a Result.
|
|
24
|
+
* Returns `ok(value)` if non-null/undefined, `fail(error)` otherwise.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const result = fromNullable(user, new NotFoundError('user'));
|
|
28
|
+
*/
|
|
29
|
+
declare function fromNullable<T, E>(value: T | null | undefined, error: E): Result<T, E>;
|
|
30
|
+
|
|
31
|
+
type OkResult<T, E> = Extract<Result<T, E>, {
|
|
32
|
+
ok: true;
|
|
33
|
+
}>;
|
|
34
|
+
type FailResult<T, E> = Extract<Result<T, E>, {
|
|
35
|
+
ok: false;
|
|
36
|
+
}>;
|
|
37
|
+
/** Narrows a `Result<T, E>` to its success branch. */
|
|
38
|
+
declare function isOk<T, E>(result: Result<T, E>): result is OkResult<T, E>;
|
|
39
|
+
/** Narrows a `Result<T, E>` to its failure branch. */
|
|
40
|
+
declare function isFail<T, E>(result: Result<T, E>): result is FailResult<T, E>;
|
|
41
|
+
/** Returns `true` if the result carries observability metadata (`track()` output). */
|
|
42
|
+
declare function isRich<T, E>(result: Result<T, E>): result is RichResult<T, E>;
|
|
43
|
+
|
|
44
|
+
/** Maps the success value. Passes failures through unchanged. */
|
|
45
|
+
declare function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;
|
|
46
|
+
/** Maps the error value. Passes successes through unchanged. */
|
|
47
|
+
declare function mapError<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;
|
|
48
|
+
/** Monadic bind — chains a Result-returning function on success. */
|
|
49
|
+
declare function flatMap<T, U, E>(result: Result<T, E>, fn: (value: T) => Result<U, E>): Result<U, E>;
|
|
50
|
+
/** Async variant of `flatMap`. */
|
|
51
|
+
declare function flatMapAsync<T, U, E>(result: Result<T, E>, fn: (value: T) => Promise<Result<U, E>>): Promise<Result<U, E>>;
|
|
52
|
+
/** Async variant of `map`. */
|
|
53
|
+
declare function mapAsync<T, U, E>(result: Result<T, E>, fn: (value: T) => Promise<U>): Promise<Result<U, E>>;
|
|
54
|
+
/**
|
|
55
|
+
* Exhaustive pattern match over both branches.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const msg = match(result, {
|
|
59
|
+
* ok: (user) => `Welcome, ${user.name}`,
|
|
60
|
+
* fail: (error) => `Error: ${error.message}`,
|
|
61
|
+
* });
|
|
62
|
+
*/
|
|
63
|
+
declare function match<T, E, R>(result: Result<T, E>, handlers: {
|
|
64
|
+
ok: (value: T) => R;
|
|
65
|
+
fail: (error: E) => R;
|
|
66
|
+
}): R;
|
|
67
|
+
/** Alias for `match` — familiar to fp-ts / Scala users. */
|
|
68
|
+
declare const fold: typeof match;
|
|
69
|
+
/** Runs a side effect on the success value; returns the result unchanged. */
|
|
70
|
+
declare function tap<T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E>;
|
|
71
|
+
/** Runs a side effect on the error value; returns the result unchanged. */
|
|
72
|
+
declare function tapError<T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E>;
|
|
73
|
+
/** Extracts the value or throws the error (re-thrown as-is if it's an Error, wrapped otherwise). */
|
|
74
|
+
declare function unwrap<T, E>(result: Result<T, E>): T;
|
|
75
|
+
/** Extracts the error or throws if the result is Ok. */
|
|
76
|
+
declare function unwrapError<T, E>(result: Result<T, E>): E;
|
|
77
|
+
/** Extracts the value or returns `defaultValue` on failure. */
|
|
78
|
+
declare function unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T;
|
|
79
|
+
/** Extracts the value or computes a fallback from the error. */
|
|
80
|
+
declare function unwrapOrElse<T, E>(result: Result<T, E>, fn: (error: E) => T): T;
|
|
81
|
+
/** Extracts the value or throws with a custom `message`. */
|
|
82
|
+
declare function expect<T, E>(result: Result<T, E>, message: string): T;
|
|
83
|
+
/** Converts to a Promise — resolves on Ok, rejects on Fail. */
|
|
84
|
+
declare function toPromise<T, E>(result: Result<T, E>): Promise<T>;
|
|
85
|
+
/** Returns the value or `null` on failure. */
|
|
86
|
+
declare function toNullable<T, E>(result: Result<T, E>): T | null;
|
|
87
|
+
/** Returns the value or `undefined` on failure. */
|
|
88
|
+
declare function toUndefined<T, E>(result: Result<T, E>): T | undefined;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Executes an async (or sync) function and captures any thrown exception,
|
|
92
|
+
* returning a `Result<T, E>` instead of propagating the error.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* const result = await run(() => fetchUser(id));
|
|
96
|
+
* const result = await run(() => fetchUser(id), (e) => new UserError(e));
|
|
97
|
+
*/
|
|
98
|
+
declare function run<T, E = Error>(fn: () => T | Promise<T>, errorTransform?: (caught: unknown) => E): Promise<Result<T, E>>;
|
|
99
|
+
/**
|
|
100
|
+
* Like `run()` but also captures timing and metadata, returning a `RichResult<T, E>`.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* const result = await track(() => fetchUser(id), { operation: 'user.fetch', tags: ['db'] });
|
|
104
|
+
*/
|
|
105
|
+
declare function track<T, E = Error>(fn: () => T | Promise<T>, options?: TrackOptions & {
|
|
106
|
+
errorTransform?: (caught: unknown) => E;
|
|
107
|
+
}): Promise<RichResult<T, E>>;
|
|
108
|
+
/**
|
|
109
|
+
* Promotes a plain `Result<T, E>` to a `RichResult<T, E>` with a zero-duration snapshot.
|
|
110
|
+
* Useful when you already have a Result and want to attach metadata.
|
|
111
|
+
*/
|
|
112
|
+
declare function enrich<T, E>(result: Result<T, E>, options?: TrackOptions): RichResult<T, E>;
|
|
113
|
+
/**
|
|
114
|
+
* Strips observability metadata from a `RichResult`, returning a plain `Result<T, E>`.
|
|
115
|
+
*/
|
|
116
|
+
declare function simplify<T, E>(rich: RichResult<T, E>): Result<T, E>;
|
|
117
|
+
|
|
118
|
+
interface RetryOptions<E> {
|
|
119
|
+
/** Maximum number of attempts (including the first). */
|
|
120
|
+
attempts: number;
|
|
121
|
+
/** Fixed delay in ms between attempts. Default: 0 */
|
|
122
|
+
delayMs?: number;
|
|
123
|
+
/** Return false to stop retrying early based on the error. */
|
|
124
|
+
shouldRetry?: (error: E, attempt: number) => boolean;
|
|
125
|
+
/** Called before each retry with the previous error and attempt number. */
|
|
126
|
+
onRetry?: (error: E, attempt: number) => void;
|
|
127
|
+
}
|
|
128
|
+
interface BackoffOptions<E> extends RetryOptions<E> {
|
|
129
|
+
/** Cap for the computed backoff delay. Default: 30_000 */
|
|
130
|
+
maxDelayMs?: number;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Retries a Result-returning function up to `options.attempts` times with
|
|
134
|
+
* an optional fixed delay between attempts.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* const result = await retry(() => run(() => callApi()), {
|
|
138
|
+
* attempts: 3,
|
|
139
|
+
* delayMs: 500,
|
|
140
|
+
* shouldRetry: (err) => err.code === 'ECONNRESET',
|
|
141
|
+
* });
|
|
142
|
+
*/
|
|
143
|
+
declare function retry<T, E = Error>(fn: () => Promise<Result<T, E>>, options: RetryOptions<E>): Promise<Result<T, E>>;
|
|
144
|
+
/**
|
|
145
|
+
* Like `retry()` but uses exponential backoff: delay doubles on each attempt,
|
|
146
|
+
* capped at `maxDelayMs`.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* const result = await retryWithBackoff(() => run(() => callApi()), {
|
|
150
|
+
* attempts: 4,
|
|
151
|
+
* delayMs: 100, // 100ms → 200ms → 400ms
|
|
152
|
+
* maxDelayMs: 1_000,
|
|
153
|
+
* });
|
|
154
|
+
*/
|
|
155
|
+
declare function retryWithBackoff<T, E = Error>(fn: () => Promise<Result<T, E>>, options: BackoffOptions<E>): Promise<Result<T, E>>;
|
|
156
|
+
/**
|
|
157
|
+
* Races a Result-returning function against a timeout.
|
|
158
|
+
* Returns `fail(timeoutError)` if `ms` elapses before the function resolves.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* const result = await withTimeout(
|
|
162
|
+
* () => run(() => fetchData()),
|
|
163
|
+
* 5_000,
|
|
164
|
+
* new TimeoutError('fetchData timed out'),
|
|
165
|
+
* );
|
|
166
|
+
*/
|
|
167
|
+
declare function withTimeout<T, E>(fn: () => Promise<Result<T, E>>, ms: number, timeoutError: E): Promise<Result<T, E>>;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Returns `ok([...values])` if every result succeeds, or the first `fail` encountered.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* const result = all([findUser(id), findAccount(id)]);
|
|
174
|
+
* // Result<[User, Account], Error>
|
|
175
|
+
*/
|
|
176
|
+
declare function all<T, E>(results: Result<T, E>[]): Result<T[], E>;
|
|
177
|
+
/**
|
|
178
|
+
* Returns the first successful result from a list of async operations,
|
|
179
|
+
* tried sequentially. Returns the last failure if all fail.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* const result = await any([
|
|
183
|
+
* () => run(() => primaryCache.get(key)),
|
|
184
|
+
* () => run(() => database.find(key)),
|
|
185
|
+
* ]);
|
|
186
|
+
*/
|
|
187
|
+
declare function any<T, E>(operations: (() => Promise<Result<T, E>>)[]): Promise<Result<T, E>>;
|
|
188
|
+
interface ParallelOptions {
|
|
189
|
+
/** Max number of operations running concurrently. Default: all at once. */
|
|
190
|
+
concurrency?: number;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Runs operations concurrently (optionally throttled by `concurrency`).
|
|
194
|
+
* Returns `ok([...values])` if all succeed, or the first failure.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* const result = await parallel(
|
|
198
|
+
* userIds.map(id => () => run(() => fetchUser(id))),
|
|
199
|
+
* { concurrency: 5 },
|
|
200
|
+
* );
|
|
201
|
+
*/
|
|
202
|
+
declare function parallel<T, E>(operations: (() => Promise<Result<T, E>>)[], options?: ParallelOptions): Promise<Result<T[], E>>;
|
|
203
|
+
/**
|
|
204
|
+
* Splits an array of Results into `[successValues, errorValues]`.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* const [users, errors] = partition(results);
|
|
208
|
+
*/
|
|
209
|
+
declare function partition<T, E>(results: Result<T, E>[]): [T[], E[]];
|
|
210
|
+
/**
|
|
211
|
+
* Extracts only the success values, silently discarding failures.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* const users = collect(results); // User[]
|
|
215
|
+
*/
|
|
216
|
+
declare function collect<T, E>(results: Result<T, E>[]): T[];
|
|
217
|
+
/**
|
|
218
|
+
* Maps each item through a Result-returning function, collecting all successes
|
|
219
|
+
* into an array or short-circuiting on the first failure.
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* const result = traverse(ids, id => fromNullable(cache.get(id), 'not-found'));
|
|
223
|
+
*/
|
|
224
|
+
declare function traverse<T, U, E>(items: T[], fn: (item: T) => Result<U, E>): Result<U[], E>;
|
|
225
|
+
/** Combines two Results into a tuple. Short-circuits on first failure. */
|
|
226
|
+
declare function combine2<A, B, E>(r1: Result<A, E>, r2: Result<B, E>): Result<[A, B], E>;
|
|
227
|
+
/** Combines three Results into a typed tuple. Short-circuits on first failure. */
|
|
228
|
+
declare function combine3<A, B, C, E>(r1: Result<A, E>, r2: Result<B, E>, r3: Result<C, E>): Result<[A, B, C], E>;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Fluent pipeline wrapper around `Result<T, E>`.
|
|
232
|
+
* Operations short-circuit on failure — subsequent transforms are skipped.
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* const price = Flow.from(findProduct(id))
|
|
236
|
+
* .map(p => p.price)
|
|
237
|
+
* .filter(price => price > 0, new Error('Price must be positive'))
|
|
238
|
+
* .map(price => price * taxRate)
|
|
239
|
+
* .getResult();
|
|
240
|
+
*/
|
|
241
|
+
declare class Flow<T, E = Error> {
|
|
242
|
+
private readonly _result;
|
|
243
|
+
private constructor();
|
|
244
|
+
/** Start a pipeline from an existing Result. */
|
|
245
|
+
static from<T, E>(result: Result<T, E>): Flow<T, E>;
|
|
246
|
+
/** Start an empty pipeline (value is `undefined`). */
|
|
247
|
+
static start(): Flow<void, never>;
|
|
248
|
+
/** Maps the success value. Skipped on failure. */
|
|
249
|
+
map<U>(fn: (value: T) => U): Flow<U, E>;
|
|
250
|
+
/** Maps the error value. Skipped on success. */
|
|
251
|
+
mapError<F>(fn: (error: E) => F): Flow<T, F>;
|
|
252
|
+
/** Chains a Result-returning function. Skipped on failure. */
|
|
253
|
+
flatMap<U>(fn: (value: T) => Result<U, E>): Flow<U, E>;
|
|
254
|
+
/** Filters the success value. Becomes `fail(error)` if predicate is false. */
|
|
255
|
+
filter(pred: (value: T) => boolean, error: E): Flow<T, E>;
|
|
256
|
+
/** Runs a side effect on success; returns `this` unchanged. */
|
|
257
|
+
tap(fn: (value: T) => void): this;
|
|
258
|
+
/** Runs a side effect on failure; returns `this` unchanged. */
|
|
259
|
+
tapError(fn: (error: E) => void): this;
|
|
260
|
+
/**
|
|
261
|
+
* Recovers from a failure by computing a new success value.
|
|
262
|
+
* Skipped if already Ok.
|
|
263
|
+
*/
|
|
264
|
+
recover(fn: (error: E) => T): Flow<T, never>;
|
|
265
|
+
/** Exhaustive pattern match — always produces a value. */
|
|
266
|
+
match<R>(handlers: {
|
|
267
|
+
ok: (value: T) => R;
|
|
268
|
+
fail: (error: E) => R;
|
|
269
|
+
}): R;
|
|
270
|
+
/** Returns the underlying `Result<T, E>`. */
|
|
271
|
+
getResult(): Result<T, E>;
|
|
272
|
+
/**
|
|
273
|
+
* Returns the underlying result as `RichResult<T, E>` if it was created by `track()`.
|
|
274
|
+
* Throws if the result has no observability metadata.
|
|
275
|
+
*/
|
|
276
|
+
getRichResult(): RichResult<T, E>;
|
|
277
|
+
isOk(): boolean;
|
|
278
|
+
isFail(): boolean;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export { type BackoffOptions, Flow, type ParallelOptions, Result, type RetryOptions, RichResult, TrackOptions, all, any, collect, combine2, combine3, enrich, expect, fail, flatMap, flatMapAsync, fold, fromNullable, fromPromise, fromThrowable, isFail, isOk, isRich, map, mapAsync, mapError, match, ok, parallel, partition, retry, retryWithBackoff, run, simplify, tap, tapError, toNullable, toPromise, toUndefined, track, traverse, unwrap, unwrapError, unwrapOr, unwrapOrElse, withTimeout };
|