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
@@ -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
- const flows = 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] = {
103
- isEnd: flows.outboundSequenceFlows.length === 0,
104
- isStart: flows.inboundSequenceFlows.length === 0 && !attachedTo && !behaviour.triggeredByEvent && !isForCompensation,
100
+ this[K_FLAGS] = {
101
+ isEnd: !outboundSequenceFlows.length,
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,31 +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;
248
- this.addInboundListeners();
249
- return this._consumeInbound();
281
+ if (this[_constants.K_ACTIVATED]) return;
282
+ this[_constants.K_ACTIVATED] = true;
283
+ return this.addInboundListeners() && this._consumeInbound();
250
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
+ */
251
318
  Activity.prototype.deactivate = function deactivate() {
252
- this[kActivated] = false;
319
+ this[_constants.K_ACTIVATED] = false;
253
320
  const broker = this.broker;
254
321
  this.removeInboundListeners();
255
322
  broker.cancel('_run-on-inbound');
256
323
  broker.cancel('_format-consumer');
257
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
+ */
258
330
  Activity.prototype.init = function init(initContent) {
259
331
  const id = this.id;
260
- const exec = this[kExec];
332
+ const exec = this[K_EXEC];
261
333
  const executionId = exec.has('initExecutionId') ? exec.get('initExecutionId') : (0, _shared.getUniqueId)(id);
262
334
  exec.set('initExecutionId', executionId);
263
335
  this.logger.debug(`<${id}> initialized with executionId <${executionId}>`);
@@ -266,10 +338,16 @@ Activity.prototype.init = function init(initContent) {
266
338
  executionId
267
339
  }));
268
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
+ */
269
347
  Activity.prototype.run = function run(runContent) {
270
348
  const id = this.id;
271
349
  if (this.isRunning) throw new Error(`activity <${id}> is already running`);
272
- const exec = this[kExec];
350
+ const exec = this[K_EXEC];
273
351
  const executionId = exec.get('initExecutionId') || (0, _shared.getUniqueId)(id);
274
352
  exec.set('executionId', executionId);
275
353
  exec.delete('initExecutionId');
@@ -281,12 +359,18 @@ Activity.prototype.run = function run(runContent) {
281
359
  const broker = this.broker;
282
360
  broker.publish('run', 'run.enter', content);
283
361
  broker.publish('run', 'run.start', (0, _messageHelper.cloneContent)(content));
284
- this[kConsuming] = true;
362
+ this[_constants.K_CONSUMING] = true;
285
363
  this._consumeRunQ();
286
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
+ */
287
371
  Activity.prototype.getState = function getState() {
288
372
  const status = this.status;
289
- const exec = this[kExec];
373
+ const exec = this[K_EXEC];
290
374
  const execution = exec.get('execution');
291
375
  const executionId = exec.get('executionId');
292
376
  const brokerState = this.broker.getState(true);
@@ -306,25 +390,37 @@ Activity.prototype.getState = function getState() {
306
390
  })
307
391
  };
308
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
+ */
309
400
  Activity.prototype.recover = function recover(state) {
310
401
  if (this.isRunning) throw new Error(`cannot recover running activity <${this.id}>`);
311
- if (!state) return;
402
+ if (!state) return this;
312
403
  this.stopped = state.stopped;
313
404
  this.status = state.status;
314
- const exec = this[kExec];
405
+ const exec = this[K_EXEC];
315
406
  exec.set('executionId', state.executionId);
316
- this[kCounters] = {
317
- ...this[kCounters],
407
+ this[_constants.K_COUNTERS] = {
408
+ ...this[_constants.K_COUNTERS],
318
409
  ...state.counters
319
410
  };
320
411
  if (state.execution) {
321
- 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));
322
413
  }
323
414
  this.broker.recover(state.broker);
324
415
  return this;
325
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
+ */
326
422
  Activity.prototype.resume = function resume() {
327
- if (this[kConsuming]) {
423
+ if (this[_constants.K_CONSUMING]) {
328
424
  throw new Error(`cannot resume running activity <${this.id}>`);
329
425
  }
330
426
  if (!this.status) return this.activate();
@@ -334,55 +430,85 @@ Activity.prototype.resume = function resume() {
334
430
  this.broker.publish('run', 'run.resume', content, {
335
431
  persistent: false
336
432
  });
337
- this[kConsuming] = true;
433
+ this[_constants.K_CONSUMING] = true;
338
434
  this._consumeRunQ();
339
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
+ */
340
442
  Activity.prototype.discard = function discard(discardContent) {
341
443
  if (!this.status) return this._runDiscard(discardContent);
342
- const execution = this[kExec].get('execution');
444
+ const execution = this[K_EXEC].get('execution');
343
445
  if (execution && !execution.completed) return execution.discard();
344
446
  this._deactivateRunConsumers();
345
447
  const broker = this.broker;
346
448
  broker.getQueue('run-q').purge();
347
- broker.publish('run', 'run.discard', (0, _messageHelper.cloneContent)(this[kStateMessage].content));
348
- this[kConsuming] = true;
449
+ broker.publish('run', 'run.discard', (0, _messageHelper.cloneContent)(this[_constants.K_STATE_MESSAGE].content));
450
+ this[_constants.K_CONSUMING] = true;
349
451
  this._consumeRunQ();
350
452
  };
453
+
454
+ /**
455
+ * Subscribe to inbound triggers (sequence flows, attached activity, or compensation associations).
456
+ * @returns {number} count of subscribed triggers
457
+ */
351
458
  Activity.prototype.addInboundListeners = function addInboundListeners() {
352
- const onInboundEvent = this._onInboundEvent.bind(this);
353
- const triggerConsumerTag = `_inbound-${this.id}`;
354
- for (const trigger of this[kFlows].inboundTriggers) {
355
- if (trigger.isSequenceFlow) {
356
- trigger.broker.subscribeTmp('event', 'flow.#', onInboundEvent, {
357
- noAck: true,
358
- consumerTag: triggerConsumerTag
359
- });
360
- } else if (this.isForCompensation) {
361
- trigger.broker.subscribeTmp('event', 'association.#', onInboundEvent, {
362
- noAck: true,
363
- consumerTag: triggerConsumerTag
364
- });
365
- } else {
366
- trigger.broker.subscribeTmp('event', 'activity.#', onInboundEvent, {
367
- noAck: true,
368
- consumerTag: triggerConsumerTag
369
- });
459
+ const triggers = this._getInboundTriggers();
460
+ if (triggers.length) {
461
+ const onInboundEvent = this._onInboundEvent.bind(this);
462
+ const triggerConsumerTag = `_inbound-${this.id}`;
463
+ for (const trigger of triggers) {
464
+ if (trigger.isSequenceFlow) {
465
+ trigger.broker.subscribeTmp('event', 'flow.#', onInboundEvent, {
466
+ noAck: true,
467
+ consumerTag: triggerConsumerTag
468
+ });
469
+ } else if (this.isForCompensation) {
470
+ trigger.broker.subscribeTmp('event', 'association.#', onInboundEvent, {
471
+ noAck: true,
472
+ consumerTag: triggerConsumerTag
473
+ });
474
+ } else {
475
+ trigger.broker.subscribeTmp('event', 'activity.#', onInboundEvent, {
476
+ noAck: true,
477
+ consumerTag: triggerConsumerTag
478
+ });
479
+ }
370
480
  }
371
481
  }
482
+ return triggers.length;
372
483
  };
484
+
485
+ /**
486
+ * Cancel inbound trigger subscriptions added by addInboundListeners.
487
+ */
373
488
  Activity.prototype.removeInboundListeners = function removeInboundListeners() {
489
+ const triggers = this[K_FLOWS].inboundTriggers;
490
+ if (!triggers) return;
374
491
  const triggerConsumerTag = `_inbound-${this.id}`;
375
- for (const trigger of this[kFlows].inboundTriggers) {
492
+ for (const trigger of triggers) {
376
493
  trigger.broker.cancel(triggerConsumerTag);
377
494
  }
378
495
  };
496
+
497
+ /**
498
+ * Stop the activity. If not currently running, just cancels the inbound consumer.
499
+ */
379
500
  Activity.prototype.stop = function stop() {
380
- if (!this[kConsuming]) return this.broker.cancel('_run-on-inbound');
381
- 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();
382
503
  };
504
+
505
+ /**
506
+ * Advance one run-step when the environment runs in step mode. No-op otherwise.
507
+ */
383
508
  Activity.prototype.next = function next() {
384
509
  if (!this.environment.settings.step) return;
385
- const stateMessage = this[kStateMessage];
510
+ /** @type {import('#types').ElementBrokerMessage} */
511
+ const stateMessage = this[_constants.K_STATE_MESSAGE];
386
512
  if (!stateMessage) return;
387
513
  if (this.status === 'executing') return false;
388
514
  if (this.status === 'formatting') return false;
@@ -390,24 +516,49 @@ Activity.prototype.next = function next() {
390
516
  stateMessage.ack();
391
517
  return current;
392
518
  };
519
+
520
+ /**
521
+ * Walk outbound flows to discover the activity graph from this point.
522
+ */
393
523
  Activity.prototype.shake = function shake() {
394
524
  this._shakeOutbound({
395
525
  content: this._createMessage()
396
526
  });
397
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
+ */
398
536
  Activity.prototype.evaluateOutbound = function evaluateOutbound(fromMessage, discardRestAtTake, callback) {
399
- return this[kFlows].outboundEvaluator.evaluate(fromMessage, discardRestAtTake, callback);
537
+ return this[K_FLOWS].outboundEvaluator.evaluate(fromMessage, discardRestAtTake, callback);
400
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
+ */
401
545
  Activity.prototype.getApi = function getApi(message) {
402
- const execution = this[kExec].get('execution');
546
+ const execution = this[K_EXEC].get('execution');
403
547
  if (execution && !execution.completed) return execution.getApi(message);
404
- return (0, _Api.ActivityApi)(this.broker, message || this[kStateMessage]);
548
+ return (0, _Api.ActivityApi)(this.broker, message || this[_constants.K_STATE_MESSAGE]);
405
549
  };
550
+
551
+ /**
552
+ * Look up another activity in the same context.
553
+ * @param {string} elementId
554
+ */
406
555
  Activity.prototype.getActivityById = function getActivityById(elementId) {
407
556
  return this.context.getActivityById(elementId);
408
557
  };
558
+
559
+ /** @internal */
409
560
  Activity.prototype._runDiscard = function runDiscard(discardContent) {
410
- const exec = this[kExec];
561
+ const exec = this[K_EXEC];
411
562
  const executionId = exec.get('initExecutionId') || (0, _shared.getUniqueId)(this.id);
412
563
  exec.set('executionId', executionId);
413
564
  exec.delete('initExecutionId');
@@ -417,13 +568,15 @@ Activity.prototype._runDiscard = function runDiscard(discardContent) {
417
568
  executionId
418
569
  });
419
570
  this.broker.publish('run', 'run.discard', content);
420
- this[kConsuming] = true;
571
+ this[_constants.K_CONSUMING] = true;
421
572
  this._consumeRunQ();
422
573
  };
574
+
575
+ /** @internal */
423
576
  Activity.prototype._discardRun = function discardRun() {
424
577
  const status = this.status;
425
578
  if (!status) return;
426
- const execution = this[kExec].get('execution');
579
+ const execution = this[K_EXEC].get('execution');
427
580
  if (execution && !execution.completed) return;
428
581
  let discardRoutingKey = 'run.discard';
429
582
  switch (status) {
@@ -439,51 +592,100 @@ Activity.prototype._discardRun = function discardRun() {
439
592
  return;
440
593
  }
441
594
  this._deactivateRunConsumers();
442
- const stateMessage = this[kStateMessage];
595
+ const stateMessage = this[_constants.K_STATE_MESSAGE];
443
596
  if (this.extensions) this.extensions.deactivate((0, _messageHelper.cloneMessage)(stateMessage));
444
597
  const broker = this.broker;
445
598
  broker.getQueue('run-q').purge();
446
599
  broker.publish('run', discardRoutingKey, (0, _messageHelper.cloneContent)(stateMessage.content), {
447
600
  correlationId: stateMessage.properties.correlationId
448
601
  });
449
- this[kConsuming] = true;
602
+ this[_constants.K_CONSUMING] = true;
450
603
  this._consumeRunQ();
451
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 */
452
625
  Activity.prototype._shakeOutbound = function shakeOutbound(sourceMessage) {
453
626
  const message = (0, _messageHelper.cloneMessage)(sourceMessage);
454
- message.content.sequence = message.content.sequence || [];
455
- 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({
456
631
  id: this.id,
457
- type: this.type
632
+ type: this.type,
633
+ count: looped ? looped.count + 1 : count
458
634
  });
459
- const broker = this.broker;
460
635
  this.broker.publish('api', 'activity.shake.start', message.content, {
461
636
  persistent: false,
462
637
  type: 'shake'
463
638
  });
464
- if (this[kFlags].isEnd) {
465
- 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), {
466
663
  persistent: false,
467
664
  type: 'shake'
468
665
  });
469
666
  }
470
- 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);
471
675
  };
676
+
677
+ /** @internal */
472
678
  Activity.prototype._consumeInbound = function consumeInbound() {
473
- if (!this[kActivated]) return;
474
- if (this.status) return;
679
+ if (!this[_constants.K_ACTIVATED]) return;
680
+ if (this.status || !this._getInboundTriggers().length) return;
475
681
  const inboundQ = this.broker.getQueue('inbound-q');
476
- const onInbound = this[kMessageHandlers].onInbound;
477
- if (this[kFlags].isParallelJoin) {
478
- return inboundQ.consume(onInbound, {
479
- consumerTag: '_run-on-inbound',
480
- prefetch: 1000
481
- });
482
- }
483
- return inboundQ.consume(onInbound, {
682
+ const onInbound = this[_constants.K_MESSAGE_HANDLERS].onInbound;
683
+ return inboundQ.assertConsumer(onInbound, {
484
684
  consumerTag: '_run-on-inbound'
485
685
  });
486
686
  };
687
+
688
+ /** @internal */
487
689
  Activity.prototype._onInbound = function onInbound(routingKey, message) {
488
690
  message.ack();
489
691
  const broker = this.broker;
@@ -491,6 +693,12 @@ Activity.prototype._onInbound = function onInbound(routingKey, message) {
491
693
  const content = message.content;
492
694
  const inbound = [(0, _messageHelper.cloneContent)(content)];
493
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
+ });
494
702
  case 'association.take':
495
703
  case 'flow.take':
496
704
  case 'activity.restart':
@@ -499,67 +707,16 @@ Activity.prototype._onInbound = function onInbound(routingKey, message) {
499
707
  message: content.message,
500
708
  inbound
501
709
  });
502
- case 'flow.discard':
503
710
  case 'activity.discard':
504
711
  {
505
- let discardSequence;
506
- if (content.discardSequence) discardSequence = content.discardSequence.slice();
507
712
  return this._runDiscard({
508
- inbound,
509
- discardSequence
713
+ inbound
510
714
  });
511
715
  }
512
716
  }
513
717
  };
514
- Activity.prototype._onJoinInbound = function onJoinInbound(routingKey, message) {
515
- const {
516
- content
517
- } = message;
518
- const {
519
- inboundJoinFlows,
520
- inboundSourceIds
521
- } = this[kFlows];
522
- let alreadyTouched = false;
523
- const touched = new Set();
524
- let taken;
525
- for (const msg of inboundJoinFlows) {
526
- const sourceId = msg.content.sourceId;
527
- touched.add(sourceId);
528
- if (sourceId === content.sourceId) {
529
- alreadyTouched = true;
530
- }
531
- }
532
- inboundJoinFlows.add(message);
533
- if (alreadyTouched) return;
534
- const remaining = inboundSourceIds.size - touched.size - 1;
535
- if (remaining) {
536
- return this.logger.debug(`<${this.id}> inbound ${message.content.action} from <${message.content.id}>, ${remaining} remaining`);
537
- }
538
- const inbound = [];
539
- for (const im of inboundJoinFlows) {
540
- if (im.fields.routingKey === 'flow.take') taken = true;
541
- im.ack();
542
- inbound.push((0, _messageHelper.cloneContent)(im.content));
543
- }
544
- const discardSequence = new Set();
545
- if (!taken) {
546
- for (const im of inboundJoinFlows) {
547
- if (!im.content.discardSequence) continue;
548
- for (const sourceId of im.content.discardSequence) {
549
- discardSequence.add(sourceId);
550
- }
551
- }
552
- }
553
- inboundJoinFlows.clear();
554
- this.broker.cancel('_run-on-inbound');
555
- if (!taken) return this._runDiscard({
556
- inbound,
557
- discardSequence: [...discardSequence]
558
- });
559
- return this.run({
560
- inbound
561
- });
562
- };
718
+
719
+ /** @internal */
563
720
  Activity.prototype._onInboundEvent = function onInboundEvent(routingKey, message) {
564
721
  const {
565
722
  fields,
@@ -571,36 +728,65 @@ Activity.prototype._onInboundEvent = function onInboundEvent(routingKey, message
571
728
  case 'activity.enter':
572
729
  case 'activity.discard':
573
730
  {
574
- if (content.id === this[kFlags].attachedTo) {
731
+ if (content.id === this[K_FLAGS].attachedTo) {
575
732
  inboundQ.queueMessage(fields, (0, _messageHelper.cloneContent)(content), properties);
576
733
  }
577
734
  break;
578
735
  }
579
736
  case 'flow.shake':
737
+ case 'activity.shake.start':
738
+ return this._onShakeMessage(message);
739
+ case 'activity.link':
580
740
  {
581
- 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;
582
763
  }
583
764
  case 'association.take':
584
765
  case 'flow.take':
585
- case 'flow.discard':
586
766
  return inboundQ.queueMessage(fields, (0, _messageHelper.cloneContent)(content), properties);
587
767
  }
588
768
  };
769
+
770
+ /** @internal */
589
771
  Activity.prototype._consumeRunQ = function consumeRunQ() {
590
- this[kConsumingRunQ] = true;
591
- 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, {
592
774
  exclusive: true,
593
775
  consumerTag: '_activity-run'
594
776
  });
595
777
  };
778
+
779
+ /** @internal */
596
780
  Activity.prototype._pauseRunQ = function pauseRunQ() {
597
- if (!this[kConsumingRunQ]) return;
598
- this[kConsumingRunQ] = false;
781
+ if (!this[K_CONSUMING_RUN_Q]) return;
782
+ this[K_CONSUMING_RUN_Q] = false;
599
783
  this.broker.cancel('_activity-run');
600
784
  };
785
+
786
+ /** @internal */
601
787
  Activity.prototype._onRunMessage = function onRunMessage(routingKey, message, messageProperties) {
602
788
  switch (routingKey) {
603
- case 'run.outbound.discard':
789
+ case 'run.execute.passthrough':
604
790
  case 'run.outbound.take':
605
791
  case 'run.next':
606
792
  return this._continueRunMessage(routingKey, message, messageProperties);
@@ -620,20 +806,22 @@ Activity.prototype._onRunMessage = function onRunMessage(routingKey, message, me
620
806
  this._continueRunMessage(routingKey, message, messageProperties);
621
807
  });
622
808
  };
809
+
810
+ /** @internal */
623
811
  Activity.prototype._continueRunMessage = function continueRunMessage(routingKey, message) {
624
812
  const isRedelivered = message.fields.redelivered;
625
813
  const content = (0, _messageHelper.cloneContent)(message.content);
626
814
  const correlationId = message.properties.correlationId;
627
815
  const id = this.id;
628
816
  const step = this.environment.settings.step;
629
- this[kStateMessage] = message;
817
+ this[_constants.K_STATE_MESSAGE] = message;
630
818
  switch (routingKey) {
631
819
  case 'run.enter':
632
820
  {
633
821
  this.logger.debug(`<${id}> enter`, isRedelivered ? 'redelivered' : '');
634
822
  this.status = 'entered';
635
823
  if (!isRedelivered) {
636
- this[kExec].delete('execution');
824
+ this[K_EXEC].delete('execution');
637
825
  if (this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message));
638
826
  this._publishEvent('enter', content, {
639
827
  correlationId
@@ -645,7 +833,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
645
833
  {
646
834
  this.logger.debug(`<${id}> discard`, isRedelivered ? 'redelivered' : '');
647
835
  this.status = 'discard';
648
- this[kExec].delete('execution');
836
+ this[K_EXEC].delete('execution');
649
837
  if (this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message));
650
838
  if (!isRedelivered) {
651
839
  this.broker.publish('run', 'run.discarded', content, {
@@ -671,25 +859,25 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
671
859
  }
672
860
  case 'run.execute.passthrough':
673
861
  {
674
- const execution = this[kExec].get('execution');
862
+ const execution = this[K_EXEC].get('execution');
675
863
  if (!isRedelivered && execution) {
676
864
  if (execution.completed) return message.ack();
677
- this[kExecuteMessage] = message;
865
+ this[_constants.K_EXECUTE_MESSAGE] = message;
678
866
  return execution.passthrough(message);
679
867
  }
680
868
  }
681
869
  case 'run.execute':
682
870
  {
683
871
  this.status = 'executing';
684
- this[kExecuteMessage] = message;
872
+ this[_constants.K_EXECUTE_MESSAGE] = message;
685
873
  if (isRedelivered && this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message));
686
- const exec = this[kExec];
874
+ const exec = this[K_EXEC];
687
875
  let execution = exec.get('execution');
688
876
  if (!execution) {
689
- execution = new _ActivityExecution.default(this, this.context);
877
+ execution = new _ActivityExecution.ActivityExecution(this, this.context);
690
878
  exec.set('execution', execution);
691
879
  }
692
- this.broker.getQueue('execution-q').assertConsumer(this[kMessageHandlers].onExecutionMessage, {
880
+ this.broker.getQueue('execution-q').assertConsumer(this[_constants.K_MESSAGE_HANDLERS].onExecutionMessage, {
693
881
  exclusive: true,
694
882
  consumerTag: '_activity-execution'
695
883
  });
@@ -699,7 +887,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
699
887
  {
700
888
  this.logger.debug(`<${id}> end`, isRedelivered ? 'redelivered' : '');
701
889
  if (isRedelivered) break;
702
- this[kCounters].taken++;
890
+ this[_constants.K_COUNTERS].taken++;
703
891
  this.status = 'end';
704
892
  return this._doRunLeave(message, false, () => {
705
893
  this._publishEvent('end', content, {
@@ -721,7 +909,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
721
909
  case 'run.discarded':
722
910
  {
723
911
  this.logger.debug(`<${content.executionId} (${id})> discarded`);
724
- this[kCounters].discarded++;
912
+ this[_constants.K_COUNTERS].discarded++;
725
913
  this.status = 'discarded';
726
914
  content.outbound = undefined;
727
915
  if (!isRedelivered) {
@@ -737,12 +925,6 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
737
925
  message.ack();
738
926
  return flow.take(content.flow);
739
927
  }
740
- case 'run.outbound.discard':
741
- {
742
- const flow = this._getOutboundSequenceFlowById(content.flow.id);
743
- message.ack();
744
- return flow.discard(content.flow);
745
- }
746
928
  case 'run.leave':
747
929
  {
748
930
  this.status = undefined;
@@ -764,8 +946,10 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
764
946
  }
765
947
  if (!step) message.ack();
766
948
  };
949
+
950
+ /** @internal */
767
951
  Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey, message) {
768
- const executeMessage = this[kExecuteMessage];
952
+ const executeMessage = this[_constants.K_EXECUTE_MESSAGE];
769
953
  const content = (0, _messageHelper.cloneContent)({
770
954
  ...executeMessage.content,
771
955
  ...message.content,
@@ -782,7 +966,7 @@ Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey,
782
966
  switch (routingKey) {
783
967
  case 'execution.outbound.take':
784
968
  {
785
- return this._doOutbound(message, false, (err, outbound) => {
969
+ return this._doOutbound(message, (err, outbound) => {
786
970
  message.ack();
787
971
  if (err) return this.emitFatal(err, content);
788
972
  broker.publish('run', 'run.execute.passthrough', (0, _messageHelper.cloneContent)(content, {
@@ -804,11 +988,13 @@ Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey,
804
988
  }
805
989
  case 'execution.cancel':
806
990
  case 'execution.discard':
807
- this.status = 'discarded';
808
- broker.publish('run', 'run.discarded', content, {
809
- correlationId
810
- });
811
- break;
991
+ {
992
+ this.status = 'discarded';
993
+ broker.publish('run', 'run.discarded', content, {
994
+ correlationId
995
+ });
996
+ break;
997
+ }
812
998
  default:
813
999
  {
814
1000
  this.status = 'executed';
@@ -820,24 +1006,28 @@ Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey,
820
1006
  message.ack();
821
1007
  this._ackRunExecuteMessage();
822
1008
  };
1009
+
1010
+ /** @internal */
823
1011
  Activity.prototype._ackRunExecuteMessage = function ackRunExecuteMessage() {
824
1012
  if (this.environment.settings.step) return;
825
- const executeMessage = this[kExecuteMessage];
1013
+ const executeMessage = this[_constants.K_EXECUTE_MESSAGE];
826
1014
  executeMessage.ack();
827
1015
  };
1016
+
1017
+ /** @internal */
828
1018
  Activity.prototype._doRunLeave = function doRunLeave(message, isDiscarded, onOutbound) {
829
1019
  const {
830
1020
  content,
831
1021
  properties
832
1022
  } = message;
833
1023
  const correlationId = properties.correlationId;
834
- if (content.ignoreOutbound) {
1024
+ if (isDiscarded || content.ignoreOutbound) {
835
1025
  this.broker.publish('run', 'run.leave', (0, _messageHelper.cloneContent)(content), {
836
1026
  correlationId
837
1027
  });
838
1028
  return onOutbound();
839
1029
  }
840
- return this._doOutbound((0, _messageHelper.cloneMessage)(message), isDiscarded, (err, outbound) => {
1030
+ return this._doOutbound((0, _messageHelper.cloneMessage)(message), (err, outbound) => {
841
1031
  if (err) {
842
1032
  return this._publishEvent('error', {
843
1033
  ...content,
@@ -856,35 +1046,31 @@ Activity.prototype._doRunLeave = function doRunLeave(message, isDiscarded, onOut
856
1046
  onOutbound();
857
1047
  });
858
1048
  };
859
- Activity.prototype._doOutbound = function doOutbound(fromMessage, isDiscarded, callback) {
860
- const outboundSequenceFlows = this[kFlows].outboundSequenceFlows;
1049
+
1050
+ /** @internal */
1051
+ Activity.prototype._doOutbound = function doOutbound(fromMessage, callback) {
1052
+ const outboundSequenceFlows = this[K_FLOWS].outboundSequenceFlows;
861
1053
  if (!outboundSequenceFlows.length) return callback(null, []);
862
1054
  const fromContent = fromMessage.content;
863
- let discardSequence = fromContent.discardSequence;
864
- if (isDiscarded && !discardSequence && this[kFlags].attachedTo && fromContent.inbound?.[0]) {
865
- discardSequence = [fromContent.inbound[0].id];
866
- }
867
1055
  let outboundFlows;
868
- if (isDiscarded) {
869
- outboundFlows = outboundSequenceFlows.map(flow => (0, _outboundEvaluator.formatFlowAction)(flow, {
870
- action: 'discard'
871
- }));
872
- } else if (fromContent.outbound?.length) {
1056
+ if (fromContent.outbound?.length) {
873
1057
  outboundFlows = outboundSequenceFlows.map(flow => (0, _outboundEvaluator.formatFlowAction)(flow, fromContent.outbound.filter(f => f.id === flow.id).pop()));
874
1058
  }
875
1059
  if (outboundFlows) {
876
- this._doRunOutbound(outboundFlows, fromContent, discardSequence);
1060
+ this._doRunOutbound(outboundFlows, fromContent);
877
1061
  return callback(null, outboundFlows);
878
1062
  }
879
1063
  return this.evaluateOutbound(fromMessage, fromContent.outboundTakeOne, (err, evaluatedOutbound) => {
880
1064
  if (err) return callback(new _Errors.ActivityError(err.message, fromMessage, err));
881
- const outbound = this._doRunOutbound(evaluatedOutbound, fromContent, discardSequence);
1065
+ const outbound = this._doRunOutbound(evaluatedOutbound, fromContent);
882
1066
  return callback(null, outbound);
883
1067
  });
884
1068
  };
885
- Activity.prototype._doRunOutbound = function doRunOutbound(outboundList, content, discardSequence) {
1069
+
1070
+ /** @internal */
1071
+ Activity.prototype._doRunOutbound = function doRunOutbound(outboundList, content) {
886
1072
  if (outboundList.length === 1) {
887
- this._publishRunOutbound(outboundList[0], content, discardSequence);
1073
+ this._publishRunOutbound(outboundList[0], content);
888
1074
  } else {
889
1075
  const targets = new Map();
890
1076
  for (const outboundFlow of outboundList) {
@@ -896,31 +1082,35 @@ Activity.prototype._doRunOutbound = function doRunOutbound(outboundList, content
896
1082
  }
897
1083
  }
898
1084
  for (const outboundFlow of targets.values()) {
899
- this._publishRunOutbound(outboundFlow, content, discardSequence);
1085
+ this._publishRunOutbound(outboundFlow, content);
900
1086
  }
901
1087
  }
902
1088
  return outboundList;
903
1089
  };
904
- Activity.prototype._publishRunOutbound = function publishRunOutbound(outboundFlow, content, discardSequence) {
1090
+
1091
+ /** @internal */
1092
+ Activity.prototype._publishRunOutbound = function publishRunOutbound(outboundFlow, content) {
905
1093
  const {
906
1094
  id: flowId,
907
1095
  action,
908
1096
  result
909
1097
  } = outboundFlow;
1098
+ if (action === 'discard') {
1099
+ return;
1100
+ }
910
1101
  this.broker.publish('run', 'run.outbound.' + action, (0, _messageHelper.cloneContent)(content, {
911
1102
  flow: {
912
1103
  ...(result && typeof result === 'object' && result),
913
1104
  ...outboundFlow,
914
- sequenceId: (0, _shared.getUniqueId)(`${flowId}_${action}`),
915
- ...(discardSequence && {
916
- discardSequence: discardSequence.slice()
917
- })
1105
+ sequenceId: (0, _shared.getUniqueId)(`${flowId}_${action}`)
918
1106
  }
919
1107
  }));
920
1108
  };
1109
+
1110
+ /** @internal */
921
1111
  Activity.prototype._onResumeMessage = function onResumeMessage(message) {
922
1112
  message.ack();
923
- const stateMessage = this[kStateMessage];
1113
+ const stateMessage = this[_constants.K_STATE_MESSAGE];
924
1114
  const fields = stateMessage.fields;
925
1115
  if (!fields.redelivered) return;
926
1116
  switch (fields.routingKey) {
@@ -937,6 +1127,8 @@ Activity.prototype._onResumeMessage = function onResumeMessage(message) {
937
1127
  this.logger.debug(`<${this.id}> resume from ${message.content.status}`);
938
1128
  return this.broker.publish('run', fields.routingKey, (0, _messageHelper.cloneContent)(stateMessage.content), stateMessage.properties);
939
1129
  };
1130
+
1131
+ /** @internal */
940
1132
  Activity.prototype._publishEvent = function publishEvent(state, content, properties) {
941
1133
  this.broker.publish('event', `activity.${state}`, (0, _messageHelper.cloneContent)(content, {
942
1134
  state
@@ -946,10 +1138,12 @@ Activity.prototype._publishEvent = function publishEvent(state, content, propert
946
1138
  mandatory: state === 'error'
947
1139
  });
948
1140
  };
1141
+
1142
+ /** @internal */
949
1143
  Activity.prototype._onStop = function onStop(message) {
950
- const running = this[kConsuming];
1144
+ const running = this[_constants.K_CONSUMING];
951
1145
  this.stopped = true;
952
- this[kConsuming] = false;
1146
+ this[_constants.K_CONSUMING] = false;
953
1147
  const broker = this.broker;
954
1148
  this._pauseRunQ();
955
1149
  broker.cancel('_activity-api');
@@ -963,17 +1157,21 @@ Activity.prototype._onStop = function onStop(message) {
963
1157
  });
964
1158
  }
965
1159
  };
1160
+
1161
+ /** @internal */
966
1162
  Activity.prototype._consumeApi = function consumeApi() {
967
- const executionId = this[kExec].get('executionId');
1163
+ const executionId = this[K_EXEC].get('executionId');
968
1164
  if (!executionId) return;
969
1165
  const broker = this.broker;
970
1166
  broker.cancel('_activity-api');
971
- broker.subscribeTmp('api', `activity.*.${executionId}`, this[kMessageHandlers].onApiMessage, {
1167
+ broker.subscribeTmp('api', `activity.*.${executionId}`, this[_constants.K_MESSAGE_HANDLERS].onApiMessage, {
972
1168
  noAck: true,
973
1169
  consumerTag: '_activity-api',
974
1170
  priority: 100
975
1171
  });
976
1172
  };
1173
+
1174
+ /** @internal */
977
1175
  Activity.prototype._onApiMessage = function onApiMessage(routingKey, message) {
978
1176
  switch (message.properties.type) {
979
1177
  case 'discard':
@@ -990,6 +1188,8 @@ Activity.prototype._onApiMessage = function onApiMessage(routingKey, message) {
990
1188
  }
991
1189
  }
992
1190
  };
1191
+
1192
+ /** @internal */
993
1193
  Activity.prototype._createMessage = function createMessage(override) {
994
1194
  const {
995
1195
  name,
@@ -1010,18 +1210,22 @@ Activity.prototype._createMessage = function createMessage(override) {
1010
1210
  parent: (0, _messageHelper.cloneParent)(parent)
1011
1211
  })
1012
1212
  };
1013
- for (const [flag, value] of Object.entries(this[kFlags])) {
1213
+ for (const [flag, value] of Object.entries(this[K_FLAGS])) {
1014
1214
  if (value) result[flag] = value;
1015
1215
  }
1016
1216
  return result;
1017
1217
  };
1218
+
1219
+ /** @internal */
1018
1220
  Activity.prototype._getOutboundSequenceFlowById = function getOutboundSequenceFlowById(flowId) {
1019
- return this[kFlows].outboundSequenceFlows.find(flow => flow.id === flowId);
1221
+ return this[K_FLOWS].outboundSequenceFlows.find(flow => flow.id === flowId);
1020
1222
  };
1223
+
1224
+ /** @internal */
1021
1225
  Activity.prototype._deactivateRunConsumers = function _deactivateRunConsumers() {
1022
1226
  const broker = this.broker;
1023
1227
  broker.cancel('_activity-api');
1024
1228
  this._pauseRunQ();
1025
1229
  broker.cancel('_activity-execution');
1026
- this[kConsuming] = false;
1230
+ this[_constants.K_CONSUMING] = false;
1027
1231
  };