"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 JsonFileStorageDriver_exports = {};
__export(JsonFileStorageDriver_exports, {
  JsonFileStorageDriver: () => JsonFileStorageDriver
});
module.exports = __toCommonJS(JsonFileStorageDriver_exports);
var import_general = require("@matter/general");
var import_node_fs = require("node:fs");
var import_promises = require("node:fs/promises");
var import_node_path = require("node:path");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class JsonFileStorageDriver extends import_general.FilesystemStorageDriver {
  static id = "json";
  /** We store changes after a value was set to the storage, but not more often than this setting (in ms). */
  static commitDelay = import_general.Seconds.one;
  committed = Promise.resolve();
  #commitTimer = import_general.Time.getTimer("Storage commit", JsonFileStorageDriver.commitDelay, () => this.#commit());
  #closed = false;
  #resolveCommitted;
  #path;
  #store;
  constructor(namespaceOrPath) {
    super(typeof namespaceOrPath === "string" || namespaceOrPath === void 0 ? void 0 : namespaceOrPath);
    this.#path = typeof namespaceOrPath === "string" ? namespaceOrPath : namespaceOrPath !== void 0 ? (0, import_node_path.join)(this.root.directory.path, "storage.json") : "";
    this.#store = new import_general.MemoryStorageDriver();
  }
  static async create(namespace, _descriptor) {
    const storage = new JsonFileStorageDriver(namespace);
    try {
      await storage.initialize();
    } catch (error) {
      await storage.close().catch(() => {
      });
      throw error;
    }
    return storage;
  }
  get initialized() {
    return this.#store.initialized;
  }
  async initialize() {
    if (this.initialized) throw new import_general.StorageError("Storage already initialized!");
    await super.initialize();
    let data = {};
    try {
      data = (0, import_general.fromJson)((0, import_node_fs.readFileSync)(this.#path, "utf-8"));
    } catch (error) {
      if (error.code !== "ENOENT") {
        throw error;
      }
    }
    this.#store = new import_general.MemoryStorageDriver(data);
    this.#store.initialize();
  }
  #triggerCommit() {
    if (!this.#commitTimer.isRunning) {
      this.committed = new Promise((resolve) => {
        this.#resolveCommitted = resolve;
      });
      this.#commitTimer.start();
    }
  }
  get(contexts, key) {
    return this.#store.get(contexts, key);
  }
  set(contexts, keyOrValues, value) {
    this.#store.set(contexts, keyOrValues, value);
    this.#triggerCommit();
  }
  delete(contexts, key) {
    this.#store.delete(contexts, key);
    this.#triggerCommit();
  }
  keys(contexts) {
    return this.#store.keys(contexts);
  }
  values(contexts) {
    return this.#store.values(contexts);
  }
  contexts(contexts) {
    return this.#store.contexts(contexts);
  }
  clearAll(contexts) {
    this.#store.clearAll(contexts);
  }
  openBlob(contexts, key) {
    return this.#store.openBlob(contexts, key);
  }
  writeBlobFromStream(contexts, key, stream) {
    return this.#store.writeBlobFromStream(contexts, key, stream);
  }
  async #commit() {
    if (!this.initialized || this.#closed) return;
    if (this.#commitTimer.isRunning) {
      this.#commitTimer.stop();
    }
    try {
      await (0, import_promises.writeFile)(this.#path, (0, import_general.toJson)(this.#store.data, 1), "utf-8");
    } finally {
      if (this.#resolveCommitted !== void 0) {
        this.#resolveCommitted();
      }
    }
  }
  async close() {
    this.#commitTimer.stop();
    await this.#commit();
    await this.#store.close();
    this.#closed = true;
    await super.close();
  }
}
//# sourceMappingURL=JsonFileStorageDriver.js.map
