0
# Storage Adapters
1
2
Pluggable storage backend system with support for Redis, MongoDB, SQLite, PostgreSQL, MySQL, and any Map-compatible storage.
3
4
## Capabilities
5
6
### Storage Adapter Interface
7
8
The KeyvStoreAdapter interface that all storage adapters must implement.
9
10
```typescript { .api }
11
interface KeyvStoreAdapter {
12
/** Configuration options for the adapter */
13
opts: any;
14
/** Optional namespace for key prefixing */
15
namespace?: string;
16
17
/** Get value by key */
18
get<Value>(key: string): Promise<StoredData<Value> | undefined>;
19
/** Set value with optional TTL */
20
set(key: string, value: any, ttl?: number): any;
21
/** Delete key */
22
delete(key: string): Promise<boolean>;
23
/** Clear all keys in namespace */
24
clear(): Promise<void>;
25
26
// Optional batch operations (provide better performance when implemented)
27
/** Set multiple values */
28
setMany?(values: Array<{key: string; value: any; ttl?: number}>): Promise<void>;
29
/** Get multiple values */
30
getMany?<Value>(keys: string[]): Promise<Array<StoredData<Value | undefined>>>;
31
/** Check if key exists */
32
has?(key: string): Promise<boolean>;
33
/** Check if multiple keys exist */
34
hasMany?(keys: string[]): Promise<boolean[]>;
35
/** Delete multiple keys */
36
deleteMany?(key: string[]): Promise<boolean>;
37
/** Disconnect from storage */
38
disconnect?(): Promise<void>;
39
/** Iterator for all keys */
40
iterator?<Value>(namespace?: string): AsyncGenerator<Array<string | Awaited<Value> | undefined>, void>;
41
}
42
43
interface IEventEmitter {
44
on(event: string, listener: (...arguments_: any[]) => void): IEventEmitter;
45
}
46
47
// KeyvStoreAdapter extends IEventEmitter for error handling
48
```
49
50
### Using Built-in Map Storage
51
52
The default in-memory storage using JavaScript Map.
53
54
```typescript { .api }
55
// Default constructor uses Map storage
56
new Keyv(); // Uses new Map() internally
57
new Keyv(new Map()); // Explicit Map usage
58
```
59
60
**Usage Examples:**
61
62
```typescript
63
import Keyv from "keyv";
64
65
// Default in-memory storage
66
const keyv = new Keyv();
67
await keyv.set('key', 'value');
68
console.log(await keyv.get('key')); // 'value'
69
70
// Using existing Map
71
const existingMap = new Map();
72
existingMap.set('prefilled', 'data');
73
const keyvWithMap = new Keyv(existingMap);
74
console.log(await keyvWithMap.get('prefilled')); // 'data'
75
76
// Map with options
77
const keyvMapWithOptions = new Keyv(new Map(), {
78
namespace: 'cache',
79
ttl: 60000
80
});
81
```
82
83
### Redis Adapter
84
85
High-performance Redis storage with native TTL support.
86
87
```typescript { .api }
88
// Import pattern for Redis adapter
89
import KeyvRedis from "@keyv/redis";
90
91
const keyvRedis = new KeyvRedis(uri: string, options?: any);
92
const keyv = new Keyv(keyvRedis);
93
```
94
95
**Usage Examples:**
96
97
```typescript
98
import Keyv from "keyv";
99
import KeyvRedis from "@keyv/redis";
100
101
// Basic Redis connection
102
const keyvRedis = new KeyvRedis('redis://localhost:6379');
103
const keyv = new Keyv(keyvRedis);
104
105
// Redis with authentication
106
const keyvAuth = new KeyvRedis('redis://user:pass@localhost:6379');
107
const keyvWithAuth = new Keyv(keyvAuth);
108
109
// Redis with options and Keyv config
110
const redisStore = new KeyvRedis('redis://localhost:6379', {
111
// Redis-specific options
112
retryDelayOnFailover: 100,
113
maxRetriesPerRequest: 3
114
});
115
116
const keyv = new Keyv(redisStore, {
117
namespace: 'app-cache',
118
ttl: 300000 // 5 minutes default TTL
119
});
120
121
// Handle connection errors
122
keyv.on('error', (err) => console.error('Redis connection error:', err));
123
124
await keyv.set('user:123', { name: 'Alice', role: 'admin' });
125
```
126
127
### MongoDB Adapter
128
129
MongoDB storage with TTL collection support.
130
131
```typescript { .api }
132
// Import pattern for MongoDB adapter
133
import KeyvMongo from "@keyv/mongo";
134
135
const keyvMongo = new KeyvMongo(uri: string, options?: any);
136
const keyv = new Keyv(keyvMongo);
137
```
138
139
**Usage Examples:**
140
141
```typescript
142
import Keyv from "keyv";
143
import KeyvMongo from "@keyv/mongo";
144
145
// Basic MongoDB connection
146
const keyvMongo = new KeyvMongo('mongodb://localhost:27017/mydb');
147
const keyv = new Keyv(keyvMongo);
148
149
// MongoDB with authentication
150
const keyvAuth = new KeyvMongo('mongodb://user:pass@localhost:27017/mydb');
151
152
// MongoDB with options
153
const mongoStore = new KeyvMongo('mongodb://localhost:27017/mydb', {
154
collection: 'cache', // Custom collection name
155
// MongoDB-specific options
156
});
157
158
const keyv = new Keyv(mongoStore, { namespace: 'sessions' });
159
160
await keyv.set('session:abc123', { userId: 456, loginTime: Date.now() });
161
```
162
163
### SQLite Adapter
164
165
Local SQLite storage for development and single-node deployments.
166
167
```typescript { .api }
168
// Import pattern for SQLite adapter
169
import KeyvSqlite from "@keyv/sqlite";
170
171
const keyvSqlite = new KeyvSqlite(uri: string);
172
const keyv = new Keyv(keyvSqlite);
173
```
174
175
**Usage Examples:**
176
177
```typescript
178
import Keyv from "keyv";
179
import KeyvSqlite from "@keyv/sqlite";
180
181
// File-based SQLite
182
const keyvSqlite = new KeyvSqlite('sqlite://path/to/database.sqlite');
183
const keyv = new Keyv(keyvSqlite);
184
185
// In-memory SQLite
186
const keyvMemory = new KeyvSqlite('sqlite://:memory:');
187
const keyvInMemory = new Keyv(keyvMemory);
188
189
// SQLite with options
190
const sqliteStore = new KeyvSqlite('sqlite://cache.db', {
191
busyTimeout: 3000 // Wait up to 3 seconds for locks
192
});
193
194
const keyv = new Keyv(sqliteStore, {
195
namespace: 'file-cache',
196
ttl: 86400000 // 24 hours
197
});
198
199
await keyv.set('file:readme.txt', 'File content here');
200
```
201
202
### PostgreSQL Adapter
203
204
Enterprise PostgreSQL storage with connection pooling.
205
206
```typescript { .api }
207
// Import pattern for PostgreSQL adapter
208
import KeyvPostgres from "@keyv/postgres";
209
210
const keyvPostgres = new KeyvPostgres(uri: string);
211
const keyv = new Keyv(keyvPostgres);
212
```
213
214
**Usage Examples:**
215
216
```typescript
217
import Keyv from "keyv";
218
import KeyvPostgres from "@keyv/postgres";
219
220
// Basic PostgreSQL connection
221
const keyvPg = new KeyvPostgres('postgresql://user:pass@localhost:5432/mydb');
222
const keyv = new Keyv(keyvPg);
223
224
// PostgreSQL with SSL
225
const keyvSecure = new KeyvPostgres('postgresql://user:pass@localhost:5432/mydb?sslmode=require');
226
227
const keyv = new Keyv(keyvSecure, {
228
namespace: 'production-cache',
229
ttl: 3600000 // 1 hour
230
});
231
232
await keyv.set('config:app', { version: '1.0.0', features: ['auth', 'cache'] });
233
```
234
235
### MySQL Adapter
236
237
MySQL/MariaDB storage support.
238
239
```typescript { .api }
240
// Import pattern for MySQL adapter
241
import KeyvMysql from "@keyv/mysql";
242
243
const keyvMysql = new KeyvMysql(uri: string);
244
const keyv = new Keyv(keyvMysql);
245
```
246
247
**Usage Examples:**
248
249
```typescript
250
import Keyv from "keyv";
251
import KeyvMysql from "@keyv/mysql";
252
253
// Basic MySQL connection
254
const keyvMysql = new KeyvMysql('mysql://user:pass@localhost:3306/mydb');
255
const keyv = new Keyv(keyvMysql);
256
257
// MySQL with options
258
const keyv = new Keyv(keyvMysql, {
259
namespace: 'session-store',
260
ttl: 1800000 // 30 minutes
261
});
262
263
await keyv.set('cart:user123', { items: [1, 2, 3], total: 99.99 });
264
```
265
266
### Custom Storage Adapters
267
268
Creating custom storage adapters that implement the KeyvStoreAdapter interface.
269
270
```typescript { .api }
271
// Custom adapter must implement KeyvStoreAdapter interface
272
class CustomStorageAdapter implements KeyvStoreAdapter {
273
opts: any;
274
namespace?: string;
275
276
async get<Value>(key: string): Promise<StoredData<Value> | undefined> {
277
// Implementation
278
}
279
280
async set(key: string, value: any, ttl?: number): Promise<any> {
281
// Implementation
282
}
283
284
async delete(key: string): Promise<boolean> {
285
// Implementation
286
}
287
288
async clear(): Promise<void> {
289
// Implementation
290
}
291
}
292
```
293
294
**Usage Examples:**
295
296
```typescript
297
import Keyv from "keyv";
298
299
// Custom file-based adapter example
300
class FileStorageAdapter {
301
constructor(private filePath: string) {
302
this.opts = { filePath };
303
}
304
305
async get(key: string) {
306
// Read from file system
307
try {
308
const data = await fs.readFile(this.filePath, 'utf8');
309
const store = JSON.parse(data);
310
return store[key];
311
} catch {
312
return undefined;
313
}
314
}
315
316
async set(key: string, value: any, ttl?: number) {
317
// Write to file system
318
try {
319
const data = await fs.readFile(this.filePath, 'utf8').catch(() => '{}');
320
const store = JSON.parse(data);
321
store[key] = { value, expires: ttl ? Date.now() + ttl : undefined };
322
await fs.writeFile(this.filePath, JSON.stringify(store));
323
return true;
324
} catch {
325
return false;
326
}
327
}
328
329
async delete(key: string) {
330
// Delete from file
331
try {
332
const data = await fs.readFile(this.filePath, 'utf8');
333
const store = JSON.parse(data);
334
const existed = key in store;
335
delete store[key];
336
await fs.writeFile(this.filePath, JSON.stringify(store));
337
return existed;
338
} catch {
339
return false;
340
}
341
}
342
343
async clear() {
344
await fs.writeFile(this.filePath, '{}');
345
}
346
}
347
348
// Use custom adapter
349
const customAdapter = new FileStorageAdapter('./cache.json');
350
const keyv = new Keyv(customAdapter);
351
352
await keyv.set('test', 'Custom storage works!');
353
```
354
355
### Third-Party Storage Adapters
356
357
Compatible third-party adapters that work with Keyv.
358
359
```typescript { .api }
360
// Third-party adapters follow same pattern
361
import QuickLRU from "quick-lru";
362
363
const lru = new QuickLRU({ maxSize: 1000 });
364
const keyv = new Keyv(lru); // Any Map-compatible store works
365
```
366
367
**Usage Examples:**
368
369
```typescript
370
import Keyv from "keyv";
371
import QuickLRU from "quick-lru";
372
373
// LRU cache with size limit
374
const lru = new QuickLRU({ maxSize: 1000 });
375
const keyv = new Keyv(lru);
376
377
await keyv.set('item1', 'data1');
378
await keyv.set('item2', 'data2');
379
// When maxSize reached, oldest items are evicted
380
381
// File system adapter
382
import KeyvFile from "keyv-file";
383
const fileStore = new KeyvFile('./cache-dir');
384
const keyvFile = new Keyv(fileStore);
385
386
// Null adapter (no storage, useful for testing)
387
import KeyvNull from "keyv-null";
388
const nullStore = new KeyvNull();
389
const keyvNull = new Keyv(nullStore); // All operations succeed but nothing is stored
390
```
391
392
## Storage Adapter Properties
393
394
### Runtime Store Management
395
396
```typescript { .api }
397
class Keyv {
398
/** Get current storage adapter */
399
get store(): KeyvStoreAdapter | Map<any, any> | any;
400
401
/** Set new storage adapter (validates and configures) */
402
set store(store: KeyvStoreAdapter | Map<any, any> | any);
403
}
404
```
405
406
**Usage Examples:**
407
408
```typescript
409
const keyv = new Keyv(); // Starts with Map storage
410
411
// Check current store
412
console.log(keyv.store instanceof Map); // true
413
414
// Switch to Redis
415
import KeyvRedis from "@keyv/redis";
416
const redisStore = new KeyvRedis('redis://localhost:6379');
417
keyv.store = redisStore; // Automatically configures events, namespace, etc.
418
419
// Store validation
420
try {
421
keyv.store = {}; // Invalid store
422
} catch (error) {
423
console.error('Invalid storage adapter'); // Throws error
424
}
425
```