"use strict";
/* Socket Lib - Built with esbuild */
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var queue_exports = {};
__export(queue_exports, {
  PromiseQueue: () => PromiseQueue
});
module.exports = __toCommonJS(queue_exports);
var import_error = require("../primordials/error");
var import_promise = require("../primordials/promise");
class PromiseQueue {
  queue = [];
  running = 0;
  idleResolvers = [];
  maxConcurrency;
  maxQueueLength;
  /**
   * Creates a new PromiseQueue.
   *
   * @param maxConcurrency - Maximum number of promises that can run
   *   concurrently.
   * @param maxQueueLength - Maximum queue size; submissions past the cap reject
   *   with "Task dropped: queue length exceeded" instead of evicting a caller
   *   that has been waiting patiently. Callers must handle this rejection or
   *   they'll see an unhandled rejection.
   */
  constructor(maxConcurrency, maxQueueLength) {
    this.maxConcurrency = maxConcurrency;
    this.maxQueueLength = maxQueueLength;
    if (maxConcurrency < 1) {
      throw new import_error.ErrorCtor("maxConcurrency must be at least 1");
    }
  }
  /**
   * Add a task to the queue.
   *
   * @param fn - Async function to execute.
   *
   * @returns Promise that resolves with the function's result, or rejects with
   *   "Task dropped: queue length exceeded" if the queue is full.
   */
  async add(fn) {
    return await new import_promise.PromiseCtor((resolve, reject) => {
      if (this.maxQueueLength !== void 0 && this.queue.length >= this.maxQueueLength) {
        reject(new import_error.ErrorCtor("Task dropped: queue length exceeded"));
        return;
      }
      const task = { fn, resolve, reject };
      this.queue.push(task);
      this.runNext();
    });
  }
  runNext() {
    if (this.running >= this.maxConcurrency || this.queue.length === 0) {
      this.notifyIdleIfNeeded();
      return;
    }
    const task = this.queue.shift();
    if (!task) {
      return;
    }
    this.running++;
    (async () => {
      try {
        const result = await task.fn();
        task.resolve(result);
      } catch (err) {
        task.reject(err);
      } finally {
        this.running--;
        this.runNext();
      }
    })();
  }
  notifyIdleIfNeeded() {
    if (this.running === 0 && this.queue.length === 0) {
      for (const resolve of this.idleResolvers) {
        resolve();
      }
      this.idleResolvers = [];
    }
  }
  /**
   * Wait for all queued and running tasks to complete.
   */
  async onIdle() {
    if (this.running === 0 && this.queue.length === 0) {
      return;
    }
    return await new import_promise.PromiseCtor((resolve) => {
      this.idleResolvers.push(resolve);
    });
  }
  /**
   * Get the number of tasks currently running.
   */
  get activeCount() {
    return this.running;
  }
  /**
   * Get the number of tasks waiting in the queue.
   */
  get pendingCount() {
    return this.queue.length;
  }
  /**
   * Clear all pending tasks from the queue (does not affect running tasks)
   */
  clear() {
    const pending = this.queue;
    this.queue = [];
    for (const task of pending) {
      task.reject(new import_error.ErrorCtor("Task cancelled: queue cleared"));
    }
    this.notifyIdleIfNeeded();
  }
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  PromiseQueue
});
