forked from vercel/swr
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.ts
More file actions
115 lines (99 loc) · 2.51 KB
/
config.ts
File metadata and controls
115 lines (99 loc) · 2.51 KB
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
import ms from 'ms'
import isDocumentVisible from './libs/is-document-visible'
import isOnline from './libs/is-online'
import {
ConfigInterface,
revalidateType,
RevalidateOptionInterface
} from './types'
// Cache
const __cache = new Map()
function cacheGet(key: string): any {
return __cache.get(key) || undefined
}
function cacheSet(key: string, value: any) {
return __cache.set(key, value)
}
function cacheClear() {
__cache.clear()
}
// state managers
const CONCURRENT_PROMISES = {}
const CONCURRENT_PROMISES_TS = {}
const FOCUS_REVALIDATORS = {}
const CACHE_REVALIDATORS = {}
const MUTATION_TS = {}
// error retry
function onErrorRetry(
_,
__,
config: ConfigInterface,
revalidate: revalidateType,
opts: RevalidateOptionInterface
): void {
if (!isDocumentVisible()) {
// if it's hidden, stop
// it will auto revalidate when focus
return
}
// exponential backoff
const count = Math.min(opts.retryCount || 0, 8)
const timeout =
~~((Math.random() + 0.5) * (1 << count)) * config.errorRetryInterval
setTimeout(revalidate, timeout, opts)
}
// config
const defaultConfig: ConfigInterface = {
// events
onLoadingSlow: () => {},
onSuccess: () => {},
onError: () => {},
onErrorRetry,
errorRetryInterval: ms('5s'),
focusThrottleInterval: ms('5s'),
dedupingInterval: ms('2s'),
loadingTimeout: ms('3s'),
refreshInterval: 0,
revalidateOnFocus: true,
refreshWhenHidden: false,
shouldRetryOnError: true,
suspense: false
}
if (typeof window !== 'undefined') {
// client side: need to adjust the config
// based on the browser status
// slow connection (<= 70Kbps)
if (navigator['connection']) {
if (
['slow-2g', '2g'].indexOf(navigator['connection'].effectiveType) !== -1
) {
defaultConfig.errorRetryInterval = ms('10s')
defaultConfig.loadingTimeout = ms('5s')
}
}
}
// Focus revalidate
let eventsBinded = false
if (typeof window !== 'undefined' && window.addEventListener && !eventsBinded) {
const revalidate = () => {
if (!isDocumentVisible() || !isOnline()) return
for (let key in FOCUS_REVALIDATORS) {
if (FOCUS_REVALIDATORS[key][0]) FOCUS_REVALIDATORS[key][0]()
}
}
window.addEventListener('visibilitychange', revalidate, false)
window.addEventListener('focus', revalidate, false)
// only bind the events once
eventsBinded = true
}
export {
CONCURRENT_PROMISES,
CONCURRENT_PROMISES_TS,
FOCUS_REVALIDATORS,
CACHE_REVALIDATORS,
MUTATION_TS,
cacheGet,
cacheSet,
cacheClear
}
export default defaultConfig