├── src ├── utils │ ├── isPromise.js │ ├── wrapActionCreators.js │ ├── storeShape.js │ ├── objectForEach.js │ ├── shallowEqual.js │ ├── warning.js │ ├── hoist-non-react-statics.js │ └── functions.js ├── index.js ├── component │ ├── PureRenderComponent.js │ ├── Provider.js │ └── connect.js ├── middleware │ └── promiseMiddleware.js ├── createActions.js ├── createStore.js ├── createConfigure.js └── createComponent.js ├── .gitignore ├── lib ├── utils │ ├── isPromise.js │ ├── storeShape.js │ ├── objectForEach.js │ ├── wrapActionCreators.js │ ├── shallowEqual.js │ ├── warning.js │ ├── hoist-non-react-statics.js │ └── functions.js ├── index.js ├── createActions.js ├── middleware │ └── promiseMiddleware.js ├── component │ ├── Provider.js │ ├── PureRenderComponent.js │ └── connect.js ├── createStore.js ├── createConfigure.js └── createComponent.js ├── example └── example │ ├── config │ ├── createRebixComponent.js │ └── RebixConfigure.js │ ├── actions │ ├── PostActions.js │ └── UserActions.js │ ├── views │ ├── index.js │ └── hello.js │ ├── index.html │ └── stores │ ├── PostStore.js │ └── UserStore.js ├── prepublish.js ├── .babelrc ├── webpack.config.js ├── package.json ├── README.md └── dist ├── react-rebix.min.js └── react-rebix.js /src/utils/isPromise.js: -------------------------------------------------------------------------------- 1 | export default function isPromise(p) { 2 | return p && (typeof p.then === 'function') && (typeof p.catch === 'function'); 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | .idea/ 3 | .idea/modules.xml 4 | .idea/rebix.iml 5 | .idea/workspace.xml 6 | node_modules/ 7 | /node_modules/ 8 | .DS_Store -------------------------------------------------------------------------------- /lib/utils/isPromise.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports["default"] = isPromise; 5 | function isPromise(p) { 6 | return p && typeof p.then === 'function' && typeof p["catch"] === 'function'; 7 | } -------------------------------------------------------------------------------- /src/utils/wrapActionCreators.js: -------------------------------------------------------------------------------- 1 | import { bindActionCreators } from 'redux' 2 | 3 | export default function wrapActionCreators(actionCreators) { 4 | return dispatch => bindActionCreators(actionCreators, dispatch) 5 | } 6 | -------------------------------------------------------------------------------- /src/utils/storeShape.js: -------------------------------------------------------------------------------- 1 | import { PropTypes } from 'react' 2 | 3 | export default PropTypes.shape({ 4 | subscribe: PropTypes.func.isRequired, 5 | dispatch: PropTypes.func.isRequired, 6 | getState: PropTypes.func.isRequired 7 | }) 8 | -------------------------------------------------------------------------------- /src/utils/objectForEach.js: -------------------------------------------------------------------------------- 1 | export default function objectForEach(obj, handler) { 2 | for (var key in obj) { 3 | if (key && obj.hasOwnProperty(key)) { 4 | var value = obj[key]; 5 | handler('' + key, value); 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /example/example/config/createRebixComponent.js: -------------------------------------------------------------------------------- 1 | import Rebix from 'react-rebix'; 2 | import RebixConfigure from './RebixConfigure'; 3 | 4 | export default function createRebixComponent(BaseComponentImpl, componentConfig) { 5 | return Rebix.createComponent(RebixConfigure, BaseComponentImpl, componentConfig); 6 | } -------------------------------------------------------------------------------- /lib/utils/storeShape.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | 5 | var _react = require('react'); 6 | 7 | exports["default"] = _react.PropTypes.shape({ 8 | subscribe: _react.PropTypes.func.isRequired, 9 | dispatch: _react.PropTypes.func.isRequired, 10 | getState: _react.PropTypes.func.isRequired 11 | }); -------------------------------------------------------------------------------- /lib/utils/objectForEach.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports["default"] = objectForEach; 5 | function objectForEach(obj, handler) { 6 | for (var key in obj) { 7 | if (key && obj.hasOwnProperty(key)) { 8 | var value = obj[key]; 9 | handler('' + key, value); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /lib/utils/wrapActionCreators.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports["default"] = wrapActionCreators; 5 | 6 | var _redux = require('redux'); 7 | 8 | function wrapActionCreators(actionCreators) { 9 | return function (dispatch) { 10 | return (0, _redux.bindActionCreators)(actionCreators, dispatch); 11 | }; 12 | } -------------------------------------------------------------------------------- /example/example/actions/PostActions.js: -------------------------------------------------------------------------------- 1 | import {createActions} from 'react-rebix'; 2 | 3 | export default createActions({ 4 | 5 | /** 6 | * 异步 Action 7 | * 一定要返回一个Promise对象 8 | */ 9 | getPostList: function (params) { 10 | return new Promise(function (resolve) { 11 | setTimeout(function () { 12 | resolve([new Date().getTime(), params]); 13 | }, 500) 14 | }) 15 | } 16 | 17 | }); -------------------------------------------------------------------------------- /example/example/views/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import RebixConfigure from '../config/RebixConfigure'; 4 | import Rebix,{Provider} from 'react-rebix'; 5 | import Hello from './hello'; 6 | 7 | var store = RebixConfigure.getStore(); 8 | 9 | console.log(store); 10 | ReactDOM.render( 11 | 12 | 13 | , 14 | document.getElementById('root') 15 | ); -------------------------------------------------------------------------------- /example/example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Ubibi 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /example/example/config/RebixConfigure.js: -------------------------------------------------------------------------------- 1 | import Rebix from 'react-rebix'; 2 | import UserActions from '../actions/UserActions'; 3 | import PostActions from '../actions/PostActions'; 4 | import UserStore from '../stores/UserStore'; 5 | import PostStore from '../stores/PostStore'; 6 | 7 | export default Rebix.createConfigure({ 8 | 9 | initialState: null, 10 | 11 | actions: { 12 | user: UserActions, 13 | post: PostActions 14 | }, 15 | 16 | stores: { 17 | user: UserStore, 18 | post: PostStore 19 | }, 20 | 21 | middleware: [ 22 | 'promiseMiddleware' 23 | ] 24 | 25 | }); -------------------------------------------------------------------------------- /src/utils/shallowEqual.js: -------------------------------------------------------------------------------- 1 | export default function shallowEqual(objA, objB) { 2 | if (objA === objB) { 3 | return true 4 | } 5 | 6 | const keysA = Object.keys(objA) 7 | const keysB = Object.keys(objB) 8 | 9 | if (keysA.length !== keysB.length) { 10 | return false 11 | } 12 | 13 | // Test for A's keys different from B. 14 | const hasOwn = Object.prototype.hasOwnProperty 15 | for (let i = 0; i < keysA.length; i++) { 16 | if (!hasOwn.call(objB, keysA[i]) || 17 | objA[keysA[i]] !== objB[keysA[i]]) { 18 | return false 19 | } 20 | } 21 | 22 | return true 23 | } 24 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import createActions from './createActions'; 2 | import createComponent from './createComponent'; 3 | import createStore from './createStore'; 4 | import createConfigure from './createConfigure'; 5 | import Provider from './component/Provider'; 6 | import PureRenderComponent from './component/PureRenderComponent'; 7 | 8 | var Reubibi = { 9 | createActions: createActions, 10 | createComponent: createComponent, 11 | createStore: createStore, 12 | createConfigure: createConfigure, 13 | Provider: Provider, 14 | PureRenderComponent:PureRenderComponent 15 | }; 16 | 17 | 18 | module.exports = Reubibi; 19 | //export default Reubibi; 20 | -------------------------------------------------------------------------------- /lib/utils/shallowEqual.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | exports.__esModule = true; 4 | exports["default"] = shallowEqual; 5 | function shallowEqual(objA, objB) { 6 | if (objA === objB) { 7 | return true; 8 | } 9 | 10 | var keysA = Object.keys(objA); 11 | var keysB = Object.keys(objB); 12 | 13 | if (keysA.length !== keysB.length) { 14 | return false; 15 | } 16 | 17 | // Test for A's keys different from B. 18 | var hasOwn = Object.prototype.hasOwnProperty; 19 | for (var i = 0; i < keysA.length; i++) { 20 | if (!hasOwn.call(objB, keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) { 21 | return false; 22 | } 23 | } 24 | 25 | return true; 26 | } -------------------------------------------------------------------------------- /src/component/PureRenderComponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import shallowEqual from '../utils/shallowEqual' 3 | 4 | 5 | export function shallowCompare(component, nextProps, nextState) { 6 | return !shallowEqual(component.props, nextProps) || !shallowEqual(component.state, nextState); 7 | } 8 | 9 | /** 10 | * React组件基础类, 浅层检查props和state是否更改, 未更改则不重新渲染 11 | * 注意: 在不使用immutable.js作为数据源格式时, 请确保浅层检查不会阻止渲染! 12 | */ 13 | export default class PureRenderComponent extends React.Component { 14 | shouldComponentUpdate(nextProps, nextState) { 15 | var isOk = shallowCompare(this, nextProps, nextState); 16 | //console.log('shallowCompare',isOk) 17 | return isOk; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /prepublish.js: -------------------------------------------------------------------------------- 1 | var glob = require('glob'); 2 | var fs = require('fs'); 3 | var es3ify = require('es3ify'); 4 | 5 | glob('./@(lib|dist)/**/*.js', function (err, files) { 6 | if (err) { 7 | throw err 8 | } 9 | 10 | files.forEach(function (file) { 11 | fs.readFile(file, 'utf8', function (err, data) { 12 | if (err) { 13 | throw err 14 | } 15 | 16 | fs.writeFile(file, es3ify.transform(data), function (err) { 17 | if (err) { 18 | throw err 19 | } 20 | //eslint-disable-line no-console 21 | console.log('es3ified ' + file) 22 | }) 23 | }) 24 | }) 25 | }); -------------------------------------------------------------------------------- /src/component/Provider.js: -------------------------------------------------------------------------------- 1 | import {Component,PropTypes, Children } from 'react' 2 | import storeShape from '../utils/storeShape' 3 | 4 | 5 | export default class Provider extends Component { 6 | getChildContext() { 7 | return {store: this.store} 8 | } 9 | 10 | constructor(props, context) { 11 | super(props, context) 12 | this.store = props.store 13 | } 14 | 15 | render() { 16 | const { children } = this.props; 17 | return Children.only(children); 18 | } 19 | } 20 | 21 | 22 | Provider.propTypes = { 23 | store: storeShape.isRequired, 24 | children: PropTypes.element.isRequired 25 | }; 26 | Provider.childContextTypes = { 27 | store: storeShape.isRequired 28 | }; 29 | -------------------------------------------------------------------------------- /src/utils/warning.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Prints a warning in the console if it exists. 3 | * 4 | * @param {String} message The warning message. 5 | * @returns {void} 6 | */ 7 | export default function warning(message) { 8 | /* eslint-disable no-console */ 9 | if (typeof console !== 'undefined' && typeof console.error === 'function') { 10 | console.error(message) 11 | } 12 | /* eslint-enable no-console */ 13 | try { 14 | // This error was thrown as a convenience so that you can use this stack 15 | // to find the callsite that caused this warning to fire. 16 | throw new Error(message) 17 | /* eslint-disable no-empty */ 18 | } catch (e) { 19 | } 20 | /* eslint-enable no-empty */ 21 | } 22 | -------------------------------------------------------------------------------- /lib/utils/warning.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports["default"] = warning; 5 | /** 6 | * Prints a warning in the console if it exists. 7 | * 8 | * @param {String} message The warning message. 9 | * @returns {void} 10 | */ 11 | function warning(message) { 12 | /* eslint-disable no-console */ 13 | if (typeof console !== 'undefined' && typeof console.error === 'function') { 14 | console.error(message); 15 | } 16 | /* eslint-enable no-console */ 17 | try { 18 | // This error was thrown as a convenience so that you can use this stack 19 | // to find the callsite that caused this warning to fire. 20 | throw new Error(message); 21 | /* eslint-disable no-empty */ 22 | } catch (e) {} 23 | /* eslint-enable no-empty */ 24 | } -------------------------------------------------------------------------------- /example/example/stores/PostStore.js: -------------------------------------------------------------------------------- 1 | import Rebix from 'react-rebix'; 2 | 3 | 4 | function wrapperOnName(name,innerFunc){ 5 | return function (state, action){ 6 | if(action.name!==name){ 7 | return state; 8 | } 9 | return innerFunc(state,action); 10 | } 11 | } 12 | 13 | function createPostStore(name) { 14 | 15 | var wrapperOnName = wrapperOnName.bind({},name); 16 | 17 | return Rebix.createStore({ 18 | 19 | initialState: { 20 | postList: [] 21 | }, 22 | 23 | 'onGetPostList': wrapperOnName(function (state, action) { 24 | state = Object.assign({}, state); 25 | var postList = action.payload; 26 | state.postList = postList; 27 | return state; 28 | }) 29 | 30 | }); 31 | 32 | } 33 | 34 | 35 | export default createPostStore(); 36 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | plugins: [ 3 | "transform-decorators-legacy", 4 | ["transform-es2015-template-literals", { "loose": true }], 5 | "transform-es2015-literals", 6 | "transform-es2015-function-name", 7 | "transform-es2015-arrow-functions", 8 | "transform-es2015-block-scoped-functions", 9 | ["transform-es2015-classes", { "loose": true }], 10 | "transform-es2015-object-super", 11 | "transform-es2015-shorthand-properties", 12 | ["transform-es2015-computed-properties", { "loose": true }], 13 | ["transform-es2015-for-of", { "loose": true }], 14 | "transform-es2015-sticky-regex", 15 | "transform-es2015-unicode-regex", 16 | "check-es2015-constants", 17 | ["transform-es2015-spread", { "loose": true }], 18 | "transform-es2015-parameters", 19 | ["transform-es2015-destructuring", { "loose": true }], 20 | "transform-es2015-block-scoping", 21 | ["transform-es2015-modules-commonjs", { "loose": true }], 22 | "transform-object-rest-spread", 23 | "transform-react-jsx", 24 | "syntax-jsx" 25 | ] 26 | } -------------------------------------------------------------------------------- /example/example/actions/UserActions.js: -------------------------------------------------------------------------------- 1 | import Rebix from 'react-rebix'; 2 | import UserStore from '../stores/UserStore'; 3 | 4 | export default Rebix.createActions({ 5 | 6 | /** 7 | * 异步 Action 8 | * 一定要返回一个Promise对象 9 | */ 10 | getUserInfo: function (params) { 11 | 12 | //Action 中开源访问Store中的数据,但是只能调用get方法 13 | var userInfo = UserStore.getUserInfo(123); 14 | 15 | return new Promise(function (resolve) { 16 | setTimeout(function () { 17 | //store层使用action.promise字段接受返回值 18 | resolve({ 19 | time: new Date().getTime(), 20 | userInfo: userInfo, 21 | params: params 22 | }); 23 | }, 1000) 24 | }) 25 | }, 26 | 27 | 28 | /** 29 | * 普通 Action 30 | */ 31 | getUserList: function (params) { 32 | //store层使用action.payload字段接受返回值 33 | return [1, 2, 3, params]; 34 | }, 35 | 36 | 37 | /** 38 | * 空Action, 不需要具体的实现 39 | * 具体操作在Store中完成. 40 | */ 41 | beginEditUserInfo: null, 42 | 43 | /** 44 | * 空Action, 不需要具体的实现 45 | * 具体操作在Store中完成. 46 | */ 47 | endEditUserInfo: null 48 | 49 | }); -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _createActions = require('./createActions'); 4 | 5 | var _createActions2 = _interopRequireDefault(_createActions); 6 | 7 | var _createComponent = require('./createComponent'); 8 | 9 | var _createComponent2 = _interopRequireDefault(_createComponent); 10 | 11 | var _createStore = require('./createStore'); 12 | 13 | var _createStore2 = _interopRequireDefault(_createStore); 14 | 15 | var _createConfigure = require('./createConfigure'); 16 | 17 | var _createConfigure2 = _interopRequireDefault(_createConfigure); 18 | 19 | var _Provider = require('./component/Provider'); 20 | 21 | var _Provider2 = _interopRequireDefault(_Provider); 22 | 23 | var _PureRenderComponent = require('./component/PureRenderComponent'); 24 | 25 | var _PureRenderComponent2 = _interopRequireDefault(_PureRenderComponent); 26 | 27 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 28 | 29 | var Reubibi = { 30 | createActions: _createActions2["default"], 31 | createComponent: _createComponent2["default"], 32 | createStore: _createStore2["default"], 33 | createConfigure: _createConfigure2["default"], 34 | Provider: _Provider2["default"], 35 | PureRenderComponent: _PureRenderComponent2["default"] 36 | }; 37 | 38 | module.exports = Reubibi; 39 | //export default Reubibi; -------------------------------------------------------------------------------- /src/middleware/promiseMiddleware.js: -------------------------------------------------------------------------------- 1 | import isPromise from '../utils/isPromise'; 2 | 3 | 4 | export default function promiseMiddleware(_ref) { 5 | 6 | const dispatch = _ref.dispatch; 7 | 8 | return next => action => { 9 | 10 | if (!isPromise(action.promise)) { 11 | action.status = 'success'; 12 | return next(action); 13 | } 14 | 15 | var {type,group,name,status,args,payload,promise} = action; 16 | 17 | const createAction = function (status1, promise1, payload1) { 18 | return { 19 | type: type, 20 | group: group, 21 | name: name, 22 | status: status1, 23 | args: args, 24 | promise: promise1, 25 | payload: payload1 //object or promise 26 | }; 27 | }; 28 | 29 | promise = promise.then( 30 | (resolved = {}) => { 31 | var successAction = createAction('success', null, resolved); 32 | return dispatch(successAction); 33 | }, 34 | 35 | (rejected = {}) => { 36 | var errorAction = createAction('error', null, rejected); 37 | return dispatch(errorAction); 38 | } 39 | ); 40 | 41 | 42 | var pendingAction = createAction('pending', promise, null); 43 | return next(pendingAction); 44 | }; 45 | 46 | } 47 | -------------------------------------------------------------------------------- /lib/utils/hoist-non-react-statics.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | var REACT_STATICS = { 8 | childContextTypes: true, 9 | contextTypes: true, 10 | defaultProps: true, 11 | displayName: true, 12 | getDefaultProps: true, 13 | mixins: true, 14 | propTypes: true, 15 | type: true 16 | }; 17 | 18 | var KNOWN_STATICS = { 19 | name: true, 20 | length: true, 21 | prototype: true, 22 | caller: true, 23 | arguments: true, 24 | arity: true 25 | }; 26 | 27 | var isGetOwnPropertySymbolsAvailable = typeof Object.getOwnPropertySymbols === 'function'; 28 | 29 | module.exports = function hoistNonReactStatics(targetComponent, sourceComponent, customStatics) { 30 | if (typeof sourceComponent !== 'string') { 31 | // don't hoist over string (html) components 32 | var keys = Object.getOwnPropertyNames(sourceComponent); 33 | 34 | /* istanbul ignore else */ 35 | if (isGetOwnPropertySymbolsAvailable) { 36 | keys = keys.concat(Object.getOwnPropertySymbols(sourceComponent)); 37 | } 38 | 39 | for (var i = 0; i < keys.length; ++i) { 40 | if (!REACT_STATICS[keys[i]] && !KNOWN_STATICS[keys[i]] && (!customStatics || !customStatics[keys[i]])) { 41 | try { 42 | targetComponent[keys[i]] = sourceComponent[keys[i]]; 43 | } catch (error) {} 44 | } 45 | } 46 | } 47 | 48 | return targetComponent; 49 | }; -------------------------------------------------------------------------------- /src/createActions.js: -------------------------------------------------------------------------------- 1 | import objectForEach from './utils/objectForEach'; 2 | import isPromise from './utils/isPromise'; 3 | 4 | /** 5 | * action函数的一个空实现 6 | */ 7 | function nullActionImpl() { 8 | return null; 9 | } 10 | 11 | function createActionImplWrapper(actionImpl, key, actionsConfig) { 12 | //ActionImplWrapper 13 | //这是真正被调用的action函数 14 | return function (group, args) { 15 | //var args = [].concat(arguments); 16 | var actionResult = actionImpl.apply(actionsConfig, args); 17 | 18 | var promise = null; 19 | var payload = null; 20 | if (isPromise(actionResult)) { 21 | promise = actionResult; 22 | } else { 23 | payload = actionResult; 24 | } 25 | 26 | return { 27 | type: group + "_" + key, 28 | group: group, //例如:user或post,是在createConfigure中配置的..这个玩意只有完成createConfigure之后才能知道,所以需要从参数中传过来 29 | name: key, //例如:getUserList 30 | status: "unknown",//pending,error,success 31 | args: args, 32 | promise: promise, 33 | payload: payload 34 | } 35 | }; 36 | } 37 | 38 | 39 | export default function createActions(actionsConfig) { 40 | var actions = {}; 41 | 42 | objectForEach(actionsConfig, function (key, actionImpl) { 43 | 44 | //空Action 45 | if (!actionImpl) { 46 | actionImpl = nullActionImpl; 47 | } 48 | 49 | //这是真正被调用的action函数 50 | actions[key] = createActionImplWrapper(actionImpl, key, actionsConfig); 51 | }); 52 | 53 | 54 | return actions; 55 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var webpack = require('webpack'); 4 | var env = process.env.NODE_ENV; 5 | 6 | var reactExternal = { 7 | root: 'React', 8 | commonjs2: 'react', 9 | commonjs: 'react', 10 | amd: 'react' 11 | }; 12 | 13 | var config = { 14 | externals: { 15 | 'react': reactExternal 16 | }, 17 | module: { 18 | loaders: [ 19 | { test: /\.js$/, loaders: ['babel-loader'], exclude: /node_modules/ } 20 | ] 21 | }, 22 | output: { 23 | library: 'ReactRebix', 24 | libraryTarget: 'umd' 25 | }, 26 | plugins: [ 27 | { 28 | apply: function apply(compiler) { 29 | compiler.parser.plugin('expression global', function expressionGlobalPlugin() { 30 | this.state.module.addVariable('global', "(function() { return this; }()) || Function('return this')()") 31 | return false 32 | }) 33 | } 34 | }, 35 | new webpack.optimize.OccurenceOrderPlugin(), 36 | new webpack.DefinePlugin({ 37 | 'process.env.NODE_ENV': JSON.stringify(env) 38 | }) 39 | ] 40 | }; 41 | 42 | if (env === 'production') { 43 | config.plugins.push( 44 | new webpack.optimize.UglifyJsPlugin({ 45 | compressor: { 46 | pure_getters: true, 47 | unsafe: true, 48 | unsafe_comps: true, 49 | screw_ie8: true, 50 | warnings: false 51 | } 52 | }) 53 | ) 54 | } 55 | 56 | module.exports = config; 57 | -------------------------------------------------------------------------------- /src/utils/hoist-non-react-statics.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015, Yahoo! Inc. 3 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 4 | */ 5 | 'use strict'; 6 | 7 | var REACT_STATICS = { 8 | childContextTypes: true, 9 | contextTypes: true, 10 | defaultProps: true, 11 | displayName: true, 12 | getDefaultProps: true, 13 | mixins: true, 14 | propTypes: true, 15 | type: true 16 | }; 17 | 18 | var KNOWN_STATICS = { 19 | name: true, 20 | length: true, 21 | prototype: true, 22 | caller: true, 23 | arguments: true, 24 | arity: true 25 | }; 26 | 27 | var isGetOwnPropertySymbolsAvailable = typeof Object.getOwnPropertySymbols === 'function'; 28 | 29 | module.exports = function hoistNonReactStatics(targetComponent, sourceComponent, customStatics) { 30 | if (typeof sourceComponent !== 'string') { // don't hoist over string (html) components 31 | var keys = Object.getOwnPropertyNames(sourceComponent); 32 | 33 | /* istanbul ignore else */ 34 | if (isGetOwnPropertySymbolsAvailable) { 35 | keys = keys.concat(Object.getOwnPropertySymbols(sourceComponent)); 36 | } 37 | 38 | for (var i = 0; i < keys.length; ++i) { 39 | if (!REACT_STATICS[keys[i]] && !KNOWN_STATICS[keys[i]] && (!customStatics || !customStatics[keys[i]])) { 40 | try { 41 | targetComponent[keys[i]] = sourceComponent[keys[i]]; 42 | } catch (error) { 43 | 44 | } 45 | } 46 | } 47 | } 48 | 49 | return targetComponent; 50 | }; -------------------------------------------------------------------------------- /example/example/stores/UserStore.js: -------------------------------------------------------------------------------- 1 | import Rebix from 'react-rebix'; 2 | 3 | 4 | export default Rebix.createStore({ 5 | 6 | initialState: { 7 | userList: [], 8 | postList: [] 9 | }, 10 | 11 | 'onGetUserList': function (state, action) { 12 | console.log(action.status); 13 | state = Object.assign({}, state); 14 | var userList = action.payload; 15 | state.userList = userList; 16 | return state; 17 | }, 18 | 19 | 20 | 'onBeginEditUserInfo': function (state) { 21 | state = Object.assign({}, state); 22 | state.isEditing = true; 23 | return state; 24 | }, 25 | 26 | 27 | 'onEndEditUserInfo': function (state) { 28 | state = Object.assign({}, state); 29 | state.isEditing = false; 30 | return state; 31 | }, 32 | 33 | 34 | /** 35 | * 通过CreateStore创建的on函数 36 | * View层根本调用不到. 37 | * 这样就保证了单项数据流 38 | */ 39 | 'post#onGetPostList': function (state, {status,payload}) { 40 | console.log(action.status); 41 | if (action.status === 'success') { 42 | state = Object.assign({}, state); 43 | var postList = action.payload; 44 | state.postList = postList; 45 | } 46 | 47 | return state; 48 | }, 49 | 50 | 51 | /** 52 | * Get函数,修改state不管用.state内部一般都是使用immutable对象,只有on函数的返回值才能对state进行修改. 53 | * View 层,可以直接调用Get函数获取Store中的数据,但是无法修改. 54 | * 在Get函数内部对state的任何修改,都不会生效. 55 | */ 56 | 'getUserInfo': function (state, a, b, c, d) { 57 | return { 58 | name: a 59 | }; 60 | } 61 | 62 | 63 | }); 64 | 65 | -------------------------------------------------------------------------------- /src/utils/functions.js: -------------------------------------------------------------------------------- 1 | const _undefined = undefined; 2 | 3 | export function isType(x, type) { 4 | return Object.prototype.toString.call(x) === '[object ' + type + ']'; 5 | } 6 | 7 | export function isFunction(x) { 8 | return isType(x, 'Function'); 9 | } 10 | export function isString(x) { 11 | return isType(x, 'String'); 12 | } 13 | 14 | 15 | export function toArray(aaa) { 16 | if (!aaa) { 17 | return []; 18 | } 19 | 20 | var argsArray = Array.prototype.slice.call(aaa); 21 | var args = [].concat(argsArray); 22 | return args; 23 | } 24 | 25 | export function getValueByKey(obj, key) { 26 | if (!obj) { 27 | return null; 28 | } 29 | var value = _undefined; 30 | if (isFunction(obj.get)) { 31 | value = obj.get(key); 32 | } 33 | if (value === _undefined) { 34 | value = obj[key]; 35 | } 36 | 37 | return value; 38 | } 39 | 40 | 41 | /** 42 | * a = { 43 | * b:{ 44 | * c:{ 45 | * d:1 46 | * } 47 | * } 48 | * } 49 | * 50 | * str : b.c.d 51 | * @param obj 52 | * @param str 53 | * @demo : 54 | * var d = getObjectValue(a,'b.c.d'); 55 | */ 56 | export function getValueInPath(obj, str) { 57 | if (!obj) { 58 | return null; 59 | } 60 | try { 61 | var propArr = str.split("."); 62 | var tmpObj = obj; 63 | var i = 0; 64 | while (i < propArr.length) { 65 | if (!tmpObj) { 66 | return null; 67 | } 68 | var prop = propArr[i]; 69 | tmpObj = getValueByKey(tmpObj, prop); 70 | i++; 71 | } 72 | return tmpObj; 73 | } catch (e) { 74 | console.log('[ERROR]', e); 75 | } 76 | 77 | return null; 78 | } -------------------------------------------------------------------------------- /lib/createActions.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports["default"] = createActions; 5 | 6 | var _objectForEach = require('./utils/objectForEach'); 7 | 8 | var _objectForEach2 = _interopRequireDefault(_objectForEach); 9 | 10 | var _isPromise = require('./utils/isPromise'); 11 | 12 | var _isPromise2 = _interopRequireDefault(_isPromise); 13 | 14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 15 | 16 | /** 17 | * action函数的一个空实现 18 | */ 19 | function nullActionImpl() { 20 | return null; 21 | } 22 | 23 | function createActionImplWrapper(actionImpl, key, actionsConfig) { 24 | //ActionImplWrapper 25 | //这是真正被调用的action函数 26 | return function (group, args) { 27 | //var args = [].concat(arguments); 28 | var actionResult = actionImpl.apply(actionsConfig, args); 29 | 30 | var promise = null; 31 | var payload = null; 32 | if ((0, _isPromise2["default"])(actionResult)) { 33 | promise = actionResult; 34 | } else { 35 | payload = actionResult; 36 | } 37 | 38 | return { 39 | type: group + "_" + key, 40 | group: group, //例如:user或post,是在createConfigure中配置的..这个玩意只有完成createConfigure之后才能知道,所以需要从参数中传过来 41 | name: key, //例如:getUserList 42 | status: "unknown", //pending,error,success 43 | args: args, 44 | promise: promise, 45 | payload: payload 46 | }; 47 | }; 48 | } 49 | 50 | function createActions(actionsConfig) { 51 | var actions = {}; 52 | 53 | (0, _objectForEach2["default"])(actionsConfig, function (key, actionImpl) { 54 | 55 | //空Action 56 | if (!actionImpl) { 57 | actionImpl = nullActionImpl; 58 | } 59 | 60 | //这是真正被调用的action函数 61 | actions[key] = createActionImplWrapper(actionImpl, key, actionsConfig); 62 | }); 63 | 64 | return actions; 65 | } -------------------------------------------------------------------------------- /lib/utils/functions.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports.isType = isType; 5 | exports.isFunction = isFunction; 6 | exports.isString = isString; 7 | exports.toArray = toArray; 8 | exports.getValueByKey = getValueByKey; 9 | exports.getValueInPath = getValueInPath; 10 | var _undefined = undefined; 11 | 12 | function isType(x, type) { 13 | return Object.prototype.toString.call(x) === '[object ' + type + ']'; 14 | } 15 | 16 | function isFunction(x) { 17 | return isType(x, 'Function'); 18 | } 19 | function isString(x) { 20 | return isType(x, 'String'); 21 | } 22 | 23 | function toArray(aaa) { 24 | if (!aaa) { 25 | return []; 26 | } 27 | 28 | var argsArray = Array.prototype.slice.call(aaa); 29 | var args = [].concat(argsArray); 30 | return args; 31 | } 32 | 33 | function getValueByKey(obj, key) { 34 | if (!obj) { 35 | return null; 36 | } 37 | var value = _undefined; 38 | if (isFunction(obj.get)) { 39 | value = obj.get(key); 40 | } 41 | if (value === _undefined) { 42 | value = obj[key]; 43 | } 44 | 45 | return value; 46 | } 47 | 48 | /** 49 | * a = { 50 | * b:{ 51 | * c:{ 52 | * d:1 53 | * } 54 | * } 55 | * } 56 | * 57 | * str : b.c.d 58 | * @param obj 59 | * @param str 60 | * @demo : 61 | * var d = getObjectValue(a,'b.c.d'); 62 | */ 63 | function getValueInPath(obj, str) { 64 | if (!obj) { 65 | return null; 66 | } 67 | try { 68 | var propArr = str.split("."); 69 | var tmpObj = obj; 70 | var i = 0; 71 | while (i < propArr.length) { 72 | if (!tmpObj) { 73 | return null; 74 | } 75 | var prop = propArr[i]; 76 | tmpObj = getValueByKey(tmpObj, prop); 77 | i++; 78 | } 79 | return tmpObj; 80 | } catch (e) { 81 | console.log('[ERROR]', e); 82 | } 83 | 84 | return null; 85 | } -------------------------------------------------------------------------------- /example/example/views/hello.js: -------------------------------------------------------------------------------- 1 | import React, {PropTypes} from 'react'; 2 | import createRebixComponent from '../config/createRebixComponent'; 3 | import UserStore from '../stores/UserStore'; 4 | 5 | 6 | class Hello extends React.Component { 7 | 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | userInfo: {} 12 | }; 13 | } 14 | 15 | componentDidMount() { 16 | var that = this; 17 | var {actions} = that.props; 18 | var mm = actions.getUserList(1234); 19 | var mm2 = actions.beginEditUserInfo(1234); 20 | 21 | 22 | actions.getPostList('absdf', 'sdf').then(function () { 23 | debugger; 24 | }); 25 | 26 | setTimeout(function () { 27 | //直接访问Store中的数据 28 | var userInfo = UserStore.getUserInfo(121); 29 | that.setState({userInfo: userInfo}); 30 | }, 2000) 31 | } 32 | 33 | 34 | render() { 35 | var userList = this.props.userList || []; 36 | var postList = this.props.postList || []; 37 | var userInfo = this.state.userInfo || {}; 38 | 39 | return ( 40 |
41 | aaa---{userInfo.name} 42 |
43 | bbb--- 44 | {userList.map(function (x) { 45 | return
{x}
46 | })} 47 |
48 | ccc--- 49 | {postList.map(function (x) { 50 | return
{x}
51 | })} 52 |
53 | ); 54 | 55 | } 56 | 57 | } 58 | 59 | 60 | export default createRebixComponent(Hello, { 61 | 62 | actions: { 63 | getUserList: 'user.getUserList', 64 | getPostList: 'post.getPostList', 65 | beginEditUserInfo: 'user.beginEditUserInfo' 66 | }, 67 | 68 | props: { 69 | userList: 'user.userList', 70 | postList: 'user.postList' 71 | } 72 | 73 | }); -------------------------------------------------------------------------------- /lib/middleware/promiseMiddleware.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports["default"] = promiseMiddleware; 5 | 6 | var _isPromise = require('../utils/isPromise'); 7 | 8 | var _isPromise2 = _interopRequireDefault(_isPromise); 9 | 10 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 11 | 12 | function promiseMiddleware(_ref) { 13 | 14 | var dispatch = _ref.dispatch; 15 | 16 | return function (next) { 17 | return function (action) { 18 | 19 | if (!(0, _isPromise2["default"])(action.promise)) { 20 | action.status = 'success'; 21 | return next(action); 22 | } 23 | 24 | var type = action.type, 25 | group = action.group, 26 | name = action.name, 27 | status = action.status, 28 | args = action.args, 29 | payload = action.payload, 30 | promise = action.promise; 31 | 32 | 33 | var createAction = function createAction(status1, promise1, payload1) { 34 | return { 35 | type: type, 36 | group: group, 37 | name: name, 38 | status: status1, 39 | args: args, 40 | promise: promise1, 41 | payload: payload1 //object or promise 42 | }; 43 | }; 44 | 45 | promise = promise.then(function () { 46 | var resolved = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 47 | 48 | var successAction = createAction('success', null, resolved); 49 | return dispatch(successAction); 50 | }, function () { 51 | var rejected = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 52 | 53 | var errorAction = createAction('error', null, rejected); 54 | return dispatch(errorAction); 55 | }); 56 | 57 | var pendingAction = createAction('pending', promise, null); 58 | return next(pendingAction); 59 | }; 60 | }; 61 | } -------------------------------------------------------------------------------- /lib/component/Provider.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports["default"] = undefined; 5 | 6 | var _react = require('react'); 7 | 8 | var _storeShape = require('../utils/storeShape'); 9 | 10 | var _storeShape2 = _interopRequireDefault(_storeShape); 11 | 12 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 13 | 14 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 15 | 16 | function _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; } 17 | 18 | function _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; } 19 | 20 | var Provider = function (_Component) { 21 | _inherits(Provider, _Component); 22 | 23 | Provider.prototype.getChildContext = function getChildContext() { 24 | return { store: this.store }; 25 | }; 26 | 27 | function Provider(props, context) { 28 | _classCallCheck(this, Provider); 29 | 30 | var _this = _possibleConstructorReturn(this, _Component.call(this, props, context)); 31 | 32 | _this.store = props.store; 33 | return _this; 34 | } 35 | 36 | Provider.prototype.render = function render() { 37 | var children = this.props.children; 38 | 39 | return _react.Children.only(children); 40 | }; 41 | 42 | return Provider; 43 | }(_react.Component); 44 | 45 | exports["default"] = Provider; 46 | 47 | 48 | Provider.propTypes = { 49 | store: _storeShape2["default"].isRequired, 50 | children: _react.PropTypes.element.isRequired 51 | }; 52 | Provider.childContextTypes = { 53 | store: _storeShape2["default"].isRequired 54 | }; -------------------------------------------------------------------------------- /lib/component/PureRenderComponent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports["default"] = undefined; 5 | exports.shallowCompare = shallowCompare; 6 | 7 | var _react = require('react'); 8 | 9 | var _react2 = _interopRequireDefault(_react); 10 | 11 | var _shallowEqual = require('../utils/shallowEqual'); 12 | 13 | var _shallowEqual2 = _interopRequireDefault(_shallowEqual); 14 | 15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 16 | 17 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 18 | 19 | function _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; } 20 | 21 | function _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; } 22 | 23 | function shallowCompare(component, nextProps, nextState) { 24 | return !(0, _shallowEqual2["default"])(component.props, nextProps) || !(0, _shallowEqual2["default"])(component.state, nextState); 25 | } 26 | 27 | /** 28 | * React组件基础类, 浅层检查props和state是否更改, 未更改则不重新渲染 29 | * 注意: 在不使用immutable.js作为数据源格式时, 请确保浅层检查不会阻止渲染! 30 | */ 31 | 32 | var PureRenderComponent = function (_React$Component) { 33 | _inherits(PureRenderComponent, _React$Component); 34 | 35 | function PureRenderComponent() { 36 | _classCallCheck(this, PureRenderComponent); 37 | 38 | return _possibleConstructorReturn(this, _React$Component.apply(this, arguments)); 39 | } 40 | 41 | PureRenderComponent.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) { 42 | var isOk = shallowCompare(this, nextProps, nextState); 43 | //console.log('shallowCompare',isOk) 44 | return isOk; 45 | }; 46 | 47 | return PureRenderComponent; 48 | }(_react2["default"].Component); 49 | 50 | exports["default"] = PureRenderComponent; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-rebix", 3 | "version": "1.0.6", 4 | "description": "react data flow framework", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build:lib": "babel src --out-dir lib", 9 | "build:umd": "cross-env NODE_ENV=development webpack src/index.js dist/react-rebix.js", 10 | "build:umd:min": "cross-env NODE_ENV=production webpack src/index.js dist/react-rebix.min.js", 11 | "build": "npm run build:lib && npm run build:umd && npm run build:umd:min && node ./prepublish", 12 | "clean": "rimraf lib dist coverage" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/luanhaipeng/rebix.git" 17 | }, 18 | "keywords": [ 19 | "react", 20 | "rebix", 21 | "data", 22 | "flow" 23 | ], 24 | "author": "ubibi.cn", 25 | "license": "ISC", 26 | "bugs": { 27 | "url": "https://github.com/luanhaipeng/rebix/issues" 28 | }, 29 | "homepage": "https://github.com/luanhaipeng/rebix#readme", 30 | "devDependencies": { 31 | "babel-cli": "^6.3.17", 32 | "babel-core": "^6.3.26", 33 | "babel-eslint": "^5.0.0-beta9", 34 | "babel-loader": "^6.2.0", 35 | "babel-plugin-check-es2015-constants": "^6.3.13", 36 | "babel-plugin-syntax-jsx": "^6.3.13", 37 | "babel-plugin-transform-decorators-legacy": "^1.2.0", 38 | "babel-plugin-transform-es2015-arrow-functions": "^6.3.13", 39 | "babel-plugin-transform-es2015-block-scoped-functions": "^6.3.13", 40 | "babel-plugin-transform-es2015-block-scoping": "^6.3.13", 41 | "babel-plugin-transform-es2015-classes": "^6.3.13", 42 | "babel-plugin-transform-es2015-computed-properties": "^6.3.13", 43 | "babel-plugin-transform-es2015-destructuring": "^6.3.13", 44 | "babel-plugin-transform-es2015-for-of": "^6.3.13", 45 | "babel-plugin-transform-es2015-function-name": "^6.3.13", 46 | "babel-plugin-transform-es2015-literals": "^6.3.13", 47 | "babel-plugin-transform-es2015-modules-commonjs": "^6.3.13", 48 | "babel-plugin-transform-es2015-object-super": "^6.3.13", 49 | "babel-plugin-transform-es2015-parameters": "^6.3.13", 50 | "babel-plugin-transform-es2015-shorthand-properties": "^6.3.13", 51 | "babel-plugin-transform-es2015-spread": "^6.3.13", 52 | "babel-plugin-transform-es2015-sticky-regex": "^6.3.13", 53 | "babel-plugin-transform-es2015-template-literals": "^6.3.13", 54 | "babel-plugin-transform-es2015-unicode-regex": "^6.3.13", 55 | "babel-plugin-transform-object-rest-spread": "^6.3.13", 56 | "babel-plugin-transform-react-display-name": "^6.4.0", 57 | "babel-plugin-transform-react-jsx": "^6.4.0", 58 | "babel-register": "^6.3.13", 59 | "cross-env": "^1.0.7", 60 | "es3ify": "^0.2.0", 61 | "eslint": "^1.7.1", 62 | "eslint-config-rackt": "1.1.0", 63 | "eslint-plugin-react": "^3.6.3", 64 | "glob": "^6.0.4", 65 | "isparta": "4.0.0", 66 | "istanbul": "^0.3.17", 67 | "jsdom": "~5.4.3", 68 | "react": "^15.4.0", 69 | "rimraf": "^2.3.4", 70 | "webpack": "^1.11.0" 71 | }, 72 | "dependencies": { 73 | "lodash": "^4.2.0", 74 | "redux": "^3.6.0" 75 | }, 76 | "browserify": { 77 | "transform": [ 78 | "loose-envify" 79 | ] 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/createStore.js: -------------------------------------------------------------------------------- 1 | import objectForEach from './utils/objectForEach'; 2 | import warning from './utils/warning'; 3 | import {isFunction,toArray} from './utils/functions'; 4 | 5 | 6 | function toFirstCharUpper(str) { 7 | return str.replace(/(^|\s+)\w/g, function (s) { 8 | return s.toUpperCase(); 9 | }); 10 | } 11 | 12 | /** 13 | * 一个Store对一个action事件只能有一个响应函数 14 | * @param actionName 15 | * @param actionGroup 16 | * @param storeConfig 17 | * @param storeGroupName 18 | */ 19 | function getReducer(actionName, actionGroup, storeConfig, storeGroupName) { 20 | if (!actionName) { 21 | return null; 22 | } 23 | 24 | //形如:onGetUserList 25 | var reducerReceiveName = "on" + toFirstCharUpper(actionName); 26 | if (actionGroup === storeGroupName) { 27 | var reducer = storeConfig[reducerReceiveName]; 28 | if (reducer) { 29 | return reducer; 30 | } 31 | } 32 | 33 | //形如:post#onGetPostList 34 | var reducerReceiveName2 = actionGroup + "#" + reducerReceiveName; 35 | reducer = storeConfig[reducerReceiveName2]; 36 | if (reducer) { 37 | return reducer; 38 | } 39 | 40 | return null; 41 | } 42 | 43 | 44 | /** 45 | * 46 | * @param state 47 | * @param action 形如: {group,name,status,args,payload} 48 | * @param storeConfig 49 | * @param storeGroupName 形如:user,post 50 | */ 51 | function reduceAction(state, action, storeConfig, storeGroupName) { 52 | var actionName = action.name; 53 | var actionGroup = action.group; 54 | var reducer = getReducer(actionName, actionGroup, storeConfig, storeGroupName); 55 | if (reducer) { 56 | 57 | var state0 = reducer(state, action); 58 | if (state0) { 59 | return state0; 60 | } 61 | else { 62 | //如果reducer没有正确返回,做一下兼容 63 | warning(`[ERROR] error store config:${actionGroup}#${actionName}`); 64 | } 65 | 66 | } 67 | return state; 68 | } 69 | 70 | 71 | /** 72 | * 创建一个真正执行的时候调用的Get函数 73 | * @param getterDef 用户配置的以get开否的函数实现 74 | * @param exportStore 75 | * @returns {Function} 76 | */ 77 | function createGetterFunction(getterDef, exportStore) { 78 | return function () { 79 | var args0 = toArray(arguments); 80 | //每次执行,都是获取最新的state 81 | var state = exportStore['$$state']; 82 | var args = [state].concat(args0); 83 | return getterDef.apply({}, args); 84 | } 85 | } 86 | 87 | 88 | /** 89 | * 对于以get开头的配置,创建get函数 90 | * @param exportStore 91 | * @param storeConfig 形如: {onGetXXX,onGetYYY,getXXX,getYYY} 92 | */ 93 | function createGetter(exportStore, storeConfig) { 94 | objectForEach(storeConfig, function (key, handler) { 95 | if (key.indexOf('get') === 0 && isFunction(handler)) { 96 | exportStore[key] = createGetterFunction(handler, exportStore); 97 | } 98 | }); 99 | } 100 | 101 | 102 | /** 103 | * 以$$开头的都是框架内部的变量,禁止业务层访问. 104 | */ 105 | export default function createStore(storeConfig) { 106 | 107 | var initialState = storeConfig.initialState || {}; 108 | 109 | //这才是真正对外暴露的Store对象 110 | var exportStore = {}; 111 | 112 | //1.创建的reducer函数 113 | var reducerFunc = function (state = initialState, action = {}) { 114 | //storeGroupName真正的值是在Reubibi.createConfigure中被重新设置的. 115 | var storeGroupName = exportStore['$$StoreGroupName']; 116 | state = reduceAction(state, action, storeConfig, storeGroupName); 117 | exportStore['$$state'] = state; 118 | return state; 119 | }; 120 | 121 | exportStore['$$reducer'] = reducerFunc; 122 | 123 | //2.$$StoreGroupName的初始化 124 | exportStore['$$StoreGroupName'] = null; 125 | 126 | //3.创建Getter函数 127 | createGetter(exportStore, storeConfig); 128 | 129 | return exportStore; 130 | } -------------------------------------------------------------------------------- /src/createConfigure.js: -------------------------------------------------------------------------------- 1 | import {createStore, applyMiddleware, combineReducers} from 'redux'; 2 | import promiseMiddleware from './middleware/promiseMiddleware'; 3 | import {isFunction} from './utils/functions' 4 | import objectForEach from './utils/objectForEach'; 5 | import warning from './utils/warning'; 6 | 7 | const getCombineReducers = function (config) { 8 | /** 9 | * { 10 | * $$state:{}, 11 | * $$reducer: function(){}, 12 | * getUserList: function(){}, 13 | * getUserInfo(): function(){}, 14 | * moreGetter.... 15 | * } 16 | */ 17 | var storesMap = config.stores || {}; 18 | var reducerMap = {}; 19 | for (var i in storesMap) { 20 | if (storesMap.hasOwnProperty(i)) { 21 | var v = storesMap[i]; 22 | //这是在createStore方法中定义的,就一个函数. 23 | var reducer = v['$$reducer']; //是一个function 24 | reducerMap[i] = reducer; 25 | } 26 | } 27 | 28 | 29 | /** 30 | * 在这里定义的数据结构最终保证了store中的数据结构 31 | * { 32 | * user:function(){}, 33 | * post:function(){} 34 | * } 35 | */ 36 | return combineReducers(reducerMap); 37 | }; 38 | 39 | 40 | /** 41 | * /Reubibi.createConfigure 配置后UserStore实例中能够获取自己的配置信息 42 | * @param config 43 | */ 44 | function setStoreGroupName(config) { 45 | var storesConfig = config.stores;//Reubibi.createConfigure 46 | if (storesConfig) { 47 | //UserStore只是一个示例 48 | objectForEach(storesConfig, function (key, UserStore) { 49 | UserStore['$$StoreGroupName'] = key; 50 | }); 51 | } 52 | } 53 | 54 | 55 | function replacePromiseMiddleware(middlewareArray){ 56 | 57 | var middlewareArray1 = []; 58 | var isHasPromiseMiddleware = false; 59 | for (var i = 0; i < middlewareArray.length; i++) { 60 | var m = middlewareArray[i]; 61 | if (m === 'promiseMiddleware') { 62 | middlewareArray1.push(promiseMiddleware); 63 | isHasPromiseMiddleware = true; 64 | } else if (isFunction(m)) { 65 | middlewareArray1.push(m); 66 | } else { 67 | throw new Error(`${m} is not a middleware`); 68 | } 69 | } 70 | 71 | if (!isHasPromiseMiddleware) { 72 | warning(`Must has a promiseMiddleware,please check createConfigure`); 73 | } 74 | 75 | return middlewareArray1; 76 | } 77 | 78 | 79 | function toCreateStoreWithMiddleware(middlewareArray) { 80 | var func = null; 81 | if (middlewareArray && middlewareArray.length > 0) { 82 | middlewareArray = replacePromiseMiddleware(middlewareArray); 83 | func = applyMiddleware.apply({},middlewareArray); 84 | } else { 85 | func = applyMiddleware(promiseMiddleware); 86 | } 87 | return func(createStore); 88 | } 89 | 90 | 91 | class ReubibiConfig { 92 | 93 | /** 94 | * 95 | * actions: { 96 | * user: userActions, 97 | * post: postActions 98 | * }, 99 | * stores: { 100 | * user: UserStore, 101 | * post: PostStore 102 | * } 103 | * 104 | */ 105 | constructor(config) { 106 | setStoreGroupName(config); 107 | this.config = config; 108 | var initialState = config.initialState; 109 | var middleware = config.middleware; 110 | var reducer = getCombineReducers(config); 111 | var createStoreWithMiddleware = toCreateStoreWithMiddleware(middleware); 112 | if(initialState){ 113 | //唯一的一个store 114 | this.store = createStoreWithMiddleware(reducer, initialState); 115 | }else { 116 | //唯一的一个store 117 | this.store = createStoreWithMiddleware(reducer); 118 | } 119 | } 120 | 121 | getStore() { 122 | return this.store; 123 | } 124 | 125 | getActions() { 126 | return this.config.actions; 127 | } 128 | 129 | } 130 | 131 | 132 | export default function createConfigure(config) { 133 | return new ReubibiConfig(config); 134 | } -------------------------------------------------------------------------------- /lib/createStore.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports["default"] = createStore; 5 | 6 | var _objectForEach = require('./utils/objectForEach'); 7 | 8 | var _objectForEach2 = _interopRequireDefault(_objectForEach); 9 | 10 | var _warning = require('./utils/warning'); 11 | 12 | var _warning2 = _interopRequireDefault(_warning); 13 | 14 | var _functions = require('./utils/functions'); 15 | 16 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 17 | 18 | function toFirstCharUpper(str) { 19 | return str.replace(/(^|\s+)\w/g, function (s) { 20 | return s.toUpperCase(); 21 | }); 22 | } 23 | 24 | /** 25 | * 一个Store对一个action事件只能有一个响应函数 26 | * @param actionName 27 | * @param actionGroup 28 | * @param storeConfig 29 | * @param storeGroupName 30 | */ 31 | function getReducer(actionName, actionGroup, storeConfig, storeGroupName) { 32 | if (!actionName) { 33 | return null; 34 | } 35 | 36 | //形如:onGetUserList 37 | var reducerReceiveName = "on" + toFirstCharUpper(actionName); 38 | if (actionGroup === storeGroupName) { 39 | var reducer = storeConfig[reducerReceiveName]; 40 | if (reducer) { 41 | return reducer; 42 | } 43 | } 44 | 45 | //形如:post#onGetPostList 46 | var reducerReceiveName2 = actionGroup + "#" + reducerReceiveName; 47 | reducer = storeConfig[reducerReceiveName2]; 48 | if (reducer) { 49 | return reducer; 50 | } 51 | 52 | return null; 53 | } 54 | 55 | /** 56 | * 57 | * @param state 58 | * @param action 形如: {group,name,status,args,payload} 59 | * @param storeConfig 60 | * @param storeGroupName 形如:user,post 61 | */ 62 | function reduceAction(state, action, storeConfig, storeGroupName) { 63 | var actionName = action.name; 64 | var actionGroup = action.group; 65 | var reducer = getReducer(actionName, actionGroup, storeConfig, storeGroupName); 66 | if (reducer) { 67 | 68 | var state0 = reducer(state, action); 69 | if (state0) { 70 | return state0; 71 | } else { 72 | //如果reducer没有正确返回,做一下兼容 73 | (0, _warning2["default"])('[ERROR] error store config:' + actionGroup + '#' + actionName); 74 | } 75 | } 76 | return state; 77 | } 78 | 79 | /** 80 | * 创建一个真正执行的时候调用的Get函数 81 | * @param getterDef 用户配置的以get开否的函数实现 82 | * @param exportStore 83 | * @returns {Function} 84 | */ 85 | function createGetterFunction(getterDef, exportStore) { 86 | return function () { 87 | var args0 = (0, _functions.toArray)(arguments); 88 | //每次执行,都是获取最新的state 89 | var state = exportStore['$$state']; 90 | var args = [state].concat(args0); 91 | return getterDef.apply({}, args); 92 | }; 93 | } 94 | 95 | /** 96 | * 对于以get开头的配置,创建get函数 97 | * @param exportStore 98 | * @param storeConfig 形如: {onGetXXX,onGetYYY,getXXX,getYYY} 99 | */ 100 | function createGetter(exportStore, storeConfig) { 101 | (0, _objectForEach2["default"])(storeConfig, function (key, handler) { 102 | if (key.indexOf('get') === 0 && (0, _functions.isFunction)(handler)) { 103 | exportStore[key] = createGetterFunction(handler, exportStore); 104 | } 105 | }); 106 | } 107 | 108 | /** 109 | * 以$$开头的都是框架内部的变量,禁止业务层访问. 110 | */ 111 | function createStore(storeConfig) { 112 | 113 | var initialState = storeConfig.initialState || {}; 114 | 115 | //这才是真正对外暴露的Store对象 116 | var exportStore = {}; 117 | 118 | //1.创建的reducer函数 119 | var reducerFunc = function reducerFunc() { 120 | var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; 121 | var action = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 122 | 123 | //storeGroupName真正的值是在Reubibi.createConfigure中被重新设置的. 124 | var storeGroupName = exportStore['$$StoreGroupName']; 125 | state = reduceAction(state, action, storeConfig, storeGroupName); 126 | exportStore['$$state'] = state; 127 | return state; 128 | }; 129 | 130 | exportStore['$$reducer'] = reducerFunc; 131 | 132 | //2.$$StoreGroupName的初始化 133 | exportStore['$$StoreGroupName'] = null; 134 | 135 | //3.创建Getter函数 136 | createGetter(exportStore, storeConfig); 137 | 138 | return exportStore; 139 | } -------------------------------------------------------------------------------- /src/createComponent.js: -------------------------------------------------------------------------------- 1 | import {bindActionCreators} from 'redux'; 2 | import connect from './component/connect'; 3 | import {getValueInPath,toArray,isString,isFunction} from './utils/functions'; 4 | import objectForEach from './utils/objectForEach'; 5 | import warning from './utils/warning'; 6 | import isPromise from './utils/isPromise'; 7 | const _undefined = undefined; 8 | 9 | function createConfiguredActionWrapper(actionWrapper, path) { 10 | 11 | //actionGroup 其实就是在createConfigure中定义的action的key 12 | //例如在example中将得到config/reubibiConfigure中配置的 'user'或'post' 13 | var actionGroup = path.split('.')[0]; 14 | 15 | //这才是真正调用的函数 16 | return function () { 17 | var args = toArray(arguments); 18 | //@see createAction ActionImplWrapper 19 | var action = actionWrapper(actionGroup, args); 20 | //{group,name,status,args,payload} 21 | return action; 22 | } 23 | } 24 | 25 | 26 | function getActionsFromConfig(reubibiConfigure, componentConfig) { 27 | var actionsResult = {}; 28 | if (!componentConfig || !reubibiConfigure) { 29 | return null; 30 | } 31 | 32 | var actionsConfig = componentConfig.actions || {}; 33 | var allActions = reubibiConfigure.getActions(); 34 | 35 | objectForEach(actionsConfig, function (key, path) { 36 | var actionWrapper = getValueInPath(allActions, path || ''); 37 | if (actionWrapper === _undefined) { 38 | warning(`[ERROR]cannot get Object by key : ${key} and path: ${path} `); 39 | } else { 40 | actionsResult[key] = createConfiguredActionWrapper(actionWrapper, path); 41 | } 42 | }); 43 | 44 | return actionsResult; 45 | 46 | } 47 | 48 | 49 | function createPromiseActionFunc(actionFunc) { 50 | return function () { 51 | var args = toArray(arguments); 52 | var actionResult = actionFunc.apply({}, args); 53 | if(actionResult){ 54 | if (isPromise(actionResult.promise)) { 55 | return actionResult.promise; 56 | } 57 | return actionResult.payload; 58 | } 59 | return null; 60 | } 61 | } 62 | 63 | 64 | function bindActionPromise(actionFunctions) { 65 | var promiseActions = {}; 66 | objectForEach(actionFunctions, function (key, actionFunc) { 67 | promiseActions[key] = createPromiseActionFunc(actionFunc); 68 | }); 69 | return promiseActions; 70 | } 71 | 72 | 73 | function getStateByConfig(state, componentConfig) { 74 | var result = {}; 75 | if (!componentConfig || !state) { 76 | return null; 77 | } 78 | 79 | var propsConfig = componentConfig.props || {}; 80 | 81 | objectForEach(propsConfig, function (key, pathOrFunc) { 82 | 83 | if(isFunction(pathOrFunc)){ 84 | result[key] = pathOrFunc(state); 85 | }else if(isString(pathOrFunc)){ 86 | result[key] = getValueInPath(state, pathOrFunc || ''); 87 | } 88 | 89 | if (result[key] === _undefined) { 90 | warning(`[ERROR]cannot get Object by key : ${key} and path: ${pathOrFunc} `); 91 | } 92 | 93 | }); 94 | 95 | return result; 96 | } 97 | 98 | 99 | /** 100 | * 101 | * @param reubibiConfigure 是一个Reubibi.createConfigure对象. 102 | * @param BaseComponentImpl React组件对象 103 | * @param componentConfig 组件的配置 形如: 104 | * 105 | * componentConfig = { 106 | * 107 | * actions: { 108 | * getUserList: 'user.getUserList' 109 | * }, 110 | * 111 | * props: { 112 | * userList: 'user.userList' 113 | * } 114 | * 115 | * } 116 | */ 117 | export default function createComponent(reubibiConfigure, BaseComponentImpl, componentConfig) { 118 | 119 | 120 | function mapStateToProps(state) { 121 | var props = getStateByConfig(state, componentConfig); 122 | return props; 123 | } 124 | 125 | 126 | function mapDispatchToProps(dispatch) { 127 | //每次数据变化时,不会执行此处代码 128 | var actions = getActionsFromConfig(reubibiConfigure, componentConfig); //这里的action执行后返回{group,name,status,args,payload} 129 | var actionDefs = bindActionCreators(actions, dispatch);//这里的action执行后返回 130 | var actionPromise = bindActionPromise(actionDefs); 131 | return {actions: actionPromise}; 132 | } 133 | 134 | return connect(mapStateToProps, mapDispatchToProps)(BaseComponentImpl); 135 | 136 | } -------------------------------------------------------------------------------- /lib/createConfigure.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports["default"] = createConfigure; 5 | 6 | var _redux = require('redux'); 7 | 8 | var _promiseMiddleware = require('./middleware/promiseMiddleware'); 9 | 10 | var _promiseMiddleware2 = _interopRequireDefault(_promiseMiddleware); 11 | 12 | var _functions = require('./utils/functions'); 13 | 14 | var _objectForEach = require('./utils/objectForEach'); 15 | 16 | var _objectForEach2 = _interopRequireDefault(_objectForEach); 17 | 18 | var _warning = require('./utils/warning'); 19 | 20 | var _warning2 = _interopRequireDefault(_warning); 21 | 22 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 23 | 24 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 25 | 26 | var getCombineReducers = function getCombineReducers(config) { 27 | /** 28 | * { 29 | * $$state:{}, 30 | * $$reducer: function(){}, 31 | * getUserList: function(){}, 32 | * getUserInfo(): function(){}, 33 | * moreGetter.... 34 | * } 35 | */ 36 | var storesMap = config.stores || {}; 37 | var reducerMap = {}; 38 | for (var i in storesMap) { 39 | if (storesMap.hasOwnProperty(i)) { 40 | var v = storesMap[i]; 41 | //这是在createStore方法中定义的,就一个函数. 42 | var reducer = v['$$reducer']; //是一个function 43 | reducerMap[i] = reducer; 44 | } 45 | } 46 | 47 | /** 48 | * 在这里定义的数据结构最终保证了store中的数据结构 49 | * { 50 | * user:function(){}, 51 | * post:function(){} 52 | * } 53 | */ 54 | return (0, _redux.combineReducers)(reducerMap); 55 | }; 56 | 57 | /** 58 | * /Reubibi.createConfigure 配置后UserStore实例中能够获取自己的配置信息 59 | * @param config 60 | */ 61 | function setStoreGroupName(config) { 62 | var storesConfig = config.stores; //Reubibi.createConfigure 63 | if (storesConfig) { 64 | //UserStore只是一个示例 65 | (0, _objectForEach2["default"])(storesConfig, function (key, UserStore) { 66 | UserStore['$$StoreGroupName'] = key; 67 | }); 68 | } 69 | } 70 | 71 | function replacePromiseMiddleware(middlewareArray) { 72 | 73 | var middlewareArray1 = []; 74 | var isHasPromiseMiddleware = false; 75 | for (var i = 0; i < middlewareArray.length; i++) { 76 | var m = middlewareArray[i]; 77 | if (m === 'promiseMiddleware') { 78 | middlewareArray1.push(_promiseMiddleware2["default"]); 79 | isHasPromiseMiddleware = true; 80 | } else if ((0, _functions.isFunction)(m)) { 81 | middlewareArray1.push(m); 82 | } else { 83 | throw new Error(m + ' is not a middleware'); 84 | } 85 | } 86 | 87 | if (!isHasPromiseMiddleware) { 88 | (0, _warning2["default"])('Must has a promiseMiddleware,please check createConfigure'); 89 | } 90 | 91 | return middlewareArray1; 92 | } 93 | 94 | function toCreateStoreWithMiddleware(middlewareArray) { 95 | var func = null; 96 | if (middlewareArray && middlewareArray.length > 0) { 97 | middlewareArray = replacePromiseMiddleware(middlewareArray); 98 | func = _redux.applyMiddleware.apply({}, middlewareArray); 99 | } else { 100 | func = (0, _redux.applyMiddleware)(_promiseMiddleware2["default"]); 101 | } 102 | return func(_redux.createStore); 103 | } 104 | 105 | var ReubibiConfig = function () { 106 | 107 | /** 108 | * 109 | * actions: { 110 | * user: userActions, 111 | * post: postActions 112 | * }, 113 | * stores: { 114 | * user: UserStore, 115 | * post: PostStore 116 | * } 117 | * 118 | */ 119 | function ReubibiConfig(config) { 120 | _classCallCheck(this, ReubibiConfig); 121 | 122 | setStoreGroupName(config); 123 | this.config = config; 124 | var initialState = config.initialState; 125 | var middleware = config.middleware; 126 | var reducer = getCombineReducers(config); 127 | var createStoreWithMiddleware = toCreateStoreWithMiddleware(middleware); 128 | if (initialState) { 129 | //唯一的一个store 130 | this.store = createStoreWithMiddleware(reducer, initialState); 131 | } else { 132 | //唯一的一个store 133 | this.store = createStoreWithMiddleware(reducer); 134 | } 135 | } 136 | 137 | ReubibiConfig.prototype.getStore = function getStore() { 138 | return this.store; 139 | }; 140 | 141 | ReubibiConfig.prototype.getActions = function getActions() { 142 | return this.config.actions; 143 | }; 144 | 145 | return ReubibiConfig; 146 | }(); 147 | 148 | function createConfigure(config) { 149 | return new ReubibiConfig(config); 150 | } -------------------------------------------------------------------------------- /lib/createComponent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | exports["default"] = createComponent; 5 | 6 | var _redux = require('redux'); 7 | 8 | var _connect = require('./component/connect'); 9 | 10 | var _connect2 = _interopRequireDefault(_connect); 11 | 12 | var _functions = require('./utils/functions'); 13 | 14 | var _objectForEach = require('./utils/objectForEach'); 15 | 16 | var _objectForEach2 = _interopRequireDefault(_objectForEach); 17 | 18 | var _warning = require('./utils/warning'); 19 | 20 | var _warning2 = _interopRequireDefault(_warning); 21 | 22 | var _isPromise = require('./utils/isPromise'); 23 | 24 | var _isPromise2 = _interopRequireDefault(_isPromise); 25 | 26 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 27 | 28 | var _undefined = undefined; 29 | 30 | function createConfiguredActionWrapper(actionWrapper, path) { 31 | 32 | //actionGroup 其实就是在createConfigure中定义的action的key 33 | //例如在example中将得到config/reubibiConfigure中配置的 'user'或'post' 34 | var actionGroup = path.split('.')[0]; 35 | 36 | //这才是真正调用的函数 37 | return function () { 38 | var args = (0, _functions.toArray)(arguments); 39 | //@see createAction ActionImplWrapper 40 | var action = actionWrapper(actionGroup, args); 41 | //{group,name,status,args,payload} 42 | return action; 43 | }; 44 | } 45 | 46 | function getActionsFromConfig(reubibiConfigure, componentConfig) { 47 | var actionsResult = {}; 48 | if (!componentConfig || !reubibiConfigure) { 49 | return null; 50 | } 51 | 52 | var actionsConfig = componentConfig.actions || {}; 53 | var allActions = reubibiConfigure.getActions(); 54 | 55 | (0, _objectForEach2["default"])(actionsConfig, function (key, path) { 56 | var actionWrapper = (0, _functions.getValueInPath)(allActions, path || ''); 57 | if (actionWrapper === _undefined) { 58 | (0, _warning2["default"])('[ERROR]cannot get Object by key : ' + key + ' and path: ' + path + ' '); 59 | } else { 60 | actionsResult[key] = createConfiguredActionWrapper(actionWrapper, path); 61 | } 62 | }); 63 | 64 | return actionsResult; 65 | } 66 | 67 | function createPromiseActionFunc(actionFunc) { 68 | return function () { 69 | var args = (0, _functions.toArray)(arguments); 70 | var actionResult = actionFunc.apply({}, args); 71 | if (actionResult) { 72 | if ((0, _isPromise2["default"])(actionResult.promise)) { 73 | return actionResult.promise; 74 | } 75 | return actionResult.payload; 76 | } 77 | return null; 78 | }; 79 | } 80 | 81 | function bindActionPromise(actionFunctions) { 82 | var promiseActions = {}; 83 | (0, _objectForEach2["default"])(actionFunctions, function (key, actionFunc) { 84 | promiseActions[key] = createPromiseActionFunc(actionFunc); 85 | }); 86 | return promiseActions; 87 | } 88 | 89 | function getStateByConfig(state, componentConfig) { 90 | var result = {}; 91 | if (!componentConfig || !state) { 92 | return null; 93 | } 94 | 95 | var propsConfig = componentConfig.props || {}; 96 | 97 | (0, _objectForEach2["default"])(propsConfig, function (key, pathOrFunc) { 98 | 99 | if ((0, _functions.isFunction)(pathOrFunc)) { 100 | result[key] = pathOrFunc(state); 101 | } else if ((0, _functions.isString)(pathOrFunc)) { 102 | result[key] = (0, _functions.getValueInPath)(state, pathOrFunc || ''); 103 | } 104 | 105 | if (result[key] === _undefined) { 106 | (0, _warning2["default"])('[ERROR]cannot get Object by key : ' + key + ' and path: ' + pathOrFunc + ' '); 107 | } 108 | }); 109 | 110 | return result; 111 | } 112 | 113 | /** 114 | * 115 | * @param reubibiConfigure 是一个Reubibi.createConfigure对象. 116 | * @param BaseComponentImpl React组件对象 117 | * @param componentConfig 组件的配置 形如: 118 | * 119 | * componentConfig = { 120 | * 121 | * actions: { 122 | * getUserList: 'user.getUserList' 123 | * }, 124 | * 125 | * props: { 126 | * userList: 'user.userList' 127 | * } 128 | * 129 | * } 130 | */ 131 | function createComponent(reubibiConfigure, BaseComponentImpl, componentConfig) { 132 | 133 | function mapStateToProps(state) { 134 | var props = getStateByConfig(state, componentConfig); 135 | return props; 136 | } 137 | 138 | function mapDispatchToProps(dispatch) { 139 | //每次数据变化时,不会执行此处代码 140 | var actions = getActionsFromConfig(reubibiConfigure, componentConfig); //这里的action执行后返回{group,name,status,args,payload} 141 | var actionDefs = (0, _redux.bindActionCreators)(actions, dispatch); //这里的action执行后返回 142 | var actionPromise = bindActionPromise(actionDefs); 143 | return { actions: actionPromise }; 144 | } 145 | 146 | return (0, _connect2["default"])(mapStateToProps, mapDispatchToProps)(BaseComponentImpl); 147 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | React Rebix 2 | =========== 3 | React的一个单向数据流框架。 4 | 5 | ##优点 6 | 7 | 内部实现依赖于Redux。但是简化了Redux的使用方法。 8 | 9 | 1. action层只需要返回action方法的处理结果,无需action去dispatch处理的结果。 10 | 2. store层,无需写大量的switch判断,而是采用reflux的风格,直接使用onXXXX来响应Action的处理。 11 | 3. view层无需自己去依赖action和store层,而是直接采用简单的配置,就能自动将action和store中的数据绑定到组件的props中。 12 | 4. view层中调用的action方法如果是异步方法会将返回值中的promise对象透传到view层。 13 | 5. action层和view层,都可以直接访问store中的Get方法。但是view层和action层,都无法访问store中的非get方法。这样既能保证调用的灵活性,又能保证数据流的单向流动。 14 | 6. 跟其他框架相比,用户省去了大量自己手动书写的对数据的pub/sub的代码。 15 | 16 | 17 | ## 安装 18 | 19 | ``` 20 | npm install --save react-rebix 21 | ``` 22 | ### 使用 23 | ``` 24 | import Rebix from 'react-rebix'; 25 | ``` 26 | OR 27 | ``` 28 | 29 | 30 | 31 | ``` 32 | 33 | 34 | ## 示例 35 | 36 | #### TODO MVC 37 | 38 | ``` 39 | https://github.com/ubibi/rebix-todo-demo 40 | ``` 41 | 42 | ####混合示例 43 | 44 | ``` 45 | https://github.com/luanhaipeng/rebix/tree/master/example/example 46 | ``` 47 | 48 | ### Action 49 | 50 | Action中可访问Store中的getXXX方法,其他方法不能访问。 51 | 52 | 支持三种Action 53 | 54 | 1. 异步 Action, 一定要返回一个Promise对象 55 | 2. 普通 Action,直接返回处理结果的js对象。 56 | 3. 空Action, 不需要具体的实现,具体操作在Store中完成. 57 | 58 | ``` 59 | import Rebix from 'react-rebix'; 60 | import UserStore from '../stores/UserStore'; 61 | 62 | export default Rebix.createActions({ 63 | 64 | /** 65 | * 异步 Action 66 | * 一定要返回一个Promise对象 67 | */ 68 | getUserInfo: function (params) { 69 | 70 | //Action 中可以访问Store中的数据。但是只能调用get方法。 71 | //Store 中的其他方法,不会对外暴露,这样方便了数据的访问,同时又保证了数据的单向流动。 72 | var userInfo = UserStore.getUserInfo(123); 73 | 74 | return new Promise(function (resolve) { 75 | setTimeout(function () { 76 | //store层使用action.promise字段接受返回值 77 | resolve({ 78 | time: new Date().getTime(), 79 | userInfo: userInfo, 80 | params: params 81 | }); 82 | }, 1000) 83 | }) 84 | }, 85 | 86 | 87 | /** 88 | * 普通 Action 89 | */ 90 | getUserList: function (params) { 91 | //store层使用action.payload字段接受返回值 92 | return [1, 2, 3, params]; 93 | }, 94 | 95 | 96 | /** 97 | * 空Action, 不需要具体的实现 98 | * 具体操作在Store中完成. 99 | */ 100 | beginEditUserInfo: null, 101 | 102 | /** 103 | * 空Action, 不需要具体的实现 104 | * 具体操作在Store中完成. 105 | */ 106 | endEditUserInfo: null 107 | 108 | }); 109 | ``` 110 | 111 | 112 | ###Store 113 | 114 | Store中的数据存储,强烈建议使用immutable,这里为了演示方便,通过Object.assign({}, state)创建了一个新对象。 115 | 116 | 说明: 117 | 118 | 1. 为了保证数据的单向流动,通过CreateStore创建的onXXXX函数,view层和action层根本调用不到。 119 | 2. 为了方便action和view层使用数据,通过CreateStore创建的getXXXX函数,view层和action层都可以调用到。 120 | 3. 一般来说action文件和store文件是一一对应的,但是有时候一个action的处理结果需要几个store层各自处理。这里提供了加井号前缀的方式实现。比如:post#onGetPostList(在UserStore中响应PostAction的结果。) 121 | 122 | ``` 123 | import Rebix from 'react-rebix'; 124 | 125 | 126 | export default Rebix.createStore({ 127 | 128 | initialState: { 129 | userList: [], 130 | postList: [] 131 | }, 132 | 133 | //类似Reflux。Action中的处理结束后,会把数据传递给Store 134 | //这里处理:action中方法 getUserList 的返回值。 135 | 'onGetUserList': function (state, action) { 136 | console.log(action.status); 137 | state = Object.assign({}, state); 138 | var userList = action.payload; 139 | state.userList = userList; 140 | return state; 141 | }, 142 | 143 | 144 | //处理action中beginEditUserInfo的行为。 145 | 'onBeginEditUserInfo': function (state) { 146 | state = Object.assign({}, state); 147 | state.isEditing = true; 148 | return state; 149 | }, 150 | 151 | //处理action中onEndEditUserInfo的行为。 152 | 'onEndEditUserInfo': function (state) { 153 | state = Object.assign({}, state); 154 | state.isEditing = false; 155 | return state; 156 | }, 157 | 158 | 159 | /** 160 | * 为了响应其它Action方法中的处理,要加#前缀 161 | */ 162 | 'post#onGetPostList': function (state, action) { 163 | console.log(action.status); 164 | if (action.status === 'success') { 165 | state = Object.assign({}, state); 166 | var postList = action.payload; 167 | state.postList = postList; 168 | } 169 | 170 | return state; 171 | }, 172 | 173 | 174 | /** 175 | * Get函数,修改state不管用.state内部一般都是使用immutable对象,只有on函数的返回值才能对state进行修改. 176 | * View 层,可以直接调用Get函数获取Store中的数据,但是无法修改. 177 | * 在Get函数内部对state的任何修改,都不会生效. 178 | */ 179 | 'getUserInfo': function (state, a, b, c, d) { 180 | return { 181 | name: a 182 | }; 183 | } 184 | 185 | 186 | }); 187 | 188 | 189 | ``` 190 | 191 | 192 | ###Config 193 | 194 | 通过Config,将action、store等资源集中起来。这样的目的是为了在view层,无需再引入大量的action、store的js文件。 195 | 196 | 说明: 197 | 198 | 1. createConfigure中只有三个配置项。 199 | 2. initialState 是用来做服务端初次数据渲染用的。 200 | 3. actions 所有action的集合。 201 | 4. stores所有stores的结合。 202 | 5. actions和stores中配置的key值基本保证是一一对应的。如下:user和post 203 | 204 | ``` 205 | import Rebix from 'react-rebix'; 206 | import UserActions from '../actions/UserActions'; 207 | import PostActions from '../actions/PostActions'; 208 | import UserStore from '../stores/UserStore'; 209 | import PostStore from '../stores/PostStore'; 210 | 211 | export default Rebix.createConfigure({ 212 | 213 | initialState: null, 214 | 215 | actions: { 216 | user: UserActions, 217 | post: PostActions 218 | }, 219 | 220 | stores: { 221 | user: UserStore, 222 | post: PostStore 223 | } 224 | 225 | }); 226 | ``` 227 | 228 | 229 | 230 | ###View 231 | 232 | 注意: 233 | 234 | 1. Action中可访问Store中的getXXX方法,其他方法不能访问。 235 | 2. View层通过Rebix.createComponent将action和store自动绑定到组建的props中。 236 | 3. Store发生了变化,会自动update,因此强烈建议重写shouldComponentUpdate来避免重复渲染。这里跟redux是一样的。 237 | 238 | 239 | 240 | ``` 241 | import React, {PropTypes} from 'react'; 242 | import createRebixComponent from '../config/createRebixComponent'; 243 | import UserStore from '../stores/UserStore'; 244 | import RebixConfigure from './RebixConfigure'; 245 | 246 | class Hello extends React.Component { 247 | 248 | constructor(props) { 249 | super(props); 250 | this.state = { 251 | userInfo: {} 252 | }; 253 | } 254 | 255 | componentDidMount() { 256 | var that = this; 257 | var {actions} = that.props; 258 | var mm = actions.getUserList(1234); 259 | var mm2 = actions.beginEditUserInfo(1234); 260 | 261 | 262 | actions.getPostList('absdf', 'sdf').then(function () { 263 | debugger; 264 | }); 265 | 266 | setTimeout(function () { 267 | //直接访问Store中的数据 268 | var userInfo = UserStore.getUserInfo(121); 269 | that.setState({userInfo: userInfo}); 270 | }, 2000) 271 | } 272 | 273 | 274 | render() { 275 | var userList = this.props.userList || []; 276 | var postList = this.props.postList || []; 277 | var userInfo = this.state.userInfo || {}; 278 | 279 | return ( 280 |
281 | aaa---{userInfo.name} 282 |
283 | bbb--- 284 | {userList.map(function (x) { 285 | return
{x}
286 | })} 287 |
288 | ccc--- 289 | {postList.map(function (x) { 290 | return
{x}
291 | })} 292 |
293 | ); 294 | 295 | } 296 | 297 | } 298 | 299 | 300 | export default Rebix.createComponent(RebixConfigure, Hello, { 301 | 302 | actions: { 303 | getUserList: 'user.getUserList', //请参考config文件中的配置。 304 | getPostList: 'post.getPostList', 305 | beginEditUserInfo: 'user.beginEditUserInfo' 306 | }, 307 | 308 | props: { 309 | userList: 'user.userList', 310 | postList: 'user.postList' 311 | } 312 | 313 | }); 314 | ``` 315 | 316 | ## 原理 317 | 318 | 内部实现还是使用Redux,只有一个唯一的Store,通过connect自动完成对store数据变化的pub/sub机制。 319 | 320 | ## License 321 | 322 | MIT 323 | 324 | -------------------------------------------------------------------------------- /src/component/connect.js: -------------------------------------------------------------------------------- 1 | import { Component, createElement } from 'react' 2 | import storeShape from '../utils/storeShape' 3 | import shallowEqual from '../utils/shallowEqual' 4 | import wrapActionCreators from '../utils/wrapActionCreators' 5 | import warning from '../utils/warning' 6 | import isPlainObject from 'lodash/isPlainObject' 7 | import hoistStatics from '../utils/hoist-non-react-statics' 8 | 9 | const defaultMapStateToProps = state => ({}); // eslint-disable-line no-unused-vars 10 | const defaultMapDispatchToProps = dispatch => ({dispatch}); 11 | const defaultMergeProps = (stateProps, dispatchProps, parentProps) => ({ 12 | ...parentProps, 13 | ...stateProps, 14 | ...dispatchProps 15 | }); 16 | 17 | function getDisplayName(WrappedComponent) { 18 | return WrappedComponent.displayName || WrappedComponent.name || 'Component' 19 | } 20 | 21 | let errorObject = {value: null}; 22 | function tryCatch(fn, ctx) { 23 | try { 24 | return fn.apply(ctx) 25 | } catch (e) { 26 | errorObject.value = e; 27 | return errorObject 28 | } 29 | } 30 | 31 | // Helps track hot reloading. 32 | let nextVersion = 0; 33 | 34 | export default function connect(mapStateToProps, mapDispatchToProps, mergeProps, options = {}) { 35 | const shouldSubscribe = Boolean(mapStateToProps); 36 | const mapState = mapStateToProps || defaultMapStateToProps; 37 | 38 | let mapDispatch; 39 | if (typeof mapDispatchToProps === 'function') { 40 | mapDispatch = mapDispatchToProps 41 | } else if (!mapDispatchToProps) { 42 | mapDispatch = defaultMapDispatchToProps 43 | } else { 44 | mapDispatch = wrapActionCreators(mapDispatchToProps) 45 | } 46 | 47 | const finalMergeProps = mergeProps || defaultMergeProps; 48 | const { pure = true, withRef = false } = options; 49 | const checkMergedEquals = pure && finalMergeProps !== defaultMergeProps; 50 | 51 | // Helps track hot reloading. 52 | const version = nextVersion++; 53 | 54 | return function wrapWithConnect(WrappedComponent) { 55 | const connectDisplayName = `Connect(${getDisplayName(WrappedComponent)})`; 56 | 57 | function checkStateShape(props, methodName) { 58 | if (!isPlainObject(props)) { 59 | warning( 60 | `${methodName}() in ${connectDisplayName} must return a plain object. ` + 61 | `Instead received ${props}.` 62 | ) 63 | } 64 | } 65 | 66 | function computeMergedProps(stateProps, dispatchProps, parentProps) { 67 | const mergedProps = finalMergeProps(stateProps, dispatchProps, parentProps); 68 | if (process.env.NODE_ENV !== 'production') { 69 | checkStateShape(mergedProps, 'mergeProps') 70 | } 71 | return mergedProps 72 | } 73 | 74 | class Connect extends Component { 75 | shouldComponentUpdate() { 76 | return !pure || this.haveOwnPropsChanged || this.hasStoreStateChanged 77 | } 78 | 79 | constructor(props, context) { 80 | super(props, context); 81 | this.version = version; 82 | this.store = props.store || context.store; 83 | 84 | 85 | if (!this.store) { 86 | var str = 87 | `Could not find "store" in either the context or ` + 88 | `props of "${connectDisplayName}". ` + 89 | `Either wrap the root component in a , ` + 90 | `or explicitly pass "store" as a prop to "${connectDisplayName}".`; 91 | console.log(str); 92 | } 93 | 94 | const storeState = this.store.getState(); 95 | this.state = {storeState}; 96 | this.clearCache(); 97 | } 98 | 99 | computeStateProps(store, props) { 100 | if (!this.finalMapStateToProps) { 101 | return this.configureFinalMapState(store, props) 102 | } 103 | 104 | const state = store.getState(); 105 | const stateProps = this.doStatePropsDependOnOwnProps ? 106 | this.finalMapStateToProps(state, props) : 107 | this.finalMapStateToProps(state); 108 | 109 | if (process.env.NODE_ENV !== 'production') { 110 | checkStateShape(stateProps, 'mapStateToProps') 111 | } 112 | return stateProps 113 | } 114 | 115 | configureFinalMapState(store, props) { 116 | const mappedState = mapState(store.getState(), props); 117 | const isFactory = typeof mappedState === 'function'; 118 | 119 | this.finalMapStateToProps = isFactory ? mappedState : mapState; 120 | this.doStatePropsDependOnOwnProps = this.finalMapStateToProps.length !== 1; 121 | 122 | if (isFactory) { 123 | return this.computeStateProps(store, props) 124 | } 125 | 126 | if (process.env.NODE_ENV !== 'production') { 127 | checkStateShape(mappedState, 'mapStateToProps') 128 | } 129 | return mappedState; 130 | } 131 | 132 | computeDispatchProps(store, props) { 133 | if (!this.finalMapDispatchToProps) { 134 | return this.configureFinalMapDispatch(store, props) 135 | } 136 | 137 | const { dispatch } = store; 138 | const dispatchProps = this.doDispatchPropsDependOnOwnProps ? 139 | this.finalMapDispatchToProps(dispatch, props) : 140 | this.finalMapDispatchToProps(dispatch); 141 | 142 | if (process.env.NODE_ENV !== 'production') { 143 | checkStateShape(dispatchProps, 'mapDispatchToProps') 144 | } 145 | return dispatchProps 146 | } 147 | 148 | configureFinalMapDispatch(store, props) { 149 | const mappedDispatch = mapDispatch(store.dispatch, props); 150 | const isFactory = typeof mappedDispatch === 'function'; 151 | 152 | this.finalMapDispatchToProps = isFactory ? mappedDispatch : mapDispatch; 153 | this.doDispatchPropsDependOnOwnProps = this.finalMapDispatchToProps.length !== 1; 154 | 155 | if (isFactory) { 156 | return this.computeDispatchProps(store, props) 157 | } 158 | 159 | if (process.env.NODE_ENV !== 'production') { 160 | checkStateShape(mappedDispatch, 'mapDispatchToProps') 161 | } 162 | return mappedDispatch 163 | } 164 | 165 | updateStatePropsIfNeeded() { 166 | const nextStateProps = this.computeStateProps(this.store, this.props); 167 | if (this.stateProps && shallowEqual(nextStateProps, this.stateProps)) { 168 | return false 169 | } 170 | 171 | this.stateProps = nextStateProps; 172 | return true 173 | } 174 | 175 | updateDispatchPropsIfNeeded() { 176 | const nextDispatchProps = this.computeDispatchProps(this.store, this.props); 177 | if (this.dispatchProps && shallowEqual(nextDispatchProps, this.dispatchProps)) { 178 | return false 179 | } 180 | 181 | this.dispatchProps = nextDispatchProps; 182 | return true 183 | } 184 | 185 | updateMergedPropsIfNeeded() { 186 | const nextMergedProps = computeMergedProps(this.stateProps, this.dispatchProps, this.props); 187 | if (this.mergedProps && checkMergedEquals && shallowEqual(nextMergedProps, this.mergedProps)) { 188 | return false 189 | } 190 | 191 | this.mergedProps = nextMergedProps; 192 | return true 193 | } 194 | 195 | isSubscribed() { 196 | return typeof this.unsubscribe === 'function' 197 | } 198 | 199 | trySubscribe() { 200 | if (shouldSubscribe && !this.unsubscribe) { 201 | this.unsubscribe = this.store.subscribe(this.handleChange.bind(this)); 202 | this.handleChange() 203 | } 204 | } 205 | 206 | tryUnsubscribe() { 207 | if (this.unsubscribe) { 208 | this.unsubscribe(); 209 | this.unsubscribe = null; 210 | } 211 | } 212 | 213 | componentDidMount() { 214 | this.trySubscribe() 215 | } 216 | 217 | componentWillReceiveProps(nextProps) { 218 | if (!pure || !shallowEqual(nextProps, this.props)) { 219 | this.haveOwnPropsChanged = true; 220 | } 221 | } 222 | 223 | componentWillUnmount() { 224 | this.tryUnsubscribe(); 225 | this.clearCache(); 226 | } 227 | 228 | clearCache() { 229 | this.dispatchProps = null; 230 | this.stateProps = null; 231 | this.mergedProps = null; 232 | this.haveOwnPropsChanged = true; 233 | this.hasStoreStateChanged = true; 234 | this.haveStatePropsBeenPrecalculated = false; 235 | this.statePropsPrecalculationError = null; 236 | this.renderedElement = null; 237 | this.finalMapDispatchToProps = null; 238 | this.finalMapStateToProps = null; 239 | } 240 | 241 | handleChange() { 242 | if (!this.unsubscribe) { 243 | return 244 | } 245 | 246 | const storeState = this.store.getState(); 247 | const prevStoreState = this.state.storeState; 248 | if (pure && prevStoreState === storeState) { 249 | return 250 | } 251 | 252 | if (pure && !this.doStatePropsDependOnOwnProps) { 253 | const haveStatePropsChanged = tryCatch(this.updateStatePropsIfNeeded, this); 254 | if (!haveStatePropsChanged) { 255 | return 256 | } 257 | if (haveStatePropsChanged === errorObject) { 258 | this.statePropsPrecalculationError = errorObject.value 259 | } 260 | this.haveStatePropsBeenPrecalculated = true 261 | } 262 | 263 | this.hasStoreStateChanged = true; 264 | this.setState({storeState}) 265 | } 266 | 267 | getWrappedInstance() { 268 | return this.refs.wrappedInstance 269 | } 270 | 271 | render() { 272 | const { 273 | haveOwnPropsChanged, 274 | hasStoreStateChanged, 275 | haveStatePropsBeenPrecalculated, 276 | statePropsPrecalculationError, 277 | renderedElement 278 | } = this; 279 | 280 | this.haveOwnPropsChanged = false; 281 | this.hasStoreStateChanged = false; 282 | this.haveStatePropsBeenPrecalculated = false; 283 | this.statePropsPrecalculationError = null; 284 | 285 | if (statePropsPrecalculationError) { 286 | throw statePropsPrecalculationError 287 | } 288 | 289 | let shouldUpdateStateProps = true; 290 | let shouldUpdateDispatchProps = true; 291 | if (pure && renderedElement) { 292 | shouldUpdateStateProps = hasStoreStateChanged || ( 293 | haveOwnPropsChanged && this.doStatePropsDependOnOwnProps 294 | ); 295 | shouldUpdateDispatchProps = 296 | haveOwnPropsChanged && this.doDispatchPropsDependOnOwnProps 297 | } 298 | 299 | let haveStatePropsChanged = false; 300 | let haveDispatchPropsChanged = false; 301 | if (haveStatePropsBeenPrecalculated) { 302 | haveStatePropsChanged = true 303 | } else if (shouldUpdateStateProps) { 304 | haveStatePropsChanged = this.updateStatePropsIfNeeded() 305 | } 306 | if (shouldUpdateDispatchProps) { 307 | haveDispatchPropsChanged = this.updateDispatchPropsIfNeeded() 308 | } 309 | 310 | let haveMergedPropsChanged = true; 311 | if ( 312 | haveStatePropsChanged || 313 | haveDispatchPropsChanged || 314 | haveOwnPropsChanged 315 | ) { 316 | haveMergedPropsChanged = this.updateMergedPropsIfNeeded() 317 | } else { 318 | haveMergedPropsChanged = false 319 | } 320 | 321 | if (!haveMergedPropsChanged && renderedElement) { 322 | return renderedElement 323 | } 324 | 325 | if (withRef) { 326 | this.renderedElement = createElement(WrappedComponent, { 327 | ...this.mergedProps, 328 | ref: 'wrappedInstance' 329 | }) 330 | } else { 331 | this.renderedElement = createElement(WrappedComponent, 332 | this.mergedProps 333 | ) 334 | } 335 | 336 | return this.renderedElement 337 | } 338 | } 339 | 340 | Connect.displayName = connectDisplayName 341 | Connect.WrappedComponent = WrappedComponent 342 | Connect.contextTypes = { 343 | store: storeShape 344 | } 345 | Connect.propTypes = { 346 | store: storeShape 347 | } 348 | 349 | if (process.env.NODE_ENV !== 'production') { 350 | Connect.prototype.componentWillUpdate = function componentWillUpdate() { 351 | if (this.version === version) { 352 | return 353 | } 354 | 355 | // We are hot reloading! 356 | this.version = version 357 | this.trySubscribe() 358 | this.clearCache() 359 | } 360 | } 361 | 362 | return hoistStatics(Connect, WrappedComponent) 363 | } 364 | } 365 | -------------------------------------------------------------------------------- /lib/component/connect.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.__esModule = true; 4 | 5 | var _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; }; 6 | 7 | exports["default"] = connect; 8 | 9 | var _react = require('react'); 10 | 11 | var _storeShape = require('../utils/storeShape'); 12 | 13 | var _storeShape2 = _interopRequireDefault(_storeShape); 14 | 15 | var _shallowEqual = require('../utils/shallowEqual'); 16 | 17 | var _shallowEqual2 = _interopRequireDefault(_shallowEqual); 18 | 19 | var _wrapActionCreators = require('../utils/wrapActionCreators'); 20 | 21 | var _wrapActionCreators2 = _interopRequireDefault(_wrapActionCreators); 22 | 23 | var _warning = require('../utils/warning'); 24 | 25 | var _warning2 = _interopRequireDefault(_warning); 26 | 27 | var _isPlainObject = require('lodash/isPlainObject'); 28 | 29 | var _isPlainObject2 = _interopRequireDefault(_isPlainObject); 30 | 31 | var _hoistNonReactStatics = require('../utils/hoist-non-react-statics'); 32 | 33 | var _hoistNonReactStatics2 = _interopRequireDefault(_hoistNonReactStatics); 34 | 35 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 36 | 37 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 38 | 39 | function _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; } 40 | 41 | function _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; } 42 | 43 | var defaultMapStateToProps = function defaultMapStateToProps(state) { 44 | return {}; 45 | }; // eslint-disable-line no-unused-vars 46 | var defaultMapDispatchToProps = function defaultMapDispatchToProps(dispatch) { 47 | return { dispatch: dispatch }; 48 | }; 49 | var defaultMergeProps = function defaultMergeProps(stateProps, dispatchProps, parentProps) { 50 | return _extends({}, parentProps, stateProps, dispatchProps); 51 | }; 52 | 53 | function getDisplayName(WrappedComponent) { 54 | return WrappedComponent.displayName || WrappedComponent.name || 'Component'; 55 | } 56 | 57 | var errorObject = { value: null }; 58 | function tryCatch(fn, ctx) { 59 | try { 60 | return fn.apply(ctx); 61 | } catch (e) { 62 | errorObject.value = e; 63 | return errorObject; 64 | } 65 | } 66 | 67 | // Helps track hot reloading. 68 | var nextVersion = 0; 69 | 70 | function connect(mapStateToProps, mapDispatchToProps, mergeProps) { 71 | var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; 72 | 73 | var shouldSubscribe = Boolean(mapStateToProps); 74 | var mapState = mapStateToProps || defaultMapStateToProps; 75 | 76 | var mapDispatch = void 0; 77 | if (typeof mapDispatchToProps === 'function') { 78 | mapDispatch = mapDispatchToProps; 79 | } else if (!mapDispatchToProps) { 80 | mapDispatch = defaultMapDispatchToProps; 81 | } else { 82 | mapDispatch = (0, _wrapActionCreators2["default"])(mapDispatchToProps); 83 | } 84 | 85 | var finalMergeProps = mergeProps || defaultMergeProps; 86 | var _options$pure = options.pure, 87 | pure = _options$pure === undefined ? true : _options$pure, 88 | _options$withRef = options.withRef, 89 | withRef = _options$withRef === undefined ? false : _options$withRef; 90 | 91 | var checkMergedEquals = pure && finalMergeProps !== defaultMergeProps; 92 | 93 | // Helps track hot reloading. 94 | var version = nextVersion++; 95 | 96 | return function wrapWithConnect(WrappedComponent) { 97 | var connectDisplayName = 'Connect(' + getDisplayName(WrappedComponent) + ')'; 98 | 99 | function checkStateShape(props, methodName) { 100 | if (!(0, _isPlainObject2["default"])(props)) { 101 | (0, _warning2["default"])(methodName + '() in ' + connectDisplayName + ' must return a plain object. ' + ('Instead received ' + props + '.')); 102 | } 103 | } 104 | 105 | function computeMergedProps(stateProps, dispatchProps, parentProps) { 106 | var mergedProps = finalMergeProps(stateProps, dispatchProps, parentProps); 107 | if (process.env.NODE_ENV !== 'production') { 108 | checkStateShape(mergedProps, 'mergeProps'); 109 | } 110 | return mergedProps; 111 | } 112 | 113 | var Connect = function (_Component) { 114 | _inherits(Connect, _Component); 115 | 116 | Connect.prototype.shouldComponentUpdate = function shouldComponentUpdate() { 117 | return !pure || this.haveOwnPropsChanged || this.hasStoreStateChanged; 118 | }; 119 | 120 | function Connect(props, context) { 121 | _classCallCheck(this, Connect); 122 | 123 | var _this = _possibleConstructorReturn(this, _Component.call(this, props, context)); 124 | 125 | _this.version = version; 126 | _this.store = props.store || context.store; 127 | 128 | if (!_this.store) { 129 | var str = 'Could not find "store" in either the context or ' + ('props of "' + connectDisplayName + '". ') + 'Either wrap the root component in a , ' + ('or explicitly pass "store" as a prop to "' + connectDisplayName + '".'); 130 | console.log(str); 131 | } 132 | 133 | var storeState = _this.store.getState(); 134 | _this.state = { storeState: storeState }; 135 | _this.clearCache(); 136 | return _this; 137 | } 138 | 139 | Connect.prototype.computeStateProps = function computeStateProps(store, props) { 140 | if (!this.finalMapStateToProps) { 141 | return this.configureFinalMapState(store, props); 142 | } 143 | 144 | var state = store.getState(); 145 | var stateProps = this.doStatePropsDependOnOwnProps ? this.finalMapStateToProps(state, props) : this.finalMapStateToProps(state); 146 | 147 | if (process.env.NODE_ENV !== 'production') { 148 | checkStateShape(stateProps, 'mapStateToProps'); 149 | } 150 | return stateProps; 151 | }; 152 | 153 | Connect.prototype.configureFinalMapState = function configureFinalMapState(store, props) { 154 | var mappedState = mapState(store.getState(), props); 155 | var isFactory = typeof mappedState === 'function'; 156 | 157 | this.finalMapStateToProps = isFactory ? mappedState : mapState; 158 | this.doStatePropsDependOnOwnProps = this.finalMapStateToProps.length !== 1; 159 | 160 | if (isFactory) { 161 | return this.computeStateProps(store, props); 162 | } 163 | 164 | if (process.env.NODE_ENV !== 'production') { 165 | checkStateShape(mappedState, 'mapStateToProps'); 166 | } 167 | return mappedState; 168 | }; 169 | 170 | Connect.prototype.computeDispatchProps = function computeDispatchProps(store, props) { 171 | if (!this.finalMapDispatchToProps) { 172 | return this.configureFinalMapDispatch(store, props); 173 | } 174 | 175 | var dispatch = store.dispatch; 176 | 177 | var dispatchProps = this.doDispatchPropsDependOnOwnProps ? this.finalMapDispatchToProps(dispatch, props) : this.finalMapDispatchToProps(dispatch); 178 | 179 | if (process.env.NODE_ENV !== 'production') { 180 | checkStateShape(dispatchProps, 'mapDispatchToProps'); 181 | } 182 | return dispatchProps; 183 | }; 184 | 185 | Connect.prototype.configureFinalMapDispatch = function configureFinalMapDispatch(store, props) { 186 | var mappedDispatch = mapDispatch(store.dispatch, props); 187 | var isFactory = typeof mappedDispatch === 'function'; 188 | 189 | this.finalMapDispatchToProps = isFactory ? mappedDispatch : mapDispatch; 190 | this.doDispatchPropsDependOnOwnProps = this.finalMapDispatchToProps.length !== 1; 191 | 192 | if (isFactory) { 193 | return this.computeDispatchProps(store, props); 194 | } 195 | 196 | if (process.env.NODE_ENV !== 'production') { 197 | checkStateShape(mappedDispatch, 'mapDispatchToProps'); 198 | } 199 | return mappedDispatch; 200 | }; 201 | 202 | Connect.prototype.updateStatePropsIfNeeded = function updateStatePropsIfNeeded() { 203 | var nextStateProps = this.computeStateProps(this.store, this.props); 204 | if (this.stateProps && (0, _shallowEqual2["default"])(nextStateProps, this.stateProps)) { 205 | return false; 206 | } 207 | 208 | this.stateProps = nextStateProps; 209 | return true; 210 | }; 211 | 212 | Connect.prototype.updateDispatchPropsIfNeeded = function updateDispatchPropsIfNeeded() { 213 | var nextDispatchProps = this.computeDispatchProps(this.store, this.props); 214 | if (this.dispatchProps && (0, _shallowEqual2["default"])(nextDispatchProps, this.dispatchProps)) { 215 | return false; 216 | } 217 | 218 | this.dispatchProps = nextDispatchProps; 219 | return true; 220 | }; 221 | 222 | Connect.prototype.updateMergedPropsIfNeeded = function updateMergedPropsIfNeeded() { 223 | var nextMergedProps = computeMergedProps(this.stateProps, this.dispatchProps, this.props); 224 | if (this.mergedProps && checkMergedEquals && (0, _shallowEqual2["default"])(nextMergedProps, this.mergedProps)) { 225 | return false; 226 | } 227 | 228 | this.mergedProps = nextMergedProps; 229 | return true; 230 | }; 231 | 232 | Connect.prototype.isSubscribed = function isSubscribed() { 233 | return typeof this.unsubscribe === 'function'; 234 | }; 235 | 236 | Connect.prototype.trySubscribe = function trySubscribe() { 237 | if (shouldSubscribe && !this.unsubscribe) { 238 | this.unsubscribe = this.store.subscribe(this.handleChange.bind(this)); 239 | this.handleChange(); 240 | } 241 | }; 242 | 243 | Connect.prototype.tryUnsubscribe = function tryUnsubscribe() { 244 | if (this.unsubscribe) { 245 | this.unsubscribe(); 246 | this.unsubscribe = null; 247 | } 248 | }; 249 | 250 | Connect.prototype.componentDidMount = function componentDidMount() { 251 | this.trySubscribe(); 252 | }; 253 | 254 | Connect.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { 255 | if (!pure || !(0, _shallowEqual2["default"])(nextProps, this.props)) { 256 | this.haveOwnPropsChanged = true; 257 | } 258 | }; 259 | 260 | Connect.prototype.componentWillUnmount = function componentWillUnmount() { 261 | this.tryUnsubscribe(); 262 | this.clearCache(); 263 | }; 264 | 265 | Connect.prototype.clearCache = function clearCache() { 266 | this.dispatchProps = null; 267 | this.stateProps = null; 268 | this.mergedProps = null; 269 | this.haveOwnPropsChanged = true; 270 | this.hasStoreStateChanged = true; 271 | this.haveStatePropsBeenPrecalculated = false; 272 | this.statePropsPrecalculationError = null; 273 | this.renderedElement = null; 274 | this.finalMapDispatchToProps = null; 275 | this.finalMapStateToProps = null; 276 | }; 277 | 278 | Connect.prototype.handleChange = function handleChange() { 279 | if (!this.unsubscribe) { 280 | return; 281 | } 282 | 283 | var storeState = this.store.getState(); 284 | var prevStoreState = this.state.storeState; 285 | if (pure && prevStoreState === storeState) { 286 | return; 287 | } 288 | 289 | if (pure && !this.doStatePropsDependOnOwnProps) { 290 | var haveStatePropsChanged = tryCatch(this.updateStatePropsIfNeeded, this); 291 | if (!haveStatePropsChanged) { 292 | return; 293 | } 294 | if (haveStatePropsChanged === errorObject) { 295 | this.statePropsPrecalculationError = errorObject.value; 296 | } 297 | this.haveStatePropsBeenPrecalculated = true; 298 | } 299 | 300 | this.hasStoreStateChanged = true; 301 | this.setState({ storeState: storeState }); 302 | }; 303 | 304 | Connect.prototype.getWrappedInstance = function getWrappedInstance() { 305 | return this.refs.wrappedInstance; 306 | }; 307 | 308 | Connect.prototype.render = function render() { 309 | var haveOwnPropsChanged = this.haveOwnPropsChanged, 310 | hasStoreStateChanged = this.hasStoreStateChanged, 311 | haveStatePropsBeenPrecalculated = this.haveStatePropsBeenPrecalculated, 312 | statePropsPrecalculationError = this.statePropsPrecalculationError, 313 | renderedElement = this.renderedElement; 314 | 315 | 316 | this.haveOwnPropsChanged = false; 317 | this.hasStoreStateChanged = false; 318 | this.haveStatePropsBeenPrecalculated = false; 319 | this.statePropsPrecalculationError = null; 320 | 321 | if (statePropsPrecalculationError) { 322 | throw statePropsPrecalculationError; 323 | } 324 | 325 | var shouldUpdateStateProps = true; 326 | var shouldUpdateDispatchProps = true; 327 | if (pure && renderedElement) { 328 | shouldUpdateStateProps = hasStoreStateChanged || haveOwnPropsChanged && this.doStatePropsDependOnOwnProps; 329 | shouldUpdateDispatchProps = haveOwnPropsChanged && this.doDispatchPropsDependOnOwnProps; 330 | } 331 | 332 | var haveStatePropsChanged = false; 333 | var haveDispatchPropsChanged = false; 334 | if (haveStatePropsBeenPrecalculated) { 335 | haveStatePropsChanged = true; 336 | } else if (shouldUpdateStateProps) { 337 | haveStatePropsChanged = this.updateStatePropsIfNeeded(); 338 | } 339 | if (shouldUpdateDispatchProps) { 340 | haveDispatchPropsChanged = this.updateDispatchPropsIfNeeded(); 341 | } 342 | 343 | var haveMergedPropsChanged = true; 344 | if (haveStatePropsChanged || haveDispatchPropsChanged || haveOwnPropsChanged) { 345 | haveMergedPropsChanged = this.updateMergedPropsIfNeeded(); 346 | } else { 347 | haveMergedPropsChanged = false; 348 | } 349 | 350 | if (!haveMergedPropsChanged && renderedElement) { 351 | return renderedElement; 352 | } 353 | 354 | if (withRef) { 355 | this.renderedElement = (0, _react.createElement)(WrappedComponent, _extends({}, this.mergedProps, { 356 | ref: 'wrappedInstance' 357 | })); 358 | } else { 359 | this.renderedElement = (0, _react.createElement)(WrappedComponent, this.mergedProps); 360 | } 361 | 362 | return this.renderedElement; 363 | }; 364 | 365 | return Connect; 366 | }(_react.Component); 367 | 368 | Connect.displayName = connectDisplayName; 369 | Connect.WrappedComponent = WrappedComponent; 370 | Connect.contextTypes = { 371 | store: _storeShape2["default"] 372 | }; 373 | Connect.propTypes = { 374 | store: _storeShape2["default"] 375 | }; 376 | 377 | if (process.env.NODE_ENV !== 'production') { 378 | Connect.prototype.componentWillUpdate = function componentWillUpdate() { 379 | if (this.version === version) { 380 | return; 381 | } 382 | 383 | // We are hot reloading! 384 | this.version = version; 385 | this.trySubscribe(); 386 | this.clearCache(); 387 | }; 388 | } 389 | 390 | return (0, _hoistNonReactStatics2["default"])(Connect, WrappedComponent); 391 | }; 392 | } -------------------------------------------------------------------------------- /dist/react-rebix.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("react")):"function"==typeof define&&define.amd?define(["react"],e):"object"==typeof exports?exports.ReactRebix=e(require("react")):t.ReactRebix=e(t.React)}(this,function(t){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}var o=r(17),i=n(o),u=r(18),a=n(u),s=r(20),c=n(s),f=r(19),p=n(f),l=r(14),d=n(l),h=r(15),y=n(h),v={createActions:i["default"],createComponent:a["default"],createStore:c["default"],createConfigure:p["default"],Provider:d["default"],PureRenderComponent:y["default"]};t.exports=v},function(t,e){"use strict";function r(t,e){for(var r in t)if(r&&t.hasOwnProperty(r)){var n=t[r];e(""+r,n)}}e.__esModule=!0,e["default"]=r},function(t,e){"use strict";function r(t){"undefined"!=typeof console&&"function"==typeof console.error&&console.error(t);try{throw Error(t)}catch(t){}}e.__esModule=!0,e["default"]=r},function(e,r){e.exports=t},function(t,e){"use strict";function r(t,e){return Object.prototype.toString.call(t)==="[object "+e+"]"}function n(t){return r(t,"Function")}function o(t){return r(t,"String")}function i(t){if(!t)return[];var e=Array.prototype.slice.call(t),r=[].concat(e);return r}function u(t,e){if(!t)return null;var r=s;return n(t.get)&&(r=t.get(e)),r===s&&(r=t[e]),r}function a(t,e){if(!t)return null;try{for(var r=e.split("."),n=t,o=0;r.length>o;){if(!n)return null;var i=r[o];n=u(n,i),o++}return n}catch(t){console.log("[ERROR]",t)}return null}e.__esModule=!0,e.isType=r,e.isFunction=n,e.isString=o,e.toArray=i,e.getValueByKey=u,e.getValueInPath=a;var s=void 0},function(t,e){"use strict";function r(t){return t&&"function"==typeof t.then&&"function"==typeof t["catch"]}e.__esModule=!0,e["default"]=r},function(t,e,r){function n(t){if(!u(t)||o(t)!=a)return!1;var e=i(t);if(null===e)return!0;var r=p.call(e,"constructor")&&e.constructor;return"function"==typeof r&&r instanceof r&&f.call(r)==l}var o=r(24),i=r(26),u=r(31),a="[object Object]",s=Function.prototype,c=Object.prototype,f=s.toString,p=c.hasOwnProperty,l=f.call(Object);t.exports=n},function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}e.__esModule=!0,e.compose=e.applyMiddleware=e.bindActionCreators=e.combineReducers=e.createStore=void 0;var o=r(12),i=n(o),u=r(34),a=n(u),s=r(33),c=n(s),f=r(32),p=n(f),l=r(11),d=n(l),h=r(13);n(h);e.createStore=i["default"],e.combineReducers=a["default"],e.bindActionCreators=c["default"],e.applyMiddleware=p["default"],e.compose=d["default"]},function(t,e){"use strict";function r(t,e){if(t===e)return!0;var r=Object.keys(t),n=Object.keys(e);if(r.length!==n.length)return!1;for(var o=Object.prototype.hasOwnProperty,i=0;r.length>i;i++)if(!o.call(e,r[i])||t[r[i]]!==e[r[i]])return!1;return!0}e.__esModule=!0,e["default"]=r},function(t,e,r){"use strict";e.__esModule=!0;var n=r(3);e["default"]=n.PropTypes.shape({subscribe:n.PropTypes.func.isRequired,dispatch:n.PropTypes.func.isRequired,getState:n.PropTypes.func.isRequired})},function(t,e,r){var n=r(30),o=n.Symbol;t.exports=o},function(t,e){"use strict";function r(){for(var t=arguments.length,e=Array(t),r=0;t>r;r++)e[r]=arguments[r];if(0===e.length)return function(t){return t};if(1===e.length)return e[0];var n=e[e.length-1],o=e.slice(0,-1);return function(){return o.reduceRight(function(t,e){return e(t)},n.apply(void 0,arguments))}}e.__esModule=!0,e["default"]=r},function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t,e,r){function n(){b===v&&(b=v.slice())}function i(){return y}function a(t){if("function"!=typeof t)throw Error("Expected listener to be a function.");var e=!0;return n(),b.push(t),function(){if(e){e=!1,n();var r=b.indexOf(t);b.splice(r,1)}}}function f(t){if(!(0,u["default"])(t))throw Error("Actions must be plain objects. Use custom middleware for async actions.");if(void 0===t.type)throw Error('Actions may not have an undefined "type" property. Have you misspelled a constant?');if(g)throw Error("Reducers may not dispatch actions.");try{g=!0,y=h(y,t)}finally{g=!1}for(var e=v=b,r=0;e.length>r;r++)e[r]();return t}function p(t){if("function"!=typeof t)throw Error("Expected the nextReducer to be a function.");h=t,f({type:c.INIT})}function l(){var t,e=a;return t={subscribe:function(t){function r(){t.next&&t.next(i())}if("object"!=typeof t)throw new TypeError("Expected the observer to be an object.");r();var n=e(r);return{unsubscribe:n}}},t[s["default"]]=function(){return this},t}var d;if("function"==typeof e&&void 0===r&&(r=e,e=void 0),void 0!==r){if("function"!=typeof r)throw Error("Expected the enhancer to be a function.");return r(o)(t,e)}if("function"!=typeof t)throw Error("Expected the reducer to be a function.");var h=t,y=e,v=[],b=v,g=!1;return f({type:c.INIT}),d={dispatch:f,subscribe:a,getState:i,replaceReducer:p},d[s["default"]]=l,d}e.__esModule=!0,e.ActionTypes=void 0,e["default"]=o;var i=r(6),u=n(i),a=r(35),s=n(a),c=e.ActionTypes={INIT:"@@redux/INIT"}},function(t,e){"use strict";function r(t){"undefined"!=typeof console&&"function"==typeof console.error&&console.error(t);try{throw Error(t)}catch(t){}}e.__esModule=!0,e["default"]=r},function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function u(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}e.__esModule=!0,e["default"]=void 0;var a=r(3),s=r(9),c=n(s),f=function(t){function e(r,n){o(this,e);var u=i(this,t.call(this,r,n));return u.store=r.store,u}return u(e,t),e.prototype.getChildContext=function(){return{store:this.store}},e.prototype.render=function(){var t=this.props.children;return a.Children.only(t)},e}(a.Component);e["default"]=f,f.propTypes={store:c["default"].isRequired,children:a.PropTypes.element.isRequired},f.childContextTypes={store:c["default"].isRequired}},function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function u(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function a(t,e,r){return!(0,p["default"])(t.props,e)||!(0,p["default"])(t.state,r)}e.__esModule=!0,e["default"]=void 0,e.shallowCompare=a;var s=r(3),c=n(s),f=r(8),p=n(f),l=function(t){function e(){return o(this,e),i(this,t.apply(this,arguments))}return u(e,t),e.prototype.shouldComponentUpdate=function(t,e){var r=a(this,t,e);return r},e}(c["default"].Component);e["default"]=l},function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function u(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function a(t){return t.displayName||t.name||"Component"}function s(t,e){try{return t.apply(e)}catch(t){return M.value=t,M}}function c(t,e,r){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},c=!!t,l=t||w,h=void 0;h="function"==typeof e?e:e?(0,b["default"])(e):O;var v=r||S,g=n.pure,P=void 0===g||g,m=n.withRef,x=void 0!==m&&m,T=P&&v!==S,C=j++;return function(t){function e(t,e,r){var n=v(t,e,r);return n}var r="Connect("+a(t)+")",n=function(n){function a(t,e){o(this,a);var u=i(this,n.call(this,t,e));if(u.version=C,u.store=t.store||e.store,!u.store){var s='Could not find "store" in either the context or '+('props of "'+r+'". ')+"Either wrap the root component in a , "+('or explicitly pass "store" as a prop to "'+r+'".');console.log(s)}var c=u.store.getState();return u.state={storeState:c},u.clearCache(),u}return u(a,n),a.prototype.shouldComponentUpdate=function(){return!P||this.haveOwnPropsChanged||this.hasStoreStateChanged},a.prototype.computeStateProps=function(t,e){if(!this.finalMapStateToProps)return this.configureFinalMapState(t,e);var r=t.getState(),n=this.doStatePropsDependOnOwnProps?this.finalMapStateToProps(r,e):this.finalMapStateToProps(r);return n},a.prototype.configureFinalMapState=function(t,e){var r=l(t.getState(),e),n="function"==typeof r;return this.finalMapStateToProps=n?r:l,this.doStatePropsDependOnOwnProps=1!==this.finalMapStateToProps.length,n?this.computeStateProps(t,e):r},a.prototype.computeDispatchProps=function(t,e){if(!this.finalMapDispatchToProps)return this.configureFinalMapDispatch(t,e);var r=t.dispatch,n=this.doDispatchPropsDependOnOwnProps?this.finalMapDispatchToProps(r,e):this.finalMapDispatchToProps(r);return n},a.prototype.configureFinalMapDispatch=function(t,e){var r=h(t.dispatch,e),n="function"==typeof r;return this.finalMapDispatchToProps=n?r:h,this.doDispatchPropsDependOnOwnProps=1!==this.finalMapDispatchToProps.length,n?this.computeDispatchProps(t,e):r},a.prototype.updateStatePropsIfNeeded=function(){var t=this.computeStateProps(this.store,this.props);return(!this.stateProps||!(0,y["default"])(t,this.stateProps))&&(this.stateProps=t,!0)},a.prototype.updateDispatchPropsIfNeeded=function(){var t=this.computeDispatchProps(this.store,this.props);return(!this.dispatchProps||!(0,y["default"])(t,this.dispatchProps))&&(this.dispatchProps=t,!0)},a.prototype.updateMergedPropsIfNeeded=function(){var t=e(this.stateProps,this.dispatchProps,this.props);return!(this.mergedProps&&T&&(0,y["default"])(t,this.mergedProps))&&(this.mergedProps=t,!0)},a.prototype.isSubscribed=function(){return"function"==typeof this.unsubscribe},a.prototype.trySubscribe=function(){c&&!this.unsubscribe&&(this.unsubscribe=this.store.subscribe(this.handleChange.bind(this)),this.handleChange())},a.prototype.tryUnsubscribe=function(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null)},a.prototype.componentDidMount=function(){this.trySubscribe()},a.prototype.componentWillReceiveProps=function(t){P&&(0,y["default"])(t,this.props)||(this.haveOwnPropsChanged=!0)},a.prototype.componentWillUnmount=function(){this.tryUnsubscribe(),this.clearCache()},a.prototype.clearCache=function(){this.dispatchProps=null,this.stateProps=null,this.mergedProps=null,this.haveOwnPropsChanged=!0,this.hasStoreStateChanged=!0,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,this.renderedElement=null,this.finalMapDispatchToProps=null,this.finalMapStateToProps=null},a.prototype.handleChange=function(){if(this.unsubscribe){var t=this.store.getState(),e=this.state.storeState;if(!P||e!==t){if(P&&!this.doStatePropsDependOnOwnProps){var r=s(this.updateStatePropsIfNeeded,this);if(!r)return;r===M&&(this.statePropsPrecalculationError=M.value),this.haveStatePropsBeenPrecalculated=!0}this.hasStoreStateChanged=!0,this.setState({storeState:t})}}},a.prototype.getWrappedInstance=function(){return this.refs.wrappedInstance},a.prototype.render=function(){var e=this.haveOwnPropsChanged,r=this.hasStoreStateChanged,n=this.haveStatePropsBeenPrecalculated,o=this.statePropsPrecalculationError,i=this.renderedElement;if(this.haveOwnPropsChanged=!1,this.hasStoreStateChanged=!1,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,o)throw o;var u=!0,a=!0;P&&i&&(u=r||e&&this.doStatePropsDependOnOwnProps,a=e&&this.doDispatchPropsDependOnOwnProps);var s=!1,c=!1;n?s=!0:u&&(s=this.updateStatePropsIfNeeded()),a&&(c=this.updateDispatchPropsIfNeeded());var l=!0;return l=!!(s||c||e)&&this.updateMergedPropsIfNeeded(),!l&&i?i:this.renderedElement=x?(0,p.createElement)(t,f({},this.mergedProps,{ref:"wrappedInstance"})):(0,p.createElement)(t,this.mergedProps)},a}(p.Component);return n.displayName=r,n.WrappedComponent=t,n.contextTypes={store:d["default"]},n.propTypes={store:d["default"]},(0,_["default"])(n,t)}}e.__esModule=!0;var f=Object.assign||function(t){for(var e=1;arguments.length>e;e++){var r=arguments[e];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t};e["default"]=c;var p=r(3),l=r(9),d=n(l),h=r(8),y=n(h),v=r(23),b=n(v),g=r(2),P=(n(g),r(6)),m=(n(P),r(22)),_=n(m),w=function(t){return{}},O=function(t){return{dispatch:t}},S=function(t,e,r){return f({},r,t,e)},M={value:null},j=0},function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(){return null}function i(t,e,r){return function(n,o){var i=t.apply(r,o),u=null,a=null;return(0,f["default"])(i)?u=i:a=i,{type:n+"_"+e,group:n,name:e,status:"unknown",args:o,promise:u,payload:a}}}function u(t){var e={};return(0,s["default"])(t,function(r,n){n||(n=o),e[r]=i(n,r,t)}),e}e.__esModule=!0,e["default"]=u;var a=r(1),s=n(a),c=r(5),f=n(c)},function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){var r=e.split(".")[0];return function(){var e=(0,d.toArray)(arguments),n=t(r,e);return n}}function i(t,e){var r={};if(!e||!t)return null;var n=e.actions||{},i=t.getActions();return(0,y["default"])(n,function(t,e){var n=(0,d.getValueInPath)(i,e||"");n===m?(0,b["default"])("[ERROR]cannot get Object by key : "+t+" and path: "+e+" "):r[t]=o(n,e)}),r}function u(t){return function(){var e=(0,d.toArray)(arguments),r=t.apply({},e);return r?(0,P["default"])(r.promise)?r.promise:r.payload:null}}function a(t){var e={};return(0,y["default"])(t,function(t,r){e[t]=u(r)}),e}function s(t,e){var r={};if(!e||!t)return null;var n=e.props||{};return(0,y["default"])(n,function(e,n){(0,d.isFunction)(n)?r[e]=n(t):(0,d.isString)(n)&&(r[e]=(0,d.getValueInPath)(t,n||"")),r[e]===m&&(0,b["default"])("[ERROR]cannot get Object by key : "+e+" and path: "+n+" ")}),r}function c(t,e,r){function n(t){var e=s(t,r);return e}function o(e){var n=i(t,r),o=(0,f.bindActionCreators)(n,e),u=a(o);return{actions:u}}return(0,l["default"])(n,o)(e)}e.__esModule=!0,e["default"]=c;var f=r(7),p=r(16),l=n(p),d=r(4),h=r(1),y=n(h),v=r(2),b=n(v),g=r(5),P=n(g),m=void 0},function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t){var e=t.stores;e&&(0,h["default"])(e,function(t,e){e.$$StoreGroupName=t})}function u(t){for(var e=[],r=!1,n=0;t.length>n;n++){var o=t[n];if("promiseMiddleware"===o)e.push(p["default"]),r=!0;else{if(!(0,l.isFunction)(o))throw Error(o+" is not a middleware");e.push(o)}}return r||(0,v["default"])("Must has a promiseMiddleware,please check createConfigure"),e}function a(t){var e=null;return t&&t.length>0?(t=u(t),e=c.applyMiddleware.apply({},t)):e=(0,c.applyMiddleware)(p["default"]),e(c.createStore)}function s(t){return new g(t)}e.__esModule=!0,e["default"]=s;var c=r(7),f=r(21),p=n(f),l=r(4),d=r(1),h=n(d),y=r(2),v=n(y),b=function(t){var e=t.stores||{},r={};for(var n in e)if(e.hasOwnProperty(n)){var o=e[n],i=o.$$reducer;r[n]=i}return(0,c.combineReducers)(r)},g=function(){function t(e){o(this,t),i(e),this.config=e;var r=e.initialState,n=e.middleware,u=b(e),s=a(n);this.store=r?s(u,r):s(u)}return t.prototype.getStore=function(){return this.store},t.prototype.getActions=function(){return this.config.actions},t}()},function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t){return t.replace(/(^|\s+)\w/g,function(t){return t.toUpperCase()})}function i(t,e,r,n){if(!t)return null;var i="on"+o(t);if(e===n){var u=r[i];if(u)return u}var a=e+"#"+i;return u=r[a],u?u:null}function u(t,e,r,n){var o=e.name,u=e.group,a=i(o,u,r,n);if(a){var s=a(t,e);if(s)return s;(0,d["default"])("[ERROR] error store config:"+u+"#"+o)}return t}function a(t,e){return function(){var r=(0,h.toArray)(arguments),n=e.$$state,o=[n].concat(r);return t.apply({},o)}}function s(t,e){(0,p["default"])(e,function(e,r){0===e.indexOf("get")&&(0,h.isFunction)(r)&&(t[e]=a(r,t))})}function c(t){var e=t.initialState||{},r={},n=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:e,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=r.$$StoreGroupName;return n=u(n,o,t,i),r.$$state=n,n};return r.$$reducer=n,r.$$StoreGroupName=null,s(r,t),r}e.__esModule=!0,e["default"]=c;var f=r(1),p=n(f),l=r(2),d=n(l),h=r(4)},function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t){var e=t.dispatch;return function(t){return function(r){if(!(0,u["default"])(r.promise))return r.status="success",t(r);var n=r.type,o=r.group,i=r.name,a=r.args,s=r.promise,c=function(t,e,r){return{type:n,group:o,name:i,status:t,args:a,promise:e,payload:r}};s=s.then(function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=c("success",null,t);return e(r)},function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=c("error",null,t);return e(r)});var f=c("pending",s,null);return t(f)}}}e.__esModule=!0,e["default"]=o;var i=r(5),u=n(i)},function(t,e){"use strict";var r={childContextTypes:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,mixins:!0,propTypes:!0,type:!0},n={name:!0,length:!0,prototype:!0,caller:!0,arguments:!0,arity:!0},o="function"==typeof Object.getOwnPropertySymbols;t.exports=function(t,e,i){if("string"!=typeof e){var u=Object.getOwnPropertyNames(e);o&&(u=u.concat(Object.getOwnPropertySymbols(e)));for(var a=0;u.length>a;++a)if(!(r[u[a]]||n[u[a]]||i&&i[u[a]]))try{t[u[a]]=e[u[a]]}catch(t){}}return t}},function(t,e,r){"use strict";function n(t){return function(e){return(0,o.bindActionCreators)(t,e)}}e.__esModule=!0,e["default"]=n;var o=r(7)},function(t,e,r){function n(t){return null==t?void 0===t?s:a:c&&c in Object(t)?i(t):u(t)}var o=r(10),i=r(27),u=r(28),a="[object Null]",s="[object Undefined]",c=o?o.toStringTag:void 0;t.exports=n},function(t,e){(function(e){var r="object"==typeof e&&e&&e.Object===Object&&e;t.exports=r}).call(e,function(){return this}()||Function("return this")())},function(t,e,r){var n=r(29),o=n(Object.getPrototypeOf,Object);t.exports=o},function(t,e,r){function n(t){var e=u.call(t,s),r=t[s];try{t[s]=void 0;var n=!0}catch(t){}var o=a.call(t);return n&&(e?t[s]=r:delete t[s]),o}var o=r(10),i=Object.prototype,u=i.hasOwnProperty,a=i.toString,s=o?o.toStringTag:void 0;t.exports=n},function(t,e){function r(t){return o.call(t)}var n=Object.prototype,o=n.toString;t.exports=r},function(t,e){function r(t,e){return function(r){return t(e(r))}}t.exports=r},function(t,e,r){var n=r(25),o="object"==typeof self&&self&&self.Object===Object&&self,i=n||o||Function("return this")();t.exports=i},function(t,e){function r(t){return null!=t&&"object"==typeof t}t.exports=r},function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(){for(var t=arguments.length,e=Array(t),r=0;t>r;r++)e[r]=arguments[r];return function(t){return function(r,n,o){var u=t(r,n,o),s=u.dispatch,c=[],f={getState:u.getState,dispatch:function(t){return s(t)}};return c=e.map(function(t){return t(f)}),s=a["default"].apply(void 0,c)(u.dispatch),i({},u,{dispatch:s})}}}e.__esModule=!0;var i=Object.assign||function(t){for(var e=1;arguments.length>e;e++){var r=arguments[e];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t};e["default"]=o;var u=r(11),a=n(u)},function(t,e){"use strict";function r(t,e){return function(){return e(t.apply(void 0,arguments))}}function n(t,e){if("function"==typeof t)return r(t,e);if("object"!=typeof t||null===t)throw Error("bindActionCreators expected an object or a function, instead received "+(null===t?"null":typeof t)+'. Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?');for(var n=Object.keys(t),o={},i=0;n.length>i;i++){var u=n[i],a=t[u];"function"==typeof a&&(o[u]=r(a,e))}return o}e.__esModule=!0,e["default"]=n},function(t,e,r){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){var r=e&&e.type,n=r&&'"'+r+'"'||"an action";return"Given action "+n+', reducer "'+t+'" returned undefined. To ignore an action, you must explicitly return the previous state.'}function i(t){Object.keys(t).forEach(function(e){var r=t[e],n=r(void 0,{type:a.ActionTypes.INIT});if(void 0===n)throw Error('Reducer "'+e+'" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined.');var o="@@redux/PROBE_UNKNOWN_ACTION_"+Math.random().toString(36).substring(7).split("").join(".");if(void 0===r(void 0,{type:o}))throw Error('Reducer "'+e+'" returned undefined when probed with a random type. '+("Don't try to handle "+a.ActionTypes.INIT+' or other actions in "redux/*" ')+"namespace. They are considered private. Instead, you must return the current state for any unknown actions, unless it is undefined, in which case you must return the initial state, regardless of the action type. The initial state may not be undefined.")})}function u(t){for(var e=Object.keys(t),r={},n=0;e.length>n;n++){var u=e[n];"function"==typeof t[u]&&(r[u]=t[u])}var a,s=Object.keys(r);try{i(r)}catch(t){a=t}return function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments[1];if(a)throw a;for(var n=!1,i={},u=0;s.length>u;u++){var c=s[u],f=r[c],p=t[c],l=f(p,e);if(void 0===l){var d=o(c,e);throw Error(d)}i[c]=l,n=n||l!==p}return n?i:t}}e.__esModule=!0,e["default"]=u;var a=r(12),s=r(6),c=(n(s),r(13));n(c)},function(t,e,r){t.exports=r(36)},function(t,e,r){(function(t,n){"use strict";function o(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(e,"__esModule",{value:!0});var i,u=r(37),a=o(u);i="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==t?t:n;var s=(0,a["default"])(i);e["default"]=s}).call(e,function(){return this}()||Function("return this")(),r(38)(t))},function(t,e){"use strict";function r(t){var e,r=t.Symbol;return"function"==typeof r?r.observable?e=r.observable:(e=r("observable"),r.observable=e):e="@@observable",e}Object.defineProperty(e,"__esModule",{value:!0}),e["default"]=r},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children=[],t.webpackPolyfill=1),t}}])}); -------------------------------------------------------------------------------- /dist/react-rebix.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(require("react")); 4 | else if(typeof define === 'function' && define.amd) 5 | define(["react"], factory); 6 | else if(typeof exports === 'object') 7 | exports["ReactRebix"] = factory(require("react")); 8 | else 9 | root["ReactRebix"] = factory(root["React"]); 10 | })(this, function(__WEBPACK_EXTERNAL_MODULE_3__) { 11 | return /******/ (function(modules) { // webpackBootstrap 12 | /******/ // The module cache 13 | /******/ var installedModules = {}; 14 | 15 | /******/ // The require function 16 | /******/ function __webpack_require__(moduleId) { 17 | 18 | /******/ // Check if module is in cache 19 | /******/ if(installedModules[moduleId]) 20 | /******/ return installedModules[moduleId].exports; 21 | 22 | /******/ // Create a new module (and put it into the cache) 23 | /******/ var module = installedModules[moduleId] = { 24 | /******/ exports: {}, 25 | /******/ id: moduleId, 26 | /******/ loaded: false 27 | /******/ }; 28 | 29 | /******/ // Execute the module function 30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 31 | 32 | /******/ // Flag the module as loaded 33 | /******/ module.loaded = true; 34 | 35 | /******/ // Return the exports of the module 36 | /******/ return module.exports; 37 | /******/ } 38 | 39 | 40 | /******/ // expose the modules object (__webpack_modules__) 41 | /******/ __webpack_require__.m = modules; 42 | 43 | /******/ // expose the module cache 44 | /******/ __webpack_require__.c = installedModules; 45 | 46 | /******/ // __webpack_public_path__ 47 | /******/ __webpack_require__.p = ""; 48 | 49 | /******/ // Load entry module and return exports 50 | /******/ return __webpack_require__(0); 51 | /******/ }) 52 | /************************************************************************/ 53 | /******/ ([ 54 | /* 0 */ 55 | /***/ function(module, exports, __webpack_require__) { 56 | 57 | 'use strict'; 58 | 59 | var _createActions = __webpack_require__(17); 60 | 61 | var _createActions2 = _interopRequireDefault(_createActions); 62 | 63 | var _createComponent = __webpack_require__(18); 64 | 65 | var _createComponent2 = _interopRequireDefault(_createComponent); 66 | 67 | var _createStore = __webpack_require__(20); 68 | 69 | var _createStore2 = _interopRequireDefault(_createStore); 70 | 71 | var _createConfigure = __webpack_require__(19); 72 | 73 | var _createConfigure2 = _interopRequireDefault(_createConfigure); 74 | 75 | var _Provider = __webpack_require__(14); 76 | 77 | var _Provider2 = _interopRequireDefault(_Provider); 78 | 79 | var _PureRenderComponent = __webpack_require__(15); 80 | 81 | var _PureRenderComponent2 = _interopRequireDefault(_PureRenderComponent); 82 | 83 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 84 | 85 | var Reubibi = { 86 | createActions: _createActions2["default"], 87 | createComponent: _createComponent2["default"], 88 | createStore: _createStore2["default"], 89 | createConfigure: _createConfigure2["default"], 90 | Provider: _Provider2["default"], 91 | PureRenderComponent: _PureRenderComponent2["default"] 92 | }; 93 | 94 | module.exports = Reubibi; 95 | //export default Reubibi; 96 | 97 | /***/ }, 98 | /* 1 */ 99 | /***/ function(module, exports) { 100 | 101 | 'use strict'; 102 | 103 | exports.__esModule = true; 104 | exports["default"] = objectForEach; 105 | function objectForEach(obj, handler) { 106 | for (var key in obj) { 107 | if (key && obj.hasOwnProperty(key)) { 108 | var value = obj[key]; 109 | handler('' + key, value); 110 | } 111 | } 112 | } 113 | 114 | /***/ }, 115 | /* 2 */ 116 | /***/ function(module, exports) { 117 | 118 | 'use strict'; 119 | 120 | exports.__esModule = true; 121 | exports["default"] = warning; 122 | /** 123 | * Prints a warning in the console if it exists. 124 | * 125 | * @param {String} message The warning message. 126 | * @returns {void} 127 | */ 128 | function warning(message) { 129 | /* eslint-disable no-console */ 130 | if (typeof console !== 'undefined' && typeof console.error === 'function') { 131 | console.error(message); 132 | } 133 | /* eslint-enable no-console */ 134 | try { 135 | // This error was thrown as a convenience so that you can use this stack 136 | // to find the callsite that caused this warning to fire. 137 | throw new Error(message); 138 | /* eslint-disable no-empty */ 139 | } catch (e) {} 140 | /* eslint-enable no-empty */ 141 | } 142 | 143 | /***/ }, 144 | /* 3 */ 145 | /***/ function(module, exports) { 146 | 147 | module.exports = __WEBPACK_EXTERNAL_MODULE_3__; 148 | 149 | /***/ }, 150 | /* 4 */ 151 | /***/ function(module, exports) { 152 | 153 | 'use strict'; 154 | 155 | exports.__esModule = true; 156 | exports.isType = isType; 157 | exports.isFunction = isFunction; 158 | exports.isString = isString; 159 | exports.toArray = toArray; 160 | exports.getValueByKey = getValueByKey; 161 | exports.getValueInPath = getValueInPath; 162 | var _undefined = undefined; 163 | 164 | function isType(x, type) { 165 | return Object.prototype.toString.call(x) === '[object ' + type + ']'; 166 | } 167 | 168 | function isFunction(x) { 169 | return isType(x, 'Function'); 170 | } 171 | function isString(x) { 172 | return isType(x, 'String'); 173 | } 174 | 175 | function toArray(aaa) { 176 | if (!aaa) { 177 | return []; 178 | } 179 | 180 | var argsArray = Array.prototype.slice.call(aaa); 181 | var args = [].concat(argsArray); 182 | return args; 183 | } 184 | 185 | function getValueByKey(obj, key) { 186 | if (!obj) { 187 | return null; 188 | } 189 | var value = _undefined; 190 | if (isFunction(obj.get)) { 191 | value = obj.get(key); 192 | } 193 | if (value === _undefined) { 194 | value = obj[key]; 195 | } 196 | 197 | return value; 198 | } 199 | 200 | /** 201 | * a = { 202 | * b:{ 203 | * c:{ 204 | * d:1 205 | * } 206 | * } 207 | * } 208 | * 209 | * str : b.c.d 210 | * @param obj 211 | * @param str 212 | * @demo : 213 | * var d = getObjectValue(a,'b.c.d'); 214 | */ 215 | function getValueInPath(obj, str) { 216 | if (!obj) { 217 | return null; 218 | } 219 | try { 220 | var propArr = str.split("."); 221 | var tmpObj = obj; 222 | var i = 0; 223 | while (i < propArr.length) { 224 | if (!tmpObj) { 225 | return null; 226 | } 227 | var prop = propArr[i]; 228 | tmpObj = getValueByKey(tmpObj, prop); 229 | i++; 230 | } 231 | return tmpObj; 232 | } catch (e) { 233 | console.log('[ERROR]', e); 234 | } 235 | 236 | return null; 237 | } 238 | 239 | /***/ }, 240 | /* 5 */ 241 | /***/ function(module, exports) { 242 | 243 | 'use strict'; 244 | 245 | exports.__esModule = true; 246 | exports["default"] = isPromise; 247 | function isPromise(p) { 248 | return p && typeof p.then === 'function' && typeof p["catch"] === 'function'; 249 | } 250 | 251 | /***/ }, 252 | /* 6 */ 253 | /***/ function(module, exports, __webpack_require__) { 254 | 255 | var baseGetTag = __webpack_require__(24), 256 | getPrototype = __webpack_require__(26), 257 | isObjectLike = __webpack_require__(31); 258 | 259 | /** `Object#toString` result references. */ 260 | var objectTag = '[object Object]'; 261 | 262 | /** Used for built-in method references. */ 263 | var funcProto = Function.prototype, 264 | objectProto = Object.prototype; 265 | 266 | /** Used to resolve the decompiled source of functions. */ 267 | var funcToString = funcProto.toString; 268 | 269 | /** Used to check objects for own properties. */ 270 | var hasOwnProperty = objectProto.hasOwnProperty; 271 | 272 | /** Used to infer the `Object` constructor. */ 273 | var objectCtorString = funcToString.call(Object); 274 | 275 | /** 276 | * Checks if `value` is a plain object, that is, an object created by the 277 | * `Object` constructor or one with a `[[Prototype]]` of `null`. 278 | * 279 | * @static 280 | * @memberOf _ 281 | * @since 0.8.0 282 | * @category Lang 283 | * @param {*} value The value to check. 284 | * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. 285 | * @example 286 | * 287 | * function Foo() { 288 | * this.a = 1; 289 | * } 290 | * 291 | * _.isPlainObject(new Foo); 292 | * // => false 293 | * 294 | * _.isPlainObject([1, 2, 3]); 295 | * // => false 296 | * 297 | * _.isPlainObject({ 'x': 0, 'y': 0 }); 298 | * // => true 299 | * 300 | * _.isPlainObject(Object.create(null)); 301 | * // => true 302 | */ 303 | function isPlainObject(value) { 304 | if (!isObjectLike(value) || baseGetTag(value) != objectTag) { 305 | return false; 306 | } 307 | var proto = getPrototype(value); 308 | if (proto === null) { 309 | return true; 310 | } 311 | var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; 312 | return typeof Ctor == 'function' && Ctor instanceof Ctor && 313 | funcToString.call(Ctor) == objectCtorString; 314 | } 315 | 316 | module.exports = isPlainObject; 317 | 318 | 319 | /***/ }, 320 | /* 7 */ 321 | /***/ function(module, exports, __webpack_require__) { 322 | 323 | 'use strict'; 324 | 325 | exports.__esModule = true; 326 | exports.compose = exports.applyMiddleware = exports.bindActionCreators = exports.combineReducers = exports.createStore = undefined; 327 | 328 | var _createStore = __webpack_require__(12); 329 | 330 | var _createStore2 = _interopRequireDefault(_createStore); 331 | 332 | var _combineReducers = __webpack_require__(34); 333 | 334 | var _combineReducers2 = _interopRequireDefault(_combineReducers); 335 | 336 | var _bindActionCreators = __webpack_require__(33); 337 | 338 | var _bindActionCreators2 = _interopRequireDefault(_bindActionCreators); 339 | 340 | var _applyMiddleware = __webpack_require__(32); 341 | 342 | var _applyMiddleware2 = _interopRequireDefault(_applyMiddleware); 343 | 344 | var _compose = __webpack_require__(11); 345 | 346 | var _compose2 = _interopRequireDefault(_compose); 347 | 348 | var _warning = __webpack_require__(13); 349 | 350 | var _warning2 = _interopRequireDefault(_warning); 351 | 352 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 353 | 354 | /* 355 | * This is a dummy function to check if the function name has been altered by minification. 356 | * If the function has been minified and NODE_ENV !== 'production', warn the user. 357 | */ 358 | function isCrushed() {} 359 | 360 | if (("development") !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') { 361 | (0, _warning2['default'])('You are currently using minified code outside of NODE_ENV === \'production\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.'); 362 | } 363 | 364 | exports.createStore = _createStore2['default']; 365 | exports.combineReducers = _combineReducers2['default']; 366 | exports.bindActionCreators = _bindActionCreators2['default']; 367 | exports.applyMiddleware = _applyMiddleware2['default']; 368 | exports.compose = _compose2['default']; 369 | 370 | /***/ }, 371 | /* 8 */ 372 | /***/ function(module, exports) { 373 | 374 | "use strict"; 375 | 376 | exports.__esModule = true; 377 | exports["default"] = shallowEqual; 378 | function shallowEqual(objA, objB) { 379 | if (objA === objB) { 380 | return true; 381 | } 382 | 383 | var keysA = Object.keys(objA); 384 | var keysB = Object.keys(objB); 385 | 386 | if (keysA.length !== keysB.length) { 387 | return false; 388 | } 389 | 390 | // Test for A's keys different from B. 391 | var hasOwn = Object.prototype.hasOwnProperty; 392 | for (var i = 0; i < keysA.length; i++) { 393 | if (!hasOwn.call(objB, keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) { 394 | return false; 395 | } 396 | } 397 | 398 | return true; 399 | } 400 | 401 | /***/ }, 402 | /* 9 */ 403 | /***/ function(module, exports, __webpack_require__) { 404 | 405 | 'use strict'; 406 | 407 | exports.__esModule = true; 408 | 409 | var _react = __webpack_require__(3); 410 | 411 | exports["default"] = _react.PropTypes.shape({ 412 | subscribe: _react.PropTypes.func.isRequired, 413 | dispatch: _react.PropTypes.func.isRequired, 414 | getState: _react.PropTypes.func.isRequired 415 | }); 416 | 417 | /***/ }, 418 | /* 10 */ 419 | /***/ function(module, exports, __webpack_require__) { 420 | 421 | var root = __webpack_require__(30); 422 | 423 | /** Built-in value references. */ 424 | var Symbol = root.Symbol; 425 | 426 | module.exports = Symbol; 427 | 428 | 429 | /***/ }, 430 | /* 11 */ 431 | /***/ function(module, exports) { 432 | 433 | "use strict"; 434 | 435 | exports.__esModule = true; 436 | exports["default"] = compose; 437 | /** 438 | * Composes single-argument functions from right to left. The rightmost 439 | * function can take multiple arguments as it provides the signature for 440 | * the resulting composite function. 441 | * 442 | * @param {...Function} funcs The functions to compose. 443 | * @returns {Function} A function obtained by composing the argument functions 444 | * from right to left. For example, compose(f, g, h) is identical to doing 445 | * (...args) => f(g(h(...args))). 446 | */ 447 | 448 | function compose() { 449 | for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) { 450 | funcs[_key] = arguments[_key]; 451 | } 452 | 453 | if (funcs.length === 0) { 454 | return function (arg) { 455 | return arg; 456 | }; 457 | } 458 | 459 | if (funcs.length === 1) { 460 | return funcs[0]; 461 | } 462 | 463 | var last = funcs[funcs.length - 1]; 464 | var rest = funcs.slice(0, -1); 465 | return function () { 466 | return rest.reduceRight(function (composed, f) { 467 | return f(composed); 468 | }, last.apply(undefined, arguments)); 469 | }; 470 | } 471 | 472 | /***/ }, 473 | /* 12 */ 474 | /***/ function(module, exports, __webpack_require__) { 475 | 476 | 'use strict'; 477 | 478 | exports.__esModule = true; 479 | exports.ActionTypes = undefined; 480 | exports['default'] = createStore; 481 | 482 | var _isPlainObject = __webpack_require__(6); 483 | 484 | var _isPlainObject2 = _interopRequireDefault(_isPlainObject); 485 | 486 | var _symbolObservable = __webpack_require__(35); 487 | 488 | var _symbolObservable2 = _interopRequireDefault(_symbolObservable); 489 | 490 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 491 | 492 | /** 493 | * These are private action types reserved by Redux. 494 | * For any unknown actions, you must return the current state. 495 | * If the current state is undefined, you must return the initial state. 496 | * Do not reference these action types directly in your code. 497 | */ 498 | var ActionTypes = exports.ActionTypes = { 499 | INIT: '@@redux/INIT' 500 | }; 501 | 502 | /** 503 | * Creates a Redux store that holds the state tree. 504 | * The only way to change the data in the store is to call `dispatch()` on it. 505 | * 506 | * There should only be a single store in your app. To specify how different 507 | * parts of the state tree respond to actions, you may combine several reducers 508 | * into a single reducer function by using `combineReducers`. 509 | * 510 | * @param {Function} reducer A function that returns the next state tree, given 511 | * the current state tree and the action to handle. 512 | * 513 | * @param {any} [preloadedState] The initial state. You may optionally specify it 514 | * to hydrate the state from the server in universal apps, or to restore a 515 | * previously serialized user session. 516 | * If you use `combineReducers` to produce the root reducer function, this must be 517 | * an object with the same shape as `combineReducers` keys. 518 | * 519 | * @param {Function} enhancer The store enhancer. You may optionally specify it 520 | * to enhance the store with third-party capabilities such as middleware, 521 | * time travel, persistence, etc. The only store enhancer that ships with Redux 522 | * is `applyMiddleware()`. 523 | * 524 | * @returns {Store} A Redux store that lets you read the state, dispatch actions 525 | * and subscribe to changes. 526 | */ 527 | function createStore(reducer, preloadedState, enhancer) { 528 | var _ref2; 529 | 530 | if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') { 531 | enhancer = preloadedState; 532 | preloadedState = undefined; 533 | } 534 | 535 | if (typeof enhancer !== 'undefined') { 536 | if (typeof enhancer !== 'function') { 537 | throw new Error('Expected the enhancer to be a function.'); 538 | } 539 | 540 | return enhancer(createStore)(reducer, preloadedState); 541 | } 542 | 543 | if (typeof reducer !== 'function') { 544 | throw new Error('Expected the reducer to be a function.'); 545 | } 546 | 547 | var currentReducer = reducer; 548 | var currentState = preloadedState; 549 | var currentListeners = []; 550 | var nextListeners = currentListeners; 551 | var isDispatching = false; 552 | 553 | function ensureCanMutateNextListeners() { 554 | if (nextListeners === currentListeners) { 555 | nextListeners = currentListeners.slice(); 556 | } 557 | } 558 | 559 | /** 560 | * Reads the state tree managed by the store. 561 | * 562 | * @returns {any} The current state tree of your application. 563 | */ 564 | function getState() { 565 | return currentState; 566 | } 567 | 568 | /** 569 | * Adds a change listener. It will be called any time an action is dispatched, 570 | * and some part of the state tree may potentially have changed. You may then 571 | * call `getState()` to read the current state tree inside the callback. 572 | * 573 | * You may call `dispatch()` from a change listener, with the following 574 | * caveats: 575 | * 576 | * 1. The subscriptions are snapshotted just before every `dispatch()` call. 577 | * If you subscribe or unsubscribe while the listeners are being invoked, this 578 | * will not have any effect on the `dispatch()` that is currently in progress. 579 | * However, the next `dispatch()` call, whether nested or not, will use a more 580 | * recent snapshot of the subscription list. 581 | * 582 | * 2. The listener should not expect to see all state changes, as the state 583 | * might have been updated multiple times during a nested `dispatch()` before 584 | * the listener is called. It is, however, guaranteed that all subscribers 585 | * registered before the `dispatch()` started will be called with the latest 586 | * state by the time it exits. 587 | * 588 | * @param {Function} listener A callback to be invoked on every dispatch. 589 | * @returns {Function} A function to remove this change listener. 590 | */ 591 | function subscribe(listener) { 592 | if (typeof listener !== 'function') { 593 | throw new Error('Expected listener to be a function.'); 594 | } 595 | 596 | var isSubscribed = true; 597 | 598 | ensureCanMutateNextListeners(); 599 | nextListeners.push(listener); 600 | 601 | return function unsubscribe() { 602 | if (!isSubscribed) { 603 | return; 604 | } 605 | 606 | isSubscribed = false; 607 | 608 | ensureCanMutateNextListeners(); 609 | var index = nextListeners.indexOf(listener); 610 | nextListeners.splice(index, 1); 611 | }; 612 | } 613 | 614 | /** 615 | * Dispatches an action. It is the only way to trigger a state change. 616 | * 617 | * The `reducer` function, used to create the store, will be called with the 618 | * current state tree and the given `action`. Its return value will 619 | * be considered the **next** state of the tree, and the change listeners 620 | * will be notified. 621 | * 622 | * The base implementation only supports plain object actions. If you want to 623 | * dispatch a Promise, an Observable, a thunk, or something else, you need to 624 | * wrap your store creating function into the corresponding middleware. For 625 | * example, see the documentation for the `redux-thunk` package. Even the 626 | * middleware will eventually dispatch plain object actions using this method. 627 | * 628 | * @param {Object} action A plain object representing “what changed”. It is 629 | * a good idea to keep actions serializable so you can record and replay user 630 | * sessions, or use the time travelling `redux-devtools`. An action must have 631 | * a `type` property which may not be `undefined`. It is a good idea to use 632 | * string constants for action types. 633 | * 634 | * @returns {Object} For convenience, the same action object you dispatched. 635 | * 636 | * Note that, if you use a custom middleware, it may wrap `dispatch()` to 637 | * return something else (for example, a Promise you can await). 638 | */ 639 | function dispatch(action) { 640 | if (!(0, _isPlainObject2['default'])(action)) { 641 | throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.'); 642 | } 643 | 644 | if (typeof action.type === 'undefined') { 645 | throw new Error('Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?'); 646 | } 647 | 648 | if (isDispatching) { 649 | throw new Error('Reducers may not dispatch actions.'); 650 | } 651 | 652 | try { 653 | isDispatching = true; 654 | currentState = currentReducer(currentState, action); 655 | } finally { 656 | isDispatching = false; 657 | } 658 | 659 | var listeners = currentListeners = nextListeners; 660 | for (var i = 0; i < listeners.length; i++) { 661 | listeners[i](); 662 | } 663 | 664 | return action; 665 | } 666 | 667 | /** 668 | * Replaces the reducer currently used by the store to calculate the state. 669 | * 670 | * You might need this if your app implements code splitting and you want to 671 | * load some of the reducers dynamically. You might also need this if you 672 | * implement a hot reloading mechanism for Redux. 673 | * 674 | * @param {Function} nextReducer The reducer for the store to use instead. 675 | * @returns {void} 676 | */ 677 | function replaceReducer(nextReducer) { 678 | if (typeof nextReducer !== 'function') { 679 | throw new Error('Expected the nextReducer to be a function.'); 680 | } 681 | 682 | currentReducer = nextReducer; 683 | dispatch({ type: ActionTypes.INIT }); 684 | } 685 | 686 | /** 687 | * Interoperability point for observable/reactive libraries. 688 | * @returns {observable} A minimal observable of state changes. 689 | * For more information, see the observable proposal: 690 | * https://github.com/zenparsing/es-observable 691 | */ 692 | function observable() { 693 | var _ref; 694 | 695 | var outerSubscribe = subscribe; 696 | return _ref = { 697 | /** 698 | * The minimal observable subscription method. 699 | * @param {Object} observer Any object that can be used as an observer. 700 | * The observer object should have a `next` method. 701 | * @returns {subscription} An object with an `unsubscribe` method that can 702 | * be used to unsubscribe the observable from the store, and prevent further 703 | * emission of values from the observable. 704 | */ 705 | subscribe: function subscribe(observer) { 706 | if (typeof observer !== 'object') { 707 | throw new TypeError('Expected the observer to be an object.'); 708 | } 709 | 710 | function observeState() { 711 | if (observer.next) { 712 | observer.next(getState()); 713 | } 714 | } 715 | 716 | observeState(); 717 | var unsubscribe = outerSubscribe(observeState); 718 | return { unsubscribe: unsubscribe }; 719 | } 720 | }, _ref[_symbolObservable2['default']] = function () { 721 | return this; 722 | }, _ref; 723 | } 724 | 725 | // When a store is created, an "INIT" action is dispatched so that every 726 | // reducer returns their initial state. This effectively populates 727 | // the initial state tree. 728 | dispatch({ type: ActionTypes.INIT }); 729 | 730 | return _ref2 = { 731 | dispatch: dispatch, 732 | subscribe: subscribe, 733 | getState: getState, 734 | replaceReducer: replaceReducer 735 | }, _ref2[_symbolObservable2['default']] = observable, _ref2; 736 | } 737 | 738 | /***/ }, 739 | /* 13 */ 740 | /***/ function(module, exports) { 741 | 742 | 'use strict'; 743 | 744 | exports.__esModule = true; 745 | exports['default'] = warning; 746 | /** 747 | * Prints a warning in the console if it exists. 748 | * 749 | * @param {String} message The warning message. 750 | * @returns {void} 751 | */ 752 | function warning(message) { 753 | /* eslint-disable no-console */ 754 | if (typeof console !== 'undefined' && typeof console.error === 'function') { 755 | console.error(message); 756 | } 757 | /* eslint-enable no-console */ 758 | try { 759 | // This error was thrown as a convenience so that if you enable 760 | // "break on all exceptions" in your console, 761 | // it would pause the execution at this line. 762 | throw new Error(message); 763 | /* eslint-disable no-empty */ 764 | } catch (e) {} 765 | /* eslint-enable no-empty */ 766 | } 767 | 768 | /***/ }, 769 | /* 14 */ 770 | /***/ function(module, exports, __webpack_require__) { 771 | 772 | 'use strict'; 773 | 774 | exports.__esModule = true; 775 | exports["default"] = undefined; 776 | 777 | var _react = __webpack_require__(3); 778 | 779 | var _storeShape = __webpack_require__(9); 780 | 781 | var _storeShape2 = _interopRequireDefault(_storeShape); 782 | 783 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 784 | 785 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 786 | 787 | function _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; } 788 | 789 | function _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; } 790 | 791 | var Provider = function (_Component) { 792 | _inherits(Provider, _Component); 793 | 794 | Provider.prototype.getChildContext = function getChildContext() { 795 | return { store: this.store }; 796 | }; 797 | 798 | function Provider(props, context) { 799 | _classCallCheck(this, Provider); 800 | 801 | var _this = _possibleConstructorReturn(this, _Component.call(this, props, context)); 802 | 803 | _this.store = props.store; 804 | return _this; 805 | } 806 | 807 | Provider.prototype.render = function render() { 808 | var children = this.props.children; 809 | 810 | return _react.Children.only(children); 811 | }; 812 | 813 | return Provider; 814 | }(_react.Component); 815 | 816 | exports["default"] = Provider; 817 | 818 | 819 | Provider.propTypes = { 820 | store: _storeShape2["default"].isRequired, 821 | children: _react.PropTypes.element.isRequired 822 | }; 823 | Provider.childContextTypes = { 824 | store: _storeShape2["default"].isRequired 825 | }; 826 | 827 | /***/ }, 828 | /* 15 */ 829 | /***/ function(module, exports, __webpack_require__) { 830 | 831 | 'use strict'; 832 | 833 | exports.__esModule = true; 834 | exports["default"] = undefined; 835 | exports.shallowCompare = shallowCompare; 836 | 837 | var _react = __webpack_require__(3); 838 | 839 | var _react2 = _interopRequireDefault(_react); 840 | 841 | var _shallowEqual = __webpack_require__(8); 842 | 843 | var _shallowEqual2 = _interopRequireDefault(_shallowEqual); 844 | 845 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 846 | 847 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 848 | 849 | function _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; } 850 | 851 | function _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; } 852 | 853 | function shallowCompare(component, nextProps, nextState) { 854 | return !(0, _shallowEqual2["default"])(component.props, nextProps) || !(0, _shallowEqual2["default"])(component.state, nextState); 855 | } 856 | 857 | /** 858 | * React组件基础类, 浅层检查props和state是否更改, 未更改则不重新渲染 859 | * 注意: 在不使用immutable.js作为数据源格式时, 请确保浅层检查不会阻止渲染! 860 | */ 861 | 862 | var PureRenderComponent = function (_React$Component) { 863 | _inherits(PureRenderComponent, _React$Component); 864 | 865 | function PureRenderComponent() { 866 | _classCallCheck(this, PureRenderComponent); 867 | 868 | return _possibleConstructorReturn(this, _React$Component.apply(this, arguments)); 869 | } 870 | 871 | PureRenderComponent.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) { 872 | var isOk = shallowCompare(this, nextProps, nextState); 873 | //console.log('shallowCompare',isOk) 874 | return isOk; 875 | }; 876 | 877 | return PureRenderComponent; 878 | }(_react2["default"].Component); 879 | 880 | exports["default"] = PureRenderComponent; 881 | 882 | /***/ }, 883 | /* 16 */ 884 | /***/ function(module, exports, __webpack_require__) { 885 | 886 | 'use strict'; 887 | 888 | exports.__esModule = true; 889 | 890 | var _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; }; 891 | 892 | exports["default"] = connect; 893 | 894 | var _react = __webpack_require__(3); 895 | 896 | var _storeShape = __webpack_require__(9); 897 | 898 | var _storeShape2 = _interopRequireDefault(_storeShape); 899 | 900 | var _shallowEqual = __webpack_require__(8); 901 | 902 | var _shallowEqual2 = _interopRequireDefault(_shallowEqual); 903 | 904 | var _wrapActionCreators = __webpack_require__(23); 905 | 906 | var _wrapActionCreators2 = _interopRequireDefault(_wrapActionCreators); 907 | 908 | var _warning = __webpack_require__(2); 909 | 910 | var _warning2 = _interopRequireDefault(_warning); 911 | 912 | var _isPlainObject = __webpack_require__(6); 913 | 914 | var _isPlainObject2 = _interopRequireDefault(_isPlainObject); 915 | 916 | var _hoistNonReactStatics = __webpack_require__(22); 917 | 918 | var _hoistNonReactStatics2 = _interopRequireDefault(_hoistNonReactStatics); 919 | 920 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 921 | 922 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 923 | 924 | function _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; } 925 | 926 | function _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; } 927 | 928 | var defaultMapStateToProps = function defaultMapStateToProps(state) { 929 | return {}; 930 | }; // eslint-disable-line no-unused-vars 931 | var defaultMapDispatchToProps = function defaultMapDispatchToProps(dispatch) { 932 | return { dispatch: dispatch }; 933 | }; 934 | var defaultMergeProps = function defaultMergeProps(stateProps, dispatchProps, parentProps) { 935 | return _extends({}, parentProps, stateProps, dispatchProps); 936 | }; 937 | 938 | function getDisplayName(WrappedComponent) { 939 | return WrappedComponent.displayName || WrappedComponent.name || 'Component'; 940 | } 941 | 942 | var errorObject = { value: null }; 943 | function tryCatch(fn, ctx) { 944 | try { 945 | return fn.apply(ctx); 946 | } catch (e) { 947 | errorObject.value = e; 948 | return errorObject; 949 | } 950 | } 951 | 952 | // Helps track hot reloading. 953 | var nextVersion = 0; 954 | 955 | function connect(mapStateToProps, mapDispatchToProps, mergeProps) { 956 | var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; 957 | 958 | var shouldSubscribe = Boolean(mapStateToProps); 959 | var mapState = mapStateToProps || defaultMapStateToProps; 960 | 961 | var mapDispatch = void 0; 962 | if (typeof mapDispatchToProps === 'function') { 963 | mapDispatch = mapDispatchToProps; 964 | } else if (!mapDispatchToProps) { 965 | mapDispatch = defaultMapDispatchToProps; 966 | } else { 967 | mapDispatch = (0, _wrapActionCreators2["default"])(mapDispatchToProps); 968 | } 969 | 970 | var finalMergeProps = mergeProps || defaultMergeProps; 971 | var _options$pure = options.pure, 972 | pure = _options$pure === undefined ? true : _options$pure, 973 | _options$withRef = options.withRef, 974 | withRef = _options$withRef === undefined ? false : _options$withRef; 975 | 976 | var checkMergedEquals = pure && finalMergeProps !== defaultMergeProps; 977 | 978 | // Helps track hot reloading. 979 | var version = nextVersion++; 980 | 981 | return function wrapWithConnect(WrappedComponent) { 982 | var connectDisplayName = 'Connect(' + getDisplayName(WrappedComponent) + ')'; 983 | 984 | function checkStateShape(props, methodName) { 985 | if (!(0, _isPlainObject2["default"])(props)) { 986 | (0, _warning2["default"])(methodName + '() in ' + connectDisplayName + ' must return a plain object. ' + ('Instead received ' + props + '.')); 987 | } 988 | } 989 | 990 | function computeMergedProps(stateProps, dispatchProps, parentProps) { 991 | var mergedProps = finalMergeProps(stateProps, dispatchProps, parentProps); 992 | if (true) { 993 | checkStateShape(mergedProps, 'mergeProps'); 994 | } 995 | return mergedProps; 996 | } 997 | 998 | var Connect = function (_Component) { 999 | _inherits(Connect, _Component); 1000 | 1001 | Connect.prototype.shouldComponentUpdate = function shouldComponentUpdate() { 1002 | return !pure || this.haveOwnPropsChanged || this.hasStoreStateChanged; 1003 | }; 1004 | 1005 | function Connect(props, context) { 1006 | _classCallCheck(this, Connect); 1007 | 1008 | var _this = _possibleConstructorReturn(this, _Component.call(this, props, context)); 1009 | 1010 | _this.version = version; 1011 | _this.store = props.store || context.store; 1012 | 1013 | if (!_this.store) { 1014 | var str = 'Could not find "store" in either the context or ' + ('props of "' + connectDisplayName + '". ') + 'Either wrap the root component in a , ' + ('or explicitly pass "store" as a prop to "' + connectDisplayName + '".'); 1015 | console.log(str); 1016 | } 1017 | 1018 | var storeState = _this.store.getState(); 1019 | _this.state = { storeState: storeState }; 1020 | _this.clearCache(); 1021 | return _this; 1022 | } 1023 | 1024 | Connect.prototype.computeStateProps = function computeStateProps(store, props) { 1025 | if (!this.finalMapStateToProps) { 1026 | return this.configureFinalMapState(store, props); 1027 | } 1028 | 1029 | var state = store.getState(); 1030 | var stateProps = this.doStatePropsDependOnOwnProps ? this.finalMapStateToProps(state, props) : this.finalMapStateToProps(state); 1031 | 1032 | if (true) { 1033 | checkStateShape(stateProps, 'mapStateToProps'); 1034 | } 1035 | return stateProps; 1036 | }; 1037 | 1038 | Connect.prototype.configureFinalMapState = function configureFinalMapState(store, props) { 1039 | var mappedState = mapState(store.getState(), props); 1040 | var isFactory = typeof mappedState === 'function'; 1041 | 1042 | this.finalMapStateToProps = isFactory ? mappedState : mapState; 1043 | this.doStatePropsDependOnOwnProps = this.finalMapStateToProps.length !== 1; 1044 | 1045 | if (isFactory) { 1046 | return this.computeStateProps(store, props); 1047 | } 1048 | 1049 | if (true) { 1050 | checkStateShape(mappedState, 'mapStateToProps'); 1051 | } 1052 | return mappedState; 1053 | }; 1054 | 1055 | Connect.prototype.computeDispatchProps = function computeDispatchProps(store, props) { 1056 | if (!this.finalMapDispatchToProps) { 1057 | return this.configureFinalMapDispatch(store, props); 1058 | } 1059 | 1060 | var dispatch = store.dispatch; 1061 | 1062 | var dispatchProps = this.doDispatchPropsDependOnOwnProps ? this.finalMapDispatchToProps(dispatch, props) : this.finalMapDispatchToProps(dispatch); 1063 | 1064 | if (true) { 1065 | checkStateShape(dispatchProps, 'mapDispatchToProps'); 1066 | } 1067 | return dispatchProps; 1068 | }; 1069 | 1070 | Connect.prototype.configureFinalMapDispatch = function configureFinalMapDispatch(store, props) { 1071 | var mappedDispatch = mapDispatch(store.dispatch, props); 1072 | var isFactory = typeof mappedDispatch === 'function'; 1073 | 1074 | this.finalMapDispatchToProps = isFactory ? mappedDispatch : mapDispatch; 1075 | this.doDispatchPropsDependOnOwnProps = this.finalMapDispatchToProps.length !== 1; 1076 | 1077 | if (isFactory) { 1078 | return this.computeDispatchProps(store, props); 1079 | } 1080 | 1081 | if (true) { 1082 | checkStateShape(mappedDispatch, 'mapDispatchToProps'); 1083 | } 1084 | return mappedDispatch; 1085 | }; 1086 | 1087 | Connect.prototype.updateStatePropsIfNeeded = function updateStatePropsIfNeeded() { 1088 | var nextStateProps = this.computeStateProps(this.store, this.props); 1089 | if (this.stateProps && (0, _shallowEqual2["default"])(nextStateProps, this.stateProps)) { 1090 | return false; 1091 | } 1092 | 1093 | this.stateProps = nextStateProps; 1094 | return true; 1095 | }; 1096 | 1097 | Connect.prototype.updateDispatchPropsIfNeeded = function updateDispatchPropsIfNeeded() { 1098 | var nextDispatchProps = this.computeDispatchProps(this.store, this.props); 1099 | if (this.dispatchProps && (0, _shallowEqual2["default"])(nextDispatchProps, this.dispatchProps)) { 1100 | return false; 1101 | } 1102 | 1103 | this.dispatchProps = nextDispatchProps; 1104 | return true; 1105 | }; 1106 | 1107 | Connect.prototype.updateMergedPropsIfNeeded = function updateMergedPropsIfNeeded() { 1108 | var nextMergedProps = computeMergedProps(this.stateProps, this.dispatchProps, this.props); 1109 | if (this.mergedProps && checkMergedEquals && (0, _shallowEqual2["default"])(nextMergedProps, this.mergedProps)) { 1110 | return false; 1111 | } 1112 | 1113 | this.mergedProps = nextMergedProps; 1114 | return true; 1115 | }; 1116 | 1117 | Connect.prototype.isSubscribed = function isSubscribed() { 1118 | return typeof this.unsubscribe === 'function'; 1119 | }; 1120 | 1121 | Connect.prototype.trySubscribe = function trySubscribe() { 1122 | if (shouldSubscribe && !this.unsubscribe) { 1123 | this.unsubscribe = this.store.subscribe(this.handleChange.bind(this)); 1124 | this.handleChange(); 1125 | } 1126 | }; 1127 | 1128 | Connect.prototype.tryUnsubscribe = function tryUnsubscribe() { 1129 | if (this.unsubscribe) { 1130 | this.unsubscribe(); 1131 | this.unsubscribe = null; 1132 | } 1133 | }; 1134 | 1135 | Connect.prototype.componentDidMount = function componentDidMount() { 1136 | this.trySubscribe(); 1137 | }; 1138 | 1139 | Connect.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { 1140 | if (!pure || !(0, _shallowEqual2["default"])(nextProps, this.props)) { 1141 | this.haveOwnPropsChanged = true; 1142 | } 1143 | }; 1144 | 1145 | Connect.prototype.componentWillUnmount = function componentWillUnmount() { 1146 | this.tryUnsubscribe(); 1147 | this.clearCache(); 1148 | }; 1149 | 1150 | Connect.prototype.clearCache = function clearCache() { 1151 | this.dispatchProps = null; 1152 | this.stateProps = null; 1153 | this.mergedProps = null; 1154 | this.haveOwnPropsChanged = true; 1155 | this.hasStoreStateChanged = true; 1156 | this.haveStatePropsBeenPrecalculated = false; 1157 | this.statePropsPrecalculationError = null; 1158 | this.renderedElement = null; 1159 | this.finalMapDispatchToProps = null; 1160 | this.finalMapStateToProps = null; 1161 | }; 1162 | 1163 | Connect.prototype.handleChange = function handleChange() { 1164 | if (!this.unsubscribe) { 1165 | return; 1166 | } 1167 | 1168 | var storeState = this.store.getState(); 1169 | var prevStoreState = this.state.storeState; 1170 | if (pure && prevStoreState === storeState) { 1171 | return; 1172 | } 1173 | 1174 | if (pure && !this.doStatePropsDependOnOwnProps) { 1175 | var haveStatePropsChanged = tryCatch(this.updateStatePropsIfNeeded, this); 1176 | if (!haveStatePropsChanged) { 1177 | return; 1178 | } 1179 | if (haveStatePropsChanged === errorObject) { 1180 | this.statePropsPrecalculationError = errorObject.value; 1181 | } 1182 | this.haveStatePropsBeenPrecalculated = true; 1183 | } 1184 | 1185 | this.hasStoreStateChanged = true; 1186 | this.setState({ storeState: storeState }); 1187 | }; 1188 | 1189 | Connect.prototype.getWrappedInstance = function getWrappedInstance() { 1190 | return this.refs.wrappedInstance; 1191 | }; 1192 | 1193 | Connect.prototype.render = function render() { 1194 | var haveOwnPropsChanged = this.haveOwnPropsChanged, 1195 | hasStoreStateChanged = this.hasStoreStateChanged, 1196 | haveStatePropsBeenPrecalculated = this.haveStatePropsBeenPrecalculated, 1197 | statePropsPrecalculationError = this.statePropsPrecalculationError, 1198 | renderedElement = this.renderedElement; 1199 | 1200 | 1201 | this.haveOwnPropsChanged = false; 1202 | this.hasStoreStateChanged = false; 1203 | this.haveStatePropsBeenPrecalculated = false; 1204 | this.statePropsPrecalculationError = null; 1205 | 1206 | if (statePropsPrecalculationError) { 1207 | throw statePropsPrecalculationError; 1208 | } 1209 | 1210 | var shouldUpdateStateProps = true; 1211 | var shouldUpdateDispatchProps = true; 1212 | if (pure && renderedElement) { 1213 | shouldUpdateStateProps = hasStoreStateChanged || haveOwnPropsChanged && this.doStatePropsDependOnOwnProps; 1214 | shouldUpdateDispatchProps = haveOwnPropsChanged && this.doDispatchPropsDependOnOwnProps; 1215 | } 1216 | 1217 | var haveStatePropsChanged = false; 1218 | var haveDispatchPropsChanged = false; 1219 | if (haveStatePropsBeenPrecalculated) { 1220 | haveStatePropsChanged = true; 1221 | } else if (shouldUpdateStateProps) { 1222 | haveStatePropsChanged = this.updateStatePropsIfNeeded(); 1223 | } 1224 | if (shouldUpdateDispatchProps) { 1225 | haveDispatchPropsChanged = this.updateDispatchPropsIfNeeded(); 1226 | } 1227 | 1228 | var haveMergedPropsChanged = true; 1229 | if (haveStatePropsChanged || haveDispatchPropsChanged || haveOwnPropsChanged) { 1230 | haveMergedPropsChanged = this.updateMergedPropsIfNeeded(); 1231 | } else { 1232 | haveMergedPropsChanged = false; 1233 | } 1234 | 1235 | if (!haveMergedPropsChanged && renderedElement) { 1236 | return renderedElement; 1237 | } 1238 | 1239 | if (withRef) { 1240 | this.renderedElement = (0, _react.createElement)(WrappedComponent, _extends({}, this.mergedProps, { 1241 | ref: 'wrappedInstance' 1242 | })); 1243 | } else { 1244 | this.renderedElement = (0, _react.createElement)(WrappedComponent, this.mergedProps); 1245 | } 1246 | 1247 | return this.renderedElement; 1248 | }; 1249 | 1250 | return Connect; 1251 | }(_react.Component); 1252 | 1253 | Connect.displayName = connectDisplayName; 1254 | Connect.WrappedComponent = WrappedComponent; 1255 | Connect.contextTypes = { 1256 | store: _storeShape2["default"] 1257 | }; 1258 | Connect.propTypes = { 1259 | store: _storeShape2["default"] 1260 | }; 1261 | 1262 | if (true) { 1263 | Connect.prototype.componentWillUpdate = function componentWillUpdate() { 1264 | if (this.version === version) { 1265 | return; 1266 | } 1267 | 1268 | // We are hot reloading! 1269 | this.version = version; 1270 | this.trySubscribe(); 1271 | this.clearCache(); 1272 | }; 1273 | } 1274 | 1275 | return (0, _hoistNonReactStatics2["default"])(Connect, WrappedComponent); 1276 | }; 1277 | } 1278 | 1279 | /***/ }, 1280 | /* 17 */ 1281 | /***/ function(module, exports, __webpack_require__) { 1282 | 1283 | 'use strict'; 1284 | 1285 | exports.__esModule = true; 1286 | exports["default"] = createActions; 1287 | 1288 | var _objectForEach = __webpack_require__(1); 1289 | 1290 | var _objectForEach2 = _interopRequireDefault(_objectForEach); 1291 | 1292 | var _isPromise = __webpack_require__(5); 1293 | 1294 | var _isPromise2 = _interopRequireDefault(_isPromise); 1295 | 1296 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 1297 | 1298 | /** 1299 | * action函数的一个空实现 1300 | */ 1301 | function nullActionImpl() { 1302 | return null; 1303 | } 1304 | 1305 | function createActionImplWrapper(actionImpl, key, actionsConfig) { 1306 | //ActionImplWrapper 1307 | //这是真正被调用的action函数 1308 | return function (group, args) { 1309 | //var args = [].concat(arguments); 1310 | var actionResult = actionImpl.apply(actionsConfig, args); 1311 | 1312 | var promise = null; 1313 | var payload = null; 1314 | if ((0, _isPromise2["default"])(actionResult)) { 1315 | promise = actionResult; 1316 | } else { 1317 | payload = actionResult; 1318 | } 1319 | 1320 | return { 1321 | type: group + "_" + key, 1322 | group: group, //例如:user或post,是在createConfigure中配置的..这个玩意只有完成createConfigure之后才能知道,所以需要从参数中传过来 1323 | name: key, //例如:getUserList 1324 | status: "unknown", //pending,error,success 1325 | args: args, 1326 | promise: promise, 1327 | payload: payload 1328 | }; 1329 | }; 1330 | } 1331 | 1332 | function createActions(actionsConfig) { 1333 | var actions = {}; 1334 | 1335 | (0, _objectForEach2["default"])(actionsConfig, function (key, actionImpl) { 1336 | 1337 | //空Action 1338 | if (!actionImpl) { 1339 | actionImpl = nullActionImpl; 1340 | } 1341 | 1342 | //这是真正被调用的action函数 1343 | actions[key] = createActionImplWrapper(actionImpl, key, actionsConfig); 1344 | }); 1345 | 1346 | return actions; 1347 | } 1348 | 1349 | /***/ }, 1350 | /* 18 */ 1351 | /***/ function(module, exports, __webpack_require__) { 1352 | 1353 | 'use strict'; 1354 | 1355 | exports.__esModule = true; 1356 | exports["default"] = createComponent; 1357 | 1358 | var _redux = __webpack_require__(7); 1359 | 1360 | var _connect = __webpack_require__(16); 1361 | 1362 | var _connect2 = _interopRequireDefault(_connect); 1363 | 1364 | var _functions = __webpack_require__(4); 1365 | 1366 | var _objectForEach = __webpack_require__(1); 1367 | 1368 | var _objectForEach2 = _interopRequireDefault(_objectForEach); 1369 | 1370 | var _warning = __webpack_require__(2); 1371 | 1372 | var _warning2 = _interopRequireDefault(_warning); 1373 | 1374 | var _isPromise = __webpack_require__(5); 1375 | 1376 | var _isPromise2 = _interopRequireDefault(_isPromise); 1377 | 1378 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 1379 | 1380 | var _undefined = undefined; 1381 | 1382 | function createConfiguredActionWrapper(actionWrapper, path) { 1383 | 1384 | //actionGroup 其实就是在createConfigure中定义的action的key 1385 | //例如在example中将得到config/reubibiConfigure中配置的 'user'或'post' 1386 | var actionGroup = path.split('.')[0]; 1387 | 1388 | //这才是真正调用的函数 1389 | return function () { 1390 | var args = (0, _functions.toArray)(arguments); 1391 | //@see createAction ActionImplWrapper 1392 | var action = actionWrapper(actionGroup, args); 1393 | //{group,name,status,args,payload} 1394 | return action; 1395 | }; 1396 | } 1397 | 1398 | function getActionsFromConfig(reubibiConfigure, componentConfig) { 1399 | var actionsResult = {}; 1400 | if (!componentConfig || !reubibiConfigure) { 1401 | return null; 1402 | } 1403 | 1404 | var actionsConfig = componentConfig.actions || {}; 1405 | var allActions = reubibiConfigure.getActions(); 1406 | 1407 | (0, _objectForEach2["default"])(actionsConfig, function (key, path) { 1408 | var actionWrapper = (0, _functions.getValueInPath)(allActions, path || ''); 1409 | if (actionWrapper === _undefined) { 1410 | (0, _warning2["default"])('[ERROR]cannot get Object by key : ' + key + ' and path: ' + path + ' '); 1411 | } else { 1412 | actionsResult[key] = createConfiguredActionWrapper(actionWrapper, path); 1413 | } 1414 | }); 1415 | 1416 | return actionsResult; 1417 | } 1418 | 1419 | function createPromiseActionFunc(actionFunc) { 1420 | return function () { 1421 | var args = (0, _functions.toArray)(arguments); 1422 | var actionResult = actionFunc.apply({}, args); 1423 | if (actionResult) { 1424 | if ((0, _isPromise2["default"])(actionResult.promise)) { 1425 | return actionResult.promise; 1426 | } 1427 | return actionResult.payload; 1428 | } 1429 | return null; 1430 | }; 1431 | } 1432 | 1433 | function bindActionPromise(actionFunctions) { 1434 | var promiseActions = {}; 1435 | (0, _objectForEach2["default"])(actionFunctions, function (key, actionFunc) { 1436 | promiseActions[key] = createPromiseActionFunc(actionFunc); 1437 | }); 1438 | return promiseActions; 1439 | } 1440 | 1441 | function getStateByConfig(state, componentConfig) { 1442 | var result = {}; 1443 | if (!componentConfig || !state) { 1444 | return null; 1445 | } 1446 | 1447 | var propsConfig = componentConfig.props || {}; 1448 | 1449 | (0, _objectForEach2["default"])(propsConfig, function (key, pathOrFunc) { 1450 | 1451 | if ((0, _functions.isFunction)(pathOrFunc)) { 1452 | result[key] = pathOrFunc(state); 1453 | } else if ((0, _functions.isString)(pathOrFunc)) { 1454 | result[key] = (0, _functions.getValueInPath)(state, pathOrFunc || ''); 1455 | } 1456 | 1457 | if (result[key] === _undefined) { 1458 | (0, _warning2["default"])('[ERROR]cannot get Object by key : ' + key + ' and path: ' + pathOrFunc + ' '); 1459 | } 1460 | }); 1461 | 1462 | return result; 1463 | } 1464 | 1465 | /** 1466 | * 1467 | * @param reubibiConfigure 是一个Reubibi.createConfigure对象. 1468 | * @param BaseComponentImpl React组件对象 1469 | * @param componentConfig 组件的配置 形如: 1470 | * 1471 | * componentConfig = { 1472 | * 1473 | * actions: { 1474 | * getUserList: 'user.getUserList' 1475 | * }, 1476 | * 1477 | * props: { 1478 | * userList: 'user.userList' 1479 | * } 1480 | * 1481 | * } 1482 | */ 1483 | function createComponent(reubibiConfigure, BaseComponentImpl, componentConfig) { 1484 | 1485 | function mapStateToProps(state) { 1486 | var props = getStateByConfig(state, componentConfig); 1487 | return props; 1488 | } 1489 | 1490 | function mapDispatchToProps(dispatch) { 1491 | //每次数据变化时,不会执行此处代码 1492 | var actions = getActionsFromConfig(reubibiConfigure, componentConfig); //这里的action执行后返回{group,name,status,args,payload} 1493 | var actionDefs = (0, _redux.bindActionCreators)(actions, dispatch); //这里的action执行后返回 1494 | var actionPromise = bindActionPromise(actionDefs); 1495 | return { actions: actionPromise }; 1496 | } 1497 | 1498 | return (0, _connect2["default"])(mapStateToProps, mapDispatchToProps)(BaseComponentImpl); 1499 | } 1500 | 1501 | /***/ }, 1502 | /* 19 */ 1503 | /***/ function(module, exports, __webpack_require__) { 1504 | 1505 | 'use strict'; 1506 | 1507 | exports.__esModule = true; 1508 | exports["default"] = createConfigure; 1509 | 1510 | var _redux = __webpack_require__(7); 1511 | 1512 | var _promiseMiddleware = __webpack_require__(21); 1513 | 1514 | var _promiseMiddleware2 = _interopRequireDefault(_promiseMiddleware); 1515 | 1516 | var _functions = __webpack_require__(4); 1517 | 1518 | var _objectForEach = __webpack_require__(1); 1519 | 1520 | var _objectForEach2 = _interopRequireDefault(_objectForEach); 1521 | 1522 | var _warning = __webpack_require__(2); 1523 | 1524 | var _warning2 = _interopRequireDefault(_warning); 1525 | 1526 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 1527 | 1528 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 1529 | 1530 | var getCombineReducers = function getCombineReducers(config) { 1531 | /** 1532 | * { 1533 | * $$state:{}, 1534 | * $$reducer: function(){}, 1535 | * getUserList: function(){}, 1536 | * getUserInfo(): function(){}, 1537 | * moreGetter.... 1538 | * } 1539 | */ 1540 | var storesMap = config.stores || {}; 1541 | var reducerMap = {}; 1542 | for (var i in storesMap) { 1543 | if (storesMap.hasOwnProperty(i)) { 1544 | var v = storesMap[i]; 1545 | //这是在createStore方法中定义的,就一个函数. 1546 | var reducer = v['$$reducer']; //是一个function 1547 | reducerMap[i] = reducer; 1548 | } 1549 | } 1550 | 1551 | /** 1552 | * 在这里定义的数据结构最终保证了store中的数据结构 1553 | * { 1554 | * user:function(){}, 1555 | * post:function(){} 1556 | * } 1557 | */ 1558 | return (0, _redux.combineReducers)(reducerMap); 1559 | }; 1560 | 1561 | /** 1562 | * /Reubibi.createConfigure 配置后UserStore实例中能够获取自己的配置信息 1563 | * @param config 1564 | */ 1565 | function setStoreGroupName(config) { 1566 | var storesConfig = config.stores; //Reubibi.createConfigure 1567 | if (storesConfig) { 1568 | //UserStore只是一个示例 1569 | (0, _objectForEach2["default"])(storesConfig, function (key, UserStore) { 1570 | UserStore['$$StoreGroupName'] = key; 1571 | }); 1572 | } 1573 | } 1574 | 1575 | function replacePromiseMiddleware(middlewareArray) { 1576 | 1577 | var middlewareArray1 = []; 1578 | var isHasPromiseMiddleware = false; 1579 | for (var i = 0; i < middlewareArray.length; i++) { 1580 | var m = middlewareArray[i]; 1581 | if (m === 'promiseMiddleware') { 1582 | middlewareArray1.push(_promiseMiddleware2["default"]); 1583 | isHasPromiseMiddleware = true; 1584 | } else if ((0, _functions.isFunction)(m)) { 1585 | middlewareArray1.push(m); 1586 | } else { 1587 | throw new Error(m + ' is not a middleware'); 1588 | } 1589 | } 1590 | 1591 | if (!isHasPromiseMiddleware) { 1592 | (0, _warning2["default"])('Must has a promiseMiddleware,please check createConfigure'); 1593 | } 1594 | 1595 | return middlewareArray1; 1596 | } 1597 | 1598 | function toCreateStoreWithMiddleware(middlewareArray) { 1599 | var func = null; 1600 | if (middlewareArray && middlewareArray.length > 0) { 1601 | middlewareArray = replacePromiseMiddleware(middlewareArray); 1602 | func = _redux.applyMiddleware.apply({}, middlewareArray); 1603 | } else { 1604 | func = (0, _redux.applyMiddleware)(_promiseMiddleware2["default"]); 1605 | } 1606 | return func(_redux.createStore); 1607 | } 1608 | 1609 | var ReubibiConfig = function () { 1610 | 1611 | /** 1612 | * 1613 | * actions: { 1614 | * user: userActions, 1615 | * post: postActions 1616 | * }, 1617 | * stores: { 1618 | * user: UserStore, 1619 | * post: PostStore 1620 | * } 1621 | * 1622 | */ 1623 | function ReubibiConfig(config) { 1624 | _classCallCheck(this, ReubibiConfig); 1625 | 1626 | setStoreGroupName(config); 1627 | this.config = config; 1628 | var initialState = config.initialState; 1629 | var middleware = config.middleware; 1630 | var reducer = getCombineReducers(config); 1631 | var createStoreWithMiddleware = toCreateStoreWithMiddleware(middleware); 1632 | if (initialState) { 1633 | //唯一的一个store 1634 | this.store = createStoreWithMiddleware(reducer, initialState); 1635 | } else { 1636 | //唯一的一个store 1637 | this.store = createStoreWithMiddleware(reducer); 1638 | } 1639 | } 1640 | 1641 | ReubibiConfig.prototype.getStore = function getStore() { 1642 | return this.store; 1643 | }; 1644 | 1645 | ReubibiConfig.prototype.getActions = function getActions() { 1646 | return this.config.actions; 1647 | }; 1648 | 1649 | return ReubibiConfig; 1650 | }(); 1651 | 1652 | function createConfigure(config) { 1653 | return new ReubibiConfig(config); 1654 | } 1655 | 1656 | /***/ }, 1657 | /* 20 */ 1658 | /***/ function(module, exports, __webpack_require__) { 1659 | 1660 | 'use strict'; 1661 | 1662 | exports.__esModule = true; 1663 | exports["default"] = createStore; 1664 | 1665 | var _objectForEach = __webpack_require__(1); 1666 | 1667 | var _objectForEach2 = _interopRequireDefault(_objectForEach); 1668 | 1669 | var _warning = __webpack_require__(2); 1670 | 1671 | var _warning2 = _interopRequireDefault(_warning); 1672 | 1673 | var _functions = __webpack_require__(4); 1674 | 1675 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 1676 | 1677 | function toFirstCharUpper(str) { 1678 | return str.replace(/(^|\s+)\w/g, function (s) { 1679 | return s.toUpperCase(); 1680 | }); 1681 | } 1682 | 1683 | /** 1684 | * 一个Store对一个action事件只能有一个响应函数 1685 | * @param actionName 1686 | * @param actionGroup 1687 | * @param storeConfig 1688 | * @param storeGroupName 1689 | */ 1690 | function getReducer(actionName, actionGroup, storeConfig, storeGroupName) { 1691 | if (!actionName) { 1692 | return null; 1693 | } 1694 | 1695 | //形如:onGetUserList 1696 | var reducerReceiveName = "on" + toFirstCharUpper(actionName); 1697 | if (actionGroup === storeGroupName) { 1698 | var reducer = storeConfig[reducerReceiveName]; 1699 | if (reducer) { 1700 | return reducer; 1701 | } 1702 | } 1703 | 1704 | //形如:post#onGetPostList 1705 | var reducerReceiveName2 = actionGroup + "#" + reducerReceiveName; 1706 | reducer = storeConfig[reducerReceiveName2]; 1707 | if (reducer) { 1708 | return reducer; 1709 | } 1710 | 1711 | return null; 1712 | } 1713 | 1714 | /** 1715 | * 1716 | * @param state 1717 | * @param action 形如: {group,name,status,args,payload} 1718 | * @param storeConfig 1719 | * @param storeGroupName 形如:user,post 1720 | */ 1721 | function reduceAction(state, action, storeConfig, storeGroupName) { 1722 | var actionName = action.name; 1723 | var actionGroup = action.group; 1724 | var reducer = getReducer(actionName, actionGroup, storeConfig, storeGroupName); 1725 | if (reducer) { 1726 | 1727 | var state0 = reducer(state, action); 1728 | if (state0) { 1729 | return state0; 1730 | } else { 1731 | //如果reducer没有正确返回,做一下兼容 1732 | (0, _warning2["default"])('[ERROR] error store config:' + actionGroup + '#' + actionName); 1733 | } 1734 | } 1735 | return state; 1736 | } 1737 | 1738 | /** 1739 | * 创建一个真正执行的时候调用的Get函数 1740 | * @param getterDef 用户配置的以get开否的函数实现 1741 | * @param exportStore 1742 | * @returns {Function} 1743 | */ 1744 | function createGetterFunction(getterDef, exportStore) { 1745 | return function () { 1746 | var args0 = (0, _functions.toArray)(arguments); 1747 | //每次执行,都是获取最新的state 1748 | var state = exportStore['$$state']; 1749 | var args = [state].concat(args0); 1750 | return getterDef.apply({}, args); 1751 | }; 1752 | } 1753 | 1754 | /** 1755 | * 对于以get开头的配置,创建get函数 1756 | * @param exportStore 1757 | * @param storeConfig 形如: {onGetXXX,onGetYYY,getXXX,getYYY} 1758 | */ 1759 | function createGetter(exportStore, storeConfig) { 1760 | (0, _objectForEach2["default"])(storeConfig, function (key, handler) { 1761 | if (key.indexOf('get') === 0 && (0, _functions.isFunction)(handler)) { 1762 | exportStore[key] = createGetterFunction(handler, exportStore); 1763 | } 1764 | }); 1765 | } 1766 | 1767 | /** 1768 | * 以$$开头的都是框架内部的变量,禁止业务层访问. 1769 | */ 1770 | function createStore(storeConfig) { 1771 | 1772 | var initialState = storeConfig.initialState || {}; 1773 | 1774 | //这才是真正对外暴露的Store对象 1775 | var exportStore = {}; 1776 | 1777 | //1.创建的reducer函数 1778 | var reducerFunc = function reducerFunc() { 1779 | var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState; 1780 | var action = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 1781 | 1782 | //storeGroupName真正的值是在Reubibi.createConfigure中被重新设置的. 1783 | var storeGroupName = exportStore['$$StoreGroupName']; 1784 | state = reduceAction(state, action, storeConfig, storeGroupName); 1785 | exportStore['$$state'] = state; 1786 | return state; 1787 | }; 1788 | 1789 | exportStore['$$reducer'] = reducerFunc; 1790 | 1791 | //2.$$StoreGroupName的初始化 1792 | exportStore['$$StoreGroupName'] = null; 1793 | 1794 | //3.创建Getter函数 1795 | createGetter(exportStore, storeConfig); 1796 | 1797 | return exportStore; 1798 | } 1799 | 1800 | /***/ }, 1801 | /* 21 */ 1802 | /***/ function(module, exports, __webpack_require__) { 1803 | 1804 | 'use strict'; 1805 | 1806 | exports.__esModule = true; 1807 | exports["default"] = promiseMiddleware; 1808 | 1809 | var _isPromise = __webpack_require__(5); 1810 | 1811 | var _isPromise2 = _interopRequireDefault(_isPromise); 1812 | 1813 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 1814 | 1815 | function promiseMiddleware(_ref) { 1816 | 1817 | var dispatch = _ref.dispatch; 1818 | 1819 | return function (next) { 1820 | return function (action) { 1821 | 1822 | if (!(0, _isPromise2["default"])(action.promise)) { 1823 | action.status = 'success'; 1824 | return next(action); 1825 | } 1826 | 1827 | var type = action.type, 1828 | group = action.group, 1829 | name = action.name, 1830 | status = action.status, 1831 | args = action.args, 1832 | payload = action.payload, 1833 | promise = action.promise; 1834 | 1835 | 1836 | var createAction = function createAction(status1, promise1, payload1) { 1837 | return { 1838 | type: type, 1839 | group: group, 1840 | name: name, 1841 | status: status1, 1842 | args: args, 1843 | promise: promise1, 1844 | payload: payload1 //object or promise 1845 | }; 1846 | }; 1847 | 1848 | promise = promise.then(function () { 1849 | var resolved = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 1850 | 1851 | var successAction = createAction('success', null, resolved); 1852 | return dispatch(successAction); 1853 | }, function () { 1854 | var rejected = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 1855 | 1856 | var errorAction = createAction('error', null, rejected); 1857 | return dispatch(errorAction); 1858 | }); 1859 | 1860 | var pendingAction = createAction('pending', promise, null); 1861 | return next(pendingAction); 1862 | }; 1863 | }; 1864 | } 1865 | 1866 | /***/ }, 1867 | /* 22 */ 1868 | /***/ function(module, exports) { 1869 | 1870 | /** 1871 | * Copyright 2015, Yahoo! Inc. 1872 | * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. 1873 | */ 1874 | 'use strict'; 1875 | 1876 | var REACT_STATICS = { 1877 | childContextTypes: true, 1878 | contextTypes: true, 1879 | defaultProps: true, 1880 | displayName: true, 1881 | getDefaultProps: true, 1882 | mixins: true, 1883 | propTypes: true, 1884 | type: true 1885 | }; 1886 | 1887 | var KNOWN_STATICS = { 1888 | name: true, 1889 | length: true, 1890 | prototype: true, 1891 | caller: true, 1892 | arguments: true, 1893 | arity: true 1894 | }; 1895 | 1896 | var isGetOwnPropertySymbolsAvailable = typeof Object.getOwnPropertySymbols === 'function'; 1897 | 1898 | module.exports = function hoistNonReactStatics(targetComponent, sourceComponent, customStatics) { 1899 | if (typeof sourceComponent !== 'string') { 1900 | // don't hoist over string (html) components 1901 | var keys = Object.getOwnPropertyNames(sourceComponent); 1902 | 1903 | /* istanbul ignore else */ 1904 | if (isGetOwnPropertySymbolsAvailable) { 1905 | keys = keys.concat(Object.getOwnPropertySymbols(sourceComponent)); 1906 | } 1907 | 1908 | for (var i = 0; i < keys.length; ++i) { 1909 | if (!REACT_STATICS[keys[i]] && !KNOWN_STATICS[keys[i]] && (!customStatics || !customStatics[keys[i]])) { 1910 | try { 1911 | targetComponent[keys[i]] = sourceComponent[keys[i]]; 1912 | } catch (error) {} 1913 | } 1914 | } 1915 | } 1916 | 1917 | return targetComponent; 1918 | }; 1919 | 1920 | /***/ }, 1921 | /* 23 */ 1922 | /***/ function(module, exports, __webpack_require__) { 1923 | 1924 | 'use strict'; 1925 | 1926 | exports.__esModule = true; 1927 | exports["default"] = wrapActionCreators; 1928 | 1929 | var _redux = __webpack_require__(7); 1930 | 1931 | function wrapActionCreators(actionCreators) { 1932 | return function (dispatch) { 1933 | return (0, _redux.bindActionCreators)(actionCreators, dispatch); 1934 | }; 1935 | } 1936 | 1937 | /***/ }, 1938 | /* 24 */ 1939 | /***/ function(module, exports, __webpack_require__) { 1940 | 1941 | var Symbol = __webpack_require__(10), 1942 | getRawTag = __webpack_require__(27), 1943 | objectToString = __webpack_require__(28); 1944 | 1945 | /** `Object#toString` result references. */ 1946 | var nullTag = '[object Null]', 1947 | undefinedTag = '[object Undefined]'; 1948 | 1949 | /** Built-in value references. */ 1950 | var symToStringTag = Symbol ? Symbol.toStringTag : undefined; 1951 | 1952 | /** 1953 | * The base implementation of `getTag` without fallbacks for buggy environments. 1954 | * 1955 | * @private 1956 | * @param {*} value The value to query. 1957 | * @returns {string} Returns the `toStringTag`. 1958 | */ 1959 | function baseGetTag(value) { 1960 | if (value == null) { 1961 | return value === undefined ? undefinedTag : nullTag; 1962 | } 1963 | return (symToStringTag && symToStringTag in Object(value)) 1964 | ? getRawTag(value) 1965 | : objectToString(value); 1966 | } 1967 | 1968 | module.exports = baseGetTag; 1969 | 1970 | 1971 | /***/ }, 1972 | /* 25 */ 1973 | /***/ function(module, exports) { 1974 | 1975 | /* WEBPACK VAR INJECTION */(function(global) {/** Detect free variable `global` from Node.js. */ 1976 | var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; 1977 | 1978 | module.exports = freeGlobal; 1979 | 1980 | /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()) || Function('return this')())) 1981 | 1982 | /***/ }, 1983 | /* 26 */ 1984 | /***/ function(module, exports, __webpack_require__) { 1985 | 1986 | var overArg = __webpack_require__(29); 1987 | 1988 | /** Built-in value references. */ 1989 | var getPrototype = overArg(Object.getPrototypeOf, Object); 1990 | 1991 | module.exports = getPrototype; 1992 | 1993 | 1994 | /***/ }, 1995 | /* 27 */ 1996 | /***/ function(module, exports, __webpack_require__) { 1997 | 1998 | var Symbol = __webpack_require__(10); 1999 | 2000 | /** Used for built-in method references. */ 2001 | var objectProto = Object.prototype; 2002 | 2003 | /** Used to check objects for own properties. */ 2004 | var hasOwnProperty = objectProto.hasOwnProperty; 2005 | 2006 | /** 2007 | * Used to resolve the 2008 | * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) 2009 | * of values. 2010 | */ 2011 | var nativeObjectToString = objectProto.toString; 2012 | 2013 | /** Built-in value references. */ 2014 | var symToStringTag = Symbol ? Symbol.toStringTag : undefined; 2015 | 2016 | /** 2017 | * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. 2018 | * 2019 | * @private 2020 | * @param {*} value The value to query. 2021 | * @returns {string} Returns the raw `toStringTag`. 2022 | */ 2023 | function getRawTag(value) { 2024 | var isOwn = hasOwnProperty.call(value, symToStringTag), 2025 | tag = value[symToStringTag]; 2026 | 2027 | try { 2028 | value[symToStringTag] = undefined; 2029 | var unmasked = true; 2030 | } catch (e) {} 2031 | 2032 | var result = nativeObjectToString.call(value); 2033 | if (unmasked) { 2034 | if (isOwn) { 2035 | value[symToStringTag] = tag; 2036 | } else { 2037 | delete value[symToStringTag]; 2038 | } 2039 | } 2040 | return result; 2041 | } 2042 | 2043 | module.exports = getRawTag; 2044 | 2045 | 2046 | /***/ }, 2047 | /* 28 */ 2048 | /***/ function(module, exports) { 2049 | 2050 | /** Used for built-in method references. */ 2051 | var objectProto = Object.prototype; 2052 | 2053 | /** 2054 | * Used to resolve the 2055 | * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) 2056 | * of values. 2057 | */ 2058 | var nativeObjectToString = objectProto.toString; 2059 | 2060 | /** 2061 | * Converts `value` to a string using `Object.prototype.toString`. 2062 | * 2063 | * @private 2064 | * @param {*} value The value to convert. 2065 | * @returns {string} Returns the converted string. 2066 | */ 2067 | function objectToString(value) { 2068 | return nativeObjectToString.call(value); 2069 | } 2070 | 2071 | module.exports = objectToString; 2072 | 2073 | 2074 | /***/ }, 2075 | /* 29 */ 2076 | /***/ function(module, exports) { 2077 | 2078 | /** 2079 | * Creates a unary function that invokes `func` with its argument transformed. 2080 | * 2081 | * @private 2082 | * @param {Function} func The function to wrap. 2083 | * @param {Function} transform The argument transform. 2084 | * @returns {Function} Returns the new function. 2085 | */ 2086 | function overArg(func, transform) { 2087 | return function(arg) { 2088 | return func(transform(arg)); 2089 | }; 2090 | } 2091 | 2092 | module.exports = overArg; 2093 | 2094 | 2095 | /***/ }, 2096 | /* 30 */ 2097 | /***/ function(module, exports, __webpack_require__) { 2098 | 2099 | var freeGlobal = __webpack_require__(25); 2100 | 2101 | /** Detect free variable `self`. */ 2102 | var freeSelf = typeof self == 'object' && self && self.Object === Object && self; 2103 | 2104 | /** Used as a reference to the global object. */ 2105 | var root = freeGlobal || freeSelf || Function('return this')(); 2106 | 2107 | module.exports = root; 2108 | 2109 | 2110 | /***/ }, 2111 | /* 31 */ 2112 | /***/ function(module, exports) { 2113 | 2114 | /** 2115 | * Checks if `value` is object-like. A value is object-like if it's not `null` 2116 | * and has a `typeof` result of "object". 2117 | * 2118 | * @static 2119 | * @memberOf _ 2120 | * @since 4.0.0 2121 | * @category Lang 2122 | * @param {*} value The value to check. 2123 | * @returns {boolean} Returns `true` if `value` is object-like, else `false`. 2124 | * @example 2125 | * 2126 | * _.isObjectLike({}); 2127 | * // => true 2128 | * 2129 | * _.isObjectLike([1, 2, 3]); 2130 | * // => true 2131 | * 2132 | * _.isObjectLike(_.noop); 2133 | * // => false 2134 | * 2135 | * _.isObjectLike(null); 2136 | * // => false 2137 | */ 2138 | function isObjectLike(value) { 2139 | return value != null && typeof value == 'object'; 2140 | } 2141 | 2142 | module.exports = isObjectLike; 2143 | 2144 | 2145 | /***/ }, 2146 | /* 32 */ 2147 | /***/ function(module, exports, __webpack_require__) { 2148 | 2149 | 'use strict'; 2150 | 2151 | exports.__esModule = true; 2152 | 2153 | var _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; }; 2154 | 2155 | exports['default'] = applyMiddleware; 2156 | 2157 | var _compose = __webpack_require__(11); 2158 | 2159 | var _compose2 = _interopRequireDefault(_compose); 2160 | 2161 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2162 | 2163 | /** 2164 | * Creates a store enhancer that applies middleware to the dispatch method 2165 | * of the Redux store. This is handy for a variety of tasks, such as expressing 2166 | * asynchronous actions in a concise manner, or logging every action payload. 2167 | * 2168 | * See `redux-thunk` package as an example of the Redux middleware. 2169 | * 2170 | * Because middleware is potentially asynchronous, this should be the first 2171 | * store enhancer in the composition chain. 2172 | * 2173 | * Note that each middleware will be given the `dispatch` and `getState` functions 2174 | * as named arguments. 2175 | * 2176 | * @param {...Function} middlewares The middleware chain to be applied. 2177 | * @returns {Function} A store enhancer applying the middleware. 2178 | */ 2179 | function applyMiddleware() { 2180 | for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) { 2181 | middlewares[_key] = arguments[_key]; 2182 | } 2183 | 2184 | return function (createStore) { 2185 | return function (reducer, preloadedState, enhancer) { 2186 | var store = createStore(reducer, preloadedState, enhancer); 2187 | var _dispatch = store.dispatch; 2188 | var chain = []; 2189 | 2190 | var middlewareAPI = { 2191 | getState: store.getState, 2192 | dispatch: function dispatch(action) { 2193 | return _dispatch(action); 2194 | } 2195 | }; 2196 | chain = middlewares.map(function (middleware) { 2197 | return middleware(middlewareAPI); 2198 | }); 2199 | _dispatch = _compose2['default'].apply(undefined, chain)(store.dispatch); 2200 | 2201 | return _extends({}, store, { 2202 | dispatch: _dispatch 2203 | }); 2204 | }; 2205 | }; 2206 | } 2207 | 2208 | /***/ }, 2209 | /* 33 */ 2210 | /***/ function(module, exports) { 2211 | 2212 | 'use strict'; 2213 | 2214 | exports.__esModule = true; 2215 | exports['default'] = bindActionCreators; 2216 | function bindActionCreator(actionCreator, dispatch) { 2217 | return function () { 2218 | return dispatch(actionCreator.apply(undefined, arguments)); 2219 | }; 2220 | } 2221 | 2222 | /** 2223 | * Turns an object whose values are action creators, into an object with the 2224 | * same keys, but with every function wrapped into a `dispatch` call so they 2225 | * may be invoked directly. This is just a convenience method, as you can call 2226 | * `store.dispatch(MyActionCreators.doSomething())` yourself just fine. 2227 | * 2228 | * For convenience, you can also pass a single function as the first argument, 2229 | * and get a function in return. 2230 | * 2231 | * @param {Function|Object} actionCreators An object whose values are action 2232 | * creator functions. One handy way to obtain it is to use ES6 `import * as` 2233 | * syntax. You may also pass a single function. 2234 | * 2235 | * @param {Function} dispatch The `dispatch` function available on your Redux 2236 | * store. 2237 | * 2238 | * @returns {Function|Object} The object mimicking the original object, but with 2239 | * every action creator wrapped into the `dispatch` call. If you passed a 2240 | * function as `actionCreators`, the return value will also be a single 2241 | * function. 2242 | */ 2243 | function bindActionCreators(actionCreators, dispatch) { 2244 | if (typeof actionCreators === 'function') { 2245 | return bindActionCreator(actionCreators, dispatch); 2246 | } 2247 | 2248 | if (typeof actionCreators !== 'object' || actionCreators === null) { 2249 | throw new Error('bindActionCreators expected an object or a function, instead received ' + (actionCreators === null ? 'null' : typeof actionCreators) + '. ' + 'Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?'); 2250 | } 2251 | 2252 | var keys = Object.keys(actionCreators); 2253 | var boundActionCreators = {}; 2254 | for (var i = 0; i < keys.length; i++) { 2255 | var key = keys[i]; 2256 | var actionCreator = actionCreators[key]; 2257 | if (typeof actionCreator === 'function') { 2258 | boundActionCreators[key] = bindActionCreator(actionCreator, dispatch); 2259 | } 2260 | } 2261 | return boundActionCreators; 2262 | } 2263 | 2264 | /***/ }, 2265 | /* 34 */ 2266 | /***/ function(module, exports, __webpack_require__) { 2267 | 2268 | 'use strict'; 2269 | 2270 | exports.__esModule = true; 2271 | exports['default'] = combineReducers; 2272 | 2273 | var _createStore = __webpack_require__(12); 2274 | 2275 | var _isPlainObject = __webpack_require__(6); 2276 | 2277 | var _isPlainObject2 = _interopRequireDefault(_isPlainObject); 2278 | 2279 | var _warning = __webpack_require__(13); 2280 | 2281 | var _warning2 = _interopRequireDefault(_warning); 2282 | 2283 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2284 | 2285 | function getUndefinedStateErrorMessage(key, action) { 2286 | var actionType = action && action.type; 2287 | var actionName = actionType && '"' + actionType.toString() + '"' || 'an action'; 2288 | 2289 | return 'Given action ' + actionName + ', reducer "' + key + '" returned undefined. ' + 'To ignore an action, you must explicitly return the previous state.'; 2290 | } 2291 | 2292 | function getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) { 2293 | var reducerKeys = Object.keys(reducers); 2294 | var argumentName = action && action.type === _createStore.ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer'; 2295 | 2296 | if (reducerKeys.length === 0) { 2297 | return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.'; 2298 | } 2299 | 2300 | if (!(0, _isPlainObject2['default'])(inputState)) { 2301 | return 'The ' + argumentName + ' has unexpected type of "' + {}.toString.call(inputState).match(/\s([a-z|A-Z]+)/)[1] + '". Expected argument to be an object with the following ' + ('keys: "' + reducerKeys.join('", "') + '"'); 2302 | } 2303 | 2304 | var unexpectedKeys = Object.keys(inputState).filter(function (key) { 2305 | return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key]; 2306 | }); 2307 | 2308 | unexpectedKeys.forEach(function (key) { 2309 | unexpectedKeyCache[key] = true; 2310 | }); 2311 | 2312 | if (unexpectedKeys.length > 0) { 2313 | return 'Unexpected ' + (unexpectedKeys.length > 1 ? 'keys' : 'key') + ' ' + ('"' + unexpectedKeys.join('", "') + '" found in ' + argumentName + '. ') + 'Expected to find one of the known reducer keys instead: ' + ('"' + reducerKeys.join('", "') + '". Unexpected keys will be ignored.'); 2314 | } 2315 | } 2316 | 2317 | function assertReducerSanity(reducers) { 2318 | Object.keys(reducers).forEach(function (key) { 2319 | var reducer = reducers[key]; 2320 | var initialState = reducer(undefined, { type: _createStore.ActionTypes.INIT }); 2321 | 2322 | if (typeof initialState === 'undefined') { 2323 | throw new Error('Reducer "' + key + '" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined.'); 2324 | } 2325 | 2326 | var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math.random().toString(36).substring(7).split('').join('.'); 2327 | if (typeof reducer(undefined, { type: type }) === 'undefined') { 2328 | throw new Error('Reducer "' + key + '" returned undefined when probed with a random type. ' + ('Don\'t try to handle ' + _createStore.ActionTypes.INIT + ' or other actions in "redux/*" ') + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined.'); 2329 | } 2330 | }); 2331 | } 2332 | 2333 | /** 2334 | * Turns an object whose values are different reducer functions, into a single 2335 | * reducer function. It will call every child reducer, and gather their results 2336 | * into a single state object, whose keys correspond to the keys of the passed 2337 | * reducer functions. 2338 | * 2339 | * @param {Object} reducers An object whose values correspond to different 2340 | * reducer functions that need to be combined into one. One handy way to obtain 2341 | * it is to use ES6 `import * as reducers` syntax. The reducers may never return 2342 | * undefined for any action. Instead, they should return their initial state 2343 | * if the state passed to them was undefined, and the current state for any 2344 | * unrecognized action. 2345 | * 2346 | * @returns {Function} A reducer function that invokes every reducer inside the 2347 | * passed object, and builds a state object with the same shape. 2348 | */ 2349 | function combineReducers(reducers) { 2350 | var reducerKeys = Object.keys(reducers); 2351 | var finalReducers = {}; 2352 | for (var i = 0; i < reducerKeys.length; i++) { 2353 | var key = reducerKeys[i]; 2354 | 2355 | if (true) { 2356 | if (typeof reducers[key] === 'undefined') { 2357 | (0, _warning2['default'])('No reducer provided for key "' + key + '"'); 2358 | } 2359 | } 2360 | 2361 | if (typeof reducers[key] === 'function') { 2362 | finalReducers[key] = reducers[key]; 2363 | } 2364 | } 2365 | var finalReducerKeys = Object.keys(finalReducers); 2366 | 2367 | if (true) { 2368 | var unexpectedKeyCache = {}; 2369 | } 2370 | 2371 | var sanityError; 2372 | try { 2373 | assertReducerSanity(finalReducers); 2374 | } catch (e) { 2375 | sanityError = e; 2376 | } 2377 | 2378 | return function combination() { 2379 | var state = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 2380 | var action = arguments[1]; 2381 | 2382 | if (sanityError) { 2383 | throw sanityError; 2384 | } 2385 | 2386 | if (true) { 2387 | var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache); 2388 | if (warningMessage) { 2389 | (0, _warning2['default'])(warningMessage); 2390 | } 2391 | } 2392 | 2393 | var hasChanged = false; 2394 | var nextState = {}; 2395 | for (var i = 0; i < finalReducerKeys.length; i++) { 2396 | var key = finalReducerKeys[i]; 2397 | var reducer = finalReducers[key]; 2398 | var previousStateForKey = state[key]; 2399 | var nextStateForKey = reducer(previousStateForKey, action); 2400 | if (typeof nextStateForKey === 'undefined') { 2401 | var errorMessage = getUndefinedStateErrorMessage(key, action); 2402 | throw new Error(errorMessage); 2403 | } 2404 | nextState[key] = nextStateForKey; 2405 | hasChanged = hasChanged || nextStateForKey !== previousStateForKey; 2406 | } 2407 | return hasChanged ? nextState : state; 2408 | }; 2409 | } 2410 | 2411 | /***/ }, 2412 | /* 35 */ 2413 | /***/ function(module, exports, __webpack_require__) { 2414 | 2415 | module.exports = __webpack_require__(36); 2416 | 2417 | 2418 | /***/ }, 2419 | /* 36 */ 2420 | /***/ function(module, exports, __webpack_require__) { 2421 | 2422 | /* WEBPACK VAR INJECTION */(function(global, module) {'use strict'; 2423 | 2424 | Object.defineProperty(exports, "__esModule", { 2425 | value: true 2426 | }); 2427 | 2428 | var _ponyfill = __webpack_require__(37); 2429 | 2430 | var _ponyfill2 = _interopRequireDefault(_ponyfill); 2431 | 2432 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 2433 | 2434 | var root; /* global window */ 2435 | 2436 | 2437 | if (typeof self !== 'undefined') { 2438 | root = self; 2439 | } else if (typeof window !== 'undefined') { 2440 | root = window; 2441 | } else if (typeof global !== 'undefined') { 2442 | root = global; 2443 | } else if (true) { 2444 | root = module; 2445 | } else { 2446 | root = Function('return this')(); 2447 | } 2448 | 2449 | var result = (0, _ponyfill2['default'])(root); 2450 | exports['default'] = result; 2451 | /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()) || Function('return this')(), __webpack_require__(38)(module))) 2452 | 2453 | /***/ }, 2454 | /* 37 */ 2455 | /***/ function(module, exports) { 2456 | 2457 | 'use strict'; 2458 | 2459 | Object.defineProperty(exports, "__esModule", { 2460 | value: true 2461 | }); 2462 | exports['default'] = symbolObservablePonyfill; 2463 | function symbolObservablePonyfill(root) { 2464 | var result; 2465 | var _Symbol = root.Symbol; 2466 | 2467 | if (typeof _Symbol === 'function') { 2468 | if (_Symbol.observable) { 2469 | result = _Symbol.observable; 2470 | } else { 2471 | result = _Symbol('observable'); 2472 | _Symbol.observable = result; 2473 | } 2474 | } else { 2475 | result = '@@observable'; 2476 | } 2477 | 2478 | return result; 2479 | }; 2480 | 2481 | /***/ }, 2482 | /* 38 */ 2483 | /***/ function(module, exports) { 2484 | 2485 | module.exports = function(module) { 2486 | if(!module.webpackPolyfill) { 2487 | module.deprecate = function() {}; 2488 | module.paths = []; 2489 | // module.parent = undefined by default 2490 | module.children = []; 2491 | module.webpackPolyfill = 1; 2492 | } 2493 | return module; 2494 | } 2495 | 2496 | 2497 | /***/ } 2498 | /******/ ]) 2499 | }); 2500 | ; --------------------------------------------------------------------------------