@foresthubai/workflow-builder 0.3.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.
- package/LICENSE +661 -0
- package/NOTICE +16 -0
- package/README.md +93 -0
- package/dist/BuilderLayout.d.ts +34 -0
- package/dist/BuilderLayout.d.ts.map +1 -0
- package/dist/BuilderLayout.js +172 -0
- package/dist/BuilderLayout.js.map +1 -0
- package/dist/Canvas.d.ts +23 -0
- package/dist/Canvas.d.ts.map +1 -0
- package/dist/Canvas.js +141 -0
- package/dist/Canvas.js.map +1 -0
- package/dist/CanvasEditor.d.ts +46 -0
- package/dist/CanvasEditor.d.ts.map +1 -0
- package/dist/CanvasEditor.js +57 -0
- package/dist/CanvasEditor.js.map +1 -0
- package/dist/CanvasTabsToolbar.d.ts +11 -0
- package/dist/CanvasTabsToolbar.d.ts.map +1 -0
- package/dist/CanvasTabsToolbar.js +101 -0
- package/dist/CanvasTabsToolbar.js.map +1 -0
- package/dist/RightConfigPanel.d.ts +27 -0
- package/dist/RightConfigPanel.d.ts.map +1 -0
- package/dist/RightConfigPanel.js +102 -0
- package/dist/RightConfigPanel.js.map +1 -0
- package/dist/WorkflowBuilder.d.ts +62 -0
- package/dist/WorkflowBuilder.d.ts.map +1 -0
- package/dist/WorkflowBuilder.js +275 -0
- package/dist/WorkflowBuilder.js.map +1 -0
- package/dist/cn.d.ts +3 -0
- package/dist/cn.d.ts.map +1 -0
- package/dist/cn.js +6 -0
- package/dist/cn.js.map +1 -0
- package/dist/components/ui/add-button.d.ts +16 -0
- package/dist/components/ui/add-button.d.ts.map +1 -0
- package/dist/components/ui/add-button.js +21 -0
- package/dist/components/ui/add-button.js.map +1 -0
- package/dist/components/ui/alert-dialog.d.ts +21 -0
- package/dist/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog.js +30 -0
- package/dist/components/ui/alert-dialog.js.map +1 -0
- package/dist/components/ui/alert.d.ts +9 -0
- package/dist/components/ui/alert.d.ts.map +1 -0
- package/dist/components/ui/alert.js +23 -0
- package/dist/components/ui/alert.js.map +1 -0
- package/dist/components/ui/badge.d.ts +10 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/badge.js +21 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/button.d.ts +13 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +40 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/card.d.ts +9 -0
- package/dist/components/ui/card.d.ts.map +1 -0
- package/dist/components/ui/card.js +17 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/checkbox.d.ts +5 -0
- package/dist/components/ui/checkbox.d.ts.map +1 -0
- package/dist/components/ui/checkbox.js +9 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/collapsible.d.ts +6 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/collapsible.js +6 -0
- package/dist/components/ui/collapsible.js.map +1 -0
- package/dist/components/ui/command.d.ts +82 -0
- package/dist/components/ui/command.d.ts.map +1 -0
- package/dist/components/ui/command.js +29 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/delete-button.d.ts +11 -0
- package/dist/components/ui/delete-button.d.ts.map +1 -0
- package/dist/components/ui/delete-button.js +14 -0
- package/dist/components/ui/delete-button.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +22 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.js +27 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +28 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.js +36 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/input.d.ts +13 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +34 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/label.d.ts +6 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +10 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/readonly-banner.d.ts +7 -0
- package/dist/components/ui/readonly-banner.d.ts.map +1 -0
- package/dist/components/ui/readonly-banner.js +12 -0
- package/dist/components/ui/readonly-banner.js.map +1 -0
- package/dist/components/ui/resizable.d.ts +24 -0
- package/dist/components/ui/resizable.d.ts.map +1 -0
- package/dist/components/ui/resizable.js +9 -0
- package/dist/components/ui/resizable.js.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +45 -0
- package/dist/components/ui/scroll-area.d.ts.map +1 -0
- package/dist/components/ui/scroll-area.js +27 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.d.ts +14 -0
- package/dist/components/ui/select.d.ts.map +1 -0
- package/dist/components/ui/select.js +30 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/separator.d.ts +5 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/separator.js +8 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/switch.d.ts +5 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/components/ui/switch.js +8 -0
- package/dist/components/ui/switch.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +12 -0
- package/dist/components/ui/textarea.d.ts.map +1 -0
- package/dist/components/ui/textarea.js +34 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/toast.d.ts +16 -0
- package/dist/components/ui/toast.d.ts.map +1 -0
- package/dist/components/ui/toast.js +34 -0
- package/dist/components/ui/toast.js.map +1 -0
- package/dist/components/ui/toaster.d.ts +2 -0
- package/dist/components/ui/toaster.d.ts.map +1 -0
- package/dist/components/ui/toaster.js +10 -0
- package/dist/components/ui/toaster.js.map +1 -0
- package/dist/components/ui/toggle-group.d.ts +13 -0
- package/dist/components/ui/toggle-group.d.ts.map +1 -0
- package/dist/components/ui/toggle-group.js +21 -0
- package/dist/components/ui/toggle-group.js.map +1 -0
- package/dist/components/ui/toggle.d.ts +13 -0
- package/dist/components/ui/toggle.d.ts.map +1 -0
- package/dist/components/ui/toggle.js +26 -0
- package/dist/components/ui/toggle.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +8 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/tooltip.js +14 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/dialogs/NodePickerDialog.d.ts +10 -0
- package/dist/dialogs/NodePickerDialog.d.ts.map +1 -0
- package/dist/dialogs/NodePickerDialog.js +39 -0
- package/dist/dialogs/NodePickerDialog.js.map +1 -0
- package/dist/dialogs/ValidationDialog.d.ts +17 -0
- package/dist/dialogs/ValidationDialog.d.ts.map +1 -0
- package/dist/dialogs/ValidationDialog.js +29 -0
- package/dist/dialogs/ValidationDialog.js.map +1 -0
- package/dist/graph/BaseNode.d.ts +9 -0
- package/dist/graph/BaseNode.d.ts.map +1 -0
- package/dist/graph/BaseNode.js +318 -0
- package/dist/graph/BaseNode.js.map +1 -0
- package/dist/graph/CustomEdge.d.ts +14 -0
- package/dist/graph/CustomEdge.d.ts.map +1 -0
- package/dist/graph/CustomEdge.js +107 -0
- package/dist/graph/CustomEdge.js.map +1 -0
- package/dist/graph/CustomNode.d.ts +3 -0
- package/dist/graph/CustomNode.d.ts.map +1 -0
- package/dist/graph/CustomNode.js +15 -0
- package/dist/graph/CustomNode.js.map +1 -0
- package/dist/graph/FunctionCallNode.d.ts +3 -0
- package/dist/graph/FunctionCallNode.d.ts.map +1 -0
- package/dist/graph/FunctionCallNode.js +25 -0
- package/dist/graph/FunctionCallNode.js.map +1 -0
- package/dist/graph/PortHandle.d.ts +21 -0
- package/dist/graph/PortHandle.d.ts.map +1 -0
- package/dist/graph/PortHandle.js +113 -0
- package/dist/graph/PortHandle.js.map +1 -0
- package/dist/graph/reactFlowRegistry.d.ts +65 -0
- package/dist/graph/reactFlowRegistry.d.ts.map +1 -0
- package/dist/graph/reactFlowRegistry.js +24 -0
- package/dist/graph/reactFlowRegistry.js.map +1 -0
- package/dist/hooks/use-toast.d.ts +47 -0
- package/dist/hooks/use-toast.d.ts.map +1 -0
- package/dist/hooks/use-toast.js +95 -0
- package/dist/hooks/use-toast.js.map +1 -0
- package/dist/hooks/useAvailableVariables.d.ts +12 -0
- package/dist/hooks/useAvailableVariables.d.ts.map +1 -0
- package/dist/hooks/useAvailableVariables.js +16 -0
- package/dist/hooks/useAvailableVariables.js.map +1 -0
- package/dist/hooks/useCanvasHistory.d.ts +14 -0
- package/dist/hooks/useCanvasHistory.d.ts.map +1 -0
- package/dist/hooks/useCanvasHistory.js +20 -0
- package/dist/hooks/useCanvasHistory.js.map +1 -0
- package/dist/hooks/useCanvasTabs.d.ts +23 -0
- package/dist/hooks/useCanvasTabs.d.ts.map +1 -0
- package/dist/hooks/useCanvasTabs.js +136 -0
- package/dist/hooks/useCanvasTabs.js.map +1 -0
- package/dist/hooks/useFunctionDiagnosticsSync.d.ts +14 -0
- package/dist/hooks/useFunctionDiagnosticsSync.d.ts.map +1 -0
- package/dist/hooks/useFunctionDiagnosticsSync.js +38 -0
- package/dist/hooks/useFunctionDiagnosticsSync.js.map +1 -0
- package/dist/hooks/useFunctionRegistry.d.ts +15 -0
- package/dist/hooks/useFunctionRegistry.d.ts.map +1 -0
- package/dist/hooks/useFunctionRegistry.js +22 -0
- package/dist/hooks/useFunctionRegistry.js.map +1 -0
- package/dist/hooks/useFunctions.d.ts +15 -0
- package/dist/hooks/useFunctions.d.ts.map +1 -0
- package/dist/hooks/useFunctions.js +34 -0
- package/dist/hooks/useFunctions.js.map +1 -0
- package/dist/hooks/useGraph.d.ts +40 -0
- package/dist/hooks/useGraph.d.ts.map +1 -0
- package/dist/hooks/useGraph.js +102 -0
- package/dist/hooks/useGraph.js.map +1 -0
- package/dist/hooks/useNodeDefinitions.d.ts +17 -0
- package/dist/hooks/useNodeDefinitions.d.ts.map +1 -0
- package/dist/hooks/useNodeDefinitions.js +65 -0
- package/dist/hooks/useNodeDefinitions.js.map +1 -0
- package/dist/hooks/useParamErrors.d.ts +12 -0
- package/dist/hooks/useParamErrors.d.ts.map +1 -0
- package/dist/hooks/useParamErrors.js +28 -0
- package/dist/hooks/useParamErrors.js.map +1 -0
- package/dist/hooks/useResolvedTheme.d.ts +10 -0
- package/dist/hooks/useResolvedTheme.d.ts.map +1 -0
- package/dist/hooks/useResolvedTheme.js +29 -0
- package/dist/hooks/useResolvedTheme.js.map +1 -0
- package/dist/hooks/useResourceDiagnosticsSync.d.ts +40 -0
- package/dist/hooks/useResourceDiagnosticsSync.d.ts.map +1 -0
- package/dist/hooks/useResourceDiagnosticsSync.js +39 -0
- package/dist/hooks/useResourceDiagnosticsSync.js.map +1 -0
- package/dist/hooks/useSuppressThemeTransition.d.ts +32 -0
- package/dist/hooks/useSuppressThemeTransition.d.ts.map +1 -0
- package/dist/hooks/useSuppressThemeTransition.js +75 -0
- package/dist/hooks/useSuppressThemeTransition.js.map +1 -0
- package/dist/hooks/useWorkflowSerialization.d.ts +24 -0
- package/dist/hooks/useWorkflowSerialization.d.ts.map +1 -0
- package/dist/hooks/useWorkflowSerialization.js +113 -0
- package/dist/hooks/useWorkflowSerialization.js.map +1 -0
- package/dist/i18n/index.d.ts +4 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +46 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/locales/de.json +501 -0
- package/dist/i18n/locales/en.json +557 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/inputs/ExpressionInput.d.ts +12 -0
- package/dist/inputs/ExpressionInput.d.ts.map +1 -0
- package/dist/inputs/ExpressionInput.js +203 -0
- package/dist/inputs/ExpressionInput.js.map +1 -0
- package/dist/inputs/ParameterEditor.d.ts +13 -0
- package/dist/inputs/ParameterEditor.d.ts.map +1 -0
- package/dist/inputs/ParameterEditor.js +204 -0
- package/dist/inputs/ParameterEditor.js.map +1 -0
- package/dist/inputs/PortSection.d.ts +31 -0
- package/dist/inputs/PortSection.d.ts.map +1 -0
- package/dist/inputs/PortSection.js +26 -0
- package/dist/inputs/PortSection.js.map +1 -0
- package/dist/panels/BuilderSidebar.d.ts +24 -0
- package/dist/panels/BuilderSidebar.d.ts.map +1 -0
- package/dist/panels/BuilderSidebar.js +202 -0
- package/dist/panels/BuilderSidebar.js.map +1 -0
- package/dist/panels/ChannelConfigPanel.d.ts +8 -0
- package/dist/panels/ChannelConfigPanel.d.ts.map +1 -0
- package/dist/panels/ChannelConfigPanel.js +26 -0
- package/dist/panels/ChannelConfigPanel.js.map +1 -0
- package/dist/panels/ChannelsPanel.d.ts +2 -0
- package/dist/panels/ChannelsPanel.d.ts.map +1 -0
- package/dist/panels/ChannelsPanel.js +16 -0
- package/dist/panels/ChannelsPanel.js.map +1 -0
- package/dist/panels/DebugConsolePanel.d.ts +2 -0
- package/dist/panels/DebugConsolePanel.d.ts.map +1 -0
- package/dist/panels/DebugConsolePanel.js +32 -0
- package/dist/panels/DebugConsolePanel.js.map +1 -0
- package/dist/panels/DebugContextPanel.d.ts +2 -0
- package/dist/panels/DebugContextPanel.d.ts.map +1 -0
- package/dist/panels/DebugContextPanel.js +32 -0
- package/dist/panels/DebugContextPanel.js.map +1 -0
- package/dist/panels/DebugExternalIOPanel.d.ts +9 -0
- package/dist/panels/DebugExternalIOPanel.d.ts.map +1 -0
- package/dist/panels/DebugExternalIOPanel.js +66 -0
- package/dist/panels/DebugExternalIOPanel.js.map +1 -0
- package/dist/panels/DiagnosticsPanel.d.ts +8 -0
- package/dist/panels/DiagnosticsPanel.d.ts.map +1 -0
- package/dist/panels/DiagnosticsPanel.js +86 -0
- package/dist/panels/DiagnosticsPanel.js.map +1 -0
- package/dist/panels/EdgeConfigPanel.d.ts +14 -0
- package/dist/panels/EdgeConfigPanel.d.ts.map +1 -0
- package/dist/panels/EdgeConfigPanel.js +34 -0
- package/dist/panels/EdgeConfigPanel.js.map +1 -0
- package/dist/panels/FunctionConfigPanel.d.ts +16 -0
- package/dist/panels/FunctionConfigPanel.d.ts.map +1 -0
- package/dist/panels/FunctionConfigPanel.js +62 -0
- package/dist/panels/FunctionConfigPanel.js.map +1 -0
- package/dist/panels/FunctionListPanel.d.ts +14 -0
- package/dist/panels/FunctionListPanel.d.ts.map +1 -0
- package/dist/panels/FunctionListPanel.js +25 -0
- package/dist/panels/FunctionListPanel.js.map +1 -0
- package/dist/panels/MemoryConfigPanel.d.ts +8 -0
- package/dist/panels/MemoryConfigPanel.d.ts.map +1 -0
- package/dist/panels/MemoryConfigPanel.js +22 -0
- package/dist/panels/MemoryConfigPanel.js.map +1 -0
- package/dist/panels/MemoryPanel.d.ts +2 -0
- package/dist/panels/MemoryPanel.d.ts.map +1 -0
- package/dist/panels/MemoryPanel.js +25 -0
- package/dist/panels/MemoryPanel.js.map +1 -0
- package/dist/panels/ModelConfigPanel.d.ts +8 -0
- package/dist/panels/ModelConfigPanel.d.ts.map +1 -0
- package/dist/panels/ModelConfigPanel.js +14 -0
- package/dist/panels/ModelConfigPanel.js.map +1 -0
- package/dist/panels/ModelsPanel.d.ts +8 -0
- package/dist/panels/ModelsPanel.d.ts.map +1 -0
- package/dist/panels/ModelsPanel.js +24 -0
- package/dist/panels/ModelsPanel.js.map +1 -0
- package/dist/panels/NodeConfigPanel.d.ts +16 -0
- package/dist/panels/NodeConfigPanel.d.ts.map +1 -0
- package/dist/panels/NodeConfigPanel.js +248 -0
- package/dist/panels/NodeConfigPanel.js.map +1 -0
- package/dist/panels/NodeLibrary.d.ts +16 -0
- package/dist/panels/NodeLibrary.d.ts.map +1 -0
- package/dist/panels/NodeLibrary.js +125 -0
- package/dist/panels/NodeLibrary.js.map +1 -0
- package/dist/panels/ResourceConfigPanel.d.ts +37 -0
- package/dist/panels/ResourceConfigPanel.d.ts.map +1 -0
- package/dist/panels/ResourceConfigPanel.js +35 -0
- package/dist/panels/ResourceConfigPanel.js.map +1 -0
- package/dist/panels/ResourceListPanel.d.ts +35 -0
- package/dist/panels/ResourceListPanel.d.ts.map +1 -0
- package/dist/panels/ResourceListPanel.js +35 -0
- package/dist/panels/ResourceListPanel.js.map +1 -0
- package/dist/panels/VariableConfigPanel.d.ts +9 -0
- package/dist/panels/VariableConfigPanel.d.ts.map +1 -0
- package/dist/panels/VariableConfigPanel.js +50 -0
- package/dist/panels/VariableConfigPanel.js.map +1 -0
- package/dist/panels/VariablesPanel.d.ts +7 -0
- package/dist/panels/VariablesPanel.d.ts.map +1 -0
- package/dist/panels/VariablesPanel.js +56 -0
- package/dist/panels/VariablesPanel.js.map +1 -0
- package/dist/stores/canvasStore.d.ts +41 -0
- package/dist/stores/canvasStore.d.ts.map +1 -0
- package/dist/stores/canvasStore.js +187 -0
- package/dist/stores/canvasStore.js.map +1 -0
- package/dist/stores/debugStore.d.ts +42 -0
- package/dist/stores/debugStore.d.ts.map +1 -0
- package/dist/stores/debugStore.js +22 -0
- package/dist/stores/debugStore.js.map +1 -0
- package/dist/stores/diagnosticsStore.d.ts +41 -0
- package/dist/stores/diagnosticsStore.d.ts.map +1 -0
- package/dist/stores/diagnosticsStore.js +67 -0
- package/dist/stores/diagnosticsStore.js.map +1 -0
- package/dist/stores/editorStore.d.ts +76 -0
- package/dist/stores/editorStore.d.ts.map +1 -0
- package/dist/stores/editorStore.js +116 -0
- package/dist/stores/editorStore.js.map +1 -0
- package/dist/utils/categoryConstants.d.ts +4 -0
- package/dist/utils/categoryConstants.d.ts.map +1 -0
- package/dist/utils/categoryConstants.js +24 -0
- package/dist/utils/categoryConstants.js.map +1 -0
- package/dist/utils/channelOperations.d.ts +21 -0
- package/dist/utils/channelOperations.d.ts.map +1 -0
- package/dist/utils/channelOperations.js +84 -0
- package/dist/utils/channelOperations.js.map +1 -0
- package/dist/utils/connectionRules.d.ts +15 -0
- package/dist/utils/connectionRules.d.ts.map +1 -0
- package/dist/utils/connectionRules.js +113 -0
- package/dist/utils/connectionRules.js.map +1 -0
- package/dist/utils/functionOperations.d.ts +27 -0
- package/dist/utils/functionOperations.d.ts.map +1 -0
- package/dist/utils/functionOperations.js +140 -0
- package/dist/utils/functionOperations.js.map +1 -0
- package/dist/utils/graphOperations.d.ts +54 -0
- package/dist/utils/graphOperations.d.ts.map +1 -0
- package/dist/utils/graphOperations.js +461 -0
- package/dist/utils/graphOperations.js.map +1 -0
- package/dist/utils/history.d.ts +76 -0
- package/dist/utils/history.d.ts.map +1 -0
- package/dist/utils/history.js +93 -0
- package/dist/utils/history.js.map +1 -0
- package/dist/utils/memoryOperations.d.ts +14 -0
- package/dist/utils/memoryOperations.d.ts.map +1 -0
- package/dist/utils/memoryOperations.js +55 -0
- package/dist/utils/memoryOperations.js.map +1 -0
- package/dist/utils/migrateFunctionNodes.d.ts +9 -0
- package/dist/utils/migrateFunctionNodes.d.ts.map +1 -0
- package/dist/utils/migrateFunctionNodes.js +89 -0
- package/dist/utils/migrateFunctionNodes.js.map +1 -0
- package/dist/utils/modelOperations.d.ts +13 -0
- package/dist/utils/modelOperations.d.ts.map +1 -0
- package/dist/utils/modelOperations.js +53 -0
- package/dist/utils/modelOperations.js.map +1 -0
- package/dist/utils/paramDisplay.d.ts +12 -0
- package/dist/utils/paramDisplay.d.ts.map +1 -0
- package/dist/utils/paramDisplay.js +56 -0
- package/dist/utils/paramDisplay.js.map +1 -0
- package/dist/utils/resourceHelpers.d.ts +17 -0
- package/dist/utils/resourceHelpers.d.ts.map +1 -0
- package/dist/utils/resourceHelpers.js +32 -0
- package/dist/utils/resourceHelpers.js.map +1 -0
- package/dist/utils/translation.d.ts +20 -0
- package/dist/utils/translation.d.ts.map +1 -0
- package/dist/utils/translation.js +23 -0
- package/dist/utils/translation.js.map +1 -0
- package/dist/utils/variableOperations.d.ts +15 -0
- package/dist/utils/variableOperations.d.ts.map +1 -0
- package/dist/utils/variableOperations.js +71 -0
- package/dist/utils/variableOperations.js.map +1 -0
- package/package.json +79 -0
- package/src/BuilderLayout.tsx +345 -0
- package/src/Canvas.tsx +261 -0
- package/src/CanvasEditor.tsx +142 -0
- package/src/CanvasTabsToolbar.tsx +176 -0
- package/src/RightConfigPanel.tsx +266 -0
- package/src/WorkflowBuilder.tsx +412 -0
- package/src/cn.ts +6 -0
- package/src/components/ui/add-button.tsx +39 -0
- package/src/components/ui/alert-dialog.tsx +141 -0
- package/src/components/ui/alert.tsx +59 -0
- package/src/components/ui/badge.tsx +36 -0
- package/src/components/ui/button.tsx +85 -0
- package/src/components/ui/card.tsx +79 -0
- package/src/components/ui/checkbox.tsx +28 -0
- package/src/components/ui/collapsible.tsx +9 -0
- package/src/components/ui/command.tsx +153 -0
- package/src/components/ui/delete-button.tsx +23 -0
- package/src/components/ui/dialog.tsx +125 -0
- package/src/components/ui/dropdown-menu.tsx +198 -0
- package/src/components/ui/input.tsx +55 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/readonly-banner.tsx +15 -0
- package/src/components/ui/resizable.tsx +43 -0
- package/src/components/ui/scroll-area.tsx +102 -0
- package/src/components/ui/select.tsx +160 -0
- package/src/components/ui/separator.tsx +29 -0
- package/src/components/ui/switch.tsx +27 -0
- package/src/components/ui/textarea.tsx +51 -0
- package/src/components/ui/toast.tsx +127 -0
- package/src/components/ui/toaster.tsx +33 -0
- package/src/components/ui/toggle-group.tsx +59 -0
- package/src/components/ui/toggle.tsx +43 -0
- package/src/components/ui/tooltip.tsx +32 -0
- package/src/dialogs/NodePickerDialog.tsx +84 -0
- package/src/dialogs/ValidationDialog.tsx +184 -0
- package/src/graph/BaseNode.tsx +557 -0
- package/src/graph/CustomEdge.tsx +185 -0
- package/src/graph/CustomNode.tsx +16 -0
- package/src/graph/FunctionCallNode.tsx +30 -0
- package/src/graph/PortHandle.tsx +189 -0
- package/src/graph/reactFlowRegistry.ts +26 -0
- package/src/hooks/use-toast.ts +125 -0
- package/src/hooks/useAvailableVariables.ts +20 -0
- package/src/hooks/useCanvasHistory.ts +22 -0
- package/src/hooks/useCanvasTabs.ts +168 -0
- package/src/hooks/useFunctionDiagnosticsSync.ts +40 -0
- package/src/hooks/useFunctionRegistry.ts +26 -0
- package/src/hooks/useFunctions.ts +44 -0
- package/src/hooks/useGraph.ts +161 -0
- package/src/hooks/useNodeDefinitions.ts +82 -0
- package/src/hooks/useParamErrors.ts +26 -0
- package/src/hooks/useResolvedTheme.ts +30 -0
- package/src/hooks/useResourceDiagnosticsSync.ts +58 -0
- package/src/hooks/useSuppressThemeTransition.ts +79 -0
- package/src/hooks/useWorkflowSerialization.ts +127 -0
- package/src/i18n/index.ts +53 -0
- package/src/i18n/locales/de.json +501 -0
- package/src/i18n/locales/en.json +557 -0
- package/src/index.ts +27 -0
- package/src/inputs/ExpressionInput.tsx +297 -0
- package/src/inputs/ParameterEditor.tsx +515 -0
- package/src/inputs/PortSection.tsx +144 -0
- package/src/panels/BuilderSidebar.tsx +301 -0
- package/src/panels/ChannelConfigPanel.tsx +49 -0
- package/src/panels/ChannelsPanel.tsx +28 -0
- package/src/panels/DebugConsolePanel.tsx +73 -0
- package/src/panels/DebugContextPanel.tsx +77 -0
- package/src/panels/DebugExternalIOPanel.tsx +180 -0
- package/src/panels/DiagnosticsPanel.tsx +170 -0
- package/src/panels/EdgeConfigPanel.tsx +104 -0
- package/src/panels/FunctionConfigPanel.tsx +179 -0
- package/src/panels/FunctionListPanel.tsx +45 -0
- package/src/panels/MemoryConfigPanel.tsx +55 -0
- package/src/panels/MemoryPanel.tsx +40 -0
- package/src/panels/ModelConfigPanel.tsx +41 -0
- package/src/panels/ModelsPanel.tsx +36 -0
- package/src/panels/NodeConfigPanel.tsx +630 -0
- package/src/panels/NodeLibrary.tsx +288 -0
- package/src/panels/ResourceConfigPanel.tsx +132 -0
- package/src/panels/ResourceListPanel.tsx +113 -0
- package/src/panels/VariableConfigPanel.tsx +161 -0
- package/src/panels/VariablesPanel.tsx +145 -0
- package/src/stores/canvasStore.test.ts +44 -0
- package/src/stores/canvasStore.ts +245 -0
- package/src/stores/debugStore.ts +74 -0
- package/src/stores/diagnosticsStore.ts +130 -0
- package/src/stores/editorStore.ts +202 -0
- package/src/styles/index.css +526 -0
- package/src/utils/categoryConstants.ts +26 -0
- package/src/utils/channelOperations.ts +86 -0
- package/src/utils/connectionRules.ts +137 -0
- package/src/utils/functionOperations.ts +179 -0
- package/src/utils/graphOperations.ts +550 -0
- package/src/utils/history.ts +207 -0
- package/src/utils/memoryOperations.ts +57 -0
- package/src/utils/migrateFunctionNodes.ts +107 -0
- package/src/utils/modelOperations.ts +55 -0
- package/src/utils/paramDisplay.ts +71 -0
- package/src/utils/resourceHelpers.ts +32 -0
- package/src/utils/translation.ts +28 -0
- package/src/utils/variableOperations.ts +75 -0
- package/tailwind-preset.ts +166 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { useState, useCallback, useEffect } from "react";
|
|
2
|
+
import { MAIN_CANVAS_ID } from "../stores/canvasStore";
|
|
3
|
+
import { useEditorStore } from "../stores/editorStore";
|
|
4
|
+
|
|
5
|
+
// Holds info for a canvas tab. id is identical to canvasId.
|
|
6
|
+
export interface CanvasTab {
|
|
7
|
+
id: string;
|
|
8
|
+
label: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Hook for managing canvas tabs UI.
|
|
13
|
+
* Tab switching directly updates the UI store's activeCanvasId.
|
|
14
|
+
*/
|
|
15
|
+
export const useCanvasTabs = () => {
|
|
16
|
+
const [tabs, setTabs] = useState<CanvasTab[]>([{ id: MAIN_CANVAS_ID, label: "Main" }]);
|
|
17
|
+
|
|
18
|
+
// Get active canvas ID and setter from editor store
|
|
19
|
+
const activeCanvasId = useEditorStore((state) => state.activeCanvasId);
|
|
20
|
+
const setActiveCanvas = useEditorStore((state) => state.setActiveCanvas);
|
|
21
|
+
const selectFunction = useEditorStore((state) => state.selectFunction);
|
|
22
|
+
|
|
23
|
+
// Tabs are a projection of the function declarations: a deleted function drops its
|
|
24
|
+
// tab (falling back to Main if it was active), a renamed one relabels. Open/close
|
|
25
|
+
// of an existing function's tab is still explicit (openTab/closeTab) — this only
|
|
26
|
+
// reconciles against the source of truth so the strip can't show a stale function.
|
|
27
|
+
const functions = useEditorStore((state) => state.functions);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
setTabs((prev) => {
|
|
30
|
+
let changed = false;
|
|
31
|
+
const next = prev.flatMap<CanvasTab>((t) => {
|
|
32
|
+
if (t.id === MAIN_CANVAS_ID) return [t];
|
|
33
|
+
const fn = functions[t.id];
|
|
34
|
+
if (!fn) {
|
|
35
|
+
changed = true;
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
if (fn.name !== t.label) {
|
|
39
|
+
changed = true;
|
|
40
|
+
return [{ ...t, label: fn.name }];
|
|
41
|
+
}
|
|
42
|
+
return [t];
|
|
43
|
+
});
|
|
44
|
+
return changed ? next : prev;
|
|
45
|
+
});
|
|
46
|
+
if (activeCanvasId !== MAIN_CANVAS_ID && !functions[activeCanvasId]) {
|
|
47
|
+
setActiveCanvas(MAIN_CANVAS_ID);
|
|
48
|
+
}
|
|
49
|
+
}, [functions, activeCanvasId, setActiveCanvas]);
|
|
50
|
+
|
|
51
|
+
// Switch to a tab's canvas. A function tab focuses its declaration (selectFunction
|
|
52
|
+
// switches the canvas AND selects the function so its config panel opens) — matching
|
|
53
|
+
// the dropdown/sidebar open path; any other tab just switches the canvas.
|
|
54
|
+
const setActiveTabId = useCallback(
|
|
55
|
+
(tabId: string) => {
|
|
56
|
+
if (tabId !== MAIN_CANVAS_ID && functions[tabId]) {
|
|
57
|
+
selectFunction(tabId);
|
|
58
|
+
} else {
|
|
59
|
+
setActiveCanvas(tabId);
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
[functions, selectFunction, setActiveCanvas],
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// Open a tab for a function (add if not exists, switch to it)
|
|
66
|
+
const openTab = useCallback(
|
|
67
|
+
(id: string, label: string) => {
|
|
68
|
+
setTabs((prev) => {
|
|
69
|
+
const existing = prev.find((t) => t.id === id);
|
|
70
|
+
if (existing) {
|
|
71
|
+
return prev; // Already exists
|
|
72
|
+
}
|
|
73
|
+
return [...prev, { id, label }];
|
|
74
|
+
});
|
|
75
|
+
setActiveCanvas(id);
|
|
76
|
+
return id;
|
|
77
|
+
},
|
|
78
|
+
[setActiveCanvas],
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// Close a tab (just removes from visible tabs, does NOT delete canvas data)
|
|
82
|
+
const closeTab = useCallback(
|
|
83
|
+
(tabId: string) => {
|
|
84
|
+
// Cannot close main tab
|
|
85
|
+
if (tabId === MAIN_CANVAS_ID) return;
|
|
86
|
+
|
|
87
|
+
setTabs((prev) => {
|
|
88
|
+
const filtered = prev.filter((t) => t.id !== tabId);
|
|
89
|
+
// If closing active tab, switch to main
|
|
90
|
+
if (tabId === activeCanvasId) {
|
|
91
|
+
setActiveCanvas(MAIN_CANVAS_ID);
|
|
92
|
+
}
|
|
93
|
+
return filtered;
|
|
94
|
+
});
|
|
95
|
+
},
|
|
96
|
+
[activeCanvasId, setActiveCanvas],
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// Remove a tab completely (called when function is deleted)
|
|
100
|
+
const removeTab = useCallback(
|
|
101
|
+
(tabId: string) => {
|
|
102
|
+
if (tabId === MAIN_CANVAS_ID) return;
|
|
103
|
+
|
|
104
|
+
setTabs((prev) => {
|
|
105
|
+
const filtered = prev.filter((t) => t.id !== tabId);
|
|
106
|
+
// Switch to main canvas if removing active tab
|
|
107
|
+
if (tabId === activeCanvasId) {
|
|
108
|
+
setActiveCanvas(MAIN_CANVAS_ID);
|
|
109
|
+
}
|
|
110
|
+
return filtered;
|
|
111
|
+
});
|
|
112
|
+
},
|
|
113
|
+
[activeCanvasId, setActiveCanvas],
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const renameTab = useCallback((tabId: string, newLabel: string) => {
|
|
117
|
+
setTabs((prev) => prev.map((t) => (t.id === tabId ? { ...t, label: newLabel } : t)));
|
|
118
|
+
}, []);
|
|
119
|
+
|
|
120
|
+
const reorderTabs = useCallback((fromIndex: number, toIndex: number) => {
|
|
121
|
+
if (fromIndex === 0 || toIndex === 0) return;
|
|
122
|
+
setTabs((prev) => {
|
|
123
|
+
const updated = [...prev];
|
|
124
|
+
const [moved] = updated.splice(fromIndex, 1);
|
|
125
|
+
if (!moved) return prev;
|
|
126
|
+
updated.splice(toIndex, 0, moved);
|
|
127
|
+
return updated;
|
|
128
|
+
});
|
|
129
|
+
}, []);
|
|
130
|
+
|
|
131
|
+
// Reset to main canvas only (closes all function tabs)
|
|
132
|
+
const resetToMain = useCallback(() => {
|
|
133
|
+
setTabs([{ id: MAIN_CANVAS_ID, label: "Main" }]);
|
|
134
|
+
setActiveCanvas(MAIN_CANVAS_ID);
|
|
135
|
+
}, [setActiveCanvas]);
|
|
136
|
+
|
|
137
|
+
// Restore a previously saved tab state
|
|
138
|
+
const restoreTabState = useCallback(
|
|
139
|
+
(savedTabs: CanvasTab[], savedActiveId: string) => {
|
|
140
|
+
setTabs(savedTabs);
|
|
141
|
+
setActiveCanvas(savedActiveId);
|
|
142
|
+
},
|
|
143
|
+
[setActiveCanvas],
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
// Get label for a tab
|
|
147
|
+
const getTabLabel = useCallback(
|
|
148
|
+
(tabId: string) => {
|
|
149
|
+
return tabs.find((t) => t.id === tabId)?.label || "Unknown";
|
|
150
|
+
},
|
|
151
|
+
[tabs],
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
tabs,
|
|
156
|
+
activeTabId: activeCanvasId,
|
|
157
|
+
setActiveTabId,
|
|
158
|
+
openTab,
|
|
159
|
+
closeTab,
|
|
160
|
+
removeTab,
|
|
161
|
+
renameTab,
|
|
162
|
+
reorderTabs,
|
|
163
|
+
resetToMain,
|
|
164
|
+
restoreTabState,
|
|
165
|
+
getTabLabel,
|
|
166
|
+
isMainCanvas: activeCanvasId === MAIN_CANVAS_ID,
|
|
167
|
+
};
|
|
168
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { validateFunction } from "@foresthubai/workflow-core/diagnostics";
|
|
3
|
+
import { computeAvailableVariables } from "@foresthubai/workflow-core/variable";
|
|
4
|
+
import { useEditorStore } from "../stores/editorStore";
|
|
5
|
+
import { useDiagnosticsStore } from "../stores/diagnosticsStore";
|
|
6
|
+
import { getCanvasStore } from "../stores/canvasStore";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Keeps the `byFunctionId` diagnostics slot in sync with the function declarations —
|
|
10
|
+
* the single source for the sidebar tab badge, the function list ring, AND the config
|
|
11
|
+
* panel's per-output rings (they all read this slot). Mounted once at the
|
|
12
|
+
* workflow-builder root so it survives tab open/close.
|
|
13
|
+
*
|
|
14
|
+
* Scope-aware: each function is validated against its own body canvas's variables, so
|
|
15
|
+
* invalid/typed return expressions surface here too — not just missing ones. (Reacts
|
|
16
|
+
* to declaration/expression edits via `functions`; a body-only edit that changes the
|
|
17
|
+
* available variables without touching a declaration refreshes on the next
|
|
18
|
+
* declaration change or a full `validate`.)
|
|
19
|
+
*/
|
|
20
|
+
export function useFunctionDiagnosticsSync(): void {
|
|
21
|
+
const functions = useEditorStore((s) => s.functions);
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const ds = useDiagnosticsStore.getState();
|
|
25
|
+
|
|
26
|
+
const seen = new Set<string>();
|
|
27
|
+
for (const [id, def] of Object.entries(functions)) {
|
|
28
|
+
seen.add(id);
|
|
29
|
+
const store = getCanvasStore(id);
|
|
30
|
+
const lookup = store
|
|
31
|
+
? computeAvailableVariables(store.getState().variables, store.getState().edges).lookup
|
|
32
|
+
: undefined;
|
|
33
|
+
ds.setFunctionDiagnostics(id, validateFunction(def, lookup));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
for (const id of Object.keys(ds.byFunctionId)) {
|
|
37
|
+
if (!seen.has(id)) ds.clearFunctionDiagnostics(id);
|
|
38
|
+
}
|
|
39
|
+
}, [functions]);
|
|
40
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useCallback, useMemo } from "react";
|
|
2
|
+
import { useEditorStore } from "../stores/editorStore";
|
|
3
|
+
import type { FunctionDeclaration } from "@foresthubai/workflow-core/function";
|
|
4
|
+
|
|
5
|
+
// Functions are a project-scoped resource: the registry IS editorStore.functions —
|
|
6
|
+
// the domain FunctionDeclaration, no conversion. (Crossing to the flat api FunctionInfo
|
|
7
|
+
// is done only when stamping a call-site snapshot; see useNodeDefinitions/migration.)
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Access to all function declarations by id. Reactive over editorStore.functions.
|
|
11
|
+
* - functions: Record of FunctionDeclaration by id
|
|
12
|
+
* - functionsList: array of FunctionDeclaration
|
|
13
|
+
* - getFunction(id): one declaration by id
|
|
14
|
+
*/
|
|
15
|
+
export function useFunctionRegistry() {
|
|
16
|
+
const functions = useEditorStore((s) => s.functions);
|
|
17
|
+
const functionsList = useMemo(() => Object.values(functions), [functions]);
|
|
18
|
+
const getFunction = useCallback((id: string): FunctionDeclaration | undefined => functions[id], [functions]);
|
|
19
|
+
|
|
20
|
+
return { functions, functionsList, getFunction };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** All function declarations without React subscription (for non-component code). */
|
|
24
|
+
export function getAllFunctions(): Record<string, FunctionDeclaration> {
|
|
25
|
+
return useEditorStore.getState().functions;
|
|
26
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useEditorStore } from "../stores/editorStore";
|
|
3
|
+
import { getOrCreateCanvasStore } from "../stores/canvasStore";
|
|
4
|
+
import { useFunctionRegistry } from "./useFunctionRegistry";
|
|
5
|
+
import { addFunction } from "../utils/functionOperations";
|
|
6
|
+
|
|
7
|
+
export interface UseFunctionsOptions {
|
|
8
|
+
/** Open (or focus) a tab for a function canvas. */
|
|
9
|
+
onOpenTab: (id: string, label: string) => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Coordinates the canvas-tab UI with function declarations (editorStore). The
|
|
14
|
+
* declarations themselves are CRUD'd in utils/functionOperations; this hook only
|
|
15
|
+
* handles the open/create flows that must also touch the tab strip and selection.
|
|
16
|
+
*/
|
|
17
|
+
export const useFunctions = ({ onOpenTab }: UseFunctionsOptions) => {
|
|
18
|
+
const { functionsList: functions, getFunction } = useFunctionRegistry();
|
|
19
|
+
const selectFunction = useEditorStore((s) => s.selectFunction);
|
|
20
|
+
|
|
21
|
+
// Open an existing function: ensure its body canvas exists, open its tab, and
|
|
22
|
+
// select it so the right panel shows its definition. onOpenTab switches the active
|
|
23
|
+
// canvas first; selectFunction sets the selection last so it isn't cleared.
|
|
24
|
+
const openFunction = useCallback(
|
|
25
|
+
(functionId: string) => {
|
|
26
|
+
const fn = getFunction(functionId);
|
|
27
|
+
if (!fn) return;
|
|
28
|
+
getOrCreateCanvasStore(functionId);
|
|
29
|
+
onOpenTab(functionId, fn.name);
|
|
30
|
+
selectFunction(functionId);
|
|
31
|
+
},
|
|
32
|
+
[getFunction, onOpenTab, selectFunction],
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
// Create a new function and open it (the canvas body is created by addFunction).
|
|
36
|
+
const createFunction = useCallback(() => {
|
|
37
|
+
const fn = addFunction();
|
|
38
|
+
onOpenTab(fn.id, fn.name);
|
|
39
|
+
selectFunction(fn.id);
|
|
40
|
+
return fn.id;
|
|
41
|
+
}, [onOpenTab, selectFunction]);
|
|
42
|
+
|
|
43
|
+
return { functions, openFunction, createFunction };
|
|
44
|
+
};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { NodeDefinition, NodeData } from "@foresthubai/workflow-core/node";
|
|
2
|
+
import { Connection, Edge, Node } from "@xyflow/react";
|
|
3
|
+
import type { EdgeData } from "@foresthubai/workflow-core/edge";
|
|
4
|
+
import { useCallback } from "react";
|
|
5
|
+
import { getOrCreateCanvasStore, MAIN_CANVAS_ID } from "../stores/canvasStore";
|
|
6
|
+
import {
|
|
7
|
+
addNodeToStore,
|
|
8
|
+
type Clipboard,
|
|
9
|
+
connectNodesInStore,
|
|
10
|
+
deleteEdgesFromStore,
|
|
11
|
+
deleteNodeFromStore,
|
|
12
|
+
pasteToStore,
|
|
13
|
+
updateEdgeInStore,
|
|
14
|
+
updateNodeInStore,
|
|
15
|
+
} from "../utils/graphOperations";
|
|
16
|
+
import type { EdgeType } from "@foresthubai/workflow-core/edge";
|
|
17
|
+
import { useNodeDefinitions } from "./useNodeDefinitions";
|
|
18
|
+
|
|
19
|
+
// Shared across all useGraph instances (one per canvas) so copy/paste works
|
|
20
|
+
// across canvas switches within a single builder session.
|
|
21
|
+
const clipboardRef: { current: Clipboard | null } = { current: null };
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Hook that provides graph management actions for a specific canvas.
|
|
25
|
+
*
|
|
26
|
+
* All mutations are:
|
|
27
|
+
* - Gated by readOnly (no-op when true)
|
|
28
|
+
* - Automatically wrapped in a history checkpoint (undo/redo)
|
|
29
|
+
*
|
|
30
|
+
* Callers don't need to worry about either concern.
|
|
31
|
+
*/
|
|
32
|
+
export const useGraph = (canvasId: string = MAIN_CANVAS_ID, readOnly: boolean = false) => {
|
|
33
|
+
const canvasStore = getOrCreateCanvasStore(canvasId);
|
|
34
|
+
const nodes = canvasStore((s) => s.nodes);
|
|
35
|
+
const edges = canvasStore((s) => s.edges);
|
|
36
|
+
const { withCheckpoint } = canvasStore;
|
|
37
|
+
|
|
38
|
+
const { getNodeDefinition } = useNodeDefinitions();
|
|
39
|
+
|
|
40
|
+
// Guarded checkpoint: skips when readOnly, otherwise wraps in undo history entry
|
|
41
|
+
const guarded = useCallback(
|
|
42
|
+
<R>(operation: () => R): R | undefined => {
|
|
43
|
+
if (readOnly) return undefined;
|
|
44
|
+
return withCheckpoint(operation);
|
|
45
|
+
},
|
|
46
|
+
[readOnly, withCheckpoint],
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const addNode = useCallback(
|
|
50
|
+
(nodeDef: NodeDefinition, position?: { x: number; y: number }) => {
|
|
51
|
+
return guarded(() => addNodeToStore(canvasStore, nodeDef, position)) ?? null;
|
|
52
|
+
},
|
|
53
|
+
[canvasStore, guarded],
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const updateNode = useCallback(
|
|
57
|
+
(nodeId: string, updates: { arguments?: Record<string, unknown>; label?: string }) => {
|
|
58
|
+
guarded(() => updateNodeInStore(canvasStore, nodeId, updates));
|
|
59
|
+
},
|
|
60
|
+
[canvasStore, guarded],
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const deleteNode = useCallback(
|
|
64
|
+
(nodeId: string) => {
|
|
65
|
+
guarded(() => deleteNodeFromStore(canvasStore, nodeId, getNodeDefinition));
|
|
66
|
+
},
|
|
67
|
+
[canvasStore, getNodeDefinition, guarded],
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const onConnect = useCallback(
|
|
71
|
+
(connection: Connection): EdgeType | false => {
|
|
72
|
+
return guarded(() => connectNodesInStore(canvasStore, connection)) ?? false;
|
|
73
|
+
},
|
|
74
|
+
[canvasStore, guarded],
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const updateEdge = useCallback(
|
|
78
|
+
(edgeId: string, updates: Record<string, unknown>) => {
|
|
79
|
+
guarded(() => updateEdgeInStore(canvasStore, edgeId, updates));
|
|
80
|
+
},
|
|
81
|
+
[canvasStore, guarded],
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const deleteEdges = useCallback(
|
|
85
|
+
(edgeIds: string[]) => {
|
|
86
|
+
guarded(() => deleteEdgesFromStore(canvasStore, edgeIds));
|
|
87
|
+
},
|
|
88
|
+
[canvasStore, guarded],
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// Batch delete nodes and edges as a single undo entry
|
|
92
|
+
const deleteSelected = useCallback(
|
|
93
|
+
(nodeIds: string[], edgeIds: string[]) => {
|
|
94
|
+
if (nodeIds.length === 0 && edgeIds.length === 0) return;
|
|
95
|
+
guarded(() => {
|
|
96
|
+
for (const nodeId of nodeIds) deleteNodeFromStore(canvasStore, nodeId, getNodeDefinition);
|
|
97
|
+
if (edgeIds.length > 0) deleteEdgesFromStore(canvasStore, edgeIds);
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
[canvasStore, getNodeDefinition, guarded],
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
// Copy is read-only — no checkpoint, no readOnly gate
|
|
104
|
+
const copySelection = useCallback(
|
|
105
|
+
(nodeIds: string[]) => {
|
|
106
|
+
if (nodeIds.length === 0) return;
|
|
107
|
+
|
|
108
|
+
const nodeIdSet = new Set(nodeIds);
|
|
109
|
+
|
|
110
|
+
const copiedNodes = nodes
|
|
111
|
+
.filter((node) => nodeIdSet.has(node.id))
|
|
112
|
+
.map((node) => JSON.parse(JSON.stringify(node)) as Node<NodeData>);
|
|
113
|
+
|
|
114
|
+
const copiedEdges = edges
|
|
115
|
+
.filter((edge) => nodeIdSet.has(edge.source) && nodeIdSet.has(edge.target))
|
|
116
|
+
.map((edge) => JSON.parse(JSON.stringify(edge)) as Edge<EdgeData>);
|
|
117
|
+
|
|
118
|
+
clipboardRef.current = { nodes: copiedNodes, edges: copiedEdges };
|
|
119
|
+
},
|
|
120
|
+
[nodes, edges],
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const pasteSelection = useCallback(
|
|
124
|
+
(offset?: { x: number; y: number }) => {
|
|
125
|
+
const clipboard = clipboardRef.current;
|
|
126
|
+
if (!clipboard) return undefined;
|
|
127
|
+
return guarded(() => pasteToStore(canvasStore, clipboard, offset, getNodeDefinition));
|
|
128
|
+
},
|
|
129
|
+
[canvasStore, getNodeDefinition, guarded],
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
// Batch add node + connect as a single undo entry (used by contextual node picker)
|
|
133
|
+
const addNodeAndConnect = useCallback(
|
|
134
|
+
(nodeDef: NodeDefinition, position: { x: number; y: number }, connection: Connection): string | null => {
|
|
135
|
+
return (
|
|
136
|
+
guarded(() => {
|
|
137
|
+
const nodeId = addNodeToStore(canvasStore, nodeDef, position);
|
|
138
|
+
if (nodeId == null) return null;
|
|
139
|
+
connectNodesInStore(canvasStore, { ...connection, target: nodeId });
|
|
140
|
+
return nodeId;
|
|
141
|
+
}) ?? null
|
|
142
|
+
);
|
|
143
|
+
},
|
|
144
|
+
[canvasStore, guarded],
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
nodes,
|
|
149
|
+
edges,
|
|
150
|
+
addNode,
|
|
151
|
+
updateNode,
|
|
152
|
+
updateEdge,
|
|
153
|
+
deleteNode,
|
|
154
|
+
deleteEdges,
|
|
155
|
+
deleteSelected,
|
|
156
|
+
onConnect,
|
|
157
|
+
addNodeAndConnect,
|
|
158
|
+
copySelection,
|
|
159
|
+
pasteSelection,
|
|
160
|
+
};
|
|
161
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { useMemo, useCallback } from "react";
|
|
2
|
+
import i18n from "../i18n";
|
|
3
|
+
import { NodeCategory, NodeRegistry, NodeDefinition, NodeData } from "@foresthubai/workflow-core/node";
|
|
4
|
+
import { useFunctionRegistry } from "./useFunctionRegistry";
|
|
5
|
+
import { toFunctionInfo, type FunctionInfo } from "@foresthubai/workflow-core/function";
|
|
6
|
+
import { FunctionCallNode, FunctionNodeDefinition, buildFunctionNodeDef as coreBuildFunctionNodeDef } from "@foresthubai/workflow-core/node";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Workflow-builder binding for {@link coreBuildFunctionNodeDef} — passes
|
|
10
|
+
* `i18n.t` so descriptions are translated. Consumers continue to call
|
|
11
|
+
* `buildFunctionNodeDef(fn)` unchanged; core's signature is the pure
|
|
12
|
+
* `(fn, t?)` form.
|
|
13
|
+
*/
|
|
14
|
+
export function buildFunctionNodeDef(fn: FunctionInfo): FunctionNodeDefinition {
|
|
15
|
+
return coreBuildFunctionNodeDef(fn, i18n.t.bind(i18n));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Use function registry to provide dynamic node definitions based on available functions
|
|
19
|
+
export const useNodeDefinitions = () => {
|
|
20
|
+
// Get static node definitions from registry (these never change)
|
|
21
|
+
const staticNodeDefs: NodeDefinition[] = NodeRegistry.getAll();
|
|
22
|
+
|
|
23
|
+
// Subscribe to function registry (derived from all canvas stores)
|
|
24
|
+
const { functions } = useFunctionRegistry();
|
|
25
|
+
|
|
26
|
+
// Dynamically create node definitions for each function. The call-site node def is
|
|
27
|
+
// built from the flat signature snapshot, so project the domain declaration here.
|
|
28
|
+
const functionNodeDefs: FunctionNodeDefinition[] = useMemo(
|
|
29
|
+
() => Object.values(functions).map((fn) => buildFunctionNodeDef(toFunctionInfo(fn))),
|
|
30
|
+
[functions],
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
// Get node definition for a node instance (still depending on all functions)
|
|
34
|
+
const getNodeDefinition = useCallback(
|
|
35
|
+
(node: NodeData): NodeDefinition | undefined => {
|
|
36
|
+
if (node.type === "FunctionCall") {
|
|
37
|
+
const fnNode = node as FunctionCallNode;
|
|
38
|
+
return functionNodeDefs.find((def) => def.type === "FunctionCall" && def.functionInfo.id === fnNode.functionInfo.id);
|
|
39
|
+
}
|
|
40
|
+
return NodeRegistry.getByType(node.type);
|
|
41
|
+
},
|
|
42
|
+
[functionNodeDefs],
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const getNodeDefinitionsByCategory = useCallback(
|
|
46
|
+
(category: NodeCategory) => {
|
|
47
|
+
const staticNodes = NodeRegistry.getByCategory(category);
|
|
48
|
+
if (category === NodeCategory.Function) {
|
|
49
|
+
return [...staticNodes, ...functionNodeDefs];
|
|
50
|
+
}
|
|
51
|
+
return staticNodes;
|
|
52
|
+
},
|
|
53
|
+
[functionNodeDefs],
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const getAllCategories = useCallback((): NodeCategory[] => {
|
|
57
|
+
const staticCategories = NodeRegistry.getAllCategories();
|
|
58
|
+
const allCategories = new Set([...staticCategories]);
|
|
59
|
+
if (functionNodeDefs.length > 0) {
|
|
60
|
+
allCategories.add(NodeCategory.Function);
|
|
61
|
+
}
|
|
62
|
+
const categoryOrder = [
|
|
63
|
+
NodeCategory.Trigger,
|
|
64
|
+
NodeCategory.Input,
|
|
65
|
+
NodeCategory.Logic,
|
|
66
|
+
NodeCategory.Data,
|
|
67
|
+
NodeCategory.Function,
|
|
68
|
+
NodeCategory.AI,
|
|
69
|
+
NodeCategory.Tool,
|
|
70
|
+
NodeCategory.Output,
|
|
71
|
+
];
|
|
72
|
+
return categoryOrder.filter((cat) => allCategories.has(cat));
|
|
73
|
+
}, [functionNodeDefs]);
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
nodeDefinitions: [...staticNodeDefs, ...functionNodeDefs],
|
|
77
|
+
getAllCategories,
|
|
78
|
+
getNodeDefinition,
|
|
79
|
+
getNodeDefinitionsByCategory,
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import type { Diagnostic } from "@foresthubai/workflow-core/diagnostics";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Build a per-parameter error map (`paramId → messages`) from a resource's
|
|
6
|
+
* diagnostics, keeping only `error`-severity entries. Shared by every config
|
|
7
|
+
* panel that renders a parameter list (node / edge / channel / memory / model)
|
|
8
|
+
* so the inline Map-building loop lives in exactly one place.
|
|
9
|
+
*
|
|
10
|
+
* Memoized on `diags`, so callers can read it from the diagnostics store with a
|
|
11
|
+
* plain selector and pass the result straight through to `<ParameterEditor>`.
|
|
12
|
+
*/
|
|
13
|
+
export function useParamErrors(diags: Diagnostic[] | undefined): Map<string, string[]> {
|
|
14
|
+
return useMemo(() => {
|
|
15
|
+
const map = new Map<string, string[]>();
|
|
16
|
+
if (!diags) return map;
|
|
17
|
+
for (const d of diags) {
|
|
18
|
+
if (d.paramId && d.severity === "error") {
|
|
19
|
+
const arr = map.get(d.paramId);
|
|
20
|
+
if (arr) arr.push(d.message);
|
|
21
|
+
else map.set(d.paramId, [d.message]);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return map;
|
|
25
|
+
}, [diags]);
|
|
26
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns "light" if `<html>` has the `light` class, else "dark". Subscribes to
|
|
5
|
+
* MutationObserver so toggles by the embedder propagate immediately.
|
|
6
|
+
*
|
|
7
|
+
* Dark is the default — the builder's CSS puts dark tokens on `:root` and
|
|
8
|
+
* overrides them under `.light`. This hook exists so things that need an
|
|
9
|
+
* explicit value — notably ReactFlow's `colorMode` prop — stay in sync.
|
|
10
|
+
*/
|
|
11
|
+
export function useResolvedTheme(): "dark" | "light" {
|
|
12
|
+
const [theme, setTheme] = useState<"dark" | "light">(() => detect());
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (typeof document === "undefined") return;
|
|
16
|
+
const root = document.documentElement;
|
|
17
|
+
const observer = new MutationObserver(() => setTheme(detect()));
|
|
18
|
+
observer.observe(root, { attributes: true, attributeFilter: ["class"] });
|
|
19
|
+
// Initial sync in case it changed between mount and effect.
|
|
20
|
+
setTheme(detect());
|
|
21
|
+
return () => observer.disconnect();
|
|
22
|
+
}, []);
|
|
23
|
+
|
|
24
|
+
return theme;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function detect(): "dark" | "light" {
|
|
28
|
+
if (typeof document === "undefined") return "dark";
|
|
29
|
+
return document.documentElement.classList.contains("light") ? "light" : "dark";
|
|
30
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { useEditorStore } from "../stores/editorStore";
|
|
3
|
+
import { useDiagnosticsStore } from "../stores/diagnosticsStore";
|
|
4
|
+
import type { Diagnostic } from "@foresthubai/workflow-core/diagnostics";
|
|
5
|
+
|
|
6
|
+
type EditorState = ReturnType<typeof useEditorStore.getState>;
|
|
7
|
+
type DiagnosticsState = ReturnType<typeof useDiagnosticsStore.getState>;
|
|
8
|
+
|
|
9
|
+
interface ResourceDiagnosticsSyncConfig<I extends { id: string }> {
|
|
10
|
+
/** Pick the resource map (e.g. `s.channels`) off the editor store. */
|
|
11
|
+
selectItems: (s: EditorState) => Record<string, I>;
|
|
12
|
+
/** Validate one instance into its diagnostics. */
|
|
13
|
+
validate: (item: I) => Diagnostic[];
|
|
14
|
+
/** Read the matching diagnostics slot (e.g. `d.byChannelId`). */
|
|
15
|
+
getStored: (d: DiagnosticsState) => Record<string, Diagnostic[]>;
|
|
16
|
+
/** Write one instance's diagnostics. */
|
|
17
|
+
set: (d: DiagnosticsState, id: string, diags: Diagnostic[]) => void;
|
|
18
|
+
/** Drop one instance's diagnostics. */
|
|
19
|
+
clear: (d: DiagnosticsState, id: string) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Keeps a project-scoped diagnostics slot (`byChannelId` / `byMemoryId` /
|
|
24
|
+
* `byModelId`) in sync with the editor's resource map.
|
|
25
|
+
*
|
|
26
|
+
* These resources are project-scoped, not canvas-scoped, and are only rendered
|
|
27
|
+
* visually when their sidebar tab is open. Tying diagnostic writes to card
|
|
28
|
+
* lifecycles would mean errors vanish the moment that tab closes, so this hook
|
|
29
|
+
* is mounted once at the workflow-builder root and reactively rewrites the store
|
|
30
|
+
* whenever the resource map changes.
|
|
31
|
+
*
|
|
32
|
+
* Lifecycle handled implicitly by the effect:
|
|
33
|
+
* - Load → setItems fires → effect re-runs → diagnostics written
|
|
34
|
+
* - Edit → store mutates → effect re-runs → entry replaced
|
|
35
|
+
* - Delete → item leaves → orphan branch → entry cleared
|
|
36
|
+
* - Unmount → store goes down with the app (no cleanup needed)
|
|
37
|
+
*/
|
|
38
|
+
export function useResourceDiagnosticsSync<I extends { id: string }>(config: ResourceDiagnosticsSyncConfig<I>): void {
|
|
39
|
+
const items = useEditorStore(config.selectItems);
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
const ds = useDiagnosticsStore.getState();
|
|
43
|
+
|
|
44
|
+
const seen = new Set<string>();
|
|
45
|
+
for (const item of Object.values(items)) {
|
|
46
|
+
seen.add(item.id);
|
|
47
|
+
config.set(ds, item.id, config.validate(item));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Drop entries for items that have been deleted.
|
|
51
|
+
for (const id of Object.keys(config.getStored(ds))) {
|
|
52
|
+
if (!seen.has(id)) config.clear(ds, id);
|
|
53
|
+
}
|
|
54
|
+
// `config` is recreated each render but only `items` drives a resync; the
|
|
55
|
+
// effect reads the latest closure on every run.
|
|
56
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
57
|
+
}, [items]);
|
|
58
|
+
}
|