runsheet 0.6.0 → 0.7.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 +244 -198
- package/dist/index.cjs +175 -285
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -140
- package/dist/index.d.ts +64 -140
- package/dist/index.js +173 -280
- package/dist/index.js.map +1 -1
- package/llms.txt +38 -90
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/internal.ts","../src/define-step.ts","../src/builder.ts","../src/middleware.ts","../src/when.ts","../src/pipeline.ts","../src/parallel.ts","../src/choice.ts","../src/map.ts","../src/filter.ts","../src/flat-map.ts"],"sourcesContent":["export { defineStep } from './define-step.js';\nexport {\n RunsheetError,\n RequiresValidationError,\n ProvidesValidationError,\n ArgsValidationError,\n PredicateError,\n TimeoutError,\n RetryExhaustedError,\n StrictOverlapError,\n ChoiceNoMatchError,\n RollbackError,\n UnknownError,\n} from './errors.js';\nexport type { RunsheetErrorCode } from './errors.js';\nexport { pipeline } from './pipeline.js';\nexport type { PipelineConfig } from './pipeline.js';\nexport { when } from './when.js';\nexport type { ConditionalStep } from './when.js';\nexport { parallel } from './parallel.js';\nexport { choice } from './choice.js';\nexport { map } from './map.js';\nexport { filter } from './filter.js';\nexport { flatMap } from './flat-map.js';\nexport type { StepMiddleware, StepInfo, StepExecutor } from './middleware.js';\nexport type { PipelineBuilder } from './builder.js';\n\nexport type {\n Step,\n TypedStep,\n AggregateStep,\n StepConfig,\n StepContext,\n StepOutput,\n StepSchema,\n ExtractRequires,\n ExtractProvides,\n RetryPolicy,\n StepResult,\n StepSuccess,\n StepFailure,\n StepMeta,\n AggregateResult,\n AggregateSuccess,\n AggregateFailure,\n AggregateMeta,\n RollbackReport,\n RollbackFailure,\n} from './types.js';\n","/**\n * Error codes for errors produced by the runsheet library itself.\n *\n * Use these to distinguish library errors from application errors:\n *\n * ```ts\n * if (!result.success) {\n * if (result.error instanceof RunsheetError) {\n * console.log(result.error.code); // 'REQUIRES_VALIDATION', etc.\n * }\n * }\n * ```\n */\nexport type RunsheetErrorCode =\n | 'REQUIRES_VALIDATION'\n | 'PROVIDES_VALIDATION'\n | 'ARGS_VALIDATION'\n | 'PREDICATE'\n | 'TIMEOUT'\n | 'RETRY_EXHAUSTED'\n | 'STRICT_OVERLAP'\n | 'CHOICE_NO_MATCH'\n | 'ROLLBACK'\n | 'UNKNOWN';\n\n/**\n * Base error class for all errors produced by the runsheet library.\n *\n * Application errors (thrown by step `run` or `rollback` functions)\n * are never wrapped in `RunsheetError` — they pass through as-is.\n * If you see a `RunsheetError` as `result.error`, the library itself\n * produced it.\n *\n * Use `instanceof RunsheetError` to distinguish library errors from\n * application errors. Use `instanceof` on a subclass (e.g.,\n * `TimeoutError`) or check the `code` property for specific failures.\n */\nexport class RunsheetError extends Error {\n /** Discriminant code identifying the type of library error. */\n readonly code: RunsheetErrorCode;\n\n /**\n * @param code - The error code.\n * @param message - A human-readable description of the failure.\n */\n constructor(code: RunsheetErrorCode, message: string) {\n super(message);\n this.name = 'RunsheetError';\n this.code = code;\n }\n}\n\n/** Schema validation failed on the accumulated context before a step ran. */\nexport class RequiresValidationError extends RunsheetError {\n constructor(message: string) {\n super('REQUIRES_VALIDATION', message);\n this.name = 'RequiresValidationError';\n }\n}\n\n/** Schema validation failed on a step's output after it ran. */\nexport class ProvidesValidationError extends RunsheetError {\n constructor(message: string) {\n super('PROVIDES_VALIDATION', message);\n this.name = 'ProvidesValidationError';\n }\n}\n\n/** Schema validation failed on the pipeline's input arguments. */\nexport class ArgsValidationError extends RunsheetError {\n constructor(message: string) {\n super('ARGS_VALIDATION', message);\n this.name = 'ArgsValidationError';\n }\n}\n\n/** A `when()` or `choice()` predicate threw an error. */\nexport class PredicateError extends RunsheetError {\n constructor(message: string) {\n super('PREDICATE', message);\n this.name = 'PredicateError';\n }\n}\n\n/** A step exceeded its configured timeout. */\nexport class TimeoutError extends RunsheetError {\n /** The timeout duration in milliseconds that was exceeded. */\n readonly timeoutMs: number;\n\n constructor(message: string, timeoutMs: number) {\n super('TIMEOUT', message);\n this.name = 'TimeoutError';\n this.timeoutMs = timeoutMs;\n }\n}\n\n/** A step failed after exhausting all retry attempts. */\nexport class RetryExhaustedError extends RunsheetError {\n /** Total number of attempts (initial + retries). */\n readonly attempts: number;\n\n constructor(message: string, attempts: number) {\n super('RETRY_EXHAUSTED', message);\n this.name = 'RetryExhaustedError';\n this.attempts = attempts;\n }\n}\n\n/** Two steps provide the same key (strict mode, detected at build time). */\nexport class StrictOverlapError extends RunsheetError {\n /** The key that is provided by multiple steps. */\n readonly key: string;\n /** The names of the two steps that both provide the key. */\n readonly steps: readonly [string, string];\n\n constructor(message: string, key: string, steps: readonly [string, string]) {\n super('STRICT_OVERLAP', message);\n this.name = 'StrictOverlapError';\n this.key = key;\n this.steps = steps;\n }\n}\n\n/** No branch matched in a `choice()` step. */\nexport class ChoiceNoMatchError extends RunsheetError {\n constructor(message: string) {\n super('CHOICE_NO_MATCH', message);\n this.name = 'ChoiceNoMatchError';\n }\n}\n\n/** A non-Error value was thrown and caught by the pipeline engine. */\nexport class UnknownError extends RunsheetError {\n /** The original thrown value before stringification. */\n readonly originalValue: unknown;\n\n constructor(message: string, originalValue: unknown) {\n super('UNKNOWN', message);\n this.name = 'UnknownError';\n this.originalValue = originalValue;\n }\n}\n\n/** One or more rollback handlers failed in a combinator. */\nexport class RollbackError extends RunsheetError {\n /** The individual errors from each failed rollback handler. */\n readonly causes: readonly Error[];\n\n constructor(message: string, causes: readonly Error[] = []) {\n super('ROLLBACK', message);\n this.name = 'RollbackError';\n this.causes = causes;\n this.cause = causes.length === 1 ? causes[0] : new AggregateError(causes, message);\n }\n}\n","import type {\n AggregateFailure,\n AggregateMeta,\n AggregateSuccess,\n RollbackReport,\n Step,\n StepContext,\n StepMeta,\n StepFailure,\n StepSuccess,\n StepOutput,\n} from './types.js';\nimport { UnknownError } from './errors.js';\n\n/** Ensure a type satisfies StepContext, falling back to StepContext. */\nexport type AsContext<T> = T extends StepContext ? T : StepContext;\n\n/** Normalize an unknown thrown value to an Error instance. */\nexport function toError(err: unknown): Error {\n if (err instanceof Error) return err;\n return new UnknownError(String(err), err);\n}\n\n/** Empty rollback report for single-step failures. */\nexport const EMPTY_ROLLBACK: RollbackReport = Object.freeze({\n completed: Object.freeze([] as string[]),\n failed: Object.freeze([] as never[]),\n});\n\n/** Format schema validation issues into a human-readable string. */\nexport function formatIssues(\n issues: readonly { path: readonly (string | number)[]; message: string }[],\n): string {\n return issues.map((i) => `${i.path.join('.')}: ${i.message}`).join(', ');\n}\n\n/**\n * Collapse an array of errors into a single error.\n *\n * Returns the sole error when there is exactly one, otherwise wraps\n * them in an `AggregateError` with the given message.\n */\nexport function collapseErrors(errors: Error[], message: string): Error {\n return errors.length === 1 ? errors[0] : new AggregateError(errors, message);\n}\n\n/**\n * Create a frozen {@link Step} object with `undefined` defaults for\n * omitted optional fields.\n *\n * Centralises the construction so that if `Step` gains new properties,\n * only this helper needs updating.\n */\nexport function createStepObject(fields: {\n name: string;\n run: Step['run'];\n rollback?: Step['rollback'];\n requires?: Step['requires'];\n provides?: Step['provides'];\n retry?: Step['retry'];\n timeout?: Step['timeout'];\n}): Step {\n return Object.freeze({\n name: fields.name,\n requires: fields.requires ?? undefined,\n provides: fields.provides ?? undefined,\n run: fields.run,\n rollback: fields.rollback ?? undefined,\n retry: fields.retry ?? undefined,\n timeout: fields.timeout ?? undefined,\n });\n}\n\n/**\n * Create a {@link StepMeta} for a step execution.\n *\n * Used by `defineStep` and collection combinators. Contains only\n * the step's name and the arguments it received.\n */\nexport function baseMeta(name: string, args: Readonly<StepContext>): StepMeta {\n return Object.freeze({ name, args });\n}\n\n/**\n * Create an {@link AggregateMeta} for an orchestrator execution.\n *\n * Used by `pipeline`, `parallel`, and `choice` to produce results\n * with orchestration detail (which steps ran).\n */\nexport function aggregateMeta(\n name: string,\n args: Readonly<StepContext>,\n stepsExecuted: readonly string[],\n): AggregateMeta {\n return Object.freeze({ name, args, stepsExecuted });\n}\n\n/**\n * Create a successful {@link StepResult}.\n *\n * The returned object is frozen (immutable). Used by `defineStep`\n * and collection combinators to produce consistent success results.\n */\nexport function stepSuccess<T extends StepOutput>(data: T, meta: StepMeta): StepSuccess<T> {\n return Object.freeze({ success: true, data, meta });\n}\n\n/**\n * Create a failed {@link StepResult}.\n *\n * The returned object is frozen (immutable). When no rollback\n * report is provided, defaults to {@link EMPTY_ROLLBACK} (no\n * rollbacks attempted).\n */\nexport function stepFailure(\n error: Error,\n meta: StepMeta,\n failedStep: string,\n rollback: RollbackReport = EMPTY_ROLLBACK,\n): StepFailure {\n return Object.freeze({ success: false, error, meta, failedStep, rollback });\n}\n\n/**\n * Create a successful {@link AggregateResult}.\n *\n * Like {@link stepSuccess} but with {@link AggregateMeta}.\n */\nexport function aggregateSuccess<T extends StepOutput>(\n data: T,\n meta: AggregateMeta,\n): AggregateSuccess<T> {\n return Object.freeze({ success: true, data, meta });\n}\n\n/**\n * Create a failed {@link AggregateResult}.\n *\n * Like {@link stepFailure} but with {@link AggregateMeta}.\n */\nexport function aggregateFailure(\n error: Error,\n meta: AggregateMeta,\n failedStep: string,\n rollback: RollbackReport = EMPTY_ROLLBACK,\n): AggregateFailure {\n return Object.freeze({ success: false, error, meta, failedStep, rollback });\n}\n","import type {\n RetryPolicy,\n StepConfig,\n StepContext,\n StepOutput,\n StepResult,\n Step,\n TypedStep,\n} from './types.js';\nimport {\n RequiresValidationError,\n ProvidesValidationError,\n TimeoutError,\n RetryExhaustedError,\n} from './errors.js';\nimport {\n toError,\n baseMeta,\n stepSuccess,\n stepFailure,\n formatIssues,\n createStepObject,\n} from './internal.js';\n\n// ---------------------------------------------------------------------------\n// Timeout and retry wrappers\n// ---------------------------------------------------------------------------\n\n// NOTE: Promise.race doesn't cancel the underlying run — if the timer wins,\n// the step's side effects continue in the background. True cancellation\n// would require AbortSignal propagation into step run functions.\n// Timer functions — declared here to avoid depending on @types/node or DOM lib\ndeclare function setTimeout(callback: () => void, ms: number): unknown;\ndeclare function clearTimeout(handle: unknown): void;\n\nfunction withTimeout<T>(fn: () => T | Promise<T>, stepName: string, ms: number): () => Promise<T> {\n return async () => {\n let timer: unknown;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n reject(new TimeoutError(`${stepName} timed out after ${ms}ms`, ms));\n }, ms);\n });\n try {\n return await Promise.race([Promise.resolve(fn()), timeout]);\n } finally {\n clearTimeout(timer);\n }\n };\n}\n\nfunction computeDelay(policy: RetryPolicy, attempt: number): number {\n const base = policy.delay ?? 0;\n if (base === 0) return 0;\n const strategy = policy.backoff ?? 'linear';\n return strategy === 'exponential' ? base * 2 ** (attempt - 1) : base * attempt;\n}\n\nfunction withRetry<T>(\n fn: () => Promise<T>,\n stepName: string,\n policy: RetryPolicy,\n): () => Promise<T> {\n return async () => {\n let lastError: Error;\n const errors: Error[] = [];\n\n try {\n return await fn();\n } catch (err) {\n lastError = toError(err);\n errors.push(lastError);\n }\n\n for (let attempt = 1; attempt <= policy.count; attempt++) {\n if (policy.retryIf && !policy.retryIf(errors)) throw lastError!;\n\n const delay = computeDelay(policy, attempt);\n if (delay > 0) await new Promise((r) => setTimeout(() => r(undefined), delay));\n\n try {\n return await fn();\n } catch (err) {\n lastError = toError(err);\n errors.push(lastError);\n }\n }\n\n const error = new RetryExhaustedError(\n `${stepName} failed after ${policy.count} retries`,\n policy.count + 1,\n );\n error.cause = errors;\n throw error;\n };\n}\n\nfunction buildExecutor<Requires extends StepContext, Provides extends StepContext>(\n config: StepConfig<Requires, Provides>,\n): (ctx: Readonly<Requires>) => Promise<Provides> {\n let fn = (ctx: Readonly<Requires>) => Promise.resolve(config.run(ctx));\n if (config.timeout !== undefined) {\n const baseFn = fn;\n const ms = config.timeout;\n fn = (ctx) => withTimeout(() => baseFn(ctx), config.name, ms)();\n }\n if (config.retry !== undefined) {\n const baseFn = fn;\n const policy = config.retry;\n fn = (ctx) => withRetry(() => baseFn(ctx), config.name, policy)();\n }\n return fn;\n}\n\n// ---------------------------------------------------------------------------\n// defineStep\n// ---------------------------------------------------------------------------\n\n/**\n * Define a pipeline step.\n *\n * Returns a frozen {@link TypedStep} with concrete types for `run`,\n * `rollback`, `requires`, and `provides`. The `run` function can be\n * sync or async — both are supported.\n *\n * **With schemas** (runtime validation + type inference):\n * ```ts\n * const charge = defineStep({\n * name: 'charge',\n * requires: z.object({ amount: z.number() }),\n * provides: z.object({ chargeId: z.string() }),\n * run: async (ctx) => ({ chargeId: 'ch_123' }),\n * });\n * ```\n *\n * **With generics only** (no runtime validation):\n * ```ts\n * const log = defineStep<{ order: Order }, { loggedAt: Date }>({\n * name: 'log',\n * run: async (ctx) => ({ loggedAt: new Date() }),\n * });\n * ```\n *\n * **Invariants:**\n * - The returned step object is always frozen (immutable).\n * - The `run` function catches thrown errors and produces\n * `StepResult` values. Step authors should throw to signal failure.\n * - This is the single type-erasure cast point in the library.\n *\n * @typeParam Requires - The context shape this step reads from.\n * @typeParam Provides - The output shape this step produces.\n * @param config - The step configuration. See {@link StepConfig}.\n * @returns A frozen {@link TypedStep} ready for use in pipelines.\n */\nexport function defineStep<Requires extends StepContext, Provides extends StepContext>(\n config: StepConfig<Requires, Provides>,\n): TypedStep<Requires, Provides> {\n const execute = buildExecutor(config);\n\n const run = async (ctx: Readonly<StepContext>): Promise<StepResult<StepOutput>> => {\n const frozenCtx = Object.freeze({ ...ctx });\n const meta = baseMeta(config.name, frozenCtx);\n\n // Validate requires\n if (config.requires) {\n const parsed = config.requires.safeParse(frozenCtx);\n if (!parsed.success) {\n const error = new RequiresValidationError(\n `${config.name} requires: ${formatIssues(parsed.error.issues)}`,\n );\n return stepFailure(error, meta, config.name);\n }\n }\n\n // Execute (with retry + timeout)\n let data: Provides;\n try {\n data = await execute(frozenCtx as Readonly<Requires>);\n } catch (err) {\n return stepFailure(toError(err), meta, config.name);\n }\n\n // Validate provides\n if (config.provides) {\n const parsed = config.provides.safeParse(data);\n if (!parsed.success) {\n const error = new ProvidesValidationError(\n `${config.name} provides: ${formatIssues(parsed.error.issues)}`,\n );\n return stepFailure(error, meta, config.name);\n }\n }\n\n return stepSuccess(data as unknown as StepOutput, meta);\n };\n\n return createStepObject({\n name: config.name,\n requires: config.requires,\n provides: config.provides,\n run: run as unknown as Step['run'],\n rollback: config.rollback\n ? async (ctx: Readonly<StepContext>, output: Readonly<StepContext>) => {\n await config.rollback!(ctx as Readonly<Requires>, output as Readonly<Provides>);\n }\n : undefined,\n retry: config.retry,\n timeout: config.timeout,\n }) as TypedStep<Requires, Provides>;\n}\n","import type {\n AggregateStep,\n ExtractProvides,\n ExtractRequires,\n Step,\n StepContext,\n StepSchema,\n} from './types.js';\nimport type { StepMiddleware } from './middleware.js';\nimport { buildPipelineStep } from './pipeline.js';\n\n// ---------------------------------------------------------------------------\n// Builder types\n// ---------------------------------------------------------------------------\n\n/**\n * A fluent pipeline builder that progressively narrows the accumulated\n * context type as steps are added.\n *\n * Each method returns a new, frozen builder — builders are immutable.\n *\n * This means you can safely fork a builder to create variants:\n *\n * ```ts\n * const base = pipeline({ name: 'order' }).step(validate);\n * const withCharge = base.step(charge).build();\n * const withoutCharge = base.build(); // unaffected by the fork\n * ```\n *\n * @typeParam Args - The pipeline's initial input type.\n * @typeParam Ctx - The accumulated context type so far (grows with each `.step()`).\n */\nexport type PipelineBuilder<Args extends StepContext, Ctx extends StepContext> = {\n /**\n * Add a step to the pipeline.\n *\n * The step's `Requires` type must be satisfied by the current `Ctx`\n * (checked via phantom brands — a step that requires less than `Ctx`\n * is always accepted). The returned builder's `Ctx` expands to\n * include the step's `Provides`.\n *\n * @typeParam S - The step type being added.\n * @param step - A {@link Step} (from `defineStep`, `when`, `pipeline`, etc.).\n * @returns A new builder with the expanded context type.\n */\n readonly step: <S extends Step>(\n step: S & ([Ctx] extends [ExtractRequires<S>] ? unknown : never),\n ) => PipelineBuilder<Args, Ctx & ExtractProvides<S>>;\n\n /**\n * Add middleware to the pipeline.\n *\n * Middleware is applied to every step. Multiple `.use()` calls\n * accumulate — earlier middleware is outermost (executes first).\n *\n * @param middleware - One or more {@link StepMiddleware} functions.\n * @returns A new builder with the middleware added.\n */\n readonly use: (...middleware: StepMiddleware[]) => PipelineBuilder<Args, Ctx>;\n\n /**\n * Build the pipeline. Returns an {@link AggregateStep} — pipelines\n * are steps whose `run()` returns {@link AggregateResult}.\n */\n readonly build: () => AggregateStep<Args, Ctx>;\n};\n\n// ---------------------------------------------------------------------------\n// Internal builder state (immutable — each method returns a new builder)\n// ---------------------------------------------------------------------------\n\n/** @internal */\nexport type BuilderState = {\n readonly name: string;\n readonly steps: readonly Step[];\n readonly middleware: readonly StepMiddleware[];\n readonly argsSchema: StepSchema<StepContext> | undefined;\n readonly strict: boolean;\n};\n\n/** @internal */\nexport function makeBuilder<Args extends StepContext, Ctx extends StepContext>(\n state: BuilderState,\n): PipelineBuilder<Args, Ctx> {\n return Object.freeze({\n step: <S extends Step>(step: S) =>\n makeBuilder<Args, Ctx & ExtractProvides<S>>({\n ...state,\n steps: [...state.steps, step],\n }),\n\n use: (...middleware: StepMiddleware[]) =>\n makeBuilder<Args, Ctx>({\n ...state,\n middleware: [...state.middleware, ...middleware],\n }),\n\n build: () =>\n buildPipelineStep({\n name: state.name,\n steps: state.steps,\n middleware: state.middleware.length > 0 ? state.middleware : undefined,\n argsSchema: state.argsSchema as StepSchema<Args> | undefined,\n strict: state.strict || undefined,\n }) as AggregateStep<Args, Ctx>,\n });\n}\n","import type { Step, StepContext, StepOutput, StepResult } from './types.js';\n\n/**\n * Metadata about the step being executed, passed to middleware.\n *\n * This is a read-only view of the step's public configuration.\n * Middleware can use it for logging, metrics, or conditional behavior.\n */\nexport type StepInfo = {\n /** The step's name. */\n readonly name: string;\n /** The step's requires schema, or `undefined` if not provided. */\n readonly requires: Step['requires'];\n /** The step's provides schema, or `undefined` if not provided. */\n readonly provides: Step['provides'];\n};\n\n/**\n * A function that executes a step (or the next middleware in the chain).\n *\n * Receives the frozen accumulated context and returns a {@link StepResult}.\n */\nexport type StepExecutor = (ctx: Readonly<StepContext>) => Promise<StepResult<StepOutput>>;\n\n/**\n * Middleware that wraps the entire step lifecycle, including schema\n * validation.\n *\n * A middleware receives the step metadata and a `next` function, and\n * returns a new executor. Call `next(ctx)` to proceed to the next\n * middleware (or the actual step execution). You can:\n *\n * - **Observe**: read the context or result for logging/metrics.\n * - **Transform**: modify the result before returning it.\n * - **Short-circuit**: return a `StepResult` without calling `next`.\n *\n * If a middleware throws, the pipeline catches it and treats it as a\n * step failure (triggering rollback for previously completed steps).\n *\n * @example\n * ```ts\n * const timing: StepMiddleware = (step, next) => async (ctx) => {\n * const start = performance.now();\n * const result = await next(ctx);\n * console.log(`${step.name}: ${performance.now() - start}ms`);\n * return result;\n * };\n * ```\n *\n * @param step - Metadata about the step being wrapped.\n * @param next - The next executor in the chain. Call it to continue.\n * @returns A new executor that wraps `next`.\n */\nexport type StepMiddleware = (step: StepInfo, next: StepExecutor) => StepExecutor;\n\n/**\n * Compose an array of middlewares around a step executor.\n *\n * First middleware in the array is the outermost wrapper (executes\n * first on the way in, last on the way out).\n *\n * @param middlewares - Middleware functions, in declaration order.\n * @param step - Metadata about the step being wrapped.\n * @param executor - The base step executor to wrap.\n * @returns A composed executor with all middleware applied.\n */\nexport function applyMiddleware(\n middlewares: readonly StepMiddleware[],\n step: StepInfo,\n executor: StepExecutor,\n): StepExecutor {\n return middlewares.reduceRight<StepExecutor>((next, mw) => mw(step, next), executor);\n}\n","import type { Step, StepContext, TypedStep } from './types.js';\nimport { createStepObject } from './internal.js';\n\n/**\n * A step with a conditional predicate attached.\n *\n * The pipeline engine checks for the `predicate` property to decide\n * whether to execute or skip the step. Use the {@link when} function\n * to create conditional steps — don't construct this type directly.\n */\nexport type ConditionalStep = Step & {\n /** Returns `true` to execute the step, `false` to skip it. */\n readonly predicate: (ctx: Readonly<StepContext>) => boolean;\n};\n\n/**\n * Wrap a step with a guard predicate.\n *\n * The step only executes when the predicate returns `true`. When\n * skipped:\n * - No context snapshot is taken.\n * - No rollback entry is created.\n * - The step name is not recorded in the pipeline's `meta.stepsExecuted`.\n *\n * @param predicate - Guard function. Return `true` to execute, `false` to skip.\n * @param step - The step to conditionally execute.\n * @returns A frozen {@link TypedStep} with the predicate attached.\n */\nexport function when<Requires extends StepContext, Provides extends StepContext>(\n predicate: (ctx: Readonly<Requires>) => boolean,\n step: TypedStep<Requires, Provides>,\n): TypedStep<Requires, Provides> {\n const base = createStepObject({\n name: step.name,\n run: step.run,\n rollback: step.rollback,\n requires: step.requires,\n provides: step.provides,\n retry: step.retry,\n timeout: step.timeout,\n });\n // createStepObject returns a frozen object, so we must build a new\n // object that includes the predicate and freeze it ourselves.\n return Object.freeze({\n ...base,\n predicate: predicate as ConditionalStep['predicate'],\n }) as unknown as TypedStep<Requires, Provides>;\n}\n\n/** Type guard for conditional steps. */\nexport function isConditionalStep(step: Step): step is ConditionalStep {\n return 'predicate' in step && typeof step.predicate === 'function';\n}\n","import type {\n AggregateResult,\n AggregateStep,\n ExtractProvides,\n RollbackFailure,\n RollbackReport,\n Step,\n StepContext,\n StepOutput,\n StepResult,\n StepSchema,\n UnionToIntersection,\n} from './types.js';\nimport type { StepMiddleware } from './middleware.js';\nimport type { PipelineBuilder } from './builder.js';\n// Circular import: builder.ts → buildPipelineStep (here), pipeline.ts →\n// makeBuilder (builder.ts). Safe in ESM because both are function\n// declarations — they're available by the time any function is called.\nimport { makeBuilder } from './builder.js';\nimport { applyMiddleware } from './middleware.js';\nimport { ArgsValidationError, PredicateError, StrictOverlapError } from './errors.js';\nimport {\n toError,\n aggregateMeta,\n aggregateSuccess,\n aggregateFailure,\n formatIssues,\n createStepObject,\n} from './internal.js';\nimport { isConditionalStep } from './when.js';\n\n// ---------------------------------------------------------------------------\n// Pipeline configuration\n// ---------------------------------------------------------------------------\n\n/**\n * Internal configuration shape for the pipeline engine.\n *\n * Users typically don't construct this directly — use `pipeline()`.\n */\nexport type PipelineConfig = {\n /** Pipeline name, used in execution metadata and error messages. */\n readonly name: string;\n /** Steps to execute in order. */\n readonly steps: readonly Step[];\n /** Optional middleware applied to every step. First in array = outermost. */\n readonly middleware?: readonly StepMiddleware[];\n /** Optional schema that validates the pipeline's input arguments. */\n readonly argsSchema?: StepSchema<StepContext>;\n /**\n * When `true`, throws at build time if two or more steps provide the\n * same key. Only checks steps that have a `provides` schema with an\n * inspectable `.shape` property (e.g., Zod objects). Steps without\n * provides schemas are not checked.\n */\n readonly strict?: boolean;\n};\n\n// ---------------------------------------------------------------------------\n// Strict mode — detect provides key collisions at build time\n// ---------------------------------------------------------------------------\n\nfunction checkStrictOverlap(steps: readonly Step[]): void {\n const seen = new Map<string, string>(); // key → step name\n\n for (const step of steps) {\n if (!step.provides) continue;\n\n // Extract keys from schemas that expose .shape (e.g., Zod objects)\n const shape = (step.provides as Record<string, unknown>).shape;\n if (!shape || typeof shape !== 'object') continue;\n\n for (const key of Object.keys(shape)) {\n const existing = seen.get(key);\n if (existing) {\n throw new StrictOverlapError(\n `strict mode: key \"${key}\" is provided by both \"${existing}\" and \"${step.name}\"`,\n key,\n [existing, step.name],\n );\n }\n seen.set(key, step.name);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Execution state — accumulated during pipeline run\n// ---------------------------------------------------------------------------\n\n/** Record of a step that executed successfully during a pipeline run. */\ntype ExecutedStepEntry = {\n step: Step;\n snapshot: StepContext;\n output: StepOutput;\n};\n\n/** Mutable state accumulated during pipeline execution. */\ntype ExecutionState = {\n context: StepContext;\n readonly executed: ExecutedStepEntry[];\n readonly stepsExecuted: string[];\n};\n\nfunction createExecutionState(args: StepContext): ExecutionState {\n return {\n context: Object.freeze({ ...args }),\n executed: [],\n stepsExecuted: [],\n };\n}\n\n// ---------------------------------------------------------------------------\n// Rollback\n// ---------------------------------------------------------------------------\n\n/**\n * Execute rollback handlers for previously completed steps in reverse\n * order. Best-effort: if a handler throws, remaining rollbacks still\n * execute. Returns a report of what succeeded and what failed.\n */\nasync function executeRollback(executed: readonly ExecutedStepEntry[]): Promise<RollbackReport> {\n const completed: string[] = [];\n const failed: RollbackFailure[] = [];\n\n for (let i = executed.length - 1; i >= 0; i--) {\n const entry = executed[i];\n if (!entry.step.rollback) continue;\n\n try {\n await entry.step.rollback(entry.snapshot, entry.output);\n completed.push(entry.step.name);\n } catch (err) {\n failed.push({ step: entry.step.name, error: toError(err) });\n }\n }\n\n return Object.freeze({ completed, failed });\n}\n\n// ---------------------------------------------------------------------------\n// Pipeline execution\n// ---------------------------------------------------------------------------\n\n/**\n * Internal result of pipeline execution, pairing the user-facing\n * {@link AggregateResult} with the execution state needed for\n * rollback when this pipeline is used as a step in an outer pipeline.\n */\ntype ExecutionOutcome = {\n result: AggregateResult<StepContext>;\n state: ExecutionState;\n};\n\n/**\n * Core pipeline execution loop.\n *\n * Runs steps sequentially, accumulating context. On failure,\n * executes rollback for previously completed steps. Returns both\n * the result and the execution state (for nested pipeline rollback).\n */\nasync function executePipeline(\n config: PipelineConfig,\n args: StepContext,\n): Promise<ExecutionOutcome> {\n const frozenArgs = Object.freeze({ ...args });\n\n // Validate pipeline args if schema provided\n if (config.argsSchema) {\n const parsed = config.argsSchema.safeParse(frozenArgs);\n if (!parsed.success) {\n const error = new ArgsValidationError(\n `${config.name} args: ${formatIssues(parsed.error.issues)}`,\n );\n const meta = aggregateMeta(config.name, frozenArgs, []);\n const state = createExecutionState(frozenArgs);\n return { result: aggregateFailure(error, meta, config.name), state };\n }\n }\n\n const state = createExecutionState(frozenArgs);\n const middlewares = config.middleware ?? [];\n\n for (const step of config.steps) {\n // Evaluate conditional predicate\n try {\n if (isConditionalStep(step) && !step.predicate(state.context)) {\n continue;\n }\n } catch (err) {\n const cause = toError(err);\n const error = new PredicateError(`${step.name} predicate: ${cause.message}`);\n error.cause = cause;\n const rollback = await executeRollback(state.executed);\n const meta = aggregateMeta(config.name, frozenArgs, [...state.stepsExecuted]);\n return { result: aggregateFailure(error, meta, step.name, rollback), state };\n }\n\n // Snapshot pre-step context\n const snapshot = state.context;\n\n // Wrap step.run with middleware\n const executor =\n middlewares.length > 0\n ? applyMiddleware(\n middlewares,\n { name: step.name, requires: step.requires, provides: step.provides },\n (ctx) => step.run(ctx),\n )\n : (ctx: Readonly<StepContext>) => step.run(ctx);\n\n // Execute\n let result: StepResult<StepOutput>;\n try {\n result = await executor(state.context);\n } catch (err) {\n const error = toError(err);\n const rollback = await executeRollback(state.executed);\n const meta = aggregateMeta(config.name, frozenArgs, [...state.stepsExecuted]);\n return { result: aggregateFailure(error, meta, step.name, rollback), state };\n }\n\n if (!result.success) {\n const rollback = await executeRollback(state.executed);\n const meta = aggregateMeta(config.name, frozenArgs, [...state.stepsExecuted]);\n return { result: aggregateFailure(result.error, meta, step.name, rollback), state };\n }\n\n // Track and accumulate\n const output = result.data;\n state.executed.push({ step, snapshot, output });\n state.stepsExecuted.push(step.name);\n state.context = Object.freeze({ ...state.context, ...output });\n }\n\n const meta = aggregateMeta(config.name, frozenArgs, [...state.stepsExecuted]);\n return { result: aggregateSuccess(state.context, meta), state };\n}\n\n// ---------------------------------------------------------------------------\n// Build an AggregateStep from a PipelineConfig\n// ---------------------------------------------------------------------------\n\n/** @internal — used by the builder; not part of the public API. */\nexport function buildPipelineStep<Args extends StepContext, S extends Step>(config: {\n readonly name: string;\n readonly steps: readonly S[];\n readonly middleware?: readonly StepMiddleware[];\n readonly argsSchema?: StepSchema<Args>;\n readonly strict?: boolean;\n}): AggregateStep<Args, Args & UnionToIntersection<ExtractProvides<S>>> {\n if (config.strict) checkStrictOverlap(config.steps);\n\n const pipelineConfig: PipelineConfig = config as PipelineConfig;\n\n // Track per-execution state for rollback when used as a nested step.\n // INVARIANT: This relies on pipeline.ts storing the exact result.data\n // reference in its outputs array. If the pipeline ever clones\n // result.data, this WeakMap lookup will silently fail.\n // Exercised by the reentrancy test in pipeline.test.ts (\"handles\n // reentrancy — parallel pipelines roll back independently\").\n const stateMap = new WeakMap<object, ExecutionState>();\n\n const run = async (ctx: Readonly<StepContext>): Promise<AggregateResult<StepOutput>> => {\n const outcome = await executePipeline(pipelineConfig, ctx as StepContext);\n if (outcome.result.success) {\n stateMap.set(outcome.result.data, outcome.state);\n }\n return outcome.result;\n };\n\n const rollback = async (_ctx: Readonly<StepContext>, output: Readonly<StepOutput>) => {\n const state = stateMap.get(output);\n if (state) {\n stateMap.delete(output);\n await executeRollback(state.executed);\n }\n };\n\n return createStepObject({\n name: config.name,\n requires: config.argsSchema,\n run,\n rollback,\n }) as unknown as AggregateStep<Args, Args & UnionToIntersection<ExtractProvides<S>>>;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Create a pipeline — either directly from steps, or via the fluent\n * builder API.\n *\n * **With steps** — returns an {@link AggregateStep} immediately:\n *\n * ```ts\n * const checkout = pipeline({\n * name: 'checkout',\n * steps: [validateOrder, chargePayment, sendConfirmation],\n * middleware: [logging, timing],\n * argsSchema: z.object({ orderId: z.string() }),\n * });\n * ```\n *\n * **Without steps** — returns a {@link PipelineBuilder} with\n * progressive type narrowing:\n *\n * ```ts\n * const checkout = pipeline({ name: 'checkout' })\n * .step(validateOrder)\n * .step(chargePayment)\n * .build();\n *\n * // With schema (runtime validation):\n * pipeline({\n * name: 'checkout',\n * argsSchema: z.object({ orderId: z.string() }),\n * }).step(validateOrder).build();\n *\n * // Type-only args (no runtime validation):\n * pipeline<{ orderId: string }>({ name: 'checkout' })\n * .step(validateOrder)\n * .build();\n * ```\n *\n * Pipelines ARE steps — they can be used directly in another\n * pipeline's steps array for composition.\n */\n\n// Overload: with steps → AggregateStep\nexport function pipeline<Args extends StepContext = StepContext, S extends Step = Step>(config: {\n readonly name: string;\n readonly steps: readonly S[];\n readonly middleware?: readonly StepMiddleware[];\n readonly argsSchema?: StepSchema<Args>;\n readonly strict?: boolean;\n}): AggregateStep<Args, Args & UnionToIntersection<ExtractProvides<S>>>;\n\n// Overload: without steps → PipelineBuilder\nexport function pipeline<Args extends StepContext = StepContext>(config: {\n readonly name: string;\n readonly middleware?: readonly StepMiddleware[];\n readonly argsSchema?: StepSchema<Args>;\n readonly strict?: boolean;\n}): PipelineBuilder<Args, Args>;\n\n// Implementation\nexport function pipeline<Args extends StepContext, S extends Step = Step>(config: {\n readonly name: string;\n readonly steps?: readonly S[];\n readonly middleware?: readonly StepMiddleware[];\n readonly argsSchema?: StepSchema<Args>;\n readonly strict?: boolean;\n}):\n | AggregateStep<Args, Args & UnionToIntersection<ExtractProvides<S>>>\n | PipelineBuilder<Args, Args> {\n // With steps → build immediately\n if (config.steps) {\n return buildPipelineStep(\n config as {\n readonly name: string;\n readonly steps: readonly S[];\n readonly middleware?: readonly StepMiddleware[];\n readonly argsSchema?: StepSchema<Args>;\n readonly strict?: boolean;\n },\n );\n }\n\n // Without steps → return builder\n return makeBuilder<Args, Args>({\n name: config.name,\n steps: [],\n middleware: config.middleware ? [...config.middleware] : [],\n argsSchema: config.argsSchema,\n strict: config.strict ?? false,\n });\n}\n","import type {\n AggregateResult,\n AggregateStep,\n ExtractProvides,\n ExtractRequires,\n Step,\n StepContext,\n StepOutput,\n UnionToIntersection,\n} from './types.js';\nimport type { AsContext } from './internal.js';\nimport {\n toError,\n aggregateMeta,\n aggregateSuccess,\n aggregateFailure,\n collapseErrors,\n createStepObject,\n} from './internal.js';\nimport { PredicateError, RollbackError } from './errors.js';\nimport { isConditionalStep } from './when.js';\n\n// ---------------------------------------------------------------------------\n// Inner step execution result\n// ---------------------------------------------------------------------------\n\ntype InnerResult = {\n step: Step;\n skipped: boolean;\n output?: StepOutput;\n error?: Error;\n};\n\n// ---------------------------------------------------------------------------\n// Execute a single inner step (with conditional check)\n// ---------------------------------------------------------------------------\n\nasync function executeInner(step: Step, ctx: Readonly<StepContext>): Promise<InnerResult> {\n // Conditional check\n try {\n if (isConditionalStep(step) && !step.predicate(ctx)) {\n return { step, skipped: true };\n }\n } catch (err) {\n const cause = toError(err);\n const error = new PredicateError(`${step.name} predicate: ${cause.message}`);\n error.cause = cause;\n return { step, skipped: false, error };\n }\n\n const result = await step.run(ctx);\n if (!result.success) return { step, skipped: false, error: result.error };\n return { step, skipped: false, output: result.data };\n}\n\n// ---------------------------------------------------------------------------\n// parallel()\n// ---------------------------------------------------------------------------\n\n/**\n * Run multiple steps concurrently and merge their outputs.\n *\n * All inner steps receive the same pre-parallel context snapshot and\n * execute via `Promise.allSettled`. On success, outputs are merged in\n * array order (deterministic). On partial failure, succeeded inner\n * steps are rolled back in reverse array order before the failure\n * propagates.\n *\n * Returns an {@link AggregateStep} with orchestration metadata\n * tracking which inner steps executed.\n *\n * Inner steps retain their own `requires`/`provides` validation,\n * `retry`, and `timeout` behavior. Conditional steps (via `when()`)\n * are evaluated per inner step.\n *\n * @example\n * ```ts\n * const p = pipeline({\n * name: 'checkout',\n * steps: [\n * validateOrder,\n * parallel(reserveInventory, chargePayment),\n * sendConfirmation,\n * ],\n * });\n * ```\n *\n * @param steps - Two or more steps to execute concurrently.\n * @returns A frozen {@link AggregateStep} whose `Requires` is the\n * intersection of all inner steps' requires, and `Provides` is the\n * intersection of all inner steps' provides.\n */\nexport function parallel<S extends readonly Step[]>(\n ...steps: [...S]\n): AggregateStep<\n AsContext<UnionToIntersection<ExtractRequires<S[number]>>>,\n AsContext<UnionToIntersection<ExtractProvides<S[number]>>>\n> {\n const name = `parallel(${steps.map((s) => s.name).join(', ')})`;\n const innerSteps: readonly Step[] = steps;\n\n // ----- run: execute all inner steps concurrently ----- //\n const run = async (ctx: Readonly<StepContext>): Promise<AggregateResult<StepOutput>> => {\n const frozenCtx = Object.freeze({ ...ctx });\n\n const settled = await Promise.allSettled(\n innerSteps.map((step) => executeInner(step, frozenCtx)),\n );\n\n const succeeded: { step: Step; output: StepOutput }[] = [];\n const allErrors: Error[] = [];\n const executed: string[] = [];\n\n for (const s of settled) {\n if (s.status === 'rejected') {\n allErrors.push(toError(s.reason));\n } else {\n const r = s.value;\n if (r.skipped) continue;\n if (r.output) {\n succeeded.push({ step: r.step, output: r.output });\n executed.push(r.step.name);\n } else if (r.error) {\n allErrors.push(r.error);\n }\n }\n }\n\n if (allErrors.length > 0) {\n // Rollback succeeded inner steps in reverse array order (best-effort)\n for (let i = succeeded.length - 1; i >= 0; i--) {\n const { step, output } = succeeded[i];\n if (step.rollback) {\n try {\n await step.rollback(frozenCtx, output);\n } catch {\n // Best-effort — inner rollback errors during partial failure\n // are not surfaced. The pipeline's own rollback report covers\n // the parallel step as a whole.\n }\n }\n }\n const error = collapseErrors(allErrors, `${name}: ${allErrors.length} step(s) failed`);\n const meta = aggregateMeta(name, frozenCtx, executed);\n return aggregateFailure(error, meta, name);\n }\n\n // Merge outputs in array order (deterministic)\n const merged: StepOutput = {};\n for (const { output } of succeeded) {\n Object.assign(merged, output);\n }\n\n // Track which inner steps executed and their individual outputs\n // for outer rollback. Individual outputs are needed so that nested\n // pipeline rollback handlers can look up their per-execution state.\n executedMap.set(\n merged,\n succeeded.map((s) => ({ step: s.step, output: s.output })),\n );\n\n const meta = aggregateMeta(name, frozenCtx, executed);\n return aggregateSuccess(merged, meta);\n };\n\n // Track which inner steps ran per execution for outer rollback.\n // INVARIANT: This relies on pipeline.ts storing the exact result.data\n // reference in its outputs array. If the pipeline ever clones\n // result.data, this WeakMap lookup will silently fail.\n // Exercised by parallel.test.ts (\"rolls back all inner steps when\n // a later sequential step fails\").\n type ExecutedEntry = { step: Step; output: StepOutput };\n const executedMap = new WeakMap<object, ExecutedEntry[]>();\n\n // ----- rollback: called when a later sequential step fails ----- //\n // The pipeline passes the merged output. Only inner steps that\n // actually executed are rolled back, and each receives its own\n // individual output (not the merged superset).\n // Rollback is called by the outer pipeline when a later step fails.\n // The thrown RollbackError is intentional — the pipeline's own\n // executeRollback loop catches it and records it in result.rollback.failed.\n const rollback: NonNullable<Step['rollback']> = async (ctx, mergedOutput) => {\n const entries = executedMap.get(mergedOutput);\n if (!entries) return;\n executedMap.delete(mergedOutput);\n const errors: Error[] = [];\n for (let i = entries.length - 1; i >= 0; i--) {\n const { step, output } = entries[i];\n if (!step.rollback) continue;\n try {\n await step.rollback(ctx, output);\n } catch (err) {\n errors.push(toError(err));\n }\n }\n if (errors.length > 0) {\n throw new RollbackError(`${name}: ${errors.length} rollback(s) failed`, errors);\n }\n };\n\n return createStepObject({\n name,\n run,\n rollback,\n }) as unknown as AggregateStep<\n AsContext<UnionToIntersection<ExtractRequires<S[number]>>>,\n AsContext<UnionToIntersection<ExtractProvides<S[number]>>>\n >;\n}\n","import type {\n AggregateResult,\n AggregateStep,\n ExtractProvides,\n ExtractRequires,\n Step,\n StepContext,\n StepOutput,\n UnionToIntersection,\n} from './types.js';\nimport type { AsContext } from './internal.js';\nimport {\n toError,\n aggregateMeta,\n aggregateSuccess,\n aggregateFailure,\n createStepObject,\n} from './internal.js';\nimport { ChoiceNoMatchError, PredicateError, RollbackError } from './errors.js';\n\n/** A [predicate, step] tuple used by {@link choice}. */\ntype BranchTuple = readonly [(ctx: Readonly<StepContext>) => boolean, Step];\n\n/** Extract the Requires type from a branch tuple's step. */\ntype BranchRequires<T> = T extends readonly [unknown, infer S extends Step]\n ? ExtractRequires<S>\n : T extends Step\n ? ExtractRequires<T>\n : StepContext;\n\n/** Extract the Provides type from a branch tuple's step. */\ntype BranchProvides<T> = T extends readonly [unknown, infer S extends Step]\n ? ExtractProvides<S>\n : T extends Step\n ? ExtractProvides<T>\n : StepContext;\n\n// ---------------------------------------------------------------------------\n// Normalize args: convert trailing bare step into a [() => true, step] tuple\n// ---------------------------------------------------------------------------\n\ntype NormalizedBranch = readonly [(ctx: Readonly<StepContext>) => boolean, Step];\n\nfunction normalizeBranches(args: readonly (BranchTuple | Step)[]): readonly NormalizedBranch[] {\n return args.map((arg): NormalizedBranch => {\n if (Array.isArray(arg)) return arg as NormalizedBranch;\n // Bare step → default branch\n return [() => true, arg as Step];\n });\n}\n\n// ---------------------------------------------------------------------------\n// choice()\n// ---------------------------------------------------------------------------\n\n/**\n * Execute the first branch whose predicate returns `true`.\n *\n * Similar to an AWS Step Functions Choice state — predicates are evaluated\n * in order, and the first match wins. Exactly one branch executes. If no\n * predicate matches, the step fails with a `CHOICE_NO_MATCH` error.\n *\n * A bare step (without a predicate tuple) can be passed as the last argument\n * to serve as a default branch — it is equivalent to `[() => true, step]`.\n *\n * Returns an {@link AggregateStep} with orchestration metadata\n * tracking which branch executed.\n *\n * All branches should provide the same output shape so that\n * subsequent steps can rely on a consistent context type.\n *\n * @example\n * ```ts\n * const p = pipeline({\n * name: 'payment',\n * steps: [\n * validateOrder,\n * choice(\n * [(ctx) => ctx.method === 'card', chargeCard],\n * [(ctx) => ctx.method === 'bank', chargeBankTransfer],\n * chargeDefault, // default\n * ),\n * sendReceipt,\n * ],\n * });\n * ```\n *\n * @param branches - One or more `[predicate, step]` tuples, optionally\n * followed by a bare step as the default.\n * @returns A frozen {@link AggregateStep} that executes the first\n * matching branch.\n */\n\n// Overload: all branches are tuples (no default)\nexport function choice<B extends readonly BranchTuple[]>(\n ...branches: [...B]\n): AggregateStep<\n AsContext<UnionToIntersection<BranchRequires<B[number]>>>,\n AsContext<UnionToIntersection<BranchProvides<B[number]>>>\n>;\n\n// Overload: tuples + trailing bare step as default\nexport function choice<B extends readonly BranchTuple[], D extends Step>(\n ...args: [...B, D]\n): AggregateStep<\n AsContext<UnionToIntersection<BranchRequires<B[number]> | ExtractRequires<D>>>,\n AsContext<UnionToIntersection<BranchProvides<B[number]> | ExtractProvides<D>>>\n>;\n\n// Implementation\nexport function choice(...args: (BranchTuple | Step)[]): AggregateStep<StepContext, StepContext> {\n const innerBranches = normalizeBranches(args);\n const name = `choice(${innerBranches.map(([, step]) => step.name).join(', ')})`;\n\n // Track which branch ran per execution for rollback.\n // INVARIANT: This relies on pipeline.ts storing the exact result.data\n // reference in its outputs array. If the pipeline ever clones\n // result.data, this WeakMap lookup will silently fail.\n // Exercised by choice.test.ts (\"rolls back the matched branch when\n // a later step fails\").\n const branchMap = new WeakMap<object, number>();\n\n const run = async (ctx: Readonly<StepContext>): Promise<AggregateResult<StepOutput>> => {\n const frozenCtx = Object.freeze({ ...ctx });\n\n for (let i = 0; i < innerBranches.length; i++) {\n const [predicate, step] = innerBranches[i];\n\n // Evaluate predicate\n let matches: boolean;\n try {\n matches = predicate(frozenCtx);\n } catch (err) {\n const cause = toError(err);\n const error = new PredicateError(`${name} predicate: ${cause.message}`);\n error.cause = cause;\n const meta = aggregateMeta(name, frozenCtx, []);\n return aggregateFailure(error, meta, name);\n }\n\n if (!matches) continue;\n\n const result = await step.run(frozenCtx);\n if (!result.success) {\n const meta = aggregateMeta(name, frozenCtx, [step.name]);\n return aggregateFailure(result.error, meta, name);\n }\n\n // Track which branch ran for rollback\n branchMap.set(result.data, i);\n\n const meta = aggregateMeta(name, frozenCtx, [step.name]);\n return aggregateSuccess(result.data, meta);\n }\n\n // No branch matched\n const meta = aggregateMeta(name, frozenCtx, []);\n return aggregateFailure(new ChoiceNoMatchError(`${name}: no branch matched`), meta, name);\n };\n\n // Rollback: only the matched branch needs rollback.\n // The thrown RollbackError is intentional — the pipeline's own\n // executeRollback loop catches it and records it in result.rollback.failed.\n const rollback: NonNullable<Step['rollback']> = async (ctx, output) => {\n const branchIndex = branchMap.get(output);\n if (branchIndex === undefined) return;\n branchMap.delete(output);\n const [, step] = innerBranches[branchIndex];\n if (step.rollback) {\n try {\n await step.rollback(ctx, output);\n } catch (err) {\n throw new RollbackError(`${name}: 1 rollback(s) failed`, [toError(err)]);\n }\n }\n };\n\n return createStepObject({\n name,\n run,\n rollback,\n }) as unknown as AggregateStep<StepContext, StepContext>;\n}\n","import type {\n ExtractProvides,\n Step,\n StepContext,\n StepOutput,\n StepResult,\n TypedStep,\n} from './types.js';\nimport {\n toError,\n baseMeta,\n stepSuccess,\n stepFailure,\n collapseErrors,\n createStepObject,\n} from './internal.js';\nimport { RollbackError } from './errors.js';\n\n// ---------------------------------------------------------------------------\n// Runtime step detection\n// ---------------------------------------------------------------------------\n\nfunction isStep(x: unknown): x is Step {\n return typeof x === 'object' && x !== null && 'run' in x && 'name' in x;\n}\n\n// ---------------------------------------------------------------------------\n// map()\n// ---------------------------------------------------------------------------\n\n/**\n * Iterate over a collection and run a function or step per item, concurrently.\n *\n * **Function form:** `(item, ctx) => result` — items can be any type.\n *\n * **Step form:** each item must be an object whose keys are spread into\n * the pipeline context before the step runs.\n *\n * The step receives `{ ...ctx, ...item }`. The step's own\n * `requires`/`provides` validation, `retry`, and `timeout` apply\n * per item. On partial failure, succeeded items are rolled back\n * (if the step has a rollback handler).\n *\n * @example\n * ```ts\n * // Function form\n * const pipeline = pipeline({\n * name: 'notify',\n * steps: [\n * map('emails', (ctx) => ctx.users, async (user) => {\n * await sendEmail(user.email);\n * return { email: user.email, sentAt: new Date() };\n * }),\n * ],\n * });\n *\n * // Step form\n * const pipeline = pipeline({\n * name: 'process',\n * steps: [\n * map('results', (ctx) => ctx.items, processItem),\n * ],\n * });\n * ```\n *\n * @param key - The output key under which results are collected.\n * @param collection - A selector that extracts the collection from context.\n * @param fnOrStep - A per-item function or a step to execute for each item.\n * @returns A frozen {@link TypedStep} that provides `{ [key]: Result[] }`.\n */\n\n// Overload: plain function callback\nexport function map<K extends string, Item, Result, Ctx extends StepContext = StepContext>(\n key: K,\n collection: (ctx: Readonly<Ctx>) => Item[],\n fn: (item: Item, ctx: Readonly<Ctx>) => Result | Promise<Result>,\n): TypedStep<Ctx, Record<K, Awaited<Result>[]>>;\n\n// Overload: step callback\nexport function map<K extends string, S extends Step, Ctx extends StepContext = StepContext>(\n key: K,\n collection: (ctx: Readonly<Ctx>) => StepContext[],\n step: S,\n): TypedStep<Ctx, Record<K, ExtractProvides<S>[]>>;\n\n// Implementation\nexport function map(\n key: string,\n collection: (ctx: Readonly<StepContext>) => unknown[],\n fnOrStep: ((item: unknown, ctx: Readonly<StepContext>) => unknown) | Step,\n): TypedStep<StepContext, StepContext> {\n const stepMode = isStep(fnOrStep);\n const name = stepMode ? `map(${key}, ${(fnOrStep as Step).name})` : `map(${key})`;\n\n // Track per-execution data for rollback (step mode only).\n // INVARIANT: This relies on pipeline.ts storing the exact result.data\n // reference in its outputs array. If the pipeline ever clones\n // result.data, this WeakMap lookup will silently fail.\n // Exercised by map.test.ts (\"rolls back all items on external\n // failure (later step fails)\").\n const executionMap = new WeakMap<object, { items: unknown[]; ctx: StepContext }>();\n\n const run = async (ctx: Readonly<StepContext>): Promise<StepResult<StepOutput>> => {\n const frozenCtx = Object.freeze({ ...ctx });\n const meta = baseMeta(name, frozenCtx);\n\n // Extract collection\n let items: unknown[];\n try {\n items = collection(frozenCtx);\n } catch (err) {\n return stepFailure(toError(err), meta, name);\n }\n\n if (stepMode) {\n return runStepMode(fnOrStep as Step, items, frozenCtx, name, key, executionMap, meta);\n } else {\n return runFunctionMode(\n fnOrStep as (item: unknown, ctx: Readonly<StepContext>) => unknown,\n items,\n frozenCtx,\n key,\n name,\n meta,\n );\n }\n };\n\n // Rollback (step mode only): roll back each succeeded item in reverse.\n // The thrown RollbackError is intentional — the pipeline's own\n // executeRollback loop catches it and records it in result.rollback.failed.\n const rollback: Step['rollback'] = stepMode\n ? async (_ctx, output) => {\n const step = fnOrStep as Step;\n if (!step.rollback) return;\n const exec = executionMap.get(output);\n if (!exec) return;\n executionMap.delete(output);\n const results = (output as Record<string, unknown>)[key] as StepOutput[];\n const errors: Error[] = [];\n for (let i = results.length - 1; i >= 0; i--) {\n try {\n const itemCtx = Object.freeze({ ...exec.ctx, ...(exec.items[i] as StepContext) });\n await step.rollback(itemCtx, results[i]);\n } catch (err) {\n errors.push(toError(err));\n }\n }\n if (errors.length > 0) {\n throw new RollbackError(`${name}: ${errors.length} rollback(s) failed`, errors);\n }\n }\n : undefined;\n\n return createStepObject({\n name,\n run: run as Step['run'],\n rollback,\n }) as unknown as TypedStep<StepContext, StepContext>;\n}\n\n// ---------------------------------------------------------------------------\n// Step mode: run inner step per item with validation + partial rollback\n// ---------------------------------------------------------------------------\n\nasync function runStepMode(\n step: Step,\n items: unknown[],\n ctx: Readonly<StepContext>,\n name: string,\n key: string,\n executionMap: WeakMap<object, { items: unknown[]; ctx: StepContext }>,\n meta: ReturnType<typeof baseMeta>,\n): Promise<StepResult<StepOutput>> {\n const settled = await Promise.allSettled(\n items.map(async (item) => {\n const itemCtx = { ...ctx, ...(item as StepContext) };\n return step.run(itemCtx);\n }),\n );\n\n const succeeded: { index: number; output: StepOutput }[] = [];\n const allErrors: Error[] = [];\n\n for (let i = 0; i < settled.length; i++) {\n const s = settled[i];\n if (s.status === 'rejected') {\n allErrors.push(toError(s.reason));\n } else if (!s.value.success) {\n allErrors.push(s.value.error);\n } else {\n succeeded.push({ index: i, output: s.value.data });\n }\n }\n\n if (allErrors.length > 0) {\n // Roll back succeeded items in reverse order (best-effort)\n if (step.rollback) {\n for (let i = succeeded.length - 1; i >= 0; i--) {\n try {\n const itemCtx = Object.freeze({ ...ctx, ...(items[succeeded[i].index] as StepContext) });\n await step.rollback(itemCtx, succeeded[i].output);\n } catch {\n // Best-effort — swallowed during partial failure\n }\n }\n }\n return stepFailure(\n collapseErrors(allErrors, `${name}: ${allErrors.length} item(s) failed`),\n meta,\n name,\n );\n }\n\n // Collect results in original order\n const results = succeeded.map((s) => s.output);\n const data: StepOutput = { [key]: results };\n executionMap.set(data, { items, ctx: { ...ctx } });\n return stepSuccess(data, meta);\n}\n\n// ---------------------------------------------------------------------------\n// Function mode: run callback per item, no rollback\n// ---------------------------------------------------------------------------\n\nasync function runFunctionMode(\n fn: (item: unknown, ctx: Readonly<StepContext>) => unknown,\n items: unknown[],\n ctx: Readonly<StepContext>,\n key: string,\n stepName: string,\n meta: ReturnType<typeof baseMeta>,\n): Promise<StepResult<StepOutput>> {\n const settled = await Promise.allSettled(items.map(async (item) => fn(item, ctx)));\n\n // Check for errors first — don't collect partial results\n const allErrors: Error[] = [];\n for (const s of settled) {\n if (s.status === 'rejected') allErrors.push(toError(s.reason));\n }\n if (allErrors.length > 0) {\n return stepFailure(\n collapseErrors(allErrors, `${stepName}: ${allErrors.length} item(s) failed`),\n meta,\n stepName,\n );\n }\n\n // All succeeded — collect results in original order\n const results = settled.map((s) => (s as PromiseFulfilledResult<unknown>).value);\n\n const data: StepOutput = { [key]: results };\n return stepSuccess(data, meta);\n}\n","import type { Step, StepContext, StepOutput, StepResult, TypedStep } from './types.js';\nimport {\n toError,\n baseMeta,\n stepSuccess,\n stepFailure,\n collapseErrors,\n createStepObject,\n} from './internal.js';\n\n// ---------------------------------------------------------------------------\n// filter()\n// ---------------------------------------------------------------------------\n\n/**\n * Filter a collection from context using a predicate, concurrently.\n *\n * Extracts a collection from the pipeline context, evaluates the\n * predicate for each item via `Promise.allSettled`, and collects\n * items that pass into an array under the given key.\n *\n * Original order is preserved.\n *\n * The predicate can be sync or async. If any predicate throws, the\n * entire step fails — no partial results are returned.\n *\n * There is no rollback (filtering is a pure operation with nothing\n * to undo).\n *\n * @example\n * ```ts\n * const pipeline = pipeline({\n * name: 'notify',\n * steps: [\n * filter(\n * 'eligible',\n * (ctx) => ctx.users,\n * (user) => user.optedIn,\n * ),\n * map('emails', (ctx) => ctx.eligible, sendEmail),\n * ],\n * });\n *\n * // Async predicate\n * filter('valid', (ctx) => ctx.orders, async (order) => {\n * const inventory = await checkInventory(order.sku);\n * return inventory.available >= order.quantity;\n * });\n * ```\n *\n * @param key - The output key under which filtered results are collected.\n * @param collection - A selector that extracts the collection from context.\n * @param predicate - A per-item predicate. Return `true` to keep, `false` to discard.\n * @returns A frozen {@link TypedStep} that provides `{ [key]: Item[] }`.\n */\nexport function filter<K extends string, Item, Ctx extends StepContext = StepContext>(\n key: K,\n collection: (ctx: Readonly<Ctx>) => Item[],\n predicate: (item: Item, ctx: Readonly<Ctx>) => boolean | Promise<boolean>,\n): TypedStep<Ctx, Record<K, Item[]>> {\n const name = `filter(${key})`;\n\n const run = async (ctx: Readonly<StepContext>): Promise<StepResult<StepOutput>> => {\n const frozenCtx = Object.freeze({ ...ctx });\n const meta = baseMeta(name, frozenCtx);\n\n let items: unknown[];\n try {\n items = collection(frozenCtx as Readonly<Ctx>);\n } catch (err) {\n return stepFailure(toError(err), meta, name);\n }\n\n return runFilter(\n items,\n frozenCtx,\n predicate as (item: unknown, ctx: Readonly<StepContext>) => boolean | Promise<boolean>,\n key,\n name,\n meta,\n );\n };\n\n return createStepObject({\n name,\n run: run as Step['run'],\n }) as unknown as TypedStep<Ctx, Record<K, Item[]>>;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nasync function runFilter(\n items: unknown[],\n ctx: Readonly<StepContext>,\n predicate: (item: unknown, ctx: Readonly<StepContext>) => boolean | Promise<boolean>,\n key: string,\n name: string,\n meta: ReturnType<typeof baseMeta>,\n): Promise<StepResult<StepOutput>> {\n const settled = await Promise.allSettled(items.map(async (item) => predicate(item, ctx)));\n\n // Check for errors first — don't collect partial results\n const allErrors: Error[] = [];\n for (const s of settled) {\n if (s.status === 'rejected') allErrors.push(toError(s.reason));\n }\n if (allErrors.length > 0) {\n return stepFailure(\n collapseErrors(allErrors, `${name}: ${allErrors.length} predicate(s) failed`),\n meta,\n name,\n );\n }\n\n // All succeeded — collect results preserving original order\n const results: unknown[] = [];\n for (let i = 0; i < settled.length; i++) {\n if ((settled[i] as PromiseFulfilledResult<boolean>).value) {\n results.push(items[i]);\n }\n }\n\n const data: StepOutput = { [key]: results };\n return stepSuccess(data, meta);\n}\n","import type { Step, StepContext, StepOutput, StepResult, TypedStep } from './types.js';\nimport {\n toError,\n baseMeta,\n stepSuccess,\n stepFailure,\n collapseErrors,\n createStepObject,\n} from './internal.js';\n\n// ---------------------------------------------------------------------------\n// flatMap()\n// ---------------------------------------------------------------------------\n\n/**\n * Map each item in a collection to an array, then flatten one level.\n *\n * Extracts a collection from the pipeline context, runs the callback\n * for each item via `Promise.allSettled`, and flattens the per-item\n * arrays into a single array under the given key.\n *\n * The callback can be sync or async. If any callback throws, the\n * entire step fails — no partial results are returned.\n *\n * There is no rollback (pure transformation with nothing to undo).\n *\n * @example\n * ```ts\n * // Expand orders into line items\n * const pipeline = pipeline({\n * name: 'process',\n * steps: [\n * flatMap(\n * 'lineItems',\n * (ctx) => ctx.orders,\n * (order) => order.items,\n * ),\n * ],\n * });\n *\n * // Async callback\n * flatMap('emails', (ctx) => ctx.teams, async (team) => {\n * const members = await fetchMembers(team.id);\n * return members.map((m) => m.email);\n * });\n * ```\n *\n * @param key - The output key under which flattened results are collected.\n * @param collection - A selector that extracts the collection from context.\n * @param fn - A per-item callback that returns an array (or Promise of array).\n * @returns A frozen {@link TypedStep} that provides `{ [key]: Item[] }`.\n */\nexport function flatMap<K extends string, Item, Result, Ctx extends StepContext = StepContext>(\n key: K,\n collection: (ctx: Readonly<Ctx>) => Item[],\n fn: (item: Item, ctx: Readonly<Ctx>) => Result[] | Promise<Result[]>,\n): TypedStep<Ctx, Record<K, Result[]>> {\n const name = `flatMap(${key})`;\n\n const run = async (ctx: Readonly<StepContext>): Promise<StepResult<StepOutput>> => {\n const frozenCtx = Object.freeze({ ...ctx });\n const meta = baseMeta(name, frozenCtx);\n\n let items: unknown[];\n try {\n items = collection(frozenCtx as Readonly<Ctx>);\n } catch (err) {\n return stepFailure(toError(err), meta, name);\n }\n\n return runFlatMap(\n items,\n frozenCtx,\n fn as (item: unknown, ctx: Readonly<StepContext>) => unknown[] | Promise<unknown[]>,\n key,\n name,\n meta,\n );\n };\n\n return createStepObject({\n name,\n run: run as Step['run'],\n }) as unknown as TypedStep<Ctx, Record<K, Result[]>>;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nasync function runFlatMap(\n items: unknown[],\n ctx: Readonly<StepContext>,\n fn: (item: unknown, ctx: Readonly<StepContext>) => unknown[] | Promise<unknown[]>,\n key: string,\n name: string,\n meta: ReturnType<typeof baseMeta>,\n): Promise<StepResult<StepOutput>> {\n const settled = await Promise.allSettled(items.map(async (item) => fn(item, ctx)));\n\n // Check for errors first — don't collect partial results\n const allErrors: Error[] = [];\n for (const s of settled) {\n if (s.status === 'rejected') allErrors.push(toError(s.reason));\n }\n if (allErrors.length > 0) {\n return stepFailure(\n collapseErrors(allErrors, `${name}: ${allErrors.length} callback(s) failed`),\n meta,\n name,\n );\n }\n\n // All succeeded — flatten results\n const results: unknown[] = [];\n for (const s of settled) {\n results.push(...(s as PromiseFulfilledResult<unknown[]>).value);\n }\n\n const data: StepOutput = { [key]: results };\n return stepSuccess(data, meta);\n}\n"],"mappings":"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","names":["meta","state","meta","meta"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/internal.ts","../src/step.ts","../src/builder.ts","../src/middleware.ts","../src/when.ts","../src/pipeline.ts","../src/parallel.ts","../src/choice.ts","../src/distribute.ts"],"sourcesContent":["export { step } from './step.js';\nexport {\n RunsheetError,\n RequiresValidationError,\n ProvidesValidationError,\n ArgsValidationError,\n PredicateError,\n TimeoutError,\n RetryExhaustedError,\n StrictOverlapError,\n RollbackError,\n UnknownError,\n} from './errors.js';\nexport type { RunsheetErrorCode } from './errors.js';\nexport { pipeline } from './pipeline.js';\nexport type { PipelineConfig } from './pipeline.js';\nexport { when } from './when.js';\nexport { parallel } from './parallel.js';\nexport { choice } from './choice.js';\n\nexport { distribute } from './distribute.js';\nexport type { StepMiddleware, StepInfo, StepExecutor } from './middleware.js';\nexport type { PipelineBuilder } from './builder.js';\n\nexport type {\n Step,\n TypedStep,\n AggregateStep,\n StepConfig,\n StepContext,\n StepOutput,\n StepSchema,\n ExtractRequires,\n ExtractProvides,\n RetryPolicy,\n StepResult,\n StepSuccess,\n StepFailure,\n StepMeta,\n AggregateResult,\n AggregateSuccess,\n AggregateFailure,\n AggregateMeta,\n RollbackReport,\n RollbackFailure,\n} from './types.js';\n","/**\n * Error codes for errors produced by the runsheet library itself.\n *\n * Use these to distinguish library errors from application errors:\n *\n * ```ts\n * if (!result.success) {\n * if (result.error instanceof RunsheetError) {\n * console.log(result.error.code); // 'REQUIRES_VALIDATION', etc.\n * }\n * }\n * ```\n */\nexport type RunsheetErrorCode =\n | 'REQUIRES_VALIDATION'\n | 'PROVIDES_VALIDATION'\n | 'ARGS_VALIDATION'\n | 'PREDICATE'\n | 'TIMEOUT'\n | 'RETRY_EXHAUSTED'\n | 'STRICT_OVERLAP'\n | 'ROLLBACK'\n | 'UNKNOWN';\n\n/**\n * Base error class for all errors produced by the runsheet library.\n *\n * Application errors (thrown by step `run` or `rollback` functions)\n * are never wrapped in `RunsheetError` — they pass through as-is.\n * If you see a `RunsheetError` as `result.error`, the library itself\n * produced it.\n *\n * Use `instanceof RunsheetError` to distinguish library errors from\n * application errors. Use `instanceof` on a subclass (e.g.,\n * `TimeoutError`) or check the `code` property for specific failures.\n */\nexport class RunsheetError extends Error {\n /** Discriminant code identifying the type of library error. */\n readonly code: RunsheetErrorCode;\n\n /**\n * @param code - The error code.\n * @param message - A human-readable description of the failure.\n */\n constructor(code: RunsheetErrorCode, message: string) {\n super(message);\n this.name = 'RunsheetError';\n this.code = code;\n }\n}\n\n/** Schema validation failed on the accumulated context before a step ran. */\nexport class RequiresValidationError extends RunsheetError {\n constructor(message: string) {\n super('REQUIRES_VALIDATION', message);\n this.name = 'RequiresValidationError';\n }\n}\n\n/** Schema validation failed on a step's output after it ran. */\nexport class ProvidesValidationError extends RunsheetError {\n constructor(message: string) {\n super('PROVIDES_VALIDATION', message);\n this.name = 'ProvidesValidationError';\n }\n}\n\n/** Schema validation failed on the pipeline's input arguments. */\nexport class ArgsValidationError extends RunsheetError {\n constructor(message: string) {\n super('ARGS_VALIDATION', message);\n this.name = 'ArgsValidationError';\n }\n}\n\n/** A `when()` or `choice()` predicate threw an error. */\nexport class PredicateError extends RunsheetError {\n constructor(message: string) {\n super('PREDICATE', message);\n this.name = 'PredicateError';\n }\n}\n\n/** A step exceeded its configured timeout. */\nexport class TimeoutError extends RunsheetError {\n /** The timeout duration in milliseconds that was exceeded. */\n readonly timeoutMs: number;\n\n constructor(message: string, timeoutMs: number) {\n super('TIMEOUT', message);\n this.name = 'TimeoutError';\n this.timeoutMs = timeoutMs;\n }\n}\n\n/** A step failed after exhausting all retry attempts. */\nexport class RetryExhaustedError extends RunsheetError {\n /** Total number of attempts (initial + retries). */\n readonly attempts: number;\n\n constructor(message: string, attempts: number) {\n super('RETRY_EXHAUSTED', message);\n this.name = 'RetryExhaustedError';\n this.attempts = attempts;\n }\n}\n\n/** Two steps provide the same key (strict mode, detected at build time). */\nexport class StrictOverlapError extends RunsheetError {\n /** The key that is provided by multiple steps. */\n readonly key: string;\n /** The names of the two steps that both provide the key. */\n readonly steps: readonly [string, string];\n\n constructor(message: string, key: string, steps: readonly [string, string]) {\n super('STRICT_OVERLAP', message);\n this.name = 'StrictOverlapError';\n this.key = key;\n this.steps = steps;\n }\n}\n\n/** A non-Error value was thrown and caught by the pipeline engine. */\nexport class UnknownError extends RunsheetError {\n /** The original thrown value before stringification. */\n readonly originalValue: unknown;\n\n constructor(message: string, originalValue: unknown) {\n super('UNKNOWN', message);\n this.name = 'UnknownError';\n this.originalValue = originalValue;\n }\n}\n\n/** One or more rollback handlers failed in a combinator. */\nexport class RollbackError extends RunsheetError {\n /** The individual errors from each failed rollback handler. */\n readonly causes: readonly Error[];\n\n constructor(message: string, causes: readonly Error[] = []) {\n super('ROLLBACK', message);\n this.name = 'RollbackError';\n this.causes = causes;\n if (causes.length === 1) this.cause = causes[0];\n else if (causes.length > 1) this.cause = new AggregateError(causes, message);\n }\n}\n","import type {\n AggregateFailure,\n AggregateMeta,\n AggregateSuccess,\n RollbackReport,\n Step,\n StepContext,\n StepMeta,\n StepFailure,\n StepSuccess,\n StepOutput,\n} from './types.js';\nimport { UnknownError } from './errors.js';\n\n/** Ensure a type satisfies StepContext, falling back to StepContext. */\nexport type AsContext<T> = T extends StepContext ? T : StepContext;\n\n/** Normalize an unknown thrown value to an Error instance. */\nexport function toError(err: unknown): Error {\n if (err instanceof Error) return err;\n return new UnknownError(String(err), err);\n}\n\n/** Empty rollback report for single-step failures. */\nexport const EMPTY_ROLLBACK: RollbackReport = Object.freeze({\n completed: Object.freeze([] as string[]),\n failed: Object.freeze([] as never[]),\n});\n\n/** Format schema validation issues into a human-readable string. */\nexport function formatIssues(\n issues: readonly { path: readonly (string | number)[]; message: string }[],\n): string {\n return issues\n .map((i) => (i.path.length > 0 ? `${i.path.join('.')}: ${i.message}` : i.message))\n .join(', ');\n}\n\n/**\n * Collapse an array of errors into a single error.\n *\n * Returns the sole error when there is exactly one, otherwise wraps\n * them in an `AggregateError` with the given message.\n */\nexport function collapseErrors(errors: Error[], message: string): Error {\n return errors.length === 1 ? errors[0] : new AggregateError(errors, message);\n}\n\n/**\n * Create a frozen {@link Step} object with `undefined` defaults for\n * omitted optional fields.\n *\n * Centralises the construction so that if `Step` gains new properties,\n * only this helper needs updating.\n */\nexport function createStepObject(fields: {\n name: string;\n run: Step['run'];\n rollback?: Step['rollback'];\n requires?: Step['requires'];\n provides?: Step['provides'];\n retry?: Step['retry'];\n timeout?: Step['timeout'];\n}): Step {\n return Object.freeze({\n name: fields.name,\n requires: fields.requires ?? undefined,\n provides: fields.provides ?? undefined,\n run: fields.run,\n rollback: fields.rollback ?? undefined,\n retry: fields.retry ?? undefined,\n timeout: fields.timeout ?? undefined,\n });\n}\n\n/**\n * Create a {@link StepMeta} for a step execution.\n *\n * Used by `step` and collection combinators. Contains only\n * the step's name and the arguments it received.\n */\nexport function baseMeta(name: string, args: Readonly<StepContext>): StepMeta {\n return Object.freeze({ name, args });\n}\n\n/**\n * Create an {@link AggregateMeta} for an orchestrator execution.\n *\n * Used by `pipeline`, `parallel`, and `choice` to produce results\n * with orchestration detail (which steps ran).\n */\nexport function aggregateMeta(\n name: string,\n args: Readonly<StepContext>,\n stepsExecuted: readonly string[],\n): AggregateMeta {\n return Object.freeze({ name, args, stepsExecuted });\n}\n\n/**\n * Create a successful {@link StepResult}.\n *\n * The returned object is frozen (immutable). Used by `step`\n * and collection combinators to produce consistent success results.\n */\nexport function stepSuccess<T extends StepOutput>(data: T, meta: StepMeta): StepSuccess<T> {\n return Object.freeze({ success: true, data, meta });\n}\n\n/**\n * Create a failed {@link StepResult}.\n *\n * The returned object is frozen (immutable). When no rollback\n * report is provided, defaults to {@link EMPTY_ROLLBACK} (no\n * rollbacks attempted).\n */\nexport function stepFailure(\n error: Error,\n meta: StepMeta,\n failedStep: string,\n rollback: RollbackReport = EMPTY_ROLLBACK,\n): StepFailure {\n return Object.freeze({ success: false, error, meta, failedStep, rollback });\n}\n\n/**\n * Create a successful {@link AggregateResult}.\n *\n * Like {@link stepSuccess} but with {@link AggregateMeta}.\n */\nexport function aggregateSuccess<T extends StepOutput>(\n data: T,\n meta: AggregateMeta,\n): AggregateSuccess<T> {\n return Object.freeze({ success: true, data, meta });\n}\n\n/**\n * Create a failed {@link AggregateResult}.\n *\n * Like {@link stepFailure} but with {@link AggregateMeta}.\n */\nexport function aggregateFailure(\n error: Error,\n meta: AggregateMeta,\n failedStep: string,\n rollback: RollbackReport = EMPTY_ROLLBACK,\n): AggregateFailure {\n return Object.freeze({ success: false, error, meta, failedStep, rollback });\n}\n","import type {\n RetryPolicy,\n StepConfig,\n StepContext,\n StepOutput,\n StepResult,\n Step,\n TypedStep,\n} from './types.js';\nimport {\n RequiresValidationError,\n ProvidesValidationError,\n TimeoutError,\n RetryExhaustedError,\n} from './errors.js';\nimport {\n toError,\n baseMeta,\n stepSuccess,\n stepFailure,\n formatIssues,\n createStepObject,\n} from './internal.js';\n\n// ---------------------------------------------------------------------------\n// Timeout and retry wrappers\n// ---------------------------------------------------------------------------\n\n// NOTE: Promise.race doesn't cancel the underlying run — if the timer wins,\n// the step's side effects continue in the background. True cancellation\n// would require AbortSignal propagation into step run functions.\n// Timer functions — declared here to avoid depending on @types/node or DOM lib\ndeclare function setTimeout(callback: () => void, ms: number): unknown;\ndeclare function clearTimeout(handle: unknown): void;\n\nfunction withTimeout<T>(fn: () => T | Promise<T>, stepName: string, ms: number): () => Promise<T> {\n return async () => {\n let timer: unknown;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n reject(new TimeoutError(`${stepName} timed out after ${ms}ms`, ms));\n }, ms);\n });\n try {\n return await Promise.race([Promise.resolve(fn()), timeout]);\n } finally {\n clearTimeout(timer);\n }\n };\n}\n\nfunction computeDelay(policy: RetryPolicy, attempt: number): number {\n const base = policy.delay ?? 0;\n if (base === 0) return 0;\n const strategy = policy.backoff ?? 'linear';\n return strategy === 'exponential' ? base * 2 ** (attempt - 1) : base * attempt;\n}\n\nfunction withRetry<T>(\n fn: () => Promise<T>,\n stepName: string,\n policy: RetryPolicy,\n): () => Promise<T> {\n return async () => {\n let lastError: Error;\n const errors: Error[] = [];\n\n try {\n return await fn();\n } catch (err) {\n lastError = toError(err);\n errors.push(lastError);\n }\n\n for (let attempt = 1; attempt <= policy.count; attempt++) {\n if (policy.retryIf && !policy.retryIf(errors)) throw lastError!;\n\n const delay = computeDelay(policy, attempt);\n if (delay > 0) await new Promise((r) => setTimeout(() => r(undefined), delay));\n\n try {\n return await fn();\n } catch (err) {\n lastError = toError(err);\n errors.push(lastError);\n }\n }\n\n const error = new RetryExhaustedError(\n `${stepName} failed after ${policy.count} retries`,\n policy.count + 1,\n );\n error.cause = errors.length === 1 ? errors[0] : new AggregateError(errors, error.message);\n throw error;\n };\n}\n\nfunction buildExecutor<Requires extends StepContext, Provides extends StepContext>(\n config: StepConfig<Requires, Provides>,\n): (ctx: Readonly<Requires>) => Promise<Provides> {\n let fn = (ctx: Readonly<Requires>) => Promise.resolve(config.run(ctx));\n if (config.timeout !== undefined) {\n const baseFn = fn;\n const ms = config.timeout;\n fn = (ctx) => withTimeout(() => baseFn(ctx), config.name, ms)();\n }\n if (config.retry !== undefined) {\n const baseFn = fn;\n const policy = config.retry;\n fn = (ctx) => withRetry(() => baseFn(ctx), config.name, policy)();\n }\n return fn;\n}\n\n// ---------------------------------------------------------------------------\n// step()\n// ---------------------------------------------------------------------------\n\n/**\n * Create a pipeline step.\n *\n * Returns a frozen {@link TypedStep} with concrete types for `run`,\n * `rollback`, `requires`, and `provides`. The `run` function can be\n * sync or async — both are supported.\n *\n * **With schemas** (runtime validation + type inference):\n * ```ts\n * const charge = step({\n * name: 'charge',\n * requires: z.object({ amount: z.number() }),\n * provides: z.object({ chargeId: z.string() }),\n * run: async (ctx) => ({ chargeId: 'ch_123' }),\n * });\n * ```\n *\n * **With generics only** (no runtime validation):\n * ```ts\n * const log = step<{ order: Order }, { loggedAt: Date }>({\n * name: 'log',\n * run: async (ctx) => ({ loggedAt: new Date() }),\n * });\n * ```\n *\n * **Invariants:**\n * - The returned step object is always frozen (immutable).\n * - The `run` function catches thrown errors and produces\n * `StepResult` values. Step authors should throw to signal failure.\n * - This is the single type-erasure cast point in the library.\n *\n * @typeParam Requires - The context shape this step reads from.\n * @typeParam Provides - The output shape this step produces.\n * @param config - The step configuration. See {@link StepConfig}.\n * @returns A frozen {@link TypedStep} ready for use in pipelines.\n */\nexport function step<Requires extends StepContext, Provides extends StepContext>(\n config: StepConfig<Requires, Provides>,\n): TypedStep<Requires, Provides> {\n const execute = buildExecutor(config);\n\n const run = async (ctx: Readonly<StepContext>): Promise<StepResult<StepOutput>> => {\n const frozenCtx = Object.freeze({ ...ctx });\n const meta = baseMeta(config.name, frozenCtx);\n\n // Validate requires\n if (config.requires) {\n const parsed = config.requires.safeParse(frozenCtx);\n if (!parsed.success) {\n const error = new RequiresValidationError(\n `${config.name} requires: ${formatIssues(parsed.error.issues)}`,\n );\n return stepFailure(error, meta, config.name);\n }\n }\n\n // Execute (with retry + timeout)\n let data: Provides;\n try {\n data = await execute(frozenCtx as Readonly<Requires>);\n } catch (err) {\n return stepFailure(toError(err), meta, config.name);\n }\n\n // Validate provides\n if (config.provides) {\n const parsed = config.provides.safeParse(data);\n if (!parsed.success) {\n const error = new ProvidesValidationError(\n `${config.name} provides: ${formatIssues(parsed.error.issues)}`,\n );\n return stepFailure(error, meta, config.name);\n }\n }\n\n return stepSuccess(data as unknown as StepOutput, meta);\n };\n\n return createStepObject({\n name: config.name,\n requires: config.requires,\n provides: config.provides,\n run: run as unknown as Step['run'],\n rollback: config.rollback\n ? async (ctx: Readonly<StepContext>, output: Readonly<StepContext>) => {\n await config.rollback!(ctx as Readonly<Requires>, output as Readonly<Provides>);\n }\n : undefined,\n retry: config.retry,\n timeout: config.timeout,\n }) as TypedStep<Requires, Provides>;\n}\n","import type {\n AggregateStep,\n ExtractProvides,\n ExtractRequires,\n Step,\n StepContext,\n StepSchema,\n} from './types.js';\nimport type { StepMiddleware } from './middleware.js';\nimport { buildPipelineStep } from './pipeline.js';\n\n// ---------------------------------------------------------------------------\n// Builder types\n// ---------------------------------------------------------------------------\n\n/**\n * A fluent pipeline builder that progressively narrows the accumulated\n * context type as steps are added.\n *\n * Each method returns a new, frozen builder — builders are immutable.\n *\n * This means you can safely fork a builder to create variants:\n *\n * ```ts\n * const base = pipeline({ name: 'order' }).step(validate);\n * const withCharge = base.step(charge).build();\n * const withoutCharge = base.build(); // unaffected by the fork\n * ```\n *\n * @typeParam Args - The pipeline's initial input type.\n * @typeParam Ctx - The accumulated context type so far (grows with each `.step()`).\n */\nexport type PipelineBuilder<Args extends StepContext, Ctx extends StepContext> = {\n /**\n * Add a step to the pipeline.\n *\n * The step's `Requires` type must be satisfied by the current `Ctx`\n * (checked via phantom brands — a step that requires less than `Ctx`\n * is always accepted). The returned builder's `Ctx` expands to\n * include the step's `Provides`.\n *\n * @typeParam S - The step type being added.\n * @param step - A {@link Step} (from `step`, `when`, `pipeline`, etc.).\n * @returns A new builder with the expanded context type.\n */\n readonly step: <S extends Step>(\n step: S & ([Ctx] extends [ExtractRequires<S>] ? unknown : never),\n ) => PipelineBuilder<Args, Ctx & ExtractProvides<S>>;\n\n /**\n * Add middleware to the pipeline.\n *\n * Middleware is applied to every step. Multiple `.use()` calls\n * accumulate — earlier middleware is outermost (executes first).\n *\n * @param middleware - One or more {@link StepMiddleware} functions.\n * @returns A new builder with the middleware added.\n */\n readonly use: (...middleware: StepMiddleware[]) => PipelineBuilder<Args, Ctx>;\n\n /**\n * Build the pipeline. Returns an {@link AggregateStep} — pipelines\n * are steps whose `run()` returns {@link AggregateResult}.\n */\n readonly build: () => AggregateStep<Args, Ctx>;\n};\n\n// ---------------------------------------------------------------------------\n// Internal builder state (immutable — each method returns a new builder)\n// ---------------------------------------------------------------------------\n\n/** @internal */\nexport type BuilderState = {\n readonly name: string;\n readonly steps: readonly Step[];\n readonly middleware: readonly StepMiddleware[];\n readonly argsSchema: StepSchema<StepContext> | undefined;\n readonly strict: boolean;\n};\n\n/** @internal */\nexport function makeBuilder<Args extends StepContext, Ctx extends StepContext>(\n state: BuilderState,\n): PipelineBuilder<Args, Ctx> {\n return Object.freeze({\n step: <S extends Step>(step: S) =>\n makeBuilder<Args, Ctx & ExtractProvides<S>>({\n ...state,\n steps: [...state.steps, step],\n }),\n\n use: (...middleware: StepMiddleware[]) =>\n makeBuilder<Args, Ctx>({\n ...state,\n middleware: [...state.middleware, ...middleware],\n }),\n\n build: () =>\n buildPipelineStep({\n name: state.name,\n steps: state.steps,\n middleware: state.middleware.length > 0 ? state.middleware : undefined,\n argsSchema: state.argsSchema as StepSchema<Args> | undefined,\n strict: state.strict ? true : undefined,\n }) as AggregateStep<Args, Ctx>,\n });\n}\n","import type { Step, StepContext, StepOutput, StepResult } from './types.js';\n\n/**\n * Metadata about the step being executed, passed to middleware.\n *\n * This is a read-only view of the step's public configuration.\n * Middleware can use it for logging, metrics, or conditional behavior.\n */\nexport type StepInfo = {\n /** The step's name. */\n readonly name: string;\n /** The step's requires schema, or `undefined` if not provided. */\n readonly requires: Step['requires'];\n /** The step's provides schema, or `undefined` if not provided. */\n readonly provides: Step['provides'];\n};\n\n/**\n * A function that executes a step (or the next middleware in the chain).\n *\n * Receives the frozen accumulated context and returns a {@link StepResult}.\n */\nexport type StepExecutor = (ctx: Readonly<StepContext>) => Promise<StepResult<StepOutput>>;\n\n/**\n * Middleware that wraps the entire step lifecycle, including schema\n * validation.\n *\n * A middleware receives the step metadata and a `next` function, and\n * returns a new executor. Call `next(ctx)` to proceed to the next\n * middleware (or the actual step execution). You can:\n *\n * - **Observe**: read the context or result for logging/metrics.\n * - **Transform**: modify the result before returning it.\n * - **Short-circuit**: return a `StepResult` without calling `next`.\n *\n * If a middleware throws, the pipeline catches it and treats it as a\n * step failure (triggering rollback for previously completed steps).\n *\n * @example\n * ```ts\n * const timing: StepMiddleware = (step, next) => async (ctx) => {\n * const start = performance.now();\n * const result = await next(ctx);\n * console.log(`${step.name}: ${performance.now() - start}ms`);\n * return result;\n * };\n * ```\n *\n * @param step - Metadata about the step being wrapped.\n * @param next - The next executor in the chain. Call it to continue.\n * @returns A new executor that wraps `next`.\n */\nexport type StepMiddleware = (step: StepInfo, next: StepExecutor) => StepExecutor;\n\n/**\n * Compose an array of middlewares around a step executor.\n *\n * First middleware in the array is the outermost wrapper (executes\n * first on the way in, last on the way out).\n *\n * @param middlewares - Middleware functions, in declaration order.\n * @param step - Metadata about the step being wrapped.\n * @param executor - The base step executor to wrap.\n * @returns A composed executor with all middleware applied.\n */\nexport function applyMiddleware(\n middlewares: readonly StepMiddleware[],\n step: StepInfo,\n executor: StepExecutor,\n): StepExecutor {\n return middlewares.reduceRight<StepExecutor>((next, mw) => mw(step, next), executor);\n}\n","import type {\n AggregateResult,\n AggregateStep,\n AggregateMeta,\n Step,\n StepContext,\n StepOutput,\n TypedStep,\n} from './types.js';\nimport {\n toError,\n aggregateMeta,\n aggregateSuccess,\n aggregateFailure,\n createStepObject,\n} from './internal.js';\nimport { PredicateError } from './errors.js';\n\n/**\n * Wrap a step with a guard predicate.\n *\n * The step only executes when the predicate returns `true`. When\n * skipped, the result contains empty data and empty `stepsExecuted`.\n * Enclosing orchestrators (pipeline, parallel) see the empty\n * `stepsExecuted` and skip tracking — no rollback entry is created\n * and the step name does not appear in the pipeline's\n * `meta.stepsExecuted`.\n *\n * @param predicate - Guard function. Return `true` to execute, `false` to skip.\n * @param step - The step to conditionally execute.\n * @returns A frozen {@link AggregateStep} that evaluates the predicate\n * and delegates to the inner step when it returns `true`.\n */\nexport function when<Requires extends StepContext, Provides extends StepContext>(\n predicate: (ctx: Readonly<Requires>) => boolean,\n step: TypedStep<Requires, Provides>,\n): AggregateStep<Requires, Provides> {\n const name = step.name;\n const innerStep = step as Step;\n\n const run = async (ctx: Readonly<StepContext>): Promise<AggregateResult<StepOutput>> => {\n const frozenCtx = Object.freeze({ ...ctx });\n\n let shouldRun: boolean;\n try {\n shouldRun = predicate(frozenCtx as Readonly<Requires>);\n } catch (err) {\n const cause = toError(err);\n const error = new PredicateError(`${name} predicate: ${cause.message}`);\n error.cause = cause;\n return aggregateFailure(error, aggregateMeta(name, frozenCtx, []), name);\n }\n\n if (!shouldRun) {\n return aggregateSuccess({}, aggregateMeta(name, frozenCtx, []));\n }\n\n const result = await innerStep.run(frozenCtx);\n if (!result.success) {\n return aggregateFailure(result.error, aggregateMeta(name, frozenCtx, [name]), name);\n }\n\n return aggregateSuccess(result.data, aggregateMeta(name, frozenCtx, [name]));\n };\n\n return createStepObject({\n name,\n run,\n rollback: innerStep.rollback,\n requires: innerStep.requires,\n provides: innerStep.provides,\n }) as unknown as AggregateStep<Requires, Provides>;\n}\n\n/**\n * Check whether a successful step result represents a skipped\n * conditional (empty `stepsExecuted` in an {@link AggregateMeta}).\n *\n * @internal — used by pipeline and parallel to decide whether to\n * track a step in their own `stepsExecuted` and rollback lists.\n */\nexport function wasSkipped(meta: { name: string; args: Readonly<StepContext> }): boolean {\n return 'stepsExecuted' in meta && (meta as AggregateMeta).stepsExecuted.length === 0;\n}\n","import type {\n AggregateResult,\n AggregateStep,\n ExtractProvides,\n RollbackFailure,\n RollbackReport,\n Step,\n StepContext,\n StepOutput,\n StepResult,\n StepSchema,\n UnionToIntersection,\n} from './types.js';\nimport type { StepMiddleware } from './middleware.js';\nimport type { PipelineBuilder } from './builder.js';\n// Circular import: builder.ts → buildPipelineStep (here), pipeline.ts →\n// makeBuilder (builder.ts). Safe in ESM because both are function\n// declarations — they're available by the time any function is called.\nimport { makeBuilder } from './builder.js';\nimport { applyMiddleware } from './middleware.js';\nimport { ArgsValidationError, RollbackError, StrictOverlapError } from './errors.js';\nimport {\n toError,\n aggregateMeta,\n aggregateSuccess,\n aggregateFailure,\n formatIssues,\n createStepObject,\n} from './internal.js';\nimport { wasSkipped } from './when.js';\n\n// ---------------------------------------------------------------------------\n// Pipeline configuration\n// ---------------------------------------------------------------------------\n\n/**\n * Internal configuration shape for the pipeline engine.\n *\n * Users typically don't construct this directly — use `pipeline()`.\n */\nexport type PipelineConfig = {\n /** Pipeline name, used in execution metadata and error messages. */\n readonly name: string;\n /** Steps to execute in order. */\n readonly steps: readonly Step[];\n /** Optional middleware applied to every step. First in array = outermost. */\n readonly middleware?: readonly StepMiddleware[];\n /** Optional schema that validates the pipeline's input arguments. */\n readonly argsSchema?: StepSchema<StepContext>;\n /**\n * When `true`, throws at build time if two or more steps provide the\n * same key. Only checks steps that have a `provides` schema with an\n * inspectable `.shape` property (e.g., Zod objects). Steps without\n * provides schemas are not checked.\n */\n readonly strict?: boolean;\n};\n\n// ---------------------------------------------------------------------------\n// Strict mode — detect provides key collisions at build time\n// ---------------------------------------------------------------------------\n\nfunction checkStrictOverlap(steps: readonly Step[]): void {\n const seen = new Map<string, string>(); // key → step name\n\n for (const step of steps) {\n if (!step.provides) continue;\n\n // Extract keys from schemas that expose .shape (e.g., Zod objects)\n const shape = (step.provides as Record<string, unknown>).shape;\n if (!shape || typeof shape !== 'object') continue;\n\n for (const key of Object.keys(shape)) {\n const existing = seen.get(key);\n if (existing) {\n throw new StrictOverlapError(\n `strict mode: key \"${key}\" is provided by both \"${existing}\" and \"${step.name}\"`,\n key,\n [existing, step.name],\n );\n }\n seen.set(key, step.name);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Execution state — accumulated during pipeline run\n// ---------------------------------------------------------------------------\n\n/** Record of a step that executed successfully during a pipeline run. */\ntype ExecutedStepEntry = {\n step: Step;\n snapshot: StepContext;\n output: StepOutput;\n};\n\n/** Mutable state accumulated during pipeline execution. */\ntype ExecutionState = {\n context: StepContext;\n readonly executed: ExecutedStepEntry[];\n readonly stepsExecuted: string[];\n};\n\nfunction createExecutionState(args: StepContext): ExecutionState {\n return {\n context: Object.freeze({ ...args }),\n executed: [],\n stepsExecuted: [],\n };\n}\n\n// ---------------------------------------------------------------------------\n// Rollback\n// ---------------------------------------------------------------------------\n\n/**\n * Execute rollback handlers for previously completed steps in reverse\n * order. Best-effort: if a handler throws, remaining rollbacks still\n * execute. Returns a report of what succeeded and what failed.\n */\nasync function executeRollback(executed: readonly ExecutedStepEntry[]): Promise<RollbackReport> {\n const completed: string[] = [];\n const failed: RollbackFailure[] = [];\n\n for (let i = executed.length - 1; i >= 0; i--) {\n const entry = executed[i];\n if (!entry.step.rollback) continue;\n\n try {\n await entry.step.rollback(entry.snapshot, entry.output);\n completed.push(entry.step.name);\n } catch (err) {\n failed.push({ step: entry.step.name, error: toError(err) });\n }\n }\n\n return Object.freeze({ completed, failed });\n}\n\n// ---------------------------------------------------------------------------\n// Pipeline execution\n// ---------------------------------------------------------------------------\n\n/**\n * Internal result of pipeline execution, pairing the user-facing\n * {@link AggregateResult} with the execution state needed for\n * rollback when this pipeline is used as a step in an outer pipeline.\n */\ntype ExecutionOutcome = {\n result: AggregateResult<StepContext>;\n state: ExecutionState;\n};\n\n/**\n * Core pipeline execution loop.\n *\n * Runs steps sequentially, accumulating context. On failure,\n * executes rollback for previously completed steps. Returns both\n * the result and the execution state (for nested pipeline rollback).\n */\nasync function executePipeline(\n config: PipelineConfig,\n args: StepContext,\n): Promise<ExecutionOutcome> {\n const frozenArgs = Object.freeze({ ...args });\n\n // Validate pipeline args if schema provided\n if (config.argsSchema) {\n const parsed = config.argsSchema.safeParse(frozenArgs);\n if (!parsed.success) {\n const error = new ArgsValidationError(\n `${config.name} args: ${formatIssues(parsed.error.issues)}`,\n );\n const meta = aggregateMeta(config.name, frozenArgs, []);\n const state = createExecutionState(frozenArgs);\n return { result: aggregateFailure(error, meta, config.name), state };\n }\n }\n\n const state = createExecutionState(frozenArgs);\n const middlewares = config.middleware ?? [];\n\n for (const step of config.steps) {\n // Snapshot pre-step context\n const snapshot = state.context;\n\n // Wrap step.run with middleware\n const executor =\n middlewares.length > 0\n ? applyMiddleware(\n middlewares,\n { name: step.name, requires: step.requires, provides: step.provides },\n (ctx) => step.run(ctx),\n )\n : (ctx: Readonly<StepContext>) => step.run(ctx);\n\n // Execute\n let result: StepResult<StepOutput>;\n try {\n result = await executor(state.context);\n } catch (err) {\n const error = toError(err);\n const rollback = await executeRollback(state.executed);\n const meta = aggregateMeta(config.name, frozenArgs, [...state.stepsExecuted]);\n return { result: aggregateFailure(error, meta, step.name, rollback), state };\n }\n\n if (!result.success) {\n const rollback = await executeRollback(state.executed);\n const meta = aggregateMeta(config.name, frozenArgs, [...state.stepsExecuted]);\n return { result: aggregateFailure(result.error, meta, step.name, rollback), state };\n }\n\n // Skip tracking for steps that didn't execute (e.g., when() with false predicate)\n if (wasSkipped(result.meta)) continue;\n\n // Track and accumulate\n const output = result.data;\n state.executed.push({ step, snapshot, output });\n state.stepsExecuted.push(step.name);\n state.context = Object.freeze({ ...state.context, ...output });\n }\n\n const meta = aggregateMeta(config.name, frozenArgs, [...state.stepsExecuted]);\n return { result: aggregateSuccess(state.context, meta), state };\n}\n\n// ---------------------------------------------------------------------------\n// Build an AggregateStep from a PipelineConfig\n// ---------------------------------------------------------------------------\n\n/** @internal — used by the builder; not part of the public API. */\nexport function buildPipelineStep<Args extends StepContext, S extends Step>(config: {\n readonly name: string;\n readonly steps: readonly S[];\n readonly middleware?: readonly StepMiddleware[];\n readonly argsSchema?: StepSchema<Args>;\n readonly strict?: boolean;\n}): AggregateStep<Args, Args & UnionToIntersection<ExtractProvides<S>>> {\n if (config.strict) checkStrictOverlap(config.steps);\n\n const pipelineConfig: PipelineConfig = config as PipelineConfig;\n\n // Track per-execution state for rollback when used as a nested step.\n // INVARIANT: This relies on pipeline.ts storing the exact result.data\n // reference in its outputs array. If the pipeline ever clones\n // result.data, this WeakMap lookup will silently fail.\n // Exercised by the reentrancy test in pipeline.test.ts (\"handles\n // reentrancy — parallel pipelines roll back independently\").\n const stateMap = new WeakMap<object, ExecutionState>();\n\n const run = async (ctx: Readonly<StepContext>): Promise<AggregateResult<StepOutput>> => {\n const outcome = await executePipeline(pipelineConfig, ctx as StepContext);\n if (outcome.result.success) {\n stateMap.set(outcome.result.data, outcome.state);\n }\n return outcome.result;\n };\n\n // Rollback: called when a later outer step fails.\n // The thrown RollbackError is intentional — the pipeline's own\n // executeRollback loop catches it and records it in result.rollback.failed.\n const rollback = async (_ctx: Readonly<StepContext>, output: Readonly<StepOutput>) => {\n const state = stateMap.get(output);\n if (!state) return;\n stateMap.delete(output);\n const report = await executeRollback(state.executed);\n if (report.failed.length > 0) {\n throw new RollbackError(\n `${config.name}: ${report.failed.length} rollback(s) failed`,\n report.failed.map((f) => f.error),\n );\n }\n };\n\n return createStepObject({\n name: config.name,\n requires: config.argsSchema,\n run,\n rollback,\n }) as unknown as AggregateStep<Args, Args & UnionToIntersection<ExtractProvides<S>>>;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Create a pipeline — either directly from steps, or via the fluent\n * builder API.\n *\n * **With steps** — returns an {@link AggregateStep} immediately:\n *\n * ```ts\n * const checkout = pipeline({\n * name: 'checkout',\n * steps: [validateOrder, chargePayment, sendConfirmation],\n * middleware: [logging, timing],\n * argsSchema: z.object({ orderId: z.string() }),\n * });\n * ```\n *\n * **Without steps** — returns a {@link PipelineBuilder} with\n * progressive type narrowing:\n *\n * ```ts\n * const checkout = pipeline({ name: 'checkout' })\n * .step(validateOrder)\n * .step(chargePayment)\n * .build();\n *\n * // With schema (runtime validation):\n * pipeline({\n * name: 'checkout',\n * argsSchema: z.object({ orderId: z.string() }),\n * }).step(validateOrder).build();\n *\n * // Type-only args (no runtime validation):\n * pipeline<{ orderId: string }>({ name: 'checkout' })\n * .step(validateOrder)\n * .build();\n * ```\n *\n * Pipelines ARE steps — they can be used directly in another\n * pipeline's steps array for composition.\n */\n\n// Overload: with steps → AggregateStep\nexport function pipeline<Args extends StepContext = StepContext, S extends Step = Step>(config: {\n readonly name: string;\n readonly steps: readonly S[];\n readonly middleware?: readonly StepMiddleware[];\n readonly argsSchema?: StepSchema<Args>;\n readonly strict?: boolean;\n}): AggregateStep<Args, Args & UnionToIntersection<ExtractProvides<S>>>;\n\n// Overload: without steps → PipelineBuilder\nexport function pipeline<Args extends StepContext = StepContext>(config: {\n readonly name: string;\n readonly middleware?: readonly StepMiddleware[];\n readonly argsSchema?: StepSchema<Args>;\n readonly strict?: boolean;\n}): PipelineBuilder<Args, Args>;\n\n// Implementation\nexport function pipeline<Args extends StepContext, S extends Step = Step>(config: {\n readonly name: string;\n readonly steps?: readonly S[];\n readonly middleware?: readonly StepMiddleware[];\n readonly argsSchema?: StepSchema<Args>;\n readonly strict?: boolean;\n}):\n | AggregateStep<Args, Args & UnionToIntersection<ExtractProvides<S>>>\n | PipelineBuilder<Args, Args> {\n // With steps → build immediately\n if (config.steps) {\n return buildPipelineStep(\n config as {\n readonly name: string;\n readonly steps: readonly S[];\n readonly middleware?: readonly StepMiddleware[];\n readonly argsSchema?: StepSchema<Args>;\n readonly strict?: boolean;\n },\n );\n }\n\n // Without steps → return builder\n return makeBuilder<Args, Args>({\n name: config.name,\n steps: [],\n middleware: config.middleware ? [...config.middleware] : [],\n argsSchema: config.argsSchema,\n strict: config.strict ?? false,\n });\n}\n","import type {\n AggregateResult,\n AggregateStep,\n ExtractProvides,\n ExtractRequires,\n Step,\n StepContext,\n StepOutput,\n UnionToIntersection,\n} from './types.js';\nimport type { AsContext } from './internal.js';\nimport {\n toError,\n aggregateMeta,\n aggregateSuccess,\n aggregateFailure,\n collapseErrors,\n createStepObject,\n} from './internal.js';\nimport { RollbackError } from './errors.js';\nimport { wasSkipped } from './when.js';\n\n// ---------------------------------------------------------------------------\n// Inner step execution result\n// ---------------------------------------------------------------------------\n\ntype InnerResult = {\n step: Step;\n skipped: boolean;\n output?: StepOutput;\n error?: Error;\n};\n\n// ---------------------------------------------------------------------------\n// Execute a single inner step (with conditional check)\n// ---------------------------------------------------------------------------\n\nasync function executeInner(step: Step, ctx: Readonly<StepContext>): Promise<InnerResult> {\n const result = await step.run(ctx);\n if (!result.success) return { step, skipped: false, error: result.error };\n if (wasSkipped(result.meta)) return { step, skipped: true };\n return { step, skipped: false, output: result.data };\n}\n\n// ---------------------------------------------------------------------------\n// parallel()\n// ---------------------------------------------------------------------------\n\n/**\n * Run multiple steps concurrently and merge their outputs.\n *\n * All inner steps receive the same pre-parallel context snapshot and\n * execute via `Promise.allSettled`. On success, outputs are merged in\n * array order (deterministic). On partial failure, succeeded inner\n * steps are rolled back in reverse array order before the failure\n * propagates.\n *\n * Returns an {@link AggregateStep} with orchestration metadata\n * tracking which inner steps executed.\n *\n * Inner steps retain their own `requires`/`provides` validation,\n * `retry`, and `timeout` behavior. Conditional steps (via `when()`)\n * are evaluated per inner step.\n *\n * @example\n * ```ts\n * const p = pipeline({\n * name: 'checkout',\n * steps: [\n * validateOrder,\n * parallel(reserveInventory, chargePayment),\n * sendConfirmation,\n * ],\n * });\n * ```\n *\n * @param steps - Two or more steps to execute concurrently.\n * @returns A frozen {@link AggregateStep} whose `Requires` is the\n * intersection of all inner steps' requires, and `Provides` is the\n * intersection of all inner steps' provides.\n */\nexport function parallel<S extends readonly Step[]>(\n ...steps: [...S]\n): AggregateStep<\n AsContext<UnionToIntersection<ExtractRequires<S[number]>>>,\n AsContext<UnionToIntersection<ExtractProvides<S[number]>>>\n> {\n const name = `parallel(${steps.map((s) => s.name).join(', ')})`;\n const innerSteps: readonly Step[] = steps;\n\n // Track which inner steps ran per execution for outer rollback.\n // INVARIANT: This relies on pipeline.ts storing the exact result.data\n // reference in its outputs array. If the pipeline ever clones\n // result.data, this WeakMap lookup will silently fail.\n // Exercised by parallel.test.ts (\"rolls back all inner steps when\n // a later sequential step fails\").\n type ExecutedEntry = { step: Step; output: StepOutput };\n const executedMap = new WeakMap<object, ExecutedEntry[]>();\n\n // ----- run: execute all inner steps concurrently ----- //\n const run = async (ctx: Readonly<StepContext>): Promise<AggregateResult<StepOutput>> => {\n const frozenCtx = Object.freeze({ ...ctx });\n\n const settled = await Promise.allSettled(\n innerSteps.map((step) => executeInner(step, frozenCtx)),\n );\n\n const succeeded: { step: Step; output: StepOutput }[] = [];\n const allErrors: Error[] = [];\n const executed: string[] = [];\n\n for (const s of settled) {\n if (s.status === 'rejected') {\n allErrors.push(toError(s.reason));\n } else {\n const r = s.value;\n if (r.skipped) continue;\n if (r.output) {\n succeeded.push({ step: r.step, output: r.output });\n executed.push(r.step.name);\n } else if (r.error) {\n allErrors.push(r.error);\n }\n }\n }\n\n if (allErrors.length > 0) {\n // Rollback succeeded inner steps in reverse array order (best-effort)\n const rollbackErrors: Error[] = [];\n for (let i = succeeded.length - 1; i >= 0; i--) {\n const { step, output } = succeeded[i];\n if (step.rollback) {\n try {\n await step.rollback(frozenCtx, output);\n } catch (err) {\n rollbackErrors.push(toError(err));\n }\n }\n }\n const error = collapseErrors(allErrors, `${name}: ${allErrors.length} step(s) failed`);\n if (rollbackErrors.length > 0) {\n error.cause = new RollbackError(\n `${name}: ${rollbackErrors.length} partial-failure rollback(s) failed`,\n rollbackErrors,\n );\n }\n const meta = aggregateMeta(name, frozenCtx, executed);\n return aggregateFailure(error, meta, name);\n }\n\n // Merge outputs in array order (deterministic)\n const merged: StepOutput = {};\n for (const { output } of succeeded) {\n Object.assign(merged, output);\n }\n\n // Track which inner steps executed and their individual outputs\n // for outer rollback. Individual outputs are needed so that nested\n // pipeline rollback handlers can look up their per-execution state.\n executedMap.set(\n merged,\n succeeded.map((s) => ({ step: s.step, output: s.output })),\n );\n\n const meta = aggregateMeta(name, frozenCtx, executed);\n return aggregateSuccess(merged, meta);\n };\n\n // ----- rollback: called when a later sequential step fails ----- //\n // The pipeline passes the merged output. Only inner steps that\n // actually executed are rolled back, and each receives its own\n // individual output (not the merged superset).\n // Rollback is called by the outer pipeline when a later step fails.\n // The thrown RollbackError is intentional — the pipeline's own\n // executeRollback loop catches it and records it in result.rollback.failed.\n const rollback: NonNullable<Step['rollback']> = async (ctx, mergedOutput) => {\n const entries = executedMap.get(mergedOutput);\n if (!entries) return;\n executedMap.delete(mergedOutput);\n const errors: Error[] = [];\n for (let i = entries.length - 1; i >= 0; i--) {\n const { step, output } = entries[i];\n if (!step.rollback) continue;\n try {\n await step.rollback(ctx, output);\n } catch (err) {\n errors.push(toError(err));\n }\n }\n if (errors.length > 0) {\n throw new RollbackError(`${name}: ${errors.length} rollback(s) failed`, errors);\n }\n };\n\n return createStepObject({\n name,\n run,\n rollback,\n }) as unknown as AggregateStep<\n AsContext<UnionToIntersection<ExtractRequires<S[number]>>>,\n AsContext<UnionToIntersection<ExtractProvides<S[number]>>>\n >;\n}\n","import type {\n AggregateResult,\n AggregateStep,\n ExtractProvides,\n ExtractRequires,\n Step,\n StepContext,\n StepOutput,\n UnionToIntersection,\n} from './types.js';\nimport type { AsContext } from './internal.js';\nimport {\n toError,\n aggregateMeta,\n aggregateSuccess,\n aggregateFailure,\n createStepObject,\n} from './internal.js';\nimport { PredicateError, RollbackError } from './errors.js';\n\n/** A [predicate, step] tuple used by {@link choice}. */\ntype BranchTuple = readonly [(ctx: Readonly<StepContext>) => boolean, Step];\n\n/** Extract the Requires type from a branch tuple's step. */\ntype BranchRequires<T> = T extends readonly [unknown, infer S extends Step]\n ? ExtractRequires<S>\n : T extends Step\n ? ExtractRequires<T>\n : StepContext;\n\n/** Extract the Provides type from a branch tuple's step. */\ntype BranchProvides<T> = T extends readonly [unknown, infer S extends Step]\n ? ExtractProvides<S>\n : T extends Step\n ? ExtractProvides<T>\n : StepContext;\n\n// ---------------------------------------------------------------------------\n// Normalize args: convert trailing bare step into a [() => true, step] tuple\n// ---------------------------------------------------------------------------\n\ntype NormalizedBranch = readonly [(ctx: Readonly<StepContext>) => boolean, Step];\n\nfunction normalizeBranches(args: readonly (BranchTuple | Step)[]): readonly NormalizedBranch[] {\n return args.map((arg): NormalizedBranch => {\n if (Array.isArray(arg)) return arg as NormalizedBranch;\n // Bare step → default branch\n return [() => true, arg as Step];\n });\n}\n\n// ---------------------------------------------------------------------------\n// choice()\n// ---------------------------------------------------------------------------\n\n/**\n * Execute the first branch whose predicate returns `true`.\n *\n * Similar to an AWS Step Functions Choice state — predicates are evaluated\n * in order, and the first match wins. Exactly one branch executes. If no\n * predicate matches, the step returns empty data with an empty\n * `stepsExecuted` — the enclosing pipeline treats it as a no-op (like a\n * skipped `when()`).\n *\n * A bare step (without a predicate tuple) can be passed as the last argument\n * to serve as a default branch — it is equivalent to `[() => true, step]`.\n *\n * Returns an {@link AggregateStep} with orchestration metadata\n * tracking which branch executed.\n *\n * All branches should provide the same output shape so that\n * subsequent steps can rely on a consistent context type.\n *\n * @example\n * ```ts\n * const p = pipeline({\n * name: 'payment',\n * steps: [\n * validateOrder,\n * choice(\n * [(ctx) => ctx.method === 'card', chargeCard],\n * [(ctx) => ctx.method === 'bank', chargeBankTransfer],\n * chargeDefault, // default\n * ),\n * sendReceipt,\n * ],\n * });\n * ```\n *\n * @param branches - One or more `[predicate, step]` tuples, optionally\n * followed by a bare step as the default.\n * @returns A frozen {@link AggregateStep} that executes the first\n * matching branch.\n */\n\n// Overload: all branches are tuples (no default)\nexport function choice<B extends readonly BranchTuple[]>(\n ...branches: [...B]\n): AggregateStep<\n AsContext<UnionToIntersection<BranchRequires<B[number]>>>,\n AsContext<UnionToIntersection<BranchProvides<B[number]>>>\n>;\n\n// Overload: tuples + trailing bare step as default\nexport function choice<B extends readonly BranchTuple[], D extends Step>(\n ...args: [...B, D]\n): AggregateStep<\n AsContext<UnionToIntersection<BranchRequires<B[number]> | ExtractRequires<D>>>,\n AsContext<UnionToIntersection<BranchProvides<B[number]> | ExtractProvides<D>>>\n>;\n\n// Implementation\nexport function choice(...args: (BranchTuple | Step)[]): AggregateStep<StepContext, StepContext> {\n const innerBranches = normalizeBranches(args);\n const name = `choice(${innerBranches.map(([, step]) => step.name).join(', ')})`;\n\n // Track which branch ran per execution for rollback.\n // INVARIANT: This relies on pipeline.ts storing the exact result.data\n // reference in its outputs array. If the pipeline ever clones\n // result.data, this WeakMap lookup will silently fail.\n // Exercised by choice.test.ts (\"rolls back the matched branch when\n // a later step fails\").\n const branchMap = new WeakMap<object, number>();\n\n const run = async (ctx: Readonly<StepContext>): Promise<AggregateResult<StepOutput>> => {\n const frozenCtx = Object.freeze({ ...ctx });\n\n for (let i = 0; i < innerBranches.length; i++) {\n const [predicate, step] = innerBranches[i];\n\n // Evaluate predicate\n let matches: boolean;\n try {\n matches = predicate(frozenCtx);\n } catch (err) {\n const cause = toError(err);\n const error = new PredicateError(`${name} predicate: ${cause.message}`);\n error.cause = cause;\n const meta = aggregateMeta(name, frozenCtx, []);\n return aggregateFailure(error, meta, name);\n }\n\n if (!matches) continue;\n\n const result = await step.run(frozenCtx);\n if (!result.success) {\n const meta = aggregateMeta(name, frozenCtx, [step.name]);\n return aggregateFailure(result.error, meta, name);\n }\n\n // Track which branch ran for rollback\n branchMap.set(result.data, i);\n\n const meta = aggregateMeta(name, frozenCtx, [step.name]);\n return aggregateSuccess(result.data, meta);\n }\n\n // No branch matched — nothing to execute, like a skipped when()\n const meta = aggregateMeta(name, frozenCtx, []);\n return aggregateSuccess({}, meta);\n };\n\n // Rollback: only the matched branch needs rollback.\n // The thrown RollbackError is intentional — the pipeline's own\n // executeRollback loop catches it and records it in result.rollback.failed.\n const rollback: NonNullable<Step['rollback']> = async (ctx, output) => {\n const branchIndex = branchMap.get(output);\n if (branchIndex === undefined) return;\n branchMap.delete(output);\n const [, step] = innerBranches[branchIndex];\n if (step.rollback) {\n try {\n await step.rollback(ctx, output);\n } catch (err) {\n throw new RollbackError(`${name}: 1 rollback(s) failed`, [toError(err)]);\n }\n }\n };\n\n return createStepObject({\n name,\n run,\n rollback,\n }) as unknown as AggregateStep<StepContext, StepContext>;\n}\n","import type {\n ExtractProvides,\n ExtractRequires,\n Step,\n StepContext,\n StepOutput,\n StepResult,\n TypedStep,\n} from './types.js';\nimport type { AsContext } from './internal.js';\nimport {\n toError,\n baseMeta,\n stepSuccess,\n stepFailure,\n collapseErrors,\n createStepObject,\n} from './internal.js';\nimport { RollbackError } from './errors.js';\n\n// ---------------------------------------------------------------------------\n// Type helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Given a step's `Requires` type and a mapping from context array keys to\n * step scalar keys, produce the context type that `distribute` requires:\n *\n * - Scalar keys consumed by the mapping are removed from Requires.\n * - Array keys are added, each typed as an array of the corresponding\n * scalar key's type.\n * - All other keys pass through unchanged.\n *\n * @example\n * ```ts\n * // Step requires { accountId: string, orgId: string }\n * // Mapping: { accountIds: 'accountId' }\n * // Result: { orgId: string, accountIds: string[] }\n * ```\n */\ntype ArrayifyMapping<R extends StepContext, M extends Record<string, keyof R & string>> = Omit<\n R,\n M[keyof M]\n> & {\n [K in keyof M & string]: R[M[K] & keyof R][];\n};\n\n// ---------------------------------------------------------------------------\n// Cross-product computation\n// ---------------------------------------------------------------------------\n\n/**\n * Compute the cross product of all mapped collections.\n *\n * For mapping `{ accountIds: 'accountId', regionIds: 'regionId' }` and\n * context `{ accountIds: ['a1', 'a2'], regionIds: ['r1', 'r2'] }`,\n * produces:\n *\n * ```\n * [\n * { accountId: 'a1', regionId: 'r1' },\n * { accountId: 'a1', regionId: 'r2' },\n * { accountId: 'a2', regionId: 'r1' },\n * { accountId: 'a2', regionId: 'r2' },\n * ]\n * ```\n *\n * If any mapped collection is empty, the result is an empty array (the\n * cross product of anything with an empty set is empty).\n */\nfunction crossProduct(mapping: Record<string, string>, ctx: Readonly<StepContext>): StepContext[] {\n const entries = Object.entries(mapping);\n let combinations: StepContext[] = [{}];\n\n for (const [contextKey, stepKey] of entries) {\n const items = ctx[contextKey];\n if (!Array.isArray(items) || items.length === 0) return [];\n const next: StepContext[] = [];\n for (const combo of combinations) {\n for (const item of items) {\n next.push({ ...combo, [stepKey]: item as unknown });\n }\n }\n combinations = next;\n }\n\n return combinations;\n}\n\n// ---------------------------------------------------------------------------\n// distribute()\n// ---------------------------------------------------------------------------\n\n/**\n * Distribute collections from context across a single step, running the\n * step once per combination (cross product) of items, concurrently.\n *\n * Similar to an AWS Step Functions Map state, but with declarative\n * key mapping and cross-product support for multiple collections.\n *\n * The mapping object connects context array keys to the step's scalar\n * input keys. All non-mapped context keys pass through unchanged.\n *\n * @example\n * ```ts\n * // Single collection — run sendEmail once per accountId\n * const d = distribute(\n * 'emails',\n * { accountIds: 'accountId' },\n * sendEmailStep,\n * );\n * // Requires: { orgId: string, accountIds: string[] }\n * // Provides: { emails: { emailId: string }[] }\n *\n * // Cross product — run once per (accountId, regionId) pair\n * const d = distribute(\n * 'reports',\n * { accountIds: 'accountId', regionIds: 'regionId' },\n * generateReportStep,\n * );\n * // 2 accounts × 3 regions = 6 concurrent executions\n * ```\n *\n * Items run concurrently via `Promise.allSettled`. On partial failure,\n * succeeded items are rolled back (if the step has a rollback handler).\n * On external failure (a later pipeline step fails), all items are\n * rolled back.\n *\n * @param key - The output key under which results are collected.\n * @param mapping - Maps context array keys to step scalar keys.\n * @param step - The step to execute for each combination.\n * @returns A frozen {@link TypedStep} that provides `{ [key]: Result[] }`.\n */\nexport function distribute<\n Name extends string,\n S extends Step,\n M extends Record<string, keyof ExtractRequires<S> & string>,\n>(\n key: Name,\n mapping: M,\n step: S,\n): TypedStep<\n AsContext<ArrayifyMapping<ExtractRequires<S>, M>>,\n Record<Name, ExtractProvides<S>[]>\n> {\n const stepName = `distribute(${key}, ${step.name})`;\n const arrayKeys = new Set(Object.keys(mapping));\n\n // Track per-execution data for rollback.\n // INVARIANT: This relies on pipeline.ts storing the exact result.data\n // reference in its outputs array. If the pipeline ever clones\n // result.data, this WeakMap lookup will silently fail.\n // Exercised by distribute.test.ts (\"rolls back all items on external\n // failure\").\n const executionMap = new WeakMap<object, { combinations: StepContext[]; baseCtx: StepContext }>();\n\n const run = async (ctx: Readonly<StepContext>): Promise<StepResult<StepOutput>> => {\n const frozenCtx = Object.freeze({ ...ctx });\n const meta = baseMeta(stepName, frozenCtx);\n\n // Compute cross product of all mapped collections\n const combinations = crossProduct(mapping, frozenCtx);\n\n // Base context: everything except the array keys\n const baseCtx: StepContext = {};\n for (const k of Object.keys(frozenCtx)) {\n if (!arrayKeys.has(k)) baseCtx[k] = frozenCtx[k];\n }\n\n // Run step for each combination concurrently\n const settled = await Promise.allSettled(\n combinations.map(async (combo) => {\n const itemCtx = Object.freeze({ ...baseCtx, ...combo });\n return step.run(itemCtx);\n }),\n );\n\n // Check for errors first\n const succeeded: { index: number; output: StepOutput }[] = [];\n const allErrors: Error[] = [];\n\n for (let i = 0; i < settled.length; i++) {\n const s = settled[i];\n if (s.status === 'rejected') {\n allErrors.push(toError(s.reason));\n } else if (!s.value.success) {\n allErrors.push(s.value.error);\n } else {\n succeeded.push({ index: i, output: s.value.data });\n }\n }\n\n if (allErrors.length > 0) {\n // Roll back succeeded items in reverse order (best-effort)\n const rollbackErrors: Error[] = [];\n if (step.rollback) {\n for (let i = succeeded.length - 1; i >= 0; i--) {\n try {\n const combo = combinations[succeeded[i].index];\n const itemCtx = Object.freeze({ ...baseCtx, ...combo });\n await step.rollback(itemCtx, succeeded[i].output);\n } catch (err) {\n rollbackErrors.push(toError(err));\n }\n }\n }\n const error = collapseErrors(allErrors, `${stepName}: ${allErrors.length} item(s) failed`);\n if (rollbackErrors.length > 0) {\n error.cause = new RollbackError(\n `${stepName}: ${rollbackErrors.length} partial-failure rollback(s) failed`,\n rollbackErrors,\n );\n }\n return stepFailure(error, meta, stepName);\n }\n\n // Collect results in cross-product order\n const results = succeeded.map((s) => s.output);\n const data: StepOutput = { [key]: results };\n executionMap.set(data, { combinations, baseCtx });\n return stepSuccess(data, meta);\n };\n\n // Rollback: called when a later pipeline step fails.\n // The thrown RollbackError is intentional — the pipeline's own\n // executeRollback loop catches it and records it in result.rollback.failed.\n const rollback: Step['rollback'] = step.rollback\n ? async (_ctx, output) => {\n const exec = executionMap.get(output);\n if (!exec) return;\n executionMap.delete(output);\n const results = (output as Record<string, unknown>)[key] as StepOutput[];\n const errors: Error[] = [];\n for (let i = results.length - 1; i >= 0; i--) {\n try {\n const itemCtx = Object.freeze({\n ...exec.baseCtx,\n ...exec.combinations[i],\n });\n await step.rollback!(itemCtx, results[i]);\n } catch (err) {\n errors.push(toError(err));\n }\n }\n if (errors.length > 0) {\n throw new RollbackError(`${stepName}: ${errors.length} rollback(s) failed`, errors);\n }\n }\n : undefined;\n\n return createStepObject({\n name: stepName,\n run: run as Step['run'],\n rollback,\n }) as unknown as TypedStep<\n AsContext<ArrayifyMapping<ExtractRequires<S>, M>>,\n Record<Name, ExtractProvides<S>[]>\n >;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACoCO,IAAM,gBAAN,cAA4B,MAAM;AAAA;AAAA,EAE9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMT,YAAY,MAAyB,SAAiB;AACpD,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,0BAAN,cAAsC,cAAc;AAAA,EACzD,YAAY,SAAiB;AAC3B,UAAM,uBAAuB,OAAO;AACpC,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,0BAAN,cAAsC,cAAc;AAAA,EACzD,YAAY,SAAiB;AAC3B,UAAM,uBAAuB,OAAO;AACpC,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,sBAAN,cAAkC,cAAc;AAAA,EACrD,YAAY,SAAiB;AAC3B,UAAM,mBAAmB,OAAO;AAChC,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,iBAAN,cAA6B,cAAc;AAAA,EAChD,YAAY,SAAiB;AAC3B,UAAM,aAAa,OAAO;AAC1B,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,eAAN,cAA2B,cAAc;AAAA;AAAA,EAErC;AAAA,EAET,YAAY,SAAiB,WAAmB;AAC9C,UAAM,WAAW,OAAO;AACxB,SAAK,OAAO;AACZ,SAAK,YAAY;AAAA,EACnB;AACF;AAGO,IAAM,sBAAN,cAAkC,cAAc;AAAA;AAAA,EAE5C;AAAA,EAET,YAAY,SAAiB,UAAkB;AAC7C,UAAM,mBAAmB,OAAO;AAChC,SAAK,OAAO;AACZ,SAAK,WAAW;AAAA,EAClB;AACF;AAGO,IAAM,qBAAN,cAAiC,cAAc;AAAA;AAAA,EAE3C;AAAA;AAAA,EAEA;AAAA,EAET,YAAY,SAAiB,KAAa,OAAkC;AAC1E,UAAM,kBAAkB,OAAO;AAC/B,SAAK,OAAO;AACZ,SAAK,MAAM;AACX,SAAK,QAAQ;AAAA,EACf;AACF;AAGO,IAAM,eAAN,cAA2B,cAAc;AAAA;AAAA,EAErC;AAAA,EAET,YAAY,SAAiB,eAAwB;AACnD,UAAM,WAAW,OAAO;AACxB,SAAK,OAAO;AACZ,SAAK,gBAAgB;AAAA,EACvB;AACF;AAGO,IAAM,gBAAN,cAA4B,cAAc;AAAA;AAAA,EAEtC;AAAA,EAET,YAAY,SAAiB,SAA2B,CAAC,GAAG;AAC1D,UAAM,YAAY,OAAO;AACzB,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,QAAI,OAAO,WAAW,EAAG,MAAK,QAAQ,OAAO,CAAC;AAAA,aACrC,OAAO,SAAS,EAAG,MAAK,QAAQ,IAAI,eAAe,QAAQ,OAAO;AAAA,EAC7E;AACF;;;AChIO,SAAS,QAAQ,KAAqB;AAC3C,MAAI,eAAe,MAAO,QAAO;AACjC,SAAO,IAAI,aAAa,OAAO,GAAG,GAAG,GAAG;AAC1C;AAGO,IAAM,iBAAiC,OAAO,OAAO;AAAA,EAC1D,WAAW,OAAO,OAAO,CAAC,CAAa;AAAA,EACvC,QAAQ,OAAO,OAAO,CAAC,CAAY;AACrC,CAAC;AAGM,SAAS,aACd,QACQ;AACR,SAAO,OACJ,IAAI,CAAC,MAAO,EAAE,KAAK,SAAS,IAAI,GAAG,EAAE,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,EAAE,OAAQ,EAChF,KAAK,IAAI;AACd;AAQO,SAAS,eAAe,QAAiB,SAAwB;AACtE,SAAO,OAAO,WAAW,IAAI,OAAO,CAAC,IAAI,IAAI,eAAe,QAAQ,OAAO;AAC7E;AASO,SAAS,iBAAiB,QAQxB;AACP,SAAO,OAAO,OAAO;AAAA,IACnB,MAAM,OAAO;AAAA,IACb,UAAU,OAAO,YAAY;AAAA,IAC7B,UAAU,OAAO,YAAY;AAAA,IAC7B,KAAK,OAAO;AAAA,IACZ,UAAU,OAAO,YAAY;AAAA,IAC7B,OAAO,OAAO,SAAS;AAAA,IACvB,SAAS,OAAO,WAAW;AAAA,EAC7B,CAAC;AACH;AAQO,SAAS,SAAS,MAAc,MAAuC;AAC5E,SAAO,OAAO,OAAO,EAAE,MAAM,KAAK,CAAC;AACrC;AAQO,SAAS,cACd,MACA,MACA,eACe;AACf,SAAO,OAAO,OAAO,EAAE,MAAM,MAAM,cAAc,CAAC;AACpD;AAQO,SAAS,YAAkC,MAAS,MAAgC;AACzF,SAAO,OAAO,OAAO,EAAE,SAAS,MAAM,MAAM,KAAK,CAAC;AACpD;AASO,SAAS,YACd,OACA,MACA,YACA,WAA2B,gBACd;AACb,SAAO,OAAO,OAAO,EAAE,SAAS,OAAO,OAAO,MAAM,YAAY,SAAS,CAAC;AAC5E;AAOO,SAAS,iBACd,MACA,MACqB;AACrB,SAAO,OAAO,OAAO,EAAE,SAAS,MAAM,MAAM,KAAK,CAAC;AACpD;AAOO,SAAS,iBACd,OACA,MACA,YACA,WAA2B,gBACT;AAClB,SAAO,OAAO,OAAO,EAAE,SAAS,OAAO,OAAO,MAAM,YAAY,SAAS,CAAC;AAC5E;;;AClHA,SAAS,YAAe,IAA0B,UAAkB,IAA8B;AAChG,SAAO,YAAY;AACjB,QAAI;AACJ,UAAM,UAAU,IAAI,QAAe,CAAC,GAAG,WAAW;AAChD,cAAQ,WAAW,MAAM;AACvB,eAAO,IAAI,aAAa,GAAG,QAAQ,oBAAoB,EAAE,MAAM,EAAE,CAAC;AAAA,MACpE,GAAG,EAAE;AAAA,IACP,CAAC;AACD,QAAI;AACF,aAAO,MAAM,QAAQ,KAAK,CAAC,QAAQ,QAAQ,GAAG,CAAC,GAAG,OAAO,CAAC;AAAA,IAC5D,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AACF;AAEA,SAAS,aAAa,QAAqB,SAAyB;AAClE,QAAM,OAAO,OAAO,SAAS;AAC7B,MAAI,SAAS,EAAG,QAAO;AACvB,QAAM,WAAW,OAAO,WAAW;AACnC,SAAO,aAAa,gBAAgB,OAAO,MAAM,UAAU,KAAK,OAAO;AACzE;AAEA,SAAS,UACP,IACA,UACA,QACkB;AAClB,SAAO,YAAY;AACjB,QAAI;AACJ,UAAM,SAAkB,CAAC;AAEzB,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAAS,KAAK;AACZ,kBAAY,QAAQ,GAAG;AACvB,aAAO,KAAK,SAAS;AAAA,IACvB;AAEA,aAAS,UAAU,GAAG,WAAW,OAAO,OAAO,WAAW;AACxD,UAAI,OAAO,WAAW,CAAC,OAAO,QAAQ,MAAM,EAAG,OAAM;AAErD,YAAM,QAAQ,aAAa,QAAQ,OAAO;AAC1C,UAAI,QAAQ,EAAG,OAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,MAAM,EAAE,MAAS,GAAG,KAAK,CAAC;AAE7E,UAAI;AACF,eAAO,MAAM,GAAG;AAAA,MAClB,SAAS,KAAK;AACZ,oBAAY,QAAQ,GAAG;AACvB,eAAO,KAAK,SAAS;AAAA,MACvB;AAAA,IACF;AAEA,UAAM,QAAQ,IAAI;AAAA,MAChB,GAAG,QAAQ,iBAAiB,OAAO,KAAK;AAAA,MACxC,OAAO,QAAQ;AAAA,IACjB;AACA,UAAM,QAAQ,OAAO,WAAW,IAAI,OAAO,CAAC,IAAI,IAAI,eAAe,QAAQ,MAAM,OAAO;AACxF,UAAM;AAAA,EACR;AACF;AAEA,SAAS,cACP,QACgD;AAChD,MAAI,KAAK,CAAC,QAA4B,QAAQ,QAAQ,OAAO,IAAI,GAAG,CAAC;AACrE,MAAI,OAAO,YAAY,QAAW;AAChC,UAAM,SAAS;AACf,UAAM,KAAK,OAAO;AAClB,SAAK,CAAC,QAAQ,YAAY,MAAM,OAAO,GAAG,GAAG,OAAO,MAAM,EAAE,EAAE;AAAA,EAChE;AACA,MAAI,OAAO,UAAU,QAAW;AAC9B,UAAM,SAAS;AACf,UAAM,SAAS,OAAO;AACtB,SAAK,CAAC,QAAQ,UAAU,MAAM,OAAO,GAAG,GAAG,OAAO,MAAM,MAAM,EAAE;AAAA,EAClE;AACA,SAAO;AACT;AA0CO,SAAS,KACd,QAC+B;AAC/B,QAAM,UAAU,cAAc,MAAM;AAEpC,QAAM,MAAM,OAAO,QAAgE;AACjF,UAAM,YAAY,OAAO,OAAO,EAAE,GAAG,IAAI,CAAC;AAC1C,UAAM,OAAO,SAAS,OAAO,MAAM,SAAS;AAG5C,QAAI,OAAO,UAAU;AACnB,YAAM,SAAS,OAAO,SAAS,UAAU,SAAS;AAClD,UAAI,CAAC,OAAO,SAAS;AACnB,cAAM,QAAQ,IAAI;AAAA,UAChB,GAAG,OAAO,IAAI,cAAc,aAAa,OAAO,MAAM,MAAM,CAAC;AAAA,QAC/D;AACA,eAAO,YAAY,OAAO,MAAM,OAAO,IAAI;AAAA,MAC7C;AAAA,IACF;AAGA,QAAI;AACJ,QAAI;AACF,aAAO,MAAM,QAAQ,SAA+B;AAAA,IACtD,SAAS,KAAK;AACZ,aAAO,YAAY,QAAQ,GAAG,GAAG,MAAM,OAAO,IAAI;AAAA,IACpD;AAGA,QAAI,OAAO,UAAU;AACnB,YAAM,SAAS,OAAO,SAAS,UAAU,IAAI;AAC7C,UAAI,CAAC,OAAO,SAAS;AACnB,cAAM,QAAQ,IAAI;AAAA,UAChB,GAAG,OAAO,IAAI,cAAc,aAAa,OAAO,MAAM,MAAM,CAAC;AAAA,QAC/D;AACA,eAAO,YAAY,OAAO,MAAM,OAAO,IAAI;AAAA,MAC7C;AAAA,IACF;AAEA,WAAO,YAAY,MAA+B,IAAI;AAAA,EACxD;AAEA,SAAO,iBAAiB;AAAA,IACtB,MAAM,OAAO;AAAA,IACb,UAAU,OAAO;AAAA,IACjB,UAAU,OAAO;AAAA,IACjB;AAAA,IACA,UAAU,OAAO,WACb,OAAO,KAA4B,WAAkC;AACnE,YAAM,OAAO,SAAU,KAA2B,MAA4B;AAAA,IAChF,IACA;AAAA,IACJ,OAAO,OAAO;AAAA,IACd,SAAS,OAAO;AAAA,EAClB,CAAC;AACH;;;AChIO,SAAS,YACd,OAC4B;AAC5B,SAAO,OAAO,OAAO;AAAA,IACnB,MAAM,CAAiBA,UACrB,YAA4C;AAAA,MAC1C,GAAG;AAAA,MACH,OAAO,CAAC,GAAG,MAAM,OAAOA,KAAI;AAAA,IAC9B,CAAC;AAAA,IAEH,KAAK,IAAI,eACP,YAAuB;AAAA,MACrB,GAAG;AAAA,MACH,YAAY,CAAC,GAAG,MAAM,YAAY,GAAG,UAAU;AAAA,IACjD,CAAC;AAAA,IAEH,OAAO,MACL,kBAAkB;AAAA,MAChB,MAAM,MAAM;AAAA,MACZ,OAAO,MAAM;AAAA,MACb,YAAY,MAAM,WAAW,SAAS,IAAI,MAAM,aAAa;AAAA,MAC7D,YAAY,MAAM;AAAA,MAClB,QAAQ,MAAM,SAAS,OAAO;AAAA,IAChC,CAAC;AAAA,EACL,CAAC;AACH;;;ACxCO,SAAS,gBACd,aACAC,OACA,UACc;AACd,SAAO,YAAY,YAA0B,CAAC,MAAM,OAAO,GAAGA,OAAM,IAAI,GAAG,QAAQ;AACrF;;;ACvCO,SAAS,KACd,WACAC,OACmC;AACnC,QAAM,OAAOA,MAAK;AAClB,QAAM,YAAYA;AAElB,QAAM,MAAM,OAAO,QAAqE;AACtF,UAAM,YAAY,OAAO,OAAO,EAAE,GAAG,IAAI,CAAC;AAE1C,QAAI;AACJ,QAAI;AACF,kBAAY,UAAU,SAA+B;AAAA,IACvD,SAAS,KAAK;AACZ,YAAM,QAAQ,QAAQ,GAAG;AACzB,YAAM,QAAQ,IAAI,eAAe,GAAG,IAAI,eAAe,MAAM,OAAO,EAAE;AACtE,YAAM,QAAQ;AACd,aAAO,iBAAiB,OAAO,cAAc,MAAM,WAAW,CAAC,CAAC,GAAG,IAAI;AAAA,IACzE;AAEA,QAAI,CAAC,WAAW;AACd,aAAO,iBAAiB,CAAC,GAAG,cAAc,MAAM,WAAW,CAAC,CAAC,CAAC;AAAA,IAChE;AAEA,UAAM,SAAS,MAAM,UAAU,IAAI,SAAS;AAC5C,QAAI,CAAC,OAAO,SAAS;AACnB,aAAO,iBAAiB,OAAO,OAAO,cAAc,MAAM,WAAW,CAAC,IAAI,CAAC,GAAG,IAAI;AAAA,IACpF;AAEA,WAAO,iBAAiB,OAAO,MAAM,cAAc,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;AAAA,EAC7E;AAEA,SAAO,iBAAiB;AAAA,IACtB;AAAA,IACA;AAAA,IACA,UAAU,UAAU;AAAA,IACpB,UAAU,UAAU;AAAA,IACpB,UAAU,UAAU;AAAA,EACtB,CAAC;AACH;AASO,SAAS,WAAW,MAA8D;AACvF,SAAO,mBAAmB,QAAS,KAAuB,cAAc,WAAW;AACrF;;;ACrBA,SAAS,mBAAmB,OAA8B;AACxD,QAAM,OAAO,oBAAI,IAAoB;AAErC,aAAWC,SAAQ,OAAO;AACxB,QAAI,CAACA,MAAK,SAAU;AAGpB,UAAM,QAASA,MAAK,SAAqC;AACzD,QAAI,CAAC,SAAS,OAAO,UAAU,SAAU;AAEzC,eAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AACpC,YAAM,WAAW,KAAK,IAAI,GAAG;AAC7B,UAAI,UAAU;AACZ,cAAM,IAAI;AAAA,UACR,qBAAqB,GAAG,0BAA0B,QAAQ,UAAUA,MAAK,IAAI;AAAA,UAC7E;AAAA,UACA,CAAC,UAAUA,MAAK,IAAI;AAAA,QACtB;AAAA,MACF;AACA,WAAK,IAAI,KAAKA,MAAK,IAAI;AAAA,IACzB;AAAA,EACF;AACF;AAoBA,SAAS,qBAAqB,MAAmC;AAC/D,SAAO;AAAA,IACL,SAAS,OAAO,OAAO,EAAE,GAAG,KAAK,CAAC;AAAA,IAClC,UAAU,CAAC;AAAA,IACX,eAAe,CAAC;AAAA,EAClB;AACF;AAWA,eAAe,gBAAgB,UAAiE;AAC9F,QAAM,YAAsB,CAAC;AAC7B,QAAM,SAA4B,CAAC;AAEnC,WAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7C,UAAM,QAAQ,SAAS,CAAC;AACxB,QAAI,CAAC,MAAM,KAAK,SAAU;AAE1B,QAAI;AACF,YAAM,MAAM,KAAK,SAAS,MAAM,UAAU,MAAM,MAAM;AACtD,gBAAU,KAAK,MAAM,KAAK,IAAI;AAAA,IAChC,SAAS,KAAK;AACZ,aAAO,KAAK,EAAE,MAAM,MAAM,KAAK,MAAM,OAAO,QAAQ,GAAG,EAAE,CAAC;AAAA,IAC5D;AAAA,EACF;AAEA,SAAO,OAAO,OAAO,EAAE,WAAW,OAAO,CAAC;AAC5C;AAuBA,eAAe,gBACb,QACA,MAC2B;AAC3B,QAAM,aAAa,OAAO,OAAO,EAAE,GAAG,KAAK,CAAC;AAG5C,MAAI,OAAO,YAAY;AACrB,UAAM,SAAS,OAAO,WAAW,UAAU,UAAU;AACrD,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,QAAQ,IAAI;AAAA,QAChB,GAAG,OAAO,IAAI,UAAU,aAAa,OAAO,MAAM,MAAM,CAAC;AAAA,MAC3D;AACA,YAAMC,QAAO,cAAc,OAAO,MAAM,YAAY,CAAC,CAAC;AACtD,YAAMC,SAAQ,qBAAqB,UAAU;AAC7C,aAAO,EAAE,QAAQ,iBAAiB,OAAOD,OAAM,OAAO,IAAI,GAAG,OAAAC,OAAM;AAAA,IACrE;AAAA,EACF;AAEA,QAAM,QAAQ,qBAAqB,UAAU;AAC7C,QAAM,cAAc,OAAO,cAAc,CAAC;AAE1C,aAAWF,SAAQ,OAAO,OAAO;AAE/B,UAAM,WAAW,MAAM;AAGvB,UAAM,WACJ,YAAY,SAAS,IACjB;AAAA,MACE;AAAA,MACA,EAAE,MAAMA,MAAK,MAAM,UAAUA,MAAK,UAAU,UAAUA,MAAK,SAAS;AAAA,MACpE,CAAC,QAAQA,MAAK,IAAI,GAAG;AAAA,IACvB,IACA,CAAC,QAA+BA,MAAK,IAAI,GAAG;AAGlD,QAAI;AACJ,QAAI;AACF,eAAS,MAAM,SAAS,MAAM,OAAO;AAAA,IACvC,SAAS,KAAK;AACZ,YAAM,QAAQ,QAAQ,GAAG;AACzB,YAAM,WAAW,MAAM,gBAAgB,MAAM,QAAQ;AACrD,YAAMC,QAAO,cAAc,OAAO,MAAM,YAAY,CAAC,GAAG,MAAM,aAAa,CAAC;AAC5E,aAAO,EAAE,QAAQ,iBAAiB,OAAOA,OAAMD,MAAK,MAAM,QAAQ,GAAG,MAAM;AAAA,IAC7E;AAEA,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,WAAW,MAAM,gBAAgB,MAAM,QAAQ;AACrD,YAAMC,QAAO,cAAc,OAAO,MAAM,YAAY,CAAC,GAAG,MAAM,aAAa,CAAC;AAC5E,aAAO,EAAE,QAAQ,iBAAiB,OAAO,OAAOA,OAAMD,MAAK,MAAM,QAAQ,GAAG,MAAM;AAAA,IACpF;AAGA,QAAI,WAAW,OAAO,IAAI,EAAG;AAG7B,UAAM,SAAS,OAAO;AACtB,UAAM,SAAS,KAAK,EAAE,MAAAA,OAAM,UAAU,OAAO,CAAC;AAC9C,UAAM,cAAc,KAAKA,MAAK,IAAI;AAClC,UAAM,UAAU,OAAO,OAAO,EAAE,GAAG,MAAM,SAAS,GAAG,OAAO,CAAC;AAAA,EAC/D;AAEA,QAAM,OAAO,cAAc,OAAO,MAAM,YAAY,CAAC,GAAG,MAAM,aAAa,CAAC;AAC5E,SAAO,EAAE,QAAQ,iBAAiB,MAAM,SAAS,IAAI,GAAG,MAAM;AAChE;AAOO,SAAS,kBAA4D,QAMJ;AACtE,MAAI,OAAO,OAAQ,oBAAmB,OAAO,KAAK;AAElD,QAAM,iBAAiC;AAQvC,QAAM,WAAW,oBAAI,QAAgC;AAErD,QAAM,MAAM,OAAO,QAAqE;AACtF,UAAM,UAAU,MAAM,gBAAgB,gBAAgB,GAAkB;AACxE,QAAI,QAAQ,OAAO,SAAS;AAC1B,eAAS,IAAI,QAAQ,OAAO,MAAM,QAAQ,KAAK;AAAA,IACjD;AACA,WAAO,QAAQ;AAAA,EACjB;AAKA,QAAM,WAAW,OAAO,MAA6B,WAAiC;AACpF,UAAM,QAAQ,SAAS,IAAI,MAAM;AACjC,QAAI,CAAC,MAAO;AACZ,aAAS,OAAO,MAAM;AACtB,UAAM,SAAS,MAAM,gBAAgB,MAAM,QAAQ;AACnD,QAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,YAAM,IAAI;AAAA,QACR,GAAG,OAAO,IAAI,KAAK,OAAO,OAAO,MAAM;AAAA,QACvC,OAAO,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAEA,SAAO,iBAAiB;AAAA,IACtB,MAAM,OAAO;AAAA,IACb,UAAU,OAAO;AAAA,IACjB;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAgEO,SAAS,SAA0D,QAQ1C;AAE9B,MAAI,OAAO,OAAO;AAChB,WAAO;AAAA,MACL;AAAA,IAOF;AAAA,EACF;AAGA,SAAO,YAAwB;AAAA,IAC7B,MAAM,OAAO;AAAA,IACb,OAAO,CAAC;AAAA,IACR,YAAY,OAAO,aAAa,CAAC,GAAG,OAAO,UAAU,IAAI,CAAC;AAAA,IAC1D,YAAY,OAAO;AAAA,IACnB,QAAQ,OAAO,UAAU;AAAA,EAC3B,CAAC;AACH;;;ACnVA,eAAe,aAAaG,OAAY,KAAkD;AACxF,QAAM,SAAS,MAAMA,MAAK,IAAI,GAAG;AACjC,MAAI,CAAC,OAAO,QAAS,QAAO,EAAE,MAAAA,OAAM,SAAS,OAAO,OAAO,OAAO,MAAM;AACxE,MAAI,WAAW,OAAO,IAAI,EAAG,QAAO,EAAE,MAAAA,OAAM,SAAS,KAAK;AAC1D,SAAO,EAAE,MAAAA,OAAM,SAAS,OAAO,QAAQ,OAAO,KAAK;AACrD;AAuCO,SAAS,YACX,OAIH;AACA,QAAM,OAAO,YAAY,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAC5D,QAAM,aAA8B;AASpC,QAAM,cAAc,oBAAI,QAAiC;AAGzD,QAAM,MAAM,OAAO,QAAqE;AACtF,UAAM,YAAY,OAAO,OAAO,EAAE,GAAG,IAAI,CAAC;AAE1C,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,WAAW,IAAI,CAACA,UAAS,aAAaA,OAAM,SAAS,CAAC;AAAA,IACxD;AAEA,UAAM,YAAkD,CAAC;AACzD,UAAM,YAAqB,CAAC;AAC5B,UAAM,WAAqB,CAAC;AAE5B,eAAW,KAAK,SAAS;AACvB,UAAI,EAAE,WAAW,YAAY;AAC3B,kBAAU,KAAK,QAAQ,EAAE,MAAM,CAAC;AAAA,MAClC,OAAO;AACL,cAAM,IAAI,EAAE;AACZ,YAAI,EAAE,QAAS;AACf,YAAI,EAAE,QAAQ;AACZ,oBAAU,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,EAAE,OAAO,CAAC;AACjD,mBAAS,KAAK,EAAE,KAAK,IAAI;AAAA,QAC3B,WAAW,EAAE,OAAO;AAClB,oBAAU,KAAK,EAAE,KAAK;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,UAAU,SAAS,GAAG;AAExB,YAAM,iBAA0B,CAAC;AACjC,eAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,cAAM,EAAE,MAAAA,OAAM,OAAO,IAAI,UAAU,CAAC;AACpC,YAAIA,MAAK,UAAU;AACjB,cAAI;AACF,kBAAMA,MAAK,SAAS,WAAW,MAAM;AAAA,UACvC,SAAS,KAAK;AACZ,2BAAe,KAAK,QAAQ,GAAG,CAAC;AAAA,UAClC;AAAA,QACF;AAAA,MACF;AACA,YAAM,QAAQ,eAAe,WAAW,GAAG,IAAI,KAAK,UAAU,MAAM,iBAAiB;AACrF,UAAI,eAAe,SAAS,GAAG;AAC7B,cAAM,QAAQ,IAAI;AAAA,UAChB,GAAG,IAAI,KAAK,eAAe,MAAM;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AACA,YAAMC,QAAO,cAAc,MAAM,WAAW,QAAQ;AACpD,aAAO,iBAAiB,OAAOA,OAAM,IAAI;AAAA,IAC3C;AAGA,UAAM,SAAqB,CAAC;AAC5B,eAAW,EAAE,OAAO,KAAK,WAAW;AAClC,aAAO,OAAO,QAAQ,MAAM;AAAA,IAC9B;AAKA,gBAAY;AAAA,MACV;AAAA,MACA,UAAU,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,EAAE,OAAO,EAAE;AAAA,IAC3D;AAEA,UAAM,OAAO,cAAc,MAAM,WAAW,QAAQ;AACpD,WAAO,iBAAiB,QAAQ,IAAI;AAAA,EACtC;AASA,QAAM,WAA0C,OAAO,KAAK,iBAAiB;AAC3E,UAAM,UAAU,YAAY,IAAI,YAAY;AAC5C,QAAI,CAAC,QAAS;AACd,gBAAY,OAAO,YAAY;AAC/B,UAAM,SAAkB,CAAC;AACzB,aAAS,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;AAC5C,YAAM,EAAE,MAAAD,OAAM,OAAO,IAAI,QAAQ,CAAC;AAClC,UAAI,CAACA,MAAK,SAAU;AACpB,UAAI;AACF,cAAMA,MAAK,SAAS,KAAK,MAAM;AAAA,MACjC,SAAS,KAAK;AACZ,eAAO,KAAK,QAAQ,GAAG,CAAC;AAAA,MAC1B;AAAA,IACF;AACA,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,IAAI,cAAc,GAAG,IAAI,KAAK,OAAO,MAAM,uBAAuB,MAAM;AAAA,IAChF;AAAA,EACF;AAEA,SAAO,iBAAiB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAIH;;;AC/JA,SAAS,kBAAkB,MAAoE;AAC7F,SAAO,KAAK,IAAI,CAAC,QAA0B;AACzC,QAAI,MAAM,QAAQ,GAAG,EAAG,QAAO;AAE/B,WAAO,CAAC,MAAM,MAAM,GAAW;AAAA,EACjC,CAAC;AACH;AA+DO,SAAS,UAAU,MAAuE;AAC/F,QAAM,gBAAgB,kBAAkB,IAAI;AAC5C,QAAM,OAAO,UAAU,cAAc,IAAI,CAAC,CAAC,EAAEE,KAAI,MAAMA,MAAK,IAAI,EAAE,KAAK,IAAI,CAAC;AAQ5E,QAAM,YAAY,oBAAI,QAAwB;AAE9C,QAAM,MAAM,OAAO,QAAqE;AACtF,UAAM,YAAY,OAAO,OAAO,EAAE,GAAG,IAAI,CAAC;AAE1C,aAAS,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;AAC7C,YAAM,CAAC,WAAWA,KAAI,IAAI,cAAc,CAAC;AAGzC,UAAI;AACJ,UAAI;AACF,kBAAU,UAAU,SAAS;AAAA,MAC/B,SAAS,KAAK;AACZ,cAAM,QAAQ,QAAQ,GAAG;AACzB,cAAM,QAAQ,IAAI,eAAe,GAAG,IAAI,eAAe,MAAM,OAAO,EAAE;AACtE,cAAM,QAAQ;AACd,cAAMC,QAAO,cAAc,MAAM,WAAW,CAAC,CAAC;AAC9C,eAAO,iBAAiB,OAAOA,OAAM,IAAI;AAAA,MAC3C;AAEA,UAAI,CAAC,QAAS;AAEd,YAAM,SAAS,MAAMD,MAAK,IAAI,SAAS;AACvC,UAAI,CAAC,OAAO,SAAS;AACnB,cAAMC,QAAO,cAAc,MAAM,WAAW,CAACD,MAAK,IAAI,CAAC;AACvD,eAAO,iBAAiB,OAAO,OAAOC,OAAM,IAAI;AAAA,MAClD;AAGA,gBAAU,IAAI,OAAO,MAAM,CAAC;AAE5B,YAAMA,QAAO,cAAc,MAAM,WAAW,CAACD,MAAK,IAAI,CAAC;AACvD,aAAO,iBAAiB,OAAO,MAAMC,KAAI;AAAA,IAC3C;AAGA,UAAM,OAAO,cAAc,MAAM,WAAW,CAAC,CAAC;AAC9C,WAAO,iBAAiB,CAAC,GAAG,IAAI;AAAA,EAClC;AAKA,QAAM,WAA0C,OAAO,KAAK,WAAW;AACrE,UAAM,cAAc,UAAU,IAAI,MAAM;AACxC,QAAI,gBAAgB,OAAW;AAC/B,cAAU,OAAO,MAAM;AACvB,UAAM,CAAC,EAAED,KAAI,IAAI,cAAc,WAAW;AAC1C,QAAIA,MAAK,UAAU;AACjB,UAAI;AACF,cAAMA,MAAK,SAAS,KAAK,MAAM;AAAA,MACjC,SAAS,KAAK;AACZ,cAAM,IAAI,cAAc,GAAG,IAAI,0BAA0B,CAAC,QAAQ,GAAG,CAAC,CAAC;AAAA,MACzE;AAAA,IACF;AAAA,EACF;AAEA,SAAO,iBAAiB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;;;AClHA,SAAS,aAAa,SAAiC,KAA2C;AAChG,QAAM,UAAU,OAAO,QAAQ,OAAO;AACtC,MAAI,eAA8B,CAAC,CAAC,CAAC;AAErC,aAAW,CAAC,YAAY,OAAO,KAAK,SAAS;AAC3C,UAAM,QAAQ,IAAI,UAAU;AAC5B,QAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,EAAG,QAAO,CAAC;AACzD,UAAM,OAAsB,CAAC;AAC7B,eAAW,SAAS,cAAc;AAChC,iBAAW,QAAQ,OAAO;AACxB,aAAK,KAAK,EAAE,GAAG,OAAO,CAAC,OAAO,GAAG,KAAgB,CAAC;AAAA,MACpD;AAAA,IACF;AACA,mBAAe;AAAA,EACjB;AAEA,SAAO;AACT;AA8CO,SAAS,WAKd,KACA,SACAE,OAIA;AACA,QAAM,WAAW,cAAc,GAAG,KAAKA,MAAK,IAAI;AAChD,QAAM,YAAY,IAAI,IAAI,OAAO,KAAK,OAAO,CAAC;AAQ9C,QAAM,eAAe,oBAAI,QAAuE;AAEhG,QAAM,MAAM,OAAO,QAAgE;AACjF,UAAM,YAAY,OAAO,OAAO,EAAE,GAAG,IAAI,CAAC;AAC1C,UAAM,OAAO,SAAS,UAAU,SAAS;AAGzC,UAAM,eAAe,aAAa,SAAS,SAAS;AAGpD,UAAM,UAAuB,CAAC;AAC9B,eAAW,KAAK,OAAO,KAAK,SAAS,GAAG;AACtC,UAAI,CAAC,UAAU,IAAI,CAAC,EAAG,SAAQ,CAAC,IAAI,UAAU,CAAC;AAAA,IACjD;AAGA,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,aAAa,IAAI,OAAO,UAAU;AAChC,cAAM,UAAU,OAAO,OAAO,EAAE,GAAG,SAAS,GAAG,MAAM,CAAC;AACtD,eAAOA,MAAK,IAAI,OAAO;AAAA,MACzB,CAAC;AAAA,IACH;AAGA,UAAM,YAAqD,CAAC;AAC5D,UAAM,YAAqB,CAAC;AAE5B,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,YAAM,IAAI,QAAQ,CAAC;AACnB,UAAI,EAAE,WAAW,YAAY;AAC3B,kBAAU,KAAK,QAAQ,EAAE,MAAM,CAAC;AAAA,MAClC,WAAW,CAAC,EAAE,MAAM,SAAS;AAC3B,kBAAU,KAAK,EAAE,MAAM,KAAK;AAAA,MAC9B,OAAO;AACL,kBAAU,KAAK,EAAE,OAAO,GAAG,QAAQ,EAAE,MAAM,KAAK,CAAC;AAAA,MACnD;AAAA,IACF;AAEA,QAAI,UAAU,SAAS,GAAG;AAExB,YAAM,iBAA0B,CAAC;AACjC,UAAIA,MAAK,UAAU;AACjB,iBAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,cAAI;AACF,kBAAM,QAAQ,aAAa,UAAU,CAAC,EAAE,KAAK;AAC7C,kBAAM,UAAU,OAAO,OAAO,EAAE,GAAG,SAAS,GAAG,MAAM,CAAC;AACtD,kBAAMA,MAAK,SAAS,SAAS,UAAU,CAAC,EAAE,MAAM;AAAA,UAClD,SAAS,KAAK;AACZ,2BAAe,KAAK,QAAQ,GAAG,CAAC;AAAA,UAClC;AAAA,QACF;AAAA,MACF;AACA,YAAM,QAAQ,eAAe,WAAW,GAAG,QAAQ,KAAK,UAAU,MAAM,iBAAiB;AACzF,UAAI,eAAe,SAAS,GAAG;AAC7B,cAAM,QAAQ,IAAI;AAAA,UAChB,GAAG,QAAQ,KAAK,eAAe,MAAM;AAAA,UACrC;AAAA,QACF;AAAA,MACF;AACA,aAAO,YAAY,OAAO,MAAM,QAAQ;AAAA,IAC1C;AAGA,UAAM,UAAU,UAAU,IAAI,CAAC,MAAM,EAAE,MAAM;AAC7C,UAAM,OAAmB,EAAE,CAAC,GAAG,GAAG,QAAQ;AAC1C,iBAAa,IAAI,MAAM,EAAE,cAAc,QAAQ,CAAC;AAChD,WAAO,YAAY,MAAM,IAAI;AAAA,EAC/B;AAKA,QAAM,WAA6BA,MAAK,WACpC,OAAO,MAAM,WAAW;AACtB,UAAM,OAAO,aAAa,IAAI,MAAM;AACpC,QAAI,CAAC,KAAM;AACX,iBAAa,OAAO,MAAM;AAC1B,UAAM,UAAW,OAAmC,GAAG;AACvD,UAAM,SAAkB,CAAC;AACzB,aAAS,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;AAC5C,UAAI;AACF,cAAM,UAAU,OAAO,OAAO;AAAA,UAC5B,GAAG,KAAK;AAAA,UACR,GAAG,KAAK,aAAa,CAAC;AAAA,QACxB,CAAC;AACD,cAAMA,MAAK,SAAU,SAAS,QAAQ,CAAC,CAAC;AAAA,MAC1C,SAAS,KAAK;AACZ,eAAO,KAAK,QAAQ,GAAG,CAAC;AAAA,MAC1B;AAAA,IACF;AACA,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,IAAI,cAAc,GAAG,QAAQ,KAAK,OAAO,MAAM,uBAAuB,MAAM;AAAA,IACpF;AAAA,EACF,IACA;AAEJ,SAAO,iBAAiB;AAAA,IACtB,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF,CAAC;AAIH;","names":["step","step","step","step","meta","state","step","meta","step","meta","step"]}
|