-
Notifications
You must be signed in to change notification settings - Fork 0
Cache System
Arham-Qureshi edited this page Jul 21, 2026
·
1 revision
Re-parsing a large codebase from scratch every time is slow. codebase-vis maintains a .cache.json file inside codebase-out/ that stores parsed results alongside file fingerprints.
{
"version": 1,
"files": {
"/abs/path/to/file.js": {
"mtime": 1700000000,
"size": 1234,
"data": {
"id": "path/to/file.js",
"dependencies": ["express", "./helper"],
"entities": {
"classes": ["MyClass"],
"functions": ["myFunc"],
"methods": ["myMethod"],
"docstrings": ["/** Does X */"]
}
}
}
}
}Each cache entry stores:
-
mtime— file modification time (fromstat.mtimeMs) -
size— file size in bytes (fromstat.size) -
data— the full parsed result (dependencies, entities)
discoverFiles()
│
▼
loadCache() ← reads .cache.json (checks version === 1)
│
▼
splitFilesByCache()
│
├── File exists in cache AND mtime+size match
│ └──→ cachedResults[] — skip parsing (zero cost)
│
└── File missing from cache OR mtime+size mismatch
└──→ toParse[] — queue for fresh parsing
│
▼
parseFileBatch(toParse) ← only changed files
│
▼
buildUpdatedCache(oldCache, toParse, parsedResults)
│
├── Merge old cache entries (unchanged files)
├── Add/update new parse results
└── Remove stale entries (files no longer on disk)
│
▼
saveCache() ← writes .cache.json
getStalePaths() identifies cache entries whose files no longer exist on disk and prunes them. This prevents the cache from growing unbounded as files are deleted or renamed.
function getStalePaths(cache, discoveredSet) {
return Object.keys(cache.files)
.filter(cachedPath => !discoveredSet.has(cachedPath))
}- First run: Parses everything, writes cache
- Second run (no changes): Zero parsing — loads entirely from cache
- After editing a few files: Only the changed files (different mtime or size) are re-parsed
- After deleting files: Stale entries are automatically cleaned up
This makes codebase-vis generate near-instant on repeated runs for codebases with few changes.