@@ -290,6 +290,31 @@ export function createPatchedFetcher(
290
290
cacheSignal . beginRead ( )
291
291
}
292
292
293
+ const isStagedRenderingInDev = ! ! (
294
+ process . env . NODE_ENV === 'development' &&
295
+ workUnitStore &&
296
+ // eslint-disable-next-line no-restricted-syntax
297
+ workUnitStore . type === 'request' &&
298
+ // TODO: there's probably a cleaner way to detect this.
299
+ ( workUnitStore . prerenderResumeDataCache ||
300
+ workUnitStore . renderResumeDataCache )
301
+ )
302
+
303
+ const isFillingCachesInDev = ! ! (
304
+ isStagedRenderingInDev && workUnitStore . cacheSignal
305
+ )
306
+
307
+ const dynamicInDevStagedRendering = async ( ) => {
308
+ if ( isFillingCachesInDev ) {
309
+ // TODO(restart-on-cache-miss): block dynamic more effectively
310
+ await waitAtLeastOneReactRenderTask ( )
311
+ await waitAtLeastOneReactRenderTask ( )
312
+ } else if ( isStagedRenderingInDev ) {
313
+ // don't block, but delay
314
+ await waitAtLeastOneReactRenderTask ( )
315
+ }
316
+ }
317
+
293
318
const result = getTracer ( ) . trace (
294
319
isInternal ? NextNodeServerSpan . internalFetch : AppRenderSpan . fetch ,
295
320
{
@@ -557,6 +582,18 @@ export function createPatchedFetcher(
557
582
case 'prerender-ppr' :
558
583
case 'prerender-legacy' :
559
584
case 'request' :
585
+ if (
586
+ process . env . NODE_ENV === 'development' &&
587
+ isStagedRenderingInDev
588
+ ) {
589
+ if ( cacheSignal ) {
590
+ cacheSignal . endRead ( )
591
+ cacheSignal = null
592
+ }
593
+ // TODO(restart-on-cache-miss): block dynamic when filling caches
594
+ await dynamicInDevStagedRendering ( )
595
+ }
596
+ break
560
597
case 'cache' :
561
598
case 'private-cache' :
562
599
case 'unstable-cache' :
@@ -667,9 +704,21 @@ export function createPatchedFetcher(
667
704
workStore . route ,
668
705
'fetch()'
669
706
)
707
+ case 'request' :
708
+ if (
709
+ process . env . NODE_ENV === 'development' &&
710
+ isStagedRenderingInDev
711
+ ) {
712
+ if ( cacheSignal ) {
713
+ cacheSignal . endRead ( )
714
+ cacheSignal = null
715
+ }
716
+ // TODO(restart-on-cache-miss): block dynamic when filling caches
717
+ await dynamicInDevStagedRendering ( )
718
+ }
719
+ break
670
720
case 'prerender-ppr' :
671
721
case 'prerender-legacy' :
672
- case 'request' :
673
722
case 'cache' :
674
723
case 'private-cache' :
675
724
case 'unstable-cache' :
@@ -841,9 +890,23 @@ export function createPatchedFetcher(
841
890
normalizedRevalidate ,
842
891
handleUnlock
843
892
)
893
+ case 'request' :
894
+ if (
895
+ process . env . NODE_ENV === 'development' &&
896
+ isFillingCachesInDev
897
+ ) {
898
+ return createCachedPrerenderResponse (
899
+ res ,
900
+ cacheKey ,
901
+ incrementalCacheConfig ,
902
+ incrementalCache ,
903
+ normalizedRevalidate ,
904
+ handleUnlock
905
+ )
906
+ }
907
+ // fallthrough
844
908
case 'prerender-ppr' :
845
909
case 'prerender-legacy' :
846
- case 'request' :
847
910
case 'cache' :
848
911
case 'private-cache' :
849
912
case 'unstable-cache' :
@@ -913,9 +976,16 @@ export function createPatchedFetcher(
913
976
// here.
914
977
await waitAtLeastOneReactRenderTask ( )
915
978
break
979
+ case 'request' :
980
+ if (
981
+ process . env . NODE_ENV === 'development' &&
982
+ isStagedRenderingInDev
983
+ ) {
984
+ await dynamicInDevStagedRendering ( )
985
+ }
986
+ break
916
987
case 'prerender-ppr' :
917
988
case 'prerender-legacy' :
918
- case 'request' :
919
989
case 'cache' :
920
990
case 'private-cache' :
921
991
case 'unstable-cache' :
@@ -929,6 +999,7 @@ export function createPatchedFetcher(
929
999
await handleUnlock ( )
930
1000
} else {
931
1001
// in dev, incremental cache response will be null in case the browser adds `cache-control: no-cache` in the request headers
1002
+ // TODO: it seems like we also hit this after revalidates in dev?
932
1003
cacheReasonOverride = 'cache-control: no-cache (hard refresh)'
933
1004
}
934
1005
@@ -995,7 +1066,11 @@ export function createPatchedFetcher(
995
1066
}
996
1067
}
997
1068
998
- if ( workStore . isStaticGeneration && init && typeof init === 'object' ) {
1069
+ if (
1070
+ ( workStore . isStaticGeneration || isStagedRenderingInDev ) &&
1071
+ init &&
1072
+ typeof init === 'object'
1073
+ ) {
999
1074
const { cache } = init
1000
1075
1001
1076
// Delete `cache` property as Cloudflare Workers will throw an error
@@ -1017,9 +1092,21 @@ export function createPatchedFetcher(
1017
1092
workStore . route ,
1018
1093
'fetch()'
1019
1094
)
1095
+ case 'request' :
1096
+ if (
1097
+ process . env . NODE_ENV === 'development' &&
1098
+ isStagedRenderingInDev
1099
+ ) {
1100
+ if ( cacheSignal ) {
1101
+ cacheSignal . endRead ( )
1102
+ cacheSignal = null
1103
+ }
1104
+ // TODO(restart-on-cache-miss): block dynamic when filling caches
1105
+ await dynamicInDevStagedRendering ( )
1106
+ }
1107
+ break
1020
1108
case 'prerender-ppr' :
1021
1109
case 'prerender-legacy' :
1022
- case 'request' :
1023
1110
case 'cache' :
1024
1111
case 'private-cache' :
1025
1112
case 'unstable-cache' :
@@ -1055,6 +1142,14 @@ export function createPatchedFetcher(
1055
1142
'fetch()'
1056
1143
)
1057
1144
case 'request' :
1145
+ if (
1146
+ process . env . NODE_ENV === 'development' &&
1147
+ isStagedRenderingInDev
1148
+ ) {
1149
+ // TODO(restart-on-cache-miss): block dynamic when filling caches
1150
+ await dynamicInDevStagedRendering ( )
1151
+ }
1152
+ break
1058
1153
case 'cache' :
1059
1154
case 'private-cache' :
1060
1155
case 'unstable-cache' :
0 commit comments