A race weekend passes through a lot of states before it becomes a line in the results table. A session is scheduled, starts late, pauses, finishes, waits for classification, and eventually settles into the archive. The photographs have their own clock: taken at the circuit, uploaded later, and published after processing.
That is the problem I am working on in AfterImage v1.5, an independent F1 archive built with TypeScript, React, Next.js and Supabase. The new race-weekend hub brings session clocks, live classification when the timing source is available, circuit context and credited photography into the same browsing path.
The interesting part is deciding what the interface is allowed to claim.
A timetable is not a live signal
A naive implementation would mark a session live as soon as its scheduled start time arrives. That looks convincing right up until the session is delayed.
AfterImage keeps a scheduled window separate from a confirmed live session. Provider signals for live, paused and delayed states take precedence over the timetable. Final classification is another explicit state, so the end of the scheduled race window does not manufacture a final result.
Here is a simplified sketch of that rule, rather than the complete production state machine:
type Signal = "live" | "paused" | "delayed";
function presentationState(
now: number,
scheduledStart: number,
signal: Signal | null,
) {
if (signal !== null) return signal;
if (now >= scheduledStart) return "scheduled_window";
return "upcoming";
}
The result is a useful distinction for users: the session is due to be happening, or the data source has actually confirmed what is happening. This applies just as well to shipping trackers and appointment systems as it does to racing.
The clock and the connection are different state
The browser receives a canonical weekend snapshot and subsequent server-sent events. Its countdown interpolates the server timestamp with performance.now(), rather than treating the device wall clock as the source of truth. Replay uses a controlled clock instead.
Connection status is separate from the snapshot. A dropped stream can change the connection label to reconnecting or degraded while preserving the last useful race context. A polling fallback requests a fresh snapshot, and older canonical snapshots for the same race are rejected so a slow HTTP response cannot roll the displayed state backward.
The practical lesson: a lost connection should explain uncertainty. It should not erase the timetable, circuit, or photographs that are already available.
Photographs need honest time and place
A photograph can have a known race without having an exact session, capture timestamp, or corner. Those fields remain optional. A missing corner is not filled in from a guess, and upload time is not silently relabeled as capture time.
The circuit activity view therefore tells users which clock its counts use: confirmed capture time when available, otherwise upload time. Circuit markers are schematic locations, not surveyed camera positions or advice about where spectators may stand.
This is less glamorous than drawing a heat map, but it makes the heat map mean something.
Credit belongs in the photo record
The photo model carries photographer, original source and license fields alongside race, driver, team and circuit relationships. Authenticated upload ownership is a separate field. An attributed Commons photographer is not presented as a registered member merely because their work is in the archive.
One public example is The Geometry of Suzuka, a six-frame exhibition of Martin Lee's credited work. Each frame connects back to its original file and circuit context. That gives the image another route through the site without losing the person who made it.
The current boundary
The timing integration depends on source availability. The upcoming weekend currently shows a countdown and timetable while awaiting a session feed. An uninterrupted active-race run has not yet been verified, so I am not claiming a latency guarantee. The public scenario lab labels its simulated classification and weather.
You can explore the race-weekend hub now. Signing in adds weekend follows, saved frames and your own uploads. AfterImage is an independent fan project, unaffiliated with Formula 1.
For anyone building a live-data interface: which failure state deserves the most design effort in your experience—stale data, delayed events, or reconnecting?
Disclosure: This article was prepared with AI assistance using the current AfterImage implementation and public pages. The code sample is a simplified illustration.
Top comments (0)