bpmn-elements 17.3.0 → 18.0.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.
Files changed (155) hide show
  1. package/README.md +3 -1
  2. package/dist/Api.js +83 -0
  3. package/dist/Context.js +228 -22
  4. package/dist/Environment.js +111 -31
  5. package/dist/EventBroker.js +57 -1
  6. package/dist/Expressions.js +3 -4
  7. package/dist/MessageFormatter.js +29 -16
  8. package/dist/Timers.js +13 -9
  9. package/dist/Tracker.js +1 -0
  10. package/dist/activity/Activity.js +434 -233
  11. package/dist/activity/ActivityExecution.js +113 -40
  12. package/dist/activity/Dummy.js +6 -1
  13. package/dist/activity/Escalation.js +36 -24
  14. package/dist/activity/ExecutionScope.js +1 -1
  15. package/dist/activity/Message.js +36 -24
  16. package/dist/activity/Signal.js +36 -24
  17. package/dist/activity/outbound-evaluator.js +1 -1
  18. package/dist/condition.js +12 -6
  19. package/dist/constants.js +27 -0
  20. package/dist/definition/Definition.js +187 -64
  21. package/dist/definition/DefinitionExecution.js +198 -84
  22. package/dist/error/BpmnError.js +12 -1
  23. package/dist/error/Errors.js +50 -9
  24. package/dist/eventDefinitions/CancelEventDefinition.js +29 -11
  25. package/dist/eventDefinitions/CompensateEventDefinition.js +51 -31
  26. package/dist/eventDefinitions/ConditionalEventDefinition.js +21 -9
  27. package/dist/eventDefinitions/ErrorEventDefinition.js +46 -30
  28. package/dist/eventDefinitions/EscalationEventDefinition.js +44 -27
  29. package/dist/eventDefinitions/EventDefinitionExecution.js +30 -23
  30. package/dist/eventDefinitions/LinkEventDefinition.js +45 -120
  31. package/dist/eventDefinitions/MessageEventDefinition.js +44 -29
  32. package/dist/eventDefinitions/SignalEventDefinition.js +46 -31
  33. package/dist/eventDefinitions/TerminateEventDefinition.js +10 -1
  34. package/dist/eventDefinitions/TimerEventDefinition.js +57 -37
  35. package/dist/eventDefinitions/index.js +20 -21
  36. package/dist/events/BoundaryEvent.js +52 -40
  37. package/dist/events/EndEvent.js +22 -8
  38. package/dist/events/IntermediateCatchEvent.js +26 -8
  39. package/dist/events/IntermediateThrowEvent.js +24 -9
  40. package/dist/events/StartEvent.js +30 -14
  41. package/dist/events/index.js +10 -11
  42. package/dist/flows/Association.js +50 -7
  43. package/dist/flows/MessageFlow.js +49 -10
  44. package/dist/flows/SequenceFlow.js +93 -22
  45. package/dist/flows/index.js +6 -7
  46. package/dist/gateways/EventBasedGateway.js +29 -15
  47. package/dist/gateways/ExclusiveGateway.js +20 -5
  48. package/dist/gateways/InclusiveGateway.js +21 -5
  49. package/dist/gateways/ParallelGateway.js +253 -15
  50. package/dist/gateways/index.js +8 -9
  51. package/dist/getPropertyValue.js +1 -1
  52. package/dist/index.js +42 -43
  53. package/dist/io/BpmnIO.js +15 -1
  54. package/dist/io/EnvironmentDataObject.js +29 -1
  55. package/dist/io/EnvironmentDataStore.js +24 -1
  56. package/dist/io/EnvironmentDataStoreReference.js +24 -1
  57. package/dist/io/InputOutputSpecification.js +21 -11
  58. package/dist/io/Properties.js +28 -17
  59. package/dist/messageHelper.js +41 -4
  60. package/dist/process/Lane.js +15 -4
  61. package/dist/process/Process.js +176 -77
  62. package/dist/process/ProcessExecution.js +397 -178
  63. package/dist/shared.js +2 -0
  64. package/dist/tasks/CallActivity.js +19 -4
  65. package/dist/tasks/LoopCharacteristics.js +94 -9
  66. package/dist/tasks/ReceiveTask.js +36 -21
  67. package/dist/tasks/ScriptTask.js +22 -6
  68. package/dist/tasks/ServiceImplementation.js +7 -4
  69. package/dist/tasks/ServiceTask.js +19 -4
  70. package/dist/tasks/SignalTask.js +19 -4
  71. package/dist/tasks/StandardLoopCharacteristics.js +8 -4
  72. package/dist/tasks/SubProcess.js +44 -29
  73. package/dist/tasks/Task.js +19 -4
  74. package/dist/tasks/Transaction.js +8 -4
  75. package/dist/tasks/index.js +16 -18
  76. package/package.json +31 -13
  77. package/src/Api.js +70 -0
  78. package/src/Context.js +200 -19
  79. package/src/Environment.js +99 -30
  80. package/src/EventBroker.js +46 -1
  81. package/src/Expressions.js +2 -3
  82. package/src/MessageFormatter.js +24 -16
  83. package/src/Timers.js +12 -9
  84. package/src/Tracker.js +1 -0
  85. package/src/activity/Activity.js +372 -218
  86. package/src/activity/ActivityExecution.js +93 -42
  87. package/src/activity/Dummy.js +6 -1
  88. package/src/activity/Escalation.js +25 -18
  89. package/src/activity/ExecutionScope.js +1 -1
  90. package/src/activity/Message.js +25 -18
  91. package/src/activity/Signal.js +25 -18
  92. package/src/activity/outbound-evaluator.js +1 -1
  93. package/src/condition.js +11 -5
  94. package/src/constants.js +21 -0
  95. package/src/definition/Definition.js +165 -63
  96. package/src/definition/DefinitionExecution.js +164 -85
  97. package/src/error/BpmnError.js +11 -1
  98. package/src/error/Errors.js +44 -5
  99. package/src/eventDefinitions/CancelEventDefinition.js +27 -13
  100. package/src/eventDefinitions/CompensateEventDefinition.js +48 -32
  101. package/src/eventDefinitions/ConditionalEventDefinition.js +20 -10
  102. package/src/eventDefinitions/ErrorEventDefinition.js +44 -33
  103. package/src/eventDefinitions/EscalationEventDefinition.js +39 -26
  104. package/src/eventDefinitions/EventDefinitionExecution.js +30 -24
  105. package/src/eventDefinitions/LinkEventDefinition.js +34 -120
  106. package/src/eventDefinitions/MessageEventDefinition.js +42 -31
  107. package/src/eventDefinitions/SignalEventDefinition.js +43 -32
  108. package/src/eventDefinitions/TerminateEventDefinition.js +9 -1
  109. package/src/eventDefinitions/TimerEventDefinition.js +53 -35
  110. package/src/eventDefinitions/index.js +10 -23
  111. package/src/events/BoundaryEvent.js +50 -39
  112. package/src/events/EndEvent.js +19 -7
  113. package/src/events/IntermediateCatchEvent.js +24 -8
  114. package/src/events/IntermediateThrowEvent.js +24 -8
  115. package/src/events/StartEvent.js +25 -14
  116. package/src/events/index.js +5 -18
  117. package/src/flows/Association.js +43 -9
  118. package/src/flows/MessageFlow.js +41 -10
  119. package/src/flows/SequenceFlow.js +82 -19
  120. package/src/flows/index.js +3 -4
  121. package/src/gateways/EventBasedGateway.js +27 -15
  122. package/src/gateways/ExclusiveGateway.js +16 -3
  123. package/src/gateways/InclusiveGateway.js +16 -3
  124. package/src/gateways/ParallelGateway.js +301 -10
  125. package/src/gateways/index.js +4 -4
  126. package/src/getPropertyValue.js +1 -1
  127. package/src/index.js +19 -19
  128. package/src/io/BpmnIO.js +13 -1
  129. package/src/io/EnvironmentDataObject.js +26 -1
  130. package/src/io/EnvironmentDataStore.js +22 -1
  131. package/src/io/EnvironmentDataStoreReference.js +22 -1
  132. package/src/io/InputOutputSpecification.js +17 -8
  133. package/src/io/Properties.js +23 -13
  134. package/src/messageHelper.js +36 -4
  135. package/src/process/Lane.js +14 -4
  136. package/src/process/Process.js +157 -74
  137. package/src/process/ProcessExecution.js +363 -176
  138. package/src/shared.js +1 -0
  139. package/src/tasks/CallActivity.js +16 -2
  140. package/src/tasks/LoopCharacteristics.js +77 -11
  141. package/src/tasks/ReceiveTask.js +33 -22
  142. package/src/tasks/ScriptTask.js +17 -3
  143. package/src/tasks/ServiceImplementation.js +6 -3
  144. package/src/tasks/ServiceTask.js +16 -2
  145. package/src/tasks/SignalTask.js +16 -2
  146. package/src/tasks/StandardLoopCharacteristics.js +7 -3
  147. package/src/tasks/SubProcess.js +37 -23
  148. package/src/tasks/Task.js +16 -2
  149. package/src/tasks/Transaction.js +7 -3
  150. package/src/tasks/index.js +8 -9
  151. package/types/bundle-errors.d.ts +1 -0
  152. package/types/bundle.d.ts +97 -0
  153. package/types/index.d.ts +2619 -84
  154. package/types/interfaces.d.ts +638 -0
  155. package/types/types.d.ts +0 -765
@@ -3,22 +3,25 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.ProcessExecution = ProcessExecution;
7
7
  var _Api = require("../Api.js");
8
8
  var _messageHelper = require("../messageHelper.js");
9
9
  var _shared = require("../shared.js");
10
10
  var _Tracker = require("../Tracker.js");
11
- var _default = exports.default = ProcessExecution;
12
- const kActivated = Symbol.for('activated');
13
- const kActivityQ = Symbol.for('activityQ');
14
- const kCompleted = Symbol.for('completed');
15
- const kElements = Symbol.for('elements');
16
- const kExecuteMessage = Symbol.for('executeMessage');
17
- const kMessageHandlers = Symbol.for('messageHandlers');
18
- const kParent = Symbol.for('parent');
19
- const kStatus = Symbol.for('status');
20
- const kStopped = Symbol.for('stopped');
21
- const kTracker = Symbol.for('activity tracker');
11
+ var _constants = require("../constants.js");
12
+ const K_ACTIVITY_Q = Symbol.for('activityQ');
13
+ const K_ELEMENTS = Symbol.for('elements');
14
+ const K_PARENT = Symbol.for('parent');
15
+ const K_TRACKER = Symbol.for('activity tracker');
16
+ const K_PEERS_DISCOVERED = Symbol.for('peers discovered');
17
+ const K_RECOVERED_VERSION = Symbol.for('recovered version');
18
+
19
+ /**
20
+ * Drives the execution of a single process or sub-process: activates children, routes activity
21
+ * events, and rolls completion up to the owning Process or sub-process Activity.
22
+ * @param {import('#types').Process | import('#types').Activity} parentActivity
23
+ * @param {import('#types').ContextInstance} context
24
+ */
22
25
  function ProcessExecution(parentActivity, context) {
23
26
  const {
24
27
  id,
@@ -27,7 +30,7 @@ function ProcessExecution(parentActivity, context) {
27
30
  isSubProcess,
28
31
  isTransaction
29
32
  } = parentActivity;
30
- this[kParent] = parentActivity;
33
+ this[K_PARENT] = parentActivity;
31
34
  this.id = id;
32
35
  this.type = type;
33
36
  this.isSubProcess = isSubProcess;
@@ -35,29 +38,30 @@ function ProcessExecution(parentActivity, context) {
35
38
  this.broker = broker;
36
39
  this.environment = context.environment;
37
40
  this.context = context;
38
- this[kElements] = {
41
+ this[K_ELEMENTS] = {
39
42
  postponed: new Set(),
40
43
  children: context.getActivities(id),
41
44
  associations: context.getAssociations(id),
42
45
  flows: context.getSequenceFlows(id),
43
46
  outboundMessageFlows: context.getMessageFlows(id),
44
47
  startActivities: new Set(),
48
+ startEventCount: 0,
45
49
  triggeredByEvent: new Set(),
46
50
  detachedActivities: new Set(),
47
- startSequences: {}
51
+ convergingGateways: new Set()
48
52
  };
49
53
  const exchangeName = this._exchangeName = isSubProcess ? 'subprocess-execution' : 'execution';
50
54
  broker.assertExchange(exchangeName, 'topic', {
51
55
  autoDelete: false,
52
56
  durable: true
53
57
  });
54
- this[kCompleted] = false;
55
- this[kStopped] = false;
56
- this[kActivated] = false;
57
- this[kStatus] = 'init';
58
- this[kTracker] = new _Tracker.ActivityTracker(id);
58
+ this[_constants.K_COMPLETED] = false;
59
+ this[_constants.K_STOPPED] = false;
60
+ this[_constants.K_ACTIVATED] = false;
61
+ this[_constants.K_STATUS] = 'init';
62
+ this[K_TRACKER] = new _Tracker.ActivityTracker(id);
59
63
  this.executionId = undefined;
60
- this[kMessageHandlers] = {
64
+ this[_constants.K_MESSAGE_HANDLERS] = {
61
65
  onActivityEvent: this._onActivityEvent.bind(this),
62
66
  onApiMessage: this._onApiMessage.bind(this),
63
67
  onChildMessage: this._onChildMessage.bind(this),
@@ -67,46 +71,52 @@ function ProcessExecution(parentActivity, context) {
67
71
  Object.defineProperties(ProcessExecution.prototype, {
68
72
  stopped: {
69
73
  get() {
70
- return this[kStopped];
74
+ return this[_constants.K_STOPPED];
71
75
  }
72
76
  },
73
77
  completed: {
74
78
  get() {
75
- return this[kCompleted];
79
+ return this[_constants.K_COMPLETED];
76
80
  }
77
81
  },
78
82
  status: {
79
83
  get() {
80
- return this[kStatus];
84
+ return this[_constants.K_STATUS];
81
85
  }
82
86
  },
83
87
  postponedCount: {
84
88
  get() {
85
- return this[kElements].postponed.size;
89
+ return this[K_ELEMENTS].postponed.size;
86
90
  }
87
91
  },
88
92
  isRunning: {
89
93
  get() {
90
- return this[kActivated];
94
+ return this[_constants.K_ACTIVATED];
91
95
  }
92
96
  },
93
97
  activityStatus: {
94
98
  get() {
95
- return this[kTracker].activityStatus;
99
+ return this[K_TRACKER].activityStatus;
96
100
  }
97
101
  }
98
102
  });
103
+
104
+ /**
105
+ * Activate children and start the process execution. Resumes if the message is redelivered.
106
+ * @param {import('#types').ElementBrokerMessage} executeMessage
107
+ * @throws {Error} when message or executionId is missing
108
+ */
99
109
  ProcessExecution.prototype.execute = function execute(executeMessage) {
100
110
  if (!executeMessage) throw new Error('Process execution requires message');
101
111
  if (!executeMessage.content || !executeMessage.content.executionId) throw new Error('Process execution requires execution id');
102
112
  const executionId = this.executionId = executeMessage.content.executionId;
103
- this[kExecuteMessage] = (0, _messageHelper.cloneMessage)(executeMessage, {
113
+ this[_constants.K_EXECUTE_MESSAGE] = (0, _messageHelper.cloneMessage)(executeMessage, {
104
114
  executionId,
105
115
  state: 'start'
106
116
  });
107
- this[kStopped] = false;
117
+ this[_constants.K_STOPPED] = false;
108
118
  this.environment.assignVariables(executeMessage);
109
- this[kActivityQ] = this.broker.assertQueue(`execute-${executionId}-q`, {
119
+ this[K_ACTIVITY_Q] = this.broker.assertQueue(`execute-${executionId}-q`, {
110
120
  durable: true,
111
121
  autoDelete: false
112
122
  });
@@ -118,28 +128,29 @@ ProcessExecution.prototype.execute = function execute(executeMessage) {
118
128
  this._start();
119
129
  return true;
120
130
  };
131
+
132
+ /**
133
+ * Resume after recover, resuming any postponed children.
134
+ */
121
135
  ProcessExecution.prototype.resume = function resume() {
122
136
  this._debug(`resume process execution at ${this.status}`);
123
- if (this[kCompleted]) return this._complete('completed');
137
+ if (this[_constants.K_COMPLETED]) return this._complete('completed');
124
138
  this._activate();
125
139
  const {
126
- startActivities,
127
- detachedActivities,
128
- postponed
129
- } = this[kElements];
130
- if (startActivities.size > 1) {
131
- for (const a of startActivities) a.shake();
132
- }
140
+ postponed,
141
+ detachedActivities
142
+ } = this[K_ELEMENTS];
143
+ this._shakeOnStart();
133
144
  postponed.clear();
134
145
  detachedActivities.clear();
135
- this[kActivityQ].consume(this[kMessageHandlers].onChildMessage, {
146
+ this[K_ACTIVITY_Q].consume(this[_constants.K_MESSAGE_HANDLERS].onChildMessage, {
136
147
  prefetch: 1000,
137
148
  consumerTag: `_process-activity-${this.executionId}`
138
149
  });
139
- if (this[kCompleted]) return;
150
+ if (this[_constants.K_COMPLETED]) return;
140
151
  const status = this.status;
141
152
  if (status === 'init') return this._start();
142
- const tracker = this[kTracker];
153
+ const tracker = this[K_TRACKER];
143
154
  for (const msg of new Set(postponed)) {
144
155
  const activity = this.getActivityById(msg.content.id);
145
156
  if (!activity) continue;
@@ -152,16 +163,23 @@ ProcessExecution.prototype.resume = function resume() {
152
163
  tracker.track(msg.fields.routingKey, msg);
153
164
  activity.resume();
154
165
  }
155
- if (this[kCompleted]) return;
166
+ if (this[_constants.K_COMPLETED]) return;
167
+ this._reconcileStartEvents();
168
+ if (this[_constants.K_COMPLETED]) return;
156
169
  if (!postponed.size && status === 'executing') return this._complete('completed');
157
170
  };
171
+
172
+ /**
173
+ * Snapshot execution state including children, flows, message flows, and associations.
174
+ * @returns {import('#types').ProcessExecutionState}
175
+ */
158
176
  ProcessExecution.prototype.getState = function getState() {
159
177
  const {
160
178
  children,
161
179
  flows,
162
180
  outboundMessageFlows,
163
181
  associations
164
- } = this[kElements];
182
+ } = this[K_ELEMENTS];
165
183
  const flowStates = flows.reduce((result, flow) => {
166
184
  const elmState = flow.getState();
167
185
  if (elmState) result.push(elmState);
@@ -169,8 +187,8 @@ ProcessExecution.prototype.getState = function getState() {
169
187
  }, []);
170
188
  return {
171
189
  executionId: this.executionId,
172
- stopped: this[kStopped],
173
- completed: this[kCompleted],
190
+ stopped: this[_constants.K_STOPPED],
191
+ completed: this[_constants.K_COMPLETED],
174
192
  status: this.status,
175
193
  children: children.reduce((result, activity) => {
176
194
  if (activity.placeholder) return result;
@@ -189,12 +207,20 @@ ProcessExecution.prototype.getState = function getState() {
189
207
  })
190
208
  };
191
209
  };
192
- ProcessExecution.prototype.recover = function recover(state) {
210
+
211
+ /**
212
+ * Restore execution state captured by getState.
213
+ * @param {import('#types').ProcessExecutionState} [state]
214
+ * @param {number} [recoveredVersion] State version
215
+ * @returns {this}
216
+ */
217
+ ProcessExecution.prototype.recover = function recover(state, recoveredVersion) {
193
218
  if (!state) return this;
194
219
  this.executionId = state.executionId;
195
- this[kStopped] = state.stopped;
196
- this[kCompleted] = state.completed;
197
- this[kStatus] = state.status;
220
+ this[K_RECOVERED_VERSION] = recoveredVersion;
221
+ this[_constants.K_STOPPED] = state.stopped;
222
+ this[_constants.K_COMPLETED] = state.completed;
223
+ this[_constants.K_STATUS] = state.status;
198
224
  this._debug(`recover process execution at ${this.status}`);
199
225
  if (state.messageFlows) {
200
226
  for (const flowState of state.messageFlows) {
@@ -226,53 +252,30 @@ ProcessExecution.prototype.recover = function recover(state) {
226
252
  }
227
253
  return this;
228
254
  };
255
+
256
+ /**
257
+ * Walk activity graph from the given start id, or every start activity when omitted.
258
+ * @param {string} [fromId]
259
+ * @returns {import('#types').ShakeResult}
260
+ */
229
261
  ProcessExecution.prototype.shake = function shake(fromId) {
230
- let executing = true;
231
- const id = this.id;
232
- if (!this.isRunning) {
233
- executing = false;
234
- this.executionId = (0, _shared.getUniqueId)(id);
235
- this._activate();
236
- }
237
- const toShake = fromId ? [this.getActivityById(fromId)].filter(Boolean) : this[kElements].startActivities;
238
- const result = {};
239
- this.broker.subscribeTmp('event', '*.shake.*', (routingKey, {
240
- content
241
- }) => {
242
- let isLooped = false;
243
- switch (routingKey) {
244
- case 'flow.shake.loop':
245
- isLooped = true;
246
- case 'activity.shake.end':
247
- {
248
- const {
249
- id: shakeId,
250
- parent: shakeParent
251
- } = content;
252
- if (shakeParent.id !== id) return;
253
- result[shakeId] = result[shakeId] || [];
254
- result[shakeId].push({
255
- ...content,
256
- isLooped
257
- });
258
- break;
259
- }
260
- }
261
- }, {
262
- noAck: true,
263
- consumerTag: `_shaker-${this.executionId}`
264
- });
265
- for (const a of toShake) a.shake();
266
- if (!executing) this._deactivate();
267
- this.broker.cancel(`_shaker-${this.executionId}`);
268
- return result;
262
+ return Object.fromEntries(this._shakeElements(fromId).sequences);
269
263
  };
264
+
265
+ /**
266
+ * Stop the running process execution via the api.
267
+ */
270
268
  ProcessExecution.prototype.stop = function stop() {
271
269
  this.getApi().stop();
272
270
  };
271
+
272
+ /**
273
+ * List currently postponed children as Api wrappers.
274
+ * @param {import('#types').filterPostponed} [filterFn]
275
+ */
273
276
  ProcessExecution.prototype.getPostponed = function getPostponed(filterFn) {
274
277
  const result = [];
275
- for (const msg of this[kElements].postponed) {
278
+ for (const msg of this[K_ELEMENTS].postponed) {
276
279
  const api = this._getChildApi(msg);
277
280
  if (!api) continue;
278
281
  if (filterFn && !filterFn(api)) continue;
@@ -280,9 +283,13 @@ ProcessExecution.prototype.getPostponed = function getPostponed(filterFn) {
280
283
  }
281
284
  return result;
282
285
  };
286
+
287
+ /**
288
+ * Queue a discard message that propagates to all running children.
289
+ */
283
290
  ProcessExecution.prototype.discard = function discard() {
284
- this[kStatus] = 'discard';
285
- return this[kActivityQ].queueMessage({
291
+ this[_constants.K_STATUS] = 'discard';
292
+ this[K_ACTIVITY_Q].queueMessage({
286
293
  routingKey: 'execution.discard'
287
294
  }, {
288
295
  id: this.id,
@@ -292,8 +299,12 @@ ProcessExecution.prototype.discard = function discard() {
292
299
  type: 'discard'
293
300
  });
294
301
  };
302
+
303
+ /**
304
+ * Queue a cancel message that propagates to all running children.
305
+ */
295
306
  ProcessExecution.prototype.cancel = function discard() {
296
- return this[kActivityQ].queueMessage({
307
+ this[K_ACTIVITY_Q].queueMessage({
297
308
  routingKey: 'execution.cancel'
298
309
  }, {
299
310
  id: this.id,
@@ -303,26 +314,52 @@ ProcessExecution.prototype.cancel = function discard() {
303
314
  type: 'cancel'
304
315
  });
305
316
  };
317
+
318
+ /**
319
+ * Get child activities in the process scope.
320
+ * @returns {import('#types').Activity[]}
321
+ */
306
322
  ProcessExecution.prototype.getActivities = function getActivities() {
307
- return this[kElements].children.slice();
323
+ return this[K_ELEMENTS].children.slice();
308
324
  };
325
+
326
+ /**
327
+ * @param {string} activityId
328
+ * @returns {import('#types').Activity}
329
+ */
309
330
  ProcessExecution.prototype.getActivityById = function getActivityById(activityId) {
310
- return this[kElements].children.find(child => child.id === activityId);
331
+ return this[K_ELEMENTS].children.find(child => child.id === activityId);
311
332
  };
333
+
334
+ /**
335
+ * Get sequence flows in the process scope.
336
+ * @returns {import('#types').SequenceFlow}
337
+ */
312
338
  ProcessExecution.prototype.getSequenceFlows = function getSequenceFlows() {
313
- return this[kElements].flows.slice();
339
+ return this[K_ELEMENTS].flows.slice();
314
340
  };
341
+
342
+ /**
343
+ * Get associations in the process scope.
344
+ * @returns {import('../flows/Association.js').Association}
345
+ */
315
346
  ProcessExecution.prototype.getAssociations = function getAssociations() {
316
- return this[kElements].associations.slice();
347
+ return this[K_ELEMENTS].associations.slice();
317
348
  };
349
+
350
+ /**
351
+ * Resolve a process or child Api for the given message.
352
+ * @param {import('#types').ElementBrokerMessage} [message]
353
+ * @returns {import('#types').IApi<import('#types').Process>}
354
+ */
318
355
  ProcessExecution.prototype.getApi = function getApi(message) {
319
- if (!message) return (0, _Api.ProcessApi)(this.broker, this[kExecuteMessage]);
356
+ if (!message) return (0, _Api.ProcessApi)(this.broker, this[_constants.K_EXECUTE_MESSAGE]);
320
357
  const content = message.content;
321
358
  if (content.executionId !== this.executionId) {
322
359
  return this._getChildApi(message);
323
360
  }
324
361
  const api = (0, _Api.ProcessApi)(this.broker, message);
325
- const postponed = this[kElements].postponed;
362
+ const postponed = this[K_ELEMENTS].postponed;
326
363
  const self = this;
327
364
  api.getExecuting = function getExecuting() {
328
365
  const result = [];
@@ -334,13 +371,15 @@ ProcessExecution.prototype.getApi = function getApi(message) {
334
371
  };
335
372
  return api;
336
373
  };
374
+
375
+ /** @internal */
337
376
  ProcessExecution.prototype._start = function start() {
338
- if (!this[kElements].children.length) {
377
+ if (!this[K_ELEMENTS].children.length) {
339
378
  return this._complete('completed');
340
379
  }
341
- this[kStatus] = 'start';
380
+ this[_constants.K_STATUS] = 'start';
342
381
  const executeContent = {
343
- ...this[kExecuteMessage].content,
382
+ ...this[_constants.K_EXECUTE_MESSAGE].content,
344
383
  state: this.status
345
384
  };
346
385
  this.broker.publish(this._exchangeName, 'execute.start', (0, _messageHelper.cloneContent)(executeContent));
@@ -348,26 +387,31 @@ ProcessExecution.prototype._start = function start() {
348
387
  startActivities,
349
388
  postponed,
350
389
  detachedActivities
351
- } = this[kElements];
352
- if (startActivities.size > 1) {
353
- for (const a of startActivities) a.shake();
354
- }
390
+ } = this[K_ELEMENTS];
391
+ this._shakeOnStart();
355
392
  for (const a of startActivities) a.init();
356
- this[kStatus] = 'executing';
393
+ this[_constants.K_STATUS] = 'executing';
357
394
  for (const a of startActivities) a.run();
395
+ if (!startActivities.size) {
396
+ for (const a of this[K_ELEMENTS].triggeredByEvent) {
397
+ if (a.isCatching && !a.isRunning) a.run();
398
+ }
399
+ }
358
400
  postponed.clear();
359
401
  detachedActivities.clear();
360
- this[kActivityQ].assertConsumer(this[kMessageHandlers].onChildMessage, {
402
+ this[K_ACTIVITY_Q].assertConsumer(this[_constants.K_MESSAGE_HANDLERS].onChildMessage, {
361
403
  prefetch: 1000,
362
404
  consumerTag: `_process-activity-${this.executionId}`
363
405
  });
364
406
  };
407
+
408
+ /** @internal */
365
409
  ProcessExecution.prototype._activate = function activate() {
366
410
  const {
367
411
  onApiMessage,
368
412
  onMessageFlowEvent,
369
413
  onActivityEvent
370
- } = this[kMessageHandlers];
414
+ } = this[_constants.K_MESSAGE_HANDLERS];
371
415
  if (!this.isSubProcess) {
372
416
  this.broker.consume('api-q', onApiMessage, {
373
417
  noAck: true,
@@ -387,8 +431,9 @@ ProcessExecution.prototype._activate = function activate() {
387
431
  associations,
388
432
  startActivities,
389
433
  triggeredByEvent,
434
+ convergingGateways,
390
435
  children
391
- } = this[kElements];
436
+ } = this[K_ELEMENTS];
392
437
  for (const flow of outboundMessageFlows) {
393
438
  flow.activate();
394
439
  flow.broker.subscribeTmp('event', '#', onMessageFlowEvent, {
@@ -413,6 +458,7 @@ ProcessExecution.prototype._activate = function activate() {
413
458
  }
414
459
  startActivities.clear();
415
460
  triggeredByEvent.clear();
461
+ let startEventCount = 0;
416
462
  for (const activity of children) {
417
463
  if (activity.placeholder) continue;
418
464
  activity.activate(this);
@@ -421,11 +467,18 @@ ProcessExecution.prototype._activate = function activate() {
421
467
  consumerTag: '_process-activity-consumer',
422
468
  priority: 200
423
469
  });
424
- if (activity.isStart) startActivities.add(activity);
425
- if (activity.triggeredByEvent) triggeredByEvent.add(activity);
470
+ if (activity.isStart) {
471
+ startActivities.add(activity);
472
+ if (activity.isStartEvent) startEventCount++;
473
+ }
474
+ if (activity.triggeredByEvent || activity.isCatching) triggeredByEvent.add(activity);
475
+ if (activity.isParallelGateway) convergingGateways.add(activity);
426
476
  }
427
- this[kActivated] = true;
477
+ this[K_ELEMENTS].startEventCount = startEventCount;
478
+ this[_constants.K_ACTIVATED] = true;
428
479
  };
480
+
481
+ /** @internal */
429
482
  ProcessExecution.prototype._deactivate = function deactivate() {
430
483
  const broker = this.broker;
431
484
  const executionId = this.executionId;
@@ -436,7 +489,7 @@ ProcessExecution.prototype._deactivate = function deactivate() {
436
489
  flows,
437
490
  associations,
438
491
  outboundMessageFlows
439
- } = this[kElements];
492
+ } = this[K_ELEMENTS];
440
493
  for (const activity of children) {
441
494
  if (activity.placeholder) continue;
442
495
  activity.broker.cancel('_process-activity-consumer');
@@ -452,8 +505,105 @@ ProcessExecution.prototype._deactivate = function deactivate() {
452
505
  flow.deactivate();
453
506
  flow.broker.cancel('_process-message-consumer');
454
507
  }
455
- this[kActivated] = false;
508
+ this[_constants.K_ACTIVATED] = false;
456
509
  };
510
+
511
+ /**
512
+ * Discover converging parallel gateway peers for the peer monitor, reusing already discovered ones.
513
+ * @internal
514
+ */
515
+ ProcessExecution.prototype._shakeOnStart = function shakeOnStart() {
516
+ const convergingGateways = this[K_ELEMENTS].convergingGateways;
517
+ if (!convergingGateways.size) return;
518
+ if (this._peersDiscovered()) {
519
+ this._debug(`reuse discovered parallel gateway peers (${convergingGateways.size})`);
520
+ return;
521
+ }
522
+ this._shakeElements();
523
+ this._debug(`forced shake to discover converging gateway peers (${convergingGateways.size})`);
524
+ };
525
+
526
+ /**
527
+ * Whether every converging parallel gateway has discovered its peers in this runtime instance.
528
+ * Peers are a runtime cache and absent after recover, so a changed source is reshaken.
529
+ * @internal
530
+ */
531
+ ProcessExecution.prototype._peersDiscovered = function peersDiscovered() {
532
+ const convergingGateways = this[K_ELEMENTS].convergingGateways;
533
+ for (const gateway of convergingGateways) {
534
+ if (!gateway[K_PEERS_DISCOVERED]) return false;
535
+ }
536
+ return true;
537
+ };
538
+
539
+ /** @internal */
540
+ ProcessExecution.prototype._shakeElements = function shakeElements(fromId) {
541
+ let executing = true;
542
+ const id = this.id;
543
+ if (!this.isRunning) {
544
+ executing = false;
545
+ this.executionId = (0, _shared.getUniqueId)(id);
546
+ this._activate();
547
+ }
548
+ const toShake = fromId ? [this.getActivityById(fromId)].filter(Boolean) : this[K_ELEMENTS].startActivities;
549
+ const result = {
550
+ sequences: new Map()
551
+ };
552
+ const convergingGateways = new Map();
553
+ const consumerTag = `_shaker-${this.executionId}`;
554
+ this.broker.subscribeTmp('event', '*.shake.*', (routingKey, {
555
+ content
556
+ }) => {
557
+ if (content.parent.id !== this.id) return;
558
+ switch (routingKey) {
559
+ case 'activity.shake.join':
560
+ {
561
+ const join = convergingGateways.get(content.join);
562
+ if (!join) {
563
+ convergingGateways.set(content.join, content);
564
+ } else {
565
+ join.sequence = join.sequence.concat(content.sequence);
566
+ }
567
+ break;
568
+ }
569
+ case 'flow.shake.loop':
570
+ case 'activity.shake.linked':
571
+ case 'activity.shake.end':
572
+ {
573
+ const {
574
+ id: shakeId,
575
+ parent: shakeParent
576
+ } = content;
577
+ if (shakeParent.id !== id) return;
578
+ let seqnce;
579
+ if (!(seqnce = result.sequences.get(shakeId))) {
580
+ seqnce = [];
581
+ result.sequences.set(shakeId, seqnce);
582
+ }
583
+ seqnce.push({
584
+ ...content,
585
+ isLooped: routingKey === 'flow.shake.loop'
586
+ });
587
+ break;
588
+ }
589
+ }
590
+ }, {
591
+ noAck: true,
592
+ consumerTag
593
+ });
594
+ for (const a of toShake) a.shake();
595
+ for (const [aid, c] of convergingGateways.entries()) {
596
+ this._debug(`manual shake of converging gateway <${aid}>`);
597
+ this.getActivityById(aid).broker.publish('api', 'activity.shake.continue', c, {
598
+ type: 'shake'
599
+ });
600
+ }
601
+ if (!executing) this._deactivate();
602
+ this.broker.cancel(consumerTag);
603
+ return result;
604
+ };
605
+
606
+ /** @internal */
457
607
  ProcessExecution.prototype._onDelegateEvent = function onDelegateEvent(message) {
458
608
  const eventType = message.properties.type;
459
609
  let delegate = true;
@@ -463,8 +613,8 @@ ProcessExecution.prototype._onDelegateEvent = function onDelegateEvent(message)
463
613
  } else {
464
614
  this._debug(`delegate ${eventType} anonymous event`);
465
615
  }
466
- for (const activity of this[kElements].triggeredByEvent) {
467
- if (activity.getStartActivities({
616
+ for (const activity of this[K_ELEMENTS].triggeredByEvent) {
617
+ if (activity.isSubProcess && activity.getStartActivities({
468
618
  referenceId: content.message?.id,
469
619
  referenceType: eventType
470
620
  }).length) {
@@ -477,15 +627,23 @@ ProcessExecution.prototype._onDelegateEvent = function onDelegateEvent(message)
477
627
  });
478
628
  return delegate;
479
629
  };
630
+
631
+ /** @internal */
480
632
  ProcessExecution.prototype._onMessageFlowEvent = function onMessageFlowEvent(routingKey, message) {
481
633
  this.broker.publish('message', routingKey, (0, _messageHelper.cloneContent)(message.content), message.properties);
482
634
  };
635
+
636
+ /** @internal */
483
637
  ProcessExecution.prototype._onActivityEvent = function onActivityEvent(routingKey, message) {
484
- if (message.fields.redelivered && message.properties.persistent === false) return;
485
- const content = message.content;
638
+ const {
639
+ fields,
640
+ content,
641
+ properties
642
+ } = message;
643
+ if (fields.redelivered && properties.persistent === false) return;
486
644
  const parent = content.parent = content.parent || {};
487
- let delegate = message.properties.delegate;
488
- const shaking = message.properties.type === 'shake';
645
+ let delegate = properties.delegate;
646
+ const shaking = properties.type === 'shake';
489
647
  const isDirectChild = content.parent.id === this.id;
490
648
  if (isDirectChild) {
491
649
  parent.executionId = this.executionId;
@@ -497,17 +655,17 @@ ProcessExecution.prototype._onActivityEvent = function onActivityEvent(routingKe
497
655
  });
498
656
  }
499
657
  if (delegate) delegate = this._onDelegateEvent(message);
500
- this[kTracker].track(routingKey, message);
658
+ this[K_TRACKER].track(routingKey, message);
501
659
  this.broker.publish('event', routingKey, content, {
502
- ...message.properties,
660
+ ...properties,
503
661
  delegate,
504
662
  mandatory: false
505
663
  });
506
- if (shaking) return this._onShookEnd(message);
664
+ if (shaking) return;
507
665
  if (!isDirectChild) return;
508
666
  switch (routingKey) {
509
667
  case 'process.terminate':
510
- return this[kActivityQ].queueMessage({
668
+ return this[K_ACTIVITY_Q].queueMessage({
511
669
  routingKey: 'execution.terminate'
512
670
  }, (0, _messageHelper.cloneContent)(content), {
513
671
  type: 'terminate',
@@ -516,11 +674,13 @@ ProcessExecution.prototype._onActivityEvent = function onActivityEvent(routingKe
516
674
  case 'activity.stop':
517
675
  return;
518
676
  }
519
- this[kActivityQ].queueMessage(message.fields, (0, _messageHelper.cloneContent)(content), {
677
+ this[K_ACTIVITY_Q].queueMessage(message.fields, (0, _messageHelper.cloneContent)(content), {
520
678
  persistent: true,
521
679
  ...message.properties
522
680
  });
523
681
  };
682
+
683
+ /** @internal */
524
684
  ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey, message) {
525
685
  if (message.fields.redelivered && message.properties.persistent === false) return message.ack();
526
686
  const content = message.content;
@@ -537,7 +697,7 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
537
697
  case 'execution.discard.detached':
538
698
  {
539
699
  message.ack();
540
- for (const detached of this[kElements].detachedActivities) {
700
+ for (const detached of this[K_ELEMENTS].detachedActivities) {
541
701
  this._getChildApi(detached).discard();
542
702
  }
543
703
  return;
@@ -548,7 +708,7 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
548
708
  case 'activity.error.caught':
549
709
  {
550
710
  let prevMsg;
551
- for (const msg of this[kElements].postponed) {
711
+ for (const msg of this[K_ELEMENTS].postponed) {
552
712
  if (msg.content.executionId === content.executionId) {
553
713
  prevMsg = msg;
554
714
  break;
@@ -557,7 +717,6 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
557
717
  if (!prevMsg) return message.ack();
558
718
  break;
559
719
  }
560
- case 'flow.looped':
561
720
  case 'activity.leave':
562
721
  return this._onChildCompleted(message);
563
722
  }
@@ -565,7 +724,7 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
565
724
  switch (routingKey) {
566
725
  case 'activity.detach':
567
726
  {
568
- this[kElements].detachedActivities.add((0, _messageHelper.cloneMessage)(message));
727
+ this[K_ELEMENTS].detachedActivities.add((0, _messageHelper.cloneMessage)(message));
569
728
  break;
570
729
  }
571
730
  case 'activity.cancel':
@@ -584,17 +743,24 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
584
743
  }
585
744
  break;
586
745
  }
746
+ case 'activity.end':
747
+ {
748
+ if (!(content.isStartEvent || this.getActivityById(content.id)?.isStartEvent)) break;
749
+ if (this[K_ELEMENTS].startEventCount <= 1) break;
750
+ this._discardArmedStartEvents(content.id);
751
+ break;
752
+ }
587
753
  case 'activity.error':
588
754
  {
589
755
  let eventCaughtBy;
590
- for (const msg of this[kElements].postponed) {
756
+ for (const msg of this[K_ELEMENTS].postponed) {
591
757
  if (msg.fields.routingKey === 'activity.catch' && msg.content.source?.executionId === content.executionId) {
592
758
  eventCaughtBy = msg;
593
759
  break;
594
760
  }
595
761
  }
596
762
  if (eventCaughtBy) {
597
- this[kActivityQ].queueMessage({
763
+ this[K_ACTIVITY_Q].queueMessage({
598
764
  routingKey: 'activity.error.caught'
599
765
  }, (0, _messageHelper.cloneContent)(content), {
600
766
  persistent: true,
@@ -608,16 +774,20 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
608
774
  }
609
775
  }
610
776
  };
777
+
778
+ /** @internal */
611
779
  ProcessExecution.prototype._stateChangeMessage = function stateChangeMessage(message, postponeMessage) {
612
780
  const previousMsg = this._popPostponed(message.content);
613
781
  if (previousMsg) previousMsg.ack();
614
- if (postponeMessage) this[kElements].postponed.add(message);
782
+ if (postponeMessage) this[K_ELEMENTS].postponed.add(message);
615
783
  };
784
+
785
+ /** @internal */
616
786
  ProcessExecution.prototype._popPostponed = function popPostponed(byContent) {
617
787
  const {
618
788
  postponed,
619
789
  detachedActivities
620
- } = this[kElements];
790
+ } = this[K_ELEMENTS];
621
791
  let postponedMsg;
622
792
  if (byContent.sequenceId) {
623
793
  for (const msg of postponed) {
@@ -644,19 +814,25 @@ ProcessExecution.prototype._popPostponed = function popPostponed(byContent) {
644
814
  }
645
815
  return postponedMsg;
646
816
  };
817
+
818
+ /** @internal */
647
819
  ProcessExecution.prototype._onChildCompleted = function onChildCompleted(message) {
648
820
  this._stateChangeMessage(message, false);
649
821
  if (message.fields.redelivered) return message.ack();
650
822
  const {
651
823
  id,
652
824
  type,
653
- isEnd
825
+ isParallelGateway
654
826
  } = message.content;
827
+ if (isParallelGateway) {
828
+ for (const inb of message.content.inbound) {
829
+ this._popPostponed(inb)?.ack();
830
+ }
831
+ }
655
832
  const {
656
833
  postponed,
657
- detachedActivities,
658
- startActivities
659
- } = this[kElements];
834
+ detachedActivities
835
+ } = this[K_ELEMENTS];
660
836
  const postponedCount = postponed.size;
661
837
  if (!postponedCount) {
662
838
  this._debug(`left <${id}> (${type}), pending runs ${postponedCount}`);
@@ -664,9 +840,9 @@ ProcessExecution.prototype._onChildCompleted = function onChildCompleted(message
664
840
  return this._complete('completed');
665
841
  }
666
842
  message.ack();
667
- this._debug(`left <${id}> (${type}), pending activities ${postponedCount}`);
843
+ this._debug(`left <${id}> (${type}), pending activities ${postponedCount} ${[...postponed].map(m => m.content.id)}`);
668
844
  if (postponedCount && postponedCount === detachedActivities.size) {
669
- return this[kActivityQ].queueMessage({
845
+ return this[K_ACTIVITY_Q].queueMessage({
670
846
  routingKey: 'execution.discard.detached'
671
847
  }, {
672
848
  id: this.id,
@@ -676,21 +852,9 @@ ProcessExecution.prototype._onChildCompleted = function onChildCompleted(message
676
852
  type: 'cancel'
677
853
  });
678
854
  }
679
- if (isEnd && startActivities.size) {
680
- const startSequences = this[kElements].startSequences;
681
- for (const msg of postponed) {
682
- const postponedId = msg.content.id;
683
- const startSequence = startSequences[postponedId];
684
- if (startSequence) {
685
- if (startSequence.content.sequence.some(({
686
- id: sid
687
- }) => sid === id)) {
688
- this._getChildApi(msg).discard();
689
- }
690
- }
691
- }
692
- }
693
855
  };
856
+
857
+ /** @internal */
694
858
  ProcessExecution.prototype._stopExecution = function stopExecution(message) {
695
859
  const postponedCount = this.postponedCount;
696
860
  this._debug(`stop process execution (stop child executions ${postponedCount})`);
@@ -698,18 +862,20 @@ ProcessExecution.prototype._stopExecution = function stopExecution(message) {
698
862
  for (const api of this.getPostponed()) api.stop();
699
863
  }
700
864
  this._deactivate();
701
- this[kStopped] = true;
865
+ this[_constants.K_STOPPED] = true;
702
866
  return this.broker.publish(this._exchangeName, `execution.stopped.${this.executionId}`, {
703
- ...this[kExecuteMessage].content,
867
+ ...this[_constants.K_EXECUTE_MESSAGE].content,
704
868
  ...(message && message.content)
705
869
  }, {
706
870
  type: 'stopped',
707
871
  persistent: false
708
872
  });
709
873
  };
874
+
875
+ /** @internal */
710
876
  ProcessExecution.prototype._onDiscard = function onDiscard() {
711
877
  this._deactivate();
712
- const postponed = this[kElements].postponed;
878
+ const postponed = this[K_ELEMENTS].postponed;
713
879
  const running = new Set(postponed);
714
880
  postponed.clear();
715
881
  this._debug(`discard process execution (discard child executions ${running.size})`);
@@ -720,17 +886,19 @@ ProcessExecution.prototype._onDiscard = function onDiscard() {
720
886
  for (const flow of this.getAssociations()) flow.stop();
721
887
  for (const msg of running) this._getChildApi(msg).discard();
722
888
  }
723
- this[kActivityQ].purge();
889
+ this[K_ACTIVITY_Q].purge();
724
890
  return this._complete('discard');
725
891
  };
892
+
893
+ /** @internal */
726
894
  ProcessExecution.prototype._onCancel = function onCancel() {
727
- const postponed = this[kElements].postponed;
895
+ const postponed = this[K_ELEMENTS].postponed;
728
896
  const running = new Set(postponed);
729
897
  const isTransaction = this.isTransaction;
730
898
  if (isTransaction) {
731
899
  this._debug(`cancel transaction execution (cancel child executions ${running.size})`);
732
- this[kStatus] = 'cancel';
733
- this.broker.publish('event', 'transaction.cancel', (0, _messageHelper.cloneMessage)(this[kExecuteMessage], {
900
+ this[_constants.K_STATUS] = 'cancel';
901
+ this.broker.publish('event', 'transaction.cancel', (0, _messageHelper.cloneMessage)(this[_constants.K_EXECUTE_MESSAGE], {
734
902
  state: 'cancel'
735
903
  }));
736
904
  for (const msg of running) {
@@ -747,6 +915,8 @@ ProcessExecution.prototype._onCancel = function onCancel() {
747
915
  }
748
916
  }
749
917
  };
918
+
919
+ /** @internal */
750
920
  ProcessExecution.prototype._onApiMessage = function onApiMessage(routingKey, message) {
751
921
  if (message.properties.delegate) {
752
922
  return this._delegateApiMessage(routingKey, message);
@@ -763,7 +933,7 @@ ProcessExecution.prototype._onApiMessage = function onApiMessage(routingKey, mes
763
933
  case 'discard':
764
934
  return this.discard(message);
765
935
  case 'stop':
766
- this[kActivityQ].queueMessage({
936
+ this[K_ACTIVITY_Q].queueMessage({
767
937
  routingKey: 'execution.stop'
768
938
  }, (0, _messageHelper.cloneContent)(message.content), {
769
939
  persistent: false
@@ -771,6 +941,8 @@ ProcessExecution.prototype._onApiMessage = function onApiMessage(routingKey, mes
771
941
  break;
772
942
  }
773
943
  };
944
+
945
+ /** @internal */
774
946
  ProcessExecution.prototype._delegateApiMessage = function delegateApiMessage(routingKey, message, continueOnConsumed) {
775
947
  const correlationId = message.properties.correlationId || (0, _shared.getUniqueId)(this.executionId);
776
948
  this._debug(`delegate api ${routingKey} message to children, with correlationId <${correlationId}>`);
@@ -785,16 +957,18 @@ ProcessExecution.prototype._delegateApiMessage = function delegateApiMessage(rou
785
957
  consumerTag: `_ct-delegate-${correlationId}`,
786
958
  noAck: true
787
959
  });
788
- for (const child of this[kElements].children) {
960
+ for (const child of this[K_ELEMENTS].children) {
789
961
  if (child.placeholder) continue;
790
962
  child.broker.publish('api', routingKey, (0, _messageHelper.cloneContent)(message.content), message.properties);
791
963
  if (consumed && !continueOnConsumed) break;
792
964
  }
793
965
  return broker.cancel(`_ct-delegate-${correlationId}`);
794
966
  };
967
+
968
+ /** @internal */
795
969
  ProcessExecution.prototype._complete = function complete(completionType, content) {
796
970
  this._deactivate();
797
- this[kCompleted] = true;
971
+ this[_constants.K_COMPLETED] = true;
798
972
  const status = this.status;
799
973
  switch (this.status) {
800
974
  case 'cancel':
@@ -806,11 +980,11 @@ ProcessExecution.prototype._complete = function complete(completionType, content
806
980
  break;
807
981
  default:
808
982
  this._debug(`process execution ${completionType}`);
809
- this[kStatus] = completionType;
983
+ this[_constants.K_STATUS] = completionType;
810
984
  }
811
985
  const broker = this.broker;
812
- this[kActivityQ].delete();
813
- return broker.publish(this._exchangeName, `execution.${completionType}.${this.executionId}`, (0, _messageHelper.cloneContent)(this[kExecuteMessage].content, {
986
+ this[K_ACTIVITY_Q].delete();
987
+ broker.publish(this._exchangeName, `execution.${completionType}.${this.executionId}`, (0, _messageHelper.cloneContent)(this[_constants.K_EXECUTE_MESSAGE].content, {
814
988
  output: {
815
989
  ...this.environment.output
816
990
  },
@@ -821,10 +995,12 @@ ProcessExecution.prototype._complete = function complete(completionType, content
821
995
  mandatory: completionType === 'error'
822
996
  });
823
997
  };
998
+
999
+ /** @internal */
824
1000
  ProcessExecution.prototype._terminate = function terminate(message) {
825
- this[kStatus] = 'terminated';
1001
+ this[_constants.K_STATUS] = 'terminated';
826
1002
  this._debug('terminating process execution');
827
- const postponed = this[kElements].postponed;
1003
+ const postponed = this[K_ELEMENTS].postponed;
828
1004
  const running = new Set(postponed);
829
1005
  postponed.clear();
830
1006
  for (const flow of this.getSequenceFlows()) flow.stop();
@@ -840,20 +1016,66 @@ ProcessExecution.prototype._terminate = function terminate(message) {
840
1016
  this._getChildApi(msg).stop();
841
1017
  msg.ack();
842
1018
  }
843
- this[kActivityQ].purge();
1019
+ this[K_ACTIVITY_Q].purge();
844
1020
  };
1021
+
1022
+ /** @internal */
845
1023
  ProcessExecution.prototype._getFlowById = function getFlowById(flowId) {
846
- return this[kElements].flows.find(f => f.id === flowId);
1024
+ return this[K_ELEMENTS].flows.find(f => f.id === flowId);
847
1025
  };
1026
+
1027
+ /** @internal */
848
1028
  ProcessExecution.prototype._getAssociationById = function getAssociationById(associationId) {
849
- return this[kElements].associations.find(a => a.id === associationId);
1029
+ return this[K_ELEMENTS].associations.find(a => a.id === associationId);
850
1030
  };
1031
+
1032
+ /** @internal */
851
1033
  ProcessExecution.prototype._getMessageFlowById = function getMessageFlowById(flowId) {
852
- return this[kElements].outboundMessageFlows.find(f => f.id === flowId);
1034
+ return this[K_ELEMENTS].outboundMessageFlows.find(f => f.id === flowId);
853
1035
  };
1036
+
1037
+ /** @internal */
854
1038
  ProcessExecution.prototype._getChildById = function getChildById(childId) {
855
1039
  return this.getActivityById(childId) || this._getFlowById(childId);
856
1040
  };
1041
+
1042
+ /**
1043
+ * Discard the other armed start events once one mutually exclusive entry point wins.
1044
+ * Resolves the start-event flag from the live activity so recovered pre-flag state is handled.
1045
+ * @internal
1046
+ */
1047
+ ProcessExecution.prototype._discardArmedStartEvents = function discardArmedStartEvents(winnerId) {
1048
+ const elements = this[K_ELEMENTS];
1049
+ const startPeers = [];
1050
+ for (const msg of elements.postponed) {
1051
+ const peerId = msg.content.id;
1052
+ if (peerId === winnerId) continue;
1053
+ if (this.getActivityById(peerId)?.isStartEvent) startPeers.push(msg);
1054
+ }
1055
+ if (!startPeers.length) return;
1056
+ elements.startEventCount = 0;
1057
+ for (const msg of startPeers) this._getChildApi(msg).discard();
1058
+ };
1059
+
1060
+ /**
1061
+ * On resume of a state from an older major, discard start events left armed when another entry
1062
+ * point already won before recovery. The winning start event's `activity.end` cannot replay, so
1063
+ * the live discard trigger never fires.
1064
+ * @internal
1065
+ */
1066
+ ProcessExecution.prototype._reconcileStartEvents = function reconcileStartEvents() {
1067
+ const elements = this[K_ELEMENTS];
1068
+ if (elements.startEventCount <= 1) return;
1069
+ if (!(this[K_RECOVERED_VERSION] < _constants.STATE_VERSION)) return;
1070
+ for (const child of elements.children) {
1071
+ if (child.isStartEvent && child.counters.taken) {
1072
+ this._discardArmedStartEvents();
1073
+ return;
1074
+ }
1075
+ }
1076
+ };
1077
+
1078
+ /** @internal */
857
1079
  ProcessExecution.prototype._getChildApi = function getChildApi(message) {
858
1080
  const content = message.content;
859
1081
  let child = this._getChildById(content.id);
@@ -867,11 +1089,8 @@ ProcessExecution.prototype._getChildApi = function getChildApi(message) {
867
1089
  if (child) return child.getApi(message);
868
1090
  }
869
1091
  };
870
- ProcessExecution.prototype._onShookEnd = function onShookEnd(message) {
871
- const routingKey = message.fields.routingKey;
872
- if (routingKey !== 'activity.shake.end') return;
873
- this[kElements].startSequences[message.content.id] = (0, _messageHelper.cloneMessage)(message);
874
- };
1092
+
1093
+ /** @internal */
875
1094
  ProcessExecution.prototype._debug = function debugMessage(logMessage) {
876
- this[kParent].logger.debug(`<${this.executionId} (${this.id})> ${logMessage}`);
1095
+ this[K_PARENT].logger.debug(`<${this.executionId} (${this.id})> ${logMessage}`);
877
1096
  };