bpmn-elements 6.0.1 → 7.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 (116) hide show
  1. package/CHANGELOG.md +322 -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 +169 -175
  6. package/dist/src/Environment.js +90 -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 +1106 -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 +722 -409
  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 +433 -359
  49. package/dist/src/process/ProcessExecution.js +744 -645
  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 +195 -175
  60. package/dist/src/tasks/Task.js +17 -19
  61. package/index.js +2 -0
  62. package/package.json +13 -13
  63. package/src/Api.js +65 -59
  64. package/src/Context.js +138 -141
  65. package/src/Environment.js +88 -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 +915 -775
  70. package/src/activity/ActivityExecution.js +293 -247
  71. package/src/activity/Dummy.js +2 -2
  72. package/src/definition/Definition.js +436 -401
  73. package/src/definition/DefinitionExecution.js +603 -343
  74. package/src/error/Errors.js +11 -6
  75. package/src/eventDefinitions/CancelEventDefinition.js +164 -121
  76. package/src/eventDefinitions/CompensateEventDefinition.js +158 -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 +16 -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 +374 -333
  106. package/src/process/ProcessExecution.js +606 -554
  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 activityDefSymbol = Symbol.for('activityDefinition');
27
+ const bpmnIoSymbol = Symbol.for('bpmnIo');
28
+ const consumingSymbol = Symbol.for('consuming');
29
+ const countersSymbol = Symbol.for('counters');
30
+ const eventDefinitionsSymbol = Symbol.for('eventDefinitions');
31
+ const execSymbol = Symbol.for('exec');
32
+ const executeMessageSymbol = Symbol.for('executeMessage');
33
+ const extensionsSymbol = Symbol.for('extensions');
34
+ const flagsSymbol = Symbol.for('flags');
35
+ const flowsSymbol = Symbol.for('flows');
36
+ const formatterSymbol = Symbol.for('formatter');
37
+ const messageHandlersSymbol = Symbol.for('messageHandlers');
38
+ const stateMessageSymbol = 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[activityDefSymbol] = 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[countersSymbol] = {
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[flowsSymbol] = {
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[flagsSymbol] = {
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[execSymbol] = {};
114
+ this[messageHandlersSymbol] = {
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,1196 @@ 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[eventDefinitionsSymbol] = 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[countersSymbol]
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[execSymbol].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[execSymbol].executionId;
173
+ }
251
174
 
252
- return result;
175
+ });
176
+ Object.defineProperty(proto, 'bpmnIo', {
177
+ enumerable: true,
178
+
179
+ get() {
180
+ if (bpmnIoSymbol in this) return this[bpmnIoSymbol];
181
+ const bpmnIo = this[bpmnIoSymbol] = 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 (extensionsSymbol in this) return this[extensionsSymbol];
191
+ const extensions = this[extensionsSymbol] = 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[formatterSymbol];
201
+ if (formatter) return formatter;
202
+ const broker = this.broker;
203
+ formatter = this[formatterSymbol] = 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[consumingSymbol]) 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[flowsSymbol].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[flowsSymbol].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[flagsSymbol].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[flagsSymbol].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[flagsSymbol].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[flagsSymbol].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[flagsSymbol].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[flagsSymbol].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[activityDefSymbol].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[flagsSymbol].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[eventDefinitionsSymbol];
308
+ }
387
309
 
388
- return inboundQ.consume(onInbound, {
389
- consumerTag: '_run-on-inbound'
390
- });
310
+ });
311
+
312
+ proto.activate = function activate() {
313
+ if (this[flagsSymbol].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[execSymbol];
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[execSymbol];
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[execSymbol];
360
+ exec.executionId = state.executionId;
361
+ this[countersSymbol] = { ...this[countersSymbol],
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[consumingSymbol]) {
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[execSymbol].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[stateMessageSymbol].content));
402
+
403
+ this._consumeRunQ();
404
+ };
405
+
406
+ proto.stop = function stop() {
407
+ if (!this[consumingSymbol]) return;
408
+ return this.getApi().stop();
409
+ };
410
+
411
+ proto.next = function next() {
412
+ if (!this.environment.settings.step) return;
413
+ const stateMessage = this[stateMessageSymbol];
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[flowsSymbol].outboundEvaluator.evaluate(fromMessage, discardRestAtTake, callback);
430
+ };
431
+
432
+ proto.getState = function getState() {
433
+ const msg = this._createMessage();
434
+
435
+ const exec = this[execSymbol];
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[execSymbol].execution;
449
+ if (execution && !execution.completed) return execution.getApi(message);
450
+ return (0, _Api.ActivityApi)(this.broker, message || this[stateMessageSymbol]);
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[execSymbol];
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[execSymbol].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[stateMessageSymbol].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[flagsSymbol].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[flowsSymbol].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[flagsSymbol].isParallelJoin) {
524
+ return inboundQ.consume(this[messageHandlersSymbol].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[messageHandlersSymbol].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[flowsSymbol];
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[flagsSymbol].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[flagsSymbol].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[consumingSymbol]) return;
675
+ this[consumingSymbol] = true;
676
+ this.broker.getQueue('run-q').assertConsumer(this[messageHandlersSymbol].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[stateMessageSymbol] = 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[execSymbol].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[execSymbol].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[executeMessageSymbol] = 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[executeMessageSymbol] = message;
783
+ this.broker.getQueue('execution-q').assertConsumer(this[messageHandlersSymbol].onExecutionMessage, {
784
+ exclusive: true,
785
+ consumerTag: '_activity-execution'
786
+ });
787
+ const exec = this[execSymbol];
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[countersSymbol].taken++;
806
+ this.status = 'end';
807
+ if (isRedelivered) break;
808
+ return this._doRunLeave(message, false, () => {
809
+ this._publishEvent('end', content, {
810
+ correlationId
811
+ });
750
812
 
751
- if (!step) ack();
813
+ if (!step) message.ack();
814
+ });
815
+ }
752
816
 
753
- function doRunLeave(isDiscarded, onOutbound) {
754
- if (content.ignoreOutbound) {
755
- broker.publish('run', 'run.leave', (0, _messageHelper.cloneContent)(content), {
817
+ case 'run.error':
818
+ {
819
+ this._publishEvent('error', { ...content,
820
+ error: isRedelivered ? (0, _Errors.makeErrorFromMessage)(message) : content.error
821
+ }, {
756
822
  correlationId
757
823
  });
758
- if (onOutbound) onOutbound();
759
- return;
824
+
825
+ break;
760
826
  }
761
827
 
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
828
+ case 'run.discarded':
829
+ {
830
+ this.logger.debug(`<${content.executionId} (${id})> discarded`);
831
+ this[countersSymbol].discarded++;
832
+ this.status = 'discarded';
833
+ content.outbound = undefined;
834
+
835
+ if (!isRedelivered) {
836
+ return this._doRunLeave(message, true, () => {
837
+ if (!step) message.ack();
768
838
  });
769
839
  }
770
840
 
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
- }
841
+ break;
842
+ }
781
843
 
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
- }
844
+ case 'run.outbound.take':
845
+ {
846
+ const flow = this._getOutboundSequenceFlowById(content.flow.id);
792
847
 
793
- function getOutboundSequenceFlowById(flowId) {
794
- return outboundSequenceFlows.find(flow => flow.id === flowId);
795
- }
848
+ message.ack();
849
+ return flow.take(content.flow);
850
+ }
851
+
852
+ case 'run.outbound.discard':
853
+ {
854
+ const flow = this._getOutboundSequenceFlowById(content.flow.id);
796
855
 
797
- function onExecutionMessage(routingKey, message) {
798
- const content = (0, _messageHelper.cloneContent)({ ...executeMessage.content,
799
- ...message.content,
800
- executionId: executeMessage.content.executionId,
801
- parent: { ...parent
856
+ message.ack();
857
+ return flow.discard(content.flow);
802
858
  }
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
859
 
822
- case 'execution.error':
823
- {
824
- status = 'error';
825
- broker.publish('run', 'run.error', content, {
826
- correlationId
860
+ case 'run.leave':
861
+ {
862
+ this.status = undefined;
863
+ if (this.bpmnIo) this.bpmnIo.deactivate(message);
864
+ if (this.extensions) this.extensions.deactivate(message);
865
+
866
+ if (!isRedelivered) {
867
+ this.broker.publish('run', 'run.next', content, {
868
+ persistent: false
827
869
  });
828
- broker.publish('run', 'run.discarded', content, {
870
+
871
+ this._publishEvent('leave', content, {
829
872
  correlationId
830
873
  });
831
- break;
832
874
  }
833
875
 
834
- case 'execution.discard':
835
- status = 'discarded';
836
- broker.publish('run', 'run.discarded', content, {
837
- correlationId
838
- });
839
876
  break;
877
+ }
840
878
 
841
- default:
842
- {
843
- status = 'executed';
844
- broker.publish('run', 'run.end', content, {
845
- correlationId
846
- });
847
- }
848
- }
849
-
850
- message.ack();
851
- ackRunExecuteMessage();
879
+ case 'run.next':
880
+ this._consumeInbound();
852
881
 
853
- function ackRunExecuteMessage() {
854
- if (step) return;
855
- if (!executeMessage) return;
856
- const ackMessage = executeMessage;
857
- executeMessage = null;
858
- ackMessage.ack();
859
- }
882
+ break;
860
883
  }
861
884
 
862
- function onApiMessage(routingKey, message) {
863
- const messageType = message.properties.type;
885
+ if (!step) message.ack();
886
+ };
864
887
 
865
- switch (messageType) {
866
- case 'discard':
867
- {
868
- discardRun(message);
869
- break;
870
- }
888
+ proto._onExecutionMessage = function onExecutionMessage(routingKey, message) {
889
+ const executeMessage = this[executeMessageSymbol];
890
+ const content = (0, _messageHelper.cloneContent)({ ...executeMessage.content,
891
+ ...message.content,
892
+ executionId: executeMessage.content.executionId,
893
+ parent: { ...this.parent
894
+ }
895
+ });
896
+ const {
897
+ correlationId
898
+ } = message.properties;
871
899
 
872
- case 'stop':
873
- {
874
- onStop(message);
875
- break;
876
- }
900
+ this._publishEvent(routingKey, content, message.properties);
877
901
 
878
- case 'shake':
879
- {
880
- shakeOutbound(message);
881
- break;
882
- }
883
- }
884
- }
902
+ const broker = this.broker;
885
903
 
886
- function shake() {
887
- shakeOutbound({
888
- content: createMessage()
889
- });
890
- }
904
+ switch (routingKey) {
905
+ case 'execution.outbound.take':
906
+ {
907
+ return this._doOutbound(message, false, (err, outbound) => {
908
+ message.ack();
909
+ if (err) return this.emitFatal(err, content);
910
+ broker.publish('run', 'run.execute.passthrough', (0, _messageHelper.cloneContent)(content, {
911
+ outbound
912
+ }));
913
+ return this._ackRunExecuteMessage();
914
+ });
915
+ }
891
916
 
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
- });
917
+ case 'execution.error':
918
+ {
919
+ this.status = 'error';
920
+ broker.publish('run', 'run.error', content, {
921
+ correlationId
922
+ });
923
+ broker.publish('run', 'run.discarded', content, {
924
+ correlationId
925
+ });
926
+ break;
927
+ }
903
928
 
904
- if (isEnd) {
905
- return broker.publish('event', 'activity.shake.end', message.content, {
906
- persistent: false,
907
- type: 'shake'
929
+ case 'execution.discard':
930
+ this.status = 'discarded';
931
+ broker.publish('run', 'run.discarded', content, {
932
+ correlationId
908
933
  });
909
- }
934
+ break;
910
935
 
911
- outboundSequenceFlows.forEach(f => f.shake(message));
936
+ default:
937
+ {
938
+ this.status = 'executed';
939
+ broker.publish('run', 'run.end', content, {
940
+ correlationId
941
+ });
942
+ }
912
943
  }
913
944
 
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
- }
945
+ message.ack();
925
946
 
926
- function doOutbound(fromMessage, isDiscarded, callback) {
927
- if (!outboundSequenceFlows.length) return callback(null, []);
928
- const fromContent = fromMessage.content;
929
- let discardSequence = fromContent.discardSequence;
947
+ this._ackRunExecuteMessage();
948
+ };
930
949
 
931
- if (isDiscarded && !discardSequence && attachedTo && fromContent.inbound && fromContent.inbound[0]) {
932
- discardSequence = [fromContent.inbound[0].id];
933
- }
950
+ proto._ackRunExecuteMessage = function ackRunExecuteMessage() {
951
+ if (this.environment.settings.step) return;
952
+ const executeMessage = this[executeMessageSymbol];
953
+ this[executeMessageSymbol] = null;
954
+ executeMessage.ack();
955
+ };
934
956
 
935
- let outboundFlows;
957
+ proto._doRunLeave = function doRunLeave(message, isDiscarded, onOutbound) {
958
+ const {
959
+ content,
960
+ properties
961
+ } = message;
962
+ const correlationId = properties.correlationId;
936
963
 
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
- }
964
+ if (content.ignoreOutbound) {
965
+ this.broker.publish('run', 'run.leave', (0, _messageHelper.cloneContent)(content), {
966
+ correlationId
967
+ });
968
+ return onOutbound();
969
+ }
944
970
 
945
- if (outboundFlows) {
946
- doRunOutbound(outboundFlows);
947
- return callback(null, outboundFlows);
971
+ return this._doOutbound((0, _messageHelper.cloneMessage)(message), isDiscarded, (err, outbound) => {
972
+ if (err) {
973
+ return this._publishEvent('error', { ...content,
974
+ error: err
975
+ }, {
976
+ correlationId
977
+ });
948
978
  }
949
979
 
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);
980
+ this.broker.publish('run', 'run.leave', (0, _messageHelper.cloneContent)(content, { ...(outbound.length ? {
981
+ outbound
982
+ } : undefined)
983
+ }), {
984
+ correlationId
954
985
  });
986
+ onOutbound();
987
+ });
988
+ };
955
989
 
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
- }
990
+ proto._doOutbound = function doOutbound(fromMessage, isDiscarded, callback) {
991
+ const outboundSequenceFlows = this[flowsSymbol].outboundSequenceFlows;
992
+ if (!outboundSequenceFlows.length) return callback(null, []);
993
+ const fromContent = fromMessage.content;
994
+ let discardSequence = fromContent.discardSequence;
995
+
996
+ if (isDiscarded && !discardSequence && this[flagsSymbol].attachedTo && fromContent.inbound && fromContent.inbound[0]) {
997
+ discardSequence = [fromContent.inbound[0].id];
973
998
  }
974
999
 
975
- function formatFlowAction(flow, options) {
976
- if (!options) options = {
1000
+ let outboundFlows;
1001
+
1002
+ if (isDiscarded) {
1003
+ outboundFlows = outboundSequenceFlows.map(flow => formatFlowAction(flow, {
977
1004
  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
- };
1005
+ }));
1006
+ } else if (fromContent.outbound && fromContent.outbound.length) {
1007
+ outboundFlows = outboundSequenceFlows.map(flow => formatFlowAction(flow, fromContent.outbound.filter(f => f.id === flow.id).pop()));
991
1008
  }
992
1009
 
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
- }
1010
+ if (outboundFlows) {
1011
+ this._doRunOutbound(outboundFlows, fromContent, discardSequence);
1008
1012
 
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
- }
1013
+ return callback(null, outboundFlows);
1014
+ }
1023
1015
 
1024
- outbound[flowId] = evalContent;
1016
+ return this.evaluateOutbound(fromMessage, fromContent.outboundTakeOne, (err, evaluatedOutbound) => {
1017
+ if (err) return callback(new _Errors.ActivityError(err.message, fromMessage, err));
1025
1018
 
1026
- if ('result' in evalContent) {
1027
- logger.debug(`<${content.executionId} (${id})> flow <${flowId}> evaluated to: ${evalContent.result}`);
1019
+ const outbound = this._doRunOutbound(evaluatedOutbound, fromContent, discardSequence);
1020
+
1021
+ return callback(null, outbound);
1022
+ });
1023
+ };
1024
+
1025
+ proto._doRunOutbound = function doRunOutbound(outboundList, content, discardSequence) {
1026
+ for (const outboundFlow of outboundList) {
1027
+ const {
1028
+ id: flowId,
1029
+ action
1030
+ } = outboundFlow;
1031
+ this.broker.publish('run', 'run.outbound.' + action, (0, _messageHelper.cloneContent)(content, {
1032
+ flow: { ...outboundFlow,
1033
+ sequenceId: (0, _shared.getUniqueId)(`${flowId}_${action}`),
1034
+ ...(discardSequence ? {
1035
+ discardSequence: discardSequence.slice()
1036
+ } : undefined)
1028
1037
  }
1038
+ }));
1039
+ }
1029
1040
 
1030
- let nextFlow = evaluateFlows.shift();
1031
- if (!nextFlow) return completed();
1041
+ return outboundList;
1042
+ };
1032
1043
 
1033
- if (discardRestAtTake && conditionMet) {
1034
- do {
1035
- outbound[nextFlow.id] = formatFlowAction(nextFlow, {
1036
- action: 'discard'
1037
- });
1038
- } while (nextFlow = evaluateFlows.shift());
1044
+ proto._onResumeMessage = function onResumeMessage(message) {
1045
+ message.ack();
1046
+ const stateMessage = this[stateMessageSymbol];
1047
+ const {
1048
+ fields
1049
+ } = stateMessage;
1050
+
1051
+ switch (fields.routingKey) {
1052
+ case 'run.enter':
1053
+ case 'run.start':
1054
+ case 'run.discarded':
1055
+ case 'run.end':
1056
+ case 'run.leave':
1057
+ break;
1058
+
1059
+ default:
1060
+ return;
1061
+ }
1062
+
1063
+ if (!fields.redelivered) return;
1064
+ this.logger.debug(`<${this.id}> resume from ${message.content.status}`);
1065
+ return this.broker.publish('run', fields.routingKey, (0, _messageHelper.cloneContent)(stateMessage.content), stateMessage.properties);
1066
+ };
1067
+
1068
+ proto._publishEvent = function publishEvent(state, content, properties = {}) {
1069
+ this.broker.publish('event', `activity.${state}`, (0, _messageHelper.cloneContent)(content, {
1070
+ state
1071
+ }), { ...properties,
1072
+ type: state,
1073
+ mandatory: state === 'error',
1074
+ persistent: 'persistent' in properties ? properties.persistent : state !== 'stop'
1075
+ });
1076
+ };
1077
+
1078
+ proto._onStop = function onStop(message) {
1079
+ const running = this[consumingSymbol];
1080
+ this.stopped = true;
1081
+ this[consumingSymbol] = false;
1082
+ const broker = this.broker;
1083
+ broker.cancel('_activity-run');
1084
+ broker.cancel('_activity-api');
1085
+ broker.cancel('_activity-execution');
1086
+ broker.cancel('_run-on-inbound');
1087
+ broker.cancel('_format-consumer');
1088
+
1089
+ if (running) {
1090
+ if (this.extensions) this.extensions.deactivate(message || this._createMessage());
1091
+
1092
+ this._publishEvent('stop', this._createMessage());
1093
+ }
1094
+ };
1095
+
1096
+ proto._consumeApi = function consumeApi() {
1097
+ const executionId = this[execSymbol].executionId;
1098
+ if (!executionId) return;
1099
+ const broker = this.broker;
1100
+ broker.cancel('_activity-api');
1101
+ broker.subscribeTmp('api', `activity.*.${executionId}`, this[messageHandlersSymbol].onApiMessage, {
1102
+ noAck: true,
1103
+ consumerTag: '_activity-api',
1104
+ priority: 100
1105
+ });
1106
+ };
1039
1107
 
1040
- return completed();
1108
+ proto._onApiMessage = function onApiMessage(routingKey, message) {
1109
+ switch (message.properties.type) {
1110
+ case 'discard':
1111
+ {
1112
+ return this._discardRun(message);
1041
1113
  }
1042
1114
 
1043
- if (conditionMet && nextFlow.isDefault) {
1044
- outbound[nextFlow.id] = formatFlowAction(nextFlow, {
1045
- action: 'discard'
1046
- });
1047
- return completed();
1115
+ case 'stop':
1116
+ {
1117
+ return this._onStop(message);
1048
1118
  }
1049
1119
 
1050
- ack();
1051
- evaluateSequenceFlows(nextFlow);
1052
- }, {
1053
- consumerTag: `_flow-evaluation-${executionId}`
1054
- });
1055
- return evaluateSequenceFlows(evaluateFlows.shift());
1120
+ case 'shake':
1121
+ {
1122
+ return this._shakeOutbound(message);
1123
+ }
1124
+ }
1125
+ };
1126
+
1127
+ proto._createMessage = function createMessage(override) {
1128
+ const name = this.name,
1129
+ status = this.status,
1130
+ parent = this.parent;
1131
+ const result = { ...override,
1132
+ id: this.id,
1133
+ type: this.type,
1134
+ ...(name ? {
1135
+ name
1136
+ } : undefined),
1137
+ ...(status ? {
1138
+ status
1139
+ } : undefined),
1140
+ ...(parent ? {
1141
+ parent: (0, _messageHelper.cloneParent)(parent)
1142
+ } : undefined)
1143
+ };
1056
1144
 
1057
- function completed(err) {
1058
- broker.cancel(`_flow-evaluation-${executionId}`);
1059
- if (err) return callback(err);
1145
+ for (const [flag, value] of Object.entries(this[flagsSymbol])) {
1146
+ if (value) result[flag] = value;
1147
+ }
1060
1148
 
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
- }
1149
+ return result;
1150
+ };
1151
+
1152
+ proto._getOutboundSequenceFlowById = function getOutboundSequenceFlowById(flowId) {
1153
+ return this[flowsSymbol].outboundSequenceFlows.find(flow => flow.id === flowId);
1154
+ };
1155
+
1156
+ proto._resumeExtensions = function resumeExtensions(message, callback) {
1157
+ const extensions = this.extensions,
1158
+ bpmnIo = this.bpmnIo;
1159
+ if (!extensions && !bpmnIo) return callback();
1160
+ if (extensions) extensions.activate((0, _messageHelper.cloneMessage)(message), this);
1161
+ if (bpmnIo) bpmnIo.activate((0, _messageHelper.cloneMessage)(message), this);
1162
+ this.status = 'formatting';
1163
+ return this.formatter.format(message, (err, formattedContent, formatted) => {
1164
+ if (err) return callback(err);
1165
+ return callback(null, formatted && formattedContent);
1166
+ });
1167
+ };
1168
+
1169
+ proto._deactivateRunConsumers = function _deactivateRunConsumers() {
1170
+ const broker = this.broker;
1171
+ broker.cancel('_activity-api');
1172
+ broker.cancel('_activity-run');
1173
+ broker.cancel('_activity-execution');
1174
+ this[consumingSymbol] = false;
1175
+ };
1176
+
1177
+ function OutboundEvaluator(activity, outboundFlows) {
1178
+ this.activity = activity;
1179
+ this.broker = activity.broker;
1180
+ const flows = this.outboundFlows = outboundFlows.slice();
1181
+ const defaultFlowIdx = flows.findIndex(({
1182
+ isDefault
1183
+ }) => isDefault);
1184
+
1185
+ if (defaultFlowIdx > -1) {
1186
+ const [defaultFlow] = flows.splice(defaultFlowIdx, 1);
1187
+ flows.push(defaultFlow);
1188
+ }
1066
1189
 
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
- }
1190
+ this.defaultFlowIdx = outboundFlows.findIndex(({
1191
+ isDefault
1192
+ }) => isDefault);
1193
+ this._onEvaluated = this.onEvaluated.bind(this);
1194
+ this.evaluateArgs = {};
1195
+ }
1196
+
1197
+ OutboundEvaluator.prototype.evaluate = function evaluate(fromMessage, discardRestAtTake, callback) {
1198
+ const outboundFlows = this.outboundFlows;
1199
+ const args = this.evaluateArgs = {
1200
+ fromMessage,
1201
+ evaluationId: fromMessage.content.executionId,
1202
+ discardRestAtTake,
1203
+ callback,
1204
+ conditionMet: false,
1205
+ result: {},
1206
+ takenCount: 0
1207
+ };
1208
+ if (!outboundFlows.length) return this.completed();
1209
+ const flows = args.flows = outboundFlows.slice();
1210
+ this.broker.subscribeTmp('execution', 'evaluate.flow.#', this._onEvaluated, {
1211
+ consumerTag: `_flow-evaluation-${args.evaluationId}`
1212
+ });
1213
+ return this.evaluateFlow(flows.shift());
1214
+ };
1078
1215
 
1079
- function evaluateSequenceFlows(flow) {
1080
- if (!flow) return completed();
1216
+ OutboundEvaluator.prototype.onEvaluated = function onEvaluated(routingKey, message) {
1217
+ const content = message.content;
1218
+ const {
1219
+ id: flowId,
1220
+ action,
1221
+ evaluationId
1222
+ } = message.content;
1223
+ const args = this.evaluateArgs;
1224
+
1225
+ if (action === 'take') {
1226
+ args.takenCount++;
1227
+ args.conditionMet = true;
1228
+ }
1081
1229
 
1082
- if (flow.isDefault) {
1083
- return broker.publish('execution', 'evaluate.flow.take', formatFlowAction(flow, {
1084
- action: 'take'
1085
- }), {
1086
- persistent: false
1087
- });
1088
- }
1230
+ args.result[flowId] = content;
1089
1231
 
1090
- const flowCondition = flow.getCondition();
1232
+ if ('result' in content) {
1233
+ this.activity.logger.debug(`<${evaluationId} (${this.activity.id})> flow <${flowId}> evaluated to: ${!!content.result}`);
1234
+ }
1091
1235
 
1092
- if (!flowCondition) {
1093
- return broker.publish('execution', 'evaluate.flow.take', formatFlowAction(flow, {
1094
- action: 'take'
1095
- }), {
1096
- persistent: false
1097
- });
1098
- }
1236
+ let nextFlow = args.flows.shift();
1237
+ if (!nextFlow) return this.completed();
1099
1238
 
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
- });
1239
+ if (args.discardRestAtTake && args.conditionMet) {
1240
+ do {
1241
+ args.result[nextFlow.id] = formatFlowAction(nextFlow, {
1242
+ action: 'discard'
1109
1243
  });
1110
- }
1244
+ } while (nextFlow = args.flows.shift());
1245
+
1246
+ return this.completed();
1111
1247
  }
1112
1248
 
1113
- function getActivityById(elementId) {
1114
- return context.getActivityById(elementId);
1249
+ if (args.conditionMet && nextFlow.isDefault) {
1250
+ args.result[nextFlow.id] = formatFlowAction(nextFlow, {
1251
+ action: 'discard'
1252
+ });
1253
+ return this.completed();
1115
1254
  }
1116
1255
 
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
- };
1256
+ message.ack();
1257
+ this.evaluateFlow(nextFlow);
1258
+ };
1259
+
1260
+ OutboundEvaluator.prototype.evaluateFlow = function evaluateFlow(flow) {
1261
+ const broker = this.broker;
1262
+
1263
+ if (flow.isDefault) {
1264
+ return broker.publish('execution', 'evaluate.flow.take', formatFlowAction(flow, {
1265
+ action: 'take'
1266
+ }), {
1267
+ persistent: false
1268
+ });
1130
1269
  }
1131
1270
 
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;
1271
+ const flowCondition = flow.getCondition();
1272
+
1273
+ if (!flowCondition) {
1274
+ return broker.publish('execution', 'evaluate.flow.take', formatFlowAction(flow, {
1275
+ action: 'take'
1276
+ }), {
1277
+ persistent: false
1278
+ });
1140
1279
  }
1141
1280
 
1142
- function getApi(message) {
1143
- if (execution && !execution.completed) return execution.getApi(message);
1144
- return (0, _Api.ActivityApi)(broker, message || stateMessage);
1281
+ const {
1282
+ fromMessage,
1283
+ evaluationId
1284
+ } = this.evaluateArgs;
1285
+ flowCondition.execute((0, _messageHelper.cloneMessage)(fromMessage), (err, result) => {
1286
+ if (err) return this.completed(err);
1287
+ const action = result ? 'take' : 'discard';
1288
+ return broker.publish('execution', 'evaluate.flow.' + action, formatFlowAction(flow, {
1289
+ action,
1290
+ result,
1291
+ evaluationId
1292
+ }), {
1293
+ persistent: false
1294
+ });
1295
+ });
1296
+ };
1297
+
1298
+ OutboundEvaluator.prototype.completed = function completed(err) {
1299
+ const {
1300
+ callback,
1301
+ evaluationId,
1302
+ fromMessage,
1303
+ result,
1304
+ takenCount
1305
+ } = this.evaluateArgs;
1306
+ this.broker.cancel(`_flow-evaluation-${evaluationId}`);
1307
+ if (err) return callback(err);
1308
+
1309
+ if (!takenCount && this.outboundFlows.length) {
1310
+ const nonTakenError = new _Errors.ActivityError(`<${this.activity.id}> no conditional flow taken`, fromMessage);
1311
+ return callback(nonTakenError);
1145
1312
  }
1313
+
1314
+ const message = fromMessage.content.message;
1315
+ const evaluationResult = [];
1316
+
1317
+ for (const flow of Object.values(result)) {
1318
+ evaluationResult.push({ ...flow,
1319
+ ...(message !== undefined ? {
1320
+ message
1321
+ } : undefined)
1322
+ });
1323
+ }
1324
+
1325
+ return callback(null, evaluationResult);
1326
+ };
1327
+
1328
+ function formatFlowAction(flow, options) {
1329
+ return { ...options,
1330
+ id: flow.id,
1331
+ action: options.action,
1332
+ ...(flow.isDefault ? {
1333
+ isDefault: true
1334
+ } : undefined)
1335
+ };
1146
1336
  }