@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,544 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings Store for FlowDrop (Svelte 5 Runes)
|
|
3
|
+
*
|
|
4
|
+
* Provides unified state management for all user-configurable settings with:
|
|
5
|
+
* - Hybrid persistence (localStorage primary, optional API sync)
|
|
6
|
+
* - Category-specific getter functions for performance
|
|
7
|
+
* - Deep merge support for partial updates
|
|
8
|
+
* - Integrated theme system with system preference detection
|
|
9
|
+
*
|
|
10
|
+
* @module stores/settingsStore
|
|
11
|
+
*/
|
|
12
|
+
import { DEFAULT_SETTINGS, SETTINGS_STORAGE_KEY } from '../types/settings.js';
|
|
13
|
+
import { logger } from '../utils/logger.js';
|
|
14
|
+
// =========================================================================
|
|
15
|
+
// Internal State
|
|
16
|
+
// =========================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Settings service reference (set via setSettingsService)
|
|
19
|
+
* Allows API sync without circular dependencies
|
|
20
|
+
*/
|
|
21
|
+
let settingsService = null;
|
|
22
|
+
/**
|
|
23
|
+
* Change listeners for external subscribers
|
|
24
|
+
*/
|
|
25
|
+
const changeListeners = new Set();
|
|
26
|
+
// =========================================================================
|
|
27
|
+
// localStorage Persistence
|
|
28
|
+
// =========================================================================
|
|
29
|
+
/**
|
|
30
|
+
* Load settings from localStorage
|
|
31
|
+
*
|
|
32
|
+
* @returns Saved settings or null if not found/invalid
|
|
33
|
+
*/
|
|
34
|
+
function loadFromStorage() {
|
|
35
|
+
if (typeof window === 'undefined') {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const saved = localStorage.getItem(SETTINGS_STORAGE_KEY);
|
|
40
|
+
if (saved) {
|
|
41
|
+
const parsed = JSON.parse(saved);
|
|
42
|
+
// Deep merge with defaults to handle missing properties
|
|
43
|
+
return deepMergeSettings(DEFAULT_SETTINGS, parsed);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
logger.warn('Failed to load settings from localStorage:', error);
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Save settings to localStorage
|
|
53
|
+
*
|
|
54
|
+
* @param settings - Settings to persist
|
|
55
|
+
*/
|
|
56
|
+
function saveToStorage(settings) {
|
|
57
|
+
if (typeof window === 'undefined') {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
localStorage.setItem(SETTINGS_STORAGE_KEY, JSON.stringify(settings));
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
logger.warn('Failed to save settings to localStorage:', error);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// =========================================================================
|
|
68
|
+
// Deep Merge Utility
|
|
69
|
+
// =========================================================================
|
|
70
|
+
/**
|
|
71
|
+
* Deep merge settings objects
|
|
72
|
+
*
|
|
73
|
+
* @param target - Target object (defaults)
|
|
74
|
+
* @param source - Source object (partial updates)
|
|
75
|
+
* @returns Merged settings
|
|
76
|
+
*/
|
|
77
|
+
function deepMergeSettings(target, source) {
|
|
78
|
+
const result = {
|
|
79
|
+
theme: { ...target.theme },
|
|
80
|
+
editor: { ...target.editor },
|
|
81
|
+
ui: { ...target.ui },
|
|
82
|
+
behavior: { ...target.behavior },
|
|
83
|
+
api: { ...target.api }
|
|
84
|
+
};
|
|
85
|
+
// Merge theme settings
|
|
86
|
+
if (source.theme) {
|
|
87
|
+
result.theme = { ...result.theme, ...source.theme };
|
|
88
|
+
}
|
|
89
|
+
// Merge editor settings
|
|
90
|
+
if (source.editor) {
|
|
91
|
+
result.editor = { ...result.editor, ...source.editor };
|
|
92
|
+
}
|
|
93
|
+
// Merge UI settings
|
|
94
|
+
if (source.ui) {
|
|
95
|
+
result.ui = { ...result.ui, ...source.ui };
|
|
96
|
+
}
|
|
97
|
+
// Merge behavior settings
|
|
98
|
+
if (source.behavior) {
|
|
99
|
+
result.behavior = { ...result.behavior, ...source.behavior };
|
|
100
|
+
}
|
|
101
|
+
// Merge API settings
|
|
102
|
+
if (source.api) {
|
|
103
|
+
result.api = { ...result.api, ...source.api };
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
// =========================================================================
|
|
108
|
+
// Main Settings Store (Rune-based)
|
|
109
|
+
// =========================================================================
|
|
110
|
+
/**
|
|
111
|
+
* Initial state loaded from localStorage or defaults
|
|
112
|
+
*/
|
|
113
|
+
const initialSettings = loadFromStorage() ?? DEFAULT_SETTINGS;
|
|
114
|
+
/**
|
|
115
|
+
* Main settings store state using $state rune
|
|
116
|
+
*/
|
|
117
|
+
let storeState = $state({
|
|
118
|
+
settings: initialSettings,
|
|
119
|
+
initialized: true,
|
|
120
|
+
syncStatus: 'idle',
|
|
121
|
+
lastSyncedAt: null,
|
|
122
|
+
syncError: null
|
|
123
|
+
});
|
|
124
|
+
/**
|
|
125
|
+
* System theme preference using $state rune
|
|
126
|
+
* Updates when system preference changes
|
|
127
|
+
*/
|
|
128
|
+
let systemThemeState = $state(typeof window !== 'undefined' ? getSystemTheme() : 'light');
|
|
129
|
+
// =========================================================================
|
|
130
|
+
// Getter Functions (replacing derived stores)
|
|
131
|
+
// =========================================================================
|
|
132
|
+
/**
|
|
133
|
+
* Get current settings (replaces settingsStore derived store)
|
|
134
|
+
*/
|
|
135
|
+
export function getSettings() {
|
|
136
|
+
return storeState.settings;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get sync status (replaces syncStatusStore derived store)
|
|
140
|
+
*/
|
|
141
|
+
export function getSyncStatus() {
|
|
142
|
+
return {
|
|
143
|
+
status: storeState.syncStatus,
|
|
144
|
+
lastSyncedAt: storeState.lastSyncedAt,
|
|
145
|
+
error: storeState.syncError
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Get theme settings (replaces themeSettings derived store)
|
|
150
|
+
*/
|
|
151
|
+
export function getThemeSettings() {
|
|
152
|
+
return storeState.settings.theme;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get editor settings (replaces editorSettings derived store)
|
|
156
|
+
*/
|
|
157
|
+
export function getEditorSettings() {
|
|
158
|
+
return storeState.settings.editor;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get UI settings (replaces uiSettings derived store)
|
|
162
|
+
*/
|
|
163
|
+
export function getUiSettings() {
|
|
164
|
+
return storeState.settings.ui;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Get behavior settings (replaces behaviorSettings derived store)
|
|
168
|
+
*/
|
|
169
|
+
export function getBehaviorSettings() {
|
|
170
|
+
return storeState.settings.behavior;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get API settings (replaces apiSettings derived store)
|
|
174
|
+
*/
|
|
175
|
+
export function getApiSettings() {
|
|
176
|
+
return storeState.settings.api;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Get theme preference (replaces theme derived store)
|
|
180
|
+
*/
|
|
181
|
+
export function getTheme() {
|
|
182
|
+
return storeState.settings.theme.preference;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Get resolved theme - the actual theme applied ('light' or 'dark')
|
|
186
|
+
* When preference is 'auto', resolves based on system preference
|
|
187
|
+
* (replaces resolvedTheme derived store)
|
|
188
|
+
*/
|
|
189
|
+
export function getResolvedTheme() {
|
|
190
|
+
if (storeState.settings.theme.preference === 'auto') {
|
|
191
|
+
return systemThemeState;
|
|
192
|
+
}
|
|
193
|
+
return storeState.settings.theme.preference;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Get system theme state (for internal use)
|
|
197
|
+
*/
|
|
198
|
+
export function getSystemThemeState() {
|
|
199
|
+
return systemThemeState;
|
|
200
|
+
}
|
|
201
|
+
// =========================================================================
|
|
202
|
+
// Theme System
|
|
203
|
+
// =========================================================================
|
|
204
|
+
/**
|
|
205
|
+
* Get the system's color scheme preference
|
|
206
|
+
*/
|
|
207
|
+
function getSystemTheme() {
|
|
208
|
+
if (typeof window === 'undefined') {
|
|
209
|
+
return 'light';
|
|
210
|
+
}
|
|
211
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Initialize the system theme change listener.
|
|
215
|
+
* Sets up a media query listener for the system color scheme preference.
|
|
216
|
+
*
|
|
217
|
+
* @returns Cleanup function that removes the listener
|
|
218
|
+
*/
|
|
219
|
+
export function initThemeListener() {
|
|
220
|
+
if (typeof window === 'undefined') {
|
|
221
|
+
return () => { };
|
|
222
|
+
}
|
|
223
|
+
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
224
|
+
const handleSystemThemeChange = (event) => {
|
|
225
|
+
systemThemeState = event.matches ? 'dark' : 'light';
|
|
226
|
+
};
|
|
227
|
+
mediaQuery.addEventListener('change', handleSystemThemeChange);
|
|
228
|
+
return () => {
|
|
229
|
+
mediaQuery.removeEventListener('change', handleSystemThemeChange);
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
// =========================================================================
|
|
233
|
+
// Settings Update Functions
|
|
234
|
+
// =========================================================================
|
|
235
|
+
/**
|
|
236
|
+
* Notify change listeners about a settings change
|
|
237
|
+
*/
|
|
238
|
+
function notifyChange(category, key, previousValue, newValue) {
|
|
239
|
+
const event = {
|
|
240
|
+
category,
|
|
241
|
+
key,
|
|
242
|
+
previousValue,
|
|
243
|
+
newValue
|
|
244
|
+
};
|
|
245
|
+
changeListeners.forEach((listener) => {
|
|
246
|
+
try {
|
|
247
|
+
listener(event);
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
logger.error('Settings change listener error:', error);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Get category settings as a plain object for comparison
|
|
256
|
+
*/
|
|
257
|
+
function getCategoryAsRecord(settings, category) {
|
|
258
|
+
return Object.fromEntries(Object.entries(settings[category]));
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Update settings with partial values
|
|
262
|
+
*
|
|
263
|
+
* @param partial - Partial settings to merge
|
|
264
|
+
*/
|
|
265
|
+
export function updateSettings(partial) {
|
|
266
|
+
const previousSettings = storeState.settings;
|
|
267
|
+
const newSettings = deepMergeSettings(storeState.settings, partial);
|
|
268
|
+
// Persist to localStorage immediately
|
|
269
|
+
saveToStorage(newSettings);
|
|
270
|
+
// Notify listeners for each changed category
|
|
271
|
+
for (const category of Object.keys(partial)) {
|
|
272
|
+
const partialCategory = partial[category];
|
|
273
|
+
if (partialCategory && typeof partialCategory === 'object') {
|
|
274
|
+
for (const key of Object.keys(partialCategory)) {
|
|
275
|
+
const prevCat = getCategoryAsRecord(previousSettings, category);
|
|
276
|
+
const newCat = getCategoryAsRecord(newSettings, category);
|
|
277
|
+
if (prevCat[key] !== newCat[key]) {
|
|
278
|
+
notifyChange(category, key, prevCat[key], newCat[key]);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
storeState = {
|
|
284
|
+
...storeState,
|
|
285
|
+
settings: newSettings
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Reset settings to defaults
|
|
290
|
+
*
|
|
291
|
+
* @param categories - Optional categories to reset (all if not specified)
|
|
292
|
+
*/
|
|
293
|
+
export function resetSettings(categories) {
|
|
294
|
+
if (categories && categories.length > 0) {
|
|
295
|
+
const partial = {};
|
|
296
|
+
for (const category of categories) {
|
|
297
|
+
partial[category] = DEFAULT_SETTINGS[category];
|
|
298
|
+
}
|
|
299
|
+
updateSettings(partial);
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
saveToStorage(DEFAULT_SETTINGS);
|
|
303
|
+
storeState = {
|
|
304
|
+
...storeState,
|
|
305
|
+
settings: DEFAULT_SETTINGS
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// =========================================================================
|
|
310
|
+
// Theme Actions
|
|
311
|
+
// =========================================================================
|
|
312
|
+
/**
|
|
313
|
+
* Set the theme preference
|
|
314
|
+
*
|
|
315
|
+
* @param newTheme - The new theme preference ('light', 'dark', or 'auto')
|
|
316
|
+
*/
|
|
317
|
+
export function setTheme(newTheme) {
|
|
318
|
+
updateSettings({ theme: { preference: newTheme } });
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Toggle between light and dark themes
|
|
322
|
+
* If currently 'auto', switches to the opposite of system preference
|
|
323
|
+
*/
|
|
324
|
+
export function toggleTheme() {
|
|
325
|
+
const currentTheme = getTheme();
|
|
326
|
+
const currentResolved = getResolvedTheme();
|
|
327
|
+
if (currentTheme === 'auto') {
|
|
328
|
+
setTheme(currentResolved === 'dark' ? 'light' : 'dark');
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
setTheme(currentTheme === 'dark' ? 'light' : 'dark');
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Cycle through theme options: light -> dark -> auto -> light
|
|
336
|
+
*/
|
|
337
|
+
export function cycleTheme() {
|
|
338
|
+
const currentTheme = getTheme();
|
|
339
|
+
switch (currentTheme) {
|
|
340
|
+
case 'light':
|
|
341
|
+
setTheme('dark');
|
|
342
|
+
break;
|
|
343
|
+
case 'dark':
|
|
344
|
+
setTheme('auto');
|
|
345
|
+
break;
|
|
346
|
+
case 'auto':
|
|
347
|
+
setTheme('light');
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Apply theme to the document
|
|
353
|
+
*
|
|
354
|
+
* @param resolved - The resolved theme to apply
|
|
355
|
+
*/
|
|
356
|
+
function applyTheme(resolved) {
|
|
357
|
+
if (typeof document === 'undefined') {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
document.documentElement.setAttribute('data-theme', resolved);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Stored cleanup function for the theme effect.
|
|
364
|
+
* Retained so it can be called by cleanupThemeSubscription().
|
|
365
|
+
*/
|
|
366
|
+
let themeEffectCleanup = null;
|
|
367
|
+
/**
|
|
368
|
+
* Clean up the theme subscription created by initializeTheme().
|
|
369
|
+
* Call this when tearing down the settings system (e.g., in tests or
|
|
370
|
+
* component cleanup) to prevent memory leaks.
|
|
371
|
+
*/
|
|
372
|
+
export function cleanupThemeSubscription() {
|
|
373
|
+
if (themeEffectCleanup) {
|
|
374
|
+
themeEffectCleanup();
|
|
375
|
+
themeEffectCleanup = null;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Initialize the theme system
|
|
380
|
+
* Should be called once on app startup
|
|
381
|
+
*
|
|
382
|
+
* This function:
|
|
383
|
+
* 1. Applies the current resolved theme to the document
|
|
384
|
+
* 2. Sets up reactivity to apply theme changes
|
|
385
|
+
*
|
|
386
|
+
* Note: In Svelte 5, we use $effect for reactivity. Since $effect can only
|
|
387
|
+
* be used in component context or $effect.root, we use $effect.root here
|
|
388
|
+
* to create a standalone reactive scope.
|
|
389
|
+
*/
|
|
390
|
+
export function initializeTheme() {
|
|
391
|
+
const resolved = getResolvedTheme();
|
|
392
|
+
applyTheme(resolved);
|
|
393
|
+
// Create a standalone reactive root to watch for theme changes.
|
|
394
|
+
// $effect.root returns a cleanup function.
|
|
395
|
+
themeEffectCleanup = $effect.root(() => {
|
|
396
|
+
$effect(() => {
|
|
397
|
+
const currentResolved = getResolvedTheme();
|
|
398
|
+
applyTheme(currentResolved);
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Check if theme system is initialized
|
|
404
|
+
* Useful for SSR scenarios
|
|
405
|
+
*
|
|
406
|
+
* @returns true if running in browser and theme is applied
|
|
407
|
+
*/
|
|
408
|
+
export function isThemeInitialized() {
|
|
409
|
+
if (typeof document === 'undefined') {
|
|
410
|
+
return false;
|
|
411
|
+
}
|
|
412
|
+
return document.documentElement.hasAttribute('data-theme');
|
|
413
|
+
}
|
|
414
|
+
// =========================================================================
|
|
415
|
+
// API Sync Functions
|
|
416
|
+
// =========================================================================
|
|
417
|
+
/**
|
|
418
|
+
* Set the settings service for API operations
|
|
419
|
+
*
|
|
420
|
+
* @param service - Settings service instance
|
|
421
|
+
*/
|
|
422
|
+
export function setSettingsService(service) {
|
|
423
|
+
settingsService = service;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Sync current settings to the backend API
|
|
427
|
+
*
|
|
428
|
+
* @returns Promise that resolves when sync is complete
|
|
429
|
+
*/
|
|
430
|
+
export async function syncSettingsToApi() {
|
|
431
|
+
if (!settingsService) {
|
|
432
|
+
logger.warn('Settings service not configured for API sync');
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
storeState = {
|
|
436
|
+
...storeState,
|
|
437
|
+
syncStatus: 'syncing',
|
|
438
|
+
syncError: null
|
|
439
|
+
};
|
|
440
|
+
try {
|
|
441
|
+
const currentSettings = getSettings();
|
|
442
|
+
await settingsService.savePreferences(currentSettings);
|
|
443
|
+
storeState = {
|
|
444
|
+
...storeState,
|
|
445
|
+
syncStatus: 'synced',
|
|
446
|
+
lastSyncedAt: Date.now(),
|
|
447
|
+
syncError: null
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
catch (error) {
|
|
451
|
+
const errorMessage = error instanceof Error ? error.message : 'Failed to sync settings';
|
|
452
|
+
storeState = {
|
|
453
|
+
...storeState,
|
|
454
|
+
syncStatus: 'error',
|
|
455
|
+
syncError: errorMessage
|
|
456
|
+
};
|
|
457
|
+
throw error;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Load settings from the backend API
|
|
462
|
+
*
|
|
463
|
+
* @returns Promise that resolves when load is complete
|
|
464
|
+
*/
|
|
465
|
+
export async function loadSettingsFromApi() {
|
|
466
|
+
if (!settingsService) {
|
|
467
|
+
logger.warn('Settings service not configured for API sync');
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
storeState = {
|
|
471
|
+
...storeState,
|
|
472
|
+
syncStatus: 'syncing',
|
|
473
|
+
syncError: null
|
|
474
|
+
};
|
|
475
|
+
try {
|
|
476
|
+
const apiSettingsData = await settingsService.getPreferences();
|
|
477
|
+
const mergedSettings = deepMergeSettings(DEFAULT_SETTINGS, apiSettingsData);
|
|
478
|
+
storeState = {
|
|
479
|
+
...storeState,
|
|
480
|
+
settings: mergedSettings,
|
|
481
|
+
syncStatus: 'synced',
|
|
482
|
+
lastSyncedAt: Date.now(),
|
|
483
|
+
syncError: null
|
|
484
|
+
};
|
|
485
|
+
// Also persist to localStorage
|
|
486
|
+
saveToStorage(mergedSettings);
|
|
487
|
+
}
|
|
488
|
+
catch (error) {
|
|
489
|
+
const errorMessage = error instanceof Error ? error.message : 'Failed to load settings from API';
|
|
490
|
+
storeState = {
|
|
491
|
+
...storeState,
|
|
492
|
+
syncStatus: 'error',
|
|
493
|
+
syncError: errorMessage
|
|
494
|
+
};
|
|
495
|
+
throw error;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
// =========================================================================
|
|
499
|
+
// Change Listeners
|
|
500
|
+
// =========================================================================
|
|
501
|
+
/**
|
|
502
|
+
* Subscribe to settings changes
|
|
503
|
+
*
|
|
504
|
+
* @param callback - Function to call when settings change
|
|
505
|
+
* @returns Unsubscribe function
|
|
506
|
+
*/
|
|
507
|
+
export function onSettingsChange(callback) {
|
|
508
|
+
changeListeners.add(callback);
|
|
509
|
+
return () => {
|
|
510
|
+
changeListeners.delete(callback);
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
// =========================================================================
|
|
514
|
+
// Initialization
|
|
515
|
+
// =========================================================================
|
|
516
|
+
/**
|
|
517
|
+
* Initialize the settings system
|
|
518
|
+
*
|
|
519
|
+
* @param options - Initialization options
|
|
520
|
+
*/
|
|
521
|
+
export async function initializeSettings(options) {
|
|
522
|
+
// Apply custom defaults if provided
|
|
523
|
+
if (options?.defaults) {
|
|
524
|
+
const currentSettings = getSettings();
|
|
525
|
+
const withDefaults = deepMergeSettings(currentSettings, options.defaults);
|
|
526
|
+
storeState = {
|
|
527
|
+
...storeState,
|
|
528
|
+
settings: withDefaults
|
|
529
|
+
};
|
|
530
|
+
saveToStorage(withDefaults);
|
|
531
|
+
}
|
|
532
|
+
// Initialize theme system
|
|
533
|
+
initializeTheme();
|
|
534
|
+
// Optionally sync with API
|
|
535
|
+
if (options?.apiSync && settingsService) {
|
|
536
|
+
try {
|
|
537
|
+
await loadSettingsFromApi();
|
|
538
|
+
}
|
|
539
|
+
catch {
|
|
540
|
+
// Silently fail - local settings are still available
|
|
541
|
+
logger.warn('Failed to sync settings from API on initialization');
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|