bpmn-elements 9.1.2 → 9.2.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.
- package/CHANGELOG.md +9 -0
- package/dist/activity/Activity.js +4 -17
- package/dist/flows/SequenceFlow.js +11 -1
- package/package.json +2 -2
- package/src/activity/Activity.js +3 -11
- package/src/flows/SequenceFlow.js +14 -1
- package/src/tasks/ReceiveTask.js +215 -215
- package/types/index.d.ts +49 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
# 9.2.0
|
|
5
|
+
|
|
6
|
+
- move outbound sequence flow evaluation logic from activity to sequence flow, where it belongs
|
|
7
|
+
- spread sequence flow evaluation result, if object, to sequence flow take message
|
|
8
|
+
|
|
9
|
+
# 9.1.3
|
|
10
|
+
|
|
11
|
+
- type declare execution scope
|
|
12
|
+
|
|
4
13
|
# 9.1.2
|
|
5
14
|
|
|
6
15
|
- allow type IScripts.register to return undefined
|
|
@@ -837,10 +837,12 @@ Activity.prototype._doRunOutbound = function doRunOutbound(outboundList, content
|
|
|
837
837
|
for (const outboundFlow of outboundList) {
|
|
838
838
|
const {
|
|
839
839
|
id: flowId,
|
|
840
|
-
action
|
|
840
|
+
action,
|
|
841
|
+
result
|
|
841
842
|
} = outboundFlow;
|
|
842
843
|
this.broker.publish('run', 'run.outbound.' + action, (0, _messageHelper.cloneContent)(content, {
|
|
843
844
|
flow: {
|
|
845
|
+
...(result && typeof result === 'object' && result),
|
|
844
846
|
...outboundFlow,
|
|
845
847
|
sequenceId: (0, _shared.getUniqueId)(`${flowId}_${action}`),
|
|
846
848
|
...(discardSequence && {
|
|
@@ -1027,26 +1029,11 @@ OutboundEvaluator.prototype.onEvaluated = function onEvaluated(routingKey, messa
|
|
|
1027
1029
|
};
|
|
1028
1030
|
OutboundEvaluator.prototype.evaluateFlow = function evaluateFlow(flow) {
|
|
1029
1031
|
const broker = this.broker;
|
|
1030
|
-
if (flow.isDefault) {
|
|
1031
|
-
return broker.publish('execution', 'evaluate.flow.take', formatFlowAction(flow, {
|
|
1032
|
-
action: 'take'
|
|
1033
|
-
}), {
|
|
1034
|
-
persistent: false
|
|
1035
|
-
});
|
|
1036
|
-
}
|
|
1037
|
-
const flowCondition = flow.getCondition();
|
|
1038
|
-
if (!flowCondition) {
|
|
1039
|
-
return broker.publish('execution', 'evaluate.flow.take', formatFlowAction(flow, {
|
|
1040
|
-
action: 'take'
|
|
1041
|
-
}), {
|
|
1042
|
-
persistent: false
|
|
1043
|
-
});
|
|
1044
|
-
}
|
|
1045
1032
|
const {
|
|
1046
1033
|
fromMessage,
|
|
1047
1034
|
evaluationId
|
|
1048
1035
|
} = this.evaluateArgs;
|
|
1049
|
-
|
|
1036
|
+
flow.evaluate((0, _messageHelper.cloneMessage)(fromMessage), (err, result) => {
|
|
1050
1037
|
if (err) return this.completed(err);
|
|
1051
1038
|
const action = result ? 'take' : 'discard';
|
|
1052
1039
|
return broker.publish('execution', 'evaluate.flow.' + action, formatFlowAction(flow, {
|
|
@@ -124,7 +124,7 @@ SequenceFlow.prototype.shake = function shake(message) {
|
|
|
124
124
|
persistent: false,
|
|
125
125
|
type: 'shake'
|
|
126
126
|
});
|
|
127
|
-
for (const s of message.content.sequence) {
|
|
127
|
+
for (const s of message.content.sequence || []) {
|
|
128
128
|
if (s.id === this.id) return this.broker.publish('event', 'flow.shake.loop', content, {
|
|
129
129
|
persistent: false,
|
|
130
130
|
type: 'shake'
|
|
@@ -164,6 +164,16 @@ SequenceFlow.prototype.createMessage = function createMessage(override) {
|
|
|
164
164
|
parent: (0, _messageHelper.cloneParent)(this.parent)
|
|
165
165
|
};
|
|
166
166
|
};
|
|
167
|
+
SequenceFlow.prototype.evaluate = function evaluate(fromMessage, callback) {
|
|
168
|
+
if (this.isDefault) {
|
|
169
|
+
return callback(null, true);
|
|
170
|
+
}
|
|
171
|
+
const flowCondition = this.getCondition();
|
|
172
|
+
if (!flowCondition) {
|
|
173
|
+
return callback(null, true);
|
|
174
|
+
}
|
|
175
|
+
flowCondition.execute(fromMessage, callback);
|
|
176
|
+
};
|
|
167
177
|
SequenceFlow.prototype._publishEvent = function publishEvent(action, content) {
|
|
168
178
|
const eventContent = this.createMessage({
|
|
169
179
|
action,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bpmn-elements",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.2.0",
|
|
4
4
|
"description": "Executable workflow elements based on BPMN 2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"chai": "^4.3.7",
|
|
56
56
|
"chronokinesis": "^5.0.2",
|
|
57
57
|
"debug": "^4.3.4",
|
|
58
|
-
"eslint": "^8.
|
|
58
|
+
"eslint": "^8.39.0",
|
|
59
59
|
"eslint-plugin-import": "^2.27.5",
|
|
60
60
|
"got": "^12.6.0",
|
|
61
61
|
"mocha": "^10.1.0",
|
package/src/activity/Activity.js
CHANGED
|
@@ -807,9 +807,10 @@ Activity.prototype._doOutbound = function doOutbound(fromMessage, isDiscarded, c
|
|
|
807
807
|
|
|
808
808
|
Activity.prototype._doRunOutbound = function doRunOutbound(outboundList, content, discardSequence) {
|
|
809
809
|
for (const outboundFlow of outboundList) {
|
|
810
|
-
const {id: flowId, action} = outboundFlow;
|
|
810
|
+
const {id: flowId, action, result} = outboundFlow;
|
|
811
811
|
this.broker.publish('run', 'run.outbound.' + action, cloneContent(content, {
|
|
812
812
|
flow: {
|
|
813
|
+
...(result && typeof result === 'object' && result),
|
|
813
814
|
...outboundFlow,
|
|
814
815
|
sequenceId: getUniqueId(`${flowId}_${action}`),
|
|
815
816
|
...(discardSequence && {discardSequence: discardSequence.slice()}),
|
|
@@ -1000,17 +1001,8 @@ OutboundEvaluator.prototype.onEvaluated = function onEvaluated(routingKey, messa
|
|
|
1000
1001
|
|
|
1001
1002
|
OutboundEvaluator.prototype.evaluateFlow = function evaluateFlow(flow) {
|
|
1002
1003
|
const broker = this.broker;
|
|
1003
|
-
if (flow.isDefault) {
|
|
1004
|
-
return broker.publish('execution', 'evaluate.flow.take', formatFlowAction(flow, {action: 'take'}), {persistent: false});
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
const flowCondition = flow.getCondition();
|
|
1008
|
-
if (!flowCondition) {
|
|
1009
|
-
return broker.publish('execution', 'evaluate.flow.take', formatFlowAction(flow, {action: 'take'}), {persistent: false});
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
1004
|
const {fromMessage, evaluationId} = this.evaluateArgs;
|
|
1013
|
-
|
|
1005
|
+
flow.evaluate(cloneMessage(fromMessage), (err, result) => {
|
|
1014
1006
|
if (err) return this.completed(err);
|
|
1015
1007
|
const action = result ? 'take' : 'discard';
|
|
1016
1008
|
return broker.publish('execution', 'evaluate.flow.' + action, formatFlowAction(flow, {
|
|
@@ -101,7 +101,7 @@ SequenceFlow.prototype.shake = function shake(message) {
|
|
|
101
101
|
|
|
102
102
|
if (content.id === this.targetId) return this.broker.publish('event', 'flow.shake.loop', content, {persistent: false, type: 'shake'});
|
|
103
103
|
|
|
104
|
-
for (const s of message.content.sequence) {
|
|
104
|
+
for (const s of message.content.sequence || []) {
|
|
105
105
|
if (s.id === this.id) return this.broker.publish('event', 'flow.shake.loop', content, {persistent: false, type: 'shake'});
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -140,6 +140,19 @@ SequenceFlow.prototype.createMessage = function createMessage(override) {
|
|
|
140
140
|
};
|
|
141
141
|
};
|
|
142
142
|
|
|
143
|
+
SequenceFlow.prototype.evaluate = function evaluate(fromMessage, callback) {
|
|
144
|
+
if (this.isDefault) {
|
|
145
|
+
return callback(null, true);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const flowCondition = this.getCondition();
|
|
149
|
+
if (!flowCondition) {
|
|
150
|
+
return callback(null, true);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
flowCondition.execute(fromMessage, callback);
|
|
154
|
+
};
|
|
155
|
+
|
|
143
156
|
SequenceFlow.prototype._publishEvent = function publishEvent(action, content) {
|
|
144
157
|
const eventContent = this.createMessage({
|
|
145
158
|
action,
|
package/src/tasks/ReceiveTask.js
CHANGED
|
@@ -1,215 +1,215 @@
|
|
|
1
|
-
import Activity from '../activity/Activity.js';
|
|
2
|
-
import {cloneContent} from '../messageHelper.js';
|
|
3
|
-
|
|
4
|
-
const kCompleted = Symbol.for('completed');
|
|
5
|
-
const kExecuteMessage = Symbol.for('executeMessage');
|
|
6
|
-
const kReferenceElement = Symbol.for('referenceElement');
|
|
7
|
-
const kReferenceInfo = Symbol.for('referenceInfo');
|
|
8
|
-
|
|
9
|
-
export default function ReceiveTask(activityDef, context) {
|
|
10
|
-
const task = new Activity(ReceiveTaskBehaviour, activityDef, context);
|
|
11
|
-
|
|
12
|
-
task.broker.assertQueue('message', {autoDelete: false, durable: true});
|
|
13
|
-
task.broker.bindQueue('message', 'api', '*.message.#', {durable: true});
|
|
14
|
-
|
|
15
|
-
return task;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function ReceiveTaskBehaviour(activity) {
|
|
19
|
-
const {id, type, behaviour} = activity;
|
|
20
|
-
|
|
21
|
-
this.id = id;
|
|
22
|
-
this.type = type;
|
|
23
|
-
|
|
24
|
-
const reference = this.reference = {
|
|
25
|
-
name: 'anonymous',
|
|
26
|
-
...behaviour.messageRef,
|
|
27
|
-
referenceType: 'message',
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
this.loopCharacteristics = behaviour.loopCharacteristics && new behaviour.loopCharacteristics.Behaviour(activity, behaviour.loopCharacteristics);
|
|
31
|
-
this.activity = activity;
|
|
32
|
-
this.broker = activity.broker;
|
|
33
|
-
|
|
34
|
-
this[kReferenceElement] = reference.id && activity.getActivityById(reference.id);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
ReceiveTaskBehaviour.prototype.execute = function execute(executeMessage) {
|
|
38
|
-
return new ReceiveTaskExecution(this).execute(executeMessage);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
function ReceiveTaskExecution(parent) {
|
|
42
|
-
const {activity, broker, loopCharacteristics, reference} = parent;
|
|
43
|
-
|
|
44
|
-
this.id = activity.id;
|
|
45
|
-
this.logger = activity.logger;
|
|
46
|
-
this.reference = reference;
|
|
47
|
-
this.broker = broker;
|
|
48
|
-
this.loopCharacteristics = loopCharacteristics;
|
|
49
|
-
this.referenceElement = parent[kReferenceElement];
|
|
50
|
-
|
|
51
|
-
this[kCompleted] = false;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
ReceiveTaskExecution.prototype.execute = function execute(executeMessage) {
|
|
55
|
-
this[kExecuteMessage] = executeMessage;
|
|
56
|
-
|
|
57
|
-
const executeContent = executeMessage.content;
|
|
58
|
-
const {executionId, isRootScope} = executeContent;
|
|
59
|
-
this.executionId = executionId;
|
|
60
|
-
|
|
61
|
-
const info = this[kReferenceInfo] = this._getReferenceInfo(executeMessage);
|
|
62
|
-
|
|
63
|
-
if (isRootScope) {
|
|
64
|
-
this._setupMessageHandling(executionId);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const loopCharacteristics = this.loopCharacteristics;
|
|
68
|
-
if (loopCharacteristics && executeMessage.content.isRootScope) {
|
|
69
|
-
return loopCharacteristics.execute(executeMessage);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const broker = this.broker;
|
|
73
|
-
broker.consume('message', this._onCatchMessage.bind(this), {
|
|
74
|
-
noAck: true,
|
|
75
|
-
consumerTag: `_onmessage-${executionId}`,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
if (this[kCompleted]) return;
|
|
79
|
-
|
|
80
|
-
broker.subscribeTmp('api', `activity.#.${executionId}`, this._onApiMessage.bind(this), {
|
|
81
|
-
noAck: true,
|
|
82
|
-
consumerTag: `_api-${executionId}`,
|
|
83
|
-
priority: 400,
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
this._debug(`expect ${info.description}`);
|
|
87
|
-
|
|
88
|
-
broker.publish('event', 'activity.wait', cloneContent(executeContent, {message: {...info.message}}));
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
ReceiveTaskExecution.prototype._onCatchMessage = function onCatchMessage(routingKey, message) {
|
|
92
|
-
const content = message.content;
|
|
93
|
-
|
|
94
|
-
const {id: signalId, executionId: signalExecutionId} = content.message || {};
|
|
95
|
-
const {message: referenceMessage, description} = this[kReferenceInfo];
|
|
96
|
-
|
|
97
|
-
if (!referenceMessage.id && signalId || signalExecutionId) {
|
|
98
|
-
if (this.loopCharacteristics && signalExecutionId !== this.executionId) return;
|
|
99
|
-
if (signalId !== this.id && signalExecutionId !== this.executionId) return;
|
|
100
|
-
this._debug('caught direct message');
|
|
101
|
-
} else if (referenceMessage.id !== signalId) return;
|
|
102
|
-
else {
|
|
103
|
-
this._debug(`caught ${description}`);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const {type: messageType, correlationId} = message.properties;
|
|
107
|
-
const broker = this.broker;
|
|
108
|
-
const executeContent = this[kExecuteMessage].content;
|
|
109
|
-
|
|
110
|
-
broker.publish('event', 'activity.consumed', cloneContent(executeContent, {message: {...message.content.message}}), {correlationId, type: messageType});
|
|
111
|
-
broker.publish('event', 'activity.catch', cloneContent(executeContent, {message: message.content.message}), {type: 'catch', correlationId});
|
|
112
|
-
|
|
113
|
-
this._complete(message.content.message, {correlationId});
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
ReceiveTaskExecution.prototype._onApiMessage = function onApiMessage(routingKey, message) {
|
|
117
|
-
const {type: messageType, correlationId} = message.properties;
|
|
118
|
-
switch (messageType) {
|
|
119
|
-
case 'message':
|
|
120
|
-
case 'signal': {
|
|
121
|
-
return this._complete(message.content.message, {correlationId});
|
|
122
|
-
}
|
|
123
|
-
case 'discard': {
|
|
124
|
-
this[kCompleted] = true;
|
|
125
|
-
this._stop();
|
|
126
|
-
return this.broker.publish('execution', 'execute.discard', cloneContent(this[kExecuteMessage].content), {correlationId});
|
|
127
|
-
}
|
|
128
|
-
case 'stop': {
|
|
129
|
-
return this._stop();
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
ReceiveTaskExecution.prototype._complete = function complete(output, options) {
|
|
135
|
-
this[kCompleted] = true;
|
|
136
|
-
this._stop();
|
|
137
|
-
return this.broker.publish('execution', 'execute.completed', cloneContent(this[kExecuteMessage].content, {output}), options);
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
ReceiveTaskExecution.prototype._stop = function stop() {
|
|
141
|
-
const broker = this.broker, executionId = this.executionId;
|
|
142
|
-
broker.cancel(`_onmessage-${executionId}`);
|
|
143
|
-
broker.cancel(`_api-${executionId}`);
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
ReceiveTaskExecution.prototype._setupMessageHandling = function setupMessageHandling(executionId) {
|
|
147
|
-
const broker = this.broker;
|
|
148
|
-
broker.subscribeTmp('api', '#.signal.*', this._onDelegateMessage.bind(this), {
|
|
149
|
-
noAck: true,
|
|
150
|
-
consumerTag: `_api-delegated-${executionId}`,
|
|
151
|
-
}, {
|
|
152
|
-
noAck: true,
|
|
153
|
-
});
|
|
154
|
-
broker.subscribeTmp('api', `activity.stop.${executionId}`, this._onStopApiMessage.bind(this), {
|
|
155
|
-
noAck: true,
|
|
156
|
-
consumerTag: `_api-stop-${executionId}`,
|
|
157
|
-
priority: 400,
|
|
158
|
-
});
|
|
159
|
-
broker.subscribeTmp('execution', 'execute.#', this._onExecutionComplete.bind(this), {
|
|
160
|
-
noAck: true,
|
|
161
|
-
consumerTag: `_execution-complete-${executionId}`,
|
|
162
|
-
}, {
|
|
163
|
-
noAck: true,
|
|
164
|
-
});
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
ReceiveTaskExecution.prototype._onDelegateMessage = function onDelegateMessage(_, message) {
|
|
168
|
-
if (!message.properties.delegate) return;
|
|
169
|
-
this.broker.sendToQueue('message', message.content, message.properties);
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
ReceiveTaskExecution.prototype._onStopApiMessage = function onStopApiMessage() {
|
|
173
|
-
this._stopMessageHandling(true);
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
ReceiveTaskExecution.prototype._onExecutionComplete = function onExecutionComplete(routingKey, {content}) {
|
|
177
|
-
if (!content.isRootScope) return;
|
|
178
|
-
switch (routingKey) {
|
|
179
|
-
case 'execute.completed':
|
|
180
|
-
case 'execute.error':
|
|
181
|
-
case 'execute.discard':
|
|
182
|
-
this._stopMessageHandling();
|
|
183
|
-
break;
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
ReceiveTaskExecution.prototype._stopMessageHandling = function stop(keepMessageQ) {
|
|
188
|
-
const broker = this.broker, executionId = this.executionId;
|
|
189
|
-
broker.cancel(`_api-delegated-${executionId}`);
|
|
190
|
-
broker.cancel(`_api-stop-${executionId}`);
|
|
191
|
-
broker.cancel(`_execution-complete-${executionId}`);
|
|
192
|
-
if (!keepMessageQ) broker.purgeQueue('message');
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
ReceiveTaskExecution.prototype._getReferenceInfo = function getReferenceInfo(message) {
|
|
196
|
-
const referenceElement = this.referenceElement;
|
|
197
|
-
if (!referenceElement) {
|
|
198
|
-
return {
|
|
199
|
-
message: {...this.reference},
|
|
200
|
-
description: 'anonymous message',
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const result = {
|
|
205
|
-
message: referenceElement.resolve(message),
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
result.description = `${result.message.name} <${result.message.id}>`;
|
|
209
|
-
|
|
210
|
-
return result;
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
ReceiveTaskExecution.prototype._debug = function debug(msg) {
|
|
214
|
-
this.logger.debug(`<${this.executionId} (${this.id})> ${msg}`);
|
|
215
|
-
};
|
|
1
|
+
import Activity from '../activity/Activity.js';
|
|
2
|
+
import {cloneContent} from '../messageHelper.js';
|
|
3
|
+
|
|
4
|
+
const kCompleted = Symbol.for('completed');
|
|
5
|
+
const kExecuteMessage = Symbol.for('executeMessage');
|
|
6
|
+
const kReferenceElement = Symbol.for('referenceElement');
|
|
7
|
+
const kReferenceInfo = Symbol.for('referenceInfo');
|
|
8
|
+
|
|
9
|
+
export default function ReceiveTask(activityDef, context) {
|
|
10
|
+
const task = new Activity(ReceiveTaskBehaviour, activityDef, context);
|
|
11
|
+
|
|
12
|
+
task.broker.assertQueue('message', {autoDelete: false, durable: true});
|
|
13
|
+
task.broker.bindQueue('message', 'api', '*.message.#', {durable: true});
|
|
14
|
+
|
|
15
|
+
return task;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function ReceiveTaskBehaviour(activity) {
|
|
19
|
+
const {id, type, behaviour} = activity;
|
|
20
|
+
|
|
21
|
+
this.id = id;
|
|
22
|
+
this.type = type;
|
|
23
|
+
|
|
24
|
+
const reference = this.reference = {
|
|
25
|
+
name: 'anonymous',
|
|
26
|
+
...behaviour.messageRef,
|
|
27
|
+
referenceType: 'message',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
this.loopCharacteristics = behaviour.loopCharacteristics && new behaviour.loopCharacteristics.Behaviour(activity, behaviour.loopCharacteristics);
|
|
31
|
+
this.activity = activity;
|
|
32
|
+
this.broker = activity.broker;
|
|
33
|
+
|
|
34
|
+
this[kReferenceElement] = reference.id && activity.getActivityById(reference.id);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
ReceiveTaskBehaviour.prototype.execute = function execute(executeMessage) {
|
|
38
|
+
return new ReceiveTaskExecution(this).execute(executeMessage);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
function ReceiveTaskExecution(parent) {
|
|
42
|
+
const {activity, broker, loopCharacteristics, reference} = parent;
|
|
43
|
+
|
|
44
|
+
this.id = activity.id;
|
|
45
|
+
this.logger = activity.logger;
|
|
46
|
+
this.reference = reference;
|
|
47
|
+
this.broker = broker;
|
|
48
|
+
this.loopCharacteristics = loopCharacteristics;
|
|
49
|
+
this.referenceElement = parent[kReferenceElement];
|
|
50
|
+
|
|
51
|
+
this[kCompleted] = false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
ReceiveTaskExecution.prototype.execute = function execute(executeMessage) {
|
|
55
|
+
this[kExecuteMessage] = executeMessage;
|
|
56
|
+
|
|
57
|
+
const executeContent = executeMessage.content;
|
|
58
|
+
const {executionId, isRootScope} = executeContent;
|
|
59
|
+
this.executionId = executionId;
|
|
60
|
+
|
|
61
|
+
const info = this[kReferenceInfo] = this._getReferenceInfo(executeMessage);
|
|
62
|
+
|
|
63
|
+
if (isRootScope) {
|
|
64
|
+
this._setupMessageHandling(executionId);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const loopCharacteristics = this.loopCharacteristics;
|
|
68
|
+
if (loopCharacteristics && executeMessage.content.isRootScope) {
|
|
69
|
+
return loopCharacteristics.execute(executeMessage);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const broker = this.broker;
|
|
73
|
+
broker.consume('message', this._onCatchMessage.bind(this), {
|
|
74
|
+
noAck: true,
|
|
75
|
+
consumerTag: `_onmessage-${executionId}`,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (this[kCompleted]) return;
|
|
79
|
+
|
|
80
|
+
broker.subscribeTmp('api', `activity.#.${executionId}`, this._onApiMessage.bind(this), {
|
|
81
|
+
noAck: true,
|
|
82
|
+
consumerTag: `_api-${executionId}`,
|
|
83
|
+
priority: 400,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
this._debug(`expect ${info.description}`);
|
|
87
|
+
|
|
88
|
+
broker.publish('event', 'activity.wait', cloneContent(executeContent, {message: {...info.message}}));
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
ReceiveTaskExecution.prototype._onCatchMessage = function onCatchMessage(routingKey, message) {
|
|
92
|
+
const content = message.content;
|
|
93
|
+
|
|
94
|
+
const {id: signalId, executionId: signalExecutionId} = content.message || {};
|
|
95
|
+
const {message: referenceMessage, description} = this[kReferenceInfo];
|
|
96
|
+
|
|
97
|
+
if (!referenceMessage.id && signalId || signalExecutionId) {
|
|
98
|
+
if (this.loopCharacteristics && signalExecutionId !== this.executionId) return;
|
|
99
|
+
if (signalId !== this.id && signalExecutionId !== this.executionId) return;
|
|
100
|
+
this._debug('caught direct message');
|
|
101
|
+
} else if (referenceMessage.id !== signalId) return;
|
|
102
|
+
else {
|
|
103
|
+
this._debug(`caught ${description}`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const {type: messageType, correlationId} = message.properties;
|
|
107
|
+
const broker = this.broker;
|
|
108
|
+
const executeContent = this[kExecuteMessage].content;
|
|
109
|
+
|
|
110
|
+
broker.publish('event', 'activity.consumed', cloneContent(executeContent, {message: {...message.content.message}}), {correlationId, type: messageType});
|
|
111
|
+
broker.publish('event', 'activity.catch', cloneContent(executeContent, {message: message.content.message}), {type: 'catch', correlationId});
|
|
112
|
+
|
|
113
|
+
this._complete(message.content.message, {correlationId});
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
ReceiveTaskExecution.prototype._onApiMessage = function onApiMessage(routingKey, message) {
|
|
117
|
+
const {type: messageType, correlationId} = message.properties;
|
|
118
|
+
switch (messageType) {
|
|
119
|
+
case 'message':
|
|
120
|
+
case 'signal': {
|
|
121
|
+
return this._complete(message.content.message, {correlationId});
|
|
122
|
+
}
|
|
123
|
+
case 'discard': {
|
|
124
|
+
this[kCompleted] = true;
|
|
125
|
+
this._stop();
|
|
126
|
+
return this.broker.publish('execution', 'execute.discard', cloneContent(this[kExecuteMessage].content), {correlationId});
|
|
127
|
+
}
|
|
128
|
+
case 'stop': {
|
|
129
|
+
return this._stop();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
ReceiveTaskExecution.prototype._complete = function complete(output, options) {
|
|
135
|
+
this[kCompleted] = true;
|
|
136
|
+
this._stop();
|
|
137
|
+
return this.broker.publish('execution', 'execute.completed', cloneContent(this[kExecuteMessage].content, {output}), options);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
ReceiveTaskExecution.prototype._stop = function stop() {
|
|
141
|
+
const broker = this.broker, executionId = this.executionId;
|
|
142
|
+
broker.cancel(`_onmessage-${executionId}`);
|
|
143
|
+
broker.cancel(`_api-${executionId}`);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
ReceiveTaskExecution.prototype._setupMessageHandling = function setupMessageHandling(executionId) {
|
|
147
|
+
const broker = this.broker;
|
|
148
|
+
broker.subscribeTmp('api', '#.signal.*', this._onDelegateMessage.bind(this), {
|
|
149
|
+
noAck: true,
|
|
150
|
+
consumerTag: `_api-delegated-${executionId}`,
|
|
151
|
+
}, {
|
|
152
|
+
noAck: true,
|
|
153
|
+
});
|
|
154
|
+
broker.subscribeTmp('api', `activity.stop.${executionId}`, this._onStopApiMessage.bind(this), {
|
|
155
|
+
noAck: true,
|
|
156
|
+
consumerTag: `_api-stop-${executionId}`,
|
|
157
|
+
priority: 400,
|
|
158
|
+
});
|
|
159
|
+
broker.subscribeTmp('execution', 'execute.#', this._onExecutionComplete.bind(this), {
|
|
160
|
+
noAck: true,
|
|
161
|
+
consumerTag: `_execution-complete-${executionId}`,
|
|
162
|
+
}, {
|
|
163
|
+
noAck: true,
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
ReceiveTaskExecution.prototype._onDelegateMessage = function onDelegateMessage(_, message) {
|
|
168
|
+
if (!message.properties.delegate) return;
|
|
169
|
+
this.broker.sendToQueue('message', message.content, message.properties);
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
ReceiveTaskExecution.prototype._onStopApiMessage = function onStopApiMessage() {
|
|
173
|
+
this._stopMessageHandling(true);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
ReceiveTaskExecution.prototype._onExecutionComplete = function onExecutionComplete(routingKey, {content}) {
|
|
177
|
+
if (!content.isRootScope) return;
|
|
178
|
+
switch (routingKey) {
|
|
179
|
+
case 'execute.completed':
|
|
180
|
+
case 'execute.error':
|
|
181
|
+
case 'execute.discard':
|
|
182
|
+
this._stopMessageHandling();
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
ReceiveTaskExecution.prototype._stopMessageHandling = function stop(keepMessageQ) {
|
|
188
|
+
const broker = this.broker, executionId = this.executionId;
|
|
189
|
+
broker.cancel(`_api-delegated-${executionId}`);
|
|
190
|
+
broker.cancel(`_api-stop-${executionId}`);
|
|
191
|
+
broker.cancel(`_execution-complete-${executionId}`);
|
|
192
|
+
if (!keepMessageQ) broker.purgeQueue('message');
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
ReceiveTaskExecution.prototype._getReferenceInfo = function getReferenceInfo(message) {
|
|
196
|
+
const referenceElement = this.referenceElement;
|
|
197
|
+
if (!referenceElement) {
|
|
198
|
+
return {
|
|
199
|
+
message: {...this.reference},
|
|
200
|
+
description: 'anonymous message',
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const result = {
|
|
205
|
+
message: referenceElement.resolve(message),
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
result.description = `${result.message.name} <${result.message.id}>`;
|
|
209
|
+
|
|
210
|
+
return result;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
ReceiveTaskExecution.prototype._debug = function debug(msg) {
|
|
214
|
+
this.logger.debug(`<${this.executionId} (${this.id})> ${msg}`);
|
|
215
|
+
};
|
package/types/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ declare module 'bpmn-elements' {
|
|
|
2
2
|
import { Broker } from 'smqp';
|
|
3
3
|
import { BrokerState } from 'smqp/types/Broker';
|
|
4
4
|
import { Consumer } from 'smqp/types/Queue';
|
|
5
|
-
import { MessageMessage } from 'smqp/types/Message';
|
|
5
|
+
import { MessageMessage, MessageFields, MessageProperties } from 'smqp/types/Message';
|
|
6
6
|
import { SerializableContext, SerializableElement } from 'moddle-context-serializer';
|
|
7
7
|
|
|
8
8
|
interface ElementBroker<T> extends Broker {
|
|
@@ -25,16 +25,16 @@ declare module 'bpmn-elements' {
|
|
|
25
25
|
[x: string]: any,
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
id?: string
|
|
30
|
-
type?: string
|
|
31
|
-
executionId?: string
|
|
32
|
-
parent?: ElementParent
|
|
33
|
-
[x: string]: any
|
|
28
|
+
interface ElementMessageContent {
|
|
29
|
+
id?: string;
|
|
30
|
+
type?: string;
|
|
31
|
+
executionId?: string;
|
|
32
|
+
parent?: ElementParent;
|
|
33
|
+
[x: string]: any;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
interface ElementBrokerMessage extends MessageMessage {
|
|
37
|
-
content:
|
|
37
|
+
content: ElementMessageContent,
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
interface EventDefinition {
|
|
@@ -211,8 +211,31 @@ declare module 'bpmn-elements' {
|
|
|
211
211
|
createMessage(content?: Record<string, any>): any;
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
+
interface ExecutionScope {
|
|
215
|
+
/** Calling element id */
|
|
216
|
+
id: string;
|
|
217
|
+
/** Calling element type */
|
|
218
|
+
type: string;
|
|
219
|
+
/** Execution message fields */
|
|
220
|
+
fields: MessageFields;
|
|
221
|
+
/** Execution message content */
|
|
222
|
+
content: ElementMessageContent;
|
|
223
|
+
/** Execution message properties */
|
|
224
|
+
properties: MessageProperties;
|
|
225
|
+
environment: Environment;
|
|
226
|
+
/** Calling element logger instance */
|
|
227
|
+
logger?: ILogger;
|
|
228
|
+
/**
|
|
229
|
+
* Resolve expression with the current scope
|
|
230
|
+
* @param expression expression string
|
|
231
|
+
* @returns Whatever the expression returns
|
|
232
|
+
*/
|
|
233
|
+
resolveExpression: (expression: string) => any;
|
|
234
|
+
ActivityError: ActivityError;
|
|
235
|
+
}
|
|
236
|
+
|
|
214
237
|
interface Script {
|
|
215
|
-
execute(executionContext:
|
|
238
|
+
execute(executionContext: ExecutionScope, callback: CallableFunction): void;
|
|
216
239
|
}
|
|
217
240
|
|
|
218
241
|
abstract class MessageElement {
|
|
@@ -458,6 +481,13 @@ declare module 'bpmn-elements' {
|
|
|
458
481
|
shake(message: any): number;
|
|
459
482
|
getCondition(): any;
|
|
460
483
|
createMessage(override?: any): object;
|
|
484
|
+
/**
|
|
485
|
+
* Evaluate flow
|
|
486
|
+
* Executes condition if any, default flow is
|
|
487
|
+
* @param fromMessage Activity message
|
|
488
|
+
* @param {evaluateCallback} callback Callback with evaluation result, if truthy flow should be taken
|
|
489
|
+
*/
|
|
490
|
+
evaluate(fromMessage: ElementBrokerMessage, callback: (err: Error, result: any) => void): void;
|
|
461
491
|
}
|
|
462
492
|
|
|
463
493
|
interface MessageFlowReference {
|
|
@@ -601,12 +631,21 @@ declare module 'bpmn-elements' {
|
|
|
601
631
|
class Signal extends MessageElement {}
|
|
602
632
|
class Escalation extends MessageElement {}
|
|
603
633
|
|
|
604
|
-
|
|
634
|
+
class ActivityError extends Error {
|
|
605
635
|
type: string;
|
|
606
636
|
description: string;
|
|
607
637
|
/** Activity that threw error */
|
|
608
638
|
source?: ElementBrokerMessage;
|
|
609
639
|
/** Original error */
|
|
610
640
|
inner?: Error;
|
|
641
|
+
code?: string;
|
|
642
|
+
constructor(description: string, sourceMessage: MessageMessage, inner?: Error);
|
|
611
643
|
}
|
|
612
644
|
}
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* Evaluate flow callback
|
|
648
|
+
* @callback evaluateCallback
|
|
649
|
+
* @param {Error} err Evaluation error
|
|
650
|
+
* @param {boolean|object} evaluationResult If thruthy flow should be taken
|
|
651
|
+
*/
|