bpmn-elements 8.2.4 → 9.1.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 (127) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +1 -1
  3. package/dist/{src/Api.js → Api.js} +11 -12
  4. package/dist/{src/Context.js → Context.js} +26 -27
  5. package/dist/{src/Environment.js → Environment.js} +15 -16
  6. package/dist/{src/EventBroker.js → EventBroker.js} +5 -1
  7. package/dist/{src/Expressions.js → Expressions.js} +1 -1
  8. package/dist/{src/MessageFormatter.js → MessageFormatter.js} +3 -3
  9. package/dist/Tracker.js +89 -0
  10. package/dist/{src/activity → activity}/Activity.js +109 -120
  11. package/dist/{src/activity → activity}/ActivityExecution.js +28 -32
  12. package/dist/{src/activity → activity}/Dummy.js +1 -1
  13. package/dist/{src/activity → activity}/ExecutionScope.js +2 -2
  14. package/dist/{src/definition → definition}/Definition.js +64 -59
  15. package/dist/{src/definition → definition}/DefinitionExecution.js +68 -46
  16. package/dist/{src/error → error}/Errors.js +1 -1
  17. package/dist/eventDefinitions/CancelEventDefinition.js +127 -0
  18. package/dist/{src/eventDefinitions → eventDefinitions}/CompensateEventDefinition.js +64 -52
  19. package/dist/{src/eventDefinitions → eventDefinitions}/ConditionalEventDefinition.js +24 -16
  20. package/dist/{src/eventDefinitions → eventDefinitions}/ErrorEventDefinition.js +15 -14
  21. package/dist/{src/eventDefinitions → eventDefinitions}/EscalationEventDefinition.js +12 -13
  22. package/dist/{src/eventDefinitions → eventDefinitions}/EventDefinitionExecution.js +10 -11
  23. package/dist/{src/eventDefinitions → eventDefinitions}/LinkEventDefinition.js +14 -15
  24. package/dist/{src/eventDefinitions → eventDefinitions}/MessageEventDefinition.js +13 -14
  25. package/dist/{src/eventDefinitions → eventDefinitions}/SignalEventDefinition.js +13 -14
  26. package/dist/{src/eventDefinitions → eventDefinitions}/TerminateEventDefinition.js +1 -1
  27. package/dist/{src/eventDefinitions → eventDefinitions}/TimerEventDefinition.js +15 -16
  28. package/dist/{src/events → events}/BoundaryEvent.js +39 -25
  29. package/dist/{src/events → events}/EndEvent.js +3 -3
  30. package/dist/{src/events → events}/IntermediateCatchEvent.js +3 -3
  31. package/dist/{src/events → events}/IntermediateThrowEvent.js +3 -3
  32. package/dist/{src/events → events}/StartEvent.js +8 -9
  33. package/dist/{src/flows → flows}/Association.js +14 -22
  34. package/dist/{src/flows → flows}/MessageFlow.js +16 -14
  35. package/dist/{src/flows → flows}/SequenceFlow.js +16 -18
  36. package/dist/{src/gateways → gateways}/EventBasedGateway.js +3 -4
  37. package/dist/{src/gateways → gateways}/ExclusiveGateway.js +2 -2
  38. package/dist/{src/gateways → gateways}/InclusiveGateway.js +2 -2
  39. package/dist/{src/gateways → gateways}/ParallelGateway.js +2 -2
  40. package/dist/index.js +48 -48
  41. package/dist/{src/io → io}/InputOutputSpecification.js +8 -9
  42. package/dist/{src/io → io}/Properties.js +7 -8
  43. package/dist/package.json +3 -0
  44. package/dist/{src/process → process}/Process.js +44 -40
  45. package/dist/{src/process → process}/ProcessExecution.js +169 -78
  46. package/dist/{src/tasks → tasks}/CallActivity.js +7 -8
  47. package/dist/{src/tasks → tasks}/LoopCharacteristics.js +2 -2
  48. package/dist/{src/tasks → tasks}/ReceiveTask.js +14 -15
  49. package/dist/{src/tasks → tasks}/ScriptTask.js +4 -4
  50. package/dist/{src/tasks → tasks}/ServiceImplementation.js +1 -1
  51. package/dist/{src/tasks → tasks}/ServiceTask.js +6 -7
  52. package/dist/{src/tasks → tasks}/SignalTask.js +7 -8
  53. package/dist/{src/tasks → tasks}/StandardLoopCharacteristics.js +1 -1
  54. package/dist/{src/tasks → tasks}/SubProcess.js +19 -19
  55. package/dist/{src/tasks → tasks}/Task.js +2 -2
  56. package/dist/{src/tasks → tasks}/Transaction.js +1 -1
  57. package/package.json +31 -31
  58. package/src/Api.js +11 -13
  59. package/src/Context.js +26 -28
  60. package/src/Environment.js +15 -17
  61. package/src/EventBroker.js +2 -1
  62. package/src/Expressions.js +1 -1
  63. package/src/MessageFormatter.js +3 -3
  64. package/src/Tracker.js +73 -0
  65. package/src/activity/Activity.js +106 -114
  66. package/src/activity/ActivityExecution.js +28 -32
  67. package/src/activity/Dummy.js +1 -1
  68. package/src/activity/ExecutionScope.js +2 -2
  69. package/src/definition/Definition.js +65 -64
  70. package/src/definition/DefinitionExecution.js +71 -47
  71. package/src/error/Errors.js +1 -1
  72. package/src/eventDefinitions/CancelEventDefinition.js +32 -78
  73. package/src/eventDefinitions/CompensateEventDefinition.js +58 -52
  74. package/src/eventDefinitions/ConditionalEventDefinition.js +25 -17
  75. package/src/eventDefinitions/ErrorEventDefinition.js +15 -15
  76. package/src/eventDefinitions/EscalationEventDefinition.js +12 -14
  77. package/src/eventDefinitions/EventDefinitionExecution.js +10 -12
  78. package/src/eventDefinitions/LinkEventDefinition.js +14 -16
  79. package/src/eventDefinitions/MessageEventDefinition.js +13 -15
  80. package/src/eventDefinitions/SignalEventDefinition.js +13 -15
  81. package/src/eventDefinitions/TerminateEventDefinition.js +1 -1
  82. package/src/eventDefinitions/TimerEventDefinition.js +15 -17
  83. package/src/events/BoundaryEvent.js +34 -24
  84. package/src/events/EndEvent.js +3 -3
  85. package/src/events/IntermediateCatchEvent.js +3 -3
  86. package/src/events/IntermediateThrowEvent.js +3 -3
  87. package/src/events/StartEvent.js +8 -10
  88. package/src/flows/Association.js +14 -26
  89. package/src/flows/MessageFlow.js +14 -15
  90. package/src/flows/SequenceFlow.js +16 -20
  91. package/src/gateways/EventBasedGateway.js +3 -4
  92. package/src/gateways/ExclusiveGateway.js +2 -2
  93. package/src/gateways/InclusiveGateway.js +2 -2
  94. package/src/gateways/ParallelGateway.js +2 -2
  95. package/src/index.js +106 -0
  96. package/src/io/InputOutputSpecification.js +8 -10
  97. package/src/io/Properties.js +7 -9
  98. package/src/process/Process.js +45 -41
  99. package/src/process/ProcessExecution.js +167 -79
  100. package/src/tasks/CallActivity.js +7 -9
  101. package/src/tasks/LoopCharacteristics.js +2 -2
  102. package/src/tasks/ReceiveTask.js +215 -217
  103. package/src/tasks/ScriptTask.js +4 -4
  104. package/src/tasks/ServiceImplementation.js +1 -1
  105. package/src/tasks/ServiceTask.js +6 -8
  106. package/src/tasks/SignalTask.js +7 -9
  107. package/src/tasks/StandardLoopCharacteristics.js +1 -1
  108. package/src/tasks/SubProcess.js +19 -20
  109. package/src/tasks/Task.js +2 -2
  110. package/src/tasks/Transaction.js +1 -1
  111. package/types/index.d.ts +520 -0
  112. package/dist/src/eventDefinitions/CancelEventDefinition.js +0 -184
  113. package/index.js +0 -106
  114. /package/dist/{src/ExtensionsMapper.js → ExtensionsMapper.js} +0 -0
  115. /package/dist/{src/Scripts.js → Scripts.js} +0 -0
  116. /package/dist/{src/Timers.js → Timers.js} +0 -0
  117. /package/dist/{src/activity → activity}/Escalation.js +0 -0
  118. /package/dist/{src/activity → activity}/Message.js +0 -0
  119. /package/dist/{src/activity → activity}/Signal.js +0 -0
  120. /package/dist/{src/error → error}/BpmnError.js +0 -0
  121. /package/dist/{src/getPropertyValue.js → getPropertyValue.js} +0 -0
  122. /package/dist/{src/io → io}/BpmnIO.js +0 -0
  123. /package/dist/{src/io → io}/EnvironmentDataObject.js +0 -0
  124. /package/dist/{src/io → io}/EnvironmentDataStore.js +0 -0
  125. /package/dist/{src/io → io}/EnvironmentDataStoreReference.js +0 -0
  126. /package/dist/{src/messageHelper.js → messageHelper.js} +0 -0
  127. /package/dist/{src/shared.js → shared.js} +0 -0
@@ -1,6 +1,7 @@
1
- import {ProcessApi} from '../Api';
2
- import {cloneContent, cloneMessage, pushParent} from '../messageHelper';
3
- import {getUniqueId} from '../shared';
1
+ import {ProcessApi} from '../Api.js';
2
+ import {cloneContent, cloneMessage, pushParent} from '../messageHelper.js';
3
+ import {getUniqueId} from '../shared.js';
4
+ import {ActivityTracker} from '../Tracker.js';
4
5
 
5
6
  export default ProcessExecution;
6
7
 
@@ -13,14 +14,16 @@ const kMessageHandlers = Symbol.for('messageHandlers');
13
14
  const kParent = Symbol.for('parent');
14
15
  const kStatus = Symbol.for('status');
15
16
  const kStopped = Symbol.for('stopped');
17
+ const kTracker = Symbol.for('activity tracker');
16
18
 
17
19
  function ProcessExecution(parentActivity, context) {
18
- const {id, type, broker, isSubProcess} = parentActivity;
20
+ const {id, type, broker, isSubProcess, isTransaction} = parentActivity;
19
21
 
20
22
  this[kParent] = parentActivity;
21
23
  this.id = id;
22
24
  this.type = type;
23
25
  this.isSubProcess = isSubProcess;
26
+ this.isTransaction = isSubProcess && isTransaction;
24
27
  this.broker = broker;
25
28
  this.environment = context.environment;
26
29
  this.context = context;
@@ -44,6 +47,7 @@ function ProcessExecution(parentActivity, context) {
44
47
  this[kStopped] = false;
45
48
  this[kActivated] = false;
46
49
  this[kStatus] = 'init';
50
+ this[kTracker] = new ActivityTracker(id);
47
51
  this.executionId = undefined;
48
52
 
49
53
  this[kMessageHandlers] = {
@@ -54,42 +58,46 @@ function ProcessExecution(parentActivity, context) {
54
58
  };
55
59
  }
56
60
 
57
- const proto = ProcessExecution.prototype;
58
-
59
- Object.defineProperty(proto, 'stopped', {
61
+ Object.defineProperty(ProcessExecution.prototype, 'stopped', {
60
62
  enumerable: true,
61
63
  get() {
62
64
  return this[kStopped];
63
65
  },
64
66
  });
65
67
 
66
- Object.defineProperty(proto, 'completed', {
68
+ Object.defineProperty(ProcessExecution.prototype, 'completed', {
67
69
  enumerable: true,
68
70
  get() {
69
71
  return this[kCompleted];
70
72
  },
71
73
  });
72
74
 
73
- Object.defineProperty(proto, 'status', {
75
+ Object.defineProperty(ProcessExecution.prototype, 'status', {
74
76
  enumerable: true,
75
77
  get() {
76
78
  return this[kStatus];
77
79
  },
78
80
  });
79
81
 
80
- Object.defineProperty(proto, 'postponedCount', {
82
+ Object.defineProperty(ProcessExecution.prototype, 'postponedCount', {
81
83
  get() {
82
84
  return this[kElements].postponed.length;
83
85
  },
84
86
  });
85
87
 
86
- Object.defineProperty(proto, 'isRunning', {
88
+ Object.defineProperty(ProcessExecution.prototype, 'isRunning', {
87
89
  get() {
88
90
  return this[kActivated];
89
91
  },
90
92
  });
91
93
 
92
- proto.execute = function execute(executeMessage) {
94
+ Object.defineProperty(ProcessExecution.prototype, 'activityStatus', {
95
+ get() {
96
+ return this[kTracker].activityStatus;
97
+ },
98
+ });
99
+
100
+ ProcessExecution.prototype.execute = function execute(executeMessage) {
93
101
  if (!executeMessage) throw new Error('Process execution requires message');
94
102
  if (!executeMessage.content || !executeMessage.content.executionId) throw new Error('Process execution requires execution id');
95
103
 
@@ -115,7 +123,7 @@ proto.execute = function execute(executeMessage) {
115
123
  return true;
116
124
  };
117
125
 
118
- proto.resume = function resume() {
126
+ ProcessExecution.prototype.resume = function resume() {
119
127
  this._debug(`resume process execution at ${this.status}`);
120
128
 
121
129
  if (this[kCompleted]) return this._complete('completed');
@@ -141,6 +149,7 @@ proto.resume = function resume() {
141
149
  const status = this.status;
142
150
  if (status === 'init') return this._start();
143
151
 
152
+ const tracker = this[kTracker];
144
153
  for (const msg of postponed.slice()) {
145
154
  const activity = this.getActivityById(msg.content.id);
146
155
  if (!activity) continue;
@@ -150,6 +159,8 @@ proto.resume = function resume() {
150
159
  msg.ack();
151
160
  continue;
152
161
  }
162
+
163
+ tracker.track(msg.fields.routingKey, msg);
153
164
  activity.resume();
154
165
  }
155
166
 
@@ -158,7 +169,7 @@ proto.resume = function resume() {
158
169
  if (!postponed.length && status === 'executing') return this._complete('completed');
159
170
  };
160
171
 
161
- proto.recover = function recover(state) {
172
+ ProcessExecution.prototype.recover = function recover(state) {
162
173
  if (!state) return this;
163
174
  this.executionId = state.executionId;
164
175
 
@@ -204,7 +215,7 @@ proto.recover = function recover(state) {
204
215
  return this;
205
216
  };
206
217
 
207
- proto.shake = function shake(fromId) {
218
+ ProcessExecution.prototype.shake = function shake(fromId) {
208
219
  let executing = true;
209
220
  const id = this.id;
210
221
  if (!this.isRunning) {
@@ -239,11 +250,11 @@ proto.shake = function shake(fromId) {
239
250
  return result;
240
251
  };
241
252
 
242
- proto.stop = function stop() {
253
+ ProcessExecution.prototype.stop = function stop() {
243
254
  this.getApi().stop();
244
255
  };
245
256
 
246
- proto.getPostponed = function getPostponed(filterFn) {
257
+ ProcessExecution.prototype.getPostponed = function getPostponed(filterFn) {
247
258
  const result = [];
248
259
  for (const msg of this[kElements].postponed.slice()) {
249
260
  const api = this._getChildApi(msg);
@@ -254,7 +265,7 @@ proto.getPostponed = function getPostponed(filterFn) {
254
265
  return result;
255
266
  };
256
267
 
257
- proto.discard = function discard() {
268
+ ProcessExecution.prototype.discard = function discard() {
258
269
  this[kStatus] = 'discard';
259
270
  return this[kActivityQ].queueMessage({routingKey: 'execution.discard'}, {
260
271
  id: this.id,
@@ -263,7 +274,15 @@ proto.discard = function discard() {
263
274
  }, {type: 'discard'});
264
275
  };
265
276
 
266
- proto.getState = function getState() {
277
+ ProcessExecution.prototype.cancel = function discard() {
278
+ return this[kActivityQ].queueMessage({ routingKey: 'execution.cancel' }, {
279
+ id: this.id,
280
+ type: this.type,
281
+ executionId: this.executionId,
282
+ }, { type: 'cancel' });
283
+ };
284
+
285
+ ProcessExecution.prototype.getState = function getState() {
267
286
  const {children, flows, outboundMessageFlows, associations} = this[kElements];
268
287
  return {
269
288
  executionId: this.executionId,
@@ -281,19 +300,23 @@ proto.getState = function getState() {
281
300
  };
282
301
  };
283
302
 
284
- proto.getActivities = function getActivities() {
303
+ ProcessExecution.prototype.getActivities = function getActivities() {
285
304
  return this[kElements].children.slice();
286
305
  };
287
306
 
288
- proto.getActivityById = function getActivityById(activityId) {
307
+ ProcessExecution.prototype.getActivityById = function getActivityById(activityId) {
289
308
  return this[kElements].children.find((child) => child.id === activityId);
290
309
  };
291
310
 
292
- proto.getSequenceFlows = function getSequenceFlows() {
311
+ ProcessExecution.prototype.getSequenceFlows = function getSequenceFlows() {
293
312
  return this[kElements].flows.slice();
294
313
  };
295
314
 
296
- proto.getApi = function getApi(message) {
315
+ ProcessExecution.prototype.getAssociations = function getAssociations() {
316
+ return this[kElements].associations.slice();
317
+ };
318
+
319
+ ProcessExecution.prototype.getApi = function getApi(message) {
297
320
  if (!message) return ProcessApi(this.broker, this[kExecuteMessage]);
298
321
 
299
322
  const content = message.content;
@@ -317,7 +340,7 @@ proto.getApi = function getApi(message) {
317
340
  return api;
318
341
  };
319
342
 
320
- proto._start = function start() {
343
+ ProcessExecution.prototype._start = function start() {
321
344
  if (this[kElements].children.length === 0) {
322
345
  return this._complete('completed');
323
346
  }
@@ -334,6 +357,7 @@ proto._start = function start() {
334
357
  }
335
358
 
336
359
  for (const a of startActivities) a.init();
360
+ this[kStatus] = 'executing';
337
361
  for (const a of startActivities) a.run();
338
362
 
339
363
  postponed.splice(0);
@@ -344,7 +368,7 @@ proto._start = function start() {
344
368
  });
345
369
  };
346
370
 
347
- proto._activate = function activate() {
371
+ ProcessExecution.prototype._activate = function activate() {
348
372
  const {onApiMessage, onMessageFlowEvent, onActivityEvent} = this[kMessageHandlers];
349
373
 
350
374
  if (!this.isSubProcess) {
@@ -406,7 +430,7 @@ proto._activate = function activate() {
406
430
  this[kActivated] = true;
407
431
  };
408
432
 
409
- proto._deactivate = function deactivate() {
433
+ ProcessExecution.prototype._deactivate = function deactivate() {
410
434
  const broker = this.broker;
411
435
  const executionId = this.executionId;
412
436
  broker.cancel(`_process-api-consumer-${executionId}`);
@@ -436,7 +460,7 @@ proto._deactivate = function deactivate() {
436
460
  this[kActivated] = false;
437
461
  };
438
462
 
439
- proto._onDelegateEvent = function onDelegateEvent(message) {
463
+ ProcessExecution.prototype._onDelegateEvent = function onDelegateEvent(message) {
440
464
  const eventType = message.properties.type;
441
465
  let delegate = true;
442
466
 
@@ -459,11 +483,11 @@ proto._onDelegateEvent = function onDelegateEvent(message) {
459
483
  return delegate;
460
484
  };
461
485
 
462
- proto._onMessageFlowEvent = function onMessageFlowEvent(routingKey, message) {
486
+ ProcessExecution.prototype._onMessageFlowEvent = function onMessageFlowEvent(routingKey, message) {
463
487
  this.broker.publish('message', routingKey, cloneContent(message.content), message.properties);
464
488
  };
465
489
 
466
- proto._onActivityEvent = function onActivityEvent(routingKey, message) {
490
+ ProcessExecution.prototype._onActivityEvent = function onActivityEvent(routingKey, message) {
467
491
  if (message.fields.redelivered && message.properties.persistent === false) return;
468
492
 
469
493
  const content = message.content;
@@ -480,10 +504,10 @@ proto._onActivityEvent = function onActivityEvent(routingKey, message) {
480
504
 
481
505
  if (delegate) delegate = this._onDelegateEvent(message);
482
506
 
507
+ this[kTracker].track(routingKey, message);
483
508
  this.broker.publish('event', routingKey, content, {...message.properties, delegate, mandatory: false});
484
509
  if (shaking) return this._onShookEnd(message);
485
510
  if (!isDirectChild) return;
486
- if (content.isAssociation) return;
487
511
 
488
512
  switch (routingKey) {
489
513
  case 'process.terminate':
@@ -495,7 +519,7 @@ proto._onActivityEvent = function onActivityEvent(routingKey, message) {
495
519
  this[kActivityQ].queueMessage(message.fields, cloneContent(content), {persistent: true, ...message.properties});
496
520
  };
497
521
 
498
- proto._onChildMessage = function onChildMessage(routingKey, message) {
522
+ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey, message) {
499
523
  if (message.fields.redelivered && message.properties.persistent === false) return message.ack();
500
524
 
501
525
  const content = message.content;
@@ -510,6 +534,16 @@ proto._onChildMessage = function onChildMessage(routingKey, message) {
510
534
  case 'execution.discard':
511
535
  message.ack();
512
536
  return this._onDiscard(message);
537
+ case 'execution.discard.detached': {
538
+ message.ack();
539
+ for (const detached of this[kElements].detachedActivities) {
540
+ this._getChildApi(detached).discard();
541
+ }
542
+ return;
543
+ }
544
+ case 'execution.cancel':
545
+ message.ack();
546
+ return this._onCancel(message);
513
547
  case 'activity.error.caught': {
514
548
  const prevMsg = this[kElements].postponed.find((msg) => {
515
549
  return msg.content.executionId === content.executionId;
@@ -517,7 +551,6 @@ proto._onChildMessage = function onChildMessage(routingKey, message) {
517
551
  if (!prevMsg) return message.ack();
518
552
  break;
519
553
  }
520
- case 'activity.compensation.end':
521
554
  case 'flow.looped':
522
555
  case 'activity.leave':
523
556
  return this._onChildCompleted(message);
@@ -530,14 +563,16 @@ proto._onChildMessage = function onChildMessage(routingKey, message) {
530
563
  this[kElements].detachedActivities.push(cloneMessage(message));
531
564
  break;
532
565
  }
566
+ case 'activity.cancel': {
567
+ if (this.isTransaction) this._onCancel(message);
568
+ break;
569
+ }
533
570
  case 'activity.discard':
534
- case 'activity.compensation.start':
535
571
  case 'activity.enter': {
536
- this[kStatus] = 'executing';
537
572
  if (!content.inbound) break;
538
573
 
539
574
  for (const inbound of content.inbound) {
540
- if (!inbound.isSequenceFlow) continue;
575
+ if (!inbound.isSequenceFlow && !inbound.isAssociation) continue;
541
576
  const inboundMessage = this._popPostponed(inbound);
542
577
  if (inboundMessage) inboundMessage.ack();
543
578
  }
@@ -558,17 +593,17 @@ proto._onChildMessage = function onChildMessage(routingKey, message) {
558
593
  }
559
594
  };
560
595
 
561
- proto._stateChangeMessage = function stateChangeMessage(message, postponeMessage) {
596
+ ProcessExecution.prototype._stateChangeMessage = function stateChangeMessage(message, postponeMessage) {
562
597
  const previousMsg = this._popPostponed(message.content);
563
598
  if (previousMsg) previousMsg.ack();
564
599
  if (postponeMessage) this[kElements].postponed.push(message);
565
600
  };
566
601
 
567
- proto._popPostponed = function popPostponed(byContent) {
602
+ ProcessExecution.prototype._popPostponed = function popPostponed(byContent) {
568
603
  const {postponed, detachedActivities} = this[kElements];
569
604
 
570
605
  const postponedIdx = postponed.findIndex((msg) => {
571
- if (msg.content.isSequenceFlow) return msg.content.sequenceId === byContent.sequenceId;
606
+ if (msg.content.isSequenceFlow || msg.content.isAssociation) return msg.content.sequenceId === byContent.sequenceId;
572
607
  return msg.content.executionId === byContent.executionId;
573
608
  });
574
609
 
@@ -583,7 +618,7 @@ proto._popPostponed = function popPostponed(byContent) {
583
618
  return postponedMsg;
584
619
  };
585
620
 
586
- proto._onChildCompleted = function onChildCompleted(message) {
621
+ ProcessExecution.prototype._onChildCompleted = function onChildCompleted(message) {
587
622
  this._stateChangeMessage(message, false);
588
623
  if (message.fields.redelivered) return message.ack();
589
624
 
@@ -600,9 +635,12 @@ proto._onChildCompleted = function onChildCompleted(message) {
600
635
 
601
636
  this._debug(`left <${id}> (${type}), pending runs ${postponedCount}, ${postponed.map((a) => a.content.id).join(',')}`);
602
637
 
603
- if (postponedCount === detachedActivities.length) {
604
- for (const api of this.getPostponed()) api.discard();
605
- return;
638
+ if (postponedCount && postponedCount === detachedActivities.length) {
639
+ return this[kActivityQ].queueMessage({ routingKey: 'execution.discard.detached' }, {
640
+ id: this.id,
641
+ type: this.type,
642
+ executionId: this.executionId,
643
+ }, { type: 'cancel' });
606
644
  }
607
645
 
608
646
  if (isEnd && startActivities.length) {
@@ -619,7 +657,7 @@ proto._onChildCompleted = function onChildCompleted(message) {
619
657
  }
620
658
  };
621
659
 
622
- proto._stopExecution = function stopExecution(message) {
660
+ ProcessExecution.prototype._stopExecution = function stopExecution(message) {
623
661
  const postponedCount = this.postponedCount;
624
662
  this._debug(`stop process execution (stop child executions ${postponedCount})`);
625
663
  if (postponedCount) {
@@ -633,40 +671,52 @@ proto._stopExecution = function stopExecution(message) {
633
671
  }, {type: 'stopped', persistent: false});
634
672
  };
635
673
 
636
- proto._onDiscard = function onDiscard() {
674
+ ProcessExecution.prototype._onDiscard = function onDiscard() {
637
675
  this._deactivate();
638
676
  const running = this[kElements].postponed.splice(0);
639
677
  this._debug(`discard process execution (discard child executions ${running.length})`);
640
678
 
641
- for (const flow of this.getSequenceFlows()) flow.stop();
642
- for (const msg of running) this._getChildApi(msg).discard();
679
+ if (this.isSubProcess) {
680
+ this.stop();
681
+ } else {
682
+ for (const flow of this.getSequenceFlows()) flow.stop();
683
+ for (const flow of this.getAssociations()) flow.stop();
684
+ for (const msg of running) this._getChildApi(msg).discard();
685
+ }
643
686
 
644
687
  this[kActivityQ].purge();
645
688
  return this._complete('discard');
646
689
  };
647
690
 
648
- proto._onApiMessage = function onApiMessage(routingKey, message) {
649
- const executionId = this.executionId;
650
- const broker = this.broker;
651
- if (message.properties.delegate) {
652
- const correlationId = message.properties.correlationId || getUniqueId(executionId);
653
- this._debug(`delegate api ${routingKey} message to children, with correlationId <${correlationId}>`);
654
-
655
- let consumed = false;
656
- broker.subscribeTmp('event', 'activity.consumed', (_, msg) => {
657
- if (msg.properties.correlationId === correlationId) {
658
- consumed = true;
659
- this._debug(`delegated api message was consumed by ${msg.content ? msg.content.executionId : 'unknown'}`);
660
- }
661
- }, {consumerTag: `_ct-delegate-${correlationId}`, noAck: true});
691
+ ProcessExecution.prototype._onCancel = function onCancel() {
692
+ const running = this[kElements].postponed.slice(0);
693
+ const isTransaction = this.isTransaction;
694
+
695
+ if (isTransaction) {
696
+ this._debug(`cancel transaction execution (cancel child executions ${running.length})`);
697
+ this[kStatus] = 'cancel';
698
+ this.broker.publish('event', 'transaction.cancel', cloneMessage(this[kExecuteMessage], {
699
+ state: 'cancel',
700
+ }));
662
701
 
663
- for (const child of this[kElements].children) {
664
- if (child.placeholder) continue;
665
- child.broker.publish('api', routingKey, cloneContent(message.content), message.properties);
666
- if (consumed) break;
702
+ for (const msg of running) {
703
+ if (msg.content.expect === 'compensate') {
704
+ this._getChildApi(msg).sendApiMessage('compensate');
705
+ } else if (!msg.content.isForCompensation) {
706
+ this._getChildApi(msg).discard();
707
+ }
708
+ }
709
+ } else {
710
+ this._debug(`cancel process execution (cancel child executions ${running.length})`);
711
+ for (const msg of running) {
712
+ this._getChildApi(msg).discard();
667
713
  }
714
+ }
715
+ };
668
716
 
669
- return broker.cancel(`_ct-delegate-${correlationId}`);
717
+ ProcessExecution.prototype._onApiMessage = function onApiMessage(routingKey, message) {
718
+ if (message.properties.delegate) {
719
+ return this._delegateApiMessage(routingKey, message);
670
720
  }
671
721
 
672
722
  if (this.id !== message.content.id) {
@@ -678,19 +728,56 @@ proto._onApiMessage = function onApiMessage(routingKey, message) {
678
728
  if (this.executionId !== message.content.executionId) return;
679
729
 
680
730
  switch (message.properties.type) {
731
+ case 'cancel':
732
+ return this.cancel(message);
681
733
  case 'discard':
682
734
  return this.discard(message);
683
735
  case 'stop':
684
- this[kActivityQ].queueMessage({routingKey: 'execution.stop'}, cloneContent(message.content), {persistent: false});
736
+ this[kActivityQ].queueMessage({ routingKey: 'execution.stop' }, cloneContent(message.content), { persistent: false });
685
737
  break;
686
738
  }
687
739
  };
688
740
 
689
- proto._complete = function complete(completionType, content) {
741
+ ProcessExecution.prototype._delegateApiMessage = function delegateApiMessage(routingKey, message, continueOnConsumed) {
742
+ const correlationId = message.properties.correlationId || getUniqueId(this.executionId);
743
+ this._debug(`delegate api ${routingKey} message to children, with correlationId <${correlationId}>`);
744
+
745
+ const broker = this.broker;
746
+ let consumed = false;
747
+ broker.subscribeTmp('event', 'activity.consumed', (_, msg) => {
748
+ if (msg.properties.correlationId === correlationId) {
749
+ consumed = true;
750
+ this._debug(`delegated api message was consumed by ${msg.content ? msg.content.executionId : 'unknown'}`);
751
+ }
752
+ }, { consumerTag: `_ct-delegate-${correlationId}`, noAck: true });
753
+
754
+ for (const child of this[kElements].children) {
755
+ if (child.placeholder) continue;
756
+ child.broker.publish('api', routingKey, cloneContent(message.content), message.properties);
757
+ if (consumed && !continueOnConsumed) break;
758
+ }
759
+
760
+ return broker.cancel(`_ct-delegate-${correlationId}`);
761
+ };
762
+
763
+ ProcessExecution.prototype._complete = function complete(completionType, content) {
690
764
  this._deactivate();
691
- this._debug(`process execution ${completionType}`);
692
765
  this[kCompleted] = true;
693
- if (this.status !== 'terminated') this[kStatus] = completionType;
766
+
767
+ const status = this.status;
768
+ switch (this.status) {
769
+ case 'cancel':
770
+ this._debug('process execution cancelled');
771
+ case 'discard':
772
+ completionType = status;
773
+ break;
774
+ case 'terminated':
775
+ break;
776
+ default:
777
+ this._debug(`process execution ${completionType}`);
778
+ this[kStatus] = completionType;
779
+ }
780
+
694
781
  const broker = this.broker;
695
782
  this[kActivityQ].delete();
696
783
 
@@ -701,17 +788,18 @@ proto._complete = function complete(completionType, content) {
701
788
  }), {type: completionType, mandatory: completionType === 'error'});
702
789
  };
703
790
 
704
- proto._terminate = function terminate(message) {
791
+ ProcessExecution.prototype._terminate = function terminate(message) {
705
792
  this[kStatus] = 'terminated';
706
793
  this._debug('terminating process execution');
707
794
 
708
795
  const running = this[kElements].postponed.splice(0);
709
796
  for (const flow of this.getSequenceFlows()) flow.stop();
797
+ for (const flow of this.getAssociations()) flow.stop();
710
798
 
711
799
  for (const msg of running) {
712
- const {id: postponedId, isSequenceFlow} = msg.content;
800
+ const {id: postponedId, isSequenceFlow, isAssociation} = msg.content;
713
801
  if (postponedId === message.content.id) continue;
714
- if (isSequenceFlow) continue;
802
+ if (isSequenceFlow || isAssociation) continue;
715
803
  this._getChildApi(msg).stop();
716
804
  msg.ack();
717
805
  }
@@ -719,23 +807,23 @@ proto._terminate = function terminate(message) {
719
807
  this[kActivityQ].purge();
720
808
  };
721
809
 
722
- proto._getFlowById = function getFlowById(flowId) {
810
+ ProcessExecution.prototype._getFlowById = function getFlowById(flowId) {
723
811
  return this[kElements].flows.find((f) => f.id === flowId);
724
812
  };
725
813
 
726
- proto._getAssociationById = function getAssociationById(associationId) {
814
+ ProcessExecution.prototype._getAssociationById = function getAssociationById(associationId) {
727
815
  return this[kElements].associations.find((a) => a.id === associationId);
728
816
  };
729
817
 
730
- proto._getMessageFlowById = function getMessageFlowById(flowId) {
818
+ ProcessExecution.prototype._getMessageFlowById = function getMessageFlowById(flowId) {
731
819
  return this[kElements].outboundMessageFlows.find((f) => f.id === flowId);
732
820
  };
733
821
 
734
- proto._getChildById = function getChildById(childId) {
822
+ ProcessExecution.prototype._getChildById = function getChildById(childId) {
735
823
  return this.getActivityById(childId) || this._getFlowById(childId);
736
824
  };
737
825
 
738
- proto._getChildApi = function getChildApi(message) {
826
+ ProcessExecution.prototype._getChildApi = function getChildApi(message) {
739
827
  const content = message.content;
740
828
 
741
829
  let child = this._getChildById(content.id);
@@ -754,12 +842,12 @@ proto._getChildApi = function getChildApi(message) {
754
842
  }
755
843
  };
756
844
 
757
- proto._onShookEnd = function onShookEnd(message) {
845
+ ProcessExecution.prototype._onShookEnd = function onShookEnd(message) {
758
846
  const routingKey = message.fields.routingKey;
759
847
  if (routingKey !== 'activity.shake.end') return;
760
848
  this[kElements].startSequences[message.content.id] = cloneMessage(message);
761
849
  };
762
850
 
763
- proto._debug = function debugMessage(logMessage) {
851
+ ProcessExecution.prototype._debug = function debugMessage(logMessage) {
764
852
  this[kParent].logger.debug(`<${this.executionId} (${this.id})> ${logMessage}`);
765
853
  };
@@ -1,6 +1,6 @@
1
- import Activity from '../activity/Activity';
2
- import {ActivityError} from '../error/Errors';
3
- import {cloneContent} from '../messageHelper';
1
+ import Activity from '../activity/Activity.js';
2
+ import {ActivityError} from '../error/Errors.js';
3
+ import {cloneContent} from '../messageHelper.js';
4
4
 
5
5
  export default function CallActivity(activityDef, context) {
6
6
  return new Activity(CallActivityBehaviour, activityDef, context);
@@ -18,9 +18,7 @@ export function CallActivityBehaviour(activity) {
18
18
  this.environment = activity.environment;
19
19
  }
20
20
 
21
- const proto = CallActivityBehaviour.prototype;
22
-
23
- proto.execute = function execute(executeMessage) {
21
+ CallActivityBehaviour.prototype.execute = function execute(executeMessage) {
24
22
  const executeContent = executeMessage.content;
25
23
  const loopCharacteristics = this.loopCharacteristics;
26
24
  if (loopCharacteristics && executeContent.isRootScope) {
@@ -59,7 +57,7 @@ proto.execute = function execute(executeMessage) {
59
57
  });
60
58
  };
61
59
 
62
- proto._onDelegatedApiMessage = function onDelegatedApiMessage(calledElement, executeMessage, routingKey, message) {
60
+ CallActivityBehaviour.prototype._onDelegatedApiMessage = function onDelegatedApiMessage(calledElement, executeMessage, routingKey, message) {
63
61
  if (!message.properties.delegate) return;
64
62
  const {content: delegateContent} = message;
65
63
  if (!delegateContent || !delegateContent.message) return;
@@ -82,7 +80,7 @@ proto._onDelegatedApiMessage = function onDelegatedApiMessage(calledElement, exe
82
80
  return this._onApiMessage(calledElement, executeMessage, routingKey, message);
83
81
  };
84
82
 
85
- proto._onApiMessage = function onApiMessage(calledElement, executeMessage, routingKey, message) {
83
+ CallActivityBehaviour.prototype._onApiMessage = function onApiMessage(calledElement, executeMessage, routingKey, message) {
86
84
  const {type: messageType, correlationId} = message.properties;
87
85
  const executeContent = executeMessage.content;
88
86
 
@@ -123,7 +121,7 @@ proto._onApiMessage = function onApiMessage(calledElement, executeMessage, routi
123
121
  }
124
122
  };
125
123
 
126
- proto._stop = function stop(executionId) {
124
+ CallActivityBehaviour.prototype._stop = function stop(executionId) {
127
125
  const broker = this.broker;
128
126
  broker.cancel(`_api-${executionId}`);
129
127
  broker.cancel(`_api-delegated-${executionId}`);
@@ -1,5 +1,5 @@
1
- import {RunError} from '../error/Errors';
2
- import {cloneContent, cloneMessage, unshiftParent, cloneParent} from '../messageHelper';
1
+ import {RunError} from '../error/Errors.js';
2
+ import {cloneContent, cloneMessage, unshiftParent, cloneParent} from '../messageHelper.js';
3
3
 
4
4
  export default function LoopCharacteristics(activity, loopCharacteristics) {
5
5
  this.activity = activity;