A third party ATProto appview
1import { QueryClient, QueryFunction } from '@tanstack/react-query';
2import { api } from './api';
3
4type UnauthorizedBehavior = 'returnNull' | 'throw';
5
6export const getQueryFn =
7 <T>(options?: { on401?: UnauthorizedBehavior }): QueryFunction<T> =>
8 async ({ queryKey }) => {
9 const url = queryKey.join('/');
10 try {
11 const data = await api.get<T>(url);
12 return data;
13 } catch (error: unknown) {
14 const err = error as { response?: { status?: number } };
15 if (options?.on401 === 'returnNull' && err.response?.status === 401) {
16 return null as T;
17 }
18 // Re-throw other errors to be handled by React Query
19 throw error;
20 }
21 };
22
23export const queryClient = new QueryClient({
24 defaultOptions: {
25 queries: {
26 queryFn: getQueryFn({ on401: 'throw' }),
27 refetchInterval: false,
28 refetchOnWindowFocus: false,
29 staleTime: Infinity,
30 retry: (failureCount, error: unknown) => {
31 const err = error as { response?: { status?: number } };
32 if (
33 err.response?.status === 401 ||
34 err.response?.status === 403 ||
35 err.response?.status === 404
36 ) {
37 return false;
38 }
39 return failureCount < 2;
40 },
41 },
42 mutations: {
43 retry: false,
44 },
45 },
46});