import { QueryClient } from '@tanstack/react-query' import { match } from 'path-to-regexp' import { fetchPost, fetchPosts } from '@/lib/posts' type Prefetcher = (qc: QueryClient, url: URL) => Promise const mPost = match<{ id: string }> ('/posts/:id') const prefetchPostsIndex: Prefetcher = async (qc, url) => { const tags = url.searchParams.get ('tags') ?? '' const match = url.searchParams.get ('match') === 'any' ? 'any' : 'all' const limit = Number (url.searchParams.get ('limit') || 20) await qc.prefetchQuery ({ queryKey: ['posts', 'index', { tags, match, limit }], queryFn: () => fetchPosts ({ tags, match, limit }) }) } const prefetchPostShow: Prefetcher = async (qc, url) => { const m = mPost (url.pathname) if (!(m)) return const { id } = m.params await qc.prefetchQuery ({ queryKey: ['posts', id], queryFn: () => fetchPost (id) }) } export const routePrefetchers: { test: (u: URL) => boolean; run: Prefetcher }[] = [ { test: u => u.pathname === '/' || u.pathname === '/posts', run: prefetchPostsIndex }, { test: u => Boolean (mPost (u.pathname)), run: prefetchPostShow }] export const prefetchForURL = async (qc: QueryClient, urlLike: string): Promise => { const u = new URL (urlLike, location.origin) const jobs = routePrefetchers.filter (r => r.test (u)).map (r => r.run (qc, u)) if (jobs.length === 0) return await Promise.all (jobs) }