Skip to content

Commit

Permalink
Next (#13)
Browse files Browse the repository at this point in the history
Next
  • Loading branch information
pofigizm authored Nov 22, 2019
2 parents 4f83dff + 3170aaa commit 91aaa5a
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ lib/
node_modules/
*.swp
package-lock.json
.idea/
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "redux-dynamic",
"version": "1.2.0",
"version": "1.3.0",
"description": "Allow add or remove redux modules dynamically",
"main": "lib/index.js",
"scripts": {
Expand Down
66 changes: 66 additions & 0 deletions src/create-instance-flat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { createDynamicMiddlewares } from 'redux-dynamic-middlewares'
import { combineReducers } from 'redux';

import { configureStore } from './configure-store'
import { reloadState } from './reload-state'
import { createAttach } from './create-attach'
import { createDetach } from './create-detach'

const emptyMiddleware = () => next => action => next(action)
const emptyReducer = (state = {}) => state

const createInstanceFlat = ({
name = 'redux-dynamic',
key = '__EMPTY__',
initial = {},
thunk = {},
reducer = emptyReducer,
middleware = emptyMiddleware,
withDevTools,
} = {}) => {
const dynamicMiddlewares = createDynamicMiddlewares()
const reducerWrapper = reducer.wrapper ? reducer.wrapper : combineReducers
const reducerInitial = reducer.wrapper ? reducer.wrapper(reducer.reducers) : emptyReducer
const reducers = reducer.reducers ? { ...reducer.reducers } : { [key]: (state = initial, action) => reducer(state, action) }

dynamicMiddlewares.addMiddleware(middleware)

const registry = {
keys: {
[key]: true,
},
reducers,
reducerWrapper,
thunks: {
[key]: thunk,
},
middlewares: {
[key]: middleware,
},
}

const store = configureStore({
name,
withDevTools,
key,
initial,
reducer: reducerInitial,
dynamicMiddlewares: dynamicMiddlewares.enhancer,
})

reloadState(registry, store, dynamicMiddlewares)

const getStore = () => store
const attach = createAttach(registry, store, dynamicMiddlewares)
const detach = createDetach(registry, store, dynamicMiddlewares)

return {
getStore,
attach,
detach,
}
}

export {
createInstanceFlat,
}
2 changes: 2 additions & 0 deletions src/create-instance.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { combineReducers } from 'redux'
import { createDynamicMiddlewares } from 'redux-dynamic-middlewares'

import { configureStore } from './configure-store'
Expand Down Expand Up @@ -25,6 +26,7 @@ const createInstance = ({
reducers: {
[key]: (state = initial, action) => reducer(state, action),
},
reducerWrapper: combineReducers,
thunks: {
[key]: thunk,
},
Expand Down
82 changes: 82 additions & 0 deletions src/index-flat.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/* eslint-disable no-console */
import { createInstanceFlat } from './index'

const reducer = (state = {}, action) => {
if (action.type === 'foo') return { ...state, foo: 'bar' }
return state
}

const complexReducer = {
reducers: {
one: reducer,
},
}

test('flat - without params', () => {
console.error = jest.fn()

const dynamicStore = createInstanceFlat()

const store = dynamicStore.getStore()
expect(store.getState()).toEqual({ __EMPTY__: {} })

store.dispatch({ type: 'foo' })
expect(console.error).not.toBeCalled()
})

test('flat - one module with simple reducer', () => {
console.error = jest.fn()

const dynamicStore = createInstanceFlat({ key: 'key', reducer })

const store = dynamicStore.getStore()
expect(store.getState()).toEqual({ key: {} })

store.dispatch({ type: 'foo' })
expect(console.error).not.toBeCalled()
expect(store.getState()).toEqual({ key: { foo: 'bar' } })
})

test('flat - one module with complex reducer', () => {
console.error = jest.fn()

const dynamicStore = createInstanceFlat({ key: 'key', reducer: complexReducer })

const store = dynamicStore.getStore()
expect(store.getState()).toEqual({ one: {} })

store.dispatch({ type: 'foo' })
expect(console.error).not.toBeCalled()
expect(store.getState()).toEqual({ one: { foo: 'bar' } })
})

test('flat - attach and detach module', () => {
console.error = jest.fn()

const dynamicStore = createInstanceFlat({ key: 'key', reducer: complexReducer })
dynamicStore.attach({ key: 'two', reducer })

const store = dynamicStore.getStore()
expect(store.getState()).toEqual({ one: {}, two: {} })

store.dispatch({ type: 'foo' })
expect(console.error).not.toBeCalled()
expect(store.getState()).toEqual({ one: { foo: 'bar' }, two: { foo: 'bar' } })

dynamicStore.detach({ key: 'two' })
expect(store.getState()).toEqual({ one: { foo: 'bar' } })
})

test('flat - initials', () => {
const initial = { one: 'bar' }
const initial2 = { foo: 'bar' }

const dynamicStore = createInstanceFlat({ key: 'key', initial, reducer: complexReducer })
dynamicStore.attach({ key: 'two', initial: initial2 })

const store = dynamicStore.getStore()
expect(store.getState()).toEqual({ one: 'bar', two: { foo: 'bar' } })

dynamicStore.detach({ key: 'two' })
expect(store.getState()).toEqual({ one: 'bar' })
})
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { createInstance } from './create-instance'
import { createInstanceFlat } from './create-instance-flat'
import { prepareActions } from './prepare-actions'

export {
createInstance,
createInstanceFlat,
prepareActions,
}
3 changes: 1 addition & 2 deletions src/reload-state.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { combineReducers } from 'redux'
import thunkMiddleware from 'redux-thunk'

const reloadState = (registry, store, dynamicMiddlewares) => {
store.replaceReducer(combineReducers(registry.reducers))
store.replaceReducer(registry.reducerWrapper(registry.reducers))
dynamicMiddlewares.resetMiddlewares()

const thunkObject = thunkMiddleware.withExtraArgument(registry.thunks)
Expand Down

0 comments on commit 91aaa5a

Please sign in to comment.