UNPKG

redux-persist-2

Version:

persist and rehydrate redux stores

208 lines (170 loc) 6.63 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _forEach2 = require('lodash/forEach'); var _forEach3 = _interopRequireDefault(_forEach2); 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.default = createPersistor; var _constants = require('./constants'); var constants = _interopRequireWildcard(_constants); var _asyncLocalStorage = require('./defaults/asyncLocalStorage'); var _asyncLocalStorage2 = _interopRequireDefault(_asyncLocalStorage); var _jsonStringifySafe = require('json-stringify-safe'); var _jsonStringifySafe2 = _interopRequireDefault(_jsonStringifySafe); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function createPersistor(store, config) { // defaults var lastStateInit = config.lastStateInit || {}; var stateIterator = config.stateIterator || defaultStateIterator; var stateGetter = config.stateGetter || defaultStateGetter; var stateSetter = config.stateSetter || defaultStateSetter; var serialize = config.serialize || defaultSerialize; var deserialize = config.deserialize || defaultDeserialize; var blacklist = config.blacklist || []; var whitelist = config.whitelist || false; var transforms = config.transforms || []; var debounce = config.debounce || false; var storage = config.storage || (0, _asyncLocalStorage2.default)('local'); // fallback getAllKeys to `keys` if present (LocalForage compatability) if (storage.keys && !storage.getAllKeys) storage = _extends({}, storage, { getAllKeys: storage.keys }); // initialize stateful values var lastState = lastStateInit; var paused = false; var purgeMode = false; var storesToProcess = []; var timeIterator = null; store.subscribe(function () { if (paused) return; var state = store.getState(); stateIterator(state, function (subState, key) { if (!passWhitelistBlacklist(key)) return; if (stateGetter(lastState, key) === stateGetter(state, key)) return; if (storesToProcess.indexOf(key) !== -1) return; storesToProcess.push(key); }); // time iterator (read: debounce) if (timeIterator === null) { timeIterator = setInterval(function () { if (storesToProcess.length === 0) { clearInterval(timeIterator); timeIterator = null; return; } var key = storesToProcess[0]; var storageKey = createStorageKey(key); var endState = transforms.reduce(function (subState, transformer) { return transformer.in(subState, key); }, stateGetter(store.getState(), key)); if (typeof endState !== 'undefined') storage.setItem(storageKey, serialize(endState), warnIfSetError(key)); storesToProcess.shift(); }, debounce); } lastState = state; }); function passWhitelistBlacklist(key) { if (whitelist && whitelist.indexOf(key) === -1) return false; if (blacklist.indexOf(key) !== -1) return false; return true; } function adhocRehydrate(incoming) { var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var state = {}; if (options.serial) { (0, _forEach3.default)(incoming, function (subState, key) { try { var data = deserialize(subState); var value = transforms.reduceRight(function (interState, transformer) { return transformer.out(interState, key); }, data); state = stateSetter(state, key, value); } catch (err) { if (process.env.NODE_ENV !== 'production') console.warn('Error rehydrating data for key "' + key + '"', subState, err); } }); } else state = incoming; store.dispatch(rehydrateAction(state)); return state; } function purge(keys) { if (typeof keys === 'undefined') { purgeAll(); } else { purgeMode = keys; (0, _forEach3.default)(keys, function (key) { storage.removeItem(createStorageKey(key), warnIfRemoveError(key)); }); } } function purgeAll() { purgeMode = '*'; storage.getAllKeys(function (err, allKeys) { if (err && process.env.NODE_ENV !== 'production') { console.warn('Error in storage.getAllKeys'); } purge(allKeys.filter(function (key) { return key.indexOf(constants.keyPrefix) === 0; }).map(function (key) { return key.slice(constants.keyPrefix.length); })); }); } // return `persistor` return { rehydrate: adhocRehydrate, pause: function pause() { paused = true; }, resume: function resume() { paused = false; }, purge: purge, purgeAll: purgeAll, _getPurgeMode: function _getPurgeMode() { return purgeMode; } }; } function warnIfRemoveError(key) { return function removeError(err) { if (err && process.env.NODE_ENV !== 'production') { console.warn('Error storing data for key:', key, err); } }; } function warnIfSetError(key) { return function setError(err) { if (err && process.env.NODE_ENV !== 'production') { console.warn('Error storing data for key:', key, err); } }; } function createStorageKey(key) { return constants.keyPrefix + key; } function defaultSerialize(data) { return (0, _jsonStringifySafe2.default)(data, null, null, function (k, v) { if (process.env.NODE_ENV !== 'production') return null; throw new Error('\n redux-persist: cannot process cyclical state.\n Consider changing your state structure to have no cycles.\n Alternatively blacklist the corresponding reducer key.\n Cycle encounted at key "' + k + '" with value "' + v + '".\n '); }); } function defaultDeserialize(serial) { return JSON.parse(serial); } function rehydrateAction(data) { return { type: constants.REHYDRATE, payload: data }; } function defaultStateIterator(collection, callback) { return (0, _forEach3.default)(collection, callback); } function defaultStateGetter(state, key) { return state[key]; } function defaultStateSetter(state, key, value) { state[key] = value; return state; }