bpmn-elements 6.0.1 → 8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/CHANGELOG.md +341 -0
  2. package/README.md +3 -0
  3. package/dist/index.js +52 -44
  4. package/dist/src/Api.js +77 -76
  5. package/dist/src/Context.js +176 -172
  6. package/dist/src/Environment.js +110 -102
  7. package/dist/src/EventBroker.js +89 -88
  8. package/dist/src/ExtensionsMapper.js +2 -2
  9. package/dist/src/MessageFormatter.js +164 -95
  10. package/dist/src/Scripts.js +6 -2
  11. package/dist/src/activity/Activity.js +1105 -916
  12. package/dist/src/activity/ActivityExecution.js +342 -297
  13. package/dist/src/activity/Dummy.js +3 -3
  14. package/dist/src/definition/Definition.js +498 -444
  15. package/dist/src/definition/DefinitionExecution.js +710 -408
  16. package/dist/src/error/Errors.js +17 -7
  17. package/dist/src/eventDefinitions/CancelEventDefinition.js +190 -150
  18. package/dist/src/eventDefinitions/CompensateEventDefinition.js +194 -161
  19. package/dist/src/eventDefinitions/ConditionalEventDefinition.js +197 -135
  20. package/dist/src/eventDefinitions/ErrorEventDefinition.js +207 -165
  21. package/dist/src/eventDefinitions/EscalationEventDefinition.js +175 -141
  22. package/dist/src/eventDefinitions/EventDefinitionExecution.js +157 -129
  23. package/dist/src/eventDefinitions/LinkEventDefinition.js +174 -149
  24. package/dist/src/eventDefinitions/MessageEventDefinition.js +213 -176
  25. package/dist/src/eventDefinitions/SignalEventDefinition.js +203 -161
  26. package/dist/src/eventDefinitions/TerminateEventDefinition.js +21 -23
  27. package/dist/src/eventDefinitions/TimerEventDefinition.js +243 -228
  28. package/dist/src/events/BoundaryEvent.js +180 -144
  29. package/dist/src/events/EndEvent.js +18 -23
  30. package/dist/src/events/IntermediateCatchEvent.js +44 -58
  31. package/dist/src/events/IntermediateThrowEvent.js +18 -23
  32. package/dist/src/events/StartEvent.js +109 -94
  33. package/dist/src/flows/Association.js +94 -100
  34. package/dist/src/flows/MessageFlow.js +86 -103
  35. package/dist/src/flows/SequenceFlow.js +173 -182
  36. package/dist/src/gateways/EventBasedGateway.js +88 -84
  37. package/dist/src/gateways/ExclusiveGateway.js +13 -16
  38. package/dist/src/gateways/InclusiveGateway.js +11 -14
  39. package/dist/src/gateways/ParallelGateway.js +11 -14
  40. package/dist/src/getPropertyValue.js +34 -34
  41. package/dist/src/io/BpmnIO.js +17 -14
  42. package/dist/src/io/EnvironmentDataObject.js +33 -29
  43. package/dist/src/io/EnvironmentDataStore.js +33 -29
  44. package/dist/src/io/EnvironmentDataStoreReference.js +35 -31
  45. package/dist/src/io/InputOutputSpecification.js +177 -168
  46. package/dist/src/io/Properties.js +117 -124
  47. package/dist/src/messageHelper.js +1 -1
  48. package/dist/src/process/Process.js +439 -362
  49. package/dist/src/process/ProcessExecution.js +748 -646
  50. package/dist/src/shared.js +2 -2
  51. package/dist/src/tasks/CallActivity.js +160 -0
  52. package/dist/src/tasks/LoopCharacteristics.js +309 -330
  53. package/dist/src/tasks/ReceiveTask.js +233 -182
  54. package/dist/src/tasks/ScriptTask.js +35 -41
  55. package/dist/src/tasks/ServiceImplementation.js +13 -20
  56. package/dist/src/tasks/ServiceTask.js +82 -75
  57. package/dist/src/tasks/SignalTask.js +97 -93
  58. package/dist/src/tasks/StandardLoopCharacteristics.js +1 -1
  59. package/dist/src/tasks/SubProcess.js +193 -175
  60. package/dist/src/tasks/Task.js +17 -19
  61. package/index.js +2 -0
  62. package/package.json +16 -16
  63. package/src/Api.js +65 -59
  64. package/src/Context.js +145 -140
  65. package/src/Environment.js +116 -100
  66. package/src/EventBroker.js +67 -68
  67. package/src/ExtensionsMapper.js +2 -2
  68. package/src/MessageFormatter.js +132 -74
  69. package/src/activity/Activity.js +914 -776
  70. package/src/activity/ActivityExecution.js +293 -247
  71. package/src/activity/Dummy.js +2 -2
  72. package/src/definition/Definition.js +437 -401
  73. package/src/definition/DefinitionExecution.js +598 -340
  74. package/src/error/Errors.js +11 -6
  75. package/src/eventDefinitions/CancelEventDefinition.js +164 -121
  76. package/src/eventDefinitions/CompensateEventDefinition.js +159 -124
  77. package/src/eventDefinitions/ConditionalEventDefinition.js +147 -104
  78. package/src/eventDefinitions/ErrorEventDefinition.js +190 -131
  79. package/src/eventDefinitions/EscalationEventDefinition.js +139 -101
  80. package/src/eventDefinitions/EventDefinitionExecution.js +127 -95
  81. package/src/eventDefinitions/LinkEventDefinition.js +160 -129
  82. package/src/eventDefinitions/MessageEventDefinition.js +178 -121
  83. package/src/eventDefinitions/SignalEventDefinition.js +162 -106
  84. package/src/eventDefinitions/TerminateEventDefinition.js +19 -19
  85. package/src/eventDefinitions/TimerEventDefinition.js +202 -167
  86. package/src/events/BoundaryEvent.js +156 -115
  87. package/src/events/EndEvent.js +15 -18
  88. package/src/events/IntermediateCatchEvent.js +40 -44
  89. package/src/events/IntermediateThrowEvent.js +15 -18
  90. package/src/events/StartEvent.js +84 -50
  91. package/src/flows/Association.js +98 -112
  92. package/src/flows/MessageFlow.js +81 -97
  93. package/src/flows/SequenceFlow.js +146 -160
  94. package/src/gateways/EventBasedGateway.js +75 -68
  95. package/src/gateways/ExclusiveGateway.js +8 -13
  96. package/src/gateways/InclusiveGateway.js +8 -13
  97. package/src/gateways/ParallelGateway.js +8 -13
  98. package/src/getPropertyValue.js +34 -33
  99. package/src/io/BpmnIO.js +20 -15
  100. package/src/io/EnvironmentDataObject.js +29 -18
  101. package/src/io/EnvironmentDataStore.js +29 -18
  102. package/src/io/EnvironmentDataStoreReference.js +31 -20
  103. package/src/io/InputOutputSpecification.js +154 -157
  104. package/src/io/Properties.js +95 -97
  105. package/src/process/Process.js +378 -333
  106. package/src/process/ProcessExecution.js +603 -553
  107. package/src/tasks/CallActivity.js +130 -0
  108. package/src/tasks/LoopCharacteristics.js +290 -289
  109. package/src/tasks/ReceiveTask.js +174 -107
  110. package/src/tasks/ScriptTask.js +27 -30
  111. package/src/tasks/ServiceImplementation.js +13 -18
  112. package/src/tasks/ServiceTask.js +67 -60
  113. package/src/tasks/SignalTask.js +77 -52
  114. package/src/tasks/StandardLoopCharacteristics.js +1 -1
  115. package/src/tasks/SubProcess.js +184 -157
  116. package/src/tasks/Task.js +15 -19
@@ -5,500 +5,536 @@ import {getUniqueId, getOptionsAndCallback} from '../shared';
5
5
  import {makeErrorFromMessage} from '../error/Errors';
6
6
  import {cloneMessage, cloneContent} from '../messageHelper';
7
7
 
8
+ const kConsuming = Symbol.for('consuming');
9
+ const kCounters = Symbol.for('counters');
10
+ const kExec = Symbol.for('execution');
11
+ const kExecuteMessage = Symbol.for('executeMessage');
12
+ const kMessageHandlers = Symbol.for('messageHandlers');
13
+ const kStateMessage = Symbol.for('stateMessage');
14
+ const kStatus = Symbol.for('status');
15
+ const kStopped = Symbol.for('stopped');
16
+
8
17
  export default Definition;
9
18
 
10
19
  export function Definition(context, options) {
20
+ if (!(this instanceof Definition)) return new Definition(context, options);
11
21
  if (!context) throw new Error('No context');
12
22
 
13
23
  const {id, name, type = 'definition'} = context;
14
- let environment = context.environment;
15
24
 
25
+ this.id = id;
26
+ this.type = type;
27
+ this.name = name;
28
+
29
+ let environment;
16
30
  if (options) {
17
- environment = environment.clone(options);
18
- context = context.clone(environment);
31
+ environment = this.environment = context.environment.clone(options);
32
+ this.context = context.clone(environment);
33
+ } else {
34
+ environment = this.environment = context.environment;
35
+ this.context = context;
19
36
  }
20
37
 
21
- const logger = environment.Logger(type.toLowerCase());
22
-
23
- let execution, executionId, processes, executableProcesses, postponedMessage, stateMessage, stopped, consumingRunQ;
24
- let status;
25
-
26
- let counters = {
38
+ this[kCounters] = {
27
39
  completed: 0,
28
40
  discarded: 0,
29
41
  };
30
42
 
31
- const definitionApi = {
32
- id,
33
- name,
34
- type,
35
- logger,
36
- context,
37
- get counters() {
38
- return {...counters};
39
- },
40
- get executionId() {
41
- return executionId;
42
- },
43
- get status() {
44
- return status;
45
- },
46
- get execution() {
47
- return execution;
48
- },
49
- get isRunning() {
50
- if (!consumingRunQ) return false;
51
- return !!status;
52
- },
53
- get environment() {
54
- return environment;
55
- },
56
- run,
57
- getApi,
58
- getState,
59
- getActivityById,
60
- getElementById,
61
- getPostponed,
62
- getProcesses,
63
- getExecutableProcesses,
64
- getProcessById,
65
- sendMessage,
66
- recover,
67
- resume,
68
- shake,
69
- signal,
70
- cancelActivity,
71
- stop,
43
+ this[kStopped] = false;
44
+ this[kExec] = {};
45
+
46
+ const onBrokerReturn = this._onBrokerReturnFn.bind(this);
47
+ this[kMessageHandlers] = {
48
+ onBrokerReturn,
49
+ onApiMessage: this._onApiMessage.bind(this),
50
+ onRunMessage: this._onRunMessage.bind(this),
51
+ onExecutionMessage: this._onExecutionMessage.bind(this),
72
52
  };
73
53
 
74
- const {broker, on, once, waitFor, emit, emitFatal} = DefinitionBroker(definitionApi, onBrokerReturn);
54
+ const {broker, on, once, waitFor, emit, emitFatal} = DefinitionBroker(this, onBrokerReturn);
55
+ this.broker = broker;
75
56
 
76
- definitionApi.on = on;
77
- definitionApi.once = once;
78
- definitionApi.waitFor = waitFor;
79
- definitionApi.emit = emit;
80
- definitionApi.emitFatal = emitFatal;
57
+ this.on = on;
58
+ this.once = once;
59
+ this.waitFor = waitFor;
60
+ this.emit = emit;
61
+ this.emitFatal = emitFatal;
81
62
 
82
- const runQ = broker.getQueue('run-q');
83
- const executionQ = broker.getQueue('execution-q');
63
+ this.logger = environment.Logger(type.toLowerCase());
64
+ }
84
65
 
85
- Object.defineProperty(definitionApi, 'broker', {
86
- enumerable: true,
87
- get: () => broker,
88
- });
66
+ const proto = Definition.prototype;
67
+
68
+ Object.defineProperty(proto, 'counters', {
69
+ enumerable: true,
70
+ get() {
71
+ return {...this[kCounters]};
72
+ },
73
+ });
74
+
75
+ Object.defineProperty(proto, 'execution', {
76
+ enumerable: true,
77
+ get() {
78
+ return this[kExec].execution;
79
+ },
80
+ });
81
+
82
+ Object.defineProperty(proto, 'executionId', {
83
+ enumerable: true,
84
+ get() {
85
+ return this[kExec].executionId;
86
+ },
87
+ });
88
+
89
+ Object.defineProperty(proto, 'isRunning', {
90
+ enumerable: true,
91
+ get() {
92
+ if (!this[kConsuming]) return false;
93
+ return !!this.status;
94
+ },
95
+ });
96
+
97
+ Object.defineProperty(proto, 'status', {
98
+ enumerable: true,
99
+ get() {
100
+ return this[kStatus];
101
+ },
102
+ });
103
+
104
+ Object.defineProperty(proto, 'stopped', {
105
+ enumerable: true,
106
+ get() {
107
+ return this[kStopped];
108
+ },
109
+ });
110
+
111
+ proto.run = function run(optionsOrCallback, optionalCallback) {
112
+ const [runOptions, callback] = getOptionsAndCallback(optionsOrCallback, optionalCallback);
113
+ if (this.isRunning) {
114
+ const err = new Error('definition is already running');
115
+ if (callback) return callback(err);
116
+ throw err;
117
+ }
89
118
 
90
- Object.defineProperty(definitionApi, 'stopped', {
91
- enumerable: true,
92
- get: () => execution && execution.stopped,
93
- });
119
+ if (callback) {
120
+ addConsumerCallbacks(this, callback);
121
+ }
94
122
 
95
- return definitionApi;
123
+ const exec = this[kExec];
124
+ exec.executionId = getUniqueId(this.id);
125
+ const content = this._createMessage({...runOptions});
96
126
 
97
- function run(optionsOrCallback, optionalCallback) {
98
- const [runOptions, callback] = getOptionsAndCallback(optionsOrCallback, optionalCallback);
99
- if (definitionApi.isRunning) {
100
- const err = new Error('definition is already running');
101
- if (callback) return callback(err);
102
- throw err;
103
- }
127
+ const broker = this.broker;
128
+ broker.publish('run', 'run.enter', content);
129
+ broker.publish('run', 'run.start', cloneContent(content));
130
+ broker.publish('run', 'run.execute', cloneContent(content));
104
131
 
105
- addConsumerCallbacks(callback);
132
+ this.logger.debug(`<${this.executionId} (${this.id})> run`);
106
133
 
107
- executionId = getUniqueId(id);
108
- const content = createMessage({...runOptions, executionId});
134
+ this._activateRunConsumers();
109
135
 
110
- broker.publish('run', 'run.enter', content);
111
- broker.publish('run', 'run.start', cloneContent(content));
112
- broker.publish('run', 'run.execute', cloneContent(content));
136
+ return this;
137
+ };
113
138
 
114
- logger.debug(`<${executionId} (${id})> run`);
139
+ proto.resume = function resume(callback) {
140
+ if (this.isRunning) {
141
+ const err = new Error('cannot resume running definition');
142
+ if (callback) return callback(err);
143
+ throw err;
144
+ }
115
145
 
116
- activateRunConsumers();
146
+ this[kStopped] = false;
147
+ if (!this.status) return this;
117
148
 
118
- return definitionApi;
149
+ if (callback) {
150
+ addConsumerCallbacks(this, callback);
119
151
  }
120
152
 
121
- function resume(callback) {
122
- if (definitionApi.isRunning) {
123
- const err = new Error('cannot resume running definition');
124
- if (callback) return callback(err);
125
- throw err;
126
- }
153
+ this.logger.debug(`<${this.executionId} (${this.id})> resume`);
127
154
 
128
- stopped = false;
129
- if (!status) return definitionApi;
155
+ const content = this._createMessage();
156
+ this.broker.publish('run', 'run.resume', content, {persistent: false});
157
+ this._activateRunConsumers();
158
+ return this;
159
+ };
130
160
 
131
- addConsumerCallbacks(callback);
161
+ proto.recover = function recover(state) {
162
+ if (this.isRunning) throw new Error('cannot recover running definition');
163
+ if (!state) return this;
132
164
 
133
- logger.debug(`<${executionId} (${id})> resume`);
165
+ this[kStopped] = !!state.stopped;
166
+ this[kStatus] = state.status;
134
167
 
135
- const content = createMessage({executionId});
136
- broker.publish('run', 'run.resume', content, {persistent: false});
137
- activateRunConsumers();
138
- return definitionApi;
168
+ const exec = this[kExec];
169
+ exec.executionId = state.executionId;
170
+ if (state.counters) {
171
+ this[kCounters] = {...this[kCounters], ...state.counters};
139
172
  }
140
173
 
141
- function recover(state) {
142
- if (definitionApi.isRunning) throw new Error('cannot recover running definition');
143
- if (!state) return definitionApi;
144
-
145
- stopped = state.stopped;
146
- status = state.status;
147
-
148
- executionId = state.executionId;
149
- if (state.counters) {
150
- counters = {...counters, ...state.counters};
151
- }
174
+ this.environment.recover(state.environment);
152
175
 
153
- environment.recover(state.environment);
176
+ if (state.execution) {
177
+ exec.execution = new DefinitionExecution(this, this.context).recover(state.execution);
178
+ }
154
179
 
155
- if (state.execution) {
156
- execution = DefinitionExecution(definitionApi, context).recover(state.execution);
180
+ this.broker.recover(state.broker);
181
+
182
+ return this;
183
+ };
184
+
185
+ proto.shake = function shake(startId) {
186
+ let result = {};
187
+ const broker = this.broker;
188
+
189
+ let bps;
190
+ if (startId) {
191
+ const startActivity = this.getActivityById(startId);
192
+ if (!startActivity) return;
193
+ const bp = this.getProcessById(startActivity.parent.id);
194
+ if (!bp) return;
195
+ bps = [bp];
196
+ } else bps = this.getProcesses();
197
+
198
+ bps.forEach(shakeProcess);
199
+
200
+ return result;
201
+
202
+ function shakeProcess(shakeBp) {
203
+ let shovel;
204
+ if (!shakeBp.isRunning) {
205
+ shovel = shakeBp.broker.createShovel('shaker', {
206
+ exchange: 'event',
207
+ pattern: '*.shake#',
208
+ }, {
209
+ broker,
210
+ exchange: 'event',
211
+ });
157
212
  }
158
213
 
159
- broker.recover(state.broker);
214
+ const shakeResult = shakeBp.shake(startId);
215
+ if (shovel) shakeBp.broker.closeShovel('shaker');
160
216
 
161
- return definitionApi;
217
+ result = {
218
+ ...result,
219
+ ...shakeResult,
220
+ };
162
221
  }
163
-
164
- function shake(startId) {
165
- let result = {};
166
-
167
- let bps;
168
- if (startId) {
169
- const startActivity = getActivityById(startId);
170
- if (!startActivity) return;
171
- const bp = getProcessById(startActivity.parent.id);
172
- if (!bp) return;
173
- bps = [bp];
174
- } else bps = getProcesses();
175
-
176
- bps.forEach(shakeProcess);
177
-
178
- return result;
179
-
180
- function shakeProcess(shakeBp) {
181
- let shovel;
182
- if (!shakeBp.isRunning) {
183
- shovel = shakeBp.broker.createShovel('shaker', {
184
- exchange: 'event',
185
- pattern: '*.shake#',
186
- }, {
187
- broker,
188
- exchange: 'event',
189
- });
190
- }
191
-
192
- const shakeResult = shakeBp.shake(startId);
193
- if (shovel) shakeBp.broker.closeShovel('shaker');
194
-
195
- result = {
196
- ...result,
197
- ...shakeResult,
198
- };
199
- }
222
+ };
223
+
224
+ proto.getState = function getState() {
225
+ return this._createMessage({
226
+ status: this.status,
227
+ stopped: this.stopped,
228
+ counters: this.counters,
229
+ environment: this.environment.getState(),
230
+ execution: this.execution && this.execution.getState(),
231
+ broker: this.broker.getState(true),
232
+ });
233
+ };
234
+
235
+ proto.getProcesses = function getProcesses() {
236
+ const execution = this.execution;
237
+ if (execution) return execution.getProcesses();
238
+ return this.context.getProcesses();
239
+ };
240
+
241
+ proto.getExecutableProcesses = function getExecutableProcesses() {
242
+ const execution = this.execution;
243
+ if (execution) return execution.getExecutableProcesses();
244
+ return this.context.getExecutableProcesses();
245
+ };
246
+
247
+ proto.getRunningProcesses = function getRunningProcesses() {
248
+ const execution = this.execution;
249
+ if (!execution) return [];
250
+ return execution.getRunningProcesses();
251
+ };
252
+
253
+ proto.getProcessById = function getProcessById(processId) {
254
+ return this.getProcesses().find((p) => p.id === processId);
255
+ };
256
+
257
+ proto.getActivityById = function getActivityById(childId) {
258
+ const bps = this.getProcesses();
259
+ for (const bp of bps) {
260
+ const child = bp.getActivityById(childId);
261
+ if (child) return child;
200
262
  }
201
-
202
- function activateRunConsumers() {
203
- consumingRunQ = true;
204
- broker.subscribeTmp('api', `definition.*.${executionId}`, onApiMessage, {noAck: true, consumerTag: '_definition-api'});
205
- runQ.assertConsumer(onRunMessage, {exclusive: true, consumerTag: '_definition-run'});
263
+ return null;
264
+ };
265
+
266
+ proto.getElementById = function getElementById(elementId) {
267
+ return this.context.getActivityById(elementId);
268
+ };
269
+
270
+ proto.getPostponed = function getPostponed(...args) {
271
+ const execution = this.execution;
272
+ if (!execution) return [];
273
+ return execution.getPostponed(...args);
274
+ };
275
+
276
+ proto.getApi = function getApi(message) {
277
+ const execution = this.execution;
278
+ if (execution) return execution.getApi(message);
279
+ message = message || this[kStateMessage];
280
+ if (!message) throw new Error('Definition is not running');
281
+ return DefinitionApi(this.broker, message);
282
+ };
283
+
284
+ proto.signal = function signal(message) {
285
+ return this.getApi().signal(message, {delegate: true});
286
+ };
287
+
288
+ proto.cancelActivity = function cancelActivity(message) {
289
+ return this.getApi().cancel(message, {delegate: true});
290
+ };
291
+
292
+ proto.sendMessage = function sendMessage(message) {
293
+ const messageContent = {message};
294
+ let messageType = 'message';
295
+ const reference = message && message.id && this.getElementById(message.id);
296
+ if (reference && reference.resolve) {
297
+ const resolvedReference = reference.resolve(this._createMessage({message}));
298
+ messageType = resolvedReference.messageType || messageType;
299
+ messageContent.message = {...message, ...resolvedReference};
206
300
  }
207
301
 
208
- function deactivateRunConsumers() {
209
- broker.cancel('_definition-api');
210
- broker.cancel('_definition-run');
211
- broker.cancel('_definition-execution');
212
- consumingRunQ = false;
213
- }
302
+ return this.getApi().sendApiMessage(messageType, messageContent, {delegate: true});
303
+ };
304
+
305
+ proto.stop = function stop() {
306
+ if (!this.isRunning) return;
307
+ this.getApi().stop();
308
+ };
309
+
310
+ proto._activateRunConsumers = function activateRunConsumers() {
311
+ this[kConsuming] = true;
312
+ const broker = this.broker;
313
+ const {onApiMessage, onRunMessage} = this[kMessageHandlers];
314
+ broker.subscribeTmp('api', `definition.*.${this.executionId}`, onApiMessage, {
315
+ noAck: true,
316
+ consumerTag: '_definition-api',
317
+ });
318
+ broker.getQueue('run-q').assertConsumer(onRunMessage, {
319
+ exclusive: true,
320
+ consumerTag: '_definition-run',
321
+ });
322
+ };
323
+
324
+ proto._deactivateRunConsumers = function deactivateRunConsumers() {
325
+ const broker = this.broker;
326
+ broker.cancel('_definition-api');
327
+ broker.cancel('_definition-run');
328
+ broker.cancel('_definition-execution');
329
+ this[kConsuming] = false;
330
+ };
331
+
332
+ proto._createMessage = function createMessage(override) {
333
+ return {
334
+ id: this.id,
335
+ type: this.type,
336
+ name: this.name,
337
+ executionId: this.executionId,
338
+ ...override,
339
+ };
340
+ };
214
341
 
215
- function stop() {
216
- if (!definitionApi.isRunning) return;
217
- getApi().stop();
342
+ proto._onRunMessage = function onRunMessage(routingKey, message) {
343
+ const {content, fields} = message;
344
+ if (routingKey === 'run.resume') {
345
+ return this._onResumeMessage(message);
218
346
  }
219
347
 
220
- function addConsumerCallbacks(callback) {
221
- if (!callback) return;
348
+ const exec = this[kExec];
349
+ this[kStateMessage] = message;
222
350
 
223
- broker.off('return', onBrokerReturn);
351
+ switch (routingKey) {
352
+ case 'run.enter': {
353
+ this.logger.debug(`<${this.executionId} (${this.id})> enter`);
224
354
 
225
- clearConsumers();
355
+ this[kStatus] = 'entered';
356
+ if (fields.redelivered) break;
226
357
 
227
- broker.subscribeOnce('event', 'definition.stop', cbLeave, {consumerTag: '_definition-callback-stop'});
228
- broker.subscribeOnce('event', 'definition.leave', cbLeave, {consumerTag: '_definition-callback-leave'});
229
- broker.subscribeOnce('event', 'definition.error', cbError, {consumerTag: '_definition-callback-error'});
230
-
231
- function cbLeave(_, message) {
232
- clearConsumers();
233
- return callback(null, getApi(message));
234
- }
235
- function cbError(_, message) {
236
- clearConsumers();
237
- reset();
238
- const err = makeErrorFromMessage(message);
239
- return callback(err);
358
+ exec.execution = undefined;
359
+ this._publishEvent('enter', content);
360
+ break;
240
361
  }
241
-
242
- function clearConsumers() {
243
- broker.cancel('_definition-callback-stop');
244
- broker.cancel('_definition-callback-leave');
245
- broker.cancel('_definition-callback-error');
246
- broker.on('return', onBrokerReturn);
247
- }
248
- }
249
-
250
- function createMessage(override) {
251
- return {
252
- id,
253
- type,
254
- name,
255
- ...override,
256
- };
257
- }
258
-
259
- function onBrokerReturn(message) {
260
- if (message.properties.type === 'error') {
261
- deactivateRunConsumers();
262
- const err = makeErrorFromMessage(message);
263
- throw err;
264
- }
265
- }
266
-
267
- function onRunMessage(routingKey, message) {
268
- const {content, ack, fields} = message;
269
- if (routingKey === 'run.resume') {
270
- return onResumeMessage();
362
+ case 'run.start': {
363
+ this.logger.debug(`<${this.executionId} (${this.id})> start`);
364
+ this[kStatus] = 'start';
365
+ this._publishEvent('start', content);
366
+ break;
271
367
  }
272
-
273
- stateMessage = message;
274
-
275
- switch (routingKey) {
276
- case 'run.enter': {
277
- logger.debug(`<${executionId} (${id})> enter`);
278
-
279
- status = 'entered';
280
- if (fields.redelivered) break;
281
-
282
- execution = undefined;
283
- publishEvent('enter', content);
284
- break;
285
- }
286
- case 'run.start': {
287
- logger.debug(`<${executionId} (${id})> start`);
288
- status = 'start';
289
- publishEvent('start', content);
290
- break;
291
- }
292
- case 'run.execute': {
293
- status = 'executing';
294
- const executeMessage = cloneMessage(message);
295
- if (fields.redelivered && !execution) {
296
- executeMessage.fields.redelivered = undefined;
297
- }
298
- postponedMessage = message;
299
- executionQ.assertConsumer(onExecutionMessage, {exclusive: true, consumerTag: '_definition-execution'});
300
-
301
- execution = execution || DefinitionExecution(definitionApi, context);
302
-
303
- if (executeMessage.fields.redelivered) {
304
- publishEvent('resume', content);
305
- }
306
-
307
- return execution.execute(executeMessage);
368
+ case 'run.execute': {
369
+ this[kStatus] = 'executing';
370
+ const executeMessage = cloneMessage(message);
371
+ if (fields.redelivered && !exec.execution) {
372
+ executeMessage.fields.redelivered = undefined;
308
373
  }
309
- case 'run.end': {
310
- if (status === 'end') break;
374
+ this[kExecuteMessage] = message;
375
+ this.broker.getQueue('execution-q').assertConsumer(this[kMessageHandlers].onExecutionMessage, {
376
+ exclusive: true,
377
+ consumerTag: '_definition-execution',
378
+ });
311
379
 
312
- counters.completed++;
380
+ exec.execution = exec.execution || new DefinitionExecution(this, this.context);
313
381
 
314
- logger.debug(`<${executionId} (${id})> completed`);
315
- status = 'end';
316
- broker.publish('run', 'run.leave', content);
317
- publishEvent('end', content);
318
- break;
382
+ if (executeMessage.fields.redelivered) {
383
+ this._publishEvent('resume', content);
319
384
  }
320
- case 'run.discarded': {
321
- if (status === 'discarded') break;
322
385
 
323
- counters.discarded++;
386
+ return exec.execution.execute(executeMessage);
387
+ }
388
+ case 'run.end': {
389
+ if (this[kStatus] === 'end') break;
324
390
 
325
- status = 'discarded';
326
- broker.publish('run', 'run.leave', content);
327
- break;
328
- }
329
- case 'run.error': {
330
- publishEvent('error', cloneContent(content, {
331
- error: fields.redelivered ? makeErrorFromMessage(message) : content.error,
332
- }), {mandatory: true});
333
- break;
334
- }
335
- case 'run.leave': {
336
- ack();
337
- status = undefined;
338
- deactivateRunConsumers();
391
+ this[kCounters].completed++;
339
392
 
340
- publishEvent('leave');
341
- break;
342
- }
393
+ this.logger.debug(`<${this.executionId} (${this.id})> completed`);
394
+ this[kStatus] = 'end';
395
+ this.broker.publish('run', 'run.leave', content);
396
+ this._publishEvent('end', content);
397
+ break;
398
+ }
399
+ case 'run.error': {
400
+ this._publishEvent('error', {
401
+ ...content,
402
+ error: fields.redelivered ? makeErrorFromMessage(message) : content.error,
403
+ }, {mandatory: true});
404
+ break;
343
405
  }
406
+ case 'run.discarded': {
407
+ if (this[kStatus] === 'discarded') break;
344
408
 
345
- ack();
409
+ this[kCounters].discarded++;
346
410
 
347
- function onResumeMessage() {
411
+ this[kStatus] = 'discarded';
412
+ this.broker.publish('run', 'run.leave', content);
413
+ break;
414
+ }
415
+ case 'run.leave': {
348
416
  message.ack();
417
+ this[kStatus] = undefined;
418
+ this._deactivateRunConsumers();
349
419
 
350
- switch (stateMessage.fields.routingKey) {
351
- case 'run.enter':
352
- case 'run.start':
353
- case 'run.discarded':
354
- case 'run.end':
355
- case 'run.leave':
356
- break;
357
- default:
358
- return;
359
- }
360
-
361
- if (!stateMessage.fields.redelivered) return;
362
-
363
- logger.debug(`<${id}> resume from ${status}`);
364
-
365
- return broker.publish('run', stateMessage.fields.routingKey, cloneContent(stateMessage.content), stateMessage.properties);
420
+ this._publishEvent('leave', this._createMessage());
421
+ return;
366
422
  }
367
423
  }
368
424
 
369
- function onExecutionMessage(routingKey, message) {
370
- const {content, properties} = message;
371
- const messageType = properties.type;
425
+ message.ack();
426
+ };
372
427
 
373
- message.ack();
374
-
375
- switch (messageType) {
376
- case 'stopped': {
377
- deactivateRunConsumers();
378
- return publishEvent('stop');
379
- }
380
- case 'error': {
381
- broker.publish('run', 'run.error', content);
382
- broker.publish('run', 'run.discarded', content);
383
- break;
384
- }
385
- default: {
386
- broker.publish('run', 'run.end', content);
387
- }
388
- }
428
+ proto._onResumeMessage = function onResumeMessage(message) {
429
+ message.ack();
389
430
 
390
- if (postponedMessage) {
391
- const ackMessage = postponedMessage;
392
- postponedMessage = null;
393
- ackMessage.ack();
394
- }
395
- }
431
+ const stateMessage = this[kStateMessage];
396
432
 
397
- function publishEvent(action, content = {}, msgOpts) {
398
- broker.publish('event', `definition.${action}`, execution ? execution.createMessage(content) : content, {type: action, ...msgOpts});
433
+ switch (stateMessage.fields.routingKey) {
434
+ case 'run.discarded':
435
+ case 'run.end':
436
+ case 'run.leave':
437
+ break;
438
+ default:
439
+ return;
399
440
  }
400
441
 
401
- function getState() {
402
- return createMessage({
403
- executionId,
404
- status,
405
- stopped,
406
- counters: {...counters},
407
- environment: environment.getState(),
408
- execution: execution && execution.getState(),
409
- broker: broker.getState(true),
410
- });
411
- }
442
+ if (!stateMessage.fields.redelivered) return;
412
443
 
413
- function getProcesses() {
414
- if (!processes) loadProcesses();
415
- return processes;
416
- }
444
+ this._debug(`resume from ${this.status}`);
417
445
 
418
- function getExecutableProcesses() {
419
- if (!processes) loadProcesses();
420
- return executableProcesses;
421
- }
446
+ return this.broker.publish('run', stateMessage.fields.routingKey, cloneContent(stateMessage.content), stateMessage.properties);
447
+ };
422
448
 
423
- function getProcessById(processId) {
424
- return getProcesses().find((p) => p.id === processId);
425
- }
449
+ proto._onExecutionMessage = function onExecutionMessage(routingKey, message) {
450
+ const {content, properties} = message;
451
+ const messageType = properties.type;
426
452
 
427
- function loadProcesses() {
428
- if (processes) return processes;
429
- executableProcesses = context.getExecutableProcesses() || [];
430
- processes = context.getProcesses() || [];
431
- logger.debug(`<${id}> found ${processes.length} processes`);
432
- }
453
+ message.ack();
433
454
 
434
- function getActivityById(childId) {
435
- let child;
436
- const siblings = getProcesses();
437
- for (let i = 0; i < siblings.length; i++) {
438
- child = siblings[i].getActivityById(childId);
439
- if (child) return child;
455
+ switch (messageType) {
456
+ case 'stopped': {
457
+ return this._onStop();
458
+ }
459
+ case 'error': {
460
+ this.broker.publish('run', 'run.error', content);
461
+ this.broker.publish('run', 'run.discarded', content);
462
+ break;
463
+ }
464
+ default: {
465
+ this.broker.publish('run', 'run.end', content);
440
466
  }
441
- return child;
442
467
  }
443
468
 
444
- function getElementById(elementId) {
445
- return context.getActivityById(elementId);
446
- }
469
+ const executeMessage = this[kExecuteMessage];
470
+ this[kExecuteMessage] = null;
471
+ executeMessage.ack();
472
+ };
447
473
 
448
- function getPostponed(...args) {
449
- if (!execution) return [];
450
- return execution.getPostponed(...args);
451
- }
452
-
453
- function getApi(message) {
454
- if (execution) return execution.getApi(message);
455
- if (!message || !stateMessage) throw new Error('Definition is not running');
456
- return DefinitionApi(broker, message || stateMessage);
474
+ proto._onApiMessage = function onApiMessage(routingKey, message) {
475
+ if (message.properties.type === 'stop') {
476
+ const execution = this.execution;
477
+ if (!execution || execution.completed) {
478
+ this._onStop();
479
+ }
457
480
  }
481
+ };
458
482
 
459
- function signal(message) {
460
- return getApi().signal(message, {delegate: true});
483
+ proto._publishEvent = function publishEvent(action, content, msgOpts) {
484
+ const execution = this.execution;
485
+ this.broker.publish('event', `definition.${action}`, execution ? execution._createMessage(content) : cloneContent(content), {
486
+ type: action,
487
+ ...msgOpts,
488
+ });
489
+ };
490
+
491
+ proto._onStop = function onStop() {
492
+ this[kStopped] = true;
493
+ this._deactivateRunConsumers();
494
+ return this._publishEvent('stop', this._createMessage());
495
+ };
496
+
497
+ proto._onBrokerReturnFn = function onBrokerReturn(message) {
498
+ if (message.properties.type === 'error') {
499
+ this._deactivateRunConsumers();
500
+ const err = makeErrorFromMessage(message);
501
+ throw err;
461
502
  }
503
+ };
462
504
 
463
- function cancelActivity(message) {
464
- return getApi().cancel(message, {delegate: true});
465
- }
505
+ proto._reset = function reset() {
506
+ this[kExec].executionId = undefined;
507
+ this._deactivateRunConsumers();
508
+ this.broker.purgeQueue('run-q');
509
+ this.broker.purgeQueue('execution-q');
510
+ };
466
511
 
467
- function sendMessage(message) {
468
- const messageContent = {message};
469
- let messageType = 'message';
470
- const reference = message && message.id && getElementById(message.id);
471
- if (reference && reference.resolve) {
472
- const resolvedReference = reference.resolve(createMessage({message}));
473
- messageType = resolvedReference.messageType || messageType;
474
- messageContent.message = {...message, ...resolvedReference};
475
- }
512
+ proto._debug = function debug(msg) {
513
+ this.logger.debug(`<${this.id}> ${msg}`);
514
+ };
476
515
 
477
- return getApi().sendApiMessage(messageType, messageContent, {delegate: true});
478
- }
516
+ function addConsumerCallbacks(definition, callback) {
517
+ const broker = definition.broker;
518
+ clearConsumers();
479
519
 
480
- function onApiMessage(routingKey, message) {
481
- const messageType = message.properties.type;
520
+ broker.subscribeOnce('event', 'definition.stop', cbLeave, {consumerTag: '_definition-callback-stop'});
521
+ broker.subscribeOnce('event', 'definition.leave', cbLeave, {consumerTag: '_definition-callback-leave'});
522
+ broker.subscribeOnce('event', 'definition.error', cbError, {consumerTag: '_definition-callback-error'});
482
523
 
483
- switch (messageType) {
484
- case 'stop': {
485
- if (execution && !execution.completed) return;
486
- onStop();
487
- break;
488
- }
489
- }
524
+ function cbLeave(_, message) {
525
+ clearConsumers();
526
+ return callback(null, definition.getApi(message));
490
527
  }
491
528
 
492
- function onStop() {
493
- stopped = true;
494
- deactivateRunConsumers();
495
- return publishEvent('stop');
529
+ function cbError(_, message) {
530
+ clearConsumers();
531
+ definition._reset();
532
+ return callback(makeErrorFromMessage(message));
496
533
  }
497
534
 
498
- function reset() {
499
- executionId = undefined;
500
- deactivateRunConsumers();
501
- runQ.purge();
502
- executionQ.purge();
535
+ function clearConsumers() {
536
+ broker.cancel('_definition-callback-stop');
537
+ broker.cancel('_definition-callback-leave');
538
+ broker.cancel('_definition-callback-error');
503
539
  }
504
540
  }