@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,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PierreSnippetView — focused line-range code view via `@pierre/diffs`.
|
|
3
|
+
*
|
|
4
|
+
* Ported from `@industry-theme/file-city-panel` so subsystem graphs and
|
|
5
|
+
* Storybook can scroll to a declaration line without that panel package.
|
|
6
|
+
*
|
|
7
|
+
* `File.selectedLines` highlights the focus line but does not scroll; we call
|
|
8
|
+
* `scrollIntoView` on the rendered line after Pierre paints.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
12
|
+
import { File } from '@pierre/diffs/react';
|
|
13
|
+
import { useTheme } from '@principal-ade/industry-theme';
|
|
14
|
+
import { buildPierreOptions, PIERRE_FILE_STYLE } from './pierreBackground';
|
|
15
|
+
import { pierreLangForPath } from './pierreFileLang';
|
|
16
|
+
import { sliceSnippetWindow } from './sliceSnippet';
|
|
17
|
+
|
|
18
|
+
import { scrollAnchorLine } from './scrollAnchor';
|
|
19
|
+
|
|
20
|
+
function scrollFocusLineIntoView(
|
|
21
|
+
fileContainer: HTMLElement,
|
|
22
|
+
focusOffset: number,
|
|
23
|
+
): void {
|
|
24
|
+
const root = fileContainer.shadowRoot ?? fileContainer;
|
|
25
|
+
const anchorLine = scrollAnchorLine(focusOffset);
|
|
26
|
+
const lineEl = root.querySelector(
|
|
27
|
+
`[data-line="${anchorLine}"]`,
|
|
28
|
+
) as HTMLElement | null;
|
|
29
|
+
lineEl?.scrollIntoView({ block: 'start', behavior: 'auto' });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface PierreSnippetViewProps {
|
|
33
|
+
filePath: string;
|
|
34
|
+
fileName: string;
|
|
35
|
+
/** First line of the snippet (1-based, inclusive). */
|
|
36
|
+
startLine: number;
|
|
37
|
+
/** Last line of the snippet (1-based, inclusive). */
|
|
38
|
+
endLine: number;
|
|
39
|
+
/** Line to call out as the focus point; defaults to `startLine`. */
|
|
40
|
+
focusLine?: number;
|
|
41
|
+
/** Lines of context above/below the snippet; defaults to 2. */
|
|
42
|
+
contextLines?: number;
|
|
43
|
+
/** Host-supplied file reader. */
|
|
44
|
+
readFile: (path: string) => Promise<string>;
|
|
45
|
+
/** Override Pierre's container background. Any CSS color string. */
|
|
46
|
+
background?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function PierreSnippetView({
|
|
50
|
+
filePath,
|
|
51
|
+
fileName,
|
|
52
|
+
startLine,
|
|
53
|
+
endLine,
|
|
54
|
+
focusLine,
|
|
55
|
+
contextLines = 2,
|
|
56
|
+
readFile,
|
|
57
|
+
background,
|
|
58
|
+
}: PierreSnippetViewProps) {
|
|
59
|
+
const { theme } = useTheme();
|
|
60
|
+
const [contents, setContents] = useState<string | null>(null);
|
|
61
|
+
const [error, setError] = useState<string | null>(null);
|
|
62
|
+
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
let cancelled = false;
|
|
65
|
+
setContents(null);
|
|
66
|
+
setError(null);
|
|
67
|
+
void readFile(filePath)
|
|
68
|
+
.then((content) => {
|
|
69
|
+
if (!cancelled) setContents(content);
|
|
70
|
+
})
|
|
71
|
+
.catch((err) => {
|
|
72
|
+
if (!cancelled) {
|
|
73
|
+
setError(err instanceof Error ? err.message : 'Failed to read file');
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return () => {
|
|
77
|
+
cancelled = true;
|
|
78
|
+
};
|
|
79
|
+
}, [filePath, readFile]);
|
|
80
|
+
|
|
81
|
+
const slice = useMemo(() => {
|
|
82
|
+
if (contents == null) return null;
|
|
83
|
+
return sliceSnippetWindow(
|
|
84
|
+
contents,
|
|
85
|
+
startLine,
|
|
86
|
+
endLine,
|
|
87
|
+
contextLines,
|
|
88
|
+
focusLine ?? startLine,
|
|
89
|
+
);
|
|
90
|
+
}, [contents, startLine, endLine, contextLines, focusLine]);
|
|
91
|
+
|
|
92
|
+
const fileObject = useMemo(
|
|
93
|
+
() =>
|
|
94
|
+
slice
|
|
95
|
+
? {
|
|
96
|
+
name: fileName,
|
|
97
|
+
contents: slice.contents,
|
|
98
|
+
lang: pierreLangForPath(filePath),
|
|
99
|
+
}
|
|
100
|
+
: null,
|
|
101
|
+
[fileName, filePath, slice],
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const lineNumberOffset = slice ? slice.sliceStart - 1 : 0;
|
|
105
|
+
|
|
106
|
+
const onPostRender = useCallback(
|
|
107
|
+
(fileContainer: HTMLElement) => {
|
|
108
|
+
if (lineNumberOffset !== 0) {
|
|
109
|
+
const root = fileContainer.shadowRoot ?? fileContainer;
|
|
110
|
+
const items = root.querySelectorAll('[data-column-number][data-line-index]');
|
|
111
|
+
items.forEach((el) => {
|
|
112
|
+
const idxStr = (el as HTMLElement).dataset.lineIndex;
|
|
113
|
+
if (idxStr == null) return;
|
|
114
|
+
const idx = Number.parseInt(idxStr, 10);
|
|
115
|
+
if (Number.isNaN(idx)) return;
|
|
116
|
+
const display = String(idx + 1 + lineNumberOffset);
|
|
117
|
+
const span = el.querySelector('[data-line-number-content]');
|
|
118
|
+
if (span && span.textContent !== display) {
|
|
119
|
+
span.textContent = display;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (slice?.focusOffset != null) {
|
|
124
|
+
scrollFocusLineIntoView(fileContainer, slice.focusOffset);
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
[lineNumberOffset, slice?.focusOffset],
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const options = useMemo(
|
|
131
|
+
() => ({
|
|
132
|
+
...buildPierreOptions(background),
|
|
133
|
+
onPostRender,
|
|
134
|
+
}),
|
|
135
|
+
[background, onPostRender],
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
if (error) {
|
|
139
|
+
return (
|
|
140
|
+
<div style={{ padding: 16, color: theme.colors.error ?? '#e5534b' }}>
|
|
141
|
+
{error}
|
|
142
|
+
</div>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
if (!fileObject || !slice) {
|
|
146
|
+
return (
|
|
147
|
+
<div style={{ padding: 16, color: theme.colors.textSecondary }}>
|
|
148
|
+
Loading…
|
|
149
|
+
</div>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const rangeLabel =
|
|
154
|
+
slice.sliceStart === slice.sliceEnd
|
|
155
|
+
? `Line ${slice.sliceStart}`
|
|
156
|
+
: `Lines ${slice.sliceStart}–${slice.sliceEnd}`;
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<div style={{ display: 'flex', flexDirection: 'column', minHeight: 0 }}>
|
|
160
|
+
<div
|
|
161
|
+
style={{
|
|
162
|
+
padding: '4px 14px 6px',
|
|
163
|
+
fontFamily: theme.fonts.monospace,
|
|
164
|
+
fontSize: theme.fontSizes[0],
|
|
165
|
+
color: theme.colors.textSecondary,
|
|
166
|
+
letterSpacing: 0.4,
|
|
167
|
+
textTransform: 'uppercase',
|
|
168
|
+
}}
|
|
169
|
+
>
|
|
170
|
+
{rangeLabel}
|
|
171
|
+
</div>
|
|
172
|
+
<File
|
|
173
|
+
file={fileObject}
|
|
174
|
+
options={options}
|
|
175
|
+
selectedLines={
|
|
176
|
+
slice.focusOffset != null
|
|
177
|
+
? { start: slice.focusOffset, end: slice.focusOffset }
|
|
178
|
+
: undefined
|
|
179
|
+
}
|
|
180
|
+
style={PIERRE_FILE_STYLE}
|
|
181
|
+
/>
|
|
182
|
+
</div>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PierreThroughlineCodeView — multi-file step snippets via `@pierre/diffs` CodeView.
|
|
3
|
+
*
|
|
4
|
+
* Renders one sliced window per throughline step in a single virtualized
|
|
5
|
+
* scroll; when `stepIndex` changes, scrolls that step's site line into view
|
|
6
|
+
* and highlights it via CodeView `selectedLines` (same mechanism as
|
|
7
|
+
* `PierreSnippetView`).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { useEffect, useMemo, useRef, useState, type ReactElement } from 'react';
|
|
11
|
+
import {
|
|
12
|
+
CodeView,
|
|
13
|
+
type CodeViewHandle,
|
|
14
|
+
type CodeViewItem,
|
|
15
|
+
type CodeViewReactOptions,
|
|
16
|
+
type DiffLineAnnotation,
|
|
17
|
+
type LineAnnotation,
|
|
18
|
+
} from '@pierre/diffs/react';
|
|
19
|
+
|
|
20
|
+
/** Mirrors Pierre's CodeViewLineSelection (not re-exported from the React entry). */
|
|
21
|
+
type CodeViewLineSelection = {
|
|
22
|
+
id: string;
|
|
23
|
+
range: { start: number; end: number };
|
|
24
|
+
};
|
|
25
|
+
/** Metadata carried on a throughline step's line annotation. */
|
|
26
|
+
type ThroughlineStepAnnotation = { text: string };
|
|
27
|
+
import { useTheme } from '@principal-ade/industry-theme';
|
|
28
|
+
import type { SubsystemThroughline } from '../subsystem/model';
|
|
29
|
+
import { buildPierreOptions, PIERRE_FILE_STYLE } from './pierreBackground';
|
|
30
|
+
import {
|
|
31
|
+
pierreCodeViewFileName,
|
|
32
|
+
pierreLangForPath,
|
|
33
|
+
} from './pierreFileLang';
|
|
34
|
+
import { resolvePierreSyntaxThemeName } from './pierreSyntaxTheme';
|
|
35
|
+
import { sliceSnippetWindow, type SnippetSlice } from './sliceSnippet';
|
|
36
|
+
|
|
37
|
+
export interface PierreThroughlineCodeViewProps {
|
|
38
|
+
throughline: SubsystemThroughline;
|
|
39
|
+
/** Focused step; `null` shows all snippets without scrolling to a step. */
|
|
40
|
+
stepIndex: number | null;
|
|
41
|
+
readFile: (path: string) => Promise<string>;
|
|
42
|
+
/** Context lines above/below each step site; defaults to 8. */
|
|
43
|
+
contextLines?: number;
|
|
44
|
+
/** Override Pierre's container background. */
|
|
45
|
+
background?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
type FileLoadState =
|
|
49
|
+
| { status: 'loading' }
|
|
50
|
+
| { status: 'error'; message: string }
|
|
51
|
+
| { status: 'ready'; byPath: Map<string, string> };
|
|
52
|
+
|
|
53
|
+
function stepItemId(throughlineId: string, index: number): string {
|
|
54
|
+
return `${throughlineId}:${index}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function PierreThroughlineCodeView({
|
|
58
|
+
throughline,
|
|
59
|
+
stepIndex,
|
|
60
|
+
readFile,
|
|
61
|
+
contextLines = 8,
|
|
62
|
+
background,
|
|
63
|
+
}: PierreThroughlineCodeViewProps) {
|
|
64
|
+
const { theme, mode } = useTheme();
|
|
65
|
+
const viewRef = useRef<CodeViewHandle<undefined>>(null);
|
|
66
|
+
const [load, setLoad] = useState<FileLoadState>({ status: 'loading' });
|
|
67
|
+
|
|
68
|
+
const pathsKey = useMemo(() => {
|
|
69
|
+
const paths = [...new Set(throughline.steps.map((s) => s.file))];
|
|
70
|
+
paths.sort();
|
|
71
|
+
return paths.join('\0');
|
|
72
|
+
}, [throughline.steps]);
|
|
73
|
+
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
let cancelled = false;
|
|
76
|
+
setLoad({ status: 'loading' });
|
|
77
|
+
const paths = [...new Set(throughline.steps.map((s) => s.file))];
|
|
78
|
+
void Promise.all(
|
|
79
|
+
paths.map(async (path) => {
|
|
80
|
+
const contents = await readFile(path);
|
|
81
|
+
return [path, contents] as const;
|
|
82
|
+
}),
|
|
83
|
+
)
|
|
84
|
+
.then((entries) => {
|
|
85
|
+
if (cancelled) return;
|
|
86
|
+
setLoad({ status: 'ready', byPath: new Map(entries) });
|
|
87
|
+
})
|
|
88
|
+
.catch((err) => {
|
|
89
|
+
if (cancelled) return;
|
|
90
|
+
setLoad({
|
|
91
|
+
status: 'error',
|
|
92
|
+
message: err instanceof Error ? err.message : 'Failed to read files',
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
return () => {
|
|
96
|
+
cancelled = true;
|
|
97
|
+
};
|
|
98
|
+
}, [throughline.id, pathsKey, readFile]);
|
|
99
|
+
|
|
100
|
+
const slices = useMemo((): SnippetSlice[] => {
|
|
101
|
+
if (load.status !== 'ready') return [];
|
|
102
|
+
return throughline.steps.map((step) => {
|
|
103
|
+
const contents = load.byPath.get(step.file) ?? '';
|
|
104
|
+
return sliceSnippetWindow(
|
|
105
|
+
contents,
|
|
106
|
+
step.line,
|
|
107
|
+
step.line,
|
|
108
|
+
contextLines,
|
|
109
|
+
step.line,
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
}, [load, throughline.steps, contextLines]);
|
|
113
|
+
|
|
114
|
+
const items = useMemo((): CodeViewItem<ThroughlineStepAnnotation>[] => {
|
|
115
|
+
if (load.status !== 'ready' || slices.length === 0) return [];
|
|
116
|
+
return throughline.steps.map((step, index) => {
|
|
117
|
+
const slice = slices[index]!;
|
|
118
|
+
const focus = slice.focusOffset;
|
|
119
|
+
const annotations:
|
|
120
|
+
| LineAnnotation<ThroughlineStepAnnotation>[]
|
|
121
|
+
| undefined =
|
|
122
|
+
step.annotation != null && step.annotation.length > 0 && focus != null
|
|
123
|
+
? [
|
|
124
|
+
{
|
|
125
|
+
lineNumber: focus,
|
|
126
|
+
metadata: { text: step.annotation },
|
|
127
|
+
},
|
|
128
|
+
]
|
|
129
|
+
: undefined;
|
|
130
|
+
return {
|
|
131
|
+
id: stepItemId(throughline.id, index),
|
|
132
|
+
type: 'file' as const,
|
|
133
|
+
version: 1,
|
|
134
|
+
annotations,
|
|
135
|
+
file: {
|
|
136
|
+
// Unique per-step name: many throughline steps share one path
|
|
137
|
+
// (e.g. seven sites in main.cpp), and identical `name`s have
|
|
138
|
+
// correlated with WebKit renderer traps in CodeView.
|
|
139
|
+
name: pierreCodeViewFileName(step.file, index),
|
|
140
|
+
contents: slice.contents,
|
|
141
|
+
// C-family → plain text: cpp Shiki still traps WebKit even with
|
|
142
|
+
// unique names (reproduced on 0.16.67).
|
|
143
|
+
lang: pierreLangForPath(step.file),
|
|
144
|
+
cacheKey: `${throughline.id}:${index}:${step.file}:${step.line}:${slice.sliceStart}-${slice.sliceEnd}`,
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
});
|
|
148
|
+
}, [load, slices, throughline.id, throughline.steps]);
|
|
149
|
+
|
|
150
|
+
/** Highlight the focused step's site line (1-based within its sliced window). */
|
|
151
|
+
const selectedLines = useMemo((): CodeViewLineSelection | null => {
|
|
152
|
+
if (stepIndex == null || stepIndex < 0 || stepIndex >= slices.length) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
const focus = slices[stepIndex]?.focusOffset;
|
|
156
|
+
if (focus == null) return null;
|
|
157
|
+
return {
|
|
158
|
+
id: stepItemId(throughline.id, stepIndex),
|
|
159
|
+
range: { start: focus, end: focus },
|
|
160
|
+
};
|
|
161
|
+
}, [stepIndex, slices, throughline.id]);
|
|
162
|
+
|
|
163
|
+
const renderHeaderPrefix = useMemo(() => {
|
|
164
|
+
return (item: CodeViewItem) => {
|
|
165
|
+
const index = Number.parseInt(item.id.split(':').pop() ?? '', 10);
|
|
166
|
+
const step = throughline.steps[index];
|
|
167
|
+
if (!step) return null;
|
|
168
|
+
const label =
|
|
169
|
+
step.symbol != null && step.symbol.length > 0
|
|
170
|
+
? step.symbol
|
|
171
|
+
: `step ${index + 1}`;
|
|
172
|
+
return (
|
|
173
|
+
<span
|
|
174
|
+
style={{
|
|
175
|
+
fontFamily: theme.fonts.monospace,
|
|
176
|
+
fontSize: theme.fontSizes[0],
|
|
177
|
+
color: theme.colors.textSecondary,
|
|
178
|
+
marginRight: 8,
|
|
179
|
+
}}
|
|
180
|
+
>
|
|
181
|
+
{index + 1}. {label}
|
|
182
|
+
</span>
|
|
183
|
+
);
|
|
184
|
+
};
|
|
185
|
+
}, [throughline.steps, theme]);
|
|
186
|
+
|
|
187
|
+
const renderHeaderMetadata = useMemo(() => {
|
|
188
|
+
return (item: CodeViewItem) => {
|
|
189
|
+
const index = Number.parseInt(item.id.split(':').pop() ?? '', 10);
|
|
190
|
+
const step = throughline.steps[index];
|
|
191
|
+
if (!step) return null;
|
|
192
|
+
return (
|
|
193
|
+
<span
|
|
194
|
+
style={{
|
|
195
|
+
fontFamily: theme.fonts.monospace,
|
|
196
|
+
fontSize: theme.fontSizes[0],
|
|
197
|
+
color: theme.colors.textSecondary,
|
|
198
|
+
marginLeft: 8,
|
|
199
|
+
}}
|
|
200
|
+
>
|
|
201
|
+
L{step.line}
|
|
202
|
+
</span>
|
|
203
|
+
);
|
|
204
|
+
};
|
|
205
|
+
}, [throughline.steps, theme]);
|
|
206
|
+
|
|
207
|
+
const renderAnnotation = useMemo(() => {
|
|
208
|
+
return (
|
|
209
|
+
annotation:
|
|
210
|
+
| LineAnnotation<ThroughlineStepAnnotation>
|
|
211
|
+
| DiffLineAnnotation<ThroughlineStepAnnotation>,
|
|
212
|
+
item: CodeViewItem<ThroughlineStepAnnotation>,
|
|
213
|
+
) => {
|
|
214
|
+
const index = Number.parseInt(item.id.split(':').pop() ?? '', 10);
|
|
215
|
+
const step = throughline.steps[index];
|
|
216
|
+
const text = annotation.metadata?.text;
|
|
217
|
+
if (!text || !step) return null;
|
|
218
|
+
return (
|
|
219
|
+
<span
|
|
220
|
+
style={{
|
|
221
|
+
display: 'inline-block',
|
|
222
|
+
fontFamily: theme.fonts.monospace,
|
|
223
|
+
fontSize: theme.fontSizes[0],
|
|
224
|
+
color: theme.colors.textSecondary,
|
|
225
|
+
fontStyle: 'italic',
|
|
226
|
+
opacity: 0.9,
|
|
227
|
+
}}
|
|
228
|
+
>
|
|
229
|
+
{text}
|
|
230
|
+
</span>
|
|
231
|
+
);
|
|
232
|
+
};
|
|
233
|
+
}, [throughline.steps, theme]);
|
|
234
|
+
|
|
235
|
+
const options = useMemo((): CodeViewReactOptions => {
|
|
236
|
+
return {
|
|
237
|
+
theme: {
|
|
238
|
+
dark: resolvePierreSyntaxThemeName('dark'),
|
|
239
|
+
light: resolvePierreSyntaxThemeName('light'),
|
|
240
|
+
},
|
|
241
|
+
stickyHeaders: true,
|
|
242
|
+
disableFileHeader: false,
|
|
243
|
+
layout: { paddingTop: 8, paddingBottom: 16, gap: 12 },
|
|
244
|
+
...(background ? buildPierreOptions(background) : {}),
|
|
245
|
+
...(mode === 'light' || mode === 'dark' ? { themeType: mode } : {}),
|
|
246
|
+
};
|
|
247
|
+
}, [background, mode]);
|
|
248
|
+
|
|
249
|
+
useEffect(() => {
|
|
250
|
+
if (load.status !== 'ready' || stepIndex == null) return;
|
|
251
|
+
if (stepIndex < 0 || stepIndex >= throughline.steps.length) return;
|
|
252
|
+
const focus = slices[stepIndex]?.focusOffset;
|
|
253
|
+
if (focus == null) return;
|
|
254
|
+
// Defer until CodeView has laid out items.
|
|
255
|
+
const id = stepItemId(throughline.id, stepIndex);
|
|
256
|
+
const t = window.setTimeout(() => {
|
|
257
|
+
viewRef.current?.scrollTo({
|
|
258
|
+
type: 'line',
|
|
259
|
+
id,
|
|
260
|
+
lineNumber: focus,
|
|
261
|
+
align: 'center',
|
|
262
|
+
});
|
|
263
|
+
}, 50);
|
|
264
|
+
return () => window.clearTimeout(t);
|
|
265
|
+
}, [
|
|
266
|
+
load.status,
|
|
267
|
+
stepIndex,
|
|
268
|
+
throughline.id,
|
|
269
|
+
throughline.steps.length,
|
|
270
|
+
slices,
|
|
271
|
+
items.length,
|
|
272
|
+
]);
|
|
273
|
+
|
|
274
|
+
if (load.status === 'error') {
|
|
275
|
+
return (
|
|
276
|
+
<div style={{ padding: 16, color: theme.colors.error ?? '#e5534b' }}>
|
|
277
|
+
{load.message}
|
|
278
|
+
</div>
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
if (load.status === 'loading' || items.length === 0) {
|
|
282
|
+
return (
|
|
283
|
+
<div style={{ padding: 16, color: theme.colors.textSecondary }}>
|
|
284
|
+
Loading…
|
|
285
|
+
</div>
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Pierre's CodeView prop / item unions blow past TS's complexity limit.
|
|
290
|
+
const CodeViewLoose = CodeView as unknown as (props: Record<string, unknown>) => ReactElement;
|
|
291
|
+
|
|
292
|
+
return (
|
|
293
|
+
<CodeViewLoose
|
|
294
|
+
ref={viewRef}
|
|
295
|
+
items={items}
|
|
296
|
+
options={options}
|
|
297
|
+
selectedLines={selectedLines}
|
|
298
|
+
renderHeaderPrefix={renderHeaderPrefix}
|
|
299
|
+
renderHeaderMetadata={renderHeaderMetadata}
|
|
300
|
+
renderAnnotation={renderAnnotation}
|
|
301
|
+
style={{ ...PIERRE_FILE_STYLE, height: '100%', overflow: 'auto' }}
|
|
302
|
+
/>
|
|
303
|
+
);
|
|
304
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
import { CONSTRUCT_COLOR, constructColorsFromPierreTheme } from './constructColors';
|
|
3
|
+
import type { SubsystemComponentConstruct } from '../subsystem/model';
|
|
4
|
+
|
|
5
|
+
const CONSTRUCTS: SubsystemComponentConstruct[] = [
|
|
6
|
+
'class',
|
|
7
|
+
'function',
|
|
8
|
+
'method',
|
|
9
|
+
'interface',
|
|
10
|
+
'type_alias',
|
|
11
|
+
'enum',
|
|
12
|
+
'module',
|
|
13
|
+
'store',
|
|
14
|
+
'external',
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const HEX = /^#[0-9a-f]{6}$/;
|
|
18
|
+
|
|
19
|
+
describe('constructColorsFromPierreTheme', () => {
|
|
20
|
+
test('resolves every construct to a hex in both themes (no fallbacks)', () => {
|
|
21
|
+
for (const themeName of ['pierre-dark', 'pierre-light'] as const) {
|
|
22
|
+
const colors = constructColorsFromPierreTheme(themeName);
|
|
23
|
+
for (const construct of CONSTRUCTS) {
|
|
24
|
+
expect(colors[construct]).toMatch(HEX);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('all seven constructs are distinguishable within a theme', () => {
|
|
30
|
+
for (const themeName of ['pierre-dark', 'pierre-light'] as const) {
|
|
31
|
+
const colors = constructColorsFromPierreTheme(themeName);
|
|
32
|
+
const values = CONSTRUCTS.map((c) => colors[c]);
|
|
33
|
+
expect(new Set(values).size).toBe(CONSTRUCTS.length);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('colliding scope pairs are shaded apart (class/type, function/method)', () => {
|
|
38
|
+
const dark = constructColorsFromPierreTheme('pierre-dark');
|
|
39
|
+
expect(dark.class).not.toBe(dark.type);
|
|
40
|
+
expect(dark.function).not.toBe(dark.method);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('dark and light instantiations differ', () => {
|
|
44
|
+
expect(constructColorsFromPierreTheme('pierre-dark')).not.toEqual(
|
|
45
|
+
constructColorsFromPierreTheme('pierre-light'),
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('the static dark instantiation matches the derived table', () => {
|
|
50
|
+
expect(CONSTRUCT_COLOR).toEqual(constructColorsFromPierreTheme('pierre-dark'));
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Construct colors derived from the Pierre syntax themes.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for node coloring: the same palette the declaration
|
|
5
|
+
* panel and Pierre file views render with. The themes are static JSON objects
|
|
6
|
+
* (VS Code/Shiki `tokenColors` scope rules), so extraction is a synchronous
|
|
7
|
+
* scope lookup — no Shiki call, no React context. Dark/light (and any future
|
|
8
|
+
* variant) resolves by mode at render time.
|
|
9
|
+
*
|
|
10
|
+
* Syntax themes deliberately reuse one hue across related scopes (class and
|
|
11
|
+
* type share `entity.name.class`); the node taxonomy needs distinguishable
|
|
12
|
+
* colors, so colliding constructs take a shade of the scope color — derived
|
|
13
|
+
* from the theme itself, toward white in dark themes and toward black in
|
|
14
|
+
* light themes.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { SubsystemComponentConstruct } from '../subsystem/model';
|
|
18
|
+
import type { PierreSyntaxThemeName } from './pierreSyntaxTheme';
|
|
19
|
+
import pierreDark from '@pierre/theme/pierre-dark';
|
|
20
|
+
import pierreLight from '@pierre/theme/pierre-light';
|
|
21
|
+
|
|
22
|
+
interface PierreThemeInput {
|
|
23
|
+
type: 'dark' | 'light';
|
|
24
|
+
colors: Record<string, string>;
|
|
25
|
+
tokenColors: Array<{ scope: string | string[]; settings: { foreground?: string } }>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const THEMES: Record<PierreSyntaxThemeName, PierreThemeInput> = {
|
|
29
|
+
'pierre-dark': pierreDark as unknown as PierreThemeInput,
|
|
30
|
+
'pierre-light': pierreLight as unknown as PierreThemeInput,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/** First rule whose scope list contains the exact scope. */
|
|
34
|
+
function scopeColor(theme: PierreThemeInput, scope: string): string | undefined {
|
|
35
|
+
for (const rule of theme.tokenColors) {
|
|
36
|
+
const scopes = Array.isArray(rule.scope) ? rule.scope : [rule.scope];
|
|
37
|
+
if (scopes.includes(scope)) return rule.settings.foreground;
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function hexToRgb(hex: string): [number, number, number] {
|
|
43
|
+
const h = hex.replace('#', '');
|
|
44
|
+
const full = h.length === 3 ? h.split('').map((c) => c + c).join('') : h;
|
|
45
|
+
const n = parseInt(full.slice(0, 6), 16);
|
|
46
|
+
return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function rgbToHex([r, g, b]: [number, number, number]): string {
|
|
50
|
+
const to = (v: number) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0');
|
|
51
|
+
return `#${to(r)}${to(g)}${to(b)}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Linear blend of two hex colors; amount 0 = base, 1 = other. */
|
|
55
|
+
function mix(hex: string, other: string, amount: number): string {
|
|
56
|
+
const base = hexToRgb(hex);
|
|
57
|
+
const target = hexToRgb(other);
|
|
58
|
+
return rgbToHex([
|
|
59
|
+
base[0] + (target[0] - base[0]) * amount,
|
|
60
|
+
base[1] + (target[1] - base[1]) * amount,
|
|
61
|
+
base[2] + (target[2] - base[2]) * amount,
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function constructColorsFromPierreTheme(
|
|
66
|
+
themeName: PierreSyntaxThemeName,
|
|
67
|
+
): Record<SubsystemComponentConstruct, string> {
|
|
68
|
+
const theme = THEMES[themeName];
|
|
69
|
+
// A scope the theme doesn't declare resolves to the theme's own foreground —
|
|
70
|
+
// still all-Pierre, never a hand-picked value.
|
|
71
|
+
const editorFg = theme.colors['editor.foreground'] ?? '#fafafa';
|
|
72
|
+
const pick = (scope: string) => scopeColor(theme, scope) ?? editorFg;
|
|
73
|
+
const towardBackground = theme.type === 'dark' ? lighten : darken;
|
|
74
|
+
|
|
75
|
+
const classColor = pick('entity.name.class');
|
|
76
|
+
const functionColor = pick('entity.name.function');
|
|
77
|
+
const typeColor = pick('support.type');
|
|
78
|
+
const moduleColor = pick('entity.name.namespace');
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
class: classColor,
|
|
82
|
+
// interface/type are the type-name scope, shaded to separate them from
|
|
83
|
+
// class (whose declaration name shares the same hue in syntax themes)
|
|
84
|
+
interface: towardBackground(typeColor, 0.14),
|
|
85
|
+
type_alias: towardBackground(typeColor, 0.28),
|
|
86
|
+
function: functionColor,
|
|
87
|
+
method: towardBackground(functionColor, 0.14),
|
|
88
|
+
// enum members are constants — the generic constant hue
|
|
89
|
+
enum: pick('constant'),
|
|
90
|
+
// module and store share the constant hue — the module holds the store,
|
|
91
|
+
// and the store IS the retained value, so the store keeps the pure
|
|
92
|
+
// `variable.other.constant` color and the module takes the shade
|
|
93
|
+
module: towardBackground(moduleColor, 0.18),
|
|
94
|
+
store: pick('variable.other.constant'),
|
|
95
|
+
external: pick('comment'),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function lighten(hex: string, amount: number): string {
|
|
100
|
+
return mix(hex, '#ffffff', amount);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function darken(hex: string, amount: number): string {
|
|
104
|
+
return mix(hex, '#000000', amount);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The dark-theme instantiation, for consumers without a mode context (the
|
|
109
|
+
* bun-side excalidraw exporter). React components derive per mode instead.
|
|
110
|
+
*/
|
|
111
|
+
export const CONSTRUCT_COLOR: Record<SubsystemComponentConstruct, string> =
|
|
112
|
+
constructColorsFromPierreTheme('pierre-dark');
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { PierreFileView } from './PierreFileView';
|
|
2
|
+
export type { PierreFileViewProps } from './PierreFileView';
|
|
3
|
+
export { PierreSnippetView } from './PierreSnippetView';
|
|
4
|
+
export type { PierreSnippetViewProps } from './PierreSnippetView';
|
|
5
|
+
export { PierreThroughlineCodeView } from './PierreThroughlineCodeView';
|
|
6
|
+
export type { PierreThroughlineCodeViewProps } from './PierreThroughlineCodeView';
|
|
7
|
+
export { sliceSnippetWindow } from './sliceSnippet';
|
|
8
|
+
export type { SnippetSlice } from './sliceSnippet';
|
|
9
|
+
export {
|
|
10
|
+
isPierreCFamilyPath,
|
|
11
|
+
pierreCodeViewFileName,
|
|
12
|
+
pierreLangForPath,
|
|
13
|
+
} from './pierreFileLang';
|
|
14
|
+
export {
|
|
15
|
+
PIERRE_DEFAULT_SYNTAX_THEMES,
|
|
16
|
+
resolvePierreSyntaxThemeName,
|
|
17
|
+
} from './pierreSyntaxTheme';
|
|
18
|
+
export type { PierreSyntaxThemeName } from './pierreSyntaxTheme';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Shared Pierre / @pierre/diffs option helpers for file + snippet views. */
|
|
2
|
+
|
|
3
|
+
export const PIERRE_FILE_STYLE = { display: 'block' } as const;
|
|
4
|
+
|
|
5
|
+
export const PIERRE_BASE_OPTIONS = {
|
|
6
|
+
disableFileHeader: true,
|
|
7
|
+
} as const;
|
|
8
|
+
|
|
9
|
+
export function buildBackgroundCSS(background: string): string {
|
|
10
|
+
return `
|
|
11
|
+
:host {
|
|
12
|
+
background: ${background} !important;
|
|
13
|
+
}
|
|
14
|
+
pre, code,
|
|
15
|
+
[data-gutter], [data-content],
|
|
16
|
+
[data-line], [data-column-number],
|
|
17
|
+
[data-gutter-buffer], [data-line-annotation], [data-no-newline],
|
|
18
|
+
[data-separator], [data-separator-wrapper] {
|
|
19
|
+
background: ${background} !important;
|
|
20
|
+
}
|
|
21
|
+
[data-line] span {
|
|
22
|
+
background: ${background} !important;
|
|
23
|
+
}
|
|
24
|
+
`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function buildPierreOptions(background?: string) {
|
|
28
|
+
if (!background) return PIERRE_BASE_OPTIONS;
|
|
29
|
+
return {
|
|
30
|
+
...PIERRE_BASE_OPTIONS,
|
|
31
|
+
unsafeCSS: buildBackgroundCSS(background),
|
|
32
|
+
};
|
|
33
|
+
}
|