-
Notifications
You must be signed in to change notification settings - Fork 7
/
useSSR.ts
53 lines (42 loc) · 1.44 KB
/
useSSR.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
interface UseSSRReturn {
isBrowser: boolean
isServer: boolean
isNative: boolean
device: Device
canUseWorkers: boolean
canUseEventListeners: boolean
canUseViewport: boolean
}
export enum Device {
Browser = 'browser',
Server = 'server',
Native = 'native',
}
const { Browser, Server, Native } = Device
const canUseDOM: boolean = !!(
typeof window !== 'undefined' &&
window.document &&
window.document.createElement
)
const canUseNative: boolean = typeof navigator != 'undefined' && navigator.product == 'ReactNative'
const device = canUseNative ? Native : canUseDOM ? Browser : Server
const SSRObject = {
isBrowser: device === Browser,
isServer: device === Server,
isNative: device === Native,
device,
canUseWorkers: typeof Worker !== 'undefined',
canUseEventListeners: device === Browser && !!window.addEventListener,
canUseViewport: device === Browser && !!window.screen,
}
// TODO: instead of this, do a polyfill for `Object.assign` https://www.npmjs.com/package/es6-object-assign
const assign = (...args: any[]) => args.reduce((acc, obj) => ({ ...acc, ...obj }), {})
const values = (obj: any) => Object.keys(obj).map(key => obj[key])
const toArrayObject = (): UseSSRReturn => assign((values(SSRObject), SSRObject))
let useSSRObject = toArrayObject()
export const weAreServer = () => {
SSRObject.isServer = true
useSSRObject = toArrayObject()
}
export const useSSR = (): UseSSRReturn => useSSRObject
export default useSSR