flamegraphContextProvider.tsx 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import {useMemo} from 'react';
  2. import {DeepPartial} from 'sentry/types/utils';
  3. import {Rect} from 'sentry/utils/profiling/gl/utils';
  4. import {useUndoableReducer} from 'sentry/utils/useUndoableReducer';
  5. import {FlamegraphProfiles} from './reducers/flamegraphProfiles';
  6. import {
  7. DEFAULT_FLAMEGRAPH_STATE,
  8. FlamegraphState,
  9. FlamegraphStateDispatchContext,
  10. flamegraphStateReducer,
  11. FlamegraphStateValue,
  12. FlamegraphStateValueContext,
  13. } from './flamegraphContext';
  14. function isValidHighlightFrame(
  15. frame: Partial<FlamegraphProfiles['highlightFrames']> | null | undefined
  16. ): frame is FlamegraphProfiles['highlightFrames'] {
  17. return !!frame && (typeof frame.name === 'string' || typeof frame.package === 'string');
  18. }
  19. interface FlamegraphStateProviderProps {
  20. children: React.ReactNode;
  21. initialState?: DeepPartial<FlamegraphState>;
  22. }
  23. function getDefaultState(initialState?: DeepPartial<FlamegraphState>): FlamegraphState {
  24. return {
  25. profiles: {
  26. highlightFrames: isValidHighlightFrame(initialState?.profiles?.highlightFrames)
  27. ? {
  28. name: undefined,
  29. package: undefined,
  30. ...initialState?.profiles?.highlightFrames,
  31. }
  32. : isValidHighlightFrame(DEFAULT_FLAMEGRAPH_STATE.profiles.highlightFrames)
  33. ? DEFAULT_FLAMEGRAPH_STATE.profiles.highlightFrames
  34. : null,
  35. selectedRoot: null,
  36. threadId:
  37. initialState?.profiles?.threadId ?? DEFAULT_FLAMEGRAPH_STATE.profiles.threadId,
  38. },
  39. position: {
  40. view: (initialState?.position?.view ??
  41. DEFAULT_FLAMEGRAPH_STATE.position.view) as Rect,
  42. },
  43. preferences: {
  44. timelines: {
  45. ...DEFAULT_FLAMEGRAPH_STATE.preferences.timelines,
  46. ...(initialState?.preferences?.timelines ?? {}),
  47. },
  48. layout:
  49. initialState?.preferences?.layout ?? DEFAULT_FLAMEGRAPH_STATE.preferences.layout,
  50. colorCoding:
  51. initialState?.preferences?.colorCoding ??
  52. DEFAULT_FLAMEGRAPH_STATE.preferences.colorCoding,
  53. sorting:
  54. initialState?.preferences?.sorting ??
  55. DEFAULT_FLAMEGRAPH_STATE.preferences.sorting,
  56. view: initialState?.preferences?.view ?? DEFAULT_FLAMEGRAPH_STATE.preferences.view,
  57. },
  58. search: {
  59. ...DEFAULT_FLAMEGRAPH_STATE.search,
  60. query: initialState?.search?.query ?? DEFAULT_FLAMEGRAPH_STATE.search.query,
  61. },
  62. };
  63. }
  64. export function FlamegraphStateProvider(
  65. props: FlamegraphStateProviderProps
  66. ): React.ReactElement {
  67. const [state, dispatch, {nextState, previousState}] = useUndoableReducer(
  68. flamegraphStateReducer,
  69. getDefaultState(props.initialState)
  70. );
  71. const flamegraphContextValue: FlamegraphStateValue = useMemo(() => {
  72. return [state, {nextState, previousState}];
  73. }, [state, nextState, previousState]);
  74. return (
  75. <FlamegraphStateValueContext.Provider value={flamegraphContextValue}>
  76. <FlamegraphStateDispatchContext.Provider value={dispatch}>
  77. {props.children}
  78. </FlamegraphStateDispatchContext.Provider>
  79. </FlamegraphStateValueContext.Provider>
  80. );
  81. }