microsoft/TypeScript
watchGuard
A 17-line helper executable that exists for a single reason: deciding whether it is safe for tsserver to enable recursive directory watching on a given path. Used only on Windows.
Purpose
Node's fs.watch(dir, { recursive: true }) is convenient but throws on certain Windows paths — network drives, mapped UNC paths, junctioned filesystems, paths exceeding internal handle limits. A throw inside tsserver itself would crash the whole language server. So tsserver first asks a separate child process to attempt the recursive watch; if the child crashes, tsserver falls back to non-recursive watching for that directory.
Source
import * as fs from 'fs';
if (process.argv.length < 3) {
process.exit(1);
}
const directoryName = process.argv[2];
// main reason why we need separate process to check if it is safe to watch some path
// is to guard against crashes that cannot be intercepted with protected blocks and
// code in tsserver already can handle normal cases, like non-existing folders.
// This means that here we treat any result (success or exception) from fs.watch as success since it does not tear down the process.
// The only case that should be considered as failure - when watchGuard process crashes.
try {
const watcher = fs.watch(directoryName, { recursive: true }, () => ({}));
watcher.close();
} catch {
/*ignore*/
}
process.exit(0);That's the entire program. Exit-zero means "safe to watch"; the process crashing (segfault, native abort) is interpreted as "not safe".
Directory layout
src/watchGuard/
├── tsconfig.json
└── watchGuard.ts # the entire programHow it works
sequenceDiagram
participant tsserver
participant watchGuard
participant fs as Node fs
tsserver->>watchGuard: spawn (path)
watchGuard->>fs: fs.watch(path, { recursive: true })
alt Native crash
fs--xwatchGuard: process aborts
watchGuard-->>tsserver: exit code != 0
tsserver->>tsserver: fall back to per-file watch
else Normal exception
fs->>watchGuard: throw
watchGuard-->>tsserver: exit 0 (caught)
tsserver->>tsserver: try recursive watch (will throw and be handled)
else Success
fs->>watchGuard: returns watcher
watchGuard-->>tsserver: exit 0
tsserver->>tsserver: enable recursive watch
endIntegration points
- Spawned by
src/server/editorServices.ts(and the host setup insrc/tsserver/nodeServer.ts) whentsserverfirst considers recursive-watching a directory it hasn't seen before. - Output is consumed only via the child-process exit code.
- Has no dependencies beyond Node's built-in
fs.
Entry points for modification
In practice nobody modifies watchGuard.ts. The interesting code is on the caller side — when and how tsserver decides to invoke it, what fallback it uses on a non-zero exit, and how it caches the per-directory verdict.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.