/
hooks.ts
53 lines (49 loc) · 1.76 KB
/
hooks.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
import { DependencyList, useContext, useEffect, useState } from 'https://esm.sh/react'
import { RouterContext } from './context.ts'
import { AsyncUseDenoError } from './error.ts'
import events from './events.ts'
export function useRouter() {
return useContext(RouterContext)
}
export function useDeno<T = any>(callback: () => (T | Promise<T>), browser?: boolean, deps?: DependencyList) {
const id = arguments[3] // generated by compiler
const { pathname, query } = useRouter()
const [data, setDate] = useState<T>(() => {
const global = window as any
const { _useDenoAsyncData: asyncData } = global
const useDenoUrl = `useDeno://${pathname}?${query.toString()}`
const key = `${useDenoUrl}#${id}`
if (asyncData && key in asyncData) {
return asyncData[key]
} else if (typeof Deno !== 'undefined' && Deno.version.deno) {
const ret = callback()
if (ret instanceof Promise) {
events.emit(useDenoUrl, id, ret.then(data => {
if (asyncData) {
asyncData[key] = data
}
events.emit(useDenoUrl, id, data)
}), true)
throw new AsyncUseDenoError('async useDeno')
} else {
if (asyncData) {
asyncData[key] = ret
}
events.emit(useDenoUrl, id, ret)
return ret
}
}
return global[key] || null
})
useEffect(() => {
if (browser) {
const ret = callback()
if (ret instanceof Promise) {
ret.then(setDate)
} else {
setDate(ret)
}
}
}, deps)
return data
}