@@ -51,7 +51,7 @@ export type NavigationTask = {
5151}
5252
5353export type NavigationRequestAccumulation = {
54- scrollableSegments : Array < FlightSegmentPath >
54+ scrollableSegments : Array < FlightSegmentPath > | null
5555 separateRefreshUrls : Set < string > | null
5656}
5757
@@ -91,6 +91,8 @@ export function startPPRNavigation(
9191 oldRouterState : FlightRouterState ,
9292 newRouterState : FlightRouterState ,
9393 shouldRefreshDynamicData : boolean ,
94+ seedData : CacheNodeSeedData | null ,
95+ seedHead : HeadData | null ,
9496 prefetchData : CacheNodeSeedData | null ,
9597 prefetchHead : HeadData | null ,
9698 isPrefetchHeadPartial : boolean ,
@@ -108,6 +110,8 @@ export function startPPRNavigation(
108110 newRouterState ,
109111 shouldRefreshDynamicData ,
110112 didFindRootLayout ,
113+ seedData ,
114+ seedHead ,
111115 prefetchData ,
112116 prefetchHead ,
113117 isPrefetchHeadPartial ,
@@ -128,6 +132,8 @@ function updateCacheNodeOnNavigation(
128132 newRouterState : FlightRouterState ,
129133 shouldRefreshDynamicData : boolean ,
130134 didFindRootLayout : boolean ,
135+ seedData : CacheNodeSeedData | null ,
136+ seedHead : HeadData | null ,
131137 prefetchData : CacheNodeSeedData | null ,
132138 prefetchHead : HeadData | null ,
133139 isPrefetchHeadPartial : boolean ,
@@ -193,6 +199,8 @@ function updateCacheNodeOnNavigation(
193199 newRouterState ,
194200 oldCacheNode ,
195201 shouldRefreshDynamicData ,
202+ seedData ,
203+ seedHead ,
196204 prefetchData ,
197205 prefetchHead ,
198206 isPrefetchHeadPartial ,
@@ -216,6 +224,7 @@ function updateCacheNodeOnNavigation(
216224
217225 const newRouterStateChildren = newRouterState [ 1 ]
218226 const oldRouterStateChildren = oldRouterState [ 1 ]
227+ const seedDataChildren = seedData !== null ? seedData [ 1 ] : null
219228 const prefetchDataChildren = prefetchData !== null ? prefetchData [ 1 ] : null
220229
221230 // We're currently traversing the part of the tree that was also part of
@@ -264,6 +273,28 @@ function updateCacheNodeOnNavigation(
264273 // Reuse the existing CacheNode
265274 newCacheNode = reuseDynamicCacheNode ( oldCacheNode , newParallelRoutes )
266275 needsDynamicRequest = false
276+ } else if ( seedData !== null ) {
277+ // If this navigation was the result of an action, then check if the
278+ // server sent back data in the action response. We should favor using
279+ // that, rather than performing a separate request. This is both better
280+ // for performance and it's more likely to be consistent with any
281+ // writes that were just performed by the action, compared to a
282+ // separate request.
283+ const seedRsc = seedData [ 0 ]
284+ const seedLoading = seedData [ 2 ]
285+ const isSeedRscPartial = false
286+ const isSeedHeadPartial = seedHead === null
287+ newCacheNode = readCacheNodeFromSeedData (
288+ seedRsc ,
289+ seedLoading ,
290+ isSeedRscPartial ,
291+ seedHead ,
292+ isSeedHeadPartial ,
293+ isLeafSegment ,
294+ newParallelRoutes ,
295+ navigatedAt
296+ )
297+ needsDynamicRequest = isLeafSegment && isSeedHeadPartial
267298 } else if ( prefetchData !== null ) {
268299 // Consult the prefetch cache.
269300 const prefetchRsc = prefetchData [ 0 ]
@@ -357,12 +388,16 @@ function updateCacheNodeOnNavigation(
357388 oldParallelRoutes !== undefined
358389 ? oldParallelRoutes . get ( parallelRouteKey )
359390 : undefined
391+
392+ let seedDataChild : CacheNodeSeedData | void | null =
393+ seedDataChildren !== null ? seedDataChildren [ parallelRouteKey ] : null
360394 let prefetchDataChild : CacheNodeSeedData | void | null =
361395 prefetchDataChildren !== null
362396 ? prefetchDataChildren [ parallelRouteKey ]
363397 : null
364398
365399 let newSegmentChild = newRouterStateChild [ 0 ]
400+ let seedHeadChild = seedHead
366401 let prefetchHeadChild = prefetchHead
367402 let isPrefetchHeadPartialChild = isPrefetchHeadPartial
368403 if ( newSegmentChild === DEFAULT_SEGMENT_KEY ) {
@@ -377,6 +412,8 @@ function updateCacheNodeOnNavigation(
377412
378413 // Since we're switching to a different route tree, these are no
379414 // longer valid, because they correspond to the outer tree.
415+ seedDataChild = null
416+ seedHeadChild = null
380417 prefetchDataChild = null
381418 prefetchHeadChild = null
382419 isPrefetchHeadPartialChild = false
@@ -396,6 +433,8 @@ function updateCacheNodeOnNavigation(
396433 newRouterStateChild ,
397434 shouldRefreshDynamicData ,
398435 childDidFindRootLayout ,
436+ seedDataChild ?? null ,
437+ seedHeadChild ,
399438 prefetchDataChild ?? null ,
400439 prefetchHeadChild ,
401440 isPrefetchHeadPartialChild ,
@@ -421,7 +460,9 @@ function updateCacheNodeOnNavigation(
421460 taskChildren . set ( parallelRouteKey , taskChild )
422461 const newCacheNodeChild = taskChild . node
423462 if ( newCacheNodeChild !== null ) {
424- const newSegmentMapChild : ChildSegmentMap = new Map ( oldSegmentMapChild )
463+ const newSegmentMapChild : ChildSegmentMap = new Map (
464+ shouldRefreshDynamicData ? undefined : oldSegmentMapChild
465+ )
425466 newSegmentMapChild . set ( newSegmentKeyChild , newCacheNodeChild )
426467 newParallelRoutes . set ( parallelRouteKey , newSegmentMapChild )
427468 }
@@ -471,6 +512,8 @@ function createCacheNodeOnNavigation(
471512 newRouterState : FlightRouterState ,
472513 oldCacheNode : CacheNode | void ,
473514 shouldRefreshDynamicData : boolean ,
515+ seedData : CacheNodeSeedData | null ,
516+ seedHead : HeadData | null ,
474517 prefetchData : CacheNodeSeedData | null ,
475518 prefetchHead : HeadData | null ,
476519 isPrefetchHeadPartial : boolean ,
@@ -497,6 +540,7 @@ function createCacheNodeOnNavigation(
497540
498541 const newRouterStateChildren = newRouterState [ 1 ]
499542 const prefetchDataChildren = prefetchData !== null ? prefetchData [ 1 ] : null
543+ const seedDataChildren = seedData !== null ? seedData [ 1 ] : null
500544 const oldParallelRoutes =
501545 oldCacheNode !== undefined ? oldCacheNode . parallelRoutes : undefined
502546 const newParallelRoutes = new Map (
@@ -514,6 +558,9 @@ function createCacheNodeOnNavigation(
514558 // TODO: We should use a string to represent the segment path instead of
515559 // an array. We already use a string representation for the path when
516560 // accessing the Segment Cache, so we can use the same one.
561+ if ( accumulation . scrollableSegments === null ) {
562+ accumulation . scrollableSegments = [ ]
563+ }
517564 accumulation . scrollableSegments . push ( segmentPath )
518565 }
519566
@@ -534,6 +581,28 @@ function createCacheNodeOnNavigation(
534581 // Reuse the existing CacheNode
535582 newCacheNode = reuseDynamicCacheNode ( oldCacheNode , newParallelRoutes )
536583 needsDynamicRequest = false
584+ } else if ( seedData !== null ) {
585+ // If this navigation was the result of an action, then check if the
586+ // server sent back data in the action response. We should favor using
587+ // that, rather than performing a separate request. This is both better
588+ // for performance and it's more likely to be consistent with any
589+ // writes that were just performed by the action, compared to a
590+ // separate request.
591+ const seedRsc = seedData [ 0 ]
592+ const seedLoading = seedData [ 2 ]
593+ const isSeedRscPartial = false
594+ const isSeedHeadPartial = seedHead === null
595+ newCacheNode = readCacheNodeFromSeedData (
596+ seedRsc ,
597+ seedLoading ,
598+ isSeedRscPartial ,
599+ seedHead ,
600+ isSeedHeadPartial ,
601+ isLeafSegment ,
602+ newParallelRoutes ,
603+ navigatedAt
604+ )
605+ needsDynamicRequest = isLeafSegment && isSeedHeadPartial
537606 } else if ( prefetchData !== null ) {
538607 // Consult the prefetch cache.
539608 const prefetchRsc = prefetchData [ 0 ]
@@ -578,6 +647,8 @@ function createCacheNodeOnNavigation(
578647 oldParallelRoutes !== undefined
579648 ? oldParallelRoutes . get ( parallelRouteKey )
580649 : undefined
650+ const seedDataChild : CacheNodeSeedData | void | null =
651+ seedDataChildren !== null ? seedDataChildren [ parallelRouteKey ] : null
581652 const prefetchDataChild : CacheNodeSeedData | void | null =
582653 prefetchDataChildren !== null
583654 ? prefetchDataChildren [ parallelRouteKey ]
@@ -596,6 +667,8 @@ function createCacheNodeOnNavigation(
596667 newRouterStateChild ,
597668 oldCacheNodeChild ,
598669 shouldRefreshDynamicData ,
670+ seedDataChild ?? null ,
671+ seedHead ,
599672 prefetchDataChild ?? null ,
600673 prefetchHead ,
601674 isPrefetchHeadPartial ,
@@ -611,7 +684,9 @@ function createCacheNodeOnNavigation(
611684 taskChildren . set ( parallelRouteKey , taskChild )
612685 const newCacheNodeChild = taskChild . node
613686 if ( newCacheNodeChild !== null ) {
614- const newSegmentMapChild : ChildSegmentMap = new Map ( oldSegmentMapChild )
687+ const newSegmentMapChild : ChildSegmentMap = new Map (
688+ shouldRefreshDynamicData ? undefined : oldSegmentMapChild
689+ )
615690 newSegmentMapChild . set ( newSegmentKeyChild , newCacheNodeChild )
616691 newParallelRoutes . set ( parallelRouteKey , newSegmentMapChild )
617692 }
0 commit comments