@principal-ai/subsystems-react 0.17.0
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 +93 -0
- package/dist/components/ConfigurationSelector.d.ts +35 -0
- package/dist/components/ConfigurationSelector.d.ts.map +1 -0
- package/dist/components/ConfigurationSelector.js +63 -0
- package/dist/components/ConfigurationSelector.js.map +1 -0
- package/dist/components/GraphRenderer.d.ts +295 -0
- package/dist/components/GraphRenderer.d.ts.map +1 -0
- package/dist/components/GraphRenderer.js +2008 -0
- package/dist/components/GraphRenderer.js.map +1 -0
- package/dist/components/MultiCanvasRenderer.d.ts +75 -0
- package/dist/components/MultiCanvasRenderer.d.ts.map +1 -0
- package/dist/components/MultiCanvasRenderer.js +203 -0
- package/dist/components/MultiCanvasRenderer.js.map +1 -0
- package/dist/components/NodeTooltip.d.ts +24 -0
- package/dist/components/NodeTooltip.d.ts.map +1 -0
- package/dist/components/NodeTooltip.js +160 -0
- package/dist/components/NodeTooltip.js.map +1 -0
- package/dist/components/SelectionSidebar.d.ts +18 -0
- package/dist/components/SelectionSidebar.d.ts.map +1 -0
- package/dist/components/SelectionSidebar.js +190 -0
- package/dist/components/SelectionSidebar.js.map +1 -0
- package/dist/components/SequenceDiagramRenderer.d.ts +77 -0
- package/dist/components/SequenceDiagramRenderer.d.ts.map +1 -0
- package/dist/components/SequenceDiagramRenderer.js +604 -0
- package/dist/components/SequenceDiagramRenderer.js.map +1 -0
- package/dist/components/WorkflowSequenceDiagram.d.ts +63 -0
- package/dist/components/WorkflowSequenceDiagram.d.ts.map +1 -0
- package/dist/components/WorkflowSequenceDiagram.js +147 -0
- package/dist/components/WorkflowSequenceDiagram.js.map +1 -0
- package/dist/components/dashboard/DashboardRenderer.d.ts +10 -0
- package/dist/components/dashboard/DashboardRenderer.d.ts.map +1 -0
- package/dist/components/dashboard/DashboardRenderer.js +179 -0
- package/dist/components/dashboard/DashboardRenderer.js.map +1 -0
- package/dist/components/dashboard/MetricPanel.d.ts +10 -0
- package/dist/components/dashboard/MetricPanel.d.ts.map +1 -0
- package/dist/components/dashboard/MetricPanel.js +103 -0
- package/dist/components/dashboard/MetricPanel.js.map +1 -0
- package/dist/components/dashboard/MockDataProvider.d.ts +30 -0
- package/dist/components/dashboard/MockDataProvider.d.ts.map +1 -0
- package/dist/components/dashboard/MockDataProvider.js +270 -0
- package/dist/components/dashboard/MockDataProvider.js.map +1 -0
- package/dist/components/dashboard/components/BarChart.d.ts +10 -0
- package/dist/components/dashboard/components/BarChart.d.ts.map +1 -0
- package/dist/components/dashboard/components/BarChart.js +167 -0
- package/dist/components/dashboard/components/BarChart.js.map +1 -0
- package/dist/components/dashboard/components/LineChart.d.ts +10 -0
- package/dist/components/dashboard/components/LineChart.d.ts.map +1 -0
- package/dist/components/dashboard/components/LineChart.js +141 -0
- package/dist/components/dashboard/components/LineChart.js.map +1 -0
- package/dist/components/dashboard/components/MetricCard.d.ts +9 -0
- package/dist/components/dashboard/components/MetricCard.d.ts.map +1 -0
- package/dist/components/dashboard/components/MetricCard.js +163 -0
- package/dist/components/dashboard/components/MetricCard.js.map +1 -0
- package/dist/components/dashboard/components/SourceLink.d.ts +9 -0
- package/dist/components/dashboard/components/SourceLink.d.ts.map +1 -0
- package/dist/components/dashboard/components/SourceLink.js +39 -0
- package/dist/components/dashboard/components/SourceLink.js.map +1 -0
- package/dist/components/dashboard/components/TimeRangeSelector.d.ts +9 -0
- package/dist/components/dashboard/components/TimeRangeSelector.d.ts.map +1 -0
- package/dist/components/dashboard/components/TimeRangeSelector.js +167 -0
- package/dist/components/dashboard/components/TimeRangeSelector.js.map +1 -0
- package/dist/components/dashboard/components/index.d.ts +6 -0
- package/dist/components/dashboard/components/index.d.ts.map +1 -0
- package/dist/components/dashboard/components/index.js +6 -0
- package/dist/components/dashboard/components/index.js.map +1 -0
- package/dist/components/dashboard/index.d.ts +6 -0
- package/dist/components/dashboard/index.d.ts.map +1 -0
- package/dist/components/dashboard/index.js +8 -0
- package/dist/components/dashboard/index.js.map +1 -0
- package/dist/components/dashboard/types.d.ts +74 -0
- package/dist/components/dashboard/types.d.ts.map +1 -0
- package/dist/components/dashboard/types.js +8 -0
- package/dist/components/dashboard/types.js.map +1 -0
- package/dist/components/session-events/SessionEventFeed.d.ts +34 -0
- package/dist/components/session-events/SessionEventFeed.d.ts.map +1 -0
- package/dist/components/session-events/SessionEventFeed.js +1196 -0
- package/dist/components/session-events/SessionEventFeed.js.map +1 -0
- package/dist/components/session-events/index.d.ts +7 -0
- package/dist/components/session-events/index.d.ts.map +1 -0
- package/dist/components/session-events/index.js +6 -0
- package/dist/components/session-events/index.js.map +1 -0
- package/dist/components/state-view/PipelineView.d.ts +14 -0
- package/dist/components/state-view/PipelineView.d.ts.map +1 -0
- package/dist/components/state-view/PipelineView.js +195 -0
- package/dist/components/state-view/PipelineView.js.map +1 -0
- package/dist/components/state-view/index.d.ts +14 -0
- package/dist/components/state-view/index.d.ts.map +1 -0
- package/dist/components/state-view/index.js +12 -0
- package/dist/components/state-view/index.js.map +1 -0
- package/dist/components/state-view/types.d.ts +188 -0
- package/dist/components/state-view/types.d.ts.map +1 -0
- package/dist/components/state-view/types.js +10 -0
- package/dist/components/state-view/types.js.map +1 -0
- package/dist/components/state-view/useStateView.d.ts +32 -0
- package/dist/components/state-view/useStateView.d.ts.map +1 -0
- package/dist/components/state-view/useStateView.js +129 -0
- package/dist/components/state-view/useStateView.js.map +1 -0
- package/dist/contexts/GraphEditContext.d.ts +20 -0
- package/dist/contexts/GraphEditContext.d.ts.map +1 -0
- package/dist/contexts/GraphEditContext.js +8 -0
- package/dist/contexts/GraphEditContext.js.map +1 -0
- package/dist/contexts/TooltipPortalContext.d.ts +8 -0
- package/dist/contexts/TooltipPortalContext.d.ts.map +1 -0
- package/dist/contexts/TooltipPortalContext.js +8 -0
- package/dist/contexts/TooltipPortalContext.js.map +1 -0
- package/dist/edges/CustomEdge.d.ts +24 -0
- package/dist/edges/CustomEdge.d.ts.map +1 -0
- package/dist/edges/CustomEdge.js +222 -0
- package/dist/edges/CustomEdge.js.map +1 -0
- package/dist/edges/GenericEdge.d.ts +18 -0
- package/dist/edges/GenericEdge.d.ts.map +1 -0
- package/dist/edges/GenericEdge.js +10 -0
- package/dist/edges/GenericEdge.js.map +1 -0
- package/dist/graphify/anchor.d.ts +28 -0
- package/dist/graphify/anchor.d.ts.map +1 -0
- package/dist/graphify/anchor.js +132 -0
- package/dist/graphify/anchor.js.map +1 -0
- package/dist/graphify/consolidated.d.ts +210 -0
- package/dist/graphify/consolidated.d.ts.map +1 -0
- package/dist/graphify/consolidated.js +11 -0
- package/dist/graphify/consolidated.js.map +1 -0
- package/dist/graphify/ids.d.ts +19 -0
- package/dist/graphify/ids.d.ts.map +1 -0
- package/dist/graphify/ids.js +46 -0
- package/dist/graphify/ids.js.map +1 -0
- package/dist/graphify/index.d.ts +18 -0
- package/dist/graphify/index.d.ts.map +1 -0
- package/dist/graphify/index.js +12 -0
- package/dist/graphify/index.js.map +1 -0
- package/dist/graphify/kind.d.ts +23 -0
- package/dist/graphify/kind.d.ts.map +1 -0
- package/dist/graphify/kind.js +77 -0
- package/dist/graphify/kind.js.map +1 -0
- package/dist/graphify/resolve.d.ts +48 -0
- package/dist/graphify/resolve.d.ts.map +1 -0
- package/dist/graphify/resolve.js +83 -0
- package/dist/graphify/resolve.js.map +1 -0
- package/dist/graphify/signature.d.ts +87 -0
- package/dist/graphify/signature.d.ts.map +1 -0
- package/dist/graphify/signature.js +276 -0
- package/dist/graphify/signature.js.map +1 -0
- package/dist/graphify/types.d.ts +141 -0
- package/dist/graphify/types.d.ts.map +1 -0
- package/dist/graphify/types.js +8 -0
- package/dist/graphify/types.js.map +1 -0
- package/dist/hooks/useElkLayout.d.ts +66 -0
- package/dist/hooks/useElkLayout.d.ts.map +1 -0
- package/dist/hooks/useElkLayout.js +136 -0
- package/dist/hooks/useElkLayout.js.map +1 -0
- package/dist/hooks/usePathBasedEvents.d.ts +42 -0
- package/dist/hooks/usePathBasedEvents.d.ts.map +1 -0
- package/dist/hooks/usePathBasedEvents.js +119 -0
- package/dist/hooks/usePathBasedEvents.js.map +1 -0
- package/dist/hooks/useSequenceLayout.d.ts +186 -0
- package/dist/hooks/useSequenceLayout.d.ts.map +1 -0
- package/dist/hooks/useSequenceLayout.js +327 -0
- package/dist/hooks/useSequenceLayout.js.map +1 -0
- package/dist/hooks/useUndoRedo.d.ts +80 -0
- package/dist/hooks/useUndoRedo.d.ts.map +1 -0
- package/dist/hooks/useUndoRedo.js +70 -0
- package/dist/hooks/useUndoRedo.js.map +1 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/nodes/CustomNode.d.ts +28 -0
- package/dist/nodes/CustomNode.d.ts.map +1 -0
- package/dist/nodes/CustomNode.js +820 -0
- package/dist/nodes/CustomNode.js.map +1 -0
- package/dist/nodes/GenericNode.d.ts +20 -0
- package/dist/nodes/GenericNode.d.ts.map +1 -0
- package/dist/nodes/GenericNode.js +20 -0
- package/dist/nodes/GenericNode.js.map +1 -0
- package/dist/nodes/otel/OtelBoundaryNode.d.ts +55 -0
- package/dist/nodes/otel/OtelBoundaryNode.d.ts.map +1 -0
- package/dist/nodes/otel/OtelBoundaryNode.js +81 -0
- package/dist/nodes/otel/OtelBoundaryNode.js.map +1 -0
- package/dist/nodes/otel/OtelEventNode.d.ts +59 -0
- package/dist/nodes/otel/OtelEventNode.d.ts.map +1 -0
- package/dist/nodes/otel/OtelEventNode.js +82 -0
- package/dist/nodes/otel/OtelEventNode.js.map +1 -0
- package/dist/nodes/otel/OtelResourceNode.d.ts +53 -0
- package/dist/nodes/otel/OtelResourceNode.d.ts.map +1 -0
- package/dist/nodes/otel/OtelResourceNode.js +105 -0
- package/dist/nodes/otel/OtelResourceNode.js.map +1 -0
- package/dist/nodes/otel/OtelScopeNode.d.ts +53 -0
- package/dist/nodes/otel/OtelScopeNode.d.ts.map +1 -0
- package/dist/nodes/otel/OtelScopeNode.js +81 -0
- package/dist/nodes/otel/OtelScopeNode.js.map +1 -0
- package/dist/nodes/otel/OtelSpanConventionNode.d.ts +61 -0
- package/dist/nodes/otel/OtelSpanConventionNode.d.ts.map +1 -0
- package/dist/nodes/otel/OtelSpanConventionNode.js +131 -0
- package/dist/nodes/otel/OtelSpanConventionNode.js.map +1 -0
- package/dist/nodes/otel/index.d.ts +17 -0
- package/dist/nodes/otel/index.d.ts.map +1 -0
- package/dist/nodes/otel/index.js +13 -0
- package/dist/nodes/otel/index.js.map +1 -0
- package/dist/nodes/otel/shared/NodeBadges.d.ts +10 -0
- package/dist/nodes/otel/shared/NodeBadges.d.ts.map +1 -0
- package/dist/nodes/otel/shared/NodeBadges.js +178 -0
- package/dist/nodes/otel/shared/NodeBadges.js.map +1 -0
- package/dist/nodes/otel/shared/NodeContent.d.ts +10 -0
- package/dist/nodes/otel/shared/NodeContent.d.ts.map +1 -0
- package/dist/nodes/otel/shared/NodeContent.js +96 -0
- package/dist/nodes/otel/shared/NodeContent.js.map +1 -0
- package/dist/nodes/otel/shared/index.d.ts +8 -0
- package/dist/nodes/otel/shared/index.d.ts.map +1 -0
- package/dist/nodes/otel/shared/index.js +8 -0
- package/dist/nodes/otel/shared/index.js.map +1 -0
- package/dist/nodes/otel/shared/types.d.ts +129 -0
- package/dist/nodes/otel/shared/types.d.ts.map +1 -0
- package/dist/nodes/otel/shared/types.js +5 -0
- package/dist/nodes/otel/shared/types.js.map +1 -0
- package/dist/nodes/otel/shared/useNodeBehavior.d.ts +42 -0
- package/dist/nodes/otel/shared/useNodeBehavior.d.ts.map +1 -0
- package/dist/nodes/otel/shared/useNodeBehavior.js +61 -0
- package/dist/nodes/otel/shared/useNodeBehavior.js.map +1 -0
- package/dist/pierre/PierreFileView.d.ts +17 -0
- package/dist/pierre/PierreFileView.d.ts.map +1 -0
- package/dist/pierre/PierreFileView.js +46 -0
- package/dist/pierre/PierreFileView.js.map +1 -0
- package/dist/pierre/PierreSnippetView.d.ts +28 -0
- package/dist/pierre/PierreSnippetView.d.ts.map +1 -0
- package/dist/pierre/PierreSnippetView.js +105 -0
- package/dist/pierre/PierreSnippetView.js.map +1 -0
- package/dist/pierre/PierreThroughlineCodeView.d.ts +22 -0
- package/dist/pierre/PierreThroughlineCodeView.d.ts.map +1 -0
- package/dist/pierre/PierreThroughlineCodeView.js +206 -0
- package/dist/pierre/PierreThroughlineCodeView.js.map +1 -0
- package/dist/pierre/constructColors.d.ts +24 -0
- package/dist/pierre/constructColors.d.ts.map +1 -0
- package/dist/pierre/constructColors.js +91 -0
- package/dist/pierre/constructColors.js.map +1 -0
- package/dist/pierre/index.d.ts +12 -0
- package/dist/pierre/index.d.ts.map +1 -0
- package/dist/pierre/index.js +7 -0
- package/dist/pierre/index.js.map +1 -0
- package/dist/pierre/pierreBackground.d.ts +15 -0
- package/dist/pierre/pierreBackground.d.ts.map +1 -0
- package/dist/pierre/pierreBackground.js +31 -0
- package/dist/pierre/pierreBackground.js.map +1 -0
- package/dist/pierre/pierreFileLang.d.ts +27 -0
- package/dist/pierre/pierreFileLang.d.ts.map +1 -0
- package/dist/pierre/pierreFileLang.js +52 -0
- package/dist/pierre/pierreFileLang.js.map +1 -0
- package/dist/pierre/pierreSyntaxTheme.d.ts +11 -0
- package/dist/pierre/pierreSyntaxTheme.d.ts.map +1 -0
- package/dist/pierre/pierreSyntaxTheme.js +20 -0
- package/dist/pierre/pierreSyntaxTheme.js.map +1 -0
- package/dist/pierre/scrollAnchor.d.ts +5 -0
- package/dist/pierre/scrollAnchor.d.ts.map +1 -0
- package/dist/pierre/scrollAnchor.js +9 -0
- package/dist/pierre/scrollAnchor.js.map +1 -0
- package/dist/pierre/sliceSnippet.d.ts +10 -0
- package/dist/pierre/sliceSnippet.d.ts.map +1 -0
- package/dist/pierre/sliceSnippet.js +16 -0
- package/dist/pierre/sliceSnippet.js.map +1 -0
- package/dist/pierre/syntaxTokens.d.ts +11 -0
- package/dist/pierre/syntaxTokens.d.ts.map +1 -0
- package/dist/pierre/syntaxTokens.js +51 -0
- package/dist/pierre/syntaxTokens.js.map +1 -0
- package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts +8 -0
- package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts.map +1 -0
- package/dist/stories/Subsystem/ComponentGraph/fixtures.js +116 -0
- package/dist/stories/Subsystem/ComponentGraph/fixtures.js.map +1 -0
- package/dist/subsystem/ComponentDeclaration.d.ts +87 -0
- package/dist/subsystem/ComponentDeclaration.d.ts.map +1 -0
- package/dist/subsystem/ComponentDeclaration.js +374 -0
- package/dist/subsystem/ComponentDeclaration.js.map +1 -0
- package/dist/subsystem/FileDrawer.d.ts +17 -0
- package/dist/subsystem/FileDrawer.d.ts.map +1 -0
- package/dist/subsystem/FileDrawer.js +72 -0
- package/dist/subsystem/FileDrawer.js.map +1 -0
- package/dist/subsystem/GraphLayoutCover.d.ts +20 -0
- package/dist/subsystem/GraphLayoutCover.d.ts.map +1 -0
- package/dist/subsystem/GraphLayoutCover.js +42 -0
- package/dist/subsystem/GraphLayoutCover.js.map +1 -0
- package/dist/subsystem/SubsystemComponentGraph.d.ts +96 -0
- package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -0
- package/dist/subsystem/SubsystemComponentGraph.js +1059 -0
- package/dist/subsystem/SubsystemComponentGraph.js.map +1 -0
- package/dist/subsystem/SubsystemFileTree.d.ts +24 -0
- package/dist/subsystem/SubsystemFileTree.d.ts.map +1 -0
- package/dist/subsystem/SubsystemFileTree.js +150 -0
- package/dist/subsystem/SubsystemFileTree.js.map +1 -0
- package/dist/subsystem/declarationRef.d.ts +39 -0
- package/dist/subsystem/declarationRef.d.ts.map +1 -0
- package/dist/subsystem/declarationRef.js +32 -0
- package/dist/subsystem/declarationRef.js.map +1 -0
- package/dist/subsystem/formatDeclaration.d.ts +11 -0
- package/dist/subsystem/formatDeclaration.d.ts.map +1 -0
- package/dist/subsystem/formatDeclaration.js +146 -0
- package/dist/subsystem/formatDeclaration.js.map +1 -0
- package/dist/subsystem/model.d.ts +353 -0
- package/dist/subsystem/model.d.ts.map +1 -0
- package/dist/subsystem/model.js +503 -0
- package/dist/subsystem/model.js.map +1 -0
- package/dist/subsystem/nodes.d.ts +69 -0
- package/dist/subsystem/nodes.d.ts.map +1 -0
- package/dist/subsystem/nodes.js +289 -0
- package/dist/subsystem/nodes.js.map +1 -0
- package/dist/subsystem/paths.d.ts +63 -0
- package/dist/subsystem/paths.d.ts.map +1 -0
- package/dist/subsystem/paths.js +86 -0
- package/dist/subsystem/paths.js.map +1 -0
- package/dist/subsystem/tokenizeComponent.d.ts +20 -0
- package/dist/subsystem/tokenizeComponent.d.ts.map +1 -0
- package/dist/subsystem/tokenizeComponent.js +56 -0
- package/dist/subsystem/tokenizeComponent.js.map +1 -0
- package/dist/subsystem/tokenizeFormatted.d.ts +12 -0
- package/dist/subsystem/tokenizeFormatted.d.ts.map +1 -0
- package/dist/subsystem/tokenizeFormatted.js +13 -0
- package/dist/subsystem/tokenizeFormatted.js.map +1 -0
- package/dist/utils/animationMapping.d.ts +53 -0
- package/dist/utils/animationMapping.d.ts.map +1 -0
- package/dist/utils/animationMapping.js +126 -0
- package/dist/utils/animationMapping.js.map +1 -0
- package/dist/utils/canvasBounds.d.ts +50 -0
- package/dist/utils/canvasBounds.d.ts.map +1 -0
- package/dist/utils/canvasBounds.js +88 -0
- package/dist/utils/canvasBounds.js.map +1 -0
- package/dist/utils/elkLayout.d.ts +137 -0
- package/dist/utils/elkLayout.d.ts.map +1 -0
- package/dist/utils/elkLayout.js +596 -0
- package/dist/utils/elkLayout.js.map +1 -0
- package/dist/utils/graphConverter.d.ts +18 -0
- package/dist/utils/graphConverter.d.ts.map +1 -0
- package/dist/utils/graphConverter.js +114 -0
- package/dist/utils/graphConverter.js.map +1 -0
- package/dist/utils/iconResolver.d.ts +29 -0
- package/dist/utils/iconResolver.d.ts.map +1 -0
- package/dist/utils/iconResolver.js +30 -0
- package/dist/utils/iconResolver.js.map +1 -0
- package/dist/utils/orientationUtils.d.ts +19 -0
- package/dist/utils/orientationUtils.d.ts.map +1 -0
- package/dist/utils/orientationUtils.js +62 -0
- package/dist/utils/orientationUtils.js.map +1 -0
- package/package.json +80 -0
- package/src/components/ConfigurationSelector.tsx +133 -0
- package/src/components/GraphRenderer.tsx +3195 -0
- package/src/components/MultiCanvasRenderer.tsx +295 -0
- package/src/components/NodeTooltip.tsx +279 -0
- package/src/components/PendingChanges.test.tsx +375 -0
- package/src/components/SelectionSidebar.tsx +352 -0
- package/src/components/SequenceDiagramRenderer.tsx +1156 -0
- package/src/components/WorkflowSequenceDiagram.tsx +270 -0
- package/src/components/dashboard/DashboardRenderer.tsx +317 -0
- package/src/components/dashboard/MetricPanel.tsx +254 -0
- package/src/components/dashboard/MockDataProvider.ts +330 -0
- package/src/components/dashboard/components/BarChart.tsx +299 -0
- package/src/components/dashboard/components/LineChart.tsx +279 -0
- package/src/components/dashboard/components/MetricCard.tsx +270 -0
- package/src/components/dashboard/components/SourceLink.tsx +63 -0
- package/src/components/dashboard/components/TimeRangeSelector.tsx +280 -0
- package/src/components/dashboard/components/index.ts +5 -0
- package/src/components/dashboard/index.ts +47 -0
- package/src/components/dashboard/types.ts +126 -0
- package/src/components/session-events/SessionEventFeed.tsx +1797 -0
- package/src/components/session-events/index.ts +13 -0
- package/src/components/state-view/PipelineView.tsx +347 -0
- package/src/components/state-view/index.ts +14 -0
- package/src/components/state-view/types.ts +261 -0
- package/src/components/state-view/useStateView.ts +205 -0
- package/src/contexts/GraphEditContext.tsx +27 -0
- package/src/contexts/TooltipPortalContext.ts +8 -0
- package/src/edges/CustomEdge.tsx +402 -0
- package/src/edges/GenericEdge.tsx +36 -0
- package/src/graphify/anchor.test.ts +124 -0
- package/src/graphify/anchor.ts +160 -0
- package/src/graphify/consolidated.ts +246 -0
- package/src/graphify/ids.ts +48 -0
- package/src/graphify/index.ts +72 -0
- package/src/graphify/kind.test.ts +108 -0
- package/src/graphify/kind.ts +120 -0
- package/src/graphify/resolve.test.ts +89 -0
- package/src/graphify/resolve.ts +115 -0
- package/src/graphify/signature.test.ts +278 -0
- package/src/graphify/signature.ts +354 -0
- package/src/graphify/types.ts +164 -0
- package/src/hooks/useElkLayout.test.ts +134 -0
- package/src/hooks/useElkLayout.ts +191 -0
- package/src/hooks/usePathBasedEvents.ts +192 -0
- package/src/hooks/useSequenceLayout.ts +543 -0
- package/src/hooks/useUndoRedo.ts +144 -0
- package/src/index.ts +341 -0
- package/src/nodes/CustomNode.tsx +1231 -0
- package/src/nodes/GenericNode.tsx +55 -0
- package/src/nodes/otel/OtelBoundaryNode.tsx +224 -0
- package/src/nodes/otel/OtelEventNode.tsx +225 -0
- package/src/nodes/otel/OtelResourceNode.tsx +251 -0
- package/src/nodes/otel/OtelScopeNode.tsx +221 -0
- package/src/nodes/otel/OtelSpanConventionNode.tsx +295 -0
- package/src/nodes/otel/index.ts +23 -0
- package/src/nodes/otel/shared/NodeBadges.tsx +295 -0
- package/src/nodes/otel/shared/NodeContent.tsx +204 -0
- package/src/nodes/otel/shared/index.ts +8 -0
- package/src/nodes/otel/shared/types.ts +138 -0
- package/src/nodes/otel/shared/useNodeBehavior.ts +114 -0
- package/src/pierre/PierreFileView.tsx +81 -0
- package/src/pierre/PierreSnippetView.tsx +184 -0
- package/src/pierre/PierreThroughlineCodeView.tsx +304 -0
- package/src/pierre/constructColors.test.ts +52 -0
- package/src/pierre/constructColors.ts +112 -0
- package/src/pierre/index.ts +18 -0
- package/src/pierre/pierreBackground.ts +33 -0
- package/src/pierre/pierreFileLang.test.ts +26 -0
- package/src/pierre/pierreFileLang.ts +55 -0
- package/src/pierre/pierreSyntaxTheme.ts +23 -0
- package/src/pierre/scrollAnchor.test.ts +13 -0
- package/src/pierre/scrollAnchor.ts +11 -0
- package/src/pierre/sliceSnippet.test.ts +21 -0
- package/src/pierre/sliceSnippet.ts +31 -0
- package/src/pierre/syntaxTokens.test.ts +35 -0
- package/src/pierre/syntaxTokens.ts +60 -0
- package/src/stories/Audit/BoundaryNodes.stories.tsx +385 -0
- package/src/stories/Audit/CanvasEdgeTypes.stories.tsx +1448 -0
- package/src/stories/Audit/CanvasNodeTypes.stories.tsx +1049 -0
- package/src/stories/Audit/ColorPriority.stories.tsx +895 -0
- package/src/stories/Audit/DiamondBadges.stories.tsx +629 -0
- package/src/stories/Audit/NodeDimensionsTesting.stories.tsx +724 -0
- package/src/stories/Audit/NodeFieldsAudit.stories.tsx +996 -0
- package/src/stories/Audit/NodeFontSizeTesting.stories.tsx +715 -0
- package/src/stories/Audit/NodeShapes.stories.tsx +1208 -0
- package/src/stories/Audit/WideNodesTesting.stories.tsx +1045 -0
- package/src/stories/Components/DashboardRenderer.stories.tsx +263 -0
- package/src/stories/Components/GraphRenderer.stories.tsx +3236 -0
- package/src/stories/Components/MultiCanvasRenderer.stories.tsx +370 -0
- package/src/stories/Components/SequenceDiagram.stories.tsx +255 -0
- package/src/stories/Components/StateView.stories.tsx +417 -0
- package/src/stories/Components/TraceViewer.stories.tsx +442 -0
- package/src/stories/Components/WorkflowSequenceDiagram.stories.tsx +802 -0
- package/src/stories/Features/AnimationWorkshop.stories.tsx +727 -0
- package/src/stories/Features/ChangeTypeVisual.stories.tsx +67 -0
- package/src/stories/Features/EventDrivenAnimations.stories.tsx +513 -0
- package/src/stories/Features/MultiConfig.stories.tsx +539 -0
- package/src/stories/Introduction.mdx +34 -0
- package/src/stories/Layout/ElkEdgeRouting.stories.tsx +539 -0
- package/src/stories/Layout/GraphOrientation.stories.tsx +500 -0
- package/src/stories/Layout/MultiDirectionalConnections.stories.tsx +352 -0
- package/src/stories/Nodes/NodeDefinitionComparison.stories.tsx +560 -0
- package/src/stories/Nodes/NodeNameFallbacks.stories.tsx +491 -0
- package/src/stories/Nodes/NumericColors.stories.tsx +440 -0
- package/src/stories/OTEL/EventNameDisplay.stories.tsx +694 -0
- package/src/stories/OTEL/EventNameFallback.stories.tsx +578 -0
- package/src/stories/OTEL/OtelComponents.stories.tsx +422 -0
- package/src/stories/OTEL/OtelNodeTypesPrototype.stories.tsx +806 -0
- package/src/stories/OTEL/RawEventCards.stories.tsx +57 -0
- package/src/stories/OTEL/SpanBadges.stories.tsx +840 -0
- package/src/stories/OTEL/ValidationEventsCanvas.stories.tsx +209 -0
- package/src/stories/Pierre/CodeView.stories.tsx +219 -0
- package/src/stories/RealWorld/BacklogMdCanvases.stories.tsx +721 -0
- package/src/stories/RealWorld/FileCitySequence.stories.tsx +516 -0
- package/src/stories/RealWorld/RealCanvasFiles.stories.tsx +336 -0
- package/src/stories/Subsystem/ComponentDeclarationAudit.stories.tsx +321 -0
- package/src/stories/Subsystem/ComponentGraph/Appearance.stories.tsx +365 -0
- package/src/stories/Subsystem/ComponentGraph/Basics.stories.tsx +137 -0
- package/src/stories/Subsystem/ComponentGraph/Captures.stories.tsx +238 -0
- package/src/stories/Subsystem/ComponentGraph/DetailPanel.stories.tsx +315 -0
- package/src/stories/Subsystem/ComponentGraph/Flows.stories.tsx +239 -0
- package/src/stories/Subsystem/ComponentGraph/FrameworkStereotype.stories.tsx +216 -0
- package/src/stories/Subsystem/ComponentGraph/GraphTitle.stories.tsx +70 -0
- package/src/stories/Subsystem/ComponentGraph/Processes.stories.tsx +68 -0
- package/src/stories/Subsystem/ComponentGraph/Scenarios.stories.tsx +959 -0
- package/src/stories/Subsystem/ComponentGraph/Spotlights.stories.tsx +681 -0
- package/src/stories/Subsystem/ComponentGraph/fixtures.ts +129 -0
- package/src/stories/__traces__/test-run.canvas.json +241 -0
- package/src/stories/data/activity-feed-analytics.dashboard.json +300 -0
- package/src/stories/data/file-city-images-transformed.otel.canvas.json +295 -0
- package/src/stories/data/file-city-workflows.json +269 -0
- package/src/stories/data/graph-converter-test-execution.json +443 -0
- package/src/stories/data/graph-converter-test.workflow.json +105 -0
- package/src/stories/data/graph-converter-validated-execution.json +58 -0
- package/src/stories/data/opencode-session-raw-events.json +273396 -0
- package/src/subsystem/ComponentDeclaration.tsx +643 -0
- package/src/subsystem/FileDrawer.tsx +106 -0
- package/src/subsystem/GraphLayoutCover.tsx +69 -0
- package/src/subsystem/SubsystemComponentGraph.tsx +1644 -0
- package/src/subsystem/SubsystemFileTree.tsx +190 -0
- package/src/subsystem/declarationRef.test.ts +33 -0
- package/src/subsystem/declarationRef.ts +63 -0
- package/src/subsystem/formatDeclaration.ts +174 -0
- package/src/subsystem/model.test.ts +244 -0
- package/src/subsystem/model.ts +850 -0
- package/src/subsystem/nodes.test.ts +56 -0
- package/src/subsystem/nodes.tsx +443 -0
- package/src/subsystem/paths.test.ts +123 -0
- package/src/subsystem/paths.ts +127 -0
- package/src/subsystem/tokenizeComponent.ts +70 -0
- package/src/subsystem/tokenizeFormatted.ts +19 -0
- package/src/utils/animationMapping.ts +166 -0
- package/src/utils/canvasBounds.ts +146 -0
- package/src/utils/elkLayout.test.ts +240 -0
- package/src/utils/elkLayout.ts +779 -0
- package/src/utils/graphConverter.ts +148 -0
- package/src/utils/iconResolver.tsx +53 -0
- package/src/utils/orientationUtils.ts +73 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graphify graph.json schema types.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the graphify data model (graphify/validate.py, graphify/export.py)
|
|
5
|
+
* so graphify output can be consumed by this library in a type-compatible way.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** Any JSON-serializable value carried in node/edge metadata. */
|
|
9
|
+
export type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue };
|
|
10
|
+
|
|
11
|
+
/** Node classification (graphify/validate.py VALID_FILE_TYPES). */
|
|
12
|
+
export type GraphifyFileType = 'code' | 'document' | 'paper' | 'image' | 'rationale' | 'concept';
|
|
13
|
+
|
|
14
|
+
/** Edge provenance tag (graphify/validate.py VALID_CONFIDENCES). */
|
|
15
|
+
export type GraphifyConfidence = 'EXTRACTED' | 'INFERRED' | 'AMBIGUOUS';
|
|
16
|
+
|
|
17
|
+
/** Optional semantic kind carried on nodes (e.g. `module`, `namespace`). */
|
|
18
|
+
export type GraphifyNodeType = 'module' | 'namespace' | string;
|
|
19
|
+
|
|
20
|
+
/** Canonical relation verbs emitted by graphify extractors and resolvers. */
|
|
21
|
+
export type GraphifyRelation =
|
|
22
|
+
| 'calls'
|
|
23
|
+
| 'imports'
|
|
24
|
+
| 'imports_from'
|
|
25
|
+
| 're_exports'
|
|
26
|
+
| 'references'
|
|
27
|
+
| 'inherits'
|
|
28
|
+
| 'implements'
|
|
29
|
+
| 'mixes_in'
|
|
30
|
+
| 'uses'
|
|
31
|
+
| 'contains'
|
|
32
|
+
| 'defines'
|
|
33
|
+
| 'method'
|
|
34
|
+
| 'decorator'
|
|
35
|
+
| 'rationale_for'
|
|
36
|
+
| 'semantically_similar_to'
|
|
37
|
+
| string;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A graphify node.
|
|
41
|
+
*
|
|
42
|
+
* Required fields are enforced by graphify/validate.py:
|
|
43
|
+
* `id`, `label`, `file_type`, `source_file`. The rest are populated by the
|
|
44
|
+
* extractors (`source_location`, optional `type`/`metadata`) and by the build
|
|
45
|
+
* writer (`community`, `community_name`, `norm_label`).
|
|
46
|
+
*/
|
|
47
|
+
export interface GraphifyNode {
|
|
48
|
+
/** Stable identifier: repo-relative path + symbol names (make_id slug). */
|
|
49
|
+
id: string;
|
|
50
|
+
/** Human-readable name. */
|
|
51
|
+
label: string;
|
|
52
|
+
/** Classification used as the primary node kind. */
|
|
53
|
+
file_type: GraphifyFileType;
|
|
54
|
+
/** Repo-relative path of the source file this node came from. */
|
|
55
|
+
source_file: string;
|
|
56
|
+
/** `L<line>` location, or `''` for sourceless stub nodes. */
|
|
57
|
+
source_location?: string | null;
|
|
58
|
+
/** Optional semantic kind (e.g. `module`, `namespace`). */
|
|
59
|
+
type?: GraphifyNodeType;
|
|
60
|
+
/** Node state / extra node definitions. */
|
|
61
|
+
state?: string;
|
|
62
|
+
/** Arbitrary per-extractor metadata (e.g. `{ kind: "csharp_namespace" }`). */
|
|
63
|
+
metadata?: Record<string, JsonValue>;
|
|
64
|
+
/** Leiden community id, stamped at build time. */
|
|
65
|
+
community?: number | null;
|
|
66
|
+
/** Human-readable community label, stamped at build time. */
|
|
67
|
+
community_name?: string;
|
|
68
|
+
/** Diacritic-stripped lowercased label, stamped at build time. */
|
|
69
|
+
norm_label?: string;
|
|
70
|
+
/** Extra fields tolerated for forward compatibility. */
|
|
71
|
+
[key: string]: unknown;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* A graphify edge.
|
|
76
|
+
*
|
|
77
|
+
* Required fields: `source`, `target`, `relation`, `confidence`, `source_file`.
|
|
78
|
+
* `context` is populated for `references` edges (e.g. `type`, `return_type`,
|
|
79
|
+
* `field`, `generic_arg`).
|
|
80
|
+
*/
|
|
81
|
+
export interface GraphifyEdge {
|
|
82
|
+
/** Source node id. */
|
|
83
|
+
source: string;
|
|
84
|
+
/** Target node id. */
|
|
85
|
+
target: string;
|
|
86
|
+
/** Canonical relation verb. */
|
|
87
|
+
relation: GraphifyRelation;
|
|
88
|
+
/** Provenance: read directly from source vs. resolved by graphify. */
|
|
89
|
+
confidence: GraphifyConfidence;
|
|
90
|
+
/** Float 0.0-1.0; 1.0 for EXTRACTED, discrete rubric for INFERRED. */
|
|
91
|
+
confidence_score?: number;
|
|
92
|
+
/** Repo-relative path where the relationship was found. */
|
|
93
|
+
source_file: string;
|
|
94
|
+
/** `L<line>` location of the relationship. */
|
|
95
|
+
source_location?: string | null;
|
|
96
|
+
/** Edge weight. */
|
|
97
|
+
weight?: number;
|
|
98
|
+
/** Reference context for `references` edges. */
|
|
99
|
+
context?: string;
|
|
100
|
+
/** Arbitrary per-extractor metadata. */
|
|
101
|
+
metadata?: Record<string, JsonValue>;
|
|
102
|
+
/** Extra fields tolerated for forward compatibility. */
|
|
103
|
+
[key: string]: unknown;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* A graphify hyperedge — a group relationship connecting 3+ nodes.
|
|
108
|
+
*
|
|
109
|
+
* Member list is canonical on `nodes` (aliases `members`/`node_ids` are folded
|
|
110
|
+
* by graphify/export.py build normalization).
|
|
111
|
+
*/
|
|
112
|
+
export interface GraphifyHyperedge {
|
|
113
|
+
/** Stable identifier. */
|
|
114
|
+
id: string;
|
|
115
|
+
/** Human-readable label. */
|
|
116
|
+
label?: string;
|
|
117
|
+
/** Member node ids (canonical key). */
|
|
118
|
+
nodes: string[];
|
|
119
|
+
/** Group relation verb (e.g. `participate_in`, `implement`, `form`). */
|
|
120
|
+
relation?: GraphifyRelation;
|
|
121
|
+
/** Provenance tag. */
|
|
122
|
+
confidence?: GraphifyConfidence;
|
|
123
|
+
/** Float 0.0-1.0. */
|
|
124
|
+
confidence_score?: number;
|
|
125
|
+
/** Repo-relative path where the relationship was found. */
|
|
126
|
+
source_file?: string;
|
|
127
|
+
/** Extra fields tolerated for forward compatibility. */
|
|
128
|
+
[key: string]: unknown;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Graph-level metadata stored on the graph (`graph` key). */
|
|
132
|
+
export interface GraphifyGraphMetadata {
|
|
133
|
+
directed?: boolean;
|
|
134
|
+
multigraph?: boolean;
|
|
135
|
+
/** Edges may be serialized under `links` (NetworkX node-link) or `edges`. */
|
|
136
|
+
hyperedges?: GraphifyHyperedge[];
|
|
137
|
+
[key: string]: unknown;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* The full graph.json document.
|
|
142
|
+
*
|
|
143
|
+
* graphify writes NetworkX node-link format: nodes under `nodes`, edges under
|
|
144
|
+
* `links`. Older/legacy payloads may use `edges` instead of `links`.
|
|
145
|
+
*/
|
|
146
|
+
export interface GraphifyGraph {
|
|
147
|
+
/** Graph nodes. */
|
|
148
|
+
nodes: GraphifyNode[];
|
|
149
|
+
/** Graph edges (NetworkX node-link key). */
|
|
150
|
+
links?: GraphifyEdge[];
|
|
151
|
+
/** Legacy alias for `links`. */
|
|
152
|
+
edges?: GraphifyEdge[];
|
|
153
|
+
/** Group relationships connecting 3+ nodes. */
|
|
154
|
+
hyperedges?: GraphifyHyperedge[];
|
|
155
|
+
/** Graph-level metadata (directed, multigraph, hyperedges). */
|
|
156
|
+
graph?: GraphifyGraphMetadata;
|
|
157
|
+
/** Top-level directed flag (NetworkX). */
|
|
158
|
+
directed?: boolean;
|
|
159
|
+
/** Top-level multigraph flag (NetworkX). */
|
|
160
|
+
multigraph?: boolean;
|
|
161
|
+
/** Git HEAD the graph was built against, when available. */
|
|
162
|
+
built_at_commit?: string;
|
|
163
|
+
[key: string]: unknown;
|
|
164
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for useElkLayout hook utilities
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, test, expect } from 'bun:test';
|
|
6
|
+
import type { Edge } from '@xyflow/react';
|
|
7
|
+
import { applyElkPathsToEdges } from './useElkLayout';
|
|
8
|
+
|
|
9
|
+
describe('useElkLayout utilities', () => {
|
|
10
|
+
describe('applyElkPathsToEdges', () => {
|
|
11
|
+
const createEdge = (id: string, source: string, target: string): Edge => ({
|
|
12
|
+
id,
|
|
13
|
+
source,
|
|
14
|
+
target,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('should return original edges when edgePaths is empty', () => {
|
|
18
|
+
const edges = [createEdge('e1', 'a', 'b')];
|
|
19
|
+
const edgePaths = new Map<string, string>();
|
|
20
|
+
const edgeLabelPositions = new Map<string, { x: number; y: number }>();
|
|
21
|
+
|
|
22
|
+
const result = applyElkPathsToEdges(edges, edgePaths, edgeLabelPositions);
|
|
23
|
+
|
|
24
|
+
expect(result).toEqual(edges);
|
|
25
|
+
expect(result[0].data?.elkPath).toBeUndefined();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('should inject elkPath into edge data', () => {
|
|
29
|
+
const edges = [createEdge('e1', 'a', 'b')];
|
|
30
|
+
const edgePaths = new Map([['e1', 'M 0 0 L 100 100']]);
|
|
31
|
+
const edgeLabelPositions = new Map<string, { x: number; y: number }>();
|
|
32
|
+
|
|
33
|
+
const result = applyElkPathsToEdges(edges, edgePaths, edgeLabelPositions);
|
|
34
|
+
|
|
35
|
+
expect(result[0].data?.elkPath).toBe('M 0 0 L 100 100');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('should inject elkLabelPosition into edge data', () => {
|
|
39
|
+
const edges = [createEdge('e1', 'a', 'b')];
|
|
40
|
+
const edgePaths = new Map([['e1', 'M 0 0 L 100 100']]);
|
|
41
|
+
const edgeLabelPositions = new Map([['e1', { x: 50, y: 50 }]]);
|
|
42
|
+
|
|
43
|
+
const result = applyElkPathsToEdges(edges, edgePaths, edgeLabelPositions);
|
|
44
|
+
|
|
45
|
+
expect(result[0].data?.elkLabelPosition).toEqual({ x: 50, y: 50 });
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('should preserve existing edge data', () => {
|
|
49
|
+
const edges: Edge[] = [
|
|
50
|
+
{
|
|
51
|
+
id: 'e1',
|
|
52
|
+
source: 'a',
|
|
53
|
+
target: 'b',
|
|
54
|
+
data: { customField: 'value', edgeType: 'flow' },
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
const edgePaths = new Map([['e1', 'M 0 0 L 100 100']]);
|
|
58
|
+
const edgeLabelPositions = new Map<string, { x: number; y: number }>();
|
|
59
|
+
|
|
60
|
+
const result = applyElkPathsToEdges(edges, edgePaths, edgeLabelPositions);
|
|
61
|
+
|
|
62
|
+
expect(result[0].data?.customField).toBe('value');
|
|
63
|
+
expect(result[0].data?.edgeType).toBe('flow');
|
|
64
|
+
expect(result[0].data?.elkPath).toBe('M 0 0 L 100 100');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('should only modify edges that have corresponding paths', () => {
|
|
68
|
+
const edges = [
|
|
69
|
+
createEdge('e1', 'a', 'b'),
|
|
70
|
+
createEdge('e2', 'b', 'c'),
|
|
71
|
+
createEdge('e3', 'c', 'd'),
|
|
72
|
+
];
|
|
73
|
+
const edgePaths = new Map([
|
|
74
|
+
['e1', 'M 0 0 L 100 0'],
|
|
75
|
+
['e3', 'M 200 0 L 300 0'],
|
|
76
|
+
// e2 has no path
|
|
77
|
+
]);
|
|
78
|
+
const edgeLabelPositions = new Map<string, { x: number; y: number }>();
|
|
79
|
+
|
|
80
|
+
const result = applyElkPathsToEdges(edges, edgePaths, edgeLabelPositions);
|
|
81
|
+
|
|
82
|
+
expect(result[0].data?.elkPath).toBe('M 0 0 L 100 0');
|
|
83
|
+
expect(result[1].data?.elkPath).toBeUndefined();
|
|
84
|
+
expect(result[2].data?.elkPath).toBe('M 200 0 L 300 0');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('should handle edges with undefined data', () => {
|
|
88
|
+
const edges: Edge[] = [
|
|
89
|
+
{ id: 'e1', source: 'a', target: 'b', data: undefined },
|
|
90
|
+
];
|
|
91
|
+
const edgePaths = new Map([['e1', 'M 0 0 L 100 100']]);
|
|
92
|
+
const edgeLabelPositions = new Map([['e1', { x: 50, y: 50 }]]);
|
|
93
|
+
|
|
94
|
+
const result = applyElkPathsToEdges(edges, edgePaths, edgeLabelPositions);
|
|
95
|
+
|
|
96
|
+
expect(result[0].data?.elkPath).toBe('M 0 0 L 100 100');
|
|
97
|
+
expect(result[0].data?.elkLabelPosition).toEqual({ x: 50, y: 50 });
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('should return new array without mutating original', () => {
|
|
101
|
+
const edges = [createEdge('e1', 'a', 'b')];
|
|
102
|
+
const edgePaths = new Map([['e1', 'M 0 0 L 100 100']]);
|
|
103
|
+
const edgeLabelPositions = new Map<string, { x: number; y: number }>();
|
|
104
|
+
|
|
105
|
+
const result = applyElkPathsToEdges(edges, edgePaths, edgeLabelPositions);
|
|
106
|
+
|
|
107
|
+
// Result should be a new array
|
|
108
|
+
expect(result).not.toBe(edges);
|
|
109
|
+
// Original edge should not be modified
|
|
110
|
+
expect(edges[0].data).toBeUndefined();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test('should handle complex path strings', () => {
|
|
114
|
+
const edges = [createEdge('e1', 'a', 'b')];
|
|
115
|
+
const complexPath = 'M 120 30 L 142 30 Q 150 30 150 38 L 150 72 Q 150 80 158 80 L 250 80';
|
|
116
|
+
const edgePaths = new Map([['e1', complexPath]]);
|
|
117
|
+
const edgeLabelPositions = new Map<string, { x: number; y: number }>();
|
|
118
|
+
|
|
119
|
+
const result = applyElkPathsToEdges(edges, edgePaths, edgeLabelPositions);
|
|
120
|
+
|
|
121
|
+
expect(result[0].data?.elkPath).toBe(complexPath);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('should handle empty edges array', () => {
|
|
125
|
+
const edges: Edge[] = [];
|
|
126
|
+
const edgePaths = new Map([['e1', 'M 0 0 L 100 100']]);
|
|
127
|
+
const edgeLabelPositions = new Map<string, { x: number; y: number }>();
|
|
128
|
+
|
|
129
|
+
const result = applyElkPathsToEdges(edges, edgePaths, edgeLabelPositions);
|
|
130
|
+
|
|
131
|
+
expect(result).toEqual([]);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
});
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React hook for ELK layout integration
|
|
3
|
+
*
|
|
4
|
+
* Provides automatic edge routing with circuit-board style paths.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
|
|
8
|
+
import type { Node, Edge } from '@xyflow/react';
|
|
9
|
+
import { computeElkLayout, type ElkLayoutOptions } from '../utils/elkLayout';
|
|
10
|
+
|
|
11
|
+
export interface UseElkLayoutOptions extends ElkLayoutOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Whether ELK layout is enabled
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
16
|
+
enabled?: boolean;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Debounce delay in ms before recomputing layout
|
|
20
|
+
* @default 100
|
|
21
|
+
*/
|
|
22
|
+
debounceMs?: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface UseElkLayoutResult {
|
|
26
|
+
/** Edge paths computed by ELK, keyed by edge ID */
|
|
27
|
+
edgePaths: Map<string, string>;
|
|
28
|
+
/** Edge label positions computed by ELK, keyed by edge ID */
|
|
29
|
+
edgeLabelPositions: Map<string, { x: number; y: number }>;
|
|
30
|
+
/** Whether layout is currently being computed */
|
|
31
|
+
isLayouting: boolean;
|
|
32
|
+
/** Any error that occurred during layout */
|
|
33
|
+
error: Error | null;
|
|
34
|
+
/** Manually trigger a layout recomputation */
|
|
35
|
+
recomputeLayout: () => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Hook for computing ELK layout for edges
|
|
40
|
+
*
|
|
41
|
+
* @param nodes - xyflow nodes
|
|
42
|
+
* @param edges - xyflow edges
|
|
43
|
+
* @param options - Layout options
|
|
44
|
+
* @returns Layout result with edge paths
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```tsx
|
|
48
|
+
* const { edgePaths, isLayouting } = useElkLayout(nodes, edges, {
|
|
49
|
+
* routingStyle: 'orthogonal',
|
|
50
|
+
* edgeSpacing: 15,
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export function useElkLayout(
|
|
55
|
+
nodes: Node[],
|
|
56
|
+
edges: Edge[],
|
|
57
|
+
options: UseElkLayoutOptions = {}
|
|
58
|
+
): UseElkLayoutResult {
|
|
59
|
+
const { enabled = true, debounceMs = 100, ...layoutOptions } = options;
|
|
60
|
+
|
|
61
|
+
const [edgePaths, setEdgePaths] = useState<Map<string, string>>(new Map());
|
|
62
|
+
const [edgeLabelPositions, setEdgeLabelPositions] = useState<Map<string, { x: number; y: number }>>(
|
|
63
|
+
new Map()
|
|
64
|
+
);
|
|
65
|
+
const [isLayouting, setIsLayouting] = useState(false);
|
|
66
|
+
const [error, setError] = useState<Error | null>(null);
|
|
67
|
+
|
|
68
|
+
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
69
|
+
const abortRef = useRef<boolean>(false);
|
|
70
|
+
const hasComputedRef = useRef<string | null>(null);
|
|
71
|
+
|
|
72
|
+
// Create stable refs for nodes and edges
|
|
73
|
+
const nodesRef = useRef(nodes);
|
|
74
|
+
nodesRef.current = nodes;
|
|
75
|
+
const edgesRef = useRef(edges);
|
|
76
|
+
edgesRef.current = edges;
|
|
77
|
+
|
|
78
|
+
// Create a stable reference to layout options
|
|
79
|
+
const optionsRef = useRef(layoutOptions);
|
|
80
|
+
optionsRef.current = layoutOptions;
|
|
81
|
+
|
|
82
|
+
// Create a stable key based on node/edge structure
|
|
83
|
+
const layoutKey = useMemo(() => {
|
|
84
|
+
const nodeKey = nodes.map(n => `${n.id}:${n.position.x}:${n.position.y}:${n.width ?? 0}:${n.height ?? 0}`).join('|');
|
|
85
|
+
const edgeKey = edges.map(e => `${e.id}:${e.source}:${e.target}`).join('|');
|
|
86
|
+
return `${enabled}:${nodeKey}:${edgeKey}`;
|
|
87
|
+
}, [enabled, nodes, edges]);
|
|
88
|
+
|
|
89
|
+
// Compute layout when key changes
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
// Skip if already computed for this key
|
|
92
|
+
if (hasComputedRef.current === layoutKey) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (!enabled || nodesRef.current.length === 0) {
|
|
97
|
+
setEdgePaths(new Map());
|
|
98
|
+
setEdgeLabelPositions(new Map());
|
|
99
|
+
hasComputedRef.current = layoutKey;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (timeoutRef.current) {
|
|
104
|
+
clearTimeout(timeoutRef.current);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
abortRef.current = false;
|
|
108
|
+
|
|
109
|
+
timeoutRef.current = setTimeout(async () => {
|
|
110
|
+
setIsLayouting(true);
|
|
111
|
+
setError(null);
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
const result = await computeElkLayout(nodesRef.current, edgesRef.current, optionsRef.current);
|
|
115
|
+
|
|
116
|
+
if (abortRef.current) return;
|
|
117
|
+
|
|
118
|
+
setEdgePaths(result.edgePaths);
|
|
119
|
+
setEdgeLabelPositions(result.edgeLabelPositions);
|
|
120
|
+
hasComputedRef.current = layoutKey;
|
|
121
|
+
} catch (err) {
|
|
122
|
+
if (!abortRef.current) {
|
|
123
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
124
|
+
console.error('ELK layout error:', err);
|
|
125
|
+
}
|
|
126
|
+
} finally {
|
|
127
|
+
if (!abortRef.current) {
|
|
128
|
+
setIsLayouting(false);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}, debounceMs);
|
|
132
|
+
|
|
133
|
+
return () => {
|
|
134
|
+
if (timeoutRef.current) {
|
|
135
|
+
clearTimeout(timeoutRef.current);
|
|
136
|
+
}
|
|
137
|
+
abortRef.current = true;
|
|
138
|
+
};
|
|
139
|
+
}, [layoutKey, enabled, debounceMs]);
|
|
140
|
+
|
|
141
|
+
const recomputeLayout = useCallback(() => {
|
|
142
|
+
hasComputedRef.current = null; // Force recompute
|
|
143
|
+
if (timeoutRef.current) {
|
|
144
|
+
clearTimeout(timeoutRef.current);
|
|
145
|
+
}
|
|
146
|
+
// Trigger effect by invalidating the key check
|
|
147
|
+
setIsLayouting(true);
|
|
148
|
+
}, []);
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
edgePaths,
|
|
152
|
+
edgeLabelPositions,
|
|
153
|
+
isLayouting,
|
|
154
|
+
error,
|
|
155
|
+
recomputeLayout,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Apply ELK-computed paths to edges
|
|
161
|
+
*
|
|
162
|
+
* This utility injects the ELK path data into edge data so CustomEdge can use it.
|
|
163
|
+
*
|
|
164
|
+
* @param edges - Original edges
|
|
165
|
+
* @param edgePaths - ELK-computed paths
|
|
166
|
+
* @param edgeLabelPositions - ELK-computed label positions
|
|
167
|
+
* @returns Edges with ELK path data injected
|
|
168
|
+
*/
|
|
169
|
+
export function applyElkPathsToEdges<T extends Edge>(
|
|
170
|
+
edges: T[],
|
|
171
|
+
edgePaths: Map<string, string>,
|
|
172
|
+
edgeLabelPositions: Map<string, { x: number; y: number }>
|
|
173
|
+
): T[] {
|
|
174
|
+
return edges.map((edge) => {
|
|
175
|
+
const elkPath = edgePaths.get(edge.id);
|
|
176
|
+
const elkLabelPosition = edgeLabelPositions.get(edge.id);
|
|
177
|
+
|
|
178
|
+
if (elkPath) {
|
|
179
|
+
return {
|
|
180
|
+
...edge,
|
|
181
|
+
data: {
|
|
182
|
+
...edge.data,
|
|
183
|
+
elkPath,
|
|
184
|
+
elkLabelPosition,
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return edge;
|
|
190
|
+
});
|
|
191
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for processing path-based events and mapping them to animations
|
|
3
|
+
*
|
|
4
|
+
* Handles ComponentActivityEvent and ComponentActionEvent from
|
|
5
|
+
* PathBasedEventProcessor (Milestone 1 & 2)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { useEffect, useCallback } from 'react';
|
|
9
|
+
import type {
|
|
10
|
+
ComponentActivityEvent,
|
|
11
|
+
ComponentActionEvent,
|
|
12
|
+
EdgeAnimationEvent,
|
|
13
|
+
PathBasedEvent,
|
|
14
|
+
} from '@principal-ai/subsystems-core';
|
|
15
|
+
import {
|
|
16
|
+
logLevelToNodeAnimation,
|
|
17
|
+
actionToNodeAnimation,
|
|
18
|
+
actionToEdgeAnimation,
|
|
19
|
+
type NodeAnimation,
|
|
20
|
+
type EdgeAnimation,
|
|
21
|
+
} from '../utils/animationMapping';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Animation update callbacks
|
|
25
|
+
*/
|
|
26
|
+
export interface AnimationCallbacks {
|
|
27
|
+
onNodeAnimation: (nodeId: string, animation: NodeAnimation & { timestamp: number }) => void;
|
|
28
|
+
onEdgeAnimation: (edgeId: string, animation: EdgeAnimation & { timestamp: number }) => void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Hook options
|
|
33
|
+
*/
|
|
34
|
+
export interface UsePathBasedEventsOptions {
|
|
35
|
+
/** Path-based events to process */
|
|
36
|
+
events: PathBasedEvent[];
|
|
37
|
+
|
|
38
|
+
/** Callbacks for triggering animations */
|
|
39
|
+
callbacks: AnimationCallbacks;
|
|
40
|
+
|
|
41
|
+
/** Optional callback when event is processed */
|
|
42
|
+
onEventProcessed?: (event: PathBasedEvent) => void;
|
|
43
|
+
|
|
44
|
+
/** Minimum log level to trigger animations (default: 'info') */
|
|
45
|
+
minLogLevel?: 'debug' | 'info' | 'warn' | 'error';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Process path-based events and trigger appropriate animations
|
|
50
|
+
*/
|
|
51
|
+
export function usePathBasedEvents({
|
|
52
|
+
events,
|
|
53
|
+
callbacks,
|
|
54
|
+
onEventProcessed,
|
|
55
|
+
minLogLevel = 'info',
|
|
56
|
+
}: UsePathBasedEventsOptions): void {
|
|
57
|
+
const { onNodeAnimation, onEdgeAnimation } = callbacks;
|
|
58
|
+
|
|
59
|
+
// Process component activity events (Milestone 1)
|
|
60
|
+
const processActivityEvent = useCallback(
|
|
61
|
+
(event: ComponentActivityEvent) => {
|
|
62
|
+
// Map log level to animation
|
|
63
|
+
const animation = logLevelToNodeAnimation(event.level);
|
|
64
|
+
|
|
65
|
+
// Trigger node animation
|
|
66
|
+
onNodeAnimation(event.componentId, {
|
|
67
|
+
...animation,
|
|
68
|
+
timestamp: event.timestamp,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
onEventProcessed?.(event);
|
|
72
|
+
},
|
|
73
|
+
[onNodeAnimation, onEventProcessed]
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
// Process component action events (Milestone 2)
|
|
77
|
+
const processActionEvent = useCallback(
|
|
78
|
+
(event: ComponentActionEvent) => {
|
|
79
|
+
// Map action/state to animation
|
|
80
|
+
const animation = actionToNodeAnimation(event.action, event.state);
|
|
81
|
+
|
|
82
|
+
// Trigger node animation
|
|
83
|
+
onNodeAnimation(event.componentId, {
|
|
84
|
+
...animation,
|
|
85
|
+
timestamp: event.timestamp,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
onEventProcessed?.(event);
|
|
89
|
+
},
|
|
90
|
+
[onNodeAnimation, onEventProcessed]
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
// Process edge animation events (Milestone 2)
|
|
94
|
+
const processEdgeAnimationEvent = useCallback(
|
|
95
|
+
(event: EdgeAnimationEvent) => {
|
|
96
|
+
const animation = actionToEdgeAnimation(event.triggeredBy?.action || 'unknown', {
|
|
97
|
+
type: event.animation,
|
|
98
|
+
duration: event.duration,
|
|
99
|
+
direction: event.direction,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
onEdgeAnimation(event.edgeId, {
|
|
103
|
+
...animation,
|
|
104
|
+
timestamp: event.timestamp,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
onEventProcessed?.(event);
|
|
108
|
+
},
|
|
109
|
+
[onEdgeAnimation, onEventProcessed]
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
// Process events when they change
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
if (events.length === 0) return;
|
|
115
|
+
|
|
116
|
+
// Process the latest event
|
|
117
|
+
const latestEvent = events[events.length - 1];
|
|
118
|
+
|
|
119
|
+
switch (latestEvent.type) {
|
|
120
|
+
case 'component-activity': {
|
|
121
|
+
// Milestone 1: Component activity from log
|
|
122
|
+
// Check if log level is high enough to trigger animation
|
|
123
|
+
const levels = ['debug', 'info', 'warn', 'error'];
|
|
124
|
+
if (levels.indexOf(latestEvent.level) >= levels.indexOf(minLogLevel)) {
|
|
125
|
+
processActivityEvent(latestEvent);
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
case 'component-action':
|
|
131
|
+
// Milestone 2: Specific action from pattern match
|
|
132
|
+
processActionEvent(latestEvent);
|
|
133
|
+
break;
|
|
134
|
+
|
|
135
|
+
case 'edge-animation':
|
|
136
|
+
// Milestone 2: Edge activation from action trigger
|
|
137
|
+
processEdgeAnimationEvent(latestEvent);
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}, [events, processActivityEvent, processActionEvent, processEdgeAnimationEvent, minLogLevel]);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Process a batch of path-based events
|
|
145
|
+
* Useful for processing historical logs or bulk updates
|
|
146
|
+
*/
|
|
147
|
+
export function processBatchEvents(
|
|
148
|
+
events: PathBasedEvent[],
|
|
149
|
+
callbacks: AnimationCallbacks,
|
|
150
|
+
minLogLevel: 'debug' | 'info' | 'warn' | 'error' = 'info'
|
|
151
|
+
): void {
|
|
152
|
+
const levels = ['debug', 'info', 'warn', 'error'];
|
|
153
|
+
const minLevelIndex = levels.indexOf(minLogLevel);
|
|
154
|
+
|
|
155
|
+
for (const event of events) {
|
|
156
|
+
switch (event.type) {
|
|
157
|
+
case 'component-activity':
|
|
158
|
+
if (levels.indexOf(event.level) >= minLevelIndex) {
|
|
159
|
+
const animation = logLevelToNodeAnimation(event.level);
|
|
160
|
+
callbacks.onNodeAnimation(event.componentId, {
|
|
161
|
+
...animation,
|
|
162
|
+
timestamp: event.timestamp,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
break;
|
|
166
|
+
|
|
167
|
+
case 'component-action':
|
|
168
|
+
{
|
|
169
|
+
const animation = actionToNodeAnimation(event.action, event.state);
|
|
170
|
+
callbacks.onNodeAnimation(event.componentId, {
|
|
171
|
+
...animation,
|
|
172
|
+
timestamp: event.timestamp,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
break;
|
|
176
|
+
|
|
177
|
+
case 'edge-animation':
|
|
178
|
+
{
|
|
179
|
+
const animation = actionToEdgeAnimation(event.triggeredBy?.action || 'unknown', {
|
|
180
|
+
type: event.animation,
|
|
181
|
+
duration: event.duration,
|
|
182
|
+
direction: event.direction,
|
|
183
|
+
});
|
|
184
|
+
callbacks.onEdgeAnimation(event.edgeId, {
|
|
185
|
+
...animation,
|
|
186
|
+
timestamp: event.timestamp,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|