1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @flow
    
  8.  */
    
  9. 
    
  10. // This client file is in the shared folder because it applies to both SSR and browser contexts.
    
  11. // It is the configuraiton of the FlightClient behavior which can run in either environment.
    
  12. 
    
  13. import type {HintCode, HintModel} from '../server/ReactFlightServerConfigDOM';
    
  14. 
    
  15. import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals';
    
  16. const ReactDOMCurrentDispatcher = ReactDOMSharedInternals.Dispatcher;
    
  17. 
    
  18. import {getCrossOriginString} from './crossOriginStrings';
    
  19. 
    
  20. export function dispatchHint<Code: HintCode>(
    
  21.   code: Code,
    
  22.   model: HintModel<Code>,
    
  23. ): void {
    
  24.   const dispatcher = ReactDOMCurrentDispatcher.current;
    
  25.   if (dispatcher) {
    
  26.     switch (code) {
    
  27.       case 'D': {
    
  28.         const refined = refineModel(code, model);
    
  29.         const href = refined;
    
  30.         dispatcher.prefetchDNS(href);
    
  31.         return;
    
  32.       }
    
  33.       case 'C': {
    
  34.         const refined = refineModel(code, model);
    
  35.         if (typeof refined === 'string') {
    
  36.           const href = refined;
    
  37.           dispatcher.preconnect(href);
    
  38.         } else {
    
  39.           const href = refined[0];
    
  40.           const crossOrigin = refined[1];
    
  41.           dispatcher.preconnect(href, crossOrigin);
    
  42.         }
    
  43.         return;
    
  44.       }
    
  45.       case 'L': {
    
  46.         const refined = refineModel(code, model);
    
  47.         const href = refined[0];
    
  48.         const as = refined[1];
    
  49.         if (refined.length === 3) {
    
  50.           const options = refined[2];
    
  51.           dispatcher.preload(href, as, options);
    
  52.         } else {
    
  53.           dispatcher.preload(href, as);
    
  54.         }
    
  55.         return;
    
  56.       }
    
  57.       case 'm': {
    
  58.         const refined = refineModel(code, model);
    
  59.         if (typeof refined === 'string') {
    
  60.           const href = refined;
    
  61.           dispatcher.preloadModule(href);
    
  62.         } else {
    
  63.           const href = refined[0];
    
  64.           const options = refined[1];
    
  65.           dispatcher.preloadModule(href, options);
    
  66.         }
    
  67.         return;
    
  68.       }
    
  69.       case 'S': {
    
  70.         const refined = refineModel(code, model);
    
  71.         if (typeof refined === 'string') {
    
  72.           const href = refined;
    
  73.           dispatcher.preinitStyle(href);
    
  74.         } else {
    
  75.           const href = refined[0];
    
  76.           const precedence = refined[1] === 0 ? undefined : refined[1];
    
  77.           const options = refined.length === 3 ? refined[2] : undefined;
    
  78.           dispatcher.preinitStyle(href, precedence, options);
    
  79.         }
    
  80.         return;
    
  81.       }
    
  82.       case 'X': {
    
  83.         const refined = refineModel(code, model);
    
  84.         if (typeof refined === 'string') {
    
  85.           const href = refined;
    
  86.           dispatcher.preinitScript(href);
    
  87.         } else {
    
  88.           const href = refined[0];
    
  89.           const options = refined[1];
    
  90.           dispatcher.preinitScript(href, options);
    
  91.         }
    
  92.         return;
    
  93.       }
    
  94.       case 'M': {
    
  95.         const refined = refineModel(code, model);
    
  96.         if (typeof refined === 'string') {
    
  97.           const href = refined;
    
  98.           dispatcher.preinitModuleScript(href);
    
  99.         } else {
    
  100.           const href = refined[0];
    
  101.           const options = refined[1];
    
  102.           dispatcher.preinitModuleScript(href, options);
    
  103.         }
    
  104.         return;
    
  105.       }
    
  106.     }
    
  107.   }
    
  108. }
    
  109. 
    
  110. // Flow is having troulbe refining the HintModels so we help it a bit.
    
  111. // This should be compiled out in the production build.
    
  112. function refineModel<T>(code: T, model: HintModel<any>): HintModel<T> {
    
  113.   return model;
    
  114. }
    
  115. 
    
  116. export function preinitModuleForSSR(
    
  117.   href: string,
    
  118.   nonce: ?string,
    
  119.   crossOrigin: ?string,
    
  120. ) {
    
  121.   const dispatcher = ReactDOMCurrentDispatcher.current;
    
  122.   if (dispatcher) {
    
  123.     dispatcher.preinitModuleScript(href, {
    
  124.       crossOrigin: getCrossOriginString(crossOrigin),
    
  125.       nonce,
    
  126.     });
    
  127.   }
    
  128. }
    
  129. 
    
  130. export function preinitScriptForSSR(
    
  131.   href: string,
    
  132.   nonce: ?string,
    
  133.   crossOrigin: ?string,
    
  134. ) {
    
  135.   const dispatcher = ReactDOMCurrentDispatcher.current;
    
  136.   if (dispatcher) {
    
  137.     dispatcher.preinitScript(href, {
    
  138.       crossOrigin: getCrossOriginString(crossOrigin),
    
  139.       nonce,
    
  140.     });
    
  141.   }
    
  142. }