@parca/profile 0.16.242 → 0.16.244

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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.16.244](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.243...@parca/profile@0.16.244) (2023-09-01)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
10
+ ## [0.16.243](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.242...@parca/profile@0.16.243) (2023-09-01)
11
+
12
+ **Note:** Version bump only for package @parca/profile
13
+
6
14
  ## [0.16.242](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.241...@parca/profile@0.16.242) (2023-08-31)
7
15
 
8
16
  **Note:** Version bump only for package @parca/profile
@@ -95,7 +95,7 @@ onCopy, row, navigateTo, }) => {
95
95
  const labelPairs = labelColumnNames
96
96
  .map((field, i) => [
97
97
  labelColumnNames[i].name.slice(pprofLabelPrefix.length),
98
- table.getChild(field.name)?.get(row) ?? '',
98
+ arrowToString(table.getChild(field.name)?.get(row)) ?? '',
99
99
  ])
100
100
  .filter(value => value[1] !== '');
101
101
  const labels = labelPairs.map((l) => (_jsx("span", { className: "mr-3 inline-block rounded-lg bg-gray-200 px-2 py-1 text-xs font-bold text-gray-700 dark:bg-gray-700 dark:text-gray-400", children: `${l[0]}="${l[1]}"` }, l[0])));
@@ -10,6 +10,6 @@ const ProfileExplorerCompare = ({ queryClient, queryA, queryB, profileA, profile
10
10
  const closeProfileB = () => {
11
11
  closeProfile('B');
12
12
  };
13
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex justify-between gap-2", children: [_jsx(Card, { className: "mt-2 p-2", children: _jsx(ProfileSelector, { queryClient: queryClient, querySelection: queryA, profileSelection: profileA, selectProfile: selectProfileA, selectQuery: selectQueryA, closeProfile: closeProfileA, enforcedProfileName: '', comparing: true, onCompareProfile: () => { } }) }), _jsx(Card, { className: "mt-2 p-2", children: _jsx(ProfileSelector, { queryClient: queryClient, querySelection: queryB, profileSelection: profileB, selectProfile: selectProfileB, selectQuery: selectQueryB, closeProfile: closeProfileB, enforcedProfileName: Query.parse(queryA.expression).profileName(), comparing: true, onCompareProfile: () => { } }) })] }), _jsx("div", { className: "grid grid-cols-1", children: profileA != null && profileB != null ? (_jsx(Card, { className: "mt-2 px-6 py-4", children: _jsx(ProfileViewWithData, { navigateTo: navigateTo, queryClient: queryClient, profileSource: new ProfileDiffSource(profileA.ProfileSource(), profileB.ProfileSource()) }) })) : (_jsx("div", { children: _jsx("div", { className: "my-20 text-center", children: _jsx("p", { children: "Select a profile on both sides." }) }) })) })] }));
13
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex justify-between gap-2", children: [_jsx(Card, { className: "mt-2 p-2", children: _jsx(ProfileSelector, { queryClient: queryClient, querySelection: queryA, profileSelection: profileA, selectProfile: selectProfileA, selectQuery: selectQueryA, closeProfile: closeProfileA, enforcedProfileName: '', comparing: true, onCompareProfile: () => { } }) }), _jsx(Card, { className: "mt-2 p-2", children: _jsx(ProfileSelector, { queryClient: queryClient, querySelection: queryB, profileSelection: profileB, selectProfile: selectProfileB, selectQuery: selectQueryB, closeProfile: closeProfileB, enforcedProfileName: Query.parse(queryA.expression).profileName(), comparing: true, onCompareProfile: () => { } }) })] }), _jsx("div", { className: "grid grid-cols-1", children: profileA != null && profileB != null ? (_jsx("div", { children: _jsx(Card, { className: "mt-2 px-6 py-4", children: _jsx(ProfileViewWithData, { navigateTo: navigateTo, queryClient: queryClient, profileSource: new ProfileDiffSource(profileA.ProfileSource(), profileB.ProfileSource()) }) }) })) : (_jsx("div", { children: _jsx("div", { className: "my-20 text-center", children: _jsx("p", { children: "Select a profile on both sides." }) }) })) })] }));
14
14
  };
15
15
  export default ProfileExplorerCompare;
@@ -4,7 +4,7 @@ import { Flamegraph } from '@parca/client';
4
4
  import { type NavigateFunction } from '@parca/utilities';
5
5
  export type ResizeHandler = (width: number, height: number) => void;
6
6
  interface ProfileIcicleGraphProps {
7
- width?: number;
7
+ width: number;
8
8
  graph?: Flamegraph;
9
9
  table?: Table<any>;
10
10
  total: bigint;
@@ -17,5 +17,5 @@ interface ProfileIcicleGraphProps {
17
17
  setActionButtons?: (buttons: React.JSX.Element) => void;
18
18
  error?: any;
19
19
  }
20
- declare const ProfileIcicleGraph: ({ graph, table, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, }: ProfileIcicleGraphProps) => JSX.Element;
20
+ declare const ProfileIcicleGraph: ({ graph, table, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, width, }: ProfileIcicleGraphProps) => JSX.Element;
21
21
  export default ProfileIcicleGraph;
@@ -15,7 +15,6 @@ import { Fragment, useCallback, useEffect, useMemo } from 'react';
15
15
  import { Menu, Transition } from '@headlessui/react';
16
16
  import { Icon } from '@iconify/react';
17
17
  import { Button, Select, useParcaContext, useURLState } from '@parca/components';
18
- import { useContainerDimensions } from '@parca/hooks';
19
18
  import { divide, selectQueryParam } from '@parca/utilities';
20
19
  import DiffLegend from '../components/DiffLegend';
21
20
  import IcicleGraph from './IcicleGraph';
@@ -50,10 +49,9 @@ const GroupAndSortActionButtons = ({ navigateTo }) => {
50
49
  }, [groupBy, setGroupBy]);
51
50
  return (_jsxs(_Fragment, { children: [_jsx(GroupByDropdown, { groupBy: groupBy, toggleGroupBy: toggleGroupBy }), _jsx(SortBySelect, { compareMode: compareMode, sortBy: storeSortBy, setSortBy: setStoreSortBy })] }));
52
51
  };
53
- const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, table, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, }) {
52
+ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, table, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, width, }) {
54
53
  const { loader } = useParcaContext();
55
54
  const compareMode = selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
56
- const { ref, dimensions } = useContainerDimensions();
57
55
  const [storeSortBy = FIELD_FUNCTION_NAME] = useURLState({
58
56
  param: 'sort_by',
59
57
  navigateTo,
@@ -97,7 +95,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, table, to
97
95
  if (isTrimmed) {
98
96
  console.info(`Trimmed ${trimmedFormatted} (${trimmedPercentage}%) too small values.`);
99
97
  }
100
- return (_jsxs("div", { className: "relative", children: [compareMode && _jsx(DiffLegend, {}), _jsxs("div", { ref: ref, className: "min-h-48", children: [graph !== undefined && (_jsx(IcicleGraph, { width: dimensions?.width, graph: graph, total: total, filtered: filtered, curPath: curPath, setCurPath: setNewCurPath, sampleUnit: sampleUnit, navigateTo: navigateTo })), table !== undefined && (_jsx(IcicleGraphArrow, { width: dimensions?.width, table: table, total: total, filtered: filtered, curPath: curPath, setCurPath: setNewCurPath, sampleUnit: sampleUnit, navigateTo: navigateTo, sortBy: storeSortBy }))] }), _jsxs("p", { className: "my-2 text-xs", children: ["Showing ", totalFormatted, ' ', isFiltered ? (_jsxs("span", { children: ["(", filteredPercentage, "%) filtered of ", totalUnfilteredFormatted, ' '] })) : (_jsx(_Fragment, {})), "values.", ' '] })] }));
98
+ return (_jsxs("div", { className: "relative", children: [compareMode && _jsx(DiffLegend, {}), _jsxs("div", { className: "min-h-48", children: [graph !== undefined && (_jsx(IcicleGraph, { width: width, graph: graph, total: total, filtered: filtered, curPath: curPath, setCurPath: setNewCurPath, sampleUnit: sampleUnit, navigateTo: navigateTo })), table !== undefined && (_jsx(IcicleGraphArrow, { width: width, table: table, total: total, filtered: filtered, curPath: curPath, setCurPath: setNewCurPath, sampleUnit: sampleUnit, navigateTo: navigateTo, sortBy: storeSortBy }))] }), _jsxs("p", { className: "my-2 text-xs", children: ["Showing ", totalFormatted, ' ', isFiltered ? (_jsxs("span", { children: ["(", filteredPercentage, "%) filtered of ", totalUnfilteredFormatted, ' '] })) : (_jsx(_Fragment, {})), "values.", ' '] })] }));
101
99
  };
102
100
  const groupByOptions = [
103
101
  {
@@ -119,7 +119,7 @@ const ProfileSelector = ({ queryClient, querySelection, selectProfile, selectQue
119
119
  queryExpressionString === '' ||
120
120
  queryExpressionString === '{}';
121
121
  const compareDisabled = selectedProfileName === '' || querySelection.expression === undefined;
122
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mb-2 flex", children: [_jsxs("div", { className: "flex w-full flex-wrap content-start items-end justify-between gap-2", children: [_jsxs("div", { children: [_jsx("label", { className: "text-xs", children: "Profile type" }), _jsx(ProfileTypeSelector, { profileTypesData: profileTypesData, loading: profileTypesLoading, selectedKey: selectedProfileName, onSelection: setProfileName, error: error })] }), _jsxs("div", { className: "w-full flex-1", children: [_jsx("label", { className: "text-xs", children: "Query" }), _jsx(MatchersInput, { queryClient: queryClient, setMatchersString: setMatchersString, runQuery: setQueryExpression, currentQuery: query })] }), _jsxs("div", { children: [_jsx("label", { className: "text-xs", children: "Period" }), _jsx(DateTimeRangePicker, { onRangeSelection: setTimeRangeSelection, range: timeRangeSelection })] }), _jsxs(ButtonGroup, { children: [!searchDisabled && (_jsx(_Fragment, { children: !comparing && (_jsx(CompareButton, { disabled: compareDisabled, onClick: handleCompareClick })) })), _jsx(Button, { disabled: searchDisabled, onClick: (e) => {
122
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mb-2 flex gap-2", children: [_jsxs("div", { className: "flex w-full flex-wrap content-start items-end justify-between gap-2", children: [_jsxs("div", { children: [_jsx("label", { className: "text-xs", children: "Profile type" }), _jsx(ProfileTypeSelector, { profileTypesData: profileTypesData, loading: profileTypesLoading, selectedKey: selectedProfileName, onSelection: setProfileName, error: error })] }), _jsxs("div", { className: "w-full flex-1", children: [_jsx("label", { className: "text-xs", children: "Query" }), _jsx(MatchersInput, { queryClient: queryClient, setMatchersString: setMatchersString, runQuery: setQueryExpression, currentQuery: query })] }), _jsxs("div", { children: [_jsx("label", { className: "text-xs", children: "Period" }), _jsx(DateTimeRangePicker, { onRangeSelection: setTimeRangeSelection, range: timeRangeSelection })] }), _jsxs(ButtonGroup, { children: [!searchDisabled && (_jsx(_Fragment, { children: !comparing && (_jsx(CompareButton, { disabled: compareDisabled, onClick: handleCompareClick })) })), _jsx(Button, { disabled: searchDisabled, onClick: (e) => {
123
123
  e.preventDefault();
124
124
  setQueryExpression();
125
125
  }, children: "Search" })] })] }), _jsx("div", { children: comparing && _jsx(IconButton, { onClick: () => closeProfile(), icon: _jsx(CloseIcon, {}) }) })] }), _jsx("div", { className: "rounded bg-white shadow dark:border-gray-500 dark:bg-gray-700", children: _jsx("div", { style: { height: heightStyle }, children: querySelection.expression !== undefined &&
@@ -130,7 +130,11 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
130
130
  return (_jsx(ConditionalWrapper, { condition: perf?.onRender != null, WrapperComponent: Profiler, wrapperProps: {
131
131
  id: 'icicleGraph',
132
132
  onRender: perf?.onRender,
133
- }, children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, table: flamegraphData?.table, graph: flamegraphData?.data, total: total, filtered: filtered, sampleUnit: sampleUnit, navigateTo: navigateTo, loading: flamegraphData.loading, setActionButtons: setActionButtons, error: flamegraphData.error }) }));
133
+ }, children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, table: flamegraphData?.table, graph: flamegraphData?.data, total: total, filtered: filtered, sampleUnit: sampleUnit, navigateTo: navigateTo, loading: flamegraphData.loading, setActionButtons: setActionButtons, error: flamegraphData.error, width: dimensions?.width !== undefined
134
+ ? isHalfScreen
135
+ ? (dimensions.width - 40) / 2
136
+ : dimensions.width - 16
137
+ : 0 }) }));
134
138
  }
135
139
  case 'callgraph': {
136
140
  return callgraphData?.data !== undefined &&
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parca/profile",
3
- "version": "0.16.242",
3
+ "version": "0.16.244",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@parca/client": "^0.16.86",
@@ -49,5 +49,5 @@
49
49
  "access": "public",
50
50
  "registry": "https://registry.npmjs.org/"
51
51
  },
52
- "gitHead": "38f61e5bc68000801734fc679bda583a75296643"
52
+ "gitHead": "cad92c30fc37a648d8989db61aaa8165b1db4028"
53
53
  }
@@ -238,7 +238,7 @@ const TooltipMetaInfo = ({
238
238
  const labelPairs = labelColumnNames
239
239
  .map((field, i) => [
240
240
  labelColumnNames[i].name.slice(pprofLabelPrefix.length),
241
- table.getChild(field.name)?.get(row) ?? '',
241
+ arrowToString(table.getChild(field.name)?.get(row)) ?? '',
242
242
  ])
243
243
  .filter(value => value[1] !== '');
244
244
  const labels = labelPairs.map(
@@ -247,7 +247,7 @@ const TooltipMetaInfo = ({
247
247
  key={l[0]}
248
248
  className="mr-3 inline-block rounded-lg bg-gray-200 px-2 py-1 text-xs font-bold text-gray-700 dark:bg-gray-700 dark:text-gray-400"
249
249
  >
250
- {`${l[0] as string}="${l[1] as string}"`}
250
+ {`${l[0]}="${l[1]}"`}
251
251
  </span>
252
252
  )
253
253
  );
@@ -88,15 +88,17 @@ const ProfileExplorerCompare = ({
88
88
  </div>
89
89
  <div className="grid grid-cols-1">
90
90
  {profileA != null && profileB != null ? (
91
- <Card className="mt-2 px-6 py-4">
92
- <ProfileViewWithData
93
- navigateTo={navigateTo}
94
- queryClient={queryClient}
95
- profileSource={
96
- new ProfileDiffSource(profileA.ProfileSource(), profileB.ProfileSource())
97
- }
98
- />
99
- </Card>
91
+ <div>
92
+ <Card className="mt-2 px-6 py-4">
93
+ <ProfileViewWithData
94
+ navigateTo={navigateTo}
95
+ queryClient={queryClient}
96
+ profileSource={
97
+ new ProfileDiffSource(profileA.ProfileSource(), profileB.ProfileSource())
98
+ }
99
+ />
100
+ </Card>
101
+ </div>
100
102
  ) : (
101
103
  <div>
102
104
  <div className="my-20 text-center">
@@ -19,7 +19,6 @@ import {Table} from 'apache-arrow';
19
19
 
20
20
  import {Flamegraph} from '@parca/client';
21
21
  import {Button, Select, useParcaContext, useURLState} from '@parca/components';
22
- import {useContainerDimensions} from '@parca/hooks';
23
22
  import {divide, selectQueryParam, type NavigateFunction} from '@parca/utilities';
24
23
 
25
24
  import DiffLegend from '../components/DiffLegend';
@@ -36,7 +35,7 @@ const numberFormatter = new Intl.NumberFormat('en-US');
36
35
  export type ResizeHandler = (width: number, height: number) => void;
37
36
 
38
37
  interface ProfileIcicleGraphProps {
39
- width?: number;
38
+ width: number;
40
39
  graph?: Flamegraph;
41
40
  table?: Table<any>;
42
41
  total: bigint;
@@ -113,11 +112,11 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
113
112
  loading,
114
113
  setActionButtons,
115
114
  error,
115
+ width,
116
116
  }: ProfileIcicleGraphProps): JSX.Element {
117
117
  const {loader} = useParcaContext();
118
118
  const compareMode: boolean =
119
119
  selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
120
- const {ref, dimensions} = useContainerDimensions();
121
120
 
122
121
  const [storeSortBy = FIELD_FUNCTION_NAME] = useURLState({
123
122
  param: 'sort_by',
@@ -200,10 +199,10 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
200
199
  return (
201
200
  <div className="relative">
202
201
  {compareMode && <DiffLegend />}
203
- <div ref={ref} className="min-h-48">
202
+ <div className="min-h-48">
204
203
  {graph !== undefined && (
205
204
  <IcicleGraph
206
- width={dimensions?.width}
205
+ width={width}
207
206
  graph={graph}
208
207
  total={total}
209
208
  filtered={filtered}
@@ -215,7 +214,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
215
214
  )}
216
215
  {table !== undefined && (
217
216
  <IcicleGraphArrow
218
- width={dimensions?.width}
217
+ width={width}
219
218
  table={table}
220
219
  total={total}
221
220
  filtered={filtered}
@@ -199,7 +199,7 @@ const ProfileSelector = ({
199
199
 
200
200
  return (
201
201
  <>
202
- <div className="mb-2 flex">
202
+ <div className="mb-2 flex gap-2">
203
203
  <div className="flex w-full flex-wrap content-start items-end justify-between gap-2">
204
204
  <div>
205
205
  <label className="text-xs">Profile type</label>
@@ -267,6 +267,13 @@ export const ProfileView = ({
267
267
  loading={flamegraphData.loading}
268
268
  setActionButtons={setActionButtons}
269
269
  error={flamegraphData.error}
270
+ width={
271
+ dimensions?.width !== undefined
272
+ ? isHalfScreen
273
+ ? (dimensions.width - 40) / 2
274
+ : dimensions.width - 16
275
+ : 0
276
+ }
270
277
  />
271
278
  </ConditionalWrapper>
272
279
  );