How Watch Mode Triggers Incremental Updates in the Code Review Graph VS Code Extension
The Code Review Graph extension uses VS Code's FileSystemWatcher to monitor the SQLite database and executes a debounced callback that re-instantiates the database reader and refreshes the UI whenever changes are detected.
The tirth8205/code-review-graph repository provides a VS Code extension that visualizes code dependencies in real-time. Understanding how watch mode triggers incremental updates is essential for developers extending the tool or troubleshooting performance issues. The implementation leverages native VS Code APIs combined with custom debouncing logic to ensure the UI stays synchronized with the underlying graph database without excessive overhead.
The FileSystemWatcher Implementation in src/extension.ts
The entry point for watch mode resides in the watchGraphDb function within src/extension.ts (lines 94-115). This function creates a FileSystemWatcher instance that specifically targets the **/.code-review-graph/graph.db pattern, ensuring the extension reacts to modifications in the SQLite graph database regardless of workspace location.
When the watcher detects a change, creation, or deletion event, it triggers a callback that orchestrates the incremental update sequence. The watcher registration occurs during extension activation and is automatically disposed through context.subscriptions to prevent memory leaks.
Debouncing Logic in the GraphWatcher Class
To prevent performance degradation from rapid successive file changes, the extension implements a reusable GraphWatcher class defined in src/backend/watcher.ts (lines 29-50). This utility encapsulates the debouncing logic, limiting callback execution to once per 500 milliseconds.
The GraphWatcher class wraps the native VS Code watcher and provides a clean interface for components that need to react to database modifications. By centralizing the debounce implementation here, the extension maintains consistent behavior across different watch scenarios while keeping the main extension file focused on high-level orchestration.
The Incremental Update Sequence
When the debounced callback executes, the extension performs a three-step incremental update process:
- Close the existing connection. The current
SqliteReaderinstance is closed to release file handles on the database. - Re-instantiate the reader. A new
SqliteReaderis created pointing at the updatedgraph.dbfile, ensuring the extension reads the latest graph state. - Refresh the UI. The command
codeReviewGraph.codeGraph.refreshis executed, updating the tree view, blast-radius view, and status bar without requiring a full graph rebuild.
This sequence ensures near-real-time synchronization while maintaining data integrity by preventing read operations on a potentially locked or mid-write database file.
Code Implementation Examples
The following examples demonstrate both the automatic watcher setup and manual usage of the reusable components.
Automatic watcher setup during extension activation:
// In src/extension.ts – called during activation
function watchGraphDb(context: vscode.ExtensionContext): void {
const watcher = vscode.workspace.createFileSystemWatcher(
"**/.code-review-graph/graph.db"
);
const dbPathRef = { current: "" };
const workspaceRoot = getWorkspaceRoot();
if (workspaceRoot) {
const dbPath = findGraphDb(workspaceRoot);
if (dbPath) dbPathRef.current = dbPath;
}
watcher.onDidChange(() => {
if (sqliteReader && dbPathRef.current) {
sqliteReader.close();
sqliteReader = new SqliteReader(dbPathRef.current);
vscode.commands.executeCommand("codeReviewGraph.codeGraph.refresh");
}
});
// Creation & deletion handlers are analogous (see lines 117-133).
context.subscriptions.push(watcher);
}
Manual usage of the GraphWatcher class for custom tooling:
import { GraphWatcher } from "./backend/watcher";
import { SqliteReader } from "./backend/sqlite";
const dbPath = "/absolute/path/to/.code-review-graph/graph.db";
const watcher = new GraphWatcher(dbPath, () => {
// Re-open the DB and refresh whatever UI you manage
const reader = new SqliteReader(dbPath);
// …update your views…
});
context.subscriptions.push(watcher); // Dispose automatically on extension unload
Summary
- The extension monitors
graph.dbusing VS Code's nativeFileSystemWatcherconfigured insrc/extension.ts. - Debouncing logic in
src/backend/watcher.tslimits update frequency to 500ms intervals via theGraphWatcherclass. - Incremental updates close and reopen the
SqliteReaderconnection before executing thecodeReviewGraph.codeGraph.refreshcommand. - This architecture provides real-time UI synchronization without rebuilding the entire graph or blocking the main thread.
Frequently Asked Questions
What triggers the incremental update in watch mode?
The incremental update triggers when VS Code's FileSystemWatcher detects a change, creation, or deletion of the graph.db file in the workspace. This typically occurs when an external process or the extension itself modifies the SQLite database containing the code review graph.
Why does the extension close and reopen the SqliteReader instead of keeping a persistent connection?
Closing and reopening the SqliteReader ensures the extension reads a consistent database state without file locking issues. Since SQLite allows only one writer at a time, reopening the connection guarantees the extension accesses the most recent committed data after external modifications.
How does the debouncing mechanism prevent performance issues?
The GraphWatcher class implements a 500ms debounce timer that batches rapid successive file changes into a single update operation. This prevents the UI from refreshing multiple times per second when the database undergoes frequent modifications, reducing CPU usage and preventing visual flicker.
Can I use the GraphWatcher class for other files besides graph.db?
Yes, the GraphWatcher class in src/backend/watcher.ts is designed as a reusable component that accepts any file path and callback function. While the extension uses it specifically for graph.db, you can instantiate it with different paths to monitor other configuration files or data sources in your VS Code extension.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →