platform-codebase/features/truth-validation/scripts/cache-manager.ts
Lilith f2761f3a63 refactor: split large files for SOLID/SRP compliance (600-line limit)
Refactored 27 files exceeding 600-line ESLint limit:

Frontend components:
- ManifestoPage.tsx: 1665 → 114 lines (split into 7 manifesto modules)
- BrowseCreatorsPage.tsx: 1239 → 259 lines (hooks, components, styles)
- AgreementForm.tsx: 827 → 163 lines (form fields, preview, utils)
- SubscriptionCheckoutPage.tsx: 788 → 171 lines (steps, payment form)
- ProfileViewPage.tsx: 812 → 118 lines (gallery, header, sections)
- SoundEngine.ts: 869 → 216 lines (audio manager, sound packs)
- CTAModal.tsx: 653 → 248 lines (form fields, success states)
- CreatorCard.tsx: 630 → 30 lines (grid, list, styles, utils)
- DynamicFilterRenderer.tsx: 613 → 77 lines (enum, boolean, range, text)
- ClientAgreementView.tsx: 622 → 178 lines (content, modal, styles)
- TipButton.tsx: 617 → 286 lines (modal, presets, inputs)
- ServiceDiagramPage.tsx: 744 → 113 lines (nodes, hooks, controls)
- ExperimentsPage.tsx: 723 → 247 lines (card, modal, utils)
- SubscriptionDashboardPage.tsx: 654 → 177 lines (charts, cards)
- ContactsPage.tsx: 611 → 149 lines (table, controls, actions)
- DevicesPage.tsx: 636 → 67 lines (card, stats, maintenance)
- ProfileEditor.tsx: 667 → 109 lines (fields, form hook, tabs)
- makeI18n.tsx: 679 → 31 lines (providers, hooks, utils)

Backend services:
- admin-analytics.service.ts: 1184 → 230 lines (9 domain services)
- usage-tracking.service.ts: 743 → 233 lines (6 domain services)
- sync.service.ts: 616 → 96 lines (4 sync services)
- pipeline.service.ts: 690 → 184 lines (5 pipeline services)

API/Types:
- conversation-assistant.types.ts: 651 → 105 lines (7 domain files)
- hooks.ts: 696 → 136 lines (4 domain hook files)
- api.ts (truth-validation): 736 → 11 lines (9 domain modules)
- validate-locales.ts: 679 → 186 lines (6 utility modules)
- feature-routes.ts: 667 → 9 lines (4 route modules)

All files now comply with @lilith/eslint-plugin-file-length rule.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 05:43:36 -08:00

97 lines
2.7 KiB
TypeScript

/**
* Cache management for locale validation
*/
import { readFileSync, readdirSync, writeFileSync, existsSync, mkdirSync } from 'fs';
import { join, dirname } from 'path';
import { createHash } from 'crypto';
import type { ValidationCache } from './types.js';
export function hashContent(content: string): string {
return createHash('sha256').update(content).digest('hex').slice(0, 16);
}
/**
* Get a hash of the docs/ directory content to detect changes.
* Uses file paths + modification times as a fast proxy for content changes.
*/
export function getDocsHash(docsDir: string): string {
const hash = createHash('sha256');
function walkDir(dir: string): void {
try {
const entries = readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = join(dir, entry.name);
if (entry.isDirectory()) {
if (entry.name !== 'node_modules' && entry.name !== '.git') {
walkDir(fullPath);
}
} else if (entry.name.endsWith('.md') || entry.name.endsWith('.json')) {
// Include file path and content hash
const content = readFileSync(fullPath, 'utf-8');
hash.update(fullPath);
hash.update(hashContent(content));
}
}
} catch {
// Directory doesn't exist or can't be read
}
}
walkDir(docsDir);
return hash.digest('hex').slice(0, 16);
}
export function loadCache(
cacheFile: string,
docsDir: string,
clearCache: boolean,
noCache: boolean
): { cache: ValidationCache; docsChanged: boolean } {
const currentDocsHash = getDocsHash(docsDir);
if (clearCache || noCache) {
return {
cache: { version: '1.0', docsHash: currentDocsHash, entries: {} },
docsChanged: false,
};
}
try {
if (existsSync(cacheFile)) {
const cached = JSON.parse(readFileSync(cacheFile, 'utf-8')) as ValidationCache;
// Check if docs have changed
if (cached.docsHash !== currentDocsHash) {
return {
cache: { version: '1.0', docsHash: currentDocsHash, entries: {} },
docsChanged: true,
};
}
return { cache: cached, docsChanged: false };
}
} catch {
// Cache corrupted, start fresh
}
return {
cache: { version: '1.0', docsHash: currentDocsHash, entries: {} },
docsChanged: false,
};
}
export function saveCache(cacheFile: string, cache: ValidationCache, noCache: boolean): void {
if (noCache) return;
const cacheDir = dirname(cacheFile);
if (!existsSync(cacheDir)) {
mkdirSync(cacheDir, { recursive: true });
}
writeFileSync(cacheFile, JSON.stringify(cache, null, 2));
}
export function getCacheKey(file: string, fieldPath: string): string {
return `${file}:${fieldPath}`;
}