import React from "react";
import ReactDOM from "react-dom/client";
import { createHashHistory, createBrowserHistory } from "@tanstack/react-router";
import "./index.css";
import { isElectron } from "./env";
import { hasCloudPublicConfig } from "./cloud/publicConfig";
import { getRouter } from "./router";
import {
syncDocumentElectronPlatformClasses,
syncDocumentWindowControlsOverlayClass,
} from "./lib/windowControlsOverlay";
import { AppRoot } from "./AppRoot";
import { clearChunkReloadGuard, reloadOnceForChunkLoadError } from "./lib/chunkReloadGuard";
// Electron loads the app from a file-backed shell, so hash history avoids path resolution issues.
const history = isElectron ? createHashHistory() : createBrowserHistory();
const router = getRouter(history);
if (isElectron) {
syncDocumentElectronPlatformClasses(navigator.platform);
syncDocumentWindowControlsOverlayClass();
}
const clerkPublishableKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY as string | undefined;
// A failed split-chunk fetch usually means the hashed assets went stale under
// a deploy; one guarded reload picks up the fresh index.html.
let chunkLoadFailed = false;
let reloadScheduled = false;
window.addEventListener("vite:preloadError", (event) => {
chunkLoadFailed = true;
if (reloadOnceForChunkLoadError()) {
reloadScheduled = true;
event.preventDefault();
}
});
const app = ;
// Managed auth is cloud-only, and the Electron Clerk provider bundles the full
// clerk-js runtime. Loading only the selected runtime as a split chunk keeps
// every Clerk byte out of the startup graph for local-mode users, and keeps
// the bundled clerk-js out of the browser build entirely.
const managedAuthShellModule =
clerkPublishableKey && hasCloudPublicConfig()
? isElectron
? import("./components/clerk/ElectronManagedAuthShell")
: import("./components/clerk/BrowserManagedAuthShell")
: null;
// The index.html boot splash lives inside #root, and React's first commit
// clears it. Resolve everything that first commit needs, the selected
// managed-auth runtime and the initial route's split chunks, before
// rendering, so the splash holds until real UI paints instead of dropping to
// a blank window while chunks download.
export const startup = Promise.all([
managedAuthShellModule?.then((module) => module.default) ?? null,
router.load(),
])
.then(([ManagedAuthShell]) => {
// A route chunk failure still resolves router.load(): the error is parked in
// the lazy component and surfaces through the route error boundary. Skip the
// paint when a reload is on its way, and only re-arm the guard after a boot
// that fetched every chunk it asked for.
if (reloadScheduled) return;
if (!chunkLoadFailed) clearChunkReloadGuard();
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
{ManagedAuthShell && clerkPublishableKey ? (
{app}
) : (
app
)}
,
);
})
.catch((error: unknown) => {
// Let the bootstrap entry show the error unless a reload is already scheduled.
if (reloadScheduled) return;
throw error;
});