@tanstack/router-core 1.131.16 → 1.131.17

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.16",
3
+ "version": "1.131.17",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
package/src/router.ts CHANGED
@@ -2318,11 +2318,9 @@ export class RouterCore<
2318
2318
  const match = this.getMatch(matchId)!
2319
2319
  if (shouldPending && match._nonReactive.pendingTimeout === undefined) {
2320
2320
  const pendingTimeout = setTimeout(() => {
2321
- try {
2322
- // Update the match and prematurely resolve the loadMatches promise so that
2323
- // the pending component can start rendering
2324
- this.triggerOnReady(innerLoadContext)
2325
- } catch {}
2321
+ // Update the match and prematurely resolve the loadMatches promise so that
2322
+ // the pending component can start rendering
2323
+ this.triggerOnReady(innerLoadContext)
2326
2324
  }, pendingMs)
2327
2325
  match._nonReactive.pendingTimeout = pendingTimeout
2328
2326
  }
@@ -2371,131 +2369,150 @@ export class RouterCore<
2371
2369
  index: number,
2372
2370
  route: AnyRoute,
2373
2371
  ): void | Promise<void> => {
2374
- const resolve = () => {
2375
- innerLoadContext.updateMatch(matchId, (prev) => {
2376
- prev._nonReactive.beforeLoadPromise?.resolve()
2377
- prev._nonReactive.beforeLoadPromise = undefined
2372
+ const match = this.getMatch(matchId)!
2378
2373
 
2379
- return {
2380
- ...prev,
2381
- isFetching: false,
2382
- }
2383
- })
2384
- }
2374
+ match._nonReactive.beforeLoadPromise = createControlledPromise<void>()
2375
+ // explicitly capture the previous loadPromise
2376
+ const prevLoadPromise = match._nonReactive.loadPromise
2377
+ match._nonReactive.loadPromise = createControlledPromise<void>(() => {
2378
+ prevLoadPromise?.resolve()
2379
+ })
2385
2380
 
2386
- try {
2387
- const match = this.getMatch(matchId)!
2388
- match._nonReactive.beforeLoadPromise = createControlledPromise<void>()
2389
- // explicitly capture the previous loadPromise
2390
- const prevLoadPromise = match._nonReactive.loadPromise
2391
- match._nonReactive.loadPromise = createControlledPromise<void>(() => {
2392
- prevLoadPromise?.resolve()
2393
- })
2381
+ const { paramsError, searchError } = match
2394
2382
 
2395
- const { paramsError, searchError } = this.getMatch(matchId)!
2383
+ if (paramsError) {
2384
+ this.handleSerialError(
2385
+ innerLoadContext,
2386
+ index,
2387
+ paramsError,
2388
+ 'PARSE_PARAMS',
2389
+ )
2390
+ }
2396
2391
 
2397
- if (paramsError) {
2398
- this.handleSerialError(
2399
- innerLoadContext,
2400
- index,
2401
- paramsError,
2402
- 'PARSE_PARAMS',
2403
- )
2404
- }
2392
+ if (searchError) {
2393
+ this.handleSerialError(
2394
+ innerLoadContext,
2395
+ index,
2396
+ searchError,
2397
+ 'VALIDATE_SEARCH',
2398
+ )
2399
+ }
2405
2400
 
2406
- if (searchError) {
2407
- this.handleSerialError(
2408
- innerLoadContext,
2409
- index,
2410
- searchError,
2411
- 'VALIDATE_SEARCH',
2412
- )
2413
- }
2401
+ this.setupPendingTimeout(innerLoadContext, matchId, route)
2414
2402
 
2415
- this.setupPendingTimeout(innerLoadContext, matchId, route)
2403
+ const abortController = new AbortController()
2416
2404
 
2417
- const abortController = new AbortController()
2405
+ const parentMatchId = innerLoadContext.matches[index - 1]?.id
2406
+ const parentMatch = parentMatchId
2407
+ ? this.getMatch(parentMatchId)!
2408
+ : undefined
2409
+ const parentMatchContext =
2410
+ parentMatch?.context ?? this.options.context ?? undefined
2418
2411
 
2419
- const parentMatchId = innerLoadContext.matches[index - 1]?.id
2420
- const parentMatch = parentMatchId
2421
- ? this.getMatch(parentMatchId)!
2422
- : undefined
2423
- const parentMatchContext =
2424
- parentMatch?.context ?? this.options.context ?? undefined
2412
+ const context = { ...parentMatchContext, ...match.__routeContext }
2425
2413
 
2414
+ let isPending = false
2415
+ const pending = () => {
2416
+ if (isPending) return
2417
+ isPending = true
2426
2418
  innerLoadContext.updateMatch(matchId, (prev) => ({
2427
2419
  ...prev,
2428
2420
  isFetching: 'beforeLoad',
2429
2421
  fetchCount: prev.fetchCount + 1,
2430
2422
  abortController,
2431
- context: {
2432
- ...parentMatchContext,
2433
- ...prev.__routeContext,
2434
- },
2423
+ context,
2424
+ }))
2425
+ }
2426
+
2427
+ const resolve = () => {
2428
+ match._nonReactive.beforeLoadPromise?.resolve()
2429
+ match._nonReactive.beforeLoadPromise = undefined
2430
+ innerLoadContext.updateMatch(matchId, (prev) => ({
2431
+ ...prev,
2432
+ isFetching: false,
2435
2433
  }))
2434
+ }
2436
2435
 
2437
- const { search, params, context, cause } = this.getMatch(matchId)!
2436
+ // if there is no `beforeLoad` option, skip everything, batch update the store, return early
2437
+ if (!route.options.beforeLoad) {
2438
+ batch(() => {
2439
+ pending()
2440
+ resolve()
2441
+ })
2442
+ return
2443
+ }
2438
2444
 
2439
- const preload = this.resolvePreload(innerLoadContext, matchId)
2445
+ const { search, params, cause } = match
2446
+ const preload = this.resolvePreload(innerLoadContext, matchId)
2447
+ const beforeLoadFnContext: BeforeLoadContextOptions<
2448
+ any,
2449
+ any,
2450
+ any,
2451
+ any,
2452
+ any
2453
+ > = {
2454
+ search,
2455
+ abortController,
2456
+ params,
2457
+ preload,
2458
+ context,
2459
+ location: innerLoadContext.location,
2460
+ navigate: (opts: any) =>
2461
+ this.navigate({ ...opts, _fromLocation: innerLoadContext.location }),
2462
+ buildLocation: this.buildLocation,
2463
+ cause: preload ? 'preload' : cause,
2464
+ matches: innerLoadContext.matches,
2465
+ }
2440
2466
 
2441
- const beforeLoadFnContext: BeforeLoadContextOptions<
2442
- any,
2443
- any,
2444
- any,
2445
- any,
2446
- any
2447
- > = {
2448
- search,
2449
- abortController,
2450
- params,
2451
- preload,
2452
- context,
2453
- location: innerLoadContext.location,
2454
- navigate: (opts: any) =>
2455
- this.navigate({ ...opts, _fromLocation: innerLoadContext.location }),
2456
- buildLocation: this.buildLocation,
2457
- cause: preload ? 'preload' : cause,
2458
- matches: innerLoadContext.matches,
2467
+ const updateContext = (beforeLoadContext: any) => {
2468
+ if (beforeLoadContext === undefined) {
2469
+ batch(() => {
2470
+ pending()
2471
+ resolve()
2472
+ })
2473
+ return
2474
+ }
2475
+ if (isRedirect(beforeLoadContext) || isNotFound(beforeLoadContext)) {
2476
+ pending()
2477
+ this.handleSerialError(
2478
+ innerLoadContext,
2479
+ index,
2480
+ beforeLoadContext,
2481
+ 'BEFORE_LOAD',
2482
+ )
2459
2483
  }
2460
2484
 
2461
- const updateContext = (beforeLoadContext: any) => {
2462
- if (isRedirect(beforeLoadContext) || isNotFound(beforeLoadContext)) {
2463
- this.handleSerialError(
2464
- innerLoadContext,
2465
- index,
2466
- beforeLoadContext,
2467
- 'BEFORE_LOAD',
2468
- )
2469
- }
2470
-
2485
+ batch(() => {
2486
+ pending()
2471
2487
  innerLoadContext.updateMatch(matchId, (prev) => ({
2472
2488
  ...prev,
2473
2489
  __beforeLoadContext: beforeLoadContext,
2474
2490
  context: {
2475
- ...parentMatchContext,
2476
- ...prev.__routeContext,
2491
+ ...prev.context,
2477
2492
  ...beforeLoadContext,
2478
2493
  },
2479
- abortController,
2480
2494
  }))
2481
- }
2495
+ resolve()
2496
+ })
2497
+ }
2482
2498
 
2483
- const beforeLoadContext = route.options.beforeLoad?.(beforeLoadFnContext)
2499
+ let beforeLoadContext
2500
+ try {
2501
+ beforeLoadContext = route.options.beforeLoad(beforeLoadFnContext)
2484
2502
  if (isPromise(beforeLoadContext)) {
2503
+ pending()
2485
2504
  return beforeLoadContext
2486
- .then(updateContext)
2487
2505
  .catch((err) => {
2488
2506
  this.handleSerialError(innerLoadContext, index, err, 'BEFORE_LOAD')
2489
2507
  })
2490
- .then(resolve)
2491
- } else {
2492
- updateContext(beforeLoadContext)
2508
+ .then(updateContext)
2493
2509
  }
2494
2510
  } catch (err) {
2511
+ pending()
2495
2512
  this.handleSerialError(innerLoadContext, index, err, 'BEFORE_LOAD')
2496
2513
  }
2497
2514
 
2498
- resolve()
2515
+ updateContext(beforeLoadContext)
2499
2516
  return
2500
2517
  }
2501
2518
 
@@ -2709,7 +2726,8 @@ export class RouterCore<
2709
2726
  } catch (e) {
2710
2727
  let error = e
2711
2728
 
2712
- await this.potentialPendingMinPromise(matchId)
2729
+ const pendingPromise = this.potentialPendingMinPromise(matchId)
2730
+ if (pendingPromise) await pendingPromise
2713
2731
 
2714
2732
  this.handleRedirectAndNotFound(
2715
2733
  innerLoadContext,