empathic

repository·main·Indexed 18 days ago

https://github.com/lukeed/empathic

A set of small and fast Node.js utilities for pathing needs, including finding configuration files, resolving package locations, and walking directory trees. It provides specialized submodules: empathic/access for permission checks, empathic/find for upward directory searches, empathic/package for package.json and cache directory management, empathic/resolve for module path resolution, and empathic/walk for collecting parent directories.

Tokens
4.1K
Snippets
15
Records
23
Agent score
62%

What's inside empathic

  1. Overview of empathic submodules

    main

    Empathic is organized into specialized submodules, each focusing on a specific pathing task:

    • empathic/access: Shortcuts for checking file access and permissions (based on fs.accessSync).
    • empathic/find: Utilities to find files or directories by walking up the parent directory tree.
    • empathic/package: Helpers for interacting with package.json files and node_modules packages.
    • empathic/resolve: Resolves absolute paths to package identifiers, relative paths, file URLs, or from other root directories.
    • empathic/walk: Collects all parent directories of a target, configurable via cwd and last options.
  2. Run benchmarks locally

    main

    To run the project's benchmarks, you must have Deno installed. Use the following commands to set up fixtures and execute the benchmark suite:

    1. Create fixtures (replace <number of files per directory> with your desired count):
      deno task fixtures <number of files per directory>
    2. Run the benchmarks:
      deno bench -RES

    Benchmark results are also available in the GitHub Actions CI pipeline, which runs all benchmarks on every push and tag.

    $ deno task fixtures <number of files per directory>
    $ deno bench -RES
  3. Basic usage of empathic utilities

    main

    Empathic provides submodules for finding files, locating package.json files, and managing cache directories. You can use the cwd option to specify the starting directory for these operations.

    Common patterns include:

    • Using empathic/find to search upwards for a specific filename.
    • Using empathic/package to find the nearest package.json or to resolve a cache directory within node_modules/.cache.
    import { resolve } from 'node:path';
    import * as find from 'empathic/find';
    import * as pkg from 'empathic/package';
    
    // Assumed example structure:
    let cwd = resolve('path/to/acme/websites/dashboard');
    
    // Find closest "foobar.config.js" file
    let file = find.up('foobar.config.js', { cwd });
    //=> "/.../path/to/acme/foobar.config.js"
    
    // Find closest "package.json" file
    let pkgfile = pkg.up({ cwd });
    //=> "/.../path/to/acme/package.json"
    
    // Construct (optionally create) "foobar" cache dir
    let cache = pkg.cache('foobar', { cwd, create: true });
    //=> "/.../path/to/acme/node_modules/.cache/foobar"
  4. Performance of find.any

    main
    The find.any method is designed to look for any of the targets listed in N parent directories. Benchmarks indicate that empathic/find.any (sync) is generally faster than locate-path and significantly faster than find-up or escalade when searching through multiple parent directories.
  5. Performance of `resolve.cwd`

    main
    The resolve.cwd method, which emulates require.resolve from the current working directory, is highly performant. In benchmarks, empathic/resolve.cwd averaged approximately 32.2 µs per iteration, making it roughly 1.14x faster than the resolve-cwd package.
  6. Performance of find.up

    main
    The find.up method is designed to look for one specific target in N parent directories. Benchmarks show that empathic/find.up (sync) significantly outperforms alternatives like find-up, find-up-simple, and escalade across various directory depths (6, 10, and 15+ parent directories).
  7. Performance of `walk.up`

    main
    The walk.up method is highly optimized for traversing up a directory tree. In benchmarks, empathic/walk.up averaged approximately 8.0 µs per iteration, achieving a throughput of roughly 125,300 iterations per second.
  8. Performance of `resolve.from`

    main
    The resolve.from method, which emulates require.resolve from a specific starting directory, is highly performant. In benchmarks, empathic/resolve.from averaged approximately 27.7 µs per iteration, making it roughly 1.33x faster than the resolve-from package.
  9. Performance of package.up

    main

    The package.up method is used for two primary tasks:

    1. Find the nearest package.json file: empathic/package.up (sync) is benchmarked as being significantly faster than package-up and pkg-up.
    2. Get the directory path of the closest package.json file: empathic/package.up (sync) is benchmarked as being significantly faster than pkg-dir and pkg-dir (sync).

    Note: empathic/package.up passes its output to path.dirname() for equality comparison.

  10. Resolve module paths with from()

    main

    The from() function emulates Node.js require.resolve behavior to find the path of a module identifier starting from a specific root directory.

    • root: A string path or a URL.
    • ident: The module identifier (e.g., 'lodash', './local-file').
    • silent: A boolean option. If true, the function returns undefined if the module cannot be resolved. If false (or omitted), it throws an error if resolution fails.
    import { from } from 'empathic/resolve';
    
    // Resolve a module from a specific directory
    const path = from('/path/to/project', 'my-module');
    
    // Resolve silently (returns undefined if not found)
    const silentPath = from('/path/to/project', 'non-existent', true);
    
    // Resolve from a URL
    const urlPath = from(new URL('file:///app/'), 'lodash');