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. import type {CacheDispatcher} from 'react-reconciler/src/ReactInternalTypes';
    
  11. import ReactSharedInternals from 'shared/ReactSharedInternals';
    
  12. 
    
  13. const ReactCurrentCache = ReactSharedInternals.ReactCurrentCache;
    
  14. 
    
  15. function unsupported() {
    
  16.   throw new Error('This feature is not supported by ReactSuspenseTestUtils.');
    
  17. }
    
  18. 
    
  19. export function waitForSuspense<T>(fn: () => T): Promise<T> {
    
  20.   const cache: Map<Function, mixed> = new Map();
    
  21.   const testDispatcher: CacheDispatcher = {
    
  22.     getCacheSignal: unsupported,
    
  23.     getCacheForType<R>(resourceType: () => R): R {
    
  24.       let entry: R | void = (cache.get(resourceType): any);
    
  25.       if (entry === undefined) {
    
  26.         entry = resourceType();
    
  27.         // TODO: Warn if undefined?
    
  28.         cache.set(resourceType, entry);
    
  29.       }
    
  30.       return entry;
    
  31.     },
    
  32.   };
    
  33.   // Not using async/await because we don't compile it.
    
  34.   return new Promise((resolve, reject) => {
    
  35.     function retry() {
    
  36.       const prevDispatcher = ReactCurrentCache.current;
    
  37.       ReactCurrentCache.current = testDispatcher;
    
  38.       try {
    
  39.         const result = fn();
    
  40.         resolve(result);
    
  41.       } catch (thrownValue) {
    
  42.         if (typeof thrownValue.then === 'function') {
    
  43.           thrownValue.then(retry, retry);
    
  44.         } else {
    
  45.           reject(thrownValue);
    
  46.         }
    
  47.       } finally {
    
  48.         ReactCurrentCache.current = prevDispatcher;
    
  49.       }
    
  50.     }
    
  51.     retry();
    
  52.   });
    
  53. }