or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-walk

A Node.js port of Python's os.walk for asynchronous and synchronous filesystem traversal with EventEmitter patterns

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/walk@2.3.x

To install, run

npx @tessl/cli install tessl/npm-walk@2.3.0

index.mddocs/

Walk

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.

Package Information

  • Package Name: walk
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install walk

Core Imports

const walk = require('walk');

Basic Usage

const walk = require('walk');

// Create an asynchronous walker
const walker = walk.walk('/tmp');

walker.on('file', function (root, fileStats, next) {
  console.log(root + '/' + fileStats.name);
  next(); // Must call next() to continue walking
});

walker.on('end', function () {
  console.log('Walk completed');
});

Architecture

Walk is built around several key components:

  • Walker Class: Internal EventEmitter-based class that performs the actual filesystem traversal
  • Flow Control: All event handlers receive a next() callback that must be called to continue processing
  • Event System: Comprehensive event system supporting both individual node events and grouped events
  • Sync/Async Modes: Both asynchronous and synchronous walking with identical APIs
  • Built-in Filtering: Directory filtering and symbolic link following options

Capabilities

Asynchronous Walking

Creates an asynchronous directory walker that traverses the filesystem using EventEmitter patterns.

/**
 * Creates an asynchronous directory walker
 * @param {string} path - Starting directory path to walk
 * @param {WalkOptions} [options] - Configuration options
 * @returns {Walker} EventEmitter instance for handling walk events
 */
function walk(path, options);

Usage Example:

const walk = require('walk');

const walker = walk.walk('./my-directory', {
  followLinks: false,
  filters: ['node_modules', '.git']
});

walker.on('file', function (root, fileStats, next) {
  console.log('Found file:', root + '/' + fileStats.name);
  next();
});

walker.on('directory', function (root, dirStats, next) {
  console.log('Found directory:', root + '/' + dirStats.name);
  next();
});

walker.on('end', function () {
  console.log('Walk completed');
});

Synchronous Walking

Creates a synchronous directory walker with the same API as the asynchronous version.

/**
 * Creates a synchronous directory walker
 * @param {string} path - Starting directory path to walk
 * @param {WalkOptions} [options] - Configuration options
 * @returns {Walker} EventEmitter instance for handling walk events
 */
function walkSync(path, options);

Usage Example:

const walk = require('walk');

// For truly synchronous operation, use options.listeners
const walker = walk.walkSync('./my-directory', {
  listeners: {
    file: function (root, fileStats, next) {
      console.log('Found file:', root + '/' + fileStats.name);
      next();
    },
    directories: function (root, dirStatsArray, next) {
      console.log('Found directories:', dirStatsArray.map(s => s.name));
      next();
    },
    end: function () {
      console.log('Walk completed');
    }
  }
});

Walker Instance Control

Control methods available on walker instances for pausing and resuming operations.

/**
 * Pauses the walker, preventing further filesystem operations
 */
walker.pause();

/**
 * Resumes a paused walker, continuing filesystem operations
 */
walker.resume();

Events

Individual Node Events

All individual node event callbacks have the signature: function (root, stat, next) {}

/**
 * Emitted for any filesystem node
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - File statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('node', function (root, stat, next) {});

/**
 * Emitted for each file (includes symbolic links when followLinks is true)
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - File statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('file', function (root, stat, next) {});

/**
 * Emitted for each directory
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Directory statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('directory', function (root, stat, next) {});

/**
 * Emitted for symbolic links (empty when followLinks is true)
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Symbolic link statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('symbolicLink', function (root, stat, next) {});

/**
 * Emitted for block devices
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Block device statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('blockDevice', function (root, stat, next) {});

/**
 * Emitted for character devices
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Character device statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('characterDevice', function (root, stat, next) {});

/**
 * Emitted for FIFO files
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - FIFO statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('FIFO', function (root, stat, next) {});

/**
 * Emitted for socket files
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Socket statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('socket', function (root, stat, next) {});

Grouped Events

All grouped event callbacks have the signature: function (root, statsArray, next) {}

/**
 * Emitted before stat operations, contains array of filenames
 * @param {string} root - Current directory path
 * @param {string[]} nodeNamesArray - Array of filenames in the directory
 * @param {function} next - Callback to continue processing (noop for names event)
 */
walker.on('names', function (root, nodeNamesArray, next) {});

/**
 * Emitted for each individual filename before stat operations
 * @param {string} root - Current directory path
 * @param {string} filename - Individual filename
 * @param {function} next - Callback to continue processing (noop for name event)
 */
walker.on('name', function (root, filename, next) {});

/**
 * Emitted for all nodes in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of all node statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('nodes', function (root, statsArray, next) {});

/**
 * Emitted for all files in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of file statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('files', function (root, statsArray, next) {});

/**
 * Emitted for all directories in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of directory statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('directories', function (root, statsArray, next) {});

/**
 * Emitted for all symbolic links in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of symbolic link statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('symbolicLinks', function (root, statsArray, next) {});

/**
 * Emitted for all block devices in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of block device statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('blockDevices', function (root, statsArray, next) {});

/**
 * Emitted for all character devices in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of character device statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('characterDevices', function (root, statsArray, next) {});

/**
 * Emitted for all FIFO files in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of FIFO statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('FIFOs', function (root, statsArray, next) {});

/**
 * Emitted for all socket files in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of socket statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('sockets', function (root, statsArray, next) {});

Error Events

/**
 * Collection of all errors encountered in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} errorStatsArray - Array of error statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('errors', function (root, errorStatsArray, next) {});

/**
 * Error when fs.stat/lstat fails
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Statistics object with error property
 * @param {function} next - Callback to continue processing
 */
walker.on('nodeError', function (root, stat, next) {});

/**
 * Error when fs.readdir fails but stat succeeded
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Statistics object with error property
 * @param {function} next - Callback to continue processing
 */
walker.on('directoryError', function (root, stat, next) {});

Completion Event

/**
 * Emitted when walking is complete
 */
walker.on('end', function () {});

Types

/**
 * Configuration options for walk operations
 */
interface WalkOptions {
  /** Whether to follow symbolic links (default: false) */
  followLinks?: boolean;
  /** Array of directory names or regex patterns to filter out */
  filters?: (string | RegExp)[];
  /** Event listeners for synchronous walker operations */
  listeners?: WalkListeners;
}

/**
 * Event listeners for synchronous walker operations
 */
interface WalkListeners {
  names?: (root: string, nodeNamesArray: string[], next: () => void) => void;
  name?: (root: string, filename: string, next: () => void) => void;
  node?: (root: string, stat: WalkStat, next: () => void) => void;
  file?: (root: string, stat: WalkStat, next: () => void) => void;
  directory?: (root: string, stat: WalkStat, next: () => void) => void;
  symbolicLink?: (root: string, stat: WalkStat, next: () => void) => void;
  blockDevice?: (root: string, stat: WalkStat, next: () => void) => void;
  characterDevice?: (root: string, stat: WalkStat, next: () => void) => void;
  FIFO?: (root: string, stat: WalkStat, next: () => void) => void;
  socket?: (root: string, stat: WalkStat, next: () => void) => void;
  nodes?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  files?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  directories?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  symbolicLinks?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  blockDevices?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  characterDevices?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  FIFOs?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  sockets?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  errors?: (root: string, errorStatsArray: WalkStat[], next: () => void) => void;
  nodeError?: (root: string, stat: WalkStat, next: () => void) => void;
  directoryError?: (root: string, stat: WalkStat, next: () => void) => void;
  end?: () => void;
}

/**
 * Enhanced file statistics object extending Node.js fs.Stats
 */
interface WalkStat {
  /** The filename */
  name: string;
  /** File type ('file', 'directory', 'symbolicLink', etc.) */
  type: string;
  /** Error object if stat operation failed */
  error?: Error;
  
  // Standard fs.Stats properties
  /** Device ID */
  dev: number;
  /** File mode (permissions and file type) */
  mode: number;
  /** Number of hard links */
  nlink: number;
  /** User ID */
  uid: number;
  /** Group ID */
  gid: number;
  /** Device ID (if special file) */
  rdev: number;
  /** Block size for filesystem I/O */
  blksize: number;
  /** Inode number */
  ino: number;
  /** Total size in bytes */
  size: number;
  /** Number of 512-byte blocks allocated */
  blocks: number;
  /** Access time */
  atime: Date;
  /** Modification time */
  mtime: Date;
  /** Change time */
  ctime: Date;
  /** Birth time (creation time) */
  birthtime: Date;
}

/**
 * Walker instance extending EventEmitter
 */
interface Walker extends EventEmitter {
  /** Pauses the walker */
  pause(): void;
  /** Resumes a paused walker */
  resume(): void;
}