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