@onrails/result 0.1.2 → 0.1.4

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 (56) hide show
  1. package/DESIGN.md +0 -1
  2. package/README.md +10 -17
  3. package/RECIPES.md +157 -34
  4. package/dist/$.cjs +40 -0
  5. package/dist/$.cjs.map +1 -0
  6. package/dist/$.js +36 -0
  7. package/dist/$.js.map +1 -0
  8. package/dist/_.d.cts +2 -0
  9. package/dist/_.d.ts +2 -0
  10. package/dist/{async-CCA1yK8q.d.cts → async-CH8Cs8KE.d.cts} +14 -0
  11. package/dist/{async-DH_-dNIo.d.ts → async-DKISqIBc.d.ts} +14 -0
  12. package/dist/compat/neverthrow.cjs +30 -12
  13. package/dist/compat/neverthrow.cjs.map +1 -1
  14. package/dist/compat/neverthrow.d.cts +1 -1
  15. package/dist/compat/neverthrow.d.ts +1 -1
  16. package/dist/compat/neverthrow.js +30 -12
  17. package/dist/compat/neverthrow.js.map +1 -1
  18. package/dist/extra.cjs +17 -10
  19. package/dist/extra.cjs.map +1 -1
  20. package/dist/extra.d.cts +10 -2
  21. package/dist/extra.d.ts +10 -2
  22. package/dist/extra.js +17 -10
  23. package/dist/extra.js.map +1 -1
  24. package/dist/fluent.cjs.map +1 -1
  25. package/dist/fluent.d.cts +3 -1
  26. package/dist/fluent.d.ts +3 -1
  27. package/dist/fluent.js.map +1 -1
  28. package/dist/index.cjs +37 -13
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +21 -5
  31. package/dist/index.d.ts +21 -5
  32. package/dist/index.js +37 -13
  33. package/dist/index.js.map +1 -1
  34. package/dist/interop.cjs +37 -13
  35. package/dist/interop.cjs.map +1 -1
  36. package/dist/interop.d.cts +13 -3
  37. package/dist/interop.d.ts +13 -3
  38. package/dist/interop.js +37 -13
  39. package/dist/interop.js.map +1 -1
  40. package/dist/railway.cjs +32 -12
  41. package/dist/railway.cjs.map +1 -1
  42. package/dist/railway.d.cts +19 -2
  43. package/dist/railway.d.ts +19 -2
  44. package/dist/railway.js +32 -13
  45. package/dist/railway.js.map +1 -1
  46. package/dist/try-gen.cjs.map +1 -1
  47. package/dist/try-gen.js.map +1 -1
  48. package/dist/validation.cjs.map +1 -1
  49. package/dist/validation.js.map +1 -1
  50. package/package.json +6 -6
  51. package/dist/mcp.cjs +0 -273
  52. package/dist/mcp.cjs.map +0 -1
  53. package/dist/mcp.d.cts +0 -62
  54. package/dist/mcp.d.ts +0 -62
  55. package/dist/mcp.js +0 -265
  56. package/dist/mcp.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/result.ts","../src/types.ts","../src/async.ts","../src/railway-core.ts","../src/railway-steps.ts"],"names":[],"mappings":"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","file":"railway.cjs","sourcesContent":["import type { Err, Ok, Result } from \"./types.js\";\n\nexport type { Err, Ok, Result } from \"./types.js\";\n\n/**\n * Lifts a value into the success track.\n *\n * @example\n * ```ts\n * const r = ok(42); // Result<number, never>\n * const typed: Result<number, \"parse\"> = ok(1);\n * ```\n */\nexport const ok = <T, E = never>(value: T): Result<T, E> => ({\n _tag: \"Ok\",\n value,\n});\n\n/**\n * Lifts a value into the error track.\n *\n * @example\n * ```ts\n * const r = err({ kind: \"parse\", message: \"bad json\" });\n * // Result<never, { kind: \"parse\"; message: string }>\n * ```\n */\nexport const err = <T = never, E = unknown>(error: E): Result<T, E> => ({\n _tag: \"Err\",\n error,\n});\n\n/**\n * Type-narrowing predicate: returns `true` when the result is `Ok`.\n *\n * @example\n * ```ts\n * if (isOk(r)) {\n * console.log(r.value); // narrowed to Ok branch\n * }\n * ```\n */\nexport const isOk = <T, E>(result: Result<T, E>): result is Ok<T, E> => result._tag === \"Ok\";\n\n/**\n * Type-narrowing predicate: returns `true` when the result is `Err`.\n *\n * @example\n * ```ts\n * if (isErr(r)) {\n * metrics.inc(\"error\", { kind: r.error.kind });\n * }\n * ```\n */\nexport const isErr = <T, E>(result: Result<T, E>): result is Err<T, E> => result._tag === \"Err\";\n\n/** Fantasy Land `of` — alias of {@link ok}. */\nexport const of = ok;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Dual-form helpers — each export accepts either shape:\n// data-first: `map(result, fn)`\n// curried: `map(fn)(result)`\n// Arity at the call site selects the overload.\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst mapImpl = <T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E> =>\n isOk(result) ? ok(fn(result.value)) : err(result.error);\n\n/**\n * Transform the `Ok` value, passing `Err` through unchanged. Dual-form:\n * call data-first or curried (for use with {@link pipe}).\n *\n * @example\n * ```ts\n * map(ok(2), (n) => n * 3); // Ok 6 — data-first\n * pipe(ok(\"x\"), map((s) => s.length));// Ok 1 — curried\n * ```\n */\nexport function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;\nexport function map<T, U>(fn: (value: T) => U): <E>(result: Result<T, E>) => Result<U, E>;\nexport function map(\n ...args: [Result<unknown, unknown>, (value: unknown) => unknown] | [(value: unknown) => unknown]\n): unknown {\n if (args.length === 2) return mapImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => mapImpl(result, fn);\n}\n\nconst mapErrImpl = <T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F> =>\n isErr(result) ? err(fn(result.error)) : ok(result.value);\n\n/**\n * Transform the `Err` value, passing `Ok` through unchanged. Useful for\n * unifying heterogeneous failure types into one app-level union.\n *\n * @example\n * ```ts\n * type AppError = { kind: \"http\"; status: number } | { kind: \"parse\" };\n * pipe(\n * fetchSync(url), // Result<Body, { status: number }>\n * mapErr((e): AppError => ({ kind: \"http\", status: e.status })),\n * );\n * ```\n */\nexport function mapErr<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;\nexport function mapErr<E, F>(fn: (error: E) => F): <T>(result: Result<T, E>) => Result<T, F>;\nexport function mapErr(\n ...args: [Result<unknown, unknown>, (error: unknown) => unknown] | [(error: unknown) => unknown]\n): unknown {\n if (args.length === 2) return mapErrImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => mapErrImpl(result, fn);\n}\n\nconst bimapImpl = <T, U, E, F>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => F,\n): Result<U, F> => (isOk(result) ? ok(onOk(result.value)) : err(onErr(result.error)));\n\n/**\n * Transform both tracks at once — `Ok` via `onOk`, `Err` via `onErr`.\n * Equivalent to `mapErr(onErr)(map(onOk)(result))` but in one pass.\n *\n * @example\n * ```ts\n * bimap(parsed, (cfg) => cfg.name, (e) => ({ kind: \"input\", cause: e }));\n * ```\n */\nexport function bimap<T, U, E, F>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => F,\n): Result<U, F>;\nexport function bimap<T, U, E, F>(\n onOk: (value: T) => U,\n onErr: (error: E) => F,\n): (result: Result<T, E>) => Result<U, F>;\nexport function bimap(\n ...args:\n | [Result<unknown, unknown>, (value: unknown) => unknown, (error: unknown) => unknown]\n | [(value: unknown) => unknown, (error: unknown) => unknown]\n): unknown {\n if (args.length === 3) return bimapImpl(args[0], args[1], args[2]);\n const [onOk, onErr] = args;\n return (result: Result<unknown, unknown>) => bimapImpl(result, onOk, onErr);\n}\n\nconst flatMapImpl = <T, U, E, F>(\n result: Result<T, E>,\n fn: (value: T) => Result<U, F>,\n): Result<U, E | F> => (isOk(result) ? fn(result.value) : err(result.error));\n\n/**\n * Canonical bind (Fantasy Land `chain`). Chains a Result-returning step,\n * widening the error union to `E | F`. Short-circuits on `Err`.\n *\n * @example\n * ```ts\n * flatMap(parseInput(raw), (data) =>\n * data.id != null ? ok(data) : err({ kind: \"missing_id\" as const }),\n * );\n * // Result<Data, ParseError | { kind: \"missing_id\" }>\n * ```\n */\nexport function flatMap<T, U, E, F>(\n result: Result<T, E>,\n fn: (value: T) => Result<U, F>,\n): Result<U, E | F>;\nexport function flatMap<T, U, F>(\n fn: (value: T) => Result<U, F>,\n): <E>(result: Result<T, E>) => Result<U, E | F>;\nexport function flatMap(\n ...args:\n | [Result<unknown, unknown>, (value: unknown) => Result<unknown, unknown>]\n | [(value: unknown) => Result<unknown, unknown>]\n): unknown {\n if (args.length === 2) return flatMapImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => flatMapImpl(result, fn);\n}\n\nconst recoverImpl = <T, E, F>(\n result: Result<T, E>,\n fn: (error: E) => Result<T, F>,\n): Result<T, F> => (isErr(result) ? fn(result.error) : ok(result.value));\n\n/**\n * Error-track bind — runs `fn` only when the result is `Err`, allowing\n * a failed workflow to recover to `Ok` or remap the failure. Mirror of\n * {@link flatMap} on the error channel.\n *\n * @example\n * ```ts\n * recover(networkResult, (e) =>\n * e.kind === \"rate_limit\" ? ok(cachedBody) : err(e),\n * );\n * ```\n */\nexport function recover<T, E, F>(\n result: Result<T, E>,\n fn: (error: E) => Result<T, F>,\n): Result<T, F>;\nexport function recover<T, E, F>(\n fn: (error: E) => Result<T, F>,\n): (result: Result<T, E>) => Result<T, F>;\nexport function recover(\n ...args:\n | [Result<unknown, unknown>, (error: unknown) => Result<unknown, unknown>]\n | [(error: unknown) => Result<unknown, unknown>]\n): unknown {\n if (args.length === 2) return recoverImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => recoverImpl(result, fn);\n}\n\nconst tapImpl = <T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E> => {\n if (isOk(result)) fn(result.value);\n return result;\n};\n\n/**\n * Observe the `Ok` value for side effects (logging, metrics) without\n * changing the carried value. Passes `Err` through untouched.\n *\n * @example\n * ```ts\n * pipe(\n * parseConfig(raw),\n * tap((cfg) => log.info({ msg: \"parsed\", name: cfg.name })),\n * flatMap(validate),\n * );\n * ```\n */\nexport function tap<T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E>;\nexport function tap<T>(fn: (value: T) => void): <E>(result: Result<T, E>) => Result<T, E>;\nexport function tap(\n ...args: [Result<unknown, unknown>, (value: unknown) => void] | [(value: unknown) => void]\n): unknown {\n if (args.length === 2) return tapImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => tapImpl(result, fn);\n}\n\nconst tapErrImpl = <T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E> => {\n if (isErr(result)) fn(result.error);\n return result;\n};\n\n/**\n * Observe the `Err` value for side effects (logging, metrics) without\n * changing the carried error. Passes `Ok` through untouched.\n *\n * @example\n * ```ts\n * pipe(\n * loadUser(id),\n * tapErr((e) => metrics.inc(\"user.load.fail\", { kind: e.kind })),\n * );\n * ```\n */\nexport function tapErr<T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E>;\nexport function tapErr<E>(fn: (error: E) => void): <T>(result: Result<T, E>) => Result<T, E>;\nexport function tapErr(\n ...args: [Result<unknown, unknown>, (error: unknown) => void] | [(error: unknown) => void]\n): unknown {\n if (args.length === 2) return tapErrImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => tapErrImpl(result, fn);\n}\n\nconst matchImpl = <T, E, U>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => U,\n): U => (isOk(result) ? onOk(result.value) : onErr(result.error));\n\n/**\n * Terminal collapse — fold both tracks into a single value. Dual-form:\n * 3-args data-first, 2-args curried for {@link pipe}. Returns whatever\n * the handlers return.\n *\n * For files that also import `match` from `ts-pattern`, the\n * collision-free alias {@link matchResult} is identical.\n *\n * @example\n * ```ts\n * const html = match(parsed, (cfg) => render(cfg), (e) => renderError(e));\n * ```\n */\nexport function match<T, E, U>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => U,\n): U;\nexport function match<T, E, U>(\n onOk: (value: T) => U,\n onErr: (error: E) => U,\n): (result: Result<T, E>) => U;\nexport function match(\n ...args:\n | [Result<unknown, unknown>, (value: unknown) => unknown, (error: unknown) => unknown]\n | [(value: unknown) => unknown, (error: unknown) => unknown]\n): unknown {\n if (args.length === 3) return matchImpl(args[0], args[1], args[2]);\n const [onOk, onErr] = args;\n return (result: Result<unknown, unknown>) => matchImpl(result, onOk, onErr);\n}\n\n/** Collision-free alias for files that also import `match` from ts-pattern. */\nexport const matchResult = match;\n\n/**\n * Curried collapse with named slots — escape valve when positional `match`\n * order is unclear at the call site (e.g. when both handlers return the same\n * type and a transposed `match(r, onErr, onOk)` would silently compile).\n */\nexport const fold =\n <T, E, U>(handlers: { readonly ok: (value: T) => U; readonly err: (error: E) => U }) =>\n (result: Result<T, E>): U =>\n matchImpl(result, handlers.ok, handlers.err);\n\n/**\n * Returns the `Ok` value, or `defaultValue` when the result is `Err`.\n *\n * @example\n * ```ts\n * unwrapOr(parsedSetting, \"default-value\");\n * ```\n */\nexport const unwrapOr = <T, E>(result: Result<T, E>, defaultValue: T): T =>\n isOk(result) ? result.value : defaultValue;\n\n/** Test/assert helper — throws the original Err value when called on Err. */\nexport function unwrapOk<T, E>(result: Result<T, E>): T {\n if (isErr(result)) throw result.error;\n return result.value;\n}\n\n/** Test/assert helper — throws TypeError when called on Ok. */\nexport function unwrapErr<T, E>(result: Result<T, E>): E {\n if (isOk(result)) throw new TypeError(\"unwrapErr called on Ok\");\n return result.error;\n}\n\n/** Wrap a throwing sync function — neverthrow `Result.fromThrowable` */\nexport function trySync<A extends readonly unknown[], T, E>(\n fn: (...args: A) => T,\n onThrow: (error: unknown) => E,\n): (...args: A) => Result<T, E>;\nexport function trySync<F extends (...args: never) => unknown, E>(\n fn: F,\n onThrow: (error: unknown) => E,\n): (...args: Parameters<F>) => Result<ReturnType<F>, E>;\nexport function trySync(\n fn: (...args: never) => unknown,\n onThrow: (error: unknown) => unknown,\n): (...args: never) => Result<unknown, unknown> {\n return (...args: never) => {\n try {\n return ok(fn(...args));\n } catch (error) {\n return err(onThrow(error));\n }\n };\n}\n\n/** First failure wins; otherwise collects values in order */\nexport const combine = <T, E>(results: readonly Result<T, E>[]): Result<T[], E> => {\n const values: T[] = [];\n for (const result of results) {\n if (isErr(result)) return err(result.error);\n values.push(result.value);\n }\n return ok(values);\n};\n\n/** Tuple-preserving combine (neverthrow-style) */\nexport const combineTuple = <const R extends readonly Result<unknown, unknown>[]>(\n results: R,\n): CombineTuple<R> =>\n // Runtime identical to combine; the cast restores per-index tuple types.\n combine(results as readonly Result<unknown, unknown>[]) as CombineTuple<R>;\n\ntype _OkValue<R> = R extends { _tag: \"Ok\"; readonly value: infer T } ? T : never;\ntype _ErrValue<R> = R extends { _tag: \"Err\"; readonly error: infer E } ? E : never;\n\ntype CombineTuple<R extends readonly Result<unknown, unknown>[]> = Result<\n { [K in keyof R]: _OkValue<R[K]> },\n { [K in keyof R]: _ErrValue<R[K]> }[number]\n>;\n\n/**\n * Variadic value-first pipe — threads `value` through up to nine unary fns.\n *\n * ```ts\n * pipe(\n * parseConfig(raw),\n * map((cfg) => cfg.name),\n * flatMap((name) => name ? ok(name) : err({ kind: \"empty\" })),\n * tap(log),\n * );\n * ```\n */\nexport function pipe<A>(value: A): A;\nexport function pipe<A, B>(value: A, ab: (a: A) => B): B;\nexport function pipe<A, B, C>(value: A, ab: (a: A) => B, bc: (b: B) => C): C;\nexport function pipe<A, B, C, D>(value: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D;\nexport function pipe<A, B, C, D, E>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n): E;\nexport function pipe<A, B, C, D, E, F>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n): F;\nexport function pipe<A, B, C, D, E, F, G>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n): G;\nexport function pipe<A, B, C, D, E, F, G, H>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n): H;\nexport function pipe<A, B, C, D, E, F, G, H, I>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n): I;\nexport function pipe(value: unknown, ...fns: ReadonlyArray<(x: unknown) => unknown>): unknown {\n let acc = value;\n for (const fn of fns) {\n acc = fn(acc);\n }\n return acc;\n}\n","/** Tagged success/failure — no classes, tree-shake friendly. */\nexport type Result<T, E> =\n | { readonly _tag: \"Ok\"; readonly value: T }\n | { readonly _tag: \"Err\"; readonly error: E };\n\nexport type Ok<T, E = never> = Extract<Result<T, E>, { _tag: \"Ok\" }>;\nexport type Err<T, E> = Extract<Result<T, E>, { _tag: \"Err\" }>;\n\n/** Thrown defect mapped when {@link fromAsync} has no `onDefect` */\nexport class UnexpectedError extends Error {\n constructor(\n message: string,\n override readonly cause?: unknown,\n ) {\n super(message);\n this.name = \"UnexpectedError\";\n }\n}\n","import { err, isErr, map, mapErr, ok } from \"./result.js\";\nimport type { Result } from \"./types.js\";\nimport { UnexpectedError } from \"./types.js\";\n\ntype PromiseFactory<T, E> = () => Promise<Result<T, E>>;\ntype AsyncOk<R> = R extends ResultAsync<infer T, unknown> ? T : never;\ntype AsyncErr<R> = R extends ResultAsync<unknown, infer E> ? E : never;\ntype CombineTupleAsync<R extends readonly ResultAsync<unknown, unknown>[]> = ResultAsync<\n { [K in keyof R]: AsyncOk<R[K]> },\n { [K in keyof R]: AsyncErr<R[K]> }[number]\n>;\n\nconst liftPromiseResult = async <T, E>(\n promise: Promise<Result<T, E>>,\n onDefect: (error: unknown) => E | UnexpectedError,\n): Promise<Result<T, E | UnexpectedError>> => {\n try {\n const result = await promise;\n if (isErr(result)) {\n return result;\n }\n // Auto-flatten one level: Ok<Result<…>> from double-wrapped interop.\n return isResultLike<T, E | UnexpectedError>(result.value) ? result.value : result;\n } catch (error) {\n return err(onDefect(error));\n }\n};\n\n/** Collapses settled results left-to-right, short-circuiting on the first `Err`. */\nconst sequenceSettled = (\n settled: readonly Result<unknown, unknown>[],\n): Result<unknown[], unknown> => {\n const values: unknown[] = [];\n for (const result of settled) {\n if (isErr(result)) {\n return err(result.error);\n }\n values.push(result.value);\n }\n return ok(values);\n};\n\n/**\n * Async result — public API never exposes `Promise<Result<…>>` directly;\n * await via `.resolve()` or `.match()`.\n */\nexport class ResultAsync<T, E> {\n protected constructor(protected readonly run: PromiseFactory<T, E>) {}\n\n static fromResult<T, E>(result: Result<T, E>): ResultAsync<T, E> {\n return new ResultAsync(async () => result);\n }\n\n static fromPromise<T, E>(\n promise: PromiseLike<T>,\n onReject: (error: unknown) => E,\n ): ResultAsync<T, E> {\n return new ResultAsync(async () => {\n try {\n return ok(await promise);\n } catch (error) {\n return err(onReject(error));\n }\n });\n }\n\n static fromSafePromise<T, E = never>(promise: PromiseLike<T>): ResultAsync<T, E> {\n return new ResultAsync(async () => ok(await promise));\n }\n\n /**\n * Defers work until {@link resolve}. Unlike {@link fromPromise}, nothing runs\n * until the `ResultAsync` is resolved (e.g. by `combineTuple` / `combineTupleParallel`).\n */\n static defer<T, E>(fn: () => Promise<Result<T, E>>): ResultAsync<T, E> {\n return new ResultAsync(fn);\n }\n\n static ok<T>(value: T): ResultAsync<T, never>;\n static ok<T, E>(value: T): ResultAsync<T, E>;\n static ok<T, E = never>(value: T): ResultAsync<T, E> {\n return new ResultAsync(async () => ok(value));\n }\n\n static err<T = never, E = unknown>(error: E): ResultAsync<T, E> {\n return new ResultAsync(async () => err(error));\n }\n\n /** @see {@link fromAsync} from `@onrails/result/interop` */\n static fromResultPromise<T, E>(\n promise: Promise<Result<T, E>>,\n onDefect?: (error: unknown) => E | UnexpectedError,\n ): ResultAsync<T, E | UnexpectedError> {\n const mapDefect =\n onDefect ?? ((error: unknown) => new UnexpectedError(\"Unexpected async defect\", error));\n return new ResultAsync(() => liftPromiseResult(promise, mapDefect));\n }\n\n static combine<T, E>(results: readonly ResultAsync<T, E>[]): ResultAsync<T[], E> {\n return new ResultAsync(async () => {\n const values: T[] = [];\n for (const ra of results) {\n const result = await ra.resolve();\n if (isErr(result)) {\n return err(result.error);\n }\n values.push(result.value);\n }\n return ok(values);\n });\n }\n\n static combineTuple<const R extends readonly ResultAsync<unknown, unknown>[]>(\n results: R,\n ): CombineTupleAsync<R> {\n // Runtime identical to combine; the cast restores per-index tuple types.\n return ResultAsync.combine(\n results as readonly ResultAsync<unknown, unknown>[],\n ) as CombineTupleAsync<R>;\n }\n\n /**\n * Like {@link combineTuple}, but starts every branch before awaiting (wall-clock\n * parallel for independent IO). On failure, returns the first `Err` in input order.\n */\n static combineTupleParallel<const R extends readonly ResultAsync<unknown, unknown>[]>(\n results: R,\n ): CombineTupleAsync<R> {\n // Cast restores per-index tuple types over the untyped sequence core.\n return new ResultAsync(async () =>\n sequenceSettled(await Promise.all(results.map((ra) => ra.resolve()))),\n ) as CombineTupleAsync<R>;\n }\n\n map<U>(fn: (value: T) => U): ResultAsync<U, E> {\n return new ResultAsync(async () => map(await this.run(), fn));\n }\n\n mapErr<F>(fn: (error: E) => F): ResultAsync<T, F> {\n return new ResultAsync(async () => mapErr(await this.run(), fn));\n }\n\n flatMap<U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F> | { inner: Result<U, F> },\n ): ResultAsync<U, E | F> {\n return new ResultAsync<U, E | F>(async () => {\n const first = await this.run();\n if (isErr(first)) {\n return first;\n }\n const next = fn(first.value);\n if (next instanceof ResultAsync) {\n return next.resolve();\n }\n if (isResultLike<U, F>(next)) {\n return next;\n }\n return isCompatLike<U, F>(next) ? next.inner : next;\n });\n }\n\n andThen<U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F> | { inner: Result<U, F> },\n ): ResultAsync<U, E | F> {\n return this.flatMap(fn);\n }\n\n chain<U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F> | { inner: Result<U, F> },\n ): ResultAsync<U, E | F> {\n return this.flatMap(fn);\n }\n\n recover<F>(fn: (error: E) => ResultAsync<T, F> | Result<T, F>): ResultAsync<T, F> {\n return new ResultAsync<T, F>(async () => {\n const first = await this.run();\n if (!isErr(first)) {\n return first;\n }\n const next = fn(first.error);\n return next instanceof ResultAsync ? next.resolve() : next;\n });\n }\n\n orElse<F>(fn: (error: E) => ResultAsync<T, F> | Result<T, F>): ResultAsync<T, F> {\n return this.recover(fn);\n }\n\n tap(fn: (value: T) => void): ResultAsync<T, E> {\n return new ResultAsync(async () => {\n const result = await this.run();\n if (!isErr(result)) {\n fn(result.value);\n }\n return result;\n });\n }\n\n tapErr(fn: (error: E) => void): ResultAsync<T, E> {\n return new ResultAsync(async () => {\n const result = await this.run();\n if (isErr(result)) {\n fn(result.error);\n }\n return result;\n });\n }\n\n unwrapOr<U>(defaultValue: U): Promise<T | U> {\n return this.run().then((result) => (isErr(result) ? defaultValue : result.value));\n }\n\n isOk(): Promise<boolean> {\n return this.run().then((result) => !isErr(result));\n }\n\n isErr(): Promise<boolean> {\n return this.run().then((result) => isErr(result));\n }\n\n match<U1, U2 = U1>(onOk: (value: T) => U1, onErr: (error: E) => U2): Promise<U1 | U2> {\n return this.run().then((result) => (isErr(result) ? onErr(result.error) : onOk(result.value)));\n }\n\n resolve(): Promise<Result<T, E>> {\n return this.run();\n }\n\n /**\n * Thenable shim — `await ra` resolves to a bare tagged-union `Result<T, E>`.\n * Narrow with `isOk(r)` / `isErr(r)` to read `.value` / `.error`.\n */\n // biome-ignore lint/suspicious/noThenProperty: makes ResultAsync awaitable\n then<R1 = Result<T, E>, R2 = never>(\n onfulfilled?: ((value: Result<T, E>) => R1 | PromiseLike<R1>) | undefined | null,\n onrejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | undefined | null,\n ): Promise<R1 | R2> {\n return this.run().then(\n // Safe: without onfulfilled, R1 stays at its Result<T, E> default.\n (r) => (onfulfilled ? onfulfilled(r) : (r as unknown as R1)),\n onrejected ?? undefined,\n );\n }\n}\n\nfunction isResultLike<U, F>(v: unknown): v is Result<U, F> {\n return (\n typeof v === \"object\" &&\n v !== null &&\n \"_tag\" in v &&\n ((v as { _tag: unknown })._tag === \"Ok\" || (v as { _tag: unknown })._tag === \"Err\")\n );\n}\n\nfunction isCompatLike<U, F>(v: unknown): v is { inner: Result<U, F> } {\n return (\n typeof v === \"object\" &&\n v !== null &&\n \"inner\" in v &&\n isResultLike((v as { inner: unknown }).inner)\n );\n}\n\n/**\n * Lifts a value into an `Ok` async result.\n *\n * @example\n * ```ts\n * const r = okAsync(42); // ResultAsync<number, never>\n * ```\n */\nexport const okAsync = ResultAsync.ok;\n\n/**\n * Lifts a value into an `Err` async result.\n *\n * @example\n * ```ts\n * const r = errAsync({ kind: \"not_found\" as const });\n * ```\n */\nexport const errAsync = ResultAsync.err;\n\n/**\n * Wraps a `PromiseLike<T>` into a {@link ResultAsync}. Reject reasons go\n * through `onReject` to become typed `Err`s; success becomes `Ok<T>`.\n *\n * @example\n * ```ts\n * const body = fromPromise(\n * fetch(url).then((r) => r.text()),\n * (e): NetworkError => ({ kind: \"network\", cause: String(e) }),\n * );\n * ```\n */\nexport const fromPromise = ResultAsync.fromPromise;\n\n/**\n * Wraps a `PromiseLike<T>` that **never rejects** into {@link ResultAsync}.\n * Skips the `onReject` mapper. Use only when the promise is provably safe.\n */\nexport const fromSafePromise = ResultAsync.fromSafePromise;\n\n/**\n * Heterogeneous async tuple combine — left-to-right, short-circuit on\n * first `Err` in input order. Preserves tuple positions so destructuring\n * stays type-safe.\n *\n * @example\n * ```ts\n * const combined = sequenceTupleAsync([loadCfg(), loadCatalog()] as const);\n * // ResultAsync<readonly [Cfg, Catalog], CfgError | CatalogError>\n * ```\n */\nexport const sequenceTupleAsync = ResultAsync.combineTuple;\n\n/**\n * Heterogeneous async tuple combine — branches overlap in wall-clock time.\n * Returns the first `Err` in **input** order (not completion order).\n *\n * @example\n * ```ts\n * const combined = parallelTupleAsync([\n * loadProfile(id),\n * loadMetrics(id),\n * loadFlags(id),\n * ] as const);\n * // ResultAsync<readonly [Profile, Metrics, Flags], …>\n * ```\n */\nexport const parallelTupleAsync = ResultAsync.combineTupleParallel;\n\nconst toError = (error: unknown): Error =>\n error instanceof Error ? error : new Error(String(error));\n\n/**\n * Convenience wrapper over {@link fromPromise} with default `Error`\n * normalization. Call without `onReject` to get `ResultAsync<T, Error>`,\n * or pass a custom mapper for a typed error.\n *\n * @example\n * ```ts\n * // Default: rejection → Err(Error)\n * const a = tryAsync(db.users.insert(row));\n *\n * // Custom: typed error\n * const b = tryAsync(db.users.insert(row), (e): DbError => ({\n * kind: \"db\",\n * cause: e,\n * }));\n * ```\n */\nexport function tryAsync<T>(promise: PromiseLike<T>): ResultAsync<T, Error>;\nexport function tryAsync<T, E>(\n promise: PromiseLike<T>,\n onReject: (error: unknown) => E,\n): ResultAsync<T, E>;\nexport function tryAsync<T, E>(\n promise: PromiseLike<T>,\n onReject?: (error: unknown) => E,\n): ResultAsync<T, E | Error> {\n if (onReject) {\n return ResultAsync.fromPromise(promise, onReject);\n }\n return ResultAsync.fromPromise(promise, toError);\n}\n","import { ResultAsync } from \"./async.js\";\nimport { err, isErr, ok, trySync } from \"./result.js\";\nimport type { Result } from \"./types.js\";\n\n/**\n * Tracks whether a {@link Railway} workflow has crossed an async boundary.\n * Sync workflows return {@link Result}; async workflows return {@link ResultAsync}.\n */\nexport type RailwayMode = \"sync\" | \"async\";\n\n/**\n * Mode-aware output type for a {@link Railway} workflow: sync mode →\n * `Result<T, E>`, async mode → `ResultAsync<T, E>`.\n */\nexport type RailwayOutput<T, E, M extends RailwayMode> = M extends \"async\"\n ? ResultAsync<T, E>\n : Result<T, E>;\n\n/**\n * Initial context shape for a `railway` functional pipeline.\n * Wraps the raw input under the `input` key so subsequent named steps\n * can reference it via `ctx.input`.\n */\nexport type RailwayInput<I> = { readonly input: I };\n\ntype RailwayState<C extends object, E> =\n | { readonly mode: \"sync\"; readonly result: Result<C, E> }\n | { readonly mode: \"async\"; readonly result: ResultAsync<C, E> };\n\nexport type BranchFn<C extends object> = (ctx: C) => ResultAsync<unknown, unknown>;\nexport type BranchRecord = Record<string, (ctx: never) => ResultAsync<unknown, unknown>>;\ntype BranchOk<R> = R extends (ctx: never) => ResultAsync<infer T, infer _E> ? T : never;\ntype BranchErr<R> = R extends (ctx: never) => ResultAsync<infer _T, infer E> ? E : never;\ntype BranchInput<R> = R extends (ctx: infer C) => ResultAsync<unknown, unknown> ? C : never;\nexport type ParallelInput<R extends BranchRecord> = BranchInput<R[keyof R]> & object;\nexport type ParallelOutput<R extends BranchRecord> = {\n [K in keyof R]: BranchOk<R[K]>;\n};\nexport type ParallelError<R extends BranchRecord> = BranchErr<R[keyof R]>;\n\nconst addField = <C extends object, K extends string, T>(\n ctx: C,\n key: K,\n value: T,\n): C & Record<K, T> => ({ ...ctx, [key]: value }) as C & Record<K, T>;\n\nconst liftResult = <C extends object, E>(result: Result<C, E>): ResultAsync<C, E> =>\n ResultAsync.fromResult(result);\n\n/**\n * Named-context workflow builder. Each step appends a typed field to the\n * accumulating context object; the workflow tracks sync/async mode so the\n * final output type ({@link RailwayOutput}) is correct.\n *\n * Use `Railway` when a service workflow has 4+ named steps, mixed sync and\n * async boundaries, or independent async branches that should run in\n * parallel. For 1–2 step flows, prefer `flatMap` / `asyncAfter` directly.\n *\n * @example\n * ```ts\n * const summary = Railway\n * .fromSync(\"id\", () => IdSchema.parse(raw), toError)\n * .fromPromise(\"row\", ({ id }) => db.profiles.findFirst({ where: eq(profiles.id, id) }), toError)\n * .require(\"profile\", \"row\", ({ id }) => ({ kind: \"not_found\" as const, id }))\n * .derive(\"normalized\", ({ profile }) => normalizeProfile(profile))\n * .parallel({\n * artifacts: ({ normalized }) => loadArtifacts(normalized.id),\n * metrics: ({ normalized }) => loadMetrics(normalized.id),\n * })\n * .select(({ normalized, artifacts, metrics }) =>\n * toProfileSummary({ profile: normalized, artifacts, metrics }),\n * );\n * // ResultAsync<ProfileSummary, ParseError | DbError | NotFound>\n * ```\n */\nexport class Railway<C extends object, E, M extends RailwayMode> {\n private constructor(private readonly state: RailwayState<C, E>) {}\n\n /** Start an empty sync workflow with no fields in context. */\n static empty(): Railway<Record<never, never>, never, \"sync\"> {\n return new Railway({ mode: \"sync\", result: ok({}) });\n }\n\n /** Start a sync workflow with the given context as the initial state. */\n static context<C extends object>(context: C): Railway<C, never, \"sync\"> {\n return new Railway({ mode: \"sync\", result: ok(context) });\n }\n\n /**\n * Start a sync workflow with a throwing function — `onThrow` maps any\n * exception to a typed error.\n */\n static fromSync<K extends string, T, E>(\n key: K,\n fn: () => T,\n onThrow: (error: unknown) => E,\n ): Railway<Record<K, T>, E, \"sync\"> {\n return Railway.empty().fromSync(key, fn, onThrow);\n }\n\n /** Start a sync workflow with a `Result`-returning function. */\n static fromResult<K extends string, T, E>(\n key: K,\n fn: () => Result<T, E>,\n ): Railway<Record<K, T>, E, \"sync\"> {\n return Railway.empty().fromResult(key, fn);\n }\n\n /** Start an async workflow with a `PromiseLike`-returning function. */\n static fromPromise<K extends string, T, E>(\n key: K,\n fn: () => PromiseLike<T>,\n onReject: (error: unknown) => E,\n ): Railway<Record<K, T>, E, \"async\"> {\n return Railway.empty().fromPromise(key, fn, onReject);\n }\n\n /** Start an async workflow with a `ResultAsync`-returning function. */\n static fromAsync<K extends string, T, E>(\n key: K,\n fn: () => ResultAsync<T, E>,\n ): Railway<Record<K, T>, E, \"async\"> {\n return Railway.empty().fromAsync(key, fn);\n }\n\n /**\n * Pure sync derivation — `fn` must not throw. Use {@link fromSync} for\n * throwing transforms.\n */\n derive<K extends string, T>(key: K, fn: (ctx: C) => T): Railway<C & Record<K, T>, E, M> {\n return this.fromResult(key, (ctx) => ok(fn(ctx)));\n }\n\n /**\n * Throwing sync transform. Adds `{ [key]: T }` to context; converts any\n * exception to `Err<F>` via `onThrow`.\n */\n fromSync<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => T,\n onThrow: (error: unknown) => F,\n ): Railway<C & Record<K, T>, E | F, M> {\n return this.fromResult(key, (ctx) => trySync(fn, onThrow)(ctx));\n }\n\n /**\n * Sync `Result`-returning step. Adds `{ [key]: T }` to context on `Ok`;\n * short-circuits the workflow on `Err`. Error union widens to `E | F`.\n */\n fromResult<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => Result<T, F>,\n ): Railway<C & Record<K, T>, E | F, M> {\n if (this.state.mode === \"sync\") {\n const current = this.state.result;\n if (isErr(current)) {\n return new Railway({ mode: \"sync\", result: err(current.error) });\n }\n const next = fn(current.value);\n if (isErr(next)) {\n return new Railway({ mode: \"sync\", result: err(next.error) });\n }\n return new Railway({\n mode: \"sync\",\n result: ok(addField(current.value, key, next.value)),\n });\n }\n\n return new Railway({\n mode: \"async\",\n result: this.state.result.flatMap((ctx) =>\n ResultAsync.fromResult(fn(ctx)).map((value) => addField(ctx, key, value)),\n ),\n }) as Railway<C & Record<K, T>, E | F, M>;\n }\n\n /**\n * Promise-returning step — upgrades the workflow to async mode. Reject\n * reasons go through `onReject` to become typed `Err<F>`.\n */\n fromPromise<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => PromiseLike<T>,\n onReject: (error: unknown) => F,\n ): Railway<C & Record<K, T>, E | F, \"async\"> {\n return this.fromAsync(key, (ctx) => ResultAsync.fromPromise(fn(ctx), onReject));\n }\n\n /**\n * `ResultAsync`-returning step — upgrades the workflow to async mode.\n * Already-typed error: no mapper needed.\n */\n fromAsync<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => ResultAsync<T, F>,\n ): Railway<C & Record<K, T>, E | F, \"async\"> {\n const current = this.state.mode === \"sync\" ? liftResult(this.state.result) : this.state.result;\n\n return new Railway({\n mode: \"async\",\n result: current.flatMap((ctx) => fn(ctx).map((value) => addField(ctx, key, value))),\n });\n }\n\n /**\n * Narrow a nullable context field into a required non-null field. If the\n * source field is `null` / `undefined`, the workflow short-circuits with\n * `onMissing(ctx)`.\n *\n * @example\n * ```ts\n * .fromPromise(\"row\", ({ id }) => db.users.findFirst({ where: eq(users.id, id) }))\n * .require(\"user\", \"row\", ({ id }) => ({ kind: \"not_found\" as const, id }))\n * // user is now User (non-null), not User | null\n * ```\n */\n require<K extends string, S extends keyof C, F>(\n key: K,\n source: S,\n onMissing: (ctx: C) => F,\n ): Railway<C & Record<K, NonNullable<C[S]>>, E | F, M> {\n return this.fromResult(key, (ctx) => {\n const value = ctx[source];\n return value == null ? err(onMissing(ctx)) : ok(value as NonNullable<C[S]>);\n });\n }\n\n /**\n * Run independent `ResultAsync` branches concurrently and merge their\n * named outputs back into context. Upgrades the workflow to async mode.\n * On multiple failures, the first `Err` in record-iteration order wins.\n *\n * @example\n * ```ts\n * .parallel({\n * recent: ({ userId }) => loadRecent(userId),\n * metrics: ({ userId }) => loadMetrics(userId),\n * })\n * // ctx now has { ..., recent, metrics }\n * ```\n */\n parallel<R extends Record<string, BranchFn<C>>>(\n branches: R,\n ): Railway<C & ParallelOutput<R>, E | ParallelError<R>, \"async\"> {\n const current = this.state.mode === \"sync\" ? liftResult(this.state.result) : this.state.result;\n\n return new Railway({\n mode: \"async\",\n result: current.flatMap((ctx) =>\n ResultAsync.combineTupleParallel(\n Object.entries(branches).map(([, branch]) => branch(ctx)),\n ).map((values) => {\n const next = { ...ctx } as C & ParallelOutput<R>;\n Object.keys(branches).forEach((key, index) => {\n (next as Record<string, unknown>)[key] = values[index];\n });\n return next;\n }),\n ),\n }) as Railway<C & ParallelOutput<R>, E | ParallelError<R>, \"async\">;\n }\n\n /**\n * Project the final context into the workflow's output type. Hides the\n * internal context shape from callers.\n */\n select<T>(fn: (ctx: C) => T): RailwayOutput<T, E, M> {\n if (this.state.mode === \"sync\") {\n const current = this.state.result;\n return (isErr(current) ? err(current.error) : ok(fn(current.value))) as RailwayOutput<\n T,\n E,\n M\n >;\n }\n\n return this.state.result.map(fn) as RailwayOutput<T, E, M>;\n }\n\n /**\n * Return the accumulated context as-is. Use when downstream code needs\n * every named field; prefer {@link select} when you can project to a DTO.\n */\n done(): RailwayOutput<C, E, M> {\n return this.state.result as RailwayOutput<C, E, M>;\n }\n}\n","import type { ResultAsync } from \"./async.js\";\nimport type {\n BranchFn,\n BranchRecord,\n ParallelError,\n ParallelInput,\n ParallelOutput,\n RailwayInput,\n RailwayMode,\n RailwayOutput,\n} from \"./railway-core.js\";\nimport { Railway } from \"./railway-core.js\";\nimport type { Result } from \"./types.js\";\n\ntype ParserLike<I, T> = { readonly parse: (input: I) => T } | ((input: I) => T);\ntype UnaryStep<I, O> = (input: I) => O;\n\nconst parseWithParser = <I, T>(parser: ParserLike<I, T>, input: I): T =>\n typeof parser === \"function\" ? parser(input) : parser.parse(input);\n\n/**\n * Functional companion to {@link Railway} — point-free composition of\n * reusable workflow steps. Starts from `Railway.context({ input })` and\n * applies each step in order. Step factories live below: {@link parseWith},\n * {@link fromSyncNamed}, {@link fromResultNamed}, {@link fromPromiseNamed},\n * {@link fromAsyncNamed}, {@link deriveNamed}, {@link requireNamed},\n * {@link parallelNamed}, {@link select}.\n *\n * @example\n * ```ts\n * const summary = railway(\n * rawId,\n * parseWith(IdSchema, toError).as(\"id\"),\n * fromPromiseNamed(\"row\", ({ id }) => db.profiles.findFirst({ where: eq(profiles.id, id) }), toError),\n * requireNamed(\"profile\", \"row\", ({ id }) => ({ kind: \"not_found\" as const, id })),\n * deriveNamed(\"normalized\", ({ profile }) => normalizeProfile(profile)),\n * select(({ normalized }) => toProfileSummary(normalized)),\n * );\n * ```\n */\nexport function railway<I, A>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n): A;\nexport function railway<I, A, B>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n): B;\nexport function railway<I, A, B, C>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n): C;\nexport function railway<I, A, B, C, D>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n): D;\nexport function railway<I, A, B, C, D, E>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n): E;\nexport function railway<I, A, B, C, D, E, F>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n step6: UnaryStep<E, F>,\n): F;\nexport function railway<I, A, B, C, D, E, F, G>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n step6: UnaryStep<E, F>,\n step7: UnaryStep<F, G>,\n): G;\nexport function railway<I, A, B, C, D, E, F, G, H>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n step6: UnaryStep<E, F>,\n step7: UnaryStep<F, G>,\n step8: UnaryStep<G, H>,\n): H;\nexport function railway<I>(input: I, ...steps: readonly ((input: never) => unknown)[]): unknown {\n return steps.reduce<unknown>(\n (current, step) => (step as (input: unknown) => unknown)(current),\n Railway.context({ input }),\n );\n}\n\n/**\n * Step factory: parse the workflow input with a Zod-like schema (or a\n * unary parse function). Call `.as(key)` to name the output field.\n *\n * @example\n * ```ts\n * parseWith(IdSchema, toError).as(\"id\");\n * // Used as the first step in `railway(rawId, parseId, ...)`\n * ```\n */\nexport const parseWith = <I, T, E>(parser: ParserLike<I, T>, onThrow: (error: unknown) => E) => ({\n as:\n <K extends string>(key: K) =>\n <F, M extends RailwayMode>(\n workflow: Railway<RailwayInput<I>, F, M>,\n ): Railway<RailwayInput<I> & Record<K, T>, F | E, M> =>\n workflow.fromSync(key, ({ input }) => parseWithParser(parser, input), onThrow),\n});\n\n/**\n * Reusable wrapper around {@link Railway.fromSync}. Captures key + fn +\n * onThrow once; applies to any compatible workflow.\n */\nexport const fromSyncNamed =\n <K extends string, C extends object, T, E>(\n key: K,\n fn: (ctx: C) => T,\n onThrow: (error: unknown) => E,\n ) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, M> =>\n workflow.fromSync(key, fn, onThrow);\n\n/** Reusable wrapper around {@link Railway.fromResult}. */\nexport const fromResultNamed =\n <K extends string, C extends object, T, E>(key: K, fn: (ctx: C) => Result<T, E>) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, M> =>\n workflow.fromResult(key, fn);\n\n/**\n * Reusable wrapper around {@link Railway.fromPromise}. Upgrades the\n * workflow to async mode when applied.\n */\nexport const fromPromiseNamed =\n <K extends string, C extends object, T, E>(\n key: K,\n fn: (ctx: C) => PromiseLike<T>,\n onReject: (error: unknown) => E,\n ) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, \"async\"> =>\n workflow.fromPromise(key, fn, onReject);\n\n/** Reusable wrapper around {@link Railway.fromAsync}. */\nexport const fromAsyncNamed =\n <K extends string, C extends object, T, E>(key: K, fn: (ctx: C) => ResultAsync<T, E>) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, \"async\"> =>\n workflow.fromAsync(key, fn);\n\n/** Reusable wrapper around {@link Railway.derive} — pure sync derivation. */\nexport const deriveNamed =\n <K extends string, C extends object, T>(key: K, fn: (ctx: C) => T) =>\n <I extends C, E, M extends RailwayMode>(\n workflow: Railway<I, E, M>,\n ): Railway<I & Record<K, T>, E, M> =>\n workflow.derive(key, fn);\n\n/** Reusable wrapper around {@link Railway.require} — narrows a nullable field. */\nexport const requireNamed =\n <K extends string, S extends string, C extends object, E>(\n key: K,\n source: S,\n onMissing: (ctx: C & Record<S, unknown>) => E,\n ) =>\n <I extends C & Record<S, unknown>, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, NonNullable<I[S]>>, F | E, M> =>\n workflow.require(key, source, onMissing);\n\n/**\n * Reusable wrapper around {@link Railway.parallel}. Branches run\n * concurrently and merge their named outputs back into context.\n */\nexport const parallelNamed =\n <R extends BranchRecord>(branches: R) =>\n <I extends ParallelInput<R>, E, M extends RailwayMode>(\n workflow: Railway<I, E, M>,\n ): Railway<I & ParallelOutput<R>, E | ParallelError<R>, \"async\"> => {\n // TS cannot prove contravariant branch params after storing reusable steps.\n const typedBranches = branches as unknown as Record<string, BranchFn<I>>;\n return workflow.parallel(typedBranches) as unknown as Railway<\n I & ParallelOutput<R>,\n E | ParallelError<R>,\n \"async\"\n >;\n };\n\n/**\n * Reusable wrapper around {@link Railway.select} — projects the final\n * context into the workflow's output type.\n */\nexport const select =\n <C extends object, T>(fn: (ctx: C) => T) =>\n <E, M extends RailwayMode>(workflow: Railway<C, E, M>): RailwayOutput<T, E, M> =>\n workflow.select(fn);\n"]}
1
+ {"version":3,"sources":["../src/result.ts","../src/types.ts","../src/async.ts","../src/railway-core.ts","../src/railway-steps.ts"],"names":[],"mappings":"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","file":"railway.cjs","sourcesContent":["import type { Err, Ok, Result } from \"./types.js\";\n\nexport type { Err, Ok, Result } from \"./types.js\";\n\n/**\n * Lifts a value into the success track.\n *\n * @example\n * ```ts\n * const r = ok(42); // Result<number, never>\n * const typed: Result<number, \"parse\"> = ok(1);\n * ```\n */\nexport const ok = <T, E = never>(value: T): Result<T, E> => ({\n _tag: \"Ok\",\n value,\n});\n\n/**\n * Lifts a value into the error track.\n *\n * @example\n * ```ts\n * const r = err({ kind: \"parse\", message: \"bad json\" });\n * // Result<never, { kind: \"parse\"; message: string }>\n * ```\n */\nexport const err = <T = never, E = unknown>(error: E): Result<T, E> => ({\n _tag: \"Err\",\n error,\n});\n\n/**\n * Type-narrowing predicate: returns `true` when the result is `Ok`.\n *\n * @example\n * ```ts\n * if (isOk(r)) {\n * console.log(r.value); // narrowed to Ok branch\n * }\n * ```\n */\nexport const isOk = <T, E>(result: Result<T, E>): result is Ok<T, E> => result._tag === \"Ok\";\n\n/**\n * Type-narrowing predicate: returns `true` when the result is `Err`.\n *\n * @example\n * ```ts\n * if (isErr(r)) {\n * metrics.inc(\"error\", { kind: r.error.kind });\n * }\n * ```\n */\nexport const isErr = <T, E>(result: Result<T, E>): result is Err<T, E> => result._tag === \"Err\";\n\n/**\n * Fantasy Land `of` — alias of {@link ok}.\n * @deprecated Use {@link ok} instead.\n */\nexport const of = ok;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Dual-form helpers — each export accepts either shape:\n// data-first: `map(result, fn)`\n// curried: `map(fn)(result)`\n// Arity at the call site selects the overload.\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst mapImpl = <T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E> =>\n isOk(result) ? ok(fn(result.value)) : err(result.error);\n\n/**\n * Transform the `Ok` value, passing `Err` through unchanged. Dual-form:\n * call data-first or curried (for use with {@link pipe}).\n *\n * @example\n * ```ts\n * map(ok(2), (n) => n * 3); // Ok 6 — data-first\n * pipe(ok(\"x\"), map((s) => s.length));// Ok 1 — curried\n * ```\n */\nexport function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;\nexport function map<T, U>(fn: (value: T) => U): <E>(result: Result<T, E>) => Result<U, E>;\nexport function map(\n ...args: [Result<unknown, unknown>, (value: unknown) => unknown] | [(value: unknown) => unknown]\n): unknown {\n if (args.length === 2) return mapImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => mapImpl(result, fn);\n}\n\nconst mapErrImpl = <T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F> =>\n isErr(result) ? err(fn(result.error)) : ok(result.value);\n\n/**\n * Transform the `Err` value, passing `Ok` through unchanged. Useful for\n * unifying heterogeneous failure types into one app-level union.\n *\n * @example\n * ```ts\n * type AppError = { kind: \"http\"; status: number } | { kind: \"parse\" };\n * pipe(\n * fetchSync(url), // Result<Body, { status: number }>\n * mapErr((e): AppError => ({ kind: \"http\", status: e.status })),\n * );\n * ```\n */\nexport function mapErr<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;\nexport function mapErr<E, F>(fn: (error: E) => F): <T>(result: Result<T, E>) => Result<T, F>;\nexport function mapErr(\n ...args: [Result<unknown, unknown>, (error: unknown) => unknown] | [(error: unknown) => unknown]\n): unknown {\n if (args.length === 2) return mapErrImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => mapErrImpl(result, fn);\n}\n\nconst bimapImpl = <T, U, E, F>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => F,\n): Result<U, F> => (isOk(result) ? ok(onOk(result.value)) : err(onErr(result.error)));\n\n/**\n * Transform both tracks at once — `Ok` via `onOk`, `Err` via `onErr`.\n * Equivalent to `mapErr(onErr)(map(onOk)(result))` but in one pass.\n *\n * @example\n * ```ts\n * bimap(parsed, (cfg) => cfg.name, (e) => ({ kind: \"input\", cause: e }));\n * ```\n */\nexport function bimap<T, U, E, F>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => F,\n): Result<U, F>;\nexport function bimap<T, U, E, F>(\n onOk: (value: T) => U,\n onErr: (error: E) => F,\n): (result: Result<T, E>) => Result<U, F>;\nexport function bimap(\n ...args:\n | [Result<unknown, unknown>, (value: unknown) => unknown, (error: unknown) => unknown]\n | [(value: unknown) => unknown, (error: unknown) => unknown]\n): unknown {\n if (args.length === 3) return bimapImpl(args[0], args[1], args[2]);\n const [onOk, onErr] = args;\n return (result: Result<unknown, unknown>) => bimapImpl(result, onOk, onErr);\n}\n\nconst flatMapImpl = <T, U, E, F>(\n result: Result<T, E>,\n fn: (value: T) => Result<U, F>,\n): Result<U, E | F> => (isOk(result) ? fn(result.value) : err(result.error));\n\n/**\n * Canonical bind (Fantasy Land `chain`). Chains a Result-returning step,\n * widening the error union to `E | F`. Short-circuits on `Err`.\n *\n * @example\n * ```ts\n * flatMap(parseInput(raw), (data) =>\n * data.id != null ? ok(data) : err({ kind: \"missing_id\" as const }),\n * );\n * // Result<Data, ParseError | { kind: \"missing_id\" }>\n * ```\n */\nexport function flatMap<T, U, E, F>(\n result: Result<T, E>,\n fn: (value: T) => Result<U, F>,\n): Result<U, E | F>;\nexport function flatMap<T, U, F>(\n fn: (value: T) => Result<U, F>,\n): <E>(result: Result<T, E>) => Result<U, E | F>;\nexport function flatMap(\n ...args:\n | [Result<unknown, unknown>, (value: unknown) => Result<unknown, unknown>]\n | [(value: unknown) => Result<unknown, unknown>]\n): unknown {\n if (args.length === 2) return flatMapImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => flatMapImpl(result, fn);\n}\n\nconst recoverImpl = <T, E, F>(\n result: Result<T, E>,\n fn: (error: E) => Result<T, F>,\n): Result<T, F> => (isErr(result) ? fn(result.error) : ok(result.value));\n\n/**\n * Error-track bind — runs `fn` only when the result is `Err`, allowing\n * a failed workflow to recover to `Ok` or remap the failure. Mirror of\n * {@link flatMap} on the error channel.\n *\n * @example\n * ```ts\n * recover(networkResult, (e) =>\n * e.kind === \"rate_limit\" ? ok(cachedBody) : err(e),\n * );\n * ```\n */\nexport function recover<T, E, F>(\n result: Result<T, E>,\n fn: (error: E) => Result<T, F>,\n): Result<T, F>;\nexport function recover<T, E, F>(\n fn: (error: E) => Result<T, F>,\n): (result: Result<T, E>) => Result<T, F>;\nexport function recover(\n ...args:\n | [Result<unknown, unknown>, (error: unknown) => Result<unknown, unknown>]\n | [(error: unknown) => Result<unknown, unknown>]\n): unknown {\n if (args.length === 2) return recoverImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => recoverImpl(result, fn);\n}\n\nconst tapImpl = <T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E> => {\n if (isOk(result)) fn(result.value);\n return result;\n};\n\n/**\n * Observe the `Ok` value for side effects (logging, metrics) without\n * changing the carried value. Passes `Err` through untouched.\n *\n * @example\n * ```ts\n * pipe(\n * parseConfig(raw),\n * tap((cfg) => log.info({ msg: \"parsed\", name: cfg.name })),\n * flatMap(validate),\n * );\n * ```\n */\nexport function tap<T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E>;\nexport function tap<T>(fn: (value: T) => void): <E>(result: Result<T, E>) => Result<T, E>;\nexport function tap(\n ...args: [Result<unknown, unknown>, (value: unknown) => void] | [(value: unknown) => void]\n): unknown {\n if (args.length === 2) return tapImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => tapImpl(result, fn);\n}\n\nconst tapErrImpl = <T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E> => {\n if (isErr(result)) fn(result.error);\n return result;\n};\n\n/**\n * Observe the `Err` value for side effects (logging, metrics) without\n * changing the carried error. Passes `Ok` through untouched.\n *\n * @example\n * ```ts\n * pipe(\n * loadUser(id),\n * tapErr((e) => metrics.inc(\"user.load.fail\", { kind: e.kind })),\n * );\n * ```\n */\nexport function tapErr<T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E>;\nexport function tapErr<E>(fn: (error: E) => void): <T>(result: Result<T, E>) => Result<T, E>;\nexport function tapErr(\n ...args: [Result<unknown, unknown>, (error: unknown) => void] | [(error: unknown) => void]\n): unknown {\n if (args.length === 2) return tapErrImpl(args[0], args[1]);\n const fn = args[0];\n return (result: Result<unknown, unknown>) => tapErrImpl(result, fn);\n}\n\nconst matchImpl = <T, E, U>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => U,\n): U => (isOk(result) ? onOk(result.value) : onErr(result.error));\n\n/**\n * Terminal collapse — fold both tracks into a single value. Dual-form:\n * 3-args data-first, 2-args curried for {@link pipe}. Returns whatever\n * the handlers return.\n *\n * For files that also import `match` from `ts-pattern`, the\n * collision-free alias {@link matchResult} is identical.\n *\n * @example\n * ```ts\n * const html = match(parsed, (cfg) => render(cfg), (e) => renderError(e));\n * ```\n */\nexport function match<T, E, U>(\n result: Result<T, E>,\n onOk: (value: T) => U,\n onErr: (error: E) => U,\n): U;\nexport function match<T, E, U>(\n onOk: (value: T) => U,\n onErr: (error: E) => U,\n): (result: Result<T, E>) => U;\nexport function match(\n ...args:\n | [Result<unknown, unknown>, (value: unknown) => unknown, (error: unknown) => unknown]\n | [(value: unknown) => unknown, (error: unknown) => unknown]\n): unknown {\n if (args.length === 3) return matchImpl(args[0], args[1], args[2]);\n const [onOk, onErr] = args;\n return (result: Result<unknown, unknown>) => matchImpl(result, onOk, onErr);\n}\n\n/**\n * Collision-free alias for files that also import `match` from ts-pattern.\n * @deprecated Namespace import carriers (e.g., `import * as R from \"@onrails/result\"`) and use canonical {@link match} instead.\n */\nexport const matchResult = match;\n\n/**\n * Curried collapse with named slots — escape valve when positional `match`\n * order is unclear at the call site (e.g. when both handlers return the same\n * type and a transposed `match(r, onErr, onOk)` would silently compile).\n * @deprecated Use curried {@link match}(onOk, onErr)(result) instead.\n */\nexport const fold =\n <T, E, U>(handlers: { readonly ok: (value: T) => U; readonly err: (error: E) => U }) =>\n (result: Result<T, E>): U =>\n matchImpl(result, handlers.ok, handlers.err);\n\n/**\n * Returns the `Ok` value, or `defaultValue` when the result is `Err`.\n *\n * @example\n * ```ts\n * unwrapOr(parsedSetting, \"default-value\");\n * ```\n */\nexport const unwrapOr = <T, E>(result: Result<T, E>, defaultValue: T): T =>\n isOk(result) ? result.value : defaultValue;\n\n/**\n * Test/assert helper — throws the original Err value when called on Err.\n *\n * @throws when the result is Err — assertion-tier; use {@link match} / {@link unwrapOr} in business logic.\n * Allowed in `*.spec.ts` / `*.test.ts`; flagged elsewhere by the plugins.\n */\nexport function unwrapOk<T, E>(result: Result<T, E>): T {\n if (isErr(result)) throw result.error;\n return result.value;\n}\n\n/**\n * Test/assert helper — throws TypeError when called on Ok.\n *\n * @throws when the result is Ok — assertion-tier; allowed in `*.spec.ts` / `*.test.ts`; flagged elsewhere by the plugins.\n */\nexport function unwrapErr<T, E>(result: Result<T, E>): E {\n if (isOk(result)) throw new TypeError(\"unwrapErr called on Ok\");\n return result.error;\n}\n\n/** Wrap a throwing sync function — neverthrow `Result.fromThrowable` */\nexport function trySync<A extends readonly unknown[], T, E>(\n fn: (...args: A) => T,\n onThrow: (error: unknown) => E,\n): (...args: A) => Result<T, E>;\nexport function trySync<F extends (...args: never) => unknown, E>(\n fn: F,\n onThrow: (error: unknown) => E,\n): (...args: Parameters<F>) => Result<ReturnType<F>, E>;\nexport function trySync(\n fn: (...args: never) => unknown,\n onThrow: (error: unknown) => unknown,\n): (...args: never) => Result<unknown, unknown> {\n return (...args: never) => {\n try {\n return ok(fn(...args));\n } catch (error) {\n return err(onThrow(error));\n }\n };\n}\n\n/** First failure wins; otherwise collects values in order */\nexport const combine = <T, E>(results: readonly Result<T, E>[]): Result<T[], E> => {\n const values: T[] = [];\n for (const result of results) {\n if (isErr(result)) return err(result.error);\n values.push(result.value);\n }\n return ok(values);\n};\n\n/** Tuple-preserving combine (neverthrow-style) */\nexport const combineTuple = <const R extends readonly Result<unknown, unknown>[]>(\n results: R,\n): CombineTuple<R> =>\n // Runtime identical to combine; the cast restores per-index tuple types.\n combine(results as readonly Result<unknown, unknown>[]) as CombineTuple<R>;\n\ntype _OkValue<R> = R extends { _tag: \"Ok\"; readonly value: infer T } ? T : never;\ntype _ErrValue<R> = R extends { _tag: \"Err\"; readonly error: infer E } ? E : never;\n\ntype CombineTuple<R extends readonly Result<unknown, unknown>[]> = Result<\n { [K in keyof R]: _OkValue<R[K]> },\n { [K in keyof R]: _ErrValue<R[K]> }[number]\n>;\n\n/**\n * Variadic value-first pipe — threads `value` through up to nine unary fns.\n *\n * ```ts\n * pipe(\n * parseConfig(raw),\n * map((cfg) => cfg.name),\n * flatMap((name) => name ? ok(name) : err({ kind: \"empty\" })),\n * tap(log),\n * );\n * ```\n */\nexport function pipe<A>(value: A): A;\nexport function pipe<A, B>(value: A, ab: (a: A) => B): B;\nexport function pipe<A, B, C>(value: A, ab: (a: A) => B, bc: (b: B) => C): C;\nexport function pipe<A, B, C, D>(value: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D;\nexport function pipe<A, B, C, D, E>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n): E;\nexport function pipe<A, B, C, D, E, F>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n): F;\nexport function pipe<A, B, C, D, E, F, G>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n): G;\nexport function pipe<A, B, C, D, E, F, G, H>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n): H;\nexport function pipe<A, B, C, D, E, F, G, H, I>(\n value: A,\n ab: (a: A) => B,\n bc: (b: B) => C,\n cd: (c: C) => D,\n de: (d: D) => E,\n ef: (e: E) => F,\n fg: (f: F) => G,\n gh: (g: G) => H,\n hi: (h: H) => I,\n): I;\nexport function pipe(value: unknown, ...fns: ReadonlyArray<(x: unknown) => unknown>): unknown {\n let acc = value;\n for (const fn of fns) {\n acc = fn(acc);\n }\n return acc;\n}\n","/** Tagged success/failure — no classes, tree-shake friendly. */\nexport type Result<T, E> =\n | { readonly _tag: \"Ok\"; readonly value: T }\n | { readonly _tag: \"Err\"; readonly error: E };\n\nexport type Ok<T, E = never> = Extract<Result<T, E>, { _tag: \"Ok\" }>;\nexport type Err<T, E> = Extract<Result<T, E>, { _tag: \"Err\" }>;\n\n/** Thrown defect mapped when {@link fromAsync} has no `onDefect` */\nexport class UnexpectedError extends Error {\n constructor(\n message: string,\n override readonly cause?: unknown,\n ) {\n super(message);\n this.name = \"UnexpectedError\";\n }\n}\n","import { err, isErr, map, mapErr, ok } from \"./result.js\";\nimport type { Result } from \"./types.js\";\nimport { UnexpectedError } from \"./types.js\";\n\ntype PromiseFactory<T, E> = () => Promise<Result<T, E>>;\ntype AsyncOk<R> = R extends ResultAsync<infer T, unknown> ? T : never;\ntype AsyncErr<R> = R extends ResultAsync<unknown, infer E> ? E : never;\ntype CombineTupleAsync<R extends readonly ResultAsync<unknown, unknown>[]> = ResultAsync<\n { [K in keyof R]: AsyncOk<R[K]> },\n { [K in keyof R]: AsyncErr<R[K]> }[number]\n>;\n\nconst liftPromiseResult = async <T, E>(\n promise: Promise<Result<T, E>>,\n onDefect: (error: unknown) => E | UnexpectedError,\n): Promise<Result<T, E | UnexpectedError>> => {\n try {\n const result = await promise;\n if (isErr(result)) {\n return result;\n }\n // Auto-flatten one level: Ok<Result<…>> from double-wrapped interop.\n return isResultLike<T, E | UnexpectedError>(result.value) ? result.value : result;\n } catch (error) {\n return err(onDefect(error));\n }\n};\n\n/** Collapses settled results left-to-right, short-circuiting on the first `Err`. */\nconst sequenceSettled = (\n settled: readonly Result<unknown, unknown>[],\n): Result<unknown[], unknown> => {\n const values: unknown[] = [];\n for (const result of settled) {\n if (isErr(result)) {\n return err(result.error);\n }\n values.push(result.value);\n }\n return ok(values);\n};\n\n/**\n * Async result — public API never exposes `Promise<Result<…>>` directly;\n * await via `.resolve()` or `.match()`.\n */\nexport class ResultAsync<T, E> {\n private promise: Promise<Result<T, E>> | null = null;\n\n protected constructor(protected readonly run: PromiseFactory<T, E>) {}\n\n static fromResult<T, E>(result: Result<T, E>): ResultAsync<T, E> {\n return new ResultAsync(async () => result);\n }\n\n static fromPromise<T, E>(\n promise: PromiseLike<T>,\n onReject: (error: unknown) => E,\n ): ResultAsync<T, E> {\n return new ResultAsync(async () => {\n try {\n return ok(await promise);\n } catch (error) {\n return err(onReject(error));\n }\n });\n }\n\n static fromSafePromise<T, E = never>(promise: PromiseLike<T>): ResultAsync<T, E> {\n return new ResultAsync(async () => ok(await promise));\n }\n\n /**\n * Defers work until {@link resolve}. Unlike {@link fromPromise}, nothing runs\n * until the `ResultAsync` is resolved (e.g. by `combineTuple` / `combineTupleParallel`).\n */\n static defer<T, E>(fn: () => Promise<Result<T, E>>): ResultAsync<T, E> {\n return new ResultAsync(fn);\n }\n\n static ok<T>(value: T): ResultAsync<T, never>;\n static ok<T, E>(value: T): ResultAsync<T, E>;\n static ok<T, E = never>(value: T): ResultAsync<T, E> {\n return new ResultAsync(async () => ok(value));\n }\n\n static err<T = never, E = unknown>(error: E): ResultAsync<T, E> {\n return new ResultAsync(async () => err(error));\n }\n\n /** @see {@link fromAsync} from `@onrails/result/interop` */\n static fromResultPromise<T, E>(\n promise: Promise<Result<T, E>>,\n onDefect?: (error: unknown) => E | UnexpectedError,\n ): ResultAsync<T, E | UnexpectedError> {\n const mapDefect =\n onDefect ?? ((error: unknown) => new UnexpectedError(\"Unexpected async defect\", error));\n return new ResultAsync(() => liftPromiseResult(promise, mapDefect));\n }\n\n static combine<T, E>(results: readonly ResultAsync<T, E>[]): ResultAsync<T[], E> {\n return new ResultAsync(async () => {\n const values: T[] = [];\n for (const ra of results) {\n const result = await ra.resolve();\n if (isErr(result)) {\n return err(result.error);\n }\n values.push(result.value);\n }\n return ok(values);\n });\n }\n\n static combineTuple<const R extends readonly ResultAsync<unknown, unknown>[]>(\n results: R,\n ): CombineTupleAsync<R> {\n // Runtime identical to combine; the cast restores per-index tuple types.\n return ResultAsync.combine(\n results as readonly ResultAsync<unknown, unknown>[],\n ) as CombineTupleAsync<R>;\n }\n\n /**\n * Like {@link combineTuple}, but starts every branch before awaiting (wall-clock\n * parallel for independent IO). On failure, returns the first `Err` in input order.\n */\n static combineTupleParallel<const R extends readonly ResultAsync<unknown, unknown>[]>(\n results: R,\n ): CombineTupleAsync<R> {\n // Cast restores per-index tuple types over the untyped sequence core.\n return new ResultAsync(async () =>\n sequenceSettled(await Promise.all(results.map((ra) => ra.resolve()))),\n ) as CombineTupleAsync<R>;\n }\n\n map<U>(fn: (value: T) => U): ResultAsync<U, E> {\n return new ResultAsync(async () => map(await this.resolve(), fn));\n }\n\n mapErr<F>(fn: (error: E) => F): ResultAsync<T, F> {\n return new ResultAsync(async () => mapErr(await this.resolve(), fn));\n }\n\n flatMap<U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F> | { inner: Result<U, F> },\n ): ResultAsync<U, E | F> {\n return new ResultAsync<U, E | F>(async () => {\n const first = await this.resolve();\n if (isErr(first)) {\n return first;\n }\n const next = fn(first.value);\n if (next instanceof ResultAsync) {\n return next.resolve();\n }\n if (isResultLike<U, F>(next)) {\n return next;\n }\n return isCompatLike<U, F>(next) ? next.inner : next;\n });\n }\n\n andThen<U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F> | { inner: Result<U, F> },\n ): ResultAsync<U, E | F> {\n return this.flatMap(fn);\n }\n\n /**\n * Alias for {@link flatMap}.\n * @deprecated Use {@link flatMap} or keep/use compat {@link andThen} instead.\n */\n chain<U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F> | { inner: Result<U, F> },\n ): ResultAsync<U, E | F> {\n return this.flatMap(fn);\n }\n\n recover<F>(fn: (error: E) => ResultAsync<T, F> | Result<T, F>): ResultAsync<T, F> {\n return new ResultAsync<T, F>(async () => {\n const first = await this.resolve();\n if (!isErr(first)) {\n return first;\n }\n const next = fn(first.error);\n return next instanceof ResultAsync ? next.resolve() : next;\n });\n }\n\n orElse<F>(fn: (error: E) => ResultAsync<T, F> | Result<T, F>): ResultAsync<T, F> {\n return this.recover(fn);\n }\n\n tap(fn: (value: T) => void): ResultAsync<T, E> {\n return new ResultAsync(async () => {\n const result = await this.resolve();\n if (!isErr(result)) {\n fn(result.value);\n }\n return result;\n });\n }\n\n tapErr(fn: (error: E) => void): ResultAsync<T, E> {\n return new ResultAsync(async () => {\n const result = await this.resolve();\n if (isErr(result)) {\n fn(result.error);\n }\n return result;\n });\n }\n\n unwrapOr<U>(defaultValue: U): Promise<T | U> {\n return this.resolve().then((result) => (isErr(result) ? defaultValue : result.value));\n }\n\n /**\n * @deprecated Await the ResultAsync and narrow with {@link isOk} — this method\n * re-executes deferred factories and cannot narrow.\n */\n isOk(): Promise<boolean> {\n return this.resolve().then((result) => !isErr(result));\n }\n\n /**\n * @deprecated Await the ResultAsync and narrow with {@link isErr} — this method\n * re-executes deferred factories and cannot narrow.\n */\n isErr(): Promise<boolean> {\n return this.resolve().then((result) => isErr(result));\n }\n\n match<U1, U2 = U1>(onOk: (value: T) => U1, onErr: (error: E) => U2): Promise<U1 | U2> {\n return this.resolve().then((result) =>\n isErr(result) ? onErr(result.error) : onOk(result.value),\n );\n }\n\n resolve(): Promise<Result<T, E>> {\n if (!this.promise) {\n this.promise = this.run();\n }\n return this.promise;\n }\n\n /**\n * Thenable shim — `await ra` resolves to a bare tagged-union `Result<T, E>`.\n * Narrow with `isOk(r)` / `isErr(r)` to read `.value` / `.error`.\n */\n // biome-ignore lint/suspicious/noThenProperty: makes ResultAsync awaitable\n then<R1 = Result<T, E>, R2 = never>(\n onfulfilled?: ((value: Result<T, E>) => R1 | PromiseLike<R1>) | undefined | null,\n onrejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | undefined | null,\n ): Promise<R1 | R2> {\n return this.resolve().then(\n // Safe: without onfulfilled, R1 stays at its Result<T, E> default.\n (r) => (onfulfilled ? onfulfilled(r) : (r as unknown as R1)),\n onrejected ?? undefined,\n );\n }\n}\n\nfunction isResultLike<U, F>(v: unknown): v is Result<U, F> {\n return (\n typeof v === \"object\" &&\n v !== null &&\n \"_tag\" in v &&\n ((v as { _tag: unknown })._tag === \"Ok\" || (v as { _tag: unknown })._tag === \"Err\")\n );\n}\n\nfunction isCompatLike<U, F>(v: unknown): v is { inner: Result<U, F> } {\n return (\n typeof v === \"object\" &&\n v !== null &&\n \"inner\" in v &&\n isResultLike((v as { inner: unknown }).inner)\n );\n}\n\n/**\n * Lifts a value into an `Ok` async result.\n *\n * @example\n * ```ts\n * const r = okAsync(42); // ResultAsync<number, never>\n * ```\n */\nexport const okAsync = ResultAsync.ok;\n\n/**\n * Lifts a value into an `Err` async result.\n *\n * @example\n * ```ts\n * const r = errAsync({ kind: \"not_found\" as const });\n * ```\n */\nexport const errAsync = ResultAsync.err;\n\n/**\n * Wraps a `PromiseLike<T>` into a {@link ResultAsync}. Reject reasons go\n * through `onReject` to become typed `Err`s; success becomes `Ok<T>`.\n *\n * @example\n * ```ts\n * const body = fromPromise(\n * fetch(url).then((r) => r.text()),\n * (e): NetworkError => ({ kind: \"network\", cause: String(e) }),\n * );\n * ```\n */\nexport const fromPromise = ResultAsync.fromPromise;\n\n/**\n * Wraps a `PromiseLike<T>` that **never rejects** into {@link ResultAsync}.\n * Skips the `onReject` mapper. Use only when the promise is provably safe.\n */\nexport const fromSafePromise = ResultAsync.fromSafePromise;\n\n/**\n * Heterogeneous async tuple combine — left-to-right, short-circuit on\n * first `Err` in input order. Preserves tuple positions so destructuring\n * stays type-safe.\n *\n * @example\n * ```ts\n * const combined = sequenceTupleAsync([loadCfg(), loadCatalog()] as const);\n * // ResultAsync<readonly [Cfg, Catalog], CfgError | CatalogError>\n * ```\n * @deprecated Use static {@link ResultAsync.combineTuple} instead.\n */\nexport const sequenceTupleAsync = ResultAsync.combineTuple;\n\n/**\n * Heterogeneous async tuple combine — branches overlap in wall-clock time.\n * Returns the first `Err` in **input** order (not completion order).\n *\n * @example\n * ```ts\n * const combined = parallelTupleAsync([\n * loadProfile(id),\n * loadMetrics(id),\n * loadFlags(id),\n * ] as const);\n * // ResultAsync<readonly [Profile, Metrics, Flags], …>\n * ```\n */\nexport const parallelTupleAsync = ResultAsync.combineTupleParallel;\n\nconst toError = (error: unknown): Error =>\n error instanceof Error ? error : new Error(String(error));\n\n/**\n * Convenience wrapper over {@link fromPromise} with default `Error`\n * normalization. Call without `onReject` to get `ResultAsync<T, Error>`,\n * or pass a custom mapper for a typed error.\n *\n * @example\n * ```ts\n * // Default: rejection → Err(Error)\n * const a = tryAsync(db.users.insert(row));\n *\n * // Custom: typed error\n * const b = tryAsync(db.users.insert(row), (e): DbError => ({\n * kind: \"db\",\n * cause: e,\n * }));\n * ```\n */\nexport function tryAsync<T>(promise: PromiseLike<T>): ResultAsync<T, Error>;\nexport function tryAsync<T, E>(\n promise: PromiseLike<T>,\n onReject: (error: unknown) => E,\n): ResultAsync<T, E>;\nexport function tryAsync<T, E>(\n promise: PromiseLike<T>,\n onReject?: (error: unknown) => E,\n): ResultAsync<T, E | Error> {\n if (onReject) {\n return ResultAsync.fromPromise(promise, onReject);\n }\n return ResultAsync.fromPromise(promise, toError);\n}\n","import { ResultAsync } from \"./async.js\";\nimport { err, isErr, ok, trySync } from \"./result.js\";\nimport type { Result } from \"./types.js\";\n\n/**\n * Tracks whether a {@link Railway} workflow has crossed an async boundary.\n * Sync workflows return {@link Result}; async workflows return {@link ResultAsync}.\n */\nexport type RailwayMode = \"sync\" | \"async\";\n\n/**\n * Mode-aware output type for a {@link Railway} workflow: sync mode →\n * `Result<T, E>`, async mode → `ResultAsync<T, E>`.\n */\nexport type RailwayOutput<T, E, M extends RailwayMode> = M extends \"async\"\n ? ResultAsync<T, E>\n : Result<T, E>;\n\n/**\n * Initial context shape for a `railway` functional pipeline.\n * Wraps the raw input under the `input` key so subsequent named steps\n * can reference it via `ctx.input`.\n */\nexport type RailwayInput<I> = { readonly input: I };\n\ntype RailwayState<C extends object, E> =\n | { readonly mode: \"sync\"; readonly result: Result<C, E> }\n | { readonly mode: \"async\"; readonly result: ResultAsync<C, E> };\n\nexport type BranchFn<C extends object> = (ctx: C) => ResultAsync<unknown, unknown>;\nexport type BranchRecord = Record<string, (ctx: never) => ResultAsync<unknown, unknown>>;\ntype BranchOk<R> = R extends (ctx: never) => ResultAsync<infer T, infer _E> ? T : never;\ntype BranchErr<R> = R extends (ctx: never) => ResultAsync<infer _T, infer E> ? E : never;\ntype BranchInput<R> = R extends (ctx: infer C) => ResultAsync<unknown, unknown> ? C : never;\nexport type ParallelInput<R extends BranchRecord> = BranchInput<R[keyof R]> & object;\nexport type ParallelOutput<R extends BranchRecord> = {\n [K in keyof R]: BranchOk<R[K]>;\n};\nexport type ParallelError<R extends BranchRecord> = BranchErr<R[keyof R]>;\n\nconst addField = <C extends object, K extends string, T>(\n ctx: C,\n key: K,\n value: T,\n): C & Record<K, T> => ({ ...ctx, [key]: value }) as C & Record<K, T>;\n\nconst liftResult = <C extends object, E>(result: Result<C, E>): ResultAsync<C, E> =>\n ResultAsync.fromResult(result);\n\n/**\n * Named-context workflow builder. Each step appends a typed field to the\n * accumulating context object; the workflow tracks sync/async mode so the\n * final output type ({@link RailwayOutput}) is correct.\n *\n * Use `Railway` when a service workflow has 4+ named steps, mixed sync and\n * async boundaries, or independent async branches that should run in\n * parallel. For 1–2 step flows, prefer `flatMap` / `asyncAfter` directly.\n *\n * @example\n * ```ts\n * const summary = Railway\n * .fromSync(\"id\", () => IdSchema.parse(raw), toError)\n * .fromPromise(\"row\", ({ id }) => db.profiles.findFirst({ where: eq(profiles.id, id) }), toError)\n * .require(\"profile\", \"row\", ({ id }) => ({ kind: \"not_found\" as const, id }))\n * .derive(\"normalized\", ({ profile }) => normalizeProfile(profile))\n * .parallel({\n * artifacts: ({ normalized }) => loadArtifacts(normalized.id),\n * metrics: ({ normalized }) => loadMetrics(normalized.id),\n * })\n * .select(({ normalized, artifacts, metrics }) =>\n * toProfileSummary({ profile: normalized, artifacts, metrics }),\n * );\n * // ResultAsync<ProfileSummary, ParseError | DbError | NotFound>\n * ```\n */\nexport class Railway<C extends object, E, M extends RailwayMode> {\n private constructor(private readonly state: RailwayState<C, E>) {}\n\n /** Start an empty sync workflow with no fields in context. */\n static empty(): Railway<Record<never, never>, never, \"sync\"> {\n return new Railway({ mode: \"sync\", result: ok({}) });\n }\n\n /** Start a sync workflow with the given context as the initial state. */\n static context<C extends object>(context: C): Railway<C, never, \"sync\"> {\n return new Railway({ mode: \"sync\", result: ok(context) });\n }\n\n /**\n * Start a sync workflow with a throwing function — `onThrow` maps any\n * exception to a typed error.\n */\n static fromSync<K extends string, T, E>(\n key: K,\n fn: () => T,\n onThrow: (error: unknown) => E,\n ): Railway<Record<K, T>, E, \"sync\"> {\n return Railway.empty().fromSync(key, fn, onThrow);\n }\n\n /** Start a sync workflow with a `Result`-returning function. */\n static fromResult<K extends string, T, E>(\n key: K,\n fn: () => Result<T, E>,\n ): Railway<Record<K, T>, E, \"sync\"> {\n return Railway.empty().fromResult(key, fn);\n }\n\n /** Start an async workflow with a `PromiseLike`-returning function. */\n static fromPromise<K extends string, T, E>(\n key: K,\n fn: () => PromiseLike<T>,\n onReject: (error: unknown) => E,\n ): Railway<Record<K, T>, E, \"async\"> {\n return Railway.empty().fromPromise(key, fn, onReject);\n }\n\n /** Start an async workflow with a `ResultAsync`-returning function. */\n static fromAsync<K extends string, T, E>(\n key: K,\n fn: () => ResultAsync<T, E>,\n ): Railway<Record<K, T>, E, \"async\"> {\n return Railway.empty().fromAsync(key, fn);\n }\n\n /**\n * Pure sync derivation — `fn` must not throw. Use {@link fromSync} for\n * throwing transforms.\n */\n derive<K extends string, T>(key: K, fn: (ctx: C) => T): Railway<C & Record<K, T>, E, M> {\n return this.fromResult(key, (ctx) => ok(fn(ctx)));\n }\n\n /**\n * Throwing sync transform. Adds `{ [key]: T }` to context; converts any\n * exception to `Err<F>` via `onThrow`.\n */\n fromSync<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => T,\n onThrow: (error: unknown) => F,\n ): Railway<C & Record<K, T>, E | F, M> {\n return this.fromResult(key, (ctx) => trySync(fn, onThrow)(ctx));\n }\n\n /**\n * Sync `Result`-returning step. Adds `{ [key]: T }` to context on `Ok`;\n * short-circuits the workflow on `Err`. Error union widens to `E | F`.\n */\n fromResult<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => Result<T, F>,\n ): Railway<C & Record<K, T>, E | F, M> {\n if (this.state.mode === \"sync\") {\n const current = this.state.result;\n if (isErr(current)) {\n return new Railway({ mode: \"sync\", result: err(current.error) });\n }\n const next = fn(current.value);\n if (isErr(next)) {\n return new Railway({ mode: \"sync\", result: err(next.error) });\n }\n return new Railway({\n mode: \"sync\",\n result: ok(addField(current.value, key, next.value)),\n });\n }\n\n return new Railway({\n mode: \"async\",\n result: this.state.result.flatMap((ctx) =>\n ResultAsync.fromResult(fn(ctx)).map((value) => addField(ctx, key, value)),\n ),\n }) as Railway<C & Record<K, T>, E | F, M>;\n }\n\n /**\n * Promise-returning step — upgrades the workflow to async mode. Reject\n * reasons go through `onReject` to become typed `Err<F>`.\n */\n fromPromise<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => PromiseLike<T>,\n onReject: (error: unknown) => F,\n ): Railway<C & Record<K, T>, E | F, \"async\"> {\n return this.fromAsync(key, (ctx) => ResultAsync.fromPromise(fn(ctx), onReject));\n }\n\n /**\n * `ResultAsync`-returning step — upgrades the workflow to async mode.\n * Already-typed error: no mapper needed.\n */\n fromAsync<K extends string, T, F>(\n key: K,\n fn: (ctx: C) => ResultAsync<T, F>,\n ): Railway<C & Record<K, T>, E | F, \"async\"> {\n const current = this.state.mode === \"sync\" ? liftResult(this.state.result) : this.state.result;\n\n return new Railway({\n mode: \"async\",\n result: current.flatMap((ctx) => fn(ctx).map((value) => addField(ctx, key, value))),\n });\n }\n\n /**\n * Narrow a nullable context field into a required non-null field. If the\n * source field is `null` / `undefined`, the workflow short-circuits with\n * `onMissing(ctx)`.\n *\n * @example\n * ```ts\n * .fromPromise(\"row\", ({ id }) => db.users.findFirst({ where: eq(users.id, id) }))\n * .require(\"user\", \"row\", ({ id }) => ({ kind: \"not_found\" as const, id }))\n * // user is now User (non-null), not User | null\n * ```\n */\n require<K extends string, S extends keyof C, F>(\n key: K,\n source: S,\n onMissing: (ctx: C) => F,\n ): Railway<C & Record<K, NonNullable<C[S]>>, E | F, M> {\n return this.fromResult(key, (ctx) => {\n const value = ctx[source];\n return value == null ? err(onMissing(ctx)) : ok(value as NonNullable<C[S]>);\n });\n }\n\n /**\n * Run independent `ResultAsync` branches concurrently and merge their\n * named outputs back into context. Upgrades the workflow to async mode.\n * On multiple failures, the first `Err` in record-iteration order wins.\n *\n * @example\n * ```ts\n * .parallel({\n * recent: ({ userId }) => loadRecent(userId),\n * metrics: ({ userId }) => loadMetrics(userId),\n * })\n * // ctx now has { ..., recent, metrics }\n * ```\n */\n parallel<R extends Record<string, BranchFn<C>>>(\n branches: R,\n ): Railway<C & ParallelOutput<R>, E | ParallelError<R>, \"async\"> {\n const current = this.state.mode === \"sync\" ? liftResult(this.state.result) : this.state.result;\n\n return new Railway({\n mode: \"async\",\n result: current.flatMap((ctx) =>\n ResultAsync.combineTupleParallel(\n Object.entries(branches).map(([, branch]) => branch(ctx)),\n ).map((values) => {\n const next = { ...ctx } as C & ParallelOutput<R>;\n Object.keys(branches).forEach((key, index) => {\n (next as Record<string, unknown>)[key] = values[index];\n });\n return next;\n }),\n ),\n }) as Railway<C & ParallelOutput<R>, E | ParallelError<R>, \"async\">;\n }\n\n /**\n * Project the final context into the workflow's output type. Hides the\n * internal context shape from callers.\n */\n select<T>(fn: (ctx: C) => T): RailwayOutput<T, E, M> {\n if (this.state.mode === \"sync\") {\n const current = this.state.result;\n return (isErr(current) ? err(current.error) : ok(fn(current.value))) as RailwayOutput<\n T,\n E,\n M\n >;\n }\n\n return this.state.result.map(fn) as RailwayOutput<T, E, M>;\n }\n\n /**\n * Return the accumulated context as-is. Use when downstream code needs\n * every named field; prefer {@link select} when you can project to a DTO.\n */\n done(): RailwayOutput<C, E, M> {\n return this.state.result as RailwayOutput<C, E, M>;\n }\n}\n","import type { ResultAsync } from \"./async.js\";\nimport type {\n BranchFn,\n BranchRecord,\n ParallelError,\n ParallelInput,\n ParallelOutput,\n RailwayInput,\n RailwayMode,\n RailwayOutput,\n} from \"./railway-core.js\";\nimport { Railway } from \"./railway-core.js\";\nimport type { Result } from \"./types.js\";\n\ntype ParserLike<I, T> = { readonly parse: (input: I) => T } | ((input: I) => T);\ntype UnaryStep<I, O> = (input: I) => O;\n\nconst parseWithParser = <I, T>(parser: ParserLike<I, T>, input: I): T =>\n typeof parser === \"function\" ? parser(input) : parser.parse(input);\n\n/**\n * Functional companion to {@link Railway} — point-free composition of\n * reusable workflow steps. Starts from `Railway.context({ input })` and\n * applies each step in order. Step factories live below: {@link parseWith},\n * {@link fromSyncNamed}, {@link fromResultNamed}, {@link fromPromiseNamed},\n * {@link fromAsyncNamed}, {@link deriveNamed}, {@link requireNamed},\n * {@link parallelNamed}, {@link select}.\n *\n * @example\n * ```ts\n * const summary = railway(\n * rawId,\n * parseWith(IdSchema, toError).as(\"id\"),\n * fromPromiseNamed(\"row\", ({ id }) => db.profiles.findFirst({ where: eq(profiles.id, id) }), toError),\n * requireNamed(\"profile\", \"row\", ({ id }) => ({ kind: \"not_found\" as const, id })),\n * deriveNamed(\"normalized\", ({ profile }) => normalizeProfile(profile)),\n * select(({ normalized }) => toProfileSummary(normalized)),\n * );\n * ```\n */\nexport function railway<I, A>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n): A;\nexport function railway<I, A, B>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n): B;\nexport function railway<I, A, B, C>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n): C;\nexport function railway<I, A, B, C, D>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n): D;\nexport function railway<I, A, B, C, D, E>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n): E;\nexport function railway<I, A, B, C, D, E, F>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n step6: UnaryStep<E, F>,\n): F;\nexport function railway<I, A, B, C, D, E, F, G>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n step6: UnaryStep<E, F>,\n step7: UnaryStep<F, G>,\n): G;\nexport function railway<I, A, B, C, D, E, F, G, H>(\n input: I,\n step1: UnaryStep<Railway<RailwayInput<I>, never, \"sync\">, A>,\n step2: UnaryStep<A, B>,\n step3: UnaryStep<B, C>,\n step4: UnaryStep<C, D>,\n step5: UnaryStep<D, E>,\n step6: UnaryStep<E, F>,\n step7: UnaryStep<F, G>,\n step8: UnaryStep<G, H>,\n): H;\nexport function railway<I>(input: I, ...steps: readonly ((input: never) => unknown)[]): unknown {\n return steps.reduce<unknown>(\n (current, step) => (step as (input: unknown) => unknown)(current),\n Railway.context({ input }),\n );\n}\n\n/**\n * Step factory: parse the workflow input with a Zod-like schema (or a\n * unary parse function). Call `.as(key)` to name the output field.\n *\n * @example\n * ```ts\n * parseWith(IdSchema, toError).as(\"id\");\n * // Used as the first step in `railway(rawId, parseId, ...)`\n * ```\n */\nexport const parseWith = <I, T, E>(parser: ParserLike<I, T>, onThrow: (error: unknown) => E) => ({\n as:\n <K extends string>(key: K) =>\n <F, M extends RailwayMode>(\n workflow: Railway<RailwayInput<I>, F, M>,\n ): Railway<RailwayInput<I> & Record<K, T>, F | E, M> =>\n workflow.fromSync(key, ({ input }) => parseWithParser(parser, input), onThrow),\n});\n\n/**\n * Name-first companion to {@link parseWith}: parse the workflow input with a\n * Zod-like schema (or unary parse fn), naming the output field in the same\n * `(key, ...)` shape as {@link fromSyncNamed}, {@link deriveNamed}, et al.\n * Prefer this in `railway(...)` pipelines so every step's name aligns at the\n * left edge.\n *\n * @example\n * ```ts\n * railway(\n * rawId,\n * parseNamed(\"id\", IdSchema, toError),\n * fromPromiseNamed(\"profile\", ({ id }) => fetchProfile(id), toError),\n * );\n * ```\n */\nexport const parseNamed =\n <K extends string, I, T, E>(key: K, parser: ParserLike<I, T>, onThrow: (error: unknown) => E) =>\n <F, M extends RailwayMode>(\n workflow: Railway<RailwayInput<I>, F, M>,\n ): Railway<RailwayInput<I> & Record<K, T>, F | E, M> =>\n workflow.fromSync(key, ({ input }) => parseWithParser(parser, input), onThrow);\n\n/**\n * Reusable wrapper around {@link Railway.fromSync}. Captures key + fn +\n * onThrow once; applies to any compatible workflow.\n */\nexport const fromSyncNamed =\n <K extends string, C extends object, T, E>(\n key: K,\n fn: (ctx: C) => T,\n onThrow: (error: unknown) => E,\n ) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, M> =>\n workflow.fromSync(key, fn, onThrow);\n\n/** Reusable wrapper around {@link Railway.fromResult}. */\nexport const fromResultNamed =\n <K extends string, C extends object, T, E>(key: K, fn: (ctx: C) => Result<T, E>) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, M> =>\n workflow.fromResult(key, fn);\n\n/**\n * Reusable wrapper around {@link Railway.fromPromise}. Upgrades the\n * workflow to async mode when applied.\n */\nexport const fromPromiseNamed =\n <K extends string, C extends object, T, E>(\n key: K,\n fn: (ctx: C) => PromiseLike<T>,\n onReject: (error: unknown) => E,\n ) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, \"async\"> =>\n workflow.fromPromise(key, fn, onReject);\n\n/** Reusable wrapper around {@link Railway.fromAsync}. */\nexport const fromAsyncNamed =\n <K extends string, C extends object, T, E>(key: K, fn: (ctx: C) => ResultAsync<T, E>) =>\n <I extends C, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, T>, F | E, \"async\"> =>\n workflow.fromAsync(key, fn);\n\n/** Reusable wrapper around {@link Railway.derive} — pure sync derivation. */\nexport const deriveNamed =\n <K extends string, C extends object, T>(key: K, fn: (ctx: C) => T) =>\n <I extends C, E, M extends RailwayMode>(\n workflow: Railway<I, E, M>,\n ): Railway<I & Record<K, T>, E, M> =>\n workflow.derive(key, fn);\n\n/** Reusable wrapper around {@link Railway.require} — narrows a nullable field. */\nexport const requireNamed =\n <K extends string, S extends string, C extends object, E>(\n key: K,\n source: S,\n onMissing: (ctx: C & Record<S, unknown>) => E,\n ) =>\n <I extends C & Record<S, unknown>, F, M extends RailwayMode>(\n workflow: Railway<I, F, M>,\n ): Railway<I & Record<K, NonNullable<I[S]>>, F | E, M> =>\n workflow.require(key, source, onMissing);\n\n/**\n * Reusable wrapper around {@link Railway.parallel}. Branches run\n * concurrently and merge their named outputs back into context.\n */\nexport const parallelNamed =\n <R extends BranchRecord>(branches: R) =>\n <I extends ParallelInput<R>, E, M extends RailwayMode>(\n workflow: Railway<I, E, M>,\n ): Railway<I & ParallelOutput<R>, E | ParallelError<R>, \"async\"> => {\n // TS cannot prove contravariant branch params after storing reusable steps.\n const typedBranches = branches as unknown as Record<string, BranchFn<I>>;\n return workflow.parallel(typedBranches) as unknown as Railway<\n I & ParallelOutput<R>,\n E | ParallelError<R>,\n \"async\"\n >;\n };\n\n/**\n * Reusable wrapper around {@link Railway.select} — projects the final\n * context into the workflow's output type.\n */\nexport const select =\n <C extends object, T>(fn: (ctx: C) => T) =>\n <E, M extends RailwayMode>(workflow: Railway<C, E, M>): RailwayOutput<T, E, M> =>\n workflow.select(fn);\n"]}
@@ -1,4 +1,4 @@
1
- import { R as ResultAsync } from './async-CCA1yK8q.cjs';
1
+ import { R as ResultAsync } from './async-CH8Cs8KE.cjs';
2
2
  import { R as Result } from './types-C2Dp1d5J.cjs';
3
3
 
4
4
  /**
@@ -183,6 +183,23 @@ declare function railway<I, A, B, C, D, E, F, G, H>(input: I, step1: UnaryStep<R
183
183
  declare const parseWith: <I, T, E>(parser: ParserLike<I, T>, onThrow: (error: unknown) => E) => {
184
184
  as: <K extends string>(key: K) => <F, M extends RailwayMode>(workflow: Railway<RailwayInput<I>, F, M>) => Railway<RailwayInput<I> & Record<K, T>, F | E, M>;
185
185
  };
186
+ /**
187
+ * Name-first companion to {@link parseWith}: parse the workflow input with a
188
+ * Zod-like schema (or unary parse fn), naming the output field in the same
189
+ * `(key, ...)` shape as {@link fromSyncNamed}, {@link deriveNamed}, et al.
190
+ * Prefer this in `railway(...)` pipelines so every step's name aligns at the
191
+ * left edge.
192
+ *
193
+ * @example
194
+ * ```ts
195
+ * railway(
196
+ * rawId,
197
+ * parseNamed("id", IdSchema, toError),
198
+ * fromPromiseNamed("profile", ({ id }) => fetchProfile(id), toError),
199
+ * );
200
+ * ```
201
+ */
202
+ declare const parseNamed: <K extends string, I, T, E>(key: K, parser: ParserLike<I, T>, onThrow: (error: unknown) => E) => <F, M extends RailwayMode>(workflow: Railway<RailwayInput<I>, F, M>) => Railway<RailwayInput<I> & Record<K, T>, F | E, M>;
186
203
  /**
187
204
  * Reusable wrapper around {@link Railway.fromSync}. Captures key + fn +
188
205
  * onThrow once; applies to any compatible workflow.
@@ -212,4 +229,4 @@ declare const parallelNamed: <R extends BranchRecord>(branches: R) => <I extends
212
229
  */
213
230
  declare const select: <C extends object, T>(fn: (ctx: C) => T) => <E, M extends RailwayMode>(workflow: Railway<C, E, M>) => RailwayOutput<T, E, M>;
214
231
 
215
- export { Railway, type RailwayInput, type RailwayMode, type RailwayOutput, deriveNamed, fromAsyncNamed, fromPromiseNamed, fromResultNamed, fromSyncNamed, parallelNamed, parseWith, railway, requireNamed, select };
232
+ export { Railway, type RailwayInput, type RailwayMode, type RailwayOutput, deriveNamed, fromAsyncNamed, fromPromiseNamed, fromResultNamed, fromSyncNamed, parallelNamed, parseNamed, parseWith, railway, requireNamed, select };
package/dist/railway.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { R as ResultAsync } from './async-DH_-dNIo.js';
1
+ import { R as ResultAsync } from './async-DKISqIBc.js';
2
2
  import { R as Result } from './types-C2Dp1d5J.js';
3
3
 
4
4
  /**
@@ -183,6 +183,23 @@ declare function railway<I, A, B, C, D, E, F, G, H>(input: I, step1: UnaryStep<R
183
183
  declare const parseWith: <I, T, E>(parser: ParserLike<I, T>, onThrow: (error: unknown) => E) => {
184
184
  as: <K extends string>(key: K) => <F, M extends RailwayMode>(workflow: Railway<RailwayInput<I>, F, M>) => Railway<RailwayInput<I> & Record<K, T>, F | E, M>;
185
185
  };
186
+ /**
187
+ * Name-first companion to {@link parseWith}: parse the workflow input with a
188
+ * Zod-like schema (or unary parse fn), naming the output field in the same
189
+ * `(key, ...)` shape as {@link fromSyncNamed}, {@link deriveNamed}, et al.
190
+ * Prefer this in `railway(...)` pipelines so every step's name aligns at the
191
+ * left edge.
192
+ *
193
+ * @example
194
+ * ```ts
195
+ * railway(
196
+ * rawId,
197
+ * parseNamed("id", IdSchema, toError),
198
+ * fromPromiseNamed("profile", ({ id }) => fetchProfile(id), toError),
199
+ * );
200
+ * ```
201
+ */
202
+ declare const parseNamed: <K extends string, I, T, E>(key: K, parser: ParserLike<I, T>, onThrow: (error: unknown) => E) => <F, M extends RailwayMode>(workflow: Railway<RailwayInput<I>, F, M>) => Railway<RailwayInput<I> & Record<K, T>, F | E, M>;
186
203
  /**
187
204
  * Reusable wrapper around {@link Railway.fromSync}. Captures key + fn +
188
205
  * onThrow once; applies to any compatible workflow.
@@ -212,4 +229,4 @@ declare const parallelNamed: <R extends BranchRecord>(branches: R) => <I extends
212
229
  */
213
230
  declare const select: <C extends object, T>(fn: (ctx: C) => T) => <E, M extends RailwayMode>(workflow: Railway<C, E, M>) => RailwayOutput<T, E, M>;
214
231
 
215
- export { Railway, type RailwayInput, type RailwayMode, type RailwayOutput, deriveNamed, fromAsyncNamed, fromPromiseNamed, fromResultNamed, fromSyncNamed, parallelNamed, parseWith, railway, requireNamed, select };
232
+ export { Railway, type RailwayInput, type RailwayMode, type RailwayOutput, deriveNamed, fromAsyncNamed, fromPromiseNamed, fromResultNamed, fromSyncNamed, parallelNamed, parseNamed, parseWith, railway, requireNamed, select };
package/dist/railway.js CHANGED
@@ -68,6 +68,7 @@ var ResultAsync = class _ResultAsync {
68
68
  this.run = run;
69
69
  }
70
70
  run;
71
+ promise = null;
71
72
  static fromResult(result) {
72
73
  return new _ResultAsync(async () => result);
73
74
  }
@@ -129,14 +130,14 @@ var ResultAsync = class _ResultAsync {
129
130
  );
130
131
  }
131
132
  map(fn) {
132
- return new _ResultAsync(async () => map(await this.run(), fn));
133
+ return new _ResultAsync(async () => map(await this.resolve(), fn));
133
134
  }
134
135
  mapErr(fn) {
135
- return new _ResultAsync(async () => mapErr(await this.run(), fn));
136
+ return new _ResultAsync(async () => mapErr(await this.resolve(), fn));
136
137
  }
137
138
  flatMap(fn) {
138
139
  return new _ResultAsync(async () => {
139
- const first = await this.run();
140
+ const first = await this.resolve();
140
141
  if (isErr(first)) {
141
142
  return first;
142
143
  }
@@ -153,12 +154,16 @@ var ResultAsync = class _ResultAsync {
153
154
  andThen(fn) {
154
155
  return this.flatMap(fn);
155
156
  }
157
+ /**
158
+ * Alias for {@link flatMap}.
159
+ * @deprecated Use {@link flatMap} or keep/use compat {@link andThen} instead.
160
+ */
156
161
  chain(fn) {
157
162
  return this.flatMap(fn);
158
163
  }
159
164
  recover(fn) {
160
165
  return new _ResultAsync(async () => {
161
- const first = await this.run();
166
+ const first = await this.resolve();
162
167
  if (!isErr(first)) {
163
168
  return first;
164
169
  }
@@ -171,7 +176,7 @@ var ResultAsync = class _ResultAsync {
171
176
  }
172
177
  tap(fn) {
173
178
  return new _ResultAsync(async () => {
174
- const result = await this.run();
179
+ const result = await this.resolve();
175
180
  if (!isErr(result)) {
176
181
  fn(result.value);
177
182
  }
@@ -180,7 +185,7 @@ var ResultAsync = class _ResultAsync {
180
185
  }
181
186
  tapErr(fn) {
182
187
  return new _ResultAsync(async () => {
183
- const result = await this.run();
188
+ const result = await this.resolve();
184
189
  if (isErr(result)) {
185
190
  fn(result.error);
186
191
  }
@@ -188,19 +193,32 @@ var ResultAsync = class _ResultAsync {
188
193
  });
189
194
  }
190
195
  unwrapOr(defaultValue) {
191
- return this.run().then((result) => isErr(result) ? defaultValue : result.value);
196
+ return this.resolve().then((result) => isErr(result) ? defaultValue : result.value);
192
197
  }
198
+ /**
199
+ * @deprecated Await the ResultAsync and narrow with {@link isOk} — this method
200
+ * re-executes deferred factories and cannot narrow.
201
+ */
193
202
  isOk() {
194
- return this.run().then((result) => !isErr(result));
203
+ return this.resolve().then((result) => !isErr(result));
195
204
  }
205
+ /**
206
+ * @deprecated Await the ResultAsync and narrow with {@link isErr} — this method
207
+ * re-executes deferred factories and cannot narrow.
208
+ */
196
209
  isErr() {
197
- return this.run().then((result) => isErr(result));
210
+ return this.resolve().then((result) => isErr(result));
198
211
  }
199
212
  match(onOk, onErr) {
200
- return this.run().then((result) => isErr(result) ? onErr(result.error) : onOk(result.value));
213
+ return this.resolve().then(
214
+ (result) => isErr(result) ? onErr(result.error) : onOk(result.value)
215
+ );
201
216
  }
202
217
  resolve() {
203
- return this.run();
218
+ if (!this.promise) {
219
+ this.promise = this.run();
220
+ }
221
+ return this.promise;
204
222
  }
205
223
  /**
206
224
  * Thenable shim — `await ra` resolves to a bare tagged-union `Result<T, E>`.
@@ -208,7 +226,7 @@ var ResultAsync = class _ResultAsync {
208
226
  */
209
227
  // biome-ignore lint/suspicious/noThenProperty: makes ResultAsync awaitable
210
228
  then(onfulfilled, onrejected) {
211
- return this.run().then(
229
+ return this.resolve().then(
212
230
  // Safe: without onfulfilled, R1 stays at its Result<T, E> default.
213
231
  (r) => onfulfilled ? onfulfilled(r) : r,
214
232
  onrejected ?? void 0
@@ -395,6 +413,7 @@ function railway(input, ...steps) {
395
413
  var parseWith = (parser, onThrow) => ({
396
414
  as: (key) => (workflow) => workflow.fromSync(key, ({ input }) => parseWithParser(parser, input), onThrow)
397
415
  });
416
+ var parseNamed = (key, parser, onThrow) => (workflow) => workflow.fromSync(key, ({ input }) => parseWithParser(parser, input), onThrow);
398
417
  var fromSyncNamed = (key, fn, onThrow) => (workflow) => workflow.fromSync(key, fn, onThrow);
399
418
  var fromResultNamed = (key, fn) => (workflow) => workflow.fromResult(key, fn);
400
419
  var fromPromiseNamed = (key, fn, onReject) => (workflow) => workflow.fromPromise(key, fn, onReject);
@@ -407,6 +426,6 @@ var parallelNamed = (branches) => (workflow) => {
407
426
  };
408
427
  var select = (fn) => (workflow) => workflow.select(fn);
409
428
 
410
- export { Railway, deriveNamed, fromAsyncNamed, fromPromiseNamed, fromResultNamed, fromSyncNamed, parallelNamed, parseWith, railway, requireNamed, select };
429
+ export { Railway, deriveNamed, fromAsyncNamed, fromPromiseNamed, fromResultNamed, fromSyncNamed, parallelNamed, parseNamed, parseWith, railway, requireNamed, select };
411
430
  //# sourceMappingURL=railway.js.map
412
431
  //# sourceMappingURL=railway.js.map