# smartwatch - Technical Hints ## Native File Watching (v6.0.0+) The module provides cross-runtime file watching support: - **Node.js/Bun**: Uses [chokidar](https://github.com/paulmillr/chokidar) v5 - **Deno**: Uses native `Deno.watchFs()` ### Exported Class The package exports the `Smartwatch` class: ```typescript import { Smartwatch } from '@push.rocks/smartwatch'; ``` ### Architecture ``` ts/ ├── smartwatch.classes.smartwatch.ts # Main Smartwatch class ├── smartwatch.plugins.ts # Dependencies ├── watchers/ │ ├── index.ts # Factory with runtime detection │ ├── interfaces.ts # IWatcher interface and types │ ├── watcher.node.ts # Node.js/Bun: chokidar wrapper │ └── watcher.deno.ts # Deno: Deno.watchFs wrapper └── utils/ └── write-stabilizer.ts # awaitWriteFinish polling implementation ``` ### Runtime Detection Uses `@push.rocks/smartenv` for runtime detection: - **Node.js/Bun**: Uses chokidar (battle-tested file watcher) - **Deno**: Uses `Deno.watchFs()` async iterable ### Dependencies - **chokidar**: Battle-tested file watcher for Node.js/Bun - **picomatch**: Glob pattern matching (zero deps) - **@push.rocks/smartenv**: Runtime detection - **@push.rocks/smartrx**: RxJS Subject/Observable management - **@push.rocks/smartpromise**: Deferred promise utilities - **@push.rocks/lik**: Stringmap for pattern storage ### Chokidar Features (Node.js/Bun) The Node.js watcher (`ts/watchers/watcher.node.ts`) is a thin ~100 line wrapper around chokidar v5: ```typescript chokidar.watch(paths, { persistent: true, ignoreInitial: false, followSymlinks: options.followSymlinks, depth: options.depth, atomic: true, // Handles atomic writes (delete+recreate, temp+rename) awaitWriteFinish: { stabilityThreshold: 300, pollInterval: 100 }, }); ``` **Chokidar handles all edge cases:** - Atomic writes (temp file + rename pattern) → emits single 'change' event - Delete + recreate detection → emits single 'change' event - Inode tracking - Cross-platform differences (inotify, FSEvents, etc.) - Debouncing - Write stabilization - ENOSPC (inotify limit) errors ### Event Handling Events are normalized across all runtimes: | Event | Description | |-------|-------------| | `add` | File added | | `change` | File modified | | `unlink` | File removed | | `addDir` | Directory added | | `unlinkDir` | Directory removed | | `ready` | Initial scan complete | | `error` | Error occurred | ### Platform Requirements - **Node.js 20+**: Required for chokidar v5 - **Deno**: Works on all versions with `Deno.watchFs()` - **Bun**: Uses Node.js compatibility layer with chokidar ### Testing ```bash pnpm test ``` Test files: - **test.basic.ts** - Core functionality (add, change, unlink events) - **test.inode.ts** - Atomic write detection (delete+recreate, temp+rename) - **test.stress.ts** - Rapid modifications, many files, interleaved operations Tests verify: - Creating Smartwatch instance - Adding glob patterns - Receiving 'add', 'change', 'unlink' events - Atomic write detection (delete+recreate → change event) - Temp file + rename pattern detection - Rapid file modifications (debouncing) - Many files created rapidly - Interleaved add/change/delete operations - Graceful shutdown ## Dev Dependencies - Using `@git.zone/tstest` v3.x with tapbundle - Import from `@git.zone/tstest/tapbundle`