@tanstack/router-core 1.122.0 → 1.123.2

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.122.0",
3
+ "version": "1.123.2",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
package/src/router.ts CHANGED
@@ -588,6 +588,7 @@ export type UpdateFn<
588
588
  export type InvalidateFn<TRouter extends AnyRouter> = (opts?: {
589
589
  filter?: (d: MakeRouteMatchUnion<TRouter>) => boolean
590
590
  sync?: boolean
591
+ forcePending?: boolean
591
592
  }) => Promise<void>
592
593
 
593
594
  export type ParseLocationFn<TRouteTree extends AnyRoute> = (
@@ -1790,16 +1791,9 @@ export class RouterCore<
1790
1791
  location: this.latestLocation,
1791
1792
  pendingMatches,
1792
1793
  // If a cached moved to pendingMatches, remove it from cachedMatches
1793
- cachedMatches: s.cachedMatches.filter((cachedMatch) => {
1794
- const pendingMatch = pendingMatches.find((e) => e.id === cachedMatch.id)
1795
-
1796
- if (!pendingMatch) return true
1797
-
1798
- return (
1799
- cachedMatch.status === 'success' &&
1800
- (cachedMatch.isFetching || cachedMatch.loaderData !== undefined)
1801
- )
1802
- }),
1794
+ cachedMatches: s.cachedMatches.filter(
1795
+ (d) => !pendingMatches.find((e) => e.id === d.id),
1796
+ ),
1803
1797
  }))
1804
1798
  }
1805
1799
 
@@ -2207,7 +2201,15 @@ export class RouterCore<
2207
2201
 
2208
2202
  // Wait for the beforeLoad to resolve before we continue
2209
2203
  await existingMatch.beforeLoadPromise
2210
- executeBeforeLoad = this.getMatch(matchId)!.status === 'error'
2204
+ const match = this.getMatch(matchId)!
2205
+ if (match.status === 'error') {
2206
+ executeBeforeLoad = true
2207
+ } else if (
2208
+ match.preload &&
2209
+ (match.status === 'redirected' || match.status === 'notFound')
2210
+ ) {
2211
+ handleRedirectAndNotFound(match, match.error)
2212
+ }
2211
2213
  }
2212
2214
  if (executeBeforeLoad) {
2213
2215
  // If we are not in the middle of a load OR the previous load failed, start it
@@ -2336,14 +2338,23 @@ export class RouterCore<
2336
2338
  validResolvedMatches.forEach(({ id: matchId, routeId }, index) => {
2337
2339
  matchPromises.push(
2338
2340
  (async () => {
2339
- const { loaderPromise: prevLoaderPromise } =
2340
- this.getMatch(matchId)!
2341
-
2342
2341
  let loaderShouldRunAsync = false
2343
2342
  let loaderIsRunningAsync = false
2344
2343
 
2345
- if (prevLoaderPromise) {
2346
- await prevLoaderPromise
2344
+ const prevMatch = this.getMatch(matchId)!
2345
+ // there is a loaderPromise, so we are in the middle of a load
2346
+ if (prevMatch.loaderPromise) {
2347
+ // do not block if we already have stale data we can show
2348
+ // but only if the ongoing load is not a preload since error handling is different for preloads
2349
+ // and we don't want to swallow errors
2350
+ if (
2351
+ prevMatch.status === 'success' &&
2352
+ !sync &&
2353
+ !prevMatch.preload
2354
+ ) {
2355
+ return this.getMatch(matchId)!
2356
+ }
2357
+ await prevMatch.loaderPromise
2347
2358
  const match = this.getMatch(matchId)!
2348
2359
  if (match.error) {
2349
2360
  handleRedirectAndNotFound(match, match.error)
@@ -2631,7 +2642,7 @@ export class RouterCore<
2631
2642
  return {
2632
2643
  ...d,
2633
2644
  invalid: true,
2634
- ...(d.status === 'error'
2645
+ ...(opts?.forcePending || d.status === 'error'
2635
2646
  ? ({ status: 'pending', error: undefined } as const)
2636
2647
  : {}),
2637
2648
  }