import { toast } from "../state/toast"; import type { InstanceEventPayload } from "../types/events"; const DEDUP_WINDOW_MS = 1000; const lastToastTime = new Map(); function makeDedupKey(instanceId: string, eventType: string): string { return `${instanceId}:${eventType}`; } function shouldShowToast(instanceId: string, eventType: string): boolean { const key = makeDedupKey(instanceId, eventType); const now = Date.now(); const last = lastToastTime.get(key); if (last && now - last < DEDUP_WINDOW_MS) { return false; } lastToastTime.set(key, now); return true; } export function mapEventToCategory(event: InstanceEventPayload): string { if (event.event.startsWith("instance.")) return "instance"; if (event.event.startsWith("health.")) return "health"; return "system"; } export function mapEventToSeverity( event: InstanceEventPayload, ): "info" | "warning" | "error" | "success" { switch (event.event) { case "instance.error": case "health.error": return "error"; case "instance.health_changed": return event.status === "unhealthy" ? "warning" : "success"; case "instance.created": case "instance.started": case "instance.stopped": case "instance.restarted": case "instance.deleted": return "info"; default: return "info"; } } export function handleEventToast(event: InstanceEventPayload): void { const { event: eventType, instance_id, status, message, metadata } = event; switch (eventType) { case "instance.started": if (shouldShowToast(instance_id, eventType)) { toast.info("Container starting...", { duration: 3000 }); } break; case "instance.health_changed": if (status === "running" && shouldShowToast(instance_id, eventType)) { toast.success("Container running", { duration: 3000 }); } else if ( status === "unhealthy" && shouldShowToast(instance_id, eventType) ) { toast.warning("Container unhealthy", { duration: 5000 }); } break; case "instance.error": if (shouldShowToast(instance_id, eventType)) { const msg = message ?? "Container error"; const exitCode = metadata?.exit_code; const fullMsg = exitCode !== undefined ? `${msg} (exit code: ${exitCode})` : msg; toast.error(fullMsg, { duration: 10000 }); } break; default: break; } } export function clearToastDedup(): void { lastToastTime.clear(); }