Caching
High-performance caching and distributed locking for OmniSvelte.
Caching
OmniSvelte provides a unified caching and locking layer with pluggable drivers (memory, redis, null, array).
Configuration
Configure stores in your vite.config.ts via the omniSvelte plugin:
ts
import { defineConfig } from 'vitest/config';
import { omniSvelte } from 'omni-svelte/vite';
export default defineConfig({
plugins: [
omniSvelte({
// Configure cache stores
cache: {
default: 'main',
stores: {
main: { driver: 'memory', ttl: 3600 },
redis: { driver: 'redis', url: process.env.REDIS_URL, ttl: 86400, prefix: 'app:' },
sessions: { driver: 'redis', url: process.env.REDIS_URL, prefix: 'sess:', ttl: 604800 }
}
}
})
]
});Basic Usage
Import the cache façade from $omni/cache. Because this is a server-only module, Vite will warn you if you attempt to import it from a universal +page.svelte file.
ts
import { cache } from '$omni/cache';
// Get and Set (TTL is always the last argument options object)
await cache.set('user:1', user, { ttl: 300 });
const user = await cache.get<User>('user:1');
await cache.delete('user:1');
await cache.has('user:1');
// Remember (cache aside)
const post = await cache.remember('post:1', () => Post.find(1), { ttl: 600 });
const settings = await cache.rememberForever('settings', () => loadSettings());
// Named Stores
const sessionCache = cache.store('sessions');
await sessionCache.set('token:123', session);Tagged Invalidation
Group related cache entries using tags (Supported natively by memory and redis drivers):
ts
// Tag cache entries
await cache.tags('posts', 'user:1').set('post:10', postData);
// Invalidate all entries tagged 'posts'
await cache.tags('posts').flush();
// Namespace helper (syntactic sugar over tags)
const userCache = cache.namespace('user');
await userCache.set('profile', profile);
await userCache.flush();Distributed Locking
Prevent stampedes and race conditions using locks:
ts
// Blocking: waits for the lock up to maxWait (default 10s), throws LockTimeoutError if exceeded
await cache.lock('generate:report', { ttl: 30 }).block(async () => {
return await buildReport();
});
// Non-blocking: attempts lock once, returns false immediately if already held
const ran = await cache.lock('nightly:prune', { ttl: 60 }).attempt(async () => {
await pruneExpiredRecords();
});Custom Drivers
You can create your own cache drivers by implementing the CacheStore interface and registering them on the global cache manager:
ts
import { cache, defineCacheDriver } from '$omni/cache';
const myCustomDriver = defineCacheDriver((config) => {
return new CustomCacheStore(config);
});
cache.extend('custom', myCustomDriver);