symbiote-ui 0.3.0-alpha.4

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 (322) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/LICENSE +21 -0
  3. package/README.md +76 -0
  4. package/canvas/AutoLayout.js +731 -0
  5. package/canvas/Breadcrumb/Breadcrumb.css.js +75 -0
  6. package/canvas/Breadcrumb/Breadcrumb.js +96 -0
  7. package/canvas/Breadcrumb/Breadcrumb.tpl.js +7 -0
  8. package/canvas/CanvasConnectionRenderer.js +971 -0
  9. package/canvas/CanvasGraph/CanvasGraph.css.js +29 -0
  10. package/canvas/CanvasGraph/CanvasGraph.js +1697 -0
  11. package/canvas/CanvasGraph/CanvasGraphDrawState.js +280 -0
  12. package/canvas/CanvasGraph/CanvasGraphGeometry.js +194 -0
  13. package/canvas/CanvasViewport.js +550 -0
  14. package/canvas/ConnectionRenderer.js +1283 -0
  15. package/canvas/FlowSimulator.js +326 -0
  16. package/canvas/ForceLayout.js +226 -0
  17. package/canvas/ForceWorker.js +1303 -0
  18. package/canvas/FrameManager.js +223 -0
  19. package/canvas/GraphExplorerShell/GraphExplorerShell.css.js +136 -0
  20. package/canvas/GraphExplorerShell/GraphExplorerShell.js +129 -0
  21. package/canvas/GraphExplorerShell/GraphExplorerShell.tpl.js +12 -0
  22. package/canvas/GraphTabs/GraphTabs.css.js +101 -0
  23. package/canvas/GraphTabs/GraphTabs.js +189 -0
  24. package/canvas/GraphTabs/GraphTabs.tpl.js +12 -0
  25. package/canvas/LODManager.js +88 -0
  26. package/canvas/Minimap/Minimap.css.js +73 -0
  27. package/canvas/Minimap/Minimap.js +210 -0
  28. package/canvas/Minimap/Minimap.tpl.js +7 -0
  29. package/canvas/NodeCanvas/NodeCanvas.css.js +398 -0
  30. package/canvas/NodeCanvas/NodeCanvas.js +1499 -0
  31. package/canvas/NodeCanvas/NodeCanvas.tpl.js +22 -0
  32. package/canvas/NodeSearch/NodeSearch.css.js +97 -0
  33. package/canvas/NodeSearch/NodeSearch.js +140 -0
  34. package/canvas/NodeSearch/NodeSearch.tpl.js +25 -0
  35. package/canvas/NodeViewManager.js +748 -0
  36. package/canvas/PcbRouteDiagnostics.js +463 -0
  37. package/canvas/PcbRouter.js +1127 -0
  38. package/canvas/PinExpansion.js +134 -0
  39. package/canvas/PseudoConnection.js +84 -0
  40. package/canvas/SelectionSync.js +163 -0
  41. package/canvas/SubgraphManager.js +203 -0
  42. package/canvas/SubgraphRouter.js +452 -0
  43. package/canvas/ViewportActions.js +473 -0
  44. package/canvas/graph-explorer.js +339 -0
  45. package/canvas/graph-layout.js +148 -0
  46. package/canvas/graph-model.js +68 -0
  47. package/canvas/html-in-canvas.js +202 -0
  48. package/canvas/project-graph-builder.js +440 -0
  49. package/canvas/project-graph-model.js +183 -0
  50. package/chat/ChatComposer/ChatComposer.css.js +652 -0
  51. package/chat/ChatComposer/ChatComposer.js +304 -0
  52. package/chat/ChatList/ChatList.css.js +102 -0
  53. package/chat/ChatList/ChatList.js +99 -0
  54. package/chat/ChatList/ChatList.tpl.js +20 -0
  55. package/chat/ChatListItem/ChatListItem.css.js +117 -0
  56. package/chat/ChatListItem/ChatListItem.js +32 -0
  57. package/chat/ChatListItem/ChatListItem.tpl.js +17 -0
  58. package/chat/ChatMessageItem/ChatMessageItem.css.js +628 -0
  59. package/chat/ChatMessageItem/ChatMessageItem.js +156 -0
  60. package/chat/ChatSidebar/ChatSidebar.css.js +150 -0
  61. package/chat/ChatSidebar/ChatSidebar.js +230 -0
  62. package/chat/ChatSidebar/ChatSidebar.tpl.js +18 -0
  63. package/chat/ChatSidebar/constants.js +11 -0
  64. package/chat/ChatSidebarItem/ChatSidebarItem.css.js +445 -0
  65. package/chat/ChatSidebarItem/ChatSidebarItem.js +304 -0
  66. package/chat/ChatTranscript/ChatTranscript.css.js +90 -0
  67. package/chat/ChatTranscript/ChatTranscript.js +244 -0
  68. package/chat/chat-context.js +123 -0
  69. package/chat/message-model.js +156 -0
  70. package/cli.js +20 -0
  71. package/control/Button/Button.css.js +93 -0
  72. package/control/Button/Button.js +78 -0
  73. package/control/Button/Button.tpl.js +3 -0
  74. package/control/Field/Field.css.js +91 -0
  75. package/control/Field/Field.js +17 -0
  76. package/control/Field/Field.tpl.js +3 -0
  77. package/core/Connection.js +47 -0
  78. package/core/Editor.js +449 -0
  79. package/core/Frame.js +33 -0
  80. package/core/GraphMermaid.js +348 -0
  81. package/core/GraphText.js +228 -0
  82. package/core/Node.js +145 -0
  83. package/core/Portal.js +106 -0
  84. package/core/Socket.js +187 -0
  85. package/core/SubgraphNode.js +121 -0
  86. package/core/base-path.js +55 -0
  87. package/core/dom-utils.js +14 -0
  88. package/core/index.js +18 -0
  89. package/core/local-cache.js +26 -0
  90. package/core/state-sync.js +227 -0
  91. package/custom-elements.json +6380 -0
  92. package/discover.js +240 -0
  93. package/display/Badge/Badge.css.js +44 -0
  94. package/display/Badge/Badge.js +17 -0
  95. package/display/Badge/Badge.tpl.js +3 -0
  96. package/display/Banner/Banner.css.js +61 -0
  97. package/display/Banner/Banner.js +17 -0
  98. package/display/Banner/Banner.tpl.js +3 -0
  99. package/display/CodeBlock/CodeBlock.css.js +194 -0
  100. package/display/CodeBlock/CodeBlock.js +220 -0
  101. package/display/CodeBlock/CodeBlock.tpl.js +11 -0
  102. package/display/DataTable/DataTable.css.js +101 -0
  103. package/display/DataTable/DataTable.js +136 -0
  104. package/display/DataTable/DataTable.tpl.js +13 -0
  105. package/display/EmptyState/EmptyState.css.js +33 -0
  106. package/display/EmptyState/EmptyState.js +17 -0
  107. package/display/EmptyState/EmptyState.tpl.js +3 -0
  108. package/display/EventFeed/EventFeed.css.js +145 -0
  109. package/display/EventFeed/EventFeed.js +64 -0
  110. package/display/EventFeed/EventFeed.tpl.js +14 -0
  111. package/display/EventFeed/EventFeedItem.js +116 -0
  112. package/display/EventFeed/EventFeedItem.tpl.js +22 -0
  113. package/display/LoadingOverlay/LoadingOverlay.css.js +91 -0
  114. package/display/LoadingOverlay/LoadingOverlay.js +48 -0
  115. package/display/LoadingOverlay/LoadingOverlay.tpl.js +12 -0
  116. package/display/Metric/Metric.css.js +60 -0
  117. package/display/Metric/Metric.js +17 -0
  118. package/display/Metric/Metric.tpl.js +6 -0
  119. package/display/OutputGraphPreview/OutputGraphPreview.css.js +122 -0
  120. package/display/OutputGraphPreview/OutputGraphPreview.js +89 -0
  121. package/display/OutputGraphPreview/OutputGraphPreview.tpl.js +13 -0
  122. package/display/OutputListPreview/OutputListPreview.css.js +109 -0
  123. package/display/OutputListPreview/OutputListPreview.js +77 -0
  124. package/display/OutputListPreview/OutputListPreview.tpl.js +13 -0
  125. package/display/SourceEditor/SourceEditor.css.js +39 -0
  126. package/display/SourceEditor/SourceEditor.js +129 -0
  127. package/display/SourceEditor/SourceEditor.tpl.js +10 -0
  128. package/display/SourceViewer/SourceViewer.css.js +80 -0
  129. package/display/SourceViewer/SourceViewer.js +418 -0
  130. package/display/SourceViewer/SourceViewer.tpl.js +17 -0
  131. package/display/StatusRibbon/StatusRibbon.css.js +73 -0
  132. package/display/StatusRibbon/StatusRibbon.js +87 -0
  133. package/display/StatusRibbon/StatusRibbon.tpl.js +7 -0
  134. package/display/event-feed-adapter.js +72 -0
  135. package/display/format-utils.js +29 -0
  136. package/display/highlight.js +659 -0
  137. package/display/icons.js +37 -0
  138. package/display/markdown-formatter.js +60 -0
  139. package/display/network-approval-page.js +487 -0
  140. package/display/output-preview.js +261 -0
  141. package/effects/CellBg/CellBg.css.js +33 -0
  142. package/effects/CellBg/CellBg.js +410 -0
  143. package/effects/CellBg/CellBg.tpl.js +5 -0
  144. package/graph/canvas-adapter.js +223 -0
  145. package/graph/graph-algorithms.js +31 -0
  146. package/graph/index.js +46 -0
  147. package/graph/model.js +176 -0
  148. package/graph/project-graph-build.js +66 -0
  149. package/graph/project-graph-metadata.js +253 -0
  150. package/graph/project-package.js +128 -0
  151. package/graph/project-runtime.js +116 -0
  152. package/graph/project-transaction.js +284 -0
  153. package/graph/skeleton-utils.js +84 -0
  154. package/graph/theme-contract.js +36 -0
  155. package/graph/transaction-parser.js +56 -0
  156. package/icons/MaterialSymbols.js +69 -0
  157. package/icons/material-symbols-outlined-400.ttf +0 -0
  158. package/icons/material-symbols.css +24 -0
  159. package/index.js +95 -0
  160. package/inspector/InspectorPanel/InspectorPanel.css.js +375 -0
  161. package/inspector/InspectorPanel/InspectorPanel.js +368 -0
  162. package/inspector/InspectorPanel/InspectorPanel.tpl.js +96 -0
  163. package/inspector/TemplatePreview/TemplatePreview.css.js +104 -0
  164. package/inspector/TemplatePreview/TemplatePreview.js +145 -0
  165. package/inspector/TemplatePreview/TemplatePreview.tpl.js +33 -0
  166. package/interactions/ConnectFlow.js +304 -0
  167. package/interactions/Drag.js +104 -0
  168. package/interactions/Selector.js +133 -0
  169. package/interactions/SnapGrid.js +66 -0
  170. package/interactions/Zoom.js +139 -0
  171. package/layout/ActionZone/ActionZone.css.js +88 -0
  172. package/layout/ActionZone/ActionZone.js +261 -0
  173. package/layout/ActionZone/ActionZone.tpl.js +11 -0
  174. package/layout/CrossLayoutPortalBridge/CrossLayoutPortalBridge.js +255 -0
  175. package/layout/Layout/Layout.css.js +91 -0
  176. package/layout/Layout/Layout.js +637 -0
  177. package/layout/Layout/Layout.tpl.js +27 -0
  178. package/layout/LayoutNode/LayoutNode.css.js +302 -0
  179. package/layout/LayoutNode/LayoutNode.js +509 -0
  180. package/layout/LayoutNode/LayoutNode.tpl.js +39 -0
  181. package/layout/LayoutPreview/LayoutPreview.css.js +46 -0
  182. package/layout/LayoutPreview/LayoutPreview.js +102 -0
  183. package/layout/LayoutPreview/LayoutPreview.tpl.js +6 -0
  184. package/layout/LayoutRouter/LayoutRouter.js +274 -0
  185. package/layout/LayoutRouter/SectionRegistry.js +135 -0
  186. package/layout/LayoutRouter/routerSync.js +250 -0
  187. package/layout/LayoutSidebar/LayoutSidebar.css.js +411 -0
  188. package/layout/LayoutSidebar/LayoutSidebar.js +368 -0
  189. package/layout/LayoutSidebar/LayoutSidebar.tpl.js +26 -0
  190. package/layout/LayoutSidebar/SidebarSection.css.js +20 -0
  191. package/layout/LayoutSidebar/SidebarSection.js +184 -0
  192. package/layout/LayoutSidebar/SidebarSection.tpl.js +22 -0
  193. package/layout/LayoutTree.js +373 -0
  194. package/layout/PanelMenu/PanelMenu.css.js +43 -0
  195. package/layout/PanelMenu/PanelMenu.js +95 -0
  196. package/layout/PanelMenu/PanelMenu.tpl.js +17 -0
  197. package/layout/ProjectTabs/ProjectTabs.css.js +188 -0
  198. package/layout/ProjectTabs/ProjectTabs.js +77 -0
  199. package/layout/ProjectTabs/ProjectTabs.tpl.js +15 -0
  200. package/layout/index.js +40 -0
  201. package/list/ListDetailShell/ListDetailShell.css.js +128 -0
  202. package/list/ListDetailShell/ListDetailShell.js +72 -0
  203. package/list/ListDetailShell/ListDetailShell.tpl.js +36 -0
  204. package/list/ListItem/ListItem.css.js +111 -0
  205. package/list/ListItem/ListItem.js +66 -0
  206. package/list/ListItem/ListItem.tpl.js +18 -0
  207. package/locale/index.js +503 -0
  208. package/manifest/component-registry.js +2446 -0
  209. package/manifest/graph-schema.js +285 -0
  210. package/manifest/index.js +6 -0
  211. package/manifest/project-schema-catalog.js +246 -0
  212. package/manifest/rule-catalog.js +201 -0
  213. package/manifest/theme-catalog.js +2149 -0
  214. package/manifest/ui-schema-catalog.js +334 -0
  215. package/menu/ContextMenu/ContextMenu.css.js +61 -0
  216. package/menu/ContextMenu/ContextMenu.js +82 -0
  217. package/menu/ContextMenu/ContextMenu.tpl.js +19 -0
  218. package/navigation/QuickOpen/QuickOpen.css.js +92 -0
  219. package/navigation/QuickOpen/QuickOpen.js +185 -0
  220. package/navigation/QuickOpen/QuickOpen.tpl.js +15 -0
  221. package/navigation/quick-open-utils.js +101 -0
  222. package/node/CtrlItem/CtrlItem.css.js +41 -0
  223. package/node/CtrlItem/CtrlItem.js +24 -0
  224. package/node/CtrlItem/CtrlItem.tpl.js +17 -0
  225. package/node/GraphFrame/GraphFrame.css.js +66 -0
  226. package/node/GraphFrame/GraphFrame.js +32 -0
  227. package/node/GraphFrame/GraphFrame.tpl.js +13 -0
  228. package/node/GraphNode/GraphNode.css.js +815 -0
  229. package/node/GraphNode/GraphNode.js +173 -0
  230. package/node/GraphNode/GraphNode.tpl.js +33 -0
  231. package/node/NodeCallout/NodeCallout.css.js +91 -0
  232. package/node/NodeCallout/NodeCallout.js +281 -0
  233. package/node/NodeCallout/NodeCallout.tpl.js +8 -0
  234. package/node/NodeSocket/NodeSocket.css.js +68 -0
  235. package/node/NodeSocket/NodeSocket.js +26 -0
  236. package/node/NodeSocket/NodeSocket.tpl.js +7 -0
  237. package/node/PortItem/PortItem.css.js +93 -0
  238. package/node/PortItem/PortItem.js +87 -0
  239. package/node/PortItem/PortItem.tpl.js +10 -0
  240. package/package.json +165 -0
  241. package/palette/PaletteBrowser/PaletteBrowser.css.js +143 -0
  242. package/palette/PaletteBrowser/PaletteBrowser.js +152 -0
  243. package/palette/PaletteBrowser/PaletteBrowser.tpl.js +23 -0
  244. package/plugins/History.js +408 -0
  245. package/plugins/Readonly.js +60 -0
  246. package/rules/symbiote-3x.json +170 -0
  247. package/schemas/component-descriptor-v1.json +91 -0
  248. package/schemas/component-descriptor-v2.json +145 -0
  249. package/schemas/graph-model-v1.json +179 -0
  250. package/schemas/graph-v1.json +91 -0
  251. package/schemas/project-package-v1.json +102 -0
  252. package/schemas/project-transaction-v1.json +114 -0
  253. package/schemas/runtime-ui-v1.json +80 -0
  254. package/schemas/theme-rule-block-v1.json +73 -0
  255. package/shapes/CircleShape.js +79 -0
  256. package/shapes/CommentShape.js +35 -0
  257. package/shapes/DiamondShape.js +130 -0
  258. package/shapes/NodeShape.js +79 -0
  259. package/shapes/PillShape.js +91 -0
  260. package/shapes/RectShape.js +84 -0
  261. package/shapes/SVGShape.js +525 -0
  262. package/shapes/index.js +63 -0
  263. package/surface/Card/Card.css.js +57 -0
  264. package/surface/Card/Card.js +17 -0
  265. package/surface/Card/Card.tpl.js +3 -0
  266. package/themes/Palette.js +30 -0
  267. package/themes/Skin.js +113 -0
  268. package/themes/Theme.js +82 -0
  269. package/themes/carbon.js +135 -0
  270. package/themes/dark.js +140 -0
  271. package/themes/default-dark.js +714 -0
  272. package/themes/default-provider.css +635 -0
  273. package/themes/default-provider.js +718 -0
  274. package/themes/ebook.js +136 -0
  275. package/themes/grey.js +137 -0
  276. package/themes/light.js +139 -0
  277. package/themes/neon.js +138 -0
  278. package/themes/pcb.js +273 -0
  279. package/themes/synthwave.js +138 -0
  280. package/tokens/base.json +29 -0
  281. package/tokens/themes/carbon.json +11 -0
  282. package/tokens/themes/dark.json +12 -0
  283. package/tokens/themes/default-dark.json +1543 -0
  284. package/tokens/themes/default-provider.json +1543 -0
  285. package/tokens/themes/ebook.json +11 -0
  286. package/tokens/themes/grey.json +11 -0
  287. package/tokens/themes/light.json +12 -0
  288. package/tokens/themes/neon.json +11 -0
  289. package/tokens/themes/pcb.json +11 -0
  290. package/tokens/themes/synthwave.json +11 -0
  291. package/toolbar/QuickToolbar/QuickToolbar.css.js +152 -0
  292. package/toolbar/QuickToolbar/QuickToolbar.js +529 -0
  293. package/toolbar/QuickToolbar/QuickToolbar.tpl.js +34 -0
  294. package/tree/TreePanel/TreePanel.css.js +112 -0
  295. package/tree/TreePanel/TreePanel.js +147 -0
  296. package/tree/TreePanel/TreePanel.tpl.js +18 -0
  297. package/tree/TreeView/TreeView.css.js +122 -0
  298. package/tree/TreeView/TreeView.js +365 -0
  299. package/tree/TreeView/TreeView.tpl.js +10 -0
  300. package/ui/dialogs.js +221 -0
  301. package/ui/host-adapters.js +114 -0
  302. package/ui/index.js +660 -0
  303. package/ui/locale.js +50 -0
  304. package/ui/overlay-stack.js +89 -0
  305. package/ui/shared-styles.js +26 -0
  306. package/webmcp.js +37 -0
  307. package/xr/deep-graph.js +646 -0
  308. package/xr/emulation.js +198 -0
  309. package/xr/gesture.js +228 -0
  310. package/xr/html-canvas-renderer.js +472 -0
  311. package/xr/index.js +15 -0
  312. package/xr/layout-projection.js +1046 -0
  313. package/xr/panel-frame.js +128 -0
  314. package/xr/panel-host.js +267 -0
  315. package/xr/pointer.js +258 -0
  316. package/xr/scene-controller.js +242 -0
  317. package/xr/spatial-scene.js +212 -0
  318. package/xr/theme-bridge.js +105 -0
  319. package/xr/three-webxr-adapter.js +3439 -0
  320. package/xr/webgl-layer-renderer.js +419 -0
  321. package/xr/webxr.js +679 -0
  322. package/xr/workbench.js +516 -0
@@ -0,0 +1,223 @@
1
+ import { normalizeGraphEdge, normalizeGraphModel } from './model.js';
2
+
3
+ function asObject(value) {
4
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
5
+ }
6
+
7
+ function copyObject(value) {
8
+ return { ...asObject(value) };
9
+ }
10
+
11
+ function normalizeId(value, fieldName) {
12
+ const id = String(value ?? '').trim();
13
+ if (!id) throw new Error(`${fieldName} is required`);
14
+ return id;
15
+ }
16
+
17
+ function normalizeCanvasNode(rawNode) {
18
+ const data = asObject(rawNode);
19
+ const id = normalizeId(data.id, 'canvas node.id');
20
+ const children = Array.isArray(data.children) ? data.children.map((childId) => normalizeId(childId, 'canvas node.children')) : [];
21
+ const node = {
22
+ ...data,
23
+ id,
24
+ label: data.label == null ? id : String(data.label),
25
+ type: String(data.type ?? data.kind ?? 'data'),
26
+ isGroup: Boolean(data.isGroup),
27
+ children,
28
+ };
29
+
30
+ if (data.parentId != null) node.parentId = normalizeId(data.parentId, 'canvas node.parentId');
31
+ return node;
32
+ }
33
+
34
+ function normalizeCanvasEdge(rawEdge) {
35
+ const data = asObject(rawEdge);
36
+ const from = normalizeId(data.from ?? data.source?.nodeId ?? data.source?.node ?? data.source?.id, 'canvas edge.from');
37
+ const to = normalizeId(data.to ?? data.target?.nodeId ?? data.target?.node ?? data.target?.id, 'canvas edge.to');
38
+ return {
39
+ ...data,
40
+ from,
41
+ to,
42
+ out: data.out == null ? 'default' : String(data.out),
43
+ in: data.in == null ? 'default' : String(data.in),
44
+ };
45
+ }
46
+
47
+ function resolveView(graph, view) {
48
+ if (!view) return null;
49
+ if (typeof view === 'string') return graph.views[view] || null;
50
+ return asObject(view);
51
+ }
52
+
53
+ function visibleNodeIdsForView(graph, view) {
54
+ const rootIds = Array.isArray(view?.roots) ? view.roots : [];
55
+ if (rootIds.length === 0) return null;
56
+
57
+ const visible = new Set();
58
+ const visit = (id) => {
59
+ if (visible.has(id)) return;
60
+ const node = graph.nodesById.get(id);
61
+ if (!node) return;
62
+ visible.add(id);
63
+ for (const childId of node.children || []) visit(childId);
64
+ };
65
+ for (const id of rootIds) visit(id);
66
+ return visible;
67
+ }
68
+
69
+ function canvasNodeFromGraphNode(node) {
70
+ const design = asObject(node.design);
71
+ const canvas = asObject(design.canvas);
72
+ const canvasNode = {
73
+ ...canvas,
74
+ id: node.id,
75
+ label: node.label,
76
+ type: String(design.variant ?? node.kind),
77
+ kind: node.kind,
78
+ parentId: node.parentId ?? null,
79
+ isGroup: Boolean(design.isGroup ?? node.children.length > 0),
80
+ children: [...node.children],
81
+ flow: copyObject(node.flow),
82
+ params: copyObject(node.params),
83
+ design: copyObject(node.design),
84
+ state: copyObject(node.state),
85
+ };
86
+
87
+ if (design.width != null) canvasNode.w = design.width;
88
+ if (design.height != null) canvasNode.h = design.height;
89
+ if (design.color != null) canvasNode.color = String(design.color);
90
+ if (node.themeScope != null) canvasNode.themeScope = node.themeScope;
91
+ if (node.metadata != null) canvasNode.metadata = copyObject(node.metadata);
92
+
93
+ return canvasNode;
94
+ }
95
+
96
+ function rootNodesForCanvas(graph, visibleNodeIds, view) {
97
+ const explicitRoots = Array.isArray(view?.roots) ? view.roots : [];
98
+ const roots = [];
99
+
100
+ for (const id of explicitRoots) {
101
+ if (graph.nodesById.has(id) && (!visibleNodeIds || visibleNodeIds.has(id))) roots.push(id);
102
+ }
103
+ if (roots.length > 0) return roots;
104
+
105
+ for (const node of graph.nodes) {
106
+ if (visibleNodeIds && !visibleNodeIds.has(node.id)) continue;
107
+ if (!node.parentId || !graph.nodesById.has(node.parentId) || (visibleNodeIds && !visibleNodeIds.has(node.parentId))) {
108
+ roots.push(node.id);
109
+ }
110
+ }
111
+ return roots;
112
+ }
113
+
114
+ export function graphModelToCanvasGraphModel(rawModel, options = {}) {
115
+ const graph = normalizeGraphModel(rawModel);
116
+ const view = resolveView(graph, options.view);
117
+ const visibleNodeIds = visibleNodeIdsForView(graph, view);
118
+ const nodes = graph.nodes
119
+ .filter((node) => !visibleNodeIds || visibleNodeIds.has(node.id))
120
+ .map(canvasNodeFromGraphNode);
121
+ const nodeIds = new Set(nodes.map((node) => node.id));
122
+ const edges = graph.edges
123
+ .filter((edge) => nodeIds.has(edge.source.nodeId) && nodeIds.has(edge.target.nodeId))
124
+ .map((edge) => ({
125
+ id: edge.id,
126
+ from: edge.source.nodeId,
127
+ to: edge.target.nodeId,
128
+ out: edge.source.port,
129
+ in: edge.target.port,
130
+ type: edge.kind,
131
+ label: edge.label,
132
+ params: copyObject(edge.params),
133
+ metadata: copyObject(edge.metadata),
134
+ }));
135
+
136
+ return {
137
+ nodes,
138
+ edges,
139
+ rootNodes: rootNodesForCanvas(graph, visibleNodeIds, view),
140
+ };
141
+ }
142
+
143
+ export function canvasGraphModelToGraphModel(rawCanvasModel = {}, options = {}) {
144
+ const data = asObject(rawCanvasModel);
145
+ const nodes = (data.nodes || []).map(normalizeCanvasNode);
146
+ const nodesById = new Set(nodes.map((node) => node.id));
147
+ const edges = (data.edges ?? data.connections ?? []).map(normalizeCanvasEdge);
148
+ const rootNodes = Array.isArray(data.rootNodes)
149
+ ? data.rootNodes.map((id) => normalizeId(id, 'canvas rootNodes')).filter((id) => nodesById.has(id))
150
+ : [];
151
+
152
+ return normalizeGraphModel({
153
+ version: 'graph-model-v1',
154
+ metadata: copyObject(options.metadata),
155
+ nodes: nodes.map((node) => {
156
+ const design = {
157
+ ...copyObject(node.design),
158
+ component: node.design?.component ?? options.component ?? (node.isGroup ? 'graph-group' : 'graph-node'),
159
+ };
160
+ if (node.w != null) design.width = node.w;
161
+ if (node.h != null) design.height = node.h;
162
+ if (node.color != null) design.color = node.color;
163
+ design.canvas = {
164
+ ...copyObject(design.canvas),
165
+ ...copyCanvasData(node),
166
+ };
167
+
168
+ const graphNode = {
169
+ id: node.id,
170
+ kind: String(node.kind ?? node.type ?? 'ui.node'),
171
+ label: node.label,
172
+ flow: copyObject(node.flow),
173
+ params: copyObject(node.params),
174
+ design,
175
+ children: node.children,
176
+ state: copyObject(node.state),
177
+ };
178
+ if (node.parentId != null) graphNode.parentId = node.parentId;
179
+ if (node.themeScope != null) graphNode.themeScope = node.themeScope;
180
+ if (node.metadata != null) graphNode.metadata = copyObject(node.metadata);
181
+ return graphNode;
182
+ }),
183
+ edges: edges.map((edge) => normalizeGraphEdge({
184
+ id: edge.id,
185
+ kind: edge.kind ?? edge.type,
186
+ label: edge.label,
187
+ source: { nodeId: edge.from, port: edge.out },
188
+ target: { nodeId: edge.to, port: edge.in },
189
+ params: edge.params,
190
+ metadata: edge.metadata,
191
+ })),
192
+ views: {
193
+ canvas: {
194
+ kind: 'canvas-graph',
195
+ roots: rootNodes,
196
+ },
197
+ },
198
+ });
199
+ }
200
+
201
+ function copyCanvasData(node) {
202
+ const skip = new Set([
203
+ 'id',
204
+ 'label',
205
+ 'type',
206
+ 'kind',
207
+ 'parentId',
208
+ 'isGroup',
209
+ 'children',
210
+ 'flow',
211
+ 'params',
212
+ 'design',
213
+ 'state',
214
+ 'w',
215
+ 'h',
216
+ 'color',
217
+ 'themeScope',
218
+ 'metadata',
219
+ ]);
220
+ return Object.fromEntries(
221
+ Object.entries(node).filter(([key, value]) => !skip.has(key) && value !== undefined)
222
+ );
223
+ }
@@ -0,0 +1,31 @@
1
+ export function resolveSymbolFile(skeleton, symbol) {
2
+ if (!skeleton || !symbol) return null;
3
+ const entry = (skeleton.n || {})[symbol];
4
+ return entry?.f || null;
5
+ }
6
+
7
+ export function findConnectionPath(connections, fromId, toId) {
8
+ if (!fromId || !toId || fromId === toId) return [];
9
+
10
+ const adjacency = new Map();
11
+ for (const connection of connections || []) {
12
+ if (!adjacency.has(connection.from)) adjacency.set(connection.from, []);
13
+ adjacency.get(connection.from).push({ to: connection.to, id: connection.id });
14
+ }
15
+
16
+ const visited = new Set([fromId]);
17
+ const queue = [[fromId, []]];
18
+
19
+ while (queue.length > 0) {
20
+ const [current, path] = queue.shift();
21
+ if (current === toId) return path;
22
+
23
+ for (const edge of adjacency.get(current) || []) {
24
+ if (visited.has(edge.to)) continue;
25
+ visited.add(edge.to);
26
+ queue.push([edge.to, [...path, edge.id]]);
27
+ }
28
+ }
29
+
30
+ return [];
31
+ }
package/graph/index.js ADDED
@@ -0,0 +1,46 @@
1
+ export {
2
+ normalizeGraphEndpoint,
3
+ normalizeGraphNode,
4
+ normalizeGraphEdge,
5
+ normalizeGraphModel,
6
+ } from './model.js';
7
+ export {
8
+ canvasGraphModelToGraphModel,
9
+ graphModelToCanvasGraphModel,
10
+ } from './canvas-adapter.js';
11
+ export { normalizeProjectPackage } from './project-package.js';
12
+ export {
13
+ applyProjectTransaction,
14
+ updateLayoutNode,
15
+ normalizeProjectTransaction,
16
+ } from './project-transaction.js';
17
+ export { createProjectRuntime } from './project-runtime.js';
18
+ export {
19
+ GRAPH_CLUSTER_COLOR_TOKENS,
20
+ GRAPH_TYPE_COLOR_TOKENS,
21
+ getGraphClusterColorToken,
22
+ isGraphColorReference,
23
+ normalizeGraphColorReference,
24
+ } from './theme-contract.js'
25
+ export { dirOf, baseName, resolveImport, collectSkeletonFiles } from './skeleton-utils.js'
26
+ export {
27
+ EMPTY_PROJECT_GRAPH_METADATA,
28
+ normalizeProjectGraphMetadata,
29
+ validateProjectGraphMetadata,
30
+ pathMatchesPattern,
31
+ findClusterForPath,
32
+ buildSemanticGroups,
33
+ parseHexColor,
34
+ } from './project-graph-metadata.js'
35
+ export { resolveSymbolFile, findConnectionPath } from './graph-algorithms.js'
36
+ export { extractProjectTransactionsFromMessages } from './transaction-parser.js'
37
+ export {
38
+ buildFlatGroups,
39
+ buildGraphStatItems,
40
+ prepareGraphBuild,
41
+ } from './project-graph-build.js'
42
+ export {
43
+ buildCanvasGraphModelFromSkeleton,
44
+ buildGraphModelFromSkeleton,
45
+ } from '../canvas/project-graph-model.js'
46
+ export { buildFileGraph, buildStructuredGraph } from '../canvas/project-graph-builder.js'
package/graph/model.js ADDED
@@ -0,0 +1,176 @@
1
+ const DEFAULT_PORT = 'default';
2
+
3
+ function asObject(value) {
4
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
5
+ }
6
+
7
+ function normalizeId(value, fieldName) {
8
+ const id = String(value ?? '').trim();
9
+ if (!id) throw new Error(`${fieldName} is required`);
10
+ return id;
11
+ }
12
+
13
+ function normalizePort(port) {
14
+ const normalized = String(port ?? DEFAULT_PORT).trim();
15
+ return normalized || DEFAULT_PORT;
16
+ }
17
+
18
+ function normalizeEndpointPort(port) {
19
+ const normalized = String(port ?? '').trim();
20
+ if (!normalized) throw new Error('endpoint.port is required');
21
+ return normalized;
22
+ }
23
+
24
+ function normalizePorts(ports) {
25
+ if (!Array.isArray(ports)) return [];
26
+ return ports.map((port) => {
27
+ if (typeof port === 'string') return { name: port, type: 'any' };
28
+ const data = asObject(port);
29
+ return {
30
+ ...data,
31
+ name: normalizeId(data.name, 'port.name'),
32
+ type: String(data.type ?? 'any'),
33
+ };
34
+ });
35
+ }
36
+
37
+ function normalizeFlow(flow = {}) {
38
+ const data = asObject(flow);
39
+ return {
40
+ ...data,
41
+ inputs: normalizePorts(data.inputs),
42
+ outputs: normalizePorts(data.outputs),
43
+ };
44
+ }
45
+
46
+ function normalizeDesign(design = {}) {
47
+ const data = asObject(design);
48
+ return {
49
+ ...data,
50
+ component: String(data.component ?? 'graph-node'),
51
+ };
52
+ }
53
+
54
+ function endpointFromObject(endpoint, fallbackPort) {
55
+ const data = asObject(endpoint);
56
+ return {
57
+ nodeId: normalizeId(data.nodeId, 'endpoint.nodeId'),
58
+ port: fallbackPort == null ? normalizeEndpointPort(data.port) : normalizePort(data.port ?? fallbackPort),
59
+ };
60
+ }
61
+
62
+ export function normalizeGraphEndpoint(endpoint, fallbackPort) {
63
+ return endpointFromObject(endpoint, fallbackPort);
64
+ }
65
+
66
+ export function normalizeGraphNode(rawNode) {
67
+ const data = asObject(rawNode);
68
+ const id = normalizeId(data.id, 'node.id');
69
+ const kind = normalizeId(data.kind, 'node.kind');
70
+ const node = {
71
+ id,
72
+ kind,
73
+ label: data.label == null ? id : String(data.label),
74
+ flow: normalizeFlow(data.flow),
75
+ params: asObject(data.params),
76
+ design: normalizeDesign(data.design),
77
+ children: Array.isArray(data.children) ? data.children.map((childId) => normalizeId(childId, 'node.children')) : [],
78
+ state: asObject(data.state),
79
+ };
80
+
81
+ if (data.parentId != null) node.parentId = normalizeId(data.parentId, 'node.parentId');
82
+ if (data.themeScope != null) node.themeScope = normalizeId(data.themeScope, 'node.themeScope');
83
+ if (data.metadata != null) node.metadata = asObject(data.metadata);
84
+
85
+ return node;
86
+ }
87
+
88
+ export function normalizeGraphEdge(rawEdge) {
89
+ const data = asObject(rawEdge);
90
+ const source = normalizeGraphEndpoint(data.source);
91
+ const target = normalizeGraphEndpoint(data.target);
92
+ const kind = String(data.kind ?? 'dataflow');
93
+ const id = data.id == null
94
+ ? `${source.nodeId}:${source.port}->${target.nodeId}:${target.port}`
95
+ : normalizeId(data.id, 'edge.id');
96
+
97
+ const edge = {
98
+ id,
99
+ kind,
100
+ source,
101
+ target,
102
+ params: asObject(data.params),
103
+ };
104
+
105
+ if (data.label != null) edge.label = String(data.label);
106
+ if (data.metadata != null) edge.metadata = asObject(data.metadata);
107
+
108
+ return edge;
109
+ }
110
+
111
+ function normalizeView(view) {
112
+ const data = asObject(view);
113
+ return {
114
+ ...data,
115
+ kind: String(data.kind ?? 'graph-canvas'),
116
+ roots: Array.isArray(data.roots) ? data.roots.map((id) => normalizeId(id, 'view.roots')) : [],
117
+ groups: Array.isArray(data.groups) ? data.groups.map((group) => ({
118
+ ...asObject(group),
119
+ id: normalizeId(asObject(group).id, 'view.group.id'),
120
+ nodeIds: Array.isArray(asObject(group).nodeIds)
121
+ ? asObject(group).nodeIds.map((id) => normalizeId(id, 'view.group.nodeIds'))
122
+ : [],
123
+ })) : [],
124
+ };
125
+ }
126
+
127
+ function normalizeViews(views) {
128
+ const data = asObject(views);
129
+ return Object.fromEntries(
130
+ Object.entries(data).map(([name, view]) => [name, normalizeView(view)])
131
+ );
132
+ }
133
+
134
+ export function normalizeGraphModel(rawModel = {}) {
135
+ const data = asObject(rawModel);
136
+ const nodes = [];
137
+ const nodesById = new Map();
138
+
139
+ for (const rawNode of data.nodes || []) {
140
+ const node = normalizeGraphNode(rawNode);
141
+ if (nodesById.has(node.id)) throw new Error(`node "${node.id}" is already defined`);
142
+ nodes.push(node);
143
+ nodesById.set(node.id, node);
144
+ }
145
+
146
+ const rawEdges = data.edges ?? [];
147
+ const edges = rawEdges.map(normalizeGraphEdge);
148
+ const edgesById = new Map();
149
+ for (const edge of edges) {
150
+ if (edgesById.has(edge.id)) throw new Error(`edge "${edge.id}" is already defined`);
151
+ if (!nodesById.has(edge.source.nodeId)) {
152
+ throw new Error(`source node "${edge.source.nodeId}" is not defined`);
153
+ }
154
+ if (!nodesById.has(edge.target.nodeId)) {
155
+ throw new Error(`target node "${edge.target.nodeId}" is not defined`);
156
+ }
157
+ edgesById.set(edge.id, edge);
158
+ }
159
+
160
+ for (const node of nodes) {
161
+ for (const childId of node.children) {
162
+ if (!nodesById.has(childId)) throw new Error(`child node "${childId}" is not defined`);
163
+ }
164
+ }
165
+
166
+ return {
167
+ version: 'graph-model-v1',
168
+ metadata: asObject(data.metadata),
169
+ nodes,
170
+ edges,
171
+ views: normalizeViews(data.views),
172
+ theme: data.theme == null ? null : asObject(data.theme),
173
+ nodesById,
174
+ edgesById,
175
+ };
176
+ }
@@ -0,0 +1,66 @@
1
+ import { buildSemanticGroups } from './project-graph-metadata.js';
2
+
3
+ export function buildFlatGroups(dirFiles, fileMap, projectGraphMetadata = null) {
4
+ let semanticGroups = buildSemanticGroups(fileMap, projectGraphMetadata);
5
+ let groups = { ...semanticGroups };
6
+ let assignedNodeIds = new Set(Object.values(semanticGroups).flat());
7
+
8
+ if (!dirFiles) return groups;
9
+
10
+ for (let [dir, files] of dirFiles.entries()) {
11
+ let nodeIds = [];
12
+ for (let file of files) {
13
+ let nodeId = fileMap.get(file);
14
+ if (nodeId && !assignedNodeIds.has(nodeId)) nodeIds.push(nodeId);
15
+ }
16
+ if (nodeIds.length > 0) groups[dir] = nodeIds;
17
+ }
18
+ return groups;
19
+ }
20
+
21
+ export function prepareGraphBuild({
22
+ cache,
23
+ skeleton,
24
+ isStructured,
25
+ projectGraphMetadata,
26
+ getOrBuildGraphFn,
27
+ getDrillableFilesFn,
28
+ buildStructuredGraphFn,
29
+ buildFileGraphFn,
30
+ }) {
31
+ let { graph, cached } = getOrBuildGraphFn({
32
+ cache,
33
+ skeleton,
34
+ isStructured,
35
+ buildStructuredGraphFn,
36
+ buildFileGraphFn,
37
+ });
38
+ let { dirFiles, fileMap, symbolMap } = graph;
39
+
40
+ return {
41
+ graph,
42
+ cached,
43
+ groups: isStructured ? {} : buildFlatGroups(dirFiles, fileMap, projectGraphMetadata),
44
+ drillableFiles: getDrillableFilesFn(symbolMap),
45
+ };
46
+ }
47
+
48
+ export function buildGraphStatItems({
49
+ skeletonStats = {},
50
+ fileCount,
51
+ edgeCount,
52
+ viaCount,
53
+ }) {
54
+ let items = [
55
+ [fileCount, 'files'],
56
+ [skeletonStats.functions || 0, 'fn'],
57
+ [skeletonStats.classes || 0, 'cls'],
58
+ [edgeCount, 'edges'],
59
+ ];
60
+
61
+ if (viaCount > 0) {
62
+ items.push([viaCount, 'vias']);
63
+ }
64
+
65
+ return items;
66
+ }