@pogodisco/zephyr 1.4.2 → 1.5.1
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 +4 -1
- package/dist/workflow-composer.d.ts +59 -27
- package/dist/workflow-composer.js +17 -0
- package/dist/workflow-executor.d.ts +3 -3
- package/dist/workflow-executor.js +11 -6
- package/dist/workflow-module.d.ts +13 -13
- package/dist/workflow-module.js +265 -6
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -27,5 +27,8 @@ export type WorkflowObserver<Reg extends ActionRegistry = any> = {
|
|
|
27
27
|
}, next: () => Promise<any>): Promise<any>;
|
|
28
28
|
};
|
|
29
29
|
export interface Executor {
|
|
30
|
-
run: (wfId: string, input: Record<string, any>,
|
|
30
|
+
run: (wfId: string, input: Record<string, any>, services: ServiceRegistry, obsververs?: WorkflowObserver[]) => Promise<any>;
|
|
31
31
|
}
|
|
32
|
+
export type ServiceRegistry = Record<string, Record<string, (...args: any[]) => any>>;
|
|
33
|
+
export type ServiceParams<S extends ServiceRegistry, K extends keyof S, M extends keyof S[K]> = Parameters<S[K][M]>;
|
|
34
|
+
export type ServiceReturn<S extends ServiceRegistry, K extends keyof S, M extends keyof S[K]> = Awaited<ReturnType<S[K][M]>>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ActionParams, ActionRegistry, ActionReturn, Simplify } from "./types.js";
|
|
1
|
+
import { ActionParams, ActionRegistry, ActionReturn, ServiceParams, ServiceRegistry, ServiceReturn, Simplify } from "./types.js";
|
|
2
2
|
type NormalizedCall = {
|
|
3
3
|
kind: "none";
|
|
4
4
|
} | {
|
|
@@ -40,14 +40,18 @@ type WorkflowOutput<T> = T extends WorkflowDef<any, any, any, any, infer O> ? un
|
|
|
40
40
|
export type StepResultFromResolve<Reg extends ActionRegistry, ActionName extends keyof Reg, R extends ResolvedStepInput> = R extends {
|
|
41
41
|
kind: "loop";
|
|
42
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>;
|
|
43
46
|
export type StepDef<Reg extends ActionRegistry, ID extends string = string, ActionName extends keyof Reg = any> = {
|
|
44
47
|
id: ID;
|
|
45
|
-
action: ActionName;
|
|
48
|
+
action: ActionName | "__service__";
|
|
46
49
|
dependsOn: string[];
|
|
47
50
|
resolve: (ctx: any) => ResolvedStepInput;
|
|
48
51
|
when?: (ctx: any) => boolean;
|
|
49
|
-
options?: StepOptions<any, any
|
|
52
|
+
options?: StepOptions<any, any>;
|
|
50
53
|
__subflowId?: string;
|
|
54
|
+
serviceCall?: ServiceCall;
|
|
51
55
|
};
|
|
52
56
|
export type WorkflowDef<Reg extends ActionRegistry, Input, Results, Steps extends StepDef<Reg, any, any>[] = StepDef<Reg, any, any>[], Output = undefined> = {
|
|
53
57
|
name: string;
|
|
@@ -59,27 +63,30 @@ export type WorkflowDef<Reg extends ActionRegistry, Input, Results, Steps extend
|
|
|
59
63
|
results: Results;
|
|
60
64
|
outputResolver?: (ctx: any) => Output;
|
|
61
65
|
};
|
|
62
|
-
type StepRuntimeCtx<I, R
|
|
66
|
+
type StepRuntimeCtx<I, R> = {
|
|
63
67
|
input: I;
|
|
64
68
|
results: R;
|
|
65
|
-
context: C;
|
|
66
69
|
};
|
|
67
|
-
type StepOptions<Input, Results
|
|
70
|
+
type StepOptions<Input, Results> = {
|
|
68
71
|
retry?: number;
|
|
69
72
|
retryDelay?: number | ((attempt: number) => number);
|
|
70
73
|
timeout?: number;
|
|
71
74
|
continueOnError?: boolean;
|
|
72
|
-
onError?: (err: unknown, ctx: StepRuntimeCtx<Input, Results
|
|
75
|
+
onError?: (err: unknown, ctx: StepRuntimeCtx<Input, Results>) => any;
|
|
73
76
|
label?: string;
|
|
74
77
|
meta?: Record<string, any>;
|
|
75
78
|
};
|
|
76
|
-
type
|
|
79
|
+
type ServiceCall = {
|
|
80
|
+
service: string;
|
|
81
|
+
method: string;
|
|
82
|
+
};
|
|
83
|
+
type MergeBranchResults<Branches extends readonly any[], Acc> = Branches extends readonly [infer Head, ...infer Tail] ? MergeBranchResults<Tail, Acc & (Head extends WorkflowBuilder<any, any, any, any, any, infer Results> ? Results : {})> : Acc;
|
|
77
84
|
type MergeBranchSteps<Branches extends readonly any[], Acc extends any[]> = Branches extends readonly [infer Head, ...infer Tail] ? MergeBranchSteps<Tail, [
|
|
78
85
|
...Acc,
|
|
79
|
-
...(Head extends WorkflowBuilder<any, any, any, any, infer
|
|
86
|
+
...(Head extends WorkflowBuilder<any, any, any, any, infer Steps, any> ? Steps : [])
|
|
80
87
|
]> : Acc;
|
|
81
|
-
export declare class WorkflowBuilder<Reg extends ActionRegistry, WFReg extends Record<string, WorkflowDef<any, any, any, any, any>>, //
|
|
82
|
-
Input = unknown,
|
|
88
|
+
export declare class WorkflowBuilder<Reg extends ActionRegistry, Services extends ServiceRegistry, WFReg extends Record<string, WorkflowDef<any, any, any, any, any>>, //
|
|
89
|
+
Input = unknown, Steps extends StepDef<Reg, any, any>[] = [], Results = {}, Output = undefined> {
|
|
83
90
|
private name;
|
|
84
91
|
private steps;
|
|
85
92
|
private frontier;
|
|
@@ -90,8 +97,7 @@ Input = unknown, Context = unknown, Steps extends StepDef<Reg, any, any>[] = [],
|
|
|
90
97
|
step<ID extends string, ActionName extends keyof Reg & string, ResolveOut extends ResolvedStepInput = ResolvedStepInput>(id: ID, action: ActionName, resolve?: (ctx: {
|
|
91
98
|
input: Input;
|
|
92
99
|
results: Results;
|
|
93
|
-
|
|
94
|
-
} & CallHelpers<Reg, ActionName>) => ResolveOut, dependsOn?: string[], options?: StepOptions<Input, Results, Context>): WorkflowBuilder<Reg, WFReg, Input, Context, [
|
|
100
|
+
} & CallHelpers<Reg, ActionName>) => ResolveOut, dependsOn?: string[], options?: StepOptions<Input, Results>): WorkflowBuilder<Reg, Services, WFReg, Input, [
|
|
95
101
|
...Steps,
|
|
96
102
|
StepDef<Reg, ID, ActionName>
|
|
97
103
|
], Simplify<Results & {
|
|
@@ -100,41 +106,67 @@ Input = unknown, Context = unknown, Steps extends StepDef<Reg, any, any>[] = [],
|
|
|
100
106
|
seq<ID extends string = string, ActionName extends keyof Reg & string = any, ResolveOut extends ResolvedStepInput = ResolvedStepInput>(id: ID, action: ActionName, resolve?: (ctx: {
|
|
101
107
|
input: Input;
|
|
102
108
|
results: Results;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
109
|
+
} & CallHelpers<Reg, ActionName>) => ResolveOut, options?: StepOptions<Input, Results>): WorkflowBuilder<Reg, Services, WFReg, Input, [...Steps, StepDef<Reg, ID, ActionName>], Results & { [K_1 in ID]: StepResultFromResolve<Reg, ActionName, ResolveOut>; } extends infer T ? { [K in keyof T]: T[K]; } : never, undefined>;
|
|
110
|
+
service<ID extends string, SK extends keyof Services & string, MK extends keyof Services[SK] & string, ResolveOut extends NormalizedCall = NormalizedCall>(id: ID, service: SK, method: MK, resolve?: (ctx: {
|
|
111
|
+
input: Input;
|
|
112
|
+
results: Results;
|
|
113
|
+
} & {
|
|
114
|
+
args: (...args: ServiceParams<Services, SK, MK>) => {
|
|
115
|
+
kind: "positional";
|
|
116
|
+
args: ServiceParams<Services, SK, MK>;
|
|
117
|
+
};
|
|
118
|
+
obj: ServiceParams<Services, SK, MK> extends [infer A] ? (arg: A) => {
|
|
119
|
+
kind: "object";
|
|
120
|
+
args: A;
|
|
121
|
+
} : never;
|
|
122
|
+
none: () => {
|
|
123
|
+
kind: "none";
|
|
124
|
+
};
|
|
125
|
+
loop: (items: {
|
|
126
|
+
kind: "positional";
|
|
127
|
+
args: ServiceParams<Services, SK, MK>;
|
|
128
|
+
}[] | {
|
|
129
|
+
kind: "object";
|
|
130
|
+
args: ServiceParams<Services, SK, MK>[0];
|
|
131
|
+
}[]) => {
|
|
132
|
+
kind: "loop";
|
|
133
|
+
items: typeof items;
|
|
134
|
+
};
|
|
135
|
+
}) => ResolveOut, options?: StepOptions<Input, Results>): WorkflowBuilder<Reg, Services, WFReg, Input, [
|
|
136
|
+
...Steps,
|
|
137
|
+
StepDef<Reg, ID, any>
|
|
138
|
+
], Simplify<Results & {
|
|
139
|
+
[K in ID]: ServiceStepResultFromResolve<Services, SK, MK, ResolveOut>;
|
|
140
|
+
}>>;
|
|
141
|
+
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> & {
|
|
106
142
|
[K in ID]: NewType;
|
|
107
143
|
}> : Results : Results, Output>;
|
|
108
|
-
parallel<Branches extends readonly WorkflowBuilder<Reg, WFReg, Input,
|
|
109
|
-
[K in keyof Branches]: (builder: WorkflowBuilder<Reg, WFReg, Input,
|
|
110
|
-
}): WorkflowBuilder<Reg, WFReg, Input,
|
|
144
|
+
parallel<Branches extends readonly WorkflowBuilder<Reg, Services, WFReg, Input, any, any>[]>(...branches: {
|
|
145
|
+
[K in keyof Branches]: (builder: WorkflowBuilder<Reg, Services, WFReg, Input, [], Results>) => Branches[K];
|
|
146
|
+
}): WorkflowBuilder<Reg, Services, WFReg, Input, MergeBranchSteps<Branches, Steps>, Simplify<MergeBranchResults<Branches, Results>>>;
|
|
111
147
|
join<ID extends string = string, ActionName extends keyof Reg & string = any, ResolveOut extends ResolvedStepInput = ResolvedStepInput>(id: ID, action: ActionName, resolve?: (ctx: {
|
|
112
148
|
input: Input;
|
|
113
149
|
results: Results;
|
|
114
|
-
|
|
115
|
-
} & CallHelpers<Reg, ActionName>) => ResolveOut, options?: StepOptions<Input, Results, Context>): WorkflowBuilder<Reg, WFReg, Input, Context, [...Steps, StepDef<Reg, ID, ActionName>], Results & { [K_1 in ID]: StepResultFromResolve<Reg, ActionName, ResolveOut>; } extends infer T ? { [K in keyof T]: T[K]; } : never, undefined>;
|
|
150
|
+
} & CallHelpers<Reg, ActionName>) => ResolveOut, options?: StepOptions<Input, Results>): WorkflowBuilder<Reg, Services, WFReg, Input, [...Steps, StepDef<Reg, ID, ActionName>], Results & { [K_1 in ID]: StepResultFromResolve<Reg, ActionName, ResolveOut>; } extends infer T ? { [K in keyof T]: T[K]; } : never, undefined>;
|
|
116
151
|
subflow<Prefix extends string, K extends keyof WFReg & string>(prefix: Prefix, workflowKey: K, resolveInput: (ctx: {
|
|
117
152
|
input: Input;
|
|
118
153
|
results: Results;
|
|
119
|
-
|
|
120
|
-
}) => WorkflowInput<WFReg[K]>, options?: StepOptions<Input, Results, Context>): WorkflowBuilder<Reg, WFReg, Input, Context, Steps, Results & {
|
|
154
|
+
}) => WorkflowInput<WFReg[K]>, options?: StepOptions<Input, Results>): WorkflowBuilder<Reg, Services, WFReg, Input, Steps, Results & {
|
|
121
155
|
[P in Prefix]: WorkflowOutput<WFReg[K]>;
|
|
122
156
|
}>;
|
|
123
157
|
when(predicate: (ctx: {
|
|
124
158
|
input: Input;
|
|
125
159
|
results: Results;
|
|
126
|
-
|
|
127
|
-
}) => boolean): WorkflowBuilder<Reg, WFReg, Input, Context, Steps, Results, Output>;
|
|
160
|
+
}) => boolean): WorkflowBuilder<Reg, Services, WFReg, Input, Steps, Results, Output>;
|
|
128
161
|
endWhen(): this;
|
|
129
162
|
output<Output>(fn: (ctx: {
|
|
130
163
|
input: Input;
|
|
131
164
|
results: Results;
|
|
132
|
-
context: Context;
|
|
133
165
|
}) => Output): WorkflowDef<Reg, Input, Results, Steps, Output>;
|
|
134
166
|
build(): WorkflowDef<Reg, Input, Results, Steps>;
|
|
135
167
|
private validateDependencies;
|
|
136
168
|
private getEndSteps;
|
|
137
169
|
}
|
|
138
170
|
export declare function createWorkflow<Reg extends ActionRegistry, WFReg extends Record<string, WorkflowDef<any, any, any, any, any>>, // 👈 NEW
|
|
139
|
-
|
|
171
|
+
Services extends ServiceRegistry>(): <Input = unknown>(name: string) => WorkflowBuilder<Reg, Services, WFReg, Input, [], {}, undefined>;
|
|
140
172
|
export {};
|
|
@@ -100,6 +100,23 @@ export class WorkflowBuilder {
|
|
|
100
100
|
seq(id, action, resolve, options) {
|
|
101
101
|
return this.step(id, action, resolve, undefined, options);
|
|
102
102
|
}
|
|
103
|
+
service(id, service, method, resolve, options) {
|
|
104
|
+
const deps = [...this.frontier];
|
|
105
|
+
this.steps.push({
|
|
106
|
+
id,
|
|
107
|
+
action: "__service__",
|
|
108
|
+
serviceCall: {
|
|
109
|
+
service,
|
|
110
|
+
method,
|
|
111
|
+
},
|
|
112
|
+
resolve: resolve ?? (() => ({ kind: "none" })),
|
|
113
|
+
dependsOn: deps,
|
|
114
|
+
when: this.pendingWhen,
|
|
115
|
+
options,
|
|
116
|
+
});
|
|
117
|
+
this.frontier = [id];
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
103
120
|
/* ------------------------------------------------ */
|
|
104
121
|
/* Override the result of the last step */
|
|
105
122
|
/* ------------------------------------------------ */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ActionRegistry, Executor, WorkflowObserver } from "./types.js";
|
|
1
|
+
import { ActionRegistry, Executor, ServiceRegistry, WorkflowObserver } from "./types.js";
|
|
2
2
|
import { WorkflowDef } from "./workflow-composer.js";
|
|
3
3
|
export declare function createCallHelpers(): {
|
|
4
4
|
args: (...args: any[]) => {
|
|
@@ -17,11 +17,11 @@ export declare function createCallHelpers(): {
|
|
|
17
17
|
items: any[];
|
|
18
18
|
};
|
|
19
19
|
};
|
|
20
|
-
export declare function executeWorkflow<Reg extends ActionRegistry, I, R, O = R>({ workflow, actionRegistry,
|
|
20
|
+
export declare function executeWorkflow<Reg extends ActionRegistry, I, R, O = R>({ workflow, actionRegistry, services, input, depsExecutors, observers, }: {
|
|
21
21
|
workflow: WorkflowDef<Reg, I, any, any, O>;
|
|
22
22
|
actionRegistry: Reg;
|
|
23
|
+
services: ServiceRegistry;
|
|
23
24
|
input: I;
|
|
24
|
-
context: any;
|
|
25
25
|
depsExecutors: Record<string, Executor>;
|
|
26
26
|
observers: WorkflowObserver<Reg>[];
|
|
27
27
|
}): Promise<{
|
|
@@ -39,7 +39,7 @@ async function runWithRetry(actionFn, stepOptions) {
|
|
|
39
39
|
}
|
|
40
40
|
throw lastError;
|
|
41
41
|
}
|
|
42
|
-
export async function executeWorkflow({ workflow, actionRegistry,
|
|
42
|
+
export async function executeWorkflow({ workflow, actionRegistry, services, input, depsExecutors, observers = [], }) {
|
|
43
43
|
const results = {};
|
|
44
44
|
const extras = {};
|
|
45
45
|
extras.frames = {};
|
|
@@ -100,7 +100,6 @@ export async function executeWorkflow({ workflow, actionRegistry, input, context
|
|
|
100
100
|
stepId,
|
|
101
101
|
input,
|
|
102
102
|
results,
|
|
103
|
-
context,
|
|
104
103
|
actionRegistry,
|
|
105
104
|
extras,
|
|
106
105
|
frame,
|
|
@@ -108,7 +107,6 @@ export async function executeWorkflow({ workflow, actionRegistry, input, context
|
|
|
108
107
|
const stepCtx = {
|
|
109
108
|
input,
|
|
110
109
|
results,
|
|
111
|
-
context,
|
|
112
110
|
...createCallHelpers(),
|
|
113
111
|
};
|
|
114
112
|
const resolvedArgs = step.resolve?.(stepCtx);
|
|
@@ -132,7 +130,7 @@ export async function executeWorkflow({ workflow, actionRegistry, input, context
|
|
|
132
130
|
if (step.__subflowId) {
|
|
133
131
|
const [modId, subWfId] = step.__subflowId.split(".");
|
|
134
132
|
const exec = depsExecutors[modId];
|
|
135
|
-
const subExecution = await exec.run(subWfId, resolvedArgs,
|
|
133
|
+
const subExecution = await exec.run(subWfId, resolvedArgs, services, observers);
|
|
136
134
|
// const subExecution = await executeWorkflow(
|
|
137
135
|
// step.__subflowId,
|
|
138
136
|
// workflowRegistry,
|
|
@@ -151,7 +149,15 @@ export async function executeWorkflow({ workflow, actionRegistry, input, context
|
|
|
151
149
|
// Normal action
|
|
152
150
|
// -----------------------------
|
|
153
151
|
const actionFn = async () => {
|
|
154
|
-
|
|
152
|
+
let action = null;
|
|
153
|
+
if (step.action === "__service__") {
|
|
154
|
+
const { service, method } = step.serviceCall;
|
|
155
|
+
action = services[service][method];
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
action = actionRegistry[step.action];
|
|
159
|
+
}
|
|
160
|
+
console.log("action", action);
|
|
155
161
|
return await runAction(resolvedArgs, action);
|
|
156
162
|
};
|
|
157
163
|
try {
|
|
@@ -194,7 +200,6 @@ export async function executeWorkflow({ workflow, actionRegistry, input, context
|
|
|
194
200
|
? workflow.outputResolver({
|
|
195
201
|
input,
|
|
196
202
|
results,
|
|
197
|
-
context,
|
|
198
203
|
})
|
|
199
204
|
: results;
|
|
200
205
|
return {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ActionRegistry, Executor, Simplify, WorkflowObserver } from "./types.js";
|
|
1
|
+
import { ActionRegistry, ServiceRegistry, Executor, Simplify, WorkflowObserver } from "./types.js";
|
|
2
2
|
import { createWorkflow, WorkflowDef } from "./workflow-composer.js";
|
|
3
3
|
type UnionToIntersection<U> = (U extends any ? (x: U) => any : never) extends (x: infer I) => any ? I : never;
|
|
4
4
|
type EnsureWorkflowShape<T> = {
|
|
@@ -13,35 +13,35 @@ type WorkflowRegistry<Own extends ModuleShape, Deps extends ModuleMap> = Own & D
|
|
|
13
13
|
type AnyWorkflow = WorkflowDef<any, any, any, any, any>;
|
|
14
14
|
type ModuleShape = Record<string, AnyWorkflow>;
|
|
15
15
|
type ModuleMap = Record<string, Module<any, any, any, any>>;
|
|
16
|
-
type
|
|
17
|
-
type
|
|
16
|
+
type FinalServices<S extends ServiceRegistry, Deps extends ModuleMap> = S & ServicesFromDepsRecursive<Deps>;
|
|
17
|
+
type ServicesFromDepsRecursive<Deps extends ModuleMap> = [keyof Deps] extends [
|
|
18
18
|
never
|
|
19
19
|
] ? {} : UnionToIntersection<{
|
|
20
|
-
[K in keyof Deps]: Deps[K] extends Module<any, infer
|
|
20
|
+
[K in keyof Deps]: Deps[K] extends Module<any, infer S, any, infer SubDeps> ? S & ServicesFromDepsRecursive<SubDeps> : never;
|
|
21
21
|
}[keyof Deps]>;
|
|
22
22
|
export type WorkflowInput<W> = W extends WorkflowDef<any, infer I, any, any, any> ? I : never;
|
|
23
23
|
export type WorkflowResults<W> = W extends WorkflowDef<any, any, infer R, any, any> ? R : never;
|
|
24
24
|
export type WorkflowOutput<W> = W extends WorkflowDef<any, any, any, any, infer O> ? O : never;
|
|
25
|
-
type Module<Reg extends ActionRegistry,
|
|
25
|
+
type Module<Reg extends ActionRegistry, S extends ServiceRegistry, Own extends ModuleShape, Deps extends ModuleMap> = {
|
|
26
26
|
workflows: Own;
|
|
27
27
|
__getExecutor: () => Executor;
|
|
28
28
|
createRuntime: (config: {
|
|
29
|
-
|
|
29
|
+
services: FinalServices<S, Deps>;
|
|
30
30
|
}) => {
|
|
31
31
|
run: <K extends keyof WorkflowRegistry<Own, Deps>>(workflow: K, input: WorkflowInput<WorkflowRegistry<Own, Deps>[K]>, observers?: WorkflowObserver<Reg>[]) => Promise<{
|
|
32
32
|
output: WorkflowOutput<WorkflowRegistry<Own, Deps>[K]>;
|
|
33
33
|
extras: Record<string, any>;
|
|
34
34
|
}>;
|
|
35
|
-
|
|
35
|
+
getServices: () => FinalServices<S, Deps>;
|
|
36
36
|
};
|
|
37
37
|
};
|
|
38
|
-
type ModuleContext<Reg extends ActionRegistry, WFReg extends Record<string, WorkflowDef<any, any, any, any, any>>,
|
|
39
|
-
wf: ReturnType<typeof createWorkflow<Reg, WFReg,
|
|
40
|
-
|
|
38
|
+
type ModuleContext<Reg extends ActionRegistry, WFReg extends Record<string, WorkflowDef<any, any, any, any, any>>, S extends ServiceRegistry> = {
|
|
39
|
+
wf: ReturnType<typeof createWorkflow<Reg, WFReg, S>>;
|
|
40
|
+
services: S;
|
|
41
41
|
};
|
|
42
|
-
export declare function createModuleFactory<
|
|
42
|
+
export declare function createModuleFactory<S extends ServiceRegistry>(): <Reg extends ActionRegistry = Record<string, any>, Use extends ModuleMap = {}, Own extends ModuleShape = {}>(config: {
|
|
43
43
|
actionRegistry: Reg;
|
|
44
44
|
use?: Use;
|
|
45
|
-
define: (ctx: ModuleContext<typeof config.actionRegistry, DepWorkflows<Use>,
|
|
46
|
-
}) => Module<Reg,
|
|
45
|
+
define: (ctx: ModuleContext<typeof config.actionRegistry, DepWorkflows<Use>, S>) => Own;
|
|
46
|
+
}) => Module<Reg, S, Own, Use>;
|
|
47
47
|
export {};
|
package/dist/workflow-module.js
CHANGED
|
@@ -1,3 +1,260 @@
|
|
|
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
|
+
// }
|
|
1
258
|
import { createWorkflow } from "./workflow-composer.js";
|
|
2
259
|
import { executeWorkflow } from "./workflow-executor.js";
|
|
3
260
|
function createModule(config) {
|
|
@@ -5,7 +262,7 @@ function createModule(config) {
|
|
|
5
262
|
const wf = createWorkflow();
|
|
6
263
|
const own = config.define({
|
|
7
264
|
wf,
|
|
8
|
-
|
|
265
|
+
services: {},
|
|
9
266
|
});
|
|
10
267
|
function buildWorkflowMap() {
|
|
11
268
|
const depWFs = Object.fromEntries(Object.entries(deps).flatMap(([name, mod]) => Object.entries(mod.workflows).map(([k, wf]) => [`${name}.${k}`, wf])));
|
|
@@ -14,7 +271,7 @@ function createModule(config) {
|
|
|
14
271
|
const workflowMap = buildWorkflowMap();
|
|
15
272
|
const depsExecutors = Object.fromEntries(Object.entries(deps).map(([name, mod]) => [name, mod.__getExecutor()]));
|
|
16
273
|
const executor = {
|
|
17
|
-
run(wfId, input,
|
|
274
|
+
run(wfId, input, services, observers = []) {
|
|
18
275
|
const workflow = workflowMap[wfId];
|
|
19
276
|
if (!workflow) {
|
|
20
277
|
throw new Error(`Workflow not found: ${String(wfId)}`);
|
|
@@ -24,7 +281,7 @@ function createModule(config) {
|
|
|
24
281
|
actionRegistry: config.actionRegistry,
|
|
25
282
|
depsExecutors,
|
|
26
283
|
input,
|
|
27
|
-
|
|
284
|
+
services,
|
|
28
285
|
observers,
|
|
29
286
|
});
|
|
30
287
|
},
|
|
@@ -32,13 +289,15 @@ function createModule(config) {
|
|
|
32
289
|
return {
|
|
33
290
|
workflows: own,
|
|
34
291
|
__getExecutor: () => executor,
|
|
35
|
-
createRuntime({
|
|
292
|
+
createRuntime({ services }) {
|
|
36
293
|
let runtimeActions = config.actionRegistry;
|
|
294
|
+
// const runtimeService = createServiceRegisty(services)
|
|
37
295
|
return {
|
|
38
296
|
run: async (workflowId, input, observers = []) => {
|
|
39
|
-
return executor.run(workflowId, input,
|
|
297
|
+
return executor.run(workflowId, input, services, observers);
|
|
40
298
|
},
|
|
41
|
-
|
|
299
|
+
// make it same, practically nothing changes but naming, and what context holds
|
|
300
|
+
getServices: () => ({ ...services }),
|
|
42
301
|
setActionRegistry(reg) {
|
|
43
302
|
runtimeActions = reg;
|
|
44
303
|
// ⚠️ optional: if you REALLY want override, you'd need:
|