@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.
- package/CHANGELOG.md +15 -0
- package/README.md +118 -0
- package/RNLuciq.podspec +6 -2
- package/android/build.gradle +25 -0
- package/android/native.gradle +1 -1
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqAPMModule.java +3 -12
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqBugReportingModule.java +28 -24
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqCrashReportingModule.java +18 -7
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsModule.java +1 -2
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerModule.java +29 -56
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqReactnativeModule.java +121 -47
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqReactnativePackage.java +2 -0
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqRepliesModule.java +4 -16
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqSessionReplayModule.java +5 -16
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqSurveysModule.java +7 -15
- package/android/src/main/java/ai/luciq/reactlibrary/utils/EventEmitterModule.java +0 -7
- package/android/src/main/java/ai/luciq/reactlibrary/utils/ReportUtil.java +0 -7
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqAPMBaseSpec.java +9 -0
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqBaseSpec.java +33 -0
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqBugReportingBaseSpec.java +33 -0
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqCrashReportingBaseSpec.java +9 -0
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsBaseSpec.java +9 -0
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerBaseSpec.java +33 -0
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqRepliesBaseSpec.java +33 -0
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqSessionReplayBaseSpec.java +33 -0
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqSurveysBaseSpec.java +33 -0
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqAPMBaseSpec.java +11 -0
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqBaseSpec.java +22 -0
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqBugReportingBaseSpec.java +22 -0
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqCrashReportingBaseSpec.java +10 -0
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsBaseSpec.java +10 -0
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerBaseSpec.java +22 -0
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqRepliesBaseSpec.java +22 -0
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqSessionReplayBaseSpec.java +22 -0
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqSurveysBaseSpec.java +22 -0
- package/dist/modules/BugReporting.js +3 -3
- package/dist/modules/Luciq.d.ts +15 -0
- package/dist/modules/Luciq.js +23 -3
- package/dist/modules/NetworkLogger.d.ts +5 -0
- package/dist/modules/NetworkLogger.js +1 -9
- package/dist/modules/Replies.js +1 -1
- package/dist/modules/Surveys.js +2 -2
- package/dist/native/NativeBugReporting.d.ts +4 -4
- package/dist/native/NativeCrashReporting.d.ts +2 -2
- package/dist/native/NativeLuciq.d.ts +5 -3
- package/dist/native/NativePackage.js +25 -2
- package/dist/native/NativeReplies.d.ts +1 -1
- package/dist/native/NativeSurveys.d.ts +2 -2
- package/dist/native/specs/NativeAPM.d.ts +21 -0
- package/dist/native/specs/NativeAPM.js +2 -0
- package/dist/native/specs/NativeBugReporting.d.ts +29 -0
- package/dist/native/specs/NativeBugReporting.js +2 -0
- package/dist/native/specs/NativeCrashReporting.d.ts +12 -0
- package/dist/native/specs/NativeCrashReporting.js +2 -0
- package/dist/native/specs/NativeFeatureRequests.d.ts +8 -0
- package/dist/native/specs/NativeFeatureRequests.js +2 -0
- package/dist/native/specs/NativeLuciq.d.ts +80 -0
- package/dist/native/specs/NativeLuciq.js +2 -0
- package/dist/native/specs/NativeNetworkLogger.d.ts +16 -0
- package/dist/native/specs/NativeNetworkLogger.js +2 -0
- package/dist/native/specs/NativeReplies.d.ts +21 -0
- package/dist/native/specs/NativeReplies.js +2 -0
- package/dist/native/specs/NativeSessionReplay.d.ts +17 -0
- package/dist/native/specs/NativeSessionReplay.js +2 -0
- package/dist/native/specs/NativeSurveys.d.ts +18 -0
- package/dist/native/specs/NativeSurveys.js +2 -0
- package/dist/utils/Enums.js +3 -1
- package/dist/utils/FeatureFlags.d.ts +0 -6
- package/dist/utils/FeatureFlags.js +0 -35
- package/dist/utils/LuciqUtils.d.ts +1 -1
- package/dist/utils/LuciqUtils.js +0 -9
- package/dist/utils/XhrNetworkInterceptor.js +53 -85
- package/ios/RNLuciq/LuciqAPMBridge.h +5 -5
- package/ios/RNLuciq/{LuciqAPMBridge.m → LuciqAPMBridge.mm} +48 -39
- package/ios/RNLuciq/LuciqBugReportingBridge.h +6 -6
- package/ios/RNLuciq/LuciqBugReportingBridge.mm +234 -0
- package/ios/RNLuciq/LuciqCrashReportingBridge.h +16 -5
- package/ios/RNLuciq/LuciqCrashReportingBridge.mm +91 -0
- package/ios/RNLuciq/LuciqFeatureRequestsBridge.h +1 -1
- package/ios/RNLuciq/{LuciqFeatureRequestsBridge.m → LuciqFeatureRequestsBridge.mm} +21 -16
- package/ios/RNLuciq/LuciqNetworkLoggerBridge.h +1 -30
- package/ios/RNLuciq/{LuciqNetworkLoggerBridge.m → LuciqNetworkLoggerBridge.mm} +46 -77
- package/ios/RNLuciq/LuciqReactBridge.h +13 -13
- package/ios/RNLuciq/{LuciqReactBridge.m → LuciqReactBridge.mm} +95 -34
- package/ios/RNLuciq/LuciqRepliesBridge.h +3 -3
- package/ios/RNLuciq/LuciqRepliesBridge.mm +86 -0
- package/ios/RNLuciq/LuciqSessionReplayBridge.h +5 -5
- package/ios/RNLuciq/{LuciqSessionReplayBridge.m → LuciqSessionReplayBridge.mm} +35 -25
- package/ios/RNLuciq/LuciqSurveysBridge.h +5 -5
- package/ios/RNLuciq/{LuciqSurveysBridge.m → LuciqSurveysBridge.mm} +34 -35
- package/ios/native.rb +1 -1
- package/package.json +9 -1
- package/src/modules/BugReporting.ts +3 -3
- package/src/modules/Luciq.ts +26 -4
- package/src/modules/NetworkLogger.ts +1 -26
- package/src/modules/Replies.ts +1 -1
- package/src/modules/Surveys.ts +2 -2
- package/src/native/NativeBugReporting.ts +3 -6
- package/src/native/NativeCrashReporting.ts +2 -2
- package/src/native/NativeLuciq.ts +7 -3
- package/src/native/NativePackage.ts +52 -2
- package/src/native/NativeReplies.ts +1 -1
- package/src/native/NativeSurveys.ts +2 -2
- package/src/native/specs/NativeAPM.ts +47 -0
- package/src/native/specs/NativeBugReporting.ts +53 -0
- package/src/native/specs/NativeCrashReporting.ts +23 -0
- package/src/native/specs/NativeFeatureRequests.ts +10 -0
- package/src/native/specs/NativeLuciq.ts +137 -0
- package/src/native/specs/NativeNetworkLogger.ts +31 -0
- package/src/native/specs/NativeReplies.ts +27 -0
- package/src/native/specs/NativeSessionReplay.ts +20 -0
- package/src/native/specs/NativeSurveys.ts +23 -0
- package/src/utils/Enums.ts +4 -1
- package/src/utils/FeatureFlags.ts +0 -44
- package/src/utils/LuciqUtils.ts +1 -21
- package/src/utils/XhrNetworkInterceptor.ts +55 -128
- package/ios/RNLuciq/LuciqBugReportingBridge.m +0 -249
- package/ios/RNLuciq/LuciqCrashReportingBridge.m +0 -68
- 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 {
|
|
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
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
31
|
-
|
|
30
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
31
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
32
32
|
|
|
33
33
|
- (void)isCustomSpanEnabled:(RCTPromiseResolveBlock)resolve
|
|
34
|
-
|
|
34
|
+
reject:(RCTPromiseRejectBlock)reject;
|
|
35
35
|
|
|
36
36
|
- (void)isAPMEnabled:(RCTPromiseResolveBlock)resolve
|
|
37
|
-
|
|
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)
|
|
34
|
+
- (id)init
|
|
30
35
|
{
|
|
31
36
|
self = [super init];
|
|
32
37
|
return self;
|
|
33
38
|
}
|
|
34
39
|
|
|
35
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
73
|
-
|
|
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
|
-
|
|
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
|
-
|
|
98
|
-
|
|
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
|
-
|
|
118
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:(
|
|
28
|
+
- (void)setFloatingButtonEdge:(NSString *)edge offset:(double)offset;
|
|
29
29
|
|
|
30
|
-
- (void)setOnInvokeHandler
|
|
30
|
+
- (void)setOnInvokeHandler;
|
|
31
31
|
|
|
32
|
-
- (void)setOnSDKDismissedHandler
|
|
32
|
+
- (void)setOnSDKDismissedHandler;
|
|
33
33
|
|
|
34
34
|
- (void)setShakingThresholdForiPhone:(double)iPhoneShakingThreshold;
|
|
35
35
|
|
|
36
36
|
- (void)setShakingThresholdForiPad:(double)iPadShakingThreshold;
|
|
37
37
|
|
|
38
|
-
- (void)setExtendedBugReportMode:(
|
|
38
|
+
- (void)setExtendedBugReportMode:(NSString *)mode;
|
|
39
39
|
|
|
40
40
|
- (void)setReportTypes:(NSArray *)types;
|
|
41
41
|
|
|
42
|
-
- (void)show:(
|
|
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
|
|
60
|
+
- (void)setProactiveReportingConfigurations:(BOOL)enabled gapBetweenModals:(double)gapBetweenModals modalDelayAfterDetection:(double)modalDelayAfterDetection;
|
|
61
61
|
|
|
62
62
|
@end
|