Skip to main content

Overview

The CacheStore interface defines the contract for cache storage implementations. It provides the methods needed to store, retrieve, and manage cached data. You can implement this interface to create custom cache backends.

Interface: CacheStore

interface CacheStore {
  get: (key: string) => Promise<string | undefined>;
  set: (key: string, value: string, ttl?: number) => Promise<boolean>;
  del: (key: string) => Promise<boolean>;
  clear: () => Promise<boolean>;

  getMultiple?: (keys: string[]) => Promise<(string | undefined)[]>;
  setMultiple?: (values: Record<string, string>, ttl?: number) => Promise<boolean>;
  delMultiple?: (keys: string[]) => Promise<boolean>;
  has?: (key: string) => Promise<boolean>;

  dispose?: () => Promise<void> | void;
}

Required Methods

get()

Retrieves a value from the cache store.
get(key: string): Promise<string | undefined>
key
string
required
The normalized cache key to retrieve
return
Promise<string | undefined>
The cached value as a string, or undefined if not found
Values are stored as JSON strings. The Cacher class handles serialization and deserialization.

set()

Stores a value in the cache store.
set(key: string, value: string, ttl?: number): Promise<boolean>
key
string
required
The normalized cache key to store the value under
value
string
required
The value to cache as a JSON string
ttl
number
Time-to-live in seconds. The implementation should expire the entry after this duration.
return
Promise<boolean>
Returns true if the operation was successful, false otherwise

del()

Deletes a value from the cache store.
del(key: string): Promise<boolean>
key
string
required
The normalized cache key to delete
return
Promise<boolean>
Returns true if the operation was successful, false otherwise

clear()

Clears all values from the cache store.
clear(): Promise<boolean>
return
Promise<boolean>
Returns true if the operation was successful, false otherwise

Optional Methods

These methods are optional but can improve performance when implemented natively by the store.

getMultiple()

Retrieves multiple values from the cache store at once.
getMultiple?(keys: string[]): Promise<(string | undefined)[]>
keys
string[]
required
Array of normalized cache keys to retrieve
return
Promise<(string | undefined)[]>
Array of values in the same order as the keys
If not implemented, the Cacher class will fall back to calling get() multiple times.

setMultiple()

Stores multiple values in the cache store at once.
setMultiple?(values: Record<string, string>, ttl?: number): Promise<boolean>
values
Record<string, string>
required
Object mapping normalized cache keys to JSON string values
ttl
number
Time-to-live in seconds for all values
return
Promise<boolean>
Returns true if all operations were successful, false otherwise

delMultiple()

Deletes multiple values from the cache store at once.
delMultiple?(keys: string[]): Promise<boolean>
keys
string[]
required
Array of normalized cache keys to delete
return
Promise<boolean>
Returns true if all operations were successful, false otherwise

has()

Checks if a key exists in the cache store.
has?(key: string): Promise<boolean>
key
string
required
The normalized cache key to check
return
Promise<boolean>
Returns true if the key exists, false otherwise

dispose()

Cleans up resources and closes connections.
dispose?(): Promise<void> | void
This method is called when the Cacher instance is disposed. Use it to clean up connections, timers, or other resources.

Built-in Implementations

The framework provides several built-in cache store implementations:
  • NullCache: A no-op cache that doesn’t store anything (default)
  • MemoryCache: An in-memory cache using a Map
  • FileCache: A file-system based cache (available in @resolid/cache-file)

Custom Implementation Example

import type { CacheStore } from '@resolid/cache';

class RedisCacheStore implements CacheStore {
  private client: RedisClient;

  constructor(client: RedisClient) {
    this.client = client;
  }

  async get(key: string): Promise<string | undefined> {
    const value = await this.client.get(key);
    return value ?? undefined;
  }

  async set(key: string, value: string, ttl?: number): Promise<boolean> {
    if (ttl) {
      await this.client.setex(key, ttl, value);
    } else {
      await this.client.set(key, value);
    }
    return true;
  }

  async del(key: string): Promise<boolean> {
    await this.client.del(key);
    return true;
  }

  async clear(): Promise<boolean> {
    await this.client.flushdb();
    return true;
  }

  async has(key: string): Promise<boolean> {
    const exists = await this.client.exists(key);
    return exists === 1;
  }

  async dispose(): Promise<void> {
    await this.client.quit();
  }
}

// Usage
const cacher = new Cacher({
  store: new RedisCacheStore(redisClient),
  defaultTtl: 3600
});

Source Code

Location: packages/cache/src/stores/types.ts

Build docs developers (and LLMs) love