@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,499 @@
1
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
2
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4
+ /* global WebSocket */
5
+ import { Platform } from 'react-native';
6
+ import NativeFTReactNativeTrace from '../specs/NativeFTReactNativeTrace';
7
+ import { startWebSocketTiming } from './FTRumWebSocketTiming';
8
+ import { clearNativeWebSocketSessions, startNativeWebSocketSession, webSocketNativeID } from './FTRumWebSocketNative';
9
+ const REACT_NATIVE_DEV_WEBSOCKET = /^wss?:\/\/(?:(?:10|172|192)\.[0-9]+\.[0-9]+\.[0-9]+|localhost|127\.0\.0\.1|\[::1\]):808[0-9]\/(?:hot|symbolicate|message|inspector|status|assets|logs|debugger-proxy)(?:[/?#].*)?$/i;
10
+
11
+ // SocketRocket embeds the actual response status in this description, which
12
+ // RCTWebSocketModule forwards to JS. Do not match proxy errors or bare numbers.
13
+ const SOCKET_ROCKET_HTTP_ERROR = /^Received\s+bad\s+response\s+code\s+from\s+server\s*:\s*([1-9]\d{2})\s*\.?$/i;
14
+ const MAX_HTTP_ERROR_PARSE_LENGTH = 512;
15
+ export class FTRumWebSocketTracking {
16
+ /** Identifies configuration and reporting work started before SDK shutdown. */
17
+ static getLifecycleVersion() {
18
+ return FTRumWebSocketTracking.lifecycleVersion;
19
+ }
20
+ static shutDown() {
21
+ FTRumWebSocketTracking.lifecycleVersion += 1;
22
+ clearNativeWebSocketSessions();
23
+ FTRumWebSocketTracking.setNativeAutoTraceEnabled(false);
24
+ FTRumWebSocketTracking.stopTracking();
25
+ FTRumWebSocketTracking.pendingHandshakes.forEach(removeListeners => removeListeners());
26
+ FTRumWebSocketTracking.pendingHandshakes.clear();
27
+ FTRumWebSocketTracking.warnedFailures.clear();
28
+ }
29
+ static setNativeAutoTraceEnabled(enabled) {
30
+ FTRumWebSocketTracking.nativeAutoTraceEnabled = enabled;
31
+ }
32
+ static stopNativeSession() {
33
+ var _FTRumWebSocketTracki;
34
+ (_FTRumWebSocketTracki = FTRumWebSocketTracking.nativeSession) === null || _FTRumWebSocketTracki === void 0 || _FTRumWebSocketTracki.stop();
35
+ FTRumWebSocketTracking.nativeSession = undefined;
36
+ }
37
+ static startTracking(resourceReporter) {
38
+ if (Platform.OS !== 'ios') {
39
+ return;
40
+ }
41
+ FTRumWebSocketTracking.enabled = true;
42
+ FTRumWebSocketTracking.resourceReporter = resourceReporter;
43
+ const runtimeGlobal = globalThis;
44
+ const originalWebSocket = runtimeGlobal.WebSocket;
45
+ if (originalWebSocket === FTRumWebSocketTracking.instrumentedWebSocket) {
46
+ return;
47
+ }
48
+ if (typeof originalWebSocket !== 'function') {
49
+ FTRumWebSocketTracking.stopNativeSession();
50
+ return;
51
+ }
52
+ if (!FTRumWebSocketTracking.nativeSession) {
53
+ FTRumWebSocketTracking.nativeSession = startNativeWebSocketSession(() => FTRumWebSocketTracking.createResourceKey());
54
+ }
55
+ const InstrumentedWebSocket = function (...args) {
56
+ if (!new.target) {
57
+ return Reflect.apply(originalWebSocket, this, args);
58
+ }
59
+ // A constructor retained before stop/reinitialization must stay passive.
60
+ if (FTRumWebSocketTracking.instrumentedWebSocket !== InstrumentedWebSocket) {
61
+ return Reflect.construct(originalWebSocket, args, new.target);
62
+ }
63
+ return FTRumWebSocketTracking.createWebSocket(originalWebSocket, args, new.target);
64
+ };
65
+ try {
66
+ InstrumentedWebSocket.prototype = originalWebSocket.prototype;
67
+ Object.setPrototypeOf(InstrumentedWebSocket, originalWebSocket);
68
+ runtimeGlobal.WebSocket = InstrumentedWebSocket;
69
+ if (runtimeGlobal.WebSocket !== InstrumentedWebSocket) {
70
+ FTRumWebSocketTracking.warnOnce('Unable to install WebSocket tracking.');
71
+ FTRumWebSocketTracking.stopNativeSession();
72
+ return;
73
+ }
74
+ FTRumWebSocketTracking.originalWebSocket = originalWebSocket;
75
+ FTRumWebSocketTracking.instrumentedWebSocket = InstrumentedWebSocket;
76
+ FTRumWebSocketTracking.installed = true;
77
+ } catch {
78
+ FTRumWebSocketTracking.stopNativeSession();
79
+ FTRumWebSocketTracking.warnOnce('Unable to install WebSocket tracking.');
80
+ }
81
+ }
82
+ static stopTracking() {
83
+ FTRumWebSocketTracking.stopNativeSession();
84
+ FTRumWebSocketTracking.enabled = false;
85
+ FTRumWebSocketTracking.resourceReporter = null;
86
+ if (!FTRumWebSocketTracking.installed) {
87
+ return;
88
+ }
89
+ const runtimeGlobal = globalThis;
90
+ if (runtimeGlobal.WebSocket === FTRumWebSocketTracking.instrumentedWebSocket && FTRumWebSocketTracking.originalWebSocket) {
91
+ try {
92
+ runtimeGlobal.WebSocket = FTRumWebSocketTracking.originalWebSocket;
93
+ if (runtimeGlobal.WebSocket !== FTRumWebSocketTracking.originalWebSocket) {
94
+ FTRumWebSocketTracking.warnOnce('Unable to restore WebSocket constructor.');
95
+ return;
96
+ }
97
+ FTRumWebSocketTracking.installed = false;
98
+ FTRumWebSocketTracking.originalWebSocket = null;
99
+ FTRumWebSocketTracking.instrumentedWebSocket = null;
100
+ } catch {
101
+ // The disabled wrapper remains a passthrough if another library froze it.
102
+ FTRumWebSocketTracking.warnOnce('Unable to restore WebSocket constructor.');
103
+ }
104
+ }
105
+ }
106
+ static createWebSocket(OriginalWebSocket, originalArguments, newTarget) {
107
+ if (!FTRumWebSocketTracking.enabled) {
108
+ return Reflect.construct(OriginalWebSocket, originalArguments, newTarget);
109
+ }
110
+ const resourceReporter = FTRumWebSocketTracking.resourceReporter;
111
+ if (!resourceReporter) {
112
+ return Reflect.construct(OriginalWebSocket, originalArguments, newTarget);
113
+ }
114
+
115
+ // Leave coercion and validation of nonstandard arguments to the constructor.
116
+ const url = originalArguments[0];
117
+ if (typeof url !== 'string') {
118
+ return Reflect.construct(OriginalWebSocket, originalArguments, newTarget);
119
+ }
120
+ const runtimeGlobal = globalThis;
121
+ if (runtimeGlobal.__DEV__ === true && REACT_NATIVE_DEV_WEBSOCKET.test(url)) {
122
+ return Reflect.construct(OriginalWebSocket, originalArguments, newTarget);
123
+ }
124
+ const options = originalArguments[2];
125
+ if (options !== undefined && (!options || typeof options !== 'object' || Array.isArray(options))) {
126
+ return Reflect.construct(OriginalWebSocket, originalArguments, newTarget);
127
+ }
128
+ const lifecycleVersion = FTRumWebSocketTracking.lifecycleVersion;
129
+ let resourceKey;
130
+ let traceKey;
131
+ let argumentsWithHeaders;
132
+ let requestHeaders;
133
+ try {
134
+ resourceKey = FTRumWebSocketTracking.createResourceKey();
135
+ // Generation may cache correlation before the bridge returns or throws.
136
+ if (FTRumWebSocketTracking.nativeAutoTraceEnabled) traceKey = resourceKey;
137
+ const traceHeaders = traceKey ? FTRumWebSocketTracking.getTraceHeaders(url, traceKey) : {};
138
+ ({
139
+ argumentsWithHeaders,
140
+ requestHeaders
141
+ } = FTRumWebSocketTracking.mergeTraceHeaders(originalArguments, traceHeaders));
142
+ } catch {
143
+ FTRumWebSocketTracking.cancelTrace(traceKey);
144
+ FTRumWebSocketTracking.warnOnce('Unable to prepare WebSocket tracking.');
145
+ return Reflect.construct(OriginalWebSocket, originalArguments, newTarget);
146
+ }
147
+ const stopTiming = startWebSocketTiming();
148
+ let socket;
149
+ let completed = false;
150
+ let cancelled = false;
151
+ let pendingCloseError;
152
+ let startPromise;
153
+ // Decide once before reporting. Never switch routes after an ambiguous
154
+ // native result: start/add may already have reached the SDK.
155
+ const nativeSession = FTRumWebSocketTracking.nativeSession;
156
+ let nativeResourceStarted = false;
157
+ const removeListeners = (keepFailureClose = false) => {
158
+ completed = true;
159
+ if (!keepFailureClose) {
160
+ pendingCloseError = undefined;
161
+ FTRumWebSocketTracking.pendingHandshakes.delete(cancelHandshake);
162
+ }
163
+ // Cleanup failures must neither interrupt business dispatch nor skip the
164
+ // other listeners. Completed guards also protect callbacks already queued.
165
+ const removers = keepFailureClose ? listenerRemovers.slice(0, 2) : listenerRemovers;
166
+ for (const remove of removers) {
167
+ try {
168
+ remove();
169
+ } catch {
170
+ FTRumWebSocketTracking.warnOnce('Unable to remove WebSocket listener.');
171
+ }
172
+ }
173
+ };
174
+ const releaseNativeResource = () => {
175
+ if (nativeResourceStarted) {
176
+ nativeResourceStarted = false;
177
+ nativeSession === null || nativeSession === void 0 || nativeSession.release(resourceKey);
178
+ }
179
+ };
180
+ const cancelHandshake = () => {
181
+ cancelled = true;
182
+ removeListeners();
183
+ releaseNativeResource();
184
+ };
185
+ const beginResource = () => {
186
+ if (!startPromise) {
187
+ nativeResourceStarted = nativeSession !== undefined;
188
+ const start = () => nativeSession ? nativeSession.startResource(resourceKey, webSocketNativeID(socket), url) : resourceReporter.startResource(resourceKey);
189
+ startPromise = FTRumWebSocketTracking.startResource(start).catch(() => {
190
+ cancelHandshake();
191
+ if (lifecycleVersion === FTRumWebSocketTracking.lifecycleVersion) {
192
+ FTRumWebSocketTracking.warnOnce('Unable to start WebSocket resource.');
193
+ }
194
+ return false;
195
+ });
196
+ }
197
+ return startPromise;
198
+ };
199
+ const complete = (resourceStatus, state, getError, event = 'error', supplementFailureClose = false) => {
200
+ if (completed) {
201
+ return;
202
+ }
203
+ completed = true;
204
+ const timing = stopTiming();
205
+ // Freeze the observed boundary before inspecting or parsing error data.
206
+ const error = getError === null || getError === void 0 ? void 0 : getError();
207
+ if (cancelled || lifecycleVersion !== FTRumWebSocketTracking.lifecycleVersion) {
208
+ removeListeners();
209
+ return;
210
+ }
211
+ let errorReady;
212
+ if (supplementFailureClose && error && !error.message) {
213
+ // RN's built-in EventTarget emits error without message, immediately
214
+ // followed by close(1006, nativeErrorMessage) in the same native-event
215
+ // callback. This also covers RN 0.79's opt-in implementation without
216
+ // guessing behavior from a version number. Freeze time and stop now;
217
+ // allow only that synchronous close to supplement the error text.
218
+ pendingCloseError = error;
219
+ removeListeners(true);
220
+ errorReady = Promise.resolve().then(() => removeListeners());
221
+ } else {
222
+ removeListeners();
223
+ }
224
+ const started = beginResource();
225
+ if (nativeSession) {
226
+ // Invoke stop at the event boundary, without waiting for the start
227
+ // promise or business callbacks. The native module processes in order.
228
+ void FTRumWebSocketTracking.completeNativeResource(nativeSession, lifecycleVersion, resourceKey, started, {
229
+ url,
230
+ httpMethod: 'GET',
231
+ requestHeader: requestHeaders,
232
+ webSocketEvent: event
233
+ }, timing, error, errorReady);
234
+ return;
235
+ }
236
+ void FTRumWebSocketTracking.completeResource(resourceReporter, lifecycleVersion, resourceKey, started, url, requestHeaders, resourceStatus, state, timing, error, errorReady);
237
+ };
238
+ const onOpen = () => complete(0, 'success', undefined, 'open');
239
+ const onError = event => {
240
+ complete(0, 'failed', () => FTRumWebSocketTracking.handshakeErrorFromEvent(event), 'error', true);
241
+ };
242
+ const onClose = event => {
243
+ if (pendingCloseError) {
244
+ const error = pendingCloseError;
245
+ const message = FTRumWebSocketTracking.failureMessageFromClose(event);
246
+ // Accessors can reenter shutdown. Do not restore a cancelled error.
247
+ if (pendingCloseError === error) error.message = message;
248
+ removeListeners();
249
+ return;
250
+ }
251
+ // A standalone close is only a terminal signal. Never interpret its
252
+ // business code/reason as a network error or as an HTTP response.
253
+ complete(0, 'failed', undefined, 'close');
254
+ };
255
+ const listenerRemovers = [() => {
256
+ var _socket;
257
+ return (_socket = socket) === null || _socket === void 0 ? void 0 : _socket.removeEventListener('open', onOpen);
258
+ }, () => {
259
+ var _socket2;
260
+ return (_socket2 = socket) === null || _socket2 === void 0 ? void 0 : _socket2.removeEventListener('error', onError);
261
+ }, () => {
262
+ var _socket3;
263
+ return (_socket3 = socket) === null || _socket3 === void 0 ? void 0 : _socket3.removeEventListener('close', onClose);
264
+ }];
265
+ try {
266
+ socket = Reflect.construct(OriginalWebSocket, argumentsWithHeaders, newTarget);
267
+ } catch (error) {
268
+ complete(0, 'failed', () => FTRumWebSocketTracking.toHandshakeError(error));
269
+ throw error;
270
+ }
271
+ try {
272
+ socket.addEventListener('open', onOpen);
273
+ socket.addEventListener('error', onError);
274
+ socket.addEventListener('close', onClose);
275
+ if (!completed) {
276
+ FTRumWebSocketTracking.pendingHandshakes.add(cancelHandshake);
277
+ // Do not leave a native Resource behind if listener installation fails.
278
+ beginResource();
279
+ }
280
+ } catch {
281
+ cancelHandshake();
282
+ // A reentrant terminal may already have started normal Resource reporting.
283
+ if (!startPromise) FTRumWebSocketTracking.cancelTrace(traceKey);
284
+ FTRumWebSocketTracking.warnOnce('Unable to observe WebSocket events.');
285
+ }
286
+ return socket;
287
+ }
288
+ static createResourceKey() {
289
+ return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, token => {
290
+ const randomNibble = Math.floor(Math.random() * 16);
291
+ const uuidNibble = token === 'x' ? randomNibble : randomNibble % 4 + 8;
292
+ return uuidNibble.toString(16);
293
+ });
294
+ }
295
+ static cancelTrace(key) {
296
+ if (!key) return;
297
+ try {
298
+ // Older native binaries do not expose this optional cancellation bridge.
299
+ if (typeof (NativeFTReactNativeTrace === null || NativeFTReactNativeTrace === void 0 ? void 0 : NativeFTReactNativeTrace.cancelWebSocketTrace) === 'function') {
300
+ void Promise.resolve(NativeFTReactNativeTrace.cancelWebSocketTrace(key)).catch(() => {});
301
+ }
302
+ } catch {
303
+ // Cleanup must never interrupt the business constructor or its exception.
304
+ }
305
+ }
306
+ static getTraceHeaders(url, resourceKey) {
307
+ try {
308
+ const headers = NativeFTReactNativeTrace === null || NativeFTReactNativeTrace === void 0 ? void 0 : NativeFTReactNativeTrace.getTraceHeaderFieldsSync(url, resourceKey);
309
+ return FTRumWebSocketTracking.toHeaderRecord(headers);
310
+ } catch {
311
+ FTRumWebSocketTracking.warnOnce('Unable to inject WebSocket trace headers.');
312
+ return {};
313
+ }
314
+ }
315
+ static mergeTraceHeaders(originalArguments, traceHeaders) {
316
+ const options = FTRumWebSocketTracking.toOptions(originalArguments[2]);
317
+ const requestHeaders = {
318
+ ...FTRumWebSocketTracking.toHeaderRecord(options.headers)
319
+ };
320
+ const traceHeaderEntries = Object.entries(traceHeaders);
321
+ if (traceHeaderEntries.length === 0) {
322
+ return {
323
+ argumentsWithHeaders: originalArguments,
324
+ requestHeaders
325
+ };
326
+ }
327
+ const traceHeaderNames = new Set(traceHeaderEntries.map(([key]) => key.toLowerCase()));
328
+ Object.keys(requestHeaders).forEach(key => {
329
+ if (traceHeaderNames.has(key.toLowerCase())) {
330
+ delete requestHeaders[key];
331
+ }
332
+ });
333
+ traceHeaderEntries.forEach(([key, value]) => {
334
+ requestHeaders[key] = value;
335
+ });
336
+ const argumentsWithHeaders = [...originalArguments];
337
+ // Read a headers accessor only once. Spreading options here would read it
338
+ // again before replacing it with the already captured header values.
339
+ const optionDescriptors = Object.getOwnPropertyDescriptors(options);
340
+ optionDescriptors.headers = {
341
+ configurable: true,
342
+ enumerable: true,
343
+ writable: true,
344
+ value: requestHeaders
345
+ };
346
+ argumentsWithHeaders[2] = Object.defineProperties({}, optionDescriptors);
347
+ return {
348
+ argumentsWithHeaders,
349
+ requestHeaders
350
+ };
351
+ }
352
+ static toOptions(value) {
353
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
354
+ return value;
355
+ }
356
+ return {};
357
+ }
358
+ static toHeaderRecord(value) {
359
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
360
+ return value;
361
+ }
362
+ return {};
363
+ }
364
+ static eventString(event, property) {
365
+ if (!event || typeof event !== 'object') {
366
+ return undefined;
367
+ }
368
+ try {
369
+ const value = event[property];
370
+ return typeof value === 'string' && value.length > 0 ? value : undefined;
371
+ } catch {
372
+ return undefined;
373
+ }
374
+ }
375
+ static handshakeErrorFromEvent(event) {
376
+ return {
377
+ message: FTRumWebSocketTracking.eventString(event, 'message')
378
+ };
379
+ }
380
+ static failureMessageFromClose(event) {
381
+ try {
382
+ if ((event === null || event === void 0 ? void 0 : event.code) === 1006) {
383
+ return FTRumWebSocketTracking.eventString(event, 'reason');
384
+ }
385
+ } catch {
386
+ // Optional event details must never interrupt business event dispatch.
387
+ }
388
+ return undefined;
389
+ }
390
+ static statusFromError(message) {
391
+ const match = message && message.length <= MAX_HTTP_ERROR_PARSE_LENGTH ? SOCKET_ROCKET_HTTP_ERROR.exec(message.trim()) : null;
392
+ return match ? Number(match[1]) : undefined;
393
+ }
394
+ static toHandshakeError(error) {
395
+ try {
396
+ return {
397
+ message: error instanceof Error ? error.message || error.name : String(error)
398
+ };
399
+ } catch {
400
+ return {};
401
+ }
402
+ }
403
+ static startResource(start) {
404
+ try {
405
+ return Promise.resolve(start()).then(() => true);
406
+ } catch (error) {
407
+ return Promise.reject(error);
408
+ }
409
+ }
410
+ static async completeResource(resourceReporter, lifecycleVersion, resourceKey, startPromise, url, requestHeader, resourceStatus, webSocketHandshakeState, timing, error, errorReady) {
411
+ const isCurrentLifecycle = () => lifecycleVersion === FTRumWebSocketTracking.lifecycleVersion;
412
+ try {
413
+ if (!(await startPromise) || !isCurrentLifecycle()) {
414
+ return;
415
+ }
416
+ try {
417
+ await resourceReporter.stopResource(resourceKey);
418
+ } catch {
419
+ // addResource completes the native Resource. Attempt it even if stop
420
+ // failed, but never retry addResource and risk duplicate completion.
421
+ if (isCurrentLifecycle()) {
422
+ FTRumWebSocketTracking.warnOnce('Unable to stop WebSocket resource.');
423
+ }
424
+ }
425
+ if (errorReady) await errorReady;
426
+ // Only old native binaries classify in JS. Resolve supplemental text
427
+ // before normalization; duration was frozen at the first terminal event.
428
+ const httpStatus = FTRumWebSocketTracking.statusFromError(error === null || error === void 0 ? void 0 : error.message);
429
+ if (httpStatus !== undefined && webSocketHandshakeState !== 'success') {
430
+ resourceStatus = httpStatus;
431
+ webSocketHandshakeState = httpStatus !== 101 ? 'rejected' : 'failed';
432
+ }
433
+ const resource = {
434
+ url,
435
+ httpMethod: 'GET',
436
+ requestHeader,
437
+ resourceStatus,
438
+ resourceType: 'websocket',
439
+ webSocketHandshake: true,
440
+ webSocketHandshakeState
441
+ };
442
+ if (error !== null && error !== void 0 && error.message) resource.errorMessage = error.message;
443
+ if (isCurrentLifecycle()) {
444
+ await resourceReporter.addResource(resourceKey, resource, timing);
445
+ }
446
+ } catch {
447
+ if (isCurrentLifecycle()) {
448
+ FTRumWebSocketTracking.warnOnce('Unable to report WebSocket resource.');
449
+ }
450
+ }
451
+ }
452
+ static async completeNativeResource(session, lifecycleVersion, key, started, content, timing, error, errorReady) {
453
+ // Attach rejection handling immediately, including when start never settles.
454
+ let stopped;
455
+ try {
456
+ stopped = Promise.resolve(session.stopResource(key, content.webSocketEvent)).catch(() => {
457
+ if (lifecycleVersion === FTRumWebSocketTracking.lifecycleVersion) FTRumWebSocketTracking.warnOnce('Unable to stop WebSocket resource.');
458
+ });
459
+ } catch {
460
+ stopped = Promise.resolve();
461
+ }
462
+ try {
463
+ if (!(await started)) return;
464
+ await stopped;
465
+ if (errorReady) await errorReady;
466
+ if (lifecycleVersion !== FTRumWebSocketTracking.lifecycleVersion) return;
467
+ await session.addResource(key, error !== null && error !== void 0 && error.message ? {
468
+ ...content,
469
+ errorMessage: error.message
470
+ } : content, timing !== null && timing !== void 0 ? timing : {});
471
+ } catch {
472
+ session.release(key);
473
+ if (lifecycleVersion === FTRumWebSocketTracking.lifecycleVersion) FTRumWebSocketTracking.warnOnce('Unable to report WebSocket resource.');
474
+ }
475
+ }
476
+ static warnOnce(message) {
477
+ if (FTRumWebSocketTracking.warnedFailures.has(message)) {
478
+ return;
479
+ }
480
+ FTRumWebSocketTracking.warnedFailures.add(message);
481
+ try {
482
+ console.warn(`[FT-SDK] ${message}`);
483
+ } catch {
484
+ // A host-provided logger must not turn instrumentation failure into one
485
+ // on the application's constructor, event dispatch or promise chain.
486
+ }
487
+ }
488
+ }
489
+ _defineProperty(FTRumWebSocketTracking, "enabled", false);
490
+ _defineProperty(FTRumWebSocketTracking, "installed", false);
491
+ _defineProperty(FTRumWebSocketTracking, "originalWebSocket", null);
492
+ _defineProperty(FTRumWebSocketTracking, "instrumentedWebSocket", null);
493
+ _defineProperty(FTRumWebSocketTracking, "resourceReporter", null);
494
+ _defineProperty(FTRumWebSocketTracking, "nativeAutoTraceEnabled", false);
495
+ _defineProperty(FTRumWebSocketTracking, "warnedFailures", new Set());
496
+ _defineProperty(FTRumWebSocketTracking, "lifecycleVersion", 0);
497
+ _defineProperty(FTRumWebSocketTracking, "nativeSession", void 0);
498
+ _defineProperty(FTRumWebSocketTracking, "pendingHandshakes", new Set());
499
+ //# sourceMappingURL=FTRumWebSocketTracking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Platform","NativeFTReactNativeTrace","startWebSocketTiming","clearNativeWebSocketSessions","startNativeWebSocketSession","webSocketNativeID","REACT_NATIVE_DEV_WEBSOCKET","SOCKET_ROCKET_HTTP_ERROR","MAX_HTTP_ERROR_PARSE_LENGTH","FTRumWebSocketTracking","getLifecycleVersion","lifecycleVersion","shutDown","setNativeAutoTraceEnabled","stopTracking","pendingHandshakes","forEach","removeListeners","clear","warnedFailures","enabled","nativeAutoTraceEnabled","stopNativeSession","_FTRumWebSocketTracki","nativeSession","stop","undefined","startTracking","resourceReporter","OS","runtimeGlobal","globalThis","originalWebSocket","WebSocket","instrumentedWebSocket","createResourceKey","InstrumentedWebSocket","args","new","target","Reflect","apply","construct","createWebSocket","prototype","Object","setPrototypeOf","warnOnce","installed","OriginalWebSocket","originalArguments","newTarget","url","__DEV__","test","options","Array","isArray","resourceKey","traceKey","argumentsWithHeaders","requestHeaders","traceHeaders","getTraceHeaders","mergeTraceHeaders","cancelTrace","stopTiming","socket","completed","cancelled","pendingCloseError","startPromise","nativeResourceStarted","keepFailureClose","delete","cancelHandshake","removers","listenerRemovers","slice","remove","releaseNativeResource","release","beginResource","start","startResource","catch","complete","resourceStatus","state","getError","event","supplementFailureClose","timing","error","errorReady","message","Promise","resolve","then","started","completeNativeResource","httpMethod","requestHeader","webSocketEvent","completeResource","onOpen","onError","handshakeErrorFromEvent","onClose","failureMessageFromClose","_socket","removeEventListener","_socket2","_socket3","toHandshakeError","addEventListener","add","replace","token","randomNibble","Math","floor","random","uuidNibble","toString","key","cancelWebSocketTrace","headers","getTraceHeaderFieldsSync","toHeaderRecord","toOptions","traceHeaderEntries","entries","length","traceHeaderNames","Set","map","toLowerCase","keys","has","value","optionDescriptors","getOwnPropertyDescriptors","configurable","enumerable","writable","defineProperties","eventString","property","code","statusFromError","match","exec","trim","Number","Error","name","String","reject","webSocketHandshakeState","isCurrentLifecycle","stopResource","httpStatus","resource","resourceType","webSocketHandshake","errorMessage","addResource","session","content","stopped","console","warn","_defineProperty"],"sources":["FTRumWebSocketTracking.ts"],"sourcesContent":["/* global WebSocket */\nimport { Platform } from 'react-native';\nimport NativeFTReactNativeTrace from '../specs/NativeFTReactNativeTrace';\nimport { startWebSocketTiming } from './FTRumWebSocketTiming';\nimport type { WebSocketTimingMetrics } from './FTRumWebSocketTiming';\nimport {\n clearNativeWebSocketSessions,\n startNativeWebSocketSession,\n webSocketNativeID,\n} from './FTRumWebSocketNative';\nimport type {\n NativeWebSocketSession,\n NativeWebSocketResource,\n} from './FTRumWebSocketNative';\n\ntype WebSocketConstructor = typeof WebSocket;\ntype WebSocketHandshakeState = 'success' | 'rejected' | 'failed';\n\ninterface ReactNativeWebSocketOptions {\n headers?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\ninterface FTRUMWebSocketResource {\n url: string;\n httpMethod: string;\n requestHeader: Record<string, unknown>;\n resourceStatus: number;\n responseHeader?: Record<string, string>;\n resourceType: 'websocket';\n webSocketHandshake: true;\n webSocketHandshakeState: WebSocketHandshakeState;\n errorMessage?: string;\n}\n\ninterface WebSocketHandshakeError {\n message?: string;\n}\n\ninterface FTRumWebSocketResourceReporter {\n startResource(key: string): Promise<void>;\n stopResource(key: string): Promise<void>;\n addResource(\n key: string,\n resource: FTRUMWebSocketResource,\n metrics?: WebSocketTimingMetrics\n ): Promise<void>;\n}\n\ntype RuntimeGlobal = typeof globalThis & {\n WebSocket: WebSocketConstructor;\n __DEV__?: boolean;\n};\n\nconst REACT_NATIVE_DEV_WEBSOCKET =\n /^wss?:\\/\\/(?:(?:10|172|192)\\.[0-9]+\\.[0-9]+\\.[0-9]+|localhost|127\\.0\\.0\\.1|\\[::1\\]):808[0-9]\\/(?:hot|symbolicate|message|inspector|status|assets|logs|debugger-proxy)(?:[/?#].*)?$/i;\n\n// SocketRocket embeds the actual response status in this description, which\n// RCTWebSocketModule forwards to JS. Do not match proxy errors or bare numbers.\nconst SOCKET_ROCKET_HTTP_ERROR =\n /^Received\\s+bad\\s+response\\s+code\\s+from\\s+server\\s*:\\s*([1-9]\\d{2})\\s*\\.?$/i;\nconst MAX_HTTP_ERROR_PARSE_LENGTH = 512;\n\nexport class FTRumWebSocketTracking {\n private static enabled = false;\n private static installed = false;\n private static originalWebSocket: WebSocketConstructor | null = null;\n private static instrumentedWebSocket: WebSocketConstructor | null = null;\n private static resourceReporter: FTRumWebSocketResourceReporter | null = null;\n private static nativeAutoTraceEnabled = false;\n private static warnedFailures = new Set<string>();\n private static lifecycleVersion = 0;\n private static nativeSession: NativeWebSocketSession | undefined;\n private static pendingHandshakes = new Set<() => void>();\n\n /** Identifies configuration and reporting work started before SDK shutdown. */\n static getLifecycleVersion(): number {\n return FTRumWebSocketTracking.lifecycleVersion;\n }\n\n static shutDown(): void {\n FTRumWebSocketTracking.lifecycleVersion += 1;\n clearNativeWebSocketSessions();\n FTRumWebSocketTracking.setNativeAutoTraceEnabled(false);\n FTRumWebSocketTracking.stopTracking();\n FTRumWebSocketTracking.pendingHandshakes.forEach((removeListeners) =>\n removeListeners()\n );\n FTRumWebSocketTracking.pendingHandshakes.clear();\n FTRumWebSocketTracking.warnedFailures.clear();\n }\n\n static setNativeAutoTraceEnabled(enabled: boolean): void {\n FTRumWebSocketTracking.nativeAutoTraceEnabled = enabled;\n }\n\n private static stopNativeSession(): void {\n FTRumWebSocketTracking.nativeSession?.stop();\n FTRumWebSocketTracking.nativeSession = undefined;\n }\n\n static startTracking(resourceReporter: FTRumWebSocketResourceReporter): void {\n if (Platform.OS !== 'ios') {\n return;\n }\n\n FTRumWebSocketTracking.enabled = true;\n FTRumWebSocketTracking.resourceReporter = resourceReporter;\n const runtimeGlobal = globalThis as RuntimeGlobal;\n const originalWebSocket = runtimeGlobal.WebSocket;\n if (originalWebSocket === FTRumWebSocketTracking.instrumentedWebSocket) {\n return;\n }\n if (typeof originalWebSocket !== 'function') {\n FTRumWebSocketTracking.stopNativeSession();\n return;\n }\n\n if (!FTRumWebSocketTracking.nativeSession) {\n FTRumWebSocketTracking.nativeSession = startNativeWebSocketSession(() =>\n FTRumWebSocketTracking.createResourceKey()\n );\n }\n\n const InstrumentedWebSocket = function (\n this: WebSocket,\n ...args: unknown[]\n ): WebSocket {\n if (!new.target) {\n return Reflect.apply(originalWebSocket, this, args);\n }\n // A constructor retained before stop/reinitialization must stay passive.\n if (\n FTRumWebSocketTracking.instrumentedWebSocket !== InstrumentedWebSocket\n ) {\n return Reflect.construct(originalWebSocket, args, new.target);\n }\n return FTRumWebSocketTracking.createWebSocket(\n originalWebSocket,\n args,\n new.target as unknown as WebSocketConstructor\n );\n } as unknown as WebSocketConstructor;\n\n try {\n InstrumentedWebSocket.prototype = originalWebSocket.prototype;\n Object.setPrototypeOf(InstrumentedWebSocket, originalWebSocket);\n runtimeGlobal.WebSocket = InstrumentedWebSocket;\n if (runtimeGlobal.WebSocket !== InstrumentedWebSocket) {\n FTRumWebSocketTracking.warnOnce(\n 'Unable to install WebSocket tracking.'\n );\n FTRumWebSocketTracking.stopNativeSession();\n return;\n }\n FTRumWebSocketTracking.originalWebSocket = originalWebSocket;\n FTRumWebSocketTracking.instrumentedWebSocket = InstrumentedWebSocket;\n FTRumWebSocketTracking.installed = true;\n } catch {\n FTRumWebSocketTracking.stopNativeSession();\n FTRumWebSocketTracking.warnOnce('Unable to install WebSocket tracking.');\n }\n }\n\n static stopTracking(): void {\n FTRumWebSocketTracking.stopNativeSession();\n FTRumWebSocketTracking.enabled = false;\n FTRumWebSocketTracking.resourceReporter = null;\n if (!FTRumWebSocketTracking.installed) {\n return;\n }\n\n const runtimeGlobal = globalThis as RuntimeGlobal;\n if (\n runtimeGlobal.WebSocket ===\n FTRumWebSocketTracking.instrumentedWebSocket &&\n FTRumWebSocketTracking.originalWebSocket\n ) {\n try {\n runtimeGlobal.WebSocket = FTRumWebSocketTracking.originalWebSocket;\n if (\n runtimeGlobal.WebSocket !== FTRumWebSocketTracking.originalWebSocket\n ) {\n FTRumWebSocketTracking.warnOnce(\n 'Unable to restore WebSocket constructor.'\n );\n return;\n }\n FTRumWebSocketTracking.installed = false;\n FTRumWebSocketTracking.originalWebSocket = null;\n FTRumWebSocketTracking.instrumentedWebSocket = null;\n } catch {\n // The disabled wrapper remains a passthrough if another library froze it.\n FTRumWebSocketTracking.warnOnce(\n 'Unable to restore WebSocket constructor.'\n );\n }\n }\n }\n\n private static createWebSocket(\n OriginalWebSocket: WebSocketConstructor,\n originalArguments: unknown[],\n newTarget: WebSocketConstructor\n ): WebSocket {\n if (!FTRumWebSocketTracking.enabled) {\n return Reflect.construct(OriginalWebSocket, originalArguments, newTarget);\n }\n\n const resourceReporter = FTRumWebSocketTracking.resourceReporter;\n if (!resourceReporter) {\n return Reflect.construct(OriginalWebSocket, originalArguments, newTarget);\n }\n\n // Leave coercion and validation of nonstandard arguments to the constructor.\n const url = originalArguments[0];\n if (typeof url !== 'string') {\n return Reflect.construct(OriginalWebSocket, originalArguments, newTarget);\n }\n const runtimeGlobal = globalThis as RuntimeGlobal;\n if (\n runtimeGlobal.__DEV__ === true &&\n REACT_NATIVE_DEV_WEBSOCKET.test(url)\n ) {\n return Reflect.construct(OriginalWebSocket, originalArguments, newTarget);\n }\n\n const options = originalArguments[2];\n if (\n options !== undefined &&\n (!options || typeof options !== 'object' || Array.isArray(options))\n ) {\n return Reflect.construct(OriginalWebSocket, originalArguments, newTarget);\n }\n const lifecycleVersion = FTRumWebSocketTracking.lifecycleVersion;\n let resourceKey: string;\n let traceKey: string | undefined;\n let argumentsWithHeaders: unknown[];\n let requestHeaders: Record<string, unknown>;\n try {\n resourceKey = FTRumWebSocketTracking.createResourceKey();\n // Generation may cache correlation before the bridge returns or throws.\n if (FTRumWebSocketTracking.nativeAutoTraceEnabled) traceKey = resourceKey;\n const traceHeaders = traceKey\n ? FTRumWebSocketTracking.getTraceHeaders(url, traceKey)\n : {};\n ({ argumentsWithHeaders, requestHeaders } =\n FTRumWebSocketTracking.mergeTraceHeaders(\n originalArguments,\n traceHeaders\n ));\n } catch {\n FTRumWebSocketTracking.cancelTrace(traceKey);\n FTRumWebSocketTracking.warnOnce('Unable to prepare WebSocket tracking.');\n return Reflect.construct(OriginalWebSocket, originalArguments, newTarget);\n }\n\n const stopTiming = startWebSocketTiming();\n let socket: WebSocket;\n let completed = false;\n let cancelled = false;\n let pendingCloseError: WebSocketHandshakeError | undefined;\n let startPromise: Promise<boolean> | undefined;\n // Decide once before reporting. Never switch routes after an ambiguous\n // native result: start/add may already have reached the SDK.\n const nativeSession = FTRumWebSocketTracking.nativeSession;\n let nativeResourceStarted = false;\n const removeListeners = (keepFailureClose = false) => {\n completed = true;\n if (!keepFailureClose) {\n pendingCloseError = undefined;\n FTRumWebSocketTracking.pendingHandshakes.delete(cancelHandshake);\n }\n // Cleanup failures must neither interrupt business dispatch nor skip the\n // other listeners. Completed guards also protect callbacks already queued.\n const removers = keepFailureClose\n ? listenerRemovers.slice(0, 2)\n : listenerRemovers;\n for (const remove of removers) {\n try {\n remove();\n } catch {\n FTRumWebSocketTracking.warnOnce(\n 'Unable to remove WebSocket listener.'\n );\n }\n }\n };\n const releaseNativeResource = () => {\n if (nativeResourceStarted) {\n nativeResourceStarted = false;\n nativeSession?.release(resourceKey);\n }\n };\n const cancelHandshake = () => {\n cancelled = true;\n removeListeners();\n releaseNativeResource();\n };\n const beginResource = () => {\n if (!startPromise) {\n nativeResourceStarted = nativeSession !== undefined;\n const start = () =>\n nativeSession\n ? nativeSession.startResource(\n resourceKey,\n webSocketNativeID(socket),\n url\n )\n : resourceReporter.startResource(resourceKey);\n startPromise = FTRumWebSocketTracking.startResource(start).catch(() => {\n cancelHandshake();\n if (lifecycleVersion === FTRumWebSocketTracking.lifecycleVersion) {\n FTRumWebSocketTracking.warnOnce(\n 'Unable to start WebSocket resource.'\n );\n }\n return false;\n });\n }\n return startPromise;\n };\n const complete = (\n resourceStatus: number,\n state: WebSocketHandshakeState,\n getError?: () => WebSocketHandshakeError,\n event: 'open' | 'error' | 'close' = 'error',\n supplementFailureClose = false\n ) => {\n if (completed) {\n return;\n }\n completed = true;\n const timing = stopTiming();\n // Freeze the observed boundary before inspecting or parsing error data.\n const error = getError?.();\n if (\n cancelled ||\n lifecycleVersion !== FTRumWebSocketTracking.lifecycleVersion\n ) {\n removeListeners();\n return;\n }\n let errorReady: Promise<void> | undefined;\n if (supplementFailureClose && error && !error.message) {\n // RN's built-in EventTarget emits error without message, immediately\n // followed by close(1006, nativeErrorMessage) in the same native-event\n // callback. This also covers RN 0.79's opt-in implementation without\n // guessing behavior from a version number. Freeze time and stop now;\n // allow only that synchronous close to supplement the error text.\n pendingCloseError = error;\n removeListeners(true);\n errorReady = Promise.resolve().then(() => removeListeners());\n } else {\n removeListeners();\n }\n const started = beginResource();\n if (nativeSession) {\n // Invoke stop at the event boundary, without waiting for the start\n // promise or business callbacks. The native module processes in order.\n void FTRumWebSocketTracking.completeNativeResource(\n nativeSession,\n lifecycleVersion,\n resourceKey,\n started,\n {\n url,\n httpMethod: 'GET',\n requestHeader: requestHeaders,\n webSocketEvent: event,\n },\n timing,\n error,\n errorReady\n );\n return;\n }\n void FTRumWebSocketTracking.completeResource(\n resourceReporter,\n lifecycleVersion,\n resourceKey,\n started,\n url,\n requestHeaders,\n resourceStatus,\n state,\n timing,\n error,\n errorReady\n );\n };\n const onOpen = () => complete(0, 'success', undefined, 'open');\n const onError = (event: Event) => {\n complete(\n 0,\n 'failed',\n () => FTRumWebSocketTracking.handshakeErrorFromEvent(event),\n 'error',\n true\n );\n };\n const onClose = (event: Event) => {\n if (pendingCloseError) {\n const error = pendingCloseError;\n const message = FTRumWebSocketTracking.failureMessageFromClose(event);\n // Accessors can reenter shutdown. Do not restore a cancelled error.\n if (pendingCloseError === error) error.message = message;\n removeListeners();\n return;\n }\n // A standalone close is only a terminal signal. Never interpret its\n // business code/reason as a network error or as an HTTP response.\n complete(0, 'failed', undefined, 'close');\n };\n const listenerRemovers = [\n () => socket?.removeEventListener('open', onOpen),\n () => socket?.removeEventListener('error', onError),\n () => socket?.removeEventListener('close', onClose),\n ];\n\n try {\n socket = Reflect.construct(\n OriginalWebSocket,\n argumentsWithHeaders,\n newTarget\n );\n } catch (error) {\n complete(0, 'failed', () =>\n FTRumWebSocketTracking.toHandshakeError(error)\n );\n throw error;\n }\n\n try {\n socket.addEventListener('open', onOpen);\n socket.addEventListener('error', onError);\n socket.addEventListener('close', onClose);\n if (!completed) {\n FTRumWebSocketTracking.pendingHandshakes.add(cancelHandshake);\n // Do not leave a native Resource behind if listener installation fails.\n beginResource();\n }\n } catch {\n cancelHandshake();\n // A reentrant terminal may already have started normal Resource reporting.\n if (!startPromise) FTRumWebSocketTracking.cancelTrace(traceKey);\n FTRumWebSocketTracking.warnOnce('Unable to observe WebSocket events.');\n }\n return socket;\n }\n\n private static createResourceKey(): string {\n return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, (token) => {\n const randomNibble = Math.floor(Math.random() * 16);\n const uuidNibble = token === 'x' ? randomNibble : (randomNibble % 4) + 8;\n return uuidNibble.toString(16);\n });\n }\n\n private static cancelTrace(key: string | undefined): void {\n if (!key) return;\n try {\n // Older native binaries do not expose this optional cancellation bridge.\n if (\n typeof NativeFTReactNativeTrace?.cancelWebSocketTrace === 'function'\n ) {\n void Promise.resolve(\n NativeFTReactNativeTrace.cancelWebSocketTrace(key)\n ).catch(() => {});\n }\n } catch {\n // Cleanup must never interrupt the business constructor or its exception.\n }\n }\n\n private static getTraceHeaders(\n url: string,\n resourceKey: string\n ): Record<string, unknown> {\n try {\n const headers = NativeFTReactNativeTrace?.getTraceHeaderFieldsSync(\n url,\n resourceKey\n );\n return FTRumWebSocketTracking.toHeaderRecord(headers);\n } catch {\n FTRumWebSocketTracking.warnOnce(\n 'Unable to inject WebSocket trace headers.'\n );\n return {};\n }\n }\n\n private static mergeTraceHeaders(\n originalArguments: unknown[],\n traceHeaders: Record<string, unknown>\n ): {\n argumentsWithHeaders: unknown[];\n requestHeaders: Record<string, unknown>;\n } {\n const options = FTRumWebSocketTracking.toOptions(originalArguments[2]);\n const requestHeaders = {\n ...FTRumWebSocketTracking.toHeaderRecord(options.headers),\n };\n const traceHeaderEntries = Object.entries(traceHeaders);\n\n if (traceHeaderEntries.length === 0) {\n return {\n argumentsWithHeaders: originalArguments,\n requestHeaders,\n };\n }\n\n const traceHeaderNames = new Set(\n traceHeaderEntries.map(([key]) => key.toLowerCase())\n );\n Object.keys(requestHeaders).forEach((key) => {\n if (traceHeaderNames.has(key.toLowerCase())) {\n delete requestHeaders[key];\n }\n });\n traceHeaderEntries.forEach(([key, value]) => {\n requestHeaders[key] = value;\n });\n\n const argumentsWithHeaders = [...originalArguments];\n // Read a headers accessor only once. Spreading options here would read it\n // again before replacing it with the already captured header values.\n const optionDescriptors = Object.getOwnPropertyDescriptors(options);\n optionDescriptors.headers = {\n configurable: true,\n enumerable: true,\n writable: true,\n value: requestHeaders,\n };\n argumentsWithHeaders[2] = Object.defineProperties({}, optionDescriptors);\n return { argumentsWithHeaders, requestHeaders };\n }\n\n private static toOptions(value: unknown): ReactNativeWebSocketOptions {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n return value as ReactNativeWebSocketOptions;\n }\n return {};\n }\n\n private static toHeaderRecord(value: unknown): Record<string, unknown> {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return {};\n }\n\n private static eventString(\n event: unknown,\n property: string\n ): string | undefined {\n if (!event || typeof event !== 'object') {\n return undefined;\n }\n try {\n const value = (event as Record<string, unknown>)[property];\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n } catch {\n return undefined;\n }\n }\n\n private static handshakeErrorFromEvent(\n event: Event\n ): WebSocketHandshakeError {\n return { message: FTRumWebSocketTracking.eventString(event, 'message') };\n }\n\n private static failureMessageFromClose(event: Event): string | undefined {\n try {\n if ((event as Event & { code?: unknown })?.code === 1006) {\n return FTRumWebSocketTracking.eventString(event, 'reason');\n }\n } catch {\n // Optional event details must never interrupt business event dispatch.\n }\n return undefined;\n }\n\n private static statusFromError(\n message: string | undefined\n ): number | undefined {\n const match =\n message && message.length <= MAX_HTTP_ERROR_PARSE_LENGTH\n ? SOCKET_ROCKET_HTTP_ERROR.exec(message.trim())\n : null;\n return match ? Number(match[1]) : undefined;\n }\n\n private static toHandshakeError(error: unknown): WebSocketHandshakeError {\n try {\n return {\n message:\n error instanceof Error ? error.message || error.name : String(error),\n };\n } catch {\n return {};\n }\n }\n\n private static startResource(start: () => Promise<void>): Promise<boolean> {\n try {\n return Promise.resolve(start()).then(() => true);\n } catch (error) {\n return Promise.reject(error);\n }\n }\n\n private static async completeResource(\n resourceReporter: FTRumWebSocketResourceReporter,\n lifecycleVersion: number,\n resourceKey: string,\n startPromise: Promise<boolean>,\n url: string,\n requestHeader: Record<string, unknown>,\n resourceStatus: number,\n webSocketHandshakeState: WebSocketHandshakeState,\n timing: WebSocketTimingMetrics | undefined,\n error?: WebSocketHandshakeError,\n errorReady?: Promise<void>\n ): Promise<void> {\n const isCurrentLifecycle = () =>\n lifecycleVersion === FTRumWebSocketTracking.lifecycleVersion;\n try {\n if (!(await startPromise) || !isCurrentLifecycle()) {\n return;\n }\n try {\n await resourceReporter.stopResource(resourceKey);\n } catch {\n // addResource completes the native Resource. Attempt it even if stop\n // failed, but never retry addResource and risk duplicate completion.\n if (isCurrentLifecycle()) {\n FTRumWebSocketTracking.warnOnce('Unable to stop WebSocket resource.');\n }\n }\n if (errorReady) await errorReady;\n // Only old native binaries classify in JS. Resolve supplemental text\n // before normalization; duration was frozen at the first terminal event.\n const httpStatus = FTRumWebSocketTracking.statusFromError(error?.message);\n if (httpStatus !== undefined && webSocketHandshakeState !== 'success') {\n resourceStatus = httpStatus;\n webSocketHandshakeState = httpStatus !== 101 ? 'rejected' : 'failed';\n }\n const resource: FTRUMWebSocketResource = {\n url,\n httpMethod: 'GET',\n requestHeader,\n resourceStatus,\n resourceType: 'websocket',\n webSocketHandshake: true,\n webSocketHandshakeState,\n };\n if (error?.message) resource.errorMessage = error.message;\n if (isCurrentLifecycle()) {\n await resourceReporter.addResource(resourceKey, resource, timing);\n }\n } catch {\n if (isCurrentLifecycle()) {\n FTRumWebSocketTracking.warnOnce('Unable to report WebSocket resource.');\n }\n }\n }\n\n private static async completeNativeResource(\n session: NativeWebSocketSession,\n lifecycleVersion: number,\n key: string,\n started: Promise<boolean>,\n content: NativeWebSocketResource,\n timing: WebSocketTimingMetrics | undefined,\n error?: WebSocketHandshakeError,\n errorReady?: Promise<void>\n ): Promise<void> {\n // Attach rejection handling immediately, including when start never settles.\n let stopped: Promise<void>;\n try {\n stopped = Promise.resolve(\n session.stopResource(key, content.webSocketEvent)\n ).catch(() => {\n if (lifecycleVersion === FTRumWebSocketTracking.lifecycleVersion)\n FTRumWebSocketTracking.warnOnce('Unable to stop WebSocket resource.');\n });\n } catch {\n stopped = Promise.resolve();\n }\n try {\n if (!(await started)) return;\n await stopped;\n if (errorReady) await errorReady;\n if (lifecycleVersion !== FTRumWebSocketTracking.lifecycleVersion) return;\n await session.addResource(\n key,\n error?.message ? { ...content, errorMessage: error.message } : content,\n timing ?? {}\n );\n } catch {\n session.release(key);\n if (lifecycleVersion === FTRumWebSocketTracking.lifecycleVersion)\n FTRumWebSocketTracking.warnOnce('Unable to report WebSocket resource.');\n }\n }\n\n private static warnOnce(message: string): void {\n if (FTRumWebSocketTracking.warnedFailures.has(message)) {\n return;\n }\n FTRumWebSocketTracking.warnedFailures.add(message);\n try {\n console.warn(`[FT-SDK] ${message}`);\n } catch {\n // A host-provided logger must not turn instrumentation failure into one\n // on the application's constructor, event dispatch or promise chain.\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,18 @@
1
+ export const MIN_LONG_TASK_THRESHOLD_MS = 100;
2
+ export const MAX_LONG_TASK_THRESHOLD_MS = 5000;
3
+ export const DEFAULT_LONG_TASK_THRESHOLD_MS = 100;
4
+
5
+ /**
6
+ * Converts the public JavaScript long task option to the numeric value expected
7
+ * by the native bridge. Enablement is controlled separately.
8
+ */
9
+ export function normalizeLongTaskThreshold(threshold) {
10
+ if (!threshold) {
11
+ return DEFAULT_LONG_TASK_THRESHOLD_MS;
12
+ }
13
+ if (threshold < MIN_LONG_TASK_THRESHOLD_MS) {
14
+ return MIN_LONG_TASK_THRESHOLD_MS;
15
+ }
16
+ return Math.min(threshold, MAX_LONG_TASK_THRESHOLD_MS);
17
+ }
18
+ //# sourceMappingURL=longTasksUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["MIN_LONG_TASK_THRESHOLD_MS","MAX_LONG_TASK_THRESHOLD_MS","DEFAULT_LONG_TASK_THRESHOLD_MS","normalizeLongTaskThreshold","threshold","Math","min"],"sources":["longTasksUtils.ts"],"sourcesContent":["export const MIN_LONG_TASK_THRESHOLD_MS = 100;\nexport const MAX_LONG_TASK_THRESHOLD_MS = 5000;\nexport const DEFAULT_LONG_TASK_THRESHOLD_MS = 100;\n\n/**\n * Converts the public JavaScript long task option to the numeric value expected\n * by the native bridge. Enablement is controlled separately.\n */\nexport function normalizeLongTaskThreshold(threshold?: number): number {\n if (!threshold) {\n return DEFAULT_LONG_TASK_THRESHOLD_MS;\n }\n if (threshold < MIN_LONG_TASK_THRESHOLD_MS) {\n return MIN_LONG_TASK_THRESHOLD_MS;\n }\n return Math.min(threshold, MAX_LONG_TASK_THRESHOLD_MS);\n}\n"],"mappings":"AAAA,OAAO,MAAMA,0BAA0B,GAAG,GAAG;AAC7C,OAAO,MAAMC,0BAA0B,GAAG,IAAI;AAC9C,OAAO,MAAMC,8BAA8B,GAAG,GAAG;;AAEjD;AACA;AACA;AACA;AACA,OAAO,SAASC,0BAA0BA,CAACC,SAAkB,EAAU;EACrE,IAAI,CAACA,SAAS,EAAE;IACd,OAAOF,8BAA8B;EACvC;EACA,IAAIE,SAAS,GAAGJ,0BAA0B,EAAE;IAC1C,OAAOA,0BAA0B;EACnC;EACA,OAAOK,IAAI,CAACC,GAAG,CAACF,SAAS,EAAEH,0BAA0B,CAAC;AACxD","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["TurboModuleRegistry","get"],"sources":["NativeFTMobileReactNative.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\nimport type { TurboModule } from 'react-native';\nimport { TurboModuleRegistry } from 'react-native';\n\nexport interface Spec extends TurboModule {\n /**\n * SDK initialization method.\n * @param config SDK initialization configuration items.\n * @returns a Promise.\n */\n sdkConfig(config: Object): Promise<void>;\n /**\n * Dynamically set the Datakit upload URL after SDK initialization.\n * @param datakitUrl Datakit upload URL.\n * @returns a Promise.\n */\n setDatakitURL(datakitUrl: string): Promise<void>;\n /**\n * Dynamically set the Dataway upload URL and client token after SDK initialization.\n * @param datawayUrl Dataway upload URL.\n * @param clientToken Dataway authentication token.\n * @returns a Promise.\n */\n setDatawayURL(datawayUrl: string, clientToken: string): Promise<void>;\n /**\n * Bind user.\n * @param userId user ID.\n * @param userName user name.\n * @param userEmail user email\n * @param extra additional user information\n * @returns a Promise.\n */\n bindRUMUserData(\n userId: string,\n userName?: string,\n userEmail?: string,\n extra?: Object\n ): Promise<void>;\n /**\n * Unbind user.\n * @returns a Promise.\n */\n unbindRUMUserData(): Promise<void>;\n /**\n * Add custom global parameters. Applies to RUM and Log data\n * @param context custom global parameters.\n * @returns a Promise.\n */\n appendGlobalContext(context: Object): Promise<void>;\n /**\n * Add custom RUM global parameters. Applies to RUM data\n * @param context custom RUM global parameters.\n * @returns a Promise.\n */\n appendRUMGlobalContext(context: Object): Promise<void>;\n /**\n * Add custom RUM and Log global parameters. Applies to Log data\n * @param context custom Log global parameters.\n * @returns a Promise.\n */\n appendLogGlobalContext(context: Object): Promise<void>;\n /**\n * Actively synchronize data. When `FTMobileConfig.autoSync=false` is configured, you need to actively trigger this method to synchronize data.\n * @returns a Promise.\n */\n flushSyncData(): Promise<void>;\n\n /**\n * Synchronize events in iOS Widget Extension, iOS only\n * @param groupIdentifier app groupId\n * @returns {groupIdentifier:string,datas:Array<Object>} can be used to view data collected in Extension.\n */\n trackEventFromExtension(identifier: string): Promise<Object>;\n /**\n * Shut down objects currently running in the SDK\n */\n shutDown(): Promise<void>;\n /**\n * Clear all data that has not yet been uploaded to the server.\n */\n clearAllData(): Promise<void>;\n}\nexport default TurboModuleRegistry.get<Spec>('FTMobileReactNative');\n"],"mappings":"AAAA;;AAEA,SAASA,mBAAmB,QAAQ,cAAc;AAgFlD,eAAeA,mBAAmB,CAACC,GAAG,CAAO,qBAAqB,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["TurboModuleRegistry","get"],"sources":["NativeFTMobileReactNative.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\nimport type { TurboModule } from 'react-native';\nimport { TurboModuleRegistry } from 'react-native';\n\nexport interface Spec extends TurboModule {\n /**\n * SDK initialization method.\n * @param config SDK initialization configuration items.\n * @returns a Promise.\n */\n sdkConfig(config: Object): Promise<void>;\n /**\n * Dynamically set the Datakit upload URL after SDK initialization.\n * @param datakitUrl Datakit upload URL.\n * @returns a Promise.\n */\n setDatakitURL(datakitUrl: string): Promise<void>;\n /**\n * Dynamically set the Dataway upload URL and client token after SDK initialization.\n * @param datawayUrl Dataway upload URL.\n * @param clientToken Dataway authentication token.\n * @returns a Promise.\n */\n setDatawayURL(datawayUrl: string, clientToken: string): Promise<void>;\n /**\n * Bind user.\n * @param userId user ID.\n * @param userName user name.\n * @param userEmail user email\n * @param extra additional user information\n * @returns a Promise.\n */\n bindRUMUserData(\n userId: string,\n userName?: string,\n userEmail?: string,\n extra?: Object\n ): Promise<void>;\n /**\n * Unbind user.\n * @returns a Promise.\n */\n unbindRUMUserData(): Promise<void>;\n resetVisitorId(): Promise<void>;\n /**\n * Add custom global parameters. Applies to RUM and Log data\n * @param context custom global parameters.\n * @returns a Promise.\n */\n appendGlobalContext(context: Object): Promise<void>;\n /**\n * Add custom RUM global parameters. Applies to RUM data\n * @param context custom RUM global parameters.\n * @returns a Promise.\n */\n appendRUMGlobalContext(context: Object): Promise<void>;\n /**\n * Add custom RUM and Log global parameters. Applies to Log data\n * @param context custom Log global parameters.\n * @returns a Promise.\n */\n appendLogGlobalContext(context: Object): Promise<void>;\n /**\n * Actively synchronize data. When `FTMobileConfig.autoSync=false` is configured, you need to actively trigger this method to synchronize data.\n * @returns a Promise.\n */\n flushSyncData(): Promise<void>;\n\n /**\n * Synchronize events in iOS Widget Extension, iOS only\n * @param groupIdentifier app groupId\n * @returns {groupIdentifier:string,datas:Array<Object>} can be used to view data collected in Extension.\n */\n trackEventFromExtension(identifier: string): Promise<Object>;\n /**\n * Shut down objects currently running in the SDK\n */\n shutDown(): Promise<void>;\n /**\n * Clear all data that has not yet been uploaded to the server.\n */\n clearAllData(): Promise<void>;\n /**\n * Update remote configuration using the configured minimum update interval.\n */\n updateRemoteConfig(): Promise<Object>;\n /**\n * Update remote configuration using a custom minimum update interval and\n * optional override rules.\n */\n updateRemoteConfigWithMiniUpdateInterval(\n interval: number,\n rules?: Array<Object>\n ): Promise<Object>;\n /**\n * Required by NativeEventEmitter for remote configuration callbacks.\n */\n addListener(eventName: string): void;\n removeListeners(count: number): void;\n}\nexport default TurboModuleRegistry.get<Spec>('FTMobileReactNative');\n"],"mappings":"AAAA;;AAEA,SAASA,mBAAmB,QAAQ,cAAc;AAkGlD,eAAeA,mBAAmB,CAACC,GAAG,CAAO,qBAAqB,CAAC","ignoreList":[]}