registryView
uses node:child_process
<package manager> view <args>, asked again (twice, a moment apart, then longer) when it fails other than by the
package or version not being there: a registry that didn't answer once (a timeout, a dropped connection) isn't a
package that doesn't exist. view and pause are for tests.
import { packageManager } from "#codebase/tcmts/loader/packages"; import type { Viewed } from "#codebase/tcmts/loader/packages"; import { spawnSync } from "node:child_process"; export function registryView( args: string[], view: (args: string[]) => Viewed = (a) => spawnSync(packageManager(), ["view", ...a], { encoding: "utf8" }), pause: (ms: number) => void = (ms) => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms), ): Viewed { let r = view(args); for (const ms of [500, 3000]) { if (r.status === 0 || /404|not found|no such package/i.test(r.stderr)) return r; pause(ms); r = view(args); } return r; }