Skip to content

Commit 12857fd

Browse files
committed
Smaller refactor
1 parent 336ef85 commit 12857fd

File tree

1 file changed

+19
-34
lines changed

1 file changed

+19
-34
lines changed

packages/react-router/lib/dom/ssr/single-fetch.tsx

+19-34
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ import {
1818
import { createRequestInit } from "./data";
1919
import type { AssetsManifest, EntryContext } from "./entry";
2020
import { escapeHtml } from "./markup";
21-
import type { RouteModule, RouteModules } from "./routeModules";
21+
import type { RouteModules } from "./routeModules";
2222
import invariant from "./invariant";
23-
import type { EntryRoute } from "./routes";
2423

2524
export const SingleFetchRedirectSymbol = Symbol("SingleFetchRedirect");
2625

@@ -316,22 +315,16 @@ async function singleFetchLoaderNavigationStrategy(
316315
matches: DataStrategyFunctionArgs["matches"],
317316
basename: string | undefined
318317
) {
319-
// Track which routes need a server load - in case we need to tack on a
320-
// `_routes` param
318+
// Track which routes need a server load for use in a `_routes` param
321319
let routesParams = new Set<string>();
322320

323-
// We only add `_routes` when one or more routes opts out of a load via
324-
// `shouldRevalidate` or `clientLoader`
321+
// Only add `_routes` when at least 1 route opts out via `shouldRevalidate`/`clientLoader`
325322
let foundOptOutRoute = false;
326323

327-
// Deferreds for each route so we can be sure they've all loaded via
328-
// `match.resolve()`, and a singular promise that can tell us all routes
329-
// have been resolved
324+
// Deferreds per-route so we can be sure they've all loaded via `match.resolve()`
330325
let routeDfds = matches.map(() => createDeferred<void>());
331-
let routesLoadedPromise = Promise.all(routeDfds.map((d) => d.promise));
332326

333-
// Deferred that we'll use for the call to the server that each match can
334-
// await and parse out it's specific result
327+
// Deferred we'll use for the singleular call to the server
335328
let singleFetchDfd = createDeferred<SingleFetchResults>();
336329

337330
// Base URL and RequestInit for calls to the server
@@ -347,10 +340,8 @@ async function singleFetchLoaderNavigationStrategy(
347340
routeDfds[i].resolve();
348341

349342
let manifestRoute = manifest.routes[m.route.id];
343+
invariant(manifestRoute, "No manifest route found for dataStrategy");
350344

351-
// Note: If this logic changes for routes that should not participate
352-
// in Single Fetch, make sure you update getLowestLoadingIndex above
353-
// as well
354345
if (!m.shouldLoad) {
355346
// If we're not yet initialized and this is the initial load, respect
356347
// `shouldLoad` because we're only dealing with `clientLoader.hydrate`
@@ -364,7 +355,6 @@ async function singleFetchLoaderNavigationStrategy(
364355
// via `shouldRevalidate`
365356
if (
366357
m.route.id in router.state.loaderData &&
367-
manifestRoute &&
368358
m.route.shouldRevalidate
369359
) {
370360
if (manifestRoute.hasLoader) {
@@ -378,7 +368,7 @@ async function singleFetchLoaderNavigationStrategy(
378368

379369
// When a route has a client loader, it opts out of the singular call and
380370
// calls it's server loader via `serverLoader()` using a `?_routes` param
381-
if (manifestRoute && manifestRoute.hasClientLoader) {
371+
if (manifestRoute.hasClientLoader) {
382372
if (manifestRoute.hasLoader) {
383373
foundOptOutRoute = true;
384374
}
@@ -422,7 +412,7 @@ async function singleFetchLoaderNavigationStrategy(
422412
);
423413

424414
// Wait for all routes to resolve above before we make the HTTP call
425-
await routesLoadedPromise;
415+
await Promise.all(routeDfds.map((d) => d.promise));
426416

427417
// We can skip the server call:
428418
// - On initial hydration - only clientLoaders can pass through via `clientLoader.hydrate`
@@ -437,24 +427,18 @@ async function singleFetchLoaderNavigationStrategy(
437427
) {
438428
singleFetchDfd.resolve({});
439429
} else {
440-
try {
441-
// When one or more routes have opted out, we add a _routes param to
442-
// limit the loaders to those that have a server loader and did not
443-
// opt out
444-
if (ssr && foundOptOutRoute && routesParams.size > 0) {
445-
url.searchParams.set(
446-
"_routes",
447-
matches
448-
.filter((m) => routesParams.has(m.route.id))
449-
.map((m) => m.route.id)
450-
.join(",")
451-
);
452-
}
430+
// When routes have opted out, add a `_routes` param to filter server loaders
431+
// Skipped in `ssr:false` because we expect to be loading static `.data` files
432+
if (ssr && foundOptOutRoute && routesParams.size > 0) {
433+
let routes = [...routesParams.keys()].join(",");
434+
url.searchParams.set("_routes", routes);
435+
}
453436

437+
try {
454438
let data = await fetchAndDecode(url, init);
455439
singleFetchDfd.resolve(data.data as SingleFetchResults);
456440
} catch (e) {
457-
singleFetchDfd.reject(e as Error);
441+
singleFetchDfd.reject(e);
458442
}
459443
}
460444

@@ -673,17 +657,18 @@ function unwrapSingleFetchResult(result: SingleFetchResult, routeId: string) {
673657
}
674658
}
675659

660+
type Deferred = ReturnType<typeof createDeferred>;
676661
function createDeferred<T = unknown>() {
677662
let resolve: (val?: any) => Promise<void>;
678-
let reject: (error?: Error) => Promise<void>;
663+
let reject: (error?: unknown) => Promise<void>;
679664
let promise = new Promise<T>((res, rej) => {
680665
resolve = async (val: T) => {
681666
res(val);
682667
try {
683668
await promise;
684669
} catch (e) {}
685670
};
686-
reject = async (error?: Error) => {
671+
reject = async (error?: unknown) => {
687672
rej(error);
688673
try {
689674
await promise;

0 commit comments

Comments
 (0)