feat(mapgen-studio): migrate client transport to oRPC, add TanStack Query client, and introduce Zustand viewStore#1610
Merged
Merged
Conversation
This was referenced Jun 12, 2026
|
Railway preview (MapGen Studio): not provisioned for this PR. Policy (Graphite stacks): previews are created only for the top-of-stack PR by default.
Debug: |
Owner
Author
This was referenced Jun 12, 2026
Merged
This was referenced Jun 12, 2026
Merged
mateicanavra
force-pushed
the
design/client-data
branch
from
June 12, 2026 20:44
272c00e to
cc3e152
Compare
Owner
Author
Merge activity
|
mateicanavra
changed the base branch from
design/server-orpc
to
graphite-base/1610
June 12, 2026 20:59
…ck Query + viewStore
Complete the client half of EVERYTHING-talks-oRPC (FRAME §4.7): the React client
now performs ZERO manual fetch of /api. All server-data callers route through the
typed oRPC client (src/lib/orpc.ts) bound to the studio contract.
- Add src/lib/query.ts (QueryClient factory) + QueryClientProvider in main.tsx.
- Migrate features/{civ7Setup,runInGame,mapConfigSave}/api.ts transport from
fetch to orpcClient.*; result envelopes preserved by construction. ORPCError
.status reproduces the legacy statusCode (run-in-game 404 restart detection);
.data carries details/observedAt/server-id echo. Non-uniform status registry
preserved.
- Migrate the live-runtime poll's three reads (civ7.live.status, civ7.live.snapshot,
inlined civ7.setupConfig) onto the oRPC client. Request-key staleness gate,
adaptive backoff, abort plumbing, and 200-with-embedded-{error} handling are
unchanged — only the transport swapped. No fetch( remains in App.tsx.
- Introduce viewStore (Zustand v5) as the single owner of browser-only view state
(canvas toggles, overlay selection, era mode, panel collapse, selected stage/step);
App holds no useState mirror. Query results are never mirrored into Zustand.
- Defer the persisted authoring/run Zustand stores to the decomposition slice
(localStorage schema is hard-core parity; safer moved alongside the component split).
OpenSpec: mapgen-studio-client-data (validated --strict).
Verify: tsc clean; vite build + worker-bundle pass; dev-server network shows only
POST /rpc/* (zero /api/*), live poll cycles over oRPC at 200, no console errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mateicanavra
force-pushed
the
design/client-data
branch
from
June 12, 2026 21:02
cc3e152 to
de0e382
Compare
This was referenced Jun 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

All client-to-server traffic in Mapgen Studio now flows through the typed oRPC client (
src/lib/orpc.ts) bound to the studio contract. Previously, the React app reached the backend through hand-rolledfetchcalls against/api/*endpoints; after this change, zero manualfetchof/apiremains anywhere in the client.Transport migration — The three
features/*/api.tswrappers (civ7Setup,runInGame,mapConfigSave) have their transport swapped fromfetchtoorpcClient.*while their result envelopes ({ ok, error, statusCode, observedAt, details }) are preserved exactly.ORPCError.statusreproduces the legacystatusCode(including the run-in-game 404 used for server-restart detection) andORPCError.datacarriesdetails/observedAt. The live-runtime poll's two reads (civ7.live.status,civ7.live.snapshot) and the inlinedciv7.setupConfigread are also migrated. The poll's request-key staleness gate, adaptive backoff, and abort plumbing are untouched — only the network call changed.Client data layer — A
QueryClientfactory (src/lib/query.ts) is added with shortstaleTime, single retry, and refetch-on-focus, and the app is wrapped inQueryClientProviderinmain.tsxwith a single module-root instance.View state consolidation — A new Zustand v5
viewStore(src/stores/viewStore.ts) becomes the single owner of browser-only view state: canvas grid/edge toggles, overlay selection and opacity, era mode, panel collapse, and selected stage/step. The scattereduseStatecalls for this surface inApp.tsxare replaced withuseViewStoreselectors;App.tsxholds no mirror. Setters accept a value or an updater function, making the migration a drop-in for existingsetX((prev) => …)call sites. Server-owned data is never mirrored into Zustand.zustand@5.0.14is added as a dependency.