Skip to content

Commit

Permalink
fix esm output
Browse files Browse the repository at this point in the history
  • Loading branch information
camille-hdl committed May 15, 2018
1 parent f68e0f5 commit 1afa086
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 63 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -28,6 +28,8 @@ type Map = {

## Usage

`npm install --save redux-combine-containers`

Let's say we have 2 react-redux containers, `document-viewer` and `document-list`. These module can be used standalone with their own state, actions and views.
We want to create a new `document-index` container, using these two submodules, with a single state tree, without duplicating code.

Expand Down
2 changes: 1 addition & 1 deletion __tests__/index.test.js
@@ -1,7 +1,7 @@
//@flow

import { fromJS } from "immutable";
import { getCombinedReducer, getCombinedDispatchToProps, getCombinedStateToProps } from "../esm/index.js";
import { getCombinedReducer, getCombinedDispatchToProps, getCombinedStateToProps } from "../index.js";

test("getCombinedReducer", () => {
const reducers = {
Expand Down
97 changes: 37 additions & 60 deletions esm/index.js
@@ -1,66 +1,48 @@
//@flow
import _Object$assign from '@babel/runtime/core-js/object/assign';
import _Object$entries from '@babel/runtime/core-js/object/entries';

/**
* Helpers to combine multiple redux containers props object (mapStateToProps/mapDispatchToProps pairs)
* into a single props object.
* Each individual container is identified by a key in the final object.
*/

/**
* mapStateToProps / mapDispatch to props pair.
*/
export type CombinedMapper = {
mapStateToProps: (state: Map) => any,
mapDispatchToProps: (dispatch: any, props: any) => any
};
/**
* mapStateToProps / mapDispatch to props pair.
*/

/**
* Simple definition of immutable.Map
*/
type Map = {
get: (key: any) => any,
set: (key: any, value: any) => Map
};

type ReduxAction = {
type: string,
data?: any
};

/**
* Naive object reduce implementation to avoid dependencies
*/
const reduceMappers = (mappers: {[key: string]: any}, fn: (accumulator: any, value: any) => any, initialValue: any) => {
return Object.entries(mappers).reduce(
(acc, pair: Array<any>) => {
return fn.call(null, acc, pair[1], pair[0]);
},
initialValue
);
const reduceMappers = (mappers, fn, initialValue) => {
return _Object$entries(mappers).reduce((acc, pair) => {
return fn.call(null, acc, pair[1], pair[0]);
}, initialValue);
};

/**
* This is essentially `combineReducers`: each sub-reducer gets his sub-state tree only.
*
* Example: "document" reducer : `state.set("document", reducers.document(state.get("document"), action));`
*
* If a reducer has a `global` key, this reducer will have access to the complete state tree.
*/
export const getCombinedReducer = (reducers: {[key: string]: (state: Map) => Map}) => {
return (state: Map, action: ReduxAction): Map => {
return reduceMappers(
reducers,
(curState: Map, reducer: (state: Map) => Map, key: string) => {
if (key === "global") {
return reducer(curState, action);
}
return curState.set(key, reducer(curState.get(key), action));
},
state
);
};
};


const getCombinedReducer = reducers => {
return (state, action) => {
return reduceMappers(reducers, (curState, reducer, key) => {
if (key === "global") {
return reducer(curState, action);
}

return curState.set(key, reducer(curState.get(key), action));
}, state);
};
};
/**
* The returned object (the final state tree) is a combination of `globalProps` with each sub-state trees.
*
Expand All @@ -69,25 +51,20 @@ export const getCombinedReducer = (reducers: {[key: string]: (state: Map) => Map
*
* `globalProps` are at the root of the state tree.
*/
export const getCombinedStateToProps = (mappers: {[key: string]: CombinedMapper}, state: Map, globalProps: any) => {
return reduceMappers(
mappers,
(props: any, mapper: any, key: string) => {
props[ key ] = props[ key ] ? props[ key ] : {};
props[ key ] = Object.assign(props[ key ], mapper.mapStateToProps(state.get(key)));
return props;
},
globalProps
);

const getCombinedStateToProps = (mappers, state, globalProps) => {
return reduceMappers(mappers, (props, mapper, key) => {
props[key] = props[key] ? props[key] : {};
props[key] = _Object$assign(props[key], mapper.mapStateToProps(state.get(key)));
return props;
}, globalProps);
};
const getCombinedDispatchToProps = (mappers, dispatch, props, defaultActions) => {
return reduceMappers(mappers, (props, mapper, key) => {
props[key] = props[key] ? props[key] : {};
props[key] = _Object$assign(props[key], mapper.mapDispatchToProps(dispatch));
return props;
}, defaultActions);
};
export const getCombinedDispatchToProps = (mappers: {[key: string]: CombinedMapper}, dispatch: () => void, props: any, defaultActions: any) => {
return reduceMappers(
mappers,
(props: any, mapper: any, key: string) => {
props[ key ] = props[ key ] ? props[ key ] : {};
props[ key ] = Object.assign(props[ key ], mapper.mapDispatchToProps(dispatch));
return props;
},
defaultActions
);
};

export { getCombinedReducer, getCombinedStateToProps, getCombinedDispatchToProps };
93 changes: 93 additions & 0 deletions index.js
@@ -0,0 +1,93 @@
//@flow
/**
* Helpers to combine multiple redux containers props object (mapStateToProps/mapDispatchToProps pairs)
* into a single props object.
* Each individual container is identified by a key in the final object.
*/

/**
* mapStateToProps / mapDispatch to props pair.
*/
export type CombinedMapper = {
mapStateToProps: (state: Map) => any,
mapDispatchToProps: (dispatch: any, props: any) => any
};

/**
* Simple definition of immutable.Map
*/
type Map = {
get: (key: any) => any,
set: (key: any, value: any) => Map
};

type ReduxAction = {
type: string,
data?: any
};

/**
* Naive object reduce implementation to avoid dependencies
*/
const reduceMappers = (mappers: {[key: string]: any}, fn: (accumulator: any, value: any) => any, initialValue: any) => {
return Object.entries(mappers).reduce(
(acc, pair: Array<any>) => {
return fn.call(null, acc, pair[1], pair[0]);
},
initialValue
);
};

/**
* This is essentially `combineReducers`: each sub-reducer gets his sub-state tree only.
*
* Example: "document" reducer : `state.set("document", reducers.document(state.get("document"), action));`
*
* If a reducer has a `global` key, this reducer will have access to the complete state tree.
*/
export const getCombinedReducer = (reducers: {[key: string]: (state: Map) => Map}) => {
return (state: Map, action: ReduxAction): Map => {
return reduceMappers(
reducers,
(curState: Map, reducer: (state: Map) => Map, key: string) => {
if (key === "global") {
return reducer(curState, action);
}
return curState.set(key, reducer(curState.get(key), action));
},
state
);
};
};


/**
* The returned object (the final state tree) is a combination of `globalProps` with each sub-state trees.
*
* Each submodule has it's key in the state tree.
* `finalProps.document = mappers.document.mapStateToProps(state)`
*
* `globalProps` are at the root of the state tree.
*/
export const getCombinedStateToProps = (mappers: {[key: string]: CombinedMapper}, state: Map, globalProps: any) => {
return reduceMappers(
mappers,
(props: any, mapper: any, key: string) => {
props[ key ] = props[ key ] ? props[ key ] : {};
props[ key ] = Object.assign(props[ key ], mapper.mapStateToProps(state.get(key)));
return props;
},
globalProps
);
};
export const getCombinedDispatchToProps = (mappers: {[key: string]: CombinedMapper}, dispatch: () => void, props: any, defaultActions: any) => {
return reduceMappers(
mappers,
(props: any, mapper: any, key: string) => {
props[ key ] = props[ key ] ? props[ key ] : {};
props[ key ] = Object.assign(props[ key ], mapper.mapDispatchToProps(dispatch));
return props;
},
defaultActions
);
};
7 changes: 5 additions & 2 deletions rollup.config.js
Expand Up @@ -3,15 +3,18 @@ import replace from "rollup-plugin-replace";


export default {
input: "./esm/index.js",
input: "./index.js",
output: [
{
file: "./cjs/index.js",
format: "cjs"
},{
file: "./esm/index.js",
format: "es"
}
],
watch: {
include: ["./esm/index.js"]
include: ["./index.js"]
},
plugins: [
replace({
Expand Down

0 comments on commit 1afa086

Please sign in to comment.