@kiberon-labs/behave-graph-flow 1.0.0 → 3.0.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 (378) hide show
  1. package/.fallowrc.json +16 -0
  2. package/.storybook/main.ts +32 -0
  3. package/.storybook/manager.ts +6 -0
  4. package/.storybook/preview.ts +64 -0
  5. package/.storybook/styles.css +16 -0
  6. package/.turbo/turbo-build.log +7 -0
  7. package/CHANGELOG.md +368 -0
  8. package/LICENSE +6 -0
  9. package/README.md +2 -2
  10. package/data/Polynomial.json +510 -0
  11. package/data/sequence.json +337 -0
  12. package/data/trigger-event.json +241 -0
  13. package/data/variable-change.json +210 -0
  14. package/dist/AnyControlImpl-Ds-CShIB.js +20 -0
  15. package/dist/AnyControlImpl-Ds-CShIB.js.map +1 -0
  16. package/dist/DocumentationBrowserPanelImpl-deZNzFX8.js +166 -0
  17. package/dist/DocumentationBrowserPanelImpl-deZNzFX8.js.map +1 -0
  18. package/dist/entry.css +4 -0
  19. package/dist/index.css +42 -0
  20. package/dist/index.css.map +1 -0
  21. package/dist/index.d.ts +3597 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +18009 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/noteImpl-KkrrWgJd.js +242 -0
  26. package/dist/noteImpl-KkrrWgJd.js.map +1 -0
  27. package/dist/styles.module-CvmpDkZj.css +3 -0
  28. package/dist/styles.module-CvmpDkZj.css.map +1 -0
  29. package/dist/styles.module-DZxg8aW9.js +271 -0
  30. package/dist/styles.module-DZxg8aW9.js.map +1 -0
  31. package/dist/useChangeNodeData-ChQGK7AI.js +23 -0
  32. package/dist/useChangeNodeData-ChQGK7AI.js.map +1 -0
  33. package/docs/notifications.md +246 -0
  34. package/docs/protocol.md +702 -0
  35. package/docs/specifics.md +191 -0
  36. package/package.json +82 -22
  37. package/postcss.config.ts +3 -4
  38. package/src/annotations/index.ts +32 -0
  39. package/src/components/FloatingToolbar/index.module.css +37 -0
  40. package/src/components/FloatingToolbar/index.tsx +256 -0
  41. package/src/components/Flow.tsx +287 -75
  42. package/src/components/contextMenus/DynamicContextMenu.tsx +85 -0
  43. package/src/components/contextMenus/NodePicker.module.css +274 -0
  44. package/src/components/contextMenus/NodePicker.tsx +481 -0
  45. package/src/components/contextMenus/edge.tsx +22 -0
  46. package/src/components/contextMenus/node.tsx +15 -0
  47. package/src/components/contextMenus/selection.tsx +11 -0
  48. package/src/components/controls/any/AnyControlImpl.tsx +14 -0
  49. package/src/components/controls/any/index.tsx +19 -0
  50. package/src/components/controls/boolean/index.tsx +13 -0
  51. package/src/components/controls/colorPicker/InputPopover.module.css +100 -0
  52. package/src/components/controls/colorPicker/InputPopover.tsx +31 -0
  53. package/src/components/controls/colorPicker/index.module.css +18 -0
  54. package/src/components/controls/colorPicker/index.tsx +61 -0
  55. package/src/components/controls/number/index.tsx +35 -0
  56. package/src/components/controls/string/index.tsx +16 -0
  57. package/src/components/edges/index.tsx +475 -0
  58. package/src/components/edges/offsetBezier.ts +134 -0
  59. package/src/components/hotKeys.tsx +20 -0
  60. package/src/components/layoutController/index.module.css +13 -0
  61. package/src/components/layoutController/index.tsx +140 -0
  62. package/src/components/layoutController/utils.ts +248 -0
  63. package/src/components/menubar/defaults.tsx +516 -0
  64. package/src/components/menubar/index.tsx +49 -0
  65. package/src/components/menubar/menuItem.module.css +31 -0
  66. package/src/components/menubar/menuItem.tsx +65 -0
  67. package/src/components/nodes/behave/Node.module.css +23 -0
  68. package/src/components/nodes/behave/Node.tsx +176 -0
  69. package/src/components/nodes/behave/NodeContainer.module.css +88 -0
  70. package/src/components/nodes/behave/NodeContainer.tsx +46 -0
  71. package/src/components/nodes/behave/index.tsx +14 -0
  72. package/src/components/nodes/group/index.tsx +109 -0
  73. package/src/components/nodes/wrapper/index.tsx +73 -0
  74. package/src/components/nodes/wrapper/styles.module.css +87 -0
  75. package/src/components/notifications/NotificationProvider.tsx +81 -0
  76. package/src/components/notifications/index.ts +2 -0
  77. package/src/components/notifications/utils.ts +71 -0
  78. package/src/components/panels/alignment/index.module.css +10 -0
  79. package/src/components/panels/alignment/index.tsx +244 -0
  80. package/src/components/panels/base/index.tsx +5 -0
  81. package/src/components/panels/base/styles.module.css +12 -0
  82. package/src/components/panels/common/PanelHeader.module.css +24 -0
  83. package/src/components/panels/common/PanelHeader.tsx +22 -0
  84. package/src/components/panels/common/SectionTitle.module.css +13 -0
  85. package/src/components/panels/common/SectionTitle.tsx +10 -0
  86. package/src/components/panels/events/EditEventPanel.tsx +324 -0
  87. package/src/components/panels/events/ManageEventsPanel.tsx +101 -0
  88. package/src/components/panels/events/index.tsx +23 -0
  89. package/src/components/panels/events/styles.module.css +178 -0
  90. package/src/components/panels/graphProperties/index.tsx +125 -0
  91. package/src/components/panels/history/index.tsx +92 -0
  92. package/src/components/panels/history/styles.module.css +97 -0
  93. package/src/components/panels/keymaps/index.module.css +68 -0
  94. package/src/components/panels/keymaps/index.tsx +166 -0
  95. package/src/components/panels/layers/index.tsx +245 -0
  96. package/src/components/panels/layers/styles.module.css +107 -0
  97. package/src/components/panels/legend/index.module.css +6 -0
  98. package/src/components/panels/legend/index.tsx +76 -0
  99. package/src/components/panels/logs/index.module.css +218 -0
  100. package/src/components/panels/logs/index.tsx +288 -0
  101. package/src/components/panels/nodeInputs/InputControl.tsx +63 -0
  102. package/src/components/panels/nodeInputs/InputsGroup.tsx +65 -0
  103. package/src/components/panels/nodeInputs/MultipleNodesView.tsx +37 -0
  104. package/src/components/panels/nodeInputs/NodeSettings.tsx +92 -0
  105. package/src/components/panels/nodeInputs/NodeTitleEditor.tsx +125 -0
  106. package/src/components/panels/nodeInputs/OutputsGroup.tsx +55 -0
  107. package/src/components/panels/nodeInputs/SocketGenerators.tsx +32 -0
  108. package/src/components/panels/nodeInputs/index.module.css +308 -0
  109. package/src/components/panels/nodeInputs/index.tsx +349 -0
  110. package/src/components/panels/nodeInputs/useNodeHandlers.ts +76 -0
  111. package/src/components/panels/nodeInputs/useNodeInputsData.ts +153 -0
  112. package/src/components/panels/nodePicker/index.tsx +115 -0
  113. package/src/components/panels/panel/index.module.css +66 -0
  114. package/src/components/panels/panel/index.tsx +88 -0
  115. package/src/components/panels/search/index.module.css +16 -0
  116. package/src/components/panels/search/index.tsx +215 -0
  117. package/src/components/panels/systemSettings/ConversionsSettings.tsx +203 -0
  118. package/src/components/panels/systemSettings/index.tsx +251 -0
  119. package/src/components/panels/systemSettings/styles.module.css +138 -0
  120. package/src/components/panels/traces/GridLines.tsx +38 -0
  121. package/src/components/panels/traces/TimeGrid.tsx +48 -0
  122. package/src/components/panels/traces/TraceLane.tsx +62 -0
  123. package/src/components/panels/traces/TraceTooltip.tsx +22 -0
  124. package/src/components/panels/traces/TracesHeader.tsx +56 -0
  125. package/src/components/panels/traces/index.module.css +159 -0
  126. package/src/components/panels/traces/index.tsx +298 -0
  127. package/src/components/panels/traces/types.ts +48 -0
  128. package/src/components/panels/traces/useDerivedSpans.ts +307 -0
  129. package/src/components/panels/traces/utils.ts +33 -0
  130. package/src/components/panels/variables/CreateVariableScreen.tsx +162 -0
  131. package/src/components/panels/variables/ManageVariablesScreen.tsx +147 -0
  132. package/src/components/panels/variables/index.tsx +125 -0
  133. package/src/components/panels/variables/styles.module.css +149 -0
  134. package/src/components/primitives/icon.module.css +45 -0
  135. package/src/components/primitives/icon.tsx +38 -0
  136. package/src/components/sockets/input/index.tsx +83 -0
  137. package/src/components/sockets/input/styles.module.css +26 -0
  138. package/src/components/sockets/output/index.tsx +68 -0
  139. package/src/components/sockets/output/styles.module.css +22 -0
  140. package/src/css/notes.css +135 -0
  141. package/src/css/prosemirror.css +57 -0
  142. package/src/css/rc-dock.css +212 -0
  143. package/src/css/rc-menu.css +101 -0
  144. package/src/css/themes/kiberon.css +127 -0
  145. package/src/css/vars.css +198 -0
  146. package/src/css/vscode-elements.css +124 -0
  147. package/src/entry.css +4 -0
  148. package/src/generators/CallSubgraphGenerator.tsx +136 -0
  149. package/src/generators/CustomEventOnTriggeredGenerator.tsx +85 -0
  150. package/src/generators/GraphBoundaryGenerator.module.css +32 -0
  151. package/src/generators/GraphBoundaryGenerator.tsx +193 -0
  152. package/src/generators/SequenceGenerator.tsx +104 -0
  153. package/src/generators/SwitchOnIntegerGenerator.tsx +256 -0
  154. package/src/generators/SwitchOnStringGenerator.tsx +263 -0
  155. package/src/generators/callSubgraphSync.ts +126 -0
  156. package/src/generators/registerDefaultGenerators.ts +55 -0
  157. package/src/generators/registerDefaults.ts +26 -0
  158. package/src/hooks/useBehaveGraphFlow.ts +17 -16
  159. package/src/hooks/useFlowHandlers.ts +154 -30
  160. package/src/hooks/useWasdPan.ts +210 -0
  161. package/src/index.css +134 -0
  162. package/src/index.ts +53 -18
  163. package/src/manifest/contributionRegistry.ts +93 -0
  164. package/src/manifest/index.ts +4 -0
  165. package/src/manifest/loadManifest.ts +82 -0
  166. package/src/manifest/manifestPlugin.ts +29 -0
  167. package/src/manifest/passthroughValueType.ts +40 -0
  168. package/src/plugin/alignment/index.ts +91 -0
  169. package/src/plugin/autosave/controller.ts +366 -0
  170. package/src/plugin/autosave/index.tsx +114 -0
  171. package/src/plugin/autosave/panel/BackupPanel.tsx +141 -0
  172. package/src/plugin/autosave/panel/index.tsx +1 -0
  173. package/src/plugin/autosave/panel/styles.module.css +56 -0
  174. package/src/plugin/autosave/settings.ts +65 -0
  175. package/src/plugin/autosave/storage.ts +147 -0
  176. package/src/plugin/docs/index.tsx +297 -0
  177. package/src/plugin/docs/panel/DocumentationBrowserPanelImpl.tsx +200 -0
  178. package/src/plugin/docs/panel/index.tsx +21 -0
  179. package/src/plugin/docs/panel/styles.module.css +174 -0
  180. package/src/plugin/graphrunner/actions.ts +326 -0
  181. package/src/plugin/graphrunner/buttons.tsx +95 -0
  182. package/src/plugin/graphrunner/client.ts +707 -0
  183. package/src/plugin/graphrunner/index.tsx +184 -0
  184. package/src/plugin/graphrunner/panel.tsx +386 -0
  185. package/src/plugin/graphrunner/runController.ts +283 -0
  186. package/src/plugin/graphrunner/runner.ts +187 -0
  187. package/src/plugin/graphrunner/session.ts +243 -0
  188. package/src/plugin/graphrunner/store.ts +196 -0
  189. package/src/plugin/graphrunner/styles.module.css +171 -0
  190. package/src/plugin/graphrunner/transport.ts +250 -0
  191. package/src/plugin/graphrunner/types.ts +693 -0
  192. package/src/plugin/graphrunner-local/execution-utils.ts +637 -0
  193. package/src/plugin/graphrunner-local/index.tsx +172 -0
  194. package/src/plugin/graphrunner-local/panel.tsx +187 -0
  195. package/src/plugin/graphrunner-local/store.ts +41 -0
  196. package/src/plugin/graphrunner-local/styles.module.css +82 -0
  197. package/src/plugin/graphrunner-local/transport.ts +1339 -0
  198. package/src/plugin/graphrunner-local/types.ts +10 -0
  199. package/src/plugin/graphrunner-webworker/graph-executor.worker.ts +635 -0
  200. package/src/plugin/graphrunner-webworker/index.tsx +140 -0
  201. package/src/plugin/graphrunner-webworker/panel.tsx +173 -0
  202. package/src/plugin/graphrunner-webworker/store.ts +98 -0
  203. package/src/plugin/graphrunner-webworker/worker-transport.ts +123 -0
  204. package/src/plugin/kitchen-sink/index.ts +38 -0
  205. package/src/plugin/layout/dagre.ts +131 -0
  206. package/src/plugin/layout/elk.ts +216 -0
  207. package/src/plugin/layout/index.ts +80 -0
  208. package/src/plugin/notes/FormatToolbar.tsx +200 -0
  209. package/src/plugin/notes/index.tsx +191 -0
  210. package/src/plugin/notes/nodeActions.ts +100 -0
  211. package/src/plugin/notes/note.tsx +20 -0
  212. package/src/plugin/notes/noteImpl.tsx +89 -0
  213. package/src/plugin/realtime/realtimeRunner.ts +624 -0
  214. package/src/specifics/CustomEventOnTriggeredSpecific.tsx +92 -0
  215. package/src/specifics/CustomEventTriggerSpecific.tsx +141 -0
  216. package/src/specifics/VariableGetSpecific.tsx +110 -0
  217. package/src/specifics/VariableSetSpecific.tsx +110 -0
  218. package/src/store/actions.tsx +698 -0
  219. package/src/store/commands.ts +278 -0
  220. package/src/store/contextMenu.ts +192 -0
  221. package/src/store/controls.tsx +62 -0
  222. package/src/store/conversions.ts +47 -0
  223. package/src/store/documentation.tsx +69 -0
  224. package/src/store/events.tsx +116 -0
  225. package/src/store/flow.tsx +230 -0
  226. package/src/store/graphMeta.ts +39 -0
  227. package/src/store/hotKeys.tsx +364 -0
  228. package/src/store/layers.ts +259 -0
  229. package/src/store/legend.tsx +76 -0
  230. package/src/store/logs.ts +28 -0
  231. package/src/store/menubar.ts +41 -0
  232. package/src/store/refs.ts +84 -0
  233. package/src/store/registry.ts +51 -0
  234. package/src/store/selection.ts +22 -0
  235. package/src/store/settings.ts +99 -0
  236. package/src/store/settingsSchema.ts +210 -0
  237. package/src/store/socketGenerator.tsx +54 -0
  238. package/src/store/specific.tsx +75 -0
  239. package/src/store/specs.tsx +35 -0
  240. package/src/store/tabs.ts +282 -0
  241. package/src/store/toolbar.tsx +45 -0
  242. package/src/store/traces.ts +240 -0
  243. package/src/store/variables.ts +37 -0
  244. package/src/system/graph.ts +131 -0
  245. package/src/system/graphSession.ts +172 -0
  246. package/src/system/index.ts +6 -0
  247. package/src/system/notifications.ts +111 -0
  248. package/src/system/persistence.ts +82 -0
  249. package/src/system/plugin.ts +55 -0
  250. package/src/system/provider.tsx +86 -0
  251. package/src/system/pubsub.ts +323 -0
  252. package/src/system/system.ts +653 -0
  253. package/src/system/tabLoader.tsx +303 -0
  254. package/src/system/undoRedo.ts +103 -0
  255. package/src/transformers/Uigraph.ts +61 -0
  256. package/src/transformers/behaveToFlow.ts +16 -4
  257. package/src/transformers/contract.ts +87 -0
  258. package/src/transformers/flowToBehave.ts +40 -12
  259. package/src/types/NodeMetadata.ts +27 -0
  260. package/src/types/graph.ts +49 -0
  261. package/src/types/nodes.ts +50 -0
  262. package/src/types.ts +18 -0
  263. package/src/util/autoConvert.ts +200 -0
  264. package/src/util/colors.ts +1 -29
  265. package/src/util/downloadJson.ts +18 -0
  266. package/src/util/extractNodeMetadata.ts +16 -0
  267. package/src/util/getPickerFilters.ts +1 -1
  268. package/src/util/isBehaveNode.ts +6 -0
  269. package/src/util/isValidConnection.ts +51 -17
  270. package/src/util/mergeSockets.ts +29 -0
  271. package/src/util/serializeVariables.ts +66 -0
  272. package/src/util/sockets.ts +43 -0
  273. package/stories/apex/layoutController/example-graph.worker.ts +39 -0
  274. package/stories/apex/layoutController/index.stories.tsx +48 -0
  275. package/stories/apex/layoutController/webworker.stories.tsx +103 -0
  276. package/stories/apex/menubar/menubar.stories.tsx +19 -0
  277. package/stories/components/colorpicker/index.stories.tsx +20 -0
  278. package/stories/components/contextMenus/edge.stories.tsx +32 -0
  279. package/stories/components/contextMenus/node.stories.tsx +26 -0
  280. package/stories/components/contextMenus/nodePicker.stories.tsx +115 -0
  281. package/stories/components/controls/any/index.stories.tsx +19 -0
  282. package/stories/components/controls/boolean/index.stories.tsx +19 -0
  283. package/stories/components/controls/colorPicker/index.stories.tsx +49 -0
  284. package/stories/components/controls/number/index.stories.tsx +19 -0
  285. package/stories/components/controls/string/index.stories.tsx +19 -0
  286. package/stories/components/nodes/behaveNode.stories.tsx +108 -0
  287. package/stories/components/panels/alignment.stories.tsx +24 -0
  288. package/stories/components/panels/events.stories.tsx +38 -0
  289. package/stories/components/panels/graphRunner.stories.tsx +317 -0
  290. package/stories/components/panels/history.stories.tsx +37 -0
  291. package/stories/components/panels/keymaps.stories.tsx +21 -0
  292. package/stories/components/panels/legend.stories.tsx +37 -0
  293. package/stories/components/panels/logs.stories.tsx +24 -0
  294. package/stories/components/panels/nodeInputs.stories.tsx +21 -0
  295. package/stories/components/panels/nodePicker.stories.tsx +37 -0
  296. package/stories/components/panels/panel.stories.tsx +39 -0
  297. package/stories/components/panels/search.stories.tsx +24 -0
  298. package/stories/components/panels/systemSettings.stories.tsx +26 -0
  299. package/stories/components/panels/traces.stories.tsx +225 -0
  300. package/stories/components/panels/variables.stories.tsx +24 -0
  301. package/stories/defaults/defaultStoryProvider.tsx +170 -0
  302. package/stories/defaults/systemGenerator.ts +43 -0
  303. package/stories/plugins/notes.stories.tsx +100 -0
  304. package/tests/autoConvert.test.ts +329 -0
  305. package/tests/autosavePlugin.test.ts +204 -0
  306. package/tests/callSubgraphSync.test.ts +148 -0
  307. package/tests/commandRegistry.test.ts +137 -0
  308. package/tests/components/edges/offsetBezier.test.ts +51 -0
  309. package/tests/components/layoutController/utils.test.ts +68 -0
  310. package/tests/components/panels/traces/utils.test.ts +52 -0
  311. package/tests/contract.test.ts +51 -0
  312. package/tests/contractSerialize.test.ts +62 -0
  313. package/tests/deriveSpans.test.ts +71 -0
  314. package/tests/flowToBehave.test.ts +27 -4
  315. package/tests/hotkeys.test.ts +79 -0
  316. package/tests/keepAliveLifecycle.test.ts +167 -0
  317. package/tests/loadManifest.test.ts +113 -0
  318. package/tests/noteMarkdown.test.ts +65 -0
  319. package/tests/notesPlugin.test.ts +162 -0
  320. package/tests/notifications.test.ts +87 -0
  321. package/tests/persistence.test.ts +51 -0
  322. package/tests/saveLoad.test.ts +373 -0
  323. package/tests/settings.test.ts +178 -0
  324. package/tests/traceStore.test.ts +46 -0
  325. package/tests/util/calculateNewEdge.test.ts +98 -0
  326. package/tests/util/getSocketsByNodeTypeAndHandleType.test.ts +31 -0
  327. package/tests/util/hasPositionMetaData.test.ts +33 -0
  328. package/tests/util/isBehaveNode.test.ts +22 -0
  329. package/tests/util/isHandleConnected.test.ts +37 -0
  330. package/tests/util/mergeSockets.test.ts +43 -0
  331. package/tests/visual/README.md +64 -0
  332. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-alignment-chromium-win32.png +0 -0
  333. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-conversation-chromium-win32.png +0 -0
  334. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-events-chromium-win32.png +0 -0
  335. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-history-chromium-win32.png +0 -0
  336. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-keymaps-chromium-win32.png +0 -0
  337. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-layers-chromium-win32.png +0 -0
  338. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-legend-chromium-win32.png +0 -0
  339. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-localGraphRunner-chromium-win32.png +0 -0
  340. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-logs-chromium-win32.png +0 -0
  341. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-nodeInputs-chromium-win32.png +0 -0
  342. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-nodePicker-chromium-win32.png +0 -0
  343. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-panel-chromium-win32.png +0 -0
  344. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-search-chromium-win32.png +0 -0
  345. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-systemSettings-chromium-win32.png +0 -0
  346. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-traces-chromium-win32.png +0 -0
  347. package/tests/visual/__screenshots__/panels.visual.test.tsx/panel-variables-chromium-win32.png +0 -0
  348. package/tests/visual/panels.visual.test.tsx +76 -0
  349. package/tests/wasdPan.test.ts +71 -0
  350. package/tsconfig.base.json +39 -0
  351. package/tsconfig.json +18 -59
  352. package/tsconfig.prod.json +23 -0
  353. package/tsdown.config.ts +15 -3
  354. package/typedoc.json +7 -7
  355. package/vite.config.js +7 -0
  356. package/vitest.config.ts +5 -2
  357. package/vitest.visual.config.ts +55 -0
  358. package/src/components/AutoSizeInput.tsx +0 -65
  359. package/src/components/Controls.tsx +0 -87
  360. package/src/components/InputSocket.tsx +0 -142
  361. package/src/components/Node.tsx +0 -68
  362. package/src/components/NodeContainer.tsx +0 -46
  363. package/src/components/NodePicker.tsx +0 -77
  364. package/src/components/OutputSocket.tsx +0 -58
  365. package/src/components/modals/ClearModal.tsx +0 -40
  366. package/src/components/modals/HelpModal.tsx +0 -36
  367. package/src/components/modals/LoadModal.tsx +0 -96
  368. package/src/components/modals/Modal.tsx +0 -64
  369. package/src/components/modals/SaveModal.tsx +0 -60
  370. package/src/hooks/useCustomNodeTypes.tsx +0 -31
  371. package/src/hooks/useGraphRunner.ts +0 -104
  372. package/src/hooks/useMergeMap.ts +0 -14
  373. package/src/hooks/useNodeSpecJson.ts +0 -20
  374. package/src/hooks/useQueriableDefinitions.ts +0 -22
  375. package/src/styles.css +0 -8
  376. package/tailwind.config.ts +0 -19
  377. package/tests/tsconfig.json +0 -10
  378. /package/src/{types.d.ts → types-declarations.d.ts} +0 -0
@@ -0,0 +1,637 @@
1
+ /**
2
+ * Shared graph execution utilities for both local and worker runners
3
+ */
4
+
5
+ import {
6
+ Engine,
7
+ type GraphInstance,
8
+ type ILifecycleEventEmitter,
9
+ readGraphFromJSON,
10
+ validateGraph,
11
+ ManualLifecycleEventEmitter,
12
+ DefaultLogger,
13
+ type ILogger,
14
+ type IRegistry,
15
+ writeNodeSpecsToJSON,
16
+ type NodeSpecJSON,
17
+ type GraphJSON
18
+ } from '@kiberon-labs/behave-graph';
19
+ import type {
20
+ GraphRunnerCapabilities,
21
+ RunStatus,
22
+ ServerGraphRunnerMessage,
23
+ ServerVariable,
24
+ ServerEvent,
25
+ TraceBatchEvent
26
+ } from '../graphrunner/types.js';
27
+ import { sleep } from '@kiberon-labs/behave-graph';
28
+
29
+ export interface ActiveRun {
30
+ runId: string;
31
+ graphId: string;
32
+ engine: Engine;
33
+ graphInstance: GraphInstance;
34
+ registry: IRegistry;
35
+ status: RunStatus;
36
+ startedAt: number;
37
+ performance: {
38
+ nodesExecuted: number;
39
+ eventsEmitted: number;
40
+ variableChanges: number;
41
+ };
42
+ isPaused: boolean;
43
+ executionPhase: 'start' | 'tick' | 'end' | 'completed';
44
+ currentTick: number;
45
+ /**
46
+ * Flushes any trace events still buffered by {@link setupTracing}. Set when
47
+ * tracing is enabled; call before emitting `completed`/`stopped` so the
48
+ * client receives the tail of the trace while the run id is still routable.
49
+ */
50
+ flushTracing?: () => void;
51
+ }
52
+
53
+ export interface MessageContext {
54
+ sendMessage: (message: ServerGraphRunnerMessage) => void;
55
+ sendError: (
56
+ code: string,
57
+ message: string,
58
+ details?: Record<string, unknown>
59
+ ) => void;
60
+ }
61
+
62
+ /**
63
+ * Create a logger that forwards messages through a callback
64
+ */
65
+ export function createForwardingLogger(
66
+ runId: string,
67
+ graphId: string,
68
+ onLog: (message: ServerGraphRunnerMessage) => void
69
+ ): ILogger {
70
+ const baseLogger = new DefaultLogger();
71
+
72
+ return {
73
+ log: (severity: string, text: string) => {
74
+ baseLogger.log(severity as any, text);
75
+ onLog({
76
+ type: 'log',
77
+ runId,
78
+ graphId,
79
+ level: severity,
80
+ message: text
81
+ });
82
+ }
83
+ };
84
+ }
85
+
86
+ /**
87
+ * Prepare a registry with required dependencies injected
88
+ */
89
+ export function prepareRegistryWithDependencies(
90
+ registry: IRegistry,
91
+ logger: ILogger
92
+ ): IRegistry {
93
+ // Ensure lifecycle event emitter and logger are available in registry
94
+ if (
95
+ !registry.dependencies?.ILifecycleEventEmitter ||
96
+ !registry.dependencies?.ILogger
97
+ ) {
98
+ // Create a new registry with required dependencies injected
99
+ return {
100
+ ...registry,
101
+ dependencies: {
102
+ ...registry.dependencies,
103
+ ILifecycleEventEmitter:
104
+ registry.dependencies?.ILifecycleEventEmitter ||
105
+ new ManualLifecycleEventEmitter(),
106
+ ILogger: logger
107
+ }
108
+ };
109
+ } else {
110
+ // Replace the existing logger
111
+ return {
112
+ ...registry,
113
+ dependencies: {
114
+ ...registry.dependencies,
115
+ ILogger: logger
116
+ }
117
+ };
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Parse and validate a graph
123
+ */
124
+ export function parseAndValidateGraph(
125
+ graphData: GraphJSON,
126
+ registry: IRegistry
127
+ ): { graphInstance: GraphInstance; errors: string[] } {
128
+ const graphInstance = readGraphFromJSON({
129
+ graphJson: graphData,
130
+ registry
131
+ });
132
+
133
+ const errors = validateGraph(graphInstance);
134
+ return { graphInstance, errors };
135
+ }
136
+
137
+ /**
138
+ * Generate a unique ID
139
+ */
140
+ export function generateId(prefix: string): string {
141
+ return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
142
+ }
143
+
144
+ /**
145
+ * Handle hello message
146
+ */
147
+ export function handleHello(
148
+ message: { type: 'hello'; protocolVersion: string },
149
+ serverId: string,
150
+ ctx: MessageContext
151
+ ): void {
152
+ ctx.sendMessage({
153
+ type: 'welcome',
154
+ protocolVersion: message.protocolVersion,
155
+ serverId,
156
+ authenticated: true,
157
+ userId: 'local-user'
158
+ });
159
+ }
160
+
161
+ /**
162
+ * Handle createSession message
163
+ */
164
+ export function handleCreateSession(
165
+ _message: { type: 'createSession'; metadata?: Record<string, unknown> },
166
+ ctx: MessageContext
167
+ ): string {
168
+ const sessionId = generateId('session');
169
+ ctx.sendMessage({
170
+ type: 'sessionCreated',
171
+ sessionId,
172
+ expiresAt: Date.now() + 24 * 60 * 60 * 1000
173
+ });
174
+ return sessionId;
175
+ }
176
+
177
+ /**
178
+ * Handle getCapabilities message
179
+ */
180
+ export function handleGetCapabilities(ctx: MessageContext): void {
181
+ const capabilities: GraphRunnerCapabilities = {
182
+ trace: true,
183
+ validation: true,
184
+ graphRegistry: false,
185
+ eventFiltering: false,
186
+ batchOperations: false,
187
+ runHistory: false,
188
+ runtimeMetadata: true,
189
+ maxConcurrentRuns: 10
190
+ };
191
+
192
+ ctx.sendMessage({
193
+ type: 'capabilities',
194
+ capabilities
195
+ });
196
+ }
197
+
198
+ /** Flush buffered trace events roughly once per frame. */
199
+ const TRACE_FLUSH_INTERVAL_MS = 16;
200
+ /** Safety valve: flush early if a single window buffers this many events. */
201
+ const TRACE_FLUSH_MAX_EVENTS = 2048;
202
+
203
+ /**
204
+ * Setup tracing for a run.
205
+ *
206
+ * Node execution events are buffered and flushed as a single `traceBatch`
207
+ * message per flush window instead of one `trace` message per event. A graph
208
+ * ticking at display rate executes every node twice per frame (start + end);
209
+ * sending each event individually made the message pipeline (store updates,
210
+ * postMessage for the worker runner) the dominant per-frame cost.
211
+ */
212
+ export function setupTracing(
213
+ run: ActiveRun,
214
+ graphId: string,
215
+ ctx: MessageContext
216
+ ): void {
217
+ let buffer: TraceBatchEvent[] = [];
218
+ let flushTimer: ReturnType<typeof setTimeout> | undefined;
219
+
220
+ const flush = () => {
221
+ if (flushTimer !== undefined) {
222
+ clearTimeout(flushTimer);
223
+ flushTimer = undefined;
224
+ }
225
+ if (buffer.length === 0) return;
226
+ const events = buffer;
227
+ buffer = [];
228
+ ctx.sendMessage({
229
+ type: 'traceBatch',
230
+ runId: run.runId,
231
+ graphId,
232
+ events
233
+ });
234
+ };
235
+ run.flushTracing = flush;
236
+
237
+ const push = (event: TraceBatchEvent) => {
238
+ buffer.push(event);
239
+ if (buffer.length >= TRACE_FLUSH_MAX_EVENTS) {
240
+ flush();
241
+ return;
242
+ }
243
+ if (flushTimer === undefined) {
244
+ flushTimer = setTimeout(flush, TRACE_FLUSH_INTERVAL_MS);
245
+ }
246
+ };
247
+
248
+ run.engine.onNodeExecutionStart.addListener((node) => {
249
+ run.performance.nodesExecuted++;
250
+ push({
251
+ nodeId: node.id,
252
+ event: 'start',
253
+ data: { typeName: node.description.typeName },
254
+ timestamp: Date.now() - run.startedAt
255
+ });
256
+ });
257
+
258
+ run.engine.onNodeExecutionEnd.addListener((node) => {
259
+ push({
260
+ nodeId: node.id,
261
+ event: 'end',
262
+ data: { typeName: node.description.typeName },
263
+ timestamp: Date.now() - run.startedAt
264
+ });
265
+ });
266
+ }
267
+
268
+ /**
269
+ * Setup variable change tracking for a run
270
+ */
271
+ export function setupVariableChangeTracking(
272
+ run: ActiveRun,
273
+ graphId: string,
274
+ ctx: MessageContext
275
+ ): void {
276
+ // Track old values so we can report them in the change event
277
+ const variableOldValues = new Map<string, unknown>();
278
+
279
+ const variables = Object.values(run.graphInstance.variables);
280
+
281
+ for (const variable of variables) {
282
+ // Store initial value as the "old" value
283
+ variableOldValues.set(variable.id, variable.get());
284
+
285
+ variable.onChanged.addListener(() => {
286
+ run.performance.variableChanges++;
287
+ const oldValue = variableOldValues.get(variable.id);
288
+ const newValue = variable.get();
289
+
290
+ // Update tracked value for next change
291
+ variableOldValues.set(variable.id, newValue);
292
+
293
+ ctx.sendMessage({
294
+ type: 'variableChanged',
295
+ runId: run.runId,
296
+ graphId,
297
+ variableName: variable.name,
298
+ oldValue,
299
+ newValue
300
+ });
301
+ });
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Execute a graph through its lifecycle phases
307
+ */
308
+ /**
309
+ * The single graph-execution lifecycle shared by both runners (the in-browser
310
+ * local transport and the web-worker runner). It drives the start → tick → end →
311
+ * completed phase machine and emits the `completed` / error messages; runner-
312
+ * specific behaviour (how fibers are stepped, tick timing, and what to do on
313
+ * completion/error) is injected via {@link ExecuteGraphLifecycleOptions} hooks so
314
+ * neither runner keeps its own copy of this logic.
315
+ */
316
+ export interface ExecuteGraphLifecycleOptions {
317
+ /** Tick timing when no {@link tickStrategy} is given. Defaults to 50ms. */
318
+ tickInterval?: number;
319
+ /**
320
+ * When true, the run finalizes (end phase, `completed` message, engine
321
+ * dispose) once its flows drain. Defaults to false: the run idles in the
322
+ * tick phase, keeping event-node subscriptions live and draining any fibers
323
+ * they commit, until it is explicitly stopped.
324
+ */
325
+ autoEnd?: boolean;
326
+ /**
327
+ * Run the engine's pending fibers for the current phase. Defaults to
328
+ * `run.engine.executeAllAsync()`; the local runner injects a pause-aware
329
+ * executor that also honours its step-delay / speed settings.
330
+ */
331
+ executeStep?: () => Promise<void>;
332
+ /** Timing between tick iterations. Defaults to `sleep(tickInterval)`. */
333
+ tickStrategy?: () => Promise<void>;
334
+ /** Invoked after each tick iteration. */
335
+ onStepComplete?: () => Promise<void>;
336
+ /**
337
+ * Invoked after a natural completion — the run is marked completed, the
338
+ * `completed` message has been sent, and the engine disposed. Lets a runner
339
+ * run session hooks and sync its own state (e.g. the local panel's status).
340
+ */
341
+ onComplete?: () => void | Promise<void>;
342
+ /**
343
+ * Invoked on error (after the run is marked errored, before the engine is
344
+ * disposed and the error rethrown). Replaces the default `sendError`.
345
+ */
346
+ onError?: (error: Error) => void | Promise<void>;
347
+ }
348
+
349
+ /** True when a lifecycle event has at least one listener attached. */
350
+ function hasListeners(event?: { listenerCount: number }): boolean {
351
+ return !!event && event.listenerCount > 0;
352
+ }
353
+
354
+ /**
355
+ * Run the `start` lifecycle phase: emit the start event (if anyone is
356
+ * listening) and drain the fibers it commits, then advance to the tick phase.
357
+ */
358
+ async function runStartPhase(
359
+ run: ActiveRun,
360
+ eventEmitter: ILifecycleEventEmitter | undefined,
361
+ executeStep: () => Promise<unknown>
362
+ ): Promise<void> {
363
+ if (run.executionPhase !== 'start') return;
364
+ if (hasListeners(eventEmitter?.startEvent)) {
365
+ eventEmitter!.startEvent.emit();
366
+ await executeStep();
367
+ }
368
+ run.executionPhase = 'tick';
369
+ }
370
+
371
+ /**
372
+ * Run the `tick` phase until the run is paused or stopped. Returns `true` when
373
+ * the loop yielded control mid-tick (paused/stopped) so the caller should bail
374
+ * out without finalizing.
375
+ *
376
+ * A run stays alive here even with no tick listeners: completing it would
377
+ * dispose the engine and tear down event-node subscriptions (ai/onToolCall,
378
+ * ai/onMessage, custom triggers) that fire out-of-band, after the start flow has
379
+ * drained. The loop keeps draining fibers those events commit. Pass
380
+ * `autoEnd: true` to restore the finalize-when-drained behaviour for
381
+ * fire-and-forget runs.
382
+ */
383
+ async function runTickPhase(
384
+ run: ActiveRun,
385
+ eventEmitter: ILifecycleEventEmitter | undefined,
386
+ executeStep: () => Promise<unknown>,
387
+ tickStrategy: () => Promise<unknown>,
388
+ options?: ExecuteGraphLifecycleOptions
389
+ ): Promise<boolean> {
390
+ if (run.executionPhase !== 'tick') return false;
391
+
392
+ const hasTickListeners = hasListeners(eventEmitter?.tickEvent);
393
+ const autoEnd = options?.autoEnd ?? false;
394
+ if (!hasTickListeners && autoEnd) {
395
+ run.executionPhase = 'end';
396
+ return false;
397
+ }
398
+
399
+ while (!run.isPaused && run.status === 'running') {
400
+ if (hasTickListeners) {
401
+ eventEmitter!.tickEvent.emit();
402
+ run.currentTick++;
403
+ }
404
+ await executeStep();
405
+
406
+ if (options?.onStepComplete) {
407
+ await options.onStepComplete();
408
+ }
409
+
410
+ if (run.isPaused || run.status !== 'running') {
411
+ return true;
412
+ }
413
+
414
+ await tickStrategy();
415
+ }
416
+ return false;
417
+ }
418
+
419
+ /**
420
+ * Run the `end` lifecycle phase: emit the end event (if listened) and drain,
421
+ * then mark the run as reaching the `completed` phase.
422
+ */
423
+ async function runEndPhase(
424
+ run: ActiveRun,
425
+ eventEmitter: ILifecycleEventEmitter | undefined,
426
+ executeStep: () => Promise<unknown>
427
+ ): Promise<void> {
428
+ if (run.executionPhase !== 'end' || run.isPaused) return;
429
+ if (hasListeners(eventEmitter?.endEvent)) {
430
+ eventEmitter!.endEvent.emit();
431
+ await executeStep();
432
+ }
433
+ run.executionPhase = 'completed';
434
+ }
435
+
436
+ /**
437
+ * Finalize a run that ran out of fibers and isn't paused. Only autoEnd runs
438
+ * advance this far; by default a run idles in the tick phase until stopped.
439
+ */
440
+ async function finalizeCompletedRun(
441
+ run: ActiveRun,
442
+ graphId: string,
443
+ ctx: MessageContext,
444
+ options?: ExecuteGraphLifecycleOptions
445
+ ): Promise<void> {
446
+ if (
447
+ run.executionPhase !== 'completed' ||
448
+ run.isPaused ||
449
+ !(options?.autoEnd ?? false)
450
+ ) {
451
+ return;
452
+ }
453
+
454
+ run.status = 'completed';
455
+ const elapsedMs = Date.now() - run.startedAt;
456
+
457
+ // Deliver any buffered trace events before `completed` , the client
458
+ // unregisters the run id on completion and would drop a late batch.
459
+ run.flushTracing?.();
460
+
461
+ ctx.sendMessage({
462
+ type: 'completed',
463
+ runId: run.runId,
464
+ graphId,
465
+ completedAt: Date.now(),
466
+ elapsedMs,
467
+ result: null,
468
+ performance: run.performance
469
+ });
470
+
471
+ run.engine.dispose();
472
+ await options?.onComplete?.();
473
+ }
474
+
475
+ /** Mark the run errored, notify, dispose the engine, and rethrow. */
476
+ async function handleLifecycleError(
477
+ run: ActiveRun,
478
+ graphId: string,
479
+ ctx: MessageContext,
480
+ error: unknown,
481
+ options?: ExecuteGraphLifecycleOptions
482
+ ): Promise<never> {
483
+ run.status = 'error';
484
+ run.flushTracing?.();
485
+ const err = error instanceof Error ? error : new Error(String(error));
486
+ if (options?.onError) {
487
+ await options.onError(err);
488
+ } else {
489
+ ctx.sendError('NODE_EXECUTION_ERROR', err.message, {
490
+ runId: run.runId,
491
+ graphId
492
+ });
493
+ }
494
+ run.engine.dispose();
495
+ throw error;
496
+ }
497
+
498
+ export async function executeGraphLifecycle(
499
+ run: ActiveRun,
500
+ graphId: string,
501
+ ctx: MessageContext,
502
+ options?: ExecuteGraphLifecycleOptions
503
+ ): Promise<void> {
504
+ const executeStep =
505
+ options?.executeStep ?? (() => run.engine.executeAllAsync());
506
+ const tickStrategy =
507
+ options?.tickStrategy ??
508
+ (() => sleep((options?.tickInterval ?? 50) / 1000));
509
+
510
+ try {
511
+ const eventEmitter = run.registry.dependencies?.ILifecycleEventEmitter as
512
+ | ILifecycleEventEmitter
513
+ | undefined;
514
+
515
+ await runStartPhase(run, eventEmitter, executeStep);
516
+
517
+ const yielded = await runTickPhase(
518
+ run,
519
+ eventEmitter,
520
+ executeStep,
521
+ tickStrategy,
522
+ options
523
+ );
524
+ if (yielded) return;
525
+
526
+ await runEndPhase(run, eventEmitter, executeStep);
527
+ await finalizeCompletedRun(run, graphId, ctx, options);
528
+ } catch (error) {
529
+ await handleLifecycleError(run, graphId, ctx, error, options);
530
+ }
531
+ }
532
+
533
+ /**
534
+ * Handle getServerVariables message
535
+ */
536
+ export function handleGetServerVariables(
537
+ variables: ServerVariable[],
538
+ ctx: MessageContext
539
+ ): void {
540
+ ctx.sendMessage({
541
+ type: 'serverVariables',
542
+ variables
543
+ });
544
+ }
545
+
546
+ /**
547
+ * Handle getServerEvents message
548
+ */
549
+ export function handleGetServerEvents(
550
+ events: ServerEvent[],
551
+ ctx: MessageContext
552
+ ): void {
553
+ ctx.sendMessage({
554
+ type: 'serverEvents',
555
+ events
556
+ });
557
+ }
558
+
559
+ /**
560
+ * Handle getSocketConstraints message
561
+ */
562
+ export function handleGetSocketConstraints(
563
+ message: {
564
+ nodeType: string;
565
+ socketName: string;
566
+ },
567
+ registry: IRegistry,
568
+ ctx: MessageContext
569
+ ): void {
570
+ const nodeSpec = writeNodeSpecsToJSON(registry).find(
571
+ (spec) => spec.type === message.nodeType
572
+ );
573
+ if (!nodeSpec) {
574
+ ctx.sendError('INVALID_GRAPH', `Node type not found: ${message.nodeType}`);
575
+ return;
576
+ }
577
+
578
+ const socket = [...nodeSpec.inputs, ...nodeSpec.outputs].find(
579
+ (s) => s.name === message.socketName
580
+ );
581
+
582
+ if (!socket) {
583
+ ctx.sendError(
584
+ 'INVALID_GRAPH',
585
+ `Socket not found: ${message.socketName} on node ${message.nodeType}`
586
+ );
587
+ return;
588
+ }
589
+
590
+ const constraints: {
591
+ type: 'enum' | 'range' | 'pattern' | 'custom';
592
+ choices?: Array<{ value: unknown; label: string }>;
593
+ min?: number;
594
+ max?: number;
595
+ pattern?: string;
596
+ validator?: string;
597
+ } = {
598
+ type: 'custom'
599
+ };
600
+
601
+ if ('choices' in socket && Array.isArray(socket.choices)) {
602
+ constraints.type = 'enum';
603
+ constraints.choices = socket.choices.map(
604
+ (choice: { text: string; value: unknown } | string) =>
605
+ typeof choice === 'string'
606
+ ? { value: choice, label: choice }
607
+ : { value: choice.value, label: choice.text }
608
+ );
609
+ }
610
+
611
+ ctx.sendMessage({
612
+ type: 'socketConstraints',
613
+ nodeType: message.nodeType,
614
+ socketName: message.socketName,
615
+ valueType: socket.valueType,
616
+ constraints
617
+ });
618
+ }
619
+
620
+ /**
621
+ * Handle getNodeTypes message
622
+ */
623
+ export function handleGetNodeTypes(
624
+ registry: IRegistry,
625
+ ctx: MessageContext
626
+ ): void {
627
+ let nodes: NodeSpecJSON[] = [];
628
+
629
+ if (registry.nodes) {
630
+ nodes = writeNodeSpecsToJSON(registry);
631
+ }
632
+
633
+ ctx.sendMessage({
634
+ type: 'nodeTypes',
635
+ nodes
636
+ });
637
+ }