12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244 |
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (factory((global.ReduxPersist = {})));
- }(this, (function (exports) { 'use strict';
- function _typeof(obj) {
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
- _typeof = function (obj) {
- return typeof obj;
- };
- } else {
- _typeof = function (obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
- }
- return _typeof(obj);
- }
- function _defineProperty(obj, key, value) {
- if (key in obj) {
- Object.defineProperty(obj, key, {
- value: value,
- enumerable: true,
- configurable: true,
- writable: true
- });
- } else {
- obj[key] = value;
- }
- return obj;
- }
- function ownKeys(object, enumerableOnly) {
- var keys = Object.keys(object);
- if (Object.getOwnPropertySymbols) {
- var symbols = Object.getOwnPropertySymbols(object);
- if (enumerableOnly) symbols = symbols.filter(function (sym) {
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
- });
- keys.push.apply(keys, symbols);
- }
- return keys;
- }
- function _objectSpread2(target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i] != null ? arguments[i] : {};
- if (i % 2) {
- ownKeys(source, true).forEach(function (key) {
- _defineProperty(target, key, source[key]);
- });
- } else if (Object.getOwnPropertyDescriptors) {
- Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
- } else {
- ownKeys(source).forEach(function (key) {
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
- });
- }
- }
- return target;
- }
- function _objectWithoutPropertiesLoose(source, excluded) {
- if (source == null) return {};
- var target = {};
- var sourceKeys = Object.keys(source);
- var key, i;
- for (i = 0; i < sourceKeys.length; i++) {
- key = sourceKeys[i];
- if (excluded.indexOf(key) >= 0) continue;
- target[key] = source[key];
- }
- return target;
- }
- function _objectWithoutProperties(source, excluded) {
- if (source == null) return {};
- var target = _objectWithoutPropertiesLoose(source, excluded);
- var key, i;
- if (Object.getOwnPropertySymbols) {
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
- for (i = 0; i < sourceSymbolKeys.length; i++) {
- key = sourceSymbolKeys[i];
- if (excluded.indexOf(key) >= 0) continue;
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
- target[key] = source[key];
- }
- }
- return target;
- }
- function _toConsumableArray(arr) {
- return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
- }
- function _arrayWithoutHoles(arr) {
- if (Array.isArray(arr)) {
- for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
- return arr2;
- }
- }
- function _iterableToArray(iter) {
- if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
- }
- function _nonIterableSpread() {
- throw new TypeError("Invalid attempt to spread non-iterable instance");
- }
- var KEY_PREFIX = 'persist:';
- var FLUSH = 'persist/FLUSH';
- var REHYDRATE = 'persist/REHYDRATE';
- var PAUSE = 'persist/PAUSE';
- var PERSIST = 'persist/PERSIST';
- var PURGE = 'persist/PURGE';
- var REGISTER = 'persist/REGISTER';
- var DEFAULT_VERSION = -1;
- /*
- autoMergeLevel1:
- - merges 1 level of substate
- - skips substate if already modified
- */
- function autoMergeLevel1(inboundState, originalState, reducedState, _ref) {
- var debug = _ref.debug;
- var newState = _objectSpread2({}, reducedState); // only rehydrate if inboundState exists and is an object
- if (inboundState && _typeof(inboundState) === 'object') {
- Object.keys(inboundState).forEach(function (key) {
- // ignore _persist data
- if (key === '_persist') return; // if reducer modifies substate, skip auto rehydration
- if (originalState[key] !== reducedState[key]) {
- if ("development" !== 'production' && debug) console.log('redux-persist/stateReconciler: sub state for key `%s` modified, skipping.', key);
- return;
- } // otherwise hard set the new value
- newState[key] = inboundState[key];
- });
- }
- if ("development" !== 'production' && debug && inboundState && _typeof(inboundState) === 'object') console.log("redux-persist/stateReconciler: rehydrated keys '".concat(Object.keys(inboundState).join(', '), "'"));
- return newState;
- }
- // @TODO remove once flow < 0.63 support is no longer required.
- function createPersistoid(config) {
- // defaults
- var blacklist = config.blacklist || null;
- var whitelist = config.whitelist || null;
- var transforms = config.transforms || [];
- var throttle = config.throttle || 0;
- var storageKey = "".concat(config.keyPrefix !== undefined ? config.keyPrefix : KEY_PREFIX).concat(config.key);
- var storage = config.storage;
- var serialize;
- if (config.serialize === false) {
- serialize = function serialize(x) {
- return x;
- };
- } else if (typeof config.serialize === 'function') {
- serialize = config.serialize;
- } else {
- serialize = defaultSerialize;
- }
- var writeFailHandler = config.writeFailHandler || null; // initialize stateful values
- var lastState = {};
- var stagedState = {};
- var keysToProcess = [];
- var timeIterator = null;
- var writePromise = null;
- var update = function update(state) {
- // add any changed keys to the queue
- Object.keys(state).forEach(function (key) {
- if (!passWhitelistBlacklist(key)) return; // is keyspace ignored? noop
- if (lastState[key] === state[key]) return; // value unchanged? noop
- if (keysToProcess.indexOf(key) !== -1) return; // is key already queued? noop
- keysToProcess.push(key); // add key to queue
- }); //if any key is missing in the new state which was present in the lastState,
- //add it for processing too
- Object.keys(lastState).forEach(function (key) {
- if (state[key] === undefined && passWhitelistBlacklist(key) && keysToProcess.indexOf(key) === -1 && lastState[key] !== undefined) {
- keysToProcess.push(key);
- }
- }); // start the time iterator if not running (read: throttle)
- if (timeIterator === null) {
- timeIterator = setInterval(processNextKey, throttle);
- }
- lastState = state;
- };
- function processNextKey() {
- if (keysToProcess.length === 0) {
- if (timeIterator) clearInterval(timeIterator);
- timeIterator = null;
- return;
- }
- var key = keysToProcess.shift();
- var endState = transforms.reduce(function (subState, transformer) {
- return transformer.in(subState, key, lastState);
- }, lastState[key]);
- if (endState !== undefined) {
- try {
- stagedState[key] = serialize(endState);
- } catch (err) {
- console.error('redux-persist/createPersistoid: error serializing state', err);
- }
- } else {
- //if the endState is undefined, no need to persist the existing serialized content
- delete stagedState[key];
- }
- if (keysToProcess.length === 0) {
- writeStagedState();
- }
- }
- function writeStagedState() {
- // cleanup any removed keys just before write.
- Object.keys(stagedState).forEach(function (key) {
- if (lastState[key] === undefined) {
- delete stagedState[key];
- }
- });
- writePromise = storage.setItem(storageKey, serialize(stagedState)).catch(onWriteFail);
- }
- function passWhitelistBlacklist(key) {
- if (whitelist && whitelist.indexOf(key) === -1 && key !== '_persist') return false;
- if (blacklist && blacklist.indexOf(key) !== -1) return false;
- return true;
- }
- function onWriteFail(err) {
- // @TODO add fail handlers (typically storage full)
- if (writeFailHandler) writeFailHandler(err);
- if (err && "development" !== 'production') {
- console.error('Error storing data', err);
- }
- }
- var flush = function flush() {
- while (keysToProcess.length !== 0) {
- processNextKey();
- }
- return writePromise || Promise.resolve();
- }; // return `persistoid`
- return {
- update: update,
- flush: flush
- };
- } // @NOTE in the future this may be exposed via config
- function defaultSerialize(data) {
- return JSON.stringify(data);
- }
- function getStoredState(config) {
- var transforms = config.transforms || [];
- var storageKey = "".concat(config.keyPrefix !== undefined ? config.keyPrefix : KEY_PREFIX).concat(config.key);
- var storage = config.storage;
- var debug = config.debug;
- var deserialize;
- if (config.deserialize === false) {
- deserialize = function deserialize(x) {
- return x;
- };
- } else if (typeof config.deserialize === 'function') {
- deserialize = config.deserialize;
- } else {
- deserialize = defaultDeserialize;
- }
- return storage.getItem(storageKey).then(function (serialized) {
- if (!serialized) return undefined;else {
- try {
- var state = {};
- var rawState = deserialize(serialized);
- Object.keys(rawState).forEach(function (key) {
- state[key] = transforms.reduceRight(function (subState, transformer) {
- return transformer.out(subState, key, rawState);
- }, deserialize(rawState[key]));
- });
- return state;
- } catch (err) {
- if ("development" !== 'production' && debug) console.log("redux-persist/getStoredState: Error restoring data ".concat(serialized), err);
- throw err;
- }
- }
- });
- }
- function defaultDeserialize(serial) {
- return JSON.parse(serial);
- }
- function purgeStoredState(config) {
- var storage = config.storage;
- var storageKey = "".concat(config.keyPrefix !== undefined ? config.keyPrefix : KEY_PREFIX).concat(config.key);
- return storage.removeItem(storageKey, warnIfRemoveError);
- }
- function warnIfRemoveError(err) {
- if (err && "development" !== 'production') {
- console.error('redux-persist/purgeStoredState: Error purging data stored state', err);
- }
- }
- var DEFAULT_TIMEOUT = 5000;
- /*
- @TODO add validation / handling for:
- - persisting a reducer which has nested _persist
- - handling actions that fire before reydrate is called
- */
- function persistReducer(config, baseReducer) {
- {
- if (!config) throw new Error('config is required for persistReducer');
- if (!config.key) throw new Error('key is required in persistor config');
- if (!config.storage) throw new Error("redux-persist: config.storage is required. Try using one of the provided storage engines `import storage from 'redux-persist/lib/storage'`");
- }
- var version = config.version !== undefined ? config.version : DEFAULT_VERSION;
- var debug = config.debug || false;
- var stateReconciler = config.stateReconciler === undefined ? autoMergeLevel1 : config.stateReconciler;
- var getStoredState$$1 = config.getStoredState || getStoredState;
- var timeout = config.timeout !== undefined ? config.timeout : DEFAULT_TIMEOUT;
- var _persistoid = null;
- var _purge = false;
- var _paused = true;
- var conditionalUpdate = function conditionalUpdate(state) {
- // update the persistoid only if we are rehydrated and not paused
- state._persist.rehydrated && _persistoid && !_paused && _persistoid.update(state);
- return state;
- };
- return function (state, action) {
- var _ref = state || {},
- _persist = _ref._persist,
- rest = _objectWithoutProperties(_ref, ["_persist"]); // $FlowIgnore need to update State type
- var restState = rest;
- if (action.type === PERSIST) {
- var _sealed = false;
- var _rehydrate = function _rehydrate(payload, err) {
- // dev warning if we are already sealed
- if ("development" !== 'production' && _sealed) console.error("redux-persist: rehydrate for \"".concat(config.key, "\" called after timeout."), payload, err); // only rehydrate if we are not already sealed
- if (!_sealed) {
- action.rehydrate(config.key, payload, err);
- _sealed = true;
- }
- };
- timeout && setTimeout(function () {
- !_sealed && _rehydrate(undefined, new Error("redux-persist: persist timed out for persist key \"".concat(config.key, "\"")));
- }, timeout); // @NOTE PERSIST resumes if paused.
- _paused = false; // @NOTE only ever create persistoid once, ensure we call it at least once, even if _persist has already been set
- if (!_persistoid) _persistoid = createPersistoid(config); // @NOTE PERSIST can be called multiple times, noop after the first
- if (_persist) {
- // We still need to call the base reducer because there might be nested
- // uses of persistReducer which need to be aware of the PERSIST action
- return _objectSpread2({}, baseReducer(restState, action), {
- _persist: _persist
- });
- }
- if (typeof action.rehydrate !== 'function' || typeof action.register !== 'function') throw new Error('redux-persist: either rehydrate or register is not a function on the PERSIST action. This can happen if the action is being replayed. This is an unexplored use case, please open an issue and we will figure out a resolution.');
- action.register(config.key);
- getStoredState$$1(config).then(function (restoredState) {
- var migrate = config.migrate || function (s, v) {
- return Promise.resolve(s);
- };
- migrate(restoredState, version).then(function (migratedState) {
- _rehydrate(migratedState);
- }, function (migrateErr) {
- if ("development" !== 'production' && migrateErr) console.error('redux-persist: migration error', migrateErr);
- _rehydrate(undefined, migrateErr);
- });
- }, function (err) {
- _rehydrate(undefined, err);
- });
- return _objectSpread2({}, baseReducer(restState, action), {
- _persist: {
- version: version,
- rehydrated: false
- }
- });
- } else if (action.type === PURGE) {
- _purge = true;
- action.result(purgeStoredState(config));
- return _objectSpread2({}, baseReducer(restState, action), {
- _persist: _persist
- });
- } else if (action.type === FLUSH) {
- action.result(_persistoid && _persistoid.flush());
- return _objectSpread2({}, baseReducer(restState, action), {
- _persist: _persist
- });
- } else if (action.type === PAUSE) {
- _paused = true;
- } else if (action.type === REHYDRATE) {
- // noop on restState if purging
- if (_purge) return _objectSpread2({}, restState, {
- _persist: _objectSpread2({}, _persist, {
- rehydrated: true
- }) // @NOTE if key does not match, will continue to default else below
- });
- if (action.key === config.key) {
- var reducedState = baseReducer(restState, action);
- var inboundState = action.payload; // only reconcile state if stateReconciler and inboundState are both defined
- var reconciledRest = stateReconciler !== false && inboundState !== undefined ? stateReconciler(inboundState, state, reducedState, config) : reducedState;
- var _newState = _objectSpread2({}, reconciledRest, {
- _persist: _objectSpread2({}, _persist, {
- rehydrated: true
- })
- });
- return conditionalUpdate(_newState);
- }
- } // if we have not already handled PERSIST, straight passthrough
- if (!_persist) return baseReducer(state, action); // run base reducer:
- // is state modified ? return original : return updated
- var newState = baseReducer(restState, action);
- if (newState === restState) return state;
- return conditionalUpdate(_objectSpread2({}, newState, {
- _persist: _persist
- }));
- };
- }
- function symbolObservablePonyfill(root) {
- var result;
- var Symbol = root.Symbol;
- if (typeof Symbol === 'function') {
- if (Symbol.observable) {
- result = Symbol.observable;
- } else {
- result = Symbol('observable');
- Symbol.observable = result;
- }
- } else {
- result = '@@observable';
- }
- return result;
- }
- /* global window */
- var root;
- if (typeof self !== 'undefined') {
- root = self;
- } else if (typeof window !== 'undefined') {
- root = window;
- } else if (typeof global !== 'undefined') {
- root = global;
- } else if (typeof module !== 'undefined') {
- root = module;
- } else {
- root = Function('return this')();
- }
- var result = symbolObservablePonyfill(root);
- /**
- * These are private action types reserved by Redux.
- * For any unknown actions, you must return the current state.
- * If the current state is undefined, you must return the initial state.
- * Do not reference these action types directly in your code.
- */
- var randomString = function randomString() {
- return Math.random().toString(36).substring(7).split('').join('.');
- };
- var ActionTypes = {
- INIT: "@@redux/INIT" + randomString(),
- REPLACE: "@@redux/REPLACE" + randomString(),
- PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() {
- return "@@redux/PROBE_UNKNOWN_ACTION" + randomString();
- }
- };
- /**
- * @param {any} obj The object to inspect.
- * @returns {boolean} True if the argument appears to be a plain object.
- */
- function isPlainObject(obj) {
- if (typeof obj !== 'object' || obj === null) return false;
- var proto = obj;
- while (Object.getPrototypeOf(proto) !== null) {
- proto = Object.getPrototypeOf(proto);
- }
- return Object.getPrototypeOf(obj) === proto;
- }
- /**
- * Creates a Redux store that holds the state tree.
- * The only way to change the data in the store is to call `dispatch()` on it.
- *
- * There should only be a single store in your app. To specify how different
- * parts of the state tree respond to actions, you may combine several reducers
- * into a single reducer function by using `combineReducers`.
- *
- * @param {Function} reducer A function that returns the next state tree, given
- * the current state tree and the action to handle.
- *
- * @param {any} [preloadedState] The initial state. You may optionally specify it
- * to hydrate the state from the server in universal apps, or to restore a
- * previously serialized user session.
- * If you use `combineReducers` to produce the root reducer function, this must be
- * an object with the same shape as `combineReducers` keys.
- *
- * @param {Function} [enhancer] The store enhancer. You may optionally specify it
- * to enhance the store with third-party capabilities such as middleware,
- * time travel, persistence, etc. The only store enhancer that ships with Redux
- * is `applyMiddleware()`.
- *
- * @returns {Store} A Redux store that lets you read the state, dispatch actions
- * and subscribe to changes.
- */
- function createStore(reducer, preloadedState, enhancer) {
- var _ref2;
- if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') {
- throw new Error('It looks like you are passing several store enhancers to ' + 'createStore(). This is not supported. Instead, compose them ' + 'together to a single function.');
- }
- if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
- enhancer = preloadedState;
- preloadedState = undefined;
- }
- if (typeof enhancer !== 'undefined') {
- if (typeof enhancer !== 'function') {
- throw new Error('Expected the enhancer to be a function.');
- }
- return enhancer(createStore)(reducer, preloadedState);
- }
- if (typeof reducer !== 'function') {
- throw new Error('Expected the reducer to be a function.');
- }
- var currentReducer = reducer;
- var currentState = preloadedState;
- var currentListeners = [];
- var nextListeners = currentListeners;
- var isDispatching = false;
- /**
- * This makes a shallow copy of currentListeners so we can use
- * nextListeners as a temporary list while dispatching.
- *
- * This prevents any bugs around consumers calling
- * subscribe/unsubscribe in the middle of a dispatch.
- */
- function ensureCanMutateNextListeners() {
- if (nextListeners === currentListeners) {
- nextListeners = currentListeners.slice();
- }
- }
- /**
- * Reads the state tree managed by the store.
- *
- * @returns {any} The current state tree of your application.
- */
- function getState() {
- if (isDispatching) {
- throw new Error('You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from the store.');
- }
- return currentState;
- }
- /**
- * Adds a change listener. It will be called any time an action is dispatched,
- * and some part of the state tree may potentially have changed. You may then
- * call `getState()` to read the current state tree inside the callback.
- *
- * You may call `dispatch()` from a change listener, with the following
- * caveats:
- *
- * 1. The subscriptions are snapshotted just before every `dispatch()` call.
- * If you subscribe or unsubscribe while the listeners are being invoked, this
- * will not have any effect on the `dispatch()` that is currently in progress.
- * However, the next `dispatch()` call, whether nested or not, will use a more
- * recent snapshot of the subscription list.
- *
- * 2. The listener should not expect to see all state changes, as the state
- * might have been updated multiple times during a nested `dispatch()` before
- * the listener is called. It is, however, guaranteed that all subscribers
- * registered before the `dispatch()` started will be called with the latest
- * state by the time it exits.
- *
- * @param {Function} listener A callback to be invoked on every dispatch.
- * @returns {Function} A function to remove this change listener.
- */
- function subscribe(listener) {
- if (typeof listener !== 'function') {
- throw new Error('Expected the listener to be a function.');
- }
- if (isDispatching) {
- throw new Error('You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api-reference/store#subscribe(listener) for more details.');
- }
- var isSubscribed = true;
- ensureCanMutateNextListeners();
- nextListeners.push(listener);
- return function unsubscribe() {
- if (!isSubscribed) {
- return;
- }
- if (isDispatching) {
- throw new Error('You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api-reference/store#subscribe(listener) for more details.');
- }
- isSubscribed = false;
- ensureCanMutateNextListeners();
- var index = nextListeners.indexOf(listener);
- nextListeners.splice(index, 1);
- };
- }
- /**
- * Dispatches an action. It is the only way to trigger a state change.
- *
- * The `reducer` function, used to create the store, will be called with the
- * current state tree and the given `action`. Its return value will
- * be considered the **next** state of the tree, and the change listeners
- * will be notified.
- *
- * The base implementation only supports plain object actions. If you want to
- * dispatch a Promise, an Observable, a thunk, or something else, you need to
- * wrap your store creating function into the corresponding middleware. For
- * example, see the documentation for the `redux-thunk` package. Even the
- * middleware will eventually dispatch plain object actions using this method.
- *
- * @param {Object} action A plain object representing “what changed”. It is
- * a good idea to keep actions serializable so you can record and replay user
- * sessions, or use the time travelling `redux-devtools`. An action must have
- * a `type` property which may not be `undefined`. It is a good idea to use
- * string constants for action types.
- *
- * @returns {Object} For convenience, the same action object you dispatched.
- *
- * Note that, if you use a custom middleware, it may wrap `dispatch()` to
- * return something else (for example, a Promise you can await).
- */
- function dispatch(action) {
- if (!isPlainObject(action)) {
- throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.');
- }
- if (typeof action.type === 'undefined') {
- throw new Error('Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?');
- }
- if (isDispatching) {
- throw new Error('Reducers may not dispatch actions.');
- }
- try {
- isDispatching = true;
- currentState = currentReducer(currentState, action);
- } finally {
- isDispatching = false;
- }
- var listeners = currentListeners = nextListeners;
- for (var i = 0; i < listeners.length; i++) {
- var listener = listeners[i];
- listener();
- }
- return action;
- }
- /**
- * Replaces the reducer currently used by the store to calculate the state.
- *
- * You might need this if your app implements code splitting and you want to
- * load some of the reducers dynamically. You might also need this if you
- * implement a hot reloading mechanism for Redux.
- *
- * @param {Function} nextReducer The reducer for the store to use instead.
- * @returns {void}
- */
- function replaceReducer(nextReducer) {
- if (typeof nextReducer !== 'function') {
- throw new Error('Expected the nextReducer to be a function.');
- }
- currentReducer = nextReducer; // This action has a similiar effect to ActionTypes.INIT.
- // Any reducers that existed in both the new and old rootReducer
- // will receive the previous state. This effectively populates
- // the new state tree with any relevant data from the old one.
- dispatch({
- type: ActionTypes.REPLACE
- });
- }
- /**
- * Interoperability point for observable/reactive libraries.
- * @returns {observable} A minimal observable of state changes.
- * For more information, see the observable proposal:
- * https://github.com/tc39/proposal-observable
- */
- function observable() {
- var _ref;
- var outerSubscribe = subscribe;
- return _ref = {
- /**
- * The minimal observable subscription method.
- * @param {Object} observer Any object that can be used as an observer.
- * The observer object should have a `next` method.
- * @returns {subscription} An object with an `unsubscribe` method that can
- * be used to unsubscribe the observable from the store, and prevent further
- * emission of values from the observable.
- */
- subscribe: function subscribe(observer) {
- if (typeof observer !== 'object' || observer === null) {
- throw new TypeError('Expected the observer to be an object.');
- }
- function observeState() {
- if (observer.next) {
- observer.next(getState());
- }
- }
- observeState();
- var unsubscribe = outerSubscribe(observeState);
- return {
- unsubscribe: unsubscribe
- };
- }
- }, _ref[result] = function () {
- return this;
- }, _ref;
- } // When a store is created, an "INIT" action is dispatched so that every
- // reducer returns their initial state. This effectively populates
- // the initial state tree.
- dispatch({
- type: ActionTypes.INIT
- });
- return _ref2 = {
- dispatch: dispatch,
- subscribe: subscribe,
- getState: getState,
- replaceReducer: replaceReducer
- }, _ref2[result] = observable, _ref2;
- }
- /**
- * Prints a warning in the console if it exists.
- *
- * @param {String} message The warning message.
- * @returns {void}
- */
- function warning(message) {
- /* eslint-disable no-console */
- if (typeof console !== 'undefined' && typeof console.error === 'function') {
- console.error(message);
- }
- /* eslint-enable no-console */
- try {
- // This error was thrown as a convenience so that if you enable
- // "break on all exceptions" in your console,
- // it would pause the execution at this line.
- throw new Error(message);
- } catch (e) {} // eslint-disable-line no-empty
- }
- function getUndefinedStateErrorMessage(key, action) {
- var actionType = action && action.type;
- var actionDescription = actionType && "action \"" + String(actionType) + "\"" || 'an action';
- return "Given " + actionDescription + ", reducer \"" + key + "\" returned undefined. " + "To ignore an action, you must explicitly return the previous state. " + "If you want this reducer to hold no value, you can return null instead of undefined.";
- }
- function getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {
- var reducerKeys = Object.keys(reducers);
- var argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';
- if (reducerKeys.length === 0) {
- return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';
- }
- if (!isPlainObject(inputState)) {
- 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('", "') + "\"");
- }
- var unexpectedKeys = Object.keys(inputState).filter(function (key) {
- return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];
- });
- unexpectedKeys.forEach(function (key) {
- unexpectedKeyCache[key] = true;
- });
- if (action && action.type === ActionTypes.REPLACE) return;
- if (unexpectedKeys.length > 0) {
- 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.");
- }
- }
- function assertReducerShape(reducers) {
- Object.keys(reducers).forEach(function (key) {
- var reducer = reducers[key];
- var initialState = reducer(undefined, {
- type: ActionTypes.INIT
- });
- if (typeof initialState === 'undefined') {
- 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. If you don't want to set a value for this reducer, " + "you can use null instead of undefined.");
- }
- if (typeof reducer(undefined, {
- type: ActionTypes.PROBE_UNKNOWN_ACTION()
- }) === 'undefined') {
- throw new Error("Reducer \"" + key + "\" returned undefined when probed with a random type. " + ("Don't try to handle " + 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, but can be null.");
- }
- });
- }
- /**
- * Turns an object whose values are different reducer functions, into a single
- * reducer function. It will call every child reducer, and gather their results
- * into a single state object, whose keys correspond to the keys of the passed
- * reducer functions.
- *
- * @param {Object} reducers An object whose values correspond to different
- * reducer functions that need to be combined into one. One handy way to obtain
- * it is to use ES6 `import * as reducers` syntax. The reducers may never return
- * undefined for any action. Instead, they should return their initial state
- * if the state passed to them was undefined, and the current state for any
- * unrecognized action.
- *
- * @returns {Function} A reducer function that invokes every reducer inside the
- * passed object, and builds a state object with the same shape.
- */
- function combineReducers(reducers) {
- var reducerKeys = Object.keys(reducers);
- var finalReducers = {};
- for (var i = 0; i < reducerKeys.length; i++) {
- var key = reducerKeys[i];
- {
- if (typeof reducers[key] === 'undefined') {
- warning("No reducer provided for key \"" + key + "\"");
- }
- }
- if (typeof reducers[key] === 'function') {
- finalReducers[key] = reducers[key];
- }
- }
- var finalReducerKeys = Object.keys(finalReducers); // This is used to make sure we don't warn about the same
- // keys multiple times.
- var unexpectedKeyCache;
- {
- unexpectedKeyCache = {};
- }
- var shapeAssertionError;
- try {
- assertReducerShape(finalReducers);
- } catch (e) {
- shapeAssertionError = e;
- }
- return function combination(state, action) {
- if (state === void 0) {
- state = {};
- }
- if (shapeAssertionError) {
- throw shapeAssertionError;
- }
- {
- var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache);
- if (warningMessage) {
- warning(warningMessage);
- }
- }
- var hasChanged = false;
- var nextState = {};
- for (var _i = 0; _i < finalReducerKeys.length; _i++) {
- var _key = finalReducerKeys[_i];
- var reducer = finalReducers[_key];
- var previousStateForKey = state[_key];
- var nextStateForKey = reducer(previousStateForKey, action);
- if (typeof nextStateForKey === 'undefined') {
- var errorMessage = getUndefinedStateErrorMessage(_key, action);
- throw new Error(errorMessage);
- }
- nextState[_key] = nextStateForKey;
- hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
- }
- return hasChanged ? nextState : state;
- };
- }
- /*
- * This is a dummy function to check if the function name has been altered by minification.
- * If the function has been minified and NODE_ENV !== 'production', warn the user.
- */
- function isCrushed() {}
- if ("development" !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') {
- warning('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 setting mode to production in webpack (https://webpack.js.org/concepts/mode/) ' + 'to ensure you have the correct code for your production build.');
- }
- /*
- autoMergeLevel2:
- - merges 2 level of substate
- - skips substate if already modified
- - this is essentially redux-perist v4 behavior
- */
- function autoMergeLevel2(inboundState, originalState, reducedState, _ref) {
- var debug = _ref.debug;
- var newState = _objectSpread2({}, reducedState); // only rehydrate if inboundState exists and is an object
- if (inboundState && _typeof(inboundState) === 'object') {
- Object.keys(inboundState).forEach(function (key) {
- // ignore _persist data
- if (key === '_persist') return; // if reducer modifies substate, skip auto rehydration
- if (originalState[key] !== reducedState[key]) {
- if ("development" !== 'production' && debug) console.log('redux-persist/stateReconciler: sub state for key `%s` modified, skipping.', key);
- return;
- }
- if (isPlainEnoughObject(reducedState[key])) {
- // if object is plain enough shallow merge the new values (hence "Level2")
- newState[key] = _objectSpread2({}, newState[key], {}, inboundState[key]);
- return;
- } // otherwise hard set
- newState[key] = inboundState[key];
- });
- }
- if ("development" !== 'production' && debug && inboundState && _typeof(inboundState) === 'object') console.log("redux-persist/stateReconciler: rehydrated keys '".concat(Object.keys(inboundState).join(', '), "'"));
- return newState;
- }
- function isPlainEnoughObject(o) {
- return o !== null && !Array.isArray(o) && _typeof(o) === 'object';
- }
- // combineReducers + persistReducer with stateReconciler defaulted to autoMergeLevel2
- function persistCombineReducers(config, reducers) {
- config.stateReconciler = config.stateReconciler === undefined ? autoMergeLevel2 : config.stateReconciler;
- return persistReducer(config, combineReducers(reducers));
- }
- var initialState = {
- registry: [],
- bootstrapped: false
- };
- var persistorReducer = function persistorReducer() {
- var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
- var action = arguments.length > 1 ? arguments[1] : undefined;
- switch (action.type) {
- case REGISTER:
- return _objectSpread2({}, state, {
- registry: [].concat(_toConsumableArray(state.registry), [action.key])
- });
- case REHYDRATE:
- var firstIndex = state.registry.indexOf(action.key);
- var registry = _toConsumableArray(state.registry);
- registry.splice(firstIndex, 1);
- return _objectSpread2({}, state, {
- registry: registry,
- bootstrapped: registry.length === 0
- });
- default:
- return state;
- }
- };
- function persistStore(store, options, cb) {
- // help catch incorrect usage of passing PersistConfig in as PersistorOptions
- {
- var optionsToTest = options || {};
- var bannedKeys = ['blacklist', 'whitelist', 'transforms', 'storage', 'keyPrefix', 'migrate'];
- bannedKeys.forEach(function (k) {
- if (!!optionsToTest[k]) console.error("redux-persist: invalid option passed to persistStore: \"".concat(k, "\". You may be incorrectly passing persistConfig into persistStore, whereas it should be passed into persistReducer."));
- });
- }
- var boostrappedCb = cb || false;
- var _pStore = createStore(persistorReducer, initialState, options && options.enhancer ? options.enhancer : undefined);
- var register = function register(key) {
- _pStore.dispatch({
- type: REGISTER,
- key: key
- });
- };
- var rehydrate = function rehydrate(key, payload, err) {
- var rehydrateAction = {
- type: REHYDRATE,
- payload: payload,
- err: err,
- key: key // dispatch to `store` to rehydrate and `persistor` to track result
- };
- store.dispatch(rehydrateAction);
- _pStore.dispatch(rehydrateAction);
- if (boostrappedCb && persistor.getState().bootstrapped) {
- boostrappedCb();
- boostrappedCb = false;
- }
- };
- var persistor = _objectSpread2({}, _pStore, {
- purge: function purge() {
- var results = [];
- store.dispatch({
- type: PURGE,
- result: function result(purgeResult) {
- results.push(purgeResult);
- }
- });
- return Promise.all(results);
- },
- flush: function flush() {
- var results = [];
- store.dispatch({
- type: FLUSH,
- result: function result(flushResult) {
- results.push(flushResult);
- }
- });
- return Promise.all(results);
- },
- pause: function pause() {
- store.dispatch({
- type: PAUSE
- });
- },
- persist: function persist() {
- store.dispatch({
- type: PERSIST,
- register: register,
- rehydrate: rehydrate
- });
- }
- });
- if (!(options && options.manualPersist)) {
- persistor.persist();
- }
- return persistor;
- }
- function createMigrate(migrations, config) {
- var _ref = config || {},
- debug = _ref.debug;
- return function (state, currentVersion) {
- if (!state) {
- if ("development" !== 'production' && debug) console.log('redux-persist: no inbound state, skipping migration');
- return Promise.resolve(undefined);
- }
- var inboundVersion = state._persist && state._persist.version !== undefined ? state._persist.version : DEFAULT_VERSION;
- if (inboundVersion === currentVersion) {
- if ("development" !== 'production' && debug) console.log('redux-persist: versions match, noop migration');
- return Promise.resolve(state);
- }
- if (inboundVersion > currentVersion) {
- console.error('redux-persist: downgrading version is not supported');
- return Promise.resolve(state);
- }
- var migrationKeys = Object.keys(migrations).map(function (ver) {
- return parseInt(ver);
- }).filter(function (key) {
- return currentVersion >= key && key > inboundVersion;
- }).sort(function (a, b) {
- return a - b;
- });
- if ("development" !== 'production' && debug) console.log('redux-persist: migrationKeys', migrationKeys);
- try {
- var migratedState = migrationKeys.reduce(function (state, versionKey) {
- if ("development" !== 'production' && debug) console.log('redux-persist: running migration for versionKey', versionKey);
- return migrations[versionKey](state);
- }, state);
- return Promise.resolve(migratedState);
- } catch (err) {
- return Promise.reject(err);
- }
- };
- }
- function createTransform( // @NOTE inbound: transform state coming from redux on its way to being serialized and stored
- inbound, // @NOTE outbound: transform state coming from storage, on its way to be rehydrated into redux
- outbound) {
- var config = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
- var whitelist = config.whitelist || null;
- var blacklist = config.blacklist || null;
- function whitelistBlacklistCheck(key) {
- if (whitelist && whitelist.indexOf(key) === -1) return true;
- if (blacklist && blacklist.indexOf(key) !== -1) return true;
- return false;
- }
- return {
- in: function _in(state, key, fullState) {
- return !whitelistBlacklistCheck(key) && inbound ? inbound(state, key, fullState) : state;
- },
- out: function out(state, key, fullState) {
- return !whitelistBlacklistCheck(key) && outbound ? outbound(state, key, fullState) : state;
- }
- };
- }
- exports.persistReducer = persistReducer;
- exports.persistCombineReducers = persistCombineReducers;
- exports.persistStore = persistStore;
- exports.createMigrate = createMigrate;
- exports.createTransform = createTransform;
- exports.getStoredState = getStoredState;
- exports.createPersistoid = createPersistoid;
- exports.purgeStoredState = purgeStoredState;
- exports.KEY_PREFIX = KEY_PREFIX;
- exports.FLUSH = FLUSH;
- exports.REHYDRATE = REHYDRATE;
- exports.PAUSE = PAUSE;
- exports.PERSIST = PERSIST;
- exports.PURGE = PURGE;
- exports.REGISTER = REGISTER;
- exports.DEFAULT_VERSION = DEFAULT_VERSION;
- Object.defineProperty(exports, '__esModule', { value: true });
- })));
- //# sourceMappingURL=redux-persist.js.map
|