@c9up/echo 0.1.4 → 0.1.5

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.
@@ -13,7 +13,7 @@ export interface CacheConfig {
13
13
  prefix?: string;
14
14
  ttl?: number;
15
15
  }
16
- export declare class CacheManager implements CacheDriver {
16
+ export declare class CacheManager {
17
17
  private driver;
18
18
  private prefix;
19
19
  private defaultTtl;
@@ -22,15 +22,27 @@ export declare class CacheManager implements CacheDriver {
22
22
  get<T = unknown>(key: string): Promise<T | null>;
23
23
  set(key: string, value: unknown, ttlSeconds?: number): Promise<void>;
24
24
  delete(key: string): Promise<boolean>;
25
- flush(): Promise<void>;
25
+ /** Clear the whole cache (AdonisJS `cache.clear()`). */
26
+ clear(): Promise<void>;
26
27
  has(key: string): Promise<boolean>;
28
+ /**
29
+ * A cache view scoped under an extra key prefix (AdonisJS `cache.namespace()`).
30
+ * `cache.namespace('users').get('42')` reads/writes `users:42` (composed with
31
+ * any existing prefix). Shares the same driver + default TTL.
32
+ */
33
+ namespace(ns: string): CacheManager;
27
34
  /** Set a value with tags for grouped invalidation. */
28
35
  setWithTags(key: string, value: unknown, tags: string[], ttlSeconds?: number): Promise<void>;
29
36
  /** Flush only entries with matching tags. */
30
37
  flushTags(tags: string[]): Promise<void>;
31
38
  /** In-flight promises for stampede prevention. Each factory is typed per-call; the map is keyed by prefixed cache key. */
32
39
  private inflight;
33
- /** Get or set — fetch from cache, or compute and store. Single-flight: concurrent misses share one factory call. */
34
- remember<T>(key: string, ttl: number, factory: () => Promise<T>): Promise<T>;
40
+ /**
41
+ * Fetch from cache, or compute via `factory` and store (AdonisJS
42
+ * `cache.getOrSet`). Single-flight: concurrent misses share one factory call.
43
+ * (Positional `(key, ttl, factory)` is a deliberate simplification over
44
+ * Adonis's object form — echo keeps a leaner cache surface.)
45
+ */
46
+ getOrSet<T>(key: string, ttl: number, factory: () => Promise<T>): Promise<T>;
35
47
  }
36
48
  //# sourceMappingURL=CacheManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CacheManager.d.ts","sourceRoot":"","sources":["../src/CacheManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,WAAW;IAC3B,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACjD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnC;AAoBD,MAAM,WAAW,WAAW;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,YAAa,YAAW,WAAW;IAC/C,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,WAAW;IAMrD,OAAO,CAAC,SAAS;IAIX,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAIhD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAapE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIxC,sDAAsD;IAChD,WAAW,CAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAmBhB,6CAA6C;IACvC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9C,0HAA0H;IAC1H,OAAO,CAAC,QAAQ,CAA4C;IAE5D,oHAAoH;IAC9G,QAAQ,CAAC,CAAC,EACf,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACvB,OAAO,CAAC,CAAC,CAAC;CA0Bb"}
1
+ {"version":3,"file":"CacheManager.d.ts","sourceRoot":"","sources":["../src/CacheManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,WAAW;IAC3B,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACjD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnC;AAoBD,MAAM,WAAW,WAAW;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,YAAY;IACxB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,WAAW;IAMrD,OAAO,CAAC,SAAS;IAIX,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAIhD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAapE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI3C,wDAAwD;IAClD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIxC;;;;OAIG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY;IAOnC,sDAAsD;IAChD,WAAW,CAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAmBhB,6CAA6C;IACvC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9C,0HAA0H;IAC1H,OAAO,CAAC,QAAQ,CAA4C;IAE5D;;;;;OAKG;IACG,QAAQ,CAAC,CAAC,EACf,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACvB,OAAO,CAAC,CAAC,CAAC;CA0Bb"}
@@ -30,12 +30,24 @@ export class CacheManager {
30
30
  async delete(key) {
31
31
  return this.driver.delete(this.prefixKey(key));
32
32
  }
33
- async flush() {
33
+ /** Clear the whole cache (AdonisJS `cache.clear()`). */
34
+ async clear() {
34
35
  return this.driver.flush();
35
36
  }
36
37
  async has(key) {
37
38
  return this.driver.has(this.prefixKey(key));
38
39
  }
40
+ /**
41
+ * A cache view scoped under an extra key prefix (AdonisJS `cache.namespace()`).
42
+ * `cache.namespace('users').get('42')` reads/writes `users:42` (composed with
43
+ * any existing prefix). Shares the same driver + default TTL.
44
+ */
45
+ namespace(ns) {
46
+ return new CacheManager(this.driver, {
47
+ prefix: this.prefix ? `${this.prefix}:${ns}` : ns,
48
+ ttl: this.defaultTtl,
49
+ });
50
+ }
39
51
  /** Set a value with tags for grouped invalidation. */
40
52
  async setWithTags(key, value, tags, ttlSeconds) {
41
53
  if (value === null || value === undefined) {
@@ -55,8 +67,13 @@ export class CacheManager {
55
67
  }
56
68
  /** In-flight promises for stampede prevention. Each factory is typed per-call; the map is keyed by prefixed cache key. */
57
69
  inflight = new Map();
58
- /** Get or set — fetch from cache, or compute and store. Single-flight: concurrent misses share one factory call. */
59
- async remember(key, ttl, factory) {
70
+ /**
71
+ * Fetch from cache, or compute via `factory` and store (AdonisJS
72
+ * `cache.getOrSet`). Single-flight: concurrent misses share one factory call.
73
+ * (Positional `(key, ttl, factory)` is a deliberate simplification over
74
+ * Adonis's object form — echo keeps a leaner cache surface.)
75
+ */
76
+ async getOrSet(key, ttl, factory) {
60
77
  const prefixed = this.prefixKey(key);
61
78
  const existing = this.inflight.get(prefixed);
62
79
  if (existing)
@@ -1 +1 @@
1
- {"version":3,"file":"CacheManager.js","sourceRoot":"","sources":["../src/CacheManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CacheManager.js","sourceRoot":"","sources":["../src/CacheManager.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryDriver.d.ts","sourceRoot":"","sources":["../../src/drivers/MemoryDriver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQtD,qBAAa,YAAa,YAAW,WAAW;;gBAKnC,eAAe,SAAS;IAiBpC,OAAO,IAAI,IAAI;IAIT,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAUhD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWpE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxC,4CAA4C;IACtC,WAAW,CAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IA+BhB,2DAA2D;IACrD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAgC9C"}
1
+ {"version":3,"file":"MemoryDriver.d.ts","sourceRoot":"","sources":["../../src/drivers/MemoryDriver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQtD,qBAAa,YAAa,YAAW,WAAW;;gBAKnC,eAAe,SAAS;IAiBpC,OAAO,IAAI,IAAI;IAIT,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAqBhD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBpE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxC,4CAA4C;IACtC,WAAW,CAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IA+BhB,2DAA2D;IACrD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAgC9C"}
@@ -11,7 +11,7 @@ export class MemoryDriver {
11
11
  const now = Date.now();
12
12
  for (const [key, entry] of this.#store) {
13
13
  if (entry.expiresAt > 0 && entry.expiresAt < now) {
14
- this.#store.delete(key);
14
+ this.#evict(key, entry);
15
15
  }
16
16
  }
17
17
  }, sweepIntervalMs);
@@ -28,16 +28,35 @@ export class MemoryDriver {
28
28
  if (!entry)
29
29
  return null;
30
30
  if (entry.expiresAt > 0 && entry.expiresAt < Date.now()) {
31
- this.#store.delete(key);
31
+ this.#evict(key, entry);
32
32
  return null;
33
33
  }
34
34
  return entry.value;
35
35
  }
36
+ /**
37
+ * Delete an entry AND scrub its tag-index refs. TTL expiry (sweep + lazy
38
+ * get) must go through this — a bare `#store.delete` left dangling refs in
39
+ * `#tagIndex`, which a later `set(key, vNew)` reusing the key would turn into
40
+ * a wrong-purge under flushTags (audit 2026-06-13).
41
+ */
42
+ #evict(key, entry) {
43
+ for (const tag of entry.tags)
44
+ this.#tagIndex.get(tag)?.delete(key);
45
+ this.#store.delete(key);
46
+ }
36
47
  async set(key, value, ttlSeconds) {
37
48
  if (value === null || value === undefined) {
38
49
  throw new TypeError("Echo: caching null/undefined values is not supported");
39
50
  }
40
51
  const expiresAt = ttlSeconds != null && ttlSeconds > 0 ? Date.now() + ttlSeconds * 1000 : 0;
52
+ // Reconcile the tag index: overwriting a previously-tagged key with an
53
+ // untagged value must drop its old tag-index refs, or a later flushTags
54
+ // would purge this fresh value (the F3 fix only covered setWithTags).
55
+ const prev = this.#store.get(key);
56
+ if (prev !== undefined) {
57
+ for (const t of prev.tags)
58
+ this.#tagIndex.get(t)?.delete(key);
59
+ }
41
60
  this.#store.set(key, { value, expiresAt, tags: [] });
42
61
  }
43
62
  async delete(key) {
@@ -1 +1 @@
1
- {"version":3,"file":"MemoryDriver.js","sourceRoot":"","sources":["../../src/drivers/MemoryDriver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MemoryDriver.js","sourceRoot":"","sources":["../../src/drivers/MemoryDriver.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RedisDriver.d.ts","sourceRoot":"","sources":["../../src/drivers/RedisDriver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC3B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,CACJ,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,OAAO,EACpB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,OAAO,EACpB,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;CAC/B;AAED,qBAAa,WAAY,YAAW,WAAW;;gBAIlC,MAAM,EAAE,WAAW,EAAE,MAAM,SAAW;IAqB5C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAerC,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAMhD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASpE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBtB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxC;;;;;;;OAOG;IACG,WAAW,CAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IA6ChB;;;;;;OAMG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA6B9C"}
1
+ {"version":3,"file":"RedisDriver.d.ts","sourceRoot":"","sources":["../../src/drivers/RedisDriver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC3B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,CACJ,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,OAAO,EACpB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,OAAO,EACpB,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;CAC/B;AAED,qBAAa,WAAY,YAAW,WAAW;;gBAIlC,MAAM,EAAE,WAAW,EAAE,MAAM,SAAW;IAqB5C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAerC,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAMhD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBpE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBtB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKxC;;;;;;;OAOG;IACG,WAAW,CAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IA6ChB;;;;;;OAMG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA6B9C"}
@@ -48,12 +48,24 @@ export class RedisDriver {
48
48
  return JSON.parse(raw);
49
49
  }
50
50
  async set(key, value, ttlSeconds) {
51
+ const fullKey = this.#key(key);
52
+ // Reconcile tags: overwriting a previously-tagged key with an untagged
53
+ // value must drop it from its old tag sets + meta index, or a later
54
+ // flushTags would wrongly purge this fresh value (set() never touched the
55
+ // tag/meta keys, unlike delete()).
56
+ const metaKey = this.#metaKey(key);
57
+ const prevTags = await this.#client.smembers(metaKey);
58
+ for (const tag of prevTags) {
59
+ await this.#client.srem(`${this.#prefix}tag:${tag}`, fullKey);
60
+ }
61
+ if (prevTags.length > 0)
62
+ await this.#client.del(metaKey);
51
63
  const serialized = JSON.stringify(value);
52
64
  if (ttlSeconds && ttlSeconds > 0) {
53
- await this.#client.set(this.#key(key), serialized, "EX", ttlSeconds);
65
+ await this.#client.set(fullKey, serialized, "EX", ttlSeconds);
54
66
  }
55
67
  else {
56
- await this.#client.set(this.#key(key), serialized);
68
+ await this.#client.set(fullKey, serialized);
57
69
  }
58
70
  }
59
71
  async flush() {
@@ -1 +1 @@
1
- {"version":3,"file":"RedisDriver.js","sourceRoot":"","sources":["../../src/drivers/RedisDriver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RedisDriver.js","sourceRoot":"","sources":["../../src/drivers/RedisDriver.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * @c9up/echo — Cache layer for the Ream framework.
3
3
  *
4
- * Provides get/set/delete/flush/tags with pluggable drivers (Memory, Redis).
4
+ * Provides get/set/delete/clear/getOrSet/namespace/tags with pluggable drivers
5
+ * (Memory, Redis).
5
6
  *
6
7
  * @implements MISS-10
7
8
  */
@@ -10,4 +11,11 @@ export { CacheManager } from "./CacheManager.js";
10
11
  export { MemoryDriver } from "./drivers/MemoryDriver.js";
11
12
  export type { RedisClient } from "./drivers/RedisDriver.js";
12
13
  export { RedisDriver } from "./drivers/RedisDriver.js";
14
+ export type { EchoProviderConfig } from "./EchoProvider.js";
15
+ import type { EchoProviderConfig } from "./EchoProvider.js";
16
+ /**
17
+ * Author-time config helper for `config/cache.ts` — AdonisJS cache `defineConfig`
18
+ * parity. Identity at runtime; the generic preserves literal types for inference.
19
+ */
20
+ export declare function defineConfig<T extends EchoProviderConfig>(config: T): T;
13
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,kBAAkB,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAEvE"}
package/dist/index.js CHANGED
@@ -1,11 +1,19 @@
1
1
  /**
2
2
  * @c9up/echo — Cache layer for the Ream framework.
3
3
  *
4
- * Provides get/set/delete/flush/tags with pluggable drivers (Memory, Redis).
4
+ * Provides get/set/delete/clear/getOrSet/namespace/tags with pluggable drivers
5
+ * (Memory, Redis).
5
6
  *
6
7
  * @implements MISS-10
7
8
  */
8
9
  export { CacheManager } from "./CacheManager.js";
9
10
  export { MemoryDriver } from "./drivers/MemoryDriver.js";
10
11
  export { RedisDriver } from "./drivers/RedisDriver.js";
12
+ /**
13
+ * Author-time config helper for `config/cache.ts` — AdonisJS cache `defineConfig`
14
+ * parity. Identity at runtime; the generic preserves literal types for inference.
15
+ */
16
+ export function defineConfig(config) {
17
+ return config;
18
+ }
11
19
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAKvD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAA+B,MAAS;IACnE,OAAO,MAAM,CAAC;AACf,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c9up/echo",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Cache — pluggable cache contract with memory + Redis drivers for the Ream framework",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -34,7 +34,7 @@ export interface CacheConfig {
34
34
  ttl?: number;
35
35
  }
36
36
 
37
- export class CacheManager implements CacheDriver {
37
+ export class CacheManager {
38
38
  private driver: CacheDriver;
39
39
  private prefix: string;
40
40
  private defaultTtl: number;
@@ -70,7 +70,8 @@ export class CacheManager implements CacheDriver {
70
70
  return this.driver.delete(this.prefixKey(key));
71
71
  }
72
72
 
73
- async flush(): Promise<void> {
73
+ /** Clear the whole cache (AdonisJS `cache.clear()`). */
74
+ async clear(): Promise<void> {
74
75
  return this.driver.flush();
75
76
  }
76
77
 
@@ -78,6 +79,18 @@ export class CacheManager implements CacheDriver {
78
79
  return this.driver.has(this.prefixKey(key));
79
80
  }
80
81
 
82
+ /**
83
+ * A cache view scoped under an extra key prefix (AdonisJS `cache.namespace()`).
84
+ * `cache.namespace('users').get('42')` reads/writes `users:42` (composed with
85
+ * any existing prefix). Shares the same driver + default TTL.
86
+ */
87
+ namespace(ns: string): CacheManager {
88
+ return new CacheManager(this.driver, {
89
+ prefix: this.prefix ? `${this.prefix}:${ns}` : ns,
90
+ ttl: this.defaultTtl,
91
+ });
92
+ }
93
+
81
94
  /** Set a value with tags for grouped invalidation. */
82
95
  async setWithTags(
83
96
  key: string,
@@ -116,8 +129,13 @@ export class CacheManager implements CacheDriver {
116
129
  /** In-flight promises for stampede prevention. Each factory is typed per-call; the map is keyed by prefixed cache key. */
117
130
  private inflight: Map<string, Promise<unknown>> = new Map();
118
131
 
119
- /** Get or set — fetch from cache, or compute and store. Single-flight: concurrent misses share one factory call. */
120
- async remember<T>(
132
+ /**
133
+ * Fetch from cache, or compute via `factory` and store (AdonisJS
134
+ * `cache.getOrSet`). Single-flight: concurrent misses share one factory call.
135
+ * (Positional `(key, ttl, factory)` is a deliberate simplification over
136
+ * Adonis's object form — echo keeps a leaner cache surface.)
137
+ */
138
+ async getOrSet<T>(
121
139
  key: string,
122
140
  ttl: number,
123
141
  factory: () => Promise<T>,
@@ -21,7 +21,7 @@ export class MemoryDriver implements CacheDriver {
21
21
  const now = Date.now();
22
22
  for (const [key, entry] of this.#store) {
23
23
  if (entry.expiresAt > 0 && entry.expiresAt < now) {
24
- this.#store.delete(key);
24
+ this.#evict(key, entry);
25
25
  }
26
26
  }
27
27
  }, sweepIntervalMs);
@@ -41,12 +41,23 @@ export class MemoryDriver implements CacheDriver {
41
41
  const entry = this.#store.get(key);
42
42
  if (!entry) return null;
43
43
  if (entry.expiresAt > 0 && entry.expiresAt < Date.now()) {
44
- this.#store.delete(key);
44
+ this.#evict(key, entry);
45
45
  return null;
46
46
  }
47
47
  return entry.value as T;
48
48
  }
49
49
 
50
+ /**
51
+ * Delete an entry AND scrub its tag-index refs. TTL expiry (sweep + lazy
52
+ * get) must go through this — a bare `#store.delete` left dangling refs in
53
+ * `#tagIndex`, which a later `set(key, vNew)` reusing the key would turn into
54
+ * a wrong-purge under flushTags (audit 2026-06-13).
55
+ */
56
+ #evict(key: string, entry: CacheEntry): void {
57
+ for (const tag of entry.tags) this.#tagIndex.get(tag)?.delete(key);
58
+ this.#store.delete(key);
59
+ }
60
+
50
61
  async set(key: string, value: unknown, ttlSeconds?: number): Promise<void> {
51
62
  if (value === null || value === undefined) {
52
63
  throw new TypeError(
@@ -55,6 +66,13 @@ export class MemoryDriver implements CacheDriver {
55
66
  }
56
67
  const expiresAt =
57
68
  ttlSeconds != null && ttlSeconds > 0 ? Date.now() + ttlSeconds * 1000 : 0;
69
+ // Reconcile the tag index: overwriting a previously-tagged key with an
70
+ // untagged value must drop its old tag-index refs, or a later flushTags
71
+ // would purge this fresh value (the F3 fix only covered setWithTags).
72
+ const prev = this.#store.get(key);
73
+ if (prev !== undefined) {
74
+ for (const t of prev.tags) this.#tagIndex.get(t)?.delete(key);
75
+ }
58
76
  this.#store.set(key, { value, expiresAt, tags: [] });
59
77
  }
60
78
 
@@ -77,11 +77,22 @@ export class RedisDriver implements CacheDriver {
77
77
  }
78
78
 
79
79
  async set(key: string, value: unknown, ttlSeconds?: number): Promise<void> {
80
+ const fullKey = this.#key(key);
81
+ // Reconcile tags: overwriting a previously-tagged key with an untagged
82
+ // value must drop it from its old tag sets + meta index, or a later
83
+ // flushTags would wrongly purge this fresh value (set() never touched the
84
+ // tag/meta keys, unlike delete()).
85
+ const metaKey = this.#metaKey(key);
86
+ const prevTags = await this.#client.smembers(metaKey);
87
+ for (const tag of prevTags) {
88
+ await this.#client.srem(`${this.#prefix}tag:${tag}`, fullKey);
89
+ }
90
+ if (prevTags.length > 0) await this.#client.del(metaKey);
80
91
  const serialized = JSON.stringify(value);
81
92
  if (ttlSeconds && ttlSeconds > 0) {
82
- await this.#client.set(this.#key(key), serialized, "EX", ttlSeconds);
93
+ await this.#client.set(fullKey, serialized, "EX", ttlSeconds);
83
94
  } else {
84
- await this.#client.set(this.#key(key), serialized);
95
+ await this.#client.set(fullKey, serialized);
85
96
  }
86
97
  }
87
98
 
package/src/index.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * @c9up/echo — Cache layer for the Ream framework.
3
3
  *
4
- * Provides get/set/delete/flush/tags with pluggable drivers (Memory, Redis).
4
+ * Provides get/set/delete/clear/getOrSet/namespace/tags with pluggable drivers
5
+ * (Memory, Redis).
5
6
  *
6
7
  * @implements MISS-10
7
8
  */
@@ -11,3 +12,14 @@ export { CacheManager } from "./CacheManager.js";
11
12
  export { MemoryDriver } from "./drivers/MemoryDriver.js";
12
13
  export type { RedisClient } from "./drivers/RedisDriver.js";
13
14
  export { RedisDriver } from "./drivers/RedisDriver.js";
15
+ export type { EchoProviderConfig } from "./EchoProvider.js";
16
+
17
+ import type { EchoProviderConfig } from "./EchoProvider.js";
18
+
19
+ /**
20
+ * Author-time config helper for `config/cache.ts` — AdonisJS cache `defineConfig`
21
+ * parity. Identity at runtime; the generic preserves literal types for inference.
22
+ */
23
+ export function defineConfig<T extends EchoProviderConfig>(config: T): T {
24
+ return config;
25
+ }