@@ -2318,11 +2318,9 @@ export class RouterCore<
23182318 const match = this . getMatch ( matchId ) !
23192319 if ( shouldPending && match . _nonReactive . pendingTimeout === undefined ) {
23202320 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 )
23262324 } , pendingMs )
23272325 match . _nonReactive . pendingTimeout = pendingTimeout
23282326 }
@@ -2371,131 +2369,150 @@ export class RouterCore<
23712369 index : number ,
23722370 route : AnyRoute ,
23732371 ) : 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 ) !
23782373
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+ } )
23852380
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
23942382
2395- const { paramsError, searchError } = this . getMatch ( matchId ) !
2383+ if ( paramsError ) {
2384+ this . handleSerialError (
2385+ innerLoadContext ,
2386+ index ,
2387+ paramsError ,
2388+ 'PARSE_PARAMS' ,
2389+ )
2390+ }
23962391
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+ }
24052400
2406- if ( searchError ) {
2407- this . handleSerialError (
2408- innerLoadContext ,
2409- index ,
2410- searchError ,
2411- 'VALIDATE_SEARCH' ,
2412- )
2413- }
2401+ this . setupPendingTimeout ( innerLoadContext , matchId , route )
24142402
2415- this . setupPendingTimeout ( innerLoadContext , matchId , route )
2403+ const abortController = new AbortController ( )
24162404
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
24182411
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 }
24252413
2414+ let isPending = false
2415+ const pending = ( ) => {
2416+ if ( isPending ) return
2417+ isPending = true
24262418 innerLoadContext . updateMatch ( matchId , ( prev ) => ( {
24272419 ...prev ,
24282420 isFetching : 'beforeLoad' ,
24292421 fetchCount : prev . fetchCount + 1 ,
24302422 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 ,
24352433 } ) )
2434+ }
24362435
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+ }
24382444
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+ }
24402466
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+ )
24592483 }
24602484
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 ( )
24712487 innerLoadContext . updateMatch ( matchId , ( prev ) => ( {
24722488 ...prev ,
24732489 __beforeLoadContext : beforeLoadContext ,
24742490 context : {
2475- ...parentMatchContext ,
2476- ...prev . __routeContext ,
2491+ ...prev . context ,
24772492 ...beforeLoadContext ,
24782493 } ,
2479- abortController,
24802494 } ) )
2481- }
2495+ resolve ( )
2496+ } )
2497+ }
24822498
2483- const beforeLoadContext = route . options . beforeLoad ?.( beforeLoadFnContext )
2499+ let beforeLoadContext
2500+ try {
2501+ beforeLoadContext = route . options . beforeLoad ( beforeLoadFnContext )
24842502 if ( isPromise ( beforeLoadContext ) ) {
2503+ pending ( )
24852504 return beforeLoadContext
2486- . then ( updateContext )
24872505 . catch ( ( err ) => {
24882506 this . handleSerialError ( innerLoadContext , index , err , 'BEFORE_LOAD' )
24892507 } )
2490- . then ( resolve )
2491- } else {
2492- updateContext ( beforeLoadContext )
2508+ . then ( updateContext )
24932509 }
24942510 } catch ( err ) {
2511+ pending ( )
24952512 this . handleSerialError ( innerLoadContext , index , err , 'BEFORE_LOAD' )
24962513 }
24972514
2498- resolve ( )
2515+ updateContext ( beforeLoadContext )
24992516 return
25002517 }
25012518
@@ -2709,7 +2726,8 @@ export class RouterCore<
27092726 } catch ( e ) {
27102727 let error = e
27112728
2712- await this . potentialPendingMinPromise ( matchId )
2729+ const pendingPromise = this . potentialPendingMinPromise ( matchId )
2730+ if ( pendingPromise ) await pendingPromise
27132731
27142732 this . handleRedirectAndNotFound (
27152733 innerLoadContext ,
0 commit comments