feat(live): add web track map (#32)

Subscribe to SignalR Position.z and CarData.z, decode DEFLATE payloads, stream throttled positions over SSE, and render live car dots against cached track outline bounds with tap telemetry.

Alignment spike: no checked-in or locally cached real Position.z samples were available in this isolated worktree; verified both streams expose the official raw F1 X/Y/Z coordinate contract and implemented shared-bounds normalization against prefetched OpenF1 outlines. Fallback build-outline-from-stream was not taken.

Playwright remains out of scope for live rendering because BOXBOX_DISABLE_LIVE is used there; coverage is via parser, web handler/SSE, pure transform, and seeded component tests.
This commit is contained in:
Aman Tahiliani
2026-07-03 19:34:09 -04:00
committed by GitHub
parent 5408a45bbd
commit 7263949260
15 changed files with 1076 additions and 18 deletions

View File

@@ -177,6 +177,22 @@ export interface LiveStateResponse {
data: LiveStreamData | null
}
export interface LivePosition {
x: number
y: number
z: number
status: string
}
export interface LiveTelemetry {
Speed: number
Throttle: number
Brake: number
DRS: number
NGear: number
RPM: number
}
export interface LiveSectorData {
Value: string
PersonalFastest: boolean
@@ -257,6 +273,7 @@ export interface LiveStreamData {
Drivers: Record<string, LiveDriverData>
DriverInfo: Record<string, LiveDriverInfo>
Tyres: Record<string, LiveTyreData>
Telemetry?: Record<string, LiveTelemetry>
RCMessages: LiveRCMessage[]
Weather: LiveWeatherData
Session: LiveSessionMeta
@@ -269,6 +286,24 @@ export interface LiveStreamData {
Stints: Record<string, LiveStintData[]>
}
export interface TrackPoint {
x: number
y: number
}
export interface TrackBounds {
minX: number
maxX: number
minY: number
maxY: number
}
export interface TrackOutline {
circuit_key: number
points: TrackPoint[]
bounds: TrackBounds
}
export interface ChampHubDriver {
driver_number: number
name_acronym: string