export interface AsyncQueue { enqueue(item: T): void; drain(): void; clear(): void; size(): number; } export function createAsyncQueue( worker: (item: T) => Promise, concurrency = 1, ): AsyncQueue { const queue: T[] = []; let active = 0; function next() { while (active < concurrency && queue.length > 0) { const item = queue.shift()!; active++; worker(item).finally(() => { active--; next(); }); } } return { enqueue(item) { queue.push(item); next(); }, drain() { next(); }, clear() { queue.length = 0; }, size() { return queue.length; }, }; }