unthrown 0.1.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.
@@ -0,0 +1,663 @@
1
+ //#region src/types.d.ts
2
+ /**
3
+ * The method surface every {@link Result} variant carries. Factored out so the
4
+ * three variants ({@link OkView}, {@link ErrView}, {@link DefectView}) can each
5
+ * intersect it. Not part of the public API on its own.
6
+ *
7
+ * @typeParam T - the success value type.
8
+ * @typeParam E - the modeled error type.
9
+ * @internal
10
+ */
11
+ type ResultMethods<T, E> = {
12
+ /**
13
+ * Transform the success value with `f`.
14
+ *
15
+ * Runs `f` only on `Ok`; `Err` and `Defect` pass through untouched. If `f`
16
+ * throws, the thrown value is captured as a `Defect`.
17
+ *
18
+ * @typeParam U - the mapped success type.
19
+ * @param f - maps the current success value to a new one.
20
+ */
21
+ map<U>(f: (value: T) => U): Result$1<U, E>;
22
+ /**
23
+ * Sequence a dependent, `Result`-returning step (monadic bind).
24
+ *
25
+ * Runs `f` only on `Ok`; `Err` and `Defect` pass through. The error channels
26
+ * combine, widening to `E | E2`. If `f` throws, the throw becomes a `Defect`.
27
+ *
28
+ * @typeParam U - the success type of the next step.
29
+ * @typeParam E2 - the error type the next step may introduce.
30
+ * @param f - produces the next `Result` from the current success value.
31
+ */
32
+ flatMap<U, E2>(f: (value: T) => Result$1<U, E2>): Result$1<U, E | E2>;
33
+ /**
34
+ * Run a side effect on the success value and pass the `Result` through
35
+ * unchanged.
36
+ *
37
+ * Runs only on `Ok`. If `f` throws, the throw becomes a `Defect`.
38
+ *
39
+ * @param f - the side effect (its return value is ignored).
40
+ */
41
+ tap(f: (value: T) => void): Result$1<T, E>;
42
+ /**
43
+ * Replace the success value with a constant `value`.
44
+ *
45
+ * Runs only on `Ok`; `Err` and `Defect` pass through.
46
+ *
47
+ * @typeParam U - the replacement value type.
48
+ */
49
+ as<U>(value: U): Result$1<U, E>;
50
+ /**
51
+ * Transform the modeled error with `f`.
52
+ *
53
+ * Runs `f` only on `Err`; `Ok` passes through and a `Defect` is **never**
54
+ * touched. If `f` throws, the throw becomes a `Defect`.
55
+ *
56
+ * @typeParam E2 - the mapped error type.
57
+ * @param f - maps the current error to a new one.
58
+ */
59
+ mapErr<E2>(f: (error: E) => E2): Result$1<T, E2>;
60
+ /**
61
+ * Recover from an `Err` by producing another `Result`.
62
+ *
63
+ * Runs `f` only on `Err`; `Ok` and `Defect` pass through. If `f` throws, the
64
+ * throw becomes a `Defect`.
65
+ *
66
+ * @typeParam U - an alternative success type `f` may produce.
67
+ * @typeParam E2 - the error type `f` may produce instead.
68
+ * @param f - produces a fallback `Result` from the current error.
69
+ */
70
+ orElse<U, E2>(f: (error: E) => Result$1<U, E2>): Result$1<T | U, E2>;
71
+ /**
72
+ * Recover from an `Err` by producing a success value, emptying the error
73
+ * channel.
74
+ *
75
+ * @remarks
76
+ * The result type is `Result<T | U, never>`, but `never` describes only the
77
+ * **error** channel — a `Defect` can still be present at runtime, so do not
78
+ * read `never` as "total". Runs `f` only on `Err`; `Ok` and `Defect` pass
79
+ * through. If `f` throws, the throw becomes a `Defect`.
80
+ *
81
+ * @typeParam U - the recovered success type.
82
+ * @param f - produces a success value from the current error.
83
+ */
84
+ recover<U>(f: (error: E) => U): Result$1<T | U, never>;
85
+ /**
86
+ * Run a side effect on the error and pass the `Result` through unchanged.
87
+ *
88
+ * Runs only on `Err`. If `f` throws, the throw becomes a `Defect`.
89
+ *
90
+ * @param f - the side effect (its return value is ignored).
91
+ */
92
+ tapErr(f: (error: E) => void): Result$1<T, E>;
93
+ /**
94
+ * Recover from a `Defect` — the **only** combinator that can touch one.
95
+ *
96
+ * @remarks
97
+ * Runs `f` only when a `Defect` is present, re-entering the modeled world by
98
+ * returning a `Result` (an `Ok` or a fresh `Err`). `Ok` and `Err` pass
99
+ * through. Recovering a defect should be rare: usually you let it bubble to
100
+ * the edge. If `f` throws, the throw becomes a new `Defect`.
101
+ *
102
+ * @typeParam U - a success type the recovery may produce.
103
+ * @typeParam E2 - an error type the recovery may produce.
104
+ * @param f - maps the defect's unknown cause to a recovering `Result`.
105
+ */
106
+ recoverDefect<U, E2>(f: (cause: unknown) => Result$1<U, E2>): Result$1<T | U, E | E2>;
107
+ /**
108
+ * Run a side effect on a present `Defect`'s cause (e.g. logging) and pass the
109
+ * `Defect` through unchanged.
110
+ *
111
+ * @param f - the side effect over the unknown cause.
112
+ */
113
+ tapDefect(f: (cause: unknown) => void): Result$1<T, E>;
114
+ /**
115
+ * Exhaustively fold all three runtime states into a single value of type `R`.
116
+ *
117
+ * @remarks
118
+ * Exactly one handler runs. Together with the throw-to-defect guarantee, this
119
+ * is typically the single place a pipeline is handled at the edge — mapping
120
+ * `ok`/`err`/`defect` to (for example) 2xx / 4xx / 5xx with no `try`/`catch`.
121
+ * (For richer matching, a `Result` is also a discriminated union — branch on
122
+ * its `tag` property, e.g. with `ts-pattern`.)
123
+ *
124
+ * @typeParam R - the folded result type.
125
+ * @param cases - one handler per channel.
126
+ */
127
+ match<R>(cases: {
128
+ ok: (value: T) => R;
129
+ err: (error: E) => R;
130
+ defect: (cause: unknown) => R;
131
+ }): R;
132
+ /**
133
+ * Extract the success value.
134
+ *
135
+ * @returns the `Ok` value.
136
+ * @throws On `Err`, an {@link UnwrapError} carrying the error. On a `Defect`,
137
+ * re-throws the **original cause** with its original stack, so an unhandled
138
+ * defect surfaces at the global handler as the real failure.
139
+ */
140
+ unwrap(): T;
141
+ /**
142
+ * Extract the modeled error.
143
+ *
144
+ * @returns the `Err` value.
145
+ * @throws On `Ok`, an {@link UnwrapError} carrying the value. On a `Defect`,
146
+ * re-throws the original cause.
147
+ */
148
+ unwrapErr(): E;
149
+ /**
150
+ * The success value, or `fallback` on `Err`.
151
+ *
152
+ * @param fallback - returned when the result is an `Err`.
153
+ * @throws Re-throws on a `Defect` — a defect is a bug, not an absent value, so
154
+ * it is never silently replaced.
155
+ */
156
+ unwrapOr(fallback: T): T;
157
+ /**
158
+ * The success value, or `f(error)` on `Err`.
159
+ *
160
+ * @param f - lazily computes the fallback from the error.
161
+ * @throws Re-throws on a `Defect`.
162
+ */
163
+ unwrapOrElse(f: (error: E) => T): T;
164
+ /**
165
+ * The success value, or `null` on `Err`.
166
+ *
167
+ * @throws Re-throws on a `Defect`.
168
+ */
169
+ getOrNull(): T | null;
170
+ /**
171
+ * The success value, or `undefined` on `Err`.
172
+ *
173
+ * @throws Re-throws on a `Defect`.
174
+ */
175
+ getOrUndefined(): T | undefined; /** Whether this result is `Ok`. */
176
+ isOk(): boolean; /** Whether this result is `Err`. */
177
+ isErr(): boolean; /** Whether this result is a `Defect`. */
178
+ isDefect(): boolean; /** Lift this synchronous `Result` into an {@link AsyncResult}. */
179
+ toAsync(): AsyncResult<T, E>;
180
+ };
181
+ /** The `Ok` variant of a {@link Result}: a success carrying a `value`. */
182
+ type OkView<T, E = never> = ResultMethods<T, E> & {
183
+ readonly tag: "Ok";
184
+ readonly value: T;
185
+ };
186
+ /** The `Err` variant of a {@link Result}: a modeled failure carrying an `error`. */
187
+ type ErrView<E, T = never> = ResultMethods<T, E> & {
188
+ readonly tag: "Err";
189
+ readonly error: E;
190
+ };
191
+ /** The `Defect` variant of a {@link Result}: an unmodeled failure carrying a `cause`. */
192
+ type DefectView<T = never, E = never> = ResultMethods<T, E> & {
193
+ readonly tag: "Defect";
194
+ readonly cause: unknown;
195
+ };
196
+ /**
197
+ * The core type of the library: a computation that has either succeeded with a
198
+ * value of type `T` or failed with a *modeled* error of type `E`.
199
+ *
200
+ * @remarks
201
+ * A `Result` is a **discriminated union** of three variants, distinguished by a
202
+ * `tag` of `"Ok"` | `"Err"` | `"Defect"`:
203
+ *
204
+ * - **`Ok`** — a success carrying a `value: T`.
205
+ * - **`Err`** — a modeled, anticipated failure carrying an `error: E`.
206
+ * - **`Defect`** — an *unmodeled* failure carrying an unknown `cause`. A defect
207
+ * never appears in `E`; it is the library's third, out-of-band channel.
208
+ *
209
+ * Because it is a real union, you can match it natively (a `switch` on `tag`, or
210
+ * `ts-pattern`'s `match(...).with({ tag: "Ok" }, …).exhaustive()`), *and* it
211
+ * carries the full method surface ({@link ResultMethods}) for fluent chaining.
212
+ * Either way, the payload (`value`/`error`/`cause`) is only reachable after you
213
+ * narrow — so "check before you access" still holds.
214
+ *
215
+ * @typeParam T - the success value type.
216
+ * @typeParam E - the modeled error type (only anticipated domain failures).
217
+ *
218
+ * @example
219
+ * ```ts
220
+ * import { ok, err, type Result } from "unthrown";
221
+ *
222
+ * function half(n: number): Result<number, "odd"> {
223
+ * return n % 2 === 0 ? ok(n / 2) : err("odd");
224
+ * }
225
+ *
226
+ * const message = half(10).match({
227
+ * ok: (n) => `got ${n}`,
228
+ * err: (e) => `failed: ${e}`,
229
+ * defect: (cause) => `bug: ${String(cause)}`,
230
+ * });
231
+ * ```
232
+ */
233
+ type Result$1<T, E> = OkView<T, E> | ErrView<E, T> | DefectView<T, E>;
234
+ /**
235
+ * A success-only thenable: awaitable, but deliberately **not** a full
236
+ * `PromiseLike`.
237
+ *
238
+ * @remarks
239
+ * An {@link AsyncResult}'s internal promise never rejects, so `await`-ing one
240
+ * always yields a {@link Result} and never throws — there is no rejection
241
+ * channel to model, and none is advertised. At runtime it is still a thenable
242
+ * (the only way `await` can collapse it); the narrowing simply keeps it from
243
+ * being treated as a raw promise (e.g. dropped into `Promise.all`).
244
+ *
245
+ * @typeParam T - the value `await` resolves to.
246
+ */
247
+ type Awaitable<T> = {
248
+ then<R = T>(onfulfilled?: ((value: T) => R | PromiseLike<R>) | null): PromiseLike<R>;
249
+ };
250
+ /**
251
+ * The asynchronous counterpart of {@link Result}: an awaitable wrapper with the
252
+ * same method surface, collapsing to a `Result<T, E>` when `await`-ed.
253
+ *
254
+ * @remarks
255
+ * **Combinator callbacks are synchronous.** A raw `Promise` may never enter an
256
+ * `AsyncResult` method — that would be an un-qualified async boundary, and its
257
+ * rejection would silently become a `Defect`, skipping the triage that
258
+ * {@link fromPromise} forces. To do further async work, re-enter through a
259
+ * qualified boundary and compose it: `ar.flatMap((v) => fromPromise(work(v),
260
+ * qualify))`. The eliminators (`unwrap`, …) return promises; the binds
261
+ * (`flatMap`, `orElse`, `recoverDefect`) additionally accept an `AsyncResult`.
262
+ *
263
+ * To pattern-match an `AsyncResult`, `await` it first: `match(await ar)`.
264
+ *
265
+ * @typeParam T - the success value type.
266
+ * @typeParam E - the modeled error type.
267
+ */
268
+ type AsyncResult<T, E> = Awaitable<Result$1<T, E>> & {
269
+ /** Asynchronous `map`. `f` is synchronous; a throw becomes a `Defect`. */map<U>(f: (value: T) => U): AsyncResult<U, E>;
270
+ /**
271
+ * Asynchronous `flatMap`. `f` may return a `Result` **or** an `AsyncResult`
272
+ * (never a raw `Promise`); a throw becomes a `Defect`.
273
+ */
274
+ flatMap<U, E2>(f: (value: T) => Result$1<U, E2> | AsyncResult<U, E2>): AsyncResult<U, E | E2>; /** Asynchronous `tap`. `f` is synchronous; a throw becomes a `Defect`. */
275
+ tap(f: (value: T) => void): AsyncResult<T, E>; /** Asynchronous `as`. */
276
+ as<U>(value: U): AsyncResult<U, E>; /** Asynchronous `mapErr`. `f` is synchronous; a throw becomes a `Defect`. */
277
+ mapErr<E2>(f: (error: E) => E2): AsyncResult<T, E2>; /** Asynchronous `orElse`. `f` may return a `Result` or an `AsyncResult`. */
278
+ orElse<U, E2>(f: (error: E) => Result$1<U, E2> | AsyncResult<U, E2>): AsyncResult<T | U, E2>; /** Asynchronous `recover`. `f` is synchronous; a throw becomes a `Defect`. */
279
+ recover<U>(f: (error: E) => U): AsyncResult<T | U, never>; /** Asynchronous `tapErr`. `f` is synchronous; a throw becomes a `Defect`. */
280
+ tapErr(f: (error: E) => void): AsyncResult<T, E>; /** Asynchronous `recoverDefect`. `f` may return a `Result` or an `AsyncResult`. */
281
+ recoverDefect<U, E2>(f: (cause: unknown) => Result$1<U, E2> | AsyncResult<U, E2>): AsyncResult<T | U, E | E2>; /** Asynchronous `tapDefect`. */
282
+ tapDefect(f: (cause: unknown) => void): AsyncResult<T, E>; /** Asynchronous `match`. Handlers are synchronous; resolves to `R`. */
283
+ match<R>(cases: {
284
+ ok: (value: T) => R;
285
+ err: (error: E) => R;
286
+ defect: (cause: unknown) => R;
287
+ }): Promise<R>; /** Asynchronous `unwrap`. The returned promise rejects on `Err`/`Defect`. */
288
+ unwrap(): Promise<T>; /** Asynchronous `unwrapErr`. */
289
+ unwrapErr(): Promise<E>; /** Asynchronous `unwrapOr`. */
290
+ unwrapOr(fallback: T): Promise<T>; /** Asynchronous `unwrapOrElse`. */
291
+ unwrapOrElse(f: (error: E) => T): Promise<T>; /** Asynchronous `getOrNull`. */
292
+ getOrNull(): Promise<T | null>; /** Asynchronous `getOrUndefined`. */
293
+ getOrUndefined(): Promise<T | undefined>;
294
+ };
295
+ /**
296
+ * Extract the success type `T` from a `Result`.
297
+ *
298
+ * @typeParam R - the `Result` type to inspect.
299
+ */
300
+ type OkOf<R> = R extends {
301
+ readonly tag: "Ok";
302
+ readonly value: infer T;
303
+ } ? T : never;
304
+ /**
305
+ * Extract the error type `E` from a `Result`.
306
+ *
307
+ * @typeParam R - the `Result` type to inspect.
308
+ */
309
+ type ErrOf<R> = R extends {
310
+ readonly tag: "Err";
311
+ readonly error: infer E;
312
+ } ? E : never;
313
+ //#endregion
314
+ //#region src/constructors.d.ts
315
+ /**
316
+ * Construct a successful {@link Result}.
317
+ *
318
+ * @typeParam T - the success value type.
319
+ * @param value - the success value to wrap.
320
+ *
321
+ * @example
322
+ * ```ts
323
+ * import { ok } from "unthrown";
324
+ * ok(42).unwrap(); // 42
325
+ * ```
326
+ */
327
+ declare function ok<T>(value: T): Result$1<T, never>;
328
+ /**
329
+ * Construct a failed {@link Result} carrying a **modeled** error.
330
+ *
331
+ * @typeParam E - the modeled error type.
332
+ * @param error - the domain error to wrap.
333
+ *
334
+ * @example
335
+ * ```ts
336
+ * import { err } from "unthrown";
337
+ * err("not_found").unwrapErr(); // "not_found"
338
+ * ```
339
+ */
340
+ declare function err<E>(error: E): Result$1<never, E>;
341
+ /**
342
+ * Type guard: narrow a {@link Result} to its `Ok` variant, exposing `.value`.
343
+ *
344
+ * @returns `true` when `r` is `Ok`.
345
+ *
346
+ * @example
347
+ * ```ts
348
+ * import { isOk, type Result } from "unthrown";
349
+ * declare const r: Result<number, string>;
350
+ * if (isOk(r)) r.value; // number, narrowed
351
+ * ```
352
+ */
353
+ declare function isOk<T, E>(r: Result$1<T, E>): r is OkView<T, E>;
354
+ /**
355
+ * Type guard: narrow a {@link Result} to its `Err` variant, exposing `.error`.
356
+ *
357
+ * @returns `true` when `r` is `Err`.
358
+ */
359
+ declare function isErr<T, E>(r: Result$1<T, E>): r is ErrView<E, T>;
360
+ /**
361
+ * Type guard: narrow a {@link Result} to its `Defect` variant, exposing `.cause`.
362
+ *
363
+ * @returns `true` when `r` is a `Defect`.
364
+ */
365
+ declare function isDefect<T, E>(r: Result$1<T, E>): r is DefectView<T, E>;
366
+ //#endregion
367
+ //#region src/core.d.ts
368
+ /**
369
+ * Thrown by a {@link Result}'s `unwrap` / `unwrapErr` when the assertion is
370
+ * wrong on a *modeled* result — `unwrap()` on an `Err`, or `unwrapErr()` on an
371
+ * `Ok`.
372
+ *
373
+ * @remarks
374
+ * A `Defect` is never wrapped in an `UnwrapError`: its original cause is
375
+ * re-thrown (with its original stack) instead.
376
+ *
377
+ * @typeParam E - the type of the {@link UnwrapError.error} it carries.
378
+ */
379
+ declare class UnwrapError<E = unknown> extends Error {
380
+ /**
381
+ * The offending value: the `Err` error for `unwrap()`, or the `Ok` value for
382
+ * `unwrapErr()`.
383
+ */
384
+ readonly error: E;
385
+ constructor(error: E);
386
+ }
387
+ //#endregion
388
+ //#region src/defect.d.ts
389
+ declare const DEFECT: unique symbol;
390
+ /**
391
+ * The marker a `qualify` function returns to triage a cause as **unexpected**.
392
+ *
393
+ * @remarks
394
+ * `qualify` (passed to {@link fromPromise} / {@link fromThrowable}) returns
395
+ * `E | Defect`: either a modeled domain error, or a `Defect` produced by
396
+ * {@link defect} to say "this failure is not modeled". A `Defect` is opaque —
397
+ * it carries the original cause for the boundary to convert into the third
398
+ * runtime state of a `Result`.
399
+ */
400
+ type Defect = {
401
+ readonly [DEFECT]: true;
402
+ readonly cause: unknown;
403
+ };
404
+ /**
405
+ * Wrap a cause as a {@link Defect} — the value you return from a `qualify`
406
+ * function when a failure is **not** a modeled domain error.
407
+ *
408
+ * @param cause - the original thrown/rejected value.
409
+ * @returns an opaque defect marker carrying `cause`.
410
+ *
411
+ * @example
412
+ * ```ts
413
+ * import { fromPromise, defect } from "unthrown";
414
+ *
415
+ * const user = fromPromise(fetchUser(id), (cause) =>
416
+ * cause instanceof NotFoundError ? cause : defect(cause),
417
+ * );
418
+ * ```
419
+ */
420
+ declare function defect(cause: unknown): Defect;
421
+ //#endregion
422
+ //#region src/interop.d.ts
423
+ /**
424
+ * Bridge a nullable value into a {@link Result}: absence becomes a **modeled**
425
+ * `Err`. The sanctioned alternative to an `Option` type.
426
+ *
427
+ * @remarks
428
+ * `null` and `undefined` map to `err(onAbsent())`; any other value (including
429
+ * falsy ones like `0`, `""`, `false`) maps to `Ok`.
430
+ *
431
+ * @typeParam T - the (nullable) value type.
432
+ * @typeParam E - the error produced when the value is absent.
433
+ * @param value - the possibly-absent value.
434
+ * @param onAbsent - lazily produces the error for the absent case.
435
+ *
436
+ * @example
437
+ * ```ts
438
+ * import { fromNullable } from "unthrown";
439
+ * fromNullable(map.get(key), () => "missing").unwrap();
440
+ * ```
441
+ */
442
+ declare function fromNullable<T, E>(value: T | null | undefined, onAbsent: () => E): Result$1<NonNullable<T>, E>;
443
+ /**
444
+ * Wrap a throwing synchronous function so it returns a {@link Result} instead of
445
+ * throwing.
446
+ *
447
+ * @remarks
448
+ * `qualify` **must** triage every thrown cause into a modeled error `E` or a
449
+ * {@link Defect} (via {@link defect}) — there is no path that leaves `unknown`
450
+ * in `E`. A throw inside `qualify` itself is treated as a `Defect`.
451
+ *
452
+ * @typeParam A - the wrapped function's argument tuple.
453
+ * @typeParam T - the wrapped function's return type.
454
+ * @typeParam E - the modeled error type.
455
+ * @param fn - the throwing function to wrap.
456
+ * @param qualify - triages a thrown cause into `E` or a `Defect`.
457
+ * @returns a function with the same arguments returning `Result<T, E>`.
458
+ *
459
+ * @example
460
+ * ```ts
461
+ * import { fromThrowable, defect } from "unthrown";
462
+ * const parse = fromThrowable(JSON.parse, (cause) => defect(cause));
463
+ * parse("{}").unwrap();
464
+ * ```
465
+ */
466
+ declare function fromThrowable<A extends unknown[], T, E>(fn: (...args: A) => T, qualify: (cause: unknown) => E | Defect): (...args: A) => Result$1<T, E>;
467
+ /**
468
+ * Wrap a `Promise` (or a thunk producing one) as an {@link AsyncResult}, forcing
469
+ * every rejection to be triaged.
470
+ *
471
+ * @remarks
472
+ * `qualify` **must** map each rejection cause into a modeled error `E` or a
473
+ * {@link Defect}. The returned `AsyncResult`'s internal promise never rejects;
474
+ * `await`-ing it always yields a `Result`. A throw inside `qualify` is itself a
475
+ * `Defect`.
476
+ *
477
+ * @typeParam T - the resolved value type.
478
+ * @typeParam E - the modeled error type.
479
+ * @param promise - the promise, or a thunk returning one.
480
+ * @param qualify - triages a rejection cause into `E` or a `Defect`.
481
+ *
482
+ * @example
483
+ * ```ts
484
+ * import { fromPromise, defect } from "unthrown";
485
+ * const user = await fromPromise(fetchUser(id), (cause) =>
486
+ * cause instanceof NotFoundError ? ("not_found" as const) : defect(cause),
487
+ * );
488
+ * ```
489
+ */
490
+ declare function fromPromise<T, E>(promise: Promise<T> | (() => Promise<T>), qualify: (cause: unknown) => E | Defect): AsyncResult<T, E>;
491
+ /**
492
+ * Wrap a `Promise` asserted **not** to fail in any modeled way: any rejection
493
+ * becomes a `Defect`.
494
+ *
495
+ * @remarks
496
+ * Use this only when a rejection genuinely indicates a bug rather than an
497
+ * anticipated outcome — the error channel is `never`, so there is nothing to
498
+ * triage. (`await`-ing still yields a `Result`; it never throws.)
499
+ *
500
+ * @typeParam T - the resolved value type.
501
+ * @param promise - the promise, or a thunk returning one.
502
+ */
503
+ declare function fromSafePromise<T>(promise: Promise<T> | (() => Promise<T>)): AsyncResult<T, never>;
504
+ /**
505
+ * Collect a tuple of {@link Result}s into a single `Result` of the tuple of
506
+ * success values.
507
+ *
508
+ * @remarks
509
+ * Short-circuits on the **first** `Err` (later entries are not inspected for
510
+ * their error); any `Defect` present **dominates**, winning even over an earlier
511
+ * `Err`. Positional types are preserved, so `all([ok(1), ok("a")])` is
512
+ * `Result<[number, string], …>`.
513
+ *
514
+ * @typeParam Rs - the tuple of input `Result` types.
515
+ * @param results - the results to combine.
516
+ *
517
+ * @example
518
+ * ```ts
519
+ * import { all, ok } from "unthrown";
520
+ * all([ok(1), ok("a"), ok(true)]).unwrap(); // [1, "a", true]
521
+ * ```
522
+ */
523
+ declare function all<Rs extends readonly Result$1<unknown, unknown>[]>(results: readonly [...Rs]): Result$1<{ [K in keyof Rs]: OkOf<Rs[K]> }, ErrOf<Rs[number]>>;
524
+ //#endregion
525
+ //#region src/facade.d.ts
526
+ /**
527
+ * Companion object grouping the standalone entry points under a single,
528
+ * discoverable namespace: {@link Result.ok}, {@link Result.err},
529
+ * {@link Result.defect}, {@link Result.fromNullable}, {@link Result.fromThrowable},
530
+ * {@link Result.fromPromise}, {@link Result.fromSafePromise}, {@link Result.all},
531
+ * {@link Result.isOk}, {@link Result.isErr}, {@link Result.isDefect}.
532
+ *
533
+ * @remarks
534
+ * Purely additive sugar — each member **is** the corresponding free function.
535
+ * The free functions remain the primary, tree-shakeable API; importing only
536
+ * `{ ok }` never pulls this object in. The value `Result` and the type
537
+ * {@link Result} share one name (the companion-object pattern).
538
+ *
539
+ * @example
540
+ * ```ts
541
+ * import { Result } from "unthrown";
542
+ * Result.ok(1).flatMap((n) => Result.ok(n + 1)).unwrap(); // 2
543
+ * ```
544
+ */
545
+ declare const Result: {
546
+ readonly ok: typeof ok;
547
+ readonly err: typeof err;
548
+ readonly defect: typeof defect;
549
+ readonly fromNullable: typeof fromNullable;
550
+ readonly fromThrowable: typeof fromThrowable;
551
+ readonly fromPromise: typeof fromPromise;
552
+ readonly fromSafePromise: typeof fromSafePromise;
553
+ readonly all: typeof all;
554
+ readonly isOk: typeof isOk;
555
+ readonly isErr: typeof isErr;
556
+ readonly isDefect: typeof isDefect;
557
+ };
558
+ type Result<T, E> = Result$1<T, E>;
559
+ //#endregion
560
+ //#region src/tagged.d.ts
561
+ type Props = Record<string, unknown>;
562
+ /**
563
+ * The instance shape produced by a {@link TaggedError} class: an `Error` plus a
564
+ * `_tag` discriminant and the (readonly) payload fields.
565
+ *
566
+ * @typeParam Tag - the string literal discriminant.
567
+ * @typeParam A - the payload object type.
568
+ */
569
+ type TaggedErrorInstance<Tag extends string, A extends Props> = Error & Readonly<A> & {
570
+ readonly _tag: Tag;
571
+ };
572
+ /**
573
+ * The class constructor returned by {@link TaggedError}. Generic in its payload:
574
+ * apply it with an instantiation expression at the `extends` site.
575
+ *
576
+ * @remarks
577
+ * When the payload is empty, the constructor takes **no** arguments (the
578
+ * `keyof A extends never ? void : A` trick); otherwise it takes the payload.
579
+ *
580
+ * @typeParam Tag - the string literal discriminant.
581
+ */
582
+ type TaggedErrorConstructor<Tag extends string> = {
583
+ new <A extends Props = {}>(args: keyof A extends never ? void : A): TaggedErrorInstance<Tag, A>;
584
+ };
585
+ /**
586
+ * Build a base class for a tagged error — a class extending `Error` with a
587
+ * `_tag` string discriminant, in the style of Effect's `Data.TaggedError`.
588
+ *
589
+ * @remarks
590
+ * Extend the returned class to declare a concrete error. Supply the payload with
591
+ * an instantiation expression; omit it for a payload-less error. A `message`
592
+ * field in the payload is forwarded to `Error`. The `_tag` always reflects
593
+ * `tag` and cannot be overridden by the payload.
594
+ *
595
+ * @typeParam Tag - the string literal discriminant.
596
+ * @param tag - the discriminant value, also used as the error `name`.
597
+ *
598
+ * @example
599
+ * ```ts
600
+ * class NotFound extends TaggedError("NotFound") {}
601
+ * class HttpError extends TaggedError("HttpError")<{ status: number }> {}
602
+ *
603
+ * new NotFound()._tag; // "NotFound"
604
+ * new HttpError({ status: 500 }).status; // 500
605
+ * ```
606
+ */
607
+ declare function TaggedError<Tag extends string>(tag: Tag): TaggedErrorConstructor<Tag>;
608
+ /**
609
+ * The handler object {@link matchTags} requires: a branch per error tag, plus
610
+ * `Ok` and `Defect`. Miss a tag and it will not compile — the exhaustiveness is
611
+ * enforced by the type, with no `.exhaustive()` to forget.
612
+ *
613
+ * @typeParam T - the success value type.
614
+ * @typeParam E - the tagged error union.
615
+ * @typeParam R - the folded result type.
616
+ */
617
+ type TagHandlers<T, E extends {
618
+ _tag: string;
619
+ }, R> = {
620
+ Ok: (value: T) => R;
621
+ Defect: (cause: unknown) => R;
622
+ } & { [K in E["_tag"]]: (error: Extract<E, {
623
+ _tag: K;
624
+ }>) => R };
625
+ /**
626
+ * Exhaustively fold a {@link Result} (or {@link AsyncResult}) whose error type is
627
+ * a tagged union, dispatching each error to the handler matching its `_tag`.
628
+ *
629
+ * @remarks
630
+ * The `handlers` object must provide `Ok`, `Defect`, and exactly one function
631
+ * per error tag; each tag's handler receives the narrowed error variant. A
632
+ * missing tag is a compile error. For an `AsyncResult`, the fold resolves to a
633
+ * `Promise<R>`.
634
+ *
635
+ * @typeParam T - the success value type.
636
+ * @typeParam E - the tagged error union (`E extends { _tag: string }`).
637
+ * @typeParam R - the folded result type.
638
+ * @param result - the result to fold.
639
+ * @param handlers - one branch per channel/tag.
640
+ *
641
+ * @example
642
+ * ```ts
643
+ * class NotFound extends TaggedError("NotFound") {}
644
+ * class Forbidden extends TaggedError("Forbidden")<{ user: string }> {}
645
+ *
646
+ * declare const r: Result<number, NotFound | Forbidden>;
647
+ * matchTags(r, {
648
+ * Ok: (n) => `got ${n}`,
649
+ * Defect: (cause) => `bug: ${String(cause)}`,
650
+ * NotFound: () => "404",
651
+ * Forbidden: (e) => `403 for ${e.user}`,
652
+ * });
653
+ * ```
654
+ */
655
+ declare function matchTags<T, E extends {
656
+ _tag: string;
657
+ }, R>(result: Result$1<T, E>, handlers: TagHandlers<T, E, R>): R;
658
+ declare function matchTags<T, E extends {
659
+ _tag: string;
660
+ }, R>(result: AsyncResult<T, E>, handlers: TagHandlers<T, E, R>): Promise<R>;
661
+ //#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 };
663
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +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;EAhEhC;;;;;;;EAwEX,MAAA,CAAO,CAAA,GAAI,KAAA,EAAO,CAAA,YAAa,QAAA,CAAO,CAAA,EAAG,CAAA;EA7D9B;;;;;;;;;;;;;EA4EX,aAAA,QAAqB,CAAA,GAAI,KAAA,cAAmB,QAAA,CAAO,CAAA,EAAG,EAAA,IAAM,QAAA,CAAO,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA;EAnE1E;;;;;;EA0EJ,SAAA,CAAU,CAAA,GAAI,KAAA,qBAA0B,QAAA,CAAO,CAAA,EAAG,CAAA;EAlE5C;;;;;;;;;;;;;EAiFN,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;EA3DhE;;;;;;;;EAoE/B,MAAA,IAAU,CAAA;EAtDF;;;;;;;EA8DR,SAAA,IAAa,CAAA;EAtDb;;;;;;;EA8DA,QAAA,CAAS,QAAA,EAAU,CAAA,GAAI,CAAA;EA/CT;;;;;;EAsDd,YAAA,CAAa,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,CAAA,GAAI,CAAA;EAtD0B;;;;;EA4D5D,SAAA,IAAa,CAAA;EArDC;;;;;EA2Dd,cAAA,IAAkB,CAAA,cA5CZ;EA+CN,IAAA,aA/C8B;EAiD9B,KAAA,aAjDoC;EAmDpC,QAAA,aAnDoD;EAsDpD,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;;;;;;;;;;;;;;;;;;AAEmB;AAGnB;KA+CY,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;AA7DjE;AAGnB;;;;;;;;;;;;;;;;AAEgB;AALG,KAkFP,WAAA,SAAoB,SAAA,CAAU,QAAA,CAAO,CAAA,EAAG,CAAA;EArClC,0EAuChB,GAAA,IAAO,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,CAAA,GAAI,WAAA,CAAY,CAAA,EAAG,CAAA;EAvCX;;;;EA4ChC,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,GA5ChD;EA8CxC,GAAA,CAAI,CAAA,GAAI,KAAA,EAAO,CAAA,YAAa,WAAA,CAAY,CAAA,EAAG,CAAA,GA9C2B;EAgDtE,EAAA,IAAM,KAAA,EAAO,CAAA,GAAI,WAAA,CAAY,CAAA,EAAG,CAAA,GAhDkC;EAmDlE,MAAA,KAAW,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,EAAA,GAAK,WAAA,CAAY,CAAA,EAAG,EAAA,GAnD/B;EAqDjB,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,GArD9D;EAuDzB,OAAA,IAAW,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,CAAA,GAAI,WAAA,CAAY,CAAA,GAAI,CAAA,UAvDb;EAyDnC,MAAA,CAAO,CAAA,GAAI,KAAA,EAAO,CAAA,YAAa,WAAA,CAAY,CAAA,EAAG,CAAA,GAzDE;EA4DhD,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,GA9D8B;EAgExD,SAAA,CAAU,CAAA,GAAI,KAAA,qBAA0B,WAAA,CAAY,CAAA,EAAG,CAAA,GAhEe;EAmEtE,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,GAvDH;EAyDT,MAAA,IAAU,OAAA,CAAQ,CAAA,GAzDuB;EA2DzC,SAAA,IAAa,OAAA,CAAQ,CAAA,GA3DwB;EA6D7C,QAAA,CAAS,QAAA,EAAU,CAAA,GAAI,OAAA,CAAQ,CAAA,GA7DuC;EA+DtE,YAAA,CAAa,CAAA,GAAI,KAAA,EAAO,CAAA,KAAM,CAAA,GAAI,OAAA,CAAQ,CAAA,GA/DuC;EAiEjF,SAAA,IAAa,OAAA,CAAQ,CAAA,UAjErB;EAmEA,cAAA,IAAkB,OAAA,CAAQ,CAAA;AAAA;;;;;;KAQhB,IAAA,MAAU,CAAC;EAAA,SAAoB,GAAA;EAAA,SAAoB,KAAA;AAAA,IAAmB,CAAA;AA3EG;AAqBrF;;;;AArBqF,KAiFzE,KAAA,MAAW,CAAC;EAAA,SAAoB,GAAA;EAAA,SAAqB,KAAA;AAAA,IAAmB,CAAA;;;AAtUpF;;;;;;;;;;;;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;;;;;;;;;;;;;;;;;;;;;;;;iBA2BV,aAAA,4BACd,EAAA,MAAQ,IAAA,EAAM,CAAA,KAAM,CAAA,EACpB,OAAA,GAAU,KAAA,cAAmB,CAAA,GAAI,MAAA,OAC5B,IAAA,EAAM,CAAA,KAAM,QAAA,CAAO,CAAA,EAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;iBAiCb,WAAA,OACd,OAAA,EAAS,OAAA,CAAQ,CAAA,WAAY,OAAA,CAAQ,CAAA,IACrC,OAAA,GAAU,KAAA,cAAmB,CAAA,GAAI,MAAA,GAChC,WAAA,CAAY,CAAA,EAAG,CAAA;;;;;;;;;;;;;iBAqBF,eAAA,IACd,OAAA,EAAS,OAAA,CAAQ,CAAA,WAAY,OAAA,CAAQ,CAAA,KACpC,WAAA,CAAY,CAAA;;;;;;;;;;;;;;;;;;;;iBAyCC,GAAA,qBAAwB,QAAA,sBACtC,OAAA,eAAsB,EAAA,IACrB,QAAA,eAAqB,EAAA,GAAK,IAAA,CAAK,EAAA,CAAG,CAAA,MAAO,KAAA,CAAM,EAAA;;;;;;;;;;;;;;;;;;;;;;cCrIrC,MAAA;EAAA;;;;;;;;;;;;KAiBD,MAAA,SAAe,QAAA,CAAW,CAAA,EAAG,CAAA;;;KC1CpC,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;;;;;;;;;;;;;;;;;;;;;;;iBAyB/E,WAAA,qBAAgC,GAAA,EAAK,GAAA,GAAM,sBAAA,CAAuB,GAAA;;;;;;;;;;KA2BtE,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"}