@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.
Files changed (496) hide show
  1. package/README.md +93 -0
  2. package/dist/components/ConfigurationSelector.d.ts +35 -0
  3. package/dist/components/ConfigurationSelector.d.ts.map +1 -0
  4. package/dist/components/ConfigurationSelector.js +63 -0
  5. package/dist/components/ConfigurationSelector.js.map +1 -0
  6. package/dist/components/GraphRenderer.d.ts +295 -0
  7. package/dist/components/GraphRenderer.d.ts.map +1 -0
  8. package/dist/components/GraphRenderer.js +2008 -0
  9. package/dist/components/GraphRenderer.js.map +1 -0
  10. package/dist/components/MultiCanvasRenderer.d.ts +75 -0
  11. package/dist/components/MultiCanvasRenderer.d.ts.map +1 -0
  12. package/dist/components/MultiCanvasRenderer.js +203 -0
  13. package/dist/components/MultiCanvasRenderer.js.map +1 -0
  14. package/dist/components/NodeTooltip.d.ts +24 -0
  15. package/dist/components/NodeTooltip.d.ts.map +1 -0
  16. package/dist/components/NodeTooltip.js +160 -0
  17. package/dist/components/NodeTooltip.js.map +1 -0
  18. package/dist/components/SelectionSidebar.d.ts +18 -0
  19. package/dist/components/SelectionSidebar.d.ts.map +1 -0
  20. package/dist/components/SelectionSidebar.js +190 -0
  21. package/dist/components/SelectionSidebar.js.map +1 -0
  22. package/dist/components/SequenceDiagramRenderer.d.ts +77 -0
  23. package/dist/components/SequenceDiagramRenderer.d.ts.map +1 -0
  24. package/dist/components/SequenceDiagramRenderer.js +604 -0
  25. package/dist/components/SequenceDiagramRenderer.js.map +1 -0
  26. package/dist/components/WorkflowSequenceDiagram.d.ts +63 -0
  27. package/dist/components/WorkflowSequenceDiagram.d.ts.map +1 -0
  28. package/dist/components/WorkflowSequenceDiagram.js +147 -0
  29. package/dist/components/WorkflowSequenceDiagram.js.map +1 -0
  30. package/dist/components/dashboard/DashboardRenderer.d.ts +10 -0
  31. package/dist/components/dashboard/DashboardRenderer.d.ts.map +1 -0
  32. package/dist/components/dashboard/DashboardRenderer.js +179 -0
  33. package/dist/components/dashboard/DashboardRenderer.js.map +1 -0
  34. package/dist/components/dashboard/MetricPanel.d.ts +10 -0
  35. package/dist/components/dashboard/MetricPanel.d.ts.map +1 -0
  36. package/dist/components/dashboard/MetricPanel.js +103 -0
  37. package/dist/components/dashboard/MetricPanel.js.map +1 -0
  38. package/dist/components/dashboard/MockDataProvider.d.ts +30 -0
  39. package/dist/components/dashboard/MockDataProvider.d.ts.map +1 -0
  40. package/dist/components/dashboard/MockDataProvider.js +270 -0
  41. package/dist/components/dashboard/MockDataProvider.js.map +1 -0
  42. package/dist/components/dashboard/components/BarChart.d.ts +10 -0
  43. package/dist/components/dashboard/components/BarChart.d.ts.map +1 -0
  44. package/dist/components/dashboard/components/BarChart.js +167 -0
  45. package/dist/components/dashboard/components/BarChart.js.map +1 -0
  46. package/dist/components/dashboard/components/LineChart.d.ts +10 -0
  47. package/dist/components/dashboard/components/LineChart.d.ts.map +1 -0
  48. package/dist/components/dashboard/components/LineChart.js +141 -0
  49. package/dist/components/dashboard/components/LineChart.js.map +1 -0
  50. package/dist/components/dashboard/components/MetricCard.d.ts +9 -0
  51. package/dist/components/dashboard/components/MetricCard.d.ts.map +1 -0
  52. package/dist/components/dashboard/components/MetricCard.js +163 -0
  53. package/dist/components/dashboard/components/MetricCard.js.map +1 -0
  54. package/dist/components/dashboard/components/SourceLink.d.ts +9 -0
  55. package/dist/components/dashboard/components/SourceLink.d.ts.map +1 -0
  56. package/dist/components/dashboard/components/SourceLink.js +39 -0
  57. package/dist/components/dashboard/components/SourceLink.js.map +1 -0
  58. package/dist/components/dashboard/components/TimeRangeSelector.d.ts +9 -0
  59. package/dist/components/dashboard/components/TimeRangeSelector.d.ts.map +1 -0
  60. package/dist/components/dashboard/components/TimeRangeSelector.js +167 -0
  61. package/dist/components/dashboard/components/TimeRangeSelector.js.map +1 -0
  62. package/dist/components/dashboard/components/index.d.ts +6 -0
  63. package/dist/components/dashboard/components/index.d.ts.map +1 -0
  64. package/dist/components/dashboard/components/index.js +6 -0
  65. package/dist/components/dashboard/components/index.js.map +1 -0
  66. package/dist/components/dashboard/index.d.ts +6 -0
  67. package/dist/components/dashboard/index.d.ts.map +1 -0
  68. package/dist/components/dashboard/index.js +8 -0
  69. package/dist/components/dashboard/index.js.map +1 -0
  70. package/dist/components/dashboard/types.d.ts +74 -0
  71. package/dist/components/dashboard/types.d.ts.map +1 -0
  72. package/dist/components/dashboard/types.js +8 -0
  73. package/dist/components/dashboard/types.js.map +1 -0
  74. package/dist/components/session-events/SessionEventFeed.d.ts +34 -0
  75. package/dist/components/session-events/SessionEventFeed.d.ts.map +1 -0
  76. package/dist/components/session-events/SessionEventFeed.js +1196 -0
  77. package/dist/components/session-events/SessionEventFeed.js.map +1 -0
  78. package/dist/components/session-events/index.d.ts +7 -0
  79. package/dist/components/session-events/index.d.ts.map +1 -0
  80. package/dist/components/session-events/index.js +6 -0
  81. package/dist/components/session-events/index.js.map +1 -0
  82. package/dist/components/state-view/PipelineView.d.ts +14 -0
  83. package/dist/components/state-view/PipelineView.d.ts.map +1 -0
  84. package/dist/components/state-view/PipelineView.js +195 -0
  85. package/dist/components/state-view/PipelineView.js.map +1 -0
  86. package/dist/components/state-view/index.d.ts +14 -0
  87. package/dist/components/state-view/index.d.ts.map +1 -0
  88. package/dist/components/state-view/index.js +12 -0
  89. package/dist/components/state-view/index.js.map +1 -0
  90. package/dist/components/state-view/types.d.ts +188 -0
  91. package/dist/components/state-view/types.d.ts.map +1 -0
  92. package/dist/components/state-view/types.js +10 -0
  93. package/dist/components/state-view/types.js.map +1 -0
  94. package/dist/components/state-view/useStateView.d.ts +32 -0
  95. package/dist/components/state-view/useStateView.d.ts.map +1 -0
  96. package/dist/components/state-view/useStateView.js +129 -0
  97. package/dist/components/state-view/useStateView.js.map +1 -0
  98. package/dist/contexts/GraphEditContext.d.ts +20 -0
  99. package/dist/contexts/GraphEditContext.d.ts.map +1 -0
  100. package/dist/contexts/GraphEditContext.js +8 -0
  101. package/dist/contexts/GraphEditContext.js.map +1 -0
  102. package/dist/contexts/TooltipPortalContext.d.ts +8 -0
  103. package/dist/contexts/TooltipPortalContext.d.ts.map +1 -0
  104. package/dist/contexts/TooltipPortalContext.js +8 -0
  105. package/dist/contexts/TooltipPortalContext.js.map +1 -0
  106. package/dist/edges/CustomEdge.d.ts +24 -0
  107. package/dist/edges/CustomEdge.d.ts.map +1 -0
  108. package/dist/edges/CustomEdge.js +222 -0
  109. package/dist/edges/CustomEdge.js.map +1 -0
  110. package/dist/edges/GenericEdge.d.ts +18 -0
  111. package/dist/edges/GenericEdge.d.ts.map +1 -0
  112. package/dist/edges/GenericEdge.js +10 -0
  113. package/dist/edges/GenericEdge.js.map +1 -0
  114. package/dist/graphify/anchor.d.ts +28 -0
  115. package/dist/graphify/anchor.d.ts.map +1 -0
  116. package/dist/graphify/anchor.js +132 -0
  117. package/dist/graphify/anchor.js.map +1 -0
  118. package/dist/graphify/consolidated.d.ts +210 -0
  119. package/dist/graphify/consolidated.d.ts.map +1 -0
  120. package/dist/graphify/consolidated.js +11 -0
  121. package/dist/graphify/consolidated.js.map +1 -0
  122. package/dist/graphify/ids.d.ts +19 -0
  123. package/dist/graphify/ids.d.ts.map +1 -0
  124. package/dist/graphify/ids.js +46 -0
  125. package/dist/graphify/ids.js.map +1 -0
  126. package/dist/graphify/index.d.ts +18 -0
  127. package/dist/graphify/index.d.ts.map +1 -0
  128. package/dist/graphify/index.js +12 -0
  129. package/dist/graphify/index.js.map +1 -0
  130. package/dist/graphify/kind.d.ts +23 -0
  131. package/dist/graphify/kind.d.ts.map +1 -0
  132. package/dist/graphify/kind.js +77 -0
  133. package/dist/graphify/kind.js.map +1 -0
  134. package/dist/graphify/resolve.d.ts +48 -0
  135. package/dist/graphify/resolve.d.ts.map +1 -0
  136. package/dist/graphify/resolve.js +83 -0
  137. package/dist/graphify/resolve.js.map +1 -0
  138. package/dist/graphify/signature.d.ts +87 -0
  139. package/dist/graphify/signature.d.ts.map +1 -0
  140. package/dist/graphify/signature.js +276 -0
  141. package/dist/graphify/signature.js.map +1 -0
  142. package/dist/graphify/types.d.ts +141 -0
  143. package/dist/graphify/types.d.ts.map +1 -0
  144. package/dist/graphify/types.js +8 -0
  145. package/dist/graphify/types.js.map +1 -0
  146. package/dist/hooks/useElkLayout.d.ts +66 -0
  147. package/dist/hooks/useElkLayout.d.ts.map +1 -0
  148. package/dist/hooks/useElkLayout.js +136 -0
  149. package/dist/hooks/useElkLayout.js.map +1 -0
  150. package/dist/hooks/usePathBasedEvents.d.ts +42 -0
  151. package/dist/hooks/usePathBasedEvents.d.ts.map +1 -0
  152. package/dist/hooks/usePathBasedEvents.js +119 -0
  153. package/dist/hooks/usePathBasedEvents.js.map +1 -0
  154. package/dist/hooks/useSequenceLayout.d.ts +186 -0
  155. package/dist/hooks/useSequenceLayout.d.ts.map +1 -0
  156. package/dist/hooks/useSequenceLayout.js +327 -0
  157. package/dist/hooks/useSequenceLayout.js.map +1 -0
  158. package/dist/hooks/useUndoRedo.d.ts +80 -0
  159. package/dist/hooks/useUndoRedo.d.ts.map +1 -0
  160. package/dist/hooks/useUndoRedo.js +70 -0
  161. package/dist/hooks/useUndoRedo.js.map +1 -0
  162. package/dist/index.d.ts +73 -0
  163. package/dist/index.d.ts.map +1 -0
  164. package/dist/index.js +51 -0
  165. package/dist/index.js.map +1 -0
  166. package/dist/nodes/CustomNode.d.ts +28 -0
  167. package/dist/nodes/CustomNode.d.ts.map +1 -0
  168. package/dist/nodes/CustomNode.js +820 -0
  169. package/dist/nodes/CustomNode.js.map +1 -0
  170. package/dist/nodes/GenericNode.d.ts +20 -0
  171. package/dist/nodes/GenericNode.d.ts.map +1 -0
  172. package/dist/nodes/GenericNode.js +20 -0
  173. package/dist/nodes/GenericNode.js.map +1 -0
  174. package/dist/nodes/otel/OtelBoundaryNode.d.ts +55 -0
  175. package/dist/nodes/otel/OtelBoundaryNode.d.ts.map +1 -0
  176. package/dist/nodes/otel/OtelBoundaryNode.js +81 -0
  177. package/dist/nodes/otel/OtelBoundaryNode.js.map +1 -0
  178. package/dist/nodes/otel/OtelEventNode.d.ts +59 -0
  179. package/dist/nodes/otel/OtelEventNode.d.ts.map +1 -0
  180. package/dist/nodes/otel/OtelEventNode.js +82 -0
  181. package/dist/nodes/otel/OtelEventNode.js.map +1 -0
  182. package/dist/nodes/otel/OtelResourceNode.d.ts +53 -0
  183. package/dist/nodes/otel/OtelResourceNode.d.ts.map +1 -0
  184. package/dist/nodes/otel/OtelResourceNode.js +105 -0
  185. package/dist/nodes/otel/OtelResourceNode.js.map +1 -0
  186. package/dist/nodes/otel/OtelScopeNode.d.ts +53 -0
  187. package/dist/nodes/otel/OtelScopeNode.d.ts.map +1 -0
  188. package/dist/nodes/otel/OtelScopeNode.js +81 -0
  189. package/dist/nodes/otel/OtelScopeNode.js.map +1 -0
  190. package/dist/nodes/otel/OtelSpanConventionNode.d.ts +61 -0
  191. package/dist/nodes/otel/OtelSpanConventionNode.d.ts.map +1 -0
  192. package/dist/nodes/otel/OtelSpanConventionNode.js +131 -0
  193. package/dist/nodes/otel/OtelSpanConventionNode.js.map +1 -0
  194. package/dist/nodes/otel/index.d.ts +17 -0
  195. package/dist/nodes/otel/index.d.ts.map +1 -0
  196. package/dist/nodes/otel/index.js +13 -0
  197. package/dist/nodes/otel/index.js.map +1 -0
  198. package/dist/nodes/otel/shared/NodeBadges.d.ts +10 -0
  199. package/dist/nodes/otel/shared/NodeBadges.d.ts.map +1 -0
  200. package/dist/nodes/otel/shared/NodeBadges.js +178 -0
  201. package/dist/nodes/otel/shared/NodeBadges.js.map +1 -0
  202. package/dist/nodes/otel/shared/NodeContent.d.ts +10 -0
  203. package/dist/nodes/otel/shared/NodeContent.d.ts.map +1 -0
  204. package/dist/nodes/otel/shared/NodeContent.js +96 -0
  205. package/dist/nodes/otel/shared/NodeContent.js.map +1 -0
  206. package/dist/nodes/otel/shared/index.d.ts +8 -0
  207. package/dist/nodes/otel/shared/index.d.ts.map +1 -0
  208. package/dist/nodes/otel/shared/index.js +8 -0
  209. package/dist/nodes/otel/shared/index.js.map +1 -0
  210. package/dist/nodes/otel/shared/types.d.ts +129 -0
  211. package/dist/nodes/otel/shared/types.d.ts.map +1 -0
  212. package/dist/nodes/otel/shared/types.js +5 -0
  213. package/dist/nodes/otel/shared/types.js.map +1 -0
  214. package/dist/nodes/otel/shared/useNodeBehavior.d.ts +42 -0
  215. package/dist/nodes/otel/shared/useNodeBehavior.d.ts.map +1 -0
  216. package/dist/nodes/otel/shared/useNodeBehavior.js +61 -0
  217. package/dist/nodes/otel/shared/useNodeBehavior.js.map +1 -0
  218. package/dist/pierre/PierreFileView.d.ts +17 -0
  219. package/dist/pierre/PierreFileView.d.ts.map +1 -0
  220. package/dist/pierre/PierreFileView.js +46 -0
  221. package/dist/pierre/PierreFileView.js.map +1 -0
  222. package/dist/pierre/PierreSnippetView.d.ts +28 -0
  223. package/dist/pierre/PierreSnippetView.d.ts.map +1 -0
  224. package/dist/pierre/PierreSnippetView.js +105 -0
  225. package/dist/pierre/PierreSnippetView.js.map +1 -0
  226. package/dist/pierre/PierreThroughlineCodeView.d.ts +22 -0
  227. package/dist/pierre/PierreThroughlineCodeView.d.ts.map +1 -0
  228. package/dist/pierre/PierreThroughlineCodeView.js +206 -0
  229. package/dist/pierre/PierreThroughlineCodeView.js.map +1 -0
  230. package/dist/pierre/constructColors.d.ts +24 -0
  231. package/dist/pierre/constructColors.d.ts.map +1 -0
  232. package/dist/pierre/constructColors.js +91 -0
  233. package/dist/pierre/constructColors.js.map +1 -0
  234. package/dist/pierre/index.d.ts +12 -0
  235. package/dist/pierre/index.d.ts.map +1 -0
  236. package/dist/pierre/index.js +7 -0
  237. package/dist/pierre/index.js.map +1 -0
  238. package/dist/pierre/pierreBackground.d.ts +15 -0
  239. package/dist/pierre/pierreBackground.d.ts.map +1 -0
  240. package/dist/pierre/pierreBackground.js +31 -0
  241. package/dist/pierre/pierreBackground.js.map +1 -0
  242. package/dist/pierre/pierreFileLang.d.ts +27 -0
  243. package/dist/pierre/pierreFileLang.d.ts.map +1 -0
  244. package/dist/pierre/pierreFileLang.js +52 -0
  245. package/dist/pierre/pierreFileLang.js.map +1 -0
  246. package/dist/pierre/pierreSyntaxTheme.d.ts +11 -0
  247. package/dist/pierre/pierreSyntaxTheme.d.ts.map +1 -0
  248. package/dist/pierre/pierreSyntaxTheme.js +20 -0
  249. package/dist/pierre/pierreSyntaxTheme.js.map +1 -0
  250. package/dist/pierre/scrollAnchor.d.ts +5 -0
  251. package/dist/pierre/scrollAnchor.d.ts.map +1 -0
  252. package/dist/pierre/scrollAnchor.js +9 -0
  253. package/dist/pierre/scrollAnchor.js.map +1 -0
  254. package/dist/pierre/sliceSnippet.d.ts +10 -0
  255. package/dist/pierre/sliceSnippet.d.ts.map +1 -0
  256. package/dist/pierre/sliceSnippet.js +16 -0
  257. package/dist/pierre/sliceSnippet.js.map +1 -0
  258. package/dist/pierre/syntaxTokens.d.ts +11 -0
  259. package/dist/pierre/syntaxTokens.d.ts.map +1 -0
  260. package/dist/pierre/syntaxTokens.js +51 -0
  261. package/dist/pierre/syntaxTokens.js.map +1 -0
  262. package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts +8 -0
  263. package/dist/stories/Subsystem/ComponentGraph/fixtures.d.ts.map +1 -0
  264. package/dist/stories/Subsystem/ComponentGraph/fixtures.js +116 -0
  265. package/dist/stories/Subsystem/ComponentGraph/fixtures.js.map +1 -0
  266. package/dist/subsystem/ComponentDeclaration.d.ts +87 -0
  267. package/dist/subsystem/ComponentDeclaration.d.ts.map +1 -0
  268. package/dist/subsystem/ComponentDeclaration.js +374 -0
  269. package/dist/subsystem/ComponentDeclaration.js.map +1 -0
  270. package/dist/subsystem/FileDrawer.d.ts +17 -0
  271. package/dist/subsystem/FileDrawer.d.ts.map +1 -0
  272. package/dist/subsystem/FileDrawer.js +72 -0
  273. package/dist/subsystem/FileDrawer.js.map +1 -0
  274. package/dist/subsystem/GraphLayoutCover.d.ts +20 -0
  275. package/dist/subsystem/GraphLayoutCover.d.ts.map +1 -0
  276. package/dist/subsystem/GraphLayoutCover.js +42 -0
  277. package/dist/subsystem/GraphLayoutCover.js.map +1 -0
  278. package/dist/subsystem/SubsystemComponentGraph.d.ts +96 -0
  279. package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -0
  280. package/dist/subsystem/SubsystemComponentGraph.js +1059 -0
  281. package/dist/subsystem/SubsystemComponentGraph.js.map +1 -0
  282. package/dist/subsystem/SubsystemFileTree.d.ts +24 -0
  283. package/dist/subsystem/SubsystemFileTree.d.ts.map +1 -0
  284. package/dist/subsystem/SubsystemFileTree.js +150 -0
  285. package/dist/subsystem/SubsystemFileTree.js.map +1 -0
  286. package/dist/subsystem/declarationRef.d.ts +39 -0
  287. package/dist/subsystem/declarationRef.d.ts.map +1 -0
  288. package/dist/subsystem/declarationRef.js +32 -0
  289. package/dist/subsystem/declarationRef.js.map +1 -0
  290. package/dist/subsystem/formatDeclaration.d.ts +11 -0
  291. package/dist/subsystem/formatDeclaration.d.ts.map +1 -0
  292. package/dist/subsystem/formatDeclaration.js +146 -0
  293. package/dist/subsystem/formatDeclaration.js.map +1 -0
  294. package/dist/subsystem/model.d.ts +353 -0
  295. package/dist/subsystem/model.d.ts.map +1 -0
  296. package/dist/subsystem/model.js +503 -0
  297. package/dist/subsystem/model.js.map +1 -0
  298. package/dist/subsystem/nodes.d.ts +69 -0
  299. package/dist/subsystem/nodes.d.ts.map +1 -0
  300. package/dist/subsystem/nodes.js +289 -0
  301. package/dist/subsystem/nodes.js.map +1 -0
  302. package/dist/subsystem/paths.d.ts +63 -0
  303. package/dist/subsystem/paths.d.ts.map +1 -0
  304. package/dist/subsystem/paths.js +86 -0
  305. package/dist/subsystem/paths.js.map +1 -0
  306. package/dist/subsystem/tokenizeComponent.d.ts +20 -0
  307. package/dist/subsystem/tokenizeComponent.d.ts.map +1 -0
  308. package/dist/subsystem/tokenizeComponent.js +56 -0
  309. package/dist/subsystem/tokenizeComponent.js.map +1 -0
  310. package/dist/subsystem/tokenizeFormatted.d.ts +12 -0
  311. package/dist/subsystem/tokenizeFormatted.d.ts.map +1 -0
  312. package/dist/subsystem/tokenizeFormatted.js +13 -0
  313. package/dist/subsystem/tokenizeFormatted.js.map +1 -0
  314. package/dist/utils/animationMapping.d.ts +53 -0
  315. package/dist/utils/animationMapping.d.ts.map +1 -0
  316. package/dist/utils/animationMapping.js +126 -0
  317. package/dist/utils/animationMapping.js.map +1 -0
  318. package/dist/utils/canvasBounds.d.ts +50 -0
  319. package/dist/utils/canvasBounds.d.ts.map +1 -0
  320. package/dist/utils/canvasBounds.js +88 -0
  321. package/dist/utils/canvasBounds.js.map +1 -0
  322. package/dist/utils/elkLayout.d.ts +137 -0
  323. package/dist/utils/elkLayout.d.ts.map +1 -0
  324. package/dist/utils/elkLayout.js +596 -0
  325. package/dist/utils/elkLayout.js.map +1 -0
  326. package/dist/utils/graphConverter.d.ts +18 -0
  327. package/dist/utils/graphConverter.d.ts.map +1 -0
  328. package/dist/utils/graphConverter.js +114 -0
  329. package/dist/utils/graphConverter.js.map +1 -0
  330. package/dist/utils/iconResolver.d.ts +29 -0
  331. package/dist/utils/iconResolver.d.ts.map +1 -0
  332. package/dist/utils/iconResolver.js +30 -0
  333. package/dist/utils/iconResolver.js.map +1 -0
  334. package/dist/utils/orientationUtils.d.ts +19 -0
  335. package/dist/utils/orientationUtils.d.ts.map +1 -0
  336. package/dist/utils/orientationUtils.js +62 -0
  337. package/dist/utils/orientationUtils.js.map +1 -0
  338. package/package.json +80 -0
  339. package/src/components/ConfigurationSelector.tsx +133 -0
  340. package/src/components/GraphRenderer.tsx +3195 -0
  341. package/src/components/MultiCanvasRenderer.tsx +295 -0
  342. package/src/components/NodeTooltip.tsx +279 -0
  343. package/src/components/PendingChanges.test.tsx +375 -0
  344. package/src/components/SelectionSidebar.tsx +352 -0
  345. package/src/components/SequenceDiagramRenderer.tsx +1156 -0
  346. package/src/components/WorkflowSequenceDiagram.tsx +270 -0
  347. package/src/components/dashboard/DashboardRenderer.tsx +317 -0
  348. package/src/components/dashboard/MetricPanel.tsx +254 -0
  349. package/src/components/dashboard/MockDataProvider.ts +330 -0
  350. package/src/components/dashboard/components/BarChart.tsx +299 -0
  351. package/src/components/dashboard/components/LineChart.tsx +279 -0
  352. package/src/components/dashboard/components/MetricCard.tsx +270 -0
  353. package/src/components/dashboard/components/SourceLink.tsx +63 -0
  354. package/src/components/dashboard/components/TimeRangeSelector.tsx +280 -0
  355. package/src/components/dashboard/components/index.ts +5 -0
  356. package/src/components/dashboard/index.ts +47 -0
  357. package/src/components/dashboard/types.ts +126 -0
  358. package/src/components/session-events/SessionEventFeed.tsx +1797 -0
  359. package/src/components/session-events/index.ts +13 -0
  360. package/src/components/state-view/PipelineView.tsx +347 -0
  361. package/src/components/state-view/index.ts +14 -0
  362. package/src/components/state-view/types.ts +261 -0
  363. package/src/components/state-view/useStateView.ts +205 -0
  364. package/src/contexts/GraphEditContext.tsx +27 -0
  365. package/src/contexts/TooltipPortalContext.ts +8 -0
  366. package/src/edges/CustomEdge.tsx +402 -0
  367. package/src/edges/GenericEdge.tsx +36 -0
  368. package/src/graphify/anchor.test.ts +124 -0
  369. package/src/graphify/anchor.ts +160 -0
  370. package/src/graphify/consolidated.ts +246 -0
  371. package/src/graphify/ids.ts +48 -0
  372. package/src/graphify/index.ts +72 -0
  373. package/src/graphify/kind.test.ts +108 -0
  374. package/src/graphify/kind.ts +120 -0
  375. package/src/graphify/resolve.test.ts +89 -0
  376. package/src/graphify/resolve.ts +115 -0
  377. package/src/graphify/signature.test.ts +278 -0
  378. package/src/graphify/signature.ts +354 -0
  379. package/src/graphify/types.ts +164 -0
  380. package/src/hooks/useElkLayout.test.ts +134 -0
  381. package/src/hooks/useElkLayout.ts +191 -0
  382. package/src/hooks/usePathBasedEvents.ts +192 -0
  383. package/src/hooks/useSequenceLayout.ts +543 -0
  384. package/src/hooks/useUndoRedo.ts +144 -0
  385. package/src/index.ts +341 -0
  386. package/src/nodes/CustomNode.tsx +1231 -0
  387. package/src/nodes/GenericNode.tsx +55 -0
  388. package/src/nodes/otel/OtelBoundaryNode.tsx +224 -0
  389. package/src/nodes/otel/OtelEventNode.tsx +225 -0
  390. package/src/nodes/otel/OtelResourceNode.tsx +251 -0
  391. package/src/nodes/otel/OtelScopeNode.tsx +221 -0
  392. package/src/nodes/otel/OtelSpanConventionNode.tsx +295 -0
  393. package/src/nodes/otel/index.ts +23 -0
  394. package/src/nodes/otel/shared/NodeBadges.tsx +295 -0
  395. package/src/nodes/otel/shared/NodeContent.tsx +204 -0
  396. package/src/nodes/otel/shared/index.ts +8 -0
  397. package/src/nodes/otel/shared/types.ts +138 -0
  398. package/src/nodes/otel/shared/useNodeBehavior.ts +114 -0
  399. package/src/pierre/PierreFileView.tsx +81 -0
  400. package/src/pierre/PierreSnippetView.tsx +184 -0
  401. package/src/pierre/PierreThroughlineCodeView.tsx +304 -0
  402. package/src/pierre/constructColors.test.ts +52 -0
  403. package/src/pierre/constructColors.ts +112 -0
  404. package/src/pierre/index.ts +18 -0
  405. package/src/pierre/pierreBackground.ts +33 -0
  406. package/src/pierre/pierreFileLang.test.ts +26 -0
  407. package/src/pierre/pierreFileLang.ts +55 -0
  408. package/src/pierre/pierreSyntaxTheme.ts +23 -0
  409. package/src/pierre/scrollAnchor.test.ts +13 -0
  410. package/src/pierre/scrollAnchor.ts +11 -0
  411. package/src/pierre/sliceSnippet.test.ts +21 -0
  412. package/src/pierre/sliceSnippet.ts +31 -0
  413. package/src/pierre/syntaxTokens.test.ts +35 -0
  414. package/src/pierre/syntaxTokens.ts +60 -0
  415. package/src/stories/Audit/BoundaryNodes.stories.tsx +385 -0
  416. package/src/stories/Audit/CanvasEdgeTypes.stories.tsx +1448 -0
  417. package/src/stories/Audit/CanvasNodeTypes.stories.tsx +1049 -0
  418. package/src/stories/Audit/ColorPriority.stories.tsx +895 -0
  419. package/src/stories/Audit/DiamondBadges.stories.tsx +629 -0
  420. package/src/stories/Audit/NodeDimensionsTesting.stories.tsx +724 -0
  421. package/src/stories/Audit/NodeFieldsAudit.stories.tsx +996 -0
  422. package/src/stories/Audit/NodeFontSizeTesting.stories.tsx +715 -0
  423. package/src/stories/Audit/NodeShapes.stories.tsx +1208 -0
  424. package/src/stories/Audit/WideNodesTesting.stories.tsx +1045 -0
  425. package/src/stories/Components/DashboardRenderer.stories.tsx +263 -0
  426. package/src/stories/Components/GraphRenderer.stories.tsx +3236 -0
  427. package/src/stories/Components/MultiCanvasRenderer.stories.tsx +370 -0
  428. package/src/stories/Components/SequenceDiagram.stories.tsx +255 -0
  429. package/src/stories/Components/StateView.stories.tsx +417 -0
  430. package/src/stories/Components/TraceViewer.stories.tsx +442 -0
  431. package/src/stories/Components/WorkflowSequenceDiagram.stories.tsx +802 -0
  432. package/src/stories/Features/AnimationWorkshop.stories.tsx +727 -0
  433. package/src/stories/Features/ChangeTypeVisual.stories.tsx +67 -0
  434. package/src/stories/Features/EventDrivenAnimations.stories.tsx +513 -0
  435. package/src/stories/Features/MultiConfig.stories.tsx +539 -0
  436. package/src/stories/Introduction.mdx +34 -0
  437. package/src/stories/Layout/ElkEdgeRouting.stories.tsx +539 -0
  438. package/src/stories/Layout/GraphOrientation.stories.tsx +500 -0
  439. package/src/stories/Layout/MultiDirectionalConnections.stories.tsx +352 -0
  440. package/src/stories/Nodes/NodeDefinitionComparison.stories.tsx +560 -0
  441. package/src/stories/Nodes/NodeNameFallbacks.stories.tsx +491 -0
  442. package/src/stories/Nodes/NumericColors.stories.tsx +440 -0
  443. package/src/stories/OTEL/EventNameDisplay.stories.tsx +694 -0
  444. package/src/stories/OTEL/EventNameFallback.stories.tsx +578 -0
  445. package/src/stories/OTEL/OtelComponents.stories.tsx +422 -0
  446. package/src/stories/OTEL/OtelNodeTypesPrototype.stories.tsx +806 -0
  447. package/src/stories/OTEL/RawEventCards.stories.tsx +57 -0
  448. package/src/stories/OTEL/SpanBadges.stories.tsx +840 -0
  449. package/src/stories/OTEL/ValidationEventsCanvas.stories.tsx +209 -0
  450. package/src/stories/Pierre/CodeView.stories.tsx +219 -0
  451. package/src/stories/RealWorld/BacklogMdCanvases.stories.tsx +721 -0
  452. package/src/stories/RealWorld/FileCitySequence.stories.tsx +516 -0
  453. package/src/stories/RealWorld/RealCanvasFiles.stories.tsx +336 -0
  454. package/src/stories/Subsystem/ComponentDeclarationAudit.stories.tsx +321 -0
  455. package/src/stories/Subsystem/ComponentGraph/Appearance.stories.tsx +365 -0
  456. package/src/stories/Subsystem/ComponentGraph/Basics.stories.tsx +137 -0
  457. package/src/stories/Subsystem/ComponentGraph/Captures.stories.tsx +238 -0
  458. package/src/stories/Subsystem/ComponentGraph/DetailPanel.stories.tsx +315 -0
  459. package/src/stories/Subsystem/ComponentGraph/Flows.stories.tsx +239 -0
  460. package/src/stories/Subsystem/ComponentGraph/FrameworkStereotype.stories.tsx +216 -0
  461. package/src/stories/Subsystem/ComponentGraph/GraphTitle.stories.tsx +70 -0
  462. package/src/stories/Subsystem/ComponentGraph/Processes.stories.tsx +68 -0
  463. package/src/stories/Subsystem/ComponentGraph/Scenarios.stories.tsx +959 -0
  464. package/src/stories/Subsystem/ComponentGraph/Spotlights.stories.tsx +681 -0
  465. package/src/stories/Subsystem/ComponentGraph/fixtures.ts +129 -0
  466. package/src/stories/__traces__/test-run.canvas.json +241 -0
  467. package/src/stories/data/activity-feed-analytics.dashboard.json +300 -0
  468. package/src/stories/data/file-city-images-transformed.otel.canvas.json +295 -0
  469. package/src/stories/data/file-city-workflows.json +269 -0
  470. package/src/stories/data/graph-converter-test-execution.json +443 -0
  471. package/src/stories/data/graph-converter-test.workflow.json +105 -0
  472. package/src/stories/data/graph-converter-validated-execution.json +58 -0
  473. package/src/stories/data/opencode-session-raw-events.json +273396 -0
  474. package/src/subsystem/ComponentDeclaration.tsx +643 -0
  475. package/src/subsystem/FileDrawer.tsx +106 -0
  476. package/src/subsystem/GraphLayoutCover.tsx +69 -0
  477. package/src/subsystem/SubsystemComponentGraph.tsx +1644 -0
  478. package/src/subsystem/SubsystemFileTree.tsx +190 -0
  479. package/src/subsystem/declarationRef.test.ts +33 -0
  480. package/src/subsystem/declarationRef.ts +63 -0
  481. package/src/subsystem/formatDeclaration.ts +174 -0
  482. package/src/subsystem/model.test.ts +244 -0
  483. package/src/subsystem/model.ts +850 -0
  484. package/src/subsystem/nodes.test.ts +56 -0
  485. package/src/subsystem/nodes.tsx +443 -0
  486. package/src/subsystem/paths.test.ts +123 -0
  487. package/src/subsystem/paths.ts +127 -0
  488. package/src/subsystem/tokenizeComponent.ts +70 -0
  489. package/src/subsystem/tokenizeFormatted.ts +19 -0
  490. package/src/utils/animationMapping.ts +166 -0
  491. package/src/utils/canvasBounds.ts +146 -0
  492. package/src/utils/elkLayout.test.ts +240 -0
  493. package/src/utils/elkLayout.ts +779 -0
  494. package/src/utils/graphConverter.ts +148 -0
  495. package/src/utils/iconResolver.tsx +53 -0
  496. package/src/utils/orientationUtils.ts +73 -0
@@ -0,0 +1,1448 @@
1
+ import React, { useState } from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+ import { GraphRenderer } from '../../components/GraphRenderer';
4
+ import type { ExtendedCanvas, DerivedEdge } from '@principal-ai/subsystems-core';
5
+ import { ThemeProvider, defaultEditorTheme } from '@principal-ade/industry-theme';
6
+
7
+ const meta = {
8
+ title: 'Audit/CanvasEdgeTypes',
9
+ component: GraphRenderer,
10
+ parameters: {
11
+ layout: 'centered',
12
+ },
13
+ tags: ['autodocs'],
14
+ decorators: [
15
+ (Story) => (
16
+ <ThemeProvider theme={defaultEditorTheme}>
17
+ <Story />
18
+ </ThemeProvider>
19
+ ),
20
+ ],
21
+ } satisfies Meta<typeof GraphRenderer>;
22
+
23
+ export default meta;
24
+ type Story = StoryObj<typeof meta>;
25
+
26
+ /**
27
+ * Helper to create a simple node
28
+ */
29
+ const createNode = (
30
+ id: string,
31
+ x: number,
32
+ y: number,
33
+ label: string,
34
+ color: 1 | 2 | 3 | 4 | 5 | 6 = 4
35
+ ) => ({
36
+ id,
37
+ type: 'text' as const,
38
+ x,
39
+ y,
40
+ width: 120,
41
+ height: 60,
42
+ text: label,
43
+ color,
44
+ pv: {
45
+ nodeType: 'example',
46
+ shape: 'rectangle' as const,
47
+ },
48
+ });
49
+
50
+ /**
51
+ * Canvas showing all edge connection sides
52
+ */
53
+ const edgeSidesCanvas: ExtendedCanvas = {
54
+ nodes: [
55
+ createNode('center', 300, 200, 'Center', 6),
56
+ createNode('top', 300, 50, 'Top', 4),
57
+ createNode('right', 500, 200, 'Right', 4),
58
+ createNode('bottom', 300, 350, 'Bottom', 4),
59
+ createNode('left', 100, 200, 'Left', 4),
60
+ ],
61
+ edges: [
62
+ {
63
+ id: 'top-edge',
64
+ fromNode: 'top',
65
+ toNode: 'center',
66
+ fromSide: 'bottom',
67
+ toSide: 'top',
68
+ pv: { edgeType: 'connection' },
69
+ },
70
+ {
71
+ id: 'right-edge',
72
+ fromNode: 'center',
73
+ toNode: 'right',
74
+ fromSide: 'right',
75
+ toSide: 'left',
76
+ pv: { edgeType: 'connection' },
77
+ },
78
+ {
79
+ id: 'bottom-edge',
80
+ fromNode: 'center',
81
+ toNode: 'bottom',
82
+ fromSide: 'bottom',
83
+ toSide: 'top',
84
+ pv: { edgeType: 'connection' },
85
+ },
86
+ {
87
+ id: 'left-edge',
88
+ fromNode: 'left',
89
+ toNode: 'center',
90
+ fromSide: 'right',
91
+ toSide: 'left',
92
+ pv: { edgeType: 'connection' },
93
+ },
94
+ ],
95
+ pv: {
96
+ version: '1.0.0',
97
+ name: 'Edge Sides Demo',
98
+ description: 'Demonstrating fromSide and toSide fields',
99
+ edgeTypes: {
100
+ connection: {
101
+ style: 'solid',
102
+ color: '#22c55e',
103
+ directed: true,
104
+ },
105
+ },
106
+ },
107
+ };
108
+
109
+ export const EdgeSides: Story = {
110
+ args: {
111
+ canvas: edgeSidesCanvas,
112
+ width: 700,
113
+ height: 500,
114
+ },
115
+ parameters: {
116
+ docs: {
117
+ description: {
118
+ story: `
119
+ **Edge Connection Sides**
120
+
121
+ Edges can connect to any of the 4 sides of a node:
122
+
123
+ - \`fromSide\` - Which side of the source node the edge starts from
124
+ - \`toSide\` - Which side of the target node the edge connects to
125
+
126
+ Values: \`'top'\` | \`'right'\` | \`'bottom'\` | \`'left'\`
127
+
128
+ If not specified, the renderer automatically chooses the best sides.
129
+ `,
130
+ },
131
+ },
132
+ },
133
+ };
134
+
135
+ /**
136
+ * Canvas showing endpoint shapes
137
+ */
138
+ const edgeEndpointsCanvas: ExtendedCanvas = {
139
+ nodes: [
140
+ createNode('a1', 100, 100, 'Source', 5),
141
+ createNode('b1', 350, 100, 'Target', 5),
142
+ createNode('a2', 100, 200, 'Source', 5),
143
+ createNode('b2', 350, 200, 'Target', 5),
144
+ createNode('a3', 100, 300, 'Source', 5),
145
+ createNode('b3', 350, 300, 'Target', 5),
146
+ createNode('a4', 100, 400, 'Source', 5),
147
+ createNode('b4', 350, 400, 'Target', 5),
148
+ ],
149
+ edges: [
150
+ {
151
+ id: 'default',
152
+ fromNode: 'a1',
153
+ toNode: 'b1',
154
+ fromSide: 'right',
155
+ toSide: 'left',
156
+ label: 'default (none → arrow)',
157
+ pv: { edgeType: 'demo' },
158
+ },
159
+ {
160
+ id: 'arrow-arrow',
161
+ fromNode: 'a2',
162
+ toNode: 'b2',
163
+ fromSide: 'right',
164
+ toSide: 'left',
165
+ fromEnd: 'arrow',
166
+ toEnd: 'arrow',
167
+ label: 'arrow → arrow',
168
+ pv: { edgeType: 'demo' },
169
+ },
170
+ {
171
+ id: 'none-none',
172
+ fromNode: 'a3',
173
+ toNode: 'b3',
174
+ fromSide: 'right',
175
+ toSide: 'left',
176
+ fromEnd: 'none',
177
+ toEnd: 'none',
178
+ label: 'none → none',
179
+ pv: { edgeType: 'demo' },
180
+ },
181
+ {
182
+ id: 'arrow-none',
183
+ fromNode: 'a4',
184
+ toNode: 'b4',
185
+ fromSide: 'right',
186
+ toSide: 'left',
187
+ fromEnd: 'arrow',
188
+ toEnd: 'none',
189
+ label: 'arrow → none',
190
+ pv: { edgeType: 'demo' },
191
+ },
192
+ ],
193
+ pv: {
194
+ version: '1.0.0',
195
+ name: 'Edge Endpoints Demo',
196
+ description: 'Demonstrating fromEnd and toEnd fields',
197
+ edgeTypes: {
198
+ demo: {
199
+ style: 'solid',
200
+ color: '#06b6d4',
201
+ directed: true,
202
+ },
203
+ },
204
+ },
205
+ };
206
+
207
+ export const EdgeEndpoints: Story = {
208
+ args: {
209
+ canvas: edgeEndpointsCanvas,
210
+ width: 600,
211
+ height: 550,
212
+ },
213
+ parameters: {
214
+ docs: {
215
+ description: {
216
+ story: `
217
+ **Edge Endpoint Shapes**
218
+
219
+ Control the arrow markers at each end of an edge:
220
+
221
+ - \`fromEnd\` - Shape at the source end (default: \`'none'\`)
222
+ - \`toEnd\` - Shape at the target end (default: \`'arrow'\`)
223
+
224
+ Values: \`'none'\` | \`'arrow'\`
225
+
226
+ This allows creating undirected edges, bidirectional arrows, or reversed arrows.
227
+ `,
228
+ },
229
+ },
230
+ },
231
+ };
232
+
233
+ /**
234
+ * Canvas showing edge colors
235
+ */
236
+ const edgeColorsCanvas: ExtendedCanvas = {
237
+ nodes: [
238
+ createNode('a1', 100, 80, 'Node', 1),
239
+ createNode('b1', 320, 80, 'Node', 1),
240
+ createNode('a2', 100, 160, 'Node', 2),
241
+ createNode('b2', 320, 160, 'Node', 2),
242
+ createNode('a3', 100, 240, 'Node', 3),
243
+ createNode('b3', 320, 240, 'Node', 3),
244
+ createNode('a4', 100, 320, 'Node', 4),
245
+ createNode('b4', 320, 320, 'Node', 4),
246
+ createNode('a5', 100, 400, 'Node', 5),
247
+ createNode('b5', 320, 400, 'Node', 5),
248
+ createNode('a6', 100, 480, 'Node', 6),
249
+ createNode('b6', 320, 480, 'Node', 6),
250
+ ],
251
+ edges: [
252
+ {
253
+ id: 'red',
254
+ fromNode: 'a1',
255
+ toNode: 'b1',
256
+ fromSide: 'right',
257
+ toSide: 'left',
258
+ color: 1,
259
+ label: 'color: 1 (red)',
260
+ pv: { edgeType: 'colored' },
261
+ },
262
+ {
263
+ id: 'orange',
264
+ fromNode: 'a2',
265
+ toNode: 'b2',
266
+ fromSide: 'right',
267
+ toSide: 'left',
268
+ color: 2,
269
+ label: 'color: 2 (orange)',
270
+ pv: { edgeType: 'colored' },
271
+ },
272
+ {
273
+ id: 'yellow',
274
+ fromNode: 'a3',
275
+ toNode: 'b3',
276
+ fromSide: 'right',
277
+ toSide: 'left',
278
+ color: 3,
279
+ label: 'color: 3 (yellow)',
280
+ pv: { edgeType: 'colored' },
281
+ },
282
+ {
283
+ id: 'green',
284
+ fromNode: 'a4',
285
+ toNode: 'b4',
286
+ fromSide: 'right',
287
+ toSide: 'left',
288
+ color: 4,
289
+ label: 'color: 4 (green)',
290
+ pv: { edgeType: 'colored' },
291
+ },
292
+ {
293
+ id: 'cyan',
294
+ fromNode: 'a5',
295
+ toNode: 'b5',
296
+ fromSide: 'right',
297
+ toSide: 'left',
298
+ color: 5,
299
+ label: 'color: 5 (cyan)',
300
+ pv: { edgeType: 'colored' },
301
+ },
302
+ {
303
+ id: 'purple',
304
+ fromNode: 'a6',
305
+ toNode: 'b6',
306
+ fromSide: 'right',
307
+ toSide: 'left',
308
+ color: 6,
309
+ label: 'color: 6 (purple)',
310
+ pv: { edgeType: 'colored' },
311
+ },
312
+ ],
313
+ pv: {
314
+ version: '1.0.0',
315
+ name: 'Edge Colors Demo',
316
+ description: 'Demonstrating edge color presets',
317
+ edgeTypes: {
318
+ colored: {
319
+ style: 'solid',
320
+ directed: true,
321
+ },
322
+ },
323
+ },
324
+ };
325
+
326
+ export const EdgeColors: Story = {
327
+ args: {
328
+ canvas: edgeColorsCanvas,
329
+ width: 550,
330
+ height: 620,
331
+ },
332
+ parameters: {
333
+ docs: {
334
+ description: {
335
+ story: `
336
+ **Edge Colors**
337
+
338
+ Edges support the same color system as nodes:
339
+
340
+ | Preset | Color |
341
+ |--------|---------|
342
+ | 1 | Red |
343
+ | 2 | Orange |
344
+ | 3 | Yellow |
345
+ | 4 | Green |
346
+ | 5 | Cyan |
347
+ | 6 | Purple |
348
+
349
+ You can also use hex strings: \`color: '#3b82f6'\`
350
+ `,
351
+ },
352
+ },
353
+ },
354
+ };
355
+
356
+ /**
357
+ * Canvas showing edge line styles (PV extension)
358
+ */
359
+ const edgeStylesCanvas: ExtendedCanvas = {
360
+ nodes: [
361
+ createNode('a1', 100, 100, 'Source', 6),
362
+ createNode('b1', 380, 100, 'Target', 6),
363
+ createNode('a2', 100, 200, 'Source', 6),
364
+ createNode('b2', 380, 200, 'Target', 6),
365
+ createNode('a3', 100, 300, 'Source', 6),
366
+ createNode('b3', 380, 300, 'Target', 6),
367
+ createNode('a4', 100, 400, 'Source', 6),
368
+ createNode('b4', 380, 400, 'Target', 6),
369
+ ],
370
+ edges: [
371
+ {
372
+ id: 'solid',
373
+ fromNode: 'a1',
374
+ toNode: 'b1',
375
+ fromSide: 'right',
376
+ toSide: 'left',
377
+ label: 'solid',
378
+ pv: { edgeType: 'solid' },
379
+ },
380
+ {
381
+ id: 'dashed',
382
+ fromNode: 'a2',
383
+ toNode: 'b2',
384
+ fromSide: 'right',
385
+ toSide: 'left',
386
+ label: 'dashed',
387
+ pv: { edgeType: 'dashed' },
388
+ },
389
+ {
390
+ id: 'dotted',
391
+ fromNode: 'a3',
392
+ toNode: 'b3',
393
+ fromSide: 'right',
394
+ toSide: 'left',
395
+ label: 'dotted',
396
+ pv: { edgeType: 'dotted' },
397
+ },
398
+ {
399
+ id: 'animated',
400
+ fromNode: 'a4',
401
+ toNode: 'b4',
402
+ fromSide: 'right',
403
+ toSide: 'left',
404
+ label: 'animated',
405
+ pv: { edgeType: 'animated' },
406
+ },
407
+ ],
408
+ pv: {
409
+ version: '1.0.0',
410
+ name: 'Edge Styles Demo',
411
+ description: 'Demonstrating PV edge style extension',
412
+ edgeTypes: {
413
+ solid: {
414
+ style: 'solid',
415
+ color: '#8b5cf6',
416
+ directed: true,
417
+ },
418
+ dashed: {
419
+ style: 'dashed',
420
+ color: '#8b5cf6',
421
+ directed: true,
422
+ },
423
+ dotted: {
424
+ style: 'dotted',
425
+ color: '#8b5cf6',
426
+ directed: true,
427
+ },
428
+ animated: {
429
+ style: 'animated',
430
+ color: '#8b5cf6',
431
+ directed: true,
432
+ animation: {
433
+ type: 'flow',
434
+ duration: 1000,
435
+ },
436
+ },
437
+ },
438
+ },
439
+ };
440
+
441
+ export const EdgeStyles: Story = {
442
+ args: {
443
+ canvas: edgeStylesCanvas,
444
+ width: 600,
445
+ height: 550,
446
+ },
447
+ parameters: {
448
+ docs: {
449
+ description: {
450
+ story: `
451
+ **Edge Line Styles (PV Extension)**
452
+
453
+ The \`pv.style\` field controls line rendering:
454
+
455
+ - \`'solid'\` - Continuous line
456
+ - \`'dashed'\` - Dashed line (- - -)
457
+ - \`'dotted'\` - Dotted line (...)
458
+ - \`'animated'\` - Animated flow effect
459
+
460
+ These styles are defined in \`pv.edgeTypes\` at the canvas level.
461
+ `,
462
+ },
463
+ },
464
+ },
465
+ };
466
+
467
+ /**
468
+ * Canvas showing labeled edges
469
+ */
470
+ const edgeLabelsCanvas: ExtendedCanvas = {
471
+ nodes: [
472
+ createNode('user', 100, 150, 'User', 5),
473
+ createNode('api', 320, 80, 'API', 4),
474
+ createNode('db', 320, 220, 'Database', 4),
475
+ createNode('cache', 540, 150, 'Cache', 3),
476
+ ],
477
+ edges: [
478
+ {
479
+ id: 'user-api',
480
+ fromNode: 'user',
481
+ toNode: 'api',
482
+ fromSide: 'right',
483
+ toSide: 'left',
484
+ label: 'HTTP Request',
485
+ pv: { edgeType: 'request' },
486
+ },
487
+ {
488
+ id: 'api-db',
489
+ fromNode: 'api',
490
+ toNode: 'db',
491
+ fromSide: 'bottom',
492
+ toSide: 'top',
493
+ label: 'Query',
494
+ pv: { edgeType: 'data' },
495
+ },
496
+ {
497
+ id: 'api-cache',
498
+ fromNode: 'api',
499
+ toNode: 'cache',
500
+ fromSide: 'right',
501
+ toSide: 'left',
502
+ label: 'Read/Write',
503
+ pv: { edgeType: 'cache' },
504
+ },
505
+ {
506
+ id: 'cache-db',
507
+ fromNode: 'cache',
508
+ toNode: 'db',
509
+ fromSide: 'bottom',
510
+ toSide: 'right',
511
+ label: 'Sync',
512
+ pv: { edgeType: 'sync' },
513
+ },
514
+ ],
515
+ pv: {
516
+ version: '1.0.0',
517
+ name: 'Edge Labels Demo',
518
+ description: 'Demonstrating edge label field',
519
+ edgeTypes: {
520
+ request: {
521
+ style: 'solid',
522
+ color: '#3b82f6',
523
+ directed: true,
524
+ },
525
+ data: {
526
+ style: 'solid',
527
+ color: '#22c55e',
528
+ directed: true,
529
+ },
530
+ cache: {
531
+ style: 'dashed',
532
+ color: '#eab308',
533
+ directed: true,
534
+ },
535
+ sync: {
536
+ style: 'dotted',
537
+ color: '#f97316',
538
+ directed: true,
539
+ },
540
+ },
541
+ },
542
+ };
543
+
544
+ export const EdgeLabels: Story = {
545
+ args: {
546
+ canvas: edgeLabelsCanvas,
547
+ width: 750,
548
+ height: 400,
549
+ },
550
+ parameters: {
551
+ docs: {
552
+ description: {
553
+ story: `
554
+ **Edge Labels**
555
+
556
+ The \`label\` field adds text to an edge:
557
+
558
+ \`\`\`json
559
+ {
560
+ "id": "user-api",
561
+ "fromNode": "user",
562
+ "toNode": "api",
563
+ "label": "HTTP Request"
564
+ }
565
+ \`\`\`
566
+
567
+ Labels are positioned at the center of the edge and help describe the relationship.
568
+ `,
569
+ },
570
+ },
571
+ },
572
+ };
573
+
574
+ /**
575
+ * Canvas showing edge type definitions
576
+ */
577
+ const edgeTypeDefinitionsCanvas: ExtendedCanvas = {
578
+ nodes: [
579
+ createNode('service-a', 100, 100, 'Service A', 5),
580
+ createNode('service-b', 350, 100, 'Service B', 5),
581
+ createNode('service-c', 100, 250, 'Service C', 5),
582
+ createNode('service-d', 350, 250, 'Service D', 5),
583
+ createNode('service-e', 225, 400, 'Service E', 5),
584
+ ],
585
+ edges: [
586
+ {
587
+ id: 'a-b',
588
+ fromNode: 'service-a',
589
+ toNode: 'service-b',
590
+ fromSide: 'right',
591
+ toSide: 'left',
592
+ label: 'depends-on',
593
+ pv: { edgeType: 'depends-on' },
594
+ },
595
+ {
596
+ id: 'c-d',
597
+ fromNode: 'service-c',
598
+ toNode: 'service-d',
599
+ fromSide: 'right',
600
+ toSide: 'left',
601
+ label: 'publishes-to',
602
+ pv: { edgeType: 'publishes-to' },
603
+ },
604
+ {
605
+ id: 'a-c',
606
+ fromNode: 'service-a',
607
+ toNode: 'service-c',
608
+ fromSide: 'bottom',
609
+ toSide: 'top',
610
+ label: 'calls',
611
+ pv: { edgeType: 'calls' },
612
+ },
613
+ {
614
+ id: 'b-d',
615
+ fromNode: 'service-b',
616
+ toNode: 'service-d',
617
+ fromSide: 'bottom',
618
+ toSide: 'top',
619
+ label: 'inherits',
620
+ pv: { edgeType: 'inherits' },
621
+ },
622
+ {
623
+ id: 'd-e',
624
+ fromNode: 'service-d',
625
+ toNode: 'service-e',
626
+ fromSide: 'bottom',
627
+ toSide: 'right',
628
+ label: 'aggregates',
629
+ pv: { edgeType: 'aggregates' },
630
+ },
631
+ ],
632
+ pv: {
633
+ version: '1.0.0',
634
+ name: 'Edge Type Definitions',
635
+ description: 'Showing canvas-level edgeTypes configuration',
636
+ edgeTypes: {
637
+ 'depends-on': {
638
+ label: 'Dependency',
639
+ style: 'solid',
640
+ color: '#ef4444',
641
+ width: 2,
642
+ directed: true,
643
+ },
644
+ 'publishes-to': {
645
+ label: 'Event Publishing',
646
+ style: 'dashed',
647
+ color: '#22c55e',
648
+ width: 2,
649
+ directed: true,
650
+ },
651
+ calls: {
652
+ label: 'RPC Call',
653
+ style: 'solid',
654
+ color: '#3b82f6',
655
+ width: 1,
656
+ directed: true,
657
+ },
658
+ inherits: {
659
+ label: 'Inheritance',
660
+ style: 'dotted',
661
+ color: '#8b5cf6',
662
+ width: 2,
663
+ directed: true,
664
+ },
665
+ aggregates: {
666
+ label: 'Aggregation',
667
+ style: 'solid',
668
+ color: '#f97316',
669
+ width: 3,
670
+ directed: false,
671
+ },
672
+ },
673
+ },
674
+ };
675
+
676
+ export const EdgeTypeDefinitions: Story = {
677
+ args: {
678
+ canvas: edgeTypeDefinitionsCanvas,
679
+ width: 600,
680
+ height: 550,
681
+ },
682
+ parameters: {
683
+ docs: {
684
+ description: {
685
+ story: `
686
+ **Edge Type Definitions (PV Extension)**
687
+
688
+ Define reusable edge types at the canvas level in \`edgeTypes\`:
689
+
690
+ \`\`\`json
691
+ {
692
+ "edgeTypes": {
693
+ "depends-on": {
694
+ "label": "Dependency",
695
+ "style": "solid",
696
+ "color": "#ef4444",
697
+ "width": 2,
698
+ "directed": true
699
+ }
700
+ }
701
+ }
702
+ \`\`\`
703
+
704
+ **Edge Type Definition Fields:**
705
+ - \`label\` - Display name for the edge type
706
+ - \`style\` - Line style: \`solid\`, \`dashed\`, \`dotted\`, \`animated\`
707
+ - \`color\` - Hex color string
708
+ - \`width\` - Line width in pixels
709
+ - \`directed\` - Whether to show arrow (true/false)
710
+ - \`animation\` - Animation configuration
711
+ - \`labelConfig\` - Label positioning options
712
+ `,
713
+ },
714
+ },
715
+ },
716
+ };
717
+
718
+ /**
719
+ * Interactive comparison template
720
+ */
721
+ const EdgeFieldsComparisonTemplate = () => {
722
+ return (
723
+ <div style={{ padding: 20, fontFamily: 'system-ui' }}>
724
+ <h2 style={{ marginBottom: 20 }}>JSON Canvas Edge Fields Reference</h2>
725
+
726
+ <h3 style={{ marginTop: 24, marginBottom: 12 }}>Standard JSON Canvas Fields</h3>
727
+ <table
728
+ style={{
729
+ width: '100%',
730
+ borderCollapse: 'collapse',
731
+ fontSize: 13,
732
+ marginBottom: 24,
733
+ }}
734
+ >
735
+ <thead>
736
+ <tr style={{ backgroundColor: '#f3f4f6' }}>
737
+ <th style={{ padding: 10, textAlign: 'left', border: '1px solid #e5e7eb' }}>Field</th>
738
+ <th style={{ padding: 10, textAlign: 'left', border: '1px solid #e5e7eb' }}>Type</th>
739
+ <th style={{ padding: 10, textAlign: 'left', border: '1px solid #e5e7eb' }}>
740
+ Required
741
+ </th>
742
+ <th style={{ padding: 10, textAlign: 'left', border: '1px solid #e5e7eb' }}>
743
+ Description
744
+ </th>
745
+ </tr>
746
+ </thead>
747
+ <tbody>
748
+ <tr>
749
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
750
+ <code>id</code>
751
+ </td>
752
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>string</td>
753
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>Yes</td>
754
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>Unique identifier</td>
755
+ </tr>
756
+ <tr>
757
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
758
+ <code>fromNode</code>
759
+ </td>
760
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>string</td>
761
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>Yes</td>
762
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>Source node ID</td>
763
+ </tr>
764
+ <tr>
765
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
766
+ <code>toNode</code>
767
+ </td>
768
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>string</td>
769
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>Yes</td>
770
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>Target node ID</td>
771
+ </tr>
772
+ <tr>
773
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
774
+ <code>fromSide</code>
775
+ </td>
776
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
777
+ 'top' | 'right' | 'bottom' | 'left'
778
+ </td>
779
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>No</td>
780
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
781
+ Side of source node to connect from
782
+ </td>
783
+ </tr>
784
+ <tr>
785
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
786
+ <code>toSide</code>
787
+ </td>
788
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
789
+ 'top' | 'right' | 'bottom' | 'left'
790
+ </td>
791
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>No</td>
792
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
793
+ Side of target node to connect to
794
+ </td>
795
+ </tr>
796
+ <tr>
797
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
798
+ <code>fromEnd</code>
799
+ </td>
800
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>'none' | 'arrow'</td>
801
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>No</td>
802
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
803
+ Endpoint shape at source (default: 'none')
804
+ </td>
805
+ </tr>
806
+ <tr>
807
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
808
+ <code>toEnd</code>
809
+ </td>
810
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>'none' | 'arrow'</td>
811
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>No</td>
812
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
813
+ Endpoint shape at target (default: 'arrow')
814
+ </td>
815
+ </tr>
816
+ <tr>
817
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
818
+ <code>color</code>
819
+ </td>
820
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>string | 1-6</td>
821
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>No</td>
822
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
823
+ Hex color or preset (1=red, 2=orange, 3=yellow, 4=green, 5=cyan, 6=purple)
824
+ </td>
825
+ </tr>
826
+ <tr>
827
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
828
+ <code>label</code>
829
+ </td>
830
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>string</td>
831
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>No</td>
832
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
833
+ Text label displayed on edge
834
+ </td>
835
+ </tr>
836
+ </tbody>
837
+ </table>
838
+
839
+ <h3 style={{ marginTop: 24, marginBottom: 12 }}>Principal View Extension Fields (pv)</h3>
840
+ <table
841
+ style={{
842
+ width: '100%',
843
+ borderCollapse: 'collapse',
844
+ fontSize: 13,
845
+ marginBottom: 24,
846
+ }}
847
+ >
848
+ <thead>
849
+ <tr style={{ backgroundColor: '#ede9fe' }}>
850
+ <th style={{ padding: 10, textAlign: 'left', border: '1px solid #e5e7eb' }}>Field</th>
851
+ <th style={{ padding: 10, textAlign: 'left', border: '1px solid #e5e7eb' }}>Type</th>
852
+ <th style={{ padding: 10, textAlign: 'left', border: '1px solid #e5e7eb' }}>
853
+ Description
854
+ </th>
855
+ </tr>
856
+ </thead>
857
+ <tbody>
858
+ <tr>
859
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
860
+ <code>pv.edgeType</code>
861
+ </td>
862
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>string</td>
863
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
864
+ References an edge type defined in canvas pv.edgeTypes
865
+ </td>
866
+ </tr>
867
+ <tr>
868
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
869
+ <code>pv.style</code>
870
+ </td>
871
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
872
+ 'solid' | 'dashed' | 'dotted' | 'animated'
873
+ </td>
874
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>Line style override</td>
875
+ </tr>
876
+ <tr>
877
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
878
+ <code>pv.width</code>
879
+ </td>
880
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>number</td>
881
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>Line width in pixels</td>
882
+ </tr>
883
+ <tr>
884
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
885
+ <code>pv.animation</code>
886
+ </td>
887
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>object</td>
888
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
889
+ Animation config: {'{'}type, duration, color{'}'}
890
+ </td>
891
+ </tr>
892
+ <tr>
893
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
894
+ <code>pv.activatedBy</code>
895
+ </td>
896
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>array</td>
897
+ <td style={{ padding: 10, border: '1px solid #e5e7eb' }}>
898
+ Event triggers for edge activation
899
+ </td>
900
+ </tr>
901
+ </tbody>
902
+ </table>
903
+
904
+ <h3 style={{ marginTop: 24, marginBottom: 12 }}>Canvas-Level Edge Type Definition</h3>
905
+ <div
906
+ style={{
907
+ backgroundColor: '#1e1e1e',
908
+ color: '#d4d4d4',
909
+ padding: 16,
910
+ borderRadius: 8,
911
+ fontSize: 12,
912
+ fontFamily: 'monospace',
913
+ overflow: 'auto',
914
+ }}
915
+ >
916
+ <pre style={{ margin: 0 }}>
917
+ {`{
918
+ "edgeTypes": {
919
+ "depends-on": {
920
+ "label": "Dependency", // Display name
921
+ "style": "solid", // solid | dashed | dotted | animated
922
+ "color": "#ef4444", // Hex color
923
+ "width": 2, // Line width in pixels
924
+ "directed": true, // Show arrow head
925
+ "animation": { // Optional animation
926
+ "type": "flow", // flow | pulse | particle | glow
927
+ "duration": 1000, // Duration in ms
928
+ "color": "#ff0000" // Animation color
929
+ },
930
+ "labelConfig": { // Label positioning
931
+ "field": "weight", // Data field to display
932
+ "position": "middle" // start | middle | end
933
+ }
934
+ }
935
+ }
936
+ }`}
937
+ </pre>
938
+ </div>
939
+
940
+ <h3 style={{ marginTop: 32, marginBottom: 16 }}>Live Example</h3>
941
+ <GraphRenderer canvas={edgeLabelsCanvas} width={750} height={350} />
942
+
943
+ <div
944
+ style={{
945
+ marginTop: 24,
946
+ padding: 16,
947
+ backgroundColor: '#f5f5f5',
948
+ borderRadius: 8,
949
+ }}
950
+ >
951
+ <h4 style={{ margin: '0 0 12px 0' }}>JSON Canvas Spec</h4>
952
+ <p style={{ fontSize: 13, margin: 0, lineHeight: 1.6 }}>
953
+ Standard edge fields follow the{' '}
954
+ <a
955
+ href="https://jsoncanvas.org/"
956
+ target="_blank"
957
+ rel="noopener noreferrer"
958
+ style={{ color: '#3b82f6' }}
959
+ >
960
+ JSON Canvas specification
961
+ </a>
962
+ . Principal View extensions are stored in the <code>pv</code> field and provide enhanced
963
+ rendering capabilities while maintaining compatibility with standard canvas tools.
964
+ </p>
965
+ </div>
966
+ </div>
967
+ );
968
+ };
969
+
970
+ export const EdgeFieldsReference: Story = {
971
+ render: () => <EdgeFieldsComparisonTemplate />,
972
+ parameters: {
973
+ docs: {
974
+ description: {
975
+ story: 'Complete reference for all JSON Canvas edge fields and Principal View extensions.',
976
+ },
977
+ },
978
+ },
979
+ };
980
+
981
+ /**
982
+ * Canvas showing edge reconnection scenario from admin-dashboard
983
+ * Tests moving an edge from left to right of the same node
984
+ */
985
+ const edgeReconnectionCanvas: ExtendedCanvas = {
986
+ nodes: [
987
+ {
988
+ id: 'client-components',
989
+ type: 'text' as const,
990
+ x: 100,
991
+ y: 200,
992
+ width: 200,
993
+ height: 100,
994
+ text: 'Client Components\n\nReact Query\nURL state (nuqs)\nReal-time updates',
995
+ color: '#06B6D4',
996
+ },
997
+ {
998
+ id: 'api-routes',
999
+ type: 'text' as const,
1000
+ x: 400,
1001
+ y: 200,
1002
+ width: 220,
1003
+ height: 180,
1004
+ text: 'API Routes Layer\n\n• /api/otel/*\n• /api/dashboards/*\n• /api/teams/*\n• /api/github/*\n• /api/sentry/*\n• /api/billing/*\n• /api/bug-fix-agent/*',
1005
+ color: '#F59E0B',
1006
+ },
1007
+ {
1008
+ id: 'pages-layer',
1009
+ type: 'text' as const,
1010
+ x: 700,
1011
+ y: 100,
1012
+ width: 220,
1013
+ height: 180,
1014
+ text: 'Pages Layer\n\n• Dashboard (/, /dashboards)\n• Sessions (/sessions)\n• Events (/events)\n• Teams (/teams)\n• Integrations (/integrations)\n• Billing (/billing)',
1015
+ color: '#10B981',
1016
+ },
1017
+ ],
1018
+ edges: [
1019
+ {
1020
+ id: 'e8',
1021
+ fromNode: 'client-components',
1022
+ toNode: 'api-routes',
1023
+ fromSide: 'right',
1024
+ toSide: 'left',
1025
+ label: 'React Query',
1026
+ pv: {
1027
+ edgeType: 'httpRest',
1028
+ },
1029
+ },
1030
+ {
1031
+ id: 'e4',
1032
+ fromNode: 'pages-layer',
1033
+ toNode: 'api-routes',
1034
+ fromSide: 'left',
1035
+ toSide: 'right',
1036
+ label: 'SSR',
1037
+ pv: {
1038
+ edgeType: 'httpRest',
1039
+ },
1040
+ },
1041
+ ],
1042
+ pv: {
1043
+ version: '1.0.0',
1044
+ name: 'Edge Reconnection Test - Admin Dashboard Scenario',
1045
+ description: 'Reproduces the httpRest edge reconnection issue when moving edge from left to right of same node',
1046
+ edgeTypes: {
1047
+ httpRest: {
1048
+ style: 'solid',
1049
+ color: '#3b82f6',
1050
+ directed: true,
1051
+ },
1052
+ },
1053
+ },
1054
+ };
1055
+
1056
+ export const EdgeReconnectionScenario: Story = {
1057
+ args: {
1058
+ canvas: edgeReconnectionCanvas,
1059
+ width: 1100,
1060
+ height: 500,
1061
+ editable: true,
1062
+ },
1063
+ parameters: {
1064
+ docs: {
1065
+ description: {
1066
+ story: `
1067
+ **Edge Reconnection Test - Admin Dashboard Scenario**
1068
+
1069
+ This story reproduces the issue from the admin-dashboard.canvas file where:
1070
+
1071
+ 1. We have text nodes connected by httpRest edges
1072
+ 2. Edge e8 connects client-components → api-routes (left → right)
1073
+ 3. Edge e4 connects pages-layer → api-routes (left → right)
1074
+
1075
+ **To Test the Bug:**
1076
+ Try to reconnect edge e8 or e4 to different sides of the api-routes node.
1077
+ You may see the error: "Cannot reconnect: httpRest edge not allowed from text to text"
1078
+
1079
+ **Root Cause:**
1080
+ The validation checks \`allowedConnections\` which is built from existing edges.
1081
+ When nodes don't have \`pv.nodeType\`, the system uses node IDs instead of node types,
1082
+ causing validation to fail when reconnecting edges between different node pairs.
1083
+
1084
+ **Expected Behavior:**
1085
+ Edges with edgeType "httpRest" should be allowed to reconnect between any text nodes,
1086
+ regardless of which specific nodes are connected.
1087
+ `,
1088
+ },
1089
+ },
1090
+ },
1091
+ };
1092
+
1093
+ /**
1094
+ * Full Admin Dashboard canvas data for comprehensive testing
1095
+ * Includes multiple httpRest edges and various node types
1096
+ */
1097
+ const adminDashboardFullCanvas: ExtendedCanvas = {
1098
+ nodes: [
1099
+ {
1100
+ id: 'user-browser',
1101
+ type: 'text' as const,
1102
+ text: 'User Browser\n\nNext.js 16 React App',
1103
+ x: 92,
1104
+ y: 374,
1105
+ width: 180,
1106
+ height: 80,
1107
+ color: '#3B82F6',
1108
+ },
1109
+ {
1110
+ id: 'pages-layer',
1111
+ type: 'text' as const,
1112
+ text: 'Pages Layer\n\n• Dashboard (/, /dashboards)\n• Sessions (/sessions)\n• Events (/events)',
1113
+ x: 400,
1114
+ y: 100,
1115
+ width: 220,
1116
+ height: 180,
1117
+ color: '#10B981',
1118
+ },
1119
+ {
1120
+ id: 'api-routes',
1121
+ type: 'text' as const,
1122
+ text: 'API Routes Layer\n\n• /api/otel/*\n• /api/dashboards/*\n• /api/teams/*\n• /api/github/*',
1123
+ x: 400,
1124
+ y: 320,
1125
+ width: 220,
1126
+ height: 180,
1127
+ color: '#F59E0B',
1128
+ },
1129
+ {
1130
+ id: 'server-components',
1131
+ type: 'text' as const,
1132
+ text: 'Server Components\n\nSSR data fetching\nDirect DB queries',
1133
+ x: 700,
1134
+ y: 63,
1135
+ width: 200,
1136
+ height: 100,
1137
+ color: '#06B6D4',
1138
+ },
1139
+ {
1140
+ id: 'client-components',
1141
+ type: 'text' as const,
1142
+ text: 'Client Components\n\nReact Query\nURL state (nuqs)',
1143
+ x: 700,
1144
+ y: 230,
1145
+ width: 200,
1146
+ height: 100,
1147
+ color: '#06B6D4',
1148
+ },
1149
+ {
1150
+ id: 'postgresql',
1151
+ type: 'text' as const,
1152
+ text: 'PostgreSQL\n\nDrizzle ORM\nUsers, orgs, teams',
1153
+ x: 1000,
1154
+ y: 124,
1155
+ width: 200,
1156
+ height: 120,
1157
+ color: '#336791',
1158
+ },
1159
+ ],
1160
+ edges: [
1161
+ {
1162
+ id: 'e2',
1163
+ fromNode: 'user-browser',
1164
+ toNode: 'pages-layer',
1165
+ fromSide: 'right',
1166
+ toSide: 'left',
1167
+ label: 'Navigate',
1168
+ pv: { edgeType: 'httpRest' },
1169
+ },
1170
+ {
1171
+ id: 'e3',
1172
+ fromNode: 'user-browser',
1173
+ toNode: 'api-routes',
1174
+ fromSide: 'right',
1175
+ toSide: 'left',
1176
+ label: 'API calls',
1177
+ pv: { edgeType: 'httpRest' },
1178
+ },
1179
+ {
1180
+ id: 'e4',
1181
+ fromNode: 'pages-layer',
1182
+ toNode: 'server-components',
1183
+ fromSide: 'right',
1184
+ toSide: 'left',
1185
+ label: 'SSR',
1186
+ pv: { edgeType: 'httpRest' },
1187
+ },
1188
+ {
1189
+ id: 'e5',
1190
+ fromNode: 'pages-layer',
1191
+ toNode: 'client-components',
1192
+ fromSide: 'right',
1193
+ toSide: 'left',
1194
+ label: 'Hydrate',
1195
+ pv: { edgeType: 'httpRest' },
1196
+ },
1197
+ {
1198
+ id: 'e6',
1199
+ fromNode: 'server-components',
1200
+ toNode: 'postgresql',
1201
+ fromSide: 'right',
1202
+ toSide: 'left',
1203
+ label: 'Drizzle ORM',
1204
+ pv: { edgeType: 'postgresQuery' },
1205
+ },
1206
+ {
1207
+ id: 'e8',
1208
+ fromNode: 'client-components',
1209
+ toNode: 'api-routes',
1210
+ fromSide: 'left',
1211
+ toSide: 'right',
1212
+ label: 'React Query',
1213
+ pv: { edgeType: 'httpRest' },
1214
+ },
1215
+ {
1216
+ id: 'e9',
1217
+ fromNode: 'api-routes',
1218
+ toNode: 'postgresql',
1219
+ fromSide: 'right',
1220
+ toSide: 'left',
1221
+ label: 'Drizzle ORM',
1222
+ pv: { edgeType: 'postgresQuery' },
1223
+ },
1224
+ ],
1225
+ pv: {
1226
+ version: '1.0.0',
1227
+ name: 'Admin Dashboard Architecture (Simplified)',
1228
+ description: 'Simplified version of admin-dashboard.canvas to test edge reconnection issues',
1229
+ edgeTypes: {
1230
+ httpRest: {
1231
+ style: 'solid',
1232
+ color: '#3b82f6',
1233
+ directed: true,
1234
+ },
1235
+ postgresQuery: {
1236
+ style: 'solid',
1237
+ color: '#336791',
1238
+ directed: true,
1239
+ },
1240
+ },
1241
+ },
1242
+ };
1243
+
1244
+ export const AdminDashboardFull: Story = {
1245
+ args: {
1246
+ canvas: adminDashboardFullCanvas,
1247
+ width: 1400,
1248
+ height: 650,
1249
+ editable: true,
1250
+ },
1251
+ parameters: {
1252
+ docs: {
1253
+ description: {
1254
+ story: `
1255
+ **Full Admin Dashboard Architecture Test**
1256
+
1257
+ This is a simplified version of the actual admin-dashboard.canvas file from /Users/griever/Developer/observability.
1258
+
1259
+ **Key Test Cases:**
1260
+
1261
+ 1. **Edge e8 (client-components → api-routes)**:
1262
+ - Currently connects from LEFT side of client-components to RIGHT side of api-routes
1263
+ - Try dragging the edge handle to connect from RIGHT side instead
1264
+ - Expected: Should work seamlessly
1265
+ - Actual: May fail with "Cannot reconnect: httpRest edge not allowed from text to text"
1266
+
1267
+ 2. **Multiple httpRest edges**:
1268
+ - Notice that e2, e3, e4, e5, and e8 all use edgeType "httpRest"
1269
+ - They connect various text nodes together
1270
+ - Try reconnecting any of these edges to different nodes or different sides
1271
+
1272
+ 3. **Mixed edge types**:
1273
+ - Some edges use "httpRest", others use "postgresQuery"
1274
+ - This tests that the validation correctly distinguishes between different edge types
1275
+
1276
+ **The Issue:**
1277
+ The \`allowedConnections\` array is built by mapping each edge to its specific source and target node IDs.
1278
+ This means edge e8's allowed connection is registered as:
1279
+ \`\`\`
1280
+ { from: "client-components", to: "api-routes", via: "httpRest" }
1281
+ \`\`\`
1282
+
1283
+ When you try to reconnect this edge to a different node pair (even with the same node types),
1284
+ the validation fails because it's checking node IDs, not node types.
1285
+
1286
+ **Enable editing mode** to test the reconnection behavior.
1287
+ `,
1288
+ },
1289
+ },
1290
+ },
1291
+ };
1292
+
1293
+ /**
1294
+ * Canvas for testing scenario sequence labels on edges
1295
+ */
1296
+ const sequenceLabelsCanvas: ExtendedCanvas = {
1297
+ nodes: [
1298
+ createNode('client', 100, 150, 'Client', 5),
1299
+ createNode('gateway', 300, 150, 'API Gateway', 4),
1300
+ createNode('auth', 500, 80, 'Auth Service', 3),
1301
+ createNode('database', 500, 220, 'Database', 6),
1302
+ createNode('cache', 700, 150, 'Cache', 2),
1303
+ ],
1304
+ edges: [
1305
+ {
1306
+ id: 'client-gateway',
1307
+ fromNode: 'client',
1308
+ toNode: 'gateway',
1309
+ fromSide: 'right',
1310
+ toSide: 'left',
1311
+ pv: { edgeType: 'request' },
1312
+ },
1313
+ {
1314
+ id: 'gateway-auth',
1315
+ fromNode: 'gateway',
1316
+ toNode: 'auth',
1317
+ fromSide: 'right',
1318
+ toSide: 'left',
1319
+ pv: { edgeType: 'request' },
1320
+ },
1321
+ {
1322
+ id: 'gateway-database',
1323
+ fromNode: 'gateway',
1324
+ toNode: 'database',
1325
+ fromSide: 'right',
1326
+ toSide: 'left',
1327
+ pv: { edgeType: 'request' },
1328
+ },
1329
+ {
1330
+ id: 'database-cache',
1331
+ fromNode: 'database',
1332
+ toNode: 'cache',
1333
+ fromSide: 'right',
1334
+ toSide: 'left',
1335
+ pv: { edgeType: 'request' },
1336
+ },
1337
+ ],
1338
+ pv: {
1339
+ version: '1.0.0',
1340
+ name: 'Sequence Labels Demo',
1341
+ description: 'Demonstrating scenario-based sequence labels on edges',
1342
+ edgeTypes: {
1343
+ request: {
1344
+ style: 'solid',
1345
+ color: '#3b82f6',
1346
+ directed: true,
1347
+ },
1348
+ },
1349
+ },
1350
+ };
1351
+
1352
+ /**
1353
+ * Scenario edges representing execution order
1354
+ * These would normally come from deriveEdgesFromSequence()
1355
+ */
1356
+ const mockScenarioEdges: Array<{ fromSpan: string; toSpan: string; sequenceNumber: number }> = [
1357
+ { fromSpan: 'client', toSpan: 'gateway', sequenceNumber: 1 },
1358
+ { fromSpan: 'gateway', toSpan: 'auth', sequenceNumber: 2 },
1359
+ { fromSpan: 'gateway', toSpan: 'database', sequenceNumber: 3 },
1360
+ { fromSpan: 'database', toSpan: 'cache', sequenceNumber: 4 },
1361
+ ];
1362
+
1363
+ /**
1364
+ * Interactive component to toggle sequence labels
1365
+ */
1366
+ const SequenceLabelsDemo = () => {
1367
+ const [showLabels, setShowLabels] = useState(true);
1368
+ const [useScenario, setUseScenario] = useState(true);
1369
+
1370
+ return (
1371
+ <div>
1372
+ <div style={{ marginBottom: 16, display: 'flex', gap: 16 }}>
1373
+ <label style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
1374
+ <input
1375
+ type="checkbox"
1376
+ checked={useScenario}
1377
+ onChange={(e) => setUseScenario(e.target.checked)}
1378
+ />
1379
+ Pass scenarioEdges
1380
+ </label>
1381
+ <label style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
1382
+ <input
1383
+ type="checkbox"
1384
+ checked={showLabels}
1385
+ onChange={(e) => setShowLabels(e.target.checked)}
1386
+ />
1387
+ showSequenceLabels
1388
+ </label>
1389
+ </div>
1390
+ <GraphRenderer
1391
+ canvas={sequenceLabelsCanvas}
1392
+ scenarioEdges={useScenario ? mockScenarioEdges : undefined}
1393
+ showSequenceLabels={showLabels}
1394
+ width={900}
1395
+ height={400}
1396
+ />
1397
+ <div style={{ marginTop: 16, fontSize: 13, color: '#666' }}>
1398
+ <strong>scenarioEdges:</strong>{' '}
1399
+ {useScenario ? (
1400
+ <pre style={{ margin: '8px 0', fontSize: 12, background: '#f5f5f5', padding: 12, borderRadius: 4 }}>
1401
+ {JSON.stringify(mockScenarioEdges, null, 2)}
1402
+ </pre>
1403
+ ) : (
1404
+ 'undefined'
1405
+ )}
1406
+ </div>
1407
+ </div>
1408
+ );
1409
+ };
1410
+
1411
+ export const SequenceLabels: Story = {
1412
+ render: () => <SequenceLabelsDemo />,
1413
+ parameters: {
1414
+ docs: {
1415
+ description: {
1416
+ story: `
1417
+ **Scenario Sequence Labels**
1418
+
1419
+ When a workflow scenario is selected, edges can display sequence numbers showing the execution order.
1420
+
1421
+ **Usage:**
1422
+
1423
+ \`\`\`tsx
1424
+ import { extractEventSpans, deriveEdgesFromSequence } from '@principal-ai/subsystems-core';
1425
+
1426
+ // Get scenario edges with sequence numbers
1427
+ const eventSpans = extractEventSpans(selectedScenario, rootSpan);
1428
+ const scenarioEdges = deriveEdgesFromSequence(eventSpans, selectedScenario.id);
1429
+
1430
+ // Pass to GraphRenderer
1431
+ <GraphRenderer
1432
+ canvas={canvas}
1433
+ scenarioEdges={scenarioEdges}
1434
+ showSequenceLabels={true} // default
1435
+ />
1436
+ \`\`\`
1437
+
1438
+ **Props:**
1439
+
1440
+ - \`scenarioEdges\` - Array of \`{ fromSpan, toSpan, sequenceNumber }\` from edge derivation
1441
+ - \`showSequenceLabels\` - Toggle visibility (default: true)
1442
+
1443
+ The sequence numbers help users understand the order of operations in a workflow scenario.
1444
+ `,
1445
+ },
1446
+ },
1447
+ },
1448
+ };