UNPKG

redux-persist

Version:

persist and rehydrate redux stores

111 lines (92 loc) 3.23 kB
'use strict'; exports.__esModule = true; exports.default = createPersistoid; var _constants = require('./constants'); // @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 = '' + (config.keyPrefix !== undefined ? config.keyPrefix : _constants.KEY_PREFIX) + config.key; var storage = config.storage; var serialize = config.serialize === false ? function (x) { return x; } : defaultSerialize; // 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) { var subState = state[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 }); // 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 (typeof endState !== 'undefined') stagedWrite(key, endState); } function stagedWrite(key, endState) { try { stagedState[key] = serialize(endState); } catch (err) { console.error('redux-persist/createPersistoid: error serializing state', err); } if (keysToProcess.length === 0) { // 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 (err && process.env.NODE_ENV !== '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); }