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
JavaScript
(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;