@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 CHANGED
@@ -3,8 +3,6 @@ export * from "./registry.js";
3
3
  export * from "./workflow-executor.js";
4
4
  export * from "./workflow-composer.js";
5
5
  export * from "./workflow-module.js";
6
- export * from "./utils.js";
7
6
  export * from "./types.js";
8
- export * from "./utils.js";
9
7
  export * from "./session.js";
10
8
  export { useMetrics, useLog } from "./observer.js";
package/dist/index.js CHANGED
@@ -3,8 +3,6 @@ export * from "./registry.js";
3
3
  export * from "./workflow-executor.js";
4
4
  export * from "./workflow-composer.js";
5
5
  export * from "./workflow-module.js";
6
- export * from "./utils.js";
7
6
  export * from "./types.js";
8
- export * from "./utils.js";
9
7
  export * from "./session.js";
10
8
  export { useMetrics, useLog } from "./observer.js";
package/dist/observer.js CHANGED
@@ -15,16 +15,17 @@ export function composeObserver(middleware, ctx, core) {
15
15
  export function useLog() {
16
16
  return async ({ frame, stepId }, next) => {
17
17
  eventStream.emit({
18
- type: "node_start",
19
- node: stepId,
18
+ stepId: frame.stepId,
19
+ state: "start",
20
+ start: frame.start,
20
21
  timestamp: frame.start,
21
22
  input: frame.input,
22
23
  });
23
24
  try {
24
25
  const res = await next();
25
26
  eventStream.emit({
26
- type: "node_success",
27
- node: stepId,
27
+ id: frame.stepId,
28
+ state: frame.skipped ? "skipped" : "success",
28
29
  output: frame.output,
29
30
  duration: frame.end - frame.start,
30
31
  attempts: frame.attempts,
@@ -34,11 +35,11 @@ export function useLog() {
34
35
  }
35
36
  catch (err) {
36
37
  eventStream.emit({
37
- type: "node_fail",
38
- node: stepId,
38
+ ...frame,
39
+ state: "fail",
39
40
  error: frame.error,
40
41
  timestamp: Date.now(),
41
- attempts: frame.attempts,
42
+ // attempts: frame.attempts,
42
43
  });
43
44
  throw err;
44
45
  }
package/dist/types.d.ts CHANGED
@@ -26,3 +26,9 @@ export type WorkflowObserver<Reg extends ActionRegistry = any> = {
26
26
  frame: ExecutionFrame;
27
27
  }, next: () => Promise<any>): Promise<any>;
28
28
  };
29
+ export interface Executor {
30
+ run: (wfId: string, input: Record<string, any>, services: ServiceRegistry, obsververs?: WorkflowObserver[]) => Promise<any>;
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]>>;
package/dist/utils.d.ts CHANGED
@@ -1,10 +1 @@
1
- type AnyFn = (...args: any[]) => any;
2
- /**
3
- * For generic actions - preserves the generic parameter
4
- */
5
- export declare function genericAction<F extends AnyFn>(fn: F): <T>() => ((...args: Parameters<F>) => ReturnType<F>);
6
- /**
7
- * For fixed actions
8
- */
9
- export declare function fixedAction<F extends AnyFn>(fn: F): () => ((...args: Parameters<F>) => ReturnType<F>);
10
- export {};
1
+ export declare function generateWorkflowId(name: string): string;
package/dist/utils.js CHANGED
@@ -1,35 +1,6 @@
1
- /**
2
- * For generic actions - preserves the generic parameter
3
- */
4
- export function genericAction(fn) {
5
- // Return a function that takes a type parameter and returns the typed function
6
- return () => {
7
- return fn;
8
- };
1
+ export function generateWorkflowId(name) {
2
+ // Short random + timestamp for practically unique ID
3
+ const random = Math.random().toString(36).slice(2, 10);
4
+ const time = Date.now().toString(36);
5
+ return `${name}-${time}-${random}`;
9
6
  }
10
- /**
11
- * For fixed actions
12
- */
13
- export function fixedAction(fn) {
14
- return () => {
15
- return fn;
16
- };
17
- }
18
- // export function createRuntime<Reg extends ActionRegistry, Context>(
19
- // registry: Reg,
20
- // context: Context,
21
- // ) {
22
- // return {
23
- // run: async <W extends WorkflowDef<Reg, any, any, any, any>>(
24
- // workflow: W,
25
- // input: W extends WorkflowDef<Reg, infer I, any, any, any> ? I : never,
26
- // observers?: WorkflowObserver[],
27
- // ): Promise<{
28
- // output: W extends WorkflowDef<Reg, any, any, any, infer O> ? O : never;
29
- // results: W extends WorkflowDef<Reg, any, infer R, any, any> ? R : never;
30
- // extras: Record<string, any>;
31
- // }> => {
32
- // return executeWorkflow(workflow, registry, input, context, observers);
33
- // },
34
- // };
35
- // }
@@ -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,17 +40,22 @@ 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, 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;
58
+ _id: string;
54
59
  steps: Steps;
55
60
  entrySteps: StepDef<Reg>[];
56
61
  endSteps: StepDef<Reg>[];
@@ -58,27 +63,30 @@ export type WorkflowDef<Reg extends ActionRegistry, Input, Results, Steps extend
58
63
  results: Results;
59
64
  outputResolver?: (ctx: any) => Output;
60
65
  };
61
- type StepRuntimeCtx<I, R, C> = {
66
+ type StepRuntimeCtx<I, R> = {
62
67
  input: I;
63
68
  results: R;
64
- context: C;
65
69
  };
66
- type StepOptions<Input, Results, Context> = {
70
+ type StepOptions<Input, Results> = {
67
71
  retry?: number;
68
72
  retryDelay?: number | ((attempt: number) => number);
69
73
  timeout?: number;
70
74
  continueOnError?: boolean;
71
- onError?: (err: unknown, ctx: StepRuntimeCtx<Input, Results, Context>) => any;
75
+ onError?: (err: unknown, ctx: StepRuntimeCtx<Input, Results>) => any;
72
76
  label?: string;
73
77
  meta?: Record<string, any>;
74
78
  };
75
- 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 R> ? R : {})> : Acc;
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;
76
84
  type MergeBranchSteps<Branches extends readonly any[], Acc extends any[]> = Branches extends readonly [infer Head, ...infer Tail] ? MergeBranchSteps<Tail, [
77
85
  ...Acc,
78
- ...(Head extends WorkflowBuilder<any, any, any, any, infer S, any> ? S : [])
86
+ ...(Head extends WorkflowBuilder<any, any, any, any, infer Steps, any> ? Steps : [])
79
87
  ]> : Acc;
80
- export declare class WorkflowBuilder<Reg extends ActionRegistry, WFReg extends Record<string, WorkflowDef<any, any, any, any, any>>, //
81
- Input = unknown, Context = unknown, Steps extends StepDef<Reg, any, any>[] = [], Results = {}, Output = undefined> {
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> {
82
90
  private name;
83
91
  private steps;
84
92
  private frontier;
@@ -89,8 +97,7 @@ Input = unknown, Context = unknown, Steps extends StepDef<Reg, any, any>[] = [],
89
97
  step<ID extends string, ActionName extends keyof Reg & string, ResolveOut extends ResolvedStepInput = ResolvedStepInput>(id: ID, action: ActionName, resolve?: (ctx: {
90
98
  input: Input;
91
99
  results: Results;
92
- context: Context;
93
- } & 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, [
94
101
  ...Steps,
95
102
  StepDef<Reg, ID, ActionName>
96
103
  ], Simplify<Results & {
@@ -99,41 +106,67 @@ Input = unknown, Context = unknown, Steps extends StepDef<Reg, any, any>[] = [],
99
106
  seq<ID extends string = string, ActionName extends keyof Reg & string = any, ResolveOut extends ResolvedStepInput = ResolvedStepInput>(id: ID, action: ActionName, resolve?: (ctx: {
100
107
  input: Input;
101
108
  results: Results;
102
- context: Context;
103
- } & 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>;
104
- as<NewType>(): WorkflowBuilder<Reg, WFReg, Input, Context, Steps, Steps extends [...infer Rest, infer Last] ? Last extends StepDef<Reg, infer ID, any> ? Simplify<Omit<Results, ID> & {
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): 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> & {
105
142
  [K in ID]: NewType;
106
143
  }> : Results : Results, Output>;
107
- parallel<Branches extends readonly WorkflowBuilder<Reg, WFReg, Input, Context, any, any>[]>(...branches: {
108
- [K in keyof Branches]: (builder: WorkflowBuilder<Reg, WFReg, Input, Context, [], Results>) => Branches[K];
109
- }): WorkflowBuilder<Reg, WFReg, Input, Context, MergeBranchSteps<Branches, Steps>, Simplify<MergeBranchResults<Branches, Results>>>;
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>>>;
110
147
  join<ID extends string = string, ActionName extends keyof Reg & string = any, ResolveOut extends ResolvedStepInput = ResolvedStepInput>(id: ID, action: ActionName, resolve?: (ctx: {
111
148
  input: Input;
112
149
  results: Results;
113
- context: Context;
114
- } & 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>;
115
151
  subflow<Prefix extends string, K extends keyof WFReg & string>(prefix: Prefix, workflowKey: K, resolveInput: (ctx: {
116
152
  input: Input;
117
153
  results: Results;
118
- context: Context;
119
- }) => 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 & {
120
155
  [P in Prefix]: WorkflowOutput<WFReg[K]>;
121
156
  }>;
122
157
  when(predicate: (ctx: {
123
158
  input: Input;
124
159
  results: Results;
125
- context: Context;
126
- }) => boolean): WorkflowBuilder<Reg, WFReg, Input, Context, Steps, Results, Output>;
160
+ }) => boolean): WorkflowBuilder<Reg, Services, WFReg, Input, Steps, Results, Output>;
127
161
  endWhen(): this;
128
162
  output<Output>(fn: (ctx: {
129
163
  input: Input;
130
164
  results: Results;
131
- context: Context;
132
165
  }) => Output): WorkflowDef<Reg, Input, Results, Steps, Output>;
133
166
  build(): WorkflowDef<Reg, Input, Results, Steps>;
134
167
  private validateDependencies;
135
168
  private getEndSteps;
136
169
  }
137
170
  export declare function createWorkflow<Reg extends ActionRegistry, WFReg extends Record<string, WorkflowDef<any, any, any, any, any>>, // 👈 NEW
138
- Context extends Record<string, any> = {}>(): <Input = unknown>(name: string) => WorkflowBuilder<Reg, WFReg, Input, Context, [], {}, undefined>;
171
+ Services extends ServiceRegistry>(): <Input = unknown>(name: string) => WorkflowBuilder<Reg, Services, WFReg, Input, [], {}, undefined>;
139
172
  export {};