Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "16.2.0-canary.55"
"version": "16.2.0-canary.56"
}
32 changes: 16 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@
"eslint-plugin-jsdoc": "48.0.4",
"eslint-plugin-mdx": "3.1.5",
"eslint-plugin-react": "7.37.0",
"eslint-plugin-react-hooks": "0.0.0-experimental-2ba30655-20260219",
"eslint-plugin-react-hooks": "0.0.0-experimental-ab18f33d-20260220",
"event-stream": "4.0.1",
"execa": "2.0.3",
"expect": "29.7.0",
Expand Down Expand Up @@ -261,16 +261,16 @@
"pretty-ms": "7.0.0",
"random-seed": "0.3.0",
"react": "19.0.0",
"react-builtin": "npm:react@19.3.0-canary-2ba30655-20260219",
"react-builtin": "npm:react@19.3.0-canary-ab18f33d-20260220",
"react-dom": "19.0.0",
"react-dom-builtin": "npm:react-dom@19.3.0-canary-2ba30655-20260219",
"react-dom-experimental-builtin": "npm:react-dom@0.0.0-experimental-2ba30655-20260219",
"react-experimental-builtin": "npm:react@0.0.0-experimental-2ba30655-20260219",
"react-is-builtin": "npm:react-is@19.3.0-canary-2ba30655-20260219",
"react-server-dom-turbopack": "19.3.0-canary-2ba30655-20260219",
"react-server-dom-turbopack-experimental": "npm:react-server-dom-turbopack@0.0.0-experimental-2ba30655-20260219",
"react-server-dom-webpack": "19.3.0-canary-2ba30655-20260219",
"react-server-dom-webpack-experimental": "npm:react-server-dom-webpack@0.0.0-experimental-2ba30655-20260219",
"react-dom-builtin": "npm:react-dom@19.3.0-canary-ab18f33d-20260220",
"react-dom-experimental-builtin": "npm:react-dom@0.0.0-experimental-ab18f33d-20260220",
"react-experimental-builtin": "npm:react@0.0.0-experimental-ab18f33d-20260220",
"react-is-builtin": "npm:react-is@19.3.0-canary-ab18f33d-20260220",
"react-server-dom-turbopack": "19.3.0-canary-ab18f33d-20260220",
"react-server-dom-turbopack-experimental": "npm:react-server-dom-turbopack@0.0.0-experimental-ab18f33d-20260220",
"react-server-dom-webpack": "19.3.0-canary-ab18f33d-20260220",
"react-server-dom-webpack-experimental": "npm:react-server-dom-webpack@0.0.0-experimental-ab18f33d-20260220",
"react-ssr-prepass": "1.0.8",
"react-virtualized": "9.22.3",
"relay-compiler": "13.0.2",
Expand All @@ -280,8 +280,8 @@
"resolve-from": "5.0.0",
"sass": "1.54.0",
"satori": "0.15.2",
"scheduler-builtin": "npm:scheduler@0.28.0-canary-2ba30655-20260219",
"scheduler-experimental-builtin": "npm:scheduler@0.0.0-experimental-2ba30655-20260219",
"scheduler-builtin": "npm:scheduler@0.28.0-canary-ab18f33d-20260220",
"scheduler-experimental-builtin": "npm:scheduler@0.0.0-experimental-ab18f33d-20260220",
"seedrandom": "3.0.5",
"semver": "7.3.7",
"serve-handler": "6.1.6",
Expand Down Expand Up @@ -326,10 +326,10 @@
"@types/react-dom": "19.2.3",
"@types/retry": "0.12.0",
"jest-snapshot": "30.0.0-alpha.6",
"react": "19.3.0-canary-2ba30655-20260219",
"react-dom": "19.3.0-canary-2ba30655-20260219",
"react-is": "19.3.0-canary-2ba30655-20260219",
"scheduler": "0.28.0-canary-2ba30655-20260219"
"react": "19.3.0-canary-ab18f33d-20260220",
"react-dom": "19.3.0-canary-ab18f33d-20260220",
"react-is": "19.3.0-canary-ab18f33d-20260220",
"scheduler": "0.28.0-canary-ab18f33d-20260220"
},
"packageExtensions": {
"eslint-plugin-react-hooks@0.0.0-experimental-6de32a5a-20250822": {
Expand Down
2 changes: 1 addition & 1 deletion packages/create-next-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-next-app",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"keywords": [
"react",
"next",
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint-config-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-config-next",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"description": "ESLint configuration used by Next.js.",
"license": "MIT",
"repository": {
Expand All @@ -12,7 +12,7 @@
"dist"
],
"dependencies": {
"@next/eslint-plugin-next": "16.2.0-canary.55",
"@next/eslint-plugin-next": "16.2.0-canary.56",
"eslint-import-resolver-node": "^0.3.6",
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-import": "^2.32.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-internal/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@next/eslint-plugin-internal",
"private": true,
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"description": "ESLint plugin for working on Next.js.",
"exports": {
".": "./src/eslint-plugin-internal.js"
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/eslint-plugin-next",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"description": "ESLint plugin for Next.js.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/font/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@next/font",
"private": true,
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"repository": {
"url": "vercel/next.js",
"directory": "packages/font"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-bundle-analyzer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/bundle-analyzer",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"main": "index.js",
"types": "index.d.ts",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-codemod/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/codemod",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"license": "MIT",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-env/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/env",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-mdx/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/mdx",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-storybook/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-storybook",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-storybook"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-module/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-module",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)",
"main": "dist/polyfill-module.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-nomodule/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-nomodule",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"description": "A polyfill for non-dead, nomodule browsers.",
"main": "dist/polyfill-nomodule.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-routing/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/routing",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-rspack/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next-rspack",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-rspack"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-swc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/swc",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"private": true,
"files": [
"native/"
Expand Down
14 changes: 7 additions & 7 deletions packages/next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next",
"version": "16.2.0-canary.55",
"version": "16.2.0-canary.56",
"description": "The React Framework",
"main": "./dist/server/next.js",
"license": "MIT",
Expand Down Expand Up @@ -97,7 +97,7 @@
]
},
"dependencies": {
"@next/env": "16.2.0-canary.55",
"@next/env": "16.2.0-canary.56",
"@swc/helpers": "0.5.15",
"baseline-browser-mapping": "^2.9.19",
"caniuse-lite": "^1.0.30001579",
Expand Down Expand Up @@ -162,11 +162,11 @@
"@modelcontextprotocol/sdk": "1.18.1",
"@mswjs/interceptors": "0.23.0",
"@napi-rs/triples": "1.2.0",
"@next/font": "16.2.0-canary.55",
"@next/polyfill-module": "16.2.0-canary.55",
"@next/polyfill-nomodule": "16.2.0-canary.55",
"@next/react-refresh-utils": "16.2.0-canary.55",
"@next/swc": "16.2.0-canary.55",
"@next/font": "16.2.0-canary.56",
"@next/polyfill-module": "16.2.0-canary.56",
"@next/polyfill-nomodule": "16.2.0-canary.56",
"@next/react-refresh-utils": "16.2.0-canary.56",
"@next/swc": "16.2.0-canary.56",
"@opentelemetry/api": "1.6.0",
"@playwright/test": "1.51.1",
"@rspack/core": "1.6.7",
Expand Down
39 changes: 26 additions & 13 deletions packages/next/src/client/components/segment-cache/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
import {
NEXT_DID_POSTPONE_HEADER,
NEXT_INSTANT_PREFETCH_HEADER,
NEXT_IS_PRERENDER_HEADER,
NEXT_ROUTER_PREFETCH_HEADER,
NEXT_ROUTER_SEGMENT_PREFETCH_HEADER,
NEXT_ROUTER_STALE_TIME_HEADER,
Expand Down Expand Up @@ -2015,14 +2014,9 @@ export async function fetchSegmentPrefetchesUsingDynamicRequest(

let isResponsePartial = false
let responseBody = response.body

// For dynamic runtime prefetches, strip the leading isPartial byte before
// passing the stream to Flight. Static responses (served from cache) don't
// have the byte. We detect them via NEXT_IS_PRERENDER_HEADER.
if (
fetchStrategy === FetchStrategy.PPRRuntime &&
!response.headers.get(NEXT_IS_PRERENDER_HEADER)
) {
// For runtime prefetches, strip the leading isPartial byte before passing
// the stream to Flight.
if (fetchStrategy === FetchStrategy.PPRRuntime) {
const stripped = await stripIsPartialByte(responseBody)
isResponsePartial = stripped.isPartial
responseBody = stripped.stream
Expand Down Expand Up @@ -2645,8 +2639,17 @@ async function getStaleAt(
}

/**
* Strips the leading isPartial byte from a runtime prefetch response stream.
* Returns the remaining stream and whether the response is partial.
* Checks for and strips the leading isPartial byte from a runtime prefetch
* response stream. If the first byte is a recognized marker ('~' for partial,
* '#' for complete), it is stripped and isPartial is set accordingly. If the
* first byte is not a recognized marker (e.g. for static responses that were
* not generated by the runtime prefetch codepath), the stream is returned
* intact with isPartial set to false.
*
* This is safe because the marker bytes (0x7e '~', 0x23 '#') cannot appear as
* the first byte of a valid RSC Flight response. Flight rows start with either
* a row ID (a hex character) or ':' (0x3a) for hint and debug chunks. Neither
* overlaps with the marker bytes.
*/
async function stripIsPartialByte(
stream: ReadableStream<Uint8Array>
Expand All @@ -2659,8 +2662,18 @@ async function stripIsPartialByte(
isPartial: false,
}
}
const isPartial = value[0] === 0x7e // ASCII '~'
const remainder = value.byteLength > 1 ? value.subarray(1) : null

const firstByte = value[0]
// '~' (0x7e) = partial, '#' (0x23) = complete
const hasMarker = firstByte === 0x7e || firstByte === 0x23
const isPartial = firstByte === 0x7e

const remainder = hasMarker
? value.byteLength > 1
? value.subarray(1)
: null
: value

return {
isPartial,
stream: new ReadableStream<Uint8Array>({
Expand Down
Loading
Loading