@parca/profile 0.19.31 → 0.19.33

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.19.33](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.32...@parca/profile@0.19.33) (2025-08-06)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
10
+ ## [0.19.32](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.31...@parca/profile@0.19.32) (2025-08-06)
11
+
12
+ **Note:** Version bump only for package @parca/profile
13
+
6
14
  ## [0.19.31](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.30...@parca/profile@0.19.31) (2025-08-04)
7
15
 
8
16
  **Note:** Version bump only for package @parca/profile
@@ -4,8 +4,10 @@ export interface FilterPreset {
4
4
  name: string;
5
5
  description: string;
6
6
  filters: Array<Omit<ProfileFilter, 'id'>>;
7
+ allowedProfileTypes?: string[];
7
8
  }
8
9
  export declare const filterPresets: FilterPreset[];
9
10
  export declare const isPresetKey: (key: string) => boolean;
10
11
  export declare const getPresetByKey: (key: string) => FilterPreset | undefined;
12
+ export declare const getPresetsForProfileType: (profileType?: string) => FilterPreset[];
11
13
  //# sourceMappingURL=filterPresets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"filterPresets.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ProfileFilters/filterPresets.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;CAC3C;AAED,eAAO,MAAM,aAAa,EAAE,YAAY,EA6CvC,CAAC;AAIF,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,OAEzC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,YAAY,GAAG,SAE3D,CAAC"}
1
+ {"version":3,"file":"filterPresets.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ProfileFilters/filterPresets.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;IAC1C,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,eAAO,MAAM,aAAa,EAAE,YAAY,EAkEvC,CAAC;AAIF,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,OAEzC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,YAAY,GAAG,SAE3D,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,cAAc,MAAM,KAAG,YAAY,EAO3E,CAAC"}
@@ -15,6 +15,7 @@ export const filterPresets = [
15
15
  key: 'go_runtime_expected_off_cpu',
16
16
  name: 'Go Runtime Expected Off-CPU',
17
17
  description: 'Excludes expected Go runtime blocking functions',
18
+ allowedProfileTypes: ['parca_agent:wallclock:nanoseconds:samples:count:delta'],
18
19
  filters: [
19
20
  {
20
21
  type: 'stack',
@@ -34,6 +35,7 @@ export const filterPresets = [
34
35
  key: 'rust_runtime_expected_off_cpu',
35
36
  name: 'Rust Expected Off-CPU',
36
37
  description: 'Excludes expected Rust runtime blocking functions',
38
+ allowedProfileTypes: ['parca_agent:wallclock:nanoseconds:samples:count:delta'],
37
39
  filters: [
38
40
  {
39
41
  type: 'stack',
@@ -55,6 +57,25 @@ export const filterPresets = [
55
57
  },
56
58
  ],
57
59
  },
60
+ {
61
+ key: 'hide_v8_internals',
62
+ name: 'Hide V8 internals',
63
+ description: 'Excludes Node.js and V8 internal functions from the profile',
64
+ filters: [
65
+ {
66
+ type: 'frame',
67
+ field: 'binary',
68
+ matchType: 'not_contains',
69
+ value: 'node',
70
+ },
71
+ {
72
+ type: 'frame',
73
+ field: 'function_name',
74
+ matchType: 'not_contains',
75
+ value: 'V8',
76
+ },
77
+ ],
78
+ },
58
79
  ];
59
80
  const presetKeys = new Set(filterPresets.map(preset => preset.key));
60
81
  export const isPresetKey = (key) => {
@@ -63,3 +84,12 @@ export const isPresetKey = (key) => {
63
84
  export const getPresetByKey = (key) => {
64
85
  return filterPresets.find(preset => preset.key === key);
65
86
  };
87
+ export const getPresetsForProfileType = (profileType) => {
88
+ if (profileType === undefined || profileType === '')
89
+ return filterPresets;
90
+ return filterPresets.filter(preset => {
91
+ if (preset.allowedProfileTypes === undefined)
92
+ return true;
93
+ return preset.allowedProfileTypes.includes(profileType);
94
+ });
95
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ProfileFilters/index.tsx"],"names":[],"mappings":"AAqBA,OAAO,EAAoB,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAE1E,eAAO,MAAM,gBAAgB,GAAI,QAAQ,aAAa,KAAG,OASxD,CAAC;AAyIF,QAAA,MAAM,cAAc,QAAO,GAAG,CAAC,OA+K9B,CAAC;AAEF,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ProfileFilters/index.tsx"],"names":[],"mappings":"AAsBA,OAAO,EAAoB,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAE1E,eAAO,MAAM,gBAAgB,GAAI,QAAQ,aAAa,KAAG,OASxD,CAAC;AAyIF,QAAA,MAAM,cAAc,QAAO,GAAG,CAAC,OAmL9B,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -15,7 +15,8 @@ import { useCallback } from 'react';
15
15
  import { Icon } from '@iconify/react';
16
16
  import cx from 'classnames';
17
17
  import { Button, Input, Select } from '@parca/components';
18
- import { filterPresets, getPresetByKey, isPresetKey } from './filterPresets';
18
+ import { useProfileViewContext } from '../../context/ProfileViewContext';
19
+ import { getPresetByKey, getPresetsForProfileType, isPresetKey } from './filterPresets';
19
20
  import { useProfileFilters } from './useProfileFilters';
20
21
  export const isFilterComplete = (filter) => {
21
22
  // For preset filters, only need type and value
@@ -25,7 +26,7 @@ export const isFilterComplete = (filter) => {
25
26
  // For regular filters, need all fields
26
27
  return (filter.value !== '' && filter.type != null && filter.field != null && filter.matchType != null);
27
28
  };
28
- const filterTypeItems = [
29
+ const getFilterTypeItems = (currentProfileType) => [
29
30
  {
30
31
  key: 'stack',
31
32
  element: {
@@ -40,7 +41,7 @@ const filterTypeItems = [
40
41
  expanded: (_jsxs(_Fragment, { children: [_jsx("span", { children: "Frame Filter" }), _jsx("br", {}), _jsx("span", { className: "text-xs", children: "Filters individual frames" })] })),
41
42
  },
42
43
  },
43
- ...filterPresets.map(preset => ({
44
+ ...getPresetsForProfileType(currentProfileType).map(preset => ({
44
45
  key: preset.key,
45
46
  element: {
46
47
  active: _jsx(_Fragment, { children: preset.name }),
@@ -139,6 +140,9 @@ const numberMatchTypeItems = [
139
140
  },
140
141
  ];
141
142
  const ProfileFilters = () => {
143
+ const { profileSource } = useProfileViewContext();
144
+ const currentProfileType = profileSource?.ProfileType()?.toString();
145
+ const filterTypeItems = getFilterTypeItems(currentProfileType);
142
146
  const { localFilters, appliedFilters, hasUnsavedChanges, onApplyFilters, addFilter, removeFilter, updateFilter, resetFilters, } = useProfileFilters();
143
147
  const handleKeyDown = useCallback((e) => {
144
148
  if (e.key === 'Enter') {
@@ -213,6 +217,6 @@ const ProfileFilters = () => {
213
217
  removeFilter(filter.id);
214
218
  }
215
219
  }, className: cx('h-[38px] p-3', filter.type != null ? 'rounded-none rounded-r-md' : 'rounded-l-none rounded-r-md'), children: _jsx(Icon, { icon: "mdi:close", className: "h-4 w-4" }) })] }, filter.id));
216
- }), localFilters.length > 0 && (_jsx(Button, { variant: "neutral", onClick: addFilter, className: "p-3 h-[38px]", children: _jsx(Icon, { icon: "mdi:filter-plus-outline", className: "h-4 w-4" }) })), localFilters.length === 0 && (appliedFilters?.length ?? 0) === 0 && (_jsxs(Button, { variant: "neutral", onClick: addFilter, className: "flex items-center gap-2", children: [_jsx(Icon, { icon: "mdi:filter-outline", className: "h-4 w-4" }), _jsx("span", { children: "Filter" })] }))] }), localFilters.length > 0 && (_jsx(Button, { variant: "primary", onClick: onApplyFilters, disabled: !hasUnsavedChanges || !localFilters.some(isFilterComplete), className: cx('flex items-center gap-2 sticky top-0 z-50'), children: _jsx("span", { children: "Apply" }) }))] }));
220
+ }), localFilters.length > 0 && (_jsx(Button, { variant: "neutral", onClick: addFilter, className: "p-3 h-[38px]", children: _jsx(Icon, { icon: "mdi:filter-plus-outline", className: "h-4 w-4" }) })), localFilters.length === 0 && (appliedFilters?.length ?? 0) === 0 && (_jsxs(Button, { variant: "neutral", onClick: addFilter, className: "flex items-center gap-2", children: [_jsx(Icon, { icon: "mdi:filter-outline", className: "h-4 w-4" }), _jsx("span", { children: "Filter" })] }))] }), localFilters.length > 0 && (_jsx(Button, { variant: "primary", onClick: onApplyFilters, disabled: !hasUnsavedChanges || !localFilters.some(isFilterComplete), className: cx('flex items-center gap-2 sticky top-0'), children: _jsx("span", { children: "Apply" }) }))] }));
217
221
  };
218
222
  export default ProfileFilters;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parca/profile",
3
- "version": "0.19.31",
3
+ "version": "0.19.33",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@floating-ui/react": "^0.27.12",
@@ -78,5 +78,5 @@
78
78
  "access": "public",
79
79
  "registry": "https://registry.npmjs.org/"
80
80
  },
81
- "gitHead": "f3fe191525193d9bdc41d811c009d9314bd98494"
81
+ "gitHead": "856f4482ef94445b2e7a05c5618652fd0079fc6e"
82
82
  }
@@ -18,6 +18,7 @@ export interface FilterPreset {
18
18
  name: string;
19
19
  description: string;
20
20
  filters: Array<Omit<ProfileFilter, 'id'>>;
21
+ allowedProfileTypes?: string[];
21
22
  }
22
23
 
23
24
  export const filterPresets: FilterPreset[] = [
@@ -25,6 +26,7 @@ export const filterPresets: FilterPreset[] = [
25
26
  key: 'go_runtime_expected_off_cpu',
26
27
  name: 'Go Runtime Expected Off-CPU',
27
28
  description: 'Excludes expected Go runtime blocking functions',
29
+ allowedProfileTypes: ['parca_agent:wallclock:nanoseconds:samples:count:delta'],
28
30
  filters: [
29
31
  {
30
32
  type: 'stack',
@@ -44,6 +46,7 @@ export const filterPresets: FilterPreset[] = [
44
46
  key: 'rust_runtime_expected_off_cpu',
45
47
  name: 'Rust Expected Off-CPU',
46
48
  description: 'Excludes expected Rust runtime blocking functions',
49
+ allowedProfileTypes: ['parca_agent:wallclock:nanoseconds:samples:count:delta'],
47
50
  filters: [
48
51
  {
49
52
  type: 'stack',
@@ -65,6 +68,25 @@ export const filterPresets: FilterPreset[] = [
65
68
  },
66
69
  ],
67
70
  },
71
+ {
72
+ key: 'hide_v8_internals',
73
+ name: 'Hide V8 internals',
74
+ description: 'Excludes Node.js and V8 internal functions from the profile',
75
+ filters: [
76
+ {
77
+ type: 'frame',
78
+ field: 'binary',
79
+ matchType: 'not_contains',
80
+ value: 'node',
81
+ },
82
+ {
83
+ type: 'frame',
84
+ field: 'function_name',
85
+ matchType: 'not_contains',
86
+ value: 'V8',
87
+ },
88
+ ],
89
+ },
68
90
  ];
69
91
 
70
92
  const presetKeys = new Set(filterPresets.map(preset => preset.key));
@@ -76,3 +98,12 @@ export const isPresetKey = (key: string): boolean => {
76
98
  export const getPresetByKey = (key: string): FilterPreset | undefined => {
77
99
  return filterPresets.find(preset => preset.key === key);
78
100
  };
101
+
102
+ export const getPresetsForProfileType = (profileType?: string): FilterPreset[] => {
103
+ if (profileType === undefined || profileType === '') return filterPresets;
104
+
105
+ return filterPresets.filter(preset => {
106
+ if (preset.allowedProfileTypes === undefined) return true;
107
+ return preset.allowedProfileTypes.includes(profileType);
108
+ });
109
+ };
@@ -18,7 +18,8 @@ import cx from 'classnames';
18
18
 
19
19
  import {Button, Input, Select, type SelectItem} from '@parca/components';
20
20
 
21
- import {filterPresets, getPresetByKey, isPresetKey} from './filterPresets';
21
+ import {useProfileViewContext} from '../../context/ProfileViewContext';
22
+ import {getPresetByKey, getPresetsForProfileType, isPresetKey} from './filterPresets';
22
23
  import {useProfileFilters, type ProfileFilter} from './useProfileFilters';
23
24
 
24
25
  export const isFilterComplete = (filter: ProfileFilter): boolean => {
@@ -32,7 +33,7 @@ export const isFilterComplete = (filter: ProfileFilter): boolean => {
32
33
  );
33
34
  };
34
35
 
35
- const filterTypeItems: SelectItem[] = [
36
+ const getFilterTypeItems = (currentProfileType?: string): SelectItem[] => [
36
37
  {
37
38
  key: 'stack',
38
39
  element: {
@@ -59,7 +60,7 @@ const filterTypeItems: SelectItem[] = [
59
60
  ),
60
61
  },
61
62
  },
62
- ...filterPresets.map(preset => ({
63
+ ...getPresetsForProfileType(currentProfileType).map(preset => ({
63
64
  key: preset.key,
64
65
  element: {
65
66
  active: <>{preset.name}</>,
@@ -168,6 +169,10 @@ const numberMatchTypeItems: SelectItem[] = [
168
169
  ];
169
170
 
170
171
  const ProfileFilters = (): JSX.Element => {
172
+ const {profileSource} = useProfileViewContext();
173
+ const currentProfileType = profileSource?.ProfileType()?.toString();
174
+ const filterTypeItems = getFilterTypeItems(currentProfileType);
175
+
171
176
  const {
172
177
  localFilters,
173
178
  appliedFilters,
@@ -335,7 +340,7 @@ const ProfileFilters = (): JSX.Element => {
335
340
  variant="primary"
336
341
  onClick={onApplyFilters}
337
342
  disabled={!hasUnsavedChanges || !localFilters.some(isFilterComplete)}
338
- className={cx('flex items-center gap-2 sticky top-0 z-50')}
343
+ className={cx('flex items-center gap-2 sticky top-0')}
339
344
  >
340
345
  <span>Apply</span>
341
346
  </Button>