Files
smartwatch/readme.hints.md

3.4 KiB

smartwatch - Technical Hints

Native File Watching (v6.0.0+)

The module provides cross-runtime file watching support:

  • Node.js/Bun: Uses chokidar v5
  • Deno: Uses native Deno.watchFs()

Exported Class

The package exports the Smartwatch class:

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:

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

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