or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdcore-factory.mdindex.mdwatcher-modes.md

watcher-modes.mddocs/

0

# Watcher Modes

1

2

Different watcher implementations for various use cases and environments, all providing a consistent EventEmitter-based API with the same event types and method signatures.

3

4

## Capabilities

5

6

### NodeWatcher (Default Mode)

7

8

Uses Node.js built-in `fs.watch` for efficient native file system watching.

9

10

```javascript { .api }

11

/**

12

* Default fs.watch-based watcher

13

* @param {string} dir - Directory to watch

14

* @param {Object} options - Watcher options

15

*/

16

class NodeWatcher extends EventEmitter {

17

constructor(dir, options);

18

19

/**

20

* Stop watching and clean up resources

21

* @param {Function} callback - Optional callback called when closed

22

*/

23

close(callback);

24

}

25

```

26

27

**Best for:**

28

- General use cases on Linux and macOS

29

- Applications requiring low CPU usage and fast response times

30

- When native file system events are available and reliable

31

32

**Limitations:**

33

- May have issues on some network file systems

34

- Windows compatibility varies

35

- Can hit file descriptor limits with many directories

36

37

**Usage Example:**

38

39

```javascript

40

const { NodeWatcher } = require('sane');

41

42

const watcher = new NodeWatcher('/path/to/watch', {

43

glob: ['**/*.js', '**/*.json'],

44

ignored: ['node_modules/**']

45

});

46

47

watcher.on('ready', () => console.log('NodeWatcher ready'));

48

watcher.on('change', (file) => console.log('Changed:', file));

49

```

50

51

### PollWatcher (Polling Mode)

52

53

Uses `fs.watchFile` polling for maximum compatibility across all environments.

54

55

```javascript { .api }

56

/**

57

* Polling-based watcher using fs.watchFile

58

* @param {string} dir - Directory to watch

59

* @param {Object} options - Watcher options including interval

60

*/

61

class PollWatcher extends EventEmitter {

62

constructor(dir, options);

63

64

/**

65

* Stop watching and clean up resources

66

* @param {Function} callback - Optional callback called when closed

67

*/

68

close(callback);

69

}

70

```

71

72

**Additional Options:**

73

74

```javascript { .api }

75

interface PollWatcherOptions {

76

/** Polling interval in milliseconds (default: 100) */

77

interval?: number;

78

}

79

```

80

81

**Best for:**

82

- Network file systems (NFS, CIFS, etc.)

83

- Virtual environments like Vagrant

84

- When native file system events are unreliable

85

- Cross-platform consistency requirements

86

87

**Limitations:**

88

- Higher CPU usage due to constant polling

89

- Slower response time (dependent on polling interval)

90

- May miss very rapid file changes

91

92

**Usage Example:**

93

94

```javascript

95

const { PollWatcher } = require('sane');

96

97

const watcher = new PollWatcher('/path/to/watch', {

98

interval: 1000, // Poll every second

99

glob: ['**/*.css', '**/*.scss']

100

});

101

102

watcher.on('ready', () => console.log('PollWatcher ready'));

103

watcher.on('add', (file) => console.log('Added:', file));

104

```

105

106

### WatchmanWatcher (Watchman Mode)

107

108

Uses Facebook's Watchman for highly efficient watching of large directory trees.

109

110

```javascript { .api }

111

/**

112

* Facebook Watchman-based watcher

113

* @param {string} dir - Directory to watch

114

* @param {Object} options - Watcher options including watchmanPath

115

*/

116

class WatchmanWatcher extends EventEmitter {

117

constructor(dir, options);

118

119

/**

120

* Stop watching and clean up resources

121

* @param {Function} callback - Optional callback called when closed

122

*/

123

close(callback);

124

125

/**

126

* Create Watchman subscription options

127

* @returns {Object} Watchman subscription configuration

128

*/

129

createOptions();

130

131

/**

132

* Handle error events from Watchman

133

* @param {Error} error - Error from Watchman service

134

*/

135

handleErrorEvent(error);

136

137

/**

138

* Handle change events from Watchman

139

* @param {Object} resp - Watchman response object

140

*/

141

handleChangeEvent(resp);

142

}

143

```

144

145

**Additional Options:**

146

147

```javascript { .api }

148

interface WatchmanOptions {

149

/** Custom path to Watchman binary */

150

watchmanPath?: string;

151

}

152

```

153

154

**Best for:**

155

- Very large codebases (thousands of files)

156

- Development environments where Watchman is already installed

157

- Applications requiring maximum performance and reliability

158

- Projects that hit fs.watch file descriptor limits

159

160

**Limitations:**

161

- Requires separate Watchman installation

162

- Additional system dependency

163

- More complex setup process

164

165

**Usage Example:**

166

167

```javascript

168

const { WatchmanWatcher } = require('sane');

169

170

const watcher = new WatchmanWatcher('/large/project', {

171

watchmanPath: '/usr/local/bin/watchman',

172

glob: ['src/**/*.js', 'test/**/*.js']

173

});

174

175

watcher.on('ready', () => console.log('Watchman ready'));

176

watcher.on('all', (type, file) => console.log(type, ':', file));

177

```

178

179

### WatchexecWatcher (Watchexec Mode)

180

181

Uses the external watchexec tool for cross-platform file watching.

182

183

```javascript { .api }

184

/**

185

* Watchexec-based watcher using external watchexec process

186

* @param {string} dir - Directory to watch

187

* @param {Object} options - Watcher options

188

*/

189

class WatchexecWatcher extends EventEmitter {

190

constructor(dir, options);

191

192

/**

193

* Stop watching and clean up resources

194

* @param {Function} callback - Optional callback called when closed

195

*/

196

close(callback);

197

198

/**

199

* Emit filesystem events to the watcher

200

* @param {string} type - Event type ('change', 'add', 'delete')

201

* @param {string} file - File path relative to watched directory

202

* @param {fs.Stats|null} stat - File statistics (null for delete events)

203

*/

204

emitEvent(type, file, stat);

205

}

206

207

/**

208

* Static message handler for processing watchexec output

209

* @static

210

*/

211

WatchexecWatcher._messageHandler;

212

```

213

214

**Best for:**

215

- Cross-platform consistency

216

- When other watchers have platform-specific issues

217

- Integration with existing watchexec workflows

218

219

**Limitations:**

220

- Requires separate watchexec installation

221

- Additional external process overhead

222

- Less mature integration compared to other modes

223

224

**Usage Example:**

225

226

```javascript

227

const { WatchexecWatcher } = require('sane');

228

229

const watcher = new WatchexecWatcher('/path/to/watch', {

230

ignored: ['*.tmp', 'build/**']

231

});

232

233

watcher.on('ready', () => console.log('Watchexec ready'));

234

watcher.on('delete', (file) => console.log('Deleted:', file));

235

```

236

237

## Common Event Interface

238

239

All watcher classes emit the same events with identical signatures:

240

241

```javascript { .api }

242

interface WatcherEvents {

243

/** Emitted when watcher is ready to detect changes */

244

'ready': () => void;

245

246

/** Emitted when a file is modified */

247

'change': (filepath: string, root: string, stat: fs.Stats) => void;

248

249

/** Emitted when a file or directory is added */

250

'add': (filepath: string, root: string, stat: fs.Stats) => void;

251

252

/** Emitted when a file or directory is deleted (stat parameter is null) */

253

'delete': (filepath: string, root: string, stat: null) => void;

254

255

/** Emitted for all change types */

256

'all': (eventType: 'change'|'add'|'delete', filepath: string, root: string, stat?: fs.Stats) => void;

257

258

/** Emitted when errors occur */

259

'error': (error: Error) => void;

260

}

261

```

262

263

## Mode Selection Guidelines

264

265

Choose the appropriate watcher mode based on your environment and requirements:

266

267

1. **NodeWatcher (Default)**: Use for most general applications on modern systems

268

2. **PollWatcher**: Use in virtual environments, network filesystems, or when native events are unreliable

269

3. **WatchmanWatcher**: Use for large projects or when maximum performance is required

270

4. **WatchexecWatcher**: Use when other modes have platform-specific issues

271

272

## Error Handling

273

274

All watchers handle common filesystem errors gracefully:

275

276

- `ENOENT` errors (file not found) are generally ignored

277

- `EPERM` errors on Windows are handled appropriately

278

- Connection errors (Watchman) are propagated as error events

279

- Process spawn errors (Watchexec) are propagated as error events

280

281

```javascript

282

watcher.on('error', (error) => {

283

if (error.code === 'ENOENT') {

284

// File was deleted, usually safe to ignore

285

} else {

286

console.error('Watcher error:', error);

287

}

288

});

289

```