mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-16 13:13:03 +00:00
93 lines
2.6 KiB
JavaScript
93 lines
2.6 KiB
JavaScript
/**
|
|
* @file
|
|
* @copyright 2020 Aleksej Komarov
|
|
* @license MIT
|
|
*/
|
|
|
|
import { flow } from 'common/fp';
|
|
import { applyMiddleware, combineReducers, createStore } from 'common/redux';
|
|
import { Component } from 'inferno';
|
|
import { assetMiddleware } from './assets';
|
|
import { backendMiddleware, backendReducer } from './backend';
|
|
import { debugMiddleware, debugReducer, relayMiddleware } from './debug';
|
|
import { createLogger } from './logging';
|
|
|
|
const logger = createLogger('store');
|
|
|
|
export const configureStore = (options = {}) => {
|
|
const { sideEffects = true } = options;
|
|
const reducer = flow([
|
|
combineReducers({
|
|
debug: debugReducer,
|
|
backend: backendReducer,
|
|
}),
|
|
options.reducer,
|
|
]);
|
|
const middleware = !sideEffects
|
|
? []
|
|
: [...(options.middleware?.pre || []), assetMiddleware, backendMiddleware, ...(options.middleware?.post || [])];
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
// We are using two if statements because Webpack is capable of
|
|
// removing this specific block as dead code.
|
|
if (sideEffects) {
|
|
middleware.unshift(loggingMiddleware, debugMiddleware, relayMiddleware);
|
|
}
|
|
}
|
|
const enhancer = applyMiddleware(...middleware);
|
|
const store = createStore(reducer, enhancer);
|
|
// Globals
|
|
window.__store__ = store;
|
|
window.__augmentStack__ = createStackAugmentor(store);
|
|
return store;
|
|
};
|
|
|
|
const loggingMiddleware = (store) => (next) => (action) => {
|
|
const { type, payload } = action;
|
|
if (type === 'update' || type === 'backend/update') {
|
|
logger.debug('action', { type });
|
|
} else {
|
|
logger.debug('action', action);
|
|
}
|
|
return next(action);
|
|
};
|
|
|
|
/**
|
|
* Creates a function, which can be assigned to window.__augmentStack__
|
|
* to augment reported stack traces with useful data for debugging.
|
|
*/
|
|
const createStackAugmentor = (store) => (stack, error) => {
|
|
if (!error) {
|
|
error = new Error(stack.split('\n')[0]);
|
|
error.stack = stack;
|
|
} else if (typeof error === 'object' && !error.stack) {
|
|
error.stack = stack;
|
|
}
|
|
logger.log('FatalError:', error);
|
|
const state = store.getState();
|
|
const config = state?.backend?.config;
|
|
let augmentedStack = stack;
|
|
augmentedStack += '\nUser Agent: ' + navigator.userAgent;
|
|
augmentedStack +=
|
|
'\nState: ' +
|
|
JSON.stringify({
|
|
ckey: config?.client?.ckey,
|
|
interface: config?.interface,
|
|
window: config?.window,
|
|
});
|
|
return augmentedStack;
|
|
};
|
|
|
|
/**
|
|
* Store provider for Inferno apps.
|
|
*/
|
|
export class StoreProvider extends Component {
|
|
getChildContext() {
|
|
const { store } = this.props;
|
|
return { store };
|
|
}
|
|
|
|
render() {
|
|
return this.props.children;
|
|
}
|
|
}
|