@n8n/engine 0.16.2 → 0.18.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 (170) hide show
  1. package/dist/auth/action-token.d.ts +7 -0
  2. package/dist/auth/action-token.js +30 -0
  3. package/dist/auth/action-token.js.map +1 -0
  4. package/dist/auth/authenticate.d.ts +4 -0
  5. package/dist/auth/authenticate.js +30 -0
  6. package/dist/auth/authenticate.js.map +1 -0
  7. package/dist/auth/identity-token.d.ts +12 -0
  8. package/dist/auth/identity-token.js +45 -0
  9. package/dist/auth/identity-token.js.map +1 -0
  10. package/dist/auth/identity.types.d.ts +7 -0
  11. package/dist/auth/identity.types.js +3 -0
  12. package/dist/auth/identity.types.js.map +1 -0
  13. package/dist/auth/index.d.ts +5 -0
  14. package/dist/auth/index.js +17 -0
  15. package/dist/auth/index.js.map +1 -0
  16. package/dist/auth/shared-secret-token.d.ts +12 -0
  17. package/dist/auth/shared-secret-token.js +44 -0
  18. package/dist/auth/shared-secret-token.js.map +1 -0
  19. package/dist/build.tsbuildinfo +1 -1
  20. package/dist/common/index.d.ts +1 -0
  21. package/dist/common/index.js +3 -1
  22. package/dist/common/index.js.map +1 -1
  23. package/dist/common/json.schema.d.ts +3 -0
  24. package/dist/common/json.schema.js +13 -0
  25. package/dist/common/json.schema.js.map +1 -0
  26. package/dist/database/create-stores.d.ts +5 -2
  27. package/dist/database/create-stores.js +6 -2
  28. package/dist/database/create-stores.js.map +1 -1
  29. package/dist/database/entities/workflow-execution.entity.d.ts +2 -4
  30. package/dist/database/entities/workflow-execution.entity.js +3 -14
  31. package/dist/database/entities/workflow-execution.entity.js.map +1 -1
  32. package/dist/database/entities/workflow-step-execution.entity.d.ts +2 -2
  33. package/dist/database/entities/workflow-step-execution.entity.js +7 -3
  34. package/dist/database/entities/workflow-step-execution.entity.js.map +1 -1
  35. package/dist/database/index.d.ts +2 -0
  36. package/dist/database/index.js +3 -1
  37. package/dist/database/index.js.map +1 -1
  38. package/dist/database/migrations/1778529600000-CreateWorkflowExecution.js +1 -1
  39. package/dist/database/migrations/1784890100000-CreateWorkflowStepExecution.js +13 -2
  40. package/dist/database/migrations/1784890100000-CreateWorkflowStepExecution.js.map +1 -1
  41. package/dist/database/typeorm-execution-store.d.ts +1 -3
  42. package/dist/database/typeorm-execution-store.js +1 -2
  43. package/dist/database/typeorm-execution-store.js.map +1 -1
  44. package/dist/database/typeorm-execution-view-store.d.ts +10 -0
  45. package/dist/database/typeorm-execution-view-store.js +49 -0
  46. package/dist/database/typeorm-execution-view-store.js.map +1 -0
  47. package/dist/database/typeorm-step-store.d.ts +7 -6
  48. package/dist/database/typeorm-step-store.js +63 -14
  49. package/dist/database/typeorm-step-store.js.map +1 -1
  50. package/dist/dependencies/external-dependencies.d.ts +3 -0
  51. package/dist/execution/batch-step.d.ts +8 -0
  52. package/dist/execution/batch-step.js +28 -0
  53. package/dist/execution/batch-step.js.map +1 -0
  54. package/dist/execution/completion.d.ts +2 -0
  55. package/dist/execution/completion.js +21 -0
  56. package/dist/execution/completion.js.map +1 -0
  57. package/dist/execution/execution-query.service.d.ts +7 -0
  58. package/dist/execution/execution-query.service.js +17 -0
  59. package/dist/execution/execution-query.service.js.map +1 -0
  60. package/dist/execution/execution-start-handler.d.ts +3 -1
  61. package/dist/execution/execution-start-handler.js +13 -2
  62. package/dist/execution/execution-start-handler.js.map +1 -1
  63. package/dist/execution/execution-store.d.ts +5 -7
  64. package/dist/execution/execution-store.js.map +1 -1
  65. package/dist/execution/execution-view-store.d.ts +26 -0
  66. package/dist/execution/execution-view-store.js +3 -0
  67. package/dist/execution/execution-view-store.js.map +1 -0
  68. package/dist/execution/execution.types.d.ts +14 -0
  69. package/dist/execution/execution.types.js +6 -1
  70. package/dist/execution/execution.types.js.map +1 -1
  71. package/dist/execution/index.d.ts +5 -2
  72. package/dist/execution/index.js +5 -1
  73. package/dist/execution/index.js.map +1 -1
  74. package/dist/execution/iteration-mapping.d.ts +14 -0
  75. package/dist/execution/iteration-mapping.js +48 -0
  76. package/dist/execution/iteration-mapping.js.map +1 -0
  77. package/dist/execution/loop-ledger.d.ts +7 -0
  78. package/dist/execution/loop-ledger.js +39 -0
  79. package/dist/execution/loop-ledger.js.map +1 -0
  80. package/dist/execution/settlement.d.ts +6 -4
  81. package/dist/execution/settlement.js +73 -17
  82. package/dist/execution/settlement.js.map +1 -1
  83. package/dist/execution/start-execution.service.d.ts +3 -3
  84. package/dist/execution/start-execution.service.js +6 -4
  85. package/dist/execution/start-execution.service.js.map +1 -1
  86. package/dist/execution/step-ready-handler.d.ts +11 -2
  87. package/dist/execution/step-ready-handler.js +66 -13
  88. package/dist/execution/step-ready-handler.js.map +1 -1
  89. package/dist/execution/step-settled-handler.d.ts +4 -3
  90. package/dist/execution/step-settled-handler.js +52 -30
  91. package/dist/execution/step-settled-handler.js.map +1 -1
  92. package/dist/execution/step-store.d.ts +9 -13
  93. package/dist/execution/step-store.js.map +1 -1
  94. package/dist/execution/store-loop-reader.d.ts +4 -0
  95. package/dist/execution/store-loop-reader.js +48 -0
  96. package/dist/execution/store-loop-reader.js.map +1 -0
  97. package/dist/graph/graph-validation.error.d.ts +3 -0
  98. package/dist/graph/graph-validation.error.js +11 -0
  99. package/dist/graph/graph-validation.error.js.map +1 -0
  100. package/dist/graph/index.d.ts +6 -2
  101. package/dist/graph/index.js +9 -2
  102. package/dist/graph/index.js.map +1 -1
  103. package/dist/graph/loops.d.ts +10 -0
  104. package/dist/graph/loops.js +172 -0
  105. package/dist/graph/loops.js.map +1 -0
  106. package/dist/graph/validate-executable-graph.d.ts +1 -3
  107. package/dist/graph/validate-executable-graph.js +13 -18
  108. package/dist/graph/validate-executable-graph.js.map +1 -1
  109. package/dist/graph/workflow-graph.d.ts +4 -0
  110. package/dist/graph/workflow-graph.js +7 -0
  111. package/dist/graph/workflow-graph.js.map +1 -1
  112. package/dist/index.d.ts +14 -7
  113. package/dist/index.js +19 -12
  114. package/dist/index.js.map +1 -1
  115. package/dist/lifecycle-events/batching-lifecycle-event-publisher.d.ts +26 -0
  116. package/dist/lifecycle-events/batching-lifecycle-event-publisher.js +121 -0
  117. package/dist/lifecycle-events/batching-lifecycle-event-publisher.js.map +1 -0
  118. package/dist/lifecycle-events/index.d.ts +6 -0
  119. package/dist/lifecycle-events/index.js +15 -0
  120. package/dist/lifecycle-events/index.js.map +1 -0
  121. package/dist/lifecycle-events/lifecycle-event-publisher.d.ts +6 -0
  122. package/dist/lifecycle-events/lifecycle-event-publisher.js +8 -0
  123. package/dist/lifecycle-events/lifecycle-event-publisher.js.map +1 -0
  124. package/dist/lifecycle-events/lifecycle-event.schema.d.ts +339 -0
  125. package/dist/lifecycle-events/lifecycle-event.schema.js +39 -0
  126. package/dist/lifecycle-events/lifecycle-event.schema.js.map +1 -0
  127. package/dist/lifecycle-events/lifecycle-event.types.d.ts +4 -0
  128. package/dist/lifecycle-events/lifecycle-event.types.js +3 -0
  129. package/dist/lifecycle-events/lifecycle-event.types.js.map +1 -0
  130. package/dist/logging/console-logger.d.ts +2 -0
  131. package/dist/logging/console-logger.js +18 -0
  132. package/dist/logging/console-logger.js.map +1 -0
  133. package/dist/logging/index.d.ts +2 -0
  134. package/dist/logging/index.js +6 -0
  135. package/dist/logging/index.js.map +1 -0
  136. package/dist/logging/logger.types.d.ts +6 -0
  137. package/dist/logging/logger.types.js +3 -0
  138. package/dist/logging/logger.types.js.map +1 -0
  139. package/dist/queue/in-memory-work-queue.d.ts +3 -0
  140. package/dist/queue/in-memory-work-queue.js +7 -2
  141. package/dist/queue/in-memory-work-queue.js.map +1 -1
  142. package/dist/runtime/create-engine-runtime.d.ts +20 -0
  143. package/dist/runtime/create-engine-runtime.js +38 -0
  144. package/dist/runtime/create-engine-runtime.js.map +1 -0
  145. package/dist/runtime/index.d.ts +2 -0
  146. package/dist/runtime/index.js +6 -0
  147. package/dist/runtime/index.js.map +1 -0
  148. package/dist/serve.js +25 -34
  149. package/dist/serve.js.map +1 -1
  150. package/dist/server/api.types.d.ts +25 -0
  151. package/dist/server/api.types.js +3 -0
  152. package/dist/server/api.types.js.map +1 -0
  153. package/dist/server/create-engine-server.d.ts +9 -7
  154. package/dist/server/create-engine-server.js +4 -8
  155. package/dist/server/create-engine-server.js.map +1 -1
  156. package/dist/server/error-response.d.ts +7 -0
  157. package/dist/server/error-response.js +12 -0
  158. package/dist/server/error-response.js.map +1 -0
  159. package/dist/server/index.d.ts +3 -0
  160. package/dist/server/index.js +3 -1
  161. package/dist/server/index.js.map +1 -1
  162. package/dist/server/routes/workflow-executions.d.ts +2 -2
  163. package/dist/server/routes/workflow-executions.handlers.d.ts +4 -0
  164. package/dist/server/routes/workflow-executions.handlers.js +68 -0
  165. package/dist/server/routes/workflow-executions.handlers.js.map +1 -0
  166. package/dist/server/routes/workflow-executions.js +16 -21
  167. package/dist/server/routes/workflow-executions.js.map +1 -1
  168. package/dist/testing/start-engine-server.d.ts +1 -1
  169. package/dist/testing/start-engine-server.js.map +1 -1
  170. package/package.json +10 -7
@@ -1,12 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateExecutableGraph = exports.GraphValidationError = exports.getSuccessorNodeIds = exports.getPredecessorNodeIds = exports.getDescendantNodeIds = exports.findTriggerNode = void 0;
3
+ exports.validateLoops = exports.deriveLoops = exports.validateExecutableGraph = exports.MAX_SLOT_INDEX = exports.GraphValidationError = exports.getSuccessorNodeIds = exports.getPredecessorNodeIds = exports.getDescendantNodeIds = exports.findTriggerNode = exports.isBatchStepConfig = void 0;
4
+ var workflow_graph_1 = require("./workflow-graph");
5
+ Object.defineProperty(exports, "isBatchStepConfig", { enumerable: true, get: function () { return workflow_graph_1.isBatchStepConfig; } });
4
6
  var workflow_graph_queries_1 = require("./workflow-graph-queries");
5
7
  Object.defineProperty(exports, "findTriggerNode", { enumerable: true, get: function () { return workflow_graph_queries_1.findTriggerNode; } });
6
8
  Object.defineProperty(exports, "getDescendantNodeIds", { enumerable: true, get: function () { return workflow_graph_queries_1.getDescendantNodeIds; } });
7
9
  Object.defineProperty(exports, "getPredecessorNodeIds", { enumerable: true, get: function () { return workflow_graph_queries_1.getPredecessorNodeIds; } });
8
10
  Object.defineProperty(exports, "getSuccessorNodeIds", { enumerable: true, get: function () { return workflow_graph_queries_1.getSuccessorNodeIds; } });
11
+ var graph_validation_error_1 = require("./graph-validation.error");
12
+ Object.defineProperty(exports, "GraphValidationError", { enumerable: true, get: function () { return graph_validation_error_1.GraphValidationError; } });
9
13
  var validate_executable_graph_1 = require("./validate-executable-graph");
10
- Object.defineProperty(exports, "GraphValidationError", { enumerable: true, get: function () { return validate_executable_graph_1.GraphValidationError; } });
14
+ Object.defineProperty(exports, "MAX_SLOT_INDEX", { enumerable: true, get: function () { return validate_executable_graph_1.MAX_SLOT_INDEX; } });
11
15
  Object.defineProperty(exports, "validateExecutableGraph", { enumerable: true, get: function () { return validate_executable_graph_1.validateExecutableGraph; } });
16
+ var loops_1 = require("./loops");
17
+ Object.defineProperty(exports, "deriveLoops", { enumerable: true, get: function () { return loops_1.deriveLoops; } });
18
+ Object.defineProperty(exports, "validateLoops", { enumerable: true, get: function () { return loops_1.validateLoops; } });
12
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":";;;AAAA,mDAAqD;AAA5C,mHAAA,iBAAiB,OAAA;AAS1B,mEAKkC;AAJjC,yHAAA,eAAe,OAAA;AACf,8HAAA,oBAAoB,OAAA;AACpB,+HAAA,qBAAqB,OAAA;AACrB,6HAAA,mBAAmB,OAAA;AAEpB,mEAAgE;AAAvD,8HAAA,oBAAoB,OAAA;AAC7B,yEAAsF;AAA7E,2HAAA,cAAc,OAAA;AAAE,oIAAA,uBAAuB,OAAA;AAChD,iCAAqD;AAA5C,oGAAA,WAAW,OAAA;AAAE,sGAAA,aAAa,OAAA"}
@@ -0,0 +1,10 @@
1
+ import { type GraphEdge, type WorkflowGraph } from './workflow-graph';
2
+ export interface WorkflowLoop {
3
+ batchNodeId: string;
4
+ memberIds: Set<string>;
5
+ backEdges: GraphEdge[];
6
+ entryEdges: GraphEdge[];
7
+ exitEdges: GraphEdge[];
8
+ }
9
+ export declare function deriveLoops(graph: WorkflowGraph): WorkflowLoop[];
10
+ export declare function validateLoops(graph: WorkflowGraph): void;
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deriveLoops = deriveLoops;
4
+ exports.validateLoops = validateLoops;
5
+ const common_1 = require("../common");
6
+ const graph_validation_error_1 = require("./graph-validation.error");
7
+ const workflow_graph_1 = require("./workflow-graph");
8
+ function deriveLoops(graph) {
9
+ const backEdgeTargets = [...new Set(graph.edges.filter((e) => e.isBackEdge).map((e) => e.to))];
10
+ if (backEdgeTargets.length === 0)
11
+ return [];
12
+ const sccByNode = computeSccMembership(graph, graph.edges);
13
+ return backEdgeTargets.map((batchNodeId) => {
14
+ const memberIds = sccByNode.get(batchNodeId) ?? new Set([batchNodeId]);
15
+ return {
16
+ batchNodeId,
17
+ memberIds,
18
+ backEdges: graph.edges.filter((e) => e.isBackEdge && e.to === batchNodeId),
19
+ entryEdges: graph.edges.filter((e) => !e.isBackEdge && e.to === batchNodeId && !memberIds.has(e.from)),
20
+ exitEdges: graph.edges.filter((e) => !e.isBackEdge && memberIds.has(e.from) && !memberIds.has(e.to)),
21
+ };
22
+ });
23
+ }
24
+ function computeSccMembership(graph, edges) {
25
+ const outgoing = new Map();
26
+ for (const edge of edges) {
27
+ const list = outgoing.get(edge.from);
28
+ if (list)
29
+ list.push(edge);
30
+ else
31
+ outgoing.set(edge.from, [edge]);
32
+ }
33
+ const indexById = new Map();
34
+ const lowlinkById = new Map();
35
+ const stack = [];
36
+ const onStack = new Set();
37
+ const membership = new Map();
38
+ let nextIndex = 0;
39
+ const connect = (nodeId) => {
40
+ indexById.set(nodeId, nextIndex);
41
+ lowlinkById.set(nodeId, nextIndex);
42
+ nextIndex += 1;
43
+ stack.push(nodeId);
44
+ onStack.add(nodeId);
45
+ for (const edge of outgoing.get(nodeId) ?? []) {
46
+ if (!indexById.has(edge.to)) {
47
+ connect(edge.to);
48
+ lowlinkById.set(nodeId, Math.min(lowlinkById.get(nodeId), lowlinkById.get(edge.to)));
49
+ }
50
+ else if (onStack.has(edge.to)) {
51
+ lowlinkById.set(nodeId, Math.min(lowlinkById.get(nodeId), indexById.get(edge.to)));
52
+ }
53
+ }
54
+ if (lowlinkById.get(nodeId) === indexById.get(nodeId)) {
55
+ const members = new Set();
56
+ let member;
57
+ do {
58
+ member = stack.pop();
59
+ onStack.delete(member);
60
+ members.add(member);
61
+ } while (member !== nodeId);
62
+ for (const id of members)
63
+ membership.set(id, members);
64
+ }
65
+ };
66
+ for (const node of graph.nodes) {
67
+ if (!indexById.has(node.id))
68
+ connect(node.id);
69
+ }
70
+ return membership;
71
+ }
72
+ function isCyclic(members, edges) {
73
+ if (members.size > 1)
74
+ return true;
75
+ const [only] = members;
76
+ return edges.some((edge) => edge.from === only && edge.to === only);
77
+ }
78
+ function validateLoops(graph) {
79
+ const namesById = new Map(graph.nodes.map((node) => [node.id, node.name]));
80
+ const name = (id) => namesById.get(id) ?? id;
81
+ const seenNodeIds = new Set();
82
+ for (const node of graph.nodes) {
83
+ if (seenNodeIds.has(node.id)) {
84
+ throw new graph_validation_error_1.GraphValidationError(`Two nodes share the id ${node.id}`);
85
+ }
86
+ seenNodeIds.add(node.id);
87
+ }
88
+ for (const edge of graph.edges) {
89
+ for (const endpoint of [edge.from, edge.to]) {
90
+ if (!namesById.has(endpoint)) {
91
+ throw new graph_validation_error_1.GraphValidationError(`Edge ${name(edge.from)} -> ${name(edge.to)} references ${endpoint}, which is not a node in the graph`);
92
+ }
93
+ }
94
+ }
95
+ const forwardEdges = graph.edges.filter((edge) => !edge.isBackEdge);
96
+ for (const members of new Set(computeSccMembership(graph, forwardEdges).values())) {
97
+ if (isCyclic(members, forwardEdges)) {
98
+ throw new graph_validation_error_1.GraphValidationError(`Nodes ${[...members].map(name).join(', ')} form a cycle with no back-edge to close it, so none of them can ever become runnable`);
99
+ }
100
+ }
101
+ const batchNodeIds = new Set(graph.nodes.filter((node) => node.type === 'batch').map((node) => node.id));
102
+ const triggerNodeIds = new Set(graph.nodes.filter((node) => node.type === 'trigger').map((node) => node.id));
103
+ const loops = deriveLoops(graph);
104
+ const loopsByBatchNode = new Map(loops.map((loop) => [loop.batchNodeId, loop]));
105
+ for (const batchNodeId of batchNodeIds) {
106
+ if (!loopsByBatchNode.has(batchNodeId)) {
107
+ throw new graph_validation_error_1.GraphValidationError(`Batch node ${name(batchNodeId)} has no back-edge returning to it, so its loop could never advance`);
108
+ }
109
+ }
110
+ for (const loop of loops) {
111
+ const { batchNodeId, memberIds, backEdges } = loop;
112
+ if (!batchNodeIds.has(batchNodeId)) {
113
+ throw new graph_validation_error_1.GraphValidationError(`Node ${name(batchNodeId)} has a back-edge returning to it but is not a batch node`);
114
+ }
115
+ const batchNode = graph.nodes.find((node) => node.id === batchNodeId);
116
+ if (!(0, workflow_graph_1.isBatchStepConfig)(batchNode?.config)) {
117
+ throw new graph_validation_error_1.GraphValidationError(`Batch node ${name(batchNodeId)} has no batch size, and it must be a whole number of at least 1`);
118
+ }
119
+ for (const memberId of memberIds) {
120
+ if (triggerNodeIds.has(memberId)) {
121
+ throw new graph_validation_error_1.GraphValidationError(`Trigger ${name(memberId)} is inside the loop of ${name(batchNodeId)}, so that loop could never start`);
122
+ }
123
+ }
124
+ for (const memberId of memberIds) {
125
+ if (memberId !== batchNodeId && batchNodeIds.has(memberId)) {
126
+ throw new common_1.UnimplementedError(`Batch node ${name(memberId)} sits inside the loop of ${name(batchNodeId)}; nested loops are not supported yet`);
127
+ }
128
+ }
129
+ for (const edge of backEdges) {
130
+ if (edge.inputIndex !== 0) {
131
+ throw new graph_validation_error_1.GraphValidationError(`Back-edge ${name(edge.from)} -> ${name(edge.to)} feeds input slot ${edge.inputIndex}; returns feed the batch node's slot 0`);
132
+ }
133
+ if (!memberIds.has(edge.from)) {
134
+ throw new graph_validation_error_1.GraphValidationError(`Back-edge ${name(edge.from)} -> ${name(edge.to)} returns from outside the loop`);
135
+ }
136
+ }
137
+ if (backEdges.length > 1) {
138
+ throw new common_1.UnimplementedError(`Batch node ${name(batchNodeId)} has ${backEdges.length} back-edges; multiple returns converge on one input slot, which is not supported yet`);
139
+ }
140
+ for (const edge of graph.edges) {
141
+ if (edge.to === batchNodeId && !edge.isBackEdge && edge.inputIndex !== 0) {
142
+ throw new graph_validation_error_1.GraphValidationError(`Edge ${name(edge.from)} -> ${name(edge.to)} feeds input slot ${edge.inputIndex} of a batch node, which has only slot 0`);
143
+ }
144
+ if (edge.from === batchNodeId && edge.outputIndex !== 0 && edge.outputIndex !== 1) {
145
+ throw new graph_validation_error_1.GraphValidationError(`Edge ${name(edge.from)} -> ${name(edge.to)} leaves output slot ${edge.outputIndex} of a batch node, which has only done (0) and loop (1)`);
146
+ }
147
+ }
148
+ if (loop.entryEdges.length > 1) {
149
+ throw new common_1.UnimplementedError(`Batch node ${name(batchNodeId)} has ${loop.entryEdges.length} entry edges; converging entries on its input slot is not supported yet`);
150
+ }
151
+ for (const edge of loop.exitEdges) {
152
+ if (edge.from !== batchNodeId) {
153
+ throw new common_1.UnimplementedError(`Edge ${name(edge.from)} -> ${name(edge.to)} leaves the loop of ${name(batchNodeId)} mid-body; dangling body branches are not supported yet`);
154
+ }
155
+ if (edge.outputIndex !== 0) {
156
+ throw new graph_validation_error_1.GraphValidationError(`Edge ${name(edge.from)} -> ${name(edge.to)} leaves the loop from the loop slot; only the done slot (0) exits`);
157
+ }
158
+ }
159
+ for (const edge of graph.edges) {
160
+ if (edge.from === batchNodeId && edge.outputIndex === 0 && memberIds.has(edge.to)) {
161
+ throw new graph_validation_error_1.GraphValidationError(`Done slot of ${name(batchNodeId)} feeds ${name(edge.to)}, a member of its own loop; a node cannot run both per iteration and after the loop`);
162
+ }
163
+ if (!edge.isBackEdge &&
164
+ memberIds.has(edge.to) &&
165
+ edge.to !== batchNodeId &&
166
+ !memberIds.has(edge.from)) {
167
+ throw new graph_validation_error_1.GraphValidationError(`Edge ${name(edge.from)} -> ${name(edge.to)} enters the loop of ${name(batchNodeId)} mid-body; the batch node is the only way in`);
168
+ }
169
+ }
170
+ }
171
+ }
172
+ //# sourceMappingURL=loops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loops.js","sourceRoot":"","sources":["../../src/graph/loops.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,3 @@
1
1
  import type { WorkflowGraph } from './workflow-graph';
2
- export declare class GraphValidationError extends Error {
3
- constructor(message: string);
4
- }
2
+ export declare const MAX_SLOT_INDEX = 100;
5
3
  export declare function validateExecutableGraph(graph: WorkflowGraph): void;
@@ -1,47 +1,42 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GraphValidationError = void 0;
3
+ exports.MAX_SLOT_INDEX = void 0;
4
4
  exports.validateExecutableGraph = validateExecutableGraph;
5
5
  const common_1 = require("../common");
6
+ const graph_validation_error_1 = require("./graph-validation.error");
7
+ const loops_1 = require("./loops");
6
8
  const workflow_graph_queries_1 = require("./workflow-graph-queries");
7
- const MAX_SLOT_INDEX = 100;
8
- class GraphValidationError extends Error {
9
- constructor(message) {
10
- super(message);
11
- this.name = 'GraphValidationError';
12
- }
13
- }
14
- exports.GraphValidationError = GraphValidationError;
9
+ exports.MAX_SLOT_INDEX = 100;
15
10
  function validateExecutableGraph(graph) {
16
11
  const triggers = graph.nodes.filter((node) => node.type === 'trigger');
17
12
  if (triggers.length === 0) {
18
- throw new GraphValidationError('Graph has no trigger node to start from');
13
+ throw new graph_validation_error_1.GraphValidationError('Graph has no trigger node to start from');
19
14
  }
20
15
  if (triggers.length > 1) {
21
- throw new GraphValidationError('Graph must have exactly one trigger node');
22
- }
23
- if (graph.edges.some((edge) => edge.isBackEdge)) {
24
- throw new common_1.UnimplementedError('Graphs with back-edges (loops) are not supported yet');
16
+ throw new graph_validation_error_1.GraphValidationError('Graph must have exactly one trigger node');
25
17
  }
18
+ (0, loops_1.validateLoops)(graph);
26
19
  const [trigger] = triggers;
27
20
  const reachable = new Set([trigger.id, ...(0, workflow_graph_queries_1.getDescendantNodeIds)(graph, trigger.id)]);
28
21
  for (const edge of graph.edges) {
29
22
  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`);
23
+ throw new graph_validation_error_1.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`);
31
24
  }
32
25
  }
33
26
  for (const edge of graph.edges) {
34
27
  for (const index of [edge.outputIndex, edge.inputIndex]) {
35
28
  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`);
29
+ throw new graph_validation_error_1.GraphValidationError(`Edge ${edge.from} -> ${edge.to} has slot index ${index}; slot indices are non-negative integers`);
37
30
  }
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`);
31
+ if (index > exports.MAX_SLOT_INDEX) {
32
+ throw new graph_validation_error_1.GraphValidationError(`Edge ${edge.from} -> ${edge.to} has slot index ${index}; slot indices above ${exports.MAX_SLOT_INDEX} are not supported yet`);
40
33
  }
41
34
  }
42
35
  }
43
36
  const seenInputSlots = new Set();
44
37
  for (const edge of graph.edges) {
38
+ if (edge.isBackEdge)
39
+ continue;
45
40
  const slot = `${edge.to}#${edge.inputIndex}`;
46
41
  if (seenInputSlots.has(slot)) {
47
42
  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`);
@@ -1 +1 @@
1
- {"version":3,"file":"validate-executable-graph.js","sourceRoot":"","sources":["../../src/graph/validate-executable-graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate-executable-graph.js","sourceRoot":"","sources":["../../src/graph/validate-executable-graph.ts"],"names":[],"mappings":";;;;AAAA,sCAA+C;AAC/C,qEAAgE;AAChE,mCAAwC;AAExC,qEAAgE;AAEnD,QAAA,cAAc,GAAG,GAAG,CAAC;AAUlC,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,6CAAoB,CAAC,yCAAyC,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,6CAAoB,CAAC,0CAA0C,CAAC,CAAC;IAC5E,CAAC;IAED,IAAA,qBAAa,EAAC,KAAK,CAAC,CAAC;IAErB,MAAM,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC;IAC3B,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,IAAA,6CAAoB,EAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACpF,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,6CAAoB,CAC7B,QAAQ,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,kEAAkE,IAAI,CAAC,EAAE,kBAAkB,IAAI,CAAC,IAAI,UAAU,CAC7I,CAAC;QACH,CAAC;IACF,CAAC;IAID,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,KAAK,MAAM,KAAK,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACzD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBAC3C,MAAM,IAAI,6CAAoB,CAC7B,QAAQ,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,mBAAmB,KAAK,0CAA0C,CACjG,CAAC;YACH,CAAC;YACD,IAAI,KAAK,GAAG,QAAA,cAAc,EAAE,CAAC;gBAC5B,MAAM,IAAI,6CAAoB,CAC7B,QAAQ,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,mBAAmB,KAAK,wBAAwB,QAAA,cAAc,wBAAwB,CACrH,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;IAID,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,UAAU;YAAE,SAAS;QAC9B,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"}
@@ -1,5 +1,9 @@
1
1
  export type StepType = 'trigger' | 'v1-node' | 'wait' | 'subworkflow' | 'batch';
2
2
  export type StepConfig = unknown;
3
+ export interface BatchStepConfig {
4
+ batchSize: number;
5
+ }
6
+ export declare function isBatchStepConfig(config: unknown): config is BatchStepConfig;
3
7
  export interface GraphNode {
4
8
  id: string;
5
9
  name: string;
@@ -1,3 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isBatchStepConfig = isBatchStepConfig;
4
+ function isBatchStepConfig(config) {
5
+ if (typeof config !== 'object' || config === null)
6
+ return false;
7
+ const { batchSize } = config;
8
+ return typeof batchSize === 'number' && Number.isInteger(batchSize) && batchSize >= 1;
9
+ }
3
10
  //# sourceMappingURL=workflow-graph.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-graph.js","sourceRoot":"","sources":["../../src/graph/workflow-graph.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"workflow-graph.js","sourceRoot":"","sources":["../../src/graph/workflow-graph.ts"],"names":[],"mappings":";;;AA0BA,2BAAkC,MAAe;IAChD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAChE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAiC,CAAC;IACxD,OAAO,OAAO,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,CAAC;AACvF,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,12 +1,19 @@
1
- export { createEngineServer } from './server';
2
- export type { EngineServerDeps } from './server';
1
+ export { createEngineRuntime } from './runtime';
2
+ export type { EngineRuntime, EngineRuntimeOptions } from './runtime';
3
+ export type { EngineLogger } from './logging';
4
+ export { ACTION_TOKEN, IDENTITY_TOKEN, InvalidActionTokenError, InvalidIdentityTokenError, mintActionToken, mintIdentityToken, SharedSecretIdentityVerifier, verifyActionToken, } from './auth';
5
+ export type { AuthenticatedCaller, ActionScope, IdentityVerifier } from './auth';
6
+ export type { EngineErrorResponse, ExecutionSnapshot, ExecutionStepsResponse, StepDetail, } from './server';
7
+ export { MAX_LIFECYCLE_EVENTS_PER_BATCH, lifecycleEventBatchSchema, lifecycleEventSchema, } from './lifecycle-events';
8
+ export type { LifecycleEventCallback, LifecycleEvent, LifecycleEventBatch, } from './lifecycle-events';
3
9
  export type { JsonObject, JsonValue } from './common';
4
- export type { GraphEdge, GraphNode, StepConfig, StepType, WorkflowGraph, } from './graph';
10
+ export { deriveLoops, isBatchStepConfig } from './graph';
11
+ export type { BatchStepConfig, GraphEdge, GraphNode, StepConfig, StepType, WorkflowGraph, WorkflowLoop, } from './graph';
5
12
  export type { ExternalDependencies, IStepExecutor, StepExecutionContext, StepExecutionRequest, StepExecutionResult, } from './dependencies';
6
13
  export { AllowAllAdmittance, AdmittanceRejectedError } from './admittance';
7
14
  export type { AdmittanceDecision, AdmittanceRequest, AdmittanceService, } from './admittance';
8
- export { InMemoryWorkQueue } from './queue';
9
15
  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';
16
+ export { ExecutionNotFoundError, StepNotFoundError } from './execution';
17
+ export type { ExecutionMode, ExecutionViewStore, ExecutionRecord, ExecutionStatus, ExecutionStore, ExecutionView, NewExecutionRecord, NewStepRecord, StartExecutionRequest, StartExecutionResult, StepError, StepKey, StepKeyId, StepRecord, StepSlots, StepStatus, StepStore, StepView, TriggerOutputs, } from './execution';
18
+ export { createDataSource, WorkflowExecution, WorkflowStepExecution } from './database';
19
+ export type { EngineStores } from './database';
package/dist/index.js CHANGED
@@ -1,25 +1,32 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
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
- var server_1 = require("./server");
5
- Object.defineProperty(exports, "createEngineServer", { enumerable: true, get: function () { return server_1.createEngineServer; } });
3
+ exports.WorkflowStepExecution = exports.WorkflowExecution = exports.createDataSource = exports.StepNotFoundError = exports.ExecutionNotFoundError = exports.AdmittanceRejectedError = exports.AllowAllAdmittance = exports.isBatchStepConfig = exports.deriveLoops = exports.lifecycleEventSchema = exports.lifecycleEventBatchSchema = exports.MAX_LIFECYCLE_EVENTS_PER_BATCH = exports.verifyActionToken = exports.SharedSecretIdentityVerifier = exports.mintIdentityToken = exports.mintActionToken = exports.InvalidIdentityTokenError = exports.InvalidActionTokenError = exports.IDENTITY_TOKEN = exports.ACTION_TOKEN = exports.createEngineRuntime = void 0;
4
+ var runtime_1 = require("./runtime");
5
+ Object.defineProperty(exports, "createEngineRuntime", { enumerable: true, get: function () { return runtime_1.createEngineRuntime; } });
6
+ var auth_1 = require("./auth");
7
+ Object.defineProperty(exports, "ACTION_TOKEN", { enumerable: true, get: function () { return auth_1.ACTION_TOKEN; } });
8
+ Object.defineProperty(exports, "IDENTITY_TOKEN", { enumerable: true, get: function () { return auth_1.IDENTITY_TOKEN; } });
9
+ Object.defineProperty(exports, "InvalidActionTokenError", { enumerable: true, get: function () { return auth_1.InvalidActionTokenError; } });
10
+ Object.defineProperty(exports, "InvalidIdentityTokenError", { enumerable: true, get: function () { return auth_1.InvalidIdentityTokenError; } });
11
+ Object.defineProperty(exports, "mintActionToken", { enumerable: true, get: function () { return auth_1.mintActionToken; } });
12
+ Object.defineProperty(exports, "mintIdentityToken", { enumerable: true, get: function () { return auth_1.mintIdentityToken; } });
13
+ Object.defineProperty(exports, "SharedSecretIdentityVerifier", { enumerable: true, get: function () { return auth_1.SharedSecretIdentityVerifier; } });
14
+ Object.defineProperty(exports, "verifyActionToken", { enumerable: true, get: function () { return auth_1.verifyActionToken; } });
15
+ var lifecycle_events_1 = require("./lifecycle-events");
16
+ Object.defineProperty(exports, "MAX_LIFECYCLE_EVENTS_PER_BATCH", { enumerable: true, get: function () { return lifecycle_events_1.MAX_LIFECYCLE_EVENTS_PER_BATCH; } });
17
+ Object.defineProperty(exports, "lifecycleEventBatchSchema", { enumerable: true, get: function () { return lifecycle_events_1.lifecycleEventBatchSchema; } });
18
+ Object.defineProperty(exports, "lifecycleEventSchema", { enumerable: true, get: function () { return lifecycle_events_1.lifecycleEventSchema; } });
19
+ var graph_1 = require("./graph");
20
+ Object.defineProperty(exports, "deriveLoops", { enumerable: true, get: function () { return graph_1.deriveLoops; } });
21
+ Object.defineProperty(exports, "isBatchStepConfig", { enumerable: true, get: function () { return graph_1.isBatchStepConfig; } });
6
22
  var admittance_1 = require("./admittance");
7
23
  Object.defineProperty(exports, "AllowAllAdmittance", { enumerable: true, get: function () { return admittance_1.AllowAllAdmittance; } });
8
24
  Object.defineProperty(exports, "AdmittanceRejectedError", { enumerable: true, get: function () { return admittance_1.AdmittanceRejectedError; } });
9
- var queue_1 = require("./queue");
10
- Object.defineProperty(exports, "InMemoryWorkQueue", { enumerable: true, get: function () { return queue_1.InMemoryWorkQueue; } });
11
25
  var execution_1 = require("./execution");
12
26
  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, "StartExecutionService", { enumerable: true, get: function () { return execution_1.StartExecutionService; } });
16
27
  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, "StepSettledHandler", { enumerable: true, get: function () { return execution_1.StepSettledHandler; } });
19
- Object.defineProperty(exports, "StepWorker", { enumerable: true, get: function () { return execution_1.StepWorker; } });
20
28
  var database_1 = require("./database");
21
29
  Object.defineProperty(exports, "createDataSource", { enumerable: true, get: function () { return database_1.createDataSource; } });
22
- Object.defineProperty(exports, "createStores", { enumerable: true, get: function () { return database_1.createStores; } });
23
30
  Object.defineProperty(exports, "WorkflowExecution", { enumerable: true, get: function () { return database_1.WorkflowExecution; } });
24
31
  Object.defineProperty(exports, "WorkflowStepExecution", { enumerable: true, get: function () { return database_1.WorkflowStepExecution; } });
25
32
  //# 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,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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qCAAgD;AAAvC,8GAAA,mBAAmB,OAAA;AAK5B,+BASgB;AARf,oGAAA,YAAY,OAAA;AACZ,sGAAA,cAAc,OAAA;AACd,+GAAA,uBAAuB,OAAA;AACvB,iHAAA,yBAAyB,OAAA;AACzB,uGAAA,eAAe,OAAA;AACf,yGAAA,iBAAiB,OAAA;AACjB,oHAAA,4BAA4B,OAAA;AAC5B,yGAAA,iBAAiB,OAAA;AAYlB,uDAI4B;AAH3B,kIAAA,8BAA8B,OAAA;AAC9B,6HAAA,yBAAyB,OAAA;AACzB,wHAAA,oBAAoB,OAAA;AAUrB,iCAAyD;AAAhD,oGAAA,WAAW,OAAA;AAAE,0GAAA,iBAAiB,OAAA;AAmBvC,2CAA2E;AAAlE,gHAAA,kBAAkB,OAAA;AAAE,qHAAA,uBAAuB,OAAA;AAgBpD,yCAAwE;AAA/D,mHAAA,sBAAsB,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAuBlD,uCAAwF;AAA/E,4GAAA,gBAAgB,OAAA;AAAE,6GAAA,iBAAiB,OAAA;AAAE,iHAAA,qBAAqB,OAAA"}
@@ -0,0 +1,26 @@
1
+ import type { LifecycleEventPublisher } from './lifecycle-event-publisher';
2
+ import type { LifecycleEventCallback, LifecycleEvent } from './lifecycle-event.types';
3
+ export declare const DEFAULT_LIFECYCLE_EVENT_FLUSH_INTERVAL_MS = 50;
4
+ export declare const DEFAULT_LIFECYCLE_EVENT_SEND_TIMEOUT_MS = 10000;
5
+ export declare const DEFAULT_MAX_PENDING_EVENTS: number;
6
+ export declare class BatchingLifecycleEventPublisher implements LifecycleEventPublisher {
7
+ private readonly send;
8
+ private readonly flushIntervalMs;
9
+ private readonly batchSize;
10
+ private readonly maxPending;
11
+ private readonly sendTimeoutMs;
12
+ private readonly pending;
13
+ private flushTimer;
14
+ private draining;
15
+ private stopped;
16
+ private abandoned;
17
+ private dropped;
18
+ constructor(send: LifecycleEventCallback, flushIntervalMs?: number, batchSize?: number, maxPending?: number, sendTimeoutMs?: number);
19
+ publish(event: LifecycleEvent): void;
20
+ stop(): Promise<void>;
21
+ private startDraining;
22
+ private drain;
23
+ private reportDropped;
24
+ private arm;
25
+ private disarm;
26
+ }
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BatchingLifecycleEventPublisher = exports.DEFAULT_MAX_PENDING_EVENTS = exports.DEFAULT_LIFECYCLE_EVENT_SEND_TIMEOUT_MS = exports.DEFAULT_LIFECYCLE_EVENT_FLUSH_INTERVAL_MS = void 0;
4
+ const lifecycle_event_schema_1 = require("./lifecycle-event.schema");
5
+ exports.DEFAULT_LIFECYCLE_EVENT_FLUSH_INTERVAL_MS = 50;
6
+ exports.DEFAULT_LIFECYCLE_EVENT_SEND_TIMEOUT_MS = 10_000;
7
+ exports.DEFAULT_MAX_PENDING_EVENTS = 20 * lifecycle_event_schema_1.MAX_LIFECYCLE_EVENTS_PER_BATCH;
8
+ class BatchingLifecycleEventPublisher {
9
+ send;
10
+ flushIntervalMs;
11
+ batchSize;
12
+ maxPending;
13
+ sendTimeoutMs;
14
+ pending = [];
15
+ flushTimer;
16
+ draining;
17
+ stopped = false;
18
+ abandoned = false;
19
+ dropped = 0;
20
+ constructor(send, flushIntervalMs = exports.DEFAULT_LIFECYCLE_EVENT_FLUSH_INTERVAL_MS, batchSize = lifecycle_event_schema_1.MAX_LIFECYCLE_EVENTS_PER_BATCH, maxPending = exports.DEFAULT_MAX_PENDING_EVENTS, sendTimeoutMs = exports.DEFAULT_LIFECYCLE_EVENT_SEND_TIMEOUT_MS) {
21
+ this.send = send;
22
+ this.flushIntervalMs = flushIntervalMs;
23
+ this.batchSize = batchSize;
24
+ this.maxPending = maxPending;
25
+ this.sendTimeoutMs = sendTimeoutMs;
26
+ }
27
+ publish(event) {
28
+ if (this.stopped)
29
+ return;
30
+ if (this.pending.length >= this.maxPending) {
31
+ this.dropped++;
32
+ return;
33
+ }
34
+ this.pending.push(event);
35
+ if (this.pending.length >= this.batchSize)
36
+ this.startDraining();
37
+ else
38
+ this.arm();
39
+ }
40
+ async stop() {
41
+ this.stopped = true;
42
+ this.startDraining();
43
+ try {
44
+ await withDeadline('lifecycle event drain', this.sendTimeoutMs, async () => {
45
+ await this.draining;
46
+ });
47
+ }
48
+ catch {
49
+ this.abandoned = true;
50
+ }
51
+ this.reportDropped();
52
+ }
53
+ startDraining() {
54
+ this.disarm();
55
+ if (this.draining)
56
+ return;
57
+ this.draining = this.drain().finally(() => {
58
+ this.draining = undefined;
59
+ });
60
+ }
61
+ async drain() {
62
+ await Promise.resolve();
63
+ while (this.pending.length > 0 && !this.abandoned) {
64
+ const batch = this.pending.splice(0, this.batchSize);
65
+ this.reportDropped();
66
+ try {
67
+ await withDeadline('lifecycle event callback', this.sendTimeoutMs, async (signal) => await this.send(batch, signal));
68
+ }
69
+ catch (error) {
70
+ console.warn(`engine: lifecycle event callback failed, dropped ${batch.length} event(s)`, error);
71
+ }
72
+ }
73
+ if (this.pending.length > 0) {
74
+ console.warn(`engine: lifecycle event publisher stopped, dropped ${this.pending.length} unsent event(s)`);
75
+ this.pending.length = 0;
76
+ }
77
+ }
78
+ reportDropped() {
79
+ if (this.dropped === 0)
80
+ return;
81
+ console.warn(`engine: lifecycle event backlog full, dropped ${this.dropped} event(s)`);
82
+ this.dropped = 0;
83
+ }
84
+ arm() {
85
+ if (this.flushTimer)
86
+ return;
87
+ this.flushTimer = setTimeout(() => {
88
+ this.flushTimer = undefined;
89
+ this.startDraining();
90
+ }, this.flushIntervalMs);
91
+ this.flushTimer.unref();
92
+ }
93
+ disarm() {
94
+ if (!this.flushTimer)
95
+ return;
96
+ clearTimeout(this.flushTimer);
97
+ this.flushTimer = undefined;
98
+ }
99
+ }
100
+ exports.BatchingLifecycleEventPublisher = BatchingLifecycleEventPublisher;
101
+ async function withDeadline(what, ms, work) {
102
+ const overdue = new AbortController();
103
+ let timer;
104
+ try {
105
+ return await Promise.race([
106
+ work(overdue.signal),
107
+ new Promise((_, reject) => {
108
+ timer = setTimeout(() => {
109
+ const error = new Error(`${what} did not settle within ${ms}ms`);
110
+ overdue.abort(error);
111
+ reject(error);
112
+ }, ms);
113
+ timer.unref();
114
+ }),
115
+ ]);
116
+ }
117
+ finally {
118
+ clearTimeout(timer);
119
+ }
120
+ }
121
+ //# sourceMappingURL=batching-lifecycle-event-publisher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batching-lifecycle-event-publisher.js","sourceRoot":"","sources":["../../src/lifecycle-events/batching-lifecycle-event-publisher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { BatchingLifecycleEventPublisher, DEFAULT_MAX_PENDING_EVENTS, DEFAULT_LIFECYCLE_EVENT_FLUSH_INTERVAL_MS, DEFAULT_LIFECYCLE_EVENT_SEND_TIMEOUT_MS, } from './batching-lifecycle-event-publisher';
2
+ export { noopLifecycleEventPublisher } from './lifecycle-event-publisher';
3
+ export type { LifecycleEventPublisher } from './lifecycle-event-publisher';
4
+ export { MAX_LIFECYCLE_EVENTS_PER_BATCH, lifecycleEventBatchSchema, lifecycleEventSchema, } from './lifecycle-event.schema';
5
+ export type { LifecycleEventBatch } from './lifecycle-event.schema';
6
+ export type { LifecycleEventCallback, LifecycleEvent } from './lifecycle-event.types';
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.lifecycleEventSchema = exports.lifecycleEventBatchSchema = exports.MAX_LIFECYCLE_EVENTS_PER_BATCH = exports.noopLifecycleEventPublisher = exports.DEFAULT_LIFECYCLE_EVENT_SEND_TIMEOUT_MS = exports.DEFAULT_LIFECYCLE_EVENT_FLUSH_INTERVAL_MS = exports.DEFAULT_MAX_PENDING_EVENTS = exports.BatchingLifecycleEventPublisher = void 0;
4
+ var batching_lifecycle_event_publisher_1 = require("./batching-lifecycle-event-publisher");
5
+ Object.defineProperty(exports, "BatchingLifecycleEventPublisher", { enumerable: true, get: function () { return batching_lifecycle_event_publisher_1.BatchingLifecycleEventPublisher; } });
6
+ Object.defineProperty(exports, "DEFAULT_MAX_PENDING_EVENTS", { enumerable: true, get: function () { return batching_lifecycle_event_publisher_1.DEFAULT_MAX_PENDING_EVENTS; } });
7
+ Object.defineProperty(exports, "DEFAULT_LIFECYCLE_EVENT_FLUSH_INTERVAL_MS", { enumerable: true, get: function () { return batching_lifecycle_event_publisher_1.DEFAULT_LIFECYCLE_EVENT_FLUSH_INTERVAL_MS; } });
8
+ Object.defineProperty(exports, "DEFAULT_LIFECYCLE_EVENT_SEND_TIMEOUT_MS", { enumerable: true, get: function () { return batching_lifecycle_event_publisher_1.DEFAULT_LIFECYCLE_EVENT_SEND_TIMEOUT_MS; } });
9
+ var lifecycle_event_publisher_1 = require("./lifecycle-event-publisher");
10
+ Object.defineProperty(exports, "noopLifecycleEventPublisher", { enumerable: true, get: function () { return lifecycle_event_publisher_1.noopLifecycleEventPublisher; } });
11
+ var lifecycle_event_schema_1 = require("./lifecycle-event.schema");
12
+ Object.defineProperty(exports, "MAX_LIFECYCLE_EVENTS_PER_BATCH", { enumerable: true, get: function () { return lifecycle_event_schema_1.MAX_LIFECYCLE_EVENTS_PER_BATCH; } });
13
+ Object.defineProperty(exports, "lifecycleEventBatchSchema", { enumerable: true, get: function () { return lifecycle_event_schema_1.lifecycleEventBatchSchema; } });
14
+ Object.defineProperty(exports, "lifecycleEventSchema", { enumerable: true, get: function () { return lifecycle_event_schema_1.lifecycleEventSchema; } });
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lifecycle-events/index.ts"],"names":[],"mappings":";;;AAAA,2FAK8C;AAJ7C,qJAAA,+BAA+B,OAAA;AAC/B,gJAAA,0BAA0B,OAAA;AAC1B,+JAAA,yCAAyC,OAAA;AACzC,6JAAA,uCAAuC,OAAA;AAExC,yEAA0E;AAAjE,wIAAA,2BAA2B,OAAA;AAEpC,mEAIkC;AAHjC,wIAAA,8BAA8B,OAAA;AAC9B,mIAAA,yBAAyB,OAAA;AACzB,8HAAA,oBAAoB,OAAA"}
@@ -0,0 +1,6 @@
1
+ import type { LifecycleEvent } from './lifecycle-event.types';
2
+ export interface LifecycleEventPublisher {
3
+ publish(event: LifecycleEvent): void;
4
+ stop(): Promise<void>;
5
+ }
6
+ export declare const noopLifecycleEventPublisher: LifecycleEventPublisher;