@pogodisco/zephyr 1.3.5 → 1.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/registry.js CHANGED
@@ -1,43 +1,3 @@
1
- // import { Action, ActionRegistry, MergeActionRegistries } from "./types.js";
2
- //
3
- // export class ActionRegistryBuilder<R extends ActionRegistry = {}> {
4
- // private registry: Partial<R> = {};
5
- //
6
- // constructor(initial?: R) {
7
- // if (initial) {
8
- // this.registry = { ...initial };
9
- // }
10
- // }
11
- //
12
- // action<K extends string, I, O>(
13
- // key: K,
14
- // action: Action<I, O>,
15
- // ): ActionRegistryBuilder<MergeActionRegistries<R, Record<K, Action<I, O>>>> {
16
- // (this.registry as any)[key] = action;
17
- // return this as any;
18
- // }
19
- //
20
- // // Extend with another registry (with override)
21
- // extend<Other extends ActionRegistry>(
22
- // other: ActionRegistryBuilder<Other> | Other,
23
- // ): ActionRegistryBuilder<MergeActionRegistries<R, Other>> {
24
- // const otherRegistry =
25
- // other instanceof ActionRegistryBuilder ? other.build() : other;
26
- //
27
- // Object.assign(this.registry, otherRegistry);
28
- // return this as any;
29
- // }
30
- //
31
- // build(): R {
32
- // return this.registry as R;
33
- // }
34
- // }
35
- //
36
- // export function createActionRegistry<R extends ActionRegistry = {}>(
37
- // initial?: R,
38
- // ): ActionRegistryBuilder<R> {
39
- // return new ActionRegistryBuilder(initial);
40
- // }
41
1
  export class ActionRegistryBuilder {
42
2
  constructor(initial) {
43
3
  this.registry = {};
package/dist/utils.js CHANGED
@@ -1,44 +1,3 @@
1
- // import { defineNode, execNode } from "./node/main.js";
2
- // import { TaskMap, TaskNodeWithContracts, TasksFromFns } from "./node/types.js";
3
- //
4
- // export function createAction<
5
- // FN extends (args: any) => any, // Allow sync or async
6
- // Out = Awaited<ReturnType<FN>>, // Unwrap Promise if present
7
- // >(fn: FN) {
8
- // // Just return the raw node definition, not wrapped with useNode
9
- // return defineNode<TasksFromFns<{ run: FN }>, Parameters<FN>[0], Out>({
10
- // run: {
11
- // fn, // Function can throw or return data
12
- // argMap: (r) => r._init,
13
- // },
14
- // _output: (r) => r.run as Out,
15
- // });
16
- // }
17
- //
18
- // export function genericAction<FN extends (args: any) => any>(fn: FN) {
19
- // return <T = Awaited<ReturnType<FN>>>() => useAction(createAction<FN, T>(fn));
20
- // }
21
- //
22
- // export function fixedAction<
23
- // FN extends (args: any) => any,
24
- // T = Awaited<ReturnType<FN>>,
25
- // >(fn: FN): () => (args: Parameters<FN>[0]) => Promise<T> {
26
- // return () => useAction(createAction<FN, T>(fn));
27
- // }
28
- //
29
- // export function useAction<
30
- // T extends TaskMap,
31
- // I extends Record<string, any> | undefined,
32
- // O,
33
- // >(node: TaskNodeWithContracts<T, I, O>) {
34
- // // Returns a function that graph can call, but WITHOUT withResponse
35
- // // Just a simple adapter that calls callNode and returns raw _output
36
- // return async (initArgs: I): Promise<O> => {
37
- // const result = await execNode(node, initArgs);
38
- // return result._output; // Just raw data, throws on error
39
- // };
40
- // }
41
- //
42
1
  /**
43
2
  * For generic actions - preserves the generic parameter
44
3
  */
@@ -1,5 +1,5 @@
1
- import { ActionRegistry, ActionReturn } from "./types.js";
2
- export type NormalizedCall = {
1
+ import { ActionParams, ActionRegistry, ActionReturn } from "./types.js";
2
+ type NormalizedCall = {
3
3
  kind: "none";
4
4
  } | {
5
5
  kind: "positional";
@@ -12,15 +12,42 @@ export type ResolvedStepInput = NormalizedCall | {
12
12
  kind: "loop";
13
13
  items: NormalizedCall[];
14
14
  };
15
+ type CallHelpers<Reg extends ActionRegistry, ActionName extends keyof Reg> = {
16
+ args: (...args: ActionParams<Reg, ActionName>) => {
17
+ kind: "positional";
18
+ args: ActionParams<Reg, ActionName>;
19
+ };
20
+ obj: ActionParams<Reg, ActionName> extends [infer A] ? (arg: A) => {
21
+ kind: "object";
22
+ args: A;
23
+ } : never;
24
+ none: () => {
25
+ kind: "none";
26
+ };
27
+ loop: (items: {
28
+ kind: "positional";
29
+ args: ActionParams<Reg, ActionName>;
30
+ }[] | {
31
+ kind: "object";
32
+ args: ActionParams<Reg, ActionName>[0];
33
+ }[]) => {
34
+ kind: "loop";
35
+ items: typeof items;
36
+ };
37
+ };
15
38
  type SubflowResult<SubResults, SubOutput> = SubOutput extends undefined ? SubResults : SubOutput;
16
- export type StepResult<Reg extends ActionRegistry, ActionName extends keyof Reg, Loop extends boolean | undefined = undefined> = Loop extends true ? ActionReturn<Reg, ActionName>[] : ActionReturn<Reg, ActionName>;
39
+ type WorkflowInput<T> = T extends WorkflowDef<any, infer I, any, any, any> ? I : never;
40
+ type WorkflowResults<T> = T extends WorkflowDef<any, any, infer R, any, any> ? R : never;
41
+ type WorkflowOutput<T> = T extends WorkflowDef<any, any, any, any, infer O> ? O : never;
42
+ export type StepResultFromResolve<Reg extends ActionRegistry, ActionName extends keyof Reg, R extends ResolvedStepInput> = R extends {
43
+ kind: "loop";
44
+ } ? ActionReturn<Reg, ActionName>[] : ActionReturn<Reg, ActionName>;
17
45
  export type StepDef<Reg extends ActionRegistry, ID extends string = string, ActionName extends keyof Reg = any> = {
18
46
  id: ID;
19
47
  action: ActionName;
20
48
  dependsOn: string[];
21
49
  resolve: (ctx: any) => ResolvedStepInput;
22
50
  when?: (ctx: any) => boolean;
23
- loop?: boolean;
24
51
  };
25
52
  export type WorkflowDef<Reg extends ActionRegistry, Input, Results, Steps extends StepDef<Reg, any, any>[] = StepDef<Reg, any, any>[], Output = undefined> = {
26
53
  name: string;
@@ -41,49 +68,45 @@ export declare class WorkflowBuilder<Reg extends ActionRegistry, Input = unknown
41
68
  private frontier;
42
69
  private outputResolver?;
43
70
  constructor(name: string, registry: Reg, context: Context);
44
- step<ID extends string, ActionName extends keyof Reg & string, Loop extends boolean | undefined = undefined>(id: ID, action: ActionName, resolve?: (ctx: {
71
+ step<ID extends string, ActionName extends keyof Reg & string, ResolveOut extends ResolvedStepInput = ResolvedStepInput>(id: ID, action: ActionName, resolve?: (ctx: {
45
72
  input: Input;
46
73
  results: Results;
47
74
  context: Context;
48
- }) => ResolvedStepInput, dependsOn?: string[], options?: {
49
- loop?: Loop;
50
- }): WorkflowBuilder<Reg, Input, Context, [
75
+ } & CallHelpers<Reg, ActionName>) => ResolveOut, dependsOn?: string[], options?: {}): WorkflowBuilder<Reg, Input, Context, [
51
76
  ...Steps,
52
77
  StepDef<Reg, ID, ActionName>
53
78
  ], Results & {
54
- [K in ID]: StepResult<Reg, ActionName, Loop>;
79
+ [K in ID]: StepResultFromResolve<Reg, ActionName, ResolveOut>;
55
80
  }>;
56
- seq<ID extends string, ActionName extends keyof Reg & string>(id: ID, action: ActionName, resolve?: (ctx: {
81
+ seq<ID extends string, ActionName extends keyof Reg & string, ResolveOut extends ResolvedStepInput = ResolvedStepInput>(id: ID, action: ActionName, resolve?: (ctx: {
57
82
  input: Input;
58
83
  results: Results;
59
84
  context: Context;
60
- }) => ResolvedStepInput, options?: {
61
- loop?: boolean;
62
- }): WorkflowBuilder<Reg, Input, Context, [...Steps, StepDef<Reg, ID, ActionName>], Results & { [K in ID]: ActionReturn<Reg, ActionName> | ActionReturn<Reg, ActionName>[]; }, undefined>;
85
+ } & CallHelpers<Reg, ActionName>) => ResolveOut, options?: {}): WorkflowBuilder<Reg, Input, Context, [...Steps, StepDef<Reg, ID, ActionName>], Results & { [K in ID]: StepResultFromResolve<Reg, ActionName, ResolveOut>; }, undefined>;
63
86
  parallel<Branches extends WorkflowBuilder<Reg, Input, Context, any, any>[]>(...branches: {
64
87
  [K in keyof Branches]: (builder: WorkflowBuilder<Reg, Input, Context, [], Results>) => Branches[K];
65
88
  }): WorkflowBuilder<Reg, Input, Context, [
66
89
  ...Steps,
67
90
  ...(Branches[number] extends WorkflowBuilder<Reg, any, any, infer S, any> ? S : never)
68
91
  ], Results & (Branches[number] extends WorkflowBuilder<Reg, any, any, any, infer R> ? UnionToIntersection<R> : {})>;
69
- join<ID extends string, ActionName extends keyof Reg & string>(id: ID, action: ActionName, resolve?: (ctx: {
92
+ join<ID extends string, ActionName extends keyof Reg & string, ResolveOut extends ResolvedStepInput = ResolvedStepInput>(id: ID, action: ActionName, resolve?: (ctx: {
70
93
  input: Input;
71
94
  results: Results;
72
95
  context: Context;
73
- }) => ResolvedStepInput, options?: {
74
- loop?: boolean;
75
- }): WorkflowBuilder<Reg, Input, Context, [...Steps, StepDef<Reg, ID, ActionName>], Results & { [K in ID]: ActionReturn<Reg, ActionName> | ActionReturn<Reg, ActionName>[]; }, undefined>;
76
- subflow<Prefix extends string, SubInput, SubResults, SubSteps extends StepDef<Reg, any, any>[], SubOutput>(prefix: Prefix, workflow: WorkflowDef<Reg, SubInput, SubResults, SubSteps, SubOutput>, resolveInput?: (ctx: {
96
+ } & CallHelpers<Reg, ActionName>) => ResolveOut, options?: {}): WorkflowBuilder<Reg, Input, Context, [...Steps, StepDef<Reg, ID, ActionName>], Results & { [K in ID]: StepResultFromResolve<Reg, ActionName, ResolveOut>; }, undefined>;
97
+ subflow<Prefix extends string, SubSteps extends StepDef<Reg, any, any>[], WF extends WorkflowDef<Reg, any, any, SubSteps, any>>(prefix: Prefix, workflow: WF, resolveInput: WorkflowInput<WF> extends undefined ? ((ctx: {
77
98
  input: Input;
78
99
  results: Results;
79
100
  context: Context;
80
- }) => SubInput, options?: {
81
- loop?: boolean;
82
- }): WorkflowBuilder<Reg, Input, Context, [
101
+ }) => WorkflowInput<WF>) | undefined : (ctx: {
102
+ input: Input;
103
+ results: Results;
104
+ context: Context;
105
+ }) => WorkflowInput<WF>, options?: {}): WorkflowBuilder<Reg, Input, Context, [
83
106
  ...Steps,
84
- ...SubSteps
107
+ ...WF["steps"]
85
108
  ], Results & {
86
- [K in Prefix]: SubflowResult<SubResults, SubOutput>;
109
+ [K in Prefix]: SubflowResult<WorkflowResults<WF>, WorkflowOutput<WF>>;
87
110
  }>;
88
111
  when(predicate: (ctx: {
89
112
  input: Input;
@@ -98,10 +121,6 @@ export declare class WorkflowBuilder<Reg extends ActionRegistry, Input = unknown
98
121
  build(): WorkflowDef<Reg, Input, Results, Steps>;
99
122
  private validateDependencies;
100
123
  private getEndSteps;
101
- static args: (...args: any[]) => NormalizedCall;
102
- static obj: (args: any) => NormalizedCall;
103
- static none: () => NormalizedCall;
104
- static loop: (items: NormalizedCall[]) => ResolvedStepInput;
105
124
  }
106
125
  export declare function createWorkflow<Reg extends ActionRegistry, Context extends Record<string, any> = {}>(registry: Reg, context?: Context): <Input = unknown>(name: string) => WorkflowBuilder<Reg, Input, Context, [], {}, undefined>;
107
126
  export {};
@@ -1,4 +1,367 @@
1
- // workflow-composer.ts
1
+ // import { ActionRegistry, ActionReturn } from "./types.js";
2
+ //
3
+ // /* ------------------------------------------------ */
4
+ // /* STEP INPUT NORMALIZATION TYPES */
5
+ // /* ------------------------------------------------ */
6
+ //
7
+ // export type NormalizedCall =
8
+ // | { kind: "none" }
9
+ // | { kind: "positional"; args: any[] }
10
+ // | { kind: "object"; args: any };
11
+ //
12
+ // export type ResolvedStepInput =
13
+ // | NormalizedCall
14
+ // | { kind: "loop"; items: NormalizedCall[] };
15
+ //
16
+ // /* ------------------------------------------------ */
17
+ // /* STEP RESULT TYPES */
18
+ // /* ------------------------------------------------ */
19
+ //
20
+ // type SubflowResult<SubResults, SubOutput> = SubOutput extends undefined
21
+ // ? SubResults
22
+ // : SubOutput;
23
+ //
24
+ // export type StepResult<
25
+ // Reg extends ActionRegistry,
26
+ // ActionName extends keyof Reg,
27
+ // Loop extends boolean | undefined = undefined,
28
+ // > = Loop extends true
29
+ // ? ActionReturn<Reg, ActionName>[]
30
+ // : ActionReturn<Reg, ActionName>;
31
+ //
32
+ // /* ------------------------------------------------ */
33
+ // /* STEP DEFINITION */
34
+ // /* ------------------------------------------------ */
35
+ //
36
+ // export type StepDef<
37
+ // Reg extends ActionRegistry,
38
+ // ID extends string = string,
39
+ // ActionName extends keyof Reg = any,
40
+ // > = {
41
+ // id: ID;
42
+ // action: ActionName;
43
+ // dependsOn: string[];
44
+ // resolve: (ctx: any) => ResolvedStepInput;
45
+ // when?: (ctx: any) => boolean;
46
+ // loop?: boolean;
47
+ // };
48
+ //
49
+ // /* ------------------------------------------------ */
50
+ // /* WORKFLOW DEFINITION */
51
+ // /* ------------------------------------------------ */
52
+ //
53
+ // export type WorkflowDef<
54
+ // Reg extends ActionRegistry,
55
+ // Input,
56
+ // Results,
57
+ // Steps extends StepDef<Reg, any, any>[] = StepDef<Reg, any, any>[],
58
+ // Output = undefined,
59
+ // > = {
60
+ // name: string;
61
+ // steps: Steps;
62
+ // entrySteps: StepDef<Reg>[];
63
+ // endSteps: StepDef<Reg>[];
64
+ // input: Input;
65
+ // results: Results;
66
+ // outputResolver?: (ctx: any) => Output;
67
+ // __context?: any;
68
+ // };
69
+ //
70
+ // /* ------------------------------------------------ */
71
+ // /* HELPER TYPES */
72
+ // /* ------------------------------------------------ */
73
+ //
74
+ // type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
75
+ // k: infer I,
76
+ // ) => void
77
+ // ? I
78
+ // : never;
79
+ //
80
+ // /* ------------------------------------------------ */
81
+ // /* FLUENT WORKFLOW BUILDER */
82
+ // /* ------------------------------------------------ */
83
+ //
84
+ // export class WorkflowBuilder<
85
+ // Reg extends ActionRegistry,
86
+ // Input = unknown,
87
+ // Context extends Record<string, any> = {},
88
+ // Steps extends StepDef<Reg, any, any>[] = [],
89
+ // Results = {},
90
+ // Output = undefined,
91
+ // > {
92
+ // private steps: StepDef<Reg, any, any>[] = [];
93
+ // private frontier: string[] = [];
94
+ // private outputResolver?: (ctx: any) => any;
95
+ //
96
+ // constructor(
97
+ // private name: string,
98
+ // private registry: Reg,
99
+ // private context: Context,
100
+ // ) {}
101
+ //
102
+ // /* ------------------------------------------------ */
103
+ // /* Base Step */
104
+ // /* ------------------------------------------------ */
105
+ // step<
106
+ // ID extends string,
107
+ // ActionName extends keyof Reg & string,
108
+ // Loop extends boolean | undefined = undefined,
109
+ // >(
110
+ // id: ID,
111
+ // action: ActionName,
112
+ // resolve?: (ctx: {
113
+ // input: Input;
114
+ // results: Results;
115
+ // context: Context;
116
+ // }) => ResolvedStepInput,
117
+ // dependsOn?: string[],
118
+ // options?: { loop?: Loop },
119
+ // ): WorkflowBuilder<
120
+ // Reg,
121
+ // Input,
122
+ // Context,
123
+ // [...Steps, StepDef<Reg, ID, ActionName>],
124
+ // Results & { [K in ID]: StepResult<Reg, ActionName, Loop> }
125
+ // > {
126
+ // const deps = dependsOn ?? [...this.frontier];
127
+ //
128
+ // this.steps.push({
129
+ // id,
130
+ // action,
131
+ // resolve: resolve ?? (() => ({ kind: "none" })),
132
+ // dependsOn: deps,
133
+ // loop: options?.loop ?? false,
134
+ // });
135
+ //
136
+ // this.frontier = [id];
137
+ //
138
+ // return this as any;
139
+ // }
140
+ //
141
+ // /* ------------------------------------------------ */
142
+ // /* Sequential shortcut */
143
+ // /* ------------------------------------------------ */
144
+ // seq<ID extends string, ActionName extends keyof Reg & string>(
145
+ // id: ID,
146
+ // action: ActionName,
147
+ // resolve?: (ctx: {
148
+ // input: Input;
149
+ // results: Results;
150
+ // context: Context;
151
+ // }) => ResolvedStepInput,
152
+ // options?: { loop?: boolean },
153
+ // ) {
154
+ // return this.step(id, action, resolve, undefined, options);
155
+ // }
156
+ //
157
+ // /* ------------------------------------------------ */
158
+ // /* Parallel branches */
159
+ // /* ------------------------------------------------ */
160
+ // parallel<Branches extends WorkflowBuilder<Reg, Input, Context, any, any>[]>(
161
+ // ...branches: {
162
+ // [K in keyof Branches]: (
163
+ // builder: WorkflowBuilder<Reg, Input, Context, [], Results>,
164
+ // ) => Branches[K];
165
+ // }
166
+ // ): WorkflowBuilder<
167
+ // Reg,
168
+ // Input,
169
+ // Context,
170
+ // [
171
+ // ...Steps,
172
+ // ...(Branches[number] extends WorkflowBuilder<Reg, any, any, infer S, any>
173
+ // ? S
174
+ // : never),
175
+ // ],
176
+ // Results &
177
+ // (Branches[number] extends WorkflowBuilder<Reg, any, any, any, infer R>
178
+ // ? UnionToIntersection<R>
179
+ // : {})
180
+ // > {
181
+ // const parentFrontier = [...this.frontier];
182
+ // const branchEnds: string[] = [];
183
+ //
184
+ // branches.forEach((branch) => {
185
+ // const b = new WorkflowBuilder<Reg, Input, Context, [], Results>(
186
+ // this.name,
187
+ // this.registry,
188
+ // this.context,
189
+ // );
190
+ //
191
+ // b.frontier = parentFrontier;
192
+ // branch(b);
193
+ // branchEnds.push(...b.frontier);
194
+ // this.steps.push(...(b as any).steps);
195
+ // });
196
+ //
197
+ // this.frontier = branchEnds;
198
+ // return this as any;
199
+ // }
200
+ //
201
+ // /* ------------------------------------------------ */
202
+ // /* Join helper */
203
+ // /* ------------------------------------------------ */
204
+ // join<ID extends string, ActionName extends keyof Reg & string>(
205
+ // id: ID,
206
+ // action: ActionName,
207
+ // resolve?: (ctx: {
208
+ // input: Input;
209
+ // results: Results;
210
+ // context: Context;
211
+ // }) => ResolvedStepInput,
212
+ // options?: { loop?: boolean },
213
+ // ) {
214
+ // return this.step(id, action, resolve, [...this.frontier], options);
215
+ // }
216
+ //
217
+ // /* ------------------------------------------------ */
218
+ // /* Subflow */
219
+ // /* ------------------------------------------------ */
220
+ // subflow<
221
+ // Prefix extends string,
222
+ // SubInput,
223
+ // SubResults,
224
+ // SubSteps extends StepDef<Reg, any, any>[],
225
+ // SubOutput,
226
+ // >(
227
+ // prefix: Prefix,
228
+ // workflow: WorkflowDef<Reg, SubInput, SubResults, SubSteps, SubOutput>,
229
+ // resolveInput?: (ctx: {
230
+ // input: Input;
231
+ // results: Results;
232
+ // context: Context;
233
+ // }) => SubInput,
234
+ // options?: { loop?: boolean },
235
+ // ): WorkflowBuilder<
236
+ // Reg,
237
+ // Input,
238
+ // Context,
239
+ // [...Steps, ...SubSteps],
240
+ // Results & { [K in Prefix]: SubflowResult<SubResults, SubOutput> }
241
+ // > {
242
+ // const idMap = new Map<string, string>();
243
+ //
244
+ // workflow.steps.forEach((step) => {
245
+ // idMap.set(step.id, `${prefix}.${step.id}`);
246
+ // });
247
+ //
248
+ // workflow.steps.forEach((step) => {
249
+ // const newStep: StepDef<Reg, any, any> = {
250
+ // ...step,
251
+ // id: idMap.get(step.id)!,
252
+ // dependsOn: step.dependsOn.map((d) => idMap.get(d)!),
253
+ // resolve: (ctx: any) => {
254
+ // const subInput = resolveInput ? resolveInput(ctx) : undefined;
255
+ // return step.resolve({
256
+ // input: subInput,
257
+ // results: ctx.results,
258
+ // context: ctx.context,
259
+ // });
260
+ // },
261
+ // ...(options ? { loop: options.loop ?? step.loop } : {}),
262
+ // };
263
+ //
264
+ // if (workflow.entrySteps.find((e) => e.id === step.id)) {
265
+ // newStep.dependsOn = [...this.frontier];
266
+ // }
267
+ //
268
+ // this.steps.push(newStep);
269
+ // });
270
+ //
271
+ // this.frontier = workflow.endSteps.map((e) => idMap.get(e.id)!);
272
+ // return this as any;
273
+ // }
274
+ //
275
+ // /* ------------------------------------------------ */
276
+ // /* Conditional */
277
+ // /* ------------------------------------------------ */
278
+ // when(
279
+ // predicate: (ctx: {
280
+ // input: Input;
281
+ // results: Results;
282
+ // context: Context;
283
+ // }) => boolean,
284
+ // ): this {
285
+ // const lastStep = this.steps[this.steps.length - 1];
286
+ // if (!lastStep) throw new Error("when() must follow a step");
287
+ // lastStep.when = predicate;
288
+ // return this;
289
+ // }
290
+ //
291
+ // /* ------------------------------------------------ */
292
+ // /* Workflow output */
293
+ // /* ------------------------------------------------ */
294
+ // output<Output>(
295
+ // fn: (ctx: { input: Input; results: Results; context: Context }) => Output,
296
+ // ): WorkflowDef<Reg, Input, Results, Steps, Output> {
297
+ // this.outputResolver = fn;
298
+ // return this.build() as WorkflowDef<Reg, Input, Results, Steps, Output>;
299
+ // }
300
+ //
301
+ // build(): WorkflowDef<Reg, Input, Results, Steps> {
302
+ // this.validateDependencies();
303
+ //
304
+ // return {
305
+ // name: this.name,
306
+ // steps: this.steps as Steps,
307
+ // entrySteps: this.steps.filter((s) => s.dependsOn.length === 0),
308
+ // endSteps: this.getEndSteps(),
309
+ // input: {} as Input,
310
+ // results: {} as Results,
311
+ // outputResolver: this.outputResolver,
312
+ // __context: this.context,
313
+ // };
314
+ // }
315
+ //
316
+ // private validateDependencies() {
317
+ // const stepIds = new Set(this.steps.map((s) => s.id));
318
+ // for (const step of this.steps) {
319
+ // for (const dep of step.dependsOn) {
320
+ // if (!stepIds.has(dep))
321
+ // throw new Error(`Step ${step.id} depends on unknown step ${dep}`);
322
+ // }
323
+ // }
324
+ // }
325
+ //
326
+ // private getEndSteps() {
327
+ // const hasDependents = new Set<string>();
328
+ // for (const step of this.steps) {
329
+ // for (const dep of step.dependsOn) hasDependents.add(dep);
330
+ // }
331
+ // return this.steps.filter((s) => !hasDependents.has(s.id));
332
+ // }
333
+ //
334
+ // /* ------------------------------------------------ */
335
+ // /* STATIC HELPERS FOR NORMALIZATION */
336
+ // /* ------------------------------------------------ */
337
+ // static args = (...args: any[]): NormalizedCall => ({
338
+ // kind: "positional",
339
+ // args,
340
+ // });
341
+ // static obj = (args: any): NormalizedCall => ({ kind: "object", args });
342
+ // static none = (): NormalizedCall => ({ kind: "none" });
343
+ // static loop = (items: NormalizedCall[]): ResolvedStepInput => ({
344
+ // kind: "loop",
345
+ // items,
346
+ // });
347
+ // }
348
+ //
349
+ // /* ------------------------------------------------ */
350
+ // /* WORKFLOW CREATOR */
351
+ // /* ------------------------------------------------ */
352
+ // export function createWorkflow<
353
+ // Reg extends ActionRegistry,
354
+ // Context extends Record<string, any> = {},
355
+ // >(registry: Reg, context?: Context) {
356
+ // return function workflow<Input = unknown>(name: string) {
357
+ // return new WorkflowBuilder<Reg, Input, Context>(
358
+ // name,
359
+ // registry,
360
+ // context || ({} as Context),
361
+ // );
362
+ // };
363
+ // }
364
+ //
2
365
  /* ------------------------------------------------ */
3
366
  /* FLUENT WORKFLOW BUILDER */
4
367
  /* ------------------------------------------------ */
@@ -20,7 +383,6 @@ export class WorkflowBuilder {
20
383
  action,
21
384
  resolve: resolve ?? (() => ({ kind: "none" })),
22
385
  dependsOn: deps,
23
- loop: options?.loop ?? false,
24
386
  });
25
387
  this.frontier = [id];
26
388
  return this;
@@ -56,6 +418,60 @@ export class WorkflowBuilder {
56
418
  /* ------------------------------------------------ */
57
419
  /* Subflow */
58
420
  /* ------------------------------------------------ */
421
+ // subflow<
422
+ // Prefix extends string,
423
+ // SubInput,
424
+ // SubResults,
425
+ // SubSteps extends StepDef<Reg, any, any>[],
426
+ // SubOutput,
427
+ // >(
428
+ // prefix: Prefix,
429
+ // workflow: WorkflowDef<Reg, SubInput, SubResults, SubSteps, SubOutput>,
430
+ // resolveInput?: (ctx: {
431
+ // input: Input;
432
+ // results: Results;
433
+ // context: Context;
434
+ // }) => SubInput,
435
+ // options?: { loop?: boolean },
436
+ // ): WorkflowBuilder<
437
+ // Reg,
438
+ // Input,
439
+ // Context,
440
+ // [...Steps, ...SubSteps],
441
+ // Results & { [K in Prefix]: SubflowResult<SubResults, SubOutput> }
442
+ // > {
443
+ // const idMap = new Map<string, string>();
444
+ //
445
+ // workflow.steps.forEach((step) => {
446
+ // idMap.set(step.id, `${prefix}.${step.id}`);
447
+ // });
448
+ //
449
+ // workflow.steps.forEach((step) => {
450
+ // const newStep: StepDef<Reg, any, any> = {
451
+ // ...step,
452
+ // id: idMap.get(step.id)!,
453
+ // dependsOn: step.dependsOn.map((d) => idMap.get(d)!),
454
+ // resolve: (ctx: any) => {
455
+ // const subInput = resolveInput ? resolveInput(ctx) : undefined;
456
+ // return step.resolve({
457
+ // input: subInput,
458
+ // results: ctx.results,
459
+ // context: ctx.context,
460
+ // });
461
+ // },
462
+ // ...(options ? { loop: options.loop ?? step.loop } : {}),
463
+ // };
464
+ //
465
+ // if (workflow.entrySteps.find((e) => e.id === step.id)) {
466
+ // newStep.dependsOn = [...this.frontier];
467
+ // }
468
+ //
469
+ // this.steps.push(newStep);
470
+ // });
471
+ //
472
+ // this.frontier = workflow.endSteps.map((e) => idMap.get(e.id)!);
473
+ // return this as any;
474
+ // }
59
475
  subflow(prefix, workflow, resolveInput, options) {
60
476
  const idMap = new Map();
61
477
  workflow.steps.forEach((step) => {
@@ -74,7 +490,6 @@ export class WorkflowBuilder {
74
490
  context: ctx.context,
75
491
  });
76
492
  },
77
- ...(options ? { loop: options.loop ?? step.loop } : {}),
78
493
  };
79
494
  if (workflow.entrySteps.find((e) => e.id === step.id)) {
80
495
  newStep.dependsOn = [...this.frontier];
@@ -133,19 +548,6 @@ export class WorkflowBuilder {
133
548
  }
134
549
  }
135
550
  /* ------------------------------------------------ */
136
- /* STATIC HELPERS FOR NORMALIZATION */
137
- /* ------------------------------------------------ */
138
- WorkflowBuilder.args = (...args) => ({
139
- kind: "positional",
140
- args,
141
- });
142
- WorkflowBuilder.obj = (args) => ({ kind: "object", args });
143
- WorkflowBuilder.none = () => ({ kind: "none" });
144
- WorkflowBuilder.loop = (items) => ({
145
- kind: "loop",
146
- items,
147
- });
148
- /* ------------------------------------------------ */
149
551
  /* WORKFLOW CREATOR */
150
552
  /* ------------------------------------------------ */
151
553
  export function createWorkflow(registry, context) {