@luciq/react-native 19.4.0-44237-SNAPSHOT → 19.4.0-47163-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 (115) hide show
  1. package/README.md +0 -118
  2. package/RNLuciq.podspec +2 -6
  3. package/android/build.gradle +0 -25
  4. package/android/proguard-rules.txt +1 -1
  5. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqAPMModule.java +12 -3
  6. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqBugReportingModule.java +24 -28
  7. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqCrashReportingModule.java +7 -18
  8. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsModule.java +2 -1
  9. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerModule.java +56 -29
  10. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqReactnativeModule.java +47 -78
  11. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqRepliesModule.java +16 -4
  12. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqSessionReplayModule.java +16 -5
  13. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqSurveysModule.java +15 -7
  14. package/android/src/main/java/ai/luciq/reactlibrary/utils/EventEmitterModule.java +7 -0
  15. package/dist/modules/BugReporting.js +3 -3
  16. package/dist/modules/Luciq.js +3 -2
  17. package/dist/modules/NetworkLogger.d.ts +0 -5
  18. package/dist/modules/NetworkLogger.js +9 -1
  19. package/dist/modules/Replies.js +1 -1
  20. package/dist/modules/Surveys.js +2 -2
  21. package/dist/native/NativeBugReporting.d.ts +4 -4
  22. package/dist/native/NativeCrashReporting.d.ts +2 -2
  23. package/dist/native/NativeLuciq.d.ts +3 -2
  24. package/dist/native/NativePackage.js +2 -25
  25. package/dist/native/NativeReplies.d.ts +1 -1
  26. package/dist/native/NativeSurveys.d.ts +2 -2
  27. package/dist/utils/Enums.js +1 -3
  28. package/dist/utils/FeatureFlags.d.ts +6 -0
  29. package/dist/utils/FeatureFlags.js +35 -0
  30. package/dist/utils/LuciqUtils.d.ts +1 -1
  31. package/dist/utils/LuciqUtils.js +9 -0
  32. package/dist/utils/XhrNetworkInterceptor.js +85 -53
  33. package/ios/RNLuciq/LuciqAPMBridge.h +5 -5
  34. package/ios/RNLuciq/{LuciqAPMBridge.mm → LuciqAPMBridge.m} +39 -48
  35. package/ios/RNLuciq/LuciqBugReportingBridge.h +6 -6
  36. package/ios/RNLuciq/LuciqBugReportingBridge.m +249 -0
  37. package/ios/RNLuciq/LuciqCrashReportingBridge.h +5 -16
  38. package/ios/RNLuciq/LuciqCrashReportingBridge.m +68 -0
  39. package/ios/RNLuciq/LuciqFeatureRequestsBridge.h +1 -1
  40. package/ios/RNLuciq/{LuciqFeatureRequestsBridge.mm → LuciqFeatureRequestsBridge.m} +16 -21
  41. package/ios/RNLuciq/LuciqNetworkLoggerBridge.h +30 -1
  42. package/ios/RNLuciq/{LuciqNetworkLoggerBridge.mm → LuciqNetworkLoggerBridge.m} +77 -46
  43. package/ios/RNLuciq/LuciqReactBridge.h +13 -13
  44. package/ios/RNLuciq/{LuciqReactBridge.mm → LuciqReactBridge.m} +34 -83
  45. package/ios/RNLuciq/LuciqRepliesBridge.h +3 -3
  46. package/ios/RNLuciq/LuciqRepliesBridge.m +80 -0
  47. package/ios/RNLuciq/LuciqSessionReplayBridge.h +5 -5
  48. package/ios/RNLuciq/{LuciqSessionReplayBridge.mm → LuciqSessionReplayBridge.m} +25 -35
  49. package/ios/RNLuciq/LuciqSurveysBridge.h +5 -5
  50. package/ios/RNLuciq/{LuciqSurveysBridge.mm → LuciqSurveysBridge.m} +35 -34
  51. package/package.json +1 -9
  52. package/scripts/get-github-app-token.sh +70 -0
  53. package/src/modules/BugReporting.ts +3 -3
  54. package/src/modules/Luciq.ts +4 -2
  55. package/src/modules/NetworkLogger.ts +26 -1
  56. package/src/modules/Replies.ts +1 -1
  57. package/src/modules/Surveys.ts +2 -2
  58. package/src/native/NativeBugReporting.ts +6 -3
  59. package/src/native/NativeCrashReporting.ts +2 -2
  60. package/src/native/NativeLuciq.ts +3 -2
  61. package/src/native/NativePackage.ts +2 -52
  62. package/src/native/NativeReplies.ts +1 -1
  63. package/src/native/NativeSurveys.ts +2 -2
  64. package/src/utils/Enums.ts +1 -4
  65. package/src/utils/FeatureFlags.ts +44 -0
  66. package/src/utils/LuciqUtils.ts +21 -1
  67. package/src/utils/XhrNetworkInterceptor.ts +128 -55
  68. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqAPMBaseSpec.java +0 -9
  69. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqBaseSpec.java +0 -33
  70. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqBugReportingBaseSpec.java +0 -33
  71. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqCrashReportingBaseSpec.java +0 -9
  72. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsBaseSpec.java +0 -9
  73. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerBaseSpec.java +0 -33
  74. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqRepliesBaseSpec.java +0 -33
  75. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqSessionReplayBaseSpec.java +0 -33
  76. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqSurveysBaseSpec.java +0 -33
  77. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqAPMBaseSpec.java +0 -11
  78. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqBaseSpec.java +0 -22
  79. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqBugReportingBaseSpec.java +0 -22
  80. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqCrashReportingBaseSpec.java +0 -10
  81. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsBaseSpec.java +0 -10
  82. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerBaseSpec.java +0 -22
  83. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqRepliesBaseSpec.java +0 -22
  84. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqSessionReplayBaseSpec.java +0 -22
  85. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqSurveysBaseSpec.java +0 -22
  86. package/dist/native/specs/NativeAPM.d.ts +0 -21
  87. package/dist/native/specs/NativeAPM.js +0 -2
  88. package/dist/native/specs/NativeBugReporting.d.ts +0 -29
  89. package/dist/native/specs/NativeBugReporting.js +0 -2
  90. package/dist/native/specs/NativeCrashReporting.d.ts +0 -12
  91. package/dist/native/specs/NativeCrashReporting.js +0 -2
  92. package/dist/native/specs/NativeFeatureRequests.d.ts +0 -8
  93. package/dist/native/specs/NativeFeatureRequests.js +0 -2
  94. package/dist/native/specs/NativeLuciq.d.ts +0 -80
  95. package/dist/native/specs/NativeLuciq.js +0 -2
  96. package/dist/native/specs/NativeNetworkLogger.d.ts +0 -16
  97. package/dist/native/specs/NativeNetworkLogger.js +0 -2
  98. package/dist/native/specs/NativeReplies.d.ts +0 -21
  99. package/dist/native/specs/NativeReplies.js +0 -2
  100. package/dist/native/specs/NativeSessionReplay.d.ts +0 -17
  101. package/dist/native/specs/NativeSessionReplay.js +0 -2
  102. package/dist/native/specs/NativeSurveys.d.ts +0 -18
  103. package/dist/native/specs/NativeSurveys.js +0 -2
  104. package/ios/RNLuciq/LuciqBugReportingBridge.mm +0 -234
  105. package/ios/RNLuciq/LuciqCrashReportingBridge.mm +0 -91
  106. package/ios/RNLuciq/LuciqRepliesBridge.mm +0 -86
  107. package/src/native/specs/NativeAPM.ts +0 -47
  108. package/src/native/specs/NativeBugReporting.ts +0 -53
  109. package/src/native/specs/NativeCrashReporting.ts +0 -23
  110. package/src/native/specs/NativeFeatureRequests.ts +0 -10
  111. package/src/native/specs/NativeLuciq.ts +0 -137
  112. package/src/native/specs/NativeNetworkLogger.ts +0 -31
  113. package/src/native/specs/NativeReplies.ts +0 -27
  114. package/src/native/specs/NativeSessionReplay.ts +0 -20
  115. package/src/native/specs/NativeSurveys.ts +0 -23
package/README.md CHANGED
@@ -231,121 +231,3 @@ await APM.addCompletedCustomSpan('Background Task', start, end);
231
231
  ## Documentation
232
232
 
233
233
  For more details about the supported APIs and how to use them, check our [**Documentation**](https://docs.luciq.ai/docs/react-native-overview).
234
-
235
- ## Contributing: Adding a Native Method
236
-
237
- The library is a dual-architecture TurboModule — one spec drives codegen for both the legacy bridge and the new architecture. When you add a new native method, you'll touch the files listed below. The exact Android step depends on which pattern the target module uses.
238
-
239
- ### 1. Spec (one file, source of truth)
240
-
241
- Declare the method in the corresponding spec file under `src/native/specs/`:
242
-
243
- | Module | Spec file |
244
- | -------------------- | -------------------------- |
245
- | Core | `NativeLuciq.ts` |
246
- | `LCQBugReporting` | `NativeBugReporting.ts` |
247
- | `LCQCrashReporting` | `NativeCrashReporting.ts` |
248
- | `LCQAPM` | `NativeAPM.ts` |
249
- | `LCQSurveys` | `NativeSurveys.ts` |
250
- | `LCQReplies` | `NativeReplies.ts` |
251
- | `LCQFeatureRequests` | `NativeFeatureRequests.ts` |
252
- | `LCQSessionReplay` | `NativeSessionReplay.ts` |
253
- | `LCQNetworkLogger` | `NativeNetworkLogger.ts` |
254
-
255
- Example — adding `setFoo(value: string): Promise<boolean>` to Crash Reporting:
256
-
257
- ```ts
258
- // src/native/specs/NativeCrashReporting.ts
259
- export interface Spec extends TurboModule {
260
- // …existing methods…
261
- setFoo(value: string): Promise<boolean>;
262
- }
263
- ```
264
-
265
- Spec type constraints to keep in mind:
266
-
267
- - Parameter types must be: `boolean`, `number`, `string`, `Object`, `UnsafeObject`, `Array<T>`, or explicit `T | null`. No TS enums, no unions of non-null types, no optional `?` parameters, no `Record<K,V>`.
268
- - Enums → `string`. The rich enum type stays in the public wrapper (`src/modules/*.ts`), which converts to the string value before the native call.
269
- - Nullable args → explicit `| null`, not `?`.
270
- - Arbitrary object payloads → `UnsafeObject` (from `react-native/Libraries/Types/CodegenTypes`).
271
- - Callback function args aren't supported. Use a no-arg method plus a `NativeEventEmitter` subscription on the JS side.
272
-
273
- ### 2. JS wrapper types
274
-
275
- Add the method to the legacy interface so public code type-checks:
276
-
277
- ```ts
278
- // src/native/NativeCrashReporting.ts
279
- export interface CrashReportingNativeModule extends NativeModule {
280
- // …existing methods…
281
- setFoo(value: string): Promise<boolean>;
282
- }
283
- ```
284
-
285
- If the method is part of the developer-facing API, also expose it from `src/modules/*.ts` with rich types (enums, overloads, etc.). That wrapper is responsible for converting rich types to the spec-compatible primitives.
286
-
287
- ### 3. iOS (one file — `.mm`)
288
-
289
- Add an `RCT_EXPORT_METHOD` block to the corresponding bridge under `ios/RNLuciq/`:
290
-
291
- ```objc
292
- // ios/RNLuciq/LuciqCrashReportingBridge.mm
293
- RCT_EXPORT_METHOD(setFoo:(NSString *)value
294
- resolve:(RCTPromiseResolveBlock)resolve
295
- reject:(RCTPromiseRejectBlock)reject) {
296
- // implementation
297
- resolve(@YES);
298
- }
299
- ```
300
-
301
- The same `RCT_EXPORT_METHOD` serves both old and new architecture. Match the selector labels (`resolve:`, `reject:`) to the codegen-generated protocol — don't use `resolver:` / `rejecter:`. The `#ifdef RCT_NEW_ARCH_ENABLED` block at the bottom of each bridge (`getTurboModule:`) is already in place; you don't need to touch it.
302
-
303
- ### 4. Android
304
-
305
- All 9 modules use the **shim pattern**. Add the method directly to the real module file in `android/src/main/java/ai/luciq/reactlibrary/RNLuciqXModule.java` with an `@ReactMethod` annotation whose signature matches the spec exactly:
306
-
307
- ```java
308
- @ReactMethod
309
- public void setFoo(String value, Promise promise) {
310
- MainThreadHandler.runOnMainThread(() -> {
311
- // implementation
312
- promise.resolve(true);
313
- });
314
- }
315
- ```
316
-
317
- How it works under the hood: each module extends a thin `RNLuciqXBaseSpec` abstract class that exists in two flavors:
318
-
319
- - `android/src/oldarch/java/.../RNLuciqXBaseSpec.java` — extends `EventEmitterModule` or `ReactContextBaseJavaModule`
320
- - `android/src/newarch/java/.../RNLuciqXBaseSpec.java` — extends the codegen-generated `NativeXSpec`
321
-
322
- Gradle activates one or the other based on `newArchEnabled`. You don't edit these shim files when adding a method — only the main module file. On old arch `@ReactMethod` handles dispatch; on new arch your method's signature overrides the abstract method on `NativeXSpec`.
323
-
324
- If the new-arch abstract signature uses `double` (codegen maps TS `number` → `double`) or `@Nullable Double` (for `number | null`), make sure your method matches exactly — the compiler will tell you if it doesn't.
325
-
326
- ### 5. Verify
327
-
328
- Run the full check:
329
-
330
- ```bash
331
- # Type-check and unit tests
332
- yarn build:lib && yarn test
333
-
334
- # Android — old arch
335
- cd examples/default/android && ./gradlew :app:compileDebugJavaWithJavac
336
-
337
- # Android — new arch
338
- ./gradlew :app:compileDebugJavaWithJavac -PnewArchEnabled=true
339
-
340
- # iOS — old arch
341
- cd examples/default/ios && pod install && xcodebuild -workspace LuciqExample.xcworkspace -scheme LuciqExample -configuration Debug -destination 'generic/platform=iOS Simulator' -sdk iphonesimulator build
342
-
343
- # iOS — new arch
344
- RCT_NEW_ARCH_ENABLED=1 pod install && RCT_NEW_ARCH_ENABLED=1 xcodebuild -workspace LuciqExample.xcworkspace -scheme LuciqExample -configuration Debug -destination 'generic/platform=iOS Simulator' -sdk iphonesimulator build
345
- ```
346
-
347
- All four builds must pass before merging.
348
-
349
- ### Platform-only methods
350
-
351
- If a method only applies to one platform (e.g. `setNotificationIcon` for Android, `setShakingThresholdForiPad` for iOS), still declare it in the spec — then stub it as a no-op on the other platform so the unified abstract class stays satisfied.
package/RNLuciq.podspec CHANGED
@@ -15,11 +15,7 @@ Pod::Spec.new do |s|
15
15
  s.platform = :ios, "15.0"
16
16
  s.source_files = "ios/**/*.{h,m,mm}"
17
17
 
18
- if respond_to?(:install_modules_dependencies, true)
19
- install_modules_dependencies(s)
20
- else
21
- s.dependency 'React-Core'
22
- end
23
-
18
+ s.dependency 'React-Core'
24
19
  use_luciq!(s)
20
+
25
21
  end
@@ -1,19 +1,4 @@
1
- boolean isNewArchitectureEnabled() {
2
- // Checks `newArchEnabled=true` in any of:
3
- // * consuming app's `android/gradle.properties` (via rootProject)
4
- // * this library's `gradle.properties` (via project)
5
- // * `-PnewArchEnabled=true` on the command line
6
- def fromRoot = rootProject.hasProperty("newArchEnabled") &&
7
- rootProject.getProperty("newArchEnabled") == "true"
8
- def fromProject = project.hasProperty("newArchEnabled") &&
9
- project.getProperty("newArchEnabled") == "true"
10
- return fromRoot || fromProject
11
- }
12
-
13
1
  apply plugin: 'com.android.library'
14
- if (isNewArchitectureEnabled()) {
15
- apply plugin: 'com.facebook.react'
16
- }
17
2
 
18
3
  apply from: './jacoco.gradle'
19
4
  apply from: './native.gradle'
@@ -84,16 +69,6 @@ android {
84
69
  abortOnError true
85
70
  // SuppressLint WrongConstant was used to suppress errors when using arrays of ints to represent annotations.
86
71
  }
87
-
88
- sourceSets {
89
- main {
90
- if (isNewArchitectureEnabled()) {
91
- java.srcDirs += ['src/newarch/java']
92
- } else {
93
- java.srcDirs += ['src/oldarch/java']
94
- }
95
- }
96
- }
97
72
  }
98
73
 
99
74
  dependencies {
@@ -1 +1 @@
1
- -keep class com.luciq.** {*;}
1
+ -keep class ai.luciq.** {*;}
@@ -28,7 +28,9 @@ import ai.luciq.apm.networkinterception.cp.APMCPNetworkLog;
28
28
  import ai.luciq.reactlibrary.utils.EventEmitterModule;
29
29
  import ai.luciq.reactlibrary.utils.MainThreadHandler;
30
30
 
31
- public class RNLuciqAPMModule extends RNLuciqAPMBaseSpec {
31
+ public class RNLuciqAPMModule extends EventEmitterModule {
32
+
33
+ private static final String NET_TAG = "LCQ-RN-NET";
32
34
 
33
35
  public RNLuciqAPMModule(ReactApplicationContext reactApplicationContext) {
34
36
  super(reactApplicationContext);
@@ -45,7 +47,7 @@ public class RNLuciqAPMModule extends RNLuciqAPMBaseSpec {
45
47
  * Pauses the current thread for 3 seconds.
46
48
  */
47
49
  @ReactMethod
48
- public void lcqSleep() {
50
+ public void LCQSleep() {
49
51
  MainThreadHandler.runOnMainThread(new Runnable() {
50
52
  @Override
51
53
  public void run() {
@@ -310,7 +312,7 @@ public class RNLuciqAPMModule extends RNLuciqAPMBaseSpec {
310
312
  * debugging and troubleshooting network-related issues.
311
313
  */
312
314
  @ReactMethod
313
- public void networkLogAndroid(final double requestStartTime,
315
+ private void networkLogAndroid(final double requestStartTime,
314
316
  final double requestDuration,
315
317
  final String requestHeaders,
316
318
  final String requestBody,
@@ -328,6 +330,7 @@ public class RNLuciqAPMModule extends RNLuciqAPMBaseSpec {
328
330
  @Nullable final String gqLCQueryName,
329
331
  @Nullable final String serverErrorMessage
330
332
  ) {
333
+ Log.d(NET_TAG, "[networkLogAndroid-APM] Received from JS: " + requestMethod + " " + requestUrl + ", status=" + (int) statusCode + ", duration=" + (long) requestDuration + "ms, startTime=" + (long) requestStartTime + ", error=" + errorDomain + ", gqlQuery=" + gqLCQueryName);
331
334
  try {
332
335
  APMNetworkLogger networkLogger = new APMNetworkLogger();
333
336
 
@@ -349,8 +352,10 @@ public class RNLuciqAPMModule extends RNLuciqAPMBaseSpec {
349
352
  }
350
353
 
351
354
  } catch (Exception e) {
355
+ Log.e(NET_TAG, "[networkLogAndroid-APM] Error parsing W3C attributes for " + requestMethod + " " + requestUrl, e);
352
356
  e.printStackTrace();
353
357
  }
358
+ Log.d(NET_TAG, "[networkLogAndroid-APM] W3C attrs — isW3cHeaderFound=" + isW3cHeaderFound + ", partialId=" + partialId + ", networkStartTimeInSeconds=" + networkStartTimeInSeconds + ", generatedHeader=" + (w3cAttributes != null && !w3cAttributes.isNull("w3cGeneratedHeader") ? w3cAttributes.getString("w3cGeneratedHeader") : "null") + ", caughtHeader=" + (w3cAttributes != null && !w3cAttributes.isNull("w3cCaughtHeader") ? w3cAttributes.getString("w3cCaughtHeader") : "null"));
354
359
  APMCPNetworkLog.W3CExternalTraceAttributes w3cExternalTraceAttributes =
355
360
  new APMCPNetworkLog.W3CExternalTraceAttributes(
356
361
  isW3cHeaderFound,
@@ -382,13 +387,17 @@ public class RNLuciqAPMModule extends RNLuciqAPMBaseSpec {
382
387
  serverErrorMessage,
383
388
  w3cExternalTraceAttributes
384
389
  );
390
+ Log.d(NET_TAG, "[networkLogAndroid-APM] Successfully invoked APMNetworkLogger.log via reflection: " + requestMethod + " " + requestUrl);
385
391
  } else {
392
+ Log.e(NET_TAG, "[networkLogAndroid-APM] APMNetworkLogger.log method NOT found by reflection — network log will be lost: " + requestMethod + " " + requestUrl);
386
393
  Log.e("IB-CP-Bridge", "APMNetworkLogger.log was not found by reflection");
387
394
  }
388
395
  } catch (Throwable e) {
396
+ Log.e(NET_TAG, "[networkLogAndroid-APM] Exception invoking APMNetworkLogger.log: " + e.getMessage() + " for " + requestMethod + " " + requestUrl, e);
389
397
  e.printStackTrace();
390
398
  }
391
399
  } catch (Throwable e) {
400
+ Log.e(NET_TAG, "[networkLogAndroid-APM] Top-level exception: " + e.getMessage() + " for " + requestMethod + " " + requestUrl, e);
392
401
  e.printStackTrace();
393
402
  }
394
403
  }
@@ -5,6 +5,7 @@ import android.annotation.TargetApi;
5
5
  import androidx.annotation.Nullable;
6
6
 
7
7
  import com.facebook.react.bridge.Arguments;
8
+ import com.facebook.react.bridge.Callback;
8
9
  import com.facebook.react.bridge.ReactApplicationContext;
9
10
  import com.facebook.react.bridge.ReactMethod;
10
11
  import com.facebook.react.bridge.ReadableArray;
@@ -19,6 +20,7 @@ import ai.luciq.library.invocation.OnInvokeCallback;
19
20
  import ai.luciq.library.invocation.util.LuciqFloatingButtonEdge;
20
21
  import ai.luciq.library.invocation.util.LuciqVideoRecordingButtonPosition;
21
22
  import ai.luciq.reactlibrary.utils.ArrayUtil;
23
+ import ai.luciq.reactlibrary.utils.EventEmitterModule;
22
24
  import ai.luciq.reactlibrary.utils.MainThreadHandler;
23
25
  import ai.luciq.bug.userConsent.ActionType;
24
26
  import java.util.ArrayList;
@@ -27,7 +29,7 @@ import ai.luciq.bug.ProactiveReportingConfigs;
27
29
 
28
30
  import javax.annotation.Nonnull;
29
31
 
30
- public class RNLuciqBugReportingModule extends RNLuciqBugReportingBaseSpec {
32
+ public class RNLuciqBugReportingModule extends EventEmitterModule {
31
33
  public RNLuciqBugReportingModule(ReactApplicationContext reactContext) {
32
34
  super(reactContext);
33
35
  }
@@ -38,6 +40,16 @@ public class RNLuciqBugReportingModule extends RNLuciqBugReportingBaseSpec {
38
40
  return "LCQBugReporting";
39
41
  }
40
42
 
43
+ @ReactMethod
44
+ public void addListener(String event) {
45
+ super.addListener(event);
46
+ }
47
+
48
+ @ReactMethod
49
+ public void removeListeners(Integer count) {
50
+ super.removeListeners(count);
51
+ }
52
+
41
53
  /**
42
54
  * Enable or disable all BugReporting related features.
43
55
  * @param isEnabled boolean indicating enabled or disabled.
@@ -229,7 +241,7 @@ public class RNLuciqBugReportingModule extends RNLuciqBugReportingBaseSpec {
229
241
  * invoking the SDK
230
242
  */
231
243
  @ReactMethod
232
- public void setOnInvokeHandler() {
244
+ public void setOnInvokeHandler(final Callback onInvokeHandler) {
233
245
  MainThreadHandler.runOnMainThread(new Runnable() {
234
246
  @Override
235
247
  public void run() {
@@ -253,13 +265,13 @@ public class RNLuciqBugReportingModule extends RNLuciqBugReportingBaseSpec {
253
265
  * @param floatingButtonOffset integer offset from the left or right edge of the screen.
254
266
  */
255
267
  @ReactMethod
256
- public void setFloatingButtonEdge(final String floatingButtonEdge, final double floatingButtonOffset) {
268
+ public void setFloatingButtonEdge(final String floatingButtonEdge, final int floatingButtonOffset) {
257
269
  MainThreadHandler.runOnMainThread(new Runnable() {
258
270
  @Override
259
271
  public void run() {
260
272
  final LuciqFloatingButtonEdge parsedEdge = ArgsRegistry.floatingButtonEdges
261
273
  .getOrDefault(floatingButtonEdge, LuciqFloatingButtonEdge.RIGHT);
262
- BugReporting.setFloatingButtonOffset((int) floatingButtonOffset);
274
+ BugReporting.setFloatingButtonOffset(floatingButtonOffset);
263
275
  BugReporting.setFloatingButtonEdge(parsedEdge);
264
276
  }
265
277
  });
@@ -274,7 +286,7 @@ public class RNLuciqBugReportingModule extends RNLuciqBugReportingBaseSpec {
274
286
  * dismissing the SDK.
275
287
  */
276
288
  @ReactMethod
277
- public void setOnSDKDismissedHandler() {
289
+ public void setOnSDKDismissedHandler(final Callback handler) {
278
290
  MainThreadHandler.runOnMainThread(new Runnable() {
279
291
  @Override
280
292
  public void run() {
@@ -304,12 +316,12 @@ public class RNLuciqBugReportingModule extends RNLuciqBugReportingBaseSpec {
304
316
  * @param androidThreshold Threshold for android devices.
305
317
  */
306
318
  @ReactMethod
307
- public void setShakingThresholdForAndroid(final double androidThreshold) {
319
+ public void setShakingThresholdForAndroid(final int androidThreshold) {
308
320
  MainThreadHandler.runOnMainThread(new Runnable() {
309
321
  @Override
310
322
  public void run() {
311
323
  try {
312
- BugReporting.setShakingThreshold((int) androidThreshold);
324
+ BugReporting.setShakingThreshold(androidThreshold);
313
325
  } catch (Exception e) {
314
326
  e.printStackTrace();
315
327
  }
@@ -384,7 +396,7 @@ public class RNLuciqBugReportingModule extends RNLuciqBugReportingBaseSpec {
384
396
  * @param reportTypes (Optional) Array of reportType. If it's not passed, the limit will apply to all report types.
385
397
  */
386
398
  @ReactMethod
387
- public void setCommentMinimumCharacterCount(final double limit, final ReadableArray reportTypes){
399
+ public void setCommentMinimumCharacterCount(final int limit, final ReadableArray reportTypes){
388
400
  MainThreadHandler.runOnMainThread(new Runnable() {
389
401
  @SuppressLint("WrongConstant")
390
402
  @Override
@@ -398,7 +410,7 @@ public class RNLuciqBugReportingModule extends RNLuciqBugReportingBaseSpec {
398
410
  typesInts[i] = types.get(i);
399
411
  }
400
412
 
401
- BugReporting.setCommentMinimumCharacterCountForBugReportType((int) limit, typesInts); } catch (Exception e) {
413
+ BugReporting.setCommentMinimumCharacterCountForBugReportType(limit, typesInts); } catch (Exception e) {
402
414
  e.printStackTrace();
403
415
  }
404
416
  }
@@ -436,13 +448,13 @@ public class RNLuciqBugReportingModule extends RNLuciqBugReportingBaseSpec {
436
448
  * @param gapBetweenModals controls the time gap between showing 2 proactive reporting dialogs in seconds
437
449
  */
438
450
  @ReactMethod
439
- public void setProactiveReportingConfigurations(final boolean enabled, final double gapBetweenModals, final double modalDelayAfterDetection) {
451
+ public void setProactiveReportingConfigurations(final boolean enabled, final int gapBetweenModals, final int modalDelayAfterDetection) {
440
452
  MainThreadHandler.runOnMainThread(new Runnable() {
441
453
  @Override
442
454
  public void run() {
443
455
  ProactiveReportingConfigs configs = new ProactiveReportingConfigs.Builder()
444
- .setGapBetweenModals((int) gapBetweenModals) // Time in seconds
445
- .setModalDelayAfterDetection((int) modalDelayAfterDetection) // Time in seconds
456
+ .setGapBetweenModals(gapBetweenModals) // Time in seconds
457
+ .setModalDelayAfterDetection(modalDelayAfterDetection) // Time in seconds
446
458
  .isEnabled(enabled) //Enable/disable
447
459
  .build();
448
460
  BugReporting.setProactiveReportingConfigurations(configs);
@@ -451,20 +463,4 @@ public class RNLuciqBugReportingModule extends RNLuciqBugReportingBaseSpec {
451
463
  }
452
464
  });
453
465
  }
454
-
455
- @ReactMethod
456
- public void setAutoScreenRecordingDuration(double maxDuration) {
457
- }
458
-
459
- @ReactMethod
460
- public void setShakingThresholdForiPhone(double threshold) {
461
- }
462
-
463
- @ReactMethod
464
- public void setShakingThresholdForiPad(double threshold) {
465
- }
466
-
467
- @ReactMethod
468
- public void setDidSelectPromptOptionHandler() {
469
- }
470
466
  }
@@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
6
6
 
7
7
  import com.facebook.react.bridge.Promise;
8
8
  import com.facebook.react.bridge.ReactApplicationContext;
9
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
9
10
  import com.facebook.react.bridge.ReactMethod;
10
11
  import com.facebook.react.bridge.ReadableMap;
11
12
  import ai.luciq.crash.CrashReporting;
@@ -23,7 +24,7 @@ import java.util.Map;
23
24
  import javax.annotation.Nonnull;
24
25
  import javax.annotation.Nullable;
25
26
 
26
- public class RNLuciqCrashReportingModule extends RNLuciqCrashReportingBaseSpec {
27
+ public class RNLuciqCrashReportingModule extends ReactContextBaseJavaModule {
27
28
 
28
29
  public RNLuciqCrashReportingModule(ReactApplicationContext reactApplicationContext) {
29
30
  super(reactApplicationContext);
@@ -66,9 +67,9 @@ public class RNLuciqCrashReportingModule extends RNLuciqCrashReportingBaseSpec {
66
67
  * finishes processing/handling the crash.
67
68
  */
68
69
  @ReactMethod
69
- public void sendJSCrash(final ReadableMap exceptionObject, final Promise promise) {
70
+ public void sendJSCrash(final String exceptionObject, final Promise promise) {
70
71
  try {
71
- JSONObject jsonObject = exceptionObject == null ? new JSONObject() : new JSONObject(exceptionObject.toHashMap());
72
+ JSONObject jsonObject = new JSONObject(exceptionObject);
72
73
  sendJSCrashByReflection(jsonObject, false, new Runnable() {
73
74
  @Override
74
75
  public void run() {
@@ -89,9 +90,9 @@ public class RNLuciqCrashReportingModule extends RNLuciqCrashReportingBaseSpec {
89
90
  * @param level different severity levels for errors
90
91
  */
91
92
  @ReactMethod
92
- public void sendHandledJSCrash(final ReadableMap exceptionObject, @Nullable final ReadableMap userAttributes, @Nullable final String fingerprint, @Nullable final String level, final Promise promise) {
93
+ public void sendHandledJSCrash(final String exceptionObject, @Nullable final ReadableMap userAttributes, @Nullable final String fingerprint, @Nullable final String level) {
93
94
  try {
94
- final JSONObject jsonObject = exceptionObject == null ? new JSONObject() : new JSONObject(exceptionObject.toHashMap());
95
+ final JSONObject jsonObject = new JSONObject(exceptionObject);
95
96
  MainThreadHandler.runOnMainThread(new Runnable() {
96
97
  @Override
97
98
  public void run() {
@@ -107,17 +108,14 @@ public class RNLuciqCrashReportingModule extends RNLuciqCrashReportingBaseSpec {
107
108
 
108
109
  RNLuciqReactnativeModule.clearCurrentReport();
109
110
  }
110
- promise.resolve(null);
111
111
  } catch (ClassNotFoundException | IllegalAccessException |
112
112
  InvocationTargetException e) {
113
113
  e.printStackTrace();
114
- promise.resolve(null);
115
114
  }
116
115
  }
117
116
  });
118
117
  } catch (Throwable e) {
119
118
  e.printStackTrace();
120
- promise.resolve(null);
121
119
  }
122
120
  }
123
121
 
@@ -152,7 +150,7 @@ public class RNLuciqCrashReportingModule extends RNLuciqCrashReportingBaseSpec {
152
150
  * @param isEnabled boolean indicating enabled or disabled.
153
151
  */
154
152
  @ReactMethod
155
- public void setNDKCrashesEnabled(final boolean isEnabled, final Promise promise) {
153
+ public void setNDKCrashesEnabled(final boolean isEnabled) {
156
154
  MainThreadHandler.runOnMainThread(new Runnable() {
157
155
  @Override
158
156
  public void run() {
@@ -165,16 +163,7 @@ public class RNLuciqCrashReportingModule extends RNLuciqCrashReportingBaseSpec {
165
163
  } catch (Exception e) {
166
164
  e.printStackTrace();
167
165
  }
168
- promise.resolve(null);
169
166
  }
170
167
  });
171
168
  }
172
-
173
- @ReactMethod
174
- public void addListener(String eventName) {
175
- }
176
-
177
- @ReactMethod
178
- public void removeListeners(double count) {
179
- }
180
169
  }
@@ -3,6 +3,7 @@ package ai.luciq.reactlibrary;
3
3
  import android.annotation.SuppressLint;
4
4
 
5
5
  import com.facebook.react.bridge.ReactApplicationContext;
6
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
6
7
  import com.facebook.react.bridge.ReactMethod;
7
8
  import com.facebook.react.bridge.ReadableArray;
8
9
  import ai.luciq.featuresrequest.FeatureRequests;
@@ -14,7 +15,7 @@ import java.util.ArrayList;
14
15
 
15
16
  import javax.annotation.Nonnull;
16
17
 
17
- public class RNLuciqFeatureRequestsModule extends RNLuciqFeatureRequestsBaseSpec {
18
+ public class RNLuciqFeatureRequestsModule extends ReactContextBaseJavaModule {
18
19
 
19
20
  public RNLuciqFeatureRequestsModule(ReactApplicationContext reactApplicationContext) {
20
21
  super(reactApplicationContext);
@@ -19,6 +19,7 @@ import com.facebook.react.bridge.WritableNativeMap;
19
19
  import ai.luciq.apm.InternalAPM;
20
20
  import ai.luciq.apm.sanitization.OnCompleteCallback;
21
21
  import ai.luciq.library.logging.listeners.networklogs.NetworkLogSnapshot;
22
+ import ai.luciq.reactlibrary.utils.EventEmitterModule;
22
23
  import ai.luciq.reactlibrary.utils.MainThreadHandler;
23
24
 
24
25
  import org.json.JSONException;
@@ -29,7 +30,9 @@ import java.util.Map;
29
30
  import java.util.concurrent.ConcurrentHashMap;
30
31
 
31
32
 
32
- public class RNLuciqNetworkLoggerModule extends RNLuciqNetworkLoggerBaseSpec {
33
+ public class RNLuciqNetworkLoggerModule extends EventEmitterModule {
34
+
35
+ private static final String NET_TAG = "LCQ-RN-NET";
33
36
 
34
37
  public final ConcurrentHashMap<String, OnCompleteCallback<NetworkLogSnapshot>> callbackMap = new ConcurrentHashMap<String, OnCompleteCallback<NetworkLogSnapshot>>();
35
38
 
@@ -45,8 +48,20 @@ public class RNLuciqNetworkLoggerModule extends RNLuciqNetworkLoggerBaseSpec {
45
48
  }
46
49
 
47
50
 
51
+ @ReactMethod
52
+ public void addListener(String event) {
53
+ super.addListener(event);
54
+ }
55
+
56
+ @ReactMethod
57
+ public void removeListeners(Integer count) {
58
+ super.removeListeners(count);
59
+ }
60
+
48
61
  private boolean getFlagValue(String key) {
49
- return InternalAPM._isFeatureEnabledCP(key, "");
62
+ boolean value = InternalAPM._isFeatureEnabledCP(key, "");
63
+ Log.d(NET_TAG, "[getFlagValue] key=" + key + ", value=" + value);
64
+ return value;
50
65
  }
51
66
 
52
67
  private WritableMap convertFromMapToWritableMap(Map<String, Object> map) {
@@ -73,14 +88,24 @@ public class RNLuciqNetworkLoggerModule extends RNLuciqNetworkLoggerBaseSpec {
73
88
  /**
74
89
  * Get first time Value of [cp_native_interception_enabled] flag
75
90
  */
76
- @ReactMethod(isBlockingSynchronousMethod = true)
77
- public boolean isNativeInterceptionEnabled() {
78
- try {
79
- return getFlagValue(CP_NATIVE_INTERCEPTION_ENABLED);
80
- } catch (Exception e) {
81
- e.printStackTrace();
82
- return false; // Will rollback to JS interceptor
83
- }
91
+ @ReactMethod
92
+ public void isNativeInterceptionEnabled(Promise promise) {
93
+ Log.d(NET_TAG, "[isNativeInterceptionEnabled] Querying CP_NATIVE_INTERCEPTION_ENABLED flag");
94
+ MainThreadHandler.runOnMainThread(new Runnable() {
95
+ @Override
96
+ public void run() {
97
+ try {
98
+ boolean enabled = getFlagValue(CP_NATIVE_INTERCEPTION_ENABLED);
99
+ Log.d(NET_TAG, "[isNativeInterceptionEnabled] Result=" + enabled);
100
+ promise.resolve(enabled);
101
+ } catch (Exception e) {
102
+ Log.e(NET_TAG, "[isNativeInterceptionEnabled] Error — falling back to false (JS interceptor)", e);
103
+ e.printStackTrace();
104
+ promise.resolve(false);
105
+ }
106
+
107
+ }
108
+ });
84
109
  }
85
110
 
86
111
  /**
@@ -90,14 +115,18 @@ public class RNLuciqNetworkLoggerModule extends RNLuciqNetworkLoggerBaseSpec {
90
115
  */
91
116
  @ReactMethod
92
117
  public void hasAPMNetworkPlugin(Promise promise) {
118
+ Log.d(NET_TAG, "[hasAPMNetworkPlugin] Querying APM_NETWORK_PLUGIN_INSTALLED flag");
93
119
  MainThreadHandler.runOnMainThread(new Runnable() {
94
120
  @Override
95
121
  public void run() {
96
122
  try {
97
- promise.resolve(getFlagValue(APM_NETWORK_PLUGIN_INSTALLED));
123
+ boolean hasPlugin = getFlagValue(APM_NETWORK_PLUGIN_INSTALLED);
124
+ Log.d(NET_TAG, "[hasAPMNetworkPlugin] Result=" + hasPlugin);
125
+ promise.resolve(hasPlugin);
98
126
  } catch (Exception e) {
127
+ Log.e(NET_TAG, "[hasAPMNetworkPlugin] Error — falling back to false", e);
99
128
  e.printStackTrace();
100
- promise.resolve(false); // Will rollback to JS interceptor
129
+ promise.resolve(false);
101
130
  }
102
131
 
103
132
  }
@@ -106,13 +135,15 @@ public class RNLuciqNetworkLoggerModule extends RNLuciqNetworkLoggerBaseSpec {
106
135
 
107
136
 
108
137
  @ReactMethod
109
- public void registerNetworkLogsListener(@androidx.annotation.Nullable String type) {
138
+ public void registerNetworkLogsListener() {
139
+ Log.d(NET_TAG, "[registerNetworkLogsListener] Registering network log sanitizer");
110
140
  MainThreadHandler.runOnMainThread(new Runnable() {
111
141
  @Override
112
142
  public void run() {
113
143
  InternalAPM._registerNetworkLogSanitizer((networkLogSnapshot, onCompleteCallback) -> {
114
144
  final String id = String.valueOf(onCompleteCallback.hashCode());
115
145
  callbackMap.put(id, onCompleteCallback);
146
+ Log.d(NET_TAG, "[NetworkLogSanitizer] Received snapshot — id=" + id + ", url=" + networkLogSnapshot.getUrl() + ", responseCode=" + networkLogSnapshot.getResponseCode() + ", callbackMapSize=" + callbackMap.size());
116
147
 
117
148
  WritableMap networkSnapshotParams = Arguments.createMap();
118
149
  networkSnapshotParams.putString("id", id);
@@ -130,6 +161,7 @@ public class RNLuciqNetworkLoggerModule extends RNLuciqNetworkLoggerBaseSpec {
130
161
  }
131
162
 
132
163
  sendEvent(Constants.LCQ_NETWORK_LOGGER_HANDLER, networkSnapshotParams);
164
+ Log.d(NET_TAG, "[NetworkLogSanitizer] Sent event to JS: " + Constants.LCQ_NETWORK_LOGGER_HANDLER + " for " + networkLogSnapshot.getUrl());
133
165
  });
134
166
  }
135
167
  });
@@ -137,10 +169,12 @@ public class RNLuciqNetworkLoggerModule extends RNLuciqNetworkLoggerBaseSpec {
137
169
 
138
170
  @ReactMethod
139
171
  public void resetNetworkLogsListener() {
172
+ Log.d(NET_TAG, "[resetNetworkLogsListener] Clearing network log sanitizer, callbackMapSize=" + callbackMap.size());
140
173
  MainThreadHandler.runOnMainThread(new Runnable() {
141
174
  @Override
142
175
  public void run() {
143
176
  InternalAPM._registerNetworkLogSanitizer(null);
177
+ Log.d(NET_TAG, "[resetNetworkLogsListener] Sanitizer cleared");
144
178
  }
145
179
  });
146
180
  }
@@ -151,40 +185,33 @@ public class RNLuciqNetworkLoggerModule extends RNLuciqNetworkLoggerBaseSpec {
151
185
  String callbackID,
152
186
  String requestBody,
153
187
  String responseBody,
154
- double responseCode,
188
+ int responseCode,
155
189
  ReadableMap requestHeaders,
156
190
  ReadableMap responseHeaders
157
191
  ) {
192
+ Log.d(NET_TAG, "[updateNetworkLogSnapshot] callbackID=" + callbackID + ", url=" + url + ", responseCode=" + responseCode + ", callbackMapSize=" + callbackMap.size());
158
193
  try {
159
- // Convert ReadableMap to a Java Map for easier handling
160
194
  Map<String, Object> requestHeadersMap = convertReadableMapToMap(requestHeaders);
161
195
  Map<String, Object> responseHeadersMap = convertReadableMapToMap(responseHeaders);
162
196
 
163
197
  NetworkLogSnapshot modifiedSnapshot = null;
164
198
  if (!url.isEmpty()) {
165
- modifiedSnapshot = new NetworkLogSnapshot(url, requestHeadersMap, requestBody, responseHeadersMap, responseBody, (int) responseCode);
199
+ modifiedSnapshot = new NetworkLogSnapshot(url, requestHeadersMap, requestBody, responseHeadersMap, responseBody, responseCode);
200
+ } else {
201
+ Log.d(NET_TAG, "[updateNetworkLogSnapshot] Empty URL — snapshot will be null (request filtered/removed)");
166
202
  }
167
203
 
168
204
  final OnCompleteCallback<NetworkLogSnapshot> callback = callbackMap.get(callbackID);
169
205
  if (callback != null) {
170
206
  callback.onComplete(modifiedSnapshot);
171
207
  callbackMap.remove(callbackID);
208
+ Log.d(NET_TAG, "[updateNetworkLogSnapshot] Callback invoked and removed for " + callbackID + ", remaining=" + callbackMap.size());
209
+ } else {
210
+ Log.e(NET_TAG, "[updateNetworkLogSnapshot] No callback found for callbackID=" + callbackID + " — possible leak or duplicate call, mapKeys=" + callbackMap.keySet());
172
211
  }
173
212
  } catch (Exception e) {
174
- // Reject the promise to indicate an error occurred
213
+ Log.e(NET_TAG, "[updateNetworkLogSnapshot] Exception processing snapshot: " + e.getMessage() + " for callbackID=" + callbackID, e);
175
214
  Log.e("IB-CP-Bridge", "LuciqNetworkLogger.updateNetworkLogSnapshot failed to parse the network snapshot object.");
176
215
  }
177
216
  }
178
-
179
- @ReactMethod
180
- public void setNetworkLoggingRequestFilterPredicateIOS(String id, boolean value) {
181
- }
182
-
183
- @ReactMethod
184
- public void forceStartNetworkLoggingIOS() {
185
- }
186
-
187
- @ReactMethod
188
- public void forceStopNetworkLoggingIOS() {
189
- }
190
217
  }