Custom Cache Strategy
Learn how to implement custom persistence backends (e.g. Redis, WebWorker, IndexedDB LRU, or BroadcastChannel) by extending ACacheProvider and registering them via CacheProviderFactory.
Katlux allows you to plug any custom caching driver into RequestProvider and data providers without modifying core toolkit code.
- 1. Subclass ACacheProvider: Implement the standard contract (get, set, remove, removeByPrefix, getKeyList, getRemainingTime, cleanupExpired).
- 2. Register with CacheProviderFactory: Use
CacheProviderFactory.registerDriver() with an async dynamic loader for optimal tree-shaking, or pass the class directly. - 3. Use Anywhere: Pass your strategy name directly to
RequestProvider, CAPIFlatServerDataProvider, or fetch it via CacheProviderFactory.getProvider().
// 1. Define your custom cache driver (e.g. ~/services/cache/CMyCustomCache.ts)
import { ACacheProvider, type ICacheEntry } from '@katlux/providers'
export class CMyCustomCache extends ACacheProvider {
private static instance: CMyCustomCache | null = null
private storage = new Map<string, ICacheEntry<any>>()
public static getInstance(): CMyCustomCache {
if (!this.instance) {
this.instance = new CMyCustomCache()
}
return this.instance
}
async getKeyList(nuxtApp?: any): Promise<string[]> {
return Array.from(this.storage.keys())
}
async get<T>(key: string, nuxtApp?: any): Promise<T | null> {
const entry = this.storage.get(key)
if (!entry) return null
if (Date.now() > entry.timestamp + entry.lifetime) {
this.storage.delete(key)
return null
}
return entry.data as T
}
async set<T>(key: string, data: T, lifetime: number, nuxtApp?: any): Promise<void> {
this.storage.set(key, { data, timestamp: Date.now(), lifetime })
}
async remove(key: string, nuxtApp?: any): Promise<void> {
this.storage.delete(key)
}
async removeByPrefix(prefix: string, nuxtApp?: any): Promise<void> {
for (const key of this.storage.keys()) {
if (key.startsWith(prefix)) this.storage.delete(key)
}
}
async getRemainingTime(key: string, nuxtApp?: any): Promise<number | null> {
const entry = this.storage.get(key)
if (!entry) return null
const remaining = (entry.timestamp + entry.lifetime) - Date.now()
return remaining > 0 ? remaining : null
}
async cleanupExpired(): Promise<void> {
const now = Date.now()
for (const [key, entry] of this.storage.entries()) {
if (now > entry.timestamp + entry.lifetime) {
this.storage.delete(key)
}
}
}
}
// 2. Register driver in a Nuxt plugin or app initialization
import { CacheProviderFactory } from '@katlux/providers'
// Option A: Code-split dynamic loader (Recommended)
CacheProviderFactory.registerDriver('MyCustom', async () => {
const { CMyCustomCache } = await import('~/services/cache/CMyCustomCache')
return CMyCustomCache
})
// Option B: Synchronous pre-bundled driver
// CacheProviderFactory.registerDriver('MyCustom', CMyCustomCache)
// 3. Consume the strategy in RequestProvider or Data Providers
import { RequestProvider, CAPIFlatServerDataProvider } from '@katlux/providers'
// Using with RequestProvider
const request = new RequestProvider('MyCustom' as any, 60_000)
// Using with DataProvider
const dataProvider = new CAPIFlatServerDataProvider({
pageSize: 20,
cacheStrategy: 'MyCustom' as any,
cacheLifetime: 300_000
})
// Directly retrieving via factory
const cache = await CacheProviderFactory.getProvider('MyCustom')
Methods on CacheProviderFactory for managing custom cache drivers
| Method | Parameters | Returns | Description |
|---|
| registerDriver | strategy: string, loaderOrClass: CacheDriverLoader | { getInstance: () => ACacheProvider } | void | Registers a custom strategy name mapped to a dynamic loader or class object. |
| getProvider | strategy: ECacheStrategy | string | Promise<ACacheProvider | null> | Asynchronously loads and returns the singleton instance for the strategy. |
| getProviderSync | strategy: ECacheStrategy | string | ACacheProvider | undefined | Synchronously returns the singleton instance if already resolved. |
| clearInstances | (none) | void | Clears cached singleton instances. |
Methods required when extending ACacheProvider
| Method | Parameters | Returns | Description |
|---|
| get<T> | key: string, nuxtApp?: any | Promise<T | null> | Retrieves cached value or null if expired/missing |
| set<T> | key: string, data: T, lifetime: number, nuxtApp?: any | Promise<void> | Stores the value with lifetime in milliseconds |
| remove | key: string, nuxtApp?: any | Promise<void> | Removes a single entry by key |
| removeByPrefix | prefix: string, nuxtApp?: any | Promise<void> | Removes all entries matching key prefix |
| getKeyList | nuxtApp?: any | Promise<Array<string>> | Array<string> | Returns list of all active cache keys |
| getRemainingTime | key: string, nuxtApp?: any | Promise<number | null> | Returns remaining TTL in milliseconds |
| cleanupExpired | (none) | Promise<void> | Evicts all expired cache entries |