/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { StorageDriver, StorageError } from "./StorageDriver.js";
import { fromJson, toJson } from "./StringifyTools.js";
class WebStorageDriver extends StorageDriver {
  #storage;
  #initialized = false;
  constructor(storage) {
    super();
    this.#storage = storage;
  }
  get initialized() {
    return this.#initialized;
  }
  initialize() {
    if (this.#initialized) {
      throw new StorageError("Storage already initialized!");
    }
    this.#initialized = true;
  }
  close() {
    this.#initialized = false;
  }
  clear() {
    return this.#storage.clear();
  }
  getContextBaseKey(contexts) {
    for (const ctx of contexts) {
      if (!ctx.length || ctx.includes(".")) {
        throw new StorageError("Context must not contain empty segments or leading or trailing dots.");
      }
    }
    return contexts.join(".");
  }
  buildStorageKey(contexts, key) {
    if (!key.length) {
      throw new StorageError("Key must not be an empty string.");
    }
    const contextKey = this.getContextBaseKey(contexts);
    return contextKey.length ? `${contextKey}.${key}` : key;
  }
  async get(contexts, key) {
    const value = await this.#storage.getItem(this.buildStorageKey(contexts, key));
    if (value === null) return void 0;
    return fromJson(value);
  }
  async set(contexts, keyOrValues, value) {
    if (typeof keyOrValues === "string") {
      await this.#storage.setItem(this.buildStorageKey(contexts, keyOrValues), toJson(value));
    } else {
      const entries = {};
      for (const [key, value2] of Object.entries(keyOrValues)) {
        entries[this.buildStorageKey(contexts, key)] = toJson(value2);
      }
      await this.#storage.setMany(entries);
    }
  }
  delete(contexts, key) {
    return this.#storage.removeItem(this.buildStorageKey(contexts, key));
  }
  async keys(contexts) {
    const contextKey = this.getContextBaseKey(contexts);
    const keys = [];
    const allKeys = await this.#storage.getAllKeys();
    if (contextKey.length) {
      const contextKeyStart = `${contextKey}.`;
      for (const key of allKeys) {
        if (key.startsWith(contextKeyStart) && !key.includes(".", contextKeyStart.length)) {
          keys.push(key.substring(contextKeyStart.length));
        }
      }
    } else {
      for (const key of allKeys) {
        if (!key.includes(".")) {
          keys.push(key);
        }
      }
    }
    return keys;
  }
  async values(contexts) {
    const keys = await this.keys(contexts);
    const storageKeys = keys.map((key) => this.buildStorageKey(contexts, key));
    const entries = await this.#storage.getMany(storageKeys);
    const values = {};
    for (const [index, key] of keys.entries()) {
      const value = entries[storageKeys[index]];
      if (value !== null && value !== void 0) {
        values[key] = fromJson(value);
      }
    }
    return values;
  }
  async contexts(contexts) {
    const contextKey = this.getContextBaseKey(contexts);
    const startContextKey = contextKey.length ? `${contextKey}.` : "";
    const foundContexts = /* @__PURE__ */ new Set();
    const allKeys = await this.#storage.getAllKeys();
    for (const key of allKeys) {
      if (key.startsWith(startContextKey)) {
        const subKeys = key.substring(startContextKey.length).split(".");
        if (subKeys.length === 1) continue;
        const context = subKeys[0];
        foundContexts.add(context);
      }
    }
    return Array.from(foundContexts);
  }
  async clearAll(contexts) {
    const contextKey = this.getContextBaseKey(contexts);
    const startContextKey = contextKey.length ? `${contextKey}.` : "";
    const allKeys = await this.#storage.getAllKeys();
    const keysToDelete = [];
    for (const key of allKeys) {
      if (key.startsWith(startContextKey)) {
        keysToDelete.push(key);
      }
    }
    if (keysToDelete.length) {
      await this.#storage.removeMany(keysToDelete);
    }
  }
}
export {
  WebStorageDriver
};
//# sourceMappingURL=WebStorageDriver.js.map
