UNPKG

@rxx/worker

Version:

React MVI micro framework.

211 lines (210 loc) 8.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var rxjs_1 = require("rxjs"); var intent_1 = require("./intent/intent"); var state_handler_1 = require("./handler/state-handler"); var utils_1 = require("./utils"); var combine_template_1 = require("./observable/combine-template"); var subject_1 = require("./subject"); var StoreGroup = (function () { function StoreGroup(intent, stores, service, subject) { this.intent = intent; this.stores = stores; this.service = service; this.subject = subject; this.storeInstances = []; } StoreGroup.prototype.initialize = function () { var _this = this; return this.stores.reduce(function (state, Store) { var store = new Store(_this.intent, _this.service, _this.subject.observable); var nextState = store.initialize(); _this.storeInstances.push(store); if (nextState.view) { state.view = utils_1.mergeDeep(state.view, nextState.view); } for (var key in nextState) { if (key !== 'view') { if (!nextState[key] || !(nextState[key] instanceof rxjs_1.Observable)) { throw new Error("Property " + key + " must be Observable."); } if (state[key]) { state[key] = state[key].merge(nextState[key]); } else { state[key] = nextState[key]; } } } return state; }, { view: {} }); }; StoreGroup.prototype.getStores = function () { return this.storeInstances; }; return StoreGroup; }()); var BUFFERING_TIME = 10; var Provisioning = (function () { function Provisioning(intentConstructors, storeConstructors, stateFactory, service, stateHandlers, intentAdvice) { if (stateFactory === void 0) { stateFactory = function (_, a) { return a; }; } if (service === void 0) { service = {}; } if (stateHandlers === void 0) { stateHandlers = {}; } if (intentAdvice === void 0) { intentAdvice = function (v) { return v; }; } this.intentConstructors = intentConstructors; this.storeConstructors = storeConstructors; this.stateFactory = stateFactory; this.service = service; this.stateHandlers = stateHandlers; this.intentAdvice = intentAdvice; this.isDisposed = false; this.handlerSubscriptions = []; this.subscribers = []; this.handlers = {}; this.cache = null; } Provisioning.prototype.dispose = function (removeCache) { if (removeCache === void 0) { removeCache = true; } this.isDisposed = true; this.subscription && this.subscription.unsubscribe(); this.subscription = null; this.handlerSubscriptions.forEach(function (s) { return s.unsubscribe(); }); if (removeCache) { this.cache = null; } }; Provisioning.prototype.prepare = function (parentState) { var _this = this; if (parentState === void 0) { parentState = {}; } if (!this.intent) { this.intent = new intent_1.Intent(); this.subject = new subject_1.SubjectTree(); } this.handlers = state_handler_1.getHandlers(); if (this.stateHandlers) { utils_1.forIn(this.stateHandlers, function (v, k) { _this.handlers[k] = v; }); } if (!this.cache) { this.cache = {}; var intentInstance = {}; for (var key in this.intentConstructors) { intentInstance[key] = this.intentAdvice(new this.intentConstructors[key](function (type, payload) { _this.subject.notify({ type: type, payload: payload }); _this.intent.push(type, payload); }, tslib_1.__assign({ intent: this.intent.response }, utils_1.mapValues(this.handlers, function (v) { return v.response; })))); } this.cache.intentInstance = intentInstance; var storeGroup = (this.cache.storeGroup = new StoreGroup(intentInstance, this.storeConstructors, this.service, this.subject)); this.cache.storeState = this.stateFactory(this.subject.observable, storeGroup.initialize()); this.cache.stores = storeGroup.getStores(); } var intentHandler = function (type, payload) { _this.intent.push(type, payload); _this.subject.notify({ type: type, payload: payload }); }; utils_1.forIn(this.handlers, function (handler) { handler.setIntent(intentHandler); handler.setSubject(_this.subject); }); if (this.isDisposed || !this.subscription) { var state = tslib_1.__assign({}, this.cache.storeState); this.subscribeHandler(state); var firstTime_1 = true; var timer_1 = 0; this.subscription = combine_template_1.combineTemplate(state).subscribe(function (state) { if (firstTime_1) { firstTime_1 = false; state.view = tslib_1.__assign({}, parentState, state.view); _this.notifyUpdate(state); } else { clearTimeout(timer_1); timer_1 = setTimeout(function () { state.view = tslib_1.__assign({}, parentState, state.view); _this.notifyUpdate(state); }, BUFFERING_TIME); } }, function (error) { console.error(error); }); } this.isDisposed = false; }; Provisioning.prototype.emitAsync = function (emitter) { setTimeout(emitter, BUFFERING_TIME); }; Provisioning.prototype.getPublisher = function () { var _this = this; var ret = function (type, payload) { _this.intent.push(type, payload); _this.subject.notify({ type: type, payload: payload }); }; ret.subscribe = function (callback) { _this.intent.subscribeEvent(function (type, payload) { return callback({ type: type, payload: payload }); }); _this.subject.subscribe(callback); }; ret.unsubscribe = function () { _this.intent.unsubscribeAll(); _this.subject.unsubscribeAll(); }; return ret; }; Provisioning.prototype.getState = function () { return this.state; }; Provisioning.prototype.getHandlers = function () { return this.handlers; }; Provisioning.prototype.subscribe = function (subscriber, runInitial) { var _this = this; if (runInitial === void 0) { runInitial = false; } this.subscribers.push(subscriber); if (runInitial) { subscriber(this.state, true); } return function () { var index = -1; _this.subscribers.some(function (v, i) { if (v === subscriber) { index = i; return true; } return false; }); _this.subscribers.splice(index, 1); }; }; Provisioning.prototype.getStores = function () { return this.cache.storeGroup.getStores(); }; Provisioning.prototype.getIntentInstance = function () { return this.cache.intentInstance; }; Provisioning.prototype.subscribeHandler = function (state) { for (var key in this.handlers) { this.handlerSubscriptions.push(this.handlers[key].subscribe(state)); } }; Provisioning.prototype.notifyUpdate = function (newState) { this.state = newState; this.subject.setState(newState); this.intent.setState(newState); utils_1.forIn(this.handlers, function (v) { return v.setState(newState); }); this.subscribers.forEach(function (subscriber) { return subscriber(newState); }); }; Provisioning.prototype.notifyUpdateView = function (viewState) { var _this = this; this.state.view = viewState; this.subject.setState(this.state); this.intent.setState(this.state); utils_1.forIn(this.handlers, function (v) { return v.setState(_this.state); }); this.subscribers.forEach(function (subscriber) { return subscriber(_this.state); }); }; return Provisioning; }()); exports.Provisioning = Provisioning;