/** * Human-readable metric formatting with automatic unit scaling. */ /** * @param {number} n * @param {number} digits */ function trimFixed(n, digits) { const s = n.toFixed(digits) if (!s.includes('.')) return s return s.replace(/0+$/, '').replace(/\.$/, '') } /** * Pick decimal places from magnitude after scaling. * @param {number} n */ function autoDigits(n) { const a = Math.abs(n) if (a >= 100) return 0 if (a >= 10) return 1 return 2 } /** * Scale a magnitude through a unit ladder. * @param {number} value absolute magnitude in base units * @param {string[]} units * @param {number} base * @returns {{ n: number, unit: string }} */ function scaleUnit(value, units, base) { let n = Math.abs(value) let i = 0 while (n >= base && i < units.length - 1) { n /= base i++ } return { n: value < 0 ? -n : n, unit: units[i] } } /** * Format memory stored as MiB → B / KiB / MiB / GiB / TiB / PiB. * @param {number|null|undefined} mib * @returns {string} */ export function formatMib(mib) { if (mib == null || !Number.isFinite(Number(mib))) return '—' const bytes = Number(mib) * 1024 * 1024 if (bytes === 0) return '0 B' const { n, unit } = scaleUnit(bytes, ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'], 1024) return `${trimFixed(n, autoDigits(n))} ${unit}` } /** * Format network rate stored as kilobits/s → b/s / kb/s / Mb/s / Gb/s / Tb/s. * @param {number|null|undefined} kbps * @returns {string} */ export function formatKilobitsPerSec(kbps) { if (kbps == null || !Number.isFinite(Number(kbps))) return '—' const bps = Number(kbps) * 1000 if (bps === 0) return '0 b/s' const { n, unit } = scaleUnit(bps, ['b/s', 'kb/s', 'Mb/s', 'Gb/s', 'Tb/s'], 1000) return `${trimFixed(n, autoDigits(n))} ${unit}` } /** * Format raw bytes → B / KiB / MiB / GiB / TiB / PiB. * @param {number|null|undefined} bytes * @returns {string} */ export function formatBytes(bytes) { if (bytes == null || !Number.isFinite(Number(bytes))) return '—' const n0 = Number(bytes) if (n0 === 0) return '0 B' const { n, unit } = scaleUnit(n0, ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'], 1024) return `${trimFixed(n, autoDigits(n))} ${unit}` }