/** Byte sizes, relative times, and git idents, formatted for display. */ /** @param {number|null|undefined} size */ export function bytes(size) { if (size === null || size === undefined) return ''; if (size < 1024) return `${size} B`; if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)} KB`; return `${(size / (1024 * 1024)).toFixed(1)} MB`; } /** @type {Array<[string, number]>} */ const UNITS = [ ['second', 60], ['minute', 60], ['hour', 24], ['day', 7], ['week', 4.35], ['month', 12], ['year', Number.POSITIVE_INFINITY], ]; /** @param {string|number} when - an ISO string or epoch milliseconds */ export function timeAgo(when) { const then = typeof when === 'number' ? when : Date.parse(when); if (!then) return ''; let value = Math.max(1, (Date.now() - then) / 1000); for (const [unit, size] of UNITS) { if (value < size) { const count = Math.floor(value); return `${count} ${unit}${count === 1 ? '' : 's'} ago`; } value /= size; } return ''; } /** * An ident is "Name
"; the page shows the name. * @param {string|undefined} ident */ export const identName = (ident) => String(ident || '').replace(/\s*<[^>]*>$/, '');