-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
138 lines (125 loc) · 3.15 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
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
127
128
129
130
131
132
133
134
135
136
137
138
import storage from 'react-native-modest-storage'
const prefix = 'cache-'
const expire = 'cache-expire-'
/**
* Utility function to add units to date based on interval
* @param {Date} date
* @param {String} interval
* @param {Number} units
*/
function dateAdd (date, interval, units) {
let result = new Date(date)
switch (interval.toLowerCase()) {
case 'year':
result.setFullYear(result.getFullYear() + units)
break
case 'quarter':
result.setMonth(result.getMonth() + 3 * units)
break
case 'month':
result.setMonth(result.getMonth() + units)
break
case 'week':
result.setDate(result.getDate() + 7 * units)
break
case 'day':
result.setDate(result.getDate() + units)
break
case 'hour':
result.setTime(result.getTime() + units * 3600000)
break
case 'minute':
result.setTime(result.getTime() + units * 60000)
break
case 'second':
result.setTime(result.getTime() + units * 1000)
break
default:
result = undefined
break
}
return result
}
/**
* Persist value and expire date of cache.
*
* @param {string} key
* @param {Any} value Value to persist
* @param {Number or Object} [time=60] Time in minutes
* @returns {Promise}
*/
function set (key, value, time = 60) {
let expireTime
const cacheKey = `${prefix}${key}`
const expireKey = `${expire}${key}`
if (typeof time === 'number') {
expireTime = dateAdd(Date.now(), 'minute', time)
} else if (time !== null && typeof time === 'object' && time.interval && time.units) {
expireTime = dateAdd(Date.now(), time.interval, time.units)
} else {
throw new Error('Invalid time provided for set')
}
return storage.set(expireKey, expireTime).then(() => storage.set(cacheKey, value))
}
/**
* Remove cached value from storage
* @param {String} key
*/
function remove (key) {
if (typeof key !== 'string') {
throw new Error('Invalid key provided for remove')
}
const keys = [`${prefix}${key}`, `${expire}${key}`]
return storage.remove(keys)
}
/**
* Determine if cache has expired
* @param {String} key
*/
function isExpired (key) {
const expireKey = `${expire}${key}`
return storage
.get(expireKey)
.then(time => Promise.resolve(Date.now() >= new Date(time).getTime(), time))
}
/**
* Retrieve value from cache. Remove if expired.
* @param {String} key
*/
function get (key) {
return isExpired(key).then(hasExpired => {
if (hasExpired) {
return remove(key).then(() => Promise.resolve(undefined))
} else {
return storage.get(`${prefix}${key}`)
}
})
}
/**
* Remove all cached values from storage
*/
function flush () {
return storage.keys().then(keys => {
return storage.remove(
keys.filter(key => key.indexOf(prefix) === 0 || key.indexOf(expire) === 0)
)
})
}
/**
* Remove all expired values from storage
*/
function flushExpired () {
return storage.keys().then(keys => {
const cacheKeys = keys.filter(key => key.indexOf(expire) === 0)
return Promise.all(cacheKeys.map(key => get(key.slice(prefix.length))))
})
}
export default {
set,
get,
remove,
isExpired,
flush,
flushExpired,
storage
}