Skip to content

Commit

Permalink
feat(store): create dynoStore
Browse files Browse the repository at this point in the history
adds the ability to code-splitting reducers in order to use them when needed

BREAKING CHANGE: initial store is replace by dynoStore

improves #32
  • Loading branch information
aneurysmjs committed Sep 21, 2019
1 parent c6146f6 commit 11d8576
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/app/store/config/configureStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ function configureStore() {
const store = createStore<{}, Actions, Dispatch<Actions>>(
reducer,
// persistedState,
// $FlowFixMe
composeEnhancers(applyMiddleware(...middlewares)), // third parameter is called an 'enhancer'
);
/* // Save the state any time the store state changes
Expand Down
64 changes: 64 additions & 0 deletions src/app/store/config/dynoStore/dynoStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* eslint-disable implicit-arrow-linebreak */
// @flow strict
import {
createStore as createReduxStore,
combineReducers,
} from 'redux';
import type { Dispatch } from 'redux';

// import type { State } from '@/store/types/State';
import type { Actions } from '@/store/types/Actions';

import reduceReducers from './reduceReducers';

let store = {};
const reducerMap = {};

// $FlowFixMe
const injectReducers = (_reducerMap): void => {
Object.entries(_reducerMap).forEach(([name, reducer]) => {
if (!reducerMap[name]) {
reducerMap[name] = [];
}
reducerMap[name].push(reducer);
});
};

const createRootReducer = () => (
// $FlowFixMe
combineReducers(Object.keys(reducerMap).reduce((result, key) => ({
...result,
[key]: reduceReducers(reducerMap[key]),
}), {}))
);

// $FlowFixMe
const createStore = (...args) => {
store = createReduxStore<{}, Actions, Dispatch<Actions>>(createRootReducer(), ...args);
return store;
};

const reloadStore = (): void => {
store.replaceReducer(createRootReducer());
// store.dispatch({ type: '@@replace-reducer' });
};

export const dynoStore = {
injectReducers,
createRootReducer,
createStore,
reloadStore,
};

export const withReloadStore = (importPromise: *): Promise<*> => (
importPromise
.then((module) => {
dynoStore.reloadStore();
return module;
},
(error) => {
throw error;
})
);

export default dynoStore;
4 changes: 4 additions & 0 deletions src/app/store/config/dynoStore/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// @flow strict

// eslint-disable-next-line import/prefer-default-export
export { default as dynoStore } from './dynoStore';
13 changes: 13 additions & 0 deletions src/app/store/config/dynoStore/reduceReducers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// @flow strict
import type { State } from '@/store/types/State';
import type { Actions } from '@/store/types/Actions';

type ReducersType = Array<($Shape<State>, Actions) => {}>;

const reduceReducers = (reducers: ReducersType) => (state: State, action: Actions) => (
reducers.reduce((result, reducer) => (
reducer(result, action)
), state)
);

export default reduceReducers;
21 changes: 21 additions & 0 deletions src/app/store/config/enhancers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @flow strict
import { compose, applyMiddleware } from 'redux';
import type { Dispatch, StoreEnhancer } from 'redux';

import middlewares from '@/store/config/middlewares';

import type { State } from '@/store/types/State';
import type { Actions } from '@/store/types/Actions';

type EnhancersType = StoreEnhancer<State, Actions, Dispatch<Actions>>
/* eslint-disable */
const devtools =
typeof window !== 'undefined' &&
typeof window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ === 'function' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ actionsBlacklist: [] });
/* eslint-enable */
const composeEnhancers = devtools || compose;
// eslint-disable-next-line no-underscore-dangle
const enhancer: EnhancersType = composeEnhancers(applyMiddleware(...middlewares));

export default enhancer;

0 comments on commit 11d8576

Please sign in to comment.