Skip to content

Commit 52fcc59

Browse files
authoredApr 21, 2023
Revert "app-router: new client-side cache semantics" (#48678)
Reverts #48383 fix NEXT-1011 revert and re-land later
1 parent f779f10 commit 52fcc59

27 files changed

+271
-951
lines changed
 

‎packages/next/src/client/components/app-router.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import {
2525
ACTION_REFRESH,
2626
ACTION_RESTORE,
2727
ACTION_SERVER_PATCH,
28-
PrefetchKind,
2928
} from './router-reducer/router-reducer-types'
3029
import { createHrefFromUrl } from './router-reducer/create-href-from-url'
3130
import {
@@ -235,7 +234,7 @@ function Router({
235234
const routerInstance: AppRouterInstance = {
236235
back: () => window.history.back(),
237236
forward: () => window.history.forward(),
238-
prefetch: async (href, options) => {
237+
prefetch: async (href) => {
239238
// If prefetch has already been triggered, don't trigger it again.
240239
if (isBot(window.navigator.userAgent)) {
241240
return
@@ -245,12 +244,12 @@ function Router({
245244
if (isExternalURL(url)) {
246245
return
247246
}
247+
248248
// @ts-ignore startTransition exists
249249
React.startTransition(() => {
250250
dispatch({
251251
type: ACTION_PREFETCH,
252252
url,
253-
kind: options?.kind ?? PrefetchKind.FULL,
254253
})
255254
})
256255
},

‎packages/next/src/client/components/layout-router.tsx

+12-8
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,16 @@ function InnerLayoutRouter({
277277
// TODO-APP: verify if this can be null based on user code
278278
childProp.current !== null
279279
) {
280-
if (!childNode) {
280+
if (childNode) {
281+
if (childNode.status === CacheStates.LAZY_INITIALIZED) {
282+
// @ts-expect-error we're changing it's type!
283+
childNode.status = CacheStates.READY
284+
// @ts-expect-error
285+
childNode.subTreeData = childProp.current
286+
// Mutates the prop in order to clean up the memory associated with the subTreeData as it is now part of the cache.
287+
childProp.current = null
288+
}
289+
} else {
281290
// Add the segment's subTreeData to the cache.
282291
// This writes to the cache when there is no item in the cache yet. It never *overwrites* existing cache items which is why it's safe in concurrent mode.
283292
childNodes.set(cacheKey, {
@@ -286,15 +295,10 @@ function InnerLayoutRouter({
286295
subTreeData: childProp.current,
287296
parallelRoutes: new Map(),
288297
})
298+
// Mutates the prop in order to clean up the memory associated with the subTreeData as it is now part of the cache.
299+
childProp.current = null
289300
// In the above case childNode was set on childNodes, so we have to get it from the cacheNodes again.
290301
childNode = childNodes.get(cacheKey)
291-
} else {
292-
if (childNode.status === CacheStates.LAZY_INITIALIZED) {
293-
// @ts-expect-error we're changing it's type!
294-
childNode.status = CacheStates.READY
295-
// @ts-expect-error
296-
childNode.subTreeData = childProp.current
297-
}
298302
}
299303
}
300304

‎packages/next/src/client/components/router-reducer/apply-flight-data.ts

+2-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export function applyFlightData(
77
existingCache: CacheNode,
88
cache: CacheNode,
99
flightDataPath: FlightDataPath,
10-
wasPrefetched: boolean = false
10+
wasPrefetched?: boolean
1111
): boolean {
1212
// The one before last item is the router state tree patch
1313
const [treePatch, subTreeData, head] = flightDataPath.slice(-3)
@@ -33,12 +33,7 @@ export function applyFlightData(
3333
cache.subTreeData = existingCache.subTreeData
3434
cache.parallelRoutes = new Map(existingCache.parallelRoutes)
3535
// Create a copy of the existing cache with the subTreeData applied.
36-
fillCacheWithNewSubTreeData(
37-
cache,
38-
existingCache,
39-
flightDataPath,
40-
wasPrefetched
41-
)
36+
fillCacheWithNewSubTreeData(cache, existingCache, flightDataPath)
4237
}
4338

4439
return true

‎packages/next/src/client/components/router-reducer/fetch-server-response.ts

+3-10
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
} from '../app-router-headers'
1515
import { urlToUrlWithoutFlightMarker } from '../app-router'
1616
import { callServer } from '../../app-call-server'
17-
import { PrefetchKind } from './router-reducer-types'
1817

1918
/**
2019
* Fetch the flight data for the provided url. Takes in the current router state to decide what to render server-side.
@@ -24,7 +23,7 @@ export async function fetchServerResponse(
2423
url: URL,
2524
flightRouterState: FlightRouterState,
2625
nextUrl: string | null,
27-
prefetchKind?: PrefetchKind
26+
prefetch?: true
2827
): Promise<[FlightData: FlightData, canonicalUrlOverride: URL | undefined]> {
2928
const headers: {
3029
[RSC]: '1'
@@ -37,14 +36,8 @@ export async function fetchServerResponse(
3736
// Provide the current router state
3837
[NEXT_ROUTER_STATE_TREE]: JSON.stringify(flightRouterState),
3938
}
40-
41-
/**
42-
* Three cases:
43-
* - `prefetchKind` is `undefined`, it means it's a normal navigation, so we want to prefetch the page data fully
44-
* - `prefetchKind` is `full` - we want to prefetch the whole page so same as above
45-
* - `prefetchKind` is `auto` - if the page is dynamic, prefetch the page data partially, if static prefetch the page data fully
46-
*/
47-
if (prefetchKind === PrefetchKind.AUTO) {
39+
if (prefetch) {
40+
// Enable prefetch response
4841
headers[NEXT_ROUTER_PREFETCH] = '1'
4942
}
5043

‎packages/next/src/client/components/router-reducer/fill-cache-with-data-property.ts

+12-19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import { FlightSegmentPath } from '../../../server/app-render/types'
21
import { CacheNode, CacheStates } from '../../../shared/lib/app-router-context'
3-
import { createRouterCacheKey } from './create-router-cache-key'
42
import { fetchServerResponse } from './fetch-server-response'
53

64
/**
@@ -9,24 +7,19 @@ import { fetchServerResponse } from './fetch-server-response'
97
export function fillCacheWithDataProperty(
108
newCache: CacheNode,
119
existingCache: CacheNode,
12-
flightSegmentPath: FlightSegmentPath,
13-
fetchResponse: () => ReturnType<typeof fetchServerResponse>,
14-
bailOnParallelRoutes: boolean = false
10+
segments: string[],
11+
fetchResponse: () => ReturnType<typeof fetchServerResponse>
1512
): { bailOptimistic: boolean } | undefined {
16-
const isLastEntry = flightSegmentPath.length <= 2
13+
const isLastEntry = segments.length === 1
1714

18-
const [parallelRouteKey, segment] = flightSegmentPath
19-
const cacheKey = createRouterCacheKey(segment)
15+
const parallelRouteKey = 'children'
16+
const [segment] = segments
2017

2118
const existingChildSegmentMap =
2219
existingCache.parallelRoutes.get(parallelRouteKey)
2320

24-
if (
25-
!existingChildSegmentMap ||
26-
(bailOnParallelRoutes && existingCache.parallelRoutes.size > 1)
27-
) {
21+
if (!existingChildSegmentMap) {
2822
// Bailout because the existing cache does not have the path to the leaf node
29-
// or the existing cache has multiple parallel routes
3023
// Will trigger lazy fetch in layout-router because of missing segment
3124
return { bailOptimistic: true }
3225
}
@@ -38,8 +31,8 @@ export function fillCacheWithDataProperty(
3831
newCache.parallelRoutes.set(parallelRouteKey, childSegmentMap)
3932
}
4033

41-
const existingChildCacheNode = existingChildSegmentMap.get(cacheKey)
42-
let childCacheNode = childSegmentMap.get(cacheKey)
34+
const existingChildCacheNode = existingChildSegmentMap.get(segment)
35+
let childCacheNode = childSegmentMap.get(segment)
4336

4437
// In case of last segment start off the fetch at this level and don't copy further down.
4538
if (isLastEntry) {
@@ -48,7 +41,7 @@ export function fillCacheWithDataProperty(
4841
!childCacheNode.data ||
4942
childCacheNode === existingChildCacheNode
5043
) {
51-
childSegmentMap.set(cacheKey, {
44+
childSegmentMap.set(segment, {
5245
status: CacheStates.DATA_FETCH,
5346
data: fetchResponse(),
5447
subTreeData: null,
@@ -61,7 +54,7 @@ export function fillCacheWithDataProperty(
6154
if (!childCacheNode || !existingChildCacheNode) {
6255
// Start fetch in the place where the existing cache doesn't have the data yet.
6356
if (!childCacheNode) {
64-
childSegmentMap.set(cacheKey, {
57+
childSegmentMap.set(segment, {
6558
status: CacheStates.DATA_FETCH,
6659
data: fetchResponse(),
6760
subTreeData: null,
@@ -78,13 +71,13 @@ export function fillCacheWithDataProperty(
7871
subTreeData: childCacheNode.subTreeData,
7972
parallelRoutes: new Map(childCacheNode.parallelRoutes),
8073
} as CacheNode
81-
childSegmentMap.set(cacheKey, childCacheNode)
74+
childSegmentMap.set(segment, childCacheNode)
8275
}
8376

8477
return fillCacheWithDataProperty(
8578
childCacheNode,
8679
existingChildCacheNode,
87-
flightSegmentPath.slice(2),
80+
segments.slice(1),
8881
fetchResponse
8982
)
9083
}

‎packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ describe('fillCacheWithNewSubtreeData', () => {
7878
// Mirrors the way router-reducer values are passed in.
7979
const flightDataPath = flightData[0]
8080

81-
fillCacheWithNewSubTreeData(cache, existingCache, flightDataPath, false)
81+
fillCacheWithNewSubTreeData(cache, existingCache, flightDataPath)
8282

8383
const expectedCache: CacheNode = {
8484
data: null,

‎packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ import { createRouterCacheKey } from './create-router-cache-key'
1010
export function fillCacheWithNewSubTreeData(
1111
newCache: CacheNode,
1212
existingCache: CacheNode,
13-
flightDataPath: FlightDataPath,
14-
wasPrefetched?: boolean
13+
flightDataPath: FlightDataPath
1514
): void {
1615
const isLastEntry = flightDataPath.length <= 5
1716
const [parallelRouteKey, segment] = flightDataPath
@@ -64,8 +63,7 @@ export function fillCacheWithNewSubTreeData(
6463
childCacheNode,
6564
existingChildCacheNode,
6665
flightDataPath[2],
67-
flightDataPath[4],
68-
wasPrefetched
66+
flightDataPath[4]
6967
)
7068

7169
childSegmentMap.set(cacheKey, childCacheNode)
@@ -92,7 +90,6 @@ export function fillCacheWithNewSubTreeData(
9290
fillCacheWithNewSubTreeData(
9391
childCacheNode,
9492
existingChildCacheNode,
95-
flightDataPath.slice(2),
96-
wasPrefetched
93+
flightDataPath.slice(2)
9794
)
9895
}

‎packages/next/src/client/components/router-reducer/get-prefetch-cache-entry-status.ts

-40
This file was deleted.

‎packages/next/src/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ describe('invalidateCacheBelowFlightSegmentPath', () => {
8686
// @ts-expect-error TODO-APP: investigate why this is not a TS error in router-reducer.
8787
cache.subTreeData = existingCache.subTreeData
8888
// Create a copy of the existing cache with the subTreeData applied.
89-
fillCacheWithNewSubTreeData(cache, existingCache, flightDataPath, false)
89+
fillCacheWithNewSubTreeData(cache, existingCache, flightDataPath)
9090

9191
// Invalidate the cache below the flight segment path. This should remove the 'about' node.
9292
invalidateCacheBelowFlightSegmentPath(

‎packages/next/src/client/components/router-reducer/reducers/navigate-reducer.test.tsx

-5
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ import {
8080
ACTION_NAVIGATE,
8181
ACTION_PREFETCH,
8282
PrefetchAction,
83-
PrefetchKind,
8483
} from '../router-reducer-types'
8584
import { navigateReducer } from './navigate-reducer'
8685
import { prefetchReducer } from './prefetch-reducer'
@@ -1006,7 +1005,6 @@ describe('navigateReducer', () => {
10061005
const prefetchAction: PrefetchAction = {
10071006
type: ACTION_PREFETCH,
10081007
url,
1009-
kind: PrefetchKind.AUTO,
10101008
}
10111009

10121010
const state = createInitialRouterState({
@@ -1088,9 +1086,6 @@ describe('navigateReducer', () => {
10881086
'/linking/about',
10891087
{
10901088
data: record,
1091-
kind: PrefetchKind.AUTO,
1092-
lastUsedTime: null,
1093-
prefetchTime: expect.any(Number),
10941089
treeAtTimeOfPrefetch: [
10951090
'',
10961091
{

0 commit comments

Comments
 (0)
Please sign in to comment.