@parca/profile 0.16.184 → 0.16.185

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 (59) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/Callgraph/constants.js +2 -2
  3. package/dist/Callgraph/index.js +35 -45
  4. package/dist/Callgraph/mockData/index.js +28 -11
  5. package/dist/Callgraph/utils.js +51 -58
  6. package/dist/GraphTooltip/ExpandOnHoverValue.js +2 -14
  7. package/dist/GraphTooltip/index.d.ts +5 -5
  8. package/dist/GraphTooltip/index.js +96 -122
  9. package/dist/MatchersInput/SuggestionItem.js +5 -17
  10. package/dist/MatchersInput/SuggestionsList.js +29 -53
  11. package/dist/MatchersInput/index.js +58 -74
  12. package/dist/MetricsCircle/index.js +2 -16
  13. package/dist/MetricsGraph/MetricsTooltip/index.js +27 -53
  14. package/dist/MetricsGraph/index.js +79 -98
  15. package/dist/MetricsSeries/index.js +4 -19
  16. package/dist/ProfileExplorer/ProfileExplorerCompare.js +4 -16
  17. package/dist/ProfileExplorer/ProfileExplorerSingle.js +2 -14
  18. package/dist/ProfileExplorer/index.js +129 -88
  19. package/dist/ProfileIcicleGraph/IcicleGraph/ColorStackLegend.js +15 -31
  20. package/dist/ProfileIcicleGraph/IcicleGraph/IcicleGraphNodes.d.ts +4 -4
  21. package/dist/ProfileIcicleGraph/IcicleGraph/IcicleGraphNodes.js +38 -54
  22. package/dist/ProfileIcicleGraph/IcicleGraph/index.d.ts +2 -2
  23. package/dist/ProfileIcicleGraph/IcicleGraph/index.js +15 -31
  24. package/dist/ProfileIcicleGraph/IcicleGraph/useColoredGraph.js +22 -26
  25. package/dist/ProfileIcicleGraph/IcicleGraph/useNodeColor.js +8 -9
  26. package/dist/ProfileIcicleGraph/IcicleGraph/utils.js +18 -20
  27. package/dist/ProfileIcicleGraph/index.d.ts +2 -2
  28. package/dist/ProfileIcicleGraph/index.js +18 -30
  29. package/dist/ProfileMetricsGraph/index.js +36 -88
  30. package/dist/ProfileSelector/CompareButton.js +8 -20
  31. package/dist/ProfileSelector/index.js +69 -69
  32. package/dist/ProfileSource.js +56 -65
  33. package/dist/ProfileTypeSelector/index.js +14 -28
  34. package/dist/ProfileView/FilterByFunctionButton.js +6 -7
  35. package/dist/ProfileView/ViewSelector.js +18 -31
  36. package/dist/ProfileView/VisualizationPanel.js +4 -16
  37. package/dist/ProfileView/index.js +72 -152
  38. package/dist/ProfileViewWithData.js +50 -101
  39. package/dist/TopTable/index.js +55 -63
  40. package/dist/components/DiffLegend.js +16 -28
  41. package/dist/components/ProfileShareButton/ResultBox.js +7 -21
  42. package/dist/components/ProfileShareButton/index.js +31 -90
  43. package/dist/useDelayedLoader.js +7 -8
  44. package/dist/useGrpcQuery/index.js +6 -48
  45. package/dist/useQuery.js +14 -58
  46. package/dist/utils.d.ts +1 -1
  47. package/dist/utils.js +16 -68
  48. package/package.json +6 -6
  49. package/src/Callgraph/index.tsx +3 -3
  50. package/src/Callgraph/utils.ts +1 -1
  51. package/src/GraphTooltip/index.tsx +17 -17
  52. package/src/MetricsGraph/index.tsx +3 -3
  53. package/src/ProfileIcicleGraph/IcicleGraph/IcicleGraphNodes.tsx +9 -10
  54. package/src/ProfileIcicleGraph/IcicleGraph/index.tsx +4 -8
  55. package/src/ProfileIcicleGraph/IcicleGraph/useNodeColor.ts +2 -2
  56. package/src/ProfileIcicleGraph/index.tsx +8 -8
  57. package/src/ProfileView/index.tsx +2 -2
  58. package/src/TopTable/index.tsx +3 -3
  59. package/src/utils.ts +2 -2
@@ -1,14 +1,3 @@
1
- var __assign = (this && this.__assign) || function () {
2
- __assign = Object.assign || function(t) {
3
- for (var s, i = 1, n = arguments.length; i < n; i++) {
4
- s = arguments[i];
5
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
- t[p] = s[p];
7
- }
8
- return t;
9
- };
10
- return __assign.apply(this, arguments);
11
- };
12
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
2
  // Copyright 2022 The Parca Authors
14
3
  // Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,12 +17,11 @@ import cx from 'classnames';
28
17
  import { IconButton } from '@parca/components';
29
18
  import { CloseIcon } from '@parca/icons';
30
19
  import ViewSelector from './ViewSelector';
31
- export var VisualizationPanel = React.memo(function VisualizationPanel(_a) {
32
- var dashboardItem = _a.dashboardItem, index = _a.index, isMultiPanelView = _a.isMultiPanelView, handleClosePanel = _a.handleClosePanel, navigateTo = _a.navigateTo, dragHandleProps = _a.dragHandleProps, getDashboardItemByType = _a.getDashboardItemByType;
33
- var _b = useState(_jsx(_Fragment, {})), actionButtons = _b[0], setActionButtons = _b[1];
34
- return (_jsxs(_Fragment, { children: [_jsxs("div", __assign({ className: "flex w-full justify-end gap-2 pb-2" }, { children: [_jsxs("div", __assign({ className: "flex w-full items-center justify-between" }, { children: [_jsxs("div", __assign({ className: "flex" }, { children: [_jsx("div", __assign({ className: cx(isMultiPanelView ? 'visible' : 'invisible', 'flex items-center') }, dragHandleProps, { children: _jsx(Icon, { className: "text-xl", icon: "material-symbols:drag-indicator" }) })), _jsx(_Fragment, { children: actionButtons })] })), _jsx(ViewSelector, { defaultValue: dashboardItem, navigateTo: navigateTo, position: index })] })), isMultiPanelView && (_jsx(IconButton, { onClick: function () { return handleClosePanel(dashboardItem); }, icon: _jsx(CloseIcon, {}) }))] })), getDashboardItemByType({
20
+ export const VisualizationPanel = React.memo(function VisualizationPanel({ dashboardItem, index, isMultiPanelView, handleClosePanel, navigateTo, dragHandleProps, getDashboardItemByType, }) {
21
+ const [actionButtons, setActionButtons] = useState(_jsx(_Fragment, {}));
22
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex w-full justify-end gap-2 pb-2", children: [_jsxs("div", { className: "flex w-full items-center justify-between", children: [_jsxs("div", { className: "flex", children: [_jsx("div", { className: cx(isMultiPanelView ? 'visible' : 'invisible', 'flex items-center'), ...dragHandleProps, children: _jsx(Icon, { className: "text-xl", icon: "material-symbols:drag-indicator" }) }), _jsx(_Fragment, { children: actionButtons })] }), _jsx(ViewSelector, { defaultValue: dashboardItem, navigateTo: navigateTo, position: index })] }), isMultiPanelView && (_jsx(IconButton, { onClick: () => handleClosePanel(dashboardItem), icon: _jsx(CloseIcon, {}) }))] }), getDashboardItemByType({
35
23
  type: dashboardItem,
36
24
  isHalfScreen: isMultiPanelView,
37
- setActionButtons: setActionButtons,
25
+ setActionButtons,
38
26
  })] }));
39
27
  });
@@ -1,59 +1,3 @@
1
- var __assign = (this && this.__assign) || function () {
2
- __assign = Object.assign || function(t) {
3
- for (var s, i = 1, n = arguments.length; i < n; i++) {
4
- s = arguments[i];
5
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
- t[p] = s[p];
7
- }
8
- return t;
9
- };
10
- return __assign.apply(this, arguments);
11
- };
12
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
- return new (P || (P = Promise))(function (resolve, reject) {
15
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
- step((generator = generator.apply(thisArg, _arguments || [])).next());
19
- });
20
- };
21
- var __generator = (this && this.__generator) || function (thisArg, body) {
22
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
- function verb(n) { return function (v) { return step([n, v]); }; }
25
- function step(op) {
26
- if (f) throw new TypeError("Generator is already executing.");
27
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
- if (y = 0, t) op = [op[0] & 2, t.value];
30
- switch (op[0]) {
31
- case 0: case 1: t = op; break;
32
- case 4: _.label++; return { value: op[1], done: false };
33
- case 5: _.label++; y = op[1]; op = [0]; continue;
34
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
- default:
36
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
- if (t[2]) _.ops.pop();
41
- _.trys.pop(); continue;
42
- }
43
- op = body.call(thisArg, _);
44
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
- }
47
- };
48
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
49
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
50
- if (ar || !(i in from)) {
51
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
52
- ar[i] = from[i];
53
- }
54
- }
55
- return to.concat(ar || Array.prototype.slice.call(from));
56
- };
57
1
  import { createElement as _createElement } from "react";
58
2
  import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
59
3
  // Copyright 2022 The Parca Authors
@@ -90,130 +34,105 @@ function arrayEquals(a, b) {
90
34
  return (Array.isArray(a) &&
91
35
  Array.isArray(b) &&
92
36
  a.length === b.length &&
93
- a.every(function (val, index) { return val === b[index]; }));
37
+ a.every((val, index) => val === b[index]));
94
38
  }
95
- export var ProfileView = function (_a) {
96
- var total = _a.total, filtered = _a.filtered, flamegraphData = _a.flamegraphData, topTableData = _a.topTableData, callgraphData = _a.callgraphData, sampleUnit = _a.sampleUnit, profileSource = _a.profileSource, queryClient = _a.queryClient, navigateTo = _a.navigateTo, onDownloadPProf = _a.onDownloadPProf, onFlamegraphContainerResize = _a.onFlamegraphContainerResize, pprofDownloading = _a.pprofDownloading;
97
- var _b = useContainerDimensions(), ref = _b.ref, dimensions = _b.dimensions;
98
- var _c = useState([]), curPath = _c[0], setCurPath = _c[1];
99
- var _d = useURLState({
39
+ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, callgraphData, sampleUnit, profileSource, queryClient, navigateTo, onDownloadPProf, onFlamegraphContainerResize, pprofDownloading, }) => {
40
+ const { ref, dimensions } = useContainerDimensions();
41
+ const [curPath, setCurPath] = useState([]);
42
+ const [rawDashboardItems, setDashboardItems] = useURLState({
100
43
  param: 'dashboard_items',
101
- navigateTo: navigateTo,
102
- }), rawDashboardItems = _d[0], setDashboardItems = _d[1];
103
- var _e = useState(false), graphvizLoaded = _e[0], setGraphvizLoaded = _e[1];
104
- var _f = useState(undefined), callgraphSVG = _f[0], setCallgraphSVG = _f[1];
105
- var currentSearchString = useURLState({ param: 'search_string' })[0];
106
- var dashboardItems = useMemo(function () {
44
+ navigateTo,
45
+ });
46
+ const [graphvizLoaded, setGraphvizLoaded] = useState(false);
47
+ const [callgraphSVG, setCallgraphSVG] = useState(undefined);
48
+ const [currentSearchString] = useURLState({ param: 'search_string' });
49
+ const dashboardItems = useMemo(() => {
107
50
  if (rawDashboardItems !== undefined) {
108
51
  return rawDashboardItems;
109
52
  }
110
53
  return ['icicle'];
111
54
  }, [rawDashboardItems]);
112
- var isDarkMode = useAppSelector(selectDarkMode);
113
- var isMultiPanelView = dashboardItems.length > 1;
114
- var _g = useParcaContext(), loader = _g.loader, perf = _g.perf;
115
- useEffect(function () {
55
+ const isDarkMode = useAppSelector(selectDarkMode);
56
+ const isMultiPanelView = dashboardItems.length > 1;
57
+ const { loader, perf } = useParcaContext();
58
+ useEffect(() => {
116
59
  // Reset the current path when the profile source changes
117
60
  setCurPath([]);
118
61
  }, [profileSource]);
119
- useEffect(function () {
120
- function loadGraphviz() {
121
- return __awaiter(this, void 0, void 0, function () {
122
- return __generator(this, function (_a) {
123
- switch (_a.label) {
124
- case 0: return [4 /*yield*/, graphviz.loadWASM()];
125
- case 1:
126
- _a.sent();
127
- setGraphvizLoaded(true);
128
- return [2 /*return*/];
129
- }
130
- });
131
- });
62
+ useEffect(() => {
63
+ async function loadGraphviz() {
64
+ await graphviz.loadWASM();
65
+ setGraphvizLoaded(true);
132
66
  }
133
67
  void loadGraphviz();
134
68
  }, []);
135
- var isLoading = useMemo(function () {
69
+ const isLoading = useMemo(() => {
136
70
  if (dashboardItems.includes('icicle')) {
137
- return Boolean(flamegraphData === null || flamegraphData === void 0 ? void 0 : flamegraphData.loading);
71
+ return Boolean(flamegraphData?.loading);
138
72
  }
139
73
  if (dashboardItems.includes('callgraph')) {
140
- return Boolean(callgraphData === null || callgraphData === void 0 ? void 0 : callgraphData.loading) || Boolean(callgraphSVG === undefined);
74
+ return Boolean(callgraphData?.loading) || Boolean(callgraphSVG === undefined);
141
75
  }
142
76
  if (dashboardItems.includes('table')) {
143
- return Boolean(topTableData === null || topTableData === void 0 ? void 0 : topTableData.loading);
77
+ return Boolean(topTableData?.loading);
144
78
  }
145
79
  return false;
146
80
  }, [
147
81
  dashboardItems,
148
- callgraphData === null || callgraphData === void 0 ? void 0 : callgraphData.loading,
149
- flamegraphData === null || flamegraphData === void 0 ? void 0 : flamegraphData.loading,
150
- topTableData === null || topTableData === void 0 ? void 0 : topTableData.loading,
82
+ callgraphData?.loading,
83
+ flamegraphData?.loading,
84
+ topTableData?.loading,
151
85
  callgraphSVG,
152
86
  ]);
153
- var isLoaderVisible = useDelayedLoader(isLoading);
154
- var maxColor = getNewSpanColor(isDarkMode);
155
- var minColor = scaleLinear([isDarkMode ? 'black' : 'white', maxColor])(0.3);
156
- var colorRange = [minColor, maxColor];
87
+ const isLoaderVisible = useDelayedLoader(isLoading);
88
+ const maxColor = getNewSpanColor(isDarkMode);
89
+ const minColor = scaleLinear([isDarkMode ? 'black' : 'white', maxColor])(0.3);
90
+ const colorRange = [minColor, maxColor];
157
91
  // Note: If we want to further optimize the experience, we could try to load the graphviz layout in the ProfileViewWithData layer
158
92
  // and pass it down to the ProfileView. This would allow us to load the layout in parallel with the flamegraph data.
159
93
  // However, the layout calculation is dependent on the width and color range of the graph container, which is why it is done at this level
160
- useEffect(function () {
161
- function loadCallgraphSVG(graph, width, colorRange) {
162
- return __awaiter(this, void 0, void 0, function () {
163
- var dataAsDot, svgGraph;
164
- return __generator(this, function (_a) {
165
- switch (_a.label) {
166
- case 0: return [4 /*yield*/, setCallgraphSVG(undefined)];
167
- case 1:
168
- _a.sent();
169
- return [4 /*yield*/, jsonToDot({
170
- graph: graph,
171
- width: width,
172
- colorRange: colorRange,
173
- })];
174
- case 2:
175
- dataAsDot = _a.sent();
176
- return [4 /*yield*/, graphviz.layout(dataAsDot, 'svg', 'dot')];
177
- case 3:
178
- svgGraph = _a.sent();
179
- return [4 /*yield*/, setCallgraphSVG(svgGraph)];
180
- case 4:
181
- _a.sent();
182
- return [2 /*return*/];
183
- }
184
- });
94
+ useEffect(() => {
95
+ async function loadCallgraphSVG(graph, width, colorRange) {
96
+ await setCallgraphSVG(undefined);
97
+ // Translate JSON to 'dot' graph string
98
+ const dataAsDot = await jsonToDot({
99
+ graph,
100
+ width,
101
+ colorRange,
185
102
  });
103
+ // Use Graphviz-WASM to translate the 'dot' graph to a 'JSON' graph
104
+ const svgGraph = await graphviz.layout(dataAsDot, 'svg', 'dot');
105
+ await setCallgraphSVG(svgGraph);
186
106
  }
187
107
  if (graphvizLoaded &&
188
- (callgraphData === null || callgraphData === void 0 ? void 0 : callgraphData.data) !== null &&
189
- (callgraphData === null || callgraphData === void 0 ? void 0 : callgraphData.data) !== undefined &&
190
- (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) !== undefined) {
191
- void loadCallgraphSVG(callgraphData === null || callgraphData === void 0 ? void 0 : callgraphData.data, dimensions === null || dimensions === void 0 ? void 0 : dimensions.width, colorRange);
108
+ callgraphData?.data !== null &&
109
+ callgraphData?.data !== undefined &&
110
+ dimensions?.width !== undefined) {
111
+ void loadCallgraphSVG(callgraphData?.data, dimensions?.width, colorRange);
192
112
  }
193
113
  // eslint-disable-next-line react-hooks/exhaustive-deps
194
- }, [graphvizLoaded, callgraphData === null || callgraphData === void 0 ? void 0 : callgraphData.data]);
195
- if ((flamegraphData === null || flamegraphData === void 0 ? void 0 : flamegraphData.error) !== null) {
196
- console.error('Error: ', flamegraphData === null || flamegraphData === void 0 ? void 0 : flamegraphData.error);
197
- return (_jsxs("div", __assign({ className: "flex justify-center p-10" }, { children: ["An error occurred: ", flamegraphData === null || flamegraphData === void 0 ? void 0 : flamegraphData.error.message] })));
114
+ }, [graphvizLoaded, callgraphData?.data]);
115
+ if (flamegraphData?.error !== null) {
116
+ console.error('Error: ', flamegraphData?.error);
117
+ return (_jsxs("div", { className: "flex justify-center p-10", children: ["An error occurred: ", flamegraphData?.error.message] }));
198
118
  }
199
- var setNewCurPath = function (path) {
119
+ const setNewCurPath = (path) => {
200
120
  if (!arrayEquals(curPath, path)) {
201
121
  setCurPath(path);
202
122
  }
203
123
  };
204
- var getDashboardItemByType = function (_a) {
205
- var type = _a.type, isHalfScreen = _a.isHalfScreen, setActionButtons = _a.setActionButtons;
124
+ const getDashboardItemByType = ({ type, isHalfScreen, setActionButtons, }) => {
206
125
  switch (type) {
207
126
  case 'icicle': {
208
- return (flamegraphData === null || flamegraphData === void 0 ? void 0 : flamegraphData.data) != null ? (_jsx(ConditionalWrapper, __assign({ condition: (perf === null || perf === void 0 ? void 0 : perf.onRender) != null, WrapperComponent: Profiler, wrapperProps: {
127
+ return flamegraphData?.data != null ? (_jsx(ConditionalWrapper, { condition: perf?.onRender != null, WrapperComponent: Profiler, wrapperProps: {
209
128
  id: 'icicleGraph',
210
- onRender: perf === null || perf === void 0 ? void 0 : perf.onRender,
211
- } }, { children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, graph: flamegraphData.data, total: Number(total), filtered: Number(filtered), sampleUnit: sampleUnit, onContainerResize: onFlamegraphContainerResize, navigateTo: navigateTo, loading: flamegraphData.loading, setActionButtons: setActionButtons }) }))) : (_jsx(_Fragment, { children: " " }));
129
+ onRender: perf?.onRender,
130
+ }, children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, graph: flamegraphData.data, total: total, filtered: filtered, sampleUnit: sampleUnit, onContainerResize: onFlamegraphContainerResize, navigateTo: navigateTo, loading: flamegraphData.loading, setActionButtons: setActionButtons }) })) : (_jsx(_Fragment, { children: " " }));
212
131
  }
213
132
  case 'callgraph': {
214
- return (callgraphData === null || callgraphData === void 0 ? void 0 : callgraphData.data) !== undefined &&
133
+ return callgraphData?.data !== undefined &&
215
134
  callgraphSVG !== undefined &&
216
- (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) !== undefined ? (_jsx(Callgraph, { data: callgraphData.data, svgString: callgraphSVG, sampleUnit: sampleUnit, width: isHalfScreen ? (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) / 2 : dimensions === null || dimensions === void 0 ? void 0 : dimensions.width })) : (_jsx(_Fragment, {}));
135
+ dimensions?.width !== undefined ? (_jsx(Callgraph, { data: callgraphData.data, svgString: callgraphSVG, sampleUnit: sampleUnit, width: isHalfScreen ? dimensions?.width / 2 : dimensions?.width })) : (_jsx(_Fragment, {}));
217
136
  }
218
137
  case 'table': {
219
138
  return topTableData != null ? (_jsx(TopTable, { loading: topTableData.loading, data: topTableData.data, sampleUnit: sampleUnit, navigateTo: navigateTo, setActionButtons: setActionButtons, currentSearchString: currentSearchString })) : (_jsx(_Fragment, {}));
@@ -223,27 +142,28 @@ export var ProfileView = function (_a) {
223
142
  }
224
143
  }
225
144
  };
226
- var handleClosePanel = function (visualizationType) {
227
- var newDashboardItems = dashboardItems.filter(function (item) { return item !== visualizationType; });
145
+ const handleClosePanel = (visualizationType) => {
146
+ const newDashboardItems = dashboardItems.filter(item => item !== visualizationType);
228
147
  setDashboardItems(newDashboardItems);
229
148
  };
230
- var onDragEnd = function (result) {
231
- var destination = result.destination, source = result.source, draggableId = result.draggableId;
232
- if (Boolean(destination) && (destination === null || destination === void 0 ? void 0 : destination.index) !== source.index) {
233
- var targetItem_1 = draggableId;
234
- var otherItems = dashboardItems.filter(function (item) { return item !== targetItem_1; });
235
- var newDashboardItems = destination.index < source.index
236
- ? __spreadArray([targetItem_1], otherItems, true) : __spreadArray(__spreadArray([], otherItems, true), [targetItem_1], false);
149
+ const onDragEnd = (result) => {
150
+ const { destination, source, draggableId } = result;
151
+ if (Boolean(destination) && destination?.index !== source.index) {
152
+ const targetItem = draggableId;
153
+ const otherItems = dashboardItems.filter(item => item !== targetItem);
154
+ const newDashboardItems = destination.index < source.index
155
+ ? [targetItem, ...otherItems]
156
+ : [...otherItems, targetItem];
237
157
  setDashboardItems(newDashboardItems);
238
158
  }
239
159
  };
240
- return (_jsx(KeyDownProvider, { children: _jsx("div", __assign({ className: "py-3" }, { children: _jsx(Card, { children: _jsxs(Card.Body, { children: [_jsxs("div", __assign({ className: "flex w-full py-3" }, { children: [_jsxs("div", __assign({ className: "flex space-x-4 lg:w-1/2" }, { children: [_jsxs("div", __assign({ className: "flex space-x-1" }, { children: [profileSource !== undefined && queryClient !== undefined ? (_jsx(ProfileShareButton, { queryRequest: profileSource.QueryRequest(), queryClient: queryClient })) : null, _jsx(Button, __assign({ color: "neutral", onClick: function (e) {
160
+ return (_jsx(KeyDownProvider, { children: _jsx("div", { className: "py-3", children: _jsx(Card, { children: _jsxs(Card.Body, { children: [_jsxs("div", { className: "flex w-full py-3", children: [_jsxs("div", { className: "flex space-x-4 lg:w-1/2", children: [_jsxs("div", { className: "flex space-x-1", children: [profileSource !== undefined && queryClient !== undefined ? (_jsx(ProfileShareButton, { queryRequest: profileSource.QueryRequest(), queryClient: queryClient })) : null, _jsx(Button, { color: "neutral", onClick: e => {
241
161
  e.preventDefault();
242
162
  onDownloadPProf();
243
- }, disabled: pprofDownloading }, { children: pprofDownloading != null && pprofDownloading
163
+ }, disabled: pprofDownloading, children: pprofDownloading != null && pprofDownloading
244
164
  ? 'Downloading'
245
- : 'Download pprof' }))] })), _jsx(FilterByFunctionButton, { navigateTo: navigateTo })] })), _jsx("div", __assign({ className: "ml-auto flex gap-2" }, { children: _jsx(ViewSelector, { defaultValue: "", navigateTo: navigateTo, position: -1, placeholderText: "Add panel...", primary: true, addView: true, disabled: isMultiPanelView || dashboardItems.length < 1 }) }))] })), _jsx("div", __assign({ className: "w-full", ref: ref }, { children: isLoaderVisible ? (_jsx(_Fragment, { children: loader })) : (_jsx(DragDropContext, __assign({ onDragEnd: onDragEnd }, { children: _jsx(Droppable, __assign({ droppableId: "droppable", direction: "horizontal" }, { children: function (provided) { return (_jsx("div", __assign({ ref: provided.innerRef, className: "flex w-full justify-between space-x-4" }, provided.droppableProps, { children: dashboardItems.map(function (dashboardItem, index) {
246
- return (_jsx(Draggable, __assign({ draggableId: dashboardItem, index: index, isDragDisabled: !isMultiPanelView }, { children: function (provided, snapshot) { return (_createElement("div", __assign({ ref: provided.innerRef }, provided.draggableProps, { key: dashboardItem, className: cx('rounded border border-gray-300 p-3 dark:border-gray-500 dark:bg-gray-700', isMultiPanelView ? 'w-1/2' : 'w-full', snapshot.isDragging ? 'bg-gray-200' : 'bg-white') }),
247
- _jsx(VisualizationPanel, { handleClosePanel: handleClosePanel, isMultiPanelView: isMultiPanelView, dashboardItem: dashboardItem, getDashboardItemByType: getDashboardItemByType, dragHandleProps: provided.dragHandleProps, navigateTo: navigateTo, index: index }))); } }), dashboardItem));
248
- }) }))); } })) }))) }))] }) }) })) }));
165
+ : 'Download pprof' })] }), _jsx(FilterByFunctionButton, { navigateTo: navigateTo })] }), _jsx("div", { className: "ml-auto flex gap-2", children: _jsx(ViewSelector, { defaultValue: "", navigateTo: navigateTo, position: -1, placeholderText: "Add panel...", primary: true, addView: true, disabled: isMultiPanelView || dashboardItems.length < 1 }) })] }), _jsx("div", { className: "w-full", ref: ref, children: isLoaderVisible ? (_jsx(_Fragment, { children: loader })) : (_jsx(DragDropContext, { onDragEnd: onDragEnd, children: _jsx(Droppable, { droppableId: "droppable", direction: "horizontal", children: provided => (_jsx("div", { ref: provided.innerRef, className: "flex w-full justify-between space-x-4", ...provided.droppableProps, children: dashboardItems.map((dashboardItem, index) => {
166
+ return (_jsx(Draggable, { draggableId: dashboardItem, index: index, isDragDisabled: !isMultiPanelView, children: (provided, snapshot) => (_createElement("div", { ref: provided.innerRef, ...provided.draggableProps, key: dashboardItem, className: cx('rounded border border-gray-300 p-3 dark:border-gray-500 dark:bg-gray-700', isMultiPanelView ? 'w-1/2' : 'w-full', snapshot.isDragging ? 'bg-gray-200' : 'bg-white') },
167
+ _jsx(VisualizationPanel, { handleClosePanel: handleClosePanel, isMultiPanelView: isMultiPanelView, dashboardItem: dashboardItem, getDashboardItemByType: getDashboardItemByType, dragHandleProps: provided.dragHandleProps, navigateTo: navigateTo, index: index }))) }, dashboardItem));
168
+ }) })) }) })) })] }) }) }) }));
249
169
  };
@@ -1,39 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- var __generator = (this && this.__generator) || function (thisArg, body) {
11
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
- function verb(n) { return function (v) { return step([n, v]); }; }
14
- function step(op) {
15
- if (f) throw new TypeError("Generator is already executing.");
16
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
- if (y = 0, t) op = [op[0] & 2, t.value];
19
- switch (op[0]) {
20
- case 0: case 1: t = op; break;
21
- case 4: _.label++; return { value: op[1], done: false };
22
- case 5: _.label++; y = op[1]; op = [0]; continue;
23
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
- default:
25
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
- if (t[2]) _.ops.pop();
30
- _.trys.pop(); continue;
31
- }
32
- op = body.call(thisArg, _);
33
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
- }
36
- };
37
1
  import { jsx as _jsx } from "react/jsx-runtime";
38
2
  // Copyright 2022 The Parca Authors
39
3
  // Licensed under the Apache License, Version 2.0 (the "License");
@@ -55,50 +19,47 @@ import { saveAsBlob } from '@parca/utilities';
55
19
  import { ProfileView } from './ProfileView';
56
20
  import { useQuery } from './useQuery';
57
21
  import { downloadPprof } from './utils';
58
- export var ProfileViewWithData = function (_a) {
59
- var _b, _c, _d, _e;
60
- var queryClient = _a.queryClient, profileSource = _a.profileSource, navigateTo = _a.navigateTo;
61
- var metadata = useGrpcMetadata();
62
- var dashboardItems = useURLState({ param: 'dashboard_items', navigateTo: navigateTo })[0];
63
- var _f = useState(0), nodeTrimThreshold = _f[0], setNodeTrimThreshold = _f[1];
64
- var enableTrimming = useUserPreference(USER_PREFERENCES.ENABLE_GRAPH_TRIMMING.key)[0];
65
- var _g = useState(false), pprofDownloading = _g[0], setPprofDownloading = _g[1];
66
- useEffect(function () {
22
+ export const ProfileViewWithData = ({ queryClient, profileSource, navigateTo, }) => {
23
+ const metadata = useGrpcMetadata();
24
+ const [dashboardItems] = useURLState({ param: 'dashboard_items', navigateTo });
25
+ const [nodeTrimThreshold, setNodeTrimThreshold] = useState(0);
26
+ const [enableTrimming] = useUserPreference(USER_PREFERENCES.ENABLE_GRAPH_TRIMMING.key);
27
+ const [pprofDownloading, setPprofDownloading] = useState(false);
28
+ useEffect(() => {
67
29
  if (!enableTrimming) {
68
30
  setNodeTrimThreshold(0);
69
31
  }
70
32
  }, [enableTrimming]);
71
- var onFlamegraphContainerResize = function (width) {
33
+ const onFlamegraphContainerResize = (width) => {
72
34
  if (!enableTrimming || width === 0) {
73
35
  return;
74
36
  }
75
- var threshold = (1 / width) * 100;
37
+ const threshold = (1 / width) * 100;
76
38
  if (threshold === nodeTrimThreshold) {
77
39
  return;
78
40
  }
79
41
  setNodeTrimThreshold(threshold);
80
42
  };
81
- var _h = useQuery(queryClient, profileSource, QueryRequest_ReportType.FLAMEGRAPH_TABLE, {
43
+ const { isLoading: flamegraphLoading, response: flamegraphResponse, error: flamegraphError, } = useQuery(queryClient, profileSource, QueryRequest_ReportType.FLAMEGRAPH_TABLE, {
82
44
  skip: !dashboardItems.includes('icicle'),
83
- nodeTrimThreshold: nodeTrimThreshold,
84
- }), flamegraphLoading = _h.isLoading, flamegraphResponse = _h.response, flamegraphError = _h.error;
85
- var perf = useParcaContext().perf;
86
- var _j = useQuery(queryClient, profileSource, QueryRequest_ReportType.TOP, {
45
+ nodeTrimThreshold,
46
+ });
47
+ const { perf } = useParcaContext();
48
+ const { isLoading: topTableLoading, response: topTableResponse, error: topTableError, } = useQuery(queryClient, profileSource, QueryRequest_ReportType.TOP, {
87
49
  skip: !dashboardItems.includes('table'),
88
- }), topTableLoading = _j.isLoading, topTableResponse = _j.response, topTableError = _j.error;
89
- var _k = useQuery(queryClient, profileSource, QueryRequest_ReportType.CALLGRAPH, {
50
+ });
51
+ const { isLoading: callgraphLoading, response: callgraphResponse, error: callgraphError, } = useQuery(queryClient, profileSource, QueryRequest_ReportType.CALLGRAPH, {
90
52
  skip: !dashboardItems.includes('callgraph'),
91
- }), callgraphLoading = _k.isLoading, callgraphResponse = _k.response, callgraphError = _k.error;
92
- useEffect(function () {
93
- var _a, _b;
94
- if (!flamegraphLoading && (flamegraphResponse === null || flamegraphResponse === void 0 ? void 0 : flamegraphResponse.report.oneofKind) === 'flamegraph') {
95
- perf === null || perf === void 0 ? void 0 : perf.markInteraction('Flamegraph render', flamegraphResponse.report.flamegraph.total);
53
+ });
54
+ useEffect(() => {
55
+ if (!flamegraphLoading && flamegraphResponse?.report.oneofKind === 'flamegraph') {
56
+ perf?.markInteraction('Flamegraph render', flamegraphResponse.report.flamegraph.total);
96
57
  }
97
- if (!topTableLoading && (topTableResponse === null || topTableResponse === void 0 ? void 0 : topTableResponse.report.oneofKind) === 'top') {
98
- perf === null || perf === void 0 ? void 0 : perf.markInteraction('Top table render', (_a = topTableResponse === null || topTableResponse === void 0 ? void 0 : topTableResponse.report) === null || _a === void 0 ? void 0 : _a.top.total);
58
+ if (!topTableLoading && topTableResponse?.report.oneofKind === 'top') {
59
+ perf?.markInteraction('Top table render', topTableResponse?.report?.top.total);
99
60
  }
100
- if (!callgraphLoading && (callgraphResponse === null || callgraphResponse === void 0 ? void 0 : callgraphResponse.report.oneofKind) === 'callgraph') {
101
- perf === null || perf === void 0 ? void 0 : perf.markInteraction('Callgraph render', (_b = callgraphResponse === null || callgraphResponse === void 0 ? void 0 : callgraphResponse.report) === null || _b === void 0 ? void 0 : _b.callgraph.cumulative);
61
+ if (!callgraphLoading && callgraphResponse?.report.oneofKind === 'callgraph') {
62
+ perf?.markInteraction('Callgraph render', callgraphResponse?.report?.callgraph.cumulative);
102
63
  }
103
64
  }, [
104
65
  flamegraphLoading,
@@ -109,38 +70,26 @@ export var ProfileViewWithData = function (_a) {
109
70
  topTableResponse,
110
71
  perf,
111
72
  ]);
112
- var sampleUnit = profileSource.ProfileType().sampleUnit;
113
- var downloadPProfClick = function () { return __awaiter(void 0, void 0, void 0, function () {
114
- var blob, error_1;
115
- return __generator(this, function (_a) {
116
- switch (_a.label) {
117
- case 0:
118
- if (profileSource == null || queryClient == null) {
119
- return [2 /*return*/];
120
- }
121
- _a.label = 1;
122
- case 1:
123
- _a.trys.push([1, 3, , 4]);
124
- setPprofDownloading(true);
125
- return [4 /*yield*/, downloadPprof(profileSource.QueryRequest(), queryClient, metadata)];
126
- case 2:
127
- blob = _a.sent();
128
- saveAsBlob(blob, "profile.pb.gz");
129
- setPprofDownloading(false);
130
- return [3 /*break*/, 4];
131
- case 3:
132
- error_1 = _a.sent();
133
- setPprofDownloading(false);
134
- console.error('Error while querying', error_1);
135
- return [3 /*break*/, 4];
136
- case 4: return [2 /*return*/];
137
- }
138
- });
139
- }); };
73
+ const sampleUnit = profileSource.ProfileType().sampleUnit;
74
+ const downloadPProfClick = async () => {
75
+ if (profileSource == null || queryClient == null) {
76
+ return;
77
+ }
78
+ try {
79
+ setPprofDownloading(true);
80
+ const blob = await downloadPprof(profileSource.QueryRequest(), queryClient, metadata);
81
+ saveAsBlob(blob, `profile.pb.gz`);
82
+ setPprofDownloading(false);
83
+ }
84
+ catch (error) {
85
+ setPprofDownloading(false);
86
+ console.error('Error while querying', error);
87
+ }
88
+ };
140
89
  // TODO: Refactor how we get responses such that we have a single response,
141
90
  // regardless of the report type.
142
- var total = BigInt(0);
143
- var filtered = BigInt(0);
91
+ let total = BigInt(0);
92
+ let filtered = BigInt(0);
144
93
  if (flamegraphResponse !== null) {
145
94
  total = BigInt(flamegraphResponse.total);
146
95
  filtered = BigInt(flamegraphResponse.filtered);
@@ -155,22 +104,22 @@ export var ProfileViewWithData = function (_a) {
155
104
  }
156
105
  return (_jsx(ProfileView, { total: total, filtered: filtered, flamegraphData: {
157
106
  loading: flamegraphLoading,
158
- data: (flamegraphResponse === null || flamegraphResponse === void 0 ? void 0 : flamegraphResponse.report.oneofKind) === 'flamegraph'
159
- ? (_b = flamegraphResponse === null || flamegraphResponse === void 0 ? void 0 : flamegraphResponse.report) === null || _b === void 0 ? void 0 : _b.flamegraph
107
+ data: flamegraphResponse?.report.oneofKind === 'flamegraph'
108
+ ? flamegraphResponse?.report?.flamegraph
160
109
  : undefined,
161
- total: BigInt((_c = flamegraphResponse === null || flamegraphResponse === void 0 ? void 0 : flamegraphResponse.total) !== null && _c !== void 0 ? _c : '0'),
162
- filtered: BigInt((_d = flamegraphResponse === null || flamegraphResponse === void 0 ? void 0 : flamegraphResponse.filtered) !== null && _d !== void 0 ? _d : '0'),
110
+ total: BigInt(flamegraphResponse?.total ?? '0'),
111
+ filtered: BigInt(flamegraphResponse?.filtered ?? '0'),
163
112
  error: flamegraphError,
164
113
  }, topTableData: {
165
114
  loading: topTableLoading,
166
- data: (topTableResponse === null || topTableResponse === void 0 ? void 0 : topTableResponse.report.oneofKind) === 'top' ? topTableResponse.report.top : undefined,
115
+ data: topTableResponse?.report.oneofKind === 'top' ? topTableResponse.report.top : undefined,
167
116
  error: topTableError,
168
117
  }, callgraphData: {
169
118
  loading: callgraphLoading,
170
- data: (callgraphResponse === null || callgraphResponse === void 0 ? void 0 : callgraphResponse.report.oneofKind) === 'callgraph'
171
- ? (_e = callgraphResponse === null || callgraphResponse === void 0 ? void 0 : callgraphResponse.report) === null || _e === void 0 ? void 0 : _e.callgraph
119
+ data: callgraphResponse?.report.oneofKind === 'callgraph'
120
+ ? callgraphResponse?.report?.callgraph
172
121
  : undefined,
173
122
  error: callgraphError,
174
- }, sampleUnit: sampleUnit, profileSource: profileSource, queryClient: queryClient, navigateTo: navigateTo, onDownloadPProf: function () { return void downloadPProfClick(); }, pprofDownloading: pprofDownloading, onFlamegraphContainerResize: onFlamegraphContainerResize }));
123
+ }, sampleUnit: sampleUnit, profileSource: profileSource, queryClient: queryClient, navigateTo: navigateTo, onDownloadPProf: () => void downloadPProfClick(), pprofDownloading: pprofDownloading, onFlamegraphContainerResize: onFlamegraphContainerResize }));
175
124
  };
176
125
  export default ProfileViewWithData;