textmachine/frontend/src/main.tsx

44 lines
1.7 KiB
TypeScript

import '@fontsource-variable/inter';
import '@fontsource-variable/jetbrains-mono';
import './tokens/reset.css'; // first: the cascade layer order is declared in its header
import './tokens/tokens.css';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { RouterProvider, createBrowserRouter } from 'react-router';
import { ApiError, startMocking } from './api';
import { routes } from './routes';
import { Locale } from './ui/Locale';
const client = new QueryClient({
defaultOptions: {
queries: {
// A refusal is not a hiccup: retrying a 4xx repeats a request the platform already answered.
// Anything else gets two more tries, because a dropped connection usually is a hiccup.
retry: (attempt, error) =>
!(error instanceof ApiError && error.status >= 400 && error.status < 500) && attempt < 2,
// Refetch on window focus stays ON deliberately. It is the race the contract's revision guard
// exists for, and turning it off would hide the race instead of handling it.
staleTime: 15_000,
},
},
});
const root = document.getElementById('root');
if (!root) throw new Error('Root node #root not found in index.html');
// Awaited before the first render: a request that leaves before the mock is intercepting goes to
// the real network instead, and the failure looks like a broken fixture rather than a race.
await startMocking(window.location.pathname);
createRoot(root).render(
<StrictMode>
<QueryClientProvider client={client}>
<Locale>
<RouterProvider router={createBrowserRouter(routes)} />
</Locale>
</QueryClientProvider>
</StrictMode>,
);