(href: string, crossOrigin: ?CrossOriginEnum)
| 6246 | } |
| 6247 | |
| 6248 | function preconnect(href: string, crossOrigin: ?CrossOriginEnum) { |
| 6249 | const request = resolveRequest(); |
| 6250 | if (!request) { |
| 6251 | // In async contexts we can sometimes resolve resources from AsyncLocalStorage. If we can't we can also |
| 6252 | // possibly get them from the stack if we are not in an async context. Since we were not able to resolve |
| 6253 | // the resources for this call in either case we opt to do nothing. We can consider making this a warning |
| 6254 | // but there may be times where calling a function outside of render is intentional (i.e. to warm up data |
| 6255 | // fetching) and we don't want to warn in those cases. |
| 6256 | previousDispatcher.C(/* preconnect */ href, crossOrigin); |
| 6257 | return; |
| 6258 | } |
| 6259 | const resumableState = getResumableState(request); |
| 6260 | const renderState = getRenderState(request); |
| 6261 | |
| 6262 | if (typeof href === 'string' && href) { |
| 6263 | const bucket = |
| 6264 | crossOrigin === 'use-credentials' |
| 6265 | ? 'credentials' |
| 6266 | : typeof crossOrigin === 'string' |
| 6267 | ? 'anonymous' |
| 6268 | : 'default'; |
| 6269 | const key = getResourceKey(href); |
| 6270 | if (!resumableState.connectResources[bucket].hasOwnProperty(key)) { |
| 6271 | resumableState.connectResources[bucket][key] = EXISTS; |
| 6272 | |
| 6273 | const headers = renderState.headers; |
| 6274 | let header; |
| 6275 | if ( |
| 6276 | headers && |
| 6277 | headers.remainingCapacity > 0 && |
| 6278 | // Compute the header since we might be able to fit it in the max length |
| 6279 | ((header = getPreconnectAsHeader(href, crossOrigin)), |
| 6280 | // We always consume the header length since once we find one header that doesn't fit |
| 6281 | // we assume all the rest won't as well. This is to avoid getting into a situation |
| 6282 | // where we have a very small remaining capacity but no headers will ever fit and we end |
| 6283 | // up constantly trying to see if the next resource might make it. In the future we can |
| 6284 | // make this behavior different between render and prerender since in the latter case |
| 6285 | // we are less sensitive to the current requests runtime per and more sensitive to maximizing |
| 6286 | // headers. |
| 6287 | (headers.remainingCapacity -= header.length + 2) >= 0) |
| 6288 | ) { |
| 6289 | // Store this in resettableState in case we are prerending and postpone in the Shell |
| 6290 | renderState.resets.connect[bucket][key] = EXISTS; |
| 6291 | if (headers.preconnects) { |
| 6292 | headers.preconnects += ', '; |
| 6293 | } |
| 6294 | // $FlowFixMe[unsafe-addition]: we assign header during the if condition |
| 6295 | headers.preconnects += header; |
| 6296 | } else { |
| 6297 | const resource: Resource = []; |
| 6298 | pushLinkImpl( |
| 6299 | resource, |
| 6300 | ({rel: 'preconnect', href, crossOrigin}: PreconnectProps), |
| 6301 | ); |
| 6302 | renderState.preconnects.add(resource); |
| 6303 | } |
| 6304 | } |
| 6305 | flushResources(request); |
nothing calls this directly
no test coverage detected