diff --git a/changelog.md b/changelog.md index ed59233..8021902 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,11 @@ # Changelog +## 2026-03-23 - 6.3.1 - fix(watcher) +unref lingering FSWatcher handles after stopping the node watcher + +- Ensures chokidar file watcher handles do not keep the process running after watcher shutdown +- Works around chokidar v5 behavior where close() can resolve before all fs.watch() handles are fully released + ## 2025-12-11 - 6.3.0 - feat(watchers) Integrate chokidar-based Node watcher, expose awaitWriteFinish options, and update docs/tests diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 0eede44..3dbb895 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartwatch', - version: '6.3.0', + version: '6.3.1', description: 'A cross-runtime file watcher with glob pattern support for Node.js, Deno, and Bun.' } diff --git a/ts/watchers/watcher.node.ts b/ts/watchers/watcher.node.ts index 78b8ef7..fd4e7e7 100644 --- a/ts/watchers/watcher.node.ts +++ b/ts/watchers/watcher.node.ts @@ -90,6 +90,14 @@ export class NodeWatcher implements IWatcher { this.watcher = null; } + // Unref any lingering FSWatcher handles from chokidar so they don't prevent process exit. + // Chokidar v5's close() resolves before all fs.watch() handles are fully released. + for (const handle of (process as any)._getActiveHandles()) { + if (handle?.constructor?.name === 'FSWatcher' && typeof handle.unref === 'function') { + handle.unref(); + } + } + this._isWatching = false; console.log('[smartwatch] Watcher stopped'); }