unthrown 4.3.0 → 5.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/dist/index.cjs +316 -167
- package/dist/index.d.cts +322 -291
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +322 -291
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +302 -166
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -4
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,35 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let ts_pattern = require("ts-pattern");
|
|
3
|
+
//#region src/defect.ts
|
|
4
|
+
const DEFECT = Symbol("unthrown/Defect");
|
|
5
|
+
/**
|
|
6
|
+
* Wrap a cause as a `Defect` marker — the value returned from a `qualify`
|
|
7
|
+
* function when a failure is **not** a modeled domain error. The boundary
|
|
8
|
+
* (`fromPromise` / `fromThrowable`) passes this in as `qualify`'s second
|
|
9
|
+
* argument, so domain code never imports it.
|
|
10
|
+
*
|
|
11
|
+
* @param cause - the original thrown/rejected value.
|
|
12
|
+
* @returns an opaque Defect marker carrying `cause`.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
function defect(cause) {
|
|
17
|
+
return Object.freeze({
|
|
18
|
+
[DEFECT]: true,
|
|
19
|
+
cause
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Internal guard for the qualify-time marker. Distinct from the public
|
|
24
|
+
* {@link isDefect} state guard — this one narrows the `E | Defect` union a
|
|
25
|
+
* `qualify` function returns, not a `Result`.
|
|
26
|
+
*
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
function isDefectMarker(x) {
|
|
30
|
+
return typeof x === "object" && x !== null && x[DEFECT] === true;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
2
33
|
//#region src/core.ts
|
|
3
34
|
/**
|
|
4
35
|
* Thrown by a {@link Result}'s `get` / `getErr` when the assertion is
|
|
@@ -6,12 +37,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
6
37
|
* `Ok`.
|
|
7
38
|
*
|
|
8
39
|
* @remarks
|
|
9
|
-
* The offending value is exposed two ways: the typed {@link
|
|
40
|
+
* The offending value is exposed two ways: the typed {@link GetError.error}
|
|
10
41
|
* property for programmatic access, and the standard `Error.cause` for the
|
|
11
42
|
* runtime and devtools to chain — when `E` is an `Error` (e.g. a `TaggedError`)
|
|
12
43
|
* its original stack is printed under "caused by".
|
|
13
44
|
*
|
|
14
|
-
* A `Defect` is never wrapped in
|
|
45
|
+
* A `Defect` is never wrapped in a `GetError`: its original cause is
|
|
15
46
|
* re-thrown (with its original stack) instead.
|
|
16
47
|
*
|
|
17
48
|
* `get()` and `getErr()` are type-gated (`this: Result<T, never>` /
|
|
@@ -19,19 +50,19 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
19
50
|
* unreachable through well-typed code — it remains only as a defensive guard
|
|
20
51
|
* against unsound runtime misuse (e.g. an `as` cast past the gate).
|
|
21
52
|
*
|
|
22
|
-
* @typeParam E - the type of the {@link
|
|
53
|
+
* @typeParam E - the type of the {@link GetError.error} it carries.
|
|
23
54
|
*
|
|
24
55
|
* @category Errors
|
|
25
56
|
*/
|
|
26
|
-
var
|
|
57
|
+
var GetError = class extends Error {
|
|
27
58
|
/**
|
|
28
59
|
* The offending value: the `Err` error for `get()`, or the `Ok` value for
|
|
29
60
|
* `getErr()`.
|
|
30
61
|
*/
|
|
31
62
|
error;
|
|
32
63
|
constructor(error) {
|
|
33
|
-
super("unthrown: called
|
|
34
|
-
this.name = "
|
|
64
|
+
super("unthrown: get() / getErr() called on a non-matching Result variant", { cause: error });
|
|
65
|
+
this.name = "GetError";
|
|
35
66
|
this.error = error;
|
|
36
67
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
37
68
|
}
|
|
@@ -55,7 +86,8 @@ var Res = class {
|
|
|
55
86
|
flatMap(f) {
|
|
56
87
|
if (this.tag !== "Ok") return passThrough(this);
|
|
57
88
|
try {
|
|
58
|
-
|
|
89
|
+
const r = f(this.value);
|
|
90
|
+
return isResult(r) ? r : nonResultCallbackDefect();
|
|
59
91
|
} catch (cause) {
|
|
60
92
|
return defectRes(cause);
|
|
61
93
|
}
|
|
@@ -73,6 +105,7 @@ var Res = class {
|
|
|
73
105
|
if (this.tag !== "Ok") return this;
|
|
74
106
|
try {
|
|
75
107
|
const r = f(this.value);
|
|
108
|
+
if (!isResult(r)) return nonResultCallbackDefect();
|
|
76
109
|
return r.tag === "Ok" ? this : passThrough(r);
|
|
77
110
|
} catch (cause) {
|
|
78
111
|
return defectRes(cause);
|
|
@@ -82,6 +115,7 @@ var Res = class {
|
|
|
82
115
|
if (this.tag !== "Ok") return passThrough(this);
|
|
83
116
|
try {
|
|
84
117
|
const r = f(this.value);
|
|
118
|
+
if (!isResult(r)) return nonResultCallbackDefect();
|
|
85
119
|
if (r.tag !== "Ok") return passThrough(r);
|
|
86
120
|
return okRes({
|
|
87
121
|
...scopeOf(this.value),
|
|
@@ -110,10 +144,20 @@ var Res = class {
|
|
|
110
144
|
if (this.tag !== "Ok") return passThrough(this);
|
|
111
145
|
return okRes(void 0);
|
|
112
146
|
}
|
|
147
|
+
ensure(predicate, onFail) {
|
|
148
|
+
if (this.tag !== "Ok") return passThrough(this);
|
|
149
|
+
try {
|
|
150
|
+
return predicate(this.value) ? this : errRes(onFail(this.value));
|
|
151
|
+
} catch (cause) {
|
|
152
|
+
return defectRes(cause);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
113
155
|
mapErr(f) {
|
|
114
156
|
if (this.tag !== "Err") return passThrough(this);
|
|
115
157
|
try {
|
|
116
|
-
|
|
158
|
+
const out = runMatch(f, this.error);
|
|
159
|
+
if (isDefectMarker(out)) return defectRes(out.cause);
|
|
160
|
+
return errRes(out);
|
|
117
161
|
} catch (cause) {
|
|
118
162
|
return defectRes(cause);
|
|
119
163
|
}
|
|
@@ -121,31 +165,28 @@ var Res = class {
|
|
|
121
165
|
flatMapErr(f) {
|
|
122
166
|
if (this.tag !== "Err") return passThrough(this);
|
|
123
167
|
try {
|
|
124
|
-
|
|
168
|
+
const out = runMatch(f, this.error);
|
|
169
|
+
if (isDefectMarker(out)) return defectRes(out.cause);
|
|
170
|
+
if (!isResult(out)) return nonResultCallbackDefect();
|
|
171
|
+
return out;
|
|
125
172
|
} catch (cause) {
|
|
126
173
|
return defectRes(cause);
|
|
127
174
|
}
|
|
128
175
|
}
|
|
129
|
-
/** @deprecated Use {@link Res.flatMapErr}. */
|
|
130
|
-
orElse(f) {
|
|
131
|
-
return this.flatMapErr(f);
|
|
132
|
-
}
|
|
133
176
|
recoverErr(f) {
|
|
134
177
|
if (this.tag !== "Err") return passThrough(this);
|
|
135
178
|
try {
|
|
136
|
-
|
|
179
|
+
const out = runMatch(f, this.error);
|
|
180
|
+
if (isDefectMarker(out)) return defectRes(out.cause);
|
|
181
|
+
return okRes(out);
|
|
137
182
|
} catch (cause) {
|
|
138
183
|
return defectRes(cause);
|
|
139
184
|
}
|
|
140
185
|
}
|
|
141
|
-
/** @deprecated Use {@link Res.recoverErr}. */
|
|
142
|
-
recover(f) {
|
|
143
|
-
return this.recoverErr(f);
|
|
144
|
-
}
|
|
145
186
|
tapErr(f) {
|
|
146
187
|
if (this.tag !== "Err") return this;
|
|
147
188
|
try {
|
|
148
|
-
f
|
|
189
|
+
runMatch(f, this.error);
|
|
149
190
|
return this;
|
|
150
191
|
} catch (cause) {
|
|
151
192
|
return observerThrowToDefect(cause, this.error);
|
|
@@ -154,7 +195,8 @@ var Res = class {
|
|
|
154
195
|
flatTapErr(f) {
|
|
155
196
|
if (this.tag !== "Err") return this;
|
|
156
197
|
try {
|
|
157
|
-
const r = f
|
|
198
|
+
const r = runMatch(f, this.error);
|
|
199
|
+
if (!isResult(r)) return nonResultCallbackDefect();
|
|
158
200
|
return r.tag === "Ok" ? this : passThrough(r);
|
|
159
201
|
} catch (cause) {
|
|
160
202
|
return observerThrowToDefect(cause, this.error);
|
|
@@ -163,7 +205,8 @@ var Res = class {
|
|
|
163
205
|
recoverDefect(f) {
|
|
164
206
|
if (this.tag !== "Defect") return this;
|
|
165
207
|
try {
|
|
166
|
-
|
|
208
|
+
const r = f(this.cause);
|
|
209
|
+
return isResult(r) ? r : nonResultCallbackDefect();
|
|
167
210
|
} catch (cause) {
|
|
168
211
|
return defectRes(cause);
|
|
169
212
|
}
|
|
@@ -189,50 +232,34 @@ var Res = class {
|
|
|
189
232
|
match(cases) {
|
|
190
233
|
switch (this.tag) {
|
|
191
234
|
case "Ok": return cases.ok(this.value);
|
|
192
|
-
case "Err": return cases.err(this.error);
|
|
235
|
+
case "Err": return cases.err((0, ts_pattern.match)(this.error)).run();
|
|
193
236
|
case "Defect": return cases.defect(this.cause);
|
|
194
237
|
}
|
|
195
238
|
}
|
|
196
239
|
get() {
|
|
197
240
|
switch (this.tag) {
|
|
198
241
|
case "Ok": return this.value;
|
|
199
|
-
case "Err": throw new
|
|
242
|
+
case "Err": throw new GetError(this.error);
|
|
200
243
|
case "Defect": throw this.cause;
|
|
201
244
|
}
|
|
202
245
|
}
|
|
203
|
-
/** @deprecated Use {@link Res.get}. */
|
|
204
|
-
unwrap() {
|
|
205
|
-
return this.get();
|
|
206
|
-
}
|
|
207
246
|
getErr() {
|
|
208
247
|
switch (this.tag) {
|
|
209
248
|
case "Err": return this.error;
|
|
210
|
-
case "Ok": throw new
|
|
249
|
+
case "Ok": throw new GetError(this.value);
|
|
211
250
|
case "Defect": throw this.cause;
|
|
212
251
|
}
|
|
213
252
|
}
|
|
214
|
-
/** @deprecated Use {@link Res.getErr}. */
|
|
215
|
-
unwrapErr() {
|
|
216
|
-
return this.getErr();
|
|
217
|
-
}
|
|
218
253
|
getOr(fallback) {
|
|
219
254
|
if (this.tag === "Ok") return this.value;
|
|
220
255
|
if (this.tag === "Defect") throw this.cause;
|
|
221
256
|
return fallback;
|
|
222
257
|
}
|
|
223
|
-
/** @deprecated Use {@link Res.getOr}. */
|
|
224
|
-
unwrapOr(fallback) {
|
|
225
|
-
return this.getOr(fallback);
|
|
226
|
-
}
|
|
227
258
|
getOrElse(f) {
|
|
228
259
|
if (this.tag === "Ok") return this.value;
|
|
229
260
|
if (this.tag === "Defect") throw this.cause;
|
|
230
261
|
return f(this.error);
|
|
231
262
|
}
|
|
232
|
-
/** @deprecated Use {@link Res.getOrElse}. */
|
|
233
|
-
unwrapOrElse(f) {
|
|
234
|
-
return this.getOrElse(f);
|
|
235
|
-
}
|
|
236
263
|
getOrNull() {
|
|
237
264
|
if (this.tag === "Ok") return this.value;
|
|
238
265
|
if (this.tag === "Defect") throw this.cause;
|
|
@@ -260,7 +287,19 @@ var Res = class {
|
|
|
260
287
|
return new AsyncRes(Promise.resolve(this));
|
|
261
288
|
}
|
|
262
289
|
};
|
|
290
|
+
/**
|
|
291
|
+
* Cross-copy brand: `Symbol.for` yields the same symbol in every copy of the
|
|
292
|
+
* library (the dual CJS/ESM build, a duplicated install, another realm), so
|
|
293
|
+
* {@link isResult} can recognise a `Result` built by another copy whose `Res`
|
|
294
|
+
* class fails the `instanceof` check. Defined non-enumerably on the prototype,
|
|
295
|
+
* before it is frozen.
|
|
296
|
+
*
|
|
297
|
+
* @internal
|
|
298
|
+
*/
|
|
299
|
+
const RESULT_BRAND = Symbol.for("unthrown.Result");
|
|
263
300
|
const RESULT_PROTO = Res.prototype;
|
|
301
|
+
Object.defineProperty(RESULT_PROTO, RESULT_BRAND, { value: true });
|
|
302
|
+
Object.freeze(RESULT_PROTO);
|
|
264
303
|
/**
|
|
265
304
|
* Construct an `Ok` result — a plain object on the {@link Res} prototype.
|
|
266
305
|
*
|
|
@@ -300,9 +339,12 @@ function defectRes(cause) {
|
|
|
300
339
|
* @remarks
|
|
301
340
|
* Unlike {@link isOk} / {@link isErr} / {@link isDefect}, which narrow a value
|
|
302
341
|
* already known to be a `Result`, this narrows from `unknown` — useful at an
|
|
303
|
-
* untyped boundary. It checks the value carries the `Result` prototype
|
|
304
|
-
*
|
|
305
|
-
*
|
|
342
|
+
* untyped boundary. It checks the value carries the `Result` prototype
|
|
343
|
+
* (`instanceof` first, falling back to the `Symbol.for("unthrown.Result")`
|
|
344
|
+
* brand the prototype carries — so a `Result` built by **another copy** of
|
|
345
|
+
* unthrown, e.g. the CJS and ESM builds loaded side by side, is still
|
|
346
|
+
* recognised). A look-alike plain object (`{ tag: "Ok" }`) carries neither and
|
|
347
|
+
* is **not** matched. An `AsyncResult` is not a `Result` and returns `false`.
|
|
306
348
|
*
|
|
307
349
|
* @returns `true` when `x` is a `Result` produced by this library.
|
|
308
350
|
*
|
|
@@ -321,7 +363,12 @@ function defectRes(cause) {
|
|
|
321
363
|
* @category Guards
|
|
322
364
|
*/
|
|
323
365
|
function isResult(x) {
|
|
324
|
-
|
|
366
|
+
if (x instanceof Res) return true;
|
|
367
|
+
try {
|
|
368
|
+
return (typeof x === "object" || typeof x === "function") && x !== null && Reflect.get(x, RESULT_BRAND) === true;
|
|
369
|
+
} catch {
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
325
372
|
}
|
|
326
373
|
/**
|
|
327
374
|
* Reuse a non-matching variant (an `Err` or `Defect`) as a differently-typed
|
|
@@ -337,6 +384,32 @@ function passThrough(self) {
|
|
|
337
384
|
return self;
|
|
338
385
|
}
|
|
339
386
|
/**
|
|
387
|
+
* The Defect minted when a callback constrained to return a `Result` returns
|
|
388
|
+
* something else — reachable only from untyped/cast callers (in typed code the
|
|
389
|
+
* constraint is a compile error). The combinator-side sibling of the
|
|
390
|
+
* aggregates' non-`Result`-element guard: surface the out-of-contract value as
|
|
391
|
+
* a `Defect` here rather than letting a poison value throw a raw `TypeError`
|
|
392
|
+
* further down the pipeline.
|
|
393
|
+
*
|
|
394
|
+
* @internal
|
|
395
|
+
*/
|
|
396
|
+
function nonResultCallbackDefect() {
|
|
397
|
+
return defectRes(/* @__PURE__ */ new TypeError("unthrown: a combinator callback returned a non-Result value"));
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Drive an error-combinator callback: build `match(error)`, hand it (plus the
|
|
401
|
+
* injected `defect`) to the callback, and `.run()` the returned exhaustive
|
|
402
|
+
* builder to its output. `.run()` executes `.exhaustive()` — type-forced
|
|
403
|
+
* exhaustive, so it always matches for well-typed callers; a value that slips
|
|
404
|
+
* through the types (a widened cast, a JS caller) throws `NonExhaustiveError`,
|
|
405
|
+
* which the caller's `try/catch` turns into a `Defect` — an unmodeled failure.
|
|
406
|
+
*
|
|
407
|
+
* @internal
|
|
408
|
+
*/
|
|
409
|
+
function runMatch(f, error) {
|
|
410
|
+
return f((0, ts_pattern.match)(error), defect).run();
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
340
413
|
* A throw inside a *failure observer* (`tapErr` / `tapDefect` / `flatTapErr`)
|
|
341
414
|
* must not destroy the failure being observed — that is the exact place (e.g. a
|
|
342
415
|
* failing error-logger) where losing the underlying failure hurts most. The
|
|
@@ -378,15 +451,15 @@ function scopeOf(value) {
|
|
|
378
451
|
* @internal
|
|
379
452
|
*/
|
|
380
453
|
var AsyncRes = class AsyncRes {
|
|
381
|
-
promise;
|
|
454
|
+
#promise;
|
|
382
455
|
constructor(promise) {
|
|
383
|
-
this
|
|
456
|
+
this.#promise = promise;
|
|
384
457
|
}
|
|
385
458
|
then(onfulfilled, onrejected) {
|
|
386
|
-
return this
|
|
459
|
+
return this.#promise.then(onfulfilled, onrejected);
|
|
387
460
|
}
|
|
388
461
|
map(f) {
|
|
389
|
-
return new AsyncRes(this
|
|
462
|
+
return new AsyncRes(this.#promise.then((r) => {
|
|
390
463
|
if (r.tag !== "Ok") return passThrough(r);
|
|
391
464
|
try {
|
|
392
465
|
return okRes(f(r.value));
|
|
@@ -396,17 +469,18 @@ var AsyncRes = class AsyncRes {
|
|
|
396
469
|
}));
|
|
397
470
|
}
|
|
398
471
|
flatMap(f) {
|
|
399
|
-
return new AsyncRes(this
|
|
472
|
+
return new AsyncRes(this.#promise.then(async (r) => {
|
|
400
473
|
if (r.tag !== "Ok") return passThrough(r);
|
|
401
474
|
try {
|
|
402
|
-
|
|
475
|
+
const inner = await f(r.value);
|
|
476
|
+
return isResult(inner) ? inner : nonResultCallbackDefect();
|
|
403
477
|
} catch (cause) {
|
|
404
478
|
return defectRes(cause);
|
|
405
479
|
}
|
|
406
480
|
}));
|
|
407
481
|
}
|
|
408
482
|
tap(f) {
|
|
409
|
-
return new AsyncRes(this
|
|
483
|
+
return new AsyncRes(this.#promise.then((r) => {
|
|
410
484
|
if (r.tag !== "Ok") return r;
|
|
411
485
|
try {
|
|
412
486
|
f(r.value);
|
|
@@ -417,10 +491,11 @@ var AsyncRes = class AsyncRes {
|
|
|
417
491
|
}));
|
|
418
492
|
}
|
|
419
493
|
flatTap(f) {
|
|
420
|
-
return new AsyncRes(this
|
|
494
|
+
return new AsyncRes(this.#promise.then(async (r) => {
|
|
421
495
|
if (r.tag !== "Ok") return passThrough(r);
|
|
422
496
|
try {
|
|
423
497
|
const inner = await f(r.value);
|
|
498
|
+
if (!isResult(inner)) return nonResultCallbackDefect();
|
|
424
499
|
return inner.tag === "Ok" ? r : passThrough(inner);
|
|
425
500
|
} catch (cause) {
|
|
426
501
|
return defectRes(cause);
|
|
@@ -428,10 +503,11 @@ var AsyncRes = class AsyncRes {
|
|
|
428
503
|
}));
|
|
429
504
|
}
|
|
430
505
|
bind(name, f) {
|
|
431
|
-
return new AsyncRes(this
|
|
506
|
+
return new AsyncRes(this.#promise.then(async (r) => {
|
|
432
507
|
if (r.tag !== "Ok") return passThrough(r);
|
|
433
508
|
try {
|
|
434
509
|
const inner = await f(r.value);
|
|
510
|
+
if (!isResult(inner)) return nonResultCallbackDefect();
|
|
435
511
|
if (inner.tag !== "Ok") return passThrough(inner);
|
|
436
512
|
return okRes({
|
|
437
513
|
...scopeOf(r.value),
|
|
@@ -443,7 +519,7 @@ var AsyncRes = class AsyncRes {
|
|
|
443
519
|
}));
|
|
444
520
|
}
|
|
445
521
|
let(name, f) {
|
|
446
|
-
return new AsyncRes(this
|
|
522
|
+
return new AsyncRes(this.#promise.then((r) => {
|
|
447
523
|
if (r.tag !== "Ok") return passThrough(r);
|
|
448
524
|
try {
|
|
449
525
|
return okRes({
|
|
@@ -456,54 +532,64 @@ var AsyncRes = class AsyncRes {
|
|
|
456
532
|
}));
|
|
457
533
|
}
|
|
458
534
|
as(value) {
|
|
459
|
-
return new AsyncRes(this
|
|
535
|
+
return new AsyncRes(this.#promise.then((r) => r.tag === "Ok" ? okRes(value) : passThrough(r)));
|
|
460
536
|
}
|
|
461
537
|
discard() {
|
|
462
|
-
return new AsyncRes(this
|
|
538
|
+
return new AsyncRes(this.#promise.then((r) => r.tag === "Ok" ? okRes(void 0) : passThrough(r)));
|
|
539
|
+
}
|
|
540
|
+
ensure(predicate, onFail) {
|
|
541
|
+
return new AsyncRes(this.#promise.then((r) => {
|
|
542
|
+
if (r.tag !== "Ok") return passThrough(r);
|
|
543
|
+
try {
|
|
544
|
+
return predicate(r.value) ? r : errRes(onFail(r.value));
|
|
545
|
+
} catch (cause) {
|
|
546
|
+
return defectRes(cause);
|
|
547
|
+
}
|
|
548
|
+
}));
|
|
463
549
|
}
|
|
464
550
|
mapErr(f) {
|
|
465
|
-
return new AsyncRes(this
|
|
551
|
+
return new AsyncRes(this.#promise.then((r) => {
|
|
466
552
|
if (r.tag !== "Err") return passThrough(r);
|
|
467
553
|
try {
|
|
468
|
-
|
|
554
|
+
const out = runMatch(f, r.error);
|
|
555
|
+
if (isDefectMarker(out)) return defectRes(out.cause);
|
|
556
|
+
return errRes(out);
|
|
469
557
|
} catch (cause) {
|
|
470
558
|
return defectRes(cause);
|
|
471
559
|
}
|
|
472
560
|
}));
|
|
473
561
|
}
|
|
474
562
|
flatMapErr(f) {
|
|
475
|
-
return new AsyncRes(this
|
|
563
|
+
return new AsyncRes(this.#promise.then(async (r) => {
|
|
476
564
|
if (r.tag !== "Err") return passThrough(r);
|
|
477
565
|
try {
|
|
478
|
-
|
|
566
|
+
const out = runMatch(f, r.error);
|
|
567
|
+
if (isDefectMarker(out)) return defectRes(out.cause);
|
|
568
|
+
const inner = await out;
|
|
569
|
+
if (!isResult(inner)) return nonResultCallbackDefect();
|
|
570
|
+
return inner;
|
|
479
571
|
} catch (cause) {
|
|
480
572
|
return defectRes(cause);
|
|
481
573
|
}
|
|
482
574
|
}));
|
|
483
575
|
}
|
|
484
|
-
/** @deprecated Use {@link AsyncRes.flatMapErr}. */
|
|
485
|
-
orElse(f) {
|
|
486
|
-
return this.flatMapErr(f);
|
|
487
|
-
}
|
|
488
576
|
recoverErr(f) {
|
|
489
|
-
return new AsyncRes(this
|
|
577
|
+
return new AsyncRes(this.#promise.then((r) => {
|
|
490
578
|
if (r.tag !== "Err") return passThrough(r);
|
|
491
579
|
try {
|
|
492
|
-
|
|
580
|
+
const out = runMatch(f, r.error);
|
|
581
|
+
if (isDefectMarker(out)) return defectRes(out.cause);
|
|
582
|
+
return okRes(out);
|
|
493
583
|
} catch (cause) {
|
|
494
584
|
return defectRes(cause);
|
|
495
585
|
}
|
|
496
586
|
}));
|
|
497
587
|
}
|
|
498
|
-
/** @deprecated Use {@link AsyncRes.recoverErr}. */
|
|
499
|
-
recover(f) {
|
|
500
|
-
return this.recoverErr(f);
|
|
501
|
-
}
|
|
502
588
|
tapErr(f) {
|
|
503
|
-
return new AsyncRes(this
|
|
589
|
+
return new AsyncRes(this.#promise.then((r) => {
|
|
504
590
|
if (r.tag !== "Err") return r;
|
|
505
591
|
try {
|
|
506
|
-
f
|
|
592
|
+
runMatch(f, r.error);
|
|
507
593
|
return r;
|
|
508
594
|
} catch (cause) {
|
|
509
595
|
return observerThrowToDefect(cause, r.error);
|
|
@@ -511,10 +597,11 @@ var AsyncRes = class AsyncRes {
|
|
|
511
597
|
}));
|
|
512
598
|
}
|
|
513
599
|
flatTapErr(f) {
|
|
514
|
-
return new AsyncRes(this
|
|
600
|
+
return new AsyncRes(this.#promise.then(async (r) => {
|
|
515
601
|
if (r.tag !== "Err") return passThrough(r);
|
|
516
602
|
try {
|
|
517
|
-
const inner = await f
|
|
603
|
+
const inner = await runMatch(f, r.error);
|
|
604
|
+
if (!isResult(inner)) return nonResultCallbackDefect();
|
|
518
605
|
return inner.tag === "Ok" ? passThrough(r) : passThrough(inner);
|
|
519
606
|
} catch (cause) {
|
|
520
607
|
return observerThrowToDefect(cause, r.error);
|
|
@@ -522,17 +609,18 @@ var AsyncRes = class AsyncRes {
|
|
|
522
609
|
}));
|
|
523
610
|
}
|
|
524
611
|
recoverDefect(f) {
|
|
525
|
-
return new AsyncRes(this
|
|
612
|
+
return new AsyncRes(this.#promise.then(async (r) => {
|
|
526
613
|
if (r.tag !== "Defect") return r;
|
|
527
614
|
try {
|
|
528
|
-
|
|
615
|
+
const inner = await f(r.cause);
|
|
616
|
+
return isResult(inner) ? inner : nonResultCallbackDefect();
|
|
529
617
|
} catch (cause) {
|
|
530
618
|
return defectRes(cause);
|
|
531
619
|
}
|
|
532
620
|
}));
|
|
533
621
|
}
|
|
534
622
|
tapDefect(f) {
|
|
535
|
-
return new AsyncRes(this
|
|
623
|
+
return new AsyncRes(this.#promise.then((r) => {
|
|
536
624
|
if (r.tag !== "Defect") return r;
|
|
537
625
|
try {
|
|
538
626
|
f(r.cause);
|
|
@@ -543,7 +631,7 @@ var AsyncRes = class AsyncRes {
|
|
|
543
631
|
}));
|
|
544
632
|
}
|
|
545
633
|
tapFailure(f) {
|
|
546
|
-
return new AsyncRes(this
|
|
634
|
+
return new AsyncRes(this.#promise.then((r) => {
|
|
547
635
|
if (r.tag === "Ok") return r;
|
|
548
636
|
try {
|
|
549
637
|
f(r);
|
|
@@ -554,46 +642,31 @@ var AsyncRes = class AsyncRes {
|
|
|
554
642
|
}));
|
|
555
643
|
}
|
|
556
644
|
match(cases) {
|
|
557
|
-
return this
|
|
645
|
+
return this.#promise.then((r) => r.match(cases));
|
|
558
646
|
}
|
|
559
647
|
get() {
|
|
560
|
-
return this
|
|
561
|
-
}
|
|
562
|
-
/** @deprecated Use {@link AsyncRes.get}. */
|
|
563
|
-
unwrap() {
|
|
564
|
-
return this.get();
|
|
648
|
+
return this.#promise.then((r) => r.get());
|
|
565
649
|
}
|
|
566
650
|
getErr() {
|
|
567
|
-
return this
|
|
568
|
-
}
|
|
569
|
-
/** @deprecated Use {@link AsyncRes.getErr}. */
|
|
570
|
-
unwrapErr() {
|
|
571
|
-
return this.getErr();
|
|
651
|
+
return this.#promise.then((r) => r.getErr());
|
|
572
652
|
}
|
|
573
653
|
getOr(fallback) {
|
|
574
|
-
return this
|
|
575
|
-
}
|
|
576
|
-
/** @deprecated Use {@link AsyncRes.getOr}. */
|
|
577
|
-
unwrapOr(fallback) {
|
|
578
|
-
return this.getOr(fallback);
|
|
654
|
+
return this.#promise.then((r) => r.getOr(fallback));
|
|
579
655
|
}
|
|
580
656
|
getOrElse(f) {
|
|
581
|
-
return this
|
|
582
|
-
}
|
|
583
|
-
/** @deprecated Use {@link AsyncRes.getOrElse}. */
|
|
584
|
-
unwrapOrElse(f) {
|
|
585
|
-
return this.getOrElse(f);
|
|
657
|
+
return this.#promise.then((r) => r.getOrElse(f));
|
|
586
658
|
}
|
|
587
659
|
getOrNull() {
|
|
588
|
-
return this
|
|
660
|
+
return this.#promise.then((r) => r.getOrNull());
|
|
589
661
|
}
|
|
590
662
|
getOrUndefined() {
|
|
591
|
-
return this
|
|
663
|
+
return this.#promise.then((r) => r.getOrUndefined());
|
|
592
664
|
}
|
|
593
665
|
getOrThrow() {
|
|
594
|
-
return this
|
|
666
|
+
return this.#promise.then((r) => r.getOrThrow());
|
|
595
667
|
}
|
|
596
668
|
};
|
|
669
|
+
Object.freeze(AsyncRes.prototype);
|
|
597
670
|
//#endregion
|
|
598
671
|
//#region src/constructors.ts
|
|
599
672
|
function Ok(value) {
|
|
@@ -759,35 +832,32 @@ function isDefect(r) {
|
|
|
759
832
|
function Do() {
|
|
760
833
|
return Ok({});
|
|
761
834
|
}
|
|
762
|
-
//#endregion
|
|
763
|
-
//#region src/defect.ts
|
|
764
|
-
const DEFECT = Symbol("unthrown/Defect");
|
|
765
835
|
/**
|
|
766
|
-
*
|
|
767
|
-
*
|
|
768
|
-
* (`fromPromise` / `fromThrowable`) passes this in as `qualify`'s second
|
|
769
|
-
* argument, so domain code never imports it.
|
|
836
|
+
* Start an **asynchronous** do-notation chain with an empty object scope — the
|
|
837
|
+
* pre-lifted form of {@link Do}, sparing you `Do().toAsync()`.
|
|
770
838
|
*
|
|
771
|
-
* @
|
|
772
|
-
*
|
|
839
|
+
* @remarks
|
|
840
|
+
* From here a `bind` may return a `Result` **or** an `AsyncResult`; the scope
|
|
841
|
+
* accumulates exactly as in a sync {@link Do} chain, and a throw in any step
|
|
842
|
+
* becomes a `Defect`. Named with the `Async` suffix the async free functions
|
|
843
|
+
* carry (`OkAsync`, `allAsync`); the {@link AsyncResult} companion aliases it as
|
|
844
|
+
* `AsyncResult.Do` (the namespace already says "async", so the suffix drops).
|
|
773
845
|
*
|
|
774
|
-
* @
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
return {
|
|
778
|
-
[DEFECT]: true,
|
|
779
|
-
cause
|
|
780
|
-
};
|
|
781
|
-
}
|
|
782
|
-
/**
|
|
783
|
-
* Internal guard for the qualify-time marker. Distinct from the public
|
|
784
|
-
* {@link isDefect} state guard — this one narrows the `E | Defect` union a
|
|
785
|
-
* `qualify` function returns, not a `Result`.
|
|
846
|
+
* @example
|
|
847
|
+
* ```ts
|
|
848
|
+
* import { DoAsync, Ok } from "unthrown";
|
|
786
849
|
*
|
|
787
|
-
*
|
|
850
|
+
* const result = await DoAsync()
|
|
851
|
+
* .bind("user", () => findUser(id)) // AsyncResult<User, NotFound>
|
|
852
|
+
* .bind("plan", ({ user }) => Ok(user.plan)) // a sync Result is accepted too
|
|
853
|
+
* .let("label", ({ user, plan }) => `${user.name} on ${plan}`);
|
|
854
|
+
* // Result<{ user: User; plan: Plan; label: string }, NotFound>
|
|
855
|
+
* ```
|
|
856
|
+
*
|
|
857
|
+
* @category Do-notation
|
|
788
858
|
*/
|
|
789
|
-
function
|
|
790
|
-
return
|
|
859
|
+
function DoAsync() {
|
|
860
|
+
return Do().toAsync();
|
|
791
861
|
}
|
|
792
862
|
//#endregion
|
|
793
863
|
//#region src/interop.ts
|
|
@@ -827,7 +897,10 @@ function fromNullable(value, onAbsent) {
|
|
|
827
897
|
* `qualify` **must** triage every thrown cause into a modeled error `E` or a
|
|
828
898
|
* `Defect` (via the injected `defect` helper, its second argument) — there is no
|
|
829
899
|
* path that leaves `unknown` in `E`. A throw inside `qualify` itself is treated
|
|
830
|
-
* as a `Defect`.
|
|
900
|
+
* as a `Defect`. `qualify` is **synchronous**: an `async` qualify is rejected at
|
|
901
|
+
* compile time ({@link NotThenable}) — its `Promise` would land in `E` un-triaged
|
|
902
|
+
* — and a thenable slipped past the types at runtime becomes a `Defect` (never
|
|
903
|
+
* an `Err(Promise)`), its orphaned rejection silenced.
|
|
831
904
|
*
|
|
832
905
|
* The modeled error type is `Exclude<R, Defect>` — the `Defect` arm of
|
|
833
906
|
* `qualify`'s return is **subtracted** from `E`, never inferred into it. So a
|
|
@@ -917,7 +990,10 @@ function fromSafeThrowable(fn) {
|
|
|
917
990
|
* `qualify` **must** map each rejection cause into a modeled error `E` or a
|
|
918
991
|
* `Defect` (via the injected `defect` helper, its second argument). The returned
|
|
919
992
|
* `AsyncResult`'s internal promise never rejects; `await`-ing it always yields a
|
|
920
|
-
* `Result`. A throw inside `qualify` is itself a `Defect`.
|
|
993
|
+
* `Result`. A throw inside `qualify` is itself a `Defect`. `qualify` is
|
|
994
|
+
* **synchronous**: an `async` qualify is rejected at compile time
|
|
995
|
+
* ({@link NotThenable}), and a thenable slipped past the types at runtime
|
|
996
|
+
* becomes a `Defect` (never an `Err(Promise)`), its orphaned rejection silenced.
|
|
921
997
|
*
|
|
922
998
|
* The modeled error type is `Exclude<R, Defect>` — the `Defect` arm of
|
|
923
999
|
* `qualify`'s return is **subtracted** from `E`, never inferred into it. So a
|
|
@@ -980,26 +1056,50 @@ function fromSafePromise(promise) {
|
|
|
980
1056
|
function qualifyToResult(cause, qualify) {
|
|
981
1057
|
try {
|
|
982
1058
|
const q = qualify(cause, defect);
|
|
983
|
-
|
|
1059
|
+
if (isDefectMarker(q)) return defectRes(q.cause);
|
|
1060
|
+
if (isThenable(q)) {
|
|
1061
|
+
Promise.resolve(q).then(void 0, () => void 0);
|
|
1062
|
+
return defectRes(/* @__PURE__ */ new TypeError("unthrown: qualify must be synchronous — it returned a thenable; triage the cause without awaiting"));
|
|
1063
|
+
}
|
|
1064
|
+
return errRes(q);
|
|
984
1065
|
} catch (qErr) {
|
|
985
1066
|
return defectRes(qErr);
|
|
986
1067
|
}
|
|
987
1068
|
}
|
|
988
1069
|
/**
|
|
1070
|
+
* Runtime thenable probe for the belt-and-braces guard above. Called inside the
|
|
1071
|
+
* caller's `try`, so even a hostile `.then` getter lands on the Defect path.
|
|
1072
|
+
*
|
|
1073
|
+
* @internal
|
|
1074
|
+
*/
|
|
1075
|
+
function isThenable(x) {
|
|
1076
|
+
return (typeof x === "object" || typeof x === "function") && x !== null && typeof x.then === "function";
|
|
1077
|
+
}
|
|
1078
|
+
/**
|
|
989
1079
|
* Fold an array of settled `Result`s: first `Err` wins, any `Defect` dominates,
|
|
990
1080
|
* else `Ok` of the values array.
|
|
991
1081
|
*
|
|
992
1082
|
* @internal
|
|
993
1083
|
*/
|
|
1084
|
+
/** The Defect minted for an out-of-contract non-`Result` element in an aggregate. */
|
|
1085
|
+
function nonResultDefect() {
|
|
1086
|
+
return defectRes(/* @__PURE__ */ new TypeError("unthrown: aggregate received a non-Result element"));
|
|
1087
|
+
}
|
|
994
1088
|
function foldArray(results) {
|
|
995
1089
|
let firstErr;
|
|
996
1090
|
let firstDefect;
|
|
997
1091
|
const values = [];
|
|
998
|
-
for (const r of results)
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1092
|
+
for (const r of results) {
|
|
1093
|
+
if (!isResult(r)) {
|
|
1094
|
+
firstDefect ??= nonResultDefect();
|
|
1095
|
+
break;
|
|
1096
|
+
}
|
|
1097
|
+
if (r.tag === "Defect") {
|
|
1098
|
+
firstDefect ??= r;
|
|
1099
|
+
break;
|
|
1100
|
+
} else if (r.tag === "Err") firstErr ??= r;
|
|
1101
|
+
else values.push(r.value);
|
|
1102
|
+
}
|
|
1003
1103
|
return firstDefect ?? firstErr ?? Ok(values);
|
|
1004
1104
|
}
|
|
1005
1105
|
/**
|
|
@@ -1013,16 +1113,22 @@ function foldRecord(results) {
|
|
|
1013
1113
|
let firstErr;
|
|
1014
1114
|
let firstDefect;
|
|
1015
1115
|
const values = {};
|
|
1016
|
-
for (const [key, r] of Object.entries(results))
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1116
|
+
for (const [key, r] of Object.entries(results)) {
|
|
1117
|
+
if (!isResult(r)) {
|
|
1118
|
+
firstDefect ??= nonResultDefect();
|
|
1119
|
+
break;
|
|
1120
|
+
}
|
|
1121
|
+
if (r.tag === "Defect") {
|
|
1122
|
+
firstDefect ??= r;
|
|
1123
|
+
break;
|
|
1124
|
+
} else if (r.tag === "Err") firstErr ??= r;
|
|
1125
|
+
else Object.defineProperty(values, key, {
|
|
1126
|
+
value: r.value,
|
|
1127
|
+
enumerable: true,
|
|
1128
|
+
writable: true,
|
|
1129
|
+
configurable: true
|
|
1130
|
+
});
|
|
1131
|
+
}
|
|
1026
1132
|
return firstDefect ?? firstErr ?? Ok(values);
|
|
1027
1133
|
}
|
|
1028
1134
|
/**
|
|
@@ -1094,7 +1200,7 @@ function allFromDict(results) {
|
|
|
1094
1200
|
* ```
|
|
1095
1201
|
*/
|
|
1096
1202
|
function allAsync(results) {
|
|
1097
|
-
return new AsyncRes(Promise.all(results).then((resolved) => foldArray(resolved)));
|
|
1203
|
+
return new AsyncRes(Promise.all(results.map((r) => Promise.resolve(r).then((x) => x, (cause) => defectRes(cause)))).then((resolved) => foldArray(resolved)));
|
|
1098
1204
|
}
|
|
1099
1205
|
/**
|
|
1100
1206
|
* The asynchronous counterpart of {@link allFromDict}: combine a record of
|
|
@@ -1119,7 +1225,7 @@ function allAsync(results) {
|
|
|
1119
1225
|
*/
|
|
1120
1226
|
function allFromDictAsync(results) {
|
|
1121
1227
|
const entries = Object.entries(results);
|
|
1122
|
-
return new AsyncRes(Promise.all(entries.map(([, ar]) => ar)).then((resolved) => {
|
|
1228
|
+
return new AsyncRes(Promise.all(entries.map(([, ar]) => Promise.resolve(ar).then((x) => x, (cause) => defectRes(cause)))).then((resolved) => {
|
|
1123
1229
|
const byKey = Object.create(null);
|
|
1124
1230
|
entries.forEach(([key], i) => {
|
|
1125
1231
|
byKey[key] = resolved[i];
|
|
@@ -1172,8 +1278,9 @@ const Result = {
|
|
|
1172
1278
|
/**
|
|
1173
1279
|
* Companion object grouping the **`AsyncResult`-producing** entry points under
|
|
1174
1280
|
* the matching namespace: {@link AsyncResult.Ok}, {@link AsyncResult.Err},
|
|
1175
|
-
* {@link AsyncResult.
|
|
1176
|
-
* {@link AsyncResult.
|
|
1281
|
+
* {@link AsyncResult.Do}, {@link AsyncResult.fromPromise},
|
|
1282
|
+
* {@link AsyncResult.fromSafePromise}, {@link AsyncResult.all},
|
|
1283
|
+
* {@link AsyncResult.allFromDict}.
|
|
1177
1284
|
*
|
|
1178
1285
|
* @remarks
|
|
1179
1286
|
* The async sibling of {@link Result}. Statics are grouped by what they
|
|
@@ -1181,7 +1288,8 @@ const Result = {
|
|
|
1181
1288
|
* and the async aggregates sit here rather than on {@link Result}; the namespace
|
|
1182
1289
|
* already conveys "async", so the members drop the `Async` suffix their free
|
|
1183
1290
|
* functions carry (`AsyncResult.Ok` is `OkAsync`; `AsyncResult.Err` is
|
|
1184
|
-
* `ErrAsync`; `AsyncResult.
|
|
1291
|
+
* `ErrAsync`; `AsyncResult.Do` is `DoAsync`; `AsyncResult.all` is `allAsync`;
|
|
1292
|
+
* `AsyncResult.allFromDict` is
|
|
1185
1293
|
* `allFromDictAsync`). Like {@link Result}, the free functions remain the
|
|
1186
1294
|
* primary, tree-shakeable API; the value `AsyncResult` and the type
|
|
1187
1295
|
* {@link AsyncResult} share one name.
|
|
@@ -1198,6 +1306,7 @@ const Result = {
|
|
|
1198
1306
|
const AsyncResult = {
|
|
1199
1307
|
Ok: OkAsync,
|
|
1200
1308
|
Err: ErrAsync,
|
|
1309
|
+
Do: DoAsync,
|
|
1201
1310
|
fromPromise,
|
|
1202
1311
|
fromSafePromise,
|
|
1203
1312
|
all: allAsync,
|
|
@@ -1221,10 +1330,16 @@ const AsyncResult = {
|
|
|
1221
1330
|
* `tag` and cannot be overridden by the payload. `name` is likewise reserved —
|
|
1222
1331
|
* it is the display label (set it with `options.name`); a payload `name` is
|
|
1223
1332
|
* rejected at compile time (and excluded from the instance type), so it can't
|
|
1224
|
-
* shadow `Error.name`.
|
|
1225
|
-
*
|
|
1226
|
-
* `
|
|
1227
|
-
*
|
|
1333
|
+
* shadow `Error.name`. `stack` is reserved the same way — it is `Error`'s
|
|
1334
|
+
* trace, and even an untyped payload `stack` cannot clobber the real one.
|
|
1335
|
+
* `cause` is deliberately **not** reserved: `Error.cause` is typed `unknown`,
|
|
1336
|
+
* so a payload `cause` (e.g. a wrapped driver error) is a legitimate,
|
|
1337
|
+
* *narrowing* structured field.
|
|
1338
|
+
*
|
|
1339
|
+
* `_tag` is the discriminant matched by {@link tag} in the error combinators
|
|
1340
|
+
* (`result.mapErr((matcher) => matcher.with(tag("NotFound"), …))`) and in
|
|
1341
|
+
* `match`; `Error.name` is the human-facing label in stack traces and logs. By
|
|
1342
|
+
* default they coincide, but
|
|
1228
1343
|
* they can be **decoupled** with `options.name` — so a tag can be namespaced for
|
|
1229
1344
|
* collision-safety (`"@my-lib/RetryableError"`) without that slash-prefixed
|
|
1230
1345
|
* string leaking into `Error.name`:
|
|
@@ -1264,7 +1379,17 @@ function TaggedError(tag, options) {
|
|
|
1264
1379
|
_tag;
|
|
1265
1380
|
constructor(props) {
|
|
1266
1381
|
super();
|
|
1267
|
-
if (props)
|
|
1382
|
+
if (props) {
|
|
1383
|
+
const stack = this.stack;
|
|
1384
|
+
Object.assign(this, props);
|
|
1385
|
+
delete this.stack;
|
|
1386
|
+
if (stack !== void 0) Object.defineProperty(this, "stack", {
|
|
1387
|
+
value: stack,
|
|
1388
|
+
writable: true,
|
|
1389
|
+
enumerable: false,
|
|
1390
|
+
configurable: true
|
|
1391
|
+
});
|
|
1392
|
+
}
|
|
1268
1393
|
this._tag = tag;
|
|
1269
1394
|
this.name = displayName;
|
|
1270
1395
|
delete this.message;
|
|
@@ -1273,28 +1398,46 @@ function TaggedError(tag, options) {
|
|
|
1273
1398
|
}
|
|
1274
1399
|
return TaggedErrorBase;
|
|
1275
1400
|
}
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1401
|
+
/**
|
|
1402
|
+
* A `ts-pattern` pattern matching any value whose `_tag` equals `value` — a
|
|
1403
|
+
* {@link TaggedError}, or any discriminated member. Equivalent to the object
|
|
1404
|
+
* pattern `{ _tag: value }`, but reads better inside an error-matching
|
|
1405
|
+
* combinator and narrows to the matching variant, payload included.
|
|
1406
|
+
*
|
|
1407
|
+
* @typeParam Tag - the string literal tag to match.
|
|
1408
|
+
* @param value - the `_tag` to match.
|
|
1409
|
+
*
|
|
1410
|
+
* @category Tagged errors
|
|
1411
|
+
*
|
|
1412
|
+
* @example
|
|
1413
|
+
* ```ts
|
|
1414
|
+
* result.mapErr((matcher) =>
|
|
1415
|
+
* matcher
|
|
1416
|
+
* .with(tag("NotFound"), () => new NotFoundException())
|
|
1417
|
+
* .with(tag("Conflict"), (e) => new ConflictException(e.key)),
|
|
1418
|
+
* );
|
|
1419
|
+
* ```
|
|
1420
|
+
*/
|
|
1421
|
+
function tag(value) {
|
|
1422
|
+
return { _tag: value };
|
|
1287
1423
|
}
|
|
1288
1424
|
//#endregion
|
|
1289
1425
|
exports.AsyncResult = AsyncResult;
|
|
1290
1426
|
exports.Do = Do;
|
|
1427
|
+
exports.DoAsync = DoAsync;
|
|
1291
1428
|
exports.Err = Err;
|
|
1292
1429
|
exports.ErrAsync = ErrAsync;
|
|
1430
|
+
exports.GetError = GetError;
|
|
1293
1431
|
exports.Ok = Ok;
|
|
1294
1432
|
exports.OkAsync = OkAsync;
|
|
1433
|
+
Object.defineProperty(exports, "P", {
|
|
1434
|
+
enumerable: true,
|
|
1435
|
+
get: function() {
|
|
1436
|
+
return ts_pattern.P;
|
|
1437
|
+
}
|
|
1438
|
+
});
|
|
1295
1439
|
exports.Result = Result;
|
|
1296
1440
|
exports.TaggedError = TaggedError;
|
|
1297
|
-
exports.UnwrapError = UnwrapError;
|
|
1298
1441
|
exports.all = all;
|
|
1299
1442
|
exports.allAsync = allAsync;
|
|
1300
1443
|
exports.allFromDict = allFromDict;
|
|
@@ -1308,4 +1451,10 @@ exports.isDefect = isDefect;
|
|
|
1308
1451
|
exports.isErr = isErr;
|
|
1309
1452
|
exports.isOk = isOk;
|
|
1310
1453
|
exports.isResult = isResult;
|
|
1311
|
-
exports
|
|
1454
|
+
Object.defineProperty(exports, "match", {
|
|
1455
|
+
enumerable: true,
|
|
1456
|
+
get: function() {
|
|
1457
|
+
return ts_pattern.match;
|
|
1458
|
+
}
|
|
1459
|
+
});
|
|
1460
|
+
exports.tag = tag;
|