@luciq/react-native 19.4.0-44237-SNAPSHOT → 19.4.0-47504-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/README.md +0 -118
- package/RNLuciq.podspec +2 -6
- package/android/build.gradle +0 -25
- package/android/proguard-rules.txt +1 -1
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqAPMModule.java +12 -3
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqBugReportingModule.java +24 -28
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqCrashReportingModule.java +7 -18
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsModule.java +2 -1
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerModule.java +56 -29
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqReactnativeModule.java +47 -78
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqRepliesModule.java +16 -4
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqSessionReplayModule.java +16 -5
- package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqSurveysModule.java +15 -7
- package/android/src/main/java/ai/luciq/reactlibrary/utils/EventEmitterModule.java +7 -0
- package/dist/modules/BugReporting.js +3 -3
- package/dist/modules/Luciq.js +3 -2
- package/dist/modules/NetworkLogger.d.ts +0 -5
- package/dist/modules/NetworkLogger.js +9 -1
- 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 +3 -2
- package/dist/native/NativePackage.js +2 -25
- package/dist/native/NativeReplies.d.ts +1 -1
- package/dist/native/NativeSurveys.d.ts +2 -2
- package/dist/utils/Enums.js +1 -3
- package/dist/utils/FeatureFlags.d.ts +6 -0
- package/dist/utils/FeatureFlags.js +35 -0
- package/dist/utils/LuciqUtils.d.ts +1 -1
- package/dist/utils/LuciqUtils.js +9 -0
- package/dist/utils/XhrNetworkInterceptor.js +85 -53
- package/ios/RNLuciq/LuciqAPMBridge.h +5 -5
- package/ios/RNLuciq/{LuciqAPMBridge.mm → LuciqAPMBridge.m} +39 -48
- package/ios/RNLuciq/LuciqBugReportingBridge.h +6 -6
- package/ios/RNLuciq/LuciqBugReportingBridge.m +249 -0
- package/ios/RNLuciq/LuciqCrashReportingBridge.h +5 -16
- package/ios/RNLuciq/LuciqCrashReportingBridge.m +68 -0
- package/ios/RNLuciq/LuciqFeatureRequestsBridge.h +1 -1
- package/ios/RNLuciq/{LuciqFeatureRequestsBridge.mm → LuciqFeatureRequestsBridge.m} +16 -21
- package/ios/RNLuciq/LuciqNetworkLoggerBridge.h +30 -1
- package/ios/RNLuciq/{LuciqNetworkLoggerBridge.mm → LuciqNetworkLoggerBridge.m} +77 -46
- package/ios/RNLuciq/LuciqReactBridge.h +13 -13
- package/ios/RNLuciq/{LuciqReactBridge.mm → LuciqReactBridge.m} +34 -83
- package/ios/RNLuciq/LuciqRepliesBridge.h +3 -3
- package/ios/RNLuciq/LuciqRepliesBridge.m +80 -0
- package/ios/RNLuciq/LuciqSessionReplayBridge.h +5 -5
- package/ios/RNLuciq/{LuciqSessionReplayBridge.mm → LuciqSessionReplayBridge.m} +25 -35
- package/ios/RNLuciq/LuciqSurveysBridge.h +5 -5
- package/ios/RNLuciq/{LuciqSurveysBridge.mm → LuciqSurveysBridge.m} +35 -34
- package/package.json +1 -9
- package/scripts/get-github-app-token.sh +70 -0
- package/scripts/notify-github.sh +17 -8
- package/src/modules/BugReporting.ts +3 -3
- package/src/modules/Luciq.ts +4 -2
- package/src/modules/NetworkLogger.ts +26 -1
- package/src/modules/Replies.ts +1 -1
- package/src/modules/Surveys.ts +2 -2
- package/src/native/NativeBugReporting.ts +6 -3
- package/src/native/NativeCrashReporting.ts +2 -2
- package/src/native/NativeLuciq.ts +3 -2
- package/src/native/NativePackage.ts +2 -52
- package/src/native/NativeReplies.ts +1 -1
- package/src/native/NativeSurveys.ts +2 -2
- package/src/utils/Enums.ts +1 -4
- package/src/utils/FeatureFlags.ts +44 -0
- package/src/utils/LuciqUtils.ts +21 -1
- package/src/utils/XhrNetworkInterceptor.ts +128 -55
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqAPMBaseSpec.java +0 -9
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqBaseSpec.java +0 -33
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqBugReportingBaseSpec.java +0 -33
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqCrashReportingBaseSpec.java +0 -9
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsBaseSpec.java +0 -9
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerBaseSpec.java +0 -33
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqRepliesBaseSpec.java +0 -33
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqSessionReplayBaseSpec.java +0 -33
- package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqSurveysBaseSpec.java +0 -33
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqAPMBaseSpec.java +0 -11
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqBaseSpec.java +0 -22
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqBugReportingBaseSpec.java +0 -22
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqCrashReportingBaseSpec.java +0 -10
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsBaseSpec.java +0 -10
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerBaseSpec.java +0 -22
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqRepliesBaseSpec.java +0 -22
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqSessionReplayBaseSpec.java +0 -22
- package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqSurveysBaseSpec.java +0 -22
- package/dist/native/specs/NativeAPM.d.ts +0 -21
- package/dist/native/specs/NativeAPM.js +0 -2
- package/dist/native/specs/NativeBugReporting.d.ts +0 -29
- package/dist/native/specs/NativeBugReporting.js +0 -2
- package/dist/native/specs/NativeCrashReporting.d.ts +0 -12
- package/dist/native/specs/NativeCrashReporting.js +0 -2
- package/dist/native/specs/NativeFeatureRequests.d.ts +0 -8
- package/dist/native/specs/NativeFeatureRequests.js +0 -2
- package/dist/native/specs/NativeLuciq.d.ts +0 -80
- package/dist/native/specs/NativeLuciq.js +0 -2
- package/dist/native/specs/NativeNetworkLogger.d.ts +0 -16
- package/dist/native/specs/NativeNetworkLogger.js +0 -2
- package/dist/native/specs/NativeReplies.d.ts +0 -21
- package/dist/native/specs/NativeReplies.js +0 -2
- package/dist/native/specs/NativeSessionReplay.d.ts +0 -17
- package/dist/native/specs/NativeSessionReplay.js +0 -2
- package/dist/native/specs/NativeSurveys.d.ts +0 -18
- package/dist/native/specs/NativeSurveys.js +0 -2
- package/ios/RNLuciq/LuciqBugReportingBridge.mm +0 -234
- package/ios/RNLuciq/LuciqCrashReportingBridge.mm +0 -91
- package/ios/RNLuciq/LuciqRepliesBridge.mm +0 -86
- package/src/native/specs/NativeAPM.ts +0 -47
- package/src/native/specs/NativeBugReporting.ts +0 -53
- package/src/native/specs/NativeCrashReporting.ts +0 -23
- package/src/native/specs/NativeFeatureRequests.ts +0 -10
- package/src/native/specs/NativeLuciq.ts +0 -137
- package/src/native/specs/NativeNetworkLogger.ts +0 -31
- package/src/native/specs/NativeReplies.ts +0 -27
- package/src/native/specs/NativeSessionReplay.ts +0 -20
- package/src/native/specs/NativeSurveys.ts +0 -23
|
@@ -20,8 +20,8 @@ export interface SurveysNativeModule extends NativeModule {
|
|
|
20
20
|
setAppStoreURL(appStoreURL: string): void;
|
|
21
21
|
|
|
22
22
|
// Callbacks //
|
|
23
|
-
setOnShowHandler(): void;
|
|
24
|
-
setOnDismissHandler(): void;
|
|
23
|
+
setOnShowHandler(onShowHandler: () => void): void;
|
|
24
|
+
setOnDismissHandler(onDismissHandler: () => void): void;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export const NativeSurveys = NativeModules.LCQSurveys;
|
package/src/utils/Enums.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { NativeLuciq } from '../native/NativeLuciq';
|
|
2
2
|
|
|
3
|
-
const constants =
|
|
4
|
-
typeof NativeLuciq.getConstants === 'function'
|
|
5
|
-
? NativeLuciq.getConstants()
|
|
6
|
-
: (NativeLuciq as any).getAllConstants();
|
|
3
|
+
const constants = NativeLuciq.getConstants();
|
|
7
4
|
|
|
8
5
|
/**
|
|
9
6
|
* Verbosity level of the SDK debug logs. This has nothing to do with `Luciq.log`,
|
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
import { NativeLuciq } from '../native/NativeLuciq';
|
|
2
2
|
import { _registerFeatureFlagsChangeListener } from '../modules/Luciq';
|
|
3
|
+
import { Logger } from './logger';
|
|
4
|
+
|
|
5
|
+
const TAG = 'LCQ-RN-NET:';
|
|
6
|
+
|
|
7
|
+
let cachedW3cFlags = {
|
|
8
|
+
isW3cExternalTraceIDEnabled: false,
|
|
9
|
+
isW3cExternalGeneratedHeaderEnabled: false,
|
|
10
|
+
isW3cCaughtHeaderEnabled: false,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export async function initFeatureFlagsCache() {
|
|
14
|
+
Logger.debug(TAG, '[FeatureFlags] Initializing W3C feature flags cache from native bridge...');
|
|
15
|
+
try {
|
|
16
|
+
const [traceID, generatedHeader, caughtHeader] = await Promise.all([
|
|
17
|
+
NativeLuciq.isW3ExternalTraceIDEnabled(),
|
|
18
|
+
NativeLuciq.isW3ExternalGeneratedHeaderEnabled(),
|
|
19
|
+
NativeLuciq.isW3CaughtHeaderEnabled(),
|
|
20
|
+
]);
|
|
21
|
+
cachedW3cFlags = {
|
|
22
|
+
isW3cExternalTraceIDEnabled: traceID,
|
|
23
|
+
isW3cExternalGeneratedHeaderEnabled: generatedHeader,
|
|
24
|
+
isW3cCaughtHeaderEnabled: caughtHeader,
|
|
25
|
+
};
|
|
26
|
+
Logger.debug(
|
|
27
|
+
TAG,
|
|
28
|
+
`[FeatureFlags] Cache initialized: traceID=${traceID}, generatedHeader=${generatedHeader}, caughtHeader=${caughtHeader}`,
|
|
29
|
+
);
|
|
30
|
+
} catch (e) {
|
|
31
|
+
Logger.debug(TAG, '[FeatureFlags] Failed to initialize cache, using defaults (all false):', e);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function getCachedW3cFlags() {
|
|
36
|
+
return cachedW3cFlags;
|
|
37
|
+
}
|
|
3
38
|
|
|
4
39
|
export const FeatureFlags = {
|
|
5
40
|
isW3ExternalTraceID: () => NativeLuciq.isW3ExternalTraceIDEnabled(),
|
|
@@ -16,6 +51,15 @@ export const registerFeatureFlagsListener = () => {
|
|
|
16
51
|
isW3CaughtHeaderEnabled: boolean;
|
|
17
52
|
networkBodyLimit: number;
|
|
18
53
|
}) => {
|
|
54
|
+
Logger.debug(
|
|
55
|
+
TAG,
|
|
56
|
+
`[FeatureFlags] Flags updated from native listener: traceID=${res.isW3ExternalTraceIDEnabled}, generatedHeader=${res.isW3ExternalGeneratedHeaderEnabled}, caughtHeader=${res.isW3CaughtHeaderEnabled}, bodyLimit=${res.networkBodyLimit}`,
|
|
57
|
+
);
|
|
58
|
+
cachedW3cFlags = {
|
|
59
|
+
isW3cExternalTraceIDEnabled: res.isW3ExternalTraceIDEnabled,
|
|
60
|
+
isW3cExternalGeneratedHeaderEnabled: res.isW3ExternalGeneratedHeaderEnabled,
|
|
61
|
+
isW3cCaughtHeaderEnabled: res.isW3CaughtHeaderEnabled,
|
|
62
|
+
};
|
|
19
63
|
FeatureFlags.isW3ExternalTraceID = async () => {
|
|
20
64
|
return res.isW3ExternalTraceIDEnabled;
|
|
21
65
|
};
|
package/src/utils/LuciqUtils.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { NativeCrashReporting } from '../native/NativeCrashReporting';
|
|
|
12
12
|
import type { NetworkData } from './XhrNetworkInterceptor';
|
|
13
13
|
import { NativeLuciq } from '../native/NativeLuciq';
|
|
14
14
|
import { NativeAPM } from '../native/NativeAPM';
|
|
15
|
+
import { Logger } from './logger';
|
|
15
16
|
import * as NetworkLogger from '../modules/NetworkLogger';
|
|
16
17
|
import {
|
|
17
18
|
NativeNetworkLogger,
|
|
@@ -164,9 +165,14 @@ export const stringifyIfNotString = (input: unknown) => {
|
|
|
164
165
|
*/
|
|
165
166
|
export async function sendCrashReport(
|
|
166
167
|
error: ExtendedError,
|
|
167
|
-
remoteSenderCallback: (json: CrashData) => Promise<void>,
|
|
168
|
+
remoteSenderCallback: (json: CrashData | string) => Promise<void>,
|
|
168
169
|
) {
|
|
169
170
|
const jsonObject = getCrashDataFromError(error);
|
|
171
|
+
|
|
172
|
+
if (Platform.OS === 'android') {
|
|
173
|
+
return remoteSenderCallback(JSON.stringify(jsonObject));
|
|
174
|
+
}
|
|
175
|
+
|
|
170
176
|
return remoteSenderCallback(jsonObject);
|
|
171
177
|
}
|
|
172
178
|
/**
|
|
@@ -226,6 +232,11 @@ export const reportNetworkLog = (network: NetworkData) => {
|
|
|
226
232
|
const requestHeaders = JSON.stringify(network.requestHeaders);
|
|
227
233
|
const responseHeaders = JSON.stringify(network.responseHeaders);
|
|
228
234
|
|
|
235
|
+
Logger.debug(
|
|
236
|
+
'LCQ-RN-NET:',
|
|
237
|
+
`[reportNetworkLog] Sending to NativeLuciq.networkLogAndroid: ${network.method} ${network.url}, status=${network.responseCode}, duration=${network.duration}ms, error=${network.errorDomain || 'none'}`,
|
|
238
|
+
);
|
|
239
|
+
|
|
229
240
|
NativeLuciq.networkLogAndroid(
|
|
230
241
|
network.url,
|
|
231
242
|
network.requestBody,
|
|
@@ -241,6 +252,10 @@ export const reportNetworkLog = (network: NetworkData) => {
|
|
|
241
252
|
!apmFlags.hasAPMNetworkPlugin ||
|
|
242
253
|
!apmFlags.shouldEnableNativeInterception
|
|
243
254
|
) {
|
|
255
|
+
Logger.debug(
|
|
256
|
+
'LCQ-RN-NET:',
|
|
257
|
+
`[reportNetworkLog] Also sending to NativeAPM.networkLogAndroid (native interception disabled): ${network.method} ${network.url}`,
|
|
258
|
+
);
|
|
244
259
|
NativeAPM.networkLogAndroid(
|
|
245
260
|
network.startTime,
|
|
246
261
|
network.duration,
|
|
@@ -266,6 +281,11 @@ export const reportNetworkLog = (network: NetworkData) => {
|
|
|
266
281
|
network.gqlQueryName,
|
|
267
282
|
network.serverErrorMessage,
|
|
268
283
|
);
|
|
284
|
+
} else {
|
|
285
|
+
Logger.debug(
|
|
286
|
+
'LCQ-RN-NET:',
|
|
287
|
+
`[reportNetworkLog] Skipping NativeAPM.networkLogAndroid (native interception enabled): nativeFeature=${apmFlags.isNativeInterceptionFeatureEnabled}, hasPlugin=${apmFlags.hasAPMNetworkPlugin}, shouldEnable=${apmFlags.shouldEnableNativeInterception}`,
|
|
288
|
+
);
|
|
269
289
|
}
|
|
270
290
|
} else {
|
|
271
291
|
NativeLuciq.networkLogIOS(
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import LuciqConstants from './LuciqConstants';
|
|
2
2
|
import { stringifyIfNotString, generateW3CHeader } from './LuciqUtils';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { getCachedW3cFlags } from './FeatureFlags';
|
|
5
|
+
import { Logger } from './logger';
|
|
6
|
+
|
|
7
|
+
const TAG = 'LCQ-RN-NET:';
|
|
5
8
|
|
|
6
9
|
export type ProgressCallback = (totalBytesSent: number, totalBytesExpectedToSend: number) => void;
|
|
7
10
|
export type NetworkDataCallback = (data: NetworkData) => void;
|
|
@@ -40,45 +43,41 @@ let originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
|
|
|
40
43
|
let onProgressCallback: ProgressCallback | null;
|
|
41
44
|
let onDoneCallback: NetworkDataCallback | null;
|
|
42
45
|
let isInterceptorEnabled = false;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const getTraceparentHeader =
|
|
73
|
-
const
|
|
46
|
+
|
|
47
|
+
const networkMap = new WeakMap<XMLHttpRequest, NetworkData>();
|
|
48
|
+
|
|
49
|
+
const createNetworkData = (): NetworkData => ({
|
|
50
|
+
id: '',
|
|
51
|
+
url: '',
|
|
52
|
+
method: '',
|
|
53
|
+
requestBody: '',
|
|
54
|
+
requestBodySize: 0,
|
|
55
|
+
responseBody: '',
|
|
56
|
+
responseBodySize: 0,
|
|
57
|
+
responseCode: 0,
|
|
58
|
+
requestHeaders: {},
|
|
59
|
+
responseHeaders: {},
|
|
60
|
+
contentType: '',
|
|
61
|
+
errorDomain: '',
|
|
62
|
+
errorCode: 0,
|
|
63
|
+
startTime: 0,
|
|
64
|
+
duration: 0,
|
|
65
|
+
gqlQueryName: '',
|
|
66
|
+
serverErrorMessage: '',
|
|
67
|
+
requestContentType: '',
|
|
68
|
+
isW3cHeaderFound: null,
|
|
69
|
+
partialId: null,
|
|
70
|
+
networkStartTimeInSeconds: null,
|
|
71
|
+
w3cGeneratedHeader: null,
|
|
72
|
+
w3cCaughtHeader: null,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const getTraceparentHeader = (networkData: NetworkData) => {
|
|
76
|
+
const {
|
|
74
77
|
isW3cExternalTraceIDEnabled,
|
|
75
78
|
isW3cExternalGeneratedHeaderEnabled,
|
|
76
79
|
isW3cCaughtHeaderEnabled,
|
|
77
|
-
|
|
78
|
-
FeatureFlags.isW3ExternalTraceID(),
|
|
79
|
-
FeatureFlags.isW3ExternalGeneratedHeader(),
|
|
80
|
-
FeatureFlags.isW3CaughtHeader(),
|
|
81
|
-
]);
|
|
80
|
+
} = getCachedW3cFlags();
|
|
82
81
|
|
|
83
82
|
return injectHeaders(networkData, {
|
|
84
83
|
isW3cExternalTraceIDEnabled,
|
|
@@ -147,44 +146,77 @@ export default {
|
|
|
147
146
|
onProgressCallback = callback;
|
|
148
147
|
},
|
|
149
148
|
enableInterception() {
|
|
150
|
-
// Prevents infinite calls to XMLHttpRequest.open when enabling interception multiple times
|
|
151
149
|
if (isInterceptorEnabled) {
|
|
150
|
+
Logger.debug(TAG, 'enableInterception called but already enabled, skipping');
|
|
152
151
|
return;
|
|
153
152
|
}
|
|
154
153
|
|
|
154
|
+
Logger.debug(TAG, 'Enabling XHR network interception');
|
|
155
|
+
|
|
155
156
|
originalXHROpen = XMLHttpRequest.prototype.open;
|
|
156
157
|
originalXHRSend = XMLHttpRequest.prototype.send;
|
|
157
158
|
originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
|
|
158
159
|
// An error code that signifies an issue with the RN client.
|
|
159
160
|
const clientErrorCode = 9876;
|
|
160
161
|
XMLHttpRequest.prototype.open = function (method, url, ...args) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
const networkData = createNetworkData();
|
|
163
|
+
networkData.url = url;
|
|
164
|
+
networkData.method = method;
|
|
165
|
+
networkMap.set(this, networkData);
|
|
166
|
+
Logger.debug(TAG, `[open] ${method} ${url}`);
|
|
164
167
|
originalXHROpen.apply(this, [method, url, ...args]);
|
|
165
168
|
};
|
|
166
169
|
|
|
167
170
|
XMLHttpRequest.prototype.setRequestHeader = function (header, value) {
|
|
168
|
-
// According to the HTTP RFC, headers are case-insensitive, so we convert
|
|
169
|
-
// them to lower-case to make accessing headers predictable.
|
|
170
|
-
// This avoid issues like failing to get the Content-Type header for a request
|
|
171
|
-
// because the header is set as 'Content-Type' instead of 'content-type'.
|
|
172
171
|
const key = header.toLowerCase();
|
|
173
|
-
|
|
172
|
+
const networkData = networkMap.get(this);
|
|
173
|
+
if (networkData) {
|
|
174
|
+
networkData.requestHeaders[key] = stringifyIfNotString(value);
|
|
175
|
+
} else {
|
|
176
|
+
Logger.debug(
|
|
177
|
+
TAG,
|
|
178
|
+
`[setRequestHeader] No networkData found in WeakMap for header "${key}" — request may have been GC'd or open() was not called`,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
174
181
|
originalXHRSetRequestHeader.apply(this, [header, value]);
|
|
175
182
|
};
|
|
176
183
|
|
|
177
|
-
XMLHttpRequest.prototype.send =
|
|
178
|
-
const
|
|
184
|
+
XMLHttpRequest.prototype.send = function (data) {
|
|
185
|
+
const networkData = networkMap.get(this);
|
|
186
|
+
if (!networkData) {
|
|
187
|
+
Logger.debug(
|
|
188
|
+
TAG,
|
|
189
|
+
'[send] No networkData found in WeakMap — falling back to original send (open() was not intercepted)',
|
|
190
|
+
);
|
|
191
|
+
originalXHRSend.apply(this, [data]);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
Logger.debug(TAG, `[send] ${networkData.method} ${networkData.url}`);
|
|
196
|
+
|
|
197
|
+
const cloneNetwork = JSON.parse(JSON.stringify(networkData));
|
|
179
198
|
cloneNetwork.requestBody = data ? data : '';
|
|
180
199
|
|
|
181
200
|
if (typeof cloneNetwork.requestBody !== 'string') {
|
|
182
201
|
cloneNetwork.requestBody = JSON.stringify(cloneNetwork.requestBody);
|
|
183
202
|
}
|
|
184
203
|
|
|
204
|
+
let isReported = false;
|
|
205
|
+
|
|
185
206
|
if (this.addEventListener) {
|
|
186
207
|
this.addEventListener('readystatechange', async () => {
|
|
187
208
|
if (!isInterceptorEnabled) {
|
|
209
|
+
Logger.debug(
|
|
210
|
+
TAG,
|
|
211
|
+
`[readystatechange] Interceptor disabled, ignoring state=${this.readyState} for ${cloneNetwork.url}`,
|
|
212
|
+
);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (isReported) {
|
|
216
|
+
Logger.debug(
|
|
217
|
+
TAG,
|
|
218
|
+
`[readystatechange] Already reported, ignoring state=${this.readyState} for ${cloneNetwork.url}`,
|
|
219
|
+
);
|
|
188
220
|
return;
|
|
189
221
|
}
|
|
190
222
|
if (this.readyState === this.HEADERS_RECEIVED) {
|
|
@@ -217,6 +249,11 @@ export default {
|
|
|
217
249
|
cloneNetwork.requestContentType =
|
|
218
250
|
cloneNetwork.requestHeaders['content-type'].split(';')[0];
|
|
219
251
|
}
|
|
252
|
+
|
|
253
|
+
Logger.debug(
|
|
254
|
+
TAG,
|
|
255
|
+
`[readystatechange] HEADERS_RECEIVED for ${cloneNetwork.url}, contentType=${cloneNetwork.contentType}`,
|
|
256
|
+
);
|
|
220
257
|
}
|
|
221
258
|
|
|
222
259
|
if (this.readyState === this.DONE) {
|
|
@@ -239,12 +276,15 @@ export default {
|
|
|
239
276
|
typeof _response === 'string' ? _response : JSON.stringify(_response);
|
|
240
277
|
cloneNetwork.responseBody = '';
|
|
241
278
|
|
|
242
|
-
// Detect a more descriptive error message.
|
|
243
279
|
if (typeof _response === 'string' && _response.length > 0) {
|
|
244
280
|
cloneNetwork.errorDomain = _response;
|
|
245
281
|
}
|
|
246
282
|
|
|
247
283
|
cloneNetwork.responseBody = `ERROR: ${cloneNetwork.errorDomain}`;
|
|
284
|
+
Logger.debug(
|
|
285
|
+
TAG,
|
|
286
|
+
`[readystatechange] DONE with client error for ${cloneNetwork.url}, errorDomain=${cloneNetwork.errorDomain}`,
|
|
287
|
+
);
|
|
248
288
|
|
|
249
289
|
// @ts-ignore
|
|
250
290
|
} else if (this._timedOut) {
|
|
@@ -253,6 +293,7 @@ export default {
|
|
|
253
293
|
cloneNetwork.responseCode = 0;
|
|
254
294
|
cloneNetwork.contentType = 'text/plain';
|
|
255
295
|
cloneNetwork.responseBody = `ERROR: ${cloneNetwork.errorDomain}`;
|
|
296
|
+
Logger.debug(TAG, `[readystatechange] DONE with timeout for ${cloneNetwork.url}`);
|
|
256
297
|
}
|
|
257
298
|
|
|
258
299
|
// Only set response body if not already set by error handlers
|
|
@@ -300,8 +341,18 @@ export default {
|
|
|
300
341
|
delete cloneNetwork.gqlQueryName;
|
|
301
342
|
}
|
|
302
343
|
|
|
344
|
+
isReported = true;
|
|
345
|
+
Logger.debug(
|
|
346
|
+
TAG,
|
|
347
|
+
`[readystatechange] DONE for ${cloneNetwork.method} ${cloneNetwork.url} — status=${cloneNetwork.responseCode}, duration=${cloneNetwork.duration}ms, hasCallback=${!!onDoneCallback}`,
|
|
348
|
+
);
|
|
303
349
|
if (onDoneCallback) {
|
|
304
350
|
onDoneCallback(cloneNetwork);
|
|
351
|
+
} else {
|
|
352
|
+
Logger.debug(
|
|
353
|
+
TAG,
|
|
354
|
+
`[readystatechange] WARNING: onDoneCallback is null, network log for ${cloneNetwork.url} will be LOST`,
|
|
355
|
+
);
|
|
305
356
|
}
|
|
306
357
|
}
|
|
307
358
|
});
|
|
@@ -310,7 +361,6 @@ export default {
|
|
|
310
361
|
if (!isInterceptorEnabled) {
|
|
311
362
|
return;
|
|
312
363
|
}
|
|
313
|
-
// check if will be able to compute progress
|
|
314
364
|
if (event.lengthComputable && onProgressCallback) {
|
|
315
365
|
const totalBytesSent = event.loaded;
|
|
316
366
|
const totalBytesExpectedToSend = event.total - event.loaded;
|
|
@@ -320,34 +370,57 @@ export default {
|
|
|
320
370
|
this.addEventListener('progress', downloadUploadProgressCallback);
|
|
321
371
|
this.upload.addEventListener('progress', downloadUploadProgressCallback);
|
|
322
372
|
|
|
323
|
-
// Handler for abort events (works with fetch, Axios, and any XHR-based requests)
|
|
324
373
|
this.addEventListener('abort', () => {
|
|
325
374
|
if (!isInterceptorEnabled) {
|
|
375
|
+
Logger.debug(
|
|
376
|
+
TAG,
|
|
377
|
+
`[abort] Interceptor disabled, ignoring abort for ${cloneNetwork.url}`,
|
|
378
|
+
);
|
|
326
379
|
return;
|
|
327
380
|
}
|
|
381
|
+
if (isReported) {
|
|
382
|
+
Logger.debug(
|
|
383
|
+
TAG,
|
|
384
|
+
`[abort] Already reported via readystatechange DONE, ignoring duplicate abort for ${cloneNetwork.url}`,
|
|
385
|
+
);
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
isReported = true;
|
|
328
389
|
cloneNetwork.duration = Date.now() - cloneNetwork.startTime;
|
|
329
390
|
cloneNetwork.responseCode = 0;
|
|
330
391
|
cloneNetwork.errorCode = clientErrorCode;
|
|
331
392
|
cloneNetwork.errorDomain = 'cancelled';
|
|
332
393
|
cloneNetwork.responseBody = `ERROR: ${cloneNetwork.errorDomain}`;
|
|
394
|
+
Logger.debug(
|
|
395
|
+
TAG,
|
|
396
|
+
`[abort] Request cancelled: ${cloneNetwork.method} ${cloneNetwork.url}, duration=${cloneNetwork.duration}ms, hasCallback=${!!onDoneCallback}`,
|
|
397
|
+
);
|
|
398
|
+
if (onDoneCallback) {
|
|
399
|
+
onDoneCallback(cloneNetwork);
|
|
400
|
+
} else {
|
|
401
|
+
Logger.debug(
|
|
402
|
+
TAG,
|
|
403
|
+
`[abort] WARNING: onDoneCallback is null, cancelled log for ${cloneNetwork.url} will be LOST`,
|
|
404
|
+
);
|
|
405
|
+
}
|
|
333
406
|
});
|
|
334
407
|
}
|
|
335
408
|
|
|
336
409
|
cloneNetwork.startTime = Date.now();
|
|
337
|
-
const traceparent =
|
|
410
|
+
const traceparent = getTraceparentHeader(cloneNetwork);
|
|
338
411
|
if (traceparent) {
|
|
339
412
|
this.setRequestHeader('Traceparent', traceparent);
|
|
340
|
-
|
|
341
|
-
if (this.readyState === this.UNSENT) {
|
|
342
|
-
return; // Prevent sending the request if not opened
|
|
413
|
+
Logger.debug(TAG, `[send] Injected traceparent header for ${cloneNetwork.url}`);
|
|
343
414
|
}
|
|
344
415
|
|
|
345
416
|
originalXHRSend.apply(this, [data]);
|
|
346
417
|
};
|
|
347
418
|
isInterceptorEnabled = true;
|
|
419
|
+
Logger.debug(TAG, 'XHR network interception enabled');
|
|
348
420
|
},
|
|
349
421
|
|
|
350
422
|
disableInterception() {
|
|
423
|
+
Logger.debug(TAG, 'Disabling XHR network interception');
|
|
351
424
|
isInterceptorEnabled = false;
|
|
352
425
|
XMLHttpRequest.prototype.send = originalXHRSend;
|
|
353
426
|
XMLHttpRequest.prototype.open = originalXHROpen;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
package ai.luciq.reactlibrary;
|
|
2
|
-
|
|
3
|
-
import androidx.annotation.Nullable;
|
|
4
|
-
|
|
5
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
6
|
-
import com.facebook.react.bridge.ReadableMap;
|
|
7
|
-
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
8
|
-
|
|
9
|
-
abstract class RNLuciqBaseSpec extends NativeLuciqSpec {
|
|
10
|
-
private int listenerCount = 0;
|
|
11
|
-
|
|
12
|
-
RNLuciqBaseSpec(ReactApplicationContext context) {
|
|
13
|
-
super(context);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public void sendEvent(String event, @Nullable ReadableMap params) {
|
|
17
|
-
if (listenerCount > 0) {
|
|
18
|
-
getReactApplicationContext()
|
|
19
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
20
|
-
.emit(event, params);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@Override
|
|
25
|
-
public void addListener(String eventName) {
|
|
26
|
-
listenerCount++;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@Override
|
|
30
|
-
public void removeListeners(double count) {
|
|
31
|
-
listenerCount = Math.max(0, listenerCount - (int) count);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
package ai.luciq.reactlibrary;
|
|
2
|
-
|
|
3
|
-
import androidx.annotation.Nullable;
|
|
4
|
-
|
|
5
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
6
|
-
import com.facebook.react.bridge.ReadableMap;
|
|
7
|
-
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
8
|
-
|
|
9
|
-
abstract class RNLuciqBugReportingBaseSpec extends NativeBugReportingSpec {
|
|
10
|
-
private int listenerCount = 0;
|
|
11
|
-
|
|
12
|
-
RNLuciqBugReportingBaseSpec(ReactApplicationContext context) {
|
|
13
|
-
super(context);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public void sendEvent(String event, @Nullable ReadableMap params) {
|
|
17
|
-
if (listenerCount > 0) {
|
|
18
|
-
getReactApplicationContext()
|
|
19
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
20
|
-
.emit(event, params);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@Override
|
|
25
|
-
public void addListener(String eventName) {
|
|
26
|
-
listenerCount++;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@Override
|
|
30
|
-
public void removeListeners(double count) {
|
|
31
|
-
listenerCount = Math.max(0, listenerCount - (int) count);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
package ai.luciq.reactlibrary;
|
|
2
|
-
|
|
3
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
4
|
-
|
|
5
|
-
abstract class RNLuciqCrashReportingBaseSpec extends NativeCrashReportingSpec {
|
|
6
|
-
RNLuciqCrashReportingBaseSpec(ReactApplicationContext context) {
|
|
7
|
-
super(context);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
package ai.luciq.reactlibrary;
|
|
2
|
-
|
|
3
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
4
|
-
|
|
5
|
-
abstract class RNLuciqFeatureRequestsBaseSpec extends NativeFeatureRequestsSpec {
|
|
6
|
-
RNLuciqFeatureRequestsBaseSpec(ReactApplicationContext context) {
|
|
7
|
-
super(context);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
package ai.luciq.reactlibrary;
|
|
2
|
-
|
|
3
|
-
import androidx.annotation.Nullable;
|
|
4
|
-
|
|
5
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
6
|
-
import com.facebook.react.bridge.ReadableMap;
|
|
7
|
-
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
8
|
-
|
|
9
|
-
abstract class RNLuciqNetworkLoggerBaseSpec extends NativeNetworkLoggerSpec {
|
|
10
|
-
private int listenerCount = 0;
|
|
11
|
-
|
|
12
|
-
RNLuciqNetworkLoggerBaseSpec(ReactApplicationContext context) {
|
|
13
|
-
super(context);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public void sendEvent(String event, @Nullable ReadableMap params) {
|
|
17
|
-
if (listenerCount > 0) {
|
|
18
|
-
getReactApplicationContext()
|
|
19
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
20
|
-
.emit(event, params);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@Override
|
|
25
|
-
public void addListener(String eventName) {
|
|
26
|
-
listenerCount++;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@Override
|
|
30
|
-
public void removeListeners(double count) {
|
|
31
|
-
listenerCount = Math.max(0, listenerCount - (int) count);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
package ai.luciq.reactlibrary;
|
|
2
|
-
|
|
3
|
-
import androidx.annotation.Nullable;
|
|
4
|
-
|
|
5
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
6
|
-
import com.facebook.react.bridge.ReadableMap;
|
|
7
|
-
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
8
|
-
|
|
9
|
-
abstract class RNLuciqRepliesBaseSpec extends NativeRepliesSpec {
|
|
10
|
-
private int listenerCount = 0;
|
|
11
|
-
|
|
12
|
-
RNLuciqRepliesBaseSpec(ReactApplicationContext context) {
|
|
13
|
-
super(context);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public void sendEvent(String event, @Nullable ReadableMap params) {
|
|
17
|
-
if (listenerCount > 0) {
|
|
18
|
-
getReactApplicationContext()
|
|
19
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
20
|
-
.emit(event, params);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@Override
|
|
25
|
-
public void addListener(String eventName) {
|
|
26
|
-
listenerCount++;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@Override
|
|
30
|
-
public void removeListeners(double count) {
|
|
31
|
-
listenerCount = Math.max(0, listenerCount - (int) count);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
package ai.luciq.reactlibrary;
|
|
2
|
-
|
|
3
|
-
import androidx.annotation.Nullable;
|
|
4
|
-
|
|
5
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
6
|
-
import com.facebook.react.bridge.ReadableMap;
|
|
7
|
-
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
8
|
-
|
|
9
|
-
abstract class RNLuciqSessionReplayBaseSpec extends NativeSessionReplaySpec {
|
|
10
|
-
private int listenerCount = 0;
|
|
11
|
-
|
|
12
|
-
RNLuciqSessionReplayBaseSpec(ReactApplicationContext context) {
|
|
13
|
-
super(context);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public void sendEvent(String event, @Nullable ReadableMap params) {
|
|
17
|
-
if (listenerCount > 0) {
|
|
18
|
-
getReactApplicationContext()
|
|
19
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
20
|
-
.emit(event, params);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@Override
|
|
25
|
-
public void addListener(String eventName) {
|
|
26
|
-
listenerCount++;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@Override
|
|
30
|
-
public void removeListeners(double count) {
|
|
31
|
-
listenerCount = Math.max(0, listenerCount - (int) count);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
package ai.luciq.reactlibrary;
|
|
2
|
-
|
|
3
|
-
import androidx.annotation.Nullable;
|
|
4
|
-
|
|
5
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
6
|
-
import com.facebook.react.bridge.ReadableMap;
|
|
7
|
-
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
8
|
-
|
|
9
|
-
abstract class RNLuciqSurveysBaseSpec extends NativeSurveysSpec {
|
|
10
|
-
private int listenerCount = 0;
|
|
11
|
-
|
|
12
|
-
RNLuciqSurveysBaseSpec(ReactApplicationContext context) {
|
|
13
|
-
super(context);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public void sendEvent(String event, @Nullable ReadableMap params) {
|
|
17
|
-
if (listenerCount > 0) {
|
|
18
|
-
getReactApplicationContext()
|
|
19
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
20
|
-
.emit(event, params);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@Override
|
|
25
|
-
public void addListener(String eventName) {
|
|
26
|
-
listenerCount++;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@Override
|
|
30
|
-
public void removeListeners(double count) {
|
|
31
|
-
listenerCount = Math.max(0, listenerCount - (int) count);
|
|
32
|
-
}
|
|
33
|
-
}
|