c4dslbuilder
Version:
A CLI tool designed to compile a folder structure of markdowns and mermaid files into a site, pdf, single file markdown or a collection of markdowns with links - inspired by c4builder
70 lines (69 loc) • 2.68 kB
JavaScript
import { createHash } from 'crypto';
import path from 'path';
import { CliLogger } from './cli-logger.js';
export class CacheManager {
cacheFilePath;
safeFiles;
logger;
cacheVersion = 1;
cache = { version: this.cacheVersion, files: {} };
constructor(cacheFilePath, safeFiles, logger = new CliLogger(CacheManager.name)) {
this.cacheFilePath = cacheFilePath;
this.safeFiles = safeFiles;
this.logger = logger;
}
async loadCache() {
const exists = await this.safeFiles.pathExists(this.cacheFilePath);
if (!exists) {
this.logger.info(`No existing cache file found at ${this.cacheFilePath}`);
return;
}
const raw = await this.safeFiles.readFileAsString(this.cacheFilePath);
if (!raw) {
this.logger.warn(`Cache file found but empty or unreadable: ${this.cacheFilePath}`);
return;
}
try {
const parsed = JSON.parse(raw);
if (parsed.version === this.cacheVersion && typeof parsed.files === 'object') {
this.cache = parsed;
this.logger.info(`Loaded cache from ${this.cacheFilePath}`);
}
else {
this.logger.warn(`Cache file version mismatch or corrupt. Ignoring existing cache.`);
}
}
catch (error) {
this.logger.error(`Failed to parse cache file: ${this.cacheFilePath}`, error);
}
}
async hasChanged(filePath) {
const absPath = path.resolve(filePath);
const content = await this.safeFiles.readFileAsString(absPath);
if (content === null) {
this.logger.warn(`Cannot determine if file changed: ${filePath}`);
return true;
}
const currentHash = this.hashString(content);
const cachedHash = this.cache.files[absPath];
return cachedHash !== currentHash;
}
async markProcessed(filePath) {
const absPath = path.resolve(filePath);
const content = await this.safeFiles.readFileAsString(absPath);
if (content === null) {
this.logger.warn(`Cannot mark file as processed: ${filePath}`);
return;
}
const currentHash = this.hashString(content);
this.cache.files[absPath] = currentHash;
}
async persist() {
const serialized = JSON.stringify(this.cache, null, 2);
await this.safeFiles.writeFile(this.cacheFilePath, serialized);
this.logger.info(`Persisted cache to ${this.cacheFilePath}`);
}
hashString(content) {
return createHash('sha256').update(content, 'utf8').digest('hex');
}
}