Repository: facebook/react
File: packages/react-reconciler/src/ReactFiberTransition.js (JavaScript)

Code before:
  thenable: Thenable<mixed>,
): void {
  if (enableAsyncActions) {
    // This is an async action.
    entangleAsyncAction(transition, thenable);
  }
}

export function notifyTransitionCallbacks(
  transition: BatchConfigTransition,
  returnValue: mixed,
) {
  const callbacks = transition._callbacks;
  callbacks.forEach(callback => callback(transition, returnValue));
}

// When retrying a Suspense/Offscreen boundary, we restore the cache that was
// used during the previous render by placing it here, on the stack.
const resumedCache: StackCursor<Cache | null> = createCursor(null);

// During the render/synchronous commit phase, we don't actually process the
// transitions. Therefore, we want to lazily combine transitions. Instead of
// comparing the arrays of transitions when we combine them and storing them
// and filtering out the duplicates, we will instead store the unprocessed transitions
// in an array and actually filter them in the passive phase.
const transitionStack: StackCursor<Array<Transition> | null> =
  createCursor(null);

function peekCacheFromPool(): Cache | null {
  if (!enableCache) {
    return (null: any);
  }

  // Check if the cache pool already has a cache we can use.

  // If we're rendering inside a Suspense boundary that is currently hidden,
  // we should use the same cache that we used during the previous render, if
  // one exists.
  const cacheResumedFromPreviousRender = resumedCache.current;
  if (cacheResumedFromPreviousRender !== null) {
    return cacheResumedFromPreviousRender;
  }

  // Otherwise, check the root's cache pool.
  const root = (getWorkInProgressRoot(): any);
  const cacheFromRootCachePool = root.pooledCache;

  return cacheFromRootCachePool;
}

export function requestCacheFromPool(renderLanes: Lanes): Cache {

Review comment (suggestion):
For flushSync and friends we went with a noop default function so we don't have to do this type check on every invocation

Code after:
//     });
//   }
//
// Currently we only compose together the code that runs at the end of each
// startTransition, because for now that's sufficient — the part that sets
// isTransition=true on the stack uses a separate shared internal field. But
// really we should delete the shared field and track isTransition per
// reconciler. Leaving this for a future PR.
const prevOnStartTransitionFinish = ReactSharedInternals.S;
ReactSharedInternals.S = function onStartTransitionFinishForReconciler(
  transition: BatchConfigTransition,
  returnValue: mixed,
) {
  if (
    enableAsyncActions &&
    typeof returnValue === 'object' &&
    returnValue !== null &&
    typeof returnValue.then === 'function'
  ) {
    // This is an async action
    const thenable: Thenable<mixed> = (returnValue: any);
    entangleAsyncAction(transition, thenable);
  }
  if (prevOnStartTransitionFinish !== null) {
    prevOnStartTransitionFinish(transition, returnValue);
  }
};

export function requestCurrentTransition(): BatchConfigTransition | null {
  return ReactSharedInternals.T;
}

// When retrying a Suspense/Offscreen boundary, we restore the cache that was
// used during the previous render by placing it here, on the stack.
const resumedCache: StackCursor<Cache | null> = createCursor(null);

// During the render/synchronous commit phase, we don't actually process the
// transitions. Therefore, we want to lazily combine transitions. Instead of
// comparing the arrays of transitions when we combine them and storing them
// and filtering out the duplicates, we will instead store the unprocessed transitions
// in an array and actually filter them in the passive phase.
const transitionStack: StackCursor<Array<Transition> | null> =
  createCursor(null);

function peekCacheFromPool(): Cache | null {
  if (!enableCache) {
    return (null: any);
  }

  // Check if the cache pool already has a cache we can use.