@parca/profile 0.14.29 → 0.14.36

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,43 @@
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.14.36](https://github.com/parca-dev/parca/compare/ui-v0.14.35...ui-v0.14.36) (2022-08-24)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **ui:** enforce @typescript-eslint/explicit-function-return-type ([22a18fd](https://github.com/parca-dev/parca/commit/22a18fd3f7befef5cc175131d8c997c3967a5713))
12
+
13
+
14
+
15
+ ## 0.14.32 (2022-08-18)
16
+
17
+
18
+
19
+
20
+
21
+ ## [0.14.31](https://github.com/parca-dev/parca/compare/ui-v0.14.30...ui-v0.14.31) (2022-08-18)
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * **ui:** address all problems reported by ESLint ([7f9c921](https://github.com/parca-dev/parca/commit/7f9c9217af49f2661a4363b9b17a9a06f1c7539b))
27
+
28
+
29
+
30
+
31
+
32
+ ## [0.14.30](https://github.com/parca-dev/parca/compare/ui-v0.14.29...ui-v0.14.30) (2022-08-17)
33
+
34
+
35
+ ### Bug Fixes
36
+
37
+ * **ui:** run eslint --fix ([#1542](https://github.com/parca-dev/parca/issues/1542)) ([e522131](https://github.com/parca-dev/parca/commit/e5221318fc1140d661c45d2d04b096bfebba4af4))
38
+
39
+
40
+
41
+
42
+
6
43
  ## [0.14.29](https://github.com/parca-dev/parca/compare/ui-v0.14.28...ui-v0.14.29) (2022-08-15)
7
44
 
8
45
 
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@parca/profile",
3
- "version": "0.14.29",
3
+ "version": "0.14.36",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@iconify/react": "^3.2.2",
7
7
  "@parca/client": "^0.14.16",
8
- "@parca/dynamicsize": "^0.14.29",
9
- "@parca/parser": "^0.14.29",
8
+ "@parca/dynamicsize": "^0.14.36",
9
+ "@parca/parser": "^0.14.36",
10
10
  "d3-scale": "^4.0.2",
11
11
  "d3-selection": "3.0.0",
12
12
  "react-copy-to-clipboard": "^5.1.0"
@@ -22,5 +22,5 @@
22
22
  "access": "public",
23
23
  "registry": "https://registry.npmjs.org/"
24
24
  },
25
- "gitHead": "e6dabbc59485409b1fc818d5c56c7999d9a22f17"
25
+ "gitHead": "7d75476b99eafbb9e9d3976c1de6cfb88cbfc8c2"
26
26
  }
@@ -91,7 +91,7 @@ function IcicleRect({
91
91
  onMouseLeave,
92
92
  onClick,
93
93
  curPath,
94
- }: IcicleRectProps) {
94
+ }: IcicleRectProps): JSX.Element {
95
95
  const currentSearchString = useAppSelector(selectSearchNodeString);
96
96
  const isFaded = curPath.length > 0 && name !== curPath[curPath.length - 1];
97
97
  const styles = isFaded ? fadedIcicleRectStyles : icicleRectStyles;
@@ -111,7 +111,11 @@ function IcicleRect({
111
111
  height={height - 1}
112
112
  style={{
113
113
  opacity:
114
- Boolean(currentSearchString) && !isSearchMatch(currentSearchString, name) ? 0.5 : 1,
114
+ currentSearchString !== undefined &&
115
+ currentSearchString !== '' &&
116
+ !isSearchMatch(currentSearchString, name)
117
+ ? 0.5
118
+ : 1,
115
119
  fill: color,
116
120
  }}
117
121
  />
@@ -130,7 +134,7 @@ export function nodeLabel(node: FlamegraphNode): string {
130
134
  if (node.meta === undefined) return '<unknown>';
131
135
  const mapping = `${
132
136
  node.meta?.mapping?.file !== undefined && node.meta?.mapping?.file !== ''
133
- ? '[' + getLastItem(node.meta.mapping.file) + '] '
137
+ ? '[' + (getLastItem(node.meta.mapping.file) ?? '') + '] '
134
138
  : ''
135
139
  }`;
136
140
  if (node.meta.function?.name !== undefined && node.meta.function?.name !== '')
@@ -154,7 +158,7 @@ export function IcicleGraphNodes({
154
158
  path,
155
159
  setCurPath,
156
160
  curPath,
157
- }: IcicleGraphNodesProps) {
161
+ }: IcicleGraphNodesProps): JSX.Element {
158
162
  const isDarkMode = useAppSelector(selectDarkMode);
159
163
 
160
164
  const nodes =
@@ -185,7 +189,7 @@ export function IcicleGraphNodes({
185
189
 
186
190
  const color = diffColor(diff, cumulative, isDarkMode);
187
191
 
188
- const onClick = () => {
192
+ const onClick = (): void => {
189
193
  setCurPath(nextPath);
190
194
  };
191
195
 
@@ -195,8 +199,8 @@ export function IcicleGraphNodes({
195
199
  ? scaleLinear().domain([0, cumulative]).range([0, totalWidth])
196
200
  : xScale;
197
201
 
198
- const onMouseEnter = () => setHoveringNode(d);
199
- const onMouseLeave = () => setHoveringNode(undefined);
202
+ const onMouseEnter = (): void => setHoveringNode(d);
203
+ const onMouseLeave = (): void => setHoveringNode(undefined);
200
204
 
201
205
  return (
202
206
  <React.Fragment key={`node-${key}`}>
@@ -246,16 +250,16 @@ export function IcicleGraphRootNode({
246
250
  setHoveringNode,
247
251
  setCurPath,
248
252
  curPath,
249
- }: IcicleGraphRootNodeProps) {
253
+ }: IcicleGraphRootNodeProps): JSX.Element {
250
254
  const isDarkMode = useAppSelector(selectDarkMode);
251
255
 
252
256
  const cumulative = parseFloat(node.cumulative);
253
257
  const diff = parseFloat(node.diff);
254
258
  const color = diffColor(diff, cumulative, isDarkMode);
255
259
 
256
- const onClick = () => setCurPath([]);
257
- const onMouseEnter = () => setHoveringNode(node);
258
- const onMouseLeave = () => setHoveringNode(undefined);
260
+ const onClick = (): void => setCurPath([]);
261
+ const onMouseEnter = (): void => setHoveringNode(node);
262
+ const onMouseLeave = (): void => setHoveringNode(undefined);
259
263
  const path = [];
260
264
 
261
265
  return (
@@ -297,7 +301,7 @@ export default function IcicleGraph({
297
301
  setCurPath,
298
302
  curPath,
299
303
  sampleUnit,
300
- }: IcicleGraphProps) {
304
+ }: IcicleGraphProps): JSX.Element {
301
305
  const [hoveringNode, setHoveringNode] = useState<
302
306
  FlamegraphNode | FlamegraphRootNode | undefined
303
307
  >();
@@ -31,7 +31,7 @@ const ProfileIcicleGraph = ({
31
31
  curPath,
32
32
  setNewCurPath,
33
33
  sampleUnit,
34
- }: ProfileIcicleGraphProps) => {
34
+ }: ProfileIcicleGraphProps): JSX.Element => {
35
35
  const compareMode = useAppSelector(selectCompareMode);
36
36
  const {ref, dimensions} = useContainerDimensions();
37
37
 
@@ -58,7 +58,7 @@ interface ProfileViewProps {
58
58
  compare?: boolean;
59
59
  }
60
60
 
61
- function arrayEquals(a, b): boolean {
61
+ function arrayEquals<T>(a: T[], b: T[]): boolean {
62
62
  return (
63
63
  Array.isArray(a) &&
64
64
  Array.isArray(b) &&
@@ -70,7 +70,7 @@ export const useProfileVisState = (): ProfileVisState => {
70
70
  const router = parseParams(window.location.search);
71
71
  const currentViewFromURL = router.currentProfileView as string;
72
72
  const [currentView, setCurrentView] = useState<VisualizationType>(
73
- (currentViewFromURL as VisualizationType) || 'icicle'
73
+ (currentViewFromURL as VisualizationType) ?? 'icicle'
74
74
  );
75
75
 
76
76
  return {currentView, setCurrentView};
@@ -98,13 +98,13 @@ export const ProfileView = ({
98
98
 
99
99
  const isLoading = useMemo(() => {
100
100
  if (currentView === 'icicle') {
101
- return !!flamegraphData?.loading;
101
+ return Boolean(flamegraphData?.loading);
102
102
  }
103
103
  if (currentView === 'table') {
104
- return !!topTableData?.loading;
104
+ return Boolean(topTableData?.loading);
105
105
  }
106
106
  if (currentView === 'both') {
107
- return !!flamegraphData?.loading || !!topTableData?.loading;
107
+ return Boolean(flamegraphData?.loading) || Boolean(topTableData?.loading);
108
108
  }
109
109
  return false;
110
110
  }, [currentView, flamegraphData?.loading, topTableData?.loading]);
@@ -124,9 +124,9 @@ export const ProfileView = ({
124
124
  );
125
125
  }
126
126
 
127
- const downloadPProf = async (e: React.MouseEvent<HTMLElement>) => {
127
+ const downloadPProf = async (e: React.MouseEvent<HTMLElement>): Promise<void> => {
128
128
  e.preventDefault();
129
- if (!profileSource || !queryClient) {
129
+ if (profileSource == null || queryClient == null) {
130
130
  return;
131
131
  }
132
132
 
@@ -141,15 +141,15 @@ export const ProfileView = ({
141
141
  }
142
142
  };
143
143
 
144
- const resetIcicleGraph = () => setCurPath([]);
144
+ const resetIcicleGraph = (): void => setCurPath([]);
145
145
 
146
- const setNewCurPath = (path: string[]) => {
146
+ const setNewCurPath = (path: string[]): void => {
147
147
  if (!arrayEquals(curPath, path)) {
148
148
  setCurPath(path);
149
149
  }
150
150
  };
151
151
 
152
- const switchProfileView = (view: VisualizationType) => {
152
+ const switchProfileView = (view: VisualizationType): void => {
153
153
  if (view == null) {
154
154
  return;
155
155
  }
@@ -169,14 +169,14 @@ export const ProfileView = ({
169
169
  <div className="flex py-3 w-full">
170
170
  <div className="w-2/5 flex space-x-4">
171
171
  <div className="flex space-x-1">
172
- {profileSource && queryClient ? (
172
+ {profileSource != null && queryClient != null ? (
173
173
  <ProfileShareButton
174
174
  queryRequest={profileSource.QueryRequest()}
175
175
  queryClient={queryClient}
176
176
  />
177
177
  ) : null}
178
178
 
179
- <Button color="neutral" onClick={downloadPProf}>
179
+ <Button color="neutral" onClick={void downloadPProf}>
180
180
  Download pprof
181
181
  </Button>
182
182
  </div>
@@ -30,7 +30,7 @@ export const ProfileViewWithData = ({
30
30
  queryClient,
31
31
  profileSource,
32
32
  navigateTo,
33
- }: ProfileViewWithDataProps) => {
33
+ }: ProfileViewWithDataProps): JSX.Element => {
34
34
  const profileVisState = useProfileVisState();
35
35
  const {currentView} = profileVisState;
36
36
  const {
@@ -38,7 +38,7 @@ export const ProfileViewWithData = ({
38
38
  response: flamegraphResponse,
39
39
  error: flamegraphError,
40
40
  } = useQuery(queryClient, profileSource, QueryRequest_ReportType.FLAMEGRAPH_UNSPECIFIED, {
41
- skip: currentView != 'icicle' && currentView != 'both',
41
+ skip: currentView !== 'icicle' && currentView !== 'both',
42
42
  });
43
43
 
44
44
  const {
@@ -46,7 +46,7 @@ export const ProfileViewWithData = ({
46
46
  response: topTableResponse,
47
47
  error: topTableError,
48
48
  } = useQuery(queryClient, profileSource, QueryRequest_ReportType.TOP, {
49
- skip: currentView != 'table' && currentView != 'both',
49
+ skip: currentView !== 'table' && currentView !== 'both',
50
50
  });
51
51
 
52
52
  const sampleUnit = profileSource.ProfileType().sampleUnit;
package/src/TopTable.tsx CHANGED
@@ -26,7 +26,7 @@ interface TopTableProps {
26
26
  sampleUnit: string;
27
27
  }
28
28
 
29
- const Arrow = ({direction}: {direction: string | undefined}) => {
29
+ const Arrow = ({direction}: {direction: string | undefined}): JSX.Element => {
30
30
  return (
31
31
  <svg
32
32
  className={`${direction !== undefined ? 'fill-[#161616] dark:fill-[#ffffff]' : ''}`}
@@ -41,12 +41,27 @@ const Arrow = ({direction}: {direction: string | undefined}) => {
41
41
  );
42
42
  };
43
43
 
44
- const useSortableData = (top?: Top, config = {key: 'cumulative', direction: 'desc'}) => {
44
+ const useSortableData = (
45
+ top?: Top,
46
+ config = {key: 'cumulative', direction: 'desc'}
47
+ ): {
48
+ items:
49
+ | Array<{
50
+ diff: number;
51
+ cumulative: number;
52
+ flat: number;
53
+ name: string | undefined;
54
+ meta?: TopNodeMeta | undefined;
55
+ }>
56
+ | undefined;
57
+ requestSort: (key: string) => void;
58
+ sortConfig: {key: string; direction: string} | null;
59
+ } => {
45
60
  const [sortConfig, setSortConfig] = React.useState<{key: string; direction: string} | null>(
46
61
  config
47
62
  );
48
63
 
49
- const rawTableReport = top ? top.list : [];
64
+ const rawTableReport = top != null ? top.list : [];
50
65
 
51
66
  const items = rawTableReport.map(node => ({
52
67
  ...node,
@@ -57,9 +72,9 @@ const useSortableData = (top?: Top, config = {key: 'cumulative', direction: 'des
57
72
  }));
58
73
 
59
74
  const sortedItems = React.useMemo(() => {
60
- if (!items) return;
75
+ if (items.length === 0) return;
61
76
 
62
- let sortableItems = [...items];
77
+ const sortableItems = [...items];
63
78
  if (sortConfig !== null) {
64
79
  sortableItems.sort((a, b) => {
65
80
  if (a[sortConfig.key] < b[sortConfig.key]) {
@@ -74,9 +89,9 @@ const useSortableData = (top?: Top, config = {key: 'cumulative', direction: 'des
74
89
  return sortableItems;
75
90
  }, [items, sortConfig]);
76
91
 
77
- const requestSort = key => {
92
+ const requestSort = (key: string): void => {
78
93
  let direction = 'desc';
79
- if (sortConfig && sortConfig.key === key && sortConfig.direction === 'desc') {
94
+ if (sortConfig != null && sortConfig.key === key && sortConfig.direction === 'desc') {
80
95
  direction = 'asc';
81
96
  }
82
97
  setSortConfig({key, direction});
@@ -89,14 +104,14 @@ export const RowLabel = (meta: TopNodeMeta | undefined): string => {
89
104
  if (meta === undefined) return '<unknown>';
90
105
  const mapping = `${
91
106
  meta?.mapping?.file !== undefined && meta?.mapping?.file !== ''
92
- ? `[${getLastItem(meta.mapping.file)}]`
107
+ ? `[${getLastItem(meta.mapping.file) ?? ''}]`
93
108
  : ''
94
109
  }`;
95
110
  if (meta.function?.name !== undefined && meta.function?.name !== '')
96
111
  return `${mapping} ${meta.function.name}`;
97
112
 
98
113
  const address = hexifyAddress(meta.location?.address);
99
- const fallback = `${mapping} ${address as string}`;
114
+ const fallback = `${mapping} ${address}`;
100
115
 
101
116
  return fallback === '' ? '<unknown>' : fallback;
102
117
  };
@@ -109,17 +124,17 @@ export const TopTable = ({data: top, sampleUnit}: TopTableProps): JSX.Element =>
109
124
 
110
125
  const unit = sampleUnit;
111
126
 
112
- const total = top ? top.list.length : 0;
127
+ const total = top != null ? top.list.length : 0;
113
128
  if (total === 0) return <>Profile has no samples</>;
114
129
 
115
- const getClassNamesFor = name => {
116
- if (!sortConfig) {
130
+ const getClassNamesFor = (name: string): string | undefined => {
131
+ if (sortConfig == null) {
117
132
  return;
118
133
  }
119
134
  return sortConfig.key === name ? sortConfig.direction : undefined;
120
135
  };
121
136
 
122
- const addPlusSign = (num: string) => {
137
+ const addPlusSign = (num: string): string => {
123
138
  if (num.charAt(0) === '0' || num.charAt(0) === '-') {
124
139
  return num;
125
140
  }
@@ -138,7 +153,9 @@ export const TopTable = ({data: top, sampleUnit}: TopTableProps): JSX.Element =>
138
153
  onClick={() => requestSort('name')}
139
154
  >
140
155
  Name
141
- <span className={`inline-block align-middle ml-2 ${getClassNamesFor('name')}`}>
156
+ <span
157
+ className={`inline-block align-middle ml-2 ${getClassNamesFor('name') ?? ''}`}
158
+ >
142
159
  <Arrow direction={getClassNamesFor('name')} />
143
160
  </span>
144
161
  </th>
@@ -147,7 +164,9 @@ export const TopTable = ({data: top, sampleUnit}: TopTableProps): JSX.Element =>
147
164
  onClick={() => requestSort('flat')}
148
165
  >
149
166
  Flat
150
- <span className={`inline-block align-middle ml-2 ${getClassNamesFor('flat')}`}>
167
+ <span
168
+ className={`inline-block align-middle ml-2 ${getClassNamesFor('flat') ?? ''}`}
169
+ >
151
170
  <Arrow direction={getClassNamesFor('flat')} />
152
171
  </span>
153
172
  </th>
@@ -157,7 +176,9 @@ export const TopTable = ({data: top, sampleUnit}: TopTableProps): JSX.Element =>
157
176
  >
158
177
  Cumulative
159
178
  <span
160
- className={`inline-block align-middle ml-2 ${getClassNamesFor('cumulative')}`}
179
+ className={`inline-block align-middle ml-2 ${
180
+ getClassNamesFor('cumulative') ?? ''
181
+ }`}
161
182
  >
162
183
  <Arrow direction={getClassNamesFor('cumulative')} />
163
184
  </span>
@@ -168,7 +189,9 @@ export const TopTable = ({data: top, sampleUnit}: TopTableProps): JSX.Element =>
168
189
  onClick={() => requestSort('diff')}
169
190
  >
170
191
  Diff
171
- <span className={`inline-block align-middle ml-2 ${getClassNamesFor('diff')}`}>
192
+ <span
193
+ className={`inline-block align-middle ml-2 ${getClassNamesFor('diff') ?? ''}`}
194
+ >
172
195
  <Arrow direction={getClassNamesFor('diff')} />
173
196
  </span>
174
197
  </th>
@@ -25,7 +25,7 @@ const DiffLegendBar = ({
25
25
  }: {
26
26
  onMouseEnter: () => void;
27
27
  onMouseLeave: () => void;
28
- }) => {
28
+ }): JSX.Element => {
29
29
  const isDarkMode = useAppSelector(selectDarkMode);
30
30
 
31
31
  return (
@@ -54,20 +54,20 @@ const DiffLegendBar = ({
54
54
  );
55
55
  };
56
56
 
57
- const DiffLegend = () => {
57
+ const DiffLegend = (): JSX.Element => {
58
58
  const [showLegendTooltip, setShowLegendTooltip] = useState(false);
59
59
  const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
60
- let [referenceElement, setReferenceElement] = useState<HTMLDivElement | null>(null);
60
+ const [referenceElement, setReferenceElement] = useState<HTMLDivElement | null>(null);
61
61
 
62
- const {styles, attributes, ...popperProps} = usePopper(referenceElement, popperElement, {
62
+ const {styles, attributes} = usePopper(referenceElement, popperElement, {
63
63
  placement: 'auto-start',
64
64
  strategy: 'absolute',
65
65
  });
66
66
 
67
- const handleMouseEnter = () => {
67
+ const handleMouseEnter = (): void => {
68
68
  setShowLegendTooltip(true);
69
69
  };
70
- const handleMouseLeave = () => {
70
+ const handleMouseLeave = (): void => {
71
71
  setShowLegendTooltip(false);
72
72
  };
73
73
 
@@ -24,10 +24,10 @@ interface Props {
24
24
 
25
25
  let timeoutHandle: ReturnType<typeof setTimeout> | null = null;
26
26
 
27
- const ResultBox = ({value, className = ''}: Props) => {
27
+ const ResultBox = ({value, className = ''}: Props): JSX.Element => {
28
28
  const [isCopied, setIsCopied] = useState<boolean>(false);
29
29
 
30
- const onCopy = () => {
30
+ const onCopy = (): void => {
31
31
  setIsCopied(true);
32
32
  (window.document?.activeElement as HTMLElement)?.blur();
33
33
  if (timeoutHandle != null) {
@@ -34,16 +34,16 @@ const ProfileShareModal = ({
34
34
  closeModal,
35
35
  queryRequest,
36
36
  queryClient,
37
- }: ProfileShareModalProps) => {
37
+ }: ProfileShareModalProps): JSX.Element => {
38
38
  const [isShared, setIsShared] = useState(false);
39
39
  const [loading, setLoading] = useState<boolean>(false);
40
40
  const [error, setError] = useState<string>('');
41
41
  const [description, setDescription] = useState<string>('');
42
42
  const [sharedLink, setSharedLink] = useState<string>('');
43
43
  const metadata = useGrpcMetadata();
44
- const isFormDataValid = () => true;
44
+ const isFormDataValid = (): boolean => true;
45
45
 
46
- const handleSubmit: () => void = async () => {
46
+ const handleSubmit: () => Promise<void> = async () => {
47
47
  try {
48
48
  setLoading(true);
49
49
  const {response} = await queryClient.shareProfile(
@@ -60,7 +60,7 @@ const ProfileShareModal = ({
60
60
  }
61
61
  };
62
62
 
63
- const onClose = () => {
63
+ const onClose = (): void => {
64
64
  setLoading(false);
65
65
  setError('');
66
66
  setDescription('');
@@ -89,7 +89,7 @@ const ProfileShareModal = ({
89
89
  className="w-fit mt-4"
90
90
  onClick={e => {
91
91
  e.preventDefault();
92
- handleSubmit();
92
+ void handleSubmit();
93
93
  }}
94
94
  disabled={loading || !isFormDataValid()}
95
95
  type="submit"
@@ -113,7 +113,7 @@ const ProfileShareModal = ({
113
113
  );
114
114
  };
115
115
 
116
- const ProfileShareButton = ({queryRequest, queryClient}: Props) => {
116
+ const ProfileShareButton = ({queryRequest, queryClient}: Props): JSX.Element => {
117
117
  const [isOpen, setIsOpen] = useState<boolean>(false);
118
118
 
119
119
  return (
@@ -17,11 +17,11 @@ interface DelayedLoaderOptions {
17
17
  delay?: number;
18
18
  }
19
19
 
20
- const useDelayedLoader = (isLoading = false, options?: DelayedLoaderOptions) => {
21
- const {delay = 500} = options || {};
20
+ const useDelayedLoader = (isLoading = false, options?: DelayedLoaderOptions): boolean => {
21
+ const {delay = 500} = options ?? {};
22
22
  const [isLoaderVisible, setIsLoaderVisible] = useState<boolean>(false);
23
23
  useEffect(() => {
24
- let showLoaderTimeout;
24
+ let showLoaderTimeout: ReturnType<typeof setTimeout>;
25
25
  if (isLoading && !isLoaderVisible) {
26
26
  // if the request takes longer than half a second, show the loading icon
27
27
  showLoaderTimeout = setTimeout(() => {
@@ -31,7 +31,7 @@ const useDelayedLoader = (isLoading = false, options?: DelayedLoaderOptions) =>
31
31
  setIsLoaderVisible(false);
32
32
  }
33
33
  return () => clearTimeout(showLoaderTimeout);
34
- }, [isLoading]);
34
+ }, [isLoading, isLoaderVisible, delay]);
35
35
 
36
36
  return isLoaderVisible;
37
37
  };
package/src/useQuery.tsx CHANGED
@@ -35,7 +35,7 @@ export const useQuery = (
35
35
  reportType: QueryRequest_ReportType,
36
36
  options?: UseQueryOptions
37
37
  ): IQueryResult => {
38
- const {skip = false} = options || {};
38
+ const {skip = false} = options ?? {};
39
39
  const [result, setResult] = useState<IQueryResult>({
40
40
  response: null,
41
41
  error: null,
@@ -58,9 +58,9 @@ export const useQuery = (
58
58
  const call = client.query(req, {meta: metadata});
59
59
 
60
60
  call.response
61
- .then(response => setResult({response: response, error: null, isLoading: false}))
62
- .catch(error => setResult({error: error, response: null, isLoading: false}));
63
- }, [client, profileSource, metadata, reportType]);
61
+ .then(response => setResult({response, error: null, isLoading: false}))
62
+ .catch(error => setResult({error, response: null, isLoading: false}));
63
+ }, [skip, client, profileSource, metadata, reportType]);
64
64
 
65
65
  return result;
66
66
  };
package/src/utils.ts CHANGED
@@ -25,7 +25,7 @@ export const downloadPprof = async (
25
25
  request: QueryRequest,
26
26
  queryClient: QueryServiceClient,
27
27
  metadata: RpcMetadata
28
- ) => {
28
+ ): Promise<Blob> => {
29
29
  const req = {
30
30
  ...request,
31
31
  reportType: QueryRequest_ReportType.PPROF,