Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CacheNode.prefetchRsc field #59537

Merged
merged 1 commit into from
Dec 12, 2023
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
13 changes: 8 additions & 5 deletions packages/next/src/client/components/app-router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,14 @@ function HistoryUpdater({
return null
}

export const createEmptyCacheNode = () => ({
lazyData: null,
rsc: null,
parallelRoutes: new Map(),
})
export function createEmptyCacheNode(): CacheNode {
return {
lazyData: null,
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map(),
}
}

function useServerActionDispatcher(dispatch: React.Dispatch<ReducerActions>) {
const serverActionDispatcher: ServerActionDispatcher = useCallback(
Expand Down
4 changes: 4 additions & 0 deletions packages/next/src/client/components/layout-router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,9 @@ function InnerLayoutRouter({
// TODO-APP: remove ''
const refetchTree = walkAddRefetch(['', ...segmentPath], fullTree)

// TODO: Since this case always suspends indefinitely, and the only thing
// we're doing here is setting `lazyData`, it would be fine to mutate the
// current cache node (if it exists) rather than cloning it.
childNode = {
lazyData: fetchServerResponse(
new URL(url, location.origin),
Expand All @@ -361,6 +364,7 @@ function InnerLayoutRouter({
buildId
),
rsc: null,
prefetchRsc: childNode ? childNode.prefetchRsc : null,
head: childNode ? childNode.head : undefined,
parallelRoutes: childNode ? childNode.parallelRoutes : new Map(),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ export function applyFlightData(
if (flightDataPath.length === 3) {
const rsc = cacheNodeSeedData[2]
cache.rsc = rsc
// This is a PPR-only field. When PPR is enabled, we shouldn't hit
// this path during a navigation, but until PPR is fully implemented
// yet it's possible the existing node does have a non-null
// `prefetchRsc`. As an incremental step, we'll just de-opt to the
// old behavior — no PPR value.
cache.prefetchRsc = null
fillLazyItemsTillLeafWithHead(
cache,
existingCache,
Expand All @@ -31,6 +37,10 @@ export function applyFlightData(
} else {
// Copy rsc for the root node of the cache.
cache.rsc = existingCache.rsc
// This is a PPR-only field. Unlike the previous branch, since we're
// just cloning the existing cache node, we might as well keep the
// PPR value, if it exists.
cache.prefetchRsc = existingCache.prefetchRsc
cache.parallelRoutes = new Map(existingCache.parallelRoutes)
// Create a copy of the existing cache with the rsc applied.
fillCacheWithNewSubTreeData(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ describe('createInitialRouterState', () => {
const expectedCache: CacheNode = {
lazyData: null,
rsc: children,
prefetchRsc: null,
parallelRoutes: new Map([
[
'children',
Expand All @@ -73,6 +74,7 @@ describe('createInitialRouterState', () => {
{
lazyData: null,
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map(),
head: <title>Test</title>,
},
Expand All @@ -82,6 +84,7 @@ describe('createInitialRouterState', () => {
]),
lazyData: null,
rsc: null,
prefetchRsc: null,
},
],
]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export function createInitialRouterState({
const cache: CacheNode = {
lazyData: null,
rsc: rsc,
prefetchRsc: null,
// The cache gets seeded during the first render. `initialParallelRoutes` ensures the cache from the first render is there during the second render.
parallelRoutes: isServer ? new Map() : initialParallelRoutes,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ describe('fillCacheWithDataProperty', () => {
const cache: CacheNode = {
lazyData: null,
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map(),
}
const existingCache: CacheNode = {
lazyData: null,
rsc: <>Root layout</>,
prefetchRsc: null,
parallelRoutes: new Map([
[
'children',
Expand All @@ -38,6 +40,7 @@ describe('fillCacheWithDataProperty', () => {
{
lazyData: null,
rsc: <>Linking</>,
prefetchRsc: null,
parallelRoutes: new Map([
[
'children',
Expand All @@ -47,6 +50,7 @@ describe('fillCacheWithDataProperty', () => {
{
lazyData: null,
rsc: <>Page</>,
prefetchRsc: null,
parallelRoutes: new Map(),
},
],
Expand Down Expand Up @@ -76,23 +80,27 @@ describe('fillCacheWithDataProperty', () => {
"" => {
"lazyData": null,
"parallelRoutes": Map {},
"prefetchRsc": null,
"rsc": <React.Fragment>
Page
</React.Fragment>,
},
},
},
"prefetchRsc": null,
"rsc": <React.Fragment>
Linking
</React.Fragment>,
},
"dashboard" => {
"lazyData": Promise {},
"parallelRoutes": Map {},
"prefetchRsc": null,
"rsc": null,
},
},
},
"prefetchRsc": null,
"rsc": null,
}
`)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export function fillCacheWithDataProperty(
childSegmentMap.set(cacheKey, {
lazyData: fetchResponse(),
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map(),
})
}
Expand All @@ -52,6 +53,7 @@ export function fillCacheWithDataProperty(
childSegmentMap.set(cacheKey, {
lazyData: fetchResponse(),
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map(),
})
}
Expand All @@ -62,6 +64,7 @@ export function fillCacheWithDataProperty(
childCacheNode = {
lazyData: childCacheNode.lazyData,
rsc: childCacheNode.rsc,
prefetchRsc: childCacheNode.prefetchRsc,
parallelRoutes: new Map(childCacheNode.parallelRoutes),
} as CacheNode
childSegmentMap.set(cacheKey, childCacheNode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ describe('fillCacheWithNewSubtreeData', () => {
const cache: CacheNode = {
lazyData: null,
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map(),
}
const existingCache: CacheNode = {
lazyData: null,
rsc: <>Root layout</>,
prefetchRsc: null,
parallelRoutes: new Map([
[
'children',
Expand All @@ -43,6 +45,7 @@ describe('fillCacheWithNewSubtreeData', () => {
{
lazyData: null,
rsc: <>Linking</>,
prefetchRsc: null,
parallelRoutes: new Map([
[
'children',
Expand All @@ -52,6 +55,7 @@ describe('fillCacheWithNewSubtreeData', () => {
{
lazyData: null,
rsc: <>Page</>,
prefetchRsc: null,
parallelRoutes: new Map(),
},
],
Expand Down Expand Up @@ -79,6 +83,7 @@ describe('fillCacheWithNewSubtreeData', () => {
const expectedCache: CacheNode = {
lazyData: null,
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map([
[
'children',
Expand All @@ -88,6 +93,7 @@ describe('fillCacheWithNewSubtreeData', () => {
{
lazyData: null,
rsc: <>Linking</>,
prefetchRsc: null,
parallelRoutes: new Map([
[
'children',
Expand All @@ -98,6 +104,7 @@ describe('fillCacheWithNewSubtreeData', () => {
{
lazyData: null,
rsc: <>Page</>,
prefetchRsc: null,
parallelRoutes: new Map(),
},
],
Expand All @@ -114,6 +121,7 @@ describe('fillCacheWithNewSubtreeData', () => {
{
lazyData: null,
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map(),
head: (
<>
Expand All @@ -126,6 +134,7 @@ describe('fillCacheWithNewSubtreeData', () => {
],
]),
rsc: <h1>SubTreeData Injected!</h1>,
prefetchRsc: null,
},
],
]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export function fillCacheWithNewSubTreeData(
childCacheNode = {
lazyData: null,
rsc,
prefetchRsc: null,
// Ensure segments other than the one we got data for are preserved.
parallelRoutes: existingChildCacheNode
? new Map(existingChildCacheNode.parallelRoutes)
Expand Down Expand Up @@ -88,6 +89,7 @@ export function fillCacheWithNewSubTreeData(
childCacheNode = {
lazyData: childCacheNode.lazyData,
rsc: childCacheNode.rsc,
prefetchRsc: childCacheNode.prefetchRsc,
parallelRoutes: new Map(childCacheNode.parallelRoutes),
} as CacheNode
childSegmentMap.set(cacheKey, childCacheNode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,13 @@ describe('fillLazyItemsTillLeafWithHead', () => {
const cache: CacheNode = {
lazyData: null,
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map(),
}
const existingCache: CacheNode = {
lazyData: null,
rsc: <>Root layout</>,
prefetchRsc: null,
parallelRoutes: new Map([
[
'children',
Expand All @@ -52,6 +54,7 @@ describe('fillLazyItemsTillLeafWithHead', () => {
{
lazyData: null,
rsc: <>Linking</>,
prefetchRsc: null,
parallelRoutes: new Map([
[
'children',
Expand All @@ -61,6 +64,7 @@ describe('fillLazyItemsTillLeafWithHead', () => {
{
lazyData: null,
rsc: <>Page</>,
prefetchRsc: null,
parallelRoutes: new Map(),
},
],
Expand Down Expand Up @@ -94,6 +98,7 @@ describe('fillLazyItemsTillLeafWithHead', () => {
const expectedCache: CacheNode = {
lazyData: null,
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map([
[
'children',
Expand All @@ -103,6 +108,7 @@ describe('fillLazyItemsTillLeafWithHead', () => {
{
lazyData: null,
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map([
[
'children',
Expand All @@ -120,6 +126,7 @@ describe('fillLazyItemsTillLeafWithHead', () => {
{
lazyData: null,
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map(),
head: (
<>
Expand All @@ -132,13 +139,15 @@ describe('fillLazyItemsTillLeafWithHead', () => {
],
]),
rsc: null,
prefetchRsc: null,
},
],
[
'',
{
lazyData: null,
rsc: <>Page</>,
prefetchRsc: null,
parallelRoutes: new Map(),
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ export function fillLazyItemsTillLeafWithHead(
newCacheNode = {
lazyData: null,
rsc: seedNode,
// This is a PPR-only field. When PPR is enabled, we shouldn't hit
// this path during a navigation, but until PPR is fully implemented
// yet it's possible the existing node does have a non-null
// `prefetchRsc`. As an incremental step, we'll just de-opt to the
// old behavior — no PPR value.
prefetchRsc: null,
parallelRoutes: new Map(existingCacheNode?.parallelRoutes),
}
} else if (wasPrefetched && existingCacheNode) {
Expand All @@ -61,6 +67,10 @@ export function fillLazyItemsTillLeafWithHead(
newCacheNode = {
lazyData: existingCacheNode.lazyData,
rsc: existingCacheNode.rsc,
// This is a PPR-only field. Unlike the previous branch, since we're
// just cloning the existing cache node, we might as well keep the
// PPR value, if it exists.
prefetchRsc: existingCacheNode.prefetchRsc,
parallelRoutes: new Map(existingCacheNode.parallelRoutes),
} as CacheNode
} else {
Expand All @@ -69,6 +79,7 @@ export function fillLazyItemsTillLeafWithHead(
newCacheNode = {
lazyData: null,
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map(existingCacheNode?.parallelRoutes),
}
}
Expand Down Expand Up @@ -97,6 +108,7 @@ export function fillLazyItemsTillLeafWithHead(
newCacheNode = {
lazyData: null,
rsc: seedNode,
prefetchRsc: null,
parallelRoutes: new Map(),
}
} else {
Expand All @@ -105,6 +117,7 @@ export function fillLazyItemsTillLeafWithHead(
newCacheNode = {
lazyData: null,
rsc: null,
prefetchRsc: null,
parallelRoutes: new Map(),
}
}
Expand Down
Loading
Loading