[PR #1059] [MERGED] refactor(app-router): introduce AppElementsWire boundary #1058

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

📋 Pull Request Information

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

Base: mainHead: nathan/726-wire-01-app-elements-wire


📝 Commits (2)

  • 2e46230 refactor(app-router): introduce AppElementsWire boundary
  • 4ebb212 chore(app-router): address AppElementsWire review

📊 Changes

13 files changed (+390 additions, -275 deletions)

View changed files

📝 packages/vinext/src/entries/app-rsc-entry.ts (+7 -6)
📝 packages/vinext/src/server/app-browser-entry.ts (+13 -15)
📝 packages/vinext/src/server/app-browser-state.ts (+2 -2)
packages/vinext/src/server/app-elements-wire.ts (+246 -0)
📝 packages/vinext/src/server/app-elements.ts (+25 -200)
📝 packages/vinext/src/server/app-page-boundary-render.ts (+7 -11)
📝 packages/vinext/src/server/app-page-element-builder.ts (+7 -9)
📝 packages/vinext/src/server/app-page-render.ts (+2 -2)
📝 packages/vinext/src/server/app-page-route-wiring.tsx (+11 -16)
📝 packages/vinext/src/server/app-ssr-entry.ts (+3 -7)
📝 packages/vinext/src/shims/link.tsx (+2 -2)
📝 packages/vinext/src/shims/navigation.ts (+5 -5)
📝 tests/app-elements.test.ts (+60 -0)

📄 Description

What this changes

Introduces #726-WIRE-01 by making AppElements wire transport pass through an explicit AppElementsWire codec boundary.

Production App Router callers now use AppElementsWire for route ids, page ids, cache keys, metadata entries, outgoing payload layout flags, wire decode, and metadata reads. The existing app-elements module remains as the compatibility barrel for current helper imports, but current production encode/decode/write paths no longer assemble raw AppElements wire metadata directly.

Why

Issue #726 calls out the flat keyed AppElements payload as a transport bridge, not the router brain. Before this PR, route identity, cache identity, metadata writes, unmatched-slot transport, and payload parsing were spread across call sites as individual helper calls and raw keys. That makes later ownership work harder because there is no single place to reason about the RSC/HTML payload boundary.

Correctness oracle: Vinext internal invariant. This PR preserves current observable App Router behavior while introducing an enforceable wire owner for the next #726 waves.

Approach

Add server/app-elements-wire.ts as the codec owner for:

  • wire constants and the unmatched-slot transport sentinel
  • AppElements and AppWireElements decode
  • route, page, and cache key encoding
  • canonical metadata entry creation
  • outgoing payload shaping with layout flags
  • metadata parsing and payload-record detection

Then route the current production call sites through AppElementsWire:

  • RSC route wiring, fallback boundaries, no-default-export payloads, and generated RSC action not-found payloads
  • SSR and browser RSC decode plus metadata reads
  • visited-response and prefetch cache key construction
  • next/link and next/navigation prefetch dedupe keys

This intentionally does not promote topology, slot ownership, lifecycle authority, or cache semantics. Those remain later #726 waves.

Validation

  • vp test run tests/app-elements.test.ts tests/slot.test.ts tests/app-browser-entry.test.ts tests/app-page-element-builder.test.ts tests/app-page-render.test.ts tests/app-page-route-wiring.test.ts tests/app-fallback-renderer.test.ts tests/app-router.test.ts tests/entry-templates.test.ts tests/link.test.ts tests/prefetch-cache.test.ts
  • vp check packages/vinext/src/server/app-elements-wire.ts packages/vinext/src/server/app-elements.ts packages/vinext/src/server/app-page-route-wiring.tsx packages/vinext/src/server/app-page-boundary-render.ts packages/vinext/src/server/app-page-element-builder.ts packages/vinext/src/server/app-page-render.ts packages/vinext/src/server/app-ssr-entry.ts packages/vinext/src/server/app-browser-state.ts packages/vinext/src/server/app-browser-entry.ts packages/vinext/src/shims/navigation.ts packages/vinext/src/shims/link.tsx packages/vinext/src/entries/app-rsc-entry.ts tests/app-elements.test.ts
  • vp run vinext#build

The focused test matrix passed 530 tests. The build completed with the repo's existing virtual-module unresolved-import warnings.

Risks / follow-ups

Open PR overlap risk exists around App Router generated entry and browser navigation files, especially #1057, #922, #698, #647, #488, #404 and older dirty PRs. This branch is based on current upstream/main and currently publishes cleanly from there.

WIRE-02 should remove or lint against raw wire-key construction outside AppElementsWire. This PR deliberately leaves legacy helper exports where covered by existing compatibility tests so the ownership migration stays reviewable.


🔄 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/1059 **Author:** [@NathanDrake2406](https://github.com/NathanDrake2406) **Created:** 5/5/2026 **Status:** ✅ Merged **Merged:** 5/5/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `nathan/726-wire-01-app-elements-wire` --- ### 📝 Commits (2) - [`2e46230`](https://github.com/cloudflare/vinext/commit/2e46230b89a4521077660480413ad3e599b15d1f) refactor(app-router): introduce AppElementsWire boundary - [`4ebb212`](https://github.com/cloudflare/vinext/commit/4ebb212dca83078bff7f7cd31c90b7e60b65e004) chore(app-router): address AppElementsWire review ### 📊 Changes **13 files changed** (+390 additions, -275 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/entries/app-rsc-entry.ts` (+7 -6) 📝 `packages/vinext/src/server/app-browser-entry.ts` (+13 -15) 📝 `packages/vinext/src/server/app-browser-state.ts` (+2 -2) ➕ `packages/vinext/src/server/app-elements-wire.ts` (+246 -0) 📝 `packages/vinext/src/server/app-elements.ts` (+25 -200) 📝 `packages/vinext/src/server/app-page-boundary-render.ts` (+7 -11) 📝 `packages/vinext/src/server/app-page-element-builder.ts` (+7 -9) 📝 `packages/vinext/src/server/app-page-render.ts` (+2 -2) 📝 `packages/vinext/src/server/app-page-route-wiring.tsx` (+11 -16) 📝 `packages/vinext/src/server/app-ssr-entry.ts` (+3 -7) 📝 `packages/vinext/src/shims/link.tsx` (+2 -2) 📝 `packages/vinext/src/shims/navigation.ts` (+5 -5) 📝 `tests/app-elements.test.ts` (+60 -0) </details> ### 📄 Description ## What this changes Introduces #726-WIRE-01 by making AppElements wire transport pass through an explicit AppElementsWire codec boundary. Production App Router callers now use AppElementsWire for route ids, page ids, cache keys, metadata entries, outgoing payload layout flags, wire decode, and metadata reads. The existing app-elements module remains as the compatibility barrel for current helper imports, but current production encode/decode/write paths no longer assemble raw AppElements wire metadata directly. ## Why Issue #726 calls out the flat keyed AppElements payload as a transport bridge, not the router brain. Before this PR, route identity, cache identity, metadata writes, unmatched-slot transport, and payload parsing were spread across call sites as individual helper calls and raw keys. That makes later ownership work harder because there is no single place to reason about the RSC/HTML payload boundary. Correctness oracle: Vinext internal invariant. This PR preserves current observable App Router behavior while introducing an enforceable wire owner for the next #726 waves. ## Approach Add server/app-elements-wire.ts as the codec owner for: - wire constants and the unmatched-slot transport sentinel - AppElements and AppWireElements decode - route, page, and cache key encoding - canonical metadata entry creation - outgoing payload shaping with layout flags - metadata parsing and payload-record detection Then route the current production call sites through AppElementsWire: - RSC route wiring, fallback boundaries, no-default-export payloads, and generated RSC action not-found payloads - SSR and browser RSC decode plus metadata reads - visited-response and prefetch cache key construction - next/link and next/navigation prefetch dedupe keys This intentionally does not promote topology, slot ownership, lifecycle authority, or cache semantics. Those remain later #726 waves. ## Validation - vp test run tests/app-elements.test.ts tests/slot.test.ts tests/app-browser-entry.test.ts tests/app-page-element-builder.test.ts tests/app-page-render.test.ts tests/app-page-route-wiring.test.ts tests/app-fallback-renderer.test.ts tests/app-router.test.ts tests/entry-templates.test.ts tests/link.test.ts tests/prefetch-cache.test.ts - vp check packages/vinext/src/server/app-elements-wire.ts packages/vinext/src/server/app-elements.ts packages/vinext/src/server/app-page-route-wiring.tsx packages/vinext/src/server/app-page-boundary-render.ts packages/vinext/src/server/app-page-element-builder.ts packages/vinext/src/server/app-page-render.ts packages/vinext/src/server/app-ssr-entry.ts packages/vinext/src/server/app-browser-state.ts packages/vinext/src/server/app-browser-entry.ts packages/vinext/src/shims/navigation.ts packages/vinext/src/shims/link.tsx packages/vinext/src/entries/app-rsc-entry.ts tests/app-elements.test.ts - vp run vinext#build The focused test matrix passed 530 tests. The build completed with the repo's existing virtual-module unresolved-import warnings. ## Risks / follow-ups Open PR overlap risk exists around App Router generated entry and browser navigation files, especially #1057, #922, #698, #647, #488, #404 and older dirty PRs. This branch is based on current upstream/main and currently publishes cleanly from there. WIRE-02 should remove or lint against raw wire-key construction outside AppElementsWire. This PR deliberately leaves legacy helper exports where covered by existing compatibility tests so the ownership migration stays reviewable. --- <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:46 +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#1058
No description provided.