Adds `frontend/src/mock/` — a fake backend that runs in the page, so the whole PWA can be demoed and driven by an automated frontend test with no FastAPI, no sidecar and no transcripts on disk. `?mock=1` on any URL (sticky, works against the deployed app) or `npm run dev:mock`. It swaps `window.fetch` (every `/api/*` route) and `window.EventSource` (the `meta`/`transcript` SSE events) for versions served from an in-memory, localStorage-persisted database. Writes really mutate it, and spawn/resume/ interrupt actually run: a scripted turn streams into the conversation item by item over SSE, then stamps the notification + DONE that mark it finished. The seed is combinatorial — harness × state × lifecycle × archived conversations, a kitchen-sink thread with every ThreadItemKind and tool card, every FileEntryKind, every service auth, every plan status, every FileDiffStatus / DiffLineType — so every visual state is reachable from a cold load, and it is deterministic (fixed clock, no RNG). Test hooks on `window.__mock`. Rows are typed with the orval-generated models, so a backend schema change breaks the seed at tsc time instead of letting the mock drift. main.tsx is now a boot shim (mock installs before the app tree is imported — the server-backed Zustand stores fetch at import time); the app tree moved to root.tsx. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
25 lines
896 B
TypeScript
25 lines
896 B
TypeScript
import { isMockEnabled } from "./mock/enabled";
|
|
|
|
/**
|
|
* Entry point — nothing but boot ordering.
|
|
*
|
|
* In demo / test mode (`?mock=1` on any URL, or a `VITE_MOCK=1` build) the
|
|
* in-browser mock backend (`src/mock/`) must install its `fetch` +
|
|
* `EventSource` interceptors **before the app tree is even imported**: modules
|
|
* in there fetch at import time (the server-backed Zustand stores hydrate
|
|
* immediately), and those calls have to hit the seeded local database, not a
|
|
* backend that isn't there. Hence both the app and the mock are pulled in with
|
|
* dynamic imports, in that order. In a normal build the mock stays in its own
|
|
* lazy chunk and is never fetched.
|
|
*/
|
|
async function boot(): Promise<void> {
|
|
if (isMockEnabled()) {
|
|
const { installMock } = await import("./mock");
|
|
installMock();
|
|
}
|
|
const { renderApp } = await import("./root");
|
|
renderApp();
|
|
}
|
|
|
|
void boot();
|