How the Secure Design Extension's File Watcher Service Detects and Reacts to Changes in Design-Related Files
The Secure Design VS Code extension uses a dedicated FileWatcherService that creates vscode.FileSystemWatcher instances for each workspace folder to monitor the .superdesign/design_iterations directory for HTML, SVG, and CSS file changes, automatically notifying the canvas panel webview via postMessage and reloading the design list on create, modify, or delete events.
The hbmartin/secure-design repository provides a VS Code extension for managing secure design iterations through a dedicated canvas interface. To maintain real-time synchronization between the filesystem and the UI, the extension implements a robust mechanism to detect and react to changes in design-related files using VS Code's native file watching capabilities.
Core Architecture of the File Watcher Service
Multi-Root Workspace Support
The FileWatcherService in src/services/fileWatcherService.ts creates isolated watchers for each workspace folder to support multi-root environments. When setupWatcher() is invoked, the service stores the configuration and calls _setupWatchersForWorkspace() to iterate through all open workspace folders, ensuring comprehensive coverage across the entire VS Code workspace.
Event Translation Layer
Rather than exposing raw VS Code URI objects directly to consumers, the service translates vscode.Uri instances into structured FileChangeEvent objects. This abstraction encapsulates critical metadata including the file name, absolute path, relative path, workspace name, and change type (create, change, or delete), enabling the canvas panel to handle file events contextually.
How the Service Detects File Changes
The detection mechanism relies on VS Code's FileSystemWatcher API configured with glob patterns. In src/SuperdesignCanvasPanel.ts (lines 80-90), the canvas panel registers the watcher with a specific pattern targeting design iterations:
this._fileWatcherService.setupWatcher({
pattern: '.superdesign/design_iterations/**/*.{html,svg,css}',
onFileChange: (event) => {
this._panel.webview.postMessage({
command: 'fileChanged',
data: event,
});
void this._loadDesignFiles();
},
});
For each workspace folder, the service constructs a vscode.RelativePattern and instantiates a FileSystemWatcher that explicitly listens to create, change, and delete events without ignoring any event types (lines 29-41 in fileWatcherService.ts).
How the Extension Reacts to Change Events
The FileWatcherService._createWatcherForFolder() method (lines 96-133) registers three distinct event handlers that convert VS Code filesystem events into actionable callbacks for the canvas panel.
Create Events (onDidCreate)
When a new HTML, SVG, or CSS file appears in the watched directory, the watcher fires the create handler. The service translates the event into a FileChangeEvent with changeType: 'create' and invokes the onFileChange callback provided during setup, triggering the canvas panel to refresh its design list.
Modify Events (onDidChange)
File modifications trigger the same notification pipeline. The canvas panel receives the fileChanged message via webview postMessage and calls _loadDesignFiles() to reload the latest file contents, ensuring the UI displays the most current design iterations without requiring manual refresh.
Delete Events (onDidDelete)
When design files are removed from the .superdesign/design_iterations folder, the delete handler executes identical UI refresh logic. The webview receives immediate notification of the deletion, and the design list updates to reflect the current filesystem state.
Automatic Cleanup and Resource Management
The service maintains a Map data structure to track each FileSystemWatcher instance and its associated subscription disposables. When workspace folders are added or removed, or when the canvas panel closes, the _disposeWatchers() method (lines 146-170 in fileWatcherService.ts) iterates through the map to clean up all event listeners and watcher instances. This prevents memory leaks in long-running VS Code sessions and ensures proper resource disposal when the SuperdesignCanvasPanel triggers cleanup via _setupWorkspaceChangeListener().
Implementation Example
To implement a custom file watcher elsewhere in the extension:
import { FileWatcherService, FileChangeEvent } from './services/fileWatcherService';
const watcher = new FileWatcherService();
watcher.setupWatcher({
pattern: '**/*.css',
onFileChange: (event: FileChangeEvent) => {
console.log(`[${event.changeType}] ${event.relativePath}`);
},
});
When disposing of the component, call watcher.dispose() to remove all watchers and event listeners automatically.
Summary
- FileWatcherService creates dedicated
FileSystemWatcherinstances for each workspace folder to support multi-root VS Code environments. - The service monitors the glob pattern
.superdesign/design_iterations/**/*.{html,svg,css}for create, modify, and delete events. - Raw VS Code URI objects are translated into structured
FileChangeEventobjects containing workspace context, absolute paths, and change metadata. - The
SuperdesignCanvasPanelreacts to changes by postingfileChangedmessages to the webview and asynchronously reloading the design file list via_loadDesignFiles(). - Automatic disposal mechanisms in
_disposeWatchers()prevent memory leaks when workspace configurations change or panels close.
Frequently Asked Questions
What file types does the Secure Design extension watch?
The extension specifically monitors HTML, SVG, and CSS files located within the .superdesign/design_iterations directory structure. This is defined by the glob pattern .superdesign/design_iterations/**/*.{html,svg,css} configured in the SuperdesignCanvasPanel.ts file, ensuring only relevant design artifacts trigger UI updates.
How does the file watcher handle multiple workspace folders?
The FileWatcherService automatically creates separate FileSystemWatcher instances for each workspace folder when setupWatcher() is called. This architecture ensures design files in any opened folder are observed, and the service recreates watchers automatically when workspace folders are added or removed through the _setupWorkspaceChangeListener() mechanism.
What information is included in the FileChangeEvent object?
According to the implementation in fileWatcherService.ts, the FileChangeEvent object contains the file name, absolute path, relative path, workspace name, and change type (create, change, or delete). This rich metadata enables the canvas panel to update the UI correctly even in complex multi-root workspace scenarios.
How does the extension prevent memory leaks when workspace folders change?
The service tracks all FileSystemWatcher instances and their subscription disposables in a Map data structure. When workspace configurations change or the panel is disposed, the _disposeWatchers() method iterates through the map to terminate every subscription and watcher instance, ensuring no event listeners remain attached to destroyed resources.
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 →