bpmn-elements 6.0.1 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/CHANGELOG.md +322 -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 +169 -175
  6. package/dist/src/Environment.js +90 -102
  7. package/dist/src/EventBroker.js +89 -88
  8. package/dist/src/ExtensionsMapper.js +2 -2
  9. package/dist/src/MessageFormatter.js +164 -95
  10. package/dist/src/Scripts.js +6 -2
  11. package/dist/src/activity/Activity.js +1106 -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 +722 -409
  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 +433 -359
  49. package/dist/src/process/ProcessExecution.js +744 -645
  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 +195 -175
  60. package/dist/src/tasks/Task.js +17 -19
  61. package/index.js +2 -0
  62. package/package.json +13 -13
  63. package/src/Api.js +65 -59
  64. package/src/Context.js +138 -141
  65. package/src/Environment.js +88 -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 +915 -775
  70. package/src/activity/ActivityExecution.js +293 -247
  71. package/src/activity/Dummy.js +2 -2
  72. package/src/definition/Definition.js +436 -401
  73. package/src/definition/DefinitionExecution.js +603 -343
  74. package/src/error/Errors.js +11 -6
  75. package/src/eventDefinitions/CancelEventDefinition.js +164 -121
  76. package/src/eventDefinitions/CompensateEventDefinition.js +158 -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 +16 -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 +374 -333
  106. package/src/process/ProcessExecution.js +606 -554
  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
@@ -4,201 +4,187 @@ import {getUniqueId} from '../shared';
4
4
  import {EventBroker} from '../EventBroker';
5
5
  import {FlowApi} from '../Api';
6
6
 
7
- export default function SequenceFlow(flowDef, {environment}) {
8
- const {id, type = 'sequenceflow', name, parent: originalParent, targetId, sourceId, isDefault, behaviour = {}} = flowDef;
9
- const parent = cloneParent(originalParent);
10
- const logger = environment.Logger(type.toLowerCase());
11
-
12
-
13
- const flowBase = {
14
- id,
15
- type,
16
- name,
17
- parent,
18
- behaviour,
19
- sourceId,
20
- targetId,
21
- isDefault,
22
- isSequenceFlow: true,
23
- environment,
24
- logger,
25
- };
26
-
27
- environment.registerScript({...flowBase});
28
-
29
- let counters = {
7
+ const countersSymbol = Symbol.for('counters');
8
+
9
+ export default SequenceFlow;
10
+
11
+ function SequenceFlow(flowDef, {environment}) {
12
+ const {id, type = 'sequenceflow', name, parent, targetId, sourceId, isDefault, behaviour = {}} = flowDef;
13
+
14
+ this.id = id;
15
+ this.type = type;
16
+ this.name = name;
17
+ this.parent = cloneParent(parent);
18
+ this.behaviour = behaviour;
19
+ this.sourceId = sourceId;
20
+ this.targetId = targetId;
21
+ this.isDefault = isDefault;
22
+ this.isSequenceFlow = true;
23
+ this.environment = environment;
24
+ const logger = this.logger = environment.Logger(type.toLowerCase());
25
+
26
+ this[countersSymbol] = {
30
27
  looped: 0,
31
28
  take: 0,
32
29
  discard: 0,
33
30
  };
34
31
 
35
- const flowApi = {
36
- ...flowBase,
37
- get counters() {
38
- return {...counters};
39
- },
40
- discard,
41
- getApi,
42
- getCondition,
43
- getState,
44
- recover,
45
- shake,
46
- stop,
47
- take,
48
- };
49
-
50
- const {broker, on, once, waitFor, emitFatal} = EventBroker(flowApi, {prefix: 'flow', durable: true, autoDelete: false});
32
+ environment.registerScript(this);
33
+ const {broker, on, once, waitFor, emitFatal} = new EventBroker(this, {prefix: 'flow', durable: true, autoDelete: false});
34
+ this.broker = broker;
35
+ this.on = on;
36
+ this.once = once;
37
+ this.waitFor = waitFor;
38
+ this.emitFatal = emitFatal;
51
39
 
52
- flowApi.on = on;
53
- flowApi.once = once;
54
- flowApi.waitFor = waitFor;
40
+ logger.debug(`<${id}> init, <${sourceId}> -> <${targetId}>`);
41
+ }
55
42
 
56
- Object.defineProperty(flowApi, 'broker', {
57
- enumerable: true,
58
- get: () => broker,
59
- });
43
+ const proto = SequenceFlow.prototype;
60
44
 
61
- logger.debug(`<${id}> init, <${sourceId}> -> <${targetId}>`);
45
+ Object.defineProperty(proto, 'counters', {
46
+ enumerable: true,
47
+ get() {
48
+ return {...this[countersSymbol]};
49
+ },
50
+ });
62
51
 
63
- return flowApi;
52
+ proto.take = function take(content = {}) {
53
+ this.looped = undefined;
64
54
 
65
- function take(content = {}) {
66
- flowApi.looped = undefined;
55
+ const {sequenceId} = content;
67
56
 
68
- const {sequenceId} = content;
57
+ this.logger.debug(`<${sequenceId} (${this.id})> take, target <${this.targetId}>`);
58
+ ++this[countersSymbol].take;
69
59
 
70
- logger.debug(`<${sequenceId} (${id})> take, target <${targetId}>`);
71
- ++counters.take;
60
+ this._publishEvent('take', content);
72
61
 
73
- publishEvent('take', content);
62
+ return true;
63
+ };
74
64
 
75
- return true;
65
+ proto.discard = function discard(content = {}) {
66
+ const {sequenceId = getUniqueId(this.id)} = content;
67
+ const discardSequence = content.discardSequence = (content.discardSequence || []).slice();
68
+ if (discardSequence.indexOf(this.targetId) > -1) {
69
+ ++this[countersSymbol].looped;
70
+ this.logger.debug(`<${this.id}> discard loop detected <${this.sourceId}> -> <${this.targetId}>. Stop.`);
71
+ return this._publishEvent('looped', content);
76
72
  }
77
73
 
78
- function discard(content = {}) {
79
- const {sequenceId = getUniqueId(id)} = content;
80
- const discardSequence = content.discardSequence = (content.discardSequence || []).slice();
81
- if (discardSequence.indexOf(targetId) > -1) {
82
- ++counters.looped;
83
- logger.debug(`<${id}> discard loop detected <${sourceId}> -> <${targetId}>. Stop.`);
84
- return publishEvent('looped', content);
85
- }
74
+ discardSequence.push(this.sourceId);
86
75
 
87
- discardSequence.push(sourceId);
76
+ this.logger.debug(`<${sequenceId} (${this.id})> discard, target <${this.targetId}>`);
77
+ ++this[countersSymbol].discard;
78
+ this._publishEvent('discard', content);
79
+ };
88
80
 
89
- logger.debug(`<${sequenceId} (${id})> discard, target <${targetId}>`);
90
- ++counters.discard;
91
- publishEvent('discard', content);
92
- }
81
+ proto.getState = function getState() {
82
+ return this.createMessage({
83
+ counters: this.counters,
84
+ broker: this.broker.getState(true),
85
+ });
86
+ };
93
87
 
94
- function publishEvent(action, content) {
95
- const eventContent = createMessage({
96
- action,
97
- ...content,
98
- });
88
+ proto.recover = function recover(state) {
89
+ Object.assign(this[countersSymbol], state.counters);
90
+ this.broker.recover(state.broker);
91
+ };
99
92
 
100
- broker.publish('event', `flow.${action}`, eventContent, {type: action});
101
- }
93
+ proto.getApi = function getApi(message) {
94
+ return FlowApi(this.broker, message || {content: this.createMessage()});
95
+ };
102
96
 
103
- function createMessage(override) {
104
- return {
105
- ...override,
106
- id,
107
- type,
108
- name,
109
- sourceId,
110
- targetId,
111
- isSequenceFlow: true,
112
- isDefault,
113
- parent: cloneParent(parent),
114
- };
115
- }
97
+ proto.stop = function stop() {
98
+ this.broker.stop();
99
+ };
116
100
 
117
- function getState() {
118
- return {
119
- id,
120
- type,
121
- name,
122
- sourceId,
123
- targetId,
124
- isDefault,
125
- counters: {...counters},
126
- broker: broker.getState(true),
127
- };
128
- }
129
-
130
- function recover(state) {
131
- counters = {...counters, ...state.counters};
132
- broker.recover(state.broker);
133
- }
101
+ proto.shake = function shake(message) {
102
+ const content = cloneContent(message.content);
103
+ content.sequence = content.sequence || [];
104
+ content.sequence.push({id: this.id, type: this.type, isSequenceFlow: true, targetId: this.targetId});
134
105
 
135
- function getApi(message) {
136
- return FlowApi(broker, message || {content: createMessage()});
137
- }
106
+ if (content.id === this.targetId) return this.broker.publish('event', 'flow.shake.loop', content, {persistent: false, type: 'shake'});
138
107
 
139
- function stop() {
140
- broker.stop();
108
+ for (const s of message.content.sequence) {
109
+ if (s.id === this.id) return this.broker.publish('event', 'flow.shake.loop', content, {persistent: false, type: 'shake'});
141
110
  }
142
111
 
143
- function shake(message) {
144
- const content = cloneContent(message.content);
145
- content.sequence = content.sequence || [];
146
- content.sequence.push({id, type, isSequenceFlow: true, targetId});
112
+ this.broker.publish('event', 'flow.shake', content, {persistent: false, type: 'shake'});
113
+ };
147
114
 
148
- if (content.id === targetId) return broker.publish('event', 'flow.shake.loop', content, {persistent: false, type: 'shake'});
115
+ proto.getCondition = function getCondition() {
116
+ const conditionExpression = this.behaviour.conditionExpression;
117
+ if (!conditionExpression) return null;
149
118
 
150
- for (const s of message.content.sequence) {
151
- if (s.id === id) return broker.publish('event', 'flow.shake.loop', content, {persistent: false, type: 'shake'});
152
- }
119
+ const {language} = conditionExpression;
120
+ const script = this.environment.getScript(language, this);
121
+ if (script) {
122
+ return new ScriptCondition(this, script, language);
123
+ }
153
124
 
154
- broker.publish('event', 'flow.shake', content, {persistent: false, type: 'shake'});
125
+ if (!conditionExpression.body) {
126
+ const msg = language ? `Condition expression script ${language} is unsupported or was not registered` : 'Condition expression without body is unsupported';
127
+ return this.emitFatal(new Error(msg), this.createMessage());
155
128
  }
156
129
 
157
- function getCondition() {
158
- const conditionExpression = behaviour.conditionExpression;
159
- if (!conditionExpression) return null;
130
+ return new ExpressionCondition(this, conditionExpression.body);
131
+ };
132
+
133
+ proto.createMessage = function createMessage(override) {
134
+ return {
135
+ ...override,
136
+ id: this.id,
137
+ type: this.type,
138
+ name: this.name,
139
+ sourceId: this.sourceId,
140
+ targetId: this.targetId,
141
+ isSequenceFlow: true,
142
+ isDefault: this.isDefault,
143
+ parent: cloneParent(this.parent),
144
+ };
145
+ };
160
146
 
161
- const {language} = conditionExpression;
162
- const script = environment.getScript(language, flowApi);
163
- if (script) {
164
- return ScriptCondition(script, language);
165
- }
147
+ proto._publishEvent = function publishEvent(action, content) {
148
+ const eventContent = this.createMessage({
149
+ action,
150
+ ...content,
151
+ });
166
152
 
167
- if (!conditionExpression.body) {
168
- const msg = language ? `Condition expression script ${language} is unsupported or was not registered` : 'Condition expression without body is unsupported';
169
- return emitFatal(new Error(msg), createMessage());
170
- }
153
+ this.broker.publish('event', `flow.${action}`, eventContent, {type: action});
154
+ };
171
155
 
172
- return ExpressionCondition(conditionExpression.body);
173
- }
156
+ function ScriptCondition(owner, script, language) {
157
+ this.type = 'script';
158
+ this.language = language;
159
+ this._owner = owner;
160
+ this._script = script;
161
+ }
174
162
 
175
- function ScriptCondition(script, language) {
176
- return {
177
- language,
178
- execute(message, callback) {
179
- try {
180
- return script.execute(ExecutionScope(flowApi, message), callback);
181
- } catch (err) {
182
- if (!callback) throw err;
183
- logger.error(`<${id}>`, err);
184
- callback(err);
185
- }
186
- },
187
- };
163
+ ScriptCondition.prototype.execute = function execute(message, callback) {
164
+ const owner = this._owner;
165
+ try {
166
+ return this._script.execute(ExecutionScope(owner, message), callback);
167
+ } catch (err) {
168
+ if (!callback) throw err;
169
+ owner.logger.error(`<${owner.id}>`, err);
170
+ callback(err);
188
171
  }
172
+ };
189
173
 
190
- function ExpressionCondition(expression) {
191
- return {
192
- execute: (message, callback) => {
193
- try {
194
- const result = environment.resolveExpression(expression, createMessage(message));
195
- if (callback) return callback(null, result);
196
- return result;
197
- } catch (err) {
198
- if (callback) return callback(err);
199
- throw err;
200
- }
201
- },
202
- };
203
- }
174
+ function ExpressionCondition(owner, expression) {
175
+ this.type = 'expression';
176
+ this.expression = expression;
177
+ this._owner = owner;
204
178
  }
179
+
180
+ ExpressionCondition.prototype.execute = function execute(message, callback) {
181
+ const owner = this._owner;
182
+ try {
183
+ const result = owner.environment.resolveExpression(this.expression, owner.createMessage(message));
184
+ if (callback) return callback(null, result);
185
+ return result;
186
+ } catch (err) {
187
+ if (callback) return callback(err);
188
+ throw err;
189
+ }
190
+ };
@@ -1,77 +1,84 @@
1
1
  import Activity from '../activity/Activity';
2
2
  import {cloneContent} from '../messageHelper';
3
3
 
4
+ const completedSymbol = Symbol.for('completed');
5
+ const targetsSymbol = Symbol.for('targets');
6
+
4
7
  export default function EventBasedGateway(activityDef, context) {
5
- return Activity(EventBasedGatewayBehaviour, {...activityDef}, context);
8
+ return new Activity(EventBasedGatewayBehaviour, activityDef, context);
6
9
  }
7
10
 
8
11
  export function EventBasedGatewayBehaviour(activity, context) {
9
- const {id, type, broker, logger, outbound: outboundSequenceFlows = []} = activity;
10
- let executing = false;
11
-
12
- const source = {
13
- id,
14
- type,
15
- execute,
16
- };
17
-
18
- return source;
19
-
20
- function execute(executeMessage) {
21
- const isRedelivered = executeMessage.fields.redelivered;
22
- const content = executeMessage.content;
23
- const {executionId, outbound = [], outboundTaken} = content;
24
-
25
- const targets = [];
26
- for (let i = 0; i < outboundSequenceFlows.length; i++) {
27
- const flow = outboundSequenceFlows[i];
28
- targets.push(context.getActivityById(flow.targetId));
29
- outbound.push({id: flow.id, action: 'take'});
30
- }
31
-
32
- if (!targets.length) return complete(content);
33
-
34
- if (executing && outboundTaken) return;
35
-
36
- const targetConsumerTag = `_gateway-listener-${id}`;
37
-
38
- targets.forEach((target) => {
39
- target.broker.subscribeOnce('event', 'activity.end', onTargetCompleted, {consumerTag: targetConsumerTag});
40
- });
41
-
42
- broker.subscribeOnce('api', `activity.stop.${executionId}`, stop, {noAck: true, consumerTag: `_api-stop-${executionId}`});
43
-
44
- executing = true;
45
- if (!isRedelivered) return broker.publish('execution', 'execute.outbound.take', cloneContent(content, {outboundTaken: true}));
46
-
47
- function onTargetCompleted(_, message, owner) {
48
- const {id: targetId, exexutionId: targetExecutionId} = message.content;
49
- logger.debug(`<${executionId} (${id})> <${targetExecutionId}> completed run, discarding the rest`);
50
- targets.forEach((target) => {
51
- if (target === owner) return;
52
- target.broker.cancel(targetConsumerTag);
53
- target.discard();
54
- });
55
-
56
- const completedContent = cloneContent(executeMessage.content, {taken: {
57
- id: targetId,
58
- executionId: targetExecutionId,
59
- }, ignoreOutbound: true});
60
-
61
- complete(completedContent);
62
- }
63
-
64
- function complete(completedContent) {
65
- broker.publish('execution', 'execute.completed', completedContent);
66
- }
67
-
68
- function stop() {
69
- executing = false;
70
- targets.forEach((target) => {
71
- target.broker.cancel(targetConsumerTag);
72
- });
73
- broker.cancel(`_api-stop-${executionId}`);
74
- }
75
- }
12
+ this.id = activity.id;
13
+ this.type = activity.type;
14
+ this.activity = activity;
15
+ this.broker = activity.broker;
16
+ this.context = context;
17
+ this[targetsSymbol] = activity.outbound.map((flow) => context.getActivityById(flow.targetId));
76
18
  }
77
19
 
20
+ EventBasedGatewayBehaviour.prototype.execute = function execute(executeMessage) {
21
+ const executeContent = executeMessage.content;
22
+ const {executionId, outbound = [], outboundTaken} = executeContent;
23
+
24
+ const targets = this[targetsSymbol];
25
+ this[completedSymbol] = false;
26
+ if (!targets.length) return this._complete(executeContent);
27
+
28
+ for (const flow of this.activity.outbound) {
29
+ outbound.push({id: flow.id, action: 'take'});
30
+ }
31
+
32
+ if (!this[completedSymbol] && outboundTaken) return;
33
+
34
+ const targetConsumerTag = `_gateway-listener-${this.id}`;
35
+
36
+ const onTargetCompleted = this._onTargetCompleted.bind(this, executeMessage);
37
+ for (const target of this[targetsSymbol]) {
38
+ target.broker.subscribeOnce('event', 'activity.end', onTargetCompleted, {consumerTag: targetConsumerTag});
39
+ }
40
+
41
+ const broker = this.activity.broker;
42
+ broker.subscribeOnce('api', `activity.stop.${executionId}`, () => this._stop(), {
43
+ noAck: true,
44
+ consumerTag: '_api-stop-execution',
45
+ });
46
+
47
+ this[completedSymbol] = false;
48
+ if (!executeMessage.fields.redelivered) return broker.publish('execution', 'execute.outbound.take', cloneContent(executeContent, {outboundTaken: true}));
49
+ };
50
+
51
+ EventBasedGatewayBehaviour.prototype._onTargetCompleted = function onTargetCompleted(executeMessage, _, message, owner) {
52
+ const {id: targetId, exexutionId: targetExecutionId} = message.content;
53
+ const executeContent = executeMessage.content;
54
+ const executionId = executeContent.executionId;
55
+ this.activity.logger.debug(`<${executionId} (${this.id})> <${targetExecutionId}> completed run, discarding the rest`);
56
+
57
+ this._stop();
58
+ for (const target of this[targetsSymbol]) {
59
+ if (target === owner) continue;
60
+ target.discard();
61
+ }
62
+
63
+ const completedContent = cloneContent(executeContent, {
64
+ taken: {
65
+ id: targetId,
66
+ executionId: targetExecutionId,
67
+ },
68
+ ignoreOutbound: true,
69
+ });
70
+
71
+ this._complete(completedContent);
72
+ };
73
+
74
+ EventBasedGatewayBehaviour.prototype._complete = function complete(completedContent) {
75
+ this[completedSymbol] = true;
76
+ this.broker.publish('execution', 'execute.completed', cloneContent(completedContent));
77
+ };
78
+
79
+ EventBasedGatewayBehaviour.prototype._stop = function stop() {
80
+ const targetConsumerTag = `_gateway-listener-${this.id}`;
81
+ for (const target of this[targetsSymbol]) target.broker.cancel(targetConsumerTag);
82
+ this.broker.cancel('_api-stop-execution');
83
+ };
84
+
@@ -2,21 +2,16 @@ import Activity from '../activity/Activity';
2
2
  import {cloneContent} from '../messageHelper';
3
3
 
4
4
  export default function ExclusiveGateway(activityDef, context) {
5
- return Activity(ExclusiveGatewayBehaviour, activityDef, context);
5
+ return new Activity(ExclusiveGatewayBehaviour, activityDef, context);
6
6
  }
7
7
 
8
8
  export function ExclusiveGatewayBehaviour(activity) {
9
9
  const {id, type, broker} = activity;
10
-
11
- const source = {
12
- id,
13
- type,
14
- execute,
15
- };
16
-
17
- return source;
18
-
19
- function execute({content}) {
20
- broker.publish('execution', 'execute.completed', cloneContent(content, {outboundTakeOne: true}));
21
- }
10
+ this.id = id;
11
+ this.type = type;
12
+ this.broker = broker;
22
13
  }
14
+
15
+ ExclusiveGatewayBehaviour.prototype.execute = function execute({content}) {
16
+ this.broker.publish('execution', 'execute.completed', cloneContent(content, {outboundTakeOne: true}));
17
+ };
@@ -2,21 +2,16 @@ import Activity from '../activity/Activity';
2
2
  import {cloneContent} from '../messageHelper';
3
3
 
4
4
  export default function InclusiveGateway(activityDef, context) {
5
- return Activity(InclusiveGatewayBehaviour, activityDef, context);
5
+ return new Activity(InclusiveGatewayBehaviour, activityDef, context);
6
6
  }
7
7
 
8
8
  export function InclusiveGatewayBehaviour(activity) {
9
9
  const {id, type, broker} = activity;
10
-
11
- const source = {
12
- id,
13
- type,
14
- execute,
15
- };
16
-
17
- return source;
18
-
19
- function execute({content}) {
20
- broker.publish('execution', 'execute.completed', cloneContent(content));
21
- }
10
+ this.id = id;
11
+ this.type = type;
12
+ this.broker = broker;
22
13
  }
14
+
15
+ InclusiveGatewayBehaviour.prototype.execute = function execute({content}) {
16
+ this.broker.publish('execution', 'execute.completed', cloneContent(content));
17
+ };
@@ -2,21 +2,16 @@ import Activity from '../activity/Activity';
2
2
  import {cloneContent} from '../messageHelper';
3
3
 
4
4
  export default function ParallelGateway(activityDef, context) {
5
- return Activity(ParallelGatewayBehaviour, {...activityDef, isParallelGateway: true}, context);
5
+ return new Activity(ParallelGatewayBehaviour, {...activityDef, isParallelGateway: true}, context);
6
6
  }
7
7
 
8
8
  export function ParallelGatewayBehaviour(activity) {
9
9
  const {id, type, broker} = activity;
10
-
11
- const source = {
12
- id,
13
- type,
14
- execute,
15
- };
16
-
17
- return source;
18
-
19
- function execute({content}) {
20
- broker.publish('execution', 'execute.completed', cloneContent(content));
21
- }
10
+ this.id = id;
11
+ this.type = type;
12
+ this.broker = broker;
22
13
  }
14
+
15
+ ParallelGatewayBehaviour.prototype.execute = function execute({content}) {
16
+ this.broker.publish('execution', 'execute.completed', cloneContent(content));
17
+ };
@@ -9,53 +9,54 @@ function getPropertyValue(inputContext, propertyPath, fnScope) {
9
9
  if (!inputContext) return;
10
10
 
11
11
  let resultValue;
12
- let next = iterateProps(inputContext, inputContext, propertyPath.trim());
12
+ let next = iterateProps(inputContext, inputContext, propertyPath.trim(), fnScope);
13
13
  while (next) {
14
14
  resultValue = next.getResult();
15
15
  next = next();
16
16
  }
17
17
  return resultValue;
18
+ }
18
19
 
19
- function iterateProps(base, iterateContext, iteratePropertyPath) {
20
- let result;
21
- const rest = iteratePropertyPath.replace(propertyPattern, (match, fnName, args, p, prop) => {
22
- if (fnName) {
23
- result = executeFn(getNamedValue(iterateContext, fnName), args, base);
24
- } else {
25
- result = getNamedValue(iterateContext, prop);
26
- }
27
- return '';
28
- });
20
+ function iterateProps(base, iterateContext, iteratePropertyPath, fnScope) {
21
+ let result;
22
+ const rest = iteratePropertyPath.replace(propertyPattern, (match, fnName, args, p, prop) => {
23
+ if (fnName) {
24
+ result = executeFn(getNamedValue(iterateContext, fnName), args, base, fnScope);
25
+ } else {
26
+ result = getNamedValue(iterateContext, prop);
27
+ }
28
+ return '';
29
+ });
29
30
 
30
- if (rest === iteratePropertyPath) return;
31
- if (result === undefined || result === null) return;
31
+ if (rest === iteratePropertyPath) return;
32
+ if (result === undefined || result === null) return;
32
33
 
33
- const iterateNext = () => iterateProps(base, result, rest);
34
- iterateNext.getResult = () => {
35
- if (rest !== '') return;
36
- return result;
37
- };
34
+ const iterateNext = () => iterateProps(base, result, rest, fnScope);
35
+ iterateNext.getResult = () => {
36
+ if (rest !== '') return;
37
+ return result;
38
+ };
38
39
 
39
- return iterateNext;
40
- }
40
+ return iterateNext;
41
+ }
41
42
 
42
- function executeFn(fn, args, base) {
43
- if (!fn) return;
43
+ function executeFn(fn, args, base, fnScope) {
44
+ if (!fn) return;
44
45
 
45
- let callArguments = [];
46
- if (args) {
47
- callArguments = splitArguments(args, base, fnScope);
48
- } else {
49
- callArguments.push(base);
50
- }
46
+ let callArguments = [];
47
+ if (args) {
48
+ callArguments = splitArguments(args, base, fnScope);
49
+ } else {
50
+ callArguments.push(base);
51
+ }
51
52
 
52
- if (!fnScope) return fn.apply(null, callArguments);
53
+ if (!fnScope) return fn.apply(null, callArguments);
53
54
 
54
- return (function ScopedIIFE() { // eslint-disable-line no-extra-parens
55
- return fn.apply(this, callArguments);
56
- }).call(fnScope);
57
- }
55
+ return (function ScopedIIFE() { // eslint-disable-line no-extra-parens
56
+ return fn.apply(this, callArguments);
57
+ }).call(fnScope);
58
58
  }
59
+
59
60
  function splitArguments(args, base, fnScope) {
60
61
  let insideString = false;
61
62
  let delimiter = '';