export class AsyncQueue {
    concurrency;
    queue = [];
    running = 0;
    constructor(concurrency = 1) {
        this.concurrency = concurrency;
        if (concurrency < 1) {
            throw new Error("Concurrency must be at least 1");
        }
    }
    /**
     * Add a task to the queue
     */
    async add(task) {
        return new Promise((resolve, reject) => {
            this.queue.push({ task, resolve, reject });
            this.process();
        });
    }
    /**
     * Process the next task in the queue if we have capacity
     */
    async process() {
        if (this.running >= this.concurrency || this.queue.length === 0) {
            return;
        }
        this.running++;
        const { task, resolve, reject } = this.queue.shift();
        try {
            const result = await task();
            resolve(result);
        }
        catch (error) {
            reject(error);
        }
        finally {
            this.running--;
            this.process(); // Process next task
        }
    }
    /**
     * Get the current queue size
     */
    get size() {
        return this.queue.length;
    }
    /**
     * Get the number of currently running tasks
     */
    get pending() {
        return this.running;
    }
    /**
     * Check if the queue is idle (no running or queued tasks)
     */
    get idle() {
        return this.running === 0 && this.queue.length === 0;
    }
    /**
     * Wait for all current tasks to complete
     */
    async onIdle() {
        if (this.idle)
            return;
        return new Promise((resolve) => {
            const check = () => {
                if (this.idle) {
                    resolve();
                }
                else {
                    setTimeout(check, 10);
                }
            };
            check();
        });
    }
    /**
     * Clear all queued tasks (doesn't affect running tasks)
     */
    clear() {
        this.queue.forEach(({ reject }) => {
            reject(new Error("Task was cleared from queue"));
        });
        this.queue = [];
    }
}
//# sourceMappingURL=async-queue.js.map