const windowMs = 30000; const minimumSpanMs = 4000; const samplesByJob = new Map(); export function updateSpeeds(jobs) { const now = performance.now(); const seenIds = new Set(); for (const job of jobs) { seenIds.add(job.id); let samples = samplesByJob.get(job.id) || []; const last = samples[samples.length - 1]; const progressWentBack = last && job.bytesDone < last.bytes; const notTransferring = job.status !== "downloading" && job.status !== "extracting" && job.status !== "moving"; if (progressWentBack || notTransferring || (last && last.status !== job.status)) { samples = []; } samples.push({ bytes: job.bytesDone, time: now, status: job.status }); while (samples.length > 2 && now - samples[1].time >= windowMs) { samples.shift(); } samplesByJob.set(job.id, samples); } for (const id of samplesByJob.keys()) { if (!seenIds.has(id)) samplesByJob.delete(id); } } export function speedOf(jobId) { const samples = samplesByJob.get(jobId); if (!samples || samples.length < 2) return 0; const first = samples[0]; const last = samples[samples.length - 1]; const spanMs = last.time - first.time; if (spanMs < minimumSpanMs) return 0; return ((last.bytes - first.bytes) * 1000) / spanMs; }