bpmn-elements 10.0.0 → 10.1.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 CHANGED
@@ -1,6 +1,13 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ # 10.1.0
5
+
6
+ - introduce Lane behaviour
7
+ - add process `lanes` property with Lane instances
8
+ - add activity `lane` property containing a reference to the process lane instance
9
+ - add activity `parentElement` property referencing parent process or sub process
10
+
4
11
  # 10.0.0
5
12
 
6
13
  - drop iso8601-duration dependency and copy source (with licence). Export as `ISODuration`. Extend with repeat pattern parsing, e.g. `R3/PT1H` that corresponds to three repetitions every one hour
package/dist/Context.js CHANGED
@@ -9,11 +9,12 @@ var _Environment = _interopRequireDefault(require("./Environment.js"));
9
9
  var _ExtensionsMapper = _interopRequireDefault(require("./ExtensionsMapper.js"));
10
10
  var _shared = require("./shared.js");
11
11
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
+ const kOwner = Symbol.for('owner');
12
13
  function Context(definitionContext, environment) {
13
14
  environment = environment ? environment.clone() : new _Environment.default();
14
15
  return new ContextInstance(definitionContext, environment);
15
16
  }
16
- function ContextInstance(definitionContext, environment) {
17
+ function ContextInstance(definitionContext, environment, owner) {
17
18
  const {
18
19
  id = 'Def',
19
20
  name,
@@ -38,7 +39,13 @@ function ContextInstance(definitionContext, environment) {
38
39
  sequenceFlowRefs: {},
39
40
  sequenceFlows: []
40
41
  };
42
+ this[kOwner] = owner;
41
43
  }
44
+ Object.defineProperty(ContextInstance.prototype, 'owner', {
45
+ get() {
46
+ return this[kOwner];
47
+ }
48
+ });
42
49
  ContextInstance.prototype.getActivityById = function getActivityById(activityId) {
43
50
  const activityInstance = this.refs.activityRefs[activityId];
44
51
  if (activityInstance) return activityInstance;
@@ -95,8 +102,8 @@ ContextInstance.prototype.upsertAssociation = function upsertAssociation(associa
95
102
  instance = refs[associationDefinition.id] = new associationDefinition.Behaviour(associationDefinition, this);
96
103
  return instance;
97
104
  };
98
- ContextInstance.prototype.clone = function clone(newEnvironment) {
99
- return new ContextInstance(this.definitionContext, newEnvironment || this.environment);
105
+ ContextInstance.prototype.clone = function clone(newEnvironment, newOwner) {
106
+ return new ContextInstance(this.definitionContext, newEnvironment || this.environment, newOwner);
100
107
  };
101
108
  ContextInstance.prototype.getProcessById = function getProcessById(processId) {
102
109
  const refs = this.refs.processRefs;
@@ -106,13 +113,16 @@ ContextInstance.prototype.getProcessById = function getProcessById(processId) {
106
113
  if (!processDefinition) return null;
107
114
  const bpContext = this.clone(this.environment.clone());
108
115
  bp = refs[processId] = new processDefinition.Behaviour(processDefinition, bpContext);
116
+ bpContext[kOwner] = bp;
109
117
  this.refs.processes.push(bp);
110
118
  return bp;
111
119
  };
112
120
  ContextInstance.prototype.getNewProcessById = function getNewProcessById(processId) {
113
121
  if (!this.getProcessById(processId)) return null;
114
122
  const bpDef = this.definitionContext.getProcessById(processId);
115
- const bp = new bpDef.Behaviour(bpDef, this.clone(this.environment.clone()));
123
+ const bpContext = this.clone(this.environment.clone());
124
+ const bp = new bpDef.Behaviour(bpDef, bpContext);
125
+ bpContext[kOwner] = bp;
116
126
  return bp;
117
127
  };
118
128
  ContextInstance.prototype.getProcesses = function getProcesses() {
@@ -175,4 +185,11 @@ ContextInstance.prototype.loadExtensions = function loadExtensions(activity) {
175
185
  if (io.hasIo) extensions.extensions.push(io);
176
186
  if (!extensions.extensions.length) return;
177
187
  return extensions;
188
+ };
189
+ ContextInstance.prototype.getActivityParentById = function getActivityParentById(activityId) {
190
+ const owner = this[kOwner];
191
+ if (owner) return owner;
192
+ const activity = this.getActivityById(activityId);
193
+ const parentId = activity.parent.id;
194
+ return this.getProcessById(parentId) || this.getActivityById(parentId);
178
195
  };
@@ -102,7 +102,8 @@ function Activity(Behaviour, activityDef, context) {
102
102
  attachedTo,
103
103
  isTransaction: activityDef.isTransaction,
104
104
  isParallelJoin,
105
- isThrowing: activityDef.isThrowing
105
+ isThrowing: activityDef.isThrowing,
106
+ lane: activityDef.lane && activityDef.lane.id
106
107
  };
107
108
  this[kExec] = {};
108
109
  this[kMessageHandlers] = {
@@ -236,12 +237,27 @@ Object.defineProperty(Activity.prototype, 'attachedTo', {
236
237
  return this.getActivityById(attachedToId);
237
238
  }
238
239
  });
240
+ Object.defineProperty(Activity.prototype, 'lane', {
241
+ enumerable: true,
242
+ get() {
243
+ const laneId = this[kFlags].lane;
244
+ if (!laneId) return undefined;
245
+ const parent = this.parentElement;
246
+ return parent.getLaneById && parent.getLaneById(laneId);
247
+ }
248
+ });
239
249
  Object.defineProperty(Activity.prototype, 'eventDefinitions', {
240
250
  enumerable: true,
241
251
  get() {
242
252
  return this[kEventDefinitions];
243
253
  }
244
254
  });
255
+ Object.defineProperty(Activity.prototype, 'parentElement', {
256
+ enumerable: true,
257
+ get() {
258
+ return this.context.getActivityParentById(this.id);
259
+ }
260
+ });
245
261
  Activity.prototype.activate = function activate() {
246
262
  this[kActivated] = true;
247
263
  this.addInboundListeners();
@@ -294,31 +294,36 @@ DefinitionExecution.prototype._activate = function activate(processList) {
294
294
  };
295
295
  DefinitionExecution.prototype._activateProcess = function activateProcess(bp) {
296
296
  const handlers = this[kMessageHandlers];
297
- bp.broker.subscribeTmp('message', 'message.outbound', handlers.onMessageOutbound, {
297
+ const broker = bp.broker;
298
+ broker.subscribeTmp('message', 'message.outbound', handlers.onMessageOutbound, {
298
299
  noAck: true,
299
300
  consumerTag: '_definition-outbound-message-consumer'
300
301
  });
301
- bp.broker.subscribeTmp('event', 'activity.signal', handlers.onDelegateMessage, {
302
+ const delegateEventQ = broker.assertQueue('_delegate-event-q', {
303
+ autoDelete: false,
304
+ durable: false
305
+ });
306
+ delegateEventQ.consume(handlers.onDelegateMessage, {
302
307
  noAck: true,
303
- consumerTag: '_definition-signal-consumer',
308
+ consumerTag: '_definition-signal-consumer'
309
+ });
310
+ broker.bindQueue('_delegate-event-q', 'event', 'activity.signal', {
304
311
  priority: 200
305
312
  });
306
- bp.broker.subscribeTmp('event', 'activity.message', handlers.onDelegateMessage, {
307
- noAck: true,
308
- consumerTag: '_definition-message-consumer',
313
+ broker.bindQueue('_delegate-event-q', 'event', 'activity.message', {
309
314
  priority: 200
310
315
  });
311
- bp.broker.subscribeTmp('event', 'activity.call', handlers.onCallActivity, {
316
+ broker.subscribeTmp('event', 'activity.call', handlers.onCallActivity, {
312
317
  noAck: true,
313
318
  consumerTag: '_definition-call-consumer',
314
319
  priority: 200
315
320
  });
316
- bp.broker.subscribeTmp('event', 'activity.call.cancel', handlers.onCancelCallActivity, {
321
+ broker.subscribeTmp('event', 'activity.call.cancel', handlers.onCancelCallActivity, {
317
322
  noAck: true,
318
323
  consumerTag: '_definition-call-cancel-consumer',
319
324
  priority: 200
320
325
  });
321
- bp.broker.subscribeTmp('event', '#', handlers.onChildEvent, {
326
+ broker.subscribeTmp('event', '#', handlers.onChildEvent, {
322
327
  noAck: true,
323
328
  consumerTag: '_definition-activity-consumer',
324
329
  priority: 100
@@ -351,7 +356,6 @@ DefinitionExecution.prototype._deactivateProcess = function deactivateProcess(bp
351
356
  bp.broker.cancel('_definition-outbound-message-consumer');
352
357
  bp.broker.cancel('_definition-activity-consumer');
353
358
  bp.broker.cancel('_definition-signal-consumer');
354
- bp.broker.cancel('_definition-message-consumer');
355
359
  bp.broker.cancel('_definition-call-consumer');
356
360
  bp.broker.cancel('_definition-call-cancel-consumer');
357
361
  };
package/dist/index.js CHANGED
@@ -172,6 +172,12 @@ Object.defineProperty(exports, "IntermediateThrowEvent", {
172
172
  return _IntermediateThrowEvent.default;
173
173
  }
174
174
  });
175
+ Object.defineProperty(exports, "Lane", {
176
+ enumerable: true,
177
+ get: function () {
178
+ return _Lane.default;
179
+ }
180
+ });
175
181
  Object.defineProperty(exports, "LinkEventDefinition", {
176
182
  enumerable: true,
177
183
  get: function () {
@@ -365,6 +371,7 @@ var _InclusiveGateway = _interopRequireDefault(require("./gateways/InclusiveGate
365
371
  var _InputOutputSpecification = _interopRequireDefault(require("./io/InputOutputSpecification.js"));
366
372
  var _IntermediateCatchEvent = _interopRequireDefault(require("./events/IntermediateCatchEvent.js"));
367
373
  var _IntermediateThrowEvent = _interopRequireDefault(require("./events/IntermediateThrowEvent.js"));
374
+ var _Lane = _interopRequireDefault(require("./process/Lane.js"));
368
375
  var _LinkEventDefinition = _interopRequireDefault(require("./eventDefinitions/LinkEventDefinition.js"));
369
376
  var _LoopCharacteristics = _interopRequireDefault(require("./tasks/LoopCharacteristics.js"));
370
377
  var _Message = _interopRequireDefault(require("./activity/Message.js"));
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = Lane;
7
+ const kProcess = Symbol.for('process');
8
+ function Lane(process, laneDefinition) {
9
+ const {
10
+ broker,
11
+ environment
12
+ } = process;
13
+ const {
14
+ id,
15
+ type,
16
+ behaviour
17
+ } = laneDefinition;
18
+ this[kProcess] = process;
19
+ this.id = id;
20
+ this.type = type;
21
+ this.name = behaviour.name;
22
+ this.parent = {
23
+ id: process.id,
24
+ type: process.type
25
+ };
26
+ this.behaviour = {
27
+ ...behaviour
28
+ };
29
+ this.environment = environment;
30
+ this.broker = broker;
31
+ this.context = process.context;
32
+ this.logger = environment.Logger(type.toLowerCase());
33
+ }
34
+ Object.defineProperty(Lane.prototype, 'process', {
35
+ get() {
36
+ return this[kProcess];
37
+ }
38
+ });
@@ -17,6 +17,7 @@ const kCounters = Symbol.for('counters');
17
17
  const kExec = Symbol.for('execution');
18
18
  const kExecuteMessage = Symbol.for('executeMessage');
19
19
  const kExtensions = Symbol.for('extensions');
20
+ const kLanes = Symbol.for('lanes');
20
21
  const kMessageHandlers = Symbol.for('messageHandlers');
21
22
  const kStateMessage = Symbol.for('stateMessage');
22
23
  const kStatus = Symbol.for('status');
@@ -66,6 +67,9 @@ function Process(processDef, context) {
66
67
  onExecutionMessage: this._onExecutionMessage.bind(this)
67
68
  };
68
69
  this.logger = environment.Logger(type.toLowerCase());
70
+ if (behaviour.lanes) {
71
+ this[kLanes] = behaviour.lanes.map(lane => new lane.Behaviour(this, lane));
72
+ }
69
73
  this[kExtensions] = context.loadExtensions(this);
70
74
  }
71
75
  Object.defineProperty(Process.prototype, 'counters', {
@@ -76,6 +80,13 @@ Object.defineProperty(Process.prototype, 'counters', {
76
80
  };
77
81
  }
78
82
  });
83
+ Object.defineProperty(Process.prototype, 'lanes', {
84
+ enumerable: true,
85
+ get() {
86
+ const lanes = this[kLanes];
87
+ return lanes && lanes.slice();
88
+ }
89
+ });
79
90
  Object.defineProperty(Process.prototype, 'extensions', {
80
91
  enumerable: true,
81
92
  get() {
@@ -404,6 +415,11 @@ Process.prototype.getSequenceFlows = function getSequenceFlows() {
404
415
  if (execution) return execution.getSequenceFlows();
405
416
  return this.context.getSequenceFlows();
406
417
  };
418
+ Process.prototype.getLaneById = function getLaneById(laneId) {
419
+ const lanes = this[kLanes];
420
+ if (!lanes) return;
421
+ return lanes.find(lane => lane.id === laneId);
422
+ };
407
423
  Process.prototype.getPostponed = function getPostponed(...args) {
408
424
  const execution = this.execution;
409
425
  if (!execution) return [];
@@ -135,7 +135,7 @@ SubProcessBehaviour.prototype.recover = function recover(state) {
135
135
  executions.splice(0);
136
136
  }
137
137
  const subEnvironment = this.environment.clone().recover(state.environment);
138
- const subContext = this.context.clone(subEnvironment);
138
+ const subContext = this.context.clone(subEnvironment, this.activity);
139
139
  const execution = new _ProcessExecution.default(this.activity, subContext).recover(state);
140
140
  executions.push(execution);
141
141
  return execution;
@@ -168,7 +168,7 @@ SubProcessBehaviour.prototype._upsertExecution = function upsertExecution(execut
168
168
  return execution;
169
169
  }
170
170
  const subEnvironment = this.environment.clone();
171
- const subContext = this.context.clone(subEnvironment);
171
+ const subContext = this.context.clone(subEnvironment, this.activity);
172
172
  execution = new _ProcessExecution.default(this.activity, subContext);
173
173
  this[kExecutions].push(execution);
174
174
  this._addListeners(execution, executionId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bpmn-elements",
3
- "version": "10.0.0",
3
+ "version": "10.1.0",
4
4
  "description": "Executable workflow elements based on BPMN 2.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -13,11 +13,11 @@
13
13
  },
14
14
  "sideEffects": false,
15
15
  "scripts": {
16
- "test": "mocha -R dot",
16
+ "test": "mocha -R @bonniernews/hot-bev -p -t 2000",
17
17
  "posttest": "npm run lint && npm run dist",
18
18
  "lint": "eslint . --cache",
19
19
  "prepack": "npm run dist",
20
- "cov:html": "c8 -r html -r text mocha -R dot",
20
+ "cov:html": "c8 -r html -r text mocha -R @bonniernews/hot-bev -p -t 2000",
21
21
  "test:lcov": "c8 -r lcov mocha && npm run lint",
22
22
  "dist": "babel src -d dist/"
23
23
  },
@@ -45,22 +45,23 @@
45
45
  ],
46
46
  "devDependencies": {
47
47
  "@aircall/expression-parser": "^1.0.4",
48
- "@babel/cli": "^7.21.5",
49
- "@babel/core": "^7.21.8",
50
- "@babel/preset-env": "^7.21.5",
51
- "@babel/register": "^7.21.0",
48
+ "@babel/cli": "^7.22.5",
49
+ "@babel/core": "^7.22.5",
50
+ "@babel/preset-env": "^7.22.5",
51
+ "@babel/register": "^7.22.5",
52
+ "@bonniernews/hot-bev": "^0.4.0",
52
53
  "bpmn-moddle": "^8.0.1",
53
- "c8": "^7.13.0",
54
+ "c8": "^7.14.0",
54
55
  "camunda-bpmn-moddle": "^7.0.1",
55
56
  "chai": "^4.3.7",
56
57
  "chronokinesis": "^5.0.2",
57
58
  "debug": "^4.3.4",
58
- "eslint": "^8.41.0",
59
+ "eslint": "^8.42.0",
59
60
  "eslint-plugin-import": "^2.27.5",
60
- "got": "^12.6.0",
61
+ "got": "^12.6.1",
61
62
  "mocha": "^10.1.0",
62
63
  "mocha-cakes-2": "^3.3.0",
63
- "moddle-context-serializer": "^3.2.2",
64
+ "moddle-context-serializer": "^4.0.0",
64
65
  "nock": "^13.3.1"
65
66
  },
66
67
  "dependencies": {
package/src/Context.js CHANGED
@@ -3,12 +3,14 @@ import Environment from './Environment.js';
3
3
  import ExtensionsMapper from './ExtensionsMapper.js';
4
4
  import {getUniqueId} from './shared.js';
5
5
 
6
+ const kOwner = Symbol.for('owner');
7
+
6
8
  export default function Context(definitionContext, environment) {
7
9
  environment = environment ? environment.clone() : new Environment();
8
10
  return new ContextInstance(definitionContext, environment);
9
11
  }
10
12
 
11
- function ContextInstance(definitionContext, environment) {
13
+ function ContextInstance(definitionContext, environment, owner) {
12
14
  const {id = 'Def', name, type = 'context'} = definitionContext;
13
15
  const sid = getUniqueId(id);
14
16
  this.id = id;
@@ -29,8 +31,15 @@ function ContextInstance(definitionContext, environment) {
29
31
  sequenceFlowRefs: {},
30
32
  sequenceFlows: [],
31
33
  };
34
+ this[kOwner] = owner;
32
35
  }
33
36
 
37
+ Object.defineProperty(ContextInstance.prototype, 'owner', {
38
+ get() {
39
+ return this[kOwner];
40
+ },
41
+ });
42
+
34
43
  ContextInstance.prototype.getActivityById = function getActivityById(activityId) {
35
44
  const activityInstance = this.refs.activityRefs[activityId];
36
45
  if (activityInstance) return activityInstance;
@@ -106,8 +115,8 @@ ContextInstance.prototype.upsertAssociation = function upsertAssociation(associa
106
115
  return instance;
107
116
  };
108
117
 
109
- ContextInstance.prototype.clone = function clone(newEnvironment) {
110
- return new ContextInstance(this.definitionContext, newEnvironment || this.environment);
118
+ ContextInstance.prototype.clone = function clone(newEnvironment, newOwner) {
119
+ return new ContextInstance(this.definitionContext, newEnvironment || this.environment, newOwner);
111
120
  };
112
121
 
113
122
  ContextInstance.prototype.getProcessById = function getProcessById(processId) {
@@ -120,6 +129,8 @@ ContextInstance.prototype.getProcessById = function getProcessById(processId) {
120
129
 
121
130
  const bpContext = this.clone(this.environment.clone());
122
131
  bp = refs[processId] = new processDefinition.Behaviour(processDefinition, bpContext);
132
+ bpContext[kOwner] = bp;
133
+
123
134
  this.refs.processes.push(bp);
124
135
 
125
136
  return bp;
@@ -128,7 +139,11 @@ ContextInstance.prototype.getProcessById = function getProcessById(processId) {
128
139
  ContextInstance.prototype.getNewProcessById = function getNewProcessById(processId) {
129
140
  if (!this.getProcessById(processId)) return null;
130
141
  const bpDef = this.definitionContext.getProcessById(processId);
131
- const bp = new bpDef.Behaviour(bpDef, this.clone(this.environment.clone()));
142
+
143
+ const bpContext = this.clone(this.environment.clone());
144
+ const bp = new bpDef.Behaviour(bpDef, bpContext);
145
+ bpContext[kOwner] = bp;
146
+
132
147
  return bp;
133
148
  };
134
149
 
@@ -201,3 +216,11 @@ ContextInstance.prototype.loadExtensions = function loadExtensions(activity) {
201
216
  if (!extensions.extensions.length) return;
202
217
  return extensions;
203
218
  };
219
+
220
+ ContextInstance.prototype.getActivityParentById = function getActivityParentById(activityId) {
221
+ const owner = this[kOwner];
222
+ if (owner) return owner;
223
+ const activity = this.getActivityById(activityId);
224
+ const parentId = activity.parent.id;
225
+ return this.getProcessById(parentId) || this.getActivityById(parentId);
226
+ };
@@ -87,6 +87,7 @@ function Activity(Behaviour, activityDef, context) {
87
87
  isTransaction: activityDef.isTransaction,
88
88
  isParallelJoin,
89
89
  isThrowing: activityDef.isThrowing,
90
+ lane: activityDef.lane && activityDef.lane.id,
90
91
  };
91
92
  this[kExec] = {};
92
93
 
@@ -235,6 +236,16 @@ Object.defineProperty(Activity.prototype, 'attachedTo', {
235
236
  },
236
237
  });
237
238
 
239
+ Object.defineProperty(Activity.prototype, 'lane', {
240
+ enumerable: true,
241
+ get() {
242
+ const laneId = this[kFlags].lane;
243
+ if (!laneId) return undefined;
244
+ const parent = this.parentElement;
245
+ return parent.getLaneById && parent.getLaneById(laneId);
246
+ },
247
+ });
248
+
238
249
  Object.defineProperty(Activity.prototype, 'eventDefinitions', {
239
250
  enumerable: true,
240
251
  get() {
@@ -242,6 +253,13 @@ Object.defineProperty(Activity.prototype, 'eventDefinitions', {
242
253
  },
243
254
  });
244
255
 
256
+ Object.defineProperty(Activity.prototype, 'parentElement', {
257
+ enumerable: true,
258
+ get() {
259
+ return this.context.getActivityParentById(this.id);
260
+ },
261
+ });
262
+
245
263
  Activity.prototype.activate = function activate() {
246
264
  this[kActivated] = true;
247
265
  this.addInboundListeners();
@@ -322,32 +322,29 @@ DefinitionExecution.prototype._activate = function activate(processList) {
322
322
 
323
323
  DefinitionExecution.prototype._activateProcess = function activateProcess(bp) {
324
324
  const handlers = this[kMessageHandlers];
325
+ const broker = bp.broker;
325
326
 
326
- bp.broker.subscribeTmp('message', 'message.outbound', handlers.onMessageOutbound, {
327
+ broker.subscribeTmp('message', 'message.outbound', handlers.onMessageOutbound, {
327
328
  noAck: true,
328
329
  consumerTag: '_definition-outbound-message-consumer',
329
330
  });
330
- bp.broker.subscribeTmp('event', 'activity.signal', handlers.onDelegateMessage, {
331
- noAck: true,
332
- consumerTag: '_definition-signal-consumer',
333
- priority: 200,
334
- });
335
- bp.broker.subscribeTmp('event', 'activity.message', handlers.onDelegateMessage, {
336
- noAck: true,
337
- consumerTag: '_definition-message-consumer',
338
- priority: 200,
339
- });
340
- bp.broker.subscribeTmp('event', 'activity.call', handlers.onCallActivity, {
331
+
332
+ const delegateEventQ = broker.assertQueue('_delegate-event-q', {autoDelete: false, durable: false});
333
+ delegateEventQ.consume(handlers.onDelegateMessage, {noAck: true, consumerTag: '_definition-signal-consumer'});
334
+ broker.bindQueue('_delegate-event-q', 'event', 'activity.signal', {priority: 200});
335
+ broker.bindQueue('_delegate-event-q', 'event', 'activity.message', {priority: 200});
336
+
337
+ broker.subscribeTmp('event', 'activity.call', handlers.onCallActivity, {
341
338
  noAck: true,
342
339
  consumerTag: '_definition-call-consumer',
343
340
  priority: 200,
344
341
  });
345
- bp.broker.subscribeTmp('event', 'activity.call.cancel', handlers.onCancelCallActivity, {
342
+ broker.subscribeTmp('event', 'activity.call.cancel', handlers.onCancelCallActivity, {
346
343
  noAck: true,
347
344
  consumerTag: '_definition-call-cancel-consumer',
348
345
  priority: 200,
349
346
  });
350
- bp.broker.subscribeTmp('event', '#', handlers.onChildEvent, {
347
+ broker.subscribeTmp('event', '#', handlers.onChildEvent, {
351
348
  noAck: true,
352
349
  consumerTag: '_definition-activity-consumer',
353
350
  priority: 100,
@@ -383,7 +380,6 @@ DefinitionExecution.prototype._deactivateProcess = function deactivateProcess(bp
383
380
  bp.broker.cancel('_definition-outbound-message-consumer');
384
381
  bp.broker.cancel('_definition-activity-consumer');
385
382
  bp.broker.cancel('_definition-signal-consumer');
386
- bp.broker.cancel('_definition-message-consumer');
387
383
  bp.broker.cancel('_definition-call-consumer');
388
384
  bp.broker.cancel('_definition-call-cancel-consumer');
389
385
  };
package/src/index.js CHANGED
@@ -23,6 +23,7 @@ import InclusiveGateway from './gateways/InclusiveGateway.js';
23
23
  import InputOutputSpecification from './io/InputOutputSpecification.js';
24
24
  import IntermediateCatchEvent from './events/IntermediateCatchEvent.js';
25
25
  import IntermediateThrowEvent from './events/IntermediateThrowEvent.js';
26
+ import Lane from './process/Lane.js';
26
27
  import LinkEventDefinition from './eventDefinitions/LinkEventDefinition.js';
27
28
  import LoopCharacteristics from './tasks/LoopCharacteristics.js';
28
29
  import Message from './activity/Message.js';
@@ -82,6 +83,7 @@ export {
82
83
  Message,
83
84
  MessageEventDefinition,
84
85
  MessageFlow,
86
+ Lane,
85
87
  LoopCharacteristics as MultiInstanceLoopCharacteristics,
86
88
  ParallelGateway,
87
89
  Process,
@@ -0,0 +1,27 @@
1
+ const kProcess = Symbol.for('process');
2
+
3
+ export default function Lane(process, laneDefinition) {
4
+ const {broker, environment} = process;
5
+ const {id, type, behaviour} = laneDefinition;
6
+
7
+ this[kProcess] = process;
8
+
9
+ this.id = id;
10
+ this.type = type;
11
+ this.name = behaviour.name;
12
+ this.parent = {
13
+ id: process.id,
14
+ type: process.type,
15
+ };
16
+ this.behaviour = {...behaviour};
17
+ this.environment = environment;
18
+ this.broker = broker;
19
+ this.context = process.context;
20
+ this.logger = environment.Logger(type.toLowerCase());
21
+ }
22
+
23
+ Object.defineProperty(Lane.prototype, 'process', {
24
+ get() {
25
+ return this[kProcess];
26
+ },
27
+ });
@@ -10,6 +10,7 @@ const kCounters = Symbol.for('counters');
10
10
  const kExec = Symbol.for('execution');
11
11
  const kExecuteMessage = Symbol.for('executeMessage');
12
12
  const kExtensions = Symbol.for('extensions');
13
+ const kLanes = Symbol.for('lanes');
13
14
  const kMessageHandlers = Symbol.for('messageHandlers');
14
15
  const kStateMessage = Symbol.for('stateMessage');
15
16
  const kStatus = Symbol.for('status');
@@ -53,6 +54,9 @@ export function Process(processDef, context) {
53
54
 
54
55
  this.logger = environment.Logger(type.toLowerCase());
55
56
 
57
+ if (behaviour.lanes) {
58
+ this[kLanes] = behaviour.lanes.map((lane) => new lane.Behaviour(this, lane));
59
+ }
56
60
  this[kExtensions] = context.loadExtensions(this);
57
61
  }
58
62
 
@@ -63,6 +67,14 @@ Object.defineProperty(Process.prototype, 'counters', {
63
67
  },
64
68
  });
65
69
 
70
+ Object.defineProperty(Process.prototype, 'lanes', {
71
+ enumerable: true,
72
+ get() {
73
+ const lanes = this[kLanes];
74
+ return lanes && lanes.slice();
75
+ },
76
+ });
77
+
66
78
  Object.defineProperty(Process.prototype, 'extensions', {
67
79
  enumerable: true,
68
80
  get() {
@@ -399,6 +411,12 @@ Process.prototype.getSequenceFlows = function getSequenceFlows() {
399
411
  return this.context.getSequenceFlows();
400
412
  };
401
413
 
414
+ Process.prototype.getLaneById = function getLaneById(laneId) {
415
+ const lanes = this[kLanes];
416
+ if (!lanes) return;
417
+ return lanes.find((lane) => lane.id === laneId);
418
+ };
419
+
402
420
  Process.prototype.getPostponed = function getPostponed(...args) {
403
421
  const execution = this.execution;
404
422
  if (!execution) return [];
@@ -135,7 +135,7 @@ SubProcessBehaviour.prototype.recover = function recover(state) {
135
135
  }
136
136
 
137
137
  const subEnvironment = this.environment.clone().recover(state.environment);
138
- const subContext = this.context.clone(subEnvironment);
138
+ const subContext = this.context.clone(subEnvironment, this.activity);
139
139
 
140
140
  const execution = new ProcessExecution(this.activity, subContext).recover(state);
141
141
 
@@ -176,7 +176,7 @@ SubProcessBehaviour.prototype._upsertExecution = function upsertExecution(execut
176
176
  }
177
177
 
178
178
  const subEnvironment = this.environment.clone();
179
- const subContext = this.context.clone(subEnvironment);
179
+ const subContext = this.context.clone(subEnvironment, this.activity);
180
180
 
181
181
  execution = new ProcessExecution(this.activity, subContext);
182
182
  this[kExecutions].push(execution);
package/types/index.d.ts CHANGED
@@ -288,6 +288,8 @@ declare module 'bpmn-elements' {
288
288
  get sid(): string;
289
289
  get definitionContext(): SerializableContext;
290
290
  get environment(): Environment;
291
+ /** Context owner, Process or SubProcess activity */
292
+ get owner(): Process | Activity | undefined;
291
293
  getActivityById<T>(activityId: string): T;
292
294
  getSequenceFlowById(sequenceFlowId: string): SequenceFlow;
293
295
  getInboundSequenceFlows(activityId: string): SequenceFlow[];
@@ -429,6 +431,7 @@ declare module 'bpmn-elements' {
429
431
  constructor(processDef: SerializableElement, context: Context);
430
432
  get isExecutable(): boolean;
431
433
  get counters(): completedCounters;
434
+ get lanes(): Lane[] | undefined;
432
435
  get extensions(): IExtension;
433
436
  get stopped(): boolean;
434
437
  get isRunning(): boolean;
@@ -448,6 +451,7 @@ declare module 'bpmn-elements' {
448
451
  getActivities(): Activity[];
449
452
  getStartActivities(filterOptions?: startActivityFilterOptions): Activity[];
450
453
  getSequenceFlows(): SequenceFlow[];
454
+ getLaneById(laneId: string): Lane | undefined;
451
455
  getPostponed(filterFn: filterPostponed): Api<ElementBase>[];
452
456
  }
453
457
 
@@ -471,6 +475,24 @@ declare module 'bpmn-elements' {
471
475
  getApi(message?: ElementBrokerMessage): Api<ElementBase>;
472
476
  }
473
477
 
478
+ class Lane extends ElementBase {
479
+ constructor(process: Process, laneDefinition: SerializableElement);
480
+ /** Process broker */
481
+ get broker(): Broker;
482
+ get process(): Process;
483
+ }
484
+
485
+ interface ISequenceFlowCondition {
486
+ /** Condition type, e.g. script or expression */
487
+ get type(): string;
488
+ /**
489
+ * Execute sequence flow condition
490
+ * @param message Source element execution message
491
+ * @param callback Callback with truthy result if flow should be taken
492
+ */
493
+ execute(message: ElementBrokerMessage, callback: (err: Error, result: any) => void): void;
494
+ }
495
+
474
496
  class SequenceFlow extends Element<SequenceFlow> {
475
497
  get sourceId(): string;
476
498
  get targetId(): string;
@@ -480,7 +502,7 @@ declare module 'bpmn-elements' {
480
502
  take(content?: any): boolean;
481
503
  discard(content?: any): void;
482
504
  shake(message: any): number;
483
- getCondition(): any;
505
+ getCondition(): ISequenceFlowCondition | null;
484
506
  createMessage(override?: any): object;
485
507
  /**
486
508
  * Evaluate flow
@@ -496,6 +518,7 @@ declare module 'bpmn-elements' {
496
518
  get id(): string;
497
519
  get processId(): string;
498
520
  }
521
+
499
522
  class MessageFlow extends Element<MessageFlow> {
500
523
  get source(): MessageFlowReference;
501
524
  get target(): MessageFlowReference;
@@ -596,6 +619,8 @@ declare module 'bpmn-elements' {
596
619
  get triggeredByEvent(): boolean;
597
620
  get attachedTo(): Activity;
598
621
  get eventDefinitions(): EventDefinition[];
622
+ /** Parent element process or sub process reference */
623
+ get parentElement(): Process | Activity;
599
624
  activate(): void;
600
625
  deactivate(): void;
601
626
  init(initContent?: any): void;