runsheet 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,26 @@
1
- import { ParserSchema, Result, Success, Failure } from 'composable-functions';
2
- export { Failure, Result, Success } from 'composable-functions';
3
-
1
+ /**
2
+ * A schema that can parse/validate unknown data.
3
+ *
4
+ * This is the structural interface that Zod schemas (and other schema
5
+ * libraries) satisfy. runsheet does not depend on any specific schema
6
+ * library — any object with a `safeParse` method works.
7
+ *
8
+ * @typeParam T - The validated output type.
9
+ */
10
+ type StepSchema<T> = {
11
+ safeParse(data: unknown): {
12
+ success: true;
13
+ data: T;
14
+ } | {
15
+ success: false;
16
+ error: {
17
+ issues: readonly {
18
+ path: readonly (string | number)[];
19
+ message: string;
20
+ }[];
21
+ };
22
+ };
23
+ };
4
24
  /**
5
25
  * The type-erased context shape used at runtime by the pipeline engine.
6
26
  *
@@ -34,18 +54,18 @@ type Step = {
34
54
  /** Unique name identifying this step in metadata and rollback reports. */
35
55
  readonly name: string;
36
56
  /** Optional schema that validates the accumulated context before `run`. */
37
- readonly requires: ParserSchema<StepContext> | undefined;
57
+ readonly requires: StepSchema<StepContext> | undefined;
38
58
  /** Optional schema that validates the step's output after `run`. */
39
- readonly provides: ParserSchema<StepOutput> | undefined;
59
+ readonly provides: StepSchema<StepOutput> | undefined;
40
60
  /**
41
61
  * Execute the step. Receives the accumulated context and returns a
42
- * `Result` — either `{ success: true, data }` or
43
- * `{ success: false, errors }`.
62
+ * {@link StepResult} — either a success with `data` or a failure with
63
+ * `error`, `failedStep`, and `rollback`.
44
64
  *
45
65
  * Step authors never call this directly; the pipeline engine calls it
46
- * after validating `requires` and wrapping with middleware.
66
+ * after wrapping with middleware.
47
67
  */
48
- readonly run: (ctx: Readonly<StepContext>) => Promise<Result<StepOutput>>;
68
+ readonly run: (ctx: Readonly<StepContext>) => Promise<StepResult<StepOutput>>;
49
69
  /**
50
70
  * Optional rollback handler, called when a later step fails.
51
71
  *
@@ -62,6 +82,10 @@ type Step = {
62
82
  * Phantom type brands for compile-time tracking of step I/O types.
63
83
  * These symbols never exist at runtime — they only guide TypeScript's
64
84
  * type checker through the builder's progressive type narrowing.
85
+ *
86
+ * `RequiresBrand` uses a function type for contravariance: a step that
87
+ * requires `StepContext` (anything) is usable where a narrower context
88
+ * is available. `ProvidesBrand` is covariant (a plain value brand).
65
89
  */
66
90
  declare const RequiresBrand: unique symbol;
67
91
  declare const ProvidesBrand: unique symbol;
@@ -76,13 +100,17 @@ declare const ProvidesBrand: unique symbol;
76
100
  * schemas or generics. When assigned to `Step` (e.g., in a pipeline's
77
101
  * step array), the intersection collapses to the erased signatures.
78
102
  *
103
+ * The typed properties appear BEFORE the `Step` intersection so that
104
+ * TypeScript's overload resolution picks the concrete signatures first
105
+ * when calling `run()` directly on a `TypedStep`.
106
+ *
79
107
  * @typeParam Requires - The context shape this step reads from.
80
108
  * @typeParam Provides - The output shape this step produces.
81
109
  *
82
110
  * @example
83
111
  * ```ts
84
112
  * // Hover over `step.run` to see:
85
- * // (ctx: Readonly<{ amount: number }>) => Promise<Result<{ chargeId: string }>>
113
+ * // (ctx: Readonly<{ amount: number }>) => Promise<StepResult<{ chargeId: string }>>
86
114
  * const step = defineStep({
87
115
  * name: 'charge',
88
116
  * requires: z.object({ amount: z.number() }),
@@ -91,15 +119,15 @@ declare const ProvidesBrand: unique symbol;
91
119
  * });
92
120
  * ```
93
121
  */
94
- type TypedStep<Requires extends StepContext = StepContext, Provides extends StepContext = StepContext> = Step & {
95
- readonly [RequiresBrand]: Requires;
122
+ type TypedStep<Requires extends StepContext = StepContext, Provides extends StepContext = StepContext> = {
123
+ readonly [RequiresBrand]: (ctx: Requires) => void;
96
124
  readonly [ProvidesBrand]: Provides;
97
125
  /** Optional schema that validates the accumulated context before `run`. */
98
- readonly requires: ParserSchema<Requires> | undefined;
126
+ readonly requires: StepSchema<Requires> | undefined;
99
127
  /** Optional schema that validates the step's output after `run`. */
100
- readonly provides: ParserSchema<Provides> | undefined;
128
+ readonly provides: StepSchema<Provides> | undefined;
101
129
  /** Execute the step with concrete input/output types. */
102
- readonly run: (ctx: Readonly<Requires>) => Promise<Result<Provides>>;
130
+ readonly run: (ctx: Readonly<Requires>) => Promise<StepResult<Provides>>;
103
131
  /**
104
132
  * Optional rollback handler, called when a later step fails.
105
133
  *
@@ -107,13 +135,30 @@ type TypedStep<Requires extends StepContext = StepContext, Provides extends Step
107
135
  * @param output - The frozen output this step produced.
108
136
  */
109
137
  readonly rollback: ((ctx: Readonly<Requires>, output: Readonly<Provides>) => Promise<void>) | undefined;
110
- };
138
+ } & Step;
111
139
  /** Convert a union type to an intersection type. */
112
140
  type UnionToIntersection<U> = [U] extends [never] ? unknown : (U extends unknown ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
113
- /** Extract the Requires type from a step. Returns `StepContext` for untyped (erased) steps. */
114
- type ExtractRequires<T extends Step> = T extends TypedStep<infer R, StepContext> ? R : StepContext;
115
- /** Extract the Provides type from a step. Returns `object` for untyped (erased) steps. */
116
- type ExtractProvides<T extends Step> = T extends TypedStep<StepContext, infer P> ? P : object;
141
+ /**
142
+ * Extract the Requires type from a step via its phantom brand.
143
+ * Returns `StepContext` for untyped (erased) steps.
144
+ *
145
+ * Matches the contravariant function brand directly — avoids full
146
+ * structural matching on `TypedStep` which would fail due to
147
+ * `run` parameter contravariance in conditional types.
148
+ */
149
+ type ExtractRequires<T extends Step> = T extends {
150
+ readonly [RequiresBrand]: (ctx: infer R) => void;
151
+ } ? R : StepContext;
152
+ /**
153
+ * Extract the Provides type from a step via its phantom brand.
154
+ * Returns `object` for untyped (erased) steps.
155
+ *
156
+ * Matches the covariant value brand directly — avoids full structural
157
+ * matching which would fail for steps with non-trivial Requires types.
158
+ */
159
+ type ExtractProvides<T extends Step> = T extends {
160
+ readonly [ProvidesBrand]: infer P;
161
+ } ? P : object;
117
162
  /**
118
163
  * Retry policy for a step's `run` function.
119
164
  *
@@ -160,23 +205,23 @@ type StepConfig<Requires extends StepContext, Provides extends StepContext> = {
160
205
  /**
161
206
  * Optional Zod (or Standard Schema compatible) schema that validates
162
207
  * the accumulated context before `run` is called. When provided, a
163
- * schema validation failure produces a `Result` error — the step's
208
+ * schema validation failure produces a `StepResult` error — the step's
164
209
  * `run` function is never invoked.
165
210
  */
166
- requires?: ParserSchema<Requires>;
211
+ requires?: StepSchema<Requires>;
167
212
  /**
168
213
  * Optional Zod (or Standard Schema compatible) schema that validates
169
214
  * the step's output after `run` returns. When provided, a schema
170
- * validation failure produces a `Result` error even though `run`
215
+ * validation failure produces a `StepResult` error even though `run`
171
216
  * succeeded.
172
217
  */
173
- provides?: ParserSchema<Provides>;
218
+ provides?: StepSchema<Provides>;
174
219
  /**
175
220
  * The step implementation. Receives the accumulated context (frozen)
176
221
  * and returns the step's output. Can be sync or async.
177
222
  *
178
223
  * To signal failure, throw an error. The pipeline catches it and
179
- * produces a `Result` failure — do not return failure objects.
224
+ * produces a `StepResult` failure — do not return failure objects.
180
225
  *
181
226
  * @param ctx - The frozen accumulated context up to this point.
182
227
  * @returns The step's output, which is merged into the accumulated context.
@@ -219,7 +264,7 @@ type RollbackFailure = {
219
264
  readonly error: Error;
220
265
  };
221
266
  /**
222
- * Summary of rollback execution after a pipeline failure.
267
+ * Summary of rollback execution after a step or pipeline failure.
223
268
  *
224
269
  * Rollback is best-effort: every completed step's rollback handler is
225
270
  * attempted in reverse order, regardless of whether earlier handlers
@@ -232,69 +277,153 @@ type RollbackReport = {
232
277
  readonly failed: readonly RollbackFailure[];
233
278
  };
234
279
  /**
235
- * Metadata about a pipeline execution, present on both success and failure
280
+ * Metadata about a step execution, present on both success and failure
236
281
  * results. Useful for logging, debugging, and observability.
237
282
  */
238
- type PipelineExecutionMeta = {
239
- /** The pipeline's name as passed to `buildPipeline` or `createPipeline`. */
240
- readonly pipeline: string;
241
- /** The original arguments passed to `pipeline.run()`. */
283
+ type StepMeta = {
284
+ /** The step's name (or pipeline name for pipeline-steps). */
285
+ readonly name: string;
286
+ /** The original arguments/context passed to `step.run()`. */
242
287
  readonly args: Readonly<StepContext>;
288
+ };
289
+ /**
290
+ * Extended metadata for orchestrator results (pipelines, parallel,
291
+ * choice).
292
+ *
293
+ * Includes orchestration detail — which steps ran — on top of the
294
+ * base {@link StepMeta}. Present on results from `pipeline()`,
295
+ * `parallel()`, and `choice()`.
296
+ */
297
+ type AggregateMeta = StepMeta & {
243
298
  /** Names of steps that executed successfully, in order. */
244
299
  readonly stepsExecuted: readonly string[];
245
- /** Names of conditional steps that were skipped (predicate returned false). */
246
- readonly stepsSkipped: readonly string[];
247
300
  };
248
301
  /**
249
- * A successful pipeline result.
302
+ * A successful step result.
250
303
  *
251
- * Extends composable-functions' `Success<T>` with pipeline execution
252
- * metadata. The `data` property contains the fully accumulated context
253
- * (initial args merged with all step outputs).
304
+ * The `data` property contains the step's output (or the fully
305
+ * accumulated context for pipeline-steps).
254
306
  *
255
- * @typeParam T - The accumulated context type.
307
+ * @typeParam T - The output type.
256
308
  */
257
- type PipelineSuccess<T> = Success<T> & {
258
- /** Pipeline execution metadata. */
259
- readonly meta: PipelineExecutionMeta;
309
+ type StepSuccess<T> = {
310
+ readonly success: true;
311
+ /** The step's output data. */
312
+ readonly data: T;
313
+ /** Step execution metadata. */
314
+ readonly meta: StepMeta;
260
315
  };
261
316
  /**
262
- * A failed pipeline result.
263
- *
264
- * Extends composable-functions' `Failure` with the name of the step that
265
- * failed, a rollback report, and pipeline execution metadata.
317
+ * A failed step result.
266
318
  *
267
- * On failure, rollback handlers for all previously completed steps are
268
- * executed in reverse order before this result is returned.
319
+ * Contains the error that caused the failure, the name of the step
320
+ * that failed, and a rollback report.
269
321
  */
270
- type PipelineFailure = Failure & {
271
- /** Pipeline execution metadata. */
272
- readonly meta: PipelineExecutionMeta;
322
+ type StepFailure = {
323
+ readonly success: false;
324
+ /** The error that caused the failure. Use `AggregateError` when multiple errors occur. */
325
+ readonly error: Error;
326
+ /** Step execution metadata. */
327
+ readonly meta: StepMeta;
273
328
  /** Name of the step that failed. */
274
329
  readonly failedStep: string;
275
330
  /** Report of which rollback handlers succeeded and which threw. */
276
331
  readonly rollback: RollbackReport;
277
332
  };
278
333
  /**
279
- * The result of running a pipeline — either a success or a failure.
334
+ * The result of running a step — either a success or a failure.
280
335
  *
281
336
  * Use the `success` discriminant to narrow:
282
337
  *
283
338
  * ```ts
284
- * const result = await pipeline.run(args);
339
+ * const result = await step.run(ctx);
285
340
  * if (result.success) {
286
- * result.data; // fully typed accumulated context
341
+ * result.data; // the step's output
287
342
  * result.meta; // execution metadata
288
343
  * } else {
289
- * result.errors; // what went wrong
344
+ * result.error; // what went wrong
290
345
  * result.failedStep; // which step failed
291
346
  * result.rollback; // { completed: [...], failed: [...] }
292
347
  * }
293
348
  * ```
294
349
  *
295
- * @typeParam T - The accumulated context type on success.
350
+ * @typeParam T - The output type on success.
296
351
  */
297
- type PipelineResult<T> = PipelineSuccess<T> | PipelineFailure;
352
+ type StepResult<T> = StepSuccess<T> | StepFailure;
353
+ /**
354
+ * A successful orchestrator result.
355
+ *
356
+ * Identical to {@link StepSuccess} but with {@link AggregateMeta}
357
+ * instead of {@link StepMeta}, providing orchestration detail.
358
+ *
359
+ * @typeParam T - The accumulated output type.
360
+ */
361
+ type AggregateSuccess<T> = {
362
+ readonly success: true;
363
+ /** The accumulated output after all inner steps. */
364
+ readonly data: T;
365
+ /** Orchestrator execution metadata including step tracking. */
366
+ readonly meta: AggregateMeta;
367
+ };
368
+ /**
369
+ * A failed orchestrator result.
370
+ *
371
+ * Identical to {@link StepFailure} but with {@link AggregateMeta}
372
+ * instead of {@link StepMeta}, providing orchestration detail.
373
+ */
374
+ type AggregateFailure = {
375
+ readonly success: false;
376
+ /** The error that caused the failure. */
377
+ readonly error: Error;
378
+ /** Orchestrator execution metadata including step tracking. */
379
+ readonly meta: AggregateMeta;
380
+ /** Name of the step that failed. */
381
+ readonly failedStep: string;
382
+ /** Report of which rollback handlers succeeded and which threw. */
383
+ readonly rollback: RollbackReport;
384
+ };
385
+ /**
386
+ * The result of running an orchestrator — extends {@link StepResult}
387
+ * with richer metadata.
388
+ *
389
+ * `AggregateResult<T>` is assignable to `StepResult<T>`, so
390
+ * orchestrators (`pipeline`, `parallel`, `choice`) satisfy the `Step`
391
+ * interface while providing orchestration detail to callers.
392
+ *
393
+ * ```ts
394
+ * const checkout = pipeline({ name: 'checkout', steps: [...] });
395
+ * const result = await checkout.run({ orderId: '123' });
396
+ * if (result.success) {
397
+ * result.meta.stepsExecuted; // string[] — which steps ran
398
+ * } else {
399
+ * result.meta.stepsExecuted; // string[] — which steps ran
400
+ * result.failedStep; // which step failed
401
+ * result.rollback; // { completed, failed }
402
+ * }
403
+ * ```
404
+ *
405
+ * @typeParam T - The accumulated output type on success.
406
+ */
407
+ type AggregateResult<T> = AggregateSuccess<T> | AggregateFailure;
408
+ /**
409
+ * A step that orchestrates other steps and returns rich results.
410
+ *
411
+ * Extends {@link TypedStep} with a narrower `run()` that returns
412
+ * {@link AggregateResult} instead of {@link StepResult}. This is the
413
+ * type returned by `pipeline()`, `parallel()`, and `choice()`.
414
+ *
415
+ * The `run` property uses an explicit overloaded function type:
416
+ * the first overload returns `AggregateResult` (matched when calling
417
+ * directly), the second preserves the erased `Step.run` signature
418
+ * (for `Step` assignability when used in pipeline arrays).
419
+ *
420
+ * @typeParam Requires - The input type.
421
+ * @typeParam Provides - The accumulated output type.
422
+ */
423
+ type AggregateStep<Requires extends StepContext = StepContext, Provides extends StepContext = StepContext> = {
424
+ /** Execute the orchestrator and return an {@link AggregateResult}. */
425
+ readonly run: (ctx: Readonly<Requires>) => Promise<AggregateResult<Provides>>;
426
+ } & TypedStep<Requires, Provides>;
298
427
 
299
428
  /**
300
429
  * Define a pipeline step.
@@ -323,9 +452,8 @@ type PipelineResult<T> = PipelineSuccess<T> | PipelineFailure;
323
452
  *
324
453
  * **Invariants:**
325
454
  * - The returned step object is always frozen (immutable).
326
- * - The `run` function is wrapped with `composable()` from
327
- * composable-functions, which catches thrown errors and produces
328
- * `Result` values. Step authors should throw to signal failure.
455
+ * - The `run` function catches thrown errors and produces
456
+ * `StepResult` values. Step authors should throw to signal failure.
329
457
  * - This is the single type-erasure cast point in the library.
330
458
  *
331
459
  * @typeParam Requires - The context shape this step reads from.
@@ -338,31 +466,28 @@ declare function defineStep<Requires extends StepContext, Provides extends StepC
338
466
  /**
339
467
  * Error codes for errors produced by the runsheet library itself.
340
468
  *
341
- * Use these to distinguish library errors from application errors
342
- * in a pipeline's `errors` array:
469
+ * Use these to distinguish library errors from application errors:
343
470
  *
344
471
  * ```ts
345
472
  * if (!result.success) {
346
- * for (const error of result.errors) {
347
- * if (error instanceof RunsheetError) {
348
- * console.log(error.code); // 'REQUIRES_VALIDATION', etc.
349
- * }
473
+ * if (result.error instanceof RunsheetError) {
474
+ * console.log(result.error.code); // 'REQUIRES_VALIDATION', etc.
350
475
  * }
351
476
  * }
352
477
  * ```
353
478
  */
354
- type RunsheetErrorCode = 'REQUIRES_VALIDATION' | 'PROVIDES_VALIDATION' | 'ARGS_VALIDATION' | 'PREDICATE' | 'TIMEOUT' | 'RETRY_EXHAUSTED' | 'STRICT_OVERLAP';
479
+ type RunsheetErrorCode = 'REQUIRES_VALIDATION' | 'PROVIDES_VALIDATION' | 'ARGS_VALIDATION' | 'PREDICATE' | 'TIMEOUT' | 'RETRY_EXHAUSTED' | 'STRICT_OVERLAP' | 'CHOICE_NO_MATCH' | 'ROLLBACK' | 'UNKNOWN';
355
480
  /**
356
481
  * Base error class for all errors produced by the runsheet library.
357
482
  *
358
483
  * Application errors (thrown by step `run` or `rollback` functions)
359
484
  * are never wrapped in `RunsheetError` — they pass through as-is.
360
- * If you see a `RunsheetError` in a result's `errors` array, the
361
- * library itself produced it.
485
+ * If you see a `RunsheetError` as `result.error`, the library itself
486
+ * produced it.
362
487
  *
363
488
  * Use `instanceof RunsheetError` to distinguish library errors from
364
- * application errors, and the `code` property to identify the
365
- * specific failure.
489
+ * application errors. Use `instanceof` on a subclass (e.g.,
490
+ * `TimeoutError`) or check the `code` property for specific failures.
366
491
  */
367
492
  declare class RunsheetError extends Error {
368
493
  /** Discriminant code identifying the type of library error. */
@@ -373,6 +498,58 @@ declare class RunsheetError extends Error {
373
498
  */
374
499
  constructor(code: RunsheetErrorCode, message: string);
375
500
  }
501
+ /** Schema validation failed on the accumulated context before a step ran. */
502
+ declare class RequiresValidationError extends RunsheetError {
503
+ constructor(message: string);
504
+ }
505
+ /** Schema validation failed on a step's output after it ran. */
506
+ declare class ProvidesValidationError extends RunsheetError {
507
+ constructor(message: string);
508
+ }
509
+ /** Schema validation failed on the pipeline's input arguments. */
510
+ declare class ArgsValidationError extends RunsheetError {
511
+ constructor(message: string);
512
+ }
513
+ /** A `when()` or `choice()` predicate threw an error. */
514
+ declare class PredicateError extends RunsheetError {
515
+ constructor(message: string);
516
+ }
517
+ /** A step exceeded its configured timeout. */
518
+ declare class TimeoutError extends RunsheetError {
519
+ /** The timeout duration in milliseconds that was exceeded. */
520
+ readonly timeoutMs: number;
521
+ constructor(message: string, timeoutMs: number);
522
+ }
523
+ /** A step failed after exhausting all retry attempts. */
524
+ declare class RetryExhaustedError extends RunsheetError {
525
+ /** Total number of attempts (initial + retries). */
526
+ readonly attempts: number;
527
+ constructor(message: string, attempts: number);
528
+ }
529
+ /** Two steps provide the same key (strict mode, detected at build time). */
530
+ declare class StrictOverlapError extends RunsheetError {
531
+ /** The key that is provided by multiple steps. */
532
+ readonly key: string;
533
+ /** The names of the two steps that both provide the key. */
534
+ readonly steps: readonly [string, string];
535
+ constructor(message: string, key: string, steps: readonly [string, string]);
536
+ }
537
+ /** No branch matched in a `choice()` step. */
538
+ declare class ChoiceNoMatchError extends RunsheetError {
539
+ constructor(message: string);
540
+ }
541
+ /** A non-Error value was thrown and caught by the pipeline engine. */
542
+ declare class UnknownError extends RunsheetError {
543
+ /** The original thrown value before stringification. */
544
+ readonly originalValue: unknown;
545
+ constructor(message: string, originalValue: unknown);
546
+ }
547
+ /** One or more rollback handlers failed in a combinator. */
548
+ declare class RollbackError extends RunsheetError {
549
+ /** The individual errors from each failed rollback handler. */
550
+ readonly causes: readonly Error[];
551
+ constructor(message: string, causes?: readonly Error[]);
552
+ }
376
553
 
377
554
  /**
378
555
  * Metadata about the step being executed, passed to middleware.
@@ -391,10 +568,9 @@ type StepInfo = {
391
568
  /**
392
569
  * A function that executes a step (or the next middleware in the chain).
393
570
  *
394
- * Receives the frozen accumulated context and returns a `Result` — either
395
- * `{ success: true, data }` or `{ success: false, errors }`.
571
+ * Receives the frozen accumulated context and returns a {@link StepResult}.
396
572
  */
397
- type StepExecutor = (ctx: Readonly<StepContext>) => Promise<Result<StepOutput>>;
573
+ type StepExecutor = (ctx: Readonly<StepContext>) => Promise<StepResult<StepOutput>>;
398
574
  /**
399
575
  * Middleware that wraps the entire step lifecycle, including schema
400
576
  * validation.
@@ -405,7 +581,7 @@ type StepExecutor = (ctx: Readonly<StepContext>) => Promise<Result<StepOutput>>;
405
581
  *
406
582
  * - **Observe**: read the context or result for logging/metrics.
407
583
  * - **Transform**: modify the result before returning it.
408
- * - **Short-circuit**: return a `Result` without calling `next`.
584
+ * - **Short-circuit**: return a `StepResult` without calling `next`.
409
585
  *
410
586
  * If a middleware throws, the pipeline catches it and treats it as a
411
587
  * step failure (triggering rollback for previously completed steps).
@@ -426,11 +602,58 @@ type StepExecutor = (ctx: Readonly<StepContext>) => Promise<Result<StepOutput>>;
426
602
  */
427
603
  type StepMiddleware = (step: StepInfo, next: StepExecutor) => StepExecutor;
428
604
 
605
+ /**
606
+ * A fluent pipeline builder that progressively narrows the accumulated
607
+ * context type as steps are added.
608
+ *
609
+ * Each method returns a new, frozen builder — builders are immutable.
610
+ *
611
+ * This means you can safely fork a builder to create variants:
612
+ *
613
+ * ```ts
614
+ * const base = pipeline({ name: 'order' }).step(validate);
615
+ * const withCharge = base.step(charge).build();
616
+ * const withoutCharge = base.build(); // unaffected by the fork
617
+ * ```
618
+ *
619
+ * @typeParam Args - The pipeline's initial input type.
620
+ * @typeParam Ctx - The accumulated context type so far (grows with each `.step()`).
621
+ */
622
+ type PipelineBuilder<Args extends StepContext, Ctx extends StepContext> = {
623
+ /**
624
+ * Add a step to the pipeline.
625
+ *
626
+ * The step's `Requires` type must be satisfied by the current `Ctx`
627
+ * (checked via phantom brands — a step that requires less than `Ctx`
628
+ * is always accepted). The returned builder's `Ctx` expands to
629
+ * include the step's `Provides`.
630
+ *
631
+ * @typeParam S - The step type being added.
632
+ * @param step - A {@link Step} (from `defineStep`, `when`, `pipeline`, etc.).
633
+ * @returns A new builder with the expanded context type.
634
+ */
635
+ readonly step: <S extends Step>(step: S & ([Ctx] extends [ExtractRequires<S>] ? unknown : never)) => PipelineBuilder<Args, Ctx & ExtractProvides<S>>;
636
+ /**
637
+ * Add middleware to the pipeline.
638
+ *
639
+ * Middleware is applied to every step. Multiple `.use()` calls
640
+ * accumulate — earlier middleware is outermost (executes first).
641
+ *
642
+ * @param middleware - One or more {@link StepMiddleware} functions.
643
+ * @returns A new builder with the middleware added.
644
+ */
645
+ readonly use: (...middleware: StepMiddleware[]) => PipelineBuilder<Args, Ctx>;
646
+ /**
647
+ * Build the pipeline. Returns an {@link AggregateStep} — pipelines
648
+ * are steps whose `run()` returns {@link AggregateResult}.
649
+ */
650
+ readonly build: () => AggregateStep<Args, Ctx>;
651
+ };
652
+
429
653
  /**
430
654
  * Internal configuration shape for the pipeline engine.
431
655
  *
432
- * Users typically don't construct this directly — use `buildPipeline()`
433
- * or `createPipeline()` instead.
656
+ * Users typically don't construct this directly — use `pipeline()`.
434
657
  */
435
658
  type PipelineConfig = {
436
659
  /** Pipeline name, used in execution metadata and error messages. */
@@ -440,7 +663,7 @@ type PipelineConfig = {
440
663
  /** Optional middleware applied to every step. First in array = outermost. */
441
664
  readonly middleware?: readonly StepMiddleware[];
442
665
  /** Optional schema that validates the pipeline's input arguments. */
443
- readonly argsSchema?: ParserSchema<StepContext>;
666
+ readonly argsSchema?: StepSchema<StepContext>;
444
667
  /**
445
668
  * When `true`, throws at build time if two or more steps provide the
446
669
  * same key. Only checks steps that have a `provides` schema with an
@@ -450,89 +673,57 @@ type PipelineConfig = {
450
673
  readonly strict?: boolean;
451
674
  };
452
675
  /**
453
- * A built pipeline, ready to execute.
454
- *
455
- * Call `run(args)` to execute the pipeline. The result is a
456
- * {@link PipelineResult} — either a success with the fully accumulated
457
- * context, or a failure with error details and a rollback report.
676
+ * Create a pipeline — either directly from steps, or via the fluent
677
+ * builder API.
458
678
  *
459
- * Pipeline objects are frozen (immutable) and can be called repeatedly.
679
+ * **With steps** returns an {@link AggregateStep} immediately:
460
680
  *
461
- * @typeParam Args - The input type accepted by `run()`.
462
- * @typeParam Ctx - The accumulated output type on success.
463
- */
464
- type Pipeline<Args extends StepContext, Ctx> = {
465
- /** The pipeline's name, as provided at build time. */
466
- readonly name: string;
467
- /**
468
- * Execute the pipeline.
469
- *
470
- * @param args - The initial arguments. Merged into the context before
471
- * the first step runs. Validated against `argsSchema` if one was
472
- * provided.
473
- * @returns A {@link PipelineResult} — discriminate on `success` to
474
- * access `data` (on success) or `errors`/`rollback` (on failure).
475
- */
476
- readonly run: (args: Args) => Promise<PipelineResult<Ctx>>;
477
- };
478
- /**
479
- * Build a pipeline from an array of steps.
480
- *
481
- * The result type is inferred from the steps — `pipeline.run()` returns
482
- * a {@link PipelineResult} whose `data` is the intersection of the
483
- * initial `Args` and all step output types.
484
- *
485
- * @example
486
681
  * ```ts
487
- * const pipeline = buildPipeline({
488
- * name: 'placeOrder',
682
+ * const checkout = pipeline({
683
+ * name: 'checkout',
489
684
  * steps: [validateOrder, chargePayment, sendConfirmation],
490
685
  * middleware: [logging, timing],
491
686
  * argsSchema: z.object({ orderId: z.string() }),
492
687
  * });
493
- *
494
- * const result = await pipeline.run({ orderId: '123' });
495
- * if (result.success) {
496
- * result.data.chargeId; // string — fully typed
497
- * }
498
688
  * ```
499
689
  *
500
- * **Execution semantics:**
501
- * - Steps execute sequentially in array order.
502
- * - Context is frozen (`Object.freeze`) at every step boundary.
503
- * - Conditional steps (wrapped with `when()`) are skipped when their
504
- * predicate returns false — no snapshot, no rollback entry.
505
- * - On step failure, rollback handlers for all previously completed
506
- * steps execute in reverse order (best-effort).
507
- * - Middleware wraps the full step lifecycle including schema validation.
690
+ * **Without steps** — returns a {@link PipelineBuilder} with
691
+ * progressive type narrowing:
508
692
  *
509
- * **Invariants:**
510
- * - The returned pipeline object is frozen (immutable).
511
- * - Errors thrown by steps, predicates, or middleware are caught and
512
- * returned as `PipelineFailure` — `run()` never throws.
513
- *
514
- * @typeParam Args - The pipeline's input type. Inferred from `argsSchema`
515
- * if provided, otherwise defaults to `StepContext`.
516
- * @typeParam S - The step types in the array. Inferred automatically —
517
- * do not specify manually.
518
- * @param config - Pipeline configuration.
519
- * @param config.name - Pipeline name, used in metadata and error messages.
520
- * @param config.steps - Steps to execute in order.
521
- * @param config.middleware - Optional middleware applied to every step.
522
- * First in array = outermost wrapper.
523
- * @param config.argsSchema - Optional schema that validates `args` before
524
- * any steps run. Validation failure produces a `PipelineFailure` with
525
- * `failedStep` set to the pipeline name.
526
- * @returns A frozen {@link Pipeline} whose `run()` method executes the
527
- * steps and returns a {@link PipelineResult}.
528
- */
529
- declare function buildPipeline<Args extends StepContext = StepContext, S extends Step = Step>(config: {
693
+ * ```ts
694
+ * const checkout = pipeline({ name: 'checkout' })
695
+ * .step(validateOrder)
696
+ * .step(chargePayment)
697
+ * .build();
698
+ *
699
+ * // With schema (runtime validation):
700
+ * pipeline({
701
+ * name: 'checkout',
702
+ * argsSchema: z.object({ orderId: z.string() }),
703
+ * }).step(validateOrder).build();
704
+ *
705
+ * // Type-only args (no runtime validation):
706
+ * pipeline<{ orderId: string }>({ name: 'checkout' })
707
+ * .step(validateOrder)
708
+ * .build();
709
+ * ```
710
+ *
711
+ * Pipelines ARE steps they can be used directly in another
712
+ * pipeline's steps array for composition.
713
+ */
714
+ declare function pipeline<Args extends StepContext = StepContext, S extends Step = Step>(config: {
530
715
  readonly name: string;
531
716
  readonly steps: readonly S[];
532
717
  readonly middleware?: readonly StepMiddleware[];
533
- readonly argsSchema?: ParserSchema<Args>;
718
+ readonly argsSchema?: StepSchema<Args>;
534
719
  readonly strict?: boolean;
535
- }): Pipeline<Args, Args & UnionToIntersection<ExtractProvides<S>>>;
720
+ }): AggregateStep<Args, Args & UnionToIntersection<ExtractProvides<S>>>;
721
+ declare function pipeline<Args extends StepContext = StepContext>(config: {
722
+ readonly name: string;
723
+ readonly middleware?: readonly StepMiddleware[];
724
+ readonly argsSchema?: StepSchema<Args>;
725
+ readonly strict?: boolean;
726
+ }): PipelineBuilder<Args, Args>;
536
727
 
537
728
  /**
538
729
  * A step with a conditional predicate attached.
@@ -552,24 +743,9 @@ type ConditionalStep = Step & {
552
743
  * skipped:
553
744
  * - No context snapshot is taken.
554
745
  * - No rollback entry is created.
555
- * - The step name is recorded in `result.meta.stepsSkipped`.
556
- *
557
- * If the predicate throws, the pipeline treats it as a step failure
558
- * and triggers rollback for any previously completed steps.
746
+ * - The step name is not recorded in the pipeline's `meta.stepsExecuted`.
559
747
  *
560
- * @example
561
- * ```ts
562
- * const steps = [
563
- * validateOrder,
564
- * when((ctx) => ctx.order.amount > 100, notifyManager),
565
- * sendConfirmation,
566
- * ];
567
- * ```
568
- *
569
- * @typeParam Requires - Inferred from the step's requires type.
570
- * @typeParam Provides - Inferred from the step's provides type.
571
- * @param predicate - Guard function. Receives the current accumulated
572
- * context (frozen). Return `true` to execute, `false` to skip.
748
+ * @param predicate - Guard function. Return `true` to execute, `false` to skip.
573
749
  * @param step - The step to conditionally execute.
574
750
  * @returns A frozen {@link TypedStep} with the predicate attached.
575
751
  */
@@ -577,6 +753,7 @@ declare function when<Requires extends StepContext, Provides extends StepContext
577
753
 
578
754
  /** Ensure a type satisfies StepContext, falling back to StepContext. */
579
755
  type AsContext<T> = T extends StepContext ? T : StepContext;
756
+
580
757
  /**
581
758
  * Run multiple steps concurrently and merge their outputs.
582
759
  *
@@ -586,8 +763,8 @@ type AsContext<T> = T extends StepContext ? T : StepContext;
586
763
  * steps are rolled back in reverse array order before the failure
587
764
  * propagates.
588
765
  *
589
- * The returned step acts as a single step from the pipeline's
590
- * perspective middleware wraps the group as a whole.
766
+ * Returns an {@link AggregateStep} with orchestration metadata
767
+ * tracking which inner steps executed.
591
768
  *
592
769
  * Inner steps retain their own `requires`/`provides` validation,
593
770
  * `retry`, and `timeout` behavior. Conditional steps (via `when()`)
@@ -595,7 +772,7 @@ type AsContext<T> = T extends StepContext ? T : StepContext;
595
772
  *
596
773
  * @example
597
774
  * ```ts
598
- * const pipeline = buildPipeline({
775
+ * const p = pipeline({
599
776
  * name: 'checkout',
600
777
  * steps: [
601
778
  * validateOrder,
@@ -606,105 +783,182 @@ type AsContext<T> = T extends StepContext ? T : StepContext;
606
783
  * ```
607
784
  *
608
785
  * @param steps - Two or more steps to execute concurrently.
609
- * @returns A frozen {@link TypedStep} whose `Requires` is the
786
+ * @returns A frozen {@link AggregateStep} whose `Requires` is the
610
787
  * intersection of all inner steps' requires, and `Provides` is the
611
788
  * intersection of all inner steps' provides.
612
789
  */
613
- declare function parallel<S extends readonly TypedStep[]>(...steps: [...S]): TypedStep<AsContext<UnionToIntersection<ExtractRequires<S[number]>>>, AsContext<UnionToIntersection<ExtractProvides<S[number]>>>>;
790
+ declare function parallel<S extends readonly Step[]>(...steps: [...S]): AggregateStep<AsContext<UnionToIntersection<ExtractRequires<S[number]>>>, AsContext<UnionToIntersection<ExtractProvides<S[number]>>>>;
614
791
 
792
+ /** A [predicate, step] tuple used by {@link choice}. */
793
+ type BranchTuple = readonly [(ctx: Readonly<StepContext>) => boolean, Step];
794
+ /** Extract the Requires type from a branch tuple's step. */
795
+ type BranchRequires<T> = T extends readonly [unknown, infer S extends Step] ? ExtractRequires<S> : T extends Step ? ExtractRequires<T> : StepContext;
796
+ /** Extract the Provides type from a branch tuple's step. */
797
+ type BranchProvides<T> = T extends readonly [unknown, infer S extends Step] ? ExtractProvides<S> : T extends Step ? ExtractProvides<T> : StepContext;
615
798
  /**
616
- * A fluent pipeline builder that progressively narrows the accumulated
617
- * context type as steps are added.
799
+ * Execute the first branch whose predicate returns `true`.
618
800
  *
619
- * Each method returns a new, frozen builderbuilders are immutable.
620
- * This means you can safely fork a builder to create variants:
801
+ * Similar to an AWS Step Functions Choice state predicates are evaluated
802
+ * in order, and the first match wins. Exactly one branch executes. If no
803
+ * predicate matches, the step fails with a `CHOICE_NO_MATCH` error.
804
+ *
805
+ * A bare step (without a predicate tuple) can be passed as the last argument
806
+ * to serve as a default branch — it is equivalent to `[() => true, step]`.
807
+ *
808
+ * Returns an {@link AggregateStep} with orchestration metadata
809
+ * tracking which branch executed.
621
810
  *
811
+ * All branches should provide the same output shape so that
812
+ * subsequent steps can rely on a consistent context type.
813
+ *
814
+ * @example
622
815
  * ```ts
623
- * const base = createPipeline('order').step(validate);
624
- * const withCharge = base.step(charge).build();
625
- * const withoutCharge = base.build(); // unaffected by the fork
816
+ * const p = pipeline({
817
+ * name: 'payment',
818
+ * steps: [
819
+ * validateOrder,
820
+ * choice(
821
+ * [(ctx) => ctx.method === 'card', chargeCard],
822
+ * [(ctx) => ctx.method === 'bank', chargeBankTransfer],
823
+ * chargeDefault, // default
824
+ * ),
825
+ * sendReceipt,
826
+ * ],
827
+ * });
626
828
  * ```
627
829
  *
628
- * @typeParam Args - The pipeline's initial input type.
629
- * @typeParam Ctx - The accumulated context type so far (grows with each `.step()`).
830
+ * @param branches - One or more `[predicate, step]` tuples, optionally
831
+ * followed by a bare step as the default.
832
+ * @returns A frozen {@link AggregateStep} that executes the first
833
+ * matching branch.
630
834
  */
631
- type PipelineBuilder<Args extends StepContext, Ctx extends StepContext> = {
632
- /**
633
- * Add a step to the pipeline.
634
- *
635
- * The step's `Requires` type must be satisfied by the current `Ctx`.
636
- * The returned builder's `Ctx` expands to include the step's `Provides`.
637
- *
638
- * @typeParam Provides - The output type of the step being added.
639
- * @param step - A {@link TypedStep} (from `defineStep` or `when`).
640
- * @returns A new builder with the expanded context type.
641
- */
642
- readonly step: <Provides extends StepContext>(step: TypedStep<Ctx, Provides>) => PipelineBuilder<Args, Ctx & Provides>;
643
- /**
644
- * Add middleware to the pipeline.
645
- *
646
- * Middleware is applied to every step. Multiple `.use()` calls
647
- * accumulate — earlier middleware is outermost (executes first).
648
- *
649
- * @param middleware - One or more {@link StepMiddleware} functions.
650
- * @returns A new builder with the middleware added.
651
- */
652
- readonly use: (...middleware: StepMiddleware[]) => PipelineBuilder<Args, Ctx>;
653
- /**
654
- * Build the pipeline.
655
- *
656
- * @returns A frozen {@link Pipeline} ready to execute with `run()`.
657
- */
658
- readonly build: () => Pipeline<Args, Ctx>;
659
- };
835
+ declare function choice<B extends readonly BranchTuple[]>(...branches: [...B]): AggregateStep<AsContext<UnionToIntersection<BranchRequires<B[number]>>>, AsContext<UnionToIntersection<BranchProvides<B[number]>>>>;
836
+ declare function choice<B extends readonly BranchTuple[], D extends Step>(...args: [...B, D]): AggregateStep<AsContext<UnionToIntersection<BranchRequires<B[number]> | ExtractRequires<D>>>, AsContext<UnionToIntersection<BranchProvides<B[number]> | ExtractProvides<D>>>>;
837
+
660
838
  /**
661
- * Start building a pipeline with the fluent builder API.
839
+ * Iterate over a collection and run a function or step per item, concurrently.
662
840
  *
663
- * The builder gives progressive type narrowingeach `.step()` call
664
- * extends the known context type, so TypeScript catches mismatches
665
- * at compile time.
841
+ * **Function form:** `(item, ctx) => result`items can be any type.
666
842
  *
667
- * **Type-only args** (no runtime validation):
668
- * ```ts
669
- * createPipeline<{ orderId: string }>('placeOrder')
670
- * .step(validateOrder)
671
- * .step(chargePayment)
672
- * .build();
673
- * ```
843
+ * **Step form:** each item must be an object whose keys are spread into
844
+ * the pipeline context before the step runs.
674
845
  *
675
- * **Schema args** (runtime validation + type inference):
846
+ * The step receives `{ ...ctx, ...item }`. The step's own
847
+ * `requires`/`provides` validation, `retry`, and `timeout` apply
848
+ * per item. On partial failure, succeeded items are rolled back
849
+ * (if the step has a rollback handler).
850
+ *
851
+ * @example
676
852
  * ```ts
677
- * createPipeline('placeOrder', z.object({ orderId: z.string() }))
678
- * .step(validateOrder)
679
- * .step(chargePayment)
680
- * .build();
853
+ * // Function form
854
+ * const pipeline = pipeline({
855
+ * name: 'notify',
856
+ * steps: [
857
+ * map('emails', (ctx) => ctx.users, async (user) => {
858
+ * await sendEmail(user.email);
859
+ * return { email: user.email, sentAt: new Date() };
860
+ * }),
861
+ * ],
862
+ * });
863
+ *
864
+ * // Step form
865
+ * const pipeline = pipeline({
866
+ * name: 'process',
867
+ * steps: [
868
+ * map('results', (ctx) => ctx.items, processItem),
869
+ * ],
870
+ * });
681
871
  * ```
682
872
  *
683
- * **Strict mode** (no schema):
873
+ * @param key - The output key under which results are collected.
874
+ * @param collection - A selector that extracts the collection from context.
875
+ * @param fnOrStep - A per-item function or a step to execute for each item.
876
+ * @returns A frozen {@link TypedStep} that provides `{ [key]: Result[] }`.
877
+ */
878
+ declare function map<K extends string, Item, Result, Ctx extends StepContext = StepContext>(key: K, collection: (ctx: Readonly<Ctx>) => Item[], fn: (item: Item, ctx: Readonly<Ctx>) => Result | Promise<Result>): TypedStep<Ctx, Record<K, Awaited<Result>[]>>;
879
+ declare function map<K extends string, S extends Step, Ctx extends StepContext = StepContext>(key: K, collection: (ctx: Readonly<Ctx>) => StepContext[], step: S): TypedStep<Ctx, Record<K, ExtractProvides<S>[]>>;
880
+
881
+ /**
882
+ * Filter a collection from context using a predicate, concurrently.
883
+ *
884
+ * Extracts a collection from the pipeline context, evaluates the
885
+ * predicate for each item via `Promise.allSettled`, and collects
886
+ * items that pass into an array under the given key.
887
+ *
888
+ * Original order is preserved.
889
+ *
890
+ * The predicate can be sync or async. If any predicate throws, the
891
+ * entire step fails — no partial results are returned.
892
+ *
893
+ * There is no rollback (filtering is a pure operation with nothing
894
+ * to undo).
895
+ *
896
+ * @example
684
897
  * ```ts
685
- * createPipeline('placeOrder', { strict: true })
898
+ * const pipeline = pipeline({
899
+ * name: 'notify',
900
+ * steps: [
901
+ * filter(
902
+ * 'eligible',
903
+ * (ctx) => ctx.users,
904
+ * (user) => user.optedIn,
905
+ * ),
906
+ * map('emails', (ctx) => ctx.eligible, sendEmail),
907
+ * ],
908
+ * });
909
+ *
910
+ * // Async predicate
911
+ * filter('valid', (ctx) => ctx.orders, async (order) => {
912
+ * const inventory = await checkInventory(order.sku);
913
+ * return inventory.available >= order.quantity;
914
+ * });
686
915
  * ```
687
916
  *
688
- * **Schema + strict mode:**
917
+ * @param key - The output key under which filtered results are collected.
918
+ * @param collection - A selector that extracts the collection from context.
919
+ * @param predicate - A per-item predicate. Return `true` to keep, `false` to discard.
920
+ * @returns A frozen {@link TypedStep} that provides `{ [key]: Item[] }`.
921
+ */
922
+ declare function filter<K extends string, Item, Ctx extends StepContext = StepContext>(key: K, collection: (ctx: Readonly<Ctx>) => Item[], predicate: (item: Item, ctx: Readonly<Ctx>) => boolean | Promise<boolean>): TypedStep<Ctx, Record<K, Item[]>>;
923
+
924
+ /**
925
+ * Map each item in a collection to an array, then flatten one level.
926
+ *
927
+ * Extracts a collection from the pipeline context, runs the callback
928
+ * for each item via `Promise.allSettled`, and flattens the per-item
929
+ * arrays into a single array under the given key.
930
+ *
931
+ * The callback can be sync or async. If any callback throws, the
932
+ * entire step fails — no partial results are returned.
933
+ *
934
+ * There is no rollback (pure transformation with nothing to undo).
935
+ *
936
+ * @example
689
937
  * ```ts
690
- * createPipeline('placeOrder', z.object({ orderId: z.string() }), { strict: true })
938
+ * // Expand orders into line items
939
+ * const pipeline = pipeline({
940
+ * name: 'process',
941
+ * steps: [
942
+ * flatMap(
943
+ * 'lineItems',
944
+ * (ctx) => ctx.orders,
945
+ * (order) => order.items,
946
+ * ),
947
+ * ],
948
+ * });
949
+ *
950
+ * // Async callback
951
+ * flatMap('emails', (ctx) => ctx.teams, async (team) => {
952
+ * const members = await fetchMembers(team.id);
953
+ * return members.map((m) => m.email);
954
+ * });
691
955
  * ```
692
956
  *
693
- * @typeParam Args - The pipeline's input type. Inferred from `argsSchema`
694
- * if provided, otherwise specify via generic parameter.
695
- * @param name - Pipeline name, used in metadata and error messages.
696
- * @param schemaOrOptions - A schema for runtime args validation, or a
697
- * {@link PipelineOptions} object.
698
- * @param options - When the second argument is a schema, pass options here.
699
- * @returns A frozen {@link PipelineBuilder} ready for `.step()`,
700
- * `.use()`, and `.build()`.
701
- */
702
- type PipelineOptions = {
703
- strict?: boolean;
704
- };
705
- declare function createPipeline<Args extends StepContext>(name: string): PipelineBuilder<Args, Args>;
706
- declare function createPipeline<Args extends StepContext>(name: string, argsSchema: ParserSchema<Args>): PipelineBuilder<Args, Args>;
707
- declare function createPipeline<Args extends StepContext>(name: string, options: PipelineOptions): PipelineBuilder<Args, Args>;
708
- declare function createPipeline<Args extends StepContext>(name: string, argsSchema: ParserSchema<Args>, options: PipelineOptions): PipelineBuilder<Args, Args>;
957
+ * @param key - The output key under which flattened results are collected.
958
+ * @param collection - A selector that extracts the collection from context.
959
+ * @param fn - A per-item callback that returns an array (or Promise of array).
960
+ * @returns A frozen {@link TypedStep} that provides `{ [key]: Item[] }`.
961
+ */
962
+ declare function flatMap<K extends string, Item, Result, Ctx extends StepContext = StepContext>(key: K, collection: (ctx: Readonly<Ctx>) => Item[], fn: (item: Item, ctx: Readonly<Ctx>) => Result[] | Promise<Result[]>): TypedStep<Ctx, Record<K, Result[]>>;
709
963
 
710
- export { type ConditionalStep, type ExtractProvides, type ExtractRequires, type Pipeline, type PipelineBuilder, type PipelineConfig, type PipelineExecutionMeta, type PipelineFailure, type PipelineResult, type PipelineSuccess, type RetryPolicy, type RollbackFailure, type RollbackReport, RunsheetError, type RunsheetErrorCode, type Step, type StepConfig, type StepContext, type StepExecutor, type StepInfo, type StepMiddleware, type StepOutput, type TypedStep, buildPipeline, createPipeline, defineStep, parallel, when };
964
+ export { type AggregateFailure, type AggregateMeta, type AggregateResult, type AggregateStep, type AggregateSuccess, ArgsValidationError, ChoiceNoMatchError, type ConditionalStep, type ExtractProvides, type ExtractRequires, type PipelineBuilder, type PipelineConfig, PredicateError, ProvidesValidationError, RequiresValidationError, RetryExhaustedError, type RetryPolicy, RollbackError, type RollbackFailure, type RollbackReport, RunsheetError, type RunsheetErrorCode, type Step, type StepConfig, type StepContext, type StepExecutor, type StepFailure, type StepInfo, type StepMeta, type StepMiddleware, type StepOutput, type StepResult, type StepSchema, type StepSuccess, StrictOverlapError, TimeoutError, type TypedStep, UnknownError, choice, defineStep, filter, flatMap, map, parallel, pipeline, when };