bpmn-elements 14.1.0 → 15.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 (64) hide show
  1. package/README.md +0 -4
  2. package/dist/Context.js +41 -35
  3. package/dist/Environment.js +4 -4
  4. package/dist/Expressions.js +1 -1
  5. package/dist/MessageFormatter.js +0 -1
  6. package/dist/Scripts.js +3 -8
  7. package/dist/Timers.js +5 -9
  8. package/dist/Tracker.js +15 -19
  9. package/dist/activity/Activity.js +68 -49
  10. package/dist/activity/ActivityExecution.js +43 -29
  11. package/dist/definition/Definition.js +20 -14
  12. package/dist/definition/DefinitionExecution.js +64 -55
  13. package/dist/eventDefinitions/EscalationEventDefinition.js +1 -1
  14. package/dist/eventDefinitions/LinkEventDefinition.js +1 -1
  15. package/dist/eventDefinitions/MessageEventDefinition.js +1 -1
  16. package/dist/eventDefinitions/SignalEventDefinition.js +1 -1
  17. package/dist/eventDefinitions/TimerEventDefinition.js +1 -1
  18. package/dist/events/BoundaryEvent.js +11 -9
  19. package/dist/events/EndEvent.js +1 -1
  20. package/dist/events/IntermediateCatchEvent.js +1 -1
  21. package/dist/events/IntermediateThrowEvent.js +1 -1
  22. package/dist/events/StartEvent.js +1 -1
  23. package/dist/flows/SequenceFlow.js +1 -1
  24. package/dist/gateways/EventBasedGateway.js +1 -1
  25. package/dist/gateways/ExclusiveGateway.js +1 -1
  26. package/dist/gateways/InclusiveGateway.js +1 -1
  27. package/dist/gateways/ParallelGateway.js +1 -1
  28. package/dist/index.js +1 -1
  29. package/dist/io/InputOutputSpecification.js +1 -1
  30. package/dist/io/Properties.js +1 -1
  31. package/dist/process/Process.js +20 -19
  32. package/dist/process/ProcessExecution.js +67 -40
  33. package/dist/shared.js +0 -8
  34. package/dist/tasks/CallActivity.js +1 -1
  35. package/dist/tasks/LoopCharacteristics.js +2 -2
  36. package/dist/tasks/ReceiveTask.js +1 -1
  37. package/dist/tasks/ScriptTask.js +3 -3
  38. package/dist/tasks/ServiceImplementation.js +1 -1
  39. package/dist/tasks/ServiceTask.js +1 -1
  40. package/dist/tasks/SignalTask.js +1 -1
  41. package/dist/tasks/StandardLoopCharacteristics.js +1 -1
  42. package/dist/tasks/SubProcess.js +30 -33
  43. package/dist/tasks/Task.js +1 -1
  44. package/dist/tasks/Transaction.js +1 -1
  45. package/package.json +4 -4
  46. package/src/Context.js +51 -35
  47. package/src/Environment.js +4 -4
  48. package/src/MessageFormatter.js +0 -3
  49. package/src/Scripts.js +3 -8
  50. package/src/Timers.js +5 -9
  51. package/src/Tracker.js +13 -17
  52. package/src/activity/Activity.js +57 -42
  53. package/src/activity/ActivityExecution.js +43 -26
  54. package/src/definition/Definition.js +19 -13
  55. package/src/definition/DefinitionExecution.js +64 -54
  56. package/src/eventDefinitions/TimerEventDefinition.js +1 -1
  57. package/src/events/BoundaryEvent.js +10 -8
  58. package/src/process/Process.js +20 -15
  59. package/src/process/ProcessExecution.js +70 -40
  60. package/src/shared.js +0 -8
  61. package/src/tasks/LoopCharacteristics.js +2 -2
  62. package/src/tasks/ScriptTask.js +2 -2
  63. package/src/tasks/SubProcess.js +31 -32
  64. package/types/types.d.ts +1 -1
@@ -29,15 +29,15 @@ function ProcessExecution(parentActivity, context) {
29
29
  this.context = context;
30
30
 
31
31
  this[kElements] = {
32
+ postponed: new Set(),
32
33
  children: context.getActivities(id),
33
34
  associations: context.getAssociations(id),
34
35
  flows: context.getSequenceFlows(id),
35
36
  outboundMessageFlows: context.getMessageFlows(id),
36
37
  startActivities: [],
37
38
  triggeredByEvent: [],
38
- detachedActivities: [],
39
+ detachedActivities: new Set(),
39
40
  startSequences: {},
40
- postponed: [],
41
41
  };
42
42
 
43
43
  const exchangeName = (this._exchangeName = isSubProcess ? 'subprocess-execution' : 'execution');
@@ -76,7 +76,7 @@ Object.defineProperties(ProcessExecution.prototype, {
76
76
  },
77
77
  postponedCount: {
78
78
  get() {
79
- return this[kElements].postponed.length;
79
+ return this[kElements].postponed.size;
80
80
  },
81
81
  },
82
82
  isRunning: {
@@ -130,8 +130,8 @@ ProcessExecution.prototype.resume = function resume() {
130
130
  for (const a of startActivities) a.shake();
131
131
  }
132
132
 
133
- postponed.splice(0);
134
- detachedActivities.splice(0);
133
+ postponed.clear();
134
+ detachedActivities.clear();
135
135
 
136
136
  this[kActivityQ].consume(this[kMessageHandlers].onChildMessage, {
137
137
  prefetch: 1000,
@@ -144,7 +144,7 @@ ProcessExecution.prototype.resume = function resume() {
144
144
  if (status === 'init') return this._start();
145
145
 
146
146
  const tracker = this[kTracker];
147
- for (const msg of postponed.slice()) {
147
+ for (const msg of new Set(postponed)) {
148
148
  const activity = this.getActivityById(msg.content.id);
149
149
  if (!activity) continue;
150
150
  if (msg.content.placeholder) continue;
@@ -160,7 +160,7 @@ ProcessExecution.prototype.resume = function resume() {
160
160
 
161
161
  if (this[kCompleted]) return;
162
162
 
163
- if (!postponed.length && status === 'executing') return this._complete('completed');
163
+ if (!postponed.size && status === 'executing') return this._complete('completed');
164
164
  };
165
165
 
166
166
  ProcessExecution.prototype.getState = function getState() {
@@ -283,7 +283,7 @@ ProcessExecution.prototype.stop = function stop() {
283
283
 
284
284
  ProcessExecution.prototype.getPostponed = function getPostponed(filterFn) {
285
285
  const result = [];
286
- for (const msg of this[kElements].postponed.slice()) {
286
+ for (const msg of this[kElements].postponed) {
287
287
  const api = this._getChildApi(msg);
288
288
  if (!api) continue;
289
289
  if (filterFn && !filterFn(api)) continue;
@@ -347,11 +347,12 @@ ProcessExecution.prototype.getApi = function getApi(message) {
347
347
  const self = this;
348
348
 
349
349
  api.getExecuting = function getExecuting() {
350
- return postponed.reduce((result, msg) => {
350
+ const result = [];
351
+ for (const msg of postponed) {
351
352
  const childApi = self._getChildApi(msg);
352
353
  if (childApi) result.push(childApi);
353
- return result;
354
- }, []);
354
+ }
355
+ return result;
355
356
  };
356
357
 
357
358
  return api;
@@ -377,8 +378,8 @@ ProcessExecution.prototype._start = function start() {
377
378
  this[kStatus] = 'executing';
378
379
  for (const a of startActivities) a.run();
379
380
 
380
- postponed.splice(0);
381
- detachedActivities.splice(0);
381
+ postponed.clear();
382
+ detachedActivities.clear();
382
383
  this[kActivityQ].assertConsumer(this[kMessageHandlers].onChildMessage, {
383
384
  prefetch: 1000,
384
385
  consumerTag: `_process-activity-${this.executionId}`,
@@ -565,9 +566,13 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
565
566
  message.ack();
566
567
  return this._onCancel(message);
567
568
  case 'activity.error.caught': {
568
- const prevMsg = this[kElements].postponed.find((msg) => {
569
- return msg.content.executionId === content.executionId;
570
- });
569
+ let prevMsg;
570
+ for (const msg of this[kElements].postponed) {
571
+ if (msg.content.executionId === content.executionId) {
572
+ prevMsg = msg;
573
+ break;
574
+ }
575
+ }
571
576
  if (!prevMsg) return message.ack();
572
577
  break;
573
578
  }
@@ -580,7 +585,7 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
580
585
 
581
586
  switch (routingKey) {
582
587
  case 'activity.detach': {
583
- this[kElements].detachedActivities.push(cloneMessage(message));
588
+ this[kElements].detachedActivities.add(cloneMessage(message));
584
589
  break;
585
590
  }
586
591
  case 'activity.cancel': {
@@ -600,10 +605,13 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
600
605
  break;
601
606
  }
602
607
  case 'activity.error': {
603
- const eventCaughtBy = this[kElements].postponed.find((msg) => {
604
- if (msg.fields.routingKey !== 'activity.catch') return;
605
- return msg.content.source && msg.content.source.executionId === content.executionId;
606
- });
608
+ let eventCaughtBy;
609
+ for (const msg of this[kElements].postponed) {
610
+ if (msg.fields.routingKey === 'activity.catch' && msg.content.source && msg.content.source.executionId === content.executionId) {
611
+ eventCaughtBy = msg;
612
+ break;
613
+ }
614
+ }
607
615
  if (eventCaughtBy) {
608
616
  this[kActivityQ].queueMessage({ routingKey: 'activity.error.caught' }, cloneContent(content), {
609
617
  persistent: true,
@@ -619,24 +627,38 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
619
627
  ProcessExecution.prototype._stateChangeMessage = function stateChangeMessage(message, postponeMessage) {
620
628
  const previousMsg = this._popPostponed(message.content);
621
629
  if (previousMsg) previousMsg.ack();
622
- if (postponeMessage) this[kElements].postponed.push(message);
630
+ if (postponeMessage) this[kElements].postponed.add(message);
623
631
  };
624
632
 
625
633
  ProcessExecution.prototype._popPostponed = function popPostponed(byContent) {
626
634
  const { postponed, detachedActivities } = this[kElements];
627
635
 
628
- const postponedIdx = postponed.findIndex((msg) => {
629
- if (msg.content.isSequenceFlow || msg.content.isAssociation) return msg.content.sequenceId === byContent.sequenceId;
630
- return msg.content.executionId === byContent.executionId;
631
- });
632
-
633
636
  let postponedMsg;
634
- if (postponedIdx > -1) {
635
- postponedMsg = postponed.splice(postponedIdx, 1)[0];
637
+ if (byContent.sequenceId) {
638
+ for (const msg of postponed) {
639
+ if (!msg.content.isSequenceFlow && !msg.content.isAssociation) continue;
640
+ if (msg.content.sequenceId === byContent.sequenceId) {
641
+ postponedMsg = msg;
642
+ break;
643
+ }
644
+ }
645
+ } else {
646
+ for (const msg of postponed) {
647
+ if (msg.content.executionId === byContent.executionId) {
648
+ postponedMsg = msg;
649
+ break;
650
+ }
651
+ }
636
652
  }
637
653
 
638
- const detachedIdx = detachedActivities.findIndex((msg) => msg.content.executionId === byContent.executionId);
639
- if (detachedIdx > -1) detachedActivities.splice(detachedIdx, 1);
654
+ if (postponedMsg) postponed.delete(postponedMsg);
655
+
656
+ for (const msg of detachedActivities) {
657
+ if (msg.content.executionId === byContent.executionId) {
658
+ detachedActivities.delete(msg);
659
+ break;
660
+ }
661
+ }
640
662
 
641
663
  return postponedMsg;
642
664
  };
@@ -648,7 +670,7 @@ ProcessExecution.prototype._onChildCompleted = function onChildCompleted(message
648
670
  const { id, type, isEnd } = message.content;
649
671
 
650
672
  const { postponed, detachedActivities, startActivities } = this[kElements];
651
- const postponedCount = postponed.length;
673
+ const postponedCount = postponed.size;
652
674
 
653
675
  if (!postponedCount) {
654
676
  this._debug(`left <${id}> (${type}), pending runs ${postponedCount}`);
@@ -657,9 +679,9 @@ ProcessExecution.prototype._onChildCompleted = function onChildCompleted(message
657
679
  }
658
680
 
659
681
  message.ack();
660
- this._debug(`left <${id}> (${type}), pending runs ${postponedCount}, ${postponed.map((a) => a.content.id).join(',')}`);
682
+ this._debug(`left <${id}> (${type}), pending activities ${postponedCount}`);
661
683
 
662
- if (postponedCount && postponedCount === detachedActivities.length) {
684
+ if (postponedCount && postponedCount === detachedActivities.size) {
663
685
  return this[kActivityQ].queueMessage(
664
686
  { routingKey: 'execution.discard.detached' },
665
687
  {
@@ -706,8 +728,11 @@ ProcessExecution.prototype._stopExecution = function stopExecution(message) {
706
728
 
707
729
  ProcessExecution.prototype._onDiscard = function onDiscard() {
708
730
  this._deactivate();
709
- const running = this[kElements].postponed.splice(0);
710
- this._debug(`discard process execution (discard child executions ${running.length})`);
731
+ const postponed = this[kElements].postponed;
732
+ const running = new Set(postponed);
733
+ postponed.clear();
734
+
735
+ this._debug(`discard process execution (discard child executions ${running.size})`);
711
736
 
712
737
  if (this.isSubProcess) {
713
738
  this.stop();
@@ -722,11 +747,13 @@ ProcessExecution.prototype._onDiscard = function onDiscard() {
722
747
  };
723
748
 
724
749
  ProcessExecution.prototype._onCancel = function onCancel() {
725
- const running = this[kElements].postponed.slice(0);
750
+ const postponed = this[kElements].postponed;
751
+ const running = new Set(postponed);
752
+
726
753
  const isTransaction = this.isTransaction;
727
754
 
728
755
  if (isTransaction) {
729
- this._debug(`cancel transaction execution (cancel child executions ${running.length})`);
756
+ this._debug(`cancel transaction execution (cancel child executions ${running.size})`);
730
757
  this[kStatus] = 'cancel';
731
758
  this.broker.publish(
732
759
  'event',
@@ -744,7 +771,7 @@ ProcessExecution.prototype._onCancel = function onCancel() {
744
771
  }
745
772
  }
746
773
  } else {
747
- this._debug(`cancel process execution (cancel child executions ${running.length})`);
774
+ this._debug(`cancel process execution (cancel child executions ${running.size})`);
748
775
  for (const msg of running) {
749
776
  this._getChildApi(msg).discard();
750
777
  }
@@ -839,7 +866,10 @@ ProcessExecution.prototype._terminate = function terminate(message) {
839
866
  this[kStatus] = 'terminated';
840
867
  this._debug('terminating process execution');
841
868
 
842
- const running = this[kElements].postponed.splice(0);
869
+ const postponed = this[kElements].postponed;
870
+ const running = new Set(postponed);
871
+ postponed.clear();
872
+
843
873
  for (const flow of this.getSequenceFlows()) flow.stop();
844
874
  for (const flow of this.getAssociations()) flow.stop();
845
875
 
package/src/shared.js CHANGED
@@ -12,14 +12,6 @@ export function getUniqueId(prefix) {
12
12
  return `${brokerSafeId(prefix)}_${generateId()}`;
13
13
  }
14
14
 
15
- export function filterUndefined(obj) {
16
- return Object.keys(obj).reduce((filtered, key) => {
17
- const objValue = obj[key];
18
- if (objValue !== undefined) filtered[key] = objValue;
19
- return filtered;
20
- }, {});
21
- }
22
-
23
15
  export function getOptionsAndCallback(optionsOrCallback, callback) {
24
16
  let options;
25
17
  if (typeof optionsOrCallback === 'function') {
@@ -146,12 +146,12 @@ ParallelLoopCharacteristics.prototype.execute = function execute(executeMessage)
146
146
  ParallelLoopCharacteristics.prototype._startBatch = function startBatch() {
147
147
  const chr = this.characteristics;
148
148
  const cardinality = chr.cardinality;
149
- const batch = [];
149
+ const batch = new Set();
150
150
 
151
151
  let startContent = chr.next(this.index);
152
152
  do {
153
153
  chr.debug(`start parallel iteration index ${this.index}`);
154
- batch.push(startContent);
154
+ batch.add(startContent);
155
155
  this.running++;
156
156
  this.index++;
157
157
 
@@ -29,8 +29,8 @@ ScriptTaskBehaviour.prototype.execute = function execute(executeMessage) {
29
29
  return loopCharacteristics.execute(executeMessage);
30
30
  }
31
31
 
32
- const activity = this.activity,
33
- scriptFormat = this.scriptFormat;
32
+ const activity = this.activity;
33
+ const scriptFormat = this.scriptFormat;
34
34
  const script = this.environment.getScript(scriptFormat, activity, cloneMessage(executeMessage));
35
35
  if (!script) {
36
36
  return activity.emitFatal(
@@ -3,7 +3,7 @@ import ProcessExecution from '../process/ProcessExecution.js';
3
3
  import { cloneContent } from '../messageHelper.js';
4
4
 
5
5
  const kExecutions = Symbol.for('executions');
6
- const kMessageHandlers = Symbol.for('messageHandlers');
6
+ const kOnExecutionCompleted = Symbol.for('execution completed handler');
7
7
 
8
8
  export default function SubProcess(activityDef, context) {
9
9
  const triggeredByEvent = activityDef.behaviour && activityDef.behaviour.triggeredByEvent;
@@ -38,21 +38,19 @@ export function SubProcessBehaviour(activity, context) {
38
38
  this.broker = activity.broker;
39
39
  this.executionId = undefined;
40
40
 
41
- this[kExecutions] = [];
42
- this[kMessageHandlers] = {
43
- onExecutionCompleted: this._onExecutionCompleted.bind(this),
44
- };
41
+ this[kExecutions] = new Set();
42
+ this[kOnExecutionCompleted] = this._onExecutionCompleted.bind(this);
45
43
  }
46
44
 
47
45
  Object.defineProperties(SubProcessBehaviour.prototype, {
48
46
  execution: {
49
47
  get() {
50
- return this[kExecutions][0];
48
+ return [...this[kExecutions]][0];
51
49
  },
52
50
  },
53
51
  executions: {
54
52
  get() {
55
- return this[kExecutions].slice();
53
+ return [...this[kExecutions]];
56
54
  },
57
55
  },
58
56
  });
@@ -74,22 +72,20 @@ SubProcessBehaviour.prototype.execute = function execute(executeMessage) {
74
72
  };
75
73
 
76
74
  SubProcessBehaviour.prototype.getState = function getState() {
75
+ const states = [];
76
+ for (const pe of this[kExecutions]) {
77
+ const state = pe.getState();
78
+ state.environment = pe.environment.getState();
79
+ states.push(state);
80
+ }
81
+
77
82
  if (this.loopCharacteristics) {
78
83
  return {
79
- executions: this[kExecutions].map((pe) => {
80
- const state = pe.getState();
81
- state.environment = pe.environment.getState();
82
- return state;
83
- }),
84
+ executions: states,
84
85
  };
85
86
  }
86
87
 
87
- const execution = this.execution;
88
- if (execution) {
89
- const state = execution.getState();
90
- state.environment = execution.environment.getState();
91
- return state;
92
- }
88
+ return states[0];
93
89
  };
94
90
 
95
91
  SubProcessBehaviour.prototype.recover = function recover(state) {
@@ -99,7 +95,7 @@ SubProcessBehaviour.prototype.recover = function recover(state) {
99
95
 
100
96
  const loopCharacteristics = this.loopCharacteristics;
101
97
  if (loopCharacteristics && state.executions) {
102
- executions.splice(0);
98
+ executions.clear();
103
99
  for (const se of state.executions) {
104
100
  this.recover(se);
105
101
  }
@@ -107,7 +103,7 @@ SubProcessBehaviour.prototype.recover = function recover(state) {
107
103
  }
108
104
 
109
105
  if (!loopCharacteristics) {
110
- executions.splice(0);
106
+ executions.clear();
111
107
  }
112
108
 
113
109
  const subEnvironment = this.environment.clone().recover(state.environment);
@@ -115,15 +111,16 @@ SubProcessBehaviour.prototype.recover = function recover(state) {
115
111
 
116
112
  const execution = new ProcessExecution(this.activity, subContext).recover(state);
117
113
 
118
- executions.push(execution);
114
+ executions.add(execution);
119
115
  return execution;
120
116
  };
121
117
 
122
118
  SubProcessBehaviour.prototype.getPostponed = function getPostponed() {
123
- return this[kExecutions].reduce((result, pe) => {
124
- result = result.concat(pe.getPostponed());
125
- return result;
126
- }, []);
119
+ let postponed = [];
120
+ for (const pe of this[kExecutions]) {
121
+ postponed = postponed.concat(pe.getPostponed());
122
+ }
123
+ return postponed;
127
124
  };
128
125
 
129
126
  SubProcessBehaviour.prototype._upsertExecution = function upsertExecution(executeMessage) {
@@ -140,7 +137,7 @@ SubProcessBehaviour.prototype._upsertExecution = function upsertExecution(execut
140
137
  const subContext = this.context.clone(subEnvironment, this.activity);
141
138
 
142
139
  execution = new ProcessExecution(this.activity, subContext);
143
- this[kExecutions].push(execution);
140
+ this[kExecutions].add(execution);
144
141
 
145
142
  this._addListeners(executionId);
146
143
 
@@ -148,7 +145,7 @@ SubProcessBehaviour.prototype._upsertExecution = function upsertExecution(execut
148
145
  };
149
146
 
150
147
  SubProcessBehaviour.prototype._addListeners = function addListeners(executionId) {
151
- this.broker.subscribeTmp('subprocess-execution', `execution.#.${executionId}`, this[kMessageHandlers].onExecutionCompleted, {
148
+ this.broker.subscribeTmp('subprocess-execution', `execution.#.${executionId}`, this[kOnExecutionCompleted], {
152
149
  noAck: true,
153
150
  consumerTag: `_sub-process-execution-${executionId}`,
154
151
  });
@@ -184,10 +181,8 @@ SubProcessBehaviour.prototype._onExecutionCompleted = function onExecutionComple
184
181
 
185
182
  SubProcessBehaviour.prototype._completeExecution = function completeExecution(completeRoutingKey, content) {
186
183
  if (this.loopCharacteristics) {
187
- const executions = this[kExecutions];
188
- const executionIdx = executions.findIndex((pe) => pe.executionId === content.executionId);
189
- if (executionIdx < 0) return;
190
- executions.splice(executionIdx, 1);
184
+ const execution = this._getExecutionById(content.executionId);
185
+ this[kExecutions].delete(execution);
191
186
  }
192
187
 
193
188
  this.broker.publish('execution', completeRoutingKey, cloneContent(content));
@@ -203,11 +198,15 @@ SubProcessBehaviour.prototype.getApi = function getApi(apiMessage) {
203
198
  return execution.getApi(apiMessage);
204
199
  }
205
200
 
201
+ if (!content.parent.path) return;
202
+
206
203
  for (const pp of content.parent.path) {
207
204
  if ((execution = this._getExecutionById(pp.executionId))) return execution.getApi(apiMessage);
208
205
  }
209
206
  };
210
207
 
211
208
  SubProcessBehaviour.prototype._getExecutionById = function getExecutionById(executionId) {
212
- return this[kExecutions].find((pe) => pe.executionId === executionId);
209
+ for (const pe of this[kExecutions]) {
210
+ if (pe.executionId === executionId) return pe;
211
+ }
213
212
  };
package/types/types.d.ts CHANGED
@@ -220,7 +220,7 @@ declare interface DefinitionExecution {
220
220
  getProcessByExecutionId(processExecutionId: string): Process;
221
221
  getRunningProcesses(): Process[];
222
222
  getExecutableProcesses(): Process[];
223
- getPostponed(filterFn: filterPostponed): Api<ElementBase>[];
223
+ getPostponed(filterFn?: filterPostponed): Api<ElementBase>[];
224
224
  }
225
225
 
226
226
  declare interface ActivityExecution {