"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 BaseEventStore_exports = {};
__export(BaseEventStore_exports, {
  BaseEventStore: () => BaseEventStore
});
module.exports = __toCommonJS(BaseEventStore_exports);
var import_general = require("@matter/general");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
const logger = import_general.Logger.get("BaseEventStore");
class BaseEventStore {
  #storage;
  #eventStorage;
  #nextNumber;
  constructor(storage) {
    this.#storage = storage;
    this.#eventStorage = storage.createContext(BaseEventStore.EVENTS_KEY);
  }
  clear() {
    return import_general.MaybePromise.then(
      this.close(),
      () => import_general.MaybePromise.then(
        this.#storage.clearAll(),
        () => import_general.MaybePromise.then(this.#eventStorage.clearAll(), () => {
          this.#nextNumber = 1n;
        })
      )
    );
  }
  async loadInitialState() {
    let reservationEnd;
    if (await this.#storage.has(BaseEventStore.LAST_RESERVED_NUMBER_KEY)) {
      reservationEnd = await this.#storage.get(BaseEventStore.LAST_RESERVED_NUMBER_KEY);
      if (reservationEnd !== void 0) {
        try {
          reservationEnd = BigInt(reservationEnd);
        } catch (e) {
          logger.warn(`Ignoring invalid value for last persisted event number: ${e}`);
          reservationEnd = void 0;
        }
      }
    }
    let nextNumber = reservationEnd;
    const eventNumbers = Array();
    for (const key of await this.#storage.createContext(BaseEventStore.EVENTS_KEY).keys()) {
      let number;
      try {
        number = BigInt(key);
      } catch (e) {
        if (e instanceof SyntaxError) {
          logger.warn(`Ignoring event stored with invalid key ${key}`);
          continue;
        }
        throw e;
      }
      eventNumbers.push(number);
      if (nextNumber === void 0 || nextNumber <= number) {
        nextNumber = number + 1n;
      }
    }
    this.#nextNumber = nextNumber ?? 1n;
    return { reservationEnd, eventIds: eventNumbers };
  }
  get nextNumber() {
    if (this.#nextNumber === void 0) {
      throw new import_general.InternalError("Event store numbering accessed before load");
    }
    return this.#nextNumber;
  }
  allocateNumber() {
    const number = this.nextNumber;
    this.#nextNumber = this.nextNumber + 1n;
    return number;
  }
  get storage() {
    return this.#storage;
  }
  get eventStorage() {
    return this.#eventStorage;
  }
  logLoad(type) {
    if (this.nextNumber === 1n) {
      logger.info(`Initialized new ${type} event store`);
    } else {
      logger.info(`Loaded ${type} event store with next number ${this.nextNumber}`);
    }
  }
  /**
   * If present in the store, this sub-context contains persisted events.
   */
  static EVENTS_KEY = "events";
  /**
   * If present in the store, this value designates the next event value to use on startup.
   *
   * This should really be "lastReservedNumber" but keeping old name for backwards compatibility.
   */
  static LAST_RESERVED_NUMBER_KEY = "lastEventNumber";
}
//# sourceMappingURL=BaseEventStore.js.map
