export interface SerialQueueOptions { /** Minimum delay between task starts. 0 = unpaced. */ minIntervalMs?: number } export class SerialQueue { private tail: Promise = Promise.resolve() private lastStart = 0 private minIntervalMs: number constructor(opts: SerialQueueOptions = {}) { this.minIntervalMs = opts.minIntervalMs ?? 0 } run(fn: () => Promise): Promise { const result = this.tail.then(async () => { if (this.minIntervalMs > 0) { const wait = this.lastStart + this.minIntervalMs - Date.now() if (wait > 0) await new Promise((r) => setTimeout(r, wait)) } this.lastStart = Date.now() return fn() }) this.tail = result.catch(() => {}) return result } }