@d34dman/flowdrop 0.0.61 → 0.0.63
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/README.md +6 -0
- package/dist/adapters/WorkflowAdapter.d.ts +1 -1
- package/dist/adapters/agentspec/AgentSpecAdapter.js +3 -1
- package/dist/api/client.d.ts +4 -0
- package/dist/api/client.js +6 -1
- package/dist/api/enhanced-client.js +7 -6
- package/dist/components/App.svelte +143 -219
- package/dist/components/CanvasBanner.stories.svelte +25 -0
- package/dist/components/CanvasBanner.stories.svelte.d.ts +27 -0
- package/dist/components/CanvasBanner.svelte +2 -2
- package/dist/components/ConfigForm.svelte +37 -36
- package/dist/components/ConfigPanel.stories.svelte +38 -0
- package/dist/components/ConfigPanel.stories.svelte.d.ts +27 -0
- package/dist/components/ConfigPanel.svelte +2 -2
- package/dist/components/ConnectionLine.svelte +2 -2
- package/dist/components/FlowDropZone.svelte +18 -2
- package/dist/components/FlowDropZone.svelte.d.ts +2 -0
- package/dist/components/LoadingSpinner.stories.svelte +30 -0
- package/dist/components/LoadingSpinner.stories.svelte.d.ts +27 -0
- package/dist/components/Logo.stories.svelte +22 -0
- package/dist/components/Logo.stories.svelte.d.ts +27 -0
- package/dist/components/Logo.svelte +33 -13
- package/dist/components/Logo.svelte.d.ts +1 -1
- package/dist/components/MarkdownDisplay.stories.svelte +21 -0
- package/dist/components/MarkdownDisplay.stories.svelte.d.ts +27 -0
- package/dist/components/MarkdownDisplay.svelte +4 -3
- package/dist/components/Navbar.stories.svelte +41 -0
- package/dist/components/Navbar.stories.svelte.d.ts +27 -0
- package/dist/components/Navbar.svelte +4 -4
- package/dist/components/NodeSidebar.svelte +12 -12
- package/dist/components/NodeStatusOverlay.stories.svelte +74 -0
- package/dist/components/NodeStatusOverlay.stories.svelte.d.ts +27 -0
- package/dist/components/PipelineStatus.svelte +11 -4
- package/dist/components/PortCoordinateTracker.svelte +1 -1
- package/dist/components/SchemaForm.stories.svelte +101 -0
- package/dist/components/SchemaForm.stories.svelte.d.ts +27 -0
- package/dist/components/SchemaForm.svelte +17 -12
- package/dist/components/SettingsModal.svelte +3 -3
- package/dist/components/SettingsPanel.svelte +23 -22
- package/dist/components/StatusIcon.stories.svelte +60 -0
- package/dist/components/StatusIcon.stories.svelte.d.ts +27 -0
- package/dist/components/StatusIcon.svelte +7 -0
- package/dist/components/StatusLabel.stories.svelte +17 -0
- package/dist/components/StatusLabel.stories.svelte.d.ts +27 -0
- package/dist/components/ThemeToggle.stories.svelte +25 -0
- package/dist/components/ThemeToggle.stories.svelte.d.ts +27 -0
- package/dist/components/ThemeToggle.svelte +8 -8
- package/dist/components/UniversalNode.svelte +1 -1
- package/dist/components/WorkflowEditor.svelte +298 -298
- package/dist/components/form/FormAutocomplete.svelte +20 -19
- package/dist/components/form/FormCheckboxGroup.stories.svelte +28 -0
- package/dist/components/form/FormCheckboxGroup.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormField.svelte +3 -3
- package/dist/components/form/FormFieldLight.svelte +2 -2
- package/dist/components/form/FormFieldWrapper.stories.svelte +31 -0
- package/dist/components/form/FormFieldWrapper.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormFieldset.svelte +7 -7
- package/dist/components/form/FormNumberField.stories.svelte +33 -0
- package/dist/components/form/FormNumberField.stories.svelte.d.ts +27 -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/FormSelect.stories.svelte +50 -0
- package/dist/components/form/FormSelect.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormTemplateEditor.svelte +2 -1
- package/dist/components/form/FormTextField.stories.svelte +30 -0
- package/dist/components/form/FormTextField.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormTextarea.stories.svelte +31 -0
- package/dist/components/form/FormTextarea.stories.svelte.d.ts +27 -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/FormUISchemaRenderer.svelte +1 -1
- package/dist/components/form/types.d.ts +15 -47
- package/dist/components/interrupt/ChoicePrompt.stories.svelte +43 -0
- package/dist/components/interrupt/ChoicePrompt.stories.svelte.d.ts +27 -0
- package/dist/components/interrupt/ChoicePrompt.svelte +24 -24
- package/dist/components/interrupt/ConfirmationPrompt.stories.svelte +49 -0
- package/dist/components/interrupt/ConfirmationPrompt.stories.svelte.d.ts +27 -0
- package/dist/components/interrupt/ConfirmationPrompt.svelte +19 -19
- package/dist/components/interrupt/FormPrompt.svelte +15 -15
- package/dist/components/interrupt/InterruptBubble.svelte +202 -236
- package/dist/components/interrupt/InterruptBubble.svelte.d.ts +1 -1
- package/dist/components/interrupt/ReviewPrompt.stories.svelte +46 -0
- package/dist/components/interrupt/ReviewPrompt.stories.svelte.d.ts +27 -0
- package/dist/components/interrupt/ReviewPrompt.svelte +842 -0
- package/dist/components/interrupt/ReviewPrompt.svelte.d.ts +23 -0
- package/dist/components/interrupt/TextInputPrompt.stories.svelte +34 -0
- package/dist/components/interrupt/TextInputPrompt.stories.svelte.d.ts +27 -0
- package/dist/components/interrupt/TextInputPrompt.svelte +21 -21
- package/dist/components/nodes/GatewayNode.stories.svelte +76 -0
- package/dist/components/nodes/GatewayNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/GatewayNode.svelte +19 -17
- package/dist/components/nodes/IdeaNode.stories.svelte +48 -0
- package/dist/components/nodes/IdeaNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/IdeaNode.svelte +10 -26
- package/dist/components/nodes/NotesNode.stories.svelte +69 -0
- package/dist/components/nodes/NotesNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/NotesNode.svelte +8 -8
- package/dist/components/nodes/SimpleNode.stories.svelte +101 -0
- package/dist/components/nodes/SimpleNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/SimpleNode.svelte +16 -24
- package/dist/components/nodes/SquareNode.stories.svelte +56 -0
- package/dist/components/nodes/SquareNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/SquareNode.svelte +13 -21
- 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 +7 -7
- package/dist/components/nodes/ToolNode.stories.svelte +71 -0
- package/dist/components/nodes/ToolNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/ToolNode.svelte +7 -15
- package/dist/components/nodes/WorkflowNode.stories.svelte +50 -0
- package/dist/components/nodes/WorkflowNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/WorkflowNode.svelte +13 -13
- package/dist/components/playground/ChatPanel.svelte +48 -48
- package/dist/components/playground/ExecutionLogs.svelte +23 -23
- package/dist/components/playground/InputCollector.svelte +24 -24
- package/dist/components/playground/MessageBubble.stories.svelte +49 -0
- package/dist/components/playground/MessageBubble.stories.svelte.d.ts +27 -0
- package/dist/components/playground/MessageBubble.svelte +49 -46
- package/dist/components/playground/Playground.svelte +194 -129
- package/dist/components/playground/PlaygroundModal.svelte +5 -5
- package/dist/components/playground/SessionManager.svelte +26 -26
- package/dist/config/constants.d.ts +22 -0
- package/dist/config/constants.js +22 -0
- package/dist/config/endpoints.d.ts +19 -0
- package/dist/config/runtimeConfig.js +2 -1
- package/dist/core/index.d.ts +5 -2
- package/dist/core/index.js +9 -1
- package/dist/editor/index.d.ts +13 -9
- package/dist/editor/index.js +15 -11
- package/dist/form/code.d.ts +2 -1
- package/dist/form/code.js +1 -3
- package/dist/form/markdown.d.ts +2 -1
- package/dist/form/markdown.js +1 -3
- package/dist/helpers/workflowEditorHelper.js +18 -33
- package/dist/mocks/app-forms.js +1 -0
- package/dist/mocks/app-navigation.js +3 -1
- package/dist/mocks/app-stores.d.ts +4 -4
- package/dist/playground/index.d.ts +4 -3
- package/dist/playground/index.js +12 -10
- package/dist/playground/mount.js +6 -13
- package/dist/services/agentSpecExecutionService.js +2 -1
- package/dist/services/api.js +10 -18
- package/dist/services/apiVariableService.js +2 -1
- package/dist/services/autoSaveService.d.ts +3 -3
- package/dist/services/autoSaveService.js +21 -17
- package/dist/services/categoriesApi.js +13 -5
- package/dist/services/draftStorage.js +5 -4
- package/dist/services/dynamicSchemaService.js +4 -4
- package/dist/services/globalSave.d.ts +60 -11
- package/dist/services/globalSave.js +160 -83
- package/dist/services/historyService.d.ts +2 -1
- package/dist/services/historyService.js +7 -3
- package/dist/services/interruptService.js +9 -8
- package/dist/services/nodeExecutionService.js +14 -6
- package/dist/services/playgroundService.js +2 -1
- package/dist/services/portConfigApi.js +11 -7
- package/dist/services/toastService.d.ts +1 -1
- package/dist/services/toastService.js +6 -5
- package/dist/services/variableService.js +3 -2
- package/dist/settings/index.d.ts +1 -1
- package/dist/settings/index.js +1 -1
- package/dist/stores/{categoriesStore.d.ts → categoriesStore.svelte.d.ts} +3 -3
- package/dist/stores/{categoriesStore.js → categoriesStore.svelte.js} +15 -18
- package/dist/stores/editorStateMachine.svelte.d.ts +42 -0
- package/dist/stores/editorStateMachine.svelte.js +132 -0
- package/dist/stores/{historyStore.d.ts → historyStore.svelte.d.ts} +18 -15
- package/dist/stores/{historyStore.js → historyStore.svelte.js} +40 -21
- package/dist/stores/{interruptStore.d.ts → interruptStore.svelte.d.ts} +16 -15
- package/dist/stores/{interruptStore.js → interruptStore.svelte.js} +85 -94
- package/dist/stores/{playgroundStore.d.ts → playgroundStore.svelte.d.ts} +41 -33
- package/dist/stores/{playgroundStore.js → playgroundStore.svelte.js} +164 -84
- package/dist/stores/{portCoordinateStore.d.ts → portCoordinateStore.svelte.d.ts} +10 -4
- package/dist/stores/{portCoordinateStore.js → portCoordinateStore.svelte.js} +38 -35
- package/dist/stores/{settingsStore.d.ts → settingsStore.svelte.d.ts} +45 -28
- package/dist/stores/{settingsStore.js → settingsStore.svelte.js} +169 -128
- package/dist/stores/{workflowStore.d.ts → workflowStore.svelte.d.ts} +101 -65
- package/dist/stores/{workflowStore.js → workflowStore.svelte.js} +285 -239
- package/dist/stories/CanvasDecorator.svelte +50 -0
- package/dist/stories/CanvasDecorator.svelte.d.ts +8 -0
- package/dist/stories/NodeDecorator.svelte +74 -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 +114 -61
- package/dist/styles/toast.css +2 -2
- package/dist/styles/tokens.css +250 -185
- package/dist/svelte-app.d.ts +0 -6
- package/dist/svelte-app.js +13 -31
- package/dist/types/index.d.ts +2 -0
- package/dist/types/interrupt.d.ts +89 -5
- package/dist/types/interrupt.js +13 -1
- package/dist/types/playground.d.ts +5 -0
- package/dist/types/settings.js +1 -1
- package/dist/utils/colors.js +4 -4
- package/dist/utils/connections.js +33 -8
- package/dist/utils/icons.js +1 -1
- package/dist/utils/logger.d.ts +47 -0
- package/dist/utils/logger.js +72 -0
- package/dist/utils/nodeWrapper.js +1 -1
- package/dist/utils/sanitize.d.ts +19 -0
- package/dist/utils/sanitize.js +31 -0
- package/dist/utils/validation.d.ts +29 -0
- package/dist/utils/validation.js +39 -0
- package/package.json +243 -232
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module services/variableService
|
|
7
7
|
*/
|
|
8
|
+
import { logger } from '../utils/logger.js';
|
|
8
9
|
/**
|
|
9
10
|
* Converts a JSON Schema property type to a TemplateVariableType.
|
|
10
11
|
*
|
|
@@ -430,13 +431,13 @@ export async function getVariableSchema(node, nodes, edges, config, workflowId,
|
|
|
430
431
|
}
|
|
431
432
|
else if (!config.api.fallbackOnError) {
|
|
432
433
|
// API failed and fallback is disabled - return empty schema
|
|
433
|
-
|
|
434
|
+
logger.error('Failed to fetch variables from API:', apiResult.error);
|
|
434
435
|
return { variables: {} };
|
|
435
436
|
}
|
|
436
437
|
// If fallback is enabled (default), continue to schema-based mode below
|
|
437
438
|
}
|
|
438
439
|
catch (error) {
|
|
439
|
-
|
|
440
|
+
logger.error('Error fetching variables from API:', error);
|
|
440
441
|
// If fallback is disabled, return empty schema
|
|
441
442
|
if (config.api.fallbackOnError === false) {
|
|
442
443
|
return { variables: {} };
|
package/dist/settings/index.d.ts
CHANGED
|
@@ -21,5 +21,5 @@ export { default as SettingsPanel } from '../components/SettingsPanel.svelte';
|
|
|
21
21
|
export { default as SettingsModal } from '../components/SettingsModal.svelte';
|
|
22
22
|
export type { ThemeSettings, EditorSettings, UISettings, BehaviorSettings, ApiSettings, FlowDropSettings, SettingsCategory, PartialSettings, DeepPartial, SettingsChangeEvent, SettingsChangeCallback, SyncStatus, SettingsStoreState } from '../types/settings.js';
|
|
23
23
|
export { SETTINGS_CATEGORIES, SETTINGS_CATEGORY_LABELS, SETTINGS_CATEGORY_ICONS, DEFAULT_THEME_SETTINGS, DEFAULT_EDITOR_SETTINGS, DEFAULT_UI_SETTINGS, DEFAULT_BEHAVIOR_SETTINGS, DEFAULT_API_SETTINGS, DEFAULT_SETTINGS, SETTINGS_STORAGE_KEY } from '../types/settings.js';
|
|
24
|
-
export { settingsStore, themeSettings, editorSettings, uiSettings, behaviorSettings, apiSettings, syncStatusStore, updateSettings, resetSettings, getSettings, initializeSettings, setSettingsService, syncSettingsToApi, loadSettingsFromApi, onSettingsChange } from '../stores/settingsStore.js';
|
|
24
|
+
export { getSettings as settingsStore, getThemeSettings as themeSettings, getEditorSettings as editorSettings, getUiSettings as uiSettings, getBehaviorSettings as behaviorSettings, getApiSettings as apiSettings, getSyncStatus as syncStatusStore, updateSettings, resetSettings, getSettings, initializeSettings, setSettingsService, syncSettingsToApi, loadSettingsFromApi, onSettingsChange } from '../stores/settingsStore.svelte.js';
|
|
25
25
|
export { settingsApi, SettingsService, createSettingsService, setSettingsEndpointConfig, getSettingsEndpointConfig } from '../services/settingsService.js';
|
package/dist/settings/index.js
CHANGED
|
@@ -26,7 +26,7 @@ export { SETTINGS_CATEGORIES, SETTINGS_CATEGORY_LABELS, SETTINGS_CATEGORY_ICONS,
|
|
|
26
26
|
// ============================================================================
|
|
27
27
|
// Settings Stores
|
|
28
28
|
// ============================================================================
|
|
29
|
-
export { settingsStore, themeSettings, editorSettings, uiSettings, behaviorSettings, apiSettings, syncStatusStore, updateSettings, resetSettings, getSettings, initializeSettings, setSettingsService, syncSettingsToApi, loadSettingsFromApi, onSettingsChange } from '../stores/settingsStore.js';
|
|
29
|
+
export { getSettings as settingsStore, getThemeSettings as themeSettings, getEditorSettings as editorSettings, getUiSettings as uiSettings, getBehaviorSettings as behaviorSettings, getApiSettings as apiSettings, getSyncStatus as syncStatusStore, updateSettings, resetSettings, getSettings, initializeSettings, setSettingsService, syncSettingsToApi, loadSettingsFromApi, onSettingsChange } from '../stores/settingsStore.svelte.js';
|
|
30
30
|
// ============================================================================
|
|
31
31
|
// Settings Service
|
|
32
32
|
// ============================================================================
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Categories Store for FlowDrop
|
|
2
|
+
* Categories Store for FlowDrop (Svelte 5 Runes)
|
|
3
3
|
*
|
|
4
4
|
* Manages category definitions with merged defaults and API-provided overrides.
|
|
5
5
|
* Exposes lookup helpers for icon, color, and label resolution.
|
|
6
6
|
*/
|
|
7
7
|
import type { CategoryDefinition, NodeCategory } from '../types/index.js';
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Get all category definitions, sorted by weight.
|
|
10
10
|
*/
|
|
11
|
-
export declare
|
|
11
|
+
export declare function getCategories(): CategoryDefinition[];
|
|
12
12
|
/**
|
|
13
13
|
* Initialize categories with API data, merging with defaults.
|
|
14
14
|
* API categories override defaults by name; custom categories are appended.
|
|
@@ -1,30 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Categories Store for FlowDrop
|
|
2
|
+
* Categories Store for FlowDrop (Svelte 5 Runes)
|
|
3
3
|
*
|
|
4
4
|
* Manages category definitions with merged defaults and API-provided overrides.
|
|
5
5
|
* Exposes lookup helpers for icon, color, and label resolution.
|
|
6
6
|
*/
|
|
7
|
-
import { writable, derived, get } from 'svelte/store';
|
|
8
7
|
import { DEFAULT_CATEGORIES } from '../config/defaultCategories.js';
|
|
9
8
|
/**
|
|
10
|
-
* Internal
|
|
9
|
+
* Internal reactive state holding the category definitions.
|
|
11
10
|
* Initialized with defaults, updated when API data is fetched.
|
|
12
11
|
*/
|
|
13
|
-
|
|
12
|
+
let categoriesState = $state([...DEFAULT_CATEGORIES]);
|
|
14
13
|
/**
|
|
15
14
|
* Derived lookup map: category name → CategoryDefinition
|
|
16
15
|
*/
|
|
17
|
-
|
|
16
|
+
let categoryMap = $derived((() => {
|
|
18
17
|
const map = new Map();
|
|
19
|
-
for (const cat of
|
|
18
|
+
for (const cat of categoriesState) {
|
|
20
19
|
map.set(cat.name, cat);
|
|
21
20
|
}
|
|
22
21
|
return map;
|
|
23
|
-
});
|
|
22
|
+
})());
|
|
24
23
|
/**
|
|
25
|
-
*
|
|
24
|
+
* Get all category definitions, sorted by weight.
|
|
26
25
|
*/
|
|
27
|
-
export
|
|
26
|
+
export function getCategories() {
|
|
27
|
+
return [...categoriesState].sort((a, b) => (a.weight ?? 999) - (b.weight ?? 999));
|
|
28
|
+
}
|
|
28
29
|
/**
|
|
29
30
|
* Initialize categories with API data, merging with defaults.
|
|
30
31
|
* API categories override defaults by name; custom categories are appended.
|
|
@@ -41,14 +42,13 @@ export function initializeCategories(apiCategories) {
|
|
|
41
42
|
...cat
|
|
42
43
|
});
|
|
43
44
|
}
|
|
44
|
-
|
|
45
|
+
categoriesState = Array.from(defaultMap.values());
|
|
45
46
|
}
|
|
46
47
|
/**
|
|
47
48
|
* Get the display label for a category.
|
|
48
49
|
*/
|
|
49
50
|
export function getCategoryLabel(category) {
|
|
50
|
-
const
|
|
51
|
-
const def = map.get(category);
|
|
51
|
+
const def = categoryMap.get(category);
|
|
52
52
|
if (def?.label)
|
|
53
53
|
return def.label;
|
|
54
54
|
// Auto-generate: capitalize each word
|
|
@@ -61,20 +61,17 @@ export function getCategoryLabel(category) {
|
|
|
61
61
|
* Get the icon for a category.
|
|
62
62
|
*/
|
|
63
63
|
export function getCategoryIcon(category) {
|
|
64
|
-
|
|
65
|
-
return map.get(category)?.icon ?? 'mdi:folder';
|
|
64
|
+
return categoryMap.get(category)?.icon ?? 'mdi:folder';
|
|
66
65
|
}
|
|
67
66
|
/**
|
|
68
67
|
* Get the color token for a category.
|
|
69
68
|
*/
|
|
70
69
|
export function getCategoryColor(category) {
|
|
71
|
-
|
|
72
|
-
return map.get(category)?.color ?? 'var(--fd-node-slate)';
|
|
70
|
+
return categoryMap.get(category)?.color ?? 'var(--fd-node-slate)';
|
|
73
71
|
}
|
|
74
72
|
/**
|
|
75
73
|
* Get the full category definition, or undefined if not found.
|
|
76
74
|
*/
|
|
77
75
|
export function getCategoryDefinition(category) {
|
|
78
|
-
|
|
79
|
-
return map.get(category);
|
|
76
|
+
return categoryMap.get(category);
|
|
80
77
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Editor State Machine for WorkflowEditor (Svelte 5 Runes)
|
|
3
|
+
*
|
|
4
|
+
* Centralizes all reactive guard logic into explicit states and transitions.
|
|
5
|
+
* Replaces scattered boolean flags (isDraggingNode, isRestoringFromHistory,
|
|
6
|
+
* lastEditorStoreValue identity checks) with a single source of truth.
|
|
7
|
+
*
|
|
8
|
+
* @module stores/editorStateMachine
|
|
9
|
+
*/
|
|
10
|
+
export type EditorState = 'uninitialized' | 'loading' | 'idle' | 'dragging' | 'connecting' | 'dropping' | 'restoring' | 'deleting' | 'updating_node';
|
|
11
|
+
export type EditorEvent = 'WORKFLOW_LOADED' | 'LOAD_COMPLETE' | 'START_DRAG' | 'STOP_DRAG' | 'START_CONNECT' | 'CONNECTION_MADE' | 'CONNECTION_CANCELLED' | 'START_DROP' | 'DROP_COMPLETE' | 'DROP_CANCELLED' | 'START_RESTORE' | 'RESTORE_COMPLETE' | 'EXTERNAL_STORE_CHANGE' | 'SYNC_COMPLETE' | 'START_DELETE' | 'DELETE_COMPLETE' | 'START_NODE_UPDATE' | 'UPDATE_COMPLETE' | 'WORKFLOW_SWITCHED' | 'WORKFLOW_CLEARED' | 'RESET';
|
|
12
|
+
/** What operations are permitted in the current state */
|
|
13
|
+
export interface StatePermissions {
|
|
14
|
+
/** Whether the editor can write to the global workflow store */
|
|
15
|
+
canWriteToStore: boolean;
|
|
16
|
+
/** Whether the editor can push to undo/redo history */
|
|
17
|
+
canPushHistory: boolean;
|
|
18
|
+
/** Suppress the store → flowNodes/flowEdges sync effect */
|
|
19
|
+
suppressEffect: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface EditorStateMachine {
|
|
22
|
+
/** Current state (reactive via $state) */
|
|
23
|
+
readonly current: EditorState;
|
|
24
|
+
/** Current permissions (reactive, derived from current state) */
|
|
25
|
+
readonly permissions: StatePermissions;
|
|
26
|
+
/** Attempt a transition. Returns true if the transition was valid. */
|
|
27
|
+
send(event: EditorEvent): boolean;
|
|
28
|
+
/** Check if an event is valid from the current state */
|
|
29
|
+
canSend(event: EditorEvent): boolean;
|
|
30
|
+
/** Subscribe to state changes (for debugging/logging). Returns unsubscribe function. */
|
|
31
|
+
onTransition(callback: (from: EditorState, event: EditorEvent, to: EditorState) => void): () => void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Create an editor state machine instance.
|
|
35
|
+
*
|
|
36
|
+
* Uses Svelte 5 `$state` rune for reactivity so that components can
|
|
37
|
+
* read `machine.current` and `machine.permissions` inside `$derived`
|
|
38
|
+
* or `$effect` blocks and react to state changes.
|
|
39
|
+
*
|
|
40
|
+
* Each WorkflowEditor component instance should create its own machine.
|
|
41
|
+
*/
|
|
42
|
+
export declare function createEditorStateMachine(initialState?: EditorState): EditorStateMachine;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Editor State Machine for WorkflowEditor (Svelte 5 Runes)
|
|
3
|
+
*
|
|
4
|
+
* Centralizes all reactive guard logic into explicit states and transitions.
|
|
5
|
+
* Replaces scattered boolean flags (isDraggingNode, isRestoringFromHistory,
|
|
6
|
+
* lastEditorStoreValue identity checks) with a single source of truth.
|
|
7
|
+
*
|
|
8
|
+
* @module stores/editorStateMachine
|
|
9
|
+
*/
|
|
10
|
+
import { logger } from '../utils/logger.js';
|
|
11
|
+
const transitions = {
|
|
12
|
+
uninitialized: {
|
|
13
|
+
WORKFLOW_LOADED: 'loading'
|
|
14
|
+
},
|
|
15
|
+
loading: {
|
|
16
|
+
LOAD_COMPLETE: 'idle'
|
|
17
|
+
},
|
|
18
|
+
idle: {
|
|
19
|
+
START_DRAG: 'dragging',
|
|
20
|
+
START_CONNECT: 'connecting',
|
|
21
|
+
START_DROP: 'dropping',
|
|
22
|
+
START_RESTORE: 'restoring',
|
|
23
|
+
EXTERNAL_STORE_CHANGE: 'loading',
|
|
24
|
+
START_DELETE: 'deleting',
|
|
25
|
+
START_NODE_UPDATE: 'updating_node',
|
|
26
|
+
WORKFLOW_SWITCHED: 'loading',
|
|
27
|
+
WORKFLOW_CLEARED: 'uninitialized'
|
|
28
|
+
},
|
|
29
|
+
dragging: {
|
|
30
|
+
STOP_DRAG: 'idle'
|
|
31
|
+
},
|
|
32
|
+
connecting: {
|
|
33
|
+
CONNECTION_MADE: 'idle',
|
|
34
|
+
CONNECTION_CANCELLED: 'idle'
|
|
35
|
+
},
|
|
36
|
+
dropping: {
|
|
37
|
+
DROP_COMPLETE: 'idle',
|
|
38
|
+
DROP_CANCELLED: 'idle'
|
|
39
|
+
},
|
|
40
|
+
restoring: {
|
|
41
|
+
RESTORE_COMPLETE: 'idle'
|
|
42
|
+
},
|
|
43
|
+
deleting: {
|
|
44
|
+
DELETE_COMPLETE: 'idle'
|
|
45
|
+
},
|
|
46
|
+
updating_node: {
|
|
47
|
+
UPDATE_COMPLETE: 'idle'
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
/** Global transitions valid from any state */
|
|
51
|
+
const globalTransitions = {
|
|
52
|
+
RESET: 'uninitialized',
|
|
53
|
+
WORKFLOW_CLEARED: 'uninitialized'
|
|
54
|
+
};
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// Permissions table
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
const permissions = {
|
|
59
|
+
uninitialized: { canWriteToStore: false, canPushHistory: false, suppressEffect: false },
|
|
60
|
+
loading: { canWriteToStore: false, canPushHistory: false, suppressEffect: false },
|
|
61
|
+
idle: { canWriteToStore: true, canPushHistory: true, suppressEffect: false },
|
|
62
|
+
dragging: { canWriteToStore: true, canPushHistory: false, suppressEffect: true },
|
|
63
|
+
connecting: { canWriteToStore: true, canPushHistory: false, suppressEffect: true },
|
|
64
|
+
dropping: { canWriteToStore: true, canPushHistory: false, suppressEffect: true },
|
|
65
|
+
restoring: { canWriteToStore: true, canPushHistory: false, suppressEffect: true },
|
|
66
|
+
deleting: { canWriteToStore: true, canPushHistory: false, suppressEffect: true },
|
|
67
|
+
updating_node: { canWriteToStore: true, canPushHistory: false, suppressEffect: true }
|
|
68
|
+
};
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Factory
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
/**
|
|
73
|
+
* Create an editor state machine instance.
|
|
74
|
+
*
|
|
75
|
+
* Uses Svelte 5 `$state` rune for reactivity so that components can
|
|
76
|
+
* read `machine.current` and `machine.permissions` inside `$derived`
|
|
77
|
+
* or `$effect` blocks and react to state changes.
|
|
78
|
+
*
|
|
79
|
+
* Each WorkflowEditor component instance should create its own machine.
|
|
80
|
+
*/
|
|
81
|
+
export function createEditorStateMachine(initialState = 'uninitialized') {
|
|
82
|
+
let _current = $state(initialState);
|
|
83
|
+
let _permissions = $state(permissions[initialState]);
|
|
84
|
+
const _listeners = new Set();
|
|
85
|
+
function send(event) {
|
|
86
|
+
// Check global transitions first (valid from any state)
|
|
87
|
+
const globalTarget = globalTransitions[event];
|
|
88
|
+
if (globalTarget !== undefined) {
|
|
89
|
+
const from = _current;
|
|
90
|
+
_current = globalTarget;
|
|
91
|
+
_permissions = permissions[globalTarget];
|
|
92
|
+
for (const cb of _listeners)
|
|
93
|
+
cb(from, event, globalTarget);
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
// Check state-specific transitions
|
|
97
|
+
const stateTransitions = transitions[_current];
|
|
98
|
+
const target = stateTransitions?.[event];
|
|
99
|
+
if (target === undefined) {
|
|
100
|
+
logger.warn(`[EditorFSM] Invalid transition: ${_current} + ${event}`);
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
const from = _current;
|
|
104
|
+
_current = target;
|
|
105
|
+
_permissions = permissions[target];
|
|
106
|
+
for (const cb of _listeners)
|
|
107
|
+
cb(from, event, target);
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
function canSend(event) {
|
|
111
|
+
if (globalTransitions[event] !== undefined)
|
|
112
|
+
return true;
|
|
113
|
+
return transitions[_current]?.[event] !== undefined;
|
|
114
|
+
}
|
|
115
|
+
function onTransition(callback) {
|
|
116
|
+
_listeners.add(callback);
|
|
117
|
+
return () => {
|
|
118
|
+
_listeners.delete(callback);
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
get current() {
|
|
123
|
+
return _current;
|
|
124
|
+
},
|
|
125
|
+
get permissions() {
|
|
126
|
+
return _permissions;
|
|
127
|
+
},
|
|
128
|
+
send,
|
|
129
|
+
canSend,
|
|
130
|
+
onTransition
|
|
131
|
+
};
|
|
132
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* History Store for FlowDrop
|
|
2
|
+
* History Store for FlowDrop (Svelte 5 Runes)
|
|
3
3
|
*
|
|
4
|
-
* Provides reactive Svelte
|
|
4
|
+
* Provides reactive Svelte 5 rune-based bindings for the history service.
|
|
5
5
|
* Exposes undo/redo state and actions for the workflow editor.
|
|
6
6
|
*
|
|
7
7
|
* @module stores/historyStore
|
|
@@ -9,39 +9,42 @@
|
|
|
9
9
|
import { type HistoryState, type PushOptions } from '../services/historyService.js';
|
|
10
10
|
import type { Workflow } from '../types/index.js';
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Clean up the historyService subscription created at module initialisation.
|
|
13
|
+
* Call this when tearing down the history store (e.g., in tests or on app
|
|
14
|
+
* unmount) to prevent memory leaks.
|
|
13
15
|
*/
|
|
14
|
-
declare
|
|
16
|
+
export declare function cleanupHistorySubscription(): void;
|
|
15
17
|
/**
|
|
16
|
-
*
|
|
18
|
+
* Get the current history state snapshot.
|
|
17
19
|
*
|
|
18
20
|
* Use this for binding to UI elements like undo/redo buttons.
|
|
19
|
-
* Subscribe using Svelte's $ prefix or the subscribe method.
|
|
20
21
|
*
|
|
21
22
|
* @example
|
|
22
23
|
* ```svelte
|
|
23
24
|
* <script>
|
|
24
|
-
* import {
|
|
25
|
+
* import { getHistoryState } from "./historyStore.svelte.js";
|
|
26
|
+
*
|
|
27
|
+
* const state = $derived(getHistoryState());
|
|
25
28
|
* </script>
|
|
26
29
|
*
|
|
27
|
-
* <button disabled={
|
|
30
|
+
* <button disabled={!state.canUndo} onclick={historyActions.undo}>
|
|
28
31
|
* Undo
|
|
29
32
|
* </button>
|
|
30
33
|
* ```
|
|
31
34
|
*/
|
|
32
|
-
export
|
|
35
|
+
export declare function getHistoryState(): HistoryState;
|
|
33
36
|
/**
|
|
34
|
-
*
|
|
37
|
+
* Convenience getter for canUndo state.
|
|
35
38
|
*
|
|
36
|
-
*
|
|
39
|
+
* @returns Whether undo is currently available
|
|
37
40
|
*/
|
|
38
|
-
export declare
|
|
41
|
+
export declare function getCanUndo(): boolean;
|
|
39
42
|
/**
|
|
40
|
-
*
|
|
43
|
+
* Convenience getter for canRedo state.
|
|
41
44
|
*
|
|
42
|
-
*
|
|
45
|
+
* @returns Whether redo is currently available
|
|
43
46
|
*/
|
|
44
|
-
export declare
|
|
47
|
+
export declare function getCanRedo(): boolean;
|
|
45
48
|
/**
|
|
46
49
|
* Set the callback for restoring workflow state
|
|
47
50
|
*
|
|
@@ -1,60 +1,79 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* History Store for FlowDrop
|
|
2
|
+
* History Store for FlowDrop (Svelte 5 Runes)
|
|
3
3
|
*
|
|
4
|
-
* Provides reactive Svelte
|
|
4
|
+
* Provides reactive Svelte 5 rune-based bindings for the history service.
|
|
5
5
|
* Exposes undo/redo state and actions for the workflow editor.
|
|
6
6
|
*
|
|
7
7
|
* @module stores/historyStore
|
|
8
8
|
*/
|
|
9
|
-
import { writable, derived, get } from 'svelte/store';
|
|
10
9
|
import { historyService } from '../services/historyService.js';
|
|
11
10
|
// =========================================================================
|
|
12
|
-
// Reactive State
|
|
11
|
+
// Reactive State (Runes)
|
|
13
12
|
// =========================================================================
|
|
14
13
|
/**
|
|
15
|
-
* Internal
|
|
14
|
+
* Internal reactive state for history, powered by $state.
|
|
16
15
|
*/
|
|
17
|
-
|
|
16
|
+
let historyState = $state({
|
|
18
17
|
canUndo: false,
|
|
19
18
|
canRedo: false,
|
|
20
19
|
currentIndex: 0,
|
|
21
20
|
historyLength: 0,
|
|
22
21
|
isInTransaction: false
|
|
23
22
|
});
|
|
24
|
-
// Subscribe to history service changes and update the
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
// Subscribe to history service changes and update the rune state.
|
|
24
|
+
// The unsubscribe function is stored so it can be called via
|
|
25
|
+
// cleanupHistorySubscription() when the store is torn down.
|
|
26
|
+
const _unsubscribeHistoryService = historyService.subscribe((state) => {
|
|
27
|
+
historyState = state;
|
|
27
28
|
});
|
|
28
29
|
/**
|
|
29
|
-
*
|
|
30
|
+
* Clean up the historyService subscription created at module initialisation.
|
|
31
|
+
* Call this when tearing down the history store (e.g., in tests or on app
|
|
32
|
+
* unmount) to prevent memory leaks.
|
|
33
|
+
*/
|
|
34
|
+
export function cleanupHistorySubscription() {
|
|
35
|
+
_unsubscribeHistoryService();
|
|
36
|
+
}
|
|
37
|
+
// =========================================================================
|
|
38
|
+
// Reactive Getters
|
|
39
|
+
// =========================================================================
|
|
40
|
+
/**
|
|
41
|
+
* Get the current history state snapshot.
|
|
30
42
|
*
|
|
31
43
|
* Use this for binding to UI elements like undo/redo buttons.
|
|
32
|
-
* Subscribe using Svelte's $ prefix or the subscribe method.
|
|
33
44
|
*
|
|
34
45
|
* @example
|
|
35
46
|
* ```svelte
|
|
36
47
|
* <script>
|
|
37
|
-
* import {
|
|
48
|
+
* import { getHistoryState } from "./historyStore.svelte.js";
|
|
49
|
+
*
|
|
50
|
+
* const state = $derived(getHistoryState());
|
|
38
51
|
* </script>
|
|
39
52
|
*
|
|
40
|
-
* <button disabled={
|
|
53
|
+
* <button disabled={!state.canUndo} onclick={historyActions.undo}>
|
|
41
54
|
* Undo
|
|
42
55
|
* </button>
|
|
43
56
|
* ```
|
|
44
57
|
*/
|
|
45
|
-
export
|
|
58
|
+
export function getHistoryState() {
|
|
59
|
+
return historyState;
|
|
60
|
+
}
|
|
46
61
|
/**
|
|
47
|
-
*
|
|
62
|
+
* Convenience getter for canUndo state.
|
|
48
63
|
*
|
|
49
|
-
*
|
|
64
|
+
* @returns Whether undo is currently available
|
|
50
65
|
*/
|
|
51
|
-
export
|
|
66
|
+
export function getCanUndo() {
|
|
67
|
+
return historyState.canUndo;
|
|
68
|
+
}
|
|
52
69
|
/**
|
|
53
|
-
*
|
|
70
|
+
* Convenience getter for canRedo state.
|
|
54
71
|
*
|
|
55
|
-
*
|
|
72
|
+
* @returns Whether redo is currently available
|
|
56
73
|
*/
|
|
57
|
-
export
|
|
74
|
+
export function getCanRedo() {
|
|
75
|
+
return historyState.canRedo;
|
|
76
|
+
}
|
|
58
77
|
// =========================================================================
|
|
59
78
|
// History Actions
|
|
60
79
|
// =========================================================================
|
|
@@ -182,7 +201,7 @@ export const historyActions = {
|
|
|
182
201
|
* @returns The current history state
|
|
183
202
|
*/
|
|
184
203
|
getState: () => {
|
|
185
|
-
return
|
|
204
|
+
return historyState;
|
|
186
205
|
}
|
|
187
206
|
};
|
|
188
207
|
export { HistoryService, historyService } from '../services/historyService.js';
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Interrupt Store
|
|
2
|
+
* Interrupt Store (Svelte 5 Runes)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Rune-based reactive state for managing interrupt state using a lightweight state machine.
|
|
5
5
|
* Ensures valid state transitions and prevents deadlocks.
|
|
6
6
|
*
|
|
7
7
|
* @module stores/interruptStore
|
|
8
8
|
*/
|
|
9
|
+
import { SvelteMap } from 'svelte/reactivity';
|
|
9
10
|
import type { Interrupt } from '../types/interrupt.js';
|
|
10
11
|
import { type InterruptState, type TransitionResult } from '../types/interruptState.js';
|
|
11
12
|
/**
|
|
@@ -16,30 +17,30 @@ export interface InterruptWithState extends Interrupt {
|
|
|
16
17
|
machineState: InterruptState;
|
|
17
18
|
}
|
|
18
19
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
20
|
+
* Get the reactive interrupts map.
|
|
21
|
+
* Use this in components within $derived() for reactivity.
|
|
21
22
|
*/
|
|
22
|
-
export declare
|
|
23
|
+
export declare function getInterruptsMap(): SvelteMap<string, InterruptWithState>;
|
|
23
24
|
/**
|
|
24
|
-
*
|
|
25
|
+
* Get pending interrupt IDs (interrupts not in a terminal state)
|
|
25
26
|
*/
|
|
26
|
-
export declare
|
|
27
|
+
export declare function getPendingInterruptIds(): string[];
|
|
27
28
|
/**
|
|
28
|
-
*
|
|
29
|
+
* Get pending interrupts array (interrupts not in a terminal state)
|
|
29
30
|
*/
|
|
30
|
-
export declare
|
|
31
|
+
export declare function getPendingInterrupts(): InterruptWithState[];
|
|
31
32
|
/**
|
|
32
|
-
*
|
|
33
|
+
* Get count of pending interrupts
|
|
33
34
|
*/
|
|
34
|
-
export declare
|
|
35
|
+
export declare function getPendingInterruptCount(): number;
|
|
35
36
|
/**
|
|
36
|
-
*
|
|
37
|
+
* Get resolved interrupts array
|
|
37
38
|
*/
|
|
38
|
-
export declare
|
|
39
|
+
export declare function getResolvedInterrupts(): InterruptWithState[];
|
|
39
40
|
/**
|
|
40
|
-
*
|
|
41
|
+
* Check if any interrupt is currently submitting
|
|
41
42
|
*/
|
|
42
|
-
export declare
|
|
43
|
+
export declare function getIsAnySubmitting(): boolean;
|
|
43
44
|
/**
|
|
44
45
|
* Interrupt store actions for modifying state
|
|
45
46
|
*/
|