// Shared sparkline utilities used by both apps/web (dashboard) and apps/status // (public status pages). Pure HTML/SVG output, no client JS required for the // first paint. import { REGION_COLORS } from "../plans"; export function sparkline(values: number[], width = 120, height = 32, color = '#60a5fa', region = 'default'): string { if (!values.length) return ''; const max = Math.max(...values, 1); const min = Math.min(...values, 0); const range = max - min || 1; const step = width / Math.max(values.length - 1, 1); const points = values.map((v, i) => { const x = i * step; const y = height - ((v - min) / range) * (height - 4) - 2; return `${x},${y}`; }).join(' '); return ``; } export function pickBestRegion(pings: Array<{ latency_ms?: number | null; region?: string | null }>): { region: string; values: number[]; latest: number | null } { const withLatency = pings.filter((p) => p.latency_ms != null); if (!withLatency.length) return { region: 'default', values: [], latest: null }; const byRegion: Record = {}; for (const p of withLatency) { const key = p.region || 'default'; if (!byRegion[key]) byRegion[key] = []; byRegion[key].push(p.latency_ms!); } const recentRegions = new Set(withLatency.slice(-3).map((p) => p.region || 'default')); let bestRegion = 'default'; let bestAvg = Infinity; for (const [region, vals] of Object.entries(byRegion)) { if (!recentRegions.has(region)) continue; const recent = vals.slice(-3); const avg = recent.reduce((a, b) => a + b, 0) / recent.length; if (avg < bestAvg) { bestAvg = avg; bestRegion = region; } } const values = byRegion[bestRegion] || []; return { region: bestRegion, values, latest: values.length ? values[values.length - 1]! : null }; } export function sparklineFromPings(pings: Array<{ latency_ms?: number | null; region?: string | null }>, width = 120, height = 32): string { const { region, values } = pickBestRegion(pings); if (!values.length) return ''; const color = REGION_COLORS[region] || '#60a5fa'; return sparkline(values, width, height, color, region); }