@@ -2311,11 +2311,9 @@ export class RouterCore<
2311
2311
const match = this . getMatch ( matchId ) !
2312
2312
if ( shouldPending && match . _nonReactive . pendingTimeout === undefined ) {
2313
2313
const pendingTimeout = setTimeout ( ( ) => {
2314
- try {
2315
- // Update the match and prematurely resolve the loadMatches promise so that
2316
- // the pending component can start rendering
2317
- this . triggerOnReady ( innerLoadContext )
2318
- } catch { }
2314
+ // Update the match and prematurely resolve the loadMatches promise so that
2315
+ // the pending component can start rendering
2316
+ this . triggerOnReady ( innerLoadContext )
2319
2317
} , pendingMs )
2320
2318
match . _nonReactive . pendingTimeout = pendingTimeout
2321
2319
}
@@ -2364,131 +2362,150 @@ export class RouterCore<
2364
2362
index : number ,
2365
2363
route : AnyRoute ,
2366
2364
) : void | Promise < void > => {
2367
- const resolve = ( ) => {
2368
- innerLoadContext . updateMatch ( matchId , ( prev ) => {
2369
- prev . _nonReactive . beforeLoadPromise ?. resolve ( )
2370
- prev . _nonReactive . beforeLoadPromise = undefined
2365
+ const match = this . getMatch ( matchId ) !
2371
2366
2372
- return {
2373
- ... prev ,
2374
- isFetching : false ,
2375
- }
2376
- } )
2377
- }
2367
+ match . _nonReactive . beforeLoadPromise = createControlledPromise < void > ( )
2368
+ // explicitly capture the previous loadPromise
2369
+ const prevLoadPromise = match . _nonReactive . loadPromise
2370
+ match . _nonReactive . loadPromise = createControlledPromise < void > ( ( ) => {
2371
+ prevLoadPromise ?. resolve ( )
2372
+ } )
2378
2373
2379
- try {
2380
- const match = this . getMatch ( matchId ) !
2381
- match . _nonReactive . beforeLoadPromise = createControlledPromise < void > ( )
2382
- // explicitly capture the previous loadPromise
2383
- const prevLoadPromise = match . _nonReactive . loadPromise
2384
- match . _nonReactive . loadPromise = createControlledPromise < void > ( ( ) => {
2385
- prevLoadPromise ?. resolve ( )
2386
- } )
2374
+ const { paramsError, searchError } = match
2387
2375
2388
- const { paramsError, searchError } = this . getMatch ( matchId ) !
2376
+ if ( paramsError ) {
2377
+ this . handleSerialError (
2378
+ innerLoadContext ,
2379
+ index ,
2380
+ paramsError ,
2381
+ 'PARSE_PARAMS' ,
2382
+ )
2383
+ }
2389
2384
2390
- if ( paramsError ) {
2391
- this . handleSerialError (
2392
- innerLoadContext ,
2393
- index ,
2394
- paramsError ,
2395
- 'PARSE_PARAMS ',
2396
- )
2397
- }
2385
+ if ( searchError ) {
2386
+ this . handleSerialError (
2387
+ innerLoadContext ,
2388
+ index ,
2389
+ searchError ,
2390
+ 'VALIDATE_SEARCH ',
2391
+ )
2392
+ }
2398
2393
2399
- if ( searchError ) {
2400
- this . handleSerialError (
2401
- innerLoadContext ,
2402
- index ,
2403
- searchError ,
2404
- 'VALIDATE_SEARCH' ,
2405
- )
2406
- }
2394
+ this . setupPendingTimeout ( innerLoadContext , matchId , route )
2407
2395
2408
- this . setupPendingTimeout ( innerLoadContext , matchId , route )
2396
+ const abortController = new AbortController ( )
2409
2397
2410
- const abortController = new AbortController ( )
2398
+ const parentMatchId = innerLoadContext . matches [ index - 1 ] ?. id
2399
+ const parentMatch = parentMatchId
2400
+ ? this . getMatch ( parentMatchId ) !
2401
+ : undefined
2402
+ const parentMatchContext =
2403
+ parentMatch ?. context ?? this . options . context ?? undefined
2411
2404
2412
- const parentMatchId = innerLoadContext . matches [ index - 1 ] ?. id
2413
- const parentMatch = parentMatchId
2414
- ? this . getMatch ( parentMatchId ) !
2415
- : undefined
2416
- const parentMatchContext =
2417
- parentMatch ?. context ?? this . options . context ?? undefined
2405
+ const context = { ...parentMatchContext , ...match . __routeContext }
2418
2406
2407
+ let isPending = false
2408
+ const pending = ( ) => {
2409
+ if ( isPending ) return
2410
+ isPending = true
2419
2411
innerLoadContext . updateMatch ( matchId , ( prev ) => ( {
2420
2412
...prev ,
2421
2413
isFetching : 'beforeLoad' ,
2422
2414
fetchCount : prev . fetchCount + 1 ,
2423
2415
abortController,
2424
- context : {
2425
- ...parentMatchContext ,
2426
- ...prev . __routeContext ,
2427
- } ,
2416
+ context,
2417
+ } ) )
2418
+ }
2419
+
2420
+ const resolve = ( ) => {
2421
+ match . _nonReactive . beforeLoadPromise ?. resolve ( )
2422
+ match . _nonReactive . beforeLoadPromise = undefined
2423
+ innerLoadContext . updateMatch ( matchId , ( prev ) => ( {
2424
+ ...prev ,
2425
+ isFetching : false ,
2428
2426
} ) )
2427
+ }
2429
2428
2430
- const { search, params, context, cause } = this . getMatch ( matchId ) !
2429
+ // if there is no `beforeLoad` option, skip everything, batch update the store, return early
2430
+ if ( ! route . options . beforeLoad ) {
2431
+ batch ( ( ) => {
2432
+ pending ( )
2433
+ resolve ( )
2434
+ } )
2435
+ return
2436
+ }
2431
2437
2432
- const preload = this . resolvePreload ( innerLoadContext , matchId )
2438
+ const { search, params, cause } = match
2439
+ const preload = this . resolvePreload ( innerLoadContext , matchId )
2440
+ const beforeLoadFnContext : BeforeLoadContextOptions <
2441
+ any ,
2442
+ any ,
2443
+ any ,
2444
+ any ,
2445
+ any
2446
+ > = {
2447
+ search,
2448
+ abortController,
2449
+ params,
2450
+ preload,
2451
+ context,
2452
+ location : innerLoadContext . location ,
2453
+ navigate : ( opts : any ) =>
2454
+ this . navigate ( { ...opts , _fromLocation : innerLoadContext . location } ) ,
2455
+ buildLocation : this . buildLocation ,
2456
+ cause : preload ? 'preload' : cause ,
2457
+ matches : innerLoadContext . matches ,
2458
+ }
2433
2459
2434
- const beforeLoadFnContext : BeforeLoadContextOptions <
2435
- any ,
2436
- any ,
2437
- any ,
2438
- any ,
2439
- any
2440
- > = {
2441
- search,
2442
- abortController,
2443
- params,
2444
- preload,
2445
- context,
2446
- location : innerLoadContext . location ,
2447
- navigate : ( opts : any ) =>
2448
- this . navigate ( { ...opts , _fromLocation : innerLoadContext . location } ) ,
2449
- buildLocation : this . buildLocation ,
2450
- cause : preload ? 'preload' : cause ,
2451
- matches : innerLoadContext . matches ,
2460
+ const updateContext = ( beforeLoadContext : any ) => {
2461
+ if ( beforeLoadContext === undefined ) {
2462
+ batch ( ( ) => {
2463
+ pending ( )
2464
+ resolve ( )
2465
+ } )
2466
+ return
2467
+ }
2468
+ if ( isRedirect ( beforeLoadContext ) || isNotFound ( beforeLoadContext ) ) {
2469
+ pending ( )
2470
+ this . handleSerialError (
2471
+ innerLoadContext ,
2472
+ index ,
2473
+ beforeLoadContext ,
2474
+ 'BEFORE_LOAD' ,
2475
+ )
2452
2476
}
2453
2477
2454
- const updateContext = ( beforeLoadContext : any ) => {
2455
- if ( isRedirect ( beforeLoadContext ) || isNotFound ( beforeLoadContext ) ) {
2456
- this . handleSerialError (
2457
- innerLoadContext ,
2458
- index ,
2459
- beforeLoadContext ,
2460
- 'BEFORE_LOAD' ,
2461
- )
2462
- }
2463
-
2478
+ batch ( ( ) => {
2479
+ pending ( )
2464
2480
innerLoadContext . updateMatch ( matchId , ( prev ) => ( {
2465
2481
...prev ,
2466
2482
__beforeLoadContext : beforeLoadContext ,
2467
2483
context : {
2468
- ...parentMatchContext ,
2469
- ...prev . __routeContext ,
2484
+ ...prev . context ,
2470
2485
...beforeLoadContext ,
2471
2486
} ,
2472
- abortController,
2473
2487
} ) )
2474
- }
2488
+ resolve ( )
2489
+ } )
2490
+ }
2475
2491
2476
- const beforeLoadContext = route . options . beforeLoad ?.( beforeLoadFnContext )
2492
+ let beforeLoadContext
2493
+ try {
2494
+ beforeLoadContext = route . options . beforeLoad ( beforeLoadFnContext )
2477
2495
if ( isPromise ( beforeLoadContext ) ) {
2496
+ pending ( )
2478
2497
return beforeLoadContext
2479
- . then ( updateContext )
2480
2498
. catch ( ( err ) => {
2481
2499
this . handleSerialError ( innerLoadContext , index , err , 'BEFORE_LOAD' )
2482
2500
} )
2483
- . then ( resolve )
2484
- } else {
2485
- updateContext ( beforeLoadContext )
2501
+ . then ( updateContext )
2486
2502
}
2487
2503
} catch ( err ) {
2504
+ pending ( )
2488
2505
this . handleSerialError ( innerLoadContext , index , err , 'BEFORE_LOAD' )
2489
2506
}
2490
2507
2491
- resolve ( )
2508
+ updateContext ( beforeLoadContext )
2492
2509
return
2493
2510
}
2494
2511
@@ -2702,7 +2719,8 @@ export class RouterCore<
2702
2719
} catch ( e ) {
2703
2720
let error = e
2704
2721
2705
- await this . potentialPendingMinPromise ( matchId )
2722
+ const pendingPromise = this . potentialPendingMinPromise ( matchId )
2723
+ if ( pendingPromise ) await pendingPromise
2706
2724
2707
2725
this . handleRedirectAndNotFound (
2708
2726
innerLoadContext ,
0 commit comments