'use client'; import { AnimatedNumber } from '@/components/ui/AnimatedNumber'; import { fmt } from '@/lib/format'; import { useDegraded, useLive } from '@/lib/live'; import { Time } from '@/lib/time'; import type { Ticker as TickerT } from '@/lib/types'; interface Cell { key: keyof TickerT; label: string; digits?: number; unit?: string; color?: (t: TickerT) => string | undefined; } const CELLS: Cell[] = [ { key: 'bgp_updates_per_s', label: 'BGP updates/s', digits: 1 }, { key: 'bgp_withdrawals_per_s', label: 'withdrawals/s', digits: 1, color: (t) => (t.bgp_withdrawals_per_s > 30 ? 'var(--p-stressed)' : undefined) }, { key: 'probes_active', label: 'probes active', digits: 0, color: (t) => (t.probes_active < t.probes_total ? 'var(--warn)' : undefined) }, { key: 'measurements_per_s', label: 'measurements/s', digits: 1 }, { key: 'targets_degraded', label: 'targets degraded', digits: 0, color: (t) => (t.targets_degraded > 0 ? 'var(--p-elevated)' : undefined) }, { key: 'regions_elevated', label: 'regions elevated', digits: 0, color: (t) => (t.regions_elevated > 0 ? 'var(--p-elevated)' : undefined) }, { key: 'regions_severe', label: 'regions severe', digits: 0, color: (t) => (t.regions_severe > 0 ? 'var(--p-severe)' : undefined) }, { key: 'dns_failures_per_min', label: 'DNS failures/min', digits: 0 }, { key: 'median_global_rtt_ms', label: 'median RTT', digits: 1, unit: 'ms' }, { key: 'route_changes_per_min', label: 'route changes/min', digits: 1 }, { key: 'active_incidents', label: 'active incidents', digits: 0, color: (t) => (t.active_incidents > 0 ? 'var(--p-high)' : undefined) }, { key: 'bgp_updates_per_min', label: 'BGP updates/min', digits: 0 }, ]; /** Live ticker — a dense grid that updates in place (no marquee). Every value is a real counter (spec §66). */ export function Ticker({ initial }: { initial: TickerT | null }) { const live = useLive((s) => s.ticker); const updates = useLive((s) => s.updates); const { degraded } = useDegraded(); const t = live ?? initial; if (!t) return

Ticker unavailable.

; return (
{CELLS.map((c) => { const v = t[c.key] as number; return (
{c.label}
{c.unit && {c.unit}} {c.key === 'probes_active' && /{fmt(t.probes_total, 0)}} {c.key === 'targets_degraded' && /{fmt(t.targets_total, 0)}}
); })}

counters at

); }