Improve performance of symlinking
Right now symlinking includes a lot of intensive file operations:
https://github.com/boltpkg/bolt/blob/d2ca298ed057b4b9c2f05fe4e6d45f645ddc04e2/src/utils/fs.js#L48-L109
Basically every single symlink() we create we do the following operations:
await mkdirp(dest)
await lstat(dest)
await rimraf(dest)
await symlink(dest, target)
This is terrible for performance, with 500 Bolt packages needing just 10 symlinks each we have 5,000 symlinks which turns into 20,000 file operations not including the overhead of Node/libuv and internal operations of mkdirp/rimraf/etc
As part of running the install process we aggregate all of the symlinks we need to create, so I think we could make this much more optimized by manually writing out only the operations we need.
We might be able to optimize it even more by doing readdir()'s with withFileTypes and either assuming the symlinks are good or using readlink() to verify them cheaply
Sweet. Just so I understand the idea here is to only link files that aren't already there essentially?
One other thing we could consider, we currently symlink all root bin files into all packages. I think the idea was to go back and only do the ones that were required? This might be a little problematic (or maybe good depending on how you look at it) as it'll probably show a lot of places that we use binaries without declaring their dev deps...
Technically the symlinks we're adding in Bolt are 100% unnecessary, I only wanted them for the potential future of having a .bolt directory with virtual installs. But I'm not sure we're going to go down that route anymore.