/** * Keep database waits and long scans visible without logging every record. * update() also checks elapsed time when a synchronous loop delays timers. */ export function createProgress({ log = console.log, intervalMs = 5000, now = Date.now } = {}) { if (!Number.isSafeInteger(intervalMs) || intervalMs < 1) throw new Error('进度输出间隔必须为正整数毫秒'); let message = ''; let startedAt; let lastOutput; let closed = false; function output(force = false) { if (closed || !message) return; const current = now(); if (!force && lastOutput !== undefined && current - lastOutput < intervalMs) return; lastOutput = current; const seconds = Math.max(0, Math.floor((current - startedAt) / 1000)); log(message + '(已用时 ' + seconds + ' 秒)'); } const timer = setInterval(() => output(), intervalMs); timer.unref?.(); return { stage(value) { if (closed) return; message = String(value ?? '').trim(); startedAt = now(); output(true); }, update(value) { if (closed) return; message = String(value ?? '').trim(); if (startedAt === undefined) startedAt = now(); output(); }, close() { if (closed) return; closed = true; clearInterval(timer); }, }; }