-
-
Notifications
You must be signed in to change notification settings - Fork 427
Expand file tree
/
Copy pathuseCachedFetch.ts
More file actions
99 lines (91 loc) · 2.63 KB
/
useCachedFetch.ts
File metadata and controls
99 lines (91 loc) · 2.63 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
import type { H3Event } from 'h3'
/**
* Type for the cachedFetch function attached to event context.
*/
export type CachedFetchFunction = <T = unknown>(
url: string,
options?: {
method?: string
body?: unknown
headers?: Record<string, string>
},
ttl?: number,
) => Promise<T>
/**
* Get the cachedFetch function from the current request context.
*
* IMPORTANT: This must be called in the composable setup context (outside of
* useAsyncData handlers). The returned function can then be used inside handlers.
*
* @example
* ```ts
* export function usePackage(name: MaybeRefOrGetter<string>) {
* // Get cachedFetch in setup context
* const cachedFetch = useCachedFetch()
*
* return useLazyAsyncData(
* () => `package:${toValue(name)}`,
* // Use it inside the handler
* () => cachedFetch<Packument>(`https://registry.npmjs.org/${toValue(name)}`)
* )
* }
* ```
*/
export function useCachedFetch(): CachedFetchFunction {
// On client, return a function that just uses $fetch
if (import.meta.client) {
return async <T = unknown>(
url: string,
options: {
method?: string
body?: unknown
headers?: Record<string, string>
} = {},
_ttl?: number,
): Promise<T> => {
return (await $fetch(url, options as Parameters<typeof $fetch>[1])) as T
}
}
// On server, get the cachedFetch from request context
const event = useRequestEvent()
const serverCachedFetch = event?.context?.cachedFetch
// If cachedFetch is available from middleware, return it
if (serverCachedFetch) {
return serverCachedFetch as CachedFetchFunction
}
// Fallback: return a function that uses regular $fetch
// (shouldn't happen in normal operation)
return async <T = unknown>(
url: string,
options: {
method?: string
body?: unknown
headers?: Record<string, string>
} = {},
_ttl?: number,
): Promise<T> => {
return (await $fetch(url, options as Parameters<typeof $fetch>[1])) as T
}
}
/**
* Create a cachedFetch function from an H3Event.
* Useful when you have direct access to the event.
*/
export function getCachedFetchFromEvent(event: H3Event | undefined): CachedFetchFunction {
const serverCachedFetch = event?.context?.cachedFetch
if (serverCachedFetch) {
return serverCachedFetch as CachedFetchFunction
}
// Fallback to regular $fetch
return async <T = unknown>(
url: string,
options: {
method?: string
body?: unknown
headers?: Record<string, string>
} = {},
_ttl?: number,
): Promise<T> => {
return (await $fetch(url, options as Parameters<typeof $fetch>[1])) as T
}
}