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