@flanksource/clicky-ui 0.3.44 → 0.3.45
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/README.md +2 -0
- package/dist/ai.cjs +4 -2
- package/dist/ai.cjs.map +1 -1
- package/dist/ai.js +3 -1
- package/dist/components/MdxEditorField.cjs +40 -22
- package/dist/components/MdxEditorField.cjs.map +1 -1
- package/dist/components/MdxEditorField.d.ts.map +1 -1
- package/dist/components/MdxEditorField.js +41 -23
- package/dist/components/MdxEditorField.js.map +1 -1
- package/dist/components/json-schema-form-item-summary.cjs +6 -1
- package/dist/components/json-schema-form-item-summary.cjs.map +1 -1
- package/dist/components/json-schema-form-item-summary.d.ts.map +1 -1
- package/dist/components/json-schema-form-item-summary.js +6 -1
- package/dist/components/json-schema-form-item-summary.js.map +1 -1
- package/dist/data/CodeBlock.cjs +3 -2
- package/dist/data/CodeBlock.cjs.map +1 -1
- package/dist/data/CodeBlock.d.ts +3 -1
- package/dist/data/CodeBlock.d.ts.map +1 -1
- package/dist/data/CodeBlock.js +3 -2
- package/dist/data/CodeBlock.js.map +1 -1
- package/dist/data/GraphDiagram.cjs +18 -6
- package/dist/data/GraphDiagram.cjs.map +1 -1
- package/dist/data/GraphDiagram.d.ts +9 -1
- package/dist/data/GraphDiagram.d.ts.map +1 -1
- package/dist/data/GraphDiagram.js +18 -6
- package/dist/data/GraphDiagram.js.map +1 -1
- package/dist/data/GraphDiagramNodes.cjs +38 -29
- package/dist/data/GraphDiagramNodes.cjs.map +1 -1
- package/dist/data/GraphDiagramNodes.d.ts +8 -2
- package/dist/data/GraphDiagramNodes.d.ts.map +1 -1
- package/dist/data/GraphDiagramNodes.js +38 -29
- package/dist/data/GraphDiagramNodes.js.map +1 -1
- package/dist/data/JsonView.cjs +118 -49
- package/dist/data/JsonView.cjs.map +1 -1
- package/dist/data/JsonView.d.ts +13 -10
- package/dist/data/JsonView.d.ts.map +1 -1
- package/dist/data/JsonView.js +118 -49
- package/dist/data/JsonView.js.map +1 -1
- package/dist/data/MarkdownEditor.cjs +2 -2
- package/dist/data/MarkdownEditor.cjs.map +1 -1
- package/dist/data/MarkdownEditor.js +2 -2
- package/dist/data/MarkdownEditor.js.map +1 -1
- package/dist/data/ai/AdvancedChatConfig.cjs +90 -249
- package/dist/data/ai/AdvancedChatConfig.cjs.map +1 -1
- package/dist/data/ai/AdvancedChatConfig.d.ts +2 -5
- package/dist/data/ai/AdvancedChatConfig.d.ts.map +1 -1
- package/dist/data/ai/AdvancedChatConfig.js +91 -250
- package/dist/data/ai/AdvancedChatConfig.js.map +1 -1
- package/dist/data/ai/ChatButton.cjs +2 -0
- package/dist/data/ai/ChatButton.cjs.map +1 -1
- package/dist/data/ai/ChatButton.d.ts +1 -1
- package/dist/data/ai/ChatButton.d.ts.map +1 -1
- package/dist/data/ai/ChatButton.js +2 -0
- package/dist/data/ai/ChatButton.js.map +1 -1
- package/dist/data/ai/ChatFab.cjs +5 -1
- package/dist/data/ai/ChatFab.cjs.map +1 -1
- package/dist/data/ai/ChatFab.d.ts +5 -1
- package/dist/data/ai/ChatFab.d.ts.map +1 -1
- package/dist/data/ai/ChatFab.js +5 -1
- package/dist/data/ai/ChatFab.js.map +1 -1
- package/dist/data/ai/ChatWindow.cjs +2 -8
- package/dist/data/ai/ChatWindow.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.js +2 -8
- package/dist/data/ai/ChatWindow.js.map +1 -1
- package/dist/data/ai/ChatWindow.runtime.cjs +0 -5
- package/dist/data/ai/ChatWindow.runtime.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.runtime.d.ts +0 -2
- package/dist/data/ai/ChatWindow.runtime.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.runtime.js +0 -5
- package/dist/data/ai/ChatWindow.runtime.js.map +1 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.cjs +2 -2
- package/dist/data/ai/PromptRunEditor/runtimeActions.cjs.map +1 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.d.ts.map +1 -1
- package/dist/data/ai/PromptRunEditor/runtimeActions.js +2 -2
- package/dist/data/ai/PromptRunEditor/runtimeActions.js.map +1 -1
- package/dist/data/ai/SessionInspector.approvals.cjs +3 -6
- package/dist/data/ai/SessionInspector.approvals.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.approvals.js +3 -6
- package/dist/data/ai/SessionInspector.approvals.js.map +1 -1
- package/dist/data/ai/SessionViewer.cjs +13 -4
- package/dist/data/ai/SessionViewer.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.d.ts +5 -1
- package/dist/data/ai/SessionViewer.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.header.cjs +1 -1
- package/dist/data/ai/SessionViewer.header.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.header.js +1 -1
- package/dist/data/ai/SessionViewer.header.js.map +1 -1
- package/dist/data/ai/SessionViewer.js +13 -4
- package/dist/data/ai/SessionViewer.js.map +1 -1
- package/dist/data/ai/SessionViewer.model.cjs +2 -0
- package/dist/data/ai/SessionViewer.model.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.model.d.ts +1 -0
- package/dist/data/ai/SessionViewer.model.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.model.js +2 -0
- package/dist/data/ai/SessionViewer.model.js.map +1 -1
- package/dist/data/ai/SessionViewer.rows.cjs +41 -27
- package/dist/data/ai/SessionViewer.rows.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.rows.d.ts +4 -2
- package/dist/data/ai/SessionViewer.rows.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.rows.js +41 -27
- package/dist/data/ai/SessionViewer.rows.js.map +1 -1
- package/dist/data/ai/SessionViewer.tokens.cjs +35 -0
- package/dist/data/ai/SessionViewer.tokens.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.tokens.d.ts +5 -0
- package/dist/data/ai/SessionViewer.tokens.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.tokens.js +35 -0
- package/dist/data/ai/SessionViewer.tokens.js.map +1 -0
- package/dist/data/ai/SessionViewer.tool-cost.cjs +128 -0
- package/dist/data/ai/SessionViewer.tool-cost.cjs.map +1 -0
- package/dist/data/ai/SessionViewer.tool-cost.d.ts +6 -0
- package/dist/data/ai/SessionViewer.tool-cost.d.ts.map +1 -0
- package/dist/data/ai/SessionViewer.tool-cost.js +128 -0
- package/dist/data/ai/SessionViewer.tool-cost.js.map +1 -0
- package/dist/data/ai/SessionViewer.tool-details.cjs +3 -1
- package/dist/data/ai/SessionViewer.tool-details.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.tool-details.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.tool-details.js +3 -1
- package/dist/data/ai/SessionViewer.tool-details.js.map +1 -1
- package/dist/data/ai/SessionViewer.tool-row.cjs +55 -35
- package/dist/data/ai/SessionViewer.tool-row.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.tool-row.d.ts +2 -1
- package/dist/data/ai/SessionViewer.tool-row.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.tool-row.js +55 -35
- package/dist/data/ai/SessionViewer.tool-row.js.map +1 -1
- package/dist/data/ai/SessionViewer.unified.d.ts +4 -0
- package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
- package/dist/data/ai/SessionViewerMenu.cjs +18 -1
- package/dist/data/ai/SessionViewerMenu.cjs.map +1 -1
- package/dist/data/ai/SessionViewerMenu.d.ts +6 -1
- package/dist/data/ai/SessionViewerMenu.d.ts.map +1 -1
- package/dist/data/ai/SessionViewerMenu.js +18 -1
- package/dist/data/ai/SessionViewerMenu.js.map +1 -1
- package/dist/data/ai/ToolPreferences.cjs +149 -143
- package/dist/data/ai/ToolPreferences.cjs.map +1 -1
- package/dist/data/ai/ToolPreferences.d.ts +20 -6
- package/dist/data/ai/ToolPreferences.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferences.js +151 -146
- package/dist/data/ai/ToolPreferences.js.map +1 -1
- package/dist/data/ai/ToolPreferences.model.cjs +14 -10
- package/dist/data/ai/ToolPreferences.model.cjs.map +1 -1
- package/dist/data/ai/ToolPreferences.model.d.ts +1 -0
- package/dist/data/ai/ToolPreferences.model.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferences.model.js +15 -11
- package/dist/data/ai/ToolPreferences.model.js.map +1 -1
- package/dist/data/ai/ToolPreferencesList.cjs +1 -0
- package/dist/data/ai/ToolPreferencesList.cjs.map +1 -1
- package/dist/data/ai/ToolPreferencesList.d.ts +4 -1
- package/dist/data/ai/ToolPreferencesList.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferencesList.js +2 -1
- package/dist/data/ai/ToolPreferencesList.js.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.cjs +52 -53
- package/dist/data/ai/ToolSchemaBrowser.cjs.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.d.ts +6 -3
- package/dist/data/ai/ToolSchemaBrowser.d.ts.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.directory-header.cjs +9 -13
- package/dist/data/ai/ToolSchemaBrowser.directory-header.cjs.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.directory-header.d.ts +5 -2
- package/dist/data/ai/ToolSchemaBrowser.directory-header.d.ts.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.directory-header.js +9 -13
- package/dist/data/ai/ToolSchemaBrowser.directory-header.js.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.js +53 -54
- package/dist/data/ai/ToolSchemaBrowser.js.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.model.cjs +19 -27
- package/dist/data/ai/ToolSchemaBrowser.model.cjs.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.model.d.ts +9 -6
- package/dist/data/ai/ToolSchemaBrowser.model.d.ts.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.model.js +20 -28
- package/dist/data/ai/ToolSchemaBrowser.model.js.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.sidebar.cjs +12 -213
- package/dist/data/ai/ToolSchemaBrowser.sidebar.cjs.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.sidebar.d.ts +1 -3
- package/dist/data/ai/ToolSchemaBrowser.sidebar.d.ts.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.sidebar.js +13 -214
- package/dist/data/ai/ToolSchemaBrowser.sidebar.js.map +1 -1
- package/dist/data/ai/ToolSchemaBrowser.strategies.cjs +54 -0
- package/dist/data/ai/ToolSchemaBrowser.strategies.cjs.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.strategies.d.ts +9 -0
- package/dist/data/ai/ToolSchemaBrowser.strategies.d.ts.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.strategies.js +54 -0
- package/dist/data/ai/ToolSchemaBrowser.strategies.js.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.tree.cjs +179 -0
- package/dist/data/ai/ToolSchemaBrowser.tree.cjs.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.tree.d.ts +20 -0
- package/dist/data/ai/ToolSchemaBrowser.tree.d.ts.map +1 -0
- package/dist/data/ai/ToolSchemaBrowser.tree.js +179 -0
- package/dist/data/ai/ToolSchemaBrowser.tree.js.map +1 -0
- package/dist/data/ai/index.d.ts +2 -2
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/ai/runtime-profiles/PermissionStrategiesEditor.cjs +8 -28
- package/dist/data/ai/runtime-profiles/PermissionStrategiesEditor.cjs.map +1 -1
- package/dist/data/ai/runtime-profiles/PermissionStrategiesEditor.d.ts.map +1 -1
- package/dist/data/ai/runtime-profiles/PermissionStrategiesEditor.js +9 -29
- package/dist/data/ai/runtime-profiles/PermissionStrategiesEditor.js.map +1 -1
- package/dist/data/ai/session-token-sizing.d.ts +32 -0
- package/dist/data/ai/session-token-sizing.d.ts.map +1 -0
- package/dist/data/ai/use-session-token-sizing.cjs +73 -0
- package/dist/data/ai/use-session-token-sizing.cjs.map +1 -0
- package/dist/data/ai/use-session-token-sizing.d.ts +21 -0
- package/dist/data/ai/use-session-token-sizing.d.ts.map +1 -0
- package/dist/data/ai/use-session-token-sizing.js +73 -0
- package/dist/data/ai/use-session-token-sizing.js.map +1 -0
- package/dist/data/call-graph/CallGraph.cjs +250 -0
- package/dist/data/call-graph/CallGraph.cjs.map +1 -0
- package/dist/data/call-graph/CallGraph.d.ts +69 -0
- package/dist/data/call-graph/CallGraph.d.ts.map +1 -0
- package/dist/data/call-graph/CallGraph.js +250 -0
- package/dist/data/call-graph/CallGraph.js.map +1 -0
- package/dist/data/call-graph/CallGraphGlyphs.cjs +39 -0
- package/dist/data/call-graph/CallGraphGlyphs.cjs.map +1 -0
- package/dist/data/call-graph/CallGraphGlyphs.d.ts +19 -0
- package/dist/data/call-graph/CallGraphGlyphs.d.ts.map +1 -0
- package/dist/data/call-graph/CallGraphGlyphs.js +39 -0
- package/dist/data/call-graph/CallGraphGlyphs.js.map +1 -0
- package/dist/data/call-graph/CallGraphMembers.cjs +50 -0
- package/dist/data/call-graph/CallGraphMembers.cjs.map +1 -0
- package/dist/data/call-graph/CallGraphMembers.d.ts +22 -0
- package/dist/data/call-graph/CallGraphMembers.d.ts.map +1 -0
- package/dist/data/call-graph/CallGraphMembers.js +50 -0
- package/dist/data/call-graph/CallGraphMembers.js.map +1 -0
- package/dist/data/call-graph/CallGraphParts.cjs +204 -0
- package/dist/data/call-graph/CallGraphParts.cjs.map +1 -0
- package/dist/data/call-graph/CallGraphParts.d.ts +44 -0
- package/dist/data/call-graph/CallGraphParts.d.ts.map +1 -0
- package/dist/data/call-graph/CallGraphParts.js +204 -0
- package/dist/data/call-graph/CallGraphParts.js.map +1 -0
- package/dist/data/call-graph/CallGraphToolbar.cjs +186 -0
- package/dist/data/call-graph/CallGraphToolbar.cjs.map +1 -0
- package/dist/data/call-graph/CallGraphToolbar.d.ts +45 -0
- package/dist/data/call-graph/CallGraphToolbar.d.ts.map +1 -0
- package/dist/data/call-graph/CallGraphToolbar.js +186 -0
- package/dist/data/call-graph/CallGraphToolbar.js.map +1 -0
- package/dist/data/call-graph/call-graph-exclude.cjs +75 -0
- package/dist/data/call-graph/call-graph-exclude.cjs.map +1 -0
- package/dist/data/call-graph/call-graph-exclude.d.ts +31 -0
- package/dist/data/call-graph/call-graph-exclude.d.ts.map +1 -0
- package/dist/data/call-graph/call-graph-exclude.js +75 -0
- package/dist/data/call-graph/call-graph-exclude.js.map +1 -0
- package/dist/data/call-graph/call-graph-labels.cjs +96 -0
- package/dist/data/call-graph/call-graph-labels.cjs.map +1 -0
- package/dist/data/call-graph/call-graph-labels.d.ts +53 -0
- package/dist/data/call-graph/call-graph-labels.d.ts.map +1 -0
- package/dist/data/call-graph/call-graph-labels.js +96 -0
- package/dist/data/call-graph/call-graph-labels.js.map +1 -0
- package/dist/data/call-graph/call-graph-model.cjs +161 -0
- package/dist/data/call-graph/call-graph-model.cjs.map +1 -0
- package/dist/data/call-graph/call-graph-model.d.ts +102 -0
- package/dist/data/call-graph/call-graph-model.d.ts.map +1 -0
- package/dist/data/call-graph/call-graph-model.js +161 -0
- package/dist/data/call-graph/call-graph-model.js.map +1 -0
- package/dist/data/call-graph/call-graph-vocabulary.cjs +177 -0
- package/dist/data/call-graph/call-graph-vocabulary.cjs.map +1 -0
- package/dist/data/call-graph/call-graph-vocabulary.d.ts +72 -0
- package/dist/data/call-graph/call-graph-vocabulary.d.ts.map +1 -0
- package/dist/data/call-graph/call-graph-vocabulary.js +177 -0
- package/dist/data/call-graph/call-graph-vocabulary.js.map +1 -0
- package/dist/data/call-graph/call-graph.fixtures.d.ts +63 -0
- package/dist/data/call-graph/call-graph.fixtures.d.ts.map +1 -0
- package/dist/data/call-graph/index.d.ts +7 -0
- package/dist/data/call-graph/index.d.ts.map +1 -0
- package/dist/data/call-graph/types.cjs +5 -0
- package/dist/data/call-graph/types.cjs.map +1 -0
- package/dist/data/call-graph/types.d.ts +135 -0
- package/dist/data/call-graph/types.d.ts.map +1 -0
- package/dist/data/call-graph/types.js +5 -0
- package/dist/data/call-graph/types.js.map +1 -0
- package/dist/data/call-graph/use-call-graph.cjs +93 -0
- package/dist/data/call-graph/use-call-graph.cjs.map +1 -0
- package/dist/data/call-graph/use-call-graph.d.ts +24 -0
- package/dist/data/call-graph/use-call-graph.d.ts.map +1 -0
- package/dist/data/call-graph/use-call-graph.js +93 -0
- package/dist/data/call-graph/use-call-graph.js.map +1 -0
- package/dist/data/chat/Chat.cjs +39 -15
- package/dist/data/chat/Chat.cjs.map +1 -1
- package/dist/data/chat/Chat.d.ts.map +1 -1
- package/dist/data/chat/Chat.fixtures.cjs +2 -2
- package/dist/data/chat/Chat.fixtures.cjs.map +1 -1
- package/dist/data/chat/Chat.fixtures.js +2 -2
- package/dist/data/chat/Chat.fixtures.js.map +1 -1
- package/dist/data/chat/Chat.js +40 -16
- package/dist/data/chat/Chat.js.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.cjs +3 -6
- 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 +3 -6
- package/dist/data/chat/ChatRuntimeToolbar.js.map +1 -1
- package/dist/data/chat/ContextMeter.bar.cjs +5 -8
- package/dist/data/chat/ContextMeter.bar.cjs.map +1 -1
- package/dist/data/chat/ContextMeter.bar.d.ts +1 -1
- package/dist/data/chat/ContextMeter.bar.d.ts.map +1 -1
- package/dist/data/chat/ContextMeter.bar.js +5 -8
- package/dist/data/chat/ContextMeter.bar.js.map +1 -1
- package/dist/data/chat/ContextMeter.cjs +18 -19
- package/dist/data/chat/ContextMeter.cjs.map +1 -1
- package/dist/data/chat/ContextMeter.d.ts +1 -1
- package/dist/data/chat/ContextMeter.d.ts.map +1 -1
- package/dist/data/chat/ContextMeter.js +18 -19
- package/dist/data/chat/ContextMeter.js.map +1 -1
- package/dist/data/chat/Conversation.cjs +2 -1
- package/dist/data/chat/Conversation.cjs.map +1 -1
- package/dist/data/chat/Conversation.d.ts +4 -1
- package/dist/data/chat/Conversation.d.ts.map +1 -1
- package/dist/data/chat/Conversation.js +2 -1
- package/dist/data/chat/Conversation.js.map +1 -1
- package/dist/data/chat/Message.cjs +39 -12
- package/dist/data/chat/Message.cjs.map +1 -1
- package/dist/data/chat/Message.d.ts +1 -1
- package/dist/data/chat/Message.d.ts.map +1 -1
- package/dist/data/chat/Message.js +40 -13
- package/dist/data/chat/Message.js.map +1 -1
- package/dist/data/chat/ToolCall.cjs +60 -5
- package/dist/data/chat/ToolCall.cjs.map +1 -1
- package/dist/data/chat/ToolCall.d.ts +7 -2
- package/dist/data/chat/ToolCall.d.ts.map +1 -1
- package/dist/data/chat/ToolCall.js +60 -5
- package/dist/data/chat/ToolCall.js.map +1 -1
- package/dist/data/chat/approval.cjs.map +1 -1
- package/dist/data/chat/approval.d.ts +2 -2
- package/dist/data/chat/approval.d.ts.map +1 -1
- package/dist/data/chat/approval.js.map +1 -1
- package/dist/data/chat/tool-policy.cjs +59 -2
- package/dist/data/chat/tool-policy.cjs.map +1 -1
- package/dist/data/chat/tool-policy.d.ts +9 -0
- package/dist/data/chat/tool-policy.d.ts.map +1 -1
- package/dist/data/chat/tool-policy.js +59 -2
- package/dist/data/chat/tool-policy.js.map +1 -1
- package/dist/data/chat/types.cjs +6 -0
- package/dist/data/chat/types.cjs.map +1 -1
- package/dist/data/chat/types.d.ts +13 -4
- package/dist/data/chat/types.d.ts.map +1 -1
- package/dist/data/chat/types.js +7 -1
- package/dist/data/chat/types.js.map +1 -1
- package/dist/data/chat/usage-snapshot.cjs +11 -6
- package/dist/data/chat/usage-snapshot.cjs.map +1 -1
- package/dist/data/chat/usage-snapshot.d.ts +0 -1
- package/dist/data/chat/usage-snapshot.d.ts.map +1 -1
- package/dist/data/chat/usage-snapshot.js +11 -6
- package/dist/data/chat/usage-snapshot.js.map +1 -1
- package/dist/data/diagnostics/StackFrameRow.cjs +3 -3
- package/dist/data/diagnostics/StackFrameRow.cjs.map +1 -1
- package/dist/data/diagnostics/StackFrameRow.js +3 -3
- package/dist/data/diagnostics/StackFrameRow.js.map +1 -1
- package/dist/data/graph-columns-layout.cjs +26 -10
- package/dist/data/graph-columns-layout.cjs.map +1 -1
- package/dist/data/graph-columns-layout.d.ts +8 -0
- package/dist/data/graph-columns-layout.d.ts.map +1 -1
- package/dist/data/graph-columns-layout.js +26 -10
- package/dist/data/graph-columns-layout.js.map +1 -1
- package/dist/data/graph-diagram-model.cjs.map +1 -1
- package/dist/data/graph-diagram-model.d.ts +5 -0
- package/dist/data/graph-diagram-model.d.ts.map +1 -1
- package/dist/data/graph-diagram-model.js.map +1 -1
- package/dist/data/graph-edge-routing.cjs +9 -3
- package/dist/data/graph-edge-routing.cjs.map +1 -1
- package/dist/data/graph-edge-routing.d.ts +2 -0
- package/dist/data/graph-edge-routing.d.ts.map +1 -1
- package/dist/data/graph-edge-routing.js +9 -3
- package/dist/data/graph-edge-routing.js.map +1 -1
- package/dist/data/json-view/JsonSource.cjs +84 -0
- package/dist/data/json-view/JsonSource.cjs.map +1 -0
- package/dist/data/json-view/JsonSource.d.ts +7 -0
- package/dist/data/json-view/JsonSource.d.ts.map +1 -0
- package/dist/data/json-view/JsonSource.js +84 -0
- package/dist/data/json-view/JsonSource.js.map +1 -0
- package/dist/data/json-view/parse-prefix.cjs +132 -0
- package/dist/data/json-view/parse-prefix.cjs.map +1 -0
- package/dist/data/json-view/parse-prefix.d.ts +11 -0
- package/dist/data/json-view/parse-prefix.d.ts.map +1 -0
- package/dist/data/json-view/parse-prefix.js +132 -0
- package/dist/data/json-view/parse-prefix.js.map +1 -0
- package/dist/data/json-view/parse-source.cjs +62 -0
- package/dist/data/json-view/parse-source.cjs.map +1 -0
- package/dist/data/json-view/parse-source.d.ts +16 -0
- package/dist/data/json-view/parse-source.d.ts.map +1 -0
- package/dist/data/json-view/parse-source.js +62 -0
- package/dist/data/json-view/parse-source.js.map +1 -0
- package/dist/data/json-view/story-fixtures.d.ts +6 -0
- package/dist/data/json-view/story-fixtures.d.ts.map +1 -0
- package/dist/data/json-view/types.d.ts +14 -0
- package/dist/data/json-view/types.d.ts.map +1 -0
- package/dist/data/runtime/RuntimeBar.cjs +2 -5
- package/dist/data/runtime/RuntimeBar.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBar.d.ts +2 -4
- package/dist/data/runtime/RuntimeBar.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBar.fields.cjs +2 -2
- package/dist/data/runtime/RuntimeBar.fields.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBar.fields.js +2 -2
- package/dist/data/runtime/RuntimeBar.fields.js.map +1 -1
- package/dist/data/runtime/RuntimeBar.js +2 -5
- package/dist/data/runtime/RuntimeBar.js.map +1 -1
- package/dist/data/runtime/RuntimeBar.selection.cjs +4 -1
- package/dist/data/runtime/RuntimeBar.selection.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBar.selection.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBar.selection.js +5 -2
- package/dist/data/runtime/RuntimeBar.selection.js.map +1 -1
- package/dist/data/runtime/RuntimeBarActions.cjs +1 -5
- package/dist/data/runtime/RuntimeBarActions.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarActions.d.ts +1 -1
- package/dist/data/runtime/RuntimeBarActions.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarActions.js +1 -5
- package/dist/data/runtime/RuntimeBarActions.js.map +1 -1
- package/dist/data/runtime/RuntimeBarIdentity.cjs +6 -14
- package/dist/data/runtime/RuntimeBarIdentity.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarIdentity.d.ts +0 -1
- package/dist/data/runtime/RuntimeBarIdentity.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarIdentity.js +6 -14
- package/dist/data/runtime/RuntimeBarIdentity.js.map +1 -1
- package/dist/data/runtime/RuntimeBarLayout.cjs +8 -27
- package/dist/data/runtime/RuntimeBarLayout.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarLayout.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarLayout.js +8 -27
- package/dist/data/runtime/RuntimeBarLayout.js.map +1 -1
- package/dist/data/runtime/RuntimeBarSegment.cjs +1 -5
- package/dist/data/runtime/RuntimeBarSegment.cjs.map +1 -1
- package/dist/data/runtime/RuntimeBarSegment.d.ts.map +1 -1
- package/dist/data/runtime/RuntimeBarSegment.js +1 -5
- package/dist/data/runtime/RuntimeBarSegment.js.map +1 -1
- package/dist/data/runtime/use-runtime-bar-overflow.cjs +4 -10
- package/dist/data/runtime/use-runtime-bar-overflow.cjs.map +1 -1
- package/dist/data/runtime/use-runtime-bar-overflow.d.ts +1 -2
- package/dist/data/runtime/use-runtime-bar-overflow.d.ts.map +1 -1
- package/dist/data/runtime/use-runtime-bar-overflow.js +4 -10
- package/dist/data/runtime/use-runtime-bar-overflow.js.map +1 -1
- package/dist/data/test-runner/TestRunner.fixtures.d.ts +0 -20
- package/dist/data/test-runner/TestRunner.fixtures.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunner.large-fixtures.d.ts +22 -0
- package/dist/data/test-runner/TestRunner.large-fixtures.d.ts.map +1 -0
- package/dist/data/use-pan-zoom.cjs +23 -10
- package/dist/data/use-pan-zoom.cjs.map +1 -1
- package/dist/data/use-pan-zoom.d.ts +16 -2
- package/dist/data/use-pan-zoom.d.ts.map +1 -1
- package/dist/data/use-pan-zoom.js +23 -10
- package/dist/data/use-pan-zoom.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +26 -2
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +1 -0
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +24 -0
- package/dist/data.js.map +1 -1
- package/dist/index.cjs +28 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -1
- package/dist/layout/Workspace.cjs +13 -4
- package/dist/layout/Workspace.cjs.map +1 -1
- package/dist/layout/Workspace.d.ts +7 -2
- package/dist/layout/Workspace.d.ts.map +1 -1
- package/dist/layout/Workspace.js +13 -4
- package/dist/layout/Workspace.js.map +1 -1
- package/dist/lib/permission-strategies.cjs +71 -11
- package/dist/lib/permission-strategies.cjs.map +1 -1
- package/dist/lib/permission-strategies.d.ts +3 -0
- package/dist/lib/permission-strategies.d.ts.map +1 -1
- package/dist/lib/permission-strategies.js +71 -11
- package/dist/lib/permission-strategies.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +5 -3
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.cjs +0 -57
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.cjs.map +0 -1
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.d.ts +0 -7
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.d.ts.map +0 -1
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.js +0 -57
- package/dist/data/ai/ToolSchemaBrowser.selection-toolbar.js.map +0 -1
- package/dist/data/runtime/RuntimeBar.context.cjs +0 -8
- package/dist/data/runtime/RuntimeBar.context.cjs.map +0 -1
- package/dist/data/runtime/RuntimeBar.context.d.ts +0 -2
- package/dist/data/runtime/RuntimeBar.context.d.ts.map +0 -1
- package/dist/data/runtime/RuntimeBar.context.js +0 -8
- package/dist/data/runtime/RuntimeBar.context.js.map +0 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const react = require("react");
|
|
5
|
+
const button = require("../../components/button.cjs");
|
|
6
|
+
const InputField = require("../../components/InputField.cjs");
|
|
7
|
+
const SegmentedControl = require("../../components/SegmentedControl.cjs");
|
|
8
|
+
const Switch = require("../../components/Switch.cjs");
|
|
9
|
+
const DropdownMenu = require("../../overlay/DropdownMenu.cjs");
|
|
10
|
+
const Badge = require("../Badge.cjs");
|
|
11
|
+
const callGraphExclude = require("./call-graph-exclude.cjs");
|
|
12
|
+
const callGraphLabels = require("./call-graph-labels.cjs");
|
|
13
|
+
const callGraphModel = require("./call-graph-model.cjs");
|
|
14
|
+
const types = require("./types.cjs");
|
|
15
|
+
const UiHome = require("../../icons/components/UiHome.cjs");
|
|
16
|
+
const UiFilter = require("../../icons/components/UiFilter.cjs");
|
|
17
|
+
const UiWarningTriangle = require("../../icons/components/UiWarningTriangle.cjs");
|
|
18
|
+
const DIRECTIONS = [
|
|
19
|
+
{ id: "callers", label: "Callers" },
|
|
20
|
+
{ id: "both", label: "Both" },
|
|
21
|
+
{ id: "callees", label: "Callees" }
|
|
22
|
+
];
|
|
23
|
+
function DepthStepper({ depth, maxDepth, onChange }) {
|
|
24
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", role: "group", "aria-label": "Depth", children: [
|
|
25
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Depth" }),
|
|
26
|
+
/* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "button", variant: "outline", size: "sm", className: "size-8 px-0", "aria-label": "Decrease depth", disabled: depth <= 1, onClick: () => onChange(depth - 1), children: "−" }),
|
|
27
|
+
/* @__PURE__ */ jsxRuntime.jsx("output", { className: "w-5 text-center text-sm font-medium tabular-nums", "aria-live": "polite", "aria-label": "Graph depth", children: depth }),
|
|
28
|
+
/* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "button", variant: "outline", size: "sm", className: "size-8 px-0", "aria-label": "Increase depth", disabled: depth >= maxDepth, onClick: () => onChange(depth + 1), children: "+" })
|
|
29
|
+
] });
|
|
30
|
+
}
|
|
31
|
+
function OmittedChip({ omitted, noun }) {
|
|
32
|
+
const parts = callGraphLabels.omittedParts(omitted);
|
|
33
|
+
if (parts.length === 0) return null;
|
|
34
|
+
const tally = callGraphLabels.excludedTally(omitted).map(({ group, count }) => `${group}: ${count}`);
|
|
35
|
+
const title = [`Not drawn: ${parts.join(", ")}`, ...tally.length ? [`Excluded per ${noun}:`, ...tally] : []].join("\n");
|
|
36
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { title, "data-testid": "graph-omitted", children: /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { tone: "warning", size: "md", icon: UiWarningTriangle.UiWarningTriangle, clickToCopy: false, children: parts.join(" · ") }) });
|
|
37
|
+
}
|
|
38
|
+
function GroupRow({ group, onToggle }) {
|
|
39
|
+
const name = group.label ?? group.name;
|
|
40
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-center gap-2 py-1", children: [
|
|
41
|
+
/* @__PURE__ */ jsxRuntime.jsx(Switch.Switch, { checked: !group.excluded, onChange: onToggle, "aria-label": `Show ${name}` }),
|
|
42
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate font-mono text-xs", title: group.name, children: name }),
|
|
43
|
+
group.external && /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { variant: "outline", size: "sm", clickToCopy: false, children: "external" }),
|
|
44
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-8 shrink-0 text-right text-xs tabular-nums text-muted-foreground", title: `${group.nodes} nodes`, children: group.nodes })
|
|
45
|
+
] });
|
|
46
|
+
}
|
|
47
|
+
function GroupFacets({ exclude, groups, matches, onExclude, onDefaults, busy, vocabulary }) {
|
|
48
|
+
const [filter, setFilter] = react.useState("");
|
|
49
|
+
const [pattern, setPattern] = react.useState("");
|
|
50
|
+
const [error, setError] = react.useState();
|
|
51
|
+
const { plural, patternHint } = vocabulary.group;
|
|
52
|
+
const needle = filter.trim().toLowerCase();
|
|
53
|
+
const shown = groups.filter((group) => `${group.name} ${group.label ?? ""}`.toLowerCase().includes(needle));
|
|
54
|
+
const submit = (event) => {
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
const typed = pattern.trim();
|
|
57
|
+
const problem = callGraphExclude.excludePatternError(exclude, typed);
|
|
58
|
+
setError(problem);
|
|
59
|
+
if (problem) return;
|
|
60
|
+
setPattern("");
|
|
61
|
+
onExclude(callGraphExclude.addExcludePattern(exclude, typed));
|
|
62
|
+
};
|
|
63
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { disabled: busy, "aria-busy": busy, className: "flex w-96 min-w-0 max-w-[90vw] flex-col gap-2 p-2 text-sm", children: [
|
|
64
|
+
/* @__PURE__ */ jsxRuntime.jsx(InputField.InputField, { "aria-label": `Filter ${plural}`, placeholder: `Filter ${plural}`, value: filter, onChange: setFilter }),
|
|
65
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-1", "aria-label": "Exclusion patterns", children: [
|
|
66
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Excluding" }),
|
|
67
|
+
exclude.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "nothing" }),
|
|
68
|
+
exclude.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
69
|
+
"button",
|
|
70
|
+
{
|
|
71
|
+
type: "button",
|
|
72
|
+
className: "rounded border border-border px-1.5 font-mono text-xs hover:bg-muted",
|
|
73
|
+
"aria-label": `Stop excluding ${entry}`,
|
|
74
|
+
title: `Stop excluding ${entry}`,
|
|
75
|
+
onClick: () => onExclude(callGraphExclude.removeExcludePattern(exclude, entry)),
|
|
76
|
+
children: [
|
|
77
|
+
entry,
|
|
78
|
+
" ×"
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
entry
|
|
82
|
+
))
|
|
83
|
+
] }),
|
|
84
|
+
/* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "max-h-72 overflow-y-auto pr-1", "aria-label": plural, children: [
|
|
85
|
+
shown.map((group) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
86
|
+
GroupRow,
|
|
87
|
+
{
|
|
88
|
+
group,
|
|
89
|
+
onToggle: () => onExclude(group.excluded ? callGraphExclude.includeGroup(exclude, group, groups, matches) : callGraphExclude.excludeGroup(exclude, group.name))
|
|
90
|
+
},
|
|
91
|
+
group.name
|
|
92
|
+
)),
|
|
93
|
+
shown.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("li", { className: "py-1 text-xs text-muted-foreground", children: groups.length ? `No ${vocabulary.group.noun} matches the filter.` : `The graph reached no ${vocabulary.group.noun}.` })
|
|
94
|
+
] }),
|
|
95
|
+
/* @__PURE__ */ jsxRuntime.jsxs("form", { className: "flex items-start gap-2", onSubmit: submit, children: [
|
|
96
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
97
|
+
/* @__PURE__ */ jsxRuntime.jsx(InputField.InputField, { "aria-label": "Exclude pattern", placeholder: patternHint, value: pattern, onChange: setPattern }),
|
|
98
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("span", { role: "alert", className: "text-xs text-destructive", children: error })
|
|
99
|
+
] }),
|
|
100
|
+
/* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "submit", size: "sm", variant: "outline", children: "Exclude" })
|
|
101
|
+
] }),
|
|
102
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between gap-2 border-t border-border pt-2", children: [
|
|
103
|
+
/* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "button", size: "sm", variant: "ghost", onClick: onDefaults, children: "Reset to defaults" }),
|
|
104
|
+
/* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "button", size: "sm", variant: "ghost", onClick: () => onExclude([]), children: "Show all" })
|
|
105
|
+
] })
|
|
106
|
+
] });
|
|
107
|
+
}
|
|
108
|
+
const ACCESS_LABELS = { call: "Calls", read: "Reads", write: "Writes" };
|
|
109
|
+
function DataAccessControls({ access, onAccess, columns, onColumns }) {
|
|
110
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
111
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", role: "group", "aria-label": "Access", children: types.CALL_GRAPH_ACCESS.map((type) => {
|
|
112
|
+
const on = access.includes(type);
|
|
113
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
114
|
+
button.Button,
|
|
115
|
+
{
|
|
116
|
+
type: "button",
|
|
117
|
+
size: "sm",
|
|
118
|
+
variant: on ? "secondary" : "outline",
|
|
119
|
+
"aria-pressed": on,
|
|
120
|
+
disabled: on && access.length === 1,
|
|
121
|
+
title: on && access.length === 1 ? "At least one kind of access stays on" : void 0,
|
|
122
|
+
onClick: () => onAccess(callGraphModel.toggleAccess(access, type)),
|
|
123
|
+
children: ACCESS_LABELS[type]
|
|
124
|
+
},
|
|
125
|
+
type
|
|
126
|
+
);
|
|
127
|
+
}) }),
|
|
128
|
+
/* @__PURE__ */ jsxRuntime.jsx(Switch.Switch, { checked: columns, label: "Columns", onChange: onColumns })
|
|
129
|
+
] });
|
|
130
|
+
}
|
|
131
|
+
function CallGraphToolbar(props) {
|
|
132
|
+
const { exclusions, pin, vocabulary } = props;
|
|
133
|
+
const excludedCount = (exclusions == null ? void 0 : exclusions.groups.filter((group) => group.excluded).length) ?? 0;
|
|
134
|
+
const hasExternal = (exclusions == null ? void 0 : exclusions.groups.some((group) => group.external)) ?? false;
|
|
135
|
+
const { noun, plural } = vocabulary.group;
|
|
136
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
137
|
+
/* @__PURE__ */ jsxRuntime.jsx(SegmentedControl.SegmentedControl, { value: props.direction, options: DIRECTIONS, onChange: props.onDirection, size: "sm", "aria-label": "Direction" }),
|
|
138
|
+
/* @__PURE__ */ jsxRuntime.jsx(DepthStepper, { depth: props.depth, maxDepth: props.maxDepth, onChange: props.onDepth }),
|
|
139
|
+
props.data && /* @__PURE__ */ jsxRuntime.jsx(DataAccessControls, { ...props.data }),
|
|
140
|
+
pin && /* @__PURE__ */ jsxRuntime.jsx(
|
|
141
|
+
button.Button,
|
|
142
|
+
{
|
|
143
|
+
type: "button",
|
|
144
|
+
variant: pin.pinned ? "secondary" : "outline",
|
|
145
|
+
size: "sm",
|
|
146
|
+
disabled: !pin.pinned && !pin.canPin,
|
|
147
|
+
"aria-pressed": pin.pinned,
|
|
148
|
+
title: pin.pinned ? "The graph keeps this root while the selection changes" : "Keep this root while the selection changes",
|
|
149
|
+
onClick: () => pin.onPin(!pin.pinned),
|
|
150
|
+
children: pin.pinned ? "Unpin root" : "Pin root"
|
|
151
|
+
}
|
|
152
|
+
),
|
|
153
|
+
/* @__PURE__ */ jsxRuntime.jsx(button.Button, { type: "button", variant: "outline", size: "sm", onClick: props.onFit, children: "Fit" }),
|
|
154
|
+
/* @__PURE__ */ jsxRuntime.jsxs(button.Button, { type: "button", variant: "outline", size: "sm", onClick: props.onReset, children: [
|
|
155
|
+
/* @__PURE__ */ jsxRuntime.jsx(UiHome.UiHome, {}),
|
|
156
|
+
"Reset"
|
|
157
|
+
] }),
|
|
158
|
+
exclusions && hasExternal && /* @__PURE__ */ jsxRuntime.jsx(
|
|
159
|
+
Switch.Switch,
|
|
160
|
+
{
|
|
161
|
+
checked: exclusions.exclude.includes(callGraphExclude.EXCLUDE_EXTERNAL),
|
|
162
|
+
disabled: exclusions.busy,
|
|
163
|
+
label: "Hide all external",
|
|
164
|
+
onChange: (hidden) => exclusions.onExclude(callGraphExclude.setExternalHidden(exclusions.exclude, hidden))
|
|
165
|
+
}
|
|
166
|
+
),
|
|
167
|
+
exclusions && /* @__PURE__ */ jsxRuntime.jsx(
|
|
168
|
+
DropdownMenu.DropdownMenu,
|
|
169
|
+
{
|
|
170
|
+
icon: UiFilter.UiFilter,
|
|
171
|
+
label: `${callGraphLabels.capitalize(plural)}${excludedCount ? ` (${excludedCount} excluded)` : ""}`,
|
|
172
|
+
variant: "outline",
|
|
173
|
+
size: "sm",
|
|
174
|
+
menuLabel: `${callGraphLabels.capitalize(noun)} exclusions`,
|
|
175
|
+
title: `Choose the ${plural} the graph leaves out`,
|
|
176
|
+
children: () => /* @__PURE__ */ jsxRuntime.jsx(GroupFacets, { ...exclusions })
|
|
177
|
+
}
|
|
178
|
+
),
|
|
179
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
|
|
180
|
+
props.omitted && /* @__PURE__ */ jsxRuntime.jsx(OmittedChip, { omitted: props.omitted, noun }),
|
|
181
|
+
props.end
|
|
182
|
+
] })
|
|
183
|
+
] });
|
|
184
|
+
}
|
|
185
|
+
exports.CallGraphToolbar = CallGraphToolbar;
|
|
186
|
+
//# sourceMappingURL=CallGraphToolbar.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallGraphToolbar.cjs","sources":["../../../src/data/call-graph/CallGraphToolbar.tsx"],"sourcesContent":["import { useState, type FormEvent, type ReactNode } from \"react\";\nimport { Button } from \"../../components/button\";\nimport { InputField } from \"../../components/InputField\";\nimport { SegmentedControl } from \"../../components/SegmentedControl\";\nimport { Switch } from \"../../components/Switch\";\nimport { UiFilter, UiHome, UiWarningTriangle } from \"../../icons\";\nimport { DropdownMenu } from \"../../overlay/DropdownMenu\";\nimport { Badge } from \"../Badge\";\nimport {\n addExcludePattern,\n EXCLUDE_EXTERNAL,\n excludeGroup,\n excludePatternError,\n includeGroup,\n removeExcludePattern,\n setExternalHidden,\n type ExcludeMatcher,\n} from \"./call-graph-exclude\";\nimport { capitalize, excludedTally, omittedParts } from \"./call-graph-labels\";\nimport { toggleAccess } from \"./call-graph-model\";\nimport type { CallGraphVocabulary } from \"./call-graph-vocabulary\";\nimport { CALL_GRAPH_ACCESS, type CallGraphAccess, type CallGraphDirection, type CallGraphGroupFact, type CallGraphOmitted } from \"./types\";\n\nconst DIRECTIONS: { id: CallGraphDirection; label: string }[] = [\n { id: \"callers\", label: \"Callers\" },\n { id: \"both\", label: \"Both\" },\n { id: \"callees\", label: \"Callees\" },\n];\n\nfunction DepthStepper({ depth, maxDepth, onChange }: { depth: number; maxDepth: number; onChange: (depth: number) => void }) {\n return (\n <div className=\"flex items-center gap-1\" role=\"group\" aria-label=\"Depth\">\n <span className=\"text-xs text-muted-foreground\">Depth</span>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"size-8 px-0\" aria-label=\"Decrease depth\" disabled={depth <= 1} onClick={() => onChange(depth - 1)}>−</Button>\n <output className=\"w-5 text-center text-sm font-medium tabular-nums\" aria-live=\"polite\" aria-label=\"Graph depth\">{depth}</output>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"size-8 px-0\" aria-label=\"Increase depth\" disabled={depth >= maxDepth} onClick={() => onChange(depth + 1)}>+</Button>\n </div>\n );\n}\n\nfunction OmittedChip({ omitted, noun }: { omitted: CallGraphOmitted; noun: string }) {\n const parts = omittedParts(omitted);\n if (parts.length === 0) return null;\n const tally = excludedTally(omitted).map(({ group, count }) => `${group}: ${count}`);\n const title = [`Not drawn: ${parts.join(\", \")}`, ...(tally.length ? [`Excluded per ${noun}:`, ...tally] : [])].join(\"\\n\");\n return (\n <span title={title} data-testid=\"graph-omitted\">\n <Badge tone=\"warning\" size=\"md\" icon={UiWarningTriangle} clickToCopy={false}>{parts.join(\" · \")}</Badge>\n </span>\n );\n}\n\nexport interface ExclusionsProps {\n /** The patterns in force. */\n exclude: string[];\n groups: CallGraphGroupFact[];\n matches: ExcludeMatcher;\n onExclude: (patterns: string[]) => void;\n onDefaults: () => void;\n /** A graph for the last edit is loading: the facts describe the one before it, so editing waits. */\n busy: boolean;\n vocabulary: CallGraphVocabulary;\n}\n\nfunction GroupRow({ group, onToggle }: { group: CallGraphGroupFact; onToggle: () => void }) {\n const name = group.label ?? group.name;\n return (\n <li className=\"flex items-center gap-2 py-1\">\n <Switch checked={!group.excluded} onChange={onToggle} aria-label={`Show ${name}`} />\n <span className=\"min-w-0 flex-1 truncate font-mono text-xs\" title={group.name}>{name}</span>\n {group.external && <Badge variant=\"outline\" size=\"sm\" clickToCopy={false}>external</Badge>}\n <span className=\"w-8 shrink-0 text-right text-xs tabular-nums text-muted-foreground\" title={`${group.nodes} nodes`}>{group.nodes}</span>\n </li>\n );\n}\n\n/** The group facets: one switch per group the walk reached, the patterns in force, and free-text patterns. */\nfunction GroupFacets({ exclude, groups, matches, onExclude, onDefaults, busy, vocabulary }: ExclusionsProps) {\n const [filter, setFilter] = useState(\"\");\n const [pattern, setPattern] = useState(\"\");\n const [error, setError] = useState<string>();\n const { plural, patternHint } = vocabulary.group;\n const needle = filter.trim().toLowerCase();\n const shown = groups.filter((group) => `${group.name} ${group.label ?? \"\"}`.toLowerCase().includes(needle));\n const submit = (event: FormEvent) => {\n event.preventDefault();\n const typed = pattern.trim();\n const problem = excludePatternError(exclude, typed);\n setError(problem);\n if (problem) return;\n setPattern(\"\");\n onExclude(addExcludePattern(exclude, typed));\n };\n // The filter box comes first: the menu focuses its first control on opening, which must not be one that drops an exclusion.\n return (\n <fieldset disabled={busy} aria-busy={busy} className=\"flex w-96 min-w-0 max-w-[90vw] flex-col gap-2 p-2 text-sm\">\n <InputField aria-label={`Filter ${plural}`} placeholder={`Filter ${plural}`} value={filter} onChange={setFilter} />\n <div className=\"flex flex-wrap items-center gap-1\" aria-label=\"Exclusion patterns\">\n <span className=\"text-xs text-muted-foreground\">Excluding</span>\n {exclude.length === 0 && <span className=\"text-xs text-muted-foreground\">nothing</span>}\n {exclude.map((entry) => (\n <button key={entry} type=\"button\" className=\"rounded border border-border px-1.5 font-mono text-xs hover:bg-muted\"\n aria-label={`Stop excluding ${entry}`} title={`Stop excluding ${entry}`} onClick={() => onExclude(removeExcludePattern(exclude, entry))}>\n {entry} ×\n </button>\n ))}\n </div>\n <ul className=\"max-h-72 overflow-y-auto pr-1\" aria-label={plural}>\n {shown.map((group) => (\n <GroupRow key={group.name} group={group}\n onToggle={() => onExclude(group.excluded ? includeGroup(exclude, group, groups, matches) : excludeGroup(exclude, group.name))} />\n ))}\n {shown.length === 0 && (\n <li className=\"py-1 text-xs text-muted-foreground\">{groups.length ? `No ${vocabulary.group.noun} matches the filter.` : `The graph reached no ${vocabulary.group.noun}.`}</li>\n )}\n </ul>\n <form className=\"flex items-start gap-2\" onSubmit={submit}>\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n <InputField aria-label=\"Exclude pattern\" placeholder={patternHint} value={pattern} onChange={setPattern} />\n {error && <span role=\"alert\" className=\"text-xs text-destructive\">{error}</span>}\n </div>\n <Button type=\"submit\" size=\"sm\" variant=\"outline\">Exclude</Button>\n </form>\n <div className=\"flex justify-between gap-2 border-t border-border pt-2\">\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" onClick={onDefaults}>Reset to defaults</Button>\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" onClick={() => onExclude([])}>Show all</Button>\n </div>\n </fieldset>\n );\n}\n\nconst ACCESS_LABELS: Record<CallGraphAccess, string> = { call: \"Calls\", read: \"Reads\", write: \"Writes\" };\n\nexport interface DataAccessProps {\n access: CallGraphAccess[];\n onAccess: (access: CallGraphAccess[]) => void;\n columns: boolean;\n onColumns: (columns: boolean) => void;\n}\n\n/** Which edge types the graph follows, at least one, and whether columns and fields are nodes of their own. */\nfunction DataAccessControls({ access, onAccess, columns, onColumns }: DataAccessProps) {\n return (\n <>\n <div className=\"flex items-center gap-1\" role=\"group\" aria-label=\"Access\">\n {CALL_GRAPH_ACCESS.map((type) => {\n const on = access.includes(type);\n return (\n <Button key={type} type=\"button\" size=\"sm\" variant={on ? \"secondary\" : \"outline\"} aria-pressed={on} disabled={on && access.length === 1}\n title={on && access.length === 1 ? \"At least one kind of access stays on\" : undefined} onClick={() => onAccess(toggleAccess(access, type))}>\n {ACCESS_LABELS[type]}\n </Button>\n );\n })}\n </div>\n <Switch checked={columns} label=\"Columns\" onChange={onColumns} />\n </>\n );\n}\n\nexport interface CallGraphToolbarProps {\n /** Shown only when the host's graph has reads and writes. */\n data?: DataAccessProps | undefined;\n direction: CallGraphDirection;\n depth: number;\n maxDepth: number;\n /** Shown only when the host keeps a root across selection changes. */\n pin?: { pinned: boolean; canPin: boolean; onPin: (pinned: boolean) => void } | undefined;\n exclusions?: ExclusionsProps | undefined;\n omitted?: CallGraphOmitted | undefined;\n /** Host content at the toolbar's end, such as server timing. */\n end?: ReactNode;\n onDirection: (direction: CallGraphDirection) => void;\n onDepth: (depth: number) => void;\n onFit: () => void;\n onReset: () => void;\n vocabulary: CallGraphVocabulary;\n}\n\nexport function CallGraphToolbar(props: CallGraphToolbarProps) {\n const { exclusions, pin, vocabulary } = props;\n const excludedCount = exclusions?.groups.filter((group) => group.excluded).length ?? 0;\n const hasExternal = exclusions?.groups.some((group) => group.external) ?? false;\n const { noun, plural } = vocabulary.group;\n return (\n <div className=\"flex flex-wrap items-center gap-3\">\n <SegmentedControl value={props.direction} options={DIRECTIONS} onChange={props.onDirection} size=\"sm\" aria-label=\"Direction\" />\n <DepthStepper depth={props.depth} maxDepth={props.maxDepth} onChange={props.onDepth} />\n {props.data && <DataAccessControls {...props.data} />}\n {pin && (\n <Button type=\"button\" variant={pin.pinned ? \"secondary\" : \"outline\"} size=\"sm\" disabled={!pin.pinned && !pin.canPin} aria-pressed={pin.pinned}\n title={pin.pinned ? \"The graph keeps this root while the selection changes\" : \"Keep this root while the selection changes\"} onClick={() => pin.onPin(!pin.pinned)}>\n {pin.pinned ? \"Unpin root\" : \"Pin root\"}\n </Button>\n )}\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={props.onFit}>Fit</Button>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={props.onReset}><UiHome />Reset</Button>\n {exclusions && hasExternal && (\n <Switch checked={exclusions.exclude.includes(EXCLUDE_EXTERNAL)} disabled={exclusions.busy} label=\"Hide all external\"\n onChange={(hidden) => exclusions.onExclude(setExternalHidden(exclusions.exclude, hidden))} />\n )}\n {exclusions && (\n <DropdownMenu icon={UiFilter} label={`${capitalize(plural)}${excludedCount ? ` (${excludedCount} excluded)` : \"\"}`} variant=\"outline\" size=\"sm\"\n menuLabel={`${capitalize(noun)} exclusions`} title={`Choose the ${plural} the graph leaves out`}>\n {() => <GroupFacets {...exclusions} />}\n </DropdownMenu>\n )}\n <div className=\"ml-auto flex items-center gap-2\">\n {props.omitted && <OmittedChip omitted={props.omitted} noun={noun} />}\n {props.end}\n </div>\n </div>\n );\n}\n"],"names":["jsx","Button","omittedParts","excludedTally","Badge","UiWarningTriangle","jsxs","Switch","useState","excludePatternError","addExcludePattern","InputField","removeExcludePattern","includeGroup","excludeGroup","Fragment","CALL_GRAPH_ACCESS","toggleAccess","SegmentedControl","UiHome","EXCLUDE_EXTERNAL","setExternalHidden","DropdownMenu","UiFilter","capitalize"],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ExcludeMatcher } from './call-graph-exclude.js';
|
|
3
|
+
import { CallGraphVocabulary } from './call-graph-vocabulary.js';
|
|
4
|
+
import { CallGraphAccess, CallGraphDirection, CallGraphGroupFact, CallGraphOmitted } from './types.js';
|
|
5
|
+
export interface ExclusionsProps {
|
|
6
|
+
/** The patterns in force. */
|
|
7
|
+
exclude: string[];
|
|
8
|
+
groups: CallGraphGroupFact[];
|
|
9
|
+
matches: ExcludeMatcher;
|
|
10
|
+
onExclude: (patterns: string[]) => void;
|
|
11
|
+
onDefaults: () => void;
|
|
12
|
+
/** A graph for the last edit is loading: the facts describe the one before it, so editing waits. */
|
|
13
|
+
busy: boolean;
|
|
14
|
+
vocabulary: CallGraphVocabulary;
|
|
15
|
+
}
|
|
16
|
+
export interface DataAccessProps {
|
|
17
|
+
access: CallGraphAccess[];
|
|
18
|
+
onAccess: (access: CallGraphAccess[]) => void;
|
|
19
|
+
columns: boolean;
|
|
20
|
+
onColumns: (columns: boolean) => void;
|
|
21
|
+
}
|
|
22
|
+
export interface CallGraphToolbarProps {
|
|
23
|
+
/** Shown only when the host's graph has reads and writes. */
|
|
24
|
+
data?: DataAccessProps | undefined;
|
|
25
|
+
direction: CallGraphDirection;
|
|
26
|
+
depth: number;
|
|
27
|
+
maxDepth: number;
|
|
28
|
+
/** Shown only when the host keeps a root across selection changes. */
|
|
29
|
+
pin?: {
|
|
30
|
+
pinned: boolean;
|
|
31
|
+
canPin: boolean;
|
|
32
|
+
onPin: (pinned: boolean) => void;
|
|
33
|
+
} | undefined;
|
|
34
|
+
exclusions?: ExclusionsProps | undefined;
|
|
35
|
+
omitted?: CallGraphOmitted | undefined;
|
|
36
|
+
/** Host content at the toolbar's end, such as server timing. */
|
|
37
|
+
end?: ReactNode;
|
|
38
|
+
onDirection: (direction: CallGraphDirection) => void;
|
|
39
|
+
onDepth: (depth: number) => void;
|
|
40
|
+
onFit: () => void;
|
|
41
|
+
onReset: () => void;
|
|
42
|
+
vocabulary: CallGraphVocabulary;
|
|
43
|
+
}
|
|
44
|
+
export declare function CallGraphToolbar(props: CallGraphToolbarProps): import("react").JSX.Element;
|
|
45
|
+
//# sourceMappingURL=CallGraphToolbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallGraphToolbar.d.ts","sourceRoot":"","sources":["../../../src/data/call-graph/CallGraphToolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAQjE,OAAO,EAQL,KAAK,cAAc,EACpB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAqB,KAAK,eAAe,EAAE,KAAK,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA+B3I,MAAM,WAAW,eAAe;IAC9B,6BAA6B;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,oGAAoG;IACpG,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,mBAAmB,CAAC;CACjC;AAuED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACvC;AAsBD,MAAM,WAAW,qBAAqB;IACpC,6DAA6D;IAC7D,IAAI,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IACnC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,GAAG,CAAC,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,GAAG,SAAS,CAAC;IACzF,UAAU,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IACzC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACvC,gEAAgE;IAChE,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,CAAC,SAAS,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACrD,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,EAAE,mBAAmB,CAAC;CACjC;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,+BAkC5D"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Button } from "../../components/button.js";
|
|
4
|
+
import { InputField } from "../../components/InputField.js";
|
|
5
|
+
import { SegmentedControl } from "../../components/SegmentedControl.js";
|
|
6
|
+
import { Switch } from "../../components/Switch.js";
|
|
7
|
+
import { DropdownMenu } from "../../overlay/DropdownMenu.js";
|
|
8
|
+
import { Badge } from "../Badge.js";
|
|
9
|
+
import { setExternalHidden, EXCLUDE_EXTERNAL, removeExcludePattern, includeGroup, excludeGroup, excludePatternError, addExcludePattern } from "./call-graph-exclude.js";
|
|
10
|
+
import { capitalize, omittedParts, excludedTally } from "./call-graph-labels.js";
|
|
11
|
+
import { toggleAccess } from "./call-graph-model.js";
|
|
12
|
+
import { CALL_GRAPH_ACCESS } from "./types.js";
|
|
13
|
+
import { UiHome } from "../../icons/components/UiHome.js";
|
|
14
|
+
import { UiFilter } from "../../icons/components/UiFilter.js";
|
|
15
|
+
import { UiWarningTriangle } from "../../icons/components/UiWarningTriangle.js";
|
|
16
|
+
const DIRECTIONS = [
|
|
17
|
+
{ id: "callers", label: "Callers" },
|
|
18
|
+
{ id: "both", label: "Both" },
|
|
19
|
+
{ id: "callees", label: "Callees" }
|
|
20
|
+
];
|
|
21
|
+
function DepthStepper({ depth, maxDepth, onChange }) {
|
|
22
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", role: "group", "aria-label": "Depth", children: [
|
|
23
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Depth" }),
|
|
24
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", className: "size-8 px-0", "aria-label": "Decrease depth", disabled: depth <= 1, onClick: () => onChange(depth - 1), children: "−" }),
|
|
25
|
+
/* @__PURE__ */ jsx("output", { className: "w-5 text-center text-sm font-medium tabular-nums", "aria-live": "polite", "aria-label": "Graph depth", children: depth }),
|
|
26
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", className: "size-8 px-0", "aria-label": "Increase depth", disabled: depth >= maxDepth, onClick: () => onChange(depth + 1), children: "+" })
|
|
27
|
+
] });
|
|
28
|
+
}
|
|
29
|
+
function OmittedChip({ omitted, noun }) {
|
|
30
|
+
const parts = omittedParts(omitted);
|
|
31
|
+
if (parts.length === 0) return null;
|
|
32
|
+
const tally = excludedTally(omitted).map(({ group, count }) => `${group}: ${count}`);
|
|
33
|
+
const title = [`Not drawn: ${parts.join(", ")}`, ...tally.length ? [`Excluded per ${noun}:`, ...tally] : []].join("\n");
|
|
34
|
+
return /* @__PURE__ */ jsx("span", { title, "data-testid": "graph-omitted", children: /* @__PURE__ */ jsx(Badge, { tone: "warning", size: "md", icon: UiWarningTriangle, clickToCopy: false, children: parts.join(" · ") }) });
|
|
35
|
+
}
|
|
36
|
+
function GroupRow({ group, onToggle }) {
|
|
37
|
+
const name = group.label ?? group.name;
|
|
38
|
+
return /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-2 py-1", children: [
|
|
39
|
+
/* @__PURE__ */ jsx(Switch, { checked: !group.excluded, onChange: onToggle, "aria-label": `Show ${name}` }),
|
|
40
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-mono text-xs", title: group.name, children: name }),
|
|
41
|
+
group.external && /* @__PURE__ */ jsx(Badge, { variant: "outline", size: "sm", clickToCopy: false, children: "external" }),
|
|
42
|
+
/* @__PURE__ */ jsx("span", { className: "w-8 shrink-0 text-right text-xs tabular-nums text-muted-foreground", title: `${group.nodes} nodes`, children: group.nodes })
|
|
43
|
+
] });
|
|
44
|
+
}
|
|
45
|
+
function GroupFacets({ exclude, groups, matches, onExclude, onDefaults, busy, vocabulary }) {
|
|
46
|
+
const [filter, setFilter] = useState("");
|
|
47
|
+
const [pattern, setPattern] = useState("");
|
|
48
|
+
const [error, setError] = useState();
|
|
49
|
+
const { plural, patternHint } = vocabulary.group;
|
|
50
|
+
const needle = filter.trim().toLowerCase();
|
|
51
|
+
const shown = groups.filter((group) => `${group.name} ${group.label ?? ""}`.toLowerCase().includes(needle));
|
|
52
|
+
const submit = (event) => {
|
|
53
|
+
event.preventDefault();
|
|
54
|
+
const typed = pattern.trim();
|
|
55
|
+
const problem = excludePatternError(exclude, typed);
|
|
56
|
+
setError(problem);
|
|
57
|
+
if (problem) return;
|
|
58
|
+
setPattern("");
|
|
59
|
+
onExclude(addExcludePattern(exclude, typed));
|
|
60
|
+
};
|
|
61
|
+
return /* @__PURE__ */ jsxs("fieldset", { disabled: busy, "aria-busy": busy, className: "flex w-96 min-w-0 max-w-[90vw] flex-col gap-2 p-2 text-sm", children: [
|
|
62
|
+
/* @__PURE__ */ jsx(InputField, { "aria-label": `Filter ${plural}`, placeholder: `Filter ${plural}`, value: filter, onChange: setFilter }),
|
|
63
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1", "aria-label": "Exclusion patterns", children: [
|
|
64
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Excluding" }),
|
|
65
|
+
exclude.length === 0 && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "nothing" }),
|
|
66
|
+
exclude.map((entry) => /* @__PURE__ */ jsxs(
|
|
67
|
+
"button",
|
|
68
|
+
{
|
|
69
|
+
type: "button",
|
|
70
|
+
className: "rounded border border-border px-1.5 font-mono text-xs hover:bg-muted",
|
|
71
|
+
"aria-label": `Stop excluding ${entry}`,
|
|
72
|
+
title: `Stop excluding ${entry}`,
|
|
73
|
+
onClick: () => onExclude(removeExcludePattern(exclude, entry)),
|
|
74
|
+
children: [
|
|
75
|
+
entry,
|
|
76
|
+
" ×"
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
entry
|
|
80
|
+
))
|
|
81
|
+
] }),
|
|
82
|
+
/* @__PURE__ */ jsxs("ul", { className: "max-h-72 overflow-y-auto pr-1", "aria-label": plural, children: [
|
|
83
|
+
shown.map((group) => /* @__PURE__ */ jsx(
|
|
84
|
+
GroupRow,
|
|
85
|
+
{
|
|
86
|
+
group,
|
|
87
|
+
onToggle: () => onExclude(group.excluded ? includeGroup(exclude, group, groups, matches) : excludeGroup(exclude, group.name))
|
|
88
|
+
},
|
|
89
|
+
group.name
|
|
90
|
+
)),
|
|
91
|
+
shown.length === 0 && /* @__PURE__ */ jsx("li", { className: "py-1 text-xs text-muted-foreground", children: groups.length ? `No ${vocabulary.group.noun} matches the filter.` : `The graph reached no ${vocabulary.group.noun}.` })
|
|
92
|
+
] }),
|
|
93
|
+
/* @__PURE__ */ jsxs("form", { className: "flex items-start gap-2", onSubmit: submit, children: [
|
|
94
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
95
|
+
/* @__PURE__ */ jsx(InputField, { "aria-label": "Exclude pattern", placeholder: patternHint, value: pattern, onChange: setPattern }),
|
|
96
|
+
error && /* @__PURE__ */ jsx("span", { role: "alert", className: "text-xs text-destructive", children: error })
|
|
97
|
+
] }),
|
|
98
|
+
/* @__PURE__ */ jsx(Button, { type: "submit", size: "sm", variant: "outline", children: "Exclude" })
|
|
99
|
+
] }),
|
|
100
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-2 border-t border-border pt-2", children: [
|
|
101
|
+
/* @__PURE__ */ jsx(Button, { type: "button", size: "sm", variant: "ghost", onClick: onDefaults, children: "Reset to defaults" }),
|
|
102
|
+
/* @__PURE__ */ jsx(Button, { type: "button", size: "sm", variant: "ghost", onClick: () => onExclude([]), children: "Show all" })
|
|
103
|
+
] })
|
|
104
|
+
] });
|
|
105
|
+
}
|
|
106
|
+
const ACCESS_LABELS = { call: "Calls", read: "Reads", write: "Writes" };
|
|
107
|
+
function DataAccessControls({ access, onAccess, columns, onColumns }) {
|
|
108
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
109
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", role: "group", "aria-label": "Access", children: CALL_GRAPH_ACCESS.map((type) => {
|
|
110
|
+
const on = access.includes(type);
|
|
111
|
+
return /* @__PURE__ */ jsx(
|
|
112
|
+
Button,
|
|
113
|
+
{
|
|
114
|
+
type: "button",
|
|
115
|
+
size: "sm",
|
|
116
|
+
variant: on ? "secondary" : "outline",
|
|
117
|
+
"aria-pressed": on,
|
|
118
|
+
disabled: on && access.length === 1,
|
|
119
|
+
title: on && access.length === 1 ? "At least one kind of access stays on" : void 0,
|
|
120
|
+
onClick: () => onAccess(toggleAccess(access, type)),
|
|
121
|
+
children: ACCESS_LABELS[type]
|
|
122
|
+
},
|
|
123
|
+
type
|
|
124
|
+
);
|
|
125
|
+
}) }),
|
|
126
|
+
/* @__PURE__ */ jsx(Switch, { checked: columns, label: "Columns", onChange: onColumns })
|
|
127
|
+
] });
|
|
128
|
+
}
|
|
129
|
+
function CallGraphToolbar(props) {
|
|
130
|
+
const { exclusions, pin, vocabulary } = props;
|
|
131
|
+
const excludedCount = (exclusions == null ? void 0 : exclusions.groups.filter((group) => group.excluded).length) ?? 0;
|
|
132
|
+
const hasExternal = (exclusions == null ? void 0 : exclusions.groups.some((group) => group.external)) ?? false;
|
|
133
|
+
const { noun, plural } = vocabulary.group;
|
|
134
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
135
|
+
/* @__PURE__ */ jsx(SegmentedControl, { value: props.direction, options: DIRECTIONS, onChange: props.onDirection, size: "sm", "aria-label": "Direction" }),
|
|
136
|
+
/* @__PURE__ */ jsx(DepthStepper, { depth: props.depth, maxDepth: props.maxDepth, onChange: props.onDepth }),
|
|
137
|
+
props.data && /* @__PURE__ */ jsx(DataAccessControls, { ...props.data }),
|
|
138
|
+
pin && /* @__PURE__ */ jsx(
|
|
139
|
+
Button,
|
|
140
|
+
{
|
|
141
|
+
type: "button",
|
|
142
|
+
variant: pin.pinned ? "secondary" : "outline",
|
|
143
|
+
size: "sm",
|
|
144
|
+
disabled: !pin.pinned && !pin.canPin,
|
|
145
|
+
"aria-pressed": pin.pinned,
|
|
146
|
+
title: pin.pinned ? "The graph keeps this root while the selection changes" : "Keep this root while the selection changes",
|
|
147
|
+
onClick: () => pin.onPin(!pin.pinned),
|
|
148
|
+
children: pin.pinned ? "Unpin root" : "Pin root"
|
|
149
|
+
}
|
|
150
|
+
),
|
|
151
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: props.onFit, children: "Fit" }),
|
|
152
|
+
/* @__PURE__ */ jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: props.onReset, children: [
|
|
153
|
+
/* @__PURE__ */ jsx(UiHome, {}),
|
|
154
|
+
"Reset"
|
|
155
|
+
] }),
|
|
156
|
+
exclusions && hasExternal && /* @__PURE__ */ jsx(
|
|
157
|
+
Switch,
|
|
158
|
+
{
|
|
159
|
+
checked: exclusions.exclude.includes(EXCLUDE_EXTERNAL),
|
|
160
|
+
disabled: exclusions.busy,
|
|
161
|
+
label: "Hide all external",
|
|
162
|
+
onChange: (hidden) => exclusions.onExclude(setExternalHidden(exclusions.exclude, hidden))
|
|
163
|
+
}
|
|
164
|
+
),
|
|
165
|
+
exclusions && /* @__PURE__ */ jsx(
|
|
166
|
+
DropdownMenu,
|
|
167
|
+
{
|
|
168
|
+
icon: UiFilter,
|
|
169
|
+
label: `${capitalize(plural)}${excludedCount ? ` (${excludedCount} excluded)` : ""}`,
|
|
170
|
+
variant: "outline",
|
|
171
|
+
size: "sm",
|
|
172
|
+
menuLabel: `${capitalize(noun)} exclusions`,
|
|
173
|
+
title: `Choose the ${plural} the graph leaves out`,
|
|
174
|
+
children: () => /* @__PURE__ */ jsx(GroupFacets, { ...exclusions })
|
|
175
|
+
}
|
|
176
|
+
),
|
|
177
|
+
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
|
|
178
|
+
props.omitted && /* @__PURE__ */ jsx(OmittedChip, { omitted: props.omitted, noun }),
|
|
179
|
+
props.end
|
|
180
|
+
] })
|
|
181
|
+
] });
|
|
182
|
+
}
|
|
183
|
+
export {
|
|
184
|
+
CallGraphToolbar
|
|
185
|
+
};
|
|
186
|
+
//# sourceMappingURL=CallGraphToolbar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallGraphToolbar.js","sources":["../../../src/data/call-graph/CallGraphToolbar.tsx"],"sourcesContent":["import { useState, type FormEvent, type ReactNode } from \"react\";\nimport { Button } from \"../../components/button\";\nimport { InputField } from \"../../components/InputField\";\nimport { SegmentedControl } from \"../../components/SegmentedControl\";\nimport { Switch } from \"../../components/Switch\";\nimport { UiFilter, UiHome, UiWarningTriangle } from \"../../icons\";\nimport { DropdownMenu } from \"../../overlay/DropdownMenu\";\nimport { Badge } from \"../Badge\";\nimport {\n addExcludePattern,\n EXCLUDE_EXTERNAL,\n excludeGroup,\n excludePatternError,\n includeGroup,\n removeExcludePattern,\n setExternalHidden,\n type ExcludeMatcher,\n} from \"./call-graph-exclude\";\nimport { capitalize, excludedTally, omittedParts } from \"./call-graph-labels\";\nimport { toggleAccess } from \"./call-graph-model\";\nimport type { CallGraphVocabulary } from \"./call-graph-vocabulary\";\nimport { CALL_GRAPH_ACCESS, type CallGraphAccess, type CallGraphDirection, type CallGraphGroupFact, type CallGraphOmitted } from \"./types\";\n\nconst DIRECTIONS: { id: CallGraphDirection; label: string }[] = [\n { id: \"callers\", label: \"Callers\" },\n { id: \"both\", label: \"Both\" },\n { id: \"callees\", label: \"Callees\" },\n];\n\nfunction DepthStepper({ depth, maxDepth, onChange }: { depth: number; maxDepth: number; onChange: (depth: number) => void }) {\n return (\n <div className=\"flex items-center gap-1\" role=\"group\" aria-label=\"Depth\">\n <span className=\"text-xs text-muted-foreground\">Depth</span>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"size-8 px-0\" aria-label=\"Decrease depth\" disabled={depth <= 1} onClick={() => onChange(depth - 1)}>−</Button>\n <output className=\"w-5 text-center text-sm font-medium tabular-nums\" aria-live=\"polite\" aria-label=\"Graph depth\">{depth}</output>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" className=\"size-8 px-0\" aria-label=\"Increase depth\" disabled={depth >= maxDepth} onClick={() => onChange(depth + 1)}>+</Button>\n </div>\n );\n}\n\nfunction OmittedChip({ omitted, noun }: { omitted: CallGraphOmitted; noun: string }) {\n const parts = omittedParts(omitted);\n if (parts.length === 0) return null;\n const tally = excludedTally(omitted).map(({ group, count }) => `${group}: ${count}`);\n const title = [`Not drawn: ${parts.join(\", \")}`, ...(tally.length ? [`Excluded per ${noun}:`, ...tally] : [])].join(\"\\n\");\n return (\n <span title={title} data-testid=\"graph-omitted\">\n <Badge tone=\"warning\" size=\"md\" icon={UiWarningTriangle} clickToCopy={false}>{parts.join(\" · \")}</Badge>\n </span>\n );\n}\n\nexport interface ExclusionsProps {\n /** The patterns in force. */\n exclude: string[];\n groups: CallGraphGroupFact[];\n matches: ExcludeMatcher;\n onExclude: (patterns: string[]) => void;\n onDefaults: () => void;\n /** A graph for the last edit is loading: the facts describe the one before it, so editing waits. */\n busy: boolean;\n vocabulary: CallGraphVocabulary;\n}\n\nfunction GroupRow({ group, onToggle }: { group: CallGraphGroupFact; onToggle: () => void }) {\n const name = group.label ?? group.name;\n return (\n <li className=\"flex items-center gap-2 py-1\">\n <Switch checked={!group.excluded} onChange={onToggle} aria-label={`Show ${name}`} />\n <span className=\"min-w-0 flex-1 truncate font-mono text-xs\" title={group.name}>{name}</span>\n {group.external && <Badge variant=\"outline\" size=\"sm\" clickToCopy={false}>external</Badge>}\n <span className=\"w-8 shrink-0 text-right text-xs tabular-nums text-muted-foreground\" title={`${group.nodes} nodes`}>{group.nodes}</span>\n </li>\n );\n}\n\n/** The group facets: one switch per group the walk reached, the patterns in force, and free-text patterns. */\nfunction GroupFacets({ exclude, groups, matches, onExclude, onDefaults, busy, vocabulary }: ExclusionsProps) {\n const [filter, setFilter] = useState(\"\");\n const [pattern, setPattern] = useState(\"\");\n const [error, setError] = useState<string>();\n const { plural, patternHint } = vocabulary.group;\n const needle = filter.trim().toLowerCase();\n const shown = groups.filter((group) => `${group.name} ${group.label ?? \"\"}`.toLowerCase().includes(needle));\n const submit = (event: FormEvent) => {\n event.preventDefault();\n const typed = pattern.trim();\n const problem = excludePatternError(exclude, typed);\n setError(problem);\n if (problem) return;\n setPattern(\"\");\n onExclude(addExcludePattern(exclude, typed));\n };\n // The filter box comes first: the menu focuses its first control on opening, which must not be one that drops an exclusion.\n return (\n <fieldset disabled={busy} aria-busy={busy} className=\"flex w-96 min-w-0 max-w-[90vw] flex-col gap-2 p-2 text-sm\">\n <InputField aria-label={`Filter ${plural}`} placeholder={`Filter ${plural}`} value={filter} onChange={setFilter} />\n <div className=\"flex flex-wrap items-center gap-1\" aria-label=\"Exclusion patterns\">\n <span className=\"text-xs text-muted-foreground\">Excluding</span>\n {exclude.length === 0 && <span className=\"text-xs text-muted-foreground\">nothing</span>}\n {exclude.map((entry) => (\n <button key={entry} type=\"button\" className=\"rounded border border-border px-1.5 font-mono text-xs hover:bg-muted\"\n aria-label={`Stop excluding ${entry}`} title={`Stop excluding ${entry}`} onClick={() => onExclude(removeExcludePattern(exclude, entry))}>\n {entry} ×\n </button>\n ))}\n </div>\n <ul className=\"max-h-72 overflow-y-auto pr-1\" aria-label={plural}>\n {shown.map((group) => (\n <GroupRow key={group.name} group={group}\n onToggle={() => onExclude(group.excluded ? includeGroup(exclude, group, groups, matches) : excludeGroup(exclude, group.name))} />\n ))}\n {shown.length === 0 && (\n <li className=\"py-1 text-xs text-muted-foreground\">{groups.length ? `No ${vocabulary.group.noun} matches the filter.` : `The graph reached no ${vocabulary.group.noun}.`}</li>\n )}\n </ul>\n <form className=\"flex items-start gap-2\" onSubmit={submit}>\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n <InputField aria-label=\"Exclude pattern\" placeholder={patternHint} value={pattern} onChange={setPattern} />\n {error && <span role=\"alert\" className=\"text-xs text-destructive\">{error}</span>}\n </div>\n <Button type=\"submit\" size=\"sm\" variant=\"outline\">Exclude</Button>\n </form>\n <div className=\"flex justify-between gap-2 border-t border-border pt-2\">\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" onClick={onDefaults}>Reset to defaults</Button>\n <Button type=\"button\" size=\"sm\" variant=\"ghost\" onClick={() => onExclude([])}>Show all</Button>\n </div>\n </fieldset>\n );\n}\n\nconst ACCESS_LABELS: Record<CallGraphAccess, string> = { call: \"Calls\", read: \"Reads\", write: \"Writes\" };\n\nexport interface DataAccessProps {\n access: CallGraphAccess[];\n onAccess: (access: CallGraphAccess[]) => void;\n columns: boolean;\n onColumns: (columns: boolean) => void;\n}\n\n/** Which edge types the graph follows, at least one, and whether columns and fields are nodes of their own. */\nfunction DataAccessControls({ access, onAccess, columns, onColumns }: DataAccessProps) {\n return (\n <>\n <div className=\"flex items-center gap-1\" role=\"group\" aria-label=\"Access\">\n {CALL_GRAPH_ACCESS.map((type) => {\n const on = access.includes(type);\n return (\n <Button key={type} type=\"button\" size=\"sm\" variant={on ? \"secondary\" : \"outline\"} aria-pressed={on} disabled={on && access.length === 1}\n title={on && access.length === 1 ? \"At least one kind of access stays on\" : undefined} onClick={() => onAccess(toggleAccess(access, type))}>\n {ACCESS_LABELS[type]}\n </Button>\n );\n })}\n </div>\n <Switch checked={columns} label=\"Columns\" onChange={onColumns} />\n </>\n );\n}\n\nexport interface CallGraphToolbarProps {\n /** Shown only when the host's graph has reads and writes. */\n data?: DataAccessProps | undefined;\n direction: CallGraphDirection;\n depth: number;\n maxDepth: number;\n /** Shown only when the host keeps a root across selection changes. */\n pin?: { pinned: boolean; canPin: boolean; onPin: (pinned: boolean) => void } | undefined;\n exclusions?: ExclusionsProps | undefined;\n omitted?: CallGraphOmitted | undefined;\n /** Host content at the toolbar's end, such as server timing. */\n end?: ReactNode;\n onDirection: (direction: CallGraphDirection) => void;\n onDepth: (depth: number) => void;\n onFit: () => void;\n onReset: () => void;\n vocabulary: CallGraphVocabulary;\n}\n\nexport function CallGraphToolbar(props: CallGraphToolbarProps) {\n const { exclusions, pin, vocabulary } = props;\n const excludedCount = exclusions?.groups.filter((group) => group.excluded).length ?? 0;\n const hasExternal = exclusions?.groups.some((group) => group.external) ?? false;\n const { noun, plural } = vocabulary.group;\n return (\n <div className=\"flex flex-wrap items-center gap-3\">\n <SegmentedControl value={props.direction} options={DIRECTIONS} onChange={props.onDirection} size=\"sm\" aria-label=\"Direction\" />\n <DepthStepper depth={props.depth} maxDepth={props.maxDepth} onChange={props.onDepth} />\n {props.data && <DataAccessControls {...props.data} />}\n {pin && (\n <Button type=\"button\" variant={pin.pinned ? \"secondary\" : \"outline\"} size=\"sm\" disabled={!pin.pinned && !pin.canPin} aria-pressed={pin.pinned}\n title={pin.pinned ? \"The graph keeps this root while the selection changes\" : \"Keep this root while the selection changes\"} onClick={() => pin.onPin(!pin.pinned)}>\n {pin.pinned ? \"Unpin root\" : \"Pin root\"}\n </Button>\n )}\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={props.onFit}>Fit</Button>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={props.onReset}><UiHome />Reset</Button>\n {exclusions && hasExternal && (\n <Switch checked={exclusions.exclude.includes(EXCLUDE_EXTERNAL)} disabled={exclusions.busy} label=\"Hide all external\"\n onChange={(hidden) => exclusions.onExclude(setExternalHidden(exclusions.exclude, hidden))} />\n )}\n {exclusions && (\n <DropdownMenu icon={UiFilter} label={`${capitalize(plural)}${excludedCount ? ` (${excludedCount} excluded)` : \"\"}`} variant=\"outline\" size=\"sm\"\n menuLabel={`${capitalize(noun)} exclusions`} title={`Choose the ${plural} the graph leaves out`}>\n {() => <GroupFacets {...exclusions} />}\n </DropdownMenu>\n )}\n <div className=\"ml-auto flex items-center gap-2\">\n {props.omitted && <OmittedChip omitted={props.omitted} noun={noun} />}\n {props.end}\n </div>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const EXCLUDE_EXTERNAL = "external";
|
|
4
|
+
const EXCLUDE_NONE = "none";
|
|
5
|
+
const matchesExclude = (pattern, group) => {
|
|
6
|
+
if (pattern === EXCLUDE_EXTERNAL) return group.external === true;
|
|
7
|
+
if (pattern.endsWith("/...")) {
|
|
8
|
+
const base = pattern.slice(0, -"/...".length);
|
|
9
|
+
return group.name === base || group.name.startsWith(`${base}/`);
|
|
10
|
+
}
|
|
11
|
+
return group.name === pattern;
|
|
12
|
+
};
|
|
13
|
+
function parseExclude(text) {
|
|
14
|
+
if (text === "") return void 0;
|
|
15
|
+
return text === EXCLUDE_NONE ? [] : text.split(",");
|
|
16
|
+
}
|
|
17
|
+
function formatExclude(patterns) {
|
|
18
|
+
if (patterns === void 0) return "";
|
|
19
|
+
return patterns.length === 0 ? EXCLUDE_NONE : patterns.join(",");
|
|
20
|
+
}
|
|
21
|
+
function excludeGroup(patterns, name) {
|
|
22
|
+
return [...patterns, name];
|
|
23
|
+
}
|
|
24
|
+
function includeGroup(patterns, target, groups, matches = matchesExclude) {
|
|
25
|
+
if (!target.excluded) throw new Error(`Group ${target.name} is not excluded`);
|
|
26
|
+
const covering = patterns.filter((pattern) => matches(pattern, target));
|
|
27
|
+
if (covering.length === 0) throw new Error(`Group ${target.name} is reported excluded, but none of ${patterns.join(", ")} matches it`);
|
|
28
|
+
const rest = patterns.filter((pattern) => !covering.includes(pattern));
|
|
29
|
+
const replacements = groups.filter(
|
|
30
|
+
(group) => group.name !== target.name && covering.some((pattern) => matches(pattern, group)) && !rest.some((pattern) => matches(pattern, group))
|
|
31
|
+
);
|
|
32
|
+
return [...rest, ...replacements.map((group) => group.name)];
|
|
33
|
+
}
|
|
34
|
+
function setExternalHidden(patterns, hidden) {
|
|
35
|
+
const others = patterns.filter((pattern) => pattern !== EXCLUDE_EXTERNAL);
|
|
36
|
+
return hidden ? [...others, EXCLUDE_EXTERNAL] : others;
|
|
37
|
+
}
|
|
38
|
+
function excludePatternError(patterns, pattern) {
|
|
39
|
+
if (pattern === "") return "Enter a name or a name ending in /...";
|
|
40
|
+
if (/[\s,]/.test(pattern)) return `One pattern at a time: ${pattern} has a comma or a space`;
|
|
41
|
+
if (pattern === EXCLUDE_NONE) return "Use Show all to exclude nothing";
|
|
42
|
+
if (patterns.includes(pattern)) return `${pattern} is already excluded`;
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
function addExcludePattern(patterns, pattern) {
|
|
46
|
+
return [...patterns, pattern];
|
|
47
|
+
}
|
|
48
|
+
function removeExcludePattern(patterns, pattern) {
|
|
49
|
+
return patterns.filter((candidate) => candidate !== pattern);
|
|
50
|
+
}
|
|
51
|
+
function callGraphGroupFacts(graph) {
|
|
52
|
+
const drawn = /* @__PURE__ */ new Map();
|
|
53
|
+
for (const node of graph.nodes) if (node.group !== void 0) drawn.set(node.group, (drawn.get(node.group) ?? 0) + 1);
|
|
54
|
+
const excluded = graph.omitted.excluded ?? {};
|
|
55
|
+
const names = [.../* @__PURE__ */ new Set([...drawn.keys(), ...Object.keys(excluded)])];
|
|
56
|
+
return names.map((name) => {
|
|
57
|
+
var _a, _b;
|
|
58
|
+
const label = (_b = (_a = graph.groups) == null ? void 0 : _a.find((group) => group.id === name)) == null ? void 0 : _b.label;
|
|
59
|
+
const shown = drawn.get(name) ?? 0;
|
|
60
|
+
return { name, ...label !== void 0 && label !== name ? { label } : {}, nodes: shown + (excluded[name] ?? 0), excluded: shown === 0 };
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
exports.EXCLUDE_EXTERNAL = EXCLUDE_EXTERNAL;
|
|
64
|
+
exports.EXCLUDE_NONE = EXCLUDE_NONE;
|
|
65
|
+
exports.addExcludePattern = addExcludePattern;
|
|
66
|
+
exports.callGraphGroupFacts = callGraphGroupFacts;
|
|
67
|
+
exports.excludeGroup = excludeGroup;
|
|
68
|
+
exports.excludePatternError = excludePatternError;
|
|
69
|
+
exports.formatExclude = formatExclude;
|
|
70
|
+
exports.includeGroup = includeGroup;
|
|
71
|
+
exports.matchesExclude = matchesExclude;
|
|
72
|
+
exports.parseExclude = parseExclude;
|
|
73
|
+
exports.removeExcludePattern = removeExcludePattern;
|
|
74
|
+
exports.setExternalHidden = setExternalHidden;
|
|
75
|
+
//# sourceMappingURL=call-graph-exclude.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-graph-exclude.cjs","sources":["../../../src/data/call-graph/call-graph-exclude.ts"],"sourcesContent":["// Editing the call graph's group exclusions. A pattern is a group name, a name ending in /... (that\n// group and every group below it), or `external` (every group outside the indexed scope). A host\n// whose source knows more keywords passes a matcher that understands them and falls back to this one.\n// No patterns excludes nothing; the host's defaults are asked for with `undefined`, never with [].\nimport type { CallGraph, CallGraphGroupFact } from \"./types\";\n\nexport const EXCLUDE_EXTERNAL = \"external\";\n/** The URL token for \"exclude nothing\", since an empty URL value stands for the host's defaults. */\nexport const EXCLUDE_NONE = \"none\";\n\n/** Whether one pattern excludes the group. */\nexport type ExcludeMatcher = (pattern: string, group: CallGraphGroupFact) => boolean;\n\nexport const matchesExclude: ExcludeMatcher = (pattern, group) => {\n if (pattern === EXCLUDE_EXTERNAL) return group.external === true;\n if (pattern.endsWith(\"/...\")) {\n const base = pattern.slice(0, -\"/...\".length);\n return group.name === base || group.name.startsWith(`${base}/`);\n }\n return group.name === pattern;\n};\n\n/** A URL value as patterns: empty is undefined, the host's defaults; `none` is no patterns. */\nexport function parseExclude(text: string): string[] | undefined {\n if (text === \"\") return undefined;\n return text === EXCLUDE_NONE ? [] : text.split(\",\");\n}\n\n/** The URL value for these patterns: undefined (the defaults) is empty, and no patterns is `none`. */\nexport function formatExclude(patterns: readonly string[] | undefined): string {\n if (patterns === undefined) return \"\";\n return patterns.length === 0 ? EXCLUDE_NONE : patterns.join(\",\");\n}\n\n/** Excludes one group by its exact name. */\nexport function excludeGroup(patterns: readonly string[], name: string): string[] {\n return [...patterns, name];\n}\n\n/**\n * Brings a group back. Every pattern that excludes it goes; a keyword or a /... pattern that also\n * covered other reached groups is replaced by their exact names, so they stay excluded.\n */\nexport function includeGroup(\n patterns: readonly string[],\n target: CallGraphGroupFact,\n groups: readonly CallGraphGroupFact[],\n matches: ExcludeMatcher = matchesExclude,\n): string[] {\n if (!target.excluded) throw new Error(`Group ${target.name} is not excluded`);\n const covering = patterns.filter((pattern) => matches(pattern, target));\n if (covering.length === 0) throw new Error(`Group ${target.name} is reported excluded, but none of ${patterns.join(\", \")} matches it`);\n const rest = patterns.filter((pattern) => !covering.includes(pattern));\n const replacements = groups.filter(\n (group) =>\n group.name !== target.name && covering.some((pattern) => matches(pattern, group)) && !rest.some((pattern) => matches(pattern, group)),\n );\n return [...rest, ...replacements.map((group) => group.name)];\n}\n\n/** Adds or removes the `external` keyword behind \"Hide all external\". */\nexport function setExternalHidden(patterns: readonly string[], hidden: boolean): string[] {\n const others = patterns.filter((pattern) => pattern !== EXCLUDE_EXTERNAL);\n return hidden ? [...others, EXCLUDE_EXTERNAL] : others;\n}\n\n/** Why a typed pattern cannot be added, or undefined when it can. The host checks the name itself. */\nexport function excludePatternError(patterns: readonly string[], pattern: string): string | undefined {\n if (pattern === \"\") return \"Enter a name or a name ending in /...\";\n if (/[\\s,]/.test(pattern)) return `One pattern at a time: ${pattern} has a comma or a space`;\n if (pattern === EXCLUDE_NONE) return \"Use Show all to exclude nothing\";\n if (patterns.includes(pattern)) return `${pattern} is already excluded`;\n return undefined;\n}\n\nexport function addExcludePattern(patterns: readonly string[], pattern: string): string[] {\n return [...patterns, pattern];\n}\n\nexport function removeExcludePattern(patterns: readonly string[], pattern: string): string[] {\n return patterns.filter((candidate) => candidate !== pattern);\n}\n\n/**\n * The groups a graph reached, for a host whose responses carry no group facts of their own: each\n * drawn group with its node count, and each group `omitted.excluded` tallies, which is excluded when\n * none of its nodes is drawn.\n */\nexport function callGraphGroupFacts(graph: CallGraph): CallGraphGroupFact[] {\n const drawn = new Map<string, number>();\n for (const node of graph.nodes) if (node.group !== undefined) drawn.set(node.group, (drawn.get(node.group) ?? 0) + 1);\n const excluded = graph.omitted.excluded ?? {};\n const names = [...new Set([...drawn.keys(), ...Object.keys(excluded)])];\n return names.map((name) => {\n const label = graph.groups?.find((group) => group.id === name)?.label;\n const shown = drawn.get(name) ?? 0;\n return { name, ...(label !== undefined && label !== name ? { label } : {}), nodes: shown + (excluded[name] ?? 0), excluded: shown === 0 };\n });\n}\n"],"names":[],"mappings":"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"}
|