Cache Plugin
The official caching plugin for endpoint-fetcher. Provides TTL-based caching with LRU eviction and custom storage support.
Installation
npm install @endpoint-fetcher/cacheRequires
endpoint-fetcherv3.0.0 or higher.
Quick Start
Wrap endpoint return types with CachingWrapper<T> to enable cache metadata and control methods:
import { createApiClient, get } from 'endpoint-fetcher';
import { cache, CachingWrapper } from '@endpoint-fetcher/cache';
const api = createApiClient({
getAll: get<void, CachingWrapper<User[]>>('/users'),
}, {
baseUrl: 'https://api.example.com',
plugins: [cache({ ttl: 300 })],
});
const result = await api.getAll();
console.log(result.data); // User[]
console.log(result.isStale); // boolean
console.log(result.expiresAt); // DateCachingWrapper<T>
Every cached response includes:
| Member | Type | Description |
|---|---|---|
data | T | The actual API response data |
cachedAt | Date | When the original fetch happened |
expiresAt | Date | When the entry expires |
isStale | boolean | Whether the current time has passed the TTL |
refresh() | () => Promise<CachingWrapper<T>> | Force a network re-fetch and update the cache |
invalidate() | () => void | Remove this entry from the cache |
const result = await api.getAll();
// Force a fresh fetch
const fresh = await result.refresh();
// Stale-while-revalidate pattern
if (result.isStale) {
result.refresh().then(fresh => render(fresh.data));
}
render(result.data);Configuration
| Option | Type | Default | Description |
|---|---|---|---|
ttl | number | 300 | Time-to-live in seconds |
maxSize | number | Infinity | Max cache entries before LRU eviction |
methods | string[] | ['GET'] | HTTP methods to cache |
storage | CacheStorage | In-memory | Custom storage adapter |
keyGenerator | Function | Default | Custom cache key logic |
Custom Storage
Persist cache across sessions with a custom storage adapter:
plugins: [
cache({
ttl: 3600,
storage: {
get: (key) => JSON.parse(localStorage.getItem(key) || 'null'),
set: (key, val) => localStorage.setItem(key, JSON.stringify(val)),
delete: (key) => localStorage.removeItem(key),
keys: () => Object.keys(localStorage),
clear: () => localStorage.clear(),
},
}),
]Global Cache Management
The cache plugin exposes methods on client.plugins.cache:
| Method | Signature | Description |
|---|---|---|
clear() | () => void | Clear all cache entries |
invalidate(method, path, input) | (string, string, any) => void | Invalidate a specific endpoint |
invalidateKey(key) | (string) => void | Invalidate by raw cache key |
// Clear everything (e.g., on logout)
api.plugins.cache.clear();
// Invalidate a specific endpoint
api.plugins.cache.invalidate('GET', '/users', undefined);
api.plugins.cache.invalidate('GET', `/users/${userId}`, { id: userId });Troubleshooting
Data is never cached — Ensure the return type uses CachingWrapper<T>. If you use just T, the plugin skips caching. Also check that the HTTP method is in methods (default: ['GET']).
Cache persists after refresh — The default storage is in-memory and clears on page load. If you use a localStorage adapter, data persists until TTL expires or you call invalidate() / clear().