43 lines
1.3 KiB
TypeScript
43 lines
1.3 KiB
TypeScript
import { MutationCache, QueryCache, QueryClient } from "@tanstack/react-query";
|
|
import { ApiError } from "@/lib/api";
|
|
import { rememberAuthRequired } from "@/auth/store";
|
|
|
|
export function handleUnauthorized(error: unknown): void {
|
|
if (!(error instanceof ApiError) || error.status !== 401) return;
|
|
if (window.location.pathname === "/login") return;
|
|
rememberAuthRequired(true);
|
|
const current = window.location.pathname + window.location.search;
|
|
window.location.assign(`/login?redirect=${encodeURIComponent(current)}`);
|
|
}
|
|
|
|
function shouldRetry(failureCount: number, error: unknown): boolean {
|
|
if (error instanceof ApiError && error.status >= 400 && error.status < 500 && error.status !== 429) {
|
|
return false;
|
|
}
|
|
return failureCount < 2;
|
|
}
|
|
|
|
function retryDelay(attemptIndex: number, error: unknown): number {
|
|
if (error instanceof ApiError && error.status === 429 && error.retryAfter !== undefined) {
|
|
return error.retryAfter * 1000;
|
|
}
|
|
return Math.min(1000 * 2 ** attemptIndex, 30_000);
|
|
}
|
|
|
|
export function createQueryClient(): QueryClient {
|
|
return new QueryClient({
|
|
queryCache: new QueryCache({ onError: handleUnauthorized }),
|
|
mutationCache: new MutationCache({ onError: handleUnauthorized }),
|
|
defaultOptions: {
|
|
queries: {
|
|
staleTime: 30_000,
|
|
retry: shouldRetry,
|
|
retryDelay,
|
|
},
|
|
mutations: {
|
|
retry: false,
|
|
},
|
|
},
|
|
});
|
|
}
|