/** * This file is the entry point for the React app, it sets up the root * element and renders the App component to the DOM. * * It is included in `src/index.html`. * * Before loading the app tree it pulls the RUNTIME shared-wallet config, sets * the global, then dynamically imports `App` so `sharedWallet.ts` reads the * value on evaluation. A `build.ts` bundle already carries the value inlined by * `define`, and then there is nothing to fetch. * * WHICH ONE APPLIES IS NOT `NODE_ENV`. This used to skip the fetch under * `NODE_ENV=production`, on the reasoning "production means built". This * project's production does NOT build: the container copies the sources and * runs `bun run start` (= `NODE_ENV=production bun src/index.ts`), serving from * src/ exactly as dev does. Nothing ever serves `dist/`. So the deployed app * skipped the only step that could give it a wallet, `ensureIdentity()` threw * for want of one, and it could never sign anybody in — while `/festipod-config.json` * sat there, served and unasked. * * The question is therefore "was the value inlined?", never "am I in * production?" — ask the global itself. */ import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; /** Fetch the runtime shared-wallet config and set the global, unless it is already there. */ async function loadRuntimeConfig(): Promise { // Already inlined by `build.ts`'s `define` → nothing to fetch. Bracket access, // so that same `define` (which rewrites the dotted global) leaves this read alone. if ((globalThis as Record)["__FESTIPOD_SHARED_WALLET_PASSWORD__"] != null) return; try { const res = await fetch("/festipod-config.json"); if (!res.ok) return; const cfg = (await res.json()) as { sharedWalletPassword?: string; autoSeed?: string }; // Bracket access so build.ts's `define` (which matches the dotted global) // never rewrites this assignment. Only set when the env actually carries one. const g = globalThis as Record; if (cfg.sharedWalletPassword && g["__FESTIPOD_SHARED_WALLET_PASSWORD__"] == null) { g["__FESTIPOD_SHARED_WALLET_PASSWORD__"] = cfg.sharedWalletPassword; } // Auto-seed gate (see src/shared/utils/autoSeed.ts): only set the global when // the env var carries a truthy value; absent → stays undefined → seed OFF. if (cfg.autoSeed && g["__FESTIPOD_AUTO_SEED__"] == null) { g["__FESTIPOD_AUTO_SEED__"] = cfg.autoSeed; } } catch { // No runtime config endpoint (static build) → rely on the compile-time define. } } async function main(): Promise { await loadRuntimeConfig(); // Dynamic import AFTER the global is set, so sharedWallet.ts reads it on eval. const { App } = await import("./App"); const elem = document.getElementById("root")!; const app = ( ); if (import.meta.hot) { // With hot module reloading, `import.meta.hot.data` is persisted. const root = (import.meta.hot.data.root ??= createRoot(elem)); root.render(app); } else { // The hot module reloading API is not available in production. createRoot(elem).render(app); } } void main();