@@ -10,6 +10,7 @@ import {
10
10
} from '@sentry/browser' ;
11
11
import type { Client , Integration , Span , TransactionSource } from '@sentry/core' ;
12
12
import {
13
+ addNonEnumerableProperty ,
13
14
debug ,
14
15
getActiveSpan ,
15
16
getClient ,
@@ -63,6 +64,15 @@ type V6CompatibleVersion = '6' | '7';
63
64
// Keeping as a global variable for cross-usage in multiple functions
64
65
const allRoutes = new Set < RouteObject > ( ) ;
65
66
67
+ /**
68
+ * Adds resolved routes as children to the parent route.
69
+ */
70
+ function addResolvedRoutesToParent ( resolvedRoutes : RouteObject [ ] , parentRoute : RouteObject ) : void {
71
+ parentRoute . children = Array . isArray ( parentRoute . children )
72
+ ? [ ...parentRoute . children , ...resolvedRoutes ]
73
+ : resolvedRoutes ;
74
+ }
75
+
66
76
/**
67
77
* Handles the result of an async handler function call.
68
78
*/
@@ -76,25 +86,47 @@ function handleAsyncHandlerResult(result: unknown, route: RouteObject, handlerKe
76
86
( result as Promise < unknown > )
77
87
. then ( ( resolvedRoutes : unknown ) => {
78
88
if ( Array . isArray ( resolvedRoutes ) ) {
79
- processResolvedRoutes ( resolvedRoutes ) ;
89
+ processResolvedRoutes ( resolvedRoutes , route ) ;
80
90
}
81
91
} )
82
92
. catch ( ( e : unknown ) => {
83
93
DEBUG_BUILD && debug . warn ( `Error resolving async handler '${ handlerKey } ' for route` , route , e ) ;
84
94
} ) ;
85
95
} else if ( Array . isArray ( result ) ) {
86
- processResolvedRoutes ( result ) ;
96
+ processResolvedRoutes ( result , route ) ;
87
97
}
88
98
}
89
99
90
100
/**
91
101
* Processes resolved routes by adding them to allRoutes and checking for nested async handlers.
92
102
*/
93
- function processResolvedRoutes ( resolvedRoutes : RouteObject [ ] ) : void {
103
+ function processResolvedRoutes ( resolvedRoutes : RouteObject [ ] , parentRoute ?: RouteObject ) : void {
94
104
resolvedRoutes . forEach ( child => {
95
105
allRoutes . add ( child ) ;
96
106
checkRouteForAsyncHandler ( child ) ;
97
107
} ) ;
108
+
109
+ if ( parentRoute ) {
110
+ // If a parent route is provided, add the resolved routes as children to the parent route
111
+ addResolvedRoutesToParent ( resolvedRoutes , parentRoute ) ;
112
+ }
113
+
114
+ // After processing lazy routes, check if we need to update an active pageload transaction
115
+ const activeRootSpan = getActiveRootSpan ( ) ;
116
+ if ( activeRootSpan && spanToJSON ( activeRootSpan ) . op === 'pageload' ) {
117
+ const location = WINDOW . location ;
118
+ if ( location ) {
119
+ // Re-run the pageload transaction update with the newly loaded routes
120
+ updatePageloadTransaction (
121
+ activeRootSpan ,
122
+ { pathname : location . pathname } ,
123
+ Array . from ( allRoutes ) ,
124
+ undefined ,
125
+ undefined ,
126
+ Array . from ( allRoutes ) ,
127
+ ) ;
128
+ }
129
+ }
98
130
}
99
131
100
132
/**
@@ -105,13 +137,17 @@ function createAsyncHandlerProxy(
105
137
route : RouteObject ,
106
138
handlerKey : string ,
107
139
) : ( ...args : unknown [ ] ) => unknown {
108
- return new Proxy ( originalFunction , {
140
+ const proxy = new Proxy ( originalFunction , {
109
141
apply ( target : ( ...args : unknown [ ] ) => unknown , thisArg , argArray ) {
110
142
const result = target . apply ( thisArg , argArray ) ;
111
143
handleAsyncHandlerResult ( result , route , handlerKey ) ;
112
144
return result ;
113
145
} ,
114
146
} ) ;
147
+
148
+ addNonEnumerableProperty ( proxy , '__sentry_proxied__' , true ) ;
149
+
150
+ return proxy ;
115
151
}
116
152
117
153
/**
@@ -122,7 +158,7 @@ export function checkRouteForAsyncHandler(route: RouteObject): void {
122
158
if ( route . handle && typeof route . handle === 'object' ) {
123
159
for ( const key of Object . keys ( route . handle ) ) {
124
160
const maybeFn = route . handle [ key ] ;
125
- if ( typeof maybeFn === 'function' ) {
161
+ if ( typeof maybeFn === 'function' && ! ( maybeFn as { __sentry_proxied__ ?: boolean } ) . __sentry_proxied__ ) {
126
162
route . handle [ key ] = createAsyncHandlerProxy ( maybeFn , route , key ) ;
127
163
}
128
164
}
@@ -620,6 +656,7 @@ function getNormalizedName(
620
656
}
621
657
622
658
let pathBuilder = '' ;
659
+
623
660
if ( branches ) {
624
661
for ( const branch of branches ) {
625
662
const route = branch . route ;
0 commit comments