Extremely high performant utility for building tools that read the file system, minimizing filesystem and path string munging operations to the greatest degree possible
npx @tessl/cli install tessl/npm-path-scurry@2.0.0path-scurry is a high-performance utility for building tools that read the file system, designed to minimize filesystem operations and path string manipulations. It provides intelligent caching mechanisms, cross-platform path handling, and multiple interfaces including streaming, async/await, and traditional callback patterns for maximum flexibility and performance.
npm install path-scurryimport { PathScurry, Path } from "path-scurry";For CommonJS:
const { PathScurry, Path } = require("path-scurry");Platform-specific imports:
import { PathScurryWin32, PathScurryPosix, PathScurryDarwin } from "path-scurry";
import { PathWin32, PathPosix } from "path-scurry";import { PathScurry } from "path-scurry";
// Create a path walker for the current directory
const pw = new PathScurry(process.cwd());
// Simple directory traversal
for await (const entry of pw) {
if (entry.isFile() && entry.name.endsWith(".js")) {
console.log(entry.fullpath());
}
}
// Path resolution with caching
const resolved = pw.resolve("./src/index.ts");
console.log(resolved); // Fully resolved absolute path
// Directory reading
const children = await pw.readdir("./src");
console.log(children.map(child => child.name));Path-scurry is built around several key components:
Core path resolution functionality with intelligent caching, supporting both relative and absolute paths across platforms.
class PathScurry {
constructor(cwd?: URL | string, opts?: PathScurryOpts);
resolve(...paths: string[]): string;
resolvePosix(...paths: string[]): string;
relative(entry?: PathBase | string): string;
relativePosix(entry?: PathBase | string): string;
basename(entry?: PathBase | string): string;
dirname(entry?: PathBase | string): string;
depth(path?: Path | string): number;
chdir(path: string | Path): void;
}
interface PathScurryOpts {
nocase?: boolean;
childrenCacheSize?: number;
fs?: FSOption;
}High-performance directory reading and traversal with caching and multiple output formats.
// Directory reading
readdir(): Promise<PathBase[]>;
readdir(opts: { withFileTypes: false }): Promise<string[]>;
readdir(entry: PathBase | string): Promise<PathBase[]>;
readdir(entry: PathBase | string, opts: { withFileTypes: false }): Promise<string[]>;
readdirSync(): PathBase[];
readdirSync(opts: { withFileTypes: false }): string[];
readdirSync(entry: PathBase | string): PathBase[];
readdirSync(entry: PathBase | string, opts: { withFileTypes: false }): string[];Cached filesystem metadata operations including lstat, readlink, and realpath with error handling.
lstat(entry?: string | PathBase): Promise<PathBase | undefined>;
lstatSync(entry?: string | PathBase): PathBase | undefined;
readlink(entry?: string | PathBase): Promise<string | undefined>;
readlink(entry: string | PathBase, opt: { withFileTypes: true }): Promise<PathBase | undefined>;
readlinkSync(entry?: string | PathBase): string | undefined;
readlinkSync(entry: string | PathBase, opt: { withFileTypes: true }): PathBase | undefined;
realpath(entry?: string | PathBase): Promise<string | undefined>;
realpath(entry: string | PathBase, opt: { withFileTypes: true }): Promise<PathBase | undefined>;
realpathSync(entry?: string | PathBase): string | undefined;
realpathSync(entry: string | PathBase, opt: { withFileTypes: true }): PathBase | undefined;Multiple interfaces for directory tree traversal including async/await, streaming, and synchronous options with filtering and symlink following.
// Async array-based walking
walk(): Promise<PathBase[]>;
walk(opts: WalkOptions): Promise<PathBase[] | string[]>;
walk(entry: string | PathBase, opts?: WalkOptions): Promise<PathBase[] | string[]>;
walkSync(): PathBase[];
walkSync(opts: WalkOptions): PathBase[] | string[];
walkSync(entry: string | PathBase, opts?: WalkOptions): PathBase[] | string[];
// Streaming interfaces
stream(): Minipass<PathBase>;
stream(opts: WalkOptions): Minipass<PathBase | string>;
streamSync(): Minipass<PathBase>;
// Async iteration
iterate(): AsyncGenerator<PathBase, void, void>;
iterate(opts: WalkOptions): AsyncGenerator<PathBase | string, void, void>;
iterateSync(): Generator<PathBase, void, void>;
interface WalkOptions {
withFileTypes?: boolean;
follow?: boolean;
filter?: (entry: PathBase) => boolean;
walkFilter?: (entry: PathBase) => boolean;
}Individual filesystem entry objects with lazy-loaded metadata, type checking, and path manipulation methods.
abstract class PathBase implements Dirent {
name: string;
isCWD: boolean;
readonly parentPath: string;
readonly path: string; // deprecated
// Path navigation
resolve(path?: string): PathBase;
relative(): string;
relativePosix(): string;
fullpath(): string;
fullpathPosix(): string;
depth(): number;
// Type checking
isFile(): boolean;
isDirectory(): boolean;
isSymbolicLink(): boolean;
isUnknown(): boolean;
isType(type: Type): boolean;
getType(): Type;
isNamed(name: string): boolean;
// Filesystem operations
readdir(): Promise<PathBase[]>;
readdirSync(): PathBase[];
lstat(): Promise<PathBase | undefined>;
lstatSync(): PathBase | undefined;
readlink(): Promise<PathBase | undefined>;
readlinkSync(): PathBase | undefined;
realpath(): Promise<PathBase | undefined>;
realpathSync(): PathBase | undefined;
}
type Type = 'Unknown' | 'FIFO' | 'CharacterDevice' | 'Directory' |
'BlockDevice' | 'File' | 'SymbolicLink' | 'Socket';type Path = PathBase | InstanceType<typeof Path>;
type PathScurry = PathScurryBase | InstanceType<typeof PathScurry>;
// Internal types also exported
type Children = PathBase[] & { provisional: number };
interface PathOpts {
fullpath?: string;
relative?: string;
relativePosix?: string;
parent?: PathBase;
fs?: FSOption;
}
interface FSOption {
lstatSync?: (path: string) => Stats;
readdir?: (path: string, options: { withFileTypes: true },
cb: (er: NodeJS.ErrnoException | null, entries?: Dirent[]) => any) => void;
readdirSync?: (path: string, options: { withFileTypes: true }) => Dirent[];
readlinkSync?: (path: string) => string;
realpathSync?: (path: string) => string;
promises?: {
lstat?: (path: string) => Promise<Stats>;
readdir?: (path: string, options: { withFileTypes: true }) => Promise<Dirent[]>;
readlink?: (path: string) => Promise<string>;
realpath?: (path: string) => Promise<string>;
};
}
// Internal cache classes (exported but advanced usage)
class ResolveCache extends LRUCache<string, string> {
constructor();
}
class ChildrenCache extends LRUCache<PathBase, Children> {
constructor(maxSize?: number);
}