valkyries 0.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.
Files changed (164) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/dist/bloom-filter/batching.d.mts +3 -0
  4. package/dist/bloom-filter/batching.d.mts.map +1 -0
  5. package/dist/bloom-filter/batching.mjs +18 -0
  6. package/dist/bloom-filter/batching.mjs.map +1 -0
  7. package/dist/bloom-filter/lookups.d.mts +6 -0
  8. package/dist/bloom-filter/lookups.d.mts.map +1 -0
  9. package/dist/bloom-filter/lookups.mjs +101 -0
  10. package/dist/bloom-filter/lookups.mjs.map +1 -0
  11. package/dist/bloom-filter/rebuilds.d.mts +9 -0
  12. package/dist/bloom-filter/rebuilds.d.mts.map +1 -0
  13. package/dist/bloom-filter/rebuilds.mjs +66 -0
  14. package/dist/bloom-filter/rebuilds.mjs.map +1 -0
  15. package/dist/bloom-filter/results.d.mts +3 -0
  16. package/dist/bloom-filter/results.d.mts.map +1 -0
  17. package/dist/bloom-filter/results.mjs +23 -0
  18. package/dist/bloom-filter/results.mjs.map +1 -0
  19. package/dist/bloom-filter/scripts.d.mts +9 -0
  20. package/dist/bloom-filter/scripts.d.mts.map +1 -0
  21. package/dist/bloom-filter/scripts.mjs +10 -0
  22. package/dist/bloom-filter/scripts.mjs.map +1 -0
  23. package/dist/bloom-filter/types.d.mts +12 -0
  24. package/dist/bloom-filter/types.d.mts.map +1 -0
  25. package/dist/bloom-filter/types.mjs +2 -0
  26. package/dist/bloom-filter/types.mjs.map +1 -0
  27. package/dist/bloom-filter/writes.d.mts +5 -0
  28. package/dist/bloom-filter/writes.d.mts.map +1 -0
  29. package/dist/bloom-filter/writes.mjs +54 -0
  30. package/dist/bloom-filter/writes.mjs.map +1 -0
  31. package/dist/bloom-filter.d.mts +90 -0
  32. package/dist/bloom-filter.d.mts.map +1 -0
  33. package/dist/bloom-filter.mjs +154 -0
  34. package/dist/bloom-filter.mjs.map +1 -0
  35. package/dist/cache/batch-read.d.mts +7 -0
  36. package/dist/cache/batch-read.d.mts.map +1 -0
  37. package/dist/cache/batch-read.mjs +142 -0
  38. package/dist/cache/batch-read.mjs.map +1 -0
  39. package/dist/cache/constants.d.mts +7 -0
  40. package/dist/cache/constants.d.mts.map +1 -0
  41. package/dist/cache/constants.mjs +8 -0
  42. package/dist/cache/constants.mjs.map +1 -0
  43. package/dist/cache/core.d.mts +38 -0
  44. package/dist/cache/core.d.mts.map +1 -0
  45. package/dist/cache/core.mjs +171 -0
  46. package/dist/cache/core.mjs.map +1 -0
  47. package/dist/cache/deletes.d.mts +8 -0
  48. package/dist/cache/deletes.d.mts.map +1 -0
  49. package/dist/cache/deletes.mjs +44 -0
  50. package/dist/cache/deletes.mjs.map +1 -0
  51. package/dist/cache/mutations.d.mts +25 -0
  52. package/dist/cache/mutations.d.mts.map +1 -0
  53. package/dist/cache/mutations.mjs +181 -0
  54. package/dist/cache/mutations.mjs.map +1 -0
  55. package/dist/cache/set-if-not-invalidated-events.d.mts +4 -0
  56. package/dist/cache/set-if-not-invalidated-events.d.mts.map +1 -0
  57. package/dist/cache/set-if-not-invalidated-events.mjs +21 -0
  58. package/dist/cache/set-if-not-invalidated-events.mjs.map +1 -0
  59. package/dist/cache/single-read.d.mts +11 -0
  60. package/dist/cache/single-read.d.mts.map +1 -0
  61. package/dist/cache/single-read.mjs +73 -0
  62. package/dist/cache/single-read.mjs.map +1 -0
  63. package/dist/cache/stale-refresh.d.mts +15 -0
  64. package/dist/cache/stale-refresh.d.mts.map +1 -0
  65. package/dist/cache/stale-refresh.mjs +70 -0
  66. package/dist/cache/stale-refresh.mjs.map +1 -0
  67. package/dist/cache-metrics.d.mts +10 -0
  68. package/dist/cache-metrics.d.mts.map +1 -0
  69. package/dist/cache-metrics.mjs +12 -0
  70. package/dist/cache-metrics.mjs.map +1 -0
  71. package/dist/cache-utils.d.mts +20 -0
  72. package/dist/cache-utils.d.mts.map +1 -0
  73. package/dist/cache-utils.mjs +67 -0
  74. package/dist/cache-utils.mjs.map +1 -0
  75. package/dist/cache.d.mts +4 -0
  76. package/dist/cache.d.mts.map +1 -0
  77. package/dist/cache.mjs +4 -0
  78. package/dist/cache.mjs.map +1 -0
  79. package/dist/clients.d.mts +51 -0
  80. package/dist/clients.d.mts.map +1 -0
  81. package/dist/clients.mjs +95 -0
  82. package/dist/clients.mjs.map +1 -0
  83. package/dist/config.d.mts +6 -0
  84. package/dist/config.d.mts.map +1 -0
  85. package/dist/config.mjs +10 -0
  86. package/dist/config.mjs.map +1 -0
  87. package/dist/delete.d.mts +3 -0
  88. package/dist/delete.d.mts.map +1 -0
  89. package/dist/delete.mjs +23 -0
  90. package/dist/delete.mjs.map +1 -0
  91. package/dist/dynamic-config/fields.d.mts +6 -0
  92. package/dist/dynamic-config/fields.d.mts.map +1 -0
  93. package/dist/dynamic-config/fields.mjs +50 -0
  94. package/dist/dynamic-config/fields.mjs.map +1 -0
  95. package/dist/dynamic-config/storage.d.mts +33 -0
  96. package/dist/dynamic-config/storage.d.mts.map +1 -0
  97. package/dist/dynamic-config/storage.mjs +55 -0
  98. package/dist/dynamic-config/storage.mjs.map +1 -0
  99. package/dist/dynamic-config.d.mts +34 -0
  100. package/dist/dynamic-config.d.mts.map +1 -0
  101. package/dist/dynamic-config.mjs +173 -0
  102. package/dist/dynamic-config.mjs.map +1 -0
  103. package/dist/errors.d.mts +4 -0
  104. package/dist/errors.d.mts.map +1 -0
  105. package/dist/errors.mjs +15 -0
  106. package/dist/errors.mjs.map +1 -0
  107. package/dist/events.d.mts +84 -0
  108. package/dist/events.d.mts.map +1 -0
  109. package/dist/events.mjs +18 -0
  110. package/dist/events.mjs.map +1 -0
  111. package/dist/index.d.mts +14 -0
  112. package/dist/index.d.mts.map +1 -0
  113. package/dist/index.mjs +13 -0
  114. package/dist/index.mjs.map +1 -0
  115. package/dist/key-normalization.d.mts +2 -0
  116. package/dist/key-normalization.d.mts.map +1 -0
  117. package/dist/key-normalization.mjs +4 -0
  118. package/dist/key-normalization.mjs.map +1 -0
  119. package/dist/rate-limiter.d.mts +40 -0
  120. package/dist/rate-limiter.d.mts.map +1 -0
  121. package/dist/rate-limiter.mjs +123 -0
  122. package/dist/rate-limiter.mjs.map +1 -0
  123. package/dist/scripts/bloom-filter-add.lua +26 -0
  124. package/dist/scripts/bloom-filter-ensure-exists.lua +13 -0
  125. package/dist/scripts/bloom-filter-exists-if-ready.lua +14 -0
  126. package/dist/scripts/bloom-filter-exists.lua +14 -0
  127. package/dist/scripts/bloom-filter-mexists-if-ready.lua +19 -0
  128. package/dist/scripts/bloom-filter-mexists.lua +17 -0
  129. package/dist/scripts/bloom-filter-reserve.lua +11 -0
  130. package/dist/scripts/cache-delete-with-invalidation.lua +29 -0
  131. package/dist/scripts/cache-set-if-not-invalidated.lua +47 -0
  132. package/dist/scripts/dynamic-config-set-fields.lua +23 -0
  133. package/dist/scripts/get-value-with-ttl.lua +35 -0
  134. package/dist/scripts/get-values-with-ttl.lua +81 -0
  135. package/dist/scripts/rate-limiter-add-and-check.lua +34 -0
  136. package/dist/scripts/rate-limiter-add.lua +26 -0
  137. package/dist/scripts/rate-limiter-get.lua +22 -0
  138. package/dist/scripts.d.mts +4 -0
  139. package/dist/scripts.d.mts.map +1 -0
  140. package/dist/scripts.mjs +31 -0
  141. package/dist/scripts.mjs.map +1 -0
  142. package/dist/shutdown.d.mts +3 -0
  143. package/dist/shutdown.d.mts.map +1 -0
  144. package/dist/shutdown.mjs +27 -0
  145. package/dist/shutdown.mjs.map +1 -0
  146. package/dist/types.d.mts +76 -0
  147. package/dist/types.d.mts.map +1 -0
  148. package/dist/types.mjs +2 -0
  149. package/dist/types.mjs.map +1 -0
  150. package/dist/utils.d.mts +16 -0
  151. package/dist/utils.d.mts.map +1 -0
  152. package/dist/utils.mjs +35 -0
  153. package/dist/utils.mjs.map +1 -0
  154. package/docs/bloom-filters.md +12 -0
  155. package/docs/cache.md +19 -0
  156. package/docs/clients.md +13 -0
  157. package/docs/configuration.md +16 -0
  158. package/docs/dynamic-config.md +13 -0
  159. package/docs/events-and-metrics.md +15 -0
  160. package/docs/lua-scripts.md +7 -0
  161. package/docs/migration.md +74 -0
  162. package/docs/rate-limiter.md +17 -0
  163. package/docs/testing-and-ci.md +21 -0
  164. package/package.json +80 -0
@@ -0,0 +1,44 @@
1
+ import { cacheValkeyClient } from "../clients.mjs";
2
+ import { emitValkeyEvent } from "../events.mjs";
3
+ import { deleteKeysWithPrefix } from "../delete.mjs";
4
+ import { normalizeCountResult } from "../utils.mjs";
5
+ import { CACHE_NAMESPACE, INVALIDATION_MARKER_TTL_SECONDS, cacheDeleteWithInvalidationScript, } from "./constants.mjs";
6
+ import { ValkeyCacheMutations } from "./mutations.mjs";
7
+ export class ValkeyCacheDeletes extends ValkeyCacheMutations {
8
+ async delete(...keys) {
9
+ const serializedKeys = [];
10
+ const keyArray = keys.flatMap((key) => {
11
+ const serialized = this.toSerializedKey(key);
12
+ if (serialized === null)
13
+ return [];
14
+ serializedKeys.push(serialized);
15
+ return [this.getSerializedCacheKey(serialized)];
16
+ });
17
+ if (keyArray.length === 0)
18
+ return 0;
19
+ const invalidationKeys = serializedKeys.map((key) => this.getSerializedInvalidationKey(key));
20
+ const result = await this.client.invokeScript(cacheDeleteWithInvalidationScript, {
21
+ keys: [...keyArray, ...invalidationKeys],
22
+ args: [String(keyArray.length), String(INVALIDATION_MARKER_TTL_SECONDS)],
23
+ });
24
+ const count = normalizeCountResult(result);
25
+ emitValkeyEvent("cache:delete", { cacheName: this.prefix, keys: serializedKeys });
26
+ return count;
27
+ }
28
+ async deleteBySerializedKey(...serializedKeys) {
29
+ const keyArray = serializedKeys.map((key) => this.getSerializedCacheKey(key));
30
+ if (keyArray.length === 0)
31
+ return 0;
32
+ const count = await this.client.unlink(keyArray);
33
+ emitValkeyEvent("cache:delete", { cacheName: this.prefix, keys: serializedKeys });
34
+ return count;
35
+ }
36
+ invalidate() {
37
+ return ValkeyCacheDeletes.invalidate(this.prefix, this.client);
38
+ }
39
+ static async invalidate(prefix, client = cacheValkeyClient) {
40
+ await deleteKeysWithPrefix(client, prefix ? `${CACHE_NAMESPACE}:${prefix}:*` : `${CACHE_NAMESPACE}:*`);
41
+ emitValkeyEvent("cache:invalidate", { cacheName: prefix });
42
+ }
43
+ }
44
+ //# sourceMappingURL=deletes.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deletes.mjs","sourceRoot":"","sources":["../../cache/deletes.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EACL,eAAe,EACf,+BAA+B,EAC/B,iCAAiC,GAClC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,MAAM,OAAO,kBAA+B,SAAQ,oBAAuB;IACzE,KAAK,CAAC,MAAM,CAAC,GAAG,IAAS;QACvB,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACpC,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;YAC7C,IAAI,UAAU,KAAK,IAAI;gBAAE,OAAO,EAAE,CAAC;YACnC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QACpC,MAAM,gBAAgB,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,4BAA4B,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7F,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,iCAAiC,EAAE;YAC/E,IAAI,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,gBAAgB,CAAC;YACxC,IAAI,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,+BAA+B,CAAC,CAAC;SACzE,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC3C,eAAe,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QAClF,OAAO,KAAK,CAAC;IACf,CAAC;IAES,KAAK,CAAC,qBAAqB,CAAC,GAAG,cAAwB;QAC/D,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9E,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjD,eAAe,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QAClF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,UAAU;QACR,OAAO,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAc,EAAE,MAAM,GAAG,iBAAiB;QAChE,MAAM,oBAAoB,CACxB,MAAM,EACN,MAAM,CAAC,CAAC,CAAC,GAAG,eAAe,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC,GAAG,eAAe,IAAI,CACnE,CAAC;QACF,eAAe,CAAC,kBAAkB,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7D,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ import { ValkeyCacheBatchRead } from "./batch-read.mts";
2
+ export declare abstract class ValkeyCacheMutations<K = string> extends ValkeyCacheBatchRead<K> {
3
+ refreshById<T>(aliases: K[], fetchByKey: (key: K) => Promise<T | null | undefined>): Promise<T | null>;
4
+ set(key: K, value: unknown, ttl?: number): Promise<void>;
5
+ setBatch(entries: Array<{
6
+ key: K;
7
+ value: unknown;
8
+ ttl?: number;
9
+ }>): Promise<void>;
10
+ protected setBySerializedKey(serializedKey: string, value: unknown, ttl?: number): Promise<void>;
11
+ protected setBySerializedKeyIfNotInvalidated(serializedKey: string, value: unknown, ttl?: number): Promise<void>;
12
+ protected setBatchIfNotInvalidated(entries: Array<{
13
+ key: K;
14
+ value: unknown;
15
+ ttl?: number;
16
+ }>): Promise<void>;
17
+ private setSerializedValue;
18
+ private setSerializedEntriesIfNotInvalidated;
19
+ private collectRefreshAliases;
20
+ private serializeRefreshResult;
21
+ private withSerializedKeys;
22
+ private entryTtl;
23
+ private handleSerializationFailure;
24
+ }
25
+ //# sourceMappingURL=mutations.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutations.d.mts","sourceRoot":"","sources":["../../cache/mutations.mts"],"names":[],"mappings":"AAMA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAGxD,8BAAsB,oBAAoB,CAAC,CAAC,GAAG,MAAM,CAAE,SAAQ,oBAAoB,CAAC,CAAC,CAAC;IAC9E,WAAW,CAAC,CAAC,EACjB,OAAO,EAAE,CAAC,EAAE,EACZ,UAAU,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,GACpD,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAkCpB,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM;IAMlC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,CAAC,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;cA6BvE,kBAAkB,CAChC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,OAAO,EACd,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;cAUA,kCAAkC,CAChD,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,OAAO,EACd,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;cASA,wBAAwB,CACtC,OAAO,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,CAAC,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GACvD,OAAO,CAAC,IAAI,CAAC;IAuBhB,OAAO,CAAC,kBAAkB;YAMZ,oCAAoC;IAoBlD,OAAO,CAAC,qBAAqB;YAYf,sBAAsB;IASpC,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,0BAA0B;CAInC"}
@@ -0,0 +1,181 @@
1
+ import { emitValkeyEvent } from "../events.mjs";
2
+ import { Batch, TimeUnit } from "@valkey/valkey-glide";
3
+ import { handleValkeyError } from "../errors.mjs";
4
+ import { ValkeyCacheTypeError, durationInMilliseconds } from "../cache-utils.mjs";
5
+ import { trackCacheCall } from "../cache-metrics.mjs";
6
+ import { cacheSetIfNotInvalidatedScript } from "./constants.mjs";
7
+ import { ValkeyCacheBatchRead } from "./batch-read.mjs";
8
+ import { emitSetIfNotInvalidatedEvents } from "./set-if-not-invalidated-events.mjs";
9
+ export class ValkeyCacheMutations extends ValkeyCacheBatchRead {
10
+ async refreshById(aliases, fetchByKey) {
11
+ const aliasState = this.collectRefreshAliases(aliases);
12
+ if (aliasState.firstValidAlias === null)
13
+ return null;
14
+ const start = process.hrtime.bigint();
15
+ try {
16
+ const result = await fetchByKey(aliasState.firstValidAlias);
17
+ const normalizedResult = result ?? null;
18
+ const serialized = await this.serializeRefreshResult(normalizedResult);
19
+ const ttl = normalizedResult === null ? this.nullTtl : this.ttl;
20
+ const batch = new Batch(false);
21
+ for (const key of aliasState.serializedKeys) {
22
+ batch.set(this.getSerializedCacheKey(key), serialized, {
23
+ expiry: { type: TimeUnit.Seconds, count: ttl },
24
+ });
25
+ }
26
+ this.client
27
+ .exec(batch, false)
28
+ .then(() => {
29
+ emitValkeyEvent("cache:set", { cacheName: this.prefix, keys: aliasState.serializedKeys });
30
+ })
31
+ .catch(handleValkeyError);
32
+ return normalizedResult;
33
+ }
34
+ finally {
35
+ trackCacheCall({
36
+ cacheName: this.prefix,
37
+ batch: false,
38
+ hits: 0,
39
+ misses: 1,
40
+ bloomMisses: 0,
41
+ duration: durationInMilliseconds(start),
42
+ });
43
+ }
44
+ }
45
+ set(key, value, ttl) {
46
+ const serializedKey = this.toSerializedKey(key);
47
+ if (serializedKey === null)
48
+ return Promise.resolve();
49
+ return this.setBySerializedKey(serializedKey, value, ttl);
50
+ }
51
+ async setBatch(entries) {
52
+ const validEntries = this.withSerializedKeys(entries);
53
+ if (validEntries.length === 0)
54
+ return;
55
+ const serializationResults = await Promise.allSettled(validEntries.map((entry) => this.serializeValue(entry.value)));
56
+ const batch = new Batch(false);
57
+ const writtenKeys = [];
58
+ for (let i = 0; i < validEntries.length; i++) {
59
+ const result = serializationResults[i];
60
+ if (result.status === "rejected") {
61
+ this.handleSerializationFailure(result.reason);
62
+ continue;
63
+ }
64
+ const entry = validEntries[i];
65
+ batch.set(this.getSerializedCacheKey(entry.serializedKey), result.value, {
66
+ expiry: { type: TimeUnit.Seconds, count: this.entryTtl(entry) },
67
+ });
68
+ writtenKeys.push(entry.serializedKey);
69
+ }
70
+ if (writtenKeys.length === 0)
71
+ return;
72
+ this.client
73
+ .exec(batch, false)
74
+ .then(() => {
75
+ emitValkeyEvent("cache:set", { cacheName: this.prefix, keys: writtenKeys });
76
+ })
77
+ .catch(handleValkeyError);
78
+ }
79
+ async setBySerializedKey(serializedKey, value, ttl) {
80
+ try {
81
+ const serialized = await this.serializeValue(value);
82
+ await this.setSerializedValue(serializedKey, serialized, ttl);
83
+ emitValkeyEvent("cache:set", { cacheName: this.prefix, keys: [serializedKey] });
84
+ }
85
+ catch (cause) {
86
+ this.handleSerializationFailure(cause);
87
+ }
88
+ }
89
+ async setBySerializedKeyIfNotInvalidated(serializedKey, value, ttl) {
90
+ try {
91
+ const serialized = await this.serializeValue(value);
92
+ await this.setSerializedEntriesIfNotInvalidated([{ serializedKey, value: serialized, ttl }]);
93
+ }
94
+ catch (cause) {
95
+ this.handleSerializationFailure(cause);
96
+ }
97
+ }
98
+ async setBatchIfNotInvalidated(entries) {
99
+ const validEntries = this.withSerializedKeys(entries);
100
+ if (validEntries.length === 0)
101
+ return;
102
+ const serializationResults = await Promise.allSettled(validEntries.map((entry) => this.serializeValue(entry.value)));
103
+ const setEntries = [];
104
+ for (let i = 0; i < validEntries.length; i++) {
105
+ const result = serializationResults[i];
106
+ if (result.status === "rejected") {
107
+ this.handleSerializationFailure(result.reason);
108
+ continue;
109
+ }
110
+ const entry = validEntries[i];
111
+ setEntries.push({
112
+ serializedKey: entry.serializedKey,
113
+ value: result.value,
114
+ ttl: this.entryTtl(entry),
115
+ });
116
+ }
117
+ await this.setSerializedEntriesIfNotInvalidated(setEntries);
118
+ }
119
+ setSerializedValue(serializedKey, serialized, ttl) {
120
+ return this.client.set(this.getSerializedCacheKey(serializedKey), serialized, {
121
+ expiry: { type: TimeUnit.Seconds, count: ttl != null && ttl > 0 ? ttl : this.ttl },
122
+ });
123
+ }
124
+ async setSerializedEntriesIfNotInvalidated(entries) {
125
+ if (entries.length === 0)
126
+ return;
127
+ const keys = [
128
+ ...entries.map((entry) => this.getSerializedCacheKey(entry.serializedKey)),
129
+ ...entries.map((entry) => this.getSerializedInvalidationKey(entry.serializedKey)),
130
+ ];
131
+ const args = [String(entries.length)];
132
+ for (const entry of entries) {
133
+ args.push(String(entry.ttl != null && entry.ttl > 0 ? entry.ttl : this.ttl));
134
+ args.push(entry.value);
135
+ }
136
+ const results = await this.client.invokeScript(cacheSetIfNotInvalidatedScript, {
137
+ keys,
138
+ args,
139
+ });
140
+ emitSetIfNotInvalidatedEvents(this.prefix, entries, results);
141
+ }
142
+ collectRefreshAliases(aliases) {
143
+ let firstValidAlias = null;
144
+ const serializedKeySet = new Set();
145
+ for (const key of aliases) {
146
+ const serialized = this.toSerializedKey(key);
147
+ if (serialized === null)
148
+ continue;
149
+ firstValidAlias ??= key;
150
+ serializedKeySet.add(serialized);
151
+ }
152
+ return { firstValidAlias, serializedKeys: [...serializedKeySet] };
153
+ }
154
+ async serializeRefreshResult(value) {
155
+ try {
156
+ return await this.serializeValue(value);
157
+ }
158
+ catch (cause) {
159
+ if (cause instanceof ValkeyCacheTypeError)
160
+ throw cause;
161
+ throw new Error("ValkeyCache: failed to stringify and/or compress value", { cause });
162
+ }
163
+ }
164
+ withSerializedKeys(entries) {
165
+ return entries.flatMap((entry) => {
166
+ const serializedKey = this.toSerializedKey(entry.key);
167
+ return serializedKey !== null ? [{ ...entry, serializedKey }] : [];
168
+ });
169
+ }
170
+ entryTtl(entry) {
171
+ if (entry.ttl != null && entry.ttl > 0)
172
+ return entry.ttl;
173
+ return entry.value === null || entry.value === undefined ? this.nullTtl : this.ttl;
174
+ }
175
+ handleSerializationFailure(cause) {
176
+ if (cause instanceof ValkeyCacheTypeError)
177
+ throw cause;
178
+ handleValkeyError(cause instanceof Error ? cause : new Error(String(cause)));
179
+ }
180
+ }
181
+ //# sourceMappingURL=mutations.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutations.mjs","sourceRoot":"","sources":["../../cache/mutations.mts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function emitSetIfNotInvalidatedEvents(prefix: string, entries: Array<{
2
+ serializedKey: string;
3
+ }>, results: unknown): void;
4
+ //# sourceMappingURL=set-if-not-invalidated-events.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-if-not-invalidated-events.d.mts","sourceRoot":"","sources":["../../cache/set-if-not-invalidated-events.mts"],"names":[],"mappings":"AAEA,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,KAAK,CAAC;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,EACzC,OAAO,EAAE,OAAO,QAoBjB"}
@@ -0,0 +1,21 @@
1
+ import { emitValkeyEvent } from "../events.mjs";
2
+ export function emitSetIfNotInvalidatedEvents(prefix, entries, results) {
3
+ const writtenKeys = Array.isArray(results)
4
+ ? entries.flatMap((entry, index) => {
5
+ const result = results[index];
6
+ return result === 1 || result === 1n ? [entry.serializedKey] : [];
7
+ })
8
+ : entries.map((entry) => entry.serializedKey);
9
+ const skippedKeys = Array.isArray(results) && results.length === entries.length
10
+ ? entries.flatMap((entry, index) => {
11
+ const result = results[index];
12
+ return result === 0 || result === 0n ? [entry.serializedKey] : [];
13
+ })
14
+ : [];
15
+ if (writtenKeys.length > 0)
16
+ emitValkeyEvent("cache:set", { cacheName: prefix, keys: writtenKeys });
17
+ if (skippedKeys.length > 0) {
18
+ emitValkeyEvent("cache:set-skipped", { cacheName: prefix, keys: skippedKeys });
19
+ }
20
+ }
21
+ //# sourceMappingURL=set-if-not-invalidated-events.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-if-not-invalidated-events.mjs","sourceRoot":"","sources":["../../cache/set-if-not-invalidated-events.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,UAAU,6BAA6B,CAC3C,MAAc,EACd,OAAyC,EACzC,OAAgB;IAEhB,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QACxC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9B,OAAO,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,CAAC,CAAC;QACJ,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAChD,MAAM,WAAW,GACf,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM;QACzD,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9B,OAAO,MAAM,KAAK,CAAC,IAAI,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,CAAC,CAAC;QACJ,CAAC,CAAC,EAAE,CAAC;IACT,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;QACxB,eAAe,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IACzE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,eAAe,CAAC,mBAAmB,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IACjF,CAAC;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ValkeyCacheResponse } from "../types.mts";
2
+ import { ValkeyCacheStaleRefresh } from "./stale-refresh.mts";
3
+ export declare abstract class ValkeyCacheSingleRead<K = string> extends ValkeyCacheStaleRefresh<K> {
4
+ cacheGetByAny<T>(fn: (key: K) => Promise<T | null | undefined>): (key: K) => Promise<T | null>;
5
+ invalidateCacheGetByAny(...keys: K[]): Promise<number>;
6
+ getKey(key: K): string;
7
+ get(key: K): ValkeyCacheResponse;
8
+ protected trackSingleRead(start: bigint, hits: number, misses: number, bloomMisses: number, serializedKey: string): void;
9
+ abstract delete(...keys: K[]): Promise<number>;
10
+ }
11
+ //# sourceMappingURL=single-read.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"single-read.d.mts","sourceRoot":"","sources":["../../cache/single-read.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAIxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,8BAAsB,qBAAqB,CAAC,CAAC,GAAG,MAAM,CAAE,SAAQ,uBAAuB,CAAC,CAAC,CAAC;IACxF,aAAa,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,IAC9C,KAAK,CAAC,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IA2C1C,uBAAuB,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;IAIpC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,MAAM;IAMhB,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,mBAAmB;IAOtC,SAAS,CAAC,eAAe,CACvB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM;IAiBvB,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAC/C"}
@@ -0,0 +1,73 @@
1
+ import { handleValkeyError } from "../errors.mjs";
2
+ import { durationInMilliseconds } from "../cache-utils.mjs";
3
+ import { trackCacheCall } from "../cache-metrics.mjs";
4
+ import { ValkeyCacheStaleRefresh } from "./stale-refresh.mjs";
5
+ export class ValkeyCacheSingleRead extends ValkeyCacheStaleRefresh {
6
+ cacheGetByAny(fn) {
7
+ return async (key) => {
8
+ const serializedKey = this.toSerializedKey(key);
9
+ if (serializedKey === null)
10
+ return null;
11
+ const start = process.hrtime.bigint();
12
+ let hits = 0;
13
+ let misses = 0;
14
+ let bloomMisses = 0;
15
+ try {
16
+ const { value: cached, ttlSecondsRemaining, bloomMiss, } = await this.getValueWithTtl(serializedKey);
17
+ if (bloomMiss) {
18
+ bloomMisses = 1;
19
+ return null;
20
+ }
21
+ const keyExists = ttlSecondsRemaining !== null && ttlSecondsRemaining !== -2;
22
+ if (cached !== null && cached !== undefined) {
23
+ hits = 1;
24
+ this.refreshStaleEntry(serializedKey, ttlSecondsRemaining, () => fn(key));
25
+ return cached;
26
+ }
27
+ if (keyExists) {
28
+ hits = 1;
29
+ return null;
30
+ }
31
+ misses = 1;
32
+ const result = await fn(key);
33
+ if (result === undefined || result === null) {
34
+ this.setBySerializedKeyIfNotInvalidated(serializedKey, null, this.nullTtl).catch(handleValkeyError);
35
+ return null;
36
+ }
37
+ this.setBySerializedKeyIfNotInvalidated(serializedKey, result).catch(handleValkeyError);
38
+ return result;
39
+ }
40
+ finally {
41
+ this.trackSingleRead(start, hits, misses, bloomMisses, serializedKey);
42
+ }
43
+ };
44
+ }
45
+ invalidateCacheGetByAny(...keys) {
46
+ return this.delete(...keys);
47
+ }
48
+ getKey(key) {
49
+ const serializedKey = this.toSerializedKey(key);
50
+ if (serializedKey === null)
51
+ throw new Error(`ValkeyCache: invalid key: ${String(key)}`);
52
+ return this.getSerializedCacheKey(serializedKey);
53
+ }
54
+ async get(key) {
55
+ const serializedKey = this.toSerializedKey(key);
56
+ if (serializedKey === null)
57
+ return null;
58
+ const { value } = await this.getValueWithTtl(serializedKey);
59
+ return value;
60
+ }
61
+ trackSingleRead(start, hits, misses, bloomMisses, serializedKey) {
62
+ trackCacheCall({
63
+ cacheName: this.prefix,
64
+ batch: false,
65
+ hits,
66
+ misses,
67
+ bloomMisses,
68
+ duration: durationInMilliseconds(start),
69
+ });
70
+ this.emitCacheEvents(hits > 0 ? [serializedKey] : [], misses > 0 ? [serializedKey] : [], bloomMisses > 0 ? [serializedKey] : []);
71
+ }
72
+ }
73
+ //# sourceMappingURL=single-read.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"single-read.mjs","sourceRoot":"","sources":["../../cache/single-read.mts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { ValkeyCacheCore, type CacheEntry } from "./core.mts";
2
+ export declare abstract class ValkeyCacheStaleRefresh<K = string> extends ValkeyCacheCore<K> {
3
+ protected refreshStaleBatchEntries<T>(serializedKeys: string[], keys: K[], entries: CacheEntry[], batchFn: (keys: K[]) => Promise<Array<T | null | undefined>>): void;
4
+ protected refreshStaleEntry(serializedKey: string, ttlSecondsRemaining: number | null, fetchValue: () => Promise<unknown>): void;
5
+ private markRefreshesPending;
6
+ private refreshBatch;
7
+ private refreshSingle;
8
+ protected abstract setBatchIfNotInvalidated(entries: Array<{
9
+ key: K;
10
+ value: unknown;
11
+ ttl?: number;
12
+ }>): Promise<void>;
13
+ protected abstract setBySerializedKeyIfNotInvalidated(serializedKey: string, value: unknown, ttl?: number): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=stale-refresh.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale-refresh.d.mts","sourceRoot":"","sources":["../../cache/stale-refresh.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE9D,8BAAsB,uBAAuB,CAAC,CAAC,GAAG,MAAM,CAAE,SAAQ,eAAe,CAAC,CAAC,CAAC;IAClF,SAAS,CAAC,wBAAwB,CAAC,CAAC,EAClC,cAAc,EAAE,MAAM,EAAE,EACxB,IAAI,EAAE,CAAC,EAAE,EACT,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAkB9D,SAAS,CAAC,iBAAiB,CACzB,aAAa,EAAE,MAAM,EACrB,mBAAmB,EAAE,MAAM,GAAG,IAAI,EAClC,UAAU,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC;IASpC,OAAO,CAAC,oBAAoB;YAKd,YAAY;YAyBZ,aAAa;IAa3B,SAAS,CAAC,QAAQ,CAAC,wBAAwB,CACzC,OAAO,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,CAAC,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GACvD,OAAO,CAAC,IAAI,CAAC;IAEhB,SAAS,CAAC,QAAQ,CAAC,kCAAkC,CACnD,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,OAAO,EACd,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;CACjB"}
@@ -0,0 +1,70 @@
1
+ import { handleValkeyError } from "../errors.mjs";
2
+ import { ValkeyCacheCore } from "./core.mjs";
3
+ export class ValkeyCacheStaleRefresh extends ValkeyCacheCore {
4
+ refreshStaleBatchEntries(serializedKeys, keys, entries, batchFn) {
5
+ const staleSerializedKeys = [];
6
+ const staleKeys = [];
7
+ for (let i = 0; i < entries.length; i++) {
8
+ const entry = entries[i];
9
+ if (entry.value === null || entry.value === undefined)
10
+ continue;
11
+ if (!this.shouldRefreshTtl(entry.ttlSecondsRemaining))
12
+ continue;
13
+ if (this.refreshPromises.has(serializedKeys[i]))
14
+ continue;
15
+ staleSerializedKeys.push(serializedKeys[i]);
16
+ staleKeys.push(keys[i]);
17
+ }
18
+ if (staleSerializedKeys.length === 0)
19
+ return;
20
+ this.markRefreshesPending(staleSerializedKeys);
21
+ const refreshPromise = this.refreshBatch(staleSerializedKeys, staleKeys, batchFn);
22
+ refreshPromise.catch(handleValkeyError);
23
+ }
24
+ refreshStaleEntry(serializedKey, ttlSecondsRemaining, fetchValue) {
25
+ if (!this.shouldRefreshTtl(ttlSecondsRemaining))
26
+ return;
27
+ if (this.refreshPromises.has(serializedKey))
28
+ return;
29
+ this.refreshPromises.set(serializedKey, Promise.resolve());
30
+ const refreshPromise = this.refreshSingle(serializedKey, fetchValue);
31
+ refreshPromise.catch(handleValkeyError);
32
+ }
33
+ markRefreshesPending(serializedKeys) {
34
+ const sentinel = Promise.resolve();
35
+ for (const key of serializedKeys)
36
+ this.refreshPromises.set(key, sentinel);
37
+ }
38
+ async refreshBatch(serializedKeys, keys, batchFn) {
39
+ try {
40
+ const results = await batchFn(keys);
41
+ if (!Array.isArray(results) || results.length !== keys.length) {
42
+ handleValkeyError(new Error(`Stale batch refresh returned invalid result: expected array of ${keys.length} items, got ${Array.isArray(results) ? results.length : typeof results}`));
43
+ return;
44
+ }
45
+ const setEntries = keys.map((key, i) => {
46
+ const value = results[i] ?? null;
47
+ return { key, value, ttl: value === null ? this.nullTtl : undefined };
48
+ });
49
+ await this.setBatchIfNotInvalidated(setEntries);
50
+ }
51
+ finally {
52
+ for (const key of serializedKeys)
53
+ this.refreshPromises.delete(key);
54
+ }
55
+ }
56
+ async refreshSingle(serializedKey, fetchValue) {
57
+ try {
58
+ const result = await fetchValue();
59
+ if (result === undefined || result === null) {
60
+ await this.setBySerializedKeyIfNotInvalidated(serializedKey, null, this.nullTtl);
61
+ return;
62
+ }
63
+ await this.setBySerializedKeyIfNotInvalidated(serializedKey, result);
64
+ }
65
+ finally {
66
+ this.refreshPromises.delete(serializedKey);
67
+ }
68
+ }
69
+ }
70
+ //# sourceMappingURL=stale-refresh.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale-refresh.mjs","sourceRoot":"","sources":["../../cache/stale-refresh.mts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export type CacheCallMetric = {
2
+ cacheName: string;
3
+ batch: boolean;
4
+ hits: number;
5
+ misses: number;
6
+ bloomMisses: number;
7
+ duration: number;
8
+ };
9
+ export declare function trackCacheCall(metric: CacheCallMetric): void;
10
+ //# sourceMappingURL=cache-metrics.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-metrics.d.mts","sourceRoot":"","sources":["../cache-metrics.mts"],"names":[],"mappings":"AAEA,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAS5D"}
@@ -0,0 +1,12 @@
1
+ import { emitValkeyEvent } from "./events.mjs";
2
+ export function trackCacheCall(metric) {
3
+ emitValkeyEvent("cache:call", {
4
+ cacheName: metric.cacheName,
5
+ batch: metric.batch,
6
+ hits: metric.hits,
7
+ misses: metric.misses,
8
+ bloomMisses: metric.bloomMisses,
9
+ durationMs: metric.duration,
10
+ });
11
+ }
12
+ //# sourceMappingURL=cache-metrics.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-metrics.mjs","sourceRoot":"","sources":["../cache-metrics.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAW/C,MAAM,UAAU,cAAc,CAAC,MAAuB;IACpD,eAAe,CAAC,YAAY,EAAE;QAC5B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,MAAM,CAAC,QAAQ;KAC5B,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Utilities for Valkey cache
3
+ */
4
+ import type { ValkeyCacheMode } from "./types.mts";
5
+ import type { GlideString } from "@valkey/valkey-glide";
6
+ export declare class ValkeyCacheTypeError extends TypeError {
7
+ constructor(message: string);
8
+ }
9
+ export declare const durationInMilliseconds: (start: bigint) => number;
10
+ /**
11
+ * Serialize a value for storage in Valkey cache
12
+ * Supports text, buffer, and JSON modes with automatic compression
13
+ */
14
+ export declare function serializeValue(value: unknown, mode: ValkeyCacheMode): Promise<string | Buffer>;
15
+ /**
16
+ * Decode a value from Valkey cache
17
+ * Handles decompression and parsing based on mode
18
+ */
19
+ export declare function decodeValue(result: GlideString | null, mode: ValkeyCacheMode): Promise<string | Buffer | Record<string, unknown> | null>;
20
+ //# sourceMappingURL=cache-utils.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-utils.d.mts","sourceRoot":"","sources":["../cache-utils.mts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,qBAAa,oBAAqB,SAAQ,SAAS;gBACrC,OAAO,EAAE,MAAM;CAI5B;AAED,eAAO,MAAM,sBAAsB,GAAI,OAAO,MAAM,KAAG,MACF,CAAC;AAMtD;;;GAGG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,CAsB1B;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,WAAW,GAAG,IAAI,EAC1B,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAwB3D"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Utilities for Valkey cache
3
+ */
4
+ import { gzip, gunzip } from "node:zlib";
5
+ import { promisify } from "node:util";
6
+ export class ValkeyCacheTypeError extends TypeError {
7
+ constructor(message) {
8
+ super(`ValkeyCache: ${message}`);
9
+ this.name = "ValkeyCacheTypeError";
10
+ }
11
+ }
12
+ export const durationInMilliseconds = (start) => Number(process.hrtime.bigint() - start) / 1_000_000;
13
+ const COMPRESSION_THRESHOLD = 2 * 1024; // 2kb
14
+ const gzipAsync = promisify(gzip);
15
+ const gunzipAsync = promisify(gunzip);
16
+ /**
17
+ * Serialize a value for storage in Valkey cache
18
+ * Supports text, buffer, and JSON modes with automatic compression
19
+ */
20
+ export async function serializeValue(value, mode) {
21
+ let serialized;
22
+ if (mode === "text") {
23
+ if (typeof value !== "string") {
24
+ throw new ValkeyCacheTypeError("text mode requires a string value");
25
+ }
26
+ serialized = value;
27
+ }
28
+ else if (mode === "buffer") {
29
+ if (!Buffer.isBuffer(value)) {
30
+ throw new ValkeyCacheTypeError("buffer mode requires a Buffer value");
31
+ }
32
+ serialized = value;
33
+ }
34
+ else {
35
+ serialized = JSON.stringify(value);
36
+ }
37
+ if (Buffer.byteLength(serialized) > COMPRESSION_THRESHOLD) {
38
+ serialized = await gzipAsync(serialized);
39
+ }
40
+ return serialized;
41
+ }
42
+ /**
43
+ * Decode a value from Valkey cache
44
+ * Handles decompression and parsing based on mode
45
+ */
46
+ export async function decodeValue(result, mode) {
47
+ if (result === null)
48
+ return null;
49
+ if (!Buffer.isBuffer(result)) {
50
+ throw new ValkeyCacheTypeError(`Expected Buffer, got ${typeof result}`);
51
+ }
52
+ let buffer = result;
53
+ // Check if buffer is gzipped by looking for gzip magic number (0x1f 0x8b)
54
+ const isGzipped = buffer.length >= 2 && buffer[0] === 0x1f && buffer[1] === 0x8b;
55
+ if (isGzipped) {
56
+ buffer = await gunzipAsync(buffer);
57
+ }
58
+ if (mode === "buffer") {
59
+ return buffer;
60
+ }
61
+ const text = buffer.toString("utf8");
62
+ if (mode === "text") {
63
+ return text;
64
+ }
65
+ return JSON.parse(text);
66
+ }
67
+ //# sourceMappingURL=cache-utils.mjs.map