@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.
Files changed (153) hide show
  1. package/FTMobileReactNativeSDK.podspec +7 -5
  2. package/android/build.gradle +10 -3
  3. package/android/src/main/java/com/ft/sdk/reactnative/FTLogImpl.java +10 -2
  4. package/android/src/main/java/com/ft/sdk/reactnative/FTMobileImpl.java +45 -10
  5. package/android/src/main/java/com/ft/sdk/reactnative/FTRUMImpl.java +131 -6
  6. package/android/src/main/java/com/ft/sdk/reactnative/FTTraceImpl.java +10 -3
  7. package/android/src/main/java/com/ft/sdk/reactnative/JsLongTaskMonitor.java +281 -0
  8. package/android/src/main/java/com/ft/sdk/reactnative/ViewTiming.java +17 -0
  9. package/android/src/main/java/com/ft/sdk/reactnative/VisitorIdConfigMapper.java +50 -0
  10. package/android/src/main/java/com/ft/sdk/reactnative/utils/ReactNativeUtils.java +5 -12
  11. package/android/src/newarch/java/com/ft/sdk/reactnative/FTMobileModule.java +14 -5
  12. package/android/src/newarch/java/com/ft/sdk/reactnative/FTRUMModule.java +44 -1
  13. package/android/src/newarch/java/com/ft/sdk/reactnative/FTTraceModule.java +14 -0
  14. package/android/src/oldarch/java/com/ft/sdk/reactnative/FTMobileModule.java +7 -2
  15. package/android/src/oldarch/java/com/ft/sdk/reactnative/FTRUMModule.java +39 -1
  16. package/android/src/oldarch/java/com/ft/sdk/reactnative/FTTraceModule.java +12 -0
  17. package/android/src/rnpost70/java/com/ft/sdk/reactnative/ReactJsThreadExecutor.java +21 -0
  18. package/android/src/rnpre70/java/com/ft/sdk/reactnative/ReactJsThreadExecutor.java +37 -0
  19. package/android/src/test/java/com/ft/sdk/reactnative/FTMobileImplTest.java +53 -0
  20. package/android/src/test/java/com/ft/sdk/reactnative/FTRUMModuleTest.java +117 -0
  21. package/android/src/test/java/com/ft/sdk/reactnative/JsLongTaskMonitorTest.java +446 -0
  22. package/android/src/test/java/com/ft/sdk/reactnative/utils/ReactNativeUtilsTest.java +33 -0
  23. package/ios/FTJSLongTaskMonitor.h +51 -0
  24. package/ios/FTJSLongTaskMonitor.m +250 -0
  25. package/ios/FTMobileReactNative.mm +54 -18
  26. package/ios/FTReactNativeLog.mm +9 -5
  27. package/ios/FTReactNativeRUM.mm +196 -31
  28. package/ios/FTReactNativeResource.h +4 -0
  29. package/ios/FTReactNativeResource.m +64 -0
  30. package/ios/FTReactNativeTrace.mm +59 -14
  31. package/ios/FTReactNativeUtils.m +10 -15
  32. package/ios/FTReactNativeViewTiming.h +18 -0
  33. package/ios/FTReactNativeWebSocket.h +10 -0
  34. package/ios/FTReactNativeWebSocket.mm +201 -0
  35. package/ios/FTWebSocketMetadataStore.h +25 -0
  36. package/ios/FTWebSocketMetadataStore.m +622 -0
  37. package/ios/FTWebSocketResourceData.h +20 -0
  38. package/ios/FTWebSocketResourceData.m +106 -0
  39. package/lib/commonjs/ft_logger.js +3 -1
  40. package/lib/commonjs/ft_logger.js.map +1 -1
  41. package/lib/commonjs/ft_mobile_agent.js +47 -4
  42. package/lib/commonjs/ft_mobile_agent.js.map +1 -1
  43. package/lib/commonjs/ft_rum.js +65 -5
  44. package/lib/commonjs/ft_rum.js.map +1 -1
  45. package/lib/commonjs/ft_tracing.js +14 -4
  46. package/lib/commonjs/ft_tracing.js.map +1 -1
  47. package/lib/commonjs/index.js +21 -0
  48. package/lib/commonjs/index.js.map +1 -1
  49. package/lib/commonjs/rum/FTBabelInteractionTracking.js +72 -0
  50. package/lib/commonjs/rum/FTBabelInteractionTracking.js.map +1 -0
  51. package/lib/commonjs/rum/FTBabelUtils.js +87 -0
  52. package/lib/commonjs/rum/FTBabelUtils.js.map +1 -0
  53. package/lib/commonjs/rum/FTRumActionTracking.js +10 -39
  54. package/lib/commonjs/rum/FTRumActionTracking.js.map +1 -1
  55. package/lib/commonjs/rum/FTRumActionTrackingContext.js +50 -0
  56. package/lib/commonjs/rum/FTRumActionTrackingContext.js.map +1 -0
  57. package/lib/commonjs/rum/FTRumViewTracking.js +147 -0
  58. package/lib/commonjs/rum/FTRumViewTracking.js.map +1 -0
  59. package/lib/commonjs/rum/FTRumWebSocketNative.js +73 -0
  60. package/lib/commonjs/rum/FTRumWebSocketNative.js.map +1 -0
  61. package/lib/commonjs/rum/FTRumWebSocketTiming.js +73 -0
  62. package/lib/commonjs/rum/FTRumWebSocketTiming.js.map +1 -0
  63. package/lib/commonjs/rum/FTRumWebSocketTracking.js +506 -0
  64. package/lib/commonjs/rum/FTRumWebSocketTracking.js.map +1 -0
  65. package/lib/commonjs/rum/longTasksUtils.js +25 -0
  66. package/lib/commonjs/rum/longTasksUtils.js.map +1 -0
  67. package/lib/commonjs/specs/NativeFTMobileReactNative.js.map +1 -1
  68. package/lib/commonjs/specs/NativeFTReactNativeRUM.js.map +1 -1
  69. package/lib/commonjs/specs/NativeFTReactNativeTrace.js.map +1 -1
  70. package/lib/commonjs/specs/NativeFTReactNativeWebSocket.js +11 -0
  71. package/lib/commonjs/specs/NativeFTReactNativeWebSocket.js.map +1 -0
  72. package/lib/commonjs/version.js +1 -1
  73. package/lib/commonjs/version.js.map +1 -1
  74. package/lib/commonjs/visitorIdConfig.js +37 -0
  75. package/lib/commonjs/visitorIdConfig.js.map +1 -0
  76. package/lib/module/ft_logger.js +3 -1
  77. package/lib/module/ft_logger.js.map +1 -1
  78. package/lib/module/ft_mobile_agent.js +47 -4
  79. package/lib/module/ft_mobile_agent.js.map +1 -1
  80. package/lib/module/ft_rum.js +65 -5
  81. package/lib/module/ft_rum.js.map +1 -1
  82. package/lib/module/ft_tracing.js +14 -2
  83. package/lib/module/ft_tracing.js.map +1 -1
  84. package/lib/module/index.js +4 -1
  85. package/lib/module/index.js.map +1 -1
  86. package/lib/module/rum/FTBabelInteractionTracking.js +66 -0
  87. package/lib/module/rum/FTBabelInteractionTracking.js.map +1 -0
  88. package/lib/module/rum/FTBabelUtils.js +80 -0
  89. package/lib/module/rum/FTBabelUtils.js.map +1 -0
  90. package/lib/module/rum/FTRumActionTracking.js +10 -39
  91. package/lib/module/rum/FTRumActionTracking.js.map +1 -1
  92. package/lib/module/rum/FTRumActionTrackingContext.js +43 -0
  93. package/lib/module/rum/FTRumActionTrackingContext.js.map +1 -0
  94. package/lib/module/rum/FTRumViewTracking.js +140 -0
  95. package/lib/module/rum/FTRumViewTracking.js.map +1 -0
  96. package/lib/module/rum/FTRumWebSocketNative.js +62 -0
  97. package/lib/module/rum/FTRumWebSocketNative.js.map +1 -0
  98. package/lib/module/rum/FTRumWebSocketTiming.js +67 -0
  99. package/lib/module/rum/FTRumWebSocketTiming.js.map +1 -0
  100. package/lib/module/rum/FTRumWebSocketTracking.js +499 -0
  101. package/lib/module/rum/FTRumWebSocketTracking.js.map +1 -0
  102. package/lib/module/rum/longTasksUtils.js +18 -0
  103. package/lib/module/rum/longTasksUtils.js.map +1 -0
  104. package/lib/module/specs/NativeFTMobileReactNative.js.map +1 -1
  105. package/lib/module/specs/NativeFTReactNativeRUM.js.map +1 -1
  106. package/lib/module/specs/NativeFTReactNativeTrace.js.map +1 -1
  107. package/lib/module/specs/NativeFTReactNativeWebSocket.js +8 -0
  108. package/lib/module/specs/NativeFTReactNativeWebSocket.js.map +1 -0
  109. package/lib/module/version.js +1 -1
  110. package/lib/module/version.js.map +1 -1
  111. package/lib/module/visitorIdConfig.js +31 -0
  112. package/lib/module/visitorIdConfig.js.map +1 -0
  113. package/lib/typescript/ft_logger.d.ts +11 -1
  114. package/lib/typescript/ft_mobile_agent.d.ts +28 -0
  115. package/lib/typescript/ft_rum.d.ts +42 -5
  116. package/lib/typescript/ft_tracing.d.ts +9 -1
  117. package/lib/typescript/index.d.ts +5 -1
  118. package/lib/typescript/rum/FTBabelInteractionTracking.d.ts +30 -0
  119. package/lib/typescript/rum/FTBabelUtils.d.ts +1 -0
  120. package/lib/typescript/rum/FTRumActionTracking.d.ts +0 -2
  121. package/lib/typescript/rum/FTRumActionTrackingContext.d.ts +11 -0
  122. package/lib/typescript/rum/FTRumViewTracking.d.ts +32 -0
  123. package/lib/typescript/rum/FTRumWebSocketNative.d.ts +22 -0
  124. package/lib/typescript/rum/FTRumWebSocketTiming.d.ts +7 -0
  125. package/lib/typescript/rum/FTRumWebSocketTracking.d.ts +54 -0
  126. package/lib/typescript/rum/longTasksUtils.d.ts +8 -0
  127. package/lib/typescript/specs/NativeFTMobileReactNative.d.ts +15 -0
  128. package/lib/typescript/specs/NativeFTReactNativeRUM.d.ts +11 -1
  129. package/lib/typescript/specs/NativeFTReactNativeTrace.d.ts +12 -0
  130. package/lib/typescript/specs/NativeFTReactNativeWebSocket.d.ts +13 -0
  131. package/lib/typescript/version.d.ts +1 -1
  132. package/lib/typescript/visitorIdConfig.d.ts +11 -0
  133. package/package.json +6 -4
  134. package/src/ft_logger.tsx +11 -1
  135. package/src/ft_mobile_agent.tsx +79 -7
  136. package/src/ft_rum.tsx +111 -7
  137. package/src/ft_tracing.tsx +24 -2
  138. package/src/index.tsx +8 -0
  139. package/src/rum/FTBabelInteractionTracking.ts +124 -0
  140. package/src/rum/FTBabelUtils.tsx +99 -0
  141. package/src/rum/FTRumActionTracking.tsx +14 -43
  142. package/src/rum/FTRumActionTrackingContext.ts +68 -0
  143. package/src/rum/FTRumViewTracking.ts +179 -0
  144. package/src/rum/FTRumWebSocketNative.ts +107 -0
  145. package/src/rum/FTRumWebSocketTiming.ts +82 -0
  146. package/src/rum/FTRumWebSocketTracking.ts +722 -0
  147. package/src/rum/longTasksUtils.ts +17 -0
  148. package/src/specs/NativeFTMobileReactNative.ts +18 -0
  149. package/src/specs/NativeFTReactNativeRUM.ts +19 -1
  150. package/src/specs/NativeFTReactNativeTrace.ts +12 -0
  151. package/src/specs/NativeFTReactNativeWebSocket.ts +33 -0
  152. package/src/version.ts +1 -1
  153. 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.2";
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.2",
4
- "description": "Base on TrueWatchTech Android iOS React Native SDK",
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 sampleRate sampling rate
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;
@@ -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: FTMobileReactNativeType =
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
- return this.sdk.sdkConfig(config);
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
- return this.sdk.shutDown();
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
- // Use bridgeContextManager to store properties in JavaScript and send to native SDK
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(interval, rules);
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 sampleRate sampling rate
76
- * @param sessionOnErrorSampleRate error session sampling rate. For sessions not sampled, if ERROR is hit, collect data 1 minute before the error occurs
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 Set specific hosts or domains allowed to collect WebView data, nil means collect all
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?: Array<string>;
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
- if (config.enableAutoTrackUserAction) {
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.setConfig(config);
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 =
@@ -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 sampleRate sampling rate
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
- return this.trace.setConfig(config);
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';