@n8n/engine 0.13.1 → 0.15.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.
Files changed (75) hide show
  1. package/dist/build.tsbuildinfo +1 -1
  2. package/dist/common/errors.d.ts +6 -0
  3. package/dist/common/errors.js +18 -0
  4. package/dist/common/errors.js.map +1 -0
  5. package/dist/common/index.d.ts +1 -0
  6. package/dist/common/index.js +4 -0
  7. package/dist/common/index.js.map +1 -1
  8. package/dist/database/entities/workflow-step-execution.entity.d.ts +4 -1
  9. package/dist/database/entities/workflow-step-execution.entity.js +13 -1
  10. package/dist/database/entities/workflow-step-execution.entity.js.map +1 -1
  11. package/dist/database/migrations/1784890100000-CreateWorkflowStepExecution.js +17 -1
  12. package/dist/database/migrations/1784890100000-CreateWorkflowStepExecution.js.map +1 -1
  13. package/dist/database/typeorm-execution-store.d.ts +5 -1
  14. package/dist/database/typeorm-execution-store.js +16 -1
  15. package/dist/database/typeorm-execution-store.js.map +1 -1
  16. package/dist/database/typeorm-step-store.d.ts +16 -4
  17. package/dist/database/typeorm-step-store.js +91 -4
  18. package/dist/database/typeorm-step-store.js.map +1 -1
  19. package/dist/dependencies/external-dependencies.d.ts +3 -4
  20. package/dist/execution/execution-start-handler.d.ts +10 -0
  21. package/dist/execution/execution-start-handler.js +43 -0
  22. package/dist/execution/execution-start-handler.js.map +1 -0
  23. package/dist/execution/execution-store.d.ts +15 -0
  24. package/dist/execution/execution-store.js +10 -0
  25. package/dist/execution/execution-store.js.map +1 -1
  26. package/dist/execution/execution.types.d.ts +2 -0
  27. package/dist/execution/index.d.ts +10 -3
  28. package/dist/execution/index.js +15 -1
  29. package/dist/execution/index.js.map +1 -1
  30. package/dist/execution/orchestration-worker.d.ts +11 -0
  31. package/dist/execution/orchestration-worker.js +35 -0
  32. package/dist/execution/orchestration-worker.js.map +1 -0
  33. package/dist/execution/start-execution.service.d.ts +4 -3
  34. package/dist/execution/start-execution.service.js +5 -1
  35. package/dist/execution/start-execution.service.js.map +1 -1
  36. package/dist/execution/step-completed-handler.d.ts +13 -0
  37. package/dist/execution/step-completed-handler.js +74 -0
  38. package/dist/execution/step-completed-handler.js.map +1 -0
  39. package/dist/execution/step-ready-handler.d.ts +16 -0
  40. package/dist/execution/step-ready-handler.js +112 -0
  41. package/dist/execution/step-ready-handler.js.map +1 -0
  42. package/dist/execution/step-store.d.ts +33 -3
  43. package/dist/execution/step-store.js +10 -0
  44. package/dist/execution/step-store.js.map +1 -1
  45. package/dist/execution/step-worker.d.ts +9 -0
  46. package/dist/execution/step-worker.js +30 -0
  47. package/dist/execution/step-worker.js.map +1 -0
  48. package/dist/execution/validate-step-context.d.ts +4 -0
  49. package/dist/execution/validate-step-context.js +15 -0
  50. package/dist/execution/validate-step-context.js.map +1 -0
  51. package/dist/graph/index.d.ts +2 -0
  52. package/dist/graph/index.js +8 -0
  53. package/dist/graph/index.js.map +1 -1
  54. package/dist/graph/validate-executable-graph.d.ts +5 -0
  55. package/dist/graph/validate-executable-graph.js +41 -0
  56. package/dist/graph/validate-executable-graph.js.map +1 -0
  57. package/dist/graph/workflow-graph-queries.d.ts +4 -0
  58. package/dist/graph/workflow-graph-queries.js +27 -0
  59. package/dist/graph/workflow-graph-queries.js.map +1 -0
  60. package/dist/graph/workflow-graph.d.ts +2 -2
  61. package/dist/index.d.ts +3 -2
  62. package/dist/index.js +9 -1
  63. package/dist/index.js.map +1 -1
  64. package/dist/queue/in-memory-work-queue.d.ts +11 -4
  65. package/dist/queue/in-memory-work-queue.js +44 -2
  66. package/dist/queue/in-memory-work-queue.js.map +1 -1
  67. package/dist/queue/index.d.ts +1 -1
  68. package/dist/queue/index.js.map +1 -1
  69. package/dist/queue/work-queue.types.d.ts +16 -3
  70. package/dist/serve.js +18 -5
  71. package/dist/serve.js.map +1 -1
  72. package/dist/server/create-engine-server.d.ts +2 -2
  73. package/dist/server/routes/workflow-executions.js +12 -2
  74. package/dist/server/routes/workflow-executions.js.map +1 -1
  75. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"start-execution.service.js","sourceRoot":"","sources":["../../src/execution/start-execution.service.ts"],"names":[],"mappings":";;;AAAA,8CAAgF;AAkBhF;IAEmB,UAAU;IACV,cAAc;IACd,SAAS;IAH3B,YACkB,UAA6B,EAC7B,cAA8B,EAC9B,SAAoB;0BAFpB,UAAU;8BACV,cAAc;yBACd,SAAS;IACxB,CAAC;IAEJ,KAAK,CAAC,KAAK,CAAC,OAA8B;QACzC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QACpF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,IAAI,oCAAuB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC;YACxD,UAAU,EAAE,OAAO,CAAC,UAAU;YAE9B,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,YAAY;YAClC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,IAAI;SAC9C,CAAC,CAAC;QAKH,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;YAC5B,IAAI,EAAE,oBAAoB;YAC1B,WAAW,EAAE,EAAE;SACf,CAAC,CAAC;QAEH,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC5B,CAAC;CACD"}
1
+ {"version":3,"file":"start-execution.service.js","sourceRoot":"","sources":["../../src/execution/start-execution.service.ts"],"names":[],"mappings":";;;AAAA,8CAAgF;AAEhF,oCAAuE;AAgBvE;IAEmB,UAAU;IACV,cAAc;IACd,SAAS;IACT,aAAa;IAJ/B,YACkB,UAA6B,EAC7B,cAA8B,EAC9B,SAA0C,EAC1C,aAAa,GAAmC,+BAAuB;0BAHvE,UAAU;8BACV,cAAc;yBACd,SAAS;6BACT,aAAa;IAC5B,CAAC;IAEJ,KAAK,CAAC,KAAK,CAAC,OAA8B;QAGzC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAElC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QACpF,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,IAAI,oCAAuB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC;YACxD,UAAU,EAAE,OAAO,CAAC,UAAU;YAE9B,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,YAAY;YAClC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,IAAI;SAC9C,CAAC,CAAC;QAKH,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;YAC5B,IAAI,EAAE,oBAAoB;YAC1B,WAAW,EAAE,EAAE;SACf,CAAC,CAAC;QAEH,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC5B,CAAC;CACD"}
@@ -0,0 +1,13 @@
1
+ import type { StepCompletedEvent, StepMessage, WorkQueue } from '../queue';
2
+ import type { ExecutionStore } from './execution-store';
3
+ import type { StepStore } from './step-store';
4
+ export declare class StepCompletedHandler {
5
+ private readonly executionStore;
6
+ private readonly stepStore;
7
+ private readonly stepQueue;
8
+ constructor(executionStore: ExecutionStore, stepStore: StepStore, stepQueue: WorkQueue<StepMessage>);
9
+ handle(event: StepCompletedEvent): Promise<void>;
10
+ private finishExecutionIfDone;
11
+ private planSuccessors;
12
+ private readySuccessorNodeIds;
13
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StepCompletedHandler = void 0;
4
+ const graph_1 = require("../graph");
5
+ const validate_step_context_1 = require("./validate-step-context");
6
+ class StepCompletedHandler {
7
+ executionStore;
8
+ stepStore;
9
+ stepQueue;
10
+ constructor(executionStore, stepStore, stepQueue) {
11
+ this.executionStore = executionStore;
12
+ this.stepStore = stepStore;
13
+ this.stepQueue = stepQueue;
14
+ }
15
+ async handle(event) {
16
+ const [step, execution] = await Promise.all([
17
+ this.stepStore.loadStep(event.stepId),
18
+ this.executionStore.loadExecution(event.executionId),
19
+ ]);
20
+ (0, validate_step_context_1.validateStepContext)(step, execution);
21
+ if (step.status === 'failed') {
22
+ await this.executionStore.finishExecution(execution.id, 'failed');
23
+ await this.stepStore.cancelQueuedSteps(execution.id);
24
+ return;
25
+ }
26
+ if (execution.status !== 'running')
27
+ return;
28
+ const planned = step.status === 'completed' ? await this.planSuccessors(execution, step.nodeId) : 0;
29
+ if (planned > 0)
30
+ return;
31
+ await this.finishExecutionIfDone(execution.id);
32
+ }
33
+ async finishExecutionIfDone(executionId) {
34
+ if (await this.stepStore.hasActiveSteps(executionId))
35
+ return;
36
+ const failed = await this.stepStore.hasFailedSteps(executionId);
37
+ await this.executionStore.finishExecution(executionId, failed ? 'failed' : 'completed');
38
+ }
39
+ async planSuccessors(execution, nodeId) {
40
+ const readyNodeIds = await this.readySuccessorNodeIds(execution, nodeId);
41
+ if (readyNodeIds.length === 0)
42
+ return 0;
43
+ const created = await this.stepStore.createSteps(readyNodeIds.map((readyNodeId) => ({
44
+ executionId: execution.id,
45
+ nodeId: readyNodeId,
46
+ status: 'queued',
47
+ })));
48
+ for (const { id: stepId } of created) {
49
+ await this.stepQueue.publish({
50
+ type: 'step:ready',
51
+ executionId: execution.id,
52
+ stepId,
53
+ });
54
+ }
55
+ return created.length;
56
+ }
57
+ async readySuccessorNodeIds(execution, nodeId) {
58
+ const successors = (0, graph_1.getSuccessorNodeIds)(execution.graph, nodeId).map((id) => ({
59
+ id,
60
+ predecessorIds: (0, graph_1.getPredecessorNodeIds)(execution.graph, id),
61
+ }));
62
+ const predecessorsToCheck = successors
63
+ .flatMap(({ predecessorIds }) => predecessorIds)
64
+ .filter((id) => id !== nodeId);
65
+ const completed = predecessorsToCheck.length === 0
66
+ ? new Set()
67
+ : await this.stepStore.loadCompletedNodeIds(execution.id, predecessorsToCheck);
68
+ return successors
69
+ .filter(({ predecessorIds }) => predecessorIds.every((id) => id === nodeId || completed.has(id)))
70
+ .map(({ id }) => id);
71
+ }
72
+ }
73
+ exports.StepCompletedHandler = StepCompletedHandler;
74
+ //# sourceMappingURL=step-completed-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-completed-handler.js","sourceRoot":"","sources":["../../src/execution/step-completed-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { ExternalDependencies } from '../dependencies';
2
+ import type { OrchestrationMessage, StepReadyEvent, WorkQueue } from '../queue';
3
+ import type { ExecutionStore } from './execution-store';
4
+ import type { StepStore } from './step-store';
5
+ export declare class StepReadyHandler {
6
+ private readonly executionStore;
7
+ private readonly stepStore;
8
+ private readonly orchestrationQueue;
9
+ private readonly dependencies;
10
+ constructor(executionStore: ExecutionStore, stepStore: StepStore, orchestrationQueue: WorkQueue<OrchestrationMessage>, dependencies: ExternalDependencies);
11
+ handle(event: StepReadyEvent): Promise<void>;
12
+ private runStep;
13
+ private assertOutputFiredForSuccessors;
14
+ private gatherInputs;
15
+ private executorFor;
16
+ }
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StepReadyHandler = void 0;
4
+ const common_1 = require("../common");
5
+ const validate_step_context_1 = require("./validate-step-context");
6
+ class StepReadyHandler {
7
+ executionStore;
8
+ stepStore;
9
+ orchestrationQueue;
10
+ dependencies;
11
+ constructor(executionStore, stepStore, orchestrationQueue, dependencies) {
12
+ this.executionStore = executionStore;
13
+ this.stepStore = stepStore;
14
+ this.orchestrationQueue = orchestrationQueue;
15
+ this.dependencies = dependencies;
16
+ }
17
+ async handle(event) {
18
+ const step = await this.stepStore.claimStep(event.stepId);
19
+ if (!step)
20
+ return;
21
+ const execution = await this.executionStore.loadExecution(event.executionId);
22
+ const node = (0, validate_step_context_1.validateStepContext)(step, execution);
23
+ const executor = this.executorFor(step, node);
24
+ if (execution.status !== 'running') {
25
+ return;
26
+ }
27
+ const inputs = await this.gatherInputs(execution, step);
28
+ let run;
29
+ try {
30
+ run = {
31
+ ok: true,
32
+ outputs: await this.runStep(step, execution, node, inputs, executor),
33
+ };
34
+ }
35
+ catch (error) {
36
+ run = { ok: false, error };
37
+ }
38
+ const recorded = run.ok
39
+ ? await this.stepStore.completeStep(event.stepId, run.outputs)
40
+ : await this.stepStore.failStep(event.stepId, toStepError(run.error));
41
+ if (!recorded)
42
+ return;
43
+ await this.orchestrationQueue.publish({
44
+ type: 'step:completed',
45
+ executionId: event.executionId,
46
+ stepId: event.stepId,
47
+ });
48
+ }
49
+ async runStep(step, execution, node, inputs, executor) {
50
+ const { outputs } = await executor.execute({
51
+ node,
52
+ inputs,
53
+ context: {
54
+ executionId: execution.id,
55
+ stepId: step.id,
56
+ workflowId: execution.workflowId,
57
+ mode: execution.mode,
58
+ },
59
+ });
60
+ if (outputs.length > 1) {
61
+ throw new common_1.UnimplementedError(`step ${step.id} runs node ${step.nodeId}, which produced ${outputs.length} output slots; only output slot 0 is supported yet`);
62
+ }
63
+ this.assertOutputFiredForSuccessors(step, execution, outputs);
64
+ return outputs;
65
+ }
66
+ assertOutputFiredForSuccessors(step, execution, outputs) {
67
+ const hasSuccessors = execution.graph.edges.some((edge) => edge.from === step.nodeId);
68
+ if (hasSuccessors && (outputs.length === 0 || outputs[0] === null)) {
69
+ throw new common_1.UnimplementedError(`step ${step.id} runs node ${step.nodeId}, which did not fire output slot 0 despite having successors; branch selection is not supported yet`);
70
+ }
71
+ }
72
+ async gatherInputs(execution, step) {
73
+ const incoming = execution.graph.edges.filter((edge) => edge.to === step.nodeId);
74
+ if (incoming.length === 0) {
75
+ throw new common_1.UnexpectedError(`step ${step.id} runs node ${step.nodeId}, which has no predecessor in the execution graph`);
76
+ }
77
+ if (incoming.length > 1) {
78
+ throw new common_1.UnexpectedError(`step ${step.id} runs node ${step.nodeId}, which has ${incoming.length} incoming edges; validated graphs have at most one edge per input slot`);
79
+ }
80
+ const [edge] = incoming;
81
+ if (edge.outputIndex !== 0 || edge.inputIndex !== 0) {
82
+ throw new common_1.UnexpectedError(`step ${step.id} runs node ${step.nodeId} through edge slots ${edge.outputIndex} → ${edge.inputIndex}; validated graphs only use slot 0`);
83
+ }
84
+ const outputsByNodeId = await this.stepStore.loadStepOutputs(execution.id, [edge.from]);
85
+ const predecessorOutputs = outputsByNodeId[edge.from];
86
+ if (!predecessorOutputs) {
87
+ throw new common_1.UnexpectedError(`step ${step.id} reads node ${edge.from}, whose step has not completed`);
88
+ }
89
+ if (predecessorOutputs.length > 1) {
90
+ throw new common_1.UnexpectedError(`step ${step.id} reads node ${edge.from}, whose step recorded more than one output slot; the write-time guard admits only slot 0`);
91
+ }
92
+ return [predecessorOutputs[0] ?? null];
93
+ }
94
+ executorFor(step, node) {
95
+ if (node.type === 'v1-node') {
96
+ const executor = this.dependencies.v1StepExecutor;
97
+ if (!executor) {
98
+ throw new common_1.UnimplementedError(`step ${step.id}: no executor configured for v1-node steps; the host must supply one in integrated mode`);
99
+ }
100
+ return executor;
101
+ }
102
+ throw new common_1.UnimplementedError(`step ${step.id}: no executor for step type ${node.type}`);
103
+ }
104
+ }
105
+ exports.StepReadyHandler = StepReadyHandler;
106
+ function toStepError(error) {
107
+ if (error instanceof Error) {
108
+ return { name: error.name, message: error.message, stack: error.stack };
109
+ }
110
+ return { name: 'Error', message: String(error) };
111
+ }
112
+ //# sourceMappingURL=step-ready-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-ready-handler.js","sourceRoot":"","sources":["../../src/execution/step-ready-handler.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,41 @@
1
- import type { StepStatus } from './execution.types';
1
+ import type { JsonValue } from '../common';
2
+ import type { StepSlots, StepStatus } from './execution.types';
2
3
  export interface NewStepRecord {
3
4
  executionId: string;
4
5
  nodeId: string;
5
6
  status: StepStatus;
7
+ outputs?: StepSlots;
8
+ }
9
+ export interface StepError {
10
+ name: string;
11
+ message: string;
12
+ stack?: string;
13
+ details?: JsonValue;
14
+ }
15
+ export interface StepRecord {
16
+ id: string;
17
+ executionId: string;
18
+ nodeId: string;
19
+ status: StepStatus;
20
+ outputs: StepSlots | null;
21
+ error: StepError | null;
22
+ }
23
+ export declare class StepNotFoundError extends Error {
24
+ readonly stepId: string;
25
+ constructor(stepId: string);
6
26
  }
7
27
  export interface StepStore {
8
- createStep(record: NewStepRecord): Promise<{
28
+ createSteps(records: NewStepRecord[]): Promise<Array<{
9
29
  id: string;
10
- }>;
30
+ nodeId: string;
31
+ }>>;
32
+ loadStep(id: string): Promise<StepRecord>;
33
+ claimStep(id: string): Promise<StepRecord | null>;
34
+ completeStep(id: string, outputs: StepSlots): Promise<boolean>;
35
+ failStep(id: string, error: StepError): Promise<boolean>;
36
+ cancelQueuedSteps(executionId: string): Promise<void>;
37
+ loadStepOutputs(executionId: string, nodeIds: string[]): Promise<Record<string, StepSlots | null>>;
38
+ loadCompletedNodeIds(executionId: string, nodeIds: string[]): Promise<Set<string>>;
39
+ hasActiveSteps(executionId: string): Promise<boolean>;
40
+ hasFailedSteps(executionId: string): Promise<boolean>;
11
41
  }
@@ -1,3 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StepNotFoundError = void 0;
4
+ class StepNotFoundError extends Error {
5
+ stepId;
6
+ constructor(stepId) {
7
+ super(`Step not found: ${stepId}`);
8
+ this.stepId = stepId;
9
+ this.name = 'StepNotFoundError';
10
+ }
11
+ }
12
+ exports.StepNotFoundError = StepNotFoundError;
3
13
  //# sourceMappingURL=step-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"step-store.js","sourceRoot":"","sources":["../../src/execution/step-store.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"step-store.js","sourceRoot":"","sources":["../../src/execution/step-store.ts"],"names":[],"mappings":";;;AAsCA,uBAA+B,SAAQ,KAAK;IACtB,MAAM;IAA3B,YAAqB,MAAc;QAClC,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;sBADf,MAAM;QAE1B,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IACjC,CAAC;CACD"}
@@ -0,0 +1,9 @@
1
+ import type { StepMessage, WorkQueue } from '../queue';
2
+ import type { StepReadyHandler } from './step-ready-handler';
3
+ export declare class StepWorker {
4
+ private readonly stepQueue;
5
+ private readonly readyHandler;
6
+ constructor(stepQueue: WorkQueue<StepMessage>, readyHandler: StepReadyHandler);
7
+ start(): void;
8
+ stop(): Promise<void>;
9
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StepWorker = void 0;
4
+ const common_1 = require("../common");
5
+ class StepWorker {
6
+ stepQueue;
7
+ readyHandler;
8
+ constructor(stepQueue, readyHandler) {
9
+ this.stepQueue = stepQueue;
10
+ this.readyHandler = readyHandler;
11
+ }
12
+ start() {
13
+ this.stepQueue.start(async (message) => {
14
+ switch (message.type) {
15
+ case 'step:ready':
16
+ await this.readyHandler.handle(message);
17
+ break;
18
+ default: {
19
+ const unhandled = message.type;
20
+ throw new common_1.UnimplementedError(`step worker received an unimplemented message type: ${String(unhandled)}`);
21
+ }
22
+ }
23
+ });
24
+ }
25
+ async stop() {
26
+ await this.stepQueue.stop();
27
+ }
28
+ }
29
+ exports.StepWorker = StepWorker;
30
+ //# sourceMappingURL=step-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-worker.js","sourceRoot":"","sources":["../../src/execution/step-worker.ts"],"names":[],"mappings":";;;AAAA,sCAA+C;AAQ/C;IAEmB,SAAS;IACT,YAAY;IAF9B,YACkB,SAAiC,EACjC,YAA8B;yBAD9B,SAAS;4BACT,YAAY;IAC3B,CAAC;IAEJ,KAAK;QACJ,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YACtC,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;gBACtB,KAAK,YAAY;oBAChB,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;oBACxC,MAAM;gBACP,SAAS,CAAC;oBAGT,MAAM,SAAS,GAAU,OAAO,CAAC,IAAI,CAAC;oBACtC,MAAM,IAAI,2BAAkB,CAC3B,uDAAuD,MAAM,CAAC,SAAS,CAAC,EAAE,CAC1E,CAAC;gBACH,CAAC;YACF,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI;QACT,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;CACD"}
@@ -0,0 +1,4 @@
1
+ import type { GraphNode } from '../graph';
2
+ import type { ExecutionRecord } from './execution-store';
3
+ import type { StepRecord } from './step-store';
4
+ export declare function validateStepContext(step: StepRecord, execution: ExecutionRecord): GraphNode;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateStepContext = validateStepContext;
4
+ const common_1 = require("../common");
5
+ function validateStepContext(step, execution) {
6
+ if (step.executionId !== execution.id) {
7
+ throw new common_1.UnexpectedError(`step ${step.id} belongs to execution ${step.executionId}, but the event claims ${execution.id}`);
8
+ }
9
+ const node = execution.graph.nodes.find((candidate) => candidate.id === step.nodeId);
10
+ if (!node) {
11
+ throw new common_1.UnexpectedError(`step ${step.id} references node ${step.nodeId}, which is absent from the execution graph`);
12
+ }
13
+ return node;
14
+ }
15
+ //# sourceMappingURL=validate-step-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-step-context.js","sourceRoot":"","sources":["../../src/execution/validate-step-context.ts"],"names":[],"mappings":";;;AAAA,sCAA4C;AAY5C,6BAAoC,IAAgB,EAAE,SAA0B;IAC/E,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,IAAI,wBAAe,CACxB,QAAQ,IAAI,CAAC,EAAE,yBAAyB,IAAI,CAAC,WAAW,0BAA0B,SAAS,CAAC,EAAE,EAAE,CAChG,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC;IACrF,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,MAAM,IAAI,wBAAe,CACxB,QAAQ,IAAI,CAAC,EAAE,oBAAoB,IAAI,CAAC,MAAM,4CAA4C,CAC1F,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC"}
@@ -1 +1,3 @@
1
1
  export type { GraphEdge, GraphNode, StepConfig, StepType, WorkflowGraph, } from './workflow-graph';
2
+ export { findTriggerNode, getPredecessorNodeIds, getSuccessorNodeIds, } from './workflow-graph-queries';
3
+ export { GraphValidationError, validateExecutableGraph } from './validate-executable-graph';
@@ -1,3 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateExecutableGraph = exports.GraphValidationError = exports.getSuccessorNodeIds = exports.getPredecessorNodeIds = exports.findTriggerNode = void 0;
4
+ var workflow_graph_queries_1 = require("./workflow-graph-queries");
5
+ Object.defineProperty(exports, "findTriggerNode", { enumerable: true, get: function () { return workflow_graph_queries_1.findTriggerNode; } });
6
+ Object.defineProperty(exports, "getPredecessorNodeIds", { enumerable: true, get: function () { return workflow_graph_queries_1.getPredecessorNodeIds; } });
7
+ Object.defineProperty(exports, "getSuccessorNodeIds", { enumerable: true, get: function () { return workflow_graph_queries_1.getSuccessorNodeIds; } });
8
+ var validate_executable_graph_1 = require("./validate-executable-graph");
9
+ Object.defineProperty(exports, "GraphValidationError", { enumerable: true, get: function () { return validate_executable_graph_1.GraphValidationError; } });
10
+ Object.defineProperty(exports, "validateExecutableGraph", { enumerable: true, get: function () { return validate_executable_graph_1.validateExecutableGraph; } });
3
11
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":";;;AAOA,mEAIkC;AAHjC,yHAAA,eAAe,OAAA;AACf,+HAAA,qBAAqB,OAAA;AACrB,6HAAA,mBAAmB,OAAA;AAEpB,yEAA4F;AAAnF,iIAAA,oBAAoB,OAAA;AAAE,oIAAA,uBAAuB,OAAA"}
@@ -0,0 +1,5 @@
1
+ import type { WorkflowGraph } from './workflow-graph';
2
+ export declare class GraphValidationError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export declare function validateExecutableGraph(graph: WorkflowGraph): void;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GraphValidationError = void 0;
4
+ exports.validateExecutableGraph = validateExecutableGraph;
5
+ const common_1 = require("../common");
6
+ class GraphValidationError extends Error {
7
+ constructor(message) {
8
+ super(message);
9
+ this.name = 'GraphValidationError';
10
+ }
11
+ }
12
+ exports.GraphValidationError = GraphValidationError;
13
+ function validateExecutableGraph(graph) {
14
+ const triggers = graph.nodes.filter((node) => node.type === 'trigger');
15
+ if (triggers.length === 0) {
16
+ throw new GraphValidationError('Graph has no trigger node to start from');
17
+ }
18
+ if (triggers.length > 1) {
19
+ throw new GraphValidationError('Graph must have exactly one trigger node');
20
+ }
21
+ if (graph.edges.some((edge) => edge.isBackEdge)) {
22
+ throw new common_1.UnimplementedError('Graphs with back-edges (loops) are not supported yet');
23
+ }
24
+ for (const edge of graph.edges) {
25
+ if (edge.outputIndex !== 0) {
26
+ throw new common_1.UnimplementedError(`Edge ${edge.from} → ${edge.to} leaves output slot ${edge.outputIndex}; only output slot 0 is supported yet`);
27
+ }
28
+ if (edge.inputIndex !== 0) {
29
+ throw new common_1.UnimplementedError(`Edge ${edge.from} → ${edge.to} arrives at input slot ${edge.inputIndex}; only input slot 0 is supported yet`);
30
+ }
31
+ }
32
+ const seenInputSlots = new Set();
33
+ for (const edge of graph.edges) {
34
+ const slot = `${edge.to}#${edge.inputIndex}`;
35
+ if (seenInputSlots.has(slot)) {
36
+ throw new common_1.UnimplementedError(`Node ${edge.to} has more than one edge into input slot ${edge.inputIndex}; converging branches on one slot is not supported yet`);
37
+ }
38
+ seenInputSlots.add(slot);
39
+ }
40
+ }
41
+ //# sourceMappingURL=validate-executable-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-executable-graph.js","sourceRoot":"","sources":["../../src/graph/validate-executable-graph.ts"],"names":[],"mappings":";;;;AAAA,sCAA+C;AAI/C,0BAAkC,SAAQ,KAAK;IAC9C,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACpC,CAAC;CACD;;AAUD,iCAAwC,KAAoB;IAC3D,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IACvE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,oBAAoB,CAAC,yCAAyC,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,oBAAoB,CAAC,0CAA0C,CAAC,CAAC;IAC5E,CAAC;IAID,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,2BAAkB,CAAC,sDAAsD,CAAC,CAAC;IACtF,CAAC;IAID,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,WAAW,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,2BAAkB,CAC3B,QAAQ,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,uBAAuB,IAAI,CAAC,WAAW,uCAAuC,CAC5G,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,2BAAkB,CAC3B,QAAQ,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,0BAA0B,IAAI,CAAC,UAAU,sCAAsC,CAC7G,CAAC;QACH,CAAC;IACF,CAAC;IAID,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QAC7C,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,2BAAkB,CAC3B,QAAQ,IAAI,CAAC,EAAE,2CAA2C,IAAI,CAAC,UAAU,wDAAwD,CACjI,CAAC;QACH,CAAC;QACD,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;AACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { GraphNode, WorkflowGraph } from './workflow-graph';
2
+ export declare function findTriggerNode(graph: WorkflowGraph): GraphNode | undefined;
3
+ export declare function getSuccessorNodeIds(graph: WorkflowGraph, nodeId: string): string[];
4
+ export declare function getPredecessorNodeIds(graph: WorkflowGraph, nodeId: string): string[];
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findTriggerNode = findTriggerNode;
4
+ exports.getSuccessorNodeIds = getSuccessorNodeIds;
5
+ exports.getPredecessorNodeIds = getPredecessorNodeIds;
6
+ function findTriggerNode(graph) {
7
+ return graph.nodes.find((node) => node.type === 'trigger');
8
+ }
9
+ function getSuccessorNodeIds(graph, nodeId) {
10
+ const successors = [];
11
+ for (const edge of graph.edges) {
12
+ if (edge.from === nodeId && !successors.includes(edge.to)) {
13
+ successors.push(edge.to);
14
+ }
15
+ }
16
+ return successors;
17
+ }
18
+ function getPredecessorNodeIds(graph, nodeId) {
19
+ const predecessors = [];
20
+ for (const edge of graph.edges) {
21
+ if (edge.to === nodeId && !predecessors.includes(edge.from)) {
22
+ predecessors.push(edge.from);
23
+ }
24
+ }
25
+ return predecessors;
26
+ }
27
+ //# sourceMappingURL=workflow-graph-queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-graph-queries.js","sourceRoot":"","sources":["../../src/graph/workflow-graph-queries.ts"],"names":[],"mappings":";;;;;AAGA,yBAAgC,KAAoB;IACnD,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;AAC5D,CAAC;AAOD,6BAAoC,KAAoB,EAAE,MAAc;IACvE,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YAC3D,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1B,CAAC;IACF,CAAC;IACD,OAAO,UAAU,CAAC;AACnB,CAAC;AAOD,+BAAsC,KAAoB,EAAE,MAAc;IACzE,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7D,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;IACF,CAAC;IACD,OAAO,YAAY,CAAC;AACrB,CAAC"}
@@ -9,8 +9,8 @@ export interface GraphNode {
9
9
  export interface GraphEdge {
10
10
  from: string;
11
11
  to: string;
12
- outputIndex?: number;
13
- inputIndex?: number;
12
+ outputIndex: number;
13
+ inputIndex: number;
14
14
  isBackEdge?: boolean;
15
15
  }
16
16
  export interface WorkflowGraph {
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export type { ExternalDependencies, IStepExecutor, StepExecutionContext, StepExe
6
6
  export { AllowAllAdmittance, AdmittanceRejectedError } from './admittance';
7
7
  export type { AdmittanceDecision, AdmittanceRequest, AdmittanceService, } from './admittance';
8
8
  export { InMemoryWorkQueue } from './queue';
9
- export type { ExecutionEnqueuedEvent, WorkQueue, WorkQueueMessage, } from './queue';
10
- export type { ExecutionMode, ExecutionStatus, ExecutionStore, NewExecutionRecord, NewStepRecord, StepStatus, StepStore, } from './execution';
9
+ export type { ExecutionEnqueuedEvent, OrchestrationMessage, StepCompletedEvent, StepMessage, StepReadyEvent, WorkQueue, } from './queue';
10
+ export { ExecutionNotFoundError, ExecutionStartHandler, OrchestrationWorker, StepCompletedHandler, StepNotFoundError, StepReadyHandler, StepWorker, } from './execution';
11
+ export type { ExecutionMode, ExecutionRecord, ExecutionStatus, ExecutionStore, NewExecutionRecord, NewStepRecord, StepError, StepRecord, StepSlots, StepStatus, StepStore, } from './execution';
11
12
  export { createDataSource, TypeOrmExecutionStore, TypeOrmStepStore } from './database';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TypeOrmStepStore = exports.TypeOrmExecutionStore = exports.createDataSource = exports.InMemoryWorkQueue = exports.AdmittanceRejectedError = exports.AllowAllAdmittance = exports.createEngineServer = void 0;
3
+ exports.TypeOrmStepStore = exports.TypeOrmExecutionStore = exports.createDataSource = exports.StepWorker = exports.StepReadyHandler = exports.StepNotFoundError = exports.StepCompletedHandler = exports.OrchestrationWorker = exports.ExecutionStartHandler = exports.ExecutionNotFoundError = exports.InMemoryWorkQueue = exports.AdmittanceRejectedError = exports.AllowAllAdmittance = exports.createEngineServer = void 0;
4
4
  var server_1 = require("./server");
5
5
  Object.defineProperty(exports, "createEngineServer", { enumerable: true, get: function () { return server_1.createEngineServer; } });
6
6
  var admittance_1 = require("./admittance");
@@ -8,6 +8,14 @@ Object.defineProperty(exports, "AllowAllAdmittance", { enumerable: true, get: fu
8
8
  Object.defineProperty(exports, "AdmittanceRejectedError", { enumerable: true, get: function () { return admittance_1.AdmittanceRejectedError; } });
9
9
  var queue_1 = require("./queue");
10
10
  Object.defineProperty(exports, "InMemoryWorkQueue", { enumerable: true, get: function () { return queue_1.InMemoryWorkQueue; } });
11
+ var execution_1 = require("./execution");
12
+ Object.defineProperty(exports, "ExecutionNotFoundError", { enumerable: true, get: function () { return execution_1.ExecutionNotFoundError; } });
13
+ Object.defineProperty(exports, "ExecutionStartHandler", { enumerable: true, get: function () { return execution_1.ExecutionStartHandler; } });
14
+ Object.defineProperty(exports, "OrchestrationWorker", { enumerable: true, get: function () { return execution_1.OrchestrationWorker; } });
15
+ Object.defineProperty(exports, "StepCompletedHandler", { enumerable: true, get: function () { return execution_1.StepCompletedHandler; } });
16
+ Object.defineProperty(exports, "StepNotFoundError", { enumerable: true, get: function () { return execution_1.StepNotFoundError; } });
17
+ Object.defineProperty(exports, "StepReadyHandler", { enumerable: true, get: function () { return execution_1.StepReadyHandler; } });
18
+ Object.defineProperty(exports, "StepWorker", { enumerable: true, get: function () { return execution_1.StepWorker; } });
11
19
  var database_1 = require("./database");
12
20
  Object.defineProperty(exports, "createDataSource", { enumerable: true, get: function () { return database_1.createDataSource; } });
13
21
  Object.defineProperty(exports, "TypeOrmExecutionStore", { enumerable: true, get: function () { return database_1.TypeOrmExecutionStore; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAA8C;AAArC,4GAAA,kBAAkB,OAAA;AAqB3B,2CAA2E;AAAlE,gHAAA,kBAAkB,OAAA;AAAE,qHAAA,uBAAuB,OAAA;AAOpD,iCAA4C;AAAnC,0GAAA,iBAAiB,OAAA;AAiB1B,uCAAuF;AAA9E,4GAAA,gBAAgB,OAAA;AAAE,iHAAA,qBAAqB,OAAA;AAAE,4GAAA,gBAAgB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAA8C;AAArC,4GAAA,kBAAkB,OAAA;AAqB3B,2CAA2E;AAAlE,gHAAA,kBAAkB,OAAA;AAAE,qHAAA,uBAAuB,OAAA;AAOpD,iCAA4C;AAAnC,0GAAA,iBAAiB,OAAA;AAU1B,yCAQqB;AAPpB,mHAAA,sBAAsB,OAAA;AACtB,kHAAA,qBAAqB,OAAA;AACrB,gHAAA,mBAAmB,OAAA;AACnB,iHAAA,oBAAoB,OAAA;AACpB,8GAAA,iBAAiB,OAAA;AACjB,6GAAA,gBAAgB,OAAA;AAChB,uGAAA,UAAU,OAAA;AAgBX,uCAAuF;AAA9E,4GAAA,gBAAgB,OAAA;AAAE,iHAAA,qBAAqB,OAAA;AAAE,4GAAA,gBAAgB,OAAA"}
@@ -1,5 +1,12 @@
1
- import type { WorkQueue, WorkQueueMessage } from './work-queue.types';
2
- export declare class InMemoryWorkQueue implements WorkQueue {
3
- readonly messages: WorkQueueMessage[];
4
- publish(message: WorkQueueMessage): Promise<void>;
1
+ import type { WorkQueue } from './work-queue.types';
2
+ export declare class InMemoryWorkQueue<TMessage> implements WorkQueue<TMessage> {
3
+ private pending;
4
+ private handler;
5
+ private dispatching;
6
+ private idleWaiters;
7
+ publish(message: TMessage): Promise<void>;
8
+ start(handler: (message: TMessage) => Promise<void>): void;
9
+ stop(): Promise<void>;
10
+ private startDispatchLoop;
11
+ private dispatchPending;
5
12
  }
@@ -2,9 +2,51 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InMemoryWorkQueue = void 0;
4
4
  class InMemoryWorkQueue {
5
- messages = [];
5
+ pending = [];
6
+ handler;
7
+ dispatching = false;
8
+ idleWaiters = [];
6
9
  async publish(message) {
7
- this.messages.push(message);
10
+ this.pending.push(message);
11
+ this.startDispatchLoop();
12
+ }
13
+ start(handler) {
14
+ this.handler = handler;
15
+ this.startDispatchLoop();
16
+ }
17
+ async stop() {
18
+ this.handler = undefined;
19
+ if (!this.dispatching)
20
+ return;
21
+ await new Promise((resolve) => this.idleWaiters.push(resolve));
22
+ }
23
+ startDispatchLoop() {
24
+ if (this.dispatching || !this.handler || this.pending.length === 0)
25
+ return;
26
+ this.dispatching = true;
27
+ this.dispatchPending().catch((error) => {
28
+ console.error('engine: work queue dispatch failed', error);
29
+ });
30
+ }
31
+ async dispatchPending() {
32
+ try {
33
+ while (this.handler && this.pending.length > 0) {
34
+ const [message] = this.pending.splice(0, 1);
35
+ try {
36
+ await this.handler(message);
37
+ }
38
+ catch (error) {
39
+ console.error('engine: work queue handler failed', error);
40
+ }
41
+ }
42
+ }
43
+ finally {
44
+ this.dispatching = false;
45
+ const waiters = this.idleWaiters;
46
+ this.idleWaiters = [];
47
+ for (const resolve of waiters)
48
+ resolve();
49
+ }
8
50
  }
9
51
  }
10
52
  exports.InMemoryWorkQueue = InMemoryWorkQueue;