@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,55 @@
1
+ import path from 'node:path';
2
+ import { playwright } from '@vitest/browser-playwright';
3
+ import { defineConfig } from 'vitest/config';
4
+
5
+ /**
6
+ * Dedicated config for visual (pixel) regression tests.
7
+ *
8
+ * These run in a real browser via Vitest browser mode + Playwright and use the
9
+ * built-in `toMatchScreenshot` assertion to detect rendering regressions.
10
+ *
11
+ * Run with `pnpm test:visual` (and `pnpm test:visual:update` to refresh
12
+ * baselines). It is intentionally separate from the default happy-dom unit-test
13
+ * config so the heavy browser runner is only spun up when explicitly requested.
14
+ *
15
+ * Screenshots are platform-sensitive (fonts/anti-aliasing differ across OSes),
16
+ * so Vitest stores baselines under per-platform folders. Generate/refresh
17
+ * baselines on the same platform/CI image that will verify them.
18
+ */
19
+ export default defineConfig({
20
+ test: {
21
+ include: ['tests/visual/**/*.visual.test.{ts,tsx}'],
22
+ watch: false,
23
+ browser: {
24
+ enabled: true,
25
+ provider: playwright(),
26
+ headless: true,
27
+ instances: [{ browser: 'chromium' }],
28
+ // Deterministic viewport, large enough to contain a panel frame without
29
+ // introducing page scrollbars that would shift layout.
30
+ viewport: { width: 900, height: 700 },
31
+ expect: {
32
+ toMatchScreenshot: {
33
+ // Allow a tiny amount of anti-aliasing noise without failing.
34
+ comparatorName: 'pixelmatch',
35
+ comparatorOptions: {
36
+ allowedMismatchedPixelRatio: 0.02
37
+ }
38
+ }
39
+ }
40
+ }
41
+ },
42
+ resolve: {
43
+ // The browser runner renders through vitest-browser-react, which can pull
44
+ // its own React/React-DOM copy (a different patch than the app's pinned
45
+ // 19.2.3). Two React instances means the renderer sets the hook dispatcher
46
+ // on one copy while the panels call hooks on the other, producing "Invalid
47
+ // hook call / more than one copy of React" and a null dispatcher. Force a
48
+ // single instance so the renderer and the components share it.
49
+ dedupe: ['react', 'react-dom'],
50
+ alias: {
51
+ '~': path.resolve(__dirname, './src'),
52
+ '@': path.resolve(__dirname, './src')
53
+ }
54
+ }
55
+ });
@@ -1,65 +0,0 @@
1
- import React from 'react';
2
- import {
3
- type CSSProperties,
4
- type HTMLProps,
5
- useCallback,
6
- useEffect,
7
- useRef,
8
- useState
9
- } from 'react';
10
-
11
- export type AutoSizeInputProps = HTMLProps<HTMLInputElement> & {
12
- minWidth?: number;
13
- };
14
-
15
- const baseStyles: CSSProperties = {
16
- position: 'absolute',
17
- top: 0,
18
- left: 0,
19
- visibility: 'hidden',
20
- height: 0,
21
- width: 'auto',
22
- whiteSpace: 'pre'
23
- };
24
-
25
- export const AutoSizeInput: React.FC<AutoSizeInputProps> = ({
26
- minWidth = 30,
27
- ...props
28
- }) => {
29
- const inputRef = useRef<HTMLInputElement | null>(null);
30
- const measureRef = useRef<HTMLSpanElement | null>(null);
31
- const [styles, setStyles] = useState<CSSProperties>({});
32
-
33
- // grab the font size of the input on ref mount
34
- const setRef = useCallback((input: HTMLInputElement | null) => {
35
- if (input) {
36
- const styles = window.getComputedStyle(input);
37
- setStyles({
38
- fontSize: styles.getPropertyValue('font-size'),
39
- paddingLeft: styles.getPropertyValue('padding-left'),
40
- paddingRight: styles.getPropertyValue('padding-right')
41
- });
42
- }
43
- inputRef.current = input;
44
- }, []);
45
-
46
- // measure the text on change and update input
47
- useEffect(() => {
48
- if (measureRef.current === null) return;
49
- if (inputRef.current === null) return;
50
-
51
- const padding = props.type === 'number' || props.type === 'float' ? 20 : 0;
52
-
53
- const width = measureRef.current.clientWidth + padding;
54
- inputRef.current.style.width = Math.max(minWidth, width) + 'px';
55
- }, [props.value, minWidth, styles, props.type]);
56
-
57
- return (
58
- <>
59
- <input ref={setRef} {...props} />
60
- <span ref={measureRef} style={{ ...baseStyles, ...styles }}>
61
- {props.value}
62
- </span>
63
- </>
64
- );
65
- };
@@ -1,87 +0,0 @@
1
- import type { GraphJSON, NodeSpecJSON } from '@kiberon-labs/behave-graph';
2
- import {
3
- faDownload,
4
- faPause,
5
- faPlay,
6
- faQuestion,
7
- faTrash,
8
- faUpload
9
- } from '@fortawesome/free-solid-svg-icons';
10
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
11
- import { useState } from 'react';
12
- import React from 'react';
13
- import { ControlButton, Controls } from 'reactflow';
14
-
15
- import { ClearModal } from './modals/ClearModal.js';
16
- import { HelpModal } from './modals/HelpModal.js';
17
- import { type Examples, LoadModal } from './modals/LoadModal.js';
18
- import { SaveModal } from './modals/SaveModal.js';
19
-
20
- export type CustomControlsProps = {
21
- playing: boolean;
22
- togglePlay: () => void;
23
- setBehaviorGraph: (value: GraphJSON) => void;
24
- examples: Examples;
25
- specJson: NodeSpecJSON[] | undefined;
26
- };
27
-
28
- export const CustomControls: React.FC<CustomControlsProps> = ({
29
- playing,
30
- togglePlay,
31
- setBehaviorGraph,
32
- examples,
33
- specJson
34
- }: {
35
- playing: boolean;
36
- togglePlay: () => void;
37
- setBehaviorGraph: (value: GraphJSON) => void;
38
- examples: Examples;
39
- specJson: NodeSpecJSON[] | undefined;
40
- }) => {
41
- const [loadModalOpen, setLoadModalOpen] = useState(false);
42
- const [saveModalOpen, setSaveModalOpen] = useState(false);
43
- const [helpModalOpen, setHelpModalOpen] = useState(false);
44
- const [clearModalOpen, setClearModalOpen] = useState(false);
45
-
46
- return (
47
- <>
48
- <Controls>
49
- <ControlButton title="Help" onClick={() => setHelpModalOpen(true)}>
50
- <FontAwesomeIcon icon={faQuestion} />
51
- </ControlButton>
52
- <ControlButton title="Load" onClick={() => setLoadModalOpen(true)}>
53
- <FontAwesomeIcon icon={faUpload} />
54
- </ControlButton>
55
- <ControlButton title="Save" onClick={() => setSaveModalOpen(true)}>
56
- <FontAwesomeIcon icon={faDownload} />
57
- </ControlButton>
58
- <ControlButton title="Clear" onClick={() => setClearModalOpen(true)}>
59
- <FontAwesomeIcon icon={faTrash} />
60
- </ControlButton>
61
- <ControlButton title="Run" onClick={togglePlay}>
62
- <FontAwesomeIcon icon={playing ? faPause : faPlay} />
63
- </ControlButton>
64
- </Controls>
65
- <LoadModal
66
- open={loadModalOpen}
67
- onClose={() => setLoadModalOpen(false)}
68
- setBehaviorGraph={setBehaviorGraph}
69
- examples={examples}
70
- />
71
- {specJson && (
72
- <SaveModal
73
- open={saveModalOpen}
74
- specJson={specJson}
75
- onClose={() => setSaveModalOpen(false)}
76
- />
77
- )}
78
- <HelpModal open={helpModalOpen} onClose={() => setHelpModalOpen(false)} />
79
- <ClearModal
80
- open={clearModalOpen}
81
- onClose={() => setClearModalOpen(false)}
82
- />
83
- </>
84
- );
85
- };
86
-
87
- export default CustomControls;
@@ -1,142 +0,0 @@
1
- import type {
2
- InputSocketSpecJSON,
3
- NodeSpecJSON
4
- } from '@kiberon-labs/behave-graph';
5
- import { faCaretRight } from '@fortawesome/free-solid-svg-icons';
6
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
7
- import cx from 'classnames';
8
- import React from 'react';
9
- import { type Connection, Handle, Position, useReactFlow } from 'reactflow';
10
-
11
- import { colors, valueTypeColorMap } from '../util/colors.js';
12
- import { isValidConnection } from '../util/isValidConnection.js';
13
- import { AutoSizeInput } from './AutoSizeInput.js';
14
-
15
- export type InputSocketProps = {
16
- connected: boolean;
17
- value: any | undefined;
18
- onChange: (key: string, value: any) => void;
19
- specJSON: NodeSpecJSON[];
20
- } & InputSocketSpecJSON;
21
-
22
- const InputFieldForValue = ({
23
- choices,
24
- value,
25
- defaultValue,
26
- onChange,
27
- name,
28
- valueType
29
- }: Pick<
30
- InputSocketProps,
31
- 'choices' | 'value' | 'defaultValue' | 'name' | 'onChange' | 'valueType'
32
- >) => {
33
- const showChoices = choices?.length;
34
- //Stops 'undefined'
35
- const defaultSafeValue =
36
- defaultValue !== undefined ? String(defaultValue) : '';
37
- const inputVal = value !== undefined ? String(value) : defaultSafeValue;
38
-
39
- if (showChoices)
40
- return (
41
- <select
42
- className="bg-gray-600 disabled:bg-gray-700 py-1 px-2 nodrag"
43
- value={value ?? defaultValue ?? ''}
44
- onChange={(e) => onChange(name, e.currentTarget.value)}
45
- >
46
- <>
47
- {choices.map((choice) => (
48
- <option key={choice.text} value={choice.value}>
49
- {choice.text}
50
- </option>
51
- ))}
52
- </>
53
- </select>
54
- );
55
-
56
- return (
57
- <>
58
- {valueType === 'string' && (
59
- <AutoSizeInput
60
- type="text"
61
- className="bg-gray-600 disabled:bg-gray-700 py-1 px-2 nodrag"
62
- value={inputVal}
63
- onChange={(e) => onChange(name, e.currentTarget.value)}
64
- />
65
- )}
66
- {valueType === 'number' && (
67
- <AutoSizeInput
68
- type="number"
69
- className=" bg-gray-600 disabled:bg-gray-700 py-1 px-2 nodrag"
70
- value={inputVal}
71
- onChange={(e) => onChange(name, e.currentTarget.value)}
72
- />
73
- )}
74
- {valueType === 'float' && (
75
- <AutoSizeInput
76
- type="number"
77
- className=" bg-gray-600 disabled:bg-gray-700 py-1 px-2 nodrag"
78
- value={inputVal}
79
- onChange={(e) => onChange(name, e.currentTarget.value)}
80
- />
81
- )}
82
- {valueType === 'integer' && (
83
- <AutoSizeInput
84
- type="number"
85
- className=" bg-gray-600 disabled:bg-gray-700 py-1 px-2 nodrag"
86
- value={inputVal}
87
- onChange={(e) => onChange(name, e.currentTarget.value)}
88
- />
89
- )}
90
- {valueType === 'boolean' && (
91
- <input
92
- type="checkbox"
93
- className=" bg-gray-600 disabled:bg-gray-700 py-1 px-2 nodrag"
94
- value={inputVal}
95
- onChange={(e) => onChange(name, e.currentTarget.checked)}
96
- />
97
- )}
98
- </>
99
- );
100
- };
101
-
102
- const InputSocket: React.FC<InputSocketProps> = ({
103
- connected,
104
- specJSON,
105
- ...rest
106
- }) => {
107
- const { name, valueType } = rest;
108
- const instance = useReactFlow();
109
-
110
- const isFlowSocket = valueType === 'flow';
111
-
112
- let colorName = valueTypeColorMap[valueType];
113
- if (colorName === undefined) {
114
- colorName = 'red';
115
- }
116
-
117
- // @ts-ignore
118
- const [backgroundColor, borderColor] = colors[colorName];
119
- const showName = isFlowSocket === false || name !== 'flow';
120
-
121
- return (
122
- <div className="flex grow items-center justify-start h-7">
123
- {isFlowSocket && (
124
- <FontAwesomeIcon icon={faCaretRight} color="#ffffff" size="lg" />
125
- )}
126
- {showName && <div className="capitalize mr-2">{name}</div>}
127
-
128
- {!isFlowSocket && !connected && <InputFieldForValue {...rest} />}
129
- <Handle
130
- id={name}
131
- type="target"
132
- position={Position.Left}
133
- className={cx(borderColor, connected ? backgroundColor : 'bg-gray-800')}
134
- isValidConnection={(connection: Connection) =>
135
- isValidConnection(connection, instance, specJSON)
136
- }
137
- />
138
- </div>
139
- );
140
- };
141
-
142
- export default InputSocket;
@@ -1,68 +0,0 @@
1
- import type { NodeSpecJSON } from '@kiberon-labs/behave-graph';
2
- import React from 'react';
3
- import { useEdges, type NodeProps as FlowNodeProps } from 'reactflow';
4
-
5
- import { useChangeNodeData } from '../hooks/useChangeNodeData.js';
6
- import { isHandleConnected } from '../util/isHandleConnected.js';
7
- import InputSocket from './InputSocket.js';
8
- import NodeContainer from './NodeContainer.js';
9
- import OutputSocket from './OutputSocket.js';
10
-
11
- type NodeProps = FlowNodeProps & {
12
- spec: NodeSpecJSON;
13
- allSpecs: NodeSpecJSON[];
14
- };
15
-
16
- const getPairs = <T, U>(arr1: T[], arr2: U[]) => {
17
- const max = Math.max(arr1.length, arr2.length);
18
- const pairs = [];
19
- for (let i = 0; i < max; i++) {
20
- const pair: [T | undefined, U | undefined] = [arr1[i], arr2[i]];
21
- pairs.push(pair);
22
- }
23
- return pairs;
24
- };
25
-
26
- export const Node: React.FC<NodeProps> = ({
27
- id,
28
- data,
29
- spec,
30
- selected,
31
- allSpecs
32
- }: NodeProps) => {
33
- const edges = useEdges();
34
- const handleChange = useChangeNodeData(id);
35
- const pairs = getPairs(spec.inputs, spec.outputs);
36
- return (
37
- <NodeContainer
38
- title={spec.label}
39
- category={spec.category}
40
- selected={selected}
41
- >
42
- {pairs.map(([input, output], ix) => (
43
- <div
44
- key={ix}
45
- className="flex flex-row justify-between gap-8 relative px-2"
46
- // className={styles.container}
47
- >
48
- {input && (
49
- <InputSocket
50
- {...input}
51
- specJSON={allSpecs}
52
- value={data[input.name] ?? input.defaultValue}
53
- onChange={handleChange}
54
- connected={isHandleConnected(edges, id, input.name, 'target')}
55
- />
56
- )}
57
- {output && (
58
- <OutputSocket
59
- {...output}
60
- specJSON={allSpecs}
61
- connected={isHandleConnected(edges, id, output.name, 'source')}
62
- />
63
- )}
64
- </div>
65
- ))}
66
- </NodeContainer>
67
- );
68
- };
@@ -1,46 +0,0 @@
1
- import { NodeCategory, type NodeSpecJSON } from '@kiberon-labs/behave-graph';
2
- import cx from 'classnames';
3
- import React, { type PropsWithChildren } from 'react';
4
-
5
- import { categoryColorMap, colors } from '../util/colors.js';
6
-
7
- type NodeProps = {
8
- title: string;
9
- category?: NodeSpecJSON['category'];
10
- selected: boolean;
11
- };
12
-
13
- const NodeContainer: React.FC<PropsWithChildren<NodeProps>> = ({
14
- title,
15
- category = NodeCategory.None,
16
- selected,
17
- children
18
- }) => {
19
- let colorName = categoryColorMap[category];
20
- if (colorName === undefined) {
21
- colorName = 'red';
22
- }
23
- let [backgroundColor, borderColor, textColor] = colors[colorName];
24
- if (selected) {
25
- borderColor = 'border-gray-800';
26
- }
27
- return (
28
- <div
29
- className={cx(
30
- 'rounded text-white text-sm bg-gray-800 min-w-[120px]',
31
- selected && 'outline outline-1'
32
- )}
33
- >
34
- <div className={`${backgroundColor} ${textColor} px-2 py-1 rounded-t`}>
35
- {title}
36
- </div>
37
- <div
38
- className={`flex flex-col gap-2 py-2 border-l border-r border-b ${borderColor} `}
39
- >
40
- {children}
41
- </div>
42
- </div>
43
- );
44
- };
45
-
46
- export default NodeContainer;
@@ -1,77 +0,0 @@
1
- import { type NodeSpecJSON } from '@kiberon-labs/behave-graph';
2
- import React, { useState } from 'react';
3
- import { useReactFlow, type XYPosition } from 'reactflow';
4
-
5
- import { useOnPressKey } from '../hooks/useOnPressKey.js';
6
-
7
- export type NodePickerFilters = {
8
- handleType: 'source' | 'target';
9
- valueType: string;
10
- };
11
-
12
- type NodePickerProps = {
13
- position: XYPosition;
14
- filters?: NodePickerFilters;
15
- onPickNode: (type: string, position: XYPosition) => void;
16
- onClose: () => void;
17
- specJSON: NodeSpecJSON[] | undefined;
18
- };
19
-
20
- export const NodePicker: React.FC<NodePickerProps> = ({
21
- position,
22
- onPickNode,
23
- onClose,
24
- filters,
25
- specJSON
26
- }: NodePickerProps) => {
27
- const [search, setSearch] = useState('');
28
- const instance = useReactFlow();
29
-
30
- useOnPressKey('Escape', onClose);
31
-
32
- if (!specJSON) return null;
33
- let filtered = specJSON;
34
- if (filters !== undefined) {
35
- filtered = filtered?.filter((node) => {
36
- const sockets =
37
- filters?.handleType === 'source' ? node.outputs : node.inputs;
38
- return sockets.some((socket) => socket.valueType === filters?.valueType);
39
- });
40
- }
41
-
42
- filtered =
43
- filtered?.filter((node) => {
44
- const term = search.toLowerCase();
45
- return node.type.toLowerCase().includes(term);
46
- }) || [];
47
-
48
- return (
49
- <div
50
- className="node-picker absolute z-10 text-sm text-white bg-gray-800 border rounded border-gray-500"
51
- style={{ top: position.y, left: position.x }}
52
- >
53
- <div className="bg-gray-500 p-2">Add Node</div>
54
- <div className="p-2">
55
- <input
56
- type="text"
57
- autoFocus
58
- placeholder="Type to filter"
59
- className=" bg-gray-600 disabled:bg-gray-700 w-full py-1 px-2"
60
- value={search}
61
- onChange={(e) => setSearch(e.target.value)}
62
- />
63
- </div>
64
- <div className="max-h-48 overflow-y-scroll">
65
- {filtered.map(({ type }) => (
66
- <div
67
- key={type}
68
- className="p-2 cursor-pointer border-b border-gray-600"
69
- onClick={() => onPickNode(type, instance.project(position))}
70
- >
71
- {type}
72
- </div>
73
- ))}
74
- </div>
75
- </div>
76
- );
77
- };
@@ -1,58 +0,0 @@
1
- import type {
2
- NodeSpecJSON,
3
- OutputSocketSpecJSON
4
- } from '@kiberon-labs/behave-graph';
5
- import { faCaretRight } from '@fortawesome/free-solid-svg-icons';
6
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
7
- import cx from 'classnames';
8
- import React from 'react';
9
- import { type Connection, Handle, Position, useReactFlow } from 'reactflow';
10
-
11
- import { colors, valueTypeColorMap } from '../util/colors.js';
12
- import { isValidConnection } from '../util/isValidConnection.js';
13
-
14
- export type OutputSocketProps = {
15
- connected: boolean;
16
- specJSON: NodeSpecJSON[];
17
- } & OutputSocketSpecJSON;
18
-
19
- export default function OutputSocket({
20
- specJSON,
21
- connected,
22
- valueType,
23
- name
24
- }: OutputSocketProps) {
25
- const instance = useReactFlow();
26
- const isFlowSocket = valueType === 'flow';
27
- let colorName = valueTypeColorMap[valueType];
28
- if (colorName === undefined) {
29
- colorName = 'red';
30
- }
31
- // @ts-ignore
32
- const [backgroundColor, borderColor] = colors[colorName];
33
- const showName = isFlowSocket === false || name !== 'flow';
34
-
35
- return (
36
- <div className="flex grow items-center justify-end h-7">
37
- {showName && <div className="capitalize">{name}</div>}
38
- {isFlowSocket && (
39
- <FontAwesomeIcon
40
- icon={faCaretRight}
41
- color="#ffffff"
42
- size="lg"
43
- className="ml-1"
44
- />
45
- )}
46
-
47
- <Handle
48
- id={name}
49
- type="source"
50
- position={Position.Right}
51
- className={cx(borderColor, connected ? backgroundColor : 'bg-gray-800')}
52
- isValidConnection={(connection: Connection) =>
53
- isValidConnection(connection, instance, specJSON)
54
- }
55
- />
56
- </div>
57
- );
58
- }
@@ -1,40 +0,0 @@
1
- import React from 'react';
2
- import { useReactFlow } from 'reactflow';
3
-
4
- import { Modal } from './Modal.js';
5
-
6
- export type ClearModalProps = {
7
- open?: boolean;
8
- onClose: () => void;
9
- };
10
-
11
- export const ClearModal: React.FC<ClearModalProps> = ({
12
- open = false,
13
- onClose
14
- }) => {
15
- const instance = useReactFlow();
16
-
17
- const handleClear = () => {
18
- instance.setNodes([]);
19
- instance.setEdges([]);
20
- // TODO better way to call fit vew after edges render
21
- setTimeout(() => {
22
- instance.fitView();
23
- }, 100);
24
- onClose();
25
- };
26
-
27
- return (
28
- <Modal
29
- title="Clear Graph"
30
- actions={[
31
- { label: 'Cancel', onClick: onClose },
32
- { label: 'Clear', onClick: handleClear }
33
- ]}
34
- open={open}
35
- onClose={onClose}
36
- >
37
- <p>Are you sure?</p>
38
- </Modal>
39
- );
40
- };
@@ -1,36 +0,0 @@
1
- import React from 'react';
2
-
3
- import { Modal } from './Modal.js';
4
-
5
- export type HelpModalProps = {
6
- open?: boolean;
7
- onClose: () => void;
8
- };
9
-
10
- export const HelpModal: React.FC<HelpModalProps> = ({
11
- open = false,
12
- onClose
13
- }) => {
14
- return (
15
- <Modal
16
- title="Help"
17
- actions={[{ label: 'Close', onClick: onClose }]}
18
- open={open}
19
- onClose={onClose}
20
- >
21
- <p className="mb-2">Right click anywhere to add a new node.</p>
22
- <p className="mb-2">
23
- Drag a connection into empty space to add a new node and connect it to
24
- the source.
25
- </p>
26
- <p className="mb-2">
27
- Click and drag on a socket to connect to another socket of the same
28
- type.
29
- </p>
30
- <p>
31
- Left click to select nodes or connections, backspace to delete selected
32
- nodes or connections.
33
- </p>
34
- </Modal>
35
- );
36
- };