Functions

f
handleWatchEvent(
config: Config,
extensions: string[],
event: string,
filePath: string,
onEventFunc: (
event: string,
file: string
) => unknown
,
onFinishFunc: ((
path: string,
event: string
) => void) | null | undefined
): Promise<void>

Routes a file-system event to fsTree mutation and optional rebuild trigger. unlinkDir bypasses the extension filter so deleted directories always clean up fsTree. When a build is already in progress, queues the event as a pending trigger (last-write-wins).

f
mutateFSTree(
fsTree: FSTree,
event: string,
filePath: string
): void

Mutates fsTree in place based on a file-system event.

f
readFileStable(
filePath: string,
read?: (p: string) => Promise<Buffer>
): Promise<Buffer>

Reads a file, re-reading until two reads spaced STABILITY_GAP_MS apart return byte-identical content — so a file caught mid-write (Windows truncate→flush; see STABILITY_GAP_MS) is hashed only once its bytes have settled. Bounded by MAX_STABILITY_ATTEMPTS; returns the latest content if it never stabilizes. read is injectable for tests; production reads from disk. Read errors propagate so the caller's catch can treat a vanished file as a removal.

f
rescanDirectoryForDelta(
watchPath: string,
config: Config,
extensions: string[],
onEventFunc: (
event: string,
file: string
) => unknown
,
onFinishFunc: ((
path: string,
event: string
) => void) | null | undefined
,
trackSymlinkFn?: (filePath: string) => void,
deps?: RescanDeps
): Promise<void>

Scans watchPath recursively and fires add / change / unlink events for any delta between the directory contents and config.fsTree. Used as a 1 s safety-net poll on macOS where FSEvents can drop events under load — additions and removals are recovered from the directory listing, and modifications are recovered by re-stat'ing every tracked file and firing change whenever its mtime is newer than config.state.watch.lastBuildEndMs (the moment the last build saw the file). The seed for that baseline is set in setup.

f
setup(
testFileLookupPaths: string[],
config: Config,
onEventFunc: (
event: string,
file: string
) => unknown
,
onFinishFunc: ((
path: string,
event: string
) => void) | null | undefined
): { fileWatchers: Record<string, FSWatcher>; killFileWatchers: () => Record<string, FSWatcher>; ready: Promise<void>; }

Starts fs.watch watchers for each lookup path and calls onEventFunc on JS/TS file changes, debounced via a per-file timestamp. Also watches each path's parent directory to detect when a watched directory is renamed or deleted (since fs.watch tracks by inode, not path). Uses config.fsTree to distinguish unlink (tracked file) from unlinkDir (directory) on deletion.

f
toWatchableRoot(lookupPath: string): string

Maps a lookup path to a path fs.watch can actually watch. A real file or directory is returned as-is; a glob is walked up to the deepest ancestor directory that exists — its base dir — which fs.watch can watch recursively (test/x/!(plugin).ts collapses to test/x).

Interfaces

I
RescanDeps

The fs calls rescanDirectoryForDelta makes — injectable so a platform-specific readdir/stat disagreement can be reproduced deterministically. Production uses the real fs.

  • readdir: readdir

    Lists the directory tree. Its dirent types are unreliable on Windows — see isMissing.

  • stat: stat

    Resolves a path (follows symlinks). Used to drop entries that are genuinely gone.