Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

bpmn-js-token-simulation

Package Overview
Dependencies
Maintainers
6
Versions
58
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bpmn-js-token-simulation - npm Package Compare versions

Comparing version 0.13.0 to 0.14.0

lib/features/context-pads/handler/EventBasedGatewayHandler.js

11

CHANGELOG.md

@@ -9,6 +9,15 @@ # Changelog

## 0.14.0
* `FEAT`: add support for event sub-process ([#71](https://github.com/bpmn-io/bpmn-js-token-simulation/issues/71))
* `FEAT`: add support for event-based gateway ([#72](https://github.com/bpmn-io/bpmn-js-token-simulation/issues/72))
* `FEAT`: support boundary events on tasks
* `FEAT`: rework context pads open/close handling
* `FEAT`: batch simulator element changed events
* `FIX`: correct scope filter integration with context pads
## 0.13.0
* `FEAT`: allow to toggle explicit mode
* `FEAT`: handle diagram import during simulation
* `FEAT`: handle diagram import during simulation
* `FIX`: do not re-add toggle mode UI on diagram re-import

@@ -15,0 +24,0 @@

104

lib/features/context-pads/ContextPads.js
import {
isAncestor
is
} from '../../util/ElementHelper';

@@ -13,2 +13,3 @@

import ExclusiveGatewayHandler from './handler/ExclusiveGatewayHandler';
import EventBasedGatewayHandler from './handler/EventBasedGatewayHandler';
import IntermediateCatchEventHandler from './handler/IntermediateCatchEventHandler';

@@ -35,5 +36,5 @@ import StartEventHandler from './handler/StartEventHandler';

this._overlayIds = {};
this._overlaysByElement = new Map();
this._handlers = {};
this._handlers = [];

@@ -44,9 +45,13 @@ this.registerHandler('bpmn:ExclusiveGateway', ExclusiveGatewayHandler);

this.registerHandler('bpmn:EventBasedGateway', EventBasedGatewayHandler);
// TODO(nikku): restore or delete
// this.registerHandler('bpmn:SubProcess', ProcessHandler);
this.registerHandler('bpmn:SubProcess', BoundaryEventHandler);
this.registerHandler('bpmn:BoundaryEvent', BoundaryEventHandler);
this.registerHandler('bpmn:StartEvent', StartEventHandler);
this.registerHandler('bpmn:Activity', BoundaryEventHandler);
this.registerHandler('bpmn:Process', StartEventHandler);
this.registerHandler('bpmn:SubProcess', StartEventHandler);
this.registerHandler('bpmn:Participant', StartEventHandler);
eventBus.on(TOGGLE_MODE_EVENT, LOW_PRIORITY, context => {

@@ -85,9 +90,16 @@ const active = context.active;

ContextPads.prototype.registerHandler = function(type, handlerCls) {
var handler = this._injector.instantiate(handlerCls);
const handler = this._injector.instantiate(handlerCls);
if (!this._handlers[type]) {
this._handlers[type] = [];
}
this._handlers.push({ handler, type });
};
this._handlers[type].push(handler);
ContextPads.prototype.getHandlers = function(element) {
return (
this._handlers.filter(
({ type }) => is(element, type)
).map(
({ handler }) => handler
)
);
};

@@ -108,9 +120,20 @@

ContextPads.prototype.registerContextPad = function(element, overlayId) {
const overlaysByElement = this._overlaysByElement;
if (!overlaysByElement.has(element)) {
overlaysByElement.set(element, []);
}
const overlayIds = overlaysByElement.get(element);
overlayIds.push(overlayId);
};
ContextPads.prototype.openElementContextPads = function(element) {
const handlers = this._handlers[element.type] || [];
const contextPads = [];
for (const handler of handlers) {
for (const handler of this.getHandlers(element)) {
const additionalPads = handler.createContextPads(element) || [];

@@ -135,38 +158,45 @@

this._overlayIds[contextPad.element.id] = overlayId;
this.registerContextPad(element, overlayId);
}
};
ContextPads.prototype.closeContextPads = function(parent) {
if (!parent) {
parent = this._canvas.getRootElement();
ContextPads.prototype.closeContextPads = function() {
for (const element of this._overlaysByElement.keys()) {
this.closeElementContextPads(element);
}
this._elementRegistry.forEach(element => {
if (isAncestor(parent, element)) {
this.closeElementContextPads(element);
}
});
};
ContextPads.prototype.closeElementContextPads = function(element) {
(element.attachers || []).forEach(attachedElement => {
this.closeElementContextPads(attachedElement);
});
var overlayId = this._overlayIds[element.id];
const overlayIds = this._overlaysByElement.get(element) || [];
if (!overlayId) {
return;
for (const overlayId of overlayIds) {
this._overlays.remove(overlayId);
}
this._overlays.remove(overlayId);
delete this._overlayIds[element.id];
overlayIds.length = 0;
};
ContextPads.prototype.get = function(element) {
return this._overlayIds[element.id || element];
};
ContextPads.$inject = [
'eventBus',
'elementRegistry',
'overlays',
'injector',
'canvas'
];
ContextPads.$inject = [ 'eventBus', 'elementRegistry', 'overlays', 'injector', 'canvas' ];
// helpers ///////////////
export function isAncestor(ancestor, descendant) {
do {
if (ancestor === descendant) {
return true;
}
descendant = descendant.parent;
} while (descendant);
return false;
}

@@ -10,2 +10,3 @@ import {

export default function BoundaryEventHandler(simulator, scopeFilter) {

@@ -17,26 +18,31 @@ this._simulator = simulator;

BoundaryEventHandler.prototype.createContextPads = function(element) {
return element.attachers.map(
attacher => this.createBoundaryContextPad(attacher)
);
};
if (is(element, 'bpmn:BoundaryEvent')) {
return [
this.createBoundaryContextPad(element)
];
}
BoundaryEventHandler.prototype.createBoundaryContextPad = function(element) {
if (is(element, 'bpmn:SubProcess')) {
return element.attachers.map(
attacher => this.createBoundaryContextPad(attacher)
);
}
};
const scopeElement = element.host;
BoundaryEventHandler.prototype.createBoundaryContextPad = function(boundaryElement) {
if (is(scopeElement, 'bpmn:SubProcess')) {
const scopeElement = boundaryElement.host;
// need nested running scopes on sub-processes
const nestedScope = this._findScope({
element: scopeElement
});
const nestedScope = this._findScope({
element: scopeElement
});
if (!nestedScope) {
return;
}
} else {
if (!nestedScope) {
return;
// need waiting scope on other elements
const waitingScope = this._findScope({
waitsOnElement: scopeElement
});
if (!waitingScope) {
return;
}
}

@@ -52,5 +58,5 @@

this._simulator.signal({
element: boundaryElement,
element: element,
scope: this._findScope({
element: boundaryElement.parent,
element: element.parent,
waitsOnElement: scopeElement

@@ -62,3 +68,3 @@ })

return {
element: boundaryElement,
element,
html

@@ -65,0 +71,0 @@ };

@@ -34,3 +34,5 @@ import {

element,
scope: activeScope
scope: this._findScope({
waitsOnElement: element
})
});

@@ -37,0 +39,0 @@ });

@@ -7,8 +7,10 @@ import {

import {
is
is,
getBusinessObject
} from '../../../util/ElementHelper';
export default function StartEventHandler(simulator) {
export default function StartEventHandler(simulator, scopeFilter) {
this._simulator = simulator;
this._scopeFilter = scopeFilter;
}

@@ -18,4 +20,31 @@

if (is(element.parent, 'bpmn:SubProcess')) {
return;
const startEvents = findStartEvents(element);
const pads = startEvents.map(
startEvent => this.createStartEventContextPad(startEvent, element)
);
return pads;
};
StartEventHandler.prototype.createStartEventContextPad = function(element, parent) {
const parentElement = element.parent;
let parentScope;
if (is(parentElement, 'bpmn:SubProcess')) {
if (!isEventSubProcess(parentElement)) {
return;
}
parentScope = this._findScope({
element: parentElement.parent
});
// no parent scope for event sub-process
if (!parentScope) {
return;
}
}

@@ -28,17 +57,60 @@

domEvent.bind(html, 'click', () => {
const parentScope = is(parentElement, 'bpmn:SubProcess') ? this._findScope({
element: parentElement.parent
}) : null;
this._simulator.signal({
element
element,
parentScope
});
});
return [
{
element,
html
}
];
return {
element,
html
};
};
StartEventHandler.prototype._findScope = function(options) {
return (
this._scopeFilter.findScope(options) ||
this._simulator.findScope(options)
);
};
StartEventHandler.$inject = [
'simulator'
];
'simulator',
'scopeFilter'
];
// helpers //////////////
function findStartEvents(processElement) {
const startEvents = processElement.businessObject.triggeredByEvent
? []
: processElement.children.filter(isStartEvent);
const eventSubProcesses = processElement.children.filter(isEventSubProcess);
return eventSubProcesses.reduce((startEvents, subProcessElement) => {
for (const subProcessChild of subProcessElement.children) {
if (isStartEvent(subProcessChild)) {
startEvents.push(subProcessChild);
}
}
return startEvents;
}, startEvents);
}
function isEventSubProcess(element) {
return getBusinessObject(element).triggeredByEvent;
}
function isStartEvent(element) {
return is(element, 'bpmn:StartEvent');
}

@@ -16,4 +16,3 @@ import {

'bpmn:InclusiveGateway',
'bpmn:ComplexGateway',
'bpmn:EventBasedGateway'
'bpmn:ComplexGateway'
];

@@ -20,0 +19,0 @@

import {
getBusinessObject
getBusinessObject,
is
} from './ModelUtil';

@@ -29,17 +30,19 @@

const childScope = this._simulator.findScope({
parent: scope,
element: scopeElement
});
if (is(scopeElement, 'bpmn:SubProcess')) {
const childScope = this._simulator.findScope({
parent: scope,
element: scopeElement
});
if (!childScope) {
throw new Error('cancel scope not found');
if (!childScope) {
throw new Error('cancel scope not found');
}
this._simulator.destroyScope(childScope, {
reason: 'cancel',
element,
scope
});
}
this._simulator.destroyScope(childScope, {
reason: 'cancel',
element,
scope
});
// remove destroyed scope token

@@ -46,0 +49,0 @@ scope.updateTokens(scopeElement, -1);

import {
isTerminate,
isMessageFlow
isMessageFlow,
isEventSubProcess
} from './ModelUtil';

@@ -50,3 +51,3 @@

if (parentScope) {
if (!isEventSubProcess(scope.element) && parentScope) {
this._simulator.exit({

@@ -53,0 +54,0 @@ element: scope.element,

@@ -9,2 +9,3 @@ import StartEventBehavior from './StartEventBehavior';

import ParallelGatewayBehavior from './ParallelGatewayBehavior';
import EventBasedGatewayBehavior from './EventBasedGatewayBehavior';

@@ -27,2 +28,3 @@ import ActivityBehavior from './ActivityBehavior';

'parallelGatewayBehavior',
'eventBasedGatewayBehavior',
'activityBehavior',

@@ -40,2 +42,3 @@ 'subProcessBehavior',

parallelGatewayBehavior: [ 'type', ParallelGatewayBehavior ],
eventBasedGatewayBehavior: [ 'type', EventBasedGatewayBehavior ],
activityBehavior: [ 'type', ActivityBehavior ],

@@ -42,0 +45,0 @@ subProcessBehavior: [ 'type', SubProcessBehavior ],

import {
isLink
isLink,
is
} from './ModelUtil';

@@ -18,5 +19,19 @@

IntermediateCatchEventBehavior.prototype.signal = function(context) {
const {
relatedElement,
scope
} = context;
const triggerEventBased = relatedElement && is(relatedElement, 'bpmn:EventBasedGateway');
if (triggerEventBased) {
scope.updateTokens(relatedElement, -1);
}
const signal = !triggerEventBased;
this._simulator.exit({
...context,
signal: true
signal
});

@@ -23,0 +38,0 @@ };

@@ -30,2 +30,6 @@ import {

});
}
export function isEventSubProcess(element) {
return getBusinessObject(element).triggeredByEvent;
}

@@ -0,1 +1,7 @@

import {
getBusinessObject,
isEventSubProcess
} from './ModelUtil';
export default function StartEventBehavior(

@@ -12,2 +18,28 @@ simulator,

StartEventBehavior.prototype.signal = function(context) {
const {
element,
parentScope,
scope
} = context;
const {
parent: parentElement
} = element;
// trigger event sub-process
if (isEventSubProcess(parentElement)) {
if (!parentScope) {
throw new Error('missing <parentScope>');
}
if (getBusinessObject(element).isInterrupting) {
this._simulator.destroyScope(parentScope, {
reason: 'cancel',
...context
}, [ scope ]);
}
}
this._simulator.exit(context);

@@ -14,0 +46,0 @@ };

@@ -19,2 +19,15 @@ import Ids from 'ids';

const changedElements = new Set();
on('tick', function() {
for (const element of changedElements) {
emit('elementChanged', {
element
});
}
changedElements.clear();
});
function queue(scope, task) {

@@ -42,2 +55,4 @@

}
emit('tick');
}

@@ -70,3 +85,3 @@

getBehavior(element).signal({
element,
...context,
scope

@@ -143,2 +158,4 @@ });

);
elementChanged(element);
},

@@ -166,2 +183,4 @@ getTokens() {

elementChanged(element);
return scope;

@@ -206,3 +225,3 @@ }

function destroyScope(scope, context=noneContext) {
function destroyScope(scope, context=noneContext, excludeChildren=[]) {

@@ -220,3 +239,3 @@ if (scope.destroyed) {

for (const childScope of scope.children) {
if (!childScope.destroyed) {
if (!childScope.destroyed && !excludeChildren.includes(childScope)) {
destroyScope(childScope, {

@@ -258,5 +277,3 @@ ...context,

function elementChanged(element) {
emit('elementChanged', {
element
});
changedElements.add(element);
}

@@ -263,0 +280,0 @@

@@ -6,2 +6,6 @@ import {

import {
is as __is
} from 'bpmn-js/lib/util/ModelUtil';
export function is(element, types) {

@@ -16,11 +20,5 @@ if (element.type === 'label') {

var isType = false;
types.forEach(function(type) {
if (type === element.type) {
isType = true;
}
return types.some(function(type) {
return __is(element, type);
});
return isType;
}

@@ -42,16 +40,2 @@

return (element && element.businessObject) || element;
}
export function isAncestor(ancestor, descendant) {
let childParent = descendant.parent;
while (childParent) {
if (childParent === ancestor) {
return true;
}
childParent = childParent.parent;
}
return false;
}
{
"name": "bpmn-js-token-simulation",
"version": "0.13.0",
"version": "0.14.0",
"description": "bpmn-js token simulation extension",

@@ -5,0 +5,0 @@ "main": "index.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc