UNPKG

@scayle/storefront-core

Version:

Collection of essential utilities to work with the Storefront API

113 lines (112 loc) 2.9 kB
export class UnstorageCache { /** * The underlying Unstorage storage instance. */ storage; /** * Key prefix used for namespacing cache entries. */ prefix; /** * Creates a new UnstorageCache instance. * * @param storage The Unstorage storage instance. * @param prefix Optional key prefix for namespacing. Defaults to an empty string. */ constructor(storage, prefix = "") { this.storage = storage; this.prefix = prefix; } /** * Retrieves a cached value by key. * * @param key The cache key. * @returns The cached value or null if not found. */ async get(key) { const value = await this.storage.getItem(this.getKey(key)); if (value === null) { return null; } return value; } /** * Checks if a key exists in the cache. * * @param key The cache key. * @returns True if the key exists, false otherwise. */ async has(key) { return await this.storage.hasItem(this.getKey(key)); } /** * Purges cache entries associated with the given tags. * * @param tags An array of tags to purge. */ async purgeTags(tags) { await Promise.all(tags.map((tag) => this.purgeTag(tag))); } /** * Purges cache entries associated with a specific tag. * * @param tag The tag to purge. */ async purgeTag(tag) { const keys = await this.storage.getItem(this.getKey(`tag:${tag}`)); await this.purgeKeys(keys ?? []); await this.storage.removeItem(this.getKey(`tag:${tag}`)); } /** * Purges cache entries by their keys. * * @param keys An array of keys to purge. */ async purgeKeys(keys) { await Promise.all(keys.map((k) => this.storage.removeItem(k))); } /** * Purges all cache entries. */ async purgeAll() { const keys = await this.storage.getKeys(this.prefix); await Promise.all(keys.map((k) => this.storage.removeItem(k))); } /** * Sets a value in the cache. * * @param key The cache key. * @param value The value to cache. * @param ttl Time-to-live in milliseconds. * @param tags Optional tags to associate with the cache entry. */ async set(key, value, ttl, tags = []) { await this.storage.setItem(this.getKey(key), value, { ttl }); await Promise.all( tags.map((tag) => this.addKeyToTag(tag, this.getKey(key))) ); } /** * Adds a key to a tag's list of associated keys. * * @param tag The tag. * @param key The key to add. * @private */ async addKeyToTag(tag, key) { const keys = await this.storage.getItem(tag); const set = new Set(keys ?? []); set.add(key); await this.storage.setItem(this.getKey(`tag:${tag}`), Array.from(set)); } /** * Generates a namespaced key. * * @param key The key to namespace. * @returns The namespaced key. * @private */ getKey(key) { return [this.prefix, key].join(":"); } }