bunqueue 2.7.0 → 2.7.2

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.
Files changed (36) hide show
  1. package/README.md +11 -0
  2. package/dist/client/workflow/emitter.d.ts +18 -0
  3. package/dist/client/workflow/emitter.d.ts.map +1 -0
  4. package/dist/client/workflow/emitter.js +75 -0
  5. package/dist/client/workflow/emitter.js.map +1 -0
  6. package/dist/client/workflow/engine.d.ts +18 -1
  7. package/dist/client/workflow/engine.d.ts.map +1 -1
  8. package/dist/client/workflow/engine.js +51 -1
  9. package/dist/client/workflow/engine.js.map +1 -1
  10. package/dist/client/workflow/executor.d.ts +17 -15
  11. package/dist/client/workflow/executor.d.ts.map +1 -1
  12. package/dist/client/workflow/executor.js +141 -126
  13. package/dist/client/workflow/executor.js.map +1 -1
  14. package/dist/client/workflow/index.d.ts +2 -1
  15. package/dist/client/workflow/index.d.ts.map +1 -1
  16. package/dist/client/workflow/index.js +1 -0
  17. package/dist/client/workflow/index.js.map +1 -1
  18. package/dist/client/workflow/loops.d.ts +15 -0
  19. package/dist/client/workflow/loops.d.ts.map +1 -0
  20. package/dist/client/workflow/loops.js +76 -0
  21. package/dist/client/workflow/loops.js.map +1 -0
  22. package/dist/client/workflow/runner.d.ts +21 -0
  23. package/dist/client/workflow/runner.d.ts.map +1 -0
  24. package/dist/client/workflow/runner.js +180 -0
  25. package/dist/client/workflow/runner.js.map +1 -0
  26. package/dist/client/workflow/store.d.ts +6 -0
  27. package/dist/client/workflow/store.d.ts.map +1 -1
  28. package/dist/client/workflow/store.js +55 -0
  29. package/dist/client/workflow/store.js.map +1 -1
  30. package/dist/client/workflow/types.d.ts +95 -0
  31. package/dist/client/workflow/types.d.ts.map +1 -1
  32. package/dist/client/workflow/workflow.d.ts +19 -1
  33. package/dist/client/workflow/workflow.d.ts.map +1 -1
  34. package/dist/client/workflow/workflow.js +93 -0
  35. package/dist/client/workflow/workflow.js.map +1 -1
  36. package/package.json +13 -2
package/README.md CHANGED
@@ -519,7 +519,18 @@ await engine.start('order-pipeline', { orderId: 'ORD-1', amount: 99.99 });
519
519
 
520
520
  - **Saga pattern** — Compensation handlers run in reverse when a step fails
521
521
  - **Branching** — Route to different paths based on runtime conditions
522
+ - **Parallel steps** — Run independent steps concurrently with `.parallel()`
522
523
  - **Human-in-the-loop** — `waitFor('event')` pauses execution, `engine.signal()` resumes it
524
+ - **Signal timeout** — `waitFor('event', { timeout })` fails if signal doesn't arrive in time
525
+ - **Step retry** — Automatic retry with exponential backoff and jitter
526
+ - **Nested workflows** — Compose workflows with `.subWorkflow()`, child results passed back
527
+ - **Loops** — `doUntil()` and `doWhile()` for conditional iteration with safety limits
528
+ - **forEach** — Iterate over dynamic item lists with indexed step results (`step:0`, `step:1`, ...)
529
+ - **Map** — Synchronous data transforms between steps with `.map()`
530
+ - **Schema validation** — Validate step input/output with Zod, ArkType, Valibot, or any `.parse()` schema
531
+ - **Subscribe** — `engine.subscribe(id, callback)` to monitor a specific execution's events
532
+ - **Observability** — Typed event emitter with 11 event types (`engine.on/onAny`)
533
+ - **Cleanup & archival** — `engine.cleanup()` / `engine.archive()` for execution history management
523
534
  - **Step timeouts** — Prevent steps from running indefinitely
524
535
  - **Context passing** — Each step accesses input and all previous step results
525
536
  - **SQLite persistence** — Execution state survives restarts
@@ -0,0 +1,18 @@
1
+ /**
2
+ * WorkflowEmitter - Typed event system for workflow observability
3
+ */
4
+ import type { WorkflowEventType, StepEvent, WorkflowLifecycleEvent, WorkflowEventListener, ExecutionState } from './types';
5
+ export declare class WorkflowEmitter {
6
+ private readonly listeners;
7
+ private readonly globalListeners;
8
+ on(type: WorkflowEventType, listener: WorkflowEventListener): this;
9
+ onAny(listener: WorkflowEventListener): this;
10
+ off(type: WorkflowEventType, listener: WorkflowEventListener): this;
11
+ offAny(listener: WorkflowEventListener): this;
12
+ emitStep(type: 'step:started' | 'step:completed' | 'step:failed' | 'step:retry', executionId: string, workflowName: string, stepName: string, extra?: Partial<Omit<StepEvent, 'type' | 'executionId' | 'workflowName' | 'timestamp' | 'stepName'>>): void;
13
+ emitWorkflow(type: 'workflow:started' | 'workflow:completed' | 'workflow:failed' | 'workflow:compensating' | 'workflow:waiting', executionId: string, workflowName: string, state: ExecutionState, extra?: Partial<Omit<WorkflowLifecycleEvent, 'type' | 'executionId' | 'workflowName' | 'timestamp' | 'state'>>): void;
14
+ emitSignal(type: 'signal:received' | 'signal:timeout', executionId: string, workflowName: string, event: string, payload?: unknown): void;
15
+ removeAllListeners(): void;
16
+ private dispatch;
17
+ }
18
+ //# sourceMappingURL=emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../../src/client/workflow/emitter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,iBAAiB,EAEjB,SAAS,EACT,sBAAsB,EAEtB,qBAAqB,EACrB,cAAc,EACf,MAAM,SAAS,CAAC;AAEjB,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4D;IACtF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoC;IAEpE,EAAE,CAAC,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAUlE,KAAK,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAK5C,GAAG,CAAC,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAKnE,MAAM,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAK7C,QAAQ,CACN,IAAI,EAAE,cAAc,GAAG,gBAAgB,GAAG,aAAa,GAAG,YAAY,EACtE,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,OAAO,CACb,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,cAAc,GAAG,WAAW,GAAG,UAAU,CAAC,CACpF,GACA,IAAI;IAYP,YAAY,CACV,IAAI,EACA,kBAAkB,GAClB,oBAAoB,GACpB,iBAAiB,GACjB,uBAAuB,GACvB,kBAAkB,EACtB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,cAAc,EACrB,KAAK,CAAC,EAAE,OAAO,CACb,IAAI,CAAC,sBAAsB,EAAE,MAAM,GAAG,aAAa,GAAG,cAAc,GAAG,WAAW,GAAG,OAAO,CAAC,CAC9F,GACA,IAAI;IAYP,UAAU,CACR,IAAI,EAAE,iBAAiB,GAAG,gBAAgB,EAC1C,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,OAAO,GAChB,IAAI;IAYP,kBAAkB,IAAI,IAAI;IAK1B,OAAO,CAAC,QAAQ;CAOjB"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * WorkflowEmitter - Typed event system for workflow observability
3
+ */
4
+ export class WorkflowEmitter {
5
+ listeners = new Map();
6
+ globalListeners = new Set();
7
+ on(type, listener) {
8
+ let set = this.listeners.get(type);
9
+ if (!set) {
10
+ set = new Set();
11
+ this.listeners.set(type, set);
12
+ }
13
+ set.add(listener);
14
+ return this;
15
+ }
16
+ onAny(listener) {
17
+ this.globalListeners.add(listener);
18
+ return this;
19
+ }
20
+ off(type, listener) {
21
+ this.listeners.get(type)?.delete(listener);
22
+ return this;
23
+ }
24
+ offAny(listener) {
25
+ this.globalListeners.delete(listener);
26
+ return this;
27
+ }
28
+ emitStep(type, executionId, workflowName, stepName, extra) {
29
+ const event = {
30
+ type,
31
+ executionId,
32
+ workflowName,
33
+ timestamp: Date.now(),
34
+ stepName,
35
+ ...extra,
36
+ };
37
+ this.dispatch(type, event);
38
+ }
39
+ emitWorkflow(type, executionId, workflowName, state, extra) {
40
+ const event = {
41
+ type,
42
+ executionId,
43
+ workflowName,
44
+ timestamp: Date.now(),
45
+ state,
46
+ ...extra,
47
+ };
48
+ this.dispatch(type, event);
49
+ }
50
+ emitSignal(type, executionId, workflowName, event, payload) {
51
+ const evt = {
52
+ type,
53
+ executionId,
54
+ workflowName,
55
+ timestamp: Date.now(),
56
+ event,
57
+ payload,
58
+ };
59
+ this.dispatch(type, evt);
60
+ }
61
+ removeAllListeners() {
62
+ this.listeners.clear();
63
+ this.globalListeners.clear();
64
+ }
65
+ dispatch(type, event) {
66
+ const typed = this.listeners.get(type);
67
+ if (typed) {
68
+ for (const fn of typed)
69
+ fn(event);
70
+ }
71
+ for (const fn of this.globalListeners)
72
+ fn(event);
73
+ }
74
+ }
75
+ //# sourceMappingURL=emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../../src/client/workflow/emitter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,MAAM,OAAO,eAAe;IACT,SAAS,GAAG,IAAI,GAAG,EAAiD,CAAC;IACrE,eAAe,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEpE,EAAE,CAAC,IAAuB,EAAE,QAA+B;QACzD,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAChC,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,QAA+B;QACnC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,GAAG,CAAC,IAAuB,EAAE,QAA+B;QAC1D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,QAA+B;QACpC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ,CACN,IAAsE,EACtE,WAAmB,EACnB,YAAoB,EACpB,QAAgB,EAChB,KAEC;QAED,MAAM,KAAK,GAAc;YACvB,IAAI;YACJ,WAAW;YACX,YAAY;YACZ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,QAAQ;YACR,GAAG,KAAK;SACT,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,YAAY,CACV,IAKsB,EACtB,WAAmB,EACnB,YAAoB,EACpB,KAAqB,EACrB,KAEC;QAED,MAAM,KAAK,GAA2B;YACpC,IAAI;YACJ,WAAW;YACX,YAAY;YACZ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,KAAK;YACL,GAAG,KAAK;SACT,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,UAAU,CACR,IAA0C,EAC1C,WAAmB,EACnB,YAAoB,EACpB,KAAa,EACb,OAAiB;QAEjB,MAAM,GAAG,GAAgB;YACvB,IAAI;YACJ,WAAW;YACX,YAAY;YACZ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,KAAK;YACL,OAAO;SACR,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,kBAAkB;QAChB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAEO,QAAQ,CAAC,IAAuB,EAAE,KAAoB;QAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,MAAM,EAAE,IAAI,KAAK;gBAAE,EAAE,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,eAAe;YAAE,EAAE,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC;CACF"}
@@ -3,12 +3,13 @@
3
3
  * Manages lifecycle of internal Queue, Worker, and Store.
4
4
  */
5
5
  import type { Workflow } from './workflow';
6
- import type { EngineOptions, RunHandle, Execution, ExecutionState } from './types';
6
+ import type { EngineOptions, RunHandle, Execution, ExecutionState, WorkflowEventType, WorkflowEventListener } from './types';
7
7
  export declare class Engine {
8
8
  private readonly queue;
9
9
  private readonly worker;
10
10
  private readonly store;
11
11
  private readonly executor;
12
+ private readonly emitter;
12
13
  constructor(opts?: EngineOptions);
13
14
  /** Register a workflow definition */
14
15
  register(workflow: Workflow): this;
@@ -20,6 +21,22 @@ export declare class Engine {
20
21
  listExecutions(workflowName?: string, state?: ExecutionState): Execution[];
21
22
  /** Send a signal to a waiting execution */
22
23
  signal(executionId: string, event: string, payload?: unknown): Promise<void>;
24
+ /** Subscribe to a specific workflow event type */
25
+ on(type: WorkflowEventType, listener: WorkflowEventListener): this;
26
+ /** Subscribe to all workflow events */
27
+ onAny(listener: WorkflowEventListener): this;
28
+ /** Unsubscribe from a specific event type */
29
+ off(type: WorkflowEventType, listener: WorkflowEventListener): this;
30
+ /** Unsubscribe a catch-all listener */
31
+ offAny(listener: WorkflowEventListener): this;
32
+ /** Subscribe to all events for a specific execution */
33
+ subscribe(executionId: string, callback: WorkflowEventListener): () => void;
34
+ /** Remove old completed/failed executions */
35
+ cleanup(maxAgeMs: number, states?: ExecutionState[]): number;
36
+ /** Archive old executions to a separate table */
37
+ archive(maxAgeMs: number, states?: ExecutionState[]): number;
38
+ /** Get archived execution count */
39
+ getArchivedCount(): number;
23
40
  /** Shut down the engine */
24
41
  close(force?: boolean): Promise<void>;
25
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/client/workflow/engine.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAe,MAAM,SAAS,CAAC;AAIhG,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmB;gBAEhC,IAAI,GAAE,aAAkB;IA2BpC,qCAAqC;IACrC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAKlC,qCAAqC;IAC/B,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAItE,gCAAgC;IAChC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAI1C,4CAA4C;IAC5C,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,cAAc,GAAG,SAAS,EAAE;IAI1E,2CAA2C;IACrC,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlF,2BAA2B;IACrB,KAAK,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAK1C"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/client/workflow/engine.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,SAAS,EACT,cAAc,EAEd,iBAAiB,EACjB,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAIjB,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmB;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;gBAE9B,IAAI,GAAE,aAAkB;IAiCpC,qCAAqC;IACrC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAKlC,qCAAqC;IAC/B,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAItE,gCAAgC;IAChC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAI1C,4CAA4C;IAC5C,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,cAAc,GAAG,SAAS,EAAE;IAI1E,2CAA2C;IACrC,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlF,kDAAkD;IAClD,EAAE,CAAC,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAKlE,uCAAuC;IACvC,KAAK,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAK5C,6CAA6C;IAC7C,GAAG,CAAC,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAKnE,uCAAuC;IACvC,MAAM,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAK7C,uDAAuD;IACvD,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,qBAAqB,GAAG,MAAM,IAAI;IAU3E,6CAA6C;IAC7C,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,EAAE,GAAG,MAAM;IAI5D,iDAAiD;IACjD,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,EAAE,GAAG,MAAM;IAI5D,mCAAmC;IACnC,gBAAgB,IAAI,MAAM;IAI1B,2BAA2B;IACrB,KAAK,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAM1C"}
@@ -6,12 +6,14 @@ import { Queue } from '../queue/queue';
6
6
  import { Worker } from '../worker/worker';
7
7
  import { WorkflowStore } from './store';
8
8
  import { WorkflowExecutor } from './executor';
9
+ import { WorkflowEmitter } from './emitter';
9
10
  const DEFAULT_QUEUE_NAME = '__wf:steps';
10
11
  export class Engine {
11
12
  queue;
12
13
  worker;
13
14
  store;
14
15
  executor;
16
+ emitter;
15
17
  constructor(opts = {}) {
16
18
  const queueName = opts.queueName ?? DEFAULT_QUEUE_NAME;
17
19
  this.queue = new Queue(queueName, {
@@ -20,7 +22,11 @@ export class Engine {
20
22
  dataPath: opts.dataPath,
21
23
  });
22
24
  this.store = new WorkflowStore(opts.dataPath);
23
- this.executor = new WorkflowExecutor(this.store, this.queue);
25
+ this.emitter = new WorkflowEmitter();
26
+ if (opts.onEvent) {
27
+ this.emitter.onAny(opts.onEvent);
28
+ }
29
+ this.executor = new WorkflowExecutor(this.store, this.queue, this.emitter);
24
30
  this.worker = new Worker(queueName, async (job) => {
25
31
  const data = job.data;
26
32
  return this.executor.processStep(data);
@@ -52,11 +58,55 @@ export class Engine {
52
58
  async signal(executionId, event, payload) {
53
59
  return this.executor.signal(executionId, event, payload);
54
60
  }
61
+ // ============ Observability ============
62
+ /** Subscribe to a specific workflow event type */
63
+ on(type, listener) {
64
+ this.emitter.on(type, listener);
65
+ return this;
66
+ }
67
+ /** Subscribe to all workflow events */
68
+ onAny(listener) {
69
+ this.emitter.onAny(listener);
70
+ return this;
71
+ }
72
+ /** Unsubscribe from a specific event type */
73
+ off(type, listener) {
74
+ this.emitter.off(type, listener);
75
+ return this;
76
+ }
77
+ /** Unsubscribe a catch-all listener */
78
+ offAny(listener) {
79
+ this.emitter.offAny(listener);
80
+ return this;
81
+ }
82
+ /** Subscribe to all events for a specific execution */
83
+ subscribe(executionId, callback) {
84
+ const filter = (event) => {
85
+ if (event.executionId === executionId)
86
+ callback(event);
87
+ };
88
+ this.emitter.onAny(filter);
89
+ return () => this.emitter.offAny(filter);
90
+ }
91
+ // ============ Cleanup ============
92
+ /** Remove old completed/failed executions */
93
+ cleanup(maxAgeMs, states) {
94
+ return this.store.cleanup(maxAgeMs, states);
95
+ }
96
+ /** Archive old executions to a separate table */
97
+ archive(maxAgeMs, states) {
98
+ return this.store.archive(maxAgeMs, states);
99
+ }
100
+ /** Get archived execution count */
101
+ getArchivedCount() {
102
+ return this.store.getArchivedCount();
103
+ }
55
104
  /** Shut down the engine */
56
105
  async close(force = false) {
57
106
  await this.worker.close(force);
58
107
  this.queue.close();
59
108
  this.store.close();
109
+ this.emitter.removeAllListeners();
60
110
  }
61
111
  }
62
112
  //# sourceMappingURL=engine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/client/workflow/engine.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAI9C,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAExC,MAAM,OAAO,MAAM;IACA,KAAK,CAAQ;IACb,MAAM,CAAS;IACf,KAAK,CAAgB;IACrB,QAAQ,CAAmB;IAE5C,YAAY,OAAsB,EAAE;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,kBAAkB,CAAC;QAEvD,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,SAAS,EAAE;YAChC,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAE7D,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CACtB,SAAS,EACT,KAAK,EAAE,GAAG,EAAE,EAAE;YACZ,MAAM,IAAI,GAAG,GAAG,CAAC,IAA8B,CAAC;YAChD,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC,EACD;YACE,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC;SACnC,CACF,CAAC;IACJ,CAAC;IAED,qCAAqC;IACrC,QAAQ,CAAC,QAAkB;QACzB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qCAAqC;IACrC,KAAK,CAAC,KAAK,CAAC,YAAoB,EAAE,KAAe;QAC/C,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;IAED,gCAAgC;IAChC,YAAY,CAAC,EAAU;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,4CAA4C;IAC5C,cAAc,CAAC,YAAqB,EAAE,KAAsB;QAC1D,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IAC3D,CAAC;IAED,2CAA2C;IAC3C,KAAK,CAAC,MAAM,CAAC,WAAmB,EAAE,KAAa,EAAE,OAAiB;QAChE,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;IAED,2BAA2B;IAC3B,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK;QACvB,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF"}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/client/workflow/engine.ts"],"names":[],"mappings":"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"}
@@ -1,32 +1,34 @@
1
- /**
2
- * WorkflowExecutor - Core execution logic
3
- * Processes steps as bunqueue jobs, handles transitions, branching, compensation.
4
- */
1
+ /** WorkflowExecutor - Core execution logic */
5
2
  import type { Queue } from '../queue/queue';
6
3
  import type { Workflow } from './workflow';
7
4
  import type { WorkflowStore } from './store';
5
+ import type { WorkflowEmitter } from './emitter';
8
6
  import type { Execution, StepJobData, RunHandle } from './types';
9
7
  export declare class WorkflowExecutor {
10
8
  private readonly store;
11
9
  private readonly queue;
10
+ private readonly emitter;
12
11
  private readonly workflows;
13
- constructor(store: WorkflowStore, queue: Queue);
12
+ private readonly timeoutTimers;
13
+ constructor(store: WorkflowStore, queue: Queue, emitter?: WorkflowEmitter | null);
14
14
  register(workflow: Workflow): void;
15
15
  start(workflowName: string, input: unknown): Promise<RunHandle>;
16
- /** Process a step job — this is the Worker processor function */
17
16
  processStep(data: StepJobData): Promise<unknown>;
18
17
  signal(executionId: string, event: string, payload: unknown): Promise<void>;
19
18
  getExecution(id: string): Execution | null;
20
19
  listExecutions(workflowName?: string, state?: Execution['state']): Execution[];
21
20
  private executeNode;
22
- private executeStep;
23
- private executeBranch;
24
- private executeWaitFor;
25
- private advanceToNext;
26
- private enqueueNode;
27
- private runCompensation;
28
- private findStepDef;
29
- private buildContext;
30
- private runWithTimeout;
21
+ private runStep;
22
+ private runBranch;
23
+ private runParallel;
24
+ private runSubWorkflow;
25
+ private runWaitFor;
26
+ private runLoop;
27
+ private runForEach;
28
+ private runMap;
29
+ private advance;
30
+ private enqueue;
31
+ private scheduleTimeoutCheck;
32
+ private compensate;
31
33
  }
32
34
  //# sourceMappingURL=executor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/client/workflow/executor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,SAAS,EAIV,MAAM,SAAS,CAAC;AASjB,qBAAa,gBAAgB;IAIzB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAJxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA+B;gBAGtC,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,KAAK;IAG/B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAS5B,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAuBrE,iEAAiE;IAC3D,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IA2BhD,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjF,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAI1C,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,SAAS,EAAE;YAMhE,WAAW;YAeX,WAAW;YAiCX,aAAa;YA2Bb,cAAc;YAkBd,aAAa;YASb,WAAW;YASX,eAAe;IA0B7B,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,cAAc;CAmBvB"}
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/client/workflow/executor.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAgC,MAAM,SAAS,CAAC;AAgB/F,qBAAa,gBAAgB;IAKzB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAN1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA+B;IACzD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoD;gBAG/D,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,KAAK,EACZ,OAAO,GAAE,eAAe,GAAG,IAAW;IAGzD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAS5B,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAwB/D,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IA8BhD,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBjF,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAI1C,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,SAAS,EAAE;YAIhE,WAAW;YAiBX,OAAO;YAQP,SAAS;YAkBT,WAAW;YAYX,cAAc;YAiBd,UAAU;YA2CV,OAAO;YAaP,UAAU;YAYV,MAAM;YAWN,OAAO;YAYP,OAAO;IASrB,OAAO,CAAC,oBAAoB;YASd,UAAU;CAwBzB"}