@tanstack/router-core 1.158.0 → 1.158.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/load-matches.cjs +38 -27
- package/dist/cjs/load-matches.cjs.map +1 -1
- package/dist/esm/load-matches.js +38 -27
- package/dist/esm/load-matches.js.map +1 -1
- package/package.json +1 -1
- package/src/load-matches.ts +64 -49
|
@@ -429,6 +429,11 @@ const runLoader = async (inner, matchId, index, route) => {
|
|
|
429
429
|
} catch (e) {
|
|
430
430
|
let error = e;
|
|
431
431
|
if (error?.name === "AbortError") {
|
|
432
|
+
if (match.abortController.signal.aborted) {
|
|
433
|
+
match._nonReactive.loaderPromise?.resolve();
|
|
434
|
+
match._nonReactive.loaderPromise = void 0;
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
432
437
|
inner.updateMatch(matchId, (prev) => ({
|
|
433
438
|
...prev,
|
|
434
439
|
status: prev.status === "pending" ? "success" : prev.status,
|
|
@@ -470,6 +475,33 @@ const runLoader = async (inner, matchId, index, route) => {
|
|
|
470
475
|
}
|
|
471
476
|
};
|
|
472
477
|
const loadRouteMatch = async (inner, index) => {
|
|
478
|
+
async function handleLoader(preload, prevMatch, match2, route2) {
|
|
479
|
+
const age = Date.now() - prevMatch.updatedAt;
|
|
480
|
+
const staleAge = preload ? route2.options.preloadStaleTime ?? inner.router.options.defaultPreloadStaleTime ?? 3e4 : route2.options.staleTime ?? inner.router.options.defaultStaleTime ?? 0;
|
|
481
|
+
const shouldReloadOption = route2.options.shouldReload;
|
|
482
|
+
const shouldReload = typeof shouldReloadOption === "function" ? shouldReloadOption(getLoaderContext(inner, matchId, index, route2)) : shouldReloadOption;
|
|
483
|
+
const { status, invalid } = match2;
|
|
484
|
+
loaderShouldRunAsync = status === "success" && (invalid || (shouldReload ?? age > staleAge));
|
|
485
|
+
if (preload && route2.options.preload === false) ;
|
|
486
|
+
else if (loaderShouldRunAsync && !inner.sync) {
|
|
487
|
+
loaderIsRunningAsync = true;
|
|
488
|
+
(async () => {
|
|
489
|
+
try {
|
|
490
|
+
await runLoader(inner, matchId, index, route2);
|
|
491
|
+
const match3 = inner.router.getMatch(matchId);
|
|
492
|
+
match3._nonReactive.loaderPromise?.resolve();
|
|
493
|
+
match3._nonReactive.loadPromise?.resolve();
|
|
494
|
+
match3._nonReactive.loaderPromise = void 0;
|
|
495
|
+
} catch (err) {
|
|
496
|
+
if (redirect.isRedirect(err)) {
|
|
497
|
+
await inner.router.navigate(err.options);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
})();
|
|
501
|
+
} else if (status !== "success" || loaderShouldRunAsync && inner.sync) {
|
|
502
|
+
await runLoader(inner, matchId, index, route2);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
473
505
|
const { id: matchId, routeId } = inner.matches[index];
|
|
474
506
|
let loaderShouldRunAsync = false;
|
|
475
507
|
let loaderIsRunningAsync = false;
|
|
@@ -480,6 +512,7 @@ const loadRouteMatch = async (inner, index) => {
|
|
|
480
512
|
}
|
|
481
513
|
} else {
|
|
482
514
|
const prevMatch = inner.router.getMatch(matchId);
|
|
515
|
+
const preload = resolvePreload(inner, matchId);
|
|
483
516
|
if (prevMatch._nonReactive.loaderPromise) {
|
|
484
517
|
if (prevMatch.status === "success" && !inner.sync && !prevMatch.preload) {
|
|
485
518
|
return prevMatch;
|
|
@@ -490,13 +523,11 @@ const loadRouteMatch = async (inner, index) => {
|
|
|
490
523
|
if (error) {
|
|
491
524
|
handleRedirectAndNotFound(inner, match2, error);
|
|
492
525
|
}
|
|
526
|
+
if (match2.status === "pending") {
|
|
527
|
+
await handleLoader(preload, prevMatch, match2, route);
|
|
528
|
+
}
|
|
493
529
|
} else {
|
|
494
|
-
const
|
|
495
|
-
const preload = resolvePreload(inner, matchId);
|
|
496
|
-
const staleAge = preload ? route.options.preloadStaleTime ?? inner.router.options.defaultPreloadStaleTime ?? 3e4 : route.options.staleTime ?? inner.router.options.defaultStaleTime ?? 0;
|
|
497
|
-
const shouldReloadOption = route.options.shouldReload;
|
|
498
|
-
const shouldReload = typeof shouldReloadOption === "function" ? shouldReloadOption(getLoaderContext(inner, matchId, index, route)) : shouldReloadOption;
|
|
499
|
-
const nextPreload = !!preload && !inner.router.state.matches.some((d) => d.id === matchId);
|
|
530
|
+
const nextPreload = preload && !inner.router.state.matches.some((d) => d.id === matchId);
|
|
500
531
|
const match2 = inner.router.getMatch(matchId);
|
|
501
532
|
match2._nonReactive.loaderPromise = utils.createControlledPromise();
|
|
502
533
|
if (nextPreload !== match2.preload) {
|
|
@@ -505,27 +536,7 @@ const loadRouteMatch = async (inner, index) => {
|
|
|
505
536
|
preload: nextPreload
|
|
506
537
|
}));
|
|
507
538
|
}
|
|
508
|
-
|
|
509
|
-
loaderShouldRunAsync = status === "success" && (invalid || (shouldReload ?? age > staleAge));
|
|
510
|
-
if (preload && route.options.preload === false) ;
|
|
511
|
-
else if (loaderShouldRunAsync && !inner.sync) {
|
|
512
|
-
loaderIsRunningAsync = true;
|
|
513
|
-
(async () => {
|
|
514
|
-
try {
|
|
515
|
-
await runLoader(inner, matchId, index, route);
|
|
516
|
-
const match3 = inner.router.getMatch(matchId);
|
|
517
|
-
match3._nonReactive.loaderPromise?.resolve();
|
|
518
|
-
match3._nonReactive.loadPromise?.resolve();
|
|
519
|
-
match3._nonReactive.loaderPromise = void 0;
|
|
520
|
-
} catch (err) {
|
|
521
|
-
if (redirect.isRedirect(err)) {
|
|
522
|
-
await inner.router.navigate(err.options);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
})();
|
|
526
|
-
} else if (status !== "success" || loaderShouldRunAsync && inner.sync) {
|
|
527
|
-
await runLoader(inner, matchId, index, route);
|
|
528
|
-
}
|
|
539
|
+
await handleLoader(preload, prevMatch, match2, route);
|
|
529
540
|
}
|
|
530
541
|
}
|
|
531
542
|
const match = inner.router.getMatch(matchId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-matches.cjs","sources":["../../src/load-matches.ts"],"sourcesContent":["import invariant from 'tiny-invariant'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { batch } from './utils/batch'\nimport { createControlledPromise, isPromise } from './utils'\nimport { isNotFound } from './not-found'\nimport { rootRouteId } from './root'\nimport { isRedirect } from './redirect'\nimport type { NotFoundError } from './not-found'\nimport type { ParsedLocation } from './location'\nimport type {\n AnyRoute,\n BeforeLoadContextOptions,\n LoaderFnContext,\n SsrContextOptions,\n} from './route'\nimport type { AnyRouteMatch, MakeRouteMatch } from './Matches'\nimport type { AnyRouter, SSROption, UpdateMatchFn } from './router'\n\n/**\n * An object of this shape is created when calling `loadMatches`.\n * It contains everything we need for all other functions in this file\n * to work. (It's basically the function's argument, plus a few mutable states)\n */\ntype InnerLoadContext = {\n /** the calling router instance */\n router: AnyRouter\n location: ParsedLocation\n /** mutable state, scoped to a `loadMatches` call */\n firstBadMatchIndex?: number\n /** mutable state, scoped to a `loadMatches` call */\n rendered?: boolean\n updateMatch: UpdateMatchFn\n matches: Array<AnyRouteMatch>\n preload?: boolean\n onReady?: () => Promise<void>\n sync?: boolean\n /** mutable state, scoped to a `loadMatches` call */\n matchPromises: Array<Promise<AnyRouteMatch>>\n}\n\nconst triggerOnReady = (inner: InnerLoadContext): void | Promise<void> => {\n if (!inner.rendered) {\n inner.rendered = true\n return inner.onReady?.()\n }\n}\n\nconst resolvePreload = (inner: InnerLoadContext, matchId: string): boolean => {\n return !!(\n inner.preload && !inner.router.state.matches.some((d) => d.id === matchId)\n )\n}\n\n/**\n * Builds the accumulated context from router options and all matches up to (and optionally including) the given index.\n * Merges __routeContext and __beforeLoadContext from each match.\n */\nconst buildMatchContext = (\n inner: InnerLoadContext,\n index: number,\n includeCurrentMatch: boolean = true,\n): Record<string, unknown> => {\n const context: Record<string, unknown> = {\n ...(inner.router.options.context ?? {}),\n }\n const end = includeCurrentMatch ? index : index - 1\n for (let i = 0; i <= end; i++) {\n const innerMatch = inner.matches[i]\n if (!innerMatch) continue\n const m = inner.router.getMatch(innerMatch.id)\n if (!m) continue\n Object.assign(context, m.__routeContext, m.__beforeLoadContext)\n }\n return context\n}\n\nconst _handleNotFound = (inner: InnerLoadContext, err: NotFoundError) => {\n // Find the route that should handle the not found error\n // First check if a specific route is requested to show the error\n const routeCursor =\n inner.router.routesById[err.routeId ?? ''] ?? inner.router.routeTree\n\n // Ensure a NotFoundComponent exists on the route\n if (\n !routeCursor.options.notFoundComponent &&\n (inner.router.options as any)?.defaultNotFoundComponent\n ) {\n routeCursor.options.notFoundComponent = (\n inner.router.options as any\n ).defaultNotFoundComponent\n }\n\n // Ensure we have a notFoundComponent\n invariant(\n routeCursor.options.notFoundComponent,\n 'No notFoundComponent found. Please set a notFoundComponent on your route or provide a defaultNotFoundComponent to the router.',\n )\n\n // Find the match for this route\n const matchForRoute = inner.matches.find((m) => m.routeId === routeCursor.id)\n\n invariant(matchForRoute, 'Could not find match for route: ' + routeCursor.id)\n\n // Assign the error to the match - using non-null assertion since we've checked with invariant\n inner.updateMatch(matchForRoute.id, (prev) => ({\n ...prev,\n status: 'notFound',\n error: err,\n isFetching: false,\n }))\n\n if ((err as any).routerCode === 'BEFORE_LOAD' && routeCursor.parentRoute) {\n err.routeId = routeCursor.parentRoute.id\n _handleNotFound(inner, err)\n }\n}\n\nconst handleRedirectAndNotFound = (\n inner: InnerLoadContext,\n match: AnyRouteMatch | undefined,\n err: unknown,\n): void => {\n if (!isRedirect(err) && !isNotFound(err)) return\n\n if (isRedirect(err) && err.redirectHandled && !err.options.reloadDocument) {\n throw err\n }\n\n // in case of a redirecting match during preload, the match does not exist\n if (match) {\n match._nonReactive.beforeLoadPromise?.resolve()\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.beforeLoadPromise = undefined\n match._nonReactive.loaderPromise = undefined\n\n const status = isRedirect(err) ? 'redirected' : 'notFound'\n\n match._nonReactive.error = err\n\n inner.updateMatch(match.id, (prev) => ({\n ...prev,\n status,\n context: buildMatchContext(inner, match.index),\n isFetching: false,\n error: err,\n }))\n\n if (isNotFound(err) && !err.routeId) {\n err.routeId = match.routeId\n }\n\n match._nonReactive.loadPromise?.resolve()\n }\n\n if (isRedirect(err)) {\n inner.rendered = true\n err.options._fromLocation = inner.location\n err.redirectHandled = true\n err = inner.router.resolveRedirect(err)\n throw err\n } else {\n _handleNotFound(inner, err)\n throw err\n }\n}\n\nconst shouldSkipLoader = (\n inner: InnerLoadContext,\n matchId: string,\n): boolean => {\n const match = inner.router.getMatch(matchId)!\n // upon hydration, we skip the loader if the match has been dehydrated on the server\n if (!(isServer ?? inner.router.isServer) && match._nonReactive.dehydrated) {\n return true\n }\n\n if ((isServer ?? inner.router.isServer) && match.ssr === false) {\n return true\n }\n\n return false\n}\n\nconst handleSerialError = (\n inner: InnerLoadContext,\n index: number,\n err: any,\n routerCode: string,\n): void => {\n const { id: matchId, routeId } = inner.matches[index]!\n const route = inner.router.looseRoutesById[routeId]!\n\n // Much like suspense, we use a promise here to know if\n // we've been outdated by a new loadMatches call and\n // should abort the current async operation\n if (err instanceof Promise) {\n throw err\n }\n\n err.routerCode = routerCode\n inner.firstBadMatchIndex ??= index\n handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), err)\n\n try {\n route.options.onError?.(err)\n } catch (errorHandlerErr) {\n err = errorHandlerErr\n handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), err)\n }\n\n inner.updateMatch(matchId, (prev) => {\n prev._nonReactive.beforeLoadPromise?.resolve()\n prev._nonReactive.beforeLoadPromise = undefined\n prev._nonReactive.loadPromise?.resolve()\n\n return {\n ...prev,\n error: err,\n status: 'error',\n isFetching: false,\n updatedAt: Date.now(),\n abortController: new AbortController(),\n }\n })\n}\n\nconst isBeforeLoadSsr = (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): void | Promise<void> => {\n const existingMatch = inner.router.getMatch(matchId)!\n const parentMatchId = inner.matches[index - 1]?.id\n const parentMatch = parentMatchId\n ? inner.router.getMatch(parentMatchId)!\n : undefined\n\n // in SPA mode, only SSR the root route\n if (inner.router.isShell()) {\n existingMatch.ssr = route.id === rootRouteId\n return\n }\n\n if (parentMatch?.ssr === false) {\n existingMatch.ssr = false\n return\n }\n\n const parentOverride = (tempSsr: SSROption) => {\n if (tempSsr === true && parentMatch?.ssr === 'data-only') {\n return 'data-only'\n }\n return tempSsr\n }\n\n const defaultSsr = inner.router.options.defaultSsr ?? true\n\n if (route.options.ssr === undefined) {\n existingMatch.ssr = parentOverride(defaultSsr)\n return\n }\n\n if (typeof route.options.ssr !== 'function') {\n existingMatch.ssr = parentOverride(route.options.ssr)\n return\n }\n const { search, params } = existingMatch\n\n const ssrFnContext: SsrContextOptions<any, any, any> = {\n search: makeMaybe(search, existingMatch.searchError),\n params: makeMaybe(params, existingMatch.paramsError),\n location: inner.location,\n matches: inner.matches.map((match) => ({\n index: match.index,\n pathname: match.pathname,\n fullPath: match.fullPath,\n staticData: match.staticData,\n id: match.id,\n routeId: match.routeId,\n search: makeMaybe(match.search, match.searchError),\n params: makeMaybe(match.params, match.paramsError),\n ssr: match.ssr,\n })),\n }\n\n const tempSsr = route.options.ssr(ssrFnContext)\n if (isPromise(tempSsr)) {\n return tempSsr.then((ssr) => {\n existingMatch.ssr = parentOverride(ssr ?? defaultSsr)\n })\n }\n\n existingMatch.ssr = parentOverride(tempSsr ?? defaultSsr)\n return\n}\n\nconst setupPendingTimeout = (\n inner: InnerLoadContext,\n matchId: string,\n route: AnyRoute,\n match: AnyRouteMatch,\n): void => {\n if (match._nonReactive.pendingTimeout !== undefined) return\n\n const pendingMs =\n route.options.pendingMs ?? inner.router.options.defaultPendingMs\n const shouldPending = !!(\n inner.onReady &&\n !(isServer ?? inner.router.isServer) &&\n !resolvePreload(inner, matchId) &&\n (route.options.loader ||\n route.options.beforeLoad ||\n routeNeedsPreload(route)) &&\n typeof pendingMs === 'number' &&\n pendingMs !== Infinity &&\n (route.options.pendingComponent ??\n (inner.router.options as any)?.defaultPendingComponent)\n )\n\n if (shouldPending) {\n const pendingTimeout = setTimeout(() => {\n // Update the match and prematurely resolve the loadMatches promise so that\n // the pending component can start rendering\n triggerOnReady(inner)\n }, pendingMs)\n match._nonReactive.pendingTimeout = pendingTimeout\n }\n}\n\nconst preBeforeLoadSetup = (\n inner: InnerLoadContext,\n matchId: string,\n route: AnyRoute,\n): void | Promise<void> => {\n const existingMatch = inner.router.getMatch(matchId)!\n\n // If we are in the middle of a load, either of these will be present\n // (not to be confused with `loadPromise`, which is always defined)\n if (\n !existingMatch._nonReactive.beforeLoadPromise &&\n !existingMatch._nonReactive.loaderPromise\n )\n return\n\n setupPendingTimeout(inner, matchId, route, existingMatch)\n\n const then = () => {\n const match = inner.router.getMatch(matchId)!\n if (\n match.preload &&\n (match.status === 'redirected' || match.status === 'notFound')\n ) {\n handleRedirectAndNotFound(inner, match, match.error)\n }\n }\n\n // Wait for the previous beforeLoad to resolve before we continue\n return existingMatch._nonReactive.beforeLoadPromise\n ? existingMatch._nonReactive.beforeLoadPromise.then(then)\n : then()\n}\n\nconst executeBeforeLoad = (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): void | Promise<void> => {\n const match = inner.router.getMatch(matchId)!\n\n // explicitly capture the previous loadPromise\n const prevLoadPromise = match._nonReactive.loadPromise\n match._nonReactive.loadPromise = createControlledPromise<void>(() => {\n prevLoadPromise?.resolve()\n })\n\n const { paramsError, searchError } = match\n\n if (paramsError) {\n handleSerialError(inner, index, paramsError, 'PARSE_PARAMS')\n }\n\n if (searchError) {\n handleSerialError(inner, index, searchError, 'VALIDATE_SEARCH')\n }\n\n setupPendingTimeout(inner, matchId, route, match)\n\n const abortController = new AbortController()\n\n let isPending = false\n const pending = () => {\n if (isPending) return\n isPending = true\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: 'beforeLoad',\n fetchCount: prev.fetchCount + 1,\n abortController,\n // Note: We intentionally don't update context here.\n // Context should only be updated after beforeLoad resolves to avoid\n // components seeing incomplete context during async beforeLoad execution.\n }))\n }\n\n const resolve = () => {\n match._nonReactive.beforeLoadPromise?.resolve()\n match._nonReactive.beforeLoadPromise = undefined\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: false,\n }))\n }\n\n // if there is no `beforeLoad` option, just mark as pending and resolve\n // Context will be updated later in loadRouteMatch after loader completes\n if (!route.options.beforeLoad) {\n batch(() => {\n pending()\n resolve()\n })\n return\n }\n\n match._nonReactive.beforeLoadPromise = createControlledPromise<void>()\n\n // Build context from all parent matches, excluding current match's __beforeLoadContext\n // (since we're about to execute beforeLoad for this match)\n const context = {\n ...buildMatchContext(inner, index, false),\n ...match.__routeContext,\n }\n const { search, params, cause } = match\n const preload = resolvePreload(inner, matchId)\n const beforeLoadFnContext: BeforeLoadContextOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = {\n search,\n abortController,\n params,\n preload,\n context,\n location: inner.location,\n navigate: (opts: any) =>\n inner.router.navigate({\n ...opts,\n _fromLocation: inner.location,\n }),\n buildLocation: inner.router.buildLocation,\n cause: preload ? 'preload' : cause,\n matches: inner.matches,\n routeId: route.id,\n ...inner.router.options.additionalContext,\n }\n\n const updateContext = (beforeLoadContext: any) => {\n if (beforeLoadContext === undefined) {\n batch(() => {\n pending()\n resolve()\n })\n return\n }\n if (isRedirect(beforeLoadContext) || isNotFound(beforeLoadContext)) {\n pending()\n handleSerialError(inner, index, beforeLoadContext, 'BEFORE_LOAD')\n }\n\n batch(() => {\n pending()\n // Only store __beforeLoadContext here, don't update context yet\n // Context will be updated in loadRouteMatch after loader completes\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n __beforeLoadContext: beforeLoadContext,\n }))\n resolve()\n })\n }\n\n let beforeLoadContext\n try {\n beforeLoadContext = route.options.beforeLoad(beforeLoadFnContext)\n if (isPromise(beforeLoadContext)) {\n pending()\n return beforeLoadContext\n .catch((err) => {\n handleSerialError(inner, index, err, 'BEFORE_LOAD')\n })\n .then(updateContext)\n }\n } catch (err) {\n pending()\n handleSerialError(inner, index, err, 'BEFORE_LOAD')\n }\n\n updateContext(beforeLoadContext)\n return\n}\n\nconst handleBeforeLoad = (\n inner: InnerLoadContext,\n index: number,\n): void | Promise<void> => {\n const { id: matchId, routeId } = inner.matches[index]!\n const route = inner.router.looseRoutesById[routeId]!\n\n const serverSsr = () => {\n // on the server, determine whether SSR the current match or not\n if (isServer ?? inner.router.isServer) {\n const maybePromise = isBeforeLoadSsr(inner, matchId, index, route)\n if (isPromise(maybePromise)) return maybePromise.then(queueExecution)\n }\n return queueExecution()\n }\n\n const execute = () => executeBeforeLoad(inner, matchId, index, route)\n\n const queueExecution = () => {\n if (shouldSkipLoader(inner, matchId)) return\n const result = preBeforeLoadSetup(inner, matchId, route)\n return isPromise(result) ? result.then(execute) : execute()\n }\n\n return serverSsr()\n}\n\nconst executeHead = (\n inner: InnerLoadContext,\n matchId: string,\n route: AnyRoute,\n): void | Promise<\n Pick<\n AnyRouteMatch,\n 'meta' | 'links' | 'headScripts' | 'headers' | 'scripts' | 'styles'\n >\n> => {\n const match = inner.router.getMatch(matchId)\n // in case of a redirecting match during preload, the match does not exist\n if (!match) {\n return\n }\n if (!route.options.head && !route.options.scripts && !route.options.headers) {\n return\n }\n const assetContext = {\n ssr: inner.router.options.ssr,\n matches: inner.matches,\n match,\n params: match.params,\n loaderData: match.loaderData,\n }\n\n return Promise.all([\n route.options.head?.(assetContext),\n route.options.scripts?.(assetContext),\n route.options.headers?.(assetContext),\n ]).then(([headFnContent, scripts, headers]) => {\n const meta = headFnContent?.meta\n const links = headFnContent?.links\n const headScripts = headFnContent?.scripts\n const styles = headFnContent?.styles\n\n return {\n meta,\n links,\n headScripts,\n headers,\n scripts,\n styles,\n }\n })\n}\n\nconst getLoaderContext = (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): LoaderFnContext => {\n const parentMatchPromise = inner.matchPromises[index - 1] as any\n const { params, loaderDeps, abortController, cause } =\n inner.router.getMatch(matchId)!\n\n const context = buildMatchContext(inner, index)\n\n const preload = resolvePreload(inner, matchId)\n\n return {\n params,\n deps: loaderDeps,\n preload: !!preload,\n parentMatchPromise,\n abortController,\n context,\n location: inner.location,\n navigate: (opts) =>\n inner.router.navigate({\n ...opts,\n _fromLocation: inner.location,\n }),\n cause: preload ? 'preload' : cause,\n route,\n ...inner.router.options.additionalContext,\n }\n}\n\nconst runLoader = async (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): Promise<void> => {\n try {\n // If the Matches component rendered\n // the pending component and needs to show it for\n // a minimum duration, we''ll wait for it to resolve\n // before committing to the match and resolving\n // the loadPromise\n\n const match = inner.router.getMatch(matchId)!\n\n // Actually run the loader and handle the result\n try {\n if (!(isServer ?? inner.router.isServer) || match.ssr === true) {\n loadRouteChunk(route)\n }\n\n // Kick off the loader!\n const loaderResult = route.options.loader?.(\n getLoaderContext(inner, matchId, index, route),\n )\n const loaderResultIsPromise =\n route.options.loader && isPromise(loaderResult)\n\n const willLoadSomething = !!(\n loaderResultIsPromise ||\n route._lazyPromise ||\n route._componentsPromise ||\n route.options.head ||\n route.options.scripts ||\n route.options.headers ||\n match._nonReactive.minPendingPromise\n )\n\n if (willLoadSomething) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: 'loader',\n }))\n }\n\n if (route.options.loader) {\n const loaderData = loaderResultIsPromise\n ? await loaderResult\n : loaderResult\n\n handleRedirectAndNotFound(\n inner,\n inner.router.getMatch(matchId),\n loaderData,\n )\n if (loaderData !== undefined) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n loaderData,\n }))\n }\n }\n\n // Lazy option can modify the route options,\n // so we need to wait for it to resolve before\n // we can use the options\n if (route._lazyPromise) await route._lazyPromise\n const pendingPromise = match._nonReactive.minPendingPromise\n if (pendingPromise) await pendingPromise\n\n // Last but not least, wait for the the components\n // to be preloaded before we resolve the match\n if (route._componentsPromise) await route._componentsPromise\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n error: undefined,\n context: buildMatchContext(inner, index),\n status: 'success',\n isFetching: false,\n updatedAt: Date.now(),\n }))\n } catch (e) {\n let error = e\n\n if ((error as any)?.name === 'AbortError') {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n status: prev.status === 'pending' ? 'success' : prev.status,\n isFetching: false,\n context: buildMatchContext(inner, index),\n }))\n return\n }\n\n const pendingPromise = match._nonReactive.minPendingPromise\n if (pendingPromise) await pendingPromise\n\n if (isNotFound(e)) {\n await (route.options.notFoundComponent as any)?.preload?.()\n }\n\n handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), e)\n\n try {\n route.options.onError?.(e)\n } catch (onErrorError) {\n error = onErrorError\n handleRedirectAndNotFound(\n inner,\n inner.router.getMatch(matchId),\n onErrorError,\n )\n }\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n error,\n context: buildMatchContext(inner, index),\n status: 'error',\n isFetching: false,\n }))\n }\n } catch (err) {\n const match = inner.router.getMatch(matchId)\n // in case of a redirecting match during preload, the match does not exist\n if (match) {\n match._nonReactive.loaderPromise = undefined\n }\n handleRedirectAndNotFound(inner, match, err)\n }\n}\n\nconst loadRouteMatch = async (\n inner: InnerLoadContext,\n index: number,\n): Promise<AnyRouteMatch> => {\n const { id: matchId, routeId } = inner.matches[index]!\n let loaderShouldRunAsync = false\n let loaderIsRunningAsync = false\n const route = inner.router.looseRoutesById[routeId]!\n\n if (shouldSkipLoader(inner, matchId)) {\n if (isServer ?? inner.router.isServer) {\n return inner.router.getMatch(matchId)!\n }\n } else {\n const prevMatch = inner.router.getMatch(matchId)!\n // there is a loaderPromise, so we are in the middle of a load\n if (prevMatch._nonReactive.loaderPromise) {\n // do not block if we already have stale data we can show\n // but only if the ongoing load is not a preload since error handling is different for preloads\n // and we don't want to swallow errors\n if (prevMatch.status === 'success' && !inner.sync && !prevMatch.preload) {\n return prevMatch\n }\n await prevMatch._nonReactive.loaderPromise\n const match = inner.router.getMatch(matchId)!\n const error = match._nonReactive.error || match.error\n if (error) {\n handleRedirectAndNotFound(inner, match, error)\n }\n } else {\n // This is where all of the stale-while-revalidate magic happens\n const age = Date.now() - prevMatch.updatedAt\n\n const preload = resolvePreload(inner, matchId)\n\n const staleAge = preload\n ? (route.options.preloadStaleTime ??\n inner.router.options.defaultPreloadStaleTime ??\n 30_000) // 30 seconds for preloads by default\n : (route.options.staleTime ??\n inner.router.options.defaultStaleTime ??\n 0)\n\n const shouldReloadOption = route.options.shouldReload\n\n // Default to reloading the route all the time\n // Allow shouldReload to get the last say,\n // if provided.\n const shouldReload =\n typeof shouldReloadOption === 'function'\n ? shouldReloadOption(getLoaderContext(inner, matchId, index, route))\n : shouldReloadOption\n\n const nextPreload =\n !!preload && !inner.router.state.matches.some((d) => d.id === matchId)\n const match = inner.router.getMatch(matchId)!\n match._nonReactive.loaderPromise = createControlledPromise<void>()\n if (nextPreload !== match.preload) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n preload: nextPreload,\n }))\n }\n\n // If the route is successful and still fresh, just resolve\n const { status, invalid } = match\n loaderShouldRunAsync =\n status === 'success' && (invalid || (shouldReload ?? age > staleAge))\n if (preload && route.options.preload === false) {\n // Do nothing\n } else if (loaderShouldRunAsync && !inner.sync) {\n loaderIsRunningAsync = true\n ;(async () => {\n try {\n await runLoader(inner, matchId, index, route)\n const match = inner.router.getMatch(matchId)!\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.loadPromise?.resolve()\n match._nonReactive.loaderPromise = undefined\n } catch (err) {\n if (isRedirect(err)) {\n await inner.router.navigate(err.options)\n }\n }\n })()\n } else if (status !== 'success' || (loaderShouldRunAsync && inner.sync)) {\n await runLoader(inner, matchId, index, route)\n }\n }\n }\n const match = inner.router.getMatch(matchId)!\n if (!loaderIsRunningAsync) {\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.loadPromise?.resolve()\n }\n\n clearTimeout(match._nonReactive.pendingTimeout)\n match._nonReactive.pendingTimeout = undefined\n if (!loaderIsRunningAsync) match._nonReactive.loaderPromise = undefined\n match._nonReactive.dehydrated = undefined\n\n const nextIsFetching = loaderIsRunningAsync ? match.isFetching : false\n if (nextIsFetching !== match.isFetching || match.invalid !== false) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: nextIsFetching,\n invalid: false,\n }))\n return inner.router.getMatch(matchId)!\n } else {\n return match\n }\n}\n\nexport async function loadMatches(arg: {\n router: AnyRouter\n location: ParsedLocation\n matches: Array<AnyRouteMatch>\n preload?: boolean\n onReady?: () => Promise<void>\n updateMatch: UpdateMatchFn\n sync?: boolean\n}): Promise<Array<MakeRouteMatch>> {\n const inner: InnerLoadContext = Object.assign(arg, {\n matchPromises: [],\n })\n\n // make sure the pending component is immediately rendered when hydrating a match that is not SSRed\n // the pending component was already rendered on the server and we want to keep it shown on the client until minPendingMs is reached\n if (\n !(isServer ?? inner.router.isServer) &&\n inner.router.state.matches.some((d) => d._forcePending)\n ) {\n triggerOnReady(inner)\n }\n\n try {\n // Execute all beforeLoads one by one\n for (let i = 0; i < inner.matches.length; i++) {\n const beforeLoad = handleBeforeLoad(inner, i)\n if (isPromise(beforeLoad)) await beforeLoad\n }\n\n // Execute all loaders in parallel\n const max = inner.firstBadMatchIndex ?? inner.matches.length\n for (let i = 0; i < max; i++) {\n inner.matchPromises.push(loadRouteMatch(inner, i))\n }\n // Use allSettled to ensure all loaders complete regardless of success/failure\n const results = await Promise.allSettled(inner.matchPromises)\n\n const failures = results\n // TODO when we drop support for TS 5.4, we can use the built-in type guard for PromiseRejectedResult\n .filter(\n (result): result is PromiseRejectedResult =>\n result.status === 'rejected',\n )\n .map((result) => result.reason)\n\n // Find first redirect (throw immediately) or notFound (throw after head execution)\n let firstNotFound: unknown\n for (const err of failures) {\n if (isRedirect(err)) {\n throw err\n }\n if (!firstNotFound && isNotFound(err)) {\n firstNotFound = err\n }\n }\n\n // serially execute head functions after all loaders have completed (successfully or not)\n // Each head execution is wrapped in try-catch to ensure all heads run even if one fails\n for (const match of inner.matches) {\n const { id: matchId, routeId } = match\n const route = inner.router.looseRoutesById[routeId]!\n try {\n const headResult = executeHead(inner, matchId, route)\n if (headResult) {\n const head = await headResult\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n ...head,\n }))\n }\n } catch (err) {\n // Log error but continue executing other head functions\n console.error(`Error executing head for route ${routeId}:`, err)\n }\n }\n\n // Throw notFound after head execution\n if (firstNotFound) {\n throw firstNotFound\n }\n\n const readyPromise = triggerOnReady(inner)\n if (isPromise(readyPromise)) await readyPromise\n } catch (err) {\n if (isNotFound(err) && !inner.preload) {\n const readyPromise = triggerOnReady(inner)\n if (isPromise(readyPromise)) await readyPromise\n throw err\n }\n if (isRedirect(err)) {\n throw err\n }\n }\n return inner.matches\n}\n\nexport async function loadRouteChunk(route: AnyRoute) {\n if (!route._lazyLoaded && route._lazyPromise === undefined) {\n if (route.lazyFn) {\n route._lazyPromise = route.lazyFn().then((lazyRoute) => {\n // explicitly don't copy over the lazy route's id\n const { id: _id, ...options } = lazyRoute.options\n Object.assign(route.options, options)\n route._lazyLoaded = true\n route._lazyPromise = undefined // gc promise, we won't need it anymore\n })\n } else {\n route._lazyLoaded = true\n }\n }\n\n // If for some reason lazy resolves more lazy components...\n // We'll wait for that before we attempt to preload the\n // components themselves.\n if (!route._componentsLoaded && route._componentsPromise === undefined) {\n const loadComponents = () => {\n const preloads = []\n for (const type of componentTypes) {\n const preload = (route.options[type] as any)?.preload\n if (preload) preloads.push(preload())\n }\n if (preloads.length)\n return Promise.all(preloads).then(() => {\n route._componentsLoaded = true\n route._componentsPromise = undefined // gc promise, we won't need it anymore\n })\n route._componentsLoaded = true\n route._componentsPromise = undefined // gc promise, we won't need it anymore\n return\n }\n route._componentsPromise = route._lazyPromise\n ? route._lazyPromise.then(loadComponents)\n : loadComponents()\n }\n return route._componentsPromise\n}\n\nfunction makeMaybe<TValue, TError>(\n value: TValue,\n error: TError,\n): { status: 'success'; value: TValue } | { status: 'error'; error: TError } {\n if (error) {\n return { status: 'error' as const, error }\n }\n return { status: 'success' as const, value }\n}\n\nexport function routeNeedsPreload(route: AnyRoute) {\n for (const componentType of componentTypes) {\n if ((route.options[componentType] as any)?.preload) {\n return true\n }\n }\n return false\n}\n\nexport const componentTypes = [\n 'component',\n 'errorComponent',\n 'pendingComponent',\n 'notFoundComponent',\n] as const\n"],"names":["isRedirect","isNotFound","isServer","rootRouteId","tempSsr","isPromise","createControlledPromise","batch","beforeLoadContext","match"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"load-matches.cjs","sources":["../../src/load-matches.ts"],"sourcesContent":["import invariant from 'tiny-invariant'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { batch } from './utils/batch'\nimport { createControlledPromise, isPromise } from './utils'\nimport { isNotFound } from './not-found'\nimport { rootRouteId } from './root'\nimport { isRedirect } from './redirect'\nimport type { NotFoundError } from './not-found'\nimport type { ParsedLocation } from './location'\nimport type {\n AnyRoute,\n BeforeLoadContextOptions,\n LoaderFnContext,\n SsrContextOptions,\n} from './route'\nimport type { AnyRouteMatch, MakeRouteMatch } from './Matches'\nimport type { AnyRouter, SSROption, UpdateMatchFn } from './router'\n\n/**\n * An object of this shape is created when calling `loadMatches`.\n * It contains everything we need for all other functions in this file\n * to work. (It's basically the function's argument, plus a few mutable states)\n */\ntype InnerLoadContext = {\n /** the calling router instance */\n router: AnyRouter\n location: ParsedLocation\n /** mutable state, scoped to a `loadMatches` call */\n firstBadMatchIndex?: number\n /** mutable state, scoped to a `loadMatches` call */\n rendered?: boolean\n updateMatch: UpdateMatchFn\n matches: Array<AnyRouteMatch>\n preload?: boolean\n onReady?: () => Promise<void>\n sync?: boolean\n /** mutable state, scoped to a `loadMatches` call */\n matchPromises: Array<Promise<AnyRouteMatch>>\n}\n\nconst triggerOnReady = (inner: InnerLoadContext): void | Promise<void> => {\n if (!inner.rendered) {\n inner.rendered = true\n return inner.onReady?.()\n }\n}\n\nconst resolvePreload = (inner: InnerLoadContext, matchId: string): boolean => {\n return !!(\n inner.preload && !inner.router.state.matches.some((d) => d.id === matchId)\n )\n}\n\n/**\n * Builds the accumulated context from router options and all matches up to (and optionally including) the given index.\n * Merges __routeContext and __beforeLoadContext from each match.\n */\nconst buildMatchContext = (\n inner: InnerLoadContext,\n index: number,\n includeCurrentMatch: boolean = true,\n): Record<string, unknown> => {\n const context: Record<string, unknown> = {\n ...(inner.router.options.context ?? {}),\n }\n const end = includeCurrentMatch ? index : index - 1\n for (let i = 0; i <= end; i++) {\n const innerMatch = inner.matches[i]\n if (!innerMatch) continue\n const m = inner.router.getMatch(innerMatch.id)\n if (!m) continue\n Object.assign(context, m.__routeContext, m.__beforeLoadContext)\n }\n return context\n}\n\nconst _handleNotFound = (inner: InnerLoadContext, err: NotFoundError) => {\n // Find the route that should handle the not found error\n // First check if a specific route is requested to show the error\n const routeCursor =\n inner.router.routesById[err.routeId ?? ''] ?? inner.router.routeTree\n\n // Ensure a NotFoundComponent exists on the route\n if (\n !routeCursor.options.notFoundComponent &&\n (inner.router.options as any)?.defaultNotFoundComponent\n ) {\n routeCursor.options.notFoundComponent = (\n inner.router.options as any\n ).defaultNotFoundComponent\n }\n\n // Ensure we have a notFoundComponent\n invariant(\n routeCursor.options.notFoundComponent,\n 'No notFoundComponent found. Please set a notFoundComponent on your route or provide a defaultNotFoundComponent to the router.',\n )\n\n // Find the match for this route\n const matchForRoute = inner.matches.find((m) => m.routeId === routeCursor.id)\n\n invariant(matchForRoute, 'Could not find match for route: ' + routeCursor.id)\n\n // Assign the error to the match - using non-null assertion since we've checked with invariant\n inner.updateMatch(matchForRoute.id, (prev) => ({\n ...prev,\n status: 'notFound',\n error: err,\n isFetching: false,\n }))\n\n if ((err as any).routerCode === 'BEFORE_LOAD' && routeCursor.parentRoute) {\n err.routeId = routeCursor.parentRoute.id\n _handleNotFound(inner, err)\n }\n}\n\nconst handleRedirectAndNotFound = (\n inner: InnerLoadContext,\n match: AnyRouteMatch | undefined,\n err: unknown,\n): void => {\n if (!isRedirect(err) && !isNotFound(err)) return\n\n if (isRedirect(err) && err.redirectHandled && !err.options.reloadDocument) {\n throw err\n }\n\n // in case of a redirecting match during preload, the match does not exist\n if (match) {\n match._nonReactive.beforeLoadPromise?.resolve()\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.beforeLoadPromise = undefined\n match._nonReactive.loaderPromise = undefined\n\n const status = isRedirect(err) ? 'redirected' : 'notFound'\n\n match._nonReactive.error = err\n\n inner.updateMatch(match.id, (prev) => ({\n ...prev,\n status,\n context: buildMatchContext(inner, match.index),\n isFetching: false,\n error: err,\n }))\n\n if (isNotFound(err) && !err.routeId) {\n err.routeId = match.routeId\n }\n\n match._nonReactive.loadPromise?.resolve()\n }\n\n if (isRedirect(err)) {\n inner.rendered = true\n err.options._fromLocation = inner.location\n err.redirectHandled = true\n err = inner.router.resolveRedirect(err)\n throw err\n } else {\n _handleNotFound(inner, err)\n throw err\n }\n}\n\nconst shouldSkipLoader = (\n inner: InnerLoadContext,\n matchId: string,\n): boolean => {\n const match = inner.router.getMatch(matchId)!\n // upon hydration, we skip the loader if the match has been dehydrated on the server\n if (!(isServer ?? inner.router.isServer) && match._nonReactive.dehydrated) {\n return true\n }\n\n if ((isServer ?? inner.router.isServer) && match.ssr === false) {\n return true\n }\n\n return false\n}\n\nconst handleSerialError = (\n inner: InnerLoadContext,\n index: number,\n err: any,\n routerCode: string,\n): void => {\n const { id: matchId, routeId } = inner.matches[index]!\n const route = inner.router.looseRoutesById[routeId]!\n\n // Much like suspense, we use a promise here to know if\n // we've been outdated by a new loadMatches call and\n // should abort the current async operation\n if (err instanceof Promise) {\n throw err\n }\n\n err.routerCode = routerCode\n inner.firstBadMatchIndex ??= index\n handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), err)\n\n try {\n route.options.onError?.(err)\n } catch (errorHandlerErr) {\n err = errorHandlerErr\n handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), err)\n }\n\n inner.updateMatch(matchId, (prev) => {\n prev._nonReactive.beforeLoadPromise?.resolve()\n prev._nonReactive.beforeLoadPromise = undefined\n prev._nonReactive.loadPromise?.resolve()\n\n return {\n ...prev,\n error: err,\n status: 'error',\n isFetching: false,\n updatedAt: Date.now(),\n abortController: new AbortController(),\n }\n })\n}\n\nconst isBeforeLoadSsr = (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): void | Promise<void> => {\n const existingMatch = inner.router.getMatch(matchId)!\n const parentMatchId = inner.matches[index - 1]?.id\n const parentMatch = parentMatchId\n ? inner.router.getMatch(parentMatchId)!\n : undefined\n\n // in SPA mode, only SSR the root route\n if (inner.router.isShell()) {\n existingMatch.ssr = route.id === rootRouteId\n return\n }\n\n if (parentMatch?.ssr === false) {\n existingMatch.ssr = false\n return\n }\n\n const parentOverride = (tempSsr: SSROption) => {\n if (tempSsr === true && parentMatch?.ssr === 'data-only') {\n return 'data-only'\n }\n return tempSsr\n }\n\n const defaultSsr = inner.router.options.defaultSsr ?? true\n\n if (route.options.ssr === undefined) {\n existingMatch.ssr = parentOverride(defaultSsr)\n return\n }\n\n if (typeof route.options.ssr !== 'function') {\n existingMatch.ssr = parentOverride(route.options.ssr)\n return\n }\n const { search, params } = existingMatch\n\n const ssrFnContext: SsrContextOptions<any, any, any> = {\n search: makeMaybe(search, existingMatch.searchError),\n params: makeMaybe(params, existingMatch.paramsError),\n location: inner.location,\n matches: inner.matches.map((match) => ({\n index: match.index,\n pathname: match.pathname,\n fullPath: match.fullPath,\n staticData: match.staticData,\n id: match.id,\n routeId: match.routeId,\n search: makeMaybe(match.search, match.searchError),\n params: makeMaybe(match.params, match.paramsError),\n ssr: match.ssr,\n })),\n }\n\n const tempSsr = route.options.ssr(ssrFnContext)\n if (isPromise(tempSsr)) {\n return tempSsr.then((ssr) => {\n existingMatch.ssr = parentOverride(ssr ?? defaultSsr)\n })\n }\n\n existingMatch.ssr = parentOverride(tempSsr ?? defaultSsr)\n return\n}\n\nconst setupPendingTimeout = (\n inner: InnerLoadContext,\n matchId: string,\n route: AnyRoute,\n match: AnyRouteMatch,\n): void => {\n if (match._nonReactive.pendingTimeout !== undefined) return\n\n const pendingMs =\n route.options.pendingMs ?? inner.router.options.defaultPendingMs\n const shouldPending = !!(\n inner.onReady &&\n !(isServer ?? inner.router.isServer) &&\n !resolvePreload(inner, matchId) &&\n (route.options.loader ||\n route.options.beforeLoad ||\n routeNeedsPreload(route)) &&\n typeof pendingMs === 'number' &&\n pendingMs !== Infinity &&\n (route.options.pendingComponent ??\n (inner.router.options as any)?.defaultPendingComponent)\n )\n\n if (shouldPending) {\n const pendingTimeout = setTimeout(() => {\n // Update the match and prematurely resolve the loadMatches promise so that\n // the pending component can start rendering\n triggerOnReady(inner)\n }, pendingMs)\n match._nonReactive.pendingTimeout = pendingTimeout\n }\n}\n\nconst preBeforeLoadSetup = (\n inner: InnerLoadContext,\n matchId: string,\n route: AnyRoute,\n): void | Promise<void> => {\n const existingMatch = inner.router.getMatch(matchId)!\n\n // If we are in the middle of a load, either of these will be present\n // (not to be confused with `loadPromise`, which is always defined)\n if (\n !existingMatch._nonReactive.beforeLoadPromise &&\n !existingMatch._nonReactive.loaderPromise\n )\n return\n\n setupPendingTimeout(inner, matchId, route, existingMatch)\n\n const then = () => {\n const match = inner.router.getMatch(matchId)!\n if (\n match.preload &&\n (match.status === 'redirected' || match.status === 'notFound')\n ) {\n handleRedirectAndNotFound(inner, match, match.error)\n }\n }\n\n // Wait for the previous beforeLoad to resolve before we continue\n return existingMatch._nonReactive.beforeLoadPromise\n ? existingMatch._nonReactive.beforeLoadPromise.then(then)\n : then()\n}\n\nconst executeBeforeLoad = (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): void | Promise<void> => {\n const match = inner.router.getMatch(matchId)!\n\n // explicitly capture the previous loadPromise\n const prevLoadPromise = match._nonReactive.loadPromise\n match._nonReactive.loadPromise = createControlledPromise<void>(() => {\n prevLoadPromise?.resolve()\n })\n\n const { paramsError, searchError } = match\n\n if (paramsError) {\n handleSerialError(inner, index, paramsError, 'PARSE_PARAMS')\n }\n\n if (searchError) {\n handleSerialError(inner, index, searchError, 'VALIDATE_SEARCH')\n }\n\n setupPendingTimeout(inner, matchId, route, match)\n\n const abortController = new AbortController()\n\n let isPending = false\n const pending = () => {\n if (isPending) return\n isPending = true\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: 'beforeLoad',\n fetchCount: prev.fetchCount + 1,\n abortController,\n // Note: We intentionally don't update context here.\n // Context should only be updated after beforeLoad resolves to avoid\n // components seeing incomplete context during async beforeLoad execution.\n }))\n }\n\n const resolve = () => {\n match._nonReactive.beforeLoadPromise?.resolve()\n match._nonReactive.beforeLoadPromise = undefined\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: false,\n }))\n }\n\n // if there is no `beforeLoad` option, just mark as pending and resolve\n // Context will be updated later in loadRouteMatch after loader completes\n if (!route.options.beforeLoad) {\n batch(() => {\n pending()\n resolve()\n })\n return\n }\n\n match._nonReactive.beforeLoadPromise = createControlledPromise<void>()\n\n // Build context from all parent matches, excluding current match's __beforeLoadContext\n // (since we're about to execute beforeLoad for this match)\n const context = {\n ...buildMatchContext(inner, index, false),\n ...match.__routeContext,\n }\n const { search, params, cause } = match\n const preload = resolvePreload(inner, matchId)\n const beforeLoadFnContext: BeforeLoadContextOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = {\n search,\n abortController,\n params,\n preload,\n context,\n location: inner.location,\n navigate: (opts: any) =>\n inner.router.navigate({\n ...opts,\n _fromLocation: inner.location,\n }),\n buildLocation: inner.router.buildLocation,\n cause: preload ? 'preload' : cause,\n matches: inner.matches,\n routeId: route.id,\n ...inner.router.options.additionalContext,\n }\n\n const updateContext = (beforeLoadContext: any) => {\n if (beforeLoadContext === undefined) {\n batch(() => {\n pending()\n resolve()\n })\n return\n }\n if (isRedirect(beforeLoadContext) || isNotFound(beforeLoadContext)) {\n pending()\n handleSerialError(inner, index, beforeLoadContext, 'BEFORE_LOAD')\n }\n\n batch(() => {\n pending()\n // Only store __beforeLoadContext here, don't update context yet\n // Context will be updated in loadRouteMatch after loader completes\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n __beforeLoadContext: beforeLoadContext,\n }))\n resolve()\n })\n }\n\n let beforeLoadContext\n try {\n beforeLoadContext = route.options.beforeLoad(beforeLoadFnContext)\n if (isPromise(beforeLoadContext)) {\n pending()\n return beforeLoadContext\n .catch((err) => {\n handleSerialError(inner, index, err, 'BEFORE_LOAD')\n })\n .then(updateContext)\n }\n } catch (err) {\n pending()\n handleSerialError(inner, index, err, 'BEFORE_LOAD')\n }\n\n updateContext(beforeLoadContext)\n return\n}\n\nconst handleBeforeLoad = (\n inner: InnerLoadContext,\n index: number,\n): void | Promise<void> => {\n const { id: matchId, routeId } = inner.matches[index]!\n const route = inner.router.looseRoutesById[routeId]!\n\n const serverSsr = () => {\n // on the server, determine whether SSR the current match or not\n if (isServer ?? inner.router.isServer) {\n const maybePromise = isBeforeLoadSsr(inner, matchId, index, route)\n if (isPromise(maybePromise)) return maybePromise.then(queueExecution)\n }\n return queueExecution()\n }\n\n const execute = () => executeBeforeLoad(inner, matchId, index, route)\n\n const queueExecution = () => {\n if (shouldSkipLoader(inner, matchId)) return\n const result = preBeforeLoadSetup(inner, matchId, route)\n return isPromise(result) ? result.then(execute) : execute()\n }\n\n return serverSsr()\n}\n\nconst executeHead = (\n inner: InnerLoadContext,\n matchId: string,\n route: AnyRoute,\n): void | Promise<\n Pick<\n AnyRouteMatch,\n 'meta' | 'links' | 'headScripts' | 'headers' | 'scripts' | 'styles'\n >\n> => {\n const match = inner.router.getMatch(matchId)\n // in case of a redirecting match during preload, the match does not exist\n if (!match) {\n return\n }\n if (!route.options.head && !route.options.scripts && !route.options.headers) {\n return\n }\n const assetContext = {\n ssr: inner.router.options.ssr,\n matches: inner.matches,\n match,\n params: match.params,\n loaderData: match.loaderData,\n }\n\n return Promise.all([\n route.options.head?.(assetContext),\n route.options.scripts?.(assetContext),\n route.options.headers?.(assetContext),\n ]).then(([headFnContent, scripts, headers]) => {\n const meta = headFnContent?.meta\n const links = headFnContent?.links\n const headScripts = headFnContent?.scripts\n const styles = headFnContent?.styles\n\n return {\n meta,\n links,\n headScripts,\n headers,\n scripts,\n styles,\n }\n })\n}\n\nconst getLoaderContext = (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): LoaderFnContext => {\n const parentMatchPromise = inner.matchPromises[index - 1] as any\n const { params, loaderDeps, abortController, cause } =\n inner.router.getMatch(matchId)!\n\n const context = buildMatchContext(inner, index)\n\n const preload = resolvePreload(inner, matchId)\n\n return {\n params,\n deps: loaderDeps,\n preload: !!preload,\n parentMatchPromise,\n abortController,\n context,\n location: inner.location,\n navigate: (opts) =>\n inner.router.navigate({\n ...opts,\n _fromLocation: inner.location,\n }),\n cause: preload ? 'preload' : cause,\n route,\n ...inner.router.options.additionalContext,\n }\n}\n\nconst runLoader = async (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): Promise<void> => {\n try {\n // If the Matches component rendered\n // the pending component and needs to show it for\n // a minimum duration, we''ll wait for it to resolve\n // before committing to the match and resolving\n // the loadPromise\n\n const match = inner.router.getMatch(matchId)!\n\n // Actually run the loader and handle the result\n try {\n if (!(isServer ?? inner.router.isServer) || match.ssr === true) {\n loadRouteChunk(route)\n }\n\n // Kick off the loader!\n const loaderResult = route.options.loader?.(\n getLoaderContext(inner, matchId, index, route),\n )\n const loaderResultIsPromise =\n route.options.loader && isPromise(loaderResult)\n\n const willLoadSomething = !!(\n loaderResultIsPromise ||\n route._lazyPromise ||\n route._componentsPromise ||\n route.options.head ||\n route.options.scripts ||\n route.options.headers ||\n match._nonReactive.minPendingPromise\n )\n\n if (willLoadSomething) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: 'loader',\n }))\n }\n\n if (route.options.loader) {\n const loaderData = loaderResultIsPromise\n ? await loaderResult\n : loaderResult\n\n handleRedirectAndNotFound(\n inner,\n inner.router.getMatch(matchId),\n loaderData,\n )\n if (loaderData !== undefined) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n loaderData,\n }))\n }\n }\n\n // Lazy option can modify the route options,\n // so we need to wait for it to resolve before\n // we can use the options\n if (route._lazyPromise) await route._lazyPromise\n const pendingPromise = match._nonReactive.minPendingPromise\n if (pendingPromise) await pendingPromise\n\n // Last but not least, wait for the the components\n // to be preloaded before we resolve the match\n if (route._componentsPromise) await route._componentsPromise\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n error: undefined,\n context: buildMatchContext(inner, index),\n status: 'success',\n isFetching: false,\n updatedAt: Date.now(),\n }))\n } catch (e) {\n let error = e\n\n if ((error as any)?.name === 'AbortError') {\n if (match.abortController.signal.aborted) {\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.loaderPromise = undefined\n return\n }\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n status: prev.status === 'pending' ? 'success' : prev.status,\n isFetching: false,\n context: buildMatchContext(inner, index),\n }))\n return\n }\n\n const pendingPromise = match._nonReactive.minPendingPromise\n if (pendingPromise) await pendingPromise\n\n if (isNotFound(e)) {\n await (route.options.notFoundComponent as any)?.preload?.()\n }\n\n handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), e)\n\n try {\n route.options.onError?.(e)\n } catch (onErrorError) {\n error = onErrorError\n handleRedirectAndNotFound(\n inner,\n inner.router.getMatch(matchId),\n onErrorError,\n )\n }\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n error,\n context: buildMatchContext(inner, index),\n status: 'error',\n isFetching: false,\n }))\n }\n } catch (err) {\n const match = inner.router.getMatch(matchId)\n // in case of a redirecting match during preload, the match does not exist\n if (match) {\n match._nonReactive.loaderPromise = undefined\n }\n handleRedirectAndNotFound(inner, match, err)\n }\n}\n\nconst loadRouteMatch = async (\n inner: InnerLoadContext,\n index: number,\n): Promise<AnyRouteMatch> => {\n async function handleLoader(\n preload: boolean,\n prevMatch: AnyRouteMatch,\n match: AnyRouteMatch,\n route: AnyRoute,\n ) {\n const age = Date.now() - prevMatch.updatedAt\n\n const staleAge = preload\n ? (route.options.preloadStaleTime ??\n inner.router.options.defaultPreloadStaleTime ??\n 30_000) // 30 seconds for preloads by default\n : (route.options.staleTime ?? inner.router.options.defaultStaleTime ?? 0)\n\n const shouldReloadOption = route.options.shouldReload\n\n // Default to reloading the route all the time\n // Allow shouldReload to get the last say,\n // if provided.\n const shouldReload =\n typeof shouldReloadOption === 'function'\n ? shouldReloadOption(getLoaderContext(inner, matchId, index, route))\n : shouldReloadOption\n\n // If the route is successful and still fresh, just resolve\n const { status, invalid } = match\n loaderShouldRunAsync =\n status === 'success' && (invalid || (shouldReload ?? age > staleAge))\n if (preload && route.options.preload === false) {\n // Do nothing\n } else if (loaderShouldRunAsync && !inner.sync) {\n loaderIsRunningAsync = true\n ;(async () => {\n try {\n await runLoader(inner, matchId, index, route)\n const match = inner.router.getMatch(matchId)!\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.loadPromise?.resolve()\n match._nonReactive.loaderPromise = undefined\n } catch (err) {\n if (isRedirect(err)) {\n await inner.router.navigate(err.options)\n }\n }\n })()\n } else if (status !== 'success' || (loaderShouldRunAsync && inner.sync)) {\n await runLoader(inner, matchId, index, route)\n }\n }\n\n const { id: matchId, routeId } = inner.matches[index]!\n let loaderShouldRunAsync = false\n let loaderIsRunningAsync = false\n const route = inner.router.looseRoutesById[routeId]!\n\n if (shouldSkipLoader(inner, matchId)) {\n if (isServer ?? inner.router.isServer) {\n return inner.router.getMatch(matchId)!\n }\n } else {\n const prevMatch = inner.router.getMatch(matchId)! // This is where all of the stale-while-revalidate magic happens\n const preload = resolvePreload(inner, matchId)\n\n // there is a loaderPromise, so we are in the middle of a load\n if (prevMatch._nonReactive.loaderPromise) {\n // do not block if we already have stale data we can show\n // but only if the ongoing load is not a preload since error handling is different for preloads\n // and we don't want to swallow errors\n if (prevMatch.status === 'success' && !inner.sync && !prevMatch.preload) {\n return prevMatch\n }\n await prevMatch._nonReactive.loaderPromise\n const match = inner.router.getMatch(matchId)!\n const error = match._nonReactive.error || match.error\n if (error) {\n handleRedirectAndNotFound(inner, match, error)\n }\n\n if (match.status === 'pending') {\n await handleLoader(preload, prevMatch, match, route)\n }\n } else {\n const nextPreload =\n preload && !inner.router.state.matches.some((d) => d.id === matchId)\n const match = inner.router.getMatch(matchId)!\n match._nonReactive.loaderPromise = createControlledPromise<void>()\n if (nextPreload !== match.preload) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n preload: nextPreload,\n }))\n }\n\n await handleLoader(preload, prevMatch, match, route)\n }\n }\n const match = inner.router.getMatch(matchId)!\n if (!loaderIsRunningAsync) {\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.loadPromise?.resolve()\n }\n\n clearTimeout(match._nonReactive.pendingTimeout)\n match._nonReactive.pendingTimeout = undefined\n if (!loaderIsRunningAsync) match._nonReactive.loaderPromise = undefined\n match._nonReactive.dehydrated = undefined\n\n const nextIsFetching = loaderIsRunningAsync ? match.isFetching : false\n if (nextIsFetching !== match.isFetching || match.invalid !== false) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: nextIsFetching,\n invalid: false,\n }))\n return inner.router.getMatch(matchId)!\n } else {\n return match\n }\n}\n\nexport async function loadMatches(arg: {\n router: AnyRouter\n location: ParsedLocation\n matches: Array<AnyRouteMatch>\n preload?: boolean\n onReady?: () => Promise<void>\n updateMatch: UpdateMatchFn\n sync?: boolean\n}): Promise<Array<MakeRouteMatch>> {\n const inner: InnerLoadContext = Object.assign(arg, {\n matchPromises: [],\n })\n\n // make sure the pending component is immediately rendered when hydrating a match that is not SSRed\n // the pending component was already rendered on the server and we want to keep it shown on the client until minPendingMs is reached\n if (\n !(isServer ?? inner.router.isServer) &&\n inner.router.state.matches.some((d) => d._forcePending)\n ) {\n triggerOnReady(inner)\n }\n\n try {\n // Execute all beforeLoads one by one\n for (let i = 0; i < inner.matches.length; i++) {\n const beforeLoad = handleBeforeLoad(inner, i)\n if (isPromise(beforeLoad)) await beforeLoad\n }\n\n // Execute all loaders in parallel\n const max = inner.firstBadMatchIndex ?? inner.matches.length\n for (let i = 0; i < max; i++) {\n inner.matchPromises.push(loadRouteMatch(inner, i))\n }\n // Use allSettled to ensure all loaders complete regardless of success/failure\n const results = await Promise.allSettled(inner.matchPromises)\n\n const failures = results\n // TODO when we drop support for TS 5.4, we can use the built-in type guard for PromiseRejectedResult\n .filter(\n (result): result is PromiseRejectedResult =>\n result.status === 'rejected',\n )\n .map((result) => result.reason)\n\n // Find first redirect (throw immediately) or notFound (throw after head execution)\n let firstNotFound: unknown\n for (const err of failures) {\n if (isRedirect(err)) {\n throw err\n }\n if (!firstNotFound && isNotFound(err)) {\n firstNotFound = err\n }\n }\n\n // serially execute head functions after all loaders have completed (successfully or not)\n // Each head execution is wrapped in try-catch to ensure all heads run even if one fails\n for (const match of inner.matches) {\n const { id: matchId, routeId } = match\n const route = inner.router.looseRoutesById[routeId]!\n try {\n const headResult = executeHead(inner, matchId, route)\n if (headResult) {\n const head = await headResult\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n ...head,\n }))\n }\n } catch (err) {\n // Log error but continue executing other head functions\n console.error(`Error executing head for route ${routeId}:`, err)\n }\n }\n\n // Throw notFound after head execution\n if (firstNotFound) {\n throw firstNotFound\n }\n\n const readyPromise = triggerOnReady(inner)\n if (isPromise(readyPromise)) await readyPromise\n } catch (err) {\n if (isNotFound(err) && !inner.preload) {\n const readyPromise = triggerOnReady(inner)\n if (isPromise(readyPromise)) await readyPromise\n throw err\n }\n if (isRedirect(err)) {\n throw err\n }\n }\n return inner.matches\n}\n\nexport async function loadRouteChunk(route: AnyRoute) {\n if (!route._lazyLoaded && route._lazyPromise === undefined) {\n if (route.lazyFn) {\n route._lazyPromise = route.lazyFn().then((lazyRoute) => {\n // explicitly don't copy over the lazy route's id\n const { id: _id, ...options } = lazyRoute.options\n Object.assign(route.options, options)\n route._lazyLoaded = true\n route._lazyPromise = undefined // gc promise, we won't need it anymore\n })\n } else {\n route._lazyLoaded = true\n }\n }\n\n // If for some reason lazy resolves more lazy components...\n // We'll wait for that before we attempt to preload the\n // components themselves.\n if (!route._componentsLoaded && route._componentsPromise === undefined) {\n const loadComponents = () => {\n const preloads = []\n for (const type of componentTypes) {\n const preload = (route.options[type] as any)?.preload\n if (preload) preloads.push(preload())\n }\n if (preloads.length)\n return Promise.all(preloads).then(() => {\n route._componentsLoaded = true\n route._componentsPromise = undefined // gc promise, we won't need it anymore\n })\n route._componentsLoaded = true\n route._componentsPromise = undefined // gc promise, we won't need it anymore\n return\n }\n route._componentsPromise = route._lazyPromise\n ? route._lazyPromise.then(loadComponents)\n : loadComponents()\n }\n return route._componentsPromise\n}\n\nfunction makeMaybe<TValue, TError>(\n value: TValue,\n error: TError,\n): { status: 'success'; value: TValue } | { status: 'error'; error: TError } {\n if (error) {\n return { status: 'error' as const, error }\n }\n return { status: 'success' as const, value }\n}\n\nexport function routeNeedsPreload(route: AnyRoute) {\n for (const componentType of componentTypes) {\n if ((route.options[componentType] as any)?.preload) {\n return true\n }\n }\n return false\n}\n\nexport const componentTypes = [\n 'component',\n 'errorComponent',\n 'pendingComponent',\n 'notFoundComponent',\n] as const\n"],"names":["isRedirect","isNotFound","isServer","rootRouteId","tempSsr","isPromise","createControlledPromise","batch","beforeLoadContext","match","route"],"mappings":"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"}
|
package/dist/esm/load-matches.js
CHANGED
|
@@ -427,6 +427,11 @@ const runLoader = async (inner, matchId, index, route) => {
|
|
|
427
427
|
} catch (e) {
|
|
428
428
|
let error = e;
|
|
429
429
|
if (error?.name === "AbortError") {
|
|
430
|
+
if (match.abortController.signal.aborted) {
|
|
431
|
+
match._nonReactive.loaderPromise?.resolve();
|
|
432
|
+
match._nonReactive.loaderPromise = void 0;
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
430
435
|
inner.updateMatch(matchId, (prev) => ({
|
|
431
436
|
...prev,
|
|
432
437
|
status: prev.status === "pending" ? "success" : prev.status,
|
|
@@ -468,6 +473,33 @@ const runLoader = async (inner, matchId, index, route) => {
|
|
|
468
473
|
}
|
|
469
474
|
};
|
|
470
475
|
const loadRouteMatch = async (inner, index) => {
|
|
476
|
+
async function handleLoader(preload, prevMatch, match2, route2) {
|
|
477
|
+
const age = Date.now() - prevMatch.updatedAt;
|
|
478
|
+
const staleAge = preload ? route2.options.preloadStaleTime ?? inner.router.options.defaultPreloadStaleTime ?? 3e4 : route2.options.staleTime ?? inner.router.options.defaultStaleTime ?? 0;
|
|
479
|
+
const shouldReloadOption = route2.options.shouldReload;
|
|
480
|
+
const shouldReload = typeof shouldReloadOption === "function" ? shouldReloadOption(getLoaderContext(inner, matchId, index, route2)) : shouldReloadOption;
|
|
481
|
+
const { status, invalid } = match2;
|
|
482
|
+
loaderShouldRunAsync = status === "success" && (invalid || (shouldReload ?? age > staleAge));
|
|
483
|
+
if (preload && route2.options.preload === false) ;
|
|
484
|
+
else if (loaderShouldRunAsync && !inner.sync) {
|
|
485
|
+
loaderIsRunningAsync = true;
|
|
486
|
+
(async () => {
|
|
487
|
+
try {
|
|
488
|
+
await runLoader(inner, matchId, index, route2);
|
|
489
|
+
const match3 = inner.router.getMatch(matchId);
|
|
490
|
+
match3._nonReactive.loaderPromise?.resolve();
|
|
491
|
+
match3._nonReactive.loadPromise?.resolve();
|
|
492
|
+
match3._nonReactive.loaderPromise = void 0;
|
|
493
|
+
} catch (err) {
|
|
494
|
+
if (isRedirect(err)) {
|
|
495
|
+
await inner.router.navigate(err.options);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
})();
|
|
499
|
+
} else if (status !== "success" || loaderShouldRunAsync && inner.sync) {
|
|
500
|
+
await runLoader(inner, matchId, index, route2);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
471
503
|
const { id: matchId, routeId } = inner.matches[index];
|
|
472
504
|
let loaderShouldRunAsync = false;
|
|
473
505
|
let loaderIsRunningAsync = false;
|
|
@@ -478,6 +510,7 @@ const loadRouteMatch = async (inner, index) => {
|
|
|
478
510
|
}
|
|
479
511
|
} else {
|
|
480
512
|
const prevMatch = inner.router.getMatch(matchId);
|
|
513
|
+
const preload = resolvePreload(inner, matchId);
|
|
481
514
|
if (prevMatch._nonReactive.loaderPromise) {
|
|
482
515
|
if (prevMatch.status === "success" && !inner.sync && !prevMatch.preload) {
|
|
483
516
|
return prevMatch;
|
|
@@ -488,13 +521,11 @@ const loadRouteMatch = async (inner, index) => {
|
|
|
488
521
|
if (error) {
|
|
489
522
|
handleRedirectAndNotFound(inner, match2, error);
|
|
490
523
|
}
|
|
524
|
+
if (match2.status === "pending") {
|
|
525
|
+
await handleLoader(preload, prevMatch, match2, route);
|
|
526
|
+
}
|
|
491
527
|
} else {
|
|
492
|
-
const
|
|
493
|
-
const preload = resolvePreload(inner, matchId);
|
|
494
|
-
const staleAge = preload ? route.options.preloadStaleTime ?? inner.router.options.defaultPreloadStaleTime ?? 3e4 : route.options.staleTime ?? inner.router.options.defaultStaleTime ?? 0;
|
|
495
|
-
const shouldReloadOption = route.options.shouldReload;
|
|
496
|
-
const shouldReload = typeof shouldReloadOption === "function" ? shouldReloadOption(getLoaderContext(inner, matchId, index, route)) : shouldReloadOption;
|
|
497
|
-
const nextPreload = !!preload && !inner.router.state.matches.some((d) => d.id === matchId);
|
|
528
|
+
const nextPreload = preload && !inner.router.state.matches.some((d) => d.id === matchId);
|
|
498
529
|
const match2 = inner.router.getMatch(matchId);
|
|
499
530
|
match2._nonReactive.loaderPromise = createControlledPromise();
|
|
500
531
|
if (nextPreload !== match2.preload) {
|
|
@@ -503,27 +534,7 @@ const loadRouteMatch = async (inner, index) => {
|
|
|
503
534
|
preload: nextPreload
|
|
504
535
|
}));
|
|
505
536
|
}
|
|
506
|
-
|
|
507
|
-
loaderShouldRunAsync = status === "success" && (invalid || (shouldReload ?? age > staleAge));
|
|
508
|
-
if (preload && route.options.preload === false) ;
|
|
509
|
-
else if (loaderShouldRunAsync && !inner.sync) {
|
|
510
|
-
loaderIsRunningAsync = true;
|
|
511
|
-
(async () => {
|
|
512
|
-
try {
|
|
513
|
-
await runLoader(inner, matchId, index, route);
|
|
514
|
-
const match3 = inner.router.getMatch(matchId);
|
|
515
|
-
match3._nonReactive.loaderPromise?.resolve();
|
|
516
|
-
match3._nonReactive.loadPromise?.resolve();
|
|
517
|
-
match3._nonReactive.loaderPromise = void 0;
|
|
518
|
-
} catch (err) {
|
|
519
|
-
if (isRedirect(err)) {
|
|
520
|
-
await inner.router.navigate(err.options);
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
})();
|
|
524
|
-
} else if (status !== "success" || loaderShouldRunAsync && inner.sync) {
|
|
525
|
-
await runLoader(inner, matchId, index, route);
|
|
526
|
-
}
|
|
537
|
+
await handleLoader(preload, prevMatch, match2, route);
|
|
527
538
|
}
|
|
528
539
|
}
|
|
529
540
|
const match = inner.router.getMatch(matchId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-matches.js","sources":["../../src/load-matches.ts"],"sourcesContent":["import invariant from 'tiny-invariant'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { batch } from './utils/batch'\nimport { createControlledPromise, isPromise } from './utils'\nimport { isNotFound } from './not-found'\nimport { rootRouteId } from './root'\nimport { isRedirect } from './redirect'\nimport type { NotFoundError } from './not-found'\nimport type { ParsedLocation } from './location'\nimport type {\n AnyRoute,\n BeforeLoadContextOptions,\n LoaderFnContext,\n SsrContextOptions,\n} from './route'\nimport type { AnyRouteMatch, MakeRouteMatch } from './Matches'\nimport type { AnyRouter, SSROption, UpdateMatchFn } from './router'\n\n/**\n * An object of this shape is created when calling `loadMatches`.\n * It contains everything we need for all other functions in this file\n * to work. (It's basically the function's argument, plus a few mutable states)\n */\ntype InnerLoadContext = {\n /** the calling router instance */\n router: AnyRouter\n location: ParsedLocation\n /** mutable state, scoped to a `loadMatches` call */\n firstBadMatchIndex?: number\n /** mutable state, scoped to a `loadMatches` call */\n rendered?: boolean\n updateMatch: UpdateMatchFn\n matches: Array<AnyRouteMatch>\n preload?: boolean\n onReady?: () => Promise<void>\n sync?: boolean\n /** mutable state, scoped to a `loadMatches` call */\n matchPromises: Array<Promise<AnyRouteMatch>>\n}\n\nconst triggerOnReady = (inner: InnerLoadContext): void | Promise<void> => {\n if (!inner.rendered) {\n inner.rendered = true\n return inner.onReady?.()\n }\n}\n\nconst resolvePreload = (inner: InnerLoadContext, matchId: string): boolean => {\n return !!(\n inner.preload && !inner.router.state.matches.some((d) => d.id === matchId)\n )\n}\n\n/**\n * Builds the accumulated context from router options and all matches up to (and optionally including) the given index.\n * Merges __routeContext and __beforeLoadContext from each match.\n */\nconst buildMatchContext = (\n inner: InnerLoadContext,\n index: number,\n includeCurrentMatch: boolean = true,\n): Record<string, unknown> => {\n const context: Record<string, unknown> = {\n ...(inner.router.options.context ?? {}),\n }\n const end = includeCurrentMatch ? index : index - 1\n for (let i = 0; i <= end; i++) {\n const innerMatch = inner.matches[i]\n if (!innerMatch) continue\n const m = inner.router.getMatch(innerMatch.id)\n if (!m) continue\n Object.assign(context, m.__routeContext, m.__beforeLoadContext)\n }\n return context\n}\n\nconst _handleNotFound = (inner: InnerLoadContext, err: NotFoundError) => {\n // Find the route that should handle the not found error\n // First check if a specific route is requested to show the error\n const routeCursor =\n inner.router.routesById[err.routeId ?? ''] ?? inner.router.routeTree\n\n // Ensure a NotFoundComponent exists on the route\n if (\n !routeCursor.options.notFoundComponent &&\n (inner.router.options as any)?.defaultNotFoundComponent\n ) {\n routeCursor.options.notFoundComponent = (\n inner.router.options as any\n ).defaultNotFoundComponent\n }\n\n // Ensure we have a notFoundComponent\n invariant(\n routeCursor.options.notFoundComponent,\n 'No notFoundComponent found. Please set a notFoundComponent on your route or provide a defaultNotFoundComponent to the router.',\n )\n\n // Find the match for this route\n const matchForRoute = inner.matches.find((m) => m.routeId === routeCursor.id)\n\n invariant(matchForRoute, 'Could not find match for route: ' + routeCursor.id)\n\n // Assign the error to the match - using non-null assertion since we've checked with invariant\n inner.updateMatch(matchForRoute.id, (prev) => ({\n ...prev,\n status: 'notFound',\n error: err,\n isFetching: false,\n }))\n\n if ((err as any).routerCode === 'BEFORE_LOAD' && routeCursor.parentRoute) {\n err.routeId = routeCursor.parentRoute.id\n _handleNotFound(inner, err)\n }\n}\n\nconst handleRedirectAndNotFound = (\n inner: InnerLoadContext,\n match: AnyRouteMatch | undefined,\n err: unknown,\n): void => {\n if (!isRedirect(err) && !isNotFound(err)) return\n\n if (isRedirect(err) && err.redirectHandled && !err.options.reloadDocument) {\n throw err\n }\n\n // in case of a redirecting match during preload, the match does not exist\n if (match) {\n match._nonReactive.beforeLoadPromise?.resolve()\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.beforeLoadPromise = undefined\n match._nonReactive.loaderPromise = undefined\n\n const status = isRedirect(err) ? 'redirected' : 'notFound'\n\n match._nonReactive.error = err\n\n inner.updateMatch(match.id, (prev) => ({\n ...prev,\n status,\n context: buildMatchContext(inner, match.index),\n isFetching: false,\n error: err,\n }))\n\n if (isNotFound(err) && !err.routeId) {\n err.routeId = match.routeId\n }\n\n match._nonReactive.loadPromise?.resolve()\n }\n\n if (isRedirect(err)) {\n inner.rendered = true\n err.options._fromLocation = inner.location\n err.redirectHandled = true\n err = inner.router.resolveRedirect(err)\n throw err\n } else {\n _handleNotFound(inner, err)\n throw err\n }\n}\n\nconst shouldSkipLoader = (\n inner: InnerLoadContext,\n matchId: string,\n): boolean => {\n const match = inner.router.getMatch(matchId)!\n // upon hydration, we skip the loader if the match has been dehydrated on the server\n if (!(isServer ?? inner.router.isServer) && match._nonReactive.dehydrated) {\n return true\n }\n\n if ((isServer ?? inner.router.isServer) && match.ssr === false) {\n return true\n }\n\n return false\n}\n\nconst handleSerialError = (\n inner: InnerLoadContext,\n index: number,\n err: any,\n routerCode: string,\n): void => {\n const { id: matchId, routeId } = inner.matches[index]!\n const route = inner.router.looseRoutesById[routeId]!\n\n // Much like suspense, we use a promise here to know if\n // we've been outdated by a new loadMatches call and\n // should abort the current async operation\n if (err instanceof Promise) {\n throw err\n }\n\n err.routerCode = routerCode\n inner.firstBadMatchIndex ??= index\n handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), err)\n\n try {\n route.options.onError?.(err)\n } catch (errorHandlerErr) {\n err = errorHandlerErr\n handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), err)\n }\n\n inner.updateMatch(matchId, (prev) => {\n prev._nonReactive.beforeLoadPromise?.resolve()\n prev._nonReactive.beforeLoadPromise = undefined\n prev._nonReactive.loadPromise?.resolve()\n\n return {\n ...prev,\n error: err,\n status: 'error',\n isFetching: false,\n updatedAt: Date.now(),\n abortController: new AbortController(),\n }\n })\n}\n\nconst isBeforeLoadSsr = (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): void | Promise<void> => {\n const existingMatch = inner.router.getMatch(matchId)!\n const parentMatchId = inner.matches[index - 1]?.id\n const parentMatch = parentMatchId\n ? inner.router.getMatch(parentMatchId)!\n : undefined\n\n // in SPA mode, only SSR the root route\n if (inner.router.isShell()) {\n existingMatch.ssr = route.id === rootRouteId\n return\n }\n\n if (parentMatch?.ssr === false) {\n existingMatch.ssr = false\n return\n }\n\n const parentOverride = (tempSsr: SSROption) => {\n if (tempSsr === true && parentMatch?.ssr === 'data-only') {\n return 'data-only'\n }\n return tempSsr\n }\n\n const defaultSsr = inner.router.options.defaultSsr ?? true\n\n if (route.options.ssr === undefined) {\n existingMatch.ssr = parentOverride(defaultSsr)\n return\n }\n\n if (typeof route.options.ssr !== 'function') {\n existingMatch.ssr = parentOverride(route.options.ssr)\n return\n }\n const { search, params } = existingMatch\n\n const ssrFnContext: SsrContextOptions<any, any, any> = {\n search: makeMaybe(search, existingMatch.searchError),\n params: makeMaybe(params, existingMatch.paramsError),\n location: inner.location,\n matches: inner.matches.map((match) => ({\n index: match.index,\n pathname: match.pathname,\n fullPath: match.fullPath,\n staticData: match.staticData,\n id: match.id,\n routeId: match.routeId,\n search: makeMaybe(match.search, match.searchError),\n params: makeMaybe(match.params, match.paramsError),\n ssr: match.ssr,\n })),\n }\n\n const tempSsr = route.options.ssr(ssrFnContext)\n if (isPromise(tempSsr)) {\n return tempSsr.then((ssr) => {\n existingMatch.ssr = parentOverride(ssr ?? defaultSsr)\n })\n }\n\n existingMatch.ssr = parentOverride(tempSsr ?? defaultSsr)\n return\n}\n\nconst setupPendingTimeout = (\n inner: InnerLoadContext,\n matchId: string,\n route: AnyRoute,\n match: AnyRouteMatch,\n): void => {\n if (match._nonReactive.pendingTimeout !== undefined) return\n\n const pendingMs =\n route.options.pendingMs ?? inner.router.options.defaultPendingMs\n const shouldPending = !!(\n inner.onReady &&\n !(isServer ?? inner.router.isServer) &&\n !resolvePreload(inner, matchId) &&\n (route.options.loader ||\n route.options.beforeLoad ||\n routeNeedsPreload(route)) &&\n typeof pendingMs === 'number' &&\n pendingMs !== Infinity &&\n (route.options.pendingComponent ??\n (inner.router.options as any)?.defaultPendingComponent)\n )\n\n if (shouldPending) {\n const pendingTimeout = setTimeout(() => {\n // Update the match and prematurely resolve the loadMatches promise so that\n // the pending component can start rendering\n triggerOnReady(inner)\n }, pendingMs)\n match._nonReactive.pendingTimeout = pendingTimeout\n }\n}\n\nconst preBeforeLoadSetup = (\n inner: InnerLoadContext,\n matchId: string,\n route: AnyRoute,\n): void | Promise<void> => {\n const existingMatch = inner.router.getMatch(matchId)!\n\n // If we are in the middle of a load, either of these will be present\n // (not to be confused with `loadPromise`, which is always defined)\n if (\n !existingMatch._nonReactive.beforeLoadPromise &&\n !existingMatch._nonReactive.loaderPromise\n )\n return\n\n setupPendingTimeout(inner, matchId, route, existingMatch)\n\n const then = () => {\n const match = inner.router.getMatch(matchId)!\n if (\n match.preload &&\n (match.status === 'redirected' || match.status === 'notFound')\n ) {\n handleRedirectAndNotFound(inner, match, match.error)\n }\n }\n\n // Wait for the previous beforeLoad to resolve before we continue\n return existingMatch._nonReactive.beforeLoadPromise\n ? existingMatch._nonReactive.beforeLoadPromise.then(then)\n : then()\n}\n\nconst executeBeforeLoad = (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): void | Promise<void> => {\n const match = inner.router.getMatch(matchId)!\n\n // explicitly capture the previous loadPromise\n const prevLoadPromise = match._nonReactive.loadPromise\n match._nonReactive.loadPromise = createControlledPromise<void>(() => {\n prevLoadPromise?.resolve()\n })\n\n const { paramsError, searchError } = match\n\n if (paramsError) {\n handleSerialError(inner, index, paramsError, 'PARSE_PARAMS')\n }\n\n if (searchError) {\n handleSerialError(inner, index, searchError, 'VALIDATE_SEARCH')\n }\n\n setupPendingTimeout(inner, matchId, route, match)\n\n const abortController = new AbortController()\n\n let isPending = false\n const pending = () => {\n if (isPending) return\n isPending = true\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: 'beforeLoad',\n fetchCount: prev.fetchCount + 1,\n abortController,\n // Note: We intentionally don't update context here.\n // Context should only be updated after beforeLoad resolves to avoid\n // components seeing incomplete context during async beforeLoad execution.\n }))\n }\n\n const resolve = () => {\n match._nonReactive.beforeLoadPromise?.resolve()\n match._nonReactive.beforeLoadPromise = undefined\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: false,\n }))\n }\n\n // if there is no `beforeLoad` option, just mark as pending and resolve\n // Context will be updated later in loadRouteMatch after loader completes\n if (!route.options.beforeLoad) {\n batch(() => {\n pending()\n resolve()\n })\n return\n }\n\n match._nonReactive.beforeLoadPromise = createControlledPromise<void>()\n\n // Build context from all parent matches, excluding current match's __beforeLoadContext\n // (since we're about to execute beforeLoad for this match)\n const context = {\n ...buildMatchContext(inner, index, false),\n ...match.__routeContext,\n }\n const { search, params, cause } = match\n const preload = resolvePreload(inner, matchId)\n const beforeLoadFnContext: BeforeLoadContextOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = {\n search,\n abortController,\n params,\n preload,\n context,\n location: inner.location,\n navigate: (opts: any) =>\n inner.router.navigate({\n ...opts,\n _fromLocation: inner.location,\n }),\n buildLocation: inner.router.buildLocation,\n cause: preload ? 'preload' : cause,\n matches: inner.matches,\n routeId: route.id,\n ...inner.router.options.additionalContext,\n }\n\n const updateContext = (beforeLoadContext: any) => {\n if (beforeLoadContext === undefined) {\n batch(() => {\n pending()\n resolve()\n })\n return\n }\n if (isRedirect(beforeLoadContext) || isNotFound(beforeLoadContext)) {\n pending()\n handleSerialError(inner, index, beforeLoadContext, 'BEFORE_LOAD')\n }\n\n batch(() => {\n pending()\n // Only store __beforeLoadContext here, don't update context yet\n // Context will be updated in loadRouteMatch after loader completes\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n __beforeLoadContext: beforeLoadContext,\n }))\n resolve()\n })\n }\n\n let beforeLoadContext\n try {\n beforeLoadContext = route.options.beforeLoad(beforeLoadFnContext)\n if (isPromise(beforeLoadContext)) {\n pending()\n return beforeLoadContext\n .catch((err) => {\n handleSerialError(inner, index, err, 'BEFORE_LOAD')\n })\n .then(updateContext)\n }\n } catch (err) {\n pending()\n handleSerialError(inner, index, err, 'BEFORE_LOAD')\n }\n\n updateContext(beforeLoadContext)\n return\n}\n\nconst handleBeforeLoad = (\n inner: InnerLoadContext,\n index: number,\n): void | Promise<void> => {\n const { id: matchId, routeId } = inner.matches[index]!\n const route = inner.router.looseRoutesById[routeId]!\n\n const serverSsr = () => {\n // on the server, determine whether SSR the current match or not\n if (isServer ?? inner.router.isServer) {\n const maybePromise = isBeforeLoadSsr(inner, matchId, index, route)\n if (isPromise(maybePromise)) return maybePromise.then(queueExecution)\n }\n return queueExecution()\n }\n\n const execute = () => executeBeforeLoad(inner, matchId, index, route)\n\n const queueExecution = () => {\n if (shouldSkipLoader(inner, matchId)) return\n const result = preBeforeLoadSetup(inner, matchId, route)\n return isPromise(result) ? result.then(execute) : execute()\n }\n\n return serverSsr()\n}\n\nconst executeHead = (\n inner: InnerLoadContext,\n matchId: string,\n route: AnyRoute,\n): void | Promise<\n Pick<\n AnyRouteMatch,\n 'meta' | 'links' | 'headScripts' | 'headers' | 'scripts' | 'styles'\n >\n> => {\n const match = inner.router.getMatch(matchId)\n // in case of a redirecting match during preload, the match does not exist\n if (!match) {\n return\n }\n if (!route.options.head && !route.options.scripts && !route.options.headers) {\n return\n }\n const assetContext = {\n ssr: inner.router.options.ssr,\n matches: inner.matches,\n match,\n params: match.params,\n loaderData: match.loaderData,\n }\n\n return Promise.all([\n route.options.head?.(assetContext),\n route.options.scripts?.(assetContext),\n route.options.headers?.(assetContext),\n ]).then(([headFnContent, scripts, headers]) => {\n const meta = headFnContent?.meta\n const links = headFnContent?.links\n const headScripts = headFnContent?.scripts\n const styles = headFnContent?.styles\n\n return {\n meta,\n links,\n headScripts,\n headers,\n scripts,\n styles,\n }\n })\n}\n\nconst getLoaderContext = (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): LoaderFnContext => {\n const parentMatchPromise = inner.matchPromises[index - 1] as any\n const { params, loaderDeps, abortController, cause } =\n inner.router.getMatch(matchId)!\n\n const context = buildMatchContext(inner, index)\n\n const preload = resolvePreload(inner, matchId)\n\n return {\n params,\n deps: loaderDeps,\n preload: !!preload,\n parentMatchPromise,\n abortController,\n context,\n location: inner.location,\n navigate: (opts) =>\n inner.router.navigate({\n ...opts,\n _fromLocation: inner.location,\n }),\n cause: preload ? 'preload' : cause,\n route,\n ...inner.router.options.additionalContext,\n }\n}\n\nconst runLoader = async (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): Promise<void> => {\n try {\n // If the Matches component rendered\n // the pending component and needs to show it for\n // a minimum duration, we''ll wait for it to resolve\n // before committing to the match and resolving\n // the loadPromise\n\n const match = inner.router.getMatch(matchId)!\n\n // Actually run the loader and handle the result\n try {\n if (!(isServer ?? inner.router.isServer) || match.ssr === true) {\n loadRouteChunk(route)\n }\n\n // Kick off the loader!\n const loaderResult = route.options.loader?.(\n getLoaderContext(inner, matchId, index, route),\n )\n const loaderResultIsPromise =\n route.options.loader && isPromise(loaderResult)\n\n const willLoadSomething = !!(\n loaderResultIsPromise ||\n route._lazyPromise ||\n route._componentsPromise ||\n route.options.head ||\n route.options.scripts ||\n route.options.headers ||\n match._nonReactive.minPendingPromise\n )\n\n if (willLoadSomething) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: 'loader',\n }))\n }\n\n if (route.options.loader) {\n const loaderData = loaderResultIsPromise\n ? await loaderResult\n : loaderResult\n\n handleRedirectAndNotFound(\n inner,\n inner.router.getMatch(matchId),\n loaderData,\n )\n if (loaderData !== undefined) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n loaderData,\n }))\n }\n }\n\n // Lazy option can modify the route options,\n // so we need to wait for it to resolve before\n // we can use the options\n if (route._lazyPromise) await route._lazyPromise\n const pendingPromise = match._nonReactive.minPendingPromise\n if (pendingPromise) await pendingPromise\n\n // Last but not least, wait for the the components\n // to be preloaded before we resolve the match\n if (route._componentsPromise) await route._componentsPromise\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n error: undefined,\n context: buildMatchContext(inner, index),\n status: 'success',\n isFetching: false,\n updatedAt: Date.now(),\n }))\n } catch (e) {\n let error = e\n\n if ((error as any)?.name === 'AbortError') {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n status: prev.status === 'pending' ? 'success' : prev.status,\n isFetching: false,\n context: buildMatchContext(inner, index),\n }))\n return\n }\n\n const pendingPromise = match._nonReactive.minPendingPromise\n if (pendingPromise) await pendingPromise\n\n if (isNotFound(e)) {\n await (route.options.notFoundComponent as any)?.preload?.()\n }\n\n handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), e)\n\n try {\n route.options.onError?.(e)\n } catch (onErrorError) {\n error = onErrorError\n handleRedirectAndNotFound(\n inner,\n inner.router.getMatch(matchId),\n onErrorError,\n )\n }\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n error,\n context: buildMatchContext(inner, index),\n status: 'error',\n isFetching: false,\n }))\n }\n } catch (err) {\n const match = inner.router.getMatch(matchId)\n // in case of a redirecting match during preload, the match does not exist\n if (match) {\n match._nonReactive.loaderPromise = undefined\n }\n handleRedirectAndNotFound(inner, match, err)\n }\n}\n\nconst loadRouteMatch = async (\n inner: InnerLoadContext,\n index: number,\n): Promise<AnyRouteMatch> => {\n const { id: matchId, routeId } = inner.matches[index]!\n let loaderShouldRunAsync = false\n let loaderIsRunningAsync = false\n const route = inner.router.looseRoutesById[routeId]!\n\n if (shouldSkipLoader(inner, matchId)) {\n if (isServer ?? inner.router.isServer) {\n return inner.router.getMatch(matchId)!\n }\n } else {\n const prevMatch = inner.router.getMatch(matchId)!\n // there is a loaderPromise, so we are in the middle of a load\n if (prevMatch._nonReactive.loaderPromise) {\n // do not block if we already have stale data we can show\n // but only if the ongoing load is not a preload since error handling is different for preloads\n // and we don't want to swallow errors\n if (prevMatch.status === 'success' && !inner.sync && !prevMatch.preload) {\n return prevMatch\n }\n await prevMatch._nonReactive.loaderPromise\n const match = inner.router.getMatch(matchId)!\n const error = match._nonReactive.error || match.error\n if (error) {\n handleRedirectAndNotFound(inner, match, error)\n }\n } else {\n // This is where all of the stale-while-revalidate magic happens\n const age = Date.now() - prevMatch.updatedAt\n\n const preload = resolvePreload(inner, matchId)\n\n const staleAge = preload\n ? (route.options.preloadStaleTime ??\n inner.router.options.defaultPreloadStaleTime ??\n 30_000) // 30 seconds for preloads by default\n : (route.options.staleTime ??\n inner.router.options.defaultStaleTime ??\n 0)\n\n const shouldReloadOption = route.options.shouldReload\n\n // Default to reloading the route all the time\n // Allow shouldReload to get the last say,\n // if provided.\n const shouldReload =\n typeof shouldReloadOption === 'function'\n ? shouldReloadOption(getLoaderContext(inner, matchId, index, route))\n : shouldReloadOption\n\n const nextPreload =\n !!preload && !inner.router.state.matches.some((d) => d.id === matchId)\n const match = inner.router.getMatch(matchId)!\n match._nonReactive.loaderPromise = createControlledPromise<void>()\n if (nextPreload !== match.preload) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n preload: nextPreload,\n }))\n }\n\n // If the route is successful and still fresh, just resolve\n const { status, invalid } = match\n loaderShouldRunAsync =\n status === 'success' && (invalid || (shouldReload ?? age > staleAge))\n if (preload && route.options.preload === false) {\n // Do nothing\n } else if (loaderShouldRunAsync && !inner.sync) {\n loaderIsRunningAsync = true\n ;(async () => {\n try {\n await runLoader(inner, matchId, index, route)\n const match = inner.router.getMatch(matchId)!\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.loadPromise?.resolve()\n match._nonReactive.loaderPromise = undefined\n } catch (err) {\n if (isRedirect(err)) {\n await inner.router.navigate(err.options)\n }\n }\n })()\n } else if (status !== 'success' || (loaderShouldRunAsync && inner.sync)) {\n await runLoader(inner, matchId, index, route)\n }\n }\n }\n const match = inner.router.getMatch(matchId)!\n if (!loaderIsRunningAsync) {\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.loadPromise?.resolve()\n }\n\n clearTimeout(match._nonReactive.pendingTimeout)\n match._nonReactive.pendingTimeout = undefined\n if (!loaderIsRunningAsync) match._nonReactive.loaderPromise = undefined\n match._nonReactive.dehydrated = undefined\n\n const nextIsFetching = loaderIsRunningAsync ? match.isFetching : false\n if (nextIsFetching !== match.isFetching || match.invalid !== false) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: nextIsFetching,\n invalid: false,\n }))\n return inner.router.getMatch(matchId)!\n } else {\n return match\n }\n}\n\nexport async function loadMatches(arg: {\n router: AnyRouter\n location: ParsedLocation\n matches: Array<AnyRouteMatch>\n preload?: boolean\n onReady?: () => Promise<void>\n updateMatch: UpdateMatchFn\n sync?: boolean\n}): Promise<Array<MakeRouteMatch>> {\n const inner: InnerLoadContext = Object.assign(arg, {\n matchPromises: [],\n })\n\n // make sure the pending component is immediately rendered when hydrating a match that is not SSRed\n // the pending component was already rendered on the server and we want to keep it shown on the client until minPendingMs is reached\n if (\n !(isServer ?? inner.router.isServer) &&\n inner.router.state.matches.some((d) => d._forcePending)\n ) {\n triggerOnReady(inner)\n }\n\n try {\n // Execute all beforeLoads one by one\n for (let i = 0; i < inner.matches.length; i++) {\n const beforeLoad = handleBeforeLoad(inner, i)\n if (isPromise(beforeLoad)) await beforeLoad\n }\n\n // Execute all loaders in parallel\n const max = inner.firstBadMatchIndex ?? inner.matches.length\n for (let i = 0; i < max; i++) {\n inner.matchPromises.push(loadRouteMatch(inner, i))\n }\n // Use allSettled to ensure all loaders complete regardless of success/failure\n const results = await Promise.allSettled(inner.matchPromises)\n\n const failures = results\n // TODO when we drop support for TS 5.4, we can use the built-in type guard for PromiseRejectedResult\n .filter(\n (result): result is PromiseRejectedResult =>\n result.status === 'rejected',\n )\n .map((result) => result.reason)\n\n // Find first redirect (throw immediately) or notFound (throw after head execution)\n let firstNotFound: unknown\n for (const err of failures) {\n if (isRedirect(err)) {\n throw err\n }\n if (!firstNotFound && isNotFound(err)) {\n firstNotFound = err\n }\n }\n\n // serially execute head functions after all loaders have completed (successfully or not)\n // Each head execution is wrapped in try-catch to ensure all heads run even if one fails\n for (const match of inner.matches) {\n const { id: matchId, routeId } = match\n const route = inner.router.looseRoutesById[routeId]!\n try {\n const headResult = executeHead(inner, matchId, route)\n if (headResult) {\n const head = await headResult\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n ...head,\n }))\n }\n } catch (err) {\n // Log error but continue executing other head functions\n console.error(`Error executing head for route ${routeId}:`, err)\n }\n }\n\n // Throw notFound after head execution\n if (firstNotFound) {\n throw firstNotFound\n }\n\n const readyPromise = triggerOnReady(inner)\n if (isPromise(readyPromise)) await readyPromise\n } catch (err) {\n if (isNotFound(err) && !inner.preload) {\n const readyPromise = triggerOnReady(inner)\n if (isPromise(readyPromise)) await readyPromise\n throw err\n }\n if (isRedirect(err)) {\n throw err\n }\n }\n return inner.matches\n}\n\nexport async function loadRouteChunk(route: AnyRoute) {\n if (!route._lazyLoaded && route._lazyPromise === undefined) {\n if (route.lazyFn) {\n route._lazyPromise = route.lazyFn().then((lazyRoute) => {\n // explicitly don't copy over the lazy route's id\n const { id: _id, ...options } = lazyRoute.options\n Object.assign(route.options, options)\n route._lazyLoaded = true\n route._lazyPromise = undefined // gc promise, we won't need it anymore\n })\n } else {\n route._lazyLoaded = true\n }\n }\n\n // If for some reason lazy resolves more lazy components...\n // We'll wait for that before we attempt to preload the\n // components themselves.\n if (!route._componentsLoaded && route._componentsPromise === undefined) {\n const loadComponents = () => {\n const preloads = []\n for (const type of componentTypes) {\n const preload = (route.options[type] as any)?.preload\n if (preload) preloads.push(preload())\n }\n if (preloads.length)\n return Promise.all(preloads).then(() => {\n route._componentsLoaded = true\n route._componentsPromise = undefined // gc promise, we won't need it anymore\n })\n route._componentsLoaded = true\n route._componentsPromise = undefined // gc promise, we won't need it anymore\n return\n }\n route._componentsPromise = route._lazyPromise\n ? route._lazyPromise.then(loadComponents)\n : loadComponents()\n }\n return route._componentsPromise\n}\n\nfunction makeMaybe<TValue, TError>(\n value: TValue,\n error: TError,\n): { status: 'success'; value: TValue } | { status: 'error'; error: TError } {\n if (error) {\n return { status: 'error' as const, error }\n }\n return { status: 'success' as const, value }\n}\n\nexport function routeNeedsPreload(route: AnyRoute) {\n for (const componentType of componentTypes) {\n if ((route.options[componentType] as any)?.preload) {\n return true\n }\n }\n return false\n}\n\nexport const componentTypes = [\n 'component',\n 'errorComponent',\n 'pendingComponent',\n 'notFoundComponent',\n] as const\n"],"names":["tempSsr","beforeLoadContext","match"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"load-matches.js","sources":["../../src/load-matches.ts"],"sourcesContent":["import invariant from 'tiny-invariant'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { batch } from './utils/batch'\nimport { createControlledPromise, isPromise } from './utils'\nimport { isNotFound } from './not-found'\nimport { rootRouteId } from './root'\nimport { isRedirect } from './redirect'\nimport type { NotFoundError } from './not-found'\nimport type { ParsedLocation } from './location'\nimport type {\n AnyRoute,\n BeforeLoadContextOptions,\n LoaderFnContext,\n SsrContextOptions,\n} from './route'\nimport type { AnyRouteMatch, MakeRouteMatch } from './Matches'\nimport type { AnyRouter, SSROption, UpdateMatchFn } from './router'\n\n/**\n * An object of this shape is created when calling `loadMatches`.\n * It contains everything we need for all other functions in this file\n * to work. (It's basically the function's argument, plus a few mutable states)\n */\ntype InnerLoadContext = {\n /** the calling router instance */\n router: AnyRouter\n location: ParsedLocation\n /** mutable state, scoped to a `loadMatches` call */\n firstBadMatchIndex?: number\n /** mutable state, scoped to a `loadMatches` call */\n rendered?: boolean\n updateMatch: UpdateMatchFn\n matches: Array<AnyRouteMatch>\n preload?: boolean\n onReady?: () => Promise<void>\n sync?: boolean\n /** mutable state, scoped to a `loadMatches` call */\n matchPromises: Array<Promise<AnyRouteMatch>>\n}\n\nconst triggerOnReady = (inner: InnerLoadContext): void | Promise<void> => {\n if (!inner.rendered) {\n inner.rendered = true\n return inner.onReady?.()\n }\n}\n\nconst resolvePreload = (inner: InnerLoadContext, matchId: string): boolean => {\n return !!(\n inner.preload && !inner.router.state.matches.some((d) => d.id === matchId)\n )\n}\n\n/**\n * Builds the accumulated context from router options and all matches up to (and optionally including) the given index.\n * Merges __routeContext and __beforeLoadContext from each match.\n */\nconst buildMatchContext = (\n inner: InnerLoadContext,\n index: number,\n includeCurrentMatch: boolean = true,\n): Record<string, unknown> => {\n const context: Record<string, unknown> = {\n ...(inner.router.options.context ?? {}),\n }\n const end = includeCurrentMatch ? index : index - 1\n for (let i = 0; i <= end; i++) {\n const innerMatch = inner.matches[i]\n if (!innerMatch) continue\n const m = inner.router.getMatch(innerMatch.id)\n if (!m) continue\n Object.assign(context, m.__routeContext, m.__beforeLoadContext)\n }\n return context\n}\n\nconst _handleNotFound = (inner: InnerLoadContext, err: NotFoundError) => {\n // Find the route that should handle the not found error\n // First check if a specific route is requested to show the error\n const routeCursor =\n inner.router.routesById[err.routeId ?? ''] ?? inner.router.routeTree\n\n // Ensure a NotFoundComponent exists on the route\n if (\n !routeCursor.options.notFoundComponent &&\n (inner.router.options as any)?.defaultNotFoundComponent\n ) {\n routeCursor.options.notFoundComponent = (\n inner.router.options as any\n ).defaultNotFoundComponent\n }\n\n // Ensure we have a notFoundComponent\n invariant(\n routeCursor.options.notFoundComponent,\n 'No notFoundComponent found. Please set a notFoundComponent on your route or provide a defaultNotFoundComponent to the router.',\n )\n\n // Find the match for this route\n const matchForRoute = inner.matches.find((m) => m.routeId === routeCursor.id)\n\n invariant(matchForRoute, 'Could not find match for route: ' + routeCursor.id)\n\n // Assign the error to the match - using non-null assertion since we've checked with invariant\n inner.updateMatch(matchForRoute.id, (prev) => ({\n ...prev,\n status: 'notFound',\n error: err,\n isFetching: false,\n }))\n\n if ((err as any).routerCode === 'BEFORE_LOAD' && routeCursor.parentRoute) {\n err.routeId = routeCursor.parentRoute.id\n _handleNotFound(inner, err)\n }\n}\n\nconst handleRedirectAndNotFound = (\n inner: InnerLoadContext,\n match: AnyRouteMatch | undefined,\n err: unknown,\n): void => {\n if (!isRedirect(err) && !isNotFound(err)) return\n\n if (isRedirect(err) && err.redirectHandled && !err.options.reloadDocument) {\n throw err\n }\n\n // in case of a redirecting match during preload, the match does not exist\n if (match) {\n match._nonReactive.beforeLoadPromise?.resolve()\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.beforeLoadPromise = undefined\n match._nonReactive.loaderPromise = undefined\n\n const status = isRedirect(err) ? 'redirected' : 'notFound'\n\n match._nonReactive.error = err\n\n inner.updateMatch(match.id, (prev) => ({\n ...prev,\n status,\n context: buildMatchContext(inner, match.index),\n isFetching: false,\n error: err,\n }))\n\n if (isNotFound(err) && !err.routeId) {\n err.routeId = match.routeId\n }\n\n match._nonReactive.loadPromise?.resolve()\n }\n\n if (isRedirect(err)) {\n inner.rendered = true\n err.options._fromLocation = inner.location\n err.redirectHandled = true\n err = inner.router.resolveRedirect(err)\n throw err\n } else {\n _handleNotFound(inner, err)\n throw err\n }\n}\n\nconst shouldSkipLoader = (\n inner: InnerLoadContext,\n matchId: string,\n): boolean => {\n const match = inner.router.getMatch(matchId)!\n // upon hydration, we skip the loader if the match has been dehydrated on the server\n if (!(isServer ?? inner.router.isServer) && match._nonReactive.dehydrated) {\n return true\n }\n\n if ((isServer ?? inner.router.isServer) && match.ssr === false) {\n return true\n }\n\n return false\n}\n\nconst handleSerialError = (\n inner: InnerLoadContext,\n index: number,\n err: any,\n routerCode: string,\n): void => {\n const { id: matchId, routeId } = inner.matches[index]!\n const route = inner.router.looseRoutesById[routeId]!\n\n // Much like suspense, we use a promise here to know if\n // we've been outdated by a new loadMatches call and\n // should abort the current async operation\n if (err instanceof Promise) {\n throw err\n }\n\n err.routerCode = routerCode\n inner.firstBadMatchIndex ??= index\n handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), err)\n\n try {\n route.options.onError?.(err)\n } catch (errorHandlerErr) {\n err = errorHandlerErr\n handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), err)\n }\n\n inner.updateMatch(matchId, (prev) => {\n prev._nonReactive.beforeLoadPromise?.resolve()\n prev._nonReactive.beforeLoadPromise = undefined\n prev._nonReactive.loadPromise?.resolve()\n\n return {\n ...prev,\n error: err,\n status: 'error',\n isFetching: false,\n updatedAt: Date.now(),\n abortController: new AbortController(),\n }\n })\n}\n\nconst isBeforeLoadSsr = (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): void | Promise<void> => {\n const existingMatch = inner.router.getMatch(matchId)!\n const parentMatchId = inner.matches[index - 1]?.id\n const parentMatch = parentMatchId\n ? inner.router.getMatch(parentMatchId)!\n : undefined\n\n // in SPA mode, only SSR the root route\n if (inner.router.isShell()) {\n existingMatch.ssr = route.id === rootRouteId\n return\n }\n\n if (parentMatch?.ssr === false) {\n existingMatch.ssr = false\n return\n }\n\n const parentOverride = (tempSsr: SSROption) => {\n if (tempSsr === true && parentMatch?.ssr === 'data-only') {\n return 'data-only'\n }\n return tempSsr\n }\n\n const defaultSsr = inner.router.options.defaultSsr ?? true\n\n if (route.options.ssr === undefined) {\n existingMatch.ssr = parentOverride(defaultSsr)\n return\n }\n\n if (typeof route.options.ssr !== 'function') {\n existingMatch.ssr = parentOverride(route.options.ssr)\n return\n }\n const { search, params } = existingMatch\n\n const ssrFnContext: SsrContextOptions<any, any, any> = {\n search: makeMaybe(search, existingMatch.searchError),\n params: makeMaybe(params, existingMatch.paramsError),\n location: inner.location,\n matches: inner.matches.map((match) => ({\n index: match.index,\n pathname: match.pathname,\n fullPath: match.fullPath,\n staticData: match.staticData,\n id: match.id,\n routeId: match.routeId,\n search: makeMaybe(match.search, match.searchError),\n params: makeMaybe(match.params, match.paramsError),\n ssr: match.ssr,\n })),\n }\n\n const tempSsr = route.options.ssr(ssrFnContext)\n if (isPromise(tempSsr)) {\n return tempSsr.then((ssr) => {\n existingMatch.ssr = parentOverride(ssr ?? defaultSsr)\n })\n }\n\n existingMatch.ssr = parentOverride(tempSsr ?? defaultSsr)\n return\n}\n\nconst setupPendingTimeout = (\n inner: InnerLoadContext,\n matchId: string,\n route: AnyRoute,\n match: AnyRouteMatch,\n): void => {\n if (match._nonReactive.pendingTimeout !== undefined) return\n\n const pendingMs =\n route.options.pendingMs ?? inner.router.options.defaultPendingMs\n const shouldPending = !!(\n inner.onReady &&\n !(isServer ?? inner.router.isServer) &&\n !resolvePreload(inner, matchId) &&\n (route.options.loader ||\n route.options.beforeLoad ||\n routeNeedsPreload(route)) &&\n typeof pendingMs === 'number' &&\n pendingMs !== Infinity &&\n (route.options.pendingComponent ??\n (inner.router.options as any)?.defaultPendingComponent)\n )\n\n if (shouldPending) {\n const pendingTimeout = setTimeout(() => {\n // Update the match and prematurely resolve the loadMatches promise so that\n // the pending component can start rendering\n triggerOnReady(inner)\n }, pendingMs)\n match._nonReactive.pendingTimeout = pendingTimeout\n }\n}\n\nconst preBeforeLoadSetup = (\n inner: InnerLoadContext,\n matchId: string,\n route: AnyRoute,\n): void | Promise<void> => {\n const existingMatch = inner.router.getMatch(matchId)!\n\n // If we are in the middle of a load, either of these will be present\n // (not to be confused with `loadPromise`, which is always defined)\n if (\n !existingMatch._nonReactive.beforeLoadPromise &&\n !existingMatch._nonReactive.loaderPromise\n )\n return\n\n setupPendingTimeout(inner, matchId, route, existingMatch)\n\n const then = () => {\n const match = inner.router.getMatch(matchId)!\n if (\n match.preload &&\n (match.status === 'redirected' || match.status === 'notFound')\n ) {\n handleRedirectAndNotFound(inner, match, match.error)\n }\n }\n\n // Wait for the previous beforeLoad to resolve before we continue\n return existingMatch._nonReactive.beforeLoadPromise\n ? existingMatch._nonReactive.beforeLoadPromise.then(then)\n : then()\n}\n\nconst executeBeforeLoad = (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): void | Promise<void> => {\n const match = inner.router.getMatch(matchId)!\n\n // explicitly capture the previous loadPromise\n const prevLoadPromise = match._nonReactive.loadPromise\n match._nonReactive.loadPromise = createControlledPromise<void>(() => {\n prevLoadPromise?.resolve()\n })\n\n const { paramsError, searchError } = match\n\n if (paramsError) {\n handleSerialError(inner, index, paramsError, 'PARSE_PARAMS')\n }\n\n if (searchError) {\n handleSerialError(inner, index, searchError, 'VALIDATE_SEARCH')\n }\n\n setupPendingTimeout(inner, matchId, route, match)\n\n const abortController = new AbortController()\n\n let isPending = false\n const pending = () => {\n if (isPending) return\n isPending = true\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: 'beforeLoad',\n fetchCount: prev.fetchCount + 1,\n abortController,\n // Note: We intentionally don't update context here.\n // Context should only be updated after beforeLoad resolves to avoid\n // components seeing incomplete context during async beforeLoad execution.\n }))\n }\n\n const resolve = () => {\n match._nonReactive.beforeLoadPromise?.resolve()\n match._nonReactive.beforeLoadPromise = undefined\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: false,\n }))\n }\n\n // if there is no `beforeLoad` option, just mark as pending and resolve\n // Context will be updated later in loadRouteMatch after loader completes\n if (!route.options.beforeLoad) {\n batch(() => {\n pending()\n resolve()\n })\n return\n }\n\n match._nonReactive.beforeLoadPromise = createControlledPromise<void>()\n\n // Build context from all parent matches, excluding current match's __beforeLoadContext\n // (since we're about to execute beforeLoad for this match)\n const context = {\n ...buildMatchContext(inner, index, false),\n ...match.__routeContext,\n }\n const { search, params, cause } = match\n const preload = resolvePreload(inner, matchId)\n const beforeLoadFnContext: BeforeLoadContextOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > = {\n search,\n abortController,\n params,\n preload,\n context,\n location: inner.location,\n navigate: (opts: any) =>\n inner.router.navigate({\n ...opts,\n _fromLocation: inner.location,\n }),\n buildLocation: inner.router.buildLocation,\n cause: preload ? 'preload' : cause,\n matches: inner.matches,\n routeId: route.id,\n ...inner.router.options.additionalContext,\n }\n\n const updateContext = (beforeLoadContext: any) => {\n if (beforeLoadContext === undefined) {\n batch(() => {\n pending()\n resolve()\n })\n return\n }\n if (isRedirect(beforeLoadContext) || isNotFound(beforeLoadContext)) {\n pending()\n handleSerialError(inner, index, beforeLoadContext, 'BEFORE_LOAD')\n }\n\n batch(() => {\n pending()\n // Only store __beforeLoadContext here, don't update context yet\n // Context will be updated in loadRouteMatch after loader completes\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n __beforeLoadContext: beforeLoadContext,\n }))\n resolve()\n })\n }\n\n let beforeLoadContext\n try {\n beforeLoadContext = route.options.beforeLoad(beforeLoadFnContext)\n if (isPromise(beforeLoadContext)) {\n pending()\n return beforeLoadContext\n .catch((err) => {\n handleSerialError(inner, index, err, 'BEFORE_LOAD')\n })\n .then(updateContext)\n }\n } catch (err) {\n pending()\n handleSerialError(inner, index, err, 'BEFORE_LOAD')\n }\n\n updateContext(beforeLoadContext)\n return\n}\n\nconst handleBeforeLoad = (\n inner: InnerLoadContext,\n index: number,\n): void | Promise<void> => {\n const { id: matchId, routeId } = inner.matches[index]!\n const route = inner.router.looseRoutesById[routeId]!\n\n const serverSsr = () => {\n // on the server, determine whether SSR the current match or not\n if (isServer ?? inner.router.isServer) {\n const maybePromise = isBeforeLoadSsr(inner, matchId, index, route)\n if (isPromise(maybePromise)) return maybePromise.then(queueExecution)\n }\n return queueExecution()\n }\n\n const execute = () => executeBeforeLoad(inner, matchId, index, route)\n\n const queueExecution = () => {\n if (shouldSkipLoader(inner, matchId)) return\n const result = preBeforeLoadSetup(inner, matchId, route)\n return isPromise(result) ? result.then(execute) : execute()\n }\n\n return serverSsr()\n}\n\nconst executeHead = (\n inner: InnerLoadContext,\n matchId: string,\n route: AnyRoute,\n): void | Promise<\n Pick<\n AnyRouteMatch,\n 'meta' | 'links' | 'headScripts' | 'headers' | 'scripts' | 'styles'\n >\n> => {\n const match = inner.router.getMatch(matchId)\n // in case of a redirecting match during preload, the match does not exist\n if (!match) {\n return\n }\n if (!route.options.head && !route.options.scripts && !route.options.headers) {\n return\n }\n const assetContext = {\n ssr: inner.router.options.ssr,\n matches: inner.matches,\n match,\n params: match.params,\n loaderData: match.loaderData,\n }\n\n return Promise.all([\n route.options.head?.(assetContext),\n route.options.scripts?.(assetContext),\n route.options.headers?.(assetContext),\n ]).then(([headFnContent, scripts, headers]) => {\n const meta = headFnContent?.meta\n const links = headFnContent?.links\n const headScripts = headFnContent?.scripts\n const styles = headFnContent?.styles\n\n return {\n meta,\n links,\n headScripts,\n headers,\n scripts,\n styles,\n }\n })\n}\n\nconst getLoaderContext = (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): LoaderFnContext => {\n const parentMatchPromise = inner.matchPromises[index - 1] as any\n const { params, loaderDeps, abortController, cause } =\n inner.router.getMatch(matchId)!\n\n const context = buildMatchContext(inner, index)\n\n const preload = resolvePreload(inner, matchId)\n\n return {\n params,\n deps: loaderDeps,\n preload: !!preload,\n parentMatchPromise,\n abortController,\n context,\n location: inner.location,\n navigate: (opts) =>\n inner.router.navigate({\n ...opts,\n _fromLocation: inner.location,\n }),\n cause: preload ? 'preload' : cause,\n route,\n ...inner.router.options.additionalContext,\n }\n}\n\nconst runLoader = async (\n inner: InnerLoadContext,\n matchId: string,\n index: number,\n route: AnyRoute,\n): Promise<void> => {\n try {\n // If the Matches component rendered\n // the pending component and needs to show it for\n // a minimum duration, we''ll wait for it to resolve\n // before committing to the match and resolving\n // the loadPromise\n\n const match = inner.router.getMatch(matchId)!\n\n // Actually run the loader and handle the result\n try {\n if (!(isServer ?? inner.router.isServer) || match.ssr === true) {\n loadRouteChunk(route)\n }\n\n // Kick off the loader!\n const loaderResult = route.options.loader?.(\n getLoaderContext(inner, matchId, index, route),\n )\n const loaderResultIsPromise =\n route.options.loader && isPromise(loaderResult)\n\n const willLoadSomething = !!(\n loaderResultIsPromise ||\n route._lazyPromise ||\n route._componentsPromise ||\n route.options.head ||\n route.options.scripts ||\n route.options.headers ||\n match._nonReactive.minPendingPromise\n )\n\n if (willLoadSomething) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: 'loader',\n }))\n }\n\n if (route.options.loader) {\n const loaderData = loaderResultIsPromise\n ? await loaderResult\n : loaderResult\n\n handleRedirectAndNotFound(\n inner,\n inner.router.getMatch(matchId),\n loaderData,\n )\n if (loaderData !== undefined) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n loaderData,\n }))\n }\n }\n\n // Lazy option can modify the route options,\n // so we need to wait for it to resolve before\n // we can use the options\n if (route._lazyPromise) await route._lazyPromise\n const pendingPromise = match._nonReactive.minPendingPromise\n if (pendingPromise) await pendingPromise\n\n // Last but not least, wait for the the components\n // to be preloaded before we resolve the match\n if (route._componentsPromise) await route._componentsPromise\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n error: undefined,\n context: buildMatchContext(inner, index),\n status: 'success',\n isFetching: false,\n updatedAt: Date.now(),\n }))\n } catch (e) {\n let error = e\n\n if ((error as any)?.name === 'AbortError') {\n if (match.abortController.signal.aborted) {\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.loaderPromise = undefined\n return\n }\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n status: prev.status === 'pending' ? 'success' : prev.status,\n isFetching: false,\n context: buildMatchContext(inner, index),\n }))\n return\n }\n\n const pendingPromise = match._nonReactive.minPendingPromise\n if (pendingPromise) await pendingPromise\n\n if (isNotFound(e)) {\n await (route.options.notFoundComponent as any)?.preload?.()\n }\n\n handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), e)\n\n try {\n route.options.onError?.(e)\n } catch (onErrorError) {\n error = onErrorError\n handleRedirectAndNotFound(\n inner,\n inner.router.getMatch(matchId),\n onErrorError,\n )\n }\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n error,\n context: buildMatchContext(inner, index),\n status: 'error',\n isFetching: false,\n }))\n }\n } catch (err) {\n const match = inner.router.getMatch(matchId)\n // in case of a redirecting match during preload, the match does not exist\n if (match) {\n match._nonReactive.loaderPromise = undefined\n }\n handleRedirectAndNotFound(inner, match, err)\n }\n}\n\nconst loadRouteMatch = async (\n inner: InnerLoadContext,\n index: number,\n): Promise<AnyRouteMatch> => {\n async function handleLoader(\n preload: boolean,\n prevMatch: AnyRouteMatch,\n match: AnyRouteMatch,\n route: AnyRoute,\n ) {\n const age = Date.now() - prevMatch.updatedAt\n\n const staleAge = preload\n ? (route.options.preloadStaleTime ??\n inner.router.options.defaultPreloadStaleTime ??\n 30_000) // 30 seconds for preloads by default\n : (route.options.staleTime ?? inner.router.options.defaultStaleTime ?? 0)\n\n const shouldReloadOption = route.options.shouldReload\n\n // Default to reloading the route all the time\n // Allow shouldReload to get the last say,\n // if provided.\n const shouldReload =\n typeof shouldReloadOption === 'function'\n ? shouldReloadOption(getLoaderContext(inner, matchId, index, route))\n : shouldReloadOption\n\n // If the route is successful and still fresh, just resolve\n const { status, invalid } = match\n loaderShouldRunAsync =\n status === 'success' && (invalid || (shouldReload ?? age > staleAge))\n if (preload && route.options.preload === false) {\n // Do nothing\n } else if (loaderShouldRunAsync && !inner.sync) {\n loaderIsRunningAsync = true\n ;(async () => {\n try {\n await runLoader(inner, matchId, index, route)\n const match = inner.router.getMatch(matchId)!\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.loadPromise?.resolve()\n match._nonReactive.loaderPromise = undefined\n } catch (err) {\n if (isRedirect(err)) {\n await inner.router.navigate(err.options)\n }\n }\n })()\n } else if (status !== 'success' || (loaderShouldRunAsync && inner.sync)) {\n await runLoader(inner, matchId, index, route)\n }\n }\n\n const { id: matchId, routeId } = inner.matches[index]!\n let loaderShouldRunAsync = false\n let loaderIsRunningAsync = false\n const route = inner.router.looseRoutesById[routeId]!\n\n if (shouldSkipLoader(inner, matchId)) {\n if (isServer ?? inner.router.isServer) {\n return inner.router.getMatch(matchId)!\n }\n } else {\n const prevMatch = inner.router.getMatch(matchId)! // This is where all of the stale-while-revalidate magic happens\n const preload = resolvePreload(inner, matchId)\n\n // there is a loaderPromise, so we are in the middle of a load\n if (prevMatch._nonReactive.loaderPromise) {\n // do not block if we already have stale data we can show\n // but only if the ongoing load is not a preload since error handling is different for preloads\n // and we don't want to swallow errors\n if (prevMatch.status === 'success' && !inner.sync && !prevMatch.preload) {\n return prevMatch\n }\n await prevMatch._nonReactive.loaderPromise\n const match = inner.router.getMatch(matchId)!\n const error = match._nonReactive.error || match.error\n if (error) {\n handleRedirectAndNotFound(inner, match, error)\n }\n\n if (match.status === 'pending') {\n await handleLoader(preload, prevMatch, match, route)\n }\n } else {\n const nextPreload =\n preload && !inner.router.state.matches.some((d) => d.id === matchId)\n const match = inner.router.getMatch(matchId)!\n match._nonReactive.loaderPromise = createControlledPromise<void>()\n if (nextPreload !== match.preload) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n preload: nextPreload,\n }))\n }\n\n await handleLoader(preload, prevMatch, match, route)\n }\n }\n const match = inner.router.getMatch(matchId)!\n if (!loaderIsRunningAsync) {\n match._nonReactive.loaderPromise?.resolve()\n match._nonReactive.loadPromise?.resolve()\n }\n\n clearTimeout(match._nonReactive.pendingTimeout)\n match._nonReactive.pendingTimeout = undefined\n if (!loaderIsRunningAsync) match._nonReactive.loaderPromise = undefined\n match._nonReactive.dehydrated = undefined\n\n const nextIsFetching = loaderIsRunningAsync ? match.isFetching : false\n if (nextIsFetching !== match.isFetching || match.invalid !== false) {\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n isFetching: nextIsFetching,\n invalid: false,\n }))\n return inner.router.getMatch(matchId)!\n } else {\n return match\n }\n}\n\nexport async function loadMatches(arg: {\n router: AnyRouter\n location: ParsedLocation\n matches: Array<AnyRouteMatch>\n preload?: boolean\n onReady?: () => Promise<void>\n updateMatch: UpdateMatchFn\n sync?: boolean\n}): Promise<Array<MakeRouteMatch>> {\n const inner: InnerLoadContext = Object.assign(arg, {\n matchPromises: [],\n })\n\n // make sure the pending component is immediately rendered when hydrating a match that is not SSRed\n // the pending component was already rendered on the server and we want to keep it shown on the client until minPendingMs is reached\n if (\n !(isServer ?? inner.router.isServer) &&\n inner.router.state.matches.some((d) => d._forcePending)\n ) {\n triggerOnReady(inner)\n }\n\n try {\n // Execute all beforeLoads one by one\n for (let i = 0; i < inner.matches.length; i++) {\n const beforeLoad = handleBeforeLoad(inner, i)\n if (isPromise(beforeLoad)) await beforeLoad\n }\n\n // Execute all loaders in parallel\n const max = inner.firstBadMatchIndex ?? inner.matches.length\n for (let i = 0; i < max; i++) {\n inner.matchPromises.push(loadRouteMatch(inner, i))\n }\n // Use allSettled to ensure all loaders complete regardless of success/failure\n const results = await Promise.allSettled(inner.matchPromises)\n\n const failures = results\n // TODO when we drop support for TS 5.4, we can use the built-in type guard for PromiseRejectedResult\n .filter(\n (result): result is PromiseRejectedResult =>\n result.status === 'rejected',\n )\n .map((result) => result.reason)\n\n // Find first redirect (throw immediately) or notFound (throw after head execution)\n let firstNotFound: unknown\n for (const err of failures) {\n if (isRedirect(err)) {\n throw err\n }\n if (!firstNotFound && isNotFound(err)) {\n firstNotFound = err\n }\n }\n\n // serially execute head functions after all loaders have completed (successfully or not)\n // Each head execution is wrapped in try-catch to ensure all heads run even if one fails\n for (const match of inner.matches) {\n const { id: matchId, routeId } = match\n const route = inner.router.looseRoutesById[routeId]!\n try {\n const headResult = executeHead(inner, matchId, route)\n if (headResult) {\n const head = await headResult\n inner.updateMatch(matchId, (prev) => ({\n ...prev,\n ...head,\n }))\n }\n } catch (err) {\n // Log error but continue executing other head functions\n console.error(`Error executing head for route ${routeId}:`, err)\n }\n }\n\n // Throw notFound after head execution\n if (firstNotFound) {\n throw firstNotFound\n }\n\n const readyPromise = triggerOnReady(inner)\n if (isPromise(readyPromise)) await readyPromise\n } catch (err) {\n if (isNotFound(err) && !inner.preload) {\n const readyPromise = triggerOnReady(inner)\n if (isPromise(readyPromise)) await readyPromise\n throw err\n }\n if (isRedirect(err)) {\n throw err\n }\n }\n return inner.matches\n}\n\nexport async function loadRouteChunk(route: AnyRoute) {\n if (!route._lazyLoaded && route._lazyPromise === undefined) {\n if (route.lazyFn) {\n route._lazyPromise = route.lazyFn().then((lazyRoute) => {\n // explicitly don't copy over the lazy route's id\n const { id: _id, ...options } = lazyRoute.options\n Object.assign(route.options, options)\n route._lazyLoaded = true\n route._lazyPromise = undefined // gc promise, we won't need it anymore\n })\n } else {\n route._lazyLoaded = true\n }\n }\n\n // If for some reason lazy resolves more lazy components...\n // We'll wait for that before we attempt to preload the\n // components themselves.\n if (!route._componentsLoaded && route._componentsPromise === undefined) {\n const loadComponents = () => {\n const preloads = []\n for (const type of componentTypes) {\n const preload = (route.options[type] as any)?.preload\n if (preload) preloads.push(preload())\n }\n if (preloads.length)\n return Promise.all(preloads).then(() => {\n route._componentsLoaded = true\n route._componentsPromise = undefined // gc promise, we won't need it anymore\n })\n route._componentsLoaded = true\n route._componentsPromise = undefined // gc promise, we won't need it anymore\n return\n }\n route._componentsPromise = route._lazyPromise\n ? route._lazyPromise.then(loadComponents)\n : loadComponents()\n }\n return route._componentsPromise\n}\n\nfunction makeMaybe<TValue, TError>(\n value: TValue,\n error: TError,\n): { status: 'success'; value: TValue } | { status: 'error'; error: TError } {\n if (error) {\n return { status: 'error' as const, error }\n }\n return { status: 'success' as const, value }\n}\n\nexport function routeNeedsPreload(route: AnyRoute) {\n for (const componentType of componentTypes) {\n if ((route.options[componentType] as any)?.preload) {\n return true\n }\n }\n return false\n}\n\nexport const componentTypes = [\n 'component',\n 'errorComponent',\n 'pendingComponent',\n 'notFoundComponent',\n] as const\n"],"names":["tempSsr","beforeLoadContext","match","route"],"mappings":"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"}
|
package/package.json
CHANGED
package/src/load-matches.ts
CHANGED
|
@@ -699,6 +699,11 @@ const runLoader = async (
|
|
|
699
699
|
let error = e
|
|
700
700
|
|
|
701
701
|
if ((error as any)?.name === 'AbortError') {
|
|
702
|
+
if (match.abortController.signal.aborted) {
|
|
703
|
+
match._nonReactive.loaderPromise?.resolve()
|
|
704
|
+
match._nonReactive.loaderPromise = undefined
|
|
705
|
+
return
|
|
706
|
+
}
|
|
702
707
|
inner.updateMatch(matchId, (prev) => ({
|
|
703
708
|
...prev,
|
|
704
709
|
status: prev.status === 'pending' ? 'success' : prev.status,
|
|
@@ -749,6 +754,56 @@ const loadRouteMatch = async (
|
|
|
749
754
|
inner: InnerLoadContext,
|
|
750
755
|
index: number,
|
|
751
756
|
): Promise<AnyRouteMatch> => {
|
|
757
|
+
async function handleLoader(
|
|
758
|
+
preload: boolean,
|
|
759
|
+
prevMatch: AnyRouteMatch,
|
|
760
|
+
match: AnyRouteMatch,
|
|
761
|
+
route: AnyRoute,
|
|
762
|
+
) {
|
|
763
|
+
const age = Date.now() - prevMatch.updatedAt
|
|
764
|
+
|
|
765
|
+
const staleAge = preload
|
|
766
|
+
? (route.options.preloadStaleTime ??
|
|
767
|
+
inner.router.options.defaultPreloadStaleTime ??
|
|
768
|
+
30_000) // 30 seconds for preloads by default
|
|
769
|
+
: (route.options.staleTime ?? inner.router.options.defaultStaleTime ?? 0)
|
|
770
|
+
|
|
771
|
+
const shouldReloadOption = route.options.shouldReload
|
|
772
|
+
|
|
773
|
+
// Default to reloading the route all the time
|
|
774
|
+
// Allow shouldReload to get the last say,
|
|
775
|
+
// if provided.
|
|
776
|
+
const shouldReload =
|
|
777
|
+
typeof shouldReloadOption === 'function'
|
|
778
|
+
? shouldReloadOption(getLoaderContext(inner, matchId, index, route))
|
|
779
|
+
: shouldReloadOption
|
|
780
|
+
|
|
781
|
+
// If the route is successful and still fresh, just resolve
|
|
782
|
+
const { status, invalid } = match
|
|
783
|
+
loaderShouldRunAsync =
|
|
784
|
+
status === 'success' && (invalid || (shouldReload ?? age > staleAge))
|
|
785
|
+
if (preload && route.options.preload === false) {
|
|
786
|
+
// Do nothing
|
|
787
|
+
} else if (loaderShouldRunAsync && !inner.sync) {
|
|
788
|
+
loaderIsRunningAsync = true
|
|
789
|
+
;(async () => {
|
|
790
|
+
try {
|
|
791
|
+
await runLoader(inner, matchId, index, route)
|
|
792
|
+
const match = inner.router.getMatch(matchId)!
|
|
793
|
+
match._nonReactive.loaderPromise?.resolve()
|
|
794
|
+
match._nonReactive.loadPromise?.resolve()
|
|
795
|
+
match._nonReactive.loaderPromise = undefined
|
|
796
|
+
} catch (err) {
|
|
797
|
+
if (isRedirect(err)) {
|
|
798
|
+
await inner.router.navigate(err.options)
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
})()
|
|
802
|
+
} else if (status !== 'success' || (loaderShouldRunAsync && inner.sync)) {
|
|
803
|
+
await runLoader(inner, matchId, index, route)
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
752
807
|
const { id: matchId, routeId } = inner.matches[index]!
|
|
753
808
|
let loaderShouldRunAsync = false
|
|
754
809
|
let loaderIsRunningAsync = false
|
|
@@ -759,7 +814,9 @@ const loadRouteMatch = async (
|
|
|
759
814
|
return inner.router.getMatch(matchId)!
|
|
760
815
|
}
|
|
761
816
|
} else {
|
|
762
|
-
const prevMatch = inner.router.getMatch(matchId)!
|
|
817
|
+
const prevMatch = inner.router.getMatch(matchId)! // This is where all of the stale-while-revalidate magic happens
|
|
818
|
+
const preload = resolvePreload(inner, matchId)
|
|
819
|
+
|
|
763
820
|
// there is a loaderPromise, so we are in the middle of a load
|
|
764
821
|
if (prevMatch._nonReactive.loaderPromise) {
|
|
765
822
|
// do not block if we already have stale data we can show
|
|
@@ -774,32 +831,13 @@ const loadRouteMatch = async (
|
|
|
774
831
|
if (error) {
|
|
775
832
|
handleRedirectAndNotFound(inner, match, error)
|
|
776
833
|
}
|
|
777
|
-
} else {
|
|
778
|
-
// This is where all of the stale-while-revalidate magic happens
|
|
779
|
-
const age = Date.now() - prevMatch.updatedAt
|
|
780
|
-
|
|
781
|
-
const preload = resolvePreload(inner, matchId)
|
|
782
|
-
|
|
783
|
-
const staleAge = preload
|
|
784
|
-
? (route.options.preloadStaleTime ??
|
|
785
|
-
inner.router.options.defaultPreloadStaleTime ??
|
|
786
|
-
30_000) // 30 seconds for preloads by default
|
|
787
|
-
: (route.options.staleTime ??
|
|
788
|
-
inner.router.options.defaultStaleTime ??
|
|
789
|
-
0)
|
|
790
|
-
|
|
791
|
-
const shouldReloadOption = route.options.shouldReload
|
|
792
|
-
|
|
793
|
-
// Default to reloading the route all the time
|
|
794
|
-
// Allow shouldReload to get the last say,
|
|
795
|
-
// if provided.
|
|
796
|
-
const shouldReload =
|
|
797
|
-
typeof shouldReloadOption === 'function'
|
|
798
|
-
? shouldReloadOption(getLoaderContext(inner, matchId, index, route))
|
|
799
|
-
: shouldReloadOption
|
|
800
834
|
|
|
835
|
+
if (match.status === 'pending') {
|
|
836
|
+
await handleLoader(preload, prevMatch, match, route)
|
|
837
|
+
}
|
|
838
|
+
} else {
|
|
801
839
|
const nextPreload =
|
|
802
|
-
|
|
840
|
+
preload && !inner.router.state.matches.some((d) => d.id === matchId)
|
|
803
841
|
const match = inner.router.getMatch(matchId)!
|
|
804
842
|
match._nonReactive.loaderPromise = createControlledPromise<void>()
|
|
805
843
|
if (nextPreload !== match.preload) {
|
|
@@ -809,30 +847,7 @@ const loadRouteMatch = async (
|
|
|
809
847
|
}))
|
|
810
848
|
}
|
|
811
849
|
|
|
812
|
-
|
|
813
|
-
const { status, invalid } = match
|
|
814
|
-
loaderShouldRunAsync =
|
|
815
|
-
status === 'success' && (invalid || (shouldReload ?? age > staleAge))
|
|
816
|
-
if (preload && route.options.preload === false) {
|
|
817
|
-
// Do nothing
|
|
818
|
-
} else if (loaderShouldRunAsync && !inner.sync) {
|
|
819
|
-
loaderIsRunningAsync = true
|
|
820
|
-
;(async () => {
|
|
821
|
-
try {
|
|
822
|
-
await runLoader(inner, matchId, index, route)
|
|
823
|
-
const match = inner.router.getMatch(matchId)!
|
|
824
|
-
match._nonReactive.loaderPromise?.resolve()
|
|
825
|
-
match._nonReactive.loadPromise?.resolve()
|
|
826
|
-
match._nonReactive.loaderPromise = undefined
|
|
827
|
-
} catch (err) {
|
|
828
|
-
if (isRedirect(err)) {
|
|
829
|
-
await inner.router.navigate(err.options)
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
})()
|
|
833
|
-
} else if (status !== 'success' || (loaderShouldRunAsync && inner.sync)) {
|
|
834
|
-
await runLoader(inner, matchId, index, route)
|
|
835
|
-
}
|
|
850
|
+
await handleLoader(preload, prevMatch, match, route)
|
|
836
851
|
}
|
|
837
852
|
}
|
|
838
853
|
const match = inner.router.getMatch(matchId)!
|