page-action-cache 1.0.1

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 (73) hide show
  1. package/dist/actions-executor.d.ts +62 -0
  2. package/dist/actions-executor.d.ts.map +1 -0
  3. package/dist/actions-executor.js +339 -0
  4. package/dist/actions-executor.js.map +1 -0
  5. package/dist/cache-invalidator.d.ts +70 -0
  6. package/dist/cache-invalidator.d.ts.map +1 -0
  7. package/dist/cache-invalidator.js +212 -0
  8. package/dist/cache-invalidator.js.map +1 -0
  9. package/dist/cache-store.d.ts +80 -0
  10. package/dist/cache-store.d.ts.map +1 -0
  11. package/dist/cache-store.js +361 -0
  12. package/dist/cache-store.js.map +1 -0
  13. package/dist/cache-strategy.d.ts +65 -0
  14. package/dist/cache-strategy.d.ts.map +1 -0
  15. package/dist/cache-strategy.js +237 -0
  16. package/dist/cache-strategy.js.map +1 -0
  17. package/dist/hooks-entry.d.ts +18 -0
  18. package/dist/hooks-entry.d.ts.map +1 -0
  19. package/dist/hooks-entry.js +27 -0
  20. package/dist/hooks-entry.js.map +1 -0
  21. package/dist/hooks.d.ts +10 -0
  22. package/dist/hooks.d.ts.map +1 -0
  23. package/dist/hooks.js +277 -0
  24. package/dist/hooks.js.map +1 -0
  25. package/dist/index.d.ts +24 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +34 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/scenario-recognizer.d.ts +45 -0
  30. package/dist/scenario-recognizer.d.ts.map +1 -0
  31. package/dist/scenario-recognizer.js +213 -0
  32. package/dist/scenario-recognizer.js.map +1 -0
  33. package/dist/security-policy.d.ts +62 -0
  34. package/dist/security-policy.d.ts.map +1 -0
  35. package/dist/security-policy.js +219 -0
  36. package/dist/security-policy.js.map +1 -0
  37. package/dist/tools.d.ts +209 -0
  38. package/dist/tools.d.ts.map +1 -0
  39. package/dist/tools.js +383 -0
  40. package/dist/tools.js.map +1 -0
  41. package/dist/types.d.ts +336 -0
  42. package/dist/types.d.ts.map +1 -0
  43. package/dist/types.js +8 -0
  44. package/dist/types.js.map +1 -0
  45. package/dist/ux-enhancer.d.ts +60 -0
  46. package/dist/ux-enhancer.d.ts.map +1 -0
  47. package/dist/ux-enhancer.js +218 -0
  48. package/dist/ux-enhancer.js.map +1 -0
  49. package/dist/variable-resolver.d.ts +28 -0
  50. package/dist/variable-resolver.d.ts.map +1 -0
  51. package/dist/variable-resolver.js +201 -0
  52. package/dist/variable-resolver.js.map +1 -0
  53. package/docs/API.md +555 -0
  54. package/docs/IMPLEMENTATION.md +1792 -0
  55. package/docs/INTEGRATION.md +387 -0
  56. package/docs/README.md +183 -0
  57. package/index.ts +118 -0
  58. package/openclaw.plugin.json +208 -0
  59. package/package.json +76 -0
  60. package/skills/page-action-cache/SKILL.md +216 -0
  61. package/src/actions-executor.ts +441 -0
  62. package/src/cache-invalidator.ts +271 -0
  63. package/src/cache-store.ts +457 -0
  64. package/src/cache-strategy.ts +327 -0
  65. package/src/hooks-entry.ts +114 -0
  66. package/src/hooks.ts +332 -0
  67. package/src/index.ts +104 -0
  68. package/src/scenario-recognizer.ts +259 -0
  69. package/src/security-policy.ts +268 -0
  70. package/src/tools.ts +437 -0
  71. package/src/types.ts +482 -0
  72. package/src/ux-enhancer.ts +266 -0
  73. package/src/variable-resolver.ts +258 -0
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Cache Invalidator
3
+ * 缓存失效检测器 - 检测页面变化并失效缓存
4
+ */
5
+ // ============================================================================
6
+ // Cache Invalidator 类
7
+ // ============================================================================
8
+ /**
9
+ * 缓存失效检测器
10
+ */
11
+ export class CacheInvalidator {
12
+ /**
13
+ * 检测页面是否发生变化
14
+ */
15
+ async detectPageChange(html, _url, _viewport, cachedEntry) {
16
+ // 计算当前 DOM hash
17
+ const currentHash = this.calculateDOMHash(html);
18
+ if (!cachedEntry || !cachedEntry.pageChangeDetection) {
19
+ return {
20
+ hasChanged: true,
21
+ changeType: "none",
22
+ confidence: 0,
23
+ domHash: currentHash,
24
+ lastCheckedAt: Date.now(),
25
+ };
26
+ }
27
+ const cachedHash = cachedEntry.pageChangeDetection.domHash;
28
+ // 比较 hash
29
+ if (currentHash === cachedHash) {
30
+ return {
31
+ hasChanged: false,
32
+ changeType: "none",
33
+ confidence: 100,
34
+ domHash: currentHash,
35
+ lastCheckedAt: Date.now(),
36
+ };
37
+ }
38
+ // 检测变化类型
39
+ const structureChanged = this.detectStructureChange(html);
40
+ const contentChanged = this.detectContentChange(html, cachedEntry);
41
+ if (structureChanged || contentChanged) {
42
+ return {
43
+ hasChanged: true,
44
+ changeType: structureChanged ? "structure" : "content",
45
+ confidence: Math.max(structureChanged ? 80 : 0, contentChanged ? 80 : 0),
46
+ domHash: currentHash,
47
+ lastCheckedAt: Date.now(),
48
+ details: structureChanged
49
+ ? "Form/Button count changed"
50
+ : "Content hash changed",
51
+ };
52
+ }
53
+ // hash 不同但结构未变,可能是动态内容
54
+ return {
55
+ hasChanged: true,
56
+ changeType: "content",
57
+ confidence: 50, // 低置信度,可能是动态内容
58
+ domHash: currentHash,
59
+ lastCheckedAt: Date.now(),
60
+ details: "Hash changed but structure is similar",
61
+ };
62
+ }
63
+ /**
64
+ * 计算 DOM hash
65
+ */
66
+ calculateDOMHash(html) {
67
+ const features = this.extractDOMFeatures(html);
68
+ return this.combineFeaturesHash(features);
69
+ }
70
+ /**
71
+ * 提取 DOM 特征
72
+ */
73
+ extractDOMFeatures(html) {
74
+ return {
75
+ formCount: this.countElements(html, "form"),
76
+ buttonCount: this.countElements(html, "button"),
77
+ linkCount: this.countElements(html, "a"),
78
+ scriptCount: this.countElements(html, "script"),
79
+ headingCount: this.countElements(html, "h1") +
80
+ this.countElements(html, "h2") +
81
+ this.countElements(html, "h3"),
82
+ };
83
+ }
84
+ /**
85
+ * 计算元素数量
86
+ */
87
+ countElements(html, tagName) {
88
+ const regex = new RegExp(`<${tagName}\\b`, "gi");
89
+ return (html.match(regex) || []).length;
90
+ }
91
+ /**
92
+ * 组合特征为 hash
93
+ */
94
+ combineFeaturesHash(features) {
95
+ const values = [
96
+ features.formCount,
97
+ features.buttonCount,
98
+ features.linkCount,
99
+ features.scriptCount,
100
+ features.headingCount,
101
+ ];
102
+ // 简单 hash 算法
103
+ let hash = 0;
104
+ for (const value of values) {
105
+ hash = ((hash << 5) - hash + value) | 0;
106
+ }
107
+ return hash.toString(16);
108
+ }
109
+ /**
110
+ * 检测结构变化
111
+ */
112
+ detectStructureChange(html) {
113
+ // 检查表单和按钮数量是否发生显著变化
114
+ const features = this.extractDOMFeatures(html);
115
+ // 如果表单数量变化,认为是结构变化
116
+ // 这里简化处理,实际应该与缓存条目比较
117
+ const hasForm = features.formCount > 0;
118
+ return !hasForm;
119
+ }
120
+ /**
121
+ * 检测内容变化
122
+ */
123
+ detectContentChange(html, cachedEntry) {
124
+ // 简化处理:检查 HTML 长度变化
125
+ const lengthChanged = Math.abs(html.length - (cachedEntry.actions.length * 100)) > 500;
126
+ return lengthChanged;
127
+ }
128
+ /**
129
+ * 判断是否应该失效缓存
130
+ */
131
+ shouldInvalidate(entry, changeResult, threshold = 80) {
132
+ // 根据页面类型和置信度决定是否失效
133
+ const pageType = entry.pageType || "mixed";
134
+ if (pageType === "static") {
135
+ // 静态页面:高置信度时失效
136
+ return changeResult.hasChanged && changeResult.confidence >= threshold;
137
+ }
138
+ else if (pageType === "dynamic") {
139
+ // 动态页面:只在结构变化时失效
140
+ return (changeResult.hasChanged && changeResult.changeType === "structure");
141
+ }
142
+ else {
143
+ // 混合页面:中等置信度时失效
144
+ return (changeResult.hasChanged && changeResult.confidence >= threshold - 10);
145
+ }
146
+ }
147
+ /**
148
+ * 创建渐进式失效器
149
+ */
150
+ createProgressiveInvalidator() {
151
+ return new ProgressiveInvalidator();
152
+ }
153
+ }
154
+ // ============================================================================
155
+ // Progressive Invalidator 类
156
+ // ============================================================================
157
+ /**
158
+ * 渐进式失效:保留多版本
159
+ */
160
+ export class ProgressiveInvalidator {
161
+ versions = new Map();
162
+ /**
163
+ * 添加版本
164
+ */
165
+ addVersion(entry, versionId) {
166
+ const key = entry.key;
167
+ if (!this.versions.has(key)) {
168
+ this.versions.set(key, []);
169
+ }
170
+ const versions = this.versions.get(key);
171
+ versions.push(versionId);
172
+ // 只保留最近的 N 个版本(默认 3 个)
173
+ if (versions.length > 3) {
174
+ versions.shift();
175
+ }
176
+ }
177
+ /**
178
+ * 获取版本列表
179
+ */
180
+ getVersions(key) {
181
+ return this.versions.get(key) || [];
182
+ }
183
+ /**
184
+ * 生成版本标识
185
+ */
186
+ generateVersion(entry) {
187
+ const time = new Date(entry.createdAt).toISOString().slice(0, 10); // YYYY-MM-DD
188
+ const pageType = entry.pageType || "unknown";
189
+ return `${pageType}-${entry.scenario}-${time}`;
190
+ }
191
+ /**
192
+ * 清理旧版本
193
+ */
194
+ cleanupOldVersions(key, maxVersions = 3) {
195
+ const versions = this.getVersions(key);
196
+ if (versions.length > maxVersions) {
197
+ const toKeep = versions.slice(-maxVersions);
198
+ this.versions.set(key, toKeep);
199
+ }
200
+ }
201
+ }
202
+ // ============================================================================
203
+ // 单例
204
+ // ============================================================================
205
+ let cacheInvalidatorInstance = null;
206
+ export function getCacheInvalidator() {
207
+ if (!cacheInvalidatorInstance) {
208
+ cacheInvalidatorInstance = new CacheInvalidator();
209
+ }
210
+ return cacheInvalidatorInstance;
211
+ }
212
+ //# sourceMappingURL=cache-invalidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-invalidator.js","sourceRoot":"","sources":["../src/cache-invalidator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Page Action Cache Store
3
+ * 管理页面操作缓存的存储
4
+ */
5
+ import type { PageActionCacheEntry, PageViewport, CacheStats, ScenarioMatch } from "./types.js";
6
+ /**
7
+ * 缓存存储管理器
8
+ */
9
+ export declare class CacheStore {
10
+ private store;
11
+ constructor();
12
+ private load;
13
+ private createEmptyStore;
14
+ private ensureCacheDir;
15
+ private save;
16
+ private scheduleSave;
17
+ private _saveTimeout;
18
+ private generateKey;
19
+ private normalizeUrl;
20
+ /**
21
+ * 设置缓存条目
22
+ */
23
+ set(url: string, viewport: PageViewport, actions: any[], metadata: {
24
+ scenario: string;
25
+ cacheLevel: "L3" | "L2" | "L1";
26
+ variables?: Record<string, string>;
27
+ description?: string;
28
+ pageType?: "static" | "dynamic" | "mixed";
29
+ }): string;
30
+ /**
31
+ * 获取缓存条目
32
+ */
33
+ get(url: string, viewport: PageViewport): PageActionCacheEntry | null;
34
+ /**
35
+ * 删除缓存条目
36
+ */
37
+ delete(url: string, viewport: PageViewport): boolean;
38
+ /**
39
+ * 按模式删除缓存条目
40
+ */
41
+ deleteByPattern(urlPattern: string): number;
42
+ /**
43
+ * 清空所有缓存
44
+ */
45
+ clear(): void;
46
+ private updateHitRate;
47
+ /**
48
+ * 更新执行统计
49
+ */
50
+ updateExecutionStats(key: string, results: Array<{
51
+ success: boolean;
52
+ duration: number;
53
+ }>): void;
54
+ /**
55
+ * 保存场景匹配
56
+ */
57
+ saveScenarioMatch(match: ScenarioMatch): void;
58
+ /**
59
+ * 获取场景匹配
60
+ */
61
+ getScenarioMatch(scenario: string): ScenarioMatch | undefined;
62
+ /**
63
+ * 获取统计信息
64
+ */
65
+ getStats(): CacheStats;
66
+ /**
67
+ * 列出所有缓存条目
68
+ */
69
+ listEntries(): PageActionCacheEntry[];
70
+ /**
71
+ * 获取热门场景
72
+ */
73
+ getTopScenarios(limit?: number): string;
74
+ /**
75
+ * 清理过期缓存
76
+ */
77
+ cleanupExpired(): number;
78
+ }
79
+ export declare function getCacheStore(): CacheStore;
80
+ //# sourceMappingURL=cache-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-store.d.ts","sourceRoot":"","sources":["../src/cache-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EACV,oBAAoB,EAEpB,YAAY,EACZ,UAAU,EACV,aAAa,EACd,MAAM,YAAY,CAAC;AA0BpB;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAuB;;IAUpC,OAAO,CAAC,IAAI;IAuBZ,OAAO,CAAC,gBAAgB;IA0BxB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,IAAI;IAgBZ,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,YAAY,CAA+B;IAMnD,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,YAAY;IAgBpB;;OAEG;IACH,GAAG,CACD,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,GAAG,EAAE,EACd,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;QAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;KAC3C,GACA,MAAM;IAwCT;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,oBAAoB,GAAG,IAAI;IA4CrE;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO;IAapD;;OAEG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAkB3C;;OAEG;IACH,KAAK,IAAI,IAAI;IAWb,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,oBAAoB,CAClB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,GACrD,IAAI;IA8BP;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAM7C;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAQ7D;;OAEG;IACH,QAAQ,IAAI,UAAU;IAItB;;OAEG;IACH,WAAW,IAAI,oBAAoB,EAAE;IAMrC;;OAEG;IACH,eAAe,CAAC,KAAK,GAAE,MAAU,GAAG,MAAM;IAqB1C;;OAEG;IACH,cAAc,IAAI,MAAM;CAkBzB;AAQD,wBAAgB,aAAa,IAAI,UAAU,CAK1C"}
@@ -0,0 +1,361 @@
1
+ /**
2
+ * Page Action Cache Store
3
+ * 管理页面操作缓存的存储
4
+ */
5
+ import fs from "node:fs";
6
+ import path from "node:path";
7
+ import { createHash } from "node:crypto";
8
+ // ============================================================================
9
+ // 配置
10
+ // ============================================================================
11
+ const CACHE_DIR = path.join(process.env.HOME || process.env.USERPROFILE || ".", ".openclaw", "cache", "page-actions");
12
+ const CACHE_FILE = path.join(CACHE_DIR, "cache.json");
13
+ const CACHE_VERSION = 1;
14
+ const DEFAULT_TTL = {
15
+ L3: 7 * 24 * 60 * 60 * 1000, // 7 天
16
+ L2: 3 * 24 * 60 * 60 * 1000, // 3 天
17
+ L1: 30 * 60 * 1000, // 30 分钟
18
+ };
19
+ // ============================================================================
20
+ // CacheStore 类
21
+ // ============================================================================
22
+ /**
23
+ * 缓存存储管理器
24
+ */
25
+ export class CacheStore {
26
+ store;
27
+ constructor() {
28
+ this.store = this.load();
29
+ }
30
+ // -------------------------------------------------------------------------
31
+ // 初始化和加载
32
+ // -------------------------------------------------------------------------
33
+ load() {
34
+ try {
35
+ if (fs.existsSync(CACHE_FILE)) {
36
+ const data = fs.readFileSync(CACHE_FILE, "utf-8");
37
+ const loaded = JSON.parse(data);
38
+ // 版本检查
39
+ if (loaded.version !== CACHE_VERSION) {
40
+ console.warn(`[CacheStore] Cache version mismatch (expected ${CACHE_VERSION}, got ${loaded.version}), clearing cache`);
41
+ return this.createEmptyStore();
42
+ }
43
+ return loaded;
44
+ }
45
+ }
46
+ catch (error) {
47
+ console.error(`[CacheStore] Failed to load cache:`, error);
48
+ }
49
+ return this.createEmptyStore();
50
+ }
51
+ createEmptyStore() {
52
+ return {
53
+ version: CACHE_VERSION,
54
+ entries: {},
55
+ scenarios: new Map(),
56
+ stats: {
57
+ totalEntries: 0,
58
+ totalHits: 0,
59
+ totalMisses: 0,
60
+ hitRate: 0,
61
+ l3Hits: 0,
62
+ l2Hits: 0,
63
+ l1Hits: 0,
64
+ scenarioMatches: 0,
65
+ llmClassifications: 0,
66
+ learnedAssociations: 0,
67
+ savedTokens: 0,
68
+ savedTime: 0,
69
+ avgExecutionTime: 0,
70
+ userConfirmations: 0,
71
+ userForcedRefreshes: 0,
72
+ cacheErrors: 0,
73
+ },
74
+ };
75
+ }
76
+ ensureCacheDir() {
77
+ if (!fs.existsSync(CACHE_DIR)) {
78
+ fs.mkdirSync(CACHE_DIR, { recursive: true });
79
+ }
80
+ }
81
+ // -------------------------------------------------------------------------
82
+ // 保存
83
+ // -------------------------------------------------------------------------
84
+ save() {
85
+ try {
86
+ this.ensureCacheDir();
87
+ // 序列化(处理 Map)
88
+ const serialized = {
89
+ ...this.store,
90
+ scenarios: Array.from(this.store.scenarios.entries()),
91
+ };
92
+ fs.writeFileSync(CACHE_FILE, JSON.stringify(serialized, null, 2));
93
+ }
94
+ catch (error) {
95
+ console.error(`[CacheStore] Failed to save cache:`, error);
96
+ }
97
+ }
98
+ scheduleSave() {
99
+ // 防抖保存(100ms)
100
+ if (this._saveTimeout) {
101
+ clearTimeout(this._saveTimeout);
102
+ }
103
+ this._saveTimeout = setTimeout(() => this.save(), 100);
104
+ }
105
+ _saveTimeout = null;
106
+ // -------------------------------------------------------------------------
107
+ // 缓存键生成
108
+ // -------------------------------------------------------------------------
109
+ generateKey(url, viewport) {
110
+ const normalizedUrl = this.normalizeUrl(url);
111
+ const viewportStr = `${viewport.width}x${viewport.height}`;
112
+ const hash = createHash("md5")
113
+ .update(`${normalizedUrl}:${viewportStr}`)
114
+ .digest("hex");
115
+ return hash || `fallback-${Date.now()}`; // 确保 hash 不为空
116
+ }
117
+ normalizeUrl(url) {
118
+ try {
119
+ const parsed = new URL(url);
120
+ // 移除查询参数和哈希(可根据配置调整)
121
+ parsed.search = "";
122
+ parsed.hash = "";
123
+ return parsed.toString();
124
+ }
125
+ catch {
126
+ return url;
127
+ }
128
+ }
129
+ // -------------------------------------------------------------------------
130
+ // 基本操作
131
+ // -------------------------------------------------------------------------
132
+ /**
133
+ * 设置缓存条目
134
+ */
135
+ set(url, viewport, actions, metadata) {
136
+ const key = this.generateKey(url, viewport);
137
+ const now = Date.now();
138
+ const ttl = DEFAULT_TTL[metadata.cacheLevel];
139
+ const entry = {
140
+ key,
141
+ url: this.normalizeUrl(url),
142
+ viewport,
143
+ cacheLevel: metadata.cacheLevel,
144
+ scenario: metadata.scenario,
145
+ description: metadata.description || `Cached ${metadata.scenario} actions`,
146
+ variables: metadata.variables,
147
+ actions,
148
+ createdAt: now,
149
+ lastAccessTime: now,
150
+ accessCount: 0,
151
+ expiresAt: now + ttl,
152
+ pageChangeDetection: {
153
+ hasChanged: false,
154
+ changeType: "none",
155
+ confidence: 100,
156
+ domHash: "",
157
+ lastCheckedAt: now,
158
+ },
159
+ source: "llm",
160
+ version: 1,
161
+ successCount: 0,
162
+ failCount: 0,
163
+ avgExecutionTime: 0,
164
+ pageType: metadata.pageType || "mixed",
165
+ };
166
+ this.store.entries[key] = entry;
167
+ this.store.stats.totalEntries++;
168
+ this.scheduleSave();
169
+ return key;
170
+ }
171
+ /**
172
+ * 获取缓存条目
173
+ */
174
+ get(url, viewport) {
175
+ const key = this.generateKey(url, viewport);
176
+ const entry = this.store.entries[key];
177
+ if (!entry) {
178
+ this.store.stats.totalMisses++;
179
+ this.updateHitRate();
180
+ return null;
181
+ }
182
+ // 检查过期
183
+ if (Date.now() > entry.expiresAt) {
184
+ delete this.store.entries[key];
185
+ this.store.stats.totalEntries--;
186
+ this.store.stats.totalMisses++;
187
+ this.updateHitRate();
188
+ this.scheduleSave();
189
+ return null;
190
+ }
191
+ // 更新访问统计
192
+ entry.lastAccessTime = Date.now();
193
+ entry.accessCount++;
194
+ // 更新层级统计
195
+ this.store.stats.totalHits++;
196
+ switch (entry.cacheLevel) {
197
+ case "L3":
198
+ this.store.stats.l3Hits++;
199
+ break;
200
+ case "L2":
201
+ this.store.stats.l2Hits++;
202
+ break;
203
+ case "L1":
204
+ this.store.stats.l1Hits++;
205
+ break;
206
+ }
207
+ this.updateHitRate();
208
+ this.scheduleSave();
209
+ return entry;
210
+ }
211
+ /**
212
+ * 删除缓存条目
213
+ */
214
+ delete(url, viewport) {
215
+ const key = this.generateKey(url, viewport);
216
+ const existed = !!this.store.entries[key];
217
+ if (existed) {
218
+ delete this.store.entries[key];
219
+ this.store.stats.totalEntries--;
220
+ this.scheduleSave();
221
+ }
222
+ return existed;
223
+ }
224
+ /**
225
+ * 按模式删除缓存条目
226
+ */
227
+ deleteByPattern(urlPattern) {
228
+ let deleted = 0;
229
+ for (const [key, entry] of Object.entries(this.store.entries)) {
230
+ if (entry.url.includes(urlPattern)) {
231
+ delete this.store.entries[key];
232
+ this.store.stats.totalEntries--;
233
+ deleted++;
234
+ }
235
+ }
236
+ if (deleted > 0) {
237
+ this.scheduleSave();
238
+ }
239
+ return deleted;
240
+ }
241
+ /**
242
+ * 清空所有缓存
243
+ */
244
+ clear() {
245
+ this.store.entries = {};
246
+ this.store.scenarios.clear();
247
+ this.store.stats = this.createEmptyStore().stats;
248
+ this.scheduleSave();
249
+ }
250
+ // -------------------------------------------------------------------------
251
+ // 统计更新
252
+ // -------------------------------------------------------------------------
253
+ updateHitRate() {
254
+ const total = this.store.stats.totalHits + this.store.stats.totalMisses;
255
+ this.store.stats.hitRate =
256
+ total > 0 ? (this.store.stats.totalHits / total) * 100 : 0;
257
+ }
258
+ /**
259
+ * 更新执行统计
260
+ */
261
+ updateExecutionStats(key, results) {
262
+ const entry = this.store.entries[key];
263
+ if (!entry)
264
+ return;
265
+ const successCount = results.filter((r) => r.success).length;
266
+ const failCount = results.length - successCount;
267
+ const avgDuration = results.reduce((sum, r) => sum + r.duration, 0) / results.length;
268
+ // 更新统计(加权平均)
269
+ const oldCount = entry.successCount + entry.failCount;
270
+ const newCount = oldCount + results.length;
271
+ entry.successCount += successCount;
272
+ entry.failCount += failCount;
273
+ entry.avgExecutionTime =
274
+ (entry.avgExecutionTime * oldCount + avgDuration * results.length) /
275
+ newCount;
276
+ // 估算节省的 token 和时间
277
+ this.store.stats.savedTokens += 5000; // 估算值
278
+ this.store.stats.savedTime += 2000; // 估算值(毫秒)
279
+ this.scheduleSave();
280
+ }
281
+ // -------------------------------------------------------------------------
282
+ // 场景匹配管理
283
+ // -------------------------------------------------------------------------
284
+ /**
285
+ * 保存场景匹配
286
+ */
287
+ saveScenarioMatch(match) {
288
+ this.store.scenarios.set(match.scenario, match);
289
+ this.store.stats.scenarioMatches++;
290
+ this.scheduleSave();
291
+ }
292
+ /**
293
+ * 获取场景匹配
294
+ */
295
+ getScenarioMatch(scenario) {
296
+ return this.store.scenarios.get(scenario);
297
+ }
298
+ // -------------------------------------------------------------------------
299
+ // 查询方法
300
+ // -------------------------------------------------------------------------
301
+ /**
302
+ * 获取统计信息
303
+ */
304
+ getStats() {
305
+ return { ...this.store.stats };
306
+ }
307
+ /**
308
+ * 列出所有缓存条目
309
+ */
310
+ listEntries() {
311
+ return Object.values(this.store.entries).sort((a, b) => b.lastAccessTime - a.lastAccessTime);
312
+ }
313
+ /**
314
+ * 获取热门场景
315
+ */
316
+ getTopScenarios(limit = 5) {
317
+ const scenarioCounts = new Map();
318
+ for (const entry of Object.values(this.store.entries)) {
319
+ const count = scenarioCounts.get(entry.scenario) || 0;
320
+ scenarioCounts.set(entry.scenario, count + entry.accessCount);
321
+ }
322
+ const sorted = Array.from(scenarioCounts.entries())
323
+ .sort((a, b) => b[1] - a[1])
324
+ .slice(0, limit);
325
+ return sorted
326
+ .map(([scenario, count]) => `- ${scenario}: ${count} 次`)
327
+ .join("\n");
328
+ }
329
+ // -------------------------------------------------------------------------
330
+ // 清理
331
+ // -------------------------------------------------------------------------
332
+ /**
333
+ * 清理过期缓存
334
+ */
335
+ cleanupExpired() {
336
+ const now = Date.now();
337
+ let cleaned = 0;
338
+ for (const [key, entry] of Object.entries(this.store.entries)) {
339
+ if (now > entry.expiresAt) {
340
+ delete this.store.entries[key];
341
+ this.store.stats.totalEntries--;
342
+ cleaned++;
343
+ }
344
+ }
345
+ if (cleaned > 0) {
346
+ this.scheduleSave();
347
+ }
348
+ return cleaned;
349
+ }
350
+ }
351
+ // ============================================================================
352
+ // 单例
353
+ // ============================================================================
354
+ let cacheStoreInstance = null;
355
+ export function getCacheStore() {
356
+ if (!cacheStoreInstance) {
357
+ cacheStoreInstance = new CacheStore();
358
+ }
359
+ return cacheStoreInstance;
360
+ }
361
+ //# sourceMappingURL=cache-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-store.js","sourceRoot":"","sources":["../src/cache-store.ts"],"names":[],"mappings":"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"}