interface QueueItem { fn: () => Promise; resolve: (value: T) => void; reject: (error: any) => void; } export class RequestQueue { private queue: QueueItem[] = []; private running = 0; private maxConcurrent: number; constructor(maxConcurrent: number = 3) { this.maxConcurrent = maxConcurrent; } /** * Add a promise-returning function to the queue * @param fn Function that returns a Promise * @returns Promise that resolves with the result of the function */ add(fn: () => Promise): Promise { return new Promise((resolve, reject) => { this.queue.push({ fn, resolve, reject }); this.processNext(); }); } /** * Clear all pending requests from the queue * Running requests will continue to completion */ flush(): void { // Reject all pending requests this.queue.forEach(item => { item.reject(new Error('Queue flushed')); }); this.queue = []; } /** * Get the current queue size (pending requests) */ get size(): number { return this.queue.length; } /** * Get the number of currently running requests */ get activeCount(): number { return this.running; } /** * Update the maximum concurrent requests limit */ setMaxConcurrent(max: number): void { this.maxConcurrent = max; // Process any queued items if we increased the limit this.processNext(); } private async processNext(): Promise { if (this.running >= this.maxConcurrent || this.queue.length === 0) { return; } const item = this.queue.shift()!; this.running++; try { const result = await item.fn(); item.resolve(result); } catch (error) { item.reject(error); } finally { this.running--; // Process next item in queue this.processNext(); } } }