/* eslint-disable no-console */ const Redux = require('redux'); const ReduxThunk = require('redux-thunk').default; const Plugin = require('../models/Plugin'); const Context = require('../models/Context'); const coreReducers = require('../reducers'); const composeReducer = require('./composeReducer'); const Components = require('../actions/components'); const I18n = require('../actions/i18n'); const Navigation = require('../actions/navigation'); const isBrowser = (typeof window !== 'undefined'); const corePlugin = new Plugin({ reduce: coreReducers, actions: { Components, I18n, Navigation } }); /** * Create a new context containing redux store from an initial state and a list of plugins. * Each plugin entry is the result of {createPlugin}. * * @param {Array} plugins * @param {Object} initialState * @return {Context} context */ function createContext(plugins, initialState) { plugins = [corePlugin].concat(plugins); // Compose the reducer from core with plugins const pluginReducers = plugins.map(plugin => plugin.reduce); const reducer = composeReducer(...pluginReducers); // Get actions from all plugins const actions = plugins.reduce((accu, plugin) => { return Object.assign(accu, plugin.actions); }, {}); // Create thunk middleware which include actions const thunk = ReduxThunk.withExtraArgument(actions); // Create the redux store const store = Redux.createStore( (state, action) => { if (isBrowser) { console.log('[store]', action.type); } return reducer(state, action); }, initialState, Redux.compose(Redux.applyMiddleware(thunk)) ); // Initialize the plugins plugins.forEach(plugin => { plugin.init(store.dispatch, store.getState, actions); }); return new Context({ store, actions }); } module.exports = createContext;