"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 async_exports = {};
__export(async_exports, {
  memoizeAsync: () => memoizeAsync
});
module.exports = __toCommonJS(async_exports);
var import_output = require("../debug/output");
var import_date = require("../primordials/date");
var import_map_set = require("../primordials/map-set");
var import_promise = require("../primordials/promise");
var import_internal = require("./_internal");
function memoizeAsync(fn, options = {}) {
  const {
    keyGen = (...args) => (0, import_internal.defaultKeyGen)(args),
    maxSize = Number.POSITIVE_INFINITY,
    name = fn.name || "anonymous",
    ttl = Number.POSITIVE_INFINITY
  } = options;
  const cache = new import_map_set.MapCtor();
  import_internal.cacheRegistry.push(() => {
    cache.clear();
  });
  function evictLRU() {
    if (cache.size >= maxSize) {
      const oldest = cache.keys().next().value;
      if (oldest !== void 0) {
        cache.delete(oldest);
        (0, import_output.debugLog)(`[memoizeAsync:${name}] clear`, {
          key: oldest,
          reason: "LRU"
        });
      }
    }
  }
  function isExpired(entry) {
    if (ttl === Number.POSITIVE_INFINITY) {
      return false;
    }
    return (0, import_date.DateNow)() - entry.timestamp > ttl;
  }
  function bumpRecency(key, entry) {
    cache.delete(key);
    cache.set(key, entry);
  }
  const refreshing = new import_map_set.MapCtor();
  return async function memoized(...args) {
    const key = keyGen(...args);
    const cached = cache.get(key);
    if (cached) {
      if (!isExpired(cached)) {
        cached.hits++;
        bumpRecency(key, cached);
        (0, import_output.debugLog)(`[memoizeAsync:${name}] hit`, { key, hits: cached.hits });
        return await cached.value;
      }
      const inflight = refreshing.get(key);
      if (inflight) {
        (0, import_output.debugLog)(`[memoizeAsync:${name}] stale-dedup`, { key });
        bumpRecency(key, cached);
        return await inflight;
      }
      cache.delete(key);
    }
    const inflightCold = refreshing.get(key);
    if (inflightCold) {
      (0, import_output.debugLog)(`[memoizeAsync:${name}] cold-dedup`, { key });
      return await inflightCold;
    }
    (0, import_output.debugLog)(`[memoizeAsync:${name}] miss`, { key });
    const promise = (async () => {
      try {
        const result = await fn(...args);
        refreshing.delete(key);
        const entry = cache.get(key);
        if (entry) {
          entry.value = (0, import_promise.PromiseResolve)(result);
          entry.timestamp = (0, import_date.DateNow)();
        }
        return result;
      } catch (error) {
        refreshing.delete(key);
        cache.delete(key);
        (0, import_output.debugLog)(`[memoizeAsync:${name}] error`, { key, error });
        throw error;
      }
    })();
    refreshing.set(key, promise);
    evictLRU();
    cache.set(key, {
      value: promise,
      timestamp: Date.now(),
      hits: 0
    });
    (0, import_output.debugLog)(`[memoizeAsync:${name}] set`, { key, cacheSize: cache.size });
    return await promise;
  };
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  memoizeAsync
});
