123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- // @flow
- import type {
- Persistor,
- PersistConfig,
- PersistorOptions,
- PersistorState,
- MigrationManifest,
- RehydrateAction,
- RehydrateErrorType,
- } from './types'
- import { createStore } from 'redux'
- import { FLUSH, PAUSE, PERSIST, PURGE, REGISTER, REHYDRATE } from './constants'
- type PendingRehydrate = [Object, RehydrateErrorType, PersistConfig]
- type Persist = <R>(PersistConfig, MigrationManifest) => R => R
- type CreatePersistor = Object => void
- type BoostrappedCb = () => any
- const initialState: PersistorState = {
- registry: [],
- bootstrapped: false,
- }
- const persistorReducer = (state = initialState, action) => {
- switch (action.type) {
- case REGISTER:
- return { ...state, registry: [...state.registry, action.key] }
- case REHYDRATE:
- let firstIndex = state.registry.indexOf(action.key)
- let registry = [...state.registry]
- registry.splice(firstIndex, 1)
- return { ...state, registry, bootstrapped: registry.length === 0 }
- default:
- return state
- }
- }
- export default function persistStore(
- store: Object,
- options?: ?PersistorOptions,
- cb?: BoostrappedCb
- ): Persistor {
- // help catch incorrect usage of passing PersistConfig in as PersistorOptions
- if (process.env.NODE_ENV !== 'production') {
- let optionsToTest: Object = options || {}
- let bannedKeys = [
- 'blacklist',
- 'whitelist',
- 'transforms',
- 'storage',
- 'keyPrefix',
- 'migrate',
- ]
- bannedKeys.forEach(k => {
- if (!!optionsToTest[k])
- console.error(
- `redux-persist: invalid option passed to persistStore: "${k}". You may be incorrectly passing persistConfig into persistStore, whereas it should be passed into persistReducer.`
- )
- })
- }
- let boostrappedCb = cb || false
- let _pStore = createStore(
- persistorReducer,
- initialState,
- options && options.enhancer ? options.enhancer : undefined
- )
- let register = (key: string) => {
- _pStore.dispatch({
- type: REGISTER,
- key,
- })
- }
- let rehydrate = (key: string, payload: Object, err: any) => {
- let rehydrateAction = {
- type: REHYDRATE,
- payload,
- err,
- 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
- }
- }
- let persistor: Persistor = {
- ..._pStore,
- purge: () => {
- let results = []
- store.dispatch({
- type: PURGE,
- result: purgeResult => {
- results.push(purgeResult)
- },
- })
- return Promise.all(results)
- },
- flush: () => {
- let results = []
- store.dispatch({
- type: FLUSH,
- result: flushResult => {
- results.push(flushResult)
- },
- })
- return Promise.all(results)
- },
- pause: () => {
- store.dispatch({
- type: PAUSE,
- })
- },
- persist: () => {
- store.dispatch({ type: PERSIST, register, rehydrate })
- },
- }
- if (!(options && options.manualPersist)){
- persistor.persist()
- }
- return persistor
- }
|