Skip to content

install: do not download tarballs that the installers never place - #43122

Merged
Jarred-Sumner merged 3 commits into
mainfrom
robobun/ea5bbcc1/skip-bundled-dep-prefetch
Sep 17, 2026
Merged

Jarred-Sumner merged 3 commits into
mainfrom
robobun/ea5bbcc1/skip-bundled-dep-prefetch

Conversation

@robobun

@robobun robobun commented Sep 17, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

  • A fresh resolve (bun install with no lockfile, bun add) downloads the tarball of every registry package it resolves. The installers place nothing below a dependency that they filter. That is a bundled dependency, a package for another platform, or a group that --production or --omit turns off. bun install of npm@10.9.2 downloads 196 tarballs to place 1 package.
  • The cause is get_or_put_resolved_package_with_find_result (src/install/PackageManager/PackageManagerEnqueue.rs:2438). It creates the tarball task for the first dependency that resolves a package, whatever that dependency is.

Fix

  • A package first resolved through a filtered dependency, or below one, gets no tarball task. A bitset in Lockfile.scratch records the dependencies below. Behavior::is_placed is the test Tree.rs already made, now shared.
  • Correct because the install phase downloads every cache miss, as it does for a lockfile install. A placed dependency that resolves to the same package takes that path. The runtime auto-install has no install phase and keeps every download.
  • Verified: test/cli/install/bun-install-registry.test.ts (23 new tests, 20 fail without the fix). Also 16 more install suites, see Notes.
  • Self-reviewed: 6 concerns raised, 4 addressed. bun update and --dry-run are left out, see Notes.

Background

  • bundleDependencies names dependencies that a package ships inside its own tarball. bun still resolves them and records them in the lockfile.
  • Both installers skip a filtered dependency and everything below it (is_filtered_dependency_or_workspace, src/install/lockfile/Tree.rs).
  • The prefetch is a latency optimisation. The resolve phase starts downloads before the install phase needs them.
Notes

Issue #27418 stays open. This PR does not change it: bun still fetches the manifest of a bundled dependency, so a bundled dependency that the registry does not have still fails the install. Only tarball downloads change.

Numbers. Release builds of main (b64b630) and of this branch, cold cache, no lockfile, real registry, 10 interleaved runs each (20 for bun-lambda). node_modules is identical between the two builds in every run. bun-lambda's lockfile already varies from run to run on main (3 distinct lockfiles in 20 runs for each build).

project tarballs cache wall, median (min)
npm@10.9.2 196 → 1 48.8 → 24.8 MB 528 (479) → 559 (432) ms
packages/bun-lambda 647 → 589 314.7 → 310.8 MB 1650 (1391) → 1683 (1470) ms
sharp + @tailwindcss/oxide + rolldown + unrs-resolver 34 → 27 114.7 → 101.9 MB 633 (610) → 636 (607) ms
npm + pacote + @npmcli/arborist (packages shared with the bundle) 197 → 157 49.5 → 46.3 MB 548 (499) → 570 (471) ms
express + jest, typescript, eslint as devDependencies, --production 403 → 69 96.4 → 20.6 MB 735 (630) → 572 (533) ms

On this link the wall time differences are inside the run-to-run noise (standard deviation 50 to 900 ms), except --production. The rows with shared packages are the cost case: a package that is first resolved below a filtered dependency loses its resolve-phase download and the install phase fetches it.

Not covered. Each of these still downloads tarballs that no install uses, on main and on this branch.

  • The dependencies of a workspace that --filter leaves out. The workspace selection is not known during the resolve.
  • Registry packages below a git or tarball dependency that is not placed. The mark only passes through registry packages.
  • bun update, when it resolves a new version below a package that came from the lockfile. The mark is only set for packages that this resolve creates.
  • --dry-run. It has no install phase at all, so the right fix is to turn the prefetch off for it. That is a separate change.

Why the runtime auto-install is exempt. With --install=force the runtime loads a bundled dependency from the cache, not from the parent's node_modules. The resolver has a branch that downloads a resolved package that is missing from the cache (src/resolver/resolver.rs, the PreinstallState::Extract arm), but it never runs: it compares the error with FileNotFound, and From<install::Error> for bun_core::Error (src/install/error.rs) maps the ENOENT to Unexpected. So a resolve is the only time the runtime downloads a package. Without the exemption bun --install=force -p 'require("outer")' fails with error: Unexpected while resolving package 'bd'.

Equivalence of the feature sets. The installers test a dependency of a local package with local_package_features and a dependency of a remote package with remote_package_features. The resolve does not know the owner, and tests with local_package_features only. The two differ in dev_dependencies and workspaces, and a remote package has neither kind of dependency (Features::NPM). The optional and peer flags are always set together.

A package with a patch that the installers do not place gets no download and no patch task, whichever arm of the resolve it takes (Extract, CalcPatchHash, ApplyPatch). Before, it was downloaded and patched in the cache, and never installed. If a placed dependency resolves to the same package, the install phase downloads it and applies the patch. The tests install each project a third way, a fresh resolve that finds its manifests in the cache. That resolve runs before the hash of any patch is known, so it reaches the CalcPatchHash arm every time.

Cache contents. A fresh resolve no longer leaves the tarballs of filtered packages in the cache. An --offline install with the same platform and flags as the run that warmed the cache is not affected: the install phase of that run fetched everything it placed. A cache warmed with --production or --omit no longer holds the groups that were left out. With --dry-run or BUN_CONFIG_SKIP_INSTALL_PACKAGES=1 there is no install phase, so a package that is first resolved below a filtered dependency is not fetched at all. An install from a lockfile never cached more than it placed. docs/pm/cli/install.mdx now states that contract.

Other suites run with the debug build: bun-prune, bun-dedupe, bun-audit, bun-lock, bun-update-transitive, bun-install-cpu-os, architecture-match, bun-lockb, bun-pm-licenses, bun-install-offline, bun-install-security-provider, bun-workspaces, bun-add, bun-install-patch, bun-patch, bun-install (13 failures, all of them need bitbucket, gitlab or another external host, and all of them also fail with the released build).


no test proof · iteration 0 · platform-specific test(s) that do not run on this machine, deferring to CI, which covers all platforms: test/cli/install/bun-install-registry.test.ts

A fresh resolve starts the tarball download of every registry package
it resolves. The installers place nothing below a dependency that they
filter: a bundled dependency (the tarball of the parent ships it), a
package for another platform, or a group that --production or --omit
turns off. Those downloads were never used. `bun install` of npm@10.9.2
downloaded 174 tarballs to place one package.

The first resolve of a package through such a dependency no longer
creates the tarball task. No flag on the dependencies below says that
they are not placed, so lockfile scratch state marks the dependencies of
each package that is first reached this way. When a dependency that the
installers do place resolves to the same package, the install phase
downloads it like any other cache miss.

Behavior::is_placed is the test that Tree and the tree printer already
made, now in one place.

The runtime auto-install keeps every download. It has no install phase,
and with --install=force it loads a bundled dependency from the cache.
@coderabbitai

coderabbitai Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Essentials

Run ID: 1af14be0-c8dd-4c8e-b13e-7bc054e0d288

📥 Commits

Reviewing files that changed from the base of the PR and between b52d513 and c60dbae.

📒 Files selected for processing (8)
  • docs/pm/cli/install.mdx
  • src/install/PackageManager.rs
  • src/install/PackageManager/PackageManagerEnqueue.rs
  • src/install/PackageManager/PackageManagerOptions.rs
  • src/install/lockfile.rs
  • src/install/lockfile/Tree.rs
  • src/install_types/resolver_hooks.rs
  • test/cli/install/bun-install-registry.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 3 remain after this review.


Walkthrough

Changes

Installer resolution now distinguishes placed and unplaced dependencies. Runtime auto-install enables resolve-triggered downloads while skipping the install phase. Registry tests cover bundled, platform-specific, omitted, patched, cached, and runtime scenarios.

Dependency placement and resolution

Layer / File(s) Summary
Placement eligibility and lockfile tracking
src/install_types/resolver_hooks.rs, src/install/lockfile.rs, src/install/lockfile/Tree.rs
Placement checks now account for bundled behavior and enabled features. Lockfile scratch state tracks dependencies under unplaced subtrees.
Installer enqueue and runtime auto-install
src/install/PackageManager/PackageManagerOptions.rs, src/install/PackageManager/PackageManagerEnqueue.rs, src/install/PackageManager.rs
The enqueue path marks unplaced packages and dependencies, skips download and patch tasks for them, and runtime initialization enables runtime_auto_install.
Resolution scenarios and cache guidance
test/cli/install/bun-install-registry.test.ts, docs/pm/cli/install.mdx
Tests compare resolution modes and linkers across dependency scenarios. Documentation describes platform and dependency-group requirements for offline cache warming.

Suggested reviewers: jarred-sumner

Priority: ➖ Normal

Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to c60db

No actionable regression risk remains from the reviewed changes.

🚥 Pre-merge checks | ✅ 2 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning Issue #27418 requires Bun to avoid contacting the configured NPM registry for bundled dependencies, including bundled dependency manifest fetches. The PR changes resolve-phase tarball prefetching for … Change bundled-dependency resolution so Bun does not enqueue or fetch the bundled dependency manifest from the configured registry. Add an automated regression test that uses a registry where the bundled package is absent and verifies that …
Out of Scope Changes check ⚠️ Warning The linked issue #27418 concerns registry contact for bundled dependencies. The PR also changes fresh-resolution placement and caching for unsupported-platform packages, dependencies excluded by `--pr… Limit this PR to the bundled-dependency registry behavior and its supporting implementation, tests, and documentation, or link separate issues that require the platform, omit, patch, and runtime auto-install behavior.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: preventing downloads of tarballs for packages that installers will not place.
Description check ✅ Passed The description thoroughly explains the problem, fix, scope, limitations, cache behavior, and verification results. It does not use the exact template headings, but it provides the required content, i…
Full details: Linked Issues check

Explanation

Issue #27418 requires Bun to avoid contacting the configured NPM registry for bundled dependencies, including bundled dependency manifest fetches. The PR changes resolve-phase tarball prefetching for unplaced packages and adds tarball request tests. The PR summary explicitly states that manifest fetching for bundled dependencies and the reported missing-package failure remain unresolved. This leaves the issue's primary coding requirement unmet.

Resolution

Change bundled-dependency resolution so Bun does not enqueue or fetch the bundled dependency manifest from the configured registry. Add an automated regression test that uses a registry where the bundled package is absent and verifies that installation does not request that manifest or fail because of it.

Full details: Out of Scope Changes check

Explanation

The linked issue #27418 concerns registry contact for bundled dependencies. The PR also changes fresh-resolution placement and caching for unsupported-platform packages, dependencies excluded by --production or --omit, patched packages, and runtime auto-install. These categories are not part of the linked issue and are not required to prevent bundled dependency manifest requests. Their tests and cache documentation therefore include demonstrated changes outside the linked issue scope.

  • Fix all pre-merge checks with AI

Comment @coderabbitai help to get the list of available commands.

@robobun

robobun commented Sep 17, 2026 •

Copy link
Copy Markdown
Collaborator Author

Status: review findings handled in 41198b3 and c60dbae, waiting for CI. PR: #43122

How I reproduced it, on main (b64b630) and on 1.4.3-canary.1:

  • Local registry that logs tarball requests. outer@1.0.0 bundles bd@1.0.0, and bd depends on tr@1.0.0. bun install with no lockfile requests the tarballs of outer, bd and tr. An install from the saved bun.lock with a cold cache requests outer only.
  • Real registry. bun install of npm@10.9.2 with a cold cache extracts 196 tarballs into the cache and installs 1 package.
  • The same comparison, a fresh resolve against an install from its lockfile, is the new test block tarballs of a fresh resolve in test/cli/install/bun-install-registry.test.ts. Run it with bun bd test test/cli/install/bun-install-registry.test.ts -t "tarballs of a fresh resolve". 20 of its 23 tests fail without the change.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing blocking. The comments below are optional suggestions. There is no need to push a fix for them before merging.

Additional findings (outside the current diff — GitHub can't attach inline comments there):

  • 🟡 src/install/PackageManager/PackageManagerEnqueue.rs — Patched packages below a bundled, disabled or omitted dependency are still downloaded by a fresh resolve, depending on timing, so the description's claim that they no longer are does not hold. The unplaced skip only gates the PreinstallState::Extract arm; the CalcPatchHash arm at PackageManagerEnqueue.rs:2491 still creates the task, and its after-state in patch_install.rs:301 re-runs determine_preinstall_state and enqueues the tarball without any unplaced check. Fix: make every resolve-phase tarball site honour the same placed/unplaced decision, e.g. carry it in EnqueueAfterState or recompute it from dep_id with a shared helper, and skip the download at patch_install.rs:301 too.

    Extended reasoning...

    Perf-only, no wrong install results; filed because it is the parallel arm of the change and the PR text says the opposite. In a fresh install, patched dependencies from package.json have patchfile_hash_is_null true (install_with_manager.rs:434). create_new_lockfile_and_enqueue pre-enqueues one calc-hash task per patch on the thread pool (install_with_manager.rs:1962-1966) and immediately calls enqueue_dependency_list (1968), which resolves synchronously any root dependency whose manifest is in the disk cache. resolve_pending_tasks then calls wait_for_calcing_patch_hashes (1993), whose is_done loop runs run_tasks (install_with_manager.rs:1045-1052), so manifests arriving meanwhile also resolve packages before the hashes land. For such a package determine_preinstall_state sees the null hash and returns CalcPatchHash (PackageManagerLifecycle.rs:107-110). The CalcPatchHash arm (PackageManagerEnqueue.rs:2491-2505) does not look at unplaced and builds the task with EnqueueAfterState{pkg_id, dependency_id, url}. When the hash task completes, patch_install.rs:287-354 resets the state,…

    Verification: nit — perf-only and the base already downloads these tarballs, but the PR's description claim ("A package with a patch that only exists inside a bundle is no longer downloaded either") does not hold, and REVIEW.md asks that parallel switch arms be covered in the same PR. Trigger: a fresh resolve where a patchedDependencies entry names a package that is first reached below a… | nit — the new…

Comment thread src/install/PackageManager/PackageManagerEnqueue.rs Outdated
The skip only covered the download arm. A package with a patch that
resolves before the hash of its patch is known takes the CalcPatchHash
arm, and the task that arm creates downloads the tarball when the hash
lands. The ApplyPatch arm patched a cached copy that no install used.

One guard arm now covers every state. The install phase fetches and
patches the package when a placed dependency resolves to it.

The tests install a third way, a fresh resolve that finds its manifests
in the cache. That resolve runs before any patch hash is known, so the
patched projects reach the CalcPatchHash arm every time.

The offline install docs say which packages an install caches.
Comment thread src/install/PackageManager/PackageManagerEnqueue.rs Outdated
Comment thread src/install/PackageManager/PackageManagerEnqueue.rs Outdated
@robobun

robobun commented Sep 17, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 11:09 AM PT - Sep 17th, 2026

✅ @robobun, your commit c60dbaec656961418f82ef6850f999ac191d94c8 passed in Build #117168! 🎉


🧪   To try this PR locally:

bunx bun-pr 43122

That installs a local version of the PR into your bun-43122 executable, so you can run:

bun-43122 --bun

Comment thread src/install/PackageManager/PackageManagerOptions.rs Outdated
Comment thread src/install/lockfile.rs Outdated
Comment thread src/install/lockfile.rs Outdated
Comment thread src/install_types/resolver_hooks.rs Outdated
@robobun

robobun commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator Author

Both review findings are handled in 41198b3. c60dbae shortens the code comments that were flagged.

Patched packages. Confirmed. With the manifests in the cache, the resolve runs before the hash of the patch is known and takes the CalcPatchHash arm. The task from that arm downloaded bd. One guard arm now replaces the check in the Extract arm, so a package that is not placed gets no download and no patch task in any state. If a placed dependency resolves to the same package, the install phase downloads it and applies the patch.

The tests now install each project a third way: a fresh resolve that finds its manifests in the cache. That phase reaches CalcPatchHash every time. The new project with a patch, below a bundled dependency fails on eed3396 in exactly that phase. with a patch, first below a bundled dependency, then needed checks that the install phase still applies the patch. The PR notes are corrected.

Cache contents. Answered in the review thread: documented in docs/pm/cli/install.mdx and in the PR notes, and the download is not kept.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No new blocking issues. 2 optional suggestions (nits or notes on pre-existing code) were found and not posted. Nothing in this review needs a push before merging.

@robobun

robobun commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator Author

The two pre-merge warnings came from a false issue link. The PR notes named #27418 right after the words "does not fix", and GitHub read that as a closing keyword. A merge would have closed the issue.

I reworded the notes. The PR has no closing reference now, and #27418 stays open. That issue is about manifest requests for bundled dependencies, which this PR does not change.

@Jarred-Sumner
Jarred-Sumner merged commit 8eaad80 into main Sep 17, 2026
10 checks passed
@Jarred-Sumner
Jarred-Sumner deleted the robobun/ea5bbcc1/skip-bundled-dep-prefetch branch September 17, 2026 20:54
dylan-conway added a commit that referenced this pull request Oct 3, 2026
…#44414)

### Problem
- `bun update <dep> <peer>` exits 1 with `error: util@^1.0.0 failed to
resolve` when `<peer>` is an auto-installed peer that nothing else
depends on. Each name alone works.
- `enqueue_peer_rows` (`src/install/update_transitive.rs:452`) calls
`populate_manifest_cache` while dependencies wait for manifests. Its
wait runs `run_tasks` in manifests-only mode, which skips their waiter
lists (`runTasks.rs:662`, `:1070`).
- The opposite mismatch aborts `bun install` over a yarn.lock with an
unusable scope registry: `panic: infallible: task queued`.

### Fix
- `run_tasks` takes the waiter list of a finished manifest request on
every pass. A prefetch request has none.
- `print_log` returns `InstallFailed` when the log it resets holds an
error. `populate_manifest_cache` starts the progress bar before its wait
(`panic: downloads_node active`).
- Verified: `bun-update-transitive.test.ts` (18 new cases),
`yarn-lock-migration.test.ts` (1). All 19 fail without the fix. Also the
update, audit and migration suites.

### Background
- A waiter is a dependency that waits for a manifest request.
`task_queue` maps request ids to waiters. Only `run_tasks` retires
requests.
- `populate_manifest_cache` fetches manifests ahead of use (`bun
outdated`, bare `bun update`, five more entrances). Its requests have no
waiters.
- Considered a reorder of the named update: it covers 1 of 7 entrances
and keeps both skips and the abort.

### Downsides
- A prefetch pass does one `task_queue` lookup per stored manifest: 15
more instructions, no insert, no allocation.
- Queued dependencies now resolve inside the prefetch wait. Such a run
can print no `Resolving dependencies` line.
- After a failed download, `bun update --latest <name>` exits 1 and
saves nothing. It exited 0 and saved bun.lock.

<details><summary>Notes</summary>

**Repro.** A loopback registry has `util@1.0.0` with `peerDependencies:
{ core: "^1.0.0" }` and `core@1.0.0`. The project depends on `util
^1.0.0`. `bun install`, then `bun update util core`: exit 1, `error:
util@^1.0.0 failed to resolve`, nothing saved. The result is the same
after `util@1.1.0` and `core@1.1.0` exist, and in either name order. The
failure is in every release since 1.4.0 (#38333 added
`enqueue_peer_rows`).

**Why 1.4.2 passed one shape.** When `core` also depends on `util`,
1.4.2 moved both packages. The re-resolved peer made a new `core@1.1.0`,
its dependency started a tarball download of a new `util`, and the
extract arm of `run_tasks` ran the waiter list of the `util` manifest.
#43122 removed that download. No revert is needed: the waiter was
already dropped, and shapes without that download fail on 1.4.2 too.

**Mechanism.** `bun update` does not read the manifest disk cache, so
each queued dependency starts a manifest request and parks a
`TaskCallbackContext::Dependency` in `task_queue`
(`PackageManagerEnqueue.rs:1331`). `populate_manifest_cache` flushes and
schedules every queued request and waits until the manager has no
pending task. In that wait the old code stored the manifest and took
`continue` before the `task_queue` take. `network_dedupe_map` keeps the
request id, so nothing asks again. The dependency stays unresolved.

**Forms that failed and now pass (each is a test).** Both name orders. A
glob next to the peer and `*`. `--latest`. A transitive dependency named
next to the peer. The peer named from a workspace member. The peer
itself added to package.json. A dependency, an optional dependency, an
override or a `file:` folder added to package.json before `bun update
<peer>`. `--prefer-offline` with only the peer's manifest cached. A
patched dependency named next to the peer. Two forms were silent on
main. With an optional dependency added to package.json, `bun update
<peer>` exits 0 and saves a bun.lock without it. `bun update
<optional-dep> <peer>` exits 0, writes `"util": ""` to package.json and
saves a bun.lock with no packages.

**`print_log`.** It has two callers, `enqueue_peer_rows` and
`plan_edges`. Both print and reset the log in the middle of an install,
and `install_with_manager` reads `log.has_errors()` later to decide
whether to save. With the waiters delivered inside the prefetch wait, an
error of such a dependency reaches the first caller: a tarball 404 or an
integrity failure for a dependency that the request does not name. The
second caller has the same defect on main: `bun update --latest <name>`
runs `plan_edges` after the first resolve wave, so a tarball 404 in that
wave prints `error: GET ... - 404`, exits 0 and saves bun.lock and
package.json, where `bun update <name>` exits 1 and saves nothing. Two
tests pin both callers. Each fails without the guard.

**Migration abort.** `Packages::All` returns at the first manifest
request it cannot start, after it scheduled earlier ones.
`fetch_necessary_package_metadata_after_yarn_or_pnpm_migration` drops
that error. The install wait then completed a request with no
`task_queue` entry and hit `.expect("infallible: task queued")`. Release
build of the merge base: exit 134. This branch: exit 0, bun.lock
written.

**Progress bar.** `start_manifest_task` starts the bar only when it
creates a request. When every name is cached or already requested by a
queued dependency, the wait starts with no bar, and the first pass of
`run_tasks` names the bar if a manifest download has completed by then.
Real timing did not hit the window: 0 panics in 200 pty runs on each
build. With the main thread paused for 400 ms before that first pass
(gdb), a release build of main panics with `downloads_node active` in 5
of 5 runs, for the peer added to package.json and for `--prefer-offline`
with only the peer's manifest cached. This branch: 0 of 25 runs. No test
covers it, because it needs a pty and that pause.

**Measurements (release builds of the merge base 4b02e10 and of this
branch, unless noted).**
- `run_tasks_erased`, pass of a normal install: parsed-manifest arm 35
-> 33 instructions from the manifest store to the
`process_dependency_list_for_ctx` call, 304 arm 34 -> 33. The
compare-and-branch on `manifests_only` is gone at both sites. Whole
function: 6517 -> 6448 instructions.
- `run_tasks_erased`: 33,102 -> 32,764 bytes. `populate_manifest_cache`:
3,724 -> 3,756 bytes. Release `.text`: 0 bytes delta (80,679,983 both).
Stripped binary: 80,848,456 bytes both. These sizes are from the first
push. The later `print_log` change adds one compare and one early
return.
- Prefetch pass with nothing queued (`bun outdated`, 30 dependencies,
empty manifest cache): 30 `task_queue` lookups (0 on the merge base), 0
inserts, 0 waiter deliveries. After the manifest store the pass runs 20
instructions for each manifest, 12 of them in `HashMap::get_index`. The
merge base runs 5.
- Waiters (debug build, gdb): `bun update util core` 1 of 1 delivered
once. With `core` depending on `util`: 2 of 2. `bun update '*'` over 40
direct dependencies and 1 peer: 40 of 40 delivered once, 41 manifest
requests with no duplicate, 41 packages moved, `bun install
--frozen-lockfile` passes. The take in the extract arm found 0 non-empty
lists.
- Requests of `bun update util core` with both packages newer: 1 `GET
/util`, 1 `GET /core`, then the 2 tarballs. `bun update core nope`: 0
requests, same reject text.
- stdout, stderr and requests of `bun update util` and of `bun update
core`: 0 changed lines.
- Event-loop waits entered (`AnyEventLoop::tick_raw`, debug builds, two
runs each): `bun update util` 3 and 5 on both builds. `bun update core`
3 and 5 to 6 on the merge base, 3 and 6 on this branch.

**Left for later.**
- A waiter that is parked on a failed manifest request stays parked in
both modes.
- The prefetch pass still runs with `install_peer = true`. Only non-peer
dependencies can be parked there today.
- `MANIFESTS_ONLY` now only keeps the parsed-manifest arm from naming
the progress bar.
- #40284 rewrites the same two hunks and keeps both early exits. #43981
adds another `populate_manifest_cache` call inside an install, which
this change makes safe in any call order.

</details>

---------

Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants