Implementation of Redis-like cache - a key-value store with expiring keys. Data is stored in the Val Town SQLite database and shared between all your vals.
- First you should decide on a name of a SQL table that will be used for storing cache data. It could something like
cacheDataorkv. Set that value to a new Environment VariableCACHE_TABLE_NAME. - Optionally you might add a new
CACHE_DEFAULT_TTLEnvironment Variable. It's value should be set to a number of seconds that will be used when saving new values to the cache without providing the expiration time. By default it's 24h. - The
setup()function should be ran before using the cache for the first time. You can do that by creating a small temporary Val:import { setup } from "https://esm.town/v/xkonti/cache"; await setup(); - Optionally create a scheduled val that will delete expired keys on some interval - 15 minutes can be a good start.
import { deleteExpired } from "https://esm.town/v/xkonti/cache"; export default async function cacheCleaner(interval: Interval) { await deleteExpired(); }
After setting your cache up you can use it simply by importing functions from https://esm.town/v/xkonti/cache.
Set a value in the cache.
key- the key to set the value forvalue- the value to set - it can be any value that can be serialized to JSONttl- the time to live in seconds. In other words, after how many seconds the key will expire. If not set, the default TTL is used.- returns the number of keys set:
1if the key was inserted/updated,0if the ttl was0or invalid
// Set a value in the cache with a default TTL
await set("luckyNumber", 13);
// Set a value that will expire in 5 minutes
await set("product:344798", { name: "Audio Interface", price: 209.99}, 5 * 60);
Set a value in the cache until a specific date and time.
key- the key to set the value forvalue- the value to set - it can be any value that can be serialized to JSONexpiresAt- the expiration time as a UTC date string- returns the number of keys set:
1if the key was inserted/updated,0if the `expiresAt`` was in the past
// Set a value in the cache until 2024-01-01 16:23:05 UTC
await setUntil(
"product:155392",
{ name: "Audio Interface", price: 209.99 },
new Date('2024-01-01T16:23:05Z').toISOString()
);
Update the expiration date of a cache entry based on TTL. If the key does not exist or is expired, nothing happens.
key- the key of the cache entry to updatettl- the time to live in seconds from now. In other words, after how many seconds the key will expire. If not set, the default TTL is used.- returns the number of keys updated:
1if updated,0if not found or ttl was0
// Set the expiration date in the cache with a default TTL
await setExpiration("luckyNumber");
// Set the expiration date in the cache for 5 minutes from now.
await setExpiration("luckyNumber", 5 * 60);
Update the expiration date of a cache entry to a specific UTC date and time. If the key does not exist or is expired, nothing happens.
key- the key of the cache entry to updateexpiresAt- the expiration time as a UTC date string- returns the number of keys updated:
1if updated,0if not found orexpiresAtwas in the past
// Set the expiration date in the cache until 2024-01-01 16:23:05 UTC
await setExpirationUntil(
"product:155392",
new Date('2024-01-01T16:23:05Z').toISOString()
);
Checks if the provided key exists (has value) in the cache. If the key is expired, it's considered non-existent.
key- the key to check for existence
// Check if the key is present in the cache
const hasLuckyNumber: Boolean = await exists("luckyNumber");
Get a value from the cache by key. You can provide a type of the return value or it will default to unknown. If there is no value for the key or the value has expired, null is returned.
key- the key to get the value for
// Get a value from the cache
const luckyNumber: number = await get<number>("luckyNumber");
const luckyNumber: number = await get("luckyNumber") as number; // same as above
Gets a list of all non-expired keys in the cache that match the prefix. If no prefix is provided, all keys are returned.
prefix- the optional prefix to match keys against
// Get all keys from the cache
const keys: string[] = await listKeys();
// Get all keys from the cache that start with "product:"
const keys: string[] = await listKeys("product:");
Get many key-value pairs from the cache that match the given prefix.
prefix- the optional prefix to match keys against. If not provided, all keys are considered.limit- the optional maximum number of key-value pairs to return. If0, no limit is applied. Defaults to0.- returns An array of key-value pairs. Each pair is an object with
keyandvalueproperties.
// Get all non-expired keys and their values
const everything = await getMany();
// Get all keys and values with a matching prefix
const allProducts = await getMany("product:");
// Get 5 keys and values with a matching prefix
const discountedProducts = await getMany("discounts:", 5);
Delete a key from the cache.
key- the key to delete- returns the number of keys deleted:
1if the key was deleted,0if the key did not exist.
// Delete a key from the cache
await deleteKey("luckyNumber");
Delete all keys from the cache that match the prefix. If no prefix is provided, all keys in the cache are deleted.
prefix- the optional prefix to match keys against- returns the number of keys deleted
// Delete all keys from the cache
await deleteKeys();
// Delete all keys from the cache that start with "product:"
await deleteKeys("product:");
Delete all expired keys from the cache. Perfect for running on a schedule to keep the cache small and fast.
- returns the number of keys deleted
// Delete all expired keys from the cache
await deleteExpired();