@onrails/result 0.1.4 → 0.3.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/DESIGN.md +11 -19
- package/README.md +14 -62
- package/RECIPES.md +12 -25
- package/dist/async-BR3AX0ck.d.cts +326 -0
- package/dist/async-SZ7BEl0g.d.ts +326 -0
- package/dist/compat/neverthrow.cjs +266 -94
- package/dist/compat/neverthrow.cjs.map +1 -1
- package/dist/compat/neverthrow.d.cts +4 -4
- package/dist/compat/neverthrow.d.ts +4 -4
- package/dist/compat/neverthrow.js +263 -91
- package/dist/compat/neverthrow.js.map +1 -1
- package/dist/extra.cjs +2 -25
- package/dist/extra.cjs.map +1 -1
- package/dist/extra.d.cts +7 -19
- package/dist/extra.d.ts +7 -19
- package/dist/extra.js +3 -25
- package/dist/extra.js.map +1 -1
- package/dist/fluent.cjs +55 -29
- package/dist/fluent.cjs.map +1 -1
- package/dist/fluent.d.cts +38 -11
- package/dist/fluent.d.ts +38 -11
- package/dist/fluent.js +55 -29
- package/dist/fluent.js.map +1 -1
- package/dist/index.cjs +290 -131
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +294 -69
- package/dist/index.d.ts +294 -69
- package/dist/index.js +287 -127
- package/dist/index.js.map +1 -1
- package/dist/pipe.cjs.map +1 -1
- package/dist/pipe.d.cts +7 -5
- package/dist/pipe.d.ts +7 -5
- package/dist/pipe.js.map +1 -1
- package/dist/railway.cjs +293 -188
- package/dist/railway.cjs.map +1 -1
- package/dist/railway.d.cts +26 -180
- package/dist/railway.d.ts +26 -180
- package/dist/railway.js +294 -178
- 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.d.cts +29 -3
- package/dist/try-gen.d.ts +29 -3
- package/dist/try-gen.js +1 -1
- package/dist/try-gen.js.map +1 -1
- package/dist/types-BQ9vv0nD.d.cts +55 -0
- package/dist/types-BQ9vv0nD.d.ts +55 -0
- package/package.json +5 -18
- package/skills/railway-do-notation/SKILL.md +397 -0
- package/skills/result-composition/SKILL.md +323 -0
- 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/async-CH8Cs8KE.d.cts +0 -161
- package/dist/async-DKISqIBc.d.ts +0 -161
- package/dist/interop.cjs +0 -253
- package/dist/interop.cjs.map +0 -1
- package/dist/interop.d.cts +0 -35
- package/dist/interop.d.ts +0 -35
- package/dist/interop.js +0 -249
- package/dist/interop.js.map +0 -1
- package/dist/types-C2Dp1d5J.d.cts +0 -21
- package/dist/types-C2Dp1d5J.d.ts +0 -21
- 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
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
// src/internal/dual.ts
|
|
4
|
+
var dual = (arity, body) => {
|
|
5
|
+
const run = body;
|
|
6
|
+
const dispatcher = (...args) => args.length >= arity ? run(...args) : (self) => run(self, ...args);
|
|
7
|
+
return dispatcher;
|
|
8
|
+
};
|
|
9
|
+
|
|
3
10
|
// src/result.ts
|
|
4
11
|
var ok = (value) => ({
|
|
5
12
|
_tag: "Ok",
|
|
@@ -11,25 +18,22 @@ var err = (error) => ({
|
|
|
11
18
|
});
|
|
12
19
|
var isOk = (result) => result._tag === "Ok";
|
|
13
20
|
var isErr = (result) => result._tag === "Err";
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
var
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return (result) => flatMapImpl(result, fn);
|
|
31
|
-
}
|
|
32
|
-
var unwrapOr = (result, defaultValue) => isOk(result) ? result.value : defaultValue;
|
|
21
|
+
var map = dual(
|
|
22
|
+
2,
|
|
23
|
+
(result, fn) => isOk(result) ? ok(fn(result.value)) : err(result.error)
|
|
24
|
+
);
|
|
25
|
+
var mapErr = dual(
|
|
26
|
+
2,
|
|
27
|
+
(result, fn) => isErr(result) ? err(fn(result.error)) : ok(result.value)
|
|
28
|
+
);
|
|
29
|
+
var flatMap = dual(
|
|
30
|
+
2,
|
|
31
|
+
(result, fn) => isOk(result) ? fn(result.value) : err(result.error)
|
|
32
|
+
);
|
|
33
|
+
var unwrapOr = dual(
|
|
34
|
+
2,
|
|
35
|
+
(result, defaultValue) => isOk(result) ? result.value : defaultValue
|
|
36
|
+
);
|
|
33
37
|
function trySync(fn, onThrow) {
|
|
34
38
|
return (...args) => {
|
|
35
39
|
try {
|
|
@@ -39,18 +43,6 @@ function trySync(fn, onThrow) {
|
|
|
39
43
|
}
|
|
40
44
|
};
|
|
41
45
|
}
|
|
42
|
-
var combine = (results) => {
|
|
43
|
-
const values = [];
|
|
44
|
-
for (const result of results) {
|
|
45
|
-
if (isErr(result)) return err(result.error);
|
|
46
|
-
values.push(result.value);
|
|
47
|
-
}
|
|
48
|
-
return ok(values);
|
|
49
|
-
};
|
|
50
|
-
var combineTuple = (results) => (
|
|
51
|
-
// Runtime identical to combine; the cast restores per-index tuple types.
|
|
52
|
-
combine(results)
|
|
53
|
-
);
|
|
54
46
|
|
|
55
47
|
// src/types.ts
|
|
56
48
|
var UnexpectedError = class extends Error {
|
|
@@ -63,17 +55,6 @@ var UnexpectedError = class extends Error {
|
|
|
63
55
|
};
|
|
64
56
|
|
|
65
57
|
// src/async.ts
|
|
66
|
-
var liftPromiseResult = async (promise, onDefect) => {
|
|
67
|
-
try {
|
|
68
|
-
const result = await promise;
|
|
69
|
-
if (isErr(result)) {
|
|
70
|
-
return result;
|
|
71
|
-
}
|
|
72
|
-
return isResultLike(result.value) ? result.value : result;
|
|
73
|
-
} catch (error) {
|
|
74
|
-
return err(onDefect(error));
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
58
|
var sequenceSettled = (settled) => {
|
|
78
59
|
const values = [];
|
|
79
60
|
for (const result of settled) {
|
|
@@ -90,9 +71,32 @@ var ResultAsync = class _ResultAsync {
|
|
|
90
71
|
}
|
|
91
72
|
run;
|
|
92
73
|
promise = null;
|
|
74
|
+
/**
|
|
75
|
+
* Lifts an already-settled sync {@link Result} into a {@link ResultAsync}.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* const ra = ResultAsync.fromResult(ok(42)); // ResultAsync<number, never>
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
93
82
|
static fromResult(result) {
|
|
94
83
|
return new _ResultAsync(async () => result);
|
|
95
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Wraps a `PromiseLike<T>` that may reject. Rejections pass through `onReject`
|
|
87
|
+
* to become a typed `Err`; resolution becomes `Ok<T>`.
|
|
88
|
+
*
|
|
89
|
+
* @param promise - the promise to wrap
|
|
90
|
+
* @param onReject - maps a rejection reason to the `Err` channel
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* const body = ResultAsync.fromPromise(
|
|
95
|
+
* fetch(url).then((r) => r.text()),
|
|
96
|
+
* (e): NetError => ({ kind: "net", cause: String(e) }),
|
|
97
|
+
* );
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
96
100
|
static fromPromise(promise, onReject) {
|
|
97
101
|
return new _ResultAsync(async () => {
|
|
98
102
|
try {
|
|
@@ -102,12 +106,29 @@ var ResultAsync = class _ResultAsync {
|
|
|
102
106
|
}
|
|
103
107
|
});
|
|
104
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Wraps a `PromiseLike<T>` that is **guaranteed not to reject**, skipping the
|
|
111
|
+
* `onReject` mapper. Use only when rejection is provably impossible.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```ts
|
|
115
|
+
* const now = ResultAsync.fromSafePromise(Promise.resolve(Date.now()));
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
105
118
|
static fromSafePromise(promise) {
|
|
106
119
|
return new _ResultAsync(async () => ok(await promise));
|
|
107
120
|
}
|
|
108
121
|
/**
|
|
109
|
-
* Defers work until {@link resolve}. Unlike {@link fromPromise},
|
|
110
|
-
* until the `ResultAsync` is resolved (e.g. by `combineTuple` /
|
|
122
|
+
* Defers work until {@link resolve}. Unlike {@link fromPromise}, the factory
|
|
123
|
+
* does not run until the `ResultAsync` is resolved (e.g. by `combineTuple` /
|
|
124
|
+
* `combineTupleParallel`). The factory runs at most once — `resolve` memoizes.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* const insert = ResultAsync.defer(() => db.orders.insert(row));
|
|
129
|
+
* // nothing has run yet
|
|
130
|
+
* const r = await insert; // factory runs exactly once here
|
|
131
|
+
* ```
|
|
111
132
|
*/
|
|
112
133
|
static defer(fn) {
|
|
113
134
|
return new _ResultAsync(fn);
|
|
@@ -115,14 +136,49 @@ var ResultAsync = class _ResultAsync {
|
|
|
115
136
|
static ok(value) {
|
|
116
137
|
return new _ResultAsync(async () => ok(value));
|
|
117
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Lifts an error into an `Err` async result.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* const r = ResultAsync.err({ kind: "not_found" as const });
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
118
147
|
static err(error) {
|
|
119
148
|
return new _ResultAsync(async () => err(error));
|
|
120
149
|
}
|
|
121
|
-
/**
|
|
150
|
+
/**
|
|
151
|
+
* Lifts an existing `Promise<Result<T, E>>` (e.g. from interop code) into a
|
|
152
|
+
* {@link ResultAsync}. A thrown defect is routed through `onDefect`,
|
|
153
|
+
* defaulting to {@link UnexpectedError}. The `Ok` value passes through
|
|
154
|
+
* verbatim — even when it happens to be Result-shaped.
|
|
155
|
+
*
|
|
156
|
+
* @param promise - a promise that already yields a `Result`
|
|
157
|
+
* @param onDefect - maps an unexpected throw to the `Err` channel
|
|
158
|
+
* @see {@link fromAsync} from `@onrails/result`
|
|
159
|
+
*/
|
|
122
160
|
static fromResultPromise(promise, onDefect) {
|
|
123
161
|
const mapDefect = onDefect ?? ((error) => new UnexpectedError("Unexpected async defect", error));
|
|
124
|
-
return new _ResultAsync(() =>
|
|
162
|
+
return new _ResultAsync(async () => {
|
|
163
|
+
try {
|
|
164
|
+
return await promise;
|
|
165
|
+
} catch (error) {
|
|
166
|
+
return err(mapDefect(error));
|
|
167
|
+
}
|
|
168
|
+
});
|
|
125
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* Combines a homogeneous array of async results into one. Resolves
|
|
172
|
+
* **sequentially** in input order, short-circuiting on the first `Err`.
|
|
173
|
+
* For heterogeneous tuples that preserve per-index types, use
|
|
174
|
+
* {@link combineTuple}; for wall-clock overlap, {@link combineTupleParallel}.
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```ts
|
|
178
|
+
* const all = ResultAsync.combine([loadA(), loadB(), loadC()]);
|
|
179
|
+
* // ResultAsync<Item[], LoadError>
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
126
182
|
static combine(results) {
|
|
127
183
|
return new _ResultAsync(async () => {
|
|
128
184
|
const values = [];
|
|
@@ -136,6 +192,23 @@ var ResultAsync = class _ResultAsync {
|
|
|
136
192
|
return ok(values);
|
|
137
193
|
});
|
|
138
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* Heterogeneous async tuple combine — resolves branches **sequentially**
|
|
197
|
+
* (left-to-right), returning the first `Err` in input order. Preserves each
|
|
198
|
+
* branch's `Ok` type by position, so the result destructures type-safely.
|
|
199
|
+
* This is the canonical sequential async combine (replaces the former
|
|
200
|
+
* `sequenceTupleAsync`).
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```ts
|
|
204
|
+
* const combined = ResultAsync.combineTuple([loadCfg(), loadCatalog()] as const);
|
|
205
|
+
* // ResultAsync<readonly [Cfg, Catalog], CfgError | CatalogError>
|
|
206
|
+
* const r = await combined;
|
|
207
|
+
* if (isOk(r)) {
|
|
208
|
+
* const [cfg, catalog] = r.value; // typed per position
|
|
209
|
+
* }
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
139
212
|
static combineTuple(results) {
|
|
140
213
|
return _ResultAsync.combine(
|
|
141
214
|
results
|
|
@@ -144,18 +217,55 @@ var ResultAsync = class _ResultAsync {
|
|
|
144
217
|
/**
|
|
145
218
|
* Like {@link combineTuple}, but starts every branch before awaiting (wall-clock
|
|
146
219
|
* parallel for independent IO). On failure, returns the first `Err` in input order.
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```ts
|
|
223
|
+
* // independent IO — overlap them
|
|
224
|
+
* const combined = ResultAsync.combineTupleParallel([
|
|
225
|
+
* loadProfile(id),
|
|
226
|
+
* loadMetrics(id),
|
|
227
|
+
* ] as const);
|
|
228
|
+
* ```
|
|
147
229
|
*/
|
|
148
230
|
static combineTupleParallel(results) {
|
|
149
231
|
return new _ResultAsync(
|
|
150
232
|
async () => sequenceSettled(await Promise.all(results.map((ra) => ra.resolve())))
|
|
151
233
|
);
|
|
152
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* Transforms the `Ok` value, passing `Err` through unchanged.
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```ts
|
|
240
|
+
* ResultAsync.ok(2).map((n) => n * 3); // ResultAsync<number> → Ok 6
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
153
243
|
map(fn) {
|
|
154
244
|
return new _ResultAsync(async () => map(await this.resolve(), fn));
|
|
155
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* Transforms the `Err` value, passing `Ok` through unchanged — useful for
|
|
248
|
+
* unifying heterogeneous failures into one app-level union.
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```ts
|
|
252
|
+
* load(id).mapErr((e): AppError => ({ kind: "load", cause: e })); // ResultAsync<T, AppError>
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
156
255
|
mapErr(fn) {
|
|
157
256
|
return new _ResultAsync(async () => mapErr(await this.resolve(), fn));
|
|
158
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* Canonical bind — chains a step that itself returns a `ResultAsync` or sync
|
|
260
|
+
* `Result`, short-circuiting on `Err`. Error types accumulate (`E | F`).
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```ts
|
|
264
|
+
* authenticate(req)
|
|
265
|
+
* .flatMap((user) => loadProfile(user.id)) // ResultAsync
|
|
266
|
+
* .flatMap((p) => validate(p)); // sync Result also accepted
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
159
269
|
flatMap(fn) {
|
|
160
270
|
return new _ResultAsync(async () => {
|
|
161
271
|
const first = await this.resolve();
|
|
@@ -163,25 +273,31 @@ var ResultAsync = class _ResultAsync {
|
|
|
163
273
|
return first;
|
|
164
274
|
}
|
|
165
275
|
const next = fn(first.value);
|
|
166
|
-
|
|
167
|
-
return next.resolve();
|
|
168
|
-
}
|
|
169
|
-
if (isResultLike(next)) {
|
|
170
|
-
return next;
|
|
171
|
-
}
|
|
172
|
-
return isCompatLike(next) ? next.inner : next;
|
|
276
|
+
return next instanceof _ResultAsync ? next.resolve() : next;
|
|
173
277
|
});
|
|
174
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* neverthrow-compat alias of {@link flatMap}. Kept as the documented compat
|
|
281
|
+
* tier; prefer {@link flatMap} in new code.
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```ts
|
|
285
|
+
* authenticate(req).andThen((user) => loadProfile(user.id));
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
175
288
|
andThen(fn) {
|
|
176
289
|
return this.flatMap(fn);
|
|
177
290
|
}
|
|
178
291
|
/**
|
|
179
|
-
*
|
|
180
|
-
*
|
|
292
|
+
* Error-channel bind — runs `fn` only on `Err`, swapping in a recovery
|
|
293
|
+
* `ResultAsync` or sync `Result`. `Ok` passes through. The mirror of
|
|
294
|
+
* {@link flatMap} on the error track.
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* ```ts
|
|
298
|
+
* loadFromCache(id).recover(() => loadFromOrigin(id)); // ResultAsync<T, F>
|
|
299
|
+
* ```
|
|
181
300
|
*/
|
|
182
|
-
chain(fn) {
|
|
183
|
-
return this.flatMap(fn);
|
|
184
|
-
}
|
|
185
301
|
recover(fn) {
|
|
186
302
|
return new _ResultAsync(async () => {
|
|
187
303
|
const first = await this.resolve();
|
|
@@ -192,9 +308,27 @@ var ResultAsync = class _ResultAsync {
|
|
|
192
308
|
return next instanceof _ResultAsync ? next.resolve() : next;
|
|
193
309
|
});
|
|
194
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* neverthrow-compat alias of {@link recover}. Kept as the documented compat
|
|
313
|
+
* tier; prefer {@link recover} in new code.
|
|
314
|
+
*
|
|
315
|
+
* @example
|
|
316
|
+
* ```ts
|
|
317
|
+
* loadFromCache(id).orElse(() => loadFromOrigin(id));
|
|
318
|
+
* ```
|
|
319
|
+
*/
|
|
195
320
|
orElse(fn) {
|
|
196
321
|
return this.recover(fn);
|
|
197
322
|
}
|
|
323
|
+
/**
|
|
324
|
+
* Runs a side effect on the `Ok` value and passes the result through
|
|
325
|
+
* unchanged; a no-op on `Err`. Mirrors {@link tapErr}.
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* ```ts
|
|
329
|
+
* saveUser(u).tap((saved) => analytics.track("user_saved", saved.id));
|
|
330
|
+
* ```
|
|
331
|
+
*/
|
|
198
332
|
tap(fn) {
|
|
199
333
|
return new _ResultAsync(async () => {
|
|
200
334
|
const result = await this.resolve();
|
|
@@ -204,6 +338,15 @@ var ResultAsync = class _ResultAsync {
|
|
|
204
338
|
return result;
|
|
205
339
|
});
|
|
206
340
|
}
|
|
341
|
+
/**
|
|
342
|
+
* Runs a side effect on the `Err` value and passes the result through
|
|
343
|
+
* unchanged; a no-op on `Ok`. The error-track mirror of {@link tap}.
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```ts
|
|
347
|
+
* saveUser(u).tapErr((e) => logger.warn("save failed", e));
|
|
348
|
+
* ```
|
|
349
|
+
*/
|
|
207
350
|
tapErr(fn) {
|
|
208
351
|
return new _ResultAsync(async () => {
|
|
209
352
|
const result = await this.resolve();
|
|
@@ -213,28 +356,49 @@ var ResultAsync = class _ResultAsync {
|
|
|
213
356
|
return result;
|
|
214
357
|
});
|
|
215
358
|
}
|
|
216
|
-
unwrapOr(defaultValue) {
|
|
217
|
-
return this.resolve().then((result) => isErr(result) ? defaultValue : result.value);
|
|
218
|
-
}
|
|
219
359
|
/**
|
|
220
|
-
*
|
|
221
|
-
*
|
|
360
|
+
* Settles to the `Ok` value, or `defaultValue` if `Err`. Terminal — returns a
|
|
361
|
+
* plain `Promise`, not a `ResultAsync`.
|
|
362
|
+
*
|
|
363
|
+
* @example
|
|
364
|
+
* ```ts
|
|
365
|
+
* const profile = await loadProfile(id).unwrapOr(guestProfile);
|
|
366
|
+
* ```
|
|
222
367
|
*/
|
|
223
|
-
|
|
224
|
-
return this.resolve().then((result) =>
|
|
368
|
+
unwrapOr(defaultValue) {
|
|
369
|
+
return this.resolve().then((result) => isErr(result) ? defaultValue : result.value);
|
|
225
370
|
}
|
|
226
371
|
/**
|
|
227
|
-
*
|
|
228
|
-
*
|
|
372
|
+
* Terminal collapse — folds both tracks into a single awaited value. Returns
|
|
373
|
+
* a plain `Promise`, settling the carrier exactly once.
|
|
374
|
+
*
|
|
375
|
+
* @param onOk - handles the `Ok` value
|
|
376
|
+
* @param onErr - handles the `Err` value
|
|
377
|
+
*
|
|
378
|
+
* @example
|
|
379
|
+
* ```ts
|
|
380
|
+
* const status = await save(row).match(
|
|
381
|
+
* () => 200,
|
|
382
|
+
* (e) => (e.kind === "conflict" ? 409 : 500),
|
|
383
|
+
* );
|
|
384
|
+
* ```
|
|
229
385
|
*/
|
|
230
|
-
isErr() {
|
|
231
|
-
return this.resolve().then((result) => isErr(result));
|
|
232
|
-
}
|
|
233
386
|
match(onOk, onErr) {
|
|
234
387
|
return this.resolve().then(
|
|
235
388
|
(result) => isErr(result) ? onErr(result.error) : onOk(result.value)
|
|
236
389
|
);
|
|
237
390
|
}
|
|
391
|
+
/**
|
|
392
|
+
* Settles the carrier to a bare sync {@link Result}, memoizing so the
|
|
393
|
+
* underlying factory runs at most once. Prefer `await ra` (the thenable) or
|
|
394
|
+
* {@link match} in app code; use `resolve` when you need the tagged union back.
|
|
395
|
+
*
|
|
396
|
+
* @example
|
|
397
|
+
* ```ts
|
|
398
|
+
* const r = await load(id).resolve(); // Result<Data, LoadError>
|
|
399
|
+
* if (isOk(r)) use(r.value);
|
|
400
|
+
* ```
|
|
401
|
+
*/
|
|
238
402
|
resolve() {
|
|
239
403
|
if (!this.promise) {
|
|
240
404
|
this.promise = this.run();
|
|
@@ -254,12 +418,20 @@ var ResultAsync = class _ResultAsync {
|
|
|
254
418
|
);
|
|
255
419
|
}
|
|
256
420
|
};
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
421
|
+
|
|
422
|
+
// src/collections.ts
|
|
423
|
+
var combine = (results) => {
|
|
424
|
+
const values = [];
|
|
425
|
+
for (const result of results) {
|
|
426
|
+
if (isErr(result)) return err(result.error);
|
|
427
|
+
values.push(result.value);
|
|
428
|
+
}
|
|
429
|
+
return ok(values);
|
|
430
|
+
};
|
|
431
|
+
var combineTuple = (results) => (
|
|
432
|
+
// Runtime identical to combine; the cast restores per-index tuple types.
|
|
433
|
+
combine(results)
|
|
434
|
+
);
|
|
263
435
|
|
|
264
436
|
// src/compat/neverthrow.ts
|
|
265
437
|
var CompatResult = class _CompatResult {
|
|
@@ -298,16 +470,10 @@ var CompatResult = class _CompatResult {
|
|
|
298
470
|
return new _CompatResult(flatMap(this.inner, (value) => fn(value).inner));
|
|
299
471
|
}
|
|
300
472
|
asyncAndThen(fn) {
|
|
301
|
-
|
|
302
|
-
return CompatResultAsync.err(this.inner.error);
|
|
303
|
-
}
|
|
304
|
-
return CompatResultAsync.fromInner(coerceToCoreAsync(fn(this.inner.value)));
|
|
473
|
+
return isErr(this.inner) ? CompatResultAsync.err(this.inner.error) : CompatResultAsync.fromInner(coerceToCoreAsync(fn(this.inner.value)));
|
|
305
474
|
}
|
|
306
475
|
orElse(fn) {
|
|
307
|
-
|
|
308
|
-
return new _CompatResult(this.inner);
|
|
309
|
-
}
|
|
310
|
-
return fn(this.inner.error);
|
|
476
|
+
return isOk(this.inner) ? new _CompatResult(this.inner) : fn(this.inner.error);
|
|
311
477
|
}
|
|
312
478
|
match(onOk, onErr) {
|
|
313
479
|
return isOk(this.inner) ? onOk(this.inner.value) : onErr(this.inner.error);
|
|
@@ -398,10 +564,16 @@ var CompatResultAsync = class _CompatResultAsync {
|
|
|
398
564
|
return this.inner.unwrapOr(defaultValue);
|
|
399
565
|
}
|
|
400
566
|
isOk() {
|
|
401
|
-
return this.inner.
|
|
567
|
+
return this.inner.match(
|
|
568
|
+
() => true,
|
|
569
|
+
() => false
|
|
570
|
+
);
|
|
402
571
|
}
|
|
403
572
|
isErr() {
|
|
404
|
-
return this.inner.
|
|
573
|
+
return this.inner.match(
|
|
574
|
+
() => false,
|
|
575
|
+
() => true
|
|
576
|
+
);
|
|
405
577
|
}
|
|
406
578
|
match(onOk, onErr) {
|
|
407
579
|
return this.inner.match(onOk, onErr);
|
|
@@ -442,20 +614,20 @@ function coerceToCore(next) {
|
|
|
442
614
|
return next;
|
|
443
615
|
}
|
|
444
616
|
var coerceToCoreAsync = (next) => next instanceof CompatResultAsync ? next.toCore() : next;
|
|
445
|
-
var
|
|
446
|
-
var
|
|
447
|
-
var
|
|
448
|
-
var
|
|
617
|
+
var okAsync = CompatResultAsync.ok;
|
|
618
|
+
var errAsync = CompatResultAsync.err;
|
|
619
|
+
var fromPromise = CompatResultAsync.fromPromise;
|
|
620
|
+
var fromSafePromise = CompatResultAsync.fromSafePromise;
|
|
449
621
|
|
|
450
622
|
exports.CompatResult = CompatResult;
|
|
451
623
|
exports.CompatResultAsync = CompatResultAsync;
|
|
452
624
|
exports.Result = Result;
|
|
453
625
|
exports.ResultAsync = CompatResultAsync;
|
|
454
626
|
exports.err = err2;
|
|
455
|
-
exports.errAsync =
|
|
456
|
-
exports.fromPromise =
|
|
457
|
-
exports.fromSafePromise =
|
|
627
|
+
exports.errAsync = errAsync;
|
|
628
|
+
exports.fromPromise = fromPromise;
|
|
629
|
+
exports.fromSafePromise = fromSafePromise;
|
|
458
630
|
exports.ok = ok2;
|
|
459
|
-
exports.okAsync =
|
|
631
|
+
exports.okAsync = okAsync;
|
|
460
632
|
//# sourceMappingURL=neverthrow.cjs.map
|
|
461
633
|
//# sourceMappingURL=neverthrow.cjs.map
|