* macOS/Windows: one recursive watcher for the whole tree. O(1) descriptors. * `filename` arrives relative to the project root (with subdirectories), so * it maps straight to a project-relative path.
()
| 434 | * it maps straight to a project-relative path. |
| 435 | */ |
| 436 | private startRecursive(): void { |
| 437 | this.recursiveWatcher = watchImpl( |
| 438 | this.projectRoot, |
| 439 | { recursive: true, persistent: true }, |
| 440 | (_event, filename) => { |
| 441 | if (this.stopped || filename == null) return; |
| 442 | this.handleChange(normalizePath(String(filename))); |
| 443 | } |
| 444 | ); |
| 445 | this.recursiveWatcher.on('error', (err: unknown) => { |
| 446 | if (isWatchResourceExhaustion(err)) { |
| 447 | this.degrade(EXHAUSTION_REASON, { error: String(err) }); |
| 448 | return; |
| 449 | } |
| 450 | logWarn('File watcher error', { error: String(err) }); |
| 451 | }); |
| 452 | } |
| 453 | |
| 454 | /** |
| 455 | * Linux: walk the (non-ignored) tree and watch each directory. One inotify |
no test coverage detected