UNPKG

@robotlegsjs/core

Version:

An architecture-based IoC framework for JavaScript/TypeScript

207 lines 8.45 kB
"use strict"; // ------------------------------------------------------------------------------ // Copyright (c) 2017-present, RobotlegsJS. All Rights Reserved. // // NOTICE: You are permitted to use, modify, and distribute this file // in accordance with the terms of the license agreement accompanying it. // ------------------------------------------------------------------------------ Object.defineProperty(exports, "__esModule", { value: true }); exports.LifecycleTransition = void 0; var LifecycleEvent_1 = require("../api/LifecycleEvent"); var MessageDispatcher_1 = require("./MessageDispatcher"); var safelyCallBack_1 = require("./safelyCallBack"); /** * Handles a lifecycle transition * * @private */ var LifecycleTransition = /** @class */ (function () { /*============================================================================*/ /* Constructor */ /*============================================================================*/ /** * Creates a lifecycle transition * * @param name The name of the transition * @param lifecycle The associated lifecycle instance */ function LifecycleTransition(name, lifecycle) { /*============================================================================*/ /* Private Properties */ /*============================================================================*/ this._fromStates = []; this._dispatcher = new MessageDispatcher_1.MessageDispatcher(); this._callbacks = []; this._reverse = false; this._name = name; this._lifecycle = lifecycle; } /*============================================================================*/ /* Public Functions */ /*============================================================================*/ /** * States that this transition is allowed to enter from * * @param states Allowed states * @return Self */ LifecycleTransition.prototype.fromStates = function () { var _this = this; var states = []; for (var _i = 0; _i < arguments.length; _i++) { states[_i] = arguments[_i]; } states.forEach(function (state) { _this._fromStates.push(state); }); return this; }; /** * The states that this transition applies * * @param transitionState The state that the target is put into during the transition * @param finalState The state that the target is put into after the transition * @return */ LifecycleTransition.prototype.toStates = function (transitionState, finalState) { this._transitionState = transitionState; this._finalState = finalState; return this; }; /** * The events that the lifecycle will dispatch * * @param preTransitionEvent * @param transitionEvent * @param postTransitionEvent * @return Self */ LifecycleTransition.prototype.withEvents = function (preTransitionEvent, transitionEvent, postTransitionEvent) { this._preTransitionEvent = preTransitionEvent; this._transitionEvent = transitionEvent; this._postTransitionEvent = postTransitionEvent; if (this._reverse) { this._lifecycle.addReversedEventTypes(preTransitionEvent, transitionEvent, postTransitionEvent); } return this; }; /** * Reverse the dispatch order of this transition * * @return Self */ LifecycleTransition.prototype.inReverse = function () { this._reverse = true; this._lifecycle.addReversedEventTypes(this._preTransitionEvent, this._transitionEvent, this._postTransitionEvent); return this; }; /** * A handler to run before the transition runs * * @param handler Possibly asynchronous before handler * @return Self */ LifecycleTransition.prototype.addBeforeHandler = function (handler) { this._dispatcher.addMessageHandler(this._name, handler); return this; }; /** * Attempts to enter the transition * * @param callback Completion callback */ LifecycleTransition.prototype.enter = function (callback) { var _this = this; // immediately call back if we have already transitioned, and exit if (this._lifecycle.state === this._finalState) { if (callback) { safelyCallBack_1.safelyCallBack(callback, null, this._name); } return; } // queue this callback if we are mid transition, and exit if (this._lifecycle.state === this._transitionState) { if (callback) { this._callbacks.push(callback); } return; } // report invalid transition, and exit if (this._invalidTransition()) { this._reportError("Invalid transition", [callback]); return; } // store the initial lifecycle state in case we need to roll back var initialState = this._lifecycle.state; // queue the first callback if (callback) { this._callbacks.push(callback); } // put lifecycle into transition state this._setState(this._transitionState); // run before handlers this._dispatcher.dispatchMessage(this._name, function (error) { // revert state, report error, and exit if (error) { _this._setState(initialState); _this._reportError(error, _this._callbacks); return; } // dispatch pre transition and transition events _this._dispatch(_this._preTransitionEvent); _this._dispatch(_this._transitionEvent); // put lifecycle into final state _this._setState(_this._finalState); // process callback queue (dup and trash for safety) var callbacks = _this._callbacks.concat(); _this._callbacks.length = 0; callbacks.forEach(function (callbackChild) { safelyCallBack_1.safelyCallBack(callbackChild, null, _this._name); }); // dispatch post transition event _this._dispatch(_this._postTransitionEvent); }, this._reverse); }; /*============================================================================*/ /* Private Functions */ /*============================================================================*/ LifecycleTransition.prototype._invalidTransition = function () { return (this._fromStates.length > 0 && this._fromStates.indexOf(this._lifecycle.state) === -1); }; LifecycleTransition.prototype._setState = function (state) { if (state) { this._lifecycle.setCurrentState(state); } }; LifecycleTransition.prototype._dispatch = function (type) { if (type && this._lifecycle.hasEventListener(type)) { this._lifecycle.dispatchEvent(new LifecycleEvent_1.LifecycleEvent(type)); } }; LifecycleTransition.prototype._reportError = function (message, callbacks) { var _this = this; // turn message into Error var error = message instanceof Error ? message : new Error(message); // dispatch error event if a listener exists, or throw if (this._lifecycle.hasEventListener(LifecycleEvent_1.LifecycleEvent.ERROR)) { var event_1 = new LifecycleEvent_1.LifecycleEvent(LifecycleEvent_1.LifecycleEvent.ERROR, error); this._lifecycle.dispatchEvent(event_1); // process callback queue if (callbacks) { callbacks.forEach(function (callback) { if (callback) { safelyCallBack_1.safelyCallBack(callback, error, _this._name); } }); callbacks.length = 0; } } else { // explode! throw error; } }; return LifecycleTransition; }()); exports.LifecycleTransition = LifecycleTransition; //# sourceMappingURL=LifecycleTransition.js.map