Comprehensive caching system with multiple implementations for different environments and use cases. Provides consistent interface across memory, localStorage, null, and fallback cache implementations.
In-memory cache implementation with optional serialization for development and server environments.
/**
* Creates an in-memory cache with optional serialization
* @param options - Configuration options for memory cache behavior
* @returns Cache instance backed by in-memory storage
*/
function createMemoryCache(options?: MemoryCacheOptions): Cache;
interface MemoryCacheOptions {
/** Whether to serialize keys and values using JSON.stringify (default: true) */
serializable?: boolean;
}Usage Examples:
import { createMemoryCache } from "@algolia/client-common";
// Default serializable cache
const cache = createMemoryCache();
// Store and retrieve data
await cache.set("user:123", { name: "John", age: 30 });
const user = await cache.get("user:123", () => Promise.resolve(null));
// Non-serializable cache (stores objects directly)
const fastCache = createMemoryCache({ serializable: false });
await fastCache.set("config", { apiUrl: "https://api.example.com" });No-operation cache that doesn't store anything, always executes the default value function.
/**
* Creates a null cache that doesn't store anything
* @returns Cache instance that always executes default value functions
*/
function createNullCache(): Cache;Usage Examples:
import { createNullCache } from "@algolia/client-common";
const cache = createNullCache();
// Always executes the default value function
const result = await cache.get("key", async () => {
console.log("This will always run");
return "fresh data";
});
// Set operations are no-ops but return the value
await cache.set("key", "value"); // Returns "value" but doesn't store itBrowser-specific cache using localStorage with TTL support and automatic cleanup.
/**
* Creates a cache backed by browser localStorage
* @param options - Configuration for localStorage cache behavior
* @returns Cache instance using browser localStorage
*/
function createBrowserLocalStorageCache(options: BrowserLocalStorageOptions): Cache;
interface BrowserLocalStorageOptions {
/** Unique key for this cache namespace */
key: string;
/** Time to live for cached items in seconds */
timeToLive?: number;
/** Custom localStorage implementation (defaults to window.localStorage) */
localStorage?: Storage;
}Usage Examples:
import { createBrowserLocalStorageCache } from "@algolia/client-common";
// Basic localStorage cache
const cache = createBrowserLocalStorageCache({
key: "algolia-cache"
});
// Cache with 1-hour TTL
const ttlCache = createBrowserLocalStorageCache({
key: "search-results",
timeToLive: 3600 // 1 hour in seconds
});
// Custom storage implementation
const customCache = createBrowserLocalStorageCache({
key: "custom",
localStorage: sessionStorage // Use sessionStorage instead
});
await cache.set("search:query123", { results: [1, 2, 3] });Chain multiple caches with automatic fallback behavior when primary caches fail.
/**
* Creates a fallback cache that tries multiple cache implementations in order
* @param options - Configuration with ordered list of cache instances
* @returns Cache that falls back through the provided cache list
*/
function createFallbackableCache(options: FallbackableCacheOptions): Cache;
interface FallbackableCacheOptions {
/** List of caches in order of preference (first = primary, last = fallback) */
caches: Cache[];
}Usage Examples:
import {
createFallbackableCache,
createBrowserLocalStorageCache,
createMemoryCache,
createNullCache
} from "@algolia/client-common";
// Try localStorage first, fall back to memory, then null cache
const cache = createFallbackableCache({
caches: [
createBrowserLocalStorageCache({ key: "primary" }),
createMemoryCache(),
createNullCache()
]
});
// Will try localStorage first, memory if that fails, null cache as last resort
await cache.set("key", "value");Common interface implemented by all cache types with get, set, delete, and clear operations.
interface Cache {
/**
* Gets a value from cache, executing defaultValue if not found
* @param key - Cache key (string or object)
* @param defaultValue - Function to execute if cache miss
* @param events - Optional cache event handlers
* @returns Promise resolving to cached or default value
*/
get: <TValue>(
key: Record<string, any> | string,
defaultValue: () => Promise<TValue>,
events?: CacheEvents<TValue>
) => Promise<TValue>;
/**
* Sets a value in the cache
* @param key - Cache key (string or object)
* @param value - Value to cache
* @returns Promise resolving to the cached value
*/
set: <TValue>(key: Record<string, any> | string, value: TValue) => Promise<TValue>;
/**
* Deletes a value from the cache
* @param key - Cache key to delete
* @returns Promise resolving when deletion completes
*/
delete: (key: Record<string, any> | string) => Promise<void>;
/**
* Clears all values from the cache
* @returns Promise resolving when cache is cleared
*/
clear: () => Promise<void>;
}
interface CacheEvents<TValue> {
/**
* Called when a cache miss occurs (key not found)
* @param value - The value that will be cached after defaultValue executes
* @returns Promise for any async operations
*/
miss: (value: TValue) => Promise<any>;
}Handle cache miss events for analytics, logging, or warming operations.
Usage Examples:
import { createMemoryCache } from "@algolia/client-common";
const cache = createMemoryCache();
const result = await cache.get(
"expensive-operation",
async () => {
// This expensive operation will run on cache miss
return await performExpensiveCalculation();
},
{
miss: async (value) => {
// Log cache miss for monitoring
console.log("Cache miss for expensive-operation", value);
// Optionally warm related cache entries
await cache.set("related-key", derivedValue);
}
}
);Object Keys:
import { createMemoryCache } from "@algolia/client-common";
const cache = createMemoryCache();
// Use objects as cache keys
const cacheKey = {
query: "search term",
filters: ["category:books"],
page: 1
};
await cache.set(cacheKey, searchResults);
const results = await cache.get(cacheKey, () => performSearch(cacheKey));Cache Patterns:
import { createMemoryCache } from "@algolia/client-common";
const cache = createMemoryCache();
// Cache-aside pattern
async function getUser(id: string) {
return cache.get(
`user:${id}`,
async () => {
const user = await fetchUserFromAPI(id);
return user;
},
{
miss: async (user) => {
console.log(`Loaded user ${id} from API`);
}
}
);
}
// Write-through pattern
async function updateUser(id: string, userData: any) {
const updatedUser = await updateUserInAPI(id, userData);
await cache.set(`user:${id}`, updatedUser);
return updatedUser;
}
// Cache invalidation
async function deleteUser(id: string) {
await deleteUserFromAPI(id);
await cache.delete(`user:${id}`);
}The localStorage cache automatically removes expired items and handles legacy cache formats:
interface BrowserLocalStorageCacheItem {
/** Cache item creation timestamp */
timestamp: number;
/** The cached value */
value: any;
}algolia-client-js-${options.key}window.localStorage