Buckets:
| import { lstat, mkdir, readdir, rm, symlink } from "fs/promises" | |
| import { join, relative } from "path" | |
| type Entry = { | |
| dir: string | |
| version: string | |
| } | |
| async function isDirectory(path: string) { | |
| try { | |
| const info = await lstat(path) | |
| return info.isDirectory() | |
| } catch { | |
| return false | |
| } | |
| } | |
| const isValidSemver = (v: string) => Bun.semver.satisfies(v, "x.x.x") | |
| const root = process.cwd() | |
| const bunRoot = join(root, "node_modules/.bun") | |
| const linkRoot = join(bunRoot, "node_modules") | |
| const directories = (await readdir(bunRoot)).sort() | |
| const versions = new Map<string, Entry[]>() | |
| for (const entry of directories) { | |
| const full = join(bunRoot, entry) | |
| if (!(await isDirectory(full))) { | |
| continue | |
| } | |
| const parsed = parseEntry(entry) | |
| if (!parsed) { | |
| continue | |
| } | |
| const list = versions.get(parsed.name) ?? [] | |
| list.push({ dir: full, version: parsed.version }) | |
| versions.set(parsed.name, list) | |
| } | |
| const selections = new Map<string, Entry>() | |
| for (const [slug, list] of versions) { | |
| list.sort((a, b) => { | |
| const aValid = isValidSemver(a.version) | |
| const bValid = isValidSemver(b.version) | |
| if (aValid && bValid) return -Bun.semver.order(a.version, b.version) | |
| if (aValid) return -1 | |
| if (bValid) return 1 | |
| return b.version.localeCompare(a.version) | |
| }) | |
| const first = list[0] | |
| if (first) selections.set(slug, first) | |
| } | |
| await rm(linkRoot, { recursive: true, force: true }) | |
| await mkdir(linkRoot, { recursive: true }) | |
| const rewrites: string[] = [] | |
| for (const [slug, entry] of Array.from(selections.entries()).sort((a, b) => a[0].localeCompare(b[0]))) { | |
| const parts = slug.split("/") | |
| const leaf = parts.pop() | |
| if (!leaf) { | |
| continue | |
| } | |
| const parent = join(linkRoot, ...parts) | |
| await mkdir(parent, { recursive: true }) | |
| const linkPath = join(parent, leaf) | |
| const desired = join(entry.dir, "node_modules", slug) | |
| if (!(await isDirectory(desired))) { | |
| continue | |
| } | |
| const relativeTarget = relative(parent, desired) | |
| const resolved = relativeTarget.length === 0 ? "." : relativeTarget | |
| await rm(linkPath, { recursive: true, force: true }) | |
| await symlink(resolved, linkPath) | |
| rewrites.push(slug + " -> " + resolved) | |
| } | |
| rewrites.sort() | |
| console.log("[canonicalize-node-modules] rebuilt", rewrites.length, "links") | |
| for (const line of rewrites.slice(0, 20)) { | |
| console.log(" ", line) | |
| } | |
| if (rewrites.length > 20) { | |
| console.log(" ...") | |
| } | |
| function parseEntry(label: string) { | |
| const marker = label.startsWith("@") ? label.indexOf("@", 1) : label.indexOf("@") | |
| if (marker <= 0) { | |
| return null | |
| } | |
| const name = label.slice(0, marker).replace(/\+/g, "/") | |
| const version = label.slice(marker + 1) | |
| if (!name || !version) { | |
| return null | |
| } | |
| return { name, version } | |
| } | |
Xet Storage Details
- Size:
- 2.74 kB
- Xet hash:
- dee14a12257266ec131e3905c88275bec06b2025abb37934c1d45dfdfc311990
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.