Files
rspade_system/node_modules/@jqhtml/ssr/src/bundle-cache.js
root 14dd2fd223 Fix code quality violations for publish
Progressive breadcrumb resolution with caching, fix double headers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-16 04:43:47 +00:00

142 lines
2.9 KiB
JavaScript

/**
* JQHTML SSR Bundle Cache
*
* Caches parsed bundle code to avoid re-parsing on every request.
* Uses LRU (Least Recently Used) eviction strategy.
*/
/**
* LRU Cache for bundle sets
*/
class BundleCache {
constructor(maxSize = 10) {
this.maxSize = maxSize;
this.cache = new Map(); // bundleSetId -> { code, lastUsed }
}
/**
* Generate a cache key from bundle array
* @param {Array<{id: string, content: string}>} bundles
* @returns {string} Cache key
*/
static generateKey(bundles) {
// Key is concatenation of all bundle IDs in order
return bundles.map(b => b.id).join('|');
}
/**
* Get cached bundle code if available
* @param {string} key - Cache key from generateKey()
* @returns {string|null} Concatenated bundle code or null if not cached
*/
get(key) {
const entry = this.cache.get(key);
if (entry) {
entry.lastUsed = Date.now();
return entry.code;
}
return null;
}
/**
* Store bundle code in cache
* @param {string} key - Cache key
* @param {string} code - Concatenated bundle code
*/
set(key, code) {
// Evict if at capacity
if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
this._evictLRU();
}
this.cache.set(key, {
code,
lastUsed: Date.now()
});
}
/**
* Check if a bundle set is cached
* @param {string} key - Cache key
* @returns {boolean}
*/
has(key) {
return this.cache.has(key);
}
/**
* Remove a specific bundle set from cache
* @param {string} key - Cache key
* @returns {boolean} True if entry was removed
*/
delete(key) {
return this.cache.delete(key);
}
/**
* Clear all cached bundles
*/
clear() {
this.cache.clear();
}
/**
* Get cache statistics
* @returns {{ size: number, maxSize: number, keys: string[] }}
*/
stats() {
return {
size: this.cache.size,
maxSize: this.maxSize,
keys: Array.from(this.cache.keys())
};
}
/**
* Evict the least recently used entry
* @private
*/
_evictLRU() {
let oldestKey = null;
let oldestTime = Infinity;
for (const [key, entry] of this.cache) {
if (entry.lastUsed < oldestTime) {
oldestTime = entry.lastUsed;
oldestKey = key;
}
}
if (oldestKey) {
this.cache.delete(oldestKey);
}
}
}
/**
* Prepare bundle code for execution
* Concatenates bundles and removes problematic patterns
* @param {Array<{id: string, content: string}>} bundles
* @returns {string} Prepared code
*/
function prepareBundleCode(bundles) {
const codeChunks = [];
for (const bundle of bundles) {
// Remove sourcemap comments
let code = bundle.content.replace(/\/\/# sourceMappingURL=.*/g, '');
// Add bundle marker comment for debugging
code = `\n/* === Bundle: ${bundle.id} === */\n${code}`;
codeChunks.push(code);
}
return codeChunks.join('\n');
}
module.exports = {
BundleCache,
prepareBundleCode
};