Commit Graph

1381 Commits

Author SHA1 Message Date
github-actions[bot] cceb1988dd chore: version packages (#2203)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
vinext@0.1.7
2026-06-22 09:26:20 +00:00
James Anderson cf9d601162 fix lockfile (#2233) 2026-06-21 18:18:31 +00:00
James Anderson 82d5f7691c fix(perf): resolve Vite from benchmark target (#2212) 2026-06-20 14:05:33 +00:00
Divanshu Chauhan e7a4e9b08b fix(image): emit hoisted var for local image import binding to avoid TDZ (#2067)
The vinext:image-imports transform rewrote `import X from './a.png'` into
two imports plus `const X = {...}`. The original import is a module-scoped
binding initialized before module-body execution, but the `const` is
block-scoped and TDZ-bound until its textual line, so any reference to `X`
that runs earlier — a hoisted function called above the import, or a
circular-import re-entry — flipped from working to a runtime
`Cannot access 'X' before initialization`.

Emit `var X = {...}` instead: it hoists like the import it replaces, so the
forward reference no longer throws (it reads `undefined` before the line,
strictly better than crashing). Matches Next.js, which leaves the consumer's
`import X` untouched and rewrites the image module itself.

Closes #1975
2026-06-20 14:49:17 +01:00
Divanshu Chauhan ad2fcfb16f fix(dynamic): render ssr:false loading with pastDelay:true to match client (#1967) (#2064)
next/dynamic's ssr:false server branch rendered the loading component with
pastDelay:false, while the client's first (pre-mount) render and Suspense
fallback default pastDelay to true. For a loading component that branches on
pastDelay (the documented `if (!pastDelay) return null` pattern), the server
emitted nothing but the client rendered the spinner, causing a React hydration
mismatch and a visible content jump.

Drop the hardcoded pastDelay:false override on the server so it defaults to
true, matching both the client render and Next.js App Router, which always
renders the loading fallback with pastDelay=true on server and client. Loading
components that ignore pastDelay are unaffected.

Update the three tests that asserted the buggy server-side pastDelay:false, and
add a server-equals-client-first-render parity assertion.

Fixes #1967
2026-06-20 14:47:02 +01:00
Divanshu Chauhan 05038707e2 fix(actions): dedupe Set-Cookie on no-JS non-redirect action responses (#1976) (#2063)
The progressive (form-state) non-redirect server-action path returned the
raw `getAndClearPendingCookies()` array, so calling `cookies().set(name, ...)`
twice for the same name emitted two `Set-Cookie` headers for that name on
no-JS form submissions. Next.js stores mutable cookies in a name-keyed
`ResponseCookies` map (last value wins) and collapses to one header, as do the
redirect and RSC action paths in vinext via `dedupePendingCookies()`.

Wrap the non-redirect branch's cookie collection in `dedupePendingCookies()`
to match the sibling paths, so same-name sets collapse to a single Set-Cookie
(last value wins). The single binding feeds both the action-failed and success
returns, covering both non-redirect sub-cases.

Follow-up to the #1481 dedup fix, which landed on the redirect and RSC paths
but missed the progressive non-redirect branch.

Adds a regression test mirroring the existing redirect-dedup test for the
non-redirect form-state path.
2026-06-20 14:45:36 +01:00
Alexander Lichter e7225b92cc fix(benchmarks): measure eager RSC entry closure (#2208) 2026-06-20 14:43:49 +01:00
Divanshu Chauhan 32973e9ddf fix(rsc): only short-circuit well-known signal digests so real errors reach onRequestError (#2066)
createRscOnErrorHandler treated ANY error carrying a digest field as a
control-flow signal: it returned String(error.digest) and skipped
reportRequestError, so a genuine server-render error that merely carried a
digest (e.g. a hashed digest from sanitizeErrorForClient, or one transported
from a nested boundary) was silently swallowed with no instrumentation and
its digest shipped to the client as if it were a signal.

Mirror Next.js getDigestForWellKnownError: add a helper that recognizes only
genuine signals (redirect / notFound+http-fallback / bailout-to-CSR /
dynamic-server) and gate the short-circuit on it. Non-signal digest errors now
fall through to reportRequestError and keep their existing digest as-is.

Fix the same conflation in createAppPageRscErrorTracker.onRenderError, which
routed any digest-bearing error to the special 307/404-swap slot; gate it on
isNavigationSignalError so real errors reach the error boundary and a later
real signal can still win the slot.

Closes #1978
2026-06-20 14:43:17 +01:00
Nathan Nguyen 46b8fe8ccd perf(server): skip duplicate App RSC vary merge (#2177)
App Router page responses commonly already carry the internal RSC Vary header before response finalization runs. Re-running the generic Vary merge in that case splits and deduplicates the known header value on every SSR response without changing the result.

Read the current Vary value first, set the internal header directly when missing, and only fall back to the generic merge path for custom Vary values that still need preservation and deduplication.
2026-06-20 14:29:46 +01:00
Nathan Nguyen 3e83ab24b4 perf(server): reuse App SSR bfcache metadata (#2182)
* perf(server): reuse App SSR bfcache metadata

* refactor(server): clarify bfcache segment parsing
2026-06-20 14:17:07 +01:00
Alexander Lichter 7c5f4c592a perf(app): omit unused server action runtime (#2206) 2026-06-20 13:51:01 +01:00
Alexander Lichter ef2e4a95dc perf(client): preserve additional route-owned shims (#2205) 2026-06-20 13:38:18 +01:00
Alexander Lichter 4fa904e10e test(e2e): stabilize app router history navigation (#2207)
* test(e2e): stabilize app router history navigation

* test(e2e): isolate temporary Vite caches
2026-06-20 13:37:21 +01:00
Alexander Lichter 94eb44ef66 feat(benchmarks): track eager client entry size (#2190) 2026-06-20 01:37:30 +01:00
James Anderson 3a9fe9927c fix(perf): keep main benchmark runs queued (#2204)
Co-authored-by: James <jamesanderson@cloudflare.com>
2026-06-20 00:36:27 +00:00
Alexander Lichter 85d49ec814 perf(dev): externalize SSR React runtime (#2191)
* perf(dev): externalize SSR React runtime

* fix(test): pass Vite config environment
2026-06-20 01:33:33 +01:00
Alexander Lichter 8da718ba43 perf(app-router): isolate action request detection (#2188) 2026-06-20 01:30:19 +01:00
dependabot[bot] ab6344d391 chore(deps): bump actions/checkout from 6.0.3 to 7.0.0 (#2192)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.3 to 7.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6.0.3...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-20 01:29:34 +01:00
Alexander Lichter b9653e8a3a perf(app): omit unused metadata route runtime (#2196)
* perf(app): omit unused metadata route runtime

* fix(app): keep metadata route helper type private

---------

Co-authored-by: James <jamesanderson@cloudflare.com>
2026-06-20 01:26:28 +01:00
Alexander Lichter 6e35d4e206 perf(client): preserve App Router route chunk boundaries (#2189) 2026-06-20 01:25:30 +01:00
Alexander Lichter 9970430c29 perf(app): omit unused middleware runtime (#2194) 2026-06-20 01:15:33 +01:00
Jerry Zhao cd328835da perf(og): use MagicString positional overwrites instead of repeated replaceAll (#2202) 2026-06-20 01:08:50 +01:00
Jerry Zhao 727c0709e5 perf(dev-server): memoize the Pages SSR handler across dev requests (#2201) 2026-06-20 01:08:22 +01:00
Jerry Zhao 680cbafabc perf(mdx): gate the MDX transform handler behind a native id filter (#2200) 2026-06-20 01:05:02 +01:00
Jerry Zhao 31167d8256 refactor(build): drop unreachable fsRoute lookup in prerenderPages (#2195) 2026-06-20 01:04:43 +01:00
Jerry Zhao d69c3cdba6 refactor(plugin): build removeConsole exclude set only after the bail-out checks (#2199) 2026-06-20 01:02:11 +01:00
Jerry Zhao e31398679a refactor(plugin): iterate SERVER_EXPORTS set instead of spreading to an array (#2198) 2026-06-20 01:01:41 +01:00
Jerry Zhao ef31ecff23 refactor(build): drop redundant Array.isArray check in prerenderApp (#2197) 2026-06-20 01:00:51 +01:00
Jerry Zhao 3dc2d83306 refactor(rsc): remove redundant replace in use cache variant parsing (#2193) 2026-06-20 00:56:54 +01:00
Alexander Lichter 92e4df5e33 fix(web): prevent benchmark chart label overlap (#2187) 2026-06-19 16:55:16 +01:00
github-actions[bot] 948a0d9d72 chore: version packages (#2147)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
vinext@0.1.6
2026-06-19 16:53:06 +01:00
James Anderson 656a381de9 fix(og): constrain inlined assets to trusted roots (#2172)
* fix(og): constrain inlined assets to trusted roots

* fix(og): canonicalize asset package boundaries

* test(og): cover canonical boundary intersections

* fix(og): support file-symlinked dependency modules

* docs(og): clarify logical asset boundary resolution

* fix(og): pin symlinked modules to matching packages

* fix(og): keep linked package boundaries narrow

* fix(og): reject workspace-root asset boundaries

* fix(og): name-pin external package boundaries

* fix(og): validate linked package ownership

* fix(og): track linked package ownership

* fix(og): harden linked package provenance

* fix(og): confine captured alias packages

* fix(og): pin captured directory aliases

* fix(og): require alias package ownership

* fix(og): support single-segment aliases

* perf(og): preserve alias lookup precedence

* refactor(og): extract asset ownership policy

* test(og): cover linked package fonts in e2e

* fix(og): recognize resolved package aliases

* fix(og): support regex package aliases

* test(og): isolate linked font fixture

* docs(test): clarify linked font coverage
2026-06-19 16:08:46 +01:00
Alexander Lichter 5581c506b3 feat(web): link benchmark chart points to commits (#2185) 2026-06-19 16:07:51 +01:00
Alexander Lichter 175662f108 feat(web): link benchmark references to GitHub (#2184) 2026-06-19 16:01:49 +01:00
James Anderson a3f137802b fix(perf): avoid dispatch publisher main race (#2180) 2026-06-19 15:22:49 +01:00
James Anderson 0fb4fe475a feat(web): show one hundred benchmark runs (#2178) 2026-06-19 15:04:09 +01:00
Nathan Nguyen 301418a3f1 perf(app-router): defer layout, template and boundary modules to first request (#2145)
* perf(app-router): defer layout, template and boundary modules to first request

The generated RSC entry statically imported every route's layout, template,
loading/error/not-found/forbidden/unauthorized boundary and parallel-slot
module at the top level. On a cold isolate — and on the dev server's first
request — that eagerly evaluated the whole app's segment tree, including
routes never visited in that lifetime. Page and route-handler modules were
already lazy; the surrounding segment modules were not.

Emit those modules as lazy `() => import()` loaders paired with `null`
placeholders in the manifest, and hydrate them onto the route's synchronous
fields in `ensureAppRouteModulesLoaded` before any read (extended from
page/handler to layouts, templates, boundaries and parallel-slot modules).
Intercept layouts hydrate via the dedicated `loadAppInterceptLayouts` because
they live on the match object, not the route. Every reader already runs behind
`ensureAppRouteModulesLoaded` (handler dispatch and `buildPageElements`) or the
intercept resolvers, so no synchronous module field is read before hydration.

The shared intercept `interceptLayouts` arrays keep their `readonly` public
types; the loader is their sole writer and fills slots through one
boundary-local cast, so route metadata stays immutable to callers.

Dev cold start is unchanged on page-heavy apps — pages were already lazy — but
on a boundary-heavy app (80 independent sections, each with
layout+template+error+loading+not-found) first-request module compile drops
704ms -> 534ms (~24%) and time-to-first-200 1917ms -> 1665ms. The saving scales
with the number of unrelated segments deferred.

* test(app-router): localize react max header font fixture

* fix(app-router): dedupe lazy intercept module loads

* fix(app-router): share intercept load state across matches

* docs(app-router): explain root layout loader reuse

---------

Co-authored-by: James <james@eli.cx>
2026-06-19 14:49:29 +01:00
Alexander Lichter 388b5c3efb feat(benchmarks): track server bundle sizes (#2173) 2026-06-19 13:23:11 +01:00
James Anderson 53e33babe2 fix(perf): ensure full profiles exist (#2175) 2026-06-19 12:35:08 +01:00
James Anderson 51b2c34958 fix(perf): allow publisher PR comments (#2174) 2026-06-19 11:43:38 +01:00
James Anderson 715ed317ed fix(perf): preserve permissioned cache roots (#2171)
* fix(perf): preserve permissioned cache roots

* fix(perf): run trusted same-repo harness

* fix(perf): ignore reaped benchmark zombies

* fix(perf): profile the build process tree

* fix(perf): wait for benchmark process cleanup

* fix(perf): profile the real build command

* fix(perf): profile the Vite Plus build entry

* fix(perf): avoid nested profiling sudo

* fix(perf): validate traces across profiles
2026-06-19 11:26:38 +01:00
James Anderson a2823aef7c fix(perf): allow isolated Vite task cache (#2170) 2026-06-19 09:26:28 +00:00
Alexander Lichter 44b0c9dcff chore(perf): pair pull request benchmark baselines (#2159)
* fix(perf): pair pull request benchmark baselines

* fix(perf): bootstrap benchmark fingerprint rollout

* fix(perf): harden paired benchmark publishing

* fix(perf): allow isolated build output creation

* fix(perf): transfer isolated build outputs

* fix(perf): verify isolated output permissions

* fix(perf): validate diagnostic trace categories

* fix(perf): retain trusted benchmark manifests

* fix(perf): close benchmark validation gaps

---------

Co-authored-by: James <james@eli.cx>
2026-06-19 10:10:22 +01:00
MaxtuneLee 42f8700f15 fix(router): enhance navigation with as mask for URL handling (#2076)
* fix(router): enhance navigation with `as` mask for URL handling

* fix(router): implement bracket-pattern interpolation for dynamic routes in Pages Router

* fix(router): preserve masked state in beforePopState

* fix(router): cover basepath navigation in ci

* docs(router): clarify navigation state invariants

* refactor(router): require complete history state

* refactor(router): share dynamic href interpolation

* test(router): cover localized masked navigation

* fix(router): keep interpolation internals private

---------

Co-authored-by: James <james@eli.cx>
2026-06-19 00:07:03 +01:00
James Anderson b2ea860284 fix(proxy): match Next.js file conventions (#2155)
* fix(proxy): match Next.js file conventions

* test(proxy): keep convention fixture out of workspace

* test(proxy): provide middleware path in handler fixture
2026-06-18 23:54:39 +01:00
Divanshu Chauhan 7487886b38 fix(prod-server): send headers-only for HEAD in sendCompressed (#1980) (#2058)
sendCompressed wrote the full body for every request. HEAD requests routed
through it (bot/crawler-buffered Pages HTML and Pages API routes) still
compressed and emitted a payload that Node then discards at the socket level.

Short-circuit with res.end() after writeHead when req.method is HEAD,
mirroring sendWebResponse. This skips spinning up a compressor for a body
that would be thrown away and keeps the buffered sender consistent with the
streamed and static-file senders, which already handle HEAD.

Co-authored-by: James <james@eli.cx>
2026-06-18 22:13:07 +00:00
Jerry Zhao 3e5f676666 refactor(shims): normalize the shim alias base to forward slashes on Windows (#2166) 2026-06-18 22:28:25 +01:00
dependabot[bot] a253b9e9e8 chore(deps): bump actions/checkout from 6.0.3 to 7.0.0 (#2161)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.3 to 7.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/df4cb1c069e1874edd31b4311f1884172cec0e10...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: James Anderson <james@eli.cx>
2026-06-18 21:18:42 +00:00
Jerry Zhao b352d671fa fix(rsc): resolve the app-rsc-handler shim to a forward-slash id on Windows (#2165) 2026-06-18 22:18:03 +01:00
Jerry Zhao 2b7faf1ec1 test(font-local): normalize the shim path fixture so the skip guard matches on Windows (#2164) 2026-06-18 22:17:46 +01:00