const SECONDS = 1000; const MINUTE = 60 * SECONDS; const HOUR = 60 * MINUTE; const DAY = 24 * HOUR; const MONTH = 30 * DAY; const YEAR = 365 * DAY; const KB = 1024; const RELATIVE_UNITS: ReadonlyArray<[number, string]> = [ [YEAR, "year"], [MONTH, "month"], [DAY, "day"], [HOUR, "hour"], [MINUTE, "minute"], ]; export function formatRelative(timestamp: number, now = Date.now()): string { const delta = now - timestamp; for (const [size, label] of RELATIVE_UNITS) { if (delta >= size) { const count = Math.floor(delta / size); return `${count} ${label}${count === 1 ? "" : "s"} ago`; } } return "just now"; } export function formatDuration(start: number | null, end: number | null): string { if (!start) return ""; const total = Math.max(0, Math.round(((end ?? Date.now()) - start) / SECONDS)); const minutes = Math.floor(total / 60); return minutes > 0 ? `${minutes}m ${total % 60}s` : `${total}s`; } export function formatBytes(bytes: number): string { if (bytes < KB) return `${bytes} B`; if (bytes < KB * KB) return `${(bytes / KB).toFixed(1)} KB`; if (bytes < KB * KB * KB) return `${(bytes / KB / KB).toFixed(1)} MB`; return `${(bytes / KB / KB / KB).toFixed(1)} GB`; }