* Stop watching for file changes.
()
| 754 | * Stop watching for file changes. |
| 755 | */ |
| 756 | stop(): void { |
| 757 | this.stopped = true; |
| 758 | |
| 759 | if (this.debounceTimer) { |
| 760 | clearTimeout(this.debounceTimer); |
| 761 | this.debounceTimer = null; |
| 762 | } |
| 763 | |
| 764 | if (this.recursiveWatcher) { |
| 765 | try { |
| 766 | this.recursiveWatcher.close(); |
| 767 | } catch { |
| 768 | /* already closed */ |
| 769 | } |
| 770 | this.recursiveWatcher = null; |
| 771 | } |
| 772 | for (const w of this.dirWatchers.values()) { |
| 773 | try { |
| 774 | w.close(); |
| 775 | } catch { |
| 776 | /* already closed */ |
| 777 | } |
| 778 | } |
| 779 | this.dirWatchers.clear(); |
| 780 | this.dirCapWarned = false; |
| 781 | this.inotifyLimitWarned = false; |
| 782 | this.lockRetryCount = 0; |
| 783 | this.syncFailureRetryCount = 0; |
| 784 | // NB: degradedReason is intentionally NOT reset here — it must survive the |
| 785 | // stop() that degrade() triggers so isDegraded() stays true. start() clears it. |
| 786 | this.inert = false; |
| 787 | |
| 788 | this.pendingFiles.clear(); |
| 789 | this.ready = false; |
| 790 | this.ignoreMatcher = null; |
| 791 | if (IS_TEST_RUNTIME) liveWatchersForTests.delete(this.projectRoot); |
| 792 | logDebug('File watcher stopped'); |
| 793 | } |
| 794 | |
| 795 | /** |
| 796 | * @internal Test-only: feed a synthetic project-relative change through the |