@scayle/storefront-core
Version:
Collection of essential utilities to work with the Storefront API
113 lines (112 loc) • 2.9 kB
JavaScript
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(":");
}
}