/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { InternalError, Logger, MaybePromise } from "@matter/general";
import { BaseEventStore } from "./BaseEventStore.js";
import { OccurrenceSummary } from "./EventStore.js";
const logger = Logger.get("EphemeralEventStore");
class VolatileEventStore extends BaseEventStore {
  #numbersReservedTo;
  #numberBlockSize = 1e3;
  #events = /* @__PURE__ */ new Map();
  #reservationWrite;
  /**
   * Uses {@link storage} for persistence of "next" event number across restarts.
   *
   * {@link numberBlockSize} specifies how often storage is update with a new starting point.  A larger number reduces
   * writes but must remain small enough to avoid exhausting the full 64-bit even numbering space.
   */
  constructor(storage, numberBlockSize = 1e3) {
    super(storage);
    this.#numberBlockSize = numberBlockSize;
  }
  async load() {
    const { reservationEnd, eventIds } = await this.loadInitialState();
    if (eventIds.length) {
      logger.warn("Converting non-volatile state store to volatile");
      await this.eventStorage.clear();
    }
    this.#numbersReservedTo = reservationEnd;
    this.logLoad("volatile");
    return [];
  }
  get(number) {
    const event = this.#events.get(number);
    if (event === void 0) {
      throw new InternalError(`Invalid event occurrence #${number}`);
    }
    return event;
  }
  delete(number) {
    return this.storage.delete(number.toString());
  }
  add(occurrence) {
    if (this.#reservationWrite) {
      let write = void 0;
      const whenReady = () => {
        if (this.#reservationWrite === write) {
          this.#reservationWrite = void 0;
        }
        return this.add(occurrence);
      };
      write = this.#reservationWrite.then(whenReady, whenReady);
    }
    const number = this.allocateNumber();
    const key = OccurrenceSummary(number, occurrence);
    const reservedTo = this.#numbersReservedTo ?? 1n;
    if (number >= reservedTo) {
      const reserveTo = reservedTo + BigInt(this.#numberBlockSize);
      let write = void 0;
      write = MaybePromise.then(this.storage.set(BaseEventStore.LAST_RESERVED_NUMBER_KEY, reserveTo), () => {
        this.#numbersReservedTo = reserveTo;
        this.#events.set(number, occurrence);
        if (write !== void 0 && this.#reservationWrite === write) {
          this.#reservationWrite = void 0;
        }
        return key;
      });
    }
    this.#events.set(number, occurrence);
    return key;
  }
  clear() {
    return MaybePromise.then(super.clear(), () => {
      this.#events = /* @__PURE__ */ new Map();
      this.#numbersReservedTo = void 0;
    });
  }
  close() {
    if (this.#reservationWrite) {
      return this.#reservationWrite?.then(
        () => {
        },
        () => {
        }
      );
    }
  }
}
export {
  VolatileEventStore
};
//# sourceMappingURL=VolatileEventStore.js.map
