@@ -38,6 +38,11 @@ import {
3838 stringToPrecomputedChunk ,
3939 clonePrecomputedChunk ,
4040} from 'react-server/src/ReactServerStreamConfig' ;
41+ import {
42+ resolveResources ,
43+ setCurrentResources ,
44+ getCurrentResources ,
45+ } from 'react-server/src/ReactFizzResources' ;
4146
4247import isAttributeNameSafe from '../shared/isAttributeNameSafe' ;
4348import isUnitlessNumber from '../shared/isUnitlessNumber' ;
@@ -79,30 +84,34 @@ import {
7984import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals' ;
8085const ReactDOMCurrentDispatcher = ReactDOMSharedInternals . Dispatcher ;
8186
82- const ReactDOMServerDispatcher = enableFloat
83- ? {
84- prefetchDNS,
85- preconnect,
86- preload,
87- preinit,
88- }
89- : { } ;
87+ const ReactDOMServerDispatcher = {
88+ prefetchDNS,
89+ preconnect,
90+ preload,
91+ preinit,
92+ } ;
9093
91- let currentResources : null | Resources = null ;
9294const currentResourcesStack = [ ] ;
9395
94- export function prepareToRender ( resources : Resources ) : mixed {
95- currentResourcesStack . push ( currentResources ) ;
96- currentResources = resources ;
96+ function pushResources ( resources : null | Resources ) {
97+ currentResourcesStack . push ( getCurrentResources ( ) ) ;
98+ setCurrentResources ( resources ) ;
99+ }
97100
98- const previousHostDispatcher = ReactDOMCurrentDispatcher . current ;
101+ function popResources ( ) {
102+ setCurrentResources ( currentResourcesStack . pop ( ) ) ;
103+ }
104+
105+ export function prepareHostDispatcher ( ) {
99106 ReactDOMCurrentDispatcher . current = ReactDOMServerDispatcher ;
100- return previousHostDispatcher ;
101107}
102108
103- export function cleanupAfterRender ( previousDispatcher : mixed ) {
104- currentResources = currentResourcesStack . pop ( ) ;
105- ReactDOMCurrentDispatcher . current = previousDispatcher ;
109+ export function prepareToRender ( resources : Resources ) : mixed {
110+ pushResources ( resources ) ;
111+ }
112+
113+ export function cleanupAfterRender ( ) {
114+ popResources ( ) ;
106115}
107116
108117// Used to distinguish these contexts from ones used in other renderers.
@@ -4804,16 +4813,18 @@ function getResourceKey(as: string, href: string): string {
48044813}
48054814
48064815export function prefetchDNS ( href : string , options ?: mixed ) {
4807- if ( ! currentResources ) {
4808- // While we expect that preconnect calls are primarily going to be observed
4809- // during render because effects and events don't run on the server it is
4810- // still possible that these get called in module scope. This is valid on
4811- // the client since there is still a document to interact with but on the
4812- // server we need a request to associate the call to. Because of this we
4813- // simply return and do not warn.
4816+ if ( ! enableFloat ) {
4817+ return ;
4818+ }
4819+ const resources = resolveResources ( ) ;
4820+ if ( ! resources ) {
4821+ // In async contexts we can sometimes resolve resources from AsyncLocalStorage. If we can't we can also
4822+ // possibly get them from the stack if we are not in an async context. Since we were not able to resolve
4823+ // the resources for this call in either case we opt to do nothing. We can consider making this a warning
4824+ // but there may be times where calling a function outside of render is intentional (i.e. to warm up data
4825+ // fetching) and we don't want to warn in those cases.
48144826 return ;
48154827 }
4816- const resources = currentResources ;
48174828 if ( __DEV__ ) {
48184829 if ( typeof href !== 'string' || ! href ) {
48194830 console . error (
@@ -4858,17 +4869,19 @@ export function prefetchDNS(href: string, options?: mixed) {
48584869 }
48594870}
48604871
4861- export function preconnect ( href : string , options ?: { crossOrigin ?: string } ) {
4862- if ( ! currentResources ) {
4863- // While we expect that preconnect calls are primarily going to be observed
4864- // during render because effects and events don't run on the server it is
4865- // still possible that these get called in module scope. This is valid on
4866- // the client since there is still a document to interact with but on the
4867- // server we need a request to associate the call to. Because of this we
4868- // simply return and do not warn.
4872+ export function preconnect ( href : string , options ?: ?{ crossOrigin ?: string } ) {
4873+ if ( ! enableFloat ) {
4874+ return ;
4875+ }
4876+ const resources = resolveResources ( ) ;
4877+ if ( ! resources ) {
4878+ // In async contexts we can sometimes resolve resources from AsyncLocalStorage. If we can't we can also
4879+ // possibly get them from the stack if we are not in an async context. Since we were not able to resolve
4880+ // the resources for this call in either case we opt to do nothing. We can consider making this a warning
4881+ // but there may be times where calling a function outside of render is intentional (i.e. to warm up data
4882+ // fetching) and we don't want to warn in those cases.
48694883 return;
48704884 }
4871- const resources = currentResources ;
48724885 if ( __DEV__ ) {
48734886 if ( typeof href !== 'string' || ! href ) {
48744887 console . error (
@@ -4917,24 +4930,25 @@ export function preconnect(href: string, options?: {crossOrigin?: string}) {
49174930 }
49184931}
49194932
4920- type PreloadAs = 'style' | 'font' | 'script' ;
49214933type PreloadOptions = {
4922- as : PreloadAs ,
4934+ as : string ,
49234935 crossOrigin ?: string ,
49244936 integrity ?: string ,
49254937 type ?: string ,
49264938} ;
49274939export function preload ( href : string , options : PreloadOptions ) {
4928- if ( ! currentResources ) {
4929- // While we expect that preload calls are primarily going to be observed
4930- // during render because effects and events don't run on the server it is
4931- // still possible that these get called in module scope. This is valid on
4932- // the client since there is still a document to interact with but on the
4933- // server we need a request to associate the call to. Because of this we
4934- // simply return and do not warn.
4940+ if ( ! enableFloat ) {
4941+ return ;
4942+ }
4943+ const resources = resolveResources ( ) ;
4944+ if ( ! resources ) {
4945+ // In async contexts we can sometimes resolve resources from AsyncLocalStorage. If we can't we can also
4946+ // possibly get them from the stack if we are not in an async context. Since we were not able to resolve
4947+ // the resources for this call in either case we opt to do nothing. We can consider making this a warning
4948+ // but there may be times where calling a function outside of render is intentional (i.e. to warm up data
4949+ // fetching) and we don't want to warn in those cases.
49354950 return ;
49364951 }
4937- const resources = currentResources ;
49384952 if ( __DEV__ ) {
49394953 if ( typeof href !== 'string' || ! href ) {
49404954 console . error (
@@ -5058,24 +5072,26 @@ export function preload(href: string, options: PreloadOptions) {
50585072 }
50595073}
50605074
5061- type PreinitAs = 'style' | 'script' ;
50625075type PreinitOptions = {
5063- as : PreinitAs ,
5076+ as : string ,
50645077 precedence ?: string ,
50655078 crossOrigin ?: string ,
50665079 integrity ?: string ,
50675080} ;
50685081export function preinit ( href : string , options : PreinitOptions ) : void {
5069- if ( ! currentResources ) {
5070- // While we expect that preinit calls are primarily going to be observed
5071- // during render because effects and events don't run on the server it is
5072- // still possible that these get called in module scope. This is valid on
5073- // the client since there is still a document to interact with but on the
5074- // server we need a request to associate the call to. Because of this we
5075- // simply return and do not warn.
5082+ if ( ! enableFloat ) {
50765083 return ;
50775084 }
5078- preinitImpl ( currentResources , href, options) ;
5085+ const resources = resolveResources ( ) ;
5086+ if ( ! resources ) {
5087+ // In async contexts we can sometimes resolve resources from AsyncLocalStorage. If we can't we can also
5088+ // possibly get them from the stack if we are not in an async context. Since we were not able to resolve
5089+ // the resources for this call in either case we opt to do nothing. We can consider making this a warning
5090+ // but there may be times where calling a function outside of render is intentional (i.e. to warm up data
5091+ // fetching) and we don't want to warn in those cases.
5092+ return;
5093+ }
5094+ preinitImpl ( resources , href , options ) ;
50795095}
50805096
50815097// On the server, preinit may be called outside of render when sending an
@@ -5297,7 +5313,7 @@ function preinitImpl(
52975313
52985314function preloadPropsFromPreloadOptions (
52995315 href : string ,
5300- as : PreloadAs ,
5316+ as : string ,
53015317 options : PreloadOptions ,
53025318) : PreloadProps {
53035319 return {
0 commit comments