export class BrowserLock {
    chain = Promise.resolve();
    active = false;
    waiters = 0;
    /**
     * Queue for exclusive browser access. The returned promise resolves once
     * everyone ahead of us has released. release() MUST be called even on
     * failure paths — typically inside finally — or the chain wedges forever.
     */
    acquire() {
        let releaseNext;
        const next = new Promise((resolve) => {
            releaseNext = resolve;
        });
        this.waiters++;
        const promise = this.chain.then(() => {
            this.waiters--;
            this.active = true;
        });
        this.chain = promise.then(() => next);
        let released = false;
        const release = () => {
            if (released)
                return;
            released = true;
            this.active = false;
            releaseNext();
        };
        return { promise, release };
    }
    /**
     * Acquire only if nothing else is holding or waiting. Used by the Chrome
     * runtime watchdog so an aged-Chrome restart never preempts in-flight
     * work. Returns null if contended.
     */
    tryAcquire() {
        if (!this.isIdle())
            return null;
        return this.acquire();
    }
    /** True when no one holds the lock and no one is waiting. */
    isIdle() {
        return !this.active && this.waiters === 0;
    }
}
//# sourceMappingURL=browser-lock.js.map