UNPKG

@gongt/ts-stl-client

Version:
164 lines 6.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const create_logger_1 = require("@gongt/ts-stl-library/debug/create-logger"); const levels_1 = require("@gongt/ts-stl-library/debug/levels"); const redux_1 = require("redux"); const combine_reducers_1 = require("./combine-reducers"); const store_internal_middleware_1 = require("./store.internal-middleware"); exports.REDUX_PRELOAD_NAME = '__REDUX_PRELOAD_DATA__'; const debug = create_logger_1.createLogger(levels_1.LOG_LEVEL.SILLY, 'redux-store'); /** * 根据逻辑函数(构造函数的参数)创建Store */ class ReduxStore { constructor(logicRegister) { this.processObject = []; this.subStore = {}; this.composeEnhancers = redux_1.compose; this.finished = false; this.middleware_callbacks = []; this.middlewares = store_internal_middleware_1.defaultMiddlewares.slice(); if (logicRegister) { if (Array.isArray(logicRegister)) { logicRegister.forEach((fn) => { fn(this); }); } else { logicRegister(this); } } } createStore(global) { if (global.has(exports.REDUX_PRELOAD_NAME)) { const preloadOrStoreObject = global.get(exports.REDUX_PRELOAD_NAME); if (typeof preloadOrStoreObject.getState === 'function') { debug(' create store: re-call, return last object.'); return preloadOrStoreObject; } } this.finished = true; const applicationLogic = this.combineReducers(); const dynamicMiddleware = this.middleware_callbacks.map((cb) => { return cb(global); }); const appliedMiddleware = redux_1.applyMiddleware(...this.middlewares, ...dynamicMiddleware); const createStoreEnhancer = this.composeEnhancers(appliedMiddleware); const enhancedCreateStore = createStoreEnhancer(redux_1.createStore); // TODO: <- this any const preloadState = this.getPreloadState(global); Object.keys(this.subStore).forEach((key) => { const st = this.subStore[key]; // console.log('%s: ', key, preloadState.hasOwnProperty(key), st.hasOwnProperty('defaultValue'), st); if (!preloadState.hasOwnProperty(key) && st.hasOwnProperty('defaultValue')) { preloadState[key] = st.defaultValue; } }); if (debug.enabled) { debug(' preloadState='); for (let name of Object.keys(preloadState)) { const v = preloadState[name]; debug(' %s -> %s', name, v.name || v.constructor.name || v); } } const store = enhancedCreateStore(applicationLogic, preloadState); store['toJSON'] = store.getState; this.processObject.forEach((fn) => { fn((f) => { f(store.getState()); return store.subscribe(() => { f(store.getState()); }); }, (act) => { if (act && act['toJSON']) { act = act['toJSON'](); } return store.dispatch(act); }); }); global.set(exports.REDUX_PRELOAD_NAME, store); return store; } /** 添加预处理 */ logicDisplayBorder(middleware) { if (this.finished) { throw new Error('ReduxStore: use middleware too late'); } this.processObject.push(middleware); } plugin(plugin) { plugin.__redux_plugin(this); } /** 添加子存储 */ register(Constructor) { if (this.finished) { throw new Error('ReduxStore: register sub store too late'); } const name = Constructor.name; // console.log('register sub store: ', name); if (this.subStore[name]) { throw new TypeError('duplicate store: ' + name); } this.subStore[name] = new Constructor(); } /** 添加中间件 */ use(middleware) { if (this.finished) { throw new Error('ReduxStore: use middleware too late'); } this.middlewares.push(middleware); } useDynamic(callback) { if (this.finished) { throw new Error('ReduxStore: use middleware too late'); } this.middleware_callbacks.push(callback); } useSimple(middleware) { if (this.finished) { throw new Error('ReduxStore: use middleware too late'); } const md = (state) => next => action => { const ret = middleware(state, action); if (!ret) { console.log('an action has been dropped: %s', action.type); return null; } else if (ret instanceof Promise) { ret.then((act) => { if (act) { next(act); } else { console.log('%can action has been dropped (after sync): %s', 'color:grey', action.type); } }, (e) => { console.error(e); throw new Error('simple middleware promise rejected.'); }); return null; } else { return next(action); } }; this.middlewares.push(md); } combineReducers() { const pass = []; for (const key of Object.keys(this.subStore)) { const st = this.subStore[key]; pass.push(...st.getReducers()); } return combine_reducers_1.MyCombineReducers(pass); } getPreloadState(global) { if (global.has(exports.REDUX_PRELOAD_NAME)) { const pl = global.get(exports.REDUX_PRELOAD_NAME); global.unset(exports.REDUX_PRELOAD_NAME); return pl; } return {}; } } exports.ReduxStore = ReduxStore; //# sourceMappingURL=store.js.map