@parca/profile 0.16.413 → 0.16.414

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.414](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.413...@parca/profile@0.16.414) (2024-07-22)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
6
10
  ## [0.16.413](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.412...@parca/profile@0.16.413) (2024-07-22)
7
11
 
8
12
  **Note:** Version bump only for package @parca/profile
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/MatchersInput/index.tsx"],"names":[],"mappings":"AAkBA,OAAO,EAAgB,cAAc,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAEhF,OAAO,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AAKpC,UAAU,kBAAkB;IAC1B,WAAW,EAAE,kBAAkB,CAAC;IAChC,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,EAAE,KAAK,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,UAAU,aAAa;IACrB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,aAAa,WAChB,kBAAkB,eACb,MAAM,UACX,MAAM,QACR,MAAM,KACX,aA4BF,CAAC;AAEF,QAAA,MAAM,aAAa,6EAMhB,kBAAkB,KAAG,GAAG,CAAC,OAoL3B,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/MatchersInput/index.tsx"],"names":[],"mappings":"AAkBA,OAAO,EAAgB,cAAc,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAEhF,OAAO,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AAMpC,UAAU,kBAAkB;IAC1B,WAAW,EAAE,kBAAkB,CAAC;IAChC,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,EAAE,KAAK,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,UAAU,aAAa;IACrB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,aAAa,WAChB,kBAAkB,eACb,MAAM,UACX,MAAM,QACR,MAAM,KACX,aAyBF,CAAC;AAEF,QAAA,MAAM,aAAa,6EAMhB,kBAAkB,KAAG,GAAG,CAAC,OAoL3B,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -17,31 +17,31 @@ import TextareaAutosize from 'react-textarea-autosize';
17
17
  import { useGrpcMetadata } from '@parca/components';
18
18
  import { Query } from '@parca/parser';
19
19
  import { millisToProtoTimestamp, sanitizeLabelValue } from '@parca/utilities';
20
+ import useGrpcQuery from '../useGrpcQuery';
20
21
  import SuggestionsList, { Suggestion, Suggestions } from './SuggestionsList';
21
22
  export const useLabelNames = (client, profileType, start, end) => {
22
- const [loading, setLoading] = useState(true);
23
- const [result, setResult] = useState({});
24
23
  const metadata = useGrpcMetadata();
25
- useEffect(() => {
26
- if (profileType === undefined || profileType === '') {
27
- return;
28
- }
29
- const request = { match: [] };
30
- if (start !== undefined && end !== undefined) {
31
- request.start = millisToProtoTimestamp(start);
32
- request.end = millisToProtoTimestamp(end);
33
- }
34
- if (profileType !== undefined) {
35
- request.profileType = profileType;
36
- }
37
- const call = client.labels(request, { meta: metadata });
38
- setLoading(true);
39
- call.response
40
- .then(response => setResult({ response }))
41
- .catch(error => setResult({ error }))
42
- .finally(() => setLoading(false));
43
- }, [client, metadata, start, end, profileType]);
44
- return { result, loading };
24
+ const { data, isLoading, error } = useGrpcQuery({
25
+ key: ['labelNames', profileType],
26
+ queryFn: async () => {
27
+ const request = { match: [] };
28
+ if (start !== undefined && end !== undefined) {
29
+ request.start = millisToProtoTimestamp(start);
30
+ request.end = millisToProtoTimestamp(end);
31
+ }
32
+ if (profileType !== undefined) {
33
+ request.profileType = profileType;
34
+ }
35
+ const { response } = await client.labels(request, { meta: metadata });
36
+ return response;
37
+ },
38
+ options: {
39
+ enabled: profileType !== undefined && profileType !== '',
40
+ staleTime: 1000 * 60 * 5, // 5 minutes
41
+ keepPreviousData: false,
42
+ },
43
+ });
44
+ return { result: { response: data, error: error }, loading: isLoading };
45
45
  };
46
46
  const MatchersInput = ({ queryClient, setMatchersString, runQuery, currentQuery, profileType, }) => {
47
47
  const inputRef = useRef(null);
@@ -9,7 +9,6 @@ export declare const ProfileMetricsEmptyState: ({ message }: ProfileMetricsEmpty
9
9
  interface ProfileMetricsGraphProps {
10
10
  queryClient: QueryServiceClient;
11
11
  queryExpression: string;
12
- dirtyQueryExpression: string;
13
12
  profile: ProfileSelection | null;
14
13
  from: number;
15
14
  to: number;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileMetricsGraph/index.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAGlD,OAAO,EAAW,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAY,MAAM,eAAe,CAAC;AACjG,OAAO,EACL,aAAa,EAKd,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAyB,gBAAgB,EAAC,MAAM,IAAI,CAAC;AAK5D,UAAU,6BAA6B;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAaD,eAAO,MAAM,wBAAwB,gBAAe,6BAA6B,KAAG,GAAG,CAAC,OAMvF,CAAC;AAEF,UAAU,wBAAwB;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,eAAe,EAAE,CACf,MAAM,EAAE;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,GAAG,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC,KACvE,IAAI,CAAC;IACV,YAAY,EAAE,CACZ,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,KAAK,EAAE,EACf,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,KACb,IAAI,CAAC;IACV,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CACxB;AAYD,eAAO,MAAM,aAAa,WAChB,kBAAkB,mBACT,MAAM,SAChB,MAAM,OACR,MAAM,SACJ,MAAM,EAAE,qBAEd,gBA+CF,CAAC;AAEF,QAAA,MAAM,mBAAmB,sIAYtB,wBAAwB,KAAG,GAAG,CAAC,OAqFjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileMetricsGraph/index.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAGlD,OAAO,EAAW,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAY,MAAM,eAAe,CAAC;AACjG,OAAO,EACL,aAAa,EAKd,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAyB,gBAAgB,EAAC,MAAM,IAAI,CAAC;AAK5D,UAAU,6BAA6B;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAaD,eAAO,MAAM,wBAAwB,gBAAe,6BAA6B,KAAG,GAAG,CAAC,OAMvF,CAAC;AAEF,UAAU,wBAAwB;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,eAAe,EAAE,CACf,MAAM,EAAE;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,GAAG,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC,KACvE,IAAI,CAAC;IACV,YAAY,EAAE,CACZ,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,KAAK,EAAE,EACf,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,KACb,IAAI,CAAC;IACV,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CACxB;AAYD,eAAO,MAAM,aAAa,WAChB,kBAAkB,mBACT,MAAM,SAChB,MAAM,OACR,MAAM,SACJ,MAAM,EAAE,qBAEd,gBA+CF,CAAC;AAEF,QAAA,MAAM,mBAAmB,sIAYtB,wBAAwB,KAAG,GAAG,CAAC,OAqFjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileSelector/index.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAGlD,OAAO,EAAQ,oBAAoB,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAY9E,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAyB,gBAAgB,EAAC,MAAM,IAAI,CAAC;AAQ5D,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,oBAAoB;IAC5B,WAAW,EAAE,kBAAkB,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,aAAa,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAClD,WAAW,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED,eAAO,MAAM,eAAe,WAAY,kBAAkB,KAAG,mBAkB5D,CAAC;AAEF,QAAA,MAAM,eAAe,qJAWlB,oBAAoB,KAAG,GAAG,CAAC,OAsT7B,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileSelector/index.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAC;AAGlD,OAAO,EAAQ,oBAAoB,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAY9E,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAyB,gBAAgB,EAAC,MAAM,IAAI,CAAC;AAQ5D,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,oBAAoB;IAC5B,WAAW,EAAE,kBAAkB,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,aAAa,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAClD,WAAW,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED,eAAO,MAAM,eAAe,WAAY,kBAAkB,KAAG,mBAkB5D,CAAC;AAEF,QAAA,MAAM,eAAe,qJAWlB,oBAAoB,KAAG,GAAG,CAAC,OAiU7B,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -49,19 +49,27 @@ const ProfileSelector = ({ queryClient, querySelection, selectProfile, selectQue
49
49
  const profileType = useMemo(() => {
50
50
  return Query.parse(queryExpressionString).profileType();
51
51
  }, [queryExpressionString]);
52
+ const selectedProfileType = useMemo(() => {
53
+ return Query.parse(querySelection.expression).profileType();
54
+ }, [querySelection.expression]);
52
55
  const { loading: labelNamesLoading, result } = useLabelNames(queryClient, profileType.toString());
56
+ const { loading: selectedLabelNamesLoading, result: selectedLabelNamesResult } = useLabelNames(queryClient, selectedProfileType.toString());
53
57
  const labels = useMemo(() => {
54
58
  return result.response?.labelNames === undefined ? [] : result.response.labelNames;
55
59
  }, [result]);
56
- const [sumBy, setSumBy, userSelectedSumBy] = useSumBy(profileType, labelNamesLoading, result.response?.labelNames, {
60
+ const selectedLabels = useMemo(() => {
61
+ return selectedLabelNamesResult.response?.labelNames === undefined
62
+ ? []
63
+ : selectedLabelNamesResult.response.labelNames;
64
+ }, [selectedLabelNamesResult]);
65
+ const [sumBy, setSumBy, { userSelectedSumBy, isLoading: isSumByLoading }] = useSumBy(selectedProfileType, selectedLabelNamesLoading, selectedLabels, {
57
66
  urlParamKey: 'sum_by' + suffix,
58
67
  });
59
- const [sumBySelection, setSumBySelection] = useSumBy(profileType, labelNamesLoading, result.response?.labelNames, {
68
+ const [sumBySelection, setSumBySelection, { isLoading: isSumBySelectionLoading }] = useSumBy(profileType, labelNamesLoading, labels, {
60
69
  urlParamKey: 'sum_by_selection' + suffix,
61
70
  withURLUpdate: false,
62
71
  defaultValue: userSelectedSumBy,
63
72
  });
64
- const sumByLoading = labelNamesLoading;
65
73
  useEffect(() => {
66
74
  if (enforcedProfileName !== '') {
67
75
  const [q, changed] = Query.parse(querySelection.expression).setProfileName(enforcedProfileName);
@@ -80,7 +88,7 @@ const ProfileSelector = ({ queryClient, querySelection, selectProfile, selectQue
80
88
  const query = enforcedProfileName !== '' ? enforcedProfileNameQuery() : Query.parse(queryExpressionString);
81
89
  const selectedProfileName = query.profileName();
82
90
  const setNewQueryExpression = (expr, updateTs = false) => {
83
- if (!sumByLoading) {
91
+ if (!isSumBySelectionLoading) {
84
92
  setSumBy(sumBySelection);
85
93
  }
86
94
  const query = enforcedProfileName !== '' ? enforcedProfileNameQuery() : Query.parse(expr);
@@ -174,7 +182,7 @@ const ProfileSelector = ({ queryClient, querySelection, selectProfile, selectQue
174
182
  }, id: "h-matcher-search-button", 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 &&
175
183
  querySelection.expression.length > 0 &&
176
184
  querySelection.from !== undefined &&
177
- querySelection.to !== undefined ? (_jsx("div", { className: "p-2", children: _jsx(ProfileMetricsGraph, { queryClient: queryClient, queryExpression: querySelection.expression, dirtyQueryExpression: queryExpressionString, from: querySelection.from, to: querySelection.to, profile: profileSelection, comparing: comparing, sumBy: sumBy, sumByLoading: sumByLoading, setTimeRange: (range) => {
185
+ querySelection.to !== undefined ? (_jsx("div", { className: "p-2", children: _jsx(ProfileMetricsGraph, { queryClient: queryClient, queryExpression: querySelection.expression, from: querySelection.from, to: querySelection.to, profile: profileSelection, comparing: comparing, sumBy: sumBy, sumByLoading: isSumByLoading, setTimeRange: (range) => {
178
186
  const from = range.getFromMs();
179
187
  const to = range.getToMs();
180
188
  let mergedProfileParams = {};
@@ -6,8 +6,9 @@ interface Props<IRes> {
6
6
  enabled?: boolean | undefined;
7
7
  staleTime?: number | undefined;
8
8
  retry?: number | boolean;
9
+ keepPreviousData?: boolean | undefined;
9
10
  };
10
11
  }
11
- declare const useGrpcQuery: <IRes>({ key, queryFn, options: { enabled, staleTime, retry }, }: Props<IRes>) => UseQueryResult<IRes>;
12
+ declare const useGrpcQuery: <IRes>({ key, queryFn, options: { enabled, staleTime, retry, keepPreviousData }, }: Props<IRes>) => UseQueryResult<IRes>;
12
13
  export default useGrpcQuery;
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/useGrpcQuery/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAW,KAAK,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAEpE,UAAU,KAAK,CAAC,IAAI;IAClB,GAAG,EAAE,OAAO,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;KAC1B,CAAC;CACH;AAED,QAAA,MAAM,YAAY,GAAI,IAAI,6DAIvB,KAAK,CAAC,IAAI,CAAC,KAAG,cAAc,CAAC,IAAI,CAYnC,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/useGrpcQuery/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAW,KAAK,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAEpE,UAAU,KAAK,CAAC,IAAI;IAClB,GAAG,EAAE,OAAO,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QACzB,gBAAgB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KACxC,CAAC;CACH;AAED,QAAA,MAAM,YAAY,GAAI,IAAI,+EAIvB,KAAK,CAAC,IAAI,CAAC,KAAG,cAAc,CAAC,IAAI,CAanC,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -11,13 +11,14 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
  import { useQuery } from '@tanstack/react-query';
14
- const useGrpcQuery = ({ key, queryFn, options: { enabled = true, staleTime, retry } = {}, }) => {
14
+ const useGrpcQuery = ({ key, queryFn, options: { enabled = true, staleTime, retry, keepPreviousData } = {}, }) => {
15
15
  return useQuery(key, async () => {
16
16
  return await queryFn();
17
17
  }, {
18
18
  enabled,
19
19
  staleTime,
20
20
  retry,
21
+ keepPreviousData,
21
22
  });
22
23
  };
23
24
  export default useGrpcQuery;
@@ -4,5 +4,8 @@ export declare const useSumBy: (profileType: ProfileType | undefined, labelNames
4
4
  urlParamKey?: string;
5
5
  withURLUpdate?: boolean;
6
6
  defaultValue?: string[];
7
- }) => [string[], (labels: string[]) => void, string[] | undefined];
7
+ }) => [string[], (labels: string[]) => void, {
8
+ userSelectedSumBy: string[] | undefined;
9
+ isLoading: boolean;
10
+ }];
8
11
  //# sourceMappingURL=useSumBy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSumBy.d.ts","sourceRoot":"","sources":["../src/useSumBy.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,eAAO,MAAM,oBAAoB,EAAE,MAAM,EAAO,CAAC;AAyBjD,eAAO,MAAM,QAAQ,gBACN,WAAW,GAAG,SAAS,qBACjB,OAAO,UAClB,MAAM,EAAE,GAAG,SAAS,kDAKzB;IACD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,KACA,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,CAkE7D,CAAC"}
1
+ {"version":3,"file":"useSumBy.d.ts","sourceRoot":"","sources":["../src/useSumBy.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,eAAO,MAAM,oBAAoB,EAAE,MAAM,EAAO,CAAC;AAyBjD,eAAO,MAAM,QAAQ,gBACN,WAAW,GAAG,SAAS,qBACjB,OAAO,UAClB,MAAM,EAAE,GAAG,SAAS,kDAKzB;IACD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,KACA,CACD,MAAM,EAAE,EACR,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,EAC1B;IAAC,iBAAiB,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAC,CA4D9D,CAAC"}
package/dist/useSumBy.js CHANGED
@@ -10,7 +10,7 @@
10
10
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
- import { useCallback, useEffect, useMemo, useState } from 'react';
13
+ import { useCallback, useMemo } from 'react';
14
14
  import { useParcaContext, useURLState } from '@parca/components';
15
15
  export const DEFAULT_EMPTY_SUM_BY = [];
16
16
  const getDefaultSumBy = (profile, labels) => {
@@ -63,16 +63,12 @@ export const useSumBy = (profileType, labelNamesLoading, labels, { urlParamKey =
63
63
  }
64
64
  setUserSelectedSumByParam(sumBy);
65
65
  }, [setUserSelectedSumByParam]);
66
- const [defaultSumBy, setDefaultSumBy] = useState(getDefaultSumBy(profileType, labels));
67
- useEffect(() => {
68
- if (labelNamesLoading) {
69
- return;
70
- }
71
- setDefaultSumBy(getDefaultSumBy(profileType, labels));
72
- }, [profileType, labels, labelNamesLoading]);
66
+ const defaultSumBy = useMemo(() => {
67
+ return getDefaultSumBy(profileType, labels);
68
+ }, [profileType, labels]);
73
69
  let sumBy = userSelectedSumBy ?? defaultSumBy ?? DEFAULT_EMPTY_SUM_BY;
74
70
  if (profileType?.delta !== true) {
75
- sumBy = [];
71
+ sumBy = DEFAULT_EMPTY_SUM_BY;
76
72
  }
77
- return [sumBy, setUserSelectedSumBy, userSelectedSumBy];
73
+ return [sumBy, setUserSelectedSumBy, { userSelectedSumBy, isLoading: labelNamesLoading }];
78
74
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parca/profile",
3
- "version": "0.16.413",
3
+ "version": "0.16.414",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@headlessui/react": "^1.7.19",
@@ -73,5 +73,5 @@
73
73
  "access": "public",
74
74
  "registry": "https://registry.npmjs.org/"
75
75
  },
76
- "gitHead": "8b3121b9f7c20b041cf55ca866260acbe0bd70c2"
76
+ "gitHead": "7344e3c5687b4d9a5c93b6c44494592726fcba23"
77
77
  }
@@ -21,6 +21,7 @@ import {useGrpcMetadata} from '@parca/components';
21
21
  import {Query} from '@parca/parser';
22
22
  import {millisToProtoTimestamp, sanitizeLabelValue} from '@parca/utilities';
23
23
 
24
+ import useGrpcQuery from '../useGrpcQuery';
24
25
  import SuggestionsList, {Suggestion, Suggestions} from './SuggestionsList';
25
26
 
26
27
  interface MatchersInputProps {
@@ -47,33 +48,30 @@ export const useLabelNames = (
47
48
  start?: number,
48
49
  end?: number
49
50
  ): UseLabelNames => {
50
- const [loading, setLoading] = useState(true);
51
- const [result, setResult] = useState<ILabelNamesResult>({});
52
51
  const metadata = useGrpcMetadata();
53
52
 
54
- useEffect(() => {
55
- if (profileType === undefined || profileType === '') {
56
- return;
57
- }
58
-
59
- const request: LabelsRequest = {match: []};
60
- if (start !== undefined && end !== undefined) {
61
- request.start = millisToProtoTimestamp(start);
62
- request.end = millisToProtoTimestamp(end);
63
- }
64
- if (profileType !== undefined) {
65
- request.profileType = profileType;
66
- }
67
- const call = client.labels(request, {meta: metadata});
68
- setLoading(true);
69
-
70
- call.response
71
- .then(response => setResult({response}))
72
- .catch(error => setResult({error}))
73
- .finally(() => setLoading(false));
74
- }, [client, metadata, start, end, profileType]);
75
-
76
- return {result, loading};
53
+ const {data, isLoading, error} = useGrpcQuery<LabelsResponse>({
54
+ key: ['labelNames', profileType],
55
+ queryFn: async () => {
56
+ const request: LabelsRequest = {match: []};
57
+ if (start !== undefined && end !== undefined) {
58
+ request.start = millisToProtoTimestamp(start);
59
+ request.end = millisToProtoTimestamp(end);
60
+ }
61
+ if (profileType !== undefined) {
62
+ request.profileType = profileType;
63
+ }
64
+ const {response} = await client.labels(request, {meta: metadata});
65
+ return response;
66
+ },
67
+ options: {
68
+ enabled: profileType !== undefined && profileType !== '',
69
+ staleTime: 1000 * 60 * 5, // 5 minutes
70
+ keepPreviousData: false,
71
+ },
72
+ });
73
+
74
+ return {result: {response: data, error: error as Error}, loading: isLoading};
77
75
  };
78
76
 
79
77
  const MatchersInput = ({
@@ -58,7 +58,6 @@ export const ProfileMetricsEmptyState = ({message}: ProfileMetricsEmptyStateProp
58
58
  interface ProfileMetricsGraphProps {
59
59
  queryClient: QueryServiceClient;
60
60
  queryExpression: string;
61
- dirtyQueryExpression: string;
62
61
  profile: ProfileSelection | null;
63
62
  from: number;
64
63
  to: number;
@@ -117,25 +117,39 @@ const ProfileSelector = ({
117
117
  return Query.parse(queryExpressionString).profileType();
118
118
  }, [queryExpressionString]);
119
119
 
120
+ const selectedProfileType = useMemo(() => {
121
+ return Query.parse(querySelection.expression).profileType();
122
+ }, [querySelection.expression]);
123
+
120
124
  const {loading: labelNamesLoading, result} = useLabelNames(queryClient, profileType.toString());
125
+ const {loading: selectedLabelNamesLoading, result: selectedLabelNamesResult} = useLabelNames(
126
+ queryClient,
127
+ selectedProfileType.toString()
128
+ );
121
129
 
122
130
  const labels = useMemo(() => {
123
131
  return result.response?.labelNames === undefined ? [] : result.response.labelNames;
124
132
  }, [result]);
125
133
 
126
- const [sumBy, setSumBy, userSelectedSumBy] = useSumBy(
127
- profileType,
128
- labelNamesLoading,
129
- result.response?.labelNames,
134
+ const selectedLabels = useMemo(() => {
135
+ return selectedLabelNamesResult.response?.labelNames === undefined
136
+ ? []
137
+ : selectedLabelNamesResult.response.labelNames;
138
+ }, [selectedLabelNamesResult]);
139
+
140
+ const [sumBy, setSumBy, {userSelectedSumBy, isLoading: isSumByLoading}] = useSumBy(
141
+ selectedProfileType,
142
+ selectedLabelNamesLoading,
143
+ selectedLabels,
130
144
  {
131
145
  urlParamKey: 'sum_by' + suffix,
132
146
  }
133
147
  );
134
148
 
135
- const [sumBySelection, setSumBySelection] = useSumBy(
149
+ const [sumBySelection, setSumBySelection, {isLoading: isSumBySelectionLoading}] = useSumBy(
136
150
  profileType,
137
151
  labelNamesLoading,
138
- result.response?.labelNames,
152
+ labels,
139
153
  {
140
154
  urlParamKey: 'sum_by_selection' + suffix,
141
155
  withURLUpdate: false,
@@ -143,8 +157,6 @@ const ProfileSelector = ({
143
157
  }
144
158
  );
145
159
 
146
- const sumByLoading = labelNamesLoading;
147
-
148
160
  useEffect(() => {
149
161
  if (enforcedProfileName !== '') {
150
162
  const [q, changed] = Query.parse(querySelection.expression).setProfileName(
@@ -169,7 +181,7 @@ const ProfileSelector = ({
169
181
  const selectedProfileName = query.profileName();
170
182
 
171
183
  const setNewQueryExpression = (expr: string, updateTs = false): void => {
172
- if (!sumByLoading) {
184
+ if (!isSumBySelectionLoading) {
173
185
  setSumBy(sumBySelection);
174
186
  }
175
187
  const query = enforcedProfileName !== '' ? enforcedProfileNameQuery() : Query.parse(expr);
@@ -345,13 +357,12 @@ const ProfileSelector = ({
345
357
  <ProfileMetricsGraph
346
358
  queryClient={queryClient}
347
359
  queryExpression={querySelection.expression}
348
- dirtyQueryExpression={queryExpressionString}
349
360
  from={querySelection.from}
350
361
  to={querySelection.to}
351
362
  profile={profileSelection}
352
363
  comparing={comparing}
353
364
  sumBy={sumBy}
354
- sumByLoading={sumByLoading}
365
+ sumByLoading={isSumByLoading}
355
366
  setTimeRange={(range: DateTimeRange) => {
356
367
  const from = range.getFromMs();
357
368
  const to = range.getToMs();
@@ -20,13 +20,14 @@ interface Props<IRes> {
20
20
  enabled?: boolean | undefined;
21
21
  staleTime?: number | undefined;
22
22
  retry?: number | boolean;
23
+ keepPreviousData?: boolean | undefined;
23
24
  };
24
25
  }
25
26
 
26
27
  const useGrpcQuery = <IRes>({
27
28
  key,
28
29
  queryFn,
29
- options: {enabled = true, staleTime, retry} = {},
30
+ options: {enabled = true, staleTime, retry, keepPreviousData} = {},
30
31
  }: Props<IRes>): UseQueryResult<IRes> => {
31
32
  return useQuery<IRes>(
32
33
  key,
@@ -37,6 +38,7 @@ const useGrpcQuery = <IRes>({
37
38
  enabled,
38
39
  staleTime,
39
40
  retry,
41
+ keepPreviousData,
40
42
  }
41
43
  );
42
44
  };
package/src/useSumBy.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
 
14
- import {useCallback, useEffect, useMemo, useState} from 'react';
14
+ import {useCallback, useMemo} from 'react';
15
15
 
16
16
  import {useParcaContext, useURLState} from '@parca/components';
17
17
  import {ProfileType} from '@parca/parser';
@@ -54,7 +54,11 @@ export const useSumBy = (
54
54
  withURLUpdate?: boolean;
55
55
  defaultValue?: string[];
56
56
  } = {}
57
- ): [string[], (labels: string[]) => void, string[] | undefined] => {
57
+ ): [
58
+ string[],
59
+ (labels: string[]) => void,
60
+ {userSelectedSumBy: string[] | undefined; isLoading: boolean}
61
+ ] => {
58
62
  const {navigateTo} = useParcaContext();
59
63
  const [userSelectedSumByParam, setUserSelectedSumByParam] = useURLState({
60
64
  param: urlParamKey,
@@ -102,22 +106,15 @@ export const useSumBy = (
102
106
  [setUserSelectedSumByParam]
103
107
  );
104
108
 
105
- const [defaultSumBy, setDefaultSumBy] = useState<string[] | undefined>(
106
- getDefaultSumBy(profileType, labels)
107
- );
108
-
109
- useEffect(() => {
110
- if (labelNamesLoading) {
111
- return;
112
- }
113
- setDefaultSumBy(getDefaultSumBy(profileType, labels));
114
- }, [profileType, labels, labelNamesLoading]);
109
+ const defaultSumBy = useMemo(() => {
110
+ return getDefaultSumBy(profileType, labels);
111
+ }, [profileType, labels]);
115
112
 
116
113
  let sumBy = userSelectedSumBy ?? defaultSumBy ?? DEFAULT_EMPTY_SUM_BY;
117
114
 
118
115
  if (profileType?.delta !== true) {
119
- sumBy = [];
116
+ sumBy = DEFAULT_EMPTY_SUM_BY;
120
117
  }
121
118
 
122
- return [sumBy, setUserSelectedSumBy, userSelectedSumBy];
119
+ return [sumBy, setUserSelectedSumBy, {userSelectedSumBy, isLoading: labelNamesLoading}];
123
120
  };