96 lines
2.4 KiB
TypeScript
96 lines
2.4 KiB
TypeScript
import { httpBatchLink } from "@trpc/client";
|
|
import { createTRPCReact } from "@trpc/react-query";
|
|
import {
|
|
useCallback,
|
|
useEffect,
|
|
useRef,
|
|
useState,
|
|
type ReactNode,
|
|
} from "react";
|
|
import SuperJSON from "superjson";
|
|
|
|
import { useAccounts } from "@/contexts/AccountsContext";
|
|
import { useAuthClient, useSession } from "@/contexts/AuthContext";
|
|
import { getAuthCookieHeaders } from "@/lib/auth-cookie";
|
|
import { performAuthReset } from "@/lib/auth-session";
|
|
import { createAppQueryClient } from "@/lib/query-client";
|
|
import type { AppRouter } from "beenvoice/server/api/root";
|
|
|
|
export const api = createTRPCReact<AppRouter>();
|
|
|
|
export function TRPCProvider({
|
|
apiUrl,
|
|
children,
|
|
}: {
|
|
apiUrl: string;
|
|
children: ReactNode;
|
|
}) {
|
|
const authClient = useAuthClient();
|
|
const { authStoragePrefix, activeAccountId, clearActiveAccount } =
|
|
useAccounts();
|
|
const { refetch } = useSession();
|
|
const authStoragePrefixRef = useRef(authStoragePrefix);
|
|
authStoragePrefixRef.current = authStoragePrefix;
|
|
|
|
const mountedRef = useRef(true);
|
|
const resettingRef = useRef(false);
|
|
|
|
useEffect(() => {
|
|
mountedRef.current = true;
|
|
return () => {
|
|
mountedRef.current = false;
|
|
};
|
|
}, []);
|
|
|
|
const handleUnauthorized = useCallback(async () => {
|
|
if (!activeAccountId || resettingRef.current || !mountedRef.current) return;
|
|
|
|
const session = await authClient.getSession();
|
|
if (session.data?.user || !mountedRef.current) return;
|
|
|
|
resettingRef.current = true;
|
|
try {
|
|
await performAuthReset({
|
|
authClient,
|
|
clearActiveAccount,
|
|
activeAccountId,
|
|
refetchSession: refetch,
|
|
});
|
|
} finally {
|
|
resettingRef.current = false;
|
|
}
|
|
}, [authClient, clearActiveAccount, activeAccountId, refetch]);
|
|
|
|
const onUnauthorizedRef = useRef(handleUnauthorized);
|
|
onUnauthorizedRef.current = handleUnauthorized;
|
|
|
|
const [queryClient] = useState(() =>
|
|
createAppQueryClient(() => {
|
|
void onUnauthorizedRef.current();
|
|
}),
|
|
);
|
|
|
|
const [trpcClient] = useState(() =>
|
|
api.createClient({
|
|
links: [
|
|
httpBatchLink({
|
|
url: `${apiUrl}/api/trpc`,
|
|
transformer: SuperJSON,
|
|
headers() {
|
|
return getAuthCookieHeaders(
|
|
authClient,
|
|
authStoragePrefixRef.current,
|
|
);
|
|
},
|
|
}),
|
|
],
|
|
}),
|
|
);
|
|
|
|
return (
|
|
<api.Provider client={trpcClient} queryClient={queryClient}>
|
|
{children}
|
|
</api.Provider>
|
|
);
|
|
}
|