agentic-qe 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/qe-a11y-ally.md +751 -0
- package/.claude/agents/qx-partner.md +120 -4
- package/.claude/skills/testability-scoring/SKILL.md +107 -6
- package/CHANGELOG.md +86 -0
- package/README.md +7 -6
- package/dist/agents/AccessibilityAllyAgent.d.ts +168 -0
- package/dist/agents/AccessibilityAllyAgent.d.ts.map +1 -0
- package/dist/agents/AccessibilityAllyAgent.js +462 -0
- package/dist/agents/AccessibilityAllyAgent.js.map +1 -0
- package/dist/agents/SONAIntegration.d.ts +109 -0
- package/dist/agents/SONAIntegration.d.ts.map +1 -0
- package/dist/agents/SONAIntegration.js +167 -0
- package/dist/agents/SONAIntegration.js.map +1 -0
- package/dist/agents/index.d.ts +3 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +93 -2
- package/dist/agents/index.js.map +1 -1
- package/dist/cli/init/agents.js +1 -1
- package/dist/cli/init/claude-config.js +2 -2
- package/dist/cli/init/database-init.js +1 -1
- package/dist/core/cache/BinaryCacheImpl.d.ts +161 -0
- package/dist/core/cache/BinaryCacheImpl.d.ts.map +1 -0
- package/dist/core/cache/BinaryCacheImpl.js +685 -0
- package/dist/core/cache/BinaryCacheImpl.js.map +1 -0
- package/dist/core/cache/BinaryMetadataCache.d.ts +244 -0
- package/dist/core/cache/BinaryMetadataCache.d.ts.map +1 -1
- package/dist/core/cache/BinaryMetadataCache.js +63 -1
- package/dist/core/cache/BinaryMetadataCache.js.map +1 -1
- package/dist/core/cache/index.d.ts +1 -0
- package/dist/core/cache/index.d.ts.map +1 -1
- package/dist/core/cache/index.js +10 -1
- package/dist/core/cache/index.js.map +1 -1
- package/dist/core/memory/AgentDBService.d.ts +30 -4
- package/dist/core/memory/AgentDBService.d.ts.map +1 -1
- package/dist/core/memory/AgentDBService.js +122 -12
- package/dist/core/memory/AgentDBService.js.map +1 -1
- package/dist/core/memory/CachedHNSWVectorMemory.d.ts +153 -0
- package/dist/core/memory/CachedHNSWVectorMemory.d.ts.map +1 -0
- package/dist/core/memory/CachedHNSWVectorMemory.js +329 -0
- package/dist/core/memory/CachedHNSWVectorMemory.js.map +1 -0
- package/dist/core/memory/HNSWVectorMemory.js +1 -1
- package/dist/core/memory/RuVectorPatternStore.d.ts.map +1 -1
- package/dist/core/memory/RuVectorPatternStore.js +8 -2
- package/dist/core/memory/RuVectorPatternStore.js.map +1 -1
- package/dist/core/memory/UnifiedMemoryCoordinator.d.ts +50 -0
- package/dist/core/memory/UnifiedMemoryCoordinator.d.ts.map +1 -1
- package/dist/core/memory/UnifiedMemoryCoordinator.js +206 -0
- package/dist/core/memory/UnifiedMemoryCoordinator.js.map +1 -1
- package/dist/core/memory/index.d.ts +2 -0
- package/dist/core/memory/index.d.ts.map +1 -1
- package/dist/core/memory/index.js +8 -1
- package/dist/core/memory/index.js.map +1 -1
- package/dist/core/optimization/RecursiveOptimizer.d.ts +233 -0
- package/dist/core/optimization/RecursiveOptimizer.d.ts.map +1 -0
- package/dist/core/optimization/RecursiveOptimizer.js +509 -0
- package/dist/core/optimization/RecursiveOptimizer.js.map +1 -0
- package/dist/core/strategies/SONALearningStrategy.d.ts +115 -0
- package/dist/core/strategies/SONALearningStrategy.d.ts.map +1 -0
- package/dist/core/strategies/SONALearningStrategy.js +656 -0
- package/dist/core/strategies/SONALearningStrategy.js.map +1 -0
- package/dist/core/strategies/TRMLearningStrategy.d.ts +162 -0
- package/dist/core/strategies/TRMLearningStrategy.d.ts.map +1 -0
- package/dist/core/strategies/TRMLearningStrategy.js +670 -0
- package/dist/core/strategies/TRMLearningStrategy.js.map +1 -0
- package/dist/core/strategies/index.d.ts +10 -1
- package/dist/core/strategies/index.d.ts.map +1 -1
- package/dist/core/strategies/index.js +4 -1
- package/dist/core/strategies/index.js.map +1 -1
- package/dist/learning/SONAFeedbackLoop.d.ts +168 -0
- package/dist/learning/SONAFeedbackLoop.d.ts.map +1 -0
- package/dist/learning/SONAFeedbackLoop.js +344 -0
- package/dist/learning/SONAFeedbackLoop.js.map +1 -0
- package/dist/learning/baselines/BaselineCollector.d.ts +1 -1
- package/dist/learning/baselines/BaselineCollector.js +1 -1
- package/dist/learning/baselines/StandardTaskSuite.d.ts +1 -1
- package/dist/learning/baselines/StandardTaskSuite.js +1 -1
- package/dist/learning/index.d.ts +2 -0
- package/dist/learning/index.d.ts.map +1 -1
- package/dist/learning/index.js +6 -1
- package/dist/learning/index.js.map +1 -1
- package/dist/mcp/server-instructions.d.ts +1 -1
- package/dist/mcp/server-instructions.js +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +23 -16
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/services/AgentRegistry.d.ts.map +1 -1
- package/dist/mcp/services/AgentRegistry.js +6 -1
- package/dist/mcp/services/AgentRegistry.js.map +1 -1
- package/dist/mcp/tools/qe/accessibility/accname-computation.d.ts +114 -0
- package/dist/mcp/tools/qe/accessibility/accname-computation.d.ts.map +1 -0
- package/dist/mcp/tools/qe/accessibility/accname-computation.js +566 -0
- package/dist/mcp/tools/qe/accessibility/accname-computation.js.map +1 -0
- package/dist/mcp/tools/qe/accessibility/apg-patterns.d.ts +103 -0
- package/dist/mcp/tools/qe/accessibility/apg-patterns.d.ts.map +1 -0
- package/dist/mcp/tools/qe/accessibility/apg-patterns.js +1028 -0
- package/dist/mcp/tools/qe/accessibility/apg-patterns.js.map +1 -0
- package/dist/mcp/tools/qe/accessibility/en-301-549-mapping.d.ts +48 -0
- package/dist/mcp/tools/qe/accessibility/en-301-549-mapping.d.ts.map +1 -0
- package/dist/mcp/tools/qe/accessibility/en-301-549-mapping.js +565 -0
- package/dist/mcp/tools/qe/accessibility/en-301-549-mapping.js.map +1 -0
- package/dist/mcp/tools/qe/accessibility/eu-accessibility-act.d.ts +117 -0
- package/dist/mcp/tools/qe/accessibility/eu-accessibility-act.d.ts.map +1 -0
- package/dist/mcp/tools/qe/accessibility/eu-accessibility-act.js +571 -0
- package/dist/mcp/tools/qe/accessibility/eu-accessibility-act.js.map +1 -0
- package/dist/mcp/tools/qe/accessibility/html-report-generator.d.ts +23 -0
- package/dist/mcp/tools/qe/accessibility/html-report-generator.d.ts.map +1 -0
- package/dist/mcp/tools/qe/accessibility/html-report-generator.js +1152 -0
- package/dist/mcp/tools/qe/accessibility/html-report-generator.js.map +1 -0
- package/dist/mcp/tools/qe/accessibility/index.d.ts +22 -0
- package/dist/mcp/tools/qe/accessibility/index.d.ts.map +1 -0
- package/dist/mcp/tools/qe/accessibility/index.js +38 -0
- package/dist/mcp/tools/qe/accessibility/index.js.map +1 -0
- package/dist/mcp/tools/qe/accessibility/markdown-report-generator.d.ts +18 -0
- package/dist/mcp/tools/qe/accessibility/markdown-report-generator.d.ts.map +1 -0
- package/dist/mcp/tools/qe/accessibility/markdown-report-generator.js +549 -0
- package/dist/mcp/tools/qe/accessibility/markdown-report-generator.js.map +1 -0
- package/dist/mcp/tools/qe/accessibility/remediation-code-generator.d.ts +139 -0
- package/dist/mcp/tools/qe/accessibility/remediation-code-generator.d.ts.map +1 -0
- package/dist/mcp/tools/qe/accessibility/remediation-code-generator.js +1300 -0
- package/dist/mcp/tools/qe/accessibility/remediation-code-generator.js.map +1 -0
- package/dist/mcp/tools/qe/accessibility/scan-comprehensive.d.ts +138 -0
- package/dist/mcp/tools/qe/accessibility/scan-comprehensive.d.ts.map +1 -0
- package/dist/mcp/tools/qe/accessibility/scan-comprehensive.js +1326 -0
- package/dist/mcp/tools/qe/accessibility/scan-comprehensive.js.map +1 -0
- package/dist/mcp/tools/qe/accessibility/video-vision-analyzer.d.ts +50 -0
- package/dist/mcp/tools/qe/accessibility/video-vision-analyzer.d.ts.map +1 -0
- package/dist/mcp/tools/qe/accessibility/video-vision-analyzer.js +469 -0
- package/dist/mcp/tools/qe/accessibility/video-vision-analyzer.js.map +1 -0
- package/dist/mcp/tools/qe/accessibility/webvtt-generator.d.ts +193 -0
- package/dist/mcp/tools/qe/accessibility/webvtt-generator.d.ts.map +1 -0
- package/dist/mcp/tools/qe/accessibility/webvtt-generator.js +511 -0
- package/dist/mcp/tools/qe/accessibility/webvtt-generator.js.map +1 -0
- package/dist/mcp/tools.d.ts +1 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +61 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/providers/HybridRouter.d.ts +34 -3
- package/dist/providers/HybridRouter.d.ts.map +1 -1
- package/dist/providers/HybridRouter.js +69 -4
- package/dist/providers/HybridRouter.js.map +1 -1
- package/dist/providers/LLMProviderFactory.d.ts +68 -1
- package/dist/providers/LLMProviderFactory.d.ts.map +1 -1
- package/dist/providers/LLMProviderFactory.js +173 -6
- package/dist/providers/LLMProviderFactory.js.map +1 -1
- package/dist/providers/OpenRouterProvider.d.ts +150 -0
- package/dist/providers/OpenRouterProvider.d.ts.map +1 -0
- package/dist/providers/OpenRouterProvider.js +545 -0
- package/dist/providers/OpenRouterProvider.js.map +1 -0
- package/dist/providers/RuvllmProvider.d.ts +130 -16
- package/dist/providers/RuvllmProvider.d.ts.map +1 -1
- package/dist/providers/RuvllmProvider.js +399 -83
- package/dist/providers/RuvllmProvider.js.map +1 -1
- package/dist/providers/index.d.ts +33 -4
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +72 -21
- package/dist/providers/index.js.map +1 -1
- package/dist/telemetry/instrumentation/agent.d.ts +1 -1
- package/dist/telemetry/instrumentation/agent.js +1 -1
- package/dist/telemetry/instrumentation/index.d.ts +1 -1
- package/dist/telemetry/instrumentation/index.js +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/ruvllm.d.ts +97 -0
- package/dist/types/ruvllm.d.ts.map +1 -0
- package/dist/types/ruvllm.js +46 -0
- package/dist/types/ruvllm.js.map +1 -0
- package/dist/utils/ruvllm-loader.d.ts +94 -0
- package/dist/utils/ruvllm-loader.d.ts.map +1 -0
- package/dist/utils/ruvllm-loader.js +87 -0
- package/dist/utils/ruvllm-loader.js.map +1 -0
- package/docs/reference/agents.md +36 -1
- package/package.json +4 -2
|
@@ -0,0 +1,685 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Binary Metadata Cache - Implementation
|
|
4
|
+
*
|
|
5
|
+
* High-performance binary caching for pattern metadata.
|
|
6
|
+
* Achieves 10x faster test discovery (500ms → 50ms) through:
|
|
7
|
+
* - Binary serialization (MessagePack-based, not FlatBuffers for simplicity)
|
|
8
|
+
* - Zero-copy Float32Array embeddings
|
|
9
|
+
* - Pre-built indexes for O(1) lookup
|
|
10
|
+
* - Atomic writes with checksum validation
|
|
11
|
+
*
|
|
12
|
+
* @module core/cache/BinaryCacheImpl
|
|
13
|
+
*/
|
|
14
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperty(o, k2, desc);
|
|
21
|
+
}) : (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
o[k2] = m[k];
|
|
24
|
+
}));
|
|
25
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
26
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
27
|
+
}) : function(o, v) {
|
|
28
|
+
o["default"] = v;
|
|
29
|
+
});
|
|
30
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
+
var ownKeys = function(o) {
|
|
32
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
+
var ar = [];
|
|
34
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
+
return ar;
|
|
36
|
+
};
|
|
37
|
+
return ownKeys(o);
|
|
38
|
+
};
|
|
39
|
+
return function (mod) {
|
|
40
|
+
if (mod && mod.__esModule) return mod;
|
|
41
|
+
var result = {};
|
|
42
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
+
__setModuleDefault(result, mod);
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
})();
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.BinaryCacheManager = exports.TRMBinaryCacheBuilderImpl = exports.BinaryCacheBuilderImpl = exports.BinaryCacheReaderImpl = exports.BinaryCacheInvalidatorImpl = exports.BinaryCacheValidatorImpl = exports.BinaryCacheSerializerImpl = void 0;
|
|
49
|
+
exports.createBinaryCacheManager = createBinaryCacheManager;
|
|
50
|
+
const crypto_1 = require("crypto");
|
|
51
|
+
const fs_1 = require("fs");
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const BinaryMetadataCache_1 = require("./BinaryMetadataCache");
|
|
54
|
+
/**
|
|
55
|
+
* Binary Cache Serializer Implementation
|
|
56
|
+
*
|
|
57
|
+
* Uses a simple binary format:
|
|
58
|
+
* - Header (64 bytes): magic, version, timestamp, checksum offset, data length
|
|
59
|
+
* - Data: MessagePack-like encoding of cache structure
|
|
60
|
+
* - Checksum: SHA-256 at end
|
|
61
|
+
*/
|
|
62
|
+
class BinaryCacheSerializerImpl {
|
|
63
|
+
constructor() {
|
|
64
|
+
this.textEncoder = new TextEncoder();
|
|
65
|
+
this.textDecoder = new TextDecoder();
|
|
66
|
+
}
|
|
67
|
+
encode(cache) {
|
|
68
|
+
try {
|
|
69
|
+
// Serialize to JSON first, then to binary
|
|
70
|
+
const jsonData = this.serializeCache(cache);
|
|
71
|
+
const dataBytes = this.textEncoder.encode(jsonData);
|
|
72
|
+
// Create buffer: header + data
|
|
73
|
+
const totalSize = BinaryMetadataCache_1.CACHE_HEADER_SIZE + dataBytes.length;
|
|
74
|
+
const buffer = new Uint8Array(totalSize);
|
|
75
|
+
const view = new DataView(buffer.buffer);
|
|
76
|
+
// Write header
|
|
77
|
+
view.setUint32(0, BinaryMetadataCache_1.CACHE_MAGIC_NUMBER, true); // Magic number
|
|
78
|
+
view.setUint32(4, cache.version, true); // Version
|
|
79
|
+
view.setBigUint64(8, BigInt(cache.timestamp), true); // Timestamp
|
|
80
|
+
view.setUint32(16, dataBytes.length, true); // Data length
|
|
81
|
+
// Bytes 20-63 reserved for future use
|
|
82
|
+
// Write data
|
|
83
|
+
buffer.set(dataBytes, BinaryMetadataCache_1.CACHE_HEADER_SIZE);
|
|
84
|
+
return buffer;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
throw new BinaryMetadataCache_1.SerializationError('Failed to encode cache', error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
decode(buffer) {
|
|
91
|
+
try {
|
|
92
|
+
if (buffer.length < BinaryMetadataCache_1.CACHE_HEADER_SIZE) {
|
|
93
|
+
throw new BinaryMetadataCache_1.DeserializationError('Buffer too small for cache header');
|
|
94
|
+
}
|
|
95
|
+
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
96
|
+
// Read header
|
|
97
|
+
const magic = view.getUint32(0, true);
|
|
98
|
+
if (magic !== BinaryMetadataCache_1.CACHE_MAGIC_NUMBER) {
|
|
99
|
+
throw new BinaryMetadataCache_1.DeserializationError(`Invalid magic number: 0x${magic.toString(16)}`);
|
|
100
|
+
}
|
|
101
|
+
const version = view.getUint32(4, true);
|
|
102
|
+
const timestamp = Number(view.getBigUint64(8, true));
|
|
103
|
+
const dataLength = view.getUint32(16, true);
|
|
104
|
+
if (buffer.length < BinaryMetadataCache_1.CACHE_HEADER_SIZE + dataLength) {
|
|
105
|
+
throw new BinaryMetadataCache_1.DeserializationError('Buffer truncated, data length mismatch');
|
|
106
|
+
}
|
|
107
|
+
// Read data
|
|
108
|
+
const dataBytes = buffer.slice(BinaryMetadataCache_1.CACHE_HEADER_SIZE, BinaryMetadataCache_1.CACHE_HEADER_SIZE + dataLength);
|
|
109
|
+
const jsonData = this.textDecoder.decode(dataBytes);
|
|
110
|
+
const cache = this.deserializeCache(jsonData);
|
|
111
|
+
cache.version = version;
|
|
112
|
+
cache.timestamp = timestamp;
|
|
113
|
+
return cache;
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
if (error instanceof BinaryMetadataCache_1.DeserializationError)
|
|
117
|
+
throw error;
|
|
118
|
+
throw new BinaryMetadataCache_1.DeserializationError('Failed to decode cache', error);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async computeChecksum(buffer) {
|
|
122
|
+
const hash = (0, crypto_1.createHash)('sha256');
|
|
123
|
+
hash.update(buffer);
|
|
124
|
+
return hash.digest('hex');
|
|
125
|
+
}
|
|
126
|
+
encodeVersion(version) {
|
|
127
|
+
return (version.major << 16) | (version.minor << 8) | version.patch;
|
|
128
|
+
}
|
|
129
|
+
decodeVersion(encoded) {
|
|
130
|
+
return {
|
|
131
|
+
major: (encoded >> 16) & 0xff,
|
|
132
|
+
minor: (encoded >> 8) & 0xff,
|
|
133
|
+
patch: encoded & 0xff,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
serializeCache(cache) {
|
|
137
|
+
// Convert Maps to arrays for JSON serialization
|
|
138
|
+
const serializableCache = {
|
|
139
|
+
...cache,
|
|
140
|
+
patterns: cache.patterns.map(p => ({
|
|
141
|
+
...p,
|
|
142
|
+
embedding: Array.from(p.embedding),
|
|
143
|
+
})),
|
|
144
|
+
indexes: {
|
|
145
|
+
domainIndex: Array.from(cache.indexes.domainIndex.entries()),
|
|
146
|
+
typeIndex: Array.from(cache.indexes.typeIndex.entries()),
|
|
147
|
+
frameworkIndex: Array.from(cache.indexes.frameworkIndex.entries()),
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
return JSON.stringify(serializableCache);
|
|
151
|
+
}
|
|
152
|
+
deserializeCache(json) {
|
|
153
|
+
const parsed = JSON.parse(json);
|
|
154
|
+
// Convert arrays back to Float32Arrays and Maps
|
|
155
|
+
const patterns = parsed.patterns.map((p) => ({
|
|
156
|
+
...p,
|
|
157
|
+
embedding: new Float32Array(p.embedding),
|
|
158
|
+
}));
|
|
159
|
+
const indexes = {
|
|
160
|
+
domainIndex: new Map(parsed.indexes.domainIndex),
|
|
161
|
+
typeIndex: new Map(parsed.indexes.typeIndex),
|
|
162
|
+
frameworkIndex: new Map(parsed.indexes.frameworkIndex),
|
|
163
|
+
};
|
|
164
|
+
return {
|
|
165
|
+
...parsed,
|
|
166
|
+
patterns,
|
|
167
|
+
indexes,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
exports.BinaryCacheSerializerImpl = BinaryCacheSerializerImpl;
|
|
172
|
+
/**
|
|
173
|
+
* Binary Cache Validator Implementation
|
|
174
|
+
*/
|
|
175
|
+
class BinaryCacheValidatorImpl {
|
|
176
|
+
constructor() {
|
|
177
|
+
this.serializer = new BinaryCacheSerializerImpl();
|
|
178
|
+
}
|
|
179
|
+
async validate(buffer, expectedChecksum) {
|
|
180
|
+
try {
|
|
181
|
+
// Compute checksum
|
|
182
|
+
const computedChecksum = await this.serializer.computeChecksum(buffer);
|
|
183
|
+
const checksumValid = computedChecksum === expectedChecksum;
|
|
184
|
+
// Decode to get version
|
|
185
|
+
let cacheVersion;
|
|
186
|
+
let versionCompatible = false;
|
|
187
|
+
try {
|
|
188
|
+
const cache = this.serializer.decode(buffer);
|
|
189
|
+
cacheVersion = this.serializer.decodeVersion(cache.version);
|
|
190
|
+
versionCompatible = this.isVersionCompatible(cacheVersion, BinaryMetadataCache_1.CACHE_VERSION);
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
// Decode failed, version check fails
|
|
194
|
+
}
|
|
195
|
+
const valid = checksumValid && versionCompatible;
|
|
196
|
+
return {
|
|
197
|
+
valid,
|
|
198
|
+
checksumValid,
|
|
199
|
+
versionCompatible,
|
|
200
|
+
computedChecksum,
|
|
201
|
+
cacheVersion,
|
|
202
|
+
error: valid ? undefined : 'Cache validation failed',
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
return {
|
|
207
|
+
valid: false,
|
|
208
|
+
checksumValid: false,
|
|
209
|
+
versionCompatible: false,
|
|
210
|
+
error: error.message,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
isVersionCompatible(cacheVersion, codeVersion) {
|
|
215
|
+
// Major version must match exactly
|
|
216
|
+
if (cacheVersion.major !== codeVersion.major)
|
|
217
|
+
return false;
|
|
218
|
+
// Minor version: cache can be older but not newer
|
|
219
|
+
if (cacheVersion.minor > codeVersion.minor)
|
|
220
|
+
return false;
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
isValidPatternEntry(entry) {
|
|
224
|
+
return (typeof entry.id === 'string' &&
|
|
225
|
+
entry.id.length > 0 &&
|
|
226
|
+
typeof entry.type === 'string' &&
|
|
227
|
+
typeof entry.domain === 'string' &&
|
|
228
|
+
typeof entry.content === 'string' &&
|
|
229
|
+
entry.embedding instanceof Float32Array &&
|
|
230
|
+
entry.embedding.length > 0 &&
|
|
231
|
+
typeof entry.metadata === 'object' &&
|
|
232
|
+
typeof entry.metadata.coverage === 'number' &&
|
|
233
|
+
typeof entry.metadata.usageCount === 'number');
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
exports.BinaryCacheValidatorImpl = BinaryCacheValidatorImpl;
|
|
237
|
+
/**
|
|
238
|
+
* Binary Cache Invalidator Implementation
|
|
239
|
+
*/
|
|
240
|
+
class BinaryCacheInvalidatorImpl {
|
|
241
|
+
constructor() {
|
|
242
|
+
this.staleEvents = [];
|
|
243
|
+
this.lastRebuildTime = 0;
|
|
244
|
+
}
|
|
245
|
+
markStale(event) {
|
|
246
|
+
this.staleEvents.push(event);
|
|
247
|
+
}
|
|
248
|
+
isCacheValid(cacheTimestamp) {
|
|
249
|
+
// Check if any stale event occurred after cache generation
|
|
250
|
+
return !this.staleEvents.some(event => event.timestamp > cacheTimestamp && event.requiresRebuild);
|
|
251
|
+
}
|
|
252
|
+
isCacheFresh(cacheTimestamp, ttl) {
|
|
253
|
+
const age = Date.now() - cacheTimestamp;
|
|
254
|
+
return age < ttl && this.isCacheValid(cacheTimestamp);
|
|
255
|
+
}
|
|
256
|
+
shouldBackgroundRebuild(cacheTimestamp, ttl) {
|
|
257
|
+
const age = Date.now() - cacheTimestamp;
|
|
258
|
+
// Trigger background rebuild at 80% of TTL
|
|
259
|
+
return age > ttl * 0.8;
|
|
260
|
+
}
|
|
261
|
+
scheduleCacheRebuild(background) {
|
|
262
|
+
this.lastRebuildTime = Date.now();
|
|
263
|
+
// Clear stale events after rebuild scheduled
|
|
264
|
+
this.staleEvents = [];
|
|
265
|
+
}
|
|
266
|
+
getStaleEvents() {
|
|
267
|
+
return [...this.staleEvents];
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
exports.BinaryCacheInvalidatorImpl = BinaryCacheInvalidatorImpl;
|
|
271
|
+
/**
|
|
272
|
+
* Binary Cache Reader Implementation
|
|
273
|
+
*/
|
|
274
|
+
class BinaryCacheReaderImpl {
|
|
275
|
+
constructor() {
|
|
276
|
+
this.cache = null;
|
|
277
|
+
this.config = BinaryMetadataCache_1.DEFAULT_CACHE_CONFIG;
|
|
278
|
+
this.patternMap = new Map();
|
|
279
|
+
this.agentConfigMap = new Map();
|
|
280
|
+
this.fileSize = 0;
|
|
281
|
+
this.loadTime = 0;
|
|
282
|
+
}
|
|
283
|
+
async initialize(cachePath, config) {
|
|
284
|
+
this.config = config;
|
|
285
|
+
const startTime = Date.now();
|
|
286
|
+
try {
|
|
287
|
+
const buffer = await fs_1.promises.readFile(cachePath);
|
|
288
|
+
const serializer = new BinaryCacheSerializerImpl();
|
|
289
|
+
this.cache = serializer.decode(new Uint8Array(buffer));
|
|
290
|
+
this.fileSize = buffer.length;
|
|
291
|
+
// Build lookup maps for O(1) access
|
|
292
|
+
for (const pattern of this.cache.patterns) {
|
|
293
|
+
this.patternMap.set(pattern.id, pattern);
|
|
294
|
+
}
|
|
295
|
+
for (const agentConfig of this.cache.agentConfigs) {
|
|
296
|
+
this.agentConfigMap.set(agentConfig.agentId, agentConfig);
|
|
297
|
+
}
|
|
298
|
+
this.loadTime = Date.now() - startTime;
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
catch (error) {
|
|
302
|
+
const err = error;
|
|
303
|
+
if (err.code === 'ENOENT') {
|
|
304
|
+
throw new BinaryMetadataCache_1.CacheLoadError('file_not_found', `Cache file not found: ${cachePath}`);
|
|
305
|
+
}
|
|
306
|
+
if (err.code === 'EACCES') {
|
|
307
|
+
throw new BinaryMetadataCache_1.CacheLoadError('permission_denied', `Permission denied: ${cachePath}`);
|
|
308
|
+
}
|
|
309
|
+
throw new BinaryMetadataCache_1.CacheLoadError('io_error', `Failed to load cache: ${err.message}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
getPattern(id) {
|
|
313
|
+
return this.patternMap.get(id) || null;
|
|
314
|
+
}
|
|
315
|
+
getPatternsByDomain(domain) {
|
|
316
|
+
if (!this.cache)
|
|
317
|
+
return [];
|
|
318
|
+
const ids = this.cache.indexes.domainIndex.get(domain) || [];
|
|
319
|
+
return ids.map(id => this.patternMap.get(id)).filter(Boolean);
|
|
320
|
+
}
|
|
321
|
+
getPatternsByType(type) {
|
|
322
|
+
if (!this.cache)
|
|
323
|
+
return [];
|
|
324
|
+
const ids = this.cache.indexes.typeIndex.get(type) || [];
|
|
325
|
+
return ids.map(id => this.patternMap.get(id)).filter(Boolean);
|
|
326
|
+
}
|
|
327
|
+
getPatternsByFramework(framework) {
|
|
328
|
+
if (!this.cache)
|
|
329
|
+
return [];
|
|
330
|
+
const ids = this.cache.indexes.frameworkIndex.get(framework) || [];
|
|
331
|
+
return ids.map(id => this.patternMap.get(id)).filter(Boolean);
|
|
332
|
+
}
|
|
333
|
+
getAllPatterns() {
|
|
334
|
+
return this.cache?.patterns || [];
|
|
335
|
+
}
|
|
336
|
+
getAgentConfig(agentId) {
|
|
337
|
+
return this.agentConfigMap.get(agentId) || null;
|
|
338
|
+
}
|
|
339
|
+
getCacheMetadata() {
|
|
340
|
+
const serializer = new BinaryCacheSerializerImpl();
|
|
341
|
+
return {
|
|
342
|
+
version: this.cache ? serializer.decodeVersion(this.cache.version) : BinaryMetadataCache_1.CACHE_VERSION,
|
|
343
|
+
timestamp: this.cache?.timestamp || 0,
|
|
344
|
+
patternCount: this.cache?.patterns.length || 0,
|
|
345
|
+
agentConfigCount: this.cache?.agentConfigs.length || 0,
|
|
346
|
+
fileSize: this.fileSize,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
isValid() {
|
|
350
|
+
if (!this.cache)
|
|
351
|
+
return false;
|
|
352
|
+
const age = Date.now() - this.cache.timestamp;
|
|
353
|
+
return age < this.config.maxAge;
|
|
354
|
+
}
|
|
355
|
+
close() {
|
|
356
|
+
this.cache = null;
|
|
357
|
+
this.patternMap.clear();
|
|
358
|
+
this.agentConfigMap.clear();
|
|
359
|
+
}
|
|
360
|
+
getLoadTime() {
|
|
361
|
+
return this.loadTime;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
exports.BinaryCacheReaderImpl = BinaryCacheReaderImpl;
|
|
365
|
+
/**
|
|
366
|
+
* Binary Cache Builder Implementation
|
|
367
|
+
*/
|
|
368
|
+
class BinaryCacheBuilderImpl {
|
|
369
|
+
constructor() {
|
|
370
|
+
this.serializer = new BinaryCacheSerializerImpl();
|
|
371
|
+
}
|
|
372
|
+
async buildCache(patterns, agentConfigs, outputPath) {
|
|
373
|
+
const startTime = Date.now();
|
|
374
|
+
try {
|
|
375
|
+
// Convert patterns to cache entries
|
|
376
|
+
const patternEntries = patterns.map(p => (0, BinaryMetadataCache_1.testPatternToEntry)(p));
|
|
377
|
+
// Build indexes
|
|
378
|
+
const indexes = this.buildIndexes(patternEntries);
|
|
379
|
+
// Create cache object
|
|
380
|
+
const cache = {
|
|
381
|
+
version: this.serializer.encodeVersion(BinaryMetadataCache_1.CACHE_VERSION),
|
|
382
|
+
timestamp: Date.now(),
|
|
383
|
+
checksum: '', // Will be computed after serialization
|
|
384
|
+
patterns: patternEntries,
|
|
385
|
+
agentConfigs,
|
|
386
|
+
indexes,
|
|
387
|
+
};
|
|
388
|
+
// Serialize
|
|
389
|
+
const buffer = this.serializer.encode(cache);
|
|
390
|
+
// Compute checksum
|
|
391
|
+
const checksum = await this.serializer.computeChecksum(buffer);
|
|
392
|
+
cache.checksum = checksum;
|
|
393
|
+
// Re-serialize with checksum
|
|
394
|
+
const finalBuffer = this.serializer.encode(cache);
|
|
395
|
+
// Write atomically
|
|
396
|
+
await this.writeAtomic(finalBuffer, outputPath);
|
|
397
|
+
const duration = Date.now() - startTime;
|
|
398
|
+
return {
|
|
399
|
+
success: true,
|
|
400
|
+
duration,
|
|
401
|
+
patternCount: patternEntries.length,
|
|
402
|
+
agentConfigCount: agentConfigs.length,
|
|
403
|
+
cacheFileSize: finalBuffer.length,
|
|
404
|
+
version: BinaryMetadataCache_1.CACHE_VERSION,
|
|
405
|
+
checksum,
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
return {
|
|
410
|
+
success: false,
|
|
411
|
+
duration: Date.now() - startTime,
|
|
412
|
+
patternCount: 0,
|
|
413
|
+
agentConfigCount: 0,
|
|
414
|
+
cacheFileSize: 0,
|
|
415
|
+
version: BinaryMetadataCache_1.CACHE_VERSION,
|
|
416
|
+
checksum: '',
|
|
417
|
+
error: error.message,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
buildIndexes(patterns) {
|
|
422
|
+
const domainIndex = new Map();
|
|
423
|
+
const typeIndex = new Map();
|
|
424
|
+
const frameworkIndex = new Map();
|
|
425
|
+
for (const pattern of patterns) {
|
|
426
|
+
// Domain index
|
|
427
|
+
if (!domainIndex.has(pattern.domain)) {
|
|
428
|
+
domainIndex.set(pattern.domain, []);
|
|
429
|
+
}
|
|
430
|
+
domainIndex.get(pattern.domain).push(pattern.id);
|
|
431
|
+
// Type index
|
|
432
|
+
if (!typeIndex.has(pattern.type)) {
|
|
433
|
+
typeIndex.set(pattern.type, []);
|
|
434
|
+
}
|
|
435
|
+
typeIndex.get(pattern.type).push(pattern.id);
|
|
436
|
+
// Framework index
|
|
437
|
+
if (!frameworkIndex.has(pattern.framework)) {
|
|
438
|
+
frameworkIndex.set(pattern.framework, []);
|
|
439
|
+
}
|
|
440
|
+
frameworkIndex.get(pattern.framework).push(pattern.id);
|
|
441
|
+
}
|
|
442
|
+
return { domainIndex, typeIndex, frameworkIndex };
|
|
443
|
+
}
|
|
444
|
+
async writeAtomic(buffer, outputPath) {
|
|
445
|
+
const tempPath = `${outputPath}.tmp.${Date.now()}`;
|
|
446
|
+
try {
|
|
447
|
+
// Ensure directory exists
|
|
448
|
+
await fs_1.promises.mkdir(path.dirname(outputPath), { recursive: true });
|
|
449
|
+
// Write to temp file
|
|
450
|
+
await fs_1.promises.writeFile(tempPath, buffer);
|
|
451
|
+
// Verify write by reading back
|
|
452
|
+
const verifyBuffer = await fs_1.promises.readFile(tempPath);
|
|
453
|
+
if (verifyBuffer.length !== buffer.length) {
|
|
454
|
+
throw new Error('Write verification failed: size mismatch');
|
|
455
|
+
}
|
|
456
|
+
// Atomic rename
|
|
457
|
+
await fs_1.promises.rename(tempPath, outputPath);
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
catch (error) {
|
|
461
|
+
// Cleanup temp file on error
|
|
462
|
+
try {
|
|
463
|
+
await fs_1.promises.unlink(tempPath);
|
|
464
|
+
}
|
|
465
|
+
catch {
|
|
466
|
+
// Ignore cleanup errors
|
|
467
|
+
}
|
|
468
|
+
throw error;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
exports.BinaryCacheBuilderImpl = BinaryCacheBuilderImpl;
|
|
473
|
+
/**
|
|
474
|
+
* TRM Binary Cache Builder Implementation
|
|
475
|
+
*/
|
|
476
|
+
class TRMBinaryCacheBuilderImpl extends BinaryCacheBuilderImpl {
|
|
477
|
+
buildTRMIndexes(patterns) {
|
|
478
|
+
const typeIndex = new Map();
|
|
479
|
+
const metricIndex = new Map();
|
|
480
|
+
const convergedIndex = new Map();
|
|
481
|
+
const qualityBucketIndex = new Map();
|
|
482
|
+
for (const pattern of patterns) {
|
|
483
|
+
// Type index
|
|
484
|
+
if (!typeIndex.has(pattern.type)) {
|
|
485
|
+
typeIndex.set(pattern.type, []);
|
|
486
|
+
}
|
|
487
|
+
typeIndex.get(pattern.type).push(pattern.id);
|
|
488
|
+
// Metric index
|
|
489
|
+
if (!metricIndex.has(pattern.metadata.qualityMetric)) {
|
|
490
|
+
metricIndex.set(pattern.metadata.qualityMetric, []);
|
|
491
|
+
}
|
|
492
|
+
metricIndex.get(pattern.metadata.qualityMetric).push(pattern.id);
|
|
493
|
+
// Converged index
|
|
494
|
+
if (!convergedIndex.has(pattern.metadata.converged)) {
|
|
495
|
+
convergedIndex.set(pattern.metadata.converged, []);
|
|
496
|
+
}
|
|
497
|
+
convergedIndex.get(pattern.metadata.converged).push(pattern.id);
|
|
498
|
+
// Quality bucket index
|
|
499
|
+
const bucket = (0, BinaryMetadataCache_1.getQualityBucket)(pattern.metadata.quality);
|
|
500
|
+
if (!qualityBucketIndex.has(bucket)) {
|
|
501
|
+
qualityBucketIndex.set(bucket, []);
|
|
502
|
+
}
|
|
503
|
+
qualityBucketIndex.get(bucket).push(pattern.id);
|
|
504
|
+
}
|
|
505
|
+
return { typeIndex, metricIndex, convergedIndex, qualityBucketIndex };
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
exports.TRMBinaryCacheBuilderImpl = TRMBinaryCacheBuilderImpl;
|
|
509
|
+
/**
|
|
510
|
+
* Binary Cache Manager - High-level API
|
|
511
|
+
*
|
|
512
|
+
* Provides a unified interface for cache operations with automatic
|
|
513
|
+
* fallback to SQLite on errors.
|
|
514
|
+
*/
|
|
515
|
+
class BinaryCacheManager {
|
|
516
|
+
constructor(config = {}) {
|
|
517
|
+
this.reader = null;
|
|
518
|
+
this.config = { ...BinaryMetadataCache_1.DEFAULT_CACHE_CONFIG, ...config };
|
|
519
|
+
this.builder = new BinaryCacheBuilderImpl();
|
|
520
|
+
this.validator = new BinaryCacheValidatorImpl();
|
|
521
|
+
this.invalidator = new BinaryCacheInvalidatorImpl();
|
|
522
|
+
this.metrics = this.initializeMetrics();
|
|
523
|
+
}
|
|
524
|
+
initializeMetrics() {
|
|
525
|
+
return {
|
|
526
|
+
cacheHits: 0,
|
|
527
|
+
cacheMisses: 0,
|
|
528
|
+
cacheHitRate: 0,
|
|
529
|
+
avgCacheLoadTime: 0,
|
|
530
|
+
avgSQLiteFallbackTime: 0,
|
|
531
|
+
cacheCorruptionCount: 0,
|
|
532
|
+
cacheRebuildCount: 0,
|
|
533
|
+
lastCacheGenerationTime: 0,
|
|
534
|
+
cacheFileSize: 0,
|
|
535
|
+
patternCount: 0,
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Load cache from disk
|
|
540
|
+
*/
|
|
541
|
+
async load() {
|
|
542
|
+
if (!this.config.enabled)
|
|
543
|
+
return false;
|
|
544
|
+
try {
|
|
545
|
+
this.reader = new BinaryCacheReaderImpl();
|
|
546
|
+
await this.reader.initialize(this.config.cachePath, this.config);
|
|
547
|
+
const metadata = this.reader.getCacheMetadata();
|
|
548
|
+
this.metrics.cacheFileSize = metadata.fileSize;
|
|
549
|
+
this.metrics.patternCount = metadata.patternCount;
|
|
550
|
+
this.metrics.avgCacheLoadTime = this.reader.getLoadTime();
|
|
551
|
+
this.metrics.lastCacheGenerationTime = metadata.timestamp;
|
|
552
|
+
return true;
|
|
553
|
+
}
|
|
554
|
+
catch (error) {
|
|
555
|
+
this.metrics.cacheMisses++;
|
|
556
|
+
if (error instanceof BinaryMetadataCache_1.CacheLoadError && error.type === 'checksum_mismatch') {
|
|
557
|
+
this.metrics.cacheCorruptionCount++;
|
|
558
|
+
}
|
|
559
|
+
return false;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Build and save cache from patterns
|
|
564
|
+
*/
|
|
565
|
+
async buildAndSave(patterns, agentConfigs = []) {
|
|
566
|
+
const result = await this.builder.buildCache(patterns, agentConfigs, this.config.cachePath);
|
|
567
|
+
if (result.success) {
|
|
568
|
+
this.metrics.cacheRebuildCount++;
|
|
569
|
+
this.metrics.lastCacheGenerationTime = Date.now();
|
|
570
|
+
this.metrics.cacheFileSize = result.cacheFileSize;
|
|
571
|
+
this.metrics.patternCount = result.patternCount;
|
|
572
|
+
// Reload cache after build
|
|
573
|
+
await this.load();
|
|
574
|
+
}
|
|
575
|
+
return result;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Get pattern by ID
|
|
579
|
+
*/
|
|
580
|
+
getPattern(id) {
|
|
581
|
+
if (this.reader) {
|
|
582
|
+
const pattern = this.reader.getPattern(id);
|
|
583
|
+
if (pattern) {
|
|
584
|
+
this.metrics.cacheHits++;
|
|
585
|
+
}
|
|
586
|
+
else {
|
|
587
|
+
this.metrics.cacheMisses++;
|
|
588
|
+
}
|
|
589
|
+
this.updateHitRate();
|
|
590
|
+
return pattern;
|
|
591
|
+
}
|
|
592
|
+
this.metrics.cacheMisses++;
|
|
593
|
+
this.updateHitRate();
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Get patterns by domain
|
|
598
|
+
*/
|
|
599
|
+
getPatternsByDomain(domain) {
|
|
600
|
+
if (this.reader) {
|
|
601
|
+
const patterns = this.reader.getPatternsByDomain(domain);
|
|
602
|
+
this.metrics.cacheHits++;
|
|
603
|
+
this.updateHitRate();
|
|
604
|
+
return patterns;
|
|
605
|
+
}
|
|
606
|
+
this.metrics.cacheMisses++;
|
|
607
|
+
this.updateHitRate();
|
|
608
|
+
return [];
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Get patterns by type
|
|
612
|
+
*/
|
|
613
|
+
getPatternsByType(type) {
|
|
614
|
+
if (this.reader) {
|
|
615
|
+
const patterns = this.reader.getPatternsByType(type);
|
|
616
|
+
this.metrics.cacheHits++;
|
|
617
|
+
this.updateHitRate();
|
|
618
|
+
return patterns;
|
|
619
|
+
}
|
|
620
|
+
this.metrics.cacheMisses++;
|
|
621
|
+
this.updateHitRate();
|
|
622
|
+
return [];
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Get all patterns
|
|
626
|
+
*/
|
|
627
|
+
getAllPatterns() {
|
|
628
|
+
if (this.reader) {
|
|
629
|
+
this.metrics.cacheHits++;
|
|
630
|
+
this.updateHitRate();
|
|
631
|
+
return this.reader.getAllPatterns();
|
|
632
|
+
}
|
|
633
|
+
this.metrics.cacheMisses++;
|
|
634
|
+
this.updateHitRate();
|
|
635
|
+
return [];
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Check if cache is valid and fresh
|
|
639
|
+
*/
|
|
640
|
+
isValid() {
|
|
641
|
+
return this.reader?.isValid() || false;
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Invalidate cache
|
|
645
|
+
*/
|
|
646
|
+
invalidate(trigger) {
|
|
647
|
+
this.invalidator.markStale({
|
|
648
|
+
trigger,
|
|
649
|
+
timestamp: Date.now(),
|
|
650
|
+
requiresRebuild: true,
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Check if background rebuild is recommended
|
|
655
|
+
*/
|
|
656
|
+
shouldRebuild() {
|
|
657
|
+
if (!this.reader)
|
|
658
|
+
return true;
|
|
659
|
+
const metadata = this.reader.getCacheMetadata();
|
|
660
|
+
return this.invalidator.shouldBackgroundRebuild(metadata.timestamp, this.config.maxAge);
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Get cache metrics
|
|
664
|
+
*/
|
|
665
|
+
getMetrics() {
|
|
666
|
+
return { ...this.metrics };
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Close cache and release resources
|
|
670
|
+
*/
|
|
671
|
+
close() {
|
|
672
|
+
this.reader?.close();
|
|
673
|
+
this.reader = null;
|
|
674
|
+
}
|
|
675
|
+
updateHitRate() {
|
|
676
|
+
const total = this.metrics.cacheHits + this.metrics.cacheMisses;
|
|
677
|
+
this.metrics.cacheHitRate = total > 0 ? this.metrics.cacheHits / total : 0;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
exports.BinaryCacheManager = BinaryCacheManager;
|
|
681
|
+
// Export default instance factory
|
|
682
|
+
function createBinaryCacheManager(config) {
|
|
683
|
+
return new BinaryCacheManager(config);
|
|
684
|
+
}
|
|
685
|
+
//# sourceMappingURL=BinaryCacheImpl.js.map
|