@coralogix/react-native-plugin 0.1.5 → 0.1.7

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 CHANGED
@@ -1,3 +1,21 @@
1
+ ## 0.1.7 (2025-11-02)
2
+
3
+ ### 🚀 Features
4
+
5
+ - added automatic navigation detection using the @react-navigation/native package
6
+
7
+ ### Patch
8
+ - Bump android native version to 2.5.6
9
+
10
+ ## 0.1.6 (2025-10-26)
11
+ ### Patch
12
+ - Bump android native version to 2.5.51
13
+ - Bump ios native version to 1.3.0
14
+
15
+ ### 🚀 Features
16
+ - Integrate support for the Coralogix Gradle Plugin for automatic network instrumentation
17
+ - Added granular control for disabling only specific mobile vitals detectors
18
+
1
19
  ## 0.1.5 (2025-10-13)
2
20
 
3
21
  ### 🩹 Fixes
package/CxSdk.podspec CHANGED
@@ -16,8 +16,8 @@ Pod::Spec.new do |s|
16
16
 
17
17
  s.source_files = "ios/**/*.{h,m,mm,swift}"
18
18
 
19
- s.dependency 'Coralogix','1.2.3'
20
- s.dependency 'CoralogixInternal','1.2.3'
19
+ s.dependency 'Coralogix','1.3.0'
20
+ s.dependency 'CoralogixInternal','1.3.0'
21
21
 
22
22
 
23
23
  # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
package/README.md CHANGED
@@ -78,15 +78,16 @@ CoralogixRum.setViewContext({
78
78
  ```
79
79
 
80
80
  You can automatically track view changes by using [react-navigation](https://reactnavigation.org/docs/navigation-container/#onstatechange).
81
+ Wrap your navigation ref with our `attachReactNavigationObserver` hook like so:
81
82
 
82
83
  ```javascript
84
+ const navigationRef = createNavigationContainerRef();
85
+ const navHooks = attachReactNavigationObserver(navigationRef);
86
+
83
87
  <NavigationContainer
84
88
  ref={navigationRef}
85
- onStateChange={() => {
86
- const currentRouteName = navigationRef.current.getCurrentRoute().name;
87
-
88
- CoralogixRum.setViewContext({ view: currentRouteName });
89
- }}
89
+ onReady={navHooks.onReady}
90
+ onStateChange={navHooks.onStateChange}
90
91
  >
91
92
  >{/* ... */}
92
93
  </NavigationContainer>
@@ -112,6 +113,24 @@ await CoralogixRum.init({
112
113
  });
113
114
  ```
114
115
 
116
+ ### Mobile Vital Detectors
117
+
118
+ Disable specific mobile vitals detection and collection
119
+
120
+ ```javascript
121
+ await CoralogixRum.init({
122
+ // ...
123
+ mobileVitals: {
124
+ warm: true,
125
+ cold: true,
126
+ cpu: true,
127
+ memory: true,
128
+ rendering: true,
129
+ slowFrozenFrames: true,
130
+ }
131
+ });
132
+ ```
133
+
115
134
  ### Ignore Errors
116
135
 
117
136
  The ignoreErrors option allows you to exclude errors that meet specific criteria.
@@ -177,6 +196,52 @@ await CoralogixRum.init({
177
196
  });
178
197
  ```
179
198
 
199
+ ### Optional - Coralogix Gradle Plugin (Android)
200
+
201
+ The Coralogix Gradle Plugin automatically instruments all OkHttp clients in your app (including third-party SDKs) at build time.
202
+ This ensures that all network traffic is automatically traced and reported to Coralogix, with no manual setup or code changes required.
203
+ This plugin is especially useful for instrumenting networking libraries that create their own OkHttpClient instances internally and would otherwise be impossible to monitor.
204
+
205
+ #### Apply the plugin
206
+
207
+ 1. Add the plugin to your project classpath <br /> In your project-level `build.gradle` file:
208
+ ```groovy
209
+ buildscript {
210
+ dependencies {
211
+ classpath "com.coralogix.gradle.plugin:gradle-plugin:0.0.2"
212
+ }
213
+ }
214
+ ```
215
+
216
+ 2. Apply the plugin in your app module <br /> At the top of your app-level build.gradle file:
217
+
218
+ ```groovy
219
+ apply plugin: "com.coralogix.gradle.plugin"
220
+ ```
221
+
222
+ #### Configure the plugin
223
+
224
+ The plugin exposes a simple Gradle extension you can use in your app module:
225
+
226
+ ```groovy
227
+ coralogix {
228
+ // Enable or disable instrumentation (default: true)
229
+ enabled = true
230
+
231
+ // Print debug logs during the build process (default: false)
232
+ log = false
233
+ }
234
+ ```
235
+
236
+ If the default configuration suits your needs, you can safely omit this block — the defaults will apply automatically.
237
+
238
+ #### Note
239
+
240
+ This plugin is optional.
241
+ Regular JavaScript `fetch` calls and standard network requests will still be instrumented without it.
242
+
243
+ However, the plugin is the only way to capture network activity from third-party libraries or SDKs that use their own `OkHttpClient` instances internally.
244
+
180
245
  ### Troubleshooting
181
246
 
182
247
  #### URL.origin is not implemented
@@ -75,7 +75,7 @@ dependencies {
75
75
  implementation "com.facebook.react:react-android"
76
76
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
77
77
 
78
- implementation "com.coralogix:android-sdk:2.5.2"
78
+ implementation "com.coralogix:android-sdk:2.5.6"
79
79
  }
80
80
 
81
81
  react {
@@ -15,6 +15,7 @@ import com.coralogix.android.sdk.model.CoralogixOptions
15
15
  import com.coralogix.android.sdk.model.Framework
16
16
  import com.coralogix.android.sdk.model.HybridMetric
17
17
  import com.coralogix.android.sdk.model.Instrumentation
18
+ import com.coralogix.android.sdk.model.MobileVitalType
18
19
  import com.coralogix.android.sdk.model.UserContext
19
20
  import com.coralogix.android.sdk.model.ViewContext
20
21
  import com.facebook.react.bridge.Arguments
@@ -171,6 +172,12 @@ class CxSdkModule(reactContext: ReactApplicationContext) :
171
172
  CoralogixRum.reportMobileVitalsMeasurement(type, list)
172
173
  }
173
174
 
175
+ @ReactMethod
176
+ override fun isCoralogixGradlePluginApplied(promise: Promise) {
177
+ val applied = CoralogixRum.isCoralogixGradlePluginApplied(reactApplicationContext)
178
+ promise.resolve(applied)
179
+ }
180
+
174
181
  @ReactMethod
175
182
  override fun shutdown(promise: Promise) {
176
183
  Handler(Looper.getMainLooper()).post {
@@ -222,11 +229,11 @@ class CxSdkModule(reactContext: ReactApplicationContext) :
222
229
  userContext = getMap("user_context")?.toUserContext() ?: UserContext(),
223
230
  viewContext = ViewContext(getMap("view_context")?.getString("view") ?: ""),
224
231
  instrumentations = getMap("instrumentations")?.toInstrumentationMap() ?: mapOf(),
232
+ mobileVitalsOptions = getMap("mobileVitals")?.toMobileVitalsOptions() ?: mapOf(),
225
233
  ignoreUrls = getArray("ignoreUrls")?.handleStringOrRegexList() ?: listOf(),
226
234
  ignoreErrors = getArray("ignoreErrors")?.handleStringOrRegexList() ?: listOf(),
227
235
  sessionSampleRate = 100,
228
236
  traceParentInHeader = isTraceParentInHeaderEnabled,
229
- fpsSamplingSeconds = if (hasKey("fpsSamplingSeconds")) getLong("fpsSamplingSeconds") else 300,
230
237
  debug = if (hasKey("debug")) getBoolean("debug") else false,
231
238
  proxyUrl = getString("proxyUrl"),
232
239
  beforeSendCallback = ::beforeSendCallback,
@@ -234,6 +241,25 @@ class CxSdkModule(reactContext: ReactApplicationContext) :
234
241
  )
235
242
  }
236
243
 
244
+ private fun ReadableMap.toMobileVitalsOptions(): Map<MobileVitalType, Boolean> {
245
+ val mapping = mapOf(
246
+ "cold" to MobileVitalType.ColdStartTime,
247
+ "warm" to MobileVitalType.WarmStartTime,
248
+ "cpu" to MobileVitalType.CpuUsage,
249
+ "memory" to MobileVitalType.MemoryUsage,
250
+ "slowFrozenFrames" to MobileVitalType.SlowFrozenFrames,
251
+ "rendering" to MobileVitalType.Fps
252
+ )
253
+
254
+ return buildMap {
255
+ for ((key, type) in mapping) {
256
+ if (hasKey(key) && !isNull(key)) {
257
+ put(type, getBoolean(key))
258
+ }
259
+ }
260
+ }
261
+ }
262
+
237
263
  private fun beforeSendCallback(data: List<Map<String, Any?>>) {
238
264
  val args = convertAnyListToWritableArray(data)
239
265
  if (!reactApplicationContext.hasActiveReactInstance()) return
@@ -20,5 +20,6 @@ interface ICxSdkModule {
20
20
  fun sendCxSpanData(results: ReadableArray)
21
21
  fun reportMobileVitalsMeasurement(type: String, value: Double, units: String)
22
22
  fun reportMobileVitalsMeasurementSet(type: String, metrics: ReadableArray)
23
+ fun isCoralogixGradlePluginApplied(promise: Promise)
23
24
  fun shutdown(promise: Promise)
24
25
  }
package/index.cjs.js CHANGED
@@ -219,7 +219,7 @@ function stopJsRefreshRateSampler() {
219
219
  appStateSub = null;
220
220
  }
221
221
 
222
- var version = "0.1.5";
222
+ var version = "0.1.7";
223
223
  var pkg = {
224
224
  version: version};
225
225
 
@@ -373,6 +373,34 @@ class CoralogixFetchInstrumentation extends instrumentationFetch.FetchInstrument
373
373
  }
374
374
  }
375
375
 
376
+ let lastRouteName;
377
+ function getLastNavigationRouteDetected() {
378
+ return lastRouteName;
379
+ }
380
+ function attachReactNavigationObserver(ref) {
381
+ const report = () => {
382
+ const route = ref.getCurrentRoute();
383
+ if (!route) return;
384
+ const name = route.name;
385
+ if (name !== lastRouteName) {
386
+ if (CoralogixRum.isInited) {
387
+ CoralogixRum.setViewContext({
388
+ view: name
389
+ });
390
+ }
391
+ lastRouteName = name;
392
+ }
393
+ };
394
+ const onReady = () => {
395
+ // Wait a tick to ensure the route is initialized
396
+ setTimeout(report, 0);
397
+ };
398
+ return {
399
+ onReady,
400
+ onStateChange: report
401
+ };
402
+ }
403
+
376
404
  let CoralogixDomain = /*#__PURE__*/function (CoralogixDomain) {
377
405
  CoralogixDomain["EU1"] = "EU1";
378
406
  CoralogixDomain["EU2"] = "EU2";
@@ -417,8 +445,19 @@ const CoralogixRum = {
417
445
  logger.debug('CoralogixRum: Session tracking is disabled');
418
446
  return;
419
447
  }
420
- registerCoralogixInstrumentations(resolvedOptions);
421
- await CxSdk.initialize(_extends({}, resolvedOptions, {
448
+ await registerCoralogixInstrumentations(resolvedOptions);
449
+ let finalOptions;
450
+ const lastNavRoute = getLastNavigationRouteDetected();
451
+ if (lastNavRoute) {
452
+ finalOptions = _extends({}, resolvedOptions, {
453
+ view_context: {
454
+ view: lastNavRoute
455
+ }
456
+ });
457
+ } else {
458
+ finalOptions = resolvedOptions;
459
+ }
460
+ await CxSdk.initialize(_extends({}, finalOptions, {
422
461
  frameworkVersion: pkg.version
423
462
  }));
424
463
  isInited = true;
@@ -544,11 +583,15 @@ const CoralogixRum = {
544
583
  }
545
584
  };
546
585
  function trackMobileVitals(options) {
547
- startJsRefreshRateSampler(_extends({}, options.jsRefreshRateSampleRate, {
548
- onSample: jsRefreshRate => {
549
- CxSdk.reportMobileVitalsMeasurement('js_refresh_rate', Math.round(jsRefreshRate), 'fps');
550
- }
551
- }));
586
+ var _options$mobileVitals;
587
+ const shouldEnableJsRefreshRateDetector = ((_options$mobileVitals = options.mobileVitals) == null ? void 0 : _options$mobileVitals.jsRefreshRate) !== false;
588
+ if (shouldEnableJsRefreshRateDetector) {
589
+ startJsRefreshRateSampler(_extends({}, options.jsRefreshRateSampleRate, {
590
+ onSample: jsRefreshRate => {
591
+ CxSdk.reportMobileVitalsMeasurement('js_refresh_rate', Math.round(jsRefreshRate), 'fps');
592
+ }
593
+ }));
594
+ }
552
595
 
553
596
  // startJSLoopDetector({
554
597
  // ...options.jsLoopDetection,
@@ -575,7 +618,7 @@ function cleanupResources() {
575
618
  stopJsRefreshRateSampler();
576
619
  // stopJSLoopDetector();
577
620
  }
578
- function registerCoralogixInstrumentations(options) {
621
+ async function registerCoralogixInstrumentations(options) {
579
622
  if (options.beforeSend) {
580
623
  beforeSendCallback = options.beforeSend;
581
624
  }
@@ -583,8 +626,13 @@ function registerCoralogixInstrumentations(options) {
583
626
  const instrumentations = [];
584
627
  const instrumentationsOptions = options.instrumentations;
585
628
 
586
- // disable network for ios, since swizzle will capture the fetch requests
587
- const shouldInterceptNetowrk = reactNative.Platform.OS === 'android' && (!instrumentationsOptions || instrumentationsOptions.network !== false);
629
+ // disable network for ios, since swizzle will capture the fetch requests, and for android if gradle plugin is applied
630
+ const isAndroid = reactNative.Platform.OS === 'android';
631
+ let pluginApplied = false;
632
+ if (isAndroid) {
633
+ pluginApplied = await CxSdk.isCoralogixGradlePluginApplied();
634
+ }
635
+ const shouldInterceptNetowrk = isAndroid && !pluginApplied && (!instrumentationsOptions || instrumentationsOptions.network !== false);
588
636
  const shouldInterceptErrors = !instrumentationsOptions || instrumentationsOptions.errors !== false;
589
637
  const shouldInterceptMobileVitals = !instrumentationsOptions || instrumentationsOptions.mobile_vitals !== false;
590
638
 
@@ -681,3 +729,4 @@ const subscription = eventEmitter.addListener('onBeforeSend', events => {
681
729
  exports.CoralogixDomain = CoralogixDomain;
682
730
  exports.CoralogixLogSeverity = CoralogixLogSeverity;
683
731
  exports.CoralogixRum = CoralogixRum;
732
+ exports.attachReactNavigationObserver = attachReactNavigationObserver;
package/index.esm.js CHANGED
@@ -217,7 +217,7 @@ function stopJsRefreshRateSampler() {
217
217
  appStateSub = null;
218
218
  }
219
219
 
220
- var version = "0.1.5";
220
+ var version = "0.1.7";
221
221
  var pkg = {
222
222
  version: version};
223
223
 
@@ -371,6 +371,34 @@ class CoralogixFetchInstrumentation extends FetchInstrumentation {
371
371
  }
372
372
  }
373
373
 
374
+ let lastRouteName;
375
+ function getLastNavigationRouteDetected() {
376
+ return lastRouteName;
377
+ }
378
+ function attachReactNavigationObserver(ref) {
379
+ const report = () => {
380
+ const route = ref.getCurrentRoute();
381
+ if (!route) return;
382
+ const name = route.name;
383
+ if (name !== lastRouteName) {
384
+ if (CoralogixRum.isInited) {
385
+ CoralogixRum.setViewContext({
386
+ view: name
387
+ });
388
+ }
389
+ lastRouteName = name;
390
+ }
391
+ };
392
+ const onReady = () => {
393
+ // Wait a tick to ensure the route is initialized
394
+ setTimeout(report, 0);
395
+ };
396
+ return {
397
+ onReady,
398
+ onStateChange: report
399
+ };
400
+ }
401
+
374
402
  let CoralogixDomain = /*#__PURE__*/function (CoralogixDomain) {
375
403
  CoralogixDomain["EU1"] = "EU1";
376
404
  CoralogixDomain["EU2"] = "EU2";
@@ -415,8 +443,19 @@ const CoralogixRum = {
415
443
  logger.debug('CoralogixRum: Session tracking is disabled');
416
444
  return;
417
445
  }
418
- registerCoralogixInstrumentations(resolvedOptions);
419
- await CxSdk.initialize(_extends({}, resolvedOptions, {
446
+ await registerCoralogixInstrumentations(resolvedOptions);
447
+ let finalOptions;
448
+ const lastNavRoute = getLastNavigationRouteDetected();
449
+ if (lastNavRoute) {
450
+ finalOptions = _extends({}, resolvedOptions, {
451
+ view_context: {
452
+ view: lastNavRoute
453
+ }
454
+ });
455
+ } else {
456
+ finalOptions = resolvedOptions;
457
+ }
458
+ await CxSdk.initialize(_extends({}, finalOptions, {
420
459
  frameworkVersion: pkg.version
421
460
  }));
422
461
  isInited = true;
@@ -542,11 +581,15 @@ const CoralogixRum = {
542
581
  }
543
582
  };
544
583
  function trackMobileVitals(options) {
545
- startJsRefreshRateSampler(_extends({}, options.jsRefreshRateSampleRate, {
546
- onSample: jsRefreshRate => {
547
- CxSdk.reportMobileVitalsMeasurement('js_refresh_rate', Math.round(jsRefreshRate), 'fps');
548
- }
549
- }));
584
+ var _options$mobileVitals;
585
+ const shouldEnableJsRefreshRateDetector = ((_options$mobileVitals = options.mobileVitals) == null ? void 0 : _options$mobileVitals.jsRefreshRate) !== false;
586
+ if (shouldEnableJsRefreshRateDetector) {
587
+ startJsRefreshRateSampler(_extends({}, options.jsRefreshRateSampleRate, {
588
+ onSample: jsRefreshRate => {
589
+ CxSdk.reportMobileVitalsMeasurement('js_refresh_rate', Math.round(jsRefreshRate), 'fps');
590
+ }
591
+ }));
592
+ }
550
593
 
551
594
  // startJSLoopDetector({
552
595
  // ...options.jsLoopDetection,
@@ -573,7 +616,7 @@ function cleanupResources() {
573
616
  stopJsRefreshRateSampler();
574
617
  // stopJSLoopDetector();
575
618
  }
576
- function registerCoralogixInstrumentations(options) {
619
+ async function registerCoralogixInstrumentations(options) {
577
620
  if (options.beforeSend) {
578
621
  beforeSendCallback = options.beforeSend;
579
622
  }
@@ -581,8 +624,13 @@ function registerCoralogixInstrumentations(options) {
581
624
  const instrumentations = [];
582
625
  const instrumentationsOptions = options.instrumentations;
583
626
 
584
- // disable network for ios, since swizzle will capture the fetch requests
585
- const shouldInterceptNetowrk = Platform.OS === 'android' && (!instrumentationsOptions || instrumentationsOptions.network !== false);
627
+ // disable network for ios, since swizzle will capture the fetch requests, and for android if gradle plugin is applied
628
+ const isAndroid = Platform.OS === 'android';
629
+ let pluginApplied = false;
630
+ if (isAndroid) {
631
+ pluginApplied = await CxSdk.isCoralogixGradlePluginApplied();
632
+ }
633
+ const shouldInterceptNetowrk = isAndroid && !pluginApplied && (!instrumentationsOptions || instrumentationsOptions.network !== false);
586
634
  const shouldInterceptErrors = !instrumentationsOptions || instrumentationsOptions.errors !== false;
587
635
  const shouldInterceptMobileVitals = !instrumentationsOptions || instrumentationsOptions.mobile_vitals !== false;
588
636
 
@@ -676,4 +724,4 @@ const subscription = eventEmitter.addListener('onBeforeSend', events => {
676
724
  }
677
725
  });
678
726
 
679
- export { CoralogixDomain, CoralogixLogSeverity, CoralogixRum };
727
+ export { CoralogixDomain, CoralogixLogSeverity, CoralogixRum, attachReactNavigationObserver };
package/ios/CxSdk.swift CHANGED
@@ -63,7 +63,7 @@ class CxSdk: RCTEventEmitter {
63
63
  @objc(getUserContext:withRejecter:)
64
64
  func getUserContext(resolve: @escaping RCTPromiseResolveBlock,
65
65
  reject: @escaping RCTPromiseRejectBlock) {
66
- let userContext = coralogixRum?.getUserContext()
66
+ let userContext = coralogixRum?.userContext
67
67
  resolve(userContext?.getDictionary())
68
68
  }
69
69
 
@@ -72,13 +72,13 @@ class CxSdk: RCTEventEmitter {
72
72
  resolve:RCTPromiseResolveBlock,
73
73
  reject:RCTPromiseRejectBlock) -> Void {
74
74
  let labels = labelsMap as? [String: String] ?? [String: String]()
75
- resolve(coralogixRum?.setLabels(labels: labels))
75
+ resolve(coralogixRum?.set(labels: labels))
76
76
  }
77
77
 
78
78
  @objc(getLabels:withRejecter:)
79
79
  func getLabels(resolve: @escaping RCTPromiseResolveBlock,
80
80
  reject: @escaping RCTPromiseRejectBlock) {
81
- if let labels = coralogixRum?.getLabels() {
81
+ if let labels = coralogixRum?.labels {
82
82
  resolve(labels) // Assuming labels is a Dictionary or Array
83
83
  } else {
84
84
  reject("GET_LABELS_ERROR", "Failed to retrieve labels", nil)
@@ -100,7 +100,7 @@ class CxSdk: RCTEventEmitter {
100
100
  @objc(isInited:withRejecter:)
101
101
  func isInited(resolve: @escaping RCTPromiseResolveBlock,
102
102
  reject: @escaping RCTPromiseRejectBlock) {
103
- if let isInit = coralogixRum?.isInitialized() {
103
+ if let isInit = coralogixRum?.isInitialized {
104
104
  resolve(isInit)
105
105
  } else {
106
106
  reject("IS_INITED", "Failed to retrieve isInited", nil)
@@ -149,7 +149,7 @@ class CxSdk: RCTEventEmitter {
149
149
  @objc(getSessionId:withRejecter:)
150
150
  func getSessionId(resolve: @escaping RCTPromiseResolveBlock,
151
151
  reject: @escaping RCTPromiseRejectBlock) -> Void {
152
- let sessionId = coralogixRum?.getSessionId()
152
+ let sessionId = coralogixRum?.getSessionId
153
153
  resolve(sessionId)
154
154
  }
155
155
 
@@ -199,7 +199,7 @@ class CxSdk: RCTEventEmitter {
199
199
  reject("Invalid sendBeforeSendData", "sendBeforeSendData is not a dictionary", nil)
200
200
  return
201
201
  }
202
- coralogixRum?.sendBeforeSendData(data: beforeSendResults)
202
+ coralogixRum?.sendBeforeSendData(beforeSendResults)
203
203
  resolve("sendBeforeSendData success")
204
204
  }
205
205
 
@@ -270,6 +270,14 @@ class CxSdk: RCTEventEmitter {
270
270
  }
271
271
  }
272
272
 
273
+ let mobileVitals = parameter["mobileVitals"] as? [String: Int] ?? [String: Int]()
274
+ var mobileVitalsDict: [CoralogixExporterOptions.MobileVitalsType: Bool] = [:]
275
+ for (key, value) in mobileVitals {
276
+ if let mobileVitalsKey = mobileVitalsType(from: key) {
277
+ mobileVitalsDict[mobileVitalsKey] = value == 0 ? false : true
278
+ }
279
+ }
280
+
273
281
  let userContext = parameter["user_context"] as? [String: Any]
274
282
  let userMetadata = userContext?["user_metadata"] as? [String: String] ?? [String: String]()
275
283
  let coralogixUser = UserContext(userId: userContext?["user_id"] as? String ?? "",
@@ -287,12 +295,12 @@ class CxSdk: RCTEventEmitter {
287
295
  ignoreUrls: ignoreUrls,
288
296
  ignoreErrors: ignoreError,
289
297
  labels: labels,
290
- sampleRate: 100,
291
- mobileVitalsFPSSamplingRate: parameter["fpsSamplingSeconds"] as? Int ?? 300,
298
+ fpsSampleRate: parameter["fpsSamplingSeconds"] as? TimeInterval ?? 300,
292
299
  instrumentations: instrumentationDict,
293
300
  collectIPData: parameter["collectIPData"] as? Bool ?? true,
294
301
  proxyUrl: parameter["proxyUrl"] as? String ?? nil,
295
302
  traceParentInHeader: parameter["traceParentInHeader"] as? [String: Any] ?? nil,
303
+ mobileVitals: mobileVitalsDict,
296
304
  debug: parameter["debug"] as? Bool ?? true)
297
305
 
298
306
  return options
@@ -326,6 +334,25 @@ class CxSdk: RCTEventEmitter {
326
334
  userMetadata: userMetadata)
327
335
  }
328
336
 
337
+ private func mobileVitalsType(from string: String) -> CoralogixExporterOptions.MobileVitalsType? {
338
+ switch string {
339
+ case "warm":
340
+ return .warmDetector
341
+ case "cold":
342
+ return .coldDetector
343
+ case "rendering":
344
+ return .renderingDetector
345
+ case "cpu":
346
+ return .cpuDetector
347
+ case "memory":
348
+ return .memoryDetector
349
+ case "slowFrozenFrames":
350
+ return .slowFrozenFramesDetector
351
+ default:
352
+ return nil
353
+ }
354
+ }
355
+
329
356
  private func instrumentationType(from string: String) -> CoralogixExporterOptions.InstrumentationType? {
330
357
  switch string {
331
358
  case "mobile_vitals":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coralogix/react-native-plugin",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Official Coralogix React Native plugin",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Coralogix",
@@ -25,8 +25,8 @@
25
25
  },
26
26
  "main": "./index.cjs.js",
27
27
  "dependencies": {
28
- "@opentelemetry/instrumentation-fetch": "0.203.0",
29
28
  "@opentelemetry/instrumentation": "0.48.0",
29
+ "@opentelemetry/instrumentation-fetch": "0.203.0",
30
30
  "@opentelemetry/sdk-trace-web": "1.30.1"
31
31
  },
32
32
  "module": "./index.esm.js",
package/src/index.d.ts CHANGED
@@ -8,3 +8,5 @@ export { type CoralogixBrowserSdkConfig, CoralogixLogSeverity, } from './model/T
8
8
  export { type CoralogixOtelWebOptionsInstrumentations } from './model/CoralogixOtelWebOptionsInstrumentations';
9
9
  export { type CustomMeasurement } from './model/CustomMeasurement';
10
10
  export { type NetworkRequestDetails } from './model/NetworkRequestDetails';
11
+ export { type CoralogixMobileVitals } from './model/CoralogixMobileVitals';
12
+ export { attachReactNavigationObserver } from './instrumentations/navigation/NavigationInstrumentation';
@@ -0,0 +1,8 @@
1
+ export declare function getLastNavigationRouteDetected(): string | undefined;
2
+ export type CurrentRouteProvider = {
3
+ getCurrentRoute: any;
4
+ };
5
+ export declare function attachReactNavigationObserver(ref: CurrentRouteProvider): {
6
+ onReady: () => void;
7
+ onStateChange: () => void;
8
+ };
@@ -0,0 +1,9 @@
1
+ export interface CoralogixMobileVitals {
2
+ warm?: boolean;
3
+ cold?: boolean;
4
+ cpu?: boolean;
5
+ memory?: boolean;
6
+ rendering?: boolean;
7
+ slowFrozenFrames?: boolean;
8
+ jsRefreshRate?: boolean;
9
+ }
@@ -3,6 +3,7 @@ import type { CoralogixOtelWebOptionsInstrumentations } from './CoralogixOtelWeb
3
3
  import { CoralogixDomain } from './CoralogixDomain';
4
4
  import { UserContextConfig } from './UserContextConfig';
5
5
  import { ViewContextConfig } from './ViewContextConfig';
6
+ import type { CoralogixMobileVitals } from './CoralogixMobileVitals.ts';
6
7
  export interface CxSpan {
7
8
  version_metadata: VersionMetaData;
8
9
  applicationName: string;
@@ -200,6 +201,7 @@ export interface CoralogixBrowserSdkConfig {
200
201
  /** Interval between FPS measurements in milliseconds (default: 300000 = 5 minutes) */
201
202
  sampleIntervalMs?: number;
202
203
  };
204
+ mobileVitals?: CoralogixMobileVitals;
203
205
  }
204
206
  export type HybridMetric = {
205
207
  name: string;