profileGroupProvider.tsx 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import {createContext, useContext, useMemo} from 'react';
  2. import * as Sentry from '@sentry/react';
  3. import type {Frame} from 'sentry/utils/profiling/frame';
  4. import type {ProfileGroup} from 'sentry/utils/profiling/profile/importProfile';
  5. import {importProfile} from 'sentry/utils/profiling/profile/importProfile';
  6. type ProfileGroupContextValue = ProfileGroup;
  7. const ProfileGroupContext = createContext<ProfileGroupContextValue | null>(null);
  8. export function useProfileGroup(): ProfileGroup {
  9. const context = useContext(ProfileGroupContext);
  10. if (!context) {
  11. throw new Error('useProfileGroup was called outside of ProfileGroupProvider');
  12. }
  13. return context;
  14. }
  15. export const LOADING_PROFILE_GROUP: Readonly<ProfileGroup> = {
  16. name: 'Loading',
  17. activeProfileIndex: 0,
  18. transactionID: null,
  19. metadata: {},
  20. measurements: {},
  21. traceID: '',
  22. profiles: [],
  23. type: 'loading',
  24. };
  25. interface ProfileGroupProviderProps {
  26. children: React.ReactNode;
  27. input: Readonly<Profiling.ProfileInput> | null;
  28. traceID: string;
  29. type: 'flamegraph' | 'flamechart';
  30. frameFilter?: (frame: Frame) => boolean;
  31. }
  32. export function ProfileGroupProvider(props: ProfileGroupProviderProps) {
  33. const profileGroup = useMemo(() => {
  34. if (!props.input) {
  35. return LOADING_PROFILE_GROUP;
  36. }
  37. const qs = new URLSearchParams(window.location.search);
  38. const threadId = qs.get('tid');
  39. try {
  40. return importProfile(
  41. props.input,
  42. props.traceID,
  43. threadId,
  44. props.type,
  45. props.frameFilter
  46. );
  47. } catch (err) {
  48. Sentry.captureException(err);
  49. return LOADING_PROFILE_GROUP;
  50. }
  51. }, [props.input, props.traceID, props.type, props.frameFilter]);
  52. return (
  53. <ProfileGroupContext.Provider value={profileGroup}>
  54. {props.children}
  55. </ProfileGroupContext.Provider>
  56. );
  57. }