layercache 1.4.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.
@@ -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) {
package/dist/cli.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  validateCacheKey,
5
5
  validatePattern,
6
6
  validateTag
7
- } from "./chunk-7KMKQ6QZ.js";
7
+ } from "./chunk-6X7NV5BG.js";
8
8
  import {
9
9
  isStoredValueEnvelope,
10
10
  resolveStoredValue