@warlock.js/cache 4.1.14 → 4.2.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 (85) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +21 -0
  3. package/cjs/index.cjs +32 -28
  4. package/cjs/index.cjs.map +1 -1
  5. package/esm/cache-manager.d.mts +1 -1
  6. package/esm/cache-manager.d.mts.map +1 -1
  7. package/esm/cache-manager.mjs +1 -1
  8. package/esm/cache-manager.mjs.map +1 -1
  9. package/esm/cached/auto-key.d.mts +1 -1
  10. package/esm/cached/auto-key.d.mts.map +1 -1
  11. package/esm/cached/auto-key.mjs +1 -1
  12. package/esm/cached/auto-key.mjs.map +1 -1
  13. package/esm/cached/cached.d.mts +1 -1
  14. package/esm/cached/cached.d.mts.map +1 -1
  15. package/esm/cached/cached.mjs +1 -1
  16. package/esm/cached/cached.mjs.map +1 -1
  17. package/esm/cached/normalize-args.d.mts +1 -1
  18. package/esm/cached/normalize-args.d.mts.map +1 -1
  19. package/esm/cached/normalize-args.mjs +1 -1
  20. package/esm/cached/normalize-args.mjs.map +1 -1
  21. package/esm/drivers/base-cache-driver.d.mts +2 -2
  22. package/esm/drivers/base-cache-driver.d.mts.map +1 -1
  23. package/esm/drivers/base-cache-driver.mjs +4 -2
  24. package/esm/drivers/base-cache-driver.mjs.map +1 -1
  25. package/esm/drivers/file-cache-driver.d.mts +1 -1
  26. package/esm/drivers/file-cache-driver.d.mts.map +1 -1
  27. package/esm/drivers/file-cache-driver.mjs +1 -1
  28. package/esm/drivers/file-cache-driver.mjs.map +1 -1
  29. package/esm/drivers/lru-memory-cache-driver.d.mts +1 -1
  30. package/esm/drivers/lru-memory-cache-driver.d.mts.map +1 -1
  31. package/esm/drivers/lru-memory-cache-driver.mjs +1 -1
  32. package/esm/drivers/lru-memory-cache-driver.mjs.map +1 -1
  33. package/esm/drivers/memory-cache-driver.d.mts +1 -1
  34. package/esm/drivers/memory-cache-driver.d.mts.map +1 -1
  35. package/esm/drivers/memory-cache-driver.mjs +1 -1
  36. package/esm/drivers/memory-cache-driver.mjs.map +1 -1
  37. package/esm/drivers/memory-extended-cache-driver.d.mts +1 -1
  38. package/esm/drivers/memory-extended-cache-driver.d.mts.map +1 -1
  39. package/esm/drivers/memory-extended-cache-driver.mjs +1 -1
  40. package/esm/drivers/memory-extended-cache-driver.mjs.map +1 -1
  41. package/esm/drivers/mock-cache-driver.d.mts +1 -1
  42. package/esm/drivers/mock-cache-driver.d.mts.map +1 -1
  43. package/esm/drivers/mock-cache-driver.mjs +1 -1
  44. package/esm/drivers/mock-cache-driver.mjs.map +1 -1
  45. package/esm/drivers/null-cache-driver.d.mts +1 -1
  46. package/esm/drivers/null-cache-driver.d.mts.map +1 -1
  47. package/esm/drivers/null-cache-driver.mjs +1 -1
  48. package/esm/drivers/null-cache-driver.mjs.map +1 -1
  49. package/esm/drivers/pg-cache-driver.d.mts +1 -1
  50. package/esm/drivers/pg-cache-driver.d.mts.map +1 -1
  51. package/esm/drivers/pg-cache-driver.mjs +1 -1
  52. package/esm/drivers/pg-cache-driver.mjs.map +1 -1
  53. package/esm/drivers/redis-cache-driver.d.mts +1 -1
  54. package/esm/drivers/redis-cache-driver.d.mts.map +1 -1
  55. package/esm/drivers/redis-cache-driver.mjs +10 -8
  56. package/esm/drivers/redis-cache-driver.mjs.map +1 -1
  57. package/esm/list/memory-cache-list.d.mts +1 -1
  58. package/esm/list/memory-cache-list.d.mts.map +1 -1
  59. package/esm/list/memory-cache-list.mjs +1 -1
  60. package/esm/list/memory-cache-list.mjs.map +1 -1
  61. package/esm/metrics.d.mts +1 -1
  62. package/esm/metrics.d.mts.map +1 -1
  63. package/esm/metrics.mjs +1 -1
  64. package/esm/metrics.mjs.map +1 -1
  65. package/esm/scoped-cache.d.mts +1 -1
  66. package/esm/scoped-cache.d.mts.map +1 -1
  67. package/esm/scoped-cache.mjs +1 -1
  68. package/esm/scoped-cache.mjs.map +1 -1
  69. package/esm/tagged-cache.d.mts +1 -1
  70. package/esm/tagged-cache.d.mts.map +1 -1
  71. package/esm/tagged-cache.mjs +1 -1
  72. package/esm/tagged-cache.mjs.map +1 -1
  73. package/esm/tagged-scoped-cache.d.mts +1 -1
  74. package/esm/tagged-scoped-cache.d.mts.map +1 -1
  75. package/esm/tagged-scoped-cache.mjs +1 -1
  76. package/esm/tagged-scoped-cache.mjs.map +1 -1
  77. package/esm/types.d.mts +2 -2
  78. package/esm/types.d.mts.map +1 -1
  79. package/esm/types.mjs +1 -1
  80. package/esm/types.mjs.map +1 -1
  81. package/esm/utils.d.mts +1 -1
  82. package/esm/utils.d.mts.map +1 -1
  83. package/esm/utils.mjs +1 -1
  84. package/esm/utils.mjs.map +1 -1
  85. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"tagged-cache.mjs","names":[],"sources":["../../../../../@warlock.js/cache/src/tagged-cache.ts"],"sourcesContent":["import type {\r\n CacheDriver,\r\n CacheKey,\r\n CacheSetOptions,\r\n CacheTtl,\r\n TaggedCacheDriver,\r\n} from \"./types\";\r\n\r\n/**\r\n * Tagged Cache Wrapper\r\n * Wraps a cache driver to automatically manage tag relationships\r\n */\r\nexport class TaggedCache implements TaggedCacheDriver {\r\n /**\r\n * The tags associated with this tagged cache instance\r\n */\r\n protected cacheTags: string[];\r\n\r\n /**\r\n * The underlying cache driver\r\n */\r\n protected driver: CacheDriver<any, any>;\r\n\r\n /**\r\n * Constructor\r\n */\r\n public constructor(tags: string[], driver: CacheDriver<any, any>) {\r\n this.cacheTags = tags;\r\n this.driver = driver;\r\n }\r\n\r\n /**\r\n * Get the tag key prefix for storing tag-key relationships\r\n */\r\n protected tagKey(tag: string): string {\r\n return `cache:tags:${tag}`;\r\n }\r\n\r\n /**\r\n * Store tag-key relationship\r\n */\r\n protected async storeTaggedKey(key: string): Promise<void> {\r\n await this.storeTagRelationship(key);\r\n }\r\n\r\n /**\r\n * Public alias of the tag-index writer. Called by `BaseCacheDriver.applyTags`\r\n * when tags are passed inline through `CacheSetOptions.tags`.\r\n *\r\n * @internal — public for cross-class use within this package; not part of the\r\n * stable consumer API.\r\n */\r\n public async storeTagRelationship(parsedKey: string): Promise<void> {\r\n for (const tag of this.cacheTags) {\r\n const tagKey = this.tagKey(tag);\r\n const keys = (await this.driver.get(tagKey)) || [];\r\n\r\n if (!keys.includes(parsedKey)) {\r\n keys.push(parsedKey);\r\n await this.driver.set(tagKey, keys, Infinity);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get all keys associated with tags\r\n */\r\n protected async getTaggedKeys(): Promise<Set<string>> {\r\n const allKeys = new Set<string>();\r\n\r\n for (const tag of this.cacheTags) {\r\n const tagKey = this.tagKey(tag);\r\n const keys = (await this.driver.get(tagKey)) || [];\r\n\r\n for (const key of keys) {\r\n allKeys.add(key);\r\n }\r\n }\r\n\r\n return allKeys;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async set(\r\n key: CacheKey,\r\n value: any,\r\n ttlOrOptions?: CacheTtl | CacheSetOptions,\r\n ): Promise<any> {\r\n const parsedKey = this.driver.parseKey(key);\r\n\r\n await this.driver.set(key, value, ttlOrOptions);\r\n\r\n await this.storeTaggedKey(parsedKey);\r\n\r\n return value;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async get(key: CacheKey): Promise<any | null> {\r\n return this.driver.get(key);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async remove(key: CacheKey): Promise<void> {\r\n const parsedKey = this.driver.parseKey(key);\r\n\r\n // Remove the value\r\n await this.driver.remove(key);\r\n\r\n // Remove from all tag relationships\r\n for (const tag of this.cacheTags) {\r\n const tagKey = this.tagKey(tag);\r\n const keys = (await this.driver.get(tagKey)) || [];\r\n const updatedKeys = keys.filter((k: string) => k !== parsedKey);\r\n await this.driver.set(tagKey, updatedKeys, Infinity);\r\n }\r\n }\r\n\r\n /**\r\n * Invalidate (clear) all keys associated with the current tags\r\n */\r\n public async invalidate(): Promise<void> {\r\n const keysToRemove = await this.getTaggedKeys();\r\n\r\n // Remove all tagged keys\r\n for (const key of keysToRemove) {\r\n await this.driver.remove(key);\r\n }\r\n\r\n // Clear tag relationship keys\r\n for (const tag of this.cacheTags) {\r\n await this.driver.remove(this.tagKey(tag));\r\n }\r\n }\r\n\r\n /**\r\n * Flush all keys associated with the current tags\r\n * @deprecated Use invalidate() instead for better semantics\r\n */\r\n public async flush(): Promise<void> {\r\n return this.invalidate();\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async has(key: CacheKey): Promise<boolean> {\r\n return this.driver.has(key);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async remember(\r\n key: CacheKey,\r\n ttl: number,\r\n callback: () => Promise<any>,\r\n ): Promise<any> {\r\n const value = await this.get(key);\r\n\r\n if (value !== null) {\r\n return value;\r\n }\r\n\r\n const result = await callback();\r\n await this.set(key, result, ttl);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async pull(key: CacheKey): Promise<any | null> {\r\n const value = await this.get(key);\r\n\r\n if (value !== null) {\r\n await this.remove(key);\r\n }\r\n\r\n return value;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async forever(key: CacheKey, value: any): Promise<any> {\r\n return this.set(key, value, Infinity);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async increment(key: CacheKey, value: number = 1): Promise<number> {\r\n const current = (await this.get(key)) || 0;\r\n\r\n if (typeof current !== \"number\") {\r\n throw new Error(\r\n `Cannot increment non-numeric value for key: ${this.driver.parseKey(key)}`,\r\n );\r\n }\r\n\r\n const newValue = current + value;\r\n await this.set(key, newValue);\r\n\r\n return newValue;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async decrement(key: CacheKey, value: number = 1): Promise<number> {\r\n return this.increment(key, -value);\r\n }\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"tagged-cache.mjs","names":[],"sources":["../../../../../../@warlock.js/cache/src/tagged-cache.ts"],"sourcesContent":["import type {\r\n CacheDriver,\r\n CacheKey,\r\n CacheSetOptions,\r\n CacheTtl,\r\n TaggedCacheDriver,\r\n} from \"./types\";\r\n\r\n/**\r\n * Tagged Cache Wrapper\r\n * Wraps a cache driver to automatically manage tag relationships\r\n */\r\nexport class TaggedCache implements TaggedCacheDriver {\r\n /**\r\n * The tags associated with this tagged cache instance\r\n */\r\n protected cacheTags: string[];\r\n\r\n /**\r\n * The underlying cache driver\r\n */\r\n protected driver: CacheDriver<any, any>;\r\n\r\n /**\r\n * Constructor\r\n */\r\n public constructor(tags: string[], driver: CacheDriver<any, any>) {\r\n this.cacheTags = tags;\r\n this.driver = driver;\r\n }\r\n\r\n /**\r\n * Get the tag key prefix for storing tag-key relationships\r\n */\r\n protected tagKey(tag: string): string {\r\n return `cache:tags:${tag}`;\r\n }\r\n\r\n /**\r\n * Store tag-key relationship\r\n */\r\n protected async storeTaggedKey(key: string): Promise<void> {\r\n await this.storeTagRelationship(key);\r\n }\r\n\r\n /**\r\n * Public alias of the tag-index writer. Called by `BaseCacheDriver.applyTags`\r\n * when tags are passed inline through `CacheSetOptions.tags`.\r\n *\r\n * @internal — public for cross-class use within this package; not part of the\r\n * stable consumer API.\r\n */\r\n public async storeTagRelationship(parsedKey: string): Promise<void> {\r\n for (const tag of this.cacheTags) {\r\n const tagKey = this.tagKey(tag);\r\n const keys = (await this.driver.get(tagKey)) || [];\r\n\r\n if (!keys.includes(parsedKey)) {\r\n keys.push(parsedKey);\r\n await this.driver.set(tagKey, keys, Infinity);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get all keys associated with tags\r\n */\r\n protected async getTaggedKeys(): Promise<Set<string>> {\r\n const allKeys = new Set<string>();\r\n\r\n for (const tag of this.cacheTags) {\r\n const tagKey = this.tagKey(tag);\r\n const keys = (await this.driver.get(tagKey)) || [];\r\n\r\n for (const key of keys) {\r\n allKeys.add(key);\r\n }\r\n }\r\n\r\n return allKeys;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async set(\r\n key: CacheKey,\r\n value: any,\r\n ttlOrOptions?: CacheTtl | CacheSetOptions,\r\n ): Promise<any> {\r\n const parsedKey = this.driver.parseKey(key);\r\n\r\n await this.driver.set(key, value, ttlOrOptions);\r\n\r\n await this.storeTaggedKey(parsedKey);\r\n\r\n return value;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async get(key: CacheKey): Promise<any | null> {\r\n return this.driver.get(key);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async remove(key: CacheKey): Promise<void> {\r\n const parsedKey = this.driver.parseKey(key);\r\n\r\n // Remove the value\r\n await this.driver.remove(key);\r\n\r\n // Remove from all tag relationships\r\n for (const tag of this.cacheTags) {\r\n const tagKey = this.tagKey(tag);\r\n const keys = (await this.driver.get(tagKey)) || [];\r\n const updatedKeys = keys.filter((k: string) => k !== parsedKey);\r\n await this.driver.set(tagKey, updatedKeys, Infinity);\r\n }\r\n }\r\n\r\n /**\r\n * Invalidate (clear) all keys associated with the current tags\r\n */\r\n public async invalidate(): Promise<void> {\r\n const keysToRemove = await this.getTaggedKeys();\r\n\r\n // Remove all tagged keys\r\n for (const key of keysToRemove) {\r\n await this.driver.remove(key);\r\n }\r\n\r\n // Clear tag relationship keys\r\n for (const tag of this.cacheTags) {\r\n await this.driver.remove(this.tagKey(tag));\r\n }\r\n }\r\n\r\n /**\r\n * Flush all keys associated with the current tags\r\n * @deprecated Use invalidate() instead for better semantics\r\n */\r\n public async flush(): Promise<void> {\r\n return this.invalidate();\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async has(key: CacheKey): Promise<boolean> {\r\n return this.driver.has(key);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async remember(\r\n key: CacheKey,\r\n ttl: number,\r\n callback: () => Promise<any>,\r\n ): Promise<any> {\r\n const value = await this.get(key);\r\n\r\n if (value !== null) {\r\n return value;\r\n }\r\n\r\n const result = await callback();\r\n await this.set(key, result, ttl);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async pull(key: CacheKey): Promise<any | null> {\r\n const value = await this.get(key);\r\n\r\n if (value !== null) {\r\n await this.remove(key);\r\n }\r\n\r\n return value;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async forever(key: CacheKey, value: any): Promise<any> {\r\n return this.set(key, value, Infinity);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async increment(key: CacheKey, value: number = 1): Promise<number> {\r\n const current = (await this.get(key)) || 0;\r\n\r\n if (typeof current !== \"number\") {\r\n throw new Error(\r\n `Cannot increment non-numeric value for key: ${this.driver.parseKey(key)}`,\r\n );\r\n }\r\n\r\n const newValue = current + value;\r\n await this.set(key, newValue);\r\n\r\n return newValue;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async decrement(key: CacheKey, value: number = 1): Promise<number> {\r\n return this.increment(key, -value);\r\n }\r\n}\r\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { CacheKey, CacheSetOptions, CacheTtl, RememberOptions, TaggedScopedCacheContract } from "./types.mjs";
2
2
  import { ScopedCache } from "./scoped-cache.mjs";
3
3
 
4
- //#region ../../@warlock.js/cache/src/tagged-scoped-cache.d.ts
4
+ //#region ../@warlock.js/cache/src/tagged-scoped-cache.d.ts
5
5
  /**
6
6
  * One-shot tagged write handle on top of a {@link ScopedCache}.
7
7
  *
@@ -1 +1 @@
1
- {"version":3,"file":"tagged-scoped-cache.d.mts","names":[],"sources":["../../../../../@warlock.js/cache/src/tagged-scoped-cache.ts"],"mappings":";;;;;;AA4CA;;;;;;;;;;;;;;;;;;;;;;;;;;cAAa,iBAAA,YAA6B,yBAAA;EA+Gb;;;;;EAAA,mBAzGR,KAAA,EAAO,WAAA;EAwHuB;;;;EAAA,mBAlH9B,UAAA;EAZqB;;;;cAkBrB,KAAA,EAAO,WAAA,EAAa,UAAA;EAZb;;;;EAqBnB,GAAA,CACL,GAAA,EAAK,QAAA,EACL,KAAA,OACA,YAAA,GAAe,QAAA,GAAW,eAAA,GACzB,OAAA;EAboC;;;EAsBhC,GAAA,SAAA,CAAa,GAAA,EAAK,QAAA,GAAW,OAAA,CAAQ,CAAA;EAX1C;;;EAkBK,GAAA,CAAI,GAAA,EAAK,QAAA,GAAW,OAAA;EAhBxB;;;;EAwBI,MAAA,CAAO,GAAA,EAAK,QAAA,GAAW,OAAA;EAfM;;;EAsB7B,IAAA,SAAA,CAAc,GAAA,EAAK,QAAA,GAAW,OAAA,CAAQ,CAAA;EAflC;;;;EAuBJ,OAAA,SAAA,CAAiB,GAAA,EAAK,QAAA,EAAU,KAAA,EAAO,CAAA,GAAI,OAAA,CAAQ,CAAA;EAf5B;;;;;EA2BjB,KAAA,CAAM,GAAA,EAAK,QAAA,EAAU,KAAA,OAAY,GAAA,YAAe,OAAA;EApBhB;;;EA+CtC,QAAA,SAAA,CACL,GAAA,EAAK,QAAA,EACL,YAAA,EAAc,QAAA,GAAW,eAAA,EACzB,QAAA,QAAgB,OAAA,CAAQ,CAAA,IACvB,OAAA,CAAQ,CAAA;EA3Ca;;;;EAwDjB,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAiB,OAAA;EA5CpC;;;EAmDN,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAiB,OAAA;EAnDH;;;;;EA4DjC,UAAA,CAAA,GAAc,OAAA;EA/BX;;;;;EAAA,UA8CN,cAAA,CAAe,GAAA,EAAK,QAAA;AAAA"}
1
+ {"version":3,"file":"tagged-scoped-cache.d.mts","names":[],"sources":["../../../../../../@warlock.js/cache/src/tagged-scoped-cache.ts"],"mappings":";;;;;;AA4CA;;;;;;;;;;;;;;;;;;;;;;;;;;cAAa,iBAAA,YAA6B,yBAAA;EA+Gb;;;;;EAAA,mBAzGR,KAAA,EAAO,WAAA;EAwHuB;;;;EAAA,mBAlH9B,UAAA;EAZqB;;;;cAkBrB,KAAA,EAAO,WAAA,EAAa,UAAA;EAZb;;;;EAqBnB,GAAA,CACL,GAAA,EAAK,QAAA,EACL,KAAA,OACA,YAAA,GAAe,QAAA,GAAW,eAAA,GACzB,OAAA;EAboC;;;EAsBhC,GAAA,UAAa,GAAA,EAAK,QAAA,GAAW,OAAA,CAAQ,CAAA;EAX1C;;;EAkBK,GAAA,CAAI,GAAA,EAAK,QAAA,GAAW,OAAA;EAhBxB;;;;EAwBI,MAAA,CAAO,GAAA,EAAK,QAAA,GAAW,OAAA;EAfM;;;EAsB7B,IAAA,UAAc,GAAA,EAAK,QAAA,GAAW,OAAA,CAAQ,CAAA;EAflC;;;;EAuBJ,OAAA,UAAiB,GAAA,EAAK,QAAA,EAAU,KAAA,EAAO,CAAA,GAAI,OAAA,CAAQ,CAAA;EAf5B;;;;;EA2BjB,KAAA,CAAM,GAAA,EAAK,QAAA,EAAU,KAAA,OAAY,GAAA,YAAe,OAAA;EApBhB;;;EA+CtC,QAAA,UACL,GAAA,EAAK,QAAA,EACL,YAAA,EAAc,QAAA,GAAW,eAAA,EACzB,QAAA,QAAgB,OAAA,CAAQ,CAAA,IACvB,OAAA,CAAQ,CAAA;EA3Ca;;;;EAwDjB,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAiB,OAAA;EA5CpC;;;EAmDN,SAAA,CAAU,GAAA,EAAK,QAAA,EAAU,KAAA,YAAiB,OAAA;EAnDH;;;;;EA4DjC,UAAA,IAAc,OAAA;EA/BX;;;;;EAAA,UA8CN,cAAA,CAAe,GAAA,EAAK,QAAA;AAAA"}
@@ -1,6 +1,6 @@
1
1
  import { injectTags, mergeTagSets, normalizeToOptions, normalizeToRememberOptions, parseCacheKey } from "./utils.mjs";
2
2
 
3
- //#region ../../@warlock.js/cache/src/tagged-scoped-cache.ts
3
+ //#region ../@warlock.js/cache/src/tagged-scoped-cache.ts
4
4
  /**
5
5
  * One-shot tagged write handle on top of a {@link ScopedCache}.
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"tagged-scoped-cache.mjs","names":[],"sources":["../../../../../@warlock.js/cache/src/tagged-scoped-cache.ts"],"sourcesContent":["import type { ScopedCache } from \"./scoped-cache\";\nimport type {\n CacheKey,\n CacheSetOptions,\n CacheTtl,\n RememberOptions,\n TaggedScopedCacheContract,\n} from \"./types\";\nimport {\n injectTags,\n mergeTagSets,\n normalizeToOptions,\n normalizeToRememberOptions,\n parseCacheKey,\n} from \"./utils\";\n\n/**\n * One-shot tagged write handle on top of a {@link ScopedCache}.\n *\n * **Role.** Returned by `scope.tags([...])`. Adds a fixed list of tags to\n * every write produced through this handle, on top of any tags the parent\n * scope already contributes. Stateless except for the captured tag list.\n *\n * **Responsibility.**\n * - Owns: appending the handle's tags to writes, delegating tag-index\n * bookkeeping for `setNX` (which lacks an inline `tags` knob on the driver\n * contract), and computing the union for `invalidate()` calls.\n * - Does NOT own: storage, prefix-prepending (delegated to the scope),\n * default `ttl` (delegated to the scope), or any kind of long-lived state.\n *\n * Tags compose additively: scope tags + handle tags + per-call tags, all\n * unioned and deduped. The handle never replaces scope tags — `invalidate()`\n * always sees the full union.\n *\n * @example\n * // Inside application code — scope provides the per-user tag automatically:\n * const feed = cache.namespace(`feed.${userId}`, { tags: [`user.${userId}`] });\n *\n * await feed.tags([\"unread\"]).set(\"messages.1\", message);\n * // → tagged with [user.<id>, unread]\n *\n * await feed.tags([\"unread\"]).invalidate();\n * // → wipes everything tagged with user.<id> OR unread.\n */\nexport class TaggedScopedCache implements TaggedScopedCacheContract {\n /**\n * The {@link ScopedCache} this handle delegates to. Held by reference so\n * scope-default changes (none today, but the option is preserved for the\n * future) are visible without rebuilding the handle.\n */\n protected readonly scope: ScopedCache;\n\n /**\n * Tags this handle contributes to every write. Cloned at the call site so\n * later mutation of the input array doesn't leak in.\n */\n protected readonly handleTags: string[];\n\n /**\n * Build a tagged handle. Constructed via `scope.tags([...])` — users never\n * call this directly.\n */\n public constructor(scope: ScopedCache, handleTags: string[]) {\n this.scope = scope;\n this.handleTags = [...handleTags];\n }\n\n /**\n * Write the scoped key with the handle's tags appended to whatever the\n * caller passed. Scope-level tags are added on top by the scope itself.\n */\n public set(\n key: CacheKey,\n value: any,\n ttlOrOptions?: CacheTtl | CacheSetOptions,\n ): Promise<any> {\n const options = injectTags(normalizeToOptions(ttlOrOptions), this.handleTags);\n\n return this.scope.set(key, value, options);\n }\n\n /**\n * Read the scoped key. Tags don't affect reads — pass-through.\n */\n public get<T = any>(key: CacheKey): Promise<T | null> {\n return this.scope.get<T>(key);\n }\n\n /**\n * Check presence of the scoped key.\n */\n public has(key: CacheKey): Promise<boolean> {\n return this.scope.has(key);\n }\n\n /**\n * Remove the scoped key. The tag-index entry will eventually be cleaned up\n * by `invalidate()`; we don't proactively rewrite it here for cost reasons.\n */\n public remove(key: CacheKey): Promise<void> {\n return this.scope.remove(key);\n }\n\n /**\n * Read-and-remove the scoped key.\n */\n public pull<T = any>(key: CacheKey): Promise<T | null> {\n return this.scope.pull<T>(key);\n }\n\n /**\n * Permanent write with handle tags applied. Bypasses both the scope's and\n * the caller's TTL (forever means forever) — only tags get injected.\n */\n public forever<T = any>(key: CacheKey, value: T): Promise<T> {\n return this.scope.set(key, value, {\n ttl: Infinity,\n tags: this.handleTags,\n }) as Promise<T>;\n }\n\n /**\n * Atomic create-or-skip with the handle's tags applied on success. The\n * driver contract has no inline `tags` knob on `setNX`, so we register the\n * tag relationship manually after a successful write.\n */\n public async setNX(key: CacheKey, value: any, ttl?: number): Promise<boolean> {\n const wasSet = await this.scope.setNX(key, value, ttl);\n\n if (!wasSet) {\n return false;\n }\n\n const allTags = mergeTagSets(this.scope.defaults.tags, this.handleTags);\n\n if (!allTags || allTags.length === 0) {\n return true;\n }\n\n const scopedKey = this.buildScopedKey(key);\n const parsedKey = this.scope.source.parseKey(scopedKey);\n const tagged = this.scope.source.tags(allTags) as unknown as {\n storeTagRelationship: (parsed: string) => Promise<void>;\n };\n\n await tagged.storeTagRelationship(parsedKey);\n\n return true;\n }\n\n /**\n * Read-or-compute with handle tags appended on the cache-miss write.\n */\n public remember<T = any>(\n key: CacheKey,\n ttlOrOptions: CacheTtl | RememberOptions,\n callback: () => Promise<T>,\n ): Promise<T> {\n const options = injectTags(\n normalizeToRememberOptions(ttlOrOptions),\n this.handleTags,\n );\n\n return this.scope.remember<T>(key, options, callback);\n }\n\n /**\n * Atomic counter increment on the scoped key. Tags aren't applied to\n * subsequent increments — they're attached at first-write time.\n */\n public increment(key: CacheKey, value?: number): Promise<number> {\n return this.scope.increment(key, value);\n }\n\n /**\n * Atomic counter decrement on the scoped key. See {@link increment}.\n */\n public decrement(key: CacheKey, value?: number): Promise<number> {\n return this.scope.decrement(key, value);\n }\n\n /**\n * Wipe every entry tagged with the union of (scope tags + handle tags).\n * Tags are global across the package, so this reaches outside the scope's\n * prefix when scope tags are also used elsewhere.\n */\n public async invalidate(): Promise<void> {\n const allTags = mergeTagSets(this.scope.defaults.tags, this.handleTags);\n\n if (!allTags || allTags.length === 0) {\n return;\n }\n\n await this.scope.source.tags(allTags).invalidate();\n }\n\n /**\n * Compute the source-side key the same way `ScopedCache.scopedKey` does —\n * needed for `setNX`, where we have to register the tag relationship by\n * hand because the driver contract doesn't accept inline tags there.\n */\n protected buildScopedKey(key: CacheKey): string {\n const keyString = typeof key === \"string\" ? key : parseCacheKey(key);\n\n if (!keyString) {\n return this.scope.prefix;\n }\n\n return `${this.scope.prefix}.${keyString}`;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,IAAa,oBAAb,MAAoE;;;;;CAkBlE,AAAO,YAAY,OAAoB,YAAsB;EAC3D,KAAK,QAAQ;EACb,KAAK,aAAa,CAAC,GAAG,UAAU;CAClC;;;;;CAMA,AAAO,IACL,KACA,OACA,cACc;EACd,MAAM,UAAU,WAAW,mBAAmB,YAAY,GAAG,KAAK,UAAU;EAE5E,OAAO,KAAK,MAAM,IAAI,KAAK,OAAO,OAAO;CAC3C;;;;CAKA,AAAO,IAAa,KAAkC;EACpD,OAAO,KAAK,MAAM,IAAO,GAAG;CAC9B;;;;CAKA,AAAO,IAAI,KAAiC;EAC1C,OAAO,KAAK,MAAM,IAAI,GAAG;CAC3B;;;;;CAMA,AAAO,OAAO,KAA8B;EAC1C,OAAO,KAAK,MAAM,OAAO,GAAG;CAC9B;;;;CAKA,AAAO,KAAc,KAAkC;EACrD,OAAO,KAAK,MAAM,KAAQ,GAAG;CAC/B;;;;;CAMA,AAAO,QAAiB,KAAe,OAAsB;EAC3D,OAAO,KAAK,MAAM,IAAI,KAAK,OAAO;GAChC,KAAK;GACL,MAAM,KAAK;EACb,CAAC;CACH;;;;;;CAOA,MAAa,MAAM,KAAe,OAAY,KAAgC;EAG5E,IAAI,CAAC,MAFgB,KAAK,MAAM,MAAM,KAAK,OAAO,GAAG,GAGnD,OAAO;EAGT,MAAM,UAAU,aAAa,KAAK,MAAM,SAAS,MAAM,KAAK,UAAU;EAEtE,IAAI,CAAC,WAAW,QAAQ,WAAW,GACjC,OAAO;EAGT,MAAM,YAAY,KAAK,eAAe,GAAG;EACzC,MAAM,YAAY,KAAK,MAAM,OAAO,SAAS,SAAS;EAKtD,MAJe,KAAK,MAAM,OAAO,KAAK,OAI3B,EAAE,qBAAqB,SAAS;EAE3C,OAAO;CACT;;;;CAKA,AAAO,SACL,KACA,cACA,UACY;EACZ,MAAM,UAAU,WACd,2BAA2B,YAAY,GACvC,KAAK,UACP;EAEA,OAAO,KAAK,MAAM,SAAY,KAAK,SAAS,QAAQ;CACtD;;;;;CAMA,AAAO,UAAU,KAAe,OAAiC;EAC/D,OAAO,KAAK,MAAM,UAAU,KAAK,KAAK;CACxC;;;;CAKA,AAAO,UAAU,KAAe,OAAiC;EAC/D,OAAO,KAAK,MAAM,UAAU,KAAK,KAAK;CACxC;;;;;;CAOA,MAAa,aAA4B;EACvC,MAAM,UAAU,aAAa,KAAK,MAAM,SAAS,MAAM,KAAK,UAAU;EAEtE,IAAI,CAAC,WAAW,QAAQ,WAAW,GACjC;EAGF,MAAM,KAAK,MAAM,OAAO,KAAK,OAAO,EAAE,WAAW;CACnD;;;;;;CAOA,AAAU,eAAe,KAAuB;EAC9C,MAAM,YAAY,OAAO,QAAQ,WAAW,MAAM,cAAc,GAAG;EAEnE,IAAI,CAAC,WACH,OAAO,KAAK,MAAM;EAGpB,OAAO,GAAG,KAAK,MAAM,OAAO,GAAG;CACjC;AACF"}
1
+ {"version":3,"file":"tagged-scoped-cache.mjs","names":[],"sources":["../../../../../../@warlock.js/cache/src/tagged-scoped-cache.ts"],"sourcesContent":["import type { ScopedCache } from \"./scoped-cache\";\nimport type {\n CacheKey,\n CacheSetOptions,\n CacheTtl,\n RememberOptions,\n TaggedScopedCacheContract,\n} from \"./types\";\nimport {\n injectTags,\n mergeTagSets,\n normalizeToOptions,\n normalizeToRememberOptions,\n parseCacheKey,\n} from \"./utils\";\n\n/**\n * One-shot tagged write handle on top of a {@link ScopedCache}.\n *\n * **Role.** Returned by `scope.tags([...])`. Adds a fixed list of tags to\n * every write produced through this handle, on top of any tags the parent\n * scope already contributes. Stateless except for the captured tag list.\n *\n * **Responsibility.**\n * - Owns: appending the handle's tags to writes, delegating tag-index\n * bookkeeping for `setNX` (which lacks an inline `tags` knob on the driver\n * contract), and computing the union for `invalidate()` calls.\n * - Does NOT own: storage, prefix-prepending (delegated to the scope),\n * default `ttl` (delegated to the scope), or any kind of long-lived state.\n *\n * Tags compose additively: scope tags + handle tags + per-call tags, all\n * unioned and deduped. The handle never replaces scope tags — `invalidate()`\n * always sees the full union.\n *\n * @example\n * // Inside application code — scope provides the per-user tag automatically:\n * const feed = cache.namespace(`feed.${userId}`, { tags: [`user.${userId}`] });\n *\n * await feed.tags([\"unread\"]).set(\"messages.1\", message);\n * // → tagged with [user.<id>, unread]\n *\n * await feed.tags([\"unread\"]).invalidate();\n * // → wipes everything tagged with user.<id> OR unread.\n */\nexport class TaggedScopedCache implements TaggedScopedCacheContract {\n /**\n * The {@link ScopedCache} this handle delegates to. Held by reference so\n * scope-default changes (none today, but the option is preserved for the\n * future) are visible without rebuilding the handle.\n */\n protected readonly scope: ScopedCache;\n\n /**\n * Tags this handle contributes to every write. Cloned at the call site so\n * later mutation of the input array doesn't leak in.\n */\n protected readonly handleTags: string[];\n\n /**\n * Build a tagged handle. Constructed via `scope.tags([...])` — users never\n * call this directly.\n */\n public constructor(scope: ScopedCache, handleTags: string[]) {\n this.scope = scope;\n this.handleTags = [...handleTags];\n }\n\n /**\n * Write the scoped key with the handle's tags appended to whatever the\n * caller passed. Scope-level tags are added on top by the scope itself.\n */\n public set(\n key: CacheKey,\n value: any,\n ttlOrOptions?: CacheTtl | CacheSetOptions,\n ): Promise<any> {\n const options = injectTags(normalizeToOptions(ttlOrOptions), this.handleTags);\n\n return this.scope.set(key, value, options);\n }\n\n /**\n * Read the scoped key. Tags don't affect reads — pass-through.\n */\n public get<T = any>(key: CacheKey): Promise<T | null> {\n return this.scope.get<T>(key);\n }\n\n /**\n * Check presence of the scoped key.\n */\n public has(key: CacheKey): Promise<boolean> {\n return this.scope.has(key);\n }\n\n /**\n * Remove the scoped key. The tag-index entry will eventually be cleaned up\n * by `invalidate()`; we don't proactively rewrite it here for cost reasons.\n */\n public remove(key: CacheKey): Promise<void> {\n return this.scope.remove(key);\n }\n\n /**\n * Read-and-remove the scoped key.\n */\n public pull<T = any>(key: CacheKey): Promise<T | null> {\n return this.scope.pull<T>(key);\n }\n\n /**\n * Permanent write with handle tags applied. Bypasses both the scope's and\n * the caller's TTL (forever means forever) — only tags get injected.\n */\n public forever<T = any>(key: CacheKey, value: T): Promise<T> {\n return this.scope.set(key, value, {\n ttl: Infinity,\n tags: this.handleTags,\n }) as Promise<T>;\n }\n\n /**\n * Atomic create-or-skip with the handle's tags applied on success. The\n * driver contract has no inline `tags` knob on `setNX`, so we register the\n * tag relationship manually after a successful write.\n */\n public async setNX(key: CacheKey, value: any, ttl?: number): Promise<boolean> {\n const wasSet = await this.scope.setNX(key, value, ttl);\n\n if (!wasSet) {\n return false;\n }\n\n const allTags = mergeTagSets(this.scope.defaults.tags, this.handleTags);\n\n if (!allTags || allTags.length === 0) {\n return true;\n }\n\n const scopedKey = this.buildScopedKey(key);\n const parsedKey = this.scope.source.parseKey(scopedKey);\n const tagged = this.scope.source.tags(allTags) as unknown as {\n storeTagRelationship: (parsed: string) => Promise<void>;\n };\n\n await tagged.storeTagRelationship(parsedKey);\n\n return true;\n }\n\n /**\n * Read-or-compute with handle tags appended on the cache-miss write.\n */\n public remember<T = any>(\n key: CacheKey,\n ttlOrOptions: CacheTtl | RememberOptions,\n callback: () => Promise<T>,\n ): Promise<T> {\n const options = injectTags(\n normalizeToRememberOptions(ttlOrOptions),\n this.handleTags,\n );\n\n return this.scope.remember<T>(key, options, callback);\n }\n\n /**\n * Atomic counter increment on the scoped key. Tags aren't applied to\n * subsequent increments — they're attached at first-write time.\n */\n public increment(key: CacheKey, value?: number): Promise<number> {\n return this.scope.increment(key, value);\n }\n\n /**\n * Atomic counter decrement on the scoped key. See {@link increment}.\n */\n public decrement(key: CacheKey, value?: number): Promise<number> {\n return this.scope.decrement(key, value);\n }\n\n /**\n * Wipe every entry tagged with the union of (scope tags + handle tags).\n * Tags are global across the package, so this reaches outside the scope's\n * prefix when scope tags are also used elsewhere.\n */\n public async invalidate(): Promise<void> {\n const allTags = mergeTagSets(this.scope.defaults.tags, this.handleTags);\n\n if (!allTags || allTags.length === 0) {\n return;\n }\n\n await this.scope.source.tags(allTags).invalidate();\n }\n\n /**\n * Compute the source-side key the same way `ScopedCache.scopedKey` does —\n * needed for `setNX`, where we have to register the tag relationship by\n * hand because the driver contract doesn't accept inline tags there.\n */\n protected buildScopedKey(key: CacheKey): string {\n const keyString = typeof key === \"string\" ? key : parseCacheKey(key);\n\n if (!keyString) {\n return this.scope.prefix;\n }\n\n return `${this.scope.prefix}.${keyString}`;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,IAAa,oBAAb,MAAoE;;;;;CAkBlE,AAAO,YAAY,OAAoB,YAAsB;EAC3D,KAAK,QAAQ;EACb,KAAK,aAAa,CAAC,GAAG,UAAU;CAClC;;;;;CAMA,AAAO,IACL,KACA,OACA,cACc;EACd,MAAM,UAAU,WAAW,mBAAmB,YAAY,GAAG,KAAK,UAAU;EAE5E,OAAO,KAAK,MAAM,IAAI,KAAK,OAAO,OAAO;CAC3C;;;;CAKA,AAAO,IAAa,KAAkC;EACpD,OAAO,KAAK,MAAM,IAAO,GAAG;CAC9B;;;;CAKA,AAAO,IAAI,KAAiC;EAC1C,OAAO,KAAK,MAAM,IAAI,GAAG;CAC3B;;;;;CAMA,AAAO,OAAO,KAA8B;EAC1C,OAAO,KAAK,MAAM,OAAO,GAAG;CAC9B;;;;CAKA,AAAO,KAAc,KAAkC;EACrD,OAAO,KAAK,MAAM,KAAQ,GAAG;CAC/B;;;;;CAMA,AAAO,QAAiB,KAAe,OAAsB;EAC3D,OAAO,KAAK,MAAM,IAAI,KAAK,OAAO;GAChC,KAAK;GACL,MAAM,KAAK;EACb,CAAC;CACH;;;;;;CAOA,MAAa,MAAM,KAAe,OAAY,KAAgC;EAG5E,IAAI,CAAC,MAFgB,KAAK,MAAM,MAAM,KAAK,OAAO,GAAG,GAGnD,OAAO;EAGT,MAAM,UAAU,aAAa,KAAK,MAAM,SAAS,MAAM,KAAK,UAAU;EAEtE,IAAI,CAAC,WAAW,QAAQ,WAAW,GACjC,OAAO;EAGT,MAAM,YAAY,KAAK,eAAe,GAAG;EACzC,MAAM,YAAY,KAAK,MAAM,OAAO,SAAS,SAAS;EAKtD,MAJe,KAAK,MAAM,OAAO,KAAK,OAI3B,CAAC,CAAC,qBAAqB,SAAS;EAE3C,OAAO;CACT;;;;CAKA,AAAO,SACL,KACA,cACA,UACY;EACZ,MAAM,UAAU,WACd,2BAA2B,YAAY,GACvC,KAAK,UACP;EAEA,OAAO,KAAK,MAAM,SAAY,KAAK,SAAS,QAAQ;CACtD;;;;;CAMA,AAAO,UAAU,KAAe,OAAiC;EAC/D,OAAO,KAAK,MAAM,UAAU,KAAK,KAAK;CACxC;;;;CAKA,AAAO,UAAU,KAAe,OAAiC;EAC/D,OAAO,KAAK,MAAM,UAAU,KAAK,KAAK;CACxC;;;;;;CAOA,MAAa,aAA4B;EACvC,MAAM,UAAU,aAAa,KAAK,MAAM,SAAS,MAAM,KAAK,UAAU;EAEtE,IAAI,CAAC,WAAW,QAAQ,WAAW,GACjC;EAGF,MAAM,KAAK,MAAM,OAAO,KAAK,OAAO,CAAC,CAAC,WAAW;CACnD;;;;;;CAOA,AAAU,eAAe,KAAuB;EAC9C,MAAM,YAAY,OAAO,QAAQ,WAAW,MAAM,cAAc,GAAG;EAEnE,IAAI,CAAC,WACH,OAAO,KAAK,MAAM;EAGpB,OAAO,GAAG,KAAK,MAAM,OAAO,GAAG;CACjC;AACF"}
package/esm/types.d.mts CHANGED
@@ -10,7 +10,7 @@ import { RedisCacheDriver } from "./drivers/redis-cache-driver.mjs";
10
10
  import { GenericObject } from "@mongez/reinforcements";
11
11
  import { RedisClientOptions } from "redis";
12
12
 
13
- //#region ../../@warlock.js/cache/src/types.d.ts
13
+ //#region ../@warlock.js/cache/src/types.d.ts
14
14
  /**
15
15
  * Base error class for cache-related errors
16
16
  */
@@ -320,7 +320,7 @@ type CacheSimilarHit<T = unknown> = {
320
320
  * Cache key type - can be a string or an object
321
321
  */
322
322
  type CacheKey = string | GenericObject;
323
- type CacheOperationType = "fetching" | "fetched" | "caching" | "cached" | "flushing" | "flushed" | "removing" | "removed" | "clearing" | "cleared" | "expired" | "notFound" | "connecting" | "error" | "connected" | "disconnecting" | "disconnected";
323
+ type CacheOperationType = "fetching" | "fetched" | "caching" | "cached" | "flushing" | "flushed" | "removing" | "removed" | "clearing" | "cleared" | "expired" | "notFound" | "connecting" | "error" | "connectionFailed" | "connected" | "disconnecting" | "disconnected";
324
324
  /**
325
325
  * Cache event types for observability
326
326
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../../../../../@warlock.js/cache/src/types.ts"],"mappings":"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"}
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../../../../../@warlock.js/cache/src/types.ts"],"mappings":"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"}
package/esm/types.mjs CHANGED
@@ -1,4 +1,4 @@
1
- //#region ../../@warlock.js/cache/src/types.ts
1
+ //#region ../@warlock.js/cache/src/types.ts
2
2
  /**
3
3
  * Base error class for cache-related errors
4
4
  */
package/esm/types.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.mjs","names":[],"sources":["../../../../../@warlock.js/cache/src/types.ts"],"sourcesContent":["import type { GenericObject } from \"@mongez/reinforcements\";\r\nimport type { RedisClientOptions } from \"redis\";\r\nimport type {\r\n BaseCacheDriver,\r\n FileCacheDriver,\r\n LRUMemoryCacheDriver,\r\n MemoryCacheDriver,\r\n MockCacheDriver,\r\n MemoryExtendedCacheDriver,\r\n NullCacheDriver,\r\n PgCacheDriver,\r\n RedisCacheDriver,\r\n} from \"./drivers\";\r\n\r\n/**\r\n * Base error class for cache-related errors\r\n */\r\nexport class CacheError extends Error {\r\n public constructor(message: string) {\r\n super(message);\r\n this.name = \"CacheError\";\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when cache connection fails\r\n */\r\nexport class CacheConnectionError extends CacheError {\r\n public constructor(message: string) {\r\n super(message);\r\n this.name = \"CacheConnectionError\";\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when cache driver configuration is invalid\r\n */\r\nexport class CacheConfigurationError extends CacheError {\r\n public constructor(message: string) {\r\n super(message);\r\n this.name = \"CacheConfigurationError\";\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when cache driver is not initialized\r\n */\r\nexport class CacheDriverNotInitializedError extends CacheError {\r\n public constructor(\r\n message: string = \"No cache driver initialized. Call cache.init() or cache.use() first.\",\r\n ) {\r\n super(message);\r\n this.name = \"CacheDriverNotInitializedError\";\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when a driver does not implement a requested operation.\r\n *\r\n * Raised when a caller invokes a method the driver cannot fulfill —\r\n * e.g. `update()` on the file driver before the file-lock primitive lands.\r\n */\r\nexport class CacheUnsupportedError extends CacheError {\r\n public constructor(message: string) {\r\n super(message);\r\n this.name = \"CacheUnsupportedError\";\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when an optimistic-concurrency update exhausts its retry budget.\r\n */\r\nexport class CacheConcurrencyError extends CacheError {\r\n public constructor(message: string) {\r\n super(message);\r\n this.name = \"CacheConcurrencyError\";\r\n }\r\n}\r\n\r\n/**\r\n * TTL shape accepted by set/remember/config calls.\r\n *\r\n * - `number` — seconds\r\n * - `string` — human-readable duration parsed via `ms` (`\"1h\"`, `\"30m\"`, `\"7d\"`, `\"2 weeks\"`, …)\r\n * - `Infinity` — no expiration\r\n */\r\nexport type CacheTtl = number | string;\r\n\r\n/**\r\n * Conflict resolution policy for `set` operations.\r\n *\r\n * - `\"create\"` — set only if the key does not exist (Redis `NX`)\r\n * - `\"update\"` — set only if the key already exists (Redis `XX`)\r\n * - `\"upsert\"` — default; overwrite whether the key exists or not\r\n */\r\nexport type CacheConflictPolicy = \"create\" | \"update\" | \"upsert\";\r\n\r\n/**\r\n * Result of a conditional write (`onConflict: \"create\" | \"update\"`).\r\n */\r\nexport type CacheSetResult<T = any> = {\r\n /**\r\n * Whether the write actually took effect.\r\n */\r\n wasSet: boolean;\r\n /**\r\n * The existing value when the write was rejected. Undefined for successful writes\r\n * and for unconditional `upsert` writes.\r\n */\r\n existing: T | null;\r\n};\r\n\r\n/**\r\n * Options for `lock()` — TTL is required (forgotten locks would stay forever),\r\n * `owner` identifies who holds the lock (handy for debugging), `driver` routes\r\n * the call through a non-default driver.\r\n *\r\n * @example\r\n * await cache.lock(\"lock.import\", { ttl: \"5m\", driver: \"redis\" }, async () => {\r\n * await runImport();\r\n * });\r\n */\r\nexport type LockOptions = {\r\n /**\r\n * How long the lock lives before auto-release. Required — guards against\r\n * forgotten locks if the process crashes between acquire and release.\r\n */\r\n ttl: CacheTtl;\r\n /**\r\n * Identifying value stored under the lock key. Defaults to `pid.<process.pid>`.\r\n * Use a custom owner when you want a human-readable label (e.g. `\"worker.jobs-2\"`).\r\n */\r\n owner?: string;\r\n /**\r\n * Per-call driver override by registered name. Manager-level only.\r\n */\r\n driver?: string;\r\n};\r\n\r\n/**\r\n * Discriminated-union result of `lock()`. Unambiguous even when the wrapped\r\n * function legitimately returns `undefined` — the `acquired` flag tells you\r\n * whether `fn` ran at all.\r\n *\r\n * @example\r\n * const outcome = await cache.lock(\"lock.x\", \"1m\", async () => computeValue());\r\n * if (outcome.acquired) {\r\n * console.log(\"ran, got\", outcome.value);\r\n * } else {\r\n * console.log(\"skipped — someone else holds the lock\");\r\n * }\r\n */\r\nexport type LockOutcome<T> =\r\n | { acquired: true; value: T }\r\n | { acquired: false };\r\n\r\n/**\r\n * Options for `remember()` when you need more than just a TTL — e.g. attaching\r\n * tags to the cache-miss write, or routing the single call to a non-default driver.\r\n *\r\n * Passed in the TTL position: `cache.remember(key, { ttl: \"1h\", tags: [\"users\"] }, fn)`.\r\n *\r\n * @example\r\n * await cache.remember(\"user.1\", { ttl: \"1h\", tags: [\"users\"] }, () =>\r\n * db.users.find(1),\r\n * );\r\n */\r\nexport type RememberOptions = {\r\n /**\r\n * TTL applied on cache miss. Accepts seconds (number) or duration string.\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Tags attached to the entry created on miss. Invalidate via `cache.tags([...]).invalidate()`.\r\n */\r\n tags?: string[];\r\n /**\r\n * Per-call driver override. Routes this remember call (both read and write)\r\n * to the named driver without mutating `currentDriver`.\r\n */\r\n driver?: string;\r\n};\r\n\r\n/**\r\n * Rich options for the `set` call-site. Mutually exclusive with a positional TTL.\r\n *\r\n * @example\r\n * await cache.set(\"user:1\", user, {\r\n * ttl: \"1h\",\r\n * tags: [\"users\", \"active\"],\r\n * onConflict: \"create\",\r\n * });\r\n */\r\nexport type CacheSetOptions = {\r\n /**\r\n * Relative TTL (seconds or duration string). Mutually exclusive with `expiresAt`.\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Absolute expiration as a Unix epoch in milliseconds or a Date. Mutually exclusive with `ttl`.\r\n */\r\n expiresAt?: number | Date;\r\n /**\r\n * Tags attached to this entry for tag-based invalidation. Inline equivalent of\r\n * `cache.tags([...]).set(key, value)`.\r\n */\r\n tags?: string[];\r\n /**\r\n * Conflict resolution policy. Defaults to `\"upsert\"`.\r\n */\r\n onConflict?: CacheConflictPolicy;\r\n /**\r\n * Per-call namespace override. Applied ahead of `globalPrefix` for this write only.\r\n */\r\n namespace?: string;\r\n /**\r\n * Per-call driver override by registered name. Routes this write to a non-default driver\r\n * without mutating `currentDriver`.\r\n */\r\n driver?: string;\r\n /**\r\n * Optional embedding vector indexed alongside the entry for similarity retrieval\r\n * via `cache.similar(...)`. Drivers without similarity support throw\r\n * {@link CacheUnsupportedError} when this option is supplied.\r\n *\r\n * Cache is embedding-agnostic — callers compute the vector with whichever embedder\r\n * they like and pass the result here.\r\n *\r\n * @example\r\n * await cache.set(\"doc.123\", doc, { vector: await embed(doc.text), ttl: \"1d\" });\r\n */\r\n vector?: number[];\r\n /**\r\n * Freshness deadline as a Unix epoch in milliseconds. Primarily set by\r\n * {@link CacheSwrOptions} flow — entries with `staleAt` in the future are\r\n * considered \"fresh\" by `cache.swr()`; entries past `staleAt` but before\r\n * `expiresAt` are \"stale-but-revalidatable.\"\r\n *\r\n * Direct callers can pin this manually when bypassing `swr()`, but the\r\n * common path is `cache.swr(key, { freshTtl, staleTtl }, fn)`.\r\n */\r\n staleAt?: number;\r\n};\r\n\r\n/**\r\n * Options for `cache.namespace(prefix, options)` — defaults applied to every\r\n * write produced through the returned scope.\r\n *\r\n * Per-call options always win over scope defaults. Tags merge additively\r\n * (scope tags + call tags, deduped). Nested scopes inherit from the parent;\r\n * the child's own values override.\r\n */\r\nexport type CacheNamespaceOptions = {\r\n /**\r\n * Default TTL for writes inside this scope. Same shape as everywhere else\r\n * — number of seconds or a duration string (`\"1h\"`, `\"30d\"`, …).\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Tags auto-attached to every write inside this scope. Useful for cross-scope\r\n * invalidation hooks (e.g. tag every entry with `user.<id>` so a single\r\n * `cache.flushTag(\"user.42\")` wipes the user's footprint everywhere).\r\n *\r\n * Merged additively with per-call tags; scope tags are never replaced.\r\n */\r\n tags?: string[];\r\n};\r\n\r\n/**\r\n * Options for `cache.swr(key, options, callback)` — stale-while-revalidate.\r\n *\r\n * Two TTLs split the entry's lifecycle into three windows:\r\n * - `now < freshTtl` → fresh, return cached value, no upstream call.\r\n * - `freshTtl <= now < staleTtl` → stale-but-revalidatable, return cached\r\n * value immediately, kick off `callback` in the background to refresh.\r\n * - `now >= staleTtl` → expired, block on `callback` like a normal miss.\r\n *\r\n * Concurrent SWR callers in the stale window all return the cached value;\r\n * the background refresh runs exactly once per key (deduped via the\r\n * driver's per-key lock map).\r\n *\r\n * If the background refresh fails, the stale entry is preserved and the\r\n * error is logged + emitted on the `error` event. Callers that received\r\n * the stale value never see the failure — they got their data.\r\n */\r\nexport type CacheSwrOptions = {\r\n /**\r\n * How long the value is considered fresh. Within this window, SWR returns\r\n * the cached value with no upstream call. Accepts seconds or duration\r\n * string (`\"1m\"`, `\"30s\"`).\r\n */\r\n freshTtl: CacheTtl;\r\n /**\r\n * Total lifetime of the entry (must be greater than `freshTtl`). Between\r\n * `freshTtl` and `staleTtl`, SWR returns the stale value and triggers a\r\n * background refresh. Past `staleTtl`, SWR blocks and refetches.\r\n */\r\n staleTtl: CacheTtl;\r\n /**\r\n * Optional tags applied on the first miss-fetch and on every successful\r\n * background refresh. Same semantics as `CacheSetOptions.tags`.\r\n */\r\n tags?: string[];\r\n /**\r\n * Per-call driver override by registered name. Routes both the read and\r\n * any write/refresh through the named driver without mutating\r\n * `currentDriver`. Same semantics as `RememberOptions.driver`.\r\n */\r\n driver?: string;\r\n};\r\n\r\n/**\r\n * Options for `cache.similar(vector, options)` — similarity retrieval against\r\n * stored entries previously written with `set({ vector })`.\r\n */\r\nexport type CacheSimilarOptions = {\r\n /**\r\n * Maximum number of hits to return. Required — no implicit default keeps\r\n * callers from accidentally pulling the entire candidate set.\r\n */\r\n topK: number;\r\n /**\r\n * Cosine similarity floor in `[0, 1]`. Hits scoring strictly below this are\r\n * filtered out before `topK` truncation.\r\n */\r\n threshold?: number;\r\n /**\r\n * Optional tag filter. Only entries tagged with at least one of the given\r\n * tags are considered (matches the union semantics elsewhere in the package).\r\n */\r\n tags?: string[];\r\n};\r\n\r\n/**\r\n * One result from a `similar()` query — the original key, its stored value,\r\n * and the cosine similarity to the query vector.\r\n */\r\nexport type CacheSimilarHit<T = unknown> = {\r\n /**\r\n * The original cache key, post-`parseKey` normalization.\r\n */\r\n key: string;\r\n /**\r\n * Stored value, deep-cloned to protect the cache from accidental mutation\r\n * (same semantics as `get`).\r\n */\r\n value: T;\r\n /**\r\n * Cosine similarity in `[0, 1]`. Higher means more similar.\r\n */\r\n score: number;\r\n};\r\n\r\n/**\r\n * Cache key type - can be a string or an object\r\n */\r\nexport type CacheKey = string | GenericObject;\r\n\r\nexport type CacheOperationType =\r\n | \"fetching\"\r\n | \"fetched\"\r\n | \"caching\"\r\n | \"cached\"\r\n | \"flushing\"\r\n | \"flushed\"\r\n | \"removing\"\r\n | \"removed\"\r\n | \"clearing\"\r\n | \"cleared\"\r\n | \"expired\"\r\n | \"notFound\"\r\n | \"connecting\"\r\n | \"error\"\r\n | \"connected\"\r\n | \"disconnecting\"\r\n | \"disconnected\";\r\n\r\n/**\r\n * Cache event types for observability\r\n */\r\nexport type CacheEventType =\r\n | \"hit\"\r\n | \"miss\"\r\n | \"set\"\r\n | \"removed\"\r\n | \"flushed\"\r\n | \"expired\"\r\n | \"connected\"\r\n | \"disconnected\"\r\n | \"error\";\r\n\r\n/**\r\n * Cache event data structure\r\n */\r\nexport type CacheEventData = {\r\n /**\r\n * The cache key involved in the event\r\n */\r\n key?: string;\r\n /**\r\n * The value (for set/hit events)\r\n */\r\n value?: any;\r\n /**\r\n * TTL in seconds (for set events)\r\n */\r\n ttl?: number;\r\n /**\r\n * Driver name that emitted the event\r\n */\r\n driver: string;\r\n /**\r\n * Error object (for error events)\r\n */\r\n error?: any;\r\n /**\r\n * Namespace (for namespace operations)\r\n */\r\n namespace?: string;\r\n};\r\n\r\n/**\r\n * Event handler function type\r\n */\r\nexport type CacheEventHandler = (eventData: CacheEventData) => void | Promise<void>;\r\n\r\n/**\r\n * Per-operation latency + counter snapshot returned by `cache.metrics()`.\r\n *\r\n * The shape is a single recursive level — the top object covers all drivers\r\n * and each entry under `byDriver` repeats the same fields without nesting\r\n * further. Use this for ad-hoc dashboards, exporters to Prometheus / StatsD,\r\n * or just `console.log` during development.\r\n */\r\nexport type CacheMetricsSnapshot = {\r\n /** Cumulative cache hits across the lifetime of the collector. */\r\n hits: number;\r\n /** Cumulative cache misses (lookups that returned null). */\r\n misses: number;\r\n /** Cumulative successful writes. */\r\n sets: number;\r\n /** Cumulative key removals. */\r\n removed: number;\r\n /** Cumulative cache errors emitted via the `error` event. */\r\n errors: number;\r\n /** `hits / (hits + misses)` — `0` when no read ops have happened yet. */\r\n hitRate: number;\r\n /** Latency percentiles in milliseconds, computed from a circular buffer. */\r\n latencyMs: {\r\n p50: number;\r\n p95: number;\r\n p99: number;\r\n /** Size of the underlying buffer at snapshot time (capped at the configured max). */\r\n samples: number;\r\n };\r\n /** Per-driver breakdowns keyed by driver name (`\"memory\"`, `\"redis\"`, …). */\r\n byDriver: Record<string, Omit<CacheMetricsSnapshot, \"byDriver\">>;\r\n /** Millisecond timestamp the collector last reset (or was instantiated). */\r\n startedAt: number;\r\n};\r\n\r\n/**\r\n * Tagged cache interface for working with cache tags\r\n */\r\nexport interface TaggedCacheDriver {\r\n /**\r\n * Set a value in cache with tags\r\n */\r\n set(key: CacheKey, value: any, ttlOrOptions?: CacheTtl | CacheSetOptions): Promise<any>;\r\n /**\r\n * Get a value from cache (checks tags)\r\n */\r\n get(key: CacheKey): Promise<any | null>;\r\n /**\r\n * Remove a specific key\r\n */\r\n remove(key: CacheKey): Promise<void>;\r\n /**\r\n * Invalidate (clear) all keys associated with the current tags\r\n */\r\n invalidate(): Promise<void>;\r\n /**\r\n * Flush all keys associated with the current tags\r\n * @deprecated Use invalidate() instead\r\n */\r\n flush(): Promise<void>;\r\n /**\r\n * Check if a key exists\r\n */\r\n has(key: CacheKey): Promise<boolean>;\r\n /**\r\n * Remember pattern with tags\r\n */\r\n remember(key: CacheKey, ttl: number, callback: () => Promise<any>): Promise<any>;\r\n /**\r\n * Pull value with tags\r\n */\r\n pull(key: CacheKey): Promise<any | null>;\r\n /**\r\n * Forever with tags\r\n */\r\n forever(key: CacheKey, value: any): Promise<any>;\r\n /**\r\n * Increment with tags\r\n */\r\n increment(key: CacheKey, value?: number): Promise<number>;\r\n /**\r\n * Decrement with tags\r\n */\r\n decrement(key: CacheKey, value?: number): Promise<number>;\r\n}\r\n\r\nexport type MemoryCacheOptions = {\r\n /**\r\n * The global prefix for the cache key\r\n */\r\n globalPrefix?: string | (() => string);\r\n /**\r\n * The default TTL for the cache. Accepts a number of seconds or a human-readable\r\n * duration string like `\"1h\"`, `\"30m\"`, `\"7d\"`.\r\n *\r\n * @default Infinity\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Maximum number of items in cache\r\n * When exceeded, least recently used items will be evicted\r\n *\r\n * @default undefined (no limit)\r\n */\r\n maxSize?: number;\r\n};\r\n\r\nexport type MemoryExtendedCacheOptions = MemoryCacheOptions;\r\n\r\nexport type LRUMemoryCacheOptions = {\r\n /**\r\n * The maximum number of items in the cache\r\n *\r\n * @default 1000\r\n */\r\n capacity?: number;\r\n /**\r\n * The global prefix for the cache key. Applied via `parseCacheKey`, same\r\n * semantics as the other drivers.\r\n */\r\n globalPrefix?: string | (() => string);\r\n /**\r\n * The default TTL for new entries. Accepts a number of seconds or a\r\n * human-readable duration string like `\"1h\"`, `\"30m\"`, `\"7d\"`.\r\n *\r\n * @default Infinity\r\n */\r\n ttl?: CacheTtl;\r\n};\r\n\r\nexport type FileCacheOptions = {\r\n /**\r\n * The global prefix for the cache key\r\n */\r\n globalPrefix?: string | (() => string);\r\n /**\r\n * The default TTL for the cache. Accepts a number of seconds or a human-readable\r\n * duration string like `\"1h\"`, `\"30m\"`, `\"7d\"`.\r\n *\r\n * @default 0\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Storage cache directory\r\n *\r\n * @default storagePath(\"cache\")\r\n */\r\n directory: string | (() => string);\r\n /**\r\n * File name\r\n *\r\n * @default cache.json\r\n */\r\n fileName?: string | (() => string);\r\n};\r\n\r\nexport type RedisOptions = {\r\n /**\r\n * Redis Port\r\n *\r\n * @default 6379\r\n */\r\n port?: number;\r\n /**\r\n * Redis Host\r\n */\r\n host?: string;\r\n /**\r\n * Redis Username\r\n */\r\n username?: string;\r\n /**\r\n * Redis Password\r\n */\r\n password?: string;\r\n /**\r\n * Redis URL\r\n *\r\n * If used, it will override the host and port options\r\n */\r\n url?: string;\r\n /**\r\n * Global prefix for the cache key\r\n */\r\n globalPrefix?: string | (() => string);\r\n /**\r\n * Default TTL. Accepts a number of seconds or a human-readable duration string\r\n * like `\"1h\"`, `\"30m\"`, `\"7d\"`.\r\n *\r\n * @default Infinity\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Redis client options\r\n */\r\n clientOptions?: RedisClientOptions;\r\n};\r\n\r\nexport type NullCacheDriverOptions = GenericObject;\r\n\r\n/**\r\n * Options accepted by {@link MockCacheDriver}. Same shape as the memory\r\n * driver — only `globalPrefix` and `ttl` apply, since the mock's storage is\r\n * a plain `Map` with no eviction policy.\r\n */\r\nexport type MockCacheOptions = {\r\n /**\r\n * Global key prefix, applied via `parseKey` (matches the other drivers).\r\n */\r\n globalPrefix?: string | (() => string);\r\n /**\r\n * Default TTL for new entries. Accepts seconds or a duration string.\r\n *\r\n * @default Infinity\r\n */\r\n ttl?: CacheTtl;\r\n};\r\n\r\n/**\r\n * One row in {@link MockCacheDriver.callLog} — captures every public op\r\n * the driver received in arrival order. Useful for behavioral assertions\r\n * in downstream tests (\"did my service actually invalidate the cache?\").\r\n */\r\nexport type CacheCall = {\r\n /**\r\n * Operation name as it appears on the driver contract — `\"set\"`, `\"get\"`,\r\n * `\"remove\"`, `\"flush\"`, `\"removeNamespace\"`, `\"has\"`, etc.\r\n */\r\n operation: string;\r\n /**\r\n * Post-`parseKey` cache key when the op is key-addressed; `undefined` for\r\n * keyless ops (`flush`, `connect`, `disconnect`).\r\n */\r\n key?: string;\r\n /**\r\n * Raw arguments passed to the call site, in declaration order. Lets\r\n * callers assert on TTLs, options objects, vector payloads, etc.\r\n */\r\n args: unknown[];\r\n /**\r\n * `Date.now()` when the call was recorded. Useful for timing-related\r\n * assertions (e.g. \"the second invalidation came within 100ms\").\r\n */\r\n timestamp: number;\r\n};\r\n\r\n/**\r\n * Minimal `pg`-compatible client surface the cache driver depends on.\r\n *\r\n * Both `pg.Pool` and `pg.Client` from the `pg` package satisfy this — the\r\n * driver only ever calls `query(text, values)`. Typing it loosely keeps\r\n * `pg` strictly optional: consumers without the `pg` package installed\r\n * never hit a missing import.\r\n */\r\nexport type PgClientLike = {\r\n query(text: string, values?: unknown[]): Promise<{ rows: any[]; rowCount?: number | null }>;\r\n};\r\n\r\nexport type PgCacheOptions = {\r\n /**\r\n * User-supplied `pg.Pool` or `pg.Client`. The driver does NOT own the\r\n * connection lifecycle — `cache.disconnect()` will not close this client.\r\n */\r\n client: PgClientLike;\r\n /**\r\n * Database table name. Default: `\"warlock_cache\"`.\r\n *\r\n * Sanitized: only `[A-Za-z0-9_]` are allowed; anything else throws\r\n * {@link CacheConfigurationError} at `setOptions` time.\r\n */\r\n table?: string;\r\n /**\r\n * Global key prefix, applied via `parseKey` (same semantics as the other drivers).\r\n */\r\n globalPrefix?: string | (() => string);\r\n /**\r\n * Default TTL for new entries. Accepts seconds or a duration string\r\n * (`\"1h\"`, `\"7d\"`, …).\r\n *\r\n * @default Infinity\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Optional pgvector configuration. When present, the driver provisions an\r\n * `embedding VECTOR(dimensions)` column + similarity index, and `similar()`\r\n * queries via the `<=>` cosine-distance operator.\r\n *\r\n * Requires the pgvector extension (`CREATE EXTENSION vector;`) — the driver\r\n * verifies its presence on the first vector operation and throws\r\n * {@link CacheConfigurationError} if missing.\r\n *\r\n * Omit this block (or remove it) to run the driver in KV-only mode —\r\n * `set({ vector })` and `similar()` then throw {@link CacheUnsupportedError}.\r\n */\r\n vector?: {\r\n /**\r\n * Vector dimension count. Must match the embedder you use throughout the\r\n * lifetime of the table. Mixing dimensions on the same table is unsupported.\r\n */\r\n dimensions: number;\r\n /**\r\n * pgvector index strategy. `hnsw` (default) is faster to query and slightly\r\n * slower to build; `ivfflat` is faster to build but typically slower to query.\r\n *\r\n * @default \"hnsw\"\r\n */\r\n index?: \"hnsw\" | \"ivfflat\";\r\n };\r\n};\r\n\r\nexport interface CacheDriver<ClientType, Options> {\r\n /**\r\n * The cache driver options\r\n */\r\n options: Options;\r\n /**\r\n * Cache driver name\r\n */\r\n name: string;\r\n /**\r\n * Set logging state\r\n */\r\n setLoggingState(shouldLog: boolean): any;\r\n /**\r\n * Remove all cached items by namespace\r\n */\r\n removeNamespace(namespace: string): Promise<any>;\r\n /**\r\n * Set the cache driver options\r\n */\r\n setOptions(options: Options): any;\r\n /**\r\n * Parse the key to be used in the cache\r\n */\r\n parseKey(key: CacheKey): string;\r\n /**\r\n * Set a value in the cache.\r\n *\r\n * @param key The cache key, could be an object or string\r\n * @param value The value to be stored in the cache\r\n * @param ttlOrOptions Either a TTL (seconds number, or duration string like `\"1h\"`),\r\n * or a full {@link CacheSetOptions} object.\r\n *\r\n * @example\r\n * // Positional TTL (back-compat)\r\n * await cache.set(\"user:1\", user, 3600);\r\n *\r\n * @example\r\n * // Human-readable duration\r\n * await cache.set(\"user:1\", user, \"1h\");\r\n *\r\n * @example\r\n * // Rich options\r\n * await cache.set(\"user:1\", user, { ttl: \"1h\", tags: [\"users\"], onConflict: \"create\" });\r\n */\r\n set(\r\n key: CacheKey,\r\n value: any,\r\n ttlOrOptions?: CacheTtl | CacheSetOptions,\r\n ): Promise<any>;\r\n /**\r\n * Get a value from the cache\r\n */\r\n get<T = any>(key: CacheKey): Promise<T | null>;\r\n /**\r\n * Remove a value from the cache\r\n */\r\n remove(key: CacheKey): Promise<void>;\r\n /**\r\n * Flush the entire cache\r\n */\r\n flush(): Promise<void>;\r\n /**\r\n * Connect to the cache driver\r\n */\r\n connect(): Promise<any>;\r\n /**\r\n * The cache client\r\n */\r\n client?: ClientType;\r\n /**\r\n * Disconnect the cache driver\r\n */\r\n disconnect(): Promise<void>;\r\n /**\r\n * Check if a key exists in the cache without fetching its value\r\n */\r\n has(key: CacheKey): Promise<boolean>;\r\n /**\r\n * Get value from cache or execute callback and cache the result.\r\n *\r\n * The second argument accepts a TTL (number of seconds or duration string like `\"1h\"`)\r\n * or a full {@link RememberOptions} object when you need to attach tags or route to\r\n * a non-default driver.\r\n *\r\n * @example\r\n * // Positional TTL — the common case\r\n * const user = await cache.remember(\"user.1\", \"1h\", () => db.users.find(1));\r\n *\r\n * @example\r\n * // Options form — tag the cache-miss write for bulk invalidation\r\n * const user = await cache.remember(\"user.1\", { ttl: \"1h\", tags: [\"users\"] }, () =>\r\n * db.users.find(1),\r\n * );\r\n */\r\n remember<T = any>(\r\n key: CacheKey,\r\n ttlOrOptions: CacheTtl | RememberOptions,\r\n callback: () => Promise<T>,\r\n ): Promise<T>;\r\n /**\r\n * Stale-while-revalidate. Returns the cached value when fresh; returns\r\n * the stale value + kicks off a background refresh when within the\r\n * `freshTtl..staleTtl` window; blocks like a normal miss when past\r\n * `staleTtl`. Concurrent stale-window callers share one in-flight\r\n * refresh.\r\n *\r\n * Background refresh failures preserve the stale entry and emit an\r\n * `error` event — the stale-returning caller never sees the failure.\r\n *\r\n * @example\r\n * const product = await cache.swr(\r\n * \"product.42\",\r\n * { freshTtl: \"1m\", staleTtl: \"1h\" },\r\n * () => db.products.find(42),\r\n * );\r\n */\r\n swr<T = any>(\r\n key: CacheKey,\r\n options: CacheSwrOptions,\r\n callback: () => Promise<T>,\r\n ): Promise<T>;\r\n /**\r\n * Get value and remove it from cache (atomic operation)\r\n */\r\n pull<T = any>(key: CacheKey): Promise<T | null>;\r\n /**\r\n * Set a value in cache permanently (no expiration)\r\n */\r\n forever<T = any>(key: CacheKey, value: T): Promise<T>;\r\n /**\r\n * Atomically read, transform, and write a cached value.\r\n *\r\n * The callback receives the current value (or `null` on miss) and returns the\r\n * next value. Returning `null` removes the key. TTL is preserved unless\r\n * explicitly overridden via options.\r\n *\r\n * @example\r\n * await cache.update<User>(\"user:1\", (current) => {\r\n * if (!current) return null;\r\n * return { ...current, lastSeen: Date.now() };\r\n * });\r\n */\r\n update<T = any>(\r\n key: CacheKey,\r\n fn: (current: T | null) => T | null | Promise<T | null>,\r\n options?: { ttl?: CacheTtl },\r\n ): Promise<T | null>;\r\n /**\r\n * Shallow-merge a partial object into a cached value.\r\n *\r\n * If the key is missing, treats the current value as `{}`. Preserves TTL by default.\r\n *\r\n * @example\r\n * await cache.merge<User>(\"user:1\", { name: \"Jane\" });\r\n */\r\n merge<T extends Record<string, any> = Record<string, any>>(\r\n key: CacheKey,\r\n partial: Partial<T>,\r\n options?: { ttl?: CacheTtl },\r\n ): Promise<T>;\r\n /**\r\n * List sub-API factory — returns a {@link CacheListAccessor} bound to the given key.\r\n *\r\n * @example\r\n * const recent = cache.list<Event>(\"recent-events\");\r\n * await recent.push(event);\r\n * const last10 = await recent.slice(0, 10);\r\n */\r\n list<T = any>(key: CacheKey): CacheListAccessor<T>;\r\n /**\r\n * Acquire a distributed lock, run `fn`, and auto-release. Returns a\r\n * {@link LockOutcome} so callers can distinguish \"ran and produced this value\"\r\n * from \"skipped because someone else holds the lock.\"\r\n *\r\n * Built on top of `set({ onConflict: \"create\" })` — Redis-native, emulated\r\n * on other drivers (single-process semantics elsewhere).\r\n *\r\n * @example\r\n * const outcome = await cache.lock(\"lock.import\", \"5m\", async () => {\r\n * await runImport();\r\n * return \"done\";\r\n * });\r\n */\r\n lock<T>(\r\n key: CacheKey,\r\n ttlOrOptions: CacheTtl | Omit<LockOptions, \"driver\">,\r\n fn: () => Promise<T>,\r\n ): Promise<LockOutcome<T>>;\r\n /**\r\n * Increment a numeric value in cache\r\n *\r\n * @param key The cache key\r\n * @param value The value to increment by (default 1)\r\n */\r\n increment(key: CacheKey, value?: number): Promise<number>;\r\n /**\r\n * Decrement a numeric value in cache\r\n *\r\n * @param key The cache key\r\n * @param value The value to decrement by (default 1)\r\n */\r\n decrement(key: CacheKey, value?: number): Promise<number>;\r\n /**\r\n * Get multiple values from cache at once\r\n */\r\n many(keys: CacheKey[]): Promise<any[]>;\r\n /**\r\n * Set multiple values in cache at once\r\n */\r\n setMany(items: Record<string, any>, ttl?: number): Promise<void>;\r\n /**\r\n * Register an event listener\r\n */\r\n on(event: CacheEventType, handler: CacheEventHandler): this;\r\n /**\r\n * Remove an event listener\r\n */\r\n off(event: CacheEventType, handler: CacheEventHandler): this;\r\n /**\r\n * Register a one-time event listener\r\n */\r\n once(event: CacheEventType, handler: CacheEventHandler): this;\r\n /**\r\n * Set if not exists (atomic operation)\r\n * Returns true if key was set, false if key already existed\r\n * Note: Not all drivers support this operation\r\n */\r\n setNX?(key: CacheKey, value: any, ttl?: number): Promise<boolean>;\r\n /**\r\n * Create a tagged cache instance for the given tags\r\n */\r\n tags(tags: string[]): TaggedCacheDriver;\r\n /**\r\n * Similarity retrieval. Returns the nearest stored entries to `vector` by\r\n * cosine similarity, ordered by descending score.\r\n *\r\n * Drivers without a similarity index throw {@link CacheUnsupportedError}.\r\n * Memory-family drivers brute-force scan in O(N) — suitable for development\r\n * but not for production knowledge bases beyond a few thousand entries; use\r\n * the `pg` driver (with pgvector) or `redis` driver (with RediSearch) instead.\r\n *\r\n * @example\r\n * const hits = await cache.similar(await embed(query), { topK: 5, threshold: 0.7 });\r\n */\r\n similar<T = any>(\r\n vector: number[],\r\n options: CacheSimilarOptions,\r\n ): Promise<CacheSimilarHit<T>[]>;\r\n}\r\n\r\n/**\r\n * Accessor for list-shaped cached values.\r\n *\r\n * Defaults to read-mutate-write semantics on non-native drivers (memory, file, LRU).\r\n * The Redis driver overrides this with native `LPUSH` / `RPUSH` / `LRANGE` / `LTRIM` for O(1) ops.\r\n */\r\nexport interface CacheListAccessor<T = any> {\r\n /**\r\n * Append one or more items to the tail of the list. Returns the new length.\r\n */\r\n push(...items: T[]): Promise<number>;\r\n /**\r\n * Prepend one or more items to the head of the list. Returns the new length.\r\n */\r\n unshift(...items: T[]): Promise<number>;\r\n /**\r\n * Remove and return the tail item, or `null` if the list is empty.\r\n */\r\n pop(): Promise<T | null>;\r\n /**\r\n * Remove and return the head item, or `null` if the list is empty.\r\n */\r\n shift(): Promise<T | null>;\r\n /**\r\n * Return a slice of the list. End is exclusive, mirroring `Array.prototype.slice`.\r\n */\r\n slice(start?: number, end?: number): Promise<T[]>;\r\n /**\r\n * Return the full list.\r\n */\r\n all(): Promise<T[]>;\r\n /**\r\n * Return the length of the list.\r\n */\r\n length(): Promise<number>;\r\n /**\r\n * Trim the list to the inclusive range `[start, end]`. Outside elements are dropped.\r\n */\r\n trim(start: number, end: number): Promise<void>;\r\n /**\r\n * Remove the entire list.\r\n */\r\n clear(): Promise<void>;\r\n}\r\n\r\n/**\r\n * One-shot tagged handle returned by `ScopedCacheContract.tags(...)`.\r\n *\r\n * Identical write surface to {@link TaggedCacheDriver}, except the underlying\r\n * scope's prefix is applied to every key and the scope's default TTL/tags\r\n * still flow through. Tags supplied here merge additively with scope-level\r\n * tags.\r\n */\r\nexport interface TaggedScopedCacheContract {\r\n set(key: CacheKey, value: any, ttlOrOptions?: CacheTtl | CacheSetOptions): Promise<any>;\r\n get<T = any>(key: CacheKey): Promise<T | null>;\r\n has(key: CacheKey): Promise<boolean>;\r\n remove(key: CacheKey): Promise<void>;\r\n pull<T = any>(key: CacheKey): Promise<T | null>;\r\n forever<T = any>(key: CacheKey, value: T): Promise<T>;\r\n setNX(key: CacheKey, value: any, ttl?: number): Promise<boolean>;\r\n remember<T = any>(\r\n key: CacheKey,\r\n ttlOrOptions: CacheTtl | RememberOptions,\r\n callback: () => Promise<T>,\r\n ): Promise<T>;\r\n increment(key: CacheKey, value?: number): Promise<number>;\r\n decrement(key: CacheKey, value?: number): Promise<number>;\r\n /**\r\n * Invalidate every entry tagged with the union of scope tags + handle tags.\r\n * Forwarded to the underlying tag index — tags are global, scope-agnostic.\r\n */\r\n invalidate(): Promise<void>;\r\n}\r\n\r\n/**\r\n * Scoped view over the cache. Returned by `cache.namespace(prefix, options?)`.\r\n *\r\n * A scope prepends its `prefix` to every key, applies optional default TTL/tags\r\n * to every write, and forwards everything else to the underlying source. It\r\n * stores nothing of its own — purely a convenience wrapper.\r\n *\r\n * @example\r\n * const chat = cache.namespace(\"chats.10\", { ttl: \"30d\" });\r\n * await chat.set(\"messages.1\", msg); // → \"chats.10.messages.1\", TTL 30d\r\n * await chat.set(\"draft\", d, { ttl: \"1h\" }); // per-call ttl wins\r\n * await chat.clear(); // wipe the whole scope\r\n */\r\nexport interface ScopedCacheContract {\r\n /** The fully-qualified prefix this scope prepends to every key. */\r\n readonly prefix: string;\r\n\r\n /**\r\n * Nested scope. Inherits the parent's defaults; child's own options override.\r\n *\r\n * @example\r\n * const chat = cache.namespace(\"chats.10\", { ttl: \"30d\" });\r\n * const typing = chat.namespace(\"typing\", { ttl: \"5s\" });\r\n * // typing.prefix === \"chats.10.typing\"\r\n */\r\n namespace(prefix: string, options?: CacheNamespaceOptions): ScopedCacheContract;\r\n\r\n /**\r\n * One-shot tagged write handle. Tags merge additively with scope defaults.\r\n */\r\n tags(tags: string[]): TaggedScopedCacheContract;\r\n\r\n /** Wipe every entry under this scope's prefix. Sugar for `removeNamespace(prefix)`. */\r\n clear(): Promise<void>;\r\n\r\n // Reads\r\n get<T = any>(key: CacheKey): Promise<T | null>;\r\n has(key: CacheKey): Promise<boolean>;\r\n many(keys: CacheKey[]): Promise<any[]>;\r\n pull<T = any>(key: CacheKey): Promise<T | null>;\r\n\r\n // Writes\r\n set(key: CacheKey, value: any, ttlOrOptions?: CacheTtl | CacheSetOptions): Promise<any>;\r\n setMany(items: Record<string, any>, ttl?: number): Promise<void>;\r\n setNX(key: CacheKey, value: any, ttl?: number): Promise<boolean>;\r\n forever<T = any>(key: CacheKey, value: T): Promise<T>;\r\n remove(key: CacheKey): Promise<void>;\r\n\r\n // Read-or-compute\r\n remember<T = any>(\r\n key: CacheKey,\r\n ttlOrOptions: CacheTtl | RememberOptions,\r\n callback: () => Promise<T>,\r\n ): Promise<T>;\r\n swr<T = any>(\r\n key: CacheKey,\r\n options: CacheSwrOptions,\r\n callback: () => Promise<T>,\r\n ): Promise<T>;\r\n\r\n // Mutations\r\n increment(key: CacheKey, value?: number): Promise<number>;\r\n decrement(key: CacheKey, value?: number): Promise<number>;\r\n update<T = any>(\r\n key: CacheKey,\r\n fn: (current: T | null) => T | null | Promise<T | null>,\r\n options?: { ttl?: CacheTtl },\r\n ): Promise<T | null>;\r\n merge<T extends Record<string, any> = Record<string, any>>(\r\n key: CacheKey,\r\n partial: Partial<T>,\r\n options?: { ttl?: CacheTtl },\r\n ): Promise<T>;\r\n\r\n // Structured accessors\r\n list<T = any>(key: CacheKey): CacheListAccessor<T>;\r\n\r\n // Coordination\r\n lock<T>(\r\n key: CacheKey,\r\n ttlOrOptions: CacheTtl | Omit<LockOptions, \"driver\">,\r\n fn: () => Promise<T>,\r\n ): Promise<LockOutcome<T>>;\r\n\r\n // Similarity (delegated; throws CacheUnsupportedError if the driver lacks it)\r\n similar<T = any>(\r\n vector: number[],\r\n options: CacheSimilarOptions,\r\n ): Promise<CacheSimilarHit<T>[]>;\r\n}\r\n\r\nexport type CacheData = {\r\n /**\r\n * Value stored in the cache\r\n */\r\n data: any;\r\n /**\r\n * The expiration date in milliseconds\r\n */\r\n expiresAt?: number;\r\n /**\r\n * Time to live in seconds\r\n */\r\n ttl?: number;\r\n /**\r\n * Freshness deadline as a millisecond timestamp. Used by `swr()` — entries\r\n * with `staleAt` in the future are \"fresh\"; past `staleAt` but before\r\n * `expiresAt` are \"stale-but-revalidatable\" and trigger a background\r\n * refresh on the next read. Optional — entries written through plain\r\n * `set()` skip this field entirely and `swr()` treats them as always-fresh.\r\n */\r\n staleAt?: number;\r\n};\r\n\r\nexport type DriverClass = new () => CacheDriver<any, any>;\r\n\r\ntype DefaultDrivers =\r\n | \"redis\"\r\n | \"file\"\r\n | \"memory\"\r\n | \"memoryExtended\"\r\n | \"null\"\r\n | \"lru\"\r\n | \"pg\"\r\n | \"mock\";\r\n\r\ntype MergeWithDefaultDrivers<T> = T extends undefined ? DefaultDrivers : DefaultDrivers | T;\r\n\r\nexport type CacheConfigurations<\r\n T extends string | undefined = undefined,\r\n DriverName = MergeWithDefaultDrivers<T>,\r\n> = {\r\n /**\r\n * The default cache driver name\r\n */\r\n default?: DriverName;\r\n /**\r\n * Determine whether to log or not\r\n *\r\n * @default true\r\n */\r\n logging?: boolean;\r\n /**\r\n * The cache drivers list\r\n */\r\n drivers: {\r\n redis?: typeof RedisCacheDriver;\r\n file?: typeof FileCacheDriver;\r\n null?: typeof NullCacheDriver;\r\n memory?: typeof MemoryCacheDriver;\r\n memoryExtended?: typeof MemoryExtendedCacheDriver;\r\n lru?: typeof LRUMemoryCacheDriver;\r\n pg?: typeof PgCacheDriver;\r\n mock?: typeof MockCacheDriver;\r\n } & {\r\n [key in Extract<T, string>]?: typeof BaseCacheDriver<any, any> | undefined;\r\n };\r\n /**\r\n * The cache driver options\r\n */\r\n options: {\r\n redis?: RedisOptions;\r\n file?: FileCacheOptions;\r\n memory?: MemoryCacheOptions;\r\n memoryExtended?: MemoryExtendedCacheOptions;\r\n null?: NullCacheDriverOptions;\r\n lru?: LRUMemoryCacheOptions;\r\n pg?: PgCacheOptions;\r\n mock?: MockCacheOptions;\r\n } & {\r\n [key in Extract<T, string>]?: GenericObject;\r\n };\r\n};\r\n"],"mappings":";;;;AAiBA,IAAa,aAAb,cAAgC,MAAM;CACpC,AAAO,YAAY,SAAiB;EAClC,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,uBAAb,cAA0C,WAAW;CACnD,AAAO,YAAY,SAAiB;EAClC,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,0BAAb,cAA6C,WAAW;CACtD,AAAO,YAAY,SAAiB;EAClC,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,iCAAb,cAAoD,WAAW;CAC7D,AAAO,YACL,UAAkB,wEAClB;EACA,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;;;;AAQA,IAAa,wBAAb,cAA2C,WAAW;CACpD,AAAO,YAAY,SAAiB;EAClC,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,wBAAb,cAA2C,WAAW;CACpD,AAAO,YAAY,SAAiB;EAClC,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF"}
1
+ {"version":3,"file":"types.mjs","names":[],"sources":["../../../../../../@warlock.js/cache/src/types.ts"],"sourcesContent":["import type { GenericObject } from \"@mongez/reinforcements\";\r\nimport type { RedisClientOptions } from \"redis\";\r\nimport type {\r\n BaseCacheDriver,\r\n FileCacheDriver,\r\n LRUMemoryCacheDriver,\r\n MemoryCacheDriver,\r\n MockCacheDriver,\r\n MemoryExtendedCacheDriver,\r\n NullCacheDriver,\r\n PgCacheDriver,\r\n RedisCacheDriver,\r\n} from \"./drivers\";\r\n\r\n/**\r\n * Base error class for cache-related errors\r\n */\r\nexport class CacheError extends Error {\r\n public constructor(message: string) {\r\n super(message);\r\n this.name = \"CacheError\";\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when cache connection fails\r\n */\r\nexport class CacheConnectionError extends CacheError {\r\n public constructor(message: string) {\r\n super(message);\r\n this.name = \"CacheConnectionError\";\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when cache driver configuration is invalid\r\n */\r\nexport class CacheConfigurationError extends CacheError {\r\n public constructor(message: string) {\r\n super(message);\r\n this.name = \"CacheConfigurationError\";\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when cache driver is not initialized\r\n */\r\nexport class CacheDriverNotInitializedError extends CacheError {\r\n public constructor(\r\n message: string = \"No cache driver initialized. Call cache.init() or cache.use() first.\",\r\n ) {\r\n super(message);\r\n this.name = \"CacheDriverNotInitializedError\";\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when a driver does not implement a requested operation.\r\n *\r\n * Raised when a caller invokes a method the driver cannot fulfill —\r\n * e.g. `update()` on the file driver before the file-lock primitive lands.\r\n */\r\nexport class CacheUnsupportedError extends CacheError {\r\n public constructor(message: string) {\r\n super(message);\r\n this.name = \"CacheUnsupportedError\";\r\n }\r\n}\r\n\r\n/**\r\n * Error thrown when an optimistic-concurrency update exhausts its retry budget.\r\n */\r\nexport class CacheConcurrencyError extends CacheError {\r\n public constructor(message: string) {\r\n super(message);\r\n this.name = \"CacheConcurrencyError\";\r\n }\r\n}\r\n\r\n/**\r\n * TTL shape accepted by set/remember/config calls.\r\n *\r\n * - `number` — seconds\r\n * - `string` — human-readable duration parsed via `ms` (`\"1h\"`, `\"30m\"`, `\"7d\"`, `\"2 weeks\"`, …)\r\n * - `Infinity` — no expiration\r\n */\r\nexport type CacheTtl = number | string;\r\n\r\n/**\r\n * Conflict resolution policy for `set` operations.\r\n *\r\n * - `\"create\"` — set only if the key does not exist (Redis `NX`)\r\n * - `\"update\"` — set only if the key already exists (Redis `XX`)\r\n * - `\"upsert\"` — default; overwrite whether the key exists or not\r\n */\r\nexport type CacheConflictPolicy = \"create\" | \"update\" | \"upsert\";\r\n\r\n/**\r\n * Result of a conditional write (`onConflict: \"create\" | \"update\"`).\r\n */\r\nexport type CacheSetResult<T = any> = {\r\n /**\r\n * Whether the write actually took effect.\r\n */\r\n wasSet: boolean;\r\n /**\r\n * The existing value when the write was rejected. Undefined for successful writes\r\n * and for unconditional `upsert` writes.\r\n */\r\n existing: T | null;\r\n};\r\n\r\n/**\r\n * Options for `lock()` — TTL is required (forgotten locks would stay forever),\r\n * `owner` identifies who holds the lock (handy for debugging), `driver` routes\r\n * the call through a non-default driver.\r\n *\r\n * @example\r\n * await cache.lock(\"lock.import\", { ttl: \"5m\", driver: \"redis\" }, async () => {\r\n * await runImport();\r\n * });\r\n */\r\nexport type LockOptions = {\r\n /**\r\n * How long the lock lives before auto-release. Required — guards against\r\n * forgotten locks if the process crashes between acquire and release.\r\n */\r\n ttl: CacheTtl;\r\n /**\r\n * Identifying value stored under the lock key. Defaults to `pid.<process.pid>`.\r\n * Use a custom owner when you want a human-readable label (e.g. `\"worker.jobs-2\"`).\r\n */\r\n owner?: string;\r\n /**\r\n * Per-call driver override by registered name. Manager-level only.\r\n */\r\n driver?: string;\r\n};\r\n\r\n/**\r\n * Discriminated-union result of `lock()`. Unambiguous even when the wrapped\r\n * function legitimately returns `undefined` — the `acquired` flag tells you\r\n * whether `fn` ran at all.\r\n *\r\n * @example\r\n * const outcome = await cache.lock(\"lock.x\", \"1m\", async () => computeValue());\r\n * if (outcome.acquired) {\r\n * console.log(\"ran, got\", outcome.value);\r\n * } else {\r\n * console.log(\"skipped — someone else holds the lock\");\r\n * }\r\n */\r\nexport type LockOutcome<T> =\r\n | { acquired: true; value: T }\r\n | { acquired: false };\r\n\r\n/**\r\n * Options for `remember()` when you need more than just a TTL — e.g. attaching\r\n * tags to the cache-miss write, or routing the single call to a non-default driver.\r\n *\r\n * Passed in the TTL position: `cache.remember(key, { ttl: \"1h\", tags: [\"users\"] }, fn)`.\r\n *\r\n * @example\r\n * await cache.remember(\"user.1\", { ttl: \"1h\", tags: [\"users\"] }, () =>\r\n * db.users.find(1),\r\n * );\r\n */\r\nexport type RememberOptions = {\r\n /**\r\n * TTL applied on cache miss. Accepts seconds (number) or duration string.\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Tags attached to the entry created on miss. Invalidate via `cache.tags([...]).invalidate()`.\r\n */\r\n tags?: string[];\r\n /**\r\n * Per-call driver override. Routes this remember call (both read and write)\r\n * to the named driver without mutating `currentDriver`.\r\n */\r\n driver?: string;\r\n};\r\n\r\n/**\r\n * Rich options for the `set` call-site. Mutually exclusive with a positional TTL.\r\n *\r\n * @example\r\n * await cache.set(\"user:1\", user, {\r\n * ttl: \"1h\",\r\n * tags: [\"users\", \"active\"],\r\n * onConflict: \"create\",\r\n * });\r\n */\r\nexport type CacheSetOptions = {\r\n /**\r\n * Relative TTL (seconds or duration string). Mutually exclusive with `expiresAt`.\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Absolute expiration as a Unix epoch in milliseconds or a Date. Mutually exclusive with `ttl`.\r\n */\r\n expiresAt?: number | Date;\r\n /**\r\n * Tags attached to this entry for tag-based invalidation. Inline equivalent of\r\n * `cache.tags([...]).set(key, value)`.\r\n */\r\n tags?: string[];\r\n /**\r\n * Conflict resolution policy. Defaults to `\"upsert\"`.\r\n */\r\n onConflict?: CacheConflictPolicy;\r\n /**\r\n * Per-call namespace override. Applied ahead of `globalPrefix` for this write only.\r\n */\r\n namespace?: string;\r\n /**\r\n * Per-call driver override by registered name. Routes this write to a non-default driver\r\n * without mutating `currentDriver`.\r\n */\r\n driver?: string;\r\n /**\r\n * Optional embedding vector indexed alongside the entry for similarity retrieval\r\n * via `cache.similar(...)`. Drivers without similarity support throw\r\n * {@link CacheUnsupportedError} when this option is supplied.\r\n *\r\n * Cache is embedding-agnostic — callers compute the vector with whichever embedder\r\n * they like and pass the result here.\r\n *\r\n * @example\r\n * await cache.set(\"doc.123\", doc, { vector: await embed(doc.text), ttl: \"1d\" });\r\n */\r\n vector?: number[];\r\n /**\r\n * Freshness deadline as a Unix epoch in milliseconds. Primarily set by\r\n * {@link CacheSwrOptions} flow — entries with `staleAt` in the future are\r\n * considered \"fresh\" by `cache.swr()`; entries past `staleAt` but before\r\n * `expiresAt` are \"stale-but-revalidatable.\"\r\n *\r\n * Direct callers can pin this manually when bypassing `swr()`, but the\r\n * common path is `cache.swr(key, { freshTtl, staleTtl }, fn)`.\r\n */\r\n staleAt?: number;\r\n};\r\n\r\n/**\r\n * Options for `cache.namespace(prefix, options)` — defaults applied to every\r\n * write produced through the returned scope.\r\n *\r\n * Per-call options always win over scope defaults. Tags merge additively\r\n * (scope tags + call tags, deduped). Nested scopes inherit from the parent;\r\n * the child's own values override.\r\n */\r\nexport type CacheNamespaceOptions = {\r\n /**\r\n * Default TTL for writes inside this scope. Same shape as everywhere else\r\n * — number of seconds or a duration string (`\"1h\"`, `\"30d\"`, …).\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Tags auto-attached to every write inside this scope. Useful for cross-scope\r\n * invalidation hooks (e.g. tag every entry with `user.<id>` so a single\r\n * `cache.flushTag(\"user.42\")` wipes the user's footprint everywhere).\r\n *\r\n * Merged additively with per-call tags; scope tags are never replaced.\r\n */\r\n tags?: string[];\r\n};\r\n\r\n/**\r\n * Options for `cache.swr(key, options, callback)` — stale-while-revalidate.\r\n *\r\n * Two TTLs split the entry's lifecycle into three windows:\r\n * - `now < freshTtl` → fresh, return cached value, no upstream call.\r\n * - `freshTtl <= now < staleTtl` → stale-but-revalidatable, return cached\r\n * value immediately, kick off `callback` in the background to refresh.\r\n * - `now >= staleTtl` → expired, block on `callback` like a normal miss.\r\n *\r\n * Concurrent SWR callers in the stale window all return the cached value;\r\n * the background refresh runs exactly once per key (deduped via the\r\n * driver's per-key lock map).\r\n *\r\n * If the background refresh fails, the stale entry is preserved and the\r\n * error is logged + emitted on the `error` event. Callers that received\r\n * the stale value never see the failure — they got their data.\r\n */\r\nexport type CacheSwrOptions = {\r\n /**\r\n * How long the value is considered fresh. Within this window, SWR returns\r\n * the cached value with no upstream call. Accepts seconds or duration\r\n * string (`\"1m\"`, `\"30s\"`).\r\n */\r\n freshTtl: CacheTtl;\r\n /**\r\n * Total lifetime of the entry (must be greater than `freshTtl`). Between\r\n * `freshTtl` and `staleTtl`, SWR returns the stale value and triggers a\r\n * background refresh. Past `staleTtl`, SWR blocks and refetches.\r\n */\r\n staleTtl: CacheTtl;\r\n /**\r\n * Optional tags applied on the first miss-fetch and on every successful\r\n * background refresh. Same semantics as `CacheSetOptions.tags`.\r\n */\r\n tags?: string[];\r\n /**\r\n * Per-call driver override by registered name. Routes both the read and\r\n * any write/refresh through the named driver without mutating\r\n * `currentDriver`. Same semantics as `RememberOptions.driver`.\r\n */\r\n driver?: string;\r\n};\r\n\r\n/**\r\n * Options for `cache.similar(vector, options)` — similarity retrieval against\r\n * stored entries previously written with `set({ vector })`.\r\n */\r\nexport type CacheSimilarOptions = {\r\n /**\r\n * Maximum number of hits to return. Required — no implicit default keeps\r\n * callers from accidentally pulling the entire candidate set.\r\n */\r\n topK: number;\r\n /**\r\n * Cosine similarity floor in `[0, 1]`. Hits scoring strictly below this are\r\n * filtered out before `topK` truncation.\r\n */\r\n threshold?: number;\r\n /**\r\n * Optional tag filter. Only entries tagged with at least one of the given\r\n * tags are considered (matches the union semantics elsewhere in the package).\r\n */\r\n tags?: string[];\r\n};\r\n\r\n/**\r\n * One result from a `similar()` query — the original key, its stored value,\r\n * and the cosine similarity to the query vector.\r\n */\r\nexport type CacheSimilarHit<T = unknown> = {\r\n /**\r\n * The original cache key, post-`parseKey` normalization.\r\n */\r\n key: string;\r\n /**\r\n * Stored value, deep-cloned to protect the cache from accidental mutation\r\n * (same semantics as `get`).\r\n */\r\n value: T;\r\n /**\r\n * Cosine similarity in `[0, 1]`. Higher means more similar.\r\n */\r\n score: number;\r\n};\r\n\r\n/**\r\n * Cache key type - can be a string or an object\r\n */\r\nexport type CacheKey = string | GenericObject;\r\n\r\nexport type CacheOperationType =\r\n | \"fetching\"\r\n | \"fetched\"\r\n | \"caching\"\r\n | \"cached\"\r\n | \"flushing\"\r\n | \"flushed\"\r\n | \"removing\"\r\n | \"removed\"\r\n | \"clearing\"\r\n | \"cleared\"\r\n | \"expired\"\r\n | \"notFound\"\r\n | \"connecting\"\r\n | \"error\"\r\n | \"connectionFailed\"\r\n | \"connected\"\r\n | \"disconnecting\"\r\n | \"disconnected\";\r\n\r\n/**\r\n * Cache event types for observability\r\n */\r\nexport type CacheEventType =\r\n | \"hit\"\r\n | \"miss\"\r\n | \"set\"\r\n | \"removed\"\r\n | \"flushed\"\r\n | \"expired\"\r\n | \"connected\"\r\n | \"disconnected\"\r\n | \"error\";\r\n\r\n/**\r\n * Cache event data structure\r\n */\r\nexport type CacheEventData = {\r\n /**\r\n * The cache key involved in the event\r\n */\r\n key?: string;\r\n /**\r\n * The value (for set/hit events)\r\n */\r\n value?: any;\r\n /**\r\n * TTL in seconds (for set events)\r\n */\r\n ttl?: number;\r\n /**\r\n * Driver name that emitted the event\r\n */\r\n driver: string;\r\n /**\r\n * Error object (for error events)\r\n */\r\n error?: any;\r\n /**\r\n * Namespace (for namespace operations)\r\n */\r\n namespace?: string;\r\n};\r\n\r\n/**\r\n * Event handler function type\r\n */\r\nexport type CacheEventHandler = (eventData: CacheEventData) => void | Promise<void>;\r\n\r\n/**\r\n * Per-operation latency + counter snapshot returned by `cache.metrics()`.\r\n *\r\n * The shape is a single recursive level — the top object covers all drivers\r\n * and each entry under `byDriver` repeats the same fields without nesting\r\n * further. Use this for ad-hoc dashboards, exporters to Prometheus / StatsD,\r\n * or just `console.log` during development.\r\n */\r\nexport type CacheMetricsSnapshot = {\r\n /** Cumulative cache hits across the lifetime of the collector. */\r\n hits: number;\r\n /** Cumulative cache misses (lookups that returned null). */\r\n misses: number;\r\n /** Cumulative successful writes. */\r\n sets: number;\r\n /** Cumulative key removals. */\r\n removed: number;\r\n /** Cumulative cache errors emitted via the `error` event. */\r\n errors: number;\r\n /** `hits / (hits + misses)` — `0` when no read ops have happened yet. */\r\n hitRate: number;\r\n /** Latency percentiles in milliseconds, computed from a circular buffer. */\r\n latencyMs: {\r\n p50: number;\r\n p95: number;\r\n p99: number;\r\n /** Size of the underlying buffer at snapshot time (capped at the configured max). */\r\n samples: number;\r\n };\r\n /** Per-driver breakdowns keyed by driver name (`\"memory\"`, `\"redis\"`, …). */\r\n byDriver: Record<string, Omit<CacheMetricsSnapshot, \"byDriver\">>;\r\n /** Millisecond timestamp the collector last reset (or was instantiated). */\r\n startedAt: number;\r\n};\r\n\r\n/**\r\n * Tagged cache interface for working with cache tags\r\n */\r\nexport interface TaggedCacheDriver {\r\n /**\r\n * Set a value in cache with tags\r\n */\r\n set(key: CacheKey, value: any, ttlOrOptions?: CacheTtl | CacheSetOptions): Promise<any>;\r\n /**\r\n * Get a value from cache (checks tags)\r\n */\r\n get(key: CacheKey): Promise<any | null>;\r\n /**\r\n * Remove a specific key\r\n */\r\n remove(key: CacheKey): Promise<void>;\r\n /**\r\n * Invalidate (clear) all keys associated with the current tags\r\n */\r\n invalidate(): Promise<void>;\r\n /**\r\n * Flush all keys associated with the current tags\r\n * @deprecated Use invalidate() instead\r\n */\r\n flush(): Promise<void>;\r\n /**\r\n * Check if a key exists\r\n */\r\n has(key: CacheKey): Promise<boolean>;\r\n /**\r\n * Remember pattern with tags\r\n */\r\n remember(key: CacheKey, ttl: number, callback: () => Promise<any>): Promise<any>;\r\n /**\r\n * Pull value with tags\r\n */\r\n pull(key: CacheKey): Promise<any | null>;\r\n /**\r\n * Forever with tags\r\n */\r\n forever(key: CacheKey, value: any): Promise<any>;\r\n /**\r\n * Increment with tags\r\n */\r\n increment(key: CacheKey, value?: number): Promise<number>;\r\n /**\r\n * Decrement with tags\r\n */\r\n decrement(key: CacheKey, value?: number): Promise<number>;\r\n}\r\n\r\nexport type MemoryCacheOptions = {\r\n /**\r\n * The global prefix for the cache key\r\n */\r\n globalPrefix?: string | (() => string);\r\n /**\r\n * The default TTL for the cache. Accepts a number of seconds or a human-readable\r\n * duration string like `\"1h\"`, `\"30m\"`, `\"7d\"`.\r\n *\r\n * @default Infinity\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Maximum number of items in cache\r\n * When exceeded, least recently used items will be evicted\r\n *\r\n * @default undefined (no limit)\r\n */\r\n maxSize?: number;\r\n};\r\n\r\nexport type MemoryExtendedCacheOptions = MemoryCacheOptions;\r\n\r\nexport type LRUMemoryCacheOptions = {\r\n /**\r\n * The maximum number of items in the cache\r\n *\r\n * @default 1000\r\n */\r\n capacity?: number;\r\n /**\r\n * The global prefix for the cache key. Applied via `parseCacheKey`, same\r\n * semantics as the other drivers.\r\n */\r\n globalPrefix?: string | (() => string);\r\n /**\r\n * The default TTL for new entries. Accepts a number of seconds or a\r\n * human-readable duration string like `\"1h\"`, `\"30m\"`, `\"7d\"`.\r\n *\r\n * @default Infinity\r\n */\r\n ttl?: CacheTtl;\r\n};\r\n\r\nexport type FileCacheOptions = {\r\n /**\r\n * The global prefix for the cache key\r\n */\r\n globalPrefix?: string | (() => string);\r\n /**\r\n * The default TTL for the cache. Accepts a number of seconds or a human-readable\r\n * duration string like `\"1h\"`, `\"30m\"`, `\"7d\"`.\r\n *\r\n * @default 0\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Storage cache directory\r\n *\r\n * @default storagePath(\"cache\")\r\n */\r\n directory: string | (() => string);\r\n /**\r\n * File name\r\n *\r\n * @default cache.json\r\n */\r\n fileName?: string | (() => string);\r\n};\r\n\r\nexport type RedisOptions = {\r\n /**\r\n * Redis Port\r\n *\r\n * @default 6379\r\n */\r\n port?: number;\r\n /**\r\n * Redis Host\r\n */\r\n host?: string;\r\n /**\r\n * Redis Username\r\n */\r\n username?: string;\r\n /**\r\n * Redis Password\r\n */\r\n password?: string;\r\n /**\r\n * Redis URL\r\n *\r\n * If used, it will override the host and port options\r\n */\r\n url?: string;\r\n /**\r\n * Global prefix for the cache key\r\n */\r\n globalPrefix?: string | (() => string);\r\n /**\r\n * Default TTL. Accepts a number of seconds or a human-readable duration string\r\n * like `\"1h\"`, `\"30m\"`, `\"7d\"`.\r\n *\r\n * @default Infinity\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Redis client options\r\n */\r\n clientOptions?: RedisClientOptions;\r\n};\r\n\r\nexport type NullCacheDriverOptions = GenericObject;\r\n\r\n/**\r\n * Options accepted by {@link MockCacheDriver}. Same shape as the memory\r\n * driver — only `globalPrefix` and `ttl` apply, since the mock's storage is\r\n * a plain `Map` with no eviction policy.\r\n */\r\nexport type MockCacheOptions = {\r\n /**\r\n * Global key prefix, applied via `parseKey` (matches the other drivers).\r\n */\r\n globalPrefix?: string | (() => string);\r\n /**\r\n * Default TTL for new entries. Accepts seconds or a duration string.\r\n *\r\n * @default Infinity\r\n */\r\n ttl?: CacheTtl;\r\n};\r\n\r\n/**\r\n * One row in {@link MockCacheDriver.callLog} — captures every public op\r\n * the driver received in arrival order. Useful for behavioral assertions\r\n * in downstream tests (\"did my service actually invalidate the cache?\").\r\n */\r\nexport type CacheCall = {\r\n /**\r\n * Operation name as it appears on the driver contract — `\"set\"`, `\"get\"`,\r\n * `\"remove\"`, `\"flush\"`, `\"removeNamespace\"`, `\"has\"`, etc.\r\n */\r\n operation: string;\r\n /**\r\n * Post-`parseKey` cache key when the op is key-addressed; `undefined` for\r\n * keyless ops (`flush`, `connect`, `disconnect`).\r\n */\r\n key?: string;\r\n /**\r\n * Raw arguments passed to the call site, in declaration order. Lets\r\n * callers assert on TTLs, options objects, vector payloads, etc.\r\n */\r\n args: unknown[];\r\n /**\r\n * `Date.now()` when the call was recorded. Useful for timing-related\r\n * assertions (e.g. \"the second invalidation came within 100ms\").\r\n */\r\n timestamp: number;\r\n};\r\n\r\n/**\r\n * Minimal `pg`-compatible client surface the cache driver depends on.\r\n *\r\n * Both `pg.Pool` and `pg.Client` from the `pg` package satisfy this — the\r\n * driver only ever calls `query(text, values)`. Typing it loosely keeps\r\n * `pg` strictly optional: consumers without the `pg` package installed\r\n * never hit a missing import.\r\n */\r\nexport type PgClientLike = {\r\n query(text: string, values?: unknown[]): Promise<{ rows: any[]; rowCount?: number | null }>;\r\n};\r\n\r\nexport type PgCacheOptions = {\r\n /**\r\n * User-supplied `pg.Pool` or `pg.Client`. The driver does NOT own the\r\n * connection lifecycle — `cache.disconnect()` will not close this client.\r\n */\r\n client: PgClientLike;\r\n /**\r\n * Database table name. Default: `\"warlock_cache\"`.\r\n *\r\n * Sanitized: only `[A-Za-z0-9_]` are allowed; anything else throws\r\n * {@link CacheConfigurationError} at `setOptions` time.\r\n */\r\n table?: string;\r\n /**\r\n * Global key prefix, applied via `parseKey` (same semantics as the other drivers).\r\n */\r\n globalPrefix?: string | (() => string);\r\n /**\r\n * Default TTL for new entries. Accepts seconds or a duration string\r\n * (`\"1h\"`, `\"7d\"`, …).\r\n *\r\n * @default Infinity\r\n */\r\n ttl?: CacheTtl;\r\n /**\r\n * Optional pgvector configuration. When present, the driver provisions an\r\n * `embedding VECTOR(dimensions)` column + similarity index, and `similar()`\r\n * queries via the `<=>` cosine-distance operator.\r\n *\r\n * Requires the pgvector extension (`CREATE EXTENSION vector;`) — the driver\r\n * verifies its presence on the first vector operation and throws\r\n * {@link CacheConfigurationError} if missing.\r\n *\r\n * Omit this block (or remove it) to run the driver in KV-only mode —\r\n * `set({ vector })` and `similar()` then throw {@link CacheUnsupportedError}.\r\n */\r\n vector?: {\r\n /**\r\n * Vector dimension count. Must match the embedder you use throughout the\r\n * lifetime of the table. Mixing dimensions on the same table is unsupported.\r\n */\r\n dimensions: number;\r\n /**\r\n * pgvector index strategy. `hnsw` (default) is faster to query and slightly\r\n * slower to build; `ivfflat` is faster to build but typically slower to query.\r\n *\r\n * @default \"hnsw\"\r\n */\r\n index?: \"hnsw\" | \"ivfflat\";\r\n };\r\n};\r\n\r\nexport interface CacheDriver<ClientType, Options> {\r\n /**\r\n * The cache driver options\r\n */\r\n options: Options;\r\n /**\r\n * Cache driver name\r\n */\r\n name: string;\r\n /**\r\n * Set logging state\r\n */\r\n setLoggingState(shouldLog: boolean): any;\r\n /**\r\n * Remove all cached items by namespace\r\n */\r\n removeNamespace(namespace: string): Promise<any>;\r\n /**\r\n * Set the cache driver options\r\n */\r\n setOptions(options: Options): any;\r\n /**\r\n * Parse the key to be used in the cache\r\n */\r\n parseKey(key: CacheKey): string;\r\n /**\r\n * Set a value in the cache.\r\n *\r\n * @param key The cache key, could be an object or string\r\n * @param value The value to be stored in the cache\r\n * @param ttlOrOptions Either a TTL (seconds number, or duration string like `\"1h\"`),\r\n * or a full {@link CacheSetOptions} object.\r\n *\r\n * @example\r\n * // Positional TTL (back-compat)\r\n * await cache.set(\"user:1\", user, 3600);\r\n *\r\n * @example\r\n * // Human-readable duration\r\n * await cache.set(\"user:1\", user, \"1h\");\r\n *\r\n * @example\r\n * // Rich options\r\n * await cache.set(\"user:1\", user, { ttl: \"1h\", tags: [\"users\"], onConflict: \"create\" });\r\n */\r\n set(\r\n key: CacheKey,\r\n value: any,\r\n ttlOrOptions?: CacheTtl | CacheSetOptions,\r\n ): Promise<any>;\r\n /**\r\n * Get a value from the cache\r\n */\r\n get<T = any>(key: CacheKey): Promise<T | null>;\r\n /**\r\n * Remove a value from the cache\r\n */\r\n remove(key: CacheKey): Promise<void>;\r\n /**\r\n * Flush the entire cache\r\n */\r\n flush(): Promise<void>;\r\n /**\r\n * Connect to the cache driver\r\n */\r\n connect(): Promise<any>;\r\n /**\r\n * The cache client\r\n */\r\n client?: ClientType;\r\n /**\r\n * Disconnect the cache driver\r\n */\r\n disconnect(): Promise<void>;\r\n /**\r\n * Check if a key exists in the cache without fetching its value\r\n */\r\n has(key: CacheKey): Promise<boolean>;\r\n /**\r\n * Get value from cache or execute callback and cache the result.\r\n *\r\n * The second argument accepts a TTL (number of seconds or duration string like `\"1h\"`)\r\n * or a full {@link RememberOptions} object when you need to attach tags or route to\r\n * a non-default driver.\r\n *\r\n * @example\r\n * // Positional TTL — the common case\r\n * const user = await cache.remember(\"user.1\", \"1h\", () => db.users.find(1));\r\n *\r\n * @example\r\n * // Options form — tag the cache-miss write for bulk invalidation\r\n * const user = await cache.remember(\"user.1\", { ttl: \"1h\", tags: [\"users\"] }, () =>\r\n * db.users.find(1),\r\n * );\r\n */\r\n remember<T = any>(\r\n key: CacheKey,\r\n ttlOrOptions: CacheTtl | RememberOptions,\r\n callback: () => Promise<T>,\r\n ): Promise<T>;\r\n /**\r\n * Stale-while-revalidate. Returns the cached value when fresh; returns\r\n * the stale value + kicks off a background refresh when within the\r\n * `freshTtl..staleTtl` window; blocks like a normal miss when past\r\n * `staleTtl`. Concurrent stale-window callers share one in-flight\r\n * refresh.\r\n *\r\n * Background refresh failures preserve the stale entry and emit an\r\n * `error` event — the stale-returning caller never sees the failure.\r\n *\r\n * @example\r\n * const product = await cache.swr(\r\n * \"product.42\",\r\n * { freshTtl: \"1m\", staleTtl: \"1h\" },\r\n * () => db.products.find(42),\r\n * );\r\n */\r\n swr<T = any>(\r\n key: CacheKey,\r\n options: CacheSwrOptions,\r\n callback: () => Promise<T>,\r\n ): Promise<T>;\r\n /**\r\n * Get value and remove it from cache (atomic operation)\r\n */\r\n pull<T = any>(key: CacheKey): Promise<T | null>;\r\n /**\r\n * Set a value in cache permanently (no expiration)\r\n */\r\n forever<T = any>(key: CacheKey, value: T): Promise<T>;\r\n /**\r\n * Atomically read, transform, and write a cached value.\r\n *\r\n * The callback receives the current value (or `null` on miss) and returns the\r\n * next value. Returning `null` removes the key. TTL is preserved unless\r\n * explicitly overridden via options.\r\n *\r\n * @example\r\n * await cache.update<User>(\"user:1\", (current) => {\r\n * if (!current) return null;\r\n * return { ...current, lastSeen: Date.now() };\r\n * });\r\n */\r\n update<T = any>(\r\n key: CacheKey,\r\n fn: (current: T | null) => T | null | Promise<T | null>,\r\n options?: { ttl?: CacheTtl },\r\n ): Promise<T | null>;\r\n /**\r\n * Shallow-merge a partial object into a cached value.\r\n *\r\n * If the key is missing, treats the current value as `{}`. Preserves TTL by default.\r\n *\r\n * @example\r\n * await cache.merge<User>(\"user:1\", { name: \"Jane\" });\r\n */\r\n merge<T extends Record<string, any> = Record<string, any>>(\r\n key: CacheKey,\r\n partial: Partial<T>,\r\n options?: { ttl?: CacheTtl },\r\n ): Promise<T>;\r\n /**\r\n * List sub-API factory — returns a {@link CacheListAccessor} bound to the given key.\r\n *\r\n * @example\r\n * const recent = cache.list<Event>(\"recent-events\");\r\n * await recent.push(event);\r\n * const last10 = await recent.slice(0, 10);\r\n */\r\n list<T = any>(key: CacheKey): CacheListAccessor<T>;\r\n /**\r\n * Acquire a distributed lock, run `fn`, and auto-release. Returns a\r\n * {@link LockOutcome} so callers can distinguish \"ran and produced this value\"\r\n * from \"skipped because someone else holds the lock.\"\r\n *\r\n * Built on top of `set({ onConflict: \"create\" })` — Redis-native, emulated\r\n * on other drivers (single-process semantics elsewhere).\r\n *\r\n * @example\r\n * const outcome = await cache.lock(\"lock.import\", \"5m\", async () => {\r\n * await runImport();\r\n * return \"done\";\r\n * });\r\n */\r\n lock<T>(\r\n key: CacheKey,\r\n ttlOrOptions: CacheTtl | Omit<LockOptions, \"driver\">,\r\n fn: () => Promise<T>,\r\n ): Promise<LockOutcome<T>>;\r\n /**\r\n * Increment a numeric value in cache\r\n *\r\n * @param key The cache key\r\n * @param value The value to increment by (default 1)\r\n */\r\n increment(key: CacheKey, value?: number): Promise<number>;\r\n /**\r\n * Decrement a numeric value in cache\r\n *\r\n * @param key The cache key\r\n * @param value The value to decrement by (default 1)\r\n */\r\n decrement(key: CacheKey, value?: number): Promise<number>;\r\n /**\r\n * Get multiple values from cache at once\r\n */\r\n many(keys: CacheKey[]): Promise<any[]>;\r\n /**\r\n * Set multiple values in cache at once\r\n */\r\n setMany(items: Record<string, any>, ttl?: number): Promise<void>;\r\n /**\r\n * Register an event listener\r\n */\r\n on(event: CacheEventType, handler: CacheEventHandler): this;\r\n /**\r\n * Remove an event listener\r\n */\r\n off(event: CacheEventType, handler: CacheEventHandler): this;\r\n /**\r\n * Register a one-time event listener\r\n */\r\n once(event: CacheEventType, handler: CacheEventHandler): this;\r\n /**\r\n * Set if not exists (atomic operation)\r\n * Returns true if key was set, false if key already existed\r\n * Note: Not all drivers support this operation\r\n */\r\n setNX?(key: CacheKey, value: any, ttl?: number): Promise<boolean>;\r\n /**\r\n * Create a tagged cache instance for the given tags\r\n */\r\n tags(tags: string[]): TaggedCacheDriver;\r\n /**\r\n * Similarity retrieval. Returns the nearest stored entries to `vector` by\r\n * cosine similarity, ordered by descending score.\r\n *\r\n * Drivers without a similarity index throw {@link CacheUnsupportedError}.\r\n * Memory-family drivers brute-force scan in O(N) — suitable for development\r\n * but not for production knowledge bases beyond a few thousand entries; use\r\n * the `pg` driver (with pgvector) or `redis` driver (with RediSearch) instead.\r\n *\r\n * @example\r\n * const hits = await cache.similar(await embed(query), { topK: 5, threshold: 0.7 });\r\n */\r\n similar<T = any>(\r\n vector: number[],\r\n options: CacheSimilarOptions,\r\n ): Promise<CacheSimilarHit<T>[]>;\r\n}\r\n\r\n/**\r\n * Accessor for list-shaped cached values.\r\n *\r\n * Defaults to read-mutate-write semantics on non-native drivers (memory, file, LRU).\r\n * The Redis driver overrides this with native `LPUSH` / `RPUSH` / `LRANGE` / `LTRIM` for O(1) ops.\r\n */\r\nexport interface CacheListAccessor<T = any> {\r\n /**\r\n * Append one or more items to the tail of the list. Returns the new length.\r\n */\r\n push(...items: T[]): Promise<number>;\r\n /**\r\n * Prepend one or more items to the head of the list. Returns the new length.\r\n */\r\n unshift(...items: T[]): Promise<number>;\r\n /**\r\n * Remove and return the tail item, or `null` if the list is empty.\r\n */\r\n pop(): Promise<T | null>;\r\n /**\r\n * Remove and return the head item, or `null` if the list is empty.\r\n */\r\n shift(): Promise<T | null>;\r\n /**\r\n * Return a slice of the list. End is exclusive, mirroring `Array.prototype.slice`.\r\n */\r\n slice(start?: number, end?: number): Promise<T[]>;\r\n /**\r\n * Return the full list.\r\n */\r\n all(): Promise<T[]>;\r\n /**\r\n * Return the length of the list.\r\n */\r\n length(): Promise<number>;\r\n /**\r\n * Trim the list to the inclusive range `[start, end]`. Outside elements are dropped.\r\n */\r\n trim(start: number, end: number): Promise<void>;\r\n /**\r\n * Remove the entire list.\r\n */\r\n clear(): Promise<void>;\r\n}\r\n\r\n/**\r\n * One-shot tagged handle returned by `ScopedCacheContract.tags(...)`.\r\n *\r\n * Identical write surface to {@link TaggedCacheDriver}, except the underlying\r\n * scope's prefix is applied to every key and the scope's default TTL/tags\r\n * still flow through. Tags supplied here merge additively with scope-level\r\n * tags.\r\n */\r\nexport interface TaggedScopedCacheContract {\r\n set(key: CacheKey, value: any, ttlOrOptions?: CacheTtl | CacheSetOptions): Promise<any>;\r\n get<T = any>(key: CacheKey): Promise<T | null>;\r\n has(key: CacheKey): Promise<boolean>;\r\n remove(key: CacheKey): Promise<void>;\r\n pull<T = any>(key: CacheKey): Promise<T | null>;\r\n forever<T = any>(key: CacheKey, value: T): Promise<T>;\r\n setNX(key: CacheKey, value: any, ttl?: number): Promise<boolean>;\r\n remember<T = any>(\r\n key: CacheKey,\r\n ttlOrOptions: CacheTtl | RememberOptions,\r\n callback: () => Promise<T>,\r\n ): Promise<T>;\r\n increment(key: CacheKey, value?: number): Promise<number>;\r\n decrement(key: CacheKey, value?: number): Promise<number>;\r\n /**\r\n * Invalidate every entry tagged with the union of scope tags + handle tags.\r\n * Forwarded to the underlying tag index — tags are global, scope-agnostic.\r\n */\r\n invalidate(): Promise<void>;\r\n}\r\n\r\n/**\r\n * Scoped view over the cache. Returned by `cache.namespace(prefix, options?)`.\r\n *\r\n * A scope prepends its `prefix` to every key, applies optional default TTL/tags\r\n * to every write, and forwards everything else to the underlying source. It\r\n * stores nothing of its own — purely a convenience wrapper.\r\n *\r\n * @example\r\n * const chat = cache.namespace(\"chats.10\", { ttl: \"30d\" });\r\n * await chat.set(\"messages.1\", msg); // → \"chats.10.messages.1\", TTL 30d\r\n * await chat.set(\"draft\", d, { ttl: \"1h\" }); // per-call ttl wins\r\n * await chat.clear(); // wipe the whole scope\r\n */\r\nexport interface ScopedCacheContract {\r\n /** The fully-qualified prefix this scope prepends to every key. */\r\n readonly prefix: string;\r\n\r\n /**\r\n * Nested scope. Inherits the parent's defaults; child's own options override.\r\n *\r\n * @example\r\n * const chat = cache.namespace(\"chats.10\", { ttl: \"30d\" });\r\n * const typing = chat.namespace(\"typing\", { ttl: \"5s\" });\r\n * // typing.prefix === \"chats.10.typing\"\r\n */\r\n namespace(prefix: string, options?: CacheNamespaceOptions): ScopedCacheContract;\r\n\r\n /**\r\n * One-shot tagged write handle. Tags merge additively with scope defaults.\r\n */\r\n tags(tags: string[]): TaggedScopedCacheContract;\r\n\r\n /** Wipe every entry under this scope's prefix. Sugar for `removeNamespace(prefix)`. */\r\n clear(): Promise<void>;\r\n\r\n // Reads\r\n get<T = any>(key: CacheKey): Promise<T | null>;\r\n has(key: CacheKey): Promise<boolean>;\r\n many(keys: CacheKey[]): Promise<any[]>;\r\n pull<T = any>(key: CacheKey): Promise<T | null>;\r\n\r\n // Writes\r\n set(key: CacheKey, value: any, ttlOrOptions?: CacheTtl | CacheSetOptions): Promise<any>;\r\n setMany(items: Record<string, any>, ttl?: number): Promise<void>;\r\n setNX(key: CacheKey, value: any, ttl?: number): Promise<boolean>;\r\n forever<T = any>(key: CacheKey, value: T): Promise<T>;\r\n remove(key: CacheKey): Promise<void>;\r\n\r\n // Read-or-compute\r\n remember<T = any>(\r\n key: CacheKey,\r\n ttlOrOptions: CacheTtl | RememberOptions,\r\n callback: () => Promise<T>,\r\n ): Promise<T>;\r\n swr<T = any>(\r\n key: CacheKey,\r\n options: CacheSwrOptions,\r\n callback: () => Promise<T>,\r\n ): Promise<T>;\r\n\r\n // Mutations\r\n increment(key: CacheKey, value?: number): Promise<number>;\r\n decrement(key: CacheKey, value?: number): Promise<number>;\r\n update<T = any>(\r\n key: CacheKey,\r\n fn: (current: T | null) => T | null | Promise<T | null>,\r\n options?: { ttl?: CacheTtl },\r\n ): Promise<T | null>;\r\n merge<T extends Record<string, any> = Record<string, any>>(\r\n key: CacheKey,\r\n partial: Partial<T>,\r\n options?: { ttl?: CacheTtl },\r\n ): Promise<T>;\r\n\r\n // Structured accessors\r\n list<T = any>(key: CacheKey): CacheListAccessor<T>;\r\n\r\n // Coordination\r\n lock<T>(\r\n key: CacheKey,\r\n ttlOrOptions: CacheTtl | Omit<LockOptions, \"driver\">,\r\n fn: () => Promise<T>,\r\n ): Promise<LockOutcome<T>>;\r\n\r\n // Similarity (delegated; throws CacheUnsupportedError if the driver lacks it)\r\n similar<T = any>(\r\n vector: number[],\r\n options: CacheSimilarOptions,\r\n ): Promise<CacheSimilarHit<T>[]>;\r\n}\r\n\r\nexport type CacheData = {\r\n /**\r\n * Value stored in the cache\r\n */\r\n data: any;\r\n /**\r\n * The expiration date in milliseconds\r\n */\r\n expiresAt?: number;\r\n /**\r\n * Time to live in seconds\r\n */\r\n ttl?: number;\r\n /**\r\n * Freshness deadline as a millisecond timestamp. Used by `swr()` — entries\r\n * with `staleAt` in the future are \"fresh\"; past `staleAt` but before\r\n * `expiresAt` are \"stale-but-revalidatable\" and trigger a background\r\n * refresh on the next read. Optional — entries written through plain\r\n * `set()` skip this field entirely and `swr()` treats them as always-fresh.\r\n */\r\n staleAt?: number;\r\n};\r\n\r\nexport type DriverClass = new () => CacheDriver<any, any>;\r\n\r\ntype DefaultDrivers =\r\n | \"redis\"\r\n | \"file\"\r\n | \"memory\"\r\n | \"memoryExtended\"\r\n | \"null\"\r\n | \"lru\"\r\n | \"pg\"\r\n | \"mock\";\r\n\r\ntype MergeWithDefaultDrivers<T> = T extends undefined ? DefaultDrivers : DefaultDrivers | T;\r\n\r\nexport type CacheConfigurations<\r\n T extends string | undefined = undefined,\r\n DriverName = MergeWithDefaultDrivers<T>,\r\n> = {\r\n /**\r\n * The default cache driver name\r\n */\r\n default?: DriverName;\r\n /**\r\n * Determine whether to log or not\r\n *\r\n * @default true\r\n */\r\n logging?: boolean;\r\n /**\r\n * The cache drivers list\r\n */\r\n drivers: {\r\n redis?: typeof RedisCacheDriver;\r\n file?: typeof FileCacheDriver;\r\n null?: typeof NullCacheDriver;\r\n memory?: typeof MemoryCacheDriver;\r\n memoryExtended?: typeof MemoryExtendedCacheDriver;\r\n lru?: typeof LRUMemoryCacheDriver;\r\n pg?: typeof PgCacheDriver;\r\n mock?: typeof MockCacheDriver;\r\n } & {\r\n [key in Extract<T, string>]?: typeof BaseCacheDriver<any, any> | undefined;\r\n };\r\n /**\r\n * The cache driver options\r\n */\r\n options: {\r\n redis?: RedisOptions;\r\n file?: FileCacheOptions;\r\n memory?: MemoryCacheOptions;\r\n memoryExtended?: MemoryExtendedCacheOptions;\r\n null?: NullCacheDriverOptions;\r\n lru?: LRUMemoryCacheOptions;\r\n pg?: PgCacheOptions;\r\n mock?: MockCacheOptions;\r\n } & {\r\n [key in Extract<T, string>]?: GenericObject;\r\n };\r\n};\r\n"],"mappings":";;;;AAiBA,IAAa,aAAb,cAAgC,MAAM;CACpC,AAAO,YAAY,SAAiB;EAClC,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,uBAAb,cAA0C,WAAW;CACnD,AAAO,YAAY,SAAiB;EAClC,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,0BAAb,cAA6C,WAAW;CACtD,AAAO,YAAY,SAAiB;EAClC,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,iCAAb,cAAoD,WAAW;CAC7D,AAAO,YACL,UAAkB,wEAClB;EACA,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;;;;AAQA,IAAa,wBAAb,cAA2C,WAAW;CACpD,AAAO,YAAY,SAAiB;EAClC,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;AAKA,IAAa,wBAAb,cAA2C,WAAW;CACpD,AAAO,YAAY,SAAiB;EAClC,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF"}
package/esm/utils.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { CacheKey, CacheSetOptions, CacheTtl, RememberOptions } from "./types.mjs";
2
2
 
3
- //#region ../../@warlock.js/cache/src/utils.d.ts
3
+ //#region ../@warlock.js/cache/src/utils.d.ts
4
4
  /**
5
5
  * Make a proper key for the cache
6
6
  */
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.mts","names":[],"sources":["../../../../../@warlock.js/cache/src/utils.ts"],"mappings":";;;;;AAQA;iBAAgB,aAAA,CACd,GAAA,EAAK,QAAQ,EACb,OAAA;EAAW,YAAA;AAAA;;;;;;AAA6C;AA+B1D;;;;AAAwC;AAsCxC;;;;AAAuD;iBAtCvC,QAAA,CAAS,KAAe,EAAR,QAAQ;;;;;;;;;;;;;iBAsCxB,cAAA,CAAe,SAAwB,WAAJ,IAAI;AA+CvD;;;;;;;;;AAAA,iBAzBgB,kBAAA,CACd,KAAA,GAAQ,QAAA,GAAW,eAAA,GAClB,eAAA;;;;AAyBe;AAuBlB;;;;;;;iBAzBgB,0BAAA,CACd,KAAA,GAAQ,QAAA,GAAW,eAAA,GAClB,eAAA;;;AA0Be;AAiClB;;;;AACU;AA4BV;;;iBAjEgB,UAAA,CACd,GAAA,EAAK,QAAA,cACL,SAAA,WAAoB,IAAI,cACxB,QAAA;;;;;;;;AAiEE;AA0BJ;;;;AAAyD;AAgCzD;iBA1FgB,YAAA,CAAA,GACX,KAAK;;;;;;;;;;iBA4BM,UAAA;EAAuB,IAAA;AAAA,EAAA,CACrC,OAAA,EAAS,CAAA,EACT,SAAA,aACC,CAAC;;AAkGM;;;;;;;;;;;;;;iBAxEM,gBAAA,CAAiB,CAAA,YAAa,CAAW;AAAA,aAgC7C,SAAA;;;;EAIV,SAAA;;;;EAIA,QAAA;;;;EAIA,QAAA;;;;EAIA,OAAA;;;;EAIA,QAAA;;;;EAIA,UAAA;;;;EAIA,SAAA;;;;EAIA,UAAA;;;;EAIA,UAAA;;;;EAIA,QAAA;AAAA"}
1
+ {"version":3,"file":"utils.d.mts","names":[],"sources":["../../../../../../@warlock.js/cache/src/utils.ts"],"mappings":";;;;;AAQA;iBAAgB,aAAA,CACd,GAAA,EAAK,QAAQ,EACb,OAAA;EAAW,YAAA;AAAA;;;;;;AAA6C;AA+B1D;;;;AAAwC;AAsCxC;;;;AAAuD;iBAtCvC,QAAA,CAAS,KAAe,EAAR,QAAQ;;;;;;;;;;;;;iBAsCxB,cAAA,CAAe,SAAwB,WAAJ,IAAI;AA+CvD;;;;;;;;;AAAA,iBAzBgB,kBAAA,CACd,KAAA,GAAQ,QAAA,GAAW,eAAA,GAClB,eAAA;;;;AAyBe;AAuBlB;;;;;;;iBAzBgB,0BAAA,CACd,KAAA,GAAQ,QAAA,GAAW,eAAA,GAClB,eAAA;;;AA0Be;AAiClB;;;;AACU;AA4BV;;;iBAjEgB,UAAA,CACd,GAAA,EAAK,QAAA,cACL,SAAA,WAAoB,IAAI,cACxB,QAAA;;;;;;;;AAiEE;AA0BJ;;;;AAAyD;AAgCzD;iBA1FgB,YAAA,IACX,KAAK;;;;;;;;;;iBA4BM,UAAA;EAAuB,IAAA;AAAA,GACrC,OAAA,EAAS,CAAA,EACT,SAAA,aACC,CAAC;;AAkGM;;;;;;;;;;;;;;iBAxEM,gBAAA,CAAiB,CAAA,YAAa,CAAW;AAAA,aAgC7C,SAAA;;;;EAIV,SAAA;;;;EAIA,QAAA;;;;EAIA,QAAA;;;;EAIA,OAAA;;;;EAIA,QAAA;;;;EAIA,UAAA;;;;EAIA,SAAA;;;;EAIA,UAAA;;;;EAIA,UAAA;;;;EAIA,QAAA;AAAA"}
package/esm/utils.mjs CHANGED
@@ -2,7 +2,7 @@ import { CacheConfigurationError } from "./types.mjs";
2
2
  import { rtrim } from "@mongez/reinforcements";
3
3
  import ms from "ms";
4
4
 
5
- //#region ../../@warlock.js/cache/src/utils.ts
5
+ //#region ../@warlock.js/cache/src/utils.ts
6
6
  /**
7
7
  * Make a proper key for the cache
8
8
  */
package/esm/utils.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.mjs","names":[],"sources":["../../../../../@warlock.js/cache/src/utils.ts"],"sourcesContent":["import { rtrim } from \"@mongez/reinforcements\";\r\nimport ms, { StringValue } from \"ms\";\r\nimport type { CacheKey, CacheSetOptions, CacheTtl, RememberOptions } from \"./types\";\r\nimport { CacheConfigurationError } from \"./types\";\r\n\r\n/**\r\n * Make a proper key for the cache\r\n */\r\nexport function parseCacheKey(\r\n key: CacheKey,\r\n options: { globalPrefix?: string | (() => string) } = {},\r\n): string {\r\n if (typeof key === \"object\") {\r\n key = JSON.stringify(key);\r\n }\r\n\r\n // remove any curly braces and double quotes along with []\r\n key = key.replace(/[{}\"[\\]]/g, \"\").replaceAll(/[:,]/g, \".\");\r\n\r\n const cachePrefix =\r\n typeof options.globalPrefix === \"function\" ? options.globalPrefix() : options.globalPrefix;\r\n\r\n return rtrim(String(cachePrefix ? rtrim(cachePrefix, \".\") + \".\" + key : key), \".\");\r\n}\r\n\r\n/**\r\n * Parse a TTL value into seconds.\r\n *\r\n * Accepts:\r\n * - a number (already in seconds) — returned unchanged\r\n * - `Infinity` — no expiration, returned unchanged\r\n * - a human-readable duration string (e.g. `\"1h\"`, `\"30m\"`, `\"7d\"`) — parsed via `ms` then converted to seconds\r\n *\r\n * Throws `CacheConfigurationError` on unparseable strings or negative numbers.\r\n *\r\n * @example\r\n * parseTtl(3600); // 3600\r\n * parseTtl(\"1h\"); // 3600\r\n * parseTtl(\"7d\"); // 604800\r\n * parseTtl(Infinity); // Infinity\r\n */\r\nexport function parseTtl(input: CacheTtl): number {\r\n if (typeof input === \"number\") {\r\n if (input < 0) {\r\n throw new CacheConfigurationError(`Invalid TTL: negative number (${input}).`);\r\n }\r\n\r\n return input;\r\n }\r\n\r\n if (typeof input !== \"string\" || input.trim() === \"\") {\r\n throw new CacheConfigurationError(\r\n `Invalid TTL: expected number or duration string, got ${typeof input}.`,\r\n );\r\n }\r\n\r\n const milliseconds = ms(input as StringValue);\r\n\r\n if (milliseconds === undefined || Number.isNaN(milliseconds)) {\r\n throw new CacheConfigurationError(\r\n `Invalid TTL duration string: \"${input}\". Expected forms like \"1h\", \"30m\", \"7d\".`,\r\n );\r\n }\r\n\r\n return Math.floor(milliseconds / 1000);\r\n}\r\n\r\n/**\r\n * Convert an absolute `expiresAt` (Date or epoch milliseconds) into a\r\n * relative TTL in seconds.\r\n *\r\n * Throws {@link CacheConfigurationError} when the deadline is in the past —\r\n * the caller almost certainly has a bug (stale timestamp, wrong unit, etc.)\r\n * and silently storing an already-expired entry would hide it.\r\n *\r\n * @example\r\n * expiresAtToTtl(new Date(Date.now() + 60_000)); // ~60\r\n * expiresAtToTtl(Date.now() + 30 * 60 * 1000); // ~1800\r\n */\r\nexport function expiresAtToTtl(expiresAt: number | Date): number {\r\n const deadline = expiresAt instanceof Date ? expiresAt.getTime() : expiresAt;\r\n const relativeMs = deadline - Date.now();\r\n\r\n if (relativeMs <= 0) {\r\n throw new CacheConfigurationError(\r\n `\\`expiresAt\\` must be in the future; got ${new Date(deadline).toISOString()}.`,\r\n );\r\n }\r\n\r\n return Math.ceil(relativeMs / 1000);\r\n}\r\n\r\n/**\r\n * Coerce the polymorphic 3rd `set` argument into a uniform `CacheSetOptions`\r\n * shape. Lets callers (and `BaseCacheDriver.resolveSetOptions`) skip per-shape\r\n * branching.\r\n *\r\n * - `undefined` / `null` → `{}` (resolves to driver-level defaults later)\r\n * - `number` / `string` (positional TTL) → `{ ttl }`\r\n * - already an options object → returned as-is\r\n */\r\nexport function normalizeToOptions(\r\n input?: CacheTtl | CacheSetOptions,\r\n): CacheSetOptions {\r\n if (input === undefined || input === null) {\r\n return {};\r\n }\r\n\r\n if (typeof input === \"number\" || typeof input === \"string\") {\r\n return { ttl: input };\r\n }\r\n\r\n return input;\r\n}\r\n\r\n/**\r\n * Sibling of {@link normalizeToOptions} for the `remember()` call site, where\r\n * the polymorphic 2nd argument is `CacheTtl | RememberOptions` (no `expiresAt`,\r\n * no `onConflict`). Returns the same shape so callers can `{ ...opts, ... }`\r\n * without branching.\r\n *\r\n * @example\r\n * normalizeToRememberOptions(60); // { ttl: 60 }\r\n * normalizeToRememberOptions(\"1h\"); // { ttl: \"1h\" }\r\n * normalizeToRememberOptions({ ttl: \"1h\", tags: [\"x\"] }); // returned as-is\r\n */\r\nexport function normalizeToRememberOptions(\r\n input?: CacheTtl | RememberOptions,\r\n): RememberOptions {\r\n if (input === undefined || input === null) {\r\n return {};\r\n }\r\n\r\n if (typeof input === \"number\" || typeof input === \"string\") {\r\n return { ttl: input };\r\n }\r\n\r\n return input;\r\n}\r\n\r\n/**\r\n * Resolve the final TTL in seconds for a `set` call. Precedence:\r\n *\r\n * 1. Caller's `ttl` (number or duration string) wins.\r\n * 2. Otherwise, caller's `expiresAt` is converted to relative seconds.\r\n * 3. Otherwise, `fallback` is used (driver-level default — typically\r\n * `Infinity` when no default is configured, meaning \"never expires\").\r\n *\r\n * Throws {@link CacheConfigurationError} when `ttl` and `expiresAt` are\r\n * supplied together (mutually exclusive).\r\n */\r\nexport function resolveTtl(\r\n ttl: CacheTtl | undefined,\r\n expiresAt: number | Date | undefined,\r\n fallback: number,\r\n): number {\r\n if (ttl !== undefined && expiresAt !== undefined) {\r\n throw new CacheConfigurationError(\r\n \"Cache set options cannot specify both `ttl` and `expiresAt` — choose one.\",\r\n );\r\n }\r\n\r\n if (ttl !== undefined) {\r\n return parseTtl(ttl);\r\n }\r\n\r\n if (expiresAt !== undefined) {\r\n return expiresAtToTtl(expiresAt);\r\n }\r\n\r\n return fallback;\r\n}\r\n\r\n/**\r\n * Combine any number of tag lists into a single deduped array, dropping\r\n * `undefined`/empty entries. Returns `undefined` when no tags survive — lets\r\n * callers skip emitting empty `tags: []` into option payloads.\r\n *\r\n * Used by scoped-cache merging where scope tags + handle tags + per-call tags\r\n * must union additively without duplicates.\r\n *\r\n * @example\r\n * mergeTagSets([\"a\", \"b\"], [\"b\", \"c\"]); // [\"a\", \"b\", \"c\"]\r\n * mergeTagSets(undefined, [\"x\"]); // [\"x\"]\r\n * mergeTagSets(undefined, undefined); // undefined\r\n * mergeTagSets([], []); // undefined\r\n */\r\nexport function mergeTagSets(\r\n ...lists: (string[] | undefined)[]\r\n): string[] | undefined {\r\n const flat: string[] = [];\r\n\r\n for (const list of lists) {\r\n if (!list || list.length === 0) {\r\n continue;\r\n }\r\n\r\n flat.push(...list);\r\n }\r\n\r\n if (flat.length === 0) {\r\n return undefined;\r\n }\r\n\r\n return Array.from(new Set(flat));\r\n}\r\n\r\n/**\r\n * Add extra tags to any option-bag that already shapes `tags?: string[]`.\r\n * Pure — clones the input shape, never mutates. Tags are appended (caller\r\n * is responsible for de-duplication if needed; pair with {@link mergeTagSets}).\r\n *\r\n * @example\r\n * injectTags({ ttl: \"1h\" }, [\"unread\"]); // { ttl: \"1h\", tags: [\"unread\"] }\r\n * injectTags({ tags: [\"a\"] }, [\"b\"]); // { tags: [\"a\", \"b\"] }\r\n */\r\nexport function injectTags<T extends { tags?: string[] }>(\r\n options: T,\r\n extraTags: string[],\r\n): T {\r\n if (extraTags.length === 0) {\r\n return options;\r\n }\r\n\r\n return {\r\n ...options,\r\n tags: [...(options.tags ?? []), ...extraTags],\r\n };\r\n}\r\n\r\n/**\r\n * Cosine similarity between two equal-length numeric vectors.\r\n *\r\n * Returns a value in `[-1, 1]` where `1` means perfectly aligned, `0` means\r\n * orthogonal, and `-1` means opposing. For typical embedding spaces (where\r\n * vectors live in the positive cone) the practical range is `[0, 1]`.\r\n *\r\n * Throws {@link CacheConfigurationError} on dimension mismatch — fail loud at\r\n * the call site rather than silently returning a misleading score. A zero-norm\r\n * vector on either side returns `0` (no defined direction to compare).\r\n *\r\n * @example\r\n * cosineSimilarity([1, 0, 0], [1, 0, 0]); // 1\r\n * cosineSimilarity([1, 0, 0], [0, 1, 0]); // 0\r\n */\r\nexport function cosineSimilarity(a: number[], b: number[]): number {\r\n if (a.length !== b.length) {\r\n throw new CacheConfigurationError(\r\n `Vector dimension mismatch: got ${a.length} and ${b.length}.`,\r\n );\r\n }\r\n\r\n if (a.length === 0) {\r\n throw new CacheConfigurationError(\r\n \"Vector dimension mismatch: empty vector cannot be compared.\",\r\n );\r\n }\r\n\r\n let dot = 0;\r\n let normA = 0;\r\n let normB = 0;\r\n\r\n for (let i = 0; i < a.length; i++) {\r\n const x = a[i];\r\n const y = b[i];\r\n dot += x * y;\r\n normA += x * x;\r\n normB += y * y;\r\n }\r\n\r\n if (normA === 0 || normB === 0) {\r\n return 0;\r\n }\r\n\r\n return dot / (Math.sqrt(normA) * Math.sqrt(normB));\r\n}\r\n\r\nexport enum CACHE_FOR {\r\n /**\r\n * Cache for 30 Minutes (in seconds)\r\n */\r\n HALF_HOUR = 1800,\r\n /**\r\n * Cache for 1 Hour (in seconds)\r\n */\r\n ONE_HOUR = 3600,\r\n /**\r\n * Cache for 12 Hours (in seconds)\r\n */\r\n HALF_DAY = 43200,\r\n /**\r\n * Cache for 24 Hours (in seconds)\r\n */\r\n ONE_DAY = 86400,\r\n /**\r\n * Cache for 7 Days (in seconds)\r\n */\r\n ONE_WEEK = 604800,\r\n /**\r\n * Cache for 15 Days (in seconds)\r\n */\r\n HALF_MONTH = 1296000,\r\n /**\r\n * Cache for 30 Days (in seconds)\r\n */\r\n ONE_MONTH = 2592000,\r\n /**\r\n * Cache for 60 Days (in seconds)\r\n */\r\n TWO_MONTHS = 5184000,\r\n /**\r\n * Cache for 180 Days (in seconds)\r\n */\r\n SIX_MONTHS = 15768000,\r\n /**\r\n * Cache for 365 Days (in seconds)\r\n */\r\n ONE_YEAR = 31536000,\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../../../../../../@warlock.js/cache/src/utils.ts"],"sourcesContent":["import { rtrim } from \"@mongez/reinforcements\";\r\nimport ms, { StringValue } from \"ms\";\r\nimport type { CacheKey, CacheSetOptions, CacheTtl, RememberOptions } from \"./types\";\r\nimport { CacheConfigurationError } from \"./types\";\r\n\r\n/**\r\n * Make a proper key for the cache\r\n */\r\nexport function parseCacheKey(\r\n key: CacheKey,\r\n options: { globalPrefix?: string | (() => string) } = {},\r\n): string {\r\n if (typeof key === \"object\") {\r\n key = JSON.stringify(key);\r\n }\r\n\r\n // remove any curly braces and double quotes along with []\r\n key = key.replace(/[{}\"[\\]]/g, \"\").replaceAll(/[:,]/g, \".\");\r\n\r\n const cachePrefix =\r\n typeof options.globalPrefix === \"function\" ? options.globalPrefix() : options.globalPrefix;\r\n\r\n return rtrim(String(cachePrefix ? rtrim(cachePrefix, \".\") + \".\" + key : key), \".\");\r\n}\r\n\r\n/**\r\n * Parse a TTL value into seconds.\r\n *\r\n * Accepts:\r\n * - a number (already in seconds) — returned unchanged\r\n * - `Infinity` — no expiration, returned unchanged\r\n * - a human-readable duration string (e.g. `\"1h\"`, `\"30m\"`, `\"7d\"`) — parsed via `ms` then converted to seconds\r\n *\r\n * Throws `CacheConfigurationError` on unparseable strings or negative numbers.\r\n *\r\n * @example\r\n * parseTtl(3600); // 3600\r\n * parseTtl(\"1h\"); // 3600\r\n * parseTtl(\"7d\"); // 604800\r\n * parseTtl(Infinity); // Infinity\r\n */\r\nexport function parseTtl(input: CacheTtl): number {\r\n if (typeof input === \"number\") {\r\n if (input < 0) {\r\n throw new CacheConfigurationError(`Invalid TTL: negative number (${input}).`);\r\n }\r\n\r\n return input;\r\n }\r\n\r\n if (typeof input !== \"string\" || input.trim() === \"\") {\r\n throw new CacheConfigurationError(\r\n `Invalid TTL: expected number or duration string, got ${typeof input}.`,\r\n );\r\n }\r\n\r\n const milliseconds = ms(input as StringValue);\r\n\r\n if (milliseconds === undefined || Number.isNaN(milliseconds)) {\r\n throw new CacheConfigurationError(\r\n `Invalid TTL duration string: \"${input}\". Expected forms like \"1h\", \"30m\", \"7d\".`,\r\n );\r\n }\r\n\r\n return Math.floor(milliseconds / 1000);\r\n}\r\n\r\n/**\r\n * Convert an absolute `expiresAt` (Date or epoch milliseconds) into a\r\n * relative TTL in seconds.\r\n *\r\n * Throws {@link CacheConfigurationError} when the deadline is in the past —\r\n * the caller almost certainly has a bug (stale timestamp, wrong unit, etc.)\r\n * and silently storing an already-expired entry would hide it.\r\n *\r\n * @example\r\n * expiresAtToTtl(new Date(Date.now() + 60_000)); // ~60\r\n * expiresAtToTtl(Date.now() + 30 * 60 * 1000); // ~1800\r\n */\r\nexport function expiresAtToTtl(expiresAt: number | Date): number {\r\n const deadline = expiresAt instanceof Date ? expiresAt.getTime() : expiresAt;\r\n const relativeMs = deadline - Date.now();\r\n\r\n if (relativeMs <= 0) {\r\n throw new CacheConfigurationError(\r\n `\\`expiresAt\\` must be in the future; got ${new Date(deadline).toISOString()}.`,\r\n );\r\n }\r\n\r\n return Math.ceil(relativeMs / 1000);\r\n}\r\n\r\n/**\r\n * Coerce the polymorphic 3rd `set` argument into a uniform `CacheSetOptions`\r\n * shape. Lets callers (and `BaseCacheDriver.resolveSetOptions`) skip per-shape\r\n * branching.\r\n *\r\n * - `undefined` / `null` → `{}` (resolves to driver-level defaults later)\r\n * - `number` / `string` (positional TTL) → `{ ttl }`\r\n * - already an options object → returned as-is\r\n */\r\nexport function normalizeToOptions(\r\n input?: CacheTtl | CacheSetOptions,\r\n): CacheSetOptions {\r\n if (input === undefined || input === null) {\r\n return {};\r\n }\r\n\r\n if (typeof input === \"number\" || typeof input === \"string\") {\r\n return { ttl: input };\r\n }\r\n\r\n return input;\r\n}\r\n\r\n/**\r\n * Sibling of {@link normalizeToOptions} for the `remember()` call site, where\r\n * the polymorphic 2nd argument is `CacheTtl | RememberOptions` (no `expiresAt`,\r\n * no `onConflict`). Returns the same shape so callers can `{ ...opts, ... }`\r\n * without branching.\r\n *\r\n * @example\r\n * normalizeToRememberOptions(60); // { ttl: 60 }\r\n * normalizeToRememberOptions(\"1h\"); // { ttl: \"1h\" }\r\n * normalizeToRememberOptions({ ttl: \"1h\", tags: [\"x\"] }); // returned as-is\r\n */\r\nexport function normalizeToRememberOptions(\r\n input?: CacheTtl | RememberOptions,\r\n): RememberOptions {\r\n if (input === undefined || input === null) {\r\n return {};\r\n }\r\n\r\n if (typeof input === \"number\" || typeof input === \"string\") {\r\n return { ttl: input };\r\n }\r\n\r\n return input;\r\n}\r\n\r\n/**\r\n * Resolve the final TTL in seconds for a `set` call. Precedence:\r\n *\r\n * 1. Caller's `ttl` (number or duration string) wins.\r\n * 2. Otherwise, caller's `expiresAt` is converted to relative seconds.\r\n * 3. Otherwise, `fallback` is used (driver-level default — typically\r\n * `Infinity` when no default is configured, meaning \"never expires\").\r\n *\r\n * Throws {@link CacheConfigurationError} when `ttl` and `expiresAt` are\r\n * supplied together (mutually exclusive).\r\n */\r\nexport function resolveTtl(\r\n ttl: CacheTtl | undefined,\r\n expiresAt: number | Date | undefined,\r\n fallback: number,\r\n): number {\r\n if (ttl !== undefined && expiresAt !== undefined) {\r\n throw new CacheConfigurationError(\r\n \"Cache set options cannot specify both `ttl` and `expiresAt` — choose one.\",\r\n );\r\n }\r\n\r\n if (ttl !== undefined) {\r\n return parseTtl(ttl);\r\n }\r\n\r\n if (expiresAt !== undefined) {\r\n return expiresAtToTtl(expiresAt);\r\n }\r\n\r\n return fallback;\r\n}\r\n\r\n/**\r\n * Combine any number of tag lists into a single deduped array, dropping\r\n * `undefined`/empty entries. Returns `undefined` when no tags survive — lets\r\n * callers skip emitting empty `tags: []` into option payloads.\r\n *\r\n * Used by scoped-cache merging where scope tags + handle tags + per-call tags\r\n * must union additively without duplicates.\r\n *\r\n * @example\r\n * mergeTagSets([\"a\", \"b\"], [\"b\", \"c\"]); // [\"a\", \"b\", \"c\"]\r\n * mergeTagSets(undefined, [\"x\"]); // [\"x\"]\r\n * mergeTagSets(undefined, undefined); // undefined\r\n * mergeTagSets([], []); // undefined\r\n */\r\nexport function mergeTagSets(\r\n ...lists: (string[] | undefined)[]\r\n): string[] | undefined {\r\n const flat: string[] = [];\r\n\r\n for (const list of lists) {\r\n if (!list || list.length === 0) {\r\n continue;\r\n }\r\n\r\n flat.push(...list);\r\n }\r\n\r\n if (flat.length === 0) {\r\n return undefined;\r\n }\r\n\r\n return Array.from(new Set(flat));\r\n}\r\n\r\n/**\r\n * Add extra tags to any option-bag that already shapes `tags?: string[]`.\r\n * Pure — clones the input shape, never mutates. Tags are appended (caller\r\n * is responsible for de-duplication if needed; pair with {@link mergeTagSets}).\r\n *\r\n * @example\r\n * injectTags({ ttl: \"1h\" }, [\"unread\"]); // { ttl: \"1h\", tags: [\"unread\"] }\r\n * injectTags({ tags: [\"a\"] }, [\"b\"]); // { tags: [\"a\", \"b\"] }\r\n */\r\nexport function injectTags<T extends { tags?: string[] }>(\r\n options: T,\r\n extraTags: string[],\r\n): T {\r\n if (extraTags.length === 0) {\r\n return options;\r\n }\r\n\r\n return {\r\n ...options,\r\n tags: [...(options.tags ?? []), ...extraTags],\r\n };\r\n}\r\n\r\n/**\r\n * Cosine similarity between two equal-length numeric vectors.\r\n *\r\n * Returns a value in `[-1, 1]` where `1` means perfectly aligned, `0` means\r\n * orthogonal, and `-1` means opposing. For typical embedding spaces (where\r\n * vectors live in the positive cone) the practical range is `[0, 1]`.\r\n *\r\n * Throws {@link CacheConfigurationError} on dimension mismatch — fail loud at\r\n * the call site rather than silently returning a misleading score. A zero-norm\r\n * vector on either side returns `0` (no defined direction to compare).\r\n *\r\n * @example\r\n * cosineSimilarity([1, 0, 0], [1, 0, 0]); // 1\r\n * cosineSimilarity([1, 0, 0], [0, 1, 0]); // 0\r\n */\r\nexport function cosineSimilarity(a: number[], b: number[]): number {\r\n if (a.length !== b.length) {\r\n throw new CacheConfigurationError(\r\n `Vector dimension mismatch: got ${a.length} and ${b.length}.`,\r\n );\r\n }\r\n\r\n if (a.length === 0) {\r\n throw new CacheConfigurationError(\r\n \"Vector dimension mismatch: empty vector cannot be compared.\",\r\n );\r\n }\r\n\r\n let dot = 0;\r\n let normA = 0;\r\n let normB = 0;\r\n\r\n for (let i = 0; i < a.length; i++) {\r\n const x = a[i];\r\n const y = b[i];\r\n dot += x * y;\r\n normA += x * x;\r\n normB += y * y;\r\n }\r\n\r\n if (normA === 0 || normB === 0) {\r\n return 0;\r\n }\r\n\r\n return dot / (Math.sqrt(normA) * Math.sqrt(normB));\r\n}\r\n\r\nexport enum CACHE_FOR {\r\n /**\r\n * Cache for 30 Minutes (in seconds)\r\n */\r\n HALF_HOUR = 1800,\r\n /**\r\n * Cache for 1 Hour (in seconds)\r\n */\r\n ONE_HOUR = 3600,\r\n /**\r\n * Cache for 12 Hours (in seconds)\r\n */\r\n HALF_DAY = 43200,\r\n /**\r\n * Cache for 24 Hours (in seconds)\r\n */\r\n ONE_DAY = 86400,\r\n /**\r\n * Cache for 7 Days (in seconds)\r\n */\r\n ONE_WEEK = 604800,\r\n /**\r\n * Cache for 15 Days (in seconds)\r\n */\r\n HALF_MONTH = 1296000,\r\n /**\r\n * Cache for 30 Days (in seconds)\r\n */\r\n ONE_MONTH = 2592000,\r\n /**\r\n * Cache for 60 Days (in seconds)\r\n */\r\n TWO_MONTHS = 5184000,\r\n /**\r\n * Cache for 180 Days (in seconds)\r\n */\r\n SIX_MONTHS = 15768000,\r\n /**\r\n * Cache for 365 Days (in seconds)\r\n */\r\n ONE_YEAR = 31536000,\r\n}\r\n"],"mappings":"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"}
package/package.json CHANGED
@@ -26,16 +26,16 @@
26
26
  "url": "https://github.com/warlockjs/cache"
27
27
  },
28
28
  "dependencies": {
29
- "@warlock.js/fs": "*",
29
+ "@warlock.js/fs": "4.2.0",
30
30
  "@mongez/reinforcements": "^3.2.0",
31
- "@warlock.js/logger": "*",
31
+ "@warlock.js/logger": "4.2.0",
32
32
  "ms": "^2.1.3"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "redis": "^4.6.10 || ^5.0.0",
36
36
  "pg": "^8.11.0"
37
37
  },
38
- "version": "4.1.14",
38
+ "version": "4.2.0",
39
39
  "main": "./cjs/index.cjs",
40
40
  "module": "./esm/index.mjs",
41
41
  "types": "./esm/index.d.mts",