/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { DataNamespace } from "./DataNamespace.js";
class DatafileRoot extends DataNamespace {
  #directory;
  #release;
  #refs = 0;
  #lockPromise;
  constructor(directory) {
    super(directory.name);
    this.#directory = directory;
  }
  get directory() {
    return this.#directory;
  }
  get path() {
    return this.#directory.path;
  }
  get isLocked() {
    return this.#refs > 0;
  }
  /**
   * Number of outstanding {@link DatafileRoot.Lock} references.  Surfaced for diagnostics so an unbalanced
   * acquire/release shows up in storage open/close logs.
   */
  get lockCount() {
    return this.#refs;
  }
  /**
   * Acquire a reference-counted lock.  The physical directory lock is acquired on the first call and released when
   * the last {@link DatafileRoot.Lock} closes.
   */
  async lock() {
    if (this.#lockPromise) {
      await this.#lockPromise;
    }
    const promise = this.#acquireRef();
    this.#lockPromise = promise;
    try {
      return await promise;
    } finally {
      if (this.#lockPromise === promise) {
        this.#lockPromise = void 0;
      }
    }
  }
  async #acquireRef() {
    if (this.#refs === 0) {
      this.#release = await this.#directory.lock();
    }
    this.#refs++;
    return new DatafileRoot.Lock(this.#directory, () => this.#releaseRef());
  }
  async #releaseRef() {
    this.#refs--;
    if (this.#refs === 0) {
      const release = this.#release;
      this.#release = void 0;
      await release?.();
    }
  }
}
((DatafileRoot2) => {
  class Lock {
    #directory;
    #release;
    constructor(directory, release) {
      this.#directory = directory;
      this.#release = release;
    }
    get directory() {
      return this.#directory;
    }
    get path() {
      return this.#directory.path;
    }
    async close() {
      const release = this.#release;
      if (release) {
        this.#release = void 0;
        await release();
      }
    }
    async [Symbol.asyncDispose]() {
      await this.close();
    }
  }
  DatafileRoot2.Lock = Lock;
})(DatafileRoot || (DatafileRoot = {}));
export {
  DatafileRoot
};
//# sourceMappingURL=DatafileRoot.js.map
