export interface InflightRequest { id?: string; model: string; req_path?: string; method?: string; timestamp?: string; elapsed_ms?: number; } export interface ModelState { id: string; state: string; } export type FeedEvent = | { type: "inflight"; operation: "snapshot" | "add"; requests: InflightRequest[] } | { type: "inflight"; operation: "remove"; id: string } | { type: "activity"; id: number } | { type: "modelStatus"; models: ModelState[] }; export type ModelRuntimeState = "stopped" | "loading" | "ready"; export class InflightTracker { private requests = new Map(); private states = new Map(); apply(event: FeedEvent): void { if (event.type === "inflight") { if (event.operation === "snapshot") { this.requests = new Map(); for (const r of event.requests) if (r.id) this.requests.set(r.id, r.model); } else if (event.operation === "add") { for (const r of event.requests) if (r.id) this.requests.set(r.id, r.model); } else if (event.operation === "remove") { this.requests.delete(event.id); } } else if (event.type === "modelStatus") { for (const m of event.models) this.states.set(m.id, normalizeState(m.state)); } } count(modelId: string): number { let n = 0; for (const model of this.requests.values()) if (model === modelId) n++; return n; } total(): number { return this.requests.size; } state(modelId: string): ModelRuntimeState | undefined { return this.states.get(modelId); } } function normalizeState(state: string): ModelRuntimeState { if (state === "ready") return "ready"; if (state === "loading") return "loading"; return "stopped"; }