unthrown 0.1.0 → 0.2.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/dist/index.cjs +76 -14
- package/dist/index.d.cts +107 -19
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +107 -19
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +76 -15
- package/dist/index.mjs.map +1 -1
- package/docs/index.md +204 -90
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -172,10 +172,10 @@ type ResultMethods<T, E> = {
|
|
|
172
172
|
*
|
|
173
173
|
* @throws Re-throws on a `Defect`.
|
|
174
174
|
*/
|
|
175
|
-
getOrUndefined(): T | undefined; /** Whether this result is `Ok`. */
|
|
176
|
-
isOk():
|
|
177
|
-
isErr():
|
|
178
|
-
isDefect():
|
|
175
|
+
getOrUndefined(): T | undefined; /** Whether this result is `Ok` — narrows `this` to its {@link OkView} on `true`. */
|
|
176
|
+
isOk(): this is OkView<T, E>; /** Whether this result is `Err` — narrows `this` to its {@link ErrView} on `true`. */
|
|
177
|
+
isErr(): this is ErrView<E, T>; /** Whether this result is a `Defect` — narrows `this` to its {@link DefectView} on `true`. */
|
|
178
|
+
isDefect(): this is DefectView<T, E>; /** Lift this synchronous `Result` into an {@link AsyncResult}. */
|
|
179
179
|
toAsync(): AsyncResult<T, E>;
|
|
180
180
|
};
|
|
181
181
|
/** The `Ok` variant of a {@link Result}: a success carrying a `value`. */
|
|
@@ -310,6 +310,18 @@ type ErrOf<R> = R extends {
|
|
|
310
310
|
readonly tag: "Err";
|
|
311
311
|
readonly error: infer E;
|
|
312
312
|
} ? E : never;
|
|
313
|
+
/**
|
|
314
|
+
* Extract the success type `T` from an {@link AsyncResult}.
|
|
315
|
+
*
|
|
316
|
+
* @typeParam R - the `AsyncResult` type to inspect.
|
|
317
|
+
*/
|
|
318
|
+
type AsyncOkOf<R> = R extends AsyncResult<infer T, unknown> ? T : never;
|
|
319
|
+
/**
|
|
320
|
+
* Extract the error type `E` from an {@link AsyncResult}.
|
|
321
|
+
*
|
|
322
|
+
* @typeParam R - the `AsyncResult` type to inspect.
|
|
323
|
+
*/
|
|
324
|
+
type AsyncErrOf<R> = R extends AsyncResult<unknown, infer E> ? E : never;
|
|
313
325
|
//#endregion
|
|
314
326
|
//#region src/constructors.d.ts
|
|
315
327
|
/**
|
|
@@ -449,9 +461,16 @@ declare function fromNullable<T, E>(value: T | null | undefined, onAbsent: () =>
|
|
|
449
461
|
* {@link Defect} (via {@link defect}) — there is no path that leaves `unknown`
|
|
450
462
|
* in `E`. A throw inside `qualify` itself is treated as a `Defect`.
|
|
451
463
|
*
|
|
464
|
+
* The modeled error type is `Exclude<R, Defect>` — the `Defect` arm of
|
|
465
|
+
* `qualify`'s return is **subtracted** from `E`, never inferred into it. So a
|
|
466
|
+
* `qualify` that returns *only* `defect(cause)` yields `E = never` (a defect is
|
|
467
|
+
* out-of-band and must not pollute the error channel); reach for
|
|
468
|
+
* {@link fromSafePromise} when every failure is a defect.
|
|
469
|
+
*
|
|
452
470
|
* @typeParam A - the wrapped function's argument tuple.
|
|
453
471
|
* @typeParam T - the wrapped function's return type.
|
|
454
|
-
* @typeParam
|
|
472
|
+
* @typeParam R - `qualify`'s return type; the modeled error `E` is
|
|
473
|
+
* `Exclude<R, Defect>` (its `Defect` arm, if any, is subtracted).
|
|
455
474
|
* @param fn - the throwing function to wrap.
|
|
456
475
|
* @param qualify - triages a thrown cause into `E` or a `Defect`.
|
|
457
476
|
* @returns a function with the same arguments returning `Result<T, E>`.
|
|
@@ -463,7 +482,7 @@ declare function fromNullable<T, E>(value: T | null | undefined, onAbsent: () =>
|
|
|
463
482
|
* parse("{}").unwrap();
|
|
464
483
|
* ```
|
|
465
484
|
*/
|
|
466
|
-
declare function fromThrowable<A extends unknown[], T,
|
|
485
|
+
declare function fromThrowable<A extends unknown[], T, R>(fn: (...args: A) => T, qualify: (cause: unknown) => R): (...args: A) => Result$1<T, Exclude<R, Defect>>;
|
|
467
486
|
/**
|
|
468
487
|
* Wrap a `Promise` (or a thunk producing one) as an {@link AsyncResult}, forcing
|
|
469
488
|
* every rejection to be triaged.
|
|
@@ -474,8 +493,14 @@ declare function fromThrowable<A extends unknown[], T, E>(fn: (...args: A) => T,
|
|
|
474
493
|
* `await`-ing it always yields a `Result`. A throw inside `qualify` is itself a
|
|
475
494
|
* `Defect`.
|
|
476
495
|
*
|
|
496
|
+
* The modeled error type is `Exclude<R, Defect>` — the `Defect` arm of
|
|
497
|
+
* `qualify`'s return is **subtracted** from `E`, never inferred into it. So a
|
|
498
|
+
* `qualify` that returns *only* `defect(cause)` yields `E = never`; when every
|
|
499
|
+
* rejection is a defect, prefer {@link fromSafePromise}.
|
|
500
|
+
*
|
|
477
501
|
* @typeParam T - the resolved value type.
|
|
478
|
-
* @typeParam
|
|
502
|
+
* @typeParam R - `qualify`'s return type; the modeled error `E` is
|
|
503
|
+
* `Exclude<R, Defect>` (its `Defect` arm, if any, is subtracted).
|
|
479
504
|
* @param promise - the promise, or a thunk returning one.
|
|
480
505
|
* @param qualify - triages a rejection cause into `E` or a `Defect`.
|
|
481
506
|
*
|
|
@@ -487,7 +512,7 @@ declare function fromThrowable<A extends unknown[], T, E>(fn: (...args: A) => T,
|
|
|
487
512
|
* );
|
|
488
513
|
* ```
|
|
489
514
|
*/
|
|
490
|
-
declare function fromPromise<T,
|
|
515
|
+
declare function fromPromise<T, R>(promise: Promise<T> | (() => Promise<T>), qualify: (cause: unknown) => R): AsyncResult<T, Exclude<R, Defect>>;
|
|
491
516
|
/**
|
|
492
517
|
* Wrap a `Promise` asserted **not** to fail in any modeled way: any rejection
|
|
493
518
|
* becomes a `Defect`.
|
|
@@ -502,25 +527,66 @@ declare function fromPromise<T, E>(promise: Promise<T> | (() => Promise<T>), qua
|
|
|
502
527
|
*/
|
|
503
528
|
declare function fromSafePromise<T>(promise: Promise<T> | (() => Promise<T>)): AsyncResult<T, never>;
|
|
504
529
|
/**
|
|
505
|
-
*
|
|
506
|
-
*
|
|
530
|
+
* The success channel of {@link all} / {@link allAsync}: a **positional tuple**
|
|
531
|
+
* for a fixed-length input (including the empty tuple), or a homogeneous
|
|
532
|
+
* **array** for a dynamic one.
|
|
533
|
+
*
|
|
534
|
+
* @remarks
|
|
535
|
+
* The split keys off the input's `length`: a fixed tuple has a literal length
|
|
536
|
+
* (`number extends Rs["length"]` is false → keep the positional `Ts`), while a
|
|
537
|
+
* general array has `length: number` (→ collapse to `Ts[number][]`). Checking
|
|
538
|
+
* length rather than `Rs extends [unknown, ...unknown[]]` keeps `all([])` typed
|
|
539
|
+
* as `Result<[], …>` instead of `Result<never[], …>`.
|
|
540
|
+
*
|
|
541
|
+
* @typeParam Rs - the tuple/array of input `Result` types.
|
|
542
|
+
* @typeParam Ts - per-element extracted success types (`OkOf` for `all`,
|
|
543
|
+
* `AsyncOkOf` for `allAsync`).
|
|
544
|
+
* @internal
|
|
545
|
+
*/
|
|
546
|
+
type AllOk<Rs extends readonly unknown[], Ts extends readonly unknown[]> = number extends Rs["length"] ? Ts[number][] : Ts;
|
|
547
|
+
/**
|
|
548
|
+
* Collect {@link Result}s into a single `Result` of all their success values.
|
|
507
549
|
*
|
|
508
550
|
* @remarks
|
|
509
551
|
* Short-circuits on the **first** `Err` (later entries are not inspected for
|
|
510
552
|
* their error); any `Defect` present **dominates**, winning even over an earlier
|
|
511
|
-
* `Err`.
|
|
512
|
-
* `Result<[number, string],
|
|
553
|
+
* `Err`. A **fixed tuple** keeps its positional types — `all([ok(1), ok("a")])`
|
|
554
|
+
* is `Result<[number, string], …>` — while a **dynamic array** `Result<T, E>[]`
|
|
555
|
+
* collapses to `Result<T[], E>` with no cast.
|
|
513
556
|
*
|
|
514
|
-
* @typeParam Rs - the tuple of input `Result` types.
|
|
557
|
+
* @typeParam Rs - the tuple/array of input `Result` types.
|
|
515
558
|
* @param results - the results to combine.
|
|
516
559
|
*
|
|
517
560
|
* @example
|
|
518
561
|
* ```ts
|
|
519
562
|
* import { all, ok } from "unthrown";
|
|
520
|
-
* all([ok(1), ok("a"), ok(true)]).unwrap(); // [1, "a", true]
|
|
563
|
+
* all([ok(1), ok("a"), ok(true)]).unwrap(); // [1, "a", true] (typed [number, string, boolean])
|
|
564
|
+
* all([ok(1), ok(2)] as Result<number, never>[]).unwrap(); // number[]
|
|
521
565
|
* ```
|
|
522
566
|
*/
|
|
523
|
-
declare function all<Rs extends readonly Result$1<unknown, unknown>[]>(results: readonly [...Rs]): Result$1<{ [K in keyof Rs]: OkOf<Rs[K]> }
|
|
567
|
+
declare function all<Rs extends readonly Result$1<unknown, unknown>[]>(results: readonly [...Rs]): Result$1<AllOk<Rs, { [K in keyof Rs]: OkOf<Rs[K]> }>, ErrOf<Rs[number]>>;
|
|
568
|
+
/**
|
|
569
|
+
* The asynchronous counterpart of {@link all}: combine {@link AsyncResult}s into
|
|
570
|
+
* one `AsyncResult` of all their success values.
|
|
571
|
+
*
|
|
572
|
+
* @remarks
|
|
573
|
+
* The inputs are resolved **concurrently** (their order is preserved); the
|
|
574
|
+
* resolved `Result`s are then folded with the same rules as {@link all} —
|
|
575
|
+
* first `Err` short-circuits, any `Defect` dominates. As ever, the returned
|
|
576
|
+
* `AsyncResult`'s internal promise never rejects. A **fixed tuple** keeps its
|
|
577
|
+
* positional types; a **dynamic array** `AsyncResult<T, E>[]` collapses to
|
|
578
|
+
* `AsyncResult<T[], E>`.
|
|
579
|
+
*
|
|
580
|
+
* @typeParam Rs - the tuple/array of input `AsyncResult` types.
|
|
581
|
+
* @param results - the async results to combine.
|
|
582
|
+
*
|
|
583
|
+
* @example
|
|
584
|
+
* ```ts
|
|
585
|
+
* import { allAsync, fromSafePromise } from "unthrown";
|
|
586
|
+
* const both = await allAsync([fromSafePromise(a()), fromSafePromise(b())]);
|
|
587
|
+
* ```
|
|
588
|
+
*/
|
|
589
|
+
declare function allAsync<Rs extends readonly AsyncResult<unknown, unknown>[]>(results: readonly [...Rs]): AsyncResult<AllOk<Rs, { [K in keyof Rs]: AsyncOkOf<Rs[K]> }>, AsyncErrOf<Rs[number]>>;
|
|
524
590
|
//#endregion
|
|
525
591
|
//#region src/facade.d.ts
|
|
526
592
|
/**
|
|
@@ -528,7 +594,8 @@ declare function all<Rs extends readonly Result$1<unknown, unknown>[]>(results:
|
|
|
528
594
|
* discoverable namespace: {@link Result.ok}, {@link Result.err},
|
|
529
595
|
* {@link Result.defect}, {@link Result.fromNullable}, {@link Result.fromThrowable},
|
|
530
596
|
* {@link Result.fromPromise}, {@link Result.fromSafePromise}, {@link Result.all},
|
|
531
|
-
* {@link Result.
|
|
597
|
+
* {@link Result.allAsync}, {@link Result.isOk}, {@link Result.isErr},
|
|
598
|
+
* {@link Result.isDefect}.
|
|
532
599
|
*
|
|
533
600
|
* @remarks
|
|
534
601
|
* Purely additive sugar — each member **is** the corresponding free function.
|
|
@@ -551,6 +618,7 @@ declare const Result: {
|
|
|
551
618
|
readonly fromPromise: typeof fromPromise;
|
|
552
619
|
readonly fromSafePromise: typeof fromSafePromise;
|
|
553
620
|
readonly all: typeof all;
|
|
621
|
+
readonly allAsync: typeof allAsync;
|
|
554
622
|
readonly isOk: typeof isOk;
|
|
555
623
|
readonly isErr: typeof isErr;
|
|
556
624
|
readonly isDefect: typeof isDefect;
|
|
@@ -592,8 +660,26 @@ type TaggedErrorConstructor<Tag extends string> = {
|
|
|
592
660
|
* field in the payload is forwarded to `Error`. The `_tag` always reflects
|
|
593
661
|
* `tag` and cannot be overridden by the payload.
|
|
594
662
|
*
|
|
663
|
+
* `_tag` is the discriminant used by {@link matchTags}; `Error.name` is the
|
|
664
|
+
* human-facing label in stack traces and logs. By default they coincide, but
|
|
665
|
+
* they can be **decoupled** with `options.name` — so a tag can be namespaced for
|
|
666
|
+
* collision-safety (`"@my-lib/RetryableError"`) without that slash-prefixed
|
|
667
|
+
* string leaking into `Error.name`:
|
|
668
|
+
*
|
|
669
|
+
* ```ts
|
|
670
|
+
* class RetryableError extends TaggedError("@my-lib/RetryableError", {
|
|
671
|
+
* name: "RetryableError",
|
|
672
|
+
* })<{ message: string }> {}
|
|
673
|
+
*
|
|
674
|
+
* const e = new RetryableError({ message: "boom" });
|
|
675
|
+
* e._tag; // "@my-lib/RetryableError" — namespaced discriminant
|
|
676
|
+
* e.name; // "RetryableError" — clean display name
|
|
677
|
+
* ```
|
|
678
|
+
*
|
|
595
679
|
* @typeParam Tag - the string literal discriminant.
|
|
596
|
-
* @param tag - the discriminant value
|
|
680
|
+
* @param tag - the discriminant value; also the default error `name`.
|
|
681
|
+
* @param options - optional overrides. `options.name` sets `Error.name`
|
|
682
|
+
* independently of `tag` (defaults to `tag`).
|
|
597
683
|
*
|
|
598
684
|
* @example
|
|
599
685
|
* ```ts
|
|
@@ -604,7 +690,9 @@ type TaggedErrorConstructor<Tag extends string> = {
|
|
|
604
690
|
* new HttpError({ status: 500 }).status; // 500
|
|
605
691
|
* ```
|
|
606
692
|
*/
|
|
607
|
-
declare function TaggedError<Tag extends string>(tag: Tag
|
|
693
|
+
declare function TaggedError<Tag extends string>(tag: Tag, options?: {
|
|
694
|
+
readonly name?: string;
|
|
695
|
+
}): TaggedErrorConstructor<Tag>;
|
|
608
696
|
/**
|
|
609
697
|
* The handler object {@link matchTags} requires: a branch per error tag, plus
|
|
610
698
|
* `Ok` and `Defect`. Miss a tag and it will not compile — the exhaustiveness is
|
|
@@ -659,5 +747,5 @@ declare function matchTags<T, E extends {
|
|
|
659
747
|
_tag: string;
|
|
660
748
|
}, R>(result: AsyncResult<T, E>, handlers: TagHandlers<T, E, R>): Promise<R>;
|
|
661
749
|
//#endregion
|
|
662
|
-
export { type AsyncResult, type Awaitable, type Defect, type DefectView, type ErrOf, type ErrView, type OkOf, type OkView, Result, type TagHandlers, TaggedError, type TaggedErrorConstructor, type TaggedErrorInstance, UnwrapError, all, defect, err, fromNullable, fromPromise, fromSafePromise, fromThrowable, isDefect, isErr, isOk, matchTags, ok };
|
|
750
|
+
export { type AsyncErrOf, type AsyncOkOf, type AsyncResult, type Awaitable, type Defect, type DefectView, type ErrOf, type ErrView, type OkOf, type OkView, Result, type TagHandlers, TaggedError, type TaggedErrorConstructor, type TaggedErrorInstance, UnwrapError, all, allAsync, defect, err, fromNullable, fromPromise, fromSafePromise, fromThrowable, isDefect, isErr, isOk, matchTags, ok };
|
|
663
751
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/constructors.ts","../src/core.ts","../src/defect.ts","../src/interop.ts","../src/facade.ts","../src/tagged.ts"],"mappings":";;AAWA;;;;;;;;KAAY,aAAA;EAqB6B;;;;;;;;;EAXvC,GAAA,IAAO,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,CAAA,GAAI,QAAA,CAAO,CAAA,EAAG,CAAA;EAoBV;;;;;;;;;;EAT5B,OAAA,QAAe,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,QAAA,CAAO,CAAA,EAAG,EAAA,IAAM,QAAA,CAAO,CAAA,EAAG,CAAA,GAAI,EAAA;EAuCxB;;;;;;;;EA9BtC,GAAA,CAAI,CAAA,GAAI,KAAA,EAAO,CAAA,YAAa,QAAA,CAAO,CAAA,EAAG,CAAA;EA4CC;;;;;;;EApCvC,EAAA,IAAM,KAAA,EAAO,CAAA,GAAI,QAAA,CAAO,CAAA,EAAG,CAAA;EA2D2B;;;;;;;;;EAhDtD,MAAA,KAAW,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,EAAA,GAAK,QAAA,CAAO,CAAA,EAAG,EAAA;EAsEb;;;;;;;;;;EA3D9B,MAAA,QAAc,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,QAAA,CAAO,CAAA,EAAG,EAAA,IAAM,QAAA,CAAO,CAAA,GAAI,CAAA,EAAG,EAAA;EA2F/B;;;;;;;;;;;;;EA7E9B,OAAA,IAAW,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,CAAA,GAAI,QAAA,CAAO,CAAA,GAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/constructors.ts","../src/core.ts","../src/defect.ts","../src/interop.ts","../src/facade.ts","../src/tagged.ts"],"mappings":";;AAWA;;;;;;;;KAAY,aAAA;EAqB6B;;;;;;;;;EAXvC,GAAA,IAAO,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,CAAA,GAAI,QAAA,CAAO,CAAA,EAAG,CAAA;EAoBV;;;;;;;;;;EAT5B,OAAA,QAAe,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,QAAA,CAAO,CAAA,EAAG,EAAA,IAAM,QAAA,CAAO,CAAA,EAAG,CAAA,GAAI,EAAA;EAuCxB;;;;;;;;EA9BtC,GAAA,CAAI,CAAA,GAAI,KAAA,EAAO,CAAA,YAAa,QAAA,CAAO,CAAA,EAAG,CAAA;EA4CC;;;;;;;EApCvC,EAAA,IAAM,KAAA,EAAO,CAAA,GAAI,QAAA,CAAO,CAAA,EAAG,CAAA;EA2D2B;;;;;;;;;EAhDtD,MAAA,KAAW,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,EAAA,GAAK,QAAA,CAAO,CAAA,EAAG,EAAA;EAsEb;;;;;;;;;;EA3D9B,MAAA,QAAc,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,QAAA,CAAO,CAAA,EAAG,EAAA,IAAM,QAAA,CAAO,CAAA,GAAI,CAAA,EAAG,EAAA;EA2F/B;;;;;;;;;;;;;EA7E9B,OAAA,IAAW,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,CAAA,GAAI,QAAA,CAAO,CAAA,GAAI,CAAA;EAmGjB;;;;;;;EA3F1B,MAAA,CAAO,CAAA,GAAI,KAAA,EAAO,CAAA,YAAa,QAAA,CAAO,CAAA,EAAG,CAAA;EAxEvB;;;;;;;;;;;;;EAuFlB,aAAA,QAAqB,CAAA,GAAI,KAAA,cAAmB,QAAA,CAAO,CAAA,EAAG,EAAA,IAAM,QAAA,CAAO,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA;EA5EpC;;;;;;EAmF1C,SAAA,CAAU,CAAA,GAAI,KAAA,qBAA0B,QAAA,CAAO,CAAA,EAAG,CAAA;EA1EnC;;;;;;;;;;;;;EAyFf,KAAA,IAAS,KAAA;IAAS,EAAA,GAAK,KAAA,EAAO,CAAA,KAAM,CAAA;IAAG,GAAA,GAAM,KAAA,EAAO,CAAA,KAAM,CAAA;IAAG,MAAA,GAAS,KAAA,cAAmB,CAAA;EAAA,IAAM,CAAA;EAtEpF;;;;;;;;EA+EX,MAAA,IAAU,CAAA;EApEqB;;;;;;;EA4E/B,SAAA,IAAa,CAAA;EA9Db;;;;;;;EAsEA,QAAA,CAAS,QAAA,EAAU,CAAA,GAAI,CAAA;EAtEoB;;;;;;EA6E3C,YAAA,CAAa,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,CAAA,GAAI,CAAA;EArEO;;;;;EA2EzC,SAAA,IAAa,CAAA;EA5DsC;;;;;EAkEnD,cAAA,IAAkB,CAAA,cAlEwD;EAqE1E,IAAA,YAAgB,MAAA,CAAO,CAAA,EAAG,CAAA,GA9D1B;EAgEA,KAAA,YAAiB,OAAA,CAAQ,CAAA,EAAG,CAAA,GAhElB;EAkEV,QAAA,YAAoB,UAAA,CAAW,CAAA,EAAG,CAAA,GAlEa;EAqE/C,OAAA,IAAW,WAAA,CAAY,CAAA,EAAG,CAAA;AAAA;;KAIhB,MAAA,iBAAuB,aAAA,CAAc,CAAA,EAAG,CAAA;EAAA,SACzC,GAAA;EAAA,SACA,KAAA,EAAO,CAAA;AAAA;;KAGN,OAAA,iBAAwB,aAAA,CAAc,CAAA,EAAG,CAAA;EAAA,SAC1C,GAAA;EAAA,SACA,KAAA,EAAO,CAAA;AAAA;;KAGN,UAAA,yBAAmC,aAAA,CAAc,CAAA,EAAG,CAAA;EAAA,SACrD,GAAA;EAAA,SACA,KAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAhBkB;AAI7B;;KAoDY,QAAA,SAAe,MAAA,CAAO,CAAA,EAAG,CAAA,IAAK,OAAA,CAAQ,CAAA,EAAG,CAAA,IAAK,UAAA,CAAW,CAAA,EAAG,CAAA;;;;;;;;;;;;;;KAe5D,SAAA;EACV,IAAA,KAAS,CAAA,EAAG,WAAA,KAAgB,KAAA,EAAO,CAAA,KAAM,CAAA,GAAI,WAAA,CAAY,CAAA,YAAa,WAAA,CAAY,CAAA;AAAA;AA/DpF;;;;;;;;;;;;;;;;;;AAAA,KAoFY,WAAA,SAAoB,SAAA,CAAU,QAAA,CAAO,CAAA,EAAG,CAAA;EA/ExC,0EAiFV,GAAA,IAAO,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,CAAA,GAAI,WAAA,CAAY,CAAA,EAAG,CAAA;EAjFvB;;;;EAsFpB,OAAA,QAAe,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,QAAA,CAAO,CAAA,EAAG,EAAA,IAAM,WAAA,CAAY,CAAA,EAAG,EAAA,IAAM,WAAA,CAAY,CAAA,EAAG,CAAA,GAAI,EAAA,GAtF9B;EAwF1D,GAAA,CAAI,CAAA,GAAI,KAAA,EAAO,CAAA,YAAa,WAAA,CAAY,CAAA,EAAG,CAAA,GAxFX;EA0FhC,EAAA,IAAM,KAAA,EAAO,CAAA,GAAI,WAAA,CAAY,CAAA,EAAG,CAAA,GA1F2B;EA6F3D,MAAA,KAAW,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,EAAA,GAAK,WAAA,CAAY,CAAA,EAAG,EAAA,GA5FvC;EA8FT,MAAA,QAAc,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,QAAA,CAAO,CAAA,EAAG,EAAA,IAAM,WAAA,CAAY,CAAA,EAAG,EAAA,IAAM,WAAA,CAAY,CAAA,GAAI,CAAA,EAAG,EAAA,GA7FzE;EA+Fd,OAAA,IAAW,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,CAAA,GAAI,WAAA,CAAY,CAAA,GAAI,CAAA,UAvDtC;EAyDV,MAAA,CAAO,CAAA,GAAI,KAAA,EAAO,CAAA,YAAa,WAAA,CAAY,CAAA,EAAG,CAAA,GAzD9B;EA4DhB,aAAA,QACE,CAAA,GAAI,KAAA,cAAmB,QAAA,CAAO,CAAA,EAAG,EAAA,IAAM,WAAA,CAAY,CAAA,EAAG,EAAA,IACrD,WAAA,CAAY,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,GA9DS;EAgEnC,SAAA,CAAU,CAAA,GAAI,KAAA,qBAA0B,WAAA,CAAY,CAAA,EAAG,CAAA,GAhEP;EAmEhD,KAAA,IAAS,KAAA;IACP,EAAA,GAAK,KAAA,EAAO,CAAA,KAAM,CAAA;IAClB,GAAA,GAAM,KAAA,EAAO,CAAA,KAAM,CAAA;IACnB,MAAA,GAAS,KAAA,cAAmB,CAAA;EAAA,IAC1B,OAAA,CAAQ,CAAA,GAvEsD;EAyElE,MAAA,IAAU,OAAA,CAAQ,CAAA,GAzED;EA2EjB,SAAA,IAAa,OAAA,CAAQ,CAAA,GA3EI;EA6EzB,QAAA,CAAS,QAAA,EAAU,CAAA,GAAI,OAAA,CAAQ,CAAA,GA7EI;EA+EnC,YAAA,CAAa,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,CAAA,GAAI,OAAA,CAAQ,CAAA,GA/EM;EAiFhD,SAAA,IAAa,OAAA,CAAQ,CAAA,UAjFmC;EAmFxD,cAAA,IAAkB,OAAA,CAAQ,CAAA;AAAA;;AAnF6C;AAezE;;;KA4EY,IAAA,MAAU,CAAC;EAAA,SAAoB,GAAA;EAAA,SAAoB,KAAA;AAAA,IAAmB,CAAA;;;;;;KAMtE,KAAA,MAAW,CAAC;EAAA,SAAoB,GAAA;EAAA,SAAqB,KAAA;AAAA,IAAmB,CAAA;;;;;;KAMxE,SAAA,MAAe,CAAA,SAAU,WAAW,qBAAqB,CAAA;;;;AAvFgB;AAqBrF;KAwEY,UAAA,MAAgB,CAAA,SAAU,WAAW,qBAAqB,CAAA;;;AAlVtE;;;;;;;;;;;;AAAA,iBCMgB,EAAA,IAAM,KAAA,EAAO,CAAA,GAAI,QAAA,CAAO,CAAA;;;;;;;;;;;;;iBAgBxB,GAAA,IAAO,KAAA,EAAO,CAAA,GAAI,QAAA,QAAc,CAAA;;;;;;;;;;;;;iBAgBhC,IAAA,OAAW,CAAA,EAAG,QAAA,CAAO,CAAA,EAAG,CAAA,IAAK,CAAA,IAAK,MAAA,CAAO,CAAA,EAAG,CAAA;;;;;;iBAQ5C,KAAA,OAAY,CAAA,EAAG,QAAA,CAAO,CAAA,EAAG,CAAA,IAAK,CAAA,IAAK,OAAA,CAAQ,CAAA,EAAG,CAAA;;;;;;iBAQ9C,QAAA,OAAe,CAAA,EAAG,QAAA,CAAO,CAAA,EAAG,CAAA,IAAK,CAAA,IAAK,UAAA,CAAW,CAAA,EAAG,CAAA;;;ADtDpE;;;;;;;;;;;AAAA,cEiBa,WAAA,sBAAiC,KAAA;EFIW;;;;EAAA,SEC9C,KAAA,EAAO,CAAA;cACJ,KAAA,EAAO,CAAA;AAAA;;;cChCf,MAAA;AHSN;;;;;;;;;;AAAA,KGGY,MAAA;EAAA,UACA,MAAM;EAAA,SACP,KAAK;AAAA;;;;;;;;;;;;;;;;;iBAmBA,MAAA,CAAO,KAAA,YAAiB,MAAM;;;;;;;;;;;;;;;;;;;;;;iBCP9B,YAAA,OACd,KAAA,EAAO,CAAA,qBACP,QAAA,QAAgB,CAAA,GACf,QAAA,CAAO,WAAA,CAAY,CAAA,GAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkCV,aAAA,4BACd,EAAA,MAAQ,IAAA,EAAM,CAAA,KAAM,CAAA,EACpB,OAAA,GAAU,KAAA,cAAmB,CAAA,OACxB,IAAA,EAAM,CAAA,KAAM,QAAA,CAAO,CAAA,EAAG,OAAA,CAAQ,CAAA,EAAG,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyCxB,WAAA,OACd,OAAA,EAAS,OAAA,CAAQ,CAAA,WAAY,OAAA,CAAQ,CAAA,IACrC,OAAA,GAAU,KAAA,cAAmB,CAAA,GAC5B,WAAA,CAAY,CAAA,EAAG,OAAA,CAAQ,CAAA,EAAG,MAAA;;;;;;;;;;;;;iBAuBb,eAAA,IACd,OAAA,EAAS,OAAA,CAAQ,CAAA,WAAY,OAAA,CAAQ,CAAA,KACpC,WAAA,CAAY,CAAA;;;;;;;;;;;;;;;;;;KAuCV,KAAA,gFAGc,EAAA,aAAe,EAAA,aAAe,EAAA;;;;;;;;;;;;;;;;;;;;;iBAsBjC,GAAA,qBAAwB,QAAA,sBACtC,OAAA,eAAsB,EAAA,IACrB,QAAA,CAAO,KAAA,CAAM,EAAA,gBAAkB,EAAA,GAAK,IAAA,CAAK,EAAA,CAAG,CAAA,OAAQ,KAAA,CAAM,EAAA;;;;;;;;;;;;;;;;;;;;;;iBAsC7C,QAAA,qBAA6B,WAAA,sBAC3C,OAAA,eAAsB,EAAA,IACrB,WAAA,CAAY,KAAA,CAAM,EAAA,gBAAkB,EAAA,GAAK,SAAA,CAAU,EAAA,CAAG,CAAA,OAAQ,UAAA,CAAW,EAAA;;;;;;;;;;;;;;;;;;;;;;;cC7M/D,MAAA;EAAA;;;;;;;;;;;;;KAkBD,MAAA,SAAe,QAAA,CAAW,CAAA,EAAG,CAAA;;;KCnDpC,KAAA,GAAQ,MAAM;;;;;;;;KASP,mBAAA,+BAAkD,KAAA,IAAS,KAAA,GACrE,QAAA,CAAS,CAAA;EAAA,SAAgB,IAAA,EAAM,GAAA;AAAA;;;;;;;;;;;KAYrB,sBAAA;EAAA,eACK,KAAA,OAAY,IAAA,QAAY,CAAA,wBAAyB,CAAA,GAAI,mBAAA,CAAoB,GAAA,EAAK,CAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2C/E,WAAA,qBACd,GAAA,EAAK,GAAA,EACL,OAAA;EAAA,SAAqB,IAAA;AAAA,IACpB,sBAAA,CAAuB,GAAA;;;;;;;;;;KA4Bd,WAAA;EAA2B,IAAA;AAAA;EACrC,EAAA,GAAK,KAAA,EAAO,CAAA,KAAM,CAAA;EAClB,MAAA,GAAS,KAAA,cAAmB,CAAA;AAAA,YAClB,CAAA,YAAa,KAAA,EAAO,OAAA,CAAQ,CAAA;EAAK,IAAA,EAAM,CAAA;AAAA,OAAS,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgC5C,SAAA;EAAyB,IAAA;AAAA,MACvC,MAAA,EAAQ,QAAA,CAAO,CAAA,EAAG,CAAA,GAClB,QAAA,EAAU,WAAA,CAAY,CAAA,EAAG,CAAA,EAAG,CAAA,IAC3B,CAAA;AAAA,iBACa,SAAA;EAAyB,IAAA;AAAA,MACvC,MAAA,EAAQ,WAAA,CAAY,CAAA,EAAG,CAAA,GACvB,QAAA,EAAU,WAAA,CAAY,CAAA,EAAG,CAAA,EAAG,CAAA,IAC3B,OAAA,CAAQ,CAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -465,9 +465,16 @@ function fromNullable(value, onAbsent) {
|
|
|
465
465
|
* {@link Defect} (via {@link defect}) — there is no path that leaves `unknown`
|
|
466
466
|
* in `E`. A throw inside `qualify` itself is treated as a `Defect`.
|
|
467
467
|
*
|
|
468
|
+
* The modeled error type is `Exclude<R, Defect>` — the `Defect` arm of
|
|
469
|
+
* `qualify`'s return is **subtracted** from `E`, never inferred into it. So a
|
|
470
|
+
* `qualify` that returns *only* `defect(cause)` yields `E = never` (a defect is
|
|
471
|
+
* out-of-band and must not pollute the error channel); reach for
|
|
472
|
+
* {@link fromSafePromise} when every failure is a defect.
|
|
473
|
+
*
|
|
468
474
|
* @typeParam A - the wrapped function's argument tuple.
|
|
469
475
|
* @typeParam T - the wrapped function's return type.
|
|
470
|
-
* @typeParam
|
|
476
|
+
* @typeParam R - `qualify`'s return type; the modeled error `E` is
|
|
477
|
+
* `Exclude<R, Defect>` (its `Defect` arm, if any, is subtracted).
|
|
471
478
|
* @param fn - the throwing function to wrap.
|
|
472
479
|
* @param qualify - triages a thrown cause into `E` or a `Defect`.
|
|
473
480
|
* @returns a function with the same arguments returning `Result<T, E>`.
|
|
@@ -480,11 +487,12 @@ function fromNullable(value, onAbsent) {
|
|
|
480
487
|
* ```
|
|
481
488
|
*/
|
|
482
489
|
function fromThrowable(fn, qualify) {
|
|
490
|
+
const triage = qualify;
|
|
483
491
|
return (...args) => {
|
|
484
492
|
try {
|
|
485
493
|
return ok(fn(...args));
|
|
486
494
|
} catch (cause) {
|
|
487
|
-
return qualifyToResult(cause,
|
|
495
|
+
return qualifyToResult(cause, triage);
|
|
488
496
|
}
|
|
489
497
|
};
|
|
490
498
|
}
|
|
@@ -498,8 +506,14 @@ function fromThrowable(fn, qualify) {
|
|
|
498
506
|
* `await`-ing it always yields a `Result`. A throw inside `qualify` is itself a
|
|
499
507
|
* `Defect`.
|
|
500
508
|
*
|
|
509
|
+
* The modeled error type is `Exclude<R, Defect>` — the `Defect` arm of
|
|
510
|
+
* `qualify`'s return is **subtracted** from `E`, never inferred into it. So a
|
|
511
|
+
* `qualify` that returns *only* `defect(cause)` yields `E = never`; when every
|
|
512
|
+
* rejection is a defect, prefer {@link fromSafePromise}.
|
|
513
|
+
*
|
|
501
514
|
* @typeParam T - the resolved value type.
|
|
502
|
-
* @typeParam
|
|
515
|
+
* @typeParam R - `qualify`'s return type; the modeled error `E` is
|
|
516
|
+
* `Exclude<R, Defect>` (its `Defect` arm, if any, is subtracted).
|
|
503
517
|
* @param promise - the promise, or a thunk returning one.
|
|
504
518
|
* @param qualify - triages a rejection cause into `E` or a `Defect`.
|
|
505
519
|
*
|
|
@@ -512,7 +526,8 @@ function fromThrowable(fn, qualify) {
|
|
|
512
526
|
* ```
|
|
513
527
|
*/
|
|
514
528
|
function fromPromise(promise, qualify) {
|
|
515
|
-
|
|
529
|
+
const triage = qualify;
|
|
530
|
+
return new AsyncRes((typeof promise === "function" ? Promise.resolve().then(promise) : promise).then((value) => okRes(value), (cause) => qualifyToResult(cause, triage)));
|
|
516
531
|
}
|
|
517
532
|
/**
|
|
518
533
|
* Wrap a `Promise` asserted **not** to fail in any modeled way: any rejection
|
|
@@ -538,22 +553,23 @@ function qualifyToResult(cause, qualify) {
|
|
|
538
553
|
}
|
|
539
554
|
}
|
|
540
555
|
/**
|
|
541
|
-
* Collect
|
|
542
|
-
* success values.
|
|
556
|
+
* Collect {@link Result}s into a single `Result` of all their success values.
|
|
543
557
|
*
|
|
544
558
|
* @remarks
|
|
545
559
|
* Short-circuits on the **first** `Err` (later entries are not inspected for
|
|
546
560
|
* their error); any `Defect` present **dominates**, winning even over an earlier
|
|
547
|
-
* `Err`.
|
|
548
|
-
* `Result<[number, string],
|
|
561
|
+
* `Err`. A **fixed tuple** keeps its positional types — `all([ok(1), ok("a")])`
|
|
562
|
+
* is `Result<[number, string], …>` — while a **dynamic array** `Result<T, E>[]`
|
|
563
|
+
* collapses to `Result<T[], E>` with no cast.
|
|
549
564
|
*
|
|
550
|
-
* @typeParam Rs - the tuple of input `Result` types.
|
|
565
|
+
* @typeParam Rs - the tuple/array of input `Result` types.
|
|
551
566
|
* @param results - the results to combine.
|
|
552
567
|
*
|
|
553
568
|
* @example
|
|
554
569
|
* ```ts
|
|
555
570
|
* import { all, ok } from "unthrown";
|
|
556
|
-
* all([ok(1), ok("a"), ok(true)]).unwrap(); // [1, "a", true]
|
|
571
|
+
* all([ok(1), ok("a"), ok(true)]).unwrap(); // [1, "a", true] (typed [number, string, boolean])
|
|
572
|
+
* all([ok(1), ok(2)] as Result<number, never>[]).unwrap(); // number[]
|
|
557
573
|
* ```
|
|
558
574
|
*/
|
|
559
575
|
function all(results) {
|
|
@@ -567,6 +583,30 @@ function all(results) {
|
|
|
567
583
|
if (firstErr) return firstErr;
|
|
568
584
|
return ok(values);
|
|
569
585
|
}
|
|
586
|
+
/**
|
|
587
|
+
* The asynchronous counterpart of {@link all}: combine {@link AsyncResult}s into
|
|
588
|
+
* one `AsyncResult` of all their success values.
|
|
589
|
+
*
|
|
590
|
+
* @remarks
|
|
591
|
+
* The inputs are resolved **concurrently** (their order is preserved); the
|
|
592
|
+
* resolved `Result`s are then folded with the same rules as {@link all} —
|
|
593
|
+
* first `Err` short-circuits, any `Defect` dominates. As ever, the returned
|
|
594
|
+
* `AsyncResult`'s internal promise never rejects. A **fixed tuple** keeps its
|
|
595
|
+
* positional types; a **dynamic array** `AsyncResult<T, E>[]` collapses to
|
|
596
|
+
* `AsyncResult<T[], E>`.
|
|
597
|
+
*
|
|
598
|
+
* @typeParam Rs - the tuple/array of input `AsyncResult` types.
|
|
599
|
+
* @param results - the async results to combine.
|
|
600
|
+
*
|
|
601
|
+
* @example
|
|
602
|
+
* ```ts
|
|
603
|
+
* import { allAsync, fromSafePromise } from "unthrown";
|
|
604
|
+
* const both = await allAsync([fromSafePromise(a()), fromSafePromise(b())]);
|
|
605
|
+
* ```
|
|
606
|
+
*/
|
|
607
|
+
function allAsync(results) {
|
|
608
|
+
return new AsyncRes(Promise.all(results).then((resolved) => all(resolved)));
|
|
609
|
+
}
|
|
570
610
|
//#endregion
|
|
571
611
|
//#region src/facade.ts
|
|
572
612
|
/**
|
|
@@ -574,7 +614,8 @@ function all(results) {
|
|
|
574
614
|
* discoverable namespace: {@link Result.ok}, {@link Result.err},
|
|
575
615
|
* {@link Result.defect}, {@link Result.fromNullable}, {@link Result.fromThrowable},
|
|
576
616
|
* {@link Result.fromPromise}, {@link Result.fromSafePromise}, {@link Result.all},
|
|
577
|
-
* {@link Result.
|
|
617
|
+
* {@link Result.allAsync}, {@link Result.isOk}, {@link Result.isErr},
|
|
618
|
+
* {@link Result.isDefect}.
|
|
578
619
|
*
|
|
579
620
|
* @remarks
|
|
580
621
|
* Purely additive sugar — each member **is** the corresponding free function.
|
|
@@ -597,6 +638,7 @@ const Result = {
|
|
|
597
638
|
fromPromise,
|
|
598
639
|
fromSafePromise,
|
|
599
640
|
all,
|
|
641
|
+
allAsync,
|
|
600
642
|
isOk,
|
|
601
643
|
isErr,
|
|
602
644
|
isDefect
|
|
@@ -613,8 +655,26 @@ const Result = {
|
|
|
613
655
|
* field in the payload is forwarded to `Error`. The `_tag` always reflects
|
|
614
656
|
* `tag` and cannot be overridden by the payload.
|
|
615
657
|
*
|
|
658
|
+
* `_tag` is the discriminant used by {@link matchTags}; `Error.name` is the
|
|
659
|
+
* human-facing label in stack traces and logs. By default they coincide, but
|
|
660
|
+
* they can be **decoupled** with `options.name` — so a tag can be namespaced for
|
|
661
|
+
* collision-safety (`"@my-lib/RetryableError"`) without that slash-prefixed
|
|
662
|
+
* string leaking into `Error.name`:
|
|
663
|
+
*
|
|
664
|
+
* ```ts
|
|
665
|
+
* class RetryableError extends TaggedError("@my-lib/RetryableError", {
|
|
666
|
+
* name: "RetryableError",
|
|
667
|
+
* })<{ message: string }> {}
|
|
668
|
+
*
|
|
669
|
+
* const e = new RetryableError({ message: "boom" });
|
|
670
|
+
* e._tag; // "@my-lib/RetryableError" — namespaced discriminant
|
|
671
|
+
* e.name; // "RetryableError" — clean display name
|
|
672
|
+
* ```
|
|
673
|
+
*
|
|
616
674
|
* @typeParam Tag - the string literal discriminant.
|
|
617
|
-
* @param tag - the discriminant value
|
|
675
|
+
* @param tag - the discriminant value; also the default error `name`.
|
|
676
|
+
* @param options - optional overrides. `options.name` sets `Error.name`
|
|
677
|
+
* independently of `tag` (defaults to `tag`).
|
|
618
678
|
*
|
|
619
679
|
* @example
|
|
620
680
|
* ```ts
|
|
@@ -625,14 +685,15 @@ const Result = {
|
|
|
625
685
|
* new HttpError({ status: 500 }).status; // 500
|
|
626
686
|
* ```
|
|
627
687
|
*/
|
|
628
|
-
function TaggedError(tag) {
|
|
688
|
+
function TaggedError(tag, options) {
|
|
689
|
+
const displayName = options?.name ?? tag;
|
|
629
690
|
class TaggedErrorBase extends Error {
|
|
630
691
|
_tag;
|
|
631
692
|
constructor(props) {
|
|
632
693
|
super(typeof props?.["message"] === "string" ? props["message"] : void 0);
|
|
633
694
|
if (props) Object.assign(this, props);
|
|
634
695
|
this._tag = tag;
|
|
635
|
-
this.name =
|
|
696
|
+
this.name = displayName;
|
|
636
697
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
637
698
|
}
|
|
638
699
|
}
|
|
@@ -650,6 +711,6 @@ function matchTags(result, handlers) {
|
|
|
650
711
|
});
|
|
651
712
|
}
|
|
652
713
|
//#endregion
|
|
653
|
-
export { Result, TaggedError, UnwrapError, all, defect, err, fromNullable, fromPromise, fromSafePromise, fromThrowable, isDefect, isErr, isOk, matchTags, ok };
|
|
714
|
+
export { Result, TaggedError, UnwrapError, all, allAsync, defect, err, fromNullable, fromPromise, fromSafePromise, fromThrowable, isDefect, isErr, isOk, matchTags, ok };
|
|
654
715
|
|
|
655
716
|
//# sourceMappingURL=index.mjs.map
|