or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cache-system.mddata-fetching.mdglobal-state.mdindex.md

cache-system.mddocs/

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

```