@tanstack/router-core 1.131.7 → 1.131.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/router-core",
3
- "version": "1.131.7",
3
+ "version": "1.131.13",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
package/src/router.ts CHANGED
@@ -1393,8 +1393,8 @@ export class RouterCore<
1393
1393
  if (!match) return
1394
1394
 
1395
1395
  match.abortController.abort()
1396
- match._nonReactive.pendingTimeout = undefined
1397
1396
  clearTimeout(match._nonReactive.pendingTimeout)
1397
+ match._nonReactive.pendingTimeout = undefined
1398
1398
  }
1399
1399
 
1400
1400
  cancelMatches = () => {
@@ -2121,50 +2121,52 @@ export class RouterCore<
2121
2121
  triggerOnReady()
2122
2122
  }
2123
2123
 
2124
- const handleRedirectAndNotFound = (match: AnyRouteMatch, err: any) => {
2125
- if (isRedirect(err) || isNotFound(err)) {
2126
- if (isRedirect(err)) {
2127
- if (err.redirectHandled) {
2128
- if (!err.options.reloadDocument) {
2129
- throw err
2130
- }
2131
- }
2132
- }
2124
+ const handleRedirectAndNotFound = (
2125
+ match: AnyRouteMatch | undefined,
2126
+ err: unknown,
2127
+ ) => {
2128
+ if (!isRedirect(err) && !isNotFound(err)) return
2129
+
2130
+ if (
2131
+ isRedirect(err) &&
2132
+ err.redirectHandled &&
2133
+ !err.options.reloadDocument
2134
+ ) {
2135
+ throw err
2136
+ }
2133
2137
 
2138
+ // in case of a redirecting match during preload, the match does not exist
2139
+ if (match) {
2134
2140
  match._nonReactive.beforeLoadPromise?.resolve()
2135
2141
  match._nonReactive.loaderPromise?.resolve()
2136
2142
  match._nonReactive.beforeLoadPromise = undefined
2137
2143
  match._nonReactive.loaderPromise = undefined
2138
2144
 
2145
+ const status = isRedirect(err) ? 'redirected' : 'notFound'
2146
+
2139
2147
  updateMatch(match.id, (prev) => ({
2140
2148
  ...prev,
2141
- status: isRedirect(err)
2142
- ? 'redirected'
2143
- : isNotFound(err)
2144
- ? 'notFound'
2145
- : 'error',
2149
+ status,
2146
2150
  isFetching: false,
2147
2151
  error: err,
2148
2152
  }))
2149
2153
 
2150
- if (!(err as any).routeId) {
2151
- ;(err as any).routeId = match.routeId
2154
+ if (isNotFound(err) && !err.routeId) {
2155
+ err.routeId = match.routeId
2152
2156
  }
2153
2157
 
2154
2158
  match._nonReactive.loadPromise?.resolve()
2159
+ }
2155
2160
 
2156
- if (isRedirect(err)) {
2157
- rendered = true
2158
- err.options._fromLocation = location
2159
- err.redirectHandled = true
2160
- err = this.resolveRedirect(err)
2161
- throw err
2162
- } else if (isNotFound(err)) {
2163
- this._handleNotFound(matches, err, {
2164
- updateMatch,
2165
- })
2166
- throw err
2167
- }
2161
+ if (isRedirect(err)) {
2162
+ rendered = true
2163
+ err.options._fromLocation = location
2164
+ err.redirectHandled = true
2165
+ err = this.resolveRedirect(err)
2166
+ throw err
2167
+ } else {
2168
+ this._handleNotFound(matches, err, updateMatch)
2169
+ throw err
2168
2170
  }
2169
2171
  }
2170
2172
 
@@ -2204,13 +2206,13 @@ export class RouterCore<
2204
2206
 
2205
2207
  err.routerCode = routerCode
2206
2208
  firstBadMatchIndex = firstBadMatchIndex ?? index
2207
- handleRedirectAndNotFound(this.getMatch(matchId)!, err)
2209
+ handleRedirectAndNotFound(this.getMatch(matchId), err)
2208
2210
 
2209
2211
  try {
2210
2212
  route.options.onError?.(err)
2211
2213
  } catch (errorHandlerErr) {
2212
2214
  err = errorHandlerErr
2213
- handleRedirectAndNotFound(this.getMatch(matchId)!, err)
2215
+ handleRedirectAndNotFound(this.getMatch(matchId), err)
2214
2216
  }
2215
2217
 
2216
2218
  updateMatch(matchId, (prev) => {
@@ -2465,35 +2467,45 @@ export class RouterCore<
2465
2467
  let loaderIsRunningAsync = false
2466
2468
  const route = this.looseRoutesById[routeId]!
2467
2469
 
2468
- const executeHead = async () => {
2470
+ const executeHead = () => {
2469
2471
  const match = this.getMatch(matchId)
2470
2472
  // in case of a redirecting match during preload, the match does not exist
2471
2473
  if (!match) {
2472
2474
  return
2473
2475
  }
2476
+ if (
2477
+ !route.options.head &&
2478
+ !route.options.scripts &&
2479
+ !route.options.headers
2480
+ ) {
2481
+ return
2482
+ }
2474
2483
  const assetContext = {
2475
2484
  matches,
2476
2485
  match,
2477
2486
  params: match.params,
2478
2487
  loaderData: match.loaderData,
2479
2488
  }
2480
- const headFnContent =
2481
- await route.options.head?.(assetContext)
2482
- const meta = headFnContent?.meta
2483
- const links = headFnContent?.links
2484
- const headScripts = headFnContent?.scripts
2485
- const styles = headFnContent?.styles
2486
-
2487
- const scripts = await route.options.scripts?.(assetContext)
2488
- const headers = await route.options.headers?.(assetContext)
2489
- return {
2490
- meta,
2491
- links,
2492
- headScripts,
2493
- headers,
2494
- scripts,
2495
- styles,
2496
- }
2489
+
2490
+ return Promise.all([
2491
+ route.options.head?.(assetContext),
2492
+ route.options.scripts?.(assetContext),
2493
+ route.options.headers?.(assetContext),
2494
+ ]).then(([headFnContent, scripts, headers]) => {
2495
+ const meta = headFnContent?.meta
2496
+ const links = headFnContent?.links
2497
+ const headScripts = headFnContent?.scripts
2498
+ const styles = headFnContent?.styles
2499
+
2500
+ return {
2501
+ meta,
2502
+ links,
2503
+ headScripts,
2504
+ headers,
2505
+ scripts,
2506
+ styles,
2507
+ }
2508
+ })
2497
2509
  }
2498
2510
 
2499
2511
  const potentialPendingMinPromise = async () => {
@@ -2506,11 +2518,14 @@ export class RouterCore<
2506
2518
  const prevMatch = this.getMatch(matchId)!
2507
2519
  if (shouldSkipLoader(matchId)) {
2508
2520
  if (this.isServer) {
2509
- const head = await executeHead()
2510
- updateMatch(matchId, (prev) => ({
2511
- ...prev,
2512
- ...head,
2513
- }))
2521
+ const headResult = executeHead()
2522
+ if (headResult) {
2523
+ const head = await headResult
2524
+ updateMatch(matchId, (prev) => ({
2525
+ ...prev,
2526
+ ...head,
2527
+ }))
2528
+ }
2514
2529
  return this.getMatch(matchId)!
2515
2530
  }
2516
2531
  }
@@ -2622,7 +2637,7 @@ export class RouterCore<
2622
2637
  await route.options.loader?.(getLoaderContext())
2623
2638
 
2624
2639
  handleRedirectAndNotFound(
2625
- this.getMatch(matchId)!,
2640
+ this.getMatch(matchId),
2626
2641
  loaderData,
2627
2642
  )
2628
2643
  updateMatch(matchId, (prev) => ({
@@ -2634,7 +2649,8 @@ export class RouterCore<
2634
2649
  // so we need to wait for it to resolve before
2635
2650
  // we can use the options
2636
2651
  await route._lazyPromise
2637
- const head = await executeHead()
2652
+ const headResult = executeHead()
2653
+ const head = headResult ? await headResult : undefined
2638
2654
  await potentialPendingMinPromise()
2639
2655
 
2640
2656
  // Last but not least, wait for the the components
@@ -2653,18 +2669,19 @@ export class RouterCore<
2653
2669
 
2654
2670
  await potentialPendingMinPromise()
2655
2671
 
2656
- handleRedirectAndNotFound(this.getMatch(matchId)!, e)
2672
+ handleRedirectAndNotFound(this.getMatch(matchId), e)
2657
2673
 
2658
2674
  try {
2659
2675
  route.options.onError?.(e)
2660
2676
  } catch (onErrorError) {
2661
2677
  error = onErrorError
2662
2678
  handleRedirectAndNotFound(
2663
- this.getMatch(matchId)!,
2679
+ this.getMatch(matchId),
2664
2680
  onErrorError,
2665
2681
  )
2666
2682
  }
2667
- const head = await executeHead()
2683
+ const headResult = executeHead()
2684
+ const head = headResult ? await headResult : undefined
2668
2685
  updateMatch(matchId, (prev) => ({
2669
2686
  ...prev,
2670
2687
  error,
@@ -2674,16 +2691,20 @@ export class RouterCore<
2674
2691
  }))
2675
2692
  }
2676
2693
  } catch (err) {
2677
- const head = await executeHead()
2678
-
2679
- updateMatch(matchId, (prev) => {
2680
- prev._nonReactive.loaderPromise = undefined
2681
- return {
2682
- ...prev,
2683
- ...head,
2694
+ const match = this.getMatch(matchId)
2695
+ // in case of a redirecting match during preload, the match does not exist
2696
+ if (match) {
2697
+ const headResult = executeHead()
2698
+ if (headResult) {
2699
+ const head = await headResult
2700
+ updateMatch(matchId, (prev) => ({
2701
+ ...prev,
2702
+ ...head,
2703
+ }))
2684
2704
  }
2685
- })
2686
- handleRedirectAndNotFound(this.getMatch(matchId)!, err)
2705
+ match._nonReactive.loaderPromise = undefined
2706
+ }
2707
+ handleRedirectAndNotFound(match, err)
2687
2708
  }
2688
2709
  }
2689
2710
 
@@ -2718,11 +2739,14 @@ export class RouterCore<
2718
2739
  // if the loader did not run, still update head.
2719
2740
  // reason: parent's beforeLoad may have changed the route context
2720
2741
  // and only now do we know the route context (and that the loader would not run)
2721
- const head = await executeHead()
2722
- updateMatch(matchId, (prev) => ({
2723
- ...prev,
2724
- ...head,
2725
- }))
2742
+ const headResult = executeHead()
2743
+ if (headResult) {
2744
+ const head = await headResult
2745
+ updateMatch(matchId, (prev) => ({
2746
+ ...prev,
2747
+ ...head,
2748
+ }))
2749
+ }
2726
2750
  }
2727
2751
  }
2728
2752
  if (!loaderIsRunningAsync) {
@@ -3035,14 +3059,10 @@ export class RouterCore<
3035
3059
  _handleNotFound = (
3036
3060
  matches: Array<AnyRouteMatch>,
3037
3061
  err: NotFoundError,
3038
- {
3039
- updateMatch = this.updateMatch,
3040
- }: {
3041
- updateMatch?: (
3042
- id: string,
3043
- updater: (match: AnyRouteMatch) => AnyRouteMatch,
3044
- ) => void
3045
- } = {},
3062
+ updateMatch: (
3063
+ id: string,
3064
+ updater: (match: AnyRouteMatch) => AnyRouteMatch,
3065
+ ) => void = this.updateMatch,
3046
3066
  ) => {
3047
3067
  // Find the route that should handle the not found error
3048
3068
  // First check if a specific route is requested to show the error
@@ -3088,9 +3108,7 @@ export class RouterCore<
3088
3108
 
3089
3109
  if ((err as any).routerCode === 'BEFORE_LOAD' && routeCursor.parentRoute) {
3090
3110
  err.routeId = routeCursor.parentRoute.id
3091
- this._handleNotFound(matches, err, {
3092
- updateMatch,
3093
- })
3111
+ this._handleNotFound(matches, err, updateMatch)
3094
3112
  }
3095
3113
  }
3096
3114