@dreamhorizonorg/pulse-react-native 0.0.1 → 0.0.3

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 (148) 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 +89 -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 +69 -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 +57 -19
  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 +179 -0
  25. package/lib/module/navigation/index.js.map +1 -0
  26. package/lib/module/navigation/navigation.interface.js +8 -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 +67 -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 +34 -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/header-helper.js +24 -0
  41. package/lib/module/network-interceptor/header-helper.js.map +1 -0
  42. package/lib/module/network-interceptor/initialization.js +18 -1
  43. package/lib/module/network-interceptor/initialization.js.map +1 -1
  44. package/lib/module/network-interceptor/request-tracker-xhr.js +61 -4
  45. package/lib/module/network-interceptor/request-tracker-xhr.js.map +1 -1
  46. package/lib/module/network-interceptor/span-helpers.js +36 -16
  47. package/lib/module/network-interceptor/span-helpers.js.map +1 -1
  48. package/lib/module/network-interceptor/url-helper.js +58 -2
  49. package/lib/module/network-interceptor/url-helper.js.map +1 -1
  50. package/lib/module/pulse.constants.js +47 -0
  51. package/lib/module/pulse.constants.js.map +1 -0
  52. package/lib/module/trace.js +17 -2
  53. package/lib/module/trace.js.map +1 -1
  54. package/lib/typescript/plugin/src/index.d.ts +5 -0
  55. package/lib/typescript/plugin/src/index.d.ts.map +1 -0
  56. package/lib/typescript/plugin/src/types.d.ts +27 -0
  57. package/lib/typescript/plugin/src/types.d.ts.map +1 -0
  58. package/lib/typescript/plugin/src/utils.d.ts +10 -0
  59. package/lib/typescript/plugin/src/utils.d.ts.map +1 -0
  60. package/lib/typescript/plugin/src/withAndroidPulse.d.ts +4 -0
  61. package/lib/typescript/plugin/src/withAndroidPulse.d.ts.map +1 -0
  62. package/lib/typescript/src/NativePulseReactNativeOtel.d.ts +15 -2
  63. package/lib/typescript/src/NativePulseReactNativeOtel.d.ts.map +1 -1
  64. package/lib/typescript/src/config.d.ts +14 -8
  65. package/lib/typescript/src/config.d.ts.map +1 -1
  66. package/lib/typescript/src/errorBoundary.d.ts.map +1 -1
  67. package/lib/typescript/src/events.d.ts.map +1 -1
  68. package/lib/typescript/src/index.d.ts +6 -4
  69. package/lib/typescript/src/index.d.ts.map +1 -1
  70. package/lib/typescript/src/navigation/index.d.ts +13 -0
  71. package/lib/typescript/src/navigation/index.d.ts.map +1 -0
  72. package/lib/typescript/src/navigation/navigation.interface.d.ts +18 -0
  73. package/lib/typescript/src/navigation/navigation.interface.d.ts.map +1 -0
  74. package/lib/typescript/src/navigation/screen-interactive.d.ts +16 -0
  75. package/lib/typescript/src/navigation/screen-interactive.d.ts.map +1 -0
  76. package/lib/typescript/src/navigation/screen-load.d.ts +13 -0
  77. package/lib/typescript/src/navigation/screen-load.d.ts.map +1 -0
  78. package/lib/typescript/src/navigation/screen-session.d.ts +15 -0
  79. package/lib/typescript/src/navigation/screen-session.d.ts.map +1 -0
  80. package/lib/typescript/src/navigation/useNavigationTracking.d.ts +5 -0
  81. package/lib/typescript/src/navigation/useNavigationTracking.d.ts.map +1 -0
  82. package/lib/typescript/src/navigation/utils.d.ts +8 -0
  83. package/lib/typescript/src/navigation/utils.d.ts.map +1 -0
  84. package/lib/typescript/src/network-interceptor/graphql-helper.d.ts +8 -0
  85. package/lib/typescript/src/network-interceptor/graphql-helper.d.ts.map +1 -0
  86. package/lib/typescript/src/network-interceptor/header-helper.d.ts +15 -0
  87. package/lib/typescript/src/network-interceptor/header-helper.d.ts.map +1 -0
  88. package/lib/typescript/src/network-interceptor/initialization.d.ts +4 -1
  89. package/lib/typescript/src/network-interceptor/initialization.d.ts.map +1 -1
  90. package/lib/typescript/src/network-interceptor/network.interface.d.ts +3 -0
  91. package/lib/typescript/src/network-interceptor/network.interface.d.ts.map +1 -1
  92. package/lib/typescript/src/network-interceptor/request-tracker-xhr.d.ts.map +1 -1
  93. package/lib/typescript/src/network-interceptor/span-helpers.d.ts +1 -1
  94. package/lib/typescript/src/network-interceptor/span-helpers.d.ts.map +1 -1
  95. package/lib/typescript/src/network-interceptor/url-helper.d.ts +9 -0
  96. package/lib/typescript/src/network-interceptor/url-helper.d.ts.map +1 -1
  97. package/lib/typescript/src/pulse.constants.d.ts +43 -0
  98. package/lib/typescript/src/pulse.constants.d.ts.map +1 -0
  99. package/lib/typescript/src/pulse.interface.d.ts +2 -1
  100. package/lib/typescript/src/pulse.interface.d.ts.map +1 -1
  101. package/lib/typescript/src/trace.d.ts +7 -0
  102. package/lib/typescript/src/trace.d.ts.map +1 -1
  103. package/package.json +29 -9
  104. package/plugin/build/index.d.ts +4 -0
  105. package/plugin/build/index.js +10 -0
  106. package/plugin/build/types.d.ts +26 -0
  107. package/plugin/build/types.js +2 -0
  108. package/plugin/build/utils.d.ts +9 -0
  109. package/plugin/build/utils.js +102 -0
  110. package/plugin/build/withAndroidPulse.d.ts +3 -0
  111. package/plugin/build/withAndroidPulse.js +53 -0
  112. package/scripts/pulse-cli.js +82 -0
  113. package/scripts/uploadService.js +122 -0
  114. package/scripts/utils.js +125 -0
  115. package/src/NativePulseReactNativeOtel.ts +18 -2
  116. package/src/config.ts +94 -23
  117. package/src/errorBoundary.tsx +11 -5
  118. package/src/events.ts +7 -0
  119. package/src/global.d.ts +0 -1
  120. package/src/index.tsx +7 -4
  121. package/src/navigation/index.ts +335 -0
  122. package/src/navigation/navigation.interface.ts +26 -0
  123. package/src/navigation/screen-interactive.ts +149 -0
  124. package/src/navigation/screen-load.ts +97 -0
  125. package/src/navigation/screen-session.ts +87 -0
  126. package/src/navigation/useNavigationTracking.ts +59 -0
  127. package/src/navigation/utils.ts +19 -0
  128. package/src/network-interceptor/graphql-helper.ts +110 -0
  129. package/src/network-interceptor/header-helper.ts +26 -0
  130. package/src/network-interceptor/initialization.ts +22 -1
  131. package/src/network-interceptor/network.interface.ts +3 -0
  132. package/src/network-interceptor/request-tracker-xhr.ts +93 -3
  133. package/src/network-interceptor/span-helpers.ts +47 -18
  134. package/src/network-interceptor/url-helper.ts +67 -1
  135. package/src/pulse.constants.ts +52 -0
  136. package/src/pulse.interface.ts +6 -1
  137. package/src/trace.ts +25 -2
  138. package/LICENSE +0 -20
  139. package/lib/module/network-interceptor/request-tracker-fetch.js +0 -72
  140. package/lib/module/network-interceptor/request-tracker-fetch.js.map +0 -1
  141. package/lib/module/reactNavigation.js +0 -100
  142. package/lib/module/reactNavigation.js.map +0 -1
  143. package/lib/typescript/src/network-interceptor/request-tracker-fetch.d.ts +0 -7
  144. package/lib/typescript/src/network-interceptor/request-tracker-fetch.d.ts.map +0 -1
  145. package/lib/typescript/src/reactNavigation.d.ts +0 -10
  146. package/lib/typescript/src/reactNavigation.d.ts.map +0 -1
  147. package/src/network-interceptor/request-tracker-fetch.ts +0 -96
  148. package/src/reactNavigation.tsx +0 -146
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ import { Pulse } from "../index.js";
4
+ import { Platform } from 'react-native';
5
+ import { SPAN_NAMES, ATTRIBUTE_KEYS, PULSE_TYPES } from "../pulse.constants.js";
6
+ import { LOG_TAGS } from "./utils.js";
7
+ export const INITIAL_SCREEN_SESSION_STATE = {
8
+ screenSessionSpan: undefined,
9
+ currentScreenKey: undefined
10
+ };
11
+ export function createScreenSessionTracker(enabled, state) {
12
+ const startScreenSession = route => {
13
+ state.screenSessionSpan = Pulse.startSpan(SPAN_NAMES.SCREEN_SESSION, {
14
+ attributes: {
15
+ [ATTRIBUTE_KEYS.PULSE_TYPE]: PULSE_TYPES.SCREEN_SESSION,
16
+ [ATTRIBUTE_KEYS.SCREEN_NAME]: route.name,
17
+ [ATTRIBUTE_KEYS.ROUTE_KEY]: route.key,
18
+ [ATTRIBUTE_KEYS.PLATFORM]: Platform.OS
19
+ }
20
+ });
21
+ state.currentScreenKey = route.key;
22
+ console.log(`${LOG_TAGS.SCREEN_SESSION} ${route.name} started`);
23
+ };
24
+ const endScreenSession = routeName => {
25
+ if (state.screenSessionSpan) {
26
+ state.screenSessionSpan.end();
27
+ if (routeName) {
28
+ console.log(`${LOG_TAGS.SCREEN_SESSION} ${routeName} ended`);
29
+ }
30
+ state.screenSessionSpan = undefined;
31
+ state.currentScreenKey = undefined;
32
+ }
33
+ };
34
+ const handleAppStateChange = (nextAppState, navigationContainer) => {
35
+ if (!enabled) {
36
+ return;
37
+ }
38
+ if (nextAppState === 'background' || nextAppState === 'inactive') {
39
+ if (state.screenSessionSpan) {
40
+ const currentRoute = navigationContainer?.getCurrentRoute();
41
+ endScreenSession(currentRoute?.name);
42
+ }
43
+ } else if (nextAppState === 'active') {
44
+ const currentRoute = navigationContainer?.getCurrentRoute();
45
+ if (currentRoute && !state.screenSessionSpan) {
46
+ startScreenSession(currentRoute);
47
+ }
48
+ }
49
+ };
50
+ const shouldStartSession = (currentRoute, appState) => {
51
+ return enabled && appState === 'active' && !state.screenSessionSpan && state.currentScreenKey !== currentRoute.key;
52
+ };
53
+ return {
54
+ startScreenSession,
55
+ endScreenSession,
56
+ handleAppStateChange,
57
+ shouldStartSession
58
+ };
59
+ }
60
+ //# sourceMappingURL=screen-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Pulse","Platform","SPAN_NAMES","ATTRIBUTE_KEYS","PULSE_TYPES","LOG_TAGS","INITIAL_SCREEN_SESSION_STATE","screenSessionSpan","undefined","currentScreenKey","createScreenSessionTracker","enabled","state","startScreenSession","route","startSpan","SCREEN_SESSION","attributes","PULSE_TYPE","SCREEN_NAME","name","ROUTE_KEY","key","PLATFORM","OS","console","log","endScreenSession","routeName","end","handleAppStateChange","nextAppState","navigationContainer","currentRoute","getCurrentRoute","shouldStartSession","appState"],"sourceRoot":"../../../src","sources":["navigation/screen-session.ts"],"mappings":";;AAAA,SAASA,KAAK,QAAmB,aAAU;AAC3C,SAA8BC,QAAQ,QAAQ,cAAc;AAC5D,SAASC,UAAU,EAAEC,cAAc,EAAEC,WAAW,QAAQ,uBAAoB;AAK5E,SAASC,QAAQ,QAAQ,YAAS;AAOlC,OAAO,MAAMC,4BAAgD,GAAG;EAC9DC,iBAAiB,EAAEC,SAAS;EAC5BC,gBAAgB,EAAED;AACpB,CAAC;AAED,OAAO,SAASE,0BAA0BA,CACxCC,OAAgB,EAChBC,KAAyB,EACzB;EACA,MAAMC,kBAAkB,GAAIC,KAAsB,IAAW;IAC3DF,KAAK,CAACL,iBAAiB,GAAGP,KAAK,CAACe,SAAS,CAACb,UAAU,CAACc,cAAc,EAAE;MACnEC,UAAU,EAAE;QACV,CAACd,cAAc,CAACe,UAAU,GAAGd,WAAW,CAACY,cAAc;QACvD,CAACb,cAAc,CAACgB,WAAW,GAAGL,KAAK,CAACM,IAAI;QACxC,CAACjB,cAAc,CAACkB,SAAS,GAAGP,KAAK,CAACQ,GAAG;QACrC,CAACnB,cAAc,CAACoB,QAAQ,GAAGtB,QAAQ,CAACuB;MACtC;IACF,CAAC,CAAC;IACFZ,KAAK,CAACH,gBAAgB,GAAGK,KAAK,CAACQ,GAAG;IAClCG,OAAO,CAACC,GAAG,CAAC,GAAGrB,QAAQ,CAACW,cAAc,IAAIF,KAAK,CAACM,IAAI,UAAU,CAAC;EACjE,CAAC;EAED,MAAMO,gBAAgB,GAAIC,SAAkB,IAAW;IACrD,IAAIhB,KAAK,CAACL,iBAAiB,EAAE;MAC3BK,KAAK,CAACL,iBAAiB,CAACsB,GAAG,CAAC,CAAC;MAC7B,IAAID,SAAS,EAAE;QACbH,OAAO,CAACC,GAAG,CAAC,GAAGrB,QAAQ,CAACW,cAAc,IAAIY,SAAS,QAAQ,CAAC;MAC9D;MACAhB,KAAK,CAACL,iBAAiB,GAAGC,SAAS;MACnCI,KAAK,CAACH,gBAAgB,GAAGD,SAAS;IACpC;EACF,CAAC;EAED,MAAMsB,oBAAoB,GAAGA,CAC3BC,YAA4B,EAC5BC,mBAAoD,KAC3C;IACT,IAAI,CAACrB,OAAO,EAAE;MACZ;IACF;IAEA,IAAIoB,YAAY,KAAK,YAAY,IAAIA,YAAY,KAAK,UAAU,EAAE;MAChE,IAAInB,KAAK,CAACL,iBAAiB,EAAE;QAC3B,MAAM0B,YAAY,GAAGD,mBAAmB,EAAEE,eAAe,CAAC,CAAC;QAC3DP,gBAAgB,CAACM,YAAY,EAAEb,IAAI,CAAC;MACtC;IACF,CAAC,MAAM,IAAIW,YAAY,KAAK,QAAQ,EAAE;MACpC,MAAME,YAAY,GAAGD,mBAAmB,EAAEE,eAAe,CAAC,CAAC;MAC3D,IAAID,YAAY,IAAI,CAACrB,KAAK,CAACL,iBAAiB,EAAE;QAC5CM,kBAAkB,CAACoB,YAAY,CAAC;MAClC;IACF;EACF,CAAC;EAED,MAAME,kBAAkB,GAAGA,CACzBF,YAA6B,EAC7BG,QAAwB,KACZ;IACZ,OACEzB,OAAO,IACPyB,QAAQ,KAAK,QAAQ,IACrB,CAACxB,KAAK,CAACL,iBAAiB,IACxBK,KAAK,CAACH,gBAAgB,KAAKwB,YAAY,CAACX,GAAG;EAE/C,CAAC;EAED,OAAO;IACLT,kBAAkB;IAClBc,gBAAgB;IAChBG,oBAAoB;IACpBK;EACF,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+
3
+ import { useRef, useCallback, useEffect, useMemo } from 'react';
4
+ import { DEFAULT_NAVIGATION_OPTIONS } from "./navigation.interface.js";
5
+ export function useNavigationTracking(navigationRef, options, createIntegration) {
6
+ const screenSessionTracking = options?.screenSessionTracking ?? DEFAULT_NAVIGATION_OPTIONS.screenSessionTracking;
7
+ const screenNavigationTracking = options?.screenNavigationTracking ?? DEFAULT_NAVIGATION_OPTIONS.screenNavigationTracking;
8
+ const screenInteractiveTracking = options?.screenInteractiveTracking ?? DEFAULT_NAVIGATION_OPTIONS.screenInteractiveTracking;
9
+ const integration = useMemo(() => {
10
+ if (createIntegration) {
11
+ return createIntegration({
12
+ screenSessionTracking,
13
+ screenNavigationTracking,
14
+ screenInteractiveTracking
15
+ });
16
+ }
17
+ throw new Error('createIntegration must be provided');
18
+ }, [screenSessionTracking, screenNavigationTracking, screenInteractiveTracking, createIntegration]);
19
+ const cleanupRef = useRef(null);
20
+ useEffect(() => {
21
+ return () => {
22
+ if (cleanupRef.current) {
23
+ cleanupRef.current();
24
+ }
25
+ };
26
+ }, []);
27
+ const onReady = useCallback(() => {
28
+ if (navigationRef.current && integration) {
29
+ cleanupRef.current = integration.registerNavigationContainer(navigationRef);
30
+ }
31
+ }, [navigationRef, integration]);
32
+ return onReady;
33
+ }
34
+ //# sourceMappingURL=useNavigationTracking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useRef","useCallback","useEffect","useMemo","DEFAULT_NAVIGATION_OPTIONS","useNavigationTracking","navigationRef","options","createIntegration","screenSessionTracking","screenNavigationTracking","screenInteractiveTracking","integration","Error","cleanupRef","current","onReady","registerNavigationContainer"],"sourceRoot":"../../../src","sources":["navigation/useNavigationTracking.ts"],"mappings":";;AAAA,SAASA,MAAM,EAAEC,WAAW,EAAEC,SAAS,EAAEC,OAAO,QAAwB,OAAO;AAC/E,SACEC,0BAA0B,QAErB,2BAAwB;AAG/B,OAAO,SAASC,qBAAqBA,CACnCC,aAA6B,EAC7BC,OAAsC,EACtCC,iBAE+B,EACnB;EACZ,MAAMC,qBAAqB,GACzBF,OAAO,EAAEE,qBAAqB,IAC9BL,0BAA0B,CAACK,qBAAqB;EAClD,MAAMC,wBAAwB,GAC5BH,OAAO,EAAEG,wBAAwB,IACjCN,0BAA0B,CAACM,wBAAwB;EACrD,MAAMC,yBAAyB,GAC7BJ,OAAO,EAAEI,yBAAyB,IAClCP,0BAA0B,CAACO,yBAAyB;EAEtD,MAAMC,WAAW,GAAGT,OAAO,CAAC,MAAM;IAChC,IAAIK,iBAAiB,EAAE;MACrB,OAAOA,iBAAiB,CAAC;QACvBC,qBAAqB;QACrBC,wBAAwB;QACxBC;MACF,CAAC,CAAC;IACJ;IACA,MAAM,IAAIE,KAAK,CAAC,oCAAoC,CAAC;EACvD,CAAC,EAAE,CACDJ,qBAAqB,EACrBC,wBAAwB,EACxBC,yBAAyB,EACzBH,iBAAiB,CAClB,CAAC;EAEF,MAAMM,UAAU,GAAGd,MAAM,CAAsB,IAAI,CAAC;EAEpDE,SAAS,CAAC,MAAM;IACd,OAAO,MAAM;MACX,IAAIY,UAAU,CAACC,OAAO,EAAE;QACtBD,UAAU,CAACC,OAAO,CAAC,CAAC;MACtB;IACF,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,MAAMC,OAAO,GAAGf,WAAW,CAAC,MAAM;IAChC,IAAIK,aAAa,CAACS,OAAO,IAAIH,WAAW,EAAE;MACxCE,UAAU,CAACC,OAAO,GAChBH,WAAW,CAACK,2BAA2B,CAACX,aAAa,CAAC;IAC1D;EACF,CAAC,EAAE,CAACA,aAAa,EAAEM,WAAW,CAAC,CAAC;EAEhC,OAAOI,OAAO;AAChB","ignoreList":[]}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ const NAVIGATION_HISTORY_MAX_SIZE = 200;
4
+ export const LOG_TAGS = {
5
+ NAVIGATION: '[Pulse Navigation]',
6
+ SCREEN_LOAD: '[Pulse Screen Load]',
7
+ SCREEN_SESSION: '[Pulse Screen Session]',
8
+ SCREEN_INTERACTIVE: '[Pulse Screen Interactive]'
9
+ };
10
+ export function pushRecentRouteKey(recentRouteKeys, key) {
11
+ const updated = [...recentRouteKeys, key];
12
+ if (updated.length > NAVIGATION_HISTORY_MAX_SIZE) {
13
+ return updated.slice(updated.length - NAVIGATION_HISTORY_MAX_SIZE);
14
+ }
15
+ return updated;
16
+ }
17
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["NAVIGATION_HISTORY_MAX_SIZE","LOG_TAGS","NAVIGATION","SCREEN_LOAD","SCREEN_SESSION","SCREEN_INTERACTIVE","pushRecentRouteKey","recentRouteKeys","key","updated","length","slice"],"sourceRoot":"../../../src","sources":["navigation/utils.ts"],"mappings":";;AAAA,MAAMA,2BAA2B,GAAG,GAAG;AAEvC,OAAO,MAAMC,QAAQ,GAAG;EACtBC,UAAU,EAAE,oBAAoB;EAChCC,WAAW,EAAE,qBAAqB;EAClCC,cAAc,EAAE,wBAAwB;EACxCC,kBAAkB,EAAE;AACtB,CAAU;AAEV,OAAO,SAASC,kBAAkBA,CAChCC,eAAyB,EACzBC,GAAW,EACD;EACV,MAAMC,OAAO,GAAG,CAAC,GAAGF,eAAe,EAAEC,GAAG,CAAC;EACzC,IAAIC,OAAO,CAACC,MAAM,GAAGV,2BAA2B,EAAE;IAChD,OAAOS,OAAO,CAACE,KAAK,CAACF,OAAO,CAACC,MAAM,GAAGV,2BAA2B,CAAC;EACpE;EACA,OAAOS,OAAO;AAChB","ignoreList":[]}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+
3
+ import { parseUrl } from "./url-helper.js";
4
+ import { ATTRIBUTE_KEYS } from "../pulse.constants.js";
5
+ export function isGraphQLRequest(url) {
6
+ if (!url || typeof url !== 'string') {
7
+ return false;
8
+ }
9
+ return url.toLowerCase().includes('graphql');
10
+ }
11
+ function parseGraphQLQuery(query) {
12
+ if (!query || typeof query !== 'string') {
13
+ return {};
14
+ }
15
+
16
+ // Named query: "query MyQuery { ... }" or "mutation CreateUser { ... }"
17
+ const namedQueryRe = /^(?:\s*)(query|mutation|subscription)(?:\s+)(\w+)(?:\s*)[{(]/;
18
+ const namedMatch = query.match(namedQueryRe);
19
+ if (namedMatch && namedMatch.length >= 3) {
20
+ return {
21
+ operationType: namedMatch[1],
22
+ operationName: namedMatch[2]
23
+ };
24
+ }
25
+
26
+ // Unnamed query: "query { ... }" or "mutation { ... }"
27
+ const unnamedQueryRe = /^(?:\s*)(query|mutation|subscription)(?:\s*)[{(]/;
28
+ const unnamedMatch = query.match(unnamedQueryRe);
29
+ if (unnamedMatch && unnamedMatch.length >= 2) {
30
+ return {
31
+ operationType: unnamedMatch[1],
32
+ operationName: undefined
33
+ };
34
+ }
35
+ return {};
36
+ }
37
+ function extractFromBody(body) {
38
+ try {
39
+ const payload = JSON.parse(body);
40
+ let data = {
41
+ operationName: payload?.operationName,
42
+ operationType: payload?.operation
43
+ };
44
+
45
+ // Fallback: If operationName/operation not in payload, parse from query string
46
+ if ((!data.operationName || !data.operationType) && payload?.query) {
47
+ const parsedQuery = parseGraphQLQuery(payload.query);
48
+ data = {
49
+ operationName: data.operationName || parsedQuery.operationName,
50
+ operationType: data.operationType || parsedQuery.operationType
51
+ };
52
+ }
53
+ return data;
54
+ } catch {
55
+ return {};
56
+ }
57
+ }
58
+ function extractFromQueryParams(url) {
59
+ try {
60
+ const parsedUrl = parseUrl(url);
61
+ if (!parsedUrl) {
62
+ return {};
63
+ }
64
+ return {
65
+ operationName: parsedUrl.searchParams.get('operationName') || undefined,
66
+ operationType: parsedUrl.searchParams.get('operation') || undefined
67
+ };
68
+ } catch {
69
+ return {};
70
+ }
71
+ }
72
+ export function updateAttributesWithGraphQLData(url, body) {
73
+ if (!isGraphQLRequest(url)) {
74
+ return {};
75
+ }
76
+ let data = {};
77
+ if (body && typeof body === 'string') {
78
+ data = extractFromBody(body);
79
+ }
80
+ if (!data.operationName && !data.operationType) {
81
+ data = extractFromQueryParams(url);
82
+ }
83
+ const attributes = {};
84
+ if (data.operationName) {
85
+ attributes[ATTRIBUTE_KEYS.GRAPHQL_OPERATION_NAME] = data.operationName;
86
+ }
87
+ if (data.operationType) {
88
+ attributes[ATTRIBUTE_KEYS.GRAPHQL_OPERATION_TYPE] = data.operationType;
89
+ }
90
+ return attributes;
91
+ }
92
+ //# sourceMappingURL=graphql-helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["parseUrl","ATTRIBUTE_KEYS","isGraphQLRequest","url","toLowerCase","includes","parseGraphQLQuery","query","namedQueryRe","namedMatch","match","length","operationType","operationName","unnamedQueryRe","unnamedMatch","undefined","extractFromBody","body","payload","JSON","parse","data","operation","parsedQuery","extractFromQueryParams","parsedUrl","searchParams","get","updateAttributesWithGraphQLData","attributes","GRAPHQL_OPERATION_NAME","GRAPHQL_OPERATION_TYPE"],"sourceRoot":"../../../src","sources":["network-interceptor/graphql-helper.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Normalizes header name according to OpenTelemetry HTTP semantic conventions:
5
+ * - Lowercase
6
+ * - Dashes replaced by underscores
7
+ * - Reference: https://opentelemetry.io/docs/specs/semconv/registry/attributes/http/
8
+ * @example
9
+ * normalizeHeaderName('Content-Type') => 'content_type'
10
+ * normalizeHeaderName('X-Request-ID') => 'x_request_id'
11
+ */
12
+ export function normalizeHeaderName(headerName) {
13
+ return headerName.toLowerCase().replace(/-/g, '_');
14
+ }
15
+
16
+ /**
17
+ * Checks if a header should be captured based on configuration.
18
+ */
19
+ export function shouldCaptureHeader(headerName, headerList) {
20
+ if (headerList.length === 0) return false;
21
+ // Case-insensitive comparison
22
+ return headerList.some(configHeader => configHeader.toLowerCase() === headerName.toLowerCase());
23
+ }
24
+ //# sourceMappingURL=header-helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["normalizeHeaderName","headerName","toLowerCase","replace","shouldCaptureHeader","headerList","length","some","configHeader"],"sourceRoot":"../../../src","sources":["network-interceptor/header-helper.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,mBAAmBA,CAACC,UAAkB,EAAU;EAC9D,OAAOA,UAAU,CAACC,WAAW,CAAC,CAAC,CAACC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;AACpD;;AAEA;AACA;AACA;AACA,OAAO,SAASC,mBAAmBA,CACjCH,UAAkB,EAClBI,UAAoB,EACX;EACT,IAAIA,UAAU,CAACC,MAAM,KAAK,CAAC,EAAE,OAAO,KAAK;EACzC;EACA,OAAOD,UAAU,CAACE,IAAI,CACnBC,YAAY,IAAKA,YAAY,CAACN,WAAW,CAAC,CAAC,KAAKD,UAAU,CAACC,WAAW,CAAC,CAC1E,CAAC;AACH","ignoreList":[]}
@@ -1,12 +1,29 @@
1
1
  "use strict";
2
2
 
3
3
  import createXmlHttpRequestTracker from "./request-tracker-xhr.js";
4
+ // Re-export header utilities for convenience (they're in a separate file to avoid dependency issues)
5
+ export { normalizeHeaderName, shouldCaptureHeader } from "./header-helper.js";
4
6
  let isInitialized = false;
5
- export function initializeNetworkInterceptor() {
7
+ let headerConfig = {
8
+ requestHeaders: [],
9
+ responseHeaders: []
10
+ };
11
+ export function getHeaderConfig() {
12
+ return headerConfig;
13
+ }
14
+ export function initializeNetworkInterceptor(config) {
6
15
  if (isInitialized) {
7
16
  console.warn('[Pulse] Network interceptor already initialized');
8
17
  return;
9
18
  }
19
+
20
+ // Store header configuration
21
+ if (config) {
22
+ headerConfig = {
23
+ requestHeaders: config.requestHeaders ?? [],
24
+ responseHeaders: config.responseHeaders ?? []
25
+ };
26
+ }
10
27
  console.log('[Pulse] 🔄 Starting network interceptor initialization...');
11
28
  try {
12
29
  // In react-native, we are intercepting XMLHttpRequest only, since axios and fetch both use it internally.
@@ -1 +1 @@
1
- {"version":3,"names":["createXmlHttpRequestTracker","isInitialized","initializeNetworkInterceptor","console","warn","log","XMLHttpRequest","error","isNetworkInterceptorInitialized"],"sourceRoot":"../../../src","sources":["network-interceptor/initialization.ts"],"mappings":";;AAAA,OAAOA,2BAA2B,MAAM,0BAAuB;AAE/D,IAAIC,aAAa,GAAG,KAAK;AAEzB,OAAO,SAASC,4BAA4BA,CAAA,EAAS;EACnD,IAAID,aAAa,EAAE;IACjBE,OAAO,CAACC,IAAI,CAAC,iDAAiD,CAAC;IAC/D;EACF;EAEAD,OAAO,CAACE,GAAG,CAAC,2DAA2D,CAAC;EAExE,IAAI;IACF;IACA;IACA,IAAI,OAAOC,cAAc,KAAK,WAAW,EAAE;MACzCN,2BAA2B,CAACM,cAAc,CAAC;IAC7C,CAAC,MAAM;MACLH,OAAO,CAACC,IAAI,CAAC,yCAAyC,CAAC;IACzD;IAEAH,aAAa,GAAG,IAAI;EACtB,CAAC,CAAC,OAAOM,KAAK,EAAE;IACdJ,OAAO,CAACI,KAAK,CAAC,mDAAmD,EAAEA,KAAK,CAAC;EAC3E;AACF;AAEA,OAAO,MAAMC,+BAA+B,GAAGA,CAAA,KAAeP,aAAa","ignoreList":[]}
1
+ {"version":3,"names":["createXmlHttpRequestTracker","normalizeHeaderName","shouldCaptureHeader","isInitialized","headerConfig","requestHeaders","responseHeaders","getHeaderConfig","initializeNetworkInterceptor","config","console","warn","log","XMLHttpRequest","error","isNetworkInterceptorInitialized"],"sourceRoot":"../../../src","sources":["network-interceptor/initialization.ts"],"mappings":";;AAAA,OAAOA,2BAA2B,MAAM,0BAAuB;AAE/D;AACA,SAASC,mBAAmB,EAAEC,mBAAmB,QAAQ,oBAAiB;AAE1E,IAAIC,aAAa,GAAG,KAAK;AACzB,IAAIC,YAAiC,GAAG;EACtCC,cAAc,EAAE,EAAE;EAClBC,eAAe,EAAE;AACnB,CAAC;AAED,OAAO,SAASC,eAAeA,CAAA,EAAwB;EACrD,OAAOH,YAAY;AACrB;AAEA,OAAO,SAASI,4BAA4BA,CAC1CC,MAA4B,EACtB;EACN,IAAIN,aAAa,EAAE;IACjBO,OAAO,CAACC,IAAI,CAAC,iDAAiD,CAAC;IAC/D;EACF;;EAEA;EACA,IAAIF,MAAM,EAAE;IACVL,YAAY,GAAG;MACbC,cAAc,EAAEI,MAAM,CAACJ,cAAc,IAAI,EAAE;MAC3CC,eAAe,EAAEG,MAAM,CAACH,eAAe,IAAI;IAC7C,CAAC;EACH;EAEAI,OAAO,CAACE,GAAG,CAAC,2DAA2D,CAAC;EAExE,IAAI;IACF;IACA;IACA,IAAI,OAAOC,cAAc,KAAK,WAAW,EAAE;MACzCb,2BAA2B,CAACa,cAAc,CAAC;IAC7C,CAAC,MAAM;MACLH,OAAO,CAACC,IAAI,CAAC,yCAAyC,CAAC;IACzD;IAEAR,aAAa,GAAG,IAAI;EACtB,CAAC,CAAC,OAAOW,KAAK,EAAE;IACdJ,OAAO,CAACI,KAAK,CAAC,mDAAmD,EAAEA,KAAK,CAAC;EAC3E;AACF;AAEA,OAAO,MAAMC,+BAA+B,GAAGA,CAAA,KAAeZ,aAAa","ignoreList":[]}
@@ -3,6 +3,8 @@
3
3
  import { RequestTracker } from "./request-tracker.js";
4
4
  import { getAbsoluteUrl } from "../utility.js";
5
5
  import { createNetworkSpan, completeNetworkSpan } from "./span-helpers.js";
6
+ import { getHeaderConfig } from "./initialization.js";
7
+ import { shouldCaptureHeader } from "./header-helper.js";
6
8
  let isXHRIntercepted = false;
7
9
  function createXmlHttpRequestTracker(xhr) {
8
10
  if (isXHRIntercepted) {
@@ -24,18 +26,42 @@ function createXmlHttpRequestTracker(xhr) {
24
26
  originalOpen.call(this, method, url, ...rest);
25
27
  };
26
28
  isXHRIntercepted = true;
29
+
30
+ // Store request headers before send
31
+ const requestHeadersMap = new WeakMap();
32
+ const originalSetRequestHeader = xhr.prototype.setRequestHeader;
33
+ xhr.prototype.setRequestHeader = function setRequestHeader(name, value) {
34
+ const headerConfig = getHeaderConfig();
35
+ const requestHeadersList = headerConfig.requestHeaders ?? [];
36
+ if (requestHeadersList.length > 0 && shouldCaptureHeader(name, requestHeadersList)) {
37
+ const existing = requestHeadersMap.get(this) || {};
38
+ requestHeadersMap.set(this, {
39
+ ...existing,
40
+ [name]: value
41
+ });
42
+ }
43
+ originalSetRequestHeader.call(this, name, value);
44
+ };
27
45
  const originalSend = xhr.prototype.send;
28
46
  xhr.prototype.send = function send(body) {
29
47
  const requestData = trackedRequests.get(this);
30
48
  if (requestData) {
31
49
  const existingHandler = requestHandlers.get(this);
32
50
  if (existingHandler) this.removeEventListener('readystatechange', existingHandler);
51
+
52
+ // Capture request headers
53
+ const headerConfig = getHeaderConfig();
54
+ const capturedRequestHeaders = requestHeadersMap.get(this);
55
+ const requestHeadersList = headerConfig.requestHeaders ?? [];
56
+ const filteredRequestHeaders = capturedRequestHeaders && requestHeadersList.length > 0 ? Object.fromEntries(Object.entries(capturedRequestHeaders).filter(([name]) => shouldCaptureHeader(name, requestHeadersList))) : undefined;
33
57
  const startContext = {
34
58
  type: 'xmlhttprequest',
35
59
  method: requestData.method,
36
- url: requestData.url
60
+ url: requestData.url,
61
+ requestHeaders: filteredRequestHeaders && Object.keys(filteredRequestHeaders).length > 0 ? filteredRequestHeaders : undefined
37
62
  };
38
- const span = createNetworkSpan(startContext, 'xmlhttprequest');
63
+ this.setRequestHeader('X-Pulse-RN-Tracked', 'true');
64
+ const span = createNetworkSpan(startContext, 'xmlhttprequest', body);
39
65
  trackedSpans.set(this, span);
40
66
  const {
41
67
  onRequestEnd
@@ -44,23 +70,54 @@ function createXmlHttpRequestTracker(xhr) {
44
70
  if (this.readyState === xhr.DONE && onRequestEnd) {
45
71
  const activeSpan = trackedSpans.get(this);
46
72
 
73
+ // Capture response headers
74
+ const responseHeaderConfig = getHeaderConfig();
75
+ const capturedResponseHeaders = {};
76
+ const responseHeadersList = responseHeaderConfig.responseHeaders ?? [];
77
+ if (responseHeadersList.length > 0) {
78
+ try {
79
+ const allHeaders = this.getAllResponseHeaders();
80
+ if (allHeaders) {
81
+ const headerLines = allHeaders.trim().split(/[\r\n]+/);
82
+ for (const line of headerLines) {
83
+ const parts = line.split(': ');
84
+ if (parts.length === 2) {
85
+ const [name, value] = parts;
86
+ if (name && value && shouldCaptureHeader(name, responseHeadersList)) {
87
+ capturedResponseHeaders[name] = value;
88
+ }
89
+ }
90
+ }
91
+ }
92
+ } catch (e) {
93
+ // Headers may not be available in some cases (CORS, etc.)
94
+ console.debug('[Pulse] Could not read response headers:', e);
95
+ }
96
+ }
97
+
47
98
  // Determine request outcome based on status code
48
99
  let endContext;
100
+ const responseHeaders = Object.keys(capturedResponseHeaders).length > 0 ? capturedResponseHeaders : undefined;
49
101
  if (this.status <= 0 || this.status >= 400) {
50
102
  endContext = {
51
103
  state: 'error',
52
- status: this.status
104
+ status: this.status,
105
+ responseHeaders
53
106
  };
54
107
  } else {
55
108
  endContext = {
56
109
  state: 'success',
57
- status: this.status
110
+ status: this.status,
111
+ responseHeaders
58
112
  };
59
113
  }
60
114
  if (activeSpan) {
61
115
  completeNetworkSpan(activeSpan, startContext, endContext, endContext.state === 'error');
62
116
  trackedSpans.delete(this);
63
117
  }
118
+
119
+ // Clean up
120
+ requestHeadersMap.delete(this);
64
121
  onRequestEnd(endContext);
65
122
  }
66
123
  };
@@ -1 +1 @@
1
- {"version":3,"names":["RequestTracker","getAbsoluteUrl","createNetworkSpan","completeNetworkSpan","isXHRIntercepted","createXmlHttpRequestTracker","xhr","console","warn","requestTracker","trackedRequests","WeakMap","trackedSpans","requestHandlers","originalOpen","prototype","open","method","url","rest","set","String","call","originalSend","send","body","requestData","get","existingHandler","removeEventListener","startContext","type","span","onRequestEnd","start","onReadyStateChange","readyState","DONE","activeSpan","endContext","status","state","delete","addEventListener"],"sourceRoot":"../../../src","sources":["network-interceptor/request-tracker-xhr.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["RequestTracker","getAbsoluteUrl","createNetworkSpan","completeNetworkSpan","getHeaderConfig","shouldCaptureHeader","isXHRIntercepted","createXmlHttpRequestTracker","xhr","console","warn","requestTracker","trackedRequests","WeakMap","trackedSpans","requestHandlers","originalOpen","prototype","open","method","url","rest","set","String","call","requestHeadersMap","originalSetRequestHeader","setRequestHeader","name","value","headerConfig","requestHeadersList","requestHeaders","length","existing","get","originalSend","send","body","requestData","existingHandler","removeEventListener","capturedRequestHeaders","filteredRequestHeaders","Object","fromEntries","entries","filter","undefined","startContext","type","keys","span","onRequestEnd","start","onReadyStateChange","readyState","DONE","activeSpan","responseHeaderConfig","capturedResponseHeaders","responseHeadersList","responseHeaders","allHeaders","getAllResponseHeaders","headerLines","trim","split","line","parts","e","debug","endContext","status","state","delete","addEventListener"],"sourceRoot":"../../../src","sources":["network-interceptor/request-tracker-xhr.ts"],"mappings":";;AAIA,SAASA,cAAc,QAAQ,sBAAmB;AAClD,SAASC,cAAc,QAAQ,eAAY;AAE3C,SAASC,iBAAiB,EAAEC,mBAAmB,QAAQ,mBAAgB;AACvE,SAASC,eAAe,QAAQ,qBAAkB;AAClD,SAASC,mBAAmB,QAAQ,oBAAiB;AASrD,IAAIC,gBAAgB,GAAG,KAAK;AAE5B,SAASC,2BAA2BA,CAClCC,GAA0B,EACV;EAChB,IAAIF,gBAAgB,EAAE;IACpBG,OAAO,CAACC,IAAI,CAAC,4CAA4C,CAAC;IAC1D,OAAO,IAAIV,cAAc,CAAC,CAAC;EAC7B;EAEA,MAAMW,cAAc,GAAG,IAAIX,cAAc,CAAC,CAAC;EAC3C,MAAMY,eAAe,GAAG,IAAIC,OAAO,CAA8B,CAAC;EAClE,MAAMC,YAAY,GAAG,IAAID,OAAO,CAAuB,CAAC;EACxD,MAAME,eAAe,GAAG,IAAIF,OAAO,CAGjC,CAAC;EAEH,MAAMG,YAAY,GAAGR,GAAG,CAACS,SAAS,CAACC,IAAI;EACvCV,GAAG,CAACS,SAAS,CAACC,IAAI,GAAG,SAASA,IAAIA,CAChCC,MAAc,EACdC,GAAiB,EACjB,GAAGC,IAAW,EACR;IACNT,eAAe,CAACU,GAAG,CAAC,IAAI,EAAE;MACxBH,MAAM;MACNC,GAAG,EAAEnB,cAAc,CAACsB,MAAM,CAACH,GAAG,CAAC;IACjC,CAAC,CAAC;;IAEF;IACAJ,YAAY,CAACQ,IAAI,CAAC,IAAI,EAAEL,MAAM,EAAEC,GAAG,EAAE,GAAGC,IAAI,CAAC;EAC/C,CAAC;EACDf,gBAAgB,GAAG,IAAI;;EAEvB;EACA,MAAMmB,iBAAiB,GAAG,IAAIZ,OAAO,CAGnC,CAAC;EACH,MAAMa,wBAAwB,GAAGlB,GAAG,CAACS,SAAS,CAACU,gBAAgB;EAC/DnB,GAAG,CAACS,SAAS,CAACU,gBAAgB,GAAG,SAASA,gBAAgBA,CACxDC,IAAY,EACZC,KAAa,EACP;IACN,MAAMC,YAAY,GAAG1B,eAAe,CAAC,CAAC;IACtC,MAAM2B,kBAAkB,GAAGD,YAAY,CAACE,cAAc,IAAI,EAAE;IAC5D,IACED,kBAAkB,CAACE,MAAM,GAAG,CAAC,IAC7B5B,mBAAmB,CAACuB,IAAI,EAAEG,kBAAkB,CAAC,EAC7C;MACA,MAAMG,QAAQ,GAAGT,iBAAiB,CAACU,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;MAClDV,iBAAiB,CAACH,GAAG,CAAC,IAAI,EAAE;QAAE,GAAGY,QAAQ;QAAE,CAACN,IAAI,GAAGC;MAAM,CAAC,CAAC;IAC7D;IACAH,wBAAwB,CAACF,IAAI,CAAC,IAAI,EAAEI,IAAI,EAAEC,KAAK,CAAC;EAClD,CAAC;EAED,MAAMO,YAAY,GAAG5B,GAAG,CAACS,SAAS,CAACoB,IAAI;EACvC7B,GAAG,CAACS,SAAS,CAACoB,IAAI,GAAG,SAASA,IAAIA,CAChCC,IAA+C,EAC/C;IACA,MAAMC,WAAW,GAAG3B,eAAe,CAACuB,GAAG,CAAC,IAAI,CAAC;IAC7C,IAAII,WAAW,EAAE;MACf,MAAMC,eAAe,GAAGzB,eAAe,CAACoB,GAAG,CAAC,IAAI,CAAC;MACjD,IAAIK,eAAe,EACjB,IAAI,CAACC,mBAAmB,CAAC,kBAAkB,EAAED,eAAe,CAAC;;MAE/D;MACA,MAAMV,YAAY,GAAG1B,eAAe,CAAC,CAAC;MACtC,MAAMsC,sBAAsB,GAAGjB,iBAAiB,CAACU,GAAG,CAAC,IAAI,CAAC;MAC1D,MAAMJ,kBAAkB,GAAGD,YAAY,CAACE,cAAc,IAAI,EAAE;MAC5D,MAAMW,sBAA0D,GAC9DD,sBAAsB,IAAIX,kBAAkB,CAACE,MAAM,GAAG,CAAC,GACnDW,MAAM,CAACC,WAAW,CAChBD,MAAM,CAACE,OAAO,CAACJ,sBAAsB,CAAC,CAACK,MAAM,CAAC,CAAC,CAACnB,IAAI,CAAC,KACnDvB,mBAAmB,CAACuB,IAAI,EAAEG,kBAAkB,CAC9C,CACF,CAAC,GACDiB,SAAS;MAEf,MAAMC,YAAiC,GAAG;QACxCC,IAAI,EAAE,gBAAgB;QACtB/B,MAAM,EAAEoB,WAAW,CAACpB,MAAM;QAC1BC,GAAG,EAAEmB,WAAW,CAACnB,GAAG;QACpBY,cAAc,EACZW,sBAAsB,IACtBC,MAAM,CAACO,IAAI,CAACR,sBAAsB,CAAC,CAACV,MAAM,GAAG,CAAC,GAC1CU,sBAAsB,GACtBK;MACR,CAAC;MAED,IAAI,CAACrB,gBAAgB,CAAC,oBAAoB,EAAE,MAAM,CAAC;MAEnD,MAAMyB,IAAI,GAAGlD,iBAAiB,CAAC+C,YAAY,EAAE,gBAAgB,EAAEX,IAAI,CAAC;MACpExB,YAAY,CAACQ,GAAG,CAAC,IAAI,EAAE8B,IAAI,CAAC;MAC5B,MAAM;QAAEC;MAAa,CAAC,GAAG1C,cAAc,CAAC2C,KAAK,CAACL,YAAY,CAAC;MAE3D,MAAMM,kBAA2C,GAAGA,CAAA,KAAM;QACxD,IAAI,IAAI,CAACC,UAAU,KAAKhD,GAAG,CAACiD,IAAI,IAAIJ,YAAY,EAAE;UAChD,MAAMK,UAAU,GAAG5C,YAAY,CAACqB,GAAG,CAAC,IAAI,CAAC;;UAEzC;UACA,MAAMwB,oBAAoB,GAAGvD,eAAe,CAAC,CAAC;UAC9C,MAAMwD,uBAA+C,GAAG,CAAC,CAAC;UAC1D,MAAMC,mBAAmB,GACvBF,oBAAoB,CAACG,eAAe,IAAI,EAAE;UAC5C,IAAID,mBAAmB,CAAC5B,MAAM,GAAG,CAAC,EAAE;YAClC,IAAI;cACF,MAAM8B,UAAU,GAAG,IAAI,CAACC,qBAAqB,CAAC,CAAC;cAC/C,IAAID,UAAU,EAAE;gBACd,MAAME,WAAW,GAAGF,UAAU,CAACG,IAAI,CAAC,CAAC,CAACC,KAAK,CAAC,SAAS,CAAC;gBACtD,KAAK,MAAMC,IAAI,IAAIH,WAAW,EAAE;kBAC9B,MAAMI,KAAK,GAAGD,IAAI,CAACD,KAAK,CAAC,IAAI,CAAC;kBAC9B,IAAIE,KAAK,CAACpC,MAAM,KAAK,CAAC,EAAE;oBACtB,MAAM,CAACL,IAAI,EAAEC,KAAK,CAAC,GAAGwC,KAAK;oBAC3B,IACEzC,IAAI,IACJC,KAAK,IACLxB,mBAAmB,CAACuB,IAAI,EAAEiC,mBAAmB,CAAC,EAC9C;sBACAD,uBAAuB,CAAChC,IAAI,CAAC,GAAGC,KAAK;oBACvC;kBACF;gBACF;cACF;YACF,CAAC,CAAC,OAAOyC,CAAC,EAAE;cACV;cACA7D,OAAO,CAAC8D,KAAK,CAAC,0CAA0C,EAAED,CAAC,CAAC;YAC9D;UACF;;UAEA;UACA,IAAIE,UAA6B;UAEjC,MAAMV,eAAe,GACnBlB,MAAM,CAACO,IAAI,CAACS,uBAAuB,CAAC,CAAC3B,MAAM,GAAG,CAAC,GAC3C2B,uBAAuB,GACvBZ,SAAS;UAEf,IAAI,IAAI,CAACyB,MAAM,IAAI,CAAC,IAAI,IAAI,CAACA,MAAM,IAAI,GAAG,EAAE;YAC1CD,UAAU,GAAG;cACXE,KAAK,EAAE,OAAO;cACdD,MAAM,EAAE,IAAI,CAACA,MAAM;cACnBX;YACF,CAAC;UACH,CAAC,MAAM;YACLU,UAAU,GAAG;cACXE,KAAK,EAAE,SAAS;cAChBD,MAAM,EAAE,IAAI,CAACA,MAAM;cACnBX;YACF,CAAC;UACH;UAEA,IAAIJ,UAAU,EAAE;YACdvD,mBAAmB,CACjBuD,UAAU,EACVT,YAAY,EACZuB,UAAU,EACVA,UAAU,CAACE,KAAK,KAAK,OACvB,CAAC;YACD5D,YAAY,CAAC6D,MAAM,CAAC,IAAI,CAAC;UAC3B;;UAEA;UACAlD,iBAAiB,CAACkD,MAAM,CAAC,IAAI,CAAC;UAE9BtB,YAAY,CAACmB,UAAU,CAAC;QAC1B;MACF,CAAC;MAED,IAAI,CAACI,gBAAgB,CAAC,kBAAkB,EAAErB,kBAAkB,CAAC;MAC7DxC,eAAe,CAACO,GAAG,CAAC,IAAI,EAAEiC,kBAAkB,CAAC;IAC/C;IAEAnB,YAAY,CAACZ,IAAI,CAAC,IAAI,EAAEc,IAAI,CAAC;EAC/B,CAAC;EAED,OAAO3B,cAAc;AACvB;AAEA,eAAeJ,2BAA2B","ignoreList":[]}
@@ -3,17 +3,20 @@
3
3
  import { Platform } from 'react-native';
4
4
  import { Pulse, SpanStatusCode } from "../index.js";
5
5
  import { extractHttpAttributes } from "./url-helper.js";
6
+ import { updateAttributesWithGraphQLData } from "./graphql-helper.js";
7
+ import { ATTRIBUTE_KEYS, PULSE_TYPES } from "../pulse.constants.js";
8
+ import { normalizeHeaderName } from "./header-helper.js";
6
9
  export function setNetworkSpanAttributes(span, startContext, endContext) {
7
10
  const method = startContext.method.toUpperCase();
8
11
  let attributes = {
9
- 'http.method': method,
10
- 'http.url': startContext.url,
11
- 'pulse.type': `network.${endContext.status ?? 0}`,
12
- 'http.request.type': startContext.type,
13
- 'platform': Platform.OS
12
+ [ATTRIBUTE_KEYS.HTTP_METHOD]: method,
13
+ [ATTRIBUTE_KEYS.HTTP_URL]: startContext.url,
14
+ [ATTRIBUTE_KEYS.PULSE_TYPE]: `${PULSE_TYPES.NETWORK}.${endContext.status ?? 0}`,
15
+ [ATTRIBUTE_KEYS.HTTP_REQUEST_TYPE]: startContext.type,
16
+ [ATTRIBUTE_KEYS.PLATFORM]: Platform.OS
14
17
  };
15
18
 
16
- // We had implemented our own URL parsing helper to avoid errors on RN < 0.80. Since this is not supported by React Native.
19
+ // We had implemented our own URL parsing helper to avoid errors on RN < 0.80. Since this is not supported by React Native.
17
20
  // Check here: https://github.com/facebook/react-native/blob/v0.79.0/packages/react-native/Libraries/Blob/URL.js
18
21
  const urlAttributes = extractHttpAttributes(startContext.url);
19
22
  attributes = {
@@ -21,29 +24,46 @@ export function setNetworkSpanAttributes(span, startContext, endContext) {
21
24
  ...urlAttributes
22
25
  };
23
26
  if (endContext.status) {
24
- attributes['http.status_code'] = endContext.status;
27
+ attributes[ATTRIBUTE_KEYS.HTTP_STATUS_CODE] = endContext.status;
25
28
  }
26
29
  if (endContext.state === 'error' && endContext.error) {
27
30
  attributes.error = true;
28
- attributes['error.message'] = endContext.error.message || String(endContext.error);
31
+ attributes[ATTRIBUTE_KEYS.ERROR_MESSAGE] = endContext.error.message || String(endContext.error);
29
32
  if (endContext.error.stack) {
30
- attributes['error.stack'] = endContext.error.stack;
33
+ attributes[ATTRIBUTE_KEYS.ERROR_STACK] = endContext.error.stack;
31
34
  }
32
35
  span.recordException(endContext.error, attributes);
33
36
  }
37
+ if (startContext.requestHeaders) {
38
+ for (const [headerName, headerValue] of Object.entries(startContext.requestHeaders)) {
39
+ const normalizedName = normalizeHeaderName(headerName);
40
+ attributes[`${ATTRIBUTE_KEYS.HTTP_REQUEST_HEADER}.${normalizedName}`] = headerValue;
41
+ }
42
+ }
43
+ if (endContext.responseHeaders) {
44
+ for (const [headerName, headerValue] of Object.entries(endContext.responseHeaders)) {
45
+ const normalizedName = normalizeHeaderName(headerName);
46
+ attributes[`${ATTRIBUTE_KEYS.HTTP_RESPONSE_HEADER}.${normalizedName}`] = headerValue;
47
+ }
48
+ }
34
49
  span.setAttributes(attributes);
35
50
  return attributes;
36
51
  }
37
- export function createNetworkSpan(startContext, interceptorType) {
52
+ export function createNetworkSpan(startContext, interceptorType, body) {
38
53
  const method = startContext.method.toUpperCase();
39
54
  const spanName = `HTTP ${method}`;
55
+ let baseAttributes = {
56
+ [ATTRIBUTE_KEYS.HTTP_METHOD]: method,
57
+ [ATTRIBUTE_KEYS.HTTP_URL]: startContext.url,
58
+ [ATTRIBUTE_KEYS.HTTP_REQUEST_TYPE]: interceptorType
59
+ };
60
+ const graphqlAttributes = updateAttributesWithGraphQLData(startContext.url, body);
61
+ const attributes = {
62
+ ...baseAttributes,
63
+ ...graphqlAttributes
64
+ };
40
65
  const span = Pulse.startSpan(spanName, {
41
- attributes: {
42
- 'http.method': method,
43
- 'http.url': startContext.url,
44
- 'pulse.type': 'network',
45
- 'http.request.type': interceptorType
46
- }
66
+ attributes
47
67
  });
48
68
  return span;
49
69
  }
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","Pulse","SpanStatusCode","extractHttpAttributes","setNetworkSpanAttributes","span","startContext","endContext","method","toUpperCase","attributes","url","status","type","OS","urlAttributes","state","error","message","String","stack","recordException","setAttributes","createNetworkSpan","interceptorType","spanName","startSpan","completeNetworkSpan","isError","console","log","spanId","spanAttributes","e","end","ERROR","UNSET"],"sourceRoot":"../../../src","sources":["network-interceptor/span-helpers.ts"],"mappings":";;AAAA,SAASA,QAAQ,QAAQ,cAAc;AAMvC,SAASC,KAAK,EAAEC,cAAc,QAAQ,aAAU;AAEhD,SAASC,qBAAqB,QAAQ,iBAAc;AAEpD,OAAO,SAASC,wBAAwBA,CACtCC,IAAU,EACVC,YAAiC,EACjCC,UAA6B,EACZ;EACjB,MAAMC,MAAM,GAAGF,YAAY,CAACE,MAAM,CAACC,WAAW,CAAC,CAAC;EAChD,IAAIC,UAA2B,GAAG;IAChC,aAAa,EAAEF,MAAM;IACrB,UAAU,EAAEF,YAAY,CAACK,GAAG;IAC5B,YAAY,EAAE,WAAWJ,UAAU,CAACK,MAAM,IAAI,CAAC,EAAE;IACjD,mBAAmB,EAAEN,YAAY,CAACO,IAAI;IACtC,UAAU,EAAEb,QAAQ,CAACc;EACvB,CAAC;;EAED;EACA;EACA,MAAMC,aAAa,GAAGZ,qBAAqB,CAACG,YAAY,CAACK,GAAG,CAAC;EAC7DD,UAAU,GAAG;IAAE,GAAGA,UAAU;IAAE,GAAGK;EAAc,CAAC;EAEhD,IAAIR,UAAU,CAACK,MAAM,EAAE;IACrBF,UAAU,CAAC,kBAAkB,CAAC,GAAGH,UAAU,CAACK,MAAM;EACpD;EAEA,IAAIL,UAAU,CAACS,KAAK,KAAK,OAAO,IAAIT,UAAU,CAACU,KAAK,EAAE;IACpDP,UAAU,CAACO,KAAK,GAAG,IAAI;IACvBP,UAAU,CAAC,eAAe,CAAC,GACzBH,UAAU,CAACU,KAAK,CAACC,OAAO,IAAIC,MAAM,CAACZ,UAAU,CAACU,KAAK,CAAC;IACtD,IAAIV,UAAU,CAACU,KAAK,CAACG,KAAK,EAAE;MAC1BV,UAAU,CAAC,aAAa,CAAC,GAAGH,UAAU,CAACU,KAAK,CAACG,KAAK;IACpD;IACAf,IAAI,CAACgB,eAAe,CAACd,UAAU,CAACU,KAAK,EAAEP,UAAU,CAAC;EACpD;EAEAL,IAAI,CAACiB,aAAa,CAACZ,UAAU,CAAC;EAC9B,OAAOA,UAAU;AACnB;AAEA,OAAO,SAASa,iBAAiBA,CAC/BjB,YAAiC,EACjCkB,eAA2C,EACrC;EACN,MAAMhB,MAAM,GAAGF,YAAY,CAACE,MAAM,CAACC,WAAW,CAAC,CAAC;EAChD,MAAMgB,QAAQ,GAAG,QAAQjB,MAAM,EAAE;EAEjC,MAAMH,IAAI,GAAGJ,KAAK,CAACyB,SAAS,CAACD,QAAQ,EAAE;IACrCf,UAAU,EAAE;MACV,aAAa,EAAEF,MAAM;MACrB,UAAU,EAAEF,YAAY,CAACK,GAAG;MAC5B,YAAY,EAAE,SAAS;MACvB,mBAAmB,EAAEa;IACvB;EACF,CAAC,CAAC;EAEF,OAAOnB,IAAI;AACb;AAEA,OAAO,SAASsB,mBAAmBA,CACjCtB,IAAU,EACVC,YAAiC,EACjCC,UAA6B,EAC7BqB,OAAgB,EACV;EACN,IAAI;IACF,MAAMlB,UAAU,GAAGN,wBAAwB,CAACC,IAAI,EAAEC,YAAY,EAAEC,UAAU,CAAC;IAC3EsB,OAAO,CAACC,GAAG,CAAC,gCAAgC,EAAE;MAC5CC,MAAM,EAAE1B,IAAI,CAAC0B,MAAM;MACnBC,cAAc,EAAEtB;IAClB,CAAC,CAAC;EACJ,CAAC,CAAC,OAAOuB,CAAC,EAAE;IACVJ,OAAO,CAACZ,KAAK,CAAC,wCAAwC,EAAEgB,CAAC,CAAC;EAC5D;EAEA5B,IAAI,CAAC6B,GAAG,CAACN,OAAO,GAAG1B,cAAc,CAACiC,KAAK,GAAGjC,cAAc,CAACkC,KAAK,CAAC;AACjE","ignoreList":[]}
1
+ {"version":3,"names":["Platform","Pulse","SpanStatusCode","extractHttpAttributes","updateAttributesWithGraphQLData","ATTRIBUTE_KEYS","PULSE_TYPES","normalizeHeaderName","setNetworkSpanAttributes","span","startContext","endContext","method","toUpperCase","attributes","HTTP_METHOD","HTTP_URL","url","PULSE_TYPE","NETWORK","status","HTTP_REQUEST_TYPE","type","PLATFORM","OS","urlAttributes","HTTP_STATUS_CODE","state","error","ERROR_MESSAGE","message","String","stack","ERROR_STACK","recordException","requestHeaders","headerName","headerValue","Object","entries","normalizedName","HTTP_REQUEST_HEADER","responseHeaders","HTTP_RESPONSE_HEADER","setAttributes","createNetworkSpan","interceptorType","body","spanName","baseAttributes","graphqlAttributes","startSpan","completeNetworkSpan","isError","console","log","spanId","spanAttributes","e","end","ERROR","UNSET"],"sourceRoot":"../../../src","sources":["network-interceptor/span-helpers.ts"],"mappings":"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","ignoreList":[]}
@@ -10,6 +10,58 @@
10
10
  * Based on: https://github.com/facebook/react-native/blob/v0.80.0/packages/react-native/Libraries/Blob/URL.js
11
11
  */
12
12
 
13
+ export class SearchParams {
14
+ params = new Map();
15
+ constructor(search) {
16
+ if (!search || typeof search !== 'string') {
17
+ return;
18
+ }
19
+
20
+ // Remove leading '?' if present
21
+ const queryString = search.startsWith('?') ? search.slice(1) : search;
22
+ if (!queryString) {
23
+ return;
24
+ }
25
+ try {
26
+ // Split by '&' to get individual parameters
27
+ const pairs = queryString.split('&');
28
+ for (const pair of pairs) {
29
+ if (!pair) continue;
30
+
31
+ // Split by '=' to get key and value
32
+ const equalIndex = pair.indexOf('=');
33
+ if (equalIndex === -1) {
34
+ // Parameter without value
35
+ const key = decodeURIComponent(pair);
36
+ if (key) {
37
+ this.params.set(key, '');
38
+ }
39
+ } else {
40
+ const key = decodeURIComponent(pair.substring(0, equalIndex));
41
+ const value = decodeURIComponent(pair.substring(equalIndex + 1));
42
+ if (key) {
43
+ this.params.set(key, value);
44
+ }
45
+ }
46
+ }
47
+ } catch (e) {
48
+ // If decoding fails, params remain empty
49
+ console.warn('[Pulse] Query parameter parsing failed:', e);
50
+ }
51
+ }
52
+ get(name) {
53
+ return this.params.has(name) ? this.params.get(name) : null;
54
+ }
55
+ has(name) {
56
+ return this.params.has(name);
57
+ }
58
+ keys() {
59
+ return Array.from(this.params.keys());
60
+ }
61
+ values() {
62
+ return Array.from(this.params.values());
63
+ }
64
+ }
13
65
  /**
14
66
  * Safely extract a regex match group
15
67
  * Returns empty string if match fails or group is undefined
@@ -18,7 +70,7 @@ function safeMatch(text, regex, groupIndex = 1) {
18
70
  try {
19
71
  const match = text.match(regex);
20
72
  return match && match[groupIndex] ? match[groupIndex] : '';
21
- } catch (e) {
73
+ } catch {
22
74
  return '';
23
75
  }
24
76
  }
@@ -66,6 +118,9 @@ export function parseUrl(url) {
66
118
  // Hash - e.g., "#section"
67
119
  const hashContent = safeMatch(url, /#([^/]*)/);
68
120
  const hash = hashContent ? `#${hashContent}` : '';
121
+
122
+ // Create SearchParams instance for query parameters
123
+ const searchParams = new SearchParams(search);
69
124
  return {
70
125
  protocol: protocolWithColon,
71
126
  hostname: hostname,
@@ -74,7 +129,8 @@ export function parseUrl(url) {
74
129
  pathname: pathname,
75
130
  search: search,
76
131
  hash: hash,
77
- href: url
132
+ href: url,
133
+ searchParams: searchParams
78
134
  };
79
135
  } catch (e) {
80
136
  // Any unexpected error during parsing - return null