@@ -3,19 +3,14 @@ import { Integration, IntegrationClass } from '@sentry/types';
3
3
import { logger } from '@sentry/utils' ;
4
4
import * as React from 'react' ;
5
5
6
- /** The Props Injected by the HOC */
7
- interface InjectedProps {
8
- /** Called when a transaction is finished */
9
- finishProfile ( ) : void ;
10
- }
11
-
12
- const DEFAULT_DURATION = 30000 ;
6
+ export const DEFAULT_DURATION = 30000 ;
7
+ export const UNKNOWN_COMPONENT = 'unknown' ;
13
8
14
9
const TRACING_GETTER = ( {
15
10
id : 'Tracing' ,
16
11
} as any ) as IntegrationClass < Integration > ;
17
12
18
- const getInitActivity = ( componentDisplayName : string , timeout = DEFAULT_DURATION ) : number | null => {
13
+ const getInitActivity = ( componentDisplayName : string , timeout : number ) : number | null => {
19
14
const tracingIntegration = getCurrentHub ( ) . getIntegration ( TRACING_GETTER ) ;
20
15
21
16
if ( tracingIntegration !== null ) {
@@ -37,45 +32,63 @@ const getInitActivity = (componentDisplayName: string, timeout = DEFAULT_DURATIO
37
32
return null ;
38
33
} ;
39
34
40
- /**
41
- * withProfiler() is a HOC that leverages the Sentry AM tracing integration to
42
- * send transactions about a React component.
43
- * @param WrappedComponent The component profiled
44
- * @param timeout A maximum timeout for the component render
45
- */
46
- export const withProfiler = < P extends object > ( WrappedComponent : React . ComponentType < P > , timeout ?: number ) => {
47
- const componentDisplayName = WrappedComponent . displayName || WrappedComponent . name || 'Component' ;
35
+ interface ProfilerProps {
36
+ componentDisplayName ?: string ;
37
+ timeout ?: number ;
38
+ }
48
39
49
- return class extends React . Component < Omit < P , keyof InjectedProps > , { activity : number | null } > {
50
- public static displayName : string = `profiler(${ componentDisplayName } )` ;
40
+ interface ProfilerState {
41
+ activity : number | null ;
42
+ }
51
43
52
- public constructor ( props : P ) {
53
- super ( props ) ;
44
+ class Profiler extends React . Component < ProfilerProps , ProfilerState > {
45
+ public constructor ( props : ProfilerProps ) {
46
+ super ( props ) ;
54
47
55
- this . state = {
56
- activity : getInitActivity ( componentDisplayName , timeout ) ,
57
- } ;
58
- }
48
+ const { componentDisplayName = UNKNOWN_COMPONENT , timeout = DEFAULT_DURATION } = this . props ;
59
49
60
- public componentWillUnmount ( ) : void {
61
- this . finishProfile ( ) ;
62
- }
63
-
64
- public finishProfile = ( ) => {
65
- if ( ! this . state . activity ) {
66
- return ;
67
- }
68
-
69
- const tracingIntegration = getCurrentHub ( ) . getIntegration ( TRACING_GETTER ) ;
70
- if ( tracingIntegration !== null ) {
71
- // tslint:disable-next-line:no-unsafe-any
72
- ( tracingIntegration as any ) . constructor . popActivity ( this . state . activity ) ;
73
- this . setState ( { activity : null } ) ;
74
- }
50
+ this . state = {
51
+ activity : getInitActivity ( componentDisplayName , timeout ) ,
75
52
} ;
53
+ }
54
+
55
+ public componentWillUnmount ( ) : void {
56
+ this . finishProfile ( ) ;
57
+ }
58
+
59
+ public finishProfile = ( ) => {
60
+ if ( ! this . state . activity ) {
61
+ return ;
62
+ }
76
63
77
- public render ( ) : React . ReactNode {
78
- return < WrappedComponent { ...this . props as P } /> ;
64
+ const tracingIntegration = getCurrentHub ( ) . getIntegration ( TRACING_GETTER ) ;
65
+ if ( tracingIntegration !== null ) {
66
+ // tslint:disable-next-line:no-unsafe-any
67
+ ( tracingIntegration as any ) . constructor . popActivity ( this . state . activity ) ;
68
+ this . setState ( { activity : null } ) ;
79
69
}
80
70
} ;
81
- } ;
71
+
72
+ public render ( ) : React . ReactNode {
73
+ return this . props . children ;
74
+ }
75
+ }
76
+
77
+ function withProfiler < P extends object > (
78
+ WrappedComponent : React . ComponentType < P > ,
79
+ profilerProps ?: ProfilerProps ,
80
+ ) : React . FC < P > {
81
+ const componentDisplayName = WrappedComponent . displayName || WrappedComponent . name || UNKNOWN_COMPONENT ;
82
+
83
+ const Wrapped : React . FC < P > = ( props : P ) => (
84
+ < Profiler componentDisplayName = { componentDisplayName } { ...profilerProps } >
85
+ < WrappedComponent { ...props } />
86
+ </ Profiler >
87
+ ) ;
88
+
89
+ Wrapped . displayName = `profiler(${ componentDisplayName } )` ;
90
+
91
+ return Wrapped ;
92
+ }
93
+
94
+ export { withProfiler , Profiler } ;
0 commit comments