@luciq/react-native 19.3.0-40271-SNAPSHOT → 19.4.0-44237-SNAPSHOT

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 (119) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +118 -0
  3. package/RNLuciq.podspec +6 -2
  4. package/android/build.gradle +25 -0
  5. package/android/native.gradle +1 -1
  6. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqAPMModule.java +3 -12
  7. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqBugReportingModule.java +28 -24
  8. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqCrashReportingModule.java +18 -7
  9. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsModule.java +1 -2
  10. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerModule.java +29 -56
  11. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqReactnativeModule.java +121 -47
  12. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqReactnativePackage.java +2 -0
  13. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqRepliesModule.java +4 -16
  14. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqSessionReplayModule.java +5 -16
  15. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqSurveysModule.java +7 -15
  16. package/android/src/main/java/ai/luciq/reactlibrary/utils/EventEmitterModule.java +0 -7
  17. package/android/src/main/java/ai/luciq/reactlibrary/utils/ReportUtil.java +0 -7
  18. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqAPMBaseSpec.java +9 -0
  19. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqBaseSpec.java +33 -0
  20. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqBugReportingBaseSpec.java +33 -0
  21. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqCrashReportingBaseSpec.java +9 -0
  22. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsBaseSpec.java +9 -0
  23. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerBaseSpec.java +33 -0
  24. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqRepliesBaseSpec.java +33 -0
  25. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqSessionReplayBaseSpec.java +33 -0
  26. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqSurveysBaseSpec.java +33 -0
  27. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqAPMBaseSpec.java +11 -0
  28. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqBaseSpec.java +22 -0
  29. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqBugReportingBaseSpec.java +22 -0
  30. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqCrashReportingBaseSpec.java +10 -0
  31. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsBaseSpec.java +10 -0
  32. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerBaseSpec.java +22 -0
  33. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqRepliesBaseSpec.java +22 -0
  34. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqSessionReplayBaseSpec.java +22 -0
  35. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqSurveysBaseSpec.java +22 -0
  36. package/dist/modules/BugReporting.js +3 -3
  37. package/dist/modules/Luciq.d.ts +15 -0
  38. package/dist/modules/Luciq.js +23 -3
  39. package/dist/modules/NetworkLogger.d.ts +5 -0
  40. package/dist/modules/NetworkLogger.js +1 -9
  41. package/dist/modules/Replies.js +1 -1
  42. package/dist/modules/Surveys.js +2 -2
  43. package/dist/native/NativeBugReporting.d.ts +4 -4
  44. package/dist/native/NativeCrashReporting.d.ts +2 -2
  45. package/dist/native/NativeLuciq.d.ts +5 -3
  46. package/dist/native/NativePackage.js +25 -2
  47. package/dist/native/NativeReplies.d.ts +1 -1
  48. package/dist/native/NativeSurveys.d.ts +2 -2
  49. package/dist/native/specs/NativeAPM.d.ts +21 -0
  50. package/dist/native/specs/NativeAPM.js +2 -0
  51. package/dist/native/specs/NativeBugReporting.d.ts +29 -0
  52. package/dist/native/specs/NativeBugReporting.js +2 -0
  53. package/dist/native/specs/NativeCrashReporting.d.ts +12 -0
  54. package/dist/native/specs/NativeCrashReporting.js +2 -0
  55. package/dist/native/specs/NativeFeatureRequests.d.ts +8 -0
  56. package/dist/native/specs/NativeFeatureRequests.js +2 -0
  57. package/dist/native/specs/NativeLuciq.d.ts +80 -0
  58. package/dist/native/specs/NativeLuciq.js +2 -0
  59. package/dist/native/specs/NativeNetworkLogger.d.ts +16 -0
  60. package/dist/native/specs/NativeNetworkLogger.js +2 -0
  61. package/dist/native/specs/NativeReplies.d.ts +21 -0
  62. package/dist/native/specs/NativeReplies.js +2 -0
  63. package/dist/native/specs/NativeSessionReplay.d.ts +17 -0
  64. package/dist/native/specs/NativeSessionReplay.js +2 -0
  65. package/dist/native/specs/NativeSurveys.d.ts +18 -0
  66. package/dist/native/specs/NativeSurveys.js +2 -0
  67. package/dist/utils/Enums.js +3 -1
  68. package/dist/utils/FeatureFlags.d.ts +0 -6
  69. package/dist/utils/FeatureFlags.js +0 -35
  70. package/dist/utils/LuciqUtils.d.ts +1 -1
  71. package/dist/utils/LuciqUtils.js +0 -9
  72. package/dist/utils/XhrNetworkInterceptor.js +53 -85
  73. package/ios/RNLuciq/LuciqAPMBridge.h +5 -5
  74. package/ios/RNLuciq/{LuciqAPMBridge.m → LuciqAPMBridge.mm} +48 -39
  75. package/ios/RNLuciq/LuciqBugReportingBridge.h +6 -6
  76. package/ios/RNLuciq/LuciqBugReportingBridge.mm +234 -0
  77. package/ios/RNLuciq/LuciqCrashReportingBridge.h +16 -5
  78. package/ios/RNLuciq/LuciqCrashReportingBridge.mm +91 -0
  79. package/ios/RNLuciq/LuciqFeatureRequestsBridge.h +1 -1
  80. package/ios/RNLuciq/{LuciqFeatureRequestsBridge.m → LuciqFeatureRequestsBridge.mm} +21 -16
  81. package/ios/RNLuciq/LuciqNetworkLoggerBridge.h +1 -30
  82. package/ios/RNLuciq/{LuciqNetworkLoggerBridge.m → LuciqNetworkLoggerBridge.mm} +46 -77
  83. package/ios/RNLuciq/LuciqReactBridge.h +13 -13
  84. package/ios/RNLuciq/{LuciqReactBridge.m → LuciqReactBridge.mm} +95 -34
  85. package/ios/RNLuciq/LuciqRepliesBridge.h +3 -3
  86. package/ios/RNLuciq/LuciqRepliesBridge.mm +86 -0
  87. package/ios/RNLuciq/LuciqSessionReplayBridge.h +5 -5
  88. package/ios/RNLuciq/{LuciqSessionReplayBridge.m → LuciqSessionReplayBridge.mm} +35 -25
  89. package/ios/RNLuciq/LuciqSurveysBridge.h +5 -5
  90. package/ios/RNLuciq/{LuciqSurveysBridge.m → LuciqSurveysBridge.mm} +34 -35
  91. package/ios/native.rb +1 -1
  92. package/package.json +9 -1
  93. package/src/modules/BugReporting.ts +3 -3
  94. package/src/modules/Luciq.ts +26 -4
  95. package/src/modules/NetworkLogger.ts +1 -26
  96. package/src/modules/Replies.ts +1 -1
  97. package/src/modules/Surveys.ts +2 -2
  98. package/src/native/NativeBugReporting.ts +3 -6
  99. package/src/native/NativeCrashReporting.ts +2 -2
  100. package/src/native/NativeLuciq.ts +7 -3
  101. package/src/native/NativePackage.ts +52 -2
  102. package/src/native/NativeReplies.ts +1 -1
  103. package/src/native/NativeSurveys.ts +2 -2
  104. package/src/native/specs/NativeAPM.ts +47 -0
  105. package/src/native/specs/NativeBugReporting.ts +53 -0
  106. package/src/native/specs/NativeCrashReporting.ts +23 -0
  107. package/src/native/specs/NativeFeatureRequests.ts +10 -0
  108. package/src/native/specs/NativeLuciq.ts +137 -0
  109. package/src/native/specs/NativeNetworkLogger.ts +31 -0
  110. package/src/native/specs/NativeReplies.ts +27 -0
  111. package/src/native/specs/NativeSessionReplay.ts +20 -0
  112. package/src/native/specs/NativeSurveys.ts +23 -0
  113. package/src/utils/Enums.ts +4 -1
  114. package/src/utils/FeatureFlags.ts +0 -44
  115. package/src/utils/LuciqUtils.ts +1 -21
  116. package/src/utils/XhrNetworkInterceptor.ts +55 -128
  117. package/ios/RNLuciq/LuciqBugReportingBridge.m +0 -249
  118. package/ios/RNLuciq/LuciqCrashReportingBridge.m +0 -68
  119. package/ios/RNLuciq/LuciqRepliesBridge.m +0 -80
@@ -1,8 +1,6 @@
1
1
  import LuciqConstants from './LuciqConstants';
2
2
  import { stringifyIfNotString, generateW3CHeader } from './LuciqUtils';
3
- import { getCachedW3cFlags } from './FeatureFlags';
4
- import { Logger } from './logger';
5
- const TAG = 'LCQ-RN-NET:';
3
+ import { FeatureFlags } from '../utils/FeatureFlags';
6
4
  const XMLHttpRequest = global.XMLHttpRequest;
7
5
  let originalXHROpen = XMLHttpRequest.prototype.open;
8
6
  let originalXHRSend = XMLHttpRequest.prototype.send;
@@ -10,34 +8,40 @@ let originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
10
8
  let onProgressCallback;
11
9
  let onDoneCallback;
12
10
  let isInterceptorEnabled = false;
13
- const networkMap = new WeakMap();
14
- const createNetworkData = () => ({
15
- id: '',
16
- url: '',
17
- method: '',
18
- requestBody: '',
19
- requestBodySize: 0,
20
- responseBody: '',
21
- responseBodySize: 0,
22
- responseCode: 0,
23
- requestHeaders: {},
24
- responseHeaders: {},
25
- contentType: '',
26
- errorDomain: '',
27
- errorCode: 0,
28
- startTime: 0,
29
- duration: 0,
30
- gqlQueryName: '',
31
- serverErrorMessage: '',
32
- requestContentType: '',
33
- isW3cHeaderFound: null,
34
- partialId: null,
35
- networkStartTimeInSeconds: null,
36
- w3cGeneratedHeader: null,
37
- w3cCaughtHeader: null,
38
- });
39
- const getTraceparentHeader = (networkData) => {
40
- const { isW3cExternalTraceIDEnabled, isW3cExternalGeneratedHeaderEnabled, isW3cCaughtHeaderEnabled, } = getCachedW3cFlags();
11
+ let network;
12
+ const _reset = () => {
13
+ network = {
14
+ id: '',
15
+ url: '',
16
+ method: '',
17
+ requestBody: '',
18
+ requestBodySize: 0,
19
+ responseBody: '',
20
+ responseBodySize: 0,
21
+ responseCode: 0,
22
+ requestHeaders: {},
23
+ responseHeaders: {},
24
+ contentType: '',
25
+ errorDomain: '',
26
+ errorCode: 0,
27
+ startTime: 0,
28
+ duration: 0,
29
+ gqlQueryName: '',
30
+ serverErrorMessage: '',
31
+ requestContentType: '',
32
+ isW3cHeaderFound: null,
33
+ partialId: null,
34
+ networkStartTimeInSeconds: null,
35
+ w3cGeneratedHeader: null,
36
+ w3cCaughtHeader: null,
37
+ };
38
+ };
39
+ const getTraceparentHeader = async (networkData) => {
40
+ const [isW3cExternalTraceIDEnabled, isW3cExternalGeneratedHeaderEnabled, isW3cCaughtHeaderEnabled,] = await Promise.all([
41
+ FeatureFlags.isW3ExternalTraceID(),
42
+ FeatureFlags.isW3ExternalGeneratedHeader(),
43
+ FeatureFlags.isW3CaughtHeader(),
44
+ ]);
41
45
  return injectHeaders(networkData, {
42
46
  isW3cExternalTraceIDEnabled,
43
47
  isW3cExternalGeneratedHeaderEnabled,
@@ -81,57 +85,39 @@ export default {
81
85
  onProgressCallback = callback;
82
86
  },
83
87
  enableInterception() {
88
+ // Prevents infinite calls to XMLHttpRequest.open when enabling interception multiple times
84
89
  if (isInterceptorEnabled) {
85
- Logger.debug(TAG, 'enableInterception called but already enabled, skipping');
86
90
  return;
87
91
  }
88
- Logger.debug(TAG, 'Enabling XHR network interception');
89
92
  originalXHROpen = XMLHttpRequest.prototype.open;
90
93
  originalXHRSend = XMLHttpRequest.prototype.send;
91
94
  originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
92
95
  // An error code that signifies an issue with the RN client.
93
96
  const clientErrorCode = 9876;
94
97
  XMLHttpRequest.prototype.open = function (method, url, ...args) {
95
- const networkData = createNetworkData();
96
- networkData.url = url;
97
- networkData.method = method;
98
- networkMap.set(this, networkData);
99
- Logger.debug(TAG, `[open] ${method} ${url}`);
98
+ _reset();
99
+ network.url = url;
100
+ network.method = method;
100
101
  originalXHROpen.apply(this, [method, url, ...args]);
101
102
  };
102
103
  XMLHttpRequest.prototype.setRequestHeader = function (header, value) {
104
+ // According to the HTTP RFC, headers are case-insensitive, so we convert
105
+ // them to lower-case to make accessing headers predictable.
106
+ // This avoid issues like failing to get the Content-Type header for a request
107
+ // because the header is set as 'Content-Type' instead of 'content-type'.
103
108
  const key = header.toLowerCase();
104
- const networkData = networkMap.get(this);
105
- if (networkData) {
106
- networkData.requestHeaders[key] = stringifyIfNotString(value);
107
- }
108
- else {
109
- Logger.debug(TAG, `[setRequestHeader] No networkData found in WeakMap for header "${key}" — request may have been GC'd or open() was not called`);
110
- }
109
+ network.requestHeaders[key] = stringifyIfNotString(value);
111
110
  originalXHRSetRequestHeader.apply(this, [header, value]);
112
111
  };
113
- XMLHttpRequest.prototype.send = function (data) {
114
- const networkData = networkMap.get(this);
115
- if (!networkData) {
116
- Logger.debug(TAG, '[send] No networkData found in WeakMap — falling back to original send (open() was not intercepted)');
117
- originalXHRSend.apply(this, [data]);
118
- return;
119
- }
120
- Logger.debug(TAG, `[send] ${networkData.method} ${networkData.url}`);
121
- const cloneNetwork = JSON.parse(JSON.stringify(networkData));
112
+ XMLHttpRequest.prototype.send = async function (data) {
113
+ const cloneNetwork = JSON.parse(JSON.stringify(network));
122
114
  cloneNetwork.requestBody = data ? data : '';
123
115
  if (typeof cloneNetwork.requestBody !== 'string') {
124
116
  cloneNetwork.requestBody = JSON.stringify(cloneNetwork.requestBody);
125
117
  }
126
- let isReported = false;
127
118
  if (this.addEventListener) {
128
119
  this.addEventListener('readystatechange', async () => {
129
120
  if (!isInterceptorEnabled) {
130
- Logger.debug(TAG, `[readystatechange] Interceptor disabled, ignoring state=${this.readyState} for ${cloneNetwork.url}`);
131
- return;
132
- }
133
- if (isReported) {
134
- Logger.debug(TAG, `[readystatechange] Already reported, ignoring state=${this.readyState} for ${cloneNetwork.url}`);
135
121
  return;
136
122
  }
137
123
  if (this.readyState === this.HEADERS_RECEIVED) {
@@ -160,7 +146,6 @@ export default {
160
146
  cloneNetwork.requestContentType =
161
147
  cloneNetwork.requestHeaders['content-type'].split(';')[0];
162
148
  }
163
- Logger.debug(TAG, `[readystatechange] HEADERS_RECEIVED for ${cloneNetwork.url}, contentType=${cloneNetwork.contentType}`);
164
149
  }
165
150
  if (this.readyState === this.DONE) {
166
151
  cloneNetwork.duration = Date.now() - cloneNetwork.startTime;
@@ -181,11 +166,11 @@ export default {
181
166
  cloneNetwork.requestBody =
182
167
  typeof _response === 'string' ? _response : JSON.stringify(_response);
183
168
  cloneNetwork.responseBody = '';
169
+ // Detect a more descriptive error message.
184
170
  if (typeof _response === 'string' && _response.length > 0) {
185
171
  cloneNetwork.errorDomain = _response;
186
172
  }
187
173
  cloneNetwork.responseBody = `ERROR: ${cloneNetwork.errorDomain}`;
188
- Logger.debug(TAG, `[readystatechange] DONE with client error for ${cloneNetwork.url}, errorDomain=${cloneNetwork.errorDomain}`);
189
174
  // @ts-ignore
190
175
  }
191
176
  else if (this._timedOut) {
@@ -194,7 +179,6 @@ export default {
194
179
  cloneNetwork.responseCode = 0;
195
180
  cloneNetwork.contentType = 'text/plain';
196
181
  cloneNetwork.responseBody = `ERROR: ${cloneNetwork.errorDomain}`;
197
- Logger.debug(TAG, `[readystatechange] DONE with timeout for ${cloneNetwork.url}`);
198
182
  }
199
183
  // Only set response body if not already set by error handlers
200
184
  if (!cloneNetwork.errorDomain) {
@@ -241,20 +225,16 @@ export default {
241
225
  else {
242
226
  delete cloneNetwork.gqlQueryName;
243
227
  }
244
- isReported = true;
245
- Logger.debug(TAG, `[readystatechange] DONE for ${cloneNetwork.method} ${cloneNetwork.url} — status=${cloneNetwork.responseCode}, duration=${cloneNetwork.duration}ms, hasCallback=${!!onDoneCallback}`);
246
228
  if (onDoneCallback) {
247
229
  onDoneCallback(cloneNetwork);
248
230
  }
249
- else {
250
- Logger.debug(TAG, `[readystatechange] WARNING: onDoneCallback is null, network log for ${cloneNetwork.url} will be LOST`);
251
- }
252
231
  }
253
232
  });
254
233
  const downloadUploadProgressCallback = (event) => {
255
234
  if (!isInterceptorEnabled) {
256
235
  return;
257
236
  }
237
+ // check if will be able to compute progress
258
238
  if (event.lengthComputable && onProgressCallback) {
259
239
  const totalBytesSent = event.loaded;
260
240
  const totalBytesExpectedToSend = event.total - event.loaded;
@@ -263,43 +243,31 @@ export default {
263
243
  };
264
244
  this.addEventListener('progress', downloadUploadProgressCallback);
265
245
  this.upload.addEventListener('progress', downloadUploadProgressCallback);
246
+ // Handler for abort events (works with fetch, Axios, and any XHR-based requests)
266
247
  this.addEventListener('abort', () => {
267
248
  if (!isInterceptorEnabled) {
268
- Logger.debug(TAG, `[abort] Interceptor disabled, ignoring abort for ${cloneNetwork.url}`);
269
- return;
270
- }
271
- if (isReported) {
272
- Logger.debug(TAG, `[abort] Already reported via readystatechange DONE, ignoring duplicate abort for ${cloneNetwork.url}`);
273
249
  return;
274
250
  }
275
- isReported = true;
276
251
  cloneNetwork.duration = Date.now() - cloneNetwork.startTime;
277
252
  cloneNetwork.responseCode = 0;
278
253
  cloneNetwork.errorCode = clientErrorCode;
279
254
  cloneNetwork.errorDomain = 'cancelled';
280
255
  cloneNetwork.responseBody = `ERROR: ${cloneNetwork.errorDomain}`;
281
- Logger.debug(TAG, `[abort] Request cancelled: ${cloneNetwork.method} ${cloneNetwork.url}, duration=${cloneNetwork.duration}ms, hasCallback=${!!onDoneCallback}`);
282
- if (onDoneCallback) {
283
- onDoneCallback(cloneNetwork);
284
- }
285
- else {
286
- Logger.debug(TAG, `[abort] WARNING: onDoneCallback is null, cancelled log for ${cloneNetwork.url} will be LOST`);
287
- }
288
256
  });
289
257
  }
290
258
  cloneNetwork.startTime = Date.now();
291
- const traceparent = getTraceparentHeader(cloneNetwork);
259
+ const traceparent = await getTraceparentHeader(cloneNetwork);
292
260
  if (traceparent) {
293
261
  this.setRequestHeader('Traceparent', traceparent);
294
- Logger.debug(TAG, `[send] Injected traceparent header for ${cloneNetwork.url}`);
262
+ }
263
+ if (this.readyState === this.UNSENT) {
264
+ return; // Prevent sending the request if not opened
295
265
  }
296
266
  originalXHRSend.apply(this, [data]);
297
267
  };
298
268
  isInterceptorEnabled = true;
299
- Logger.debug(TAG, 'XHR network interception enabled');
300
269
  },
301
270
  disableInterception() {
302
- Logger.debug(TAG, 'Disabling XHR network interception');
303
271
  isInterceptorEnabled = false;
304
272
  XMLHttpRequest.prototype.send = originalXHRSend;
305
273
  XMLHttpRequest.prototype.open = originalXHROpen;
@@ -17,7 +17,7 @@
17
17
  - (void)setAutoUITraceEnabled:(BOOL)isEnabled;
18
18
  - (void)startFlow:(NSString *)name;
19
19
  - (void)endFlow:(NSString *)name;
20
- - (void)setFlowAttribute:(NSString *)name :(NSString *)key :(NSString *_Nullable)value;
20
+ - (void)setFlowAttribute:(NSString *)name key:(NSString *)key value:(NSString *_Nullable)value;
21
21
  - (void)startUITrace:(NSString *)name;
22
22
  - (void)endUITrace;
23
23
 
@@ -27,13 +27,13 @@
27
27
  - (void)syncCustomSpan:(NSString *)name
28
28
  startTimestamp:(double)startTimestamp
29
29
  endTimestamp:(double)endTimestamp
30
- resolver:(RCTPromiseResolveBlock)resolve
31
- rejecter:(RCTPromiseRejectBlock)reject;
30
+ resolve:(RCTPromiseResolveBlock)resolve
31
+ reject:(RCTPromiseRejectBlock)reject;
32
32
 
33
33
  - (void)isCustomSpanEnabled:(RCTPromiseResolveBlock)resolve
34
- rejecter:(RCTPromiseRejectBlock)reject;
34
+ reject:(RCTPromiseRejectBlock)reject;
35
35
 
36
36
  - (void)isAPMEnabled:(RCTPromiseResolveBlock)resolve
37
- rejecter:(RCTPromiseRejectBlock)reject;
37
+ reject:(RCTPromiseRejectBlock)reject;
38
38
 
39
39
  @end
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  #import "LuciqAPMBridge.h"
4
2
  #import <LuciqSDK/LCQAPM.h>
5
3
  #import <asl.h>
@@ -9,6 +7,13 @@
9
7
  #import <React/RCTUIManager.h>
10
8
  #import "Util/LCQAPM+PrivateAPIs.h"
11
9
 
10
+ #ifdef RCT_NEW_ARCH_ENABLED
11
+ #import <RNLuciqSpec/RNLuciqSpec.h>
12
+
13
+ @interface LuciqAPMBridge () <NativeAPMSpec>
14
+ @end
15
+ #endif
16
+
12
17
  @implementation LuciqAPMBridge
13
18
 
14
19
  - (dispatch_queue_t)methodQueue {
@@ -26,86 +31,91 @@
26
31
 
27
32
  RCT_EXPORT_MODULE(LCQAPM)
28
33
 
29
- - (id) init
34
+ - (id)init
30
35
  {
31
36
  self = [super init];
32
37
  return self;
33
38
  }
34
39
 
35
- // Pauses the current thread for 3 seconds.
36
- RCT_EXPORT_METHOD(LCQSleep) {
40
+ RCT_EXPORT_METHOD(lcqSleep) {
37
41
  [NSThread sleepForTimeInterval:3.0f];
38
42
  }
39
43
 
40
- // Enables or disables APM.
41
44
  RCT_EXPORT_METHOD(setEnabled:(BOOL)isEnabled) {
42
45
  LCQAPM.enabled = isEnabled;
43
46
  }
44
47
 
45
- // Determines either coldAppLaunch is enabled or not.
46
48
  RCT_EXPORT_METHOD(setAppLaunchEnabled:(BOOL)isEnabled) {
47
49
  LCQAPM.coldAppLaunchEnabled = isEnabled;
48
50
  }
49
51
 
50
- // This method is used to signal the end of the app launch process.
51
52
  RCT_EXPORT_METHOD(endAppLaunch) {
52
53
  [LCQAPM endAppLaunch];
53
54
  }
54
55
 
55
- // Controls whether automatic tracing of UI interactions is enabled or disabled within the SDK.
56
56
  RCT_EXPORT_METHOD(setAutoUITraceEnabled:(BOOL)isEnabled) {
57
57
  LCQAPM.autoUITraceEnabled = isEnabled;
58
58
  }
59
59
 
60
- // Starts a flow trace with the specified `name`,
61
- // allowing the SDK to capture and analyze the flow of execution within the application.
62
- RCT_EXPORT_METHOD(startFlow: (NSString *)name) {
60
+ RCT_EXPORT_METHOD(startFlow:(NSString *)name) {
63
61
  [LCQAPM startFlowWithName:name];
64
62
  }
65
63
 
66
- // Ends a flow with the specified `name`.
67
- RCT_EXPORT_METHOD(endFlow: (NSString *)name) {
64
+ RCT_EXPORT_METHOD(endFlow:(NSString *)name) {
68
65
  [LCQAPM endFlowWithName:name];
69
66
  }
70
67
 
71
-
72
- // Sets a user defined attribute for the currently active flow.
73
- RCT_EXPORT_METHOD(setFlowAttribute:(NSString *)name :(NSString *)key :(NSString *_Nullable)value) {
68
+ RCT_EXPORT_METHOD(setFlowAttribute:(NSString *)name
69
+ key:(NSString *)key
70
+ value:(NSString * _Nullable)value) {
74
71
  [LCQAPM setAttributeForFlowWithName:name key:key value:value];
75
72
  }
76
73
 
77
- // Starts a new `UITrace` with the provided `name` parameter,
78
- // allowing the SDK to capture and analyze the UI components within the application.
79
74
  RCT_EXPORT_METHOD(startUITrace:(NSString *)name) {
80
75
  [LCQAPM startUITraceWithName:name];
81
76
  }
82
77
 
83
- // Terminates the currently active UI trace.
84
78
  RCT_EXPORT_METHOD(endUITrace) {
85
79
  [LCQAPM endUITrace];
86
80
  }
87
81
 
88
- // Enables or disables screen render.
89
82
  RCT_EXPORT_METHOD(setScreenRenderingEnabled:(BOOL)isEnabled) {
90
83
  LCQAPM.screenRenderingEnabled = isEnabled;
91
84
  }
92
85
 
93
- // Syncs a custom span to the native SDK (currently logs only)
86
+ RCT_EXPORT_METHOD(networkLogAndroid:(double)requestStartTime
87
+ requestDuration:(double)requestDuration
88
+ requestHeaders:(NSString *)requestHeaders
89
+ requestBody:(NSString *)requestBody
90
+ requestBodySize:(double)requestBodySize
91
+ requestMethod:(NSString *)requestMethod
92
+ requestUrl:(NSString *)requestUrl
93
+ requestContentType:(NSString *)requestContentType
94
+ responseHeaders:(NSString *)responseHeaders
95
+ responseBody:(NSString * _Nullable)responseBody
96
+ responseBodySize:(double)responseBodySize
97
+ statusCode:(double)statusCode
98
+ responseContentType:(NSString *)responseContentType
99
+ errorDomain:(NSString *)errorDomain
100
+ w3cExternalTraceAttributes:(NSDictionary *)w3cExternalTraceAttributes
101
+ gqlQueryName:(NSString * _Nullable)gqlQueryName
102
+ serverErrorMessage:(NSString * _Nullable)serverErrorMessage) {
103
+ // Android-only; iOS no-op to satisfy unified spec.
104
+ }
105
+
94
106
  RCT_EXPORT_METHOD(syncCustomSpan:(NSString *)name
95
107
  startTimestamp:(double)startTimestamp
96
108
  endTimestamp:(double)endTimestamp
97
- resolver:(RCTPromiseResolveBlock)resolve
98
- rejecter:(RCTPromiseRejectBlock)reject)
109
+ resolve:(RCTPromiseResolveBlock)resolve
110
+ reject:(RCTPromiseRejectBlock)reject)
99
111
  {
100
112
  @try {
101
- // Convert microseconds → seconds (NSDate uses seconds)
102
113
  NSTimeInterval startSeconds = startTimestamp / 1e6;
103
114
  NSTimeInterval endSeconds = endTimestamp / 1e6;
104
115
 
105
116
  NSDate *startDate = [NSDate dateWithTimeIntervalSince1970:startSeconds];
106
117
  NSDate *endDate = [NSDate dateWithTimeIntervalSince1970:endSeconds];
107
118
 
108
- // Add completed span to APM
109
119
  [LCQAPM addCompletedCustomSpanWithName:name
110
120
  startDate:startDate
111
121
  endDate:endDate];
@@ -113,17 +123,14 @@ RCT_EXPORT_METHOD(syncCustomSpan:(NSString *)name
113
123
  resolve(@YES);
114
124
  }
115
125
  @catch (NSException *exception) {
116
- reject(
117
- @"SYNC_CUSTOM_SPAN_ERROR",
118
- exception.reason ?: @"Failed to sync custom span",
119
- nil
120
- );
126
+ reject(@"SYNC_CUSTOM_SPAN_ERROR",
127
+ exception.reason ?: @"Failed to sync custom span",
128
+ nil);
121
129
  }
122
130
  }
123
131
 
124
- // Checks if custom spans feature is enabled
125
132
  RCT_EXPORT_METHOD(isCustomSpanEnabled:(RCTPromiseResolveBlock)resolve
126
- rejecter:(RCTPromiseRejectBlock)reject) {
133
+ reject:(RCTPromiseRejectBlock)reject) {
127
134
  @try {
128
135
  BOOL enabled = LCQAPM.customSpansEnabled;
129
136
  resolve(@(enabled));
@@ -133,9 +140,8 @@ RCT_EXPORT_METHOD(isCustomSpanEnabled:(RCTPromiseResolveBlock)resolve
133
140
  }
134
141
  }
135
142
 
136
- // Checks if APM is enabled
137
143
  RCT_EXPORT_METHOD(isAPMEnabled:(RCTPromiseResolveBlock)resolve
138
- rejecter:(RCTPromiseRejectBlock)reject) {
144
+ reject:(RCTPromiseRejectBlock)reject) {
139
145
  @try {
140
146
  BOOL enabled = LCQAPM.enabled;
141
147
  resolve(@(enabled));
@@ -145,13 +151,16 @@ RCT_EXPORT_METHOD(isAPMEnabled:(RCTPromiseResolveBlock)resolve
145
151
  }
146
152
  }
147
153
 
148
-
154
+ #ifdef RCT_NEW_ARCH_ENABLED
155
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
156
+ (const facebook::react::ObjCTurboModule::InitParams &)params
157
+ {
158
+ return std::make_shared<facebook::react::NativeAPMSpecJSI>(params);
159
+ }
160
+ #endif
149
161
 
150
162
  @synthesize description;
151
-
152
163
  @synthesize hash;
153
-
154
164
  @synthesize superclass;
155
165
 
156
166
  @end
157
-
@@ -25,21 +25,21 @@
25
25
 
26
26
  - (void)setOptions:(NSArray *)optionsArray;
27
27
 
28
- - (void)setFloatingButtonEdge:(CGRectEdge)floatingButtonEdge withTopOffset:(double)floatingButtonOffsetFromTop;
28
+ - (void)setFloatingButtonEdge:(NSString *)edge offset:(double)offset;
29
29
 
30
- - (void)setOnInvokeHandler:(RCTResponseSenderBlock)callBack;
30
+ - (void)setOnInvokeHandler;
31
31
 
32
- - (void)setOnSDKDismissedHandler:(RCTResponseSenderBlock)callBack;
32
+ - (void)setOnSDKDismissedHandler;
33
33
 
34
34
  - (void)setShakingThresholdForiPhone:(double)iPhoneShakingThreshold;
35
35
 
36
36
  - (void)setShakingThresholdForiPad:(double)iPadShakingThreshold;
37
37
 
38
- - (void)setExtendedBugReportMode:(LCQExtendedBugReportMode)extendedBugReportMode;
38
+ - (void)setExtendedBugReportMode:(NSString *)mode;
39
39
 
40
40
  - (void)setReportTypes:(NSArray *)types;
41
41
 
42
- - (void)show:(LCQBugReportingReportType)type options:(NSArray *)options;
42
+ - (void)show:(NSString *)type options:(NSArray *)options;
43
43
 
44
44
  - (void)setAutoScreenRecordingEnabled:(BOOL)enabled;
45
45
 
@@ -57,6 +57,6 @@
57
57
  checked:(BOOL)checked
58
58
  actionType:(id)actionType;
59
59
 
60
- - (void)setProactiveReportingConfigurations:(BOOL)enabled gap:(NSNumber* )gap model:(NSNumber* )modal;
60
+ - (void)setProactiveReportingConfigurations:(BOOL)enabled gapBetweenModals:(double)gapBetweenModals modalDelayAfterDetection:(double)modalDelayAfterDetection;
61
61
 
62
62
  @end