/** * @license * Copyright 2022-2024 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ import { MaybePromise } from "../util/Promises.js"; import { Storage, StorageError, StorageOperationResult } from "./Storage.js"; import { SupportedStorageTypes } from "./StringifyTools.js"; export class StorageContext { constructor( private readonly storage: S, readonly thisContexts: string[], ) {} get(key: string, defaultValue?: T): StorageOperationResult { const value = this.storage.get(this.thisContexts, key); if (value !== undefined) { if (MaybePromise.is(value)) { return value.then(v => { if (v !== undefined) return v; if (defaultValue === undefined) { throw new StorageError( `No value found for key ${key} in context ${this.thisContexts} and no default value specified!`, ); } return defaultValue; }) as StorageOperationResult; } return value as StorageOperationResult; } if (defaultValue === undefined) { throw new StorageError( `No value found for key ${key} in context ${this.thisContexts} and no default value specified!`, ); } return defaultValue as StorageOperationResult; } has(key: string) { const value = this.storage.get(this.thisContexts, key); if (value !== undefined) { if (MaybePromise.is(value)) { return value.then(v => v !== undefined) as StorageOperationResult; } return true as StorageOperationResult; } return false as StorageOperationResult; } set(key: string, value: SupportedStorageTypes): StorageOperationResult; set(values: Record): StorageOperationResult; set(keyOrValues: string | Record, value?: SupportedStorageTypes) { if (typeof keyOrValues === "string") { return this.storage.set(this.thisContexts, keyOrValues, value) as StorageOperationResult; } return this.storage.set(this.thisContexts, keyOrValues) as StorageOperationResult; } delete(key: string) { return this.storage.delete(this.thisContexts, key) as StorageOperationResult; } createContext(context: string): StorageContext { if (context.length === 0) throw new StorageError("Context must not be an empty string"); if (context.includes(".")) throw new StorageError("Context must not contain dots!"); return new StorageContext(this.storage, [...this.thisContexts, context]); } keys() { return this.storage.keys(this.thisContexts) as StorageOperationResult; } values() { return this.storage.values(this.thisContexts) as StorageOperationResult< S, Record >; } contexts() { return this.storage.contexts(this.thisContexts) as StorageOperationResult; } /** Clears all keys in this context */ clear() { const keys = this.keys(); if (MaybePromise.is(keys)) { return keys.then(keys => { return Promise.all(keys.map(key => this.delete(key))).then(() => Promise.resolve()); }) as StorageOperationResult; } const promises = new Array>(); keys.forEach(key => { const promise = this.delete(key); if (promise !== undefined && MaybePromise.is(promise)) { promises.push(promise); } }); if (promises.length > 0) { return Promise.all(promises).then(() => Promise.resolve()) as StorageOperationResult; } return undefined as StorageOperationResult; } /** Clears all keys in this context and all created sub-contexts. */ clearAll() { return this.storage.clearAll(this.thisContexts) as StorageOperationResult; } }