@dreamhorizonorg/pulse-react-native 0.0.1 → 0.0.2

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 (135) hide show
  1. package/PulseReactNativeOtel.podspec +1 -1
  2. package/README.md +34 -879
  3. package/android/build.gradle +10 -15
  4. package/android/proguard-rules.pro +3 -99
  5. package/android/src/main/java/com/pulsereactnativeotel/Pulse.kt +87 -0
  6. package/android/src/main/java/com/pulsereactnativeotel/PulseOtelConstants.kt +1 -1
  7. package/android/src/main/java/com/pulsereactnativeotel/PulseReactNativeOtelLogger.kt +3 -1
  8. package/android/src/main/java/com/pulsereactnativeotel/PulseReactNativeOtelModule.kt +53 -3
  9. package/android/src/main/java/com/pulsereactnativeotel/PulseReactNativeOtelPackage.kt +1 -1
  10. package/android/src/main/java/com/pulsereactnativeotel/PulseReactNativeOtelTracer.kt +24 -8
  11. package/android/src/main/java/com/pulsereactnativeotel/ReactNativeScreenAttributesLogRecordProcessor.kt +21 -0
  12. package/android/src/main/java/com/pulsereactnativeotel/ReactNativeScreenAttributesSpanProcessor.kt +30 -0
  13. package/android/src/main/java/com/pulsereactnativeotel/ReactNativeScreenNameTracker.kt +17 -0
  14. package/app.plugin.js +1 -0
  15. package/ios/PulseReactNativeOtel.mm +7 -1
  16. package/lib/module/NativePulseReactNativeOtel.js.map +1 -1
  17. package/lib/module/config.js +29 -9
  18. package/lib/module/config.js.map +1 -1
  19. package/lib/module/errorBoundary.js.map +1 -1
  20. package/lib/module/events.js +6 -0
  21. package/lib/module/events.js.map +1 -1
  22. package/lib/module/index.js +4 -2
  23. package/lib/module/index.js.map +1 -1
  24. package/lib/module/navigation/index.js +172 -0
  25. package/lib/module/navigation/index.js.map +1 -0
  26. package/lib/module/navigation/navigation.interface.js +2 -0
  27. package/lib/module/navigation/navigation.interface.js.map +1 -0
  28. package/lib/module/navigation/screen-interactive.js +101 -0
  29. package/lib/module/navigation/screen-interactive.js.map +1 -0
  30. package/lib/module/navigation/screen-load.js +68 -0
  31. package/lib/module/navigation/screen-load.js.map +1 -0
  32. package/lib/module/navigation/screen-session.js +60 -0
  33. package/lib/module/navigation/screen-session.js.map +1 -0
  34. package/lib/module/navigation/useNavigationTracking.js +33 -0
  35. package/lib/module/navigation/useNavigationTracking.js.map +1 -0
  36. package/lib/module/navigation/utils.js +17 -0
  37. package/lib/module/navigation/utils.js.map +1 -0
  38. package/lib/module/network-interceptor/graphql-helper.js +92 -0
  39. package/lib/module/network-interceptor/graphql-helper.js.map +1 -0
  40. package/lib/module/network-interceptor/request-tracker-xhr.js +2 -1
  41. package/lib/module/network-interceptor/request-tracker-xhr.js.map +1 -1
  42. package/lib/module/network-interceptor/span-helpers.js +24 -16
  43. package/lib/module/network-interceptor/span-helpers.js.map +1 -1
  44. package/lib/module/network-interceptor/url-helper.js +58 -2
  45. package/lib/module/network-interceptor/url-helper.js.map +1 -1
  46. package/lib/module/pulse.constants.js +42 -0
  47. package/lib/module/pulse.constants.js.map +1 -0
  48. package/lib/module/trace.js +17 -2
  49. package/lib/module/trace.js.map +1 -1
  50. package/lib/typescript/plugin/src/index.d.ts +5 -0
  51. package/lib/typescript/plugin/src/index.d.ts.map +1 -0
  52. package/lib/typescript/plugin/src/types.d.ts +27 -0
  53. package/lib/typescript/plugin/src/types.d.ts.map +1 -0
  54. package/lib/typescript/plugin/src/utils.d.ts +10 -0
  55. package/lib/typescript/plugin/src/utils.d.ts.map +1 -0
  56. package/lib/typescript/plugin/src/withAndroidPulse.d.ts +4 -0
  57. package/lib/typescript/plugin/src/withAndroidPulse.d.ts.map +1 -0
  58. package/lib/typescript/src/NativePulseReactNativeOtel.d.ts +8 -2
  59. package/lib/typescript/src/NativePulseReactNativeOtel.d.ts.map +1 -1
  60. package/lib/typescript/src/config.d.ts +8 -2
  61. package/lib/typescript/src/config.d.ts.map +1 -1
  62. package/lib/typescript/src/errorBoundary.d.ts.map +1 -1
  63. package/lib/typescript/src/events.d.ts.map +1 -1
  64. package/lib/typescript/src/index.d.ts +5 -3
  65. package/lib/typescript/src/index.d.ts.map +1 -1
  66. package/lib/typescript/src/navigation/index.d.ts +12 -0
  67. package/lib/typescript/src/navigation/index.d.ts.map +1 -0
  68. package/lib/typescript/src/navigation/navigation.interface.d.ts +17 -0
  69. package/lib/typescript/src/navigation/navigation.interface.d.ts.map +1 -0
  70. package/lib/typescript/src/navigation/screen-interactive.d.ts +16 -0
  71. package/lib/typescript/src/navigation/screen-interactive.d.ts.map +1 -0
  72. package/lib/typescript/src/navigation/screen-load.d.ts +13 -0
  73. package/lib/typescript/src/navigation/screen-load.d.ts.map +1 -0
  74. package/lib/typescript/src/navigation/screen-session.d.ts +15 -0
  75. package/lib/typescript/src/navigation/screen-session.d.ts.map +1 -0
  76. package/lib/typescript/src/navigation/useNavigationTracking.d.ts +5 -0
  77. package/lib/typescript/src/navigation/useNavigationTracking.d.ts.map +1 -0
  78. package/lib/typescript/src/navigation/utils.d.ts +8 -0
  79. package/lib/typescript/src/navigation/utils.d.ts.map +1 -0
  80. package/lib/typescript/src/network-interceptor/graphql-helper.d.ts +8 -0
  81. package/lib/typescript/src/network-interceptor/graphql-helper.d.ts.map +1 -0
  82. package/lib/typescript/src/network-interceptor/request-tracker-xhr.d.ts.map +1 -1
  83. package/lib/typescript/src/network-interceptor/span-helpers.d.ts +1 -1
  84. package/lib/typescript/src/network-interceptor/span-helpers.d.ts.map +1 -1
  85. package/lib/typescript/src/network-interceptor/url-helper.d.ts +9 -0
  86. package/lib/typescript/src/network-interceptor/url-helper.d.ts.map +1 -1
  87. package/lib/typescript/src/pulse.constants.d.ts +35 -0
  88. package/lib/typescript/src/pulse.constants.d.ts.map +1 -0
  89. package/lib/typescript/src/pulse.interface.d.ts +2 -1
  90. package/lib/typescript/src/pulse.interface.d.ts.map +1 -1
  91. package/lib/typescript/src/trace.d.ts +7 -0
  92. package/lib/typescript/src/trace.d.ts.map +1 -1
  93. package/package.json +29 -9
  94. package/plugin/build/index.d.ts +4 -0
  95. package/plugin/build/index.js +10 -0
  96. package/plugin/build/types.d.ts +26 -0
  97. package/plugin/build/types.js +2 -0
  98. package/plugin/build/utils.d.ts +9 -0
  99. package/plugin/build/utils.js +102 -0
  100. package/plugin/build/withAndroidPulse.d.ts +3 -0
  101. package/plugin/build/withAndroidPulse.js +53 -0
  102. package/scripts/pulse-cli.js +82 -0
  103. package/scripts/uploadService.js +122 -0
  104. package/scripts/utils.js +125 -0
  105. package/src/NativePulseReactNativeOtel.ts +11 -2
  106. package/src/config.ts +37 -8
  107. package/src/errorBoundary.tsx +11 -5
  108. package/src/events.ts +7 -0
  109. package/src/global.d.ts +0 -1
  110. package/src/index.tsx +6 -3
  111. package/src/navigation/index.ts +306 -0
  112. package/src/navigation/navigation.interface.ts +19 -0
  113. package/src/navigation/screen-interactive.ts +149 -0
  114. package/src/navigation/screen-load.ts +103 -0
  115. package/src/navigation/screen-session.ts +87 -0
  116. package/src/navigation/useNavigationTracking.ts +50 -0
  117. package/src/navigation/utils.ts +19 -0
  118. package/src/network-interceptor/graphql-helper.ts +110 -0
  119. package/src/network-interceptor/request-tracker-xhr.ts +3 -1
  120. package/src/network-interceptor/span-helpers.ts +27 -18
  121. package/src/network-interceptor/url-helper.ts +67 -1
  122. package/src/pulse.constants.ts +38 -0
  123. package/src/pulse.interface.ts +6 -1
  124. package/src/trace.ts +25 -2
  125. package/LICENSE +0 -20
  126. package/lib/module/network-interceptor/request-tracker-fetch.js +0 -72
  127. package/lib/module/network-interceptor/request-tracker-fetch.js.map +0 -1
  128. package/lib/module/reactNavigation.js +0 -100
  129. package/lib/module/reactNavigation.js.map +0 -1
  130. package/lib/typescript/src/network-interceptor/request-tracker-fetch.d.ts +0 -7
  131. package/lib/typescript/src/network-interceptor/request-tracker-fetch.d.ts.map +0 -1
  132. package/lib/typescript/src/reactNavigation.d.ts +0 -10
  133. package/lib/typescript/src/reactNavigation.d.ts.map +0 -1
  134. package/src/network-interceptor/request-tracker-fetch.ts +0 -96
  135. package/src/reactNavigation.tsx +0 -146
@@ -0,0 +1,19 @@
1
+ const NAVIGATION_HISTORY_MAX_SIZE = 200;
2
+
3
+ export const LOG_TAGS = {
4
+ NAVIGATION: '[Pulse Navigation]',
5
+ SCREEN_LOAD: '[Pulse Screen Load]',
6
+ SCREEN_SESSION: '[Pulse Screen Session]',
7
+ SCREEN_INTERACTIVE: '[Pulse Screen Interactive]',
8
+ } as const;
9
+
10
+ export function pushRecentRouteKey(
11
+ recentRouteKeys: string[],
12
+ key: string
13
+ ): string[] {
14
+ const updated = [...recentRouteKeys, key];
15
+ if (updated.length > NAVIGATION_HISTORY_MAX_SIZE) {
16
+ return updated.slice(updated.length - NAVIGATION_HISTORY_MAX_SIZE);
17
+ }
18
+ return updated;
19
+ }
@@ -0,0 +1,110 @@
1
+ import type { PulseAttributes } from '../pulse.interface';
2
+ import { parseUrl } from './url-helper';
3
+ import { ATTRIBUTE_KEYS } from '../pulse.constants';
4
+
5
+ export interface GraphQLOperationData {
6
+ operationName?: string;
7
+ operationType?: string;
8
+ }
9
+
10
+ export function isGraphQLRequest(url: string): boolean {
11
+ if (!url || typeof url !== 'string') {
12
+ return false;
13
+ }
14
+ return url.toLowerCase().includes('graphql');
15
+ }
16
+
17
+ function parseGraphQLQuery(query: string): GraphQLOperationData {
18
+ if (!query || typeof query !== 'string') {
19
+ return {};
20
+ }
21
+
22
+ // Named query: "query MyQuery { ... }" or "mutation CreateUser { ... }"
23
+ const namedQueryRe =
24
+ /^(?:\s*)(query|mutation|subscription)(?:\s+)(\w+)(?:\s*)[{(]/;
25
+ const namedMatch = query.match(namedQueryRe);
26
+ if (namedMatch && namedMatch.length >= 3) {
27
+ return {
28
+ operationType: namedMatch[1],
29
+ operationName: namedMatch[2],
30
+ };
31
+ }
32
+
33
+ // Unnamed query: "query { ... }" or "mutation { ... }"
34
+ const unnamedQueryRe = /^(?:\s*)(query|mutation|subscription)(?:\s*)[{(]/;
35
+ const unnamedMatch = query.match(unnamedQueryRe);
36
+ if (unnamedMatch && unnamedMatch.length >= 2) {
37
+ return {
38
+ operationType: unnamedMatch[1],
39
+ operationName: undefined,
40
+ };
41
+ }
42
+
43
+ return {};
44
+ }
45
+
46
+ function extractFromBody(body: string): GraphQLOperationData {
47
+ try {
48
+ const payload = JSON.parse(body);
49
+ let data: GraphQLOperationData = {
50
+ operationName: payload?.operationName,
51
+ operationType: payload?.operation,
52
+ };
53
+
54
+ // Fallback: If operationName/operation not in payload, parse from query string
55
+ if ((!data.operationName || !data.operationType) && payload?.query) {
56
+ const parsedQuery = parseGraphQLQuery(payload.query);
57
+ data = {
58
+ operationName: data.operationName || parsedQuery.operationName,
59
+ operationType: data.operationType || parsedQuery.operationType,
60
+ };
61
+ }
62
+
63
+ return data;
64
+ } catch {
65
+ return {};
66
+ }
67
+ }
68
+
69
+ function extractFromQueryParams(url: string): GraphQLOperationData {
70
+ try {
71
+ const parsedUrl = parseUrl(url);
72
+ if (!parsedUrl) {
73
+ return {};
74
+ }
75
+ return {
76
+ operationName: parsedUrl.searchParams.get('operationName') || undefined,
77
+ operationType: parsedUrl.searchParams.get('operation') || undefined,
78
+ };
79
+ } catch {
80
+ return {};
81
+ }
82
+ }
83
+
84
+ export function updateAttributesWithGraphQLData(
85
+ url: string,
86
+ body?: Document | XMLHttpRequestBodyInit | null
87
+ ): PulseAttributes {
88
+ if (!isGraphQLRequest(url)) {
89
+ return {};
90
+ }
91
+
92
+ let data: GraphQLOperationData = {};
93
+
94
+ if (body && typeof body === 'string') {
95
+ data = extractFromBody(body);
96
+ }
97
+ if (!data.operationName && !data.operationType) {
98
+ data = extractFromQueryParams(url);
99
+ }
100
+
101
+ const attributes: PulseAttributes = {};
102
+ if (data.operationName) {
103
+ attributes[ATTRIBUTE_KEYS.GRAPHQL_OPERATION_NAME] = data.operationName;
104
+ }
105
+ if (data.operationType) {
106
+ attributes[ATTRIBUTE_KEYS.GRAPHQL_OPERATION_TYPE] = data.operationType;
107
+ }
108
+
109
+ return attributes;
110
+ }
@@ -64,7 +64,9 @@ function createXmlHttpRequestTracker(
64
64
  url: requestData.url,
65
65
  };
66
66
 
67
- const span = createNetworkSpan(startContext, 'xmlhttprequest');
67
+ this.setRequestHeader('X-Pulse-RN-Tracked', 'true');
68
+
69
+ const span = createNetworkSpan(startContext, 'xmlhttprequest', body);
68
70
  trackedSpans.set(this, span);
69
71
  const { onRequestEnd } = requestTracker.start(startContext);
70
72
 
@@ -7,6 +7,8 @@ import type { Span } from '../index';
7
7
  import { Pulse, SpanStatusCode } from '../index';
8
8
  import type { PulseAttributes } from '../pulse.interface';
9
9
  import { extractHttpAttributes } from './url-helper';
10
+ import { updateAttributesWithGraphQLData } from './graphql-helper';
11
+ import { ATTRIBUTE_KEYS, PHASE_VALUES } from '../pulse.constants';
10
12
 
11
13
  export function setNetworkSpanAttributes(
12
14
  span: Span,
@@ -15,28 +17,28 @@ export function setNetworkSpanAttributes(
15
17
  ): PulseAttributes {
16
18
  const method = startContext.method.toUpperCase();
17
19
  let attributes: PulseAttributes = {
18
- 'http.method': method,
19
- 'http.url': startContext.url,
20
- 'pulse.type': `network.${endContext.status ?? 0}`,
21
- 'http.request.type': startContext.type,
22
- 'platform': Platform.OS as 'android' | 'ios' | 'web',
20
+ [ATTRIBUTE_KEYS.HTTP_METHOD]: method,
21
+ [ATTRIBUTE_KEYS.HTTP_URL]: startContext.url,
22
+ [ATTRIBUTE_KEYS.PULSE_TYPE]: `network.${endContext.status ?? 0}`,
23
+ [ATTRIBUTE_KEYS.HTTP_REQUEST_TYPE]: startContext.type,
24
+ [ATTRIBUTE_KEYS.PLATFORM]: Platform.OS,
23
25
  };
24
26
 
25
- // We had implemented our own URL parsing helper to avoid errors on RN < 0.80. Since this is not supported by React Native.
27
+ // We had implemented our own URL parsing helper to avoid errors on RN < 0.80. Since this is not supported by React Native.
26
28
  // Check here: https://github.com/facebook/react-native/blob/v0.79.0/packages/react-native/Libraries/Blob/URL.js
27
29
  const urlAttributes = extractHttpAttributes(startContext.url);
28
30
  attributes = { ...attributes, ...urlAttributes };
29
31
 
30
32
  if (endContext.status) {
31
- attributes['http.status_code'] = endContext.status;
33
+ attributes[ATTRIBUTE_KEYS.HTTP_STATUS_CODE] = endContext.status;
32
34
  }
33
35
 
34
36
  if (endContext.state === 'error' && endContext.error) {
35
37
  attributes.error = true;
36
- attributes['error.message'] =
38
+ attributes[ATTRIBUTE_KEYS.ERROR_MESSAGE] =
37
39
  endContext.error.message || String(endContext.error);
38
40
  if (endContext.error.stack) {
39
- attributes['error.stack'] = endContext.error.stack;
41
+ attributes[ATTRIBUTE_KEYS.ERROR_STACK] = endContext.error.stack;
40
42
  }
41
43
  span.recordException(endContext.error, attributes);
42
44
  }
@@ -47,19 +49,26 @@ export function setNetworkSpanAttributes(
47
49
 
48
50
  export function createNetworkSpan(
49
51
  startContext: RequestStartContext,
50
- interceptorType: 'fetch' | 'xmlhttprequest'
52
+ interceptorType: 'fetch' | 'xmlhttprequest',
53
+ body?: Document | XMLHttpRequestBodyInit | null
51
54
  ): Span {
52
55
  const method = startContext.method.toUpperCase();
53
56
  const spanName = `HTTP ${method}`;
54
57
 
55
- const span = Pulse.startSpan(spanName, {
56
- attributes: {
57
- 'http.method': method,
58
- 'http.url': startContext.url,
59
- 'pulse.type': 'network',
60
- 'http.request.type': interceptorType,
61
- },
62
- });
58
+ let baseAttributes: PulseAttributes = {
59
+ [ATTRIBUTE_KEYS.HTTP_METHOD]: method,
60
+ [ATTRIBUTE_KEYS.HTTP_URL]: startContext.url,
61
+ [ATTRIBUTE_KEYS.PULSE_TYPE]: PHASE_VALUES.NETWORK,
62
+ [ATTRIBUTE_KEYS.HTTP_REQUEST_TYPE]: interceptorType,
63
+ };
64
+
65
+ const graphqlAttributes = updateAttributesWithGraphQLData(
66
+ startContext.url,
67
+ body
68
+ );
69
+ const attributes = { ...baseAttributes, ...graphqlAttributes };
70
+
71
+ const span = Pulse.startSpan(spanName, { attributes });
63
72
 
64
73
  return span;
65
74
  }
@@ -8,6 +8,67 @@
8
8
  * Based on: https://github.com/facebook/react-native/blob/v0.80.0/packages/react-native/Libraries/Blob/URL.js
9
9
  */
10
10
 
11
+ export class SearchParams {
12
+ private params: Map<string, string> = new Map();
13
+
14
+ constructor(search: string) {
15
+ if (!search || typeof search !== 'string') {
16
+ return;
17
+ }
18
+
19
+ // Remove leading '?' if present
20
+ const queryString = search.startsWith('?') ? search.slice(1) : search;
21
+
22
+ if (!queryString) {
23
+ return;
24
+ }
25
+
26
+ try {
27
+ // Split by '&' to get individual parameters
28
+ const pairs = queryString.split('&');
29
+
30
+ for (const pair of pairs) {
31
+ if (!pair) continue;
32
+
33
+ // Split by '=' to get key and value
34
+ const equalIndex = pair.indexOf('=');
35
+ if (equalIndex === -1) {
36
+ // Parameter without value
37
+ const key = decodeURIComponent(pair);
38
+ if (key) {
39
+ this.params.set(key, '');
40
+ }
41
+ } else {
42
+ const key = decodeURIComponent(pair.substring(0, equalIndex));
43
+ const value = decodeURIComponent(pair.substring(equalIndex + 1));
44
+ if (key) {
45
+ this.params.set(key, value);
46
+ }
47
+ }
48
+ }
49
+ } catch (e) {
50
+ // If decoding fails, params remain empty
51
+ console.warn('[Pulse] Query parameter parsing failed:', e);
52
+ }
53
+ }
54
+
55
+ get(name: string): string | null {
56
+ return this.params.has(name) ? this.params.get(name)! : null;
57
+ }
58
+
59
+ has(name: string): boolean {
60
+ return this.params.has(name);
61
+ }
62
+
63
+ keys(): string[] {
64
+ return Array.from(this.params.keys());
65
+ }
66
+
67
+ values(): string[] {
68
+ return Array.from(this.params.values());
69
+ }
70
+ }
71
+
11
72
  export interface ParsedUrl {
12
73
  protocol: string;
13
74
  hostname: string;
@@ -17,6 +78,7 @@ export interface ParsedUrl {
17
78
  search: string;
18
79
  hash: string;
19
80
  href: string;
81
+ searchParams: SearchParams;
20
82
  }
21
83
 
22
84
  /**
@@ -31,7 +93,7 @@ function safeMatch(
31
93
  try {
32
94
  const match = text.match(regex);
33
95
  return match && match[groupIndex] ? match[groupIndex] : '';
34
- } catch (e) {
96
+ } catch {
35
97
  return '';
36
98
  }
37
99
  }
@@ -81,6 +143,9 @@ export function parseUrl(url: string): ParsedUrl | null {
81
143
  const hashContent = safeMatch(url, /#([^/]*)/);
82
144
  const hash = hashContent ? `#${hashContent}` : '';
83
145
 
146
+ // Create SearchParams instance for query parameters
147
+ const searchParams = new SearchParams(search);
148
+
84
149
  return {
85
150
  protocol: protocolWithColon,
86
151
  hostname: hostname,
@@ -90,6 +155,7 @@ export function parseUrl(url: string): ParsedUrl | null {
90
155
  search: search,
91
156
  hash: hash,
92
157
  href: url,
158
+ searchParams: searchParams,
93
159
  };
94
160
  } catch (e) {
95
161
  // Any unexpected error during parsing - return null
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Constants for Pulse React Native OpenTelemetry integration
3
+ */
4
+
5
+ export enum SPAN_NAMES {
6
+ SCREEN_SESSION = 'ScreenSession',
7
+ NAVIGATED = 'Navigated',
8
+ SCREEN_INTERACTIVE = 'ScreenInteractive',
9
+ }
10
+
11
+ export enum ATTRIBUTE_KEYS {
12
+ PULSE_TYPE = 'pulse.type',
13
+ SCREEN_NAME = 'screen.name',
14
+ ROUTE_KEY = 'routeKey',
15
+ PHASE = 'phase',
16
+ LAST_SCREEN_NAME = 'last.screen.name',
17
+ ROUTE_HAS_BEEN_SEEN = 'routeHasBeenSeen',
18
+ PLATFORM = 'platform',
19
+ GRAPHQL_OPERATION_NAME = 'graphql.operation.name',
20
+ GRAPHQL_OPERATION_TYPE = 'graphql.operation.type',
21
+ HTTP_METHOD = 'http.method',
22
+ HTTP_URL = 'http.url',
23
+ HTTP_STATUS_CODE = 'http.status_code',
24
+ HTTP_REQUEST_TYPE = 'http.request.type',
25
+ ERROR_MESSAGE = 'error.message',
26
+ ERROR_STACK = 'error.stack',
27
+ }
28
+
29
+ export enum PULSE_TYPES {
30
+ SCREEN_SESSION = 'screen_session',
31
+ SCREEN_LOAD = 'screen_load',
32
+ SCREEN_INTERACTIVE = 'screen_interactive',
33
+ }
34
+
35
+ export enum PHASE_VALUES {
36
+ START = 'start',
37
+ NETWORK = 'network',
38
+ }
@@ -11,4 +11,9 @@ export type PulseAttributeValue =
11
11
  | number[]
12
12
  | boolean[];
13
13
 
14
- export type PulseAttributes = Record<string, PulseAttributeValue | undefined>;
14
+ export type PulseAttributes = Record<
15
+ string,
16
+ PulseAttributeValue | undefined | null
17
+ >;
18
+
19
+ export type PulseFeatureConfig = Record<string, boolean> | null;
package/src/trace.ts CHANGED
@@ -4,8 +4,14 @@ import { mergeWithGlobalAttributes } from './globalAttributes';
4
4
  import { extractErrorDetails } from './utility';
5
5
  import type { PulseAttributes } from './pulse.interface';
6
6
 
7
+ /**
8
+ * Options for starting a span.
9
+ * @param attributes - Attributes to set on the span.
10
+ * @param inheritContext - Controls whether or not the new span will be parented in the existing (current) context. If false, a new context is created.
11
+ */
7
12
  export type SpanOptions = {
8
13
  attributes?: PulseAttributes;
14
+ inheritContext?: boolean;
9
15
  };
10
16
 
11
17
  export enum SpanStatusCode {
@@ -35,7 +41,12 @@ export function startSpan(name: string, options?: SpanOptions): Span {
35
41
  }
36
42
 
37
43
  const mergedAttributes = mergeWithGlobalAttributes(options?.attributes || {});
38
- const spanId = PulseReactNativeOtel.startSpan(name, mergedAttributes);
44
+ const inheritContext = options?.inheritContext ?? true;
45
+ const spanId = PulseReactNativeOtel.startSpan(
46
+ name,
47
+ inheritContext,
48
+ mergedAttributes
49
+ );
39
50
  return {
40
51
  end: (statusCode?: SpanStatusCode) => {
41
52
  return endSpan(spanId, statusCode);
@@ -63,7 +74,12 @@ export function trackSpan<T>(
63
74
  }
64
75
 
65
76
  const mergedAttributes = mergeWithGlobalAttributes(options?.attributes || {});
66
- const spanId = PulseReactNativeOtel.startSpan(name, mergedAttributes);
77
+ const inheritContext = options?.inheritContext ?? true;
78
+ const spanId = PulseReactNativeOtel.startSpan(
79
+ name,
80
+ inheritContext,
81
+ mergedAttributes
82
+ );
67
83
 
68
84
  const result = fn();
69
85
 
@@ -81,6 +97,13 @@ function endSpan(spanId: string, statusCode?: SpanStatusCode): void {
81
97
  PulseReactNativeOtel.endSpan(spanId, statusCode);
82
98
  }
83
99
 
100
+ export function discardSpan(spanId: string): void {
101
+ if (!isSupportedPlatform()) {
102
+ return;
103
+ }
104
+ PulseReactNativeOtel.discardSpan(spanId);
105
+ }
106
+
84
107
  function addSpanEvent(
85
108
  spanId: string,
86
109
  name: string,
package/LICENSE DELETED
@@ -1,20 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 HorizonOS
4
- Permission is hereby granted, free of charge, to any person obtaining a copy
5
- of this software and associated documentation files (the "Software"), to deal
6
- in the Software without restriction, including without limitation the rights
7
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- copies of the Software, and to permit persons to whom the Software is
9
- furnished to do so, subject to the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be included in all
12
- copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- SOFTWARE.
@@ -1,72 +0,0 @@
1
- "use strict";
2
-
3
- import { RequestTracker } from "./request-tracker.js";
4
- import { getAbsoluteUrl } from "../utility.js";
5
- import { createNetworkSpan, completeNetworkSpan } from "./span-helpers.js";
6
- function createStartContext(input, init) {
7
- const inputIsRequest = isRequest(input);
8
- const url = inputIsRequest ? input.url : String(input);
9
- const method = !!init && init.method || inputIsRequest && input.method || 'GET';
10
- return {
11
- url: getAbsoluteUrl(url),
12
- method,
13
- type: 'fetch'
14
- };
15
- }
16
- function isRequest(input) {
17
- return !!input && typeof input === 'object' && !(input instanceof URL);
18
- }
19
- let isFetchIntercepted = false;
20
- let originalFetch = null;
21
- function createFetchRequestTracker(global) {
22
- if (isFetchIntercepted) {
23
- console.warn('[Pulse] Fetch already intercepted');
24
- return new RequestTracker();
25
- }
26
- if (originalFetch && global.fetch !== originalFetch) {
27
- console.warn('[Pulse] Fetch already wrapped by another interceptor');
28
- isFetchIntercepted = true;
29
- return new RequestTracker();
30
- }
31
- if (global.fetch?._pulseIntercepted) {
32
- console.warn('[Pulse] Fetch already wrapped by Pulse');
33
- isFetchIntercepted = true;
34
- return new RequestTracker();
35
- }
36
- const requestTracker = new RequestTracker();
37
- originalFetch = global.fetch;
38
- isFetchIntercepted = true;
39
- const fetchWrapper = function fetch(input, init) {
40
- const startContext = createStartContext(input, init);
41
- const span = createNetworkSpan(startContext, 'fetch');
42
- const {
43
- onRequestEnd
44
- } = requestTracker.start(startContext);
45
- const fetchToCall = originalFetch;
46
- return fetchToCall.call(global, input, init).then(response => {
47
- // Determine if response is successful based on status code
48
- // 2xx and 3xx are successful, 4xx and 5xx are errors
49
- const isSuccess = response.status >= 200 && response.status < 400;
50
- const endContext = {
51
- status: response.status,
52
- state: isSuccess ? 'success' : 'error'
53
- };
54
- completeNetworkSpan(span, startContext, endContext, !isSuccess);
55
- onRequestEnd(endContext);
56
- return response;
57
- }).catch(error => {
58
- const endContext = {
59
- error,
60
- state: 'error'
61
- };
62
- completeNetworkSpan(span, startContext, endContext, true);
63
- onRequestEnd(endContext);
64
- throw error;
65
- });
66
- };
67
- fetchWrapper._pulseIntercepted = true;
68
- global.fetch = fetchWrapper;
69
- return requestTracker;
70
- }
71
- export default createFetchRequestTracker;
72
- //# sourceMappingURL=request-tracker-fetch.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["RequestTracker","getAbsoluteUrl","createNetworkSpan","completeNetworkSpan","createStartContext","input","init","inputIsRequest","isRequest","url","String","method","type","URL","isFetchIntercepted","originalFetch","createFetchRequestTracker","global","console","warn","fetch","_pulseIntercepted","requestTracker","fetchWrapper","startContext","span","onRequestEnd","start","fetchToCall","call","then","response","isSuccess","status","endContext","state","catch","error"],"sourceRoot":"../../../src","sources":["network-interceptor/request-tracker-fetch.ts"],"mappings":"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","ignoreList":[]}
@@ -1,100 +0,0 @@
1
- "use strict";
2
-
3
- import { Pulse } from "./index.js";
4
- const NAVIGATION_HISTORY_MAX_SIZE = 200;
5
- export function createReactNavigationIntegration() {
6
- let navigationContainer;
7
- let latestRoute;
8
- let recentRouteKeys = [];
9
- let isInitialized = false;
10
- let span;
11
- const onNavigationDispatch = () => {
12
- try {
13
- span = Pulse.startSpan('Navigated', {
14
- attributes: {
15
- 'pulse.type': 'screen_load',
16
- 'phase': 'start'
17
- }
18
- });
19
- console.log('[Pulse Navigation] Navigation dispatch span started', span);
20
- } catch (error) {
21
- console.warn('[Pulse Navigation] Error in onNavigationDispatch:', error);
22
- }
23
- };
24
- const onStateChange = () => {
25
- try {
26
- if (!navigationContainer) {
27
- console.warn('[Pulse Navigation] Navigation container not registered');
28
- return;
29
- }
30
- const currentRoute = navigationContainer.getCurrentRoute();
31
- if (!currentRoute) {
32
- return;
33
- }
34
- if (!span) {
35
- latestRoute = currentRoute;
36
- pushRecentRouteKey(currentRoute.key);
37
- return;
38
- }
39
- const previousRoute = latestRoute;
40
- if (previousRoute && previousRoute.key === currentRoute.key) {
41
- return;
42
- }
43
- latestRoute = currentRoute;
44
- const routeHasBeenSeen = recentRouteKeys.includes(currentRoute.key);
45
- pushRecentRouteKey(currentRoute.key);
46
- span?.setAttributes({
47
- 'screen.name': currentRoute.name,
48
- 'last.screen.name': previousRoute?.name || undefined,
49
- 'routeHasBeenSeen': routeHasBeenSeen,
50
- 'routeKey': currentRoute.key
51
- });
52
- span?.end();
53
- console.log('[Pulse Navigation] Navigation dispatch span ended', span);
54
- span = undefined;
55
- } catch (error) {
56
- console.warn('[Pulse Navigation] Error in onStateChange:', error);
57
- span = undefined;
58
- }
59
- };
60
- const registerNavigationContainer = maybeNavigationContainer => {
61
- try {
62
- let container;
63
- if (typeof maybeNavigationContainer === 'object' && maybeNavigationContainer !== null && 'current' in maybeNavigationContainer) {
64
- container = maybeNavigationContainer.current;
65
- } else {
66
- container = maybeNavigationContainer;
67
- }
68
- if (!container) {
69
- console.warn('[Pulse Navigation] Invalid navigation container ref');
70
- return;
71
- }
72
- if (isInitialized && navigationContainer === container) {
73
- console.log('[Pulse Navigation] Container already registered');
74
- return;
75
- }
76
- navigationContainer = container;
77
- navigationContainer.addListener('__unsafe_action__', onNavigationDispatch);
78
- navigationContainer.addListener('state', onStateChange);
79
- const currentRoute = navigationContainer.getCurrentRoute();
80
- if (currentRoute) {
81
- latestRoute = currentRoute;
82
- pushRecentRouteKey(currentRoute.key);
83
- }
84
- isInitialized = true;
85
- console.log('[Pulse Navigation] Integration initialized successfully');
86
- } catch (error) {
87
- console.error('[Pulse Navigation] Error registering container:', error);
88
- }
89
- };
90
- const pushRecentRouteKey = key => {
91
- recentRouteKeys.push(key);
92
- if (recentRouteKeys.length > NAVIGATION_HISTORY_MAX_SIZE) {
93
- recentRouteKeys = recentRouteKeys.slice(recentRouteKeys.length - NAVIGATION_HISTORY_MAX_SIZE);
94
- }
95
- };
96
- return {
97
- registerNavigationContainer
98
- };
99
- }
100
- //# sourceMappingURL=reactNavigation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["Pulse","NAVIGATION_HISTORY_MAX_SIZE","createReactNavigationIntegration","navigationContainer","latestRoute","recentRouteKeys","isInitialized","span","onNavigationDispatch","startSpan","attributes","console","log","error","warn","onStateChange","currentRoute","getCurrentRoute","pushRecentRouteKey","key","previousRoute","routeHasBeenSeen","includes","setAttributes","name","undefined","end","registerNavigationContainer","maybeNavigationContainer","container","current","addListener","push","length","slice"],"sourceRoot":"../../src","sources":["reactNavigation.tsx"],"mappings":"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","ignoreList":[]}
@@ -1,7 +0,0 @@
1
- import { RequestTracker } from './request-tracker';
2
- interface GlobalWithFetch {
3
- fetch: typeof fetch;
4
- }
5
- declare function createFetchRequestTracker(global: GlobalWithFetch): RequestTracker;
6
- export default createFetchRequestTracker;
7
- //# sourceMappingURL=request-tracker-fetch.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"request-tracker-fetch.d.ts","sourceRoot":"","sources":["../../../../src/network-interceptor/request-tracker-fetch.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAInD,UAAU,eAAe;IACvB,KAAK,EAAE,OAAO,KAAK,CAAC;CACrB;AAsBD,iBAAS,yBAAyB,CAAC,MAAM,EAAE,eAAe,GAAG,cAAc,CA6D1E;AAED,eAAe,yBAAyB,CAAC"}
@@ -1,10 +0,0 @@
1
- export interface NavigationRoute {
2
- name: string;
3
- key: string;
4
- params?: Record<string, any>;
5
- }
6
- export declare function createReactNavigationIntegration(): {
7
- registerNavigationContainer: (maybeNavigationContainer: unknown) => void;
8
- };
9
- export type ReactNavigationIntegration = ReturnType<typeof createReactNavigationIntegration>;
10
- //# sourceMappingURL=reactNavigation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reactNavigation.d.ts","sourceRoot":"","sources":["../../../src/reactNavigation.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B;AAOD,wBAAgB,gCAAgC;4DAoElB,OAAO,KAChC,IAAI;EAyDR;AAED,MAAM,MAAM,0BAA0B,GAAG,UAAU,CACjD,OAAO,gCAAgC,CACxC,CAAC"}