tubeless 0.2.6 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +3 -3
  2. package/dist/core/pipeline-finalizer.js +0 -1
  3. package/dist/core/pipeline-finalizer.js.map +1 -1
  4. package/dist/core/pipeline-steps.d.ts +61 -77
  5. package/dist/core/pipeline-steps.js +25 -44
  6. package/dist/core/pipeline-steps.js.map +1 -1
  7. package/dist/project/project-compiler.d.ts +21 -4
  8. package/dist/project/project-compiler.js +120 -13
  9. package/dist/project/project-compiler.js.map +1 -1
  10. package/dist/project/project-document.d.ts +32 -2
  11. package/dist/project/project-document.js +39 -4
  12. package/dist/project/project-document.js.map +1 -1
  13. package/dist/project/project.d.ts +2 -2
  14. package/dist/project/project.js.map +1 -1
  15. package/dist/reporter/interactive-reporter.js +2 -6
  16. package/dist/reporter/interactive-reporter.js.map +1 -1
  17. package/dist/reporter/live-ticker-worker.js +55 -50
  18. package/dist/reporter/live-ticker-worker.js.map +1 -1
  19. package/dist/reporter/live-ticker.d.ts +0 -3
  20. package/dist/reporter/live-ticker.js +92 -170
  21. package/dist/reporter/live-ticker.js.map +1 -1
  22. package/dist/workbench/workbench-bin.d.ts +2 -6
  23. package/dist/workbench/workbench-bin.js +8 -20
  24. package/dist/workbench/workbench-bin.js.map +1 -1
  25. package/dist/workbench/workbench-shared.d.ts +1 -15
  26. package/dist/workbench/workbench-shared.js +10 -42
  27. package/dist/workbench/workbench-shared.js.map +1 -1
  28. package/dist/workbench/workbench-ui.js +0 -3
  29. package/dist/workbench/workbench-ui.js.map +1 -1
  30. package/docs/README.md +12 -13
  31. package/docs/agent-guide.md +17 -12
  32. package/docs/api-reference.md +4 -10
  33. package/docs/api-report.json +4 -10
  34. package/docs/child-pipeline-composition.md +24 -19
  35. package/docs/cli.md +4 -6
  36. package/docs/concepts.md +13 -11
  37. package/docs/declarative-pipelines.md +74 -26
  38. package/docs/getting-started.md +5 -6
  39. package/docs/llms.txt +0 -3
  40. package/docs/pipeline-document.schema.json +53 -2
  41. package/docs/recipes.md +6 -6
  42. package/docs/remote-step-composition.md +4 -3
  43. package/examples/best-effort.ts +1 -1
  44. package/examples/cancellation-and-testing.ts +1 -1
  45. package/examples/catalog/pipelines/enrich.ts +3 -3
  46. package/examples/catalog/pipelines/import.ts +2 -2
  47. package/examples/catalog/pipelines/normalize.ts +1 -1
  48. package/examples/catalog/pipelines/publish.ts +1 -1
  49. package/examples/catalog/tubeless.project.ts +4 -0
  50. package/examples/child-pipeline.ts +4 -4
  51. package/examples/cli-job.ts +1 -1
  52. package/examples/conditional-step.ts +2 -2
  53. package/examples/declarative/handlers.ts +47 -4
  54. package/examples/declarative/pipelines.yaml +29 -7
  55. package/examples/fan-out-progress.ts +3 -3
  56. package/examples/host-embedding.ts +1 -1
  57. package/examples/live-tui.ts +1 -1
  58. package/examples/node-artifacts.ts +1 -1
  59. package/examples/peloton.ts +9 -6
  60. package/examples/publish-with-gates.ts +1 -1
  61. package/examples/remote-steps.ts +2 -2
  62. package/examples/resumable-enrichment.ts +1 -1
  63. package/examples/tracing.ts +1 -1
  64. package/examples/typed-import.ts +1 -1
  65. package/examples/validated-boundaries.ts +1 -1
  66. package/package.json +2 -5
  67. package/skills/tubeless/SKILL.md +12 -9
  68. package/skills/tubeless-make-pipeline/SKILL.md +5 -4
  69. package/dist/reporter/live-ticker-supervisor.d.ts +0 -1
  70. package/dist/reporter/live-ticker-supervisor.js +0 -44
  71. package/dist/reporter/live-ticker-supervisor.js.map +0 -1
  72. package/dist/workbench/workbench-trampoline.d.ts +0 -71
  73. package/dist/workbench/workbench-trampoline.js +0 -136
  74. package/dist/workbench/workbench-trampoline.js.map +0 -1
package/README.md CHANGED
@@ -36,8 +36,8 @@ Tubeless is pre-1.0, so the public API may change between releases.
36
36
 
37
37
  ## Quick start
38
38
 
39
- This pipeline loads a list of strings, normalizes them, and returns the result.
40
- Declaring `load` as a dependency gives `normalize` a typed input.
39
+ This pipeline loads and normalizes strings. `step` creates a step; dependencies give typed
40
+ inputs. Adding `skip` makes it skippable and widens its output to include `undefined`.
41
41
 
42
42
  ```ts
43
43
  import { createSteps, definePipeline, requireOutputs } from "tubeless";
@@ -46,7 +46,7 @@ interface ImportOptions {
46
46
  lines: readonly string[];
47
47
  }
48
48
 
49
- const step = createSteps<ImportOptions>();
49
+ const { step } = createSteps<ImportOptions>();
50
50
 
51
51
  const load = step("load", {
52
52
  run: (_inputs, context) => context.options.lines,
@@ -18,7 +18,6 @@ export function requireOutputs(requiredSteps, finalize) {
18
18
  }
19
19
  // SAFETY: every required step id was verified present above, so the partial
20
20
  // outputs contain all required keys and are a complete required-outputs map.
21
- // oxlint-disable-next-line anti-slop/no-chained-type-assertions
22
21
  return finalize(outputs, context);
23
22
  };
24
23
  const requiredFinalizer = (outputs, context) => invoke(uniqueRequiredSteps.map((step) => step.id), outputs, context);
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline-finalizer.js","sourceRoot":"","sources":["../../src/core/pipeline-finalizer.ts"],"names":[],"mappings":"AAIA,MAAM,0BAA0B,GAAkB,MAAM,CAAC,mCAAmC,CAAC,CAAC;AAW9F,MAAM,UAAU,yBAAyB,CACvC,QAAgB;IAEhB,yEAAyE;IACzE,mEAAmE;IACnE,OAAQ,QAAmF,CACzF,0BAA0B,CAC3B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,aAA6B,EAC7B,QAG+B;IAK/B,MAAM,mBAAmB,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,CACb,eAAkC,EAClC,OAAyD,EACzD,OAA+D,EAC/D,EAAE;QACF,MAAM,cAAc,GAAG,eAAe,CAAC,MAAM,CAC3C,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CACnE,CAAC;QACF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,sCAAsC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrF,CAAC;QACD,4EAA4E;QAC5E,6EAA6E;QAC7E,gEAAgE;QAChE,OAAO,QAAQ,CAAC,OAA6D,EAAE,OAAO,CAAC,CAAC;IAC1F,CAAC,CAAC;IACF,MAAM,iBAAiB,GAAG,CACxB,OAAyD,EACzD,OAA+D,EAC/D,EAAE,CACF,MAAM,CACJ,mBAAmB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAC1C,OAAO,EACP,OAAO,CACR,CAAC;IACJ,MAAM,QAAQ,GAA4D,MAAM,CAAC,MAAM,CAAC;QACtF,OAAO,EAAE,CAAC,eAAkC,EAAE,EAAE;YAC9C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;YACrD,OAAO,CACL,OAAyD,EACzD,OAA+D,EAC/D,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC;KAC/C,CAAC,CAAC;IACH,MAAM,CAAC,cAAc,CAAC,iBAAiB,EAAE,0BAA0B,EAAE;QACnE,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC;IACH,OAAO,iBAAiB,CAAC;AAC3B,CAAC","sourcesContent":["import type { AnyStep, StepOutput } from \"./pipeline-steps.js\";\nimport type { StepsOptions } from \"./pipeline-definition.js\";\nimport type { PipelineExecutionContext } from \"./pipeline-types.js\";\n\nconst REQUIRED_FINALIZER_OUTPUTS: unique symbol = Symbol(\"tubeless.requiredFinalizerOutputs\");\n\nexport interface RequiredFinalizerMetadata<TOptions extends object> {\n readonly steps: readonly AnyStep<TOptions>[];\n compile(requiredStepIds: readonly string[]): (...args: never[]) => unknown;\n}\n\ntype RequiredPipelineOutputs<TSteps extends readonly AnyStep[]> = {\n [S in TSteps[number] as S[\"id\"]]-?: StepOutput<S>;\n};\n\nexport function requiredFinalizerMetadata<TOptions extends object>(\n finalize: object\n): RequiredFinalizerMetadata<TOptions> | undefined {\n // SAFETY: `requireOutputs` stamps internal compilation metadata onto the\n // finalizer; the intersection only exposes that optional property.\n return (finalize as { [REQUIRED_FINALIZER_OUTPUTS]?: RequiredFinalizerMetadata<TOptions> })[\n REQUIRED_FINALIZER_OUTPUTS\n ];\n}\n\n/**\n * Build a finalizer that only runs when every listed step published an output.\n * Presence is checked by output slot, so a successfully published `undefined`\n * remains distinct from a structural skip or failure.\n */\nexport function requireOutputs<const TRequiredSteps extends readonly AnyStep[], TResult>(\n requiredSteps: TRequiredSteps,\n finalize: (\n outputs: RequiredPipelineOutputs<TRequiredSteps>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) => TResult | Promise<TResult>\n): (\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n) => TResult | Promise<TResult> {\n const uniqueRequiredSteps = [...new Set(requiredSteps)];\n const invoke = (\n requiredStepIds: readonly string[],\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) => {\n const missingStepIds = requiredStepIds.filter(\n (stepId) => !Object.prototype.hasOwnProperty.call(outputs, stepId)\n );\n if (missingStepIds.length > 0) {\n throw new Error(`Required pipeline outputs missing: ${missingStepIds.join(\", \")}`);\n }\n // SAFETY: every required step id was verified present above, so the partial\n // outputs contain all required keys and are a complete required-outputs map.\n // oxlint-disable-next-line anti-slop/no-chained-type-assertions\n return finalize(outputs as unknown as RequiredPipelineOutputs<TRequiredSteps>, context);\n };\n const requiredFinalizer = (\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) =>\n invoke(\n uniqueRequiredSteps.map((step) => step.id),\n outputs,\n context\n );\n const metadata: RequiredFinalizerMetadata<StepsOptions<TRequiredSteps>> = Object.freeze({\n compile: (requiredStepIds: readonly string[]) => {\n const snapshot = Object.freeze([...requiredStepIds]);\n return (\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) => invoke(snapshot, outputs, context);\n },\n steps: Object.freeze([...uniqueRequiredSteps]),\n });\n Object.defineProperty(requiredFinalizer, REQUIRED_FINALIZER_OUTPUTS, {\n value: metadata,\n });\n return requiredFinalizer;\n}\n"]}
1
+ {"version":3,"file":"pipeline-finalizer.js","sourceRoot":"","sources":["../../src/core/pipeline-finalizer.ts"],"names":[],"mappings":"AAIA,MAAM,0BAA0B,GAAkB,MAAM,CAAC,mCAAmC,CAAC,CAAC;AAW9F,MAAM,UAAU,yBAAyB,CACvC,QAAgB;IAEhB,yEAAyE;IACzE,mEAAmE;IACnE,OAAQ,QAAmF,CACzF,0BAA0B,CAC3B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,aAA6B,EAC7B,QAG+B;IAK/B,MAAM,mBAAmB,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,CACb,eAAkC,EAClC,OAAyD,EACzD,OAA+D,EAC/D,EAAE;QACF,MAAM,cAAc,GAAG,eAAe,CAAC,MAAM,CAC3C,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CACnE,CAAC;QACF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,sCAAsC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrF,CAAC;QACD,4EAA4E;QAC5E,6EAA6E;QAC7E,OAAO,QAAQ,CAAC,OAA6D,EAAE,OAAO,CAAC,CAAC;IAC1F,CAAC,CAAC;IACF,MAAM,iBAAiB,GAAG,CACxB,OAAyD,EACzD,OAA+D,EAC/D,EAAE,CACF,MAAM,CACJ,mBAAmB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAC1C,OAAO,EACP,OAAO,CACR,CAAC;IACJ,MAAM,QAAQ,GAA4D,MAAM,CAAC,MAAM,CAAC;QACtF,OAAO,EAAE,CAAC,eAAkC,EAAE,EAAE;YAC9C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;YACrD,OAAO,CACL,OAAyD,EACzD,OAA+D,EAC/D,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC;KAC/C,CAAC,CAAC;IACH,MAAM,CAAC,cAAc,CAAC,iBAAiB,EAAE,0BAA0B,EAAE;QACnE,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC;IACH,OAAO,iBAAiB,CAAC;AAC3B,CAAC","sourcesContent":["import type { AnyStep, StepOutput } from \"./pipeline-steps.js\";\nimport type { StepsOptions } from \"./pipeline-definition.js\";\nimport type { PipelineExecutionContext } from \"./pipeline-types.js\";\n\nconst REQUIRED_FINALIZER_OUTPUTS: unique symbol = Symbol(\"tubeless.requiredFinalizerOutputs\");\n\nexport interface RequiredFinalizerMetadata<TOptions extends object> {\n readonly steps: readonly AnyStep<TOptions>[];\n compile(requiredStepIds: readonly string[]): (...args: never[]) => unknown;\n}\n\ntype RequiredPipelineOutputs<TSteps extends readonly AnyStep[]> = {\n [S in TSteps[number] as S[\"id\"]]-?: StepOutput<S>;\n};\n\nexport function requiredFinalizerMetadata<TOptions extends object>(\n finalize: object\n): RequiredFinalizerMetadata<TOptions> | undefined {\n // SAFETY: `requireOutputs` stamps internal compilation metadata onto the\n // finalizer; the intersection only exposes that optional property.\n return (finalize as { [REQUIRED_FINALIZER_OUTPUTS]?: RequiredFinalizerMetadata<TOptions> })[\n REQUIRED_FINALIZER_OUTPUTS\n ];\n}\n\n/**\n * Build a finalizer that only runs when every listed step published an output.\n * Presence is checked by output slot, so a successfully published `undefined`\n * remains distinct from a structural skip or failure.\n */\nexport function requireOutputs<const TRequiredSteps extends readonly AnyStep[], TResult>(\n requiredSteps: TRequiredSteps,\n finalize: (\n outputs: RequiredPipelineOutputs<TRequiredSteps>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) => TResult | Promise<TResult>\n): (\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n) => TResult | Promise<TResult> {\n const uniqueRequiredSteps = [...new Set(requiredSteps)];\n const invoke = (\n requiredStepIds: readonly string[],\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) => {\n const missingStepIds = requiredStepIds.filter(\n (stepId) => !Object.prototype.hasOwnProperty.call(outputs, stepId)\n );\n if (missingStepIds.length > 0) {\n throw new Error(`Required pipeline outputs missing: ${missingStepIds.join(\", \")}`);\n }\n // SAFETY: every required step id was verified present above, so the partial\n // outputs contain all required keys and are a complete required-outputs map.\n return finalize(outputs as unknown as RequiredPipelineOutputs<TRequiredSteps>, context);\n };\n const requiredFinalizer = (\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) =>\n invoke(\n uniqueRequiredSteps.map((step) => step.id),\n outputs,\n context\n );\n const metadata: RequiredFinalizerMetadata<StepsOptions<TRequiredSteps>> = Object.freeze({\n compile: (requiredStepIds: readonly string[]) => {\n const snapshot = Object.freeze([...requiredStepIds]);\n return (\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) => invoke(snapshot, outputs, context);\n },\n steps: Object.freeze([...uniqueRequiredSteps]),\n });\n Object.defineProperty(requiredFinalizer, REQUIRED_FINALIZER_OUTPUTS, {\n value: metadata,\n });\n return requiredFinalizer;\n}\n"]}
@@ -117,67 +117,6 @@ type PlainStepFields<TOptions extends object, TDeps extends readonly AnyStep<TOp
117
117
  type SchemaStepFields<TOptions extends object, TDeps extends readonly AnyStep<TOptions>[], TOptionalDeps extends readonly AnyStep<TOptions>[], TSchema extends StandardSchemaV1> = Omit<PlainStepFields<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>, "outputSchema"> & {
118
118
  outputSchema: TSchema;
119
119
  };
120
- interface StepConstructor<TOptions extends object, TInputOptions extends object = TOptions> {
121
- /** Ordinary steps never policy-skip, so dependents receive their full output. */
122
- <TId extends string, TSchema extends StandardSchemaV1, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: SchemaStepFields<TOptions, TDeps, TOptionalDeps, TSchema> & {
123
- skip?: never;
124
- }): Step<TId, InferSchemaOutput<TSchema>, TOptions, TInputOptions, InferSchemaInput<TSchema>>;
125
- <TId extends string, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = [], TOut = unknown>(id: TId, definition: PlainStepFields<TOptions, TDeps, TOptionalDeps, TOut> & {
126
- skip?: never;
127
- }): Step<TId, TOut, TOptions, TInputOptions>;
128
- /** Explicit policy-skip constructor; dependents receive `TOut | undefined`. */
129
- skippable: SkippableStepConstructor<TOptions, TInputOptions>;
130
- }
131
- interface SkippableStepConstructor<TOptions extends object, TInputOptions extends object = TOptions> {
132
- <TId extends string, TSchema extends StandardSchemaV1, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: SchemaStepFields<TOptions, TDeps, TOptionalDeps, TSchema> & {
133
- skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>> | undefined;
134
- }): Step<TId, InferSchemaOutput<TSchema> | undefined, TOptions, TInputOptions, InferSchemaInput<TSchema>>;
135
- <TId extends string, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = [], TOut = unknown>(id: TId, definition: PlainStepFields<TOptions, TDeps, TOptionalDeps, TOut> & {
136
- skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, TOut> | undefined;
137
- }): Step<TId, TOut | undefined, TOptions, TInputOptions>;
138
- }
139
- interface FromPipelineConstructor<TOptions extends object, TInputOptions extends object = TOptions> {
140
- <TId extends string, TChildPipeline extends Pipeline<object, unknown>, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: ChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {
141
- skip?: never;
142
- mapResult?: undefined;
143
- }): Step<TId, PipelineResultOf<TChildPipeline>, TOptions, TInputOptions>;
144
- <TId extends string, TChildPipeline extends Pipeline<object, unknown>, TOut, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {
145
- skip?: never;
146
- mapResult(value: PipelineResultOf<TChildPipeline>, result: PipelineRun<PipelineResultOf<TChildPipeline>>, context: PipelineStepContext<TOptions>): TOut;
147
- }): Step<TId, Awaited<TOut>, TOptions, TInputOptions>;
148
- skippable: SkippableFromPipelineConstructor<TOptions, TInputOptions>;
149
- }
150
- interface SkippableFromPipelineConstructor<TOptions extends object, TInputOptions extends object = TOptions> {
151
- <TId extends string, TChildPipeline extends Pipeline<object, unknown>, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {
152
- skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, PipelineResultOf<TChildPipeline>> | undefined;
153
- mapResult?: undefined;
154
- }): Step<TId, PipelineResultOf<TChildPipeline> | undefined, TOptions, TInputOptions>;
155
- <TId extends string, TChildPipeline extends Pipeline<object, unknown>, TOut, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {
156
- skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, NoInfer<Awaited<TOut>>> | undefined;
157
- mapResult(value: PipelineResultOf<TChildPipeline>, result: PipelineRun<PipelineResultOf<TChildPipeline>>, context: PipelineStepContext<TOptions>): TOut;
158
- }): Step<TId, Awaited<TOut> | undefined, TOptions, TInputOptions>;
159
- }
160
- interface ForEachPipelineConstructor<TOptions extends object, TInputOptions extends object = TOptions> {
161
- <TId extends string, TChildPipeline extends Pipeline<object, unknown>, TItem, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: MappedChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline, TItem> & {
162
- skip?: never;
163
- mapResult?: undefined;
164
- }): Step<TId, readonly PipelineResultOf<TChildPipeline>[], TOptions, TInputOptions>;
165
- <TId extends string, TChildPipeline extends Pipeline<object, unknown>, TItem, TOut, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: MappedChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline, TItem> & {
166
- skip?: never;
167
- mapResult(value: PipelineResultOf<TChildPipeline>, result: PipelineRun<PipelineResultOf<TChildPipeline>>, item: TItem, index: number, context: PipelineStepContext<TOptions>): TOut;
168
- }): Step<TId, readonly TOut[], TOptions, TInputOptions>;
169
- skippable: SkippableForEachPipelineConstructor<TOptions, TInputOptions>;
170
- }
171
- interface SkippableForEachPipelineConstructor<TOptions extends object, TInputOptions extends object = TOptions> {
172
- <TId extends string, TChildPipeline extends Pipeline<object, unknown>, TItem, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: MappedChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline, TItem> & {
173
- skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, readonly PipelineResultOf<TChildPipeline>[]> | undefined;
174
- mapResult?: undefined;
175
- }): Step<TId, readonly PipelineResultOf<TChildPipeline>[] | undefined, TOptions, TInputOptions>;
176
- <TId extends string, TChildPipeline extends Pipeline<object, unknown>, TItem, TOut, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: MappedChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline, TItem> & {
177
- skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, NoInfer<readonly TOut[]>> | undefined;
178
- mapResult(value: PipelineResultOf<TChildPipeline>, result: PipelineRun<PipelineResultOf<TChildPipeline>>, item: TItem, index: number, context: PipelineStepContext<TOptions>): TOut;
179
- }): Step<TId, readonly TOut[] | undefined, TOptions, TInputOptions>;
180
- }
181
120
  type RemoteStepDefinitionBase<TParentOptions extends object, TDeps extends readonly AnyStep<TParentOptions>[], TOptionalDeps extends readonly AnyStep<TParentOptions>[], TPayload, TSchema extends StandardSchemaV1> = {
182
121
  adapter: RemoteStepAdapter<TParentOptions, TPayload, InferSchemaInput<TSchema>>;
183
122
  mapInput(inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, context: PipelineStepContext<TParentOptions>): TPayload;
@@ -189,22 +128,7 @@ type RemoteStepDefinitionBase<TParentOptions extends object, TDeps extends reado
189
128
  description?: string;
190
129
  dryRun?: StepDryRunPolicy<TParentOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>;
191
130
  };
192
- interface FromRemoteConstructor<TOptions extends object, TInputOptions extends object = TOptions> {
193
- <TId extends string, TSchema extends StandardSchemaV1, TPayload, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: RemoteStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TPayload, TSchema> & {
194
- skip?: never;
195
- }): Step<TId, InferSchemaOutput<TSchema>, TOptions, TInputOptions, InferSchemaInput<TSchema>>;
196
- skippable: SkippableFromRemoteConstructor<TOptions, TInputOptions>;
197
- }
198
- interface SkippableFromRemoteConstructor<TOptions extends object, TInputOptions extends object = TOptions> {
199
- <TId extends string, TSchema extends StandardSchemaV1, TPayload, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: RemoteStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TPayload, TSchema> & {
200
- skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>> | undefined;
201
- }): Step<TId, InferSchemaOutput<TSchema> | undefined, TOptions, TInputOptions, InferSchemaInput<TSchema>>;
202
- }
203
- export interface StepFactory<TOptions extends object, TInputOptions extends object = TOptions> extends StepConstructor<TOptions, TInputOptions> {
204
- fromPipeline: FromPipelineConstructor<TOptions, TInputOptions>;
205
- fromRemote: FromRemoteConstructor<TOptions, TInputOptions>;
206
- forEachPipeline: ForEachPipelineConstructor<TOptions, TInputOptions>;
207
- }
131
+ export type StepFactory<TOptions extends object, TInputOptions extends object = TOptions> = ReturnType<typeof createStepFactory<TOptions, TInputOptions>>;
208
132
  /**
209
133
  * Returns a step factory scoped to one pipeline's domain options. Pass built-in
210
134
  * run controls as the second argument to `run` / `runOrThrow`. Child
@@ -212,4 +136,64 @@ export interface StepFactory<TOptions extends object, TInputOptions extends obje
212
136
  */
213
137
  export declare function createSteps<TOptions extends object = {}>(): StepFactory<TOptions>;
214
138
  export declare function createSteps<const TSchema extends StandardSchemaV1<object, object>>(optionsSchema: TSchema): StepFactory<InferSchemaOutput<TSchema>, InferSchemaInput<TSchema>>;
139
+ declare function createStepFactory<TOptions extends object, TInputOptions extends object = TOptions>(optionsSchema?: StandardSchemaV1): {
140
+ step: {
141
+ <TId extends string, TSchema extends StandardSchemaV1, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: SchemaStepFields<TOptions, TDeps, TOptionalDeps, TSchema> & {
142
+ skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>> | undefined;
143
+ }): Step<TId, InferSchemaOutput<TSchema> | undefined, TOptions, TInputOptions, InferSchemaInput<TSchema>>;
144
+ <TId extends string, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = [], TOut = unknown>(id: TId, definition: PlainStepFields<TOptions, TDeps, TOptionalDeps, TOut> & {
145
+ skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, TOut> | undefined;
146
+ }): Step<TId, TOut | undefined, TOptions, TInputOptions>;
147
+ <TId extends string, TSchema extends StandardSchemaV1, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: SchemaStepFields<TOptions, TDeps, TOptionalDeps, TSchema> & {
148
+ skip?: never;
149
+ }): Step<TId, InferSchemaOutput<TSchema>, TOptions, TInputOptions, InferSchemaInput<TSchema>>;
150
+ <TId extends string, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = [], TOut = unknown>(id: TId, definition: PlainStepFields<TOptions, TDeps, TOptionalDeps, TOut> & {
151
+ skip?: never;
152
+ }): Step<TId, TOut, TOptions, TInputOptions>;
153
+ };
154
+ fromPipeline: {
155
+ <TId extends string, TChildPipeline extends Pipeline<object, unknown>, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: ChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {
156
+ skip?: never;
157
+ mapResult?: undefined;
158
+ }): Step<TId, PipelineResultOf<TChildPipeline>, TOptions, TInputOptions>;
159
+ <TId extends string, TChildPipeline extends Pipeline<object, unknown>, TOut, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {
160
+ skip?: never;
161
+ mapResult(value: PipelineResultOf<TChildPipeline>, result: PipelineRun<PipelineResultOf<TChildPipeline>>, context: PipelineStepContext<TOptions>): TOut;
162
+ }): Step<TId, Awaited<TOut>, TOptions, TInputOptions>;
163
+ <TId extends string, TChildPipeline extends Pipeline<object, unknown>, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {
164
+ skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, PipelineResultOf<TChildPipeline>> | undefined;
165
+ mapResult?: undefined;
166
+ }): Step<TId, PipelineResultOf<TChildPipeline> | undefined, TOptions, TInputOptions>;
167
+ <TId extends string, TChildPipeline extends Pipeline<object, unknown>, TOut, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {
168
+ skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, NoInfer<Awaited<TOut>>> | undefined;
169
+ mapResult(value: PipelineResultOf<TChildPipeline>, result: PipelineRun<PipelineResultOf<TChildPipeline>>, context: PipelineStepContext<TOptions>): TOut;
170
+ }): Step<TId, Awaited<TOut> | undefined, TOptions, TInputOptions>;
171
+ };
172
+ fromRemote: {
173
+ <TId extends string, TSchema extends StandardSchemaV1, TPayload, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: RemoteStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TPayload, TSchema> & {
174
+ skip?: never;
175
+ }): Step<TId, InferSchemaOutput<TSchema>, TOptions, TInputOptions, InferSchemaInput<TSchema>>;
176
+ <TId extends string, TSchema extends StandardSchemaV1, TPayload, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: RemoteStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TPayload, TSchema> & {
177
+ skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>> | undefined;
178
+ }): Step<TId, InferSchemaOutput<TSchema> | undefined, TOptions, TInputOptions, InferSchemaInput<TSchema>>;
179
+ };
180
+ forEachPipeline: {
181
+ <TId extends string, TChildPipeline extends Pipeline<object, unknown>, TItem, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: MappedChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline, TItem> & {
182
+ skip?: never;
183
+ mapResult?: undefined;
184
+ }): Step<TId, readonly PipelineResultOf<TChildPipeline>[], TOptions, TInputOptions>;
185
+ <TId extends string, TChildPipeline extends Pipeline<object, unknown>, TItem, TOut, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: MappedChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline, TItem> & {
186
+ skip?: never;
187
+ mapResult(value: PipelineResultOf<TChildPipeline>, result: PipelineRun<PipelineResultOf<TChildPipeline>>, item: TItem, index: number, context: PipelineStepContext<TOptions>): TOut;
188
+ }): Step<TId, readonly TOut[], TOptions, TInputOptions>;
189
+ <TId extends string, TChildPipeline extends Pipeline<object, unknown>, TItem, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: MappedChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline, TItem> & {
190
+ skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, readonly PipelineResultOf<TChildPipeline>[]> | undefined;
191
+ mapResult?: undefined;
192
+ }): Step<TId, readonly PipelineResultOf<TChildPipeline>[] | undefined, TOptions, TInputOptions>;
193
+ <TId extends string, TChildPipeline extends Pipeline<object, unknown>, TItem, TOut, const TDeps extends readonly AnyStep<TOptions>[] = [], const TOptionalDeps extends readonly AnyStep<TOptions>[] = []>(id: TId, definition: MappedChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline, TItem> & {
194
+ skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, NoInfer<readonly TOut[]>> | undefined;
195
+ mapResult(value: PipelineResultOf<TChildPipeline>, result: PipelineRun<PipelineResultOf<TChildPipeline>>, item: TItem, index: number, context: PipelineStepContext<TOptions>): TOut;
196
+ }): Step<TId, readonly TOut[] | undefined, TOptions, TInputOptions>;
197
+ };
198
+ };
215
199
  export {};
@@ -1,24 +1,21 @@
1
- import { createMappedChildRunner, createSingleChildRunner, } from "./child-execution.js";
1
+ import { createMappedChildRunner, createSingleChildRunner } from "./child-execution.js";
2
2
  import { isPipelineCancellation, PipelineExecutionError } from "./pipeline-execute.js";
3
3
  import { STEP_NESTED_PIPELINE, STEP_OPTIONS_SCHEMA, STEP_REMOTE, } from "./pipeline-step-metadata.js";
4
4
  export function createSteps(optionsSchema) {
5
5
  return createStepFactory(optionsSchema);
6
6
  }
7
7
  function createStepFactory(optionsSchema) {
8
- // Runtime construction is deliberately simple; the public factory owns the
9
- // distinction between ordinary and explicitly skippable constructors.
10
8
  const buildStep = (id, definition) => {
11
- // SAFETY: `definition` carries the step's own fields; spreading it onto the
12
- // id-bearing shell yields a value whose shape matches `AnyStep<TOptions>`.
13
9
  const built = { id, ...definition };
14
10
  if (optionsSchema) {
15
11
  Object.defineProperty(built, STEP_OPTIONS_SCHEMA, { value: optionsSchema });
16
12
  }
17
13
  return built;
18
14
  };
19
- // SAFETY: the closure's parameter and return shapes match the
20
- // `fromPipeline` constructor signature it is assigned to.
21
- const fromPipeline = ((id, config) => {
15
+ function step(id, definition) {
16
+ return buildStep(id, definition);
17
+ }
18
+ const buildPipelineStep = (id, config) => {
22
19
  const definition = {
23
20
  [STEP_NESTED_PIPELINE]: {
24
21
  mode: "single",
@@ -31,9 +28,6 @@ function createStepFactory(optionsSchema) {
31
28
  name: config.name,
32
29
  description: config.description,
33
30
  dryRun: config.dryRun,
34
- // SAFETY: the config carries `pipeline` and `mapResult`; the runner
35
- // derives `mapOptions` from the same fields, so the config is a valid
36
- // single-child execution config at runtime.
37
31
  run: createSingleChildRunner(config, {
38
32
  createExecutionError: (result, message) => new PipelineExecutionError(result, message),
39
33
  isCancellation: (error, childContext) => isPipelineCancellation(error, childContext),
@@ -41,14 +35,14 @@ function createStepFactory(optionsSchema) {
41
35
  };
42
36
  const skip = config.skip;
43
37
  if (skip !== undefined) {
44
- // SAFETY: each constructor preserves the skip predicate's dependency inputs and context.
45
- definition.skip = (inputs, context) => skip(inputs, context);
38
+ definition.skip = skip;
46
39
  }
47
40
  return buildStep(id, definition);
48
- });
49
- // SAFETY: the closure's parameter and return shapes match the
50
- // `fromRemote` constructor signature it is assigned to.
51
- const fromRemote = ((id, config) => {
41
+ };
42
+ function fromPipeline(id, definition) {
43
+ return buildPipelineStep(id, definition);
44
+ }
45
+ const buildRemoteStep = (id, config) => {
52
46
  const remote = { engine: config.adapter.engine };
53
47
  if (config.adapter.target !== undefined)
54
48
  remote.target = config.adapter.target;
@@ -65,14 +59,14 @@ function createStepFactory(optionsSchema) {
65
59
  };
66
60
  const skip = config.skip;
67
61
  if (skip !== undefined) {
68
- // SAFETY: each constructor preserves the skip predicate's dependency inputs and context.
69
- definition.skip = (inputs, context) => skip(inputs, context);
62
+ definition.skip = skip;
70
63
  }
71
64
  return buildStep(id, definition);
72
- });
73
- // SAFETY: the closure's parameter and return shapes match the
74
- // `forEachPipeline` constructor signature it is assigned to.
75
- const forEachPipeline = ((id, config) => {
65
+ };
66
+ function fromRemote(id, definition) {
67
+ return buildRemoteStep(id, definition);
68
+ }
69
+ const buildMappedPipelineStep = (id, config) => {
76
70
  const definition = {
77
71
  [STEP_NESTED_PIPELINE]: {
78
72
  mode: "for-each",
@@ -85,9 +79,6 @@ function createStepFactory(optionsSchema) {
85
79
  name: config.name,
86
80
  description: config.description,
87
81
  dryRun: config.dryRun,
88
- // SAFETY: the config carries `pipeline`, `items`, `key`, and `mapResult`;
89
- // the runner derives the rest from those fields, so the config is a valid
90
- // mapped-child execution config at runtime.
91
82
  run: createMappedChildRunner(config, {
92
83
  createExecutionError: (result, message) => new PipelineExecutionError(result, message),
93
84
  isCancellation: (error, childContext) => isPipelineCancellation(error, childContext),
@@ -95,29 +86,19 @@ function createStepFactory(optionsSchema) {
95
86
  };
96
87
  const skip = config.skip;
97
88
  if (skip !== undefined) {
98
- // SAFETY: each constructor preserves the skip predicate's dependency inputs and context.
99
- definition.skip = (inputs, context) => skip(inputs, context);
89
+ definition.skip = skip;
100
90
  }
101
91
  return buildStep(id, definition);
102
- });
103
- // SAFETY: `buildStep` is a callable; attaching the constructor properties
104
- // yields exactly the `StepFactory` surface (call + skippable + fromPipeline +
105
- // forEachPipeline), so the single assertion is sound.
106
- const factory = Object.assign(buildStep, {
107
- skippable: buildStep,
92
+ };
93
+ function forEachPipeline(id, definition) {
94
+ return buildMappedPipelineStep(id, definition);
95
+ }
96
+ const factory = {
97
+ step,
108
98
  fromPipeline,
109
99
  fromRemote,
110
100
  forEachPipeline,
111
- });
112
- // SAFETY: `fromPipeline` is the same callable as `factory.fromPipeline`; it
113
- // carries the skippable variant, so the assignment is sound.
114
- factory.fromPipeline.skippable = fromPipeline;
115
- // SAFETY: `fromRemote` is the same callable as `factory.fromRemote`; it
116
- // carries the skippable variant, so the assignment is sound.
117
- factory.fromRemote.skippable = fromRemote;
118
- // SAFETY: `forEachPipeline` is the same callable as `factory.forEachPipeline`;
119
- // it carries the skippable variant, so the assignment is sound.
120
- factory.forEachPipeline.skippable = forEachPipeline;
101
+ };
121
102
  return factory;
122
103
  }
123
104
  //# sourceMappingURL=pipeline-steps.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline-steps.js","sourceRoot":"","sources":["../../src/core/pipeline-steps.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createMappedChildRunner,\n createSingleChildRunner,\n type MappedChildExecutionConfig,\n type SingleChildExecutionConfig,\n} from \"./child-execution.js\";\nimport type { ToMappedChildStepProgressOptions } from \"./mapped-child-progress.js\";\nimport { isPipelineCancellation, PipelineExecutionError } from \"./pipeline-execute.js\";\nimport {\n STEP_NESTED_PIPELINE,\n STEP_OPTIONS_SCHEMA,\n STEP_REMOTE,\n} from \"./pipeline-step-metadata.js\";\nimport type {\n InferSchemaInput,\n InferSchemaOutput,\n Pipeline,\n PipelineExecutionContext,\n PipelinePlanStep,\n PipelineRun,\n PipelineRunOptions,\n PipelineStepContext,\n RemoteStepAdapter,\n StandardSchemaV1,\n StepSkipDecision,\n} from \"./pipeline-types.js\";\n\n/**\n * A step's dependencies are references to the dependency's own step object, not string ids\n * into a hand-maintained output-type map. This buys two things no amount of extra generics\n * on a string-keyed design could:\n * - a step used before its dependency exists is a compile error (JS temporal dead zone on\n * `const`), so out-of-order and self/cyclic dependencies are caught by the language, not\n * a bespoke runtime check\n * - each step only ever states its own id/deps; the output-type map is derived, never\n * restated, and callers of `definePipeline`/`createSteps` never write out its generics\n */\ntype AnyStepDryRunHandler<TOptions extends object> = {\n bivarianceHack(\n inputs: Record<string, unknown>,\n context: PipelineStepContext<TOptions>\n ): unknown | Promise<unknown>;\n}[\"bivarianceHack\"];\n\nexport interface AnyStep<TOptions extends object = object> {\n readonly [STEP_NESTED_PIPELINE]?: NonNullable<PipelinePlanStep[\"nestedPipeline\"]>;\n readonly [STEP_REMOTE]?: NonNullable<PipelinePlanStep[\"remote\"]>;\n readonly [STEP_OPTIONS_SCHEMA]?: StandardSchemaV1;\n readonly id: string;\n readonly dependsOn?: readonly AnyStep<TOptions>[];\n readonly optionalDependsOn?: readonly AnyStep<TOptions>[];\n readonly skipAfterFailureOf?: readonly AnyStep<TOptions>[];\n /** Optional human-facing display name. Stable machine identity remains `id`. */\n readonly name?: string;\n readonly description?: string;\n /**\n * Dry-run policy. Omitted runs the normal handler, `\"skip\"` structurally\n * skips it, and a handler substitutes for `run` while preserving its output.\n */\n readonly dryRun?: \"skip\" | AnyStepDryRunHandler<TOptions>;\n /** Optional Standard Schema for values published by this step. */\n readonly outputSchema?: StandardSchemaV1;\n /**\n * Optional runtime skip. Return a non-empty reason (or `{ reason, value }`) to\n * skip without calling `run`. Policy skips unlock dependents; structural skips\n * (dry-run, filtered, …) do not use this hook.\n */\n skip?(\n inputs: Record<string, unknown>,\n context: PipelineExecutionContext<TOptions>\n ): StepSkipDecision | Promise<StepSkipDecision>;\n run(inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>): unknown;\n}\n\n/** The step fields that `buildStep` merges onto the id-bearing shell. */\ntype StepDefinitionBody<TOptions extends object> = Omit<AnyStep<TOptions>, \"id\">;\n\nexport interface Step<\n TId extends string,\n TOut,\n TOptions extends object,\n TInputOptions extends object = TOptions,\n TRunOut = TOut,\n> extends AnyStep<TOptions> {\n readonly id: TId;\n run(\n inputs: Record<string, unknown>,\n context: PipelineStepContext<TOptions>\n ): TRunOut | Promise<TRunOut>;\n /** Type-only: carries this step's output type for sibling inference. Never set at runtime. */\n readonly __outputType?: TOut;\n /** Type-only: carries pre-validation run options for pipeline call-site inference. */\n readonly __inputOptionsType?: TInputOptions;\n}\n\n/**\n * Extract a step's output type for dependency typing.\n * Prefer matching `Step<…, TOut, …>` over `{ __outputType?: infer T }`: optional-property\n * inference collapses `TOut | undefined` to `TOut`, which hides policy-skip widening.\n */\nexport type StepOutput<S> =\n S extends Step<string, infer TOut, infer _TOptions, infer _TInputOptions, infer _TRunOut>\n ? TOut\n : never;\n\ninterface StepToken {\n readonly id: string;\n readonly __outputType?: unknown;\n}\n\ntype RequiredInputs<TDeps extends readonly StepToken[]> = {\n [S in TDeps[number] as S[\"id\"]]: StepOutput<S>;\n};\n\ntype OptionalInputs<TDeps extends readonly StepToken[]> = {\n [S in TDeps[number] as S[\"id\"]]?: StepOutput<S>;\n};\n\ntype PipelineResultOf<TPipeline> =\n TPipeline extends Pipeline<object, infer TResult, infer _TStepId, infer _TTargetId>\n ? TResult\n : never;\n\ntype PipelineRunOptionsOf<TPipeline> =\n TPipeline extends Pipeline<infer TOptions, unknown, infer TStepId, infer TTargetId>\n ? PipelineRunOptions<TOptions, TStepId, TTargetId>\n : never;\n\ntype ChildPipelineStepDefinitionBase<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TChildPipeline extends Pipeline<object, unknown>,\n> = {\n pipeline: TChildPipeline;\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];\n name?: string;\n description?: string;\n dryRun?: \"skip\";\n mapOptions(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): PipelineRunOptionsOf<TChildPipeline>;\n};\n\n/** Child step without policy skip (dependents see the full child result type). */\ntype ChildPipelineStepDefinition<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TChildPipeline extends Pipeline<object, unknown>,\n> = ChildPipelineStepDefinitionBase<TParentOptions, TDeps, TOptionalDeps, TChildPipeline>;\n\n/**\n * Presentation options for opaque `forEachPipeline` progress.\n * Defaults are domain-neutral (`N/M items · K running · key/step`).\n * Override `formatMessage` when a domain wants its own noun (images, shards, …).\n */\nexport type MappedChildProgressOptions = ToMappedChildStepProgressOptions;\n\ntype MappedChildPipelineStepDefinition<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n> = {\n pipeline: TChildPipeline;\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];\n name?: string;\n description?: string;\n dryRun?: \"skip\";\n items(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): readonly TItem[] | Promise<readonly TItem[]>;\n key(item: TItem, index: number): string;\n concurrency?:\n | number\n | ((\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ) => number);\n /**\n * How the opaque parent step reports live fan-out progress.\n * Purely presentational — does not change scheduling or results.\n */\n progress?: MappedChildProgressOptions;\n mapOptions(\n item: TItem,\n index: number,\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): PipelineRunOptionsOf<TChildPipeline>;\n};\n\ntype StepSkipPredicate<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TOut,\n> = (\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TOptions>\n) => StepSkipDecision<TOut> | Promise<StepSkipDecision<TOut>>;\n\ntype StepDryRunPolicy<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TOut,\n> =\n | \"skip\"\n | ((\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineStepContext<TOptions>\n ) => TOut | Promise<TOut>);\n\ntype PlainStepFields<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TOut,\n> = {\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TOptions>[];\n name?: string;\n description?: string;\n dryRun?: StepDryRunPolicy<TOptions, TDeps, TOptionalDeps, TOut>;\n outputSchema?: never;\n run(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineStepContext<TOptions>\n ): TOut | Promise<TOut>;\n};\n\ntype SchemaStepFields<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TSchema extends StandardSchemaV1,\n> = Omit<\n PlainStepFields<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>,\n \"outputSchema\"\n> & {\n outputSchema: TSchema;\n};\n\ninterface StepConstructor<TOptions extends object, TInputOptions extends object = TOptions> {\n /** Ordinary steps never policy-skip, so dependents receive their full output. */\n <\n TId extends string,\n TSchema extends StandardSchemaV1,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: SchemaStepFields<TOptions, TDeps, TOptionalDeps, TSchema> & { skip?: never }\n ): Step<TId, InferSchemaOutput<TSchema>, TOptions, TInputOptions, InferSchemaInput<TSchema>>;\n\n <\n TId extends string,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n TOut = unknown,\n >(\n id: TId,\n definition: PlainStepFields<TOptions, TDeps, TOptionalDeps, TOut> & { skip?: never }\n ): Step<TId, TOut, TOptions, TInputOptions>;\n\n /** Explicit policy-skip constructor; dependents receive `TOut | undefined`. */\n skippable: SkippableStepConstructor<TOptions, TInputOptions>;\n}\n\ninterface SkippableStepConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TSchema extends StandardSchemaV1,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: SchemaStepFields<TOptions, TDeps, TOptionalDeps, TSchema> & {\n skip:\n | StepSkipPredicate<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>\n | undefined;\n }\n ): Step<\n TId,\n InferSchemaOutput<TSchema> | undefined,\n TOptions,\n TInputOptions,\n InferSchemaInput<TSchema>\n >;\n\n <\n TId extends string,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n TOut = unknown,\n >(\n id: TId,\n definition: PlainStepFields<TOptions, TDeps, TOptionalDeps, TOut> & {\n skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, TOut> | undefined;\n }\n ): Step<TId, TOut | undefined, TOptions, TInputOptions>;\n}\n\ninterface FromPipelineConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip?: never;\n mapResult?: undefined;\n }\n ): Step<TId, PipelineResultOf<TChildPipeline>, TOptions, TInputOptions>;\n\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip?: never;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, Awaited<TOut>, TOptions, TInputOptions>;\n\n skippable: SkippableFromPipelineConstructor<TOptions, TInputOptions>;\n}\n\ninterface SkippableFromPipelineConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip:\n | StepSkipPredicate<TOptions, TDeps, TOptionalDeps, PipelineResultOf<TChildPipeline>>\n | undefined;\n mapResult?: undefined;\n }\n ): Step<TId, PipelineResultOf<TChildPipeline> | undefined, TOptions, TInputOptions>;\n\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, NoInfer<Awaited<TOut>>> | undefined;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, Awaited<TOut> | undefined, TOptions, TInputOptions>;\n}\n\ninterface ForEachPipelineConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip?: never;\n mapResult?: undefined;\n }\n ): Step<TId, readonly PipelineResultOf<TChildPipeline>[], TOptions, TInputOptions>;\n\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip?: never;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n item: TItem,\n index: number,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, readonly TOut[], TOptions, TInputOptions>;\n\n skippable: SkippableForEachPipelineConstructor<TOptions, TInputOptions>;\n}\n\ninterface SkippableForEachPipelineConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip:\n | StepSkipPredicate<\n TOptions,\n TDeps,\n TOptionalDeps,\n readonly PipelineResultOf<TChildPipeline>[]\n >\n | undefined;\n mapResult?: undefined;\n }\n ): Step<TId, readonly PipelineResultOf<TChildPipeline>[] | undefined, TOptions, TInputOptions>;\n\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, NoInfer<readonly TOut[]>> | undefined;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n item: TItem,\n index: number,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, readonly TOut[] | undefined, TOptions, TInputOptions>;\n}\n\ntype RemoteStepDefinitionBase<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TPayload,\n TSchema extends StandardSchemaV1,\n> = {\n adapter: RemoteStepAdapter<TParentOptions, TPayload, InferSchemaInput<TSchema>>;\n mapInput(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineStepContext<TParentOptions>\n ): TPayload;\n outputSchema: TSchema;\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];\n name?: string;\n description?: string;\n dryRun?: StepDryRunPolicy<TParentOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>;\n};\n\ninterface FromRemoteConstructor<TOptions extends object, TInputOptions extends object = TOptions> {\n <\n TId extends string,\n TSchema extends StandardSchemaV1,\n TPayload,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: RemoteStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TPayload, TSchema> & {\n skip?: never;\n }\n ): Step<TId, InferSchemaOutput<TSchema>, TOptions, TInputOptions, InferSchemaInput<TSchema>>;\n\n skippable: SkippableFromRemoteConstructor<TOptions, TInputOptions>;\n}\n\ninterface SkippableFromRemoteConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TSchema extends StandardSchemaV1,\n TPayload,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: RemoteStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TPayload, TSchema> & {\n skip:\n | StepSkipPredicate<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>\n | undefined;\n }\n ): Step<\n TId,\n InferSchemaOutput<TSchema> | undefined,\n TOptions,\n TInputOptions,\n InferSchemaInput<TSchema>\n >;\n}\n\nexport interface StepFactory<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> extends StepConstructor<TOptions, TInputOptions> {\n fromPipeline: FromPipelineConstructor<TOptions, TInputOptions>;\n fromRemote: FromRemoteConstructor<TOptions, TInputOptions>;\n forEachPipeline: ForEachPipelineConstructor<TOptions, TInputOptions>;\n}\n\n/**\n * Returns a step factory scoped to one pipeline's domain options. Pass built-in\n * run controls as the second argument to `run` / `runOrThrow`. Child\n * `mapOptions` may still return domain options plus those controls.\n */\nexport function createSteps<TOptions extends object = {}>(): StepFactory<TOptions>;\nexport function createSteps<const TSchema extends StandardSchemaV1<object, object>>(\n optionsSchema: TSchema\n): StepFactory<InferSchemaOutput<TSchema>, InferSchemaInput<TSchema>>;\nexport function createSteps(optionsSchema?: StandardSchemaV1<object, object>): StepFactory<object> {\n return createStepFactory<object>(optionsSchema);\n}\n\nfunction createStepFactory<TOptions extends object, TInputOptions extends object = TOptions>(\n optionsSchema?: StandardSchemaV1\n): StepFactory<TOptions, TInputOptions> {\n // Runtime construction is deliberately simple; the public factory owns the\n // distinction between ordinary and explicitly skippable constructors.\n const buildStep = (id: string, definition: StepDefinitionBody<TOptions>): AnyStep<TOptions> => {\n // SAFETY: `definition` carries the step's own fields; spreading it onto the\n // id-bearing shell yields a value whose shape matches `AnyStep<TOptions>`.\n const built = { id, ...definition } as AnyStep<TOptions>;\n if (optionsSchema) {\n Object.defineProperty(built, STEP_OPTIONS_SCHEMA, { value: optionsSchema });\n }\n return built;\n };\n\n // SAFETY: the closure's parameter and return shapes match the\n // `fromPipeline` constructor signature it is assigned to.\n const fromPipeline = ((\n id: string,\n config: ChildPipelineStepDefinitionBase<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n Pipeline<object, unknown>\n > & {\n skip?: StepSkipPredicate<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n unknown\n >;\n mapResult?: (\n value: unknown,\n result: PipelineRun<unknown>,\n context: PipelineStepContext<TOptions>\n ) => unknown;\n }\n ) => {\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_NESTED_PIPELINE]: {\n mode: \"single\" as const,\n pipelineId: config.pipeline.id,\n stepIds: config.pipeline.stepIds,\n },\n dependsOn: config.dependsOn,\n optionalDependsOn: config.optionalDependsOn,\n skipAfterFailureOf: config.skipAfterFailureOf,\n name: config.name,\n description: config.description,\n dryRun: config.dryRun,\n // SAFETY: the config carries `pipeline` and `mapResult`; the runner\n // derives `mapOptions` from the same fields, so the config is a valid\n // single-child execution config at runtime.\n run: createSingleChildRunner(config as SingleChildExecutionConfig<TOptions>, {\n createExecutionError: (result, message) => new PipelineExecutionError(result, message),\n isCancellation: (error, childContext) => isPipelineCancellation(error, childContext),\n }),\n };\n\n const skip = config.skip;\n if (skip !== undefined) {\n // SAFETY: each constructor preserves the skip predicate's dependency inputs and context.\n definition.skip = (inputs, context) => skip(inputs as never, context);\n }\n return buildStep(id, definition);\n }) as StepFactory<TOptions, TInputOptions>[\"fromPipeline\"];\n\n // SAFETY: the closure's parameter and return shapes match the\n // `fromRemote` constructor signature it is assigned to.\n const fromRemote = ((\n id: string,\n config: {\n adapter: RemoteStepAdapter<object, unknown, unknown>;\n mapInput: (\n inputs: Record<string, unknown>,\n context: PipelineStepContext<TOptions>\n ) => unknown;\n outputSchema: StandardSchemaV1;\n dependsOn?: readonly AnyStep<TOptions>[];\n optionalDependsOn?: readonly AnyStep<TOptions>[];\n skipAfterFailureOf?: readonly AnyStep<TOptions>[];\n name?: string;\n description?: string;\n dryRun?: \"skip\" | AnyStepDryRunHandler<TOptions>;\n skip?: StepSkipPredicate<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n unknown\n >;\n }\n ) => {\n const remote: NonNullable<PipelinePlanStep[\"remote\"]> = { engine: config.adapter.engine };\n if (config.adapter.target !== undefined) remote.target = config.adapter.target;\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_REMOTE]: remote,\n dependsOn: config.dependsOn,\n optionalDependsOn: config.optionalDependsOn,\n skipAfterFailureOf: config.skipAfterFailureOf,\n name: config.name,\n description: config.description,\n dryRun: config.dryRun,\n outputSchema: config.outputSchema,\n run: (inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>) =>\n config.adapter.invoke(config.mapInput(inputs, context), context),\n };\n const skip = config.skip;\n if (skip !== undefined) {\n // SAFETY: each constructor preserves the skip predicate's dependency inputs and context.\n definition.skip = (inputs, context) => skip(inputs as never, context);\n }\n return buildStep(id, definition);\n }) as StepFactory<TOptions, TInputOptions>[\"fromRemote\"];\n\n // SAFETY: the closure's parameter and return shapes match the\n // `forEachPipeline` constructor signature it is assigned to.\n const forEachPipeline = ((\n id: string,\n config: MappedChildPipelineStepDefinition<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n Pipeline<object, unknown>,\n unknown\n > & {\n mapResult?: (\n value: unknown,\n result: PipelineRun<unknown>,\n item: unknown,\n index: number,\n context: PipelineStepContext<TOptions>\n ) => unknown;\n skip?: StepSkipPredicate<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n unknown\n >;\n }\n ) => {\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_NESTED_PIPELINE]: {\n mode: \"for-each\" as const,\n pipelineId: config.pipeline.id,\n stepIds: config.pipeline.stepIds,\n },\n dependsOn: config.dependsOn,\n optionalDependsOn: config.optionalDependsOn,\n skipAfterFailureOf: config.skipAfterFailureOf,\n name: config.name,\n description: config.description,\n dryRun: config.dryRun,\n // SAFETY: the config carries `pipeline`, `items`, `key`, and `mapResult`;\n // the runner derives the rest from those fields, so the config is a valid\n // mapped-child execution config at runtime.\n run: createMappedChildRunner(config as MappedChildExecutionConfig<TOptions>, {\n createExecutionError: (result, message) => new PipelineExecutionError(result, message),\n isCancellation: (error, childContext) => isPipelineCancellation(error, childContext),\n }),\n };\n\n const skip = config.skip;\n if (skip !== undefined) {\n // SAFETY: each constructor preserves the skip predicate's dependency inputs and context.\n definition.skip = (inputs, context) => skip(inputs as never, context);\n }\n return buildStep(id, definition);\n }) as StepFactory<TOptions, TInputOptions>[\"forEachPipeline\"];\n\n // SAFETY: `buildStep` is a callable; attaching the constructor properties\n // yields exactly the `StepFactory` surface (call + skippable + fromPipeline +\n // forEachPipeline), so the single assertion is sound.\n const factory = Object.assign(buildStep, {\n skippable: buildStep,\n fromPipeline,\n fromRemote,\n forEachPipeline,\n }) as StepFactory<TOptions, TInputOptions>;\n // SAFETY: `fromPipeline` is the same callable as `factory.fromPipeline`; it\n // carries the skippable variant, so the assignment is sound.\n factory.fromPipeline.skippable = fromPipeline as StepFactory<\n TOptions,\n TInputOptions\n >[\"fromPipeline\"][\"skippable\"];\n // SAFETY: `fromRemote` is the same callable as `factory.fromRemote`; it\n // carries the skippable variant, so the assignment is sound.\n factory.fromRemote.skippable = fromRemote as StepFactory<\n TOptions,\n TInputOptions\n >[\"fromRemote\"][\"skippable\"];\n // SAFETY: `forEachPipeline` is the same callable as `factory.forEachPipeline`;\n // it carries the skippable variant, so the assignment is sound.\n factory.forEachPipeline.skippable = forEachPipeline as StepFactory<\n TOptions,\n TInputOptions\n >[\"forEachPipeline\"][\"skippable\"];\n\n return factory;\n}\n"]}
1
+ {"version":3,"file":"pipeline-steps.js","sourceRoot":"","sources":["../../src/core/pipeline-steps.ts"],"names":[],"mappings":"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","sourcesContent":["import { createMappedChildRunner, createSingleChildRunner } from \"./child-execution.js\";\nimport type { ToMappedChildStepProgressOptions } from \"./mapped-child-progress.js\";\nimport { isPipelineCancellation, PipelineExecutionError } from \"./pipeline-execute.js\";\nimport {\n STEP_NESTED_PIPELINE,\n STEP_OPTIONS_SCHEMA,\n STEP_REMOTE,\n} from \"./pipeline-step-metadata.js\";\nimport type {\n InferSchemaInput,\n InferSchemaOutput,\n Pipeline,\n PipelineExecutionContext,\n PipelinePlanStep,\n PipelineRun,\n PipelineRunOptions,\n PipelineStepContext,\n RemoteStepAdapter,\n StandardSchemaV1,\n StepSkipDecision,\n} from \"./pipeline-types.js\";\n\n/**\n * A step's dependencies are references to the dependency's own step object, not string ids\n * into a hand-maintained output-type map. This buys two things no amount of extra generics\n * on a string-keyed design could:\n * - a step used before its dependency exists is a compile error (JS temporal dead zone on\n * `const`), so out-of-order and self/cyclic dependencies are caught by the language, not\n * a bespoke runtime check\n * - each step only ever states its own id/deps; the output-type map is derived, never\n * restated, and callers of `definePipeline`/`createSteps` never write out its generics\n */\ntype AnyStepDryRunHandler<TOptions extends object> = {\n bivarianceHack(\n inputs: Record<string, unknown>,\n context: PipelineStepContext<TOptions>\n ): unknown | Promise<unknown>;\n}[\"bivarianceHack\"];\n\nexport interface AnyStep<TOptions extends object = object> {\n readonly [STEP_NESTED_PIPELINE]?: NonNullable<PipelinePlanStep[\"nestedPipeline\"]>;\n readonly [STEP_REMOTE]?: NonNullable<PipelinePlanStep[\"remote\"]>;\n readonly [STEP_OPTIONS_SCHEMA]?: StandardSchemaV1;\n readonly id: string;\n readonly dependsOn?: readonly AnyStep<TOptions>[];\n readonly optionalDependsOn?: readonly AnyStep<TOptions>[];\n readonly skipAfterFailureOf?: readonly AnyStep<TOptions>[];\n /** Optional human-facing display name. Stable machine identity remains `id`. */\n readonly name?: string;\n readonly description?: string;\n /**\n * Dry-run policy. Omitted runs the normal handler, `\"skip\"` structurally\n * skips it, and a handler substitutes for `run` while preserving its output.\n */\n readonly dryRun?: \"skip\" | AnyStepDryRunHandler<TOptions>;\n /** Optional Standard Schema for values published by this step. */\n readonly outputSchema?: StandardSchemaV1;\n /**\n * Optional runtime skip. Return a non-empty reason (or `{ reason, value }`) to\n * skip without calling `run`. Policy skips unlock dependents; structural skips\n * (dry-run, filtered, …) do not use this hook.\n */\n skip?(\n inputs: Record<string, unknown>,\n context: PipelineExecutionContext<TOptions>\n ): StepSkipDecision | Promise<StepSkipDecision>;\n run(inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>): unknown;\n}\n\n/** The step fields that `buildStep` merges onto the id-bearing shell. */\ntype StepDefinitionBody<TOptions extends object> = Omit<AnyStep<TOptions>, \"id\">;\n\nexport interface Step<\n TId extends string,\n TOut,\n TOptions extends object,\n TInputOptions extends object = TOptions,\n TRunOut = TOut,\n> extends AnyStep<TOptions> {\n readonly id: TId;\n run(\n inputs: Record<string, unknown>,\n context: PipelineStepContext<TOptions>\n ): TRunOut | Promise<TRunOut>;\n /** Type-only: carries this step's output type for sibling inference. Never set at runtime. */\n readonly __outputType?: TOut;\n /** Type-only: carries pre-validation run options for pipeline call-site inference. */\n readonly __inputOptionsType?: TInputOptions;\n}\n\n/**\n * Extract a step's output type for dependency typing.\n * Prefer matching `Step<…, TOut, …>` over `{ __outputType?: infer T }`: optional-property\n * inference collapses `TOut | undefined` to `TOut`, which hides policy-skip widening.\n */\nexport type StepOutput<S> =\n S extends Step<string, infer TOut, infer _TOptions, infer _TInputOptions, infer _TRunOut>\n ? TOut\n : never;\n\ninterface StepToken {\n readonly id: string;\n readonly __outputType?: unknown;\n}\n\ntype RequiredInputs<TDeps extends readonly StepToken[]> = {\n [S in TDeps[number] as S[\"id\"]]: StepOutput<S>;\n};\n\ntype OptionalInputs<TDeps extends readonly StepToken[]> = {\n [S in TDeps[number] as S[\"id\"]]?: StepOutput<S>;\n};\n\ntype PipelineResultOf<TPipeline> =\n TPipeline extends Pipeline<object, infer TResult, infer _TStepId, infer _TTargetId>\n ? TResult\n : never;\n\ntype PipelineRunOptionsOf<TPipeline> =\n TPipeline extends Pipeline<infer TOptions, unknown, infer TStepId, infer TTargetId>\n ? PipelineRunOptions<TOptions, TStepId, TTargetId>\n : never;\n\ntype ChildPipelineStepDefinitionBase<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TChildPipeline extends Pipeline<object, unknown>,\n> = {\n pipeline: TChildPipeline;\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];\n name?: string;\n description?: string;\n dryRun?: \"skip\";\n mapOptions(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): PipelineRunOptionsOf<TChildPipeline>;\n};\n\n/** Child step without policy skip (dependents see the full child result type). */\ntype ChildPipelineStepDefinition<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TChildPipeline extends Pipeline<object, unknown>,\n> = ChildPipelineStepDefinitionBase<TParentOptions, TDeps, TOptionalDeps, TChildPipeline>;\n\n/**\n * Presentation options for opaque `forEachPipeline` progress.\n * Defaults are domain-neutral (`N/M items · K running · key/step`).\n * Override `formatMessage` when a domain wants its own noun (images, shards, …).\n */\nexport type MappedChildProgressOptions = ToMappedChildStepProgressOptions;\n\ntype MappedChildPipelineStepDefinition<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n> = {\n pipeline: TChildPipeline;\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];\n name?: string;\n description?: string;\n dryRun?: \"skip\";\n items(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): readonly TItem[] | Promise<readonly TItem[]>;\n key(item: TItem, index: number): string;\n concurrency?:\n | number\n | ((\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ) => number);\n /**\n * How the opaque parent step reports live fan-out progress.\n * Purely presentational — does not change scheduling or results.\n */\n progress?: MappedChildProgressOptions;\n mapOptions(\n item: TItem,\n index: number,\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): PipelineRunOptionsOf<TChildPipeline>;\n};\n\ntype StepSkipPredicate<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TOut,\n> = (\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TOptions>\n) => StepSkipDecision<TOut> | Promise<StepSkipDecision<TOut>>;\n\ntype StepDryRunPolicy<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TOut,\n> =\n | \"skip\"\n | ((\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineStepContext<TOptions>\n ) => TOut | Promise<TOut>);\n\ntype PlainStepFields<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TOut,\n> = {\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TOptions>[];\n name?: string;\n description?: string;\n dryRun?: StepDryRunPolicy<TOptions, TDeps, TOptionalDeps, TOut>;\n outputSchema?: never;\n run(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineStepContext<TOptions>\n ): TOut | Promise<TOut>;\n};\n\ntype SchemaStepFields<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TSchema extends StandardSchemaV1,\n> = Omit<\n PlainStepFields<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>,\n \"outputSchema\"\n> & {\n outputSchema: TSchema;\n};\n\ntype RemoteStepDefinitionBase<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TPayload,\n TSchema extends StandardSchemaV1,\n> = {\n adapter: RemoteStepAdapter<TParentOptions, TPayload, InferSchemaInput<TSchema>>;\n mapInput(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineStepContext<TParentOptions>\n ): TPayload;\n outputSchema: TSchema;\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];\n name?: string;\n description?: string;\n dryRun?: StepDryRunPolicy<TParentOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>;\n};\n\nexport type StepFactory<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> = ReturnType<typeof createStepFactory<TOptions, TInputOptions>>;\n\n/**\n * Returns a step factory scoped to one pipeline's domain options. Pass built-in\n * run controls as the second argument to `run` / `runOrThrow`. Child\n * `mapOptions` may still return domain options plus those controls.\n */\nexport function createSteps<TOptions extends object = {}>(): StepFactory<TOptions>;\nexport function createSteps<const TSchema extends StandardSchemaV1<object, object>>(\n optionsSchema: TSchema\n): StepFactory<InferSchemaOutput<TSchema>, InferSchemaInput<TSchema>>;\nexport function createSteps(optionsSchema?: StandardSchemaV1<object, object>): StepFactory<object> {\n return createStepFactory<object>(optionsSchema);\n}\n\nfunction createStepFactory<TOptions extends object, TInputOptions extends object = TOptions>(\n optionsSchema?: StandardSchemaV1\n) {\n const buildStep = (id: string, definition: StepDefinitionBody<TOptions>): AnyStep<TOptions> => {\n const built: AnyStep<TOptions> = { id, ...definition };\n if (optionsSchema) {\n Object.defineProperty(built, STEP_OPTIONS_SCHEMA, { value: optionsSchema });\n }\n return built;\n };\n\n function step<\n TId extends string,\n TSchema extends StandardSchemaV1,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: SchemaStepFields<TOptions, TDeps, TOptionalDeps, TSchema> & {\n skip:\n | StepSkipPredicate<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>\n | undefined;\n }\n ): Step<\n TId,\n InferSchemaOutput<TSchema> | undefined,\n TOptions,\n TInputOptions,\n InferSchemaInput<TSchema>\n >;\n function step<\n TId extends string,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n TOut = unknown,\n >(\n id: TId,\n definition: PlainStepFields<TOptions, TDeps, TOptionalDeps, TOut> & {\n skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, TOut> | undefined;\n }\n ): Step<TId, TOut | undefined, TOptions, TInputOptions>;\n function step<\n TId extends string,\n TSchema extends StandardSchemaV1,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: SchemaStepFields<TOptions, TDeps, TOptionalDeps, TSchema> & { skip?: never }\n ): Step<TId, InferSchemaOutput<TSchema>, TOptions, TInputOptions, InferSchemaInput<TSchema>>;\n function step<\n TId extends string,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n TOut = unknown,\n >(\n id: TId,\n definition: PlainStepFields<TOptions, TDeps, TOptionalDeps, TOut> & { skip?: never }\n ): Step<TId, TOut, TOptions, TInputOptions>;\n function step(id: string, definition: StepDefinitionBody<TOptions>): AnyStep<TOptions> {\n return buildStep(id, definition);\n }\n\n const buildPipelineStep = (\n id: string,\n config: ChildPipelineStepDefinitionBase<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n Pipeline<object, unknown>\n > & {\n skip?: StepSkipPredicate<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n unknown\n >;\n mapResult?: (\n value: unknown,\n result: PipelineRun<unknown>,\n context: PipelineStepContext<TOptions>\n ) => unknown;\n }\n ) => {\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_NESTED_PIPELINE]: {\n mode: \"single\" as const,\n pipelineId: config.pipeline.id,\n stepIds: config.pipeline.stepIds,\n },\n dependsOn: config.dependsOn,\n optionalDependsOn: config.optionalDependsOn,\n skipAfterFailureOf: config.skipAfterFailureOf,\n name: config.name,\n description: config.description,\n dryRun: config.dryRun,\n run: createSingleChildRunner(config, {\n createExecutionError: (result, message) => new PipelineExecutionError(result, message),\n isCancellation: (error, childContext) => isPipelineCancellation(error, childContext),\n }),\n };\n\n const skip = config.skip;\n if (skip !== undefined) {\n definition.skip = skip;\n }\n return buildStep(id, definition);\n };\n\n function fromPipeline<\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip?: never;\n mapResult?: undefined;\n }\n ): Step<TId, PipelineResultOf<TChildPipeline>, TOptions, TInputOptions>;\n function fromPipeline<\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip?: never;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, Awaited<TOut>, TOptions, TInputOptions>;\n function fromPipeline<\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip:\n | StepSkipPredicate<TOptions, TDeps, TOptionalDeps, PipelineResultOf<TChildPipeline>>\n | undefined;\n mapResult?: undefined;\n }\n ): Step<TId, PipelineResultOf<TChildPipeline> | undefined, TOptions, TInputOptions>;\n function fromPipeline<\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, NoInfer<Awaited<TOut>>> | undefined;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, Awaited<TOut> | undefined, TOptions, TInputOptions>;\n function fromPipeline(\n id: string,\n definition: Parameters<typeof buildPipelineStep>[1]\n ): AnyStep<TOptions> {\n return buildPipelineStep(id, definition);\n }\n\n const buildRemoteStep = (\n id: string,\n config: {\n adapter: RemoteStepAdapter<object, unknown, unknown>;\n mapInput(inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>): unknown;\n outputSchema: StandardSchemaV1;\n dependsOn?: readonly AnyStep<TOptions>[];\n optionalDependsOn?: readonly AnyStep<TOptions>[];\n skipAfterFailureOf?: readonly AnyStep<TOptions>[];\n name?: string;\n description?: string;\n dryRun?: \"skip\" | AnyStepDryRunHandler<TOptions>;\n skip?: StepSkipPredicate<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n unknown\n >;\n }\n ) => {\n const remote: NonNullable<PipelinePlanStep[\"remote\"]> = { engine: config.adapter.engine };\n if (config.adapter.target !== undefined) remote.target = config.adapter.target;\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_REMOTE]: remote,\n dependsOn: config.dependsOn,\n optionalDependsOn: config.optionalDependsOn,\n skipAfterFailureOf: config.skipAfterFailureOf,\n name: config.name,\n description: config.description,\n dryRun: config.dryRun,\n outputSchema: config.outputSchema,\n run: (inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>) =>\n config.adapter.invoke(config.mapInput(inputs, context), context),\n };\n const skip = config.skip;\n if (skip !== undefined) {\n definition.skip = skip;\n }\n return buildStep(id, definition);\n };\n\n function fromRemote<\n TId extends string,\n TSchema extends StandardSchemaV1,\n TPayload,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: RemoteStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TPayload, TSchema> & {\n skip?: never;\n }\n ): Step<TId, InferSchemaOutput<TSchema>, TOptions, TInputOptions, InferSchemaInput<TSchema>>;\n function fromRemote<\n TId extends string,\n TSchema extends StandardSchemaV1,\n TPayload,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: RemoteStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TPayload, TSchema> & {\n skip:\n | StepSkipPredicate<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>\n | undefined;\n }\n ): Step<\n TId,\n InferSchemaOutput<TSchema> | undefined,\n TOptions,\n TInputOptions,\n InferSchemaInput<TSchema>\n >;\n function fromRemote(\n id: string,\n definition: Parameters<typeof buildRemoteStep>[1]\n ): AnyStep<TOptions> {\n return buildRemoteStep(id, definition);\n }\n\n const buildMappedPipelineStep = (\n id: string,\n config: MappedChildPipelineStepDefinition<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n Pipeline<object, unknown>,\n unknown\n > & {\n mapResult?: (\n value: unknown,\n result: PipelineRun<unknown>,\n item: unknown,\n index: number,\n context: PipelineStepContext<TOptions>\n ) => unknown;\n skip?: StepSkipPredicate<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n unknown\n >;\n }\n ) => {\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_NESTED_PIPELINE]: {\n mode: \"for-each\" as const,\n pipelineId: config.pipeline.id,\n stepIds: config.pipeline.stepIds,\n },\n dependsOn: config.dependsOn,\n optionalDependsOn: config.optionalDependsOn,\n skipAfterFailureOf: config.skipAfterFailureOf,\n name: config.name,\n description: config.description,\n dryRun: config.dryRun,\n run: createMappedChildRunner(config, {\n createExecutionError: (result, message) => new PipelineExecutionError(result, message),\n isCancellation: (error, childContext) => isPipelineCancellation(error, childContext),\n }),\n };\n\n const skip = config.skip;\n if (skip !== undefined) {\n definition.skip = skip;\n }\n return buildStep(id, definition);\n };\n\n function forEachPipeline<\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip?: never;\n mapResult?: undefined;\n }\n ): Step<TId, readonly PipelineResultOf<TChildPipeline>[], TOptions, TInputOptions>;\n function forEachPipeline<\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip?: never;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n item: TItem,\n index: number,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, readonly TOut[], TOptions, TInputOptions>;\n function forEachPipeline<\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip:\n | StepSkipPredicate<\n TOptions,\n TDeps,\n TOptionalDeps,\n readonly PipelineResultOf<TChildPipeline>[]\n >\n | undefined;\n mapResult?: undefined;\n }\n ): Step<TId, readonly PipelineResultOf<TChildPipeline>[] | undefined, TOptions, TInputOptions>;\n function forEachPipeline<\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, NoInfer<readonly TOut[]>> | undefined;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n item: TItem,\n index: number,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, readonly TOut[] | undefined, TOptions, TInputOptions>;\n function forEachPipeline(\n id: string,\n definition: Parameters<typeof buildMappedPipelineStep>[1]\n ): AnyStep<TOptions> {\n return buildMappedPipelineStep(id, definition);\n }\n\n const factory = {\n step,\n fromPipeline,\n fromRemote,\n forEachPipeline,\n };\n\n return factory;\n}\n"]}
@@ -1,14 +1,31 @@
1
- import { type Pipeline, type PipelineExecutionContext, type PipelineStepContext, type StandardSchemaV1 } from "../core/pipeline.js";
1
+ import { type MappedChildProgressOptions, type Pipeline, type PipelineExecutionContext, type PipelineRun, type PipelineRunOptions, type PipelineStepContext, type StandardSchemaV1, type StepSkipDecision } from "../core/pipeline.js";
2
2
  import { PipelineDocumentError } from "./project-document.js";
3
3
  export { PipelineDocumentError };
4
- export type { PipelineDocument, PipelineDocumentDefinition, PipelineDocumentStep, } from "./project-document.js";
5
4
  /** Dependency values are checked at runtime rather than inferred from a project document. */
6
- export type PipelineDocumentHandler = (inputs: Record<string, unknown>, context: PipelineStepContext<object>) => unknown;
7
- export type PipelineDocumentFinalizer = (outputs: Record<string, unknown>, context: PipelineExecutionContext<object>) => unknown;
5
+ type PipelineDocumentHandler = (inputs: Record<string, unknown>, context: PipelineStepContext<object>) => unknown;
6
+ type PipelineDocumentFinalizer = (outputs: Record<string, unknown>, context: PipelineExecutionContext<object>) => unknown;
7
+ type PipelineDocumentSkipPredicate = (inputs: Record<string, unknown>, context: PipelineExecutionContext<object>) => StepSkipDecision | Promise<StepSkipDecision>;
8
+ /** Application-owned wiring for one declarative `fromPipeline` step. */
9
+ interface PipelineDocumentFromPipelineAdapter {
10
+ mapOptions(inputs: Record<string, unknown>, context: PipelineExecutionContext<object>): PipelineRunOptions;
11
+ mapResult?(value: unknown, result: PipelineRun<unknown>, context: PipelineStepContext<object>): unknown;
12
+ }
13
+ /** Application-owned wiring for one declarative `forEachPipeline` step. */
14
+ interface PipelineDocumentForEachPipelineAdapter {
15
+ items(inputs: Record<string, unknown>, context: PipelineExecutionContext<object>): readonly unknown[] | Promise<readonly unknown[]>;
16
+ key(item: unknown, index: number): string;
17
+ concurrency?: number | ((inputs: Record<string, unknown>, context: PipelineExecutionContext<object>) => number);
18
+ progress?: MappedChildProgressOptions;
19
+ mapOptions(item: unknown, index: number, inputs: Record<string, unknown>, context: PipelineExecutionContext<object>): PipelineRunOptions;
20
+ mapResult?(value: unknown, result: PipelineRun<unknown>, item: unknown, index: number, context: PipelineStepContext<object>): unknown;
21
+ }
8
22
  /** Only explicitly registered functions and schemas can be referenced by a document. */
9
23
  export interface PipelineDocumentRegistry {
10
24
  steps: Readonly<Record<string, PipelineDocumentHandler>>;
11
25
  finalizers: Readonly<Record<string, PipelineDocumentFinalizer>>;
26
+ skipPredicates?: Readonly<Record<string, PipelineDocumentSkipPredicate>>;
27
+ fromPipelineAdapters?: Readonly<Record<string, PipelineDocumentFromPipelineAdapter>>;
28
+ forEachPipelineAdapters?: Readonly<Record<string, PipelineDocumentForEachPipelineAdapter>>;
12
29
  optionsSchemas?: Readonly<Record<string, StandardSchemaV1<object, object>>>;
13
30
  schemas?: Readonly<Record<string, StandardSchemaV1>>;
14
31
  }