@n8n/engine 0.15.4 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build.tsbuildinfo +1 -1
- package/dist/database/create-stores.d.ts +7 -0
- package/dist/database/create-stores.js +13 -0
- package/dist/database/create-stores.js.map +1 -0
- package/dist/database/index.d.ts +1 -0
- package/dist/database/index.js +3 -1
- package/dist/database/index.js.map +1 -1
- package/dist/database/migrations/1784890100000-CreateWorkflowStepExecution.js +1 -1
- package/dist/database/migrations/1784890100000-CreateWorkflowStepExecution.js.map +1 -1
- package/dist/database/typeorm-step-store.d.ts +7 -7
- package/dist/database/typeorm-step-store.js +96 -56
- package/dist/database/typeorm-step-store.js.map +1 -1
- package/dist/execution/execution-start-handler.js +2 -3
- package/dist/execution/execution-start-handler.js.map +1 -1
- package/dist/execution/execution.types.d.ts +3 -1
- package/dist/execution/execution.types.js +11 -0
- package/dist/execution/execution.types.js.map +1 -1
- package/dist/execution/index.d.ts +1 -1
- package/dist/execution/index.js +3 -3
- package/dist/execution/index.js.map +1 -1
- package/dist/execution/orchestration-worker.d.ts +3 -3
- package/dist/execution/orchestration-worker.js +5 -5
- package/dist/execution/orchestration-worker.js.map +1 -1
- package/dist/execution/settlement.d.ts +7 -0
- package/dist/execution/settlement.js +31 -0
- package/dist/execution/settlement.js.map +1 -0
- package/dist/execution/step-ready-handler.d.ts +0 -1
- package/dist/execution/step-ready-handler.js +29 -28
- package/dist/execution/step-ready-handler.js.map +1 -1
- package/dist/execution/step-settled-handler.d.ts +17 -0
- package/dist/execution/step-settled-handler.js +97 -0
- package/dist/execution/step-settled-handler.js.map +1 -0
- package/dist/execution/step-store.d.ts +18 -9
- package/dist/execution/step-store.js.map +1 -1
- package/dist/graph/index.d.ts +1 -1
- package/dist/graph/index.js +2 -1
- package/dist/graph/index.js.map +1 -1
- package/dist/graph/validate-executable-graph.js +15 -4
- package/dist/graph/validate-executable-graph.js.map +1 -1
- package/dist/graph/workflow-graph-queries.d.ts +1 -0
- package/dist/graph/workflow-graph-queries.js +14 -0
- package/dist/graph/workflow-graph-queries.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/queue/index.d.ts +1 -1
- package/dist/queue/work-queue.types.d.ts +3 -3
- package/dist/serve.js +2 -3
- package/dist/serve.js.map +1 -1
- package/package.json +8 -7
- package/dist/execution/step-completed-handler.d.ts +0 -13
- package/dist/execution/step-completed-handler.js +0 -74
- package/dist/execution/step-completed-handler.js.map +0 -1
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StepReadyHandler = void 0;
|
|
4
4
|
const common_1 = require("../common");
|
|
5
|
+
const execution_types_1 = require("./execution.types");
|
|
5
6
|
const validate_step_context_1 = require("./validate-step-context");
|
|
6
7
|
class StepReadyHandler {
|
|
7
8
|
executionStore;
|
|
@@ -41,7 +42,7 @@ class StepReadyHandler {
|
|
|
41
42
|
if (!recorded)
|
|
42
43
|
return;
|
|
43
44
|
await this.orchestrationQueue.publish({
|
|
44
|
-
type: 'step:
|
|
45
|
+
type: 'step:settled',
|
|
45
46
|
executionId: event.executionId,
|
|
46
47
|
stepId: event.stepId,
|
|
47
48
|
});
|
|
@@ -57,39 +58,21 @@ class StepReadyHandler {
|
|
|
57
58
|
mode: execution.mode,
|
|
58
59
|
},
|
|
59
60
|
});
|
|
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
61
|
return outputs;
|
|
65
62
|
}
|
|
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
63
|
async gatherInputs(execution, step) {
|
|
73
|
-
const
|
|
74
|
-
if (
|
|
64
|
+
const incomingEdges = execution.graph.edges.filter((edge) => edge.to === step.nodeId);
|
|
65
|
+
if (incomingEdges.length === 0) {
|
|
75
66
|
throw new common_1.UnexpectedError(`step ${step.id} runs node ${step.nodeId}, which has no predecessor in the execution graph`);
|
|
76
67
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
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`);
|
|
68
|
+
validateIncomingEdges(incomingEdges, step);
|
|
69
|
+
const predecessorNodeIds = [...new Set(incomingEdges.map((edge) => edge.from))];
|
|
70
|
+
const predecessorSteps = await this.stepStore.loadStepsByNodeIds(execution.id, predecessorNodeIds);
|
|
71
|
+
const inputs = Array.from({ length: Math.max(...incomingEdges.map((edge) => edge.inputIndex)) + 1 }, () => null);
|
|
72
|
+
for (const edge of incomingEdges) {
|
|
73
|
+
inputs[edge.inputIndex] = readEdgeValue(edge, predecessorSteps, step);
|
|
91
74
|
}
|
|
92
|
-
return
|
|
75
|
+
return inputs;
|
|
93
76
|
}
|
|
94
77
|
executorFor(step, node) {
|
|
95
78
|
if (node.type === 'v1-node') {
|
|
@@ -103,6 +86,24 @@ class StepReadyHandler {
|
|
|
103
86
|
}
|
|
104
87
|
}
|
|
105
88
|
exports.StepReadyHandler = StepReadyHandler;
|
|
89
|
+
function validateIncomingEdges(incomingEdges, step) {
|
|
90
|
+
const filledSlots = new Set();
|
|
91
|
+
for (const edge of incomingEdges) {
|
|
92
|
+
if (filledSlots.has(edge.inputIndex)) {
|
|
93
|
+
throw new common_1.UnexpectedError(`step ${step.id} runs node ${step.nodeId}, which has more than one edge into input slot ${edge.inputIndex}; validated graphs have at most one edge per input slot`);
|
|
94
|
+
}
|
|
95
|
+
filledSlots.add(edge.inputIndex);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function readEdgeValue(edge, predecessorSteps, step) {
|
|
99
|
+
const row = predecessorSteps[edge.from];
|
|
100
|
+
if (!row || !(0, execution_types_1.isSettledStatus)(row.status)) {
|
|
101
|
+
throw new common_1.UnexpectedError(`step ${step.id} reads node ${edge.from}, whose step has not settled`);
|
|
102
|
+
}
|
|
103
|
+
if (row.status !== 'completed')
|
|
104
|
+
return null;
|
|
105
|
+
return row.outputs?.[edge.outputIndex] ?? null;
|
|
106
|
+
}
|
|
106
107
|
function toStepError(error) {
|
|
107
108
|
if (error instanceof Error) {
|
|
108
109
|
return { name: error.name, message: error.message, stack: error.stack };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step-ready-handler.js","sourceRoot":"","sources":["../../src/execution/step-ready-handler.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"step-ready-handler.js","sourceRoot":"","sources":["../../src/execution/step-ready-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { OrchestrationMessage, StepMessage, StepSettledEvent, WorkQueue } from '../queue';
|
|
2
|
+
import type { ExecutionStore } from './execution-store';
|
|
3
|
+
import type { StepStore } from './step-store';
|
|
4
|
+
export declare class StepSettledHandler {
|
|
5
|
+
private readonly executionStore;
|
|
6
|
+
private readonly stepStore;
|
|
7
|
+
private readonly stepQueue;
|
|
8
|
+
private readonly orchestrationQueue;
|
|
9
|
+
constructor(executionStore: ExecutionStore, stepStore: StepStore, stepQueue: WorkQueue<StepMessage>, orchestrationQueue: WorkQueue<OrchestrationMessage>);
|
|
10
|
+
handle(event: StepSettledEvent): Promise<void>;
|
|
11
|
+
private failExecution;
|
|
12
|
+
private planSuccessors;
|
|
13
|
+
private loadDecisionSteps;
|
|
14
|
+
private announceCreatedSteps;
|
|
15
|
+
private finishExecutionIfDone;
|
|
16
|
+
private reachableNodeCount;
|
|
17
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StepSettledHandler = void 0;
|
|
4
|
+
const common_1 = require("../common");
|
|
5
|
+
const graph_1 = require("../graph");
|
|
6
|
+
const settlement_1 = require("./settlement");
|
|
7
|
+
const validate_step_context_1 = require("./validate-step-context");
|
|
8
|
+
class StepSettledHandler {
|
|
9
|
+
executionStore;
|
|
10
|
+
stepStore;
|
|
11
|
+
stepQueue;
|
|
12
|
+
orchestrationQueue;
|
|
13
|
+
constructor(executionStore, stepStore, stepQueue, orchestrationQueue) {
|
|
14
|
+
this.executionStore = executionStore;
|
|
15
|
+
this.stepStore = stepStore;
|
|
16
|
+
this.stepQueue = stepQueue;
|
|
17
|
+
this.orchestrationQueue = orchestrationQueue;
|
|
18
|
+
}
|
|
19
|
+
async handle(event) {
|
|
20
|
+
const [step, execution] = await Promise.all([
|
|
21
|
+
this.stepStore.loadStep(event.stepId),
|
|
22
|
+
this.executionStore.loadExecution(event.executionId),
|
|
23
|
+
]);
|
|
24
|
+
(0, validate_step_context_1.validateStepContext)(step, execution);
|
|
25
|
+
if (step.status === 'failed') {
|
|
26
|
+
await this.failExecution(execution.id);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (execution.status !== 'running')
|
|
30
|
+
return;
|
|
31
|
+
let queued = 0;
|
|
32
|
+
if (step.status === 'completed' || step.status === 'skipped') {
|
|
33
|
+
if (await this.stepStore.hasFailedSteps(execution.id)) {
|
|
34
|
+
await this.failExecution(execution.id);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const steps = await this.loadDecisionSteps(execution, step.nodeId);
|
|
38
|
+
queued = await this.planSuccessors(execution, step.nodeId, steps);
|
|
39
|
+
}
|
|
40
|
+
if (queued > 0)
|
|
41
|
+
return;
|
|
42
|
+
await this.finishExecutionIfDone(execution);
|
|
43
|
+
}
|
|
44
|
+
async failExecution(executionId) {
|
|
45
|
+
await this.executionStore.finishExecution(executionId, 'failed');
|
|
46
|
+
await this.stepStore.cancelQueuedSteps(executionId);
|
|
47
|
+
}
|
|
48
|
+
async planSuccessors(execution, nodeId, steps) {
|
|
49
|
+
const { toQueue, toSkip } = (0, settlement_1.decideSuccessors)(execution.graph, nodeId, steps);
|
|
50
|
+
if (toQueue.length === 0 && toSkip.length === 0)
|
|
51
|
+
return 0;
|
|
52
|
+
const created = await this.stepStore.createSteps(execution.id, [
|
|
53
|
+
...toQueue.map((id) => ({ nodeId: id, status: 'queued' })),
|
|
54
|
+
...toSkip.map((id) => ({ nodeId: id, status: 'skipped' })),
|
|
55
|
+
]);
|
|
56
|
+
return await this.announceCreatedSteps(execution.id, created, new Set(toQueue));
|
|
57
|
+
}
|
|
58
|
+
async loadDecisionSteps(execution, nodeId) {
|
|
59
|
+
const successors = (0, graph_1.getSuccessorNodeIds)(execution.graph, nodeId);
|
|
60
|
+
const nodeIds = [
|
|
61
|
+
...new Set([
|
|
62
|
+
...successors,
|
|
63
|
+
...successors.flatMap((id) => (0, graph_1.getPredecessorNodeIds)(execution.graph, id)),
|
|
64
|
+
]),
|
|
65
|
+
];
|
|
66
|
+
return await this.stepStore.loadStepSummaries(execution.id, nodeIds);
|
|
67
|
+
}
|
|
68
|
+
async announceCreatedSteps(executionId, created, queuedNodeIds) {
|
|
69
|
+
let queued = 0;
|
|
70
|
+
for (const { id: stepId, nodeId } of created) {
|
|
71
|
+
if (queuedNodeIds.has(nodeId)) {
|
|
72
|
+
queued += 1;
|
|
73
|
+
await this.stepQueue.publish({ type: 'step:ready', executionId, stepId });
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
await this.orchestrationQueue.publish({ type: 'step:settled', executionId, stepId });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return queued;
|
|
80
|
+
}
|
|
81
|
+
async finishExecutionIfDone(execution) {
|
|
82
|
+
const settled = await this.stepStore.countSettledSteps(execution.id);
|
|
83
|
+
if (settled < this.reachableNodeCount(execution))
|
|
84
|
+
return;
|
|
85
|
+
const failed = await this.stepStore.hasFailedSteps(execution.id);
|
|
86
|
+
await this.executionStore.finishExecution(execution.id, failed ? 'failed' : 'completed');
|
|
87
|
+
}
|
|
88
|
+
reachableNodeCount(execution) {
|
|
89
|
+
const trigger = (0, graph_1.findTriggerNode)(execution.graph);
|
|
90
|
+
if (!trigger) {
|
|
91
|
+
throw new common_1.UnexpectedError(`Execution ${execution.id} has no trigger node in its graph`);
|
|
92
|
+
}
|
|
93
|
+
return 1 + (0, graph_1.getDescendantNodeIds)(execution.graph, trigger.id).length;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
exports.StepSettledHandler = StepSettledHandler;
|
|
97
|
+
//# sourceMappingURL=step-settled-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-settled-handler.js","sourceRoot":"","sources":["../../src/execution/step-settled-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { JsonValue } from '../common';
|
|
2
2
|
import type { StepSlots, StepStatus } from './execution.types';
|
|
3
|
-
export
|
|
4
|
-
executionId: string;
|
|
3
|
+
export type NewStepRecord = {
|
|
5
4
|
nodeId: string;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
} & ({
|
|
6
|
+
status: Extract<StepStatus, 'queued' | 'skipped'>;
|
|
7
|
+
outputs?: never;
|
|
8
|
+
} | {
|
|
9
|
+
status: Extract<StepStatus, 'completed'>;
|
|
10
|
+
outputs: StepSlots;
|
|
11
|
+
});
|
|
9
12
|
export interface StepError {
|
|
10
13
|
name: string;
|
|
11
14
|
message: string;
|
|
@@ -20,12 +23,18 @@ export interface StepRecord {
|
|
|
20
23
|
outputs: StepSlots | null;
|
|
21
24
|
error: StepError | null;
|
|
22
25
|
}
|
|
26
|
+
export interface StepSummary {
|
|
27
|
+
id: string;
|
|
28
|
+
nodeId: string;
|
|
29
|
+
status: StepStatus;
|
|
30
|
+
filledOutputSlots: boolean[];
|
|
31
|
+
}
|
|
23
32
|
export declare class StepNotFoundError extends Error {
|
|
24
33
|
readonly stepId: string;
|
|
25
34
|
constructor(stepId: string);
|
|
26
35
|
}
|
|
27
36
|
export interface StepStore {
|
|
28
|
-
createSteps(records: NewStepRecord[]): Promise<Array<{
|
|
37
|
+
createSteps(executionId: string, records: NewStepRecord[]): Promise<Array<{
|
|
29
38
|
id: string;
|
|
30
39
|
nodeId: string;
|
|
31
40
|
}>>;
|
|
@@ -34,8 +43,8 @@ export interface StepStore {
|
|
|
34
43
|
completeStep(id: string, outputs: StepSlots): Promise<boolean>;
|
|
35
44
|
failStep(id: string, error: StepError): Promise<boolean>;
|
|
36
45
|
cancelQueuedSteps(executionId: string): Promise<void>;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
loadStepsByNodeIds(executionId: string, nodeIds: string[]): Promise<Record<string, StepRecord>>;
|
|
47
|
+
loadStepSummaries(executionId: string, nodeIds: string[]): Promise<Record<string, StepSummary>>;
|
|
48
|
+
countSettledSteps(executionId: string): Promise<number>;
|
|
40
49
|
hasFailedSteps(executionId: string): Promise<boolean>;
|
|
41
50
|
}
|
|
@@ -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":";;;AA0DA,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"}
|
package/dist/graph/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export type { GraphEdge, GraphNode, StepConfig, StepType, WorkflowGraph, } from './workflow-graph';
|
|
2
|
-
export { findTriggerNode, getPredecessorNodeIds, getSuccessorNodeIds, } from './workflow-graph-queries';
|
|
2
|
+
export { findTriggerNode, getDescendantNodeIds, getPredecessorNodeIds, getSuccessorNodeIds, } from './workflow-graph-queries';
|
|
3
3
|
export { GraphValidationError, validateExecutableGraph } from './validate-executable-graph';
|
package/dist/graph/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
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;
|
|
3
|
+
exports.validateExecutableGraph = exports.GraphValidationError = exports.getSuccessorNodeIds = exports.getPredecessorNodeIds = exports.getDescendantNodeIds = exports.findTriggerNode = void 0;
|
|
4
4
|
var workflow_graph_queries_1 = require("./workflow-graph-queries");
|
|
5
5
|
Object.defineProperty(exports, "findTriggerNode", { enumerable: true, get: function () { return workflow_graph_queries_1.findTriggerNode; } });
|
|
6
|
+
Object.defineProperty(exports, "getDescendantNodeIds", { enumerable: true, get: function () { return workflow_graph_queries_1.getDescendantNodeIds; } });
|
|
6
7
|
Object.defineProperty(exports, "getPredecessorNodeIds", { enumerable: true, get: function () { return workflow_graph_queries_1.getPredecessorNodeIds; } });
|
|
7
8
|
Object.defineProperty(exports, "getSuccessorNodeIds", { enumerable: true, get: function () { return workflow_graph_queries_1.getSuccessorNodeIds; } });
|
|
8
9
|
var validate_executable_graph_1 = require("./validate-executable-graph");
|
package/dist/graph/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":";;;AAOA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":";;;AAOA,mEAKkC;AAJjC,yHAAA,eAAe,OAAA;AACf,8HAAA,oBAAoB,OAAA;AACpB,+HAAA,qBAAqB,OAAA;AACrB,6HAAA,mBAAmB,OAAA;AAEpB,yEAA4F;AAAnF,iIAAA,oBAAoB,OAAA;AAAE,oIAAA,uBAAuB,OAAA"}
|
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.GraphValidationError = void 0;
|
|
4
4
|
exports.validateExecutableGraph = validateExecutableGraph;
|
|
5
5
|
const common_1 = require("../common");
|
|
6
|
+
const workflow_graph_queries_1 = require("./workflow-graph-queries");
|
|
7
|
+
const MAX_SLOT_INDEX = 100;
|
|
6
8
|
class GraphValidationError extends Error {
|
|
7
9
|
constructor(message) {
|
|
8
10
|
super(message);
|
|
@@ -21,12 +23,21 @@ function validateExecutableGraph(graph) {
|
|
|
21
23
|
if (graph.edges.some((edge) => edge.isBackEdge)) {
|
|
22
24
|
throw new common_1.UnimplementedError('Graphs with back-edges (loops) are not supported yet');
|
|
23
25
|
}
|
|
26
|
+
const [trigger] = triggers;
|
|
27
|
+
const reachable = new Set([trigger.id, ...(0, workflow_graph_queries_1.getDescendantNodeIds)(graph, trigger.id)]);
|
|
24
28
|
for (const edge of graph.edges) {
|
|
25
|
-
if (edge.
|
|
26
|
-
throw new
|
|
29
|
+
if (reachable.has(edge.to) && !reachable.has(edge.from)) {
|
|
30
|
+
throw new GraphValidationError(`Edge ${edge.from} → ${edge.to} feeds a node the trigger reaches from one it cannot reach, so ${edge.to} would wait on ${edge.from} forever`);
|
|
27
31
|
}
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
}
|
|
33
|
+
for (const edge of graph.edges) {
|
|
34
|
+
for (const index of [edge.outputIndex, edge.inputIndex]) {
|
|
35
|
+
if (!Number.isInteger(index) || index < 0) {
|
|
36
|
+
throw new GraphValidationError(`Edge ${edge.from} → ${edge.to} has slot index ${index}; slot indices are non-negative integers`);
|
|
37
|
+
}
|
|
38
|
+
if (index > MAX_SLOT_INDEX) {
|
|
39
|
+
throw new GraphValidationError(`Edge ${edge.from} → ${edge.to} has slot index ${index}; slot indices above ${MAX_SLOT_INDEX} are not supported yet`);
|
|
40
|
+
}
|
|
30
41
|
}
|
|
31
42
|
}
|
|
32
43
|
const seenInputSlots = new Set();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-executable-graph.js","sourceRoot":"","sources":["../../src/graph/validate-executable-graph.ts"],"names":[],"mappings":";;;;AAAA,sCAA+C;
|
|
1
|
+
{"version":3,"file":"validate-executable-graph.js","sourceRoot":"","sources":["../../src/graph/validate-executable-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { GraphNode, WorkflowGraph } from './workflow-graph';
|
|
2
2
|
export declare function findTriggerNode(graph: WorkflowGraph): GraphNode | undefined;
|
|
3
3
|
export declare function getSuccessorNodeIds(graph: WorkflowGraph, nodeId: string): string[];
|
|
4
|
+
export declare function getDescendantNodeIds(graph: WorkflowGraph, nodeId: string): string[];
|
|
4
5
|
export declare function getPredecessorNodeIds(graph: WorkflowGraph, nodeId: string): string[];
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.findTriggerNode = findTriggerNode;
|
|
4
4
|
exports.getSuccessorNodeIds = getSuccessorNodeIds;
|
|
5
|
+
exports.getDescendantNodeIds = getDescendantNodeIds;
|
|
5
6
|
exports.getPredecessorNodeIds = getPredecessorNodeIds;
|
|
6
7
|
function findTriggerNode(graph) {
|
|
7
8
|
return graph.nodes.find((node) => node.type === 'trigger');
|
|
@@ -15,6 +16,19 @@ function getSuccessorNodeIds(graph, nodeId) {
|
|
|
15
16
|
}
|
|
16
17
|
return successors;
|
|
17
18
|
}
|
|
19
|
+
function getDescendantNodeIds(graph, nodeId) {
|
|
20
|
+
const descendants = getSuccessorNodeIds(graph, nodeId);
|
|
21
|
+
const visited = new Set(descendants);
|
|
22
|
+
for (let i = 0; i < descendants.length; i++) {
|
|
23
|
+
for (const successor of getSuccessorNodeIds(graph, descendants[i])) {
|
|
24
|
+
if (visited.has(successor))
|
|
25
|
+
continue;
|
|
26
|
+
visited.add(successor);
|
|
27
|
+
descendants.push(successor);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return descendants;
|
|
31
|
+
}
|
|
18
32
|
function getPredecessorNodeIds(graph, nodeId) {
|
|
19
33
|
const predecessors = [];
|
|
20
34
|
for (const edge of graph.edges) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-graph-queries.js","sourceRoot":"","sources":["../../src/graph/workflow-graph-queries.ts"],"names":[],"mappings":"
|
|
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;AAQD,8BAAqC,KAAoB,EAAE,MAAc;IAGxE,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,KAAK,MAAM,SAAS,IAAI,mBAAmB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;gBAAE,SAAS;YACrC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACvB,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;IACF,CAAC;IACD,OAAO,WAAW,CAAC;AACpB,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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +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, OrchestrationMessage,
|
|
10
|
-
export { ExecutionNotFoundError, ExecutionStartHandler, OrchestrationWorker,
|
|
11
|
-
export type { ExecutionMode, ExecutionRecord, ExecutionStatus, ExecutionStore, NewExecutionRecord, NewStepRecord, StepError, StepRecord, StepSlots, StepStatus, StepStore, } from './execution';
|
|
12
|
-
export { createDataSource,
|
|
9
|
+
export type { ExecutionEnqueuedEvent, OrchestrationMessage, StepSettledEvent, StepMessage, StepReadyEvent, WorkQueue, } from './queue';
|
|
10
|
+
export { ExecutionNotFoundError, ExecutionStartHandler, OrchestrationWorker, StartExecutionService, StepNotFoundError, StepReadyHandler, StepSettledHandler, StepWorker, } from './execution';
|
|
11
|
+
export type { ExecutionMode, ExecutionRecord, ExecutionStatus, ExecutionStore, NewExecutionRecord, NewStepRecord, StartExecutionRequest, StartExecutionResult, StepError, StepRecord, StepSlots, StepStatus, StepStore, } from './execution';
|
|
12
|
+
export { createDataSource, createStores, WorkflowExecution, WorkflowStepExecution, } 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.
|
|
3
|
+
exports.WorkflowStepExecution = exports.WorkflowExecution = exports.createStores = exports.createDataSource = exports.StepWorker = exports.StepSettledHandler = exports.StepReadyHandler = exports.StepNotFoundError = exports.StartExecutionService = 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");
|
|
@@ -12,12 +12,14 @@ var execution_1 = require("./execution");
|
|
|
12
12
|
Object.defineProperty(exports, "ExecutionNotFoundError", { enumerable: true, get: function () { return execution_1.ExecutionNotFoundError; } });
|
|
13
13
|
Object.defineProperty(exports, "ExecutionStartHandler", { enumerable: true, get: function () { return execution_1.ExecutionStartHandler; } });
|
|
14
14
|
Object.defineProperty(exports, "OrchestrationWorker", { enumerable: true, get: function () { return execution_1.OrchestrationWorker; } });
|
|
15
|
-
Object.defineProperty(exports, "
|
|
15
|
+
Object.defineProperty(exports, "StartExecutionService", { enumerable: true, get: function () { return execution_1.StartExecutionService; } });
|
|
16
16
|
Object.defineProperty(exports, "StepNotFoundError", { enumerable: true, get: function () { return execution_1.StepNotFoundError; } });
|
|
17
17
|
Object.defineProperty(exports, "StepReadyHandler", { enumerable: true, get: function () { return execution_1.StepReadyHandler; } });
|
|
18
|
+
Object.defineProperty(exports, "StepSettledHandler", { enumerable: true, get: function () { return execution_1.StepSettledHandler; } });
|
|
18
19
|
Object.defineProperty(exports, "StepWorker", { enumerable: true, get: function () { return execution_1.StepWorker; } });
|
|
19
20
|
var database_1 = require("./database");
|
|
20
21
|
Object.defineProperty(exports, "createDataSource", { enumerable: true, get: function () { return database_1.createDataSource; } });
|
|
21
|
-
Object.defineProperty(exports, "
|
|
22
|
-
Object.defineProperty(exports, "
|
|
22
|
+
Object.defineProperty(exports, "createStores", { enumerable: true, get: function () { return database_1.createStores; } });
|
|
23
|
+
Object.defineProperty(exports, "WorkflowExecution", { enumerable: true, get: function () { return database_1.WorkflowExecution; } });
|
|
24
|
+
Object.defineProperty(exports, "WorkflowStepExecution", { enumerable: true, get: function () { return database_1.WorkflowStepExecution; } });
|
|
23
25
|
//# sourceMappingURL=index.js.map
|
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;AAU1B,
|
|
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,yCASqB;AARpB,mHAAA,sBAAsB,OAAA;AACtB,kHAAA,qBAAqB,OAAA;AACrB,gHAAA,mBAAmB,OAAA;AACnB,kHAAA,qBAAqB,OAAA;AACrB,8GAAA,iBAAiB,OAAA;AACjB,6GAAA,gBAAgB,OAAA;AAChB,+GAAA,kBAAkB,OAAA;AAClB,uGAAA,UAAU,OAAA;AAkBX,uCAKoB;AAJnB,4GAAA,gBAAgB,OAAA;AAChB,wGAAA,YAAY,OAAA;AACZ,6GAAA,iBAAiB,OAAA;AACjB,iHAAA,qBAAqB,OAAA"}
|
package/dist/queue/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { ExecutionEnqueuedEvent, OrchestrationMessage,
|
|
1
|
+
export type { ExecutionEnqueuedEvent, OrchestrationMessage, StepSettledEvent, StepMessage, StepReadyEvent, WorkQueue, } from './work-queue.types';
|
|
2
2
|
export { InMemoryWorkQueue } from './in-memory-work-queue';
|
|
@@ -2,12 +2,12 @@ export interface ExecutionEnqueuedEvent {
|
|
|
2
2
|
type: 'execution:enqueued';
|
|
3
3
|
executionId: string;
|
|
4
4
|
}
|
|
5
|
-
export interface
|
|
6
|
-
type: 'step:
|
|
5
|
+
export interface StepSettledEvent {
|
|
6
|
+
type: 'step:settled';
|
|
7
7
|
executionId: string;
|
|
8
8
|
stepId: string;
|
|
9
9
|
}
|
|
10
|
-
export type OrchestrationMessage = ExecutionEnqueuedEvent |
|
|
10
|
+
export type OrchestrationMessage = ExecutionEnqueuedEvent | StepSettledEvent;
|
|
11
11
|
export interface StepReadyEvent {
|
|
12
12
|
type: 'step:ready';
|
|
13
13
|
executionId: string;
|
package/dist/serve.js
CHANGED
|
@@ -23,9 +23,8 @@ async function main() {
|
|
|
23
23
|
let orchestrationWorker;
|
|
24
24
|
let stepWorker;
|
|
25
25
|
if (dataSource) {
|
|
26
|
-
const executionStore =
|
|
27
|
-
|
|
28
|
-
orchestrationWorker = new execution_1.OrchestrationWorker(orchestrationQueue, new execution_1.ExecutionStartHandler(executionStore, stepStore, orchestrationQueue), new execution_1.StepCompletedHandler(executionStore, stepStore, stepQueue));
|
|
26
|
+
const { executionStore, stepStore } = (0, database_1.createStores)(dataSource);
|
|
27
|
+
orchestrationWorker = new execution_1.OrchestrationWorker(orchestrationQueue, new execution_1.ExecutionStartHandler(executionStore, stepStore, orchestrationQueue), new execution_1.StepSettledHandler(executionStore, stepStore, stepQueue, orchestrationQueue));
|
|
29
28
|
stepWorker = new execution_1.StepWorker(stepQueue, new execution_1.StepReadyHandler(executionStore, stepStore, orchestrationQueue, {}));
|
|
30
29
|
orchestrationWorker.start();
|
|
31
30
|
stepWorker.start();
|
package/dist/serve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":";;AAAA,wCAA2C;AAC3C,gCAAoC;AAGpC,6CAAkD;AAClD,
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":";;AAAA,wCAA2C;AAC3C,gCAAoC;AAGpC,6CAAkD;AAClD,yCAA4D;AAC5D,2CAMqB;AACrB,mCAA4C;AAE5C,qCAA8C;AAE9C,KAAK,UAAU,IAAI;IAClB,MAAM,MAAM,GAAG,cAAS,CAAC,GAAG,CAAC,qBAAY,CAAC,CAAC;IAE3C,IAAI,UAAkC,CAAC;IACvC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACxB,UAAU,GAAG,IAAA,2BAAgB,EAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAClD,MAAM,UAAU,CAAC,UAAU,EAAE,CAAC;QAC9B,MAAM,UAAU,CAAC,aAAa,EAAE,CAAC;IAClC,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,IAAI,CACX,mHAAmH,CACnH,CAAC;IACH,CAAC;IAED,MAAM,kBAAkB,GAAG,IAAI,yBAAiB,EAAwB,CAAC;IACzE,MAAM,SAAS,GAAG,IAAI,yBAAiB,EAAe,CAAC;IAEvD,IAAI,mBAAoD,CAAC;IACzD,IAAI,UAAkC,CAAC;IACvC,IAAI,UAAU,EAAE,CAAC;QAChB,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,IAAA,uBAAY,EAAC,UAAU,CAAC,CAAC;QAC/D,mBAAmB,GAAG,IAAI,+BAAmB,CAC5C,kBAAkB,EAClB,IAAI,iCAAqB,CAAC,cAAc,EAAE,SAAS,EAAE,kBAAkB,CAAC,EACxE,IAAI,8BAAkB,CAAC,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAChF,CAAC;QAIF,UAAU,GAAG,IAAI,sBAAU,CAC1B,SAAS,EACT,IAAI,4BAAgB,CAAC,cAAc,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,CAAC,CACvE,CAAC;QACF,mBAAmB,CAAC,KAAK,EAAE,CAAC;QAC5B,UAAU,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,GAAG,IAAA,2BAAkB,EACjC,UAAU;QACT,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,+BAAkB,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE;QACrF,CAAC,CAAC,SAAS,CACZ,CAAC;IAEF,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;QACxD,OAAO,CAAC,GAAG,CAAC,+BAA+B,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;QACxD,IAAI,YAAY;YAAE,OAAO;QACzB,YAAY,GAAG,IAAI,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,iBAAiB,CAAC,CAAC;QACzD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAIH,IAAI,mBAAmB;YAAE,MAAM,mBAAmB,CAAC,IAAI,EAAE,CAAC;QAC1D,IAAI,UAAU;YAAE,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;QACxC,IAAI,UAAU,EAAE,aAAa;YAAE,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAQ,EAAE;QACzC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACzC,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC/B,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@n8n/engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.1",
|
|
4
4
|
"description": "n8n workflow execution engine (v2)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"dist/**/*",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
9
|
+
"LICENSE.md",
|
|
10
|
+
"LICENSE_EE.md"
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"express": "5.1.0",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"reflect-metadata": "0.2.2",
|
|
16
16
|
"uuid": "11.1.1",
|
|
17
17
|
"zod": "3.25.76",
|
|
18
|
-
"@n8n/config": "2.
|
|
18
|
+
"@n8n/config": "2.34.1",
|
|
19
19
|
"@n8n/di": "0.16.0",
|
|
20
|
-
"@n8n/typeorm": "0.
|
|
20
|
+
"@n8n/typeorm": "0.8.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@testcontainers/postgresql": "^11.13.0",
|
|
@@ -28,8 +28,9 @@
|
|
|
28
28
|
"testcontainers": "^11.13.0",
|
|
29
29
|
"typescript": "7.0.2",
|
|
30
30
|
"vitest": "^4.1.9",
|
|
31
|
-
"@n8n/
|
|
32
|
-
"@n8n/
|
|
31
|
+
"@n8n/typescript-config": "1.10.0",
|
|
32
|
+
"@n8n/vitest-config": "1.21.0",
|
|
33
|
+
"n8n-containers": "1.0.0"
|
|
33
34
|
},
|
|
34
35
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
35
36
|
"homepage": "https://n8n.io",
|
|
@@ -1,13 +0,0 @@
|
|
|
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
|
-
}
|