0
# Cache System
1
2
Configurable cache implementations for storing fetched data with TTL support, automatic expiration, and pluggable storage adapters.
3
4
## Capabilities
5
6
### SWRVCache Class
7
8
Default in-memory cache implementation with automatic expiration and key serialization.
9
10
```typescript { .api }
11
/**
12
* In-memory cache implementation with TTL support
13
* @param ttl - Default time to live in milliseconds (0 = no expiration)
14
*/
15
class SWRVCache<CacheData> {
16
constructor(ttl?: number);
17
18
/** Retrieve cached item by key */
19
get(k: string): ICacheItem<CacheData>;
20
21
/** Store item in cache with optional TTL override */
22
set(k: string, v: any, ttl: number): void;
23
24
/** Remove item from cache */
25
delete(serializedKey: string): void;
26
27
/** Convert complex keys to stable string identifiers */
28
serializeKey(key: IKey): string;
29
}
30
```
31
32
**Usage Examples:**
33
34
```typescript
35
import { SWRVCache } from "swrv";
36
37
// Basic cache usage
38
const cache = new SWRVCache();
39
cache.set('/api/users', userData, 0); // No expiration
40
const item = cache.get('/api/users');
41
42
// Cache with default TTL
43
const shortCache = new SWRVCache(5000); // 5 second default TTL
44
shortCache.set('/api/temp', tempData, 0); // Override with no expiration
45
shortCache.set('/api/quick', quickData, 1000); // Override with 1 second TTL
46
47
// Using with swrv configuration
48
const { data } = useSWRV('/api/data', fetcher, {
49
cache: new SWRVCache(300000) // 5 minute cache
50
});
51
```
52
53
### LocalStorageCache Class
54
55
Persistent cache implementation using browser localStorage with JSON serialization.
56
57
```typescript { .api }
58
/**
59
* localStorage-based cache adapter extending SWRVCache
60
* Data persists across browser sessions
61
* @param key - localStorage key prefix for all cache entries
62
* @param ttl - Default time to live in milliseconds
63
*/
64
class LocalStorageCache extends SWRVCache<any> {
65
constructor(key?: string, ttl?: number);
66
67
/** Retrieve cached item from localStorage */
68
get(k: string): ICacheItem<any>;
69
70
/** Store item in localStorage with TTL */
71
set(k: string, v: any, ttl: number): void;
72
73
/** Remove item from localStorage */
74
delete(serializedKey: string): void;
75
}
76
```
77
78
**Usage Examples:**
79
80
```typescript
81
import LocalStorageCache from "swrv/dist/cache/adapters/localStorage";
82
83
// Basic localStorage cache
84
const persistentCache = new LocalStorageCache();
85
86
// Custom storage key and TTL
87
const appCache = new LocalStorageCache('myapp-cache', 86400000); // 24 hour TTL
88
89
// Using with swrv for offline support
90
const { data } = useSWRV('/api/users', fetcher, {
91
cache: new LocalStorageCache('user-cache'),
92
shouldRetryOnError: false // Don't retry when offline
93
});
94
95
// Multiple cache instances for different data types
96
const userCache = new LocalStorageCache('users', 3600000); // 1 hour
97
const settingsCache = new LocalStorageCache('settings', 86400000); // 24 hours
98
99
const { data: users } = useSWRV('/api/users', fetcher, { cache: userCache });
100
const { data: settings } = useSWRV('/api/settings', fetcher, { cache: settingsCache });
101
```
102
103
### Cache Item Structure
104
105
Structure of cached data with metadata for expiration and timestamps.
106
107
```typescript { .api }
108
interface ICacheItem<Data> {
109
/** The actual cached data */
110
data: Data;
111
/** Timestamp when item was created */
112
createdAt: number;
113
/** Timestamp when item expires (Infinity for no expiration) */
114
expiresAt: number;
115
}
116
```
117
118
**Cache Item Examples:**
119
120
```typescript
121
// Accessing cache item metadata
122
const cache = new SWRVCache();
123
cache.set('/api/data', { users: [] }, 5000);
124
125
const item = cache.get('/api/data');
126
if (item) {
127
console.log('Data:', item.data);
128
console.log('Created:', new Date(item.createdAt));
129
console.log('Expires:', new Date(item.expiresAt));
130
console.log('Age:', Date.now() - item.createdAt);
131
}
132
133
// Check if item is expired
134
function isExpired(item) {
135
return Date.now() >= item.expiresAt;
136
}
137
```
138
139
### Key Serialization
140
141
Convert complex cache keys to stable string identifiers for consistent caching.
142
143
```typescript { .api }
144
/**
145
* Serialize complex keys to stable strings
146
* @param key - Key to serialize (string, array, function, or reactive)
147
* @returns Serialized string key
148
*/
149
serializeKey(key: IKey): string;
150
```
151
152
**Key Serialization Examples:**
153
154
```typescript
155
const cache = new SWRVCache();
156
157
// String keys (passed through)
158
cache.serializeKey('/api/users'); // '/api/users'
159
160
// Array keys (hashed to stable string)
161
cache.serializeKey(['/api/search', { q: 'vue', page: 1 }]); // 'arg@"/api/search"@0'
162
163
// Function keys (evaluated then serialized)
164
const userId = ref(123);
165
cache.serializeKey(() => `/api/users/${userId.value}`); // '/api/users/123'
166
167
// Null/undefined keys
168
cache.serializeKey(null); // ''
169
cache.serializeKey(undefined); // ''
170
```
171
172
### Custom Cache Implementation
173
174
Create custom cache adapters by extending SWRVCache or implementing the same interface.
175
176
**Custom Cache Examples:**
177
178
```typescript
179
// Redis cache adapter example
180
class RedisCache extends SWRVCache<any> {
181
constructor(private redisClient, ttl = 0) {
182
super(ttl);
183
}
184
185
async get(k: string) {
186
const key = this.serializeKey(k);
187
const data = await this.redisClient.get(key);
188
return data ? JSON.parse(data) : undefined;
189
}
190
191
async set(k: string, v: any, ttl: number) {
192
const key = this.serializeKey(k);
193
const timeToLive = ttl || this.ttl;
194
const item = {
195
data: v,
196
createdAt: Date.now(),
197
expiresAt: timeToLive ? Date.now() + timeToLive : Infinity
198
};
199
200
if (timeToLive) {
201
await this.redisClient.setex(key, Math.ceil(timeToLive / 1000), JSON.stringify(item));
202
} else {
203
await this.redisClient.set(key, JSON.stringify(item));
204
}
205
}
206
207
async delete(serializedKey: string) {
208
await this.redisClient.del(serializedKey);
209
}
210
}
211
212
// IndexedDB cache adapter example
213
class IndexedDBCache extends SWRVCache<any> {
214
constructor(private dbName = 'swrv-cache', ttl = 0) {
215
super(ttl);
216
}
217
218
async get(k: string) {
219
const key = this.serializeKey(k);
220
const db = await this.openDB();
221
const tx = db.transaction(['cache'], 'readonly');
222
const store = tx.objectStore('cache');
223
const result = await store.get(key);
224
225
if (result && Date.now() < result.expiresAt) {
226
return result;
227
}
228
229
return undefined;
230
}
231
232
async set(k: string, v: any, ttl: number) {
233
const key = this.serializeKey(k);
234
const timeToLive = ttl || this.ttl;
235
const item = {
236
key,
237
data: v,
238
createdAt: Date.now(),
239
expiresAt: timeToLive ? Date.now() + timeToLive : Infinity
240
};
241
242
const db = await this.openDB();
243
const tx = db.transaction(['cache'], 'readwrite');
244
const store = tx.objectStore('cache');
245
await store.put(item);
246
}
247
248
private async openDB() {
249
return new Promise((resolve, reject) => {
250
const request = indexedDB.open(this.dbName, 1);
251
request.onerror = () => reject(request.error);
252
request.onsuccess = () => resolve(request.result);
253
request.onupgradeneeded = () => {
254
const db = request.result;
255
if (!db.objectStoreNames.contains('cache')) {
256
db.createObjectStore('cache', { keyPath: 'key' });
257
}
258
};
259
});
260
}
261
}
262
```
263
264
### Cache Configuration Patterns
265
266
Common patterns for configuring caches in different scenarios.
267
268
**Configuration Examples:**
269
270
```typescript
271
// Development vs Production caching
272
const isDev = process.env.NODE_ENV === 'development';
273
const cache = isDev
274
? new SWRVCache(1000) // Short TTL for dev
275
: new LocalStorageCache('prod-cache', 300000); // Persistent cache for prod
276
277
// Multi-tier caching strategy
278
const l1Cache = new SWRVCache(30000); // 30 second memory cache
279
const l2Cache = new LocalStorageCache('l2-cache', 3600000); // 1 hour persistent
280
281
class MultiTierCache extends SWRVCache<any> {
282
get(k: string) {
283
// Try L1 first
284
let item = l1Cache.get(k);
285
if (item) return item;
286
287
// Fall back to L2
288
item = l2Cache.get(k);
289
if (item) {
290
// Promote to L1
291
l1Cache.set(k, item.data, 30000);
292
return item;
293
}
294
295
return undefined;
296
}
297
298
set(k: string, v: any, ttl: number) {
299
l1Cache.set(k, v, Math.min(ttl, 30000)); // Max 30s in L1
300
l2Cache.set(k, v, ttl); // Full TTL in L2
301
}
302
}
303
304
// Cache per user/session
305
function createUserCache(userId: string) {
306
return new LocalStorageCache(`user-${userId}`, 3600000);
307
}
308
309
// Conditional caching based on data size
310
function createAdaptiveCache() {
311
return new (class extends SWRVCache<any> {
312
set(k: string, v: any, ttl: number) {
313
const size = JSON.stringify(v).length;
314
315
if (size > 100000) { // Large data to localStorage
316
const lsCache = new LocalStorageCache();
317
lsCache.set(k, v, ttl);
318
} else { // Small data to memory
319
super.set(k, v, ttl);
320
}
321
}
322
})();
323
}
324
```