bpmn-elements 6.0.1 → 8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/CHANGELOG.md +341 -0
  2. package/README.md +3 -0
  3. package/dist/index.js +52 -44
  4. package/dist/src/Api.js +77 -76
  5. package/dist/src/Context.js +176 -172
  6. package/dist/src/Environment.js +110 -102
  7. package/dist/src/EventBroker.js +89 -88
  8. package/dist/src/ExtensionsMapper.js +2 -2
  9. package/dist/src/MessageFormatter.js +164 -95
  10. package/dist/src/Scripts.js +6 -2
  11. package/dist/src/activity/Activity.js +1105 -916
  12. package/dist/src/activity/ActivityExecution.js +342 -297
  13. package/dist/src/activity/Dummy.js +3 -3
  14. package/dist/src/definition/Definition.js +498 -444
  15. package/dist/src/definition/DefinitionExecution.js +710 -408
  16. package/dist/src/error/Errors.js +17 -7
  17. package/dist/src/eventDefinitions/CancelEventDefinition.js +190 -150
  18. package/dist/src/eventDefinitions/CompensateEventDefinition.js +194 -161
  19. package/dist/src/eventDefinitions/ConditionalEventDefinition.js +197 -135
  20. package/dist/src/eventDefinitions/ErrorEventDefinition.js +207 -165
  21. package/dist/src/eventDefinitions/EscalationEventDefinition.js +175 -141
  22. package/dist/src/eventDefinitions/EventDefinitionExecution.js +157 -129
  23. package/dist/src/eventDefinitions/LinkEventDefinition.js +174 -149
  24. package/dist/src/eventDefinitions/MessageEventDefinition.js +213 -176
  25. package/dist/src/eventDefinitions/SignalEventDefinition.js +203 -161
  26. package/dist/src/eventDefinitions/TerminateEventDefinition.js +21 -23
  27. package/dist/src/eventDefinitions/TimerEventDefinition.js +243 -228
  28. package/dist/src/events/BoundaryEvent.js +180 -144
  29. package/dist/src/events/EndEvent.js +18 -23
  30. package/dist/src/events/IntermediateCatchEvent.js +44 -58
  31. package/dist/src/events/IntermediateThrowEvent.js +18 -23
  32. package/dist/src/events/StartEvent.js +109 -94
  33. package/dist/src/flows/Association.js +94 -100
  34. package/dist/src/flows/MessageFlow.js +86 -103
  35. package/dist/src/flows/SequenceFlow.js +173 -182
  36. package/dist/src/gateways/EventBasedGateway.js +88 -84
  37. package/dist/src/gateways/ExclusiveGateway.js +13 -16
  38. package/dist/src/gateways/InclusiveGateway.js +11 -14
  39. package/dist/src/gateways/ParallelGateway.js +11 -14
  40. package/dist/src/getPropertyValue.js +34 -34
  41. package/dist/src/io/BpmnIO.js +17 -14
  42. package/dist/src/io/EnvironmentDataObject.js +33 -29
  43. package/dist/src/io/EnvironmentDataStore.js +33 -29
  44. package/dist/src/io/EnvironmentDataStoreReference.js +35 -31
  45. package/dist/src/io/InputOutputSpecification.js +177 -168
  46. package/dist/src/io/Properties.js +117 -124
  47. package/dist/src/messageHelper.js +1 -1
  48. package/dist/src/process/Process.js +439 -362
  49. package/dist/src/process/ProcessExecution.js +748 -646
  50. package/dist/src/shared.js +2 -2
  51. package/dist/src/tasks/CallActivity.js +160 -0
  52. package/dist/src/tasks/LoopCharacteristics.js +309 -330
  53. package/dist/src/tasks/ReceiveTask.js +233 -182
  54. package/dist/src/tasks/ScriptTask.js +35 -41
  55. package/dist/src/tasks/ServiceImplementation.js +13 -20
  56. package/dist/src/tasks/ServiceTask.js +82 -75
  57. package/dist/src/tasks/SignalTask.js +97 -93
  58. package/dist/src/tasks/StandardLoopCharacteristics.js +1 -1
  59. package/dist/src/tasks/SubProcess.js +193 -175
  60. package/dist/src/tasks/Task.js +17 -19
  61. package/index.js +2 -0
  62. package/package.json +16 -16
  63. package/src/Api.js +65 -59
  64. package/src/Context.js +145 -140
  65. package/src/Environment.js +116 -100
  66. package/src/EventBroker.js +67 -68
  67. package/src/ExtensionsMapper.js +2 -2
  68. package/src/MessageFormatter.js +132 -74
  69. package/src/activity/Activity.js +914 -776
  70. package/src/activity/ActivityExecution.js +293 -247
  71. package/src/activity/Dummy.js +2 -2
  72. package/src/definition/Definition.js +437 -401
  73. package/src/definition/DefinitionExecution.js +598 -340
  74. package/src/error/Errors.js +11 -6
  75. package/src/eventDefinitions/CancelEventDefinition.js +164 -121
  76. package/src/eventDefinitions/CompensateEventDefinition.js +159 -124
  77. package/src/eventDefinitions/ConditionalEventDefinition.js +147 -104
  78. package/src/eventDefinitions/ErrorEventDefinition.js +190 -131
  79. package/src/eventDefinitions/EscalationEventDefinition.js +139 -101
  80. package/src/eventDefinitions/EventDefinitionExecution.js +127 -95
  81. package/src/eventDefinitions/LinkEventDefinition.js +160 -129
  82. package/src/eventDefinitions/MessageEventDefinition.js +178 -121
  83. package/src/eventDefinitions/SignalEventDefinition.js +162 -106
  84. package/src/eventDefinitions/TerminateEventDefinition.js +19 -19
  85. package/src/eventDefinitions/TimerEventDefinition.js +202 -167
  86. package/src/events/BoundaryEvent.js +156 -115
  87. package/src/events/EndEvent.js +15 -18
  88. package/src/events/IntermediateCatchEvent.js +40 -44
  89. package/src/events/IntermediateThrowEvent.js +15 -18
  90. package/src/events/StartEvent.js +84 -50
  91. package/src/flows/Association.js +98 -112
  92. package/src/flows/MessageFlow.js +81 -97
  93. package/src/flows/SequenceFlow.js +146 -160
  94. package/src/gateways/EventBasedGateway.js +75 -68
  95. package/src/gateways/ExclusiveGateway.js +8 -13
  96. package/src/gateways/InclusiveGateway.js +8 -13
  97. package/src/gateways/ParallelGateway.js +8 -13
  98. package/src/getPropertyValue.js +34 -33
  99. package/src/io/BpmnIO.js +20 -15
  100. package/src/io/EnvironmentDataObject.js +29 -18
  101. package/src/io/EnvironmentDataStore.js +29 -18
  102. package/src/io/EnvironmentDataStoreReference.js +31 -20
  103. package/src/io/InputOutputSpecification.js +154 -157
  104. package/src/io/Properties.js +95 -97
  105. package/src/process/Process.js +378 -333
  106. package/src/process/ProcessExecution.js +603 -553
  107. package/src/tasks/CallActivity.js +130 -0
  108. package/src/tasks/LoopCharacteristics.js +290 -289
  109. package/src/tasks/ReceiveTask.js +174 -107
  110. package/src/tasks/ScriptTask.js +27 -30
  111. package/src/tasks/ServiceImplementation.js +13 -18
  112. package/src/tasks/ServiceTask.js +67 -60
  113. package/src/tasks/SignalTask.js +77 -52
  114. package/src/tasks/StandardLoopCharacteristics.js +1 -1
  115. package/src/tasks/SubProcess.js +184 -157
  116. package/src/tasks/Task.js +15 -19
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = Activity;
6
+ exports.default = void 0;
7
7
 
8
8
  var _ActivityExecution = _interopRequireDefault(require("./ActivityExecution"));
9
9
 
@@ -23,35 +23,49 @@ var _Errors = require("../error/Errors");
23
23
 
24
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
25
 
26
+ const kActivityDef = Symbol.for('activityDefinition');
27
+ const kBpmnIo = Symbol.for('bpmnIo');
28
+ const kConsuming = Symbol.for('consuming');
29
+ const kCounters = Symbol.for('counters');
30
+ const kEventDefinitions = Symbol.for('eventDefinitions');
31
+ const kExec = Symbol.for('exec');
32
+ const kExecuteMessage = Symbol.for('executeMessage');
33
+ const kExtensions = Symbol.for('extensions');
34
+ const kFlags = Symbol.for('flags');
35
+ const kFlows = Symbol.for('flows');
36
+ const kFormatter = Symbol.for('formatter');
37
+ const kMessageHandlers = Symbol.for('messageHandlers');
38
+ const kStateMessage = Symbol.for('stateMessage');
39
+ var _default = Activity;
40
+ exports.default = _default;
41
+
26
42
  function Activity(Behaviour, activityDef, context) {
27
43
  const {
28
44
  id,
29
45
  type = 'activity',
30
46
  name,
31
- parent: originalParent = {},
32
- behaviour = {},
33
- isParallelGateway,
34
- isSubProcess,
35
- triggeredByEvent,
36
- isThrowing,
37
- isTransaction
47
+ behaviour = {}
38
48
  } = activityDef;
39
- const isForCompensation = behaviour.isForCompensation;
40
- const parent = (0, _messageHelper.cloneParent)(originalParent);
41
- const {
42
- environment,
43
- getInboundSequenceFlows,
44
- getOutboundSequenceFlows,
45
- getInboundAssociations
46
- } = context;
47
- const logger = environment.Logger(type.toLowerCase());
48
- const {
49
- step
50
- } = environment.settings;
51
49
  const {
52
50
  attachedTo: attachedToRef,
53
51
  eventDefinitions
54
52
  } = behaviour;
53
+ this[kActivityDef] = activityDef;
54
+ this.id = id;
55
+ this.type = type;
56
+ this.name = name;
57
+ this.behaviour = { ...behaviour,
58
+ eventDefinitions
59
+ };
60
+ this.Behaviour = Behaviour;
61
+ this.parent = activityDef.parent ? (0, _messageHelper.cloneParent)(activityDef.parent) : {};
62
+ this.logger = context.environment.Logger(type.toLowerCase());
63
+ this.environment = context.environment;
64
+ this.context = context;
65
+ this[kCounters] = {
66
+ taken: 0,
67
+ discarded: 0
68
+ };
55
69
  let attachedToActivity, attachedTo;
56
70
 
57
71
  if (attachedToRef) {
@@ -59,118 +73,67 @@ function Activity(Behaviour, activityDef, context) {
59
73
  attachedToActivity = context.getActivityById(attachedToRef.id);
60
74
  }
61
75
 
62
- const inboundSequenceFlows = getInboundSequenceFlows(id) || [];
63
- const outboundSequenceFlows = getOutboundSequenceFlows(id) || [];
64
- const inboundAssociations = getInboundAssociations(id) || [];
65
- const isStart = inboundSequenceFlows.length === 0 && !attachedTo && !triggeredByEvent && !isForCompensation;
66
- const isEnd = outboundSequenceFlows.length === 0;
67
- const isParallelJoin = inboundSequenceFlows.length > 1 && isParallelGateway;
68
- const isMultiInstance = !!behaviour.loopCharacteristics;
69
- let execution,
70
- initExecutionId,
71
- executionId,
72
- stateMessage,
73
- status,
74
- stopped = false,
75
- executeMessage,
76
- consumingRunQ;
77
- const inboundTriggers = attachedToActivity ? [attachedToActivity] : inboundSequenceFlows.slice();
78
- const inboundJoinFlows = [];
79
- let counters = {
80
- taken: 0,
81
- discarded: 0
82
- };
83
- const activityApi = {
84
- id,
85
- type,
86
- name,
87
- isEnd,
88
- isStart,
89
- isSubProcess,
90
- isThrowing,
91
- isForCompensation,
92
- triggeredByEvent,
93
- parent: (0, _messageHelper.cloneParent)(parent),
94
- behaviour: { ...behaviour,
95
- eventDefinitions
96
- },
97
- attachedTo: attachedToActivity,
98
- environment,
99
- inbound: inboundSequenceFlows,
100
- outbound: outboundSequenceFlows,
101
-
102
- get counters() {
103
- return { ...counters
104
- };
105
- },
106
-
107
- get executionId() {
108
- return executionId;
109
- },
110
-
111
- get status() {
112
- return status;
113
- },
114
-
115
- get stopped() {
116
- return stopped;
117
- },
118
-
119
- get isRunning() {
120
- if (!consumingRunQ) return false;
121
- return !!status;
122
- },
123
-
124
- Behaviour,
125
- activate,
126
- deactivate,
127
- evaluateOutbound,
128
- logger,
129
- discard,
130
- getApi,
131
- getActivityById,
132
- getState,
133
- init,
134
- recover,
135
- resume,
136
- run,
137
- shake,
138
- stop,
139
- next: step && next
140
- };
141
76
  const {
142
77
  broker,
143
78
  on,
144
79
  once,
145
80
  waitFor,
146
81
  emitFatal
147
- } = (0, _EventBroker.ActivityBroker)(activityApi);
148
- activityApi.on = on;
149
- activityApi.once = once;
150
- activityApi.waitFor = waitFor;
151
- activityApi.emitFatal = emitFatal;
152
- const runQ = broker.getQueue('run-q');
153
- const executionQ = broker.getQueue('execution-q');
154
- const inboundQ = broker.assertQueue('inbound-q', {
82
+ } = (0, _EventBroker.ActivityBroker)(this);
83
+ this.broker = broker;
84
+ this.on = on;
85
+ this.once = once;
86
+ this.waitFor = waitFor;
87
+ this.emitFatal = emitFatal;
88
+ const inboundSequenceFlows = context.getInboundSequenceFlows(id);
89
+ const inboundAssociations = context.getInboundAssociations(id);
90
+ const inboundTriggers = attachedToActivity ? [attachedToActivity] : inboundSequenceFlows.slice();
91
+ const outboundSequenceFlows = context.getOutboundSequenceFlows(id);
92
+ const flows = this[kFlows] = {
93
+ inboundSequenceFlows,
94
+ inboundAssociations,
95
+ inboundJoinFlows: [],
96
+ inboundTriggers,
97
+ outboundSequenceFlows,
98
+ outboundEvaluator: new OutboundEvaluator(this, outboundSequenceFlows)
99
+ };
100
+ const isForCompensation = !!behaviour.isForCompensation;
101
+ const isParallelJoin = activityDef.isParallelGateway && flows.inboundSequenceFlows.length > 1;
102
+ this[kFlags] = {
103
+ isEnd: flows.outboundSequenceFlows.length === 0,
104
+ isStart: flows.inboundSequenceFlows.length === 0 && !attachedTo && !behaviour.triggeredByEvent && !isForCompensation,
105
+ isSubProcess: activityDef.isSubProcess,
106
+ isMultiInstance: !!behaviour.loopCharacteristics,
107
+ isForCompensation,
108
+ attachedTo,
109
+ isTransaction: activityDef.isTransaction,
110
+ isParallelJoin,
111
+ isThrowing: activityDef.isThrowing
112
+ };
113
+ this[kExec] = {};
114
+ this[kMessageHandlers] = {
115
+ onInbound: isParallelJoin ? this._onJoinInbound.bind(this) : this._onInbound.bind(this),
116
+ onRunMessage: this._onRunMessage.bind(this),
117
+ onApiMessage: this._onApiMessage.bind(this),
118
+ onExecutionMessage: this._onExecutionMessage.bind(this)
119
+ };
120
+
121
+ const onInboundEvent = this._onInboundEvent.bind(this);
122
+
123
+ broker.assertQueue('inbound-q', {
155
124
  durable: true,
156
125
  autoDelete: false
157
126
  });
158
- const formatRunQ = broker.getQueue('format-run-q');
159
- const formatter = (0, _MessageFormatter.Formatter)({
160
- id,
161
- broker,
162
- logger
163
- }, formatRunQ);
164
127
 
165
128
  if (isForCompensation) {
166
- inboundAssociations.forEach(trigger => {
129
+ for (const trigger of inboundAssociations) {
167
130
  trigger.broker.subscribeTmp('event', '#', onInboundEvent, {
168
131
  noAck: true,
169
132
  consumerTag: `_inbound-${id}`
170
133
  });
171
- });
134
+ }
172
135
  } else {
173
- inboundTriggers.forEach(trigger => {
136
+ for (const trigger of inboundTriggers) {
174
137
  if (trigger.isSequenceFlow) trigger.broker.subscribeTmp('event', 'flow.#', onInboundEvent, {
175
138
  noAck: true,
176
139
  consumerTag: `_inbound-${id}`
@@ -178,969 +141,1195 @@ function Activity(Behaviour, activityDef, context) {
178
141
  noAck: true,
179
142
  consumerTag: `_inbound-${id}`
180
143
  });
181
- });
144
+ }
182
145
  }
183
146
 
184
- Object.defineProperty(activityApi, 'broker', {
185
- enumerable: true,
186
- get: () => broker
187
- });
188
- Object.defineProperty(activityApi, 'execution', {
189
- enumerable: true,
190
- get: () => execution
191
- });
192
- const bpmnIo = (0, _BpmnIO.default)(activityApi, context);
193
- const loaedEventDefinitions = eventDefinitions && eventDefinitions.map(ed => ed.Behaviour(activityApi, ed, context));
194
- Object.defineProperty(activityApi, 'eventDefinitions', {
195
- enumerable: true,
196
- get: () => loaedEventDefinitions
197
- });
198
- const extensions = context.loadExtensions(activityApi);
199
- Object.defineProperty(activityApi, 'extensions', {
200
- enumerable: true,
201
- get: () => extensions
202
- });
203
- return activityApi;
147
+ this[kEventDefinitions] = eventDefinitions && eventDefinitions.map(ed => new ed.Behaviour(this, ed, this.context));
148
+ }
204
149
 
205
- function init(initContent) {
206
- initExecutionId = initExecutionId || (0, _shared.getUniqueId)(id);
207
- logger.debug(`<${id}> initialized with executionId <${initExecutionId}>`);
208
- publishEvent('init', createMessage({ ...initContent,
209
- executionId: initExecutionId
210
- }));
150
+ const proto = Activity.prototype;
151
+ Object.defineProperty(proto, 'counters', {
152
+ enumerable: true,
153
+
154
+ get() {
155
+ return { ...this[kCounters]
156
+ };
211
157
  }
212
158
 
213
- function run(runContent) {
214
- if (activityApi.isRunning) throw new Error(`activity <${id}> is already running`);
215
- executionId = initExecutionId || (0, _shared.getUniqueId)(id);
216
- initExecutionId = undefined;
217
- consumeApi();
218
- const content = createMessage({ ...runContent,
219
- executionId
220
- });
221
- broker.publish('run', 'run.enter', content);
222
- broker.publish('run', 'run.start', (0, _messageHelper.cloneContent)(content));
223
- consumeRunQ();
159
+ });
160
+ Object.defineProperty(proto, 'execution', {
161
+ enumerable: true,
162
+
163
+ get() {
164
+ return this[kExec].execution;
224
165
  }
225
166
 
226
- function createMessage(override = {}) {
227
- const result = { ...override,
228
- id,
229
- type,
230
- ...(name ? {
231
- name
232
- } : undefined),
233
- ...(status ? {
234
- status
235
- } : undefined),
236
- parent: (0, _messageHelper.cloneParent)(parent)
237
- };
238
- const flags = {
239
- isEnd,
240
- isStart,
241
- isSubProcess,
242
- isMultiInstance,
243
- isForCompensation,
244
- attachedTo,
245
- isTransaction
246
- };
167
+ });
168
+ Object.defineProperty(proto, 'executionId', {
169
+ enumerable: true,
247
170
 
248
- for (const flag in flags) {
249
- if (flags[flag]) result[flag] = flags[flag];
250
- }
171
+ get() {
172
+ return this[kExec].executionId;
173
+ }
251
174
 
252
- return result;
175
+ });
176
+ Object.defineProperty(proto, 'bpmnIo', {
177
+ enumerable: true,
178
+
179
+ get() {
180
+ if (kBpmnIo in this) return this[kBpmnIo];
181
+ const bpmnIo = this[kBpmnIo] = new _BpmnIO.default(this, this.context);
182
+ return bpmnIo;
253
183
  }
254
184
 
255
- function recover(state) {
256
- if (activityApi.isRunning) throw new Error(`cannot recover running activity <${id}>`);
257
- if (!state) return;
258
- stopped = state.stopped;
259
- status = state.status;
260
- executionId = state.executionId;
261
- counters = { ...counters,
262
- ...state.counters
263
- };
185
+ });
186
+ Object.defineProperty(proto, 'extensions', {
187
+ enumerable: true,
264
188
 
265
- if (state.execution) {
266
- execution = (0, _ActivityExecution.default)(activityApi, context).recover(state.execution);
267
- }
189
+ get() {
190
+ if (kExtensions in this) return this[kExtensions];
191
+ const extensions = this[kExtensions] = this.context.loadExtensions(this);
192
+ return extensions;
193
+ }
268
194
 
269
- broker.recover(state.broker);
270
- return activityApi;
195
+ });
196
+ Object.defineProperty(proto, 'formatter', {
197
+ enumerable: true,
198
+
199
+ get() {
200
+ let formatter = this[kFormatter];
201
+ if (formatter) return formatter;
202
+ const broker = this.broker;
203
+ formatter = this[kFormatter] = new _MessageFormatter.Formatter({
204
+ id: this.id,
205
+ broker,
206
+ logger: this.logger
207
+ }, broker.getQueue('format-run-q'));
208
+ return formatter;
271
209
  }
272
210
 
273
- function resume() {
274
- if (consumingRunQ) {
275
- throw new Error(`cannot resume running activity <${id}>`);
276
- }
211
+ });
212
+ Object.defineProperty(proto, 'isRunning', {
213
+ enumerable: true,
277
214
 
278
- if (!status) return activate();
279
- stopped = false;
280
- consumeApi();
281
- const content = createMessage({
282
- executionId
283
- });
284
- broker.publish('run', 'run.resume', content, {
285
- persistent: false
286
- });
287
- consumeRunQ();
215
+ get() {
216
+ if (!this[kConsuming]) return false;
217
+ return !!this.status;
288
218
  }
289
219
 
290
- function discard(discardContent) {
291
- if (!status) return runDiscard(discardContent);
292
- if (execution && !execution.completed) return execution.discard();
293
- deactivateRunConsumers();
294
- runQ.purge();
295
- broker.publish('run', 'run.discard', (0, _messageHelper.cloneContent)(stateMessage.content));
296
- consumeRunQ();
220
+ });
221
+ Object.defineProperty(proto, 'outbound', {
222
+ enumerable: true,
223
+
224
+ get() {
225
+ return this[kFlows].outboundSequenceFlows;
297
226
  }
298
227
 
299
- function discardRun() {
300
- if (!status) return;
301
- if (execution && !execution.completed) return;
228
+ });
229
+ Object.defineProperty(proto, 'inbound', {
230
+ enumerable: true,
231
+
232
+ get() {
233
+ return this[kFlows].inboundSequenceFlows;
234
+ }
302
235
 
303
- switch (status) {
304
- case 'executing':
305
- case 'error':
306
- case 'discarded':
307
- return;
308
- }
236
+ });
237
+ Object.defineProperty(proto, 'isEnd', {
238
+ enumerable: true,
309
239
 
310
- deactivateRunConsumers();
311
- if (extensions) extensions.deactivate();
312
- runQ.purge();
313
- broker.publish('run', 'run.discard', (0, _messageHelper.cloneContent)(stateMessage.content));
314
- consumeRunQ();
240
+ get() {
241
+ return this[kFlags].isEnd;
315
242
  }
316
243
 
317
- function runDiscard(discardContent = {}) {
318
- executionId = initExecutionId || (0, _shared.getUniqueId)(id);
319
- consumeApi();
320
- initExecutionId = undefined;
321
- const content = createMessage({ ...discardContent,
322
- executionId
323
- });
324
- broker.publish('run', 'run.discard', content);
325
- consumeRunQ();
244
+ });
245
+ Object.defineProperty(proto, 'isStart', {
246
+ enumerable: true,
247
+
248
+ get() {
249
+ return this[kFlags].isStart;
326
250
  }
327
251
 
328
- function stop() {
329
- if (!consumingRunQ) return;
330
- return getApi().stop();
252
+ });
253
+ Object.defineProperty(proto, 'isSubProcess', {
254
+ enumerable: true,
255
+
256
+ get() {
257
+ return this[kFlags].isSubProcess;
331
258
  }
332
259
 
333
- function onStop(message) {
334
- const running = consumingRunQ;
335
- stopped = true;
336
- consumingRunQ = false;
337
- broker.cancel('_activity-run');
338
- broker.cancel('_activity-api');
339
- broker.cancel('_activity-execution');
340
- broker.cancel('_run-on-inbound');
341
- broker.cancel('_format-consumer');
342
-
343
- if (running) {
344
- if (extensions) extensions.deactivate(message || createMessage());
345
- publishEvent('stop');
346
- }
260
+ });
261
+ Object.defineProperty(proto, 'isMultiInstance', {
262
+ enumerable: true,
263
+
264
+ get() {
265
+ return this[kFlags].isMultiInstance;
347
266
  }
348
267
 
349
- function activate() {
350
- if (isForCompensation) return;
351
- return consumeInbound();
268
+ });
269
+ Object.defineProperty(proto, 'isThrowing', {
270
+ enumerable: true,
271
+
272
+ get() {
273
+ return this[kFlags].isThrowing;
352
274
  }
353
275
 
354
- function deactivate() {
355
- broker.cancel('_run-on-inbound');
356
- broker.cancel('_format-consumer');
276
+ });
277
+ Object.defineProperty(proto, 'isForCompensation', {
278
+ enumerable: true,
279
+
280
+ get() {
281
+ return this[kFlags].isForCompensation;
357
282
  }
358
283
 
359
- function consumeRunQ() {
360
- if (consumingRunQ) return;
361
- consumingRunQ = true;
362
- runQ.assertConsumer(onRunMessage, {
363
- exclusive: true,
364
- consumerTag: '_activity-run'
365
- });
284
+ });
285
+ Object.defineProperty(proto, 'triggeredByEvent', {
286
+ enumerable: true,
287
+
288
+ get() {
289
+ return this[kActivityDef].triggeredByEvent;
366
290
  }
367
291
 
368
- function consumeApi() {
369
- if (!executionId) return;
370
- broker.cancel('_activity-api');
371
- broker.subscribeTmp('api', `activity.*.${executionId}`, onApiMessage, {
372
- noAck: true,
373
- consumerTag: '_activity-api',
374
- priority: 100
375
- });
292
+ });
293
+ Object.defineProperty(proto, 'attachedTo', {
294
+ enumerable: true,
295
+
296
+ get() {
297
+ const attachedToId = this[kFlags].attachedTo;
298
+ if (!attachedToId) return null;
299
+ return this.getActivityById(attachedToId);
376
300
  }
377
301
 
378
- function consumeInbound() {
379
- if (status) return;
302
+ });
303
+ Object.defineProperty(proto, 'eventDefinitions', {
304
+ enumerable: true,
380
305
 
381
- if (isParallelJoin) {
382
- return inboundQ.consume(onJoinInbound, {
383
- consumerTag: '_run-on-inbound',
384
- prefetch: 1000
385
- });
386
- }
306
+ get() {
307
+ return this[kEventDefinitions];
308
+ }
387
309
 
388
- return inboundQ.consume(onInbound, {
389
- consumerTag: '_run-on-inbound'
390
- });
310
+ });
311
+
312
+ proto.activate = function activate() {
313
+ if (this[kFlags].isForCompensation) return;
314
+ return this._consumeInbound();
315
+ };
316
+
317
+ proto.deactivate = function deactivate() {
318
+ const broker = this.broker;
319
+ broker.cancel('_run-on-inbound');
320
+ broker.cancel('_format-consumer');
321
+ };
322
+
323
+ proto.init = function init(initContent) {
324
+ const id = this.id;
325
+ const exec = this[kExec];
326
+ const executionId = exec.initExecutionId = exec.initExecutionId || (0, _shared.getUniqueId)(id);
327
+ this.logger.debug(`<${id}> initialized with executionId <${executionId}>`);
328
+
329
+ this._publishEvent('init', this._createMessage({ ...initContent,
330
+ executionId
331
+ }));
332
+ };
333
+
334
+ proto.run = function run(runContent) {
335
+ const id = this.id;
336
+ if (this.isRunning) throw new Error(`activity <${id}> is already running`);
337
+ const exec = this[kExec];
338
+ const executionId = exec.executionId = exec.initExecutionId || (0, _shared.getUniqueId)(id);
339
+ exec.initExecutionId = null;
340
+
341
+ this._consumeApi();
342
+
343
+ const content = this._createMessage({ ...runContent,
344
+ executionId
345
+ });
346
+
347
+ const broker = this.broker;
348
+ broker.publish('run', 'run.enter', content);
349
+ broker.publish('run', 'run.start', (0, _messageHelper.cloneContent)(content));
350
+
351
+ this._consumeRunQ();
352
+ };
353
+
354
+ proto.recover = function recover(state) {
355
+ if (this.isRunning) throw new Error(`cannot recover running activity <${this.id}>`);
356
+ if (!state) return;
357
+ this.stopped = state.stopped;
358
+ this.status = state.status;
359
+ const exec = this[kExec];
360
+ exec.executionId = state.executionId;
361
+ this[kCounters] = { ...this[kCounters],
362
+ ...state.counters
363
+ };
364
+
365
+ if (state.execution) {
366
+ exec.execution = new _ActivityExecution.default(this, this.context).recover(state.execution);
391
367
  }
392
368
 
393
- function deactivateRunConsumers() {
394
- broker.cancel('_activity-api');
395
- broker.cancel('_activity-run');
396
- broker.cancel('_activity-execution');
397
- consumingRunQ = false;
369
+ this.broker.recover(state.broker);
370
+ return this;
371
+ };
372
+
373
+ proto.resume = function resume() {
374
+ if (this[kConsuming]) {
375
+ throw new Error(`cannot resume running activity <${this.id}>`);
398
376
  }
399
377
 
400
- function onInboundEvent(routingKey, message) {
401
- const {
402
- fields,
403
- content,
404
- properties
405
- } = message;
406
-
407
- switch (routingKey) {
408
- case 'activity.enter':
409
- case 'activity.discard':
410
- {
411
- if (content.id === attachedToActivity.id) {
412
- inboundQ.queueMessage(fields, (0, _messageHelper.cloneContent)(content), properties);
413
- }
414
-
415
- break;
416
- }
378
+ if (!this.status) return this.activate();
379
+ this.stopped = false;
417
380
 
418
- case 'flow.shake':
419
- {
420
- shakeOutbound(message);
421
- break;
422
- }
381
+ this._consumeApi();
423
382
 
424
- case 'association.take':
425
- case 'flow.take':
426
- case 'flow.discard':
427
- inboundQ.queueMessage(fields, (0, _messageHelper.cloneContent)(content), properties);
428
- break;
383
+ const content = this._createMessage();
429
384
 
430
- case 'association.discard':
431
- {
432
- logger.debug(`<${id}> compensation discarded`);
433
- inboundQ.purge();
434
- break;
435
- }
385
+ this.broker.publish('run', 'run.resume', content, {
386
+ persistent: false
387
+ });
436
388
 
437
- case 'association.complete':
438
- {
439
- if (!isForCompensation) break;
440
- inboundQ.queueMessage(fields, (0, _messageHelper.cloneContent)(content), properties);
441
- const compensationId = `${(0, _shared.brokerSafeId)(id)}_${(0, _shared.brokerSafeId)(content.sequenceId)}`;
442
- publishEvent('compensation.start', createMessage({
443
- executionId: compensationId,
444
- placeholder: true
445
- }));
446
- logger.debug(`<${id}> start compensation with id <${compensationId}>`);
447
- consumeInbound();
448
- break;
449
- }
450
- }
389
+ this._consumeRunQ();
390
+ };
391
+
392
+ proto.discard = function discard(discardContent) {
393
+ if (!this.status) return this._runDiscard(discardContent);
394
+ const execution = this[kExec].execution;
395
+ if (execution && !execution.completed) return execution.discard();
396
+
397
+ this._deactivateRunConsumers();
398
+
399
+ const broker = this.broker;
400
+ broker.getQueue('run-q').purge();
401
+ broker.publish('run', 'run.discard', (0, _messageHelper.cloneContent)(this[kStateMessage].content));
402
+
403
+ this._consumeRunQ();
404
+ };
405
+
406
+ proto.stop = function stop() {
407
+ if (!this[kConsuming]) return;
408
+ return this.getApi().stop();
409
+ };
410
+
411
+ proto.next = function next() {
412
+ if (!this.environment.settings.step) return;
413
+ const stateMessage = this[kStateMessage];
414
+ if (!stateMessage) return;
415
+ if (this.status === 'executing') return false;
416
+ if (this.status === 'formatting') return false;
417
+ const current = stateMessage;
418
+ stateMessage.ack();
419
+ return current;
420
+ };
421
+
422
+ proto.shake = function shake() {
423
+ this._shakeOutbound({
424
+ content: this._createMessage()
425
+ });
426
+ };
427
+
428
+ proto.evaluateOutbound = function evaluateOutbound(fromMessage, discardRestAtTake, callback) {
429
+ return this[kFlows].outboundEvaluator.evaluate(fromMessage, discardRestAtTake, callback);
430
+ };
431
+
432
+ proto.getState = function getState() {
433
+ const msg = this._createMessage();
434
+
435
+ const exec = this[kExec];
436
+ return { ...msg,
437
+ executionId: exec.executionId,
438
+ stopped: this.stopped,
439
+ behaviour: { ...this.behaviour
440
+ },
441
+ counters: this.counters,
442
+ broker: this.broker.getState(true),
443
+ execution: exec.execution && exec.execution.getState()
444
+ };
445
+ };
446
+
447
+ proto.getApi = function getApi(message) {
448
+ const execution = this[kExec].execution;
449
+ if (execution && !execution.completed) return execution.getApi(message);
450
+ return (0, _Api.ActivityApi)(this.broker, message || this[kStateMessage]);
451
+ };
452
+
453
+ proto.getActivityById = function getActivityById(elementId) {
454
+ return this.context.getActivityById(elementId);
455
+ };
456
+
457
+ proto._runDiscard = function runDiscard(discardContent) {
458
+ const exec = this[kExec];
459
+ const executionId = exec.executionId = exec.initExecutionId || (0, _shared.getUniqueId)(this.id);
460
+ exec.initExecutionId = null;
461
+
462
+ this._consumeApi();
463
+
464
+ const content = this._createMessage({ ...discardContent,
465
+ executionId
466
+ });
467
+
468
+ this.broker.publish('run', 'run.discard', content);
469
+
470
+ this._consumeRunQ();
471
+ };
472
+
473
+ proto._discardRun = function discardRun() {
474
+ const status = this.status;
475
+ if (!status) return;
476
+ const execution = this[kExec].execution;
477
+ if (execution && !execution.completed) return;
478
+
479
+ switch (status) {
480
+ case 'executing':
481
+ case 'error':
482
+ case 'discarded':
483
+ return;
451
484
  }
452
485
 
453
- function onInbound(routingKey, message) {
454
- message.ack();
455
- broker.cancel('_run-on-inbound');
456
- const content = message.content;
457
- const inbound = [(0, _messageHelper.cloneContent)(content)];
458
-
459
- switch (routingKey) {
460
- case 'association.take':
461
- case 'flow.take':
462
- case 'activity.enter':
463
- run({
464
- message: content.message,
465
- inbound
466
- });
467
- break;
486
+ this._deactivateRunConsumers();
468
487
 
469
- case 'flow.discard':
470
- case 'activity.discard':
471
- {
472
- let discardSequence;
473
- if (content.discardSequence) discardSequence = content.discardSequence.slice();
474
- runDiscard({
475
- inbound,
476
- discardSequence
477
- });
478
- break;
479
- }
488
+ if (this.extensions) this.extensions.deactivate();
489
+ const broker = this.broker;
490
+ broker.getQueue('run-q').purge();
491
+ broker.publish('run', 'run.discard', (0, _messageHelper.cloneContent)(this[kStateMessage].content));
480
492
 
481
- case 'association.complete':
482
- {
483
- broker.cancel('_run-on-inbound');
484
- const compensationId = `${(0, _shared.brokerSafeId)(id)}_${(0, _shared.brokerSafeId)(content.sequenceId)}`;
485
- logger.debug(`<${id}> completed compensation with id <${compensationId}>`);
486
- publishEvent('compensation.end', createMessage({
487
- executionId: compensationId
488
- }));
489
- break;
490
- }
491
- }
493
+ this._consumeRunQ();
494
+ };
495
+
496
+ proto._shakeOutbound = function shakeOutbound(sourceMessage) {
497
+ const message = (0, _messageHelper.cloneMessage)(sourceMessage);
498
+ message.content.sequence = message.content.sequence || [];
499
+ message.content.sequence.push({
500
+ id: this.id,
501
+ type: this.type
502
+ });
503
+ const broker = this.broker;
504
+ this.broker.publish('api', 'activity.shake.start', message.content, {
505
+ persistent: false,
506
+ type: 'shake'
507
+ });
508
+
509
+ if (this[kFlags].isEnd) {
510
+ return broker.publish('event', 'activity.shake.end', message.content, {
511
+ persistent: false,
512
+ type: 'shake'
513
+ });
492
514
  }
493
515
 
494
- function onJoinInbound(routingKey, message) {
495
- const {
496
- content
497
- } = message;
498
- const idx = inboundJoinFlows.findIndex(msg => msg.content.id === content.id);
499
- inboundJoinFlows.push(message);
500
- if (idx > -1) return;
501
- const allTouched = inboundJoinFlows.length >= inboundTriggers.length;
502
-
503
- if (!allTouched) {
504
- const remaining = inboundSequenceFlows.filter((inb, i, list) => list.indexOf(inb) === i).length - inboundJoinFlows.length;
505
- return logger.debug(`<${id}> inbound ${message.content.action} from <${message.content.id}>, ${remaining} remaining`);
506
- }
516
+ for (const flow of this[kFlows].outboundSequenceFlows) flow.shake(message);
517
+ };
518
+
519
+ proto._consumeInbound = function consumeInbound() {
520
+ if (this.status) return;
521
+ const inboundQ = this.broker.getQueue('inbound-q');
507
522
 
508
- const evaluatedInbound = inboundJoinFlows.splice(0);
509
- let taken;
510
- const inbound = evaluatedInbound.map(im => {
511
- if (im.fields.routingKey === 'flow.take') taken = true;
512
- im.ack();
513
- return (0, _messageHelper.cloneContent)(im.content);
523
+ if (this[kFlags].isParallelJoin) {
524
+ return inboundQ.consume(this[kMessageHandlers].onInbound, {
525
+ consumerTag: '_run-on-inbound',
526
+ prefetch: 1000
514
527
  });
515
- const discardSequence = !taken && evaluatedInbound.reduce((result, im) => {
516
- if (!im.content.discardSequence) return result;
517
- im.content.discardSequence.forEach(sourceId => {
518
- if (result.indexOf(sourceId) === -1) result.push(sourceId);
528
+ }
529
+
530
+ return inboundQ.consume(this[kMessageHandlers].onInbound, {
531
+ consumerTag: '_run-on-inbound'
532
+ });
533
+ };
534
+
535
+ proto._onInbound = function onInbound(routingKey, message) {
536
+ message.ack();
537
+ const id = this.id;
538
+ const broker = this.broker;
539
+ broker.cancel('_run-on-inbound');
540
+ const content = message.content;
541
+ const inbound = [(0, _messageHelper.cloneContent)(content)];
542
+
543
+ switch (routingKey) {
544
+ case 'association.take':
545
+ case 'flow.take':
546
+ case 'activity.enter':
547
+ return this.run({
548
+ message: content.message,
549
+ inbound
519
550
  });
520
- return result;
521
- }, []);
522
- broker.cancel('_run-on-inbound');
523
- if (!taken) return runDiscard({
524
- inbound,
525
- discardSequence
526
- });
527
- return run({
528
- inbound
529
- });
551
+
552
+ case 'flow.discard':
553
+ case 'activity.discard':
554
+ {
555
+ let discardSequence;
556
+ if (content.discardSequence) discardSequence = content.discardSequence.slice();
557
+ return this._runDiscard({
558
+ inbound,
559
+ discardSequence
560
+ });
561
+ }
562
+
563
+ case 'association.complete':
564
+ {
565
+ broker.cancel('_run-on-inbound');
566
+ const compensationId = `${(0, _shared.brokerSafeId)(id)}_${(0, _shared.brokerSafeId)(content.sequenceId)}`;
567
+ this.logger.debug(`<${id}> completed compensation with id <${compensationId}>`);
568
+ return this._publishEvent('compensation.end', this._createMessage({
569
+ executionId: compensationId
570
+ }));
571
+ }
572
+ }
573
+ };
574
+
575
+ proto._onJoinInbound = function onJoinInbound(routingKey, message) {
576
+ const {
577
+ content
578
+ } = message;
579
+ const {
580
+ inboundSequenceFlows,
581
+ inboundJoinFlows,
582
+ inboundTriggers
583
+ } = this[kFlows];
584
+ const idx = inboundJoinFlows.findIndex(msg => msg.content.id === content.id);
585
+ inboundJoinFlows.push(message);
586
+ if (idx > -1) return;
587
+ const allTouched = inboundJoinFlows.length >= inboundTriggers.length;
588
+
589
+ if (!allTouched) {
590
+ const remaining = inboundSequenceFlows.filter((inb, i, list) => list.indexOf(inb) === i).length - inboundJoinFlows.length;
591
+ return this.logger.debug(`<${this.id}> inbound ${message.content.action} from <${message.content.id}>, ${remaining} remaining`);
530
592
  }
531
593
 
532
- function onRunMessage(routingKey, message, messageProperties) {
533
- switch (routingKey) {
534
- case 'run.outbound.discard':
535
- case 'run.outbound.take':
536
- case 'run.next':
537
- return continueRunMessage(routingKey, message, messageProperties);
594
+ const evaluatedInbound = inboundJoinFlows.splice(0);
595
+ let taken;
596
+ const inbound = evaluatedInbound.map(im => {
597
+ if (im.fields.routingKey === 'flow.take') taken = true;
598
+ im.ack();
599
+ return (0, _messageHelper.cloneContent)(im.content);
600
+ });
601
+ const discardSequence = !taken && evaluatedInbound.reduce((result, im) => {
602
+ if (!im.content.discardSequence) return result;
538
603
 
539
- case 'run.resume':
540
- {
541
- return onResumeMessage();
542
- }
604
+ for (const sourceId of im.content.discardSequence) {
605
+ if (result.indexOf(sourceId) === -1) result.push(sourceId);
543
606
  }
544
607
 
545
- const preStatus = status;
546
- status = 'formatting';
547
- return formatter(message, (err, formattedContent, formatted) => {
548
- if (err) return emitFatal(err, message.content);
549
- if (formatted) message.content = formattedContent;
550
- status = preStatus;
551
- continueRunMessage(routingKey, message, messageProperties);
552
- });
608
+ return result;
609
+ }, []);
610
+ this.broker.cancel('_run-on-inbound');
611
+ if (!taken) return this._runDiscard({
612
+ inbound,
613
+ discardSequence
614
+ });
615
+ return this.run({
616
+ inbound
617
+ });
618
+ };
619
+
620
+ proto._onInboundEvent = function onInboundEvent(routingKey, message) {
621
+ const {
622
+ fields,
623
+ content,
624
+ properties
625
+ } = message;
626
+ const id = this.id;
627
+ const inboundQ = this.broker.getQueue('inbound-q');
628
+
629
+ switch (routingKey) {
630
+ case 'activity.enter':
631
+ case 'activity.discard':
632
+ {
633
+ if (content.id === this[kFlags].attachedTo) {
634
+ inboundQ.queueMessage(fields, (0, _messageHelper.cloneContent)(content), properties);
635
+ }
553
636
 
554
- function onResumeMessage() {
555
- message.ack();
556
- const {
557
- fields
558
- } = stateMessage;
559
-
560
- switch (fields.routingKey) {
561
- case 'run.enter':
562
- case 'run.start':
563
- case 'run.discarded':
564
- case 'run.end':
565
- case 'run.leave':
566
- break;
567
-
568
- default:
569
- return;
637
+ break;
570
638
  }
571
639
 
572
- if (!fields.redelivered) return;
573
- logger.debug(`<${id}> resume from ${message.content.status}`);
574
- return broker.publish('run', fields.routingKey, (0, _messageHelper.cloneContent)(stateMessage.content), stateMessage.properties);
575
- }
640
+ case 'flow.shake':
641
+ {
642
+ return this._shakeOutbound(message);
643
+ }
644
+
645
+ case 'association.take':
646
+ case 'flow.take':
647
+ case 'flow.discard':
648
+ return inboundQ.queueMessage(fields, (0, _messageHelper.cloneContent)(content), properties);
649
+
650
+ case 'association.discard':
651
+ {
652
+ this.logger.debug(`<${id}> compensation discarded`);
653
+ return inboundQ.purge();
654
+ }
655
+
656
+ case 'association.complete':
657
+ {
658
+ if (!this[kFlags].isForCompensation) break;
659
+ inboundQ.queueMessage(fields, (0, _messageHelper.cloneContent)(content), properties);
660
+ const compensationId = `${(0, _shared.brokerSafeId)(id)}_${(0, _shared.brokerSafeId)(content.sequenceId)}`;
661
+
662
+ this._publishEvent('compensation.start', this._createMessage({
663
+ executionId: compensationId,
664
+ placeholder: true
665
+ }));
666
+
667
+ this.logger.debug(`<${id}> start compensation with id <${compensationId}>`);
668
+ return this._consumeInbound();
669
+ }
670
+ }
671
+ };
672
+
673
+ proto._consumeRunQ = function consumeRunQ() {
674
+ if (this[kConsuming]) return;
675
+ this[kConsuming] = true;
676
+ this.broker.getQueue('run-q').assertConsumer(this[kMessageHandlers].onRunMessage, {
677
+ exclusive: true,
678
+ consumerTag: '_activity-run'
679
+ });
680
+ };
681
+
682
+ proto._onRunMessage = function onRunMessage(routingKey, message, messageProperties) {
683
+ switch (routingKey) {
684
+ case 'run.outbound.discard':
685
+ case 'run.outbound.take':
686
+ case 'run.next':
687
+ return this._continueRunMessage(routingKey, message, messageProperties);
688
+
689
+ case 'run.resume':
690
+ {
691
+ return this._onResumeMessage(message);
692
+ }
576
693
  }
577
694
 
578
- function continueRunMessage(routingKey, message) {
579
- const {
580
- fields,
581
- content: originalContent,
582
- ack
583
- } = message;
584
- const isRedelivered = fields.redelivered;
585
- const content = (0, _messageHelper.cloneContent)(originalContent);
586
- const {
587
- correlationId
588
- } = message.properties;
589
- stateMessage = message;
590
-
591
- switch (routingKey) {
592
- case 'run.enter':
593
- {
594
- logger.debug(`<${id}> enter`, isRedelivered ? 'redelivered' : '');
595
- status = 'entered';
596
-
597
- if (!isRedelivered) {
598
- execution = undefined;
599
- }
600
-
601
- if (extensions) extensions.activate((0, _messageHelper.cloneMessage)(message), activityApi);
602
- if (bpmnIo) bpmnIo.activate(message);
603
- if (!isRedelivered) publishEvent('enter', content, {
604
- correlationId
605
- });
606
- break;
607
- }
695
+ const preStatus = this.status;
696
+ this.status = 'formatting';
697
+ return this.formatter.format(message, (err, formattedContent, formatted) => {
698
+ if (err) return this.emitFatal(err, message.content);
699
+ if (formatted) message.content = formattedContent;
700
+ this.status = preStatus;
608
701
 
609
- case 'run.discard':
610
- {
611
- logger.debug(`<${id}> discard`, isRedelivered ? 'redelivered' : '');
612
- status = 'discard';
613
- execution = undefined;
614
- if (extensions) extensions.activate((0, _messageHelper.cloneMessage)(message), activityApi);
615
- if (bpmnIo) bpmnIo.activate(message);
616
-
617
- if (!isRedelivered) {
618
- broker.publish('run', 'run.discarded', content, {
619
- correlationId
620
- });
621
- publishEvent('discard', content);
622
- }
623
-
624
- break;
702
+ this._continueRunMessage(routingKey, message, messageProperties);
703
+ });
704
+ };
705
+
706
+ proto._continueRunMessage = function continueRunMessage(routingKey, message) {
707
+ const isRedelivered = message.fields.redelivered;
708
+ const content = (0, _messageHelper.cloneContent)(message.content);
709
+ const correlationId = message.properties.correlationId;
710
+ const id = this.id;
711
+ const step = this.environment.settings.step;
712
+ this[kStateMessage] = message;
713
+
714
+ switch (routingKey) {
715
+ case 'run.enter':
716
+ {
717
+ this.logger.debug(`<${id}> enter`, isRedelivered ? 'redelivered' : '');
718
+ this.status = 'entered';
719
+
720
+ if (!isRedelivered) {
721
+ this[kExec].execution = null;
625
722
  }
626
723
 
627
- case 'run.start':
628
- {
629
- logger.debug(`<${id}> start`, isRedelivered ? 'redelivered' : '');
630
- status = 'started';
631
-
632
- if (!isRedelivered) {
633
- broker.publish('run', 'run.execute', content, {
634
- correlationId
635
- });
636
- publishEvent('start', content, {
637
- correlationId
638
- });
639
- }
640
-
641
- break;
642
- }
724
+ if (this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message), this);
725
+ if (this.bpmnIo) this.bpmnIo.activate(message);
726
+ if (!isRedelivered) this._publishEvent('enter', content, {
727
+ correlationId
728
+ });
729
+ break;
730
+ }
643
731
 
644
- case 'run.execute.passthrough':
645
- {
646
- if (!isRedelivered && execution) {
647
- executeMessage = message;
648
- return execution.passthrough(message);
649
- }
650
- }
732
+ case 'run.discard':
733
+ {
734
+ this.logger.debug(`<${id}> discard`, isRedelivered ? 'redelivered' : '');
735
+ this.status = 'discard';
736
+ this[kExec].execution = null;
737
+ if (this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message), this);
738
+ if (this.bpmnIo) this.bpmnIo.activate(message);
651
739
 
652
- case 'run.execute':
653
- {
654
- status = 'executing';
655
- executeMessage = message;
656
- executionQ.assertConsumer(onExecutionMessage, {
657
- exclusive: true,
658
- consumerTag: '_activity-execution'
740
+ if (!isRedelivered) {
741
+ this.broker.publish('run', 'run.discarded', content, {
742
+ correlationId
659
743
  });
660
- execution = execution || (0, _ActivityExecution.default)(activityApi, context);
661
-
662
- if (isRedelivered) {
663
- return resumeExtensions(message, (err, formattedContent) => {
664
- if (err) return emitFatal(err, message.content);
665
- if (formattedContent) message.content = formattedContent;
666
- status = 'executing';
667
- return execution.execute(message);
668
- });
669
- }
670
-
671
- return execution.execute(message);
744
+
745
+ this._publishEvent('discard', content);
672
746
  }
673
747
 
674
- case 'run.end':
675
- {
676
- if (status === 'end') break;
677
- counters.taken++;
678
- status = 'end';
679
- if (isRedelivered) break;
680
- return doRunLeave(false, () => {
681
- publishEvent('end', content, {
682
- correlationId
683
- });
684
- if (!step) ack();
748
+ break;
749
+ }
750
+
751
+ case 'run.start':
752
+ {
753
+ this.logger.debug(`<${id}> start`, isRedelivered ? 'redelivered' : '');
754
+ this.status = 'started';
755
+
756
+ if (!isRedelivered) {
757
+ this.broker.publish('run', 'run.execute', content, {
758
+ correlationId
685
759
  });
686
- }
687
760
 
688
- case 'run.error':
689
- {
690
- publishEvent('error', (0, _messageHelper.cloneContent)(content, {
691
- error: fields.redelivered ? (0, _Errors.makeErrorFromMessage)(message) : content.error
692
- }), {
761
+ this._publishEvent('start', content, {
693
762
  correlationId
694
763
  });
695
- break;
696
764
  }
697
765
 
698
- case 'run.discarded':
699
- {
700
- logger.debug(`<${executionId} (${id})> discarded`);
701
- counters.discarded++;
702
- status = 'discarded';
703
- content.outbound = undefined;
704
-
705
- if (!isRedelivered) {
706
- return doRunLeave(true, () => {
707
- if (!step) ack();
708
- });
709
- }
766
+ break;
767
+ }
710
768
 
711
- break;
712
- }
769
+ case 'run.execute.passthrough':
770
+ {
771
+ const execution = this.execution;
713
772
 
714
- case 'run.outbound.take':
715
- {
716
- const flow = getOutboundSequenceFlowById(content.flow.id);
717
- ack();
718
- return flow.take(content.flow);
773
+ if (!isRedelivered && execution) {
774
+ this[kExecuteMessage] = message;
775
+ return execution.passthrough(message);
719
776
  }
777
+ }
720
778
 
721
- case 'run.outbound.discard':
722
- {
723
- const flow = getOutboundSequenceFlowById(content.flow.id);
724
- ack();
725
- return flow.discard(content.flow);
779
+ case 'run.execute':
780
+ {
781
+ this.status = 'executing';
782
+ this[kExecuteMessage] = message;
783
+ this.broker.getQueue('execution-q').assertConsumer(this[kMessageHandlers].onExecutionMessage, {
784
+ exclusive: true,
785
+ consumerTag: '_activity-execution'
786
+ });
787
+ const exec = this[kExec];
788
+ if (!exec.execution) exec.execution = new _ActivityExecution.default(this, this.context);
789
+
790
+ if (isRedelivered) {
791
+ return this._resumeExtensions(message, (err, formattedContent) => {
792
+ if (err) return this.emitFatal(err, message.content);
793
+ if (formattedContent) message.content = formattedContent;
794
+ this.status = 'executing';
795
+ return exec.execution.execute(message);
796
+ });
726
797
  }
727
798
 
728
- case 'run.leave':
729
- {
730
- status = undefined;
731
- if (bpmnIo) bpmnIo.deactivate(message);
732
- if (extensions) extensions.deactivate(message);
733
-
734
- if (!isRedelivered) {
735
- broker.publish('run', 'run.next', (0, _messageHelper.cloneContent)(content), {
736
- persistent: false
737
- });
738
- publishEvent('leave', content, {
739
- correlationId
740
- });
741
- }
742
-
743
- break;
744
- }
799
+ return exec.execution.execute(message);
800
+ }
745
801
 
746
- case 'run.next':
747
- consumeInbound();
748
- break;
749
- }
802
+ case 'run.end':
803
+ {
804
+ if (this.status === 'end') break;
805
+ this[kCounters].taken++;
806
+ this.status = 'end';
807
+ return this._doRunLeave(message, false, () => {
808
+ this._publishEvent('end', content, {
809
+ correlationId
810
+ });
750
811
 
751
- if (!step) ack();
812
+ if (!step) message.ack();
813
+ });
814
+ }
752
815
 
753
- function doRunLeave(isDiscarded, onOutbound) {
754
- if (content.ignoreOutbound) {
755
- broker.publish('run', 'run.leave', (0, _messageHelper.cloneContent)(content), {
816
+ case 'run.error':
817
+ {
818
+ this._publishEvent('error', { ...content,
819
+ error: isRedelivered ? (0, _Errors.makeErrorFromMessage)(message) : content.error
820
+ }, {
756
821
  correlationId
757
822
  });
758
- if (onOutbound) onOutbound();
759
- return;
823
+
824
+ break;
760
825
  }
761
826
 
762
- return doOutbound((0, _messageHelper.cloneMessage)(message), isDiscarded, (err, outbound) => {
763
- if (err) {
764
- return publishEvent('error', (0, _messageHelper.cloneContent)(content, {
765
- error: err
766
- }), {
767
- correlationId
827
+ case 'run.discarded':
828
+ {
829
+ this.logger.debug(`<${content.executionId} (${id})> discarded`);
830
+ this[kCounters].discarded++;
831
+ this.status = 'discarded';
832
+ content.outbound = undefined;
833
+
834
+ if (!isRedelivered) {
835
+ return this._doRunLeave(message, true, () => {
836
+ if (!step) message.ack();
768
837
  });
769
838
  }
770
839
 
771
- broker.publish('run', 'run.leave', (0, _messageHelper.cloneContent)(content, { ...(outbound.length ? {
772
- outbound
773
- } : undefined)
774
- }), {
775
- correlationId
776
- });
777
- if (onOutbound) onOutbound();
778
- });
779
- }
780
- }
840
+ break;
841
+ }
781
842
 
782
- function resumeExtensions(message, callback) {
783
- if (!extensions && !bpmnIo) return callback();
784
- if (extensions) extensions.activate((0, _messageHelper.cloneMessage)(message), activityApi);
785
- if (bpmnIo) bpmnIo.activate((0, _messageHelper.cloneMessage)(message));
786
- status = 'formatting';
787
- return formatter(message, (err, formattedContent, formatted) => {
788
- if (err) return callback(err);
789
- return callback(null, formatted && formattedContent);
790
- });
791
- }
843
+ case 'run.outbound.take':
844
+ {
845
+ const flow = this._getOutboundSequenceFlowById(content.flow.id);
792
846
 
793
- function getOutboundSequenceFlowById(flowId) {
794
- return outboundSequenceFlows.find(flow => flow.id === flowId);
795
- }
847
+ message.ack();
848
+ return flow.take(content.flow);
849
+ }
850
+
851
+ case 'run.outbound.discard':
852
+ {
853
+ const flow = this._getOutboundSequenceFlowById(content.flow.id);
796
854
 
797
- function onExecutionMessage(routingKey, message) {
798
- const content = (0, _messageHelper.cloneContent)({ ...executeMessage.content,
799
- ...message.content,
800
- executionId: executeMessage.content.executionId,
801
- parent: { ...parent
855
+ message.ack();
856
+ return flow.discard(content.flow);
802
857
  }
803
- });
804
- const {
805
- correlationId
806
- } = message.properties;
807
- publishEvent(routingKey, content, message.properties);
808
-
809
- switch (routingKey) {
810
- case 'execution.outbound.take':
811
- {
812
- return doOutbound((0, _messageHelper.cloneMessage)(message), false, (err, outbound) => {
813
- message.ack();
814
- if (err) return emitFatal(err, content);
815
- broker.publish('run', 'run.execute.passthrough', (0, _messageHelper.cloneContent)(content, {
816
- outbound
817
- }));
818
- return ackRunExecuteMessage();
819
- });
820
- }
821
858
 
822
- case 'execution.error':
823
- {
824
- status = 'error';
825
- broker.publish('run', 'run.error', content, {
826
- correlationId
859
+ case 'run.leave':
860
+ {
861
+ this.status = undefined;
862
+ if (this.bpmnIo) this.bpmnIo.deactivate(message);
863
+ if (this.extensions) this.extensions.deactivate(message);
864
+
865
+ if (!isRedelivered) {
866
+ this.broker.publish('run', 'run.next', content, {
867
+ persistent: false
827
868
  });
828
- broker.publish('run', 'run.discarded', content, {
869
+
870
+ this._publishEvent('leave', content, {
829
871
  correlationId
830
872
  });
831
- break;
832
873
  }
833
874
 
834
- case 'execution.discard':
835
- status = 'discarded';
836
- broker.publish('run', 'run.discarded', content, {
837
- correlationId
838
- });
839
875
  break;
876
+ }
840
877
 
841
- default:
842
- {
843
- status = 'executed';
844
- broker.publish('run', 'run.end', content, {
845
- correlationId
846
- });
847
- }
848
- }
849
-
850
- message.ack();
851
- ackRunExecuteMessage();
878
+ case 'run.next':
879
+ this._consumeInbound();
852
880
 
853
- function ackRunExecuteMessage() {
854
- if (step) return;
855
- if (!executeMessage) return;
856
- const ackMessage = executeMessage;
857
- executeMessage = null;
858
- ackMessage.ack();
859
- }
881
+ break;
860
882
  }
861
883
 
862
- function onApiMessage(routingKey, message) {
863
- const messageType = message.properties.type;
884
+ if (!step) message.ack();
885
+ };
864
886
 
865
- switch (messageType) {
866
- case 'discard':
867
- {
868
- discardRun(message);
869
- break;
870
- }
887
+ proto._onExecutionMessage = function onExecutionMessage(routingKey, message) {
888
+ const executeMessage = this[kExecuteMessage];
889
+ const content = (0, _messageHelper.cloneContent)({ ...executeMessage.content,
890
+ ...message.content,
891
+ executionId: executeMessage.content.executionId,
892
+ parent: { ...this.parent
893
+ }
894
+ });
895
+ const {
896
+ correlationId
897
+ } = message.properties;
871
898
 
872
- case 'stop':
873
- {
874
- onStop(message);
875
- break;
876
- }
899
+ this._publishEvent(routingKey, content, message.properties);
877
900
 
878
- case 'shake':
879
- {
880
- shakeOutbound(message);
881
- break;
882
- }
883
- }
884
- }
901
+ const broker = this.broker;
885
902
 
886
- function shake() {
887
- shakeOutbound({
888
- content: createMessage()
889
- });
890
- }
903
+ switch (routingKey) {
904
+ case 'execution.outbound.take':
905
+ {
906
+ return this._doOutbound(message, false, (err, outbound) => {
907
+ message.ack();
908
+ if (err) return this.emitFatal(err, content);
909
+ broker.publish('run', 'run.execute.passthrough', (0, _messageHelper.cloneContent)(content, {
910
+ outbound
911
+ }));
912
+ return this._ackRunExecuteMessage();
913
+ });
914
+ }
891
915
 
892
- function shakeOutbound(sourceMessage) {
893
- const message = (0, _messageHelper.cloneMessage)(sourceMessage);
894
- message.content.sequence = message.content.sequence || [];
895
- message.content.sequence.push({
896
- id,
897
- type
898
- });
899
- broker.publish('api', 'activity.shake.start', message.content, {
900
- persistent: false,
901
- type: 'shake'
902
- });
916
+ case 'execution.error':
917
+ {
918
+ this.status = 'error';
919
+ broker.publish('run', 'run.error', content, {
920
+ correlationId
921
+ });
922
+ broker.publish('run', 'run.discarded', content, {
923
+ correlationId
924
+ });
925
+ break;
926
+ }
903
927
 
904
- if (isEnd) {
905
- return broker.publish('event', 'activity.shake.end', message.content, {
906
- persistent: false,
907
- type: 'shake'
928
+ case 'execution.discard':
929
+ this.status = 'discarded';
930
+ broker.publish('run', 'run.discarded', content, {
931
+ correlationId
908
932
  });
909
- }
933
+ break;
910
934
 
911
- outboundSequenceFlows.forEach(f => f.shake(message));
935
+ default:
936
+ {
937
+ this.status = 'executed';
938
+ broker.publish('run', 'run.end', content, {
939
+ correlationId
940
+ });
941
+ }
912
942
  }
913
943
 
914
- function publishEvent(state, content, messageProperties = {}) {
915
- if (!state) return;
916
- if (!content) content = createMessage();
917
- broker.publish('event', `activity.${state}`, { ...content,
918
- state
919
- }, { ...messageProperties,
920
- type: state,
921
- mandatory: state === 'error',
922
- persistent: 'persistent' in messageProperties ? messageProperties.persistent : state !== 'stop'
923
- });
924
- }
944
+ message.ack();
925
945
 
926
- function doOutbound(fromMessage, isDiscarded, callback) {
927
- if (!outboundSequenceFlows.length) return callback(null, []);
928
- const fromContent = fromMessage.content;
929
- let discardSequence = fromContent.discardSequence;
946
+ this._ackRunExecuteMessage();
947
+ };
930
948
 
931
- if (isDiscarded && !discardSequence && attachedTo && fromContent.inbound && fromContent.inbound[0]) {
932
- discardSequence = [fromContent.inbound[0].id];
933
- }
949
+ proto._ackRunExecuteMessage = function ackRunExecuteMessage() {
950
+ if (this.environment.settings.step) return;
951
+ const executeMessage = this[kExecuteMessage];
952
+ this[kExecuteMessage] = null;
953
+ executeMessage.ack();
954
+ };
934
955
 
935
- let outboundFlows;
956
+ proto._doRunLeave = function doRunLeave(message, isDiscarded, onOutbound) {
957
+ const {
958
+ content,
959
+ properties
960
+ } = message;
961
+ const correlationId = properties.correlationId;
936
962
 
937
- if (isDiscarded) {
938
- outboundFlows = outboundSequenceFlows.map(flow => formatFlowAction(flow, {
939
- action: 'discard'
940
- }));
941
- } else if (fromContent.outbound && fromContent.outbound.length) {
942
- outboundFlows = outboundSequenceFlows.map(flow => formatFlowAction(flow, fromContent.outbound.filter(f => f.id === flow.id).pop()));
943
- }
963
+ if (content.ignoreOutbound) {
964
+ this.broker.publish('run', 'run.leave', (0, _messageHelper.cloneContent)(content), {
965
+ correlationId
966
+ });
967
+ return onOutbound();
968
+ }
944
969
 
945
- if (outboundFlows) {
946
- doRunOutbound(outboundFlows);
947
- return callback(null, outboundFlows);
970
+ return this._doOutbound((0, _messageHelper.cloneMessage)(message), isDiscarded, (err, outbound) => {
971
+ if (err) {
972
+ return this._publishEvent('error', { ...content,
973
+ error: err
974
+ }, {
975
+ correlationId
976
+ });
948
977
  }
949
978
 
950
- return evaluateOutbound(fromMessage, fromContent.outboundTakeOne, (err, evaluatedOutbound) => {
951
- if (err) return callback(new _Errors.ActivityError(err.message, fromMessage, err));
952
- const outbound = doRunOutbound(evaluatedOutbound);
953
- return callback(null, outbound);
979
+ this.broker.publish('run', 'run.leave', (0, _messageHelper.cloneContent)(content, { ...(outbound.length ? {
980
+ outbound
981
+ } : undefined)
982
+ }), {
983
+ correlationId
954
984
  });
985
+ onOutbound();
986
+ });
987
+ };
955
988
 
956
- function doRunOutbound(outboundList) {
957
- return outboundList.map(outboundFlow => {
958
- const {
959
- id: flowId,
960
- action
961
- } = outboundFlow;
962
- broker.publish('run', 'run.outbound.' + action, (0, _messageHelper.cloneContent)(fromContent, {
963
- flow: { ...outboundFlow,
964
- sequenceId: (0, _shared.getUniqueId)(`${flowId}_${action}`),
965
- ...(discardSequence ? {
966
- discardSequence: discardSequence.slice()
967
- } : undefined)
968
- }
969
- }));
970
- return outboundFlow;
971
- });
972
- }
989
+ proto._doOutbound = function doOutbound(fromMessage, isDiscarded, callback) {
990
+ const outboundSequenceFlows = this[kFlows].outboundSequenceFlows;
991
+ if (!outboundSequenceFlows.length) return callback(null, []);
992
+ const fromContent = fromMessage.content;
993
+ let discardSequence = fromContent.discardSequence;
994
+
995
+ if (isDiscarded && !discardSequence && this[kFlags].attachedTo && fromContent.inbound && fromContent.inbound[0]) {
996
+ discardSequence = [fromContent.inbound[0].id];
973
997
  }
974
998
 
975
- function formatFlowAction(flow, options) {
976
- if (!options) options = {
999
+ let outboundFlows;
1000
+
1001
+ if (isDiscarded) {
1002
+ outboundFlows = outboundSequenceFlows.map(flow => formatFlowAction(flow, {
977
1003
  action: 'discard'
978
- };
979
- const action = options.action;
980
- const message = options.message;
981
- return { ...options,
982
- id: flow.id,
983
- action,
984
- ...(flow.isDefault ? {
985
- isDefault: true
986
- } : undefined),
987
- ...(message !== undefined ? {
988
- message
989
- } : undefined)
990
- };
1004
+ }));
1005
+ } else if (fromContent.outbound && fromContent.outbound.length) {
1006
+ outboundFlows = outboundSequenceFlows.map(flow => formatFlowAction(flow, fromContent.outbound.filter(f => f.id === flow.id).pop()));
991
1007
  }
992
1008
 
993
- function evaluateOutbound(fromMessage, discardRestAtTake, callback) {
994
- let conditionMet;
995
- const outbound = {};
996
- if (!outboundSequenceFlows.length) return completed();
997
- const content = fromMessage.content;
998
- const message = content.message;
999
- const evaluateFlows = outboundSequenceFlows.slice();
1000
- const defaultFlowIdx = outboundSequenceFlows.findIndex(({
1001
- isDefault
1002
- }) => isDefault);
1003
-
1004
- if (defaultFlowIdx > -1) {
1005
- evaluateFlows.splice(defaultFlowIdx, 1);
1006
- evaluateFlows.push(outboundSequenceFlows[defaultFlowIdx]);
1007
- }
1009
+ if (outboundFlows) {
1010
+ this._doRunOutbound(outboundFlows, fromContent, discardSequence);
1008
1011
 
1009
- let takenCount = 0;
1010
- broker.subscribeTmp('execution', 'evaluate.flow.#', (routingKey, {
1011
- content: evalContent,
1012
- ack
1013
- }) => {
1014
- const {
1015
- id: flowId,
1016
- action
1017
- } = evalContent;
1018
-
1019
- if (action === 'take') {
1020
- takenCount++;
1021
- conditionMet = true;
1022
- }
1012
+ return callback(null, outboundFlows);
1013
+ }
1023
1014
 
1024
- outbound[flowId] = evalContent;
1015
+ return this.evaluateOutbound(fromMessage, fromContent.outboundTakeOne, (err, evaluatedOutbound) => {
1016
+ if (err) return callback(new _Errors.ActivityError(err.message, fromMessage, err));
1025
1017
 
1026
- if ('result' in evalContent) {
1027
- logger.debug(`<${content.executionId} (${id})> flow <${flowId}> evaluated to: ${evalContent.result}`);
1018
+ const outbound = this._doRunOutbound(evaluatedOutbound, fromContent, discardSequence);
1019
+
1020
+ return callback(null, outbound);
1021
+ });
1022
+ };
1023
+
1024
+ proto._doRunOutbound = function doRunOutbound(outboundList, content, discardSequence) {
1025
+ for (const outboundFlow of outboundList) {
1026
+ const {
1027
+ id: flowId,
1028
+ action
1029
+ } = outboundFlow;
1030
+ this.broker.publish('run', 'run.outbound.' + action, (0, _messageHelper.cloneContent)(content, {
1031
+ flow: { ...outboundFlow,
1032
+ sequenceId: (0, _shared.getUniqueId)(`${flowId}_${action}`),
1033
+ ...(discardSequence ? {
1034
+ discardSequence: discardSequence.slice()
1035
+ } : undefined)
1028
1036
  }
1037
+ }));
1038
+ }
1029
1039
 
1030
- let nextFlow = evaluateFlows.shift();
1031
- if (!nextFlow) return completed();
1040
+ return outboundList;
1041
+ };
1032
1042
 
1033
- if (discardRestAtTake && conditionMet) {
1034
- do {
1035
- outbound[nextFlow.id] = formatFlowAction(nextFlow, {
1036
- action: 'discard'
1037
- });
1038
- } while (nextFlow = evaluateFlows.shift());
1043
+ proto._onResumeMessage = function onResumeMessage(message) {
1044
+ message.ack();
1045
+ const stateMessage = this[kStateMessage];
1046
+ const {
1047
+ fields
1048
+ } = stateMessage;
1049
+
1050
+ switch (fields.routingKey) {
1051
+ case 'run.enter':
1052
+ case 'run.start':
1053
+ case 'run.discarded':
1054
+ case 'run.end':
1055
+ case 'run.leave':
1056
+ break;
1057
+
1058
+ default:
1059
+ return;
1060
+ }
1061
+
1062
+ if (!fields.redelivered) return;
1063
+ this.logger.debug(`<${this.id}> resume from ${message.content.status}`);
1064
+ return this.broker.publish('run', fields.routingKey, (0, _messageHelper.cloneContent)(stateMessage.content), stateMessage.properties);
1065
+ };
1066
+
1067
+ proto._publishEvent = function publishEvent(state, content, properties = {}) {
1068
+ this.broker.publish('event', `activity.${state}`, (0, _messageHelper.cloneContent)(content, {
1069
+ state
1070
+ }), { ...properties,
1071
+ type: state,
1072
+ mandatory: state === 'error',
1073
+ persistent: 'persistent' in properties ? properties.persistent : state !== 'stop'
1074
+ });
1075
+ };
1076
+
1077
+ proto._onStop = function onStop(message) {
1078
+ const running = this[kConsuming];
1079
+ this.stopped = true;
1080
+ this[kConsuming] = false;
1081
+ const broker = this.broker;
1082
+ broker.cancel('_activity-run');
1083
+ broker.cancel('_activity-api');
1084
+ broker.cancel('_activity-execution');
1085
+ broker.cancel('_run-on-inbound');
1086
+ broker.cancel('_format-consumer');
1087
+
1088
+ if (running) {
1089
+ if (this.extensions) this.extensions.deactivate(message || this._createMessage());
1090
+
1091
+ this._publishEvent('stop', this._createMessage());
1092
+ }
1093
+ };
1094
+
1095
+ proto._consumeApi = function consumeApi() {
1096
+ const executionId = this[kExec].executionId;
1097
+ if (!executionId) return;
1098
+ const broker = this.broker;
1099
+ broker.cancel('_activity-api');
1100
+ broker.subscribeTmp('api', `activity.*.${executionId}`, this[kMessageHandlers].onApiMessage, {
1101
+ noAck: true,
1102
+ consumerTag: '_activity-api',
1103
+ priority: 100
1104
+ });
1105
+ };
1039
1106
 
1040
- return completed();
1107
+ proto._onApiMessage = function onApiMessage(routingKey, message) {
1108
+ switch (message.properties.type) {
1109
+ case 'discard':
1110
+ {
1111
+ return this._discardRun(message);
1041
1112
  }
1042
1113
 
1043
- if (conditionMet && nextFlow.isDefault) {
1044
- outbound[nextFlow.id] = formatFlowAction(nextFlow, {
1045
- action: 'discard'
1046
- });
1047
- return completed();
1114
+ case 'stop':
1115
+ {
1116
+ return this._onStop(message);
1048
1117
  }
1049
1118
 
1050
- ack();
1051
- evaluateSequenceFlows(nextFlow);
1052
- }, {
1053
- consumerTag: `_flow-evaluation-${executionId}`
1054
- });
1055
- return evaluateSequenceFlows(evaluateFlows.shift());
1119
+ case 'shake':
1120
+ {
1121
+ return this._shakeOutbound(message);
1122
+ }
1123
+ }
1124
+ };
1125
+
1126
+ proto._createMessage = function createMessage(override) {
1127
+ const name = this.name,
1128
+ status = this.status,
1129
+ parent = this.parent;
1130
+ const result = { ...override,
1131
+ id: this.id,
1132
+ type: this.type,
1133
+ ...(name ? {
1134
+ name
1135
+ } : undefined),
1136
+ ...(status ? {
1137
+ status
1138
+ } : undefined),
1139
+ ...(parent ? {
1140
+ parent: (0, _messageHelper.cloneParent)(parent)
1141
+ } : undefined)
1142
+ };
1056
1143
 
1057
- function completed(err) {
1058
- broker.cancel(`_flow-evaluation-${executionId}`);
1059
- if (err) return callback(err);
1144
+ for (const [flag, value] of Object.entries(this[kFlags])) {
1145
+ if (value) result[flag] = value;
1146
+ }
1060
1147
 
1061
- if (!takenCount) {
1062
- const nonTakenError = new _Errors.ActivityError(`<${id}> no conditional flow taken`, fromMessage);
1063
- logger.error(`<${id}>`, nonTakenError);
1064
- return callback(nonTakenError);
1065
- }
1148
+ return result;
1149
+ };
1150
+
1151
+ proto._getOutboundSequenceFlowById = function getOutboundSequenceFlowById(flowId) {
1152
+ return this[kFlows].outboundSequenceFlows.find(flow => flow.id === flowId);
1153
+ };
1154
+
1155
+ proto._resumeExtensions = function resumeExtensions(message, callback) {
1156
+ const extensions = this.extensions,
1157
+ bpmnIo = this.bpmnIo;
1158
+ if (!extensions && !bpmnIo) return callback();
1159
+ if (extensions) extensions.activate((0, _messageHelper.cloneMessage)(message), this);
1160
+ if (bpmnIo) bpmnIo.activate((0, _messageHelper.cloneMessage)(message), this);
1161
+ this.status = 'formatting';
1162
+ return this.formatter.format(message, (err, formattedContent, formatted) => {
1163
+ if (err) return callback(err);
1164
+ return callback(null, formatted && formattedContent);
1165
+ });
1166
+ };
1167
+
1168
+ proto._deactivateRunConsumers = function _deactivateRunConsumers() {
1169
+ const broker = this.broker;
1170
+ broker.cancel('_activity-api');
1171
+ broker.cancel('_activity-run');
1172
+ broker.cancel('_activity-execution');
1173
+ this[kConsuming] = false;
1174
+ };
1175
+
1176
+ function OutboundEvaluator(activity, outboundFlows) {
1177
+ this.activity = activity;
1178
+ this.broker = activity.broker;
1179
+ const flows = this.outboundFlows = outboundFlows.slice();
1180
+ const defaultFlowIdx = flows.findIndex(({
1181
+ isDefault
1182
+ }) => isDefault);
1183
+
1184
+ if (defaultFlowIdx > -1) {
1185
+ const [defaultFlow] = flows.splice(defaultFlowIdx, 1);
1186
+ flows.push(defaultFlow);
1187
+ }
1066
1188
 
1067
- const outboundList = Object.keys(outbound).reduce((result, flowId) => {
1068
- const flow = outbound[flowId];
1069
- result.push({ ...flow,
1070
- ...(message !== undefined ? {
1071
- message
1072
- } : undefined)
1073
- });
1074
- return result;
1075
- }, []);
1076
- return callback(null, outboundList);
1077
- }
1189
+ this.defaultFlowIdx = outboundFlows.findIndex(({
1190
+ isDefault
1191
+ }) => isDefault);
1192
+ this._onEvaluated = this.onEvaluated.bind(this);
1193
+ this.evaluateArgs = {};
1194
+ }
1195
+
1196
+ OutboundEvaluator.prototype.evaluate = function evaluate(fromMessage, discardRestAtTake, callback) {
1197
+ const outboundFlows = this.outboundFlows;
1198
+ const args = this.evaluateArgs = {
1199
+ fromMessage,
1200
+ evaluationId: fromMessage.content.executionId,
1201
+ discardRestAtTake,
1202
+ callback,
1203
+ conditionMet: false,
1204
+ result: {},
1205
+ takenCount: 0
1206
+ };
1207
+ if (!outboundFlows.length) return this.completed();
1208
+ const flows = args.flows = outboundFlows.slice();
1209
+ this.broker.subscribeTmp('execution', 'evaluate.flow.#', this._onEvaluated, {
1210
+ consumerTag: `_flow-evaluation-${args.evaluationId}`
1211
+ });
1212
+ return this.evaluateFlow(flows.shift());
1213
+ };
1078
1214
 
1079
- function evaluateSequenceFlows(flow) {
1080
- if (!flow) return completed();
1215
+ OutboundEvaluator.prototype.onEvaluated = function onEvaluated(routingKey, message) {
1216
+ const content = message.content;
1217
+ const {
1218
+ id: flowId,
1219
+ action,
1220
+ evaluationId
1221
+ } = message.content;
1222
+ const args = this.evaluateArgs;
1223
+
1224
+ if (action === 'take') {
1225
+ args.takenCount++;
1226
+ args.conditionMet = true;
1227
+ }
1081
1228
 
1082
- if (flow.isDefault) {
1083
- return broker.publish('execution', 'evaluate.flow.take', formatFlowAction(flow, {
1084
- action: 'take'
1085
- }), {
1086
- persistent: false
1087
- });
1088
- }
1229
+ args.result[flowId] = content;
1089
1230
 
1090
- const flowCondition = flow.getCondition();
1231
+ if ('result' in content) {
1232
+ this.activity.logger.debug(`<${evaluationId} (${this.activity.id})> flow <${flowId}> evaluated to: ${!!content.result}`);
1233
+ }
1091
1234
 
1092
- if (!flowCondition) {
1093
- return broker.publish('execution', 'evaluate.flow.take', formatFlowAction(flow, {
1094
- action: 'take'
1095
- }), {
1096
- persistent: false
1097
- });
1098
- }
1235
+ let nextFlow = args.flows.shift();
1236
+ if (!nextFlow) return this.completed();
1099
1237
 
1100
- flowCondition.execute((0, _messageHelper.cloneMessage)(fromMessage), (err, result) => {
1101
- if (err) return completed(err);
1102
- const action = result ? 'take' : 'discard';
1103
- return broker.publish('execution', 'evaluate.flow.' + action, formatFlowAction(flow, {
1104
- action,
1105
- result
1106
- }), {
1107
- persistent: false
1108
- });
1238
+ if (args.discardRestAtTake && args.conditionMet) {
1239
+ do {
1240
+ args.result[nextFlow.id] = formatFlowAction(nextFlow, {
1241
+ action: 'discard'
1109
1242
  });
1110
- }
1243
+ } while (nextFlow = args.flows.shift());
1244
+
1245
+ return this.completed();
1111
1246
  }
1112
1247
 
1113
- function getActivityById(elementId) {
1114
- return context.getActivityById(elementId);
1248
+ if (args.conditionMet && nextFlow.isDefault) {
1249
+ args.result[nextFlow.id] = formatFlowAction(nextFlow, {
1250
+ action: 'discard'
1251
+ });
1252
+ return this.completed();
1115
1253
  }
1116
1254
 
1117
- function getState() {
1118
- const msg = createMessage();
1119
- return { ...msg,
1120
- status,
1121
- executionId,
1122
- stopped,
1123
- behaviour: { ...behaviour
1124
- },
1125
- counters: { ...counters
1126
- },
1127
- broker: broker.getState(true),
1128
- execution: execution && execution.getState()
1129
- };
1255
+ message.ack();
1256
+ this.evaluateFlow(nextFlow);
1257
+ };
1258
+
1259
+ OutboundEvaluator.prototype.evaluateFlow = function evaluateFlow(flow) {
1260
+ const broker = this.broker;
1261
+
1262
+ if (flow.isDefault) {
1263
+ return broker.publish('execution', 'evaluate.flow.take', formatFlowAction(flow, {
1264
+ action: 'take'
1265
+ }), {
1266
+ persistent: false
1267
+ });
1130
1268
  }
1131
1269
 
1132
- function next() {
1133
- if (!step) return;
1134
- if (!stateMessage) return;
1135
- if (status === 'executing') return false;
1136
- if (status === 'formatting') return false;
1137
- const current = stateMessage;
1138
- stateMessage.ack();
1139
- return current;
1270
+ const flowCondition = flow.getCondition();
1271
+
1272
+ if (!flowCondition) {
1273
+ return broker.publish('execution', 'evaluate.flow.take', formatFlowAction(flow, {
1274
+ action: 'take'
1275
+ }), {
1276
+ persistent: false
1277
+ });
1140
1278
  }
1141
1279
 
1142
- function getApi(message) {
1143
- if (execution && !execution.completed) return execution.getApi(message);
1144
- return (0, _Api.ActivityApi)(broker, message || stateMessage);
1280
+ const {
1281
+ fromMessage,
1282
+ evaluationId
1283
+ } = this.evaluateArgs;
1284
+ flowCondition.execute((0, _messageHelper.cloneMessage)(fromMessage), (err, result) => {
1285
+ if (err) return this.completed(err);
1286
+ const action = result ? 'take' : 'discard';
1287
+ return broker.publish('execution', 'evaluate.flow.' + action, formatFlowAction(flow, {
1288
+ action,
1289
+ result,
1290
+ evaluationId
1291
+ }), {
1292
+ persistent: false
1293
+ });
1294
+ });
1295
+ };
1296
+
1297
+ OutboundEvaluator.prototype.completed = function completed(err) {
1298
+ const {
1299
+ callback,
1300
+ evaluationId,
1301
+ fromMessage,
1302
+ result,
1303
+ takenCount
1304
+ } = this.evaluateArgs;
1305
+ this.broker.cancel(`_flow-evaluation-${evaluationId}`);
1306
+ if (err) return callback(err);
1307
+
1308
+ if (!takenCount && this.outboundFlows.length) {
1309
+ const nonTakenError = new _Errors.ActivityError(`<${this.activity.id}> no conditional flow taken`, fromMessage);
1310
+ return callback(nonTakenError);
1145
1311
  }
1312
+
1313
+ const message = fromMessage.content.message;
1314
+ const evaluationResult = [];
1315
+
1316
+ for (const flow of Object.values(result)) {
1317
+ evaluationResult.push({ ...flow,
1318
+ ...(message !== undefined ? {
1319
+ message
1320
+ } : undefined)
1321
+ });
1322
+ }
1323
+
1324
+ return callback(null, evaluationResult);
1325
+ };
1326
+
1327
+ function formatFlowAction(flow, options) {
1328
+ return { ...options,
1329
+ id: flow.id,
1330
+ action: options.action,
1331
+ ...(flow.isDefault ? {
1332
+ isDefault: true
1333
+ } : undefined)
1334
+ };
1146
1335
  }