0
# Walk
1
2
Walk is a Node.js port of Python's os.walk that provides both asynchronous and synchronous filesystem traversal capabilities. It uses EventEmitter patterns with built-in flow control to minimize file descriptor usage, making it well-suited for traditional hard disk operations.
3
4
## Package Information
5
6
- **Package Name**: walk
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install walk`
10
11
## Core Imports
12
13
```javascript
14
const walk = require('walk');
15
```
16
17
## Basic Usage
18
19
```javascript
20
const walk = require('walk');
21
22
// Create an asynchronous walker
23
const walker = walk.walk('/tmp');
24
25
walker.on('file', function (root, fileStats, next) {
26
console.log(root + '/' + fileStats.name);
27
next(); // Must call next() to continue walking
28
});
29
30
walker.on('end', function () {
31
console.log('Walk completed');
32
});
33
```
34
35
## Architecture
36
37
Walk is built around several key components:
38
39
- **Walker Class**: Internal EventEmitter-based class that performs the actual filesystem traversal
40
- **Flow Control**: All event handlers receive a `next()` callback that must be called to continue processing
41
- **Event System**: Comprehensive event system supporting both individual node events and grouped events
42
- **Sync/Async Modes**: Both asynchronous and synchronous walking with identical APIs
43
- **Built-in Filtering**: Directory filtering and symbolic link following options
44
45
## Capabilities
46
47
### Asynchronous Walking
48
49
Creates an asynchronous directory walker that traverses the filesystem using EventEmitter patterns.
50
51
```javascript { .api }
52
/**
53
* Creates an asynchronous directory walker
54
* @param {string} path - Starting directory path to walk
55
* @param {WalkOptions} [options] - Configuration options
56
* @returns {Walker} EventEmitter instance for handling walk events
57
*/
58
function walk(path, options);
59
```
60
61
**Usage Example:**
62
63
```javascript
64
const walk = require('walk');
65
66
const walker = walk.walk('./my-directory', {
67
followLinks: false,
68
filters: ['node_modules', '.git']
69
});
70
71
walker.on('file', function (root, fileStats, next) {
72
console.log('Found file:', root + '/' + fileStats.name);
73
next();
74
});
75
76
walker.on('directory', function (root, dirStats, next) {
77
console.log('Found directory:', root + '/' + dirStats.name);
78
next();
79
});
80
81
walker.on('end', function () {
82
console.log('Walk completed');
83
});
84
```
85
86
### Synchronous Walking
87
88
Creates a synchronous directory walker with the same API as the asynchronous version.
89
90
```javascript { .api }
91
/**
92
* Creates a synchronous directory walker
93
* @param {string} path - Starting directory path to walk
94
* @param {WalkOptions} [options] - Configuration options
95
* @returns {Walker} EventEmitter instance for handling walk events
96
*/
97
function walkSync(path, options);
98
```
99
100
**Usage Example:**
101
102
```javascript
103
const walk = require('walk');
104
105
// For truly synchronous operation, use options.listeners
106
const walker = walk.walkSync('./my-directory', {
107
listeners: {
108
file: function (root, fileStats, next) {
109
console.log('Found file:', root + '/' + fileStats.name);
110
next();
111
},
112
directories: function (root, dirStatsArray, next) {
113
console.log('Found directories:', dirStatsArray.map(s => s.name));
114
next();
115
},
116
end: function () {
117
console.log('Walk completed');
118
}
119
}
120
});
121
```
122
123
### Walker Instance Control
124
125
Control methods available on walker instances for pausing and resuming operations.
126
127
```javascript { .api }
128
/**
129
* Pauses the walker, preventing further filesystem operations
130
*/
131
walker.pause();
132
133
/**
134
* Resumes a paused walker, continuing filesystem operations
135
*/
136
walker.resume();
137
```
138
139
## Events
140
141
### Individual Node Events
142
143
All individual node event callbacks have the signature: `function (root, stat, next) {}`
144
145
```javascript { .api }
146
/**
147
* Emitted for any filesystem node
148
* @param {string} root - Current directory path
149
* @param {WalkStat} stat - File statistics with additional properties
150
* @param {function} next - Callback to continue processing
151
*/
152
walker.on('node', function (root, stat, next) {});
153
154
/**
155
* Emitted for each file (includes symbolic links when followLinks is true)
156
* @param {string} root - Current directory path
157
* @param {WalkStat} stat - File statistics with additional properties
158
* @param {function} next - Callback to continue processing
159
*/
160
walker.on('file', function (root, stat, next) {});
161
162
/**
163
* Emitted for each directory
164
* @param {string} root - Current directory path
165
* @param {WalkStat} stat - Directory statistics with additional properties
166
* @param {function} next - Callback to continue processing
167
*/
168
walker.on('directory', function (root, stat, next) {});
169
170
/**
171
* Emitted for symbolic links (empty when followLinks is true)
172
* @param {string} root - Current directory path
173
* @param {WalkStat} stat - Symbolic link statistics with additional properties
174
* @param {function} next - Callback to continue processing
175
*/
176
walker.on('symbolicLink', function (root, stat, next) {});
177
178
/**
179
* Emitted for block devices
180
* @param {string} root - Current directory path
181
* @param {WalkStat} stat - Block device statistics with additional properties
182
* @param {function} next - Callback to continue processing
183
*/
184
walker.on('blockDevice', function (root, stat, next) {});
185
186
/**
187
* Emitted for character devices
188
* @param {string} root - Current directory path
189
* @param {WalkStat} stat - Character device statistics with additional properties
190
* @param {function} next - Callback to continue processing
191
*/
192
walker.on('characterDevice', function (root, stat, next) {});
193
194
/**
195
* Emitted for FIFO files
196
* @param {string} root - Current directory path
197
* @param {WalkStat} stat - FIFO statistics with additional properties
198
* @param {function} next - Callback to continue processing
199
*/
200
walker.on('FIFO', function (root, stat, next) {});
201
202
/**
203
* Emitted for socket files
204
* @param {string} root - Current directory path
205
* @param {WalkStat} stat - Socket statistics with additional properties
206
* @param {function} next - Callback to continue processing
207
*/
208
walker.on('socket', function (root, stat, next) {});
209
```
210
211
### Grouped Events
212
213
All grouped event callbacks have the signature: `function (root, statsArray, next) {}`
214
215
```javascript { .api }
216
/**
217
* Emitted before stat operations, contains array of filenames
218
* @param {string} root - Current directory path
219
* @param {string[]} nodeNamesArray - Array of filenames in the directory
220
* @param {function} next - Callback to continue processing (noop for names event)
221
*/
222
walker.on('names', function (root, nodeNamesArray, next) {});
223
224
/**
225
* Emitted for each individual filename before stat operations
226
* @param {string} root - Current directory path
227
* @param {string} filename - Individual filename
228
* @param {function} next - Callback to continue processing (noop for name event)
229
*/
230
walker.on('name', function (root, filename, next) {});
231
232
/**
233
* Emitted for all nodes in a directory
234
* @param {string} root - Current directory path
235
* @param {WalkStat[]} statsArray - Array of all node statistics
236
* @param {function} next - Callback to continue processing
237
*/
238
walker.on('nodes', function (root, statsArray, next) {});
239
240
/**
241
* Emitted for all files in a directory
242
* @param {string} root - Current directory path
243
* @param {WalkStat[]} statsArray - Array of file statistics
244
* @param {function} next - Callback to continue processing
245
*/
246
walker.on('files', function (root, statsArray, next) {});
247
248
/**
249
* Emitted for all directories in a directory
250
* @param {string} root - Current directory path
251
* @param {WalkStat[]} statsArray - Array of directory statistics
252
* @param {function} next - Callback to continue processing
253
*/
254
walker.on('directories', function (root, statsArray, next) {});
255
256
/**
257
* Emitted for all symbolic links in a directory
258
* @param {string} root - Current directory path
259
* @param {WalkStat[]} statsArray - Array of symbolic link statistics
260
* @param {function} next - Callback to continue processing
261
*/
262
walker.on('symbolicLinks', function (root, statsArray, next) {});
263
264
/**
265
* Emitted for all block devices in a directory
266
* @param {string} root - Current directory path
267
* @param {WalkStat[]} statsArray - Array of block device statistics
268
* @param {function} next - Callback to continue processing
269
*/
270
walker.on('blockDevices', function (root, statsArray, next) {});
271
272
/**
273
* Emitted for all character devices in a directory
274
* @param {string} root - Current directory path
275
* @param {WalkStat[]} statsArray - Array of character device statistics
276
* @param {function} next - Callback to continue processing
277
*/
278
walker.on('characterDevices', function (root, statsArray, next) {});
279
280
/**
281
* Emitted for all FIFO files in a directory
282
* @param {string} root - Current directory path
283
* @param {WalkStat[]} statsArray - Array of FIFO statistics
284
* @param {function} next - Callback to continue processing
285
*/
286
walker.on('FIFOs', function (root, statsArray, next) {});
287
288
/**
289
* Emitted for all socket files in a directory
290
* @param {string} root - Current directory path
291
* @param {WalkStat[]} statsArray - Array of socket statistics
292
* @param {function} next - Callback to continue processing
293
*/
294
walker.on('sockets', function (root, statsArray, next) {});
295
```
296
297
### Error Events
298
299
```javascript { .api }
300
/**
301
* Collection of all errors encountered in a directory
302
* @param {string} root - Current directory path
303
* @param {WalkStat[]} errorStatsArray - Array of error statistics
304
* @param {function} next - Callback to continue processing
305
*/
306
walker.on('errors', function (root, errorStatsArray, next) {});
307
308
/**
309
* Error when fs.stat/lstat fails
310
* @param {string} root - Current directory path
311
* @param {WalkStat} stat - Statistics object with error property
312
* @param {function} next - Callback to continue processing
313
*/
314
walker.on('nodeError', function (root, stat, next) {});
315
316
/**
317
* Error when fs.readdir fails but stat succeeded
318
* @param {string} root - Current directory path
319
* @param {WalkStat} stat - Statistics object with error property
320
* @param {function} next - Callback to continue processing
321
*/
322
walker.on('directoryError', function (root, stat, next) {});
323
```
324
325
### Completion Event
326
327
```javascript { .api }
328
/**
329
* Emitted when walking is complete
330
*/
331
walker.on('end', function () {});
332
```
333
334
## Types
335
336
```javascript { .api }
337
/**
338
* Configuration options for walk operations
339
*/
340
interface WalkOptions {
341
/** Whether to follow symbolic links (default: false) */
342
followLinks?: boolean;
343
/** Array of directory names or regex patterns to filter out */
344
filters?: (string | RegExp)[];
345
/** Event listeners for synchronous walker operations */
346
listeners?: WalkListeners;
347
}
348
349
/**
350
* Event listeners for synchronous walker operations
351
*/
352
interface WalkListeners {
353
names?: (root: string, nodeNamesArray: string[], next: () => void) => void;
354
name?: (root: string, filename: string, next: () => void) => void;
355
node?: (root: string, stat: WalkStat, next: () => void) => void;
356
file?: (root: string, stat: WalkStat, next: () => void) => void;
357
directory?: (root: string, stat: WalkStat, next: () => void) => void;
358
symbolicLink?: (root: string, stat: WalkStat, next: () => void) => void;
359
blockDevice?: (root: string, stat: WalkStat, next: () => void) => void;
360
characterDevice?: (root: string, stat: WalkStat, next: () => void) => void;
361
FIFO?: (root: string, stat: WalkStat, next: () => void) => void;
362
socket?: (root: string, stat: WalkStat, next: () => void) => void;
363
nodes?: (root: string, statsArray: WalkStat[], next: () => void) => void;
364
files?: (root: string, statsArray: WalkStat[], next: () => void) => void;
365
directories?: (root: string, statsArray: WalkStat[], next: () => void) => void;
366
symbolicLinks?: (root: string, statsArray: WalkStat[], next: () => void) => void;
367
blockDevices?: (root: string, statsArray: WalkStat[], next: () => void) => void;
368
characterDevices?: (root: string, statsArray: WalkStat[], next: () => void) => void;
369
FIFOs?: (root: string, statsArray: WalkStat[], next: () => void) => void;
370
sockets?: (root: string, statsArray: WalkStat[], next: () => void) => void;
371
errors?: (root: string, errorStatsArray: WalkStat[], next: () => void) => void;
372
nodeError?: (root: string, stat: WalkStat, next: () => void) => void;
373
directoryError?: (root: string, stat: WalkStat, next: () => void) => void;
374
end?: () => void;
375
}
376
377
/**
378
* Enhanced file statistics object extending Node.js fs.Stats
379
*/
380
interface WalkStat {
381
/** The filename */
382
name: string;
383
/** File type ('file', 'directory', 'symbolicLink', etc.) */
384
type: string;
385
/** Error object if stat operation failed */
386
error?: Error;
387
388
// Standard fs.Stats properties
389
/** Device ID */
390
dev: number;
391
/** File mode (permissions and file type) */
392
mode: number;
393
/** Number of hard links */
394
nlink: number;
395
/** User ID */
396
uid: number;
397
/** Group ID */
398
gid: number;
399
/** Device ID (if special file) */
400
rdev: number;
401
/** Block size for filesystem I/O */
402
blksize: number;
403
/** Inode number */
404
ino: number;
405
/** Total size in bytes */
406
size: number;
407
/** Number of 512-byte blocks allocated */
408
blocks: number;
409
/** Access time */
410
atime: Date;
411
/** Modification time */
412
mtime: Date;
413
/** Change time */
414
ctime: Date;
415
/** Birth time (creation time) */
416
birthtime: Date;
417
}
418
419
/**
420
* Walker instance extending EventEmitter
421
*/
422
interface Walker extends EventEmitter {
423
/** Pauses the walker */
424
pause(): void;
425
/** Resumes a paused walker */
426
resume(): void;
427
}
428
```