Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 91x 91x 91x 91x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 91x 91x | import { type DefaultOptions, QueryClient } from '@tanstack/react-query'
import { cache } from 'react'
const queryConfig: DefaultOptions = {
queries: {
// Default stale time of 5 minutes
staleTime: 1000 * 60 * 5,
// Retry failed requests once
retry: 1,
// Refetch on window focus in production only
refetchOnWindowFocus: process.env.NODE_ENV === 'production',
},
}
/**
* Creates a new QueryClient instance with default configuration.
* All API routes are expected to be prefixed with /api.
*/
export function createQueryClient() {
return new QueryClient({
defaultOptions: queryConfig,
})
}
/**
* Server-side query client, memoized per-request via React cache().
* Use this in Server Components for SSR data prefetching.
*
* @example
* ```tsx
* // In a Server Component
* const queryClient = getQueryClient()
* await queryClient.prefetchQuery({
* queryKey: ['user', id],
* queryFn: () => getUser(id),
* })
* return (
* <HydrationBoundary state={dehydrate(queryClient)}>
* <ClientComponent />
* </HydrationBoundary>
* )
* ```
*/
export const getQueryClient = cache(() => createQueryClient())
/**
* Helper function to construct API URLs with the /api prefix.
* Use this for consistency when making API calls.
*
* @param path - The API path without the /api prefix (e.g., 'users', 'posts/123')
* @returns The full API URL (e.g., '/api/users', '/api/posts/123')
*
* @example
* ```ts
* const url = apiUrl('users') // '/api/users'
* const url = apiUrl('posts/123') // '/api/posts/123'
* ```
*/
export function apiUrl(path: string): string {
// Remove leading slash if present to avoid double slashes
const cleanPath = path.startsWith('/') ? path.slice(1) : path
return `/api/${cleanPath}`
}
/**
* Wrapper around fetch that automatically prefixes paths with /api.
* Provides a consistent way to make API calls throughout the application.
*
* @param path - The API path without the /api prefix (e.g., 'users', 'posts/123')
* @param options - Standard fetch options (method, headers, body, etc.)
* @returns Promise with the fetch Response
*
* @example
* ```ts
* // GET request
* const response = await api('users')
* const users = await response.json()
*
* // POST request
* const response = await api('users', {
* method: 'POST',
* headers: { 'Content-Type': 'application/json' },
* body: JSON.stringify({ name: 'John' })
* })
* ```
*/
export function api(path: string, options?: RequestInit): Promise<Response> {
return fetch(apiUrl(path), options)
}
|