feat: task 1.4 runtime config endpoint
Three-file config module under src/config/: - schema.ts: RuntimeConfigSchema (directusUrl, liveWsUrl, businessWsUrl, optional googleMapsKey, env enum). Custom UrlOrAbsolutePath validator accepts http(s)/ws(s) URLs plus paths starting with /. - load.ts: loadConfig() fetches /config.json with cache: 'no-store', safeParse, throws ConfigValidationError on schema failure. - context.ts: RuntimeConfigContext + useRuntimeConfig() hook (no JSX). - provider.tsx: RuntimeConfigProvider — loading / ready / error states. Single retry after 500ms on network failure; renders zod issues on validation failure for debuggability. public/config.json: committed dev defaults (relative paths matching the Vite proxy from 1.3). src/main.tsx wraps App in <RuntimeConfigProvider>. README gains a Runtime config section with the schema table. Deviation: spec sketched provider+hook in one context.tsx. Split into context.ts (hook only) and provider.tsx (component only) to satisfy react-refresh/only-export-components without adding an eslint override.
This commit is contained in:
@@ -102,4 +102,18 @@ Auth state needs Zustand (read in many places, granular subscribers). Runtime co
|
||||
|
||||
## Done
|
||||
|
||||
(Filled in when the task lands.)
|
||||
Three files under `src/config/` plus the dev-defaults JSON:
|
||||
|
||||
- `schema.ts` — `RuntimeConfigSchema` + inferred `RuntimeConfig` type. Custom `UrlOrAbsolutePath` validator accepts `http(s)://`, `ws(s)://`, or paths starting with `/` (so the dev defaults' relative paths validate while still catching obvious typos).
|
||||
- `load.ts` — `loadConfig()` fetches `/config.json` with `cache: 'no-store'`, `safeParse`s, throws `ConfigValidationError` on schema failure or a generic `Error` on network/non-2xx.
|
||||
- `context.ts` — `RuntimeConfigContext` + `useRuntimeConfig()` hook (split from the provider so the file has no component exports — keeps `react-refresh/only-export-components` happy without an eslint override).
|
||||
- `provider.tsx` — `RuntimeConfigProvider`. Three states (loading / ready / error). Network failure retries once after 500 ms; a second failure surfaces the error to the operator with a clear "reload or check the deployment" message. Validation failures render the zod issues so misconfigured `config.json` is debuggable, not a generic crash.
|
||||
- `public/config.json` — committed dev defaults: `{ directusUrl: '/api', liveWsUrl: '/ws-live', businessWsUrl: '/ws-business', env: 'dev' }`. Vite serves it from `public/` at `/config.json` automatically.
|
||||
|
||||
`src/main.tsx` updated to wrap `<App />` in `<RuntimeConfigProvider>`. README "Runtime config" section added with the schema table + override pattern.
|
||||
|
||||
**Deviation from spec:** the spec sketched the provider in `src/config/context.tsx` exporting both the provider and the hook. That triggers `react-refresh/only-export-components` because hooks aren't components. Split into `context.ts` (hook + context object, no JSX) and `provider.tsx` (component only). Cleaner than adding an eslint override and matches conventional React patterns.
|
||||
|
||||
**Smoke check:** `pnpm typecheck`, `pnpm lint`, `pnpm format:check`, `pnpm build` all green. Bundle: 283KB raw / 87KB gzipped (up from 222KB / 70KB after zod entered the runtime path). Could not browser-smoke `useRuntimeConfig` without running `pnpm dev` interactively — flagged as a manual sanity step before 1.5 lands.
|
||||
|
||||
Landed in `PENDING_SHA`.
|
||||
|
||||
Reference in New Issue
Block a user