layercache 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7KMKQ6QZ.js → chunk-6X7NV5BG.js} +33 -0
- package/dist/{chunk-FFZCC7EQ.js → chunk-IVX6ABFX.js} +87 -0
- package/dist/cli.cjs +33 -0
- package/dist/cli.js +1 -1
- package/dist/{edge-D2FpRlyS.d.cts → edge-BCU8D-Yd.d.cts} +504 -0
- package/dist/{edge-D2FpRlyS.d.ts → edge-BCU8D-Yd.d.ts} +504 -0
- package/dist/edge.cjs +87 -0
- package/dist/edge.d.cts +1 -1
- package/dist/edge.d.ts +1 -1
- package/dist/edge.js +1 -1
- package/dist/index.cjs +485 -0
- package/dist/index.d.cts +244 -2
- package/dist/index.d.ts +244 -2
- package/dist/index.js +367 -2
- package/package.json +1 -1
|
@@ -151,9 +151,15 @@ var RedisTagIndex = class {
|
|
|
151
151
|
this.scanCount = options.scanCount ?? 100;
|
|
152
152
|
this.knownKeysShards = normalizeKnownKeysShards(options.knownKeysShards);
|
|
153
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Records a key as known without changing tag assignments.
|
|
156
|
+
*/
|
|
154
157
|
async touch(key) {
|
|
155
158
|
await this.client.sadd(this.knownKeysKeyFor(key), key);
|
|
156
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Replaces the tags associated with a key and records the key as known.
|
|
162
|
+
*/
|
|
157
163
|
async track(key, tags) {
|
|
158
164
|
const keyTagsKey = this.keyTagsKey(key);
|
|
159
165
|
const existingTags = await this.client.smembers(keyTagsKey);
|
|
@@ -171,6 +177,9 @@ var RedisTagIndex = class {
|
|
|
171
177
|
}
|
|
172
178
|
await pipeline.exec();
|
|
173
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Removes a key from all tag mappings and known-key tracking.
|
|
182
|
+
*/
|
|
174
183
|
async remove(key) {
|
|
175
184
|
const keyTagsKey = this.keyTagsKey(key);
|
|
176
185
|
const existingTags = await this.client.smembers(keyTagsKey);
|
|
@@ -182,9 +191,15 @@ var RedisTagIndex = class {
|
|
|
182
191
|
}
|
|
183
192
|
await pipeline.exec();
|
|
184
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Returns keys currently associated with a tag.
|
|
196
|
+
*/
|
|
185
197
|
async keysForTag(tag) {
|
|
186
198
|
return this.client.smembers(this.tagKeysKey(tag));
|
|
187
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Visits keys currently associated with a tag.
|
|
202
|
+
*/
|
|
188
203
|
async forEachKeyForTag(tag, visitor) {
|
|
189
204
|
let cursor = "0";
|
|
190
205
|
const tagKey = this.tagKeysKey(tag);
|
|
@@ -196,6 +211,9 @@ var RedisTagIndex = class {
|
|
|
196
211
|
}
|
|
197
212
|
} while (cursor !== "0");
|
|
198
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Returns known keys that start with a prefix.
|
|
216
|
+
*/
|
|
199
217
|
async keysForPrefix(prefix) {
|
|
200
218
|
const matches = [];
|
|
201
219
|
for (const knownKeysKey of this.knownKeysKeys()) {
|
|
@@ -208,6 +226,9 @@ var RedisTagIndex = class {
|
|
|
208
226
|
}
|
|
209
227
|
return matches;
|
|
210
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* Visits known keys that start with a prefix.
|
|
231
|
+
*/
|
|
211
232
|
async forEachKeyForPrefix(prefix, visitor) {
|
|
212
233
|
for (const knownKeysKey of this.knownKeysKeys()) {
|
|
213
234
|
let cursor = "0";
|
|
@@ -222,9 +243,15 @@ var RedisTagIndex = class {
|
|
|
222
243
|
} while (cursor !== "0");
|
|
223
244
|
}
|
|
224
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* Returns the tags currently associated with a key.
|
|
248
|
+
*/
|
|
225
249
|
async tagsForKey(key) {
|
|
226
250
|
return this.client.smembers(this.keyTagsKey(key));
|
|
227
251
|
}
|
|
252
|
+
/**
|
|
253
|
+
* Returns known keys matching a wildcard pattern.
|
|
254
|
+
*/
|
|
228
255
|
async matchPattern(pattern) {
|
|
229
256
|
const matches = [];
|
|
230
257
|
for (const knownKeysKey of this.knownKeysKeys()) {
|
|
@@ -244,6 +271,9 @@ var RedisTagIndex = class {
|
|
|
244
271
|
}
|
|
245
272
|
return matches;
|
|
246
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* Visits known keys matching a wildcard pattern.
|
|
276
|
+
*/
|
|
247
277
|
async forEachKeyMatchingPattern(pattern, visitor) {
|
|
248
278
|
for (const knownKeysKey of this.knownKeysKeys()) {
|
|
249
279
|
let cursor = "0";
|
|
@@ -265,6 +295,9 @@ var RedisTagIndex = class {
|
|
|
265
295
|
} while (cursor !== "0");
|
|
266
296
|
}
|
|
267
297
|
}
|
|
298
|
+
/**
|
|
299
|
+
* Clears all Redis tag-index state under this prefix.
|
|
300
|
+
*/
|
|
268
301
|
async clear() {
|
|
269
302
|
const indexKeys = await this.scanIndexKeys();
|
|
270
303
|
if (indexKeys.length === 0) {
|
|
@@ -12,6 +12,9 @@ var MemoryLayer = class {
|
|
|
12
12
|
onEvict;
|
|
13
13
|
entries = /* @__PURE__ */ new Map();
|
|
14
14
|
cleanupTimer;
|
|
15
|
+
/**
|
|
16
|
+
* Creates an in-memory cache layer.
|
|
17
|
+
*/
|
|
15
18
|
constructor(options = {}) {
|
|
16
19
|
this.name = options.name ?? "memory";
|
|
17
20
|
this.defaultTtl = options.ttl;
|
|
@@ -25,10 +28,16 @@ var MemoryLayer = class {
|
|
|
25
28
|
this.cleanupTimer.unref?.();
|
|
26
29
|
}
|
|
27
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Reads and unwraps a fresh value from memory.
|
|
33
|
+
*/
|
|
28
34
|
async get(key) {
|
|
29
35
|
const value = await this.getEntry(key);
|
|
30
36
|
return unwrapStoredValue(value);
|
|
31
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Reads the raw stored value or envelope from memory.
|
|
40
|
+
*/
|
|
32
41
|
async getEntry(key) {
|
|
33
42
|
const entry = this.entries.get(key);
|
|
34
43
|
if (!entry) {
|
|
@@ -47,12 +56,21 @@ var MemoryLayer = class {
|
|
|
47
56
|
}
|
|
48
57
|
return entry.value;
|
|
49
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Reads many raw entries from memory.
|
|
61
|
+
*/
|
|
50
62
|
async getMany(keys) {
|
|
51
63
|
return Promise.all(keys.map((key) => this.getEntry(key)));
|
|
52
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Writes many entries to memory.
|
|
67
|
+
*/
|
|
53
68
|
async setMany(entries) {
|
|
54
69
|
await Promise.all(entries.map((entry) => this.set(entry.key, entry.value, entry.ttl)));
|
|
55
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Stores a value in memory using the provided TTL or layer default TTL.
|
|
73
|
+
*/
|
|
56
74
|
async set(key, value, ttl = this.defaultTtl) {
|
|
57
75
|
this.entries.delete(key);
|
|
58
76
|
this.entries.set(key, {
|
|
@@ -65,6 +83,9 @@ var MemoryLayer = class {
|
|
|
65
83
|
this.evict();
|
|
66
84
|
}
|
|
67
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Returns true when the key exists and has not expired.
|
|
88
|
+
*/
|
|
68
89
|
async has(key) {
|
|
69
90
|
const entry = this.entries.get(key);
|
|
70
91
|
if (!entry) {
|
|
@@ -76,6 +97,9 @@ var MemoryLayer = class {
|
|
|
76
97
|
}
|
|
77
98
|
return true;
|
|
78
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Returns remaining TTL in milliseconds, or null when absent or non-expiring.
|
|
102
|
+
*/
|
|
79
103
|
async ttl(key) {
|
|
80
104
|
const entry = this.entries.get(key);
|
|
81
105
|
if (!entry) {
|
|
@@ -90,40 +114,67 @@ var MemoryLayer = class {
|
|
|
90
114
|
}
|
|
91
115
|
return Math.max(0, Math.ceil(entry.expiresAt - Date.now()));
|
|
92
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Returns the number of currently retained, non-expired entries.
|
|
119
|
+
*/
|
|
93
120
|
async size() {
|
|
94
121
|
this.pruneExpired();
|
|
95
122
|
return this.entries.size;
|
|
96
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Deletes a key from memory.
|
|
126
|
+
*/
|
|
97
127
|
async delete(key) {
|
|
98
128
|
this.entries.delete(key);
|
|
99
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Deletes multiple keys from memory.
|
|
132
|
+
*/
|
|
100
133
|
async deleteMany(keys) {
|
|
101
134
|
for (const key of keys) {
|
|
102
135
|
this.entries.delete(key);
|
|
103
136
|
}
|
|
104
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Removes all entries from memory.
|
|
140
|
+
*/
|
|
105
141
|
async clear() {
|
|
106
142
|
this.entries.clear();
|
|
107
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Health check hook that always succeeds for the in-process layer.
|
|
146
|
+
*/
|
|
108
147
|
async ping() {
|
|
109
148
|
return true;
|
|
110
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* Stops the cleanup timer, when one is active.
|
|
152
|
+
*/
|
|
111
153
|
async dispose() {
|
|
112
154
|
if (this.cleanupTimer) {
|
|
113
155
|
clearInterval(this.cleanupTimer);
|
|
114
156
|
this.cleanupTimer = void 0;
|
|
115
157
|
}
|
|
116
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Returns all currently retained, non-expired keys.
|
|
161
|
+
*/
|
|
117
162
|
async keys() {
|
|
118
163
|
this.pruneExpired();
|
|
119
164
|
return [...this.entries.keys()];
|
|
120
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Visits all currently retained, non-expired keys.
|
|
168
|
+
*/
|
|
121
169
|
async forEachKey(visitor) {
|
|
122
170
|
this.pruneExpired();
|
|
123
171
|
for (const key of this.entries.keys()) {
|
|
124
172
|
await visitor(key);
|
|
125
173
|
}
|
|
126
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Exports memory entries for process-local snapshots.
|
|
177
|
+
*/
|
|
127
178
|
exportState() {
|
|
128
179
|
this.pruneExpired();
|
|
129
180
|
return [...this.entries.entries()].map(([key, entry]) => ({
|
|
@@ -132,6 +183,9 @@ var MemoryLayer = class {
|
|
|
132
183
|
expiresAt: entry.expiresAt
|
|
133
184
|
}));
|
|
134
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* Imports entries previously produced by `exportState()`.
|
|
188
|
+
*/
|
|
135
189
|
importState(entries) {
|
|
136
190
|
for (const entry of entries) {
|
|
137
191
|
if (entry.expiresAt !== null && entry.expiresAt <= Date.now()) {
|
|
@@ -202,10 +256,16 @@ var TagIndex = class {
|
|
|
202
256
|
constructor(options = {}) {
|
|
203
257
|
this.maxKnownKeys = options.maxKnownKeys ?? 1e5;
|
|
204
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* Records a key as known without changing tag assignments.
|
|
261
|
+
*/
|
|
205
262
|
async touch(key) {
|
|
206
263
|
this.insertKnownKey(key);
|
|
207
264
|
this.pruneKnownKeysIfNeeded();
|
|
208
265
|
}
|
|
266
|
+
/**
|
|
267
|
+
* Replaces the tags associated with a key and records the key as known.
|
|
268
|
+
*/
|
|
209
269
|
async track(key, tags) {
|
|
210
270
|
this.insertKnownKey(key);
|
|
211
271
|
this.pruneKnownKeysIfNeeded();
|
|
@@ -226,17 +286,29 @@ var TagIndex = class {
|
|
|
226
286
|
this.tagToKeys.set(tag, keys);
|
|
227
287
|
}
|
|
228
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* Removes a key from all tag mappings and known-key tracking.
|
|
291
|
+
*/
|
|
229
292
|
async remove(key) {
|
|
230
293
|
this.removeKey(key);
|
|
231
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Returns keys currently associated with a tag.
|
|
297
|
+
*/
|
|
232
298
|
async keysForTag(tag) {
|
|
233
299
|
return [...this.tagToKeys.get(tag) ?? /* @__PURE__ */ new Set()];
|
|
234
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* Visits keys currently associated with a tag.
|
|
303
|
+
*/
|
|
235
304
|
async forEachKeyForTag(tag, visitor) {
|
|
236
305
|
for (const key of this.tagToKeys.get(tag) ?? /* @__PURE__ */ new Set()) {
|
|
237
306
|
await visitor(key);
|
|
238
307
|
}
|
|
239
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* Returns known keys that start with a prefix.
|
|
311
|
+
*/
|
|
240
312
|
async keysForPrefix(prefix) {
|
|
241
313
|
const node = this.findNode(prefix);
|
|
242
314
|
if (!node) {
|
|
@@ -246,6 +318,9 @@ var TagIndex = class {
|
|
|
246
318
|
this.collectFromNode(node, prefix, matches);
|
|
247
319
|
return matches;
|
|
248
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* Visits known keys that start with a prefix.
|
|
323
|
+
*/
|
|
249
324
|
async forEachKeyForPrefix(prefix, visitor) {
|
|
250
325
|
const node = this.findNode(prefix);
|
|
251
326
|
if (!node) {
|
|
@@ -253,20 +328,32 @@ var TagIndex = class {
|
|
|
253
328
|
}
|
|
254
329
|
await this.visitFromNode(node, prefix, visitor);
|
|
255
330
|
}
|
|
331
|
+
/**
|
|
332
|
+
* Returns the tags currently associated with a key.
|
|
333
|
+
*/
|
|
256
334
|
async tagsForKey(key) {
|
|
257
335
|
return [...this.keyToTags.get(key) ?? /* @__PURE__ */ new Set()];
|
|
258
336
|
}
|
|
337
|
+
/**
|
|
338
|
+
* Returns known keys matching a wildcard pattern.
|
|
339
|
+
*/
|
|
259
340
|
async matchPattern(pattern) {
|
|
260
341
|
const matches = /* @__PURE__ */ new Set();
|
|
261
342
|
this.collectPatternMatches(this.root, "", pattern, 0, matches, /* @__PURE__ */ new Set(), 0);
|
|
262
343
|
return [...matches];
|
|
263
344
|
}
|
|
345
|
+
/**
|
|
346
|
+
* Visits known keys matching a wildcard pattern.
|
|
347
|
+
*/
|
|
264
348
|
async forEachKeyMatchingPattern(pattern, visitor) {
|
|
265
349
|
const matches = await this.matchPattern(pattern);
|
|
266
350
|
for (const key of matches) {
|
|
267
351
|
await visitor(key);
|
|
268
352
|
}
|
|
269
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* Clears all tag and known-key index state.
|
|
356
|
+
*/
|
|
270
357
|
async clear() {
|
|
271
358
|
this.tagToKeys.clear();
|
|
272
359
|
this.keyToTags.clear();
|
package/dist/cli.cjs
CHANGED
|
@@ -227,9 +227,15 @@ var RedisTagIndex = class {
|
|
|
227
227
|
this.scanCount = options.scanCount ?? 100;
|
|
228
228
|
this.knownKeysShards = normalizeKnownKeysShards(options.knownKeysShards);
|
|
229
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* Records a key as known without changing tag assignments.
|
|
232
|
+
*/
|
|
230
233
|
async touch(key) {
|
|
231
234
|
await this.client.sadd(this.knownKeysKeyFor(key), key);
|
|
232
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* Replaces the tags associated with a key and records the key as known.
|
|
238
|
+
*/
|
|
233
239
|
async track(key, tags) {
|
|
234
240
|
const keyTagsKey = this.keyTagsKey(key);
|
|
235
241
|
const existingTags = await this.client.smembers(keyTagsKey);
|
|
@@ -247,6 +253,9 @@ var RedisTagIndex = class {
|
|
|
247
253
|
}
|
|
248
254
|
await pipeline.exec();
|
|
249
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* Removes a key from all tag mappings and known-key tracking.
|
|
258
|
+
*/
|
|
250
259
|
async remove(key) {
|
|
251
260
|
const keyTagsKey = this.keyTagsKey(key);
|
|
252
261
|
const existingTags = await this.client.smembers(keyTagsKey);
|
|
@@ -258,9 +267,15 @@ var RedisTagIndex = class {
|
|
|
258
267
|
}
|
|
259
268
|
await pipeline.exec();
|
|
260
269
|
}
|
|
270
|
+
/**
|
|
271
|
+
* Returns keys currently associated with a tag.
|
|
272
|
+
*/
|
|
261
273
|
async keysForTag(tag) {
|
|
262
274
|
return this.client.smembers(this.tagKeysKey(tag));
|
|
263
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Visits keys currently associated with a tag.
|
|
278
|
+
*/
|
|
264
279
|
async forEachKeyForTag(tag, visitor) {
|
|
265
280
|
let cursor = "0";
|
|
266
281
|
const tagKey = this.tagKeysKey(tag);
|
|
@@ -272,6 +287,9 @@ var RedisTagIndex = class {
|
|
|
272
287
|
}
|
|
273
288
|
} while (cursor !== "0");
|
|
274
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* Returns known keys that start with a prefix.
|
|
292
|
+
*/
|
|
275
293
|
async keysForPrefix(prefix) {
|
|
276
294
|
const matches = [];
|
|
277
295
|
for (const knownKeysKey of this.knownKeysKeys()) {
|
|
@@ -284,6 +302,9 @@ var RedisTagIndex = class {
|
|
|
284
302
|
}
|
|
285
303
|
return matches;
|
|
286
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Visits known keys that start with a prefix.
|
|
307
|
+
*/
|
|
287
308
|
async forEachKeyForPrefix(prefix, visitor) {
|
|
288
309
|
for (const knownKeysKey of this.knownKeysKeys()) {
|
|
289
310
|
let cursor = "0";
|
|
@@ -298,9 +319,15 @@ var RedisTagIndex = class {
|
|
|
298
319
|
} while (cursor !== "0");
|
|
299
320
|
}
|
|
300
321
|
}
|
|
322
|
+
/**
|
|
323
|
+
* Returns the tags currently associated with a key.
|
|
324
|
+
*/
|
|
301
325
|
async tagsForKey(key) {
|
|
302
326
|
return this.client.smembers(this.keyTagsKey(key));
|
|
303
327
|
}
|
|
328
|
+
/**
|
|
329
|
+
* Returns known keys matching a wildcard pattern.
|
|
330
|
+
*/
|
|
304
331
|
async matchPattern(pattern) {
|
|
305
332
|
const matches = [];
|
|
306
333
|
for (const knownKeysKey of this.knownKeysKeys()) {
|
|
@@ -320,6 +347,9 @@ var RedisTagIndex = class {
|
|
|
320
347
|
}
|
|
321
348
|
return matches;
|
|
322
349
|
}
|
|
350
|
+
/**
|
|
351
|
+
* Visits known keys matching a wildcard pattern.
|
|
352
|
+
*/
|
|
323
353
|
async forEachKeyMatchingPattern(pattern, visitor) {
|
|
324
354
|
for (const knownKeysKey of this.knownKeysKeys()) {
|
|
325
355
|
let cursor = "0";
|
|
@@ -341,6 +371,9 @@ var RedisTagIndex = class {
|
|
|
341
371
|
} while (cursor !== "0");
|
|
342
372
|
}
|
|
343
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* Clears all Redis tag-index state under this prefix.
|
|
376
|
+
*/
|
|
344
377
|
async clear() {
|
|
345
378
|
const indexKeys = await this.scanIndexKeys();
|
|
346
379
|
if (indexKeys.length === 0) {
|