pruneCache
uses node:fs
Remove from .tcm/cache what no branch can use, all of it made again when it's needed: the modules of code no
branch names nor uses (past versions), with what rendered.json says of them; tcm run's runners; and the apps
suites packed, untouched for a day. Only what wasn't written in the last hour goes: a check in another process
writes modules of code it hasn't saved, and imports them. How many files went, and their bytes.
import type { Codebase } from "#codebase/tcmts/cli/codebase"; import fs from "node:fs"; import path from "node:path"; export function pruneCache(cb: Codebase): { files: number; bytes: number } { const dir = cb.lay.cacheDir; const live = cb.store.liveComponents(); const now = Date.now(); let files = 0; let bytes = 0; const gone = (file: string, age: number): boolean => { const s = fs.statSync(file, { throwIfNoEntry: false }); if (!s || now - s.mtimeMs < age) return false; if (s.isDirectory()) { for (const f of fs.readdirSync(file, { recursive: true, withFileTypes: true })) if (f.isFile()) { files++; bytes += fs.statSync(path.join(f.parentPath, f.name)).size; } } else { files++; bytes += s.size; } fs.rmSync(file, { recursive: true, force: true }); return true; }; const hour = 60 * 60 * 1000; for (const f of fs.existsSync(dir) ? fs.readdirSync(dir) : []) { const m = /^(run_)?([a-z2-7]{52})\.tsx?$/.exec(f); if (m && (m[1] || !live.has(m[2]!))) gone(path.join(dir, f), hour); } const apps = path.join(dir, "apps"); for (const f of fs.existsSync(apps) ? fs.readdirSync(apps) : []) gone(path.join(apps, f), 24 * hour); // (what's left of a module is all rendered.json needs: one gone is rendered again whatever it says) const stamps = path.join(dir, "rendered.json"); try { const rendered = JSON.parse(fs.readFileSync(stamps, "utf8")) as Record<string, string>; for (const c of Object.keys(rendered)) if ( !live.has(c) && !fs.existsSync(path.join(dir, `${c}.ts`)) && !fs.existsSync(path.join(dir, `${c}.tsx`)) ) delete rendered[c]; const part = `${stamps}.${process.pid}`; fs.writeFileSync(part, JSON.stringify(rendered)); fs.renameSync(part, stamps); } catch { // (none, or cut short: materialize renders what it doesn't know) } return { files, bytes }; }