or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-operations.mdcore-walking.mdevents-control.mdindex.mdoptions-configuration.mdsync-operations.md

events-control.mddocs/

0

# Event System & Control

1

2

Event emitter interface providing comprehensive file system events and flow control methods for directory traversal operations.

3

4

## Capabilities

5

6

### WalkEmitter Interface

7

8

The emitter returned by walkdir provides fine-grained control over the traversal process.

9

10

```javascript { .api }

11

/**

12

* Extended EventEmitter with walkdir-specific control methods

13

*/

14

interface WalkEmitter extends EventEmitter {

15

/** Stop the walk immediately and prevent further events */

16

end(): void;

17

/** Alias for end() - stop the walk immediately */

18

stop(): void;

19

/** Pause event emission while keeping traversal active */

20

pause(): void;

21

/** Resume event emission after pause */

22

resume(): void;

23

/** Ignore specific paths during traversal */

24

ignore(paths: string | string[]): void;

25

}

26

```

27

28

**Usage Examples:**

29

30

```javascript

31

const walkdir = require('walkdir');

32

33

const emitter = walkdir('./my-directory');

34

35

// Stop after finding 100 files

36

let fileCount = 0;

37

emitter.on('file', (path, stat) => {

38

fileCount++;

39

if (fileCount >= 100) {

40

emitter.end(); // Stop immediately

41

}

42

});

43

44

// Pause and resume based on system load

45

emitter.on('directory', (path, stat) => {

46

if (isSystemBusy()) {

47

emitter.pause();

48

setTimeout(() => emitter.resume(), 1000);

49

}

50

});

51

52

// Ignore specific directories dynamically

53

emitter.on('directory', (path, stat) => {

54

if (path.includes('node_modules') || path.includes('.git')) {

55

emitter.ignore(path); // Skip this directory and all children

56

}

57

});

58

```

59

60

### Core Events

61

62

Events emitted for different types of file system objects found during traversal.

63

64

```javascript { .api }

65

/**

66

* All events follow the pattern: (path: string, stat: fs.Stats, depth: number)

67

*/

68

69

/** Emitted for every file system object found */

70

emitter.on('path', (path, stat, depth) => {});

71

72

/** Emitted only for regular files */

73

emitter.on('file', (path, stat, depth) => {});

74

75

/** Emitted only for directories */

76

emitter.on('directory', (path, stat, depth) => {});

77

78

/** Emitted only for symbolic links */

79

emitter.on('link', (path, stat, depth) => {});

80

81

/** Emitted for the initial target directory (if it's a directory) */

82

emitter.on('targetdirectory', (path, stat, depth) => {});

83

84

/** Emitted when a directory is empty */

85

emitter.on('empty', (path, stat, depth) => {});

86

87

/** Emitted when traversal completes successfully */

88

emitter.on('end', () => {});

89

```

90

91

**Usage Examples:**

92

93

```javascript

94

const emitter = walkdir('./project');

95

96

// Process different file types

97

emitter.on('file', (path, stat, depth) => {

98

if (path.endsWith('.js')) {

99

console.log('JavaScript file:', path, 'at depth', depth);

100

}

101

});

102

103

emitter.on('directory', (path, stat, depth) => {

104

console.log('Directory:', path, 'contains', stat.size, 'entries');

105

});

106

107

emitter.on('link', (path, stat, depth) => {

108

console.log('Symbolic link found:', path);

109

});

110

111

// Handle completion

112

emitter.on('end', () => {

113

console.log('Directory traversal completed');

114

});

115

116

// Track progress

117

let totalItems = 0;

118

emitter.on('path', () => {

119

totalItems++;

120

if (totalItems % 100 === 0) {

121

console.log(`Processed ${totalItems} items...`);

122

}

123

});

124

```

125

126

### Special Device Events

127

128

Events for special file system objects like sockets, fifos, and devices.

129

130

```javascript { .api }

131

/** Emitted for socket descriptors */

132

emitter.on('socket', (path, stat, depth) => {});

133

134

/** Emitted for FIFO/named pipes */

135

emitter.on('fifo', (path, stat, depth) => {});

136

137

/** Emitted for block devices */

138

emitter.on('blockdevice', (path, stat, depth) => {});

139

140

/** Emitted for character devices */

141

emitter.on('characterdevice', (path, stat, depth) => {});

142

```

143

144

**Usage Example:**

145

146

```javascript

147

const emitter = walkdir('/dev');

148

149

emitter.on('blockdevice', (path, stat) => {

150

console.log('Block device (disk):', path);

151

});

152

153

emitter.on('characterdevice', (path, stat) => {

154

console.log('Character device (terminal/tty):', path);

155

});

156

157

emitter.on('socket', (path, stat) => {

158

console.log('Socket found:', path);

159

});

160

```

161

162

### Error Events

163

164

Error handling events for various failure scenarios during traversal.

165

166

```javascript { .api }

167

/** Emitted for fatal errors reading the target directory */

168

emitter.on('error', (error) => {});

169

170

/** Emitted for non-fatal errors reading nested paths */

171

emitter.on('fail', (path, error) => {});

172

173

/** Emitted when maximum depth is reached */

174

emitter.on('maxdepth', (path, stat, depth) => {});

175

```

176

177

**Error Handling Examples:**

178

179

```javascript

180

const emitter = walkdir('./some-directory');

181

182

// Handle fatal errors (target directory issues)

183

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

184

console.error('Fatal error - cannot read target directory:', error.message);

185

process.exit(1);

186

});

187

188

// Handle non-fatal errors (permission issues, corrupt files, etc.)

189

emitter.on('fail', (path, error) => {

190

console.warn('Could not access path:', path, '-', error.message);

191

// Continue processing other paths

192

});

193

194

// Handle depth limits

195

emitter.on('maxdepth', (path, stat, depth) => {

196

console.log('Reached maximum depth at:', path, 'depth:', depth);

197

// Note: traversal continues but won't go deeper into this path

198

});

199

200

// Graceful error handling

201

let errorCount = 0;

202

emitter.on('fail', (path, error) => {

203

errorCount++;

204

if (errorCount > 10) {

205

console.warn('Too many errors, stopping traversal');

206

emitter.end();

207

}

208

});

209

```

210

211

### Flow Control Methods

212

213

Methods for controlling the traversal process dynamically.

214

215

```javascript { .api }

216

/**

217

* Stop the walk immediately

218

* No more events will be emitted after calling end()

219

*/

220

emitter.end();

221

222

/**

223

* Alias for end() - stop the walk immediately

224

* Same functionality as end()

225

*/

226

emitter.stop();

227

228

/**

229

* Pause event emission

230

* Traversal continues but events are queued until resume()

231

*/

232

emitter.pause();

233

234

/**

235

* Resume event emission after pause

236

* Queued events will be emitted in order

237

*/

238

emitter.resume();

239

240

/**

241

* Ignore specific paths during traversal

242

* Ignored directories will not be entered or have children processed

243

* @param {string|string[]} paths - Path or array of paths to ignore

244

*/

245

emitter.ignore(paths);

246

```

247

248

**Flow Control Examples:**

249

250

```javascript

251

const emitter = walkdir('./large-project');

252

253

// Conditional stopping

254

emitter.on('file', (path, stat) => {

255

if (path.endsWith('.exe') && stat.size > 100 * 1024 * 1024) {

256

console.log('Found large executable, stopping scan');

257

emitter.end();

258

}

259

});

260

261

// Throttling with pause/resume

262

let processedCount = 0;

263

emitter.on('path', (path, stat) => {

264

processedCount++;

265

266

// Pause every 1000 items to prevent overwhelming

267

if (processedCount % 1000 === 0) {

268

emitter.pause();

269

setTimeout(() => {

270

console.log(`Processed ${processedCount} items, resuming...`);

271

emitter.resume();

272

}, 100);

273

}

274

});

275

276

// Dynamic path ignoring

277

const ignoredPaths = [];

278

emitter.on('directory', (path, stat) => {

279

if (path.includes('cache') || path.includes('temp')) {

280

ignoredPaths.push(path);

281

emitter.ignore(path);

282

console.log('Ignoring cache/temp directory:', path);

283

}

284

});

285

286

// Bulk ignore patterns

287

emitter.on('targetdirectory', () => {

288

// Ignore common build/cache directories upfront

289

emitter.ignore([

290

'./node_modules',

291

'./.git',

292

'./build',

293

'./dist',

294

'./.cache'

295

]);

296

});

297

```

298

299

### Event Chaining Patterns

300

301

Common patterns for combining events and control methods.

302

303

```javascript

304

// Progress reporting with early termination

305

const emitter = walkdir('./project');

306

let startTime = Date.now();

307

let itemCount = 0;

308

309

emitter.on('path', (path, stat) => {

310

itemCount++;

311

312

// Progress every 500 items

313

if (itemCount % 500 === 0) {

314

const elapsed = (Date.now() - startTime) / 1000;

315

console.log(`${itemCount} items processed in ${elapsed}s`);

316

}

317

318

// Stop after 10 seconds

319

if (Date.now() - startTime > 10000) {

320

console.log('Time limit reached, stopping');

321

emitter.end();

322

}

323

});

324

325

emitter.on('end', () => {

326

const elapsed = (Date.now() - startTime) / 1000;

327

console.log(`Completed: ${itemCount} items in ${elapsed}s`);

328

});

329

```