bpmn-elements 16.1.0 → 16.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Api.js +1 -1
- package/dist/Context.js +2 -4
- package/dist/Environment.js +3 -3
- package/dist/EventBroker.js +1 -1
- package/dist/MessageFormatter.js +2 -2
- package/dist/Tracker.js +1 -0
- package/dist/activity/Activity.js +67 -163
- package/dist/activity/ActivityExecution.js +2 -2
- package/dist/activity/outbound-evaluator.js +131 -0
- package/dist/definition/Definition.js +4 -4
- package/dist/definition/DefinitionExecution.js +6 -6
- package/dist/error/Errors.js +7 -10
- package/dist/eventDefinitions/CancelEventDefinition.js +1 -2
- package/dist/eventDefinitions/CompensateEventDefinition.js +2 -3
- package/dist/eventDefinitions/ConditionalEventDefinition.js +2 -3
- package/dist/eventDefinitions/ErrorEventDefinition.js +3 -4
- package/dist/eventDefinitions/EscalationEventDefinition.js +1 -2
- package/dist/eventDefinitions/LinkEventDefinition.js +1 -2
- package/dist/eventDefinitions/MessageEventDefinition.js +2 -3
- package/dist/eventDefinitions/SignalEventDefinition.js +2 -3
- package/dist/eventDefinitions/TimerEventDefinition.js +2 -3
- package/dist/events/BoundaryEvent.js +2 -3
- package/dist/events/StartEvent.js +1 -2
- package/dist/flows/Association.js +2 -2
- package/dist/flows/SequenceFlow.js +3 -7
- package/dist/gateways/EventBasedGateway.js +7 -5
- package/dist/io/EnvironmentDataObject.js +1 -1
- package/dist/io/EnvironmentDataStore.js +1 -1
- package/dist/io/EnvironmentDataStoreReference.js +1 -1
- package/dist/io/InputOutputSpecification.js +2 -2
- package/dist/io/Properties.js +14 -14
- package/dist/process/Process.js +5 -7
- package/dist/process/ProcessExecution.js +13 -13
- package/dist/tasks/ServiceTask.js +1 -1
- package/package.json +2 -2
- package/src/Api.js +1 -1
- package/src/Context.js +2 -1
- package/src/Environment.js +3 -3
- package/src/EventBroker.js +1 -1
- package/src/MessageFormatter.js +2 -2
- package/src/Tracker.js +1 -0
- package/src/activity/Activity.js +65 -159
- package/src/activity/ActivityExecution.js +2 -2
- package/src/activity/outbound-evaluator.js +127 -0
- package/src/definition/Definition.js +4 -4
- package/src/definition/DefinitionExecution.js +6 -6
- package/src/error/Errors.js +7 -11
- package/src/eventDefinitions/CancelEventDefinition.js +1 -2
- package/src/eventDefinitions/CompensateEventDefinition.js +2 -3
- package/src/eventDefinitions/ConditionalEventDefinition.js +2 -3
- package/src/eventDefinitions/ErrorEventDefinition.js +3 -4
- package/src/eventDefinitions/EscalationEventDefinition.js +1 -2
- package/src/eventDefinitions/LinkEventDefinition.js +1 -2
- package/src/eventDefinitions/MessageEventDefinition.js +2 -3
- package/src/eventDefinitions/SignalEventDefinition.js +2 -3
- package/src/eventDefinitions/TimerEventDefinition.js +2 -3
- package/src/events/BoundaryEvent.js +2 -3
- package/src/events/StartEvent.js +1 -2
- package/src/flows/Association.js +2 -2
- package/src/flows/SequenceFlow.js +3 -3
- package/src/gateways/EventBasedGateway.js +5 -3
- package/src/io/EnvironmentDataObject.js +1 -1
- package/src/io/EnvironmentDataStore.js +1 -1
- package/src/io/EnvironmentDataStoreReference.js +1 -1
- package/src/io/InputOutputSpecification.js +2 -2
- package/src/io/Properties.js +14 -14
- package/src/process/Process.js +5 -7
- package/src/process/ProcessExecution.js +13 -13
- package/src/tasks/ServiceTask.js +1 -1
package/src/Environment.js
CHANGED
|
@@ -59,7 +59,7 @@ Environment.prototype.recover = function recover(state) {
|
|
|
59
59
|
return this;
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
-
Environment.prototype.clone = function clone(overrideOptions
|
|
62
|
+
Environment.prototype.clone = function clone(overrideOptions) {
|
|
63
63
|
const services = this[kServices];
|
|
64
64
|
const newOptions = {
|
|
65
65
|
settings: { ...this.settings },
|
|
@@ -74,7 +74,7 @@ Environment.prototype.clone = function clone(overrideOptions = {}) {
|
|
|
74
74
|
services,
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
-
if (overrideOptions
|
|
77
|
+
if (overrideOptions?.services) newOptions.services = { ...services, ...overrideOptions.services };
|
|
78
78
|
|
|
79
79
|
return new this.constructor(newOptions);
|
|
80
80
|
};
|
|
@@ -109,7 +109,7 @@ Environment.prototype.getServiceByName = function getServiceByName(serviceName)
|
|
|
109
109
|
return this[kServices][serviceName];
|
|
110
110
|
};
|
|
111
111
|
|
|
112
|
-
Environment.prototype.resolveExpression = function resolveExpression(expression, message
|
|
112
|
+
Environment.prototype.resolveExpression = function resolveExpression(expression, message, expressionFnContext) {
|
|
113
113
|
const from = {
|
|
114
114
|
environment: this,
|
|
115
115
|
...message,
|
package/src/EventBroker.js
CHANGED
|
@@ -78,7 +78,7 @@ EventBroker.prototype.on = function on(eventName, callback, eventOptions = { onc
|
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
-
EventBroker.prototype.once = function once(eventName, callback, eventOptions
|
|
81
|
+
EventBroker.prototype.once = function once(eventName, callback, eventOptions) {
|
|
82
82
|
return this.on(eventName, callback, { ...eventOptions, once: true });
|
|
83
83
|
};
|
|
84
84
|
|
package/src/MessageFormatter.js
CHANGED
|
@@ -65,7 +65,7 @@ Formatter.prototype._onMessage = function onMessage(routingKey, message) {
|
|
|
65
65
|
default: {
|
|
66
66
|
message.ack();
|
|
67
67
|
|
|
68
|
-
const endRoutingKey = message.content
|
|
68
|
+
const endRoutingKey = message.content?.endRoutingKey;
|
|
69
69
|
if (endRoutingKey) {
|
|
70
70
|
this._decorate(message.content);
|
|
71
71
|
pending.push(message);
|
|
@@ -99,7 +99,7 @@ Formatter.prototype._complete = function complete(message, isError) {
|
|
|
99
99
|
this.broker.cancel(message.fields.consumerTag);
|
|
100
100
|
|
|
101
101
|
if (isError) {
|
|
102
|
-
const error =
|
|
102
|
+
const error = message.content?.error || new Error('formatting failed');
|
|
103
103
|
const errMessage = error.message || 'formatting failed';
|
|
104
104
|
this._debug(`formatting of ${formatKey} failed with ${message.fields.routingKey}: ${errMessage}`);
|
|
105
105
|
return callback(new ActivityError(errMessage, cloneMessage(runMessage), error));
|
package/src/Tracker.js
CHANGED
|
@@ -30,6 +30,7 @@ ActivityTracker.prototype.track = function track(routingKey, message) {
|
|
|
30
30
|
break;
|
|
31
31
|
case 'activity.execution.outbound.take':
|
|
32
32
|
case 'activity.detach':
|
|
33
|
+
case 'activity.call':
|
|
33
34
|
case 'activity.wait': {
|
|
34
35
|
if (content.isMultiInstance) this._waiting(content.parent.executionId);
|
|
35
36
|
else this._waiting(executionId);
|
package/src/activity/Activity.js
CHANGED
|
@@ -5,6 +5,7 @@ import { ActivityBroker } from '../EventBroker.js';
|
|
|
5
5
|
import { Formatter } from '../MessageFormatter.js';
|
|
6
6
|
import { cloneContent, cloneParent, cloneMessage } from '../messageHelper.js';
|
|
7
7
|
import { makeErrorFromMessage, ActivityError } from '../error/Errors.js';
|
|
8
|
+
import { OutboundEvaluator, formatFlowAction } from './outbound-evaluator.js';
|
|
8
9
|
|
|
9
10
|
const kActivityDef = Symbol.for('activityDefinition');
|
|
10
11
|
const kConsuming = Symbol.for('consuming');
|
|
@@ -68,16 +69,21 @@ function Activity(Behaviour, activityDef, context) {
|
|
|
68
69
|
inboundTriggers = inboundSequenceFlows.slice();
|
|
69
70
|
}
|
|
70
71
|
const outboundSequenceFlows = context.getOutboundSequenceFlows(id);
|
|
72
|
+
|
|
73
|
+
const isParallelJoin = activityDef.isParallelGateway && inboundSequenceFlows.length > 1;
|
|
74
|
+
|
|
71
75
|
const flows = (this[kFlows] = {
|
|
72
76
|
inboundSequenceFlows,
|
|
73
77
|
inboundAssociations,
|
|
74
|
-
inboundJoinFlows: new Set(),
|
|
75
78
|
inboundTriggers,
|
|
76
79
|
outboundSequenceFlows,
|
|
77
80
|
outboundEvaluator: new OutboundEvaluator(this, outboundSequenceFlows),
|
|
81
|
+
...(isParallelJoin && {
|
|
82
|
+
inboundJoinFlows: new Set(),
|
|
83
|
+
inboundSourceIds: new Set(inboundSequenceFlows.map(({ sourceId }) => sourceId)),
|
|
84
|
+
}),
|
|
78
85
|
});
|
|
79
86
|
|
|
80
|
-
const isParallelJoin = activityDef.isParallelGateway && flows.inboundSequenceFlows.length > 1;
|
|
81
87
|
this[kFlags] = {
|
|
82
88
|
isEnd: flows.outboundSequenceFlows.length === 0,
|
|
83
89
|
isStart: flows.inboundSequenceFlows.length === 0 && !attachedTo && !behaviour.triggeredByEvent && !isForCompensation,
|
|
@@ -88,7 +94,7 @@ function Activity(Behaviour, activityDef, context) {
|
|
|
88
94
|
isTransaction: activityDef.isTransaction,
|
|
89
95
|
isParallelJoin,
|
|
90
96
|
isThrowing: activityDef.isThrowing,
|
|
91
|
-
lane: activityDef.lane
|
|
97
|
+
lane: activityDef.lane?.id,
|
|
92
98
|
};
|
|
93
99
|
this[kExec] = new Map();
|
|
94
100
|
|
|
@@ -99,7 +105,7 @@ function Activity(Behaviour, activityDef, context) {
|
|
|
99
105
|
onExecutionMessage: this._onExecutionMessage.bind(this),
|
|
100
106
|
};
|
|
101
107
|
|
|
102
|
-
this[kEventDefinitions] = eventDefinitions
|
|
108
|
+
this[kEventDefinitions] = eventDefinitions?.map((ed, idx) => new ed.Behaviour(this, ed, context, idx));
|
|
103
109
|
this[kExtensions] = context.loadExtensions(this);
|
|
104
110
|
this[kConsuming] = false;
|
|
105
111
|
this[kConsumingRunQ] = undefined;
|
|
@@ -129,7 +135,7 @@ Object.defineProperties(Activity.prototype, {
|
|
|
129
135
|
bpmnIo: {
|
|
130
136
|
get() {
|
|
131
137
|
const extensions = this[kExtensions];
|
|
132
|
-
return extensions
|
|
138
|
+
return extensions?.extensions.find((e) => e.type === 'bpmnio');
|
|
133
139
|
},
|
|
134
140
|
},
|
|
135
141
|
formatter: {
|
|
@@ -502,16 +508,16 @@ Activity.prototype._onInbound = function onInbound(routingKey, message) {
|
|
|
502
508
|
|
|
503
509
|
Activity.prototype._onJoinInbound = function onJoinInbound(routingKey, message) {
|
|
504
510
|
const { content } = message;
|
|
505
|
-
const { inboundJoinFlows,
|
|
511
|
+
const { inboundJoinFlows, inboundSourceIds } = this[kFlows];
|
|
506
512
|
let alreadyTouched = false;
|
|
507
513
|
|
|
508
514
|
const touched = new Set();
|
|
509
515
|
|
|
510
516
|
let taken;
|
|
511
517
|
for (const msg of inboundJoinFlows) {
|
|
512
|
-
const
|
|
513
|
-
touched.add(
|
|
514
|
-
if (
|
|
518
|
+
const sourceId = msg.content.sourceId;
|
|
519
|
+
touched.add(sourceId);
|
|
520
|
+
if (sourceId === content.sourceId) {
|
|
515
521
|
alreadyTouched = true;
|
|
516
522
|
}
|
|
517
523
|
}
|
|
@@ -520,7 +526,7 @@ Activity.prototype._onJoinInbound = function onJoinInbound(routingKey, message)
|
|
|
520
526
|
|
|
521
527
|
if (alreadyTouched) return;
|
|
522
528
|
|
|
523
|
-
const remaining =
|
|
529
|
+
const remaining = inboundSourceIds.size - touched.size - 1;
|
|
524
530
|
if (remaining) {
|
|
525
531
|
return this.logger.debug(`<${this.id}> inbound ${message.content.action} from <${message.content.id}>, ${remaining} remaining`);
|
|
526
532
|
}
|
|
@@ -649,7 +655,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
|
|
|
649
655
|
break;
|
|
650
656
|
}
|
|
651
657
|
case 'run.execute.passthrough': {
|
|
652
|
-
const execution = this.execution;
|
|
658
|
+
const execution = this[kExec].get('execution');
|
|
653
659
|
if (!isRedelivered && execution) {
|
|
654
660
|
if (execution.completed) return message.ack();
|
|
655
661
|
this[kExecuteMessage] = message;
|
|
@@ -660,13 +666,19 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
|
|
|
660
666
|
this.status = 'executing';
|
|
661
667
|
this[kExecuteMessage] = message;
|
|
662
668
|
|
|
663
|
-
const exec = this[kExec];
|
|
664
669
|
if (isRedelivered && this.extensions) this.extensions.activate(cloneMessage(message));
|
|
665
|
-
|
|
670
|
+
|
|
671
|
+
const exec = this[kExec];
|
|
672
|
+
let execution = exec.get('execution');
|
|
673
|
+
if (!execution) {
|
|
674
|
+
execution = new ActivityExecution(this, this.context);
|
|
675
|
+
exec.set('execution', execution);
|
|
676
|
+
}
|
|
677
|
+
|
|
666
678
|
this.broker
|
|
667
679
|
.getQueue('execution-q')
|
|
668
680
|
.assertConsumer(this[kMessageHandlers].onExecutionMessage, { exclusive: true, consumerTag: '_activity-execution' });
|
|
669
|
-
return
|
|
681
|
+
return execution.execute(message);
|
|
670
682
|
}
|
|
671
683
|
case 'run.end': {
|
|
672
684
|
this.logger.debug(`<${id}> end`, isRedelivered ? 'redelivered' : '');
|
|
@@ -821,14 +833,14 @@ Activity.prototype._doOutbound = function doOutbound(fromMessage, isDiscarded, c
|
|
|
821
833
|
const fromContent = fromMessage.content;
|
|
822
834
|
|
|
823
835
|
let discardSequence = fromContent.discardSequence;
|
|
824
|
-
if (isDiscarded && !discardSequence && this[kFlags].attachedTo && fromContent.inbound
|
|
836
|
+
if (isDiscarded && !discardSequence && this[kFlags].attachedTo && fromContent.inbound?.[0]) {
|
|
825
837
|
discardSequence = [fromContent.inbound[0].id];
|
|
826
838
|
}
|
|
827
839
|
|
|
828
840
|
let outboundFlows;
|
|
829
841
|
if (isDiscarded) {
|
|
830
842
|
outboundFlows = outboundSequenceFlows.map((flow) => formatFlowAction(flow, { action: 'discard' }));
|
|
831
|
-
} else if (fromContent.outbound
|
|
843
|
+
} else if (fromContent.outbound?.length) {
|
|
832
844
|
outboundFlows = outboundSequenceFlows.map((flow) => formatFlowAction(flow, fromContent.outbound.filter((f) => f.id === flow.id).pop()));
|
|
833
845
|
}
|
|
834
846
|
|
|
@@ -845,24 +857,44 @@ Activity.prototype._doOutbound = function doOutbound(fromMessage, isDiscarded, c
|
|
|
845
857
|
};
|
|
846
858
|
|
|
847
859
|
Activity.prototype._doRunOutbound = function doRunOutbound(outboundList, content, discardSequence) {
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
860
|
+
if (outboundList.length === 1) {
|
|
861
|
+
this._publishRunOutbound(outboundList[0], content, discardSequence);
|
|
862
|
+
} else {
|
|
863
|
+
const targets = new Map();
|
|
864
|
+
|
|
865
|
+
for (const outboundFlow of outboundList) {
|
|
866
|
+
const prevTarget = targets.get(outboundFlow.targetId);
|
|
867
|
+
if (!prevTarget) {
|
|
868
|
+
targets.set(outboundFlow.targetId, outboundFlow);
|
|
869
|
+
} else if (outboundFlow.action === 'take' && outboundFlow.action !== prevTarget.action) {
|
|
870
|
+
targets.set(outboundFlow.targetId, outboundFlow);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
for (const outboundFlow of targets.values()) {
|
|
875
|
+
this._publishRunOutbound(outboundFlow, content, discardSequence);
|
|
876
|
+
}
|
|
862
877
|
}
|
|
878
|
+
|
|
863
879
|
return outboundList;
|
|
864
880
|
};
|
|
865
881
|
|
|
882
|
+
Activity.prototype._publishRunOutbound = function publishRunOutbound(outboundFlow, content, discardSequence) {
|
|
883
|
+
const { id: flowId, action, result } = outboundFlow;
|
|
884
|
+
this.broker.publish(
|
|
885
|
+
'run',
|
|
886
|
+
'run.outbound.' + action,
|
|
887
|
+
cloneContent(content, {
|
|
888
|
+
flow: {
|
|
889
|
+
...(result && typeof result === 'object' && result),
|
|
890
|
+
...outboundFlow,
|
|
891
|
+
sequenceId: getUniqueId(`${flowId}_${action}`),
|
|
892
|
+
...(discardSequence && { discardSequence: discardSequence.slice() }),
|
|
893
|
+
},
|
|
894
|
+
}),
|
|
895
|
+
);
|
|
896
|
+
};
|
|
897
|
+
|
|
866
898
|
Activity.prototype._onResumeMessage = function onResumeMessage(message) {
|
|
867
899
|
message.ack();
|
|
868
900
|
|
|
@@ -888,7 +920,7 @@ Activity.prototype._onResumeMessage = function onResumeMessage(message) {
|
|
|
888
920
|
return this.broker.publish('run', fields.routingKey, cloneContent(stateMessage.content), stateMessage.properties);
|
|
889
921
|
};
|
|
890
922
|
|
|
891
|
-
Activity.prototype._publishEvent = function publishEvent(state, content, properties
|
|
923
|
+
Activity.prototype._publishEvent = function publishEvent(state, content, properties) {
|
|
892
924
|
this.broker.publish('event', `activity.${state}`, cloneContent(content, { state }), {
|
|
893
925
|
...properties,
|
|
894
926
|
type: state,
|
|
@@ -943,9 +975,8 @@ Activity.prototype._onApiMessage = function onApiMessage(routingKey, message) {
|
|
|
943
975
|
};
|
|
944
976
|
|
|
945
977
|
Activity.prototype._createMessage = function createMessage(override) {
|
|
946
|
-
const name = this
|
|
947
|
-
|
|
948
|
-
parent = this.parent;
|
|
978
|
+
const { name, status, parent } = this;
|
|
979
|
+
|
|
949
980
|
const result = {
|
|
950
981
|
...override,
|
|
951
982
|
id: this.id,
|
|
@@ -973,128 +1004,3 @@ Activity.prototype._deactivateRunConsumers = function _deactivateRunConsumers()
|
|
|
973
1004
|
broker.cancel('_activity-execution');
|
|
974
1005
|
this[kConsuming] = false;
|
|
975
1006
|
};
|
|
976
|
-
|
|
977
|
-
function OutboundEvaluator(activity, outboundFlows) {
|
|
978
|
-
this.activity = activity;
|
|
979
|
-
this.broker = activity.broker;
|
|
980
|
-
const flows = (this.outboundFlows = outboundFlows.slice());
|
|
981
|
-
const defaultFlowIdx = flows.findIndex(({ isDefault }) => isDefault);
|
|
982
|
-
if (defaultFlowIdx > -1) {
|
|
983
|
-
const [defaultFlow] = flows.splice(defaultFlowIdx, 1);
|
|
984
|
-
flows.push(defaultFlow);
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
this.defaultFlowIdx = outboundFlows.findIndex(({ isDefault }) => isDefault);
|
|
988
|
-
this._onEvaluated = this.onEvaluated.bind(this);
|
|
989
|
-
this.evaluateArgs = {};
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
OutboundEvaluator.prototype.evaluate = function evaluate(fromMessage, discardRestAtTake, callback) {
|
|
993
|
-
const outboundFlows = this.outboundFlows;
|
|
994
|
-
|
|
995
|
-
const args = (this.evaluateArgs = {
|
|
996
|
-
fromMessage,
|
|
997
|
-
evaluationId: fromMessage.content.executionId,
|
|
998
|
-
discardRestAtTake,
|
|
999
|
-
callback,
|
|
1000
|
-
conditionMet: false,
|
|
1001
|
-
result: {},
|
|
1002
|
-
takenCount: 0,
|
|
1003
|
-
});
|
|
1004
|
-
|
|
1005
|
-
if (!outboundFlows.length) return this.completed();
|
|
1006
|
-
|
|
1007
|
-
const flows = (args.flows = outboundFlows.slice());
|
|
1008
|
-
|
|
1009
|
-
this.broker.subscribeTmp('execution', 'evaluate.flow.#', this._onEvaluated, {
|
|
1010
|
-
consumerTag: `_flow-evaluation-${args.evaluationId}`,
|
|
1011
|
-
});
|
|
1012
|
-
|
|
1013
|
-
return this.evaluateFlow(flows.shift());
|
|
1014
|
-
};
|
|
1015
|
-
|
|
1016
|
-
OutboundEvaluator.prototype.onEvaluated = function onEvaluated(routingKey, message) {
|
|
1017
|
-
const content = message.content;
|
|
1018
|
-
const { id: flowId, action, evaluationId } = message.content;
|
|
1019
|
-
const args = this.evaluateArgs;
|
|
1020
|
-
|
|
1021
|
-
if (action === 'take') {
|
|
1022
|
-
args.takenCount++;
|
|
1023
|
-
args.conditionMet = true;
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
args.result[flowId] = content;
|
|
1027
|
-
|
|
1028
|
-
if ('result' in content) {
|
|
1029
|
-
this.activity.logger.debug(`<${evaluationId} (${this.activity.id})> flow <${flowId}> evaluated to: ${!!content.result}`);
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
let nextFlow = args.flows.shift();
|
|
1033
|
-
if (!nextFlow) return this.completed();
|
|
1034
|
-
|
|
1035
|
-
if (args.discardRestAtTake && args.conditionMet) {
|
|
1036
|
-
do {
|
|
1037
|
-
args.result[nextFlow.id] = formatFlowAction(nextFlow, { action: 'discard' });
|
|
1038
|
-
} while ((nextFlow = args.flows.shift()));
|
|
1039
|
-
return this.completed();
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
if (args.conditionMet && nextFlow.isDefault) {
|
|
1043
|
-
args.result[nextFlow.id] = formatFlowAction(nextFlow, { action: 'discard' });
|
|
1044
|
-
return this.completed();
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
message.ack();
|
|
1048
|
-
this.evaluateFlow(nextFlow);
|
|
1049
|
-
};
|
|
1050
|
-
|
|
1051
|
-
OutboundEvaluator.prototype.evaluateFlow = function evaluateFlow(flow) {
|
|
1052
|
-
const broker = this.broker;
|
|
1053
|
-
const { fromMessage, evaluationId } = this.evaluateArgs;
|
|
1054
|
-
flow.evaluate(cloneMessage(fromMessage), (err, result) => {
|
|
1055
|
-
if (err) return this.completed(err);
|
|
1056
|
-
const action = result ? 'take' : 'discard';
|
|
1057
|
-
return broker.publish(
|
|
1058
|
-
'execution',
|
|
1059
|
-
'evaluate.flow.' + action,
|
|
1060
|
-
formatFlowAction(flow, {
|
|
1061
|
-
action,
|
|
1062
|
-
result,
|
|
1063
|
-
evaluationId,
|
|
1064
|
-
}),
|
|
1065
|
-
{ persistent: false },
|
|
1066
|
-
);
|
|
1067
|
-
});
|
|
1068
|
-
};
|
|
1069
|
-
|
|
1070
|
-
OutboundEvaluator.prototype.completed = function completed(err) {
|
|
1071
|
-
const { callback, evaluationId, fromMessage, result, takenCount } = this.evaluateArgs;
|
|
1072
|
-
this.broker.cancel(`_flow-evaluation-${evaluationId}`);
|
|
1073
|
-
|
|
1074
|
-
if (err) return callback(err);
|
|
1075
|
-
|
|
1076
|
-
if (!takenCount && this.outboundFlows.length) {
|
|
1077
|
-
const nonTakenError = new ActivityError(`<${this.activity.id}> no conditional flow taken`, fromMessage);
|
|
1078
|
-
return callback(nonTakenError);
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
const message = fromMessage.content.message;
|
|
1082
|
-
const evaluationResult = [];
|
|
1083
|
-
for (const flow of Object.values(result)) {
|
|
1084
|
-
evaluationResult.push({
|
|
1085
|
-
...flow,
|
|
1086
|
-
...(message !== undefined && { message }),
|
|
1087
|
-
});
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
return callback(null, evaluationResult);
|
|
1091
|
-
};
|
|
1092
|
-
|
|
1093
|
-
function formatFlowAction(flow, options) {
|
|
1094
|
-
return {
|
|
1095
|
-
...options,
|
|
1096
|
-
id: flow.id,
|
|
1097
|
-
action: options.action,
|
|
1098
|
-
...(flow.isDefault && { isDefault: true }),
|
|
1099
|
-
};
|
|
1100
|
-
}
|
|
@@ -32,7 +32,7 @@ Object.defineProperty(ActivityExecution.prototype, 'completed', {
|
|
|
32
32
|
|
|
33
33
|
ActivityExecution.prototype.execute = function execute(executeMessage) {
|
|
34
34
|
if (!executeMessage) throw new Error('Execution requires message');
|
|
35
|
-
const executionId = executeMessage.content
|
|
35
|
+
const executionId = executeMessage.content?.executionId;
|
|
36
36
|
if (!executionId) throw new Error('Execution requires execution id');
|
|
37
37
|
|
|
38
38
|
this.executionId = executionId;
|
|
@@ -347,7 +347,7 @@ ActivityExecution.prototype._onParentApiMessage = function onParentApiMessage(ro
|
|
|
347
347
|
};
|
|
348
348
|
|
|
349
349
|
ActivityExecution.prototype._onStop = function onStop(message) {
|
|
350
|
-
const stoppedId = message
|
|
350
|
+
const stoppedId = message?.content?.executionId;
|
|
351
351
|
const running = this.getPostponed();
|
|
352
352
|
for (const api of running) {
|
|
353
353
|
if (stoppedId !== api.content.executionId) {
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { ActivityError } from '../error/Errors.js';
|
|
2
|
+
import { cloneMessage } from '../messageHelper.js';
|
|
3
|
+
|
|
4
|
+
export function OutboundEvaluator(activity, outboundFlows) {
|
|
5
|
+
this.activity = activity;
|
|
6
|
+
this.broker = activity.broker;
|
|
7
|
+
const flows = (this.outboundFlows = outboundFlows.slice());
|
|
8
|
+
const defaultFlowIdx = flows.findIndex(({ isDefault }) => isDefault);
|
|
9
|
+
if (defaultFlowIdx > -1) {
|
|
10
|
+
const [defaultFlow] = flows.splice(defaultFlowIdx, 1);
|
|
11
|
+
flows.push(defaultFlow);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
this._onEvaluated = this.onEvaluated.bind(this);
|
|
15
|
+
this.evaluateArgs = {};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
OutboundEvaluator.prototype.evaluate = function evaluate(fromMessage, discardRestAtTake, callback) {
|
|
19
|
+
const outboundFlows = this.outboundFlows;
|
|
20
|
+
|
|
21
|
+
const args = (this.evaluateArgs = {
|
|
22
|
+
fromMessage,
|
|
23
|
+
evaluationId: fromMessage.content.executionId,
|
|
24
|
+
discardRestAtTake,
|
|
25
|
+
callback,
|
|
26
|
+
conditionMet: false,
|
|
27
|
+
result: {},
|
|
28
|
+
takenCount: 0,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
if (!outboundFlows.length) return this.completed();
|
|
32
|
+
|
|
33
|
+
const flows = (args.flows = outboundFlows.slice());
|
|
34
|
+
|
|
35
|
+
this.broker.subscribeTmp('execution', 'evaluate.flow.#', this._onEvaluated, {
|
|
36
|
+
consumerTag: `_flow-evaluation-${args.evaluationId}`,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
return this.evaluateFlow(flows.shift());
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
OutboundEvaluator.prototype.onEvaluated = function onEvaluated(routingKey, message) {
|
|
43
|
+
const content = message.content;
|
|
44
|
+
const { id: flowId, action, evaluationId } = message.content;
|
|
45
|
+
const args = this.evaluateArgs;
|
|
46
|
+
|
|
47
|
+
if (action === 'take') {
|
|
48
|
+
args.takenCount++;
|
|
49
|
+
args.conditionMet = true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
args.result[flowId] = content;
|
|
53
|
+
|
|
54
|
+
if ('result' in content) {
|
|
55
|
+
this.activity.logger.debug(`<${evaluationId} (${this.activity.id})> flow <${flowId}> evaluated to: ${!!content.result}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let nextFlow = args.flows.shift();
|
|
59
|
+
if (!nextFlow) return this.completed();
|
|
60
|
+
|
|
61
|
+
if (args.discardRestAtTake && args.conditionMet) {
|
|
62
|
+
do {
|
|
63
|
+
args.result[nextFlow.id] = formatFlowAction(nextFlow, { action: 'discard' });
|
|
64
|
+
} while ((nextFlow = args.flows.shift()));
|
|
65
|
+
return this.completed();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (args.conditionMet && nextFlow.isDefault) {
|
|
69
|
+
args.result[nextFlow.id] = formatFlowAction(nextFlow, { action: 'discard' });
|
|
70
|
+
return this.completed();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
message.ack();
|
|
74
|
+
this.evaluateFlow(nextFlow);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
OutboundEvaluator.prototype.evaluateFlow = function evaluateFlow(flow) {
|
|
78
|
+
const broker = this.broker;
|
|
79
|
+
const { fromMessage, evaluationId } = this.evaluateArgs;
|
|
80
|
+
flow.evaluate(cloneMessage(fromMessage), (err, result) => {
|
|
81
|
+
if (err) return this.completed(err);
|
|
82
|
+
const action = result ? 'take' : 'discard';
|
|
83
|
+
return broker.publish(
|
|
84
|
+
'execution',
|
|
85
|
+
'evaluate.flow.' + action,
|
|
86
|
+
formatFlowAction(flow, {
|
|
87
|
+
action,
|
|
88
|
+
result,
|
|
89
|
+
evaluationId,
|
|
90
|
+
}),
|
|
91
|
+
{ persistent: false },
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
OutboundEvaluator.prototype.completed = function completed(err) {
|
|
97
|
+
const { callback, evaluationId, fromMessage, result, takenCount } = this.evaluateArgs;
|
|
98
|
+
this.broker.cancel(`_flow-evaluation-${evaluationId}`);
|
|
99
|
+
|
|
100
|
+
if (err) return callback(err);
|
|
101
|
+
|
|
102
|
+
if (!takenCount && this.outboundFlows.length) {
|
|
103
|
+
const nonTakenError = new ActivityError(`<${this.activity.id}> no conditional flow taken`, fromMessage);
|
|
104
|
+
return callback(nonTakenError);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const message = fromMessage.content.message;
|
|
108
|
+
const evaluationResult = [];
|
|
109
|
+
for (const flow of Object.values(result)) {
|
|
110
|
+
evaluationResult.push({
|
|
111
|
+
...flow,
|
|
112
|
+
...(message !== undefined && { message }),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return callback(null, evaluationResult);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export function formatFlowAction(flow, options) {
|
|
120
|
+
return {
|
|
121
|
+
...options,
|
|
122
|
+
id: flow.id,
|
|
123
|
+
action: options.action,
|
|
124
|
+
targetId: flow.targetId,
|
|
125
|
+
...(flow.isDefault && { isDefault: true }),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
@@ -98,7 +98,7 @@ Object.defineProperties(Definition.prototype, {
|
|
|
98
98
|
activityStatus: {
|
|
99
99
|
get() {
|
|
100
100
|
const execution = this[kExec].get('execution');
|
|
101
|
-
return
|
|
101
|
+
return execution?.activityStatus || 'idle';
|
|
102
102
|
},
|
|
103
103
|
},
|
|
104
104
|
});
|
|
@@ -160,7 +160,7 @@ Definition.prototype.getState = function getState() {
|
|
|
160
160
|
stopped: this.stopped,
|
|
161
161
|
counters: this.counters,
|
|
162
162
|
environment: this.environment.getState(),
|
|
163
|
-
execution: this.execution
|
|
163
|
+
execution: this.execution?.getState(),
|
|
164
164
|
broker: this.broker.getState(true),
|
|
165
165
|
});
|
|
166
166
|
};
|
|
@@ -289,8 +289,8 @@ Definition.prototype.cancelActivity = function cancelActivity(message) {
|
|
|
289
289
|
Definition.prototype.sendMessage = function sendMessage(message) {
|
|
290
290
|
const messageContent = { message };
|
|
291
291
|
let messageType = 'message';
|
|
292
|
-
const reference = message
|
|
293
|
-
if (reference
|
|
292
|
+
const reference = message?.id && this.getElementById(message.id);
|
|
293
|
+
if (reference?.resolve) {
|
|
294
294
|
const resolvedReference = reference.resolve(this._createMessage({ message }));
|
|
295
295
|
messageType = resolvedReference.messageType || messageType;
|
|
296
296
|
messageContent.message = { ...message, ...resolvedReference };
|
|
@@ -408,7 +408,7 @@ DefinitionExecution.prototype._onProcessMessage = function onProcessMessage(rout
|
|
|
408
408
|
this[kStatus] = 'executing';
|
|
409
409
|
break;
|
|
410
410
|
case 'process.discarded': {
|
|
411
|
-
if (inbound
|
|
411
|
+
if (inbound?.length) {
|
|
412
412
|
const calledFrom = inbound[0];
|
|
413
413
|
this._getProcessApi({ content: calledFrom }).cancel({
|
|
414
414
|
executionId: calledFrom.executionId,
|
|
@@ -417,7 +417,7 @@ DefinitionExecution.prototype._onProcessMessage = function onProcessMessage(rout
|
|
|
417
417
|
break;
|
|
418
418
|
}
|
|
419
419
|
case 'process.end': {
|
|
420
|
-
if (inbound
|
|
420
|
+
if (inbound?.length) {
|
|
421
421
|
const calledFrom = inbound[0];
|
|
422
422
|
|
|
423
423
|
this._getProcessApi({ content: calledFrom }).signal({
|
|
@@ -430,7 +430,7 @@ DefinitionExecution.prototype._onProcessMessage = function onProcessMessage(rout
|
|
|
430
430
|
break;
|
|
431
431
|
}
|
|
432
432
|
case 'process.error': {
|
|
433
|
-
if (inbound
|
|
433
|
+
if (inbound?.length) {
|
|
434
434
|
const calledFrom = inbound[0];
|
|
435
435
|
|
|
436
436
|
this._getProcessApi({ content: calledFrom }).sendApiMessage(
|
|
@@ -478,7 +478,7 @@ DefinitionExecution.prototype._onProcessCompleted = function onProcessCompleted(
|
|
|
478
478
|
message.ack();
|
|
479
479
|
this._debug(`left <${executionId} (${id})> (${type}), pending runs ${this.postponedCount}`);
|
|
480
480
|
|
|
481
|
-
if (inbound
|
|
481
|
+
if (inbound?.length) {
|
|
482
482
|
const bp = this._removeProcessByExecutionId(executionId);
|
|
483
483
|
this._deactivateProcess(bp);
|
|
484
484
|
}
|
|
@@ -651,7 +651,7 @@ DefinitionExecution.prototype._onDelegateMessage = function onDelegateMessage(ro
|
|
|
651
651
|
const delegateMessage = executeMessage.content.message;
|
|
652
652
|
|
|
653
653
|
const reference = this.context.getActivityById(delegateMessage.id);
|
|
654
|
-
const message = reference
|
|
654
|
+
const message = reference?.resolve(executeMessage);
|
|
655
655
|
|
|
656
656
|
this._debug(
|
|
657
657
|
`<${reference ? `${messageType} ${delegateMessage.id}>` : `anonymous ${messageType}`} event received from <${content.parent.id}.${content.id}>. Delegating.`,
|
|
@@ -710,7 +710,7 @@ DefinitionExecution.prototype._complete = function complete(completionType, cont
|
|
|
710
710
|
);
|
|
711
711
|
};
|
|
712
712
|
|
|
713
|
-
DefinitionExecution.prototype._createMessage = function createMessage(content
|
|
713
|
+
DefinitionExecution.prototype._createMessage = function createMessage(content) {
|
|
714
714
|
return {
|
|
715
715
|
id: this.id,
|
|
716
716
|
type: this.type,
|
package/src/error/Errors.js
CHANGED
|
@@ -6,8 +6,7 @@ class ActivityError extends Error {
|
|
|
6
6
|
this.type = 'ActivityError';
|
|
7
7
|
this.name = this.constructor.name;
|
|
8
8
|
this.description = description;
|
|
9
|
-
if (sourceMessage)
|
|
10
|
-
this.source = cloneMessage(sourceMessage, sourceMessage.content && sourceMessage.content.error && { error: undefined });
|
|
9
|
+
if (sourceMessage) this.source = cloneMessage(sourceMessage, sourceMessage.content?.error && { error: undefined });
|
|
11
10
|
if (inner) {
|
|
12
11
|
this.inner = inner;
|
|
13
12
|
if (inner.name) this.name = inner.name;
|
|
@@ -24,17 +23,14 @@ class RunError extends ActivityError {
|
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
class BpmnError extends Error {
|
|
27
|
-
constructor(description, behaviour
|
|
28
|
-
const { errorCode } = behaviour;
|
|
29
|
-
|
|
26
|
+
constructor(description, behaviour, sourceMessage, inner) {
|
|
30
27
|
super(description);
|
|
31
28
|
this.type = 'BpmnError';
|
|
32
|
-
this.name = behaviour
|
|
29
|
+
this.name = behaviour?.name ?? this.constructor.name;
|
|
33
30
|
this.description = description;
|
|
34
|
-
this.code =
|
|
35
|
-
this.id = behaviour
|
|
36
|
-
if (sourceMessage)
|
|
37
|
-
this.source = cloneMessage(sourceMessage, sourceMessage.content && sourceMessage.content.error && { error: undefined });
|
|
31
|
+
this.code = behaviour?.errorCode?.toString() ?? behaviour?.code;
|
|
32
|
+
this.id = behaviour?.id;
|
|
33
|
+
if (sourceMessage) this.source = cloneMessage(sourceMessage, sourceMessage.content?.error && { error: undefined });
|
|
38
34
|
if (inner) this.inner = inner;
|
|
39
35
|
}
|
|
40
36
|
}
|
|
@@ -47,7 +43,7 @@ function makeErrorFromMessage(errorMessage) {
|
|
|
47
43
|
if (isKnownError(content)) return content;
|
|
48
44
|
|
|
49
45
|
const { error } = content;
|
|
50
|
-
if (!error) return new Error(`Malformatted error message with routing key ${errorMessage.fields
|
|
46
|
+
if (!error) return new Error(`Malformatted error message with routing key ${errorMessage.fields?.routingKey}`);
|
|
51
47
|
|
|
52
48
|
if (isKnownError(error)) return error;
|
|
53
49
|
|