PRININIT / lib /src /file-cache.js
Rachit-Tw's picture
Upload 183 files
272a04f verified
Raw
History Blame Contribute Delete
6.13 kB
"use strict";
/**
* FILE-LEVEL MEMORY CACHE
*
* Caches semantic summaries per file to reduce token costs across multiple PRs.
* Prevents re-analyzing the same file repeatedly.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFileSummary = getFileSummary;
exports.getFileSummaryString = getFileSummaryString;
exports.clearFileCache = clearFileCache;
exports.getFileCacheStats = getFileCacheStats;
exports.isFileCached = isFileCached;
/**
* Generate a simple hash of file content for cache validation
*/
function hashContent(content) {
let hash = 0;
for (let i = 0; i < content.length; i++) {
hash = ((hash << 5) - hash + content.charCodeAt(i)) | 0;
}
return Math.abs(hash).toString(36);
}
/**
* Extract semantic summary from file content
*/
function extractSummary(content, language = 'typescript') {
const lines = content.split('\n');
const summary = [];
// Extract function definitions
const functionRegex = /(?:function|const|let|var)\s+(\w+)\s*(?:=\s*(?:async\s*)?\(|\()/;
const functions = [];
// Extract imports
const importRegex = /import\s+.*from\s+['"]([^'"]+)['"]/;
const imports = [];
// Extract exports
const exportRegex = /export\s+(?:const|function|class|interface)\s+(\w+)/;
const exports = [];
for (const line of lines) {
const funcMatch = line.match(functionRegex);
if (funcMatch)
functions.push(funcMatch[1]);
const importMatch = line.match(importRegex);
if (importMatch)
imports.push(importMatch[1]);
const exportMatch = line.match(exportRegex);
if (exportMatch)
exports.push(exportMatch[1]);
}
// Build summary
if (functions.length > 0) {
summary.push(`Functions: ${functions.slice(0, 5).join(', ')}`);
}
if (imports.length > 0) {
summary.push(`Imports: ${imports.slice(0, 5).join(', ')}`);
}
if (exports.length > 0) {
summary.push(`Exports: ${exports.join(', ')}`);
}
// Detect patterns
if (content.includes('useState') || content.includes('useEffect')) {
summary.push('React hooks detected');
}
if (content.includes('async') || content.includes('await')) {
summary.push('Async operations');
}
if (content.includes('fetch') || content.includes('axios')) {
summary.push('HTTP requests');
}
return summary.join(' | ');
}
/**
* File cache implementation
*/
class FileCache {
cache = new Map();
TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
MAX_CACHE_SIZE = 1000;
/**
* Get cached summary for a file
*/
get(path, content) {
const cached = this.cache.get(path);
if (!cached)
return null;
// Check if expired
if (Date.now() - cached.lastAnalyzed > this.TTL_MS) {
this.cache.delete(path);
return null;
}
// Check if content has changed
const currentHash = hashContent(content);
if (cached.hash !== currentHash) {
this.cache.delete(path);
return null;
}
return cached;
}
/**
* Set cached summary for a file
*/
set(path, content, language = 'typescript') {
const summary = extractSummary(content, language);
const lines = content.split('\n');
const functions = [];
const imports = [];
const exports = [];
for (const line of lines) {
const funcMatch = line.match(/(?:function|const|let|var)\s+(\w+)\s*(?:=\s*(?:async\s*)?\(|\()/);
if (funcMatch)
functions.push(funcMatch[1]);
const importMatch = line.match(/import\s+.*from\s+['"]([^'"]+)['"]/);
if (importMatch)
imports.push(importMatch[1]);
const exportMatch = line.match(/export\s+(?:const|function|class|interface)\s+(\w+)/);
if (exportMatch)
exports.push(exportMatch[1]);
}
const fileSummary = {
path,
summary,
functions,
imports,
exports,
lastAnalyzed: Date.now(),
hash: hashContent(content)
};
this.cache.set(path, fileSummary);
// Evict old entries if cache is too large
if (this.cache.size > this.MAX_CACHE_SIZE) {
this.evictOld();
}
return fileSummary;
}
/**
* Evict old entries
*/
evictOld() {
const entries = Array.from(this.cache.entries());
entries.sort((a, b) => a[1].lastAnalyzed - b[1].lastAnalyzed);
// Remove oldest 10% of entries
const toRemove = Math.floor(entries.length * 0.1);
for (let i = 0; i < toRemove; i++) {
this.cache.delete(entries[i][0]);
}
}
/**
* Clear cache
*/
clear() {
this.cache.clear();
}
/**
* Get cache statistics
*/
getStats() {
return { size: this.cache.size };
}
/**
* Check if file is in cache
*/
has(path) {
return this.cache.has(path);
}
}
// Global file cache instance
const fileCache = new FileCache();
/**
* Get cached summary for a file
*/
function getFileSummary(path, content, language = 'typescript') {
const cached = fileCache.get(path, content);
if (cached) {
return cached;
}
// Cache miss - analyze and cache
return fileCache.set(path, content, language);
}
/**
* Get summary string for a file (for use in prompts)
*/
function getFileSummaryString(path, content, language = 'typescript') {
const summary = getFileSummary(path, content, language);
if (!summary) {
return extractSummary(content, language);
}
return summary.summary;
}
/**
* Clear file cache
*/
function clearFileCache() {
fileCache.clear();
}
/**
* Get file cache statistics
*/
function getFileCacheStats() {
return fileCache.getStats();
}
/**
* Check if file is cached
*/
function isFileCached(path) {
return fileCache.has(path);
}
//# sourceMappingURL=file-cache.js.map