"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 Cache_exports = {};
__export(Cache_exports, {
  AsyncCache: () => AsyncCache,
  Cache: () => Cache
});
module.exports = __toCommonJS(Cache_exports);
var import_Diagnostic = require("../log/Diagnostic.js");
var import_Time = require("../time/Time.js");
/**
 * Cache computed values or resources for a specified duration to improve performances.
 *
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class GenericCache {
  constructor(name, expiration, expireCallback) {
    this.expiration = expiration;
    this.expireCallback = expireCallback;
    this.periodicTimer = import_Time.Time.getPeriodicTimer(
      import_Diagnostic.Diagnostic.upgrade(`${name} cache expiration`, [import_Diagnostic.Diagnostic.strong(name), "cache expiration"]),
      expiration,
      () => this.expire()
    ).start();
    this.periodicTimer.utility = true;
  }
  knownKeys = /* @__PURE__ */ new Set();
  values = /* @__PURE__ */ new Map();
  timestamps = /* @__PURE__ */ new Map();
  periodicTimer;
  keys() {
    return Array.from(this.knownKeys.values());
  }
  async delete(key) {
    const value = this.values.get(key);
    if (this.expireCallback !== void 0 && value !== void 0) {
      await this.expireCallback(key, value);
    }
    this.values.delete(key);
    this.timestamps.delete(key);
  }
  async clear() {
    for (const key of this.values.keys()) {
      await this.delete(key);
    }
    this.values.clear();
    this.timestamps.clear();
  }
  async close() {
    await this.clear();
    this.knownKeys.clear();
    this.periodicTimer.stop();
  }
  async expire() {
    const now = import_Time.Time.nowMs;
    for (const [key, timestamp] of this.timestamps.entries()) {
      if (now - timestamp < this.expiration) continue;
      await this.delete(key);
    }
  }
}
class Cache extends GenericCache {
  constructor(name, generator, expiration, expireCallback) {
    super(name, expiration, expireCallback);
    this.generator = generator;
  }
  get(...params) {
    const key = params.join(",");
    let value = this.values.get(key);
    if (value === void 0) {
      value = this.generator(...params);
      this.values.set(key, value);
      this.knownKeys.add(key);
    }
    this.timestamps.set(key, import_Time.Time.nowMs);
    return value;
  }
}
class AsyncCache extends GenericCache {
  constructor(name, generator, expiration, expireCallback) {
    super(name, expiration, expireCallback);
    this.generator = generator;
  }
  async get(...params) {
    const key = params.join(",");
    let value = this.values.get(key);
    if (value === void 0) {
      value = await this.generator(...params);
      this.values.set(key, value);
      this.knownKeys.add(key);
    }
    this.timestamps.set(key, import_Time.Time.nowMs);
    return value;
  }
}
//# sourceMappingURL=Cache.js.map
