@parca/profile 0.16.253 → 0.16.254
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 +4 -0
- package/dist/ProfileExplorer/index.d.ts +1 -1
- package/dist/ProfileExplorer/index.js +11 -4
- package/dist/ProfileIcicleGraph/index.js +10 -4
- package/dist/ProfileMetricsGraph/index.js +11 -5
- package/package.json +5 -5
- package/src/ProfileExplorer/index.tsx +19 -12
- package/src/ProfileIcicleGraph/index.tsx +18 -4
- package/src/ProfileMetricsGraph/index.tsx +19 -12
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.254 (2023-09-14)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
6
10
|
## [0.16.253](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.252...@parca/profile@0.16.253) (2023-09-11)
|
|
7
11
|
|
|
8
12
|
**Note:** Version bump only for package @parca/profile
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { QueryServiceClient } from '@parca/client';
|
|
3
|
-
import type
|
|
3
|
+
import { type NavigateFunction } from '@parca/utilities';
|
|
4
4
|
interface ProfileExplorerProps {
|
|
5
5
|
queryClient: QueryServiceClient;
|
|
6
6
|
queryParams: any;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
// Copyright 2022 The Parca Authors
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -15,10 +15,14 @@ import { useEffect, useState } from 'react';
|
|
|
15
15
|
import { Provider } from 'react-redux';
|
|
16
16
|
import { DateTimeRange, KeyDownProvider, useParcaContext } from '@parca/components';
|
|
17
17
|
import { store } from '@parca/store';
|
|
18
|
+
import { capitalizeOnlyFirstLetter } from '@parca/utilities';
|
|
18
19
|
import { ProfileSelectionFromParams, SuffixParams } from '..';
|
|
19
20
|
import { useProfileTypes } from '../ProfileSelector';
|
|
20
21
|
import ProfileExplorerCompare from './ProfileExplorerCompare';
|
|
21
22
|
import ProfileExplorerSingle from './ProfileExplorerSingle';
|
|
23
|
+
const ErrorContent = ({ errorMessage }) => {
|
|
24
|
+
return (_jsx("div", { className: "relative rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700", role: "alert", children: _jsx("span", { className: "block sm:inline", children: errorMessage }) }));
|
|
25
|
+
};
|
|
22
26
|
const getExpressionAsAString = (expression) => {
|
|
23
27
|
const x = Array.isArray(expression) ? expression.join() : expression;
|
|
24
28
|
return x;
|
|
@@ -45,10 +49,10 @@ const swapQueryParameters = (o) => {
|
|
|
45
49
|
};
|
|
46
50
|
const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
47
51
|
const { loading: profileTypesLoading, data: profileTypesData, error: profileTypesError, } = useProfileTypes(queryClient);
|
|
48
|
-
const { loader, noDataPrompt, onError } = useParcaContext();
|
|
52
|
+
const { loader, noDataPrompt, onError, authenticationErrorMessage } = useParcaContext();
|
|
49
53
|
useEffect(() => {
|
|
50
54
|
if (profileTypesError !== undefined && profileTypesError !== null) {
|
|
51
|
-
onError?.(profileTypesError
|
|
55
|
+
onError?.(profileTypesError);
|
|
52
56
|
}
|
|
53
57
|
}, [profileTypesError, onError]);
|
|
54
58
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
@@ -83,7 +87,10 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
83
87
|
return _jsx(_Fragment, { children: noDataPrompt });
|
|
84
88
|
}
|
|
85
89
|
if (profileTypesError !== undefined && profileTypesError !== null) {
|
|
86
|
-
|
|
90
|
+
if (authenticationErrorMessage !== undefined && profileTypesError.code === 'UNAUTHENTICATED') {
|
|
91
|
+
return _jsx(ErrorContent, { errorMessage: authenticationErrorMessage });
|
|
92
|
+
}
|
|
93
|
+
return _jsx(ErrorContent, { errorMessage: capitalizeOnlyFirstLetter(profileTypesError.message) });
|
|
87
94
|
}
|
|
88
95
|
const sanitizedRange = sanitizeDateRange(time_selection_a, from_a, to_a);
|
|
89
96
|
time_selection_a = sanitizedRange.time_selection_a;
|
|
@@ -16,11 +16,14 @@ import { Menu, Transition } from '@headlessui/react';
|
|
|
16
16
|
import { Icon } from '@iconify/react';
|
|
17
17
|
import { Button, Select, useParcaContext, useURLState } from '@parca/components';
|
|
18
18
|
import { USER_PREFERENCES, useUserPreference } from '@parca/hooks';
|
|
19
|
-
import { divide, selectQueryParam } from '@parca/utilities';
|
|
19
|
+
import { capitalizeOnlyFirstLetter, divide, selectQueryParam, } from '@parca/utilities';
|
|
20
20
|
import DiffLegend from '../components/DiffLegend';
|
|
21
21
|
import IcicleGraph from './IcicleGraph';
|
|
22
22
|
import IcicleGraphArrow, { FIELD_CUMULATIVE, FIELD_DIFF, FIELD_FUNCTION_NAME, FIELD_LABELS, } from './IcicleGraphArrow';
|
|
23
23
|
const numberFormatter = new Intl.NumberFormat('en-US');
|
|
24
|
+
const ErrorContent = ({ errorMessage }) => {
|
|
25
|
+
return _jsx("div", { className: "flex justify-center p-10", children: errorMessage });
|
|
26
|
+
};
|
|
24
27
|
const ShowHideLegendButton = ({ navigateTo }) => {
|
|
25
28
|
const [colorStackLegend, setStoreColorStackLegend] = useURLState({
|
|
26
29
|
param: 'color_stack_legend',
|
|
@@ -64,7 +67,7 @@ const GroupAndSortActionButtons = ({ navigateTo }) => {
|
|
|
64
67
|
return (_jsxs(_Fragment, { children: [_jsx(GroupByDropdown, { groupBy: groupBy, toggleGroupBy: toggleGroupBy }), _jsx(SortBySelect, { compareMode: compareMode, sortBy: storeSortBy, setSortBy: setStoreSortBy })] }));
|
|
65
68
|
};
|
|
66
69
|
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, width, }) {
|
|
67
|
-
const { loader } = useParcaContext();
|
|
70
|
+
const { loader, onError, authenticationErrorMessage } = useParcaContext();
|
|
68
71
|
const compareMode = selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
69
72
|
const [storeSortBy = FIELD_FUNCTION_NAME] = useURLState({
|
|
70
73
|
param: 'sort_by',
|
|
@@ -98,8 +101,11 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, to
|
|
|
98
101
|
return _jsx("div", { className: "h-96", children: loader });
|
|
99
102
|
}
|
|
100
103
|
if (error != null) {
|
|
101
|
-
|
|
102
|
-
|
|
104
|
+
onError?.(error);
|
|
105
|
+
if (authenticationErrorMessage !== undefined && error.code === 'UNAUTHENTICATED') {
|
|
106
|
+
return _jsx(ErrorContent, { errorMessage: authenticationErrorMessage });
|
|
107
|
+
}
|
|
108
|
+
return _jsx(ErrorContent, { errorMessage: capitalizeOnlyFirstLetter(error.message) });
|
|
103
109
|
}
|
|
104
110
|
if (graph === undefined && arrow === undefined)
|
|
105
111
|
return _jsx("div", { className: "mx-auto text-center", children: "No data..." });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
// Copyright 2022 The Parca Authors
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -15,10 +15,13 @@ import { useEffect, useState } from 'react';
|
|
|
15
15
|
import { Duration, Timestamp } from '@parca/client';
|
|
16
16
|
import { useGrpcMetadata, useParcaContext } from '@parca/components';
|
|
17
17
|
import { Query } from '@parca/parser';
|
|
18
|
-
import { getStepDuration } from '@parca/utilities';
|
|
18
|
+
import { capitalizeOnlyFirstLetter, getStepDuration } from '@parca/utilities';
|
|
19
19
|
import MetricsGraph from '../MetricsGraph';
|
|
20
20
|
import { useMetricsGraphDimensions } from '../MetricsGraph/useMetricsGraphDimensions';
|
|
21
21
|
import useDelayedLoader from '../useDelayedLoader';
|
|
22
|
+
const ErrorContent = ({ errorMessage }) => {
|
|
23
|
+
return (_jsx("div", { className: "relative rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700", role: "alert", children: _jsx("span", { className: "block sm:inline", children: errorMessage }) }));
|
|
24
|
+
};
|
|
22
25
|
export const ProfileMetricsEmptyState = ({ message }) => {
|
|
23
26
|
return (_jsx("div", { className: "flex h-full w-full flex-col items-center justify-center", children: _jsx("p", { children: message }) }));
|
|
24
27
|
};
|
|
@@ -58,11 +61,11 @@ export const useQueryRange = (client, queryExpression, start, end) => {
|
|
|
58
61
|
const ProfileMetricsGraph = ({ queryClient, queryExpression, profile, from, to, setTimeRange, addLabelMatcher, onPointClick, comparing = false, }) => {
|
|
59
62
|
const { isLoading, response, error } = useQueryRange(queryClient, queryExpression, from, to);
|
|
60
63
|
const isLoaderVisible = useDelayedLoader(isLoading);
|
|
61
|
-
const { loader, onError, perf } = useParcaContext();
|
|
64
|
+
const { loader, onError, perf, authenticationErrorMessage } = useParcaContext();
|
|
62
65
|
const { width, height, margin } = useMetricsGraphDimensions(comparing);
|
|
63
66
|
useEffect(() => {
|
|
64
67
|
if (error !== null) {
|
|
65
|
-
onError?.(error
|
|
68
|
+
onError?.(error);
|
|
66
69
|
}
|
|
67
70
|
}, [error, onError]);
|
|
68
71
|
useEffect(() => {
|
|
@@ -77,7 +80,10 @@ const ProfileMetricsGraph = ({ queryClient, queryExpression, profile, from, to,
|
|
|
77
80
|
return _jsx(_Fragment, { children: loader });
|
|
78
81
|
}
|
|
79
82
|
if (error !== null) {
|
|
80
|
-
|
|
83
|
+
if (authenticationErrorMessage !== undefined && error.code === 'UNAUTHENTICATED') {
|
|
84
|
+
return _jsx(ErrorContent, { errorMessage: authenticationErrorMessage });
|
|
85
|
+
}
|
|
86
|
+
return _jsx(ErrorContent, { errorMessage: capitalizeOnlyFirstLetter(error.message) });
|
|
81
87
|
}
|
|
82
88
|
if (dataAvailable) {
|
|
83
89
|
const handleSampleClick = (timestamp, _value, labels) => {
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parca/profile",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.254",
|
|
4
4
|
"description": "Profile viewing libraries",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@parca/client": "^0.16.86",
|
|
7
|
-
"@parca/components": "^0.16.
|
|
7
|
+
"@parca/components": "^0.16.192",
|
|
8
8
|
"@parca/dynamicsize": "^0.16.54",
|
|
9
9
|
"@parca/hooks": "^0.0.23",
|
|
10
10
|
"@parca/parser": "^0.16.55",
|
|
11
|
-
"@parca/store": "^0.16.
|
|
12
|
-
"@parca/utilities": "^0.0.
|
|
11
|
+
"@parca/store": "^0.16.103",
|
|
12
|
+
"@parca/utilities": "^0.0.31",
|
|
13
13
|
"@tanstack/react-query": "^4.0.5",
|
|
14
14
|
"@types/react-beautiful-dnd": "^13.1.3",
|
|
15
15
|
"apache-arrow": "^12.0.0",
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"access": "public",
|
|
50
50
|
"registry": "https://registry.npmjs.org/"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "0ca31b9ddf1c2db1ccd5cd3c5e7d7f0e572299fd"
|
|
53
53
|
}
|
|
@@ -18,7 +18,7 @@ import {Provider} from 'react-redux';
|
|
|
18
18
|
import {QueryServiceClient} from '@parca/client';
|
|
19
19
|
import {DateTimeRange, KeyDownProvider, useParcaContext} from '@parca/components';
|
|
20
20
|
import {store} from '@parca/store';
|
|
21
|
-
import type
|
|
21
|
+
import {capitalizeOnlyFirstLetter, type NavigateFunction} from '@parca/utilities';
|
|
22
22
|
|
|
23
23
|
import {ProfileSelection, ProfileSelectionFromParams, SuffixParams} from '..';
|
|
24
24
|
import {QuerySelection, useProfileTypes} from '../ProfileSelector';
|
|
@@ -31,6 +31,17 @@ interface ProfileExplorerProps {
|
|
|
31
31
|
navigateTo: NavigateFunction;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
const ErrorContent = ({errorMessage}: {errorMessage: string}): JSX.Element => {
|
|
35
|
+
return (
|
|
36
|
+
<div
|
|
37
|
+
className="relative rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700"
|
|
38
|
+
role="alert"
|
|
39
|
+
>
|
|
40
|
+
<span className="block sm:inline">{errorMessage}</span>
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
34
45
|
const getExpressionAsAString = (expression: string | []): string => {
|
|
35
46
|
const x = Array.isArray(expression) ? expression.join() : expression;
|
|
36
47
|
return x;
|
|
@@ -81,11 +92,11 @@ const ProfileExplorerApp = ({
|
|
|
81
92
|
error: profileTypesError,
|
|
82
93
|
} = useProfileTypes(queryClient);
|
|
83
94
|
|
|
84
|
-
const {loader, noDataPrompt, onError} = useParcaContext();
|
|
95
|
+
const {loader, noDataPrompt, onError, authenticationErrorMessage} = useParcaContext();
|
|
85
96
|
|
|
86
97
|
useEffect(() => {
|
|
87
98
|
if (profileTypesError !== undefined && profileTypesError !== null) {
|
|
88
|
-
onError?.(profileTypesError
|
|
99
|
+
onError?.(profileTypesError);
|
|
89
100
|
}
|
|
90
101
|
}, [profileTypesError, onError]);
|
|
91
102
|
|
|
@@ -166,15 +177,11 @@ const ProfileExplorerApp = ({
|
|
|
166
177
|
}
|
|
167
178
|
|
|
168
179
|
if (profileTypesError !== undefined && profileTypesError !== null) {
|
|
169
|
-
|
|
170
|
-
<
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
<strong className="font-bold">Error! </strong>
|
|
175
|
-
<span className="block sm:inline">{profileTypesError.message}</span>
|
|
176
|
-
</div>
|
|
177
|
-
);
|
|
180
|
+
if (authenticationErrorMessage !== undefined && profileTypesError.code === 'UNAUTHENTICATED') {
|
|
181
|
+
return <ErrorContent errorMessage={authenticationErrorMessage} />;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return <ErrorContent errorMessage={capitalizeOnlyFirstLetter(profileTypesError.message)} />;
|
|
178
185
|
}
|
|
179
186
|
|
|
180
187
|
const sanitizedRange = sanitizeDateRange(time_selection_a, from_a, to_a);
|
|
@@ -19,7 +19,12 @@ import {Icon} from '@iconify/react';
|
|
|
19
19
|
import {Flamegraph, FlamegraphArrow} from '@parca/client';
|
|
20
20
|
import {Button, Select, useParcaContext, useURLState} from '@parca/components';
|
|
21
21
|
import {USER_PREFERENCES, useUserPreference} from '@parca/hooks';
|
|
22
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
capitalizeOnlyFirstLetter,
|
|
24
|
+
divide,
|
|
25
|
+
selectQueryParam,
|
|
26
|
+
type NavigateFunction,
|
|
27
|
+
} from '@parca/utilities';
|
|
23
28
|
|
|
24
29
|
import DiffLegend from '../components/DiffLegend';
|
|
25
30
|
import IcicleGraph from './IcicleGraph';
|
|
@@ -49,6 +54,10 @@ interface ProfileIcicleGraphProps {
|
|
|
49
54
|
error?: any;
|
|
50
55
|
}
|
|
51
56
|
|
|
57
|
+
const ErrorContent = ({errorMessage}: {errorMessage: string}): JSX.Element => {
|
|
58
|
+
return <div className="flex justify-center p-10">{errorMessage}</div>;
|
|
59
|
+
};
|
|
60
|
+
|
|
52
61
|
const ShowHideLegendButton = ({navigateTo}: {navigateTo?: NavigateFunction}): JSX.Element => {
|
|
53
62
|
const [colorStackLegend, setStoreColorStackLegend] = useURLState({
|
|
54
63
|
param: 'color_stack_legend',
|
|
@@ -152,7 +161,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
152
161
|
error,
|
|
153
162
|
width,
|
|
154
163
|
}: ProfileIcicleGraphProps): JSX.Element {
|
|
155
|
-
const {loader} = useParcaContext();
|
|
164
|
+
const {loader, onError, authenticationErrorMessage} = useParcaContext();
|
|
156
165
|
const compareMode: boolean =
|
|
157
166
|
selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
158
167
|
|
|
@@ -217,8 +226,13 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
217
226
|
}
|
|
218
227
|
|
|
219
228
|
if (error != null) {
|
|
220
|
-
|
|
221
|
-
|
|
229
|
+
onError?.(error);
|
|
230
|
+
|
|
231
|
+
if (authenticationErrorMessage !== undefined && error.code === 'UNAUTHENTICATED') {
|
|
232
|
+
return <ErrorContent errorMessage={authenticationErrorMessage} />;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return <ErrorContent errorMessage={capitalizeOnlyFirstLetter(error.message)} />;
|
|
222
236
|
}
|
|
223
237
|
|
|
224
238
|
if (graph === undefined && arrow === undefined)
|
|
@@ -18,7 +18,7 @@ import {RpcError} from '@protobuf-ts/runtime-rpc';
|
|
|
18
18
|
import {Duration, Label, QueryRangeResponse, QueryServiceClient, Timestamp} from '@parca/client';
|
|
19
19
|
import {DateTimeRange, useGrpcMetadata, useParcaContext} from '@parca/components';
|
|
20
20
|
import {Query} from '@parca/parser';
|
|
21
|
-
import {getStepDuration} from '@parca/utilities';
|
|
21
|
+
import {capitalizeOnlyFirstLetter, getStepDuration} from '@parca/utilities';
|
|
22
22
|
|
|
23
23
|
import {MergedProfileSelection, ProfileSelection} from '..';
|
|
24
24
|
import MetricsGraph from '../MetricsGraph';
|
|
@@ -29,6 +29,17 @@ interface ProfileMetricsEmptyStateProps {
|
|
|
29
29
|
message: string;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
const ErrorContent = ({errorMessage}: {errorMessage: string}): JSX.Element => {
|
|
33
|
+
return (
|
|
34
|
+
<div
|
|
35
|
+
className="relative rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700"
|
|
36
|
+
role="alert"
|
|
37
|
+
>
|
|
38
|
+
<span className="block sm:inline">{errorMessage}</span>
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
32
43
|
export const ProfileMetricsEmptyState = ({message}: ProfileMetricsEmptyStateProps): JSX.Element => {
|
|
33
44
|
return (
|
|
34
45
|
<div className="flex h-full w-full flex-col items-center justify-center">
|
|
@@ -114,12 +125,12 @@ const ProfileMetricsGraph = ({
|
|
|
114
125
|
}: ProfileMetricsGraphProps): JSX.Element => {
|
|
115
126
|
const {isLoading, response, error} = useQueryRange(queryClient, queryExpression, from, to);
|
|
116
127
|
const isLoaderVisible = useDelayedLoader(isLoading);
|
|
117
|
-
const {loader, onError, perf} = useParcaContext();
|
|
128
|
+
const {loader, onError, perf, authenticationErrorMessage} = useParcaContext();
|
|
118
129
|
const {width, height, margin} = useMetricsGraphDimensions(comparing);
|
|
119
130
|
|
|
120
131
|
useEffect(() => {
|
|
121
132
|
if (error !== null) {
|
|
122
|
-
onError?.(error
|
|
133
|
+
onError?.(error);
|
|
123
134
|
}
|
|
124
135
|
}, [error, onError]);
|
|
125
136
|
|
|
@@ -139,15 +150,11 @@ const ProfileMetricsGraph = ({
|
|
|
139
150
|
}
|
|
140
151
|
|
|
141
152
|
if (error !== null) {
|
|
142
|
-
|
|
143
|
-
<
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
<strong className="font-bold">Error! </strong>
|
|
148
|
-
<span className="block sm:inline">{error.message}</span>
|
|
149
|
-
</div>
|
|
150
|
-
);
|
|
153
|
+
if (authenticationErrorMessage !== undefined && error.code === 'UNAUTHENTICATED') {
|
|
154
|
+
return <ErrorContent errorMessage={authenticationErrorMessage} />;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return <ErrorContent errorMessage={capitalizeOnlyFirstLetter(error.message)} />;
|
|
151
158
|
}
|
|
152
159
|
|
|
153
160
|
if (dataAvailable) {
|