[PR #1019] [MERGED] refactor(app-router): extract browser navigation lifecycle controller #1023

Closed
opened 2026-05-06 13:11:36 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/1019
Author: @NathanDrake2406
Created: 5/2/2026
Status: Merged
Merged: 5/3/2026
Merged by: @james-elicx

Base: mainHead: nathan/app-browser-navigation-controller


📝 Commits (5)

  • 9ce9934 refactor(app-router): extract browser navigation lifecycle controller
  • 6e7b621 fix(app-router): separate render ids from navigation ids
  • 462927e merge(upstream): resolve browser navigation conflicts
  • bfd5d98 fix(app-router): satisfy ci lint rules
  • 4a45b37 fix(app-router): narrow controller surface, add hmrReplaceTree, restore lost comments, fix tests

📊 Changes

3 files changed (+1030 additions, -523 deletions)

View changed files

📝 packages/vinext/src/server/app-browser-entry.ts (+124 -522)
packages/vinext/src/server/app-browser-navigation-controller.ts (+582 -0)
📝 tests/app-browser-entry.test.ts (+324 -1)

📄 Description

Summary

Extract the App Router browser navigation lifecycle into app-browser-navigation-controller.ts so app-browser-entry.ts only wires the browser root and delegates lifecycle authority.

This keeps behavior unchanged while making the current lifecycle explicit and testable ahead of #726. Scope intentionally excludes route semantics, cache reuse, router-kernel changes, and any new lifecycle policy.

What changed

  • Moved active navigation identity, pending browser-router promise ownership, pending commit settlement, pre-paint commit effects, stale-navigation checks, and dispatch / hard-navigation handling into the controller.
  • Kept app-browser-entry.ts thin: it now adapts browser state into the controller and delegates navigation / same-URL commits.
  • Added focused behavior tests for stale navigation suppression, pending browser-router promise supersession, pre-paint commit queuing, and same-URL dispatch vs hard navigation.

Verification

  • vp test tests/app-browser-entry.test.ts

Next.js references


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/1019 **Author:** [@NathanDrake2406](https://github.com/NathanDrake2406) **Created:** 5/2/2026 **Status:** ✅ Merged **Merged:** 5/3/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `nathan/app-browser-navigation-controller` --- ### 📝 Commits (5) - [`9ce9934`](https://github.com/cloudflare/vinext/commit/9ce9934c161aabf08de0d1abb463f6f0369eefd8) refactor(app-router): extract browser navigation lifecycle controller - [`6e7b621`](https://github.com/cloudflare/vinext/commit/6e7b62132e91a3aff0ac2a4130547a7e014270e8) fix(app-router): separate render ids from navigation ids - [`462927e`](https://github.com/cloudflare/vinext/commit/462927eedeca220b4f1933237d9471a21f63c919) merge(upstream): resolve browser navigation conflicts - [`bfd5d98`](https://github.com/cloudflare/vinext/commit/bfd5d987041a02188e068a7a20420b503134bb5f) fix(app-router): satisfy ci lint rules - [`4a45b37`](https://github.com/cloudflare/vinext/commit/4a45b37588c1f9d8b540fbadafd1e146bc5a3ef9) fix(app-router): narrow controller surface, add hmrReplaceTree, restore lost comments, fix tests ### 📊 Changes **3 files changed** (+1030 additions, -523 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/server/app-browser-entry.ts` (+124 -522) ➕ `packages/vinext/src/server/app-browser-navigation-controller.ts` (+582 -0) 📝 `tests/app-browser-entry.test.ts` (+324 -1) </details> ### 📄 Description ## Summary Extract the App Router browser navigation lifecycle into `app-browser-navigation-controller.ts` so `app-browser-entry.ts` only wires the browser root and delegates lifecycle authority. This keeps behavior unchanged while making the current lifecycle explicit and testable ahead of #726. Scope intentionally excludes route semantics, cache reuse, router-kernel changes, and any new lifecycle policy. ## What changed - Moved active navigation identity, pending browser-router promise ownership, pending commit settlement, pre-paint commit effects, stale-navigation checks, and dispatch / hard-navigation handling into the controller. - Kept `app-browser-entry.ts` thin: it now adapts browser state into the controller and delegates navigation / same-URL commits. - Added focused behavior tests for stale navigation suppression, pending browser-router promise supersession, pre-paint commit queuing, and same-URL dispatch vs hard navigation. ## Verification - `vp test tests/app-browser-entry.test.ts` ## Next.js references - Browser-router lifecycle and transition handling: [app-router.tsx](https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/app-router.tsx#L154-L323) - Router dispatch queue and module-level action ownership: [use-action-queue.ts](https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/use-action-queue.ts#L12-L140) - Hard-navigation fallback on navigation errors: [nav-failure-handler.ts](https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/nav-failure-handler.ts#L4-L45) - Pending navigation state that stays true until unload: [navigation.test.ts](https://github.com/vercel/next.js/blob/canary/test/e2e/app-dir/navigation/navigation.test.ts#L577-L610) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:11:36 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#1023
No description provided.