···11+import * as semver from 'semver';
22+33+import type { Registry } from '../lib/package-name';
44+55+import { fetchPackument } from './lib/registry';
66+import { pickVersion } from './lib/resolve';
77+import type { AbbreviatedManifest } from './lib/types';
88+99+/**
1010+ * resolved packument-level metadata for a package.
1111+ * fetched on the main thread so the package header (with a version switcher)
1212+ * can render before the bundler worker is spawned. keyed on registry + name
1313+ * only — version selection happens separately so switching versions doesn't
1414+ * refetch the packument or remount the header.
1515+ */
1616+export interface PackageManifest {
1717+ registry: Registry;
1818+ name: string;
1919+ versions: Record<string, AbbreviatedManifest>;
2020+ distTags: Record<string, string>;
2121+ /** all available versions, sorted newest first */
2222+ availableVersions: string[];
2323+}
2424+2525+/**
2626+ * fetches the packument for a package. the browser's http cache handles
2727+ * deduping with the worker's own packument fetch during dependency resolution.
2828+ */
2929+export async function fetchPackageManifest(registry: Registry, name: string): Promise<PackageManifest> {
3030+ const packument = await fetchPackument(name, registry);
3131+ const availableVersions = Object.keys(packument.versions).toSorted(semver.rcompare);
3232+3333+ return {
3434+ registry,
3535+ name,
3636+ versions: packument.versions,
3737+ distTags: packument['dist-tags'],
3838+ availableVersions,
3939+ };
4040+}
4141+4242+/**
4343+ * resolves a range against a package manifest, returning the matching version string.
4444+ */
4545+export function pickPackageVersion(manifest: PackageManifest, range: string): string | undefined {
4646+ return pickVersion(manifest.versions, manifest.distTags, range)?.version;
4747+}