@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,28 @@
1
+ import type { LogSeverity } from '@kiberon-labs/behave-graph';
2
+ import { create } from 'zustand';
3
+
4
+ interface ILogMessage {
5
+ message: string;
6
+ }
7
+
8
+ export interface ILog {
9
+ data: ILogMessage;
10
+ time: Date;
11
+ type: LogSeverity;
12
+ }
13
+
14
+ export type LogStore = {
15
+ logs: ILog[];
16
+ append: (log: ILog) => void;
17
+ clear: () => void;
18
+ };
19
+
20
+ export const logStoreFactory = () =>
21
+ create<LogStore>((set) => ({
22
+ logs: [],
23
+ append: (log: ILog) =>
24
+ set((state) => {
25
+ return { logs: [...state.logs, log] };
26
+ }),
27
+ clear: () => set(() => ({ logs: [] }))
28
+ }));
@@ -0,0 +1,41 @@
1
+ import { defaultMenuDataFactory } from '@/components/menubar';
2
+ import { createStore } from 'zustand';
3
+
4
+ export type IMenuItem = {
5
+ name: string;
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+ render: (rest: { [key: string]: any }) => React.ReactNode;
8
+ };
9
+
10
+ export type ISubMenu = {
11
+ title: string;
12
+ name: string;
13
+ items: (IMenuItem | Seperator)[];
14
+ };
15
+ export type IMenu = {
16
+ items: ISubMenu[];
17
+ };
18
+
19
+ export class Seperator {}
20
+
21
+ export type MenuBarStore = {
22
+ show: boolean;
23
+ setShow: (show: boolean) => void;
24
+ items: ISubMenu[];
25
+ setItems: (items: ISubMenu[]) => void;
26
+ setSubMenuItems: (menuName: string, items: (IMenuItem | Seperator)[]) => void;
27
+ };
28
+
29
+ export const menubarStoreFactory = () =>
30
+ createStore<MenuBarStore>((set) => ({
31
+ show: true,
32
+ setShow: (show) => set({ show }),
33
+ items: defaultMenuDataFactory().items,
34
+ setItems: (items) => set({ items }),
35
+ setSubMenuItems: (menuName, items) =>
36
+ set((state) => ({
37
+ items: state.items.map((subMenu) =>
38
+ subMenu.name === menuName ? { ...subMenu, items } : subMenu
39
+ )
40
+ }))
41
+ }));
@@ -0,0 +1,84 @@
1
+ import type { ReactFlowInstance } from 'reactflow';
2
+ import { create, useStore, type StoreApi } from 'zustand';
3
+ import { subscribeWithSelector } from 'zustand/middleware';
4
+ import type { XYPosition } from 'reactflow';
5
+
6
+ export type Refs = {
7
+ reactflow: ReactFlowInstance;
8
+ nodePickerPosition?: XYPosition;
9
+ selectedDocumentationType?: string;
10
+ };
11
+
12
+ export type RefStore = {
13
+ refs: Refs;
14
+ setRef: <T extends keyof Refs>(key: T, ref: Refs[T]) => void;
15
+ getRef: <T extends keyof Refs>(key: T) => Refs[T] | undefined;
16
+ removeRef: (key: keyof Refs) => void;
17
+ hasRef: (key: keyof Refs) => boolean;
18
+ };
19
+
20
+ export const refStoreFactory = () =>
21
+ create<RefStore>()(
22
+ subscribeWithSelector((set, get) => ({
23
+ refs: {} as Refs,
24
+
25
+ setRef: <T extends keyof Refs>(key: T, ref: Refs[T]) => {
26
+ set((state) => ({
27
+ refs: {
28
+ ...state.refs,
29
+ [key]: ref
30
+ }
31
+ }));
32
+ },
33
+
34
+ getRef: <T extends keyof Refs>(key: T) => {
35
+ return get().refs[key] as Refs[T] | undefined;
36
+ },
37
+
38
+ removeRef: (key: keyof Refs) => {
39
+ set((state) => {
40
+ const { [key]: _, ...rest } = state.refs;
41
+ return { refs: rest as Refs };
42
+ });
43
+ },
44
+
45
+ hasRef: (key: string) => {
46
+ return key in get().refs;
47
+ }
48
+ }))
49
+ );
50
+
51
+ /**
52
+ * Subscribe to changes of a specific ref
53
+ * @param store - The ref store
54
+ * @param key - The key of the ref to watch
55
+ * @param callback - Callback fired when the ref changes
56
+ * @returns Unsubscribe function
57
+ */
58
+ export function subscribeToRef<T extends keyof Refs>(
59
+ store: StoreApi<RefStore>,
60
+ key: T,
61
+ callback: (ref: Refs[T] | undefined) => void
62
+ ) {
63
+ return store.subscribe((state, prevState) => {
64
+ const current = state.refs[key] as Refs[T] | undefined;
65
+ const previous = prevState.refs[key] as Refs[T] | undefined;
66
+ if (current !== previous) {
67
+ return current;
68
+ }
69
+ callback(current);
70
+ });
71
+ }
72
+
73
+ /**
74
+ * Hook to access the current value of a ref from the store
75
+ * @param store - The ref store
76
+ * @param key - The key of the ref
77
+ * @returns The current value of the ref or null
78
+ */
79
+ export function useRefFromStore<T extends keyof Refs>(
80
+ store: StoreApi<RefStore>,
81
+ key: T
82
+ ): Refs[T] | undefined {
83
+ return useStore(store, (state) => state.refs[key] as Refs[T] | undefined);
84
+ }
@@ -0,0 +1,51 @@
1
+ import { create } from 'zustand';
2
+ import type { INodeRegistry, ValueTypeMetadata } from '../types/NodeMetadata';
3
+ import type { NodeSpecJSON } from '@kiberon-labs/behave-graph';
4
+
5
+ export type RegistryStore = {
6
+ readonly values: Record<string, ValueTypeMetadata>;
7
+ readonly specs: NodeSpecJSON[];
8
+
9
+ getRegistry: () => INodeRegistry;
10
+ updateRegistry: (registry: INodeRegistry) => void;
11
+ updateValues: (values: Record<string, ValueTypeMetadata>) => void;
12
+ updateSpecs: (specs: NodeSpecJSON[]) => void;
13
+ };
14
+
15
+ export const registryStoreFactory = () =>
16
+ create<RegistryStore>((set, get) => ({
17
+ values: {},
18
+ specs: [],
19
+
20
+ getRegistry: (): INodeRegistry => {
21
+ const state = get();
22
+ return {
23
+ values: state.values,
24
+ specs: state.specs
25
+ };
26
+ },
27
+
28
+ updateRegistry: (registry: INodeRegistry) =>
29
+ set((x) => {
30
+ // Merge specs by type (additive) so layering multiple profiles/plugins
31
+ // (core + image + ai + ...) doesn't clobber previously-registered node
32
+ // types. Later registrations override an existing type. Use updateSpecs
33
+ // for a full replacement.
34
+ const byType = new Map(x.specs.map((spec) => [spec.type, spec]));
35
+ for (const spec of registry.specs) byType.set(spec.type, spec);
36
+ return {
37
+ values: { ...x.values, ...registry.values },
38
+ specs: Array.from(byType.values())
39
+ };
40
+ }),
41
+
42
+ updateValues: (values: Record<string, ValueTypeMetadata>) =>
43
+ set((x) => ({
44
+ values: { ...x.values, ...values }
45
+ })),
46
+
47
+ updateSpecs: (specs: NodeSpecJSON[]) =>
48
+ set(() => ({
49
+ specs
50
+ }))
51
+ }));
@@ -0,0 +1,22 @@
1
+ import type { GraphSession } from '@/system/graphSession';
2
+ import { create } from 'zustand';
3
+
4
+ export type SelectionStore = {
5
+ selectedNodeId: string | null;
6
+ setSelectedNodeId: (nodeId: string | null) => void;
7
+ };
8
+
9
+ export const selectionStoreFactory = (session: GraphSession) => {
10
+ const store = create<SelectionStore>((set) => ({
11
+ selectedNodeId: null,
12
+ setSelectedNodeId: (selectedNodeId: string | null) =>
13
+ set(() => ({ selectedNodeId }))
14
+ }));
15
+ //Track side effect of selected node in the node store
16
+ session.nodeStore.subscribe((state) => {
17
+ const selectedNode = state.nodes.find((n) => n.selected);
18
+ store.getState().setSelectedNodeId(selectedNode?.id ?? null);
19
+ });
20
+
21
+ return store;
22
+ };
@@ -0,0 +1,99 @@
1
+ import { create } from 'zustand';
2
+
3
+ export const EDGE_TYPE = {
4
+ bezier: 'Bezier',
5
+ smoothStep: 'Smooth step',
6
+ straight: 'Straight',
7
+ simpleBezier: 'Simple Bezier'
8
+ } as const;
9
+
10
+ export type EdgeType = (typeof EDGE_TYPE)[keyof typeof EDGE_TYPE];
11
+
12
+ export type GeneratorLocation = 'inline' | 'panel';
13
+
14
+ /**
15
+ * Single source of truth for editor settings. Each entry's `default` defines the
16
+ * value (and its type); `persist: false` excludes it from the saved settings.
17
+ * The store shape, setters, and the persisted-key list are all derived from this
18
+ * , adding a setting here is the only edit needed (no setter boilerplate, no
19
+ * separate persist allow-list to keep in sync).
20
+ */
21
+ const SETTINGS = {
22
+ edgeType: { default: EDGE_TYPE.bezier as EdgeType },
23
+ debugMode: { default: false as boolean },
24
+ showMenu: { default: true as boolean },
25
+ showTimings: { default: false as boolean },
26
+ showMinimap: { default: false as boolean },
27
+ showGrid: { default: true as boolean },
28
+ // Transient UI state , not persisted.
29
+ showSearch: { default: false as boolean, persist: false },
30
+ /** Delay applying a node value change until the user commits it. */
31
+ delayedUpdate: { default: false as boolean },
32
+ /** Show value types inline on nodes. */
33
+ inlineTypes: { default: false as boolean },
34
+ /** Show values inline on nodes. */
35
+ inlineValues: { default: false as boolean },
36
+ connectOnClick: { default: true as boolean },
37
+ /**
38
+ * When connecting sockets of different-but-convertible value types,
39
+ * automatically insert a conversion node between them.
40
+ */
41
+ autoConvert: { default: true as boolean },
42
+ snapGrid: { default: false as boolean },
43
+ gridSize: { default: 15 as number },
44
+ generatorLocation: { default: 'panel' as GeneratorLocation }
45
+ } satisfies Record<string, { default: unknown; persist?: boolean }>;
46
+
47
+ type SettingsSchema = typeof SETTINGS;
48
+
49
+ type SettingsState = {
50
+ [K in keyof SettingsSchema]: SettingsSchema[K]['default'];
51
+ };
52
+
53
+ type SettingsSetters = {
54
+ [K in keyof SettingsSchema as `set${Capitalize<K & string>}`]: (
55
+ value: SettingsSchema[K]['default']
56
+ ) => void;
57
+ };
58
+
59
+ /**
60
+ * Generic accessors so plugin-contributed settings (dynamic keys not in the
61
+ * static {@link SETTINGS} schema) live in the same store as the typed built-ins.
62
+ * The auto-generated panel writes every row through {@link SystemSettingsStore.setSetting};
63
+ * the typed per-key setters above remain for existing typed consumers.
64
+ */
65
+ type SettingsDynamicAccess = {
66
+ /** Dynamic plugin-contributed setting values, keyed by descriptor key. */
67
+ [key: string]: unknown;
68
+ /** Set any setting by key (used by the schema-driven panel + plugins). */
69
+ setSetting: (key: string, value: unknown) => void;
70
+ };
71
+
72
+ export type SystemSettingsStore = SettingsState &
73
+ SettingsSetters &
74
+ SettingsDynamicAccess;
75
+
76
+ const setterName = (key: string): string =>
77
+ `set${key.charAt(0).toUpperCase()}${key.slice(1)}`;
78
+
79
+ /** Settings round-tripped to persisted storage (everything except `persist:false`). */
80
+ export const PERSISTED_SETTING_KEYS = (
81
+ Object.entries(SETTINGS) as [keyof SettingsSchema, { persist?: boolean }][]
82
+ )
83
+ .filter(([, spec]) => spec.persist !== false)
84
+ .map(([key]) => key);
85
+
86
+ export const systemSettingsFactory = () =>
87
+ create<SystemSettingsStore>((set) => {
88
+ const initial: Record<string, unknown> = {};
89
+ for (const [key, spec] of Object.entries(SETTINGS)) {
90
+ initial[key] = spec.default;
91
+ initial[setterName(key)] = (value: unknown) =>
92
+ set({ [key]: value } as Partial<SystemSettingsStore>);
93
+ }
94
+ // Generic setter for dynamic (plugin-contributed) keys and for the
95
+ // schema-driven panel, which writes every row by key.
96
+ initial.setSetting = (key: string, value: unknown) =>
97
+ set({ [key]: value } as Partial<SystemSettingsStore>);
98
+ return initial as SystemSettingsStore;
99
+ });
@@ -0,0 +1,210 @@
1
+ import { createStore, type StoreApi } from 'zustand/vanilla';
2
+ import type { FC } from 'react';
3
+ import { EDGE_TYPE } from './settings';
4
+
5
+ /**
6
+ * Schema-driven settings.
7
+ *
8
+ * The Settings panel is auto-generated from a registry of {@link SettingDescriptor}s
9
+ * rather than hand-coded JSX. Built-in settings are seeded as {@link DEFAULT_SETTINGS};
10
+ * plugins contribute their own via `system.registerSetting(...)`, and the panel
11
+ * renders them the same way — so a plugin can surface settings without forking
12
+ * the panel.
13
+ *
14
+ * Descriptors are intentionally plain data (everything except `render`/`when` is
15
+ * JSON-serializable), so a future declarative manifest `contributes.configuration`
16
+ * section can feed this same registry.
17
+ */
18
+
19
+ export type SettingEnumOption = { value: string; label: string };
20
+
21
+ /** Live values bag passed to a descriptor's {@link SettingDescriptorBase.when}. */
22
+ export type SettingsValues = Record<string, unknown>;
23
+
24
+ /** Props handed to a `type: 'custom'` descriptor's `render` component. */
25
+ export type SettingControlProps = {
26
+ value: unknown;
27
+ setValue: (value: unknown) => void;
28
+ descriptor: SettingDescriptor;
29
+ };
30
+
31
+ type SettingDescriptorBase = {
32
+ /**
33
+ * Unique key. Built-ins are flat (`edgeType`) and match the value-store keys
34
+ * 1:1; plugin settings should be namespaced (`graphRunner.autoStart`) to avoid
35
+ * collisions.
36
+ */
37
+ key: string;
38
+ /** Category heading the row is grouped under, e.g. `"Layout"`. */
39
+ section: string;
40
+ /** Sort order within the section (falls back to registration order). */
41
+ order?: number;
42
+ /** Row label. */
43
+ title?: string;
44
+ /** Secondary description text under the label. */
45
+ description?: string;
46
+ /** Excluded from persisted settings when `false`. Defaults to `true`. */
47
+ persist?: boolean;
48
+ /** Hide the row unless this returns true for the current values. */
49
+ when?: (values: SettingsValues) => boolean;
50
+ };
51
+
52
+ export type SettingDescriptor =
53
+ | (SettingDescriptorBase & { type: 'boolean'; default: boolean })
54
+ | (SettingDescriptorBase & {
55
+ type: 'number';
56
+ default: number;
57
+ min?: number;
58
+ max?: number;
59
+ step?: number;
60
+ })
61
+ | (SettingDescriptorBase & {
62
+ type: 'string';
63
+ default: string;
64
+ placeholder?: string;
65
+ })
66
+ | (SettingDescriptorBase & {
67
+ type: 'enum';
68
+ default: string;
69
+ options: SettingEnumOption[];
70
+ })
71
+ | (SettingDescriptorBase & {
72
+ type: 'custom';
73
+ default?: unknown;
74
+ render: FC<SettingControlProps>;
75
+ });
76
+
77
+ export type SettingsSchemaStore = {
78
+ /** Registered descriptors, in registration order. */
79
+ settings: SettingDescriptor[];
80
+ /** Section names in first-seen order, for stable display grouping. */
81
+ sectionOrder: string[];
82
+ registerSetting: (descriptor: SettingDescriptor) => void;
83
+ registerSettings: (descriptors: SettingDescriptor[]) => void;
84
+ };
85
+
86
+ const toOptions = (values: readonly string[]): SettingEnumOption[] =>
87
+ values.map((value) => ({ value, label: value }));
88
+
89
+ /**
90
+ * Built-in editor settings, mirroring the previously hand-coded panel. Keys
91
+ * match the value-store keys in {@link file://./settings.ts} exactly, so typed
92
+ * consumers (`settings.edgeType`, …) are unaffected.
93
+ */
94
+ export const DEFAULT_SETTINGS: SettingDescriptor[] = [
95
+ {
96
+ key: 'edgeType',
97
+ section: 'Layout',
98
+ type: 'enum',
99
+ default: EDGE_TYPE.bezier,
100
+ options: toOptions(Object.values(EDGE_TYPE)),
101
+ title: 'Edge Type',
102
+ description: 'Select the type of edge to use in the graph editor.'
103
+ },
104
+ {
105
+ key: 'inlineTypes',
106
+ section: 'Accessibility',
107
+ type: 'boolean',
108
+ default: false,
109
+ title: 'Show inline types',
110
+ description:
111
+ 'Adds additional spans to help differentiate types for colorblind users.'
112
+ },
113
+ {
114
+ key: 'delayedUpdate',
115
+ section: 'Interaction',
116
+ type: 'boolean',
117
+ default: false,
118
+ title: 'Use delayed interaction',
119
+ description: 'Forces a user to click save to update port.'
120
+ },
121
+ {
122
+ key: 'connectOnClick',
123
+ section: 'Interaction',
124
+ type: 'boolean',
125
+ default: true,
126
+ title: 'Click to connect',
127
+ description: 'Allows you to quick connect nodes by clicking on the 2 port.'
128
+ },
129
+ {
130
+ key: 'autoConvert',
131
+ section: 'Interaction',
132
+ type: 'boolean',
133
+ default: true,
134
+ title: 'Auto-convert types',
135
+ description:
136
+ 'When connecting different but convertible types, insert a conversion node automatically.'
137
+ },
138
+ {
139
+ key: 'showMinimap',
140
+ section: 'Display',
141
+ type: 'boolean',
142
+ default: false,
143
+ title: 'Show Minimap',
144
+ description: 'Shows the minimap in the graph editing area.'
145
+ },
146
+ {
147
+ key: 'showGrid',
148
+ section: 'Display',
149
+ type: 'boolean',
150
+ default: true,
151
+ title: 'Show Grid',
152
+ description: 'Shows the grid in the graph editing area.'
153
+ },
154
+ {
155
+ key: 'snapGrid',
156
+ section: 'Display',
157
+ type: 'boolean',
158
+ default: false,
159
+ title: 'Snap to Grid',
160
+ description: 'Snaps nodes to the grid while dragging.'
161
+ },
162
+ {
163
+ key: 'showTimings',
164
+ section: 'Performance',
165
+ type: 'boolean',
166
+ default: false,
167
+ title: 'Show execution time',
168
+ description: 'Shows how long it takes for a node to process.'
169
+ }
170
+ ];
171
+
172
+ export const settingsSchemaStoreFactory = (
173
+ initial: SettingDescriptor[] = DEFAULT_SETTINGS
174
+ ): StoreApi<SettingsSchemaStore> =>
175
+ createStore<SettingsSchemaStore>((set, get) => {
176
+ const registerSetting = (descriptor: SettingDescriptor): void => {
177
+ const { settings, sectionOrder } = get();
178
+ if (settings.some((existing) => existing.key === descriptor.key)) {
179
+ console.warn(
180
+ `Setting "${descriptor.key}" is already registered; ignoring duplicate.`
181
+ );
182
+ return;
183
+ }
184
+ set({
185
+ settings: [...settings, descriptor],
186
+ sectionOrder: sectionOrder.includes(descriptor.section)
187
+ ? sectionOrder
188
+ : [...sectionOrder, descriptor.section]
189
+ });
190
+ };
191
+
192
+ // Seed the built-in descriptors as the starting state.
193
+ const settings: SettingDescriptor[] = [];
194
+ const sectionOrder: string[] = [];
195
+ for (const descriptor of initial) {
196
+ if (settings.some((existing) => existing.key === descriptor.key))
197
+ continue;
198
+ settings.push(descriptor);
199
+ if (!sectionOrder.includes(descriptor.section)) {
200
+ sectionOrder.push(descriptor.section);
201
+ }
202
+ }
203
+
204
+ return {
205
+ settings,
206
+ sectionOrder,
207
+ registerSetting,
208
+ registerSettings: (descriptors) => descriptors.forEach(registerSetting)
209
+ };
210
+ });
@@ -0,0 +1,54 @@
1
+ import type { IBehaveNode } from '@/types/nodes';
2
+ import type { NodeSpecJSON } from '@kiberon-labs/behave-graph';
3
+ import type { ComponentType } from 'react';
4
+ import { create } from 'zustand';
5
+
6
+ export type SocketGeneratorNode = {
7
+ id: string;
8
+ data: IBehaveNode['data'];
9
+ spec: NodeSpecJSON;
10
+ selected: boolean;
11
+ };
12
+
13
+ export type SocketGeneratorRenderProps = {
14
+ node: SocketGeneratorNode;
15
+ };
16
+
17
+ export type SocketGenerator = {
18
+ name: string;
19
+ check: (spec: NodeSpecJSON) => boolean;
20
+ render: ComponentType<SocketGeneratorRenderProps>;
21
+ };
22
+
23
+ export type SocketGeneratorStore = {
24
+ generators: SocketGenerator[];
25
+ registerGenerator: (generator: SocketGenerator) => void;
26
+ unregisterGenerator: (name: string) => void;
27
+ };
28
+
29
+ export const socketGeneratorStoreFactory = () =>
30
+ create<SocketGeneratorStore>((set) => ({
31
+ generators: [],
32
+
33
+ registerGenerator: (generator) =>
34
+ set((state) => {
35
+ const existingIndex = state.generators.findIndex(
36
+ (x) => x.name === generator.name
37
+ );
38
+
39
+ if (existingIndex === -1) {
40
+ return {
41
+ generators: [...state.generators, generator]
42
+ };
43
+ }
44
+
45
+ const next = state.generators.slice();
46
+ next[existingIndex] = generator;
47
+ return { generators: next };
48
+ }),
49
+
50
+ unregisterGenerator: (name) =>
51
+ set((state) => ({
52
+ generators: state.generators.filter((x) => x.name !== name)
53
+ }))
54
+ }));
@@ -0,0 +1,75 @@
1
+ import type { NodeSpecJSON } from '@kiberon-labs/behave-graph';
2
+ import type { ComponentType } from 'react';
3
+ import { create } from 'zustand';
4
+ import { getCustomEventOnTriggeredSpecific } from '@/specifics/CustomEventOnTriggeredSpecific';
5
+ import { getCustomEventTriggerSpecific } from '@/specifics/CustomEventTriggerSpecific';
6
+ import { getVariableGetSpecific } from '@/specifics/VariableGetSpecific';
7
+ import { getVariableSetSpecific } from '@/specifics/VariableSetSpecific';
8
+ import type { IBehaveNode } from '@/types/nodes';
9
+
10
+ export type SpecificNode = {
11
+ id: string;
12
+ data: IBehaveNode['data'];
13
+ spec: NodeSpecJSON;
14
+ selected: boolean;
15
+ };
16
+
17
+ export type SpecificRenderProps = {
18
+ node: SpecificNode;
19
+ };
20
+
21
+ export type Specific = {
22
+ name: string;
23
+ check: (spec: NodeSpecJSON) => boolean;
24
+ render: ComponentType<SpecificRenderProps>;
25
+ };
26
+
27
+ export type SpecificStore = {
28
+ specifics: Specific[];
29
+ titleBarActions: Record<string, React.ReactElement>;
30
+ registerSpecific: (specific: Specific) => void;
31
+ unregisterSpecific: (name: string) => void;
32
+ registryTitleBarAction: (name: string, action: React.ReactElement) => void;
33
+ };
34
+
35
+ const defaultSpecifics: Specific[] = [
36
+ getCustomEventOnTriggeredSpecific(),
37
+ getCustomEventTriggerSpecific(),
38
+ getVariableGetSpecific(),
39
+ getVariableSetSpecific()
40
+ ];
41
+
42
+ export const specificStoreFactory = () =>
43
+ create<SpecificStore>((set) => ({
44
+ specifics: defaultSpecifics,
45
+
46
+ registerSpecific: (specific) =>
47
+ set((state) => {
48
+ const existingIndex = state.specifics.findIndex(
49
+ (x) => x.name === specific.name
50
+ );
51
+
52
+ if (existingIndex === -1) {
53
+ return {
54
+ specifics: [...state.specifics, specific]
55
+ };
56
+ }
57
+
58
+ const next = state.specifics.slice();
59
+ next[existingIndex] = specific;
60
+ return { specifics: next };
61
+ }),
62
+
63
+ unregisterSpecific: (name) =>
64
+ set((state) => ({
65
+ specifics: state.specifics.filter((x) => x.name !== name)
66
+ })),
67
+ titleBarActions: {},
68
+ registryTitleBarAction: (name: string, action: React.ReactElement) =>
69
+ set((state) => ({
70
+ titleBarActions: {
71
+ ...state.titleBarActions,
72
+ [name]: action
73
+ }
74
+ }))
75
+ }));