[PR #1017] [MERGED] refactor(app-rsc-entry): delegate pure helpers to typed server modules #1021

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/1017
Author: @NathanDrake2406
Created: 5/2/2026
Status: Merged
Merged: 5/3/2026
Merged by: @james-elicx

Base: mainHead: refactor/extract-entry-helpers


📝 Commits (5)

  • 877eda3 refactor(app-rsc-entry): delegate pure helpers to typed server modules
  • b09e7d6 fix: remove redundant as cast and fix test module caching
  • aaea32f fix: resolve entry helper rebase conflicts
  • b8b4cf2 ci: rerun checks (font-google flake)
  • df196bc Update packages/vinext/src/entries/app-rsc-entry.ts

📊 Changes

13 files changed (+608 additions, -86 deletions)

View changed files

📝 knip.ts (+5 -0)
📝 packages/vinext/src/entries/app-rsc-entry.ts (+33 -86)
packages/vinext/src/server/app-hook-warning-suppression.ts (+14 -0)
packages/vinext/src/server/app-post-middleware-context.ts (+25 -0)
packages/vinext/src/server/app-request-context.ts (+30 -0)
packages/vinext/src/server/app-rsc-error-handler.ts (+38 -0)
📝 packages/vinext/src/server/rsc-stream-hints.ts (+6 -0)
tests/app-hook-warning-suppression.test.ts (+87 -0)
tests/app-post-middleware-context.test.ts (+91 -0)
tests/app-request-context.test.ts (+101 -0)
📝 tests/app-router.test.ts (+61 -0)
tests/app-rsc-error-handler.test.ts (+107 -0)
📝 tests/entry-templates.test.ts (+10 -0)

📄 Description

Deepseek V4 Pro Max

What this changes

Extracts five inline runtime helpers from the generated App Router RSC entry template into dedicated typed modules under packages/vinext/src/server/. The generated entry now imports and wires these helpers instead of owning their implementation.

Why

The generated RSC entry template (entries/app-rsc-entry.ts) contained five inline implementations of pure runtime behavior inside the template string. These inline blocks:

  • Lived inside template strings where type-checking and unit testing were unavailable
  • Added ~55 lines of runtime logic to generated code that should describe the app shape, not own behavior
  • Violated the architecture principle that generated entries are codegen glue, not homes for request lifecycle logic (per AGENTS.md: "Generated Entry Modules Should Stay Thin")

Approach

Five new or enhanced typed modules, each with focused unit tests:

Inline helper (old) New typed module Tests
__buildPostMwRequestContext(request) server/app-post-middleware-context.tsbuildPostMwRequestContext() 5 tests
createRscOnErrorHandler(request, pathname, routePath) server/app-rsc-error-handler.tscreateAppRscOnErrorHandler() 6 tests
__clearRequestContext() + setNavigationContext() server/app-request-context.tsclearAppRequestContext() + setAppNavigationContext() 5 tests
renderToReadableStream preload hint wrapper server/rsc-stream-hints.tscreateRscRenderer() factory 4 existing + new factory export
console.error hook warning patch + ALS server/app-hook-warning-suppression.ts — side-effect import 4 tests

Key design decisions:

  1. Aliased imports preserve call sites: The entry template aliases module exports so existing call sites need no changes. For example, clearAppRequestContext is imported as __clearRequestContext so all 11 existing __clearRequestContext() calls remain valid.

  2. createAppRscOnErrorHandler takes reportRequestError as an explicit first parameter rather than capturing it from scope, making the factory pure and testable without mocking module imports.

  3. Hook warning suppression is imported as a side-effect module — the console.error patch runs once at module evaluation time, matching the existing behavior. The entry template only imports the ALS handle (suppressHookWarningAls) for per-route suppression.

  4. createRscRenderer is a pure factory that takes the raw renderToReadableStream import and returns a wrapped version with preload hint normalization. This replaces the inline function renderToReadableStream(model, options) { ... } wrapper.

  5. Removed unused imports from the template string: AsyncLocalStorage, setHeadersContext, getHeadersContext, normalizeHost, _setNavigationContextOrig. These were only needed by the removed inline code.

Reference architecture: this extends the pattern established by server/app-rsc-errors.ts, server/app-rsc-route-matching.ts, and server/app-page-dispatch.ts, which were already extracted from the same template. See AGENTS.md section "Generated Entry Modules Should Stay Thin."

Validation

  • 24 unit tests cover the five new/extended helper modules
  • 374 existing tests pass unchanged (app-router integration, entry-templates snapshots, unit tests)
  • Clean entry template output confirmed via snapshot test assertions
  • No more unused-export warnings from knip for the generated-code imports

Risks / follow-ups

  • Other generated entry files (app-browser-entry.ts, app-ssr-entry.ts, pages-server-entry.ts) may benefit from the same extraction pattern in future PRs
  • createRscRenderer is only consumed by the generated entry template string, so it appears unused to static analysis (handled via knip config exception)

🔄 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/1017 **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:** `refactor/extract-entry-helpers` --- ### 📝 Commits (5) - [`877eda3`](https://github.com/cloudflare/vinext/commit/877eda34010db8f42de9e53d1b523d93cec1fc5a) refactor(app-rsc-entry): delegate pure helpers to typed server modules - [`b09e7d6`](https://github.com/cloudflare/vinext/commit/b09e7d6ece535c92446a7c63840eadaa021800a5) fix: remove redundant as cast and fix test module caching - [`aaea32f`](https://github.com/cloudflare/vinext/commit/aaea32f6a569282d3e1f78d26c9739b58d477a54) fix: resolve entry helper rebase conflicts - [`b8b4cf2`](https://github.com/cloudflare/vinext/commit/b8b4cf23b6b1eefeb5b138ec8ea86252130ff70e) ci: rerun checks (font-google flake) - [`df196bc`](https://github.com/cloudflare/vinext/commit/df196bc40ca61f35b2569b9719df9a5e8164fe13) Update packages/vinext/src/entries/app-rsc-entry.ts ### 📊 Changes **13 files changed** (+608 additions, -86 deletions) <details> <summary>View changed files</summary> 📝 `knip.ts` (+5 -0) 📝 `packages/vinext/src/entries/app-rsc-entry.ts` (+33 -86) ➕ `packages/vinext/src/server/app-hook-warning-suppression.ts` (+14 -0) ➕ `packages/vinext/src/server/app-post-middleware-context.ts` (+25 -0) ➕ `packages/vinext/src/server/app-request-context.ts` (+30 -0) ➕ `packages/vinext/src/server/app-rsc-error-handler.ts` (+38 -0) 📝 `packages/vinext/src/server/rsc-stream-hints.ts` (+6 -0) ➕ `tests/app-hook-warning-suppression.test.ts` (+87 -0) ➕ `tests/app-post-middleware-context.test.ts` (+91 -0) ➕ `tests/app-request-context.test.ts` (+101 -0) 📝 `tests/app-router.test.ts` (+61 -0) ➕ `tests/app-rsc-error-handler.test.ts` (+107 -0) 📝 `tests/entry-templates.test.ts` (+10 -0) </details> ### 📄 Description Deepseek V4 Pro Max ## What this changes Extracts five inline runtime helpers from the generated App Router RSC entry template into dedicated typed modules under `packages/vinext/src/server/`. The generated entry now imports and wires these helpers instead of owning their implementation. ## Why The generated RSC entry template (`entries/app-rsc-entry.ts`) contained five inline implementations of pure runtime behavior inside the template string. These inline blocks: - Lived inside template strings where type-checking and unit testing were unavailable - Added ~55 lines of runtime logic to generated code that should describe the app shape, not own behavior - Violated the architecture principle that generated entries are codegen glue, not homes for request lifecycle logic (per `AGENTS.md`: "Generated Entry Modules Should Stay Thin") ## Approach Five new or enhanced typed modules, each with focused unit tests: | Inline helper (old) | New typed module | Tests | |---|---|---| | `__buildPostMwRequestContext(request)` | `server/app-post-middleware-context.ts` — `buildPostMwRequestContext()` | 5 tests | | `createRscOnErrorHandler(request, pathname, routePath)` | `server/app-rsc-error-handler.ts` — `createAppRscOnErrorHandler()` | 6 tests | | `__clearRequestContext()` + `setNavigationContext()` | `server/app-request-context.ts` — `clearAppRequestContext()` + `setAppNavigationContext()` | 5 tests | | `renderToReadableStream` preload hint wrapper | `server/rsc-stream-hints.ts` — `createRscRenderer()` factory | 4 existing + new factory export | | `console.error` hook warning patch + ALS | `server/app-hook-warning-suppression.ts` — side-effect import | 4 tests | **Key design decisions:** 1. **Aliased imports preserve call sites**: The entry template aliases module exports so existing call sites need no changes. For example, `clearAppRequestContext` is imported as `__clearRequestContext` so all 11 existing `__clearRequestContext()` calls remain valid. 2. **`createAppRscOnErrorHandler` takes `reportRequestError` as an explicit first parameter** rather than capturing it from scope, making the factory pure and testable without mocking module imports. 3. **Hook warning suppression is imported as a side-effect module** — the `console.error` patch runs once at module evaluation time, matching the existing behavior. The entry template only imports the ALS handle (`suppressHookWarningAls`) for per-route suppression. 4. **`createRscRenderer` is a pure factory** that takes the raw `renderToReadableStream` import and returns a wrapped version with preload hint normalization. This replaces the inline `function renderToReadableStream(model, options) { ... }` wrapper. 5. **Removed unused imports** from the template string: `AsyncLocalStorage`, `setHeadersContext`, `getHeadersContext`, `normalizeHost`, `_setNavigationContextOrig`. These were only needed by the removed inline code. **Reference architecture**: this extends the pattern established by `server/app-rsc-errors.ts`, `server/app-rsc-route-matching.ts`, and `server/app-page-dispatch.ts`, which were already extracted from the same template. See `AGENTS.md` section "Generated Entry Modules Should Stay Thin." ## Validation - **24 unit tests** cover the five new/extended helper modules - **374 existing tests pass unchanged** (app-router integration, entry-templates snapshots, unit tests) - Clean entry template output confirmed via snapshot test assertions - No more unused-export warnings from knip for the generated-code imports ## Risks / follow-ups - Other generated entry files (`app-browser-entry.ts`, `app-ssr-entry.ts`, `pages-server-entry.ts`) may benefit from the same extraction pattern in future PRs - `createRscRenderer` is only consumed by the generated entry template string, so it appears unused to static analysis (handled via knip config exception) --- <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#1021
No description provided.