@@ -25,6 +25,7 @@ import {
25
25
type CachedFetchData ,
26
26
} from '../response-cache'
27
27
import { waitAtLeastOneReactRenderTask } from '../../lib/scheduler'
28
+ import { cloneResponse } from './clone-response'
28
29
29
30
const isEdgeRuntime = process . env . NEXT_RUNTIME === 'edge'
30
31
@@ -676,20 +677,21 @@ export function createPatchedFetcher(
676
677
statusText : res . statusText ,
677
678
} )
678
679
} else {
680
+ const [ cloned1 , cloned2 ] = cloneResponse ( res )
681
+
679
682
// We are dynamically rendering including dev mode. We want to return
680
683
// the response to the caller as soon as possible because it might stream
681
684
// over a very long time.
682
- res
683
- . clone ( )
685
+ cloned1
684
686
. arrayBuffer ( )
685
687
. then ( async ( arrayBuffer ) => {
686
688
const bodyBuffer = Buffer . from ( arrayBuffer )
687
689
688
690
const fetchedData = {
689
- headers : Object . fromEntries ( res . headers . entries ( ) ) ,
691
+ headers : Object . fromEntries ( cloned1 . headers . entries ( ) ) ,
690
692
body : bodyBuffer . toString ( 'base64' ) ,
691
- status : res . status ,
692
- url : res . url ,
693
+ status : cloned1 . status ,
694
+ url : cloned1 . url ,
693
695
}
694
696
695
697
requestStore ?. serverComponentsHmrCache ?. set (
@@ -720,7 +722,7 @@ export function createPatchedFetcher(
720
722
)
721
723
. finally ( handleUnlock )
722
724
723
- return res
725
+ return cloned2
724
726
}
725
727
}
726
728
@@ -788,14 +790,23 @@ export function createPatchedFetcher(
788
790
if ( entry . isStale ) {
789
791
workStore . pendingRevalidates ??= { }
790
792
if ( ! workStore . pendingRevalidates [ cacheKey ] ) {
791
- workStore . pendingRevalidates [ cacheKey ] = doOriginalFetch (
792
- true
793
- )
794
- . catch ( console . error )
793
+ const pendingRevalidate = doOriginalFetch ( true )
794
+ . then ( async ( response ) => ( {
795
+ body : await response . arrayBuffer ( ) ,
796
+ headers : response . headers ,
797
+ status : response . status ,
798
+ statusText : response . statusText ,
799
+ } ) )
795
800
. finally ( ( ) => {
796
801
workStore . pendingRevalidates ??= { }
797
802
delete workStore . pendingRevalidates [ cacheKey || '' ]
798
803
} )
804
+
805
+ // Attach the empty catch here so we don't get a "unhandled
806
+ // promise rejection" warning.
807
+ pendingRevalidate . catch ( console . error )
808
+
809
+ workStore . pendingRevalidates [ cacheKey ] = pendingRevalidate
799
810
}
800
811
}
801
812
@@ -895,7 +906,7 @@ export function createPatchedFetcher(
895
906
if ( cacheKey && isForegroundRevalidate ) {
896
907
const pendingRevalidateKey = cacheKey
897
908
workStore . pendingRevalidates ??= { }
898
- const pendingRevalidate =
909
+ let pendingRevalidate =
899
910
workStore . pendingRevalidates [ pendingRevalidateKey ]
900
911
901
912
if ( pendingRevalidate ) {
@@ -920,21 +931,19 @@ export function createPatchedFetcher(
920
931
// available we construct manually cloned Response objects with the
921
932
// body as an ArrayBuffer. This will be resolvable in a microtask
922
933
// making it compatible with dynamicIO.
923
- const pendingResponse = doOriginalFetch ( true , cacheReasonOverride )
924
-
925
- const nextRevalidate = pendingResponse
926
- . then ( async ( response ) => {
927
- // Clone the response here. It'll run first because we attached
928
- // the resolve before we returned below. We have to clone it
929
- // because the original response is going to be consumed by
930
- // at a later point in time.
931
- const clonedResponse = response . clone ( )
932
-
934
+ const pendingResponse = doOriginalFetch (
935
+ true ,
936
+ cacheReasonOverride
937
+ ) . then ( cloneResponse )
938
+
939
+ pendingRevalidate = pendingResponse
940
+ . then ( async ( responses ) => {
941
+ const response = responses [ 0 ]
933
942
return {
934
- body : await clonedResponse . arrayBuffer ( ) ,
935
- headers : clonedResponse . headers ,
936
- status : clonedResponse . status ,
937
- statusText : clonedResponse . statusText ,
943
+ body : await response . arrayBuffer ( ) ,
944
+ headers : response . headers ,
945
+ status : response . status ,
946
+ statusText : response . statusText ,
938
947
}
939
948
} )
940
949
. finally ( ( ) => {
@@ -949,11 +958,11 @@ export function createPatchedFetcher(
949
958
950
959
// Attach the empty catch here so we don't get a "unhandled promise
951
960
// rejection" warning
952
- nextRevalidate . catch ( ( ) => { } )
961
+ pendingRevalidate . catch ( ( ) => { } )
953
962
954
- workStore . pendingRevalidates [ pendingRevalidateKey ] = nextRevalidate
963
+ workStore . pendingRevalidates [ pendingRevalidateKey ] = pendingRevalidate
955
964
956
- return pendingResponse
965
+ return pendingResponse . then ( ( responses ) => responses [ 1 ] )
957
966
} else {
958
967
return doOriginalFetch ( false , cacheReasonOverride )
959
968
}
0 commit comments