UNPKG

react-redux-provide

Version:

Build your UI with React. Manage application state with Redux providers. Persist and share application state with replication. Use pure functions everywhere.

1,627 lines (1,326 loc) 133 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("react"), require("redux"), require("redux-replicate")); else if(typeof define === 'function' && define.amd) define(["react", "redux", "redux-replicate"], factory); else if(typeof exports === 'object') exports["ReactReduxProvide"] = factory(require("react"), require("redux"), require("redux-replicate")); else root["ReactReduxProvide"] = factory(root["React"], root["Redux"], root["ReduxReplicate"]); })(this, function(__WEBPACK_EXTERNAL_MODULE_18__, __WEBPACK_EXTERNAL_MODULE_19__, __WEBPACK_EXTERNAL_MODULE_20__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.unshiftClear = exports.pushClear = exports.unshiftWait = exports.pushWait = exports.unshiftReplicator = exports.pushReplicator = exports.unshiftReplication = exports.pushReplication = exports.unshiftOnReady = exports.pushOnReady = exports.unshiftOnInstantiated = exports.pushOnInstantiated = exports.unshiftEnhancer = exports.pushEnhancer = exports.unshiftMiddleware = exports.pushMiddleware = exports.handleQueries = exports.getMergedResult = exports.getQueryHandlers = exports.getQueriesOptions = exports.getQueryOptions = exports.getQuery = exports.getQueries = exports.getFunctionOrObject = exports.getQueryResults = exports.getActiveQueries = exports.getProviderInstances = exports.getProviders = exports.getFromContextOrProps = exports.instantiateProvider = exports.shallowEqual = exports.createKeyConcat = exports.getInitialState = exports.getClientState = exports.createProviderStore = exports.reloadProviders = exports.reloadFunctions = exports.provide = undefined; var _provide = __webpack_require__(11); var _provide2 = _interopRequireDefault(_provide); var _createProviderStore = __webpack_require__(3); var _createProviderStore2 = _interopRequireDefault(_createProviderStore); var _createKeyConcat = __webpack_require__(2); var _createKeyConcat2 = _interopRequireDefault(_createKeyConcat); var _shallowEqual = __webpack_require__(1); var _shallowEqual2 = _interopRequireDefault(_shallowEqual); var _instantiateProvider = __webpack_require__(5); var _instantiateProvider2 = _interopRequireDefault(_instantiateProvider); var _keyConcats = __webpack_require__(6); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _provide2.default; exports.provide = _provide2.default; exports.reloadFunctions = _provide.reloadFunctions; exports.reloadProviders = _provide.reloadProviders; exports.createProviderStore = _createProviderStore2.default; exports.getClientState = _createProviderStore.getClientState; exports.getInitialState = _createProviderStore.getInitialState; exports.createKeyConcat = _createKeyConcat2.default; exports.shallowEqual = _shallowEqual2.default; exports.instantiateProvider = _instantiateProvider2.default; exports.getFromContextOrProps = _instantiateProvider.getFromContextOrProps; exports.getProviders = _instantiateProvider.getProviders; exports.getProviderInstances = _instantiateProvider.getProviderInstances; exports.getActiveQueries = _instantiateProvider.getActiveQueries; exports.getQueryResults = _instantiateProvider.getQueryResults; exports.getFunctionOrObject = _instantiateProvider.getFunctionOrObject; exports.getQueries = _instantiateProvider.getQueries; exports.getQuery = _instantiateProvider.getQuery; exports.getQueryOptions = _instantiateProvider.getQueryOptions; exports.getQueriesOptions = _instantiateProvider.getQueriesOptions; exports.getQueryHandlers = _instantiateProvider.getQueryHandlers; exports.getMergedResult = _instantiateProvider.getMergedResult; exports.handleQueries = _instantiateProvider.handleQueries; exports.pushMiddleware = _keyConcats.pushMiddleware; exports.unshiftMiddleware = _keyConcats.unshiftMiddleware; exports.pushEnhancer = _keyConcats.pushEnhancer; exports.unshiftEnhancer = _keyConcats.unshiftEnhancer; exports.pushOnInstantiated = _keyConcats.pushOnInstantiated; exports.unshiftOnInstantiated = _keyConcats.unshiftOnInstantiated; exports.pushOnReady = _keyConcats.pushOnReady; exports.unshiftOnReady = _keyConcats.unshiftOnReady; exports.pushReplication = _keyConcats.pushReplication; exports.unshiftReplication = _keyConcats.unshiftReplication; exports.pushReplicator = _keyConcats.pushReplicator; exports.unshiftReplicator = _keyConcats.unshiftReplicator; exports.pushWait = _keyConcats.pushWait; exports.unshiftWait = _keyConcats.unshiftWait; exports.pushClear = _keyConcats.pushClear; exports.unshiftClear = _keyConcats.unshiftClear; /***/ }), /* 1 */ /***/ (function(module, exports) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.default = shallowEqual; function shallowEqual(objA, objB) { if (objA === objB) { return true; } if (!objA || (typeof objA === 'undefined' ? 'undefined' : _typeof(objA)) !== 'object' || !objB || (typeof objB === 'undefined' ? 'undefined' : _typeof(objB)) !== 'object') { return false; } var keysA = Object.keys(objA); var keysB = Object.keys(objB); if (keysA.length !== keysB.length) { return false; } // Test for A's keys different from B. var hasOwn = Object.prototype.hasOwnProperty; for (var i = 0; i < keysA.length; i++) { if (!hasOwn.call(objB, keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) { return false; } } return true; } /***/ }), /* 2 */ /***/ (function(module, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = createKeyConcat; function createKeyConcat(keys, unshift) { var key = keys; var getTarget = function getTarget(provider) { return provider; }; if (Array.isArray(keys)) { keys = [].concat(keys); key = keys.pop(); getTarget = function getTarget(provider) { return keys.reduce(function (obj, key) { return obj[key]; }, provider); }; } return function (providers, value) { for (var providerKey in providers) { var target = getTarget(providers[providerKey]); if (target) { if (!target[key]) { target[key] = []; } else if (!Array.isArray(target[key])) { target[key] = [target[key]]; } if (unshift) { target[key] = [].concat(value).concat(target[key]); } else { target[key] = target[key].concat(value); } } } }; } /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); 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; }; exports.getClientState = getClientState; exports.getInitialState = getInitialState; exports.default = createProviderStore; var _redux = __webpack_require__(19); var _reduxReplicate = __webpack_require__(20); var _reduxReplicate2 = _interopRequireDefault(_reduxReplicate); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function getClientState(_ref) { var providerKey = _ref.providerKey; if (typeof window !== 'undefined' && window.clientStates) { var clientState = window.clientStates[providerKey]; if (typeof clientState !== 'undefined') { return clientState; } } return null; } function getInitialState(_ref2) { var providerKey = _ref2.providerKey, state = _ref2.state; var clientState = getClientState({ providerKey: providerKey, state: state }); if (clientState) { delete window.clientStates[providerKey]; return state ? _extends({}, state, clientState) : clientState; } return state || {}; } /** * Creates and returns a store specifically for some provider instance. * * @param {Object} providerInstance * @param {Mixed} storeKey Optional * @param {Object} createState Optional * @param {Function} createFunction Optional * @param {Object} creatorStore Optional * @return {Object} * @api public */ function createProviderStore(providerInstance, storeKey, createState, createFunction, creatorStore) { var reducers = providerInstance.reducers, middleware = providerInstance.middleware, enhancer = providerInstance.enhancer, replication = providerInstance.replication; var watchedReducers = {}; var watching = {}; var enhancers = []; var create = void 0; var store = void 0; var setState = void 0; var settingState = void 0; var combinedReducers = void 0; if (typeof storeKey === 'undefined') { storeKey = providerInstance.providerKey; } function unshiftReplication(_ref3) { var key = _ref3.key, reducerKeys = _ref3.reducerKeys, queryable = _ref3.queryable, baseQuery = _ref3.baseQuery, replicator = _ref3.replicator; if (replicator) { if (baseQuery) { if (Array.isArray(reducerKeys)) { for (var reducerKey in baseQuery) { if (reducerKeys.indexOf(reducerKey) < 0) { reducerKeys.push(reducerKey); } } } if (Array.isArray(queryable)) { for (var _reducerKey in baseQuery) { if (queryable.indexOf(_reducerKey) < 0) { queryable.push(_reducerKey); } } } } enhancers.unshift((0, _reduxReplicate2.default)({ key: typeof key === 'undefined' ? storeKey : key, reducerKeys: reducerKeys, queryable: queryable, replicator: replicator, create: createFunction || Boolean(createState), clientState: getClientState(providerInstance), creatorStore: creatorStore })); } } if (middleware) { enhancers.push(_redux.applyMiddleware.apply(null, [].concat(middleware))); } if (enhancer) { enhancers = enhancers.concat(enhancer); } if (replication) { if (Array.isArray(replication)) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = replication[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var _ref5 = _step.value; var key = _ref5.key; if (typeof key !== 'undefined') { storeKey = key; break; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } replication.forEach(unshiftReplication); } else { unshiftReplication(replication); } } if (enhancers.length) { create = _redux.compose.apply(undefined, _toConsumableArray(enhancers))(_redux.createStore); } else { create = _redux.createStore; } var initialState = {}; var preInitialState = _extends({}, createState || getInitialState(providerInstance)); Object.keys(reducers).forEach(function (reducerKey) { if (typeof preInitialState[reducerKey] !== 'undefined') { initialState[reducerKey] = preInitialState[reducerKey]; } watchedReducers[reducerKey] = function (state, action) { var nextState = void 0; if (settingState && typeof settingState[reducerKey] !== 'undefined') { nextState = settingState[reducerKey]; } else { nextState = reducers[reducerKey](state, action); } if (watching[reducerKey] && state !== nextState) { watching[reducerKey].forEach(function (fn) { return fn(nextState); }); } return nextState; }; }); combinedReducers = (0, _redux.combineReducers)(watchedReducers); store = create(combinedReducers, initialState); // we use a custom `watch` method with instead of a replicator // since it's slightly more efficient and every clock cycle counts, // especially with potentially thousands or even millions of components store.watch = function (reducerKey, fn) { if (!watching[reducerKey]) { watching[reducerKey] = new Set(); } watching[reducerKey].add(fn); return function () { return watching[reducerKey].delete(fn); }; }; setState = store.setState; store.setState = function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var nextState = args[0]; var state = store.getState(); if (setState) { var _loop = function _loop(reducerKey) { var current = state[reducerKey]; var next = nextState[reducerKey]; if (watching[reducerKey] && current !== next) { watching[reducerKey].forEach(function (fn) { return fn(next); }); } }; for (var reducerKey in nextState) { _loop(reducerKey); } setState.apply(undefined, args); } else { settingState = nextState; store.replaceReducer(combinedReducers); settingState = null; } }; return store; } /***/ }), /* 4 */ /***/ (function(module, exports) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.default = getRelevantKeys; function getRelevantKeys() { var a = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var relevantKeys = []; if ((typeof b === 'undefined' ? 'undefined' : _typeof(b)) === 'object') { for (var key in b) { if (key in a) { relevantKeys.push(key); } } } return relevantKeys; } /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); 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; }; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.default = instantiateProvider; exports.getTempFauxInstance = getTempFauxInstance; exports.getFromContextOrProps = getFromContextOrProps; exports.getProviders = getProviders; exports.getProviderInstances = getProviderInstances; exports.getActiveQueries = getActiveQueries; exports.getQueryResults = getQueryResults; exports.getPartialStates = getPartialStates; exports.getFunctionOrObject = getFunctionOrObject; exports.getQueries = getQueries; exports.getQuery = getQuery; exports.getQueryOptions = getQueryOptions; exports.getQueriesOptions = getQueriesOptions; exports.getQueryHandlers = getQueryHandlers; exports.getMergedResult = getMergedResult; exports.resultsEqual = resultsEqual; exports.handleQueries = handleQueries; var _shallowEqual = __webpack_require__(1); var _shallowEqual2 = _interopRequireDefault(_shallowEqual); var _getRelevantKeys = __webpack_require__(4); var _getRelevantKeys2 = _interopRequireDefault(_getRelevantKeys); var _createProviderStore = __webpack_require__(3); var _createProviderStore2 = _interopRequireDefault(_createProviderStore); var _keyConcats = __webpack_require__(6); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var isServerSide = typeof window === 'undefined'; var isTesting = typeof process !== 'undefined' && process.env && ("development") === 'test'; var globalProviderInstances = {}; // TODO: we'll use this at some point to select only component propTypes /* function hasReducerKeys(providerInstance, getReducerKeys) { if (!getReducerKeys) { return true; } const { hasReducerKeys = {} } = providerInstance; for (let reducerKey in getReducerKeys) { if (!hasReducerKeys[reducerKey]) { providerInstance.hasReducerKeys = { ...hasReducerKeys, ...getReducerKeys }; return false; } } return true; }*/ /** * Instantiates a provider with its own store. * * @param {Object} fauxInstance resembles { props, context } * @param {Object} provider * @param {String|Function} providerKey Optional * @param {Function} readyCallback Optional * @param {Object} createState Optional * @param {Object} getReducerKeys Optional * @param {Boolean} useCreator Optional * @return {Object} * @api public */ function instantiateProvider(fauxInstance, provider, providerKey, readyCallback, createState, getReducerKeys, useCreator // TODO: clean this up ) { if (arguments.length === 1) { fauxInstance = arguments[0].fauxInstance; provider = arguments[0].provider; providerKey = arguments[0].providerKey; readyCallback = arguments[0].readyCallback; createState = arguments[0].createState; getReducerKeys = arguments[0].getReducerKeys; useCreator = arguments[0].useCreator; if (!fauxInstance) { provider = arguments[0]; fauxInstance = {}; } } if (!fauxInstance.props) { fauxInstance.props = {}; } if (typeof providerKey === 'undefined') { providerKey = provider.key; } if (!provider.actions) { provider.actions = {}; } if (!provider.reducers) { provider.reducers = {}; } if (getReducerKeys === true) { getReducerKeys = provider.reducers; } var providers = getProviders(fauxInstance); var providerInstances = getProviderInstances(fauxInstance); var providerInstance = void 0; var isStatic = typeof providerKey !== 'function'; var storeKey = void 0; var creator = void 0; if (typeof provider.key === 'string') { if (!providers[provider.key]) { providers[provider.key] = provider; } } else if (provider.defaultKey) { if (!providers[provider.defaultKey]) { providers[provider.defaultKey] = provider; } } else if (!provider.key || !provider.key.toString) { console.warn('Missing or invalid provider key!'); } else if (!providers[provider.key.toString()]) { providers[provider.key.toString()] = provider; } if (!isStatic) { // get actual `providerKey` providerKey = providerKey(fauxInstance); // if actual `providerKey` matches `key`, treat as static provider isStatic = providerKey === provider.key; } if (providerKey === null) { storeKey = null; providerKey = provider.defaultKey; isStatic = true; } providerInstance = provider.isGlobal ? globalProviderInstances[providerKey] : providerInstances && providerInstances[providerKey]; if (fauxInstance.relevantProviders) { fauxInstance.relevantProviders[providerKey] = true; } if (createState && (typeof createState === 'undefined' ? 'undefined' : _typeof(createState)) === 'object' && provider.state && _typeof(provider.state) === 'object') { createState = _extends({}, provider.state, createState); } // TODO: we'll use this at some point //if (providerInstance && hasReducerKeys(providerInstance, getReducerKeys)) { if (providerInstance) { if (createState) { if (useCreator) { // TODO: clean this up creator = providerInstance; } else { providerInstances[providerKey] = providerInstance; providerInstance.store.setState(createState, false, true); if (readyCallback) { if (providerInstance.ready) { readyCallback(providerInstance); } else { (0, _keyConcats.pushOnReady)({ providerInstance: providerInstance }, readyCallback); } } return providerInstance; } } else { providerInstances[providerKey] = providerInstance; if (readyCallback) { if (providerInstance.ready) { readyCallback(providerInstance); } else { (0, _keyConcats.pushOnReady)({ providerInstance: providerInstance }, readyCallback); } } return providerInstance; } } if (!provider.hasThunk) { var findProvider = function findProvider(props) { if ((0, _getRelevantKeys2.default)(provider.reducers, props).length) { return provider; } for (var key in providers) { if ((0, _getRelevantKeys2.default)(providers[key].reducers, props).length) { return providers[key]; } } return provider; }; var getResultInstances = function getResultInstances(result, callback) { var resultInstances = []; var semaphore = result && result.length; function clear() { if (--semaphore === 0) { callback(resultInstances); } } if (!semaphore) { semaphore = 1; clear(); return; } result.forEach(function (resultProps, index) { resultInstances[index] = null; instantiateProvider({ fauxInstance: getTempFauxInstance(fauxInstance, resultProps), provider: findProvider(resultProps), readyCallback: function readyCallback(resultInstance) { resultInstances[index] = resultInstance; clear(); } }); }); }; var getInstance = function getInstance(props, callback, create, useCreator) { var provider = void 0; var providerKey = void 0; if (typeof props === 'string') { // key is already known if (providerInstances[props]) { providerKey = props; } provider = providers[props] || providerInstances[props]; props = {}; } else { provider = findProvider(props); } return instantiateProvider({ fauxInstance: getTempFauxInstance(fauxInstance, props), provider: provider, providerKey: providerKey, readyCallback: callback, createState: create ? props : null, useCreator: useCreator }); }; var getInstances = function getInstances(propsArray, callback, create, useCreator) { var instances = []; var getCount = propsArray.length; var clear = function clear() { if (--getCount === 0) { if (callback) { callback(instances); } } }; propsArray.forEach(function (props, index) { getInstance(props, function (instance) { instances[index] = instance; clear(); }, create); }); return instances; }; var createInstance = function createInstance(props, callback, useCreator) { return getInstance(props, callback, true, useCreator); }; var createInstances = function createInstances(propsArray, callback, useCreator) { return getInstances(propsArray, callback, true, useCreator); }; var setStates = function setStates(states) { var gettingInstances = []; var settingStates = []; var clientStates = null; if (!isServerSide) { if (!window.clientStates) { window.clientStates = {}; } clientStates = window.clientStates; } var _loop = function _loop(_providerKey) { var state = states[_providerKey]; var providerInstance = providerInstances[_providerKey]; if (providerInstance) { if (providerInstance.store.setState) { settingStates.push(function () { return providerInstance.store.setState(state); }); } } else { if (clientStates) { clientStates[_providerKey] = state; } gettingInstances.push(state); } }; for (var _providerKey in states) { _loop(_providerKey); } // now that `clientStates` are cached... while (gettingInstances.length) { getInstance(gettingInstances.shift()); } while (settingStates.length) { settingStates.shift()(); } }; var find = function find(props, doInstantiate, callback) { if (arguments.length === 2) { callback = doInstantiate; doInstantiate = false; } handleQueries(getTempFauxInstance(fauxInstance, props), function () { if (!doInstantiate) { callback(props.query ? props.result : props.results); return; } if (props.query) { getResultInstances(props.result, callback); return; } var results = props.results; var resultsInstances = {}; var resultsKeys = results && Object.keys(results); var semaphore = resultsKeys && resultsKeys.length; function clear() { if (--semaphore === 0) { callback(resultsInstances); } } if (!semaphore) { semaphore = 1; clear(); } resultsKeys.forEach(function (resultKey) { resultsInstances[resultKey] = []; getResultInstances(results[resultKey], function (resultInstances) { resultsInstances[resultKey] = resultInstances; clear(); }); }); }); }; provider.hasThunk = true; if (provider.wait && !Array.isArray(provider.wait)) { provider.wait = [provider.wait]; } if (provider.clear && !Array.isArray(provider.clear)) { provider.clear = [provider.clear]; } var providerApi = { getInstance: getInstance, getInstances: getInstances, createInstance: createInstance, createInstances: createInstances, setStates: setStates, find: find }; (0, _keyConcats.unshiftMiddleware)({ provider: provider }, function (_ref) { var dispatch = _ref.dispatch, getState = _ref.getState; return function (next) { return function (action) { if (typeof action !== 'function') { return next(action); } if (provider.wait) { provider.wait.forEach(function (fn) { return fn(); }); } return action(function (action) { var state = store.getState(); var storeChanged = false; dispatch(action); if (provider.clear) { storeChanged = state !== store.getState(); provider.clear.forEach(function (fn) { return fn(storeChanged); }); } }, getState, providerApi); }; }; }); } if (provider.wait) { provider.wait.forEach(function (fn) { return fn(); }); } providerInstance = Object.create(provider); providerInstance.providerKey = providerKey; providerInstance.isStatic = isStatic; var store = (0, _createProviderStore2.default)(providerInstance, storeKey, createState, createState ? function (state) { var _providerInstance = providerInstance, onReady = _providerInstance.onReady; providerInstance = instantiateProvider({ fauxInstance: getTempFauxInstance(fauxInstance, state), provider: provider, readyCallback: function readyCallback(createdInstance) { if (Array.isArray(onReady)) { onReady.forEach(function (fn) { return fn(createdInstance); }); } else if (onReady) { onReady(createdInstance); } } }); } : null, // TODO: we need a better way to create + replicate creator && creator.store); var initialState = store.getState(); var _providerInstance2 = providerInstance, actions = _providerInstance2.actions; var actionCreators = {}; var setKey = store.setKey; if (setKey) { store.setKey = function (newKey, readyCallback) { if (provider.wait) { provider.wait.forEach(function (fn) { return fn(); }); } setKey(newKey, function () { if (Array.isArray(providerInstance.onReady)) { providerInstance.onReady.forEach(function (fn) { return fn(providerInstance); }); } else if (providerInstance.onReady) { providerInstance.onReady(providerInstance); } if (readyCallback) { readyCallback(); } if (provider.clear) { provider.clear.forEach(function (fn) { return fn(true); }); } }); }; } var _loop2 = function _loop2(actionKey) { actionCreators[actionKey] = function () { return store.dispatch(actions[actionKey].apply(this, arguments)); }; }; for (var actionKey in actions) { _loop2(actionKey); } providerInstance.store = store; providerInstance.actionCreators = actionCreators; if (!createState) { if (provider.isGlobal) { globalProviderInstances[providerKey] = providerInstance; } if (providerInstances) { providerInstances[providerKey] = providerInstance; } if (!provider.instances) { provider.instances = []; } provider.instances.push(providerInstance); } if (provider.subscribers) { Object.keys(provider.subscribers).forEach(function (key) { var handler = provider.subscribers[key]; var subProvider = providers[key]; var subKey = provider.defaultKey || (typeof provider.key === 'function' ? provider.key({}) : String(provider.key)); var callHandler = function callHandler() { var subProviderInstances = subProvider && subProvider.instances; if (subProviderInstances) { subProviderInstances.forEach(function (subProviderInstance) { handler(providerInstance, subProviderInstance); }); } }; if (subProvider) { if (!subProvider.subscribeTo) { subProvider.subscribeTo = {}; } if (!subProvider.subscribeTo[subKey]) { subProvider.subscribeTo[subKey] = handler; } } providerInstance.store.subscribe(callHandler); callHandler(); }); } if (provider.subscribeTo) { Object.keys(provider.subscribeTo).forEach(function (key) { var handler = provider.subscribeTo[key]; var supProvider = providers[key]; var supKey = provider.defaultKey || (typeof provider.key === 'function' ? provider.key({}) : String(provider.key)); if (!supProvider) { return; } if (!supProvider.subscribers) { supProvider.subscribers = {}; } if (!supProvider.subscribers[supKey]) { supProvider.subscribers[supKey] = handler; if (supProvider.instances) { supProvider.instances.forEach(function (supProviderInstance) { supProviderInstance.store.subscribe(function () { provider.instances.forEach(function (providerInstance) { handler(supProviderInstance, providerInstance); }); }); }); } } if (supProvider.instances) { supProvider.instances.forEach(function (supProviderInstance) { handler(supProviderInstance, providerInstance); }); } }); } if (!createState) { if (Array.isArray(providerInstance.onInstantiated)) { providerInstance.onInstantiated.forEach(function (fn) { return fn(providerInstance); }); } else if (providerInstance.onInstantiated) { providerInstance.onInstantiated(providerInstance); } } (0, _keyConcats.unshiftOnReady)({ providerInstance: providerInstance }, function () { providerInstance.ready = true; }); if (readyCallback) { (0, _keyConcats.pushOnReady)({ providerInstance: providerInstance }, readyCallback); } function done() { if (Array.isArray(providerInstance.onReady)) { providerInstance.onReady.forEach(function (fn) { return fn(providerInstance); }); } else if (providerInstance.onReady) { providerInstance.onReady(providerInstance); } if (provider.clear) { var storeChanged = initialState !== providerInstance.store.getState(); provider.clear.forEach(function (fn) { return fn(storeChanged); }); } } if (provider.replication && store.onReady && !store.initializedReplication) { store.onReady(done); } else { done(); } return providerInstance; } function getContext(fauxInstance) { if (!fauxInstance.context) { fauxInstance.context = {}; } return fauxInstance.context; } function getTempFauxInstance(fauxInstance, props) { return { props: props, context: getContext(fauxInstance), providers: getProviders(fauxInstance), providerInstances: getProviderInstances(fauxInstance), activeQueries: getActiveQueries(fauxInstance), queryResults: getQueryResults(fauxInstance), partialStates: getPartialStates(fauxInstance) }; } function getFromContextOrProps(fauxInstance, key, defaultValue) { if (typeof fauxInstance[key] === 'undefined') { var props = fauxInstance.props; var context = getContext(fauxInstance); if (typeof props[key] !== 'undefined') { fauxInstance[key] = props[key]; } else if (typeof context[key] !== 'undefined') { fauxInstance[key] = context[key]; } else { fauxInstance[key] = defaultValue; } } return fauxInstance[key]; } function getProviders(fauxInstance) { return getFromContextOrProps(fauxInstance, 'providers', {}); } function getProviderInstances(fauxInstance) { return getFromContextOrProps(fauxInstance, 'providerInstances', {}); } function getActiveQueries(fauxInstance) { return getFromContextOrProps(fauxInstance, 'activeQueries', {}); } function getQueryResults(fauxInstance) { return getFromContextOrProps(fauxInstance, 'queryResults', {}); } function getPartialStates(fauxInstance) { return getFromContextOrProps(fauxInstance, 'partialStates', {}); } function getFunctionOrObject(fauxInstance, key) { var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; if (typeof fauxInstance[key] !== 'undefined') { return fauxInstance[key]; } var value = fauxInstance.props[key]; if (typeof value === 'function') { value = value(fauxInstance); } fauxInstance[key] = value || defaultValue; return fauxInstance[key]; } function getQueries(fauxInstance) { if (getQueries.disabled) { return false; } if (typeof fauxInstance.queries !== 'undefined') { return fauxInstance.queries; } var props = fauxInstance.props, relevantProviders = fauxInstance.relevantProviders; var providers = getProviders(fauxInstance); var query = getQuery(fauxInstance); var queries = getFunctionOrObject(fauxInstance, 'queries'); var hasQueries = false; if (query) { // we need to map the query to relevant provider(s) if (!queries) { queries = {}; } else if (typeof props.queries !== 'function') { queries = _extends({}, queries); } for (var key in providers) { var provider = providers[key]; var queryKeys = (0, _getRelevantKeys2.default)(provider.reducers, query); if (queryKeys.length) { // provider is relevant, so we map it within the queries object if (!queries[key]) { queries[key] = {}; } var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = queryKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var queryKey = _step.value; queries[key][queryKey] = query[queryKey]; } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } } } for (var _key in queries) { var _query = queries[_key]; if (typeof _query === 'function') { queries[_key] = _query(fauxInstance); } // make sure each provider is instantiated instantiateProvider(fauxInstance, providers[_key]); hasQueries = true; } if (!hasQueries) { queries = null; if (props.query) { props.result = null; } if (props.queries) { props.results = {}; } } fauxInstance.queries = queries; return queries; } function getQuery(fauxInstance) { return getFunctionOrObject(fauxInstance, 'query'); } function getQueryOptions(fauxInstance) { return getFunctionOrObject(fauxInstance, 'queryOptions'); } function getQueriesOptions(fauxInstance) { return getFunctionOrObject(fauxInstance, 'queriesOptions', {}); } // gets all `handleQuery` functions within replicators function getQueryHandlers(provider) { var queryHandlers = []; var replication = provider.replication; if (replication) { if (!Array.isArray(replication)) { replication = [replication]; } var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = replication[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var _ref3 = _step2.value; var replicator = _ref3.replicator, reducerKeys = _ref3.reducerKeys, baseQuery = _ref3.baseQuery, baseQueryOptions = _ref3.baseQueryOptions; if (replicator) { if (!Array.isArray(replicator)) { replicator = [replicator]; } var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = replicator[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var _ref5 = _step3.value; var handleQuery = _ref5.handleQuery; if (handleQuery) { queryHandlers.push({ handleQuery: handleQuery, reducerKeys: reducerKeys || Object.keys(provider.reducers), baseQuery: baseQuery, baseQueryOptions: baseQueryOptions }); } } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } } } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } return queryHandlers; } function getMergedResult(mergedResult, result) { if (Array.isArray(result)) { return [].concat(_toConsumableArray(mergedResult || []), _toConsumableArray(result)); } else if (result && (typeof result === 'undefined' ? 'undefined' : _typeof(result)) === 'object' && result.constructor === Object) { return _extends({}, mergedResult || {}, result); } else if (typeof result !== 'undefined') { return result; } else { return mergedResult; } } function resultsEqual(result, previousResult) { if (result === previousResult) { return true; } if ((typeof result === 'undefined' ? 'undefined' : _typeof(result)) !== (typeof previousResult === 'undefined' ? 'undefined' : _typeof(previousResult))) { return false; } if (Array.isArray(result)) { if (Array.isArray(previousResult)) { var i = 0; var length = result.length; if (length !== previousResult.length) { return false; } while (i < length) { if (!(0, _shallowEqual2.default)(result[i], previousResult[i])) { return false; } i++; } } else { return false; } } else if (Array.isArray(previousResult)) { return false; } return (0, _shallowEqual2.default)(result, previousResult); } // this is admittedly a mess... :( // we're accounting for both synchronous and asynchronous query handling // where asynchronous results will override the synchronous results function handleQueries(fauxInstance, callback, previousResults) { var doUpdate = false; var queries = getQueries(fauxInstance); if (!queries) { if (callback) { callback(doUpdate); } return false; } var props = fauxInstance.props; var context = getContext(fauxInstance); var originalResult = props.result, originalResults = props.results; var validQuery = false; // for determining whether or not we should update if (!previousResults) { previousResults = _extends({}, props.results); } // get what we need to handle the queries var query = getQuery(fauxInstance); var queryOptions = getQueryOptions(fauxInstance); var queriesOptions = getQueriesOptions(fauxInstance); var activeQueries = getActiveQueries(fauxInstance); var queryResults = getQueryResults(fauxInstance); var partialStates = getPartialStates(fauxInstance); var providers = getProviders(fauxInstance); var providerInstances = getProviderInstances(fauxInstance); // TODO: we should probably do something better at some point var setPartialStates = function setPartialStates(provider, result) { if (!result || typeof result.map !== 'function' || !isServerSide) { return; } var _iteratorNormalCompletion4 = true; var _didIteratorError4 = false; var _iteratorError4 = undefined; try { for (var _iterator4 = result[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { var partialState = _step4.value; var providerKey = provider.key; if (typeof providerKey === 'function') { providerKey = providerKey({ props: partialState, context: context }); } if (providerKey !== null && !providerInstances[providerKey]) { partialStates[providerKey] = partialState; } } } catch (err) { _didIteratorError4 = true; _iteratorError4 = err; } finally { try { if (!_iteratorNormalCompletion4 && _iterator4.return) { _iterator4.return(); } } finally { if (_didIteratorError4) { throw _iteratorError4; } } } }; // most queries should be async var queryCount = Object.keys(queries).length; var queryClear = function queryClear() { if (--queryCount === 0) { // at this point we have all our results if (callback) { callback(doUpdate); } } }; // merge each result into `props.result` if using `props.query` var setMergedResult = function setMergedResult(result) { if (props.query) { props.result = getMergedResult(props.result, result); } }; // go ahead and set null value if using `props.query` if (props.query) { props.result = null; } // results start out as an empty object props.results = {}; // check each query Object.keys(queries).forEach(function (key) { var provider = providers[key]; var queryHandlers = getQueryHandlers(provider); var handlerCount = queryHandlers.length; // no handlers? Y U DO DIS? if (!handlerCount) { queryClear(); return; } validQuery = true; // let the provider know we're waiting for all of the handlers to finish if (Array.isArray(provider.wait)) { provider.wait.forEach(function (fn) { return fn(); }); } else if (provider.wait) { provider.wait(); } // here we determine the `resultKey` used for caching the results // in the current context var query = queries[key]; var options = queryOptions || queriesOptions[key] || {}; var resultKey = JSON.stringify({ query: query, options: options }); var queryResult = queryResults[resultKey]; var queryResultExists = typeof queryResult !== 'undefined'; // subscribe to all of this provider's instances' stores for requeries subscribeToAll(key, provider, fauxInstance, resultKey, query, callback); // result handler for both sync and async queries var setResult = function setResult(result) { if (!activeQueries[resultKey]) { console.warn('setResult was called but the following query is no longer active:', { query: query, options: options }); return; } var first = activeQueries[resultKey].values().next().value; var leader = setResult === first; var previousResult = queryResultExists ? queryResult : previousResults[key]; var asyncReset = setResult.asyncReset; // if new result, set `doUpdate` flag if (!doUpdate && !resultsEqual(result, previousResult)) { doUpdate = true; } // a special `asyncReset` flag is set if async handler is detected; // we want async results to override sync if (asyncReset) { // this should only occur once, at the start of setting async results setResult.asyncReset = false; props.results = {}; if (props.query) { props.result = null; } } props.results[key] = result; previousResults[key] = result;