fix(auth): show the shared-wallet flow in dev; hide re-import when already connected
The access barrier's shared-wallet steps are gated on hasSharedWallet(), which reads a global set only by build.ts's compile-time `define`. The src-served paths (bun run dev AND bun run start) bundle index.html via Bun's HTML import, which applies no define and inlines neither `process.env` nor `bun --define` (verified) — so FESTIPOD_SHARED_WALLET_PASSWORD passed to `bun run dev` never reached the frontend, and the barrier showed the identifier-only variant. Expose the config at runtime instead: src/index.ts serves /festipod-config.json (+ /shared-wallet.ngw), and the entry (frontend.tsx) fetches it, sets the global, then dynamically imports App so sharedWallet.ts reads it on eval. In a build.ts bundle the value is inlined via define, so the fetch is skipped (NODE_ENV). Verified in a headless browser: FESTIPOD_SHARED_WALLET_PASSWORD=1 bun run dev now renders the download + import steps AND the identifier field, no console errors. Also: only show the download/import steps when status !== 'connected' — after a faux-logout the wallet is still open, so re-import must not be offered (just the identifier). Documents the build-define-vs-runtime-config pitfall in tech-stack. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+45
-15
@@ -3,24 +3,54 @@
|
||||
* 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 (dev
|
||||
* server + `bun run start`, which serve from src/ and so miss build.ts's
|
||||
* compile-time `define`), sets the global, then dynamically imports `App` so
|
||||
* `sharedWallet.ts` reads the value on evaluation. In a build.ts bundle the
|
||||
* password is already inlined via `define`, so this step is skipped (NODE_ENV).
|
||||
*/
|
||||
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { App } from "./App";
|
||||
|
||||
const elem = document.getElementById("root")!;
|
||||
const app = (
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
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);
|
||||
/** Fetch the runtime shared-wallet config and set the global (dev/start only). */
|
||||
async function loadRuntimeConfig(): Promise<void> {
|
||||
if (process.env.NODE_ENV === "production") return; // build.ts define provides it
|
||||
try {
|
||||
const res = await fetch("/festipod-config.json");
|
||||
if (!res.ok) return;
|
||||
const cfg = (await res.json()) as { sharedWalletPassword?: 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<string, unknown>;
|
||||
if (cfg.sharedWalletPassword && g["__FESTIPOD_SHARED_WALLET_PASSWORD__"] == null) {
|
||||
g["__FESTIPOD_SHARED_WALLET_PASSWORD__"] = cfg.sharedWalletPassword;
|
||||
}
|
||||
} catch {
|
||||
// No runtime config endpoint (static build) → rely on the compile-time define.
|
||||
}
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
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 = (
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>
|
||||
);
|
||||
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user