"use client"; import type { FetchTiming } from "@fetcha/core/client"; import { formatMs } from "@/lib/format"; import { cn } from "@/lib/utils"; const PHASES: Array<{ key: keyof FetchTiming; label: string; hint: string; color: string }> = [ { key: "dns_ms", label: "DNS", hint: "Hostname resolution and SSRF validation", color: "bg-fg-subtle" }, { key: "proxy_connect_ms", label: "Network connect", hint: "Connecting through the selected network class", color: "bg-info" }, { key: "tls_ms", label: "TLS", hint: "TLS handshake with the target", color: "bg-accent" }, { key: "origin_ms", label: "Origin", hint: "Time to receive the full response from the target", color: "bg-success" }, { key: "processing_ms", label: "Processing", hint: "Decoding, format conversion and metadata", color: "bg-warning" }, ]; /** Horizontal breakdown of the request timing phases. */ export function TimingBars({ timing, totalFallbackMs }: { timing: FetchTiming | undefined; totalFallbackMs: number }) { if (!timing) { return

No timing breakdown was returned for this request. Total duration: {formatMs(totalFallbackMs)}.

; } const sum = PHASES.reduce((a, p) => a + Math.max(0, timing[p.key] ?? 0), 0); const total = Math.max(timing.total_ms || 0, sum, 1); return (
{PHASES.map((p) => { const v = Math.max(0, timing[p.key] ?? 0); if (v <= 0) return null; return
; })}
{PHASES.map((p) => { const v = Math.max(0, timing[p.key] ?? 0); const pct = total ? (v / total) * 100 : 0; return (
{p.label} ยท {p.hint}
{formatMs(v)} ({pct.toFixed(0)}%)
); })}
Total {formatMs(timing.total_ms || total)}
); }