@parca/profile 0.16.64 → 0.16.65

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,10 @@
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.65 (2022-11-09)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
6
10
  ## [0.16.64](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.63...@parca/profile@0.16.64) (2022-11-08)
7
11
 
8
12
  **Note:** Version bump only for package @parca/profile
@@ -27,7 +27,7 @@ import { Transition } from '@headlessui/react';
27
27
  import { Query } from '@parca/parser';
28
28
  import { usePopper } from 'react-popper';
29
29
  import cx from 'classnames';
30
- import { useParcaTheme, useGrpcMetadata } from '@parca/components';
30
+ import { useParcaContext, useGrpcMetadata } from '@parca/components';
31
31
  export var useLabelNames = function (client) {
32
32
  var _a = useState(true), loading = _a[0], setLoading = _a[1];
33
33
  var _b = useState({}), result = _b[0], setResult = _b[1];
@@ -73,7 +73,7 @@ var MatchersInput = function (_a) {
73
73
  placement: 'bottom-start',
74
74
  }), styles = _l.styles, attributes = _l.attributes;
75
75
  var metadata = useGrpcMetadata();
76
- var Spinner = useParcaTheme().loader;
76
+ var Spinner = useParcaContext().loader;
77
77
  var _m = useLabelNames(queryClient), labelNamesLoading = _m.loading, result = _m.result;
78
78
  var labelNamesResponse = result.response, labelNamesError = result.error;
79
79
  var LoadingSpinner = function () {
@@ -62,7 +62,7 @@ import { useState, useEffect } from 'react';
62
62
  import MetricsGraph from '../MetricsGraph';
63
63
  import { SingleProfileSelection } from '..';
64
64
  import { Timestamp } from '@parca/client';
65
- import { useGrpcMetadata, useParcaTheme } from '@parca/components';
65
+ import { useGrpcMetadata, useParcaContext } from '@parca/components';
66
66
  import { Query } from '@parca/parser';
67
67
  import useDelayedLoader from '../useDelayedLoader';
68
68
  export var useQueryRange = function (client, queryExpression, start, end) {
@@ -100,7 +100,7 @@ var ProfileMetricsGraph = function (_a) {
100
100
  var queryClient = _a.queryClient, queryExpression = _a.queryExpression, profile = _a.profile, from = _a.from, to = _a.to, select = _a.select, setTimeRange = _a.setTimeRange, addLabelMatcher = _a.addLabelMatcher;
101
101
  var _b = useQueryRange(queryClient, queryExpression, from, to), isLoading = _b.isLoading, response = _b.response, error = _b.error;
102
102
  var isLoaderVisible = useDelayedLoader(isLoading);
103
- var loader = useParcaTheme().loader;
103
+ var loader = useParcaContext().loader;
104
104
  if (isLoaderVisible) {
105
105
  return _jsx(_Fragment, { children: loader });
106
106
  }
@@ -22,18 +22,18 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
22
22
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
23
  // See the License for the specific language governing permissions and
24
24
  // limitations under the License.
25
- import { useEffect, useMemo, useState } from 'react';
25
+ import { Profiler, useEffect, useMemo, useState } from 'react';
26
+ import { scaleLinear } from 'd3';
26
27
  import { getNewSpanColor, parseParams } from '@parca/functions';
27
28
  import useUIFeatureFlag from '@parca/functions/useUIFeatureFlag';
28
- import { Button, Card, SearchNodes, useParcaTheme } from '@parca/components';
29
- import { Callgraph } from './';
29
+ import { Button, Card, SearchNodes, useParcaContext } from '@parca/components';
30
30
  import { useContainerDimensions } from '@parca/dynamicsize';
31
31
  import { useAppSelector, selectDarkMode, selectSearchNodeString } from '@parca/store';
32
+ import { Callgraph } from './';
32
33
  import ProfileShareButton from './components/ProfileShareButton';
33
34
  import ProfileIcicleGraph from './ProfileIcicleGraph';
34
35
  import TopTable from './TopTable';
35
36
  import useDelayedLoader from './useDelayedLoader';
36
- import { scaleLinear } from 'd3';
37
37
  import './ProfileView.styles.css';
38
38
  function arrayEquals(a, b) {
39
39
  return (Array.isArray(a) &&
@@ -63,7 +63,7 @@ export var ProfileView = function (_a) {
63
63
  var isDarkMode = useAppSelector(selectDarkMode);
64
64
  var currentSearchString = useAppSelector(selectSearchNodeString);
65
65
  var callgraphEnabled = useUIFeatureFlag('callgraph')[0];
66
- var loader = useParcaTheme().loader;
66
+ var _d = useParcaContext(), loader = _d.loader, perf = _d.perf;
67
67
  useEffect(function () {
68
68
  // Reset the current path when the profile source changes
69
69
  setCurPath([]);
@@ -115,5 +115,5 @@ export var ProfileView = function (_a) {
115
115
  return (_jsx(_Fragment, { children: _jsx("div", __assign({ className: "py-3" }, { children: _jsx(Card, { children: _jsxs(Card.Body, { children: [_jsxs("div", __assign({ className: "flex py-3 w-full" }, { children: [_jsxs("div", __assign({ className: "w-2/5 flex space-x-4" }, { children: [_jsxs("div", __assign({ className: "flex space-x-1" }, { children: [profileSource != null && queryClient != null ? (_jsx(ProfileShareButton, { queryRequest: profileSource.QueryRequest(), queryClient: queryClient })) : null, _jsx(Button, __assign({ color: "neutral", onClick: function (e) {
116
116
  e.preventDefault();
117
117
  onDownloadPProf();
118
- } }, { children: "Download pprof" }))] })), _jsx(SearchNodes, {})] })), _jsxs("div", __assign({ className: "flex ml-auto" }, { children: [_jsx("div", __assign({ className: "mr-3" }, { children: _jsx(Button, __assign({ color: "neutral", onClick: resetIcicleGraph, disabled: curPath.length === 0, className: "whitespace-nowrap text-ellipsis" }, { children: "Reset View" })) })), callgraphEnabled ? (_jsx("div", __assign({ className: "mr-3" }, { children: _jsx(Button, __assign({ variant: "".concat(currentView === 'callgraph' ? 'primary' : 'neutral'), onClick: function () { return switchProfileView('callgraph'); }, className: "whitespace-nowrap text-ellipsis" }, { children: "Callgraph" })) }))) : null, _jsx(Button, __assign({ variant: "".concat(currentView === 'table' ? 'primary' : 'neutral'), className: "items-center rounded-tr-none rounded-br-none w-auto px-8 whitespace-nowrap text-ellipsis no-outline-on-buttons", onClick: function () { return switchProfileView('table'); } }, { children: "Table" })), _jsx(Button, __assign({ variant: "".concat(currentView === 'both' ? 'primary' : 'neutral'), className: "items-center rounded-tl-none rounded-tr-none rounded-bl-none rounded-br-none border-l-0 border-r-0 w-auto px-8 whitespace-nowrap no-outline-on-buttons text-ellipsis", onClick: function () { return switchProfileView('both'); } }, { children: "Both" })), _jsx(Button, __assign({ variant: "".concat(currentView === 'icicle' ? 'primary' : 'neutral'), className: "items-center rounded-tl-none rounded-bl-none w-auto px-8 whitespace-nowrap text-ellipsis no-outline-on-buttons", onClick: function () { return switchProfileView('icicle'); } }, { children: "Icicle Graph" }))] }))] })), _jsxs("div", __assign({ ref: ref, className: "flex space-x-4 justify-between w-full" }, { children: [currentView === 'icicle' && (flamegraphData === null || flamegraphData === void 0 ? void 0 : flamegraphData.data) != null && (_jsx("div", __assign({ className: "w-full" }, { children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, graph: flamegraphData.data, sampleUnit: sampleUnit }) }))), currentView === 'callgraph' && (callgraphData === null || callgraphData === void 0 ? void 0 : callgraphData.data) != null && (_jsx("div", __assign({ className: "w-full" }, { children: (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) !== undefined && (_jsx(Callgraph, { graph: callgraphData.data, sampleUnit: sampleUnit, width: dimensions === null || dimensions === void 0 ? void 0 : dimensions.width, colorRange: colorRange })) }))), currentView === 'table' && topTableData != null && (_jsx("div", __assign({ className: "w-full" }, { children: _jsx(TopTable, { data: topTableData.data, sampleUnit: sampleUnit }) }))), currentView === 'both' && (_jsxs(_Fragment, { children: [_jsx("div", __assign({ className: "w-1/2" }, { children: _jsx(TopTable, { data: topTableData === null || topTableData === void 0 ? void 0 : topTableData.data, sampleUnit: sampleUnit }) })), _jsx("div", __assign({ className: "w-1/2" }, { children: flamegraphData != null && (_jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, graph: flamegraphData.data, sampleUnit: sampleUnit })) }))] }))] }))] }) }) })) }));
118
+ } }, { children: "Download pprof" }))] })), _jsx(SearchNodes, {})] })), _jsxs("div", __assign({ className: "flex ml-auto" }, { children: [_jsx("div", __assign({ className: "mr-3" }, { children: _jsx(Button, __assign({ color: "neutral", onClick: resetIcicleGraph, disabled: curPath.length === 0, className: "whitespace-nowrap text-ellipsis" }, { children: "Reset View" })) })), callgraphEnabled ? (_jsx("div", __assign({ className: "mr-3" }, { children: _jsx(Button, __assign({ variant: "".concat(currentView === 'callgraph' ? 'primary' : 'neutral'), onClick: function () { return switchProfileView('callgraph'); }, className: "whitespace-nowrap text-ellipsis" }, { children: "Callgraph" })) }))) : null, _jsx(Button, __assign({ variant: "".concat(currentView === 'table' ? 'primary' : 'neutral'), className: "items-center rounded-tr-none rounded-br-none w-auto px-8 whitespace-nowrap text-ellipsis no-outline-on-buttons", onClick: function () { return switchProfileView('table'); } }, { children: "Table" })), _jsx(Button, __assign({ variant: "".concat(currentView === 'both' ? 'primary' : 'neutral'), className: "items-center rounded-tl-none rounded-tr-none rounded-bl-none rounded-br-none border-l-0 border-r-0 w-auto px-8 whitespace-nowrap no-outline-on-buttons text-ellipsis", onClick: function () { return switchProfileView('both'); } }, { children: "Both" })), _jsx(Button, __assign({ variant: "".concat(currentView === 'icicle' ? 'primary' : 'neutral'), className: "items-center rounded-tl-none rounded-bl-none w-auto px-8 whitespace-nowrap text-ellipsis no-outline-on-buttons", onClick: function () { return switchProfileView('icicle'); } }, { children: "Icicle Graph" }))] }))] })), _jsxs("div", __assign({ ref: ref, className: "flex space-x-4 justify-between w-full" }, { children: [currentView === 'icicle' && (flamegraphData === null || flamegraphData === void 0 ? void 0 : flamegraphData.data) != null && (_jsx("div", __assign({ className: "w-full" }, { children: _jsx(Profiler, __assign({ id: "icicleGraph", onRender: perf.onRender }, { children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, graph: flamegraphData.data, sampleUnit: sampleUnit }) })) }))), currentView === 'callgraph' && (callgraphData === null || callgraphData === void 0 ? void 0 : callgraphData.data) != null && (_jsx("div", __assign({ className: "w-full" }, { children: (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) !== undefined && (_jsx(Callgraph, { graph: callgraphData.data, sampleUnit: sampleUnit, width: dimensions === null || dimensions === void 0 ? void 0 : dimensions.width, colorRange: colorRange })) }))), currentView === 'table' && topTableData != null && (_jsx("div", __assign({ className: "w-full" }, { children: _jsx(TopTable, { data: topTableData.data, sampleUnit: sampleUnit }) }))), currentView === 'both' && (_jsxs(_Fragment, { children: [_jsx("div", __assign({ className: "w-1/2" }, { children: _jsx(TopTable, { data: topTableData === null || topTableData === void 0 ? void 0 : topTableData.data, sampleUnit: sampleUnit }) })), _jsx("div", __assign({ className: "w-1/2" }, { children: flamegraphData != null && (_jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, graph: flamegraphData.data, sampleUnit: sampleUnit })) }))] }))] }))] }) }) })) }));
119
119
  };
@@ -51,8 +51,9 @@ import { QueryRequest_ReportType } from '@parca/client';
51
51
  import { useQuery } from './useQuery';
52
52
  import { ProfileView, useProfileVisState } from './ProfileView';
53
53
  import { downloadPprof } from './utils';
54
- import { useGrpcMetadata } from '@parca/components';
54
+ import { useGrpcMetadata, useParcaContext } from '@parca/components';
55
55
  import { saveAsBlob } from '@parca/functions';
56
+ import { useEffect } from 'react';
56
57
  export var ProfileViewWithData = function (_a) {
57
58
  var _b, _c;
58
59
  var queryClient = _a.queryClient, profileSource = _a.profileSource, navigateTo = _a.navigateTo;
@@ -62,6 +63,13 @@ export var ProfileViewWithData = function (_a) {
62
63
  var _d = useQuery(queryClient, profileSource, QueryRequest_ReportType.FLAMEGRAPH_TABLE, {
63
64
  skip: currentView !== 'icicle' && currentView !== 'both',
64
65
  }), flamegraphLoading = _d.isLoading, flamegraphResponse = _d.response, flamegraphError = _d.error;
66
+ var perf = useParcaContext().perf;
67
+ useEffect(function () {
68
+ if (flamegraphLoading) {
69
+ return;
70
+ }
71
+ perf.markInteraction('Flamegraph Render');
72
+ }, [flamegraphLoading, flamegraphResponse, perf]);
65
73
  var _e = useQuery(queryClient, profileSource, QueryRequest_ReportType.TOP, {
66
74
  skip: currentView !== 'table' && currentView !== 'both',
67
75
  }), topTableLoading = _e.isLoading, topTableResponse = _e.response, topTableError = _e.error;
package/dist/useQuery.js CHANGED
@@ -30,7 +30,6 @@ export var useQuery = function (client, profileSource, reportType, options) {
30
30
  isLoading: true,
31
31
  });
32
32
  var req = profileSource.QueryRequest();
33
- console.log('req', req);
34
33
  req.reportType = reportType;
35
34
  var call = client.query(req, { meta: metadata });
36
35
  call.response
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@parca/profile",
3
- "version": "0.16.64",
3
+ "version": "0.16.65",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@iconify/react": "^3.2.2",
7
7
  "@parca/client": "^0.16.54",
8
- "@parca/components": "^0.16.59",
8
+ "@parca/components": "^0.16.60",
9
9
  "@parca/dynamicsize": "^0.16.51",
10
10
  "@parca/functions": "^0.16.51",
11
11
  "@parca/parser": "^0.16.50",
@@ -40,5 +40,5 @@
40
40
  "access": "public",
41
41
  "registry": "https://registry.npmjs.org/"
42
42
  },
43
- "gitHead": "38667cf5c5702dff21fdfeb5d9f1053be97a1f9d"
43
+ "gitHead": "0b1285b6be9aee7b2716d230e1d4bdc5a0cea4d2"
44
44
  }
@@ -17,7 +17,8 @@ import {Query} from '@parca/parser';
17
17
  import {LabelsResponse, QueryServiceClient} from '@parca/client';
18
18
  import {usePopper} from 'react-popper';
19
19
  import cx from 'classnames';
20
- import {useParcaTheme, useGrpcMetadata} from '@parca/components';
20
+
21
+ import {useParcaContext, useGrpcMetadata} from '@parca/components';
21
22
 
22
23
  interface MatchersInputProps {
23
24
  queryClient: QueryServiceClient;
@@ -97,7 +98,7 @@ const MatchersInput = ({
97
98
  placement: 'bottom-start',
98
99
  });
99
100
  const metadata = useGrpcMetadata();
100
- const {loader: Spinner} = useParcaTheme();
101
+ const {loader: Spinner} = useParcaContext();
101
102
 
102
103
  const {loading: labelNamesLoading, result} = useLabelNames(queryClient);
103
104
  const {response: labelNamesResponse, error: labelNamesError} = result;
@@ -16,7 +16,7 @@ import MetricsGraph from '../MetricsGraph';
16
16
  import {ProfileSelection, SingleProfileSelection} from '..';
17
17
  import {QueryServiceClient, QueryRangeResponse, Label, Timestamp} from '@parca/client';
18
18
  import {RpcError} from '@protobuf-ts/runtime-rpc';
19
- import {DateTimeRange, useGrpcMetadata, useParcaTheme} from '@parca/components';
19
+ import {DateTimeRange, useGrpcMetadata, useParcaContext} from '@parca/components';
20
20
  import {Query} from '@parca/parser';
21
21
  import useDelayedLoader from '../useDelayedLoader';
22
22
 
@@ -89,7 +89,7 @@ const ProfileMetricsGraph = ({
89
89
  }: ProfileMetricsGraphProps): JSX.Element => {
90
90
  const {isLoading, response, error} = useQueryRange(queryClient, queryExpression, from, to);
91
91
  const isLoaderVisible = useDelayedLoader(isLoading);
92
- const {loader} = useParcaTheme();
92
+ const {loader} = useParcaContext();
93
93
 
94
94
  if (isLoaderVisible) {
95
95
  return <>{loader}</>;
@@ -11,22 +11,22 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
 
14
- import React, {useEffect, useMemo, useState} from 'react';
14
+ import {Profiler, useEffect, useMemo, useState} from 'react';
15
+ import {scaleLinear} from 'd3';
15
16
 
16
17
  import {getNewSpanColor, parseParams} from '@parca/functions';
17
18
  import useUIFeatureFlag from '@parca/functions/useUIFeatureFlag';
18
19
  import {QueryServiceClient, Flamegraph, Top, Callgraph as CallgraphType} from '@parca/client';
19
- import {Button, Card, SearchNodes, useParcaTheme} from '@parca/components';
20
- import {Callgraph} from './';
20
+ import {Button, Card, SearchNodes, useParcaContext} from '@parca/components';
21
21
  import {useContainerDimensions} from '@parca/dynamicsize';
22
22
  import {useAppSelector, selectDarkMode, selectSearchNodeString} from '@parca/store';
23
23
 
24
+ import {Callgraph} from './';
24
25
  import ProfileShareButton from './components/ProfileShareButton';
25
26
  import ProfileIcicleGraph from './ProfileIcicleGraph';
26
27
  import {ProfileSource} from './ProfileSource';
27
28
  import TopTable from './TopTable';
28
29
  import useDelayedLoader from './useDelayedLoader';
29
- import {scaleLinear} from 'd3';
30
30
 
31
31
  import './ProfileView.styles.css';
32
32
 
@@ -114,7 +114,7 @@ export const ProfileView = ({
114
114
 
115
115
  const [callgraphEnabled] = useUIFeatureFlag('callgraph');
116
116
 
117
- const {loader} = useParcaTheme();
117
+ const {loader, perf} = useParcaContext();
118
118
 
119
119
  useEffect(() => {
120
120
  // Reset the current path when the profile source changes
@@ -265,12 +265,14 @@ export const ProfileView = ({
265
265
  <div ref={ref} className="flex space-x-4 justify-between w-full">
266
266
  {currentView === 'icicle' && flamegraphData?.data != null && (
267
267
  <div className="w-full">
268
- <ProfileIcicleGraph
269
- curPath={curPath}
270
- setNewCurPath={setNewCurPath}
271
- graph={flamegraphData.data}
272
- sampleUnit={sampleUnit}
273
- />
268
+ <Profiler id="icicleGraph" onRender={perf.onRender}>
269
+ <ProfileIcicleGraph
270
+ curPath={curPath}
271
+ setNewCurPath={setNewCurPath}
272
+ graph={flamegraphData.data}
273
+ sampleUnit={sampleUnit}
274
+ />
275
+ </Profiler>
274
276
  </div>
275
277
  )}
276
278
  {currentView === 'callgraph' && callgraphData?.data != null && (
@@ -17,8 +17,9 @@ import {useQuery} from './useQuery';
17
17
  import {ProfileView, useProfileVisState} from './ProfileView';
18
18
  import {ProfileSource} from './ProfileSource';
19
19
  import {downloadPprof} from './utils';
20
- import {useGrpcMetadata} from '@parca/components';
20
+ import {useGrpcMetadata, useParcaContext} from '@parca/components';
21
21
  import {saveAsBlob} from '@parca/functions';
22
+ import {useEffect} from 'react';
22
23
 
23
24
  type NavigateFunction = (path: string, queryParams: any) => void;
24
25
 
@@ -44,6 +45,14 @@ export const ProfileViewWithData = ({
44
45
  } = useQuery(queryClient, profileSource, QueryRequest_ReportType.FLAMEGRAPH_TABLE, {
45
46
  skip: currentView !== 'icicle' && currentView !== 'both',
46
47
  });
48
+ const {perf} = useParcaContext();
49
+
50
+ useEffect(() => {
51
+ if (flamegraphLoading) {
52
+ return;
53
+ }
54
+ perf.markInteraction('Flamegraph Render');
55
+ }, [flamegraphLoading, flamegraphResponse, perf]);
47
56
 
48
57
  const {
49
58
  isLoading: topTableLoading,
package/src/useQuery.tsx CHANGED
@@ -53,7 +53,6 @@ export const useQuery = (
53
53
  isLoading: true,
54
54
  });
55
55
  const req = profileSource.QueryRequest();
56
- console.log('req', req);
57
56
  req.reportType = reportType;
58
57
 
59
58
  const call = client.query(req, {meta: metadata});