ui/phase-14: rename planet end-to-end + order read-back
Wires the first end-to-end command through the full pipeline:
inspector rename action → local order draft → user.games.order
submit → optimistic overlay on map / inspector → server hydration
on cache miss via the new user.games.order.get message type.
Backend: GET /api/v1/user/games/{id}/orders forwards to engine
GET /api/v1/order. Gateway parses the engine PUT response into the
extended UserGamesOrderResponse FBS envelope and adds
executeUserGamesOrderGet for the read-back path. Frontend ports
ValidateTypeName to TS, lands the inline rename editor + Submit
button, and exposes a renderedReport context so consumers see the
overlay-applied snapshot.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
// Provides a derived view of the server `GameReport` overlaid with
|
||||
// the player's local order draft. Every consumer that needs to
|
||||
// render the player's current intent (inspector, map, mobile sheet)
|
||||
// subscribes through this context instead of reading `gameState.report`
|
||||
// directly.
|
||||
//
|
||||
// Lifetime matches the in-game shell layout: one source per game,
|
||||
// rebuilt on layout remount. The source itself is a thin reactive
|
||||
// wrapper — the actual overlay computation lives in
|
||||
// `applyOrderOverlay` (api/game-state.ts) and runs lazily on every
|
||||
// access through the `report` getter.
|
||||
|
||||
import {
|
||||
applyOrderOverlay,
|
||||
type GameReport,
|
||||
} from "../api/game-state";
|
||||
import type { GameStateStore } from "./game-state.svelte";
|
||||
import type { OrderDraftStore } from "../sync/order-draft.svelte";
|
||||
|
||||
/**
|
||||
* RENDERED_REPORT_CONTEXT_KEY is the Svelte context key the in-game
|
||||
* shell layout uses to expose a `RenderedReportSource` instance to
|
||||
* descendants. Consumers read the latest overlay through `source.report`
|
||||
* (a reactive getter) and re-render when the underlying stores
|
||||
* change.
|
||||
*/
|
||||
export const RENDERED_REPORT_CONTEXT_KEY = Symbol("rendered-report");
|
||||
|
||||
export interface RenderedReportSource {
|
||||
readonly report: GameReport | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* createRenderedReportSource binds the live `GameStateStore` and
|
||||
* `OrderDraftStore` to a getter that returns the overlay-applied
|
||||
* report on every read. The getter is reactive: Svelte tracks the
|
||||
* underlying `$state` accesses inside `applyOrderOverlay`, so any
|
||||
* change to the report or the draft re-runs every dependent
|
||||
* `$derived` block.
|
||||
*/
|
||||
export function createRenderedReportSource(
|
||||
gameState: GameStateStore,
|
||||
orderDraft: OrderDraftStore,
|
||||
): RenderedReportSource {
|
||||
return {
|
||||
get report(): GameReport | null {
|
||||
const raw = gameState.report;
|
||||
if (raw === null) return null;
|
||||
return applyOrderOverlay(raw, orderDraft.commands, orderDraft.statuses);
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user