-
Notifications
You must be signed in to change notification settings - Fork 5
Description
Summary
The current deleteModules() function in src/scanner.ts:415-451 processes deletions sequentially — it spawns a new rm -rf process for each directory one at a time. For users with hundreds of node_modules directories, this is a bottleneck.
Current Implementation
// src/scanner.ts:424-442
for (const mod of modules) {
try {
const proc = Bun.spawn({
cmd: ["rm", "-rf", mod.path],
stdout: "ignore",
stderr: "ignore",
});
const ok = await proc.exited === 0;
// ...
}
}Each deletion waits for the previous one to finish before starting the next. With 265 node_modules directories, the overhead of spawning 265 separate processes sequentially adds up.
Proposed Improvements
1. Parallel deletions with concurrency limit
Use a semaphore (like the existing Semaphore class in the same file) to run multiple deletions in parallel:
const semaphore = new Semaphore(8); // configurable concurrency
await Promise.allSettled(modules.map(async (mod) => {
await semaphore.acquire();
try {
// delete mod.path
} finally {
semaphore.release();
}
}));2. Use native fs.rm instead of spawning rm -rf
Spawning a shell process per directory has significant overhead. Using fs.promises.rm() (or Bun native) avoids process creation:
import { rm } from "node:fs/promises";
await rm(mod.path, { recursive: true, force: true });This is cross-platform (fixes Windows too) and avoids process spawn overhead.
3. Batch deletions
For very large deletion sets, consider batching progress updates to reduce UI re-renders.
Expected Impact
- Sequential
rm -rf: ~265 process spawns, one at a time - Concurrent
fs.rm: No process overhead, parallel I/O, dramatically faster - Rough estimate: 2-10x speedup depending on filesystem and number of directories
Acceptance Criteria
- Deletions run concurrently with a configurable concurrency limit
- Replace
rm -rfspawn withfs.promises.rm()(cross-platform bonus) - Progress feedback during deletion (shows current/deleted count)
- Error handling per-directory (one failure does not stop others)
- Benchmark: deletion time for 100+ directories is measurably faster
- All existing functionality preserved (dry-run, interactive delete, delete-all)