feat(pacquet/resolving-npm-resolver): port abbreviated metadata fast path#11794
Conversation
…path Default the resolver-time fetch to the abbreviated install-v1 packument (`application/vnd.npm.install-v1+json`) and only request full metadata when the call explicitly needs it. Mirrors pnpm's `fullMetadata = opts.optional || ctx.fullMetadata` derivation in [pickPackage.ts L201](https://github.com/pnpm/pnpm/blob/2a9bd897bf/resolving/npm-resolver/src/pickPackage.ts#L201). - Adds `full_metadata` to the cached/non-cached fetchers and routes the Accept header + mirror dir (`ABBREVIATED_META_DIR` vs `FULL_META_DIR`) off it. - `PickPackageContext.full_metadata` is the install-wide bias; `PickPackageOptions.optional` forces full per-call (#9950). In-memory cache key gains a `:full` suffix when full so the two modes can coexist without contamination. - Ports `maybeUpgradeAbbreviatedMetaForReleaseAge`: when `published_by` is active, the picker ends up with an abbreviated packument that lacks per-version `time`, and the package's top-level `modified` falls past the cutoff, the orchestrator re-fetches full metadata so the maturity check runs on real timestamps. The upgraded full meta is persisted back to the abbreviated mirror so the next install skips the upgrade fetch. - Verifier and resolver pass the appropriate flag explicitly (`true` for the verifier, `false` for the resolver and named registry resolver). Tests cover the abbreviated default, the optional override, the cache-key separation, the boundary case `modified == cutoff`, and the upgrade trigger when `modified > cutoff`. --- Written by an agent (Claude Code, claude-opus-4-7).
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (15)
📝 WalkthroughWalkthroughThis PR implements full vs. abbreviated npm packument metadata selection throughout the resolution stack. Resolvers now default to abbreviated metadata but can upgrade to full metadata per-call when needed (e.g., for optional dependencies or maturity filtering), with automatic upgrade logic when abbreviated metadata lacks per-version timestamps. ChangesFull vs. Abbreviated Packument Metadata Selection
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
Suggested labels
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Micro-Benchmark ResultsLinux |
…a intra-doc link `fetch_full_metadata` is both a function and a module, so the bare `[fetch_full_metadata]` link triggers `rustdoc::broken_intra_doc_links` under `--deny warnings`. Add parentheses so it resolves to the function. --- Written by an agent (Claude Code, claude-opus-4-7).
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #11794 +/- ##
==========================================
+ Coverage 87.20% 87.21% +0.01%
==========================================
Files 190 193 +3
Lines 22525 22745 +220
==========================================
+ Hits 19642 19837 +195
- Misses 2883 2908 +25 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Integrated-Benchmark Report (Linux)Scenario: Frozen Lockfile
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 2.5114722401200007,
"stddev": 0.09922436863299834,
"median": 2.51435993732,
"user": 2.7726585399999997,
"system": 3.7823095,
"min": 2.35164001832,
"max": 2.70825047732,
"times": [
2.53539317032,
2.48113460832,
2.5804553873200002,
2.70825047732,
2.56307147432,
2.52532752932,
2.50339234532,
2.35164001832,
2.4708671193200002,
2.39519027132
]
},
{
"command": "pacquet@main",
"mean": 2.41694094312,
"stddev": 0.087946634574729,
"median": 2.36510078982,
"user": 2.80432894,
"system": 3.7189978000000004,
"min": 2.3253760313200003,
"max": 2.54025872332,
"times": [
2.35629283832,
2.3253760313200003,
2.37234943732,
2.3420560203200003,
2.54025872332,
2.53494301932,
2.35785214232,
2.45783668232,
2.52630498332,
2.3561395533200002
]
},
{
"command": "pnpm",
"mean": 4.87898504812,
"stddev": 0.08342204992821828,
"median": 4.86118812032,
"user": 8.302601039999999,
"system": 4.2356356,
"min": 4.76724645732,
"max": 5.01118736732,
"times": [
4.92640410232,
4.83139105332,
4.77957710032,
4.83877100432,
4.88360523632,
4.93452690732,
4.831757677320001,
4.76724645732,
4.98538357532,
5.01118736732
]
}
]
}Scenario: Frozen Lockfile (Hot Cache)
BENCHMARK_REPORT.json{
"results": [
{
"command": "pacquet@HEAD",
"mean": 0.68030974682,
"stddev": 0.0190958721363392,
"median": 0.67510885582,
"user": 0.38464622000000004,
"system": 1.56064372,
"min": 0.66688203682,
"max": 0.73333308582,
"times": [
0.73333308582,
0.67848867182,
0.67512061982,
0.6719791458200001,
0.67411647982,
0.67784498782,
0.68081557982,
0.66941976882,
0.66688203682,
0.67509709182
]
},
{
"command": "pacquet@main",
"mean": 0.7216909539199999,
"stddev": 0.05748444012501744,
"median": 0.69359617782,
"user": 0.40327751999999994,
"system": 1.5740221200000002,
"min": 0.68703620182,
"max": 0.86997046782,
"times": [
0.86997046782,
0.69555754682,
0.69120849982,
0.69023980982,
0.7217799808200001,
0.71387665682,
0.6916348088200001,
0.68964573782,
0.76595982882,
0.68703620182
]
},
{
"command": "pnpm",
"mean": 2.5897434523199996,
"stddev": 0.08257935042297507,
"median": 2.56276864582,
"user": 3.2852317199999996,
"system": 2.24980022,
"min": 2.49479246082,
"max": 2.70614046282,
"times": [
2.69370965982,
2.56235973682,
2.70614046282,
2.64959589182,
2.53290100582,
2.49479246082,
2.5631775548199998,
2.51156404382,
2.50909433282,
2.67409937382
]
}
]
} |
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
Summary
Default the resolver-time fetch to the abbreviated install-v1 packument (
application/vnd.npm.install-v1+json) and only request full metadata when the call explicitly needs it — mirrors pnpm'sfullMetadata = opts.optional || ctx.fullMetadataderivation in pickPackage.ts L201.Pacquet previously always requested full metadata; the picker module documented this as a known simplification. After this PR pacquet matches pnpm's two-tier metadata flow.
What changed
fetch_full_metadata.rs,fetch_full_metadata_cached.rs): added afull_metadata: boolfield. Selects betweenAccept: application/json; q=1.0, */*(full) andapplication/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*(abbreviated). The cached variant also routes the on-disk mirror toFULL_META_DIRvsABBREVIATED_META_DIR.PickPackageContext.full_metadatais the install-wide bias;PickPackageOptions.optionalis the per-call override that forces full (needed forlibc/cpu/osfields on optional deps — pnpm/pnpm#9950). In-memory cache key gains a:fullsuffix when full, so the two modes can coexist without contamination.maybe_upgrade_abbreviated_meta_for_release_ageports pnpm'smaybeUpgradeAbbreviatedMetaForReleaseAge. Whenpublished_byis active, the picker has abbreviated metadata that lacks per-versiontime, and the package's top-levelmodifiedfalls past the cutoff, the orchestrator re-fetches full metadata so theminimumReleaseAgecheck runs on real timestamps instead of degrading to the warn-and-skip fallback. The upgraded full meta is persisted back to the abbreviated mirror so the next install skips the upgrade fetch — matches upstream'spersistUpgradedMeta.NpmResolverandNamedRegistryResolvergainfull_metadata(defaulted tofalse) and plumbwanted_dependency.optionalinto the picker. The verifier setsfull_metadata: trueexplicitly.persist_meta_to_mirrortakes ameta_dirparameter so tests can seed either cache.Test plan
pick_package/tests.rs: abbreviated default, optional override forces full, cache-key separation between modes, upgrade triggers whenmodified > cutoff, upgrade skipped whenmodified == cutoff(boundary).cargo nextest run --workspace).cargo fmt --checkclean.cargo clippy --workspace --all-targets -- --deny warningsclean.Written by an agent (Claude Code, claude-opus-4-7).
Summary by CodeRabbit
Release Notes