"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const _CleanupQueue = class _CleanupQueue {
  constructor() {
    this.tasks = /* @__PURE__ */ new Map();
    this.timeoutId = null;
    this.microtaskScheduled = false;
  }
  static getInstance() {
    if (!_CleanupQueue.instance) {
      _CleanupQueue.instance = new _CleanupQueue();
    }
    return _CleanupQueue.instance;
  }
  /**
   * Queues a cleanup task and defers timeout selection to a microtask so
   * multiple synchronous registrations can share one root timer.
   */
  schedule(key, gcTime, callback) {
    const executeAt = Date.now() + gcTime;
    this.tasks.set(key, { executeAt, callback });
    if (!this.microtaskScheduled) {
      this.microtaskScheduled = true;
      Promise.resolve().then(() => {
        this.microtaskScheduled = false;
        this.updateTimeout();
      });
    }
  }
  cancel(key) {
    this.tasks.delete(key);
  }
  /**
   * Keeps only one active timeout: whichever task is due next.
   */
  updateTimeout() {
    if (this.timeoutId !== null) {
      clearTimeout(this.timeoutId);
      this.timeoutId = null;
    }
    if (this.tasks.size === 0) {
      return;
    }
    let earliestTime = Infinity;
    for (const task of this.tasks.values()) {
      if (task.executeAt < earliestTime) {
        earliestTime = task.executeAt;
      }
    }
    const delay = Math.max(0, earliestTime - Date.now());
    this.timeoutId = setTimeout(() => this.process(), delay);
  }
  /**
   * Runs every task whose deadline has passed, then schedules the next wakeup
   * if there is still pending work.
   */
  process() {
    this.timeoutId = null;
    const now = Date.now();
    for (const [key, task] of this.tasks.entries()) {
      if (now >= task.executeAt) {
        this.tasks.delete(key);
        try {
          task.callback();
        } catch (error) {
          console.error("Error in CleanupQueue task:", error);
        }
      }
    }
    if (this.tasks.size > 0) {
      this.updateTimeout();
    }
  }
  /**
   * Resets the singleton instance for tests.
   */
  static resetInstance() {
    if (_CleanupQueue.instance) {
      if (_CleanupQueue.instance.timeoutId !== null) {
        clearTimeout(_CleanupQueue.instance.timeoutId);
      }
      _CleanupQueue.instance = null;
    }
  }
};
_CleanupQueue.instance = null;
let CleanupQueue = _CleanupQueue;
exports.CleanupQueue = CleanupQueue;
//# sourceMappingURL=cleanup-queue.cjs.map
