@pogodisco/zephyr 1.5.1 → 1.5.3
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/types.d.ts +22 -0
- package/dist/types.js +1 -0
- package/dist/workflow-composer-pipe.d.ts +71 -0
- package/dist/workflow-composer-pipe.js +28 -0
- package/dist/workflow-composer.d.ts +23 -64
- package/dist/workflow-composer.js +24 -70
- package/dist/workflow-executor.d.ts +0 -4
- package/dist/workflow-executor.js +36 -13
- package/dist/workflow-module.js +0 -257
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -32,3 +32,25 @@ export interface Executor {
|
|
|
32
32
|
export type ServiceRegistry = Record<string, Record<string, (...args: any[]) => any>>;
|
|
33
33
|
export type ServiceParams<S extends ServiceRegistry, K extends keyof S, M extends keyof S[K]> = Parameters<S[K][M]>;
|
|
34
34
|
export type ServiceReturn<S extends ServiceRegistry, K extends keyof S, M extends keyof S[K]> = Awaited<ReturnType<S[K][M]>>;
|
|
35
|
+
export type NormalizedCall = {
|
|
36
|
+
kind: "none";
|
|
37
|
+
} | {
|
|
38
|
+
kind: "positional";
|
|
39
|
+
args: any[];
|
|
40
|
+
} | {
|
|
41
|
+
kind: "object";
|
|
42
|
+
args: any;
|
|
43
|
+
};
|
|
44
|
+
export type CallHelpers<Reg extends ActionRegistry, ActionName extends keyof Reg> = {
|
|
45
|
+
args: (...args: ActionParams<Reg, ActionName>) => {
|
|
46
|
+
kind: "positional";
|
|
47
|
+
args: ActionParams<Reg, ActionName>;
|
|
48
|
+
};
|
|
49
|
+
obj: ActionParams<Reg, ActionName> extends [infer A] ? (arg: A) => {
|
|
50
|
+
kind: "object";
|
|
51
|
+
args: A;
|
|
52
|
+
} : never;
|
|
53
|
+
none: () => {
|
|
54
|
+
kind: "none";
|
|
55
|
+
};
|
|
56
|
+
};
|
package/dist/types.js
CHANGED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { ActionRegistry, ActionReturn, CallHelpers, NormalizedCall, ServiceParams, ServiceRegistry, ServiceReturn } from "./types.js";
|
|
2
|
+
type PipeStep = {
|
|
3
|
+
type: "action" | "service";
|
|
4
|
+
action?: string;
|
|
5
|
+
service?: string;
|
|
6
|
+
method?: string;
|
|
7
|
+
resolve: (ctx: any) => NormalizedCall;
|
|
8
|
+
};
|
|
9
|
+
export type PipeDef = {
|
|
10
|
+
input: (ctx: any) => any[];
|
|
11
|
+
steps: PipeStep[];
|
|
12
|
+
};
|
|
13
|
+
type InferStepReturn<Step, Reg extends ActionRegistry, Services extends ServiceRegistry> = Step extends {
|
|
14
|
+
type: "action";
|
|
15
|
+
action: infer A;
|
|
16
|
+
} ? A extends keyof Reg ? ActionReturn<Reg, A> : never : Step extends {
|
|
17
|
+
type: "service";
|
|
18
|
+
service: infer SK;
|
|
19
|
+
method: infer MK;
|
|
20
|
+
} ? SK extends keyof Services ? MK extends keyof Services[SK] ? ServiceReturn<Services, SK, MK> : never : never : never;
|
|
21
|
+
export type PipeFinalType<Steps, Reg extends ActionRegistry, Services extends ServiceRegistry> = Steps extends [...any[], infer Last] ? InferStepReturn<Last, Reg, Services> : never;
|
|
22
|
+
export type StepsOfPipeBuilder<PB> = PB extends PipeBuilder<any, any, any, any, infer S> ? S : never;
|
|
23
|
+
export declare class PipeBuilder<Current, Reg extends ActionRegistry, Services extends ServiceRegistry, Results, Steps extends any[] = []> {
|
|
24
|
+
private steps;
|
|
25
|
+
action<A extends keyof Reg & string>(action: A, resolve: (ctx: {
|
|
26
|
+
current: Current;
|
|
27
|
+
results: Results;
|
|
28
|
+
} & CallHelpers<Reg, A>) => NormalizedCall): PipeBuilder<ActionReturn<Reg, A>, Reg, Services, Results, [
|
|
29
|
+
...Steps,
|
|
30
|
+
{
|
|
31
|
+
type: "action";
|
|
32
|
+
action: A;
|
|
33
|
+
}
|
|
34
|
+
]>;
|
|
35
|
+
service<SK extends keyof Services & string, MK extends keyof Services[SK] & string>(id: string, service: SK, method: MK, resolve: (ctx: {
|
|
36
|
+
current: Current;
|
|
37
|
+
results: Results;
|
|
38
|
+
} & {
|
|
39
|
+
args: (...args: ServiceParams<Services, SK, MK>) => {
|
|
40
|
+
kind: "positional";
|
|
41
|
+
args: ServiceParams<Services, SK, MK>;
|
|
42
|
+
};
|
|
43
|
+
obj: ServiceParams<Services, SK, MK> extends [infer A] ? (arg: A) => {
|
|
44
|
+
kind: "object";
|
|
45
|
+
args: A;
|
|
46
|
+
} : never;
|
|
47
|
+
none: () => {
|
|
48
|
+
kind: "none";
|
|
49
|
+
};
|
|
50
|
+
loop: (items: {
|
|
51
|
+
kind: "positional";
|
|
52
|
+
args: ServiceParams<Services, SK, MK>;
|
|
53
|
+
}[] | {
|
|
54
|
+
kind: "object";
|
|
55
|
+
args: ServiceParams<Services, SK, MK>[0];
|
|
56
|
+
}[]) => {
|
|
57
|
+
kind: "loop";
|
|
58
|
+
items: typeof items;
|
|
59
|
+
};
|
|
60
|
+
}) => NormalizedCall): PipeBuilder<ServiceReturn<Services, SK, MK>, Reg, Services, Results, [
|
|
61
|
+
...Steps,
|
|
62
|
+
{
|
|
63
|
+
type: "service";
|
|
64
|
+
service: SK;
|
|
65
|
+
method: MK;
|
|
66
|
+
}
|
|
67
|
+
]>;
|
|
68
|
+
getSteps(): Steps;
|
|
69
|
+
build(): PipeStep[];
|
|
70
|
+
}
|
|
71
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export class PipeBuilder {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.steps = [];
|
|
4
|
+
}
|
|
5
|
+
action(action, resolve) {
|
|
6
|
+
this.steps.push({
|
|
7
|
+
type: "action",
|
|
8
|
+
action,
|
|
9
|
+
resolve,
|
|
10
|
+
});
|
|
11
|
+
return this;
|
|
12
|
+
}
|
|
13
|
+
service(id, service, method, resolve) {
|
|
14
|
+
this.steps.push({
|
|
15
|
+
type: "service",
|
|
16
|
+
service,
|
|
17
|
+
method,
|
|
18
|
+
resolve,
|
|
19
|
+
});
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
getSteps() {
|
|
23
|
+
return this.steps;
|
|
24
|
+
}
|
|
25
|
+
build() {
|
|
26
|
+
return this.steps;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -1,57 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
kind: "none";
|
|
4
|
-
} | {
|
|
5
|
-
kind: "positional";
|
|
6
|
-
args: any[];
|
|
7
|
-
} | {
|
|
8
|
-
kind: "object";
|
|
9
|
-
args: any;
|
|
10
|
-
};
|
|
11
|
-
export type ResolvedStepInput = NormalizedCall | {
|
|
12
|
-
kind: "loop";
|
|
13
|
-
items: NormalizedCall[];
|
|
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
|
-
};
|
|
1
|
+
import { ActionRegistry, ActionReturn, CallHelpers, NormalizedCall, ServiceParams, ServiceRegistry, ServiceReturn, Simplify } from "./types.js";
|
|
2
|
+
import { PipeBuilder, PipeDef, PipeFinalType, StepsOfPipeBuilder } from "./workflow-composer-pipe.js";
|
|
38
3
|
type WorkflowInput<T> = T extends WorkflowDef<any, infer I, any, any, any> ? I : never;
|
|
39
4
|
type WorkflowOutput<T> = T extends WorkflowDef<any, any, any, any, infer O> ? unknown extends O ? undefined : O : undefined;
|
|
40
|
-
export type StepResultFromResolve<Reg extends ActionRegistry, ActionName extends keyof Reg, R extends ResolvedStepInput> = R extends {
|
|
41
|
-
kind: "loop";
|
|
42
|
-
} ? ActionReturn<Reg, ActionName>[] : ActionReturn<Reg, ActionName>;
|
|
43
|
-
export type ServiceStepResultFromResolve<S extends ServiceRegistry, SK extends keyof S, MK extends keyof S[SK], R extends ResolvedStepInput> = R extends {
|
|
44
|
-
kind: "loop";
|
|
45
|
-
} ? ServiceReturn<S, SK, MK>[] : ServiceReturn<S, SK, MK>;
|
|
46
5
|
export type StepDef<Reg extends ActionRegistry, ID extends string = string, ActionName extends keyof Reg = any> = {
|
|
47
6
|
id: ID;
|
|
48
7
|
action: ActionName | "__service__";
|
|
49
8
|
dependsOn: string[];
|
|
50
|
-
resolve: (ctx: any) =>
|
|
9
|
+
resolve: (ctx: any) => NormalizedCall;
|
|
51
10
|
when?: (ctx: any) => boolean;
|
|
52
11
|
options?: StepOptions<any, any>;
|
|
53
12
|
__subflowId?: string;
|
|
54
13
|
serviceCall?: ServiceCall;
|
|
14
|
+
pipe?: PipeDef;
|
|
55
15
|
};
|
|
56
16
|
export type WorkflowDef<Reg extends ActionRegistry, Input, Results, Steps extends StepDef<Reg, any, any>[] = StepDef<Reg, any, any>[], Output = undefined> = {
|
|
57
17
|
name: string;
|
|
@@ -94,20 +54,20 @@ Input = unknown, Steps extends StepDef<Reg, any, any>[] = [], Results = {}, Outp
|
|
|
94
54
|
private outputResolver?;
|
|
95
55
|
private clearPendingWhen;
|
|
96
56
|
constructor(name: string);
|
|
97
|
-
step<ID extends string, ActionName extends keyof Reg & string
|
|
57
|
+
step<ID extends string, ActionName extends keyof Reg & string>(id: ID, action: ActionName, resolve?: (ctx: {
|
|
98
58
|
input: Input;
|
|
99
59
|
results: Results;
|
|
100
|
-
} & CallHelpers<Reg, ActionName>) =>
|
|
60
|
+
} & CallHelpers<Reg, ActionName>) => NormalizedCall, dependsOn?: string[], options?: StepOptions<Input, Results>): WorkflowBuilder<Reg, Services, WFReg, Input, [
|
|
101
61
|
...Steps,
|
|
102
62
|
StepDef<Reg, ID, ActionName>
|
|
103
63
|
], Simplify<Results & {
|
|
104
|
-
[K in ID]:
|
|
64
|
+
[K in ID]: ActionReturn<Reg, ActionName>;
|
|
105
65
|
}>>;
|
|
106
|
-
seq<ID extends string = string, ActionName extends keyof Reg & string = any
|
|
66
|
+
seq<ID extends string = string, ActionName extends keyof Reg & string = any>(id: ID, action: ActionName, resolve?: (ctx: {
|
|
107
67
|
input: Input;
|
|
108
68
|
results: Results;
|
|
109
|
-
} & CallHelpers<Reg, ActionName>) =>
|
|
110
|
-
service<ID extends string, SK extends keyof Services & string, MK extends keyof Services[SK] & string
|
|
69
|
+
} & CallHelpers<Reg, ActionName>) => NormalizedCall, options?: StepOptions<Input, Results>): WorkflowBuilder<Reg, Services, WFReg, Input, [...Steps, StepDef<Reg, ID, ActionName>], Results & { [K_1 in ID]: ActionReturn<Reg, ActionName>; } extends infer T ? { [K in keyof T]: T[K]; } : never, undefined>;
|
|
70
|
+
service<ID extends string, SK extends keyof Services & string, MK extends keyof Services[SK] & string>(id: ID, service: SK, method: MK, resolve?: (ctx: {
|
|
111
71
|
input: Input;
|
|
112
72
|
results: Results;
|
|
113
73
|
} & {
|
|
@@ -122,21 +82,20 @@ Input = unknown, Steps extends StepDef<Reg, any, any>[] = [], Results = {}, Outp
|
|
|
122
82
|
none: () => {
|
|
123
83
|
kind: "none";
|
|
124
84
|
};
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}) => ResolveOut, options?: StepOptions<Input, Results>): WorkflowBuilder<Reg, Services, WFReg, Input, [
|
|
85
|
+
}) => NormalizedCall, options?: StepOptions<Input, Results>): WorkflowBuilder<Reg, Services, WFReg, Input, [
|
|
86
|
+
...Steps,
|
|
87
|
+
StepDef<Reg, ID, any>
|
|
88
|
+
], Simplify<Results & {
|
|
89
|
+
[K in ID]: ServiceReturn<Services, SK, MK>;
|
|
90
|
+
}>>;
|
|
91
|
+
pipe<ID extends string, Arr extends any[], PB extends PipeBuilder<any, Reg, Services, Results, any>>(id: ID, input: (ctx: {
|
|
92
|
+
input: Input;
|
|
93
|
+
results: Results;
|
|
94
|
+
}) => Arr, builder: (p: PipeBuilder<Arr[number], Reg, Services, Results>) => PB, options?: StepOptions<Input, Results>): WorkflowBuilder<Reg, Services, WFReg, Input, [
|
|
136
95
|
...Steps,
|
|
137
96
|
StepDef<Reg, ID, any>
|
|
138
97
|
], Simplify<Results & {
|
|
139
|
-
[K in ID]:
|
|
98
|
+
[K in ID]: PipeFinalType<StepsOfPipeBuilder<PB>, Reg, Services>[];
|
|
140
99
|
}>>;
|
|
141
100
|
as<NewType>(): WorkflowBuilder<Reg, Services, WFReg, Input, Steps, Steps extends [...infer Rest, infer Last] ? Last extends StepDef<Reg, infer ID, any> ? Simplify<Omit<Results, ID> & {
|
|
142
101
|
[K in ID]: NewType;
|
|
@@ -144,10 +103,10 @@ Input = unknown, Steps extends StepDef<Reg, any, any>[] = [], Results = {}, Outp
|
|
|
144
103
|
parallel<Branches extends readonly WorkflowBuilder<Reg, Services, WFReg, Input, any, any>[]>(...branches: {
|
|
145
104
|
[K in keyof Branches]: (builder: WorkflowBuilder<Reg, Services, WFReg, Input, [], Results>) => Branches[K];
|
|
146
105
|
}): WorkflowBuilder<Reg, Services, WFReg, Input, MergeBranchSteps<Branches, Steps>, Simplify<MergeBranchResults<Branches, Results>>>;
|
|
147
|
-
join<ID extends string = string, ActionName extends keyof Reg & string = any
|
|
106
|
+
join<ID extends string = string, ActionName extends keyof Reg & string = any>(id: ID, action: ActionName, resolve?: (ctx: {
|
|
148
107
|
input: Input;
|
|
149
108
|
results: Results;
|
|
150
|
-
} & CallHelpers<Reg, ActionName>) =>
|
|
109
|
+
} & CallHelpers<Reg, ActionName>) => NormalizedCall, options?: StepOptions<Input, Results>): WorkflowBuilder<Reg, Services, WFReg, Input, [...Steps, StepDef<Reg, ID, ActionName>], Results & { [K_1 in ID]: ActionReturn<Reg, ActionName>; } extends infer T ? { [K in keyof T]: T[K]; } : never, undefined>;
|
|
151
110
|
subflow<Prefix extends string, K extends keyof WFReg & string>(prefix: Prefix, workflowKey: K, resolveInput: (ctx: {
|
|
152
111
|
input: Input;
|
|
153
112
|
results: Results;
|
|
@@ -1,74 +1,5 @@
|
|
|
1
|
-
// /* ------------------------------------------------ */
|
|
2
|
-
// /* Subflow */
|
|
3
|
-
// /* ------------------------------------------------ */
|
|
4
|
-
//
|
|
5
|
-
// subflow<
|
|
6
|
-
// Prefix extends string,
|
|
7
|
-
// SubSteps extends StepDef<Reg, any, any>[],
|
|
8
|
-
// WF extends WorkflowDef<Reg, any, any, SubSteps, any>,
|
|
9
|
-
// >(
|
|
10
|
-
// prefix: Prefix,
|
|
11
|
-
// workflow: WF,
|
|
12
|
-
// resolveInput: WorkflowInput<WF> extends undefined
|
|
13
|
-
// ?
|
|
14
|
-
// | ((ctx: {
|
|
15
|
-
// input: Input;
|
|
16
|
-
// results: Results;
|
|
17
|
-
// context: Context;
|
|
18
|
-
// }) => WorkflowInput<WF>)
|
|
19
|
-
// | undefined
|
|
20
|
-
// : (ctx: {
|
|
21
|
-
// input: Input;
|
|
22
|
-
// results: Results;
|
|
23
|
-
// context: Context;
|
|
24
|
-
// }) => WorkflowInput<WF>,
|
|
25
|
-
// options?: StepOptions<Input, Results, Context>,
|
|
26
|
-
// ): WorkflowBuilder<
|
|
27
|
-
// Reg,
|
|
28
|
-
// Input,
|
|
29
|
-
// Context,
|
|
30
|
-
// [...Steps, ...WF["steps"]],
|
|
31
|
-
// Results & {
|
|
32
|
-
// [K in Prefix]: SubflowResult<WorkflowResults<WF>, WorkflowOutput<WF>>;
|
|
33
|
-
// }
|
|
34
|
-
// > {
|
|
35
|
-
// const idMap = new Map<string, string>();
|
|
36
|
-
//
|
|
37
|
-
// workflow.steps.forEach((step) => {
|
|
38
|
-
// idMap.set(step.id, `${prefix}.${step.id}`);
|
|
39
|
-
// });
|
|
40
|
-
//
|
|
41
|
-
// workflow.steps.forEach((step) => {
|
|
42
|
-
// const newStep: StepDef<Reg, any, any> = {
|
|
43
|
-
// ...step,
|
|
44
|
-
// id: idMap.get(step.id)!,
|
|
45
|
-
// dependsOn: step.dependsOn.map((d) => idMap.get(d)!),
|
|
46
|
-
// resolve: (ctx: any) => {
|
|
47
|
-
// const subInput = resolveInput ? resolveInput(ctx) : undefined;
|
|
48
|
-
// return step.resolve({
|
|
49
|
-
// input: subInput,
|
|
50
|
-
// results: ctx.results,
|
|
51
|
-
// context: ctx.context,
|
|
52
|
-
// });
|
|
53
|
-
// },
|
|
54
|
-
// };
|
|
55
|
-
//
|
|
56
|
-
// if (workflow.entrySteps.find((e) => e.id === step.id)) {
|
|
57
|
-
// newStep.dependsOn = [...this.frontier];
|
|
58
|
-
// }
|
|
59
|
-
//
|
|
60
|
-
// this.steps.push(newStep);
|
|
61
|
-
// });
|
|
62
|
-
//
|
|
63
|
-
// this.frontier = workflow.endSteps.map((e) => idMap.get(e.id)!);
|
|
64
|
-
// return this as any;
|
|
65
|
-
// }
|
|
66
|
-
//
|
|
67
|
-
// /* ------------------------------------------------ */
|
|
68
|
-
// /* Conditional */
|
|
69
|
-
// /* ------------------------------------------------ */
|
|
70
|
-
//
|
|
71
1
|
import { generateWorkflowId } from "./utils.js";
|
|
2
|
+
import { PipeBuilder, } from "./workflow-composer-pipe.js";
|
|
72
3
|
/* ------------------------------------------------ */
|
|
73
4
|
/* FLUENT WORKFLOW BUILDER */
|
|
74
5
|
/* ------------------------------------------------ */
|
|
@@ -117,6 +48,29 @@ export class WorkflowBuilder {
|
|
|
117
48
|
this.frontier = [id];
|
|
118
49
|
return this;
|
|
119
50
|
}
|
|
51
|
+
/* ----------------------- */
|
|
52
|
+
/* Pipe */
|
|
53
|
+
/* ----------------------- */
|
|
54
|
+
pipe(id, input, builder, options) {
|
|
55
|
+
const deps = [...this.frontier];
|
|
56
|
+
const pb = new PipeBuilder();
|
|
57
|
+
const built = builder(pb);
|
|
58
|
+
const steps = built.getSteps();
|
|
59
|
+
this.steps.push({
|
|
60
|
+
id,
|
|
61
|
+
action: "__pipe__",
|
|
62
|
+
pipe: {
|
|
63
|
+
input,
|
|
64
|
+
steps,
|
|
65
|
+
},
|
|
66
|
+
dependsOn: deps,
|
|
67
|
+
when: this.pendingWhen,
|
|
68
|
+
resolve: () => ({ kind: "none" }),
|
|
69
|
+
options,
|
|
70
|
+
});
|
|
71
|
+
this.frontier = [id];
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
120
74
|
/* ------------------------------------------------ */
|
|
121
75
|
/* Override the result of the last step */
|
|
122
76
|
/* ------------------------------------------------ */
|
|
@@ -12,10 +12,6 @@ export declare function createCallHelpers(): {
|
|
|
12
12
|
none: () => {
|
|
13
13
|
kind: string;
|
|
14
14
|
};
|
|
15
|
-
loop: (items: any[]) => {
|
|
16
|
-
kind: string;
|
|
17
|
-
items: any[];
|
|
18
|
-
};
|
|
19
15
|
};
|
|
20
16
|
export declare function executeWorkflow<Reg extends ActionRegistry, I, R, O = R>({ workflow, actionRegistry, services, input, depsExecutors, observers, }: {
|
|
21
17
|
workflow: WorkflowDef<Reg, I, any, any, O>;
|
|
@@ -4,10 +4,8 @@ export function createCallHelpers() {
|
|
|
4
4
|
args: (...args) => ({ kind: "positional", args }),
|
|
5
5
|
obj: (arg) => ({ kind: "object", args: arg }),
|
|
6
6
|
none: () => ({ kind: "none" }),
|
|
7
|
-
loop: (items) => ({ kind: "loop", items }),
|
|
8
7
|
};
|
|
9
8
|
}
|
|
10
|
-
// Helper to wrap action execution with timeout
|
|
11
9
|
async function withTimeout(promise, ms) {
|
|
12
10
|
if (!ms)
|
|
13
11
|
return promise;
|
|
@@ -77,8 +75,6 @@ export async function executeWorkflow({ workflow, actionRegistry, services, inpu
|
|
|
77
75
|
return await action(...input.args);
|
|
78
76
|
case "object":
|
|
79
77
|
return await action(input.args);
|
|
80
|
-
case "loop":
|
|
81
|
-
return await Promise.all(input.items.map((item) => runAction(item, action)));
|
|
82
78
|
default:
|
|
83
79
|
throw new Error(`Unknown ResolvedStepInput kind: ${input.kind}`);
|
|
84
80
|
}
|
|
@@ -125,20 +121,47 @@ export async function executeWorkflow({ workflow, actionRegistry, services, inpu
|
|
|
125
121
|
return undefined;
|
|
126
122
|
}
|
|
127
123
|
// -----------------------------
|
|
128
|
-
//
|
|
124
|
+
// Pipe handling
|
|
129
125
|
// -----------------------------
|
|
126
|
+
if (step.pipe && step.pipe.steps) {
|
|
127
|
+
const items = step.pipe.input(stepCtx);
|
|
128
|
+
const pipeResults = await Promise.all(items.map(async (item) => {
|
|
129
|
+
let current = item;
|
|
130
|
+
for (const pipeStep of step.pipe.steps) {
|
|
131
|
+
const pipeCtx = {
|
|
132
|
+
current,
|
|
133
|
+
results,
|
|
134
|
+
...createCallHelpers(),
|
|
135
|
+
};
|
|
136
|
+
const resolved = pipeStep.resolve(pipeCtx);
|
|
137
|
+
let action;
|
|
138
|
+
if (pipeStep.type === "action") {
|
|
139
|
+
action = actionRegistry[pipeStep.action];
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
action = services[pipeStep.service][pipeStep.method];
|
|
143
|
+
}
|
|
144
|
+
if (!action) {
|
|
145
|
+
throw new Error(`Unknown ${pipeStep.type} in pipe step: ${pipeStep.type === "action"
|
|
146
|
+
? pipeStep.action
|
|
147
|
+
: `${pipeStep.service}.${pipeStep.method}`}`);
|
|
148
|
+
}
|
|
149
|
+
current = await runAction(resolved, action);
|
|
150
|
+
}
|
|
151
|
+
return current;
|
|
152
|
+
}));
|
|
153
|
+
results[step.id] = pipeResults;
|
|
154
|
+
frame.output = pipeResults;
|
|
155
|
+
frame.end = Date.now();
|
|
156
|
+
return pipeResults;
|
|
157
|
+
}
|
|
130
158
|
if (step.__subflowId) {
|
|
159
|
+
// -----------------------------
|
|
160
|
+
// Subflow handling
|
|
161
|
+
// -----------------------------
|
|
131
162
|
const [modId, subWfId] = step.__subflowId.split(".");
|
|
132
163
|
const exec = depsExecutors[modId];
|
|
133
164
|
const subExecution = await exec.run(subWfId, resolvedArgs, services, observers);
|
|
134
|
-
// const subExecution = await executeWorkflow(
|
|
135
|
-
// step.__subflowId,
|
|
136
|
-
// workflowRegistry,
|
|
137
|
-
// actionRegistry,
|
|
138
|
-
// resolvedArgs as any,
|
|
139
|
-
// context,
|
|
140
|
-
// observers,
|
|
141
|
-
// );
|
|
142
165
|
frame.output = subExecution.output;
|
|
143
166
|
frame.end = Date.now();
|
|
144
167
|
results[step.id] = subExecution.output;
|
package/dist/workflow-module.js
CHANGED
|
@@ -1,260 +1,3 @@
|
|
|
1
|
-
// ActionRegistry,
|
|
2
|
-
// import {
|
|
3
|
-
// Executor,
|
|
4
|
-
// Simplify,
|
|
5
|
-
// WorkflowObserver,
|
|
6
|
-
// } from "./types.js";
|
|
7
|
-
// import { createWorkflow, WorkflowDef } from "./workflow-composer.js";
|
|
8
|
-
// import { executeWorkflow } from "./workflow-executor.js";
|
|
9
|
-
// type UnionToIntersection<U> = (U extends any ? (x: U) => any : never) extends (
|
|
10
|
-
// x: infer I,
|
|
11
|
-
// ) => any
|
|
12
|
-
// ? I
|
|
13
|
-
// : never;
|
|
14
|
-
// /* ------------------------------------------------ */
|
|
15
|
-
// /* WORKFLOW REGISTRY TYPES */
|
|
16
|
-
// /* ------------------------------------------------ */
|
|
17
|
-
// type EnsureWorkflowRecord<T> =
|
|
18
|
-
// T extends Record<string, WorkflowDef<any, any, any, any, any>>
|
|
19
|
-
// ? T
|
|
20
|
-
// : Record<string, WorkflowDef<any, any, any, any, any>>;
|
|
21
|
-
//
|
|
22
|
-
// type EnsureWorkflowShape<T> = {
|
|
23
|
-
// [K in keyof T]: T[K] extends WorkflowDef<any, any, any, any, any>
|
|
24
|
-
// ? T[K]
|
|
25
|
-
// : never;
|
|
26
|
-
// };
|
|
27
|
-
//
|
|
28
|
-
// type DepWorkflows<Deps extends ModuleMap> = keyof Deps extends never
|
|
29
|
-
// ? {}
|
|
30
|
-
// : Simplify<
|
|
31
|
-
// EnsureWorkflowShape<
|
|
32
|
-
// UnionToIntersection<
|
|
33
|
-
// {
|
|
34
|
-
// [D in keyof Deps & string]: {
|
|
35
|
-
// [K in keyof Deps[D]["workflows"] &
|
|
36
|
-
// string as `${D}.${K}`]: Deps[D]["workflows"][K];
|
|
37
|
-
// };
|
|
38
|
-
// }[keyof Deps & string]
|
|
39
|
-
// >
|
|
40
|
-
// >
|
|
41
|
-
// >;
|
|
42
|
-
//
|
|
43
|
-
// type WorkflowRegistry<Own extends ModuleShape, Deps extends ModuleMap> = Own &
|
|
44
|
-
// DepWorkflows<Deps>;
|
|
45
|
-
//
|
|
46
|
-
// /* ------------------------------------------------ */
|
|
47
|
-
// /* MODULE TYPES */
|
|
48
|
-
// /* ------------------------------------------------ */
|
|
49
|
-
//
|
|
50
|
-
// type AnyWorkflow = WorkflowDef<any, any, any, any, any>;
|
|
51
|
-
// type ModuleShape = Record<string, AnyWorkflow>;
|
|
52
|
-
// type ModuleMap = Record<string, Module<any, any, any, any>>;
|
|
53
|
-
//
|
|
54
|
-
// // type ContextFromDeps<Deps> = [keyof Deps] extends [never]
|
|
55
|
-
// // ? {}
|
|
56
|
-
// // : {
|
|
57
|
-
// // [K in keyof Deps]: Deps[K] extends Module<any, infer Ctx, any, any>
|
|
58
|
-
// // ? Ctx
|
|
59
|
-
// // : never;
|
|
60
|
-
// // }[keyof Deps];
|
|
61
|
-
//
|
|
62
|
-
// type FinalContext<
|
|
63
|
-
// Context extends Record<string, any>,
|
|
64
|
-
// Deps extends ModuleMap,
|
|
65
|
-
// > = Context & ContextFromDepsRecursive<Deps>;
|
|
66
|
-
//
|
|
67
|
-
// // type ContextFromDeps<Deps> = [keyof Deps] extends [never]
|
|
68
|
-
// // ? {}
|
|
69
|
-
// // : UnionToIntersection<
|
|
70
|
-
// // {
|
|
71
|
-
// // [K in keyof Deps]: Deps[K] extends Module<any, infer Ctx, any, any>
|
|
72
|
-
// // ? Ctx
|
|
73
|
-
// // : never;
|
|
74
|
-
// // }[keyof Deps]
|
|
75
|
-
// // >;
|
|
76
|
-
//
|
|
77
|
-
// type ContextFromDepsRecursive<Deps extends ModuleMap> = [keyof Deps] extends [
|
|
78
|
-
// never,
|
|
79
|
-
// ]
|
|
80
|
-
// ? {} // no deps
|
|
81
|
-
// : UnionToIntersection<
|
|
82
|
-
// {
|
|
83
|
-
// [K in keyof Deps]: Deps[K] extends Module<
|
|
84
|
-
// any,
|
|
85
|
-
// infer Ctx,
|
|
86
|
-
// any,
|
|
87
|
-
// infer SubDeps
|
|
88
|
-
// >
|
|
89
|
-
// ? Ctx & ContextFromDepsRecursive<SubDeps>
|
|
90
|
-
// : never;
|
|
91
|
-
// }[keyof Deps]
|
|
92
|
-
// >;
|
|
93
|
-
//
|
|
94
|
-
// /* ------------------------------------------------ */
|
|
95
|
-
// /* WORKFLOW IO TYPES */
|
|
96
|
-
// /* ------------------------------------------------ */
|
|
97
|
-
//
|
|
98
|
-
// export type WorkflowInput<W> =
|
|
99
|
-
// W extends WorkflowDef<any, infer I, any, any, any> ? I : never;
|
|
100
|
-
//
|
|
101
|
-
// export type WorkflowResults<W> =
|
|
102
|
-
// W extends WorkflowDef<any, any, infer R, any, any> ? R : never;
|
|
103
|
-
//
|
|
104
|
-
// export type WorkflowOutput<W> =
|
|
105
|
-
// W extends WorkflowDef<any, any, any, any, infer O> ? O : never;
|
|
106
|
-
//
|
|
107
|
-
// /* ------------------------------------------------ */
|
|
108
|
-
// /* MODULE RUNTIME */
|
|
109
|
-
// /* ------------------------------------------------ */
|
|
110
|
-
//
|
|
111
|
-
// type Module<
|
|
112
|
-
// Reg extends ActionRegistry,
|
|
113
|
-
// Context extends Record<string, any>,
|
|
114
|
-
// Own extends ModuleShape,
|
|
115
|
-
// Deps extends ModuleMap,
|
|
116
|
-
// > = {
|
|
117
|
-
// workflows: Own;
|
|
118
|
-
// __getExecutor: () => Executor;
|
|
119
|
-
//
|
|
120
|
-
// createRuntime: (config: { context: FinalContext<Context, Deps> }) => {
|
|
121
|
-
// run: <K extends keyof WorkflowRegistry<Own, Deps>>(
|
|
122
|
-
// workflow: K,
|
|
123
|
-
// input: WorkflowInput<WorkflowRegistry<Own, Deps>[K]>,
|
|
124
|
-
// observers?: WorkflowObserver<Reg>[],
|
|
125
|
-
// ) => Promise<{
|
|
126
|
-
// // results: WorkflowResults<WorkflowRegistry<Own, Deps>[K]>;
|
|
127
|
-
// output: WorkflowOutput<WorkflowRegistry<Own, Deps>[K]>;
|
|
128
|
-
// extras: Record<string, any>;
|
|
129
|
-
// }>;
|
|
130
|
-
//
|
|
131
|
-
// getContext: () => FinalContext<Context, Deps>;
|
|
132
|
-
// };
|
|
133
|
-
// };
|
|
134
|
-
//
|
|
135
|
-
// /* ------------------------------------------------ */
|
|
136
|
-
// /* MODULE CONTEXT (FIXED) */
|
|
137
|
-
// /* ------------------------------------------------ */
|
|
138
|
-
//
|
|
139
|
-
// type ModuleContext<
|
|
140
|
-
// Reg extends ActionRegistry,
|
|
141
|
-
// WFReg extends Record<string, WorkflowDef<any, any, any, any, any>>,
|
|
142
|
-
// Context extends Record<string, any>,
|
|
143
|
-
// > = {
|
|
144
|
-
// wf: ReturnType<typeof createWorkflow<Reg, WFReg, Context>>;
|
|
145
|
-
// context: Context;
|
|
146
|
-
// };
|
|
147
|
-
//
|
|
148
|
-
// function createModule<
|
|
149
|
-
// Reg extends ActionRegistry,
|
|
150
|
-
// Context extends Record<string, any>,
|
|
151
|
-
// Use extends ModuleMap,
|
|
152
|
-
// Own extends ModuleShape,
|
|
153
|
-
// >(config: {
|
|
154
|
-
// actionRegistry: Reg;
|
|
155
|
-
// use?: Use;
|
|
156
|
-
// define: (ctx: ModuleContext<Reg, DepWorkflows<Use>, Context>) => Own;
|
|
157
|
-
// }): Module<Reg, Context, Own, Use> {
|
|
158
|
-
// const deps = (config.use ?? {}) as Use;
|
|
159
|
-
//
|
|
160
|
-
// const wf = createWorkflow<Reg, DepWorkflows<Use>, Context>();
|
|
161
|
-
//
|
|
162
|
-
// const own = config.define({
|
|
163
|
-
// wf,
|
|
164
|
-
// context: {} as Context,
|
|
165
|
-
// });
|
|
166
|
-
//
|
|
167
|
-
// function buildWorkflowMap(): WorkflowRegistry<Own, Use> {
|
|
168
|
-
// const depWFs = Object.fromEntries(
|
|
169
|
-
// Object.entries(deps).flatMap(([name, mod]) =>
|
|
170
|
-
// Object.entries(mod.workflows).map(([k, wf]) => [`${name}.${k}`, wf]),
|
|
171
|
-
// ),
|
|
172
|
-
// );
|
|
173
|
-
//
|
|
174
|
-
// return { ...own, ...depWFs } as WorkflowRegistry<Own, Use>;
|
|
175
|
-
// }
|
|
176
|
-
//
|
|
177
|
-
// const workflowMap = buildWorkflowMap();
|
|
178
|
-
//
|
|
179
|
-
// const depsExecutors = Object.fromEntries(
|
|
180
|
-
// Object.entries(deps).map(([name, mod]) => [name, mod.__getExecutor()]),
|
|
181
|
-
// );
|
|
182
|
-
//
|
|
183
|
-
// const executor: Executor = {
|
|
184
|
-
// run(wfId, input, context, observers = []) {
|
|
185
|
-
// const workflow = workflowMap[wfId];
|
|
186
|
-
//
|
|
187
|
-
// if (!workflow) {
|
|
188
|
-
// throw new Error(`Workflow not found: ${String(wfId)}`);
|
|
189
|
-
// }
|
|
190
|
-
//
|
|
191
|
-
// return executeWorkflow({
|
|
192
|
-
// workflow,
|
|
193
|
-
// actionRegistry: config.actionRegistry,
|
|
194
|
-
// depsExecutors,
|
|
195
|
-
// input,
|
|
196
|
-
// context,
|
|
197
|
-
// observers,
|
|
198
|
-
// });
|
|
199
|
-
// },
|
|
200
|
-
// };
|
|
201
|
-
//
|
|
202
|
-
// return {
|
|
203
|
-
// workflows: own,
|
|
204
|
-
// __getExecutor: () => executor,
|
|
205
|
-
//
|
|
206
|
-
// createRuntime({ services }) {
|
|
207
|
-
// let runtimeActions = config.actionRegistry;
|
|
208
|
-
//
|
|
209
|
-
// // const runtimeService = createServiceRegisty(services)
|
|
210
|
-
// return {
|
|
211
|
-
// run: async <K extends keyof WorkflowRegistry<Own, Use>>(
|
|
212
|
-
// workflowId: K,
|
|
213
|
-
// input: WorkflowInput<WorkflowRegistry<Own, Use>[K]>,
|
|
214
|
-
// observers: WorkflowObserver<Reg>[] = [],
|
|
215
|
-
// ) => {
|
|
216
|
-
// return executor.run(workflowId as string, input, context, observers);
|
|
217
|
-
// },
|
|
218
|
-
// // make it same, practically nothing changes but naming, and what context holds
|
|
219
|
-
// getContext: () => ({ ...context }) as FinalContext<Context, Use>,
|
|
220
|
-
//
|
|
221
|
-
// setActionRegistry(reg: Reg) {
|
|
222
|
-
// runtimeActions = reg;
|
|
223
|
-
// // ⚠️ optional: if you REALLY want override, you'd need:
|
|
224
|
-
// // executor.actions = reg
|
|
225
|
-
// // but better keep actions immutable
|
|
226
|
-
// },
|
|
227
|
-
// };
|
|
228
|
-
// },
|
|
229
|
-
// };
|
|
230
|
-
// }
|
|
231
|
-
//
|
|
232
|
-
// /* ------------------------------------------------ */
|
|
233
|
-
// /* FACTORY (FIXED) */
|
|
234
|
-
// /* ------------------------------------------------ */
|
|
235
|
-
//
|
|
236
|
-
// export function createModuleFactory<
|
|
237
|
-
// // Reg extends ActionRegistry,
|
|
238
|
-
// Context extends Record<string, any>,
|
|
239
|
-
// >() {
|
|
240
|
-
// return function <
|
|
241
|
-
// Reg extends ActionRegistry = Record<string, any>,
|
|
242
|
-
// Use extends ModuleMap = {},
|
|
243
|
-
// Own extends ModuleShape = {},
|
|
244
|
-
// >(config: {
|
|
245
|
-
// actionRegistry: Reg;
|
|
246
|
-
// use?: Use;
|
|
247
|
-
// define: (
|
|
248
|
-
// ctx: ModuleContext<
|
|
249
|
-
// typeof config.actionRegistry,
|
|
250
|
-
// DepWorkflows<Use>,
|
|
251
|
-
// Context
|
|
252
|
-
// >, // ✅ FIXED HERE
|
|
253
|
-
// ) => Own;
|
|
254
|
-
// }): Module<Reg, Context, Own, Use> {
|
|
255
|
-
// return createModule<Reg, Context, Use, Own>(config);
|
|
256
|
-
// };
|
|
257
|
-
// }
|
|
258
1
|
import { createWorkflow } from "./workflow-composer.js";
|
|
259
2
|
import { executeWorkflow } from "./workflow-executor.js";
|
|
260
3
|
function createModule(config) {
|