UNPKG

bpmn-elements

Version:

Executable workflow elements based on BPMN 2.0

182 lines (181 loc) 5.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _messageHelper = require("../messageHelper.js"); var _shared = require("../shared.js"); var _EventBroker = require("../EventBroker.js"); var _Api = require("../Api.js"); var _condition = require("../condition.js"); const kCounters = Symbol.for('counters'); var _default = exports.default = SequenceFlow; function SequenceFlow(flowDef, { environment }) { const { id, type = 'sequenceflow', name, parent, targetId, sourceId, isDefault, behaviour = {} } = flowDef; this.id = id; this.type = type; this.name = name; this.parent = (0, _messageHelper.cloneParent)(parent); this.behaviour = behaviour; this.sourceId = sourceId; this.targetId = targetId; this.isDefault = isDefault; this.isSequenceFlow = true; this.environment = environment; const logger = this.logger = environment.Logger(type.toLowerCase()); this[kCounters] = { looped: 0, take: 0, discard: 0 }; const { broker, on, once, waitFor, emitFatal } = new _EventBroker.EventBroker(this, { prefix: 'flow', durable: true, autoDelete: false }); this.broker = broker; this.on = on; this.once = once; this.waitFor = waitFor; this.emitFatal = emitFatal; environment.registerScript(this); logger.debug(`<${id}> init, <${sourceId}> -> <${targetId}>`); } Object.defineProperty(SequenceFlow.prototype, 'counters', { get() { return { ...this[kCounters] }; } }); SequenceFlow.prototype.take = function take(content) { const sequenceId = content?.sequenceId; this.logger.debug(`<${sequenceId} (${this.id})> take, target <${this.targetId}>`); ++this[kCounters].take; this._publishEvent('take', content); return true; }; SequenceFlow.prototype.discard = function discard(content = {}) { const sequenceId = content?.sequenceId ?? (0, _shared.getUniqueId)(this.id); const discardSequence = content.discardSequence = (content.discardSequence || []).slice(); if (discardSequence.indexOf(this.targetId) > -1) { ++this[kCounters].looped; this.logger.debug(`<${this.id}> discard loop detected <${this.sourceId}> -> <${this.targetId}>. Stop.`); return this._publishEvent('looped', content); } discardSequence.push(this.sourceId); this.logger.debug(`<${sequenceId} (${this.id})> discard, target <${this.targetId}>`); ++this[kCounters].discard; this._publishEvent('discard', content); }; SequenceFlow.prototype.getState = function getState() { const brokerState = this.broker.getState(true); if (!brokerState && this.environment.settings.disableTrackState) return; return { id: this.id, type: this.type, counters: this.counters, broker: brokerState }; }; SequenceFlow.prototype.recover = function recover(state) { Object.assign(this[kCounters], state.counters); this.broker.recover(state.broker); }; SequenceFlow.prototype.getApi = function getApi(message) { return (0, _Api.FlowApi)(this.broker, message || { content: this.createMessage() }); }; SequenceFlow.prototype.stop = function stop() { this.broker.stop(); }; SequenceFlow.prototype.shake = function shake(message) { const content = (0, _messageHelper.cloneContent)(message.content); content.sequence = content.sequence || []; content.sequence.push({ id: this.id, type: this.type, isSequenceFlow: true, targetId: this.targetId }); if (content.id === this.targetId) return this.broker.publish('event', 'flow.shake.loop', content, { persistent: false, type: 'shake' }); for (const s of message.content.sequence || []) { if (s.id === this.id) return this.broker.publish('event', 'flow.shake.loop', content, { persistent: false, type: 'shake' }); } this.broker.publish('event', 'flow.shake', content, { persistent: false, type: 'shake' }); }; SequenceFlow.prototype.getCondition = function getCondition() { const conditionExpression = this.behaviour.conditionExpression; if (!conditionExpression) return null; const { language } = conditionExpression; const script = this.environment.getScript(language, this); if (script) { return new _condition.ScriptCondition(this, script, language); } if (!conditionExpression.body) { const msg = language ? `Condition expression script ${language} is unsupported or was not registered` : 'Condition expression without body is unsupported'; return this.emitFatal(new Error(msg), this.createMessage()); } return new _condition.ExpressionCondition(this, conditionExpression.body); }; SequenceFlow.prototype.createMessage = function createMessage(override) { return { ...override, id: this.id, type: this.type, name: this.name, sourceId: this.sourceId, targetId: this.targetId, isSequenceFlow: true, isDefault: this.isDefault, parent: (0, _messageHelper.cloneParent)(this.parent) }; }; SequenceFlow.prototype.evaluate = function evaluate(fromMessage, callback) { if (this.isDefault) { return callback(null, true); } const flowCondition = this.getCondition(); if (!flowCondition) { return callback(null, true); } flowCondition.execute(fromMessage, callback); }; SequenceFlow.prototype._publishEvent = function publishEvent(action, content) { const eventContent = this.createMessage({ action, ...content }); this.broker.publish('event', `flow.${action}`, eventContent, { type: action }); };