@truewatchtech/react-native-mobile 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FTMobileReactNativeSDK.podspec +7 -5
- package/android/build.gradle +10 -3
- package/android/src/main/java/com/ft/sdk/reactnative/FTLogImpl.java +10 -2
- package/android/src/main/java/com/ft/sdk/reactnative/FTMobileImpl.java +45 -10
- package/android/src/main/java/com/ft/sdk/reactnative/FTRUMImpl.java +131 -6
- package/android/src/main/java/com/ft/sdk/reactnative/FTTraceImpl.java +10 -3
- package/android/src/main/java/com/ft/sdk/reactnative/JsLongTaskMonitor.java +281 -0
- package/android/src/main/java/com/ft/sdk/reactnative/ViewTiming.java +17 -0
- package/android/src/main/java/com/ft/sdk/reactnative/VisitorIdConfigMapper.java +50 -0
- package/android/src/main/java/com/ft/sdk/reactnative/utils/ReactNativeUtils.java +5 -12
- package/android/src/newarch/java/com/ft/sdk/reactnative/FTMobileModule.java +14 -5
- package/android/src/newarch/java/com/ft/sdk/reactnative/FTRUMModule.java +44 -1
- package/android/src/newarch/java/com/ft/sdk/reactnative/FTTraceModule.java +14 -0
- package/android/src/oldarch/java/com/ft/sdk/reactnative/FTMobileModule.java +7 -2
- package/android/src/oldarch/java/com/ft/sdk/reactnative/FTRUMModule.java +39 -1
- package/android/src/oldarch/java/com/ft/sdk/reactnative/FTTraceModule.java +12 -0
- package/android/src/rnpost70/java/com/ft/sdk/reactnative/ReactJsThreadExecutor.java +21 -0
- package/android/src/rnpre70/java/com/ft/sdk/reactnative/ReactJsThreadExecutor.java +37 -0
- package/android/src/test/java/com/ft/sdk/reactnative/FTMobileImplTest.java +53 -0
- package/android/src/test/java/com/ft/sdk/reactnative/FTRUMModuleTest.java +117 -0
- package/android/src/test/java/com/ft/sdk/reactnative/JsLongTaskMonitorTest.java +446 -0
- package/android/src/test/java/com/ft/sdk/reactnative/utils/ReactNativeUtilsTest.java +33 -0
- package/ios/FTJSLongTaskMonitor.h +51 -0
- package/ios/FTJSLongTaskMonitor.m +250 -0
- package/ios/FTMobileReactNative.mm +54 -18
- package/ios/FTReactNativeLog.mm +9 -5
- package/ios/FTReactNativeRUM.mm +196 -31
- package/ios/FTReactNativeResource.h +4 -0
- package/ios/FTReactNativeResource.m +64 -0
- package/ios/FTReactNativeTrace.mm +59 -14
- package/ios/FTReactNativeUtils.m +10 -15
- package/ios/FTReactNativeViewTiming.h +18 -0
- package/ios/FTReactNativeWebSocket.h +10 -0
- package/ios/FTReactNativeWebSocket.mm +201 -0
- package/ios/FTWebSocketMetadataStore.h +25 -0
- package/ios/FTWebSocketMetadataStore.m +622 -0
- package/ios/FTWebSocketResourceData.h +20 -0
- package/ios/FTWebSocketResourceData.m +106 -0
- package/lib/commonjs/ft_logger.js +3 -1
- package/lib/commonjs/ft_logger.js.map +1 -1
- package/lib/commonjs/ft_mobile_agent.js +47 -4
- package/lib/commonjs/ft_mobile_agent.js.map +1 -1
- package/lib/commonjs/ft_rum.js +65 -5
- package/lib/commonjs/ft_rum.js.map +1 -1
- package/lib/commonjs/ft_tracing.js +14 -4
- package/lib/commonjs/ft_tracing.js.map +1 -1
- package/lib/commonjs/index.js +21 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/rum/FTBabelInteractionTracking.js +72 -0
- package/lib/commonjs/rum/FTBabelInteractionTracking.js.map +1 -0
- package/lib/commonjs/rum/FTBabelUtils.js +87 -0
- package/lib/commonjs/rum/FTBabelUtils.js.map +1 -0
- package/lib/commonjs/rum/FTRumActionTracking.js +10 -39
- package/lib/commonjs/rum/FTRumActionTracking.js.map +1 -1
- package/lib/commonjs/rum/FTRumActionTrackingContext.js +50 -0
- package/lib/commonjs/rum/FTRumActionTrackingContext.js.map +1 -0
- package/lib/commonjs/rum/FTRumViewTracking.js +147 -0
- package/lib/commonjs/rum/FTRumViewTracking.js.map +1 -0
- package/lib/commonjs/rum/FTRumWebSocketNative.js +73 -0
- package/lib/commonjs/rum/FTRumWebSocketNative.js.map +1 -0
- package/lib/commonjs/rum/FTRumWebSocketTiming.js +73 -0
- package/lib/commonjs/rum/FTRumWebSocketTiming.js.map +1 -0
- package/lib/commonjs/rum/FTRumWebSocketTracking.js +506 -0
- package/lib/commonjs/rum/FTRumWebSocketTracking.js.map +1 -0
- package/lib/commonjs/rum/longTasksUtils.js +25 -0
- package/lib/commonjs/rum/longTasksUtils.js.map +1 -0
- package/lib/commonjs/specs/NativeFTMobileReactNative.js.map +1 -1
- package/lib/commonjs/specs/NativeFTReactNativeRUM.js.map +1 -1
- package/lib/commonjs/specs/NativeFTReactNativeTrace.js.map +1 -1
- package/lib/commonjs/specs/NativeFTReactNativeWebSocket.js +11 -0
- package/lib/commonjs/specs/NativeFTReactNativeWebSocket.js.map +1 -0
- package/lib/commonjs/version.js +1 -1
- package/lib/commonjs/version.js.map +1 -1
- package/lib/commonjs/visitorIdConfig.js +37 -0
- package/lib/commonjs/visitorIdConfig.js.map +1 -0
- package/lib/module/ft_logger.js +3 -1
- package/lib/module/ft_logger.js.map +1 -1
- package/lib/module/ft_mobile_agent.js +47 -4
- package/lib/module/ft_mobile_agent.js.map +1 -1
- package/lib/module/ft_rum.js +65 -5
- package/lib/module/ft_rum.js.map +1 -1
- package/lib/module/ft_tracing.js +14 -2
- package/lib/module/ft_tracing.js.map +1 -1
- package/lib/module/index.js +4 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/rum/FTBabelInteractionTracking.js +66 -0
- package/lib/module/rum/FTBabelInteractionTracking.js.map +1 -0
- package/lib/module/rum/FTBabelUtils.js +80 -0
- package/lib/module/rum/FTBabelUtils.js.map +1 -0
- package/lib/module/rum/FTRumActionTracking.js +10 -39
- package/lib/module/rum/FTRumActionTracking.js.map +1 -1
- package/lib/module/rum/FTRumActionTrackingContext.js +43 -0
- package/lib/module/rum/FTRumActionTrackingContext.js.map +1 -0
- package/lib/module/rum/FTRumViewTracking.js +140 -0
- package/lib/module/rum/FTRumViewTracking.js.map +1 -0
- package/lib/module/rum/FTRumWebSocketNative.js +62 -0
- package/lib/module/rum/FTRumWebSocketNative.js.map +1 -0
- package/lib/module/rum/FTRumWebSocketTiming.js +67 -0
- package/lib/module/rum/FTRumWebSocketTiming.js.map +1 -0
- package/lib/module/rum/FTRumWebSocketTracking.js +499 -0
- package/lib/module/rum/FTRumWebSocketTracking.js.map +1 -0
- package/lib/module/rum/longTasksUtils.js +18 -0
- package/lib/module/rum/longTasksUtils.js.map +1 -0
- package/lib/module/specs/NativeFTMobileReactNative.js.map +1 -1
- package/lib/module/specs/NativeFTReactNativeRUM.js.map +1 -1
- package/lib/module/specs/NativeFTReactNativeTrace.js.map +1 -1
- package/lib/module/specs/NativeFTReactNativeWebSocket.js +8 -0
- package/lib/module/specs/NativeFTReactNativeWebSocket.js.map +1 -0
- package/lib/module/version.js +1 -1
- package/lib/module/version.js.map +1 -1
- package/lib/module/visitorIdConfig.js +31 -0
- package/lib/module/visitorIdConfig.js.map +1 -0
- package/lib/typescript/ft_logger.d.ts +11 -1
- package/lib/typescript/ft_mobile_agent.d.ts +28 -0
- package/lib/typescript/ft_rum.d.ts +42 -5
- package/lib/typescript/ft_tracing.d.ts +9 -1
- package/lib/typescript/index.d.ts +5 -1
- package/lib/typescript/rum/FTBabelInteractionTracking.d.ts +30 -0
- package/lib/typescript/rum/FTBabelUtils.d.ts +1 -0
- package/lib/typescript/rum/FTRumActionTracking.d.ts +0 -2
- package/lib/typescript/rum/FTRumActionTrackingContext.d.ts +11 -0
- package/lib/typescript/rum/FTRumViewTracking.d.ts +32 -0
- package/lib/typescript/rum/FTRumWebSocketNative.d.ts +22 -0
- package/lib/typescript/rum/FTRumWebSocketTiming.d.ts +7 -0
- package/lib/typescript/rum/FTRumWebSocketTracking.d.ts +54 -0
- package/lib/typescript/rum/longTasksUtils.d.ts +8 -0
- package/lib/typescript/specs/NativeFTMobileReactNative.d.ts +15 -0
- package/lib/typescript/specs/NativeFTReactNativeRUM.d.ts +11 -1
- package/lib/typescript/specs/NativeFTReactNativeTrace.d.ts +12 -0
- package/lib/typescript/specs/NativeFTReactNativeWebSocket.d.ts +13 -0
- package/lib/typescript/version.d.ts +1 -1
- package/lib/typescript/visitorIdConfig.d.ts +11 -0
- package/package.json +6 -4
- package/src/ft_logger.tsx +11 -1
- package/src/ft_mobile_agent.tsx +79 -7
- package/src/ft_rum.tsx +111 -7
- package/src/ft_tracing.tsx +24 -2
- package/src/index.tsx +8 -0
- package/src/rum/FTBabelInteractionTracking.ts +124 -0
- package/src/rum/FTBabelUtils.tsx +99 -0
- package/src/rum/FTRumActionTracking.tsx +14 -43
- package/src/rum/FTRumActionTrackingContext.ts +68 -0
- package/src/rum/FTRumViewTracking.ts +179 -0
- package/src/rum/FTRumWebSocketNative.ts +107 -0
- package/src/rum/FTRumWebSocketTiming.ts +82 -0
- package/src/rum/FTRumWebSocketTracking.ts +722 -0
- package/src/rum/longTasksUtils.ts +17 -0
- package/src/specs/NativeFTMobileReactNative.ts +18 -0
- package/src/specs/NativeFTReactNativeRUM.ts +19 -1
- package/src/specs/NativeFTReactNativeTrace.ts +12 -0
- package/src/specs/NativeFTReactNativeWebSocket.ts +33 -0
- package/src/version.ts +1 -1
- package/src/visitorIdConfig.ts +123 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TurboModule } from 'react-native';
|
|
2
|
+
/** Internal iOS handshake reporting bridge; absent on Android and older binaries. */
|
|
3
|
+
export interface Spec extends TurboModule {
|
|
4
|
+
startCapture(session: string): Promise<void>;
|
|
5
|
+
stopCapture(session: string): Promise<void>;
|
|
6
|
+
clear(): Promise<void>;
|
|
7
|
+
startResource(key: string, socketID: number, url: string, session: string, sequence: number, property: Object): Promise<void>;
|
|
8
|
+
stopResource(key: string, event: string, session: string, property: Object): Promise<void>;
|
|
9
|
+
addResource(key: string, content: Object, metrics: Object, session: string): Promise<void>;
|
|
10
|
+
releaseResource(key: string, session: string): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
declare const _default: Spec | null;
|
|
13
|
+
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "0.4.
|
|
1
|
+
export declare const version = "0.4.3";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Anonymous Visitor ID header configuration for HTTP(S), excluding WebSockets. */
|
|
2
|
+
export interface FTVisitorIdConfig {
|
|
3
|
+
header: string;
|
|
4
|
+
/** Fixed lifetime in hours; defaults to 24. Access does not renew it. */
|
|
5
|
+
ttlHours?: number;
|
|
6
|
+
/** Complete HTTP(S) prefixes constrained to the same scheme, host and port. */
|
|
7
|
+
urlPrefixes?: string[];
|
|
8
|
+
/** Native regular expressions searched against the complete URL; rules use OR. */
|
|
9
|
+
regularExpressions?: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare function validateVisitorIdConfig(config: FTVisitorIdConfig): void;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truewatchtech/react-native-mobile",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "Base on
|
|
3
|
+
"version": "0.4.3",
|
|
4
|
+
"description": "Base on TrueWatch Android iOS React Native SDK",
|
|
5
5
|
"main": "lib/commonjs/index",
|
|
6
6
|
"module": "lib/module/index",
|
|
7
7
|
"types": "lib/typescript/index.d.ts",
|
|
@@ -78,7 +78,8 @@
|
|
|
78
78
|
[
|
|
79
79
|
"typescript",
|
|
80
80
|
{
|
|
81
|
-
"tsc": "../../node_modules/.bin/tsc"
|
|
81
|
+
"tsc": "../../node_modules/.bin/tsc",
|
|
82
|
+
"project": "tsconfig.build.json"
|
|
82
83
|
}
|
|
83
84
|
]
|
|
84
85
|
]
|
|
@@ -96,5 +97,6 @@
|
|
|
96
97
|
},
|
|
97
98
|
"directories": {
|
|
98
99
|
"lib": "lib"
|
|
99
|
-
}
|
|
100
|
+
},
|
|
101
|
+
"gitHead": "61ed39427761a210cbfe6b339e71296f952f9697"
|
|
100
102
|
}
|
package/src/ft_logger.tsx
CHANGED
|
@@ -18,8 +18,10 @@ export enum FTLogCacheDiscard {
|
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* Configure log output configuration.
|
|
21
|
-
* @param
|
|
21
|
+
* @param logSamplingRate Log sampling percentage in [0, 100], default 100. Supports fractional percentages and takes precedence over sampleRate.
|
|
22
|
+
* @param sampleRate Deprecated log sampling probability in [0, 1], default 1. Used only when logSamplingRate is omitted; multiplied by 100 before passing to Native.
|
|
22
23
|
* @param enableLinkRumData whether to link with RUM
|
|
24
|
+
* @param enableWebViewLog Collect Browser Logs SDK events from WebViews, default false
|
|
23
25
|
* @param enableCustomLog whether to enable custom logs
|
|
24
26
|
* @param discardStrategy log discard strategy
|
|
25
27
|
* @param logLevelFilters log level filter
|
|
@@ -27,9 +29,17 @@ export enum FTLogCacheDiscard {
|
|
|
27
29
|
* @param logCacheLimitCount get maximum log entry count limit [1000,), default 5000
|
|
28
30
|
*/
|
|
29
31
|
export interface FTLogConfig {
|
|
32
|
+
/**
|
|
33
|
+
* Log sampling percentage in [0, 100], default 100.
|
|
34
|
+
* Supports fractional percentages: 12.5 means 12.5%, not 0.125.
|
|
35
|
+
* Takes precedence over sampleRate when both are supplied, including 0.
|
|
36
|
+
*/
|
|
37
|
+
logSamplingRate?: number;
|
|
38
|
+
/** @deprecated Use logSamplingRate. Probability in [0, 1], default 1; 0.125 maps to 12.5%. Ignored when logSamplingRate is supplied. */
|
|
30
39
|
sampleRate?: number;
|
|
31
40
|
enableLinkRumData?: boolean;
|
|
32
41
|
enableCustomLog?: boolean;
|
|
42
|
+
enableWebViewLog?: boolean;
|
|
33
43
|
discardStrategy?: FTLogCacheDiscard;
|
|
34
44
|
logLevelFilters?: Array<FTLogStatus>;
|
|
35
45
|
globalContext?: object;
|
package/src/ft_mobile_agent.tsx
CHANGED
|
@@ -3,7 +3,10 @@ import {
|
|
|
3
3
|
NativeEventEmitter,
|
|
4
4
|
NativeModules,
|
|
5
5
|
} from 'react-native';
|
|
6
|
+
import type { Spec as NativeFTMobileReactNativeSpec } from './specs/NativeFTMobileReactNative';
|
|
7
|
+
import type { Spec as NativeFTReactNativeRUMSpec } from './specs/NativeFTReactNativeRUM';
|
|
6
8
|
import { version as sdkVersion } from './version';
|
|
9
|
+
import { FTRumWebSocketTracking } from './rum/FTRumWebSocketTracking';
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
* Bridge context manager for managing shared properties across RUM and Logger modules
|
|
@@ -13,6 +16,7 @@ import { version as sdkVersion } from './version';
|
|
|
13
16
|
class BridgeContextManager {
|
|
14
17
|
private static instance: BridgeContextManager;
|
|
15
18
|
private properties: Map<string, any> = new Map();
|
|
19
|
+
private longTaskContextEnabled = false;
|
|
16
20
|
|
|
17
21
|
private constructor() {
|
|
18
22
|
// Initialize with SDK version information
|
|
@@ -55,11 +59,35 @@ class BridgeContextManager {
|
|
|
55
59
|
Object.entries(properties).forEach(([key, value]) => {
|
|
56
60
|
this.properties.set(key, value);
|
|
57
61
|
});
|
|
62
|
+
if (this.longTaskContextEnabled) {
|
|
63
|
+
this.syncLongTaskContext();
|
|
64
|
+
}
|
|
58
65
|
} catch (error) {
|
|
59
66
|
console.warn('Failed to append bridge context:', error);
|
|
60
67
|
}
|
|
61
68
|
}
|
|
62
69
|
|
|
70
|
+
public configureLongTaskContext(enabled: boolean): void {
|
|
71
|
+
this.longTaskContextEnabled = enabled;
|
|
72
|
+
if (enabled) {
|
|
73
|
+
this.syncLongTaskContext();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private syncLongTaskContext(): void {
|
|
78
|
+
try {
|
|
79
|
+
// Apply the snapshot before JS can block. An async native call may run after
|
|
80
|
+
// the frame that detects the long task and attach stale context to it.
|
|
81
|
+
const rum: NativeFTReactNativeRUMSpec =
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
83
|
+
require('./specs/NativeFTReactNativeRUM').default;
|
|
84
|
+
rum.setLongTaskContext(this.mergeWithLocalPropertiesSync());
|
|
85
|
+
} catch (error) {
|
|
86
|
+
// Context synchronization must not make a destroyed/older bridge crash the host.
|
|
87
|
+
console.warn('Failed to sync JS long task bridge context:', error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
63
91
|
/**
|
|
64
92
|
* Merge bridge context properties with local properties
|
|
65
93
|
* Bridge context properties take precedence over local properties
|
|
@@ -135,6 +163,8 @@ export type FTRemoteConfigOverrideMatch = {
|
|
|
135
163
|
/**
|
|
136
164
|
* Values that can be modified by remote config override rules.
|
|
137
165
|
* These values will adjust the fetched remote configuration before it is applied.
|
|
166
|
+
* Omitted fields are not changed by this rule. Sampling percentages use [0, 100]
|
|
167
|
+
* and support fractions (12.5 means 12.5%); legacy probabilities use [0, 1].
|
|
138
168
|
*/
|
|
139
169
|
export type FTRemoteConfigOverrideValues = {
|
|
140
170
|
env?: string;
|
|
@@ -143,7 +173,21 @@ export type FTRemoteConfigOverrideValues = {
|
|
|
143
173
|
compressIntakeRequests?: boolean;
|
|
144
174
|
syncPageSize?: number;
|
|
145
175
|
syncSleepTime?: number;
|
|
176
|
+
/** RUM session sampling percentage override in [0, 100]; takes precedence over rumSampleRate, including 0. */
|
|
177
|
+
sessionSamplingRate?: number;
|
|
178
|
+
/** Error session sampling percentage override in [0, 100]; takes precedence over rumSessionOnErrorSampleRate, including 0. */
|
|
179
|
+
sessionOnErrorSamplingRate?: number;
|
|
180
|
+
/** Trace sampling percentage override in [0, 100]; takes precedence over traceSampleRate, including 0. */
|
|
181
|
+
traceSamplingRate?: number;
|
|
182
|
+
/** Log sampling percentage override in [0, 100]; takes precedence over logSampleRate, including 0. */
|
|
183
|
+
logSamplingRate?: number;
|
|
184
|
+
/** Session Replay sampling percentage override in [0, 100]; fractional percentages are supported. */
|
|
185
|
+
sessionReplaySamplingRate?: number;
|
|
186
|
+
/** Error replay sampling percentage override in [0, 100]; fractional percentages are supported. */
|
|
187
|
+
sessionReplayOnErrorSamplingRate?: number;
|
|
188
|
+
/** @deprecated Use sessionSamplingRate. Legacy RUM probability override in [0, 1]; 0.125 maps to 12.5%. */
|
|
146
189
|
rumSampleRate?: number;
|
|
190
|
+
/** @deprecated Use sessionOnErrorSamplingRate. Legacy error session probability override in [0, 1]. */
|
|
147
191
|
rumSessionOnErrorSampleRate?: number;
|
|
148
192
|
rumEnableTraceUserAction?: boolean;
|
|
149
193
|
rumEnableTraceUserView?: boolean;
|
|
@@ -155,12 +199,15 @@ export type FTRemoteConfigOverrideValues = {
|
|
|
155
199
|
rumEnableTrackAppANR?: boolean;
|
|
156
200
|
rumEnableTraceWebView?: boolean;
|
|
157
201
|
rumAllowWebViewHost?: Array<string>;
|
|
202
|
+
/** @deprecated Use traceSamplingRate. Legacy Trace probability override in [0, 1]. */
|
|
158
203
|
traceSampleRate?: number;
|
|
159
204
|
traceEnableAutoTrace?: boolean;
|
|
160
205
|
traceType?: string;
|
|
206
|
+
/** @deprecated Use logSamplingRate. Legacy log probability override in [0, 1]. */
|
|
161
207
|
logSampleRate?: number;
|
|
162
208
|
logLevelFilters?: Array<string>;
|
|
163
209
|
logEnableCustomLog?: boolean;
|
|
210
|
+
logEnableWebViewLog?: boolean;
|
|
164
211
|
logEnableConsoleLog?: boolean;
|
|
165
212
|
};
|
|
166
213
|
|
|
@@ -241,6 +288,10 @@ export interface FTMobileConfig {
|
|
|
241
288
|
compressIntakeRequests?: boolean;
|
|
242
289
|
enableDataFilter?: boolean;
|
|
243
290
|
dataFilters?: Record<string, Array<string>>;
|
|
291
|
+
/** Shared WebView host allowlist for RUM and Log. Omitted uses the legacy RUM
|
|
292
|
+
* config; null allows every host; [] disables bridge access. Remote config wins.
|
|
293
|
+
*/
|
|
294
|
+
allowWebViewHost?: Array<string> | null;
|
|
244
295
|
globalContext?: object;
|
|
245
296
|
groupIdentifiers?: Array<string>;
|
|
246
297
|
enableLimitWithDbSize?: boolean;
|
|
@@ -292,6 +343,8 @@ type FTMobileReactNativeType = {
|
|
|
292
343
|
* @returns a Promise.
|
|
293
344
|
*/
|
|
294
345
|
unbindRUMUserData(): Promise<void>;
|
|
346
|
+
/** Rotate the native anonymous Visitor ID for subsequent requests. */
|
|
347
|
+
resetVisitorId(): Promise<void>;
|
|
295
348
|
/**
|
|
296
349
|
* Add custom global parameters. Applies to RUM and Log data
|
|
297
350
|
* @param context custom global parameters.
|
|
@@ -361,8 +414,10 @@ type FTMobileReactNativeType = {
|
|
|
361
414
|
|
|
362
415
|
class FTMobileReactNativeWrapper implements FTMobileReactNativeType {
|
|
363
416
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
364
|
-
private sdk:
|
|
417
|
+
private sdk: NativeFTMobileReactNativeSpec =
|
|
365
418
|
require('./specs/NativeFTMobileReactNative').default;
|
|
419
|
+
private rum: NativeFTReactNativeRUMSpec =
|
|
420
|
+
require('./specs/NativeFTReactNativeRUM').default;
|
|
366
421
|
/* eslint-enable @typescript-eslint/no-var-requires */
|
|
367
422
|
|
|
368
423
|
private emitter: NativeEventEmitter | null = null;
|
|
@@ -385,7 +440,12 @@ class FTMobileReactNativeWrapper implements FTMobileReactNativeType {
|
|
|
385
440
|
) {
|
|
386
441
|
config.datakitUrl = config.serverUrl;
|
|
387
442
|
}
|
|
388
|
-
|
|
443
|
+
const nativeConfig = { ...config };
|
|
444
|
+
// Keep undefined equivalent to omission; explicit null overrides legacy hosts.
|
|
445
|
+
if (nativeConfig.allowWebViewHost === undefined) {
|
|
446
|
+
delete nativeConfig.allowWebViewHost;
|
|
447
|
+
}
|
|
448
|
+
return this.sdk.sdkConfig(nativeConfig);
|
|
389
449
|
}
|
|
390
450
|
setDatakitURL(datakitUrl: string): Promise<void> {
|
|
391
451
|
return this.sdk.setDatakitURL(datakitUrl);
|
|
@@ -401,6 +461,9 @@ class FTMobileReactNativeWrapper implements FTMobileReactNativeType {
|
|
|
401
461
|
): Promise<void> {
|
|
402
462
|
return this.sdk.bindRUMUserData(userId, userName, userEmail, extra);
|
|
403
463
|
}
|
|
464
|
+
resetVisitorId(): Promise<void> {
|
|
465
|
+
return this.sdk.resetVisitorId();
|
|
466
|
+
}
|
|
404
467
|
unbindRUMUserData(): Promise<void> {
|
|
405
468
|
return this.sdk.unbindRUMUserData();
|
|
406
469
|
}
|
|
@@ -419,24 +482,33 @@ class FTMobileReactNativeWrapper implements FTMobileReactNativeType {
|
|
|
419
482
|
flushSyncData(): Promise<void> {
|
|
420
483
|
return this.sdk.flushSyncData();
|
|
421
484
|
}
|
|
422
|
-
shutDown(): Promise<void> {
|
|
423
|
-
|
|
485
|
+
async shutDown(): Promise<void> {
|
|
486
|
+
bridgeContextManager.configureLongTaskContext(false);
|
|
487
|
+
try {
|
|
488
|
+
FTRumWebSocketTracking.shutDown();
|
|
489
|
+
await this.rum.stopLongTaskTracking();
|
|
490
|
+
} finally {
|
|
491
|
+
await this.sdk.shutDown();
|
|
492
|
+
}
|
|
424
493
|
}
|
|
425
494
|
clearAllData(): Promise<void> {
|
|
426
495
|
return this.sdk.clearAllData();
|
|
427
496
|
}
|
|
428
497
|
appendBridgeContext(properties: Record<string, any>): void {
|
|
429
|
-
//
|
|
498
|
+
// Store properties in JS and update the native long task snapshot when enabled.
|
|
430
499
|
bridgeContextManager.appendBridgeContext(properties);
|
|
431
500
|
}
|
|
432
501
|
updateRemoteConfig(): Promise<FTRemoteConfigResult> {
|
|
433
|
-
return this.sdk.updateRemoteConfig()
|
|
502
|
+
return this.sdk.updateRemoteConfig() as Promise<FTRemoteConfigResult>;
|
|
434
503
|
}
|
|
435
504
|
updateRemoteConfigWithMiniUpdateInterval(
|
|
436
505
|
interval: number,
|
|
437
506
|
rules?: Array<FTRemoteConfigOverrideRule>
|
|
438
507
|
): Promise<FTRemoteConfigResult> {
|
|
439
|
-
return this.sdk.updateRemoteConfigWithMiniUpdateInterval(
|
|
508
|
+
return this.sdk.updateRemoteConfigWithMiniUpdateInterval(
|
|
509
|
+
interval,
|
|
510
|
+
rules
|
|
511
|
+
) as Promise<FTRemoteConfigResult>;
|
|
440
512
|
}
|
|
441
513
|
addRemoteConfigListener(
|
|
442
514
|
listener: (result: FTRemoteConfigResult) => void
|
package/src/ft_rum.tsx
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import { FTVisitorIdConfig, validateVisitorIdConfig } from './visitorIdConfig';
|
|
1
2
|
// import { NativeModules } from 'react-native';
|
|
3
|
+
import { Platform } from 'react-native';
|
|
2
4
|
import { FTRumErrorTracking } from './rum/FTRumErrorTracking';
|
|
3
5
|
import { FTRumActionTracking } from './rum/FTRumActionTracking';
|
|
6
|
+
import { FTBabelInteractionTracking } from './rum/FTBabelInteractionTracking';
|
|
7
|
+
import { FTRumWebSocketTracking } from './rum/FTRumWebSocketTracking';
|
|
4
8
|
import { bridgeContextManager } from './ft_mobile_agent';
|
|
9
|
+
import { normalizeLongTaskThreshold } from './rum/longTasksUtils';
|
|
5
10
|
|
|
6
11
|
/**
|
|
7
12
|
* Error monitoring type.
|
|
@@ -72,17 +77,25 @@ export enum IOSCrashMonitoringType {
|
|
|
72
77
|
* Set RUM tracking conditions.
|
|
73
78
|
* @param androidAppId appId, apply during monitoring
|
|
74
79
|
* @param iOSAppId appId, apply during monitoring
|
|
75
|
-
* @param
|
|
76
|
-
* @param
|
|
80
|
+
* @param sessionSamplingRate RUM session sampling percentage in [0, 100], default 100. Supports fractional percentages and takes precedence over sampleRate.
|
|
81
|
+
* @param sessionOnErrorSamplingRate Sampling percentage in [0, 100] for otherwise unsampled sessions when an error occurs, default 0. Supports fractional percentages and takes precedence over sessionOnErrorSampleRate.
|
|
82
|
+
* @param sampleRate Deprecated RUM session sampling probability in [0, 1], default 1. Used only when sessionSamplingRate is omitted; multiplied by 100 before passing to Native.
|
|
83
|
+
* @param sessionOnErrorSampleRate Deprecated error session sampling probability in [0, 1], default 0. Used only when sessionOnErrorSamplingRate is omitted; multiplied by 100 before passing to Native.
|
|
77
84
|
* @param enableAutoTrackUserAction whether to automatically collect react-native control click events, can set actionName with accessibilityLabel when enabled
|
|
78
85
|
* @param enableTrackError whether to automatically collect react-native Error
|
|
79
86
|
* @param enableTrackNativeCrash whether to collect Native Error
|
|
80
87
|
* @param enableTrackNativeAppANR whether to collect Native ANR
|
|
81
88
|
* @param enableTrackNativeFreeze whether to collect Native Freeze
|
|
82
89
|
* @param nativeFreezeDurationMs set the threshold for collecting Native Freeze, value range [100,), unit ms. iOS default 250ms, Android default 1000ms
|
|
90
|
+
* @param enableLongTask whether to collect React Native JavaScript LongTasks, default false
|
|
91
|
+
* @param longTaskThresholdMs set the threshold for collecting React Native JavaScript LongTasks, unit ms. Defaults to 100 and is clamped to [100, 5000]
|
|
83
92
|
* @param enableNativeUserAction whether to start Native Action tracking, Button click events, recommended to disable for pure react-native apps
|
|
84
93
|
* @param enableNativeUserView whether to start Native View auto tracking, recommended to disable for pure react-native apps
|
|
85
94
|
* @param enableNativeUserResource whether to automatically collect react-native Resource
|
|
95
|
+
* @param enableIOSWebSocketResource whether to collect iOS WebSocket opening handshakes as RUM Resources. Defaults to false.
|
|
96
|
+
* Independent of enableNativeUserResource. Android native WebSocket collection is unaffected.
|
|
97
|
+
* iOS WebSocket Trace header injection requires both this option and enableNativeAutoTrace.
|
|
98
|
+
* When disabled, new iOS WebSocket connections are not instrumented or automatically injected with Trace headers by this SDK.
|
|
86
99
|
* @param enableResourceHostIP whether to collect network request Host IP (only for native http, iOS 13 and above)
|
|
87
100
|
* @param errorMonitorType error monitoring supplement type
|
|
88
101
|
* @param deviceMonitorType page monitoring supplement type
|
|
@@ -91,13 +104,30 @@ export enum IOSCrashMonitoringType {
|
|
|
91
104
|
* @param rumCacheLimitCount RUM max cache size, default 100_000
|
|
92
105
|
* @param rumDiscardStrategy RUM data discard strategy
|
|
93
106
|
* @param enableTraceWebView Set whether to enable WebView data collection, default true
|
|
94
|
-
* @param allowWebViewHost
|
|
107
|
+
* @param allowWebViewHost Deprecated; use FTMobileConfig.allowWebViewHost for shared WebView host filtering.
|
|
95
108
|
* @param iosCrashMonitoringType iOS crash monitoring type , default is highCompatibility, which does not include Mach exceptions for better compatibility. you must enable system crash monitoring to get crash stack traces and crash information.
|
|
96
109
|
*/
|
|
97
110
|
export interface FTRUMConfig {
|
|
111
|
+
/** Valid config enables Visitor ID; omitted/null disables it. */
|
|
112
|
+
visitorIdConfig?: FTVisitorIdConfig | null;
|
|
98
113
|
androidAppId: string;
|
|
99
114
|
iOSAppId: string;
|
|
115
|
+
/**
|
|
116
|
+
* RUM session sampling percentage in [0, 100], default 100.
|
|
117
|
+
* Supports fractional percentages: 12.5 means 12.5%, not 0.125.
|
|
118
|
+
* Takes precedence over sampleRate when both are supplied, including 0.
|
|
119
|
+
* Setting 0 disables regular session sampling; error session sampling is separate.
|
|
120
|
+
*/
|
|
121
|
+
sessionSamplingRate?: number;
|
|
122
|
+
/** @deprecated Use sessionSamplingRate. Probability in [0, 1], default 1; 0.125 maps to 12.5%. Ignored when sessionSamplingRate is supplied. */
|
|
100
123
|
sampleRate?: number;
|
|
124
|
+
/**
|
|
125
|
+
* Sampling percentage for otherwise unsampled RUM sessions when an error occurs.
|
|
126
|
+
* Range [0, 100], default 0; fractional percentages are supported.
|
|
127
|
+
* Takes precedence over sessionOnErrorSampleRate when both are supplied, including 0.
|
|
128
|
+
*/
|
|
129
|
+
sessionOnErrorSamplingRate?: number;
|
|
130
|
+
/** @deprecated Use sessionOnErrorSamplingRate. Probability in [0, 1], default 0; multiplied by 100. Ignored when sessionOnErrorSamplingRate is supplied. */
|
|
101
131
|
sessionOnErrorSampleRate?: number;
|
|
102
132
|
enableAutoTrackUserAction?: boolean;
|
|
103
133
|
enableAutoTrackError?: boolean;
|
|
@@ -105,9 +135,12 @@ export interface FTRUMConfig {
|
|
|
105
135
|
enableTrackNativeAppANR?: boolean;
|
|
106
136
|
enableTrackNativeFreeze?: boolean;
|
|
107
137
|
nativeFreezeDurationMs?: number;
|
|
138
|
+
enableLongTask?: boolean;
|
|
139
|
+
longTaskThresholdMs?: number;
|
|
108
140
|
enableNativeUserAction?: boolean;
|
|
109
141
|
enableNativeUserView?: boolean;
|
|
110
142
|
enableNativeUserResource?: boolean;
|
|
143
|
+
enableIOSWebSocketResource?: boolean;
|
|
111
144
|
enableResourceHostIP?: boolean;
|
|
112
145
|
errorMonitorType?: ErrorMonitorType;
|
|
113
146
|
deviceMonitorType?: DeviceMetricsMonitorType;
|
|
@@ -116,7 +149,8 @@ export interface FTRUMConfig {
|
|
|
116
149
|
rumCacheLimitCount?: number;
|
|
117
150
|
rumDiscardStrategy?: FTRUMCacheDiscard;
|
|
118
151
|
enableTraceWebView?: boolean;
|
|
119
|
-
allowWebViewHost
|
|
152
|
+
/** @deprecated Configure the shared host allowlist in FTMobileConfig.allowWebViewHost. */
|
|
153
|
+
allowWebViewHost?: Array<string> | null;
|
|
120
154
|
iosCrashMonitoringType?: IOSCrashMonitoringType;
|
|
121
155
|
}
|
|
122
156
|
/**
|
|
@@ -192,10 +226,17 @@ type FTReactNativeRUMType = {
|
|
|
192
226
|
/**
|
|
193
227
|
* view load duration.
|
|
194
228
|
* @param viewName view name
|
|
195
|
-
* @param loadTime view load duration
|
|
229
|
+
* @param loadTime monotonic view load duration in nanoseconds
|
|
196
230
|
* @returns a Promise.
|
|
197
231
|
*/
|
|
198
232
|
onCreateView(viewName: string, loadTime: number): Promise<void>;
|
|
233
|
+
/**
|
|
234
|
+
* Replace the current active View's loading duration, between startView and stopView.
|
|
235
|
+
* @param duration monotonic elapsed time in nanoseconds; a non-negative safe integer.
|
|
236
|
+
* Zero clears loading time. Late calls can update a newer View; no View ID is supplied.
|
|
237
|
+
* @returns a Promise for the native call, not for data upload.
|
|
238
|
+
*/
|
|
239
|
+
updateViewLoadingTime(duration: number): Promise<void>;
|
|
199
240
|
/**
|
|
200
241
|
* view start.
|
|
201
242
|
* @param viewName page name
|
|
@@ -259,20 +300,73 @@ type FTReactNativeRUMType = {
|
|
|
259
300
|
): Promise<void>;
|
|
260
301
|
};
|
|
261
302
|
|
|
303
|
+
function isBabelPluginEnabled(): boolean {
|
|
304
|
+
if (typeof globalThis !== 'undefined') {
|
|
305
|
+
return globalThis.__FT_RN_BABEL_PLUGIN_ENABLED__ === true;
|
|
306
|
+
}
|
|
307
|
+
if (typeof global !== 'undefined') {
|
|
308
|
+
return global.__FT_RN_BABEL_PLUGIN_ENABLED__ === true;
|
|
309
|
+
}
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
|
|
262
313
|
class FTReactNativeRUMWrapper implements FTReactNativeRUMType {
|
|
314
|
+
private webSocketConfigVersion = 0;
|
|
263
315
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
264
316
|
private rum: FTReactNativeRUMType = require('./specs/NativeFTReactNativeRUM')
|
|
265
317
|
.default;
|
|
266
318
|
|
|
267
319
|
setConfig(config: FTRUMConfig): Promise<void> {
|
|
320
|
+
if (config.visitorIdConfig != null) {
|
|
321
|
+
try {
|
|
322
|
+
validateVisitorIdConfig(config.visitorIdConfig);
|
|
323
|
+
} catch (error) {
|
|
324
|
+
return Promise.reject(error);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
bridgeContextManager.configureLongTaskContext(
|
|
328
|
+
config.enableLongTask === true
|
|
329
|
+
);
|
|
330
|
+
const webSocketLifecycle = FTRumWebSocketTracking.getLifecycleVersion();
|
|
331
|
+
const webSocketConfigVersion = ++this.webSocketConfigVersion;
|
|
332
|
+
const trackWebSocket = config.enableIOSWebSocketResource === true;
|
|
268
333
|
console.log('FTRUMConfig');
|
|
269
334
|
if (config.enableAutoTrackError) {
|
|
270
335
|
FTRumErrorTracking.startTracking();
|
|
271
336
|
}
|
|
272
|
-
|
|
337
|
+
const babelPluginEnabled = isBabelPluginEnabled();
|
|
338
|
+
FTBabelInteractionTracking.configure({
|
|
339
|
+
trackInteractions:
|
|
340
|
+
babelPluginEnabled && Boolean(config.enableAutoTrackUserAction),
|
|
341
|
+
actionReporter: (actionName, actionType, property) =>
|
|
342
|
+
this.startAction(actionName, actionType, property),
|
|
343
|
+
});
|
|
344
|
+
if (config.enableAutoTrackUserAction && !babelPluginEnabled) {
|
|
273
345
|
FTRumActionTracking.startTracking();
|
|
346
|
+
} else {
|
|
347
|
+
FTRumActionTracking.stopTracking();
|
|
274
348
|
}
|
|
275
|
-
return this.rum
|
|
349
|
+
return this.rum
|
|
350
|
+
.setConfig({
|
|
351
|
+
...config,
|
|
352
|
+
enableLongTask: config.enableLongTask === true,
|
|
353
|
+
longTaskThresholdMs: normalizeLongTaskThreshold(
|
|
354
|
+
config.longTaskThresholdMs
|
|
355
|
+
),
|
|
356
|
+
})
|
|
357
|
+
.then(() => {
|
|
358
|
+
if (
|
|
359
|
+
webSocketLifecycle !== FTRumWebSocketTracking.getLifecycleVersion() ||
|
|
360
|
+
webSocketConfigVersion !== this.webSocketConfigVersion
|
|
361
|
+
) {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
if (Platform.OS === 'ios' && trackWebSocket) {
|
|
365
|
+
FTRumWebSocketTracking.startTracking(this);
|
|
366
|
+
} else {
|
|
367
|
+
FTRumWebSocketTracking.stopTracking();
|
|
368
|
+
}
|
|
369
|
+
});
|
|
276
370
|
}
|
|
277
371
|
startAction(
|
|
278
372
|
actionName: string,
|
|
@@ -297,6 +391,16 @@ class FTReactNativeRUMWrapper implements FTReactNativeRUMType {
|
|
|
297
391
|
onCreateView(viewName: string, loadTime: number): Promise<void> {
|
|
298
392
|
return this.rum.onCreateView(viewName, loadTime);
|
|
299
393
|
}
|
|
394
|
+
updateViewLoadingTime(duration: number): Promise<void> {
|
|
395
|
+
if (!Number.isSafeInteger(duration) || duration < 0) {
|
|
396
|
+
return Promise.reject(
|
|
397
|
+
new RangeError(
|
|
398
|
+
'duration must be a non-negative safe integer in nanoseconds'
|
|
399
|
+
)
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
return this.rum.updateViewLoadingTime(duration);
|
|
403
|
+
}
|
|
300
404
|
startView(viewName: string, property?: object): Promise<void> {
|
|
301
405
|
// Automatically merge bridge context properties with local properties
|
|
302
406
|
const mergedProperties =
|
package/src/ft_tracing.tsx
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// import { NativeModules } from 'react-native';
|
|
2
2
|
//FTReactNativeTrace
|
|
3
3
|
|
|
4
|
+
import { FTRumWebSocketTracking } from './rum/FTRumWebSocketTracking';
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
* Trace types for use.
|
|
6
8
|
*/
|
|
@@ -33,12 +35,20 @@ export enum TraceType {
|
|
|
33
35
|
}
|
|
34
36
|
/**
|
|
35
37
|
* Configure trace.
|
|
36
|
-
* @param
|
|
38
|
+
* @param traceSamplingRate Trace sampling percentage in [0, 100], default 100. Supports fractional percentages and takes precedence over sampleRate.
|
|
39
|
+
* @param sampleRate Deprecated Trace sampling probability in [0, 1], default 1. Used only when traceSamplingRate is omitted; multiplied by 100 before passing to Native.
|
|
37
40
|
* @param traceType trace type
|
|
38
41
|
* @param enableLinkRUMData whether to link with RUM data
|
|
39
42
|
* @param enableNativeAutoTrace whether to enable automatic tracing
|
|
40
43
|
*/
|
|
41
44
|
export interface FTTraceConfig {
|
|
45
|
+
/**
|
|
46
|
+
* Trace sampling percentage in [0, 100], default 100.
|
|
47
|
+
* Supports fractional percentages: 12.5 means 12.5%, not 0.125.
|
|
48
|
+
* Takes precedence over sampleRate when both are supplied, including 0.
|
|
49
|
+
*/
|
|
50
|
+
traceSamplingRate?: number;
|
|
51
|
+
/** @deprecated Use traceSamplingRate. Probability in [0, 1], default 1; 0.125 maps to 12.5%. Ignored when traceSamplingRate is supplied. */
|
|
42
52
|
sampleRate?: number;
|
|
43
53
|
traceType?: TraceType;
|
|
44
54
|
enableLinkRUMData?: boolean;
|
|
@@ -68,13 +78,25 @@ type FTReactNativeTraceType = {
|
|
|
68
78
|
};
|
|
69
79
|
|
|
70
80
|
class FTReactNativeTraceWrapper implements FTReactNativeTraceType {
|
|
81
|
+
private webSocketConfigVersion = 0;
|
|
71
82
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
72
83
|
private trace: FTReactNativeTraceType =
|
|
73
84
|
require('./specs/NativeFTReactNativeTrace').default;
|
|
74
85
|
/* eslint-enable @typescript-eslint/no-var-requires */
|
|
75
86
|
|
|
76
87
|
setConfig(config: FTTraceConfig): Promise<void> {
|
|
77
|
-
|
|
88
|
+
const webSocketLifecycle = FTRumWebSocketTracking.getLifecycleVersion();
|
|
89
|
+
const webSocketConfigVersion = ++this.webSocketConfigVersion;
|
|
90
|
+
const traceWebSocket = config.enableNativeAutoTrace === true;
|
|
91
|
+
return this.trace.setConfig(config).then(() => {
|
|
92
|
+
if (
|
|
93
|
+
webSocketLifecycle !== FTRumWebSocketTracking.getLifecycleVersion() ||
|
|
94
|
+
webSocketConfigVersion !== this.webSocketConfigVersion
|
|
95
|
+
) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
FTRumWebSocketTracking.setNativeAutoTraceEnabled(traceWebSocket);
|
|
99
|
+
});
|
|
78
100
|
}
|
|
79
101
|
/**
|
|
80
102
|
* Get trace HTTP request header data.
|
package/src/index.tsx
CHANGED
|
@@ -28,6 +28,8 @@ import {
|
|
|
28
28
|
import { FTTraceConfig, FTReactNativeTrace, TraceType } from './ft_tracing';
|
|
29
29
|
import { FTRumActionTracking } from './rum/FTRumActionTracking';
|
|
30
30
|
import { FTRumErrorTracking } from './rum/FTRumErrorTracking';
|
|
31
|
+
import { FTBabelInteractionTracking } from './rum/FTBabelInteractionTracking';
|
|
32
|
+
import { __ftExtractText } from './rum/FTBabelUtils';
|
|
31
33
|
|
|
32
34
|
export {
|
|
33
35
|
FTMobileReactNative,
|
|
@@ -56,4 +58,10 @@ export {
|
|
|
56
58
|
TraceType,
|
|
57
59
|
FTRumActionTracking,
|
|
58
60
|
FTRumErrorTracking,
|
|
61
|
+
FTBabelInteractionTracking,
|
|
62
|
+
__ftExtractText,
|
|
59
63
|
};
|
|
64
|
+
|
|
65
|
+
export type { FTVisitorIdConfig } from './visitorIdConfig';
|
|
66
|
+
|
|
67
|
+
export { FTRumViewTracking } from './rum/FTRumViewTracking';
|