bpmn-elements 16.2.1 → 17.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 (39) hide show
  1. package/dist/MessageFormatter.js +47 -47
  2. package/dist/activity/Activity.js +14 -9
  3. package/dist/getPropertyValue.js +1 -2
  4. package/dist/tasks/CallActivity.js +7 -2
  5. package/package.json +6 -6
  6. package/src/Api.js +6 -8
  7. package/src/EventBroker.js +5 -7
  8. package/src/MessageFormatter.js +48 -54
  9. package/src/activity/Activity.js +16 -15
  10. package/src/activity/ActivityExecution.js +2 -2
  11. package/src/activity/outbound-evaluator.js +1 -1
  12. package/src/definition/Definition.js +2 -2
  13. package/src/definition/DefinitionExecution.js +7 -7
  14. package/src/error/Errors.js +6 -8
  15. package/src/eventDefinitions/CancelEventDefinition.js +1 -1
  16. package/src/eventDefinitions/CompensateEventDefinition.js +1 -1
  17. package/src/eventDefinitions/ConditionalEventDefinition.js +2 -2
  18. package/src/eventDefinitions/ErrorEventDefinition.js +3 -3
  19. package/src/eventDefinitions/LinkEventDefinition.js +1 -1
  20. package/src/eventDefinitions/MessageEventDefinition.js +2 -2
  21. package/src/eventDefinitions/SignalEventDefinition.js +2 -2
  22. package/src/eventDefinitions/TimerEventDefinition.js +2 -2
  23. package/src/events/BoundaryEvent.js +6 -6
  24. package/src/events/IntermediateCatchEvent.js +1 -1
  25. package/src/events/StartEvent.js +2 -2
  26. package/src/flows/MessageFlow.js +1 -1
  27. package/src/getPropertyValue.js +1 -3
  28. package/src/io/InputOutputSpecification.js +2 -2
  29. package/src/io/Properties.js +4 -4
  30. package/src/messageHelper.js +6 -8
  31. package/src/process/Process.js +1 -1
  32. package/src/process/ProcessExecution.js +8 -8
  33. package/src/tasks/CallActivity.js +18 -14
  34. package/src/tasks/LoopCharacteristics.js +1 -1
  35. package/src/tasks/ReceiveTask.js +2 -2
  36. package/src/tasks/ScriptTask.js +2 -2
  37. package/src/tasks/ServiceTask.js +1 -1
  38. package/src/tasks/SignalTask.js +4 -4
  39. package/types/types.d.ts +9 -1
@@ -10,7 +10,13 @@ var _Errors = require("./error/Errors.js");
10
10
  var _smqp = require("smqp");
11
11
  const kOnMessage = Symbol.for('onMessage');
12
12
  const kExecution = Symbol.for('execution');
13
- function Formatter(element, formatQ) {
13
+ const EXEC_ROUTING_KEY = 'run._formatting.exec';
14
+
15
+ /**
16
+ * Message formatter used to enrich an element run message before continuing to the next run message
17
+ * @param {import('types').ElementBase} element
18
+ */
19
+ function Formatter(element) {
14
20
  const {
15
21
  id,
16
22
  broker,
@@ -19,16 +25,19 @@ function Formatter(element, formatQ) {
19
25
  this.id = id;
20
26
  this.broker = broker;
21
27
  this.logger = logger;
22
- this.formatQ = formatQ;
23
28
  this[kOnMessage] = this._onMessage.bind(this);
24
29
  }
30
+
31
+ /**
32
+ * Format message
33
+ * @param {import('types').ElementBrokerMessage} message
34
+ * @param {CallableFunction} callback
35
+ */
25
36
  Formatter.prototype.format = function format(message, callback) {
26
37
  const correlationId = this._runId = (0, _shared.getUniqueId)(message.fields.routingKey);
27
38
  const consumerTag = '_formatter-' + correlationId;
28
- const formatQ = this.formatQ;
29
- formatQ.queueMessage({
30
- routingKey: '_formatting.exec'
31
- }, {}, {
39
+ const broker = this.broker;
40
+ broker.publish('format', EXEC_ROUTING_KEY, {}, {
32
41
  correlationId,
33
42
  persistent: false
34
43
  });
@@ -37,11 +46,11 @@ Formatter.prototype.format = function format(message, callback) {
37
46
  formatKey: message.fields.routingKey,
38
47
  runMessage: (0, _messageHelper.cloneMessage)(message),
39
48
  callback,
40
- pending: [],
49
+ pending: new Set(),
41
50
  formatted: false,
42
51
  executeMessage: null
43
52
  };
44
- formatQ.consume(this[kOnMessage], {
53
+ broker.consume('format-run-q', this[kOnMessage], {
45
54
  consumerTag,
46
55
  prefetch: 100
47
56
  });
@@ -53,41 +62,33 @@ Formatter.prototype._onMessage = function onMessage(routingKey, message) {
53
62
  pending,
54
63
  executeMessage
55
64
  } = this[kExecution];
56
- const asyncFormatting = pending.length;
57
- switch (routingKey) {
58
- case '_formatting.exec':
59
- if (message.properties.correlationId !== correlationId) return message.ack();
60
- if (!asyncFormatting) {
61
- message.ack();
62
- return this._complete(message);
63
- }
64
- this[kExecution].executeMessage = message;
65
- break;
66
- default:
67
- {
68
- message.ack();
69
- const endRoutingKey = message.content?.endRoutingKey;
70
- if (endRoutingKey) {
71
- this._decorate(message.content);
72
- pending.push(message);
73
- return this._debug(`start formatting ${formatKey} message content with formatter ${routingKey}`);
74
- }
75
- if (asyncFormatting) {
76
- const {
77
- isError,
78
- message: startMessage
79
- } = this._popFormatStart(pending, routingKey);
80
- if (startMessage) startMessage.ack();
81
- if (isError) {
82
- return this._complete(message, true);
83
- }
84
- }
85
- this._decorate(message.content);
86
- this._debug(`format ${message.fields.routingKey} message content with formatter ${routingKey}`);
87
- if (executeMessage && asyncFormatting && !pending.length) {
88
- this._complete(message);
89
- }
65
+ const asyncFormatting = pending.size;
66
+ if (routingKey === EXEC_ROUTING_KEY) {
67
+ if (message.properties.correlationId !== correlationId) return message.ack();
68
+ message.ack();
69
+ if (!asyncFormatting) {
70
+ return this._complete(message);
71
+ }
72
+ this[kExecution].executeMessage = message;
73
+ } else {
74
+ message.ack();
75
+ const endRoutingKey = message.content?.endRoutingKey;
76
+ if (endRoutingKey) {
77
+ this._enrich(message.content);
78
+ pending.add(message);
79
+ return this._debug(`start formatting ${formatKey} message content with formatter ${routingKey}`);
80
+ }
81
+ if (asyncFormatting) {
82
+ const isError = this._popFormatStart(pending, routingKey).isError;
83
+ if (isError) {
84
+ return this._complete(message, true);
90
85
  }
86
+ }
87
+ this._enrich(message.content);
88
+ this._debug(`format ${message.fields.routingKey} message content with formatter ${routingKey}`);
89
+ if (executeMessage && !pending.size) {
90
+ this._complete(message);
91
+ }
91
92
  }
92
93
  };
93
94
  Formatter.prototype._complete = function complete(message, isError) {
@@ -109,7 +110,7 @@ Formatter.prototype._complete = function complete(message, isError) {
109
110
  }
110
111
  return callback(null, runMessage.content, formatted);
111
112
  };
112
- Formatter.prototype._decorate = function decorate(withContent) {
113
+ Formatter.prototype._enrich = function enrich(withContent) {
113
114
  const content = this[kExecution].runMessage.content;
114
115
  for (const key in withContent) {
115
116
  switch (key) {
@@ -134,20 +135,19 @@ Formatter.prototype._decorate = function decorate(withContent) {
134
135
  }
135
136
  };
136
137
  Formatter.prototype._popFormatStart = function popFormattingStart(pending, routingKey) {
137
- for (let idx = 0; idx < pending.length; idx++) {
138
- const msg = pending[idx];
138
+ for (const msg of pending) {
139
139
  const {
140
140
  endRoutingKey,
141
141
  errorRoutingKey = '#.error'
142
142
  } = msg.content;
143
143
  if (endRoutingKey && (0, _smqp.getRoutingKeyPattern)(endRoutingKey).test(routingKey)) {
144
144
  this._debug(`completed formatting ${msg.fields.routingKey} message content with formatter ${routingKey}`);
145
- pending.splice(idx, 1);
145
+ pending.delete(msg);
146
146
  return {
147
147
  message: msg
148
148
  };
149
149
  } else if ((0, _smqp.getRoutingKeyPattern)(errorRoutingKey).test(routingKey)) {
150
- pending.splice(idx, 1);
150
+ pending.delete(msg);
151
151
  return {
152
152
  isError: true,
153
153
  message: msg
@@ -156,12 +156,7 @@ Object.defineProperties(Activity.prototype, {
156
156
  get() {
157
157
  let formatter = this[kFormatter];
158
158
  if (formatter) return formatter;
159
- const broker = this.broker;
160
- formatter = this[kFormatter] = new _MessageFormatter.Formatter({
161
- id: this.id,
162
- broker,
163
- logger: this.logger
164
- }, broker.getQueue('format-run-q'));
159
+ formatter = this[kFormatter] = new _MessageFormatter.Formatter(this);
165
160
  return formatter;
166
161
  }
167
162
  },
@@ -430,7 +425,13 @@ Activity.prototype._discardRun = function discardRun() {
430
425
  if (!status) return;
431
426
  const execution = this[kExec].get('execution');
432
427
  if (execution && !execution.completed) return;
428
+ let discardRoutingKey = 'run.discard';
433
429
  switch (status) {
430
+ case 'executed':
431
+ {
432
+ discardRoutingKey = 'run.discarded';
433
+ break;
434
+ }
434
435
  case 'end':
435
436
  case 'executing':
436
437
  case 'error':
@@ -442,7 +443,9 @@ Activity.prototype._discardRun = function discardRun() {
442
443
  if (this.extensions) this.extensions.deactivate((0, _messageHelper.cloneMessage)(stateMessage));
443
444
  const broker = this.broker;
444
445
  broker.getQueue('run-q').purge();
445
- broker.publish('run', 'run.discard', (0, _messageHelper.cloneContent)(stateMessage.content));
446
+ broker.publish('run', discardRoutingKey, (0, _messageHelper.cloneContent)(stateMessage.content), {
447
+ correlationId: stateMessage.properties.correlationId
448
+ });
446
449
  this[kConsuming] = true;
447
450
  this._consumeRunQ();
448
451
  };
@@ -609,9 +612,11 @@ Activity.prototype._onRunMessage = function onRunMessage(routingKey, message, me
609
612
  const preStatus = this.status;
610
613
  this.status = 'formatting';
611
614
  return this.formatter.format(message, (err, formattedContent, formatted) => {
612
- if (err) return this.emitFatal(err, message.content);
613
- if (formatted) message.content = formattedContent;
614
615
  this.status = preStatus;
616
+ if (err) {
617
+ return this.emitFatal(err, message.content);
618
+ }
619
+ if (formatted) message.content = formattedContent;
615
620
  this._continueRunMessage(routingKey, message, messageProperties);
616
621
  });
617
622
  };
@@ -3,12 +3,11 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.default = getPropertyValue;
7
7
  const propertyPattern = /(\w+)\((.*?)(?:\))|(\.|\[|^)(.+?)(?:\]|\[|\.|$)/;
8
8
  const stringConstantPattern = /^(['"])(.*)\1$/;
9
9
  const numberConstantPattern = /^\W*-?\d+(.\d+)?\W*$/;
10
10
  const negativeIndexPattern = /^-\d+$/;
11
- var _default = exports.default = getPropertyValue;
12
11
  function getPropertyValue(inputContext, propertyPath, fnScope) {
13
12
  if (!inputContext) return;
14
13
  let resultValue;
@@ -52,7 +52,11 @@ CallActivityBehaviour.prototype.execute = function execute(executeMessage) {
52
52
  });
53
53
  broker.subscribeTmp('api', '#.signal.*', (...args) => this._onDelegatedApiMessage(calledElement, executeMessage, ...args), {
54
54
  noAck: true,
55
- consumerTag: `_api-delegated-${executionId}`
55
+ consumerTag: `_api-delegated-signal-${executionId}`
56
+ });
57
+ broker.subscribeTmp('api', '#.cancel.*', (...args) => this._onDelegatedApiMessage(calledElement, executeMessage, ...args), {
58
+ noAck: true,
59
+ consumerTag: `_api-delegated-cancel-${executionId}`
56
60
  });
57
61
  broker.publish('event', 'activity.call', (0, _messageHelper.cloneContent)(executeContent, {
58
62
  state: 'wait',
@@ -134,5 +138,6 @@ CallActivityBehaviour.prototype._onApiMessage = function onApiMessage(calledElem
134
138
  CallActivityBehaviour.prototype._stop = function stop(executionId) {
135
139
  const broker = this.broker;
136
140
  broker.cancel(`_api-${executionId}`);
137
- broker.cancel(`_api-delegated-${executionId}`);
141
+ broker.cancel(`_api-delegated-signal-${executionId}`);
142
+ broker.cancel(`_api-delegated-cancel-${executionId}`);
138
143
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bpmn-elements",
3
- "version": "16.2.1",
3
+ "version": "17.0.0",
4
4
  "description": "Executable workflow elements based on BPMN 2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -85,7 +85,7 @@
85
85
  "@babel/preset-env": "^7.24.4",
86
86
  "@babel/register": "^7.23.7",
87
87
  "@bonniernews/hot-bev": "^0.4.0",
88
- "@types/node": "^16.18.95",
88
+ "@types/node": "^18.19.63",
89
89
  "bpmn-moddle": "^9.0.1",
90
90
  "c8": "^10.1.1",
91
91
  "camunda-bpmn-moddle": "^7.0.1",
@@ -95,15 +95,15 @@
95
95
  "eslint": "^9.0.0",
96
96
  "globals": "^15.0.0",
97
97
  "got": "^14.2.1",
98
- "mocha": "^10.4.0",
98
+ "mocha": "^11.0.1",
99
99
  "mocha-cakes-2": "^3.3.0",
100
100
  "moddle-context-serializer": "^4.2.1",
101
- "nock": "^13.5.3",
101
+ "nock": "^14.0.0",
102
102
  "prettier": "^3.2.5",
103
103
  "texample": "^0.0.6"
104
104
  },
105
105
  "dependencies": {
106
- "@0dep/piso": "^2.2.0",
107
- "smqp": "^9.0.2"
106
+ "@0dep/piso": "^2.4.0",
107
+ "smqp": "^9.0.6"
108
108
  }
109
109
  }
package/src/Api.js CHANGED
@@ -1,25 +1,23 @@
1
1
  import { cloneMessage } from './messageHelper.js';
2
2
  import { getUniqueId } from './shared.js';
3
3
 
4
- export { ActivityApi, DefinitionApi, ProcessApi, FlowApi, Api };
5
-
6
- function ActivityApi(broker, apiMessage, environment) {
4
+ export function ActivityApi(broker, apiMessage, environment) {
7
5
  return new Api('activity', broker, apiMessage, environment);
8
6
  }
9
7
 
10
- function DefinitionApi(broker, apiMessage, environment) {
8
+ export function DefinitionApi(broker, apiMessage, environment) {
11
9
  return new Api('definition', broker, apiMessage, environment);
12
10
  }
13
11
 
14
- function ProcessApi(broker, apiMessage, environment) {
12
+ export function ProcessApi(broker, apiMessage, environment) {
15
13
  return new Api('process', broker, apiMessage, environment);
16
14
  }
17
15
 
18
- function FlowApi(broker, apiMessage, environment) {
16
+ export function FlowApi(broker, apiMessage, environment) {
19
17
  return new Api('flow', broker, apiMessage, environment);
20
18
  }
21
19
 
22
- function Api(pfx, broker, sourceMessage, environment) {
20
+ export function Api(pfx, broker, sourceMessage, environment) {
23
21
  if (!sourceMessage) throw new Error('Api requires message');
24
22
 
25
23
  const apiMessage = cloneMessage(sourceMessage);
@@ -66,7 +64,7 @@ Api.prototype.resolveExpression = function resolveExpression(expression) {
66
64
  content: this.content,
67
65
  properties: this.messageProperties,
68
66
  },
69
- this.owner,
67
+ this.owner
70
68
  );
71
69
  };
72
70
 
@@ -1,25 +1,23 @@
1
1
  import { Broker } from 'smqp';
2
2
  import { makeErrorFromMessage } from './error/Errors.js';
3
3
 
4
- export { ActivityBroker, DefinitionBroker, MessageFlowBroker, ProcessBroker, EventBroker };
5
-
6
- function ActivityBroker(activity) {
4
+ export function ActivityBroker(activity) {
7
5
  const executionBroker = ExecutionBroker(activity, 'activity');
8
6
  return executionBroker;
9
7
  }
10
8
 
11
- function ProcessBroker(owner) {
9
+ export function ProcessBroker(owner) {
12
10
  const executionBroker = ExecutionBroker(owner, 'process');
13
11
  executionBroker.broker.assertQueue('api-q', { durable: false, autoDelete: false });
14
12
  executionBroker.broker.bindQueue('api-q', 'api', '#');
15
13
  return executionBroker;
16
14
  }
17
15
 
18
- function DefinitionBroker(owner, onBrokerReturn) {
16
+ export function DefinitionBroker(owner, onBrokerReturn) {
19
17
  return ExecutionBroker(owner, 'definition', onBrokerReturn);
20
18
  }
21
19
 
22
- function MessageFlowBroker(owner) {
20
+ export function MessageFlowBroker(owner) {
23
21
  const eventBroker = new EventBroker(owner, { prefix: 'messageflow', autoDelete: false, durable: false });
24
22
  const broker = eventBroker.broker;
25
23
 
@@ -51,7 +49,7 @@ function ExecutionBroker(brokerOwner, prefix, onBrokerReturn) {
51
49
  return eventBroker;
52
50
  }
53
51
 
54
- function EventBroker(brokerOwner, options, onBrokerReturn) {
52
+ export function EventBroker(brokerOwner, options, onBrokerReturn) {
55
53
  this.options = options;
56
54
  this.eventPrefix = options.prefix;
57
55
 
@@ -6,44 +6,43 @@ import { getRoutingKeyPattern } from 'smqp';
6
6
  const kOnMessage = Symbol.for('onMessage');
7
7
  const kExecution = Symbol.for('execution');
8
8
 
9
- export { Formatter };
9
+ const EXEC_ROUTING_KEY = 'run._formatting.exec';
10
10
 
11
- function Formatter(element, formatQ) {
11
+ /**
12
+ * Message formatter used to enrich an element run message before continuing to the next run message
13
+ * @param {import('types').ElementBase} element
14
+ */
15
+ export function Formatter(element) {
12
16
  const { id, broker, logger } = element;
13
17
  this.id = id;
14
18
  this.broker = broker;
15
19
  this.logger = logger;
16
- this.formatQ = formatQ;
17
20
  this[kOnMessage] = this._onMessage.bind(this);
18
21
  }
19
22
 
23
+ /**
24
+ * Format message
25
+ * @param {import('types').ElementBrokerMessage} message
26
+ * @param {CallableFunction} callback
27
+ */
20
28
  Formatter.prototype.format = function format(message, callback) {
21
29
  const correlationId = (this._runId = getUniqueId(message.fields.routingKey));
22
30
  const consumerTag = '_formatter-' + correlationId;
23
- const formatQ = this.formatQ;
24
-
25
- formatQ.queueMessage(
26
- {
27
- routingKey: '_formatting.exec',
28
- },
29
- {},
30
- {
31
- correlationId,
32
- persistent: false,
33
- },
34
- );
31
+ const broker = this.broker;
32
+
33
+ broker.publish('format', EXEC_ROUTING_KEY, {}, { correlationId, persistent: false });
35
34
 
36
35
  this[kExecution] = {
37
36
  correlationId,
38
37
  formatKey: message.fields.routingKey,
39
38
  runMessage: cloneMessage(message),
40
39
  callback,
41
- pending: [],
40
+ pending: new Set(),
42
41
  formatted: false,
43
42
  executeMessage: null,
44
43
  };
45
44
 
46
- formatQ.consume(this[kOnMessage], {
45
+ broker.consume('format-run-q', this[kOnMessage], {
47
46
  consumerTag,
48
47
  prefetch: 100,
49
48
  });
@@ -51,43 +50,40 @@ Formatter.prototype.format = function format(message, callback) {
51
50
 
52
51
  Formatter.prototype._onMessage = function onMessage(routingKey, message) {
53
52
  const { formatKey, correlationId, pending, executeMessage } = this[kExecution];
54
- const asyncFormatting = pending.length;
55
-
56
- switch (routingKey) {
57
- case '_formatting.exec':
58
- if (message.properties.correlationId !== correlationId) return message.ack();
59
- if (!asyncFormatting) {
60
- message.ack();
61
- return this._complete(message);
62
- }
63
- this[kExecution].executeMessage = message;
64
- break;
65
- default: {
66
- message.ack();
67
-
68
- const endRoutingKey = message.content?.endRoutingKey;
69
- if (endRoutingKey) {
70
- this._decorate(message.content);
71
- pending.push(message);
72
- return this._debug(`start formatting ${formatKey} message content with formatter ${routingKey}`);
73
- }
53
+ const asyncFormatting = pending.size;
74
54
 
75
- if (asyncFormatting) {
76
- const { isError, message: startMessage } = this._popFormatStart(pending, routingKey);
77
- if (startMessage) startMessage.ack();
55
+ if (routingKey === EXEC_ROUTING_KEY) {
56
+ if (message.properties.correlationId !== correlationId) return message.ack();
57
+ message.ack();
58
+ if (!asyncFormatting) {
59
+ return this._complete(message);
60
+ }
61
+ this[kExecution].executeMessage = message;
62
+ } else {
63
+ message.ack();
78
64
 
79
- if (isError) {
80
- return this._complete(message, true);
81
- }
82
- }
65
+ const endRoutingKey = message.content?.endRoutingKey;
83
66
 
84
- this._decorate(message.content);
85
- this._debug(`format ${message.fields.routingKey} message content with formatter ${routingKey}`);
67
+ if (endRoutingKey) {
68
+ this._enrich(message.content);
69
+ pending.add(message);
70
+ return this._debug(`start formatting ${formatKey} message content with formatter ${routingKey}`);
71
+ }
86
72
 
87
- if (executeMessage && asyncFormatting && !pending.length) {
88
- this._complete(message);
73
+ if (asyncFormatting) {
74
+ const isError = this._popFormatStart(pending, routingKey).isError;
75
+
76
+ if (isError) {
77
+ return this._complete(message, true);
89
78
  }
90
79
  }
80
+
81
+ this._enrich(message.content);
82
+ this._debug(`format ${message.fields.routingKey} message content with formatter ${routingKey}`);
83
+
84
+ if (executeMessage && !pending.size) {
85
+ this._complete(message);
86
+ }
91
87
  }
92
88
  };
93
89
 
@@ -108,7 +104,7 @@ Formatter.prototype._complete = function complete(message, isError) {
108
104
  return callback(null, runMessage.content, formatted);
109
105
  };
110
106
 
111
- Formatter.prototype._decorate = function decorate(withContent) {
107
+ Formatter.prototype._enrich = function enrich(withContent) {
112
108
  const content = this[kExecution].runMessage.content;
113
109
  for (const key in withContent) {
114
110
  switch (key) {
@@ -133,16 +129,14 @@ Formatter.prototype._decorate = function decorate(withContent) {
133
129
  };
134
130
 
135
131
  Formatter.prototype._popFormatStart = function popFormattingStart(pending, routingKey) {
136
- for (let idx = 0; idx < pending.length; idx++) {
137
- const msg = pending[idx];
132
+ for (const msg of pending) {
138
133
  const { endRoutingKey, errorRoutingKey = '#.error' } = msg.content;
139
-
140
134
  if (endRoutingKey && getRoutingKeyPattern(endRoutingKey).test(routingKey)) {
141
135
  this._debug(`completed formatting ${msg.fields.routingKey} message content with formatter ${routingKey}`);
142
- pending.splice(idx, 1);
136
+ pending.delete(msg);
143
137
  return { message: msg };
144
138
  } else if (getRoutingKeyPattern(errorRoutingKey).test(routingKey)) {
145
- pending.splice(idx, 1);
139
+ pending.delete(msg);
146
140
  return { isError: true, message: msg };
147
141
  }
148
142
  }
@@ -143,15 +143,7 @@ Object.defineProperties(Activity.prototype, {
143
143
  let formatter = this[kFormatter];
144
144
  if (formatter) return formatter;
145
145
 
146
- const broker = this.broker;
147
- formatter = this[kFormatter] = new Formatter(
148
- {
149
- id: this.id,
150
- broker,
151
- logger: this.logger,
152
- },
153
- broker.getQueue('format-run-q'),
154
- );
146
+ formatter = this[kFormatter] = new Formatter(this);
155
147
  return formatter;
156
148
  },
157
149
  },
@@ -430,7 +422,12 @@ Activity.prototype._discardRun = function discardRun() {
430
422
  const execution = this[kExec].get('execution');
431
423
  if (execution && !execution.completed) return;
432
424
 
425
+ let discardRoutingKey = 'run.discard';
433
426
  switch (status) {
427
+ case 'executed': {
428
+ discardRoutingKey = 'run.discarded';
429
+ break;
430
+ }
434
431
  case 'end':
435
432
  case 'executing':
436
433
  case 'error':
@@ -442,10 +439,11 @@ Activity.prototype._discardRun = function discardRun() {
442
439
 
443
440
  const stateMessage = this[kStateMessage];
444
441
  if (this.extensions) this.extensions.deactivate(cloneMessage(stateMessage));
442
+
445
443
  const broker = this.broker;
446
444
  broker.getQueue('run-q').purge();
447
445
 
448
- broker.publish('run', 'run.discard', cloneContent(stateMessage.content));
446
+ broker.publish('run', discardRoutingKey, cloneContent(stateMessage.content), { correlationId: stateMessage.properties.correlationId });
449
447
  this[kConsuming] = true;
450
448
  this._consumeRunQ();
451
449
  };
@@ -602,10 +600,13 @@ Activity.prototype._onRunMessage = function onRunMessage(routingKey, message, me
602
600
 
603
601
  const preStatus = this.status;
604
602
  this.status = 'formatting';
603
+
605
604
  return this.formatter.format(message, (err, formattedContent, formatted) => {
606
- if (err) return this.emitFatal(err, message.content);
607
- if (formatted) message.content = formattedContent;
608
605
  this.status = preStatus;
606
+ if (err) {
607
+ return this.emitFatal(err, message.content);
608
+ }
609
+ if (formatted) message.content = formattedContent;
609
610
  this._continueRunMessage(routingKey, message, messageProperties);
610
611
  });
611
612
  };
@@ -700,7 +701,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
700
701
  ...content,
701
702
  error: isRedelivered ? makeErrorFromMessage(message) : content.error,
702
703
  },
703
- { correlationId },
704
+ { correlationId }
704
705
  );
705
706
  break;
706
707
  }
@@ -819,7 +820,7 @@ Activity.prototype._doRunLeave = function doRunLeave(message, isDiscarded, onOut
819
820
  cloneContent(content, {
820
821
  ...(outbound.length && { outbound }),
821
822
  }),
822
- { correlationId },
823
+ { correlationId }
823
824
  );
824
825
 
825
826
  onOutbound();
@@ -891,7 +892,7 @@ Activity.prototype._publishRunOutbound = function publishRunOutbound(outboundFlo
891
892
  sequenceId: getUniqueId(`${flowId}_${action}`),
892
893
  ...(discardSequence && { discardSequence: discardSequence.slice() }),
893
894
  },
894
- }),
895
+ })
895
896
  );
896
897
  };
897
898
 
@@ -306,7 +306,7 @@ ActivityExecution.prototype._onExecutionDiscarded = function onExecutionDiscarde
306
306
  ActivityExecution.prototype._publishExecutionCompleted = function publishExecutionCompleted(
307
307
  completionType,
308
308
  completeContent,
309
- correlationId,
309
+ correlationId
310
310
  ) {
311
311
  this[kCompleted] = true;
312
312
 
@@ -317,7 +317,7 @@ ActivityExecution.prototype._publishExecutionCompleted = function publishExecuti
317
317
  ...completeContent,
318
318
  state: completionType,
319
319
  },
320
- { type: completionType, correlationId },
320
+ { type: completionType, correlationId }
321
321
  );
322
322
  };
323
323
 
@@ -88,7 +88,7 @@ OutboundEvaluator.prototype.evaluateFlow = function evaluateFlow(flow) {
88
88
  result,
89
89
  evaluationId,
90
90
  }),
91
- { persistent: false },
91
+ { persistent: false }
92
92
  );
93
93
  });
94
94
  };
@@ -219,7 +219,7 @@ Definition.prototype._shakeProcess = function shakeProcess(shakeBp, startId) {
219
219
  {
220
220
  broker: this.broker,
221
221
  exchange: 'event',
222
- },
222
+ }
223
223
  );
224
224
  }
225
225
 
@@ -404,7 +404,7 @@ Definition.prototype._onRunMessage = function onRunMessage(routingKey, message)
404
404
  ...content,
405
405
  error: fields.redelivered ? makeErrorFromMessage(message) : content.error,
406
406
  },
407
- { mandatory: true },
407
+ { mandatory: true }
408
408
  );
409
409
  break;
410
410
  }