@onrails/result 0.1.4 → 0.3.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.
Files changed (72) hide show
  1. package/DESIGN.md +11 -19
  2. package/README.md +14 -62
  3. package/RECIPES.md +12 -25
  4. package/dist/async-BR3AX0ck.d.cts +326 -0
  5. package/dist/async-SZ7BEl0g.d.ts +326 -0
  6. package/dist/compat/neverthrow.cjs +266 -94
  7. package/dist/compat/neverthrow.cjs.map +1 -1
  8. package/dist/compat/neverthrow.d.cts +4 -4
  9. package/dist/compat/neverthrow.d.ts +4 -4
  10. package/dist/compat/neverthrow.js +263 -91
  11. package/dist/compat/neverthrow.js.map +1 -1
  12. package/dist/extra.cjs +2 -25
  13. package/dist/extra.cjs.map +1 -1
  14. package/dist/extra.d.cts +7 -19
  15. package/dist/extra.d.ts +7 -19
  16. package/dist/extra.js +3 -25
  17. package/dist/extra.js.map +1 -1
  18. package/dist/fluent.cjs +55 -29
  19. package/dist/fluent.cjs.map +1 -1
  20. package/dist/fluent.d.cts +38 -11
  21. package/dist/fluent.d.ts +38 -11
  22. package/dist/fluent.js +55 -29
  23. package/dist/fluent.js.map +1 -1
  24. package/dist/index.cjs +290 -131
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +294 -69
  27. package/dist/index.d.ts +294 -69
  28. package/dist/index.js +287 -127
  29. package/dist/index.js.map +1 -1
  30. package/dist/pipe.cjs.map +1 -1
  31. package/dist/pipe.d.cts +7 -5
  32. package/dist/pipe.d.ts +7 -5
  33. package/dist/pipe.js.map +1 -1
  34. package/dist/railway.cjs +293 -188
  35. package/dist/railway.cjs.map +1 -1
  36. package/dist/railway.d.cts +26 -180
  37. package/dist/railway.d.ts +26 -180
  38. package/dist/railway.js +294 -178
  39. package/dist/railway.js.map +1 -1
  40. package/dist/try-gen.cjs +1 -1
  41. package/dist/try-gen.cjs.map +1 -1
  42. package/dist/try-gen.d.cts +29 -3
  43. package/dist/try-gen.d.ts +29 -3
  44. package/dist/try-gen.js +1 -1
  45. package/dist/try-gen.js.map +1 -1
  46. package/dist/types-BQ9vv0nD.d.cts +55 -0
  47. package/dist/types-BQ9vv0nD.d.ts +55 -0
  48. package/package.json +5 -18
  49. package/skills/railway-do-notation/SKILL.md +397 -0
  50. package/skills/result-composition/SKILL.md +323 -0
  51. package/dist/$.cjs +0 -40
  52. package/dist/$.cjs.map +0 -1
  53. package/dist/$.js +0 -36
  54. package/dist/$.js.map +0 -1
  55. package/dist/_.d.cts +0 -2
  56. package/dist/_.d.ts +0 -2
  57. package/dist/async-CH8Cs8KE.d.cts +0 -161
  58. package/dist/async-DKISqIBc.d.ts +0 -161
  59. package/dist/interop.cjs +0 -253
  60. package/dist/interop.cjs.map +0 -1
  61. package/dist/interop.d.cts +0 -35
  62. package/dist/interop.d.ts +0 -35
  63. package/dist/interop.js +0 -249
  64. package/dist/interop.js.map +0 -1
  65. package/dist/types-C2Dp1d5J.d.cts +0 -21
  66. package/dist/types-C2Dp1d5J.d.ts +0 -21
  67. package/dist/validation.cjs +0 -53
  68. package/dist/validation.cjs.map +0 -1
  69. package/dist/validation.d.cts +0 -72
  70. package/dist/validation.d.ts +0 -72
  71. package/dist/validation.js +0 -48
  72. package/dist/validation.js.map +0 -1
package/dist/index.d.cts CHANGED
@@ -1,10 +1,204 @@
1
- export { R as ResultAsync, e as errAsync, f as fromPromise, a as fromSafePromise, o as okAsync, p as parallelTupleAsync, s as sequenceTupleAsync, t as tryAsync } from './async-CH8Cs8KE.cjs';
2
- export { InferErr, InferOk, asyncAfter, fromAsync, fromResult } from './interop.cjs';
1
+ import { R as ResultAsync, I as InferErr, a as InferOk } from './async-BR3AX0ck.cjs';
2
+ import { R as Result, U as UnexpectedError, E as Err, O as Ok } from './types-BQ9vv0nD.cjs';
3
3
  export { flow } from './pipe.cjs';
4
- import { R as Result, E as Err, O as Ok } from './types-C2Dp1d5J.cjs';
5
- export { U as UnexpectedError } from './types-C2Dp1d5J.cjs';
6
4
  export { $, tryGen, yieldResult } from './try-gen.cjs';
7
5
 
6
+ /**
7
+ * @onrails/result — THE lift module. Every "value → {@link ResultAsync}"
8
+ * entry point is defined exactly once, here: `okAsync`, `errAsync`,
9
+ * `fromPromise`, `fromSafePromise`, `fromResult`, `fromAsync`, `asyncAfter`,
10
+ * `tryAsync`.
11
+ */
12
+
13
+ /**
14
+ * Lifts a value into an `Ok` async result.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const r = okAsync(42); // ResultAsync<number, never>
19
+ * ```
20
+ */
21
+ declare const okAsync: typeof ResultAsync.ok;
22
+ /**
23
+ * Lifts a value into an `Err` async result.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const r = errAsync({ kind: "not_found" as const });
28
+ * ```
29
+ */
30
+ declare const errAsync: typeof ResultAsync.err;
31
+ /**
32
+ * Wraps a `PromiseLike<T>` into a {@link ResultAsync}. Reject reasons go
33
+ * through `onReject` to become typed `Err`s; success becomes `Ok<T>`.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * const body = fromPromise(
38
+ * fetch(url).then((r) => r.text()),
39
+ * (e): NetworkError => ({ kind: "network", cause: String(e) }),
40
+ * );
41
+ * ```
42
+ */
43
+ declare const fromPromise: typeof ResultAsync.fromPromise;
44
+ /**
45
+ * Wraps a `PromiseLike<T>` that **never rejects** into {@link ResultAsync}.
46
+ * Skips the `onReject` mapper. Use only when the promise is provably safe.
47
+ */
48
+ declare const fromSafePromise: typeof ResultAsync.fromSafePromise;
49
+ /**
50
+ * Lifts an already-settled sync {@link Result} into a {@link ResultAsync}, so
51
+ * it can be chained alongside async steps in a railway.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * const ra = fromResult(ok(1)); // ResultAsync<number, never>
56
+ * await fromResult(err(error)).resolve(); // Err(error)
57
+ * ```
58
+ */
59
+ declare const fromResult: typeof ResultAsync.fromResult;
60
+ /**
61
+ * Bind a sync {@link Result} into an async step without widening defects.
62
+ * Dual-form: data-first for one-shots, data-last (curried) for `pipe`/`flow`.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * asyncAfter(result, (u) => tryAsync(db.insert(u), toErr)); // data-first
67
+ * asyncAfter((u) => tryAsync(db.insert(u), toErr)); // data-last
68
+ * ```
69
+ */
70
+ declare const asyncAfter: {
71
+ <T, U, E, F>(result: Result<T, E>, fn: (value: T) => ResultAsync<U, F>): ResultAsync<U, E | F>;
72
+ <T, U, F>(fn: (value: T) => ResultAsync<U, F>): <E>(result: Result<T, E>) => ResultAsync<U, E | F>;
73
+ };
74
+ type AnyResult = Result<unknown, unknown>;
75
+ /**
76
+ * Lifts a `(...args) => Promise<Result<T, E>>` function (typical of interop or
77
+ * boundary code) into one returning `(...args) => ResultAsync<T, E>`. Expected
78
+ * `Err`s pass through; an unexpected promise rejection (a defect) is routed via
79
+ * `onDefect`, defaulting to {@link UnexpectedError} and widening the error union.
80
+ *
81
+ * @param fn - a function returning a promise that already yields a `Result`
82
+ * @param onDefect - maps an unexpected rejection to the `Err` channel
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * const loadUser = fromAsync(
87
+ * (id: string): Promise<Result<User, NotFound>> => api.getUser(id),
88
+ * );
89
+ * const ra = loadUser("u1"); // ResultAsync<User, NotFound | UnexpectedError>
90
+ * ```
91
+ */
92
+ declare const fromAsync: <A extends readonly unknown[], R extends AnyResult>(fn: (...args: A) => Promise<R>, onDefect?: (error: unknown) => InferErr<R> | UnexpectedError) => ((...args: A) => ResultAsync<InferOk<R>, InferErr<R> | UnexpectedError>);
93
+ /**
94
+ * Convenience wrapper over {@link fromPromise} with default `Error`
95
+ * normalization. Call without `onReject` to get `ResultAsync<T, Error>`,
96
+ * or pass a custom mapper for a typed error.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * // Default: rejection → Err(Error)
101
+ * const a = tryAsync(db.users.insert(row));
102
+ *
103
+ * // Custom: typed error
104
+ * const b = tryAsync(db.users.insert(row), (e): DbError => ({
105
+ * kind: "db",
106
+ * cause: e,
107
+ * }));
108
+ * ```
109
+ */
110
+ declare function tryAsync<T>(promise: PromiseLike<T>): ResultAsync<T, Error>;
111
+ declare function tryAsync<T, E>(promise: PromiseLike<T>, onReject: (error: unknown) => E): ResultAsync<T, E>;
112
+
113
+ /**
114
+ * @onrails/result — sync aggregation, one module, two axes:
115
+ *
116
+ * short-circuit (first `Err` wins) — {@link combine} / {@link combineTuple}
117
+ * accumulate expected failures — {@link validateAll} / {@link validateTuple}
118
+ *
119
+ * The accumulate pair collects every failure into a readonly array by
120
+ * default, or folds them with an explicit `combineErrors` when given one.
121
+ */
122
+
123
+ /**
124
+ * Combines a homogeneous array of results into a single result holding an
125
+ * array of the `Ok` values, in input order. Short-circuits on the first `Err`
126
+ * (first failure wins). For heterogeneous tuples that preserve per-index
127
+ * types, use {@link combineTuple}.
128
+ *
129
+ * @example
130
+ * ```ts
131
+ * combine([ok(1), ok(2)]); // Ok([1, 2])
132
+ * combine([ok(1), err("e")]); // Err("e")
133
+ * ```
134
+ */
135
+ declare const combine: <T, E>(results: readonly Result<T, E>[]) => Result<T[], E>;
136
+ type CombineTuple<R extends readonly Result<unknown, unknown>[]> = Result<{
137
+ [K in keyof R]: InferOk<R[K]>;
138
+ }, {
139
+ [K in keyof R]: InferErr<R[K]>;
140
+ }[number]>;
141
+ /**
142
+ * Heterogeneous tuple combine — like {@link combine} but preserves each
143
+ * branch's `Ok` type by position, so the result destructures type-safely.
144
+ * Short-circuits on the first `Err` in input order (neverthrow-style).
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * const r = combineTuple([ok(1), ok("x")] as const);
149
+ * // Result<readonly [number, string], never>
150
+ * if (isOk(r)) {
151
+ * const [n, s] = r.value; // typed per position
152
+ * }
153
+ * ```
154
+ */
155
+ declare const combineTuple: <const R extends readonly Result<unknown, unknown>[]>(results: R) => CombineTuple<R>;
156
+ /**
157
+ * Accumulate independent validation failures. Returns `Ok<T[]>` only when
158
+ * every input is `Ok`. Without a combiner, failures are collected into a
159
+ * readonly array; with `combineErrors` they are folded into a single `E`.
160
+ *
161
+ * Unlike {@link combine}, this does **not** short-circuit on first failure —
162
+ * use for independent checks where you want to report all problems at once.
163
+ *
164
+ * @example
165
+ * ```ts
166
+ * const checks: Result<string, string[]>[] = [ok("Ada"), err(["age required"])];
167
+ *
168
+ * validateAll(checks);
169
+ * // Result<string[], readonly string[][]>
170
+ *
171
+ * validateAll(checks, (left, right) => [...left, ...right]);
172
+ * // Result<string[], string[]>
173
+ * ```
174
+ */
175
+ declare function validateAll<T, E>(results: readonly Result<T, E>[]): Result<T[], readonly E[]>;
176
+ declare function validateAll<T, E>(results: readonly Result<T, E>[], combineErrors: (left: E, right: E) => E): Result<T[], E>;
177
+ /**
178
+ * Tuple-preserving variant of {@link validateAll}. Heterogeneous input tuple
179
+ * → preserved `Ok` tuple shape. Without a combiner, the error union is
180
+ * collected into a readonly array; with `combineErrors`, all inputs must
181
+ * share the error type `E` and failures fold into a single `E`.
182
+ *
183
+ * @example
184
+ * ```ts
185
+ * const name: Result<string, string[]> = ok("Ada");
186
+ * const age: Result<number, string[]> = ok(36);
187
+ *
188
+ * validateTuple([name, age] as const);
189
+ * // Result<readonly [string, number], readonly string[][]>
190
+ *
191
+ * validateTuple([name, age] as const, (l, r) => [...l, ...r]);
192
+ * // Result<readonly [string, number], string[]>
193
+ * ```
194
+ */
195
+ declare function validateTuple<const R extends readonly Result<unknown, unknown>[]>(results: R): Result<{
196
+ [K in keyof R]: InferOk<R[K]>;
197
+ }, readonly InferErr<R[number]>[]>;
198
+ declare function validateTuple<const R extends readonly Result<unknown, unknown>[], E = InferErr<R[number]>>(results: R & readonly Result<unknown, E>[], combineErrors: (left: E, right: E) => E): Result<{
199
+ [K in keyof R]: InferOk<R[K]>;
200
+ }, E>;
201
+
8
202
  /**
9
203
  * Lifts a value into the success track.
10
204
  *
@@ -47,11 +241,6 @@ declare const isOk: <T, E>(result: Result<T, E>) => result is Ok<T, E>;
47
241
  * ```
48
242
  */
49
243
  declare const isErr: <T, E>(result: Result<T, E>) => result is Err<T, E>;
50
- /**
51
- * Fantasy Land `of` — alias of {@link ok}.
52
- * @deprecated Use {@link ok} instead.
53
- */
54
- declare const of: <T, E = never>(value: T) => Result<T, E>;
55
244
  /**
56
245
  * Transform the `Ok` value, passing `Err` through unchanged. Dual-form:
57
246
  * call data-first or curried (for use with {@link pipe}).
@@ -62,8 +251,10 @@ declare const of: <T, E = never>(value: T) => Result<T, E>;
62
251
  * pipe(ok("x"), map((s) => s.length));// Ok 1 — curried
63
252
  * ```
64
253
  */
65
- declare function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;
66
- declare function map<T, U>(fn: (value: T) => U): <E>(result: Result<T, E>) => Result<U, E>;
254
+ declare const map: {
255
+ <T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;
256
+ <T, U>(fn: (value: T) => U): <E>(result: Result<T, E>) => Result<U, E>;
257
+ };
67
258
  /**
68
259
  * Transform the `Err` value, passing `Ok` through unchanged. Useful for
69
260
  * unifying heterogeneous failure types into one app-level union.
@@ -77,8 +268,10 @@ declare function map<T, U>(fn: (value: T) => U): <E>(result: Result<T, E>) => Re
77
268
  * );
78
269
  * ```
79
270
  */
80
- declare function mapErr<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;
81
- declare function mapErr<E, F>(fn: (error: E) => F): <T>(result: Result<T, E>) => Result<T, F>;
271
+ declare const mapErr: {
272
+ <T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;
273
+ <E, F>(fn: (error: E) => F): <T>(result: Result<T, E>) => Result<T, F>;
274
+ };
82
275
  /**
83
276
  * Transform both tracks at once — `Ok` via `onOk`, `Err` via `onErr`.
84
277
  * Equivalent to `mapErr(onErr)(map(onOk)(result))` but in one pass.
@@ -88,8 +281,10 @@ declare function mapErr<E, F>(fn: (error: E) => F): <T>(result: Result<T, E>) =>
88
281
  * bimap(parsed, (cfg) => cfg.name, (e) => ({ kind: "input", cause: e }));
89
282
  * ```
90
283
  */
91
- declare function bimap<T, U, E, F>(result: Result<T, E>, onOk: (value: T) => U, onErr: (error: E) => F): Result<U, F>;
92
- declare function bimap<T, U, E, F>(onOk: (value: T) => U, onErr: (error: E) => F): (result: Result<T, E>) => Result<U, F>;
284
+ declare const bimap: {
285
+ <T, U, E, F>(result: Result<T, E>, onOk: (value: T) => U, onErr: (error: E) => F): Result<U, F>;
286
+ <T, U, E, F>(onOk: (value: T) => U, onErr: (error: E) => F): (result: Result<T, E>) => Result<U, F>;
287
+ };
93
288
  /**
94
289
  * Canonical bind (Fantasy Land `chain`). Chains a Result-returning step,
95
290
  * widening the error union to `E | F`. Short-circuits on `Err`.
@@ -102,8 +297,10 @@ declare function bimap<T, U, E, F>(onOk: (value: T) => U, onErr: (error: E) => F
102
297
  * // Result<Data, ParseError | { kind: "missing_id" }>
103
298
  * ```
104
299
  */
105
- declare function flatMap<T, U, E, F>(result: Result<T, E>, fn: (value: T) => Result<U, F>): Result<U, E | F>;
106
- declare function flatMap<T, U, F>(fn: (value: T) => Result<U, F>): <E>(result: Result<T, E>) => Result<U, E | F>;
300
+ declare const flatMap: {
301
+ <T, U, E, F>(result: Result<T, E>, fn: (value: T) => Result<U, F>): Result<U, E | F>;
302
+ <T, U, F>(fn: (value: T) => Result<U, F>): <E>(result: Result<T, E>) => Result<U, E | F>;
303
+ };
107
304
  /**
108
305
  * Error-track bind — runs `fn` only when the result is `Err`, allowing
109
306
  * a failed workflow to recover to `Ok` or remap the failure. Mirror of
@@ -116,8 +313,10 @@ declare function flatMap<T, U, F>(fn: (value: T) => Result<U, F>): <E>(result: R
116
313
  * );
117
314
  * ```
118
315
  */
119
- declare function recover<T, E, F>(result: Result<T, E>, fn: (error: E) => Result<T, F>): Result<T, F>;
120
- declare function recover<T, E, F>(fn: (error: E) => Result<T, F>): (result: Result<T, E>) => Result<T, F>;
316
+ declare const recover: {
317
+ <T, E, F>(result: Result<T, E>, fn: (error: E) => Result<T, F>): Result<T, F>;
318
+ <T, E, F>(fn: (error: E) => Result<T, F>): (result: Result<T, E>) => Result<T, F>;
319
+ };
121
320
  /**
122
321
  * Observe the `Ok` value for side effects (logging, metrics) without
123
322
  * changing the carried value. Passes `Err` through untouched.
@@ -131,8 +330,10 @@ declare function recover<T, E, F>(fn: (error: E) => Result<T, F>): (result: Resu
131
330
  * );
132
331
  * ```
133
332
  */
134
- declare function tap<T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E>;
135
- declare function tap<T>(fn: (value: T) => void): <E>(result: Result<T, E>) => Result<T, E>;
333
+ declare const tap: {
334
+ <T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E>;
335
+ <T>(fn: (value: T) => void): <E>(result: Result<T, E>) => Result<T, E>;
336
+ };
136
337
  /**
137
338
  * Observe the `Err` value for side effects (logging, metrics) without
138
339
  * changing the carried error. Passes `Ok` through untouched.
@@ -145,38 +346,28 @@ declare function tap<T>(fn: (value: T) => void): <E>(result: Result<T, E>) => Re
145
346
  * );
146
347
  * ```
147
348
  */
148
- declare function tapErr<T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E>;
149
- declare function tapErr<E>(fn: (error: E) => void): <T>(result: Result<T, E>) => Result<T, E>;
349
+ declare const tapErr: {
350
+ <T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E>;
351
+ <E>(fn: (error: E) => void): <T>(result: Result<T, E>) => Result<T, E>;
352
+ };
150
353
  /**
151
354
  * Terminal collapse — fold both tracks into a single value. Dual-form:
152
355
  * 3-args data-first, 2-args curried for {@link pipe}. Returns whatever
153
356
  * the handlers return.
154
357
  *
155
- * For files that also import `match` from `ts-pattern`, the
156
- * collision-free alias {@link matchResult} is identical.
358
+ * For files that also import `match` from `ts-pattern`, use a namespace
359
+ * import (`import * as R from "@onrails/result"` → `R.match`) to dissolve
360
+ * the collision.
157
361
  *
158
362
  * @example
159
363
  * ```ts
160
364
  * const html = match(parsed, (cfg) => render(cfg), (e) => renderError(e));
161
365
  * ```
162
366
  */
163
- declare function match<T, E, U>(result: Result<T, E>, onOk: (value: T) => U, onErr: (error: E) => U): U;
164
- declare function match<T, E, U>(onOk: (value: T) => U, onErr: (error: E) => U): (result: Result<T, E>) => U;
165
- /**
166
- * Collision-free alias for files that also import `match` from ts-pattern.
167
- * @deprecated Namespace import carriers (e.g., `import * as R from "@onrails/result"`) and use canonical {@link match} instead.
168
- */
169
- declare const matchResult: typeof match;
170
- /**
171
- * Curried collapse with named slots — escape valve when positional `match`
172
- * order is unclear at the call site (e.g. when both handlers return the same
173
- * type and a transposed `match(r, onErr, onOk)` would silently compile).
174
- * @deprecated Use curried {@link match}(onOk, onErr)(result) instead.
175
- */
176
- declare const fold: <T, E, U>(handlers: {
177
- readonly ok: (value: T) => U;
178
- readonly err: (error: E) => U;
179
- }) => (result: Result<T, E>) => U;
367
+ declare const match: {
368
+ <T, E, U>(result: Result<T, E>, onOk: (value: T) => U, onErr: (error: E) => U): U;
369
+ <T, E, U>(onOk: (value: T) => U, onErr: (error: E) => U): (result: Result<T, E>) => U;
370
+ };
180
371
  /**
181
372
  * Returns the `Ok` value, or `defaultValue` when the result is `Err`.
182
373
  *
@@ -185,48 +376,82 @@ declare const fold: <T, E, U>(handlers: {
185
376
  * unwrapOr(parsedSetting, "default-value");
186
377
  * ```
187
378
  */
188
- declare const unwrapOr: <T, E>(result: Result<T, E>, defaultValue: T) => T;
379
+ declare const unwrapOr: {
380
+ <T, E>(result: Result<T, E>, defaultValue: T): T;
381
+ <T>(defaultValue: T): <E>(result: Result<T, E>) => T;
382
+ };
189
383
  /**
190
- * Test/assert helper — throws the original Err value when called on Err.
384
+ * Test/assert helper — returns the `Ok` value, or **throws the original `Err`
385
+ * value** when called on an `Err`. This is the assertion tier (RFC 0001 §4):
386
+ * intended for `*.spec.ts` / `*.test.ts`, where throwing fails the test loudly.
387
+ * In business logic prefer {@link match} or {@link unwrapOr}; the lint plugins
388
+ * flag `unwrapOk` outside test files.
191
389
  *
192
- * @throws when the result is Err — assertion-tier; use {@link match} / {@link unwrapOr} in business logic.
193
- * Allowed in `*.spec.ts` / `*.test.ts`; flagged elsewhere by the plugins.
390
+ * @returns the unwrapped `Ok` value
391
+ * @throws the carried `Err` value when the result is `Err`
392
+ *
393
+ * @example
394
+ * ```ts
395
+ * // in a *.spec.ts
396
+ * expect(unwrapOk(ok(5))).toBe(5);
397
+ * expect(() => unwrapOk(err(error))).toThrow(error);
398
+ * ```
194
399
  */
195
400
  declare function unwrapOk<T, E>(result: Result<T, E>): T;
401
+ /** Alias of {@link unwrapOk} for syntax cohesion with `@onrails/maybe`. */
402
+ declare const unwrap: typeof unwrapOk;
196
403
  /**
197
- * Test/assert helper — throws TypeError when called on Ok.
404
+ * Test/assert helper — returns the `Err` value, or **throws a `TypeError`**
405
+ * when called on an `Ok`. Mirror of {@link unwrapOk} on the error track and
406
+ * part of the same assertion tier (RFC 0001 §4): intended for `*.spec.ts` /
407
+ * `*.test.ts`. Prefer {@link match} / {@link unwrapOr} in business logic; the
408
+ * lint plugins flag `unwrapErr` outside test files.
198
409
  *
199
- * @throws when the result is Ok — assertion-tier; allowed in `*.spec.ts` / `*.test.ts`; flagged elsewhere by the plugins.
410
+ * @returns the unwrapped `Err` value
411
+ * @throws `TypeError` when the result is `Ok`
412
+ *
413
+ * @example
414
+ * ```ts
415
+ * // in a *.spec.ts
416
+ * expect(unwrapErr(err("x"))).toBe("x");
417
+ * expect(() => unwrapErr(ok(5))).toThrow(TypeError);
418
+ * ```
200
419
  */
201
420
  declare function unwrapErr<T, E>(result: Result<T, E>): E;
202
- /** Wrap a throwing sync function — neverthrow `Result.fromThrowable` */
421
+ /**
422
+ * Wraps a throwing sync function, returning a function that produces a
423
+ * {@link Result} instead of throwing. Thrown errors pass through `onThrow` to
424
+ * become a typed `Err`; a normal return becomes `Ok`. The neverthrow analogue
425
+ * is `Result.fromThrowable`.
426
+ *
427
+ * @param fn - the throwing function to wrap
428
+ * @param onThrow - maps a thrown value to the `Err` channel
429
+ * @returns a function with `fn`'s parameters that returns `Result<ReturnType, E>`
430
+ *
431
+ * @example
432
+ * ```ts
433
+ * type ParseError = { kind: "parse"; message: string };
434
+ * const parse = trySync(
435
+ * JSON.parse,
436
+ * (e): ParseError => ({ kind: "parse", message: String(e) }),
437
+ * );
438
+ * parse("{}"); // Ok({})
439
+ * parse("nope"); // Err({ kind: "parse", … })
440
+ * ```
441
+ */
203
442
  declare function trySync<A extends readonly unknown[], T, E>(fn: (...args: A) => T, onThrow: (error: unknown) => E): (...args: A) => Result<T, E>;
204
443
  declare function trySync<F extends (...args: never) => unknown, E>(fn: F, onThrow: (error: unknown) => E): (...args: Parameters<F>) => Result<ReturnType<F>, E>;
205
- /** First failure wins; otherwise collects values in order */
206
- declare const combine: <T, E>(results: readonly Result<T, E>[]) => Result<T[], E>;
207
- /** Tuple-preserving combine (neverthrow-style) */
208
- declare const combineTuple: <const R extends readonly Result<unknown, unknown>[]>(results: R) => CombineTuple<R>;
209
- type _OkValue<R> = R extends {
210
- _tag: "Ok";
211
- readonly value: infer T;
212
- } ? T : never;
213
- type _ErrValue<R> = R extends {
214
- _tag: "Err";
215
- readonly error: infer E;
216
- } ? E : never;
217
- type CombineTuple<R extends readonly Result<unknown, unknown>[]> = Result<{
218
- [K in keyof R]: _OkValue<R[K]>;
219
- }, {
220
- [K in keyof R]: _ErrValue<R[K]>;
221
- }[number]>;
222
444
  /**
223
- * Variadic value-first pipe — threads `value` through up to nine unary fns.
445
+ * Variadic value-first pipe — threads `value` through up to nine unary fns,
446
+ * left-to-right. Use {@link pipe} when you already have a starting value;
447
+ * use {@link flow} to define a reusable composed function with no value yet.
224
448
  *
449
+ * @example
225
450
  * ```ts
226
451
  * pipe(
227
452
  * parseConfig(raw),
228
453
  * map((cfg) => cfg.name),
229
- * flatMap((name) => name ? ok(name) : err({ kind: "empty" })),
454
+ * flatMap((name) => (name ? ok(name) : err({ kind: "empty" as const }))),
230
455
  * tap(log),
231
456
  * );
232
457
  * ```
@@ -241,4 +466,4 @@ declare function pipe<A, B, C, D, E, F, G>(value: A, ab: (a: A) => B, bc: (b: B)
241
466
  declare function pipe<A, B, C, D, E, F, G, H>(value: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H): H;
242
467
  declare function pipe<A, B, C, D, E, F, G, H, I>(value: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I): I;
243
468
 
244
- export { Err, Ok, Result, bimap, combine, combineTuple, err, flatMap, fold, isErr, isOk, map, mapErr, match, matchResult, of, ok, pipe, recover, tap, tapErr, trySync, unwrapErr, unwrapOk, unwrapOr };
469
+ export { Err, InferErr, InferOk, Ok, Result, ResultAsync, UnexpectedError, asyncAfter, bimap, combine, combineTuple, err, errAsync, flatMap, fromAsync, fromPromise, fromResult, fromSafePromise, isErr, isOk, map, mapErr, match, ok, okAsync, pipe, recover, tap, tapErr, tryAsync, trySync, unwrap, unwrapErr, unwrapOk, unwrapOr, validateAll, validateTuple };