@coralogix/react-native-plugin 0.3.3 → 0.5.0

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/index.cjs.js CHANGED
@@ -27,6 +27,20 @@ let CoralogixLogSeverity = /*#__PURE__*/function (CoralogixLogSeverity) {
27
27
  return CoralogixLogSeverity;
28
28
  }({});
29
29
 
30
+ /**
31
+ * Instrumentation names that can be excluded from a custom tracer's span context.
32
+ * Pass one or more values to `getCustomTracer()` to prevent those event types from
33
+ * being linked to spans created by that tracer.
34
+ */
35
+
36
+ /**
37
+ * Event categories that can opt out of session sampling. When the session is
38
+ * sampled out, events whose category is listed in `excludeFromSampling` are still
39
+ * emitted; everything else is dropped. Mirrors the iOS/Android native enums.
40
+ */
41
+
42
+ /** OTLP JSON-format trace data delivered to the `tracesExporter` callback. */
43
+
30
44
  const ERROR_INSTRUMENTATION_NAME = 'errors';
31
45
  const ERROR_INSTRUMENTATION_VERSION = '1';
32
46
 
@@ -523,7 +537,7 @@ function stopJsRefreshRateSampler() {
523
537
  appStateSub = null;
524
538
  }
525
539
 
526
- var version = "0.3.3";
540
+ var version = "0.5.0";
527
541
  var pkg = {
528
542
  version: version};
529
543
 
@@ -561,6 +575,128 @@ class Logger {
561
575
  }
562
576
  const logger = new Logger();
563
577
 
578
+ let activeGlobalSpanId = null;
579
+ const spanTraceIds = new Map();
580
+ let ignoredInstruments = new Set();
581
+ const CustomSpanRegistry = {
582
+ getActive: () => activeGlobalSpanId,
583
+ setActive: id => {
584
+ activeGlobalSpanId = id;
585
+ },
586
+ clearActive: () => {
587
+ activeGlobalSpanId = null;
588
+ },
589
+ registerSpan: (spanId, traceId) => {
590
+ spanTraceIds.set(spanId, traceId);
591
+ },
592
+ unregisterSpan: spanId => {
593
+ spanTraceIds.delete(spanId);
594
+ },
595
+ getTraceId: spanId => spanTraceIds.get(spanId),
596
+ setIgnoredInstruments: set => {
597
+ ignoredInstruments = set;
598
+ },
599
+ getIgnoredInstruments: () => ignoredInstruments,
600
+ clear: () => {
601
+ activeGlobalSpanId = null;
602
+ spanTraceIds.clear();
603
+ ignoredInstruments.clear();
604
+ }
605
+ };
606
+
607
+ /** A child span nested under a {@link CoralogixGlobalSpan}. */
608
+ class CoralogixCustomSpan {
609
+ constructor(spanId, traceId, bridge) {
610
+ this.spanId = void 0;
611
+ this.traceId = void 0;
612
+ this.bridge = void 0;
613
+ this.spanId = spanId;
614
+ this.traceId = traceId;
615
+ this.bridge = bridge;
616
+ }
617
+ async endSpan() {
618
+ CustomSpanRegistry.unregisterSpan(this.spanId);
619
+ await this.bridge.endSpan(this.spanId);
620
+ }
621
+ }
622
+
623
+ /** A root-level custom span. All child spans and `withContext` network calls share its traceId. */
624
+ class CoralogixGlobalSpan {
625
+ constructor(spanId, traceId, bridge) {
626
+ this.spanId = void 0;
627
+ this.traceId = void 0;
628
+ this.bridge = void 0;
629
+ this.spanId = spanId;
630
+ this.traceId = traceId;
631
+ this.bridge = bridge;
632
+ }
633
+
634
+ /** Creates a child span nested under this global span. */
635
+ async startCustomSpan(name, labels) {
636
+ const raw = await this.bridge.startCustomSpan(this.spanId, name, labels != null ? labels : null);
637
+ if (!raw) return null;
638
+ CustomSpanRegistry.registerSpan(raw.spanId, raw.traceId);
639
+ return new CoralogixCustomSpan(raw.spanId, raw.traceId, this.bridge);
640
+ }
641
+
642
+ /**
643
+ * Runs fn() with this span set as the active global span for the duration of
644
+ * the returned promise. The active span ID remains set throughout the full
645
+ * async chain — including code after intermediate awaits — because we await
646
+ * fn() before clearing. Only detached callbacks (e.g. setTimeout) that fire
647
+ * after withContext resolves won't be linked.
648
+ */
649
+ async withContext(fn) {
650
+ const prev = CustomSpanRegistry.getActive();
651
+ CustomSpanRegistry.setActive(this.spanId);
652
+ try {
653
+ return await fn();
654
+ } finally {
655
+ if (prev !== null) {
656
+ CustomSpanRegistry.setActive(prev);
657
+ } else {
658
+ CustomSpanRegistry.clearActive();
659
+ }
660
+ }
661
+ }
662
+ async endSpan() {
663
+ CustomSpanRegistry.unregisterSpan(this.spanId);
664
+ if (CustomSpanRegistry.getActive() === this.spanId) {
665
+ CustomSpanRegistry.clearActive();
666
+ }
667
+ await this.bridge.endSpan(this.spanId);
668
+ }
669
+ }
670
+
671
+ /**
672
+ * Entry point for manual RUM tracing. Obtain an instance via `CoralogixRum.getCustomTracer()`.
673
+ * The `ignoredInstruments` list controls which auto-instrumented events are NOT linked to spans
674
+ * created by this tracer (e.g. passing `['networkRequests']` keeps network spans independent).
675
+ */
676
+ class CoralogixCustomTracer {
677
+ constructor(ignoredInstruments, bridge) {
678
+ this.ignoredInstruments = void 0;
679
+ this.bridge = void 0;
680
+ this.ignoredInstruments = ignoredInstruments;
681
+ this.bridge = bridge;
682
+ }
683
+
684
+ /**
685
+ * Starts a new global (root) span. Returns `null` if a global span is already active —
686
+ * only one global span may exist at a time across the entire app.
687
+ */
688
+ async startGlobalSpan(name, labels) {
689
+ const raw = await this.bridge.startGlobalSpan(name, labels != null ? labels : null, this.ignoredInstruments);
690
+ if (!raw) {
691
+ logger.debug('CoralogixCustomTracer: startGlobalSpan returned null — check that the SDK is initialized, traceParentInHeader is enabled, and no other global span is already active');
692
+ return null;
693
+ }
694
+ CustomSpanRegistry.registerSpan(raw.spanId, raw.traceId);
695
+ CustomSpanRegistry.setIgnoredInstruments(new Set(this.ignoredInstruments));
696
+ return new CoralogixGlobalSpan(raw.spanId, raw.traceId, this.bridge);
697
+ }
698
+ }
699
+
564
700
  const CORALOGIX_LOGS_URL_SUFFIX = '/browser/v1beta/logs';
565
701
  const CORALOGIX_RECORDING_URL_SUFFIX = '/sessionrecording';
566
702
  const OPTIONS_DEFAULTS = {
@@ -838,6 +974,7 @@ let CoralogixDomain = /*#__PURE__*/function (CoralogixDomain) {
838
974
  CoralogixDomain["AP1"] = "AP1";
839
975
  CoralogixDomain["AP2"] = "AP2";
840
976
  CoralogixDomain["AP3"] = "AP3";
977
+ CoralogixDomain["US3"] = "US3";
841
978
  CoralogixDomain["STAGING"] = "staging";
842
979
  return CoralogixDomain;
843
980
  }({});
@@ -847,6 +984,7 @@ const LINKING_ERROR = `The package 'cx-plugin' doesn't seem to be linked. Make s
847
984
  default: ''
848
985
  }) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n';
849
986
  let beforeSendCallback;
987
+ let tracesExporterSubscription;
850
988
  let _deregisterInstrumentations;
851
989
  const CxSdk = reactNative.NativeModules.CxSdk ? reactNative.NativeModules.CxSdk : createErrorProxy(LINKING_ERROR);
852
990
  function createErrorProxy(errorMessage) {
@@ -863,14 +1001,15 @@ const CoralogixRum = {
863
1001
  return isInited;
864
1002
  },
865
1003
  init: async function (options) {
866
- var _resolvedOptions$debu;
1004
+ var _resolvedOptions$debu, _resolvedOptions$excl, _resolvedOptions$excl2;
867
1005
  if (isInited) {
868
1006
  console.warn('[Coralogix React Native SDK] - already initialized');
869
1007
  return;
870
1008
  }
871
1009
  const resolvedOptions = resolveCoralogixOtelWebConfig(options);
872
1010
  logger.shouldLog = (_resolvedOptions$debu = resolvedOptions.debug) != null ? _resolvedOptions$debu : false;
873
- if (!isSamplingOn(resolvedOptions.sessionSampleRate)) {
1011
+ const hasExcludeOverrides = ((_resolvedOptions$excl = (_resolvedOptions$excl2 = resolvedOptions.excludeFromSampling) == null ? void 0 : _resolvedOptions$excl2.length) != null ? _resolvedOptions$excl : 0) > 0;
1012
+ if (!isSamplingOn(resolvedOptions.sessionSampleRate) && !hasExcludeOverrides) {
874
1013
  logger.debug('CoralogixRum: Session tracking is disabled');
875
1014
  return;
876
1015
  }
@@ -886,10 +1025,28 @@ const CoralogixRum = {
886
1025
  } else {
887
1026
  finalOptions = resolvedOptions;
888
1027
  }
1028
+ if (finalOptions.tracesExporter) {
1029
+ const callback = finalOptions.tracesExporter;
1030
+ tracesExporterSubscription = eventEmitter.addListener('onTracesExport', jsonString => {
1031
+ let data;
1032
+ try {
1033
+ data = JSON.parse(jsonString);
1034
+ } catch (e) {
1035
+ logger.warn('Error parsing onTracesExport payload:', e);
1036
+ return;
1037
+ }
1038
+ try {
1039
+ callback(data);
1040
+ } catch (e) {
1041
+ logger.warn('tracesExporter callback threw:', e);
1042
+ }
1043
+ });
1044
+ }
889
1045
  await CxSdk.initialize(_extends({}, finalOptions, {
890
1046
  frameworkVersion: pkg.version,
891
1047
  networkExtraConfig: finalOptions.networkExtraConfig ? serializeNetworkCaptureRules(finalOptions.networkExtraConfig) : undefined,
892
- hasBeforeSend: !!finalOptions.beforeSend
1048
+ hasBeforeSend: !!finalOptions.beforeSend,
1049
+ hasTracesExporter: !!finalOptions.tracesExporter
893
1050
  }));
894
1051
  isInited = true;
895
1052
  },
@@ -901,6 +1058,10 @@ const CoralogixRum = {
901
1058
  if (subscription) {
902
1059
  subscription.remove();
903
1060
  }
1061
+ if (tracesExporterSubscription) {
1062
+ tracesExporterSubscription.remove();
1063
+ tracesExporterSubscription = undefined;
1064
+ }
904
1065
  isInited = false;
905
1066
  _deregisterInstrumentations == null || _deregisterInstrumentations();
906
1067
  _deregisterInstrumentations = undefined;
@@ -992,6 +1153,19 @@ const CoralogixRum = {
992
1153
  reportNetworkRequest: details => {
993
1154
  CxSdk.reportNetworkRequest(details);
994
1155
  },
1156
+ /**
1157
+ * Returns a tracer for creating manual custom spans.
1158
+ * Pass `ignoredInstruments` to prevent specific auto-instrumented event types from being
1159
+ * linked to spans created by this tracer.
1160
+ */
1161
+ getCustomTracer(ignoredInstruments = []) {
1162
+ const bridge = {
1163
+ startGlobalSpan: (name, labels, instruments) => CxSdk.startGlobalSpan(name, labels, instruments),
1164
+ startCustomSpan: (parentSpanId, name, labels) => CxSdk.startCustomSpan(parentSpanId, name, labels),
1165
+ endSpan: spanId => CxSdk.endSpan(spanId)
1166
+ };
1167
+ return new CoralogixCustomTracer(ignoredInstruments, bridge);
1168
+ },
995
1169
  sendCustomMeasurement: measurement => {
996
1170
  if (!isInited) {
997
1171
  logger.debug('CoralogixRum must be initiated before sending custom measurements');
@@ -999,6 +1173,20 @@ const CoralogixRum = {
999
1173
  }
1000
1174
  CxSdk.sendCustomMeasurement(measurement);
1001
1175
  },
1176
+ startTimeMeasure: (name, labels) => {
1177
+ if (!isInited) {
1178
+ logger.debug('CoralogixRum must be initiated before startTimeMeasure');
1179
+ return;
1180
+ }
1181
+ CxSdk.startTimeMeasure(name, labels != null ? labels : {});
1182
+ },
1183
+ endTimeMeasure: name => {
1184
+ if (!isInited) {
1185
+ logger.debug('CoralogixRum must be initiated before endTimeMeasure');
1186
+ return;
1187
+ }
1188
+ CxSdk.endTimeMeasure(name);
1189
+ },
1002
1190
  reportError: (error, isCrash) => {
1003
1191
  if (!isInited) {
1004
1192
  logger.debug('CoralogixRum must be initiated before error reporting');
@@ -1221,7 +1409,10 @@ const subscription = eventEmitter.addListener('onBeforeSend', events => {
1221
1409
  }
1222
1410
  });
1223
1411
 
1412
+ exports.CoralogixCustomSpan = CoralogixCustomSpan;
1413
+ exports.CoralogixCustomTracer = CoralogixCustomTracer;
1224
1414
  exports.CoralogixDomain = CoralogixDomain;
1415
+ exports.CoralogixGlobalSpan = CoralogixGlobalSpan;
1225
1416
  exports.CoralogixLogSeverity = CoralogixLogSeverity;
1226
1417
  exports.CoralogixRum = CoralogixRum;
1227
1418
  exports.CxSdk = CxSdk;
package/index.esm.js CHANGED
@@ -25,6 +25,20 @@ let CoralogixLogSeverity = /*#__PURE__*/function (CoralogixLogSeverity) {
25
25
  return CoralogixLogSeverity;
26
26
  }({});
27
27
 
28
+ /**
29
+ * Instrumentation names that can be excluded from a custom tracer's span context.
30
+ * Pass one or more values to `getCustomTracer()` to prevent those event types from
31
+ * being linked to spans created by that tracer.
32
+ */
33
+
34
+ /**
35
+ * Event categories that can opt out of session sampling. When the session is
36
+ * sampled out, events whose category is listed in `excludeFromSampling` are still
37
+ * emitted; everything else is dropped. Mirrors the iOS/Android native enums.
38
+ */
39
+
40
+ /** OTLP JSON-format trace data delivered to the `tracesExporter` callback. */
41
+
28
42
  const ERROR_INSTRUMENTATION_NAME = 'errors';
29
43
  const ERROR_INSTRUMENTATION_VERSION = '1';
30
44
 
@@ -521,7 +535,7 @@ function stopJsRefreshRateSampler() {
521
535
  appStateSub = null;
522
536
  }
523
537
 
524
- var version = "0.3.3";
538
+ var version = "0.5.0";
525
539
  var pkg = {
526
540
  version: version};
527
541
 
@@ -559,6 +573,128 @@ class Logger {
559
573
  }
560
574
  const logger = new Logger();
561
575
 
576
+ let activeGlobalSpanId = null;
577
+ const spanTraceIds = new Map();
578
+ let ignoredInstruments = new Set();
579
+ const CustomSpanRegistry = {
580
+ getActive: () => activeGlobalSpanId,
581
+ setActive: id => {
582
+ activeGlobalSpanId = id;
583
+ },
584
+ clearActive: () => {
585
+ activeGlobalSpanId = null;
586
+ },
587
+ registerSpan: (spanId, traceId) => {
588
+ spanTraceIds.set(spanId, traceId);
589
+ },
590
+ unregisterSpan: spanId => {
591
+ spanTraceIds.delete(spanId);
592
+ },
593
+ getTraceId: spanId => spanTraceIds.get(spanId),
594
+ setIgnoredInstruments: set => {
595
+ ignoredInstruments = set;
596
+ },
597
+ getIgnoredInstruments: () => ignoredInstruments,
598
+ clear: () => {
599
+ activeGlobalSpanId = null;
600
+ spanTraceIds.clear();
601
+ ignoredInstruments.clear();
602
+ }
603
+ };
604
+
605
+ /** A child span nested under a {@link CoralogixGlobalSpan}. */
606
+ class CoralogixCustomSpan {
607
+ constructor(spanId, traceId, bridge) {
608
+ this.spanId = void 0;
609
+ this.traceId = void 0;
610
+ this.bridge = void 0;
611
+ this.spanId = spanId;
612
+ this.traceId = traceId;
613
+ this.bridge = bridge;
614
+ }
615
+ async endSpan() {
616
+ CustomSpanRegistry.unregisterSpan(this.spanId);
617
+ await this.bridge.endSpan(this.spanId);
618
+ }
619
+ }
620
+
621
+ /** A root-level custom span. All child spans and `withContext` network calls share its traceId. */
622
+ class CoralogixGlobalSpan {
623
+ constructor(spanId, traceId, bridge) {
624
+ this.spanId = void 0;
625
+ this.traceId = void 0;
626
+ this.bridge = void 0;
627
+ this.spanId = spanId;
628
+ this.traceId = traceId;
629
+ this.bridge = bridge;
630
+ }
631
+
632
+ /** Creates a child span nested under this global span. */
633
+ async startCustomSpan(name, labels) {
634
+ const raw = await this.bridge.startCustomSpan(this.spanId, name, labels != null ? labels : null);
635
+ if (!raw) return null;
636
+ CustomSpanRegistry.registerSpan(raw.spanId, raw.traceId);
637
+ return new CoralogixCustomSpan(raw.spanId, raw.traceId, this.bridge);
638
+ }
639
+
640
+ /**
641
+ * Runs fn() with this span set as the active global span for the duration of
642
+ * the returned promise. The active span ID remains set throughout the full
643
+ * async chain — including code after intermediate awaits — because we await
644
+ * fn() before clearing. Only detached callbacks (e.g. setTimeout) that fire
645
+ * after withContext resolves won't be linked.
646
+ */
647
+ async withContext(fn) {
648
+ const prev = CustomSpanRegistry.getActive();
649
+ CustomSpanRegistry.setActive(this.spanId);
650
+ try {
651
+ return await fn();
652
+ } finally {
653
+ if (prev !== null) {
654
+ CustomSpanRegistry.setActive(prev);
655
+ } else {
656
+ CustomSpanRegistry.clearActive();
657
+ }
658
+ }
659
+ }
660
+ async endSpan() {
661
+ CustomSpanRegistry.unregisterSpan(this.spanId);
662
+ if (CustomSpanRegistry.getActive() === this.spanId) {
663
+ CustomSpanRegistry.clearActive();
664
+ }
665
+ await this.bridge.endSpan(this.spanId);
666
+ }
667
+ }
668
+
669
+ /**
670
+ * Entry point for manual RUM tracing. Obtain an instance via `CoralogixRum.getCustomTracer()`.
671
+ * The `ignoredInstruments` list controls which auto-instrumented events are NOT linked to spans
672
+ * created by this tracer (e.g. passing `['networkRequests']` keeps network spans independent).
673
+ */
674
+ class CoralogixCustomTracer {
675
+ constructor(ignoredInstruments, bridge) {
676
+ this.ignoredInstruments = void 0;
677
+ this.bridge = void 0;
678
+ this.ignoredInstruments = ignoredInstruments;
679
+ this.bridge = bridge;
680
+ }
681
+
682
+ /**
683
+ * Starts a new global (root) span. Returns `null` if a global span is already active —
684
+ * only one global span may exist at a time across the entire app.
685
+ */
686
+ async startGlobalSpan(name, labels) {
687
+ const raw = await this.bridge.startGlobalSpan(name, labels != null ? labels : null, this.ignoredInstruments);
688
+ if (!raw) {
689
+ logger.debug('CoralogixCustomTracer: startGlobalSpan returned null — check that the SDK is initialized, traceParentInHeader is enabled, and no other global span is already active');
690
+ return null;
691
+ }
692
+ CustomSpanRegistry.registerSpan(raw.spanId, raw.traceId);
693
+ CustomSpanRegistry.setIgnoredInstruments(new Set(this.ignoredInstruments));
694
+ return new CoralogixGlobalSpan(raw.spanId, raw.traceId, this.bridge);
695
+ }
696
+ }
697
+
562
698
  const CORALOGIX_LOGS_URL_SUFFIX = '/browser/v1beta/logs';
563
699
  const CORALOGIX_RECORDING_URL_SUFFIX = '/sessionrecording';
564
700
  const OPTIONS_DEFAULTS = {
@@ -836,6 +972,7 @@ let CoralogixDomain = /*#__PURE__*/function (CoralogixDomain) {
836
972
  CoralogixDomain["AP1"] = "AP1";
837
973
  CoralogixDomain["AP2"] = "AP2";
838
974
  CoralogixDomain["AP3"] = "AP3";
975
+ CoralogixDomain["US3"] = "US3";
839
976
  CoralogixDomain["STAGING"] = "staging";
840
977
  return CoralogixDomain;
841
978
  }({});
@@ -845,6 +982,7 @@ const LINKING_ERROR = `The package 'cx-plugin' doesn't seem to be linked. Make s
845
982
  default: ''
846
983
  }) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n';
847
984
  let beforeSendCallback;
985
+ let tracesExporterSubscription;
848
986
  let _deregisterInstrumentations;
849
987
  const CxSdk = NativeModules.CxSdk ? NativeModules.CxSdk : createErrorProxy(LINKING_ERROR);
850
988
  function createErrorProxy(errorMessage) {
@@ -861,14 +999,15 @@ const CoralogixRum = {
861
999
  return isInited;
862
1000
  },
863
1001
  init: async function (options) {
864
- var _resolvedOptions$debu;
1002
+ var _resolvedOptions$debu, _resolvedOptions$excl, _resolvedOptions$excl2;
865
1003
  if (isInited) {
866
1004
  console.warn('[Coralogix React Native SDK] - already initialized');
867
1005
  return;
868
1006
  }
869
1007
  const resolvedOptions = resolveCoralogixOtelWebConfig(options);
870
1008
  logger.shouldLog = (_resolvedOptions$debu = resolvedOptions.debug) != null ? _resolvedOptions$debu : false;
871
- if (!isSamplingOn(resolvedOptions.sessionSampleRate)) {
1009
+ const hasExcludeOverrides = ((_resolvedOptions$excl = (_resolvedOptions$excl2 = resolvedOptions.excludeFromSampling) == null ? void 0 : _resolvedOptions$excl2.length) != null ? _resolvedOptions$excl : 0) > 0;
1010
+ if (!isSamplingOn(resolvedOptions.sessionSampleRate) && !hasExcludeOverrides) {
872
1011
  logger.debug('CoralogixRum: Session tracking is disabled');
873
1012
  return;
874
1013
  }
@@ -884,10 +1023,28 @@ const CoralogixRum = {
884
1023
  } else {
885
1024
  finalOptions = resolvedOptions;
886
1025
  }
1026
+ if (finalOptions.tracesExporter) {
1027
+ const callback = finalOptions.tracesExporter;
1028
+ tracesExporterSubscription = eventEmitter.addListener('onTracesExport', jsonString => {
1029
+ let data;
1030
+ try {
1031
+ data = JSON.parse(jsonString);
1032
+ } catch (e) {
1033
+ logger.warn('Error parsing onTracesExport payload:', e);
1034
+ return;
1035
+ }
1036
+ try {
1037
+ callback(data);
1038
+ } catch (e) {
1039
+ logger.warn('tracesExporter callback threw:', e);
1040
+ }
1041
+ });
1042
+ }
887
1043
  await CxSdk.initialize(_extends({}, finalOptions, {
888
1044
  frameworkVersion: pkg.version,
889
1045
  networkExtraConfig: finalOptions.networkExtraConfig ? serializeNetworkCaptureRules(finalOptions.networkExtraConfig) : undefined,
890
- hasBeforeSend: !!finalOptions.beforeSend
1046
+ hasBeforeSend: !!finalOptions.beforeSend,
1047
+ hasTracesExporter: !!finalOptions.tracesExporter
891
1048
  }));
892
1049
  isInited = true;
893
1050
  },
@@ -899,6 +1056,10 @@ const CoralogixRum = {
899
1056
  if (subscription) {
900
1057
  subscription.remove();
901
1058
  }
1059
+ if (tracesExporterSubscription) {
1060
+ tracesExporterSubscription.remove();
1061
+ tracesExporterSubscription = undefined;
1062
+ }
902
1063
  isInited = false;
903
1064
  _deregisterInstrumentations == null || _deregisterInstrumentations();
904
1065
  _deregisterInstrumentations = undefined;
@@ -990,6 +1151,19 @@ const CoralogixRum = {
990
1151
  reportNetworkRequest: details => {
991
1152
  CxSdk.reportNetworkRequest(details);
992
1153
  },
1154
+ /**
1155
+ * Returns a tracer for creating manual custom spans.
1156
+ * Pass `ignoredInstruments` to prevent specific auto-instrumented event types from being
1157
+ * linked to spans created by this tracer.
1158
+ */
1159
+ getCustomTracer(ignoredInstruments = []) {
1160
+ const bridge = {
1161
+ startGlobalSpan: (name, labels, instruments) => CxSdk.startGlobalSpan(name, labels, instruments),
1162
+ startCustomSpan: (parentSpanId, name, labels) => CxSdk.startCustomSpan(parentSpanId, name, labels),
1163
+ endSpan: spanId => CxSdk.endSpan(spanId)
1164
+ };
1165
+ return new CoralogixCustomTracer(ignoredInstruments, bridge);
1166
+ },
993
1167
  sendCustomMeasurement: measurement => {
994
1168
  if (!isInited) {
995
1169
  logger.debug('CoralogixRum must be initiated before sending custom measurements');
@@ -997,6 +1171,20 @@ const CoralogixRum = {
997
1171
  }
998
1172
  CxSdk.sendCustomMeasurement(measurement);
999
1173
  },
1174
+ startTimeMeasure: (name, labels) => {
1175
+ if (!isInited) {
1176
+ logger.debug('CoralogixRum must be initiated before startTimeMeasure');
1177
+ return;
1178
+ }
1179
+ CxSdk.startTimeMeasure(name, labels != null ? labels : {});
1180
+ },
1181
+ endTimeMeasure: name => {
1182
+ if (!isInited) {
1183
+ logger.debug('CoralogixRum must be initiated before endTimeMeasure');
1184
+ return;
1185
+ }
1186
+ CxSdk.endTimeMeasure(name);
1187
+ },
1000
1188
  reportError: (error, isCrash) => {
1001
1189
  if (!isInited) {
1002
1190
  logger.debug('CoralogixRum must be initiated before error reporting');
@@ -1219,4 +1407,4 @@ const subscription = eventEmitter.addListener('onBeforeSend', events => {
1219
1407
  }
1220
1408
  });
1221
1409
 
1222
- export { CoralogixDomain, CoralogixLogSeverity, CoralogixRum, CxSdk, SessionReplay, attachReactNavigationObserver, parseErrorStack };
1410
+ export { CoralogixCustomSpan, CoralogixCustomTracer, CoralogixDomain, CoralogixGlobalSpan, CoralogixLogSeverity, CoralogixRum, CxSdk, SessionReplay, attachReactNavigationObserver, parseErrorStack };
package/ios/CxSdk.mm CHANGED
@@ -80,6 +80,11 @@ RCT_EXTERN_METHOD(sendCustomMeasurement:(NSDictionary *)measurement
80
80
  withResolver:(RCTPromiseResolveBlock)resolve
81
81
  withRejecter:(RCTPromiseRejectBlock)reject)
82
82
 
83
+ RCT_EXTERN_METHOD(startTimeMeasure:(NSString *)name
84
+ labels:(NSDictionary *)labels)
85
+
86
+ RCT_EXTERN_METHOD(endTimeMeasure:(NSString *)name)
87
+
83
88
  RCT_EXTERN_METHOD(initializeSessionReplay:(NSDictionary *)options
84
89
  withResolver:(RCTPromiseResolveBlock)resolve
85
90
  withRejecter:(RCTPromiseRejectBlock)reject)
@@ -106,6 +111,22 @@ RCT_EXTERN_METHOD(maskViewByTag:(nonnull NSNumber *)viewTag
106
111
  withResolver:(RCTPromiseResolveBlock)resolve
107
112
  withRejecter:(RCTPromiseRejectBlock)reject)
108
113
 
114
+ RCT_EXTERN_METHOD(startGlobalSpan:(NSString *)name
115
+ labels:(NSDictionary *)labels
116
+ ignoredInstruments:(NSArray *)ignoredInstruments
117
+ withResolver:(RCTPromiseResolveBlock)resolve
118
+ withRejecter:(RCTPromiseRejectBlock)reject)
119
+
120
+ RCT_EXTERN_METHOD(startCustomSpan:(NSString *)parentSpanId
121
+ name:(NSString *)name
122
+ labels:(NSDictionary *)labels
123
+ withResolver:(RCTPromiseResolveBlock)resolve
124
+ withRejecter:(RCTPromiseRejectBlock)reject)
125
+
126
+ RCT_EXTERN_METHOD(endSpan:(NSString *)spanId
127
+ withResolver:(RCTPromiseResolveBlock)resolve
128
+ withRejecter:(RCTPromiseRejectBlock)reject)
129
+
109
130
  + (BOOL)requiresMainQueueSetup
110
131
  {
111
132
  return NO;