@c9up/echo 0.1.5 → 0.1.7

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.
Files changed (56) hide show
  1. package/dist/CacheManager.d.ts +63 -28
  2. package/dist/CacheManager.d.ts.map +1 -1
  3. package/dist/CacheManager.js +348 -70
  4. package/dist/CacheManager.js.map +1 -1
  5. package/dist/EchoProvider.d.ts +15 -9
  6. package/dist/EchoProvider.d.ts.map +1 -1
  7. package/dist/EchoProvider.js +47 -13
  8. package/dist/EchoProvider.js.map +1 -1
  9. package/dist/StoreManager.d.ts +61 -0
  10. package/dist/StoreManager.d.ts.map +1 -0
  11. package/dist/StoreManager.js +70 -0
  12. package/dist/StoreManager.js.map +1 -0
  13. package/dist/drivers/MemoryDriver.d.ts +13 -6
  14. package/dist/drivers/MemoryDriver.d.ts.map +1 -1
  15. package/dist/drivers/MemoryDriver.js +67 -61
  16. package/dist/drivers/MemoryDriver.js.map +1 -1
  17. package/dist/drivers/RedisDriver.d.ts +17 -17
  18. package/dist/drivers/RedisDriver.d.ts.map +1 -1
  19. package/dist/drivers/RedisDriver.js +103 -55
  20. package/dist/drivers/RedisDriver.js.map +1 -1
  21. package/dist/drivers/TieredDriver.d.ts +41 -0
  22. package/dist/drivers/TieredDriver.d.ts.map +1 -0
  23. package/dist/drivers/TieredDriver.js +132 -0
  24. package/dist/drivers/TieredDriver.js.map +1 -0
  25. package/dist/duration.d.ts +32 -0
  26. package/dist/duration.d.ts.map +1 -0
  27. package/dist/duration.js +75 -0
  28. package/dist/duration.js.map +1 -0
  29. package/dist/errors.d.ts +21 -0
  30. package/dist/errors.d.ts.map +1 -0
  31. package/dist/errors.js +31 -0
  32. package/dist/errors.js.map +1 -0
  33. package/dist/index.d.ts +15 -3
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +10 -2
  36. package/dist/index.js.map +1 -1
  37. package/dist/testing/main.d.ts +41 -0
  38. package/dist/testing/main.d.ts.map +1 -0
  39. package/dist/testing/main.js +41 -0
  40. package/dist/testing/main.js.map +1 -0
  41. package/dist/types.d.ts +146 -0
  42. package/dist/types.d.ts.map +1 -0
  43. package/dist/types.js +6 -0
  44. package/dist/types.js.map +1 -0
  45. package/package.json +6 -1
  46. package/src/CacheManager.ts +497 -99
  47. package/src/EchoProvider.ts +58 -15
  48. package/src/StoreManager.ts +104 -0
  49. package/src/drivers/MemoryDriver.ts +97 -66
  50. package/src/drivers/RedisDriver.ts +135 -58
  51. package/src/drivers/TieredDriver.ts +186 -0
  52. package/src/duration.ts +86 -0
  53. package/src/errors.ts +33 -0
  54. package/src/index.ts +43 -3
  55. package/src/testing/main.ts +69 -0
  56. package/src/types.ts +156 -0
@@ -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;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"}
1
+ {"version":3,"file":"RedisDriver.d.ts","sourceRoot":"","sources":["../../src/drivers/RedisDriver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhF,+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;AAiBD,qBAAa,WAAY,YAAW,cAAc;;gBAIrC,MAAM,EAAE,WAAW,EAAE,MAAM,SAAW;IAkB5C,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,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAgDjE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOpE,QAAQ,CACb,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,gBAAgB,GACvB,OAAO,CAAC,IAAI,CAAC;IAwBV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBtB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiDxC,0EAA0E;IACpE,WAAW,CAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAMhB;;;;OAIG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BhD,gDAAgD;IAC1C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAG9C"}
@@ -1,11 +1,23 @@
1
1
  /**
2
- * Redis cache driver — production-grade cache with TTL and tags.
2
+ * Redis cache driver — production-grade cache with TTL, grace
3
+ * (stale-while-revalidate) and tags. Suitable as the L2 tier of
4
+ * {@link TieredDriver}.
3
5
  *
4
6
  * Requires a Redis client instance implementing the minimal interface below.
5
7
  * Compatible with ioredis and redis (node-redis) clients.
6
8
  *
7
- * @implements MISS-10
9
+ * STORAGE FORMAT (breaking vs echo <=0.1.5): values are stored as a JSON
10
+ * envelope `{ "v": <value>, "e": <logicalExpiryEpochMs> }`. The physical Redis
11
+ * TTL (`EX`) covers `ttl + grace` so a logically-expired value survives for the
12
+ * grace window; `e` records the logical expiry so reads can flag it stale.
8
13
  */
14
+ function isEnvelope(x) {
15
+ return (typeof x === "object" &&
16
+ x !== null &&
17
+ "v" in x &&
18
+ "e" in x &&
19
+ typeof Reflect.get(x, "e") === "number");
20
+ }
9
21
  export class RedisDriver {
10
22
  #client;
11
23
  #prefix;
@@ -17,12 +29,9 @@ export class RedisDriver {
17
29
  return `${this.#prefix}${k}`;
18
30
  }
19
31
  /**
20
- * Reverse-index for per-key tag membership. Lets `setWithTags()` clean
21
- * stale memberships when a key is retagged, and `delete()` drop the key
22
- * from every tag-set it belongs to. Without this, a re-tag like
23
- * `setWithTags('article:42', v, ['homepage'])` (was `['news']`) leaves
24
- * `tag:news` pointing at `article:42`, and a later `flushTags(['news'])`
25
- * silently deletes the value.
32
+ * Reverse-index for per-key tag membership. Lets tag writes clean stale
33
+ * memberships on retag, and `delete()` drop the key from every tag-set it
34
+ * belongs to.
26
35
  */
27
36
  #metaKey(k) {
28
37
  return `${this.#prefix}meta:tags:${k}`;
@@ -42,31 +51,79 @@ export class RedisDriver {
42
51
  return count > 0;
43
52
  }
44
53
  async get(key) {
54
+ const entry = await this.getEntry(key);
55
+ if (entry === null || entry.stale)
56
+ return null;
57
+ return entry.value;
58
+ }
59
+ async getEntry(key) {
45
60
  const raw = await this.#client.get(this.#key(key));
46
61
  if (raw === null)
47
62
  return null;
48
- return JSON.parse(raw);
63
+ const parsed = JSON.parse(raw);
64
+ if (!isEnvelope(parsed))
65
+ return null;
66
+ const stale = parsed.e > 0 && parsed.e < Date.now();
67
+ // Deserialize boundary: the on-the-wire value is genuinely `unknown`; the
68
+ // caller's generic `T` is the assertion. This is the single unavoidable
69
+ // cast site (mirrors echo <=0.1.5 `JSON.parse(raw) as T`).
70
+ const value = parsed.v;
71
+ return { value, stale, expiresAt: parsed.e };
49
72
  }
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);
73
+ /** Write the value envelope with a physical (grace-inclusive) TTL in seconds. */
74
+ async #writeEnvelope(fullKey, value, logicalTtlSeconds, physicalTtlSeconds, logicalExpiresAtOverride) {
75
+ // An absolute override (e.g. `expire()` marking stale-now) wins over the
76
+ // ttl-derived logical expiry; a past value flags the entry stale on read.
77
+ const expiresAt = logicalExpiresAtOverride !== undefined
78
+ ? logicalExpiresAtOverride
79
+ : logicalTtlSeconds > 0
80
+ ? Date.now() + logicalTtlSeconds * 1000
81
+ : 0;
82
+ const envelope = { v: value, e: expiresAt };
83
+ const serialized = JSON.stringify(envelope);
84
+ if (physicalTtlSeconds > 0) {
85
+ await this.#client.set(fullKey, serialized, "EX", physicalTtlSeconds);
86
+ }
87
+ else {
88
+ await this.#client.set(fullKey, serialized);
89
+ }
90
+ }
91
+ /** Drop a key from its previous tag memberships (reconcile before re-tagging). */
92
+ async #dropTags(fullKey, metaKey) {
57
93
  const prevTags = await this.#client.smembers(metaKey);
58
94
  for (const tag of prevTags) {
59
95
  await this.#client.srem(`${this.#prefix}tag:${tag}`, fullKey);
60
96
  }
61
97
  if (prevTags.length > 0)
62
98
  await this.#client.del(metaKey);
63
- const serialized = JSON.stringify(value);
64
- if (ttlSeconds && ttlSeconds > 0) {
65
- await this.#client.set(fullKey, serialized, "EX", ttlSeconds);
66
- }
67
- else {
68
- await this.#client.set(fullKey, serialized);
99
+ return prevTags;
100
+ }
101
+ async set(key, value, ttlSeconds) {
102
+ const fullKey = this.#key(key);
103
+ await this.#dropTags(fullKey, this.#metaKey(key));
104
+ const ttl = ttlSeconds && ttlSeconds > 0 ? ttlSeconds : 0;
105
+ await this.#writeEnvelope(fullKey, value, ttl, ttl);
106
+ }
107
+ async setEntry(key, value, options) {
108
+ const fullKey = this.#key(key);
109
+ const metaKey = this.#metaKey(key);
110
+ const ttl = options.ttlSeconds && options.ttlSeconds > 0 ? options.ttlSeconds : 0;
111
+ const grace = options.graceSeconds && options.graceSeconds > 0
112
+ ? options.graceSeconds
113
+ : 0;
114
+ // With an absolute logical expiry (e.g. `expire()` marking stale-now), the
115
+ // ttl no longer drives physical retention — keep the value for the grace
116
+ // window measured from now so a stale-but-graced read still finds it.
117
+ const override = options.expiresAt;
118
+ const physical = override !== undefined ? grace : ttl > 0 ? ttl + grace : 0;
119
+ const tags = options.tags ?? [];
120
+ if (tags.length === 0) {
121
+ await this.#dropTags(fullKey, metaKey);
122
+ await this.#writeEnvelope(fullKey, value, ttl, physical, override);
123
+ return;
69
124
  }
125
+ await this.#writeEnvelope(fullKey, value, ttl, physical, override);
126
+ await this.#applyTags(key, tags, physical);
70
127
  }
71
128
  async flush() {
72
129
  const scan = this.#client.scan;
@@ -85,19 +142,13 @@ export class RedisDriver {
85
142
  }
86
143
  }
87
144
  async has(key) {
88
- const exists = await this.#client.exists(this.#key(key));
89
- return exists > 0;
145
+ return (await this.get(key)) !== null;
90
146
  }
91
147
  /**
92
- * Set a value with tag memberships for group invalidation.
93
- *
94
- * Re-tagging an existing key (e.g. `['news']` → `['homepage']`) cleans
95
- * the stale memberships via the per-key reverse-index — without this,
96
- * a later `flushTags(['news'])` would silently wipe the still-current
97
- * value because the abandoned `tag:news` set kept pointing at it.
148
+ * Reconcile the tag reverse-index for `key` to exactly `tags`, and extend
149
+ * tag-set / meta TTLs to the physical (grace-inclusive) retention.
98
150
  */
99
- async setWithTags(key, value, tags, ttlSeconds) {
100
- await this.set(key, value, ttlSeconds);
151
+ async #applyTags(key, tags, physicalTtlSeconds) {
101
152
  const fullKey = this.#key(key);
102
153
  const metaKey = this.#metaKey(key);
103
154
  const oldTags = await this.#client.smembers(metaKey);
@@ -105,54 +156,47 @@ export class RedisDriver {
105
156
  const oldTagSet = new Set(oldTags);
106
157
  const removedTags = oldTags.filter((t) => !newTagSet.has(t));
107
158
  const addedTags = tags.filter((t) => !oldTagSet.has(t));
108
- // Drop the key from tag-sets it no longer belongs to.
109
159
  for (const tag of removedTags) {
110
- const tagKey = `${this.#prefix}tag:${tag}`;
111
- await this.#client.srem(tagKey, fullKey);
160
+ await this.#client.srem(`${this.#prefix}tag:${tag}`, fullKey);
112
161
  }
113
- // Add to new tag-sets; re-touch TTLs on every declared tag so existing
114
- // memberships extend correctly on re-set.
115
162
  for (const tag of tags) {
116
163
  const tagKey = `${this.#prefix}tag:${tag}`;
117
164
  if (addedTags.includes(tag)) {
118
165
  await this.#client.sadd(tagKey, fullKey);
119
166
  }
120
- if (ttlSeconds && ttlSeconds > 0) {
167
+ if (physicalTtlSeconds > 0) {
121
168
  const currentTtl = await this.#client.ttl(tagKey);
122
- if (currentTtl < 0 || ttlSeconds > currentTtl) {
123
- await this.#client.expire(tagKey, ttlSeconds);
169
+ if (currentTtl < 0 || physicalTtlSeconds > currentTtl) {
170
+ await this.#client.expire(tagKey, physicalTtlSeconds);
124
171
  }
125
172
  }
126
173
  }
127
- // Refresh the reverse-index to match the new tag set. Drop+re-add is
128
- // simpler than diff-mutating the set and matches `tags` exactly even
129
- // in the empty-array case.
130
174
  if (oldTags.length > 0) {
131
175
  await this.#client.del(metaKey);
132
176
  }
133
177
  if (tags.length > 0) {
134
178
  await this.#client.sadd(metaKey, ...tags);
135
- if (ttlSeconds && ttlSeconds > 0) {
136
- await this.#client.expire(metaKey, ttlSeconds);
179
+ if (physicalTtlSeconds > 0) {
180
+ await this.#client.expire(metaKey, physicalTtlSeconds);
137
181
  }
138
182
  }
139
183
  }
184
+ /** Set a value with tag memberships for group invalidation (no grace). */
185
+ async setWithTags(key, value, tags, ttlSeconds) {
186
+ const ttl = ttlSeconds && ttlSeconds > 0 ? ttlSeconds : 0;
187
+ await this.#writeEnvelope(this.#key(key), value, ttl, ttl);
188
+ await this.#applyTags(key, tags, ttl);
189
+ }
140
190
  /**
141
- * Flush all entries tagged with any of the given tags. Cleans up the
142
- * per-key reverse-index AND cross-tag memberships so a multi-tag key
143
- * (e.g. `['news', 'homepage']`) flushed via `news` is also removed from
144
- * the `homepage` tag-set — otherwise the `homepage` set ends up with a
145
- * dangling reference to a now-deleted value.
191
+ * Invalidate all entries tagged with any of the given tags. Cleans the
192
+ * per-key reverse-index AND cross-tag memberships so a multi-tag key flushed
193
+ * via one tag is also removed from the others.
146
194
  */
147
- async flushTags(tags) {
195
+ async deleteByTag(tags) {
148
196
  for (const tag of tags) {
149
197
  const tagKey = `${this.#prefix}tag:${tag}`;
150
198
  const members = await this.#client.smembers(tagKey);
151
199
  for (const fullKey of members) {
152
- // Read every OTHER tag this key claims (via the reverse-index)
153
- // and SREM the key from each. The reverse-index key derives
154
- // from the unprefixed user key — recover it by stripping the
155
- // prefix.
156
200
  const userKey = fullKey.startsWith(this.#prefix)
157
201
  ? fullKey.slice(this.#prefix.length)
158
202
  : fullKey;
@@ -174,5 +218,9 @@ export class RedisDriver {
174
218
  await this.#client.del(tagKey);
175
219
  }
176
220
  }
221
+ /** @deprecated alias of {@link deleteByTag}. */
222
+ async flushTags(tags) {
223
+ return this.deleteByTag(tags);
224
+ }
177
225
  }
178
226
  //# sourceMappingURL=RedisDriver.js.map
@@ -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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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * TieredDriver — two-tier cache composing an L1 (in-process, e.g.
3
+ * {@link MemoryDriver}) and an L2 (distributed, e.g. {@link RedisDriver}).
4
+ *
5
+ * Reads go L1 → L2 → miss, promoting an L2 hit back into L1. Writes are
6
+ * write-through to both tiers. An optional {@link CacheBus} broadcasts
7
+ * invalidations so peer instances drop their (now stale) L1 copies — the L2 is
8
+ * shared, so only L1 needs cross-instance invalidation.
9
+ */
10
+ import type { CacheDriver, CacheEntry, DriverSetOptions, TaggableDriver } from "../types.js";
11
+ /** A cross-instance invalidation message. */
12
+ export interface BusMessage {
13
+ type: "delete" | "clear";
14
+ keys: string[];
15
+ }
16
+ /** Duck-typed pub/sub bus for cross-instance L1 invalidation (e.g. Redis pub/sub). */
17
+ export interface CacheBus {
18
+ publish(message: BusMessage): void | Promise<void>;
19
+ subscribe(handler: (message: BusMessage) => void): void;
20
+ }
21
+ export interface TieredDriverOptions {
22
+ l1: CacheDriver;
23
+ l2: CacheDriver;
24
+ bus?: CacheBus;
25
+ }
26
+ export declare class TieredDriver implements TaggableDriver {
27
+ #private;
28
+ constructor(options: TieredDriverOptions);
29
+ getEntry<T = unknown>(key: string): Promise<CacheEntry<T> | null>;
30
+ get<T = unknown>(key: string): Promise<T | null>;
31
+ set(key: string, value: unknown, ttlSeconds?: number): Promise<void>;
32
+ setEntry(key: string, value: unknown, options: DriverSetOptions): Promise<void>;
33
+ delete(key: string): Promise<boolean>;
34
+ flush(): Promise<void>;
35
+ has(key: string): Promise<boolean>;
36
+ setWithTags(key: string, value: unknown, tags: string[], ttlSeconds?: number): Promise<void>;
37
+ deleteByTag(tags: string[]): Promise<void>;
38
+ /** @deprecated alias of {@link deleteByTag}. */
39
+ flushTags(tags: string[]): Promise<void>;
40
+ }
41
+ //# sourceMappingURL=TieredDriver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TieredDriver.d.ts","sourceRoot":"","sources":["../../src/drivers/TieredDriver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACX,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,MAAM,aAAa,CAAC;AAErB,6CAA6C;AAC7C,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IACzB,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAED,sFAAsF;AACtF,MAAM,WAAW,QAAQ;IACxB,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAC;CACxD;AAED,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,WAAW,CAAC;IAChB,EAAE,EAAE,WAAW,CAAC;IAChB,GAAG,CAAC,EAAE,QAAQ,CAAC;CACf;AAqCD,qBAAa,YAAa,YAAW,cAAc;;gBAKtC,OAAO,EAAE,mBAAmB;IAclC,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IA+BjE,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;IAIpE,QAAQ,CACb,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,gBAAgB,GACvB,OAAO,CAAC,IAAI,CAAC;IAMV,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlC,WAAW,CAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EAAE,EACd,UAAU,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAIV,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAehD,gDAAgD;IAC1C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAG9C"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * TieredDriver — two-tier cache composing an L1 (in-process, e.g.
3
+ * {@link MemoryDriver}) and an L2 (distributed, e.g. {@link RedisDriver}).
4
+ *
5
+ * Reads go L1 → L2 → miss, promoting an L2 hit back into L1. Writes are
6
+ * write-through to both tiers. An optional {@link CacheBus} broadcasts
7
+ * invalidations so peer instances drop their (now stale) L1 copies — the L2 is
8
+ * shared, so only L1 needs cross-instance invalidation.
9
+ */
10
+ function isTaggable(driver) {
11
+ const candidate = driver;
12
+ return (typeof candidate.setWithTags === "function" &&
13
+ (typeof candidate.deleteByTag === "function" ||
14
+ typeof candidate.flushTags === "function"));
15
+ }
16
+ async function readEntry(driver, key) {
17
+ if (driver.getEntry)
18
+ return driver.getEntry(key);
19
+ const value = await driver.get(key);
20
+ return value === null ? null : { value, stale: false };
21
+ }
22
+ async function writeEntry(driver, key, value, options) {
23
+ if (driver.setEntry) {
24
+ await driver.setEntry(key, value, options);
25
+ return;
26
+ }
27
+ if (options.tags && options.tags.length > 0 && isTaggable(driver)) {
28
+ await driver.setWithTags(key, value, options.tags, options.ttlSeconds);
29
+ return;
30
+ }
31
+ await driver.set(key, value, options.ttlSeconds);
32
+ }
33
+ export class TieredDriver {
34
+ #l1;
35
+ #l2;
36
+ #bus;
37
+ constructor(options) {
38
+ this.#l1 = options.l1;
39
+ this.#l2 = options.l2;
40
+ this.#bus = options.bus;
41
+ this.#bus?.subscribe((message) => {
42
+ // Peer invalidation: only the local L1 needs clearing (L2 is shared).
43
+ if (message.type === "clear") {
44
+ void this.#l1.flush();
45
+ return;
46
+ }
47
+ for (const key of message.keys)
48
+ void this.#l1.delete(key);
49
+ });
50
+ }
51
+ async getEntry(key) {
52
+ const l1 = await readEntry(this.#l1, key);
53
+ if (l1 && !l1.stale)
54
+ return l1;
55
+ const l2 = await readEntry(this.#l2, key);
56
+ if (l2 && !l2.stale) {
57
+ // Promote a fresh L2 hit into L1 — preserving the remaining logical TTL
58
+ // so L1 cannot outlive L2 (a promotion with no TTL left an immortal L1
59
+ // entry that kept serving a value the L2 had already expired).
60
+ if (l2.expiresAt === undefined) {
61
+ // Driver doesn't expose expiry — promoting with no TTL risks an
62
+ // immortal L1 copy; skip promotion rather than cache it forever.
63
+ return l2;
64
+ }
65
+ const opts = {};
66
+ if (l2.expiresAt > 0) {
67
+ const remainingSeconds = (l2.expiresAt - Date.now()) / 1000;
68
+ // Raced past expiry between the stale check and now — don't promote
69
+ // a value that is already dead.
70
+ if (remainingSeconds <= 0)
71
+ return l2;
72
+ opts.ttlSeconds = remainingSeconds;
73
+ }
74
+ // expiresAt === 0 → the L2 entry genuinely never expires → promote as-is.
75
+ await writeEntry(this.#l1, key, l2.value, opts);
76
+ return l2;
77
+ }
78
+ if (l2)
79
+ return l2; // stale L2 (grace)
80
+ if (l1)
81
+ return l1; // stale L1 (grace)
82
+ return null;
83
+ }
84
+ async get(key) {
85
+ const entry = await this.getEntry(key);
86
+ if (entry === null || entry.stale)
87
+ return null;
88
+ return entry.value;
89
+ }
90
+ async set(key, value, ttlSeconds) {
91
+ await this.setEntry(key, value, { ttlSeconds });
92
+ }
93
+ async setEntry(key, value, options) {
94
+ await writeEntry(this.#l1, key, value, options);
95
+ await writeEntry(this.#l2, key, value, options);
96
+ await this.#bus?.publish({ type: "delete", keys: [key] });
97
+ }
98
+ async delete(key) {
99
+ const l1 = await this.#l1.delete(key);
100
+ const l2 = await this.#l2.delete(key);
101
+ await this.#bus?.publish({ type: "delete", keys: [key] });
102
+ return l1 || l2;
103
+ }
104
+ async flush() {
105
+ await this.#l1.flush();
106
+ await this.#l2.flush();
107
+ await this.#bus?.publish({ type: "clear", keys: [] });
108
+ }
109
+ async has(key) {
110
+ return (await this.get(key)) !== null;
111
+ }
112
+ async setWithTags(key, value, tags, ttlSeconds) {
113
+ await this.setEntry(key, value, { ttlSeconds, tags });
114
+ }
115
+ async deleteByTag(tags) {
116
+ const l1 = this.#l1;
117
+ const l2 = this.#l2;
118
+ if (!isTaggable(l1) || !isTaggable(l2)) {
119
+ throw new Error("Echo: TieredDriver.deleteByTag requires both tiers to be taggable");
120
+ }
121
+ await l1.deleteByTag(tags);
122
+ await l2.deleteByTag(tags);
123
+ // Peers can't map tags → keys locally; broadcast a clear so their L1 drops
124
+ // any tagged copies (conservative but correct).
125
+ await this.#bus?.publish({ type: "clear", keys: [] });
126
+ }
127
+ /** @deprecated alias of {@link deleteByTag}. */
128
+ async flushTags(tags) {
129
+ return this.deleteByTag(tags);
130
+ }
131
+ }
132
+ //# sourceMappingURL=TieredDriver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TieredDriver.js","sourceRoot":"","sources":["../../src/drivers/TieredDriver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Duration parsing — bentocache `Duration` parity, adapted to echo's
3
+ * seconds-native driver layer.
4
+ *
5
+ * DIVERGENCE (named): bentocache treats a bare `number` as **milliseconds**.
6
+ * Echo's drivers, positional API (`set(key, value, ttlSeconds)`) and the
7
+ * kitchen-sink app are all **seconds-native**, so a bare `number` here means
8
+ * **seconds**. Keeping one unit across the positional and object forms avoids
9
+ * a dual-unit footgun (cf. DNR `helpers_no_magic_layer`). String durations use
10
+ * the same human syntax as bento (`'5m'`, `'300s'`, `'2h'`, `'500ms'`).
11
+ */
12
+ /**
13
+ * A cache duration:
14
+ * - `number` — seconds (echo-native; see divergence note above)
15
+ * - `string` — human duration (`'5m'`, `'2h'`, `'1d'`, `'500ms'`, …)
16
+ * - `null` — never expires
17
+ */
18
+ export type Duration = number | string | null;
19
+ /**
20
+ * Parse a human duration string (`'5m'`, `'300s'`, `'500ms'`) into seconds.
21
+ * A unit-less numeric string is interpreted as seconds.
22
+ */
23
+ export declare function parseDuration(value: string): number;
24
+ /**
25
+ * Resolve a {@link Duration} to a TTL in **seconds**.
26
+ *
27
+ * @returns the TTL in seconds; `0` means "never expires" (either an explicit
28
+ * `null`, or a non-positive value, matching echo's driver convention where
29
+ * `ttlSeconds <= 0` is treated as immortal).
30
+ */
31
+ export declare function resolveTtlSeconds(ttl: Duration | undefined, defaultSeconds: number): number;
32
+ //# sourceMappingURL=duration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duration.d.ts","sourceRoot":"","sources":["../src/duration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAiC9C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAanD;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAChC,GAAG,EAAE,QAAQ,GAAG,SAAS,EACzB,cAAc,EAAE,MAAM,GACpB,MAAM,CAKR"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Duration parsing — bentocache `Duration` parity, adapted to echo's
3
+ * seconds-native driver layer.
4
+ *
5
+ * DIVERGENCE (named): bentocache treats a bare `number` as **milliseconds**.
6
+ * Echo's drivers, positional API (`set(key, value, ttlSeconds)`) and the
7
+ * kitchen-sink app are all **seconds-native**, so a bare `number` here means
8
+ * **seconds**. Keeping one unit across the positional and object forms avoids
9
+ * a dual-unit footgun (cf. DNR `helpers_no_magic_layer`). String durations use
10
+ * the same human syntax as bento (`'5m'`, `'300s'`, `'2h'`, `'500ms'`).
11
+ */
12
+ const UNIT_SECONDS = {
13
+ ms: 1 / 1000,
14
+ msec: 1 / 1000,
15
+ msecs: 1 / 1000,
16
+ millisecond: 1 / 1000,
17
+ milliseconds: 1 / 1000,
18
+ s: 1,
19
+ sec: 1,
20
+ secs: 1,
21
+ second: 1,
22
+ seconds: 1,
23
+ m: 60,
24
+ min: 60,
25
+ mins: 60,
26
+ minute: 60,
27
+ minutes: 60,
28
+ h: 3600,
29
+ hr: 3600,
30
+ hrs: 3600,
31
+ hour: 3600,
32
+ hours: 3600,
33
+ d: 86_400,
34
+ day: 86_400,
35
+ days: 86_400,
36
+ w: 604_800,
37
+ week: 604_800,
38
+ weeks: 604_800,
39
+ };
40
+ const DURATION_RE = /^\s*(-?\d+(?:\.\d+)?)\s*([a-z]+)?\s*$/i;
41
+ /**
42
+ * Parse a human duration string (`'5m'`, `'300s'`, `'500ms'`) into seconds.
43
+ * A unit-less numeric string is interpreted as seconds.
44
+ */
45
+ export function parseDuration(value) {
46
+ const match = DURATION_RE.exec(value);
47
+ if (!match) {
48
+ throw new TypeError(`Echo: invalid duration string "${value}"`);
49
+ }
50
+ const amount = Number(match[1]);
51
+ const unit = match[2]?.toLowerCase();
52
+ if (unit === undefined)
53
+ return amount;
54
+ const factor = UNIT_SECONDS[unit];
55
+ if (factor === undefined) {
56
+ throw new TypeError(`Echo: unknown duration unit "${unit}" in "${value}"`);
57
+ }
58
+ return amount * factor;
59
+ }
60
+ /**
61
+ * Resolve a {@link Duration} to a TTL in **seconds**.
62
+ *
63
+ * @returns the TTL in seconds; `0` means "never expires" (either an explicit
64
+ * `null`, or a non-positive value, matching echo's driver convention where
65
+ * `ttlSeconds <= 0` is treated as immortal).
66
+ */
67
+ export function resolveTtlSeconds(ttl, defaultSeconds) {
68
+ if (ttl === null)
69
+ return 0;
70
+ if (ttl === undefined)
71
+ return defaultSeconds;
72
+ const seconds = typeof ttl === "number" ? ttl : parseDuration(ttl);
73
+ return seconds > 0 ? seconds : 0;
74
+ }
75
+ //# sourceMappingURL=duration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duration.js","sourceRoot":"","sources":["../src/duration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,MAAM,YAAY,GAA2B;IAC5C,EAAE,EAAE,CAAC,GAAG,IAAI;IACZ,IAAI,EAAE,CAAC,GAAG,IAAI;IACd,KAAK,EAAE,CAAC,GAAG,IAAI;IACf,WAAW,EAAE,CAAC,GAAG,IAAI;IACrB,YAAY,EAAE,CAAC,GAAG,IAAI;IACtB,CAAC,EAAE,CAAC;IACJ,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,CAAC;IACV,CAAC,EAAE,EAAE;IACL,GAAG,EAAE,EAAE;IACP,IAAI,EAAE,EAAE;IACR,MAAM,EAAE,EAAE;IACV,OAAO,EAAE,EAAE;IACX,CAAC,EAAE,IAAI;IACP,EAAE,EAAE,IAAI;IACR,GAAG,EAAE,IAAI;IACT,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,IAAI;IACX,CAAC,EAAE,MAAM;IACT,GAAG,EAAE,MAAM;IACX,IAAI,EAAE,MAAM;IACZ,CAAC,EAAE,OAAO;IACV,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,OAAO;CACd,CAAC;AAEF,MAAM,WAAW,GAAG,wCAAwC,CAAC;AAE7D;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IAC1C,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,IAAI,SAAS,CAAC,kCAAkC,KAAK,GAAG,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IACrC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACtC,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,SAAS,CAAC,gCAAgC,IAAI,SAAS,KAAK,GAAG,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,MAAM,GAAG,MAAM,CAAC;AACxB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAChC,GAAyB,EACzB,cAAsB;IAEtB,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,CAAC,CAAC;IAC3B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,cAAc,CAAC;IAC7C,MAAM,OAAO,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACnE,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Echo cache errors — bentocache parity (`errors.ts`).
3
+ */
4
+ /** Raised when a factory exceeds its configured `hardTimeout`. */
5
+ export declare class TimeoutError extends Error {
6
+ constructor(key: string, timeoutMs: number);
7
+ }
8
+ /**
9
+ * Wraps an error thrown by a `getOrSet` factory. Passed to `onFactoryError`
10
+ * so callers can observe both foreground and background factory failures.
11
+ */
12
+ export declare class FactoryError extends Error {
13
+ /** The cache key the factory was computing. */
14
+ readonly key: string;
15
+ /** The original error thrown by the factory. */
16
+ readonly cause: unknown;
17
+ /** `true` when the factory was running in the background (soft timeout / refresh). */
18
+ readonly isBackground: boolean;
19
+ constructor(key: string, cause: unknown, isBackground: boolean);
20
+ }
21
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,kEAAkE;AAClE,qBAAa,YAAa,SAAQ,KAAK;gBAC1B,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAI1C;AAED;;;GAGG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACtC,+CAA+C;IAC/C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,SAAkB,KAAK,EAAE,OAAO,CAAC;IACjC,sFAAsF;IACtF,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;gBAEnB,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO;CAQ9D"}