@onrails/result 0.2.0 → 0.3.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/DESIGN.md +11 -18
- package/README.md +14 -59
- package/RECIPES.md +12 -25
- package/dist/{async-1fIhfzFu.d.ts → async-Ci6WSL5-.d.ts} +60 -18
- package/dist/{async-u8U5P2EH.d.cts → async-DcXR7k9K.d.cts} +60 -18
- package/dist/compat/neverthrow.cjs +42 -51
- package/dist/compat/neverthrow.cjs.map +1 -1
- package/dist/compat/neverthrow.d.cts +3 -3
- package/dist/compat/neverthrow.d.ts +3 -3
- package/dist/compat/neverthrow.js +42 -51
- package/dist/compat/neverthrow.js.map +1 -1
- package/dist/extra.cjs +1 -1
- package/dist/extra.cjs.map +1 -1
- package/dist/extra.d.cts +5 -11
- package/dist/extra.d.ts +5 -11
- package/dist/extra.js +1 -1
- package/dist/extra.js.map +1 -1
- package/dist/fluent.cjs +66 -28
- package/dist/fluent.cjs.map +1 -1
- package/dist/fluent.d.cts +41 -6
- package/dist/fluent.d.ts +41 -6
- package/dist/fluent.js +66 -28
- package/dist/fluent.js.map +1 -1
- package/dist/index.cjs +95 -95
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +168 -44
- package/dist/index.d.ts +168 -44
- package/dist/index.js +90 -95
- package/dist/index.js.map +1 -1
- package/dist/railway.cjs +101 -172
- package/dist/railway.cjs.map +1 -1
- package/dist/railway.d.cts +25 -179
- package/dist/railway.d.ts +25 -179
- package/dist/railway.js +102 -162
- package/dist/railway.js.map +1 -1
- package/dist/try-gen.cjs +1 -1
- package/dist/try-gen.cjs.map +1 -1
- package/dist/try-gen.js +1 -1
- package/dist/try-gen.js.map +1 -1
- package/package.json +1 -16
- package/skills/railway-do-notation/SKILL.md +29 -68
- package/skills/result-composition/SKILL.md +2 -4
- package/dist/$.cjs +0 -40
- package/dist/$.cjs.map +0 -1
- package/dist/$.js +0 -36
- package/dist/$.js.map +0 -1
- package/dist/_.d.cts +0 -2
- package/dist/_.d.ts +0 -2
- package/dist/interop.cjs +0 -433
- package/dist/interop.cjs.map +0 -1
- package/dist/interop.d.cts +0 -75
- package/dist/interop.d.ts +0 -75
- package/dist/interop.js +0 -429
- package/dist/interop.js.map +0 -1
- package/dist/validation.cjs +0 -53
- package/dist/validation.cjs.map +0 -1
- package/dist/validation.d.cts +0 -72
- package/dist/validation.d.ts +0 -72
- package/dist/validation.js +0 -48
- package/dist/validation.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import { R as ResultAsync } from './async-
|
|
2
|
-
import { R as Result, E as Err, O as Ok } from './types-BQ9vv0nD.js';
|
|
3
|
-
export { U as UnexpectedError } from './types-BQ9vv0nD.js';
|
|
4
|
-
export { InferErr, InferOk, asyncAfter, fromAsync, fromResult } from './interop.js';
|
|
1
|
+
import { R as ResultAsync, I as InferErr, a as InferOk } from './async-Ci6WSL5-.js';
|
|
2
|
+
import { R as Result, U as UnexpectedError, E as Err, O as Ok } from './types-BQ9vv0nD.js';
|
|
5
3
|
export { flow } from './pipe.js';
|
|
6
4
|
export { $, tryGen, yieldResult } from './try-gen.js';
|
|
7
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @onrails/result — THE lift module. Every "value → {@link ResultAsync}"
|
|
8
|
+
* entry point is defined exactly once, here: `okAsync`, `errAsync`,
|
|
9
|
+
* `fromPromise`, `fromSafePromise`, `fromResult`, `fromAsync`, `asyncAfter`,
|
|
10
|
+
* `tryAsync`.
|
|
11
|
+
*/
|
|
12
|
+
|
|
8
13
|
/**
|
|
9
14
|
* Lifts a value into an `Ok` async result.
|
|
10
15
|
*
|
|
@@ -42,20 +47,49 @@ declare const fromPromise: typeof ResultAsync.fromPromise;
|
|
|
42
47
|
*/
|
|
43
48
|
declare const fromSafePromise: typeof ResultAsync.fromSafePromise;
|
|
44
49
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
50
|
+
* Lifts an already-settled sync {@link Result} into a {@link ResultAsync}, so
|
|
51
|
+
* it can be chained alongside async steps in a railway.
|
|
47
52
|
*
|
|
48
53
|
* @example
|
|
49
54
|
* ```ts
|
|
50
|
-
* const
|
|
51
|
-
*
|
|
52
|
-
* loadMetrics(id),
|
|
53
|
-
* loadFlags(id),
|
|
54
|
-
* ] as const);
|
|
55
|
-
* // ResultAsync<readonly [Profile, Metrics, Flags], …>
|
|
55
|
+
* const ra = fromResult(ok(1)); // ResultAsync<number, never>
|
|
56
|
+
* await fromResult(err(error)).resolve(); // Err(error)
|
|
56
57
|
* ```
|
|
57
58
|
*/
|
|
58
|
-
declare const
|
|
59
|
+
declare const fromResult: typeof ResultAsync.fromResult;
|
|
60
|
+
/**
|
|
61
|
+
* Bind a sync {@link Result} into an async step without widening defects.
|
|
62
|
+
* Dual-form: data-first for one-shots, data-last (curried) for `pipe`/`flow`.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* asyncAfter(result, (u) => tryAsync(db.insert(u), toErr)); // data-first
|
|
67
|
+
* asyncAfter((u) => tryAsync(db.insert(u), toErr)); // data-last
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
declare const asyncAfter: {
|
|
71
|
+
<T, U, E, F>(result: Result<T, E>, fn: (value: T) => ResultAsync<U, F>): ResultAsync<U, E | F>;
|
|
72
|
+
<T, U, F>(fn: (value: T) => ResultAsync<U, F>): <E>(result: Result<T, E>) => ResultAsync<U, E | F>;
|
|
73
|
+
};
|
|
74
|
+
type AnyResult = Result<unknown, unknown>;
|
|
75
|
+
/**
|
|
76
|
+
* Lifts a `(...args) => Promise<Result<T, E>>` function (typical of interop or
|
|
77
|
+
* boundary code) into one returning `(...args) => ResultAsync<T, E>`. Expected
|
|
78
|
+
* `Err`s pass through; an unexpected promise rejection (a defect) is routed via
|
|
79
|
+
* `onDefect`, defaulting to {@link UnexpectedError} and widening the error union.
|
|
80
|
+
*
|
|
81
|
+
* @param fn - a function returning a promise that already yields a `Result`
|
|
82
|
+
* @param onDefect - maps an unexpected rejection to the `Err` channel
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* const loadUser = fromAsync(
|
|
87
|
+
* (id: string): Promise<Result<User, NotFound>> => api.getUser(id),
|
|
88
|
+
* );
|
|
89
|
+
* const ra = loadUser("u1"); // ResultAsync<User, NotFound | UnexpectedError>
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
declare const fromAsync: <A extends readonly unknown[], R extends AnyResult>(fn: (...args: A) => Promise<R>, onDefect?: (error: unknown) => InferErr<R> | UnexpectedError) => ((...args: A) => ResultAsync<InferOk<R>, InferErr<R> | UnexpectedError>);
|
|
59
93
|
/**
|
|
60
94
|
* Convenience wrapper over {@link fromPromise} with default `Error`
|
|
61
95
|
* normalization. Call without `onReject` to get `ResultAsync<T, Error>`,
|
|
@@ -76,6 +110,16 @@ declare const parallelTupleAsync: typeof ResultAsync.combineTupleParallel;
|
|
|
76
110
|
declare function tryAsync<T>(promise: PromiseLike<T>): ResultAsync<T, Error>;
|
|
77
111
|
declare function tryAsync<T, E>(promise: PromiseLike<T>, onReject: (error: unknown) => E): ResultAsync<T, E>;
|
|
78
112
|
|
|
113
|
+
/**
|
|
114
|
+
* @onrails/result — sync aggregation, one module, two axes:
|
|
115
|
+
*
|
|
116
|
+
* short-circuit (first `Err` wins) — {@link combine} / {@link combineTuple}
|
|
117
|
+
* accumulate expected failures — {@link validateAll} / {@link validateTuple}
|
|
118
|
+
*
|
|
119
|
+
* The accumulate pair collects every failure into a readonly array by
|
|
120
|
+
* default, or folds them with an explicit `combineErrors` when given one.
|
|
121
|
+
*/
|
|
122
|
+
|
|
79
123
|
/**
|
|
80
124
|
* Combines a homogeneous array of results into a single result holding an
|
|
81
125
|
* array of the `Ok` values, in input order. Short-circuits on the first `Err`
|
|
@@ -89,6 +133,11 @@ declare function tryAsync<T, E>(promise: PromiseLike<T>, onReject: (error: unkno
|
|
|
89
133
|
* ```
|
|
90
134
|
*/
|
|
91
135
|
declare const combine: <T, E>(results: readonly Result<T, E>[]) => Result<T[], E>;
|
|
136
|
+
type CombineTuple<R extends readonly Result<unknown, unknown>[]> = Result<{
|
|
137
|
+
[K in keyof R]: InferOk<R[K]>;
|
|
138
|
+
}, {
|
|
139
|
+
[K in keyof R]: InferErr<R[K]>;
|
|
140
|
+
}[number]>;
|
|
92
141
|
/**
|
|
93
142
|
* Heterogeneous tuple combine — like {@link combine} but preserves each
|
|
94
143
|
* branch's `Ok` type by position, so the result destructures type-safely.
|
|
@@ -104,19 +153,51 @@ declare const combine: <T, E>(results: readonly Result<T, E>[]) => Result<T[], E
|
|
|
104
153
|
* ```
|
|
105
154
|
*/
|
|
106
155
|
declare const combineTuple: <const R extends readonly Result<unknown, unknown>[]>(results: R) => CombineTuple<R>;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Accumulate independent validation failures. Returns `Ok<T[]>` only when
|
|
158
|
+
* every input is `Ok`. Without a combiner, failures are collected into a
|
|
159
|
+
* readonly array; with `combineErrors` they are folded into a single `E`.
|
|
160
|
+
*
|
|
161
|
+
* Unlike {@link combine}, this does **not** short-circuit on first failure —
|
|
162
|
+
* use for independent checks where you want to report all problems at once.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```ts
|
|
166
|
+
* const checks: Result<string, string[]>[] = [ok("Ada"), err(["age required"])];
|
|
167
|
+
*
|
|
168
|
+
* validateAll(checks);
|
|
169
|
+
* // Result<string[], readonly string[][]>
|
|
170
|
+
*
|
|
171
|
+
* validateAll(checks, (left, right) => [...left, ...right]);
|
|
172
|
+
* // Result<string[], string[]>
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
declare function validateAll<T, E>(results: readonly Result<T, E>[]): Result<T[], readonly E[]>;
|
|
176
|
+
declare function validateAll<T, E>(results: readonly Result<T, E>[], combineErrors: (left: E, right: E) => E): Result<T[], E>;
|
|
177
|
+
/**
|
|
178
|
+
* Tuple-preserving variant of {@link validateAll}. Heterogeneous input tuple
|
|
179
|
+
* → preserved `Ok` tuple shape. Without a combiner, the error union is
|
|
180
|
+
* collected into a readonly array; with `combineErrors`, all inputs must
|
|
181
|
+
* share the error type `E` and failures fold into a single `E`.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* const name: Result<string, string[]> = ok("Ada");
|
|
186
|
+
* const age: Result<number, string[]> = ok(36);
|
|
187
|
+
*
|
|
188
|
+
* validateTuple([name, age] as const);
|
|
189
|
+
* // Result<readonly [string, number], readonly string[][]>
|
|
190
|
+
*
|
|
191
|
+
* validateTuple([name, age] as const, (l, r) => [...l, ...r]);
|
|
192
|
+
* // Result<readonly [string, number], string[]>
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
declare function validateTuple<const R extends readonly Result<unknown, unknown>[]>(results: R): Result<{
|
|
196
|
+
[K in keyof R]: InferOk<R[K]>;
|
|
197
|
+
}, readonly InferErr<R[number]>[]>;
|
|
198
|
+
declare function validateTuple<const R extends readonly Result<unknown, unknown>[], E = InferErr<R[number]>>(results: R & readonly Result<unknown, E>[], combineErrors: (left: E, right: E) => E): Result<{
|
|
199
|
+
[K in keyof R]: InferOk<R[K]>;
|
|
200
|
+
}, E>;
|
|
120
201
|
|
|
121
202
|
/**
|
|
122
203
|
* Lifts a value into the success track.
|
|
@@ -128,6 +209,16 @@ type CombineTuple<R extends readonly Result<unknown, unknown>[]> = Result<{
|
|
|
128
209
|
* ```
|
|
129
210
|
*/
|
|
130
211
|
declare const ok: <T, E = never>(value: T) => Result<T, E>;
|
|
212
|
+
/**
|
|
213
|
+
* Fantasy Land `pure` — alias of {@link ok}. One lift name shared across the
|
|
214
|
+
* trio (`of` / `Maybe.of` / `ResultAsync.of`) for generic and FL-style code.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* const r = of(42); // Result<number, never> — identical to ok(42)
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
declare const of: <T, E = never>(value: T) => Result<T, E>;
|
|
131
222
|
/**
|
|
132
223
|
* Lifts a value into the error track.
|
|
133
224
|
*
|
|
@@ -170,8 +261,10 @@ declare const isErr: <T, E>(result: Result<T, E>) => result is Err<T, E>;
|
|
|
170
261
|
* pipe(ok("x"), map((s) => s.length));// Ok 1 — curried
|
|
171
262
|
* ```
|
|
172
263
|
*/
|
|
173
|
-
declare
|
|
174
|
-
|
|
264
|
+
declare const map: {
|
|
265
|
+
<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;
|
|
266
|
+
<T, U>(fn: (value: T) => U): <E>(result: Result<T, E>) => Result<U, E>;
|
|
267
|
+
};
|
|
175
268
|
/**
|
|
176
269
|
* Transform the `Err` value, passing `Ok` through unchanged. Useful for
|
|
177
270
|
* unifying heterogeneous failure types into one app-level union.
|
|
@@ -185,8 +278,10 @@ declare function map<T, U>(fn: (value: T) => U): <E>(result: Result<T, E>) => Re
|
|
|
185
278
|
* );
|
|
186
279
|
* ```
|
|
187
280
|
*/
|
|
188
|
-
declare
|
|
189
|
-
|
|
281
|
+
declare const mapErr: {
|
|
282
|
+
<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;
|
|
283
|
+
<E, F>(fn: (error: E) => F): <T>(result: Result<T, E>) => Result<T, F>;
|
|
284
|
+
};
|
|
190
285
|
/**
|
|
191
286
|
* Transform both tracks at once — `Ok` via `onOk`, `Err` via `onErr`.
|
|
192
287
|
* Equivalent to `mapErr(onErr)(map(onOk)(result))` but in one pass.
|
|
@@ -196,8 +291,10 @@ declare function mapErr<E, F>(fn: (error: E) => F): <T>(result: Result<T, E>) =>
|
|
|
196
291
|
* bimap(parsed, (cfg) => cfg.name, (e) => ({ kind: "input", cause: e }));
|
|
197
292
|
* ```
|
|
198
293
|
*/
|
|
199
|
-
declare
|
|
200
|
-
|
|
294
|
+
declare const bimap: {
|
|
295
|
+
<T, U, E, F>(result: Result<T, E>, onOk: (value: T) => U, onErr: (error: E) => F): Result<U, F>;
|
|
296
|
+
<T, U, E, F>(onOk: (value: T) => U, onErr: (error: E) => F): (result: Result<T, E>) => Result<U, F>;
|
|
297
|
+
};
|
|
201
298
|
/**
|
|
202
299
|
* Canonical bind (Fantasy Land `chain`). Chains a Result-returning step,
|
|
203
300
|
* widening the error union to `E | F`. Short-circuits on `Err`.
|
|
@@ -210,8 +307,10 @@ declare function bimap<T, U, E, F>(onOk: (value: T) => U, onErr: (error: E) => F
|
|
|
210
307
|
* // Result<Data, ParseError | { kind: "missing_id" }>
|
|
211
308
|
* ```
|
|
212
309
|
*/
|
|
213
|
-
declare
|
|
214
|
-
|
|
310
|
+
declare const flatMap: {
|
|
311
|
+
<T, U, E, F>(result: Result<T, E>, fn: (value: T) => Result<U, F>): Result<U, E | F>;
|
|
312
|
+
<T, U, F>(fn: (value: T) => Result<U, F>): <E>(result: Result<T, E>) => Result<U, E | F>;
|
|
313
|
+
};
|
|
215
314
|
/**
|
|
216
315
|
* Error-track bind — runs `fn` only when the result is `Err`, allowing
|
|
217
316
|
* a failed workflow to recover to `Ok` or remap the failure. Mirror of
|
|
@@ -224,8 +323,10 @@ declare function flatMap<T, U, F>(fn: (value: T) => Result<U, F>): <E>(result: R
|
|
|
224
323
|
* );
|
|
225
324
|
* ```
|
|
226
325
|
*/
|
|
227
|
-
declare
|
|
228
|
-
|
|
326
|
+
declare const recover: {
|
|
327
|
+
<T, E, F>(result: Result<T, E>, fn: (error: E) => Result<T, F>): Result<T, F>;
|
|
328
|
+
<T, E, F>(fn: (error: E) => Result<T, F>): (result: Result<T, E>) => Result<T, F>;
|
|
329
|
+
};
|
|
229
330
|
/**
|
|
230
331
|
* Observe the `Ok` value for side effects (logging, metrics) without
|
|
231
332
|
* changing the carried value. Passes `Err` through untouched.
|
|
@@ -239,8 +340,10 @@ declare function recover<T, E, F>(fn: (error: E) => Result<T, F>): (result: Resu
|
|
|
239
340
|
* );
|
|
240
341
|
* ```
|
|
241
342
|
*/
|
|
242
|
-
declare
|
|
243
|
-
|
|
343
|
+
declare const tap: {
|
|
344
|
+
<T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E>;
|
|
345
|
+
<T>(fn: (value: T) => void): <E>(result: Result<T, E>) => Result<T, E>;
|
|
346
|
+
};
|
|
244
347
|
/**
|
|
245
348
|
* Observe the `Err` value for side effects (logging, metrics) without
|
|
246
349
|
* changing the carried error. Passes `Ok` through untouched.
|
|
@@ -253,8 +356,10 @@ declare function tap<T>(fn: (value: T) => void): <E>(result: Result<T, E>) => Re
|
|
|
253
356
|
* );
|
|
254
357
|
* ```
|
|
255
358
|
*/
|
|
256
|
-
declare
|
|
257
|
-
|
|
359
|
+
declare const tapErr: {
|
|
360
|
+
<T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E>;
|
|
361
|
+
<E>(fn: (error: E) => void): <T>(result: Result<T, E>) => Result<T, E>;
|
|
362
|
+
};
|
|
258
363
|
/**
|
|
259
364
|
* Terminal collapse — fold both tracks into a single value. Dual-form:
|
|
260
365
|
* 3-args data-first, 2-args curried for {@link pipe}. Returns whatever
|
|
@@ -269,8 +374,10 @@ declare function tapErr<E>(fn: (error: E) => void): <T>(result: Result<T, E>) =>
|
|
|
269
374
|
* const html = match(parsed, (cfg) => render(cfg), (e) => renderError(e));
|
|
270
375
|
* ```
|
|
271
376
|
*/
|
|
272
|
-
declare
|
|
273
|
-
|
|
377
|
+
declare const match: {
|
|
378
|
+
<T, E, U>(result: Result<T, E>, onOk: (value: T) => U, onErr: (error: E) => U): U;
|
|
379
|
+
<T, E, U>(onOk: (value: T) => U, onErr: (error: E) => U): (result: Result<T, E>) => U;
|
|
380
|
+
};
|
|
274
381
|
/**
|
|
275
382
|
* Returns the `Ok` value, or `defaultValue` when the result is `Err`.
|
|
276
383
|
*
|
|
@@ -279,7 +386,10 @@ declare function match<T, E, U>(onOk: (value: T) => U, onErr: (error: E) => U):
|
|
|
279
386
|
* unwrapOr(parsedSetting, "default-value");
|
|
280
387
|
* ```
|
|
281
388
|
*/
|
|
282
|
-
declare const unwrapOr:
|
|
389
|
+
declare const unwrapOr: {
|
|
390
|
+
<T, E>(result: Result<T, E>, defaultValue: T): T;
|
|
391
|
+
<T>(defaultValue: T): <E>(result: Result<T, E>) => T;
|
|
392
|
+
};
|
|
283
393
|
/**
|
|
284
394
|
* Test/assert helper — returns the `Ok` value, or **throws the original `Err`
|
|
285
395
|
* value** when called on an `Err`. This is the assertion tier (RFC 0001 §4):
|
|
@@ -298,6 +408,8 @@ declare const unwrapOr: <T, E>(result: Result<T, E>, defaultValue: T) => T;
|
|
|
298
408
|
* ```
|
|
299
409
|
*/
|
|
300
410
|
declare function unwrapOk<T, E>(result: Result<T, E>): T;
|
|
411
|
+
/** Alias of {@link unwrapOk} for syntax cohesion with `@onrails/maybe`. */
|
|
412
|
+
declare const unwrap: typeof unwrapOk;
|
|
301
413
|
/**
|
|
302
414
|
* Test/assert helper — returns the `Err` value, or **throws a `TypeError`**
|
|
303
415
|
* when called on an `Ok`. Mirror of {@link unwrapOk} on the error track and
|
|
@@ -363,5 +475,17 @@ declare function pipe<A, B, C, D, E, F>(value: A, ab: (a: A) => B, bc: (b: B) =>
|
|
|
363
475
|
declare function pipe<A, B, C, D, E, F, G>(value: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G): G;
|
|
364
476
|
declare function pipe<A, B, C, D, E, F, G, H>(value: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H): H;
|
|
365
477
|
declare function pipe<A, B, C, D, E, F, G, H, I>(value: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I): I;
|
|
478
|
+
/**
|
|
479
|
+
* Debug printer — renders a result as `Ok(…)` / `Err(…)` for logs. Payloads
|
|
480
|
+
* print as JSON (values are plain data by design); non-JSON payloads fall
|
|
481
|
+
* back to `String(...)`.
|
|
482
|
+
*
|
|
483
|
+
* @example
|
|
484
|
+
* ```ts
|
|
485
|
+
* show(ok(1)); // 'Ok(1)'
|
|
486
|
+
* show(err({ kind: "e" })); // 'Err({"kind":"e"})'
|
|
487
|
+
* ```
|
|
488
|
+
*/
|
|
489
|
+
declare const show: <T, E>(result: Result<T, E>) => string;
|
|
366
490
|
|
|
367
|
-
export { Err, Ok, Result, ResultAsync, bimap, combine, combineTuple, err, errAsync, flatMap, fromPromise, fromSafePromise, isErr, isOk, map, mapErr, match, ok, okAsync,
|
|
491
|
+
export { Err, InferErr, InferOk, Ok, Result, ResultAsync, UnexpectedError, asyncAfter, bimap, combine, combineTuple, err, errAsync, flatMap, fromAsync, fromPromise, fromResult, fromSafePromise, isErr, isOk, map, mapErr, match, of, ok, okAsync, pipe, recover, show, tap, tapErr, tryAsync, trySync, unwrap, unwrapErr, unwrapOk, unwrapOr, validateAll, validateTuple };
|
package/dist/index.js
CHANGED
|
@@ -1,73 +1,63 @@
|
|
|
1
|
+
// src/internal/dual.ts
|
|
2
|
+
var dual = (arity, body) => {
|
|
3
|
+
const run = body;
|
|
4
|
+
const dispatcher = (...args) => args.length >= arity ? run(...args) : (self) => run(self, ...args);
|
|
5
|
+
return dispatcher;
|
|
6
|
+
};
|
|
7
|
+
|
|
1
8
|
// src/result.ts
|
|
2
9
|
var ok = (value) => ({
|
|
3
10
|
_tag: "Ok",
|
|
4
11
|
value
|
|
5
12
|
});
|
|
13
|
+
var of = ok;
|
|
6
14
|
var err = (error) => ({
|
|
7
15
|
_tag: "Err",
|
|
8
16
|
error
|
|
9
17
|
});
|
|
10
18
|
var isOk = (result) => result._tag === "Ok";
|
|
11
19
|
var isErr = (result) => result._tag === "Err";
|
|
12
|
-
var
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
var
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const fn = args[0];
|
|
34
|
-
return (result) => flatMapImpl(result, fn);
|
|
35
|
-
}
|
|
36
|
-
var recoverImpl = (result, fn) => isErr(result) ? fn(result.error) : ok(result.value);
|
|
37
|
-
function recover(...args) {
|
|
38
|
-
if (args.length === 2) return recoverImpl(args[0], args[1]);
|
|
39
|
-
const fn = args[0];
|
|
40
|
-
return (result) => recoverImpl(result, fn);
|
|
41
|
-
}
|
|
42
|
-
var tapImpl = (result, fn) => {
|
|
20
|
+
var map = dual(
|
|
21
|
+
2,
|
|
22
|
+
(result, fn) => isOk(result) ? ok(fn(result.value)) : err(result.error)
|
|
23
|
+
);
|
|
24
|
+
var mapErr = dual(
|
|
25
|
+
2,
|
|
26
|
+
(result, fn) => isErr(result) ? err(fn(result.error)) : ok(result.value)
|
|
27
|
+
);
|
|
28
|
+
var bimap = dual(
|
|
29
|
+
3,
|
|
30
|
+
(result, onOk, onErr) => isOk(result) ? ok(onOk(result.value)) : err(onErr(result.error))
|
|
31
|
+
);
|
|
32
|
+
var flatMap = dual(
|
|
33
|
+
2,
|
|
34
|
+
(result, fn) => isOk(result) ? fn(result.value) : err(result.error)
|
|
35
|
+
);
|
|
36
|
+
var recover = dual(
|
|
37
|
+
2,
|
|
38
|
+
(result, fn) => isErr(result) ? fn(result.error) : ok(result.value)
|
|
39
|
+
);
|
|
40
|
+
var tap = dual(2, (result, fn) => {
|
|
43
41
|
if (isOk(result)) fn(result.value);
|
|
44
42
|
return result;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
if (args.length === 2) return tapImpl(args[0], args[1]);
|
|
48
|
-
const fn = args[0];
|
|
49
|
-
return (result) => tapImpl(result, fn);
|
|
50
|
-
}
|
|
51
|
-
var tapErrImpl = (result, fn) => {
|
|
43
|
+
});
|
|
44
|
+
var tapErr = dual(2, (result, fn) => {
|
|
52
45
|
if (isErr(result)) fn(result.error);
|
|
53
46
|
return result;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const [onOk, onErr] = args;
|
|
64
|
-
return (result) => matchImpl(result, onOk, onErr);
|
|
65
|
-
}
|
|
66
|
-
var unwrapOr = (result, defaultValue) => isOk(result) ? result.value : defaultValue;
|
|
47
|
+
});
|
|
48
|
+
var match = dual(
|
|
49
|
+
3,
|
|
50
|
+
(result, onOk, onErr) => isOk(result) ? onOk(result.value) : onErr(result.error)
|
|
51
|
+
);
|
|
52
|
+
var unwrapOr = dual(
|
|
53
|
+
2,
|
|
54
|
+
(result, defaultValue) => isOk(result) ? result.value : defaultValue
|
|
55
|
+
);
|
|
67
56
|
function unwrapOk(result) {
|
|
68
57
|
if (isErr(result)) throw result.error;
|
|
69
58
|
return result.value;
|
|
70
59
|
}
|
|
60
|
+
var unwrap = unwrapOk;
|
|
71
61
|
function unwrapErr(result) {
|
|
72
62
|
if (isOk(result)) throw new TypeError("unwrapErr called on Ok");
|
|
73
63
|
return result.error;
|
|
@@ -88,6 +78,14 @@ function pipe(value, ...fns) {
|
|
|
88
78
|
}
|
|
89
79
|
return acc;
|
|
90
80
|
}
|
|
81
|
+
var printPayload = (payload) => {
|
|
82
|
+
try {
|
|
83
|
+
return JSON.stringify(payload) ?? String(payload);
|
|
84
|
+
} catch {
|
|
85
|
+
return String(payload);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
var show = (result) => isOk(result) ? `Ok(${printPayload(result.value)})` : `Err(${printPayload(result.error)})`;
|
|
91
89
|
|
|
92
90
|
// src/types.ts
|
|
93
91
|
var UnexpectedError = class extends Error {
|
|
@@ -100,17 +98,6 @@ var UnexpectedError = class extends Error {
|
|
|
100
98
|
};
|
|
101
99
|
|
|
102
100
|
// src/async.ts
|
|
103
|
-
var liftPromiseResult = async (promise, onDefect) => {
|
|
104
|
-
try {
|
|
105
|
-
const result = await promise;
|
|
106
|
-
if (isErr(result)) {
|
|
107
|
-
return result;
|
|
108
|
-
}
|
|
109
|
-
return isResultLike(result.value) ? result.value : result;
|
|
110
|
-
} catch (error) {
|
|
111
|
-
return err(onDefect(error));
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
101
|
var sequenceSettled = (settled) => {
|
|
115
102
|
const values = [];
|
|
116
103
|
for (const result of settled) {
|
|
@@ -192,6 +179,9 @@ var ResultAsync = class _ResultAsync {
|
|
|
192
179
|
static ok(value) {
|
|
193
180
|
return new _ResultAsync(async () => ok(value));
|
|
194
181
|
}
|
|
182
|
+
static of(value) {
|
|
183
|
+
return _ResultAsync.ok(value);
|
|
184
|
+
}
|
|
195
185
|
/**
|
|
196
186
|
* Lifts an error into an `Err` async result.
|
|
197
187
|
*
|
|
@@ -205,16 +195,23 @@ var ResultAsync = class _ResultAsync {
|
|
|
205
195
|
}
|
|
206
196
|
/**
|
|
207
197
|
* Lifts an existing `Promise<Result<T, E>>` (e.g. from interop code) into a
|
|
208
|
-
* {@link ResultAsync}
|
|
209
|
-
*
|
|
198
|
+
* {@link ResultAsync}. A thrown defect is routed through `onDefect`,
|
|
199
|
+
* defaulting to {@link UnexpectedError}. The `Ok` value passes through
|
|
200
|
+
* verbatim — even when it happens to be Result-shaped.
|
|
210
201
|
*
|
|
211
202
|
* @param promise - a promise that already yields a `Result`
|
|
212
203
|
* @param onDefect - maps an unexpected throw to the `Err` channel
|
|
213
|
-
* @see {@link fromAsync} from `@onrails/result
|
|
204
|
+
* @see {@link fromAsync} from `@onrails/result`
|
|
214
205
|
*/
|
|
215
206
|
static fromResultPromise(promise, onDefect) {
|
|
216
207
|
const mapDefect = onDefect ?? ((error) => new UnexpectedError("Unexpected async defect", error));
|
|
217
|
-
return new _ResultAsync(() =>
|
|
208
|
+
return new _ResultAsync(async () => {
|
|
209
|
+
try {
|
|
210
|
+
return await promise;
|
|
211
|
+
} catch (error) {
|
|
212
|
+
return err(mapDefect(error));
|
|
213
|
+
}
|
|
214
|
+
});
|
|
218
215
|
}
|
|
219
216
|
/**
|
|
220
217
|
* Combines a homogeneous array of async results into one. Resolves
|
|
@@ -298,7 +295,7 @@ var ResultAsync = class _ResultAsync {
|
|
|
298
295
|
*
|
|
299
296
|
* @example
|
|
300
297
|
* ```ts
|
|
301
|
-
* load(id).mapErr((e): AppError => ({ kind: "load", cause: e }));
|
|
298
|
+
* load(id).mapErr((e): AppError => ({ kind: "load", cause: e })); // ResultAsync<T, AppError>
|
|
302
299
|
* ```
|
|
303
300
|
*/
|
|
304
301
|
mapErr(fn) {
|
|
@@ -322,18 +319,12 @@ var ResultAsync = class _ResultAsync {
|
|
|
322
319
|
return first;
|
|
323
320
|
}
|
|
324
321
|
const next = fn(first.value);
|
|
325
|
-
|
|
326
|
-
return next.resolve();
|
|
327
|
-
}
|
|
328
|
-
if (isResultLike(next)) {
|
|
329
|
-
return next;
|
|
330
|
-
}
|
|
331
|
-
return isCompatLike(next) ? next.inner : next;
|
|
322
|
+
return next instanceof _ResultAsync ? next.resolve() : next;
|
|
332
323
|
});
|
|
333
324
|
}
|
|
334
325
|
/**
|
|
335
326
|
* neverthrow-compat alias of {@link flatMap}. Kept as the documented compat
|
|
336
|
-
* tier; prefer
|
|
327
|
+
* tier; prefer {@link flatMap} in new code.
|
|
337
328
|
*
|
|
338
329
|
* @example
|
|
339
330
|
* ```ts
|
|
@@ -350,7 +341,7 @@ var ResultAsync = class _ResultAsync {
|
|
|
350
341
|
*
|
|
351
342
|
* @example
|
|
352
343
|
* ```ts
|
|
353
|
-
* loadFromCache(id).recover(() => loadFromOrigin(id));
|
|
344
|
+
* loadFromCache(id).recover(() => loadFromOrigin(id)); // ResultAsync<T, F>
|
|
354
345
|
* ```
|
|
355
346
|
*/
|
|
356
347
|
recover(fn) {
|
|
@@ -365,7 +356,7 @@ var ResultAsync = class _ResultAsync {
|
|
|
365
356
|
}
|
|
366
357
|
/**
|
|
367
358
|
* neverthrow-compat alias of {@link recover}. Kept as the documented compat
|
|
368
|
-
* tier; prefer
|
|
359
|
+
* tier; prefer {@link recover} in new code.
|
|
369
360
|
*
|
|
370
361
|
* @example
|
|
371
362
|
* ```ts
|
|
@@ -473,19 +464,18 @@ var ResultAsync = class _ResultAsync {
|
|
|
473
464
|
);
|
|
474
465
|
}
|
|
475
466
|
};
|
|
476
|
-
function isResultLike(v) {
|
|
477
|
-
return typeof v === "object" && v !== null && "_tag" in v && (v._tag === "Ok" || v._tag === "Err");
|
|
478
|
-
}
|
|
479
|
-
function isCompatLike(v) {
|
|
480
|
-
return typeof v === "object" && v !== null && "inner" in v && isResultLike(v.inner);
|
|
481
|
-
}
|
|
482
467
|
|
|
483
468
|
// src/async-lift.ts
|
|
484
469
|
var okAsync = ResultAsync.ok;
|
|
485
470
|
var errAsync = ResultAsync.err;
|
|
486
471
|
var fromPromise = ResultAsync.fromPromise;
|
|
487
472
|
var fromSafePromise = ResultAsync.fromSafePromise;
|
|
488
|
-
var
|
|
473
|
+
var fromResult = ResultAsync.fromResult;
|
|
474
|
+
var asyncAfter = dual(
|
|
475
|
+
2,
|
|
476
|
+
(result, fn) => fromResult(result).flatMap(fn)
|
|
477
|
+
);
|
|
478
|
+
var fromAsync = (fn, onDefect) => (...args) => ResultAsync.fromResultPromise(fn(...args), onDefect);
|
|
489
479
|
var toError = (error) => error instanceof Error ? error : new Error(String(error));
|
|
490
480
|
function tryAsync(promise, onReject) {
|
|
491
481
|
return onReject ? ResultAsync.fromPromise(promise, onReject) : ResultAsync.fromPromise(promise, toError);
|
|
@@ -504,17 +494,22 @@ var combineTuple = (results) => (
|
|
|
504
494
|
// Runtime identical to combine; the cast restores per-index tuple types.
|
|
505
495
|
combine(results)
|
|
506
496
|
);
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
497
|
+
function validateAll(results, combineErrors) {
|
|
498
|
+
const values = [];
|
|
499
|
+
const errors = [];
|
|
500
|
+
for (const result of results) {
|
|
501
|
+
if (isErr(result)) {
|
|
502
|
+
errors.push(result.error);
|
|
503
|
+
} else {
|
|
504
|
+
values.push(result.value);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
if (errors.length === 0) return ok(values);
|
|
508
|
+
return err(combineErrors ? errors.reduce(combineErrors) : errors);
|
|
509
|
+
}
|
|
510
|
+
function validateTuple(results, combineErrors) {
|
|
511
|
+
return combineErrors ? validateAll(results, combineErrors) : validateAll(results);
|
|
516
512
|
}
|
|
517
|
-
var fromAsync = (fn, onDefect) => (...args) => ResultAsync.fromResultPromise(fn(...args), onDefect);
|
|
518
513
|
|
|
519
514
|
// src/pipe.ts
|
|
520
515
|
function flow(first, ...rest) {
|
|
@@ -553,6 +548,6 @@ var tryGen = (fn) => {
|
|
|
553
548
|
}
|
|
554
549
|
};
|
|
555
550
|
|
|
556
|
-
export { $, ResultAsync, asyncAfter, bimap, combine, combineTuple, err, errAsync, flatMap, flow, fromAsync, fromPromise, fromResult, fromSafePromise, isErr, isOk, map, mapErr, match, ok, okAsync,
|
|
551
|
+
export { $, ResultAsync, UnexpectedError, asyncAfter, bimap, combine, combineTuple, err, errAsync, flatMap, flow, fromAsync, fromPromise, fromResult, fromSafePromise, isErr, isOk, map, mapErr, match, of, ok, okAsync, pipe, recover, show, tap, tapErr, tryAsync, tryGen, trySync, unwrap, unwrapErr, unwrapOk, unwrapOr, validateAll, validateTuple, yieldResult };
|
|
557
552
|
//# sourceMappingURL=index.js.map
|
|
558
553
|
//# sourceMappingURL=index.js.map
|