@flanksource/clicky-ui 0.3.45 → 0.3.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +11 -0
- package/README.md +22 -0
- package/dist/ai.cjs +13 -8
- package/dist/ai.cjs.map +1 -1
- package/dist/ai.js +7 -2
- package/dist/ai.js.map +1 -1
- package/dist/components/ErrorWrapper.cjs +2 -3
- package/dist/components/ErrorWrapper.cjs.map +1 -1
- package/dist/components/ErrorWrapper.d.ts.map +1 -1
- package/dist/components/ErrorWrapper.js +3 -4
- package/dist/components/ErrorWrapper.js.map +1 -1
- package/dist/data/AccessMark.cjs +23 -0
- package/dist/data/AccessMark.cjs.map +1 -0
- package/dist/data/AccessMark.d.ts +11 -0
- package/dist/data/AccessMark.d.ts.map +1 -0
- package/dist/data/AccessMark.js +23 -0
- package/dist/data/AccessMark.js.map +1 -0
- package/dist/data/Clicky.cjs +3 -0
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.js +3 -0
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/CodeDiff.cjs +116 -23
- package/dist/data/CodeDiff.cjs.map +1 -1
- package/dist/data/CodeDiff.d.ts +26 -0
- package/dist/data/CodeDiff.d.ts.map +1 -1
- package/dist/data/CodeDiff.js +116 -23
- package/dist/data/CodeDiff.js.map +1 -1
- package/dist/data/FilterPill.cjs +15 -2
- package/dist/data/FilterPill.cjs.map +1 -1
- package/dist/data/FilterPill.d.ts +1 -1
- package/dist/data/FilterPill.d.ts.map +1 -1
- package/dist/data/FilterPill.js +15 -2
- package/dist/data/FilterPill.js.map +1 -1
- package/dist/data/GraphDiagram.cjs +65 -13
- package/dist/data/GraphDiagram.cjs.map +1 -1
- package/dist/data/GraphDiagram.d.ts +9 -2
- package/dist/data/GraphDiagram.d.ts.map +1 -1
- package/dist/data/GraphDiagram.js +66 -14
- package/dist/data/GraphDiagram.js.map +1 -1
- package/dist/data/GraphDiagramGroups.cjs +100 -0
- package/dist/data/GraphDiagramGroups.cjs.map +1 -0
- package/dist/data/GraphDiagramGroups.d.ts +24 -0
- package/dist/data/GraphDiagramGroups.d.ts.map +1 -0
- package/dist/data/GraphDiagramGroups.js +100 -0
- package/dist/data/GraphDiagramGroups.js.map +1 -0
- package/dist/data/GraphDiagramNodes.cjs +17 -31
- package/dist/data/GraphDiagramNodes.cjs.map +1 -1
- package/dist/data/GraphDiagramNodes.d.ts +6 -13
- package/dist/data/GraphDiagramNodes.d.ts.map +1 -1
- package/dist/data/GraphDiagramNodes.js +17 -31
- package/dist/data/GraphDiagramNodes.js.map +1 -1
- package/dist/data/LogViewer.cjs +27 -8
- package/dist/data/LogViewer.cjs.map +1 -1
- package/dist/data/LogViewer.d.ts +11 -3
- package/dist/data/LogViewer.d.ts.map +1 -1
- package/dist/data/LogViewer.js +27 -8
- package/dist/data/LogViewer.js.map +1 -1
- package/dist/data/Properties.cjs +2 -15
- package/dist/data/Properties.cjs.map +1 -1
- package/dist/data/Properties.d.ts +4 -0
- package/dist/data/Properties.d.ts.map +1 -1
- package/dist/data/Properties.js +2 -15
- package/dist/data/Properties.js.map +1 -1
- package/dist/data/PropertyValue.cjs +37 -0
- package/dist/data/PropertyValue.cjs.map +1 -0
- package/dist/data/PropertyValue.d.ts +6 -0
- package/dist/data/PropertyValue.d.ts.map +1 -0
- package/dist/data/PropertyValue.js +37 -0
- package/dist/data/PropertyValue.js.map +1 -0
- package/dist/data/Tree.cjs +4 -3
- package/dist/data/Tree.cjs.map +1 -1
- package/dist/data/Tree.d.ts +3 -1
- package/dist/data/Tree.d.ts.map +1 -1
- package/dist/data/Tree.js +4 -3
- package/dist/data/Tree.js.map +1 -1
- package/dist/data/TreeNode.cjs +1 -1
- package/dist/data/TreeNode.cjs.map +1 -1
- package/dist/data/TreeNode.d.ts.map +1 -1
- package/dist/data/TreeNode.js +1 -1
- package/dist/data/TreeNode.js.map +1 -1
- package/dist/data/ai/ChatFab.cjs +1 -1
- package/dist/data/ai/ChatFab.cjs.map +1 -1
- package/dist/data/ai/ChatFab.js +1 -1
- package/dist/data/ai/ChatFab.js.map +1 -1
- package/dist/data/ai/ChatWindow.cjs +106 -171
- package/dist/data/ai/ChatWindow.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.d.ts +6 -2
- package/dist/data/ai/ChatWindow.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.header.cjs +104 -0
- package/dist/data/ai/ChatWindow.header.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.header.d.ts +29 -0
- package/dist/data/ai/ChatWindow.header.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.header.js +104 -0
- package/dist/data/ai/ChatWindow.header.js.map +1 -0
- package/dist/data/ai/ChatWindow.js +107 -172
- package/dist/data/ai/ChatWindow.js.map +1 -1
- package/dist/data/ai/ChatWindow.placement.cjs +95 -0
- package/dist/data/ai/ChatWindow.placement.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.placement.d.ts +32 -0
- package/dist/data/ai/ChatWindow.placement.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.placement.js +95 -0
- package/dist/data/ai/ChatWindow.placement.js.map +1 -0
- package/dist/data/ai/SessionChatComposer.cjs +3 -1
- package/dist/data/ai/SessionChatComposer.cjs.map +1 -1
- package/dist/data/ai/SessionChatComposer.d.ts +4 -1
- package/dist/data/ai/SessionChatComposer.d.ts.map +1 -1
- package/dist/data/ai/SessionChatComposer.js +3 -1
- package/dist/data/ai/SessionChatComposer.js.map +1 -1
- package/dist/data/ai/SessionInspector.cjs +68 -72
- package/dist/data/ai/SessionInspector.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.composer-slot.cjs +8 -0
- package/dist/data/ai/SessionInspector.composer-slot.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.composer-slot.d.ts +9 -0
- package/dist/data/ai/SessionInspector.composer-slot.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.composer-slot.js +8 -0
- package/dist/data/ai/SessionInspector.composer-slot.js.map +1 -0
- package/dist/data/ai/SessionInspector.d.ts +6 -1
- package/dist/data/ai/SessionInspector.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.js +69 -73
- package/dist/data/ai/SessionInspector.js.map +1 -1
- package/dist/data/ai/SessionInspector.legacy.cjs +41 -42
- package/dist/data/ai/SessionInspector.legacy.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.legacy.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.legacy.js +41 -42
- package/dist/data/ai/SessionInspector.legacy.js.map +1 -1
- package/dist/data/ai/SessionInspector.remote-view.cjs +14 -9
- package/dist/data/ai/SessionInspector.remote-view.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.remote-view.d.ts +6 -2
- package/dist/data/ai/SessionInspector.remote-view.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.remote-view.js +14 -9
- package/dist/data/ai/SessionInspector.remote-view.js.map +1 -1
- package/dist/data/ai/SessionInspector.remote.cjs +84 -16
- package/dist/data/ai/SessionInspector.remote.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.remote.d.ts +42 -7
- package/dist/data/ai/SessionInspector.remote.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.remote.js +86 -18
- package/dist/data/ai/SessionInspector.remote.js.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.cjs +5 -0
- package/dist/data/ai/SessionInspector.transcript.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.js +5 -0
- package/dist/data/ai/SessionInspector.transcript.js.map +1 -1
- package/dist/data/ai/SessionTail.cjs +63 -0
- package/dist/data/ai/SessionTail.cjs.map +1 -0
- package/dist/data/ai/SessionTail.d.ts +14 -0
- package/dist/data/ai/SessionTail.d.ts.map +1 -0
- package/dist/data/ai/SessionTail.js +63 -0
- package/dist/data/ai/SessionTail.js.map +1 -0
- package/dist/data/ai/SessionViewer.cjs +10 -3
- package/dist/data/ai/SessionViewer.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.d.ts +7 -1
- package/dist/data/ai/SessionViewer.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.js +10 -3
- package/dist/data/ai/SessionViewer.js.map +1 -1
- package/dist/data/ai/SessionViewer.unified.d.ts +14 -0
- package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
- package/dist/data/ai/index.d.ts +4 -3
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/ai/use-session-scroll.cjs +30 -6
- package/dist/data/ai/use-session-scroll.cjs.map +1 -1
- package/dist/data/ai/use-session-scroll.d.ts +7 -0
- package/dist/data/ai/use-session-scroll.d.ts.map +1 -1
- package/dist/data/ai/use-session-scroll.js +30 -6
- package/dist/data/ai/use-session-scroll.js.map +1 -1
- package/dist/data/call-graph/CallGraph.cjs +50 -31
- package/dist/data/call-graph/CallGraph.cjs.map +1 -1
- package/dist/data/call-graph/CallGraph.d.ts +10 -1
- package/dist/data/call-graph/CallGraph.d.ts.map +1 -1
- package/dist/data/call-graph/CallGraph.js +52 -33
- package/dist/data/call-graph/CallGraph.js.map +1 -1
- package/dist/data/call-graph/CallGraphMembers.cjs +5 -4
- package/dist/data/call-graph/CallGraphMembers.cjs.map +1 -1
- package/dist/data/call-graph/CallGraphMembers.d.ts +1 -1
- package/dist/data/call-graph/CallGraphMembers.d.ts.map +1 -1
- package/dist/data/call-graph/CallGraphMembers.js +5 -4
- package/dist/data/call-graph/CallGraphMembers.js.map +1 -1
- package/dist/data/call-graph/CallGraphToolbar.cjs +17 -5
- package/dist/data/call-graph/CallGraphToolbar.cjs.map +1 -1
- package/dist/data/call-graph/CallGraphToolbar.d.ts +10 -0
- package/dist/data/call-graph/CallGraphToolbar.d.ts.map +1 -1
- package/dist/data/call-graph/CallGraphToolbar.js +18 -6
- package/dist/data/call-graph/CallGraphToolbar.js.map +1 -1
- package/dist/data/call-graph/call-graph-model.cjs +169 -18
- package/dist/data/call-graph/call-graph-model.cjs.map +1 -1
- package/dist/data/call-graph/call-graph-model.d.ts +40 -4
- package/dist/data/call-graph/call-graph-model.d.ts.map +1 -1
- package/dist/data/call-graph/call-graph-model.js +170 -19
- package/dist/data/call-graph/call-graph-model.js.map +1 -1
- package/dist/data/call-graph/call-graph-vocabulary.cjs +19 -1
- package/dist/data/call-graph/call-graph-vocabulary.cjs.map +1 -1
- package/dist/data/call-graph/call-graph-vocabulary.d.ts +4 -0
- package/dist/data/call-graph/call-graph-vocabulary.d.ts.map +1 -1
- package/dist/data/call-graph/call-graph-vocabulary.js +19 -1
- package/dist/data/call-graph/call-graph-vocabulary.js.map +1 -1
- package/dist/data/call-graph/call-graph.fixtures.d.ts.map +1 -1
- package/dist/data/call-graph/index.d.ts +2 -2
- package/dist/data/call-graph/index.d.ts.map +1 -1
- package/dist/data/call-graph/types.cjs.map +1 -1
- package/dist/data/call-graph/types.d.ts +7 -2
- package/dist/data/call-graph/types.d.ts.map +1 -1
- package/dist/data/call-graph/types.js.map +1 -1
- package/dist/data/chat/Chat.cjs +1 -1
- package/dist/data/chat/Chat.cjs.map +1 -1
- package/dist/data/chat/Chat.js +1 -1
- package/dist/data/chat/Chat.js.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.cjs +4 -4
- package/dist/data/chat/ChatRuntimeToolbar.cjs.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.d.ts.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.js +4 -4
- package/dist/data/chat/ChatRuntimeToolbar.js.map +1 -1
- package/dist/data/chat/PromptInput.cjs +4 -2
- package/dist/data/chat/PromptInput.cjs.map +1 -1
- package/dist/data/chat/PromptInput.d.ts +5 -1
- package/dist/data/chat/PromptInput.d.ts.map +1 -1
- package/dist/data/chat/PromptInput.js +4 -2
- package/dist/data/chat/PromptInput.js.map +1 -1
- package/dist/data/data-access.cjs +8 -0
- package/dist/data/data-access.cjs.map +1 -0
- package/dist/data/data-access.d.ts +5 -0
- package/dist/data/data-access.d.ts.map +1 -0
- package/dist/data/data-access.js +8 -0
- package/dist/data/data-access.js.map +1 -0
- package/dist/data/diagnostics/ErrorDetails.cjs +13 -2
- package/dist/data/diagnostics/ErrorDetails.cjs.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.d.ts +3 -1
- package/dist/data/diagnostics/ErrorDetails.d.ts.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.js +14 -3
- package/dist/data/diagnostics/ErrorDetails.js.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.cjs +3 -2
- package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.js +3 -2
- package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.cjs +5 -0
- package/dist/data/diagnostics/error-diagnostics.cjs.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.d.ts +1 -0
- package/dist/data/diagnostics/error-diagnostics.d.ts.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.js +6 -1
- package/dist/data/diagnostics/error-diagnostics.js.map +1 -1
- package/dist/data/git/GitChangeList.cjs +6 -2
- package/dist/data/git/GitChangeList.cjs.map +1 -1
- package/dist/data/git/GitChangeList.d.ts +6 -1
- package/dist/data/git/GitChangeList.d.ts.map +1 -1
- package/dist/data/git/GitChangeList.js +6 -2
- package/dist/data/git/GitChangeList.js.map +1 -1
- package/dist/data/graph-columns-layout.cjs +47 -16
- package/dist/data/graph-columns-layout.cjs.map +1 -1
- package/dist/data/graph-columns-layout.d.ts +34 -0
- package/dist/data/graph-columns-layout.d.ts.map +1 -1
- package/dist/data/graph-columns-layout.js +47 -16
- package/dist/data/graph-columns-layout.js.map +1 -1
- package/dist/data/graph-diagram-model.cjs +5 -0
- package/dist/data/graph-diagram-model.cjs.map +1 -1
- package/dist/data/graph-diagram-model.d.ts +19 -0
- package/dist/data/graph-diagram-model.d.ts.map +1 -1
- package/dist/data/graph-diagram-model.js +5 -0
- package/dist/data/graph-diagram-model.js.map +1 -1
- package/dist/data/graph-group-window.cjs +60 -0
- package/dist/data/graph-group-window.cjs.map +1 -0
- package/dist/data/graph-group-window.d.ts +33 -0
- package/dist/data/graph-group-window.d.ts.map +1 -0
- package/dist/data/graph-group-window.js +60 -0
- package/dist/data/graph-group-window.js.map +1 -0
- package/dist/data/har/HarPanel.cjs +3 -1
- package/dist/data/har/HarPanel.cjs.map +1 -1
- package/dist/data/har/HarPanel.d.ts +4 -1
- package/dist/data/har/HarPanel.d.ts.map +1 -1
- package/dist/data/har/HarPanel.js +3 -1
- package/dist/data/har/HarPanel.js.map +1 -1
- package/dist/data/test-runner/Expectation.cjs +57 -0
- package/dist/data/test-runner/Expectation.cjs.map +1 -0
- package/dist/data/test-runner/Expectation.d.ts +19 -0
- package/dist/data/test-runner/Expectation.d.ts.map +1 -0
- package/dist/data/test-runner/Expectation.js +57 -0
- package/dist/data/test-runner/Expectation.js.map +1 -0
- package/dist/data/test-runner/MarkIcons.cjs +38 -0
- package/dist/data/test-runner/MarkIcons.cjs.map +1 -0
- package/dist/data/test-runner/MarkIcons.d.ts +15 -0
- package/dist/data/test-runner/MarkIcons.d.ts.map +1 -0
- package/dist/data/test-runner/MarkIcons.js +38 -0
- package/dist/data/test-runner/MarkIcons.js.map +1 -0
- package/dist/data/test-runner/TestDetailPanel.cjs +74 -42
- package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.js +76 -44
- package/dist/data/test-runner/TestDetailPanel.js.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.cjs +23 -27
- package/dist/data/test-runner/TestFailureDetail.cjs.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.d.ts +2 -2
- package/dist/data/test-runner/TestFailureDetail.d.ts.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.js +23 -27
- package/dist/data/test-runner/TestFailureDetail.js.map +1 -1
- package/dist/data/test-runner/TestFilterBar.cjs +87 -93
- package/dist/data/test-runner/TestFilterBar.cjs.map +1 -1
- package/dist/data/test-runner/TestFilterBar.d.ts +3 -2
- package/dist/data/test-runner/TestFilterBar.d.ts.map +1 -1
- package/dist/data/test-runner/TestFilterBar.js +89 -95
- package/dist/data/test-runner/TestFilterBar.js.map +1 -1
- package/dist/data/test-runner/TestRunSummary.cjs +35 -21
- package/dist/data/test-runner/TestRunSummary.cjs.map +1 -1
- package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunSummary.js +35 -21
- package/dist/data/test-runner/TestRunSummary.js.map +1 -1
- package/dist/data/test-runner/TestRunner.cjs +52 -30
- package/dist/data/test-runner/TestRunner.cjs.map +1 -1
- package/dist/data/test-runner/TestRunner.d.ts +3 -2
- package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunner.js +52 -30
- package/dist/data/test-runner/TestRunner.js.map +1 -1
- package/dist/data/test-runner/TestTree.cjs +5 -2
- package/dist/data/test-runner/TestTree.cjs.map +1 -1
- package/dist/data/test-runner/TestTree.d.ts +5 -2
- package/dist/data/test-runner/TestTree.d.ts.map +1 -1
- package/dist/data/test-runner/TestTree.js +5 -2
- package/dist/data/test-runner/TestTree.js.map +1 -1
- package/dist/data/test-runner/TestTreeNode.cjs +27 -19
- package/dist/data/test-runner/TestTreeNode.cjs.map +1 -1
- package/dist/data/test-runner/TestTreeNode.d.ts.map +1 -1
- package/dist/data/test-runner/TestTreeNode.js +28 -20
- package/dist/data/test-runner/TestTreeNode.js.map +1 -1
- package/dist/data/test-runner/adapter.cjs +11 -0
- package/dist/data/test-runner/adapter.cjs.map +1 -1
- package/dist/data/test-runner/adapter.d.ts +18 -7
- package/dist/data/test-runner/adapter.d.ts.map +1 -1
- package/dist/data/test-runner/adapter.js +11 -0
- package/dist/data/test-runner/adapter.js.map +1 -1
- package/dist/data/test-runner/copy.cjs +114 -0
- package/dist/data/test-runner/copy.cjs.map +1 -0
- package/dist/data/test-runner/copy.d.ts +47 -0
- package/dist/data/test-runner/copy.d.ts.map +1 -0
- package/dist/data/test-runner/copy.js +114 -0
- package/dist/data/test-runner/copy.js.map +1 -0
- package/dist/data/test-runner/index.d.ts +5 -2
- package/dist/data/test-runner/index.d.ts.map +1 -1
- package/dist/data/test-runner/marks.cjs +143 -0
- package/dist/data/test-runner/marks.cjs.map +1 -0
- package/dist/data/test-runner/marks.d.ts +30 -0
- package/dist/data/test-runner/marks.d.ts.map +1 -0
- package/dist/data/test-runner/marks.js +143 -0
- package/dist/data/test-runner/marks.js.map +1 -0
- package/dist/data/test-runner/status.cjs +27 -44
- package/dist/data/test-runner/status.cjs.map +1 -1
- package/dist/data/test-runner/status.d.ts +12 -3
- package/dist/data/test-runner/status.d.ts.map +1 -1
- package/dist/data/test-runner/status.js +27 -44
- package/dist/data/test-runner/status.js.map +1 -1
- package/dist/data/use-group-windows.cjs +50 -0
- package/dist/data/use-group-windows.cjs.map +1 -0
- package/dist/data/use-group-windows.d.ts +27 -0
- package/dist/data/use-group-windows.d.ts.map +1 -0
- package/dist/data/use-group-windows.js +50 -0
- package/dist/data/use-group-windows.js.map +1 -0
- package/dist/data/verification/adapterViews.cjs +16 -41
- package/dist/data/verification/adapterViews.cjs.map +1 -1
- package/dist/data/verification/adapterViews.d.ts.map +1 -1
- package/dist/data/verification/adapterViews.js +16 -41
- package/dist/data/verification/adapterViews.js.map +1 -1
- package/dist/data/verification/adapters.cjs +115 -3
- package/dist/data/verification/adapters.cjs.map +1 -1
- package/dist/data/verification/adapters.d.ts.map +1 -1
- package/dist/data/verification/adapters.js +115 -3
- package/dist/data/verification/adapters.js.map +1 -1
- package/dist/data/verification/verifyReportTests.cjs.map +1 -1
- package/dist/data/verification/verifyReportTests.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +54 -3
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +6 -2
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +58 -7
- package/dist/data.js.map +1 -1
- package/dist/hooks/event-hub.cjs +229 -0
- package/dist/hooks/event-hub.cjs.map +1 -0
- package/dist/hooks/event-hub.d.ts +26 -0
- package/dist/hooks/event-hub.d.ts.map +1 -0
- package/dist/hooks/event-hub.js +229 -0
- package/dist/hooks/event-hub.js.map +1 -0
- package/dist/hooks.cjs +2 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.ts +1 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +2 -0
- package/dist/hooks.js.map +1 -1
- package/dist/icons/components/UiLogoEslint.cjs +10 -0
- package/dist/icons/components/UiLogoEslint.cjs.map +1 -0
- package/dist/icons/components/UiLogoEslint.d.ts +9 -0
- package/dist/icons/components/UiLogoEslint.d.ts.map +1 -0
- package/dist/icons/components/UiLogoEslint.js +10 -0
- package/dist/icons/components/UiLogoEslint.js.map +1 -0
- package/dist/icons/components/UiLogoGo.cjs +10 -0
- package/dist/icons/components/UiLogoGo.cjs.map +1 -0
- package/dist/icons/components/UiLogoGo.d.ts +9 -0
- package/dist/icons/components/UiLogoGo.d.ts.map +1 -0
- package/dist/icons/components/UiLogoGo.js +10 -0
- package/dist/icons/components/UiLogoGo.js.map +1 -0
- package/dist/icons/components/UiLogoJest.cjs +10 -0
- package/dist/icons/components/UiLogoJest.cjs.map +1 -0
- package/dist/icons/components/UiLogoJest.d.ts +9 -0
- package/dist/icons/components/UiLogoJest.d.ts.map +1 -0
- package/dist/icons/components/UiLogoJest.js +10 -0
- package/dist/icons/components/UiLogoJest.js.map +1 -0
- package/dist/icons/components/UiLogoMarkdown.cjs +10 -0
- package/dist/icons/components/UiLogoMarkdown.cjs.map +1 -0
- package/dist/icons/components/UiLogoMarkdown.d.ts +9 -0
- package/dist/icons/components/UiLogoMarkdown.d.ts.map +1 -0
- package/dist/icons/components/UiLogoMarkdown.js +10 -0
- package/dist/icons/components/UiLogoMarkdown.js.map +1 -0
- package/dist/icons/components/UiLogoOxc.cjs +10 -0
- package/dist/icons/components/UiLogoOxc.cjs.map +1 -0
- package/dist/icons/components/UiLogoOxc.d.ts +9 -0
- package/dist/icons/components/UiLogoOxc.d.ts.map +1 -0
- package/dist/icons/components/UiLogoOxc.js +10 -0
- package/dist/icons/components/UiLogoOxc.js.map +1 -0
- package/dist/icons/components/UiLogoPlaywright.cjs +10 -0
- package/dist/icons/components/UiLogoPlaywright.cjs.map +1 -0
- package/dist/icons/components/UiLogoPlaywright.d.ts +9 -0
- package/dist/icons/components/UiLogoPlaywright.d.ts.map +1 -0
- package/dist/icons/components/UiLogoPlaywright.js +10 -0
- package/dist/icons/components/UiLogoPlaywright.js.map +1 -0
- package/dist/icons/components/UiLogoPython.cjs +10 -0
- package/dist/icons/components/UiLogoPython.cjs.map +1 -0
- package/dist/icons/components/UiLogoPython.d.ts +9 -0
- package/dist/icons/components/UiLogoPython.d.ts.map +1 -0
- package/dist/icons/components/UiLogoPython.js +10 -0
- package/dist/icons/components/UiLogoPython.js.map +1 -0
- package/dist/icons/components/UiLogoReact.cjs +10 -0
- package/dist/icons/components/UiLogoReact.cjs.map +1 -0
- package/dist/icons/components/UiLogoReact.d.ts +9 -0
- package/dist/icons/components/UiLogoReact.d.ts.map +1 -0
- package/dist/icons/components/UiLogoReact.js +10 -0
- package/dist/icons/components/UiLogoReact.js.map +1 -0
- package/dist/icons/components/UiLogoRuff.cjs +10 -0
- package/dist/icons/components/UiLogoRuff.cjs.map +1 -0
- package/dist/icons/components/UiLogoRuff.d.ts +9 -0
- package/dist/icons/components/UiLogoRuff.d.ts.map +1 -0
- package/dist/icons/components/UiLogoRuff.js +10 -0
- package/dist/icons/components/UiLogoRuff.js.map +1 -0
- package/dist/icons/components/UiLogoTypescript.cjs +10 -0
- package/dist/icons/components/UiLogoTypescript.cjs.map +1 -0
- package/dist/icons/components/UiLogoTypescript.d.ts +9 -0
- package/dist/icons/components/UiLogoTypescript.d.ts.map +1 -0
- package/dist/icons/components/UiLogoTypescript.js +10 -0
- package/dist/icons/components/UiLogoTypescript.js.map +1 -0
- package/dist/icons/components/UiLogoVitest.cjs +10 -0
- package/dist/icons/components/UiLogoVitest.cjs.map +1 -0
- package/dist/icons/components/UiLogoVitest.d.ts +9 -0
- package/dist/icons/components/UiLogoVitest.d.ts.map +1 -0
- package/dist/icons/components/UiLogoVitest.js +10 -0
- package/dist/icons/components/UiLogoVitest.js.map +1 -0
- package/dist/icons/index.d.ts +11 -0
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/registry.cjs +22 -0
- package/dist/icons/registry.cjs.map +1 -1
- package/dist/icons/registry.d.ts.map +1 -1
- package/dist/icons/registry.js +22 -0
- package/dist/icons/registry.js.map +1 -1
- package/dist/icons.cjs +22 -0
- package/dist/icons.cjs.map +1 -1
- package/dist/icons.js +22 -0
- package/dist/icons.js.map +1 -1
- package/dist/index.cjs +56 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +60 -7
- package/dist/index.js.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.cjs +4 -4
- package/dist/overlay/DropdownMenuSubmenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.js +4 -4
- package/dist/overlay/DropdownMenuSubmenu.js.map +1 -1
- package/dist/overlay/modalStack.cjs +13 -6
- package/dist/overlay/modalStack.cjs.map +1 -1
- package/dist/overlay/modalStack.d.ts.map +1 -1
- package/dist/overlay/modalStack.js +13 -6
- package/dist/overlay/modalStack.js.map +1 -1
- package/dist/rpc/InlineError.cjs +12 -43
- package/dist/rpc/InlineError.cjs.map +1 -1
- package/dist/rpc/InlineError.d.ts.map +1 -1
- package/dist/rpc/InlineError.js +13 -44
- package/dist/rpc/InlineError.js.map +1 -1
- package/dist/rpc/OperationScheduleDialog.cjs +63 -10
- package/dist/rpc/OperationScheduleDialog.cjs.map +1 -1
- package/dist/rpc/OperationScheduleDialog.d.ts +4 -0
- package/dist/rpc/OperationScheduleDialog.d.ts.map +1 -1
- package/dist/rpc/OperationScheduleDialog.js +63 -10
- package/dist/rpc/OperationScheduleDialog.js.map +1 -1
- package/dist/rpc/OperationSchedules.cjs +12 -2
- package/dist/rpc/OperationSchedules.cjs.map +1 -1
- package/dist/rpc/OperationSchedules.d.ts.map +1 -1
- package/dist/rpc/OperationSchedules.js +12 -2
- package/dist/rpc/OperationSchedules.js.map +1 -1
- package/dist/rpc/operation-schedule-model.cjs +2 -0
- package/dist/rpc/operation-schedule-model.cjs.map +1 -1
- package/dist/rpc/operation-schedule-model.d.ts.map +1 -1
- package/dist/rpc/operation-schedule-model.js +2 -0
- package/dist/rpc/operation-schedule-model.js.map +1 -1
- package/dist/rpc/operation-schedule-types.d.ts +7 -1
- package/dist/rpc/operation-schedule-types.d.ts.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/dist/data/test-runner/frameworkIcon.cjs +0 -27
- package/dist/data/test-runner/frameworkIcon.cjs.map +0 -1
- package/dist/data/test-runner/frameworkIcon.d.ts +0 -3
- package/dist/data/test-runner/frameworkIcon.d.ts.map +0 -1
- package/dist/data/test-runner/frameworkIcon.js +0 -27
- package/dist/data/test-runner/frameworkIcon.js.map +0 -1
|
@@ -4,6 +4,7 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
|
4
4
|
const react = require("react");
|
|
5
5
|
const button = require("../../components/button.cjs");
|
|
6
6
|
const utils = require("../../lib/utils.cjs");
|
|
7
|
+
const AccessMark = require("../AccessMark.cjs");
|
|
7
8
|
const GraphDiagram = require("../GraphDiagram.cjs");
|
|
8
9
|
const callGraphExclude = require("./call-graph-exclude.cjs");
|
|
9
10
|
const callGraphModel = require("./call-graph-model.cjs");
|
|
@@ -26,7 +27,7 @@ function Alert({ message }) {
|
|
|
26
27
|
if (!message) return null;
|
|
27
28
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "alert", className: "whitespace-pre-wrap rounded-md border border-destructive p-3 text-sm text-destructive", children: message });
|
|
28
29
|
}
|
|
29
|
-
const ACCESS_WORDS = { call: "Calls", read: "Reads", write: "Writes" };
|
|
30
|
+
const ACCESS_WORDS = { call: "Calls", read: "Reads", write: "Writes", variable: "Variables" };
|
|
30
31
|
function accessWords(access) {
|
|
31
32
|
return access.map((type) => ACCESS_WORDS[type]).join(" and ");
|
|
32
33
|
}
|
|
@@ -43,7 +44,11 @@ function CallGraph(props) {
|
|
|
43
44
|
const [exclude, setExclude] = useCallGraph.useHeld(props.exclude, props.onExcludeChange);
|
|
44
45
|
const [access, setAccess] = useCallGraph.useHeld(props.access ?? [...types.CALL_GRAPH_ACCESS], props.onAccessChange);
|
|
45
46
|
const [columns, setColumns] = useCallGraph.useHeld(props.columns ?? false, props.onColumnsChange);
|
|
46
|
-
|
|
47
|
+
const [collapsedGroups, setCollapsedGroups] = useCallGraph.useHeld(props.collapsedGroups ?? [], props.onCollapsedGroupsChange);
|
|
48
|
+
if (callGraphModel.baseAccess(access).length === 0) throw new Error("call graph: access must name at least one of call, read and write");
|
|
49
|
+
if (access.includes("variable") && !(props.dataAccess && props.variableAccess)) {
|
|
50
|
+
throw new Error("call graph: access names variable, but the host does not offer variableAccess");
|
|
51
|
+
}
|
|
47
52
|
const [ownSelection, setOwnSelection] = react.useState();
|
|
48
53
|
const request = root === void 0 ? void 0 : { root, direction, depth, exclude, access, columns, purpose: "load" };
|
|
49
54
|
const key = `call-graph:${JSON.stringify([request ?? null, props.fetchKey ?? null])}`;
|
|
@@ -76,36 +81,42 @@ function CallGraph(props) {
|
|
|
76
81
|
const glyphs = react.useMemo(() => ({
|
|
77
82
|
node: (glyph, words) => /* @__PURE__ */ jsxRuntime.jsx(CallGraphGlyphs.NodeGlyphIcon, { vocabulary, glyph, title: words }),
|
|
78
83
|
edge: (type) => type === "call" ? void 0 : /* @__PURE__ */ jsxRuntime.jsx(CallGraphGlyphs.EdgeTypeGlyph, { type, title: labels[type] }),
|
|
79
|
-
group: (caption) => /* @__PURE__ */ jsxRuntime.jsx(CallGraphGlyphs.GroupCaption, { icon: vocabulary.group.icon, caption })
|
|
84
|
+
group: (caption, glyph) => /* @__PURE__ */ jsxRuntime.jsx(CallGraphGlyphs.GroupCaption, { icon: glyph === void 0 ? vocabulary.group.icon : callGraphVocabulary.requireGlyph(vocabulary, glyph).icon, caption }),
|
|
85
|
+
access: (access2) => /* @__PURE__ */ jsxRuntime.jsx(AccessMark.AccessMark, { access: access2 })
|
|
80
86
|
}), [vocabulary, labels.dispatch, labels.read, labels.write]);
|
|
81
87
|
const guardLabel = props.guardLabel ?? "innermost";
|
|
82
88
|
const diagram = react.useMemo(
|
|
83
|
-
() => graph && visible && callGraphModel.toDiagram({ graph, visible, direction, options: { ...OPTIONS, guardLabel }, glyphs, vocabulary, edgeLabels: labels }),
|
|
84
|
-
[graph, visible, direction, guardLabel, glyphs, vocabulary, labels.call, labels.dispatch, labels.read, labels.write]
|
|
89
|
+
() => graph && visible && callGraphModel.toDiagram({ graph, visible, direction, options: { ...OPTIONS, guardLabel }, glyphs, vocabulary, edgeLabels: labels, collapsed: collapsedGroups }),
|
|
90
|
+
[graph, visible, direction, guardLabel, glyphs, vocabulary, labels.call, labels.dispatch, labels.read, labels.write, collapsedGroups]
|
|
85
91
|
);
|
|
92
|
+
const drawn = diagram == null ? void 0 : diagram.drawn;
|
|
93
|
+
const collapsible = react.useMemo(() => graph && visible ? callGraphModel.collapsibleGroups(graph, visible) : [], [graph, visible]);
|
|
94
|
+
const toggleGroup = (id) => setCollapsedGroups(collapsedGroups.includes(id) ? collapsedGroups.filter((entry) => entry !== id) : [...collapsedGroups, id]);
|
|
86
95
|
const rootId = graph == null ? void 0 : graph.roots[0];
|
|
87
96
|
const selection = props.onSelectedChange ? props.selected : (ownSelection == null ? void 0 : ownSelection.key) === (shown == null ? void 0 : shown.key) ? ownSelection == null ? void 0 : ownSelection.selected : void 0;
|
|
88
97
|
const select = (next) => {
|
|
89
98
|
if (props.onSelectedChange) props.onSelectedChange(next);
|
|
90
99
|
else setOwnSelection(next && shown ? { key: shown.key, selected: next } : void 0);
|
|
91
100
|
};
|
|
92
|
-
const openAction = (node,
|
|
101
|
+
const openAction = (node, drawn2) => {
|
|
93
102
|
var _a2;
|
|
94
103
|
const { onOpenNode, canOpenNode } = props;
|
|
95
|
-
const accepted = onOpenNode && ((canOpenNode == null ? void 0 : canOpenNode(node,
|
|
96
|
-
return action((_a2 = props.nodeHref) == null ? void 0 : _a2.call(props, node,
|
|
104
|
+
const accepted = onOpenNode && ((canOpenNode == null ? void 0 : canOpenNode(node, drawn2)) ?? true) ? () => onOpenNode(node, drawn2) : void 0;
|
|
105
|
+
return action((_a2 = props.nodeHref) == null ? void 0 : _a2.call(props, node, drawn2), accepted);
|
|
97
106
|
};
|
|
98
|
-
const selectedNode = (selection == null ? void 0 : selection.kind) === "node" ?
|
|
99
|
-
const selectedEdge = (selection == null ? void 0 : selection.kind) === "edge" ?
|
|
100
|
-
const
|
|
107
|
+
const selectedNode = (selection == null ? void 0 : selection.kind) === "node" ? drawn == null ? void 0 : drawn.visible.nodes.find((node) => node.id === selection.id) : void 0;
|
|
108
|
+
const selectedEdge = (selection == null ? void 0 : selection.kind) === "edge" ? drawn == null ? void 0 : drawn.visible.edges.find((edge) => edge.id === selection.id) : void 0;
|
|
109
|
+
const mergedEdge = selectedEdge !== void 0 && (drawn == null ? void 0 : drawn.merged.has(selectedEdge.id)) === true;
|
|
110
|
+
const standIn = selectedNode !== void 0 && (drawn == null ? void 0 : drawn.folds.has(selectedNode.id)) === true;
|
|
111
|
+
const guards = useCallGraph.useSiteGuards(props.loadSiteGuards, shown == null ? void 0 : shown.key, mergedEdge ? void 0 : selectedEdge, graph);
|
|
101
112
|
const expansion = (expanding == null ? void 0 : expanding.request.key) === key ? expanding : void 0;
|
|
102
|
-
const expand = async (
|
|
113
|
+
const expand = async (drawn2, id) => {
|
|
103
114
|
var _a2, _b2;
|
|
104
|
-
if (
|
|
105
|
-
if (((_a2 = pendingExpansion.current) == null ? void 0 : _a2.key) ===
|
|
115
|
+
if (drawn2.key !== activeKey.current) return;
|
|
116
|
+
if (((_a2 = pendingExpansion.current) == null ? void 0 : _a2.key) === drawn2.key && pendingExpansion.current.nodeId === id) return;
|
|
106
117
|
(_b2 = pendingExpansion.current) == null ? void 0 : _b2.controller.abort();
|
|
107
|
-
const node = callGraphModel.requireNode(
|
|
108
|
-
const request2 = { key:
|
|
118
|
+
const node = callGraphModel.requireNode(drawn2.graph, id);
|
|
119
|
+
const request2 = { key: drawn2.key, nodeId: id, label: node.label, controller: new AbortController() };
|
|
109
120
|
pendingExpansion.current = request2;
|
|
110
121
|
setExpanding({ request: request2 });
|
|
111
122
|
try {
|
|
@@ -119,15 +130,15 @@ function CallGraph(props) {
|
|
|
119
130
|
purpose: "expand",
|
|
120
131
|
signal: request2.controller.signal
|
|
121
132
|
});
|
|
122
|
-
if (request2.controller.signal.aborted || activeKey.current !==
|
|
133
|
+
if (request2.controller.signal.aborted || activeKey.current !== drawn2.key || pendingExpansion.current !== request2) return;
|
|
123
134
|
setExpanded((held) => {
|
|
124
|
-
if (request2.controller.signal.aborted || activeKey.current !==
|
|
125
|
-
const base = (held == null ? void 0 : held.key) ===
|
|
126
|
-
return { key:
|
|
135
|
+
if (request2.controller.signal.aborted || activeKey.current !== drawn2.key) return held;
|
|
136
|
+
const base = (held == null ? void 0 : held.key) === drawn2.key ? held : drawn2;
|
|
137
|
+
return { key: drawn2.key, graph: callGraphModel.mergeGraph(base.graph, data), revealed: [...base.revealed, ...data.nodes.map((entry) => entry.id)] };
|
|
127
138
|
});
|
|
128
139
|
setExpanding((current) => (current == null ? void 0 : current.request) === request2 ? void 0 : current);
|
|
129
140
|
} catch (error) {
|
|
130
|
-
if (request2.controller.signal.aborted || activeKey.current !==
|
|
141
|
+
if (request2.controller.signal.aborted || activeKey.current !== drawn2.key || pendingExpansion.current !== request2) return;
|
|
131
142
|
setExpanding((current) => (current == null ? void 0 : current.request) === request2 ? { request: request2, error: `Cannot expand ${node.label}: ${useCallGraph.errorMessage(error)}` } : current);
|
|
132
143
|
} finally {
|
|
133
144
|
if (pendingExpansion.current === request2) pendingExpansion.current = void 0;
|
|
@@ -155,7 +166,13 @@ function CallGraph(props) {
|
|
|
155
166
|
onExclude: (patterns) => setExclude(patterns),
|
|
156
167
|
onDefaults: () => setExclude(void 0)
|
|
157
168
|
} } : {},
|
|
158
|
-
...props.dataAccess ? { data: { access, onAccess: setAccess, columns, onColumns: setColumns } } : {},
|
|
169
|
+
...props.dataAccess ? { data: { access, onAccess: setAccess, columns, onColumns: setColumns, variables: props.variableAccess ?? false } } : {},
|
|
170
|
+
...collapsible.length > 0 ? { groupCollapse: {
|
|
171
|
+
anyCollapsed: collapsedGroups.some((id) => collapsible.includes(id)),
|
|
172
|
+
anyExpanded: collapsible.some((id) => !collapsedGroups.includes(id)),
|
|
173
|
+
onExpandAll: () => setCollapsedGroups([]),
|
|
174
|
+
onCollapseAll: () => setCollapsedGroups(collapsible)
|
|
175
|
+
} } : {},
|
|
159
176
|
onDirection: setDirection,
|
|
160
177
|
onDepth: setDepth,
|
|
161
178
|
onFit: () => setOpening({ nonce: opening.nonce + 1, fit: true }),
|
|
@@ -176,7 +193,7 @@ function CallGraph(props) {
|
|
|
176
193
|
graph && ((_b = props.renderHeader) == null ? void 0 : _b.call(props, graph)),
|
|
177
194
|
!shown && load.loading && /* @__PURE__ */ jsxRuntime.jsx(Notice, { children: "Loading call graph…" }),
|
|
178
195
|
graph && !rootId && /* @__PURE__ */ jsxRuntime.jsx(Notice, { children: "The root resolved to no node in this scope." }),
|
|
179
|
-
graph && rootId && graph.edges.length === 0 && access.length < types.CALL_GRAPH_ACCESS.length && /* @__PURE__ */ jsxRuntime.jsx(Notice, { children: `Nothing is reachable with ${accessWords(access)} only.` }),
|
|
196
|
+
graph && rootId && graph.edges.length === 0 && callGraphModel.baseAccess(access).length < types.CALL_GRAPH_ACCESS.length && /* @__PURE__ */ jsxRuntime.jsx(Notice, { children: `Nothing is reachable with ${accessWords(callGraphModel.baseAccess(access))} only.` }),
|
|
180
197
|
graph && rootId && graph.edges.length > 0 && !selectedEdge && !selectedNode && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Select an edge to list its sites, or a node to see its details." }),
|
|
181
198
|
shown && graph && rootId && diagram && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 gap-3", children: [
|
|
182
199
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn("relative min-h-64 min-w-0 flex-1 rounded-lg border border-border bg-background", load.loading && "opacity-60"), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -194,10 +211,12 @@ function CallGraph(props) {
|
|
|
194
211
|
nodeWidth: NODE_WIDTH,
|
|
195
212
|
nodeHeight: NODE_HEIGHT,
|
|
196
213
|
compactNodeHeight: COMPACT_NODE_HEIGHT,
|
|
214
|
+
recordHeaderHeight: 24,
|
|
197
215
|
columnGap: callGraphModel.columnGap(diagram),
|
|
198
216
|
rowGap: ROW_GAP,
|
|
199
217
|
className: "h-full",
|
|
200
218
|
ariaLabel: `Call graph of ${callGraphModel.requireNode(graph, rootId).label}`,
|
|
219
|
+
onGroupToggle: toggleGroup,
|
|
201
220
|
onNodeSelect: (id) => select({ kind: "node", id }),
|
|
202
221
|
onEdgeSelect: (id) => select({ kind: "edge", id }),
|
|
203
222
|
...fresh ? { onNodeExpand: (id) => void expand(fresh, id) } : {},
|
|
@@ -209,15 +228,15 @@ function CallGraph(props) {
|
|
|
209
228
|
(selectedEdge || selectedNode || expansion) && /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "w-80 max-w-[45%] shrink-0 overflow-y-auto rounded-lg border border-border bg-card p-3", "aria-label": "Selection", children: [
|
|
210
229
|
expansion && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", className: "mb-2 text-xs text-muted-foreground", children: expansion.error ?? `Loading more around ${expansion.request.label}…` }),
|
|
211
230
|
(selectedEdge || selectedNode) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-1 flex justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "button", size: "sm", variant: "ghost", "aria-label": "Close selection", onClick: () => select(void 0), children: "×" }) }),
|
|
212
|
-
selectedEdge ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
231
|
+
selectedEdge && drawn ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
213
232
|
CallGraphParts.EdgeSites,
|
|
214
233
|
{
|
|
215
234
|
edge: selectedEdge,
|
|
216
|
-
graph,
|
|
235
|
+
graph: drawn.graph,
|
|
217
236
|
labels,
|
|
218
237
|
guards,
|
|
219
238
|
lazyGuards: props.loadSiteGuards !== void 0,
|
|
220
|
-
siteAction: (props.siteHref || props.onRevealSite) && vocabulary.hasSource(callGraphModel.requireNode(graph, selectedEdge.from)) ? (site) => {
|
|
239
|
+
siteAction: (props.siteHref || props.onRevealSite) && !drawn.folds.has(selectedEdge.from) && vocabulary.hasSource(callGraphModel.requireNode(graph, selectedEdge.from)) ? (site) => {
|
|
221
240
|
var _a2;
|
|
222
241
|
return action((_a2 = props.siteHref) == null ? void 0 : _a2.call(props, site, selectedEdge, graph), props.onRevealSite && (() => {
|
|
223
242
|
var _a3;
|
|
@@ -225,17 +244,17 @@ function CallGraph(props) {
|
|
|
225
244
|
})) ?? {};
|
|
226
245
|
} : void 0
|
|
227
246
|
}
|
|
228
|
-
) : selectedNode && /* @__PURE__ */ jsxRuntime.jsx(
|
|
247
|
+
) : selectedNode && drawn && /* @__PURE__ */ jsxRuntime.jsx(
|
|
229
248
|
CallGraphParts.NodeDetails,
|
|
230
249
|
{
|
|
231
250
|
node: selectedNode,
|
|
232
|
-
graph,
|
|
251
|
+
graph: drawn.graph,
|
|
233
252
|
vocabulary,
|
|
234
253
|
isRoot: selectedNode.id === rootId,
|
|
235
254
|
openLabel: props.openLabel ?? "Open",
|
|
236
|
-
opens: props.nodeHref !== void 0 || props.onOpenNode !== void 0,
|
|
237
|
-
open: openAction(selectedNode, graph),
|
|
238
|
-
onFocus: props.onFocusNode && ((id) => {
|
|
255
|
+
opens: !standIn && (props.nodeHref !== void 0 || props.onOpenNode !== void 0),
|
|
256
|
+
open: standIn ? void 0 : openAction(selectedNode, graph),
|
|
257
|
+
onFocus: standIn ? void 0 : props.onFocusNode && ((id) => {
|
|
239
258
|
var _a2;
|
|
240
259
|
return (_a2 = props.onFocusNode) == null ? void 0 : _a2.call(props, id, graph);
|
|
241
260
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CallGraph.cjs","sources":["../../../src/data/call-graph/CallGraph.tsx"],"sourcesContent":["// A call graph around one root: fetched through the host, with `+N` expansions merged in, the call\n// sites of a selected edge (guards fetched on selection when the host's graph leaves them out) and the\n// details of a selected node. It knows no language: the host's vocabulary names and draws node kinds,\n// and the host's callbacks open nodes and sites.\nimport { useEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { Button } from \"../../components/button\";\nimport { cn } from \"../../lib/utils\";\nimport { GraphDiagram } from \"../GraphDiagram\";\nimport { matchesExclude, type ExcludeMatcher } from \"./call-graph-exclude\";\nimport type { GuardLabel } from \"./call-graph-labels\";\nimport {\n CALL_GRAPH_DEFAULT_DEPTH,\n CALL_GRAPH_MAX_DEPTH,\n columnGap,\n DEFAULT_EDGE_LABELS,\n expansionDirection,\n mergeGraph,\n requireNode,\n toDiagram,\n visibleGraph,\n type DiagramGlyphs,\n type DiagramOptions,\n} from \"./call-graph-model\";\nimport { UIR_CALL_GRAPH_VOCABULARY, type CallGraphVocabulary } from \"./call-graph-vocabulary\";\nimport { EdgeTypeGlyph, GroupCaption, NodeGlyphIcon } from \"./CallGraphGlyphs\";\nimport { EdgeSites, Legend, NodeDetails, type CallGraphAction } from \"./CallGraphParts\";\nimport { CallGraphToolbar } from \"./CallGraphToolbar\";\nimport {\n CALL_GRAPH_ACCESS,\n type CallGraph as Graph,\n type CallGraphAccess,\n type CallGraphDirection,\n type CallGraphEdge,\n type CallGraphEdgeLabels,\n type CallGraphFetchParams,\n type CallGraphGroupFact,\n type CallGraphNode,\n type CallGraphSelection,\n type CallGraphSite,\n} from \"./types\";\nimport { errorMessage, useGraphLoad, useHeld, useSiteGuards, type GraphRequest } from \"./use-call-graph\";\n\nexport interface CallGraphProps<G extends Graph = Graph> {\n /** What the graph is drawn around, in the host's terms. Undefined shows `emptyMessage`. */\n root: string | undefined;\n /** Loads the graph around `params.root`, and one hop around a node for its `+N`. */\n fetchGraph: (params: CallGraphFetchParams) => Promise<G>;\n /** What else `fetchGraph` reads, such as the host's scope: part of the request's key, so a change refetches. */\n fetchKey?: string;\n /** Pass `onDirectionChange` to control it; without one the component holds it, starting here. */\n direction?: CallGraphDirection;\n onDirectionChange?: (direction: CallGraphDirection) => void;\n depth?: number;\n onDepthChange?: (depth: number) => void;\n /** The exclusion patterns; undefined takes the host's defaults. Controlled with `onExcludeChange`. */\n exclude?: string[] | undefined;\n onExcludeChange?: (exclude: string[] | undefined) => void;\n selected?: CallGraphSelection | undefined;\n onSelectedChange?: (selected: CallGraphSelection | undefined) => void;\n /** The source reports reads and writes of data: shows the Access toggles and the Columns switch. */\n dataAccess?: boolean;\n /** The edge types the host follows, never empty; all three by default. Controlled with `onAccessChange`. */\n access?: CallGraphAccess[];\n onAccessChange?: (access: CallGraphAccess[]) => void;\n /** Columns and fields as nodes of their own; collapsed into tables and entities by default. */\n columns?: boolean;\n onColumnsChange?: (columns: boolean) => void;\n /** The groups the graph reached, drawn or excluded. Without it the graph offers no exclusions. */\n groupFacts?: (graph: G) => CallGraphGroupFact[];\n /** The patterns in force when `exclude` is undefined: the host's defaults, as its response reports them. */\n defaultExclude?: (graph: G) => string[];\n /** How a pattern matches a group, for a host with keywords of its own. */\n excludeMatcher?: ExcludeMatcher;\n /**\n * Where a node opens. A node the vocabulary gives no source is never opened, and Open is disabled on\n * a node with no href that `onOpenNode` does not accept.\n */\n nodeHref?: (node: CallGraphNode, graph: G) => string | undefined;\n /** Opens a node; with `nodeHref` it handles a plain click on the link. */\n onOpenNode?: (node: CallGraphNode, graph: G) => void;\n /** Whether `onOpenNode` opens a node; every node by default. */\n canOpenNode?: (node: CallGraphNode, graph: G) => boolean;\n openLabel?: string;\n /** Re-roots the graph on a node, by id: a drawn node the vocabulary can root, or the column behind a field. */\n onFocusNode?: (nodeId: string, graph: G) => void;\n /** Where a call site opens; a site opens only when its caller has a source. */\n siteHref?: (site: CallGraphSite, edge: CallGraphEdge, graph: G) => string | undefined;\n onRevealSite?: (site: CallGraphSite, edge: CallGraphEdge, graph: G) => void;\n /** Fetches the guards of a selected edge's sites, for a host whose graph leaves them out. */\n loadSiteGuards?: (edge: CallGraphEdge, graph: G, signal: AbortSignal) => Promise<CallGraphSite[]>;\n edgeLabels?: Partial<CallGraphEdgeLabels>;\n /** What a conditional edge's pill says of its guards; \"innermost\" by default. The edge's tooltip always lists them. */\n guardLabel?: GuardLabel;\n vocabulary?: CallGraphVocabulary;\n /** Shows a Pin root toggle; the host keeps `root` while pinned. */\n pinned?: boolean;\n onPinnedChange?: (pinned: boolean, rootId: string | undefined) => void;\n /** Host facts above the diagram, such as how the root was resolved. */\n renderHeader?: (graph: G) => ReactNode;\n toolbarEnd?: ReactNode;\n emptyMessage?: ReactNode;\n maxDepth?: number;\n className?: string;\n}\n\ntype Held<G> = { key: string; graph: G; revealed: string[] };\ntype PendingExpansion = { key: string; nodeId: string; label: string; controller: AbortController };\n\nconst NODE_WIDTH = 188;\nconst NODE_HEIGHT = 32;\nconst COMPACT_NODE_HEIGHT = 22;\nconst ROW_GAP = 14;\n/** Node labels are 12px: at this scale they are 7.2px, the smallest that still reads. */\nconst READABLE_SCALE = 0.6;\nconst OPTIONS: Omit<DiagramOptions, \"guardLabel\"> = { truncateAt: 32, grouped: true };\n\nfunction Notice({ children }: { children: ReactNode }) {\n return (\n <div className=\"flex h-full items-center justify-center p-6 text-center\">\n <span className=\"text-sm text-muted-foreground\">{children}</span>\n </div>\n );\n}\n\nfunction Alert({ message }: { message: string | undefined }) {\n if (!message) return null;\n return <div role=\"alert\" className=\"whitespace-pre-wrap rounded-md border border-destructive p-3 text-sm text-destructive\">{message}</div>;\n}\n\nconst ACCESS_WORDS: Record<CallGraphAccess, string> = { call: \"Calls\", read: \"Reads\", write: \"Writes\" };\n\nfunction accessWords(access: readonly CallGraphAccess[]): string {\n return access.map((type) => ACCESS_WORDS[type]).join(\" and \");\n}\n\nfunction action(href: string | undefined, onSelect: (() => void) | undefined): CallGraphAction | undefined {\n if (href === undefined && onSelect === undefined) return undefined;\n return { ...(href !== undefined ? { href } : {}), ...(onSelect ? { onSelect } : {}) };\n}\n\nexport function CallGraph<G extends Graph = Graph>(props: CallGraphProps<G>) {\n const { root, fetchGraph, vocabulary = UIR_CALL_GRAPH_VOCABULARY, maxDepth = CALL_GRAPH_MAX_DEPTH } = props;\n const labels: CallGraphEdgeLabels = { ...DEFAULT_EDGE_LABELS, ...props.edgeLabels };\n const [direction, setDirection] = useHeld(props.direction ?? \"both\", props.onDirectionChange);\n const [depth, setDepth] = useHeld(props.depth ?? CALL_GRAPH_DEFAULT_DEPTH, props.onDepthChange);\n const [exclude, setExclude] = useHeld(props.exclude, props.onExcludeChange);\n const [access, setAccess] = useHeld(props.access ?? [...CALL_GRAPH_ACCESS], props.onAccessChange);\n const [columns, setColumns] = useHeld(props.columns ?? false, props.onColumnsChange);\n if (access.length === 0) throw new Error(\"call graph: access must name at least one of call, read and write\");\n const [ownSelection, setOwnSelection] = useState<{ key: string; selected: CallGraphSelection }>();\n\n const request: GraphRequest | undefined = root === undefined ? undefined : { root, direction, depth, exclude, access, columns, purpose: \"load\" };\n const key = `call-graph:${JSON.stringify([request ?? null, props.fetchKey ?? null])}`;\n const load = useGraphLoad(fetchGraph, request, key);\n\n const [expanded, setExpanded] = useState<Held<G>>();\n const [expanding, setExpanding] = useState<{ request: PendingExpansion; error?: string }>();\n const pendingExpansion = useRef<PendingExpansion | undefined>(undefined);\n const activeKey = useRef(key);\n activeKey.current = key;\n useEffect(() => {\n setExpanding((current) => current?.request.key === key && !current.request.controller.signal.aborted ? current : undefined);\n return () => {\n if (pendingExpansion.current?.key === key) {\n pendingExpansion.current.controller.abort();\n pendingExpansion.current = undefined;\n }\n };\n }, [key]);\n const [opening, setOpening] = useState({ nonce: 0, fit: false });\n const fresh = useMemo<Held<G> | undefined>(\n () => load.fresh && (expanded?.key === key ? expanded : { key, graph: load.fresh, revealed: [] }),\n [load.fresh, expanded, key],\n );\n const [last, setLast] = useState<Held<G>>();\n if (fresh && fresh !== last) setLast(fresh);\n const shown = root === undefined ? undefined : (fresh ?? last);\n const graph = shown?.graph;\n\n const visible = useMemo(() => shown && visibleGraph(shown.graph, { direction, depth, revealed: shown.revealed }), [shown, direction, depth]);\n const glyphs = useMemo<DiagramGlyphs>(() => ({\n node: (glyph, words) => <NodeGlyphIcon vocabulary={vocabulary} glyph={glyph} title={words} />,\n edge: (type) => (type === \"call\" ? undefined : <EdgeTypeGlyph type={type} title={labels[type]} />),\n group: (caption) => <GroupCaption icon={vocabulary.group.icon} caption={caption} />,\n }), [vocabulary, labels.dispatch, labels.read, labels.write]);\n const guardLabel = props.guardLabel ?? \"innermost\";\n const diagram = useMemo(\n () => graph && visible && toDiagram({ graph, visible, direction, options: { ...OPTIONS, guardLabel }, glyphs, vocabulary, edgeLabels: labels }),\n [graph, visible, direction, guardLabel, glyphs, vocabulary, labels.call, labels.dispatch, labels.read, labels.write],\n );\n\n const rootId = graph?.roots[0];\n const selection = props.onSelectedChange ? props.selected : ownSelection?.key === shown?.key ? ownSelection?.selected : undefined;\n const select = (next: CallGraphSelection | undefined) => {\n if (props.onSelectedChange) props.onSelectedChange(next);\n else setOwnSelection(next && shown ? { key: shown.key, selected: next } : undefined);\n };\n const openAction = (node: CallGraphNode, drawn: G) => {\n const { onOpenNode, canOpenNode } = props;\n const accepted = onOpenNode && (canOpenNode?.(node, drawn) ?? true) ? () => onOpenNode(node, drawn) : undefined;\n return action(props.nodeHref?.(node, drawn), accepted);\n };\n const selectedNode = selection?.kind === \"node\" ? visible?.nodes.find((node) => node.id === selection.id) : undefined;\n const selectedEdge = selection?.kind === \"edge\" ? visible?.edges.find((edge) => edge.id === selection.id) : undefined;\n const guards = useSiteGuards(props.loadSiteGuards, shown?.key, selectedEdge, graph);\n const expansion = expanding?.request.key === key ? expanding : undefined;\n\n // A `+N` loads one more hop on the node's outer side and merges it into the graph this request drew.\n const expand = async (drawn: Held<G>, id: string) => {\n if (drawn.key !== activeKey.current) return;\n if (pendingExpansion.current?.key === drawn.key && pendingExpansion.current.nodeId === id) return;\n pendingExpansion.current?.controller.abort();\n const node = requireNode(drawn.graph, id);\n const request: PendingExpansion = { key: drawn.key, nodeId: id, label: node.label, controller: new AbortController() };\n pendingExpansion.current = request;\n setExpanding({ request });\n try {\n const data = await fetchGraph({\n root: id, direction: expansionDirection(node), depth: 1, exclude, access, columns, purpose: \"expand\", signal: request.controller.signal,\n });\n if (request.controller.signal.aborted || activeKey.current !== drawn.key || pendingExpansion.current !== request) return;\n setExpanded((held) => {\n if (request.controller.signal.aborted || activeKey.current !== drawn.key) return held;\n const base = held?.key === drawn.key ? held : drawn;\n return { key: drawn.key, graph: mergeGraph(base.graph, data), revealed: [...base.revealed, ...data.nodes.map((entry) => entry.id)] };\n });\n setExpanding((current) => current?.request === request ? undefined : current);\n } catch (error) {\n if (request.controller.signal.aborted || activeKey.current !== drawn.key || pendingExpansion.current !== request) return;\n setExpanding((current) => current?.request === request\n ? { request, error: `Cannot expand ${node.label}: ${errorMessage(error)}` } : current);\n } finally {\n if (pendingExpansion.current === request) pendingExpansion.current = undefined;\n }\n };\n\n const groups = graph && props.groupFacts?.(graph);\n const effectiveExclude = exclude ?? (graph && props.defaultExclude ? props.defaultExclude(graph) : []);\n const { onPinnedChange } = props;\n const toolbar = (\n <CallGraphToolbar direction={direction} depth={depth} maxDepth={maxDepth} omitted={graph?.omitted} end={props.toolbarEnd} vocabulary={vocabulary}\n {...(onPinnedChange ? { pin: { pinned: props.pinned ?? false, canPin: rootId !== undefined, onPin: (pinned: boolean) => onPinnedChange(pinned, rootId) } } : {})}\n {...(groups ? { exclusions: { exclude: effectiveExclude, groups, matches: props.excludeMatcher ?? matchesExclude, busy: load.loading, vocabulary,\n onExclude: (patterns: string[]) => setExclude(patterns), onDefaults: () => setExclude(undefined) } } : {})}\n {...(props.dataAccess ? { data: { access, onAccess: setAccess, columns, onColumns: setColumns } } : {})}\n onDirection={setDirection} onDepth={setDepth}\n onFit={() => setOpening({ nonce: opening.nonce + 1, fit: true })} onReset={() => setOpening({ nonce: opening.nonce + 1, fit: false })} />\n );\n\n const frame = cn(\"flex h-full min-h-0 flex-col gap-2 p-2\", props.className);\n if (root === undefined) {\n return <div className={frame}>{toolbar}<Notice>{props.emptyMessage ?? \"Select a node to draw its call graph.\"}</Notice></div>;\n }\n const loadError = load.error && `Cannot draw the call graph: ${load.error}`;\n return (\n <div className={frame} aria-busy={load.loading}>\n {toolbar}\n <Alert message={loadError} />\n {graph && props.renderHeader?.(graph)}\n {!shown && load.loading && <Notice>Loading call graph…</Notice>}\n {graph && !rootId && <Notice>The root resolved to no node in this scope.</Notice>}\n {graph && rootId && graph.edges.length === 0 && access.length < CALL_GRAPH_ACCESS.length && (\n <Notice>{`Nothing is reachable with ${accessWords(access)} only.`}</Notice>\n )}\n {graph && rootId && graph.edges.length > 0 && !selectedEdge && !selectedNode && (\n <p className=\"text-xs text-muted-foreground\">Select an edge to list its sites, or a node to see its details.</p>\n )}\n {shown && graph && rootId && diagram && (\n <div className=\"flex min-h-0 flex-1 gap-3\">\n <div className={cn(\"relative min-h-64 min-w-0 flex-1 rounded-lg border border-border bg-background\", load.loading && \"opacity-60\")}>\n <GraphDiagram key={`${shown.key}:${opening.nonce}`} nodes={diagram.nodes} edges={diagram.edges} groups={diagram.groups} layout=\"columns\" zoomable wheelZoom=\"zoom\" edgeFocus=\"auto\"\n focusId={rootId} {...(opening.fit ? {} : { fitMinScale: READABLE_SCALE })} nodeWidth={NODE_WIDTH} nodeHeight={NODE_HEIGHT} compactNodeHeight={COMPACT_NODE_HEIGHT} columnGap={columnGap(diagram)} rowGap={ROW_GAP}\n className=\"h-full\" ariaLabel={`Call graph of ${requireNode(graph, rootId).label}`}\n onNodeSelect={(id: string) => select({ kind: \"node\", id })} onEdgeSelect={(id: string) => select({ kind: \"edge\", id })}\n {...(fresh ? { onNodeExpand: (id: string) => void expand(fresh, id) } : {})}\n {...(selectedNode ? { selectedId: selectedNode.id } : {})} {...(selectedEdge ? { selectedEdgeId: selectedEdge.id } : {})} />\n </div>\n {(selectedEdge || selectedNode || expansion) && (\n <aside className=\"w-80 max-w-[45%] shrink-0 overflow-y-auto rounded-lg border border-border bg-card p-3\" aria-label=\"Selection\">\n {expansion && <p role=\"status\" className=\"mb-2 text-xs text-muted-foreground\">{expansion.error ?? `Loading more around ${expansion.request.label}…`}</p>}\n {(selectedEdge || selectedNode) && (\n <div className=\"mb-1 flex justify-end\">\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" aria-label=\"Close selection\" onClick={() => select(undefined)}>×</Button>\n </div>\n )}\n {selectedEdge ? (\n <EdgeSites edge={selectedEdge} graph={graph} labels={labels} guards={guards} lazyGuards={props.loadSiteGuards !== undefined}\n siteAction={(props.siteHref || props.onRevealSite) && vocabulary.hasSource(requireNode(graph, selectedEdge.from))\n ? (site) => action(props.siteHref?.(site, selectedEdge, graph), props.onRevealSite && (() => props.onRevealSite?.(site, selectedEdge, graph))) ?? {}\n : undefined} />\n ) : selectedNode && (\n <NodeDetails node={selectedNode} graph={graph} vocabulary={vocabulary} isRoot={selectedNode.id === rootId} openLabel={props.openLabel ?? \"Open\"}\n opens={props.nodeHref !== undefined || props.onOpenNode !== undefined} open={openAction(selectedNode, graph)}\n onFocus={props.onFocusNode && ((id: string) => props.onFocusNode?.(id, graph))} />\n )}\n </aside>\n )}\n </div>\n )}\n {graph && rootId && <div className=\"shrink-0\"><Legend graph={graph} vocabulary={vocabulary} labels={labels} /></div>}\n </div>\n );\n}\n"],"names":["jsx","UIR_CALL_GRAPH_VOCABULARY","CALL_GRAPH_MAX_DEPTH","DEFAULT_EDGE_LABELS","useHeld","CALL_GRAPH_DEFAULT_DEPTH","CALL_GRAPH_ACCESS","useState","useGraphLoad","useRef","useEffect","_a","useMemo","visibleGraph","NodeGlyphIcon","EdgeTypeGlyph","GroupCaption","toDiagram","useSiteGuards","_b","requireNode","request","expansionDirection","mergeGraph","errorMessage","CallGraphToolbar","matchesExclude","cn","jsxs","GraphDiagram","columnGap","Button","EdgeSites","NodeDetails","Legend"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CallGraph.cjs","sources":["../../../src/data/call-graph/CallGraph.tsx"],"sourcesContent":["// A call graph around one root: fetched through the host, with `+N` expansions merged in, the call\n// sites of a selected edge (guards fetched on selection when the host's graph leaves them out) and the\n// details of a selected node. It knows no language: the host's vocabulary names and draws node kinds,\n// and the host's callbacks open nodes and sites.\nimport { useEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport { Button } from \"../../components/button\";\nimport { cn } from \"../../lib/utils\";\nimport { AccessMark } from \"../AccessMark\";\nimport { GraphDiagram } from \"../GraphDiagram\";\nimport { matchesExclude, type ExcludeMatcher } from \"./call-graph-exclude\";\nimport type { GuardLabel } from \"./call-graph-labels\";\nimport {\n baseAccess,\n CALL_GRAPH_DEFAULT_DEPTH,\n CALL_GRAPH_MAX_DEPTH,\n collapsibleGroups,\n columnGap,\n DEFAULT_EDGE_LABELS,\n expansionDirection,\n mergeGraph,\n requireNode,\n toDiagram,\n visibleGraph,\n type DiagramGlyphs,\n type DiagramOptions,\n} from \"./call-graph-model\";\nimport { requireGlyph, UIR_CALL_GRAPH_VOCABULARY, type CallGraphVocabulary } from \"./call-graph-vocabulary\";\nimport { EdgeTypeGlyph, GroupCaption, NodeGlyphIcon } from \"./CallGraphGlyphs\";\nimport { EdgeSites, Legend, NodeDetails, type CallGraphAction } from \"./CallGraphParts\";\nimport { CallGraphToolbar } from \"./CallGraphToolbar\";\nimport {\n CALL_GRAPH_ACCESS,\n type CallGraph as Graph,\n type CallGraphAccess,\n type CallGraphDirection,\n type CallGraphEdge,\n type CallGraphEdgeLabels,\n type CallGraphFetchParams,\n type CallGraphGroupFact,\n type CallGraphNode,\n type CallGraphSelection,\n type CallGraphSite,\n} from \"./types\";\nimport { errorMessage, useGraphLoad, useHeld, useSiteGuards, type GraphRequest } from \"./use-call-graph\";\n\nexport interface CallGraphProps<G extends Graph = Graph> {\n /** What the graph is drawn around, in the host's terms. Undefined shows `emptyMessage`. */\n root: string | undefined;\n /** Loads the graph around `params.root`, and one hop around a node for its `+N`. */\n fetchGraph: (params: CallGraphFetchParams) => Promise<G>;\n /** What else `fetchGraph` reads, such as the host's scope: part of the request's key, so a change refetches. */\n fetchKey?: string;\n /** Pass `onDirectionChange` to control it; without one the component holds it, starting here. */\n direction?: CallGraphDirection;\n onDirectionChange?: (direction: CallGraphDirection) => void;\n depth?: number;\n onDepthChange?: (depth: number) => void;\n /** The exclusion patterns; undefined takes the host's defaults. Controlled with `onExcludeChange`. */\n exclude?: string[] | undefined;\n onExcludeChange?: (exclude: string[] | undefined) => void;\n selected?: CallGraphSelection | undefined;\n onSelectedChange?: (selected: CallGraphSelection | undefined) => void;\n /** The source reports reads and writes of data: shows the Access toggles and the Columns switch. */\n dataAccess?: boolean;\n /** The source can follow the variables a body reads and writes: shows a Variables toggle beside the Access ones. Needs `dataAccess`. */\n variableAccess?: boolean;\n /** The edge types the host follows, at least one of call, read and write; all three by default. Controlled with `onAccessChange`. */\n access?: CallGraphAccess[];\n onAccessChange?: (access: CallGraphAccess[]) => void;\n /** Columns and fields as nodes of their own; collapsed into tables and entities by default. */\n columns?: boolean;\n onColumnsChange?: (columns: boolean) => void;\n /**\n * The groups drawn as their header alone, by `graph.groups` id: each folds into one node, and its\n * members' edges merge onto it, counting the members. The root's group never folds. Controlled with\n * `onCollapsedGroupsChange`; without one the component holds it, starting here, none by default.\n */\n collapsedGroups?: string[];\n onCollapsedGroupsChange?: (ids: string[]) => void;\n /** The groups the graph reached, drawn or excluded. Without it the graph offers no exclusions. */\n groupFacts?: (graph: G) => CallGraphGroupFact[];\n /** The patterns in force when `exclude` is undefined: the host's defaults, as its response reports them. */\n defaultExclude?: (graph: G) => string[];\n /** How a pattern matches a group, for a host with keywords of its own. */\n excludeMatcher?: ExcludeMatcher;\n /**\n * Where a node opens. A node the vocabulary gives no source is never opened, and Open is disabled on\n * a node with no href that `onOpenNode` does not accept.\n */\n nodeHref?: (node: CallGraphNode, graph: G) => string | undefined;\n /** Opens a node; with `nodeHref` it handles a plain click on the link. */\n onOpenNode?: (node: CallGraphNode, graph: G) => void;\n /** Whether `onOpenNode` opens a node; every node by default. */\n canOpenNode?: (node: CallGraphNode, graph: G) => boolean;\n openLabel?: string;\n /** Re-roots the graph on a node, by id: a drawn node the vocabulary can root, or the column behind a field. */\n onFocusNode?: (nodeId: string, graph: G) => void;\n /** Where a call site opens; a site opens only when its caller has a source. */\n siteHref?: (site: CallGraphSite, edge: CallGraphEdge, graph: G) => string | undefined;\n onRevealSite?: (site: CallGraphSite, edge: CallGraphEdge, graph: G) => void;\n /** Fetches the guards of a selected edge's sites, for a host whose graph leaves them out. */\n loadSiteGuards?: (edge: CallGraphEdge, graph: G, signal: AbortSignal) => Promise<CallGraphSite[]>;\n edgeLabels?: Partial<CallGraphEdgeLabels>;\n /** What a conditional edge's pill says of its guards; \"innermost\" by default. The edge's tooltip always lists them. */\n guardLabel?: GuardLabel;\n vocabulary?: CallGraphVocabulary;\n /** Shows a Pin root toggle; the host keeps `root` while pinned. */\n pinned?: boolean;\n onPinnedChange?: (pinned: boolean, rootId: string | undefined) => void;\n /** Host facts above the diagram, such as how the root was resolved. */\n renderHeader?: (graph: G) => ReactNode;\n toolbarEnd?: ReactNode;\n emptyMessage?: ReactNode;\n maxDepth?: number;\n className?: string;\n}\n\ntype Held<G> = { key: string; graph: G; revealed: string[] };\ntype PendingExpansion = { key: string; nodeId: string; label: string; controller: AbortController };\n\nconst NODE_WIDTH = 188;\nconst NODE_HEIGHT = 32;\nconst COMPACT_NODE_HEIGHT = 22;\nconst ROW_GAP = 14;\n/** Node labels are 12px: at this scale they are 7.2px, the smallest that still reads. */\nconst READABLE_SCALE = 0.6;\nconst OPTIONS: Omit<DiagramOptions, \"guardLabel\"> = { truncateAt: 32, grouped: true };\n\nfunction Notice({ children }: { children: ReactNode }) {\n return (\n <div className=\"flex h-full items-center justify-center p-6 text-center\">\n <span className=\"text-sm text-muted-foreground\">{children}</span>\n </div>\n );\n}\n\nfunction Alert({ message }: { message: string | undefined }) {\n if (!message) return null;\n return <div role=\"alert\" className=\"whitespace-pre-wrap rounded-md border border-destructive p-3 text-sm text-destructive\">{message}</div>;\n}\n\nconst ACCESS_WORDS: Record<CallGraphAccess, string> = { call: \"Calls\", read: \"Reads\", write: \"Writes\", variable: \"Variables\" };\n\nfunction accessWords(access: readonly CallGraphAccess[]): string {\n return access.map((type) => ACCESS_WORDS[type]).join(\" and \");\n}\n\nfunction action(href: string | undefined, onSelect: (() => void) | undefined): CallGraphAction | undefined {\n if (href === undefined && onSelect === undefined) return undefined;\n return { ...(href !== undefined ? { href } : {}), ...(onSelect ? { onSelect } : {}) };\n}\n\nexport function CallGraph<G extends Graph = Graph>(props: CallGraphProps<G>) {\n const { root, fetchGraph, vocabulary = UIR_CALL_GRAPH_VOCABULARY, maxDepth = CALL_GRAPH_MAX_DEPTH } = props;\n const labels: CallGraphEdgeLabels = { ...DEFAULT_EDGE_LABELS, ...props.edgeLabels };\n const [direction, setDirection] = useHeld(props.direction ?? \"both\", props.onDirectionChange);\n const [depth, setDepth] = useHeld(props.depth ?? CALL_GRAPH_DEFAULT_DEPTH, props.onDepthChange);\n const [exclude, setExclude] = useHeld(props.exclude, props.onExcludeChange);\n const [access, setAccess] = useHeld(props.access ?? [...CALL_GRAPH_ACCESS], props.onAccessChange);\n const [columns, setColumns] = useHeld(props.columns ?? false, props.onColumnsChange);\n const [collapsedGroups, setCollapsedGroups] = useHeld(props.collapsedGroups ?? [], props.onCollapsedGroupsChange);\n if (baseAccess(access).length === 0) throw new Error(\"call graph: access must name at least one of call, read and write\");\n if (access.includes(\"variable\") && !(props.dataAccess && props.variableAccess)) {\n throw new Error(\"call graph: access names variable, but the host does not offer variableAccess\");\n }\n const [ownSelection, setOwnSelection] = useState<{ key: string; selected: CallGraphSelection }>();\n\n const request: GraphRequest | undefined = root === undefined ? undefined : { root, direction, depth, exclude, access, columns, purpose: \"load\" };\n const key = `call-graph:${JSON.stringify([request ?? null, props.fetchKey ?? null])}`;\n const load = useGraphLoad(fetchGraph, request, key);\n\n const [expanded, setExpanded] = useState<Held<G>>();\n const [expanding, setExpanding] = useState<{ request: PendingExpansion; error?: string }>();\n const pendingExpansion = useRef<PendingExpansion | undefined>(undefined);\n const activeKey = useRef(key);\n activeKey.current = key;\n useEffect(() => {\n setExpanding((current) => current?.request.key === key && !current.request.controller.signal.aborted ? current : undefined);\n return () => {\n if (pendingExpansion.current?.key === key) {\n pendingExpansion.current.controller.abort();\n pendingExpansion.current = undefined;\n }\n };\n }, [key]);\n const [opening, setOpening] = useState({ nonce: 0, fit: false });\n const fresh = useMemo<Held<G> | undefined>(\n () => load.fresh && (expanded?.key === key ? expanded : { key, graph: load.fresh, revealed: [] }),\n [load.fresh, expanded, key],\n );\n const [last, setLast] = useState<Held<G>>();\n if (fresh && fresh !== last) setLast(fresh);\n const shown = root === undefined ? undefined : (fresh ?? last);\n const graph = shown?.graph;\n\n const visible = useMemo(() => shown && visibleGraph(shown.graph, { direction, depth, revealed: shown.revealed }), [shown, direction, depth]);\n const glyphs = useMemo<DiagramGlyphs>(() => ({\n node: (glyph, words) => <NodeGlyphIcon vocabulary={vocabulary} glyph={glyph} title={words} />,\n edge: (type) => (type === \"call\" ? undefined : <EdgeTypeGlyph type={type} title={labels[type]} />),\n group: (caption, glyph) => <GroupCaption icon={glyph === undefined ? vocabulary.group.icon : requireGlyph(vocabulary, glyph).icon} caption={caption} />,\n access: (access) => <AccessMark access={access} />,\n }), [vocabulary, labels.dispatch, labels.read, labels.write]);\n const guardLabel = props.guardLabel ?? \"innermost\";\n const diagram = useMemo(\n () => graph && visible && toDiagram({ graph, visible, direction, options: { ...OPTIONS, guardLabel }, glyphs, vocabulary, edgeLabels: labels, collapsed: collapsedGroups }),\n [graph, visible, direction, guardLabel, glyphs, vocabulary, labels.call, labels.dispatch, labels.read, labels.write, collapsedGroups],\n );\n // What a selection is looked up in: the graph as drawn, collapsed groups folded into their stand-ins.\n const drawn = diagram?.drawn;\n const collapsible = useMemo(() => (graph && visible ? collapsibleGroups(graph, visible) : []), [graph, visible]);\n const toggleGroup = (id: string) => setCollapsedGroups(collapsedGroups.includes(id) ? collapsedGroups.filter((entry) => entry !== id) : [...collapsedGroups, id]);\n\n const rootId = graph?.roots[0];\n const selection = props.onSelectedChange ? props.selected : ownSelection?.key === shown?.key ? ownSelection?.selected : undefined;\n const select = (next: CallGraphSelection | undefined) => {\n if (props.onSelectedChange) props.onSelectedChange(next);\n else setOwnSelection(next && shown ? { key: shown.key, selected: next } : undefined);\n };\n const openAction = (node: CallGraphNode, drawn: G) => {\n const { onOpenNode, canOpenNode } = props;\n const accepted = onOpenNode && (canOpenNode?.(node, drawn) ?? true) ? () => onOpenNode(node, drawn) : undefined;\n return action(props.nodeHref?.(node, drawn), accepted);\n };\n const selectedNode = selection?.kind === \"node\" ? drawn?.visible.nodes.find((node) => node.id === selection.id) : undefined;\n const selectedEdge = selection?.kind === \"edge\" ? drawn?.visible.edges.find((edge) => edge.id === selection.id) : undefined;\n // A merged edge stands for several the host knows: it has no guards of its own to load.\n const mergedEdge = selectedEdge !== undefined && drawn?.merged.has(selectedEdge.id) === true;\n const standIn = selectedNode !== undefined && drawn?.folds.has(selectedNode.id) === true;\n const guards = useSiteGuards(props.loadSiteGuards, shown?.key, mergedEdge ? undefined : selectedEdge, graph);\n const expansion = expanding?.request.key === key ? expanding : undefined;\n\n // A `+N` loads one more hop on the node's outer side and merges it into the graph this request drew.\n const expand = async (drawn: Held<G>, id: string) => {\n if (drawn.key !== activeKey.current) return;\n if (pendingExpansion.current?.key === drawn.key && pendingExpansion.current.nodeId === id) return;\n pendingExpansion.current?.controller.abort();\n const node = requireNode(drawn.graph, id);\n const request: PendingExpansion = { key: drawn.key, nodeId: id, label: node.label, controller: new AbortController() };\n pendingExpansion.current = request;\n setExpanding({ request });\n try {\n const data = await fetchGraph({\n root: id, direction: expansionDirection(node), depth: 1, exclude, access, columns, purpose: \"expand\", signal: request.controller.signal,\n });\n if (request.controller.signal.aborted || activeKey.current !== drawn.key || pendingExpansion.current !== request) return;\n setExpanded((held) => {\n if (request.controller.signal.aborted || activeKey.current !== drawn.key) return held;\n const base = held?.key === drawn.key ? held : drawn;\n return { key: drawn.key, graph: mergeGraph(base.graph, data), revealed: [...base.revealed, ...data.nodes.map((entry) => entry.id)] };\n });\n setExpanding((current) => current?.request === request ? undefined : current);\n } catch (error) {\n if (request.controller.signal.aborted || activeKey.current !== drawn.key || pendingExpansion.current !== request) return;\n setExpanding((current) => current?.request === request\n ? { request, error: `Cannot expand ${node.label}: ${errorMessage(error)}` } : current);\n } finally {\n if (pendingExpansion.current === request) pendingExpansion.current = undefined;\n }\n };\n\n const groups = graph && props.groupFacts?.(graph);\n const effectiveExclude = exclude ?? (graph && props.defaultExclude ? props.defaultExclude(graph) : []);\n const { onPinnedChange } = props;\n const toolbar = (\n <CallGraphToolbar direction={direction} depth={depth} maxDepth={maxDepth} omitted={graph?.omitted} end={props.toolbarEnd} vocabulary={vocabulary}\n {...(onPinnedChange ? { pin: { pinned: props.pinned ?? false, canPin: rootId !== undefined, onPin: (pinned: boolean) => onPinnedChange(pinned, rootId) } } : {})}\n {...(groups ? { exclusions: { exclude: effectiveExclude, groups, matches: props.excludeMatcher ?? matchesExclude, busy: load.loading, vocabulary,\n onExclude: (patterns: string[]) => setExclude(patterns), onDefaults: () => setExclude(undefined) } } : {})}\n {...(props.dataAccess ? { data: { access, onAccess: setAccess, columns, onColumns: setColumns, variables: props.variableAccess ?? false } } : {})}\n {...(collapsible.length > 0 ? { groupCollapse: {\n anyCollapsed: collapsedGroups.some((id) => collapsible.includes(id)),\n anyExpanded: collapsible.some((id) => !collapsedGroups.includes(id)),\n onExpandAll: () => setCollapsedGroups([]),\n onCollapseAll: () => setCollapsedGroups(collapsible),\n } } : {})}\n onDirection={setDirection} onDepth={setDepth}\n onFit={() => setOpening({ nonce: opening.nonce + 1, fit: true })} onReset={() => setOpening({ nonce: opening.nonce + 1, fit: false })} />\n );\n\n const frame = cn(\"flex h-full min-h-0 flex-col gap-2 p-2\", props.className);\n if (root === undefined) {\n return <div className={frame}>{toolbar}<Notice>{props.emptyMessage ?? \"Select a node to draw its call graph.\"}</Notice></div>;\n }\n const loadError = load.error && `Cannot draw the call graph: ${load.error}`;\n return (\n <div className={frame} aria-busy={load.loading}>\n {toolbar}\n <Alert message={loadError} />\n {graph && props.renderHeader?.(graph)}\n {!shown && load.loading && <Notice>Loading call graph…</Notice>}\n {graph && !rootId && <Notice>The root resolved to no node in this scope.</Notice>}\n {graph && rootId && graph.edges.length === 0 && baseAccess(access).length < CALL_GRAPH_ACCESS.length && (\n <Notice>{`Nothing is reachable with ${accessWords(baseAccess(access))} only.`}</Notice>\n )}\n {graph && rootId && graph.edges.length > 0 && !selectedEdge && !selectedNode && (\n <p className=\"text-xs text-muted-foreground\">Select an edge to list its sites, or a node to see its details.</p>\n )}\n {shown && graph && rootId && diagram && (\n <div className=\"flex min-h-0 flex-1 gap-3\">\n <div className={cn(\"relative min-h-64 min-w-0 flex-1 rounded-lg border border-border bg-background\", load.loading && \"opacity-60\")}>\n <GraphDiagram key={`${shown.key}:${opening.nonce}`} nodes={diagram.nodes} edges={diagram.edges} groups={diagram.groups} layout=\"columns\" zoomable wheelZoom=\"zoom\" edgeFocus=\"auto\"\n focusId={rootId} {...(opening.fit ? {} : { fitMinScale: READABLE_SCALE })} nodeWidth={NODE_WIDTH} nodeHeight={NODE_HEIGHT} compactNodeHeight={COMPACT_NODE_HEIGHT} recordHeaderHeight={24} columnGap={columnGap(diagram)} rowGap={ROW_GAP}\n className=\"h-full\" ariaLabel={`Call graph of ${requireNode(graph, rootId).label}`} onGroupToggle={toggleGroup}\n onNodeSelect={(id: string) => select({ kind: \"node\", id })} onEdgeSelect={(id: string) => select({ kind: \"edge\", id })}\n {...(fresh ? { onNodeExpand: (id: string) => void expand(fresh, id) } : {})}\n {...(selectedNode ? { selectedId: selectedNode.id } : {})} {...(selectedEdge ? { selectedEdgeId: selectedEdge.id } : {})} />\n </div>\n {(selectedEdge || selectedNode || expansion) && (\n <aside className=\"w-80 max-w-[45%] shrink-0 overflow-y-auto rounded-lg border border-border bg-card p-3\" aria-label=\"Selection\">\n {expansion && <p role=\"status\" className=\"mb-2 text-xs text-muted-foreground\">{expansion.error ?? `Loading more around ${expansion.request.label}…`}</p>}\n {(selectedEdge || selectedNode) && (\n <div className=\"mb-1 flex justify-end\">\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" aria-label=\"Close selection\" onClick={() => select(undefined)}>×</Button>\n </div>\n )}\n {selectedEdge && drawn ? (\n <EdgeSites edge={selectedEdge} graph={drawn.graph} labels={labels} guards={guards} lazyGuards={props.loadSiteGuards !== undefined}\n siteAction={(props.siteHref || props.onRevealSite) && !drawn.folds.has(selectedEdge.from) && vocabulary.hasSource(requireNode(graph, selectedEdge.from))\n ? (site) => action(props.siteHref?.(site, selectedEdge, graph), props.onRevealSite && (() => props.onRevealSite?.(site, selectedEdge, graph))) ?? {}\n : undefined} />\n ) : selectedNode && drawn && (\n <NodeDetails node={selectedNode} graph={drawn.graph} vocabulary={vocabulary} isRoot={selectedNode.id === rootId} openLabel={props.openLabel ?? \"Open\"}\n opens={!standIn && (props.nodeHref !== undefined || props.onOpenNode !== undefined)} open={standIn ? undefined : openAction(selectedNode, graph)}\n onFocus={standIn ? undefined : props.onFocusNode && ((id: string) => props.onFocusNode?.(id, graph))} />\n )}\n </aside>\n )}\n </div>\n )}\n {graph && rootId && <div className=\"shrink-0\"><Legend graph={graph} vocabulary={vocabulary} labels={labels} /></div>}\n </div>\n );\n}\n"],"names":["jsx","UIR_CALL_GRAPH_VOCABULARY","CALL_GRAPH_MAX_DEPTH","DEFAULT_EDGE_LABELS","useHeld","CALL_GRAPH_DEFAULT_DEPTH","CALL_GRAPH_ACCESS","baseAccess","useState","useGraphLoad","useRef","useEffect","_a","useMemo","visibleGraph","NodeGlyphIcon","EdgeTypeGlyph","GroupCaption","requireGlyph","access","AccessMark","toDiagram","collapsibleGroups","drawn","useSiteGuards","_b","requireNode","request","expansionDirection","mergeGraph","errorMessage","CallGraphToolbar","matchesExclude","cn","jsxs","GraphDiagram","columnGap","Button","EdgeSites","NodeDetails","Legend"],"mappings":"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"}
|
|
@@ -22,12 +22,21 @@ export interface CallGraphProps<G extends Graph = Graph> {
|
|
|
22
22
|
onSelectedChange?: (selected: CallGraphSelection | undefined) => void;
|
|
23
23
|
/** The source reports reads and writes of data: shows the Access toggles and the Columns switch. */
|
|
24
24
|
dataAccess?: boolean;
|
|
25
|
-
/** The
|
|
25
|
+
/** The source can follow the variables a body reads and writes: shows a Variables toggle beside the Access ones. Needs `dataAccess`. */
|
|
26
|
+
variableAccess?: boolean;
|
|
27
|
+
/** The edge types the host follows, at least one of call, read and write; all three by default. Controlled with `onAccessChange`. */
|
|
26
28
|
access?: CallGraphAccess[];
|
|
27
29
|
onAccessChange?: (access: CallGraphAccess[]) => void;
|
|
28
30
|
/** Columns and fields as nodes of their own; collapsed into tables and entities by default. */
|
|
29
31
|
columns?: boolean;
|
|
30
32
|
onColumnsChange?: (columns: boolean) => void;
|
|
33
|
+
/**
|
|
34
|
+
* The groups drawn as their header alone, by `graph.groups` id: each folds into one node, and its
|
|
35
|
+
* members' edges merge onto it, counting the members. The root's group never folds. Controlled with
|
|
36
|
+
* `onCollapsedGroupsChange`; without one the component holds it, starting here, none by default.
|
|
37
|
+
*/
|
|
38
|
+
collapsedGroups?: string[];
|
|
39
|
+
onCollapsedGroupsChange?: (ids: string[]) => void;
|
|
31
40
|
/** The groups the graph reached, drawn or excluded. Without it the graph offers no exclusions. */
|
|
32
41
|
groupFacts?: (graph: G) => CallGraphGroupFact[];
|
|
33
42
|
/** The patterns in force when `exclude` is undefined: the host's defaults, as its response reports them. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CallGraph.d.ts","sourceRoot":"","sources":["../../../src/data/call-graph/CallGraph.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"CallGraph.d.ts","sourceRoot":"","sources":["../../../src/data/call-graph/CallGraph.tsx"],"names":[],"mappings":"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"}
|
|
@@ -2,10 +2,11 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState, useRef, useEffect, useMemo } from "react";
|
|
3
3
|
import { Button } from "../../components/button.js";
|
|
4
4
|
import { cn } from "../../lib/utils.js";
|
|
5
|
+
import { AccessMark } from "../AccessMark.js";
|
|
5
6
|
import { GraphDiagram } from "../GraphDiagram.js";
|
|
6
7
|
import { matchesExclude } from "./call-graph-exclude.js";
|
|
7
|
-
import { CALL_GRAPH_MAX_DEPTH, CALL_GRAPH_DEFAULT_DEPTH, visibleGraph, DEFAULT_EDGE_LABELS, toDiagram, requireNode, columnGap, expansionDirection, mergeGraph } from "./call-graph-model.js";
|
|
8
|
-
import { UIR_CALL_GRAPH_VOCABULARY } from "./call-graph-vocabulary.js";
|
|
8
|
+
import { CALL_GRAPH_MAX_DEPTH, CALL_GRAPH_DEFAULT_DEPTH, baseAccess, visibleGraph, DEFAULT_EDGE_LABELS, toDiagram, collapsibleGroups, requireNode, columnGap, expansionDirection, mergeGraph } from "./call-graph-model.js";
|
|
9
|
+
import { UIR_CALL_GRAPH_VOCABULARY, requireGlyph } from "./call-graph-vocabulary.js";
|
|
9
10
|
import { GroupCaption, EdgeTypeGlyph, NodeGlyphIcon } from "./CallGraphGlyphs.js";
|
|
10
11
|
import { EdgeSites, NodeDetails, Legend } from "./CallGraphParts.js";
|
|
11
12
|
import { CallGraphToolbar } from "./CallGraphToolbar.js";
|
|
@@ -24,7 +25,7 @@ function Alert({ message }) {
|
|
|
24
25
|
if (!message) return null;
|
|
25
26
|
return /* @__PURE__ */ jsx("div", { role: "alert", className: "whitespace-pre-wrap rounded-md border border-destructive p-3 text-sm text-destructive", children: message });
|
|
26
27
|
}
|
|
27
|
-
const ACCESS_WORDS = { call: "Calls", read: "Reads", write: "Writes" };
|
|
28
|
+
const ACCESS_WORDS = { call: "Calls", read: "Reads", write: "Writes", variable: "Variables" };
|
|
28
29
|
function accessWords(access) {
|
|
29
30
|
return access.map((type) => ACCESS_WORDS[type]).join(" and ");
|
|
30
31
|
}
|
|
@@ -41,7 +42,11 @@ function CallGraph(props) {
|
|
|
41
42
|
const [exclude, setExclude] = useHeld(props.exclude, props.onExcludeChange);
|
|
42
43
|
const [access, setAccess] = useHeld(props.access ?? [...CALL_GRAPH_ACCESS], props.onAccessChange);
|
|
43
44
|
const [columns, setColumns] = useHeld(props.columns ?? false, props.onColumnsChange);
|
|
44
|
-
|
|
45
|
+
const [collapsedGroups, setCollapsedGroups] = useHeld(props.collapsedGroups ?? [], props.onCollapsedGroupsChange);
|
|
46
|
+
if (baseAccess(access).length === 0) throw new Error("call graph: access must name at least one of call, read and write");
|
|
47
|
+
if (access.includes("variable") && !(props.dataAccess && props.variableAccess)) {
|
|
48
|
+
throw new Error("call graph: access names variable, but the host does not offer variableAccess");
|
|
49
|
+
}
|
|
45
50
|
const [ownSelection, setOwnSelection] = useState();
|
|
46
51
|
const request = root === void 0 ? void 0 : { root, direction, depth, exclude, access, columns, purpose: "load" };
|
|
47
52
|
const key = `call-graph:${JSON.stringify([request ?? null, props.fetchKey ?? null])}`;
|
|
@@ -74,36 +79,42 @@ function CallGraph(props) {
|
|
|
74
79
|
const glyphs = useMemo(() => ({
|
|
75
80
|
node: (glyph, words) => /* @__PURE__ */ jsx(NodeGlyphIcon, { vocabulary, glyph, title: words }),
|
|
76
81
|
edge: (type) => type === "call" ? void 0 : /* @__PURE__ */ jsx(EdgeTypeGlyph, { type, title: labels[type] }),
|
|
77
|
-
group: (caption) => /* @__PURE__ */ jsx(GroupCaption, { icon: vocabulary.group.icon, caption })
|
|
82
|
+
group: (caption, glyph) => /* @__PURE__ */ jsx(GroupCaption, { icon: glyph === void 0 ? vocabulary.group.icon : requireGlyph(vocabulary, glyph).icon, caption }),
|
|
83
|
+
access: (access2) => /* @__PURE__ */ jsx(AccessMark, { access: access2 })
|
|
78
84
|
}), [vocabulary, labels.dispatch, labels.read, labels.write]);
|
|
79
85
|
const guardLabel = props.guardLabel ?? "innermost";
|
|
80
86
|
const diagram = useMemo(
|
|
81
|
-
() => graph && visible && toDiagram({ graph, visible, direction, options: { ...OPTIONS, guardLabel }, glyphs, vocabulary, edgeLabels: labels }),
|
|
82
|
-
[graph, visible, direction, guardLabel, glyphs, vocabulary, labels.call, labels.dispatch, labels.read, labels.write]
|
|
87
|
+
() => graph && visible && toDiagram({ graph, visible, direction, options: { ...OPTIONS, guardLabel }, glyphs, vocabulary, edgeLabels: labels, collapsed: collapsedGroups }),
|
|
88
|
+
[graph, visible, direction, guardLabel, glyphs, vocabulary, labels.call, labels.dispatch, labels.read, labels.write, collapsedGroups]
|
|
83
89
|
);
|
|
90
|
+
const drawn = diagram == null ? void 0 : diagram.drawn;
|
|
91
|
+
const collapsible = useMemo(() => graph && visible ? collapsibleGroups(graph, visible) : [], [graph, visible]);
|
|
92
|
+
const toggleGroup = (id) => setCollapsedGroups(collapsedGroups.includes(id) ? collapsedGroups.filter((entry) => entry !== id) : [...collapsedGroups, id]);
|
|
84
93
|
const rootId = graph == null ? void 0 : graph.roots[0];
|
|
85
94
|
const selection = props.onSelectedChange ? props.selected : (ownSelection == null ? void 0 : ownSelection.key) === (shown == null ? void 0 : shown.key) ? ownSelection == null ? void 0 : ownSelection.selected : void 0;
|
|
86
95
|
const select = (next) => {
|
|
87
96
|
if (props.onSelectedChange) props.onSelectedChange(next);
|
|
88
97
|
else setOwnSelection(next && shown ? { key: shown.key, selected: next } : void 0);
|
|
89
98
|
};
|
|
90
|
-
const openAction = (node,
|
|
99
|
+
const openAction = (node, drawn2) => {
|
|
91
100
|
var _a2;
|
|
92
101
|
const { onOpenNode, canOpenNode } = props;
|
|
93
|
-
const accepted = onOpenNode && ((canOpenNode == null ? void 0 : canOpenNode(node,
|
|
94
|
-
return action((_a2 = props.nodeHref) == null ? void 0 : _a2.call(props, node,
|
|
102
|
+
const accepted = onOpenNode && ((canOpenNode == null ? void 0 : canOpenNode(node, drawn2)) ?? true) ? () => onOpenNode(node, drawn2) : void 0;
|
|
103
|
+
return action((_a2 = props.nodeHref) == null ? void 0 : _a2.call(props, node, drawn2), accepted);
|
|
95
104
|
};
|
|
96
|
-
const selectedNode = (selection == null ? void 0 : selection.kind) === "node" ?
|
|
97
|
-
const selectedEdge = (selection == null ? void 0 : selection.kind) === "edge" ?
|
|
98
|
-
const
|
|
105
|
+
const selectedNode = (selection == null ? void 0 : selection.kind) === "node" ? drawn == null ? void 0 : drawn.visible.nodes.find((node) => node.id === selection.id) : void 0;
|
|
106
|
+
const selectedEdge = (selection == null ? void 0 : selection.kind) === "edge" ? drawn == null ? void 0 : drawn.visible.edges.find((edge) => edge.id === selection.id) : void 0;
|
|
107
|
+
const mergedEdge = selectedEdge !== void 0 && (drawn == null ? void 0 : drawn.merged.has(selectedEdge.id)) === true;
|
|
108
|
+
const standIn = selectedNode !== void 0 && (drawn == null ? void 0 : drawn.folds.has(selectedNode.id)) === true;
|
|
109
|
+
const guards = useSiteGuards(props.loadSiteGuards, shown == null ? void 0 : shown.key, mergedEdge ? void 0 : selectedEdge, graph);
|
|
99
110
|
const expansion = (expanding == null ? void 0 : expanding.request.key) === key ? expanding : void 0;
|
|
100
|
-
const expand = async (
|
|
111
|
+
const expand = async (drawn2, id) => {
|
|
101
112
|
var _a2, _b2;
|
|
102
|
-
if (
|
|
103
|
-
if (((_a2 = pendingExpansion.current) == null ? void 0 : _a2.key) ===
|
|
113
|
+
if (drawn2.key !== activeKey.current) return;
|
|
114
|
+
if (((_a2 = pendingExpansion.current) == null ? void 0 : _a2.key) === drawn2.key && pendingExpansion.current.nodeId === id) return;
|
|
104
115
|
(_b2 = pendingExpansion.current) == null ? void 0 : _b2.controller.abort();
|
|
105
|
-
const node = requireNode(
|
|
106
|
-
const request2 = { key:
|
|
116
|
+
const node = requireNode(drawn2.graph, id);
|
|
117
|
+
const request2 = { key: drawn2.key, nodeId: id, label: node.label, controller: new AbortController() };
|
|
107
118
|
pendingExpansion.current = request2;
|
|
108
119
|
setExpanding({ request: request2 });
|
|
109
120
|
try {
|
|
@@ -117,15 +128,15 @@ function CallGraph(props) {
|
|
|
117
128
|
purpose: "expand",
|
|
118
129
|
signal: request2.controller.signal
|
|
119
130
|
});
|
|
120
|
-
if (request2.controller.signal.aborted || activeKey.current !==
|
|
131
|
+
if (request2.controller.signal.aborted || activeKey.current !== drawn2.key || pendingExpansion.current !== request2) return;
|
|
121
132
|
setExpanded((held) => {
|
|
122
|
-
if (request2.controller.signal.aborted || activeKey.current !==
|
|
123
|
-
const base = (held == null ? void 0 : held.key) ===
|
|
124
|
-
return { key:
|
|
133
|
+
if (request2.controller.signal.aborted || activeKey.current !== drawn2.key) return held;
|
|
134
|
+
const base = (held == null ? void 0 : held.key) === drawn2.key ? held : drawn2;
|
|
135
|
+
return { key: drawn2.key, graph: mergeGraph(base.graph, data), revealed: [...base.revealed, ...data.nodes.map((entry) => entry.id)] };
|
|
125
136
|
});
|
|
126
137
|
setExpanding((current) => (current == null ? void 0 : current.request) === request2 ? void 0 : current);
|
|
127
138
|
} catch (error) {
|
|
128
|
-
if (request2.controller.signal.aborted || activeKey.current !==
|
|
139
|
+
if (request2.controller.signal.aborted || activeKey.current !== drawn2.key || pendingExpansion.current !== request2) return;
|
|
129
140
|
setExpanding((current) => (current == null ? void 0 : current.request) === request2 ? { request: request2, error: `Cannot expand ${node.label}: ${errorMessage(error)}` } : current);
|
|
130
141
|
} finally {
|
|
131
142
|
if (pendingExpansion.current === request2) pendingExpansion.current = void 0;
|
|
@@ -153,7 +164,13 @@ function CallGraph(props) {
|
|
|
153
164
|
onExclude: (patterns) => setExclude(patterns),
|
|
154
165
|
onDefaults: () => setExclude(void 0)
|
|
155
166
|
} } : {},
|
|
156
|
-
...props.dataAccess ? { data: { access, onAccess: setAccess, columns, onColumns: setColumns } } : {},
|
|
167
|
+
...props.dataAccess ? { data: { access, onAccess: setAccess, columns, onColumns: setColumns, variables: props.variableAccess ?? false } } : {},
|
|
168
|
+
...collapsible.length > 0 ? { groupCollapse: {
|
|
169
|
+
anyCollapsed: collapsedGroups.some((id) => collapsible.includes(id)),
|
|
170
|
+
anyExpanded: collapsible.some((id) => !collapsedGroups.includes(id)),
|
|
171
|
+
onExpandAll: () => setCollapsedGroups([]),
|
|
172
|
+
onCollapseAll: () => setCollapsedGroups(collapsible)
|
|
173
|
+
} } : {},
|
|
157
174
|
onDirection: setDirection,
|
|
158
175
|
onDepth: setDepth,
|
|
159
176
|
onFit: () => setOpening({ nonce: opening.nonce + 1, fit: true }),
|
|
@@ -174,7 +191,7 @@ function CallGraph(props) {
|
|
|
174
191
|
graph && ((_b = props.renderHeader) == null ? void 0 : _b.call(props, graph)),
|
|
175
192
|
!shown && load.loading && /* @__PURE__ */ jsx(Notice, { children: "Loading call graph…" }),
|
|
176
193
|
graph && !rootId && /* @__PURE__ */ jsx(Notice, { children: "The root resolved to no node in this scope." }),
|
|
177
|
-
graph && rootId && graph.edges.length === 0 && access.length < CALL_GRAPH_ACCESS.length && /* @__PURE__ */ jsx(Notice, { children: `Nothing is reachable with ${accessWords(access)} only.` }),
|
|
194
|
+
graph && rootId && graph.edges.length === 0 && baseAccess(access).length < CALL_GRAPH_ACCESS.length && /* @__PURE__ */ jsx(Notice, { children: `Nothing is reachable with ${accessWords(baseAccess(access))} only.` }),
|
|
178
195
|
graph && rootId && graph.edges.length > 0 && !selectedEdge && !selectedNode && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Select an edge to list its sites, or a node to see its details." }),
|
|
179
196
|
shown && graph && rootId && diagram && /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 gap-3", children: [
|
|
180
197
|
/* @__PURE__ */ jsx("div", { className: cn("relative min-h-64 min-w-0 flex-1 rounded-lg border border-border bg-background", load.loading && "opacity-60"), children: /* @__PURE__ */ jsx(
|
|
@@ -192,10 +209,12 @@ function CallGraph(props) {
|
|
|
192
209
|
nodeWidth: NODE_WIDTH,
|
|
193
210
|
nodeHeight: NODE_HEIGHT,
|
|
194
211
|
compactNodeHeight: COMPACT_NODE_HEIGHT,
|
|
212
|
+
recordHeaderHeight: 24,
|
|
195
213
|
columnGap: columnGap(diagram),
|
|
196
214
|
rowGap: ROW_GAP,
|
|
197
215
|
className: "h-full",
|
|
198
216
|
ariaLabel: `Call graph of ${requireNode(graph, rootId).label}`,
|
|
217
|
+
onGroupToggle: toggleGroup,
|
|
199
218
|
onNodeSelect: (id) => select({ kind: "node", id }),
|
|
200
219
|
onEdgeSelect: (id) => select({ kind: "edge", id }),
|
|
201
220
|
...fresh ? { onNodeExpand: (id) => void expand(fresh, id) } : {},
|
|
@@ -207,15 +226,15 @@ function CallGraph(props) {
|
|
|
207
226
|
(selectedEdge || selectedNode || expansion) && /* @__PURE__ */ jsxs("aside", { className: "w-80 max-w-[45%] shrink-0 overflow-y-auto rounded-lg border border-border bg-card p-3", "aria-label": "Selection", children: [
|
|
208
227
|
expansion && /* @__PURE__ */ jsx("p", { role: "status", className: "mb-2 text-xs text-muted-foreground", children: expansion.error ?? `Loading more around ${expansion.request.label}…` }),
|
|
209
228
|
(selectedEdge || selectedNode) && /* @__PURE__ */ jsx("div", { className: "mb-1 flex justify-end", children: /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", variant: "ghost", "aria-label": "Close selection", onClick: () => select(void 0), children: "×" }) }),
|
|
210
|
-
selectedEdge ? /* @__PURE__ */ jsx(
|
|
229
|
+
selectedEdge && drawn ? /* @__PURE__ */ jsx(
|
|
211
230
|
EdgeSites,
|
|
212
231
|
{
|
|
213
232
|
edge: selectedEdge,
|
|
214
|
-
graph,
|
|
233
|
+
graph: drawn.graph,
|
|
215
234
|
labels,
|
|
216
235
|
guards,
|
|
217
236
|
lazyGuards: props.loadSiteGuards !== void 0,
|
|
218
|
-
siteAction: (props.siteHref || props.onRevealSite) && vocabulary.hasSource(requireNode(graph, selectedEdge.from)) ? (site) => {
|
|
237
|
+
siteAction: (props.siteHref || props.onRevealSite) && !drawn.folds.has(selectedEdge.from) && vocabulary.hasSource(requireNode(graph, selectedEdge.from)) ? (site) => {
|
|
219
238
|
var _a2;
|
|
220
239
|
return action((_a2 = props.siteHref) == null ? void 0 : _a2.call(props, site, selectedEdge, graph), props.onRevealSite && (() => {
|
|
221
240
|
var _a3;
|
|
@@ -223,17 +242,17 @@ function CallGraph(props) {
|
|
|
223
242
|
})) ?? {};
|
|
224
243
|
} : void 0
|
|
225
244
|
}
|
|
226
|
-
) : selectedNode && /* @__PURE__ */ jsx(
|
|
245
|
+
) : selectedNode && drawn && /* @__PURE__ */ jsx(
|
|
227
246
|
NodeDetails,
|
|
228
247
|
{
|
|
229
248
|
node: selectedNode,
|
|
230
|
-
graph,
|
|
249
|
+
graph: drawn.graph,
|
|
231
250
|
vocabulary,
|
|
232
251
|
isRoot: selectedNode.id === rootId,
|
|
233
252
|
openLabel: props.openLabel ?? "Open",
|
|
234
|
-
opens: props.nodeHref !== void 0 || props.onOpenNode !== void 0,
|
|
235
|
-
open: openAction(selectedNode, graph),
|
|
236
|
-
onFocus: props.onFocusNode && ((id) => {
|
|
253
|
+
opens: !standIn && (props.nodeHref !== void 0 || props.onOpenNode !== void 0),
|
|
254
|
+
open: standIn ? void 0 : openAction(selectedNode, graph),
|
|
255
|
+
onFocus: standIn ? void 0 : props.onFocusNode && ((id) => {
|
|
237
256
|
var _a2;
|
|
238
257
|
return (_a2 = props.onFocusNode) == null ? void 0 : _a2.call(props, id, graph);
|
|
239
258
|
})
|