@gongt/ts-stl-client
Version:
164 lines • 6.11 kB
JavaScript
;
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