bpmn-elements 17.3.0 → 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 +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 +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 +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 +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 +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 +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 +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 +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
@@ -3,8 +3,8 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
7
- var _ActivityExecution = _interopRequireDefault(require("./ActivityExecution.js"));
6
+ exports.Activity = Activity;
7
+ var _ActivityExecution = require("./ActivityExecution.js");
8
8
  var _shared = require("../shared.js");
9
9
  var _Api = require("../Api.js");
10
10
  var _EventBroker = require("../EventBroker.js");
@@ -12,22 +12,21 @@ var _MessageFormatter = require("../MessageFormatter.js");
12
12
  var _messageHelper = require("../messageHelper.js");
13
13
  var _Errors = require("../error/Errors.js");
14
14
  var _outboundEvaluator = require("./outbound-evaluator.js");
15
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
- const kActivityDef = Symbol.for('activityDefinition');
17
- const kConsuming = Symbol.for('consuming');
18
- const kConsumingRunQ = Symbol.for('run queue consumer');
19
- const kCounters = Symbol.for('counters');
20
- const kEventDefinitions = Symbol.for('eventDefinitions');
21
- const kExec = Symbol.for('exec');
22
- const kExecuteMessage = Symbol.for('executeMessage');
23
- const kExtensions = Symbol.for('extensions');
24
- const kFlags = Symbol.for('flags');
25
- const kFlows = Symbol.for('flows');
26
- const kFormatter = Symbol.for('formatter');
27
- const kMessageHandlers = Symbol.for('messageHandlers');
28
- const kStateMessage = Symbol.for('stateMessage');
29
- const kActivated = Symbol.for('activated');
30
- var _default = exports.default = Activity;
15
+ var _constants = require("../constants.js");
16
+ const K_ACTIVITY_DEF = Symbol.for('activityDefinition');
17
+ const K_CONSUMING_RUN_Q = Symbol.for('run queue consumer');
18
+ const K_EVENT_DEFINITIONS = Symbol.for('eventDefinitions');
19
+ const K_EXEC = Symbol.for('exec');
20
+ const K_FLAGS = Symbol.for('flags');
21
+ const K_FLOWS = Symbol.for('flows');
22
+ const K_FORMATTER = Symbol.for('formatter');
23
+
24
+ /**
25
+ * Activity wraps any element (task, event, gateway) and orchestrates its lifecycle through the broker.
26
+ * @param {import('#types').IActivityBehaviour} Behaviour Element-specific behaviour constructor invoked per execution
27
+ * @param {import('moddle-context-serializer').Activity} activityDef Parsed BPMN element definition
28
+ * @param {import('#types').ContextInstance} context Per-execution registry and factory
29
+ */
31
30
  function Activity(Behaviour, activityDef, context) {
32
31
  const {
33
32
  id,
@@ -39,20 +38,29 @@ function Activity(Behaviour, activityDef, context) {
39
38
  attachedTo: attachedToRef,
40
39
  eventDefinitions
41
40
  } = behaviour;
42
- this[kActivityDef] = activityDef;
41
+ this[K_ACTIVITY_DEF] = activityDef;
43
42
  this.id = id;
44
43
  this.type = type;
45
44
  this.name = name;
45
+ /** @type {import('moddle-context-serializer').ActivityBehaviour} */
46
46
  this.behaviour = {
47
47
  ...behaviour,
48
- eventDefinitions
48
+ eventDefinitions,
49
+ ...(activityDef.linkNames && {
50
+ linkNames: activityDef.linkNames,
51
+ linkBehaviour: activityDef.linkBehaviour
52
+ })
49
53
  };
50
54
  this.Behaviour = Behaviour;
55
+ /** @type {import('moddle-context-serializer').Parent} */
51
56
  this.parent = activityDef.parent ? (0, _messageHelper.cloneParent)(activityDef.parent) : {};
57
+ /** @type {import('#types').ILogger} */
52
58
  this.logger = context.environment.Logger(type.toLowerCase());
53
59
  this.environment = context.environment;
54
60
  this.context = context;
55
- this[kCounters] = {
61
+ /** @type {import('#types').ActivityStatus | undefined} */
62
+ this.status = undefined;
63
+ this[_constants.K_COUNTERS] = {
56
64
  taken: 0,
57
65
  discarded: 0
58
66
  };
@@ -76,156 +84,173 @@ function Activity(Behaviour, activityDef, context) {
76
84
  this.emitFatal = emitFatal;
77
85
  const inboundSequenceFlows = context.getInboundSequenceFlows(id);
78
86
  const inboundAssociations = context.getInboundAssociations(id);
79
- let inboundTriggers;
80
- if (attachedToActivity) {
81
- inboundTriggers = [attachedToActivity];
82
- } else if (isForCompensation) {
83
- inboundTriggers = inboundAssociations.slice();
84
- } else {
85
- inboundTriggers = inboundSequenceFlows.slice();
86
- }
87
+ const hasInboundTrigger = attachedToActivity ? true : isForCompensation ? !!inboundAssociations.length : !!inboundSequenceFlows.length;
87
88
  const outboundSequenceFlows = context.getOutboundSequenceFlows(id);
88
- const isParallelJoin = activityDef.isParallelGateway && inboundSequenceFlows.length > 1;
89
- this[kFlows] = {
89
+ const inboundSourceIds = new Set(inboundSequenceFlows.map(({
90
+ sourceId
91
+ }) => sourceId));
92
+ const isParallelJoin = activityDef.isParallelGateway && inboundSourceIds.size > 1;
93
+ this[K_FLOWS] = {
90
94
  inboundSequenceFlows,
91
95
  inboundAssociations,
92
- inboundTriggers,
96
+ inboundTriggers: undefined,
93
97
  outboundSequenceFlows,
94
- outboundEvaluator: new _outboundEvaluator.OutboundEvaluator(this, outboundSequenceFlows),
95
- ...(isParallelJoin && {
96
- inboundJoinFlows: new Set(),
97
- inboundSourceIds: new Set(inboundSequenceFlows.map(({
98
- sourceId
99
- }) => sourceId))
100
- })
98
+ outboundEvaluator: new _outboundEvaluator.OutboundEvaluator(this, outboundSequenceFlows)
101
99
  };
102
- this[kFlags] = {
100
+ this[K_FLAGS] = {
103
101
  isEnd: !outboundSequenceFlows.length,
104
- isStart: !inboundTriggers.length && !behaviour.triggeredByEvent,
102
+ isStart: !hasInboundTrigger && !behaviour.triggeredByEvent && !activityDef.isCatching,
105
103
  isSubProcess: activityDef.isSubProcess,
106
104
  isMultiInstance: !!behaviour.loopCharacteristics,
107
105
  isForCompensation,
108
106
  attachedTo,
109
107
  isTransaction: activityDef.isTransaction,
110
108
  isParallelJoin,
109
+ isParallelGateway: activityDef.isParallelGateway,
110
+ isStartEvent: !!activityDef.isStartEvent,
111
111
  isThrowing: activityDef.isThrowing,
112
+ linkNames: activityDef.linkNames,
113
+ linkBehaviour: activityDef.linkBehaviour,
114
+ isCatching: activityDef.isCatching,
112
115
  lane: activityDef.lane?.id
113
116
  };
114
- this[kExec] = new Map();
115
- this[kMessageHandlers] = {
116
- onInbound: isParallelJoin ? this._onJoinInbound.bind(this) : this._onInbound.bind(this),
117
+ this[K_EXEC] = new Map();
118
+ this[_constants.K_MESSAGE_HANDLERS] = {
119
+ onInbound: this._onInbound.bind(this),
117
120
  onRunMessage: this._onRunMessage.bind(this),
118
121
  onApiMessage: this._onApiMessage.bind(this),
119
122
  onExecutionMessage: this._onExecutionMessage.bind(this)
120
123
  };
121
- this[kEventDefinitions] = eventDefinitions?.map((ed, idx) => new ed.Behaviour(this, ed, context, idx));
122
- this[kExtensions] = context.loadExtensions(this);
123
- this[kConsuming] = false;
124
- this[kConsumingRunQ] = undefined;
124
+
125
+ /** @type {import('#types').EventDefinition[] | undefined} */
126
+ this[K_EVENT_DEFINITIONS] = eventDefinitions?.map((ed, idx) => new ed.Behaviour(this, ed, context, idx));
127
+ this[_constants.K_EXTENSIONS] = context.loadExtensions(this);
128
+ this[_constants.K_CONSUMING] = false;
129
+ this[K_CONSUMING_RUN_Q] = undefined;
125
130
  }
126
131
  Object.defineProperties(Activity.prototype, {
127
132
  counters: {
128
133
  get() {
129
134
  return {
130
- ...this[kCounters]
135
+ ...this[_constants.K_COUNTERS]
131
136
  };
132
137
  }
133
138
  },
134
139
  execution: {
135
140
  get() {
136
- return this[kExec].get('execution');
141
+ return this[K_EXEC].get('execution');
137
142
  }
138
143
  },
139
144
  executionId: {
140
145
  get() {
141
- return this[kExec].get('executionId');
146
+ return this[K_EXEC].get('executionId');
142
147
  }
143
148
  },
144
149
  extensions: {
145
150
  get() {
146
- return this[kExtensions];
151
+ return this[_constants.K_EXTENSIONS];
147
152
  }
148
153
  },
149
154
  bpmnIo: {
150
155
  get() {
151
- const extensions = this[kExtensions];
156
+ const extensions = this[_constants.K_EXTENSIONS];
152
157
  return extensions?.extensions.find(e => e.type === 'bpmnio');
153
158
  }
154
159
  },
155
160
  formatter: {
156
161
  get() {
157
- let formatter = this[kFormatter];
162
+ let formatter = this[K_FORMATTER];
158
163
  if (formatter) return formatter;
159
- formatter = this[kFormatter] = new _MessageFormatter.Formatter(this);
164
+ formatter = this[K_FORMATTER] = new _MessageFormatter.Formatter(this);
160
165
  return formatter;
161
166
  }
162
167
  },
163
168
  isRunning: {
164
169
  get() {
165
- if (!this[kConsuming]) return false;
170
+ if (!this[_constants.K_CONSUMING]) return false;
166
171
  return !!this.status;
167
172
  }
168
173
  },
169
174
  outbound: {
170
175
  get() {
171
- return this[kFlows].outboundSequenceFlows;
176
+ return this[K_FLOWS].outboundSequenceFlows;
172
177
  }
173
178
  },
174
179
  inbound: {
175
180
  get() {
176
- return this[kFlows].inboundSequenceFlows;
181
+ return this[K_FLOWS].inboundSequenceFlows;
177
182
  }
178
183
  },
179
184
  isEnd: {
180
185
  get() {
181
- return this[kFlags].isEnd;
186
+ return this[K_FLAGS].isEnd;
182
187
  }
183
188
  },
184
189
  isStart: {
185
190
  get() {
186
- return this[kFlags].isStart;
191
+ return this[K_FLAGS].isStart;
187
192
  }
188
193
  },
189
194
  isSubProcess: {
190
195
  get() {
191
- return this[kFlags].isSubProcess;
196
+ return this[K_FLAGS].isSubProcess;
192
197
  }
193
198
  },
194
199
  isTransaction: {
195
200
  get() {
196
- return this[kFlags].isTransaction;
201
+ return this[K_FLAGS].isTransaction;
197
202
  }
198
203
  },
199
204
  isMultiInstance: {
200
205
  get() {
201
- return this[kFlags].isMultiInstance;
206
+ return this[K_FLAGS].isMultiInstance;
202
207
  }
203
208
  },
204
209
  isThrowing: {
205
210
  get() {
206
- return this[kFlags].isThrowing;
211
+ return this[K_FLAGS].isThrowing;
212
+ }
213
+ },
214
+ isCatching: {
215
+ get() {
216
+ return this[K_FLAGS].isCatching;
207
217
  }
208
218
  },
209
219
  isForCompensation: {
210
220
  get() {
211
- return this[kFlags].isForCompensation;
221
+ return this[K_FLAGS].isForCompensation;
222
+ }
223
+ },
224
+ isParallelJoin: {
225
+ get() {
226
+ return this[K_FLAGS].isParallelJoin;
227
+ }
228
+ },
229
+ isParallelGateway: {
230
+ get() {
231
+ return this[K_FLAGS].isParallelGateway;
232
+ }
233
+ },
234
+ isStartEvent: {
235
+ get() {
236
+ return this[K_FLAGS].isStartEvent;
212
237
  }
213
238
  },
214
239
  triggeredByEvent: {
215
240
  get() {
216
- return this[kActivityDef].triggeredByEvent;
241
+ return this[K_ACTIVITY_DEF].triggeredByEvent;
217
242
  }
218
243
  },
219
244
  attachedTo: {
220
245
  get() {
221
- const attachedToId = this[kFlags].attachedTo;
246
+ const attachedToId = this[K_FLAGS].attachedTo;
222
247
  if (!attachedToId) return null;
223
248
  return this.getActivityById(attachedToId);
224
249
  }
225
250
  },
226
251
  lane: {
227
252
  get() {
228
- const laneId = this[kFlags].lane;
253
+ const laneId = this[K_FLAGS].lane;
229
254
  if (!laneId) return undefined;
230
255
  const parent = this.parentElement;
231
256
  return parent.getLaneById && parent.getLaneById(laneId);
@@ -233,30 +258,78 @@ Object.defineProperties(Activity.prototype, {
233
258
  },
234
259
  eventDefinitions: {
235
260
  get() {
236
- return this[kEventDefinitions];
261
+ return this[K_EVENT_DEFINITIONS];
237
262
  }
238
263
  },
239
264
  parentElement: {
240
265
  get() {
241
266
  return this.context.getActivityParentById(this.id);
242
267
  }
268
+ },
269
+ initialized: {
270
+ get() {
271
+ return !!this[K_EXEC]?.get('initExecutionId');
272
+ }
243
273
  }
244
274
  });
275
+
276
+ /**
277
+ * Subscribe to inbound flows and start consuming the inbound queue.
278
+ * @returns {void}
279
+ */
245
280
  Activity.prototype.activate = function activate() {
246
- if (this[kActivated]) return;
247
- this[kActivated] = true;
281
+ if (this[_constants.K_ACTIVATED]) return;
282
+ this[_constants.K_ACTIVATED] = true;
248
283
  return this.addInboundListeners() && this._consumeInbound();
249
284
  };
285
+
286
+ /** @internal */
287
+ Activity.prototype._getInboundTriggers = function _getInboundTriggers() {
288
+ const flows = this[K_FLOWS];
289
+ if (flows.inboundTriggers) return flows.inboundTriggers;
290
+ const flags = this[K_FLAGS];
291
+ let triggers;
292
+ if (flags.attachedTo) {
293
+ triggers = [this.context.getActivityById(flags.attachedTo)];
294
+ } else if (flags.isForCompensation) {
295
+ triggers = flows.inboundAssociations.slice();
296
+ } else {
297
+ triggers = flows.inboundSequenceFlows.slice();
298
+ }
299
+ const {
300
+ isCatching,
301
+ linkNames,
302
+ linkBehaviour
303
+ } = flags;
304
+ if (isCatching && linkNames?.length) {
305
+ const known = new Set(triggers.map(t => t.id));
306
+ for (const source of this.context.getActivitiesByEventDefinitionBehaviour(linkBehaviour, linkNames)) {
307
+ if (source.id === this.id || !source.isThrowing || known.has(source.id)) continue;
308
+ triggers.push(source);
309
+ known.add(source.id);
310
+ }
311
+ }
312
+ return flows.inboundTriggers = triggers;
313
+ };
314
+
315
+ /**
316
+ * Cancel inbound subscriptions and any pending run/format consumers.
317
+ */
250
318
  Activity.prototype.deactivate = function deactivate() {
251
- this[kActivated] = false;
319
+ this[_constants.K_ACTIVATED] = false;
252
320
  const broker = this.broker;
253
321
  this.removeInboundListeners();
254
322
  broker.cancel('_run-on-inbound');
255
323
  broker.cancel('_format-consumer');
256
324
  };
325
+
326
+ /**
327
+ * Initialise activity executionId and emit init event without starting the run.
328
+ * @param {Record<string, any>} [initContent] Optional content merged into the init message
329
+ */
257
330
  Activity.prototype.init = function init(initContent) {
258
331
  const id = this.id;
259
- const exec = this[kExec];
332
+ const exec = this[K_EXEC];
260
333
  const executionId = exec.has('initExecutionId') ? exec.get('initExecutionId') : (0, _shared.getUniqueId)(id);
261
334
  exec.set('initExecutionId', executionId);
262
335
  this.logger.debug(`<${id}> initialized with executionId <${executionId}>`);
@@ -265,10 +338,16 @@ Activity.prototype.init = function init(initContent) {
265
338
  executionId
266
339
  }));
267
340
  };
341
+
342
+ /**
343
+ * Start running the activity by publishing run.enter and run.start.
344
+ * @param {Record<string, any>} [runContent] Optional content merged into the run message
345
+ * @throws {Error} if the activity is already running
346
+ */
268
347
  Activity.prototype.run = function run(runContent) {
269
348
  const id = this.id;
270
349
  if (this.isRunning) throw new Error(`activity <${id}> is already running`);
271
- const exec = this[kExec];
350
+ const exec = this[K_EXEC];
272
351
  const executionId = exec.get('initExecutionId') || (0, _shared.getUniqueId)(id);
273
352
  exec.set('executionId', executionId);
274
353
  exec.delete('initExecutionId');
@@ -280,12 +359,18 @@ Activity.prototype.run = function run(runContent) {
280
359
  const broker = this.broker;
281
360
  broker.publish('run', 'run.enter', content);
282
361
  broker.publish('run', 'run.start', (0, _messageHelper.cloneContent)(content));
283
- this[kConsuming] = true;
362
+ this[_constants.K_CONSUMING] = true;
284
363
  this._consumeRunQ();
285
364
  };
365
+
366
+ /**
367
+ * Snapshot activity state for recover.
368
+ * Returns undefined when nothing is running and `disableTrackState` is set.
369
+ * @returns {import('#types').ActivityState}
370
+ */
286
371
  Activity.prototype.getState = function getState() {
287
372
  const status = this.status;
288
- const exec = this[kExec];
373
+ const exec = this[K_EXEC];
289
374
  const execution = exec.get('execution');
290
375
  const executionId = exec.get('executionId');
291
376
  const brokerState = this.broker.getState(true);
@@ -305,25 +390,37 @@ Activity.prototype.getState = function getState() {
305
390
  })
306
391
  };
307
392
  };
393
+
394
+ /**
395
+ * Restore activity state captured by getState. Cannot be called while running.
396
+ * @param {import('#types').ActivityState} [state]
397
+ * @returns {this} this when state was applied
398
+ * @throws {Error} when activity is currently running
399
+ */
308
400
  Activity.prototype.recover = function recover(state) {
309
401
  if (this.isRunning) throw new Error(`cannot recover running activity <${this.id}>`);
310
- if (!state) return;
402
+ if (!state) return this;
311
403
  this.stopped = state.stopped;
312
404
  this.status = state.status;
313
- const exec = this[kExec];
405
+ const exec = this[K_EXEC];
314
406
  exec.set('executionId', state.executionId);
315
- this[kCounters] = {
316
- ...this[kCounters],
407
+ this[_constants.K_COUNTERS] = {
408
+ ...this[_constants.K_COUNTERS],
317
409
  ...state.counters
318
410
  };
319
411
  if (state.execution) {
320
- exec.set('execution', new _ActivityExecution.default(this, this.context).recover(state.execution));
412
+ exec.set('execution', new _ActivityExecution.ActivityExecution(this, this.context).recover(state.execution));
321
413
  }
322
414
  this.broker.recover(state.broker);
323
415
  return this;
324
416
  };
417
+
418
+ /**
419
+ * Resume after recover. If no run has been started, falls back to activate.
420
+ * @throws {Error} when called on a running activity
421
+ */
325
422
  Activity.prototype.resume = function resume() {
326
- if (this[kConsuming]) {
423
+ if (this[_constants.K_CONSUMING]) {
327
424
  throw new Error(`cannot resume running activity <${this.id}>`);
328
425
  }
329
426
  if (!this.status) return this.activate();
@@ -333,22 +430,33 @@ Activity.prototype.resume = function resume() {
333
430
  this.broker.publish('run', 'run.resume', content, {
334
431
  persistent: false
335
432
  });
336
- this[kConsuming] = true;
433
+ this[_constants.K_CONSUMING] = true;
337
434
  this._consumeRunQ();
338
435
  };
436
+
437
+ /**
438
+ * Discard the activity. Stops execution if running; the activity leaves without taking any outbound flow.
439
+ * @param {Record<string, any>} [discardContent] Optional content propagated with the discard
440
+ * @returns {void}
441
+ */
339
442
  Activity.prototype.discard = function discard(discardContent) {
340
443
  if (!this.status) return this._runDiscard(discardContent);
341
- const execution = this[kExec].get('execution');
444
+ const execution = this[K_EXEC].get('execution');
342
445
  if (execution && !execution.completed) return execution.discard();
343
446
  this._deactivateRunConsumers();
344
447
  const broker = this.broker;
345
448
  broker.getQueue('run-q').purge();
346
- broker.publish('run', 'run.discard', (0, _messageHelper.cloneContent)(this[kStateMessage].content));
347
- this[kConsuming] = true;
449
+ broker.publish('run', 'run.discard', (0, _messageHelper.cloneContent)(this[_constants.K_STATE_MESSAGE].content));
450
+ this[_constants.K_CONSUMING] = true;
348
451
  this._consumeRunQ();
349
452
  };
453
+
454
+ /**
455
+ * Subscribe to inbound triggers (sequence flows, attached activity, or compensation associations).
456
+ * @returns {number} count of subscribed triggers
457
+ */
350
458
  Activity.prototype.addInboundListeners = function addInboundListeners() {
351
- const triggers = this[kFlows].inboundTriggers;
459
+ const triggers = this._getInboundTriggers();
352
460
  if (triggers.length) {
353
461
  const onInboundEvent = this._onInboundEvent.bind(this);
354
462
  const triggerConsumerTag = `_inbound-${this.id}`;
@@ -373,19 +481,34 @@ Activity.prototype.addInboundListeners = function addInboundListeners() {
373
481
  }
374
482
  return triggers.length;
375
483
  };
484
+
485
+ /**
486
+ * Cancel inbound trigger subscriptions added by addInboundListeners.
487
+ */
376
488
  Activity.prototype.removeInboundListeners = function removeInboundListeners() {
489
+ const triggers = this[K_FLOWS].inboundTriggers;
490
+ if (!triggers) return;
377
491
  const triggerConsumerTag = `_inbound-${this.id}`;
378
- for (const trigger of this[kFlows].inboundTriggers) {
492
+ for (const trigger of triggers) {
379
493
  trigger.broker.cancel(triggerConsumerTag);
380
494
  }
381
495
  };
496
+
497
+ /**
498
+ * Stop the activity. If not currently running, just cancels the inbound consumer.
499
+ */
382
500
  Activity.prototype.stop = function stop() {
383
- if (!this[kConsuming]) return this.broker.cancel('_run-on-inbound');
384
- return this.getApi(this[kStateMessage]).stop();
501
+ if (!this[_constants.K_CONSUMING]) return this.broker.cancel('_run-on-inbound');
502
+ return this.getApi(this[_constants.K_STATE_MESSAGE]).stop();
385
503
  };
504
+
505
+ /**
506
+ * Advance one run-step when the environment runs in step mode. No-op otherwise.
507
+ */
386
508
  Activity.prototype.next = function next() {
387
509
  if (!this.environment.settings.step) return;
388
- const stateMessage = this[kStateMessage];
510
+ /** @type {import('#types').ElementBrokerMessage} */
511
+ const stateMessage = this[_constants.K_STATE_MESSAGE];
389
512
  if (!stateMessage) return;
390
513
  if (this.status === 'executing') return false;
391
514
  if (this.status === 'formatting') return false;
@@ -393,24 +516,49 @@ Activity.prototype.next = function next() {
393
516
  stateMessage.ack();
394
517
  return current;
395
518
  };
519
+
520
+ /**
521
+ * Walk outbound flows to discover the activity graph from this point.
522
+ */
396
523
  Activity.prototype.shake = function shake() {
397
524
  this._shakeOutbound({
398
525
  content: this._createMessage()
399
526
  });
400
527
  };
528
+
529
+ /**
530
+ * Evaluate outbound sequence flows for the given source message.
531
+ * @param {import('#types').ElementBrokerMessage} fromMessage Source run message
532
+ * @param {boolean} discardRestAtTake When true, take only the first matching flow and discard the rest
533
+ * @param {(err: Error, evaluationResult: any) => void} callback
534
+ * @returns {void}
535
+ */
401
536
  Activity.prototype.evaluateOutbound = function evaluateOutbound(fromMessage, discardRestAtTake, callback) {
402
- return this[kFlows].outboundEvaluator.evaluate(fromMessage, discardRestAtTake, callback);
537
+ return this[K_FLOWS].outboundEvaluator.evaluate(fromMessage, discardRestAtTake, callback);
403
538
  };
539
+
540
+ /**
541
+ * Resolve an Api wrapper for the activity, preferring the running execution if any.
542
+ * @param {import('#types').ElementBrokerMessage} [message]
543
+ * @returns {import('#types').IApi<import('./Activity.js').Activity>}
544
+ */
404
545
  Activity.prototype.getApi = function getApi(message) {
405
- const execution = this[kExec].get('execution');
546
+ const execution = this[K_EXEC].get('execution');
406
547
  if (execution && !execution.completed) return execution.getApi(message);
407
- return (0, _Api.ActivityApi)(this.broker, message || this[kStateMessage]);
548
+ return (0, _Api.ActivityApi)(this.broker, message || this[_constants.K_STATE_MESSAGE]);
408
549
  };
550
+
551
+ /**
552
+ * Look up another activity in the same context.
553
+ * @param {string} elementId
554
+ */
409
555
  Activity.prototype.getActivityById = function getActivityById(elementId) {
410
556
  return this.context.getActivityById(elementId);
411
557
  };
558
+
559
+ /** @internal */
412
560
  Activity.prototype._runDiscard = function runDiscard(discardContent) {
413
- const exec = this[kExec];
561
+ const exec = this[K_EXEC];
414
562
  const executionId = exec.get('initExecutionId') || (0, _shared.getUniqueId)(this.id);
415
563
  exec.set('executionId', executionId);
416
564
  exec.delete('initExecutionId');
@@ -420,13 +568,15 @@ Activity.prototype._runDiscard = function runDiscard(discardContent) {
420
568
  executionId
421
569
  });
422
570
  this.broker.publish('run', 'run.discard', content);
423
- this[kConsuming] = true;
571
+ this[_constants.K_CONSUMING] = true;
424
572
  this._consumeRunQ();
425
573
  };
574
+
575
+ /** @internal */
426
576
  Activity.prototype._discardRun = function discardRun() {
427
577
  const status = this.status;
428
578
  if (!status) return;
429
- const execution = this[kExec].get('execution');
579
+ const execution = this[K_EXEC].get('execution');
430
580
  if (execution && !execution.completed) return;
431
581
  let discardRoutingKey = 'run.discard';
432
582
  switch (status) {
@@ -442,51 +592,100 @@ Activity.prototype._discardRun = function discardRun() {
442
592
  return;
443
593
  }
444
594
  this._deactivateRunConsumers();
445
- const stateMessage = this[kStateMessage];
595
+ const stateMessage = this[_constants.K_STATE_MESSAGE];
446
596
  if (this.extensions) this.extensions.deactivate((0, _messageHelper.cloneMessage)(stateMessage));
447
597
  const broker = this.broker;
448
598
  broker.getQueue('run-q').purge();
449
599
  broker.publish('run', discardRoutingKey, (0, _messageHelper.cloneContent)(stateMessage.content), {
450
600
  correlationId: stateMessage.properties.correlationId
451
601
  });
452
- this[kConsuming] = true;
602
+ this[_constants.K_CONSUMING] = true;
453
603
  this._consumeRunQ();
454
604
  };
605
+
606
+ /** @internal */
607
+ Activity.prototype._onShakeMessage = function _onShakeMessage(sourceMessage) {
608
+ if (this[K_FLAGS].isParallelGateway) {
609
+ const message = (0, _messageHelper.cloneMessage)(sourceMessage, {
610
+ join: this.id
611
+ });
612
+ message.content.sequence.push({
613
+ id: this.id,
614
+ type: this.type
615
+ });
616
+ return this.broker.publish('event', 'activity.shake.join', message.content, {
617
+ persistent: false,
618
+ type: 'shake'
619
+ });
620
+ }
621
+ this._shakeOutbound(sourceMessage);
622
+ };
623
+
624
+ /** @internal */
455
625
  Activity.prototype._shakeOutbound = function shakeOutbound(sourceMessage) {
456
626
  const message = (0, _messageHelper.cloneMessage)(sourceMessage);
457
- message.content.sequence = message.content.sequence || [];
458
- message.content.sequence.push({
627
+ const sequence = message.content.sequence = message.content.sequence || [];
628
+ const count = 1;
629
+ const looped = sequence?.find(f => f.id === this.id);
630
+ sequence.push({
459
631
  id: this.id,
460
- type: this.type
632
+ type: this.type,
633
+ count: looped ? looped.count + 1 : count
461
634
  });
462
- const broker = this.broker;
463
635
  this.broker.publish('api', 'activity.shake.start', message.content, {
464
636
  persistent: false,
465
637
  type: 'shake'
466
638
  });
467
- if (this[kFlags].isEnd) {
468
- return broker.publish('event', 'activity.shake.end', message.content, {
639
+ const flags = this[K_FLAGS];
640
+ if (flags.isThrowing && flags.linkNames?.length) {
641
+ for (const target of this.context.getActivitiesByEventDefinitionBehaviour(flags.linkBehaviour, flags.linkNames)) {
642
+ if (target.id === this.id || !target.isCatching) continue;
643
+ const linkedContent = (0, _messageHelper.cloneContent)(message.content, {
644
+ sourceId: this.id,
645
+ targetId: target.id,
646
+ isLinked: true
647
+ });
648
+ linkedContent.sequence = linkedContent.sequence.concat({
649
+ id: target.id,
650
+ type: target.type
651
+ });
652
+ target.broker.publish('event', 'activity.shake.linked', linkedContent, {
653
+ persistent: false,
654
+ type: 'shake'
655
+ });
656
+ for (const flow of target.outbound) flow.shake({
657
+ content: (0, _messageHelper.cloneContent)(linkedContent)
658
+ });
659
+ }
660
+ }
661
+ if (this[K_FLAGS].isEnd) {
662
+ return this.broker.publish('event', 'activity.shake.end', (0, _messageHelper.cloneContent)(message.content), {
469
663
  persistent: false,
470
664
  type: 'shake'
471
665
  });
472
666
  }
473
- for (const flow of this[kFlows].outboundSequenceFlows) flow.shake(message);
667
+ const targets = new Map();
668
+ for (const outboundFlow of this[K_FLOWS].outboundSequenceFlows) {
669
+ const prevTarget = targets.get(outboundFlow.targetId);
670
+ if (!prevTarget) {
671
+ targets.set(outboundFlow.targetId, outboundFlow);
672
+ }
673
+ }
674
+ for (const t of targets.values()) t.shake(message);
474
675
  };
676
+
677
+ /** @internal */
475
678
  Activity.prototype._consumeInbound = function consumeInbound() {
476
- if (!this[kActivated]) return;
477
- if (this.status || !this[kFlows].inboundTriggers.length) return;
679
+ if (!this[_constants.K_ACTIVATED]) return;
680
+ if (this.status || !this._getInboundTriggers().length) return;
478
681
  const inboundQ = this.broker.getQueue('inbound-q');
479
- const onInbound = this[kMessageHandlers].onInbound;
480
- if (this[kFlags].isParallelJoin) {
481
- return inboundQ.assertConsumer(onInbound, {
482
- consumerTag: '_run-on-inbound',
483
- prefetch: 1000
484
- });
485
- }
682
+ const onInbound = this[_constants.K_MESSAGE_HANDLERS].onInbound;
486
683
  return inboundQ.assertConsumer(onInbound, {
487
684
  consumerTag: '_run-on-inbound'
488
685
  });
489
686
  };
687
+
688
+ /** @internal */
490
689
  Activity.prototype._onInbound = function onInbound(routingKey, message) {
491
690
  message.ack();
492
691
  const broker = this.broker;
@@ -494,6 +693,12 @@ Activity.prototype._onInbound = function onInbound(routingKey, message) {
494
693
  const content = message.content;
495
694
  const inbound = [(0, _messageHelper.cloneContent)(content)];
496
695
  switch (routingKey) {
696
+ case 'activity.relink':
697
+ if (content.executionId) this[K_EXEC].set('initExecutionId', content.executionId);
698
+ return this.run({
699
+ message: content.message,
700
+ inbound
701
+ });
497
702
  case 'association.take':
498
703
  case 'flow.take':
499
704
  case 'activity.restart':
@@ -502,67 +707,16 @@ Activity.prototype._onInbound = function onInbound(routingKey, message) {
502
707
  message: content.message,
503
708
  inbound
504
709
  });
505
- case 'flow.discard':
506
710
  case 'activity.discard':
507
711
  {
508
- let discardSequence;
509
- if (content.discardSequence) discardSequence = content.discardSequence.slice();
510
712
  return this._runDiscard({
511
- inbound,
512
- discardSequence
713
+ inbound
513
714
  });
514
715
  }
515
716
  }
516
717
  };
517
- Activity.prototype._onJoinInbound = function onJoinInbound(routingKey, message) {
518
- const {
519
- content
520
- } = message;
521
- const {
522
- inboundJoinFlows,
523
- inboundSourceIds
524
- } = this[kFlows];
525
- let alreadyTouched = false;
526
- const touched = new Set();
527
- let taken;
528
- for (const msg of inboundJoinFlows) {
529
- const sourceId = msg.content.sourceId;
530
- touched.add(sourceId);
531
- if (sourceId === content.sourceId) {
532
- alreadyTouched = true;
533
- }
534
- }
535
- inboundJoinFlows.add(message);
536
- if (alreadyTouched) return;
537
- const remaining = inboundSourceIds.size - touched.size - 1;
538
- if (remaining) {
539
- return this.logger.debug(`<${this.id}> inbound ${message.content.action} from <${message.content.id}>, ${remaining} remaining`);
540
- }
541
- const inbound = [];
542
- for (const im of inboundJoinFlows) {
543
- if (im.fields.routingKey === 'flow.take') taken = true;
544
- im.ack();
545
- inbound.push((0, _messageHelper.cloneContent)(im.content));
546
- }
547
- const discardSequence = new Set();
548
- if (!taken) {
549
- for (const im of inboundJoinFlows) {
550
- if (!im.content.discardSequence) continue;
551
- for (const sourceId of im.content.discardSequence) {
552
- discardSequence.add(sourceId);
553
- }
554
- }
555
- }
556
- inboundJoinFlows.clear();
557
- this.broker.cancel('_run-on-inbound');
558
- if (!taken) return this._runDiscard({
559
- inbound,
560
- discardSequence: [...discardSequence]
561
- });
562
- return this.run({
563
- inbound
564
- });
565
- };
718
+
719
+ /** @internal */
566
720
  Activity.prototype._onInboundEvent = function onInboundEvent(routingKey, message) {
567
721
  const {
568
722
  fields,
@@ -574,36 +728,65 @@ Activity.prototype._onInboundEvent = function onInboundEvent(routingKey, message
574
728
  case 'activity.enter':
575
729
  case 'activity.discard':
576
730
  {
577
- if (content.id === this[kFlags].attachedTo) {
731
+ if (content.id === this[K_FLAGS].attachedTo) {
578
732
  inboundQ.queueMessage(fields, (0, _messageHelper.cloneContent)(content), properties);
579
733
  }
580
734
  break;
581
735
  }
582
736
  case 'flow.shake':
737
+ case 'activity.shake.start':
738
+ return this._onShakeMessage(message);
739
+ case 'activity.link':
583
740
  {
584
- return this._shakeOutbound(message);
741
+ const linkName = content.message?.linkName;
742
+ if (!this[K_FLAGS].linkNames?.includes(linkName)) break;
743
+ const executionId = (0, _shared.getUniqueId)(this.id);
744
+ this.broker.publish('event', 'activity.enter', (0, _messageHelper.cloneContent)(content, {
745
+ id: this.id,
746
+ type: this.type,
747
+ executionId,
748
+ state: 'enter',
749
+ message: {
750
+ ...content.message
751
+ }
752
+ }));
753
+ inboundQ.queueMessage({
754
+ routingKey: 'activity.relink'
755
+ }, (0, _messageHelper.cloneContent)(content, {
756
+ id: this.id,
757
+ executionId,
758
+ message: {
759
+ ...content.message
760
+ }
761
+ }), properties);
762
+ return;
585
763
  }
586
764
  case 'association.take':
587
765
  case 'flow.take':
588
- case 'flow.discard':
589
766
  return inboundQ.queueMessage(fields, (0, _messageHelper.cloneContent)(content), properties);
590
767
  }
591
768
  };
769
+
770
+ /** @internal */
592
771
  Activity.prototype._consumeRunQ = function consumeRunQ() {
593
- this[kConsumingRunQ] = true;
594
- this.broker.getQueue('run-q').assertConsumer(this[kMessageHandlers].onRunMessage, {
772
+ this[K_CONSUMING_RUN_Q] = true;
773
+ this.broker.getQueue('run-q').assertConsumer(this[_constants.K_MESSAGE_HANDLERS].onRunMessage, {
595
774
  exclusive: true,
596
775
  consumerTag: '_activity-run'
597
776
  });
598
777
  };
778
+
779
+ /** @internal */
599
780
  Activity.prototype._pauseRunQ = function pauseRunQ() {
600
- if (!this[kConsumingRunQ]) return;
601
- this[kConsumingRunQ] = false;
781
+ if (!this[K_CONSUMING_RUN_Q]) return;
782
+ this[K_CONSUMING_RUN_Q] = false;
602
783
  this.broker.cancel('_activity-run');
603
784
  };
785
+
786
+ /** @internal */
604
787
  Activity.prototype._onRunMessage = function onRunMessage(routingKey, message, messageProperties) {
605
788
  switch (routingKey) {
606
- case 'run.outbound.discard':
789
+ case 'run.execute.passthrough':
607
790
  case 'run.outbound.take':
608
791
  case 'run.next':
609
792
  return this._continueRunMessage(routingKey, message, messageProperties);
@@ -623,20 +806,22 @@ Activity.prototype._onRunMessage = function onRunMessage(routingKey, message, me
623
806
  this._continueRunMessage(routingKey, message, messageProperties);
624
807
  });
625
808
  };
809
+
810
+ /** @internal */
626
811
  Activity.prototype._continueRunMessage = function continueRunMessage(routingKey, message) {
627
812
  const isRedelivered = message.fields.redelivered;
628
813
  const content = (0, _messageHelper.cloneContent)(message.content);
629
814
  const correlationId = message.properties.correlationId;
630
815
  const id = this.id;
631
816
  const step = this.environment.settings.step;
632
- this[kStateMessage] = message;
817
+ this[_constants.K_STATE_MESSAGE] = message;
633
818
  switch (routingKey) {
634
819
  case 'run.enter':
635
820
  {
636
821
  this.logger.debug(`<${id}> enter`, isRedelivered ? 'redelivered' : '');
637
822
  this.status = 'entered';
638
823
  if (!isRedelivered) {
639
- this[kExec].delete('execution');
824
+ this[K_EXEC].delete('execution');
640
825
  if (this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message));
641
826
  this._publishEvent('enter', content, {
642
827
  correlationId
@@ -648,7 +833,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
648
833
  {
649
834
  this.logger.debug(`<${id}> discard`, isRedelivered ? 'redelivered' : '');
650
835
  this.status = 'discard';
651
- this[kExec].delete('execution');
836
+ this[K_EXEC].delete('execution');
652
837
  if (this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message));
653
838
  if (!isRedelivered) {
654
839
  this.broker.publish('run', 'run.discarded', content, {
@@ -674,25 +859,25 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
674
859
  }
675
860
  case 'run.execute.passthrough':
676
861
  {
677
- const execution = this[kExec].get('execution');
862
+ const execution = this[K_EXEC].get('execution');
678
863
  if (!isRedelivered && execution) {
679
864
  if (execution.completed) return message.ack();
680
- this[kExecuteMessage] = message;
865
+ this[_constants.K_EXECUTE_MESSAGE] = message;
681
866
  return execution.passthrough(message);
682
867
  }
683
868
  }
684
869
  case 'run.execute':
685
870
  {
686
871
  this.status = 'executing';
687
- this[kExecuteMessage] = message;
872
+ this[_constants.K_EXECUTE_MESSAGE] = message;
688
873
  if (isRedelivered && this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message));
689
- const exec = this[kExec];
874
+ const exec = this[K_EXEC];
690
875
  let execution = exec.get('execution');
691
876
  if (!execution) {
692
- execution = new _ActivityExecution.default(this, this.context);
877
+ execution = new _ActivityExecution.ActivityExecution(this, this.context);
693
878
  exec.set('execution', execution);
694
879
  }
695
- this.broker.getQueue('execution-q').assertConsumer(this[kMessageHandlers].onExecutionMessage, {
880
+ this.broker.getQueue('execution-q').assertConsumer(this[_constants.K_MESSAGE_HANDLERS].onExecutionMessage, {
696
881
  exclusive: true,
697
882
  consumerTag: '_activity-execution'
698
883
  });
@@ -702,7 +887,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
702
887
  {
703
888
  this.logger.debug(`<${id}> end`, isRedelivered ? 'redelivered' : '');
704
889
  if (isRedelivered) break;
705
- this[kCounters].taken++;
890
+ this[_constants.K_COUNTERS].taken++;
706
891
  this.status = 'end';
707
892
  return this._doRunLeave(message, false, () => {
708
893
  this._publishEvent('end', content, {
@@ -724,7 +909,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
724
909
  case 'run.discarded':
725
910
  {
726
911
  this.logger.debug(`<${content.executionId} (${id})> discarded`);
727
- this[kCounters].discarded++;
912
+ this[_constants.K_COUNTERS].discarded++;
728
913
  this.status = 'discarded';
729
914
  content.outbound = undefined;
730
915
  if (!isRedelivered) {
@@ -740,12 +925,6 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
740
925
  message.ack();
741
926
  return flow.take(content.flow);
742
927
  }
743
- case 'run.outbound.discard':
744
- {
745
- const flow = this._getOutboundSequenceFlowById(content.flow.id);
746
- message.ack();
747
- return flow.discard(content.flow);
748
- }
749
928
  case 'run.leave':
750
929
  {
751
930
  this.status = undefined;
@@ -767,8 +946,10 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
767
946
  }
768
947
  if (!step) message.ack();
769
948
  };
949
+
950
+ /** @internal */
770
951
  Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey, message) {
771
- const executeMessage = this[kExecuteMessage];
952
+ const executeMessage = this[_constants.K_EXECUTE_MESSAGE];
772
953
  const content = (0, _messageHelper.cloneContent)({
773
954
  ...executeMessage.content,
774
955
  ...message.content,
@@ -785,7 +966,7 @@ Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey,
785
966
  switch (routingKey) {
786
967
  case 'execution.outbound.take':
787
968
  {
788
- return this._doOutbound(message, false, (err, outbound) => {
969
+ return this._doOutbound(message, (err, outbound) => {
789
970
  message.ack();
790
971
  if (err) return this.emitFatal(err, content);
791
972
  broker.publish('run', 'run.execute.passthrough', (0, _messageHelper.cloneContent)(content, {
@@ -807,11 +988,13 @@ Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey,
807
988
  }
808
989
  case 'execution.cancel':
809
990
  case 'execution.discard':
810
- this.status = 'discarded';
811
- broker.publish('run', 'run.discarded', content, {
812
- correlationId
813
- });
814
- break;
991
+ {
992
+ this.status = 'discarded';
993
+ broker.publish('run', 'run.discarded', content, {
994
+ correlationId
995
+ });
996
+ break;
997
+ }
815
998
  default:
816
999
  {
817
1000
  this.status = 'executed';
@@ -823,24 +1006,28 @@ Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey,
823
1006
  message.ack();
824
1007
  this._ackRunExecuteMessage();
825
1008
  };
1009
+
1010
+ /** @internal */
826
1011
  Activity.prototype._ackRunExecuteMessage = function ackRunExecuteMessage() {
827
1012
  if (this.environment.settings.step) return;
828
- const executeMessage = this[kExecuteMessage];
1013
+ const executeMessage = this[_constants.K_EXECUTE_MESSAGE];
829
1014
  executeMessage.ack();
830
1015
  };
1016
+
1017
+ /** @internal */
831
1018
  Activity.prototype._doRunLeave = function doRunLeave(message, isDiscarded, onOutbound) {
832
1019
  const {
833
1020
  content,
834
1021
  properties
835
1022
  } = message;
836
1023
  const correlationId = properties.correlationId;
837
- if (content.ignoreOutbound) {
1024
+ if (isDiscarded || content.ignoreOutbound) {
838
1025
  this.broker.publish('run', 'run.leave', (0, _messageHelper.cloneContent)(content), {
839
1026
  correlationId
840
1027
  });
841
1028
  return onOutbound();
842
1029
  }
843
- return this._doOutbound((0, _messageHelper.cloneMessage)(message), isDiscarded, (err, outbound) => {
1030
+ return this._doOutbound((0, _messageHelper.cloneMessage)(message), (err, outbound) => {
844
1031
  if (err) {
845
1032
  return this._publishEvent('error', {
846
1033
  ...content,
@@ -859,35 +1046,31 @@ Activity.prototype._doRunLeave = function doRunLeave(message, isDiscarded, onOut
859
1046
  onOutbound();
860
1047
  });
861
1048
  };
862
- Activity.prototype._doOutbound = function doOutbound(fromMessage, isDiscarded, callback) {
863
- const outboundSequenceFlows = this[kFlows].outboundSequenceFlows;
1049
+
1050
+ /** @internal */
1051
+ Activity.prototype._doOutbound = function doOutbound(fromMessage, callback) {
1052
+ const outboundSequenceFlows = this[K_FLOWS].outboundSequenceFlows;
864
1053
  if (!outboundSequenceFlows.length) return callback(null, []);
865
1054
  const fromContent = fromMessage.content;
866
- let discardSequence = fromContent.discardSequence;
867
- if (isDiscarded && !discardSequence && this[kFlags].attachedTo && fromContent.inbound?.[0]) {
868
- discardSequence = [fromContent.inbound[0].id];
869
- }
870
1055
  let outboundFlows;
871
- if (isDiscarded) {
872
- outboundFlows = outboundSequenceFlows.map(flow => (0, _outboundEvaluator.formatFlowAction)(flow, {
873
- action: 'discard'
874
- }));
875
- } else if (fromContent.outbound?.length) {
1056
+ if (fromContent.outbound?.length) {
876
1057
  outboundFlows = outboundSequenceFlows.map(flow => (0, _outboundEvaluator.formatFlowAction)(flow, fromContent.outbound.filter(f => f.id === flow.id).pop()));
877
1058
  }
878
1059
  if (outboundFlows) {
879
- this._doRunOutbound(outboundFlows, fromContent, discardSequence);
1060
+ this._doRunOutbound(outboundFlows, fromContent);
880
1061
  return callback(null, outboundFlows);
881
1062
  }
882
1063
  return this.evaluateOutbound(fromMessage, fromContent.outboundTakeOne, (err, evaluatedOutbound) => {
883
1064
  if (err) return callback(new _Errors.ActivityError(err.message, fromMessage, err));
884
- const outbound = this._doRunOutbound(evaluatedOutbound, fromContent, discardSequence);
1065
+ const outbound = this._doRunOutbound(evaluatedOutbound, fromContent);
885
1066
  return callback(null, outbound);
886
1067
  });
887
1068
  };
888
- Activity.prototype._doRunOutbound = function doRunOutbound(outboundList, content, discardSequence) {
1069
+
1070
+ /** @internal */
1071
+ Activity.prototype._doRunOutbound = function doRunOutbound(outboundList, content) {
889
1072
  if (outboundList.length === 1) {
890
- this._publishRunOutbound(outboundList[0], content, discardSequence);
1073
+ this._publishRunOutbound(outboundList[0], content);
891
1074
  } else {
892
1075
  const targets = new Map();
893
1076
  for (const outboundFlow of outboundList) {
@@ -899,31 +1082,35 @@ Activity.prototype._doRunOutbound = function doRunOutbound(outboundList, content
899
1082
  }
900
1083
  }
901
1084
  for (const outboundFlow of targets.values()) {
902
- this._publishRunOutbound(outboundFlow, content, discardSequence);
1085
+ this._publishRunOutbound(outboundFlow, content);
903
1086
  }
904
1087
  }
905
1088
  return outboundList;
906
1089
  };
907
- Activity.prototype._publishRunOutbound = function publishRunOutbound(outboundFlow, content, discardSequence) {
1090
+
1091
+ /** @internal */
1092
+ Activity.prototype._publishRunOutbound = function publishRunOutbound(outboundFlow, content) {
908
1093
  const {
909
1094
  id: flowId,
910
1095
  action,
911
1096
  result
912
1097
  } = outboundFlow;
1098
+ if (action === 'discard') {
1099
+ return;
1100
+ }
913
1101
  this.broker.publish('run', 'run.outbound.' + action, (0, _messageHelper.cloneContent)(content, {
914
1102
  flow: {
915
1103
  ...(result && typeof result === 'object' && result),
916
1104
  ...outboundFlow,
917
- sequenceId: (0, _shared.getUniqueId)(`${flowId}_${action}`),
918
- ...(discardSequence && {
919
- discardSequence: discardSequence.slice()
920
- })
1105
+ sequenceId: (0, _shared.getUniqueId)(`${flowId}_${action}`)
921
1106
  }
922
1107
  }));
923
1108
  };
1109
+
1110
+ /** @internal */
924
1111
  Activity.prototype._onResumeMessage = function onResumeMessage(message) {
925
1112
  message.ack();
926
- const stateMessage = this[kStateMessage];
1113
+ const stateMessage = this[_constants.K_STATE_MESSAGE];
927
1114
  const fields = stateMessage.fields;
928
1115
  if (!fields.redelivered) return;
929
1116
  switch (fields.routingKey) {
@@ -940,6 +1127,8 @@ Activity.prototype._onResumeMessage = function onResumeMessage(message) {
940
1127
  this.logger.debug(`<${this.id}> resume from ${message.content.status}`);
941
1128
  return this.broker.publish('run', fields.routingKey, (0, _messageHelper.cloneContent)(stateMessage.content), stateMessage.properties);
942
1129
  };
1130
+
1131
+ /** @internal */
943
1132
  Activity.prototype._publishEvent = function publishEvent(state, content, properties) {
944
1133
  this.broker.publish('event', `activity.${state}`, (0, _messageHelper.cloneContent)(content, {
945
1134
  state
@@ -949,10 +1138,12 @@ Activity.prototype._publishEvent = function publishEvent(state, content, propert
949
1138
  mandatory: state === 'error'
950
1139
  });
951
1140
  };
1141
+
1142
+ /** @internal */
952
1143
  Activity.prototype._onStop = function onStop(message) {
953
- const running = this[kConsuming];
1144
+ const running = this[_constants.K_CONSUMING];
954
1145
  this.stopped = true;
955
- this[kConsuming] = false;
1146
+ this[_constants.K_CONSUMING] = false;
956
1147
  const broker = this.broker;
957
1148
  this._pauseRunQ();
958
1149
  broker.cancel('_activity-api');
@@ -966,17 +1157,21 @@ Activity.prototype._onStop = function onStop(message) {
966
1157
  });
967
1158
  }
968
1159
  };
1160
+
1161
+ /** @internal */
969
1162
  Activity.prototype._consumeApi = function consumeApi() {
970
- const executionId = this[kExec].get('executionId');
1163
+ const executionId = this[K_EXEC].get('executionId');
971
1164
  if (!executionId) return;
972
1165
  const broker = this.broker;
973
1166
  broker.cancel('_activity-api');
974
- broker.subscribeTmp('api', `activity.*.${executionId}`, this[kMessageHandlers].onApiMessage, {
1167
+ broker.subscribeTmp('api', `activity.*.${executionId}`, this[_constants.K_MESSAGE_HANDLERS].onApiMessage, {
975
1168
  noAck: true,
976
1169
  consumerTag: '_activity-api',
977
1170
  priority: 100
978
1171
  });
979
1172
  };
1173
+
1174
+ /** @internal */
980
1175
  Activity.prototype._onApiMessage = function onApiMessage(routingKey, message) {
981
1176
  switch (message.properties.type) {
982
1177
  case 'discard':
@@ -993,6 +1188,8 @@ Activity.prototype._onApiMessage = function onApiMessage(routingKey, message) {
993
1188
  }
994
1189
  }
995
1190
  };
1191
+
1192
+ /** @internal */
996
1193
  Activity.prototype._createMessage = function createMessage(override) {
997
1194
  const {
998
1195
  name,
@@ -1013,18 +1210,22 @@ Activity.prototype._createMessage = function createMessage(override) {
1013
1210
  parent: (0, _messageHelper.cloneParent)(parent)
1014
1211
  })
1015
1212
  };
1016
- for (const [flag, value] of Object.entries(this[kFlags])) {
1213
+ for (const [flag, value] of Object.entries(this[K_FLAGS])) {
1017
1214
  if (value) result[flag] = value;
1018
1215
  }
1019
1216
  return result;
1020
1217
  };
1218
+
1219
+ /** @internal */
1021
1220
  Activity.prototype._getOutboundSequenceFlowById = function getOutboundSequenceFlowById(flowId) {
1022
- return this[kFlows].outboundSequenceFlows.find(flow => flow.id === flowId);
1221
+ return this[K_FLOWS].outboundSequenceFlows.find(flow => flow.id === flowId);
1023
1222
  };
1223
+
1224
+ /** @internal */
1024
1225
  Activity.prototype._deactivateRunConsumers = function _deactivateRunConsumers() {
1025
1226
  const broker = this.broker;
1026
1227
  broker.cancel('_activity-api');
1027
1228
  this._pauseRunQ();
1028
1229
  broker.cancel('_activity-execution');
1029
- this[kConsuming] = false;
1230
+ this[_constants.K_CONSUMING] = false;
1030
1231
  };