H4 + H2 formatter half: carry raw numbers across the progress boundary

Closes H4 and the remaining formatter half of H2.

- New @shared/format.ts is the single home for fmtBytes/fmtSpeed/fmtEta, imported
  by both main and renderer. main/lib/formatters.ts re-exports them.
- DownloadProgress now carries raw speedBytesPerSec/etaSeconds instead of
  pre-formatted speed/eta strings. main's parseProgress emits the raw numbers.
- The renderer stores the raw numbers on DownloadItem; QueueItem formats them for
  per-item display, and summarizeQueue sums/maxes them directly. The lossy
  string->number->string round-trip in queueStats (parseSpeed / parseEtaSeconds /
  a local formatSpeed / formatEta) is deleted, along with a duplicate fmtEta in
  store/downloads.ts.
- Per-item and aggregate speed now use the same 1024-based scale; the aggregate
  previously used a 1000-based formatter (a latent inconsistency).

Tests updated for the raw-number contract (parseProgress, summarizeQueue).
typecheck + 248 tests + eslint + prettier green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 21:03:14 -04:00
parent d050e48af6
commit 3d09174c16
9 changed files with 122 additions and 135 deletions
+4 -4
View File
@@ -468,10 +468,10 @@ export interface DownloadProgress {
status: string
/** 0..1 (0 when total size is unknown) */
progress: number
/** human-readable, e.g. '4.7 MB/s' */
speed?: string
/** human-readable, e.g. '1:12' */
eta?: string
/** raw transfer rate in bytes/sec; the renderer formats + aggregates it (H4) */
speedBytesPerSec?: number
/** raw time remaining in seconds; the renderer formats + aggregates it (H4) */
etaSeconds?: number
/** human-readable total size, e.g. '512 MB' */
sizeLabel?: string
/** true when yt-dlp reports no total/estimated size (livestreams, some sites),