"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PromiseQueue = void 0;
/**
 * A simple serial promise queue.
 * Enqueued functions execute one at a time, in order.
 * If a function rejects, the error propagates to the caller
 * but the queue continues processing subsequent items.
 */
class PromiseQueue {
    queue = [];
    running = false;
    /**
     * Enqueue an async function. Returns a promise that resolves/rejects
     * with the function's result once it has been executed in turn.
     */
    enqueue(fn) {
        return new Promise((resolve, reject) => {
            this.queue.push(async () => {
                try {
                    resolve(await fn());
                }
                catch (e) {
                    reject(e);
                }
            });
            if (!this.running)
                this.drain();
        });
    }
    /**
     * Wait for all currently enqueued tasks to finish.
     * Resolves immediately if the queue is empty.
     */
    async waitForPending() {
        if (!this.running && this.queue.length === 0)
            return;
        return this.enqueue(async () => { });
    }
    async drain() {
        this.running = true;
        while (this.queue.length > 0) {
            const task = this.queue.shift();
            await task();
        }
        this.running = false;
    }
}
exports.PromiseQueue = PromiseQueue;
