import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import { ClerkProvider } from '@clerk/react' import { enUS, idID } from '@clerk/localizations' import { MutationCache, QueryClient, QueryClientProvider } from '@tanstack/react-query' import { BrowserRouter, useLocation } from 'react-router-dom' import { EngineError } from './api/client' import App from './App' import { ErrorBoundary } from './components/ErrorBoundary' import { forgetReads } from './express/results' import { useLang } from './i18n' import './styles/mockup.css' import './styles/app.css' import './styles/theme.css' const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY if (!clerkPubKey) { throw new Error('Missing VITE_CLERK_PUBLISHABLE_KEY (set it, or keep ../learning-lab/backend/.env available)') } const queryClient: QueryClient = new QueryClient({ mutationCache: new MutationCache({ // Runs before the action's own onSuccess, whose invalidations must not get a remembered read. onSuccess: forgetReads, // Any action may have spent workspace credits, so the topbar balance is read again after each one. onSettled: () => queryClient.invalidateQueries({ queryKey: ['credits'] }), }), defaultOptions: { // Retrying a 4xx (auth, credits, validation) only repeats the same answer. queries: { retry: (n, e) => n < 2 && !(e instanceof EngineError && e.status >= 400 && e.status < 500 && e.status !== 429), // A busy engine (rate limited) is asked again only after it has had time to recover; an // immediate retry from every query at once is what keeps it over the limit. retryDelay: (n, e) => (e instanceof EngineError && (e.status === 503 || e.status === 429) ? 5000 : 1000) * 2 ** n, }, }, }) // Clerk's sign-in and organization screens match the theme in styles/theme.css. const clerkAppearance = { variables: { colorPrimary: '#1570ef', colorText: '#101828', fontFamily: "'Plus Jakarta Sans', system-ui, sans-serif", borderRadius: '12px' }, } // A crash outside a page (the layout, the sign-in gate) would otherwise unmount everything and leave // a white page until a reload; moving to another page tries again. function AppBoundary() { const { pathname } = useLocation() return } // Clerk's own sign-in and organization screens follow the app language. function Root() { const lang = useLang() return ( ) } createRoot(document.getElementById('root')!).render( , )