bpmn-elements 17.2.2 → 18.0.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 (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 +458 -254
  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 +21 -0
  20. package/dist/definition/Definition.js +182 -64
  21. package/dist/definition/DefinitionExecution.js +195 -82
  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 +2 -2
  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 +174 -76
  62. package/dist/process/ProcessExecution.js +362 -177
  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 +388 -231
  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 +15 -0
  95. package/src/definition/Definition.js +157 -62
  96. package/src/definition/DefinitionExecution.js +161 -83
  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 +2 -2
  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 +154 -72
  137. package/src/process/ProcessExecution.js +326 -175
  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 +2614 -84
  154. package/types/interfaces.d.ts +636 -0
  155. package/types/types.d.ts +0 -765
@@ -1,49 +1,57 @@
1
1
  import { ActivityApi } from '../Api.js';
2
2
  import { cloneContent, cloneMessage } from '../messageHelper.js';
3
-
4
- const kCompleted = Symbol.for('completed');
5
- const kExecuteQ = Symbol.for('executeQ');
6
- const kExecuteMessage = Symbol.for('executeMessage');
7
- const kMessageHandlers = Symbol.for('messageHandlers');
8
- const kPostponed = Symbol.for('postponed');
9
-
10
- export default ActivityExecution;
11
-
12
- function ActivityExecution(activity, context) {
3
+ import { K_COMPLETED, K_EXECUTE_MESSAGE, K_MESSAGE_HANDLERS } from '../constants.js';
4
+
5
+ const K_EXECUTE_Q = Symbol.for('executeQ');
6
+ const K_POSTPONED = Symbol.for('postponed');
7
+
8
+ /**
9
+ * Per-run execution orchestrator for an Activity. Instantiates the element-specific behaviour
10
+ * and drives the execute message flow over the activity broker.
11
+ * @param {import('./Activity.js').Activity} activity
12
+ * @param {import('../Context.js').ContextInstance} context
13
+ */
14
+ export function ActivityExecution(activity, context) {
13
15
  this.activity = activity;
14
16
  this.context = context;
15
17
  this.id = activity.id;
16
18
  this.broker = activity.broker;
17
- this[kPostponed] = new Set();
18
- this[kCompleted] = false;
19
- this[kExecuteQ] = this.broker.assertQueue('execute-q', { durable: true, autoDelete: false });
19
+ this[K_POSTPONED] = new Set();
20
+ this[K_COMPLETED] = false;
21
+ this[K_EXECUTE_Q] = this.broker.assertQueue('execute-q', { durable: true, autoDelete: false });
20
22
 
21
- this[kMessageHandlers] = {
23
+ this[K_MESSAGE_HANDLERS] = {
22
24
  onParentApiMessage: this._onParentApiMessage.bind(this),
23
25
  onExecuteMessage: this._onExecuteMessage.bind(this),
24
26
  };
25
27
  }
26
28
 
27
29
  Object.defineProperty(ActivityExecution.prototype, 'completed', {
30
+ /** @returns {boolean} */
28
31
  get() {
29
- return this[kCompleted];
32
+ return this[K_COMPLETED];
30
33
  },
31
34
  });
32
35
 
36
+ /**
37
+ * Begin executing the activity behaviour. Resumes if the message is redelivered.
38
+ * @param {import('#types').ElementBrokerMessage} executeMessage
39
+ * @throws {Error} when message or executionId is missing
40
+ */
33
41
  ActivityExecution.prototype.execute = function execute(executeMessage) {
34
42
  if (!executeMessage) throw new Error('Execution requires message');
35
43
  const executionId = executeMessage.content?.executionId;
36
44
  if (!executionId) throw new Error('Execution requires execution id');
37
45
 
38
46
  this.executionId = executionId;
39
- const initMessage = (this[kExecuteMessage] = cloneMessage(executeMessage, {
47
+ const initMessage = (this[K_EXECUTE_MESSAGE] = cloneMessage(executeMessage, {
40
48
  executionId,
41
49
  state: 'start',
42
50
  isRootScope: true,
43
51
  }));
44
52
 
45
53
  if (executeMessage.fields.redelivered) {
46
- this[kPostponed].clear();
54
+ this[K_POSTPONED].clear();
47
55
  this._debug('resume execution');
48
56
 
49
57
  if (!this.source) this.source = new this.activity.Behaviour(this.activity, this.context);
@@ -58,22 +66,25 @@ ActivityExecution.prototype.execute = function execute(executeMessage) {
58
66
  this.broker.publish('execution', 'execute.start', cloneContent(initMessage.content));
59
67
  };
60
68
 
69
+ /**
70
+ * Bind the execute queue and start consuming execute and api messages.
71
+ */
61
72
  ActivityExecution.prototype.activate = function activate() {
62
- if (this[kCompleted]) return;
73
+ if (this[K_COMPLETED]) return;
63
74
 
64
75
  const broker = this.broker;
65
76
  const batchSize = this.activity.environment.settings.batchSize || 50;
66
77
  broker.bindQueue('execute-q', 'execution', 'execute.#', { priority: 100 });
67
78
 
68
- const { onExecuteMessage, onParentApiMessage } = this[kMessageHandlers];
69
- this[kExecuteQ].assertConsumer(onExecuteMessage, {
79
+ const { onExecuteMessage, onParentApiMessage } = this[K_MESSAGE_HANDLERS];
80
+ this[K_EXECUTE_Q].assertConsumer(onExecuteMessage, {
70
81
  exclusive: true,
71
82
  prefetch: batchSize * 2,
72
83
  priority: 100,
73
84
  consumerTag: '_activity-execute',
74
85
  });
75
86
 
76
- if (this[kCompleted]) return this.deactivate();
87
+ if (this[K_COMPLETED]) return this.deactivate();
77
88
 
78
89
  broker.subscribeTmp('api', `activity.*.${this.executionId}`, onParentApiMessage, {
79
90
  noAck: true,
@@ -82,6 +93,9 @@ ActivityExecution.prototype.activate = function activate() {
82
93
  });
83
94
  };
84
95
 
96
+ /**
97
+ * Cancel execute and api consumers and unbind the execute queue.
98
+ */
85
99
  ActivityExecution.prototype.deactivate = function deactivate() {
86
100
  const broker = this.broker;
87
101
  broker.cancel('_activity-api-execution');
@@ -89,16 +103,24 @@ ActivityExecution.prototype.deactivate = function deactivate() {
89
103
  broker.unbindQueue('execute-q', 'execution', 'execute.#');
90
104
  };
91
105
 
106
+ /**
107
+ * Discard the running execution.
108
+ */
92
109
  ActivityExecution.prototype.discard = function discard() {
93
- if (this[kCompleted]) return;
94
- const initMessage = this[kExecuteMessage];
110
+ if (this[K_COMPLETED]) return;
111
+ const initMessage = this[K_EXECUTE_MESSAGE];
95
112
  if (!initMessage) return this.activity.logger.warn(`<${this.id}> is not executing`);
96
113
  this.getApi(initMessage).discard();
97
114
  };
98
115
 
116
+ /**
117
+ * Resolve an Api wrapper, preferring a behaviour-specific Api when the source exposes one.
118
+ * @param {import('#types').ElementBrokerMessage} [apiMessage]
119
+ * @returns {import('#types').IApi<import('./Activity.js').Activity>}
120
+ */
99
121
  ActivityExecution.prototype.getApi = function getApi(apiMessage) {
100
122
  const self = this;
101
- if (!apiMessage) apiMessage = this[kExecuteMessage];
123
+ if (!apiMessage) apiMessage = this[K_EXECUTE_MESSAGE];
102
124
 
103
125
  if (self.source.getApi) {
104
126
  const sourceApi = self.source.getApi(apiMessage);
@@ -109,7 +131,7 @@ ActivityExecution.prototype.getApi = function getApi(apiMessage) {
109
131
 
110
132
  api.getExecuting = function getExecuting() {
111
133
  const result = [];
112
- for (const msg of self[kPostponed]) {
134
+ for (const msg of self[K_POSTPONED]) {
113
135
  if (msg.content.executionId === apiMessage.content.executionId) continue;
114
136
  result.push(self.getApi(msg));
115
137
  }
@@ -119,14 +141,22 @@ ActivityExecution.prototype.getApi = function getApi(apiMessage) {
119
141
  return api;
120
142
  };
121
143
 
144
+ /**
145
+ * Pass an execute message straight to the behaviour, executing first if no source is set up yet.
146
+ * @param {import('#types').ElementBrokerMessage} executeMessage
147
+ * @returns {void}
148
+ */
122
149
  ActivityExecution.prototype.passthrough = function passthrough(executeMessage) {
123
150
  if (!this.source) return this.execute(executeMessage);
124
151
  return this._sourceExecute(executeMessage);
125
152
  };
126
153
 
154
+ /**
155
+ * List currently postponed executions as Api wrappers, including those from sub-process behaviours.
156
+ */
127
157
  ActivityExecution.prototype.getPostponed = function getPostponed() {
128
158
  let apis = [];
129
- for (const msg of this[kPostponed]) {
159
+ for (const msg of this[K_POSTPONED]) {
130
160
  apis.push(this.getApi(msg));
131
161
  }
132
162
  if (!this.activity.isSubProcess || !this.source) return apis;
@@ -134,19 +164,28 @@ ActivityExecution.prototype.getPostponed = function getPostponed() {
134
164
  return apis;
135
165
  };
136
166
 
167
+ /**
168
+ * Snapshot execution state, merging behaviour-specific state when the source provides it.
169
+ * @returns {import('#types').ActivityExecutionState}
170
+ */
137
171
  ActivityExecution.prototype.getState = function getState() {
138
- const result = { completed: this[kCompleted] };
172
+ const result = { completed: this[K_COMPLETED] };
139
173
  const source = this.source;
140
174
 
141
175
  if (!source || !source.getState) return result;
142
176
  return { ...result, ...source.getState() };
143
177
  };
144
178
 
179
+ /**
180
+ * Restore execution state captured by getState.
181
+ * @param {import('#types').ActivityExecutionState} [state]
182
+ * @returns {this}
183
+ */
145
184
  ActivityExecution.prototype.recover = function recover(state) {
146
- this[kPostponed].clear();
185
+ this[K_POSTPONED].clear();
147
186
 
148
187
  if (!state) return this;
149
- if ('completed' in state) this[kCompleted] = state.completed;
188
+ if ('completed' in state) this[K_COMPLETED] = state.completed;
150
189
 
151
190
  const source = (this.source = new this.activity.Behaviour(this.activity, this.context));
152
191
  if (source.recover) {
@@ -156,12 +195,16 @@ ActivityExecution.prototype.recover = function recover(state) {
156
195
  return this;
157
196
  };
158
197
 
198
+ /**
199
+ * Stop the execution via the activity api.
200
+ */
159
201
  ActivityExecution.prototype.stop = function stop() {
160
- const executeMessage = this[kExecuteMessage];
202
+ const executeMessage = this[K_EXECUTE_MESSAGE];
161
203
  if (!executeMessage) return;
162
204
  this.getApi(executeMessage).stop();
163
205
  };
164
206
 
207
+ /** @internal */
165
208
  ActivityExecution.prototype._sourceExecute = function sourceExecute(executeMessage) {
166
209
  try {
167
210
  return this.source.execute(executeMessage);
@@ -170,6 +213,7 @@ ActivityExecution.prototype._sourceExecute = function sourceExecute(executeMessa
170
213
  }
171
214
  };
172
215
 
216
+ /** @internal */
173
217
  ActivityExecution.prototype._onExecuteMessage = function onExecuteMessage(routingKey, message) {
174
218
  const { fields, content, properties } = message;
175
219
  const isRedelivered = fields.redelivered;
@@ -178,7 +222,7 @@ ActivityExecution.prototype._onExecuteMessage = function onExecuteMessage(routin
178
222
 
179
223
  switch (routingKey) {
180
224
  case 'execute.resume.execution': {
181
- if (!this[kPostponed].size) return this.broker.publish('execution', 'execute.start', cloneContent(this[kExecuteMessage].content));
225
+ if (!this[K_POSTPONED].size) return this.broker.publish('execution', 'execute.start', cloneContent(this[K_EXECUTE_MESSAGE].content));
182
226
  break;
183
227
  }
184
228
  case 'execute.cancel':
@@ -216,9 +260,10 @@ ActivityExecution.prototype._onExecuteMessage = function onExecuteMessage(routin
216
260
  }
217
261
  };
218
262
 
263
+ /** @internal */
219
264
  ActivityExecution.prototype._onStateChangeMessage = function onStateChangeMessage(message) {
220
265
  const { ignoreIfExecuting, executionId } = message.content;
221
- const postponed = this[kPostponed];
266
+ const postponed = this[K_POSTPONED];
222
267
 
223
268
  let previousMsg;
224
269
  for (const msg of postponed) {
@@ -242,14 +287,15 @@ ActivityExecution.prototype._onStateChangeMessage = function onStateChangeMessag
242
287
  }
243
288
  };
244
289
 
290
+ /** @internal */
245
291
  ActivityExecution.prototype._onExecutionCompleted = function onExecutionCompleted(message) {
246
292
  const postponedMsg = this._ackPostponed(message);
247
293
  if (!postponedMsg) return;
248
- const postponed = this[kPostponed];
294
+ const postponed = this[K_POSTPONED];
249
295
 
250
296
  const { executionId, keep, isRootScope } = message.content;
251
297
  if (!isRootScope) {
252
- this._debug('completed sub execution');
298
+ this._debug('completed sub execution', executionId);
253
299
  if (!keep) message.ack();
254
300
  if (postponed.size === 1) {
255
301
  const onlyMessage = postponed.values().next().value;
@@ -261,7 +307,7 @@ ActivityExecution.prototype._onExecutionCompleted = function onExecutionComplete
261
307
  }
262
308
 
263
309
  this._debug('completed execution', executionId);
264
- this[kCompleted] = true;
310
+ this[K_COMPLETED] = true;
265
311
 
266
312
  message.ack(true);
267
313
 
@@ -274,12 +320,13 @@ ActivityExecution.prototype._onExecutionCompleted = function onExecutionComplete
274
320
  this._publishExecutionCompleted('completed', { ...postponedMsg.content, ...message.content }, message.properties.correlationId);
275
321
  };
276
322
 
323
+ /** @internal */
277
324
  ActivityExecution.prototype._onExecutionDiscarded = function onExecutionDiscarded(discardType, message) {
278
325
  const postponedMsg = this._ackPostponed(message);
279
326
  const { isRootScope, error } = message.content;
280
327
  if (!isRootScope && !postponedMsg) return;
281
328
 
282
- const postponed = this[kPostponed];
329
+ const postponed = this[K_POSTPONED];
283
330
  const correlationId = message.properties.correlationId;
284
331
  if (!error && !isRootScope) {
285
332
  message.ack();
@@ -303,12 +350,13 @@ ActivityExecution.prototype._onExecutionDiscarded = function onExecutionDiscarde
303
350
  this._publishExecutionCompleted(discardType, cloneContent(message.content), correlationId);
304
351
  };
305
352
 
353
+ /** @internal */
306
354
  ActivityExecution.prototype._publishExecutionCompleted = function publishExecutionCompleted(
307
355
  completionType,
308
356
  completeContent,
309
357
  correlationId
310
358
  ) {
311
- this[kCompleted] = true;
359
+ this[K_COMPLETED] = true;
312
360
 
313
361
  this.broker.publish(
314
362
  'execution',
@@ -321,10 +369,11 @@ ActivityExecution.prototype._publishExecutionCompleted = function publishExecuti
321
369
  );
322
370
  };
323
371
 
372
+ /** @internal */
324
373
  ActivityExecution.prototype._ackPostponed = function ackPostponed(completeMessage) {
325
374
  const { executionId: eid } = completeMessage.content;
326
375
 
327
- const postponed = this[kPostponed];
376
+ const postponed = this[K_POSTPONED];
328
377
  for (const msg of postponed) {
329
378
  if (msg.content.executionId === eid) {
330
379
  postponed.delete(msg);
@@ -334,18 +383,20 @@ ActivityExecution.prototype._ackPostponed = function ackPostponed(completeMessag
334
383
  }
335
384
  };
336
385
 
386
+ /** @internal */
337
387
  ActivityExecution.prototype._onParentApiMessage = function onParentApiMessage(routingKey, message) {
338
388
  switch (message.properties.type) {
339
389
  case 'error':
340
- return this[kExecuteQ].queueMessage({ routingKey: 'execute.error' }, { error: message.content.error });
390
+ return this[K_EXECUTE_Q].queueMessage({ routingKey: 'execute.error' }, { error: message.content.error });
341
391
  case 'discard':
342
- return this[kExecuteQ].queueMessage({ routingKey: 'execute.discard' }, cloneContent(this[kExecuteMessage].content));
392
+ return this[K_EXECUTE_Q].queueMessage({ routingKey: 'execute.discard' }, cloneContent(this[K_EXECUTE_MESSAGE].content));
343
393
  case 'stop': {
344
394
  return this._onStop(message);
345
395
  }
346
396
  }
347
397
  };
348
398
 
399
+ /** @internal */
349
400
  ActivityExecution.prototype._onStop = function onStop(message) {
350
401
  const stoppedId = message?.content?.executionId;
351
402
  const running = this.getPostponed();
@@ -359,15 +410,15 @@ ActivityExecution.prototype._onStop = function onStop(message) {
359
410
  this.broker.cancel('_activity-api-execution');
360
411
  };
361
412
 
413
+ /** @internal */
362
414
  ActivityExecution.prototype._debug = function debug(logMessage, executionId) {
363
415
  executionId = executionId || this.executionId;
364
416
  this.activity.logger.debug(`<${executionId} (${this.id})> ${logMessage}`);
365
417
  };
366
418
 
367
419
  function getExecuteMessage(message) {
368
- const result = cloneMessage(message, {
420
+ return cloneMessage(message, {
369
421
  ...(message.fields.redelivered && { isRecovered: true }),
370
422
  ignoreIfExecuting: undefined,
371
423
  });
372
- return result;
373
424
  }
@@ -1,6 +1,11 @@
1
1
  import { cloneParent } from '../messageHelper.js';
2
2
 
3
- export default function DummyActivity(activityDef) {
3
+ /**
4
+ * Placeholder activity for non-executable elements (text annotations, groups, categories).
5
+ * @param {import('moddle-context-serializer').Activity} activityDef
6
+ * @returns {{ id: string, type: string, name: string | undefined, behaviour: Record<string, any>, parent: import('#types').ElementParent, placeholder: true }}
7
+ */
8
+ export function DummyActivity(activityDef) {
4
9
  const { id, type = 'dummy', name, parent, behaviour } = activityDef;
5
10
  return {
6
11
  id,
@@ -1,23 +1,30 @@
1
- export default function Escalation(signalDef, context) {
2
- const { id, type, name, parent: originalParent } = signalDef;
3
- const { environment } = context;
4
- const parent = { ...originalParent };
1
+ /**
2
+ * Escalation reference element. Resolves the escalation name expression against the execution message.
3
+ * @param {import('moddle-context-serializer').SerializableElement} escalationDef
4
+ * @param {import('#types').ContextInstance} context
5
+ */
6
+ export function Escalation(escalationDef, context) {
7
+ if (!(this instanceof Escalation)) return new Escalation(escalationDef, context);
8
+ const { id, type, name, parent } = escalationDef;
9
+ this.id = id;
10
+ this.type = type;
11
+ this.name = name;
12
+ /** @type {import('#types').ElementParent} */
13
+ this.parent = { ...parent };
14
+ this.environment = context.environment;
15
+ }
5
16
 
17
+ /**
18
+ * Resolve escalation reference for the given execution message.
19
+ * @param {import('#types').ElementBrokerMessage} executionMessage
20
+ */
21
+ Escalation.prototype.resolve = function resolve(executionMessage) {
22
+ const { id, type, name, parent } = this;
6
23
  return {
7
24
  id,
8
25
  type,
9
- name,
10
- parent,
11
- resolve,
26
+ messageType: 'escalation',
27
+ name: name && this.environment.resolveExpression(name, executionMessage),
28
+ parent: { ...parent },
12
29
  };
13
-
14
- function resolve(executionMessage) {
15
- return {
16
- id,
17
- type,
18
- messageType: 'escalation',
19
- name: name && environment.resolveExpression(name, executionMessage),
20
- parent: { ...parent },
21
- };
22
- }
23
- }
30
+ };
@@ -1,7 +1,7 @@
1
1
  import { cloneMessage } from '../messageHelper.js';
2
2
  import { ActivityError, BpmnError } from '../error/Errors.js';
3
3
 
4
- export default function ExecutionScope(activity, initMessage) {
4
+ export function ExecutionScope(activity, initMessage) {
5
5
  const { id, type, environment, logger } = activity;
6
6
 
7
7
  const { fields, content, properties } = cloneMessage(initMessage);
@@ -1,23 +1,30 @@
1
- export default function Message(messageDef, context) {
2
- const { id, type, name, parent: originalParent } = messageDef;
3
- const { environment } = context;
4
- const parent = { ...originalParent };
1
+ /**
2
+ * Message reference element. Resolves the message name expression against the execution message.
3
+ * @param {import('moddle-context-serializer').SerializableElement} messageDef
4
+ * @param {import('#types').ContextInstance} context
5
+ */
6
+ export function Message(messageDef, context) {
7
+ if (!(this instanceof Message)) return new Message(messageDef, context);
8
+ const { id, type, name, parent } = messageDef;
9
+ this.id = id;
10
+ this.type = type;
11
+ this.name = name;
12
+ /** @type {import('#types').ElementParent} */
13
+ this.parent = { ...parent };
14
+ this.environment = context.environment;
15
+ }
5
16
 
17
+ /**
18
+ * Resolve message reference for the given execution message.
19
+ * @param {import('#types').ElementBrokerMessage} executionMessage
20
+ */
21
+ Message.prototype.resolve = function resolve(executionMessage) {
22
+ const { id, type, name, parent } = this;
6
23
  return {
7
24
  id,
8
25
  type,
9
- name,
10
- parent,
11
- resolve,
26
+ messageType: 'message',
27
+ ...(name && { name: this.environment.resolveExpression(name, executionMessage) }),
28
+ parent: { ...parent },
12
29
  };
13
-
14
- function resolve(executionMessage) {
15
- return {
16
- id,
17
- type,
18
- messageType: 'message',
19
- ...(name && { name: environment.resolveExpression(name, executionMessage) }),
20
- parent: { ...parent },
21
- };
22
- }
23
- }
30
+ };
@@ -1,23 +1,30 @@
1
- export default function Signal(signalDef, context) {
2
- const { id, type = 'Signal', name, parent: originalParent } = signalDef;
3
- const { environment } = context;
4
- const parent = { ...originalParent };
1
+ /**
2
+ * Signal reference element. Resolves the signal name expression against the execution message.
3
+ * @param {import('moddle-context-serializer').SerializableElement} signalDef
4
+ * @param {import('#types').ContextInstance} context
5
+ */
6
+ export function Signal(signalDef, context) {
7
+ if (!(this instanceof Signal)) return new Signal(signalDef, context);
8
+ const { id, type = 'Signal', name, parent } = signalDef;
9
+ this.id = id;
10
+ this.type = type;
11
+ this.name = name;
12
+ /** @type {import('#types').ElementParent} */
13
+ this.parent = { ...parent };
14
+ this.environment = context.environment;
15
+ }
5
16
 
17
+ /**
18
+ * Resolve signal reference for the given execution message.
19
+ * @param {import('#types').ElementBrokerMessage} executionMessage
20
+ */
21
+ Signal.prototype.resolve = function resolve(executionMessage) {
22
+ const { id, type, name, parent } = this;
6
23
  return {
7
24
  id,
8
25
  type,
9
- name,
10
- parent,
11
- resolve,
26
+ messageType: 'signal',
27
+ ...(name && { name: this.environment.resolveExpression(name, executionMessage) }),
28
+ parent: { ...parent },
12
29
  };
13
-
14
- function resolve(executionMessage) {
15
- return {
16
- id,
17
- type,
18
- messageType: 'signal',
19
- ...(name && { name: environment.resolveExpression(name, executionMessage) }),
20
- parent: { ...parent },
21
- };
22
- }
23
- }
30
+ };
@@ -99,7 +99,7 @@ OutboundEvaluator.prototype.completed = function completed(err) {
99
99
 
100
100
  if (err) return callback(err);
101
101
 
102
- if (!takenCount && this.outboundFlows.length) {
102
+ if (!takenCount && this.outboundFlows.length && fromMessage.content.requireOutbound) {
103
103
  const nonTakenError = new ActivityError(`<${this.activity.id}> no conditional flow taken`, fromMessage);
104
104
  return callback(nonTakenError);
105
105
  }
package/src/condition.js CHANGED
@@ -1,8 +1,7 @@
1
- import ExecutionScope from './activity/ExecutionScope.js';
2
-
1
+ import { ExecutionScope } from './activity/ExecutionScope.js';
3
2
  /**
4
3
  * Script condition
5
- * @param {import('types').ElementBase} owner
4
+ * @param {import('#types').ElementBase} owner
6
5
  * @param {any} script
7
6
  * @param {string} language
8
7
  */
@@ -31,7 +30,7 @@ ScriptCondition.prototype.execute = function execute(message, callback) {
31
30
 
32
31
  /**
33
32
  * Expression condition
34
- * @param {import('types').ElementBase} owner
33
+ * @param {import('#types').ElementBase} owner
35
34
  * @param {string} expression
36
35
  */
37
36
  export function ExpressionCondition(owner, expression) {
@@ -42,13 +41,20 @@ export function ExpressionCondition(owner, expression) {
42
41
 
43
42
  /**
44
43
  * Execute
45
- * @param {any} message
44
+ * @param {import('#types').ElementBrokerMessage} message
46
45
  * @param {CallableFunction} callback
47
46
  */
48
47
  ExpressionCondition.prototype.execute = function execute(message, callback) {
49
48
  const owner = this._owner;
50
49
  try {
51
50
  const result = owner.environment.resolveExpression(this.expression, message);
51
+ if (typeof result === 'function') {
52
+ const scope = ExecutionScope(owner, message);
53
+ if (callback && result.length > 1) return result.call(owner, scope, callback);
54
+ const conditionResult = result.call(owner, scope);
55
+ if (callback) return callback(null, conditionResult);
56
+ return conditionResult;
57
+ }
52
58
  if (callback) return callback(null, result);
53
59
  return result;
54
60
  } catch (err) {
@@ -0,0 +1,15 @@
1
+ export const K_ACTIVATED = Symbol.for('activated');
2
+ export const K_COMPLETED = Symbol.for('completed');
3
+ export const K_CONSUMING = Symbol.for('consuming');
4
+ export const K_COUNTERS = Symbol.for('counters');
5
+ export const K_EXECUTE_MESSAGE = Symbol.for('executeMessage');
6
+ export const K_EXECUTION = Symbol.for('execution');
7
+ export const K_EXTENSIONS = Symbol.for('extensions');
8
+ export const K_MESSAGE_HANDLERS = Symbol.for('messageHandlers');
9
+ export const K_MESSAGE_Q = Symbol.for('messageQ');
10
+ export const K_REFERENCE_ELEMENT = Symbol.for('referenceElement');
11
+ export const K_REFERENCE_INFO = Symbol.for('referenceInfo');
12
+ export const K_STATE_MESSAGE = Symbol.for('stateMessage');
13
+ export const K_STATUS = Symbol.for('status');
14
+ export const K_STOPPED = Symbol.for('stopped');
15
+ export const K_TARGETS = Symbol.for('targets');