[
  {
    "path": ".babelrc",
    "content": "{\n  \"presets\": [ \"react\", \"stage-0\", \"es2015\" ],\n  \"plugins\": [ \"lodash\" ],\n}\n"
  },
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n  extends: 'airbnb',\n  parser: 'babel-eslint',\n  plugins: [\n    'react',\n  ],\n  rules: {\n    'react/jsx-filename-extension': [1, {\n      extensions: ['.js', '.jsx'],\n    }],\n  },\n};\n"
  },
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\n\n# Runtime data\npids\n*.pid\n*.seed\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (http://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directory\n# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git\nnode_modules\n\n*.sw*\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 UniversalAvenue\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "README.md",
    "content": "![React Compose](https://s3.amazonaws.com/f.cl.ly/items/1y000n0q2a2n0L2Y243S/react-compose-logo@2x.png)\n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)\n[![Circle CI](https://circleci.com/gh/UniversalAvenue/react-compose/tree/master.svg?style=svg)](https://circleci.com/gh/UniversalAvenue/react-compose/tree/master)\n\n**React-compose** allows you to encapsulate component logic into smaller,\nreusable functions, which in turn can be combined back into component. The\nfundamental idea is that React components has a way of becoming bloated with,\noften repeated, logic. This lib provides you with a set of tools to avoid that.\n\nThe encapsulated pieces will be easily testable, either because they are\nconstant or since their functionality has a more narrow scope than a\ncorresponding component would have. \n\nThe other aspect of **react-compose** is based upon the fact that whenever you\ncreate a React component, you also create an api for it as well. It is\nessential, for any large scale project that this api is well formed and consistent\nacross the application. Most components should also be extendable too, which is\nwhy, significant care is needed to make sure that each component doesn't break\nthese rules.\n\nLet's show a simple example of extendablity:\n\n```javascript\nconst ButtonComponent = props => {\n  const {\n    onClick,\n    label,\n  } = props;\n  return <button onClick={onClick}>{label}</button>;\n};\n```\n\nNow if a developer would like to manipulate the style of `ButtonComponent` from\nthe outside, it would have to be changed accordingly:\n\n```javascript\nconst ButtonComponent = props => {\n  const {\n    onClick,\n    style,\n    label,\n  } = props;\n  return <button onClick={onClick} style={style}>{label}</button>;\n};\n```\n\nOn the other hand, if all props should be passed down to the `button` element,\nthe following is much more useful:\n\n```javascript\nconst ButtonComponent = props => {\n  const {\n    label,\n  } = props;\n  return <button {...props}>{label}</button>;\n};\n```\nWith **react-compose**, the above would be written as:\n\n```javascript\nconst labelToChildren = ({ label }) => ({ children: label });\n\nconst ButtonComponent = compose(labelToChildren)('button');\n```\nLeaving much less room for breaking the rules of extendability and resuability.\nThe CustomComponent should essentially work as you would expect that the basic\nhtml elements does, `ButtonComponent` ~ `button`, beyond of course the added\nbehavior. \n\nAs an extra bonus, it is also more straight forward to test the encapsulated\nbehavior rather than the component as a whole.\n\n```javascript\ndescribe('labelToChildren', () => {\n  it('should pass whatever input label as children', () => {\n    expect(labelToChildren({ label: 'string' }).children).toEqual('string');\n  });\n});\n```\n\nFinally, the heart of **react-compose**, is finding those elementary patterns\nthat are present in your application. In this case, we can create a nice higher\norder function for the `labelToChildren` logic.\n\n```javascript\nconst mixProp = (from, to) => props => ({ [to]: props[from] });\nconst labelToChildren = mixProp('label', 'children');\n```\n\n## Installation\n\nInstall package, and check that you are using a matching version of React (^0.14)\n\n```bash\nnpm install -s react-compose\n```\n\n## API\n\nExample api usage:\n\n```javascript\nimport { compose } from 'react-compose';\n\nconst constantProper = {\n  age: 15,\n};\n\nconst dynamicProper = props => {\n  return {\n    children: `The cat is ${props.age} years old`,\n  };\n};\n\nconst Cat = compose(constantProper, dynamicProper)('p');\n\n// => <p>The cat is 15 years old</p>;\n```\n\nSpecialized style composing\n\n```javascript\nimport { compose, styles } from 'react-compose';\n\nconst constantStyle = {\n  background: 'red',\n};\nconst dynamicStyle = ({ isActive }) => (!isActive && {\n  display: 'none',\n});\n\nconst Component = compose(styles(constantStyle, dynamicStyle))('p');\n\nreturn (props) => {\n  return <Component isActive={false}>Some text</Component>;\n};\n```\n\nStacking custom components\n\n```javascript\nimport { compose } from 'react-compose';\n\nconst Cat = props => {\n  return <p>The cat is {props.age} years old</p>;\n};\n\nconst injectAge = {\n  age: 5,\n};\n\nconst Composed = compose(injectAge)(Cat);\n\n// => <p>The cat is 5 years old</p>\n```\n\nComposing complex children values\n\n```javascript\nimport { compose, children } from 'react-compose';\n\nconst AgeInfo = props => {\n  return <p>Age: {props.age} years</p>;\n};\n\nconst LengthInfo = props => {\n  return <p>Length: {props.length} cm</p>;\n};\n\nconst HeightInfo = props => {\n  return <p>Height: {props.height} cm</p>;\n};\n\nconst Info = compose(children(AgeInfo, LengthInfo, HeightInfo))('div');\n\nconst dogData = {\n  age: 5,\n  length: 250,\n  height: 150,\n};\n\nconst DogInfo = compose(dogData)(Info);\n\n// => <div>\n//      <p>Age: 5</p>\n//      <p>Length: 250</p>\n//      <p>Height: 150</p>\n//    </div>\n```\n\nComposing classNames, using the awesome [classnames](https://github.com/JedWatson/classnames) lib\n\n```javascript\nimport { compose, classNames } from 'react-compose';\n\nconst btnClassNames = classNames('btn',\n  ({ pressed }) => pressed && 'btn-pressed',\n  ({ hover }) => hover && 'btn-hover');\n \nconst Button = compose(btnClassNames)('button');\n\n// pressed: true => <button className=\"btn btn-pressed\" />\n// pressed: false, hover: true => <button className=\"btn btn-hover\" />\n```\n"
  },
  {
    "path": "circle.yml",
    "content": "machine:\n  node:\n    version: 8.0.0\ndependencies:\n  pre:\n    - npm install -g npm\ntest:\n  post:\n    - npm run semantic-release || true\n"
  },
  {
    "path": "lib/__tests__/compose-test.js",
    "content": "'use strict';\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\njest.autoMockOff();\n\nvar _ = require('lodash');\n\nvar _require = require('enzyme'),\n    shallow = _require.shallow;\n\nvar optimize = require('../index').optimize;\nvar applyFunctor = require('../index').applyFunctor;\nvar compose = require('../index').compose;\nvar styles = require('../index').styles;\nvar children = require('../index').children;\nvar classNames = require('../index').classNames;\nvar mapProp = require('../index').mapProp;\n\ndescribe('optimize', function () {\n  it('should merge propers', function () {\n    var res = optimize({\n      propA: 'alpha'\n    }, {\n      propB: 2\n    }, function () {\n      return { width: 400 };\n    }, function () {\n      return { width: 400 };\n    });\n    expect(res.constant).toEqual({\n      propA: 'alpha',\n      propB: 2\n    });\n    expect(res.dynamic.length).toEqual(2);\n  });\n  it('should merge propers ignore constants after dynamics', function () {\n    var res = optimize({\n      propA: 'alpha'\n    }, function () {\n      return { width: 400 };\n    }, { propB: 2 }, function () {\n      return { width: 400 };\n    });\n    expect(res.constant).toEqual({\n      propA: 'alpha'\n    });\n    expect(res.dynamic.length).toEqual(3);\n  });\n});\n\ndescribe('Apply functor', function () {\n  var functorCreator = function functorCreator(key, value) {\n    return function () {\n      return _defineProperty({}, key, value);\n    };\n  };\n  var deepFunctorCreator = function deepFunctorCreator(values) {\n    return function () {\n      return _.map(values, function (value, idx) {\n        return functorCreator(idx, value);\n      });\n    };\n  };\n  it('should apply each functor in order', function () {\n    var functors = [functorCreator('a', 1), functorCreator('b', 3), functorCreator('b', 2)];\n    var res = _.assign.apply(_, [{}].concat(_toConsumableArray(applyFunctor(functors))));\n    expect(res).toEqual({\n      a: 1,\n      b: 2\n    });\n  });\n  it('should apply deep functors', function () {\n    var functors = [functorCreator('a', 1), deepFunctorCreator(['alpha', 'beta', 'ceta'])];\n    var res = _.assign.apply(_, [{}].concat(_toConsumableArray(applyFunctor(functors))));\n    expect(res).toEqual({\n      a: 1,\n      0: 'alpha',\n      1: 'beta',\n      2: 'ceta'\n    });\n  });\n});\n\nvar PropTypes = require('prop-types');\n\nvar React = require('react');\n\ndescribe('Compose', function () {\n  var mapPropToKeyFunctor = function mapPropToKeyFunctor(propKey, key) {\n    return function (props) {\n      return _defineProperty({}, key, props[propKey]);\n    };\n  };\n  it('should produce a valid component', function () {\n    var Compo = compose({ background: 'blue' }, { children: 'boo' })('p');\n    var wrapper = shallow(React.createElement(Compo, null));\n    var para = wrapper.find('p');\n    expect(para.node.props.background).toEqual('blue');\n  });\n\n  it('should pass fed props into style functors', function () {\n    var Compo = compose({ background: 'blue', strength: '400px' }, mapPropToKeyFunctor('strength', 'fontSize'))('p');\n    var wrapper = shallow(React.createElement(Compo, { style: { color: 'white' } }));\n    var para = wrapper.find('p').node;\n    expect(para.props.background).toEqual('blue');\n    expect(para.props.style.color).toEqual('white');\n    expect(para.props.fontSize).toEqual('400px');\n  });\n});\n\ndescribe('Styles', function () {\n  var pToK = function pToK(propKey, key) {\n    return function (props) {\n      return _defineProperty({}, key, props[propKey]);\n    };\n  };\n  it('should produce a valid component', function () {\n    var Compo = compose(styles({ background: 'blue' }, { color: 'white' }))('p');\n    var para = shallow(React.createElement(Compo, null)).find('p').node;\n    expect(para.props.style.background).toEqual('blue');\n    expect(para.props.style.color).toEqual('white');\n  });\n  it('should produce a valid component with two separate styles', function () {\n    var Compo = compose(styles({ background: 'blue' }), styles({ color: 'white' }))('p');\n    var para = shallow(React.createElement(Compo, null)).find('p').node;\n    expect(para.props.style.background).toEqual('blue');\n    expect(para.props.style.color).toEqual('white');\n  });\n  it('should produce a valid component with two dynamic stylers', function () {\n    var Compo = compose({ strength: '5px', weight: 'normal' }, styles(pToK('strength', 'fontSize'), pToK('weight', 'fontWeight')))('p');\n    var para = shallow(React.createElement(Compo, null)).find('p').node;\n    expect(para.props.style.fontSize).toEqual('5px');\n    expect(para.props.style.fontWeight).toEqual('normal');\n  });\n  it('should produce a valid component with composite dynamic stylers', function () {\n    var fontStyle = {\n      fontSize: '5px',\n      fontWeight: 'normal'\n    };\n    var colorStyle = {\n      color: 'blue',\n      backgroundColor: 'white'\n    };\n    var compositeStyle = function compositeStyle() {\n      return [fontStyle, colorStyle];\n    };\n    var Compo = compose(styles(compositeStyle))('p');\n    var para = shallow(React.createElement(Compo, null)).find('p').node;\n    expect(para.props.style.fontSize).toEqual('5px');\n    expect(para.props.style.fontWeight).toEqual('normal');\n  });\n  it('should produce a valid component with composite multilayer dynamic stylers', function () {\n    var fontStyle = pToK('strength', 'fontSize');\n    var colorStyle = {\n      color: 'blue',\n      backgroundColor: 'white'\n    };\n    var compositeStyle = function compositeStyle() {\n      return [fontStyle, colorStyle];\n    };\n    var Compo = compose({ strength: '5px' }, styles(compositeStyle))('p');\n    var para = shallow(React.createElement(Compo, null)).find('p').node;\n    expect(para.props.style.fontSize).toEqual('5px');\n  });\n});\n\ndescribe('Children', function () {\n  it('should produce a valid component', function () {\n    var Alpha = function Alpha(props) {\n      return React.createElement(\n        'span',\n        null,\n        'The cat is ' + props.feeling\n      );\n    };\n    Alpha.propTypes = {\n      feeling: PropTypes.string.isRequired\n    };\n    var Compo = compose({ feeling: 'angry' }, children(Alpha))('p');\n    var para = shallow(React.createElement(Compo, null)).childAt(0).shallow().node;\n    expect(para.props.children).toEqual('The cat is angry');\n  });\n});\n\ndescribe('classNames', function () {\n  it('should produce a correct className', function () {\n    var result = classNames('btn', 'btn-pressed')({});\n    expect(result.className).toEqual('btn btn-pressed');\n  });\n  it('should handle classNames propers', function () {\n    var result = classNames('btn', function (_ref4) {\n      var pressed = _ref4.pressed;\n      return pressed && 'btn-pressed';\n    })({\n      pressed: true\n    });\n    expect(result.className).toEqual('btn btn-pressed');\n  });\n  it('should handle falsy classNames propers', function () {\n    var result = classNames('btn', function (_ref5) {\n      var pressed = _ref5.pressed;\n      return pressed && 'btn-pressed';\n    })({\n      pressed: false\n    });\n    expect(result.className).toEqual('btn');\n  });\n  it('should append with input classNames', function () {\n    var result = classNames('btn', function (_ref6) {\n      var pressed = _ref6.pressed;\n      return pressed && 'btn-pressed';\n    })({\n      pressed: false,\n      className: 'alpha'\n    });\n    expect(result.className).toEqual('btn alpha');\n  });\n});\n\ndescribe('Nesting', function () {\n  it('should optimize nested compose calls', function () {\n    var Root = function Root(props) {\n      return React.createElement(\n        'p',\n        props,\n        'root'\n      );\n    };\n    var Level1 = compose({ background: 'red' })(Root);\n    var Level2 = compose({ color: 'blue' })(Level1);\n    var wrapper = shallow(React.createElement(Level2, null));\n    var para = wrapper.shallow().find('p').node;\n    expect(para.props.background).toEqual('red');\n    expect(para.props.color).toEqual('blue');\n  });\n  fit('should optimize nested compose calls and dynamics should be correct', function () {\n    var Root = function Root(props) {\n      return React.createElement(\n        'p',\n        props,\n        'root'\n      );\n    };\n    var Level1 = compose({ background: 'red' }, function () {\n      return { color: 'red' };\n    })(Root);\n    var Level2 = compose({ color: 'blue' }, function (_ref7) {\n      var background = _ref7.background;\n      return {\n        background: background === 'red' ? 'blue' : 'brown'\n      };\n    })(Level1);\n    var wrapper = shallow(React.createElement(Level2, null));\n    var para = wrapper.shallow().find('p').node;\n    expect(para.props.background).toEqual('red');\n    expect(para.props.color).toEqual('red');\n  });\n  it('should produce a great display name', function () {\n    function Root() {\n      return React.createElement(\n        'p',\n        null,\n        'Names'\n      );\n    }\n    var Level1 = compose({ background: 'red' })(Root);\n    var Level2 = compose({ color: 'blue' })(Level1);\n    expect(Level2.displayName).toEqual('composed(Root)');\n  });\n});\n\ndescribe('mapProp', function () {\n  it('should transform input value', function () {\n    function Root(props) {\n      return React.createElement('p', props);\n    }\n    var Comped = compose(mapProp('x', function (x) {\n      return x * 2;\n    }))(Root);\n    var p = shallow(React.createElement(Comped, { x: 5 })).node;\n    expect(p.props.x).toEqual(10);\n  });\n});\n\ndescribe('composing', function () {\n  it('chains properly', function () {\n    var f0 = {\n      a: 7\n    };\n    function f1() {\n      return { b: 5 };\n    }\n    function f2(_ref8) {\n      var a = _ref8.a,\n          b = _ref8.b;\n\n      return { c: a + b };\n    }\n    var Comped = compose(f0, f1, f2)('p');\n    var p = shallow(React.createElement(Comped, null)).node;\n    expect(p.props.c).toEqual(12);\n  });\n  it('chains properly while nesting', function () {\n    var f0 = {\n      a: 7\n    };\n    function f1() {\n      return { b: 5 };\n    }\n    function f2(_ref9) {\n      var a = _ref9.a,\n          b = _ref9.b;\n\n      return { c: a + b };\n    }\n    function f3() {\n      return { d: 5 };\n    }\n    var C1 = compose(f2)('p');\n    var Comped = compose(f0, f1, f3)(C1);\n    var p = shallow(React.createElement(Comped, null)).node;\n    expect(p.props.c).toEqual(12);\n  });\n  it('chains properly while deeply nesting', function () {\n    var f0 = {\n      a: 7\n    };\n    function f1() {\n      return { b: 5 };\n    }\n    function f2(_ref10) {\n      var a = _ref10.a,\n          b = _ref10.b;\n\n      return { c: a + b };\n    }\n    function f3(_ref11) {\n      var c = _ref11.c;\n\n      return { d: c + 2 };\n    }\n    var C0 = compose(f3)('p');\n    var C1 = compose(f2)(C0);\n    var Comped = compose(f0, f1)(C1);\n    var p = shallow(React.createElement(Comped, null)).node;\n    expect(p.props.d).toEqual(14);\n  });\n});"
  },
  {
    "path": "lib/__tests__/connect-test.js",
    "content": "'use strict';\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\njest.autoMockOff();\n\nvar React = require('react');\n\nvar _require = require('enzyme'),\n    mount = _require.mount;\n\nvar thunk = require('redux-thunk').default;\n\nvar connect = require('../connect').default;\nvar applyMiddleware = require('../connect').applyMiddleware;\n\ndescribe('connect', function () {\n  it('creates a valid component', function () {\n    var reducer = jest.fn(function (state) {\n      return state;\n    });\n    var Component = connect(reducer, { onClick: 'doClick' })('button');\n    var wrapper = mount(React.createElement(Component, null));\n    wrapper.find('button').simulate('click');\n    expect(reducer.mock.calls[0][0]).toEqual({});\n    expect(reducer.mock.calls[1][1].type).toEqual('doClick');\n  });\n  it('changes a prop as a result', function () {\n    var Button = function Button(props) {\n      return React.createElement('button', props);\n    };\n    var reducer = jest.fn(function (state, action) {\n      if (action.type === 'doClick') {\n        return _extends({}, state, {\n          isToggled: !state.isToggled\n        });\n      }\n      return state;\n    });\n    var Component = connect(reducer, { onClick: 'doClick' })(Button);\n    var wrapper = mount(React.createElement(Component, null));\n    var btn = wrapper.find('button');\n    btn.simulate('click');\n    expect(btn.prop('isToggled')).toEqual(true);\n    btn.simulate('click');\n    expect(btn.prop('isToggled')).toEqual(false);\n    wrapper.setProps({ isToggled: true });\n    expect(btn.prop('isToggled')).toEqual(true);\n  });\n  it('hides willReceiveProps behaviour', function () {\n    var Button = function Button(props) {\n      return React.createElement('button', props);\n    };\n    var reducer = jest.fn(function (state) {\n      return state;\n    });\n    var Component = connect(reducer, {}, {\n      componentWillReceiveProps: function componentWillReceiveProps() {}\n    })(Button);\n    var wrapper = mount(React.createElement(Component, { isToggled: true }));\n    var btn = wrapper.find('button');\n    expect(btn.prop('isToggled')).toEqual(true);\n    wrapper.setProps({ isToggled: false });\n    expect(btn.prop('isToggled')).toEqual(true);\n  });\n  it('update onDidMount', function () {\n    var Button = function Button(props) {\n      return React.createElement('button', props);\n    };\n    var reducer = jest.fn(function (state, action) {\n      if (action.type === 'doClick') {\n        return _extends({}, state, {\n          isToggled: !state.isToggled\n        });\n      }\n      return state;\n    });\n    var Component = connect(reducer, {}, {\n      componentDidMount: function componentDidMount() {\n        this.dispatch({\n          type: 'doClick'\n        });\n      }\n    })(Button);\n    var wrapper = mount(React.createElement(Component, null));\n    var btn = wrapper.find('button');\n    expect(btn.prop('isToggled')).toEqual(true);\n  });\n  it('can handle short form life cycles', function () {\n    var Button = function Button(props) {\n      return React.createElement('button', props);\n    };\n    var reducer = jest.fn(function (state, action) {\n      if (action.type === 'doClick') {\n        return _extends({}, state, {\n          isToggled: !state.isToggled\n        });\n      }\n      return state;\n    });\n    var Component = connect(reducer, {}, {\n      componentDidMount: 'doClick'\n    })(Button);\n    var wrapper = mount(React.createElement(Component, null));\n    var btn = wrapper.find('button');\n    expect(btn.prop('isToggled')).toEqual(true);\n  });\n  it('works with middleware like redux-thunk', function () {\n    var Button = function Button(props) {\n      return React.createElement('button', props);\n    };\n    var reducer = jest.fn(function (state, action) {\n      if (action.type === 'doClick') {\n        return _extends({}, state, {\n          isToggled: !state.isToggled\n        });\n      }\n      return state;\n    });\n    var ac = applyMiddleware(thunk);\n    var Component = ac(reducer, function (dispatch) {\n      return {\n        onClick: function onClick() {\n          dispatch(function (disp) {\n            disp({ type: 'doClick' });\n          });\n        }\n      };\n    })(Button);\n    var wrapper = mount(React.createElement(Component, null));\n    var btn = wrapper.find('button');\n    btn.simulate('click');\n    expect(btn.prop('isToggled')).toEqual(true);\n  });\n});"
  },
  {
    "path": "lib/config.js",
    "content": "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.plugin = exports.renderChild = exports.composeComponent = exports.exposeContextTypes = undefined;\n\nvar _assign2 = require('lodash/assign');\n\nvar _assign3 = _interopRequireDefault(_assign2);\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nvar _propTypes = require('prop-types');\n\nvar _propTypes2 = _interopRequireDefault(_propTypes);\n\nvar _react = require('react');\n\nvar _react2 = _interopRequireDefault(_react);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nvar plugin = {};\nvar functions = {};\n\nvar configurable = function configurable(key, defaultFn) {\n  var argGetter = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {\n    return [];\n  };\n\n  var apply = function apply(fn) {\n    return function () {\n      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n        args[_key] = arguments[_key];\n      }\n\n      return fn.apply(null, [].concat(args, _toConsumableArray(argGetter())));\n    };\n  };\n  plugin[key] = function (fn) {\n    functions[key] = apply(fn);\n  };\n  functions[key] = apply(defaultFn);\n  return function () {\n    for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n      args[_key2] = arguments[_key2];\n    }\n\n    return functions[key].apply(null, args);\n  };\n};\n\nvar defaultContextTypes = function defaultContextTypes() {\n  return {};\n};\nvar exposeContextTypes = exports.exposeContextTypes = configurable('exposeContextTypes', defaultContextTypes, function () {\n  return [_propTypes2.default];\n});\n\nvar merge = function merge(arr) {\n  return _assign3.default.apply(_assign3.default.apply.placeholder, [{}].concat(_toConsumableArray(arr)));\n};\nvar defaultComposeComponent = function defaultComposeComponent(Component, _ref) {\n  var _ref$styles = _ref.styles,\n      styles = _ref$styles === undefined ? [] : _ref$styles,\n      _ref$style = _ref.style,\n      style = _ref$style === undefined ? {} : _ref$style,\n      rest = _objectWithoutProperties(_ref, ['styles', 'style']);\n\n  var mergedStyle = merge([style].concat(styles));\n  return _react2.default.createElement(Component, _extends({ style: mergedStyle }, rest));\n};\nvar composeComponent = exports.composeComponent = configurable('composeComponent', defaultComposeComponent);\n\nvar defaultRenderChild = function defaultRenderChild(props) {\n  return function (Child, index) {\n    return _react2.default.createElement(Child, _extends({}, props, { key: (Child.displayName || '') + index }));\n  };\n};\n\nvar renderChild = exports.renderChild = configurable('renderChild', defaultRenderChild);\n\nexports.plugin = plugin;"
  },
  {
    "path": "lib/connect.js",
    "content": "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\n\nvar _each2 = require('lodash/each');\n\nvar _each3 = _interopRequireDefault(_each2);\n\nvar _omitBy2 = require('lodash/omitBy');\n\nvar _omitBy3 = _interopRequireDefault(_omitBy2);\n\nvar _reduce2 = require('lodash/reduce');\n\nvar _reduce3 = _interopRequireDefault(_reduce2);\n\nvar _isString2 = require('lodash/isString');\n\nvar _isString3 = _interopRequireDefault(_isString2);\n\nvar _isFunction2 = require('lodash/isFunction');\n\nvar _isFunction3 = _interopRequireDefault(_isFunction2);\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nexports.default = connect;\nexports.applyMiddleware = applyMiddleware;\n\nvar _react = require('react');\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _getDisplayName = require('./getDisplayName');\n\nvar _getDisplayName2 = _interopRequireDefault(_getDisplayName);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nvar defaultMergeProps = function defaultMergeProps(stateProps, dispatchProps, parentProps) {\n  return _extends({}, parentProps, stateProps, dispatchProps);\n};\n\nfunction createDispatchProps(dispatchers, dispatch) {\n  if ((0, _isFunction3.default)(dispatchers)) {\n    return dispatchers(dispatch);\n  }\n  function dispatchHandler(fn) {\n    var action = (0, _isString3.default)(fn) ? { type: fn } : fn;\n    return function () {\n      return dispatch(action);\n    };\n  }\n  return (0, _reduce3.default)(dispatchers, function (sum, fn, key) {\n    return Object.assign(sum, _defineProperty({}, key, dispatchHandler(fn)));\n  }, {});\n}\n\nfunction wrapLifeCycle(fn) {\n  if (!(0, _isFunction3.default)(fn)) {\n    var action = (0, _isString3.default)(fn) ? { type: fn } : fn;\n    return function wrappedStaticLifeCycleMethod() {\n      this.dispatch(action);\n    };\n  }\n  return fn;\n}\n\nfunction connect(reducer, dispatchers) {\n  var lifeCycle = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n  var merge = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : defaultMergeProps;\n  var middlewares = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];\n\n  return function (Component) {\n    var Connected = function (_React$Component) {\n      _inherits(Connected, _React$Component);\n\n      function Connected(props) {\n        _classCallCheck(this, Connected);\n\n        var _this = _possibleConstructorReturn(this, (Connected.__proto__ || Object.getPrototypeOf(Connected)).call(this, props));\n\n        _this.state = reducer(props, {});\n        _this.dispatch = _this.dispatch.bind(_this);\n        var middlewareAPI = {\n          getState: function getState() {\n            return _this.state;\n          },\n          dispatch: _this.dispatch\n        };\n        var chain = middlewares.map(function (middleware) {\n          return middleware(middlewareAPI);\n        });\n        _this.dispatch = [].concat(_toConsumableArray(chain)).reduceRight(function (a, fn) {\n          return fn(a);\n        }, _this.dispatch);\n        _this.dispatchProps = createDispatchProps(dispatchers, _this.dispatch);\n        return _this;\n      }\n\n      _createClass(Connected, [{\n        key: 'componentWillReceiveProps',\n        value: function componentWillReceiveProps(nextProps) {\n          var _this2 = this;\n\n          this.setState((0, _omitBy3.default)(nextProps, function (val, key) {\n            return val === _this2.state[key];\n          }));\n        }\n      }, {\n        key: 'getProps',\n        value: function getProps() {\n          return merge(this.state, this.dispatchProps, this.props);\n        }\n      }, {\n        key: 'dispatch',\n        value: function dispatch(action) {\n          var nextState = reducer(this.state, action);\n          if (nextState !== this.state) {\n            this.setState(nextState);\n          }\n          return action;\n        }\n      }, {\n        key: 'render',\n        value: function render() {\n          return _react2.default.createElement(Component, this.getProps());\n        }\n      }]);\n\n      return Connected;\n    }(_react2.default.Component);\n\n    Connected.displayName = 'connect(' + (0, _getDisplayName2.default)(Component) + ')';\n    (0, _each3.default)(lifeCycle, function (fn, key) {\n      return Object.assign(Connected.prototype, _defineProperty({}, key, wrapLifeCycle(fn)));\n    });\n    return Connected;\n  };\n}\n\nfunction applyMiddleware() {\n  for (var _len = arguments.length, wares = Array(_len), _key = 0; _key < _len; _key++) {\n    wares[_key] = arguments[_key];\n  }\n\n  return function () {\n    return connect.apply(null, [arguments.length <= 0 ? undefined : arguments[0], arguments.length <= 1 ? undefined : arguments[1], (arguments.length <= 2 ? undefined : arguments[2]) || {}, (arguments.length <= 3 ? undefined : arguments[3]) || defaultMergeProps, wares]);\n  };\n}"
  },
  {
    "path": "lib/getDisplayName.js",
    "content": "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDisplayName;\n// https://github.com/jurassix/react-display-name/blob/master/src/getDisplayName.js\nfunction getDisplayName(Component) {\n  return Component.displayName || Component.name || (typeof Component === 'string' ? Component : 'Component');\n}"
  },
  {
    "path": "lib/index.js",
    "content": "'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.children = exports.styles = exports.compose = exports.applyFunctor = exports.optimize = undefined;\n\nvar _reduce2 = require('lodash/reduce');\n\nvar _reduce3 = _interopRequireDefault(_reduce2);\n\nvar _isString2 = require('lodash/isString');\n\nvar _isString3 = _interopRequireDefault(_isString2);\n\nvar _isArray2 = require('lodash/isArray');\n\nvar _isArray3 = _interopRequireDefault(_isArray2);\n\nvar _slice2 = require('lodash/slice');\n\nvar _slice3 = _interopRequireDefault(_slice2);\n\nvar _isFunction2 = require('lodash/isFunction');\n\nvar _isFunction3 = _interopRequireDefault(_isFunction2);\n\nvar _takeWhile2 = require('lodash/takeWhile');\n\nvar _takeWhile3 = _interopRequireDefault(_takeWhile2);\n\nvar _flattenDeep2 = require('lodash/flattenDeep');\n\nvar _flattenDeep3 = _interopRequireDefault(_flattenDeep2);\n\nvar _map2 = require('lodash/map');\n\nvar _map3 = _interopRequireDefault(_map2);\n\nvar _compact2 = require('lodash/compact');\n\nvar _compact3 = _interopRequireDefault(_compact2);\n\nvar _flatten2 = require('lodash/flatten');\n\nvar _flatten3 = _interopRequireDefault(_flatten2);\n\nvar _assign2 = require('lodash/assign');\n\nvar _assign3 = _interopRequireDefault(_assign2);\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nexports.classNames = classNames;\nexports.mapProp = mapProp;\n\nvar _classnames = require('classnames');\n\nvar _classnames2 = _interopRequireDefault(_classnames);\n\nvar _config = require('./config');\n\nvar _getDisplayName = require('./getDisplayName');\n\nvar _getDisplayName2 = _interopRequireDefault(_getDisplayName);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\n/**\n * aggregates a set of functions/objects into a constant part + a dynamic part\n *\n *\n **/\n\nvar mergeObjArr = function mergeObjArr(arr) {\n  var base = _assign3.default.apply(_assign3.default.apply.placeholder, [{}].concat(_toConsumableArray(arr)));\n  var styles = (0, _flatten3.default)((0, _compact3.default)((0, _map3.default)(arr, 'styles')));\n  if (styles.length > 1) {\n    base.styles = styles;\n  }\n  return base;\n};\n\nvar optimize = exports.optimize = function optimize() {\n  for (var _len = arguments.length, propers = Array(_len), _key = 0; _key < _len; _key++) {\n    propers[_key] = arguments[_key];\n  }\n\n  var flattened = (0, _compact3.default)((0, _flattenDeep3.default)(propers));\n  var constantStyles = (0, _takeWhile3.default)(flattened, function (st) {\n    return !(0, _isFunction3.default)(st);\n  }) || [];\n  var dynamic = (0, _slice3.default)(flattened, constantStyles.length, flattened.length) || [];\n  var constant = mergeObjArr(constantStyles);\n  return {\n    constant: constant,\n    dynamic: dynamic\n  };\n};\n\nvar flatMap = function flatMap(arr, fn) {\n  if ((0, _isArray3.default)(arr)) {\n    return (0, _flattenDeep3.default)((0, _map3.default)(arr, fn));\n  }\n  return fn(arr);\n};\n\nvar applyFunctor = exports.applyFunctor = function applyFunctor(functor) {\n  for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n    args[_key2 - 1] = arguments[_key2];\n  }\n\n  var reapply = function reapply(f) {\n    return applyFunctor.apply(null, [f].concat(args));\n  };\n  if ((0, _isArray3.default)(functor)) {\n    return flatMap(functor, reapply);\n  }\n  if ((0, _isFunction3.default)(functor)) {\n    return reapply(functor.apply(undefined, args));\n  }\n  return functor;\n};\n\nfunction mergePropers(a, b) {\n  return optimize([a.constant].concat(_toConsumableArray(a.dynamic), [b.constant], _toConsumableArray(b.dynamic)));\n}\n\nvar compose = exports.compose = function compose() {\n  for (var _len3 = arguments.length, propers = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n    propers[_key3] = arguments[_key3];\n  }\n\n  var optimizedPropers = optimize(propers);\n\n  function doCompose(Component, ps) {\n    var ComposedComponent = function ComposedComponent(props, context) {\n      var base = _extends({}, props, ps.constant);\n      var finalProps = ps.dynamic.reduce(function (obj, fn) {\n        return Object.assign({}, obj, applyFunctor(fn, obj, context));\n      }, base);\n      return (0, _config.composeComponent)(Component, finalProps);\n    };\n    ComposedComponent.contextTypes = (0, _config.exposeContextTypes)();\n    ComposedComponent.displayName = 'composed(' + (0, _getDisplayName2.default)(Component) + ')';\n    return ComposedComponent;\n  }\n\n  function mergeComposed(Component) {\n    var Target = Component;\n    var ps = optimizedPropers;\n    if (Component && Component.composedBy) {\n      var _Component$composedBy = Component.composedBy,\n          composers = _Component$composedBy.composers,\n          Parent = _Component$composedBy.Parent;\n\n      ps = mergePropers(optimizedPropers, composers);\n      Target = Parent;\n    }\n    var Result = doCompose(Target, ps);\n    Result.composedBy = {\n      composers: ps,\n      Parent: Target\n    };\n    return Result;\n  }\n\n  return mergeComposed;\n};\n\nvar styles = exports.styles = function styles() {\n  for (var _len4 = arguments.length, stylers = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n    stylers[_key4] = arguments[_key4];\n  }\n\n  var _optimize = optimize(stylers),\n      constant = _optimize.constant,\n      dynamic = _optimize.dynamic;\n\n  // If all constants, return a constant proper\n\n\n  if (dynamic.length === 0) {\n    return {\n      styles: constant\n    };\n  }\n\n  return function (props, context) {\n    var upstream = props.styles || [];\n    var base = [].concat(_toConsumableArray(upstream), [constant]);\n    var applied = applyFunctor(dynamic, _extends({}, props, { styles: base }), context);\n    var finalStyles = [].concat(_toConsumableArray(base), _toConsumableArray(applied));\n    return {\n      styles: finalStyles\n    };\n  };\n};\n\nvar children = exports.children = function children() {\n  for (var _len5 = arguments.length, childers = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {\n    childers[_key5] = arguments[_key5];\n  }\n\n  return function (props) {\n    return {\n      children: (0, _map3.default)(childers, (0, _config.renderChild)(props))\n    };\n  };\n};\n\nfunction handleUpstreamClassName(name) {\n  if (!name) {\n    return {};\n  }\n  if ((0, _isString3.default)(name)) {\n    return _defineProperty({}, name, true);\n  }\n  return name;\n}\n\nfunction arrayToClassNames(arr) {\n  return (0, _reduce3.default)(arr, function (sum, item) {\n    return (0, _isString3.default)(item) ? _extends({}, sum, _defineProperty({}, item, true)) : _extends({}, sum, item);\n  }, {});\n}\n\nfunction classNames() {\n  for (var _len6 = arguments.length, names = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {\n    names[_key6] = arguments[_key6];\n  }\n\n  return function (props, context) {\n    return {\n      className: (0, _classnames2.default)(_extends({}, arrayToClassNames(applyFunctor(names, props, context)), handleUpstreamClassName(props.className)))\n    };\n  };\n}\n\nfunction mapProp(property, fn, defaultValue) {\n  return function (props) {\n    return _defineProperty({}, property, fn(props[property] || defaultValue));\n  };\n}"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-compose\",\n  \"description\": \"Compose react components with a functional api\",\n  \"main\": \"lib/index.js\",\n  \"scripts\": {\n    \"clean\": \"./node_modules/rimraf/bin.js lib\",\n    \"test\": \"npm run build && ./node_modules/jest-cli/bin/jest.js\",\n    \"build\": \"./node_modules/babel-cli/bin/babel.js src --out-dir lib\",\n    \"pkgfiles\": \"./node_modules/pkgfiles/bin/pkgfiles.js\",\n    \"prepublish\": \"npm run clean && npm run build\",\n    \"semantic-release\": \"semantic-release pre && npm publish && semantic-release post\"\n  },\n  \"files\": [\n    \"lib\",\n    \"!lib/__tests__\"\n  ],\n  \"release\": {\n    \"verifyConditions\": \"condition-circle\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/UniversalAvenue/react-compose.git\"\n  },\n  \"keywords\": [\n    \"React\",\n    \"compose\"\n  ],\n  \"author\": \"Daniel Werthén <danielwerthen@gmail.com> (https://github.com/danielwerthen)\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/UniversalAvenue/react-compose/issues\"\n  },\n  \"homepage\": \"https://github.com/UniversalAvenue/react-compose#readme\",\n  \"peerDependencies\": {\n    \"react\": \">=15.5.4\"\n  },\n  \"devDependencies\": {\n    \"babel-cli\": \"^6.6.5\",\n    \"babel-eslint\": \"^7.2.3\",\n    \"babel-plugin-lodash\": \"^3.2.11\",\n    \"babel-preset-es2015\": \"^6.5.0\",\n    \"babel-preset-react\": \"^6.5.0\",\n    \"babel-preset-stage-0\": \"^6.5.0\",\n    \"condition-circle\": \"^1.2.0\",\n    \"cz-conventional-changelog\": \"^2.0.0\",\n    \"enzyme\": \"^2.3.0\",\n    \"eslint\": \"^3.19.0\",\n    \"eslint-config-airbnb\": \"^15.0.1\",\n    \"eslint-plugin-import\": \"^2.3.0\",\n    \"eslint-plugin-jsx-a11y\": \"^5.0.3\",\n    \"eslint-plugin-react\": \"^7.0.1\",\n    \"jest-cli\": \"^20.0.4\",\n    \"pkgfiles\": \"^2.3.0\",\n    \"react\": \">=15.5.4\",\n    \"react-addons-test-utils\": \"^15.5.1\",\n    \"react-dom\": \"^15.5.4\",\n    \"redux-thunk\": \"^2.1.0\",\n    \"rimraf\": \"^2.4.4\",\n    \"semantic-release\": \"^6.3.6\"\n  },\n  \"jest\": {\n    \"roots\": [\n      \"lib\"\n    ]\n  },\n  \"config\": {\n    \"commitizen\": {\n      \"path\": \"./node_modules/cz-conventional-changelog\"\n    }\n  },\n  \"dependencies\": {\n    \"classnames\": \"^2.2.3\",\n    \"lodash\": \"^4.0.0\",\n    \"prop-types\": \"^15.5.10\"\n  }\n}\n"
  },
  {
    "path": "src/__tests__/.eslintrc.js",
    "content": "module.exports = {\n  env: {\n    jest: true,\n  },\n};\n"
  },
  {
    "path": "src/__tests__/compose-test.js",
    "content": "jest.autoMockOff();\n\nconst _ = require('lodash');\nconst { shallow } = require('enzyme');\n\nconst optimize = require('../index').optimize;\nconst applyFunctor = require('../index').applyFunctor;\nconst compose = require('../index').compose;\nconst styles = require('../index').styles;\nconst children = require('../index').children;\nconst classNames = require('../index').classNames;\nconst mapProp = require('../index').mapProp;\n\ndescribe('optimize', () => {\n  it('should merge propers', () => {\n    const res = optimize({\n      propA: 'alpha',\n    }, {\n      propB: 2,\n    }, () => ({ width: 400 }),\n    () => ({ width: 400 }),\n    );\n    expect(res.constant).toEqual({\n      propA: 'alpha',\n      propB: 2,\n    });\n    expect(res.dynamic.length).toEqual(2);\n  });\n  it('should merge propers ignore constants after dynamics', () => {\n    const res = optimize({\n      propA: 'alpha',\n    }, () => ({ width: 400 }),\n    { propB: 2 },\n    () => ({ width: 400 }),\n    );\n    expect(res.constant).toEqual({\n      propA: 'alpha',\n    });\n    expect(res.dynamic.length).toEqual(3);\n  });\n});\n\ndescribe('Apply functor', () => {\n  const functorCreator = (key, value) => () => ({\n    [key]: value,\n  });\n  const deepFunctorCreator = values => () =>\n    _.map(values, (value, idx) => functorCreator(idx, value));\n  it('should apply each functor in order', () => {\n    const functors = [\n      functorCreator('a', 1),\n      functorCreator('b', 3),\n      functorCreator('b', 2),\n    ];\n    const res = _.assign.apply(_, [{}, ...applyFunctor(functors)]);\n    expect(res).toEqual({\n      a: 1,\n      b: 2,\n    });\n  });\n  it('should apply deep functors', () => {\n    const functors = [\n      functorCreator('a', 1),\n      deepFunctorCreator(['alpha', 'beta', 'ceta']),\n    ];\n    const res = _.assign.apply(_, [{}, ...applyFunctor(functors)]);\n    expect(res).toEqual({\n      a: 1,\n      0: 'alpha',\n      1: 'beta',\n      2: 'ceta',\n    });\n  });\n});\n\nconst PropTypes = require('prop-types');\n\nconst React = require('react');\n\ndescribe('Compose', () => {\n  const mapPropToKeyFunctor = (propKey, key) => props => ({\n    [key]: props[propKey],\n  });\n  it('should produce a valid component', () => {\n    const Compo = compose({ background: 'blue' }, { children: 'boo' })('p');\n    const wrapper = shallow(<Compo />);\n    const para = wrapper.find('p');\n    expect(para.node.props.background).toEqual('blue');\n  });\n\n  it('should pass fed props into style functors', () => {\n    const Compo = compose({ background: 'blue', strength: '400px' },\n      mapPropToKeyFunctor('strength', 'fontSize'))('p');\n    const wrapper = shallow(<Compo style={{ color: 'white' }} />);\n    const para = wrapper.find('p').node;\n    expect(para.props.background).toEqual('blue');\n    expect(para.props.style.color).toEqual('white');\n    expect(para.props.fontSize).toEqual('400px');\n  });\n});\n\ndescribe('Styles', () => {\n  const pToK = (propKey, key) => props => ({\n    [key]: props[propKey],\n  });\n  it('should produce a valid component', () => {\n    const Compo = compose(styles({ background: 'blue' }, { color: 'white' }))('p');\n    const para = shallow(<Compo />).find('p').node;\n    expect(para.props.style.background).toEqual('blue');\n    expect(para.props.style.color).toEqual('white');\n  });\n  it('should produce a valid component with two separate styles', () => {\n    const Compo = compose(styles({ background: 'blue' }), styles({ color: 'white' }))('p');\n    const para = shallow(<Compo />).find('p').node;\n    expect(para.props.style.background).toEqual('blue');\n    expect(para.props.style.color).toEqual('white');\n  });\n  it('should produce a valid component with two dynamic stylers', () => {\n    const Compo = compose({ strength: '5px', weight: 'normal' },\n      styles(pToK('strength', 'fontSize'), pToK('weight', 'fontWeight')),\n    )('p');\n    const para = shallow(<Compo />).find('p').node;\n    expect(para.props.style.fontSize).toEqual('5px');\n    expect(para.props.style.fontWeight).toEqual('normal');\n  });\n  it('should produce a valid component with composite dynamic stylers', () => {\n    const fontStyle = {\n      fontSize: '5px',\n      fontWeight: 'normal',\n    };\n    const colorStyle = {\n      color: 'blue',\n      backgroundColor: 'white',\n    };\n    const compositeStyle = () => [fontStyle, colorStyle];\n    const Compo = compose(\n      styles(compositeStyle),\n    )('p');\n    const para = shallow(<Compo />).find('p').node;\n    expect(para.props.style.fontSize).toEqual('5px');\n    expect(para.props.style.fontWeight).toEqual('normal');\n  });\n  it('should produce a valid component with composite multilayer dynamic stylers', () => {\n    const fontStyle = pToK('strength', 'fontSize');\n    const colorStyle = {\n      color: 'blue',\n      backgroundColor: 'white',\n    };\n    const compositeStyle = () => [fontStyle, colorStyle];\n    const Compo = compose({ strength: '5px' },\n      styles(compositeStyle),\n    )('p');\n    const para = shallow(<Compo />).find('p').node;\n    expect(para.props.style.fontSize).toEqual('5px');\n  });\n});\n\ndescribe('Children', () => {\n  it('should produce a valid component', () => {\n    const Alpha = props => <span>{`The cat is ${props.feeling}`}</span>;\n    Alpha.propTypes = {\n      feeling: PropTypes.string.isRequired,\n    };\n    const Compo = compose({ feeling: 'angry' }, children(Alpha))('p');\n    const para = shallow(<Compo />).childAt(0).shallow().node;\n    expect(para.props.children).toEqual('The cat is angry');\n  });\n});\n\ndescribe('classNames', () => {\n  it('should produce a correct className', () => {\n    const result = classNames('btn', 'btn-pressed')({});\n    expect(result.className).toEqual('btn btn-pressed');\n  });\n  it('should handle classNames propers', () => {\n    const result = classNames('btn', ({ pressed }) => pressed && 'btn-pressed')({\n      pressed: true,\n    });\n    expect(result.className).toEqual('btn btn-pressed');\n  });\n  it('should handle falsy classNames propers', () => {\n    const result = classNames('btn', ({ pressed }) => pressed && 'btn-pressed')({\n      pressed: false,\n    });\n    expect(result.className).toEqual('btn');\n  });\n  it('should append with input classNames', () => {\n    const result = classNames('btn', ({ pressed }) => pressed && 'btn-pressed')({\n      pressed: false,\n      className: 'alpha',\n    });\n    expect(result.className).toEqual('btn alpha');\n  });\n});\n\ndescribe('Nesting', () => {\n  it('should optimize nested compose calls', () => {\n    const Root = props => <p {...props}>root</p>;\n    const Level1 = compose({ background: 'red' })(Root);\n    const Level2 = compose({ color: 'blue' })(Level1);\n    const wrapper = shallow(<Level2 />);\n    const para = wrapper.shallow().find('p').node;\n    expect(para.props.background).toEqual('red');\n    expect(para.props.color).toEqual('blue');\n  });\n  fit('should optimize nested compose calls and dynamics should be correct', () => {\n    const Root = props => <p {...props}>root</p>;\n    const Level1 = compose({ background: 'red' }, () => ({ color: 'red' }))(Root);\n    const Level2 = compose({ color: 'blue' }, ({ background }) =>\n      ({\n        background: background === 'red' ? 'blue' : 'brown',\n      }),\n    )(Level1);\n    const wrapper = shallow(<Level2 />);\n    const para = wrapper.shallow().find('p').node;\n    expect(para.props.background).toEqual('red');\n    expect(para.props.color).toEqual('red');\n  });\n  it('should produce a great display name', () => {\n    function Root() {\n      return <p>Names</p>;\n    }\n    const Level1 = compose({ background: 'red' })(Root);\n    const Level2 = compose({ color: 'blue' })(Level1);\n    expect(Level2.displayName).toEqual('composed(Root)');\n  });\n});\n\ndescribe('mapProp', () => {\n  it('should transform input value', () => {\n    function Root(props) {\n      return <p {...props} />;\n    }\n    const Comped = compose(mapProp('x', x => x * 2))(Root);\n    const p = shallow(<Comped x={5} />).node;\n    expect(p.props.x).toEqual(10);\n  });\n});\n\ndescribe('composing', () => {\n  it('chains properly', () => {\n    const f0 = {\n      a: 7,\n    };\n    function f1() {\n      return { b: 5 };\n    }\n    function f2({ a, b }) {\n      return { c: a + b };\n    }\n    const Comped = compose(f0, f1, f2)('p');\n    const p = shallow(<Comped />).node;\n    expect(p.props.c).toEqual(12);\n  });\n  it('chains properly while nesting', () => {\n    const f0 = {\n      a: 7,\n    };\n    function f1() {\n      return { b: 5 };\n    }\n    function f2({ a, b }) {\n      return { c: a + b };\n    }\n    function f3() {\n      return { d: 5 };\n    }\n    const C1 = compose(f2)('p');\n    const Comped = compose(f0, f1, f3)(C1);\n    const p = shallow(<Comped />).node;\n    expect(p.props.c).toEqual(12);\n  });\n  it('chains properly while deeply nesting', () => {\n    const f0 = {\n      a: 7,\n    };\n    function f1() {\n      return { b: 5 };\n    }\n    function f2({ a, b }) {\n      return { c: a + b };\n    }\n    function f3({ c }) {\n      return { d: c + 2 };\n    }\n    const C0 = compose(f3)('p');\n    const C1 = compose(f2)(C0);\n    const Comped = compose(f0, f1)(C1);\n    const p = shallow(<Comped />).node;\n    expect(p.props.d).toEqual(14);\n  });\n});\n"
  },
  {
    "path": "src/__tests__/connect-test.js",
    "content": "jest.autoMockOff();\n\nconst React = require('react');\nconst { mount } = require('enzyme');\nconst thunk = require('redux-thunk').default;\n\nconst connect = require('../connect').default;\nconst applyMiddleware = require('../connect').applyMiddleware;\n\ndescribe('connect', () => {\n  it('creates a valid component', () => {\n    const reducer = jest.fn(state => state);\n    const Component = connect(reducer, { onClick: 'doClick' })('button');\n    const wrapper = mount(<Component />);\n    wrapper.find('button').simulate('click');\n    expect(reducer.mock.calls[0][0]).toEqual({});\n    expect(reducer.mock.calls[1][1].type).toEqual('doClick');\n  });\n  it('changes a prop as a result', () => {\n    const Button = props => <button {...props} />;\n    const reducer = jest.fn((state, action) => {\n      if (action.type === 'doClick') {\n        return {\n          ...state,\n          isToggled: !state.isToggled,\n        };\n      }\n      return state;\n    });\n    const Component = connect(reducer, { onClick: 'doClick' })(Button);\n    const wrapper = mount(<Component />);\n    const btn = wrapper.find('button');\n    btn.simulate('click');\n    expect(btn.prop('isToggled')).toEqual(true);\n    btn.simulate('click');\n    expect(btn.prop('isToggled')).toEqual(false);\n    wrapper.setProps({ isToggled: true });\n    expect(btn.prop('isToggled')).toEqual(true);\n  });\n  it('hides willReceiveProps behaviour', () => {\n    const Button = props => <button {...props} />;\n    const reducer = jest.fn(state => state);\n    const Component = connect(reducer, {}, {\n      componentWillReceiveProps() {},\n    })(Button);\n    const wrapper = mount(<Component isToggled />);\n    const btn = wrapper.find('button');\n    expect(btn.prop('isToggled')).toEqual(true);\n    wrapper.setProps({ isToggled: false });\n    expect(btn.prop('isToggled')).toEqual(true);\n  });\n  it('update onDidMount', () => {\n    const Button = props => <button {...props} />;\n    const reducer = jest.fn((state, action) => {\n      if (action.type === 'doClick') {\n        return {\n          ...state,\n          isToggled: !state.isToggled,\n        };\n      }\n      return state;\n    });\n    const Component = connect(reducer, {}, {\n      componentDidMount() {\n        this.dispatch({\n          type: 'doClick',\n        });\n      },\n    })(Button);\n    const wrapper = mount(<Component />);\n    const btn = wrapper.find('button');\n    expect(btn.prop('isToggled')).toEqual(true);\n  });\n  it('can handle short form life cycles', () => {\n    const Button = props => <button {...props} />;\n    const reducer = jest.fn((state, action) => {\n      if (action.type === 'doClick') {\n        return {\n          ...state,\n          isToggled: !state.isToggled,\n        };\n      }\n      return state;\n    });\n    const Component = connect(reducer, {}, {\n      componentDidMount: 'doClick',\n    })(Button);\n    const wrapper = mount(<Component />);\n    const btn = wrapper.find('button');\n    expect(btn.prop('isToggled')).toEqual(true);\n  });\n  it('works with middleware like redux-thunk', () => {\n    const Button = props => <button {...props} />;\n    const reducer = jest.fn((state, action) => {\n      if (action.type === 'doClick') {\n        return {\n          ...state,\n          isToggled: !state.isToggled,\n        };\n      }\n      return state;\n    });\n    const ac = applyMiddleware(thunk);\n    const Component = ac(reducer, dispatch => ({\n      onClick: () => {\n        dispatch((disp) => {\n          disp({ type: 'doClick' });\n        });\n      },\n    }))(Button);\n    const wrapper = mount(<Component />);\n    const btn = wrapper.find('button');\n    btn.simulate('click');\n    expect(btn.prop('isToggled')).toEqual(true);\n  });\n});\n"
  },
  {
    "path": "src/config.js",
    "content": "import _ from 'lodash';\nimport PropTypes from 'prop-types';\nimport React from 'react';\n\nconst plugin = {};\nconst functions = {};\n\nconst configurable = (key, defaultFn, argGetter = () => []) => {\n  const apply = fn => (...args) => fn.apply(null, [...args, ...argGetter()]);\n  plugin[key] = (fn) => {\n    functions[key] = apply(fn);\n  };\n  functions[key] = apply(defaultFn);\n  return (...args) => functions[key].apply(null, args);\n};\n\nconst defaultContextTypes = () => ({});\nexport const exposeContextTypes = configurable('exposeContextTypes',\n  defaultContextTypes,\n  () => [PropTypes]);\n\nconst merge = arr => _.assign.apply(_, [{}, ...arr]);\nconst defaultComposeComponent = (Component, {\n  styles = [],\n  style = {},\n  ...rest\n}) => {\n  const mergedStyle = merge([style].concat(styles));\n  return <Component style={mergedStyle} {...rest} />;\n};\nexport const composeComponent = configurable('composeComponent', defaultComposeComponent);\n\nconst defaultRenderChild = props => (Child, index) =>\n  <Child {...props} key={(Child.displayName || '') + index} />;\n\nexport const renderChild = configurable('renderChild', defaultRenderChild);\n\nexport {\n  plugin,\n};\n"
  },
  {
    "path": "src/connect.js",
    "content": "import React from 'react';\nimport _ from 'lodash';\nimport getDisplayName from './getDisplayName';\n\nconst defaultMergeProps = (stateProps, dispatchProps, parentProps) => ({\n  ...parentProps,\n  ...stateProps,\n  ...dispatchProps,\n});\n\nfunction createDispatchProps(dispatchers, dispatch) {\n  if (_.isFunction(dispatchers)) {\n    return dispatchers(dispatch);\n  }\n  function dispatchHandler(fn) {\n    const action = _.isString(fn) ? { type: fn } : fn;\n    return () => dispatch(action);\n  }\n  return _.reduce(dispatchers, (sum, fn, key) =>\n    Object.assign(sum, {\n      [key]: dispatchHandler(fn),\n    }),\n    {});\n}\n\nfunction wrapLifeCycle(fn) {\n  if (!_.isFunction(fn)) {\n    const action = _.isString(fn) ? { type: fn } : fn;\n    return function wrappedStaticLifeCycleMethod() {\n      this.dispatch(action);\n    };\n  }\n  return fn;\n}\n\n\nexport default function connect(reducer,\n  dispatchers,\n  lifeCycle = {},\n  merge = defaultMergeProps,\n  middlewares = []) {\n  return (Component) => {\n    class Connected extends React.Component {\n      constructor(props) {\n        super(props);\n        this.state = reducer(props, {});\n        this.dispatch = this.dispatch.bind(this);\n        const middlewareAPI = {\n          getState: () => this.state,\n          dispatch: this.dispatch,\n        };\n        const chain = middlewares.map(middleware => middleware(middlewareAPI));\n        this.dispatch = [...chain].reduceRight((a, fn) => fn(a), this.dispatch);\n        this.dispatchProps = createDispatchProps(dispatchers, this.dispatch);\n      }\n      componentWillReceiveProps(nextProps) {\n        this.setState(_.omitBy(nextProps, (val, key) =>\n          val === this.state[key]));\n      }\n      getProps() {\n        return merge(this.state, this.dispatchProps, this.props);\n      }\n      dispatch(action) {\n        const nextState = reducer(this.state, action);\n        if (nextState !== this.state) {\n          this.setState(nextState);\n        }\n        return action;\n      }\n      render() {\n        return <Component {...this.getProps()} />;\n      }\n    }\n    Connected.displayName = `connect(${getDisplayName(Component)})`;\n    _.each(lifeCycle, (fn, key) => Object.assign(Connected.prototype, {\n      [key]: wrapLifeCycle(fn),\n    }));\n    return Connected;\n  };\n}\n\nexport function applyMiddleware(...wares) {\n  return (...args) => connect.apply(null,\n    [args[0], args[1], args[2] || {}, args[3] || defaultMergeProps, wares]);\n}\n"
  },
  {
    "path": "src/getDisplayName.js",
    "content": "// https://github.com/jurassix/react-display-name/blob/master/src/getDisplayName.js\nexport default function getDisplayName(Component) {\n  return (\n    Component.displayName ||\n    Component.name ||\n    (typeof Component === 'string' ? Component : 'Component')\n  );\n}\n"
  },
  {
    "path": "src/index.js",
    "content": "import _ from 'lodash';\nimport combineNames from 'classnames';\n\nimport { composeComponent, exposeContextTypes, renderChild } from './config';\nimport getDisplayName from './getDisplayName';\n\n/**\n * aggregates a set of functions/objects into a constant part + a dynamic part\n *\n *\n **/\n\nconst mergeObjArr = (arr) => {\n  const base = _.assign.apply(_, [{}, ...arr]);\n  const styles = _.flatten(_.compact(_.map(arr, 'styles')));\n  if (styles.length > 1) {\n    base.styles = styles;\n  }\n  return base;\n};\n\nexport const optimize = (...propers) => {\n  const flattened = _.compact(_.flattenDeep(propers));\n  const constantStyles = _.takeWhile(flattened, st => !_.isFunction(st)) || [];\n  const dynamic = _.slice(flattened, constantStyles.length, flattened.length) || [];\n  const constant = mergeObjArr(constantStyles);\n  return {\n    constant,\n    dynamic,\n  };\n};\n\nconst flatMap = (arr, fn) => {\n  if (_.isArray(arr)) {\n    return _.flattenDeep(_.map(arr, fn));\n  }\n  return fn(arr);\n};\n\nexport const applyFunctor = (functor, ...args) => {\n  const reapply = f => applyFunctor.apply(null, [f, ...args]);\n  if (_.isArray(functor)) {\n    return flatMap(functor, reapply);\n  }\n  if (_.isFunction(functor)) {\n    return reapply(functor(...args));\n  }\n  return functor;\n};\n\nfunction mergePropers(a, b) {\n  return optimize([a.constant, ...a.dynamic, b.constant, ...b.dynamic]);\n}\n\nexport const compose = (...propers) => {\n  const optimizedPropers = optimize(propers);\n\n  function doCompose(Component, ps) {\n    const ComposedComponent = (props, context) => {\n      const base = { ...props, ...ps.constant };\n      const finalProps = ps.dynamic.reduce((obj, fn) =>\n        Object.assign({}, obj, applyFunctor(fn, obj, context)),\n        base);\n      return composeComponent(Component, finalProps);\n    };\n    ComposedComponent.contextTypes = exposeContextTypes();\n    ComposedComponent.displayName = `composed(${getDisplayName(Component)})`;\n    return ComposedComponent;\n  }\n\n  function mergeComposed(Component) {\n    let Target = Component;\n    let ps = optimizedPropers;\n    if (Component && Component.composedBy) {\n      const {\n        composers,\n        Parent,\n      } = Component.composedBy;\n      ps = mergePropers(optimizedPropers, composers);\n      Target = Parent;\n    }\n    const Result = doCompose(Target, ps);\n    Result.composedBy = {\n      composers: ps,\n      Parent: Target,\n    };\n    return Result;\n  }\n\n  return mergeComposed;\n};\n\nexport const styles = (...stylers) => {\n  const {\n    constant,\n    dynamic,\n  } = optimize(stylers);\n\n  // If all constants, return a constant proper\n  if (dynamic.length === 0) {\n    return {\n      styles: constant,\n    };\n  }\n\n  return (props, context) => {\n    const upstream = props.styles || [];\n    const base = [...upstream, constant];\n    const applied = applyFunctor(dynamic, { ...props, styles: base }, context);\n    const finalStyles = [...base, ...applied];\n    return {\n      styles: finalStyles,\n    };\n  };\n};\n\nexport const children = (...childers) =>\n  props =>\n    ({\n      children: _.map(childers, renderChild(props)),\n    });\n\nfunction handleUpstreamClassName(name) {\n  if (!name) {\n    return {};\n  }\n  if (_.isString(name)) {\n    return {\n      [name]: true,\n    };\n  }\n  return name;\n}\n\nfunction arrayToClassNames(arr) {\n  return _.reduce(arr, (sum, item) =>\n    (_.isString(item) ?\n      { ...sum, [item]: true } :\n      { ...sum, ...item }),\n  {});\n}\n\nexport function classNames(...names) {\n  return (props, context) => ({\n    className: combineNames({\n      ...arrayToClassNames(applyFunctor(names, props, context)),\n      ...handleUpstreamClassName(props.className),\n    }),\n  });\n}\n\nexport function mapProp(property, fn, defaultValue) {\n  return props => ({ [property]: fn(props[property] || defaultValue) });\n}\n"
  }
]