A self hosted solution for privately rating and reviewing different sorts of media
at master 95 lines 2.8 kB view raw
1'use client'; 2 3import { QueryClientProvider, type QueryClient } from '@tanstack/react-query'; 4import { 5 httpBatchLink, 6 httpBatchStreamLink, 7 loggerLink, 8 splitLink, 9} from '@trpc/client'; 10import { createTRPCReact } from '@trpc/react-query'; 11import { type inferRouterInputs, type inferRouterOutputs } from '@trpc/server'; 12import { useState } from 'react'; 13import SuperJSON from 'superjson'; 14 15import { type AppRouter } from '@/server/api/root'; 16import { createQueryClient } from './query-client'; 17 18let clientQueryClientSingleton: QueryClient | undefined = undefined; 19const getQueryClient = () => { 20 if (typeof window === 'undefined') { 21 // Server: always make a new query client 22 return createQueryClient(); 23 } 24 // Browser: use singleton pattern to keep the same query client 25 return (clientQueryClientSingleton ??= createQueryClient()); 26}; 27 28export const api = createTRPCReact<AppRouter>(); 29 30/** 31 * Inference helper for inputs. 32 * 33 * @example type HelloInput = RouterInputs['example']['hello'] 34 */ 35export type RouterInputs = inferRouterInputs<AppRouter>; 36 37/** 38 * Inference helper for outputs. 39 * 40 * @example type HelloOutput = RouterOutputs['example']['hello'] 41 */ 42export type RouterOutputs = inferRouterOutputs<AppRouter>; 43 44export function TRPCReactProvider(props: { children: React.ReactNode }) { 45 const queryClient = getQueryClient(); 46 47 const [trpcClient] = useState(() => 48 api.createClient({ 49 links: [ 50 loggerLink({ 51 enabled: op => 52 process.env.NODE_ENV === 'development' || 53 (op.direction === 'down' && op.result instanceof Error), 54 }), 55 splitLink({ 56 condition(op) { 57 return op.path.startsWith('auth.'); 58 }, 59 true: httpBatchLink({ 60 transformer: SuperJSON, 61 url: getBaseUrl() + '/api/trpc', 62 headers() { 63 const headers = new Headers(); 64 headers.set('x-trpc-source', 'react-no-stream'); 65 return headers; 66 }, 67 }), 68 false: httpBatchStreamLink({ 69 transformer: SuperJSON, 70 url: getBaseUrl() + '/api/trpc', 71 headers() { 72 const headers = new Headers(); 73 headers.set('x-trpc-source', 'react-stream'); 74 return headers; 75 }, 76 }), 77 }), 78 ], 79 }) 80 ); 81 82 return ( 83 <QueryClientProvider client={queryClient}> 84 <api.Provider client={trpcClient} queryClient={queryClient}> 85 {props.children} 86 </api.Provider> 87 </QueryClientProvider> 88 ); 89} 90 91function getBaseUrl() { 92 if (typeof window !== 'undefined') return window.location.origin; 93 if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`; 94 return `http://localhost:${process.env.PORT ?? 3000}`; 95}