@parca/profile 0.19.24 → 0.19.25

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.
Files changed (31) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/ProfileView/components/ColorStackLegend.d.ts.map +1 -1
  3. package/dist/ProfileView/components/ColorStackLegend.js +0 -1
  4. package/dist/ProfileView/components/DashboardItems/index.d.ts +3 -2
  5. package/dist/ProfileView/components/DashboardItems/index.d.ts.map +1 -1
  6. package/dist/ProfileView/components/DashboardItems/index.js +2 -2
  7. package/dist/ProfileView/index.d.ts +1 -1
  8. package/dist/ProfileView/index.d.ts.map +1 -1
  9. package/dist/ProfileView/index.js +2 -1
  10. package/dist/ProfileView/types/visualization.d.ts +6 -10
  11. package/dist/ProfileView/types/visualization.d.ts.map +1 -1
  12. package/dist/ProfileViewWithData.d.ts.map +1 -1
  13. package/dist/ProfileViewWithData.js +52 -22
  14. package/dist/Sandwich/components/CalleesSection.d.ts +3 -12
  15. package/dist/Sandwich/components/CalleesSection.d.ts.map +1 -1
  16. package/dist/Sandwich/components/CalleesSection.js +2 -4
  17. package/dist/Sandwich/components/CallersSection.d.ts +3 -13
  18. package/dist/Sandwich/components/CallersSection.d.ts.map +1 -1
  19. package/dist/Sandwich/components/CallersSection.js +5 -8
  20. package/dist/Sandwich/index.d.ts +2 -10
  21. package/dist/Sandwich/index.d.ts.map +1 -1
  22. package/dist/Sandwich/index.js +5 -103
  23. package/package.json +6 -6
  24. package/src/ProfileView/components/ColorStackLegend.tsx +0 -2
  25. package/src/ProfileView/components/DashboardItems/index.tsx +4 -12
  26. package/src/ProfileView/index.tsx +2 -0
  27. package/src/ProfileView/types/visualization.ts +7 -18
  28. package/src/ProfileViewWithData.tsx +65 -30
  29. package/src/Sandwich/components/CalleesSection.tsx +10 -28
  30. package/src/Sandwich/components/CallersSection.tsx +13 -34
  31. package/src/Sandwich/index.tsx +8 -170
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.19.25](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.24...@parca/profile@0.19.25) (2025-07-21)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
6
10
  ## [0.19.24](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.23...@parca/profile@0.19.24) (2025-07-17)
7
11
 
8
12
  **Note:** Version bump only for package @parca/profile
@@ -1 +1 @@
1
- {"version":3,"file":"ColorStackLegend.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/components/ColorStackLegend.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAarC,UAAU,KAAK;IACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,QAAA,MAAM,gBAAgB,GAAI,oCAA0C,KAAK,KAAG,KAAK,CAAC,GAAG,CAAC,OAyGrF,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"ColorStackLegend.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/components/ColorStackLegend.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAarC,UAAU,KAAK;IACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,QAAA,MAAM,gBAAgB,GAAI,oCAA0C,KAAK,KAAG,KAAK,CAAC,GAAG,CAAC,OAuGrF,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -33,7 +33,6 @@ const ColorStackLegend = ({ mappings, compareMode = false, loading }) => {
33
33
  .filter(f => f.type === 'frame' && f.field === 'binary')
34
34
  .map(f => f.value);
35
35
  }, [appliedFilters]);
36
- console.log('currentBinaryFilters', currentBinaryFilters);
37
36
  const mappingsList = useMappingList(mappings);
38
37
  const mappingColors = useMemo(() => {
39
38
  const colors = getMappingColors(mappingsList, isDarkMode, currentColorProfile);
@@ -2,7 +2,7 @@ import { ProfilerOnRenderCallback } from 'react';
2
2
  import { QueryServiceClient } from '@parca/client';
3
3
  import { CurrentPathFrame } from '../../../ProfileFlameGraph/FlameGraphArrow/utils';
4
4
  import { ProfileSource } from '../../../ProfileSource';
5
- import type { FlamegraphData, SourceData, TopTableData, VisualizationType } from '../../types/visualization';
5
+ import type { FlamegraphData, SandwichData, SourceData, TopTableData, VisualizationType } from '../../types/visualization';
6
6
  interface GetDashboardItemProps {
7
7
  type: VisualizationType;
8
8
  isHalfScreen: boolean;
@@ -10,6 +10,7 @@ interface GetDashboardItemProps {
10
10
  flamegraphData: FlamegraphData;
11
11
  flamechartData: FlamegraphData;
12
12
  topTableData?: TopTableData;
13
+ sandwichData: SandwichData;
13
14
  sourceData?: SourceData;
14
15
  profileSource: ProfileSource;
15
16
  total: bigint;
@@ -23,6 +24,6 @@ interface GetDashboardItemProps {
23
24
  };
24
25
  queryClient?: QueryServiceClient;
25
26
  }
26
- export declare const getDashboardItem: ({ type, isHalfScreen, dimensions, flamegraphData, flamechartData, topTableData, sourceData, profileSource, total, filtered, curPathArrow, setNewCurPathArrow, perf, queryClient, }: GetDashboardItemProps) => JSX.Element;
27
+ export declare const getDashboardItem: ({ type, isHalfScreen, dimensions, flamegraphData, flamechartData, topTableData, sourceData, sandwichData, profileSource, total, filtered, curPathArrow, setNewCurPathArrow, perf, }: GetDashboardItemProps) => JSX.Element;
27
28
  export {};
28
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/DashboardItems/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAW,wBAAwB,EAAC,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAIjD,OAAO,EAAC,gBAAgB,EAAC,MAAM,kDAAkD,CAAC;AAClF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAIrD,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC,UAAU,qBAAqB;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,kBAAkB,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACvD,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,wBAAwB,CAAC;KACrC,CAAC;IACF,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,eAAO,MAAM,gBAAgB,GAAI,oLAe9B,qBAAqB,KAAG,GAAG,CAAC,OAyG9B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/DashboardItems/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAW,wBAAwB,EAAC,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAIjD,OAAO,EAAC,gBAAgB,EAAC,MAAM,kDAAkD,CAAC;AAClF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAIrD,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC,UAAU,qBAAqB;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,kBAAkB,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACvD,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,wBAAwB,CAAC;KACrC,CAAC;IACF,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,eAAO,MAAM,gBAAgB,GAAI,qLAe9B,qBAAqB,KAAG,GAAG,CAAC,OA+F9B,CAAC"}
@@ -17,7 +17,7 @@ import ProfileFlameGraph from '../../../ProfileFlameGraph';
17
17
  import Sandwich from '../../../Sandwich';
18
18
  import { SourceView } from '../../../SourceView';
19
19
  import { Table } from '../../../Table';
20
- export const getDashboardItem = ({ type, isHalfScreen, dimensions, flamegraphData, flamechartData, topTableData, sourceData, profileSource, total, filtered, curPathArrow, setNewCurPathArrow, perf, queryClient, }) => {
20
+ export const getDashboardItem = ({ type, isHalfScreen, dimensions, flamegraphData, flamechartData, topTableData, sourceData, sandwichData, profileSource, total, filtered, curPathArrow, setNewCurPathArrow, perf, }) => {
21
21
  switch (type) {
22
22
  case 'flamegraph':
23
23
  return (_jsx(ConditionalWrapper, { condition: perf?.onRender != null, WrapperComponent: Profiler, wrapperProps: {
@@ -37,7 +37,7 @@ export const getDashboardItem = ({ type, isHalfScreen, dimensions, flamegraphDat
37
37
  case 'table':
38
38
  return topTableData != null ? (_jsx(Table, { total: total, filtered: filtered, loading: topTableData.loading, data: topTableData.arrow?.record, unit: topTableData.unit, profileType: profileSource?.ProfileType(), isHalfScreen: isHalfScreen, metadataMappingFiles: flamegraphData.metadataMappingFiles })) : (_jsx(_Fragment, {}));
39
39
  case 'sandwich':
40
- return topTableData != null ? (_jsx(Sandwich, { total: total, filtered: filtered, loading: topTableData.loading, data: topTableData.arrow?.record, unit: topTableData.unit, profileType: profileSource?.ProfileType(), metadataMappingFiles: flamegraphData.metadataMappingFiles, profileSource: profileSource, queryClient: queryClient })) : (_jsx(_Fragment, {}));
40
+ return topTableData != null ? (_jsx(Sandwich, { profileSource: profileSource, sandwichData: sandwichData })) : (_jsx(_Fragment, {}));
41
41
  case 'source':
42
42
  return sourceData != null ? (_jsx(SourceView, { loading: sourceData.loading, data: sourceData.data, total: total, filtered: filtered })) : (_jsx(_Fragment, {}));
43
43
  default:
@@ -1,3 +1,3 @@
1
1
  import type { ProfileViewProps } from './types/visualization';
2
- export declare const ProfileView: ({ total, filtered, flamegraphData, flamechartData, topTableData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector, }: ProfileViewProps) => JSX.Element;
2
+ export declare const ProfileView: ({ total, filtered, flamegraphData, flamechartData, topTableData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector, sandwichData, }: ProfileViewProps) => JSX.Element;
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAC,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAE/E,eAAO,MAAM,WAAW,GAAI,mLAazB,gBAAgB,KAAG,GAAG,CAAC,OA8HzB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAC,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAE/E,eAAO,MAAM,WAAW,GAAI,iMAczB,gBAAgB,KAAG,GAAG,CAAC,OA+HzB,CAAC"}
@@ -23,7 +23,7 @@ import { DashboardProvider } from './context/DashboardContext';
23
23
  import { ProfileViewContextProvider } from './context/ProfileViewContext';
24
24
  import { useProfileMetadata } from './hooks/useProfileMetadata';
25
25
  import { useVisualizationState } from './hooks/useVisualizationState';
26
- export const ProfileView = ({ total, filtered, flamegraphData, flamechartData, topTableData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector, }) => {
26
+ export const ProfileView = ({ total, filtered, flamegraphData, flamechartData, topTableData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector, sandwichData, }) => {
27
27
  const { timezone, perf, profileViewExternalMainActions, preferencesModal, profileViewExternalSubActions, } = useParcaContext();
28
28
  const { ref, dimensions } = useContainerDimensions();
29
29
  const { curPath, setCurPath, curPathArrow, setCurPathArrow, colorStackLegend, colorBy, groupBy, toggleGroupBy, setGroupByLabels, sandwichFunctionName, resetSandwichFunctionName, } = useVisualizationState();
@@ -38,6 +38,7 @@ export const ProfileView = ({ total, filtered, flamegraphData, flamechartData, t
38
38
  (selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true');
39
39
  const getDashboardItemByType = ({ type, isHalfScreen, }) => {
40
40
  return getDashboardItem({
41
+ sandwichData,
41
42
  type,
42
43
  isHalfScreen,
43
44
  dimensions,
@@ -1,8 +1,7 @@
1
- import { Callgraph as CallgraphType, Flamegraph, FlamegraphArrow, QueryServiceClient, Source, TableArrow } from '@parca/client';
1
+ import { FlamegraphArrow, QueryServiceClient, Source, TableArrow } from '@parca/client';
2
2
  import { ProfileSource } from '../../ProfileSource';
3
3
  export interface FlamegraphData {
4
4
  loading: boolean;
5
- data?: Flamegraph;
6
5
  arrow?: FlamegraphArrow;
7
6
  total?: bigint;
8
7
  filtered?: bigint;
@@ -19,26 +18,23 @@ export interface TopTableData {
19
18
  error?: any;
20
19
  unit?: string;
21
20
  }
22
- export interface CallgraphData {
23
- loading: boolean;
24
- data?: CallgraphType;
25
- total?: bigint;
26
- filtered?: bigint;
27
- error?: any;
28
- }
29
21
  export interface SourceData {
30
22
  loading: boolean;
31
23
  data?: Source;
32
24
  error?: any;
33
25
  }
26
+ export interface SandwichData {
27
+ callees: FlamegraphData;
28
+ callers: FlamegraphData;
29
+ }
34
30
  export type VisualizationType = 'flamegraph' | 'callgraph' | 'table' | 'source' | 'flamechart' | 'sandwich';
35
31
  export interface ProfileViewProps {
36
32
  total: bigint;
37
33
  filtered: bigint;
38
34
  flamegraphData: FlamegraphData;
39
35
  flamechartData: FlamegraphData;
36
+ sandwichData: SandwichData;
40
37
  topTableData?: TopTableData;
41
- callgraphData?: CallgraphData;
42
38
  sourceData?: SourceData;
43
39
  profileSource: ProfileSource;
44
40
  queryClient?: QueryServiceClient;
@@ -1 +1 @@
1
- {"version":3,"file":"visualization.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/types/visualization.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,SAAS,IAAI,aAAa,EAC1B,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,MAAM,EACN,UAAU,EACX,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,WAAW,GACX,OAAO,GACP,QAAQ,GACR,YAAY,GACZ,UAAU,CAAC;AAEf,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC"}
1
+ {"version":3,"file":"visualization.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/types/visualization.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,eAAe,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAC,MAAM,eAAe,CAAC;AAEtF,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,cAAc,CAAC;IACxB,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,WAAW,GACX,OAAO,GACP,QAAQ,GACR,YAAY,GACZ,UAAU,CAAC;AAEf,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ProfileViewWithData.d.ts","sourceRoot":"","sources":["../src/ProfileViewWithData.tsx"],"names":[],"mappings":"AAeA,OAAO,EAA0B,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAM1E,OAAO,EAAsB,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAMnE,UAAU,wBAAwB;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED,eAAO,MAAM,mBAAmB,GAAI,4DAIjC,wBAAwB,KAAG,GAAG,CAAC,OA0QjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"ProfileViewWithData.d.ts","sourceRoot":"","sources":["../src/ProfileViewWithData.tsx"],"names":[],"mappings":"AAeA,OAAO,EAA0B,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAM1E,OAAO,EAAsB,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAMnE,UAAU,wBAAwB;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED,eAAO,MAAM,mBAAmB,GAAI,4DAIjC,wBAAwB,KAAG,GAAG,CAAC,OA6SjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -32,6 +32,7 @@ export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizat
32
32
  defaultValue: [FIELD_FUNCTION_NAME],
33
33
  alwaysReturnArray: true,
34
34
  });
35
+ const [sandwichFunctionName] = useURLState('sandwich_function_name');
35
36
  const [invertStack] = useURLState('invert_call_stack');
36
37
  const invertCallStack = invertStack === 'true';
37
38
  const [pprofDownloading, setPprofDownloading] = useState(false);
@@ -88,16 +89,28 @@ export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizat
88
89
  skip: !dashboardItems.includes('table') && !dashboardItems.includes('sandwich'),
89
90
  protoFilters,
90
91
  });
91
- const { isLoading: callgraphLoading, response: callgraphResponse, error: callgraphError, } = useQuery(queryClient, profileSource, QueryRequest_ReportType.CALLGRAPH, {
92
- skip: !dashboardItems.includes('callgraph'),
93
- protoFilters,
94
- });
95
92
  const { isLoading: sourceLoading, response: sourceResponse, error: sourceError, } = useQuery(queryClient, profileSource, QueryRequest_ReportType.SOURCE, {
96
93
  skip: !dashboardItems.includes('source'),
97
94
  sourceBuildID,
98
95
  sourceFilename,
99
96
  protoFilters,
100
97
  });
98
+ const { isLoading: callersFlamegraphLoading, response: callersFlamegraphResponse, error: callersFlamegraphError, } = useQuery(queryClient, profileSource, QueryRequest_ReportType.FLAMEGRAPH_ARROW, {
99
+ nodeTrimThreshold,
100
+ groupBy: [FIELD_FUNCTION_NAME],
101
+ invertCallStack: true,
102
+ sandwichByFunction: sandwichFunctionName,
103
+ skip: sandwichFunctionName === undefined && !dashboardItems.includes('sandwich'),
104
+ protoFilters,
105
+ });
106
+ const { isLoading: calleesFlamegraphLoading, response: calleesFlamegraphResponse, error: calleesFlamegraphError, } = useQuery(queryClient, profileSource, QueryRequest_ReportType.FLAMEGRAPH_ARROW, {
107
+ nodeTrimThreshold,
108
+ groupBy: [FIELD_FUNCTION_NAME],
109
+ invertCallStack: false,
110
+ sandwichByFunction: sandwichFunctionName,
111
+ skip: sandwichFunctionName === undefined && !dashboardItems.includes('sandwich'),
112
+ protoFilters,
113
+ });
101
114
  useEffect(() => {
102
115
  if ((!flamegraphLoading && flamegraphResponse?.report.oneofKind === 'flamegraph') ||
103
116
  flamegraphResponse?.report.oneofKind === 'flamegraphArrow') {
@@ -106,17 +119,12 @@ export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizat
106
119
  if (!tableLoading && tableResponse?.report.oneofKind === 'tableArrow') {
107
120
  perf?.markInteraction('table render', tableResponse.total);
108
121
  }
109
- if (!callgraphLoading && callgraphResponse?.report.oneofKind === 'callgraph') {
110
- perf?.markInteraction('Callgraph render', callgraphResponse.total);
111
- }
112
122
  if (!sourceLoading && sourceResponse?.report.oneofKind === 'source') {
113
123
  perf?.markInteraction('Source render', sourceResponse.total);
114
124
  }
115
125
  }, [
116
126
  flamegraphLoading,
117
127
  flamegraphResponse,
118
- callgraphResponse,
119
- callgraphLoading,
120
128
  tableLoading,
121
129
  tableResponse,
122
130
  sourceLoading,
@@ -152,10 +160,6 @@ export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizat
152
160
  total = BigInt(tableResponse.total);
153
161
  filtered = BigInt(tableResponse.filtered);
154
162
  }
155
- else if (callgraphResponse !== null) {
156
- total = BigInt(callgraphResponse.total);
157
- filtered = BigInt(callgraphResponse.filtered);
158
- }
159
163
  else if (sourceResponse !== null) {
160
164
  total = BigInt(sourceResponse.total);
161
165
  filtered = BigInt(sourceResponse.filtered);
@@ -164,11 +168,16 @@ export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizat
164
168
  total = BigInt(flamechartResponse.total);
165
169
  filtered = BigInt(flamechartResponse.filtered);
166
170
  }
171
+ else if (callersFlamegraphResponse !== null) {
172
+ total = BigInt(callersFlamegraphResponse.total);
173
+ filtered = BigInt(callersFlamegraphResponse.filtered);
174
+ }
175
+ else if (calleesFlamegraphResponse !== null) {
176
+ total = BigInt(calleesFlamegraphResponse.total);
177
+ filtered = BigInt(calleesFlamegraphResponse.filtered);
178
+ }
167
179
  return (_jsx(ProfileView, { total: total, filtered: filtered, flamegraphData: {
168
180
  loading: flamegraphLoading && profileMetadataLoading,
169
- data: flamegraphResponse?.report.oneofKind === 'flamegraph'
170
- ? flamegraphResponse?.report?.flamegraph
171
- : undefined,
172
181
  arrow: flamegraphResponse?.report.oneofKind === 'flamegraphArrow'
173
182
  ? flamegraphResponse?.report?.flamegraphArrow
174
183
  : undefined,
@@ -206,18 +215,39 @@ export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizat
206
215
  unit: tableResponse?.report.oneofKind === 'tableArrow'
207
216
  ? tableResponse.report.tableArrow.unit
208
217
  : '',
209
- }, callgraphData: {
210
- loading: callgraphLoading,
211
- data: callgraphResponse?.report.oneofKind === 'callgraph'
212
- ? callgraphResponse?.report?.callgraph
213
- : undefined,
214
- error: callgraphError,
215
218
  }, sourceData: {
216
219
  loading: sourceLoading,
217
220
  data: sourceResponse?.report.oneofKind === 'source'
218
221
  ? sourceResponse?.report?.source
219
222
  : undefined,
220
223
  error: sourceError,
224
+ }, sandwichData: {
225
+ callees: {
226
+ arrow: calleesFlamegraphResponse?.report.oneofKind === 'flamegraphArrow'
227
+ ? calleesFlamegraphResponse?.report?.flamegraphArrow
228
+ : undefined,
229
+ loading: calleesFlamegraphLoading,
230
+ error: calleesFlamegraphError,
231
+ total: BigInt(calleesFlamegraphResponse?.total ?? '0'),
232
+ filtered: BigInt(calleesFlamegraphResponse?.filtered ?? '0'),
233
+ metadataMappingFiles: profileMetadataResponse?.report.oneofKind === 'profileMetadata'
234
+ ? profileMetadataResponse?.report?.profileMetadata?.mappingFiles
235
+ : undefined,
236
+ metadataLoading: profileMetadataLoading,
237
+ },
238
+ callers: {
239
+ arrow: callersFlamegraphResponse?.report.oneofKind === 'flamegraphArrow'
240
+ ? callersFlamegraphResponse?.report?.flamegraphArrow
241
+ : undefined,
242
+ loading: callersFlamegraphLoading,
243
+ error: callersFlamegraphError,
244
+ total: BigInt(callersFlamegraphResponse?.total ?? '0'),
245
+ filtered: BigInt(callersFlamegraphResponse?.filtered ?? '0'),
246
+ metadataMappingFiles: profileMetadataResponse?.report.oneofKind === 'profileMetadata'
247
+ ? profileMetadataResponse?.report?.profileMetadata?.mappingFiles
248
+ : undefined,
249
+ metadataLoading: profileMetadataLoading,
250
+ },
221
251
  }, profileSource: profileSource, queryClient: queryClient, onDownloadPProf: () => void downloadPProfClick(), pprofDownloading: pprofDownloading, showVisualizationSelector: showVisualizationSelector }));
222
252
  };
223
253
  export default ProfileViewWithData;
@@ -1,24 +1,15 @@
1
1
  import React from 'react';
2
- import { type FlamegraphArrow } from '@parca/client';
3
2
  import { type CurrentPathFrame } from '../../ProfileFlameGraph/FlameGraphArrow/utils';
4
3
  import { type ProfileSource } from '../../ProfileSource';
4
+ import { FlamegraphData } from '../../ProfileView/types/visualization';
5
5
  interface CalleesSectionProps {
6
6
  calleesRef: React.RefObject<HTMLDivElement>;
7
- calleesFlamegraphResponse?: {
8
- report: {
9
- oneofKind: string;
10
- flamegraphArrow?: FlamegraphArrow;
11
- };
12
- total?: string;
13
- };
14
- calleesFlamegraphLoading: boolean;
15
- calleesFlamegraphError: any;
16
- filtered: bigint;
7
+ calleesFlamegraphData: FlamegraphData;
17
8
  profileSource: ProfileSource;
18
9
  curPathArrow: CurrentPathFrame[];
19
10
  setCurPathArrow: (path: CurrentPathFrame[]) => void;
20
11
  metadataMappingFiles?: string[];
21
12
  }
22
- export declare function CalleesSection({ calleesRef, calleesFlamegraphResponse, calleesFlamegraphLoading, calleesFlamegraphError, filtered, profileSource, curPathArrow, setCurPathArrow, metadataMappingFiles, }: CalleesSectionProps): JSX.Element;
13
+ export declare function CalleesSection({ calleesRef, calleesFlamegraphData, profileSource, curPathArrow, setCurPathArrow, }: CalleesSectionProps): JSX.Element;
23
14
  export {};
24
15
  //# sourceMappingURL=CalleesSection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CalleesSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CalleesSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAC,KAAK,eAAe,EAAC,MAAM,eAAe,CAAC;AAGnD,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,+CAA+C,CAAC;AACpF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAEvD,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,yBAAyB,CAAC,EAAE;QAC1B,MAAM,EAAE;YACN,SAAS,EAAE,MAAM,CAAC;YAClB,eAAe,CAAC,EAAE,eAAe,CAAC;SACnC,CAAC;QACF,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,wBAAwB,EAAE,OAAO,CAAC;IAClC,sBAAsB,EAAE,GAAG,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,eAAe,EACf,oBAAoB,GACrB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CA+BnC"}
1
+ {"version":3,"file":"CalleesSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CalleesSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,+CAA+C,CAAC;AACpF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAC,cAAc,EAAC,MAAM,uCAAuC,CAAC;AAErE,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,qBAAqB,EAAE,cAAc,CAAC;IACtC,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,eAAe,GAChB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CA2BnC"}
@@ -1,7 +1,5 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  import ProfileFlameGraph from '../../ProfileFlameGraph';
3
- export function CalleesSection({ calleesRef, calleesFlamegraphResponse, calleesFlamegraphLoading, calleesFlamegraphError, filtered, profileSource, curPathArrow, setCurPathArrow, metadataMappingFiles, }) {
4
- return (_jsxs("div", { className: "flex relative items-start flex-row", ref: calleesRef, children: [_jsxs("div", { className: "[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left", children: ['<-', " Callees"] }), _jsx(ProfileFlameGraph, { arrow: calleesFlamegraphResponse?.report.oneofKind === 'flamegraphArrow'
5
- ? calleesFlamegraphResponse?.report?.flamegraphArrow
6
- : undefined, total: BigInt(calleesFlamegraphResponse?.total ?? '0'), filtered: filtered, profileType: profileSource?.ProfileType(), loading: calleesFlamegraphLoading, error: calleesFlamegraphError, isHalfScreen: true, width: calleesRef.current != null ? calleesRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: metadataMappingFiles, metadataLoading: false, isInSandwichView: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, profileSource: profileSource, tooltipId: "callees" })] }));
3
+ export function CalleesSection({ calleesRef, calleesFlamegraphData, profileSource, curPathArrow, setCurPathArrow, }) {
4
+ return (_jsxs("div", { className: "flex relative items-start flex-row", ref: calleesRef, children: [_jsxs("div", { className: "[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left", children: ['<-', " Callees"] }), _jsx(ProfileFlameGraph, { arrow: calleesFlamegraphData?.arrow, total: calleesFlamegraphData.total ?? BigInt(0), filtered: calleesFlamegraphData.filtered ?? BigInt(0), profileType: profileSource?.ProfileType(), loading: calleesFlamegraphData.loading, error: calleesFlamegraphData.error, isHalfScreen: true, width: calleesRef.current != null ? calleesRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: calleesFlamegraphData.metadataMappingFiles, metadataLoading: calleesFlamegraphData.metadataLoading, isInSandwichView: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, profileSource: profileSource, tooltipId: "callees" })] }));
7
5
  }
@@ -1,27 +1,17 @@
1
1
  import React from 'react';
2
- import { type FlamegraphArrow } from '@parca/client';
3
2
  import { type CurrentPathFrame } from '../../ProfileFlameGraph/FlameGraphArrow/utils';
4
3
  import { type ProfileSource } from '../../ProfileSource';
4
+ import { FlamegraphData } from '../../ProfileView/types/visualization';
5
5
  interface CallersSectionProps {
6
6
  callersRef: React.RefObject<HTMLDivElement>;
7
- callersFlamegraphResponse?: {
8
- report: {
9
- oneofKind: string;
10
- flamegraphArrow?: FlamegraphArrow;
11
- };
12
- total?: string;
13
- };
14
- callersFlamegraphLoading: boolean;
15
- callersFlamegraphError: any;
16
- filtered: bigint;
7
+ callersFlamegraphData: FlamegraphData;
17
8
  profileSource: ProfileSource;
18
9
  curPathArrow: CurrentPathFrame[];
19
10
  setCurPathArrow: (path: CurrentPathFrame[]) => void;
20
- metadataMappingFiles?: string[];
21
11
  isExpanded: boolean;
22
12
  setIsExpanded: (isExpanded: boolean) => void;
23
13
  defaultMaxFrames: number;
24
14
  }
25
- export declare function CallersSection({ callersRef, callersFlamegraphResponse, callersFlamegraphLoading, callersFlamegraphError, filtered, profileSource, curPathArrow, setCurPathArrow, metadataMappingFiles, isExpanded, setIsExpanded, defaultMaxFrames, }: CallersSectionProps): JSX.Element;
15
+ export declare function CallersSection({ callersRef, callersFlamegraphData, profileSource, curPathArrow, setCurPathArrow, isExpanded, setIsExpanded, defaultMaxFrames, }: CallersSectionProps): JSX.Element;
26
16
  export {};
27
17
  //# sourceMappingURL=CallersSection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CallersSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CallersSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAKrC,OAAO,EAAC,KAAK,eAAe,EAAC,MAAM,eAAe,CAAC;AAInD,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,+CAA+C,CAAC;AACpF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAevD,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,yBAAyB,CAAC,EAAE;QAC1B,MAAM,EAAE;YACN,SAAS,EAAE,MAAM,CAAC;YAClB,eAAe,CAAC,EAAE,eAAe,CAAC;SACnC,CAAC;QACF,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,wBAAwB,EAAE,OAAO,CAAC;IAClC,sBAAsB,EAAE,GAAG,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,EACtB,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,gBAAgB,GACjB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAwEnC"}
1
+ {"version":3,"file":"CallersSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CallersSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAQrC,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,+CAA+C,CAAC;AACpF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAC,cAAc,EAAC,MAAM,uCAAuC,CAAC;AAerE,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,qBAAqB,EAAE,cAAc,CAAC;IACtC,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,eAAe,EACf,UAAU,EACV,aAAa,EACb,gBAAgB,GACjB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAiEnC"}
@@ -28,20 +28,17 @@ function getMaxDepth(depthColumn) {
28
28
  }
29
29
  return max;
30
30
  }
31
- export function CallersSection({ callersRef, callersFlamegraphResponse, callersFlamegraphLoading, callersFlamegraphError, filtered, profileSource, curPathArrow, setCurPathArrow, metadataMappingFiles, isExpanded, setIsExpanded, defaultMaxFrames, }) {
31
+ export function CallersSection({ callersRef, callersFlamegraphData, profileSource, curPathArrow, setCurPathArrow, isExpanded, setIsExpanded, defaultMaxFrames, }) {
32
32
  const maxDepth = useMemo(() => {
33
- if (callersFlamegraphResponse?.report.oneofKind === 'flamegraphArrow' &&
34
- callersFlamegraphResponse?.report?.flamegraphArrow != null) {
35
- const table = tableFromIPC(callersFlamegraphResponse.report.flamegraphArrow.record);
33
+ if (callersFlamegraphData?.arrow != null) {
34
+ const table = tableFromIPC(callersFlamegraphData.arrow.record);
36
35
  const depthColumn = table.getChild(FIELD_DEPTH);
37
36
  return getMaxDepth(depthColumn);
38
37
  }
39
38
  return 0;
40
- }, [callersFlamegraphResponse]);
39
+ }, [callersFlamegraphData]);
41
40
  const shouldShowButton = maxDepth > defaultMaxFrames;
42
41
  return (_jsxs(_Fragment, { children: [shouldShowButton && (_jsxs(Button, { variant: "neutral", onClick: () => setIsExpanded(!isExpanded), className: "absolute right-8 top-[-46px] z-10", type: "button", children: [_jsx("span", { "data-tooltip-content": !isExpanded
43
42
  ? `This profile has ${maxDepth} frames, showing only the top ${defaultMaxFrames} frames. Click to show more frames.`
44
- : `This profile has ${maxDepth} frames, showing all frames. Click to hide frames.`, "data-tooltip-id": "show-more-frames", children: isExpanded ? 'Hide frames' : 'Show more frames' }), _jsx(Tooltip, { id: "show-more-frames" })] })), _jsxs("div", { className: "flex relative flex-row overflow-hidden", ref: callersRef, children: [_jsxs("div", { className: "[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left flex-shrink-0", children: ["Callers ", '->'] }), _jsx("div", { className: "flex-1 overflow-hidden relative", children: _jsx(ProfileFlameGraph, { arrow: callersFlamegraphResponse?.report.oneofKind === 'flamegraphArrow'
45
- ? callersFlamegraphResponse?.report?.flamegraphArrow
46
- : undefined, total: BigInt(callersFlamegraphResponse?.total ?? '0'), filtered: filtered, profileType: profileSource?.ProfileType(), loading: callersFlamegraphLoading, error: callersFlamegraphError, isHalfScreen: true, width: callersRef.current != null ? callersRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: metadataMappingFiles, metadataLoading: false, isInSandwichView: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, isRenderedAsFlamegraph: true, profileSource: profileSource, tooltipId: "callers", maxFrameCount: defaultMaxFrames, isExpanded: isExpanded }) })] })] }));
43
+ : `This profile has ${maxDepth} frames, showing all frames. Click to hide frames.`, "data-tooltip-id": "show-more-frames", children: isExpanded ? 'Hide frames' : 'Show more frames' }), _jsx(Tooltip, { id: "show-more-frames" })] })), _jsxs("div", { className: "flex relative flex-row overflow-hidden", ref: callersRef, children: [_jsxs("div", { className: "[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left flex-shrink-0", children: ["Callers ", '->'] }), _jsx("div", { className: "flex-1 overflow-hidden relative", children: _jsx(ProfileFlameGraph, { arrow: callersFlamegraphData?.arrow, total: callersFlamegraphData.total ?? BigInt(0), filtered: callersFlamegraphData.filtered ?? BigInt(0), profileType: profileSource?.ProfileType(), loading: callersFlamegraphData.loading, error: callersFlamegraphData.error, isHalfScreen: true, width: callersRef.current != null ? callersRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: callersFlamegraphData.metadataMappingFiles, metadataLoading: callersFlamegraphData.metadataLoading, isInSandwichView: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, isRenderedAsFlamegraph: true, profileSource: profileSource, tooltipId: "callers", maxFrameCount: defaultMaxFrames, isExpanded: isExpanded }) })] })] }));
47
44
  }
@@ -1,17 +1,9 @@
1
1
  import React from 'react';
2
- import { QueryServiceClient } from '@parca/client';
3
- import { ProfileType } from '@parca/parser';
4
2
  import { ProfileSource } from '../ProfileSource';
3
+ import { SandwichData } from '../ProfileView/types/visualization';
5
4
  interface Props {
6
- data?: Uint8Array;
7
- total: bigint;
8
- filtered: bigint;
9
- profileType?: ProfileType;
10
- loading: boolean;
11
- unit?: string;
12
- metadataMappingFiles?: string[];
13
- queryClient?: QueryServiceClient;
14
5
  profileSource: ProfileSource;
6
+ sandwichData: SandwichData;
15
7
  }
16
8
  declare const Sandwich: React.NamedExoticComponent<Props>;
17
9
  export default Sandwich;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Sandwich/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAMlE,OAAO,EAA0B,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAG1E,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAK1C,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAW/C,UAAU,KAAK;IACb,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,QAAA,MAAM,QAAQ,mCAmNZ,CAAC;AAEH,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Sandwich/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAyB,MAAM,OAAO,CAAC;AAM9C,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAC,YAAY,EAAC,MAAM,oCAAoC,CAAC;AAIhE,UAAU,KAAK;IACb,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,QAAA,MAAM,QAAQ,mCAoEZ,CAAC;AAEH,eAAe,QAAQ,CAAC"}
@@ -11,120 +11,22 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
11
11
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
- import React, { useEffect, useMemo, useRef, useState } from 'react';
15
- import { tableFromIPC } from 'apache-arrow';
14
+ import React, { useRef, useState } from 'react';
16
15
  import { AnimatePresence, motion } from 'framer-motion';
17
- import { QueryRequest_ReportType } from '@parca/client';
18
- import { useParcaContext, useURLState } from '@parca/components';
19
- import { useCurrentColorProfile } from '@parca/hooks';
20
- import useMappingList, { useFilenamesList, } from '../ProfileFlameGraph/FlameGraphArrow/useMappingList';
21
- import { useProfileFilters } from '../ProfileView/components/ProfileFilters/useProfileFilters';
16
+ import { useURLState } from '@parca/components';
22
17
  import { useDashboard } from '../ProfileView/context/DashboardContext';
23
18
  import { useVisualizationState } from '../ProfileView/hooks/useVisualizationState';
24
- import { FIELD_FUNCTION_NAME } from '../Table';
25
- import { useColorManagement } from '../Table/hooks/useColorManagement';
26
- import { useQuery } from '../useQuery';
27
19
  import { CalleesSection } from './components/CalleesSection';
28
20
  import { CallersSection } from './components/CallersSection';
29
- import { processRowData } from './utils/processRowData';
30
- const Sandwich = React.memo(function Sandwich({ data, filtered, profileType, loading, unit, metadataMappingFiles, queryClient, profileSource, }) {
31
- const currentColorProfile = useCurrentColorProfile();
21
+ const Sandwich = React.memo(function Sandwich({ sandwichData, profileSource, }) {
32
22
  const { dashboardItems } = useDashboard();
33
23
  const [sandwichFunctionName] = useURLState('sandwich_function_name');
34
- const { isDarkMode } = useParcaContext();
35
- const [selectedRow, setSelectedRow] = useState(null);
36
24
  const callersRef = React.useRef(null);
37
25
  const calleesRef = React.useRef(null);
38
26
  const [isExpanded, setIsExpanded] = useState(false);
39
27
  const defaultMaxFrames = 10;
40
28
  const callersCalleesContainerRef = useRef(null);
41
- const { colorBy, setColorBy, curPathArrow, setCurPathArrow } = useVisualizationState();
42
- const nodeTrimThreshold = useMemo(() => {
43
- let width =
44
- // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
45
- window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
46
- // subtract the padding
47
- width = width - 12 - 16 - 12;
48
- return (1 / width) * 100;
49
- }, []);
50
- const { protoFilters } = useProfileFilters();
51
- const { isLoading: callersFlamegraphLoading, response: callersFlamegraphResponse, error: callersFlamegraphError, } = useQuery(queryClient, profileSource, QueryRequest_ReportType.FLAMEGRAPH_ARROW, {
52
- nodeTrimThreshold,
53
- groupBy: [FIELD_FUNCTION_NAME],
54
- invertCallStack: true,
55
- sandwichByFunction: sandwichFunctionName,
56
- skip: sandwichFunctionName === undefined,
57
- protoFilters,
58
- });
59
- const { isLoading: calleesFlamegraphLoading, response: calleesFlamegraphResponse, error: calleesFlamegraphError, } = useQuery(queryClient, profileSource, QueryRequest_ReportType.FLAMEGRAPH_ARROW, {
60
- nodeTrimThreshold,
61
- groupBy: [FIELD_FUNCTION_NAME],
62
- invertCallStack: false,
63
- sandwichByFunction: sandwichFunctionName,
64
- skip: sandwichFunctionName === undefined,
65
- protoFilters,
66
- });
67
- const table = useMemo(() => {
68
- if (loading || data == null) {
69
- return null;
70
- }
71
- return tableFromIPC(data);
72
- }, [data, loading]);
73
- const mappingsList = useMappingList(metadataMappingFiles);
74
- const filenamesList = useFilenamesList(table);
75
- const mappingsListCount = useMemo(() => mappingsList.filter(m => m !== '').length, [mappingsList]);
76
- // If there is only one mapping file, we want to color by filename by default.
77
- useEffect(() => {
78
- if (mappingsListCount === 1 && colorBy !== 'filename') {
79
- setColorBy('filename');
80
- }
81
- // eslint-disable-next-line react-hooks/exhaustive-deps
82
- }, [mappingsListCount]);
83
- const { colorByColors, colorByValue } = useColorManagement({
84
- isDarkMode,
85
- currentColorProfile,
86
- mappingsList,
87
- filenamesList,
88
- colorBy,
89
- });
90
- unit = useMemo(() => unit ?? profileType?.sampleUnit ?? '', [unit, profileType?.sampleUnit]);
91
- const rows = useMemo(() => {
92
- if (table == null || table.numRows === 0) {
93
- return [];
94
- }
95
- return processRowData({
96
- table,
97
- colorByColors,
98
- colorBy: colorByValue,
99
- });
100
- }, [table, colorByColors, colorByValue]);
101
- useEffect(() => {
102
- if (sandwichFunctionName !== undefined && selectedRow == null) {
103
- // find the row with the sandwichFunctionName
104
- const row = rows.find(row => {
105
- return row.name.trim() === sandwichFunctionName.trim();
106
- });
107
- if (row != null) {
108
- setSelectedRow(row);
109
- }
110
- }
111
- }, [sandwichFunctionName, rows, selectedRow]);
112
- return (_jsx("section", { className: "flex flex-row h-full w-full", children: _jsx(AnimatePresence, { children: _jsx(motion.div, { className: "h-full w-full", initial: { display: 'none', opacity: 0 }, animate: { display: 'block', opacity: 1 }, transition: { duration: 0.5 }, children: _jsx("div", { className: "relative flex flex-row", children: sandwichFunctionName !== undefined ? (_jsxs("div", { className: "w-full flex flex-col", ref: callersCalleesContainerRef, children: [_jsx(CallersSection, { callersRef: callersRef, callersFlamegraphResponse: callersFlamegraphResponse?.report.oneofKind === 'flamegraphArrow'
113
- ? {
114
- report: {
115
- oneofKind: 'flamegraphArrow',
116
- flamegraphArrow: callersFlamegraphResponse.report.flamegraphArrow,
117
- },
118
- total: callersFlamegraphResponse.total?.toString() ?? '0',
119
- }
120
- : undefined, callersFlamegraphLoading: callersFlamegraphLoading, callersFlamegraphError: callersFlamegraphError, filtered: filtered, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow, metadataMappingFiles: metadataMappingFiles, isExpanded: isExpanded, setIsExpanded: setIsExpanded, defaultMaxFrames: defaultMaxFrames }), _jsx("div", { className: "h-4" }), _jsx(CalleesSection, { calleesRef: calleesRef, calleesFlamegraphResponse: calleesFlamegraphResponse?.report.oneofKind === 'flamegraphArrow'
121
- ? {
122
- report: {
123
- oneofKind: 'flamegraphArrow',
124
- flamegraphArrow: calleesFlamegraphResponse.report.flamegraphArrow,
125
- },
126
- total: calleesFlamegraphResponse.total?.toString() ?? '0',
127
- }
128
- : undefined, calleesFlamegraphLoading: calleesFlamegraphLoading, calleesFlamegraphError: calleesFlamegraphError, filtered: filtered, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow, metadataMappingFiles: metadataMappingFiles })] })) : (_jsx("div", { className: "items-center justify-center flex h-full w-full", children: _jsx("p", { className: "text-sm", children: dashboardItems.includes('table') ? ('Please select a function to view its callers and callees.') : (_jsxs(_Fragment, { children: ["Use the right-click menu on the Flame", ' ', dashboardItems.includes('flamegraph') ? 'Graph' : 'Chart', " to choose a function to view its callers and callees."] })) }) })) }) }, "sandwich-loaded") }) }));
29
+ const { curPathArrow, setCurPathArrow } = useVisualizationState();
30
+ return (_jsx("section", { className: "flex flex-row h-full w-full", children: _jsx(AnimatePresence, { children: _jsx(motion.div, { className: "h-full w-full", initial: { display: 'none', opacity: 0 }, animate: { display: 'block', opacity: 1 }, transition: { duration: 0.5 }, children: _jsx("div", { className: "relative flex flex-row", children: sandwichFunctionName !== undefined ? (_jsxs("div", { className: "w-full flex flex-col", ref: callersCalleesContainerRef, children: [_jsx(CallersSection, { callersRef: callersRef, callersFlamegraphData: sandwichData.callers, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow, isExpanded: isExpanded, setIsExpanded: setIsExpanded, defaultMaxFrames: defaultMaxFrames }), _jsx("div", { className: "h-4" }), _jsx(CalleesSection, { calleesRef: calleesRef, calleesFlamegraphData: sandwichData.callees, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow })] })) : (_jsx("div", { className: "items-center justify-center flex h-full w-full", children: _jsx("p", { className: "text-sm", children: dashboardItems.includes('table') ? ('Please select a function to view its callers and callees.') : (_jsxs(_Fragment, { children: ["Use the right-click menu on the Flame", ' ', dashboardItems.includes('flamegraph') ? 'Graph' : 'Chart', " to choose a function to view its callers and callees."] })) }) })) }) }, "sandwich-loaded") }) }));
129
31
  });
130
32
  export default Sandwich;
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@parca/profile",
3
- "version": "0.19.24",
3
+ "version": "0.19.25",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@floating-ui/react": "^0.27.12",
7
7
  "@headlessui/react": "^1.7.19",
8
8
  "@iconify/react": "^4.0.0",
9
9
  "@parca/client": "0.17.3",
10
- "@parca/components": "0.16.351",
10
+ "@parca/components": "0.16.352",
11
11
  "@parca/dynamicsize": "0.16.65",
12
- "@parca/hooks": "0.0.96",
12
+ "@parca/hooks": "0.0.97",
13
13
  "@parca/icons": "0.16.72",
14
14
  "@parca/parser": "0.16.79",
15
- "@parca/store": "0.16.180",
16
- "@parca/utilities": "0.0.104",
15
+ "@parca/store": "0.16.181",
16
+ "@parca/utilities": "0.0.105",
17
17
  "@popperjs/core": "^2.11.8",
18
18
  "@protobuf-ts/runtime-rpc": "^2.5.0",
19
19
  "@storybook/preview-api": "^8.4.3",
@@ -78,5 +78,5 @@
78
78
  "access": "public",
79
79
  "registry": "https://registry.npmjs.org/"
80
80
  },
81
- "gitHead": "a14a290bb5329cb3faaf18c171f1278df2821bda"
81
+ "gitHead": "cc47470182d39d477dbb43ba2304be48a4356ecf"
82
82
  }