1
- import { AfterViewInit , Directive , Injectable , Input , OnDestroy , OnInit } from '@angular/core' ;
1
+ import { AfterViewInit , Directive , Injectable , Input , NgModule , OnDestroy , OnInit } from '@angular/core' ;
2
2
import { Event , NavigationEnd , NavigationStart , Router } from '@angular/router' ;
3
3
import { getCurrentHub } from '@sentry/browser' ;
4
4
import { Span , Transaction , TransactionContext } from '@sentry/types' ;
5
5
import { logger , stripUrlQueryAndFragment , timestampWithMs } from '@sentry/utils' ;
6
6
import { Observable , Subscription } from 'rxjs' ;
7
7
import { filter , tap } from 'rxjs/operators' ;
8
8
9
- // That's the `global.Zone` exposed when the `zone.js` package is used.
10
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
- declare const Zone : any ;
12
-
13
- // There're 2 types of Angular applications:
14
- // 1) zone-full (by default)
15
- // 2) zone-less
16
- // The developer can avoid importing the `zone.js` package and tells Angular that
17
- // he is responsible for running the change detection by himself. This is done by
18
- // "nooping" the zone through `CompilerOptions` when bootstrapping the root module.
19
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
20
- const isNgZoneEnabled = typeof Zone !== 'undefined' && ! ! Zone . current ;
9
+ import { runOutsideAngular } from './zone' ;
21
10
22
11
let instrumentationInitialized : boolean ;
23
12
let stashedStartTransaction : ( context : TransactionContext ) => Transaction | undefined ;
@@ -106,21 +95,10 @@ export class TraceService implements OnDestroy {
106
95
filter ( event => event instanceof NavigationEnd ) ,
107
96
tap ( ( ) => {
108
97
if ( this . _routingSpan ) {
109
- if ( isNgZoneEnabled ) {
110
- // The `Zone.root.run` basically will finish the transaction in the most parent zone.
111
- // The Angular's zone is forked from the `Zone.root`. In this case, `zone.js` won't
112
- // trigger change detection, and `ApplicationRef.tick()` will not be run.
113
- // Caretaker note: we're using `Zone.root` except `NgZone.runOutsideAngular` since this
114
- // will require injecting the `NgZone` facade. That will create a breaking change for
115
- // projects already using the `TraceService`.
116
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
117
- Zone . root . run ( ( ) => {
118
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
119
- this . _routingSpan ! . finish ( ) ;
120
- } ) ;
121
- } else {
122
- this . _routingSpan . finish ( ) ;
123
- }
98
+ runOutsideAngular ( ( ) => {
99
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
100
+ this . _routingSpan ! . finish ( ) ;
101
+ } ) ;
124
102
this . _routingSpan = null ;
125
103
}
126
104
} ) ,
@@ -136,7 +114,7 @@ export class TraceService implements OnDestroy {
136
114
137
115
/**
138
116
* This is used to prevent memory leaks when the root view is created and destroyed multiple times,
139
- * since `subscribe` callbacks captures `this` and prevent many resources from being GC'd.
117
+ * since `subscribe` callbacks capture `this` and prevent many resources from being GC'd.
140
118
*/
141
119
public ngOnDestroy ( ) : void {
142
120
this . _subscription . unsubscribe ( ) ;
@@ -179,6 +157,15 @@ export class TraceDirective implements OnInit, AfterViewInit {
179
157
}
180
158
}
181
159
160
+ /**
161
+ * A module serves as a single compilation unit for the `TraceDirective` and can be re-used by any other module.
162
+ */
163
+ @NgModule ( {
164
+ declarations : [ TraceDirective ] ,
165
+ exports : [ TraceDirective ] ,
166
+ } )
167
+ export class TraceModule { }
168
+
182
169
/**
183
170
* Decorator function that can be used to capture initialization lifecycle of the whole component.
184
171
*/
0 commit comments