@@ -57,23 +57,27 @@ declare global {
57
57
export function createCallServer ( {
58
58
decode,
59
59
encodeAction,
60
+ fetch : fetchImplementation = fetch ,
60
61
} : {
61
62
decode : DecodeServerResponseFunction ;
62
63
encodeAction : EncodeActionFunction ;
64
+ fetch ?: ( request : Request ) => Promise < Response > ;
63
65
} ) {
64
66
let landedActionId = 0 ;
65
67
return async ( id : string , args : unknown [ ] ) => {
66
68
let actionId = ( window . __routerActionID =
67
69
( window . __routerActionID ??= 0 ) + 1 ) ;
68
70
69
- const response = await fetch ( location . href , {
70
- body : await encodeAction ( args ) ,
71
- method : "POST" ,
72
- headers : {
73
- Accept : "text/x-component" ,
74
- "rsc-action-id" : id ,
75
- } ,
76
- } ) ;
71
+ const response = await fetchImplementation (
72
+ new Request ( location . href , {
73
+ body : await encodeAction ( args ) ,
74
+ method : "POST" ,
75
+ headers : {
76
+ Accept : "text/x-component" ,
77
+ "rsc-action-id" : id ,
78
+ } ,
79
+ } )
80
+ ) ;
77
81
if ( ! response . body ) {
78
82
throw new Error ( "No response body" ) ;
79
83
}
@@ -162,11 +166,13 @@ export function createCallServer({
162
166
}
163
167
164
168
function createRouterFromPayload ( {
169
+ fetchImplementation,
165
170
decode,
166
171
payload,
167
172
} : {
168
173
payload : ServerPayload ;
169
174
decode : DecodeServerResponseFunction ;
175
+ fetchImplementation : ( request : Request ) => Promise < Response > ;
170
176
} ) {
171
177
if ( window . __router ) return window . __router ;
172
178
@@ -225,14 +231,20 @@ function createRouterFromPayload({
225
231
if ( discoveredPaths . has ( path ) ) {
226
232
return ;
227
233
}
228
- await fetchAndApplyManifestPatches ( [ path ] , decode , signal ) ;
234
+ await fetchAndApplyManifestPatches (
235
+ [ path ] ,
236
+ decode ,
237
+ fetchImplementation ,
238
+ signal
239
+ ) ;
229
240
} ,
230
241
// FIXME: Pass `build.ssr` and `build.basename` into this function
231
242
dataStrategy : getRSCSingleFetchDataStrategy (
232
243
( ) => window . __router ,
233
244
true ,
234
245
undefined ,
235
- decode
246
+ decode ,
247
+ fetchImplementation
236
248
) ,
237
249
} ) ;
238
250
@@ -261,7 +273,8 @@ export function getRSCSingleFetchDataStrategy(
261
273
getRouter : ( ) => DataRouter ,
262
274
ssr : boolean ,
263
275
basename : string | undefined ,
264
- decode : DecodeServerResponseFunction
276
+ decode : DecodeServerResponseFunction ,
277
+ fetchImplementation : ( request : Request ) => Promise < Response >
265
278
) : DataStrategyFunction {
266
279
// TODO: Clean this up with a shared type
267
280
type RSCDataRouteMatch = DataRouteMatch & {
@@ -290,7 +303,7 @@ export function getRSCSingleFetchDataStrategy(
290
303
} ;
291
304
} ,
292
305
// pass map into fetchAndDecode so it can add payloads
293
- getFetchAndDecodeViaRSC ( decode ) ,
306
+ getFetchAndDecodeViaRSC ( decode , fetchImplementation ) ,
294
307
ssr ,
295
308
basename ,
296
309
// If the route has a component but we don't have an element, we need to hit
@@ -344,7 +357,8 @@ export function getRSCSingleFetchDataStrategy(
344
357
}
345
358
346
359
function getFetchAndDecodeViaRSC (
347
- decode : DecodeServerResponseFunction
360
+ decode : DecodeServerResponseFunction ,
361
+ fetchImplementation : ( request : Request ) => Promise < Response >
348
362
) : FetchAndDecodeFunction {
349
363
return async (
350
364
args : DataStrategyFunctionArgs < unknown > ,
@@ -360,7 +374,9 @@ function getFetchAndDecodeViaRSC(
360
374
}
361
375
}
362
376
363
- let res = await fetch ( url , await createRequestInit ( request ) ) ;
377
+ let res = await fetchImplementation (
378
+ new Request ( url , await createRequestInit ( request ) )
379
+ ) ;
364
380
365
381
// If this 404'd without hitting the running server (most likely in a
366
382
// pre-rendered app using a CDN), then bubble a standard 404 ErrorResponse
@@ -426,19 +442,25 @@ function getFetchAndDecodeViaRSC(
426
442
427
443
export function RSCHydratedRouter ( {
428
444
decode,
445
+ fetch : fetchImplementation = fetch ,
429
446
payload,
430
447
routeDiscovery = "eager" ,
431
448
} : {
432
449
decode : DecodeServerResponseFunction ;
450
+ fetch ?: ( request : Request ) => Promise < Response > ;
433
451
payload : ServerPayload ;
434
452
routeDiscovery ?: "eager" | "lazy" ;
435
453
} ) {
436
454
if ( payload . type !== "render" ) throw new Error ( "Invalid payload type" ) ;
437
455
438
456
let router = React . useMemo (
439
- ( ) => createRouterFromPayload ( { decode, payload } ) ,
440
- // eslint-disable-next-line react-hooks/exhaustive-deps
441
- [ ]
457
+ ( ) =>
458
+ createRouterFromPayload ( {
459
+ decode,
460
+ payload,
461
+ fetchImplementation,
462
+ } ) ,
463
+ [ decode , payload , fetchImplementation ]
442
464
) ;
443
465
444
466
React . useLayoutEffect ( ( ) => {
@@ -510,7 +532,7 @@ export function RSCHydratedRouter({
510
532
}
511
533
512
534
try {
513
- await fetchAndApplyManifestPatches ( paths , decode ) ;
535
+ await fetchAndApplyManifestPatches ( paths , decode , fetchImplementation ) ;
514
536
} catch ( e ) {
515
537
console . error ( "Failed to fetch manifest patches" , e ) ;
516
538
}
@@ -529,7 +551,7 @@ export function RSCHydratedRouter({
529
551
attributes : true ,
530
552
attributeFilter : [ "data-discover" , "href" , "action" ] ,
531
553
} ) ;
532
- } , [ routeDiscovery , decode ] ) ;
554
+ } , [ routeDiscovery , decode , fetchImplementation ] ) ;
533
555
534
556
const frameworkContext : FrameworkContextObject = {
535
557
future : {
@@ -704,6 +726,7 @@ const URL_LIMIT = 7680;
704
726
async function fetchAndApplyManifestPatches (
705
727
paths : string [ ] ,
706
728
decode : DecodeServerResponseFunction ,
729
+ fetchImplementation : ( request : Request ) => Promise < Response > ,
707
730
signal ?: AbortSignal
708
731
) {
709
732
let basename = ( window . __router . basename ?? "" ) . replace ( / ^ \/ | \/ $ / g, "" ) ;
@@ -718,7 +741,7 @@ async function fetchAndApplyManifestPatches(
718
741
return ;
719
742
}
720
743
721
- let response = await fetch ( url , { signal } ) ;
744
+ let response = await fetchImplementation ( new Request ( url , { signal } ) ) ;
722
745
if ( ! response . body || response . status < 200 || response . status >= 300 ) {
723
746
throw new Error ( "Unable to fetch new route matches from the server" ) ;
724
747
}
0 commit comments