// Pure display formatters shared by main and renderer. Kept in @shared (not a // main- or renderer-only lib) so byte/speed/ETA formatting has ONE definition on // both sides of the IPC boundary — the renderer no longer re-parses formatted // strings back into numbers to aggregate them (H2/H4). /** Format a byte count as a binary-scaled size, e.g. 1048576 → '1.0 MB'. */ export function fmtBytes(bytes: number): string { if (bytes < 1024) return `${bytes} B` const units = ['KB', 'MB', 'GB', 'TB'] let v = bytes / 1024 let i = 0 while (v >= 1024 && i < units.length - 1) { v /= 1024 i++ } return `${v.toFixed(v >= 100 ? 0 : 1)} ${units[i]}` } /** Format a transfer rate, e.g. 4928307 → '4.7 MB/s'. Undefined for no rate. */ export function fmtSpeed(bytesPerSec?: number): string | undefined { if (bytesPerSec == null) return undefined return `${fmtBytes(bytesPerSec)}/s` } /** Format a duration in seconds as M:SS or H:MM:SS. Undefined for no value. */ export function fmtEta(seconds?: number): string | undefined { if (seconds == null) return undefined const s = Math.max(0, Math.round(seconds)) const h = Math.floor(s / 3600) const m = Math.floor((s % 3600) / 60) const r = s % 60 if (h > 0) return `${h}:${String(m).padStart(2, '0')}:${String(r).padStart(2, '0')}` return `${m}:${String(r).padStart(2, '0')}` }