@parca/profile 0.19.139 → 0.19.142

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 (170) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/GraphTooltipArrow/Content.js +224 -30
  3. package/dist/GraphTooltipArrow/DockedGraphTooltip/index.js +192 -33
  4. package/dist/GraphTooltipArrow/ExpandOnHoverValue.js +53 -3
  5. package/dist/GraphTooltipArrow/index.d.ts.map +1 -1
  6. package/dist/GraphTooltipArrow/index.js +86 -56
  7. package/dist/GraphTooltipArrow/useGraphTooltip/index.js +37 -37
  8. package/dist/GraphTooltipArrow/useGraphTooltipMetaInfo/index.js +103 -73
  9. package/dist/MatchersInput/SuggestionItem.js +91 -12
  10. package/dist/MatchersInput/SuggestionsList.d.ts +2 -1
  11. package/dist/MatchersInput/SuggestionsList.d.ts.map +1 -1
  12. package/dist/MatchersInput/SuggestionsList.js +371 -157
  13. package/dist/MatchersInput/SuggestionsList.test.d.ts +2 -0
  14. package/dist/MatchersInput/SuggestionsList.test.d.ts.map +1 -0
  15. package/dist/MatchersInput/index.js +308 -115
  16. package/dist/MetricsCircle/index.js +39 -3
  17. package/dist/MetricsGraph/MetricsContextMenu/index.js +119 -19
  18. package/dist/MetricsGraph/MetricsInfoPanel/index.js +81 -20
  19. package/dist/MetricsGraph/MetricsTooltip/index.d.ts.map +1 -1
  20. package/dist/MetricsGraph/MetricsTooltip/index.js +107 -74
  21. package/dist/MetricsGraph/index.js +552 -203
  22. package/dist/MetricsGraph/useMetricsGraphDimensions.js +46 -25
  23. package/dist/MetricsGraph/utils/colorMapping.js +24 -17
  24. package/dist/MetricsSeries/index.js +70 -7
  25. package/dist/PreSelectedMatchers/index.d.ts.map +1 -1
  26. package/dist/PreSelectedMatchers/index.js +249 -102
  27. package/dist/ProfileExplorer/ProfileExplorerCompare.js +240 -49
  28. package/dist/ProfileExplorer/ProfileExplorerSingle.js +98 -11
  29. package/dist/ProfileExplorer/index.js +183 -32
  30. package/dist/ProfileFlameChart/SamplesStrips/SamplesGraph/index.js +333 -148
  31. package/dist/ProfileFlameChart/SamplesStrips/SamplesStrips.stories.js +69 -35
  32. package/dist/ProfileFlameChart/SamplesStrips/index.js +645 -134
  33. package/dist/ProfileFlameChart/SamplesStrips/labelSetUtils.js +114 -55
  34. package/dist/ProfileFlameChart/index.js +266 -134
  35. package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenu.js +287 -88
  36. package/dist/ProfileFlameGraph/FlameGraphArrow/ContextMenuWrapper.js +56 -20
  37. package/dist/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.js +211 -140
  38. package/dist/ProfileFlameGraph/FlameGraphArrow/MemoizedTooltip.js +133 -38
  39. package/dist/ProfileFlameGraph/FlameGraphArrow/MiniMap.js +261 -216
  40. package/dist/ProfileFlameGraph/FlameGraphArrow/TextWithEllipsis.d.ts.map +1 -1
  41. package/dist/ProfileFlameGraph/FlameGraphArrow/TextWithEllipsis.js +71 -45
  42. package/dist/ProfileFlameGraph/FlameGraphArrow/TooltipContext.d.ts.map +1 -1
  43. package/dist/ProfileFlameGraph/FlameGraphArrow/TooltipContext.js +58 -28
  44. package/dist/ProfileFlameGraph/FlameGraphArrow/ZoomControls.d.ts.map +1 -1
  45. package/dist/ProfileFlameGraph/FlameGraphArrow/ZoomControls.js +59 -8
  46. package/dist/ProfileFlameGraph/FlameGraphArrow/index.js +396 -179
  47. package/dist/ProfileFlameGraph/FlameGraphArrow/useBatchedRendering.d.ts.map +1 -1
  48. package/dist/ProfileFlameGraph/FlameGraphArrow/useBatchedRendering.js +68 -50
  49. package/dist/ProfileFlameGraph/FlameGraphArrow/useMappingList.js +62 -38
  50. package/dist/ProfileFlameGraph/FlameGraphArrow/useNodeColor.js +14 -6
  51. package/dist/ProfileFlameGraph/FlameGraphArrow/useScrollViewport.js +124 -82
  52. package/dist/ProfileFlameGraph/FlameGraphArrow/useVisibleNodes.js +160 -98
  53. package/dist/ProfileFlameGraph/FlameGraphArrow/useZoom.js +232 -112
  54. package/dist/ProfileFlameGraph/FlameGraphArrow/utils.js +137 -114
  55. package/dist/ProfileFlameGraph/benchmarks/benchdata/populateData.js +85 -0
  56. package/dist/ProfileFlameGraph/index.js +324 -148
  57. package/dist/ProfileMetricsGraph/hooks/useQueryRange.js +140 -32
  58. package/dist/ProfileMetricsGraph/index.js +518 -259
  59. package/dist/ProfileSelector/CompareButton.js +132 -12
  60. package/dist/ProfileSelector/MetricsGraphSection.js +234 -67
  61. package/dist/ProfileSelector/index.d.ts.map +1 -1
  62. package/dist/ProfileSelector/index.js +730 -142
  63. package/dist/ProfileSelector/useAutoQuerySelector.js +249 -130
  64. package/dist/ProfileSource.js +230 -163
  65. package/dist/ProfileTypeSelector/index.js +214 -125
  66. package/dist/ProfileView/components/ActionButtons/GroupByDropdown.js +50 -4
  67. package/dist/ProfileView/components/ActionButtons/SortByDropdown.js +139 -33
  68. package/dist/ProfileView/components/ColorStackLegend.js +184 -55
  69. package/dist/ProfileView/components/DashboardItems/index.js +87 -28
  70. package/dist/ProfileView/components/DashboardLayout/index.js +108 -16
  71. package/dist/ProfileView/components/DiffLegend.js +172 -29
  72. package/dist/ProfileView/components/GroupByLabelsDropdown/index.js +199 -55
  73. package/dist/ProfileView/components/InvertCallStack/index.js +99 -10
  74. package/dist/ProfileView/components/ProfileFilters/filterPresets.js +260 -315
  75. package/dist/ProfileView/components/ProfileFilters/index.js +518 -215
  76. package/dist/ProfileView/components/ProfileFilters/useProfileFilters.js +370 -306
  77. package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.js +188 -120
  78. package/dist/ProfileView/components/ProfileHeader/index.js +105 -11
  79. package/dist/ProfileView/components/ShareButton/ResultBox.js +119 -16
  80. package/dist/ProfileView/components/ShareButton/index.js +352 -62
  81. package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.d.ts.map +1 -1
  82. package/dist/ProfileView/components/Toolbars/MultiLevelDropdown.js +675 -195
  83. package/dist/ProfileView/components/Toolbars/SwitchMenuItem.js +94 -7
  84. package/dist/ProfileView/components/Toolbars/TableColumnsDropdown.js +198 -157
  85. package/dist/ProfileView/components/Toolbars/index.js +441 -21
  86. package/dist/ProfileView/components/ViewSelector/Dropdown.js +233 -22
  87. package/dist/ProfileView/components/ViewSelector/index.js +211 -91
  88. package/dist/ProfileView/components/VisualizationContainer/index.d.ts.map +1 -1
  89. package/dist/ProfileView/components/VisualizationContainer/index.js +52 -7
  90. package/dist/ProfileView/components/VisualizationPanel.js +185 -8
  91. package/dist/ProfileView/context/DashboardContext.js +84 -28
  92. package/dist/ProfileView/context/ProfileViewContext.js +56 -15
  93. package/dist/ProfileView/hooks/useAutoSelectDimension.js +71 -41
  94. package/dist/ProfileView/hooks/useProfileMetadata.js +50 -18
  95. package/dist/ProfileView/hooks/useResetFlameGraphState.js +31 -10
  96. package/dist/ProfileView/hooks/useResetStateOnProfileTypeChange.js +72 -29
  97. package/dist/ProfileView/hooks/useResetStateOnSeriesChange.js +39 -13
  98. package/dist/ProfileView/hooks/useVisualizationState.js +262 -87
  99. package/dist/ProfileView/index.js +383 -45
  100. package/dist/ProfileView/types/visualization.js +1 -13
  101. package/dist/ProfileView/utils/colorUtils.js +8 -7
  102. package/dist/ProfileViewWithData.js +332 -237
  103. package/dist/QueryControls/index.js +418 -47
  104. package/dist/Sandwich/components/CalleesSection.js +54 -4
  105. package/dist/Sandwich/components/CallersSection.js +97 -27
  106. package/dist/Sandwich/components/TableSection.js +77 -4
  107. package/dist/Sandwich/index.js +125 -12
  108. package/dist/Sandwich/utils/processRowData.js +48 -39
  109. package/dist/SelectWithRefresh/index.js +102 -28
  110. package/dist/SimpleMatchers/Select.js +520 -187
  111. package/dist/SimpleMatchers/index.js +590 -288
  112. package/dist/SourceView/Highlighter.js +230 -70
  113. package/dist/SourceView/LineNo.js +72 -17
  114. package/dist/SourceView/index.js +177 -101
  115. package/dist/SourceView/lang-detector/ext-to-lang.json +798 -798
  116. package/dist/SourceView/lang-detector/index.js +28 -14
  117. package/dist/SourceView/useSelectedLineRange.js +97 -16
  118. package/dist/Table/ColorCell.js +42 -1
  119. package/dist/Table/ColumnsVisibility.js +114 -6
  120. package/dist/Table/MoreDropdown.js +121 -27
  121. package/dist/Table/TableContextMenu.js +150 -139
  122. package/dist/Table/TableContextMenuWrapper.js +59 -14
  123. package/dist/Table/hooks/useColorManagement.js +58 -16
  124. package/dist/Table/hooks/useTableConfiguration.d.ts.map +1 -1
  125. package/dist/Table/hooks/useTableConfiguration.js +331 -168
  126. package/dist/Table/index.js +222 -126
  127. package/dist/Table/utils/functions.js +169 -144
  128. package/dist/Table/utils/topAndBottomExpandedRowModel.js +69 -52
  129. package/dist/TimelineGuide/index.js +209 -16
  130. package/dist/TopTable/benchmarks/benchdata/populateData.js +91 -0
  131. package/dist/TopTable/index.js +340 -122
  132. package/dist/contexts/LabelsQueryProvider.js +94 -32
  133. package/dist/contexts/UnifiedLabelsContext.js +114 -49
  134. package/dist/contexts/utils.js +37 -15
  135. package/dist/hooks/useCompareModeMeta.js +157 -94
  136. package/dist/hooks/useLabels.js +295 -52
  137. package/dist/hooks/useQueryState.js +371 -330
  138. package/dist/index.js +21 -16
  139. package/dist/testdata/fg-diff.json +3750 -0
  140. package/dist/testdata/fg-simple.json +1879 -0
  141. package/dist/testdata/link_data.json +56 -0
  142. package/dist/testdata/tabular.json +30 -0
  143. package/dist/testdata/test_flamegraph.json +26846 -0
  144. package/dist/testdata/test_graph.json +53 -0
  145. package/dist/useDelayedLoader.js +32 -18
  146. package/dist/useGrpcQuery/index.js +71 -11
  147. package/dist/useHasProfileData.js +90 -12
  148. package/dist/useQuery.js +205 -64
  149. package/dist/useSumBy.d.ts.map +1 -1
  150. package/dist/useSumBy.js +294 -138
  151. package/dist/utils.js +62 -30
  152. package/package.json +9 -9
  153. package/src/GraphTooltipArrow/index.tsx +3 -0
  154. package/src/MatchersInput/SuggestionsList.test.tsx +70 -0
  155. package/src/MatchersInput/SuggestionsList.tsx +11 -10
  156. package/src/MatchersInput/index.tsx +1 -1
  157. package/src/MetricsGraph/MetricsTooltip/index.tsx +22 -34
  158. package/src/PreSelectedMatchers/index.tsx +3 -0
  159. package/src/ProfileFlameGraph/FlameGraphArrow/TextWithEllipsis.tsx +3 -0
  160. package/src/ProfileFlameGraph/FlameGraphArrow/TooltipContext.tsx +3 -0
  161. package/src/ProfileFlameGraph/FlameGraphArrow/ZoomControls.tsx +3 -0
  162. package/src/ProfileFlameGraph/FlameGraphArrow/useBatchedRendering.ts +3 -0
  163. package/src/ProfileSelector/index.tsx +30 -7
  164. package/src/ProfileView/components/Toolbars/MultiLevelDropdown.tsx +3 -0
  165. package/src/ProfileView/components/VisualizationContainer/index.tsx +3 -0
  166. package/src/Table/hooks/useTableConfiguration.tsx +7 -13
  167. package/src/useDelayedLoader.ts +10 -10
  168. package/src/useSumBy.ts +12 -18
  169. package/dist/ProfileView/components/ProfileFilters/useProfileFiltersUrlState.test.js +0 -541
  170. package/dist/hooks/useQueryState.test.js +0 -984
@@ -1,4 +1,3 @@
1
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
1
  // Copyright 2022 The Parca Authors
3
2
  // Licensed under the Apache License, Version 2.0 (the "License");
4
3
  // you may not use this file except in compliance with the License.
@@ -11,153 +10,225 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
11
10
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
11
  // See the License for the specific language governing permissions and
13
12
  // limitations under the License.
13
+
14
14
  import React, { useCallback, useMemo } from 'react';
15
15
  import cx from 'classnames';
16
16
  import { selectBinaries, useAppSelector } from '@parca/store';
17
17
  import 'react-contexify/dist/ReactContexify.css';
18
18
  import TextWithEllipsis from './TextWithEllipsis';
19
- import { FIELD_CUMULATIVE, FIELD_DEPTH, FIELD_DIFF, FIELD_FUNCTION_FILE_NAME, FIELD_FUNCTION_NAME, FIELD_MAPPING_FILE, FIELD_TIMESTAMP, FIELD_VALUE_OFFSET, } from './index';
19
+ import { FIELD_CUMULATIVE, FIELD_DEPTH, FIELD_DIFF, FIELD_FUNCTION_FILE_NAME, FIELD_FUNCTION_NAME, FIELD_MAPPING_FILE, FIELD_TIMESTAMP, FIELD_VALUE_OFFSET } from './index';
20
20
  import useNodeColor from './useNodeColor';
21
21
  import { arrowToString, boundsFromProfileSource, nodeLabel } from './utils';
22
- export const RowHeight = 26;
23
- export const flameRectStyles = {
24
- cursor: 'pointer',
25
- transition: 'opacity .15s linear',
22
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
23
+ export var RowHeight = 26;
24
+ export var flameRectStyles = {
25
+ cursor: 'pointer',
26
+ transition: 'opacity .15s linear'
26
27
  };
27
- export const fadedFlameRectStyles = {
28
- cursor: 'pointer',
29
- transition: 'opacity .15s linear',
30
- opacity: '0.5',
28
+ export var fadedFlameRectStyles = {
29
+ cursor: 'pointer',
30
+ transition: 'opacity .15s linear',
31
+ opacity: '0.5'
31
32
  };
32
- export const FlameNode = React.memo(function FlameNodeNoMemo({ table, row, colors, colorBy, height, totalWidth, darkMode, compareMode, colorForSimilarNodes, selectedRow, onClick, onContextMenu, hoveringRow, setHoveringRow, isFlameChart, profileSource, isRenderedAsFlamegraph = false, isInSandwichView = false, maxDepth = 0, effectiveDepth, tooltipId = 'default', }) {
33
- // Memoize column references - only changes when table changes
34
- const columns = useMemo(() => ({
35
- mapping: table.getChild(FIELD_MAPPING_FILE),
36
- functionName: table.getChild(FIELD_FUNCTION_NAME),
37
- cumulative: table.getChild(FIELD_CUMULATIVE),
38
- depth: table.getChild(FIELD_DEPTH),
39
- diff: table.getChild(FIELD_DIFF),
40
- filename: table.getChild(FIELD_FUNCTION_FILE_NAME),
41
- valueOffset: table.getChild(FIELD_VALUE_OFFSET),
42
- ts: table.getChild(FIELD_TIMESTAMP),
43
- }), [table]);
44
- // get the actual values from the columns
45
- const binaries = useAppSelector(selectBinaries);
46
- // Memoize row data extraction - only changes when table or row changes
47
- const rowData = useMemo(() => {
48
- const mappingFile = arrowToString(columns.mapping?.get(row));
49
- const functionName = arrowToString(columns.functionName?.get(row));
50
- const cumulative = columns.cumulative?.get(row) != null ? BigInt(columns.cumulative?.get(row)) : 0n;
51
- const diff = columns.diff?.get(row) != null ? BigInt(columns.diff?.get(row)) : null;
52
- const filename = arrowToString(columns.filename?.get(row));
53
- const depth = columns.depth?.get(row) ?? 0;
54
- const valueOffset = columns.valueOffset?.get(row) !== null && columns.valueOffset?.get(row) !== undefined
55
- ? BigInt(columns.valueOffset?.get(row))
56
- : 0n;
57
- return { mappingFile, functionName, cumulative, diff, filename, depth, valueOffset };
58
- }, [columns, row]);
59
- const { mappingFile, functionName, cumulative, diff, filename, depth, valueOffset } = rowData;
60
- const colorAttribute = colorBy === 'filename' ? filename : colorBy === 'binary' ? mappingFile : null;
61
- // Memoize hovering name lookup
62
- const hoveringName = useMemo(() => {
63
- return hoveringRow !== undefined ? arrowToString(columns.functionName?.get(hoveringRow)) : '';
64
- }, [columns.functionName, hoveringRow]);
65
- const shouldBeHighlighted = functionName != null && hoveringName != null && functionName === hoveringName;
66
- const colorResult = useNodeColor({
67
- isDarkMode: darkMode,
68
- compareMode,
69
- cumulative,
70
- diff,
71
- colorsMap: colors,
72
- colorAttribute,
73
- });
74
- const name = useMemo(() => {
75
- return row === 0 ? 'root' : nodeLabel(table, row, binaries.length > 1);
76
- }, [table, row, binaries]);
77
- // Memoize selection data - only changes when selectedRow changes
78
- const selectionData = useMemo(() => {
79
- const selectionOffset = columns.valueOffset?.get(selectedRow) !== null &&
80
- columns.valueOffset?.get(selectedRow) !== undefined
81
- ? BigInt(columns.valueOffset?.get(selectedRow))
82
- : 0n;
83
- const selectionCumulative = columns.cumulative?.get(selectedRow) !== null
84
- ? BigInt(columns.cumulative?.get(selectedRow))
85
- : 0n;
86
- const selectedDepth = columns.depth?.get(selectedRow);
87
- const total = columns.cumulative?.get(selectedRow);
88
- return { selectionOffset, selectionCumulative, selectedDepth, total };
89
- }, [columns, selectedRow]);
90
- const { selectionOffset, selectionCumulative, selectedDepth, total } = selectionData;
91
- // Memoize tsBounds - only changes when profileSource changes
92
- const tsBounds = useMemo(() => boundsFromProfileSource(profileSource), [profileSource]);
93
- // Memoize event handlers
94
- const onMouseEnter = useCallback(() => {
95
- setHoveringRow(row);
96
- window.dispatchEvent(new CustomEvent(`flame-tooltip-update-${tooltipId}`, {
97
- detail: { row },
98
- }));
99
- }, [setHoveringRow, row, tooltipId]);
100
- const onMouseLeave = useCallback(() => {
101
- setHoveringRow(undefined);
102
- window.dispatchEvent(new CustomEvent(`flame-tooltip-update-${tooltipId}`, {
103
- detail: { row: null },
104
- }));
105
- }, [setHoveringRow, tooltipId]);
106
- const handleContextMenu = useCallback((e) => {
107
- onContextMenu(e, row);
108
- }, [onContextMenu, row]);
109
- // Early returns - all hooks must be called before this point
110
- // Hide frames beyond effective depth limit
111
- if (effectiveDepth !== undefined && depth > effectiveDepth) {
112
- return _jsx(_Fragment, {});
113
- }
114
- if (valueOffset + cumulative <= selectionOffset ||
115
- valueOffset >= selectionOffset + selectionCumulative) {
116
- // If the end of the node is before the selection offset or the start of the node is after the selection offset + totalWidth, we don't render it.
117
- return _jsx(_Fragment, {});
118
- }
119
- if (row === 0 && (isFlameChart || isInSandwichView)) {
120
- // The root node is not rendered in the flame chart or sandwich view, so we return null.
121
- return _jsx(_Fragment, {});
33
+ export var FlameNode = /*#__PURE__*/React.memo(function FlameNodeNoMemo(_ref) {
34
+ var table = _ref.table,
35
+ row = _ref.row,
36
+ colors = _ref.colors,
37
+ colorBy = _ref.colorBy,
38
+ height = _ref.height,
39
+ totalWidth = _ref.totalWidth,
40
+ darkMode = _ref.darkMode,
41
+ compareMode = _ref.compareMode,
42
+ colorForSimilarNodes = _ref.colorForSimilarNodes,
43
+ selectedRow = _ref.selectedRow,
44
+ onClick = _ref.onClick,
45
+ onContextMenu = _ref.onContextMenu,
46
+ hoveringRow = _ref.hoveringRow,
47
+ setHoveringRow = _ref.setHoveringRow,
48
+ isFlameChart = _ref.isFlameChart,
49
+ profileSource = _ref.profileSource,
50
+ _ref$isRenderedAsFlam = _ref.isRenderedAsFlamegraph,
51
+ isRenderedAsFlamegraph = _ref$isRenderedAsFlam === void 0 ? false : _ref$isRenderedAsFlam,
52
+ _ref$isInSandwichView = _ref.isInSandwichView,
53
+ isInSandwichView = _ref$isInSandwichView === void 0 ? false : _ref$isInSandwichView,
54
+ _ref$maxDepth = _ref.maxDepth,
55
+ maxDepth = _ref$maxDepth === void 0 ? 0 : _ref$maxDepth,
56
+ effectiveDepth = _ref.effectiveDepth,
57
+ _ref$tooltipId = _ref.tooltipId,
58
+ tooltipId = _ref$tooltipId === void 0 ? 'default' : _ref$tooltipId;
59
+ // Memoize column references - only changes when table changes
60
+ var columns = useMemo(function () {
61
+ return {
62
+ mapping: table.getChild(FIELD_MAPPING_FILE),
63
+ functionName: table.getChild(FIELD_FUNCTION_NAME),
64
+ cumulative: table.getChild(FIELD_CUMULATIVE),
65
+ depth: table.getChild(FIELD_DEPTH),
66
+ diff: table.getChild(FIELD_DIFF),
67
+ filename: table.getChild(FIELD_FUNCTION_FILE_NAME),
68
+ valueOffset: table.getChild(FIELD_VALUE_OFFSET),
69
+ ts: table.getChild(FIELD_TIMESTAMP)
70
+ };
71
+ }, [table]);
72
+
73
+ // get the actual values from the columns
74
+ var binaries = useAppSelector(selectBinaries);
75
+
76
+ // Memoize row data extraction - only changes when table or row changes
77
+ var rowData = useMemo(function () {
78
+ var _columns$mapping, _columns$functionName, _columns$cumulative, _columns$cumulative2, _columns$diff, _columns$diff2, _columns$filename, _columns$depth$get, _columns$depth, _columns$valueOffset, _columns$valueOffset2, _columns$valueOffset3;
79
+ var mappingFile = arrowToString((_columns$mapping = columns.mapping) === null || _columns$mapping === void 0 ? void 0 : _columns$mapping.get(row));
80
+ var functionName = arrowToString((_columns$functionName = columns.functionName) === null || _columns$functionName === void 0 ? void 0 : _columns$functionName.get(row));
81
+ var cumulative = ((_columns$cumulative = columns.cumulative) === null || _columns$cumulative === void 0 ? void 0 : _columns$cumulative.get(row)) != null ? BigInt((_columns$cumulative2 = columns.cumulative) === null || _columns$cumulative2 === void 0 ? void 0 : _columns$cumulative2.get(row)) : 0n;
82
+ var diff = ((_columns$diff = columns.diff) === null || _columns$diff === void 0 ? void 0 : _columns$diff.get(row)) != null ? BigInt((_columns$diff2 = columns.diff) === null || _columns$diff2 === void 0 ? void 0 : _columns$diff2.get(row)) : null;
83
+ var filename = arrowToString((_columns$filename = columns.filename) === null || _columns$filename === void 0 ? void 0 : _columns$filename.get(row));
84
+ var depth = (_columns$depth$get = (_columns$depth = columns.depth) === null || _columns$depth === void 0 ? void 0 : _columns$depth.get(row)) !== null && _columns$depth$get !== void 0 ? _columns$depth$get : 0;
85
+ var valueOffset = ((_columns$valueOffset = columns.valueOffset) === null || _columns$valueOffset === void 0 ? void 0 : _columns$valueOffset.get(row)) !== null && ((_columns$valueOffset2 = columns.valueOffset) === null || _columns$valueOffset2 === void 0 ? void 0 : _columns$valueOffset2.get(row)) !== undefined ? BigInt((_columns$valueOffset3 = columns.valueOffset) === null || _columns$valueOffset3 === void 0 ? void 0 : _columns$valueOffset3.get(row)) : 0n;
86
+ return {
87
+ mappingFile: mappingFile,
88
+ functionName: functionName,
89
+ cumulative: cumulative,
90
+ diff: diff,
91
+ filename: filename,
92
+ depth: depth,
93
+ valueOffset: valueOffset
94
+ };
95
+ }, [columns, row]);
96
+ var mappingFile_0 = rowData.mappingFile,
97
+ functionName_0 = rowData.functionName,
98
+ cumulative_0 = rowData.cumulative,
99
+ diff_0 = rowData.diff,
100
+ filename_0 = rowData.filename,
101
+ depth_0 = rowData.depth,
102
+ valueOffset_0 = rowData.valueOffset;
103
+ var colorAttribute = colorBy === 'filename' ? filename_0 : colorBy === 'binary' ? mappingFile_0 : null;
104
+
105
+ // Memoize hovering name lookup
106
+ var hoveringName = useMemo(function () {
107
+ var _columns$functionName2;
108
+ return hoveringRow !== undefined ? arrowToString((_columns$functionName2 = columns.functionName) === null || _columns$functionName2 === void 0 ? void 0 : _columns$functionName2.get(hoveringRow)) : '';
109
+ }, [columns.functionName, hoveringRow]);
110
+ var shouldBeHighlighted = functionName_0 != null && hoveringName != null && functionName_0 === hoveringName;
111
+ var colorResult = useNodeColor({
112
+ isDarkMode: darkMode,
113
+ compareMode: compareMode,
114
+ cumulative: cumulative_0,
115
+ diff: diff_0,
116
+ colorsMap: colors,
117
+ colorAttribute: colorAttribute
118
+ });
119
+ var name = useMemo(function () {
120
+ return row === 0 ? 'root' : nodeLabel(table, row, binaries.length > 1);
121
+ }, [table, row, binaries]);
122
+
123
+ // Memoize selection data - only changes when selectedRow changes
124
+ var selectionData = useMemo(function () {
125
+ var _columns$valueOffset4, _columns$valueOffset5, _columns$valueOffset6, _columns$cumulative3, _columns$cumulative4, _columns$depth2, _columns$cumulative5;
126
+ var selectionOffset = ((_columns$valueOffset4 = columns.valueOffset) === null || _columns$valueOffset4 === void 0 ? void 0 : _columns$valueOffset4.get(selectedRow)) !== null && ((_columns$valueOffset5 = columns.valueOffset) === null || _columns$valueOffset5 === void 0 ? void 0 : _columns$valueOffset5.get(selectedRow)) !== undefined ? BigInt((_columns$valueOffset6 = columns.valueOffset) === null || _columns$valueOffset6 === void 0 ? void 0 : _columns$valueOffset6.get(selectedRow)) : 0n;
127
+ var selectionCumulative = ((_columns$cumulative3 = columns.cumulative) === null || _columns$cumulative3 === void 0 ? void 0 : _columns$cumulative3.get(selectedRow)) !== null ? BigInt((_columns$cumulative4 = columns.cumulative) === null || _columns$cumulative4 === void 0 ? void 0 : _columns$cumulative4.get(selectedRow)) : 0n;
128
+ var selectedDepth = (_columns$depth2 = columns.depth) === null || _columns$depth2 === void 0 ? void 0 : _columns$depth2.get(selectedRow);
129
+ var total = (_columns$cumulative5 = columns.cumulative) === null || _columns$cumulative5 === void 0 ? void 0 : _columns$cumulative5.get(selectedRow);
130
+ return {
131
+ selectionOffset: selectionOffset,
132
+ selectionCumulative: selectionCumulative,
133
+ selectedDepth: selectedDepth,
134
+ total: total
135
+ };
136
+ }, [columns, selectedRow]);
137
+ var selectionOffset_0 = selectionData.selectionOffset,
138
+ selectionCumulative_0 = selectionData.selectionCumulative,
139
+ selectedDepth_0 = selectionData.selectedDepth,
140
+ total_0 = selectionData.total;
141
+
142
+ // Memoize tsBounds - only changes when profileSource changes
143
+ var tsBounds = useMemo(function () {
144
+ return boundsFromProfileSource(profileSource);
145
+ }, [profileSource]);
146
+
147
+ // Memoize event handlers
148
+ var onMouseEnter = useCallback(function () {
149
+ setHoveringRow(row);
150
+ window.dispatchEvent(new CustomEvent("flame-tooltip-update-".concat(tooltipId), {
151
+ detail: {
152
+ row: row
153
+ }
154
+ }));
155
+ }, [setHoveringRow, row, tooltipId]);
156
+ var onMouseLeave = useCallback(function () {
157
+ setHoveringRow(undefined);
158
+ window.dispatchEvent(new CustomEvent("flame-tooltip-update-".concat(tooltipId), {
159
+ detail: {
160
+ row: null
161
+ }
162
+ }));
163
+ }, [setHoveringRow, tooltipId]);
164
+ var handleContextMenu = useCallback(function (e) {
165
+ onContextMenu(e, row);
166
+ }, [onContextMenu, row]);
167
+
168
+ // Early returns - all hooks must be called before this point
169
+ // Hide frames beyond effective depth limit
170
+ if (effectiveDepth !== undefined && depth_0 > effectiveDepth) {
171
+ return /*#__PURE__*/_jsx(_Fragment, {});
172
+ }
173
+ if (valueOffset_0 + cumulative_0 <= selectionOffset_0 || valueOffset_0 >= selectionOffset_0 + selectionCumulative_0) {
174
+ // If the end of the node is before the selection offset or the start of the node is after the selection offset + totalWidth, we don't render it.
175
+ return /*#__PURE__*/_jsx(_Fragment, {});
176
+ }
177
+ if (row === 0 && (isFlameChart || isInSandwichView)) {
178
+ // The root node is not rendered in the flame chart or sandwich view, so we return null.
179
+ return /*#__PURE__*/_jsx(_Fragment, {});
180
+ }
181
+
182
+ // Cumulative can be larger than total when a selection is made. All parents of the selection are likely larger, but we want to only show them as 100% in the graph.
183
+ var totalRatio = cumulative_0 > total_0 ? 1 : Number(cumulative_0) / Number(total_0);
184
+ var width = isFlameChart ? Number(cumulative_0) / (Number(tsBounds[1]) - Number(tsBounds[0])) * totalWidth : totalRatio * totalWidth;
185
+ if (width <= 1) {
186
+ return /*#__PURE__*/_jsx(_Fragment, {});
187
+ }
188
+ var styles = selectedDepth_0 !== undefined && selectedDepth_0 > depth_0 ? fadedFlameRectStyles : flameRectStyles;
189
+ var ts = columns.ts !== null ? Number(columns.ts.get(row)) : 0;
190
+ var x = isFlameChart && columns.ts !== null ? (ts - Number(tsBounds[0])) / (Number(tsBounds[1]) - Number(tsBounds[0])) * totalWidth : selectedDepth_0 > depth_0 ? 0 : (Number(valueOffset_0) - Number(selectionOffset_0)) / Number(total_0) * totalWidth;
191
+ var calculateY = function calculateY(isRenderedAsFlamegraph_0, isInSandwichView_0, isFlameChart_0, maxDepth_0, depth_1, height_0) {
192
+ if (isRenderedAsFlamegraph_0) {
193
+ return (maxDepth_0 - depth_1) * height_0; // Flamegraph is inverted
122
194
  }
123
- // Cumulative can be larger than total when a selection is made. All parents of the selection are likely larger, but we want to only show them as 100% in the graph.
124
- const totalRatio = cumulative > total ? 1 : Number(cumulative) / Number(total);
125
- const width = isFlameChart
126
- ? (Number(cumulative) / (Number(tsBounds[1]) - Number(tsBounds[0]))) * totalWidth
127
- : totalRatio * totalWidth;
128
- if (width <= 1) {
129
- return _jsx(_Fragment, {});
195
+ if (isFlameChart_0 || isInSandwichView_0) {
196
+ return (depth_1 - 1) * height_0;
130
197
  }
131
- const styles = selectedDepth !== undefined && selectedDepth > depth ? fadedFlameRectStyles : flameRectStyles;
132
- const ts = columns.ts !== null ? Number(columns.ts.get(row)) : 0;
133
- const x = isFlameChart && columns.ts !== null
134
- ? ((ts - Number(tsBounds[0])) / (Number(tsBounds[1]) - Number(tsBounds[0]))) * totalWidth
135
- : selectedDepth > depth
136
- ? 0
137
- : ((Number(valueOffset) - Number(selectionOffset)) / Number(total)) * totalWidth;
138
- const calculateY = (isRenderedAsFlamegraph, isInSandwichView, isFlameChart, maxDepth, depth, height) => {
139
- if (isRenderedAsFlamegraph) {
140
- return (maxDepth - depth) * height; // Flamegraph is inverted
141
- }
142
- if (isFlameChart || isInSandwichView) {
143
- return (depth - 1) * height;
144
- }
145
- return depth * height;
146
- };
147
- const y = calculateY(isRenderedAsFlamegraph, isInSandwichView, isFlameChart, effectiveDepth ?? maxDepth, depth, height);
148
- return (_jsx(_Fragment, { children: _jsxs("g", { id: row === 0 ? 'root-span' : undefined, transform: `translate(${x + 1}, ${y + 1})`, style: styles, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onClick: onClick, onContextMenu: handleContextMenu, children: [_jsx("rect", { x: 0, y: 0, width: width, height: height, style: {
149
- fill: colorResult,
150
- }, className: cx(shouldBeHighlighted
151
- ? `${colorForSimilarNodes} stroke-[3] [stroke-dasharray:6,4] [stroke-linecap:round] [stroke-linejoin:round] h-6`
152
- : 'stroke-white dark:stroke-gray-700') }), width > 5 && (_jsx("svg", { width: width - 5, height: height, children: _jsx(TextWithEllipsis, { text: name, x: 5, y: 15, width: width - 10 }) }))] }) }));
153
- }, (prevProps, nextProps) => {
154
- // Only re-render if the relevant props have changed
155
- return (prevProps.row === nextProps.row &&
156
- prevProps.selectedRow === nextProps.selectedRow &&
157
- prevProps.hoveringRow === nextProps.hoveringRow &&
158
- prevProps.totalWidth === nextProps.totalWidth &&
159
- prevProps.height === nextProps.height &&
160
- prevProps.effectiveDepth === nextProps.effectiveDepth &&
161
- prevProps.colorBy === nextProps.colorBy &&
162
- prevProps.colors === nextProps.colors);
163
- });
198
+ return depth_1 * height_0;
199
+ };
200
+ var y = calculateY(isRenderedAsFlamegraph, isInSandwichView, isFlameChart, effectiveDepth !== null && effectiveDepth !== void 0 ? effectiveDepth : maxDepth, depth_0, height);
201
+ return /*#__PURE__*/_jsx(_Fragment, {
202
+ children: /*#__PURE__*/_jsxs("g", {
203
+ id: row === 0 ? 'root-span' : undefined,
204
+ transform: "translate(".concat(x + 1, ", ").concat(y + 1, ")"),
205
+ style: styles,
206
+ onMouseEnter: onMouseEnter,
207
+ onMouseLeave: onMouseLeave,
208
+ onClick: onClick,
209
+ onContextMenu: handleContextMenu,
210
+ children: [/*#__PURE__*/_jsx("rect", {
211
+ x: 0,
212
+ y: 0,
213
+ width: width,
214
+ height: height,
215
+ style: {
216
+ fill: colorResult
217
+ },
218
+ className: cx(shouldBeHighlighted ? "".concat(colorForSimilarNodes, " stroke-[3] [stroke-dasharray:6,4] [stroke-linecap:round] [stroke-linejoin:round] h-6") : 'stroke-white dark:stroke-gray-700')
219
+ }), width > 5 && /*#__PURE__*/_jsx("svg", {
220
+ width: width - 5,
221
+ height: height,
222
+ children: /*#__PURE__*/_jsx(TextWithEllipsis, {
223
+ text: name,
224
+ x: 5,
225
+ y: 15,
226
+ width: width - 10 // Subtract padding from available width
227
+ })
228
+ })]
229
+ })
230
+ });
231
+ }, function (prevProps, nextProps) {
232
+ // Only re-render if the relevant props have changed
233
+ return prevProps.row === nextProps.row && prevProps.selectedRow === nextProps.selectedRow && prevProps.hoveringRow === nextProps.hoveringRow && prevProps.totalWidth === nextProps.totalWidth && prevProps.height === nextProps.height && prevProps.effectiveDepth === nextProps.effectiveDepth && prevProps.colorBy === nextProps.colorBy && prevProps.colors === nextProps.colors;
234
+ });
@@ -1,4 +1,10 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
4
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
7
+ import { c as _c } from "react-compiler-runtime";
2
8
  // Copyright 2022 The Parca Authors
3
9
  // Licensed under the Apache License, Version 2.0 (the "License");
4
10
  // you may not use this file except in compliance with the License.
@@ -11,46 +17,135 @@ import { jsx as _jsx } from "react/jsx-runtime";
11
17
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
18
  // See the License for the specific language governing permissions and
13
19
  // limitations under the License.
14
- import { memo, useEffect, useState } from 'react';
20
+
21
+ import React, { memo, useEffect, useState } from 'react';
15
22
  import GraphTooltipArrow from '../../GraphTooltipArrow';
16
23
  import GraphTooltipArrowContent from '../../GraphTooltipArrow/Content';
17
24
  import { DockedGraphTooltip } from '../../GraphTooltipArrow/DockedGraphTooltip';
18
25
  import { useTooltipContext } from './TooltipContext';
19
- export const MemoizedTooltip = memo(function MemoizedTooltip({ contextElement, dockedMetainfo, }) {
20
- const [tooltipRow, setTooltipRow] = useState(null);
21
- const { table, total, totalUnfiltered, profileType, unit, compareAbsolute, tooltipId } = useTooltipContext();
22
- // This component subscribes to tooltip updates through a callback
23
- // passed to the TooltipProvider, avoiding the need to lift state
24
- useEffect(() => {
25
- const handleTooltipUpdate = (event) => {
26
- setTooltipRow(event.detail.row);
27
- };
28
- const eventName = `flame-tooltip-update-${tooltipId}`;
29
- // Delay to ensure all DOM updates and React renders are complete
30
- // This fixes the race condition in sandwich view
31
- const timeoutId = setTimeout(() => {
32
- window.addEventListener(eventName, handleTooltipUpdate);
33
- }, 200);
34
- return () => {
35
- clearTimeout(timeoutId);
36
- window.removeEventListener(eventName, handleTooltipUpdate);
37
- };
38
- }, [tooltipId, table]);
39
- // Re-render when contextElement becomes available (fixes sandwich view timing issue)
40
- useEffect(() => {
41
- // Force re-render when contextElement transitions from null to valid element
42
- // This ensures tooltips work immediately in sandwich view
43
- }, [contextElement, tooltipId]);
44
- if (dockedMetainfo) {
45
- return (_jsx(DockedGraphTooltip, { table: table, row: tooltipRow, total: total, totalUnfiltered: totalUnfiltered, profileType: profileType, unit: unit, compareAbsolute: compareAbsolute }));
46
- }
47
- if (tooltipRow === null) {
48
- return null;
49
- }
50
- // Fix for sandwich view tooltip issue: Don't render tooltip if contextElement is null
51
- // This happens when the SVG ref isn't ready yet during initial sandwich view render
52
- if (contextElement === null) {
53
- return null;
26
+ import { jsx as _jsx } from "react/jsx-runtime";
27
+ export var MemoizedTooltip = /*#__PURE__*/memo(function MemoizedTooltip(t0) {
28
+ var $ = _c(27);
29
+ var contextElement = t0.contextElement,
30
+ dockedMetainfo = t0.dockedMetainfo;
31
+ var _useState = useState(null),
32
+ _useState2 = _slicedToArray(_useState, 2),
33
+ tooltipRow = _useState2[0],
34
+ setTooltipRow = _useState2[1];
35
+ var _useTooltipContext = useTooltipContext(),
36
+ table = _useTooltipContext.table,
37
+ total = _useTooltipContext.total,
38
+ totalUnfiltered = _useTooltipContext.totalUnfiltered,
39
+ profileType = _useTooltipContext.profileType,
40
+ unit = _useTooltipContext.unit,
41
+ compareAbsolute = _useTooltipContext.compareAbsolute,
42
+ tooltipId = _useTooltipContext.tooltipId;
43
+ var t1;
44
+ if ($[0] !== tooltipId) {
45
+ t1 = function t1() {
46
+ var handleTooltipUpdate = function handleTooltipUpdate(event) {
47
+ setTooltipRow(event.detail.row);
48
+ };
49
+ var eventName = "flame-tooltip-update-".concat(tooltipId);
50
+ var timeoutId = setTimeout(function () {
51
+ window.addEventListener(eventName, handleTooltipUpdate);
52
+ }, 200);
53
+ return function () {
54
+ clearTimeout(timeoutId);
55
+ window.removeEventListener(eventName, handleTooltipUpdate);
56
+ };
57
+ };
58
+ $[0] = tooltipId;
59
+ $[1] = t1;
60
+ } else {
61
+ t1 = $[1];
62
+ }
63
+ var t2;
64
+ if ($[2] !== table || $[3] !== tooltipId) {
65
+ t2 = [tooltipId, table];
66
+ $[2] = table;
67
+ $[3] = tooltipId;
68
+ $[4] = t2;
69
+ } else {
70
+ t2 = $[4];
71
+ }
72
+ useEffect(t1, t2);
73
+ var t3;
74
+ if ($[5] !== contextElement || $[6] !== tooltipId) {
75
+ t3 = [contextElement, tooltipId];
76
+ $[5] = contextElement;
77
+ $[6] = tooltipId;
78
+ $[7] = t3;
79
+ } else {
80
+ t3 = $[7];
81
+ }
82
+ useEffect(_temp, t3);
83
+ if (dockedMetainfo) {
84
+ var _t;
85
+ if ($[8] !== compareAbsolute || $[9] !== profileType || $[10] !== table || $[11] !== tooltipRow || $[12] !== total || $[13] !== totalUnfiltered || $[14] !== unit) {
86
+ _t = /*#__PURE__*/_jsx(DockedGraphTooltip, {
87
+ table: table,
88
+ row: tooltipRow,
89
+ total: total,
90
+ totalUnfiltered: totalUnfiltered,
91
+ profileType: profileType,
92
+ unit: unit,
93
+ compareAbsolute: compareAbsolute
94
+ });
95
+ $[8] = compareAbsolute;
96
+ $[9] = profileType;
97
+ $[10] = table;
98
+ $[11] = tooltipRow;
99
+ $[12] = total;
100
+ $[13] = totalUnfiltered;
101
+ $[14] = unit;
102
+ $[15] = _t;
103
+ } else {
104
+ _t = $[15];
54
105
  }
55
- return (_jsx(GraphTooltipArrow, { contextElement: contextElement, children: _jsx(GraphTooltipArrowContent, { table: table, row: tooltipRow, isFixed: false, total: total, totalUnfiltered: totalUnfiltered, profileType: profileType, unit: unit, compareAbsolute: compareAbsolute }) }));
106
+ return _t;
107
+ }
108
+ if (tooltipRow === null) {
109
+ return null;
110
+ }
111
+ if (contextElement === null) {
112
+ return null;
113
+ }
114
+ var t4;
115
+ if ($[16] !== compareAbsolute || $[17] !== profileType || $[18] !== table || $[19] !== tooltipRow || $[20] !== total || $[21] !== totalUnfiltered || $[22] !== unit) {
116
+ t4 = /*#__PURE__*/_jsx(GraphTooltipArrowContent, {
117
+ table: table,
118
+ row: tooltipRow,
119
+ isFixed: false,
120
+ total: total,
121
+ totalUnfiltered: totalUnfiltered,
122
+ profileType: profileType,
123
+ unit: unit,
124
+ compareAbsolute: compareAbsolute
125
+ });
126
+ $[16] = compareAbsolute;
127
+ $[17] = profileType;
128
+ $[18] = table;
129
+ $[19] = tooltipRow;
130
+ $[20] = total;
131
+ $[21] = totalUnfiltered;
132
+ $[22] = unit;
133
+ $[23] = t4;
134
+ } else {
135
+ t4 = $[23];
136
+ }
137
+ var t5;
138
+ if ($[24] !== contextElement || $[25] !== t4) {
139
+ t5 = /*#__PURE__*/_jsx(GraphTooltipArrow, {
140
+ contextElement: contextElement,
141
+ children: t4
142
+ });
143
+ $[24] = contextElement;
144
+ $[25] = t4;
145
+ $[26] = t5;
146
+ } else {
147
+ t5 = $[26];
148
+ }
149
+ return t5;
56
150
  });
151
+ function _temp() {}