@pogodisco/zephyr 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -2
- package/dist/observer.js +8 -7
- package/dist/types.d.ts +6 -0
- package/dist/utils.d.ts +1 -10
- package/dist/utils.js +5 -34
- package/dist/workflow-composer.d.ts +60 -27
- package/dist/workflow-composer.js +21 -451
- package/dist/workflow-executor.d.ts +10 -4
- package/dist/workflow-executor.js +36 -248
- package/dist/workflow-module.d.ts +23 -18
- package/dist/workflow-module.js +222 -87
- package/package.json +5 -2
package/dist/workflow-module.js
CHANGED
|
@@ -1,38 +1,100 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ActionRegistry,
|
|
2
|
+
// import {
|
|
3
|
+
// Executor,
|
|
4
|
+
// Simplify,
|
|
5
|
+
// WorkflowObserver,
|
|
6
|
+
// } from "./types.js";
|
|
2
7
|
// import { createWorkflow, WorkflowDef } from "./workflow-composer.js";
|
|
3
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>>;
|
|
4
21
|
//
|
|
5
|
-
// type
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
// [K in keyof Deps]: Deps[K] extends Module<any, any, infer Own, infer SubDeps>
|
|
9
|
-
// ? Own[keyof Own] | WorkflowFromDeps<SubDeps>
|
|
22
|
+
// type EnsureWorkflowShape<T> = {
|
|
23
|
+
// [K in keyof T]: T[K] extends WorkflowDef<any, any, any, any, any>
|
|
24
|
+
// ? T[K]
|
|
10
25
|
// : never;
|
|
11
|
-
// }
|
|
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>;
|
|
12
51
|
// type ModuleShape = Record<string, AnyWorkflow>;
|
|
52
|
+
// type ModuleMap = Record<string, Module<any, any, any, any>>;
|
|
13
53
|
//
|
|
14
|
-
// type ContextFromDeps<Deps> = [keyof Deps] extends [never]
|
|
15
|
-
// ? {}
|
|
16
|
-
// : {
|
|
17
|
-
// [K in keyof Deps]: Deps[K] extends Module<any, infer Ctx, any, any>
|
|
18
|
-
// ? Ctx
|
|
19
|
-
// : never;
|
|
20
|
-
// }[keyof Deps];
|
|
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];
|
|
21
61
|
//
|
|
22
62
|
// type FinalContext<
|
|
23
|
-
// Reg extends ActionRegistry,
|
|
24
63
|
// Context extends Record<string, any>,
|
|
25
|
-
// Deps extends ModuleMap
|
|
26
|
-
// > = Context &
|
|
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
|
+
// >;
|
|
27
93
|
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
// >;
|
|
94
|
+
// /* ------------------------------------------------ */
|
|
95
|
+
// /* WORKFLOW IO TYPES */
|
|
96
|
+
// /* ------------------------------------------------ */
|
|
32
97
|
//
|
|
33
|
-
// // type Module<Own extends ModuleShape = {}, Deps extends ModuleMap = {}> = Own & {
|
|
34
|
-
// // deps: Deps;
|
|
35
|
-
// // };
|
|
36
98
|
// export type WorkflowInput<W> =
|
|
37
99
|
// W extends WorkflowDef<any, infer I, any, any, any> ? I : never;
|
|
38
100
|
//
|
|
@@ -41,134 +103,207 @@
|
|
|
41
103
|
//
|
|
42
104
|
// export type WorkflowOutput<W> =
|
|
43
105
|
// W extends WorkflowDef<any, any, any, any, infer O> ? O : never;
|
|
106
|
+
//
|
|
107
|
+
// /* ------------------------------------------------ */
|
|
108
|
+
// /* MODULE RUNTIME */
|
|
109
|
+
// /* ------------------------------------------------ */
|
|
110
|
+
//
|
|
44
111
|
// type Module<
|
|
45
112
|
// Reg extends ActionRegistry,
|
|
46
113
|
// Context extends Record<string, any>,
|
|
47
|
-
// Own extends ModuleShape
|
|
48
|
-
// Deps extends ModuleMap
|
|
114
|
+
// Own extends ModuleShape,
|
|
115
|
+
// Deps extends ModuleMap,
|
|
49
116
|
// > = {
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
// input: WorkflowInput<W>,
|
|
59
|
-
// obververs?: WorkflowObserver<Reg>[],
|
|
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>[],
|
|
60
125
|
// ) => Promise<{
|
|
61
|
-
// results: WorkflowResults<
|
|
62
|
-
// output: WorkflowOutput<
|
|
126
|
+
// // results: WorkflowResults<WorkflowRegistry<Own, Deps>[K]>;
|
|
127
|
+
// output: WorkflowOutput<WorkflowRegistry<Own, Deps>[K]>;
|
|
63
128
|
// extras: Record<string, any>;
|
|
64
129
|
// }>;
|
|
65
|
-
//
|
|
130
|
+
//
|
|
131
|
+
// getContext: () => FinalContext<Context, Deps>;
|
|
66
132
|
// };
|
|
67
133
|
// };
|
|
68
134
|
//
|
|
69
|
-
//
|
|
135
|
+
// /* ------------------------------------------------ */
|
|
136
|
+
// /* MODULE CONTEXT (FIXED) */
|
|
137
|
+
// /* ------------------------------------------------ */
|
|
138
|
+
//
|
|
139
|
+
// type ModuleContext<
|
|
70
140
|
// Reg extends ActionRegistry,
|
|
141
|
+
// WFReg extends Record<string, WorkflowDef<any, any, any, any, any>>,
|
|
71
142
|
// Context extends Record<string, any>,
|
|
72
|
-
// Deps extends ModuleMap<Reg>,
|
|
73
143
|
// > = {
|
|
74
|
-
// wf: ReturnType<typeof createWorkflow<Reg, Context>>;
|
|
75
|
-
//
|
|
76
|
-
// deps: Deps;
|
|
144
|
+
// wf: ReturnType<typeof createWorkflow<Reg, WFReg, Context>>;
|
|
77
145
|
// context: Context;
|
|
78
|
-
//
|
|
79
|
-
// tools: <T>(
|
|
80
|
-
// factory: (ctx: {
|
|
81
|
-
// wf: ModuleContext<Reg, Context, Deps>["wf"];
|
|
82
|
-
// deps: Deps;
|
|
83
|
-
// context: Context;
|
|
84
|
-
// }) => T,
|
|
85
|
-
// ) => T;
|
|
86
146
|
// };
|
|
87
147
|
//
|
|
88
148
|
// function createModule<
|
|
89
149
|
// Reg extends ActionRegistry,
|
|
90
150
|
// Context extends Record<string, any>,
|
|
91
|
-
// Use extends ModuleMap
|
|
151
|
+
// Use extends ModuleMap,
|
|
92
152
|
// Own extends ModuleShape,
|
|
93
153
|
// >(config: {
|
|
154
|
+
// actionRegistry: Reg;
|
|
94
155
|
// use?: Use;
|
|
95
|
-
// define: (ctx: ModuleContext<Reg, Context
|
|
156
|
+
// define: (ctx: ModuleContext<Reg, DepWorkflows<Use>, Context>) => Own;
|
|
96
157
|
// }): Module<Reg, Context, Own, Use> {
|
|
97
|
-
// const wf = createWorkflow<Reg, Context>();
|
|
98
|
-
//
|
|
99
158
|
// const deps = (config.use ?? {}) as Use;
|
|
100
159
|
//
|
|
101
|
-
// const
|
|
160
|
+
// const wf = createWorkflow<Reg, DepWorkflows<Use>, Context>();
|
|
161
|
+
//
|
|
162
|
+
// const own = config.define({
|
|
102
163
|
// wf,
|
|
103
|
-
// deps,
|
|
104
164
|
// context: {} as Context,
|
|
165
|
+
// });
|
|
105
166
|
//
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
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];
|
|
113
186
|
//
|
|
114
|
-
//
|
|
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
|
+
// };
|
|
115
201
|
//
|
|
116
202
|
// return {
|
|
117
|
-
// own,
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
203
|
+
// workflows: own,
|
|
204
|
+
// __getExecutor: () => executor,
|
|
205
|
+
//
|
|
206
|
+
// createRuntime({ services }) {
|
|
207
|
+
// let runtimeActions = config.actionRegistry;
|
|
208
|
+
//
|
|
209
|
+
// // const runtimeService = createServiceRegisty(services)
|
|
121
210
|
// return {
|
|
122
|
-
// run: async
|
|
123
|
-
//
|
|
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
|
|
124
226
|
// },
|
|
125
|
-
// getContext: () => ({ ...runtimeCtx }),
|
|
126
227
|
// };
|
|
127
228
|
// },
|
|
128
229
|
// };
|
|
129
230
|
// }
|
|
130
231
|
//
|
|
232
|
+
// /* ------------------------------------------------ */
|
|
233
|
+
// /* FACTORY (FIXED) */
|
|
234
|
+
// /* ------------------------------------------------ */
|
|
235
|
+
//
|
|
131
236
|
// export function createModuleFactory<
|
|
132
|
-
// Reg extends ActionRegistry,
|
|
237
|
+
// // Reg extends ActionRegistry,
|
|
133
238
|
// Context extends Record<string, any>,
|
|
134
239
|
// >() {
|
|
135
240
|
// return function <
|
|
136
|
-
//
|
|
241
|
+
// Reg extends ActionRegistry = Record<string, any>,
|
|
242
|
+
// Use extends ModuleMap = {},
|
|
137
243
|
// Own extends ModuleShape = {},
|
|
138
244
|
// >(config: {
|
|
245
|
+
// actionRegistry: Reg;
|
|
139
246
|
// use?: Use;
|
|
140
|
-
// define: (
|
|
247
|
+
// define: (
|
|
248
|
+
// ctx: ModuleContext<
|
|
249
|
+
// typeof config.actionRegistry,
|
|
250
|
+
// DepWorkflows<Use>,
|
|
251
|
+
// Context
|
|
252
|
+
// >, // ✅ FIXED HERE
|
|
253
|
+
// ) => Own;
|
|
141
254
|
// }): Module<Reg, Context, Own, Use> {
|
|
142
255
|
// return createModule<Reg, Context, Use, Own>(config);
|
|
143
256
|
// };
|
|
144
257
|
// }
|
|
145
|
-
//
|
|
146
258
|
import { createWorkflow } from "./workflow-composer.js";
|
|
147
259
|
import { executeWorkflow } from "./workflow-executor.js";
|
|
148
|
-
/* ------------------------------------------------ */
|
|
149
|
-
/* CREATE MODULE (FIXED) */
|
|
150
|
-
/* ------------------------------------------------ */
|
|
151
260
|
function createModule(config) {
|
|
152
261
|
const deps = (config.use ?? {});
|
|
153
|
-
// ✅ CRITICAL: wf only sees DEP workflows
|
|
154
262
|
const wf = createWorkflow();
|
|
155
263
|
const own = config.define({
|
|
156
264
|
wf,
|
|
157
|
-
|
|
265
|
+
services: {},
|
|
158
266
|
});
|
|
159
|
-
function
|
|
267
|
+
function buildWorkflowMap() {
|
|
160
268
|
const depWFs = Object.fromEntries(Object.entries(deps).flatMap(([name, mod]) => Object.entries(mod.workflows).map(([k, wf]) => [`${name}.${k}`, wf])));
|
|
161
269
|
return { ...own, ...depWFs };
|
|
162
270
|
}
|
|
271
|
+
const workflowMap = buildWorkflowMap();
|
|
272
|
+
const depsExecutors = Object.fromEntries(Object.entries(deps).map(([name, mod]) => [name, mod.__getExecutor()]));
|
|
273
|
+
const executor = {
|
|
274
|
+
run(wfId, input, services, observers = []) {
|
|
275
|
+
const workflow = workflowMap[wfId];
|
|
276
|
+
if (!workflow) {
|
|
277
|
+
throw new Error(`Workflow not found: ${String(wfId)}`);
|
|
278
|
+
}
|
|
279
|
+
return executeWorkflow({
|
|
280
|
+
workflow,
|
|
281
|
+
actionRegistry: config.actionRegistry,
|
|
282
|
+
depsExecutors,
|
|
283
|
+
input,
|
|
284
|
+
services,
|
|
285
|
+
observers,
|
|
286
|
+
});
|
|
287
|
+
},
|
|
288
|
+
};
|
|
163
289
|
return {
|
|
164
290
|
workflows: own,
|
|
165
|
-
|
|
166
|
-
|
|
291
|
+
__getExecutor: () => executor,
|
|
292
|
+
createRuntime({ services }) {
|
|
293
|
+
let runtimeActions = config.actionRegistry;
|
|
294
|
+
// const runtimeService = createServiceRegisty(services)
|
|
167
295
|
return {
|
|
168
296
|
run: async (workflowId, input, observers = []) => {
|
|
169
|
-
return
|
|
297
|
+
return executor.run(workflowId, input, services, observers);
|
|
298
|
+
},
|
|
299
|
+
// make it same, practically nothing changes but naming, and what context holds
|
|
300
|
+
getServices: () => ({ ...services }),
|
|
301
|
+
setActionRegistry(reg) {
|
|
302
|
+
runtimeActions = reg;
|
|
303
|
+
// ⚠️ optional: if you REALLY want override, you'd need:
|
|
304
|
+
// executor.actions = reg
|
|
305
|
+
// but better keep actions immutable
|
|
170
306
|
},
|
|
171
|
-
getContext: () => ({ ...context }),
|
|
172
307
|
};
|
|
173
308
|
},
|
|
174
309
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pogodisco/zephyr",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -33,6 +33,8 @@
|
|
|
33
33
|
"prepublishOnly": "npm run build",
|
|
34
34
|
"build": "tsc -p tsconfig.build.json",
|
|
35
35
|
"dev": "tsc -w -p tsconfig.json",
|
|
36
|
+
"test": "vitest",
|
|
37
|
+
"test:run": "vitest run",
|
|
36
38
|
"test:types": "tsd"
|
|
37
39
|
},
|
|
38
40
|
"tsd": {
|
|
@@ -45,6 +47,7 @@
|
|
|
45
47
|
"@types/node": "^25.2.3",
|
|
46
48
|
"chalk": "^5.6.2",
|
|
47
49
|
"pretty-format": "^30.2.0",
|
|
48
|
-
"tsd": "^0.33.0"
|
|
50
|
+
"tsd": "^0.33.0",
|
|
51
|
+
"vitest": "^4.1.2"
|
|
49
52
|
}
|
|
50
53
|
}
|