@sonicjs-cms/core 2.19.0 → 3.0.0-beta.11

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 (230) hide show
  1. package/README.md +52 -52
  2. package/dist/admin-documents-form.template-DDSH6ROU.js +6 -0
  3. package/dist/{admin-layout-catalyst.template-UMTIN66R.js.map → admin-documents-form.template-DDSH6ROU.js.map} +1 -1
  4. package/dist/admin-documents-form.template-LSZKGA5J.cjs +19 -0
  5. package/dist/{admin-layout-catalyst.template-HFD37TY5.cjs.map → admin-documents-form.template-LSZKGA5J.cjs.map} +1 -1
  6. package/dist/{filter-bar.template-DlVYMk-T.d.cts → admin-layout-catalyst.template-DrwDUfsE.d.cts} +25 -1
  7. package/dist/{filter-bar.template-DlVYMk-T.d.ts → admin-layout-catalyst.template-DrwDUfsE.d.ts} +25 -1
  8. package/dist/admin-layout-catalyst.template-KDHKVLXR.cjs +21 -0
  9. package/dist/admin-layout-catalyst.template-KDHKVLXR.cjs.map +1 -0
  10. package/dist/admin-layout-catalyst.template-YQ4EMF2J.js +7 -0
  11. package/dist/admin-layout-catalyst.template-YQ4EMF2J.js.map +1 -0
  12. package/dist/app-Bo0X1OWX.d.ts +1268 -0
  13. package/dist/app-Do66yCcV.d.cts +1268 -0
  14. package/dist/cache-DDARE4QE.js +4 -0
  15. package/dist/cache-DDARE4QE.js.map +1 -0
  16. package/dist/cache-LVYS4BPL.cjs +33 -0
  17. package/dist/cache-LVYS4BPL.cjs.map +1 -0
  18. package/dist/chunk-2CB4KY7I.cjs +771 -0
  19. package/dist/chunk-2CB4KY7I.cjs.map +1 -0
  20. package/dist/{chunk-4NPCDK6B.js → chunk-3PU4WVU6.js} +557 -90
  21. package/dist/chunk-3PU4WVU6.js.map +1 -0
  22. package/dist/chunk-4BTBSXMR.cjs +912 -0
  23. package/dist/chunk-4BTBSXMR.cjs.map +1 -0
  24. package/dist/{chunk-55RDMDOP.js → chunk-5V62WT6M.js} +181 -57
  25. package/dist/chunk-5V62WT6M.js.map +1 -0
  26. package/dist/chunk-6H66MSSL.js +273 -0
  27. package/dist/chunk-6H66MSSL.js.map +1 -0
  28. package/dist/chunk-AI663NBO.js +821 -0
  29. package/dist/chunk-AI663NBO.js.map +1 -0
  30. package/dist/chunk-BLMTL57B.js +767 -0
  31. package/dist/chunk-BLMTL57B.js.map +1 -0
  32. package/dist/{chunk-4ZSNJDLS.cjs → chunk-CRGUD4KC.cjs} +9 -9
  33. package/dist/chunk-CRGUD4KC.cjs.map +1 -0
  34. package/dist/chunk-GCDZZNIN.js +192 -0
  35. package/dist/chunk-GCDZZNIN.js.map +1 -0
  36. package/dist/chunk-HIKBY7MS.cjs +70 -0
  37. package/dist/chunk-HIKBY7MS.cjs.map +1 -0
  38. package/dist/chunk-HPAJKZAQ.js +387 -0
  39. package/dist/chunk-HPAJKZAQ.js.map +1 -0
  40. package/dist/chunk-IESEVHXL.js +66 -0
  41. package/dist/chunk-IESEVHXL.js.map +1 -0
  42. package/dist/chunk-IVPRUGTY.js +242 -0
  43. package/dist/chunk-IVPRUGTY.js.map +1 -0
  44. package/dist/{chunk-JZVHLLSI.cjs → chunk-IXUHXTHW.cjs} +2 -151
  45. package/dist/chunk-IXUHXTHW.cjs.map +1 -0
  46. package/dist/chunk-J6JTWD2A.cjs +100 -0
  47. package/dist/chunk-J6JTWD2A.cjs.map +1 -0
  48. package/dist/chunk-JEQ7FLOD.cjs +199 -0
  49. package/dist/chunk-JEQ7FLOD.cjs.map +1 -0
  50. package/dist/{chunk-ON5ZMSU4.js → chunk-JQISFW6U.js} +3 -3
  51. package/dist/chunk-JQISFW6U.js.map +1 -0
  52. package/dist/chunk-K25XHMM3.js +566 -0
  53. package/dist/chunk-K25XHMM3.js.map +1 -0
  54. package/dist/{chunk-R4FOLLFB.cjs → chunk-K342JMA3.cjs} +8730 -11520
  55. package/dist/chunk-K342JMA3.cjs.map +1 -0
  56. package/dist/{chunk-UYJ6TJHX.cjs → chunk-K623Q6WD.cjs} +181 -56
  57. package/dist/chunk-K623Q6WD.cjs.map +1 -0
  58. package/dist/chunk-KV3CM5RK.cjs +158 -0
  59. package/dist/chunk-KV3CM5RK.cjs.map +1 -0
  60. package/dist/{chunk-ABB34XUS.cjs → chunk-MKKGA3C4.cjs} +667 -19
  61. package/dist/chunk-MKKGA3C4.cjs.map +1 -0
  62. package/dist/chunk-N32OWET6.cjs +327 -0
  63. package/dist/chunk-N32OWET6.cjs.map +1 -0
  64. package/dist/chunk-NUKJ54GA.cjs +245 -0
  65. package/dist/chunk-NUKJ54GA.cjs.map +1 -0
  66. package/dist/{chunk-XWIA3HVX.js → chunk-OBA2RYZN.js} +6 -1249
  67. package/dist/chunk-OBA2RYZN.js.map +1 -0
  68. package/dist/chunk-ORF4CT74.cjs +276 -0
  69. package/dist/chunk-ORF4CT74.cjs.map +1 -0
  70. package/dist/{chunk-TFNTM3OA.js → chunk-PDYRDYXI.js} +645 -15
  71. package/dist/chunk-PDYRDYXI.js.map +1 -0
  72. package/dist/{chunk-OHYBNCVL.cjs → chunk-PXNTCCPE.cjs} +10 -1256
  73. package/dist/chunk-PXNTCCPE.cjs.map +1 -0
  74. package/dist/{chunk-E4YFJBM2.cjs → chunk-QJNKSFDJ.cjs} +876 -829
  75. package/dist/chunk-QJNKSFDJ.cjs.map +1 -0
  76. package/dist/chunk-QLFTG3QJ.js +1828 -0
  77. package/dist/chunk-QLFTG3QJ.js.map +1 -0
  78. package/dist/{chunk-BU7SFHGP.js → chunk-QZGABF2M.js} +3 -149
  79. package/dist/chunk-QZGABF2M.js.map +1 -0
  80. package/dist/chunk-RMRJGMDE.js +323 -0
  81. package/dist/chunk-RMRJGMDE.js.map +1 -0
  82. package/dist/chunk-RNZFGN4R.js +88 -0
  83. package/dist/chunk-RNZFGN4R.js.map +1 -0
  84. package/dist/chunk-RQ6N3FTV.js +900 -0
  85. package/dist/chunk-RQ6N3FTV.js.map +1 -0
  86. package/dist/{chunk-OCL3HMEG.js → chunk-SXLVXD2X.js} +7004 -9807
  87. package/dist/chunk-SXLVXD2X.js.map +1 -0
  88. package/dist/chunk-UHRHZXVR.cjs +408 -0
  89. package/dist/chunk-UHRHZXVR.cjs.map +1 -0
  90. package/dist/chunk-YA3TJ65D.cjs +575 -0
  91. package/dist/chunk-YA3TJ65D.cjs.map +1 -0
  92. package/dist/{chunk-7A4CB7T3.cjs → chunk-YJEBDJDV.cjs} +561 -91
  93. package/dist/chunk-YJEBDJDV.cjs.map +1 -0
  94. package/dist/chunk-YP7GW2G5.cjs +866 -0
  95. package/dist/chunk-YP7GW2G5.cjs.map +1 -0
  96. package/dist/chunk-ZUEIQFE5.js +154 -0
  97. package/dist/chunk-ZUEIQFE5.js.map +1 -0
  98. package/dist/{collection-config-B4PG-AaF.d.cts → collection-config-JgHOpFCG.d.cts} +30 -2
  99. package/dist/{collection-config-B4PG-AaF.d.ts → collection-config-JgHOpFCG.d.ts} +30 -2
  100. package/dist/config-HFXANXCC.js +6 -0
  101. package/dist/config-HFXANXCC.js.map +1 -0
  102. package/dist/config-ON6FNMYX.cjs +19 -0
  103. package/dist/config-ON6FNMYX.cjs.map +1 -0
  104. package/dist/define-plugin-BzNHc1ZI.d.ts +1321 -0
  105. package/dist/define-plugin-IWDKYaVm.d.cts +1321 -0
  106. package/dist/document-projection-TDWRJX3Z.cjs +13 -0
  107. package/dist/document-projection-TDWRJX3Z.cjs.map +1 -0
  108. package/dist/document-projection-YYMC6I4U.js +4 -0
  109. package/dist/document-projection-YYMC6I4U.js.map +1 -0
  110. package/dist/index.cjs +13739 -4328
  111. package/dist/index.cjs.map +1 -1
  112. package/dist/index.d.cts +331 -493
  113. package/dist/index.d.ts +331 -493
  114. package/dist/index.js +13456 -4067
  115. package/dist/index.js.map +1 -1
  116. package/dist/middleware.cjs +38 -32
  117. package/dist/middleware.d.cts +50 -7
  118. package/dist/middleware.d.ts +50 -7
  119. package/dist/middleware.js +9 -3
  120. package/dist/migrations-XQLBY7E5.js +4 -0
  121. package/dist/{migrations-H5IXZNCO.js.map → migrations-XQLBY7E5.js.map} +1 -1
  122. package/dist/migrations-ZXJEUTFA.cjs +13 -0
  123. package/dist/{migrations-566IIPS2.cjs.map → migrations-ZXJEUTFA.cjs.map} +1 -1
  124. package/dist/{plugin-bootstrap-DfVerYV4.d.cts → plugin-bootstrap-B8ThJU21.d.cts} +4315 -1661
  125. package/dist/{plugin-bootstrap-P_ciLp_C.d.ts → plugin-bootstrap-qu8hJgUt.d.ts} +4315 -1661
  126. package/dist/plugins.cjs +171 -12
  127. package/dist/plugins.d.cts +36 -2
  128. package/dist/plugins.d.ts +36 -2
  129. package/dist/plugins.js +5 -2
  130. package/dist/rbac-O73MFKDA.js +5 -0
  131. package/dist/rbac-O73MFKDA.js.map +1 -0
  132. package/dist/rbac-VONLJJKB.cjs +14 -0
  133. package/dist/rbac-VONLJJKB.cjs.map +1 -0
  134. package/dist/routes.cjs +42 -46
  135. package/dist/routes.d.cts +56 -146
  136. package/dist/routes.d.ts +56 -146
  137. package/dist/routes.js +18 -10
  138. package/dist/services.cjs +43 -76
  139. package/dist/services.d.cts +93 -55
  140. package/dist/services.d.ts +93 -55
  141. package/dist/services.js +6 -3
  142. package/dist/{telemetry-B9vIV4wh.d.cts → telemetry-Cku1ax74.d.cts} +1 -1
  143. package/dist/{telemetry-B9vIV4wh.d.ts → telemetry-Cku1ax74.d.ts} +1 -1
  144. package/dist/templates.cjs +17 -29
  145. package/dist/templates.d.cts +2 -89
  146. package/dist/templates.d.ts +2 -89
  147. package/dist/templates.js +3 -3
  148. package/dist/types-Dea1eNxU.d.cts +286 -0
  149. package/dist/types-Dea1eNxU.d.ts +286 -0
  150. package/dist/types.d.cts +2 -2
  151. package/dist/types.d.ts +2 -2
  152. package/dist/utils.cjs +21 -20
  153. package/dist/utils.d.cts +2 -2
  154. package/dist/utils.d.ts +2 -2
  155. package/dist/utils.js +3 -2
  156. package/migrations/0001_core.sql +184 -0
  157. package/migrations/0002_documents.sql +163 -0
  158. package/package.json +12 -7
  159. package/dist/admin-layout-catalyst.template-HFD37TY5.cjs +0 -17
  160. package/dist/admin-layout-catalyst.template-UMTIN66R.js +0 -7
  161. package/dist/app-C9esKLmh.d.cts +0 -112
  162. package/dist/app-C9esKLmh.d.ts +0 -112
  163. package/dist/chunk-4NPCDK6B.js.map +0 -1
  164. package/dist/chunk-4ZSNJDLS.cjs.map +0 -1
  165. package/dist/chunk-55RDMDOP.js.map +0 -1
  166. package/dist/chunk-635JAMSE.cjs +0 -653
  167. package/dist/chunk-635JAMSE.cjs.map +0 -1
  168. package/dist/chunk-7A4CB7T3.cjs.map +0 -1
  169. package/dist/chunk-ABB34XUS.cjs.map +0 -1
  170. package/dist/chunk-BU7SFHGP.js.map +0 -1
  171. package/dist/chunk-E4YFJBM2.cjs.map +0 -1
  172. package/dist/chunk-EXNEW5US.js +0 -648
  173. package/dist/chunk-EXNEW5US.js.map +0 -1
  174. package/dist/chunk-JZV22DEV.js +0 -1783
  175. package/dist/chunk-JZV22DEV.js.map +0 -1
  176. package/dist/chunk-JZVHLLSI.cjs.map +0 -1
  177. package/dist/chunk-OCL3HMEG.js.map +0 -1
  178. package/dist/chunk-OHYBNCVL.cjs.map +0 -1
  179. package/dist/chunk-ON5ZMSU4.js.map +0 -1
  180. package/dist/chunk-QFWHAFEO.js +0 -1843
  181. package/dist/chunk-QFWHAFEO.js.map +0 -1
  182. package/dist/chunk-R4FOLLFB.cjs.map +0 -1
  183. package/dist/chunk-RLMUFFUD.cjs +0 -2219
  184. package/dist/chunk-RLMUFFUD.cjs.map +0 -1
  185. package/dist/chunk-TFNTM3OA.js.map +0 -1
  186. package/dist/chunk-UYJ6TJHX.cjs.map +0 -1
  187. package/dist/chunk-WAEQXGCX.cjs +0 -1898
  188. package/dist/chunk-WAEQXGCX.cjs.map +0 -1
  189. package/dist/chunk-XWIA3HVX.js.map +0 -1
  190. package/dist/chunk-ZYAYUIZE.js +0 -2217
  191. package/dist/chunk-ZYAYUIZE.js.map +0 -1
  192. package/dist/migrations-566IIPS2.cjs +0 -13
  193. package/dist/migrations-H5IXZNCO.js +0 -4
  194. package/dist/plugin-manager-BoM3Q7o7.d.cts +0 -328
  195. package/dist/plugin-manager-Efx9RyDX.d.ts +0 -328
  196. package/migrations/001_initial_schema.sql +0 -170
  197. package/migrations/002_faq_plugin.sql +0 -86
  198. package/migrations/003_stage5_enhancements.sql +0 -121
  199. package/migrations/004_stage6_user_management.sql +0 -183
  200. package/migrations/005_stage7_workflow_automation.sql +0 -294
  201. package/migrations/006_plugin_system.sql +0 -155
  202. package/migrations/007_demo_login_plugin.sql +0 -23
  203. package/migrations/008_fix_slug_validation.sql +0 -22
  204. package/migrations/009_system_logging.sql +0 -57
  205. package/migrations/011_config_managed_collections.sql +0 -15
  206. package/migrations/012_testimonials_plugin.sql +0 -80
  207. package/migrations/013_code_examples_plugin.sql +0 -177
  208. package/migrations/014_fix_plugin_registry.sql +0 -88
  209. package/migrations/015_add_remaining_plugins.sql +0 -89
  210. package/migrations/016_remove_duplicate_cache_plugin.sql +0 -17
  211. package/migrations/017_auth_configurable_fields.sql +0 -49
  212. package/migrations/018_settings_table.sql +0 -23
  213. package/migrations/019_remove_blog_posts_collection.sql +0 -15
  214. package/migrations/020_add_email_plugin.sql +0 -22
  215. package/migrations/021_add_magic_link_auth_plugin.sql +0 -42
  216. package/migrations/022_add_tinymce_plugin.sql +0 -25
  217. package/migrations/023_add_easy_mdx_plugin.sql +0 -25
  218. package/migrations/024_add_quill_editor_plugin.sql +0 -25
  219. package/migrations/025_add_easymde_plugin.sql +0 -25
  220. package/migrations/026_add_otp_login.sql +0 -42
  221. package/migrations/027_fix_slug_field_type.sql +0 -18
  222. package/migrations/028_fix_slug_field_type_in_schemas.sql +0 -30
  223. package/migrations/029_add_forms_system.sql +0 -184
  224. package/migrations/030_add_turnstile_to_forms.sql +0 -14
  225. package/migrations/031_ai_search_plugin.sql +0 -45
  226. package/migrations/032_user_profiles.sql +0 -37
  227. package/migrations/033_form_content_integration.sql +0 -19
  228. package/migrations/034_security_audit_plugin.sql +0 -27
  229. package/migrations/035_user_profiles_data_column.sql +0 -16
  230. package/migrations/036_analytics_events.sql +0 -22
@@ -0,0 +1,575 @@
1
+ 'use strict';
2
+
3
+ // src/plugins/cache/services/cache-config.ts
4
+ var CACHE_CONFIGS = {
5
+ // Content (high read, low write)
6
+ content: {
7
+ ttl: 3600,
8
+ // 1 hour
9
+ kvEnabled: true,
10
+ memoryEnabled: true,
11
+ namespace: "content",
12
+ invalidateOn: ["content.update", "content.delete", "content.publish"],
13
+ version: "v1"
14
+ },
15
+ // User data (medium read, medium write)
16
+ user: {
17
+ ttl: 900,
18
+ // 15 minutes
19
+ kvEnabled: true,
20
+ memoryEnabled: true,
21
+ namespace: "user",
22
+ invalidateOn: ["user.update", "user.delete", "auth.login"],
23
+ version: "v1"
24
+ },
25
+ // Configuration (high read, very low write)
26
+ config: {
27
+ ttl: 7200,
28
+ // 2 hours
29
+ kvEnabled: true,
30
+ memoryEnabled: true,
31
+ namespace: "config",
32
+ invalidateOn: ["config.update", "plugin.activate", "plugin.deactivate"],
33
+ version: "v1"
34
+ },
35
+ // Media metadata (high read, low write)
36
+ media: {
37
+ ttl: 3600,
38
+ // 1 hour
39
+ kvEnabled: true,
40
+ memoryEnabled: true,
41
+ namespace: "media",
42
+ invalidateOn: ["media.upload", "media.delete", "media.update"],
43
+ version: "v1"
44
+ },
45
+ // API responses (very high read, low write)
46
+ api: {
47
+ ttl: 300,
48
+ // 5 minutes
49
+ kvEnabled: true,
50
+ memoryEnabled: true,
51
+ namespace: "api",
52
+ invalidateOn: ["content.update", "content.publish"],
53
+ version: "v1"
54
+ },
55
+ // Session data (very high read, medium write)
56
+ session: {
57
+ ttl: 1800,
58
+ // 30 minutes
59
+ kvEnabled: false,
60
+ // Only in-memory for sessions
61
+ memoryEnabled: true,
62
+ namespace: "session",
63
+ invalidateOn: ["auth.logout"],
64
+ version: "v1"
65
+ },
66
+ // Plugin data
67
+ plugin: {
68
+ ttl: 3600,
69
+ // 1 hour
70
+ kvEnabled: true,
71
+ memoryEnabled: true,
72
+ namespace: "plugin",
73
+ invalidateOn: ["plugin.activate", "plugin.deactivate", "plugin.update"],
74
+ version: "v1"
75
+ },
76
+ // Collections/schema
77
+ collection: {
78
+ ttl: 7200,
79
+ // 2 hours
80
+ kvEnabled: true,
81
+ memoryEnabled: true,
82
+ namespace: "collection",
83
+ invalidateOn: ["collection.update", "collection.delete"],
84
+ version: "v1"
85
+ }
86
+ };
87
+ function getCacheConfig(namespace) {
88
+ return CACHE_CONFIGS[namespace] || {
89
+ ttl: 3600,
90
+ kvEnabled: true,
91
+ memoryEnabled: true,
92
+ namespace,
93
+ invalidateOn: [],
94
+ version: "v1"
95
+ };
96
+ }
97
+ function generateCacheKey(namespace, type, identifier, version) {
98
+ const v = version || getCacheConfig(namespace).version || "v1";
99
+ return `${namespace}:${type}:${identifier}:${v}`;
100
+ }
101
+ function parseCacheKey(key) {
102
+ const parts = key.split(":");
103
+ if (parts.length !== 4) {
104
+ return null;
105
+ }
106
+ return {
107
+ namespace: parts[0] || "",
108
+ type: parts[1] || "",
109
+ identifier: parts[2] || "",
110
+ version: parts[3] || ""
111
+ };
112
+ }
113
+
114
+ // src/plugins/cache/services/cache.ts
115
+ var MemoryCache = class {
116
+ cache = /* @__PURE__ */ new Map();
117
+ maxSize = 50 * 1024 * 1024;
118
+ // 50MB
119
+ currentSize = 0;
120
+ /**
121
+ * Get item from memory cache
122
+ */
123
+ get(key) {
124
+ const entry = this.cache.get(key);
125
+ if (!entry) {
126
+ return null;
127
+ }
128
+ if (Date.now() > entry.expiresAt) {
129
+ this.delete(key);
130
+ return null;
131
+ }
132
+ return entry.data;
133
+ }
134
+ /**
135
+ * Set item in memory cache
136
+ */
137
+ set(key, value, ttl, version = "v1") {
138
+ const now = Date.now();
139
+ const entry = {
140
+ data: value,
141
+ timestamp: now,
142
+ expiresAt: now + ttl * 1e3,
143
+ version
144
+ };
145
+ const entrySize = JSON.stringify(entry).length * 2;
146
+ if (this.currentSize + entrySize > this.maxSize) {
147
+ this.evictLRU(entrySize);
148
+ }
149
+ if (this.cache.has(key)) {
150
+ this.delete(key);
151
+ }
152
+ this.cache.set(key, entry);
153
+ this.currentSize += entrySize;
154
+ }
155
+ /**
156
+ * Delete item from memory cache
157
+ */
158
+ delete(key) {
159
+ const entry = this.cache.get(key);
160
+ if (entry) {
161
+ const entrySize = JSON.stringify(entry).length * 2;
162
+ this.currentSize -= entrySize;
163
+ return this.cache.delete(key);
164
+ }
165
+ return false;
166
+ }
167
+ /**
168
+ * Clear all items from memory cache
169
+ */
170
+ clear() {
171
+ this.cache.clear();
172
+ this.currentSize = 0;
173
+ }
174
+ /**
175
+ * Get cache statistics
176
+ */
177
+ getStats() {
178
+ return {
179
+ size: this.currentSize,
180
+ count: this.cache.size
181
+ };
182
+ }
183
+ /**
184
+ * Evict least recently used items to make space
185
+ */
186
+ evictLRU(neededSpace) {
187
+ const entries = Array.from(this.cache.entries()).sort(
188
+ (a, b) => a[1].timestamp - b[1].timestamp
189
+ );
190
+ let freedSpace = 0;
191
+ for (const [key, entry] of entries) {
192
+ if (freedSpace >= neededSpace) break;
193
+ const entrySize = JSON.stringify(entry).length * 2;
194
+ this.delete(key);
195
+ freedSpace += entrySize;
196
+ }
197
+ }
198
+ /**
199
+ * Delete items matching a pattern
200
+ */
201
+ invalidatePattern(pattern) {
202
+ const regex = new RegExp(
203
+ "^" + pattern.replace(/\*/g, ".*").replace(/\?/g, ".") + "$"
204
+ );
205
+ let count = 0;
206
+ for (const key of this.cache.keys()) {
207
+ if (regex.test(key)) {
208
+ this.delete(key);
209
+ count++;
210
+ }
211
+ }
212
+ return count;
213
+ }
214
+ };
215
+ var CacheService = class {
216
+ memoryCache;
217
+ config;
218
+ stats;
219
+ kvNamespace;
220
+ constructor(config, kvNamespace) {
221
+ this.memoryCache = new MemoryCache();
222
+ this.config = config;
223
+ this.kvNamespace = kvNamespace;
224
+ this.stats = {
225
+ memoryHits: 0,
226
+ memoryMisses: 0,
227
+ kvHits: 0,
228
+ kvMisses: 0,
229
+ dbHits: 0,
230
+ totalRequests: 0,
231
+ hitRate: 0,
232
+ memorySize: 0,
233
+ entryCount: 0
234
+ };
235
+ }
236
+ /**
237
+ * Get value from cache (tries memory first, then KV)
238
+ */
239
+ async get(key) {
240
+ this.stats.totalRequests++;
241
+ if (this.config.memoryEnabled) {
242
+ const memoryValue = this.memoryCache.get(key);
243
+ if (memoryValue !== null) {
244
+ this.stats.memoryHits++;
245
+ this.updateHitRate();
246
+ return memoryValue;
247
+ }
248
+ this.stats.memoryMisses++;
249
+ }
250
+ if (this.config.kvEnabled && this.kvNamespace) {
251
+ try {
252
+ const kvValue = await this.kvNamespace.get(key, "json");
253
+ if (kvValue !== null) {
254
+ this.stats.kvHits++;
255
+ if (this.config.memoryEnabled) {
256
+ this.memoryCache.set(key, kvValue, this.config.ttl, this.config.version);
257
+ }
258
+ this.updateHitRate();
259
+ return kvValue;
260
+ }
261
+ this.stats.kvMisses++;
262
+ } catch (error) {
263
+ console.error("KV cache read error:", error);
264
+ this.stats.kvMisses++;
265
+ }
266
+ }
267
+ this.updateHitRate();
268
+ return null;
269
+ }
270
+ /**
271
+ * Get value from cache with source information
272
+ */
273
+ async getWithSource(key) {
274
+ this.stats.totalRequests++;
275
+ if (this.config.memoryEnabled) {
276
+ const memoryValue = this.memoryCache.get(key);
277
+ if (memoryValue !== null) {
278
+ this.stats.memoryHits++;
279
+ this.updateHitRate();
280
+ const entry = await this.getEntry(key);
281
+ return {
282
+ data: memoryValue,
283
+ source: "memory",
284
+ hit: true,
285
+ timestamp: entry?.timestamp,
286
+ ttl: entry?.ttl
287
+ };
288
+ }
289
+ this.stats.memoryMisses++;
290
+ }
291
+ if (this.config.kvEnabled && this.kvNamespace) {
292
+ try {
293
+ const kvValue = await this.kvNamespace.get(key, "json");
294
+ if (kvValue !== null) {
295
+ this.stats.kvHits++;
296
+ if (this.config.memoryEnabled) {
297
+ this.memoryCache.set(key, kvValue, this.config.ttl, this.config.version);
298
+ }
299
+ this.updateHitRate();
300
+ return {
301
+ data: kvValue,
302
+ source: "kv",
303
+ hit: true
304
+ };
305
+ }
306
+ this.stats.kvMisses++;
307
+ } catch (error) {
308
+ console.error("KV cache read error:", error);
309
+ this.stats.kvMisses++;
310
+ }
311
+ }
312
+ this.updateHitRate();
313
+ return {
314
+ data: null,
315
+ source: "miss",
316
+ hit: false
317
+ };
318
+ }
319
+ /**
320
+ * Set value in cache (stores in both memory and KV)
321
+ */
322
+ async set(key, value, customConfig) {
323
+ const config = { ...this.config, ...customConfig };
324
+ if (config.memoryEnabled) {
325
+ this.memoryCache.set(key, value, config.ttl, config.version);
326
+ }
327
+ if (config.kvEnabled && this.kvNamespace) {
328
+ try {
329
+ await this.kvNamespace.put(key, JSON.stringify(value), {
330
+ // Cloudflare KV requires minimum 60s TTL in production; clamp silently.
331
+ expirationTtl: Math.max(config.ttl, 60)
332
+ });
333
+ } catch (error) {
334
+ console.error("KV cache write error:", error);
335
+ }
336
+ }
337
+ }
338
+ /**
339
+ * Delete value from cache (removes from both memory and KV)
340
+ */
341
+ async delete(key) {
342
+ if (this.config.memoryEnabled) {
343
+ this.memoryCache.delete(key);
344
+ }
345
+ if (this.config.kvEnabled && this.kvNamespace) {
346
+ try {
347
+ await this.kvNamespace.delete(key);
348
+ } catch (error) {
349
+ console.error("KV cache delete error:", error);
350
+ }
351
+ }
352
+ }
353
+ /**
354
+ * Clear all cache entries for this namespace
355
+ */
356
+ async clear() {
357
+ if (this.config.memoryEnabled) {
358
+ this.memoryCache.clear();
359
+ }
360
+ this.stats = {
361
+ memoryHits: 0,
362
+ memoryMisses: 0,
363
+ kvHits: 0,
364
+ kvMisses: 0,
365
+ dbHits: 0,
366
+ totalRequests: 0,
367
+ hitRate: 0,
368
+ memorySize: 0,
369
+ entryCount: 0
370
+ };
371
+ }
372
+ /**
373
+ * Invalidate cache entries matching a pattern
374
+ */
375
+ async invalidate(pattern) {
376
+ let count = 0;
377
+ if (this.config.memoryEnabled) {
378
+ count += this.memoryCache.invalidatePattern(pattern);
379
+ }
380
+ if (this.config.kvEnabled && this.kvNamespace) {
381
+ try {
382
+ const regex = new RegExp(
383
+ "^" + pattern.replace(/\*/g, ".*").replace(/\?/g, ".") + "$"
384
+ );
385
+ const prefix = this.config.namespace + ":";
386
+ const list = await this.kvNamespace.list({ prefix });
387
+ for (const key of list.keys) {
388
+ if (regex.test(key.name)) {
389
+ await this.kvNamespace.delete(key.name);
390
+ count++;
391
+ }
392
+ }
393
+ } catch (error) {
394
+ console.error("KV cache invalidation error:", error);
395
+ }
396
+ }
397
+ return count;
398
+ }
399
+ /**
400
+ * Invalidate cache entries matching a pattern (alias for invalidate)
401
+ */
402
+ async invalidatePattern(pattern) {
403
+ return this.invalidate(pattern);
404
+ }
405
+ /**
406
+ * Get cache statistics
407
+ */
408
+ getStats() {
409
+ const memStats = this.memoryCache.getStats();
410
+ return {
411
+ ...this.stats,
412
+ memorySize: memStats.size,
413
+ entryCount: memStats.count
414
+ };
415
+ }
416
+ /**
417
+ * Update hit rate calculation
418
+ */
419
+ updateHitRate() {
420
+ const totalHits = this.stats.memoryHits + this.stats.kvHits + this.stats.dbHits;
421
+ this.stats.hitRate = this.stats.totalRequests > 0 ? totalHits / this.stats.totalRequests * 100 : 0;
422
+ }
423
+ /**
424
+ * Generate a cache key using the configured namespace
425
+ */
426
+ generateKey(type, identifier) {
427
+ return generateCacheKey(
428
+ this.config.namespace,
429
+ type,
430
+ identifier,
431
+ this.config.version
432
+ );
433
+ }
434
+ /**
435
+ * Warm cache with multiple entries
436
+ */
437
+ async warmCache(entries) {
438
+ for (const entry of entries) {
439
+ await this.set(entry.key, entry.value);
440
+ }
441
+ }
442
+ /**
443
+ * Check if a key exists in cache
444
+ */
445
+ async has(key) {
446
+ const value = await this.get(key);
447
+ return value !== null;
448
+ }
449
+ /**
450
+ * Get multiple values at once
451
+ */
452
+ async getMany(keys) {
453
+ const results = /* @__PURE__ */ new Map();
454
+ for (const key of keys) {
455
+ const value = await this.get(key);
456
+ if (value !== null) {
457
+ results.set(key, value);
458
+ }
459
+ }
460
+ return results;
461
+ }
462
+ /**
463
+ * Set multiple values at once
464
+ */
465
+ async setMany(entries, customConfig) {
466
+ for (const entry of entries) {
467
+ await this.set(entry.key, entry.value, customConfig);
468
+ }
469
+ }
470
+ /**
471
+ * Delete multiple keys at once
472
+ */
473
+ async deleteMany(keys) {
474
+ for (const key of keys) {
475
+ await this.delete(key);
476
+ }
477
+ }
478
+ /**
479
+ * Get or set pattern - fetch from cache or compute if not found
480
+ */
481
+ async getOrSet(key, fetcher, customConfig) {
482
+ const cached = await this.get(key);
483
+ if (cached !== null) {
484
+ return cached;
485
+ }
486
+ const value = await fetcher();
487
+ await this.set(key, value, customConfig);
488
+ return value;
489
+ }
490
+ /**
491
+ * List all cache keys with metadata
492
+ */
493
+ async listKeys() {
494
+ const keys = [];
495
+ if (this.config.memoryEnabled) {
496
+ const cache = this.memoryCache.cache;
497
+ for (const [key, entry] of cache.entries()) {
498
+ const size = JSON.stringify(entry).length * 2;
499
+ const age = Date.now() - entry.timestamp;
500
+ keys.push({
501
+ key,
502
+ size,
503
+ expiresAt: entry.expiresAt,
504
+ age
505
+ });
506
+ }
507
+ }
508
+ return keys.sort((a, b) => a.age - b.age);
509
+ }
510
+ /**
511
+ * Get cache entry with full metadata
512
+ */
513
+ async getEntry(key) {
514
+ if (!this.config.memoryEnabled) {
515
+ return null;
516
+ }
517
+ const cache = this.memoryCache.cache;
518
+ const entry = cache.get(key);
519
+ if (!entry) {
520
+ return null;
521
+ }
522
+ if (Date.now() > entry.expiresAt) {
523
+ await this.delete(key);
524
+ return null;
525
+ }
526
+ const size = JSON.stringify(entry).length * 2;
527
+ const ttl = Math.max(0, entry.expiresAt - Date.now()) / 1e3;
528
+ return {
529
+ data: entry.data,
530
+ timestamp: entry.timestamp,
531
+ expiresAt: entry.expiresAt,
532
+ ttl,
533
+ size
534
+ };
535
+ }
536
+ };
537
+ function createCacheService(config, kvNamespace) {
538
+ return new CacheService(config, kvNamespace);
539
+ }
540
+ var cacheInstances = /* @__PURE__ */ new Map();
541
+ var globalKVNamespace;
542
+ function setGlobalKVNamespace(kvNamespace) {
543
+ globalKVNamespace = kvNamespace;
544
+ }
545
+ function getCacheService(config, kvNamespace) {
546
+ const key = config.namespace;
547
+ if (!cacheInstances.has(key)) {
548
+ const kv = kvNamespace || globalKVNamespace;
549
+ cacheInstances.set(key, new CacheService(config, kv));
550
+ }
551
+ return cacheInstances.get(key);
552
+ }
553
+ async function clearAllCaches() {
554
+ for (const cache of cacheInstances.values()) {
555
+ await cache.clear();
556
+ }
557
+ }
558
+ function getAllCacheStats() {
559
+ const stats = {};
560
+ for (const [namespace, cache] of cacheInstances.entries()) {
561
+ stats[namespace] = cache.getStats();
562
+ }
563
+ return stats;
564
+ }
565
+
566
+ exports.CACHE_CONFIGS = CACHE_CONFIGS;
567
+ exports.CacheService = CacheService;
568
+ exports.clearAllCaches = clearAllCaches;
569
+ exports.createCacheService = createCacheService;
570
+ exports.getAllCacheStats = getAllCacheStats;
571
+ exports.getCacheService = getCacheService;
572
+ exports.parseCacheKey = parseCacheKey;
573
+ exports.setGlobalKVNamespace = setGlobalKVNamespace;
574
+ //# sourceMappingURL=chunk-YA3TJ65D.cjs.map
575
+ //# sourceMappingURL=chunk-YA3TJ65D.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins/cache/services/cache-config.ts","../src/plugins/cache/services/cache.ts"],"names":[],"mappings":"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","file":"chunk-YA3TJ65D.cjs","sourcesContent":["/**\n * Cache Configuration\n *\n * Defines cache configurations for different entity types\n */\n\nexport interface CacheConfig {\n ttl: number // Time-to-live in seconds\n kvEnabled: boolean // Use KV cache tier\n memoryEnabled: boolean // Use in-memory cache tier\n namespace: string // Cache namespace/prefix\n invalidateOn: string[] // Events that invalidate this cache\n version?: string // Cache version for busting\n}\n\nexport interface CacheStats {\n memoryHits: number\n memoryMisses: number\n kvHits: number\n kvMisses: number\n dbHits: number\n totalRequests: number\n hitRate: number\n memorySize: number\n entryCount: number\n}\n\n/**\n * Default cache configurations by entity type\n */\nexport const CACHE_CONFIGS: Record<string, CacheConfig> = {\n // Content (high read, low write)\n content: {\n ttl: 3600, // 1 hour\n kvEnabled: true,\n memoryEnabled: true,\n namespace: 'content',\n invalidateOn: ['content.update', 'content.delete', 'content.publish'],\n version: 'v1'\n },\n\n // User data (medium read, medium write)\n user: {\n ttl: 900, // 15 minutes\n kvEnabled: true,\n memoryEnabled: true,\n namespace: 'user',\n invalidateOn: ['user.update', 'user.delete', 'auth.login'],\n version: 'v1'\n },\n\n // Configuration (high read, very low write)\n config: {\n ttl: 7200, // 2 hours\n kvEnabled: true,\n memoryEnabled: true,\n namespace: 'config',\n invalidateOn: ['config.update', 'plugin.activate', 'plugin.deactivate'],\n version: 'v1'\n },\n\n // Media metadata (high read, low write)\n media: {\n ttl: 3600, // 1 hour\n kvEnabled: true,\n memoryEnabled: true,\n namespace: 'media',\n invalidateOn: ['media.upload', 'media.delete', 'media.update'],\n version: 'v1'\n },\n\n // API responses (very high read, low write)\n api: {\n ttl: 300, // 5 minutes\n kvEnabled: true,\n memoryEnabled: true,\n namespace: 'api',\n invalidateOn: ['content.update', 'content.publish'],\n version: 'v1'\n },\n\n // Session data (very high read, medium write)\n session: {\n ttl: 1800, // 30 minutes\n kvEnabled: false, // Only in-memory for sessions\n memoryEnabled: true,\n namespace: 'session',\n invalidateOn: ['auth.logout'],\n version: 'v1'\n },\n\n // Plugin data\n plugin: {\n ttl: 3600, // 1 hour\n kvEnabled: true,\n memoryEnabled: true,\n namespace: 'plugin',\n invalidateOn: ['plugin.activate', 'plugin.deactivate', 'plugin.update'],\n version: 'v1'\n },\n\n // Collections/schema\n collection: {\n ttl: 7200, // 2 hours\n kvEnabled: true,\n memoryEnabled: true,\n namespace: 'collection',\n invalidateOn: ['collection.update', 'collection.delete'],\n version: 'v1'\n }\n}\n\n/**\n * Get cache configuration for a specific namespace\n */\nexport function getCacheConfig(namespace: string): CacheConfig {\n return CACHE_CONFIGS[namespace] || {\n ttl: 3600,\n kvEnabled: true,\n memoryEnabled: true,\n namespace,\n invalidateOn: [],\n version: 'v1'\n }\n}\n\n/**\n * Generate a cache key with consistent format\n * Format: {namespace}:{type}:{identifier}:{version}\n */\nexport function generateCacheKey(\n namespace: string,\n type: string,\n identifier: string,\n version?: string\n): string {\n const v = version || getCacheConfig(namespace).version || 'v1'\n return `${namespace}:${type}:${identifier}:${v}`\n}\n\n/**\n * Parse a cache key back into its components\n */\nexport function parseCacheKey(key: string): {\n namespace: string\n type: string\n identifier: string\n version: string\n} | null {\n const parts = key.split(':')\n if (parts.length !== 4) {\n return null\n }\n\n return {\n namespace: parts[0] || '',\n type: parts[1] || '',\n identifier: parts[2] || '',\n version: parts[3] || ''\n }\n}\n\n/**\n * Generate a hash for complex query parameters\n */\nexport function hashQueryParams(params: Record<string, any>): string {\n // Sort keys for consistent hashing\n const sortedKeys = Object.keys(params).sort()\n const normalized = sortedKeys.map(key => `${key}=${params[key]}`).join('&')\n\n // Simple hash function (for better performance, consider using crypto)\n let hash = 0\n for (let i = 0; i < normalized.length; i++) {\n const char = normalized.charCodeAt(i)\n hash = ((hash << 5) - hash) + char\n hash = hash & hash // Convert to 32-bit integer\n }\n\n return Math.abs(hash).toString(36)\n}\n\n/**\n * Create a pattern for cache invalidation\n */\nexport function createCachePattern(\n namespace: string,\n type?: string,\n identifier?: string\n): string {\n let pattern = namespace\n if (type) pattern += `:${type}`\n if (identifier) pattern += `:${identifier}`\n return pattern + ':*'\n}\n","/**\n * Cache Service\n *\n * Three-tiered caching implementation:\n * 1. In-Memory Cache (fastest, region-specific)\n * 2. Cloudflare KV Cache (fast, global)\n * 3. Database (fallback, source of truth)\n */\n\nimport { CacheConfig, CacheStats, generateCacheKey } from './cache-config.js'\n\n/**\n * Cache entry with metadata\n */\ninterface CacheEntry<T> {\n data: T\n timestamp: number\n expiresAt: number\n version: string\n}\n\n/**\n * In-memory cache store\n */\nclass MemoryCache {\n private cache: Map<string, CacheEntry<any>> = new Map()\n private maxSize: number = 50 * 1024 * 1024 // 50MB\n private currentSize: number = 0\n\n /**\n * Get item from memory cache\n */\n get<T>(key: string): T | null {\n const entry = this.cache.get(key)\n\n if (!entry) {\n return null\n }\n\n // Check expiration\n if (Date.now() > entry.expiresAt) {\n this.delete(key)\n return null\n }\n\n return entry.data as T\n }\n\n /**\n * Set item in memory cache\n */\n set<T>(key: string, value: T, ttl: number, version: string = 'v1'): void {\n const now = Date.now()\n const entry: CacheEntry<T> = {\n data: value,\n timestamp: now,\n expiresAt: now + (ttl * 1000),\n version\n }\n\n // Estimate size (rough approximation)\n const entrySize = JSON.stringify(entry).length * 2 // UTF-16\n\n // Check if we need to evict\n if (this.currentSize + entrySize > this.maxSize) {\n this.evictLRU(entrySize)\n }\n\n // Delete old entry if exists\n if (this.cache.has(key)) {\n this.delete(key)\n }\n\n this.cache.set(key, entry)\n this.currentSize += entrySize\n }\n\n /**\n * Delete item from memory cache\n */\n delete(key: string): boolean {\n const entry = this.cache.get(key)\n if (entry) {\n const entrySize = JSON.stringify(entry).length * 2\n this.currentSize -= entrySize\n return this.cache.delete(key)\n }\n return false\n }\n\n /**\n * Clear all items from memory cache\n */\n clear(): void {\n this.cache.clear()\n this.currentSize = 0\n }\n\n /**\n * Get cache statistics\n */\n getStats(): { size: number; count: number } {\n return {\n size: this.currentSize,\n count: this.cache.size\n }\n }\n\n /**\n * Evict least recently used items to make space\n */\n private evictLRU(neededSpace: number): void {\n // Sort by timestamp (oldest first)\n const entries = Array.from(this.cache.entries()).sort(\n (a, b) => a[1].timestamp - b[1].timestamp\n )\n\n let freedSpace = 0\n for (const [key, entry] of entries) {\n if (freedSpace >= neededSpace) break\n\n const entrySize = JSON.stringify(entry).length * 2\n this.delete(key)\n freedSpace += entrySize\n }\n }\n\n /**\n * Delete items matching a pattern\n */\n invalidatePattern(pattern: string): number {\n const regex = new RegExp(\n '^' + pattern.replace(/\\*/g, '.*').replace(/\\?/g, '.') + '$'\n )\n\n let count = 0\n for (const key of this.cache.keys()) {\n if (regex.test(key)) {\n this.delete(key)\n count++\n }\n }\n\n return count\n }\n}\n\n/**\n * Cache result with source information\n */\nexport interface CacheResult<T> {\n data: T | null\n source: 'memory' | 'kv' | 'miss'\n hit: boolean\n timestamp?: number\n ttl?: number\n}\n\n/**\n * Main cache service with multi-tier support\n */\nexport class CacheService {\n private memoryCache: MemoryCache\n private config: CacheConfig\n private stats: CacheStats\n private kvNamespace?: KVNamespace\n\n constructor(config: CacheConfig, kvNamespace?: KVNamespace) {\n this.memoryCache = new MemoryCache()\n this.config = config\n this.kvNamespace = kvNamespace\n this.stats = {\n memoryHits: 0,\n memoryMisses: 0,\n kvHits: 0,\n kvMisses: 0,\n dbHits: 0,\n totalRequests: 0,\n hitRate: 0,\n memorySize: 0,\n entryCount: 0\n }\n }\n\n /**\n * Get value from cache (tries memory first, then KV)\n */\n async get<T>(key: string): Promise<T | null> {\n this.stats.totalRequests++\n\n // Try memory cache first (Tier 1)\n if (this.config.memoryEnabled) {\n const memoryValue = this.memoryCache.get<T>(key)\n if (memoryValue !== null) {\n this.stats.memoryHits++\n this.updateHitRate()\n return memoryValue\n }\n this.stats.memoryMisses++\n }\n\n // Try KV cache (Tier 2)\n if (this.config.kvEnabled && this.kvNamespace) {\n try {\n const kvValue = await this.kvNamespace.get(key, 'json')\n if (kvValue !== null) {\n this.stats.kvHits++\n\n // Populate memory cache for faster subsequent access\n if (this.config.memoryEnabled) {\n this.memoryCache.set(key, kvValue as T, this.config.ttl, this.config.version)\n }\n\n this.updateHitRate()\n return kvValue as T\n }\n this.stats.kvMisses++\n } catch (error) {\n console.error('KV cache read error:', error)\n this.stats.kvMisses++\n }\n }\n\n this.updateHitRate()\n return null\n }\n\n /**\n * Get value from cache with source information\n */\n async getWithSource<T>(key: string): Promise<CacheResult<T>> {\n this.stats.totalRequests++\n\n // Try memory cache first (Tier 1)\n if (this.config.memoryEnabled) {\n const memoryValue = this.memoryCache.get<T>(key)\n if (memoryValue !== null) {\n this.stats.memoryHits++\n this.updateHitRate()\n\n const entry = await this.getEntry<T>(key)\n return {\n data: memoryValue,\n source: 'memory',\n hit: true,\n timestamp: entry?.timestamp,\n ttl: entry?.ttl\n }\n }\n this.stats.memoryMisses++\n }\n\n // Try KV cache (Tier 2)\n if (this.config.kvEnabled && this.kvNamespace) {\n try {\n const kvValue = await this.kvNamespace.get(key, 'json')\n if (kvValue !== null) {\n this.stats.kvHits++\n\n // Populate memory cache for faster subsequent access\n if (this.config.memoryEnabled) {\n this.memoryCache.set(key, kvValue as T, this.config.ttl, this.config.version)\n }\n\n this.updateHitRate()\n return {\n data: kvValue as T,\n source: 'kv',\n hit: true\n }\n }\n this.stats.kvMisses++\n } catch (error) {\n console.error('KV cache read error:', error)\n this.stats.kvMisses++\n }\n }\n\n this.updateHitRate()\n return {\n data: null,\n source: 'miss',\n hit: false\n }\n }\n\n /**\n * Set value in cache (stores in both memory and KV)\n */\n async set<T>(\n key: string,\n value: T,\n customConfig?: Partial<CacheConfig>\n ): Promise<void> {\n const config = { ...this.config, ...customConfig }\n\n // Store in memory cache (Tier 1)\n if (config.memoryEnabled) {\n this.memoryCache.set(key, value, config.ttl, config.version)\n }\n\n // Store in KV cache (Tier 2)\n if (config.kvEnabled && this.kvNamespace) {\n try {\n await this.kvNamespace.put(key, JSON.stringify(value), {\n // Cloudflare KV requires minimum 60s TTL in production; clamp silently.\n expirationTtl: Math.max(config.ttl, 60)\n })\n } catch (error) {\n console.error('KV cache write error:', error)\n }\n }\n }\n\n /**\n * Delete value from cache (removes from both memory and KV)\n */\n async delete(key: string): Promise<void> {\n // Delete from memory (Tier 1)\n if (this.config.memoryEnabled) {\n this.memoryCache.delete(key)\n }\n\n // Delete from KV (Tier 2)\n if (this.config.kvEnabled && this.kvNamespace) {\n try {\n await this.kvNamespace.delete(key)\n } catch (error) {\n console.error('KV cache delete error:', error)\n }\n }\n }\n\n /**\n * Clear all cache entries for this namespace\n */\n async clear(): Promise<void> {\n if (this.config.memoryEnabled) {\n this.memoryCache.clear()\n }\n\n // Reset stats\n this.stats = {\n memoryHits: 0,\n memoryMisses: 0,\n kvHits: 0,\n kvMisses: 0,\n dbHits: 0,\n totalRequests: 0,\n hitRate: 0,\n memorySize: 0,\n entryCount: 0\n }\n }\n\n /**\n * Invalidate cache entries matching a pattern\n */\n async invalidate(pattern: string): Promise<number> {\n let count = 0\n\n // Invalidate from memory (Tier 1)\n if (this.config.memoryEnabled) {\n count += this.memoryCache.invalidatePattern(pattern)\n }\n\n // Invalidate from KV (Tier 2)\n // Note: KV doesn't support pattern matching, so we need to list all keys\n // This is expensive and should be used sparingly\n if (this.config.kvEnabled && this.kvNamespace) {\n try {\n const regex = new RegExp(\n '^' + pattern.replace(/\\*/g, '.*').replace(/\\?/g, '.') + '$'\n )\n\n // List all keys with the namespace prefix\n const prefix = this.config.namespace + ':'\n const list = await this.kvNamespace.list({ prefix })\n\n for (const key of list.keys) {\n if (regex.test(key.name)) {\n await this.kvNamespace.delete(key.name)\n count++\n }\n }\n } catch (error) {\n console.error('KV cache invalidation error:', error)\n }\n }\n\n return count\n }\n\n /**\n * Invalidate cache entries matching a pattern (alias for invalidate)\n */\n async invalidatePattern(pattern: string): Promise<number> {\n return this.invalidate(pattern)\n }\n\n /**\n * Get cache statistics\n */\n getStats(): CacheStats {\n const memStats = this.memoryCache.getStats()\n\n return {\n ...this.stats,\n memorySize: memStats.size,\n entryCount: memStats.count\n }\n }\n\n /**\n * Update hit rate calculation\n */\n private updateHitRate(): void {\n const totalHits = this.stats.memoryHits + this.stats.kvHits + this.stats.dbHits\n this.stats.hitRate = this.stats.totalRequests > 0\n ? (totalHits / this.stats.totalRequests) * 100\n : 0\n }\n\n /**\n * Generate a cache key using the configured namespace\n */\n generateKey(type: string, identifier: string): string {\n return generateCacheKey(\n this.config.namespace,\n type,\n identifier,\n this.config.version\n )\n }\n\n /**\n * Warm cache with multiple entries\n */\n async warmCache<T>(entries: Array<{ key: string; value: T }>): Promise<void> {\n for (const entry of entries) {\n await this.set(entry.key, entry.value)\n }\n }\n\n /**\n * Check if a key exists in cache\n */\n async has(key: string): Promise<boolean> {\n const value = await this.get(key)\n return value !== null\n }\n\n /**\n * Get multiple values at once\n */\n async getMany<T>(keys: string[]): Promise<Map<string, T>> {\n const results = new Map<string, T>()\n\n for (const key of keys) {\n const value = await this.get<T>(key)\n if (value !== null) {\n results.set(key, value)\n }\n }\n\n return results\n }\n\n /**\n * Set multiple values at once\n */\n async setMany<T>(\n entries: Array<{ key: string; value: T }>,\n customConfig?: Partial<CacheConfig>\n ): Promise<void> {\n for (const entry of entries) {\n await this.set(entry.key, entry.value, customConfig)\n }\n }\n\n /**\n * Delete multiple keys at once\n */\n async deleteMany(keys: string[]): Promise<void> {\n for (const key of keys) {\n await this.delete(key)\n }\n }\n\n /**\n * Get or set pattern - fetch from cache or compute if not found\n */\n async getOrSet<T>(\n key: string,\n fetcher: () => Promise<T>,\n customConfig?: Partial<CacheConfig>\n ): Promise<T> {\n // Try to get from cache\n const cached = await this.get<T>(key)\n if (cached !== null) {\n return cached\n }\n\n // Fetch from source\n const value = await fetcher()\n\n // Store in cache\n await this.set(key, value, customConfig)\n\n return value\n }\n\n /**\n * List all cache keys with metadata\n */\n async listKeys(): Promise<Array<{ key: string; size: number; expiresAt: number; age: number }>> {\n const keys: Array<{ key: string; size: number; expiresAt: number; age: number }> = []\n\n // Get keys from memory cache\n if (this.config.memoryEnabled) {\n const cache = (this.memoryCache as any).cache as Map<string, CacheEntry<any>>\n for (const [key, entry] of cache.entries()) {\n const size = JSON.stringify(entry).length * 2\n const age = Date.now() - entry.timestamp\n keys.push({\n key,\n size,\n expiresAt: entry.expiresAt,\n age\n })\n }\n }\n\n // Sort by age (newest first)\n return keys.sort((a, b) => a.age - b.age)\n }\n\n /**\n * Get cache entry with full metadata\n */\n async getEntry<T>(key: string): Promise<{\n data: T\n timestamp: number\n expiresAt: number\n ttl: number\n size: number\n } | null> {\n if (!this.config.memoryEnabled) {\n return null\n }\n\n const cache = (this.memoryCache as any).cache as Map<string, CacheEntry<any>>\n const entry = cache.get(key)\n\n if (!entry) {\n return null\n }\n\n // Check expiration\n if (Date.now() > entry.expiresAt) {\n await this.delete(key)\n return null\n }\n\n const size = JSON.stringify(entry).length * 2\n const ttl = Math.max(0, entry.expiresAt - Date.now()) / 1000\n\n return {\n data: entry.data as T,\n timestamp: entry.timestamp,\n expiresAt: entry.expiresAt,\n ttl,\n size\n }\n }\n}\n\n/**\n * Create a cache service instance with configuration\n */\nexport function createCacheService(config: CacheConfig, kvNamespace?: KVNamespace): CacheService {\n return new CacheService(config, kvNamespace)\n}\n\n/**\n * Global cache instances by namespace (singleton pattern)\n */\nconst cacheInstances = new Map<string, CacheService>()\nlet globalKVNamespace: KVNamespace | undefined\n\n/**\n * Set global KV namespace for all cache instances\n */\nexport function setGlobalKVNamespace(kvNamespace: KVNamespace): void {\n globalKVNamespace = kvNamespace\n}\n\n/**\n * Get or create a cache service for a namespace\n */\nexport function getCacheService(config: CacheConfig, kvNamespace?: KVNamespace): CacheService {\n const key = config.namespace\n\n if (!cacheInstances.has(key)) {\n // Use provided KV namespace or global one\n const kv = kvNamespace || globalKVNamespace\n cacheInstances.set(key, new CacheService(config, kv))\n }\n\n return cacheInstances.get(key)!\n}\n\n/**\n * Clear all cache instances\n */\nexport async function clearAllCaches(): Promise<void> {\n for (const cache of cacheInstances.values()) {\n await cache.clear()\n }\n}\n\n/**\n * Get stats from all cache instances\n */\nexport function getAllCacheStats(): Record<string, CacheStats> {\n const stats: Record<string, CacheStats> = {}\n\n for (const [namespace, cache] of cacheInstances.entries()) {\n stats[namespace] = cache.getStats()\n }\n\n return stats\n}\n"]}