UNPKG

@genialis/resolwe

Version:
151 lines (149 loc) 16.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _ = require("lodash"); var angular = require("angular"); var serialization_1 = require("../utils/serialization"); /** * Manager of all stateful components' state. */ var StateManager = /** @class */ (function () { // @ngInject StateManager.$inject = ["sharedStoreManager"]; function StateManager(sharedStoreManager) { this._topLevelComponents = []; this._nextState = {}; this._sharedStoreManager = sharedStoreManager; } Object.defineProperty(StateManager.prototype, "sharedStoreManager", { /** * Returns the shared store manager. */ get: function () { return this._sharedStoreManager; }, enumerable: true, configurable: true }); /** * Adds a top-level component. * * @param component Top-level component instance */ StateManager.prototype.addTopLevelComponent = function (component) { this._topLevelComponents.push(component); }; /** * Removes a top-level component. * * @param component Top-level component instance */ StateManager.prototype.removeTopLevelComponent = function (component) { _.remove(this._topLevelComponents, component); }; /** * Returns the current top-level component. */ StateManager.prototype.topLevelComponents = function () { return this._topLevelComponents; }; /** * Saves a component's current state so it will be reloaded when the component * is next constructed. * * @param component Target component */ StateManager.prototype.savePendingComponentState = function (component) { _.assign(this._nextState, component.saveState(false)); }; /** * Loads any pending state for a specified component. State may be pending if * it gets loaded before the target component has been constructed. In this * case it will get loaded as soon as the target component gets constructed. * * @param component Target component */ StateManager.prototype.loadPendingComponentState = function (component) { var state = this._nextState[component.globalStateId]; if (!state) return; component.loadState(this._nextState, false); delete this._nextState[component.globalStateId]; }; /** * Returns application state by combining component.saveState of all * components and shared stores. * * When to use: * - saving state into memory (non-serialized), e.g. like components do * when they are destroyed * - when you just need to collect components' saveState * - if you need to store functions in state * When not to use: * - when saving state into a serialized form; use [[saveSerializableState]]. */ StateManager.prototype.save = function () { if (_.isEmpty(this._topLevelComponents)) return null; var states = _.map(this._topLevelComponents, function (component) { return component.saveState(); }); // Note: _.merge loses undefined values. `_.merge({}, {a:undefined}, {b:4})` returns {b:4}. var state = _.assign.apply(_, [{}].concat(states)); state['_stores'] = this._sharedStoreManager.saveState(); // Safeguard against incorrect usage of JSON.stringify. state['toJSON'] = function () { console.error("stateManager.save() is not serializable. Use stateManager.saveSerializableState() when you want to stringify\n state (and loadSerializableState after parse)."); return this; }; return state; }; /** * Loads existing application state. * * @param state Application state */ StateManager.prototype.load = function (state) { var _this = this; this._sharedStoreManager.loadState(state['_stores'] || {}); delete state['_stores']; this._nextState = state; _.each(this._topLevelComponents, function (component) { return component.loadState(_this._nextState); }); }; /** * Saves this component's current state and returns it in a format that is * safe to serialize. Values `undefined`, `NaN`, and `Infinity` are kept * when stringified with JSON.stringify. * * When to use: * - saving state into serialized forms, e.g. before transferring to backend * When not to use: * - to store functions */ StateManager.prototype.saveSerializableState = function () { var state = this.save(); if (!_.isNull(state)) { delete state['toJSON']; // Remove safeguard. } try { return serialization_1.makeSafelySerializable(state); } catch (e) { if (e instanceof serialization_1.SerializationError) { throw new serialization_1.SerializationError("Error saving state. " + e.message + " " + e.serializedValue, serialization_1.verboseSerialize(state)); } else { throw e; } } }; StateManager.prototype.loadSerializableState = function (serializableState) { var state = serialization_1.parseSafelySerializable(serializableState); return this.load(state); }; return StateManager; }()); exports.StateManager = StateManager; var angularModule = angular.module('resolwe.services.state_manager', [ 'resolwe.services.shared_store', ]); // Register the state manager as a service, so it can be used by components. angularModule.service('stateManager', StateManager); //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb3JlL2NvbXBvbmVudHMvbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDBCQUE0QjtBQUM1QixpQ0FBbUM7QUFJbkMsd0RBQTZIO0FBRTdIOztHQUVHO0FBQ0g7SUFNSSxZQUFZO0lBQ1osc0JBQVksa0JBQXNDO1FBTDFDLHdCQUFtQixHQUE0QixFQUFFLENBQUM7UUFFbEQsZUFBVSxHQUFRLEVBQUUsQ0FBQztRQUl6QixJQUFJLENBQUMsbUJBQW1CLEdBQUcsa0JBQWtCLENBQUM7SUFDbEQsQ0FBQztJQUtELHNCQUFXLDRDQUFrQjtRQUg3Qjs7V0FFRzthQUNIO1lBQ0ksT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUM7UUFDcEMsQ0FBQzs7O09BQUE7SUFFRDs7OztPQUlHO0lBQ0ksMkNBQW9CLEdBQTNCLFVBQTRCLFNBQWdDO1FBQ3hELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSw4Q0FBdUIsR0FBOUIsVUFBK0IsU0FBZ0M7UUFDM0QsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVEOztPQUVHO0lBQ0kseUNBQWtCLEdBQXpCO1FBQ0ksT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUM7SUFDcEMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksZ0RBQXlCLEdBQWhDLFVBQWlDLFNBQWdDO1FBQzdELENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLGdEQUF5QixHQUFoQyxVQUFpQyxTQUFnQztRQUM3RCxJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENB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T0FBTyxDQUFDLGNBQWMsRUFBRSxZQUFZLENBQUMsQ0FBQyIsImZpbGUiOiJjb3JlL2NvbXBvbmVudHMvbWFuYWdlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCAqIGFzIGFuZ3VsYXIgZnJvbSAnYW5ndWxhcic7XG5cbmltcG9ydCB7U3RhdGVmdWxDb21wb25lbnRCYXNlfSBmcm9tICcuL3N0YXRlZnVsJztcbmltcG9ydCB7U2hhcmVkU3RvcmVNYW5hZ2VyfSBmcm9tICcuLi9zaGFyZWRfc3RvcmUvaW5kZXgnO1xuaW1wb3J0IHttYWtlU2FmZWx5U2VyaWFsaXphYmxlLCBwYXJzZVNhZmVseVNlcmlhbGl6YWJsZSwgdmVyYm9zZVNlcmlhbGl6ZSwgU2VyaWFsaXphdGlvbkVycm9yfSBmcm9tICcuLi91dGlscy9zZXJpYWxpemF0aW9uJztcblxuLyoqXG4gKiBNYW5hZ2VyIG9mIGFsbCBzdGF0ZWZ1bCBjb21wb25lbnRzJyBzdGF0ZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFN0YXRlTWFuYWdlciB7XG4gICAgcHJpdmF0ZSBfc2hhcmVkU3RvcmVNYW5hZ2VyOiBTaGFyZWRTdG9yZU1hbmFnZXI7XG4gICAgcHJpdmF0ZSBfdG9wTGV2ZWxDb21wb25lbnRzOiBTdGF0ZWZ1bENvbXBvbmVudEJhc2VbXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBfbmV4dFN0YXRlOiBhbnkgPSB7fTtcblxuICAgIC8vIEBuZ0luamVjdFxuICAgIGNvbnN0cnVjdG9yKHNoYXJlZFN0b3JlTWFuYWdlcjogU2hhcmVkU3RvcmVNYW5hZ2VyKSB7XG4gICAgICAgIHRoaXMuX3NoYXJlZFN0b3JlTWFuYWdlciA9IHNoYXJlZFN0b3JlTWFuYWdlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzaGFyZWQgc3RvcmUgbWFuYWdlci5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHNoYXJlZFN0b3JlTWFuYWdlcigpOiBTaGFyZWRTdG9yZU1hbmFnZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcmVkU3RvcmVNYW5hZ2VyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSB0b3AtbGV2ZWwgY29tcG9uZW50LlxuICAgICAqXG4gICAgICogQHBhcmFtIGNvbXBvbmVudCBUb3AtbGV2ZWwgY29tcG9uZW50IGluc3RhbmNlXG4gICAgICovXG4gICAgcHVibGljIGFkZFRvcExldmVsQ29tcG9uZW50KGNvbXBvbmVudDogU3RhdGVmdWxDb21wb25lbnRCYXNlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX3RvcExldmVsQ29tcG9uZW50cy5wdXNoKGNvbXBvbmVudCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIHRvcC1sZXZlbCBjb21wb25lbnQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY29tcG9uZW50IFRvcC1sZXZlbCBjb21wb25lbnQgaW5zdGFuY2VcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVtb3ZlVG9wTGV2ZWxDb21wb25lbnQoY29tcG9uZW50OiBTdGF0ZWZ1bENvbXBvbmVudEJhc2UpOiB2b2lkIHtcbiAgICAgICAgXy5yZW1vdmUodGhpcy5fdG9wTGV2ZWxDb21wb25lbnRzLCBjb21wb25lbnQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgdG9wLWxldmVsIGNvbXBvbmVudC5cbiAgICAgKi9cbiAgICBwdWJsaWMgdG9wTGV2ZWxDb21wb25lbnRzKCk6IFN0YXRlZnVsQ29tcG9uZW50QmFzZVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RvcExldmVsQ29tcG9uZW50cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTYXZlcyBhIGNvbXBvbmVudCdzIGN1cnJlbnQgc3RhdGUgc28gaXQgd2lsbCBiZSByZWxvYWRlZCB3aGVuIHRoZSBjb21wb25lbnRcbiAgICAgKiBpcyBuZXh0IGNvbnN0cnVjdGVkLlxuICAgICAqXG4gICAgICogQHBhcmFtIGNvbXBvbmVudCBUYXJnZXQgY29tcG9uZW50XG4gICAgICovXG4gICAgcHVibGljIHNhdmVQZW5kaW5nQ29tcG9uZW50U3RhdGUoY29tcG9uZW50OiBTdGF0ZWZ1bENvbXBvbmVudEJhc2UpOiB2b2lkIHtcbiAgICAgICAgXy5hc3NpZ24odGhpcy5fbmV4dFN0YXRlLCBjb21wb25lbnQuc2F2ZVN0YXRlKGZhbHNlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTG9hZHMgYW55IHBlbmRpbmcgc3RhdGUgZm9yIGEgc3BlY2lmaWVkIGNvbXBvbmVudC4gU3RhdGUgbWF5IGJlIHBlbmRpbmcgaWZcbiAgICAgKiBpdCBnZXRzIGxvYWRlZCBiZWZvcmUgdGhlIHRhcmdldCBjb21wb25lbnQgaGFzIGJlZW4gY29uc3RydWN0ZWQuIEluIHRoaXNcbiAgICAgKiBjYXNlIGl0IHdpbGwgZ2V0IGxvYWRlZCBhcyBzb29uIGFzIHRoZSB0YXJnZXQgY29tcG9uZW50IGdldHMgY29uc3RydWN0ZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY29tcG9uZW50IFRhcmdldCBjb21wb25lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgbG9hZFBlbmRpbmdDb21wb25lbnRTdGF0ZShjb21wb25lbnQ6IFN0YXRlZnVsQ29tcG9uZW50QmFzZSk6IHZvaWQge1xuICAgICAgICBjb25zdCBzdGF0ZSA9IHRoaXMuX25leHRTdGF0ZVtjb21wb25lbnQuZ2xvYmFsU3RhdGVJZF07XG4gICAgICAgIGlmICghc3RhdGUpIHJldHVybjtcblxuICAgICAgICBjb21wb25lbnQubG9hZFN0YXRlKHRoaXMuX25leHRTdGF0ZSwgZmFsc2UpO1xuICAgICAgICBkZWxldGUgdGhpcy5fbmV4dFN0YXRlW2NvbXBvbmVudC5nbG9iYWxTdGF0ZUlkXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFwcGxpY2F0aW9uIHN0YXRlIGJ5IGNvbWJpbmluZyBjb21wb25lbnQuc2F2ZVN0YXRlIG9mIGFsbFxuICAgICAqIGNvbXBvbmVudHMgYW5kIHNoYXJlZCBzdG9yZXMuXG4gICAgICpcbiAgICAgKiBXaGVuIHRvIHVzZTpcbiAgICAgKiAgIC0gc2F2aW5nIHN0YXRlIGludG8gbWVtb3J5IChub24tc2VyaWFsaXplZCksIGUuZy4gbGlrZSBjb21wb25lbnRzIGRvXG4gICAgICogICAgIHdoZW4gdGhleSBhcmUgZGVzdHJveWVkXG4gICAgICogICAtIHdoZW4geW91IGp1c3QgbmVlZCB0byBjb2xsZWN0IGNvbXBvbmVudHMnIHNhdmVTdGF0ZVxuICAgICAqICAgLSBpZiB5b3UgbmVlZCB0byBzdG9yZSBmdW5jdGlvbnMgaW4gc3RhdGVcbiAgICAgKiBXaGVuIG5vdCB0byB1c2U6XG4gICAgICogICAtIHdoZW4gc2F2aW5nIHN0YXRlIGludG8gYSBzZXJpYWxpemVkIGZvcm07IHVzZSBbW3NhdmVTZXJpYWxpemFibGVTdGF0ZV1dLlxuICAgICAqL1xuICAgIHB1YmxpYyBzYXZlKCk6IGFueSB7XG4gICAgICAgIGlmIChfLmlzRW1wdHkodGhpcy5fdG9wTGV2ZWxDb21wb25lbnRzKSkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgY29uc3Qgc3RhdGVzID0gXy5tYXAodGhpcy5fdG9wTGV2ZWxDb21wb25lbnRzLCAoY29tcG9uZW50KSA9PiBjb21wb25lbnQuc2F2ZVN0YXRlKCkpO1xuICAgICAgICAvLyBOb3RlOiBfLm1lcmdlIGxvc2VzIHVuZGVmaW5lZCB2YWx1ZXMuIGBfLm1lcmdlKHt9LCB7YTp1bmRlZmluZWR9LCB7Yjo0fSlgIHJldHVybnMge2I6NH0uXG4gICAgICAgIGNvbnN0IHN0YXRlID0gXy5hc3NpZ24oe30sIC4uLnN0YXRlcyk7XG5cbiAgICAgICAgc3RhdGVbJ19zdG9yZXMnXSA9IHRoaXMuX3NoYXJlZFN0b3JlTWFuYWdlci5zYXZlU3RhdGUoKTtcblxuICAgICAgICAvLyBTYWZlZ3VhcmQgYWdhaW5zdCBpbmNvcnJlY3QgdXNhZ2Ugb2YgSlNPTi5zdHJpbmdpZnkuXG4gICAgICAgIHN0YXRlWyd0b0pTT04nXSA9IGZ1bmN0aW9uICh0aGlzOiBhbnkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYHN0YXRlTWFuYWdlci5zYXZlKCkgaXMgbm90IHNlcmlhbGl6YWJsZS4gVXNlIHN0YXRlTWFuYWdlci5zYXZlU2VyaWFsaXphYmxlU3RhdGUoKSB3aGVuIHlvdSB3YW50IHRvIHN0cmluZ2lmeVxuICAgICAgICAgICAgICAgIHN0YXRlIChhbmQgbG9hZFNlcmlhbGl6YWJsZVN0YXRlIGFmdGVyIHBhcnNlKS5gKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTG9hZHMgZXhpc3RpbmcgYXBwbGljYXRpb24gc3RhdGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc3RhdGUgQXBwbGljYXRpb24gc3RhdGVcbiAgICAgKi9cbiAgICBwdWJsaWMgbG9hZChzdGF0ZTogYW55KTogdm9pZCB7XG4gICAgICAgIHRoaXMuX3NoYXJlZFN0b3JlTWFuYWdlci5sb2FkU3RhdGUoc3RhdGVbJ19zdG9yZXMnXSB8fCB7fSk7XG4gICAgICAgIGRlbGV0ZSBzdGF0ZVsnX3N0b3JlcyddO1xuICAgICAgICB0aGlzLl9uZXh0U3RhdGUgPSBzdGF0ZTtcblxuICAgICAgICBfLmVhY2godGhpcy5fdG9wTGV2ZWxDb21wb25lbnRzLCAoY29tcG9uZW50KSA9PiBjb21wb25lbnQubG9hZFN0YXRlKHRoaXMuX25leHRTdGF0ZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNhdmVzIHRoaXMgY29tcG9uZW50J3MgY3VycmVudCBzdGF0ZSBhbmQgcmV0dXJucyBpdCBpbiBhIGZvcm1hdCB0aGF0IGlzXG4gICAgICogc2FmZSB0byBzZXJpYWxpemUuIFZhbHVlcyBgdW5kZWZpbmVkYCwgYE5hTmAsIGFuZCBgSW5maW5pdHlgIGFyZSBrZXB0XG4gICAgICogd2hlbiBzdHJpbmdpZmllZCB3aXRoIEpTT04uc3RyaW5naWZ5LlxuICAgICAqXG4gICAgICogV2hlbiB0byB1c2U6XG4gICAgICogICAtIHNhdmluZyBzdGF0ZSBpbnRvIHNlcmlhbGl6ZWQgZm9ybXMsIGUuZy4gYmVmb3JlIHRyYW5zZmVycmluZyB0byBiYWNrZW5kXG4gICAgICogV2hlbiBub3QgdG8gdXNlOlxuICAgICAqICAgLSB0byBzdG9yZSBmdW5jdGlvbnNcbiAgICAgKi9cbiAgICBwdWJsaWMgc2F2ZVNlcmlhbGl6YWJsZVN0YXRlKCk6IGFueSB7XG4gICAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5zYXZlKCk7XG4gICAgICAgIGlmICghXy5pc051bGwoc3RhdGUpKSB7XG4gICAgICAgICAgICBkZWxldGUgc3RhdGVbJ3RvSlNPTiddOyAvLyBSZW1vdmUgc2FmZWd1YXJkLlxuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBtYWtlU2FmZWx5U2VyaWFsaXphYmxlKHN0YXRlKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBTZXJpYWxpemF0aW9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKGBFcnJvciBzYXZpbmcgc3RhdGUuICR7ZS5tZXNzYWdlfSAke2Uuc2VyaWFsaXplZFZhbHVlfWAsIHZlcmJvc2VTZXJpYWxpemUoc3RhdGUpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBsb2FkU2VyaWFsaXphYmxlU3RhdGUoc2VyaWFsaXphYmxlU3RhdGU6IGFueSk6IHZvaWQge1xuICAgICAgICBjb25zdCBzdGF0ZSA9IHBhcnNlU2FmZWx5U2VyaWFsaXphYmxlKHNlcmlhbGl6YWJsZVN0YXRlKTtcbiAgICAgICAgcmV0dXJuIHRoaXMubG9hZChzdGF0ZSk7XG4gICAgfVxuXG59XG5cbmNvbnN0IGFuZ3VsYXJNb2R1bGU6IGFuZ3VsYXIuSU1vZHVsZSA9IGFuZ3VsYXIubW9kdWxlKCdyZXNvbHdlLnNlcnZpY2VzLnN0YXRlX21hbmFnZXInLCBbXG4gICAgJ3Jlc29sd2Uuc2VydmljZXMuc2hhcmVkX3N0b3JlJyxcbl0pO1xuXG4vLyBSZWdpc3RlciB0aGUgc3RhdGUgbWFuYWdlciBhcyBhIHNlcnZpY2UsIHNvIGl0IGNhbiBiZSB1c2VkIGJ5IGNvbXBvbmVudHMuXG5hbmd1bGFyTW9kdWxlLnNlcnZpY2UoJ3N0YXRlTWFuYWdlcicsIFN0YXRlTWFuYWdlcik7XG4iXX0=