@sonicjs-cms/core 2.19.0 → 3.0.0-beta.2
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.
- package/README.md +4 -3
- package/dist/admin-documents-form.template-KN7JF66Q.cjs +19 -0
- package/dist/{admin-layout-catalyst.template-UMTIN66R.js.map → admin-documents-form.template-KN7JF66Q.cjs.map} +1 -1
- package/dist/admin-documents-form.template-NLSI6Z42.js +6 -0
- package/dist/{admin-layout-catalyst.template-HFD37TY5.cjs.map → admin-documents-form.template-NLSI6Z42.js.map} +1 -1
- package/dist/admin-layout-catalyst.template-WHJGSWWD.js +7 -0
- package/dist/admin-layout-catalyst.template-WHJGSWWD.js.map +1 -0
- package/dist/admin-layout-catalyst.template-ZK5HD545.cjs +17 -0
- package/dist/admin-layout-catalyst.template-ZK5HD545.cjs.map +1 -0
- package/dist/app-Bo0X1OWX.d.ts +1268 -0
- package/dist/app-Do66yCcV.d.cts +1268 -0
- package/dist/cache-DDARE4QE.js +4 -0
- package/dist/cache-DDARE4QE.js.map +1 -0
- package/dist/cache-LVYS4BPL.cjs +33 -0
- package/dist/cache-LVYS4BPL.cjs.map +1 -0
- package/dist/chunk-2CB4KY7I.cjs +771 -0
- package/dist/chunk-2CB4KY7I.cjs.map +1 -0
- package/dist/{chunk-55RDMDOP.js → chunk-3TB6AT6X.js} +148 -55
- package/dist/chunk-3TB6AT6X.js.map +1 -0
- package/dist/{chunk-ON5ZMSU4.js → chunk-6JQOUUOB.js} +3 -3
- package/dist/chunk-6JQOUUOB.js.map +1 -0
- package/dist/chunk-6OUHGKFD.js +387 -0
- package/dist/chunk-6OUHGKFD.js.map +1 -0
- package/dist/{chunk-7A4CB7T3.cjs → chunk-AAWNRBRB.cjs} +509 -91
- package/dist/chunk-AAWNRBRB.cjs.map +1 -0
- package/dist/chunk-AI663NBO.js +821 -0
- package/dist/chunk-AI663NBO.js.map +1 -0
- package/dist/chunk-BDDABDAB.cjs +1149 -0
- package/dist/chunk-BDDABDAB.cjs.map +1 -0
- package/dist/chunk-BLMTL57B.js +767 -0
- package/dist/chunk-BLMTL57B.js.map +1 -0
- package/dist/chunk-DNQCEKUK.cjs +327 -0
- package/dist/chunk-DNQCEKUK.cjs.map +1 -0
- package/dist/chunk-DSA4UX5B.cjs +276 -0
- package/dist/chunk-DSA4UX5B.cjs.map +1 -0
- package/dist/chunk-EF2NQUIQ.js +323 -0
- package/dist/chunk-EF2NQUIQ.js.map +1 -0
- package/dist/chunk-GCDZZNIN.js +192 -0
- package/dist/chunk-GCDZZNIN.js.map +1 -0
- package/dist/{chunk-ABB34XUS.cjs → chunk-H2AXVCLS.cjs} +667 -19
- package/dist/chunk-H2AXVCLS.cjs.map +1 -0
- package/dist/{chunk-XWIA3HVX.js → chunk-HDWE5FRJ.js} +6 -1249
- package/dist/chunk-HDWE5FRJ.js.map +1 -0
- package/dist/chunk-HIKBY7MS.cjs +70 -0
- package/dist/chunk-HIKBY7MS.cjs.map +1 -0
- package/dist/chunk-IESEVHXL.js +66 -0
- package/dist/chunk-IESEVHXL.js.map +1 -0
- package/dist/chunk-IVPRUGTY.js +242 -0
- package/dist/chunk-IVPRUGTY.js.map +1 -0
- package/dist/{chunk-JZVHLLSI.cjs → chunk-IXUHXTHW.cjs} +2 -151
- package/dist/chunk-IXUHXTHW.cjs.map +1 -0
- package/dist/chunk-J6JTWD2A.cjs +100 -0
- package/dist/chunk-J6JTWD2A.cjs.map +1 -0
- package/dist/chunk-JEQ7FLOD.cjs +199 -0
- package/dist/chunk-JEQ7FLOD.cjs.map +1 -0
- package/dist/chunk-K25XHMM3.js +566 -0
- package/dist/chunk-K25XHMM3.js.map +1 -0
- package/dist/chunk-LRZIAW7U.cjs +158 -0
- package/dist/chunk-LRZIAW7U.cjs.map +1 -0
- package/dist/{chunk-OHYBNCVL.cjs → chunk-MVIZJOO5.cjs} +10 -1256
- package/dist/chunk-MVIZJOO5.cjs.map +1 -0
- package/dist/{chunk-UYJ6TJHX.cjs → chunk-NAVPFIG5.cjs} +148 -55
- package/dist/chunk-NAVPFIG5.cjs.map +1 -0
- package/dist/chunk-NLJVSER2.js +273 -0
- package/dist/chunk-NLJVSER2.js.map +1 -0
- package/dist/chunk-NMPEMSU4.js +154 -0
- package/dist/chunk-NMPEMSU4.js.map +1 -0
- package/dist/chunk-NUKJ54GA.cjs +245 -0
- package/dist/chunk-NUKJ54GA.cjs.map +1 -0
- package/dist/{chunk-E4YFJBM2.cjs → chunk-QAYFOER6.cjs} +621 -829
- package/dist/chunk-QAYFOER6.cjs.map +1 -0
- package/dist/{chunk-BU7SFHGP.js → chunk-QZGABF2M.js} +3 -149
- package/dist/chunk-QZGABF2M.js.map +1 -0
- package/dist/chunk-RNZFGN4R.js +88 -0
- package/dist/chunk-RNZFGN4R.js.map +1 -0
- package/dist/{chunk-4NPCDK6B.js → chunk-RZ6H7OZK.js} +505 -90
- package/dist/chunk-RZ6H7OZK.js.map +1 -0
- package/dist/{chunk-OCL3HMEG.js → chunk-VD2EA3WT.js} +7004 -9807
- package/dist/chunk-VD2EA3WT.js.map +1 -0
- package/dist/{chunk-R4FOLLFB.cjs → chunk-VXE42MYF.cjs} +8730 -11520
- package/dist/chunk-VXE42MYF.cjs.map +1 -0
- package/dist/{chunk-4ZSNJDLS.cjs → chunk-WULONYGB.cjs} +9 -9
- package/dist/chunk-WULONYGB.cjs.map +1 -0
- package/dist/chunk-XW56B23A.cjs +408 -0
- package/dist/chunk-XW56B23A.cjs.map +1 -0
- package/dist/chunk-YA3TJ65D.cjs +575 -0
- package/dist/chunk-YA3TJ65D.cjs.map +1 -0
- package/dist/{chunk-TFNTM3OA.js → chunk-YHSQVQXX.js} +645 -15
- package/dist/chunk-YHSQVQXX.js.map +1 -0
- package/dist/chunk-YP7GW2G5.cjs +866 -0
- package/dist/chunk-YP7GW2G5.cjs.map +1 -0
- package/dist/{chunk-QFWHAFEO.js → chunk-ZEZ245PW.js} +148 -858
- package/dist/chunk-ZEZ245PW.js.map +1 -0
- package/dist/{chunk-JZV22DEV.js → chunk-ZGGXCFR6.js} +611 -817
- package/dist/chunk-ZGGXCFR6.js.map +1 -0
- package/dist/{collection-config-B4PG-AaF.d.cts → collection-config-JgHOpFCG.d.cts} +30 -2
- package/dist/{collection-config-B4PG-AaF.d.ts → collection-config-JgHOpFCG.d.ts} +30 -2
- package/dist/config-HFXANXCC.js +6 -0
- package/dist/config-HFXANXCC.js.map +1 -0
- package/dist/config-ON6FNMYX.cjs +19 -0
- package/dist/config-ON6FNMYX.cjs.map +1 -0
- package/dist/define-plugin-BzNHc1ZI.d.ts +1321 -0
- package/dist/define-plugin-IWDKYaVm.d.cts +1321 -0
- package/dist/document-projection-TDWRJX3Z.cjs +13 -0
- package/dist/document-projection-TDWRJX3Z.cjs.map +1 -0
- package/dist/document-projection-YYMC6I4U.js +4 -0
- package/dist/document-projection-YYMC6I4U.js.map +1 -0
- package/dist/index.cjs +13734 -4328
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +329 -492
- package/dist/index.d.ts +329 -492
- package/dist/index.js +13385 -3998
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +36 -32
- package/dist/middleware.d.cts +50 -7
- package/dist/middleware.d.ts +50 -7
- package/dist/middleware.js +7 -3
- package/dist/migrations-NJJWQUKK.cjs +13 -0
- package/dist/{migrations-566IIPS2.cjs.map → migrations-NJJWQUKK.cjs.map} +1 -1
- package/dist/migrations-WCAVBD7C.js +4 -0
- package/dist/{migrations-H5IXZNCO.js.map → migrations-WCAVBD7C.js.map} +1 -1
- package/dist/{plugin-bootstrap-DfVerYV4.d.cts → plugin-bootstrap-B8ThJU21.d.cts} +4315 -1661
- package/dist/{plugin-bootstrap-P_ciLp_C.d.ts → plugin-bootstrap-qu8hJgUt.d.ts} +4315 -1661
- package/dist/plugins.cjs +171 -12
- package/dist/plugins.d.cts +36 -2
- package/dist/plugins.d.ts +36 -2
- package/dist/plugins.js +5 -2
- package/dist/rbac-O73MFKDA.js +5 -0
- package/dist/rbac-O73MFKDA.js.map +1 -0
- package/dist/rbac-VONLJJKB.cjs +14 -0
- package/dist/rbac-VONLJJKB.cjs.map +1 -0
- package/dist/routes.cjs +41 -45
- package/dist/routes.d.cts +56 -146
- package/dist/routes.d.ts +56 -146
- package/dist/routes.js +17 -9
- package/dist/services.cjs +39 -72
- package/dist/services.d.cts +79 -54
- package/dist/services.d.ts +79 -54
- package/dist/services.js +6 -3
- package/dist/templates.cjs +17 -29
- package/dist/templates.d.cts +1 -66
- package/dist/templates.d.ts +1 -66
- package/dist/templates.js +3 -3
- package/dist/types-Dea1eNxU.d.cts +286 -0
- package/dist/types-Dea1eNxU.d.ts +286 -0
- package/dist/types.d.cts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utils.cjs +18 -17
- package/dist/utils.d.cts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +2 -1
- package/migrations/0001_core.sql +184 -0
- package/migrations/0002_documents.sql +163 -0
- package/package.json +12 -7
- package/dist/admin-layout-catalyst.template-HFD37TY5.cjs +0 -17
- package/dist/admin-layout-catalyst.template-UMTIN66R.js +0 -7
- package/dist/app-C9esKLmh.d.cts +0 -112
- package/dist/app-C9esKLmh.d.ts +0 -112
- package/dist/chunk-4NPCDK6B.js.map +0 -1
- package/dist/chunk-4ZSNJDLS.cjs.map +0 -1
- package/dist/chunk-55RDMDOP.js.map +0 -1
- package/dist/chunk-635JAMSE.cjs +0 -653
- package/dist/chunk-635JAMSE.cjs.map +0 -1
- package/dist/chunk-7A4CB7T3.cjs.map +0 -1
- package/dist/chunk-ABB34XUS.cjs.map +0 -1
- package/dist/chunk-BU7SFHGP.js.map +0 -1
- package/dist/chunk-E4YFJBM2.cjs.map +0 -1
- package/dist/chunk-EXNEW5US.js +0 -648
- package/dist/chunk-EXNEW5US.js.map +0 -1
- package/dist/chunk-JZV22DEV.js.map +0 -1
- package/dist/chunk-JZVHLLSI.cjs.map +0 -1
- package/dist/chunk-OCL3HMEG.js.map +0 -1
- package/dist/chunk-OHYBNCVL.cjs.map +0 -1
- package/dist/chunk-ON5ZMSU4.js.map +0 -1
- package/dist/chunk-QFWHAFEO.js.map +0 -1
- package/dist/chunk-R4FOLLFB.cjs.map +0 -1
- package/dist/chunk-RLMUFFUD.cjs +0 -2219
- package/dist/chunk-RLMUFFUD.cjs.map +0 -1
- package/dist/chunk-TFNTM3OA.js.map +0 -1
- package/dist/chunk-UYJ6TJHX.cjs.map +0 -1
- package/dist/chunk-WAEQXGCX.cjs +0 -1898
- package/dist/chunk-WAEQXGCX.cjs.map +0 -1
- package/dist/chunk-XWIA3HVX.js.map +0 -1
- package/dist/chunk-ZYAYUIZE.js +0 -2217
- package/dist/chunk-ZYAYUIZE.js.map +0 -1
- package/dist/migrations-566IIPS2.cjs +0 -13
- package/dist/migrations-H5IXZNCO.js +0 -4
- package/dist/plugin-manager-BoM3Q7o7.d.cts +0 -328
- package/dist/plugin-manager-Efx9RyDX.d.ts +0 -328
- package/migrations/001_initial_schema.sql +0 -170
- package/migrations/002_faq_plugin.sql +0 -86
- package/migrations/003_stage5_enhancements.sql +0 -121
- package/migrations/004_stage6_user_management.sql +0 -183
- package/migrations/005_stage7_workflow_automation.sql +0 -294
- package/migrations/006_plugin_system.sql +0 -155
- package/migrations/007_demo_login_plugin.sql +0 -23
- package/migrations/008_fix_slug_validation.sql +0 -22
- package/migrations/009_system_logging.sql +0 -57
- package/migrations/011_config_managed_collections.sql +0 -15
- package/migrations/012_testimonials_plugin.sql +0 -80
- package/migrations/013_code_examples_plugin.sql +0 -177
- package/migrations/014_fix_plugin_registry.sql +0 -88
- package/migrations/015_add_remaining_plugins.sql +0 -89
- package/migrations/016_remove_duplicate_cache_plugin.sql +0 -17
- package/migrations/017_auth_configurable_fields.sql +0 -49
- package/migrations/018_settings_table.sql +0 -23
- package/migrations/019_remove_blog_posts_collection.sql +0 -15
- package/migrations/020_add_email_plugin.sql +0 -22
- package/migrations/021_add_magic_link_auth_plugin.sql +0 -42
- package/migrations/022_add_tinymce_plugin.sql +0 -25
- package/migrations/023_add_easy_mdx_plugin.sql +0 -25
- package/migrations/024_add_quill_editor_plugin.sql +0 -25
- package/migrations/025_add_easymde_plugin.sql +0 -25
- package/migrations/026_add_otp_login.sql +0 -42
- package/migrations/027_fix_slug_field_type.sql +0 -18
- package/migrations/028_fix_slug_field_type_in_schemas.sql +0 -30
- package/migrations/029_add_forms_system.sql +0 -184
- package/migrations/030_add_turnstile_to_forms.sql +0 -14
- package/migrations/031_ai_search_plugin.sql +0 -45
- package/migrations/032_user_profiles.sql +0 -37
- package/migrations/033_form_content_integration.sql +0 -19
- package/migrations/034_security_audit_plugin.sql +0 -27
- package/migrations/035_user_profiles_data_column.sql +0 -16
- 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"]}
|