CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-walkdir

Directory traversal library that walks file system trees with multiple interface options including callback, event emitter, synchronous, and promise-based patterns.

Pending
Overview
Eval results
Files

async-operations.mddocs/

Promise-based Operations

Modern async/await compatible interface that returns promises for directory traversal operations.

Capabilities

Async Function

Walk directory tree and return a promise that resolves with all discovered paths.

/**
 * Walk directory tree and return promise of results
 * @param {string} path - Directory path to walk
 * @param {WalkOptions} [options] - Walk configuration options
 * @param {WalkEventListener} [eventListener] - Optional callback for each path found
 * @returns {Promise<string[]|Object<string,fs.Stats>>} - Promise resolving to paths array or stats object
 */
function walkdir.async(path, options, eventListener);

Promise Resolution:

  • Default: Resolves to string[] - Array of all discovered paths
  • With return_object: true: Resolves to {[path]: fs.Stats} - Object with paths as keys and stat objects as values
  • With no_return: true: Resolves to undefined after completion

Usage Examples:

const walkdir = require('walkdir');

// Basic async/await usage
async function listFiles() {
  try {
    const paths = await walkdir.async('./my-directory');
    console.log('Found', paths.length, 'items');
    return paths;
  } catch (error) {
    console.error('Failed to walk directory:', error);
  }
}

// Promise chain syntax
walkdir.async('./src')
  .then(paths => {
    const jsFiles = paths.filter(p => p.endsWith('.js'));
    console.log('JavaScript files:', jsFiles);
  })
  .catch(error => {
    console.error('Walk failed:', error);
  });

// With event listener callback
const paths = await walkdir.async('./project', (path, stat) => {
  if (stat.isFile() && stat.size > 1024 * 1024) {
    console.log('Large file found:', path);
  }
});

// Return object format
const stats = await walkdir.async('./project', { return_object: true });
for (const [path, stat] of Object.entries(stats)) {
  console.log(path, 'modified:', stat.mtime);
}

Async with Options

Configure async behavior with comprehensive options.

/**
 * Walk directory tree with specific options and return promise
 * @param {string} path - Directory path to walk
 * @param {WalkOptions} options - Configuration options
 * @param {WalkEventListener} [eventListener] - Optional callback for each path
 * @returns {Promise<string[]|Object<string,fs.Stats>|undefined>} - Promise resolving based on options
 */
function walkdir.async(path, options, eventListener);

Advanced Usage Examples:

// Depth-limited traversal
const shallowPaths = await walkdir.async('./deep-directory', {
  max_depth: 3
});

// Custom filtering with promise-based filter
const filteredPaths = await walkdir.async('./src', {
  filter: async (dir, files) => {
    // Async filter - could involve file system checks, database lookups, etc.
    const results = [];
    for (const file of files) {
      if (file.endsWith('.js') || file.endsWith('.ts')) {
        results.push(file);
      }
    }
    return results;
  }
});

// Memory-optimized async traversal
await walkdir.async('/var/log', { no_return: true }, (path, stat) => {
  // Process each path immediately without building result array
  if (stat.isFile() && path.endsWith('.log')) {
    console.log('Log file:', path, 'Size:', stat.size);
  }
});

// Follow symlinks
const allPaths = await walkdir.async('./project', {
  follow_symlinks: true,
  max_depth: 10  // Prevent infinite loops
});

// Custom fs implementation
const gracefulFs = require('graceful-fs');
const paths = await walkdir.async('./directory', {
  fs: gracefulFs  // Use graceful-fs for better error handling
});

Promise Error Handling

The async function provides detailed error handling through promise rejection.

/**
 * Promise rejection scenarios:
 * - Target directory doesn't exist or can't be accessed
 * - Permissions error on initial path
 * - Filter function throws an error
 * - Custom fs implementation throws an error
 */

Error Handling Examples:

try {
  const paths = await walkdir.async('./nonexistent');
} catch (error) {
  console.error('Directory access failed:', error.message);
  // Error includes details about the failing path
}

// Handle nested path failures gracefully
const paths = await walkdir.async('./mixed-permissions', (path, stat) => {
  console.log('Accessible path:', path);
});
// Note: nested permission errors don't cause promise rejection
// They're handled by emitting 'fail' events internally

// Monitor for nested failures with event listener
const emitter = walkdir('./mixed-permissions');
emitter.on('fail', (path, error) => {
  console.warn('Could not access:', path, error.message);
});

const paths = await walkdir.async('./mixed-permissions');

Combining with Event Listeners

The async function can be combined with event listeners for real-time processing.

async function processLargeDirectory() {
  let processedCount = 0;
  
  const paths = await walkdir.async('./huge-directory', (path, stat) => {
    processedCount++;
    if (processedCount % 1000 === 0) {
      console.log(`Processed ${processedCount} items so far...`);
    }
    
    // Real-time processing
    if (stat.isFile() && path.endsWith('.txt')) {
      // Process text files immediately
      processFile(path);
    }
  });
  
  console.log(`Completed! Total items: ${paths.length}`);
  return paths;
}

Integration Patterns

With Modern async/await

async function analyzeProject(projectPath) {
  const [allPaths, stats] = await Promise.all([
    walkdir.async(projectPath),
    walkdir.async(projectPath, { return_object: true })
  ]);
  
  return {
    totalFiles: allPaths.length,
    totalSize: Object.values(stats)
      .filter(stat => stat.isFile())
      .reduce((sum, stat) => sum + stat.size, 0),
    directories: Object.values(stats)
      .filter(stat => stat.isDirectory()).length
  };
}

Error Recovery Patterns

async function robustWalk(path, options = {}) {
  const maxRetries = 3;
  let attempt = 0;
  
  while (attempt < maxRetries) {
    try {
      return await walkdir.async(path, options);
    } catch (error) {
      attempt++;
      if (attempt >= maxRetries) throw error;
      
      console.warn(`Walk attempt ${attempt} failed, retrying...`);
      await new Promise(resolve => setTimeout(resolve, 1000));
    }
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-walkdir

docs

async-operations.md

core-walking.md

events-control.md

index.md

options-configuration.md

sync-operations.md

tile.json