* Stop watching for file changes.
()
| 707 | * Stop watching for file changes. |
| 708 | */ |
| 709 | stop(): void { |
| 710 | this.stopped = true; |
| 711 | |
| 712 | if (this.debounceTimer) { |
| 713 | clearTimeout(this.debounceTimer); |
| 714 | this.debounceTimer = null; |
| 715 | } |
| 716 | |
| 717 | if (this.recursiveWatcher) { |
| 718 | try { |
| 719 | this.recursiveWatcher.close(); |
| 720 | } catch { |
| 721 | /* already closed */ |
| 722 | } |
| 723 | this.recursiveWatcher = null; |
| 724 | } |
| 725 | for (const w of this.dirWatchers.values()) { |
| 726 | try { |
| 727 | w.close(); |
| 728 | } catch { |
| 729 | /* already closed */ |
| 730 | } |
| 731 | } |
| 732 | this.dirWatchers.clear(); |
| 733 | this.dirCapWarned = false; |
| 734 | this.inotifyLimitWarned = false; |
| 735 | this.lockRetryCount = 0; |
| 736 | this.syncFailureRetryCount = 0; |
| 737 | // NB: degradedReason is intentionally NOT reset here — it must survive the |
| 738 | // stop() that degrade() triggers so isDegraded() stays true. start() clears it. |
| 739 | this.inert = false; |
| 740 | |
| 741 | this.pendingFiles.clear(); |
| 742 | this.ready = false; |
| 743 | this.ignoreMatcher = null; |
| 744 | if (IS_TEST_RUNTIME) liveWatchersForTests.delete(this.projectRoot); |
| 745 | logDebug('File watcher stopped'); |
| 746 | } |
| 747 | |
| 748 | /** |
| 749 | * @internal Test-only: feed a synthetic project-relative change through the |