Files
pnpm/pnpm11/resolving/npm-resolver/test/pickVersionFallback.test.ts
b065ea3eb7 perf(resolver): adopt the indexed pnpm-meta-v1 metadata mirror with lazy version hydration (#13512)
The metadata mirror stored one JSON document per package, so every
resolution parsed every version manifest of every packument it touched:
178MB of JSON for the 1246-package benchmark fixture, of which ~1% (the
picked versions) was ever read. loadMeta was 23% of resolution CPU after
pnpm/pnpm#13504.

The Rust CLI already shipped an indexed mirror layout (headers record,
index record with per-version byte spans, concatenated raw version
fragments); the TypeScript CLI treated those mirrors as cache misses,
so the two stacks thrashed a shared cache. Both CLIs now read and write
the same layout under the format id pnpm-meta-v1, and the metadata
cache directories move from v11 to v12 so a pnpm version that predates
the layout never opens the files at all. The offline legacy-mirror hint
now looks under v11, and pnpm cache prune removes the v11 roots. NDJSON
remains the layout for filterMetadata documents and is still read as a
fallback.

Loading an indexed mirror parses only the two leading records and
builds versions as enumerable parse-once getters over byte spans, so a
manifest keeps one identity across filtered views and hook mutations.
Corruption is treated like an unreadable mirror in both stacks: a
fragment that does not parse throws a typed error, offline resolution
fails with NO_OFFLINE_META, the disk fast paths fall through to the
network (only for errors attributable to the disk copy), and a 304 over
a damaged file escalates to a cache-bypassing refetch that rewrites the
mirror — otherwise the intact etag would keep 304-validating a poisoned
file forever. The declared headers length is bounded, the encoded
mirror form is memoized per fetch result so workspace projects sharing
one in-flight fetch do not each serialize a copy, and cache view reads
through the shared loader in both CLIs.

Resolution of the 1246-package fixture is 16% faster on a warm mirror
(3.82s -> 3.21s, interleaved paired runs, offline); the resulting
lockfile is byte-identical across old-format, new-format, and
mixed-format configurations.

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:49:33 +02:00

62 lines
2.2 KiB
TypeScript

import { expect, test } from '@jest/globals'
import type { PackageInRegistry, PackageMeta } from '@pnpm/resolving.registry.types'
import { pickVersionByVersionRange } from '../src/pickPackageFromMeta.js'
// Builds a meta whose versions hydrate through getters, like a lazily-loaded
// indexed mirror does, recording which versions were hydrated. A null manifest
// input models a version key the document lists without a manifest.
function lazyMeta (manifests: Record<string, PackageInRegistry | null>): { meta: PackageMeta, hydrated: string[] } {
const hydrated: string[] = []
const versions: PackageMeta['versions'] = Object.create(null)
for (const [version, manifest] of Object.entries(manifests)) {
Object.defineProperty(versions, version, {
enumerable: true,
configurable: true,
get (): PackageInRegistry | undefined {
hydrated.push(version)
return manifest ?? undefined
},
})
}
return {
meta: { name: 'foo', 'dist-tags': {}, versions },
hydrated,
}
}
function manifest (version: string, deprecated?: string): PackageInRegistry {
return { name: 'foo', version, deprecated } as PackageInRegistry
}
test('the deprecated fallback hydrates only versions that satisfy the range', () => {
const { meta, hydrated } = lazyMeta({
'1.0.0': manifest('1.0.0'),
'2.0.0': manifest('2.0.0'),
'2.0.1': manifest('2.0.1', 'use 3.x'),
})
expect(pickVersionByVersionRange({ meta, versionRange: '^2.0.0' })).toBe('2.0.0')
expect(hydrated).not.toContain('1.0.0')
})
test('a missing manifest on the max satisfying version fails the pick instead of crashing', () => {
const { meta } = lazyMeta({
'1.0.0': manifest('1.0.0'),
'2.0.0': null,
})
// The version is still chosen (the picker's missing-manifest handling turns
// it into a failed pick downstream); the deprecated check must not crash.
expect(pickVersionByVersionRange({ meta, versionRange: '>=1.0.0' })).toBe('2.0.0')
})
test('a missing manifest is not offered as the non-deprecated alternative', () => {
const { meta } = lazyMeta({
'2.0.0': null,
'2.0.1': manifest('2.0.1', 'use 3.x'),
})
expect(pickVersionByVersionRange({ meta, versionRange: '^2.0.0' })).toBe('2.0.1')
})