123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- // @flow
- import getStoredStateV5 from '../getStoredState'
- import type { PersistConfig, Transform } from '../types'
- type V4Config = {
- storage?: Object,
- serialize: boolean,
- keyPrefix?: string,
- transforms?: Array<Transform>,
- blacklist?: Array<string>,
- whitelist?: Array<string>,
- }
- export default function getStoredState(v4Config: V4Config) {
- return function(v5Config: PersistConfig) {
- return getStoredStateV5(v5Config).then(state => {
- if (state) return state
- else return getStoredStateV4(v4Config)
- })
- }
- }
- const KEY_PREFIX = 'reduxPersist:'
- function hasLocalStorage() {
- if (typeof self !== 'object' || !('localStorage' in self)) {
- return false
- }
- try {
- let storage = self.localStorage
- const testKey = `redux-persist localStorage test`
- storage.setItem(testKey, 'test')
- storage.getItem(testKey)
- storage.removeItem(testKey)
- } catch (e) {
- if (process.env.NODE_ENV !== 'production')
- console.warn(
- `redux-persist localStorage test failed, persistence will be disabled.`
- )
- return false
- }
- return true
- }
- let noop = (...args: any) => {
- /* noop */ return null
- }
- const noStorage = {
- getItem: noop,
- setItem: noop,
- removeItem: noop,
- getAllKeys: noop,
- }
- const createAsyncLocalStorage = () => {
- if (!hasLocalStorage()) return noStorage
- let localStorage = self.localStorage
- return {
- getAllKeys: function(cb) {
- try {
- var keys = []
- for (var i = 0; i < localStorage.length; i++) {
- keys.push(localStorage.key(i))
- }
- cb(null, keys)
- } catch (e) {
- cb(e)
- }
- },
- getItem(key, cb) {
- try {
- var s = localStorage.getItem(key)
- cb(null, s)
- } catch (e) {
- cb(e)
- }
- },
- setItem(key, string, cb) {
- try {
- localStorage.setItem(key, string)
- cb(null)
- } catch (e) {
- cb(e)
- }
- },
- removeItem(key, cb) {
- try {
- localStorage.removeItem(key)
- cb && cb(null)
- } catch (e) {
- cb(e)
- }
- },
- }
- }
- function getStoredStateV4(v4Config: V4Config) {
- return new Promise((resolve, reject) => {
- let storage = v4Config.storage || createAsyncLocalStorage()
- const deserializer =
- v4Config.serialize === false
- ? data => data
- : (serial: string) => JSON.parse(serial)
- const blacklist = v4Config.blacklist || []
- const whitelist = v4Config.whitelist || false
- const transforms = v4Config.transforms || []
- const keyPrefix =
- v4Config.keyPrefix !== undefined ? v4Config.keyPrefix : KEY_PREFIX
- // fallback getAllKeys to `keys` if present (LocalForage compatability)
- if (storage.keys && !storage.getAllKeys)
- storage = { ...storage, getAllKeys: storage.keys }
- let restoredState = {}
- let completionCount = 0
- storage.getAllKeys((err, allKeys = []) => {
- if (err) {
- if (process.env.NODE_ENV !== 'production')
- console.warn(
- 'redux-persist/getStoredState: Error in storage.getAllKeys'
- )
- return reject(err)
- }
- let persistKeys = allKeys
- .filter(key => key.indexOf(keyPrefix) === 0)
- .map(key => key.slice(keyPrefix.length))
- let keysToRestore = persistKeys.filter(passWhitelistBlacklist)
- let restoreCount = keysToRestore.length
- if (restoreCount === 0) resolve(undefined)
- keysToRestore.forEach(key => {
- storage.getItem(createStorageKey(key), (err, serialized) => {
- if (err && process.env.NODE_ENV !== 'production')
- console.warn(
- 'redux-persist/getStoredState: Error restoring data for key:',
- key,
- err
- )
- else restoredState[key] = rehydrate(key, serialized)
- completionCount += 1
- if (completionCount === restoreCount) resolve(restoredState)
- })
- })
- })
- function rehydrate(key: string, serialized: ?string) {
- let state = null
- try {
- let data = serialized ? deserializer(serialized) : undefined
- state = transforms.reduceRight((subState, transformer) => {
- return transformer.out(subState, key, {})
- }, data)
- } catch (err) {
- if (process.env.NODE_ENV !== 'production')
- console.warn(
- 'redux-persist/getStoredState: Error restoring data for key:',
- key,
- err
- )
- }
- return state
- }
- function passWhitelistBlacklist(key) {
- if (whitelist && whitelist.indexOf(key) === -1) return false
- if (blacklist.indexOf(key) !== -1) return false
- return true
- }
- function createStorageKey(key) {
- return `${keyPrefix}${key}`
- }
- })
- }
- function defaultDeserializer(serial: string) {
- return JSON.parse(serial)
- }
|