0
# Cache Management
1
2
Core cache orchestration that manages sequential traversal through multiple cache stores with comprehensive logging and error handling via Metro's logging system.
3
4
## Capabilities
5
6
### Cache Class
7
8
Main cache coordinator that traverses multiple cache stores sequentially, checking faster stores first and ensuring values are propagated to all stores.
9
10
```javascript { .api }
11
/**
12
* Main cache class that receives an array of cache instances and sequentially
13
* traverses them to return a previously stored value. Ensures setting the value
14
* in all instances with comprehensive error handling.
15
* @template T - Type of cached values
16
*/
17
class Cache<T> {
18
/**
19
* Create a new cache instance with multiple stores
20
* @param stores - Array of cache store instances to traverse sequentially
21
*/
22
constructor(stores: Array<CacheStore<T>>);
23
24
/**
25
* Retrieve a cached value by key, checking stores sequentially
26
* @param key - Cache key as Buffer
27
* @returns Promise resolving to cached value or null if not found
28
*/
29
get(key: Buffer): Promise<T | null>;
30
31
/**
32
* Store a value in all cache stores (up to the store that had the cached value)
33
* @param key - Cache key as Buffer
34
* @param value - Value to cache
35
* @returns Promise that resolves when all store operations complete
36
* @throws AggregateError if any store write operations fail
37
*/
38
set(key: Buffer, value: T): Promise<void>;
39
40
/**
41
* Check if cache is disabled (has no stores)
42
* @returns true if cache has no stores configured
43
*/
44
get isDisabled(): boolean;
45
}
46
```
47
48
**Usage Examples:**
49
50
```javascript
51
const { Cache, FileStore, HttpStore } = require("metro-cache");
52
53
// Create cache with multiple stores (checked in order)
54
const cache = new Cache([
55
new FileStore({ root: "./local-cache" }),
56
new HttpStore({ endpoint: "https://shared-cache.example.com" })
57
]);
58
59
// Get operation checks FileStore first, then HttpStore
60
const key = Buffer.from("my-cache-key", "hex");
61
const result = await cache.get(key);
62
63
if (result === null) {
64
// Cache miss - compute value
65
const computedValue = { data: "processed content" };
66
67
// Set operation stores in FileStore (faster store that didn't have it)
68
await cache.set(key, computedValue);
69
return computedValue;
70
}
71
72
// Cache hit - return cached value
73
return result;
74
```
75
76
### Cache Store Interface
77
78
Contract that all cache store implementations must follow to be compatible with the Cache orchestrator.
79
80
```javascript { .api }
81
/**
82
* Interface that all cache store implementations must implement
83
* @template T - Type of values stored in the cache
84
*/
85
interface CacheStore<T> {
86
/**
87
* Optional name for the store (used in logging)
88
*/
89
name?: string;
90
91
/**
92
* Retrieve a cached value by key
93
* @param key - Cache key as Buffer
94
* @returns Cached value, null if not found, or Promise resolving to either
95
*/
96
get(key: Buffer): T | null | Promise<T | null>;
97
98
/**
99
* Store a value by key
100
* @param key - Cache key as Buffer
101
* @param value - Value to store
102
* @returns void or Promise that resolves when storage is complete
103
*/
104
set(key: Buffer, value: T): void | Promise<void>;
105
106
/**
107
* Clear all cached values
108
* @returns void or Promise that resolves when clearing is complete
109
*/
110
clear(): void | Promise<void>;
111
}
112
```
113
114
## Error Handling
115
116
The Cache class provides comprehensive error handling:
117
118
- **Read Operations**: If a store throws during get(), the error is logged and the next store is tried
119
- **Write Operations**: All store write failures are collected and thrown as an AggregateError
120
- **Logging Integration**: All operations are logged via Metro's Logger with timing and hit/miss information
121
122
**Error Handling Example:**
123
124
```javascript
125
const cache = new Cache([fileStore, flakyHttpStore]);
126
127
try {
128
await cache.set(key, value);
129
} catch (error) {
130
if (error instanceof AggregateError) {
131
console.log(`Write failed for ${error.errors.length} stores`);
132
for (const storeError of error.errors) {
133
console.error("Store error:", storeError.message);
134
}
135
}
136
}
137
```
138
139
## Performance Optimization
140
141
The Cache class includes several performance optimizations:
142
143
- **Hit Tracking**: Remembers which store provided a cached value to optimize future set() operations
144
- **Sequential Access**: Stops checking stores once a value is found
145
- **Parallel Writes**: Writes to multiple stores happen in parallel using Promise.allSettled()
146
- **Early Termination**: Only writes to stores that come before the store that had the cached value