Repository: remix-run/react-router
File: packages/react-router/lib/dom/ssr/single-fetch.tsx (TypeScript)

Code before:
          <StreamTransfer
            context={context}
            identifier={identifier + 1}
            reader={reader}
            textDecoder={textDecoder}
            nonce={nonce}
          />
        </React.Suspense>
      </>
    );
  }
}

export function getSingleFetchDataStrategy(
  manifest: AssetsManifest,
  ssr: boolean,
  basename: string | undefined,
  getRouter: () => DataRouter
): DataStrategyFunction {
  let dataStrategy = getSingleFetchDataStrategyImpl(
    manifest,
    ssr,
    basename,
    getRouter
  );
  return async (args) => args.unstable_runMiddleware(dataStrategy);
}

export function getSingleFetchDataStrategyImpl(
  manifest: AssetsManifest,
  ssr: boolean,
  basename: string | undefined,
  getRouter: () => DataRouter
): DataStrategyFunction {
  return async (args) => {
    let { request, matches, fetcherKey } = args;

    // Actions are simple and behave the same for navigations and fetchers
    if (request.method !== "GET") {
      return singleFetchActionStrategy(args, basename);
    }

    let foundRevalidatingServerLoader = matches.some(
      (m) =>
        m.unstable_shouldCallHandler() &&
        manifest.routes[m.route.id]?.hasLoader &&
        !manifest.routes[m.route.id]?.hasClientLoader
    );
    if (!ssr && !foundRevalidatingServerLoader) {
      // If this is SPA mode, there won't be any loaders below root and we'll
      // disable single fetch.  We have to keep the `dataStrategy` defined for

Review comment (suggestion):
Use the new `runMiddleware` API to wrap middleware around our existing `dataStrategy` - instead of calling middleware independently for each fork in the `dataStrategy`

Code after:
          <StreamTransfer
            context={context}
            identifier={identifier + 1}
            reader={reader}
            textDecoder={textDecoder}
            nonce={nonce}
          />
        </React.Suspense>
      </>
    );
  }
}

export function getSingleFetchDataStrategy(
  manifest: AssetsManifest,
  ssr: boolean,
  basename: string | undefined,
  getRouter: () => DataRouter
): DataStrategyFunction {
  let dataStrategy = getSingleFetchDataStrategyImpl(
    manifest,
    ssr,
    basename,
    getRouter
  );
  return async (args) => args.unstable_runClientMiddleware(dataStrategy);
}

export function getSingleFetchDataStrategyImpl(
  manifest: AssetsManifest,
  ssr: boolean,
  basename: string | undefined,
  getRouter: () => DataRouter
): DataStrategyFunction {
  return async (args) => {
    let { request, matches, fetcherKey } = args;

    // Actions are simple and behave the same for navigations and fetchers
    if (request.method !== "GET") {
      return singleFetchActionStrategy(args, basename);
    }

    let foundRevalidatingServerLoader = matches.some(
      (m) =>
        m.unstable_shouldCallHandler() &&
        manifest.routes[m.route.id]?.hasLoader &&
        !manifest.routes[m.route.id]?.hasClientLoader
    );
    if (!ssr && !foundRevalidatingServerLoader) {
      // If this is SPA mode, there won't be any loaders below root and we'll
      // disable single fetch.  We have to keep the `dataStrategy` defined for