@onrails/result 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DESIGN.md +10 -18
- package/README.md +14 -59
- package/RECIPES.md +12 -25
- package/dist/{async-u8U5P2EH.d.cts → async-BR3AX0ck.d.cts} +54 -18
- package/dist/{async-1fIhfzFu.d.ts → async-SZ7BEl0g.d.ts} +54 -18
- package/dist/compat/neverthrow.cjs +39 -51
- package/dist/compat/neverthrow.cjs.map +1 -1
- package/dist/compat/neverthrow.d.cts +3 -3
- package/dist/compat/neverthrow.d.ts +3 -3
- package/dist/compat/neverthrow.js +39 -51
- package/dist/compat/neverthrow.js.map +1 -1
- package/dist/extra.cjs +1 -1
- package/dist/extra.cjs.map +1 -1
- package/dist/extra.d.cts +5 -11
- package/dist/extra.d.ts +5 -11
- package/dist/extra.js +1 -1
- package/dist/extra.js.map +1 -1
- package/dist/fluent.cjs +55 -27
- package/dist/fluent.cjs.map +1 -1
- package/dist/fluent.d.cts +37 -6
- package/dist/fluent.d.ts +37 -6
- package/dist/fluent.js +55 -27
- package/dist/fluent.js.map +1 -1
- package/dist/index.cjs +80 -94
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +146 -44
- package/dist/index.d.ts +146 -44
- package/dist/index.js +77 -94
- package/dist/index.js.map +1 -1
- package/dist/railway.cjs +98 -172
- package/dist/railway.cjs.map +1 -1
- package/dist/railway.d.cts +25 -179
- package/dist/railway.d.ts +25 -179
- package/dist/railway.js +99 -162
- package/dist/railway.js.map +1 -1
- package/dist/try-gen.cjs +1 -1
- package/dist/try-gen.cjs.map +1 -1
- package/dist/try-gen.js +1 -1
- package/dist/try-gen.js.map +1 -1
- package/package.json +1 -16
- package/skills/railway-do-notation/SKILL.md +29 -68
- package/skills/result-composition/SKILL.md +2 -4
- package/dist/$.cjs +0 -40
- package/dist/$.cjs.map +0 -1
- package/dist/$.js +0 -36
- package/dist/$.js.map +0 -1
- package/dist/_.d.cts +0 -2
- package/dist/_.d.ts +0 -2
- package/dist/interop.cjs +0 -433
- package/dist/interop.cjs.map +0 -1
- package/dist/interop.d.cts +0 -75
- package/dist/interop.d.ts +0 -75
- package/dist/interop.js +0 -429
- package/dist/interop.js.map +0 -1
- package/dist/validation.cjs +0 -53
- package/dist/validation.cjs.map +0 -1
- package/dist/validation.d.cts +0 -72
- package/dist/validation.d.ts +0 -72
- package/dist/validation.js +0 -48
- package/dist/validation.js.map +0 -1
package/dist/fluent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/result.ts","../src/fluent.ts"],"names":[],"mappings":"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","file":"fluent.js","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// 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`, use a namespace\n * import (`import * as R from \"@onrails/result\"` → `R.match`) to dissolve\n * the collision.\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 * 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 — returns the `Ok` value, or **throws the original `Err`\n * value** when called on an `Err`. This is the assertion tier (RFC 0001 §4):\n * intended for `*.spec.ts` / `*.test.ts`, where throwing fails the test loudly.\n * In business logic prefer {@link match} or {@link unwrapOr}; the lint plugins\n * flag `unwrapOk` outside test files.\n *\n * @returns the unwrapped `Ok` value\n * @throws the carried `Err` value when the result is `Err`\n *\n * @example\n * ```ts\n * // in a *.spec.ts\n * expect(unwrapOk(ok(5))).toBe(5);\n * expect(() => unwrapOk(err(error))).toThrow(error);\n * ```\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 — returns the `Err` value, or **throws a `TypeError`**\n * when called on an `Ok`. Mirror of {@link unwrapOk} on the error track and\n * part of the same assertion tier (RFC 0001 §4): intended for `*.spec.ts` /\n * `*.test.ts`. Prefer {@link match} / {@link unwrapOr} in business logic; the\n * lint plugins flag `unwrapErr` outside test files.\n *\n * @returns the unwrapped `Err` value\n * @throws `TypeError` when the result is `Ok`\n *\n * @example\n * ```ts\n * // in a *.spec.ts\n * expect(unwrapErr(err(\"x\"))).toBe(\"x\");\n * expect(() => unwrapErr(ok(5))).toThrow(TypeError);\n * ```\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/**\n * Wraps a throwing sync function, returning a function that produces a\n * {@link Result} instead of throwing. Thrown errors pass through `onThrow` to\n * become a typed `Err`; a normal return becomes `Ok`. The neverthrow analogue\n * is `Result.fromThrowable`.\n *\n * @param fn - the throwing function to wrap\n * @param onThrow - maps a thrown value to the `Err` channel\n * @returns a function with `fn`'s parameters that returns `Result<ReturnType, E>`\n *\n * @example\n * ```ts\n * type ParseError = { kind: \"parse\"; message: string };\n * const parse = trySync(\n * JSON.parse,\n * (e): ParseError => ({ kind: \"parse\", message: String(e) }),\n * );\n * parse(\"{}\"); // Ok({})\n * parse(\"nope\"); // Err({ kind: \"parse\", … })\n * ```\n */\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/**\n * Variadic value-first pipe — threads `value` through up to nine unary fns,\n * left-to-right. Use {@link pipe} when you already have a starting value;\n * use {@link flow} to define a reusable composed function with no value yet.\n *\n * @example\n * ```ts\n * pipe(\n * parseConfig(raw),\n * map((cfg) => cfg.name),\n * flatMap((name) => (name ? ok(name) : err({ kind: \"empty\" as const }))),\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","import type { ResultAsync } from \"./async.js\";\nimport { flatMap, map, mapErr, match, unwrapOr } from \"./result.js\";\nimport type { Result } from \"./types.js\";\n\n/** Opt-in dot chaining over a sync {@link Result} */\nexport type FluentResult<T, E> = {\n readonly result: Result<T, E>;\n map: <U>(fn: (value: T) => U) => FluentResult<U, E>;\n mapErr: <F>(fn: (error: E) => F) => FluentResult<T, F>;\n flatMap: <U>(fn: (value: T) => Result<U, E>) => FluentResult<U, E>;\n andThen: <U>(fn: (value: T) => Result<U, E>) => FluentResult<U, E>;\n\n match: <U>(onOk: (value: T) => U, onErr: (error: E) => U) => U;\n unwrapOr: (defaultValue: T) => T;\n};\n\nexport const fluent = <T, E>(result: Result<T, E>): FluentResult<T, E> => ({\n result,\n map: (fn) => fluent(map(result, fn)),\n mapErr: (fn) => fluent(mapErr(result, fn)),\n flatMap: (fn) => fluent(flatMap(result, fn)),\n andThen: (fn) => fluent(flatMap(result, fn)),\n\n match: (onOk, onErr) => match(onOk, onErr)(result),\n unwrapOr: (defaultValue) => unwrapOr(result, defaultValue),\n});\n\n/** Opt-in dot chaining over {@link ResultAsync} */\nexport type FluentResultAsync<T, E> = {\n readonly resultAsync: ResultAsync<T, E>;\n map: <U>(fn: (value: T) => U) => FluentResultAsync<U, E>;\n mapErr: <F>(fn: (error: E) => F) => FluentResultAsync<T, F>;\n flatMap: <U>(fn: (value: T) => ResultAsync<U, E>) => FluentResultAsync<U, E>;\n andThen: <U>(fn: (value: T) => ResultAsync<U, E>) => FluentResultAsync<U, E>;\n\n match: <U>(onOk: (value: T) => U, onErr: (error: E) => U) => Promise<U>;\n};\n\nexport const fluentAsync = <T, E>(resultAsync: ResultAsync<T, E>): FluentResultAsync<T, E> => ({\n resultAsync,\n map: (fn) => fluentAsync(resultAsync.map(fn)),\n mapErr: (fn) => fluentAsync(resultAsync.mapErr(fn)),\n flatMap: (fn) => fluentAsync(resultAsync.flatMap(fn)),\n andThen: (fn) => fluentAsync(resultAsync.andThen(fn)),\n\n match: (onOk, onErr) => resultAsync.match(onOk, onErr),\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/dual.ts","../src/result.ts","../src/fluent.ts"],"names":[],"mappings":"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","file":"fluent.js","sourcesContent":["/**\n * @onrails/result internal — owning module for the **dual-form idiom**.\n *\n * Every dual-form transform in this package (`map`, `flatMap`, `match`, …)\n * accepts either shape:\n *\n * data-first: `map(result, fn)` — full arity, runs immediately\n * curried: `map(fn)(result)` — arity minus the leading `self`, returns\n * a unary function awaiting the data\n *\n * {@link dual} is the single arity dispatcher those transforms derive from;\n * hand-rolled `args.length` checks are not allowed elsewhere.\n *\n * NOTE: a twin copy of this module lives at `packages/maybe/src/internal/dual.ts`\n * — keep the two in sync when editing.\n *\n * Internal only: not listed in package.json `exports` or tsup entries.\n */\n\n/**\n * Derive a dual-form (data-first / curried) function from a single\n * data-first `body`.\n *\n * When called with `args.length >= arity` the wrapper runs `body(...args)`\n * (data-first). With fewer arguments it returns `(self) => body(self, ...args)`\n * — the curried, data-last-`self` form used with `pipe`/`flow`.\n *\n * The public type is supplied entirely by the caller: annotate the exported\n * const with the exact overload set and let `F` be inferred from it.\n *\n * @example\n * ```ts\n * export const map: {\n * <T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;\n * <T, U>(fn: (value: T) => U): <E>(result: Result<T, E>) => Result<U, E>;\n * } = dual(\n * 2,\n * <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 */\nexport const dual = <F>(arity: number, body: (...args: never[]) => unknown): F => {\n // `(...args: never[]) => unknown` is the top function type, so every typed\n // body is assignable to the parameter — but it cannot be invoked with\n // `unknown` arguments. Re-view it through the variadic shape the dispatcher\n // actually forwards; the constraint is that `body` only ever receives the\n // arguments the caller's overload annotation admitted.\n const run = body as (...args: readonly unknown[]) => unknown;\n const dispatcher = (...args: readonly unknown[]): unknown =>\n args.length >= arity ? run(...args) : (self: unknown) => run(self, ...args);\n // The caller's overload annotation on the exported const supplies the real\n // public type; internally the dispatcher stays `unknown`-typed.\n return dispatcher as F;\n};\n","import { dual } from \"./internal/dual.js\";\nimport 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// Dual-form helpers — each export accepts either shape:\n// data-first: `map(result, fn)`\n// curried: `map(fn)(result)`\n// Arity dispatch is derived from the internal `dual` combinator\n// (src/internal/dual.ts); the const annotation carries the public overloads.\n// ─────────────────────────────────────────────────────────────────────────────\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 const map: {\n <T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;\n <T, U>(fn: (value: T) => U): <E>(result: Result<T, E>) => Result<U, E>;\n} = dual(\n 2,\n <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/**\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 const mapErr: {\n <T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;\n <E, F>(fn: (error: E) => F): <T>(result: Result<T, E>) => Result<T, F>;\n} = dual(\n 2,\n <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/**\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 const bimap: {\n <T, U, E, F>(result: Result<T, E>, onOk: (value: T) => U, onErr: (error: E) => F): Result<U, F>;\n <T, U, E, F>(\n onOk: (value: T) => U,\n onErr: (error: E) => F,\n ): (result: Result<T, E>) => Result<U, F>;\n} = dual(\n 3,\n <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/**\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 const flatMap: {\n <T, U, E, F>(result: Result<T, E>, fn: (value: T) => Result<U, F>): Result<U, E | F>;\n <T, U, F>(fn: (value: T) => Result<U, F>): <E>(result: Result<T, E>) => Result<U, E | F>;\n} = dual(\n 2,\n <T, U, E, F>(result: Result<T, E>, fn: (value: T) => Result<U, F>): Result<U, E | F> =>\n isOk(result) ? fn(result.value) : err(result.error),\n);\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 const recover: {\n <T, E, F>(result: Result<T, E>, fn: (error: E) => Result<T, F>): Result<T, F>;\n <T, E, F>(fn: (error: E) => Result<T, F>): (result: Result<T, E>) => Result<T, F>;\n} = dual(\n 2,\n <T, E, F>(result: Result<T, E>, fn: (error: E) => Result<T, F>): Result<T, F> =>\n isErr(result) ? fn(result.error) : ok(result.value),\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 const tap: {\n <T, E>(result: Result<T, E>, fn: (value: T) => void): Result<T, E>;\n <T>(fn: (value: T) => void): <E>(result: Result<T, E>) => Result<T, E>;\n} = dual(2, <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 `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 const tapErr: {\n <T, E>(result: Result<T, E>, fn: (error: E) => void): Result<T, E>;\n <E>(fn: (error: E) => void): <T>(result: Result<T, E>) => Result<T, E>;\n} = dual(2, <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 * 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`, use a namespace\n * import (`import * as R from \"@onrails/result\"` → `R.match`) to dissolve\n * the collision.\n *\n * @example\n * ```ts\n * const html = match(parsed, (cfg) => render(cfg), (e) => renderError(e));\n * ```\n */\nexport const match: {\n <T, E, U>(result: Result<T, E>, onOk: (value: T) => U, onErr: (error: E) => U): U;\n <T, E, U>(onOk: (value: T) => U, onErr: (error: E) => U): (result: Result<T, E>) => U;\n} = dual(\n 3,\n <T, E, U>(result: Result<T, E>, onOk: (value: T) => U, onErr: (error: E) => U): U =>\n isOk(result) ? onOk(result.value) : onErr(result.error),\n);\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: {\n <T, E>(result: Result<T, E>, defaultValue: T): T;\n <T>(defaultValue: T): <E>(result: Result<T, E>) => T;\n} = dual(\n 2,\n <T, E>(result: Result<T, E>, defaultValue: T): T => (isOk(result) ? result.value : defaultValue),\n);\n\n/**\n * Test/assert helper — returns the `Ok` value, or **throws the original `Err`\n * value** when called on an `Err`. This is the assertion tier (RFC 0001 §4):\n * intended for `*.spec.ts` / `*.test.ts`, where throwing fails the test loudly.\n * In business logic prefer {@link match} or {@link unwrapOr}; the lint plugins\n * flag `unwrapOk` outside test files.\n *\n * @returns the unwrapped `Ok` value\n * @throws the carried `Err` value when the result is `Err`\n *\n * @example\n * ```ts\n * // in a *.spec.ts\n * expect(unwrapOk(ok(5))).toBe(5);\n * expect(() => unwrapOk(err(error))).toThrow(error);\n * ```\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/** Alias of {@link unwrapOk} for syntax cohesion with `@onrails/maybe`. */\nexport const unwrap = unwrapOk;\n\n/**\n * Test/assert helper — returns the `Err` value, or **throws a `TypeError`**\n * when called on an `Ok`. Mirror of {@link unwrapOk} on the error track and\n * part of the same assertion tier (RFC 0001 §4): intended for `*.spec.ts` /\n * `*.test.ts`. Prefer {@link match} / {@link unwrapOr} in business logic; the\n * lint plugins flag `unwrapErr` outside test files.\n *\n * @returns the unwrapped `Err` value\n * @throws `TypeError` when the result is `Ok`\n *\n * @example\n * ```ts\n * // in a *.spec.ts\n * expect(unwrapErr(err(\"x\"))).toBe(\"x\");\n * expect(() => unwrapErr(ok(5))).toThrow(TypeError);\n * ```\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/**\n * Wraps a throwing sync function, returning a function that produces a\n * {@link Result} instead of throwing. Thrown errors pass through `onThrow` to\n * become a typed `Err`; a normal return becomes `Ok`. The neverthrow analogue\n * is `Result.fromThrowable`.\n *\n * @param fn - the throwing function to wrap\n * @param onThrow - maps a thrown value to the `Err` channel\n * @returns a function with `fn`'s parameters that returns `Result<ReturnType, E>`\n *\n * @example\n * ```ts\n * type ParseError = { kind: \"parse\"; message: string };\n * const parse = trySync(\n * JSON.parse,\n * (e): ParseError => ({ kind: \"parse\", message: String(e) }),\n * );\n * parse(\"{}\"); // Ok({})\n * parse(\"nope\"); // Err({ kind: \"parse\", … })\n * ```\n */\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/**\n * Variadic value-first pipe — threads `value` through up to nine unary fns,\n * left-to-right. Use {@link pipe} when you already have a starting value;\n * use {@link flow} to define a reusable composed function with no value yet.\n *\n * @example\n * ```ts\n * pipe(\n * parseConfig(raw),\n * map((cfg) => cfg.name),\n * flatMap((name) => (name ? ok(name) : err({ kind: \"empty\" as const }))),\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","import type { ResultAsync } from \"./async.js\";\nimport { bimap, flatMap, map, mapErr, match, recover, tap, tapErr, unwrapOr } from \"./result.js\";\nimport type { Result } from \"./types.js\";\n\n/** Opt-in dot chaining over a sync {@link Result} */\nexport type FluentResult<T, E> = {\n readonly result: Result<T, E>;\n map: <U>(fn: (value: T) => U) => FluentResult<U, E>;\n mapErr: <F>(fn: (error: E) => F) => FluentResult<T, F>;\n bimap: <U, F>(onOk: (value: T) => U, onErr: (error: E) => F) => FluentResult<U, F>;\n flatMap: <U, F = E>(fn: (value: T) => Result<U, F>) => FluentResult<U, E | F>;\n andThen: <U, F = E>(fn: (value: T) => Result<U, F>) => FluentResult<U, E | F>;\n recover: <F>(fn: (error: E) => Result<T, F>) => FluentResult<T, F>;\n tap: (fn: (value: T) => void) => FluentResult<T, E>;\n tapErr: (fn: (error: E) => void) => FluentResult<T, E>;\n\n match: <U>(onOk: (value: T) => U, onErr: (error: E) => U) => U;\n unwrapOr: (defaultValue: T) => T;\n};\n\n/**\n * Wrap a {@link Result} for opt-in dot chaining — app-edge sugar. Keep the\n * data-first helpers ({@link map}, {@link flatMap}) in library internals.\n *\n * Mirrors every core transform; `test/parity.spec.ts` enforces the mirror.\n *\n * @example\n * ```ts\n * fluent(ok(2)).map((n) => n * 3).unwrapOr(0); // 6\n * ```\n */\nexport const fluent = <T, E>(result: Result<T, E>): FluentResult<T, E> => ({\n result,\n map: (fn) => fluent(map(result, fn)),\n mapErr: (fn) => fluent(mapErr(result, fn)),\n bimap: (onOk, onErr) => fluent(bimap(result, onOk, onErr)),\n flatMap: (fn) => fluent(flatMap(result, fn)),\n andThen: (fn) => fluent(flatMap(result, fn)),\n recover: (fn) => fluent(recover(result, fn)),\n tap: (fn) => fluent(tap(result, fn)),\n tapErr: (fn) => fluent(tapErr(result, fn)),\n\n match: (onOk, onErr) => match(result, onOk, onErr),\n unwrapOr: (defaultValue) => unwrapOr(result, defaultValue),\n});\n\n/** Opt-in dot chaining over {@link ResultAsync} */\nexport type FluentResultAsync<T, E> = {\n readonly resultAsync: ResultAsync<T, E>;\n map: <U>(fn: (value: T) => U) => FluentResultAsync<U, E>;\n mapErr: <F>(fn: (error: E) => F) => FluentResultAsync<T, F>;\n flatMap: <U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F>,\n ) => FluentResultAsync<U, E | F>;\n andThen: <U, F = E>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F>,\n ) => FluentResultAsync<U, E | F>;\n recover: <F>(fn: (error: E) => ResultAsync<T, F> | Result<T, F>) => FluentResultAsync<T, F>;\n orElse: <F>(fn: (error: E) => ResultAsync<T, F> | Result<T, F>) => FluentResultAsync<T, F>;\n tap: (fn: (value: T) => void) => FluentResultAsync<T, E>;\n tapErr: (fn: (error: E) => void) => FluentResultAsync<T, E>;\n\n match: <U1, U2 = U1>(onOk: (value: T) => U1, onErr: (error: E) => U2) => Promise<U1 | U2>;\n unwrapOr: <U>(defaultValue: U) => Promise<T | U>;\n resolve: () => Promise<Result<T, E>>;\n};\n\n/**\n * Wrap a {@link ResultAsync} for opt-in dot chaining — the async counterpart of\n * {@link fluent}. App-edge sugar; await a terminal (`match`, `unwrapOr`,\n * `resolve`) to leave the fluent world.\n *\n * @example\n * ```ts\n * fluentAsync(okAsync(2)).map((n) => n * 3); // FluentResultAsync<number, never>\n * ```\n */\nexport const fluentAsync = <T, E>(resultAsync: ResultAsync<T, E>): FluentResultAsync<T, E> => ({\n resultAsync,\n map: (fn) => fluentAsync(resultAsync.map(fn)),\n mapErr: (fn) => fluentAsync(resultAsync.mapErr(fn)),\n flatMap: (fn) => fluentAsync(resultAsync.flatMap(fn)),\n andThen: (fn) => fluentAsync(resultAsync.andThen(fn)),\n recover: (fn) => fluentAsync(resultAsync.recover(fn)),\n orElse: (fn) => fluentAsync(resultAsync.orElse(fn)),\n tap: (fn) => fluentAsync(resultAsync.tap(fn)),\n tapErr: (fn) => fluentAsync(resultAsync.tapErr(fn)),\n\n match: (onOk, onErr) => resultAsync.match(onOk, onErr),\n unwrapOr: (defaultValue) => resultAsync.unwrapOr(defaultValue),\n resolve: () => resultAsync.resolve(),\n});\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
// src/internal/dual.ts
|
|
4
|
+
var dual = (arity, body) => {
|
|
5
|
+
const run = body;
|
|
6
|
+
const dispatcher = (...args) => args.length >= arity ? run(...args) : (self) => run(self, ...args);
|
|
7
|
+
return dispatcher;
|
|
8
|
+
};
|
|
9
|
+
|
|
3
10
|
// src/result.ts
|
|
4
11
|
var ok = (value) => ({
|
|
5
12
|
_tag: "Ok",
|
|
@@ -11,65 +18,47 @@ var err = (error) => ({
|
|
|
11
18
|
});
|
|
12
19
|
var isOk = (result) => result._tag === "Ok";
|
|
13
20
|
var isErr = (result) => result._tag === "Err";
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
var
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const fn = args[0];
|
|
36
|
-
return (result) => flatMapImpl(result, fn);
|
|
37
|
-
}
|
|
38
|
-
var recoverImpl = (result, fn) => isErr(result) ? fn(result.error) : ok(result.value);
|
|
39
|
-
function recover(...args) {
|
|
40
|
-
if (args.length === 2) return recoverImpl(args[0], args[1]);
|
|
41
|
-
const fn = args[0];
|
|
42
|
-
return (result) => recoverImpl(result, fn);
|
|
43
|
-
}
|
|
44
|
-
var tapImpl = (result, fn) => {
|
|
21
|
+
var map = dual(
|
|
22
|
+
2,
|
|
23
|
+
(result, fn) => isOk(result) ? ok(fn(result.value)) : err(result.error)
|
|
24
|
+
);
|
|
25
|
+
var mapErr = dual(
|
|
26
|
+
2,
|
|
27
|
+
(result, fn) => isErr(result) ? err(fn(result.error)) : ok(result.value)
|
|
28
|
+
);
|
|
29
|
+
var bimap = dual(
|
|
30
|
+
3,
|
|
31
|
+
(result, onOk, onErr) => isOk(result) ? ok(onOk(result.value)) : err(onErr(result.error))
|
|
32
|
+
);
|
|
33
|
+
var flatMap = dual(
|
|
34
|
+
2,
|
|
35
|
+
(result, fn) => isOk(result) ? fn(result.value) : err(result.error)
|
|
36
|
+
);
|
|
37
|
+
var recover = dual(
|
|
38
|
+
2,
|
|
39
|
+
(result, fn) => isErr(result) ? fn(result.error) : ok(result.value)
|
|
40
|
+
);
|
|
41
|
+
var tap = dual(2, (result, fn) => {
|
|
45
42
|
if (isOk(result)) fn(result.value);
|
|
46
43
|
return result;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
if (args.length === 2) return tapImpl(args[0], args[1]);
|
|
50
|
-
const fn = args[0];
|
|
51
|
-
return (result) => tapImpl(result, fn);
|
|
52
|
-
}
|
|
53
|
-
var tapErrImpl = (result, fn) => {
|
|
44
|
+
});
|
|
45
|
+
var tapErr = dual(2, (result, fn) => {
|
|
54
46
|
if (isErr(result)) fn(result.error);
|
|
55
47
|
return result;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const [onOk, onErr] = args;
|
|
66
|
-
return (result) => matchImpl(result, onOk, onErr);
|
|
67
|
-
}
|
|
68
|
-
var unwrapOr = (result, defaultValue) => isOk(result) ? result.value : defaultValue;
|
|
48
|
+
});
|
|
49
|
+
var match = dual(
|
|
50
|
+
3,
|
|
51
|
+
(result, onOk, onErr) => isOk(result) ? onOk(result.value) : onErr(result.error)
|
|
52
|
+
);
|
|
53
|
+
var unwrapOr = dual(
|
|
54
|
+
2,
|
|
55
|
+
(result, defaultValue) => isOk(result) ? result.value : defaultValue
|
|
56
|
+
);
|
|
69
57
|
function unwrapOk(result) {
|
|
70
58
|
if (isErr(result)) throw result.error;
|
|
71
59
|
return result.value;
|
|
72
60
|
}
|
|
61
|
+
var unwrap = unwrapOk;
|
|
73
62
|
function unwrapErr(result) {
|
|
74
63
|
if (isOk(result)) throw new TypeError("unwrapErr called on Ok");
|
|
75
64
|
return result.error;
|
|
@@ -102,17 +91,6 @@ var UnexpectedError = class extends Error {
|
|
|
102
91
|
};
|
|
103
92
|
|
|
104
93
|
// src/async.ts
|
|
105
|
-
var liftPromiseResult = async (promise, onDefect) => {
|
|
106
|
-
try {
|
|
107
|
-
const result = await promise;
|
|
108
|
-
if (isErr(result)) {
|
|
109
|
-
return result;
|
|
110
|
-
}
|
|
111
|
-
return isResultLike(result.value) ? result.value : result;
|
|
112
|
-
} catch (error) {
|
|
113
|
-
return err(onDefect(error));
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
94
|
var sequenceSettled = (settled) => {
|
|
117
95
|
const values = [];
|
|
118
96
|
for (const result of settled) {
|
|
@@ -207,16 +185,23 @@ var ResultAsync = class _ResultAsync {
|
|
|
207
185
|
}
|
|
208
186
|
/**
|
|
209
187
|
* Lifts an existing `Promise<Result<T, E>>` (e.g. from interop code) into a
|
|
210
|
-
* {@link ResultAsync}
|
|
211
|
-
*
|
|
188
|
+
* {@link ResultAsync}. A thrown defect is routed through `onDefect`,
|
|
189
|
+
* defaulting to {@link UnexpectedError}. The `Ok` value passes through
|
|
190
|
+
* verbatim — even when it happens to be Result-shaped.
|
|
212
191
|
*
|
|
213
192
|
* @param promise - a promise that already yields a `Result`
|
|
214
193
|
* @param onDefect - maps an unexpected throw to the `Err` channel
|
|
215
|
-
* @see {@link fromAsync} from `@onrails/result
|
|
194
|
+
* @see {@link fromAsync} from `@onrails/result`
|
|
216
195
|
*/
|
|
217
196
|
static fromResultPromise(promise, onDefect) {
|
|
218
197
|
const mapDefect = onDefect ?? ((error) => new UnexpectedError("Unexpected async defect", error));
|
|
219
|
-
return new _ResultAsync(() =>
|
|
198
|
+
return new _ResultAsync(async () => {
|
|
199
|
+
try {
|
|
200
|
+
return await promise;
|
|
201
|
+
} catch (error) {
|
|
202
|
+
return err(mapDefect(error));
|
|
203
|
+
}
|
|
204
|
+
});
|
|
220
205
|
}
|
|
221
206
|
/**
|
|
222
207
|
* Combines a homogeneous array of async results into one. Resolves
|
|
@@ -300,7 +285,7 @@ var ResultAsync = class _ResultAsync {
|
|
|
300
285
|
*
|
|
301
286
|
* @example
|
|
302
287
|
* ```ts
|
|
303
|
-
* load(id).mapErr((e): AppError => ({ kind: "load", cause: e }));
|
|
288
|
+
* load(id).mapErr((e): AppError => ({ kind: "load", cause: e })); // ResultAsync<T, AppError>
|
|
304
289
|
* ```
|
|
305
290
|
*/
|
|
306
291
|
mapErr(fn) {
|
|
@@ -324,18 +309,12 @@ var ResultAsync = class _ResultAsync {
|
|
|
324
309
|
return first;
|
|
325
310
|
}
|
|
326
311
|
const next = fn(first.value);
|
|
327
|
-
|
|
328
|
-
return next.resolve();
|
|
329
|
-
}
|
|
330
|
-
if (isResultLike(next)) {
|
|
331
|
-
return next;
|
|
332
|
-
}
|
|
333
|
-
return isCompatLike(next) ? next.inner : next;
|
|
312
|
+
return next instanceof _ResultAsync ? next.resolve() : next;
|
|
334
313
|
});
|
|
335
314
|
}
|
|
336
315
|
/**
|
|
337
316
|
* neverthrow-compat alias of {@link flatMap}. Kept as the documented compat
|
|
338
|
-
* tier; prefer
|
|
317
|
+
* tier; prefer {@link flatMap} in new code.
|
|
339
318
|
*
|
|
340
319
|
* @example
|
|
341
320
|
* ```ts
|
|
@@ -352,7 +331,7 @@ var ResultAsync = class _ResultAsync {
|
|
|
352
331
|
*
|
|
353
332
|
* @example
|
|
354
333
|
* ```ts
|
|
355
|
-
* loadFromCache(id).recover(() => loadFromOrigin(id));
|
|
334
|
+
* loadFromCache(id).recover(() => loadFromOrigin(id)); // ResultAsync<T, F>
|
|
356
335
|
* ```
|
|
357
336
|
*/
|
|
358
337
|
recover(fn) {
|
|
@@ -367,7 +346,7 @@ var ResultAsync = class _ResultAsync {
|
|
|
367
346
|
}
|
|
368
347
|
/**
|
|
369
348
|
* neverthrow-compat alias of {@link recover}. Kept as the documented compat
|
|
370
|
-
* tier; prefer
|
|
349
|
+
* tier; prefer {@link recover} in new code.
|
|
371
350
|
*
|
|
372
351
|
* @example
|
|
373
352
|
* ```ts
|
|
@@ -475,19 +454,18 @@ var ResultAsync = class _ResultAsync {
|
|
|
475
454
|
);
|
|
476
455
|
}
|
|
477
456
|
};
|
|
478
|
-
function isResultLike(v) {
|
|
479
|
-
return typeof v === "object" && v !== null && "_tag" in v && (v._tag === "Ok" || v._tag === "Err");
|
|
480
|
-
}
|
|
481
|
-
function isCompatLike(v) {
|
|
482
|
-
return typeof v === "object" && v !== null && "inner" in v && isResultLike(v.inner);
|
|
483
|
-
}
|
|
484
457
|
|
|
485
458
|
// src/async-lift.ts
|
|
486
459
|
var okAsync = ResultAsync.ok;
|
|
487
460
|
var errAsync = ResultAsync.err;
|
|
488
461
|
var fromPromise = ResultAsync.fromPromise;
|
|
489
462
|
var fromSafePromise = ResultAsync.fromSafePromise;
|
|
490
|
-
var
|
|
463
|
+
var fromResult = ResultAsync.fromResult;
|
|
464
|
+
var asyncAfter = dual(
|
|
465
|
+
2,
|
|
466
|
+
(result, fn) => fromResult(result).flatMap(fn)
|
|
467
|
+
);
|
|
468
|
+
var fromAsync = (fn, onDefect) => (...args) => ResultAsync.fromResultPromise(fn(...args), onDefect);
|
|
491
469
|
var toError = (error) => error instanceof Error ? error : new Error(String(error));
|
|
492
470
|
function tryAsync(promise, onReject) {
|
|
493
471
|
return onReject ? ResultAsync.fromPromise(promise, onReject) : ResultAsync.fromPromise(promise, toError);
|
|
@@ -506,17 +484,22 @@ var combineTuple = (results) => (
|
|
|
506
484
|
// Runtime identical to combine; the cast restores per-index tuple types.
|
|
507
485
|
combine(results)
|
|
508
486
|
);
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
487
|
+
function validateAll(results, combineErrors) {
|
|
488
|
+
const values = [];
|
|
489
|
+
const errors = [];
|
|
490
|
+
for (const result of results) {
|
|
491
|
+
if (isErr(result)) {
|
|
492
|
+
errors.push(result.error);
|
|
493
|
+
} else {
|
|
494
|
+
values.push(result.value);
|
|
495
|
+
}
|
|
516
496
|
}
|
|
517
|
-
|
|
497
|
+
if (errors.length === 0) return ok(values);
|
|
498
|
+
return err(combineErrors ? errors.reduce(combineErrors) : errors);
|
|
499
|
+
}
|
|
500
|
+
function validateTuple(results, combineErrors) {
|
|
501
|
+
return combineErrors ? validateAll(results, combineErrors) : validateAll(results);
|
|
518
502
|
}
|
|
519
|
-
var fromAsync = (fn, onDefect) => (...args) => ResultAsync.fromResultPromise(fn(...args), onDefect);
|
|
520
503
|
|
|
521
504
|
// src/pipe.ts
|
|
522
505
|
function flow(first, ...rest) {
|
|
@@ -557,6 +540,7 @@ var tryGen = (fn) => {
|
|
|
557
540
|
|
|
558
541
|
exports.$ = $;
|
|
559
542
|
exports.ResultAsync = ResultAsync;
|
|
543
|
+
exports.UnexpectedError = UnexpectedError;
|
|
560
544
|
exports.asyncAfter = asyncAfter;
|
|
561
545
|
exports.bimap = bimap;
|
|
562
546
|
exports.combine = combine;
|
|
@@ -576,7 +560,6 @@ exports.mapErr = mapErr;
|
|
|
576
560
|
exports.match = match;
|
|
577
561
|
exports.ok = ok;
|
|
578
562
|
exports.okAsync = okAsync;
|
|
579
|
-
exports.parallelTupleAsync = parallelTupleAsync;
|
|
580
563
|
exports.pipe = pipe;
|
|
581
564
|
exports.recover = recover;
|
|
582
565
|
exports.tap = tap;
|
|
@@ -584,9 +567,12 @@ exports.tapErr = tapErr;
|
|
|
584
567
|
exports.tryAsync = tryAsync;
|
|
585
568
|
exports.tryGen = tryGen;
|
|
586
569
|
exports.trySync = trySync;
|
|
570
|
+
exports.unwrap = unwrap;
|
|
587
571
|
exports.unwrapErr = unwrapErr;
|
|
588
572
|
exports.unwrapOk = unwrapOk;
|
|
589
573
|
exports.unwrapOr = unwrapOr;
|
|
574
|
+
exports.validateAll = validateAll;
|
|
575
|
+
exports.validateTuple = validateTuple;
|
|
590
576
|
exports.yieldResult = yieldResult;
|
|
591
577
|
//# sourceMappingURL=index.cjs.map
|
|
592
578
|
//# sourceMappingURL=index.cjs.map
|