-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathindex.js
78 lines (69 loc) · 2.14 KB
/
index.js
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
/**
* Storeon module to persist state to local storage
*
* @param {(String|RegExp)[]} paths The keys of state object
* that will be store in local storage
* @param {Object} config The config object
* @param {String} [config.key='storeon'] The default key
* to use in local storage
* @param {Storage} [config.storage] Can be set as `sessionStorage` or
* `localStorage`. Defaults value is `localStorage`.
* @param {Function} [config.serializer] Function that will serialize
* your data. Should take object as an argument. Defaults to `JSON.stringify`
* @param {Function} [config.deserializer] Function that will deserialize
* your data. Should take string as an argument. Defaults to `JSON.parse`
*/
let persistState = (paths, config) => {
config = config || {}
paths = paths || []
if (typeof window === 'undefined') return
let key = config.key || 'storeon'
let storage = config.storage || localStorage
let serializer = config.serializer || JSON.stringify
let deserializer = config.deserializer || JSON.parse
let onChange = state => {
if (paths.length) {
state = filterState(state, paths)
}
let saveState
try {
saveState = serializer(state)
} catch (err) {
return
}
storage.setItem(key, saveState)
}
let event = Symbol('persistState')
return store => {
store.on(event, (_, serializedState) => {
try {
return deserializer(serializedState)
} catch (err) {}
})
store.on('@init', () => {
store.on('@changed', onChange)
let savedState = storage.getItem(key)
if (savedState) {
if (typeof savedState.then === 'function') {
savedState.then(value => store.dispatch(event, value))
} else {
try {
return deserializer(savedState)
} catch (err) {}
}
}
})
}
}
let filterState = (state, paths) => {
let filteredState = {}
for (let key in state) {
for (let condition of paths) {
if ((condition.test && condition.test(key)) || condition === key) {
filteredState[key] = state[key]
}
}
}
return filteredState
}
module.exports = { persistState }