unthrown 0.3.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.cjs +172 -56
- package/dist/index.d.cts +128 -45
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +128 -45
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +169 -54
- package/dist/index.mjs.map +1 -1
- package/docs/index.md +161 -119
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -11,10 +11,10 @@ pnpm add unthrown
|
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
|
-
import {
|
|
14
|
+
import { Ok, Err, fromPromise, Defect, type Result } from "unthrown";
|
|
15
15
|
|
|
16
16
|
const user = fromPromise(fetchUser(id), (cause) =>
|
|
17
|
-
cause instanceof NotFoundError ? new NotFound() :
|
|
17
|
+
cause instanceof NotFoundError ? new NotFound() : Defect(cause),
|
|
18
18
|
);
|
|
19
19
|
|
|
20
20
|
const status = await user.match({
|
package/dist/index.cjs
CHANGED
|
@@ -33,7 +33,7 @@ var UnwrapError = class extends Error {
|
|
|
33
33
|
*/
|
|
34
34
|
var Res = class {
|
|
35
35
|
map(f) {
|
|
36
|
-
if (this.tag !== "Ok") return this;
|
|
36
|
+
if (this.tag !== "Ok") return passThrough(this);
|
|
37
37
|
try {
|
|
38
38
|
return okRes(f(this.value));
|
|
39
39
|
} catch (cause) {
|
|
@@ -41,7 +41,7 @@ var Res = class {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
flatMap(f) {
|
|
44
|
-
if (this.tag !== "Ok") return this;
|
|
44
|
+
if (this.tag !== "Ok") return passThrough(this);
|
|
45
45
|
try {
|
|
46
46
|
return f(this.value);
|
|
47
47
|
} catch (cause) {
|
|
@@ -61,17 +61,41 @@ var Res = class {
|
|
|
61
61
|
if (this.tag !== "Ok") return this;
|
|
62
62
|
try {
|
|
63
63
|
const r = f(this.value);
|
|
64
|
-
return r.tag === "Ok" ? this : r;
|
|
64
|
+
return r.tag === "Ok" ? this : passThrough(r);
|
|
65
|
+
} catch (cause) {
|
|
66
|
+
return defectRes(cause);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
bind(name, f) {
|
|
70
|
+
if (this.tag !== "Ok") return passThrough(this);
|
|
71
|
+
try {
|
|
72
|
+
const r = f(this.value);
|
|
73
|
+
if (r.tag !== "Ok") return passThrough(r);
|
|
74
|
+
return okRes({
|
|
75
|
+
...scopeOf(this.value),
|
|
76
|
+
[name]: r.value
|
|
77
|
+
});
|
|
78
|
+
} catch (cause) {
|
|
79
|
+
return defectRes(cause);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
let(name, f) {
|
|
83
|
+
if (this.tag !== "Ok") return passThrough(this);
|
|
84
|
+
try {
|
|
85
|
+
return okRes({
|
|
86
|
+
...scopeOf(this.value),
|
|
87
|
+
[name]: f(this.value)
|
|
88
|
+
});
|
|
65
89
|
} catch (cause) {
|
|
66
90
|
return defectRes(cause);
|
|
67
91
|
}
|
|
68
92
|
}
|
|
69
93
|
as(value) {
|
|
70
|
-
if (this.tag !== "Ok") return this;
|
|
94
|
+
if (this.tag !== "Ok") return passThrough(this);
|
|
71
95
|
return okRes(value);
|
|
72
96
|
}
|
|
73
97
|
mapErr(f) {
|
|
74
|
-
if (this.tag !== "Err") return this;
|
|
98
|
+
if (this.tag !== "Err") return passThrough(this);
|
|
75
99
|
try {
|
|
76
100
|
return errRes(f(this.error));
|
|
77
101
|
} catch (cause) {
|
|
@@ -79,7 +103,7 @@ var Res = class {
|
|
|
79
103
|
}
|
|
80
104
|
}
|
|
81
105
|
orElse(f) {
|
|
82
|
-
if (this.tag !== "Err") return this;
|
|
106
|
+
if (this.tag !== "Err") return passThrough(this);
|
|
83
107
|
try {
|
|
84
108
|
return f(this.error);
|
|
85
109
|
} catch (cause) {
|
|
@@ -87,7 +111,7 @@ var Res = class {
|
|
|
87
111
|
}
|
|
88
112
|
}
|
|
89
113
|
recover(f) {
|
|
90
|
-
if (this.tag !== "Err") return this;
|
|
114
|
+
if (this.tag !== "Err") return passThrough(this);
|
|
91
115
|
try {
|
|
92
116
|
return okRes(f(this.error));
|
|
93
117
|
} catch (cause) {
|
|
@@ -208,6 +232,41 @@ function defectRes(cause) {
|
|
|
208
232
|
});
|
|
209
233
|
}
|
|
210
234
|
/**
|
|
235
|
+
* Reuse a non-matching variant (an `Err` or `Defect`) as a differently-typed
|
|
236
|
+
* `Result`, with no runtime work. Sound because the passed-through variant
|
|
237
|
+
* carries no value of the changed success type, so retyping it is a no-op — only
|
|
238
|
+
* the phantom type parameter moves. This is the single sanctioned home for that
|
|
239
|
+
* assertion (the same one boxed applies inline at every pass-through); every
|
|
240
|
+
* combinator's short-circuit branch funnels through here instead of casting.
|
|
241
|
+
*
|
|
242
|
+
* @internal
|
|
243
|
+
*/
|
|
244
|
+
function passThrough(self) {
|
|
245
|
+
return self;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Validate that a `bind`/`let` scope is a real (non-null) object before merging a
|
|
249
|
+
* key into it.
|
|
250
|
+
*
|
|
251
|
+
* @remarks
|
|
252
|
+
* Do-notation accumulates an **object** scope: a chain starts at `Do()` (an
|
|
253
|
+
* empty object) and every `bind`/`let` returns an object, so in typed code the
|
|
254
|
+
* scope is always an object. The method lives on the general `Result` surface,
|
|
255
|
+
* though, so a primitive `Ok` (e.g. `Ok(5).bind(...)`, or a chain whose value was
|
|
256
|
+
* `map`-ped away from its scope) could reach it. Rather than let `{ ...5 }`
|
|
257
|
+
* silently collapse to `{}` and drop the prior scope, we throw here — the
|
|
258
|
+
* surrounding `try` turns it into a {@link Defect}, surfacing the misuse as the
|
|
259
|
+
* bug it is (a defect is a bug, not an absent value). A `this: object` constraint
|
|
260
|
+
* was rejected: TypeScript does not hard-enforce a constraint inferred solely
|
|
261
|
+
* from `this`, and it breaks `AsyncRes implements AsyncResult`.
|
|
262
|
+
*
|
|
263
|
+
* @internal
|
|
264
|
+
*/
|
|
265
|
+
function scopeOf(value) {
|
|
266
|
+
if (typeof value !== "object" || value === null) throw new TypeError("bind/let requires an object scope — start a do-chain with Do()");
|
|
267
|
+
return value;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
211
270
|
* The sole runtime implementation of {@link AsyncResult}: wraps a
|
|
212
271
|
* `Promise<Result>` constructed never to reject. Operates on the public `Result`
|
|
213
272
|
* union (via `tag`), never on `Res` internals. Never re-exported from `index.ts`.
|
|
@@ -224,7 +283,7 @@ var AsyncRes = class AsyncRes {
|
|
|
224
283
|
}
|
|
225
284
|
map(f) {
|
|
226
285
|
return new AsyncRes(this.promise.then((r) => {
|
|
227
|
-
if (r.tag !== "Ok") return r;
|
|
286
|
+
if (r.tag !== "Ok") return passThrough(r);
|
|
228
287
|
try {
|
|
229
288
|
return okRes(f(r.value));
|
|
230
289
|
} catch (cause) {
|
|
@@ -234,7 +293,7 @@ var AsyncRes = class AsyncRes {
|
|
|
234
293
|
}
|
|
235
294
|
flatMap(f) {
|
|
236
295
|
return new AsyncRes(this.promise.then(async (r) => {
|
|
237
|
-
if (r.tag !== "Ok") return r;
|
|
296
|
+
if (r.tag !== "Ok") return passThrough(r);
|
|
238
297
|
try {
|
|
239
298
|
return await f(r.value);
|
|
240
299
|
} catch (cause) {
|
|
@@ -255,21 +314,49 @@ var AsyncRes = class AsyncRes {
|
|
|
255
314
|
}
|
|
256
315
|
flatTap(f) {
|
|
257
316
|
return new AsyncRes(this.promise.then(async (r) => {
|
|
258
|
-
if (r.tag !== "Ok") return r;
|
|
317
|
+
if (r.tag !== "Ok") return passThrough(r);
|
|
259
318
|
try {
|
|
260
319
|
const inner = await f(r.value);
|
|
261
|
-
return inner.tag === "Ok" ? r : inner;
|
|
320
|
+
return inner.tag === "Ok" ? r : passThrough(inner);
|
|
321
|
+
} catch (cause) {
|
|
322
|
+
return defectRes(cause);
|
|
323
|
+
}
|
|
324
|
+
}));
|
|
325
|
+
}
|
|
326
|
+
bind(name, f) {
|
|
327
|
+
return new AsyncRes(this.promise.then(async (r) => {
|
|
328
|
+
if (r.tag !== "Ok") return passThrough(r);
|
|
329
|
+
try {
|
|
330
|
+
const inner = await f(r.value);
|
|
331
|
+
if (inner.tag !== "Ok") return passThrough(inner);
|
|
332
|
+
return okRes({
|
|
333
|
+
...scopeOf(r.value),
|
|
334
|
+
[name]: inner.value
|
|
335
|
+
});
|
|
336
|
+
} catch (cause) {
|
|
337
|
+
return defectRes(cause);
|
|
338
|
+
}
|
|
339
|
+
}));
|
|
340
|
+
}
|
|
341
|
+
let(name, f) {
|
|
342
|
+
return new AsyncRes(this.promise.then((r) => {
|
|
343
|
+
if (r.tag !== "Ok") return passThrough(r);
|
|
344
|
+
try {
|
|
345
|
+
return okRes({
|
|
346
|
+
...scopeOf(r.value),
|
|
347
|
+
[name]: f(r.value)
|
|
348
|
+
});
|
|
262
349
|
} catch (cause) {
|
|
263
350
|
return defectRes(cause);
|
|
264
351
|
}
|
|
265
352
|
}));
|
|
266
353
|
}
|
|
267
354
|
as(value) {
|
|
268
|
-
return new AsyncRes(this.promise.then((r) => r.tag === "Ok" ? okRes(value) : r));
|
|
355
|
+
return new AsyncRes(this.promise.then((r) => r.tag === "Ok" ? okRes(value) : passThrough(r)));
|
|
269
356
|
}
|
|
270
357
|
mapErr(f) {
|
|
271
358
|
return new AsyncRes(this.promise.then((r) => {
|
|
272
|
-
if (r.tag !== "Err") return r;
|
|
359
|
+
if (r.tag !== "Err") return passThrough(r);
|
|
273
360
|
try {
|
|
274
361
|
return errRes(f(r.error));
|
|
275
362
|
} catch (cause) {
|
|
@@ -279,7 +366,7 @@ var AsyncRes = class AsyncRes {
|
|
|
279
366
|
}
|
|
280
367
|
orElse(f) {
|
|
281
368
|
return new AsyncRes(this.promise.then(async (r) => {
|
|
282
|
-
if (r.tag !== "Err") return r;
|
|
369
|
+
if (r.tag !== "Err") return passThrough(r);
|
|
283
370
|
try {
|
|
284
371
|
return await f(r.error);
|
|
285
372
|
} catch (cause) {
|
|
@@ -289,7 +376,7 @@ var AsyncRes = class AsyncRes {
|
|
|
289
376
|
}
|
|
290
377
|
recover(f) {
|
|
291
378
|
return new AsyncRes(this.promise.then((r) => {
|
|
292
|
-
if (r.tag !== "Err") return r;
|
|
379
|
+
if (r.tag !== "Err") return passThrough(r);
|
|
293
380
|
try {
|
|
294
381
|
return okRes(f(r.error));
|
|
295
382
|
} catch (cause) {
|
|
@@ -365,11 +452,11 @@ var AsyncRes = class AsyncRes {
|
|
|
365
452
|
*
|
|
366
453
|
* @example
|
|
367
454
|
* ```ts
|
|
368
|
-
* import {
|
|
369
|
-
*
|
|
455
|
+
* import { Ok } from "unthrown";
|
|
456
|
+
* Ok(42).unwrap(); // 42
|
|
370
457
|
* ```
|
|
371
458
|
*/
|
|
372
|
-
function
|
|
459
|
+
function Ok(value) {
|
|
373
460
|
return okRes(value);
|
|
374
461
|
}
|
|
375
462
|
/**
|
|
@@ -380,11 +467,11 @@ function ok(value) {
|
|
|
380
467
|
*
|
|
381
468
|
* @example
|
|
382
469
|
* ```ts
|
|
383
|
-
* import {
|
|
384
|
-
*
|
|
470
|
+
* import { Err } from "unthrown";
|
|
471
|
+
* Err("not_found").unwrapErr(); // "not_found"
|
|
385
472
|
* ```
|
|
386
473
|
*/
|
|
387
|
-
function
|
|
474
|
+
function Err(error) {
|
|
388
475
|
return errRes(error);
|
|
389
476
|
}
|
|
390
477
|
/**
|
|
@@ -420,24 +507,24 @@ function isDefect(r) {
|
|
|
420
507
|
}
|
|
421
508
|
//#endregion
|
|
422
509
|
//#region src/defect.ts
|
|
423
|
-
const DEFECT = Symbol("unthrown/
|
|
510
|
+
const DEFECT = Symbol("unthrown/Defect");
|
|
424
511
|
/**
|
|
425
512
|
* Wrap a cause as a {@link Defect} — the value you return from a `qualify`
|
|
426
513
|
* function when a failure is **not** a modeled domain error.
|
|
427
514
|
*
|
|
428
515
|
* @param cause - the original thrown/rejected value.
|
|
429
|
-
* @returns an opaque
|
|
516
|
+
* @returns an opaque Defect marker carrying `cause`.
|
|
430
517
|
*
|
|
431
518
|
* @example
|
|
432
519
|
* ```ts
|
|
433
|
-
* import { fromPromise,
|
|
520
|
+
* import { fromPromise, Defect } from "unthrown";
|
|
434
521
|
*
|
|
435
522
|
* const user = fromPromise(fetchUser(id), (cause) =>
|
|
436
|
-
* cause instanceof NotFoundError ? cause :
|
|
523
|
+
* cause instanceof NotFoundError ? cause : Defect(cause),
|
|
437
524
|
* );
|
|
438
525
|
* ```
|
|
439
526
|
*/
|
|
440
|
-
function
|
|
527
|
+
function Defect(cause) {
|
|
441
528
|
return {
|
|
442
529
|
[DEFECT]: true,
|
|
443
530
|
cause
|
|
@@ -454,13 +541,40 @@ function isDefectMarker(x) {
|
|
|
454
541
|
return typeof x === "object" && x !== null && x[DEFECT] === true;
|
|
455
542
|
}
|
|
456
543
|
//#endregion
|
|
544
|
+
//#region src/do.ts
|
|
545
|
+
/**
|
|
546
|
+
* Start a do-notation chain with an empty object scope, grown step by step with
|
|
547
|
+
* `bind` (for `Result`-returning steps) and `let` (for pure values).
|
|
548
|
+
*
|
|
549
|
+
* @remarks
|
|
550
|
+
* Capitalised because `do` is a reserved word. Each step receives the scope
|
|
551
|
+
* accumulated so far; the error types union across `bind`s, and a throw in any
|
|
552
|
+
* step becomes a `Defect`. To go asynchronous, lift the chain with `toAsync()`
|
|
553
|
+
* (then a `bind` may return an `AsyncResult`).
|
|
554
|
+
*
|
|
555
|
+
* @example
|
|
556
|
+
* ```ts
|
|
557
|
+
* import { Do, Ok } from "unthrown";
|
|
558
|
+
*
|
|
559
|
+
* const result = Do()
|
|
560
|
+
* .bind("user", () => findUser(id)) // Result<User, NotFound>
|
|
561
|
+
* .bind("org", ({ user }) => findOrg(user.orgId)) // Result<Org, NotFound>
|
|
562
|
+
* .let("label", ({ user, org }) => `${user.name} @ ${org.name}`)
|
|
563
|
+
* .map(({ user, org, label }) => render(user, org, label));
|
|
564
|
+
* // Result<View, NotFound>
|
|
565
|
+
* ```
|
|
566
|
+
*/
|
|
567
|
+
function Do() {
|
|
568
|
+
return Ok({});
|
|
569
|
+
}
|
|
570
|
+
//#endregion
|
|
457
571
|
//#region src/interop.ts
|
|
458
572
|
/**
|
|
459
573
|
* Bridge a nullable value into a {@link Result}: absence becomes a **modeled**
|
|
460
574
|
* `Err`. The sanctioned alternative to an `Option` type.
|
|
461
575
|
*
|
|
462
576
|
* @remarks
|
|
463
|
-
* `null` and `undefined` map to `
|
|
577
|
+
* `null` and `undefined` map to `Err(onAbsent())`; any other value (including
|
|
464
578
|
* falsy ones like `0`, `""`, `false`) maps to `Ok`.
|
|
465
579
|
*
|
|
466
580
|
* @typeParam T - the (nullable) value type.
|
|
@@ -475,7 +589,7 @@ function isDefectMarker(x) {
|
|
|
475
589
|
* ```
|
|
476
590
|
*/
|
|
477
591
|
function fromNullable(value, onAbsent) {
|
|
478
|
-
return value === null || value === void 0 ?
|
|
592
|
+
return value === null || value === void 0 ? Err(onAbsent()) : Ok(value);
|
|
479
593
|
}
|
|
480
594
|
/**
|
|
481
595
|
* Wrap a throwing synchronous function so it returns a {@link Result} instead of
|
|
@@ -483,14 +597,14 @@ function fromNullable(value, onAbsent) {
|
|
|
483
597
|
*
|
|
484
598
|
* @remarks
|
|
485
599
|
* `qualify` **must** triage every thrown cause into a modeled error `E` or a
|
|
486
|
-
* {@link Defect} (via {@link
|
|
600
|
+
* {@link Defect} (via {@link Defect}) — there is no path that leaves `unknown`
|
|
487
601
|
* in `E`. A throw inside `qualify` itself is treated as a `Defect`.
|
|
488
602
|
*
|
|
489
603
|
* The modeled error type is `Exclude<R, Defect>` — the `Defect` arm of
|
|
490
604
|
* `qualify`'s return is **subtracted** from `E`, never inferred into it. So a
|
|
491
|
-
* `qualify` that returns *only* `
|
|
605
|
+
* `qualify` that returns *only* `Defect(cause)` yields `E = never` (a Defect is
|
|
492
606
|
* out-of-band and must not pollute the error channel); reach for
|
|
493
|
-
* {@link fromSafePromise} when every failure is a
|
|
607
|
+
* {@link fromSafePromise} when every failure is a Defect.
|
|
494
608
|
*
|
|
495
609
|
* @typeParam A - the wrapped function's argument tuple.
|
|
496
610
|
* @typeParam T - the wrapped function's return type.
|
|
@@ -502,8 +616,8 @@ function fromNullable(value, onAbsent) {
|
|
|
502
616
|
*
|
|
503
617
|
* @example
|
|
504
618
|
* ```ts
|
|
505
|
-
* import { fromThrowable,
|
|
506
|
-
* const parse = fromThrowable(JSON.parse, (cause) =>
|
|
619
|
+
* import { fromThrowable, Defect } from "unthrown";
|
|
620
|
+
* const parse = fromThrowable(JSON.parse, (cause) => Defect(cause));
|
|
507
621
|
* parse("{}").unwrap();
|
|
508
622
|
* ```
|
|
509
623
|
*/
|
|
@@ -511,7 +625,7 @@ function fromThrowable(fn, qualify) {
|
|
|
511
625
|
const triage = qualify;
|
|
512
626
|
return (...args) => {
|
|
513
627
|
try {
|
|
514
|
-
return
|
|
628
|
+
return Ok(fn(...args));
|
|
515
629
|
} catch (cause) {
|
|
516
630
|
return qualifyToResult(cause, triage);
|
|
517
631
|
}
|
|
@@ -529,8 +643,8 @@ function fromThrowable(fn, qualify) {
|
|
|
529
643
|
*
|
|
530
644
|
* The modeled error type is `Exclude<R, Defect>` — the `Defect` arm of
|
|
531
645
|
* `qualify`'s return is **subtracted** from `E`, never inferred into it. So a
|
|
532
|
-
* `qualify` that returns *only* `
|
|
533
|
-
* rejection is a
|
|
646
|
+
* `qualify` that returns *only* `Defect(cause)` yields `E = never`; when every
|
|
647
|
+
* rejection is a Defect, prefer {@link fromSafePromise}.
|
|
534
648
|
*
|
|
535
649
|
* @typeParam T - the resolved value type.
|
|
536
650
|
* @typeParam R - `qualify`'s return type; the modeled error `E` is
|
|
@@ -540,9 +654,9 @@ function fromThrowable(fn, qualify) {
|
|
|
540
654
|
*
|
|
541
655
|
* @example
|
|
542
656
|
* ```ts
|
|
543
|
-
* import { fromPromise,
|
|
657
|
+
* import { fromPromise, Defect } from "unthrown";
|
|
544
658
|
* const user = await fromPromise(fetchUser(id), (cause) =>
|
|
545
|
-
* cause instanceof NotFoundError ? ("not_found" as const) :
|
|
659
|
+
* cause instanceof NotFoundError ? ("not_found" as const) : Defect(cause),
|
|
546
660
|
* );
|
|
547
661
|
* ```
|
|
548
662
|
*/
|
|
@@ -586,7 +700,7 @@ function foldArray(results) {
|
|
|
586
700
|
for (const r of results) if (r.tag === "Defect") firstDefect ??= r;
|
|
587
701
|
else if (r.tag === "Err") firstErr ??= r;
|
|
588
702
|
else values.push(r.value);
|
|
589
|
-
return firstDefect ?? firstErr ??
|
|
703
|
+
return firstDefect ?? firstErr ?? Ok(values);
|
|
590
704
|
}
|
|
591
705
|
/**
|
|
592
706
|
* Fold a record of settled `Result`s with the same rules, else `Ok` of the
|
|
@@ -607,7 +721,7 @@ function foldRecord(results) {
|
|
|
607
721
|
writable: true,
|
|
608
722
|
configurable: true
|
|
609
723
|
});
|
|
610
|
-
return firstDefect ?? firstErr ??
|
|
724
|
+
return firstDefect ?? firstErr ?? Ok(values);
|
|
611
725
|
}
|
|
612
726
|
/**
|
|
613
727
|
* Collect a tuple/array of {@link Result}s into a single `Result` of all their
|
|
@@ -616,16 +730,16 @@ function foldRecord(results) {
|
|
|
616
730
|
* @remarks
|
|
617
731
|
* Short-circuits on the **first** `Err` (later entries are not inspected for
|
|
618
732
|
* their error); any `Defect` present **dominates**, winning even over an earlier
|
|
619
|
-
* `Err`. A **fixed tuple** keeps its positional types — `all([
|
|
733
|
+
* `Err`. A **fixed tuple** keeps its positional types — `all([Ok(1), Ok("a")])`
|
|
620
734
|
* is `Result<[number, string], …>` — while a **dynamic array** `Result<T, E>[]`
|
|
621
735
|
* collapses to `Result<T[], E>` with no cast. For a **record** keyed by name,
|
|
622
736
|
* use {@link allFromDict}.
|
|
623
737
|
*
|
|
624
738
|
* @example
|
|
625
739
|
* ```ts
|
|
626
|
-
* import { all,
|
|
627
|
-
* all([
|
|
628
|
-
* all([
|
|
740
|
+
* import { all, Ok } from "unthrown";
|
|
741
|
+
* all([Ok(1), Ok("a"), Ok(true)]).unwrap(); // [1, "a", true] (typed [number, string, boolean])
|
|
742
|
+
* all([Ok(1), Ok(2)] as Result<number, never>[]).unwrap(); // number[]
|
|
629
743
|
* ```
|
|
630
744
|
*/
|
|
631
745
|
function all(results) {
|
|
@@ -643,8 +757,8 @@ function all(results) {
|
|
|
643
757
|
*
|
|
644
758
|
* @example
|
|
645
759
|
* ```ts
|
|
646
|
-
* import { allFromDict,
|
|
647
|
-
* allFromDict({ id:
|
|
760
|
+
* import { allFromDict, Ok } from "unthrown";
|
|
761
|
+
* allFromDict({ id: Ok(1), name: Ok("ada") }).unwrap(); // { id: 1, name: "ada" }
|
|
648
762
|
* ```
|
|
649
763
|
*/
|
|
650
764
|
function allFromDict(results) {
|
|
@@ -697,8 +811,8 @@ function allFromDictAsync(results) {
|
|
|
697
811
|
//#region src/facade.ts
|
|
698
812
|
/**
|
|
699
813
|
* Companion object grouping the standalone entry points under a single,
|
|
700
|
-
* discoverable namespace: {@link Result.
|
|
701
|
-
* {@link Result.
|
|
814
|
+
* discoverable namespace: {@link Result.Ok}, {@link Result.Err},
|
|
815
|
+
* {@link Result.Defect}, {@link Result.fromNullable}, {@link Result.fromThrowable},
|
|
702
816
|
* {@link Result.fromPromise}, {@link Result.fromSafePromise}, {@link Result.all},
|
|
703
817
|
* {@link Result.allAsync}, {@link Result.allFromDict},
|
|
704
818
|
* {@link Result.allFromDictAsync}, {@link Result.isOk}, {@link Result.isErr},
|
|
@@ -707,19 +821,20 @@ function allFromDictAsync(results) {
|
|
|
707
821
|
* @remarks
|
|
708
822
|
* Purely additive sugar — each member **is** the corresponding free function.
|
|
709
823
|
* The free functions remain the primary, tree-shakeable API; importing only
|
|
710
|
-
* `{
|
|
824
|
+
* `{ Ok }` never pulls this object in. The value `Result` and the type
|
|
711
825
|
* {@link Result} share one name (the companion-object pattern).
|
|
712
826
|
*
|
|
713
827
|
* @example
|
|
714
828
|
* ```ts
|
|
715
829
|
* import { Result } from "unthrown";
|
|
716
|
-
* Result.
|
|
830
|
+
* Result.Ok(1).flatMap((n) => Result.Ok(n + 1)).unwrap(); // 2
|
|
717
831
|
* ```
|
|
718
832
|
*/
|
|
719
833
|
const Result = {
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
834
|
+
Ok,
|
|
835
|
+
Err,
|
|
836
|
+
Defect,
|
|
837
|
+
Do,
|
|
723
838
|
fromNullable,
|
|
724
839
|
fromThrowable,
|
|
725
840
|
fromPromise,
|
|
@@ -800,6 +915,10 @@ function matchTags(result, handlers) {
|
|
|
800
915
|
});
|
|
801
916
|
}
|
|
802
917
|
//#endregion
|
|
918
|
+
exports.Defect = Defect;
|
|
919
|
+
exports.Do = Do;
|
|
920
|
+
exports.Err = Err;
|
|
921
|
+
exports.Ok = Ok;
|
|
803
922
|
exports.Result = Result;
|
|
804
923
|
exports.TaggedError = TaggedError;
|
|
805
924
|
exports.UnwrapError = UnwrapError;
|
|
@@ -807,8 +926,6 @@ exports.all = all;
|
|
|
807
926
|
exports.allAsync = allAsync;
|
|
808
927
|
exports.allFromDict = allFromDict;
|
|
809
928
|
exports.allFromDictAsync = allFromDictAsync;
|
|
810
|
-
exports.defect = defect;
|
|
811
|
-
exports.err = err;
|
|
812
929
|
exports.fromNullable = fromNullable;
|
|
813
930
|
exports.fromPromise = fromPromise;
|
|
814
931
|
exports.fromSafePromise = fromSafePromise;
|
|
@@ -817,4 +934,3 @@ exports.isDefect = isDefect;
|
|
|
817
934
|
exports.isErr = isErr;
|
|
818
935
|
exports.isOk = isOk;
|
|
819
936
|
exports.matchTags = matchTags;
|
|
820
|
-
exports.ok = ok;
|