@opentrace/opentrace 0.4.0-rc.635 → 0.4.0-rc.641

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.
@@ -8,9 +8,9 @@ import { p as parseGitHubUrl, h as parseGitLabUrl, j as parseBitbucketUrl, k as
8
8
  import { V as useResizablePanel, Q as PanelResizeHandle, o as DEFAULT_LAYOUT_CONFIG, R as PhysicsPanel, z as GraphToolbar, y as GraphLegend, P as PixiGraphCanvas, U as useDiscoverTree, p as DiscoverPanel, b6 as useResizablePanelHeight, w as FilterPanel } from "./useDiscoverTree-D0ibE3xF.js";
9
9
  import ReactMarkdown from "react-markdown";
10
10
  import remarkGfm from "remark-gfm";
11
+ import { A as AddRepoModal, n as normalizeRepoUrl, I as IndexingProgress, d as detectProvider } from "./IndexingProgress-oSLMNtVa.js";
11
12
  import { g as getNodeColor } from "./nodeColors-DlBHz1C_.js";
12
13
  import { c as getLinkColor, u as useCommunities, d as useHighlights } from "./communityColors-CZf-Unx2.js";
13
- import { A as AddRepoModal, n as normalizeRepoUrl, I as IndexingProgress, d as detectProvider } from "./IndexingProgress-oSLMNtVa.js";
14
14
  import { D as DEFAULT_SUMMARIZER_CONFIG } from "./types-C9CgA2DQ.js";
15
15
  const anthropic = {
16
16
  name: "Anthropic Claude",
@@ -68386,7 +68386,7 @@ async function postAzureDevOpsPRComment(owner, repo, number2, token, body) {
68386
68386
  })
68387
68387
  });
68388
68388
  }
68389
- const ATTRIBUTION_FOOTER = "\n\n---\n*Generated via [OpenTrace](https://oss.opentrace.ai)*";
68389
+ const ATTRIBUTION_FOOTER = "\n\n---\n*Generated via [OpenTrace](https://app.opentrace.ai)*";
68390
68390
  class PRClient {
68391
68391
  meta;
68392
68392
  token;
@@ -72538,6 +72538,568 @@ function useGraphInteraction() {
72538
72538
  }
72539
72539
  return ctx;
72540
72540
  }
72541
+ const EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
72542
+ function readPersistedSettings() {
72543
+ try {
72544
+ return JSON.parse(localStorage.getItem("graph-settings") ?? "{}");
72545
+ } catch {
72546
+ return {};
72547
+ }
72548
+ }
72549
+ function useGraphViewer(options = {}) {
72550
+ const {
72551
+ chatHighlightNodes,
72552
+ extraHighlightSource,
72553
+ suppressNextAutoFitRef,
72554
+ autoFitMode = "schedule"
72555
+ } = options;
72556
+ const canvasRef = useRef(null);
72557
+ const { graphData, stats, lastSearchQuery, graphVersion, loadGraph } = useGraph();
72558
+ const {
72559
+ selectedNode,
72560
+ setSelectedNode,
72561
+ selectedLink,
72562
+ setSelectedLink,
72563
+ setNodeHistory,
72564
+ setHiddenNodeTypes,
72565
+ setHiddenCommunities,
72566
+ colorMode,
72567
+ searchQuery,
72568
+ setSearchQuery,
72569
+ hops,
72570
+ setHops,
72571
+ focusedCommunityNodes,
72572
+ setFocusedCommunityNodes,
72573
+ communityData,
72574
+ filteredGraphData,
72575
+ highlights
72576
+ } = useGraphInteraction();
72577
+ const graphDataRef = useRef(graphData);
72578
+ useEffect(() => {
72579
+ graphDataRef.current = graphData;
72580
+ }, [graphData]);
72581
+ useEffect(() => {
72582
+ if (graphVersion === 0) return;
72583
+ if (suppressNextAutoFitRef?.current) {
72584
+ suppressNextAutoFitRef.current = false;
72585
+ return;
72586
+ }
72587
+ if (autoFitMode === "unconditional") {
72588
+ const t = setTimeout(() => canvasRef.current?.zoomToFit(400), 500);
72589
+ return () => clearTimeout(t);
72590
+ }
72591
+ canvasRef.current?.scheduleAutoFit?.(400);
72592
+ }, [graphVersion, suppressNextAutoFitRef, autoFitMode]);
72593
+ const chatHighlightLinks = useMemo(() => {
72594
+ if (!chatHighlightNodes || chatHighlightNodes.size < 2) return EMPTY_SET;
72595
+ const links = /* @__PURE__ */ new Set();
72596
+ for (const link of graphData.links) {
72597
+ if (chatHighlightNodes.has(link.source) && chatHighlightNodes.has(link.target)) {
72598
+ links.add(`${link.source}-${link.target}`);
72599
+ }
72600
+ }
72601
+ return links;
72602
+ }, [graphData.links, chatHighlightNodes]);
72603
+ useEffect(() => {
72604
+ if (!chatHighlightNodes || chatHighlightNodes.size === 0) return;
72605
+ const now = Date.now();
72606
+ setNodeHistory((prev) => {
72607
+ const existing = new Set(prev.map((e) => e.id));
72608
+ const newEntries = [];
72609
+ for (const id of chatHighlightNodes) {
72610
+ if (existing.has(id)) continue;
72611
+ const node = graphDataRef.current.nodes.find((n2) => n2.id === id);
72612
+ if (!node) continue;
72613
+ newEntries.push({
72614
+ id: node.id,
72615
+ name: node.name,
72616
+ type: node.type,
72617
+ timestamp: now,
72618
+ source: "chat"
72619
+ });
72620
+ }
72621
+ if (newEntries.length === 0) return prev;
72622
+ return [...newEntries, ...prev].slice(0, 500);
72623
+ });
72624
+ }, [chatHighlightNodes, setNodeHistory]);
72625
+ const [edgeHighlightNodes, setEdgeHighlightNodes] = useState(EMPTY_SET);
72626
+ const [edgeHighlightLinks, setEdgeHighlightLinks] = useState(EMPTY_SET);
72627
+ const [edgeLabelNodes, setEdgeLabelNodes] = useState(EMPTY_SET);
72628
+ const [activeFilter, setActiveFilter] = useState(null);
72629
+ const stored = useMemo(readPersistedSettings, []);
72630
+ const ps = (key, def) => stored[key] ?? def;
72631
+ const [zoomOnSelect, setZoomOnSelect] = useState(
72632
+ () => ps("zoomOnSelect", true)
72633
+ );
72634
+ const [repulsion, setRepulsion] = useState(() => ps("repulsion", 120));
72635
+ const [labelsVisible, setLabelsVisible] = useState(
72636
+ () => ps("labelsVisible", true)
72637
+ );
72638
+ const [physicsRunning, setPhysicsRunning] = useState(false);
72639
+ const [pixiLinkDist, setPixiLinkDist] = useState(
72640
+ () => ps("pixiLinkDist", 200)
72641
+ );
72642
+ const [pixiCenter, setPixiCenter] = useState(() => ps("pixiCenter", 0.3));
72643
+ const [pixiZoomExponent, setPixiZoomExponent] = useState(
72644
+ () => ps("pixiZoomExponent", 0.8)
72645
+ );
72646
+ const [layoutMode, setLayoutMode] = useState(
72647
+ () => ps("layoutMode", "spread")
72648
+ );
72649
+ const [compactRadial, setCompactRadial] = useState(
72650
+ () => ps("compactRadial", 8)
72651
+ );
72652
+ const [compactCommunity, setCompactCommunity] = useState(
72653
+ () => ps("compactCommunity", 10)
72654
+ );
72655
+ const [compactCentering, setCompactCentering] = useState(
72656
+ () => ps("compactCentering", 5)
72657
+ );
72658
+ const [compactRadius, setCompactRadius] = useState(
72659
+ () => ps("compactRadius", 32)
72660
+ );
72661
+ const [mode3d, setMode3d] = useState(() => ps("mode3d", true));
72662
+ const [mode3dSpeed, setMode3dSpeed] = useState(() => ps("mode3dSpeed", 30));
72663
+ const [mode3dTilt, setMode3dTilt] = useState(() => ps("mode3dTilt", 35));
72664
+ const [labelScale, setLabelScale] = useState(() => ps("labelScale", 100));
72665
+ const [rendererAutoRotate, setRendererAutoRotate] = useState(
72666
+ null
72667
+ );
72668
+ useEffect(() => {
72669
+ const settings2 = {
72670
+ repulsion,
72671
+ labelsVisible,
72672
+ zoomOnSelect,
72673
+ pixiLinkDist,
72674
+ pixiCenter,
72675
+ pixiZoomExponent,
72676
+ layoutMode,
72677
+ compactRadial,
72678
+ compactCommunity,
72679
+ compactCentering,
72680
+ compactRadius,
72681
+ mode3d,
72682
+ mode3dSpeed,
72683
+ mode3dTilt,
72684
+ labelScale
72685
+ };
72686
+ localStorage.setItem("graph-settings", JSON.stringify(settings2));
72687
+ }, [
72688
+ repulsion,
72689
+ labelsVisible,
72690
+ zoomOnSelect,
72691
+ pixiLinkDist,
72692
+ pixiCenter,
72693
+ pixiZoomExponent,
72694
+ layoutMode,
72695
+ compactRadial,
72696
+ compactCommunity,
72697
+ compactCentering,
72698
+ compactRadius,
72699
+ mode3d,
72700
+ mode3dSpeed,
72701
+ mode3dTilt,
72702
+ labelScale
72703
+ ]);
72704
+ const handleSearch = useCallback(() => {
72705
+ if (searchQuery.trim()) {
72706
+ loadGraph(searchQuery.trim(), hops);
72707
+ }
72708
+ }, [searchQuery, hops, loadGraph]);
72709
+ const handleReset = useCallback(() => {
72710
+ setSearchQuery("");
72711
+ setHops(2);
72712
+ setSelectedNode(null);
72713
+ setSelectedLink(null);
72714
+ setActiveFilter(null);
72715
+ setFocusedCommunityNodes(EMPTY_SET);
72716
+ setHiddenNodeTypes(/* @__PURE__ */ new Set());
72717
+ setHiddenCommunities(/* @__PURE__ */ new Set());
72718
+ if (lastSearchQuery) {
72719
+ loadGraph();
72720
+ }
72721
+ }, [
72722
+ setSearchQuery,
72723
+ setHops,
72724
+ setSelectedNode,
72725
+ setSelectedLink,
72726
+ setFocusedCommunityNodes,
72727
+ setHiddenNodeTypes,
72728
+ setHiddenCommunities,
72729
+ lastSearchQuery,
72730
+ loadGraph
72731
+ ]);
72732
+ const applyFilter = useCallback(
72733
+ (filter) => {
72734
+ if (!filter) {
72735
+ setFocusedCommunityNodes(EMPTY_SET);
72736
+ return;
72737
+ }
72738
+ if (filter.type === "community") {
72739
+ const nodeIds = Object.entries(communityData.assignments).filter(([, id]) => id === filter.communityId).map(([nodeId]) => nodeId);
72740
+ if (nodeIds.length > 0) {
72741
+ const nodeSet = new Set(nodeIds);
72742
+ setFocusedCommunityNodes(nodeSet);
72743
+ canvasRef.current?.zoomToNodes(nodeSet, 600);
72744
+ }
72745
+ }
72746
+ },
72747
+ [communityData.assignments, setFocusedCommunityNodes]
72748
+ );
72749
+ const onNodeClick = useCallback(
72750
+ (node) => {
72751
+ setSelectedNode(node);
72752
+ setSelectedLink(null);
72753
+ setEdgeHighlightNodes(EMPTY_SET);
72754
+ setEdgeHighlightLinks(EMPTY_SET);
72755
+ setEdgeLabelNodes(EMPTY_SET);
72756
+ setFocusedCommunityNodes(EMPTY_SET);
72757
+ setNodeHistory((prev) => {
72758
+ if (prev.length > 0 && prev[0].id === node.id) return prev;
72759
+ const entry = {
72760
+ id: node.id,
72761
+ name: node.name,
72762
+ type: node.type,
72763
+ timestamp: Date.now(),
72764
+ source: "user"
72765
+ };
72766
+ return [entry, ...prev].slice(0, 500);
72767
+ });
72768
+ },
72769
+ [
72770
+ setSelectedNode,
72771
+ setSelectedLink,
72772
+ setFocusedCommunityNodes,
72773
+ setNodeHistory
72774
+ ]
72775
+ );
72776
+ const onLinkClick = useCallback(
72777
+ (edge) => {
72778
+ setSelectedLink(edge);
72779
+ setSelectedNode(null);
72780
+ },
72781
+ [setSelectedLink, setSelectedNode]
72782
+ );
72783
+ const activeFilterRef = useRef(activeFilter);
72784
+ activeFilterRef.current = activeFilter;
72785
+ const onStageClick = useCallback(() => {
72786
+ setSelectedNode(null);
72787
+ setSelectedLink(null);
72788
+ setEdgeHighlightNodes(EMPTY_SET);
72789
+ setEdgeHighlightLinks(EMPTY_SET);
72790
+ setEdgeLabelNodes(EMPTY_SET);
72791
+ applyFilter(activeFilterRef.current);
72792
+ }, [applyFilter, setSelectedLink, setSelectedNode]);
72793
+ const handleSuggestionSelect = useCallback(
72794
+ (suggestion) => {
72795
+ switch (suggestion.category) {
72796
+ case "community": {
72797
+ const cid = suggestion.communityId;
72798
+ if (cid !== void 0) {
72799
+ setActiveFilter({ type: "community", communityId: cid });
72800
+ applyFilter({ type: "community", communityId: cid });
72801
+ setSelectedNode(null);
72802
+ setSelectedLink(null);
72803
+ }
72804
+ break;
72805
+ }
72806
+ default: {
72807
+ setActiveFilter(null);
72808
+ const targetId = suggestion.nodeId;
72809
+ loadGraph(suggestion.label, hops).then(() => {
72810
+ if (targetId) {
72811
+ const node = graphDataRef.current.nodes.find(
72812
+ (n2) => n2.id === targetId
72813
+ );
72814
+ if (node) {
72815
+ onNodeClick(node);
72816
+ setTimeout(() => {
72817
+ canvasRef.current?.zoomToNodes(/* @__PURE__ */ new Set([targetId]), 600);
72818
+ }, 100);
72819
+ }
72820
+ }
72821
+ });
72822
+ break;
72823
+ }
72824
+ }
72825
+ },
72826
+ [
72827
+ applyFilter,
72828
+ hops,
72829
+ loadGraph,
72830
+ onNodeClick,
72831
+ setSelectedLink,
72832
+ setSelectedNode
72833
+ ]
72834
+ );
72835
+ useEffect(() => {
72836
+ if (focusedCommunityNodes.size > 0) {
72837
+ canvasRef.current?.zoomToNodes(focusedCommunityNodes, 600);
72838
+ }
72839
+ }, [focusedCommunityNodes]);
72840
+ useEffect(() => {
72841
+ if (!selectedLink) {
72842
+ setEdgeHighlightNodes(EMPTY_SET);
72843
+ setEdgeHighlightLinks(EMPTY_SET);
72844
+ setEdgeLabelNodes(EMPTY_SET);
72845
+ return;
72846
+ }
72847
+ const { source: sourceId, target: targetId } = selectedLink;
72848
+ setEdgeHighlightNodes(/* @__PURE__ */ new Set([sourceId, targetId]));
72849
+ setEdgeHighlightLinks(/* @__PURE__ */ new Set([`${sourceId}-${targetId}`]));
72850
+ setEdgeLabelNodes(/* @__PURE__ */ new Set([sourceId, targetId]));
72851
+ canvasRef.current?.zoomToNodes([sourceId, targetId], 600);
72852
+ }, [selectedLink]);
72853
+ const selectedNodeId = selectedNode?.id;
72854
+ const hasSelectedLink = !!selectedLink;
72855
+ const focusedCommunitySize = focusedCommunityNodes.size;
72856
+ useEffect(() => {
72857
+ if (!zoomOnSelect) return;
72858
+ if (selectedNode) {
72859
+ if (highlights.highlightNodes.size > 0) {
72860
+ canvasRef.current?.zoomToNodes(highlights.highlightNodes, 600);
72861
+ }
72862
+ } else if (!selectedLink && focusedCommunityNodes.size === 0) {
72863
+ canvasRef.current?.zoomToFit(600);
72864
+ }
72865
+ }, [zoomOnSelect, selectedNodeId, hasSelectedLink, focusedCommunitySize]);
72866
+ const legendNodeItems = useMemo(() => {
72867
+ const counts = {};
72868
+ filteredGraphData.nodes.forEach((n2) => {
72869
+ counts[n2.type] = (counts[n2.type] || 0) + 1;
72870
+ });
72871
+ return Object.entries(counts).map(([label, count]) => ({
72872
+ label,
72873
+ count,
72874
+ color: getNodeColor(label)
72875
+ })).sort((a, b) => b.count - a.count);
72876
+ }, [filteredGraphData.nodes]);
72877
+ const legendCommunityItems = useMemo(() => {
72878
+ if (colorMode !== "community") return [];
72879
+ const counts = /* @__PURE__ */ new Map();
72880
+ for (const n2 of filteredGraphData.nodes) {
72881
+ const cid = communityData.assignments[n2.id];
72882
+ if (cid !== void 0) {
72883
+ counts.set(cid, (counts.get(cid) || 0) + 1);
72884
+ }
72885
+ }
72886
+ return [...counts.entries()].sort((a, b) => b[1] - a[1]).map(([cid, count]) => ({
72887
+ label: communityData.names.get(cid) ?? `Community ${cid}`,
72888
+ count,
72889
+ color: communityData.colorMap.get(cid) ?? "#64748b"
72890
+ }));
72891
+ }, [colorMode, filteredGraphData.nodes, communityData]);
72892
+ const legendItems = colorMode === "community" ? legendCommunityItems : legendNodeItems;
72893
+ const legendLinkItems = useMemo(() => {
72894
+ const counts = {};
72895
+ filteredGraphData.links.forEach((l) => {
72896
+ const label = l.label || "unknown";
72897
+ counts[label] = (counts[label] || 0) + 1;
72898
+ });
72899
+ return Object.entries(counts).map(([label, count]) => ({
72900
+ label,
72901
+ count,
72902
+ color: getLinkColor(label)
72903
+ })).sort((a, b) => b.count - a.count);
72904
+ }, [filteredGraphData.links]);
72905
+ const searchSuggestions = useMemo(() => {
72906
+ const nameMap = /* @__PURE__ */ new Map();
72907
+ for (const n2 of graphData.nodes) {
72908
+ if (!nameMap.has(n2.name)) {
72909
+ const cid = communityData.assignments[n2.id];
72910
+ nameMap.set(n2.name, {
72911
+ type: n2.type,
72912
+ communityId: cid,
72913
+ nodeId: n2.id
72914
+ });
72915
+ }
72916
+ }
72917
+ const suggestions = [];
72918
+ for (const [name, info] of nameMap) {
72919
+ const cLabel = info.communityId !== void 0 ? communityData.names.get(info.communityId) : void 0;
72920
+ const cColor = info.communityId !== void 0 ? communityData.colorMap.get(info.communityId) : void 0;
72921
+ suggestions.push({
72922
+ label: name,
72923
+ category: "name",
72924
+ color: getNodeColor(info.type),
72925
+ communityLabel: cLabel,
72926
+ communityColor: cColor,
72927
+ nodeId: info.nodeId
72928
+ });
72929
+ }
72930
+ for (const [cid, name] of communityData.names) {
72931
+ suggestions.push({
72932
+ label: name,
72933
+ category: "community",
72934
+ color: communityData.colorMap.get(cid),
72935
+ communityId: cid
72936
+ });
72937
+ }
72938
+ return suggestions;
72939
+ }, [graphData.nodes, communityData]);
72940
+ const layoutConfig = useMemo(
72941
+ () => ({
72942
+ ...DEFAULT_LAYOUT_CONFIG,
72943
+ fa2ScalingRatio: repulsion
72944
+ }),
72945
+ [repulsion]
72946
+ );
72947
+ const highlightProps = useMemo(() => {
72948
+ const hasChat = !!chatHighlightNodes && chatHighlightNodes.size > 0;
72949
+ const hasExtraNodes = !!extraHighlightSource && extraHighlightSource.nodes.size > 0;
72950
+ const hasExtraLinks = !!extraHighlightSource && extraHighlightSource.links.size > 0;
72951
+ const hasExtraLabels = !!extraHighlightSource && extraHighlightSource.labels.size > 0;
72952
+ const highlightNodes = selectedLink ? edgeHighlightNodes : focusedCommunityNodes.size > 0 ? focusedCommunityNodes : highlights.highlightNodes.size > 0 ? highlights.highlightNodes : hasChat ? chatHighlightNodes : hasExtraNodes ? extraHighlightSource.nodes : highlights.highlightNodes;
72953
+ const highlightLinks = selectedLink ? edgeHighlightLinks : focusedCommunityNodes.size > 0 ? EMPTY_SET : highlights.highlightLinks.size > 0 ? highlights.highlightLinks : chatHighlightLinks.size > 0 ? chatHighlightLinks : hasExtraLinks ? extraHighlightSource.links : highlights.highlightLinks;
72954
+ const labelNodes = selectedLink ? edgeLabelNodes : focusedCommunityNodes.size > 0 ? focusedCommunityNodes : highlights.labelNodes.size > 0 ? highlights.labelNodes : hasChat ? chatHighlightNodes : hasExtraLabels ? extraHighlightSource.labels : highlights.labelNodes;
72955
+ return { highlightNodes, highlightLinks, labelNodes };
72956
+ }, [
72957
+ selectedLink,
72958
+ edgeHighlightNodes,
72959
+ edgeHighlightLinks,
72960
+ edgeLabelNodes,
72961
+ focusedCommunityNodes,
72962
+ highlights.highlightNodes,
72963
+ highlights.highlightLinks,
72964
+ highlights.labelNodes,
72965
+ chatHighlightNodes,
72966
+ chatHighlightLinks,
72967
+ extraHighlightSource
72968
+ ]);
72969
+ const toolbar = useMemo(
72970
+ () => ({
72971
+ searchQuery,
72972
+ onSearchQueryChange: setSearchQuery,
72973
+ onSearch: handleSearch,
72974
+ onReset: handleReset,
72975
+ searchDisabled: !searchQuery.trim() || searchQuery === lastSearchQuery,
72976
+ showResetButton: !!lastSearchQuery,
72977
+ searchSuggestions,
72978
+ onSuggestionSelect: handleSuggestionSelect,
72979
+ hops,
72980
+ onHopsChange: setHops,
72981
+ nodeCount: filteredGraphData.nodes.length,
72982
+ edgeCount: filteredGraphData.links.length,
72983
+ totalNodes: stats?.total_nodes,
72984
+ totalEdges: stats?.total_edges,
72985
+ showDetailsTab: !!(selectedNode || selectedLink)
72986
+ }),
72987
+ [
72988
+ searchQuery,
72989
+ setSearchQuery,
72990
+ handleSearch,
72991
+ handleReset,
72992
+ lastSearchQuery,
72993
+ searchSuggestions,
72994
+ handleSuggestionSelect,
72995
+ hops,
72996
+ setHops,
72997
+ filteredGraphData.nodes.length,
72998
+ filteredGraphData.links.length,
72999
+ stats?.total_nodes,
73000
+ stats?.total_edges,
73001
+ selectedNode,
73002
+ selectedLink
73003
+ ]
73004
+ );
73005
+ const settings = useMemo(
73006
+ () => ({
73007
+ repulsion,
73008
+ setRepulsion,
73009
+ labelsVisible,
73010
+ setLabelsVisible,
73011
+ zoomOnSelect,
73012
+ setZoomOnSelect,
73013
+ pixiLinkDist,
73014
+ setPixiLinkDist,
73015
+ pixiCenter,
73016
+ setPixiCenter,
73017
+ pixiZoomExponent,
73018
+ setPixiZoomExponent,
73019
+ layoutMode,
73020
+ setLayoutMode,
73021
+ compactRadial,
73022
+ setCompactRadial,
73023
+ compactCommunity,
73024
+ setCompactCommunity,
73025
+ compactCentering,
73026
+ setCompactCentering,
73027
+ compactRadius,
73028
+ setCompactRadius,
73029
+ mode3d,
73030
+ setMode3d,
73031
+ mode3dSpeed,
73032
+ setMode3dSpeed,
73033
+ mode3dTilt,
73034
+ setMode3dTilt,
73035
+ labelScale,
73036
+ setLabelScale,
73037
+ rendererAutoRotate,
73038
+ setRendererAutoRotate,
73039
+ physicsRunning,
73040
+ setPhysicsRunning
73041
+ }),
73042
+ [
73043
+ repulsion,
73044
+ labelsVisible,
73045
+ zoomOnSelect,
73046
+ pixiLinkDist,
73047
+ pixiCenter,
73048
+ pixiZoomExponent,
73049
+ layoutMode,
73050
+ compactRadial,
73051
+ compactCommunity,
73052
+ compactCentering,
73053
+ compactRadius,
73054
+ mode3d,
73055
+ mode3dSpeed,
73056
+ mode3dTilt,
73057
+ labelScale,
73058
+ rendererAutoRotate,
73059
+ physicsRunning
73060
+ ]
73061
+ );
73062
+ const isEmpty2 = graphData.nodes.length === 0;
73063
+ const isSearchEmpty = isEmpty2 && !!lastSearchQuery;
73064
+ const buildImperativeHandle = useCallback(
73065
+ () => ({
73066
+ selectNode: (nodeId, nodeHops) => {
73067
+ if (nodeHops !== void 0) setHops(nodeHops);
73068
+ const node = graphDataRef.current.nodes.find((n2) => n2.id === nodeId);
73069
+ if (node) onNodeClick(node);
73070
+ },
73071
+ triggerPing: (nodeIds) => {
73072
+ canvasRef.current?.triggerPing?.(nodeIds);
73073
+ },
73074
+ resetCamera: () => {
73075
+ canvasRef.current?.resetCamera();
73076
+ },
73077
+ zoomToFit: (duration2) => {
73078
+ canvasRef.current?.zoomToFit(duration2);
73079
+ },
73080
+ reload: (query, hopsArg) => loadGraph(query, hopsArg)
73081
+ }),
73082
+ [onNodeClick, setHops, loadGraph]
73083
+ );
73084
+ return {
73085
+ canvasRef,
73086
+ graphDataRef,
73087
+ settings,
73088
+ toolbar,
73089
+ legendNodeItems,
73090
+ legendCommunityItems,
73091
+ legendItems,
73092
+ legendLinkItems,
73093
+ onNodeClick,
73094
+ onLinkClick,
73095
+ onStageClick,
73096
+ highlightProps,
73097
+ layoutConfig,
73098
+ isEmpty: isEmpty2,
73099
+ isSearchEmpty,
73100
+ buildImperativeHandle
73101
+ };
73102
+ }
72541
73103
  function ExportModal({ onExport, onCancel }) {
72542
73104
  const { store } = useStore();
72543
73105
  const [includeSource, setIncludeSource] = useState(false);
@@ -73536,7 +74098,6 @@ function toIndexingProps(job, repoUrl) {
73536
74098
  const icon = provider === "gitlab" ? /* @__PURE__ */ jsx(GitLabIcon, {}) : provider ? /* @__PURE__ */ jsx(GitHubIcon, {}) : null;
73537
74099
  return { state, title, message, icon };
73538
74100
  }
73539
- const EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
73540
74101
  const GraphViewer = memo(
73541
74102
  forwardRef(
73542
74103
  function GraphViewer2(props, ref) {
@@ -73569,7 +74130,30 @@ const GraphViewer = memo(
73569
74130
  onMobilePanelTabChange
73570
74131
  } = props;
73571
74132
  const { store } = useStore();
73572
- const canvasRef = useRef(null);
74133
+ const suppressNextFitRef = useRef(false);
74134
+ const v = useGraphViewer({
74135
+ chatHighlightNodes,
74136
+ suppressNextAutoFitRef: suppressNextFitRef
74137
+ });
74138
+ const {
74139
+ graphData,
74140
+ loading,
74141
+ error,
74142
+ lastSearchQuery,
74143
+ loadGraph,
74144
+ setError
74145
+ } = useGraph();
74146
+ const {
74147
+ selectedNode,
74148
+ hiddenNodeTypes,
74149
+ hiddenLinkTypes,
74150
+ hiddenSubTypes,
74151
+ hiddenCommunities,
74152
+ colorMode,
74153
+ setColorMode,
74154
+ availableSubTypes,
74155
+ communityData
74156
+ } = useGraphInteraction();
73573
74157
  const [indexedRepos, setIndexedRepos] = useState([]);
73574
74158
  useEffect(() => {
73575
74159
  if (!showAddRepo) return;
@@ -73599,188 +74183,14 @@ const GraphViewer = memo(
73599
74183
  },
73600
74184
  [indexedRepos]
73601
74185
  );
73602
- const suppressNextFitRef = useRef(false);
73603
- const {
73604
- graphData,
73605
- loading,
73606
- error,
73607
- stats,
73608
- lastSearchQuery,
73609
- graphVersion,
73610
- loadGraph,
73611
- setError
73612
- } = useGraph();
73613
- const graphDataRef = useRef(graphData);
73614
- useEffect(() => {
73615
- graphDataRef.current = graphData;
73616
- }, [graphData]);
73617
- useEffect(() => {
73618
- if (graphVersion === 0) return;
73619
- if (suppressNextFitRef.current) {
73620
- suppressNextFitRef.current = false;
73621
- return;
73622
- }
73623
- canvasRef.current?.scheduleAutoFit?.(400);
73624
- }, [graphVersion]);
73625
- const chatHighlightLinks = useMemo(() => {
73626
- if (!chatHighlightNodes || chatHighlightNodes.size < 2)
73627
- return EMPTY_SET;
73628
- const links = /* @__PURE__ */ new Set();
73629
- for (const link of graphData.links) {
73630
- if (chatHighlightNodes.has(link.source) && chatHighlightNodes.has(link.target)) {
73631
- links.add(`${link.source}-${link.target}`);
73632
- }
73633
- }
73634
- return links;
73635
- }, [graphData.links, chatHighlightNodes]);
73636
- const {
73637
- selectedNode,
73638
- setSelectedNode,
73639
- selectedLink,
73640
- setSelectedLink,
73641
- setNodeHistory,
73642
- hiddenNodeTypes,
73643
- setHiddenNodeTypes,
73644
- hiddenLinkTypes,
73645
- hiddenSubTypes,
73646
- hiddenCommunities,
73647
- setHiddenCommunities,
73648
- colorMode,
73649
- setColorMode,
73650
- searchQuery,
73651
- setSearchQuery,
73652
- hops,
73653
- setHops,
73654
- focusedCommunityNodes,
73655
- setFocusedCommunityNodes,
73656
- availableSubTypes,
73657
- communityData,
73658
- filteredGraphData,
73659
- highlights
73660
- } = useGraphInteraction();
73661
74186
  const [showResetConfirm, setShowResetConfirm] = useState(false);
73662
74187
  const [showExportModal, setShowExportModal] = useState(false);
73663
74188
  const [exporting, setExporting] = useState(false);
73664
- useEffect(() => {
73665
- if (!chatHighlightNodes || chatHighlightNodes.size === 0) return;
73666
- const now = Date.now();
73667
- setNodeHistory((prev) => {
73668
- const existing = new Set(prev.map((e) => e.id));
73669
- const newEntries = [];
73670
- for (const id of chatHighlightNodes) {
73671
- if (existing.has(id)) continue;
73672
- const node = graphDataRef.current.nodes.find((n2) => n2.id === id);
73673
- if (!node) continue;
73674
- newEntries.push({
73675
- id: node.id,
73676
- name: node.name,
73677
- type: node.type,
73678
- timestamp: now,
73679
- source: "chat"
73680
- });
73681
- }
73682
- if (newEntries.length === 0) return prev;
73683
- return [...newEntries, ...prev].slice(0, 500);
73684
- });
73685
- }, [chatHighlightNodes, setNodeHistory]);
74189
+ const [showPhysicsPanel, setShowPhysicsPanel] = useState(false);
73686
74190
  const pendingMinimize = useRef(false);
73687
74191
  const minimizeTimeoutRef = useRef(
73688
74192
  null
73689
74193
  );
73690
- const [edgeHighlightNodes, setEdgeHighlightNodes] = useState(
73691
- /* @__PURE__ */ new Set()
73692
- );
73693
- const [edgeHighlightLinks, setEdgeHighlightLinks] = useState(
73694
- /* @__PURE__ */ new Set()
73695
- );
73696
- const [edgeLabelNodes, setEdgeLabelNodes] = useState(
73697
- /* @__PURE__ */ new Set()
73698
- );
73699
- const [activeFilter, setActiveFilter] = useState(null);
73700
- const [showPhysicsPanel, setShowPhysicsPanel] = useState(false);
73701
- const stored = useMemo(() => {
73702
- try {
73703
- return JSON.parse(
73704
- localStorage.getItem("graph-settings") ?? "{}"
73705
- );
73706
- } catch {
73707
- return {};
73708
- }
73709
- }, []);
73710
- const ps = (key, def) => stored[key] ?? def;
73711
- const [zoomOnSelect, setZoomOnSelect] = useState(
73712
- () => ps("zoomOnSelect", true)
73713
- );
73714
- const [repulsion, setRepulsion] = useState(() => ps("repulsion", 120));
73715
- const [labelsVisible, setLabelsVisible] = useState(
73716
- () => ps("labelsVisible", true)
73717
- );
73718
- const [physicsRunning, setPhysicsRunning] = useState(false);
73719
- const [pixiLinkDist, setPixiLinkDist] = useState(
73720
- () => ps("pixiLinkDist", 200)
73721
- );
73722
- const [pixiCenter, setPixiCenter] = useState(() => ps("pixiCenter", 0.3));
73723
- const [pixiZoomExponent, setPixiZoomExponent] = useState(
73724
- () => ps("pixiZoomExponent", 0.8)
73725
- );
73726
- const [layoutMode, setLayoutMode] = useState(
73727
- () => ps("layoutMode", "spread")
73728
- );
73729
- const [compactRadial, setCompactRadial] = useState(
73730
- () => ps("compactRadial", 8)
73731
- );
73732
- const [compactCommunity, setCompactCommunity] = useState(
73733
- () => ps("compactCommunity", 10)
73734
- );
73735
- const [compactCentering, setCompactCentering] = useState(
73736
- () => ps("compactCentering", 5)
73737
- );
73738
- const [compactRadius, setCompactRadius] = useState(
73739
- () => ps("compactRadius", 32)
73740
- );
73741
- const [mode3d, setMode3d] = useState(() => ps("mode3d", true));
73742
- const [mode3dSpeed, setMode3dSpeed] = useState(
73743
- () => ps("mode3dSpeed", 30)
73744
- );
73745
- const [mode3dTilt, setMode3dTilt] = useState(() => ps("mode3dTilt", 35));
73746
- const [labelScale, setLabelScale] = useState(() => ps("labelScale", 100));
73747
- const [rendererAutoRotate, setRendererAutoRotate] = useState(null);
73748
- useEffect(() => {
73749
- const settings = {
73750
- repulsion,
73751
- labelsVisible,
73752
- zoomOnSelect,
73753
- pixiLinkDist,
73754
- pixiCenter,
73755
- pixiZoomExponent,
73756
- layoutMode,
73757
- compactRadial,
73758
- compactCommunity,
73759
- compactCentering,
73760
- compactRadius,
73761
- mode3d,
73762
- mode3dSpeed,
73763
- mode3dTilt,
73764
- labelScale
73765
- };
73766
- localStorage.setItem("graph-settings", JSON.stringify(settings));
73767
- }, [
73768
- repulsion,
73769
- labelsVisible,
73770
- zoomOnSelect,
73771
- pixiLinkDist,
73772
- pixiCenter,
73773
- pixiZoomExponent,
73774
- layoutMode,
73775
- compactRadial,
73776
- compactCommunity,
73777
- compactCentering,
73778
- compactRadius,
73779
- mode3d,
73780
- mode3dSpeed,
73781
- mode3dTilt,
73782
- labelScale
73783
- ]);
73784
74194
  useEffect(() => {
73785
74195
  if (jobState.status === "persisted") {
73786
74196
  loadGraph().then(() => {
@@ -73797,259 +74207,11 @@ const GraphViewer = memo(
73797
74207
  });
73798
74208
  }
73799
74209
  }, [jobState.status, loadGraph]);
73800
- const handleSearch = () => {
73801
- if (searchQuery.trim()) {
73802
- loadGraph(searchQuery.trim(), hops);
73803
- }
73804
- };
73805
- const handleReset = () => {
73806
- setSearchQuery("");
73807
- setHops(2);
73808
- setSelectedNode(null);
73809
- setSelectedLink(null);
73810
- setActiveFilter(null);
73811
- setFocusedCommunityNodes(EMPTY_SET);
73812
- setHiddenNodeTypes(/* @__PURE__ */ new Set());
73813
- setHiddenCommunities(/* @__PURE__ */ new Set());
73814
- if (lastSearchQuery) {
73815
- loadGraph();
73816
- }
73817
- };
73818
- const layoutConfig = useMemo(
73819
- () => ({
73820
- ...DEFAULT_LAYOUT_CONFIG,
73821
- fa2ScalingRatio: repulsion
73822
- }),
73823
- [repulsion]
73824
- );
73825
- const onNodeClick = useCallback(
73826
- (node) => {
73827
- setSelectedNode(node);
73828
- setSelectedLink(null);
73829
- setEdgeHighlightNodes(EMPTY_SET);
73830
- setEdgeHighlightLinks(EMPTY_SET);
73831
- setEdgeLabelNodes(EMPTY_SET);
73832
- setFocusedCommunityNodes(EMPTY_SET);
73833
- setNodeHistory((prev) => {
73834
- if (prev.length > 0 && prev[0].id === node.id) return prev;
73835
- const entry = {
73836
- id: node.id,
73837
- name: node.name,
73838
- type: node.type,
73839
- timestamp: Date.now(),
73840
- source: "user"
73841
- };
73842
- return [entry, ...prev].slice(0, 500);
73843
- });
73844
- },
73845
- [
73846
- setSelectedNode,
73847
- setSelectedLink,
73848
- setFocusedCommunityNodes,
73849
- setNodeHistory
73850
- ]
73851
- );
73852
- useEffect(() => {
73853
- if (focusedCommunityNodes.size > 0) {
73854
- canvasRef.current?.zoomToNodes(focusedCommunityNodes, 600);
73855
- }
73856
- }, [focusedCommunityNodes]);
73857
- useImperativeHandle(
73858
- ref,
73859
- () => ({
73860
- selectNode: (nodeId, nodeHops) => {
73861
- if (nodeHops !== void 0) setHops(nodeHops);
73862
- const node = graphDataRef.current.nodes.find(
73863
- (n2) => n2.id === nodeId
73864
- );
73865
- if (node) onNodeClick(node);
73866
- },
73867
- triggerPing: (nodeIds) => {
73868
- canvasRef.current?.triggerPing?.(nodeIds);
73869
- },
73870
- resetCamera: () => {
73871
- canvasRef.current?.resetCamera();
73872
- },
73873
- zoomToFit: (duration2) => {
73874
- canvasRef.current?.zoomToFit(duration2);
73875
- }
73876
- }),
73877
- [onNodeClick, setHops]
73878
- );
73879
- const onLinkClick = useCallback(
73880
- (edge) => {
73881
- setSelectedLink(edge);
73882
- setSelectedNode(null);
73883
- },
73884
- [setSelectedLink, setSelectedNode]
73885
- );
73886
- useEffect(() => {
73887
- if (!selectedLink) {
73888
- setEdgeHighlightNodes(EMPTY_SET);
73889
- setEdgeHighlightLinks(EMPTY_SET);
73890
- setEdgeLabelNodes(EMPTY_SET);
73891
- return;
73892
- }
73893
- const { source: sourceId, target: targetId } = selectedLink;
73894
- setEdgeHighlightNodes(/* @__PURE__ */ new Set([sourceId, targetId]));
73895
- setEdgeHighlightLinks(/* @__PURE__ */ new Set([`${sourceId}-${targetId}`]));
73896
- setEdgeLabelNodes(/* @__PURE__ */ new Set([sourceId, targetId]));
73897
- canvasRef.current?.zoomToNodes([sourceId, targetId], 600);
73898
- }, [selectedLink]);
73899
- useEffect(() => {
73900
- if (!zoomOnSelect) return;
73901
- if (selectedNode) {
73902
- if (highlights.highlightNodes.size > 0) {
73903
- canvasRef.current?.zoomToNodes(highlights.highlightNodes, 600);
73904
- }
73905
- } else if (!selectedLink && focusedCommunityNodes.size === 0) {
73906
- canvasRef.current?.zoomToFit(600);
73907
- }
73908
- }, [
73909
- zoomOnSelect,
73910
- selectedNode?.id,
73911
- !!selectedLink,
73912
- focusedCommunityNodes.size
73913
- ]);
73914
- const legendNodeItems = useMemo(() => {
73915
- const counts = {};
73916
- filteredGraphData.nodes.forEach((n2) => {
73917
- counts[n2.type] = (counts[n2.type] || 0) + 1;
73918
- });
73919
- return Object.entries(counts).map(([label, count]) => ({
73920
- label,
73921
- count,
73922
- color: getNodeColor(label)
73923
- })).sort((a, b) => b.count - a.count);
73924
- }, [filteredGraphData.nodes]);
73925
- const legendCommunityItems = useMemo(() => {
73926
- if (colorMode !== "community") return [];
73927
- const counts = /* @__PURE__ */ new Map();
73928
- for (const n2 of filteredGraphData.nodes) {
73929
- const cid = communityData.assignments[n2.id];
73930
- if (cid !== void 0) {
73931
- counts.set(cid, (counts.get(cid) || 0) + 1);
73932
- }
73933
- }
73934
- return [...counts.entries()].sort((a, b) => b[1] - a[1]).map(([cid, count]) => ({
73935
- label: communityData.names.get(cid) ?? `Community ${cid}`,
73936
- count,
73937
- color: communityData.colorMap.get(cid) ?? "#64748b"
73938
- }));
73939
- }, [colorMode, filteredGraphData.nodes, communityData]);
73940
- const legendItems = colorMode === "community" ? legendCommunityItems : legendNodeItems;
73941
- const searchSuggestions = useMemo(() => {
73942
- const nameMap = /* @__PURE__ */ new Map();
73943
- for (const n2 of graphData.nodes) {
73944
- if (!nameMap.has(n2.name)) {
73945
- const cid = communityData.assignments[n2.id];
73946
- nameMap.set(n2.name, {
73947
- type: n2.type,
73948
- communityId: cid,
73949
- nodeId: n2.id
73950
- });
73951
- }
73952
- }
73953
- const suggestions = [];
73954
- for (const [name, info] of nameMap) {
73955
- const cLabel = info.communityId !== void 0 ? communityData.names.get(info.communityId) : void 0;
73956
- const cColor = info.communityId !== void 0 ? communityData.colorMap.get(info.communityId) : void 0;
73957
- suggestions.push({
73958
- label: name,
73959
- category: "name",
73960
- color: getNodeColor(info.type),
73961
- communityLabel: cLabel,
73962
- communityColor: cColor,
73963
- nodeId: info.nodeId
73964
- });
73965
- }
73966
- for (const [cid, name] of communityData.names) {
73967
- suggestions.push({
73968
- label: name,
73969
- category: "community",
73970
- color: communityData.colorMap.get(cid),
73971
- communityId: cid
73972
- });
73973
- }
73974
- return suggestions;
73975
- }, [graphData.nodes, communityData]);
73976
- const applyFilter = useCallback(
73977
- (filter) => {
73978
- if (!filter) {
73979
- setFocusedCommunityNodes(EMPTY_SET);
73980
- return;
73981
- }
73982
- if (filter.type === "community") {
73983
- const nodeIds = Object.entries(communityData.assignments).filter(([, id]) => id === filter.communityId).map(([nodeId]) => nodeId);
73984
- if (nodeIds.length > 0) {
73985
- const nodeSet = new Set(nodeIds);
73986
- setFocusedCommunityNodes(nodeSet);
73987
- canvasRef.current?.zoomToNodes(nodeSet, 600);
73988
- }
73989
- }
73990
- },
73991
- [communityData.assignments, setFocusedCommunityNodes]
73992
- );
73993
- const handleSuggestionSelect = useCallback(
73994
- (suggestion) => {
73995
- switch (suggestion.category) {
73996
- case "community": {
73997
- const cid = suggestion.communityId;
73998
- if (cid !== void 0) {
73999
- setActiveFilter({ type: "community", communityId: cid });
74000
- applyFilter({ type: "community", communityId: cid });
74001
- setSelectedNode(null);
74002
- setSelectedLink(null);
74003
- }
74004
- break;
74005
- }
74006
- default: {
74007
- setActiveFilter(null);
74008
- const targetId = suggestion.nodeId;
74009
- loadGraph(suggestion.label, hops).then(() => {
74010
- if (targetId) {
74011
- const node = graphDataRef.current.nodes.find(
74012
- (n2) => n2.id === targetId
74013
- );
74014
- if (node) {
74015
- onNodeClick(node);
74016
- setTimeout(() => {
74017
- canvasRef.current?.zoomToNodes(/* @__PURE__ */ new Set([targetId]), 600);
74018
- }, 100);
74019
- }
74020
- }
74021
- });
74022
- break;
74023
- }
74024
- }
74025
- },
74026
- [
74027
- applyFilter,
74028
- hops,
74029
- loadGraph,
74030
- onNodeClick,
74031
- setSelectedLink,
74032
- setSelectedNode
74033
- ]
74034
- );
74035
- const legendLinkItems = useMemo(() => {
74036
- const counts = {};
74037
- filteredGraphData.links.forEach((l) => {
74038
- const label = l.label || "unknown";
74039
- counts[label] = (counts[label] || 0) + 1;
74040
- });
74041
- return Object.entries(counts).map(([label, count]) => ({
74042
- label,
74043
- count,
74044
- color: getLinkColor(label)
74045
- })).sort((a, b) => b.count - a.count);
74046
- }, [filteredGraphData.links]);
74047
- const isEmpty2 = graphData.nodes.length === 0;
74048
- const isSearchEmpty = isEmpty2 && !!lastSearchQuery;
74049
- const showFullModal = jobState.status === "running" || jobState.status === "persisted" || jobState.status === "error" || (jobState.status === "enriching" || jobState.status === "done") && (jobExpanded || loading && isEmpty2);
74210
+ useImperativeHandle(ref, () => v.buildImperativeHandle(), [v]);
74211
+ const showFullModal = jobState.status === "running" || jobState.status === "persisted" || jobState.status === "error" || (jobState.status === "enriching" || jobState.status === "done") && (jobExpanded || loading && v.isEmpty);
74050
74212
  const graphWidth = showChat || showHelp ? width - chatWidth : width;
74051
74213
  useEffect(() => {
74052
- if (pendingMinimize.current && !isEmpty2) {
74214
+ if (pendingMinimize.current && !v.isEmpty) {
74053
74215
  pendingMinimize.current = false;
74054
74216
  minimizeTimeoutRef.current = setTimeout(() => {
74055
74217
  minimizeTimeoutRef.current = null;
@@ -74062,23 +74224,14 @@ const GraphViewer = memo(
74062
74224
  minimizeTimeoutRef.current = null;
74063
74225
  }
74064
74226
  };
74065
- }, [isEmpty2, onJobMinimize]);
74227
+ }, [v.isEmpty, onJobMinimize]);
74066
74228
  useEffect(() => {
74067
- if (isEmpty2 && !isSearchEmpty && !loading && jobState.status === "idle") {
74229
+ if (v.isEmpty && !v.isSearchEmpty && !loading && jobState.status === "idle") {
74068
74230
  onAddRepoOpen();
74069
74231
  }
74070
- }, [isEmpty2, isSearchEmpty, loading, jobState.status, onAddRepoOpen]);
74071
- const activeFilterRef = useRef(activeFilter);
74072
- activeFilterRef.current = activeFilter;
74073
- const handleStageClick = useCallback(() => {
74074
- setSelectedNode(null);
74075
- setSelectedLink(null);
74076
- setEdgeHighlightNodes(EMPTY_SET);
74077
- setEdgeHighlightLinks(EMPTY_SET);
74078
- setEdgeLabelNodes(EMPTY_SET);
74079
- applyFilter(activeFilterRef.current);
74080
- }, [applyFilter, setSelectedLink, setSelectedNode]);
74081
- if (loading && isEmpty2 && !showAddRepo && !showFullModal) {
74232
+ }, [v.isEmpty, v.isSearchEmpty, loading, jobState.status, onAddRepoOpen]);
74233
+ const persistentActions = useMemo(() => /* @__PURE__ */ jsx(GitHubStarButton, {}), []);
74234
+ if (loading && v.isEmpty && !showAddRepo && !showFullModal) {
74082
74235
  return /* @__PURE__ */ jsx(GraphLoadingState, {});
74083
74236
  }
74084
74237
  if (error) {
@@ -74093,16 +74246,16 @@ const GraphViewer = memo(
74093
74246
  }
74094
74247
  );
74095
74248
  }
74096
- if (isSearchEmpty && !showFullModal) {
74249
+ if (v.isSearchEmpty && !showFullModal) {
74097
74250
  return /* @__PURE__ */ jsx(
74098
74251
  GraphSearchEmpty,
74099
74252
  {
74100
74253
  searchQuery: lastSearchQuery,
74101
- onClearSearch: handleReset
74254
+ onClearSearch: v.toolbar.onReset
74102
74255
  }
74103
74256
  );
74104
74257
  }
74105
- if (isEmpty2 && !showFullModal) {
74258
+ if (v.isEmpty && !showFullModal) {
74106
74259
  return /* @__PURE__ */ jsx(
74107
74260
  GraphInitialEmpty,
74108
74261
  {
@@ -74139,25 +74292,25 @@ const GraphViewer = memo(
74139
74292
  ]
74140
74293
  }
74141
74294
  ),
74142
- searchQuery,
74143
- onSearchQueryChange: setSearchQuery,
74144
- onSearch: handleSearch,
74145
- onReset: handleReset,
74146
- searchDisabled: !searchQuery.trim() || searchQuery === lastSearchQuery,
74147
- showResetButton: !!lastSearchQuery,
74148
- searchSuggestions,
74149
- onSuggestionSelect: handleSuggestionSelect,
74150
- hops,
74151
- onHopsChange: setHops,
74152
- nodeCount: filteredGraphData.nodes.length,
74153
- edgeCount: filteredGraphData.links.length,
74154
- totalNodes: stats?.total_nodes,
74155
- totalEdges: stats?.total_edges,
74295
+ searchQuery: v.toolbar.searchQuery,
74296
+ onSearchQueryChange: v.toolbar.onSearchQueryChange,
74297
+ onSearch: v.toolbar.onSearch,
74298
+ onReset: v.toolbar.onReset,
74299
+ searchDisabled: v.toolbar.searchDisabled,
74300
+ showResetButton: v.toolbar.showResetButton,
74301
+ searchSuggestions: v.toolbar.searchSuggestions,
74302
+ onSuggestionSelect: v.toolbar.onSuggestionSelect,
74303
+ hops: v.toolbar.hops,
74304
+ onHopsChange: v.toolbar.onHopsChange,
74305
+ nodeCount: v.toolbar.nodeCount,
74306
+ edgeCount: v.toolbar.edgeCount,
74307
+ totalNodes: v.toolbar.totalNodes,
74308
+ totalEdges: v.toolbar.totalEdges,
74156
74309
  mobilePanelTabs: buildMobilePanelTabs({
74157
- showDetails: !!(selectedNode || selectedLink)
74310
+ showDetails: v.toolbar.showDetailsTab
74158
74311
  }),
74159
74312
  onMobilePanelTab: (key) => onMobilePanelTabChange?.(key),
74160
- persistentActions: /* @__PURE__ */ jsx(GitHubStarButton, {}),
74313
+ persistentActions,
74161
74314
  actions: /* @__PURE__ */ jsx(
74162
74315
  GraphToolbarActionButtons,
74163
74316
  {
@@ -74228,7 +74381,7 @@ const GraphViewer = memo(
74228
74381
  onValidate: validateRepo
74229
74382
  }
74230
74383
  ),
74231
- isEmpty2 && showFullModal && /* @__PURE__ */ jsx(EmptyStateHeader, {}),
74384
+ v.isEmpty && showFullModal && /* @__PURE__ */ jsx(EmptyStateHeader, {}),
74232
74385
  showFullModal && /* @__PURE__ */ jsx(
74233
74386
  IndexingProgress,
74234
74387
  {
@@ -74237,38 +74390,38 @@ const GraphViewer = memo(
74237
74390
  onClose: onJobClose
74238
74391
  }
74239
74392
  ),
74240
- /* @__PURE__ */ jsx(GraphLegend, { items: legendItems, linkItems: legendLinkItems }),
74393
+ /* @__PURE__ */ jsx(GraphLegend, { items: v.legendItems, linkItems: v.legendLinkItems }),
74241
74394
  /* @__PURE__ */ jsx(
74242
74395
  PixiGraphCanvas,
74243
74396
  {
74244
- ref: canvasRef,
74397
+ ref: v.canvasRef,
74245
74398
  nodes: graphData.nodes,
74246
74399
  links: graphData.links,
74247
74400
  width: graphWidth,
74248
74401
  height,
74249
- layoutConfig,
74402
+ layoutConfig: v.layoutConfig,
74250
74403
  colorMode,
74251
74404
  hiddenNodeTypes,
74252
74405
  hiddenLinkTypes,
74253
74406
  hiddenSubTypes,
74254
74407
  hiddenCommunities,
74255
- searchQuery,
74408
+ searchQuery: v.toolbar.searchQuery,
74256
74409
  selectedNodeId: selectedNode?.id,
74257
- hops,
74410
+ hops: v.toolbar.hops,
74258
74411
  getSubType,
74259
- highlightNodes: selectedLink ? edgeHighlightNodes : focusedCommunityNodes.size > 0 ? focusedCommunityNodes : highlights.highlightNodes.size > 0 ? highlights.highlightNodes : chatHighlightNodes && chatHighlightNodes.size > 0 ? chatHighlightNodes : highlights.highlightNodes,
74260
- highlightLinks: selectedLink ? edgeHighlightLinks : focusedCommunityNodes.size > 0 ? EMPTY_SET : highlights.highlightLinks.size > 0 ? highlights.highlightLinks : chatHighlightLinks.size > 0 ? chatHighlightLinks : highlights.highlightLinks,
74261
- labelNodes: selectedLink ? edgeLabelNodes : focusedCommunityNodes.size > 0 ? focusedCommunityNodes : highlights.labelNodes.size > 0 ? highlights.labelNodes : chatHighlightNodes && chatHighlightNodes.size > 0 ? chatHighlightNodes : highlights.labelNodes,
74412
+ highlightNodes: v.highlightProps.highlightNodes,
74413
+ highlightLinks: v.highlightProps.highlightLinks,
74414
+ labelNodes: v.highlightProps.labelNodes,
74262
74415
  availableSubTypes,
74263
74416
  zIndex: true,
74264
74417
  communityData,
74265
- onNodeClick,
74266
- onEdgeClick: onLinkClick,
74267
- onStageClick: handleStageClick,
74268
- labelsVisible,
74269
- layoutMode,
74270
- mode3d,
74271
- on3DAutoRotateChange: setRendererAutoRotate,
74418
+ onNodeClick: v.onNodeClick,
74419
+ onEdgeClick: v.onLinkClick,
74420
+ onStageClick: v.onStageClick,
74421
+ labelsVisible: v.settings.labelsVisible,
74422
+ layoutMode: v.settings.layoutMode,
74423
+ mode3d: v.settings.mode3d,
74424
+ on3DAutoRotateChange: v.settings.setRendererAutoRotate,
74272
74425
  animationSettings,
74273
74426
  style: { isolation: "isolate" }
74274
74427
  }
@@ -74276,57 +74429,57 @@ const GraphViewer = memo(
74276
74429
  showPhysicsPanel && /* @__PURE__ */ jsx(
74277
74430
  PhysicsPanelContainer,
74278
74431
  {
74279
- canvasRef,
74280
- repulsion,
74281
- setRepulsion,
74282
- labelsVisible,
74283
- setLabelsVisible,
74432
+ canvasRef: v.canvasRef,
74433
+ repulsion: v.settings.repulsion,
74434
+ setRepulsion: v.settings.setRepulsion,
74435
+ labelsVisible: v.settings.labelsVisible,
74436
+ setLabelsVisible: v.settings.setLabelsVisible,
74284
74437
  colorMode,
74285
74438
  setColorMode,
74286
- physicsRunning,
74287
- setPhysicsRunning,
74288
- pixiLinkDist,
74289
- setPixiLinkDist,
74290
- pixiCenter,
74291
- setPixiCenter,
74292
- pixiZoomExponent,
74293
- setPixiZoomExponent,
74294
- layoutMode,
74295
- setLayoutMode,
74296
- compactRadial,
74297
- setCompactRadial,
74298
- compactCommunity,
74299
- setCompactCommunity,
74300
- compactCentering,
74301
- setCompactCentering,
74302
- compactRadius,
74303
- setCompactRadius,
74304
- mode3d,
74305
- setMode3d,
74306
- mode3dSpeed,
74307
- setMode3dSpeed,
74308
- mode3dTilt,
74309
- setMode3dTilt,
74310
- rendererAutoRotate,
74311
- setRendererAutoRotate,
74312
- labelScale,
74313
- setLabelScale
74439
+ physicsRunning: v.settings.physicsRunning,
74440
+ setPhysicsRunning: v.settings.setPhysicsRunning,
74441
+ pixiLinkDist: v.settings.pixiLinkDist,
74442
+ setPixiLinkDist: v.settings.setPixiLinkDist,
74443
+ pixiCenter: v.settings.pixiCenter,
74444
+ setPixiCenter: v.settings.setPixiCenter,
74445
+ pixiZoomExponent: v.settings.pixiZoomExponent,
74446
+ setPixiZoomExponent: v.settings.setPixiZoomExponent,
74447
+ layoutMode: v.settings.layoutMode,
74448
+ setLayoutMode: v.settings.setLayoutMode,
74449
+ compactRadial: v.settings.compactRadial,
74450
+ setCompactRadial: v.settings.setCompactRadial,
74451
+ compactCommunity: v.settings.compactCommunity,
74452
+ setCompactCommunity: v.settings.setCompactCommunity,
74453
+ compactCentering: v.settings.compactCentering,
74454
+ setCompactCentering: v.settings.setCompactCentering,
74455
+ compactRadius: v.settings.compactRadius,
74456
+ setCompactRadius: v.settings.setCompactRadius,
74457
+ mode3d: v.settings.mode3d,
74458
+ setMode3d: v.settings.setMode3d,
74459
+ mode3dSpeed: v.settings.mode3dSpeed,
74460
+ setMode3dSpeed: v.settings.setMode3dSpeed,
74461
+ mode3dTilt: v.settings.mode3dTilt,
74462
+ setMode3dTilt: v.settings.setMode3dTilt,
74463
+ rendererAutoRotate: v.settings.rendererAutoRotate,
74464
+ setRendererAutoRotate: v.settings.setRendererAutoRotate,
74465
+ labelScale: v.settings.labelScale,
74466
+ setLabelScale: v.settings.setLabelScale
74314
74467
  }
74315
74468
  ),
74316
74469
  /* @__PURE__ */ jsx(
74317
74470
  GraphControlsBar,
74318
74471
  {
74319
- canvasRef,
74472
+ canvasRef: v.canvasRef,
74320
74473
  graphFullscreen,
74321
74474
  onToggleGraphFullscreen,
74322
- zoomOnSelect,
74323
- setZoomOnSelect,
74475
+ zoomOnSelect: v.settings.zoomOnSelect,
74476
+ setZoomOnSelect: v.settings.setZoomOnSelect,
74324
74477
  showPhysicsPanel,
74325
74478
  setShowPhysicsPanel,
74326
- layoutMode,
74327
- setLayoutMode,
74328
- mode3d,
74329
- setMode3d
74479
+ layoutMode: v.settings.layoutMode,
74480
+ setLayoutMode: v.settings.setLayoutMode,
74481
+ mode3d: v.settings.mode3d,
74482
+ setMode3d: v.settings.setMode3d
74330
74483
  }
74331
74484
  )
74332
74485
  ] });
@@ -79081,7 +79234,8 @@ export {
79081
79234
  useGraphData as k,
79082
79235
  linkId as l,
79083
79236
  useGraphInteraction as m,
79084
- loadAnimationSettings as n,
79237
+ useGraphViewer as n,
79238
+ loadAnimationSettings as o,
79085
79239
  useGraph as u
79086
79240
  };
79087
- //# sourceMappingURL=SidePanel-BaXstpCn.js.map
79241
+ //# sourceMappingURL=SidePanel-CmyYalhz.js.map