mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
5dc3ae1fe7
## Summary Repro (from #96692): enable the Nav Inspector, click a `<Link prefetch={true}>`, close the inspector, navigate home, re-enable it, and click the same link. The app hung in a pending "Compiling..." state while firing prefetch requests in an infinite loop (~30/sec). The Instant Navigation Testing lock restricted navigation reads to entries created within the current lock scope (`ownedEntries`), enforced as a post-hoc filter after the cache lookup. But the segment cache resolves lookups by most-specific-match, so a previous scope's runtime-prefetch entries at concrete param keypaths kept winning the lookup, the filter kept rejecting them, and the locked prefetch created its replacement at a more generic keypath that could never win — every scheduler pass discarded and refetched forever. Rather than patch the filter, this replaces the `ownedEntries` mechanism: - Each lock scope owns a private segment `CacheMap` that starts empty and is discarded at release, so a captured navigation structurally observes only data fetched under the lock — cross-scope shadowing becomes impossible by construction. - The map is an explicit capability bound when work is created: a prefetch task captures its map when scheduled (`PrefetchTask.segmentCacheMap` — the single place that consults lock state), a locked navigation inherits its driving task's map, and everything else — unlocked navigations, hydration, refreshes, traversals, server actions and patches — binds to the shared map. Reads and response writes receive the map explicitly, so a request that straddles a scope boundary still writes into the map its entries live in. In production builds without the testing API this compiles down to the previous single-map behavior. Includes the failing test from #96692 (thanks @samselikoff), hardened to use the retry-based panel-reopen helper the sibling tests use. ## Verification - `pnpm test-dev-turbo test/development/app-dir/instant-navs-devtools/instant-navs-devtools.test.ts` (32/32, includes the new regression test) - `pnpm test-dev-webpack test/development/app-dir/instant-navs-devtools/instant-navs-devtools.test.ts -t "repeat clicks"` - `pnpm test-dev-turbo test/e2e/app-dir/instant-navigation-testing-api/instant-navigation-testing-api.test.ts` - `pnpm test-start-turbo test/e2e/app-dir/instant-navigation-testing-api/instant-navigation-testing-api.test.ts` - `pnpm test-start-turbo test/e2e/app-dir/segment-cache/basic/segment-cache-basic.test.ts` (production paths unregressed) <!-- NEXT_JS_LLM --> --------- Co-authored-by: Sam Selikoff <sam.selikoff@gmail.com>