@parca/profile 0.19.150 → 0.19.152

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 (38) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/GraphTooltipArrow/Content.d.ts +2 -1
  3. package/dist/GraphTooltipArrow/Content.d.ts.map +1 -1
  4. package/dist/GraphTooltipArrow/Content.js +203 -9
  5. package/dist/GraphTooltipArrow/gpuFrameDescriptions.d.ts +28 -0
  6. package/dist/GraphTooltipArrow/gpuFrameDescriptions.d.ts.map +1 -0
  7. package/dist/GraphTooltipArrow/gpuFrameDescriptions.js +845 -0
  8. package/dist/GraphTooltipArrow/index.d.ts +2 -1
  9. package/dist/GraphTooltipArrow/index.d.ts.map +1 -1
  10. package/dist/GraphTooltipArrow/index.js +11 -2
  11. package/dist/GraphTooltipArrow/openInNewTab.d.ts +2 -0
  12. package/dist/GraphTooltipArrow/openInNewTab.d.ts.map +1 -0
  13. package/dist/GraphTooltipArrow/openInNewTab.js +40 -0
  14. package/dist/ProfileExplorer/ProfileExplorerCompare.d.ts +1 -3
  15. package/dist/ProfileExplorer/ProfileExplorerCompare.d.ts.map +1 -1
  16. package/dist/ProfileExplorer/ProfileExplorerCompare.js +34 -39
  17. package/dist/ProfileExplorer/ProfileExplorerSingle.d.ts +1 -3
  18. package/dist/ProfileExplorer/ProfileExplorerSingle.d.ts.map +1 -1
  19. package/dist/ProfileExplorer/ProfileExplorerSingle.js +18 -21
  20. package/dist/ProfileExplorer/index.d.ts +1 -3
  21. package/dist/ProfileExplorer/index.d.ts.map +1 -1
  22. package/dist/ProfileExplorer/index.js +24 -32
  23. package/dist/ProfileFlameGraph/FlameGraphArrow/MemoizedTooltip.d.ts.map +1 -1
  24. package/dist/ProfileFlameGraph/FlameGraphArrow/MemoizedTooltip.js +119 -56
  25. package/dist/ProfileSelector/index.d.ts +1 -3
  26. package/dist/ProfileSelector/index.d.ts.map +1 -1
  27. package/dist/styles.css +1 -1
  28. package/package.json +2 -2
  29. package/src/GraphTooltipArrow/Content.tsx +86 -5
  30. package/src/GraphTooltipArrow/gpuFrameDescriptions.test.ts +53 -0
  31. package/src/GraphTooltipArrow/gpuFrameDescriptions.ts +556 -0
  32. package/src/GraphTooltipArrow/index.tsx +13 -1
  33. package/src/GraphTooltipArrow/openInNewTab.ts +43 -0
  34. package/src/ProfileExplorer/ProfileExplorerCompare.tsx +1 -8
  35. package/src/ProfileExplorer/ProfileExplorerSingle.tsx +1 -7
  36. package/src/ProfileExplorer/index.tsx +6 -7
  37. package/src/ProfileFlameGraph/FlameGraphArrow/MemoizedTooltip.tsx +35 -2
  38. package/src/ProfileSelector/index.tsx +1 -3
@@ -16,7 +16,6 @@ import {useCallback, useEffect, useMemo, useState} from 'react';
16
16
  import {QueryServiceClient} from '@parca/client';
17
17
  import {Query} from '@parca/parser';
18
18
  import {TEST_IDS, testId} from '@parca/test-utils';
19
- import type {NavigateFunction} from '@parca/utilities';
20
19
 
21
20
  import {ProfileDiffSource, ProfileViewWithData} from '..';
22
21
  import ProfileSelector from '../ProfileSelector';
@@ -25,13 +24,9 @@ import {useQueryState} from '../hooks/useQueryState';
25
24
 
26
25
  interface ProfileExplorerCompareProps {
27
26
  queryClient: QueryServiceClient;
28
- navigateTo: NavigateFunction;
29
27
  }
30
28
 
31
- const ProfileExplorerCompare = ({
32
- queryClient,
33
- navigateTo,
34
- }: ProfileExplorerCompareProps): JSX.Element => {
29
+ const ProfileExplorerCompare = ({queryClient}: ProfileExplorerCompareProps): JSX.Element => {
35
30
  const [showMetricsGraph, setShowMetricsGraph] = useState(true);
36
31
  const {closeCompareMode, isCompareMode, isCompareAbsolute} = useCompareModeMeta();
37
32
 
@@ -107,7 +102,6 @@ const ProfileExplorerCompare = ({
107
102
  closeProfile={closeProfileA}
108
103
  enforcedProfileName={''}
109
104
  comparing={true}
110
- navigateTo={navigateTo}
111
105
  suffix="_a"
112
106
  showMetricsGraph={showMetricsGraph}
113
107
  setDisplayHideMetricsGraphButton={setShowMetricsGraph}
@@ -122,7 +116,6 @@ const ProfileExplorerCompare = ({
122
116
  closeProfile={closeProfileB}
123
117
  enforcedProfileName={enforcedProfileNameA}
124
118
  comparing={true}
125
- navigateTo={navigateTo}
126
119
  suffix="_b"
127
120
  showMetricsGraph={showMetricsGraph}
128
121
  setDisplayHideMetricsGraphButton={setShowMetricsGraph}
@@ -14,7 +14,6 @@
14
14
  import {useCallback, useState} from 'react';
15
15
 
16
16
  import {QueryServiceClient} from '@parca/client';
17
- import type {NavigateFunction} from '@parca/utilities';
18
17
 
19
18
  import {ProfileViewWithData} from '..';
20
19
  import ProfileSelector from '../ProfileSelector';
@@ -22,13 +21,9 @@ import {useQueryState} from '../hooks/useQueryState';
22
21
 
23
22
  interface ProfileExplorerSingleProps {
24
23
  queryClient: QueryServiceClient;
25
- navigateTo: NavigateFunction;
26
24
  }
27
25
 
28
- const ProfileExplorerSingle = ({
29
- queryClient,
30
- navigateTo,
31
- }: ProfileExplorerSingleProps): JSX.Element => {
26
+ const ProfileExplorerSingle = ({queryClient}: ProfileExplorerSingleProps): JSX.Element => {
32
27
  const [showMetricsGraph, setShowMetricsGraph] = useState(true);
33
28
  const {profileSource, setDraftTimeRange, commitDraft} = useQueryState({suffix: '_a'});
34
29
 
@@ -47,7 +42,6 @@ const ProfileExplorerSingle = ({
47
42
  closeProfile={() => {}} // eslint-disable-line @typescript-eslint/no-empty-function
48
43
  comparing={false}
49
44
  enforcedProfileName={''}
50
- navigateTo={navigateTo}
51
45
  suffix="_a"
52
46
  showMetricsGraph={showMetricsGraph}
53
47
  setDisplayHideMetricsGraphButton={setShowMetricsGraph}
@@ -18,7 +18,7 @@ import {Provider} from 'react-redux';
18
18
  import {QueryServiceClient} from '@parca/client';
19
19
  import {KeyDownProvider, useParcaContext} from '@parca/components';
20
20
  import {createStore} from '@parca/store';
21
- import {capitalizeOnlyFirstLetter, type NavigateFunction} from '@parca/utilities';
21
+ import {capitalizeOnlyFirstLetter} from '@parca/utilities';
22
22
 
23
23
  import {useCompareModeMeta} from '../hooks/useCompareModeMeta';
24
24
  import {useHasProfileData} from '../useHasProfileData';
@@ -27,7 +27,6 @@ import ProfileExplorerSingle from './ProfileExplorerSingle';
27
27
 
28
28
  interface ProfileExplorerProps {
29
29
  queryClient: QueryServiceClient;
30
- navigateTo: NavigateFunction;
31
30
  }
32
31
 
33
32
  const ErrorContent = ({errorMessage}: {errorMessage: string}): JSX.Element => {
@@ -41,7 +40,7 @@ const ErrorContent = ({errorMessage}: {errorMessage: string}): JSX.Element => {
41
40
  );
42
41
  };
43
42
 
44
- const ProfileExplorerApp = ({queryClient, navigateTo}: ProfileExplorerProps): JSX.Element => {
43
+ const ProfileExplorerApp = ({queryClient}: ProfileExplorerProps): JSX.Element => {
45
44
  const {
46
45
  loading: hasProfileDataLoading,
47
46
  data: hasProfileData,
@@ -77,13 +76,13 @@ const ProfileExplorerApp = ({queryClient, navigateTo}: ProfileExplorerProps): JS
77
76
  }
78
77
 
79
78
  if (isCompareMode) {
80
- return <ProfileExplorerCompare queryClient={queryClient} navigateTo={navigateTo} />;
79
+ return <ProfileExplorerCompare queryClient={queryClient} />;
81
80
  }
82
81
 
83
- return <ProfileExplorerSingle queryClient={queryClient} navigateTo={navigateTo} />;
82
+ return <ProfileExplorerSingle queryClient={queryClient} />;
84
83
  };
85
84
 
86
- const ProfileExplorer = ({queryClient, navigateTo}: ProfileExplorerProps): JSX.Element => {
85
+ const ProfileExplorer = ({queryClient}: ProfileExplorerProps): JSX.Element => {
87
86
  const {additionalFlamegraphColorProfiles} = useParcaContext();
88
87
 
89
88
  const {store: reduxStore} = useMemo(() => {
@@ -93,7 +92,7 @@ const ProfileExplorer = ({queryClient, navigateTo}: ProfileExplorerProps): JSX.E
93
92
  return (
94
93
  <Provider store={reduxStore}>
95
94
  <KeyDownProvider>
96
- <ProfileExplorerApp queryClient={queryClient} navigateTo={navigateTo} />
95
+ <ProfileExplorerApp queryClient={queryClient} />
97
96
  </KeyDownProvider>
98
97
  </Provider>
99
98
  );
@@ -11,7 +11,7 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
 
14
- import React, {memo, useEffect, useState} from 'react';
14
+ import React, {memo, useEffect, useRef, useState} from 'react';
15
15
 
16
16
  import GraphTooltipArrow from '../../GraphTooltipArrow';
17
17
  import GraphTooltipArrowContent from '../../GraphTooltipArrow/Content';
@@ -28,13 +28,45 @@ export const MemoizedTooltip = memo(function MemoizedTooltip({
28
28
  dockedMetainfo,
29
29
  }: MemoizedTooltipProps): React.JSX.Element | null {
30
30
  const [tooltipRow, setTooltipRow] = useState<number | null>(null);
31
+ const [shiftHeld, setShiftHeld] = useState(false);
32
+ const shiftHeldRef = useRef(false);
33
+
34
+ useEffect(() => {
35
+ shiftHeldRef.current = shiftHeld;
36
+ }, [shiftHeld]);
37
+
31
38
  const {table, total, totalUnfiltered, profileType, unit, compareAbsolute, tooltipId} =
32
39
  useTooltipContext();
33
40
 
41
+ useEffect(() => {
42
+ const onKeyDown = (e: KeyboardEvent): void => {
43
+ if (e.key === 'Shift') setShiftHeld(true);
44
+ };
45
+ const onKeyUp = (e: KeyboardEvent): void => {
46
+ if (e.key === 'Shift') setShiftHeld(false);
47
+ };
48
+ // If the user opens the attribution link, releases Shift in the new tab,
49
+ // and comes back — our window never saw the keyup, so the frozen state
50
+ // would stick. Clear it whenever focus leaves the tab.
51
+ const onBlurOrHide = (): void => setShiftHeld(false);
52
+ window.addEventListener('keydown', onKeyDown);
53
+ window.addEventListener('keyup', onKeyUp);
54
+ window.addEventListener('blur', onBlurOrHide);
55
+ document.addEventListener('visibilitychange', onBlurOrHide);
56
+ return () => {
57
+ window.removeEventListener('keydown', onKeyDown);
58
+ window.removeEventListener('keyup', onKeyUp);
59
+ window.removeEventListener('blur', onBlurOrHide);
60
+ document.removeEventListener('visibilitychange', onBlurOrHide);
61
+ };
62
+ }, []);
63
+
34
64
  // This component subscribes to tooltip updates through a callback
35
65
  // passed to the TooltipProvider, avoiding the need to lift state
36
66
  useEffect(() => {
37
67
  const handleTooltipUpdate = (event: CustomEvent<{row: number | null}>): void => {
68
+ // While Shift is held, lock the tooltip to its original frame.
69
+ if (shiftHeldRef.current) return;
38
70
  setTooltipRow(event.detail.row);
39
71
  };
40
72
 
@@ -82,7 +114,7 @@ export const MemoizedTooltip = memo(function MemoizedTooltip({
82
114
  return null;
83
115
  }
84
116
  return (
85
- <GraphTooltipArrow contextElement={contextElement}>
117
+ <GraphTooltipArrow contextElement={contextElement} frozen={shiftHeld}>
86
118
  <GraphTooltipArrowContent
87
119
  table={table}
88
120
  row={tooltipRow}
@@ -92,6 +124,7 @@ export const MemoizedTooltip = memo(function MemoizedTooltip({
92
124
  profileType={profileType}
93
125
  unit={unit}
94
126
  compareAbsolute={compareAbsolute}
127
+ frozen={shiftHeld}
95
128
  />
96
129
  </GraphTooltipArrow>
97
130
  );
@@ -21,7 +21,7 @@ import {DateTimeRange, IconButton, useGrpcMetadata, useParcaContext} from '@parc
21
21
  import {CloseIcon} from '@parca/icons';
22
22
  import {Query} from '@parca/parser';
23
23
  import {TEST_IDS, testId} from '@parca/test-utils';
24
- import {millisToProtoTimestamp, type NavigateFunction} from '@parca/utilities';
24
+ import {millisToProtoTimestamp} from '@parca/utilities';
25
25
 
26
26
  import {
27
27
  ProfileFilter,
@@ -59,7 +59,6 @@ interface ProfileSelectorProps extends ProfileSelectorFeatures {
59
59
  closeProfile: () => void;
60
60
  enforcedProfileName: string;
61
61
  comparing: boolean;
62
- navigateTo: NavigateFunction;
63
62
  setDisplayHideMetricsGraphButton?: Dispatch<SetStateAction<boolean>>;
64
63
  suffix?: '_a' | '_b'; // For comparison mode
65
64
  onSearchHook?: () => void;
@@ -104,7 +103,6 @@ const ProfileSelector = ({
104
103
  closeProfile,
105
104
  enforcedProfileName,
106
105
  comparing,
107
- navigateTo: _navigateTo,
108
106
  showMetricsGraph = true,
109
107
  showSumBySelector = true,
110
108
  showProfileTypeSelector = true,