@@ -37,6 +37,11 @@ import {
3737 stringToPrecomputedChunk ,
3838 clonePrecomputedChunk ,
3939} from 'react-server/src/ReactServerStreamConfig' ;
40+ import {
41+ resolveResources ,
42+ setCurrentResources ,
43+ getCurrentResources ,
44+ } from 'react-server/src/ReactFizzResources' ;
4045
4146import isAttributeNameSafe from '../shared/isAttributeNameSafe' ;
4247import isUnitlessNumber from '../shared/isUnitlessNumber' ;
@@ -78,30 +83,34 @@ import {
7883import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals' ;
7984const ReactDOMCurrentDispatcher = ReactDOMSharedInternals . Dispatcher ;
8085
81- const ReactDOMServerDispatcher = enableFloat
82- ? {
83- prefetchDNS,
84- preconnect,
85- preload,
86- preinit,
87- }
88- : { } ;
86+ const ReactDOMServerDispatcher = {
87+ prefetchDNS,
88+ preconnect,
89+ preload,
90+ preinit,
91+ } ;
8992
90- let currentResources : null | Resources = null ;
9193const currentResourcesStack = [ ] ;
9294
93- export function prepareToRender ( resources : Resources ) : mixed {
94- currentResourcesStack . push ( currentResources ) ;
95- currentResources = resources ;
95+ function pushResources ( resources : null | Resources ) {
96+ currentResourcesStack . push ( getCurrentResources ( ) ) ;
97+ setCurrentResources ( resources ) ;
98+ }
9699
97- const previousHostDispatcher = ReactDOMCurrentDispatcher . current ;
100+ function popResources ( ) {
101+ setCurrentResources ( currentResourcesStack . pop ( ) ) ;
102+ }
103+
104+ export function prepareHostDispatcher ( ) {
98105 ReactDOMCurrentDispatcher . current = ReactDOMServerDispatcher ;
99- return previousHostDispatcher ;
100106}
101107
102- export function cleanupAfterRender ( previousDispatcher : mixed ) {
103- currentResources = currentResourcesStack . pop ( ) ;
104- ReactDOMCurrentDispatcher . current = previousDispatcher ;
108+ export function prepareToRender ( resources : Resources ) : mixed {
109+ pushResources ( resources ) ;
110+ }
111+
112+ export function cleanupAfterRender ( ) {
113+ popResources ( ) ;
105114}
106115
107116// Used to distinguish these contexts from ones used in other renderers.
@@ -4490,16 +4499,18 @@ function getResourceKey(as: string, href: string): string {
44904499}
44914500
44924501export function prefetchDNS ( href : string , options ?: mixed ) {
4493- if ( ! currentResources ) {
4494- // While we expect that preconnect calls are primarily going to be observed
4495- // during render because effects and events don't run on the server it is
4496- // still possible that these get called in module scope. This is valid on
4497- // the client since there is still a document to interact with but on the
4498- // server we need a request to associate the call to. Because of this we
4499- // simply return and do not warn.
4502+ if ( ! enableFloat ) {
4503+ return ;
4504+ }
4505+ const resources = resolveResources ( ) ;
4506+ if ( ! resources ) {
4507+ // In async contexts we can sometimes resolve resources from AsyncLocalStorage. If we can't we can also
4508+ // possibly get them from the stack if we are not in an async context. Since we were not able to resolve
4509+ // the resources for this call in either case we opt to do nothing. We can consider making this a warning
4510+ // but there may be times where calling a function outside of render is intentional (i.e. to warm up data
4511+ // fetching) and we don't want to warn in those cases.
45004512 return ;
45014513 }
4502- const resources = currentResources ;
45034514 if ( __DEV__ ) {
45044515 if ( typeof href !== 'string' || ! href ) {
45054516 console . error (
@@ -4544,17 +4555,19 @@ export function prefetchDNS(href: string, options?: mixed) {
45444555 }
45454556}
45464557
4547- export function preconnect ( href : string , options ?: { crossOrigin ?: string } ) {
4548- if ( ! currentResources ) {
4549- // While we expect that preconnect calls are primarily going to be observed
4550- // during render because effects and events don't run on the server it is
4551- // still possible that these get called in module scope. This is valid on
4552- // the client since there is still a document to interact with but on the
4553- // server we need a request to associate the call to. Because of this we
4554- // simply return and do not warn.
4558+ export function preconnect ( href : string , options ?: ?{ crossOrigin ?: string } ) {
4559+ if ( ! enableFloat ) {
4560+ return ;
4561+ }
4562+ const resources = resolveResources ( ) ;
4563+ if ( ! resources ) {
4564+ // In async contexts we can sometimes resolve resources from AsyncLocalStorage. If we can't we can also
4565+ // possibly get them from the stack if we are not in an async context. Since we were not able to resolve
4566+ // the resources for this call in either case we opt to do nothing. We can consider making this a warning
4567+ // but there may be times where calling a function outside of render is intentional (i.e. to warm up data
4568+ // fetching) and we don't want to warn in those cases.
45554569 return;
45564570 }
4557- const resources = currentResources ;
45584571 if ( __DEV__ ) {
45594572 if ( typeof href !== 'string' || ! href ) {
45604573 console . error (
@@ -4603,24 +4616,25 @@ export function preconnect(href: string, options?: {crossOrigin?: string}) {
46034616 }
46044617}
46054618
4606- type PreloadAs = 'style' | 'font' | 'script' ;
46074619type PreloadOptions = {
4608- as : PreloadAs ,
4620+ as : string ,
46094621 crossOrigin ?: string ,
46104622 integrity ?: string ,
46114623 type ?: string ,
46124624} ;
46134625export function preload ( href : string , options : PreloadOptions ) {
4614- if ( ! currentResources ) {
4615- // While we expect that preload calls are primarily going to be observed
4616- // during render because effects and events don't run on the server it is
4617- // still possible that these get called in module scope. This is valid on
4618- // the client since there is still a document to interact with but on the
4619- // server we need a request to associate the call to. Because of this we
4620- // simply return and do not warn.
4626+ if ( ! enableFloat ) {
4627+ return ;
4628+ }
4629+ const resources = resolveResources ( ) ;
4630+ if ( ! resources ) {
4631+ // In async contexts we can sometimes resolve resources from AsyncLocalStorage. If we can't we can also
4632+ // possibly get them from the stack if we are not in an async context. Since we were not able to resolve
4633+ // the resources for this call in either case we opt to do nothing. We can consider making this a warning
4634+ // but there may be times where calling a function outside of render is intentional (i.e. to warm up data
4635+ // fetching) and we don't want to warn in those cases.
46214636 return ;
46224637 }
4623- const resources = currentResources ;
46244638 if ( __DEV__ ) {
46254639 if ( typeof href !== 'string' || ! href ) {
46264640 console . error (
@@ -4744,24 +4758,26 @@ export function preload(href: string, options: PreloadOptions) {
47444758 }
47454759}
47464760
4747- type PreinitAs = 'style' | 'script' ;
47484761type PreinitOptions = {
4749- as : PreinitAs ,
4762+ as : string ,
47504763 precedence ?: string ,
47514764 crossOrigin ?: string ,
47524765 integrity ?: string ,
47534766} ;
47544767export function preinit ( href : string , options : PreinitOptions ) : void {
4755- if ( ! currentResources ) {
4756- // While we expect that preinit calls are primarily going to be observed
4757- // during render because effects and events don't run on the server it is
4758- // still possible that these get called in module scope. This is valid on
4759- // the client since there is still a document to interact with but on the
4760- // server we need a request to associate the call to. Because of this we
4761- // simply return and do not warn.
4768+ if ( ! enableFloat ) {
47624769 return ;
47634770 }
4764- preinitImpl ( currentResources , href, options) ;
4771+ const resources = resolveResources ( ) ;
4772+ if ( ! resources ) {
4773+ // In async contexts we can sometimes resolve resources from AsyncLocalStorage. If we can't we can also
4774+ // possibly get them from the stack if we are not in an async context. Since we were not able to resolve
4775+ // the resources for this call in either case we opt to do nothing. We can consider making this a warning
4776+ // but there may be times where calling a function outside of render is intentional (i.e. to warm up data
4777+ // fetching) and we don't want to warn in those cases.
4778+ return;
4779+ }
4780+ preinitImpl ( resources , href , options ) ;
47654781}
47664782
47674783// On the server, preinit may be called outside of render when sending an
@@ -4983,7 +4999,7 @@ function preinitImpl(
49834999
49845000function preloadPropsFromPreloadOptions (
49855001 href : string ,
4986- as : PreloadAs ,
5002+ as : string ,
49875003 options : PreloadOptions ,
49885004) : PreloadProps {
49895005 return {
0 commit comments