or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

batch-operations.mdconfiguration.mdcore-storage.mdevents-hooks.mdindex.mdraw-data-access.mdstorage-adapters.md
tile.json

storage-adapters.mddocs/

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

```