@jagreehal/workflow 1.5.0 → 1.6.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/README.md +664 -350
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +179 -1
- package/dist/core.d.ts +179 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +5 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/visualize.cjs +6 -6
- package/dist/visualize.cjs.map +1 -1
- package/dist/visualize.js +6 -6
- package/dist/visualize.js.map +1 -1
- package/dist/workflow.cjs +1 -1
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.js +1 -1
- package/dist/workflow.js.map +1 -1
- package/docs/coming-from-neverthrow.md +920 -0
- package/docs/visualize-examples.md +330 -0
- package/package.json +2 -1
package/dist/core.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core.ts"],"sourcesContent":["/**\n * @jagreehal/workflow/core\n *\n * Core Result primitives and run() function.\n * Use this module for minimal bundle size when you don't need the full workflow capabilities\n * (like retries, timeout, or state persistence) provided by `createWorkflow`.\n *\n * This module provides:\n * 1. `Result` types for error handling without try/catch\n * 2. `run()` function for executing steps with standardized error management\n * 3. Utilities for transforming and combining Results\n */\n\n// =============================================================================\n// Core Result Types\n// =============================================================================\n\n/**\n * Represents a successful computation or a failed one.\n * Use this type to represent the outcome of an operation that might fail,\n * instead of throwing exceptions.\n *\n * @template T - The type of the success value\n * @template E - The type of the error value (defaults to unknown)\n * @template C - The type of the cause (defaults to unknown)\n */\nexport type Result<T, E = unknown, C = unknown> =\n | { ok: true; value: T }\n | { ok: false; error: E; cause?: C };\n\n/**\n * A Promise that resolves to a Result.\n * Use this for asynchronous operations that might fail.\n */\nexport type AsyncResult<T, E = unknown, C = unknown> = Promise<Result<T, E, C>>;\n\nexport type UnexpectedStepFailureCause =\n | {\n type: \"STEP_FAILURE\";\n origin: \"result\";\n error: unknown;\n cause?: unknown;\n }\n | {\n type: \"STEP_FAILURE\";\n origin: \"throw\";\n error: unknown;\n thrown: unknown;\n };\n\nexport type UnexpectedCause =\n | { type: \"UNCAUGHT_EXCEPTION\"; thrown: unknown }\n | UnexpectedStepFailureCause;\n\nexport type UnexpectedError = {\n type: \"UNEXPECTED_ERROR\";\n cause: UnexpectedCause;\n};\nexport type PromiseRejectedError = { type: \"PROMISE_REJECTED\"; cause: unknown };\n/** Cause type for promise rejections in async batch helpers */\nexport type PromiseRejectionCause = { type: \"PROMISE_REJECTION\"; reason: unknown };\nexport type EmptyInputError = { type: \"EMPTY_INPUT\"; message: string };\nexport type MaybeAsyncResult<T, E, C = unknown> = Result<T, E, C> | Promise<Result<T, E, C>>;\n\n// =============================================================================\n// Result Constructors\n// =============================================================================\n\n/**\n * Creates a successful Result.\n * Use this when an operation completes successfully.\n *\n * @param value - The success value to wrap\n * @returns A Result object with `{ ok: true, value }`\n *\n * @example\n * ```typescript\n * function divide(a: number, b: number): Result<number, string> {\n * if (b === 0) return err(\"Division by zero\");\n * return ok(a / b);\n * }\n * ```\n */\nexport const ok = <T>(value: T): Result<T, never, never> => ({ ok: true, value });\n\n/**\n * Creates a failed Result.\n * Use this when an operation fails.\n *\n * @param error - The error value describing what went wrong (e.g., error code, object)\n * @param options - Optional context about the failure\n * @param options.cause - The underlying cause of the error (e.g., a caught exception)\n * @returns A Result object with `{ ok: false, error }` (and optional cause)\n *\n * @example\n * ```typescript\n * // Simple error\n * const r1 = err(\"NOT_FOUND\");\n *\n * // Error with cause (useful for wrapping exceptions)\n * try {\n * // ... unsafe code\n * } catch (e) {\n * return err(\"PROCESSING_FAILED\", { cause: e });\n * }\n * ```\n */\nexport const err = <E, C = unknown>(\n error: E,\n options?: { cause?: C }\n): Result<never, E, C> => ({\n ok: false,\n error,\n ...(options?.cause !== undefined ? { cause: options.cause } : {}),\n});\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Checks if a Result is successful.\n * Use this to narrow the type of a Result to the success case.\n *\n * @param r - The Result to check\n * @returns `true` if successful, allowing access to `r.value`\n *\n * @example\n * ```typescript\n * const r = someOperation();\n * if (isOk(r)) {\n * // Use r.value (Type is T)\n * processValue(r.value);\n * } else {\n * // Handle r.error (Type is E)\n * handleError(r.error);\n * }\n * ```\n */\nexport const isOk = <T, E, C>(r: Result<T, E, C>): r is { ok: true; value: T } =>\n r.ok;\n\n/**\n * Checks if a Result is a failure.\n * Use this to narrow the type of a Result to the error case.\n *\n * @param r - The Result to check\n * @returns `true` if failed, allowing access to `r.error` and `r.cause`\n *\n * @example\n * ```typescript\n * if (isErr(r)) {\n * // Handle error case early\n * return;\n * }\n * // Proceed with success case\n * ```\n */\nexport const isErr = <T, E, C>(\n r: Result<T, E, C>\n): r is { ok: false; error: E; cause?: C } => !r.ok;\n\n/**\n * Checks if an error is an UnexpectedError.\n * Used internally by the framework but exported for advanced custom handling.\n * Indicates an error that wasn't typed/expected in the `run` signature.\n */\nexport const isUnexpectedError = (e: unknown): e is UnexpectedError =>\n typeof e === \"object\" &&\n e !== null &&\n (e as UnexpectedError).type === \"UNEXPECTED_ERROR\";\n\n// =============================================================================\n// Type Utilities\n// =============================================================================\n\ntype AnyFunction = (...args: never[]) => unknown;\n\n/**\n * Helper to extract the error type from Result or AsyncResult return values.\n * Works even when a function is declared to return a union of both forms.\n */\ntype ErrorOfReturn<R> = Extract<Awaited<R>, { ok: false }> extends { error: infer E }\n ? E\n : never;\n\n/**\n * Extract error type from a single function's return type\n */\nexport type ErrorOf<T extends AnyFunction> = ErrorOfReturn<ReturnType<T>>;\n\n/**\n * Extract union of error types from multiple functions\n */\nexport type Errors<T extends AnyFunction[]> = {\n [K in keyof T]: ErrorOf<T[K]>;\n}[number];\n\n/**\n * Extract value type from Result\n */\nexport type ExtractValue<T> = T extends { ok: true; value: infer U }\n ? U\n : never;\n\n/**\n * Extract error type from Result\n */\nexport type ExtractError<T> = T extends { ok: false; error: infer E }\n ? E\n : never;\n\n/**\n * Extract cause type from Result\n */\nexport type ExtractCause<T> = T extends { ok: false; cause?: infer C }\n ? C\n : never;\n\n/**\n * Helper to extract the cause type from Result or AsyncResult return values.\n * Works even when a function is declared to return a union of both forms.\n */\ntype CauseOfReturn<R> = Extract<Awaited<R>, { ok: false }> extends { cause?: infer C }\n ? C\n : never;\n\n/**\n * Extract cause type from a function's return type\n */\nexport type CauseOf<T extends AnyFunction> = CauseOfReturn<ReturnType<T>>;\n\n// =============================================================================\n// Step Options\n// =============================================================================\n\n/**\n * Options for configuring a step within a workflow.\n * Use these to enable tracing, caching, and state persistence.\n */\nexport type StepOptions = {\n /**\n * Human-readable label for the step.\n * Used in logs, traces, and error messages.\n * Highly recommended for debugging complex workflows.\n */\n name?: string;\n\n /**\n * Stable identity key for the step.\n * REQUIRED for:\n * 1. Caching: Used as the cache key.\n * 2. Resuming: Used to identify which steps have already completed.\n *\n * Must be unique within the workflow.\n */\n key?: string;\n\n /**\n * Retry configuration for transient failures.\n * When specified, the step will retry on errors according to this config.\n */\n retry?: RetryOptions;\n\n /**\n * Timeout configuration for the operation.\n * When specified, each attempt will be aborted after the timeout duration.\n */\n timeout?: TimeoutOptions;\n};\n\n// =============================================================================\n// Retry and Timeout Types\n// =============================================================================\n\n/**\n * Backoff strategy for retry operations.\n */\nexport type BackoffStrategy = \"fixed\" | \"linear\" | \"exponential\";\n\n/**\n * Configuration for step retry behavior.\n */\nexport type RetryOptions = {\n /**\n * Total number of attempts (1 = no retry, 3 = initial + 2 retries).\n * Must be >= 1.\n */\n attempts: number;\n\n /**\n * Backoff strategy between retries.\n * - 'fixed': Same delay each time (initialDelay)\n * - 'linear': Delay increases linearly (initialDelay * attempt)\n * - 'exponential': Delay doubles each time (initialDelay * 2^(attempt-1))\n * @default 'exponential'\n */\n backoff?: BackoffStrategy;\n\n /**\n * Initial delay in milliseconds before first retry.\n * @default 100\n */\n initialDelay?: number;\n\n /**\n * Maximum delay cap in milliseconds.\n * Prevents exponential backoff from growing too large.\n * @default 30000 (30 seconds)\n */\n maxDelay?: number;\n\n /**\n * Whether to add random jitter (0-25% of delay).\n * Helps prevent thundering herd when multiple workflows retry simultaneously.\n * @default true\n */\n jitter?: boolean;\n\n /**\n * Predicate to determine if a retry should occur.\n * Receives the error and current attempt number (1-indexed).\n * Return true to retry, false to fail immediately.\n * @default Always retry on any error\n */\n retryOn?: (error: unknown, attempt: number) => boolean;\n\n /**\n * Callback invoked before each retry attempt.\n * Useful for logging, metrics, or side effects.\n */\n onRetry?: (error: unknown, attempt: number, delayMs: number) => void;\n};\n\n/**\n * Configuration for step timeout behavior.\n */\nexport type TimeoutOptions = {\n /**\n * Timeout duration in milliseconds per attempt.\n * When combined with retry, each attempt gets its own timeout.\n */\n ms: number;\n\n /**\n * Custom error to use when timeout occurs.\n * @default StepTimeoutError with step details\n */\n error?: unknown;\n\n /**\n * Whether to pass an AbortSignal to the operation.\n * When true, the operation function receives (signal: AbortSignal) as argument.\n * Useful for fetch() and other APIs that support cancellation.\n * @default false\n */\n signal?: boolean;\n};\n\n/**\n * Standard timeout error type.\n */\nexport type StepTimeoutError = {\n type: \"STEP_TIMEOUT\";\n stepName?: string;\n stepKey?: string;\n timeoutMs: number;\n attempt?: number;\n};\n\n/**\n * Symbol used to mark any error (including custom errors) as a timeout error.\n * This allows detection of timeout errors even when users provide custom error payloads.\n */\nexport const STEP_TIMEOUT_MARKER: unique symbol = Symbol.for(\"step_timeout_marker\");\n\n/**\n * Metadata attached to timeout-marked errors.\n */\nexport type StepTimeoutMarkerMeta = {\n timeoutMs: number;\n stepName?: string;\n stepKey?: string;\n attempt?: number;\n};\n\n/**\n * Type guard to check if an error is a StepTimeoutError.\n * This checks both the standard type field AND the timeout marker symbol,\n * so custom errors provided via timeout.error are also detected.\n */\nexport function isStepTimeoutError(e: unknown): e is StepTimeoutError {\n if (typeof e !== \"object\" || e === null) {\n return false;\n }\n // Check for standard type field\n if ((e as StepTimeoutError).type === \"STEP_TIMEOUT\") {\n return true;\n }\n // Check for timeout marker (custom errors)\n return STEP_TIMEOUT_MARKER in e;\n}\n\n/**\n * Get timeout metadata from a timeout error (works with both standard and custom errors).\n * Returns undefined if the error is not a timeout error.\n */\nexport function getStepTimeoutMeta(e: unknown): StepTimeoutMarkerMeta | undefined {\n if (typeof e !== \"object\" || e === null) {\n return undefined;\n }\n // Check for standard type field first\n if ((e as StepTimeoutError).type === \"STEP_TIMEOUT\") {\n const err = e as StepTimeoutError;\n return {\n timeoutMs: err.timeoutMs,\n stepName: err.stepName,\n stepKey: err.stepKey,\n attempt: err.attempt,\n };\n }\n // Check for timeout marker (custom errors)\n if (STEP_TIMEOUT_MARKER in e) {\n return (e as Record<symbol, StepTimeoutMarkerMeta>)[STEP_TIMEOUT_MARKER];\n }\n return undefined;\n}\n\n// =============================================================================\n// RunStep Interface\n// =============================================================================\n\n/**\n * The `step` object passed to the function in `run(async (step) => { ... })`.\n * acts as the bridge between your business logic and the workflow engine.\n *\n * It provides methods to:\n * 1. Execute operations that return `Result` types.\n * 2. safely wrap operations that might throw exceptions (using `step.try`).\n * 3. Assign names and keys to operations for tracing and caching.\n *\n * @template E - The union of all known error types expected in this workflow.\n */\nexport interface RunStep<E = unknown> {\n /**\n * Execute a Result-returning operation (lazy function form).\n *\n * Use this form when the operation has side effects or is expensive,\n * so it's only executed if the step hasn't been cached/completed yet.\n *\n * @param operation - A function that returns a Result or AsyncResult\n * @param options - Step name or options object\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If the result is an error (stops execution safely)\n *\n * @example\n * ```typescript\n * const user = await step(() => fetchUser(id), \"fetch-user\");\n * ```\n */\n <T, StepE extends E, StepC = unknown>(\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n options?: StepOptions | string\n ): Promise<T>;\n\n /**\n * Execute a Result-returning operation (direct value form).\n *\n * Use this form for simple operations or when you already have a Result/Promise.\n * Note: The operation has already started/completed by the time `step` is called.\n *\n * @param result - A Result object or Promise resolving to a Result\n * @param options - Step name or options object\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If the result is an error (stops execution safely)\n *\n * @example\n * ```typescript\n * const user = await step(existingResult, \"check-result\");\n * ```\n */\n <T, StepE extends E, StepC = unknown>(\n result: Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n options?: StepOptions | string\n ): Promise<T>;\n\n /**\n * Execute a standard throwing operation safely.\n * Catches exceptions and maps them to a typed error, or wraps them if no mapper is provided.\n *\n * Use this when integrating with libraries that throw exceptions.\n *\n * @param operation - A function that returns a value or Promise (may throw)\n * @param options - Configuration including error mapping\n * @returns The success value\n * @throws {EarlyExit} If the operation throws (stops execution safely)\n *\n * @example\n * ```typescript\n * const data = await step.try(\n * () => db.query(),\n * {\n * name: \"db-query\",\n * onError: (e) => ({ type: \"DB_ERROR\", cause: e })\n * }\n * );\n * ```\n */\n try: <T, const Err extends E>(\n operation: () => T | Promise<T>,\n options:\n | { error: Err; name?: string; key?: string }\n | { onError: (cause: unknown) => Err; name?: string; key?: string }\n ) => Promise<T>;\n\n /**\n * Execute a Result-returning function and map its error to a typed error.\n *\n * Use this when calling functions that return Result<T, E> and you want to\n * map their typed errors to your workflow's error type. Unlike step.try(),\n * the error passed to onError is typed (not unknown).\n *\n * @param operation - A function that returns a Result or AsyncResult\n * @param options - Configuration including error mapping\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If the result is an error (stops execution safely)\n *\n * @example\n * ```typescript\n * const response = await step.fromResult(\n * () => callProvider(input),\n * {\n * name: \"call-provider\",\n * onError: (providerError) => ({\n * type: \"PROVIDER_FAILED\",\n * provider: providerError.provider,\n * cause: providerError\n * })\n * }\n * );\n * ```\n */\n fromResult: <T, ResultE, const Err extends E>(\n operation: () => Result<T, ResultE, unknown> | AsyncResult<T, ResultE, unknown>,\n options:\n | { error: Err; name?: string; key?: string }\n | { onError: (resultError: ResultE) => Err; name?: string; key?: string }\n ) => Promise<T>;\n\n /**\n * Execute a parallel operation (allAsync) with scope events for visualization.\n *\n * This wraps the operation with scope_start and scope_end events, enabling\n * visualization of parallel execution branches.\n *\n * @param name - Name for this parallel block (used in visualization)\n * @param operation - A function that returns a Result from allAsync or allSettledAsync\n * @returns The success value (unwrapped array)\n *\n * @example\n * ```typescript\n * const [user, posts] = await step.parallel('Fetch all data', () =>\n * allAsync([fetchUser(id), fetchPosts(id)])\n * );\n * ```\n */\n parallel: <T, StepE extends E, StepC = unknown>(\n name: string,\n operation: () => Result<T[], StepE, StepC> | AsyncResult<T[], StepE, StepC>\n ) => Promise<T[]>;\n\n /**\n * Execute a race operation (anyAsync) with scope events for visualization.\n *\n * This wraps the operation with scope_start and scope_end events, enabling\n * visualization of racing execution branches.\n *\n * @param name - Name for this race block (used in visualization)\n * @param operation - A function that returns a Result from anyAsync\n * @returns The success value (first to succeed)\n *\n * @example\n * ```typescript\n * const data = await step.race('Fastest API', () =>\n * anyAsync([fetchFromPrimary(id), fetchFromFallback(id)])\n * );\n * ```\n */\n race: <T, StepE extends E, StepC = unknown>(\n name: string,\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>\n ) => Promise<T>;\n\n /**\n * Execute an allSettled operation with scope events for visualization.\n *\n * This wraps the operation with scope_start and scope_end events, enabling\n * visualization of allSettled execution branches. Unlike step.parallel,\n * allSettled collects all results even if some fail.\n *\n * @param name - Name for this allSettled block (used in visualization)\n * @param operation - A function that returns a Result from allSettledAsync\n * @returns The success value (unwrapped array)\n *\n * @example\n * ```typescript\n * const [user, posts] = await step.allSettled('Fetch all data', () =>\n * allSettledAsync([fetchUser(id), fetchPosts(id)])\n * );\n * ```\n */\n allSettled: <T, StepE extends E, StepC = unknown>(\n name: string,\n operation: () => Result<T[], StepE, StepC> | AsyncResult<T[], StepE, StepC>\n ) => Promise<T[]>;\n\n /**\n * Execute an operation with retry and optional timeout.\n *\n * Use this for operations that may fail transiently (network issues, rate limits)\n * and benefit from automatic retry with backoff.\n *\n * @param operation - A function that returns a Result or AsyncResult\n * @param options - Retry configuration and optional timeout\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If all retries are exhausted (stops execution safely)\n *\n * @example\n * ```typescript\n * const data = await step.retry(\n * () => fetchFromExternalApi(id),\n * {\n * name: 'fetch-external',\n * attempts: 3,\n * backoff: 'exponential',\n * initialDelay: 200,\n * retryOn: (error) => error === 'RATE_LIMITED' || error === 'TRANSIENT',\n * onRetry: (error, attempt, delay) => {\n * console.log(`Retry ${attempt} after ${delay}ms`);\n * },\n * }\n * );\n * ```\n */\n retry: <T, StepE extends E, StepC = unknown>(\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n options: RetryOptions & { name?: string; key?: string; timeout?: TimeoutOptions }\n ) => Promise<T>;\n\n /**\n * Execute an operation with a timeout.\n *\n * Use this for operations that may hang indefinitely (external APIs, connections)\n * and need to be aborted after a certain duration.\n *\n * When `signal: true` is set, an AbortSignal is passed to your operation,\n * which you can use with APIs like fetch() for proper cancellation.\n *\n * @param operation - A function that returns a Result (may receive AbortSignal)\n * @param options - Timeout configuration\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If the operation times out (stops execution safely)\n *\n * @example\n * ```typescript\n * // Without AbortSignal\n * const data = await step.withTimeout(\n * () => fetchData(id),\n * { ms: 5000, name: 'fetch-data' }\n * );\n *\n * // With AbortSignal for fetch()\n * const data = await step.withTimeout(\n * (signal) => fetch(url, { signal }).then(r => ok(r.json())),\n * { ms: 5000, signal: true, name: 'fetch-url' }\n * );\n * ```\n */\n withTimeout: <T, StepE extends E, StepC = unknown>(\n operation:\n | (() => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>)\n | ((signal: AbortSignal) => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>),\n options: TimeoutOptions & { name?: string; key?: string }\n ) => Promise<T>;\n}\n\n// =============================================================================\n// Event Types (for run() optional event support)\n// =============================================================================\n\n/**\n * Unified event stream for workflow execution.\n *\n * Note: step_complete.result uses Result<unknown, unknown, unknown> because events\n * aggregate results from heterogeneous steps. At runtime, the actual Result object\n * preserves its original types, but the event type cannot statically represent them.\n * Use runtime checks or the meta field to interpret cause values.\n */\n/**\n * Scope types for parallel and race operations.\n */\nexport type ScopeType = \"parallel\" | \"race\" | \"allSettled\";\n\nexport type WorkflowEvent<E> =\n | { type: \"workflow_start\"; workflowId: string; ts: number }\n | { type: \"workflow_success\"; workflowId: string; ts: number; durationMs: number }\n | { type: \"workflow_error\"; workflowId: string; ts: number; durationMs: number; error: E }\n | { type: \"step_start\"; workflowId: string; stepId: string; stepKey?: string; name?: string; ts: number }\n | { type: \"step_success\"; workflowId: string; stepId: string; stepKey?: string; name?: string; ts: number; durationMs: number }\n | { type: \"step_error\"; workflowId: string; stepId: string; stepKey?: string; name?: string; ts: number; durationMs: number; error: E }\n | { type: \"step_aborted\"; workflowId: string; stepId: string; stepKey?: string; name?: string; ts: number; durationMs: number }\n | { type: \"step_complete\"; workflowId: string; stepKey: string; name?: string; ts: number; durationMs: number; result: Result<unknown, unknown, unknown>; meta?: StepFailureMeta }\n | { type: \"step_cache_hit\"; workflowId: string; stepKey: string; name?: string; ts: number }\n | { type: \"step_cache_miss\"; workflowId: string; stepKey: string; name?: string; ts: number }\n | { type: \"step_skipped\"; workflowId: string; stepKey?: string; name?: string; reason?: string; decisionId?: string; ts: number }\n | { type: \"scope_start\"; workflowId: string; scopeId: string; scopeType: ScopeType; name?: string; ts: number }\n | { type: \"scope_end\"; workflowId: string; scopeId: string; ts: number; durationMs: number; winnerId?: string }\n // Retry events\n | {\n type: \"step_retry\";\n workflowId: string;\n stepId: string;\n stepKey?: string;\n name?: string;\n ts: number;\n attempt: number;\n maxAttempts: number;\n delayMs: number;\n error: E;\n }\n | {\n type: \"step_retries_exhausted\";\n workflowId: string;\n stepId: string;\n stepKey?: string;\n name?: string;\n ts: number;\n durationMs: number;\n attempts: number;\n lastError: E;\n }\n // Timeout event\n | {\n type: \"step_timeout\";\n workflowId: string;\n stepId: string;\n stepKey?: string;\n name?: string;\n ts: number;\n timeoutMs: number;\n attempt?: number;\n };\n\n// =============================================================================\n// Run Options\n// =============================================================================\n\nexport type RunOptionsWithCatch<E, C = void> = {\n /**\n * Handler for expected errors.\n * Called when a step fails with a known error type.\n */\n onError?: (error: E, stepName?: string) => void;\n /**\n * Listener for workflow events (start, success, error, step events).\n * Use this for logging, telemetry, or debugging.\n */\n onEvent?: (event: WorkflowEvent<E | UnexpectedError>, ctx: C) => void;\n /**\n * Catch-all mapper for unexpected exceptions.\n * Required for \"Strict Mode\".\n * Converts unknown exceptions (like network crashes or bugs) into your typed error union E.\n */\n catchUnexpected: (cause: unknown) => E;\n /**\n * Unique ID for this workflow execution.\n * Defaults to a random UUID.\n * Useful for correlating logs across distributed systems.\n */\n workflowId?: string;\n /**\n * Arbitrary context object passed to onEvent.\n * Useful for passing request IDs, user IDs, or loggers.\n */\n context?: C;\n};\n\nexport type RunOptionsWithoutCatch<E, C = void> = {\n /**\n * Handler for expected errors AND unexpected errors.\n * Unexpected errors will be wrapped in `UnexpectedError`.\n */\n onError?: (error: E | UnexpectedError, stepName?: string) => void;\n onEvent?: (event: WorkflowEvent<E | UnexpectedError>, ctx: C) => void;\n catchUnexpected?: undefined;\n workflowId?: string;\n context?: C;\n};\n\nexport type RunOptions<E, C = void> = RunOptionsWithCatch<E, C> | RunOptionsWithoutCatch<E, C>;\n\n// =============================================================================\n// Early Exit Mechanism (exported for caching layer)\n// =============================================================================\n\n/**\n * Symbol used to identify early exit throws.\n * Exported for the caching layer in workflow.ts.\n * @internal\n */\nexport const EARLY_EXIT_SYMBOL: unique symbol = Symbol(\"early-exit\");\n\n/**\n * Metadata about how a step failed.\n * @internal\n */\nexport type StepFailureMeta =\n | { origin: \"result\"; resultCause?: unknown }\n | { origin: \"throw\"; thrown: unknown };\n\n/**\n * Early exit object thrown to short-circuit workflow execution.\n * @internal\n */\nexport type EarlyExit<E> = {\n [EARLY_EXIT_SYMBOL]: true;\n error: E;\n meta: StepFailureMeta;\n};\n\n/**\n * Create an early exit throw object.\n * Used by the caching layer to synthesize early exits for cached errors.\n * @internal\n */\nexport function createEarlyExit<E>(error: E, meta: StepFailureMeta): EarlyExit<E> {\n return {\n [EARLY_EXIT_SYMBOL]: true,\n error,\n meta,\n };\n}\n\n/**\n * Type guard for early exit objects.\n * @internal\n */\nexport function isEarlyExit<E>(e: unknown): e is EarlyExit<E> {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as Record<PropertyKey, unknown>)[EARLY_EXIT_SYMBOL] === true\n );\n}\n\n/**\n * Symbol to mark exceptions thrown by catchUnexpected mappers.\n * These should propagate without being re-processed.\n * @internal\n */\nconst MAPPER_EXCEPTION_SYMBOL: unique symbol = Symbol(\"mapper-exception\");\n\ntype MapperException = {\n [MAPPER_EXCEPTION_SYMBOL]: true;\n thrown: unknown;\n};\n\nfunction createMapperException(thrown: unknown): MapperException {\n return { [MAPPER_EXCEPTION_SYMBOL]: true, thrown };\n}\n\nfunction isMapperException(e: unknown): e is MapperException {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as Record<PropertyKey, unknown>)[MAPPER_EXCEPTION_SYMBOL] === true\n );\n}\n\n/** Helper to parse step options - accepts string or object form */\nfunction parseStepOptions(\n options?: StepOptions | string\n): StepOptions & { name?: string; key?: string } {\n if (typeof options === \"string\") {\n return { name: options };\n }\n return options ?? {};\n}\n\n// =============================================================================\n// Retry and Timeout Utilities\n// =============================================================================\n\n/**\n * Calculate the delay for a retry attempt based on the backoff strategy.\n * @internal\n */\nfunction calculateRetryDelay(\n attempt: number,\n options: {\n backoff: BackoffStrategy;\n initialDelay: number;\n maxDelay: number;\n jitter: boolean;\n }\n): number {\n const { backoff, initialDelay, maxDelay, jitter } = options;\n\n let delay: number;\n\n switch (backoff) {\n case \"fixed\":\n delay = initialDelay;\n break;\n case \"linear\":\n delay = initialDelay * attempt;\n break;\n case \"exponential\":\n delay = initialDelay * Math.pow(2, attempt - 1);\n break;\n }\n\n // Apply max cap\n delay = Math.min(delay, maxDelay);\n\n // Apply jitter (0-25% of delay)\n if (jitter) {\n const jitterAmount = delay * 0.25 * Math.random();\n delay = delay + jitterAmount;\n }\n\n return Math.floor(delay);\n}\n\n/**\n * Sleep for a specified number of milliseconds.\n * @internal\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Symbol used internally to identify timeout rejection.\n */\nconst TIMEOUT_SYMBOL: unique symbol = Symbol(\"timeout\");\n\n/**\n * Execute an operation with a timeout using Promise.race.\n * @internal\n */\nasync function executeWithTimeout<T>(\n operation: (() => Promise<T>) | ((signal: AbortSignal) => Promise<T>),\n options: TimeoutOptions,\n stepInfo: { name?: string; key?: string; attempt?: number }\n): Promise<T> {\n const controller = new AbortController();\n\n // Create the timeout error once\n const timeoutError: StepTimeoutError =\n (options.error as StepTimeoutError) ?? {\n type: \"STEP_TIMEOUT\",\n stepName: stepInfo.name,\n stepKey: stepInfo.key,\n timeoutMs: options.ms,\n attempt: stepInfo.attempt,\n };\n\n // Track the timeout ID for cleanup\n let timeoutId: ReturnType<typeof setTimeout>;\n\n // Create a timeout promise that rejects after the specified duration\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n controller.abort(); // Signal abort for operations that support it\n reject({ [TIMEOUT_SYMBOL]: true, error: timeoutError });\n }, options.ms);\n });\n\n // Execute the operation\n let operationPromise: Promise<T>;\n if (options.signal) {\n // Operation expects an AbortSignal\n operationPromise = Promise.resolve(\n (operation as (signal: AbortSignal) => Promise<T>)(controller.signal)\n );\n } else {\n // Standard operation\n operationPromise = Promise.resolve((operation as () => Promise<T>)());\n }\n\n try {\n // Race between operation and timeout\n const result = await Promise.race([operationPromise, timeoutPromise]);\n return result;\n } catch (error) {\n // Check if this was our timeout\n if (\n typeof error === \"object\" &&\n error !== null &&\n (error as Record<symbol, unknown>)[TIMEOUT_SYMBOL] === true\n ) {\n const errorToThrow = (error as { error: unknown }).error;\n\n // Mark the error with STEP_TIMEOUT_MARKER if it's a custom error (not already a StepTimeoutError)\n // This allows isStepTimeoutError() and getStepTimeoutMeta() to work with custom errors\n // Note: Always update metadata to reflect the current attempt (same error may be reused across retries)\n if (\n typeof errorToThrow === \"object\" &&\n errorToThrow !== null &&\n (errorToThrow as StepTimeoutError).type !== \"STEP_TIMEOUT\"\n ) {\n const meta: StepTimeoutMarkerMeta = {\n timeoutMs: options.ms,\n stepName: stepInfo.name,\n stepKey: stepInfo.key,\n attempt: stepInfo.attempt,\n };\n\n if (STEP_TIMEOUT_MARKER in errorToThrow) {\n // Update existing marker with current attempt's metadata\n (errorToThrow as Record<symbol, StepTimeoutMarkerMeta>)[STEP_TIMEOUT_MARKER] = meta;\n } else {\n // Define new marker (writable so it can be updated on retry)\n Object.defineProperty(errorToThrow, STEP_TIMEOUT_MARKER, {\n value: meta,\n enumerable: false,\n writable: true,\n configurable: false,\n });\n }\n }\n\n throw errorToThrow;\n }\n // Re-throw other errors\n throw error;\n } finally {\n // Always clear the timeout to prevent leaks\n clearTimeout(timeoutId!);\n }\n}\n\n/**\n * Default retry configuration values.\n * @internal\n */\nconst DEFAULT_RETRY_CONFIG = {\n backoff: \"exponential\" as BackoffStrategy,\n initialDelay: 100,\n maxDelay: 30000,\n jitter: true,\n retryOn: () => true,\n onRetry: () => {},\n} as const;\n\n// =============================================================================\n// run() Function\n// =============================================================================\n\n/**\n * Execute a workflow with step-based error handling.\n *\n * ## When to Use run()\n *\n * Use `run()` when:\n * - Dependencies are dynamic (passed at runtime, not known at compile time)\n * - You don't need step caching or resume state\n * - Error types are known upfront and can be specified manually\n * - Building lightweight, one-off workflows\n *\n * For automatic error type inference from static dependencies, use `createWorkflow()`.\n *\n * ## Modes\n *\n * `run()` has three modes based on options:\n * - **Strict Mode** (`catchUnexpected`): Returns `Result<T, E>` (closed union)\n * - **Typed Mode** (`onError`): Returns `Result<T, E | UnexpectedError>`\n * - **Safe Default** (no options): Returns `Result<T, UnexpectedError>`\n *\n * @example\n * ```typescript\n * // Typed mode with explicit error union\n * const result = await run<Output, 'NOT_FOUND' | 'FETCH_ERROR'>(\n * async (step) => {\n * const user = await step(fetchUser(userId));\n * return user;\n * },\n * { onError: (e) => console.log('Failed:', e) }\n * );\n * ```\n *\n * @see createWorkflow - For static dependencies with auto error inference\n */\n\n/**\n * Execute a workflow with \"Strict Mode\" error handling.\n *\n * In this mode, you MUST provide `catchUnexpected` to map unknown exceptions\n * to your typed error union `E`. This guarantees that the returned Result\n * will only ever contain errors of type `E`.\n *\n * @param fn - The workflow function containing steps\n * @param options - Configuration options, including `catchUnexpected`\n * @returns A Promise resolving to `Result<T, E>`\n *\n * @example\n * ```typescript\n * const result = await run(async (step) => {\n * // ... steps ...\n * }, {\n * catchUnexpected: (e) => ({ type: 'UNKNOWN_ERROR', cause: e })\n * });\n * ```\n */\nexport function run<T, E, C = void>(\n fn: (step: RunStep<E>) => Promise<T> | T,\n options: RunOptionsWithCatch<E, C>\n): AsyncResult<T, E, unknown>;\n\n/**\n * Execute a workflow with \"Typed Mode\" error handling.\n *\n * In this mode, you provide an `onError` callback. The returned Result\n * may contain your typed errors `E` OR `UnexpectedError` if an uncaught\n * exception occurs.\n *\n * @param fn - The workflow function containing steps\n * @param options - Configuration options, including `onError`\n * @returns A Promise resolving to `Result<T, E | UnexpectedError>`\n */\nexport function run<T, E, C = void>(\n fn: (step: RunStep<E | UnexpectedError>) => Promise<T> | T,\n options: {\n onError: (error: E | UnexpectedError, stepName?: string) => void;\n onEvent?: (event: WorkflowEvent<E | UnexpectedError>, ctx: C) => void;\n workflowId?: string;\n context?: C;\n }\n): AsyncResult<T, E | UnexpectedError, unknown>;\n\n/**\n * Execute a workflow with \"Safe Default\" error handling.\n *\n * In this mode, you don't need to specify any error types.\n * Any error (Result error or thrown exception) will be returned as\n * an `UnexpectedError`.\n *\n * @param fn - The workflow function containing steps\n * @param options - Optional configuration\n * @returns A Promise resolving to `Result<T, UnexpectedError>`\n *\n * @example\n * ```typescript\n * const result = await run(async (step) => {\n * return await step(someOp());\n * });\n * ```\n */\nexport function run<T, C = void>(\n fn: (step: RunStep) => Promise<T> | T,\n options?: {\n onEvent?: (event: WorkflowEvent<UnexpectedError>, ctx: C) => void;\n workflowId?: string;\n context?: C;\n }\n): AsyncResult<T, UnexpectedError, unknown>;\n\n// Implementation\nexport async function run<T, E, C = void>(\n fn: (step: RunStep<E | UnexpectedError>) => Promise<T> | T,\n options?: RunOptions<E, C>\n): AsyncResult<T, E | UnexpectedError> {\n const {\n onError,\n onEvent,\n catchUnexpected,\n workflowId: providedWorkflowId,\n context,\n } = options && typeof options === \"object\"\n ? (options as RunOptions<E, C>)\n : ({} as RunOptions<E, C>);\n\n const workflowId = providedWorkflowId ?? crypto.randomUUID();\n const wrapMode = !onError && !catchUnexpected;\n\n // Track active scopes as a stack for proper nesting\n // When a step succeeds, only the innermost race scope gets the winner\n const activeScopeStack: Array<{ scopeId: string; type: \"race\" | \"parallel\" | \"allSettled\"; winnerId?: string }> = [];\n\n // Counter for generating unique step IDs\n let stepIdCounter = 0;\n\n // Generate a unique step ID\n // Uses stepKey when provided (for cache stability), otherwise generates a unique ID.\n // Note: name is NOT used for stepId because multiple concurrent steps may share a name,\n // which would cause them to collide in activeSteps tracking and race winner detection.\n const generateStepId = (stepKey?: string): string => {\n return stepKey ?? `step_${++stepIdCounter}`;\n };\n\n const emitEvent = (event: WorkflowEvent<E | UnexpectedError>) => {\n // Track first successful step in the innermost race scope for winnerId\n if (event.type === \"step_success\") {\n // Use the stepId from the event (already generated at step start)\n const stepId = event.stepId;\n\n // Find innermost race scope (search from end of stack)\n for (let i = activeScopeStack.length - 1; i >= 0; i--) {\n const scope = activeScopeStack[i];\n if (scope.type === \"race\" && !scope.winnerId) {\n scope.winnerId = stepId;\n break; // Only update innermost race scope\n }\n }\n }\n onEvent?.(event, context as C);\n };\n\n // Use the exported early exit function with proper type parameter\n const earlyExit = createEarlyExit<E>;\n\n // Local type guard that narrows to EarlyExit<E> specifically\n const isEarlyExitE = (e: unknown): e is EarlyExit<E> => isEarlyExit(e);\n\n const wrapForStep = (\n error: unknown,\n meta?: StepFailureMeta\n ): E | UnexpectedError => {\n if (!wrapMode) {\n return error as E;\n }\n\n if (meta?.origin === \"result\") {\n return {\n type: \"UNEXPECTED_ERROR\",\n cause: {\n type: \"STEP_FAILURE\",\n origin: \"result\",\n error,\n ...(meta.resultCause !== undefined\n ? { cause: meta.resultCause }\n : {}),\n },\n };\n }\n\n if (meta?.origin === \"throw\") {\n return {\n type: \"UNEXPECTED_ERROR\",\n cause: {\n type: \"STEP_FAILURE\",\n origin: \"throw\",\n error,\n thrown: meta.thrown,\n },\n };\n }\n\n return {\n type: \"UNEXPECTED_ERROR\",\n cause: {\n type: \"STEP_FAILURE\",\n origin: \"result\",\n error,\n },\n };\n };\n\n const causeFromMeta = (meta: StepFailureMeta): unknown => {\n if (meta.origin === \"result\") {\n return meta.resultCause;\n }\n return meta.thrown;\n };\n\n const unexpectedFromFailure = (failure: EarlyExit<E>): UnexpectedError => ({\n type: \"UNEXPECTED_ERROR\",\n cause:\n failure.meta.origin === \"result\"\n ? {\n type: \"STEP_FAILURE\" as const,\n origin: \"result\" as const,\n error: failure.error,\n ...(failure.meta.resultCause !== undefined\n ? { cause: failure.meta.resultCause }\n : {}),\n }\n : {\n type: \"STEP_FAILURE\" as const,\n origin: \"throw\" as const,\n error: failure.error,\n thrown: failure.meta.thrown,\n },\n });\n\n try {\n const stepFn = <T, StepE, StepC = unknown>(\n operationOrResult:\n | (() => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>)\n | Result<T, StepE, StepC>\n | AsyncResult<T, StepE, StepC>,\n stepOptions?: StepOptions | string\n ): Promise<T> => {\n return (async () => {\n const parsedOptions = parseStepOptions(stepOptions);\n const { name: stepName, key: stepKey, retry: retryConfig, timeout: timeoutConfig } = parsedOptions;\n const stepId = generateStepId(stepKey);\n const hasEventListeners = onEvent;\n const overallStartTime = hasEventListeners ? performance.now() : 0;\n\n // Validate that retry/timeout are only used with function operations\n // Direct Promise/Result values cannot be re-executed or wrapped with timeout\n const isFunction = typeof operationOrResult === \"function\";\n if (!isFunction) {\n if (retryConfig && retryConfig.attempts > 1) {\n throw new Error(\n `step: retry options require a function operation. ` +\n `Direct Promise/Result values cannot be re-executed on retry. ` +\n `Wrap your operation in a function: step(() => yourOperation, { retry: {...} })`\n );\n }\n if (timeoutConfig) {\n throw new Error(\n `step: timeout options require a function operation. ` +\n `Direct Promise/Result values cannot be wrapped with timeout after they've started. ` +\n `Wrap your operation in a function: step(() => yourOperation, { timeout: {...} })`\n );\n }\n }\n\n // Build effective retry config with defaults\n // Ensure at least 1 attempt (0 would skip the loop entirely and crash)\n const maxAttempts = Math.max(1, retryConfig?.attempts ?? 1);\n const effectiveRetry = {\n attempts: maxAttempts,\n backoff: retryConfig?.backoff ?? DEFAULT_RETRY_CONFIG.backoff,\n initialDelay: retryConfig?.initialDelay ?? DEFAULT_RETRY_CONFIG.initialDelay,\n maxDelay: retryConfig?.maxDelay ?? DEFAULT_RETRY_CONFIG.maxDelay,\n jitter: retryConfig?.jitter ?? DEFAULT_RETRY_CONFIG.jitter,\n retryOn: retryConfig?.retryOn ?? DEFAULT_RETRY_CONFIG.retryOn,\n onRetry: retryConfig?.onRetry ?? DEFAULT_RETRY_CONFIG.onRetry,\n };\n\n // Emit step_start only once (before first attempt)\n if (onEvent) {\n emitEvent({\n type: \"step_start\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n });\n }\n\n let lastResult: Result<T, StepE, StepC> | undefined;\n\n for (let attempt = 1; attempt <= effectiveRetry.attempts; attempt++) {\n const attemptStartTime = hasEventListeners ? performance.now() : 0;\n\n try {\n // Execute operation with optional timeout\n let result: Result<T, StepE, StepC>;\n\n if (typeof operationOrResult === \"function\") {\n if (timeoutConfig) {\n // Wrap with timeout\n result = await executeWithTimeout(\n operationOrResult as () => Promise<Result<T, StepE, StepC>>,\n timeoutConfig,\n { name: stepName, key: stepKey, attempt }\n );\n } else {\n result = await operationOrResult();\n }\n } else {\n // Direct value - timeout doesn't apply\n result = await operationOrResult;\n }\n\n // Success case\n if (result.ok) {\n const durationMs = performance.now() - overallStartTime;\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result,\n });\n }\n return result.value;\n }\n\n // Result error case - check if we should retry\n lastResult = result;\n\n if (attempt < effectiveRetry.attempts && effectiveRetry.retryOn(result.error, attempt)) {\n const delay = calculateRetryDelay(attempt, effectiveRetry);\n\n // Emit retry event\n emitEvent({\n type: \"step_retry\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n attempt: attempt + 1,\n maxAttempts: effectiveRetry.attempts,\n delayMs: delay,\n error: result.error as unknown as E,\n });\n\n effectiveRetry.onRetry(result.error, attempt, delay);\n await sleep(delay);\n continue;\n }\n\n // No more retries or retryOn returned false - emit exhausted event if we retried\n if (effectiveRetry.attempts > 1) {\n emitEvent({\n type: \"step_retries_exhausted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: performance.now() - overallStartTime,\n attempts: attempt,\n lastError: result.error as unknown as E,\n });\n }\n\n // Fall through to final error handling below\n break;\n\n } catch (thrown) {\n const durationMs = performance.now() - attemptStartTime;\n\n // Handle early exit - propagate immediately\n if (isEarlyExitE(thrown)) {\n emitEvent({\n type: \"step_aborted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n throw thrown;\n }\n\n // Handle timeout error\n if (isStepTimeoutError(thrown)) {\n // Get timeout metadata from the error (works for both standard and custom errors)\n const timeoutMeta = getStepTimeoutMeta(thrown);\n const timeoutMs = timeoutConfig?.ms ?? timeoutMeta?.timeoutMs ?? 0;\n emitEvent({\n type: \"step_timeout\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n timeoutMs,\n attempt,\n });\n\n // Check if we should retry after timeout\n if (attempt < effectiveRetry.attempts && effectiveRetry.retryOn(thrown, attempt)) {\n const delay = calculateRetryDelay(attempt, effectiveRetry);\n\n emitEvent({\n type: \"step_retry\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n attempt: attempt + 1,\n maxAttempts: effectiveRetry.attempts,\n delayMs: delay,\n error: thrown as unknown as E,\n });\n\n effectiveRetry.onRetry(thrown, attempt, delay);\n await sleep(delay);\n continue;\n }\n\n // No more retries - emit exhausted if we retried\n if (effectiveRetry.attempts > 1) {\n emitEvent({\n type: \"step_retries_exhausted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: performance.now() - overallStartTime,\n attempts: attempt,\n lastError: thrown as unknown as E,\n });\n }\n\n // Treat timeout as a thrown error for error handling\n }\n\n // Handle other thrown errors (continue to error handling below)\n\n // Check if we should retry thrown errors\n if (attempt < effectiveRetry.attempts && effectiveRetry.retryOn(thrown, attempt)) {\n const delay = calculateRetryDelay(attempt, effectiveRetry);\n\n emitEvent({\n type: \"step_retry\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n attempt: attempt + 1,\n maxAttempts: effectiveRetry.attempts,\n delayMs: delay,\n error: thrown as unknown as E,\n });\n\n effectiveRetry.onRetry(thrown, attempt, delay);\n await sleep(delay);\n continue;\n }\n\n // No more retries for thrown errors - emit exhausted if we retried\n if (effectiveRetry.attempts > 1 && !isStepTimeoutError(thrown)) {\n emitEvent({\n type: \"step_retries_exhausted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: performance.now() - overallStartTime,\n attempts: attempt,\n lastError: thrown as unknown as E,\n });\n }\n\n // Handle the error based on mode\n const totalDurationMs = performance.now() - overallStartTime;\n\n if (catchUnexpected) {\n let mappedError: E;\n try {\n mappedError = catchUnexpected(thrown) as unknown as E;\n } catch (mapperError) {\n throw createMapperException(mapperError);\n }\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: totalDurationMs,\n error: mappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: totalDurationMs,\n result: err(mappedError, { cause: thrown }),\n meta: { origin: \"throw\", thrown },\n });\n }\n onError?.(mappedError as E, stepName);\n throw earlyExit(mappedError as E, { origin: \"throw\", thrown });\n } else {\n const unexpectedError: UnexpectedError = {\n type: \"UNEXPECTED_ERROR\",\n cause: { type: \"UNCAUGHT_EXCEPTION\", thrown },\n };\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: totalDurationMs,\n error: unexpectedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: totalDurationMs,\n result: err(unexpectedError, { cause: thrown }),\n meta: { origin: \"throw\", thrown },\n });\n }\n throw thrown;\n }\n }\n }\n\n // All retries exhausted with Result error - handle final error\n // At this point lastResult must be an error result (we only reach here on error)\n const errorResult = lastResult as { ok: false; error: StepE; cause?: StepC };\n const totalDurationMs = performance.now() - overallStartTime;\n const wrappedError = wrapForStep(errorResult.error, {\n origin: \"result\",\n resultCause: errorResult.cause,\n });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: totalDurationMs,\n error: wrappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: totalDurationMs,\n result: errorResult,\n meta: { origin: \"result\", resultCause: errorResult.cause },\n });\n }\n onError?.(errorResult.error as unknown as E, stepName);\n throw earlyExit(errorResult.error as unknown as E, {\n origin: \"result\",\n resultCause: errorResult.cause,\n });\n })();\n };\n\n stepFn.try = <T, Err>(\n operation: () => T | Promise<T>,\n opts:\n | { error: Err; name?: string; key?: string }\n | { onError: (cause: unknown) => Err; name?: string; key?: string }\n ): Promise<T> => {\n const stepName = opts.name;\n const stepKey = opts.key;\n const stepId = generateStepId(stepKey);\n const mapToError = \"error\" in opts ? () => opts.error : opts.onError;\n const hasEventListeners = onEvent;\n\n return (async () => {\n const startTime = hasEventListeners ? performance.now() : 0;\n\n if (onEvent) {\n emitEvent({\n type: \"step_start\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n });\n }\n\n try {\n const value = await operation();\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n // Emit step_complete for keyed steps (for state persistence)\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: ok(value),\n });\n }\n return value;\n } catch (error) {\n const mapped = mapToError(error);\n const durationMs = performance.now() - startTime;\n const wrappedError = wrapForStep(mapped, { origin: \"throw\", thrown: error });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: wrappedError,\n });\n // Emit step_complete for keyed steps (for state persistence)\n // Note: For step.try errors, we encode the mapped error, not the original thrown\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: err(mapped, { cause: error }),\n meta: { origin: \"throw\", thrown: error },\n });\n }\n onError?.(mapped as unknown as E, stepName);\n throw earlyExit(mapped as unknown as E, { origin: \"throw\", thrown: error });\n }\n })();\n };\n\n // step.fromResult: Execute a Result-returning function and map its typed error\n stepFn.fromResult = <T, ResultE, Err>(\n operation: () => Result<T, ResultE, unknown> | AsyncResult<T, ResultE, unknown>,\n opts:\n | { error: Err; name?: string; key?: string }\n | { onError: (resultError: ResultE) => Err; name?: string; key?: string }\n ): Promise<T> => {\n const stepName = opts.name;\n const stepKey = opts.key;\n const stepId = generateStepId(stepKey);\n const mapToError = \"error\" in opts ? () => opts.error : opts.onError;\n const hasEventListeners = onEvent;\n\n return (async () => {\n const startTime = hasEventListeners ? performance.now() : 0;\n\n if (onEvent) {\n emitEvent({\n type: \"step_start\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n });\n }\n\n const result = await operation();\n\n if (result.ok) {\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n // Emit step_complete for keyed steps (for state persistence)\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: ok(result.value),\n });\n }\n return result.value;\n } else {\n const mapped = mapToError(result.error);\n const durationMs = performance.now() - startTime;\n // For fromResult, the cause is the original result.error (what got mapped)\n // This is analogous to step.try using thrown exception as cause\n const wrappedError = wrapForStep(mapped, {\n origin: \"result\",\n resultCause: result.error,\n });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: wrappedError,\n });\n // Emit step_complete for keyed steps (for state persistence)\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: err(mapped, { cause: result.error }),\n meta: { origin: \"result\", resultCause: result.error },\n });\n }\n onError?.(mapped as unknown as E, stepName);\n throw earlyExit(mapped as unknown as E, {\n origin: \"result\",\n resultCause: result.error,\n });\n }\n })();\n };\n\n // step.retry: Execute an operation with retry and optional timeout\n stepFn.retry = <T, StepE, StepC = unknown>(\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n options: RetryOptions & { name?: string; key?: string; timeout?: TimeoutOptions }\n ): Promise<T> => {\n // Delegate to stepFn with retry options merged into StepOptions\n return stepFn(operation, {\n name: options.name,\n key: options.key,\n retry: {\n attempts: options.attempts,\n backoff: options.backoff,\n initialDelay: options.initialDelay,\n maxDelay: options.maxDelay,\n jitter: options.jitter,\n retryOn: options.retryOn,\n onRetry: options.onRetry,\n },\n timeout: options.timeout,\n });\n };\n\n // step.withTimeout: Execute an operation with a timeout\n stepFn.withTimeout = <T, StepE, StepC = unknown>(\n operation:\n | (() => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>)\n | ((signal: AbortSignal) => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>),\n options: TimeoutOptions & { name?: string; key?: string }\n ): Promise<T> => {\n // Delegate to stepFn with timeout options\n // The signal handling happens in executeWithTimeout when timeout.signal is true\n return stepFn(\n operation as () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n {\n name: options.name,\n key: options.key,\n timeout: options,\n }\n );\n };\n\n // step.parallel: Execute a parallel operation with scope events\n stepFn.parallel = <T, StepE, StepC>(\n name: string,\n operation: () => Result<T[], StepE, StepC> | AsyncResult<T[], StepE, StepC>\n ): Promise<T[]> => {\n const scopeId = `scope_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n return (async () => {\n const startTime = performance.now();\n let scopeEnded = false;\n\n // Push this scope onto the stack for proper nesting tracking\n activeScopeStack.push({ scopeId, type: \"parallel\" });\n\n // Helper to emit scope_end exactly once\n const emitScopeEnd = () => {\n if (scopeEnded) return;\n scopeEnded = true;\n // Pop this scope from the stack\n const idx = activeScopeStack.findIndex(s => s.scopeId === scopeId);\n if (idx !== -1) activeScopeStack.splice(idx, 1);\n emitEvent({\n type: \"scope_end\",\n workflowId,\n scopeId,\n ts: Date.now(),\n durationMs: performance.now() - startTime,\n });\n };\n\n // Emit scope_start event\n emitEvent({\n type: \"scope_start\",\n workflowId,\n scopeId,\n scopeType: \"parallel\",\n name,\n ts: Date.now(),\n });\n\n try {\n const result = await operation();\n\n // Emit scope_end before processing result\n emitScopeEnd();\n\n if (!result.ok) {\n onError?.(result.error as unknown as E, name);\n throw earlyExit(result.error as unknown as E, {\n origin: \"result\",\n resultCause: result.cause,\n });\n }\n\n return result.value;\n } catch (error) {\n // Always emit scope_end in finally-like fashion\n emitScopeEnd();\n throw error;\n }\n })();\n };\n\n // step.race: Execute a race operation with scope events\n stepFn.race = <T, StepE, StepC>(\n name: string,\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>\n ): Promise<T> => {\n const scopeId = `scope_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n return (async () => {\n const startTime = performance.now();\n let scopeEnded = false;\n\n // Push this race scope onto the stack to track the first successful step as winner\n const scopeEntry = { scopeId, type: \"race\" as const, winnerId: undefined as string | undefined };\n activeScopeStack.push(scopeEntry);\n\n // Helper to emit scope_end exactly once, including winnerId\n const emitScopeEnd = () => {\n if (scopeEnded) return;\n scopeEnded = true;\n // Pop this scope from the stack\n const idx = activeScopeStack.findIndex(s => s.scopeId === scopeId);\n if (idx !== -1) activeScopeStack.splice(idx, 1);\n emitEvent({\n type: \"scope_end\",\n workflowId,\n scopeId,\n ts: Date.now(),\n durationMs: performance.now() - startTime,\n winnerId: scopeEntry.winnerId,\n });\n };\n\n // Emit scope_start event\n emitEvent({\n type: \"scope_start\",\n workflowId,\n scopeId,\n scopeType: \"race\",\n name,\n ts: Date.now(),\n });\n\n try {\n const result = await operation();\n\n // Emit scope_end before processing result\n emitScopeEnd();\n\n if (!result.ok) {\n onError?.(result.error as unknown as E, name);\n throw earlyExit(result.error as unknown as E, {\n origin: \"result\",\n resultCause: result.cause,\n });\n }\n\n return result.value;\n } catch (error) {\n // Always emit scope_end in finally-like fashion\n emitScopeEnd();\n throw error;\n }\n })();\n };\n\n // step.allSettled: Execute an allSettled operation with scope events\n stepFn.allSettled = <T, StepE, StepC>(\n name: string,\n operation: () => Result<T[], StepE, StepC> | AsyncResult<T[], StepE, StepC>\n ): Promise<T[]> => {\n const scopeId = `scope_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n return (async () => {\n const startTime = performance.now();\n let scopeEnded = false;\n\n // Push this scope onto the stack for proper nesting tracking\n activeScopeStack.push({ scopeId, type: \"allSettled\" });\n\n // Helper to emit scope_end exactly once\n const emitScopeEnd = () => {\n if (scopeEnded) return;\n scopeEnded = true;\n // Pop this scope from the stack\n const idx = activeScopeStack.findIndex(s => s.scopeId === scopeId);\n if (idx !== -1) activeScopeStack.splice(idx, 1);\n emitEvent({\n type: \"scope_end\",\n workflowId,\n scopeId,\n ts: Date.now(),\n durationMs: performance.now() - startTime,\n });\n };\n\n // Emit scope_start event\n emitEvent({\n type: \"scope_start\",\n workflowId,\n scopeId,\n scopeType: \"allSettled\",\n name,\n ts: Date.now(),\n });\n\n try {\n const result = await operation();\n\n // Emit scope_end before processing result\n emitScopeEnd();\n\n if (!result.ok) {\n onError?.(result.error as unknown as E, name);\n throw earlyExit(result.error as unknown as E, {\n origin: \"result\",\n resultCause: result.cause,\n });\n }\n\n return result.value;\n } catch (error) {\n // Always emit scope_end in finally-like fashion\n emitScopeEnd();\n throw error;\n }\n })();\n };\n\n const step = stepFn as RunStep<E | UnexpectedError>;\n const value = await fn(step);\n return ok(value);\n } catch (error) {\n // If a catchUnexpected mapper threw, propagate without re-processing\n if (isMapperException(error)) {\n throw error.thrown;\n }\n\n if (isEarlyExitE(error)) {\n const failureCause = causeFromMeta(error.meta);\n if (catchUnexpected || onError) {\n return err(error.error, { cause: failureCause });\n }\n // If the error is already an UnexpectedError (e.g., from resumed state),\n // return it directly without wrapping in another STEP_FAILURE\n if (isUnexpectedError(error.error)) {\n return err(error.error, { cause: failureCause });\n }\n const unexpectedError = unexpectedFromFailure(error);\n return err(unexpectedError, { cause: failureCause });\n }\n\n if (catchUnexpected) {\n const mapped = catchUnexpected(error);\n onError?.(mapped, \"unexpected\");\n return err(mapped, { cause: error });\n }\n\n const unexpectedError: UnexpectedError = {\n type: \"UNEXPECTED_ERROR\",\n cause: { type: \"UNCAUGHT_EXCEPTION\", thrown: error },\n };\n onError?.(unexpectedError as unknown as E, \"unexpected\");\n return err(unexpectedError, { cause: error });\n }\n}\n\n/**\n * Executes a workflow in \"Strict Mode\" with a closed error union.\n *\n * ## When to Use\n *\n * Use `run.strict()` when:\n * - You want a closed error union (no `UnexpectedError`)\n * - You need exhaustive error handling in production\n * - You want to guarantee all errors are explicitly typed\n * - You're building APIs where error types must be known\n *\n * ## Why Use This\n *\n * - **Closed union**: Error type is exactly `E`, no `UnexpectedError`\n * - **Exhaustive**: Forces you to handle all possible errors\n * - **Type-safe**: TypeScript ensures all errors are typed\n * - **Production-ready**: Better for APIs and libraries\n *\n * ## Important\n *\n * You MUST provide `catchUnexpected` to map any uncaught exceptions to your error type `E`.\n * This ensures the error union is truly closed.\n *\n * @param fn - The workflow function containing steps\n * @param options - Configuration options, MUST include `catchUnexpected`\n * @returns A Promise resolving to `Result<T, E>` (no UnexpectedError)\n *\n * @example\n * ```typescript\n * type AppError = 'NOT_FOUND' | 'UNAUTHORIZED' | 'UNEXPECTED';\n *\n * const result = await run.strict<User, AppError>(\n * async (step) => {\n * return await step(fetchUser(id));\n * },\n * {\n * catchUnexpected: () => 'UNEXPECTED' as const\n * }\n * );\n * // result.error: 'NOT_FOUND' | 'UNAUTHORIZED' | 'UNEXPECTED' (exactly)\n * ```\n */\nrun.strict = <T, E, C = void>(\n fn: (step: RunStep<E>) => Promise<T> | T,\n options: {\n onError?: (error: E, stepName?: string) => void;\n onEvent?: (event: WorkflowEvent<E | UnexpectedError>, ctx: C) => void;\n catchUnexpected: (cause: unknown) => E;\n workflowId?: string;\n context?: C;\n }\n): AsyncResult<T, E, unknown> => {\n return run<T, E, C>(fn, options);\n};\n\n// =============================================================================\n// Unwrap Utilities\n// =============================================================================\n\n/**\n * Error thrown when `unwrap()` is called on an error Result.\n *\n * This error is thrown to prevent silent failures when using `unwrap()`.\n * Prefer using `unwrapOr`, `unwrapOrElse`, or pattern matching with `match` or `isOk`/`isErr`.\n */\nexport class UnwrapError<E = unknown, C = unknown> extends Error {\n constructor(\n public readonly error: E,\n public readonly cause?: C\n ) {\n super(`Unwrap called on an error result: ${String(error)}`);\n this.name = \"UnwrapError\";\n }\n}\n\n/**\n * Unwraps a Result, throwing an error if it's a failure.\n *\n * ## When to Use\n *\n * Use `unwrap()` when:\n * - You're certain the Result is successful (e.g., after checking with `isOk`)\n * - You're in a context where errors should crash (e.g., tests, initialization)\n * - You need the value immediately and can't handle errors gracefully\n *\n * ## Why Avoid This\n *\n * **Prefer alternatives** in production code:\n * - `unwrapOr(defaultValue)` - Provide a fallback value\n * - `unwrapOrElse(fn)` - Compute fallback from error\n * - `match()` - Handle both cases explicitly\n * - `isOk()` / `isErr()` - Type-safe pattern matching\n *\n * Throwing errors makes error handling harder and can crash your application.\n *\n * @param r - The Result to unwrap\n * @returns The success value if the Result is successful\n * @throws {UnwrapError} If the Result is an error (includes the error and cause)\n *\n * @example\n * ```typescript\n * // Safe usage after checking\n * const result = someOperation();\n * if (isOk(result)) {\n * const value = unwrap(result); // Safe - we know it's ok\n * }\n *\n * // Unsafe usage (not recommended)\n * const value = unwrap(someOperation()); // May throw!\n * ```\n */\nexport const unwrap = <T, E, C>(r: Result<T, E, C>): T => {\n if (r.ok) return r.value;\n throw new UnwrapError<E, C>(r.error, r.cause);\n};\n\n/**\n * Unwraps a Result, returning a default value if it's a failure.\n *\n * ## When to Use\n *\n * Use `unwrapOr()` when:\n * - You have a sensible default value for errors\n * - You want to continue execution even on failure\n * - The default value is cheap to compute (use `unwrapOrElse` if expensive)\n *\n * ## Why Use This\n *\n * - **Safe**: Never throws, always returns a value\n * - **Simple**: One-liner for common error handling\n * - **Type-safe**: TypeScript knows you'll always get a `T`\n *\n * @param r - The Result to unwrap\n * @param defaultValue - The value to return if the Result is an error\n * @returns The success value if successful, otherwise the default value\n *\n * @example\n * ```typescript\n * // Provide default for missing data\n * const user = unwrapOr(fetchUser(id), { id: 'anonymous', name: 'Guest' });\n *\n * // Provide default for numeric operations\n * const count = unwrapOr(parseCount(input), 0);\n *\n * // Provide default for optional features\n * const config = unwrapOr(loadConfig(), getDefaultConfig());\n * ```\n */\nexport const unwrapOr = <T, E, C>(r: Result<T, E, C>, defaultValue: T): T =>\n r.ok ? r.value : defaultValue;\n\n/**\n * Unwraps a Result, computing a default value from the error if it's a failure.\n *\n * ## When to Use\n *\n * Use `unwrapOrElse()` when:\n * - The default value is expensive to compute (lazy evaluation)\n * - You need to log or handle the error before providing a default\n * - The default depends on the error type or cause\n * - You want to transform the error into a success value\n *\n * ## Why Use This Instead of `unwrapOr`\n *\n * - **Lazy**: Default is only computed if needed (better performance)\n * - **Error-aware**: You can inspect the error before providing default\n * - **Flexible**: Default can depend on error type or cause\n *\n * @param r - The Result to unwrap\n * @param fn - Function that receives the error and optional cause, returns the default value\n * @returns The success value if successful, otherwise the result of calling `fn(error, cause)`\n *\n * @example\n * ```typescript\n * // Compute default based on error type\n * const port = unwrapOrElse(parsePort(env.PORT), (error) => {\n * if (error === 'INVALID_FORMAT') return 3000;\n * if (error === 'OUT_OF_RANGE') return 8080;\n * return 4000; // default\n * });\n *\n * // Log error before providing default\n * const data = unwrapOrElse(fetchData(), (error, cause) => {\n * console.error('Failed to fetch:', error, cause);\n * return getCachedData();\n * });\n *\n * // Transform error into success value\n * const result = unwrapOrElse(operation(), (error) => {\n * return { success: false, reason: String(error) };\n * });\n * ```\n */\nexport const unwrapOrElse = <T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => T\n): T => (r.ok ? r.value : fn(r.error, r.cause));\n\n// =============================================================================\n// Wrapping Functions\n// =============================================================================\n\n/**\n * Wraps a synchronous throwing function in a Result.\n *\n * ## When to Use\n *\n * Use `from()` when:\n * - You have a synchronous function that throws exceptions\n * - You want to convert exceptions to typed errors\n * - You're integrating with libraries that throw (e.g., JSON.parse, fs.readFileSync)\n * - You need to handle errors without try/catch blocks\n *\n * ## Why Use This\n *\n * - **Type-safe errors**: Convert thrown exceptions to typed Result errors\n * - **No try/catch**: Cleaner code without nested try/catch blocks\n * - **Composable**: Results can be chained with `andThen`, `map`, etc.\n * - **Explicit errors**: Forces you to handle errors explicitly\n *\n * @param fn - The synchronous function to execute (may throw)\n * @returns A Result with the function's return value or the thrown error\n *\n * @example\n * ```typescript\n * // Wrap JSON.parse\n * const parsed = from(() => JSON.parse('{\"key\": \"value\"}'));\n * // parsed: { ok: true, value: { key: \"value\" } }\n *\n * const error = from(() => JSON.parse('invalid'));\n * // error: { ok: false, error: SyntaxError }\n * ```\n */\nexport function from<T>(fn: () => T): Result<T, unknown>;\n/**\n * Wraps a synchronous throwing function in a Result with custom error mapping.\n *\n * Use this overload when you want to map thrown exceptions to your typed error union.\n *\n * @param fn - The synchronous function to execute (may throw)\n * @param onError - Function to map the thrown exception to a typed error\n * @returns A Result with the function's return value or the mapped error\n *\n * @example\n * ```typescript\n * // Map exceptions to typed errors\n * const parsed = from(\n * () => JSON.parse(input),\n * (cause) => ({ type: 'PARSE_ERROR' as const, cause })\n * );\n * // parsed.error: { type: 'PARSE_ERROR', cause: SyntaxError }\n *\n * // Map to simple error codes\n * const value = from(\n * () => riskyOperation(),\n * () => 'OPERATION_FAILED' as const\n * );\n * ```\n */\nexport function from<T, E>(fn: () => T, onError: (cause: unknown) => E): Result<T, E>;\nexport function from<T, E>(fn: () => T, onError?: (cause: unknown) => E) {\n try {\n return ok(fn());\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Wraps a Promise in a Result, converting rejections to errors.\n *\n * ## When to Use\n *\n * Use `fromPromise()` when:\n * - You have an existing Promise that might reject\n * - You want to convert Promise rejections to typed errors\n * - You're working with libraries that return Promises (fetch, database clients)\n * - You need to handle rejections without .catch() chains\n *\n * ## Why Use This\n *\n * - **Type-safe errors**: Convert Promise rejections to typed Result errors\n * - **Composable**: Results can be chained with `andThen`, `map`, etc.\n * - **Explicit handling**: Forces you to handle errors explicitly\n * - **No .catch() chains**: Cleaner than Promise.catch() patterns\n *\n * @param promise - The Promise to await (may reject)\n * @returns A Promise resolving to a Result with the resolved value or rejection reason\n *\n * @example\n * ```typescript\n * // Wrap fetch\n * const result = await fromPromise(\n * fetch('/api').then(r => r.json())\n * );\n * // result.ok: true if fetch succeeded, false if rejected\n * ```\n */\nexport function fromPromise<T>(promise: Promise<T>): AsyncResult<T, unknown>;\n/**\n * Wraps a Promise in a Result with custom error mapping.\n *\n * Use this overload when you want to map Promise rejections to your typed error union.\n *\n * @param promise - The Promise to await (may reject)\n * @param onError - Function to map the rejection reason to a typed error\n * @returns A Promise resolving to a Result with the resolved value or mapped error\n *\n * @example\n * ```typescript\n * // Map fetch errors to typed errors\n * const result = await fromPromise(\n * fetch('/api').then(r => {\n * if (!r.ok) throw new Error(`HTTP ${r.status}`);\n * return r.json();\n * }),\n * () => 'FETCH_FAILED' as const\n * );\n * // result.error: 'FETCH_FAILED' if fetch failed\n *\n * // Map with error details\n * const data = await fromPromise(\n * db.query(sql),\n * (cause) => ({ type: 'DB_ERROR' as const, message: String(cause) })\n * );\n * ```\n */\nexport function fromPromise<T, E>(\n promise: Promise<T>,\n onError: (cause: unknown) => E\n): AsyncResult<T, E>;\nexport async function fromPromise<T, E>(\n promise: Promise<T>,\n onError?: (cause: unknown) => E\n): AsyncResult<T, E | unknown> {\n try {\n return ok(await promise);\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Wraps an async function in a Result, catching both thrown exceptions and Promise rejections.\n *\n * ## When to Use\n *\n * Use `tryAsync()` when:\n * - You have an async function that might throw or reject\n * - You want to convert both exceptions and rejections to typed errors\n * - You're creating new async functions (use `fromPromise` for existing Promises)\n * - You need to handle errors without try/catch or .catch()\n *\n * ## Why Use This Instead of `fromPromise`\n *\n * - **Function form**: Takes a function, not a Promise (lazy evaluation)\n * - **Catches both**: Handles both thrown exceptions and Promise rejections\n * - **Cleaner syntax**: No need to wrap in Promise manually\n *\n * @param fn - The async function to execute (may throw or reject)\n * @returns A Promise resolving to a Result with the function's return value or error\n *\n * @example\n * ```typescript\n * // Wrap async function\n * const result = await tryAsync(async () => {\n * const data = await fetchData();\n * return processData(data);\n * });\n * ```\n */\nexport function tryAsync<T>(fn: () => Promise<T>): AsyncResult<T, unknown>;\n/**\n * Wraps an async function in a Result with custom error mapping.\n *\n * Use this overload when you want to map errors to your typed error union.\n *\n * @param fn - The async function to execute (may throw or reject)\n * @param onError - Function to map the error (exception or rejection) to a typed error\n * @returns A Promise resolving to a Result with the function's return value or mapped error\n *\n * @example\n * ```typescript\n * // Map errors to typed errors\n * const result = await tryAsync(\n * async () => await fetchData(),\n * () => 'FETCH_ERROR' as const\n * );\n *\n * // Map with error details\n * const data = await tryAsync(\n * async () => await processFile(path),\n * (cause) => ({ type: 'PROCESSING_ERROR' as const, cause })\n * );\n * ```\n */\nexport function tryAsync<T, E>(\n fn: () => Promise<T>,\n onError: (cause: unknown) => E\n): AsyncResult<T, E>;\nexport async function tryAsync<T, E>(\n fn: () => Promise<T>,\n onError?: (cause: unknown) => E\n): AsyncResult<T, E | unknown> {\n try {\n return ok(await fn());\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Converts a nullable value to a Result.\n *\n * ## When to Use\n *\n * Use `fromNullable()` when:\n * - You have a value that might be `null` or `undefined`\n * - You want to treat null/undefined as an error case\n * - You're working with APIs that return nullable values (DOM APIs, optional properties)\n * - You want to avoid null checks scattered throughout your code\n *\n * ## Why Use This\n *\n * - **Type-safe**: Converts nullable types to non-nullable Results\n * - **Explicit errors**: Forces you to handle null/undefined cases\n * - **Composable**: Results can be chained with `andThen`, `map`, etc.\n * - **No null checks**: Eliminates need for `if (value == null)` checks\n *\n * @param value - The value that may be null or undefined\n * @param onNull - Function that returns an error when value is null/undefined\n * @returns A Result with the value if not null/undefined, otherwise the error from `onNull`\n *\n * @example\n * ```typescript\n * // Convert DOM element lookup\n * const element = fromNullable(\n * document.getElementById('app'),\n * () => 'ELEMENT_NOT_FOUND' as const\n * );\n *\n * // Convert optional property\n * const userId = fromNullable(\n * user.id,\n * () => 'USER_ID_MISSING' as const\n * );\n *\n * // Convert database query result\n * const record = fromNullable(\n * await db.find(id),\n * () => ({ type: 'NOT_FOUND' as const, id })\n * );\n * ```\n */\nexport function fromNullable<T, E>(\n value: T | null | undefined,\n onNull: () => E\n): Result<T, E> {\n return value != null ? ok(value) : err(onNull());\n}\n\n// =============================================================================\n// Transformers\n// =============================================================================\n\n/**\n * Transforms the success value of a Result.\n *\n * ## When to Use\n *\n * Use `map()` when:\n * - You need to transform a success value to another type\n * - You want to apply a pure function to the value\n * - You're building a pipeline of transformations\n * - The transformation cannot fail (use `andThen` if it can fail)\n *\n * ## Why Use This\n *\n * - **Functional style**: Composable, chainable transformations\n * - **Error-preserving**: Errors pass through unchanged\n * - **Type-safe**: TypeScript tracks the transformation\n * - **No unwrapping**: Avoids manual `if (r.ok)` checks\n *\n * @param r - The Result to transform\n * @param fn - Pure function that transforms the success value (must not throw)\n * @returns A new Result with the transformed value, or the original error if `r` was an error\n *\n * @example\n * ```typescript\n * // Transform numeric value\n * const doubled = map(ok(21), n => n * 2);\n * // doubled: { ok: true, value: 42 }\n *\n * // Transform object property\n * const name = map(fetchUser(id), user => user.name);\n *\n * // Chain transformations\n * const formatted = map(\n * map(parseNumber(input), n => n * 2),\n * n => `Result: ${n}`\n * );\n * ```\n */\nexport function map<T, U, E, C>(\n r: Result<T, E, C>,\n fn: (value: T) => U\n): Result<U, E, C> {\n return r.ok ? ok(fn(r.value)) : r;\n}\n\n/**\n * Transforms the error value of a Result.\n *\n * ## When to Use\n *\n * Use `mapError()` when:\n * - You need to normalize or transform error types\n * - You want to convert errors to a different error type\n * - You're building error handling pipelines\n * - You need to format error messages or codes\n *\n * ## Why Use This\n *\n * - **Error normalization**: Convert errors to a common format\n * - **Type transformation**: Change error type while preserving value type\n * - **Composable**: Can be chained with other transformers\n * - **Success-preserving**: Success values pass through unchanged\n *\n * @param r - The Result to transform\n * @param fn - Function that transforms the error value (must not throw)\n * @returns A new Result with the original value, or the transformed error if `r` was an error\n *\n * @example\n * ```typescript\n * // Normalize error codes\n * const normalized = mapError(err('not_found'), e => e.toUpperCase());\n * // normalized: { ok: false, error: 'NOT_FOUND' }\n *\n * // Convert error types\n * const typed = mapError(\n * err('404'),\n * code => ({ type: 'HTTP_ERROR' as const, status: parseInt(code) })\n * );\n *\n * // Format error messages\n * const formatted = mapError(\n * err('PARSE_ERROR'),\n * code => `Failed to parse: ${code}`\n * );\n * ```\n */\nexport function mapError<T, E, F, C>(\n r: Result<T, E, C>,\n fn: (error: E) => F\n): Result<T, F, C> {\n return r.ok ? r : err(fn(r.error), { cause: r.cause });\n}\n\n/**\n * Pattern matches on a Result, calling the appropriate handler.\n *\n * ## When to Use\n *\n * Use `match()` when:\n * - You need to handle both success and error cases\n * - You want to transform a Result to a different type\n * - You need exhaustive handling (both cases must be handled)\n * - You're building user-facing messages or responses\n *\n * ## Why Use This\n *\n * - **Exhaustive**: Forces you to handle both success and error cases\n * - **Type-safe**: TypeScript ensures both handlers are provided\n * - **Functional**: Pattern matching style, similar to Rust's `match` or Haskell's `case`\n * - **Single expression**: Can be used in expressions, not just statements\n *\n * @param r - The Result to match\n * @param handlers - Object with `ok` and `err` handler functions\n * @param handlers.ok - Function called with the success value\n * @param handlers.err - Function called with the error and optional cause\n * @returns The return value of the appropriate handler (both must return the same type `R`)\n *\n * @example\n * ```typescript\n * // Build user-facing messages\n * const message = match(result, {\n * ok: (user) => `Hello ${user.name}`,\n * err: (error) => `Error: ${error}`,\n * });\n *\n * // Transform to API response\n * const response = match(operation(), {\n * ok: (data) => ({ status: 200, body: data }),\n * err: (error) => ({ status: 400, error: String(error) }),\n * });\n *\n * // Handle with cause\n * const response = match(result, {\n * ok: (value) => ({ status: 'success', data: value }),\n * err: (error, cause) => ({ status: 'error', error, cause }),\n * });\n * ```\n */\nexport function match<T, E, C, R>(\n r: Result<T, E, C>,\n handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }\n): R {\n return r.ok ? handlers.ok(r.value) : handlers.err(r.error, r.cause);\n}\n\n/**\n * Chains Results together (flatMap/monadic bind).\n *\n * ## When to Use\n *\n * Use `andThen()` when:\n * - You need to chain operations that can fail\n * - The next operation depends on the previous success value\n * - You're building a pipeline of dependent operations\n * - You want to avoid nested `if (r.ok)` checks\n *\n * ## Why Use This Instead of `map`\n *\n * - **Can fail**: The chained function returns a Result (can fail)\n * - **Short-circuits**: If first Result fails, second operation never runs\n * - **Error accumulation**: Errors from both operations are in the union\n * - **Composable**: Can chain multiple operations together\n *\n * ## Common Pattern\n *\n * This is the fundamental building block for Result pipelines:\n * ```typescript\n * andThen(operation1(), value1 =>\n * andThen(operation2(value1), value2 =>\n * ok({ value1, value2 })\n * )\n * )\n * ```\n *\n * @param r - The first Result\n * @param fn - Function that takes the success value and returns a new Result (may fail)\n * @returns The Result from `fn` if `r` was successful, otherwise the original error\n *\n * @example\n * ```typescript\n * // Chain dependent operations\n * const userPosts = andThen(\n * fetchUser('1'),\n * user => fetchPosts(user.id)\n * );\n *\n * // Build complex pipelines\n * const result = andThen(parseInput(input), parsed =>\n * andThen(validate(parsed), validated =>\n * process(validated)\n * )\n * );\n *\n * // Chain with different error types\n * const data = andThen(\n * fetchUser(id), // Returns Result<User, 'FETCH_ERROR'>\n * user => fetchPosts(user.id) // Returns Result<Post[], 'NOT_FOUND'>\n * );\n * // data.error: 'FETCH_ERROR' | 'NOT_FOUND'\n * ```\n */\nexport function andThen<T, U, E, F, C1, C2>(\n r: Result<T, E, C1>,\n fn: (value: T) => Result<U, F, C2>\n): Result<U, E | F, C1 | C2> {\n return r.ok ? fn(r.value) : r;\n}\n\n/**\n * Executes a side effect on a successful Result without changing it.\n *\n * ## When to Use\n *\n * Use `tap()` when:\n * - You need to log, debug, or observe success values\n * - You want to perform side effects in a pipeline\n * - You need to mutate external state based on success\n * - You're debugging and want to inspect values without breaking the chain\n *\n * ## Why Use This\n *\n * - **Non-breaking**: Doesn't change the Result, just performs side effect\n * - **Composable**: Can be inserted anywhere in a pipeline\n * - **Type-preserving**: Returns the same Result type\n * - **Lazy**: Side effect only runs if Result is successful\n *\n * @param r - The Result to tap\n * @param fn - Side effect function called with the success value (return value ignored)\n * @returns The original Result unchanged (for chaining)\n *\n * @example\n * ```typescript\n * // Log success values\n * const logged = tap(result, user => console.log('Got user:', user.name));\n * // logged === result, but console.log was called\n *\n * // Debug in pipeline\n * const debugged = pipe(\n * fetchUser(id),\n * r => tap(r, user => console.log('Fetched:', user)),\n * r => map(r, user => user.name)\n * );\n *\n * // Mutate external state\n * const tracked = tap(result, data => {\n * analytics.track('operation_success', data);\n * });\n * ```\n */\nexport function tap<T, E, C>(\n r: Result<T, E, C>,\n fn: (value: T) => void\n): Result<T, E, C> {\n if (r.ok) fn(r.value);\n return r;\n}\n\n/**\n * Executes a side effect on an error Result without changing it.\n *\n * ## When to Use\n *\n * Use `tapError()` when:\n * - You need to log, debug, or observe error values\n * - You want to perform side effects on errors in a pipeline\n * - You need to report errors to external systems (logging, monitoring)\n * - You're debugging and want to inspect errors without breaking the chain\n *\n * ## Why Use This\n *\n * - **Non-breaking**: Doesn't change the Result, just performs side effect\n * - **Composable**: Can be inserted anywhere in a pipeline\n * - **Type-preserving**: Returns the same Result type\n * - **Lazy**: Side effect only runs if Result is an error\n *\n * @param r - The Result to tap\n * @param fn - Side effect function called with the error and optional cause (return value ignored)\n * @returns The original Result unchanged (for chaining)\n *\n * @example\n * ```typescript\n * // Log errors\n * const logged = tapError(result, (error, cause) => {\n * console.error('Error:', error, cause);\n * });\n *\n * // Report to error tracking\n * const tracked = tapError(result, (error, cause) => {\n * errorTracker.report(error, cause);\n * });\n *\n * // Debug in pipeline\n * const debugged = pipe(\n * operation(),\n * r => tapError(r, (err, cause) => console.error('Failed:', err)),\n * r => mapError(r, err => 'FORMATTED_ERROR')\n * );\n * ```\n */\nexport function tapError<T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => void\n): Result<T, E, C> {\n if (!r.ok) fn(r.error, r.cause);\n return r;\n}\n\n/**\n * Transforms the success value of a Result, catching any errors thrown by the transform.\n *\n * ## When to Use\n *\n * Use `mapTry()` when:\n * - Your transform function might throw exceptions\n * - You want to convert transform errors to typed errors\n * - You're working with libraries that throw (e.g., JSON.parse, Date parsing)\n * - You need to handle both Result errors and transform exceptions\n *\n * ## Why Use This Instead of `map`\n *\n * - **Exception-safe**: Catches exceptions from the transform function\n * - **Error mapping**: Converts thrown exceptions to typed errors\n * - **Dual error handling**: Handles both Result errors and transform exceptions\n *\n * @param result - The Result to transform\n * @param transform - Function to transform the success value (may throw exceptions)\n * @param onError - Function to map thrown exceptions to a typed error\n * @returns A Result with:\n * - Transformed value if both Result and transform succeed\n * - Original error if Result was an error\n * - Transform error if transform threw an exception\n *\n * @example\n * ```typescript\n * // Safe JSON parsing\n * const parsed = mapTry(\n * ok('{\"key\": \"value\"}'),\n * JSON.parse,\n * () => 'PARSE_ERROR' as const\n * );\n *\n * // Safe date parsing\n * const date = mapTry(\n * ok('2024-01-01'),\n * str => new Date(str),\n * () => 'INVALID_DATE' as const\n * );\n *\n * // Transform with error details\n * const processed = mapTry(\n * result,\n * value => riskyTransform(value),\n * (cause) => ({ type: 'TRANSFORM_ERROR' as const, cause })\n * );\n * ```\n */\nexport function mapTry<T, U, E, F, C>(\n result: Result<T, E, C>,\n transform: (value: T) => U,\n onError: (cause: unknown) => F\n): Result<U, E | F, C | unknown> {\n if (!result.ok) return result;\n try {\n return ok(transform(result.value));\n } catch (error) {\n return err(onError(error), { cause: error });\n }\n}\n\n/**\n * Transforms the error value of a Result, catching any errors thrown by the transform.\n *\n * ## When to Use\n *\n * Use `mapErrorTry()` when:\n * - Your error transform function might throw exceptions\n * - You're doing complex error transformations (e.g., string formatting, object construction)\n * - You want to handle both Result errors and transform exceptions\n * - You need to safely normalize error types\n *\n * ## Why Use This Instead of `mapError`\n *\n * - **Exception-safe**: Catches exceptions from the error transform function\n * - **Error mapping**: Converts thrown exceptions to typed errors\n * - **Dual error handling**: Handles both Result errors and transform exceptions\n *\n * @param result - The Result to transform\n * @param transform - Function to transform the error value (may throw exceptions)\n * @param onError - Function to map thrown exceptions to a typed error\n * @returns A Result with:\n * - Original value if Result was successful\n * - Transformed error if both Result was error and transform succeeded\n * - Transform error if transform threw an exception\n *\n * @example\n * ```typescript\n * // Safe error formatting\n * const formatted = mapErrorTry(\n * err('not_found'),\n * e => e.toUpperCase(), // Might throw if e is not a string\n * () => 'FORMAT_ERROR' as const\n * );\n *\n * // Complex error transformation\n * const normalized = mapErrorTry(\n * result,\n * error => ({ type: 'NORMALIZED', message: String(error) }),\n * () => 'TRANSFORM_ERROR' as const\n * );\n * ```\n */\nexport function mapErrorTry<T, E, F, G, C>(\n result: Result<T, E, C>,\n transform: (error: E) => F,\n onError: (cause: unknown) => G\n): Result<T, F | G, C | unknown> {\n if (result.ok) return result;\n try {\n return err(transform(result.error), { cause: result.cause });\n } catch (error) {\n return err(onError(error), { cause: error });\n }\n}\n\n// =============================================================================\n// Batch Operations\n// =============================================================================\n\ntype AllValues<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> ? V : never;\n};\ntype AllErrors<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> ? E : never;\n}[number];\ntype AllCauses<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> ? C : never;\n}[number];\n\n/**\n * Combines multiple Results into one, requiring all to succeed.\n *\n * ## When to Use\n *\n * Use `all()` when:\n * - You have multiple independent operations that all must succeed\n * - You want to short-circuit on the first error (fail-fast)\n * - You need all values together (e.g., combining API responses)\n * - Performance matters (stops on first error, doesn't wait for all)\n *\n * ## Why Use This\n *\n * - **Fail-fast**: Stops immediately on first error (better performance)\n * - **Type-safe**: TypeScript infers the array type from input\n * - **Short-circuit**: Doesn't evaluate remaining Results after error\n * - **Composable**: Can be chained with other operations\n *\n * ## Important\n *\n * - **Short-circuits**: Returns first error immediately, doesn't wait for all Results\n * - **All must succeed**: If any Result fails, the entire operation fails\n * - **Use `allSettled`**: If you need to collect all errors (e.g., form validation)\n *\n * @param results - Array of Results to combine (all must succeed)\n * @returns A Result with an array of all success values, or the first error encountered\n *\n * @example\n * ```typescript\n * // Combine multiple successful Results\n * const combined = all([ok(1), ok(2), ok(3)]);\n * // combined: { ok: true, value: [1, 2, 3] }\n *\n * // Short-circuits on first error\n * const error = all([ok(1), err('ERROR'), ok(3)]);\n * // error: { ok: false, error: 'ERROR' }\n * // Note: ok(3) is never evaluated\n *\n * // Combine API responses\n * const data = all([\n * fetchUser(id),\n * fetchPosts(id),\n * fetchComments(id)\n * ]);\n * // data.value: [user, posts, comments] if all succeed\n * ```\n */\nexport function all<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): Result<AllValues<T>, AllErrors<T>, AllCauses<T>> {\n const values: unknown[] = [];\n for (const result of results) {\n if (!result.ok) {\n return result as unknown as Result<AllValues<T>, AllErrors<T>, AllCauses<T>>;\n }\n values.push(result.value);\n }\n return ok(values) as Result<AllValues<T>, AllErrors<T>, AllCauses<T>>;\n}\n\n/**\n * Combines multiple Results or Promises of Results into one (async version of `all`).\n *\n * ## When to Use\n *\n * Use `allAsync()` when:\n * - You have multiple async operations that all must succeed\n * - You want to run operations in parallel (better performance)\n * - You want to short-circuit on the first error (fail-fast)\n * - You need all values together from parallel operations\n *\n * ## Why Use This Instead of `all`\n *\n * - **Parallel execution**: All Promises start immediately (faster)\n * - **Async support**: Works with Promises and AsyncResults\n * - **Promise rejection handling**: Converts Promise rejections to `PromiseRejectedError`\n *\n * ## Important\n *\n * - **Short-circuits**: Returns first error immediately, cancels remaining operations\n * - **Parallel**: All operations start simultaneously (unlike sequential `andThen`)\n * - **Use `allSettledAsync`**: If you need to collect all errors\n *\n * @param results - Array of Results or Promises of Results to combine (all must succeed)\n * @returns A Promise resolving to a Result with an array of all success values, or the first error\n *\n * @example\n * ```typescript\n * // Parallel API calls\n * const combined = await allAsync([\n * fetchUser('1'),\n * fetchPosts('1'),\n * fetchComments('1')\n * ]);\n * // All three calls start simultaneously\n * // combined: { ok: true, value: [user, posts, comments] } if all succeed\n *\n * // Mix Results and Promises\n * const data = await allAsync([\n * ok(cachedUser), // Already resolved\n * fetchPosts(userId), // Promise\n * ]);\n * ```\n */\nexport async function allAsync<\n const T extends readonly (Result<unknown, unknown, unknown> | Promise<Result<unknown, unknown, unknown>>)[]\n>(\n results: T\n): Promise<\n Result<\n { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> | Promise<Result<infer V, unknown, unknown>> ? V : never },\n { [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> | Promise<Result<unknown, infer E, unknown>> ? E : never }[number] | PromiseRejectedError,\n { [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> | Promise<Result<unknown, unknown, infer C>> ? C : never }[number] | PromiseRejectionCause\n >\n> {\n type Values = { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> | Promise<Result<infer V, unknown, unknown>> ? V : never };\n type Errors = { [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> | Promise<Result<unknown, infer E, unknown>> ? E : never }[number] | PromiseRejectedError;\n type Causes = { [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> | Promise<Result<unknown, unknown, infer C>> ? C : never }[number] | PromiseRejectionCause;\n\n if (results.length === 0) {\n return ok([]) as Result<Values, Errors, Causes>;\n }\n\n return new Promise((resolve) => {\n let settled = false;\n let pendingCount = results.length;\n const values: unknown[] = new Array(results.length);\n\n for (let i = 0; i < results.length; i++) {\n const index = i;\n Promise.resolve(results[index])\n .catch((reason) => err(\n { type: \"PROMISE_REJECTED\" as const, cause: reason },\n { cause: { type: \"PROMISE_REJECTION\" as const, reason } as PromiseRejectionCause }\n ))\n .then((result) => {\n if (settled) return;\n\n if (!result.ok) {\n settled = true;\n resolve(result as Result<Values, Errors, Causes>);\n return;\n }\n\n values[index] = result.value;\n pendingCount--;\n\n if (pendingCount === 0) {\n resolve(ok(values) as Result<Values, Errors, Causes>);\n }\n });\n }\n });\n}\n\nexport type SettledError<E, C = unknown> = { error: E; cause?: C };\n\ntype AllSettledResult<T extends readonly Result<unknown, unknown, unknown>[]> = Result<\n AllValues<T>,\n SettledError<AllErrors<T>, AllCauses<T>>[]\n>;\n\n/**\n * Combines multiple Results, collecting all errors instead of short-circuiting.\n *\n * ## When to Use\n *\n * Use `allSettled()` when:\n * - You need to see ALL errors, not just the first one\n * - You're doing form validation (show all field errors)\n * - You want to collect partial results (some succeed, some fail)\n * - You need to process all Results regardless of failures\n *\n * ## Why Use This Instead of `all`\n *\n * - **Collects all errors**: Returns array of all errors, not just first\n * - **No short-circuit**: Evaluates all Results even if some fail\n * - **Partial success**: Can see which operations succeeded and which failed\n * - **Better UX**: Show users all validation errors at once\n *\n * ## Important\n *\n * - **No short-circuit**: All Results are evaluated (slower if many fail early)\n * - **Error array**: Returns array of `{ error, cause }` objects, not single error\n * - **Use `all`**: If you want fail-fast behavior (better performance)\n *\n * @param results - Array of Results to combine (all are evaluated)\n * @returns A Result with:\n * - Array of all success values if all succeed\n * - Array of `{ error, cause }` objects if any fail\n *\n * @example\n * ```typescript\n * // Form validation - show all errors\n * const validated = allSettled([\n * validateEmail(email),\n * validatePassword(password),\n * validateAge(age),\n * ]);\n * // If email and password fail:\n * // { ok: false, error: [\n * // { error: 'INVALID_EMAIL' },\n * // { error: 'WEAK_PASSWORD' }\n * // ]}\n *\n * // Collect partial results\n * const results = allSettled([\n * fetchUser('1'), // succeeds\n * fetchUser('2'), // fails\n * fetchUser('3'), // succeeds\n * ]);\n * // Can see which succeeded and which failed\n * ```\n */\nexport function allSettled<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): AllSettledResult<T> {\n const values: unknown[] = [];\n const errors: SettledError<unknown>[] = [];\n\n for (const result of results) {\n if (result.ok) {\n values.push(result.value);\n } else {\n errors.push({ error: result.error, cause: result.cause });\n }\n }\n\n if (errors.length > 0) {\n return err(errors) as unknown as AllSettledResult<T>;\n }\n\n return ok(values) as unknown as AllSettledResult<T>;\n}\n\n/**\n * Splits an array of Results into separate arrays of success values and errors.\n *\n * ## When to Use\n *\n * Use `partition()` when:\n * - You have an array of Results and need to separate successes from failures\n * - You want to process successes and errors separately\n * - You're collecting results from multiple operations (some may fail)\n * - You need to handle partial success scenarios\n *\n * ## Why Use This\n *\n * - **Simple separation**: One call splits successes and errors\n * - **Type-safe**: TypeScript knows `values` is `T[]` and `errors` is `E[]`\n * - **No unwrapping**: Doesn't require manual `if (r.ok)` checks\n * - **Preserves order**: Maintains original array order in both arrays\n *\n * ## Common Pattern\n *\n * Often used after `Promise.all()` with Results:\n * ```typescript\n * const results = await Promise.all(ids.map(id => fetchUser(id)));\n * const { values: users, errors } = partition(results);\n * // Process successful users, handle errors separately\n * ```\n *\n * @param results - Array of Results to partition\n * @returns An object with:\n * - `values`: Array of all success values (type `T[]`)\n * - `errors`: Array of all error values (type `E[]`)\n *\n * @example\n * ```typescript\n * // Split successes and errors\n * const results = [ok(1), err('ERROR_1'), ok(3), err('ERROR_2')];\n * const { values, errors } = partition(results);\n * // values: [1, 3]\n * // errors: ['ERROR_1', 'ERROR_2']\n *\n * // Process batch operations\n * const userResults = await Promise.all(userIds.map(id => fetchUser(id)));\n * const { values: users, errors: fetchErrors } = partition(userResults);\n *\n * // Process successful users\n * users.forEach(user => processUser(user));\n *\n * // Handle errors\n * fetchErrors.forEach(error => logError(error));\n * ```\n */\nexport function partition<T, E, C>(\n results: readonly Result<T, E, C>[]\n): { values: T[]; errors: E[] } {\n const values: T[] = [];\n const errors: E[] = [];\n\n for (const result of results) {\n if (result.ok) {\n values.push(result.value);\n } else {\n errors.push(result.error);\n }\n }\n\n return { values, errors };\n}\n\ntype AnyValue<T extends readonly Result<unknown, unknown, unknown>[]> =\n T[number] extends Result<infer U, unknown, unknown> ? U : never;\ntype AnyErrors<T extends readonly Result<unknown, unknown, unknown>[]> = {\n -readonly [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> ? E : never;\n}[number];\ntype AnyCauses<T extends readonly Result<unknown, unknown, unknown>[]> = {\n -readonly [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> ? C : never;\n}[number];\n\n/**\n * Returns the first successful Result from an array (succeeds fast).\n *\n * ## When to Use\n *\n * Use `any()` when:\n * - You have multiple fallback options and need the first that succeeds\n * - You're trying multiple strategies (e.g., cache → DB → API)\n * - You want fail-fast success (stops on first success)\n * - You have redundant data sources and any one will do\n *\n * ## Why Use This\n *\n * - **Succeeds fast**: Returns immediately on first success (better performance)\n * - **Fallback pattern**: Perfect for trying multiple options\n * - **Short-circuits**: Stops evaluating after first success\n * - **Type-safe**: TypeScript infers the success type\n *\n * ## Important\n *\n * - **First success wins**: Returns first successful Result, ignores rest\n * - **All errors**: If all fail, returns first error (not all errors)\n * - **Empty array**: Returns `EmptyInputError` if array is empty\n * - **Use `all`**: If you need ALL to succeed\n *\n * @param results - Array of Results to check (evaluated in order)\n * @returns The first successful Result, or first error if all fail, or `EmptyInputError` if empty\n *\n * @example\n * ```typescript\n * // Try multiple fallback strategies\n * const data = any([\n * fetchFromCache(id),\n * fetchFromDB(id),\n * fetchFromAPI(id)\n * ]);\n * // Returns first that succeeds\n *\n * // Try multiple formats\n * const parsed = any([\n * parseJSON(input),\n * parseXML(input),\n * parseYAML(input)\n * ]);\n *\n * // All errors case\n * const allErrors = any([err('A'), err('B'), err('C')]);\n * // allErrors: { ok: false, error: 'A' } (first error)\n * ```\n */\nexport function any<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): Result<AnyValue<T>, AnyErrors<T> | EmptyInputError, AnyCauses<T>> {\n type ReturnErr = Result<never, AnyErrors<T> | EmptyInputError, AnyCauses<T>>;\n type ReturnOk = Result<AnyValue<T>, never, AnyCauses<T>>;\n\n if (results.length === 0) {\n return err({\n type: \"EMPTY_INPUT\",\n message: \"any() requires at least one Result\",\n }) as ReturnErr;\n }\n let firstError: Result<never, unknown, unknown> | null = null;\n for (const result of results) {\n if (result.ok) return result as ReturnOk;\n if (!firstError) firstError = result;\n }\n return firstError as ReturnErr;\n}\n\ntype AnyAsyncValue<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> =\n Awaited<T[number]> extends Result<infer U, unknown, unknown> ? U : never;\ntype AnyAsyncErrors<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n -readonly [K in keyof T]: Awaited<T[K]> extends Result<unknown, infer E, unknown>\n ? E\n : never;\n}[number];\ntype AnyAsyncCauses<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n -readonly [K in keyof T]: Awaited<T[K]> extends Result<unknown, unknown, infer C>\n ? C\n : never;\n}[number];\n\n/**\n * Returns the first successful Result from an array of Results or Promises (async version of `any`).\n *\n * ## When to Use\n *\n * Use `anyAsync()` when:\n * - You have multiple async fallback options and need the first that succeeds\n * - You're trying multiple async strategies in parallel (cache → DB → API)\n * - You want fail-fast success from parallel operations\n * - You have redundant async data sources and any one will do\n *\n * ## Why Use This Instead of `any`\n *\n * - **Parallel execution**: All Promises start immediately (faster)\n * - **Async support**: Works with Promises and AsyncResults\n * - **Promise rejection handling**: Converts Promise rejections to `PromiseRejectedError`\n *\n * ## Important\n *\n * - **First success wins**: Returns first successful Result (from any Promise)\n * - **Parallel**: All operations run simultaneously\n * - **All errors**: If all fail, returns first error encountered\n *\n * @param results - Array of Results or Promises of Results to check (all start in parallel)\n * @returns A Promise resolving to the first successful Result, or first error if all fail\n *\n * @example\n * ```typescript\n * // Try multiple async fallbacks in parallel\n * const data = await anyAsync([\n * fetchFromCache(id), // Fastest wins\n * fetchFromDB(id),\n * fetchFromAPI(id)\n * ]);\n *\n * // Try multiple API endpoints\n * const response = await anyAsync([\n * fetch('/api/v1/data'),\n * fetch('/api/v2/data'),\n * fetch('/backup-api/data')\n * ]);\n * ```\n */\nexport async function anyAsync<\n const T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[],\n>(\n results: T\n): Promise<\n Result<AnyAsyncValue<T>, AnyAsyncErrors<T> | EmptyInputError | PromiseRejectedError, AnyAsyncCauses<T> | PromiseRejectionCause>\n> {\n type ReturnErr = Result<\n never,\n AnyAsyncErrors<T> | EmptyInputError | PromiseRejectedError,\n AnyAsyncCauses<T> | PromiseRejectionCause\n >;\n type ReturnOk = Result<AnyAsyncValue<T>, never, AnyAsyncCauses<T>>;\n\n if (results.length === 0) {\n return err({\n type: \"EMPTY_INPUT\",\n message: \"anyAsync() requires at least one Result\",\n }) as ReturnErr;\n }\n\n return new Promise((resolve) => {\n let settled = false;\n let pendingCount = results.length;\n let firstError: Result<never, unknown, unknown> | null = null;\n\n for (const item of results) {\n Promise.resolve(item)\n .catch((reason) =>\n err(\n { type: \"PROMISE_REJECTED\" as const, cause: reason },\n { cause: { type: \"PROMISE_REJECTION\" as const, reason } as PromiseRejectionCause }\n )\n )\n .then((result) => {\n if (settled) return;\n\n if (result.ok) {\n settled = true;\n resolve(result as ReturnOk);\n return;\n }\n\n if (!firstError) firstError = result;\n pendingCount--;\n\n if (pendingCount === 0) {\n resolve(firstError as ReturnErr);\n }\n });\n }\n });\n}\n\ntype AllAsyncValues<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n [K in keyof T]: Awaited<T[K]> extends Result<infer V, unknown, unknown> ? V : never;\n};\ntype AllAsyncErrors<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n [K in keyof T]: Awaited<T[K]> extends Result<unknown, infer E, unknown> ? E : never;\n}[number];\ntype AllAsyncCauses<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n [K in keyof T]: Awaited<T[K]> extends Result<unknown, unknown, infer C> ? C : never;\n}[number];\n\n/**\n * Combines multiple Results or Promises of Results, collecting all errors (async version of `allSettled`).\n *\n * ## When to Use\n *\n * Use `allSettledAsync()` when:\n * - You have multiple async operations and need ALL errors\n * - You're doing async form validation (show all field errors)\n * - You want to run operations in parallel and collect all results\n * - You need partial results from parallel operations\n *\n * ## Why Use This Instead of `allSettled`\n *\n * - **Parallel execution**: All Promises start immediately (faster)\n * - **Async support**: Works with Promises and AsyncResults\n * - **Promise rejection handling**: Converts Promise rejections to `PromiseRejectedError`\n *\n * ## Important\n *\n * - **No short-circuit**: All operations complete (even if some fail)\n * - **Parallel**: All operations run simultaneously\n * - **Error array**: Returns array of `{ error, cause }` objects\n *\n * @param results - Array of Results or Promises of Results to combine (all are evaluated)\n * @returns A Promise resolving to a Result with:\n * - Array of all success values if all succeed\n * - Array of `{ error, cause }` objects if any fail\n *\n * @example\n * ```typescript\n * // Async form validation\n * const validated = await allSettledAsync([\n * validateEmailAsync(email),\n * validatePasswordAsync(password),\n * checkUsernameAvailableAsync(username),\n * ]);\n *\n * // Parallel API calls with error collection\n * const results = await allSettledAsync([\n * fetchUser('1'),\n * fetchUser('2'),\n * fetchUser('3'),\n * ]);\n * // Can see which succeeded and which failed\n * ```\n */\nexport async function allSettledAsync<\n const T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[],\n>(\n results: T\n): Promise<Result<AllAsyncValues<T>, SettledError<AllAsyncErrors<T> | PromiseRejectedError, AllAsyncCauses<T> | PromiseRejectionCause>[]>> {\n const settled = await Promise.all(\n results.map((item) =>\n Promise.resolve(item)\n .then((result) => ({ status: \"result\" as const, result }))\n .catch((reason) => ({\n status: \"rejected\" as const,\n error: { type: \"PROMISE_REJECTED\" as const, cause: reason } as PromiseRejectedError,\n cause: { type: \"PROMISE_REJECTION\" as const, reason } as PromiseRejectionCause,\n }))\n )\n );\n\n const values: unknown[] = [];\n const errors: SettledError<unknown, unknown>[] = [];\n\n for (const item of settled) {\n if (item.status === \"rejected\") {\n errors.push({ error: item.error, cause: item.cause });\n } else if (item.result.ok) {\n values.push(item.result.value);\n } else {\n errors.push({ error: item.result.error, cause: item.result.cause });\n }\n }\n\n if (errors.length > 0) {\n return err(errors) as unknown as Result<AllAsyncValues<T>, SettledError<AllAsyncErrors<T> | PromiseRejectedError, AllAsyncCauses<T> | PromiseRejectionCause>[]>;\n }\n return ok(values) as unknown as Result<AllAsyncValues<T>, SettledError<AllAsyncErrors<T> | PromiseRejectedError, AllAsyncCauses<T> | PromiseRejectionCause>[]>;\n}\n"],"mappings":"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","names":["core_exports","__export","EARLY_EXIT_SYMBOL","STEP_TIMEOUT_MARKER","UnwrapError","all","allAsync","allSettled","allSettledAsync","andThen","any","anyAsync","createEarlyExit","err","from","fromNullable","fromPromise","getStepTimeoutMeta","isEarlyExit","isErr","isOk","isStepTimeoutError","isUnexpectedError","map","mapError","mapErrorTry","mapTry","match","ok","partition","run","tap","tapError","tryAsync","unwrap","unwrapOr","unwrapOrElse","__toCommonJS","value","error","options","r","meta","MAPPER_EXCEPTION_SYMBOL","createMapperException","thrown","isMapperException","parseStepOptions","calculateRetryDelay","attempt","backoff","initialDelay","maxDelay","jitter","delay","jitterAmount","sleep","ms","resolve","TIMEOUT_SYMBOL","executeWithTimeout","operation","stepInfo","controller","timeoutError","timeoutId","timeoutPromise","_","reject","operationPromise","errorToThrow","DEFAULT_RETRY_CONFIG","fn","onError","onEvent","catchUnexpected","providedWorkflowId","context","workflowId","wrapMode","activeScopeStack","stepIdCounter","generateStepId","stepKey","emitEvent","event","stepId","i","scope","earlyExit","isEarlyExitE","e","wrapForStep","causeFromMeta","unexpectedFromFailure","failure","stepFn","operationOrResult","stepOptions","parsedOptions","stepName","retryConfig","timeoutConfig","hasEventListeners","overallStartTime","effectiveRetry","lastResult","attemptStartTime","result","durationMs","timeoutMeta","timeoutMs","totalDurationMs","mappedError","mapperError","unexpectedError","errorResult","wrappedError","opts","mapToError","startTime","mapped","name","scopeId","scopeEnded","emitScopeEnd","idx","s","scopeEntry","failureCause","cause","defaultValue","promise","onNull","handlers","transform","results","values","settled","pendingCount","index","reason","errors","firstError","item"]}
|
|
1
|
+
{"version":3,"sources":["../src/core.ts"],"sourcesContent":["/**\n * @jagreehal/workflow/core\n *\n * Core Result primitives and run() function.\n * Use this module for minimal bundle size when you don't need the full workflow capabilities\n * (like retries, timeout, or state persistence) provided by `createWorkflow`.\n *\n * This module provides:\n * 1. `Result` types for error handling without try/catch\n * 2. `run()` function for executing steps with standardized error management\n * 3. Utilities for transforming and combining Results\n */\n\n// =============================================================================\n// Core Result Types\n// =============================================================================\n\n/**\n * Represents a successful computation or a failed one.\n * Use this type to represent the outcome of an operation that might fail,\n * instead of throwing exceptions.\n *\n * @template T - The type of the success value\n * @template E - The type of the error value (defaults to unknown)\n * @template C - The type of the cause (defaults to unknown)\n */\nexport type Result<T, E = unknown, C = unknown> =\n | { ok: true; value: T }\n | { ok: false; error: E; cause?: C };\n\n/**\n * A Promise that resolves to a Result.\n * Use this for asynchronous operations that might fail.\n */\nexport type AsyncResult<T, E = unknown, C = unknown> = Promise<Result<T, E, C>>;\n\nexport type UnexpectedStepFailureCause =\n | {\n type: \"STEP_FAILURE\";\n origin: \"result\";\n error: unknown;\n cause?: unknown;\n }\n | {\n type: \"STEP_FAILURE\";\n origin: \"throw\";\n error: unknown;\n thrown: unknown;\n };\n\nexport type UnexpectedCause =\n | { type: \"UNCAUGHT_EXCEPTION\"; thrown: unknown }\n | UnexpectedStepFailureCause;\n\nexport type UnexpectedError = {\n type: \"UNEXPECTED_ERROR\";\n cause: UnexpectedCause;\n};\nexport type PromiseRejectedError = { type: \"PROMISE_REJECTED\"; cause: unknown };\n/** Cause type for promise rejections in async batch helpers */\nexport type PromiseRejectionCause = { type: \"PROMISE_REJECTION\"; reason: unknown };\nexport type EmptyInputError = { type: \"EMPTY_INPUT\"; message: string };\nexport type MaybeAsyncResult<T, E, C = unknown> = Result<T, E, C> | Promise<Result<T, E, C>>;\n\n// =============================================================================\n// Result Constructors\n// =============================================================================\n\n/**\n * Creates a successful Result.\n * Use this when an operation completes successfully.\n *\n * @param value - The success value to wrap\n * @returns A Result object with `{ ok: true, value }`\n *\n * @example\n * ```typescript\n * function divide(a: number, b: number): Result<number, string> {\n * if (b === 0) return err(\"Division by zero\");\n * return ok(a / b);\n * }\n * ```\n */\nexport const ok = <T>(value: T): Result<T, never, never> => ({ ok: true, value });\n\n/**\n * Creates a failed Result.\n * Use this when an operation fails.\n *\n * @param error - The error value describing what went wrong (e.g., error code, object)\n * @param options - Optional context about the failure\n * @param options.cause - The underlying cause of the error (e.g., a caught exception)\n * @returns A Result object with `{ ok: false, error }` (and optional cause)\n *\n * @example\n * ```typescript\n * // Simple error\n * const r1 = err(\"NOT_FOUND\");\n *\n * // Error with cause (useful for wrapping exceptions)\n * try {\n * // ... unsafe code\n * } catch (e) {\n * return err(\"PROCESSING_FAILED\", { cause: e });\n * }\n * ```\n */\nexport const err = <E, C = unknown>(\n error: E,\n options?: { cause?: C }\n): Result<never, E, C> => ({\n ok: false,\n error,\n ...(options?.cause !== undefined ? { cause: options.cause } : {}),\n});\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Checks if a Result is successful.\n * Use this to narrow the type of a Result to the success case.\n *\n * @param r - The Result to check\n * @returns `true` if successful, allowing access to `r.value`\n *\n * @example\n * ```typescript\n * const r = someOperation();\n * if (isOk(r)) {\n * // Use r.value (Type is T)\n * processValue(r.value);\n * } else {\n * // Handle r.error (Type is E)\n * handleError(r.error);\n * }\n * ```\n */\nexport const isOk = <T, E, C>(r: Result<T, E, C>): r is { ok: true; value: T } =>\n r.ok;\n\n/**\n * Checks if a Result is a failure.\n * Use this to narrow the type of a Result to the error case.\n *\n * @param r - The Result to check\n * @returns `true` if failed, allowing access to `r.error` and `r.cause`\n *\n * @example\n * ```typescript\n * if (isErr(r)) {\n * // Handle error case early\n * return;\n * }\n * // Proceed with success case\n * ```\n */\nexport const isErr = <T, E, C>(\n r: Result<T, E, C>\n): r is { ok: false; error: E; cause?: C } => !r.ok;\n\n/**\n * Checks if an error is an UnexpectedError.\n * Used internally by the framework but exported for advanced custom handling.\n * Indicates an error that wasn't typed/expected in the `run` signature.\n */\nexport const isUnexpectedError = (e: unknown): e is UnexpectedError =>\n typeof e === \"object\" &&\n e !== null &&\n (e as UnexpectedError).type === \"UNEXPECTED_ERROR\";\n\n// =============================================================================\n// Type Utilities\n// =============================================================================\n\ntype AnyFunction = (...args: never[]) => unknown;\n\n/**\n * Helper to extract the error type from Result or AsyncResult return values.\n * Works even when a function is declared to return a union of both forms.\n */\ntype ErrorOfReturn<R> = Extract<Awaited<R>, { ok: false }> extends { error: infer E }\n ? E\n : never;\n\n/**\n * Extract error type from a single function's return type\n */\nexport type ErrorOf<T extends AnyFunction> = ErrorOfReturn<ReturnType<T>>;\n\n/**\n * Extract union of error types from multiple functions\n */\nexport type Errors<T extends AnyFunction[]> = {\n [K in keyof T]: ErrorOf<T[K]>;\n}[number];\n\n/**\n * Extract value type from Result\n */\nexport type ExtractValue<T> = T extends { ok: true; value: infer U }\n ? U\n : never;\n\n/**\n * Extract error type from Result\n */\nexport type ExtractError<T> = T extends { ok: false; error: infer E }\n ? E\n : never;\n\n/**\n * Extract cause type from Result\n */\nexport type ExtractCause<T> = T extends { ok: false; cause?: infer C }\n ? C\n : never;\n\n/**\n * Helper to extract the cause type from Result or AsyncResult return values.\n * Works even when a function is declared to return a union of both forms.\n */\ntype CauseOfReturn<R> = Extract<Awaited<R>, { ok: false }> extends { cause?: infer C }\n ? C\n : never;\n\n/**\n * Extract cause type from a function's return type\n */\nexport type CauseOf<T extends AnyFunction> = CauseOfReturn<ReturnType<T>>;\n\n// =============================================================================\n// Step Options\n// =============================================================================\n\n/**\n * Options for configuring a step within a workflow.\n * Use these to enable tracing, caching, and state persistence.\n */\nexport type StepOptions = {\n /**\n * Human-readable label for the step.\n * Used in logs, traces, and error messages.\n * Highly recommended for debugging complex workflows.\n */\n name?: string;\n\n /**\n * Stable identity key for the step.\n * REQUIRED for:\n * 1. Caching: Used as the cache key.\n * 2. Resuming: Used to identify which steps have already completed.\n *\n * Must be unique within the workflow.\n */\n key?: string;\n\n /**\n * Retry configuration for transient failures.\n * When specified, the step will retry on errors according to this config.\n */\n retry?: RetryOptions;\n\n /**\n * Timeout configuration for the operation.\n * When specified, each attempt will be aborted after the timeout duration.\n */\n timeout?: TimeoutOptions;\n};\n\n// =============================================================================\n// Retry and Timeout Types\n// =============================================================================\n\n/**\n * Backoff strategy for retry operations.\n */\nexport type BackoffStrategy = \"fixed\" | \"linear\" | \"exponential\";\n\n/**\n * Configuration for step retry behavior.\n */\nexport type RetryOptions = {\n /**\n * Total number of attempts (1 = no retry, 3 = initial + 2 retries).\n * Must be >= 1.\n */\n attempts: number;\n\n /**\n * Backoff strategy between retries.\n * - 'fixed': Same delay each time (initialDelay)\n * - 'linear': Delay increases linearly (initialDelay * attempt)\n * - 'exponential': Delay doubles each time (initialDelay * 2^(attempt-1))\n * @default 'exponential'\n */\n backoff?: BackoffStrategy;\n\n /**\n * Initial delay in milliseconds before first retry.\n * @default 100\n */\n initialDelay?: number;\n\n /**\n * Maximum delay cap in milliseconds.\n * Prevents exponential backoff from growing too large.\n * @default 30000 (30 seconds)\n */\n maxDelay?: number;\n\n /**\n * Whether to add random jitter (0-25% of delay).\n * Helps prevent thundering herd when multiple workflows retry simultaneously.\n * @default true\n */\n jitter?: boolean;\n\n /**\n * Predicate to determine if a retry should occur.\n * Receives the error and current attempt number (1-indexed).\n * Return true to retry, false to fail immediately.\n * @default Always retry on any error\n */\n retryOn?: (error: unknown, attempt: number) => boolean;\n\n /**\n * Callback invoked before each retry attempt.\n * Useful for logging, metrics, or side effects.\n */\n onRetry?: (error: unknown, attempt: number, delayMs: number) => void;\n};\n\n/**\n * Configuration for step timeout behavior.\n */\nexport type TimeoutOptions = {\n /**\n * Timeout duration in milliseconds per attempt.\n * When combined with retry, each attempt gets its own timeout.\n */\n ms: number;\n\n /**\n * Custom error to use when timeout occurs.\n * @default StepTimeoutError with step details\n */\n error?: unknown;\n\n /**\n * Whether to pass an AbortSignal to the operation.\n * When true, the operation function receives (signal: AbortSignal) as argument.\n * Useful for fetch() and other APIs that support cancellation.\n * @default false\n */\n signal?: boolean;\n};\n\n/**\n * Standard timeout error type.\n */\nexport type StepTimeoutError = {\n type: \"STEP_TIMEOUT\";\n stepName?: string;\n stepKey?: string;\n timeoutMs: number;\n attempt?: number;\n};\n\n/**\n * Symbol used to mark any error (including custom errors) as a timeout error.\n * This allows detection of timeout errors even when users provide custom error payloads.\n */\nexport const STEP_TIMEOUT_MARKER: unique symbol = Symbol.for(\"step_timeout_marker\");\n\n/**\n * Metadata attached to timeout-marked errors.\n */\nexport type StepTimeoutMarkerMeta = {\n timeoutMs: number;\n stepName?: string;\n stepKey?: string;\n attempt?: number;\n};\n\n/**\n * Type guard to check if an error is a StepTimeoutError.\n * This checks both the standard type field AND the timeout marker symbol,\n * so custom errors provided via timeout.error are also detected.\n */\nexport function isStepTimeoutError(e: unknown): e is StepTimeoutError {\n if (typeof e !== \"object\" || e === null) {\n return false;\n }\n // Check for standard type field\n if ((e as StepTimeoutError).type === \"STEP_TIMEOUT\") {\n return true;\n }\n // Check for timeout marker (custom errors)\n return STEP_TIMEOUT_MARKER in e;\n}\n\n/**\n * Get timeout metadata from a timeout error (works with both standard and custom errors).\n * Returns undefined if the error is not a timeout error.\n */\nexport function getStepTimeoutMeta(e: unknown): StepTimeoutMarkerMeta | undefined {\n if (typeof e !== \"object\" || e === null) {\n return undefined;\n }\n // Check for standard type field first\n if ((e as StepTimeoutError).type === \"STEP_TIMEOUT\") {\n const err = e as StepTimeoutError;\n return {\n timeoutMs: err.timeoutMs,\n stepName: err.stepName,\n stepKey: err.stepKey,\n attempt: err.attempt,\n };\n }\n // Check for timeout marker (custom errors)\n if (STEP_TIMEOUT_MARKER in e) {\n return (e as Record<symbol, StepTimeoutMarkerMeta>)[STEP_TIMEOUT_MARKER];\n }\n return undefined;\n}\n\n// =============================================================================\n// RunStep Interface\n// =============================================================================\n\n/**\n * The `step` object passed to the function in `run(async (step) => { ... })`.\n * acts as the bridge between your business logic and the workflow engine.\n *\n * It provides methods to:\n * 1. Execute operations that return `Result` types.\n * 2. safely wrap operations that might throw exceptions (using `step.try`).\n * 3. Assign names and keys to operations for tracing and caching.\n *\n * @template E - The union of all known error types expected in this workflow.\n */\nexport interface RunStep<E = unknown> {\n /**\n * Execute a Result-returning operation (lazy function form).\n *\n * Use this form when the operation has side effects or is expensive,\n * so it's only executed if the step hasn't been cached/completed yet.\n *\n * @param operation - A function that returns a Result or AsyncResult\n * @param options - Step name or options object\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If the result is an error (stops execution safely)\n *\n * @example\n * ```typescript\n * const user = await step(() => fetchUser(id), \"fetch-user\");\n * ```\n */\n <T, StepE extends E, StepC = unknown>(\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n options?: StepOptions | string\n ): Promise<T>;\n\n /**\n * Execute a Result-returning operation (direct value form).\n *\n * Use this form for simple operations or when you already have a Result/Promise.\n * Note: The operation has already started/completed by the time `step` is called.\n *\n * @param result - A Result object or Promise resolving to a Result\n * @param options - Step name or options object\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If the result is an error (stops execution safely)\n *\n * @example\n * ```typescript\n * const user = await step(existingResult, \"check-result\");\n * ```\n */\n <T, StepE extends E, StepC = unknown>(\n result: Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n options?: StepOptions | string\n ): Promise<T>;\n\n /**\n * Execute a standard throwing operation safely.\n * Catches exceptions and maps them to a typed error, or wraps them if no mapper is provided.\n *\n * Use this when integrating with libraries that throw exceptions.\n *\n * @param operation - A function that returns a value or Promise (may throw)\n * @param options - Configuration including error mapping\n * @returns The success value\n * @throws {EarlyExit} If the operation throws (stops execution safely)\n *\n * @example\n * ```typescript\n * const data = await step.try(\n * () => db.query(),\n * {\n * name: \"db-query\",\n * onError: (e) => ({ type: \"DB_ERROR\", cause: e })\n * }\n * );\n * ```\n */\n try: <T, const Err extends E>(\n operation: () => T | Promise<T>,\n options:\n | { error: Err; name?: string; key?: string }\n | { onError: (cause: unknown) => Err; name?: string; key?: string }\n ) => Promise<T>;\n\n /**\n * Execute a Result-returning function and map its error to a typed error.\n *\n * Use this when calling functions that return Result<T, E> and you want to\n * map their typed errors to your workflow's error type. Unlike step.try(),\n * the error passed to onError is typed (not unknown).\n *\n * @param operation - A function that returns a Result or AsyncResult\n * @param options - Configuration including error mapping\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If the result is an error (stops execution safely)\n *\n * @example\n * ```typescript\n * const response = await step.fromResult(\n * () => callProvider(input),\n * {\n * name: \"call-provider\",\n * onError: (providerError) => ({\n * type: \"PROVIDER_FAILED\",\n * provider: providerError.provider,\n * cause: providerError\n * })\n * }\n * );\n * ```\n */\n fromResult: <T, ResultE, const Err extends E>(\n operation: () => Result<T, ResultE, unknown> | AsyncResult<T, ResultE, unknown>,\n options:\n | { error: Err; name?: string; key?: string }\n | { onError: (resultError: ResultE) => Err; name?: string; key?: string }\n ) => Promise<T>;\n\n /**\n * Execute a parallel operation (allAsync) with scope events for visualization.\n *\n * This wraps the operation with scope_start and scope_end events, enabling\n * visualization of parallel execution branches.\n *\n * @param name - Name for this parallel block (used in visualization)\n * @param operation - A function that returns a Result from allAsync or allSettledAsync\n * @returns The success value (unwrapped array)\n *\n * @example\n * ```typescript\n * const [user, posts] = await step.parallel('Fetch all data', () =>\n * allAsync([fetchUser(id), fetchPosts(id)])\n * );\n * ```\n */\n parallel: <T, StepE extends E, StepC = unknown>(\n name: string,\n operation: () => Result<T[], StepE, StepC> | AsyncResult<T[], StepE, StepC>\n ) => Promise<T[]>;\n\n /**\n * Execute a race operation (anyAsync) with scope events for visualization.\n *\n * This wraps the operation with scope_start and scope_end events, enabling\n * visualization of racing execution branches.\n *\n * @param name - Name for this race block (used in visualization)\n * @param operation - A function that returns a Result from anyAsync\n * @returns The success value (first to succeed)\n *\n * @example\n * ```typescript\n * const data = await step.race('Fastest API', () =>\n * anyAsync([fetchFromPrimary(id), fetchFromFallback(id)])\n * );\n * ```\n */\n race: <T, StepE extends E, StepC = unknown>(\n name: string,\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>\n ) => Promise<T>;\n\n /**\n * Execute an allSettled operation with scope events for visualization.\n *\n * This wraps the operation with scope_start and scope_end events, enabling\n * visualization of allSettled execution branches. Unlike step.parallel,\n * allSettled collects all results even if some fail.\n *\n * @param name - Name for this allSettled block (used in visualization)\n * @param operation - A function that returns a Result from allSettledAsync\n * @returns The success value (unwrapped array)\n *\n * @example\n * ```typescript\n * const [user, posts] = await step.allSettled('Fetch all data', () =>\n * allSettledAsync([fetchUser(id), fetchPosts(id)])\n * );\n * ```\n */\n allSettled: <T, StepE extends E, StepC = unknown>(\n name: string,\n operation: () => Result<T[], StepE, StepC> | AsyncResult<T[], StepE, StepC>\n ) => Promise<T[]>;\n\n /**\n * Execute an operation with retry and optional timeout.\n *\n * Use this for operations that may fail transiently (network issues, rate limits)\n * and benefit from automatic retry with backoff.\n *\n * @param operation - A function that returns a Result or AsyncResult\n * @param options - Retry configuration and optional timeout\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If all retries are exhausted (stops execution safely)\n *\n * @example\n * ```typescript\n * const data = await step.retry(\n * () => fetchFromExternalApi(id),\n * {\n * name: 'fetch-external',\n * attempts: 3,\n * backoff: 'exponential',\n * initialDelay: 200,\n * retryOn: (error) => error === 'RATE_LIMITED' || error === 'TRANSIENT',\n * onRetry: (error, attempt, delay) => {\n * console.log(`Retry ${attempt} after ${delay}ms`);\n * },\n * }\n * );\n * ```\n */\n retry: <T, StepE extends E, StepC = unknown>(\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n options: RetryOptions & { name?: string; key?: string; timeout?: TimeoutOptions }\n ) => Promise<T>;\n\n /**\n * Execute an operation with a timeout.\n *\n * Use this for operations that may hang indefinitely (external APIs, connections)\n * and need to be aborted after a certain duration.\n *\n * When `signal: true` is set, an AbortSignal is passed to your operation,\n * which you can use with APIs like fetch() for proper cancellation.\n *\n * @param operation - A function that returns a Result (may receive AbortSignal)\n * @param options - Timeout configuration\n * @returns The success value (unwrapped)\n * @throws {EarlyExit} If the operation times out (stops execution safely)\n *\n * @example\n * ```typescript\n * // Without AbortSignal\n * const data = await step.withTimeout(\n * () => fetchData(id),\n * { ms: 5000, name: 'fetch-data' }\n * );\n *\n * // With AbortSignal for fetch()\n * const data = await step.withTimeout(\n * (signal) => fetch(url, { signal }).then(r => ok(r.json())),\n * { ms: 5000, signal: true, name: 'fetch-url' }\n * );\n * ```\n */\n withTimeout: <T, StepE extends E, StepC = unknown>(\n operation:\n | (() => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>)\n | ((signal: AbortSignal) => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>),\n options: TimeoutOptions & { name?: string; key?: string }\n ) => Promise<T>;\n}\n\n// =============================================================================\n// Event Types (for run() optional event support)\n// =============================================================================\n\n/**\n * Unified event stream for workflow execution.\n *\n * Note: step_complete.result uses Result<unknown, unknown, unknown> because events\n * aggregate results from heterogeneous steps. At runtime, the actual Result object\n * preserves its original types, but the event type cannot statically represent them.\n * Use runtime checks or the meta field to interpret cause values.\n */\n/**\n * Scope types for parallel and race operations.\n */\nexport type ScopeType = \"parallel\" | \"race\" | \"allSettled\";\n\nexport type WorkflowEvent<E> =\n | { type: \"workflow_start\"; workflowId: string; ts: number }\n | { type: \"workflow_success\"; workflowId: string; ts: number; durationMs: number }\n | { type: \"workflow_error\"; workflowId: string; ts: number; durationMs: number; error: E }\n | { type: \"step_start\"; workflowId: string; stepId: string; stepKey?: string; name?: string; ts: number }\n | { type: \"step_success\"; workflowId: string; stepId: string; stepKey?: string; name?: string; ts: number; durationMs: number }\n | { type: \"step_error\"; workflowId: string; stepId: string; stepKey?: string; name?: string; ts: number; durationMs: number; error: E }\n | { type: \"step_aborted\"; workflowId: string; stepId: string; stepKey?: string; name?: string; ts: number; durationMs: number }\n | { type: \"step_complete\"; workflowId: string; stepKey: string; name?: string; ts: number; durationMs: number; result: Result<unknown, unknown, unknown>; meta?: StepFailureMeta }\n | { type: \"step_cache_hit\"; workflowId: string; stepKey: string; name?: string; ts: number }\n | { type: \"step_cache_miss\"; workflowId: string; stepKey: string; name?: string; ts: number }\n | { type: \"step_skipped\"; workflowId: string; stepKey?: string; name?: string; reason?: string; decisionId?: string; ts: number }\n | { type: \"scope_start\"; workflowId: string; scopeId: string; scopeType: ScopeType; name?: string; ts: number }\n | { type: \"scope_end\"; workflowId: string; scopeId: string; ts: number; durationMs: number; winnerId?: string }\n // Retry events\n | {\n type: \"step_retry\";\n workflowId: string;\n stepId: string;\n stepKey?: string;\n name?: string;\n ts: number;\n attempt: number;\n maxAttempts: number;\n delayMs: number;\n error: E;\n }\n | {\n type: \"step_retries_exhausted\";\n workflowId: string;\n stepId: string;\n stepKey?: string;\n name?: string;\n ts: number;\n durationMs: number;\n attempts: number;\n lastError: E;\n }\n // Timeout event\n | {\n type: \"step_timeout\";\n workflowId: string;\n stepId: string;\n stepKey?: string;\n name?: string;\n ts: number;\n timeoutMs: number;\n attempt?: number;\n };\n\n// =============================================================================\n// Run Options\n// =============================================================================\n\nexport type RunOptionsWithCatch<E, C = void> = {\n /**\n * Handler for expected errors.\n * Called when a step fails with a known error type.\n */\n onError?: (error: E, stepName?: string) => void;\n /**\n * Listener for workflow events (start, success, error, step events).\n * Use this for logging, telemetry, or debugging.\n */\n onEvent?: (event: WorkflowEvent<E | UnexpectedError>, ctx: C) => void;\n /**\n * Catch-all mapper for unexpected exceptions.\n * Required for \"Strict Mode\".\n * Converts unknown exceptions (like network crashes or bugs) into your typed error union E.\n */\n catchUnexpected: (cause: unknown) => E;\n /**\n * Unique ID for this workflow execution.\n * Defaults to a random UUID.\n * Useful for correlating logs across distributed systems.\n */\n workflowId?: string;\n /**\n * Arbitrary context object passed to onEvent.\n * Useful for passing request IDs, user IDs, or loggers.\n */\n context?: C;\n};\n\nexport type RunOptionsWithoutCatch<E, C = void> = {\n /**\n * Handler for expected errors AND unexpected errors.\n * Unexpected errors will be wrapped in `UnexpectedError`.\n */\n onError?: (error: E | UnexpectedError, stepName?: string) => void;\n onEvent?: (event: WorkflowEvent<E | UnexpectedError>, ctx: C) => void;\n catchUnexpected?: undefined;\n workflowId?: string;\n context?: C;\n};\n\nexport type RunOptions<E, C = void> = RunOptionsWithCatch<E, C> | RunOptionsWithoutCatch<E, C>;\n\n// =============================================================================\n// Early Exit Mechanism (exported for caching layer)\n// =============================================================================\n\n/**\n * Symbol used to identify early exit throws.\n * Exported for the caching layer in workflow.ts.\n * @internal\n */\nexport const EARLY_EXIT_SYMBOL: unique symbol = Symbol(\"early-exit\");\n\n/**\n * Metadata about how a step failed.\n * @internal\n */\nexport type StepFailureMeta =\n | { origin: \"result\"; resultCause?: unknown }\n | { origin: \"throw\"; thrown: unknown };\n\n/**\n * Early exit object thrown to short-circuit workflow execution.\n * @internal\n */\nexport type EarlyExit<E> = {\n [EARLY_EXIT_SYMBOL]: true;\n error: E;\n meta: StepFailureMeta;\n};\n\n/**\n * Create an early exit throw object.\n * Used by the caching layer to synthesize early exits for cached errors.\n * @internal\n */\nexport function createEarlyExit<E>(error: E, meta: StepFailureMeta): EarlyExit<E> {\n return {\n [EARLY_EXIT_SYMBOL]: true,\n error,\n meta,\n };\n}\n\n/**\n * Type guard for early exit objects.\n * @internal\n */\nexport function isEarlyExit<E>(e: unknown): e is EarlyExit<E> {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as Record<PropertyKey, unknown>)[EARLY_EXIT_SYMBOL] === true\n );\n}\n\n/**\n * Symbol to mark exceptions thrown by catchUnexpected mappers.\n * These should propagate without being re-processed.\n * @internal\n */\nconst MAPPER_EXCEPTION_SYMBOL: unique symbol = Symbol(\"mapper-exception\");\n\ntype MapperException = {\n [MAPPER_EXCEPTION_SYMBOL]: true;\n thrown: unknown;\n};\n\nfunction createMapperException(thrown: unknown): MapperException {\n return { [MAPPER_EXCEPTION_SYMBOL]: true, thrown };\n}\n\nfunction isMapperException(e: unknown): e is MapperException {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as Record<PropertyKey, unknown>)[MAPPER_EXCEPTION_SYMBOL] === true\n );\n}\n\n/** Helper to parse step options - accepts string or object form */\nfunction parseStepOptions(\n options?: StepOptions | string\n): StepOptions & { name?: string; key?: string } {\n if (typeof options === \"string\") {\n return { name: options };\n }\n return options ?? {};\n}\n\n// =============================================================================\n// Retry and Timeout Utilities\n// =============================================================================\n\n/**\n * Calculate the delay for a retry attempt based on the backoff strategy.\n * @internal\n */\nfunction calculateRetryDelay(\n attempt: number,\n options: {\n backoff: BackoffStrategy;\n initialDelay: number;\n maxDelay: number;\n jitter: boolean;\n }\n): number {\n const { backoff, initialDelay, maxDelay, jitter } = options;\n\n let delay: number;\n\n switch (backoff) {\n case \"fixed\":\n delay = initialDelay;\n break;\n case \"linear\":\n delay = initialDelay * attempt;\n break;\n case \"exponential\":\n delay = initialDelay * Math.pow(2, attempt - 1);\n break;\n }\n\n // Apply max cap\n delay = Math.min(delay, maxDelay);\n\n // Apply jitter (0-25% of delay)\n if (jitter) {\n const jitterAmount = delay * 0.25 * Math.random();\n delay = delay + jitterAmount;\n }\n\n return Math.floor(delay);\n}\n\n/**\n * Sleep for a specified number of milliseconds.\n * @internal\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Symbol used internally to identify timeout rejection.\n */\nconst TIMEOUT_SYMBOL: unique symbol = Symbol(\"timeout\");\n\n/**\n * Execute an operation with a timeout using Promise.race.\n * @internal\n */\nasync function executeWithTimeout<T>(\n operation: (() => Promise<T>) | ((signal: AbortSignal) => Promise<T>),\n options: TimeoutOptions,\n stepInfo: { name?: string; key?: string; attempt?: number }\n): Promise<T> {\n const controller = new AbortController();\n\n // Create the timeout error once\n const timeoutError: StepTimeoutError =\n (options.error as StepTimeoutError) ?? {\n type: \"STEP_TIMEOUT\",\n stepName: stepInfo.name,\n stepKey: stepInfo.key,\n timeoutMs: options.ms,\n attempt: stepInfo.attempt,\n };\n\n // Track the timeout ID for cleanup\n let timeoutId: ReturnType<typeof setTimeout>;\n\n // Create a timeout promise that rejects after the specified duration\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n controller.abort(); // Signal abort for operations that support it\n reject({ [TIMEOUT_SYMBOL]: true, error: timeoutError });\n }, options.ms);\n });\n\n // Execute the operation\n let operationPromise: Promise<T>;\n if (options.signal) {\n // Operation expects an AbortSignal\n operationPromise = Promise.resolve(\n (operation as (signal: AbortSignal) => Promise<T>)(controller.signal)\n );\n } else {\n // Standard operation\n operationPromise = Promise.resolve((operation as () => Promise<T>)());\n }\n\n try {\n // Race between operation and timeout\n const result = await Promise.race([operationPromise, timeoutPromise]);\n return result;\n } catch (error) {\n // Check if this was our timeout\n if (\n typeof error === \"object\" &&\n error !== null &&\n (error as Record<symbol, unknown>)[TIMEOUT_SYMBOL] === true\n ) {\n const errorToThrow = (error as { error: unknown }).error;\n\n // Mark the error with STEP_TIMEOUT_MARKER if it's a custom error (not already a StepTimeoutError)\n // This allows isStepTimeoutError() and getStepTimeoutMeta() to work with custom errors\n // Note: Always update metadata to reflect the current attempt (same error may be reused across retries)\n if (\n typeof errorToThrow === \"object\" &&\n errorToThrow !== null &&\n (errorToThrow as StepTimeoutError).type !== \"STEP_TIMEOUT\"\n ) {\n const meta: StepTimeoutMarkerMeta = {\n timeoutMs: options.ms,\n stepName: stepInfo.name,\n stepKey: stepInfo.key,\n attempt: stepInfo.attempt,\n };\n\n if (STEP_TIMEOUT_MARKER in errorToThrow) {\n // Update existing marker with current attempt's metadata\n (errorToThrow as Record<symbol, StepTimeoutMarkerMeta>)[STEP_TIMEOUT_MARKER] = meta;\n } else {\n // Define new marker (writable so it can be updated on retry)\n Object.defineProperty(errorToThrow, STEP_TIMEOUT_MARKER, {\n value: meta,\n enumerable: false,\n writable: true,\n configurable: false,\n });\n }\n }\n\n throw errorToThrow;\n }\n // Re-throw other errors\n throw error;\n } finally {\n // Always clear the timeout to prevent leaks\n clearTimeout(timeoutId!);\n }\n}\n\n/**\n * Default retry configuration values.\n * @internal\n */\nconst DEFAULT_RETRY_CONFIG = {\n backoff: \"exponential\" as BackoffStrategy,\n initialDelay: 100,\n maxDelay: 30000,\n jitter: true,\n retryOn: () => true,\n onRetry: () => {},\n} as const;\n\n// =============================================================================\n// run() Function\n// =============================================================================\n\n/**\n * Execute a workflow with step-based error handling.\n *\n * ## When to Use run()\n *\n * Use `run()` when:\n * - Dependencies are dynamic (passed at runtime, not known at compile time)\n * - You don't need step caching or resume state\n * - Error types are known upfront and can be specified manually\n * - Building lightweight, one-off workflows\n *\n * For automatic error type inference from static dependencies, use `createWorkflow()`.\n *\n * ## Modes\n *\n * `run()` has three modes based on options:\n * - **Strict Mode** (`catchUnexpected`): Returns `Result<T, E>` (closed union)\n * - **Typed Mode** (`onError`): Returns `Result<T, E | UnexpectedError>`\n * - **Safe Default** (no options): Returns `Result<T, UnexpectedError>`\n *\n * @example\n * ```typescript\n * // Typed mode with explicit error union\n * const result = await run<Output, 'NOT_FOUND' | 'FETCH_ERROR'>(\n * async (step) => {\n * const user = await step(fetchUser(userId));\n * return user;\n * },\n * { onError: (e) => console.log('Failed:', e) }\n * );\n * ```\n *\n * @see createWorkflow - For static dependencies with auto error inference\n */\n\n/**\n * Execute a workflow with \"Strict Mode\" error handling.\n *\n * In this mode, you MUST provide `catchUnexpected` to map unknown exceptions\n * to your typed error union `E`. This guarantees that the returned Result\n * will only ever contain errors of type `E`.\n *\n * @param fn - The workflow function containing steps\n * @param options - Configuration options, including `catchUnexpected`\n * @returns A Promise resolving to `Result<T, E>`\n *\n * @example\n * ```typescript\n * const result = await run(async (step) => {\n * // ... steps ...\n * }, {\n * catchUnexpected: (e) => ({ type: 'UNKNOWN_ERROR', cause: e })\n * });\n * ```\n */\nexport function run<T, E, C = void>(\n fn: (step: RunStep<E>) => Promise<T> | T,\n options: RunOptionsWithCatch<E, C>\n): AsyncResult<T, E, unknown>;\n\n/**\n * Execute a workflow with \"Typed Mode\" error handling.\n *\n * In this mode, you provide an `onError` callback. The returned Result\n * may contain your typed errors `E` OR `UnexpectedError` if an uncaught\n * exception occurs.\n *\n * @param fn - The workflow function containing steps\n * @param options - Configuration options, including `onError`\n * @returns A Promise resolving to `Result<T, E | UnexpectedError>`\n */\nexport function run<T, E, C = void>(\n fn: (step: RunStep<E | UnexpectedError>) => Promise<T> | T,\n options: {\n onError: (error: E | UnexpectedError, stepName?: string) => void;\n onEvent?: (event: WorkflowEvent<E | UnexpectedError>, ctx: C) => void;\n workflowId?: string;\n context?: C;\n }\n): AsyncResult<T, E | UnexpectedError, unknown>;\n\n/**\n * Execute a workflow with \"Safe Default\" error handling.\n *\n * In this mode, you don't need to specify any error types.\n * Any error (Result error or thrown exception) will be returned as\n * an `UnexpectedError`.\n *\n * @param fn - The workflow function containing steps\n * @param options - Optional configuration\n * @returns A Promise resolving to `Result<T, UnexpectedError>`\n *\n * @example\n * ```typescript\n * const result = await run(async (step) => {\n * return await step(someOp());\n * });\n * ```\n */\nexport function run<T, C = void>(\n fn: (step: RunStep) => Promise<T> | T,\n options?: {\n onEvent?: (event: WorkflowEvent<UnexpectedError>, ctx: C) => void;\n workflowId?: string;\n context?: C;\n }\n): AsyncResult<T, UnexpectedError, unknown>;\n\n// Implementation\nexport async function run<T, E, C = void>(\n fn: (step: RunStep<E | UnexpectedError>) => Promise<T> | T,\n options?: RunOptions<E, C>\n): AsyncResult<T, E | UnexpectedError> {\n const {\n onError,\n onEvent,\n catchUnexpected,\n workflowId: providedWorkflowId,\n context,\n } = options && typeof options === \"object\"\n ? (options as RunOptions<E, C>)\n : ({} as RunOptions<E, C>);\n\n const workflowId = providedWorkflowId ?? crypto.randomUUID();\n const wrapMode = !onError && !catchUnexpected;\n\n // Track active scopes as a stack for proper nesting\n // When a step succeeds, only the innermost race scope gets the winner\n const activeScopeStack: Array<{ scopeId: string; type: \"race\" | \"parallel\" | \"allSettled\"; winnerId?: string }> = [];\n\n // Counter for generating unique step IDs\n let stepIdCounter = 0;\n\n // Generate a unique step ID\n // Uses stepKey when provided (for cache stability), otherwise generates a unique ID.\n // Note: name is NOT used for stepId because multiple concurrent steps may share a name,\n // which would cause them to collide in activeSteps tracking and race winner detection.\n const generateStepId = (stepKey?: string): string => {\n return stepKey ?? `step_${++stepIdCounter}`;\n };\n\n const emitEvent = (event: WorkflowEvent<E | UnexpectedError>) => {\n // Track first successful step in the innermost race scope for winnerId\n if (event.type === \"step_success\") {\n // Use the stepId from the event (already generated at step start)\n const stepId = event.stepId;\n\n // Find innermost race scope (search from end of stack)\n for (let i = activeScopeStack.length - 1; i >= 0; i--) {\n const scope = activeScopeStack[i];\n if (scope.type === \"race\" && !scope.winnerId) {\n scope.winnerId = stepId;\n break; // Only update innermost race scope\n }\n }\n }\n onEvent?.(event, context as C);\n };\n\n // Use the exported early exit function with proper type parameter\n const earlyExit = createEarlyExit<E>;\n\n // Local type guard that narrows to EarlyExit<E> specifically\n const isEarlyExitE = (e: unknown): e is EarlyExit<E> => isEarlyExit(e);\n\n const wrapForStep = (\n error: unknown,\n meta?: StepFailureMeta\n ): E | UnexpectedError => {\n if (!wrapMode) {\n return error as E;\n }\n\n if (meta?.origin === \"result\") {\n return {\n type: \"UNEXPECTED_ERROR\",\n cause: {\n type: \"STEP_FAILURE\",\n origin: \"result\",\n error,\n ...(meta.resultCause !== undefined\n ? { cause: meta.resultCause }\n : {}),\n },\n };\n }\n\n if (meta?.origin === \"throw\") {\n return {\n type: \"UNEXPECTED_ERROR\",\n cause: {\n type: \"STEP_FAILURE\",\n origin: \"throw\",\n error,\n thrown: meta.thrown,\n },\n };\n }\n\n return {\n type: \"UNEXPECTED_ERROR\",\n cause: {\n type: \"STEP_FAILURE\",\n origin: \"result\",\n error,\n },\n };\n };\n\n const causeFromMeta = (meta: StepFailureMeta): unknown => {\n if (meta.origin === \"result\") {\n return meta.resultCause;\n }\n return meta.thrown;\n };\n\n const unexpectedFromFailure = (failure: EarlyExit<E>): UnexpectedError => ({\n type: \"UNEXPECTED_ERROR\",\n cause:\n failure.meta.origin === \"result\"\n ? {\n type: \"STEP_FAILURE\" as const,\n origin: \"result\" as const,\n error: failure.error,\n ...(failure.meta.resultCause !== undefined\n ? { cause: failure.meta.resultCause }\n : {}),\n }\n : {\n type: \"STEP_FAILURE\" as const,\n origin: \"throw\" as const,\n error: failure.error,\n thrown: failure.meta.thrown,\n },\n });\n\n try {\n const stepFn = <T, StepE, StepC = unknown>(\n operationOrResult:\n | (() => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>)\n | Result<T, StepE, StepC>\n | AsyncResult<T, StepE, StepC>,\n stepOptions?: StepOptions | string\n ): Promise<T> => {\n return (async () => {\n const parsedOptions = parseStepOptions(stepOptions);\n const { name: stepName, key: stepKey, retry: retryConfig, timeout: timeoutConfig } = parsedOptions;\n const stepId = generateStepId(stepKey);\n const hasEventListeners = onEvent;\n const overallStartTime = hasEventListeners ? performance.now() : 0;\n\n // Validate that retry/timeout are only used with function operations\n // Direct Promise/Result values cannot be re-executed or wrapped with timeout\n const isFunction = typeof operationOrResult === \"function\";\n if (!isFunction) {\n if (retryConfig && retryConfig.attempts > 1) {\n throw new Error(\n `step: retry options require a function operation. ` +\n `Direct Promise/Result values cannot be re-executed on retry. ` +\n `Wrap your operation in a function: step(() => yourOperation, { retry: {...} })`\n );\n }\n if (timeoutConfig) {\n throw new Error(\n `step: timeout options require a function operation. ` +\n `Direct Promise/Result values cannot be wrapped with timeout after they've started. ` +\n `Wrap your operation in a function: step(() => yourOperation, { timeout: {...} })`\n );\n }\n }\n\n // Build effective retry config with defaults\n // Ensure at least 1 attempt (0 would skip the loop entirely and crash)\n const maxAttempts = Math.max(1, retryConfig?.attempts ?? 1);\n const effectiveRetry = {\n attempts: maxAttempts,\n backoff: retryConfig?.backoff ?? DEFAULT_RETRY_CONFIG.backoff,\n initialDelay: retryConfig?.initialDelay ?? DEFAULT_RETRY_CONFIG.initialDelay,\n maxDelay: retryConfig?.maxDelay ?? DEFAULT_RETRY_CONFIG.maxDelay,\n jitter: retryConfig?.jitter ?? DEFAULT_RETRY_CONFIG.jitter,\n retryOn: retryConfig?.retryOn ?? DEFAULT_RETRY_CONFIG.retryOn,\n onRetry: retryConfig?.onRetry ?? DEFAULT_RETRY_CONFIG.onRetry,\n };\n\n // Emit step_start only once (before first attempt)\n if (onEvent) {\n emitEvent({\n type: \"step_start\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n });\n }\n\n let lastResult: Result<T, StepE, StepC> | undefined;\n\n for (let attempt = 1; attempt <= effectiveRetry.attempts; attempt++) {\n const attemptStartTime = hasEventListeners ? performance.now() : 0;\n\n try {\n // Execute operation with optional timeout\n let result: Result<T, StepE, StepC>;\n\n if (typeof operationOrResult === \"function\") {\n if (timeoutConfig) {\n // Wrap with timeout\n result = await executeWithTimeout(\n operationOrResult as () => Promise<Result<T, StepE, StepC>>,\n timeoutConfig,\n { name: stepName, key: stepKey, attempt }\n );\n } else {\n result = await operationOrResult();\n }\n } else {\n // Direct value - timeout doesn't apply\n result = await operationOrResult;\n }\n\n // Success case\n if (result.ok) {\n const durationMs = performance.now() - overallStartTime;\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result,\n });\n }\n return result.value;\n }\n\n // Result error case - check if we should retry\n lastResult = result;\n\n if (attempt < effectiveRetry.attempts && effectiveRetry.retryOn(result.error, attempt)) {\n const delay = calculateRetryDelay(attempt, effectiveRetry);\n\n // Emit retry event\n emitEvent({\n type: \"step_retry\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n attempt: attempt + 1,\n maxAttempts: effectiveRetry.attempts,\n delayMs: delay,\n error: result.error as unknown as E,\n });\n\n effectiveRetry.onRetry(result.error, attempt, delay);\n await sleep(delay);\n continue;\n }\n\n // No more retries or retryOn returned false - emit exhausted event if we retried\n if (effectiveRetry.attempts > 1) {\n emitEvent({\n type: \"step_retries_exhausted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: performance.now() - overallStartTime,\n attempts: attempt,\n lastError: result.error as unknown as E,\n });\n }\n\n // Fall through to final error handling below\n break;\n\n } catch (thrown) {\n const durationMs = performance.now() - attemptStartTime;\n\n // Handle early exit - propagate immediately\n if (isEarlyExitE(thrown)) {\n emitEvent({\n type: \"step_aborted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n throw thrown;\n }\n\n // Handle timeout error\n if (isStepTimeoutError(thrown)) {\n // Get timeout metadata from the error (works for both standard and custom errors)\n const timeoutMeta = getStepTimeoutMeta(thrown);\n const timeoutMs = timeoutConfig?.ms ?? timeoutMeta?.timeoutMs ?? 0;\n emitEvent({\n type: \"step_timeout\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n timeoutMs,\n attempt,\n });\n\n // Check if we should retry after timeout\n if (attempt < effectiveRetry.attempts && effectiveRetry.retryOn(thrown, attempt)) {\n const delay = calculateRetryDelay(attempt, effectiveRetry);\n\n emitEvent({\n type: \"step_retry\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n attempt: attempt + 1,\n maxAttempts: effectiveRetry.attempts,\n delayMs: delay,\n error: thrown as unknown as E,\n });\n\n effectiveRetry.onRetry(thrown, attempt, delay);\n await sleep(delay);\n continue;\n }\n\n // No more retries - emit exhausted if we retried\n if (effectiveRetry.attempts > 1) {\n emitEvent({\n type: \"step_retries_exhausted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: performance.now() - overallStartTime,\n attempts: attempt,\n lastError: thrown as unknown as E,\n });\n }\n\n // Treat timeout as a thrown error for error handling\n }\n\n // Handle other thrown errors (continue to error handling below)\n\n // Check if we should retry thrown errors\n if (attempt < effectiveRetry.attempts && effectiveRetry.retryOn(thrown, attempt)) {\n const delay = calculateRetryDelay(attempt, effectiveRetry);\n\n emitEvent({\n type: \"step_retry\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n attempt: attempt + 1,\n maxAttempts: effectiveRetry.attempts,\n delayMs: delay,\n error: thrown as unknown as E,\n });\n\n effectiveRetry.onRetry(thrown, attempt, delay);\n await sleep(delay);\n continue;\n }\n\n // No more retries for thrown errors - emit exhausted if we retried\n if (effectiveRetry.attempts > 1 && !isStepTimeoutError(thrown)) {\n emitEvent({\n type: \"step_retries_exhausted\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: performance.now() - overallStartTime,\n attempts: attempt,\n lastError: thrown as unknown as E,\n });\n }\n\n // Handle the error based on mode\n const totalDurationMs = performance.now() - overallStartTime;\n\n if (catchUnexpected) {\n let mappedError: E;\n try {\n mappedError = catchUnexpected(thrown) as unknown as E;\n } catch (mapperError) {\n throw createMapperException(mapperError);\n }\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: totalDurationMs,\n error: mappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: totalDurationMs,\n result: err(mappedError, { cause: thrown }),\n meta: { origin: \"throw\", thrown },\n });\n }\n onError?.(mappedError as E, stepName);\n throw earlyExit(mappedError as E, { origin: \"throw\", thrown });\n } else {\n const unexpectedError: UnexpectedError = {\n type: \"UNEXPECTED_ERROR\",\n cause: { type: \"UNCAUGHT_EXCEPTION\", thrown },\n };\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: totalDurationMs,\n error: unexpectedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: totalDurationMs,\n result: err(unexpectedError, { cause: thrown }),\n meta: { origin: \"throw\", thrown },\n });\n }\n throw thrown;\n }\n }\n }\n\n // All retries exhausted with Result error - handle final error\n // At this point lastResult must be an error result (we only reach here on error)\n const errorResult = lastResult as { ok: false; error: StepE; cause?: StepC };\n const totalDurationMs = performance.now() - overallStartTime;\n const wrappedError = wrapForStep(errorResult.error, {\n origin: \"result\",\n resultCause: errorResult.cause,\n });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: totalDurationMs,\n error: wrappedError,\n });\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs: totalDurationMs,\n result: errorResult,\n meta: { origin: \"result\", resultCause: errorResult.cause },\n });\n }\n onError?.(errorResult.error as unknown as E, stepName);\n throw earlyExit(errorResult.error as unknown as E, {\n origin: \"result\",\n resultCause: errorResult.cause,\n });\n })();\n };\n\n stepFn.try = <T, Err>(\n operation: () => T | Promise<T>,\n opts:\n | { error: Err; name?: string; key?: string }\n | { onError: (cause: unknown) => Err; name?: string; key?: string }\n ): Promise<T> => {\n const stepName = opts.name;\n const stepKey = opts.key;\n const stepId = generateStepId(stepKey);\n const mapToError = \"error\" in opts ? () => opts.error : opts.onError;\n const hasEventListeners = onEvent;\n\n return (async () => {\n const startTime = hasEventListeners ? performance.now() : 0;\n\n if (onEvent) {\n emitEvent({\n type: \"step_start\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n });\n }\n\n try {\n const value = await operation();\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n // Emit step_complete for keyed steps (for state persistence)\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: ok(value),\n });\n }\n return value;\n } catch (error) {\n const mapped = mapToError(error);\n const durationMs = performance.now() - startTime;\n const wrappedError = wrapForStep(mapped, { origin: \"throw\", thrown: error });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: wrappedError,\n });\n // Emit step_complete for keyed steps (for state persistence)\n // Note: For step.try errors, we encode the mapped error, not the original thrown\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: err(mapped, { cause: error }),\n meta: { origin: \"throw\", thrown: error },\n });\n }\n onError?.(mapped as unknown as E, stepName);\n throw earlyExit(mapped as unknown as E, { origin: \"throw\", thrown: error });\n }\n })();\n };\n\n // step.fromResult: Execute a Result-returning function and map its typed error\n stepFn.fromResult = <T, ResultE, Err>(\n operation: () => Result<T, ResultE, unknown> | AsyncResult<T, ResultE, unknown>,\n opts:\n | { error: Err; name?: string; key?: string }\n | { onError: (resultError: ResultE) => Err; name?: string; key?: string }\n ): Promise<T> => {\n const stepName = opts.name;\n const stepKey = opts.key;\n const stepId = generateStepId(stepKey);\n const mapToError = \"error\" in opts ? () => opts.error : opts.onError;\n const hasEventListeners = onEvent;\n\n return (async () => {\n const startTime = hasEventListeners ? performance.now() : 0;\n\n if (onEvent) {\n emitEvent({\n type: \"step_start\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n });\n }\n\n const result = await operation();\n\n if (result.ok) {\n const durationMs = performance.now() - startTime;\n emitEvent({\n type: \"step_success\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n });\n // Emit step_complete for keyed steps (for state persistence)\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: ok(result.value),\n });\n }\n return result.value;\n } else {\n const mapped = mapToError(result.error);\n const durationMs = performance.now() - startTime;\n // For fromResult, the cause is the original result.error (what got mapped)\n // This is analogous to step.try using thrown exception as cause\n const wrappedError = wrapForStep(mapped, {\n origin: \"result\",\n resultCause: result.error,\n });\n emitEvent({\n type: \"step_error\",\n workflowId,\n stepId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n error: wrappedError,\n });\n // Emit step_complete for keyed steps (for state persistence)\n if (stepKey) {\n emitEvent({\n type: \"step_complete\",\n workflowId,\n stepKey,\n name: stepName,\n ts: Date.now(),\n durationMs,\n result: err(mapped, { cause: result.error }),\n meta: { origin: \"result\", resultCause: result.error },\n });\n }\n onError?.(mapped as unknown as E, stepName);\n throw earlyExit(mapped as unknown as E, {\n origin: \"result\",\n resultCause: result.error,\n });\n }\n })();\n };\n\n // step.retry: Execute an operation with retry and optional timeout\n stepFn.retry = <T, StepE, StepC = unknown>(\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n options: RetryOptions & { name?: string; key?: string; timeout?: TimeoutOptions }\n ): Promise<T> => {\n // Delegate to stepFn with retry options merged into StepOptions\n return stepFn(operation, {\n name: options.name,\n key: options.key,\n retry: {\n attempts: options.attempts,\n backoff: options.backoff,\n initialDelay: options.initialDelay,\n maxDelay: options.maxDelay,\n jitter: options.jitter,\n retryOn: options.retryOn,\n onRetry: options.onRetry,\n },\n timeout: options.timeout,\n });\n };\n\n // step.withTimeout: Execute an operation with a timeout\n stepFn.withTimeout = <T, StepE, StepC = unknown>(\n operation:\n | (() => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>)\n | ((signal: AbortSignal) => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>),\n options: TimeoutOptions & { name?: string; key?: string }\n ): Promise<T> => {\n // Delegate to stepFn with timeout options\n // The signal handling happens in executeWithTimeout when timeout.signal is true\n return stepFn(\n operation as () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>,\n {\n name: options.name,\n key: options.key,\n timeout: options,\n }\n );\n };\n\n // step.parallel: Execute a parallel operation with scope events\n stepFn.parallel = <T, StepE, StepC>(\n name: string,\n operation: () => Result<T[], StepE, StepC> | AsyncResult<T[], StepE, StepC>\n ): Promise<T[]> => {\n const scopeId = `scope_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n return (async () => {\n const startTime = performance.now();\n let scopeEnded = false;\n\n // Push this scope onto the stack for proper nesting tracking\n activeScopeStack.push({ scopeId, type: \"parallel\" });\n\n // Helper to emit scope_end exactly once\n const emitScopeEnd = () => {\n if (scopeEnded) return;\n scopeEnded = true;\n // Pop this scope from the stack\n const idx = activeScopeStack.findIndex(s => s.scopeId === scopeId);\n if (idx !== -1) activeScopeStack.splice(idx, 1);\n emitEvent({\n type: \"scope_end\",\n workflowId,\n scopeId,\n ts: Date.now(),\n durationMs: performance.now() - startTime,\n });\n };\n\n // Emit scope_start event\n emitEvent({\n type: \"scope_start\",\n workflowId,\n scopeId,\n scopeType: \"parallel\",\n name,\n ts: Date.now(),\n });\n\n try {\n const result = await operation();\n\n // Emit scope_end before processing result\n emitScopeEnd();\n\n if (!result.ok) {\n onError?.(result.error as unknown as E, name);\n throw earlyExit(result.error as unknown as E, {\n origin: \"result\",\n resultCause: result.cause,\n });\n }\n\n return result.value;\n } catch (error) {\n // Always emit scope_end in finally-like fashion\n emitScopeEnd();\n throw error;\n }\n })();\n };\n\n // step.race: Execute a race operation with scope events\n stepFn.race = <T, StepE, StepC>(\n name: string,\n operation: () => Result<T, StepE, StepC> | AsyncResult<T, StepE, StepC>\n ): Promise<T> => {\n const scopeId = `scope_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n return (async () => {\n const startTime = performance.now();\n let scopeEnded = false;\n\n // Push this race scope onto the stack to track the first successful step as winner\n const scopeEntry = { scopeId, type: \"race\" as const, winnerId: undefined as string | undefined };\n activeScopeStack.push(scopeEntry);\n\n // Helper to emit scope_end exactly once, including winnerId\n const emitScopeEnd = () => {\n if (scopeEnded) return;\n scopeEnded = true;\n // Pop this scope from the stack\n const idx = activeScopeStack.findIndex(s => s.scopeId === scopeId);\n if (idx !== -1) activeScopeStack.splice(idx, 1);\n emitEvent({\n type: \"scope_end\",\n workflowId,\n scopeId,\n ts: Date.now(),\n durationMs: performance.now() - startTime,\n winnerId: scopeEntry.winnerId,\n });\n };\n\n // Emit scope_start event\n emitEvent({\n type: \"scope_start\",\n workflowId,\n scopeId,\n scopeType: \"race\",\n name,\n ts: Date.now(),\n });\n\n try {\n const result = await operation();\n\n // Emit scope_end before processing result\n emitScopeEnd();\n\n if (!result.ok) {\n onError?.(result.error as unknown as E, name);\n throw earlyExit(result.error as unknown as E, {\n origin: \"result\",\n resultCause: result.cause,\n });\n }\n\n return result.value;\n } catch (error) {\n // Always emit scope_end in finally-like fashion\n emitScopeEnd();\n throw error;\n }\n })();\n };\n\n // step.allSettled: Execute an allSettled operation with scope events\n stepFn.allSettled = <T, StepE, StepC>(\n name: string,\n operation: () => Result<T[], StepE, StepC> | AsyncResult<T[], StepE, StepC>\n ): Promise<T[]> => {\n const scopeId = `scope_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n return (async () => {\n const startTime = performance.now();\n let scopeEnded = false;\n\n // Push this scope onto the stack for proper nesting tracking\n activeScopeStack.push({ scopeId, type: \"allSettled\" });\n\n // Helper to emit scope_end exactly once\n const emitScopeEnd = () => {\n if (scopeEnded) return;\n scopeEnded = true;\n // Pop this scope from the stack\n const idx = activeScopeStack.findIndex(s => s.scopeId === scopeId);\n if (idx !== -1) activeScopeStack.splice(idx, 1);\n emitEvent({\n type: \"scope_end\",\n workflowId,\n scopeId,\n ts: Date.now(),\n durationMs: performance.now() - startTime,\n });\n };\n\n // Emit scope_start event\n emitEvent({\n type: \"scope_start\",\n workflowId,\n scopeId,\n scopeType: \"allSettled\",\n name,\n ts: Date.now(),\n });\n\n try {\n const result = await operation();\n\n // Emit scope_end before processing result\n emitScopeEnd();\n\n if (!result.ok) {\n onError?.(result.error as unknown as E, name);\n throw earlyExit(result.error as unknown as E, {\n origin: \"result\",\n resultCause: result.cause,\n });\n }\n\n return result.value;\n } catch (error) {\n // Always emit scope_end in finally-like fashion\n emitScopeEnd();\n throw error;\n }\n })();\n };\n\n const step = stepFn as RunStep<E | UnexpectedError>;\n const value = await fn(step);\n return ok(value);\n } catch (error) {\n // If a catchUnexpected mapper threw, propagate without re-processing\n if (isMapperException(error)) {\n throw error.thrown;\n }\n\n if (isEarlyExitE(error)) {\n const failureCause = causeFromMeta(error.meta);\n if (catchUnexpected || onError) {\n return err(error.error, { cause: failureCause });\n }\n // If the error is already an UnexpectedError (e.g., from resumed state),\n // return it directly without wrapping in another STEP_FAILURE\n if (isUnexpectedError(error.error)) {\n return err(error.error, { cause: failureCause });\n }\n const unexpectedError = unexpectedFromFailure(error);\n return err(unexpectedError, { cause: failureCause });\n }\n\n if (catchUnexpected) {\n const mapped = catchUnexpected(error);\n onError?.(mapped, \"unexpected\");\n return err(mapped, { cause: error });\n }\n\n const unexpectedError: UnexpectedError = {\n type: \"UNEXPECTED_ERROR\",\n cause: { type: \"UNCAUGHT_EXCEPTION\", thrown: error },\n };\n onError?.(unexpectedError as unknown as E, \"unexpected\");\n return err(unexpectedError, { cause: error });\n }\n}\n\n/**\n * Executes a workflow in \"Strict Mode\" with a closed error union.\n *\n * ## When to Use\n *\n * Use `run.strict()` when:\n * - You want a closed error union (no `UnexpectedError`)\n * - You need exhaustive error handling in production\n * - You want to guarantee all errors are explicitly typed\n * - You're building APIs where error types must be known\n *\n * ## Why Use This\n *\n * - **Closed union**: Error type is exactly `E`, no `UnexpectedError`\n * - **Exhaustive**: Forces you to handle all possible errors\n * - **Type-safe**: TypeScript ensures all errors are typed\n * - **Production-ready**: Better for APIs and libraries\n *\n * ## Important\n *\n * You MUST provide `catchUnexpected` to map any uncaught exceptions to your error type `E`.\n * This ensures the error union is truly closed.\n *\n * @param fn - The workflow function containing steps\n * @param options - Configuration options, MUST include `catchUnexpected`\n * @returns A Promise resolving to `Result<T, E>` (no UnexpectedError)\n *\n * @example\n * ```typescript\n * type AppError = 'NOT_FOUND' | 'UNAUTHORIZED' | 'UNEXPECTED';\n *\n * const result = await run.strict<User, AppError>(\n * async (step) => {\n * return await step(fetchUser(id));\n * },\n * {\n * catchUnexpected: () => 'UNEXPECTED' as const\n * }\n * );\n * // result.error: 'NOT_FOUND' | 'UNAUTHORIZED' | 'UNEXPECTED' (exactly)\n * ```\n */\nrun.strict = <T, E, C = void>(\n fn: (step: RunStep<E>) => Promise<T> | T,\n options: {\n onError?: (error: E, stepName?: string) => void;\n onEvent?: (event: WorkflowEvent<E | UnexpectedError>, ctx: C) => void;\n catchUnexpected: (cause: unknown) => E;\n workflowId?: string;\n context?: C;\n }\n): AsyncResult<T, E, unknown> => {\n return run<T, E, C>(fn, options);\n};\n\n// =============================================================================\n// Unwrap Utilities\n// =============================================================================\n\n/**\n * Error thrown when `unwrap()` is called on an error Result.\n *\n * This error is thrown to prevent silent failures when using `unwrap()`.\n * Prefer using `unwrapOr`, `unwrapOrElse`, or pattern matching with `match` or `isOk`/`isErr`.\n */\nexport class UnwrapError<E = unknown, C = unknown> extends Error {\n constructor(\n public readonly error: E,\n public readonly cause?: C\n ) {\n super(`Unwrap called on an error result: ${String(error)}`);\n this.name = \"UnwrapError\";\n }\n}\n\n/**\n * Unwraps a Result, throwing an error if it's a failure.\n *\n * ## When to Use\n *\n * Use `unwrap()` when:\n * - You're certain the Result is successful (e.g., after checking with `isOk`)\n * - You're in a context where errors should crash (e.g., tests, initialization)\n * - You need the value immediately and can't handle errors gracefully\n *\n * ## Why Avoid This\n *\n * **Prefer alternatives** in production code:\n * - `unwrapOr(defaultValue)` - Provide a fallback value\n * - `unwrapOrElse(fn)` - Compute fallback from error\n * - `match()` - Handle both cases explicitly\n * - `isOk()` / `isErr()` - Type-safe pattern matching\n *\n * Throwing errors makes error handling harder and can crash your application.\n *\n * @param r - The Result to unwrap\n * @returns The success value if the Result is successful\n * @throws {UnwrapError} If the Result is an error (includes the error and cause)\n *\n * @example\n * ```typescript\n * // Safe usage after checking\n * const result = someOperation();\n * if (isOk(result)) {\n * const value = unwrap(result); // Safe - we know it's ok\n * }\n *\n * // Unsafe usage (not recommended)\n * const value = unwrap(someOperation()); // May throw!\n * ```\n */\nexport const unwrap = <T, E, C>(r: Result<T, E, C>): T => {\n if (r.ok) return r.value;\n throw new UnwrapError<E, C>(r.error, r.cause);\n};\n\n/**\n * Unwraps a Result, returning a default value if it's a failure.\n *\n * ## When to Use\n *\n * Use `unwrapOr()` when:\n * - You have a sensible default value for errors\n * - You want to continue execution even on failure\n * - The default value is cheap to compute (use `unwrapOrElse` if expensive)\n *\n * ## Why Use This\n *\n * - **Safe**: Never throws, always returns a value\n * - **Simple**: One-liner for common error handling\n * - **Type-safe**: TypeScript knows you'll always get a `T`\n *\n * @param r - The Result to unwrap\n * @param defaultValue - The value to return if the Result is an error\n * @returns The success value if successful, otherwise the default value\n *\n * @example\n * ```typescript\n * // Provide default for missing data\n * const user = unwrapOr(fetchUser(id), { id: 'anonymous', name: 'Guest' });\n *\n * // Provide default for numeric operations\n * const count = unwrapOr(parseCount(input), 0);\n *\n * // Provide default for optional features\n * const config = unwrapOr(loadConfig(), getDefaultConfig());\n * ```\n */\nexport const unwrapOr = <T, E, C>(r: Result<T, E, C>, defaultValue: T): T =>\n r.ok ? r.value : defaultValue;\n\n/**\n * Unwraps a Result, computing a default value from the error if it's a failure.\n *\n * ## When to Use\n *\n * Use `unwrapOrElse()` when:\n * - The default value is expensive to compute (lazy evaluation)\n * - You need to log or handle the error before providing a default\n * - The default depends on the error type or cause\n * - You want to transform the error into a success value\n *\n * ## Why Use This Instead of `unwrapOr`\n *\n * - **Lazy**: Default is only computed if needed (better performance)\n * - **Error-aware**: You can inspect the error before providing default\n * - **Flexible**: Default can depend on error type or cause\n *\n * @param r - The Result to unwrap\n * @param fn - Function that receives the error and optional cause, returns the default value\n * @returns The success value if successful, otherwise the result of calling `fn(error, cause)`\n *\n * @example\n * ```typescript\n * // Compute default based on error type\n * const port = unwrapOrElse(parsePort(env.PORT), (error) => {\n * if (error === 'INVALID_FORMAT') return 3000;\n * if (error === 'OUT_OF_RANGE') return 8080;\n * return 4000; // default\n * });\n *\n * // Log error before providing default\n * const data = unwrapOrElse(fetchData(), (error, cause) => {\n * console.error('Failed to fetch:', error, cause);\n * return getCachedData();\n * });\n *\n * // Transform error into success value\n * const result = unwrapOrElse(operation(), (error) => {\n * return { success: false, reason: String(error) };\n * });\n * ```\n */\nexport const unwrapOrElse = <T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => T\n): T => (r.ok ? r.value : fn(r.error, r.cause));\n\n// =============================================================================\n// Wrapping Functions\n// =============================================================================\n\n/**\n * Wraps a synchronous throwing function in a Result.\n *\n * ## When to Use\n *\n * Use `from()` when:\n * - You have a synchronous function that throws exceptions\n * - You want to convert exceptions to typed errors\n * - You're integrating with libraries that throw (e.g., JSON.parse, fs.readFileSync)\n * - You need to handle errors without try/catch blocks\n *\n * ## Why Use This\n *\n * - **Type-safe errors**: Convert thrown exceptions to typed Result errors\n * - **No try/catch**: Cleaner code without nested try/catch blocks\n * - **Composable**: Results can be chained with `andThen`, `map`, etc.\n * - **Explicit errors**: Forces you to handle errors explicitly\n *\n * @param fn - The synchronous function to execute (may throw)\n * @returns A Result with the function's return value or the thrown error\n *\n * @example\n * ```typescript\n * // Wrap JSON.parse\n * const parsed = from(() => JSON.parse('{\"key\": \"value\"}'));\n * // parsed: { ok: true, value: { key: \"value\" } }\n *\n * const error = from(() => JSON.parse('invalid'));\n * // error: { ok: false, error: SyntaxError }\n * ```\n */\nexport function from<T>(fn: () => T): Result<T, unknown>;\n/**\n * Wraps a synchronous throwing function in a Result with custom error mapping.\n *\n * Use this overload when you want to map thrown exceptions to your typed error union.\n *\n * @param fn - The synchronous function to execute (may throw)\n * @param onError - Function to map the thrown exception to a typed error\n * @returns A Result with the function's return value or the mapped error\n *\n * @example\n * ```typescript\n * // Map exceptions to typed errors\n * const parsed = from(\n * () => JSON.parse(input),\n * (cause) => ({ type: 'PARSE_ERROR' as const, cause })\n * );\n * // parsed.error: { type: 'PARSE_ERROR', cause: SyntaxError }\n *\n * // Map to simple error codes\n * const value = from(\n * () => riskyOperation(),\n * () => 'OPERATION_FAILED' as const\n * );\n * ```\n */\nexport function from<T, E>(fn: () => T, onError: (cause: unknown) => E): Result<T, E>;\nexport function from<T, E>(fn: () => T, onError?: (cause: unknown) => E) {\n try {\n return ok(fn());\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Wraps a Promise in a Result, converting rejections to errors.\n *\n * ## When to Use\n *\n * Use `fromPromise()` when:\n * - You have an existing Promise that might reject\n * - You want to convert Promise rejections to typed errors\n * - You're working with libraries that return Promises (fetch, database clients)\n * - You need to handle rejections without .catch() chains\n *\n * ## Why Use This\n *\n * - **Type-safe errors**: Convert Promise rejections to typed Result errors\n * - **Composable**: Results can be chained with `andThen`, `map`, etc.\n * - **Explicit handling**: Forces you to handle errors explicitly\n * - **No .catch() chains**: Cleaner than Promise.catch() patterns\n *\n * @param promise - The Promise to await (may reject)\n * @returns A Promise resolving to a Result with the resolved value or rejection reason\n *\n * @example\n * ```typescript\n * // Wrap fetch\n * const result = await fromPromise(\n * fetch('/api').then(r => r.json())\n * );\n * // result.ok: true if fetch succeeded, false if rejected\n * ```\n */\nexport function fromPromise<T>(promise: Promise<T>): AsyncResult<T, unknown>;\n/**\n * Wraps a Promise in a Result with custom error mapping.\n *\n * Use this overload when you want to map Promise rejections to your typed error union.\n *\n * @param promise - The Promise to await (may reject)\n * @param onError - Function to map the rejection reason to a typed error\n * @returns A Promise resolving to a Result with the resolved value or mapped error\n *\n * @example\n * ```typescript\n * // Map fetch errors to typed errors\n * const result = await fromPromise(\n * fetch('/api').then(r => {\n * if (!r.ok) throw new Error(`HTTP ${r.status}`);\n * return r.json();\n * }),\n * () => 'FETCH_FAILED' as const\n * );\n * // result.error: 'FETCH_FAILED' if fetch failed\n *\n * // Map with error details\n * const data = await fromPromise(\n * db.query(sql),\n * (cause) => ({ type: 'DB_ERROR' as const, message: String(cause) })\n * );\n * ```\n */\nexport function fromPromise<T, E>(\n promise: Promise<T>,\n onError: (cause: unknown) => E\n): AsyncResult<T, E>;\nexport async function fromPromise<T, E>(\n promise: Promise<T>,\n onError?: (cause: unknown) => E\n): AsyncResult<T, E | unknown> {\n try {\n return ok(await promise);\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Wraps an async function in a Result, catching both thrown exceptions and Promise rejections.\n *\n * ## When to Use\n *\n * Use `tryAsync()` when:\n * - You have an async function that might throw or reject\n * - You want to convert both exceptions and rejections to typed errors\n * - You're creating new async functions (use `fromPromise` for existing Promises)\n * - You need to handle errors without try/catch or .catch()\n *\n * ## Why Use This Instead of `fromPromise`\n *\n * - **Function form**: Takes a function, not a Promise (lazy evaluation)\n * - **Catches both**: Handles both thrown exceptions and Promise rejections\n * - **Cleaner syntax**: No need to wrap in Promise manually\n *\n * @param fn - The async function to execute (may throw or reject)\n * @returns A Promise resolving to a Result with the function's return value or error\n *\n * @example\n * ```typescript\n * // Wrap async function\n * const result = await tryAsync(async () => {\n * const data = await fetchData();\n * return processData(data);\n * });\n * ```\n */\nexport function tryAsync<T>(fn: () => Promise<T>): AsyncResult<T, unknown>;\n/**\n * Wraps an async function in a Result with custom error mapping.\n *\n * Use this overload when you want to map errors to your typed error union.\n *\n * @param fn - The async function to execute (may throw or reject)\n * @param onError - Function to map the error (exception or rejection) to a typed error\n * @returns A Promise resolving to a Result with the function's return value or mapped error\n *\n * @example\n * ```typescript\n * // Map errors to typed errors\n * const result = await tryAsync(\n * async () => await fetchData(),\n * () => 'FETCH_ERROR' as const\n * );\n *\n * // Map with error details\n * const data = await tryAsync(\n * async () => await processFile(path),\n * (cause) => ({ type: 'PROCESSING_ERROR' as const, cause })\n * );\n * ```\n */\nexport function tryAsync<T, E>(\n fn: () => Promise<T>,\n onError: (cause: unknown) => E\n): AsyncResult<T, E>;\nexport async function tryAsync<T, E>(\n fn: () => Promise<T>,\n onError?: (cause: unknown) => E\n): AsyncResult<T, E | unknown> {\n try {\n return ok(await fn());\n } catch (cause) {\n return onError ? err(onError(cause), { cause }) : err(cause);\n }\n}\n\n/**\n * Converts a nullable value to a Result.\n *\n * ## When to Use\n *\n * Use `fromNullable()` when:\n * - You have a value that might be `null` or `undefined`\n * - You want to treat null/undefined as an error case\n * - You're working with APIs that return nullable values (DOM APIs, optional properties)\n * - You want to avoid null checks scattered throughout your code\n *\n * ## Why Use This\n *\n * - **Type-safe**: Converts nullable types to non-nullable Results\n * - **Explicit errors**: Forces you to handle null/undefined cases\n * - **Composable**: Results can be chained with `andThen`, `map`, etc.\n * - **No null checks**: Eliminates need for `if (value == null)` checks\n *\n * @param value - The value that may be null or undefined\n * @param onNull - Function that returns an error when value is null/undefined\n * @returns A Result with the value if not null/undefined, otherwise the error from `onNull`\n *\n * @example\n * ```typescript\n * // Convert DOM element lookup\n * const element = fromNullable(\n * document.getElementById('app'),\n * () => 'ELEMENT_NOT_FOUND' as const\n * );\n *\n * // Convert optional property\n * const userId = fromNullable(\n * user.id,\n * () => 'USER_ID_MISSING' as const\n * );\n *\n * // Convert database query result\n * const record = fromNullable(\n * await db.find(id),\n * () => ({ type: 'NOT_FOUND' as const, id })\n * );\n * ```\n */\nexport function fromNullable<T, E>(\n value: T | null | undefined,\n onNull: () => E\n): Result<T, E> {\n return value != null ? ok(value) : err(onNull());\n}\n\n// =============================================================================\n// Transformers\n// =============================================================================\n\n/**\n * Transforms the success value of a Result.\n *\n * ## When to Use\n *\n * Use `map()` when:\n * - You need to transform a success value to another type\n * - You want to apply a pure function to the value\n * - You're building a pipeline of transformations\n * - The transformation cannot fail (use `andThen` if it can fail)\n *\n * ## Why Use This\n *\n * - **Functional style**: Composable, chainable transformations\n * - **Error-preserving**: Errors pass through unchanged\n * - **Type-safe**: TypeScript tracks the transformation\n * - **No unwrapping**: Avoids manual `if (r.ok)` checks\n *\n * @param r - The Result to transform\n * @param fn - Pure function that transforms the success value (must not throw)\n * @returns A new Result with the transformed value, or the original error if `r` was an error\n *\n * @example\n * ```typescript\n * // Transform numeric value\n * const doubled = map(ok(21), n => n * 2);\n * // doubled: { ok: true, value: 42 }\n *\n * // Transform object property\n * const name = map(fetchUser(id), user => user.name);\n *\n * // Chain transformations\n * const formatted = map(\n * map(parseNumber(input), n => n * 2),\n * n => `Result: ${n}`\n * );\n * ```\n */\nexport function map<T, U, E, C>(\n r: Result<T, E, C>,\n fn: (value: T) => U\n): Result<U, E, C> {\n return r.ok ? ok(fn(r.value)) : r;\n}\n\n/**\n * Transforms the error value of a Result.\n *\n * ## When to Use\n *\n * Use `mapError()` when:\n * - You need to normalize or transform error types\n * - You want to convert errors to a different error type\n * - You're building error handling pipelines\n * - You need to format error messages or codes\n *\n * ## Why Use This\n *\n * - **Error normalization**: Convert errors to a common format\n * - **Type transformation**: Change error type while preserving value type\n * - **Composable**: Can be chained with other transformers\n * - **Success-preserving**: Success values pass through unchanged\n *\n * @param r - The Result to transform\n * @param fn - Function that transforms the error value (must not throw)\n * @returns A new Result with the original value, or the transformed error if `r` was an error\n *\n * @example\n * ```typescript\n * // Normalize error codes\n * const normalized = mapError(err('not_found'), e => e.toUpperCase());\n * // normalized: { ok: false, error: 'NOT_FOUND' }\n *\n * // Convert error types\n * const typed = mapError(\n * err('404'),\n * code => ({ type: 'HTTP_ERROR' as const, status: parseInt(code) })\n * );\n *\n * // Format error messages\n * const formatted = mapError(\n * err('PARSE_ERROR'),\n * code => `Failed to parse: ${code}`\n * );\n * ```\n */\nexport function mapError<T, E, F, C>(\n r: Result<T, E, C>,\n fn: (error: E) => F\n): Result<T, F, C> {\n return r.ok ? r : err(fn(r.error), { cause: r.cause });\n}\n\n/**\n * Pattern matches on a Result, calling the appropriate handler.\n *\n * ## When to Use\n *\n * Use `match()` when:\n * - You need to handle both success and error cases\n * - You want to transform a Result to a different type\n * - You need exhaustive handling (both cases must be handled)\n * - You're building user-facing messages or responses\n *\n * ## Why Use This\n *\n * - **Exhaustive**: Forces you to handle both success and error cases\n * - **Type-safe**: TypeScript ensures both handlers are provided\n * - **Functional**: Pattern matching style, similar to Rust's `match` or Haskell's `case`\n * - **Single expression**: Can be used in expressions, not just statements\n *\n * @param r - The Result to match\n * @param handlers - Object with `ok` and `err` handler functions\n * @param handlers.ok - Function called with the success value\n * @param handlers.err - Function called with the error and optional cause\n * @returns The return value of the appropriate handler (both must return the same type `R`)\n *\n * @example\n * ```typescript\n * // Build user-facing messages\n * const message = match(result, {\n * ok: (user) => `Hello ${user.name}`,\n * err: (error) => `Error: ${error}`,\n * });\n *\n * // Transform to API response\n * const response = match(operation(), {\n * ok: (data) => ({ status: 200, body: data }),\n * err: (error) => ({ status: 400, error: String(error) }),\n * });\n *\n * // Handle with cause\n * const response = match(result, {\n * ok: (value) => ({ status: 'success', data: value }),\n * err: (error, cause) => ({ status: 'error', error, cause }),\n * });\n * ```\n */\nexport function match<T, E, C, R>(\n r: Result<T, E, C>,\n handlers: { ok: (value: T) => R; err: (error: E, cause?: C) => R }\n): R {\n return r.ok ? handlers.ok(r.value) : handlers.err(r.error, r.cause);\n}\n\n/**\n * Chains Results together (flatMap/monadic bind).\n *\n * ## When to Use\n *\n * Use `andThen()` when:\n * - You need to chain operations that can fail\n * - The next operation depends on the previous success value\n * - You're building a pipeline of dependent operations\n * - You want to avoid nested `if (r.ok)` checks\n *\n * ## Why Use This Instead of `map`\n *\n * - **Can fail**: The chained function returns a Result (can fail)\n * - **Short-circuits**: If first Result fails, second operation never runs\n * - **Error accumulation**: Errors from both operations are in the union\n * - **Composable**: Can chain multiple operations together\n *\n * ## Common Pattern\n *\n * This is the fundamental building block for Result pipelines:\n * ```typescript\n * andThen(operation1(), value1 =>\n * andThen(operation2(value1), value2 =>\n * ok({ value1, value2 })\n * )\n * )\n * ```\n *\n * @param r - The first Result\n * @param fn - Function that takes the success value and returns a new Result (may fail)\n * @returns The Result from `fn` if `r` was successful, otherwise the original error\n *\n * @example\n * ```typescript\n * // Chain dependent operations\n * const userPosts = andThen(\n * fetchUser('1'),\n * user => fetchPosts(user.id)\n * );\n *\n * // Build complex pipelines\n * const result = andThen(parseInput(input), parsed =>\n * andThen(validate(parsed), validated =>\n * process(validated)\n * )\n * );\n *\n * // Chain with different error types\n * const data = andThen(\n * fetchUser(id), // Returns Result<User, 'FETCH_ERROR'>\n * user => fetchPosts(user.id) // Returns Result<Post[], 'NOT_FOUND'>\n * );\n * // data.error: 'FETCH_ERROR' | 'NOT_FOUND'\n * ```\n */\nexport function andThen<T, U, E, F, C1, C2>(\n r: Result<T, E, C1>,\n fn: (value: T) => Result<U, F, C2>\n): Result<U, E | F, C1 | C2> {\n return r.ok ? fn(r.value) : r;\n}\n\n/**\n * Executes a side effect on a successful Result without changing it.\n *\n * ## When to Use\n *\n * Use `tap()` when:\n * - You need to log, debug, or observe success values\n * - You want to perform side effects in a pipeline\n * - You need to mutate external state based on success\n * - You're debugging and want to inspect values without breaking the chain\n *\n * ## Why Use This\n *\n * - **Non-breaking**: Doesn't change the Result, just performs side effect\n * - **Composable**: Can be inserted anywhere in a pipeline\n * - **Type-preserving**: Returns the same Result type\n * - **Lazy**: Side effect only runs if Result is successful\n *\n * @param r - The Result to tap\n * @param fn - Side effect function called with the success value (return value ignored)\n * @returns The original Result unchanged (for chaining)\n *\n * @example\n * ```typescript\n * // Log success values\n * const logged = tap(result, user => console.log('Got user:', user.name));\n * // logged === result, but console.log was called\n *\n * // Debug in pipeline\n * const debugged = pipe(\n * fetchUser(id),\n * r => tap(r, user => console.log('Fetched:', user)),\n * r => map(r, user => user.name)\n * );\n *\n * // Mutate external state\n * const tracked = tap(result, data => {\n * analytics.track('operation_success', data);\n * });\n * ```\n */\nexport function tap<T, E, C>(\n r: Result<T, E, C>,\n fn: (value: T) => void\n): Result<T, E, C> {\n if (r.ok) fn(r.value);\n return r;\n}\n\n/**\n * Executes a side effect on an error Result without changing it.\n *\n * ## When to Use\n *\n * Use `tapError()` when:\n * - You need to log, debug, or observe error values\n * - You want to perform side effects on errors in a pipeline\n * - You need to report errors to external systems (logging, monitoring)\n * - You're debugging and want to inspect errors without breaking the chain\n *\n * ## Why Use This\n *\n * - **Non-breaking**: Doesn't change the Result, just performs side effect\n * - **Composable**: Can be inserted anywhere in a pipeline\n * - **Type-preserving**: Returns the same Result type\n * - **Lazy**: Side effect only runs if Result is an error\n *\n * @param r - The Result to tap\n * @param fn - Side effect function called with the error and optional cause (return value ignored)\n * @returns The original Result unchanged (for chaining)\n *\n * @example\n * ```typescript\n * // Log errors\n * const logged = tapError(result, (error, cause) => {\n * console.error('Error:', error, cause);\n * });\n *\n * // Report to error tracking\n * const tracked = tapError(result, (error, cause) => {\n * errorTracker.report(error, cause);\n * });\n *\n * // Debug in pipeline\n * const debugged = pipe(\n * operation(),\n * r => tapError(r, (err, cause) => console.error('Failed:', err)),\n * r => mapError(r, err => 'FORMATTED_ERROR')\n * );\n * ```\n */\nexport function tapError<T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => void\n): Result<T, E, C> {\n if (!r.ok) fn(r.error, r.cause);\n return r;\n}\n\n/**\n * Transforms the success value of a Result, catching any errors thrown by the transform.\n *\n * ## When to Use\n *\n * Use `mapTry()` when:\n * - Your transform function might throw exceptions\n * - You want to convert transform errors to typed errors\n * - You're working with libraries that throw (e.g., JSON.parse, Date parsing)\n * - You need to handle both Result errors and transform exceptions\n *\n * ## Why Use This Instead of `map`\n *\n * - **Exception-safe**: Catches exceptions from the transform function\n * - **Error mapping**: Converts thrown exceptions to typed errors\n * - **Dual error handling**: Handles both Result errors and transform exceptions\n *\n * @param result - The Result to transform\n * @param transform - Function to transform the success value (may throw exceptions)\n * @param onError - Function to map thrown exceptions to a typed error\n * @returns A Result with:\n * - Transformed value if both Result and transform succeed\n * - Original error if Result was an error\n * - Transform error if transform threw an exception\n *\n * @example\n * ```typescript\n * // Safe JSON parsing\n * const parsed = mapTry(\n * ok('{\"key\": \"value\"}'),\n * JSON.parse,\n * () => 'PARSE_ERROR' as const\n * );\n *\n * // Safe date parsing\n * const date = mapTry(\n * ok('2024-01-01'),\n * str => new Date(str),\n * () => 'INVALID_DATE' as const\n * );\n *\n * // Transform with error details\n * const processed = mapTry(\n * result,\n * value => riskyTransform(value),\n * (cause) => ({ type: 'TRANSFORM_ERROR' as const, cause })\n * );\n * ```\n */\nexport function mapTry<T, U, E, F, C>(\n result: Result<T, E, C>,\n transform: (value: T) => U,\n onError: (cause: unknown) => F\n): Result<U, E | F, C | unknown> {\n if (!result.ok) return result;\n try {\n return ok(transform(result.value));\n } catch (error) {\n return err(onError(error), { cause: error });\n }\n}\n\n/**\n * Transforms the error value of a Result, catching any errors thrown by the transform.\n *\n * ## When to Use\n *\n * Use `mapErrorTry()` when:\n * - Your error transform function might throw exceptions\n * - You're doing complex error transformations (e.g., string formatting, object construction)\n * - You want to handle both Result errors and transform exceptions\n * - You need to safely normalize error types\n *\n * ## Why Use This Instead of `mapError`\n *\n * - **Exception-safe**: Catches exceptions from the error transform function\n * - **Error mapping**: Converts thrown exceptions to typed errors\n * - **Dual error handling**: Handles both Result errors and transform exceptions\n *\n * @param result - The Result to transform\n * @param transform - Function to transform the error value (may throw exceptions)\n * @param onError - Function to map thrown exceptions to a typed error\n * @returns A Result with:\n * - Original value if Result was successful\n * - Transformed error if both Result was error and transform succeeded\n * - Transform error if transform threw an exception\n *\n * @example\n * ```typescript\n * // Safe error formatting\n * const formatted = mapErrorTry(\n * err('not_found'),\n * e => e.toUpperCase(), // Might throw if e is not a string\n * () => 'FORMAT_ERROR' as const\n * );\n *\n * // Complex error transformation\n * const normalized = mapErrorTry(\n * result,\n * error => ({ type: 'NORMALIZED', message: String(error) }),\n * () => 'TRANSFORM_ERROR' as const\n * );\n * ```\n */\nexport function mapErrorTry<T, E, F, G, C>(\n result: Result<T, E, C>,\n transform: (error: E) => F,\n onError: (cause: unknown) => G\n): Result<T, F | G, C | unknown> {\n if (result.ok) return result;\n try {\n return err(transform(result.error), { cause: result.cause });\n } catch (error) {\n return err(onError(error), { cause: error });\n }\n}\n\n/**\n * Transforms both the success value and error value of a Result simultaneously.\n *\n * ## When to Use\n *\n * Use `bimap()` when:\n * - You need to transform both success and error in one operation\n * - You're normalizing Results to a common format\n * - You want symmetric transformation of both cases\n * - You're building adapters between different Result types\n *\n * ## Why Use This Instead of `map` + `mapError`\n *\n * - **Single operation**: Transforms both cases in one call\n * - **Clearer intent**: Shows you're handling both cases symmetrically\n * - **Less code**: Avoids chaining map and mapError\n *\n * @param r - The Result to transform\n * @param onOk - Function that transforms the success value\n * @param onErr - Function that transforms the error value\n * @returns A new Result with transformed value or transformed error\n *\n * @example\n * ```typescript\n * // Normalize to API response format\n * const response = bimap(\n * fetchUser(id),\n * user => ({ status: 'success', data: user }),\n * error => ({ status: 'error', code: error })\n * );\n *\n * // Transform types\n * const stringified = bimap(\n * parseNumber(input),\n * n => `Value: ${n}`,\n * e => `Error: ${e}`\n * );\n *\n * // Adapt between error types\n * const adapted = bimap(\n * externalResult,\n * value => internalValue(value),\n * error => internalError(error)\n * );\n * ```\n */\nexport function bimap<T, U, E, F, C>(\n r: Result<T, E, C>,\n onOk: (value: T) => U,\n onErr: (error: E) => F\n): Result<U, F, C> {\n return r.ok ? ok(onOk(r.value)) : err(onErr(r.error), { cause: r.cause });\n}\n\n/**\n * Recovers from an error by returning a new Result.\n * Similar to neverthrow's `.orElse()`.\n *\n * ## When to Use\n *\n * Use `orElse()` when:\n * - You want to recover from errors with fallback operations\n * - The recovery might also fail (returns a Result)\n * - You need to chain fallback strategies\n * - You're implementing retry or fallback patterns\n *\n * ## Why Use This\n *\n * - **Fallback chains**: Try alternative operations on failure\n * - **Error recovery**: Convert errors to success with fallback values\n * - **Composable**: Can chain multiple orElse calls for cascading fallbacks\n * - **Type-safe**: TypeScript tracks the error union through recovery\n *\n * @param r - The Result to potentially recover from\n * @param fn - Function that takes the error and returns a new Result (may succeed or fail)\n * @returns The original Result if successful, or the result of the recovery function\n *\n * @example\n * ```typescript\n * // Fallback to default user\n * const user = orElse(\n * fetchUser(id),\n * error => error === 'NOT_FOUND' ? ok(defaultUser) : err(error)\n * );\n *\n * // Try cache, then database, then fail\n * const data = orElse(\n * orElse(\n * fetchFromCache(key),\n * () => fetchFromDatabase(key)\n * ),\n * () => err('DATA_UNAVAILABLE' as const)\n * );\n *\n * // Convert specific errors to success\n * const result = orElse(\n * riskyOperation(),\n * error => error.code === 'RETRY' ? ok(defaultValue) : err(error)\n * );\n * ```\n */\nexport function orElse<T, E, E2, C, C2>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => Result<T, E2, C2>\n): Result<T, E2, C2> {\n return r.ok ? r : fn(r.error, r.cause);\n}\n\n/**\n * Async version of orElse for recovering from errors with async operations.\n *\n * @param r - The Result or AsyncResult to potentially recover from\n * @param fn - Async function that takes the error and returns a new Result\n * @returns Promise of the original Result if successful, or the result of the recovery function\n *\n * @example\n * ```typescript\n * // Try primary API, fall back to secondary\n * const data = await orElseAsync(\n * await fetchFromPrimaryApi(),\n * async (error) => {\n * if (error === 'UNAVAILABLE') {\n * return await fetchFromSecondaryApi();\n * }\n * return err(error);\n * }\n * );\n * ```\n */\nexport async function orElseAsync<T, E, E2, C, C2>(\n r: Result<T, E, C> | Promise<Result<T, E, C>>,\n fn: (error: E, cause?: C) => Result<T, E2, C2> | Promise<Result<T, E2, C2>>\n): Promise<Result<T, E2, C2>> {\n const resolved = await r;\n return resolved.ok ? resolved : fn(resolved.error, resolved.cause);\n}\n\n/**\n * Recovers from an error by returning a plain value (not a Result).\n * Useful when you want to provide a default value on error.\n *\n * ## When to Use\n *\n * Use `recover()` when:\n * - You want to provide a fallback value on error\n * - Recovery cannot fail (unlike orElse which returns a Result)\n * - You're implementing default value patterns\n * - You want to guarantee a successful Result\n *\n * ## Why Use This Instead of `orElse`\n *\n * - **Simpler**: Recovery function returns plain value, not Result\n * - **Guaranteed success**: Always returns ok() after recovery\n * - **Clearer intent**: Shows recovery cannot fail\n *\n * @param r - The Result to potentially recover from\n * @param fn - Function that takes the error and returns a recovery value\n * @returns The original Result if successful, or ok(recoveryValue) if error\n *\n * @example\n * ```typescript\n * // Provide default user on NOT_FOUND\n * const user = recover(\n * fetchUser(id),\n * error => error === 'NOT_FOUND' ? defaultUser : guestUser\n * );\n *\n * // Convert all errors to default\n * const config = recover(\n * loadConfig(),\n * () => defaultConfig\n * );\n *\n * // Recover with error-based defaults\n * const value = recover(\n * parseNumber(input),\n * error => error === 'EMPTY' ? 0 : -1\n * );\n * ```\n */\nexport function recover<T, E, C>(\n r: Result<T, E, C>,\n fn: (error: E, cause?: C) => T\n): Result<T, never, never> {\n return r.ok ? ok(r.value) : ok(fn(r.error, r.cause));\n}\n\n/**\n * Async version of recover for recovering with async operations.\n *\n * @param r - The Result or AsyncResult to potentially recover from\n * @param fn - Async function that takes the error and returns a recovery value\n * @returns Promise of ok(value) - either original or recovered\n *\n * @example\n * ```typescript\n * // Recover by fetching default from API\n * const user = await recoverAsync(\n * await fetchUser(id),\n * async (error) => await fetchDefaultUser()\n * );\n * ```\n */\nexport async function recoverAsync<T, E, C>(\n r: Result<T, E, C> | Promise<Result<T, E, C>>,\n fn: (error: E, cause?: C) => T | Promise<T>\n): Promise<Result<T, never, never>> {\n const resolved = await r;\n if (resolved.ok) return ok(resolved.value);\n return ok(await fn(resolved.error, resolved.cause));\n}\n\n// =============================================================================\n// Batch Operations\n// =============================================================================\n\ntype AllValues<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> ? V : never;\n};\ntype AllErrors<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> ? E : never;\n}[number];\ntype AllCauses<T extends readonly Result<unknown, unknown, unknown>[]> = {\n [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> ? C : never;\n}[number];\n\n/**\n * Combines multiple Results into one, requiring all to succeed.\n *\n * ## When to Use\n *\n * Use `all()` when:\n * - You have multiple independent operations that all must succeed\n * - You want to short-circuit on the first error (fail-fast)\n * - You need all values together (e.g., combining API responses)\n * - Performance matters (stops on first error, doesn't wait for all)\n *\n * ## Why Use This\n *\n * - **Fail-fast**: Stops immediately on first error (better performance)\n * - **Type-safe**: TypeScript infers the array type from input\n * - **Short-circuit**: Doesn't evaluate remaining Results after error\n * - **Composable**: Can be chained with other operations\n *\n * ## Important\n *\n * - **Short-circuits**: Returns first error immediately, doesn't wait for all Results\n * - **All must succeed**: If any Result fails, the entire operation fails\n * - **Use `allSettled`**: If you need to collect all errors (e.g., form validation)\n *\n * @param results - Array of Results to combine (all must succeed)\n * @returns A Result with an array of all success values, or the first error encountered\n *\n * @example\n * ```typescript\n * // Combine multiple successful Results\n * const combined = all([ok(1), ok(2), ok(3)]);\n * // combined: { ok: true, value: [1, 2, 3] }\n *\n * // Short-circuits on first error\n * const error = all([ok(1), err('ERROR'), ok(3)]);\n * // error: { ok: false, error: 'ERROR' }\n * // Note: ok(3) is never evaluated\n *\n * // Combine API responses\n * const data = all([\n * fetchUser(id),\n * fetchPosts(id),\n * fetchComments(id)\n * ]);\n * // data.value: [user, posts, comments] if all succeed\n * ```\n */\nexport function all<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): Result<AllValues<T>, AllErrors<T>, AllCauses<T>> {\n const values: unknown[] = [];\n for (const result of results) {\n if (!result.ok) {\n return result as unknown as Result<AllValues<T>, AllErrors<T>, AllCauses<T>>;\n }\n values.push(result.value);\n }\n return ok(values) as Result<AllValues<T>, AllErrors<T>, AllCauses<T>>;\n}\n\n/**\n * Combines multiple Results or Promises of Results into one (async version of `all`).\n *\n * ## When to Use\n *\n * Use `allAsync()` when:\n * - You have multiple async operations that all must succeed\n * - You want to run operations in parallel (better performance)\n * - You want to short-circuit on the first error (fail-fast)\n * - You need all values together from parallel operations\n *\n * ## Why Use This Instead of `all`\n *\n * - **Parallel execution**: All Promises start immediately (faster)\n * - **Async support**: Works with Promises and AsyncResults\n * - **Promise rejection handling**: Converts Promise rejections to `PromiseRejectedError`\n *\n * ## Important\n *\n * - **Short-circuits**: Returns first error immediately, cancels remaining operations\n * - **Parallel**: All operations start simultaneously (unlike sequential `andThen`)\n * - **Use `allSettledAsync`**: If you need to collect all errors\n *\n * @param results - Array of Results or Promises of Results to combine (all must succeed)\n * @returns A Promise resolving to a Result with an array of all success values, or the first error\n *\n * @example\n * ```typescript\n * // Parallel API calls\n * const combined = await allAsync([\n * fetchUser('1'),\n * fetchPosts('1'),\n * fetchComments('1')\n * ]);\n * // All three calls start simultaneously\n * // combined: { ok: true, value: [user, posts, comments] } if all succeed\n *\n * // Mix Results and Promises\n * const data = await allAsync([\n * ok(cachedUser), // Already resolved\n * fetchPosts(userId), // Promise\n * ]);\n * ```\n */\nexport async function allAsync<\n const T extends readonly (Result<unknown, unknown, unknown> | Promise<Result<unknown, unknown, unknown>>)[]\n>(\n results: T\n): Promise<\n Result<\n { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> | Promise<Result<infer V, unknown, unknown>> ? V : never },\n { [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> | Promise<Result<unknown, infer E, unknown>> ? E : never }[number] | PromiseRejectedError,\n { [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> | Promise<Result<unknown, unknown, infer C>> ? C : never }[number] | PromiseRejectionCause\n >\n> {\n type Values = { [K in keyof T]: T[K] extends Result<infer V, unknown, unknown> | Promise<Result<infer V, unknown, unknown>> ? V : never };\n type Errors = { [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> | Promise<Result<unknown, infer E, unknown>> ? E : never }[number] | PromiseRejectedError;\n type Causes = { [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> | Promise<Result<unknown, unknown, infer C>> ? C : never }[number] | PromiseRejectionCause;\n\n if (results.length === 0) {\n return ok([]) as Result<Values, Errors, Causes>;\n }\n\n return new Promise((resolve) => {\n let settled = false;\n let pendingCount = results.length;\n const values: unknown[] = new Array(results.length);\n\n for (let i = 0; i < results.length; i++) {\n const index = i;\n Promise.resolve(results[index])\n .catch((reason) => err(\n { type: \"PROMISE_REJECTED\" as const, cause: reason },\n { cause: { type: \"PROMISE_REJECTION\" as const, reason } as PromiseRejectionCause }\n ))\n .then((result) => {\n if (settled) return;\n\n if (!result.ok) {\n settled = true;\n resolve(result as Result<Values, Errors, Causes>);\n return;\n }\n\n values[index] = result.value;\n pendingCount--;\n\n if (pendingCount === 0) {\n resolve(ok(values) as Result<Values, Errors, Causes>);\n }\n });\n }\n });\n}\n\nexport type SettledError<E, C = unknown> = { error: E; cause?: C };\n\ntype AllSettledResult<T extends readonly Result<unknown, unknown, unknown>[]> = Result<\n AllValues<T>,\n SettledError<AllErrors<T>, AllCauses<T>>[]\n>;\n\n/**\n * Combines multiple Results, collecting all errors instead of short-circuiting.\n *\n * ## When to Use\n *\n * Use `allSettled()` when:\n * - You need to see ALL errors, not just the first one\n * - You're doing form validation (show all field errors)\n * - You want to collect partial results (some succeed, some fail)\n * - You need to process all Results regardless of failures\n *\n * ## Why Use This Instead of `all`\n *\n * - **Collects all errors**: Returns array of all errors, not just first\n * - **No short-circuit**: Evaluates all Results even if some fail\n * - **Partial success**: Can see which operations succeeded and which failed\n * - **Better UX**: Show users all validation errors at once\n *\n * ## Important\n *\n * - **No short-circuit**: All Results are evaluated (slower if many fail early)\n * - **Error array**: Returns array of `{ error, cause }` objects, not single error\n * - **Use `all`**: If you want fail-fast behavior (better performance)\n *\n * @param results - Array of Results to combine (all are evaluated)\n * @returns A Result with:\n * - Array of all success values if all succeed\n * - Array of `{ error, cause }` objects if any fail\n *\n * @example\n * ```typescript\n * // Form validation - show all errors\n * const validated = allSettled([\n * validateEmail(email),\n * validatePassword(password),\n * validateAge(age),\n * ]);\n * // If email and password fail:\n * // { ok: false, error: [\n * // { error: 'INVALID_EMAIL' },\n * // { error: 'WEAK_PASSWORD' }\n * // ]}\n *\n * // Collect partial results\n * const results = allSettled([\n * fetchUser('1'), // succeeds\n * fetchUser('2'), // fails\n * fetchUser('3'), // succeeds\n * ]);\n * // Can see which succeeded and which failed\n * ```\n */\nexport function allSettled<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): AllSettledResult<T> {\n const values: unknown[] = [];\n const errors: SettledError<unknown>[] = [];\n\n for (const result of results) {\n if (result.ok) {\n values.push(result.value);\n } else {\n errors.push({ error: result.error, cause: result.cause });\n }\n }\n\n if (errors.length > 0) {\n return err(errors) as unknown as AllSettledResult<T>;\n }\n\n return ok(values) as unknown as AllSettledResult<T>;\n}\n\n/**\n * Splits an array of Results into separate arrays of success values and errors.\n *\n * ## When to Use\n *\n * Use `partition()` when:\n * - You have an array of Results and need to separate successes from failures\n * - You want to process successes and errors separately\n * - You're collecting results from multiple operations (some may fail)\n * - You need to handle partial success scenarios\n *\n * ## Why Use This\n *\n * - **Simple separation**: One call splits successes and errors\n * - **Type-safe**: TypeScript knows `values` is `T[]` and `errors` is `E[]`\n * - **No unwrapping**: Doesn't require manual `if (r.ok)` checks\n * - **Preserves order**: Maintains original array order in both arrays\n *\n * ## Common Pattern\n *\n * Often used after `Promise.all()` with Results:\n * ```typescript\n * const results = await Promise.all(ids.map(id => fetchUser(id)));\n * const { values: users, errors } = partition(results);\n * // Process successful users, handle errors separately\n * ```\n *\n * @param results - Array of Results to partition\n * @returns An object with:\n * - `values`: Array of all success values (type `T[]`)\n * - `errors`: Array of all error values (type `E[]`)\n *\n * @example\n * ```typescript\n * // Split successes and errors\n * const results = [ok(1), err('ERROR_1'), ok(3), err('ERROR_2')];\n * const { values, errors } = partition(results);\n * // values: [1, 3]\n * // errors: ['ERROR_1', 'ERROR_2']\n *\n * // Process batch operations\n * const userResults = await Promise.all(userIds.map(id => fetchUser(id)));\n * const { values: users, errors: fetchErrors } = partition(userResults);\n *\n * // Process successful users\n * users.forEach(user => processUser(user));\n *\n * // Handle errors\n * fetchErrors.forEach(error => logError(error));\n * ```\n */\nexport function partition<T, E, C>(\n results: readonly Result<T, E, C>[]\n): { values: T[]; errors: E[] } {\n const values: T[] = [];\n const errors: E[] = [];\n\n for (const result of results) {\n if (result.ok) {\n values.push(result.value);\n } else {\n errors.push(result.error);\n }\n }\n\n return { values, errors };\n}\n\ntype AnyValue<T extends readonly Result<unknown, unknown, unknown>[]> =\n T[number] extends Result<infer U, unknown, unknown> ? U : never;\ntype AnyErrors<T extends readonly Result<unknown, unknown, unknown>[]> = {\n -readonly [K in keyof T]: T[K] extends Result<unknown, infer E, unknown> ? E : never;\n}[number];\ntype AnyCauses<T extends readonly Result<unknown, unknown, unknown>[]> = {\n -readonly [K in keyof T]: T[K] extends Result<unknown, unknown, infer C> ? C : never;\n}[number];\n\n/**\n * Returns the first successful Result from an array (succeeds fast).\n *\n * ## When to Use\n *\n * Use `any()` when:\n * - You have multiple fallback options and need the first that succeeds\n * - You're trying multiple strategies (e.g., cache → DB → API)\n * - You want fail-fast success (stops on first success)\n * - You have redundant data sources and any one will do\n *\n * ## Why Use This\n *\n * - **Succeeds fast**: Returns immediately on first success (better performance)\n * - **Fallback pattern**: Perfect for trying multiple options\n * - **Short-circuits**: Stops evaluating after first success\n * - **Type-safe**: TypeScript infers the success type\n *\n * ## Important\n *\n * - **First success wins**: Returns first successful Result, ignores rest\n * - **All errors**: If all fail, returns first error (not all errors)\n * - **Empty array**: Returns `EmptyInputError` if array is empty\n * - **Use `all`**: If you need ALL to succeed\n *\n * @param results - Array of Results to check (evaluated in order)\n * @returns The first successful Result, or first error if all fail, or `EmptyInputError` if empty\n *\n * @example\n * ```typescript\n * // Try multiple fallback strategies\n * const data = any([\n * fetchFromCache(id),\n * fetchFromDB(id),\n * fetchFromAPI(id)\n * ]);\n * // Returns first that succeeds\n *\n * // Try multiple formats\n * const parsed = any([\n * parseJSON(input),\n * parseXML(input),\n * parseYAML(input)\n * ]);\n *\n * // All errors case\n * const allErrors = any([err('A'), err('B'), err('C')]);\n * // allErrors: { ok: false, error: 'A' } (first error)\n * ```\n */\nexport function any<const T extends readonly Result<unknown, unknown, unknown>[]>(\n results: T\n): Result<AnyValue<T>, AnyErrors<T> | EmptyInputError, AnyCauses<T>> {\n type ReturnErr = Result<never, AnyErrors<T> | EmptyInputError, AnyCauses<T>>;\n type ReturnOk = Result<AnyValue<T>, never, AnyCauses<T>>;\n\n if (results.length === 0) {\n return err({\n type: \"EMPTY_INPUT\",\n message: \"any() requires at least one Result\",\n }) as ReturnErr;\n }\n let firstError: Result<never, unknown, unknown> | null = null;\n for (const result of results) {\n if (result.ok) return result as ReturnOk;\n if (!firstError) firstError = result;\n }\n return firstError as ReturnErr;\n}\n\ntype AnyAsyncValue<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> =\n Awaited<T[number]> extends Result<infer U, unknown, unknown> ? U : never;\ntype AnyAsyncErrors<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n -readonly [K in keyof T]: Awaited<T[K]> extends Result<unknown, infer E, unknown>\n ? E\n : never;\n}[number];\ntype AnyAsyncCauses<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n -readonly [K in keyof T]: Awaited<T[K]> extends Result<unknown, unknown, infer C>\n ? C\n : never;\n}[number];\n\n/**\n * Returns the first successful Result from an array of Results or Promises (async version of `any`).\n *\n * ## When to Use\n *\n * Use `anyAsync()` when:\n * - You have multiple async fallback options and need the first that succeeds\n * - You're trying multiple async strategies in parallel (cache → DB → API)\n * - You want fail-fast success from parallel operations\n * - You have redundant async data sources and any one will do\n *\n * ## Why Use This Instead of `any`\n *\n * - **Parallel execution**: All Promises start immediately (faster)\n * - **Async support**: Works with Promises and AsyncResults\n * - **Promise rejection handling**: Converts Promise rejections to `PromiseRejectedError`\n *\n * ## Important\n *\n * - **First success wins**: Returns first successful Result (from any Promise)\n * - **Parallel**: All operations run simultaneously\n * - **All errors**: If all fail, returns first error encountered\n *\n * @param results - Array of Results or Promises of Results to check (all start in parallel)\n * @returns A Promise resolving to the first successful Result, or first error if all fail\n *\n * @example\n * ```typescript\n * // Try multiple async fallbacks in parallel\n * const data = await anyAsync([\n * fetchFromCache(id), // Fastest wins\n * fetchFromDB(id),\n * fetchFromAPI(id)\n * ]);\n *\n * // Try multiple API endpoints\n * const response = await anyAsync([\n * fetch('/api/v1/data'),\n * fetch('/api/v2/data'),\n * fetch('/backup-api/data')\n * ]);\n * ```\n */\nexport async function anyAsync<\n const T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[],\n>(\n results: T\n): Promise<\n Result<AnyAsyncValue<T>, AnyAsyncErrors<T> | EmptyInputError | PromiseRejectedError, AnyAsyncCauses<T> | PromiseRejectionCause>\n> {\n type ReturnErr = Result<\n never,\n AnyAsyncErrors<T> | EmptyInputError | PromiseRejectedError,\n AnyAsyncCauses<T> | PromiseRejectionCause\n >;\n type ReturnOk = Result<AnyAsyncValue<T>, never, AnyAsyncCauses<T>>;\n\n if (results.length === 0) {\n return err({\n type: \"EMPTY_INPUT\",\n message: \"anyAsync() requires at least one Result\",\n }) as ReturnErr;\n }\n\n return new Promise((resolve) => {\n let settled = false;\n let pendingCount = results.length;\n let firstError: Result<never, unknown, unknown> | null = null;\n\n for (const item of results) {\n Promise.resolve(item)\n .catch((reason) =>\n err(\n { type: \"PROMISE_REJECTED\" as const, cause: reason },\n { cause: { type: \"PROMISE_REJECTION\" as const, reason } as PromiseRejectionCause }\n )\n )\n .then((result) => {\n if (settled) return;\n\n if (result.ok) {\n settled = true;\n resolve(result as ReturnOk);\n return;\n }\n\n if (!firstError) firstError = result;\n pendingCount--;\n\n if (pendingCount === 0) {\n resolve(firstError as ReturnErr);\n }\n });\n }\n });\n}\n\ntype AllAsyncValues<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n [K in keyof T]: Awaited<T[K]> extends Result<infer V, unknown, unknown> ? V : never;\n};\ntype AllAsyncErrors<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n [K in keyof T]: Awaited<T[K]> extends Result<unknown, infer E, unknown> ? E : never;\n}[number];\ntype AllAsyncCauses<T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[]> = {\n [K in keyof T]: Awaited<T[K]> extends Result<unknown, unknown, infer C> ? C : never;\n}[number];\n\n/**\n * Combines multiple Results or Promises of Results, collecting all errors (async version of `allSettled`).\n *\n * ## When to Use\n *\n * Use `allSettledAsync()` when:\n * - You have multiple async operations and need ALL errors\n * - You're doing async form validation (show all field errors)\n * - You want to run operations in parallel and collect all results\n * - You need partial results from parallel operations\n *\n * ## Why Use This Instead of `allSettled`\n *\n * - **Parallel execution**: All Promises start immediately (faster)\n * - **Async support**: Works with Promises and AsyncResults\n * - **Promise rejection handling**: Converts Promise rejections to `PromiseRejectedError`\n *\n * ## Important\n *\n * - **No short-circuit**: All operations complete (even if some fail)\n * - **Parallel**: All operations run simultaneously\n * - **Error array**: Returns array of `{ error, cause }` objects\n *\n * @param results - Array of Results or Promises of Results to combine (all are evaluated)\n * @returns A Promise resolving to a Result with:\n * - Array of all success values if all succeed\n * - Array of `{ error, cause }` objects if any fail\n *\n * @example\n * ```typescript\n * // Async form validation\n * const validated = await allSettledAsync([\n * validateEmailAsync(email),\n * validatePasswordAsync(password),\n * checkUsernameAvailableAsync(username),\n * ]);\n *\n * // Parallel API calls with error collection\n * const results = await allSettledAsync([\n * fetchUser('1'),\n * fetchUser('2'),\n * fetchUser('3'),\n * ]);\n * // Can see which succeeded and which failed\n * ```\n */\nexport async function allSettledAsync<\n const T extends readonly MaybeAsyncResult<unknown, unknown, unknown>[],\n>(\n results: T\n): Promise<Result<AllAsyncValues<T>, SettledError<AllAsyncErrors<T> | PromiseRejectedError, AllAsyncCauses<T> | PromiseRejectionCause>[]>> {\n const settled = await Promise.all(\n results.map((item) =>\n Promise.resolve(item)\n .then((result) => ({ status: \"result\" as const, result }))\n .catch((reason) => ({\n status: \"rejected\" as const,\n error: { type: \"PROMISE_REJECTED\" as const, cause: reason } as PromiseRejectedError,\n cause: { type: \"PROMISE_REJECTION\" as const, reason } as PromiseRejectionCause,\n }))\n )\n );\n\n const values: unknown[] = [];\n const errors: SettledError<unknown, unknown>[] = [];\n\n for (const item of settled) {\n if (item.status === \"rejected\") {\n errors.push({ error: item.error, cause: item.cause });\n } else if (item.result.ok) {\n values.push(item.result.value);\n } else {\n errors.push({ error: item.result.error, cause: item.result.cause });\n }\n }\n\n if (errors.length > 0) {\n return err(errors) as unknown as Result<AllAsyncValues<T>, SettledError<AllAsyncErrors<T> | PromiseRejectedError, AllAsyncCauses<T> | PromiseRejectionCause>[]>;\n }\n return ok(values) as unknown as Result<AllAsyncValues<T>, SettledError<AllAsyncErrors<T> | PromiseRejectedError, AllAsyncCauses<T> | PromiseRejectionCause>[]>;\n}\n"],"mappings":"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","names":["core_exports","__export","EARLY_EXIT_SYMBOL","STEP_TIMEOUT_MARKER","UnwrapError","all","allAsync","allSettled","allSettledAsync","andThen","any","anyAsync","bimap","createEarlyExit","err","from","fromNullable","fromPromise","getStepTimeoutMeta","isEarlyExit","isErr","isOk","isStepTimeoutError","isUnexpectedError","map","mapError","mapErrorTry","mapTry","match","ok","orElse","orElseAsync","partition","recover","recoverAsync","run","tap","tapError","tryAsync","unwrap","unwrapOr","unwrapOrElse","__toCommonJS","value","error","options","r","meta","MAPPER_EXCEPTION_SYMBOL","createMapperException","thrown","isMapperException","parseStepOptions","calculateRetryDelay","attempt","backoff","initialDelay","maxDelay","jitter","delay","jitterAmount","sleep","ms","resolve","TIMEOUT_SYMBOL","executeWithTimeout","operation","stepInfo","controller","timeoutError","timeoutId","timeoutPromise","_","reject","operationPromise","errorToThrow","DEFAULT_RETRY_CONFIG","fn","onError","onEvent","catchUnexpected","providedWorkflowId","context","workflowId","wrapMode","activeScopeStack","stepIdCounter","generateStepId","stepKey","emitEvent","event","stepId","i","scope","earlyExit","isEarlyExitE","e","wrapForStep","causeFromMeta","unexpectedFromFailure","failure","stepFn","operationOrResult","stepOptions","parsedOptions","stepName","retryConfig","timeoutConfig","hasEventListeners","overallStartTime","effectiveRetry","lastResult","attemptStartTime","result","durationMs","timeoutMeta","timeoutMs","totalDurationMs","mappedError","mapperError","unexpectedError","errorResult","wrappedError","opts","mapToError","startTime","mapped","name","scopeId","scopeEnded","emitScopeEnd","idx","s","scopeEntry","failureCause","cause","defaultValue","promise","onNull","handlers","transform","onOk","onErr","resolved","results","values","settled","pendingCount","index","reason","errors","firstError","item"]}
|