@flowdrop/flowdrop 1.14.0 → 2.0.0-beta.1
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/CHANGELOG.md +475 -0
- package/MIGRATION-2.0.md +472 -0
- package/README.md +23 -23
- package/dist/adapters/WorkflowAdapter.d.ts +1 -1
- package/dist/adapters/WorkflowAdapter.js +14 -8
- package/dist/adapters/agentspec/AgentSpecAdapter.js +7 -7
- package/dist/chat/batchFeedback.d.ts +39 -0
- package/dist/chat/batchFeedback.js +51 -0
- package/dist/commands/executor.js +15 -1
- package/dist/commands/storeIntegration.svelte.d.ts +4 -1
- package/dist/commands/storeIntegration.svelte.js +26 -21
- package/dist/commands/types.d.ts +2 -0
- package/dist/components/App.svelte +162 -192
- package/dist/components/App.svelte.d.ts +47 -8
- package/dist/components/ConfigForm.svelte +110 -66
- package/dist/components/ConfigModal.svelte +7 -2
- package/dist/components/ConnectionLine.svelte +4 -2
- package/dist/components/Navbar.svelte +61 -1
- package/dist/components/NodeSidebar.svelte +27 -45
- package/dist/components/NodeStatusOverlay.svelte +94 -6
- package/dist/components/NodeSwapPicker.svelte +10 -8
- package/dist/components/PipelineStatus.svelte +16 -67
- package/dist/components/PortCoordinateTracker.svelte +5 -6
- package/dist/components/SchemaForm.stories.svelte +1 -3
- package/dist/components/SchemaForm.svelte +45 -40
- package/dist/components/SchemaForm.svelte.d.ts +0 -8
- package/dist/components/SettingsModal.svelte +8 -3
- package/dist/components/SettingsPanel.svelte +20 -4
- package/dist/components/SwapMappingEditor.svelte +67 -49
- package/dist/components/SwapMappingEditor.svelte.d.ts +0 -2
- package/dist/components/UniversalNode.svelte +9 -7
- package/dist/components/WorkflowEditor.svelte +118 -111
- package/dist/components/WorkflowEditor.svelte.d.ts +18 -10
- package/dist/components/chat/AIChatPanel.svelte +93 -89
- package/dist/components/chat/AIChatPanel.svelte.d.ts +0 -4
- package/dist/components/chat/CommandPreview.svelte +2 -1
- package/dist/components/console/CommandConsole.svelte +7 -5
- package/dist/components/console/ConsoleAutocomplete.svelte +10 -11
- package/dist/components/console/ConsoleAutocomplete.svelte.d.ts +6 -0
- package/dist/components/console/ConsoleInput.svelte +15 -6
- package/dist/components/console/ConsoleOutput.svelte +2 -1
- package/dist/components/form/FormArray.svelte +5 -9
- package/dist/components/form/FormArray.svelte.d.ts +2 -1
- package/dist/components/form/FormAutocomplete.svelte +29 -13
- package/dist/components/form/FormField.svelte +4 -2
- package/dist/components/form/FormFieldLight.svelte +4 -2
- package/dist/components/form/FormMarkdownEditor.svelte +9 -4
- package/dist/components/form/FormRangeField.svelte +1 -0
- package/dist/components/form/FormTemplateEditor.svelte +11 -3
- package/dist/components/form/FormToggle.svelte +5 -12
- package/dist/components/form/FormToggle.svelte.d.ts +4 -2
- package/dist/components/form/templateAutocomplete.js +1 -5
- package/dist/components/form/types.d.ts +1 -14
- package/dist/components/interrupt/FormPrompt.svelte +3 -2
- package/dist/components/interrupt/InterruptBubble.svelte +16 -17
- package/dist/components/interrupt/ReviewPrompt.svelte +10 -3
- package/dist/components/interrupt/TextInputPrompt.svelte +2 -1
- package/dist/components/layouts/MainLayout.svelte +20 -13
- package/dist/components/layouts/MainLayout.svelte.d.ts +4 -0
- package/dist/components/nodes/AtomNode.svelte +292 -0
- package/dist/components/nodes/AtomNode.svelte.d.ts +26 -0
- package/dist/components/nodes/GatewayNode.svelte +19 -10
- package/dist/components/nodes/IdeaNode.svelte +7 -0
- package/dist/components/nodes/SimpleNode.svelte +11 -6
- package/dist/components/nodes/SquareNode.svelte +15 -8
- package/dist/components/nodes/TerminalNode.svelte +9 -4
- package/dist/components/nodes/ToolNode.svelte +7 -1
- package/dist/components/nodes/WorkflowNode.svelte +16 -7
- package/dist/components/playground/ChatInput.svelte +11 -14
- package/dist/components/playground/ChatPanel.svelte +6 -49
- package/dist/components/playground/ChatPanel.svelte.d.ts +0 -14
- package/dist/components/playground/ControlPanel.svelte +134 -123
- package/dist/components/playground/ControlPanel.svelte.d.ts +3 -0
- package/dist/components/playground/ExecutionLogs.svelte +11 -9
- package/dist/components/playground/InputCollector.svelte +11 -9
- package/dist/components/playground/MessageStream.svelte +17 -23
- package/dist/components/playground/PipelineKanbanView.svelte +65 -6
- package/dist/components/playground/PipelinePanel.svelte +11 -5
- package/dist/components/playground/PipelineTableView.svelte +186 -44
- package/dist/components/playground/Playground.svelte +95 -92
- package/dist/components/playground/Playground.svelte.d.ts +2 -0
- package/dist/components/playground/PlaygroundApp.svelte +6 -1
- package/dist/components/playground/PlaygroundApp.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundModal.svelte +13 -3
- package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundStudio.svelte +34 -32
- package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -0
- package/dist/components/playground/SessionManager.svelte +9 -12
- package/dist/components/playground/pipelineViewUtils.svelte.d.ts +28 -0
- package/dist/components/playground/pipelineViewUtils.svelte.js +38 -1
- package/dist/config/endpoints.d.ts +0 -7
- package/dist/config/endpoints.js +2 -10
- package/dist/core/index.d.ts +4 -4
- package/dist/core/index.js +6 -6
- package/dist/display/index.d.ts +0 -2
- package/dist/display/index.js +0 -6
- package/dist/editor/index.d.ts +19 -20
- package/dist/editor/index.js +25 -35
- package/dist/form/code.d.ts +25 -15
- package/dist/form/code.js +44 -41
- package/dist/form/fieldRegistry.d.ts +17 -13
- package/dist/form/fieldRegistry.js +32 -12
- package/dist/form/full.d.ts +17 -13
- package/dist/form/full.js +22 -27
- package/dist/form/index.d.ts +3 -3
- package/dist/form/index.js +3 -3
- package/dist/form/markdown.d.ts +13 -8
- package/dist/form/markdown.js +22 -23
- package/dist/helpers/proximityConnect.d.ts +7 -3
- package/dist/helpers/proximityConnect.js +19 -6
- package/dist/helpers/workflowEditorHelper.d.ts +12 -5
- package/dist/helpers/workflowEditorHelper.js +27 -25
- package/dist/index.d.ts +28 -24
- package/dist/index.js +27 -50
- package/dist/messages/defaults.d.ts +2 -5
- package/dist/messages/defaults.js +3 -6
- package/dist/messages/index.d.ts +0 -1
- package/dist/messages/index.js +0 -1
- package/dist/mocks/app-forms.d.ts +6 -2
- package/dist/mocks/app-forms.js +11 -4
- package/dist/openapi/v1/openapi.yaml +227 -164
- package/dist/playground/index.d.ts +2 -3
- package/dist/playground/index.js +2 -30
- package/dist/playground/mount.d.ts +15 -0
- package/dist/playground/mount.js +46 -20
- package/dist/registry/{BaseRegistry.d.ts → BaseRegistry.svelte.d.ts} +22 -1
- package/dist/registry/{BaseRegistry.js → BaseRegistry.svelte.js} +37 -1
- package/dist/registry/builtinFormats.d.ts +9 -18
- package/dist/registry/builtinFormats.js +9 -39
- package/dist/registry/builtinNodes.d.ts +1 -26
- package/dist/registry/builtinNodes.js +14 -50
- package/dist/registry/index.d.ts +3 -4
- package/dist/registry/index.js +4 -6
- package/dist/registry/nodeComponentRegistry.d.ts +182 -15
- package/dist/registry/nodeComponentRegistry.js +235 -17
- package/dist/registry/workflowFormatRegistry.d.ts +14 -9
- package/dist/registry/workflowFormatRegistry.js +24 -8
- package/dist/{schema → schemas}/index.d.ts +2 -2
- package/dist/{schema → schemas}/index.js +2 -2
- package/dist/schemas/v1/workflow.schema.json +53 -6
- package/dist/services/agentSpecExecutionService.js +0 -1
- package/dist/services/apiVariableService.d.ts +2 -1
- package/dist/services/apiVariableService.js +5 -22
- package/dist/services/autoSaveService.d.ts +7 -0
- package/dist/services/autoSaveService.js +6 -4
- package/dist/services/chatService.d.ts +8 -4
- package/dist/services/chatService.js +15 -15
- package/dist/services/draftStorage.d.ts +129 -13
- package/dist/services/draftStorage.js +185 -37
- package/dist/services/dynamicSchemaService.d.ts +2 -1
- package/dist/services/dynamicSchemaService.js +5 -22
- package/dist/services/globalSave.d.ts +13 -12
- package/dist/services/globalSave.js +29 -51
- package/dist/services/historyService.d.ts +9 -3
- package/dist/services/historyService.js +9 -3
- package/dist/services/interruptService.d.ts +14 -9
- package/dist/services/interruptService.js +27 -27
- package/dist/services/nodeExecutionService.d.ts +18 -3
- package/dist/services/nodeExecutionService.js +71 -45
- package/dist/services/playgroundService.d.ts +14 -9
- package/dist/services/playgroundService.js +31 -30
- package/dist/services/variableService.d.ts +2 -1
- package/dist/services/variableService.js +2 -2
- package/dist/services/workflowStorage.js +6 -6
- package/dist/stores/apiContext.d.ts +45 -0
- package/dist/stores/apiContext.js +65 -0
- package/dist/stores/categoriesStore.svelte.d.ts +28 -23
- package/dist/stores/categoriesStore.svelte.js +70 -64
- package/dist/stores/getInstance.svelte.d.ts +39 -0
- package/dist/stores/getInstance.svelte.js +65 -0
- package/dist/stores/historyStore.svelte.d.ts +77 -93
- package/dist/stores/historyStore.svelte.js +134 -160
- package/dist/stores/instanceContainer.svelte.d.ts +111 -0
- package/dist/stores/instanceContainer.svelte.js +114 -0
- package/dist/stores/interruptStore.svelte.d.ts +112 -82
- package/dist/stores/interruptStore.svelte.js +253 -226
- package/dist/stores/pipelinePanelStore.svelte.d.ts +27 -3
- package/dist/stores/pipelinePanelStore.svelte.js +61 -14
- package/dist/stores/playgroundStore.svelte.d.ts +169 -216
- package/dist/stores/playgroundStore.svelte.js +515 -572
- package/dist/stores/portCoordinateStore.svelte.d.ts +57 -51
- package/dist/stores/portCoordinateStore.svelte.js +109 -98
- package/dist/stores/settingsStore.svelte.d.ts +4 -1
- package/dist/stores/settingsStore.svelte.js +47 -12
- package/dist/stores/workflowStore.svelte.d.ts +178 -213
- package/dist/stores/workflowStore.svelte.js +449 -501
- package/dist/stories/EdgeDecorator.svelte +5 -2
- package/dist/stories/NodeDecorator.svelte +5 -3
- package/dist/svelte-app.d.ts +60 -10
- package/dist/svelte-app.js +157 -53
- package/dist/types/events.d.ts +6 -3
- package/dist/types/index.d.ts +71 -6
- package/dist/types/navbar.d.ts +7 -0
- package/dist/types/playground.d.ts +18 -3
- package/dist/types/settings.d.ts +13 -0
- package/dist/types/settings.js +1 -0
- package/dist/utils/colors.d.ts +47 -21
- package/dist/utils/colors.js +69 -68
- package/dist/utils/connections.d.ts +9 -15
- package/dist/utils/connections.js +13 -32
- package/dist/utils/duration.d.ts +13 -0
- package/dist/utils/duration.js +45 -0
- package/dist/utils/formMerge.d.ts +36 -0
- package/dist/utils/formMerge.js +70 -0
- package/dist/utils/icons.d.ts +5 -2
- package/dist/utils/icons.js +6 -5
- package/dist/utils/nodeSwap.d.ts +6 -2
- package/dist/utils/nodeSwap.js +62 -126
- package/dist/utils/nodeTypes.d.ts +17 -8
- package/dist/utils/nodeTypes.js +27 -19
- package/dist/utils/performanceUtils.js +7 -0
- package/package.json +6 -5
- package/dist/messages/deprecation.d.ts +0 -20
- package/dist/messages/deprecation.js +0 -33
- package/dist/registry/plugin.d.ts +0 -215
- package/dist/registry/plugin.js +0 -249
- package/dist/services/api.d.ts +0 -129
- package/dist/services/api.js +0 -217
|
@@ -11,60 +11,66 @@
|
|
|
11
11
|
* Coordinates are derived from SvelteFlow's InternalNode.internals.handleBounds
|
|
12
12
|
* which SvelteFlow already maintains for all node types. This avoids replicating
|
|
13
13
|
* CSS positioning logic and stays automatically accurate.
|
|
14
|
-
*/
|
|
15
|
-
import type { WorkflowNode as WorkflowNodeType, PortCoordinate, PortCoordinateMap } from '../types/index.js';
|
|
16
|
-
import type { InternalNode } from '@xyflow/svelte';
|
|
17
|
-
/**
|
|
18
|
-
* Rebuild coordinates for ALL nodes from SvelteFlow internals.
|
|
19
|
-
* Call on initial workflow load (after render) and after bulk changes.
|
|
20
|
-
*
|
|
21
|
-
* @param nodes - All workflow nodes
|
|
22
|
-
* @param getInternalNode - SvelteFlow's getInternalNode function
|
|
23
|
-
*/
|
|
24
|
-
export declare function rebuildAllPortCoordinates(nodes: WorkflowNodeType[], getInternalNode: (id: string) => InternalNode | undefined): void;
|
|
25
|
-
/**
|
|
26
|
-
* Update coordinates for a single node (efficient for drag updates).
|
|
27
|
-
* Only recomputes ports for the specified node.
|
|
28
|
-
*
|
|
29
|
-
* @param node - The workflow node to update
|
|
30
|
-
* @param getInternalNode - SvelteFlow's getInternalNode function
|
|
31
|
-
*/
|
|
32
|
-
export declare function updateNodePortCoordinates(node: WorkflowNodeType, getInternalNode: (id: string) => InternalNode | undefined): void;
|
|
33
|
-
/**
|
|
34
|
-
* Remove all coordinates for a node (on node delete).
|
|
35
|
-
*
|
|
36
|
-
* @param nodeId - ID of the node to remove
|
|
37
|
-
*/
|
|
38
|
-
export declare function removeNodePortCoordinates(nodeId: string): void;
|
|
39
|
-
/**
|
|
40
|
-
* Clear all port coordinates (lifecycle cleanup).
|
|
41
|
-
*/
|
|
42
|
-
export declare function clearPortCoordinates(): void;
|
|
43
|
-
/**
|
|
44
|
-
* Get coordinates for a specific handle.
|
|
45
14
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*/
|
|
49
|
-
export declare function getPortCoordinate(handleId: string): PortCoordinate | undefined;
|
|
50
|
-
/**
|
|
51
|
-
* Get all coordinates for a specific node.
|
|
15
|
+
* The reactive state lives in the {@link PortCoordinateStore} class — one per
|
|
16
|
+
* FlowDrop instance, resolved in components via `getInstance().portCoordinates`.
|
|
52
17
|
*
|
|
53
|
-
* @
|
|
54
|
-
* @returns Array of port coordinates for the node
|
|
18
|
+
* @module stores/portCoordinateStore
|
|
55
19
|
*/
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
* Get the current snapshot of all port coordinates.
|
|
59
|
-
* Returns the reactive SvelteMap directly.
|
|
60
|
-
*
|
|
61
|
-
* @returns Current port coordinate map
|
|
62
|
-
*/
|
|
63
|
-
export declare function getPortCoordinateSnapshot(): PortCoordinateMap;
|
|
20
|
+
import type { WorkflowNode as WorkflowNodeType, PortCoordinate, PortCoordinateMap } from '../types/index.js';
|
|
21
|
+
import type { InternalNode } from '@xyflow/svelte';
|
|
64
22
|
/**
|
|
65
|
-
*
|
|
66
|
-
* Useful for components that need to reactively read the coordinates.
|
|
23
|
+
* Per-instance absolute port coordinates, keyed by handleId.
|
|
67
24
|
*
|
|
68
|
-
*
|
|
25
|
+
* A single SvelteMap mutated in place: per-key reads (getPortCoordinate)
|
|
26
|
+
* only react to the keys they touch, and Svelte coalesces synchronous
|
|
27
|
+
* mutations into one flush, so bulk updates stay cheap.
|
|
69
28
|
*/
|
|
70
|
-
export declare
|
|
29
|
+
export declare class PortCoordinateStore {
|
|
30
|
+
#private;
|
|
31
|
+
/**
|
|
32
|
+
* Rebuild coordinates for ALL nodes from SvelteFlow internals.
|
|
33
|
+
* Call on initial workflow load (after render) and after bulk changes.
|
|
34
|
+
*
|
|
35
|
+
* @param nodes - All workflow nodes
|
|
36
|
+
* @param getInternalNode - SvelteFlow's getInternalNode function
|
|
37
|
+
*/
|
|
38
|
+
rebuildAll(nodes: WorkflowNodeType[], getInternalNode: (id: string) => InternalNode | undefined): void;
|
|
39
|
+
/**
|
|
40
|
+
* Update coordinates for a single node (efficient for drag updates).
|
|
41
|
+
* Only recomputes ports for the specified node.
|
|
42
|
+
*
|
|
43
|
+
* @param node - The workflow node to update
|
|
44
|
+
* @param getInternalNode - SvelteFlow's getInternalNode function
|
|
45
|
+
*/
|
|
46
|
+
updateNode(node: WorkflowNodeType, getInternalNode: (id: string) => InternalNode | undefined): void;
|
|
47
|
+
/**
|
|
48
|
+
* Remove all coordinates for a node (on node delete).
|
|
49
|
+
*
|
|
50
|
+
* @param nodeId - ID of the node to remove
|
|
51
|
+
*/
|
|
52
|
+
removeNode(nodeId: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Clear all port coordinates (lifecycle cleanup).
|
|
55
|
+
*/
|
|
56
|
+
clear(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Get coordinates for a specific handle.
|
|
59
|
+
*
|
|
60
|
+
* @param handleId - The handle ID to look up
|
|
61
|
+
* @returns The port coordinate or undefined if not found
|
|
62
|
+
*/
|
|
63
|
+
get(handleId: string): PortCoordinate | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Get all coordinates for a specific node.
|
|
66
|
+
*
|
|
67
|
+
* @param nodeId - The node ID to look up
|
|
68
|
+
* @returns Array of port coordinates for the node
|
|
69
|
+
*/
|
|
70
|
+
getForNode(nodeId: string): PortCoordinate[];
|
|
71
|
+
/**
|
|
72
|
+
* The reactive port coordinate map.
|
|
73
|
+
* Returns the reactive SvelteMap directly.
|
|
74
|
+
*/
|
|
75
|
+
get coordinates(): PortCoordinateMap;
|
|
76
|
+
}
|
|
@@ -11,12 +11,15 @@
|
|
|
11
11
|
* Coordinates are derived from SvelteFlow's InternalNode.internals.handleBounds
|
|
12
12
|
* which SvelteFlow already maintains for all node types. This avoids replicating
|
|
13
13
|
* CSS positioning logic and stays automatically accurate.
|
|
14
|
+
*
|
|
15
|
+
* The reactive state lives in the {@link PortCoordinateStore} class — one per
|
|
16
|
+
* FlowDrop instance, resolved in components via `getInstance().portCoordinates`.
|
|
17
|
+
*
|
|
18
|
+
* @module stores/portCoordinateStore
|
|
14
19
|
*/
|
|
15
20
|
import { SvelteMap } from 'svelte/reactivity';
|
|
16
21
|
import { untrack } from 'svelte';
|
|
17
22
|
import { ProximityConnectHelper } from '../helpers/proximityConnect.js';
|
|
18
|
-
/** Reactive state holding all port absolute coordinates, keyed by handleId */
|
|
19
|
-
let coordinates = $state(new SvelteMap());
|
|
20
23
|
/**
|
|
21
24
|
* Parse a handle ID to extract nodeId, direction, and portId.
|
|
22
25
|
* Handle ID format: ${nodeId}-${direction}-${portId}
|
|
@@ -92,111 +95,119 @@ function computeNodePortCoordinates(node, internalNode) {
|
|
|
92
95
|
}
|
|
93
96
|
return result;
|
|
94
97
|
}
|
|
98
|
+
// =========================================================================
|
|
99
|
+
// PortCoordinateStore (per-instance reactive state)
|
|
100
|
+
// =========================================================================
|
|
95
101
|
/**
|
|
96
|
-
*
|
|
97
|
-
* Call on initial workflow load (after render) and after bulk changes.
|
|
102
|
+
* Per-instance absolute port coordinates, keyed by handleId.
|
|
98
103
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
104
|
+
* A single SvelteMap mutated in place: per-key reads (getPortCoordinate)
|
|
105
|
+
* only react to the keys they touch, and Svelte coalesces synchronous
|
|
106
|
+
* mutations into one flush, so bulk updates stay cheap.
|
|
101
107
|
*/
|
|
102
|
-
export
|
|
103
|
-
|
|
104
|
-
|
|
108
|
+
export class PortCoordinateStore {
|
|
109
|
+
/**
|
|
110
|
+
* Reactive state holding all port absolute coordinates, keyed by handleId.
|
|
111
|
+
*/
|
|
112
|
+
#coordinates = new SvelteMap();
|
|
113
|
+
/**
|
|
114
|
+
* Rebuild coordinates for ALL nodes from SvelteFlow internals.
|
|
115
|
+
* Call on initial workflow load (after render) and after bulk changes.
|
|
116
|
+
*
|
|
117
|
+
* @param nodes - All workflow nodes
|
|
118
|
+
* @param getInternalNode - SvelteFlow's getInternalNode function
|
|
119
|
+
*/
|
|
120
|
+
rebuildAll(nodes, getInternalNode) {
|
|
121
|
+
this.#coordinates.clear();
|
|
122
|
+
for (const node of nodes) {
|
|
123
|
+
const internalNode = getInternalNode(node.id);
|
|
124
|
+
if (!internalNode)
|
|
125
|
+
continue;
|
|
126
|
+
const coords = computeNodePortCoordinates(node, internalNode);
|
|
127
|
+
for (const coord of coords) {
|
|
128
|
+
this.#coordinates.set(coord.handleId, coord);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Update coordinates for a single node (efficient for drag updates).
|
|
134
|
+
* Only recomputes ports for the specified node.
|
|
135
|
+
*
|
|
136
|
+
* @param node - The workflow node to update
|
|
137
|
+
* @param getInternalNode - SvelteFlow's getInternalNode function
|
|
138
|
+
*/
|
|
139
|
+
updateNode(node, getInternalNode) {
|
|
105
140
|
const internalNode = getInternalNode(node.id);
|
|
106
141
|
if (!internalNode)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
142
|
+
return;
|
|
143
|
+
// Collect this node's stale keys without tracking the read (callers run
|
|
144
|
+
// inside $effect), then mutate in place — only the touched keys notify.
|
|
145
|
+
const stale = [];
|
|
146
|
+
untrack(() => {
|
|
147
|
+
for (const [key, coord] of this.#coordinates) {
|
|
148
|
+
if (coord.nodeId === node.id)
|
|
149
|
+
stale.push(key);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
for (const key of stale) {
|
|
153
|
+
this.#coordinates.delete(key);
|
|
111
154
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Update coordinates for a single node (efficient for drag updates).
|
|
117
|
-
* Only recomputes ports for the specified node.
|
|
118
|
-
*
|
|
119
|
-
* @param node - The workflow node to update
|
|
120
|
-
* @param getInternalNode - SvelteFlow's getInternalNode function
|
|
121
|
-
*/
|
|
122
|
-
export function updateNodePortCoordinates(node, getInternalNode) {
|
|
123
|
-
const internalNode = getInternalNode(node.id);
|
|
124
|
-
if (!internalNode)
|
|
125
|
-
return;
|
|
126
|
-
// Build a new map with all entries except this node's, then add recomputed entries.
|
|
127
|
-
// Single assignment fires one reactive notification instead of N deletes + M sets.
|
|
128
|
-
const newMap = new SvelteMap();
|
|
129
|
-
untrack(() => {
|
|
130
|
-
for (const [key, coord] of coordinates) {
|
|
131
|
-
if (coord.nodeId !== node.id)
|
|
132
|
-
newMap.set(key, coord);
|
|
155
|
+
for (const coord of computeNodePortCoordinates(node, internalNode)) {
|
|
156
|
+
this.#coordinates.set(coord.handleId, coord);
|
|
133
157
|
}
|
|
134
|
-
});
|
|
135
|
-
for (const coord of computeNodePortCoordinates(node, internalNode)) {
|
|
136
|
-
newMap.set(coord.handleId, coord);
|
|
137
158
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
159
|
+
/**
|
|
160
|
+
* Remove all coordinates for a node (on node delete).
|
|
161
|
+
*
|
|
162
|
+
* @param nodeId - ID of the node to remove
|
|
163
|
+
*/
|
|
164
|
+
removeNode(nodeId) {
|
|
165
|
+
const stale = [];
|
|
166
|
+
untrack(() => {
|
|
167
|
+
for (const [key, coord] of this.#coordinates) {
|
|
168
|
+
if (coord.nodeId === nodeId)
|
|
169
|
+
stale.push(key);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
for (const key of stale) {
|
|
173
|
+
this.#coordinates.delete(key);
|
|
151
174
|
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
result.push(coord);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Clear all port coordinates (lifecycle cleanup).
|
|
178
|
+
*/
|
|
179
|
+
clear() {
|
|
180
|
+
this.#coordinates.clear();
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get coordinates for a specific handle.
|
|
184
|
+
*
|
|
185
|
+
* @param handleId - The handle ID to look up
|
|
186
|
+
* @returns The port coordinate or undefined if not found
|
|
187
|
+
*/
|
|
188
|
+
get(handleId) {
|
|
189
|
+
return this.#coordinates.get(handleId);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Get all coordinates for a specific node.
|
|
193
|
+
*
|
|
194
|
+
* @param nodeId - The node ID to look up
|
|
195
|
+
* @returns Array of port coordinates for the node
|
|
196
|
+
*/
|
|
197
|
+
getForNode(nodeId) {
|
|
198
|
+
const result = [];
|
|
199
|
+
for (const coord of this.#coordinates.values()) {
|
|
200
|
+
if (coord.nodeId === nodeId) {
|
|
201
|
+
result.push(coord);
|
|
202
|
+
}
|
|
181
203
|
}
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* The reactive port coordinate map.
|
|
208
|
+
* Returns the reactive SvelteMap directly.
|
|
209
|
+
*/
|
|
210
|
+
get coordinates() {
|
|
211
|
+
return this.#coordinates;
|
|
182
212
|
}
|
|
183
|
-
return result;
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Get the current snapshot of all port coordinates.
|
|
187
|
-
* Returns the reactive SvelteMap directly.
|
|
188
|
-
*
|
|
189
|
-
* @returns Current port coordinate map
|
|
190
|
-
*/
|
|
191
|
-
export function getPortCoordinateSnapshot() {
|
|
192
|
-
return coordinates;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Get the reactive port coordinates state.
|
|
196
|
-
* Useful for components that need to reactively read the coordinates.
|
|
197
|
-
*
|
|
198
|
-
* @returns The reactive port coordinate map
|
|
199
|
-
*/
|
|
200
|
-
export function getPortCoordinates() {
|
|
201
|
-
return coordinates;
|
|
202
213
|
}
|
|
@@ -99,11 +99,14 @@ export declare function cycleTheme(): void;
|
|
|
99
99
|
export declare function cleanupThemeSubscription(): void;
|
|
100
100
|
/**
|
|
101
101
|
* Initialize the theme system
|
|
102
|
-
*
|
|
102
|
+
* Called on app startup; safe to call more than once (idempotent) — the
|
|
103
|
+
* mount functions call it before mounting and <App> calls it on mount so
|
|
104
|
+
* direct component embeds get the persisted theme applied too.
|
|
103
105
|
*
|
|
104
106
|
* This function:
|
|
105
107
|
* 1. Applies the current resolved theme to the document
|
|
106
108
|
* 2. Sets up reactivity to apply theme changes
|
|
109
|
+
* 3. Subscribes to the system color-scheme so 'auto' tracks it live
|
|
107
110
|
*
|
|
108
111
|
* Note: In Svelte 5, we use $effect for reactivity. Since $effect can only
|
|
109
112
|
* be used in component context or $effect.root, we use $effect.root here
|
|
@@ -27,20 +27,18 @@ const changeListeners = new Set();
|
|
|
27
27
|
// localStorage Persistence
|
|
28
28
|
// =========================================================================
|
|
29
29
|
/**
|
|
30
|
-
* Load settings from localStorage
|
|
30
|
+
* Load the raw persisted settings snapshot from localStorage
|
|
31
31
|
*
|
|
32
|
-
* @returns
|
|
32
|
+
* @returns The parsed partial snapshot, or null if not found/invalid
|
|
33
33
|
*/
|
|
34
|
-
function
|
|
34
|
+
function loadRawFromStorage() {
|
|
35
35
|
if (typeof window === 'undefined') {
|
|
36
36
|
return null;
|
|
37
37
|
}
|
|
38
38
|
try {
|
|
39
39
|
const saved = localStorage.getItem(SETTINGS_STORAGE_KEY);
|
|
40
40
|
if (saved) {
|
|
41
|
-
|
|
42
|
-
// Deep merge with defaults to handle missing properties
|
|
43
|
-
return deepMergeSettings(DEFAULT_SETTINGS, parsed);
|
|
41
|
+
return JSON.parse(saved);
|
|
44
42
|
}
|
|
45
43
|
}
|
|
46
44
|
catch (error) {
|
|
@@ -48,6 +46,19 @@ function loadFromStorage() {
|
|
|
48
46
|
}
|
|
49
47
|
return null;
|
|
50
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Load settings from localStorage
|
|
51
|
+
*
|
|
52
|
+
* @returns Saved settings merged over defaults, or null if not found/invalid
|
|
53
|
+
*/
|
|
54
|
+
function loadFromStorage() {
|
|
55
|
+
const raw = loadRawFromStorage();
|
|
56
|
+
if (!raw) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
// Deep merge with defaults to handle missing properties
|
|
60
|
+
return deepMergeSettings(DEFAULT_SETTINGS, raw);
|
|
61
|
+
}
|
|
51
62
|
/**
|
|
52
63
|
* Save settings to localStorage
|
|
53
64
|
*
|
|
@@ -377,11 +388,14 @@ export function cleanupThemeSubscription() {
|
|
|
377
388
|
}
|
|
378
389
|
/**
|
|
379
390
|
* Initialize the theme system
|
|
380
|
-
*
|
|
391
|
+
* Called on app startup; safe to call more than once (idempotent) — the
|
|
392
|
+
* mount functions call it before mounting and <App> calls it on mount so
|
|
393
|
+
* direct component embeds get the persisted theme applied too.
|
|
381
394
|
*
|
|
382
395
|
* This function:
|
|
383
396
|
* 1. Applies the current resolved theme to the document
|
|
384
397
|
* 2. Sets up reactivity to apply theme changes
|
|
398
|
+
* 3. Subscribes to the system color-scheme so 'auto' tracks it live
|
|
385
399
|
*
|
|
386
400
|
* Note: In Svelte 5, we use $effect for reactivity. Since $effect can only
|
|
387
401
|
* be used in component context or $effect.root, we use $effect.root here
|
|
@@ -390,14 +404,25 @@ export function cleanupThemeSubscription() {
|
|
|
390
404
|
export function initializeTheme() {
|
|
391
405
|
const resolved = getResolvedTheme();
|
|
392
406
|
applyTheme(resolved);
|
|
407
|
+
// Already wired (theme is page-global) — don't stack effect roots or
|
|
408
|
+
// media-query listeners on repeated mounts.
|
|
409
|
+
if (themeEffectCleanup) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
// Track the system preference so 'auto' reacts to OS theme changes.
|
|
413
|
+
const stopThemeListener = initThemeListener();
|
|
393
414
|
// Create a standalone reactive root to watch for theme changes.
|
|
394
415
|
// $effect.root returns a cleanup function.
|
|
395
|
-
|
|
416
|
+
const stopEffectRoot = $effect.root(() => {
|
|
396
417
|
$effect(() => {
|
|
397
418
|
const currentResolved = getResolvedTheme();
|
|
398
419
|
applyTheme(currentResolved);
|
|
399
420
|
});
|
|
400
421
|
});
|
|
422
|
+
themeEffectCleanup = () => {
|
|
423
|
+
stopThemeListener();
|
|
424
|
+
stopEffectRoot();
|
|
425
|
+
};
|
|
401
426
|
}
|
|
402
427
|
/**
|
|
403
428
|
* Check if theme system is initialized
|
|
@@ -519,15 +544,25 @@ export function onSettingsChange(callback) {
|
|
|
519
544
|
* @param options - Initialization options
|
|
520
545
|
*/
|
|
521
546
|
export async function initializeSettings(options) {
|
|
522
|
-
// Apply custom defaults if provided
|
|
547
|
+
// Apply custom defaults if provided.
|
|
548
|
+
//
|
|
549
|
+
// Precedence (lowest to highest): library DEFAULT_SETTINGS < host
|
|
550
|
+
// `defaults` < the user's persisted snapshot. Host defaults SEED values
|
|
551
|
+
// the user has never saved — they must not override a returning user's
|
|
552
|
+
// persisted choices, and they are not eagerly written to storage
|
|
553
|
+
// (storage stays user-driven, written by updateSettings on real
|
|
554
|
+
// changes). Before 2.0.0 this merged host defaults OVER the persisted
|
|
555
|
+
// snapshot and re-saved it, which reset e.g. the user's dark-mode
|
|
556
|
+
// preference on every page load for hosts passing a `settings` mount
|
|
557
|
+
// option.
|
|
523
558
|
if (options?.defaults) {
|
|
524
|
-
const
|
|
525
|
-
const
|
|
559
|
+
const seeded = deepMergeSettings(DEFAULT_SETTINGS, options.defaults);
|
|
560
|
+
const raw = loadRawFromStorage();
|
|
561
|
+
const withDefaults = raw ? deepMergeSettings(seeded, raw) : seeded;
|
|
526
562
|
storeState = {
|
|
527
563
|
...storeState,
|
|
528
564
|
settings: withDefaults
|
|
529
565
|
};
|
|
530
|
-
saveToStorage(withDefaults);
|
|
531
566
|
}
|
|
532
567
|
// Initialize theme system
|
|
533
568
|
initializeTheme();
|