@@ -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 ,
0 commit comments