UNPKG

@mdfriday/foundry

Version:

The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.

266 lines 8.76 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.MemoryModuleCache = exports.FsModuleCache = void 0; exports.newModuleCache = newModuleCache; exports.newMemoryModuleCache = newMemoryModuleCache; const type_1 = require("../type"); const log_1 = require("../../../../pkg/log"); const path = __importStar(require("path")); // Create domain-specific logger for cache operations const log = (0, log_1.getDomainLogger)('module', { component: 'cache' }); /** * File system based module cache implementation */ class FsModuleCache { constructor(fs, cacheDir = './module/cache') { this.fs = fs; this.cacheDir = cacheDir; } /** * Get module metadata from cache */ async get(modulePath) { try { const cacheFile = this.getCacheFilePath(modulePath); const file = await this.fs.open(cacheFile); const fileInfo = await file.stat(); const buffer = new Uint8Array(fileInfo.size()); await file.read(buffer); await file.close(); const content = new TextDecoder().decode(buffer); return JSON.parse(content); } catch (error) { if (error.message?.includes('ENOENT') || error.message?.includes('no such file')) { log.error(`Cache miss: ${modulePath}`, error); return null; } const message = error instanceof Error ? error.message : String(error); log.error(`Cache read error for ${modulePath}: ${message}`); throw new type_1.ModuleError(`Failed to read cache: ${message}`, 'CACHE_READ_FAILED'); } } /** * Set module metadata in cache */ async set(modulePath, metadata) { try { // Ensure cache directory exists await this.fs.mkdirAll(this.cacheDir, 0o755); const cacheFile = this.getCacheFilePath(modulePath); const content = JSON.stringify(metadata, null, 2); const buffer = new TextEncoder().encode(content); const file = await this.fs.create(cacheFile); await file.write(buffer); await file.sync(); await file.close(); } catch (error) { const message = error instanceof Error ? error.message : String(error); log.error(`Cache write error for ${modulePath}: ${message}`); throw new type_1.ModuleError(`Failed to write cache: ${message}`, 'CACHE_WRITE_FAILED'); } } /** * Check if module exists in cache */ async has(modulePath) { try { const cacheFile = this.getCacheFilePath(modulePath); await this.fs.stat(cacheFile); return true; } catch (error) { return false; } } /** * Delete module from cache */ async delete(modulePath) { try { const cacheFile = this.getCacheFilePath(modulePath); await this.fs.remove(cacheFile); } catch (error) { // File not found is not an error for deletion if (!error.message?.includes('ENOENT') && !error.message?.includes('no such file')) { const message = error instanceof Error ? error.message : String(error); log.error(`Cache delete error for ${modulePath}: ${message}`); throw new type_1.ModuleError(`Failed to delete cache: ${message}`, 'CACHE_DELETE_FAILED'); } } } /** * Clear all cache */ async clear() { try { await this.fs.removeAll(this.cacheDir); } catch (error) { // Directory not found is not an error for clearing if (!error.message?.includes('ENOENT') && !error.message?.includes('no such file')) { const message = error instanceof Error ? error.message : String(error); log.error(`Cache clear error: ${message}`); throw new type_1.ModuleError(`Failed to clear cache: ${message}`, 'CACHE_CLEAR_FAILED'); } } } /** * Get cache file path for module */ getCacheFilePath(modulePath) { // Convert module path to safe filename const safeFileName = modulePath .replace(/[/\\:*?"<>|]/g, '_') // Replace invalid characters .replace(/^_+|_+$/g, '') // Remove leading/trailing underscores + '.json'; return path.join(this.cacheDir, safeFileName); } /** * Get cache directory */ getCacheDir() { return this.cacheDir; } /** * Get cache stats */ async getStats() { try { const files = await this.listCacheFiles(); let totalSize = 0; for (const file of files) { try { const filePath = path.join(this.cacheDir, file); const fileInfo = await this.fs.stat(filePath); totalSize += fileInfo.size(); } catch (error) { // Skip files that can't be read } } return { totalEntries: files.length, totalSize, }; } catch (error) { return { totalEntries: 0, totalSize: 0, }; } } /** * List all cached modules */ async listCached() { try { const files = await this.listCacheFiles(); return files.map(file => path.basename(file, '.json').replace(/_/g, '/')); } catch (error) { return []; } } /** * Helper to list cache files */ async listCacheFiles() { try { const dir = await this.fs.open(this.cacheDir); const files = await dir.readdirnames(-1); await dir.close(); return files.filter(file => file.endsWith('.json')); } catch (error) { return []; } } } exports.FsModuleCache = FsModuleCache; /** * In-memory module cache implementation for testing */ class MemoryModuleCache { constructor() { this.cache = new Map(); } async get(modulePath) { const metadata = this.cache.get(modulePath); return metadata ? { ...metadata } : null; // Return copy to prevent mutation } async set(modulePath, metadata) { this.cache.set(modulePath, { ...metadata }); // Store copy to prevent mutation } async has(modulePath) { return this.cache.has(modulePath); } async delete(modulePath) { this.cache.delete(modulePath); } async clear() { this.cache.clear(); } /** * Get cache size for testing */ size() { return this.cache.size; } /** * Get all keys for testing */ keys() { return Array.from(this.cache.keys()); } } exports.MemoryModuleCache = MemoryModuleCache; /** * Creates a new file system based module cache */ function newModuleCache(fs, cacheDir) { return new FsModuleCache(fs, cacheDir); } /** * Creates a new in-memory module cache for testing */ function newMemoryModuleCache() { return new MemoryModuleCache(); } //# sourceMappingURL=cache.js.map