Skip to content

Commit

Permalink
Merge branch 'canary' into fix/router-filter-check
Browse files Browse the repository at this point in the history
  • Loading branch information
ijjk authored Jan 12, 2024
2 parents afd7330 + 61803f8 commit c139d46
Show file tree
Hide file tree
Showing 34 changed files with 807 additions and 470 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "14.0.5-canary.53"
"version": "14.0.5-canary.54"
}
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": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"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": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"description": "ESLint configuration used by Next.js.",
"main": "index.js",
"license": "MIT",
Expand All @@ -10,7 +10,7 @@
},
"homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config",
"dependencies": {
"@next/eslint-plugin-next": "14.0.5-canary.53",
"@next/eslint-plugin-next": "14.0.5-canary.54",
"@rushstack/eslint-patch": "^1.3.3",
"@typescript-eslint/parser": "^5.4.2 || ^6.0.0",
"eslint-import-resolver-node": "^0.3.6",
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": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"description": "ESLint plugin for Next.js.",
"main": "dist/index.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/font/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/font",
"version": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"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": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"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": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"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": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"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": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"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": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"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": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"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": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"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-swc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/swc",
"version": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"private": true,
"scripts": {
"clean": "node ../../scripts/rm.mjs 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": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"description": "The React Framework",
"main": "./dist/server/next.js",
"license": "MIT",
Expand Down Expand Up @@ -92,7 +92,7 @@
]
},
"dependencies": {
"@next/env": "14.0.5-canary.53",
"@next/env": "14.0.5-canary.54",
"@swc/helpers": "0.5.2",
"busboy": "1.6.0",
"caniuse-lite": "^1.0.30001406",
Expand Down Expand Up @@ -146,11 +146,11 @@
"@mswjs/interceptors": "0.23.0",
"@napi-rs/cli": "2.16.2",
"@napi-rs/triples": "1.1.0",
"@next/polyfill-module": "14.0.5-canary.53",
"@next/polyfill-nomodule": "14.0.5-canary.53",
"@next/react-dev-overlay": "14.0.5-canary.53",
"@next/react-refresh-utils": "14.0.5-canary.53",
"@next/swc": "14.0.5-canary.53",
"@next/polyfill-module": "14.0.5-canary.54",
"@next/polyfill-nomodule": "14.0.5-canary.54",
"@next/react-dev-overlay": "14.0.5-canary.54",
"@next/react-refresh-utils": "14.0.5-canary.54",
"@next/swc": "14.0.5-canary.54",
"@opentelemetry/api": "1.6.0",
"@playwright/test": "^1.35.1",
"@taskr/clear": "1.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,67 @@ function abortPendingCacheNode(
}
}

export function updateCacheNodeOnPopstateRestoration(
oldCacheNode: CacheNode,
routerState: FlightRouterState
) {
// A popstate navigation reads data from the local cache. It does not issue
// new network requests (unless the cache entries have been evicted). So, we
// update the cache to drop the prefetch data for any segment whose dynamic
// data was already received. This prevents an unnecessary flash back to PPR
// state during a back/forward navigation.
//
// This function clones the entire cache node tree and sets the `prefetchRsc`
// field to `null` to prevent it from being rendered. We can't mutate the node
// in place because this is a concurrent data structure.

const routerStateChildren = routerState[1]
const oldParallelRoutes = oldCacheNode.parallelRoutes
const newParallelRoutes = new Map(oldParallelRoutes)
for (let parallelRouteKey in routerStateChildren) {
const routerStateChild: FlightRouterState =
routerStateChildren[parallelRouteKey]
const segmentChild = routerStateChild[0]
const segmentKeyChild = createRouterCacheKey(segmentChild)
const oldSegmentMapChild = oldParallelRoutes.get(parallelRouteKey)
if (oldSegmentMapChild !== undefined) {
const oldCacheNodeChild = oldSegmentMapChild.get(segmentKeyChild)
if (oldCacheNodeChild !== undefined) {
const newCacheNodeChild = updateCacheNodeOnPopstateRestoration(
oldCacheNodeChild,
routerStateChild
)
const newSegmentMapChild = new Map(oldSegmentMapChild)
newSegmentMapChild.set(segmentKeyChild, newCacheNodeChild)
newParallelRoutes.set(parallelRouteKey, newSegmentMapChild)
}
}
}

// Only show prefetched data if the dynamic data is still pending.
//
// Tehnically, what we're actually checking is whether the dynamic network
// response was received. But since it's a streaming response, this does not
// mean that all the dynamic data has fully streamed in. It just means that
// _some_ of the dynamic data was received. But as a heuristic, we assume that
// the rest dynamic data will stream in quickly, so it's still better to skip
// the prefetch state.
const rsc = oldCacheNode.rsc
const shouldUsePrefetch = isDeferredRsc(rsc) && rsc.status === 'pending'

return {
lazyData: null,
rsc,
head: oldCacheNode.head,

prefetchHead: shouldUsePrefetch ? oldCacheNode.prefetchHead : null,
prefetchRsc: shouldUsePrefetch ? oldCacheNode.prefetchRsc : null,

// These are the cloned children we computed above
parallelRoutes: newParallelRoutes,
}
}

const DEFERRED = Symbol()

type PendingDeferredRsc = Promise<React.ReactNode> & {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
RestoreAction,
} from '../router-reducer-types'
import { extractPathFromFlightRouterState } from '../compute-changed-path'
import { updateCacheNodeOnPopstateRestoration } from '../ppr-navigations'

export function restoreReducer(
state: ReadonlyReducerState,
Expand All @@ -13,6 +14,15 @@ export function restoreReducer(
const { url, tree } = action
const href = createHrefFromUrl(url)

const oldCache = state.cache
const newCache = process.env.__NEXT_PPR
? // When PPR is enabled, we update the cache to drop the prefetch
// data for any segment whose dynamic data was already received. This
// prevents an unnecessary flash back to PPR state during a
// back/forward navigation.
updateCacheNodeOnPopstateRestoration(oldCache, tree)
: oldCache

return {
buildId: state.buildId,
// Set canonical url
Expand All @@ -24,7 +34,7 @@ export function restoreReducer(
preserveCustomHistoryState: true,
},
focusAndScrollRef: state.focusAndScrollRef,
cache: state.cache,
cache: newCache,
prefetchCache: state.prefetchCache,
// Restore provided tree
tree: tree,
Expand Down
2 changes: 1 addition & 1 deletion packages/react-dev-overlay/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/react-dev-overlay",
"version": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"description": "A development-only overlay for developing React applications.",
"repository": {
"url": "vercel/next.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-refresh-utils/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/react-refresh-utils",
"version": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"description": "An experimental package providing utilities for React Refresh.",
"repository": {
"url": "vercel/next.js",
Expand Down
4 changes: 2 additions & 2 deletions packages/third-parties/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/third-parties",
"version": "14.0.5-canary.53",
"version": "14.0.5-canary.54",
"repository": {
"url": "vercel/next.js",
"directory": "packages/third-parties"
Expand All @@ -26,7 +26,7 @@
"third-party-capital": "1.0.20"
},
"devDependencies": {
"next": "14.0.5-canary.53",
"next": "14.0.5-canary.54",
"outdent": "0.8.0",
"prettier": "2.5.1"
},
Expand Down
16 changes: 8 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ShouldFallbackThrowContainer } from './some-page/client'

export default function Root({ children }) {
return (
<html>
<body>
<ShouldFallbackThrowContainer>{children}</ShouldFallbackThrowContainer>
</body>
</html>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Link from 'next/link'

export default function Page() {
return (
<div>
<Link href="/some-page">Some page</Link>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use client'

import { Component, createContext, use, useState } from 'react'

const ShouldFallbackThrowContext = createContext(false)

export function ShouldFallbackThrowContainer({ children }) {
const [shouldFallbackThrow, setShouldFallbackThrow] = useState(false)
return (
<>
<label>
Throw if fallback appears
<input
id="should-fallback-throw"
type="checkbox"
checked={shouldFallbackThrow}
onChange={(e) => setShouldFallbackThrow(e.target.checked)}
/>
</label>
<ShouldFallbackThrowContext.Provider value={shouldFallbackThrow}>
<ErrorBoundary>{children}</ErrorBoundary>
</ShouldFallbackThrowContext.Provider>
</>
)
}

export function Fallback({ children }) {
if (use(ShouldFallbackThrowContext)) {
throw new Error('Unexpected fallback')
}
return children
}

class ErrorBoundary extends Component<{ children: React.ReactNode }> {
state = { error: null }
static getDerivedStateFromError(error) {
return { error }
}
render() {
if (this.state.error) {
return <div id="error">{this.state.error.message}</div>
}
return this.props.children
}
}
Loading

0 comments on commit c139d46

Please sign in to comment.