-
Notifications
You must be signed in to change notification settings - Fork 864
/
Copy pathpersistStore.ts
126 lines (115 loc) · 3.1 KB
/
persistStore.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* eslint-disable @typescript-eslint/no-explicit-any */
import type {
Persistor,
PersistorOptions,
PersistorState,
} from './types'
import { AnyAction, createStore, Store } from 'redux'
import { FLUSH, PAUSE, PERSIST, PURGE, REGISTER, REHYDRATE } from './constants'
type BoostrappedCb = () => any;
const initialState: PersistorState = {
registry: [],
bootstrapped: false,
}
const persistorReducer = (state = initialState, action: AnyAction) => {
const firstIndex = state.registry.indexOf(action.key)
const registry = [...state.registry]
switch (action.type) {
case REGISTER:
return { ...state, registry: [...state.registry, action.key] }
case REHYDRATE:
registry.splice(firstIndex, 1)
return { ...state, registry, bootstrapped: registry.length === 0 }
default:
return state
}
}
interface OptionToTestObject {
[key: string]: any;
}
export default function persistStore(
store: Store,
options?: PersistorOptions,
cb?: BoostrappedCb
): Persistor {
// help catch incorrect usage of passing PersistConfig in as PersistorOptions
if (process.env.NODE_ENV !== 'production') {
const optionsToTest: OptionToTestObject = options || {}
const 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
const _pStore = createStore(
persistorReducer,
initialState,
options && options.enhancer ? options.enhancer : undefined
)
const register = (key: string) => {
_pStore.dispatch({
type: REGISTER,
key,
})
}
const rehydrate = (key: string, payload: Record<string, unknown>, err: any) => {
const rehydrateAction = {
type: REHYDRATE,
payload,
err,
key,
}
// dispatch to `store` to rehydrate and `persistor` to track result
store.dispatch(rehydrateAction)
_pStore.dispatch(rehydrateAction)
if (typeof boostrappedCb === "function" && persistor.getState().bootstrapped) {
boostrappedCb()
boostrappedCb = false
}
}
const persistor: Persistor = {
..._pStore,
purge: () => {
const results: Array<any> = []
store.dispatch({
type: PURGE,
result: (purgeResult: any) => {
results.push(purgeResult)
},
})
return Promise.all(results)
},
flush: () => {
const results: Array<any> = []
store.dispatch({
type: FLUSH,
result: (flushResult: any) => {
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
}