@flowdrop/flowdrop 1.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.
- package/LICENSE +21 -0
- package/README.md +252 -0
- package/dist/adapters/WorkflowAdapter.d.ts +167 -0
- package/dist/adapters/WorkflowAdapter.js +368 -0
- package/dist/adapters/agentspec/AgentSpecAdapter.d.ts +96 -0
- package/dist/adapters/agentspec/AgentSpecAdapter.js +626 -0
- package/dist/adapters/agentspec/agentAdapter.d.ts +59 -0
- package/dist/adapters/agentspec/agentAdapter.js +91 -0
- package/dist/adapters/agentspec/autoLayout.d.ts +34 -0
- package/dist/adapters/agentspec/autoLayout.js +127 -0
- package/dist/adapters/agentspec/componentTypeDefaults.d.ts +73 -0
- package/dist/adapters/agentspec/componentTypeDefaults.js +238 -0
- package/dist/adapters/agentspec/defaultNodeTypes.d.ts +53 -0
- package/dist/adapters/agentspec/defaultNodeTypes.js +561 -0
- package/dist/adapters/agentspec/index.d.ts +37 -0
- package/dist/adapters/agentspec/index.js +39 -0
- package/dist/adapters/agentspec/validator.d.ts +34 -0
- package/dist/adapters/agentspec/validator.js +169 -0
- package/dist/api/enhanced-client.d.ts +183 -0
- package/dist/api/enhanced-client.js +430 -0
- package/dist/components/App.svelte +981 -0
- package/dist/components/App.svelte.d.ts +54 -0
- package/dist/components/CanvasBanner.stories.svelte +29 -0
- package/dist/components/CanvasBanner.stories.svelte.d.ts +27 -0
- package/dist/components/CanvasBanner.svelte +57 -0
- package/dist/components/CanvasBanner.svelte.d.ts +8 -0
- package/dist/components/ConfigForm.svelte +1138 -0
- package/dist/components/ConfigForm.svelte.d.ts +44 -0
- package/dist/components/ConfigModal.svelte +188 -0
- package/dist/components/ConfigModal.svelte.d.ts +13 -0
- package/dist/components/ConfigPanel.stories.svelte +47 -0
- package/dist/components/ConfigPanel.stories.svelte.d.ts +27 -0
- package/dist/components/ConfigPanel.svelte +182 -0
- package/dist/components/ConfigPanel.svelte.d.ts +32 -0
- package/dist/components/ConnectionLine.svelte +32 -0
- package/dist/components/ConnectionLine.svelte.d.ts +3 -0
- package/dist/components/EdgeRefresher.svelte +41 -0
- package/dist/components/EdgeRefresher.svelte.d.ts +9 -0
- package/dist/components/FlowDropZone.svelte +83 -0
- package/dist/components/FlowDropZone.svelte.d.ts +13 -0
- package/dist/components/LoadingSpinner.stories.svelte +30 -0
- package/dist/components/LoadingSpinner.stories.svelte.d.ts +27 -0
- package/dist/components/LoadingSpinner.svelte +36 -0
- package/dist/components/LoadingSpinner.svelte.d.ts +8 -0
- package/dist/components/Logo.stories.svelte +22 -0
- package/dist/components/Logo.stories.svelte.d.ts +27 -0
- package/dist/components/Logo.svelte +102 -0
- package/dist/components/Logo.svelte.d.ts +26 -0
- package/dist/components/LogsSidebar.svelte +563 -0
- package/dist/components/LogsSidebar.svelte.d.ts +17 -0
- package/dist/components/MarkdownDisplay.stories.svelte +36 -0
- package/dist/components/MarkdownDisplay.stories.svelte.d.ts +27 -0
- package/dist/components/MarkdownDisplay.svelte +29 -0
- package/dist/components/MarkdownDisplay.svelte.d.ts +7 -0
- package/dist/components/Navbar.stories.svelte +53 -0
- package/dist/components/Navbar.stories.svelte.d.ts +27 -0
- package/dist/components/Navbar.svelte +726 -0
- package/dist/components/Navbar.svelte.d.ts +29 -0
- package/dist/components/NodeSidebar.svelte +762 -0
- package/dist/components/NodeSidebar.svelte.d.ts +9 -0
- package/dist/components/NodeStatusOverlay.stories.svelte +85 -0
- package/dist/components/NodeStatusOverlay.stories.svelte.d.ts +27 -0
- package/dist/components/NodeStatusOverlay.svelte +327 -0
- package/dist/components/NodeStatusOverlay.svelte.d.ts +11 -0
- package/dist/components/PipelineStatus.svelte +314 -0
- package/dist/components/PipelineStatus.svelte.d.ts +20 -0
- package/dist/components/PortCoordinateTracker.svelte +58 -0
- package/dist/components/PortCoordinateTracker.svelte.d.ts +12 -0
- package/dist/components/ReadOnlyDetails.svelte +170 -0
- package/dist/components/ReadOnlyDetails.svelte.d.ts +25 -0
- package/dist/components/SchemaForm.stories.svelte +116 -0
- package/dist/components/SchemaForm.stories.svelte.d.ts +27 -0
- package/dist/components/SchemaForm.svelte +536 -0
- package/dist/components/SchemaForm.svelte.d.ts +83 -0
- package/dist/components/SettingsModal.svelte +279 -0
- package/dist/components/SettingsModal.svelte.d.ts +23 -0
- package/dist/components/SettingsPanel.svelte +638 -0
- package/dist/components/SettingsPanel.svelte.d.ts +21 -0
- package/dist/components/StatusIcon.stories.svelte +60 -0
- package/dist/components/StatusIcon.stories.svelte.d.ts +27 -0
- package/dist/components/StatusIcon.svelte +119 -0
- package/dist/components/StatusIcon.svelte.d.ts +10 -0
- package/dist/components/StatusLabel.stories.svelte +17 -0
- package/dist/components/StatusLabel.stories.svelte.d.ts +27 -0
- package/dist/components/StatusLabel.svelte +33 -0
- package/dist/components/StatusLabel.svelte.d.ts +7 -0
- package/dist/components/ThemeToggle.stories.svelte +25 -0
- package/dist/components/ThemeToggle.stories.svelte.d.ts +27 -0
- package/dist/components/ThemeToggle.svelte +185 -0
- package/dist/components/ThemeToggle.svelte.d.ts +14 -0
- package/dist/components/UniversalNode.svelte +155 -0
- package/dist/components/UniversalNode.svelte.d.ts +15 -0
- package/dist/components/WorkflowEditor.svelte +1035 -0
- package/dist/components/WorkflowEditor.svelte.d.ts +23 -0
- package/dist/components/form/FormArray.svelte +1049 -0
- package/dist/components/form/FormArray.svelte.d.ts +22 -0
- package/dist/components/form/FormAutocomplete.svelte +1009 -0
- package/dist/components/form/FormAutocomplete.svelte.d.ts +25 -0
- package/dist/components/form/FormCheckboxGroup.stories.svelte +28 -0
- package/dist/components/form/FormCheckboxGroup.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormCheckboxGroup.svelte +155 -0
- package/dist/components/form/FormCheckboxGroup.svelte.d.ts +17 -0
- package/dist/components/form/FormCodeEditor.svelte +458 -0
- package/dist/components/form/FormCodeEditor.svelte.d.ts +25 -0
- package/dist/components/form/FormField.svelte +417 -0
- package/dist/components/form/FormField.svelte.d.ts +29 -0
- package/dist/components/form/FormFieldLight.svelte +425 -0
- package/dist/components/form/FormFieldLight.svelte.d.ts +18 -0
- package/dist/components/form/FormFieldWrapper.stories.svelte +53 -0
- package/dist/components/form/FormFieldWrapper.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormFieldWrapper.svelte +125 -0
- package/dist/components/form/FormFieldWrapper.svelte.d.ts +18 -0
- package/dist/components/form/FormFieldset.svelte +142 -0
- package/dist/components/form/FormFieldset.svelte.d.ts +11 -0
- package/dist/components/form/FormMarkdownEditor.svelte +752 -0
- package/dist/components/form/FormMarkdownEditor.svelte.d.ts +33 -0
- package/dist/components/form/FormNumberField.stories.svelte +36 -0
- package/dist/components/form/FormNumberField.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormNumberField.svelte +112 -0
- package/dist/components/form/FormNumberField.svelte.d.ts +25 -0
- package/dist/components/form/FormRangeField.stories.svelte +31 -0
- package/dist/components/form/FormRangeField.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormRangeField.svelte +246 -0
- package/dist/components/form/FormRangeField.svelte.d.ts +23 -0
- package/dist/components/form/FormSelect.stories.svelte +50 -0
- package/dist/components/form/FormSelect.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormSelect.svelte +129 -0
- package/dist/components/form/FormSelect.svelte.d.ts +20 -0
- package/dist/components/form/FormTemplateEditor.svelte +825 -0
- package/dist/components/form/FormTemplateEditor.svelte.d.ts +41 -0
- package/dist/components/form/FormTextField.stories.svelte +30 -0
- package/dist/components/form/FormTextField.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormTextField.svelte +91 -0
- package/dist/components/form/FormTextField.svelte.d.ts +19 -0
- package/dist/components/form/FormTextarea.stories.svelte +34 -0
- package/dist/components/form/FormTextarea.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormTextarea.svelte +97 -0
- package/dist/components/form/FormTextarea.svelte.d.ts +21 -0
- package/dist/components/form/FormToggle.stories.svelte +30 -0
- package/dist/components/form/FormToggle.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormToggle.svelte +126 -0
- package/dist/components/form/FormToggle.svelte.d.ts +19 -0
- package/dist/components/form/FormUISchemaRenderer.svelte +136 -0
- package/dist/components/form/FormUISchemaRenderer.svelte.d.ts +32 -0
- package/dist/components/form/index.d.ts +50 -0
- package/dist/components/form/index.js +54 -0
- package/dist/components/form/templateAutocomplete.d.ts +29 -0
- package/dist/components/form/templateAutocomplete.js +254 -0
- package/dist/components/form/types.d.ts +485 -0
- package/dist/components/form/types.js +73 -0
- package/dist/components/interrupt/ChoicePrompt.stories.svelte +52 -0
- package/dist/components/interrupt/ChoicePrompt.stories.svelte.d.ts +27 -0
- package/dist/components/interrupt/ChoicePrompt.svelte +401 -0
- package/dist/components/interrupt/ChoicePrompt.svelte.d.ts +23 -0
- package/dist/components/interrupt/ConfirmationPrompt.stories.svelte +71 -0
- package/dist/components/interrupt/ConfirmationPrompt.stories.svelte.d.ts +27 -0
- package/dist/components/interrupt/ConfirmationPrompt.svelte +292 -0
- package/dist/components/interrupt/ConfirmationPrompt.svelte.d.ts +25 -0
- package/dist/components/interrupt/FormPrompt.svelte +236 -0
- package/dist/components/interrupt/FormPrompt.svelte.d.ts +23 -0
- package/dist/components/interrupt/InterruptBubble.svelte +601 -0
- package/dist/components/interrupt/InterruptBubble.svelte.d.ts +16 -0
- package/dist/components/interrupt/ReviewPrompt.stories.svelte +67 -0
- package/dist/components/interrupt/ReviewPrompt.stories.svelte.d.ts +27 -0
- package/dist/components/interrupt/ReviewPrompt.svelte +861 -0
- package/dist/components/interrupt/ReviewPrompt.svelte.d.ts +23 -0
- package/dist/components/interrupt/TextInputPrompt.stories.svelte +47 -0
- package/dist/components/interrupt/TextInputPrompt.stories.svelte.d.ts +27 -0
- package/dist/components/interrupt/TextInputPrompt.svelte +346 -0
- package/dist/components/interrupt/TextInputPrompt.svelte.d.ts +23 -0
- package/dist/components/interrupt/index.d.ts +13 -0
- package/dist/components/interrupt/index.js +15 -0
- package/dist/components/layouts/MainLayout.svelte +718 -0
- package/dist/components/layouts/MainLayout.svelte.d.ts +62 -0
- package/dist/components/nodes/GatewayNode.stories.svelte +108 -0
- package/dist/components/nodes/GatewayNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/GatewayNode.svelte +591 -0
- package/dist/components/nodes/GatewayNode.svelte.d.ts +15 -0
- package/dist/components/nodes/IdeaNode.stories.svelte +52 -0
- package/dist/components/nodes/IdeaNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/IdeaNode.svelte +455 -0
- package/dist/components/nodes/IdeaNode.svelte.d.ts +24 -0
- package/dist/components/nodes/NotesNode.stories.svelte +76 -0
- package/dist/components/nodes/NotesNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/NotesNode.svelte +378 -0
- package/dist/components/nodes/NotesNode.svelte.d.ts +24 -0
- package/dist/components/nodes/SimpleNode.stories.svelte +159 -0
- package/dist/components/nodes/SimpleNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/SimpleNode.svelte +451 -0
- package/dist/components/nodes/SimpleNode.svelte.d.ts +25 -0
- package/dist/components/nodes/SquareNode.stories.svelte +82 -0
- package/dist/components/nodes/SquareNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/SquareNode.svelte +407 -0
- package/dist/components/nodes/SquareNode.svelte.d.ts +25 -0
- package/dist/components/nodes/TerminalNode.stories.svelte +25 -0
- package/dist/components/nodes/TerminalNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/TerminalNode.svelte +690 -0
- package/dist/components/nodes/TerminalNode.svelte.d.ts +25 -0
- package/dist/components/nodes/ToolNode.stories.svelte +189 -0
- package/dist/components/nodes/ToolNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/ToolNode.svelte +471 -0
- package/dist/components/nodes/ToolNode.svelte.d.ts +36 -0
- package/dist/components/nodes/WorkflowNode.stories.svelte +55 -0
- package/dist/components/nodes/WorkflowNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/WorkflowNode.svelte +571 -0
- package/dist/components/nodes/WorkflowNode.svelte.d.ts +15 -0
- package/dist/components/playground/ChatPanel.svelte +905 -0
- package/dist/components/playground/ChatPanel.svelte.d.ts +46 -0
- package/dist/components/playground/ExecutionLogs.svelte +488 -0
- package/dist/components/playground/ExecutionLogs.svelte.d.ts +14 -0
- package/dist/components/playground/InputCollector.svelte +444 -0
- package/dist/components/playground/InputCollector.svelte.d.ts +16 -0
- package/dist/components/playground/MessageBubble.stories.svelte +62 -0
- package/dist/components/playground/MessageBubble.stories.svelte.d.ts +27 -0
- package/dist/components/playground/MessageBubble.svelte +633 -0
- package/dist/components/playground/MessageBubble.svelte.d.ts +24 -0
- package/dist/components/playground/Playground.svelte +1075 -0
- package/dist/components/playground/Playground.svelte.d.ts +25 -0
- package/dist/components/playground/PlaygroundModal.svelte +220 -0
- package/dist/components/playground/PlaygroundModal.svelte.d.ts +25 -0
- package/dist/components/playground/SessionManager.svelte +538 -0
- package/dist/components/playground/SessionManager.svelte.d.ts +20 -0
- package/dist/config/agentSpecEndpoints.d.ts +70 -0
- package/dist/config/agentSpecEndpoints.js +65 -0
- package/dist/config/constants.d.ts +43 -0
- package/dist/config/constants.js +31 -0
- package/dist/config/defaultCategories.d.ts +7 -0
- package/dist/config/defaultCategories.js +126 -0
- package/dist/config/defaultPortConfig.d.ts +6 -0
- package/dist/config/defaultPortConfig.js +201 -0
- package/dist/config/endpoints.d.ts +160 -0
- package/dist/config/endpoints.js +146 -0
- package/dist/config/runtimeConfig.d.ts +47 -0
- package/dist/config/runtimeConfig.js +80 -0
- package/dist/core/index.d.ts +75 -0
- package/dist/core/index.js +92 -0
- package/dist/display/index.d.ts +29 -0
- package/dist/display/index.js +36 -0
- package/dist/editor/index.d.ts +95 -0
- package/dist/editor/index.js +138 -0
- package/dist/form/code.d.ts +101 -0
- package/dist/form/code.js +168 -0
- package/dist/form/fieldRegistry.d.ts +169 -0
- package/dist/form/fieldRegistry.js +152 -0
- package/dist/form/full.d.ts +56 -0
- package/dist/form/full.js +80 -0
- package/dist/form/index.d.ts +77 -0
- package/dist/form/index.js +91 -0
- package/dist/form/markdown.d.ts +69 -0
- package/dist/form/markdown.js +103 -0
- package/dist/helpers/nodeLayoutHelper.d.ts +14 -0
- package/dist/helpers/nodeLayoutHelper.js +19 -0
- package/dist/helpers/proximityConnect.d.ts +94 -0
- package/dist/helpers/proximityConnect.js +314 -0
- package/dist/helpers/workflowEditorHelper.d.ts +183 -0
- package/dist/helpers/workflowEditorHelper.js +595 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +64 -0
- package/dist/mocks/app-environment.d.ts +8 -0
- package/dist/mocks/app-environment.js +16 -0
- package/dist/mocks/app-forms.d.ts +2 -0
- package/dist/mocks/app-forms.js +22 -0
- package/dist/mocks/app-navigation.d.ts +5 -0
- package/dist/mocks/app-navigation.js +36 -0
- package/dist/mocks/app-stores.d.ts +14 -0
- package/dist/mocks/app-stores.js +26 -0
- package/dist/playground/index.d.ts +131 -0
- package/dist/playground/index.js +172 -0
- package/dist/playground/mount.d.ts +203 -0
- package/dist/playground/mount.js +235 -0
- package/dist/registry/BaseRegistry.d.ts +92 -0
- package/dist/registry/BaseRegistry.js +124 -0
- package/dist/registry/builtinFormats.d.ts +23 -0
- package/dist/registry/builtinFormats.js +70 -0
- package/dist/registry/builtinNodes.d.ts +77 -0
- package/dist/registry/builtinNodes.js +211 -0
- package/dist/registry/index.d.ts +8 -0
- package/dist/registry/index.js +12 -0
- package/dist/registry/nodeComponentRegistry.d.ts +276 -0
- package/dist/registry/nodeComponentRegistry.js +262 -0
- package/dist/registry/plugin.d.ts +215 -0
- package/dist/registry/plugin.js +249 -0
- package/dist/registry/workflowFormatRegistry.d.ts +122 -0
- package/dist/registry/workflowFormatRegistry.js +96 -0
- package/dist/schema/index.d.ts +23 -0
- package/dist/schema/index.js +23 -0
- package/dist/schemas/v1/workflow.schema.json +1078 -0
- package/dist/services/agentSpecExecutionService.d.ts +106 -0
- package/dist/services/agentSpecExecutionService.js +334 -0
- package/dist/services/api.d.ts +115 -0
- package/dist/services/api.js +214 -0
- package/dist/services/apiVariableService.d.ts +114 -0
- package/dist/services/apiVariableService.js +338 -0
- package/dist/services/autoSaveService.d.ts +112 -0
- package/dist/services/autoSaveService.js +227 -0
- package/dist/services/categoriesApi.d.ts +14 -0
- package/dist/services/categoriesApi.js +49 -0
- package/dist/services/draftStorage.d.ts +171 -0
- package/dist/services/draftStorage.js +299 -0
- package/dist/services/dynamicSchemaService.d.ts +108 -0
- package/dist/services/dynamicSchemaService.js +444 -0
- package/dist/services/globalSave.d.ts +69 -0
- package/dist/services/globalSave.js +248 -0
- package/dist/services/historyService.d.ts +208 -0
- package/dist/services/historyService.js +321 -0
- package/dist/services/interruptService.d.ts +133 -0
- package/dist/services/interruptService.js +280 -0
- package/dist/services/nodeExecutionService.d.ts +63 -0
- package/dist/services/nodeExecutionService.js +266 -0
- package/dist/services/playgroundService.d.ts +130 -0
- package/dist/services/playgroundService.js +321 -0
- package/dist/services/portConfigApi.d.ts +14 -0
- package/dist/services/portConfigApi.js +54 -0
- package/dist/services/settingsService.d.ts +92 -0
- package/dist/services/settingsService.js +196 -0
- package/dist/services/toastService.d.ts +156 -0
- package/dist/services/toastService.js +265 -0
- package/dist/services/variableService.d.ts +141 -0
- package/dist/services/variableService.js +463 -0
- package/dist/services/workflowStorage.d.ts +37 -0
- package/dist/services/workflowStorage.js +116 -0
- package/dist/settings/index.d.ts +25 -0
- package/dist/settings/index.js +33 -0
- package/dist/stores/categoriesStore.svelte.d.ts +32 -0
- package/dist/stores/categoriesStore.svelte.js +77 -0
- package/dist/stores/editorStateMachine.svelte.d.ts +42 -0
- package/dist/stores/editorStateMachine.svelte.js +132 -0
- package/dist/stores/historyStore.svelte.d.ts +136 -0
- package/dist/stores/historyStore.svelte.js +207 -0
- package/dist/stores/interruptStore.svelte.d.ts +179 -0
- package/dist/stores/interruptStore.svelte.js +346 -0
- package/dist/stores/playgroundStore.svelte.d.ts +230 -0
- package/dist/stores/playgroundStore.svelte.js +515 -0
- package/dist/stores/portCoordinateStore.svelte.d.ts +66 -0
- package/dist/stores/portCoordinateStore.svelte.js +186 -0
- package/dist/stores/settingsStore.svelte.d.ts +158 -0
- package/dist/stores/settingsStore.svelte.js +544 -0
- package/dist/stores/workflowStore.svelte.d.ts +260 -0
- package/dist/stores/workflowStore.svelte.js +649 -0
- package/dist/stories/CanvasDecorator.svelte +49 -0
- package/dist/stories/CanvasDecorator.svelte.d.ts +8 -0
- package/dist/stories/NodeDecorator.svelte +73 -0
- package/dist/stories/NodeDecorator.svelte.d.ts +8 -0
- package/dist/stories/utils.d.ts +93 -0
- package/dist/stories/utils.js +122 -0
- package/dist/styles/base.css +1300 -0
- package/dist/styles/toast.css +35 -0
- package/dist/styles/tokens.css +475 -0
- package/dist/svelte-app.d.ts +150 -0
- package/dist/svelte-app.js +295 -0
- package/dist/types/agentspec.d.ts +318 -0
- package/dist/types/agentspec.js +48 -0
- package/dist/types/auth.d.ts +263 -0
- package/dist/types/auth.js +229 -0
- package/dist/types/config.d.ts +151 -0
- package/dist/types/config.js +7 -0
- package/dist/types/events.d.ts +190 -0
- package/dist/types/events.js +30 -0
- package/dist/types/index.d.ts +1234 -0
- package/dist/types/index.js +27 -0
- package/dist/types/interrupt.d.ts +390 -0
- package/dist/types/interrupt.js +145 -0
- package/dist/types/interruptState.d.ts +211 -0
- package/dist/types/interruptState.js +308 -0
- package/dist/types/playground.d.ts +351 -0
- package/dist/types/playground.js +95 -0
- package/dist/types/settings.d.ts +189 -0
- package/dist/types/settings.js +97 -0
- package/dist/types/uischema.d.ts +144 -0
- package/dist/types/uischema.js +51 -0
- package/dist/utils/colors.d.ts +288 -0
- package/dist/utils/colors.js +548 -0
- package/dist/utils/config.d.ts +37 -0
- package/dist/utils/config.js +226 -0
- package/dist/utils/connections.d.ts +125 -0
- package/dist/utils/connections.js +414 -0
- package/dist/utils/errors.d.ts +28 -0
- package/dist/utils/errors.js +44 -0
- package/dist/utils/fetchWithAuth.d.ts +25 -0
- package/dist/utils/fetchWithAuth.js +34 -0
- package/dist/utils/handleIds.d.ts +35 -0
- package/dist/utils/handleIds.js +58 -0
- package/dist/utils/handlePositioning.d.ts +31 -0
- package/dist/utils/handlePositioning.js +35 -0
- package/dist/utils/icons.d.ts +106 -0
- package/dist/utils/icons.js +157 -0
- package/dist/utils/logger.d.ts +47 -0
- package/dist/utils/logger.js +72 -0
- package/dist/utils/nodeStatus.d.ts +53 -0
- package/dist/utils/nodeStatus.js +183 -0
- package/dist/utils/nodeTypes.d.ts +117 -0
- package/dist/utils/nodeTypes.js +244 -0
- package/dist/utils/nodeWrapper.d.ts +39 -0
- package/dist/utils/nodeWrapper.js +62 -0
- package/dist/utils/performanceUtils.d.ts +30 -0
- package/dist/utils/performanceUtils.js +108 -0
- package/dist/utils/sanitize.d.ts +19 -0
- package/dist/utils/sanitize.js +31 -0
- package/dist/utils/uischema.d.ts +52 -0
- package/dist/utils/uischema.js +88 -0
- package/dist/utils/validation.d.ts +29 -0
- package/dist/utils/validation.js +39 -0
- package/package.json +292 -0
|
@@ -0,0 +1,649 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Store for FlowDrop (Svelte 5 Runes)
|
|
3
|
+
*
|
|
4
|
+
* Provides global state management for workflows with dirty state tracking
|
|
5
|
+
* and undo/redo history integration.
|
|
6
|
+
*
|
|
7
|
+
* **Important: Single-instance only.** This store uses module-level singletons.
|
|
8
|
+
* Only one FlowDrop editor instance per page is supported. Mounting multiple
|
|
9
|
+
* FlowDrop editors on the same page will cause them to share workflow state.
|
|
10
|
+
*
|
|
11
|
+
* @module stores/workflowStore
|
|
12
|
+
*/
|
|
13
|
+
import { DEFAULT_WORKFLOW_FORMAT } from '../types/index.js';
|
|
14
|
+
import { historyService } from '../services/historyService.js';
|
|
15
|
+
/**
|
|
16
|
+
* Safely build updated workflow metadata, providing defaults for required fields.
|
|
17
|
+
*/
|
|
18
|
+
function buildMetadata(existing, updates) {
|
|
19
|
+
return {
|
|
20
|
+
version: existing?.version ?? '1.0',
|
|
21
|
+
createdAt: existing?.createdAt ?? new Date().toISOString(),
|
|
22
|
+
updatedAt: new Date().toISOString(),
|
|
23
|
+
author: existing?.author,
|
|
24
|
+
tags: existing?.tags,
|
|
25
|
+
versionId: existing?.versionId,
|
|
26
|
+
updateNumber: existing?.updateNumber,
|
|
27
|
+
format: existing?.format,
|
|
28
|
+
...updates
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// =========================================================================
|
|
32
|
+
// Core Workflow State (Svelte 5 Runes)
|
|
33
|
+
// =========================================================================
|
|
34
|
+
/** Global workflow state */
|
|
35
|
+
let workflowState = $state(null);
|
|
36
|
+
// =========================================================================
|
|
37
|
+
// Dirty State Tracking
|
|
38
|
+
// =========================================================================
|
|
39
|
+
/**
|
|
40
|
+
* State for tracking if there are unsaved changes
|
|
41
|
+
*
|
|
42
|
+
* This is set to true whenever the workflow changes after initialization.
|
|
43
|
+
* It can be reset to false by calling markAsSaved().
|
|
44
|
+
*/
|
|
45
|
+
let isDirtyState = $state(false);
|
|
46
|
+
/**
|
|
47
|
+
* Snapshot of the workflow when it was last saved
|
|
48
|
+
*
|
|
49
|
+
* Used to compare current state with saved state.
|
|
50
|
+
*/
|
|
51
|
+
let savedSnapshot = null;
|
|
52
|
+
/**
|
|
53
|
+
* Callback for dirty state changes
|
|
54
|
+
*
|
|
55
|
+
* Set by the App component to notify parent application.
|
|
56
|
+
*/
|
|
57
|
+
let onDirtyStateChangeCallback = null;
|
|
58
|
+
/**
|
|
59
|
+
* Callback for workflow changes
|
|
60
|
+
*
|
|
61
|
+
* Set by the App component to notify parent application.
|
|
62
|
+
*/
|
|
63
|
+
let onWorkflowChangeCallback = null;
|
|
64
|
+
/**
|
|
65
|
+
* Flag to track if we're currently restoring from history (undo/redo)
|
|
66
|
+
*
|
|
67
|
+
* When true, prevents pushing to history to avoid recursive loops.
|
|
68
|
+
*/
|
|
69
|
+
let isRestoringFromHistory = false;
|
|
70
|
+
/**
|
|
71
|
+
* Flag to track if history recording is enabled
|
|
72
|
+
*
|
|
73
|
+
* Can be disabled for bulk operations or when history is not needed.
|
|
74
|
+
*/
|
|
75
|
+
let historyEnabled = true;
|
|
76
|
+
// =========================================================================
|
|
77
|
+
// Getter Functions (Reactive State Access)
|
|
78
|
+
// =========================================================================
|
|
79
|
+
/**
|
|
80
|
+
* Get the current workflow store value reactively
|
|
81
|
+
*
|
|
82
|
+
* @returns The current workflow or null
|
|
83
|
+
*/
|
|
84
|
+
export function getWorkflowStore() {
|
|
85
|
+
return workflowState;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get the current dirty state reactively
|
|
89
|
+
*
|
|
90
|
+
* @returns true if there are unsaved changes
|
|
91
|
+
*/
|
|
92
|
+
export function getIsDirty() {
|
|
93
|
+
return isDirtyState;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get the workflow ID reactively
|
|
97
|
+
*
|
|
98
|
+
* @returns The workflow ID or null
|
|
99
|
+
*/
|
|
100
|
+
export function getWorkflowId() {
|
|
101
|
+
return workflowState?.id ?? null;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get the workflow name reactively
|
|
105
|
+
*
|
|
106
|
+
* @returns The workflow name or 'Untitled Workflow'
|
|
107
|
+
*/
|
|
108
|
+
export function getWorkflowName() {
|
|
109
|
+
return workflowState?.name ?? 'Untitled Workflow';
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Get the workflow nodes reactively
|
|
113
|
+
*
|
|
114
|
+
* @returns Array of workflow nodes
|
|
115
|
+
*/
|
|
116
|
+
export function getWorkflowNodes() {
|
|
117
|
+
return workflowState?.nodes ?? [];
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get the workflow edges reactively
|
|
121
|
+
*
|
|
122
|
+
* @returns Array of workflow edges
|
|
123
|
+
*/
|
|
124
|
+
export function getWorkflowEdges() {
|
|
125
|
+
return workflowState?.edges ?? [];
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get the workflow metadata reactively
|
|
129
|
+
*
|
|
130
|
+
* @returns The workflow metadata with defaults
|
|
131
|
+
*/
|
|
132
|
+
export function getWorkflowMetadata() {
|
|
133
|
+
return (workflowState?.metadata ?? {
|
|
134
|
+
version: '1.0.0',
|
|
135
|
+
createdAt: new Date().toISOString(),
|
|
136
|
+
updatedAt: new Date().toISOString(),
|
|
137
|
+
versionId: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
138
|
+
updateNumber: 0
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get the current workflow format reactively
|
|
143
|
+
*
|
|
144
|
+
* @returns The workflow format string
|
|
145
|
+
*/
|
|
146
|
+
export function getWorkflowFormat() {
|
|
147
|
+
return workflowState?.metadata?.format ?? DEFAULT_WORKFLOW_FORMAT;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get workflow change summary reactively (useful for triggering saves)
|
|
151
|
+
*
|
|
152
|
+
* @returns Object with nodes, edges, and name
|
|
153
|
+
*/
|
|
154
|
+
export function getWorkflowChanged() {
|
|
155
|
+
return {
|
|
156
|
+
nodes: getWorkflowNodes(),
|
|
157
|
+
edges: getWorkflowEdges(),
|
|
158
|
+
name: getWorkflowName()
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get workflow validation state reactively
|
|
163
|
+
*
|
|
164
|
+
* @returns Validation info object
|
|
165
|
+
*/
|
|
166
|
+
export function getWorkflowValidation() {
|
|
167
|
+
const nodes = getWorkflowNodes();
|
|
168
|
+
const edges = getWorkflowEdges();
|
|
169
|
+
return {
|
|
170
|
+
hasNodes: nodes.length > 0,
|
|
171
|
+
hasEdges: edges.length > 0,
|
|
172
|
+
nodeCount: nodes.length,
|
|
173
|
+
edgeCount: edges.length,
|
|
174
|
+
isValid: nodes.length > 0 && edges.length >= 0
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Get workflow metadata change summary reactively
|
|
179
|
+
*
|
|
180
|
+
* @returns Metadata change info
|
|
181
|
+
*/
|
|
182
|
+
export function getWorkflowMetadataChanged() {
|
|
183
|
+
const metadata = getWorkflowMetadata();
|
|
184
|
+
return {
|
|
185
|
+
createdAt: metadata.createdAt,
|
|
186
|
+
updatedAt: metadata.updatedAt,
|
|
187
|
+
version: metadata.version ?? '1.0.0'
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Get connected handles reactively
|
|
192
|
+
*
|
|
193
|
+
* Provides a Set of all handle IDs that are currently connected to edges.
|
|
194
|
+
* Used by node components to implement hideUnconnectedHandles functionality.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```typescript
|
|
198
|
+
* import { getConnectedHandles } from './workflowStore.svelte.js';
|
|
199
|
+
*
|
|
200
|
+
* // Check if a specific handle is connected
|
|
201
|
+
* const isConnected = getConnectedHandles().has('node-1-input-data');
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
export function getConnectedHandles() {
|
|
205
|
+
const edges = getWorkflowEdges();
|
|
206
|
+
const handles = new Set();
|
|
207
|
+
edges.forEach((edge) => {
|
|
208
|
+
// Add source handle (output port)
|
|
209
|
+
if (edge.sourceHandle) {
|
|
210
|
+
handles.add(edge.sourceHandle);
|
|
211
|
+
}
|
|
212
|
+
// Add target handle (input port)
|
|
213
|
+
if (edge.targetHandle) {
|
|
214
|
+
handles.add(edge.targetHandle);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
return handles;
|
|
218
|
+
}
|
|
219
|
+
// =========================================================================
|
|
220
|
+
// Callback Setters
|
|
221
|
+
// =========================================================================
|
|
222
|
+
/**
|
|
223
|
+
* Set the dirty state change callback
|
|
224
|
+
*
|
|
225
|
+
* @param callback - Function to call when dirty state changes
|
|
226
|
+
*/
|
|
227
|
+
export function setOnDirtyStateChange(callback) {
|
|
228
|
+
onDirtyStateChangeCallback = callback;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Set the workflow change callback
|
|
232
|
+
*
|
|
233
|
+
* @param callback - Function to call when workflow changes
|
|
234
|
+
*/
|
|
235
|
+
export function setOnWorkflowChange(callback) {
|
|
236
|
+
onWorkflowChangeCallback = callback;
|
|
237
|
+
}
|
|
238
|
+
// =========================================================================
|
|
239
|
+
// Internal Helpers
|
|
240
|
+
// =========================================================================
|
|
241
|
+
/**
|
|
242
|
+
* Create a snapshot of the workflow for comparison
|
|
243
|
+
*
|
|
244
|
+
* @param workflow - The workflow to snapshot
|
|
245
|
+
* @returns A JSON string representation for comparison
|
|
246
|
+
*/
|
|
247
|
+
function createSnapshot(workflow) {
|
|
248
|
+
if (!workflow)
|
|
249
|
+
return null;
|
|
250
|
+
// Only include the parts that matter for "dirty" detection
|
|
251
|
+
const toSnapshot = {
|
|
252
|
+
name: workflow.name,
|
|
253
|
+
description: workflow.description,
|
|
254
|
+
nodes: workflow.nodes.map((n) => ({
|
|
255
|
+
id: n.id,
|
|
256
|
+
position: n.position,
|
|
257
|
+
data: {
|
|
258
|
+
label: n.data.label,
|
|
259
|
+
config: n.data.config
|
|
260
|
+
}
|
|
261
|
+
})),
|
|
262
|
+
edges: workflow.edges.map((e) => ({
|
|
263
|
+
id: e.id,
|
|
264
|
+
source: e.source,
|
|
265
|
+
target: e.target,
|
|
266
|
+
sourceHandle: e.sourceHandle,
|
|
267
|
+
targetHandle: e.targetHandle
|
|
268
|
+
}))
|
|
269
|
+
};
|
|
270
|
+
return JSON.stringify(toSnapshot);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Update dirty state based on current workflow
|
|
274
|
+
*
|
|
275
|
+
* Compares current workflow with saved snapshot.
|
|
276
|
+
*/
|
|
277
|
+
function updateDirtyState() {
|
|
278
|
+
const currentSnapshot = createSnapshot(workflowState);
|
|
279
|
+
const newIsDirty = currentSnapshot !== savedSnapshot;
|
|
280
|
+
if (newIsDirty !== isDirtyState) {
|
|
281
|
+
isDirtyState = newIsDirty;
|
|
282
|
+
if (onDirtyStateChangeCallback) {
|
|
283
|
+
onDirtyStateChangeCallback(newIsDirty);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Mark the workflow change and update dirty state
|
|
289
|
+
*
|
|
290
|
+
* @param changeType - The type of change that occurred
|
|
291
|
+
*/
|
|
292
|
+
function notifyWorkflowChange(changeType) {
|
|
293
|
+
if (workflowState && onWorkflowChangeCallback) {
|
|
294
|
+
onWorkflowChangeCallback(workflowState, changeType);
|
|
295
|
+
}
|
|
296
|
+
updateDirtyState();
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Mark the current workflow state as saved
|
|
300
|
+
*
|
|
301
|
+
* Clears the dirty state by updating the saved snapshot.
|
|
302
|
+
*/
|
|
303
|
+
export function markAsSaved() {
|
|
304
|
+
savedSnapshot = createSnapshot(workflowState);
|
|
305
|
+
isDirtyState = false;
|
|
306
|
+
if (onDirtyStateChangeCallback) {
|
|
307
|
+
onDirtyStateChangeCallback(false);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Check if there are unsaved changes (non-reactive version for plain TS)
|
|
312
|
+
*
|
|
313
|
+
* @returns true if there are unsaved changes
|
|
314
|
+
*/
|
|
315
|
+
export function isDirty() {
|
|
316
|
+
return isDirtyState;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Enable or disable history recording
|
|
320
|
+
*
|
|
321
|
+
* Useful for bulk operations where you don't want individual history entries.
|
|
322
|
+
*
|
|
323
|
+
* @param enabled - Whether history should be recorded
|
|
324
|
+
*/
|
|
325
|
+
export function setHistoryEnabled(enabled) {
|
|
326
|
+
historyEnabled = enabled;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Check if history recording is enabled
|
|
330
|
+
*
|
|
331
|
+
* @returns true if history is being recorded
|
|
332
|
+
*/
|
|
333
|
+
export function isHistoryEnabled() {
|
|
334
|
+
return historyEnabled;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Set the restoring from history flag
|
|
338
|
+
*
|
|
339
|
+
* Used internally by the history store when performing undo/redo.
|
|
340
|
+
*
|
|
341
|
+
* @param restoring - Whether we're currently restoring from history
|
|
342
|
+
*/
|
|
343
|
+
export function setRestoringFromHistory(restoring) {
|
|
344
|
+
isRestoringFromHistory = restoring;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Push current state to history before making changes
|
|
348
|
+
*
|
|
349
|
+
* @param description - Description of the change about to be made
|
|
350
|
+
* @param workflow - Optional workflow to push (uses store if not provided)
|
|
351
|
+
*/
|
|
352
|
+
function pushToHistory(description, workflow) {
|
|
353
|
+
if (!historyEnabled || isRestoringFromHistory) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
const workflowToPush = workflow ?? workflowState;
|
|
357
|
+
if (workflowToPush) {
|
|
358
|
+
historyService.push(workflowToPush, { description });
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Get the current workflow (non-reactive version for plain TS)
|
|
363
|
+
*
|
|
364
|
+
* @returns The current workflow or null
|
|
365
|
+
*/
|
|
366
|
+
export function getWorkflow() {
|
|
367
|
+
return workflowState;
|
|
368
|
+
}
|
|
369
|
+
// =========================================================================
|
|
370
|
+
// Helper Functions
|
|
371
|
+
// =========================================================================
|
|
372
|
+
/**
|
|
373
|
+
* Check if workflow data has actually changed
|
|
374
|
+
*
|
|
375
|
+
* Used to prevent unnecessary updates and infinite loops.
|
|
376
|
+
*/
|
|
377
|
+
function hasWorkflowDataChanged(currentWorkflow, newNodes, newEdges) {
|
|
378
|
+
if (!currentWorkflow)
|
|
379
|
+
return true;
|
|
380
|
+
// Check if nodes have changed
|
|
381
|
+
if (currentWorkflow.nodes.length !== newNodes.length)
|
|
382
|
+
return true;
|
|
383
|
+
for (let i = 0; i < newNodes.length; i++) {
|
|
384
|
+
const currentNode = currentWorkflow.nodes[i];
|
|
385
|
+
const newNode = newNodes[i];
|
|
386
|
+
if (!currentNode || !newNode)
|
|
387
|
+
return true;
|
|
388
|
+
if (currentNode.id !== newNode.id)
|
|
389
|
+
return true;
|
|
390
|
+
if (currentNode.position.x !== newNode.position.x ||
|
|
391
|
+
currentNode.position.y !== newNode.position.y)
|
|
392
|
+
return true;
|
|
393
|
+
if (JSON.stringify(currentNode.data) !== JSON.stringify(newNode.data))
|
|
394
|
+
return true;
|
|
395
|
+
}
|
|
396
|
+
// Check if edges have changed
|
|
397
|
+
if (currentWorkflow.edges.length !== newEdges.length)
|
|
398
|
+
return true;
|
|
399
|
+
for (let i = 0; i < newEdges.length; i++) {
|
|
400
|
+
const currentEdge = currentWorkflow.edges[i];
|
|
401
|
+
const newEdge = newEdges[i];
|
|
402
|
+
if (!currentEdge || !newEdge)
|
|
403
|
+
return true;
|
|
404
|
+
if (currentEdge.id !== newEdge.id)
|
|
405
|
+
return true;
|
|
406
|
+
if (currentEdge.source !== newEdge.source || currentEdge.target !== newEdge.target)
|
|
407
|
+
return true;
|
|
408
|
+
}
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
// =========================================================================
|
|
412
|
+
// Workflow Actions
|
|
413
|
+
// =========================================================================
|
|
414
|
+
/**
|
|
415
|
+
* Actions for updating the workflow
|
|
416
|
+
*
|
|
417
|
+
* All actions that modify the workflow will trigger dirty state updates
|
|
418
|
+
* and emit change events.
|
|
419
|
+
*/
|
|
420
|
+
export const workflowActions = {
|
|
421
|
+
/**
|
|
422
|
+
* Initialize workflow (from load or new)
|
|
423
|
+
*
|
|
424
|
+
* This sets the initial saved snapshot, clears dirty state, and initializes history.
|
|
425
|
+
*/
|
|
426
|
+
initialize: (workflow) => {
|
|
427
|
+
workflowState = workflow;
|
|
428
|
+
// Set the saved snapshot - workflow is "clean" after initialization
|
|
429
|
+
savedSnapshot = createSnapshot(workflow);
|
|
430
|
+
isDirtyState = false;
|
|
431
|
+
if (onDirtyStateChangeCallback) {
|
|
432
|
+
onDirtyStateChangeCallback(false);
|
|
433
|
+
}
|
|
434
|
+
// Initialize history with the loaded workflow
|
|
435
|
+
historyService.initialize(workflow);
|
|
436
|
+
},
|
|
437
|
+
/**
|
|
438
|
+
* Update the entire workflow
|
|
439
|
+
*
|
|
440
|
+
* Note: This is typically called from SvelteFlow sync and should not push to history
|
|
441
|
+
* for every small change. History is pushed by specific actions or drag handlers.
|
|
442
|
+
*/
|
|
443
|
+
updateWorkflow: (workflow) => {
|
|
444
|
+
workflowState = workflow;
|
|
445
|
+
notifyWorkflowChange('metadata');
|
|
446
|
+
},
|
|
447
|
+
/**
|
|
448
|
+
* Restore workflow from history (undo/redo)
|
|
449
|
+
*
|
|
450
|
+
* This bypasses history recording to prevent recursive loops.
|
|
451
|
+
*/
|
|
452
|
+
restoreFromHistory: (workflow) => {
|
|
453
|
+
isRestoringFromHistory = true;
|
|
454
|
+
workflowState = workflow;
|
|
455
|
+
notifyWorkflowChange('metadata');
|
|
456
|
+
isRestoringFromHistory = false;
|
|
457
|
+
},
|
|
458
|
+
/**
|
|
459
|
+
* Update nodes
|
|
460
|
+
*/
|
|
461
|
+
updateNodes: (nodes) => {
|
|
462
|
+
if (!workflowState)
|
|
463
|
+
return;
|
|
464
|
+
// Check if nodes have actually changed to prevent infinite loops
|
|
465
|
+
if (!hasWorkflowDataChanged(workflowState, nodes, workflowState.edges)) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
// Generate unique version identifier
|
|
469
|
+
const versionId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
470
|
+
workflowState = {
|
|
471
|
+
...workflowState,
|
|
472
|
+
nodes,
|
|
473
|
+
metadata: buildMetadata(workflowState.metadata, {
|
|
474
|
+
versionId,
|
|
475
|
+
updateNumber: (workflowState.metadata?.updateNumber ?? 0) + 1
|
|
476
|
+
})
|
|
477
|
+
};
|
|
478
|
+
notifyWorkflowChange('node_move');
|
|
479
|
+
},
|
|
480
|
+
/**
|
|
481
|
+
* Update edges
|
|
482
|
+
*/
|
|
483
|
+
updateEdges: (edges) => {
|
|
484
|
+
if (!workflowState)
|
|
485
|
+
return;
|
|
486
|
+
// Check if edges have actually changed to prevent infinite loops
|
|
487
|
+
if (!hasWorkflowDataChanged(workflowState, workflowState.nodes, edges)) {
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
// Generate unique version identifier
|
|
491
|
+
const versionId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
492
|
+
workflowState = {
|
|
493
|
+
...workflowState,
|
|
494
|
+
edges,
|
|
495
|
+
metadata: buildMetadata(workflowState.metadata, {
|
|
496
|
+
versionId,
|
|
497
|
+
updateNumber: (workflowState.metadata?.updateNumber ?? 0) + 1
|
|
498
|
+
})
|
|
499
|
+
};
|
|
500
|
+
notifyWorkflowChange('edge_add');
|
|
501
|
+
},
|
|
502
|
+
/**
|
|
503
|
+
* Update workflow name
|
|
504
|
+
*/
|
|
505
|
+
updateName: (name) => {
|
|
506
|
+
if (!workflowState)
|
|
507
|
+
return;
|
|
508
|
+
workflowState = {
|
|
509
|
+
...workflowState,
|
|
510
|
+
name,
|
|
511
|
+
metadata: buildMetadata(workflowState.metadata)
|
|
512
|
+
};
|
|
513
|
+
notifyWorkflowChange('name');
|
|
514
|
+
},
|
|
515
|
+
/**
|
|
516
|
+
* Add a node
|
|
517
|
+
*/
|
|
518
|
+
addNode: (node) => {
|
|
519
|
+
pushToHistory('Add node');
|
|
520
|
+
if (!workflowState)
|
|
521
|
+
return;
|
|
522
|
+
workflowState = {
|
|
523
|
+
...workflowState,
|
|
524
|
+
nodes: [...workflowState.nodes, node],
|
|
525
|
+
metadata: buildMetadata(workflowState.metadata)
|
|
526
|
+
};
|
|
527
|
+
notifyWorkflowChange('node_add');
|
|
528
|
+
},
|
|
529
|
+
/**
|
|
530
|
+
* Remove a node
|
|
531
|
+
*
|
|
532
|
+
* This is an atomic operation that also removes connected edges.
|
|
533
|
+
* A single undo will restore both the node and its edges.
|
|
534
|
+
*/
|
|
535
|
+
removeNode: (nodeId) => {
|
|
536
|
+
pushToHistory('Delete node');
|
|
537
|
+
if (!workflowState)
|
|
538
|
+
return;
|
|
539
|
+
workflowState = {
|
|
540
|
+
...workflowState,
|
|
541
|
+
nodes: workflowState.nodes.filter((node) => node.id !== nodeId),
|
|
542
|
+
edges: workflowState.edges.filter((edge) => edge.source !== nodeId && edge.target !== nodeId),
|
|
543
|
+
metadata: buildMetadata(workflowState.metadata)
|
|
544
|
+
};
|
|
545
|
+
notifyWorkflowChange('node_remove');
|
|
546
|
+
},
|
|
547
|
+
/**
|
|
548
|
+
* Add an edge
|
|
549
|
+
*/
|
|
550
|
+
addEdge: (edge) => {
|
|
551
|
+
pushToHistory('Add connection');
|
|
552
|
+
if (!workflowState)
|
|
553
|
+
return;
|
|
554
|
+
workflowState = {
|
|
555
|
+
...workflowState,
|
|
556
|
+
edges: [...workflowState.edges, edge],
|
|
557
|
+
metadata: buildMetadata(workflowState.metadata)
|
|
558
|
+
};
|
|
559
|
+
notifyWorkflowChange('edge_add');
|
|
560
|
+
},
|
|
561
|
+
/**
|
|
562
|
+
* Remove an edge
|
|
563
|
+
*/
|
|
564
|
+
removeEdge: (edgeId) => {
|
|
565
|
+
pushToHistory('Delete connection');
|
|
566
|
+
if (!workflowState)
|
|
567
|
+
return;
|
|
568
|
+
workflowState = {
|
|
569
|
+
...workflowState,
|
|
570
|
+
edges: workflowState.edges.filter((edge) => edge.id !== edgeId),
|
|
571
|
+
metadata: buildMetadata(workflowState.metadata)
|
|
572
|
+
};
|
|
573
|
+
notifyWorkflowChange('edge_remove');
|
|
574
|
+
},
|
|
575
|
+
/**
|
|
576
|
+
* Update a specific node
|
|
577
|
+
*
|
|
578
|
+
* Used for config changes. Pushes to history for undo support.
|
|
579
|
+
*/
|
|
580
|
+
updateNode: (nodeId, updates) => {
|
|
581
|
+
pushToHistory('Update node config');
|
|
582
|
+
if (!workflowState)
|
|
583
|
+
return;
|
|
584
|
+
workflowState = {
|
|
585
|
+
...workflowState,
|
|
586
|
+
nodes: workflowState.nodes.map((node) => node.id === nodeId ? { ...node, ...updates } : node),
|
|
587
|
+
metadata: buildMetadata(workflowState.metadata)
|
|
588
|
+
};
|
|
589
|
+
notifyWorkflowChange('node_config');
|
|
590
|
+
},
|
|
591
|
+
/**
|
|
592
|
+
* Clear the workflow
|
|
593
|
+
*
|
|
594
|
+
* Resets the workflow and clears history.
|
|
595
|
+
*/
|
|
596
|
+
clear: () => {
|
|
597
|
+
workflowState = null;
|
|
598
|
+
savedSnapshot = null;
|
|
599
|
+
isDirtyState = false;
|
|
600
|
+
historyService.clear();
|
|
601
|
+
if (onDirtyStateChangeCallback) {
|
|
602
|
+
onDirtyStateChangeCallback(false);
|
|
603
|
+
}
|
|
604
|
+
},
|
|
605
|
+
/**
|
|
606
|
+
* Update workflow metadata
|
|
607
|
+
*/
|
|
608
|
+
updateMetadata: (metadata) => {
|
|
609
|
+
if (!workflowState)
|
|
610
|
+
return;
|
|
611
|
+
workflowState = {
|
|
612
|
+
...workflowState,
|
|
613
|
+
metadata: buildMetadata(workflowState.metadata, metadata)
|
|
614
|
+
};
|
|
615
|
+
notifyWorkflowChange('metadata');
|
|
616
|
+
},
|
|
617
|
+
/**
|
|
618
|
+
* Batch update nodes and edges
|
|
619
|
+
*
|
|
620
|
+
* Useful for complex operations that update multiple things at once.
|
|
621
|
+
* Creates a single history entry for the entire batch.
|
|
622
|
+
*/
|
|
623
|
+
batchUpdate: (updates) => {
|
|
624
|
+
pushToHistory('Batch update');
|
|
625
|
+
if (!workflowState)
|
|
626
|
+
return;
|
|
627
|
+
workflowState = {
|
|
628
|
+
...workflowState,
|
|
629
|
+
...(updates.nodes && { nodes: updates.nodes }),
|
|
630
|
+
...(updates.edges && { edges: updates.edges }),
|
|
631
|
+
...(updates.name && { name: updates.name }),
|
|
632
|
+
...(updates.description !== undefined && { description: updates.description }),
|
|
633
|
+
metadata: buildMetadata(workflowState.metadata, updates.metadata ?? undefined)
|
|
634
|
+
};
|
|
635
|
+
notifyWorkflowChange('metadata');
|
|
636
|
+
},
|
|
637
|
+
/**
|
|
638
|
+
* Push current state to history manually
|
|
639
|
+
*
|
|
640
|
+
* Use this before operations that modify the workflow through other means
|
|
641
|
+
* (e.g., drag operations handled by SvelteFlow directly).
|
|
642
|
+
*
|
|
643
|
+
* @param description - Description of the upcoming change
|
|
644
|
+
* @param workflow - Optional workflow to push (uses store state if not provided)
|
|
645
|
+
*/
|
|
646
|
+
pushHistory: (description, workflow) => {
|
|
647
|
+
pushToHistory(description, workflow);
|
|
648
|
+
}
|
|
649
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
CanvasDecorator: Renders child components inside an empty SvelteFlow canvas,
|
|
3
|
+
matching how overlay components (e.g. CanvasBanner) appear in the workflow editor.
|
|
4
|
+
-->
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
import { SvelteFlow, Controls } from '@xyflow/svelte';
|
|
7
|
+
import type { ColorMode } from '@xyflow/svelte';
|
|
8
|
+
import '@xyflow/svelte/dist/style.css';
|
|
9
|
+
import type { Snippet } from 'svelte';
|
|
10
|
+
|
|
11
|
+
let { children }: { children: Snippet } = $props();
|
|
12
|
+
|
|
13
|
+
// Watch the data-theme attribute set by Storybook's addon-themes
|
|
14
|
+
let colorMode = $state<ColorMode>(
|
|
15
|
+
(document.documentElement.getAttribute('data-theme') as ColorMode) || 'light'
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
$effect(() => {
|
|
19
|
+
const observer = new MutationObserver(() => {
|
|
20
|
+
colorMode = (document.documentElement.getAttribute('data-theme') as ColorMode) || 'light';
|
|
21
|
+
});
|
|
22
|
+
observer.observe(document.documentElement, {
|
|
23
|
+
attributes: true,
|
|
24
|
+
attributeFilter: ['data-theme']
|
|
25
|
+
});
|
|
26
|
+
return () => observer.disconnect();
|
|
27
|
+
});
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<div class="canvas-decorator-wrapper">
|
|
31
|
+
<SvelteFlow nodes={[]} edges={[]} {colorMode}>
|
|
32
|
+
<Controls />
|
|
33
|
+
{@render children()}
|
|
34
|
+
</SvelteFlow>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<style>
|
|
38
|
+
.canvas-decorator-wrapper {
|
|
39
|
+
width: 800px;
|
|
40
|
+
height: 400px;
|
|
41
|
+
position: relative;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Fix: SvelteFlow's scoped styles use non-prefixed --background-color-default
|
|
45
|
+
which doesn't update with colorMode="dark". Map the --xy- themed value. */
|
|
46
|
+
.canvas-decorator-wrapper :global(.svelte-flow.dark) {
|
|
47
|
+
--background-color-default: var(--xy-background-color-default);
|
|
48
|
+
}
|
|
49
|
+
</style>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import '@xyflow/svelte/dist/style.css';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
children: Snippet;
|
|
5
|
+
};
|
|
6
|
+
declare const CanvasDecorator: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type CanvasDecorator = ReturnType<typeof CanvasDecorator>;
|
|
8
|
+
export default CanvasDecorator;
|