bpmn-elements 17.2.2 → 18.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +3 -1
  2. package/dist/Api.js +83 -0
  3. package/dist/Context.js +228 -22
  4. package/dist/Environment.js +111 -31
  5. package/dist/EventBroker.js +57 -1
  6. package/dist/Expressions.js +3 -4
  7. package/dist/MessageFormatter.js +29 -16
  8. package/dist/Timers.js +13 -9
  9. package/dist/Tracker.js +1 -0
  10. package/dist/activity/Activity.js +458 -254
  11. package/dist/activity/ActivityExecution.js +113 -40
  12. package/dist/activity/Dummy.js +6 -1
  13. package/dist/activity/Escalation.js +36 -24
  14. package/dist/activity/ExecutionScope.js +1 -1
  15. package/dist/activity/Message.js +36 -24
  16. package/dist/activity/Signal.js +36 -24
  17. package/dist/activity/outbound-evaluator.js +1 -1
  18. package/dist/condition.js +12 -6
  19. package/dist/constants.js +21 -0
  20. package/dist/definition/Definition.js +182 -64
  21. package/dist/definition/DefinitionExecution.js +195 -82
  22. package/dist/error/BpmnError.js +12 -1
  23. package/dist/error/Errors.js +50 -9
  24. package/dist/eventDefinitions/CancelEventDefinition.js +29 -11
  25. package/dist/eventDefinitions/CompensateEventDefinition.js +51 -31
  26. package/dist/eventDefinitions/ConditionalEventDefinition.js +21 -9
  27. package/dist/eventDefinitions/ErrorEventDefinition.js +46 -30
  28. package/dist/eventDefinitions/EscalationEventDefinition.js +44 -27
  29. package/dist/eventDefinitions/EventDefinitionExecution.js +30 -23
  30. package/dist/eventDefinitions/LinkEventDefinition.js +45 -120
  31. package/dist/eventDefinitions/MessageEventDefinition.js +44 -29
  32. package/dist/eventDefinitions/SignalEventDefinition.js +46 -31
  33. package/dist/eventDefinitions/TerminateEventDefinition.js +10 -1
  34. package/dist/eventDefinitions/TimerEventDefinition.js +57 -37
  35. package/dist/eventDefinitions/index.js +20 -21
  36. package/dist/events/BoundaryEvent.js +52 -40
  37. package/dist/events/EndEvent.js +22 -8
  38. package/dist/events/IntermediateCatchEvent.js +26 -8
  39. package/dist/events/IntermediateThrowEvent.js +24 -9
  40. package/dist/events/StartEvent.js +30 -14
  41. package/dist/events/index.js +10 -11
  42. package/dist/flows/Association.js +50 -7
  43. package/dist/flows/MessageFlow.js +49 -10
  44. package/dist/flows/SequenceFlow.js +93 -22
  45. package/dist/flows/index.js +6 -7
  46. package/dist/gateways/EventBasedGateway.js +29 -15
  47. package/dist/gateways/ExclusiveGateway.js +20 -5
  48. package/dist/gateways/InclusiveGateway.js +21 -5
  49. package/dist/gateways/ParallelGateway.js +253 -15
  50. package/dist/gateways/index.js +8 -9
  51. package/dist/getPropertyValue.js +2 -2
  52. package/dist/index.js +42 -43
  53. package/dist/io/BpmnIO.js +15 -1
  54. package/dist/io/EnvironmentDataObject.js +29 -1
  55. package/dist/io/EnvironmentDataStore.js +24 -1
  56. package/dist/io/EnvironmentDataStoreReference.js +24 -1
  57. package/dist/io/InputOutputSpecification.js +21 -11
  58. package/dist/io/Properties.js +28 -17
  59. package/dist/messageHelper.js +41 -4
  60. package/dist/process/Lane.js +15 -4
  61. package/dist/process/Process.js +174 -76
  62. package/dist/process/ProcessExecution.js +362 -177
  63. package/dist/shared.js +2 -0
  64. package/dist/tasks/CallActivity.js +19 -4
  65. package/dist/tasks/LoopCharacteristics.js +94 -9
  66. package/dist/tasks/ReceiveTask.js +36 -21
  67. package/dist/tasks/ScriptTask.js +22 -6
  68. package/dist/tasks/ServiceImplementation.js +7 -4
  69. package/dist/tasks/ServiceTask.js +19 -4
  70. package/dist/tasks/SignalTask.js +19 -4
  71. package/dist/tasks/StandardLoopCharacteristics.js +8 -4
  72. package/dist/tasks/SubProcess.js +44 -29
  73. package/dist/tasks/Task.js +19 -4
  74. package/dist/tasks/Transaction.js +8 -4
  75. package/dist/tasks/index.js +16 -18
  76. package/package.json +31 -13
  77. package/src/Api.js +70 -0
  78. package/src/Context.js +200 -19
  79. package/src/Environment.js +99 -30
  80. package/src/EventBroker.js +46 -1
  81. package/src/Expressions.js +2 -3
  82. package/src/MessageFormatter.js +24 -16
  83. package/src/Timers.js +12 -9
  84. package/src/Tracker.js +1 -0
  85. package/src/activity/Activity.js +388 -231
  86. package/src/activity/ActivityExecution.js +93 -42
  87. package/src/activity/Dummy.js +6 -1
  88. package/src/activity/Escalation.js +25 -18
  89. package/src/activity/ExecutionScope.js +1 -1
  90. package/src/activity/Message.js +25 -18
  91. package/src/activity/Signal.js +25 -18
  92. package/src/activity/outbound-evaluator.js +1 -1
  93. package/src/condition.js +11 -5
  94. package/src/constants.js +15 -0
  95. package/src/definition/Definition.js +157 -62
  96. package/src/definition/DefinitionExecution.js +161 -83
  97. package/src/error/BpmnError.js +11 -1
  98. package/src/error/Errors.js +44 -5
  99. package/src/eventDefinitions/CancelEventDefinition.js +27 -13
  100. package/src/eventDefinitions/CompensateEventDefinition.js +48 -32
  101. package/src/eventDefinitions/ConditionalEventDefinition.js +20 -10
  102. package/src/eventDefinitions/ErrorEventDefinition.js +44 -33
  103. package/src/eventDefinitions/EscalationEventDefinition.js +39 -26
  104. package/src/eventDefinitions/EventDefinitionExecution.js +30 -24
  105. package/src/eventDefinitions/LinkEventDefinition.js +34 -120
  106. package/src/eventDefinitions/MessageEventDefinition.js +42 -31
  107. package/src/eventDefinitions/SignalEventDefinition.js +43 -32
  108. package/src/eventDefinitions/TerminateEventDefinition.js +9 -1
  109. package/src/eventDefinitions/TimerEventDefinition.js +53 -35
  110. package/src/eventDefinitions/index.js +10 -23
  111. package/src/events/BoundaryEvent.js +50 -39
  112. package/src/events/EndEvent.js +19 -7
  113. package/src/events/IntermediateCatchEvent.js +24 -8
  114. package/src/events/IntermediateThrowEvent.js +24 -8
  115. package/src/events/StartEvent.js +25 -14
  116. package/src/events/index.js +5 -18
  117. package/src/flows/Association.js +43 -9
  118. package/src/flows/MessageFlow.js +41 -10
  119. package/src/flows/SequenceFlow.js +82 -19
  120. package/src/flows/index.js +3 -4
  121. package/src/gateways/EventBasedGateway.js +27 -15
  122. package/src/gateways/ExclusiveGateway.js +16 -3
  123. package/src/gateways/InclusiveGateway.js +16 -3
  124. package/src/gateways/ParallelGateway.js +301 -10
  125. package/src/gateways/index.js +4 -4
  126. package/src/getPropertyValue.js +2 -2
  127. package/src/index.js +19 -19
  128. package/src/io/BpmnIO.js +13 -1
  129. package/src/io/EnvironmentDataObject.js +26 -1
  130. package/src/io/EnvironmentDataStore.js +22 -1
  131. package/src/io/EnvironmentDataStoreReference.js +22 -1
  132. package/src/io/InputOutputSpecification.js +17 -8
  133. package/src/io/Properties.js +23 -13
  134. package/src/messageHelper.js +36 -4
  135. package/src/process/Lane.js +14 -4
  136. package/src/process/Process.js +154 -72
  137. package/src/process/ProcessExecution.js +326 -175
  138. package/src/shared.js +1 -0
  139. package/src/tasks/CallActivity.js +16 -2
  140. package/src/tasks/LoopCharacteristics.js +77 -11
  141. package/src/tasks/ReceiveTask.js +33 -22
  142. package/src/tasks/ScriptTask.js +17 -3
  143. package/src/tasks/ServiceImplementation.js +6 -3
  144. package/src/tasks/ServiceTask.js +16 -2
  145. package/src/tasks/SignalTask.js +16 -2
  146. package/src/tasks/StandardLoopCharacteristics.js +7 -3
  147. package/src/tasks/SubProcess.js +37 -23
  148. package/src/tasks/Task.js +16 -2
  149. package/src/tasks/Transaction.js +7 -3
  150. package/src/tasks/index.js +8 -9
  151. package/types/bundle-errors.d.ts +1 -0
  152. package/types/bundle.d.ts +97 -0
  153. package/types/index.d.ts +2614 -84
  154. package/types/interfaces.d.ts +636 -0
  155. package/types/types.d.ts +0 -765
@@ -1,40 +1,52 @@
1
- import Activity from '../activity/Activity.js';
1
+ import { Activity } from '../activity/Activity.js';
2
2
  import { cloneContent } from '../messageHelper.js';
3
-
4
- const kCompleted = Symbol.for('completed');
5
- const kTargets = Symbol.for('targets');
6
-
7
- export default function EventBasedGateway(activityDef, context) {
3
+ import { K_COMPLETED, K_TARGETS } from '../constants.js';
4
+
5
+ /**
6
+ * Event based gateway
7
+ * @param {import('moddle-context-serializer').Activity} activityDef
8
+ * @param {import('#types').ContextInstance} context
9
+ */
10
+ export function EventBasedGateway(activityDef, context) {
8
11
  return new Activity(EventBasedGatewayBehaviour, activityDef, context);
9
12
  }
10
13
 
14
+ /**
15
+ * Event based gateway behaviour
16
+ * @param {import('#types').Activity} activity
17
+ * @param {import('#types').ContextInstance} context
18
+ */
11
19
  export function EventBasedGatewayBehaviour(activity, context) {
12
20
  this.id = activity.id;
13
21
  this.type = activity.type;
14
22
  this.activity = activity;
15
23
  this.broker = activity.broker;
16
24
  this.context = context;
17
- this[kTargets] = new Set(activity.outbound.map((flow) => context.getActivityById(flow.targetId)));
25
+ this[K_TARGETS] = new Set(activity.outbound.map((flow) => context.getActivityById(flow.targetId)));
18
26
  }
19
27
 
28
+ /**
29
+ * @param {import('#types').ElementBrokerMessage} executeMessage
30
+ * @returns {void}
31
+ */
20
32
  EventBasedGatewayBehaviour.prototype.execute = function execute(executeMessage) {
21
33
  const executeContent = executeMessage.content;
22
34
  const { executionId, outbound = [], outboundTaken } = executeContent;
23
35
 
24
- const targets = this[kTargets];
25
- this[kCompleted] = false;
36
+ const targets = this[K_TARGETS];
37
+ this[K_COMPLETED] = false;
26
38
  if (!targets.size) return this._complete(executeContent);
27
39
 
28
40
  for (const flow of this.activity.outbound) {
29
41
  outbound.push({ id: flow.id, action: 'take' });
30
42
  }
31
43
 
32
- if (!this[kCompleted] && outboundTaken) return;
44
+ if (!this[K_COMPLETED] && outboundTaken) return;
33
45
 
34
46
  const targetConsumerTag = `_gateway-listener-${this.id}`;
35
47
 
36
48
  const onTargetCompleted = this._onTargetCompleted.bind(this, executeMessage);
37
- for (const target of this[kTargets]) {
49
+ for (const target of this[K_TARGETS]) {
38
50
  target.broker.subscribeOnce('event', 'activity.end', onTargetCompleted, { consumerTag: targetConsumerTag });
39
51
  }
40
52
 
@@ -43,7 +55,7 @@ EventBasedGatewayBehaviour.prototype.execute = function execute(executeMessage)
43
55
  consumerTag: '_api-stop-execution',
44
56
  });
45
57
 
46
- this[kCompleted] = false;
58
+ this[K_COMPLETED] = false;
47
59
 
48
60
  if (!executeMessage.fields.redelivered) {
49
61
  return broker.publish('execution', 'execute.outbound.take', cloneContent(executeContent, { outboundTaken: true }));
@@ -57,7 +69,7 @@ EventBasedGatewayBehaviour.prototype._onTargetCompleted = function onTargetCompl
57
69
  this.activity.logger.debug(`<${executionId} (${this.id})> <${targetExecutionId}> completed run, discarding the rest`);
58
70
 
59
71
  this._stop();
60
- for (const target of this[kTargets]) {
72
+ for (const target of this[K_TARGETS]) {
61
73
  if (target === owner) continue;
62
74
  target.discard();
63
75
  }
@@ -74,12 +86,12 @@ EventBasedGatewayBehaviour.prototype._onTargetCompleted = function onTargetCompl
74
86
  };
75
87
 
76
88
  EventBasedGatewayBehaviour.prototype._complete = function complete(completedContent) {
77
- this[kCompleted] = true;
89
+ this[K_COMPLETED] = true;
78
90
  this.broker.publish('execution', 'execute.completed', cloneContent(completedContent));
79
91
  };
80
92
 
81
93
  EventBasedGatewayBehaviour.prototype._stop = function stop() {
82
94
  const targetConsumerTag = `_gateway-listener-${this.id}`;
83
- for (const target of this[kTargets]) target.broker.cancel(targetConsumerTag);
95
+ for (const target of this[K_TARGETS]) target.broker.cancel(targetConsumerTag);
84
96
  this.broker.cancel('_api-stop-execution');
85
97
  };
@@ -1,10 +1,19 @@
1
- import Activity from '../activity/Activity.js';
1
+ import { Activity } from '../activity/Activity.js';
2
2
  import { cloneContent } from '../messageHelper.js';
3
3
 
4
- export default function ExclusiveGateway(activityDef, context) {
4
+ /**
5
+ * Exclusive gateway
6
+ * @param {import('moddle-context-serializer').Activity} activityDef
7
+ * @param {import('#types').ContextInstance} context
8
+ */
9
+ export function ExclusiveGateway(activityDef, context) {
5
10
  return new Activity(ExclusiveGatewayBehaviour, activityDef, context);
6
11
  }
7
12
 
13
+ /**
14
+ * Exclusive gateway behaviour
15
+ * @param {import('#types').Activity} activity
16
+ */
8
17
  export function ExclusiveGatewayBehaviour(activity) {
9
18
  const { id, type, broker } = activity;
10
19
  this.id = id;
@@ -12,6 +21,10 @@ export function ExclusiveGatewayBehaviour(activity) {
12
21
  this.broker = broker;
13
22
  }
14
23
 
24
+ /**
25
+ * @param {import('#types').ElementBrokerMessage} executeMessage
26
+ * @returns {void}
27
+ */
15
28
  ExclusiveGatewayBehaviour.prototype.execute = function execute({ content }) {
16
- this.broker.publish('execution', 'execute.completed', cloneContent(content, { outboundTakeOne: true }));
29
+ this.broker.publish('execution', 'execute.completed', cloneContent(content, { outboundTakeOne: true, requireOutbound: true }));
17
30
  };
@@ -1,10 +1,19 @@
1
- import Activity from '../activity/Activity.js';
1
+ import { Activity } from '../activity/Activity.js';
2
2
  import { cloneContent } from '../messageHelper.js';
3
3
 
4
- export default function InclusiveGateway(activityDef, context) {
4
+ /**
5
+ * Inclusive gateway
6
+ * @param {import('moddle-context-serializer').Activity} activityDef
7
+ * @param {import('#types').ContextInstance} context
8
+ */
9
+ export function InclusiveGateway(activityDef, context) {
5
10
  return new Activity(InclusiveGatewayBehaviour, activityDef, context);
6
11
  }
7
12
 
13
+ /**
14
+ * Inclusive gateway behaviour
15
+ * @param {import('#types').Activity} activity
16
+ */
8
17
  export function InclusiveGatewayBehaviour(activity) {
9
18
  const { id, type, broker } = activity;
10
19
  this.id = id;
@@ -12,6 +21,10 @@ export function InclusiveGatewayBehaviour(activity) {
12
21
  this.broker = broker;
13
22
  }
14
23
 
24
+ /**
25
+ * @param {import('#types').ElementBrokerMessage} executeMessage
26
+ * @returns {void}
27
+ */
15
28
  InclusiveGatewayBehaviour.prototype.execute = function execute({ content }) {
16
- this.broker.publish('execution', 'execute.completed', cloneContent(content));
29
+ this.broker.publish('execution', 'execute.completed', cloneContent(content, { requireOutbound: true }));
17
30
  };
@@ -1,17 +1,308 @@
1
- import Activity from '../activity/Activity.js';
2
- import { cloneContent } from '../messageHelper.js';
1
+ import { Activity } from '../activity/Activity.js';
2
+ import { cloneContent, cloneMessage } from '../messageHelper.js';
3
+ import { K_EXECUTE_MESSAGE, K_TARGETS } from '../constants.js';
3
4
 
4
- export default function ParallelGateway(activityDef, context) {
5
- return new Activity(ParallelGatewayBehaviour, { ...activityDef, isParallelGateway: true }, context);
5
+ const STATE_MONTITORING = 'monitoring';
6
+ const STATE_SETUP = 'setup';
7
+
8
+ const K_PEERS = Symbol.for('peers');
9
+ const K_PEERS_DISCOVERED = Symbol.for('peers discovered');
10
+
11
+ /**
12
+ * Parallel gateway
13
+ * @param {import('moddle-context-serializer').Activity} activityDef
14
+ * @param {import('#types').ContextInstance} context
15
+ */
16
+ export function ParallelGateway(activityDef, context) {
17
+ const activity = new Activity(ParallelGatewayBehaviour, { ...activityDef, isParallelGateway: true }, context);
18
+
19
+ const id = (this.id = activity.id);
20
+
21
+ activity.broker.cancel('_api-shake');
22
+ activity.broker.subscribeTmp('api', 'activity.shake.continue', onApiShake, { noAck: true, consumerTag: '_api-shake', priority: 1000 });
23
+
24
+ const peers = (activity[K_PEERS] = new Map(activity.inbound.map(({ id: flowId, sourceId }) => [flowId, new Set([sourceId])])));
25
+
26
+ const cachedPeers = context.getShakenPeers(id);
27
+ if (cachedPeers) {
28
+ for (const [flowId, sourceIds] of cachedPeers) {
29
+ let peer = peers.get(flowId);
30
+ if (!peer) peers.set(flowId, (peer = new Set()));
31
+ for (const sourceId of sourceIds) peer.add(sourceId);
32
+ }
33
+ activity[K_PEERS_DISCOVERED] = true;
34
+ }
35
+
36
+ return activity;
37
+
38
+ function onApiShake(_, message) {
39
+ const collect = new Set();
40
+
41
+ let sequenceFlow;
42
+ for (const s of message.content.sequence) {
43
+ if (s.isSequenceFlow) {
44
+ sequenceFlow = s;
45
+ } else if (s.id === id) {
46
+ const peer = peers.get(sequenceFlow.id);
47
+ for (const c of collect) {
48
+ peer.add(c);
49
+ }
50
+ collect.clear();
51
+ } else {
52
+ collect.add(s.id);
53
+ }
54
+ }
55
+
56
+ activity.logger.debug(`<${activity.id}> collected parallel gateway peers`);
57
+
58
+ activity[K_PEERS_DISCOVERED] = true;
59
+ context.setShakenPeers(
60
+ id,
61
+ [...peers].map(([flowId, sourceIds]) => [flowId, [...sourceIds]])
62
+ );
63
+
64
+ activity.shake(message);
65
+ }
6
66
  }
7
67
 
68
+ /**
69
+ * Parallel gateway behaviour
70
+ * @param {import('#types').Activity} activity
71
+ */
8
72
  export function ParallelGatewayBehaviour(activity) {
9
- const { id, type, broker } = activity;
10
- this.id = id;
11
- this.type = type;
12
- this.broker = broker;
73
+ this.id = activity.id;
74
+ this.type = activity.type;
75
+ this.activity = activity;
76
+ this.broker = activity.broker;
77
+ this.inbound = new Set();
78
+
79
+ this.isConverging = true;
80
+ this[K_EXECUTE_MESSAGE] = undefined;
81
+ }
82
+
83
+ Object.defineProperty(ParallelGatewayBehaviour.prototype, 'executionId', {
84
+ get() {
85
+ return this[K_EXECUTE_MESSAGE]?.content.executionId;
86
+ },
87
+ });
88
+
89
+ /**
90
+ * @param {import('#types').ElementBrokerMessage} executeMessage
91
+ * @returns {void}
92
+ */
93
+ ParallelGatewayBehaviour.prototype.execute = function execute(executeMessage) {
94
+ const routingKey = executeMessage.fields.routingKey;
95
+ const isRedelivered = executeMessage.fields.redelivered;
96
+ const executeContent = executeMessage.content;
97
+
98
+ if (executeContent.isRootScope) {
99
+ this[K_EXECUTE_MESSAGE] = executeMessage;
100
+
101
+ switch (routingKey) {
102
+ case 'execute.start': {
103
+ if (!isRedelivered && executeContent.state === STATE_SETUP && !this.peerMonitor.isRunning) {
104
+ return this._complete();
105
+ }
106
+ if (executeContent.state !== 'start' && !isRedelivered) {
107
+ return;
108
+ }
109
+ return this.setup(executeMessage);
110
+ }
111
+ }
112
+ }
113
+ };
114
+
115
+ ParallelGatewayBehaviour.prototype.setup = function setup(executeMessage) {
116
+ const peerIds = new Set([...this.activity[K_PEERS].values()].map((v) => [...v]).flat());
117
+ this[K_TARGETS] = new Map([...peerIds].map((pid) => [pid, this.activity.getActivityById(pid)]));
118
+
119
+ this.peerMonitor = new PeerMonitor(this.activity, this[K_TARGETS]);
120
+
121
+ const message = (this[K_EXECUTE_MESSAGE] = cloneMessage(executeMessage));
122
+ const executeContent = message.content;
123
+ const { executionId } = executeContent;
124
+
125
+ this.inbound.add(cloneContent(executeMessage.content.inbound[0]));
126
+
127
+ this.broker.subscribeOnce('api', `activity.stop.${executionId}`, () => this._stop(), {
128
+ consumerTag: '_api-stop-execution',
129
+ });
130
+
131
+ this.broker.subscribeTmp('execution', 'execute.completed', this._onExecuteMessage.bind(this), {
132
+ noAck: true,
133
+ consumerTag: '_parallel-execution-execute-tag',
134
+ });
135
+
136
+ this.broker.subscribeTmp('execution', 'execute.start', this._onPeerEnterMessage.bind(this), {
137
+ noAck: true,
138
+ consumerTag: '_parallel-execution-peer-enter-tag',
139
+ });
140
+
141
+ this.peerMonitor.execute(message);
142
+
143
+ const inboundQ = this.broker.getQueue('inbound-q');
144
+ inboundQ.consume(
145
+ (_, inboundMessage) => {
146
+ this.inbound.add(inboundMessage);
147
+
148
+ message.content.inbound.push(cloneContent(inboundMessage.content));
149
+
150
+ this.peerMonitor.execute(message);
151
+ },
152
+ { consumerTag: '_converging-inbound', exclusive: true, prefetch: 10000 }
153
+ );
154
+
155
+ if (this.isConverging) {
156
+ this.broker.publish('event', 'activity.converge', cloneContent(executeContent));
157
+ }
158
+
159
+ return this.broker.publish(
160
+ 'execution',
161
+ 'execute.start',
162
+ cloneContent(executeMessage.content, { preventComplete: true, state: STATE_SETUP })
163
+ );
164
+ };
165
+
166
+ ParallelGatewayBehaviour.prototype._onExecuteMessage = function onExecuteMessage(routingKey, message) {
167
+ this.activity.logger.debug(`<${this.executionId} (${this.id})> received completed from <${message.content.id}>`);
168
+ if (this.peerMonitor._onCompleteMessage(routingKey, message)) {
169
+ return this._complete();
170
+ }
171
+ };
172
+
173
+ ParallelGatewayBehaviour.prototype._onPeerEnterMessage = function onPeerEnterMessage(_, message) {
174
+ if (!message.properties.monitor) return;
175
+ const peer = this.peerMonitor.watching.get(message.content.id);
176
+ if (peer) this.peerMonitor.running.set(message.content.id, peer);
177
+ };
178
+
179
+ ParallelGatewayBehaviour.prototype._complete = function complete() {
180
+ this.broker.cancel('_converging-inbound', false);
181
+
182
+ this._stop();
183
+
184
+ this.activity.logger.debug(`<${this.executionId} (${this.id})> completed monitoring`);
185
+
186
+ const content = cloneContent(this[K_EXECUTE_MESSAGE].content, { isRootScope: true, state: 'completed' });
187
+ content.inbound = this.peerMonitor.inbound;
188
+
189
+ return this.broker.publish('execution', 'execute.completed', content);
190
+ };
191
+
192
+ ParallelGatewayBehaviour.prototype._stop = function stop() {
193
+ this.broker.cancel('_converging-inbound');
194
+ this.broker.cancel('_api-stop-execution');
195
+ this.broker.cancel('_parallel-execution-execute-tag');
196
+ this.broker.cancel('_parallel-execution-peer-enter-tag');
197
+ this.peerMonitor.stop();
198
+ };
199
+
200
+ function PeerMonitor(activity, targets) {
201
+ this.activity = activity;
202
+ this.id = activity.id;
203
+ this.broker = activity.broker;
204
+ this.running = 0;
205
+ this.index = 0;
206
+ this.discarded = 0;
207
+ this.running = new Map();
208
+ this.watching = new Map();
209
+ this.targets = targets;
210
+ this.touched = new Set();
211
+ this.inbound = [];
13
212
  }
14
213
 
15
- ParallelGatewayBehaviour.prototype.execute = function execute({ content }) {
16
- this.broker.publish('execution', 'execute.completed', cloneContent(content));
214
+ Object.defineProperty(PeerMonitor.prototype, 'isRunning', {
215
+ get() {
216
+ return this.running.size > 0;
217
+ },
218
+ });
219
+
220
+ PeerMonitor.prototype.execute = function execute(executeMessage) {
221
+ const message = cloneMessage(executeMessage);
222
+ const inbound = message.content.inbound.pop();
223
+ this.inbound.push(cloneContent(inbound));
224
+
225
+ this.activity.logger.debug(`<${executeMessage.content.executionId} (${this.id})> start monitoring inbound <${inbound.id}> peers`);
226
+
227
+ this.activity.broker.publish('execution', 'execute.start', {
228
+ ...cloneContent(executeMessage.content),
229
+ inbound: this.inbound.slice(),
230
+ state: STATE_MONTITORING,
231
+ preventComplete: true,
232
+ });
233
+
234
+ this.touched.add(inbound.sourceId);
235
+
236
+ for (const target of this.targets.values()) {
237
+ this.monitor(target);
238
+ }
239
+
240
+ return this.running.size;
241
+ };
242
+
243
+ PeerMonitor.prototype.monitor = function monitor(peerActivity) {
244
+ if (this.watching.has(peerActivity.id)) return;
245
+
246
+ this.activity.logger.debug(`<${this.id}> monitor <${peerActivity.id}> with status: ${peerActivity.status}`);
247
+
248
+ this.watching.set(peerActivity.id, peerActivity);
249
+
250
+ if (peerActivity.status || peerActivity.initialized) {
251
+ this.running.set(peerActivity.id, peerActivity);
252
+ }
253
+
254
+ peerActivity.broker.createShovel(
255
+ `_on-enter-${this.id}`,
256
+ {
257
+ exchange: 'event',
258
+ pattern: 'activity.enter',
259
+ },
260
+ {
261
+ broker: this.broker,
262
+ exchange: 'execution',
263
+ exchangeKey: 'execute.start',
264
+ publishProperties: {
265
+ monitor: true,
266
+ },
267
+ },
268
+ {
269
+ cloneMessage(sourceMessage) {
270
+ return cloneMessage(sourceMessage, { isRootScope: false });
271
+ },
272
+ }
273
+ );
274
+
275
+ peerActivity.broker.createShovel(
276
+ `_on-leave-${this.id}`,
277
+ {
278
+ exchange: 'event',
279
+ pattern: 'activity.leave',
280
+ },
281
+ {
282
+ broker: this.broker,
283
+ exchange: 'execution',
284
+ exchangeKey: 'execute.completed',
285
+ publishProperties: {
286
+ monitor: true,
287
+ },
288
+ },
289
+ {
290
+ cloneMessage(sourceMessage) {
291
+ return cloneMessage(sourceMessage, { isRootScope: false, preventComplete: true });
292
+ },
293
+ }
294
+ );
295
+ };
296
+
297
+ PeerMonitor.prototype._onCompleteMessage = function onCompleteMessage(_routingKey, message) {
298
+ this.running.delete(message.content.id);
299
+
300
+ return !this.running.size;
301
+ };
302
+
303
+ PeerMonitor.prototype.stop = function stop() {
304
+ for (const peerActivity of this.watching.values()) {
305
+ peerActivity.broker.closeShovel(`_on-leave-${this.id}`);
306
+ peerActivity.broker.closeShovel(`_on-enter-${this.id}`);
307
+ }
17
308
  };
@@ -1,7 +1,7 @@
1
- import EventBasedGateway, { EventBasedGatewayBehaviour } from './EventBasedGateway.js';
2
- import ExclusiveGateway, { ExclusiveGatewayBehaviour } from './ExclusiveGateway.js';
3
- import InclusiveGateway, { InclusiveGatewayBehaviour } from './InclusiveGateway.js';
4
- import ParallelGateway, { ParallelGatewayBehaviour } from './ParallelGateway.js';
1
+ import { EventBasedGateway, EventBasedGatewayBehaviour } from './EventBasedGateway.js';
2
+ import { ExclusiveGateway, ExclusiveGatewayBehaviour } from './ExclusiveGateway.js';
3
+ import { InclusiveGateway, InclusiveGatewayBehaviour } from './InclusiveGateway.js';
4
+ import { ParallelGateway, ParallelGatewayBehaviour } from './ParallelGateway.js';
5
5
 
6
6
  export {
7
7
  EventBasedGateway,
@@ -3,7 +3,7 @@ const stringConstantPattern = /^(['"])(.*)\1$/;
3
3
  const numberConstantPattern = /^\W*-?\d+(.\d+)?\W*$/;
4
4
  const negativeIndexPattern = /^-\d+$/;
5
5
 
6
- export default function getPropertyValue(inputContext, propertyPath, fnScope) {
6
+ export function getPropertyValue(inputContext, propertyPath, fnScope) {
7
7
  if (!inputContext) return;
8
8
 
9
9
  let resultValue;
@@ -86,7 +86,7 @@ function splitArguments(args, base, fnScope) {
86
86
  }
87
87
 
88
88
  if (argCompleted) {
89
- if (arg.length > 0) {
89
+ if (arg.length) {
90
90
  callArguments.push(getFunctionArgument(base, arg.trim(), fnScope));
91
91
  }
92
92
  arg = '';
package/src/index.js CHANGED
@@ -1,22 +1,22 @@
1
- import Activity from './activity/Activity.js';
2
- import BpmnError from './error/BpmnError.js';
3
- import Context from './Context.js';
4
- import DataObject from './io/EnvironmentDataObject.js';
5
- import DataStore from './io/EnvironmentDataStore.js';
6
- import DataStoreReference from './io/EnvironmentDataStoreReference.js';
7
- import Definition from './definition/Definition.js';
8
- import Dummy from './activity/Dummy.js';
9
- import Environment from './Environment.js';
10
- import Escalation from './activity/Escalation.js';
11
- import InputOutputSpecification from './io/InputOutputSpecification.js';
12
- import Lane from './process/Lane.js';
13
- import LoopCharacteristics from './tasks/LoopCharacteristics.js';
14
- import Message from './activity/Message.js';
15
- import Process from './process/Process.js';
16
- import Properties from './io/Properties.js';
17
- import ServiceImplementation from './tasks/ServiceImplementation.js';
18
- import Signal from './activity/Signal.js';
19
- import StandardLoopCharacteristics from './tasks/StandardLoopCharacteristics.js';
1
+ import { Activity } from './activity/Activity.js';
2
+ import { BpmnErrorActivity as BpmnError } from './error/BpmnError.js';
3
+ import { Context } from './Context.js';
4
+ import { EnvironmentDataObject as DataObject } from './io/EnvironmentDataObject.js';
5
+ import { EnvironmentDataStore as DataStore } from './io/EnvironmentDataStore.js';
6
+ import { EnvironmentDataStoreReference as DataStoreReference } from './io/EnvironmentDataStoreReference.js';
7
+ import { Definition } from './definition/Definition.js';
8
+ import { DummyActivity as Dummy } from './activity/Dummy.js';
9
+ import { Environment } from './Environment.js';
10
+ import { Escalation } from './activity/Escalation.js';
11
+ import { IoSpecification as InputOutputSpecification } from './io/InputOutputSpecification.js';
12
+ import { Lane } from './process/Lane.js';
13
+ import { LoopCharacteristics } from './tasks/LoopCharacteristics.js';
14
+ import { Message } from './activity/Message.js';
15
+ import { Process } from './process/Process.js';
16
+ import { Properties } from './io/Properties.js';
17
+ import { ServiceImplementation } from './tasks/ServiceImplementation.js';
18
+ import { Signal } from './activity/Signal.js';
19
+ import { StandardLoopCharacteristics } from './tasks/StandardLoopCharacteristics.js';
20
20
  import { Association, MessageFlow, SequenceFlow } from './flows/index.js';
21
21
  import { BoundaryEvent, EndEvent, IntermediateCatchEvent, IntermediateThrowEvent, StartEvent } from './events/index.js';
22
22
  import { EventBasedGateway, ExclusiveGateway, InclusiveGateway, ParallelGateway } from './gateways/index.js';
package/src/io/BpmnIO.js CHANGED
@@ -1,4 +1,10 @@
1
- export default function BpmnIO(activity, context) {
1
+ /**
2
+ * Built-in IO extension. Composes the activity's ioSpecification and properties behaviours.
3
+ * @param {import('#types').Activity} activity
4
+ * @param {import('#types').ContextInstance} context
5
+ * @satisfies {import('#types').IExtension}
6
+ */
7
+ export function BpmnIO(activity, context) {
2
8
  this.activity = activity;
3
9
  this.context = context;
4
10
  this.type = 'bpmnio';
@@ -15,6 +21,9 @@ Object.defineProperty(BpmnIO.prototype, 'hasIo', {
15
21
  },
16
22
  });
17
23
 
24
+ /**
25
+ * @param {import('#types').ElementBrokerMessage} message
26
+ */
18
27
  BpmnIO.prototype.activate = function activate(message) {
19
28
  const properties = this.properties,
20
29
  specification = this.specification;
@@ -22,6 +31,9 @@ BpmnIO.prototype.activate = function activate(message) {
22
31
  if (specification) specification.activate(message);
23
32
  };
24
33
 
34
+ /**
35
+ * @param {import('#types').ElementBrokerMessage} message
36
+ */
25
37
  BpmnIO.prototype.deactivate = function deactivate(message) {
26
38
  const properties = this.properties,
27
39
  specification = this.specification;
@@ -1,13 +1,27 @@
1
- export default function EnvironmentDataObject(dataObjectDef, { environment }) {
1
+ /**
2
+ * Builtin data object. Reads from / writes to `environment.variables._data`.
3
+ * @param {import('moddle-context-serializer').DataObject} dataObjectDef
4
+ * @param {import('#types').ContextInstance} context
5
+ * @satisfies {import('#types').IIOData}
6
+ */
7
+ export function EnvironmentDataObject(dataObjectDef, { environment }) {
2
8
  const { id, type, name, behaviour, parent } = dataObjectDef;
3
9
  this.id = id;
4
10
  this.type = type;
5
11
  this.name = name;
12
+ /** @type {Record<string, any>} */
6
13
  this.behaviour = behaviour;
14
+ /** @type {import('moddle-context-serializer').Parent | undefined} */
7
15
  this.parent = parent;
8
16
  this.environment = environment;
9
17
  }
10
18
 
19
+ /**
20
+ * @param {import('smqp').Broker} broker
21
+ * @param {string} exchange
22
+ * @param {string} routingKeyPrefix
23
+ * @param {Record<string, any>} [messageProperties]
24
+ */
11
25
  EnvironmentDataObject.prototype.read = function read(broker, exchange, routingKeyPrefix, messageProperties) {
12
26
  const environment = this.environment;
13
27
  const value = environment.variables._data?.[this.id];
@@ -15,6 +29,13 @@ EnvironmentDataObject.prototype.read = function read(broker, exchange, routingKe
15
29
  return broker.publish(exchange, `${routingKeyPrefix}response`, content, messageProperties);
16
30
  };
17
31
 
32
+ /**
33
+ * @param {import('smqp').Broker} broker
34
+ * @param {string} exchange
35
+ * @param {string} routingKeyPrefix
36
+ * @param {any} value
37
+ * @param {Record<string, any>} [messageProperties]
38
+ */
18
39
  EnvironmentDataObject.prototype.write = function write(broker, exchange, routingKeyPrefix, value, messageProperties) {
19
40
  const environment = this.environment;
20
41
  environment.variables._data = environment.variables._data || {};
@@ -23,6 +44,10 @@ EnvironmentDataObject.prototype.write = function write(broker, exchange, routing
23
44
  return broker.publish(exchange, `${routingKeyPrefix}response`, content, messageProperties);
24
45
  };
25
46
 
47
+ /**
48
+ * @private
49
+ * Create content
50
+ */
26
51
  EnvironmentDataObject.prototype._createContent = function createContent(value) {
27
52
  return {
28
53
  id: this.id,