@flowdrop/flowdrop 1.15.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 +71 -47
- 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 +18 -25
- 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 +8 -6
- 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 +17 -5
- 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 +90 -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 +3 -2
- package/dist/helpers/proximityConnect.js +2 -5
- 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 +3 -3
- 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 +0 -25
- package/dist/registry/builtinNodes.js +1 -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 +3 -3
- 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 -222
- package/dist/stores/playgroundStore.svelte.js +515 -580
- 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 +33 -3
- 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/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 +26 -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
|
@@ -45,6 +45,15 @@ export class PortCompatibilityChecker {
|
|
|
45
45
|
this.compatibilityMap = new Map();
|
|
46
46
|
this.buildCompatibilityMap();
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Replace the port configuration and rebuild the compatibility map in place.
|
|
50
|
+
* Used by mount to apply the backend-fetched port config to an instance's
|
|
51
|
+
* checker without swapping the instance field.
|
|
52
|
+
*/
|
|
53
|
+
reinitialize(portConfig) {
|
|
54
|
+
this.portConfig = portConfig;
|
|
55
|
+
this.buildCompatibilityMap();
|
|
56
|
+
}
|
|
48
57
|
/**
|
|
49
58
|
* Build the compatibility map from configuration rules
|
|
50
59
|
*/
|
|
@@ -106,41 +115,16 @@ export class PortCompatibilityChecker {
|
|
|
106
115
|
return this.portConfig.dataTypes.filter((dt) => dt.enabled !== false);
|
|
107
116
|
}
|
|
108
117
|
}
|
|
109
|
-
// Global instance - will be initialized with configuration
|
|
110
|
-
let globalCompatibilityChecker = null;
|
|
111
|
-
/**
|
|
112
|
-
* Initialize the global port compatibility checker
|
|
113
|
-
*/
|
|
114
|
-
export function initializePortCompatibility(portConfig) {
|
|
115
|
-
globalCompatibilityChecker = new PortCompatibilityChecker(portConfig);
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Returns true if the port compatibility checker has been initialized.
|
|
119
|
-
*/
|
|
120
|
-
export function isPortCompatibilityInitialized() {
|
|
121
|
-
return globalCompatibilityChecker !== null;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Get the global port compatibility checker
|
|
125
|
-
*/
|
|
126
|
-
export function getPortCompatibilityChecker() {
|
|
127
|
-
if (!globalCompatibilityChecker) {
|
|
128
|
-
throw new Error('Port compatibility checker not initialized. Call initializePortCompatibility() first.');
|
|
129
|
-
}
|
|
130
|
-
return globalCompatibilityChecker;
|
|
131
|
-
}
|
|
132
118
|
/**
|
|
133
119
|
* Get all possible connections from a source node to target nodes
|
|
134
120
|
*/
|
|
135
|
-
export function getPossibleConnections(sourceNode, targetNodes, nodeTypes) {
|
|
121
|
+
export function getPossibleConnections(checker, sourceNode, targetNodes, nodeTypes) {
|
|
136
122
|
const sourceMetadata = nodeTypes.find((nt) => nt.id === sourceNode.data.metadata.id);
|
|
137
123
|
if (!sourceMetadata)
|
|
138
124
|
return [];
|
|
139
125
|
const possibleConnections = [];
|
|
140
126
|
// Get all output ports from source node
|
|
141
127
|
const sourceOutputs = sourceMetadata.outputs;
|
|
142
|
-
// Get the compatibility checker instance
|
|
143
|
-
const checker = getPortCompatibilityChecker();
|
|
144
128
|
// Check each target node
|
|
145
129
|
for (const targetNode of targetNodes) {
|
|
146
130
|
if (targetNode.id === sourceNode.id)
|
|
@@ -171,7 +155,7 @@ export function getPossibleConnections(sourceNode, targetNodes, nodeTypes) {
|
|
|
171
155
|
/**
|
|
172
156
|
* Validate if a specific connection is valid
|
|
173
157
|
*/
|
|
174
|
-
export function validateConnection(sourceNodeId, sourcePortId, targetNodeId, targetPortId, nodes, nodeTypes) {
|
|
158
|
+
export function validateConnection(checker, sourceNodeId, sourcePortId, targetNodeId, targetPortId, nodes, nodeTypes) {
|
|
175
159
|
// Check if nodes exist
|
|
176
160
|
const sourceNode = nodes.find((n) => n.id === sourceNodeId);
|
|
177
161
|
const targetNode = nodes.find((n) => n.id === targetNodeId);
|
|
@@ -200,8 +184,7 @@ export function validateConnection(sourceNodeId, sourcePortId, targetNodeId, tar
|
|
|
200
184
|
if (!targetPort) {
|
|
201
185
|
return { valid: false, error: 'Target port not found' };
|
|
202
186
|
}
|
|
203
|
-
// Check data type compatibility using the
|
|
204
|
-
const checker = getPortCompatibilityChecker();
|
|
187
|
+
// Check data type compatibility using the instance's checker
|
|
205
188
|
if (!checker.areDataTypesCompatible(sourcePort.dataType, targetPort.dataType)) {
|
|
206
189
|
return {
|
|
207
190
|
valid: false,
|
|
@@ -213,7 +196,7 @@ export function validateConnection(sourceNodeId, sourcePortId, targetNodeId, tar
|
|
|
213
196
|
/**
|
|
214
197
|
* Get connection suggestions for a node
|
|
215
198
|
*/
|
|
216
|
-
export function getConnectionSuggestions(nodeId, nodes, nodeTypes) {
|
|
199
|
+
export function getConnectionSuggestions(checker, nodeId, nodes, nodeTypes) {
|
|
217
200
|
const node = nodes.find((n) => n.id === nodeId);
|
|
218
201
|
if (!node)
|
|
219
202
|
return [];
|
|
@@ -223,8 +206,6 @@ export function getConnectionSuggestions(nodeId, nodes, nodeTypes) {
|
|
|
223
206
|
const suggestions = [];
|
|
224
207
|
// Get all other nodes
|
|
225
208
|
const otherNodes = nodes.filter((n) => n.id !== nodeId);
|
|
226
|
-
// Get the compatibility checker instance
|
|
227
|
-
const checker = getPortCompatibilityChecker();
|
|
228
209
|
for (const otherNode of otherNodes) {
|
|
229
210
|
const otherMetadata = nodeTypes.find((nt) => nt.id === otherNode.data.metadata.id);
|
|
230
211
|
if (!otherMetadata)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Duration formatting helpers.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the backend `Drupal\flowdrop\Utility\Duration::formatMicroseconds()`
|
|
5
|
+
* tiers so the playground and the Drupal admin pages render identical values.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Formats a duration in human-readable form from microseconds.
|
|
9
|
+
*
|
|
10
|
+
* Examples: `150µs`, `2.5ms`, `25.1ms`, `250ms`, `1.23s`, `45s`,
|
|
11
|
+
* `2m 30s`, `1h 30m`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatMicroseconds(microseconds: number | null | undefined): string | null;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Duration formatting helpers.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the backend `Drupal\flowdrop\Utility\Duration::formatMicroseconds()`
|
|
5
|
+
* tiers so the playground and the Drupal admin pages render identical values.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Formats a duration in human-readable form from microseconds.
|
|
9
|
+
*
|
|
10
|
+
* Examples: `150µs`, `2.5ms`, `25.1ms`, `250ms`, `1.23s`, `45s`,
|
|
11
|
+
* `2m 30s`, `1h 30m`.
|
|
12
|
+
*/
|
|
13
|
+
export function formatMicroseconds(microseconds) {
|
|
14
|
+
if (microseconds == null || !Number.isFinite(microseconds) || microseconds < 0)
|
|
15
|
+
return null;
|
|
16
|
+
const us = Math.round(microseconds);
|
|
17
|
+
if (us < 1000) {
|
|
18
|
+
return `${us}µs`;
|
|
19
|
+
}
|
|
20
|
+
if (us < 1_000_000) {
|
|
21
|
+
const ms = us / 1000;
|
|
22
|
+
if (us < 100_000) {
|
|
23
|
+
// 2 decimals below 10ms, 1 decimal below 100ms — matches PHP round().
|
|
24
|
+
const decimals = us < 10_000 ? 2 : 1;
|
|
25
|
+
// Drop trailing zeros the way PHP round() renders (2.50 → 2.5, 3.00 → 3).
|
|
26
|
+
return `${parseFloat(ms.toFixed(decimals))}ms`;
|
|
27
|
+
}
|
|
28
|
+
return `${Math.round(ms)}ms`;
|
|
29
|
+
}
|
|
30
|
+
if (us < 10_000_000) {
|
|
31
|
+
return `${parseFloat((us / 1_000_000).toFixed(2))}s`;
|
|
32
|
+
}
|
|
33
|
+
if (us < 60_000_000) {
|
|
34
|
+
return `${Math.floor(us / 1_000_000)}s`;
|
|
35
|
+
}
|
|
36
|
+
const totalSeconds = Math.floor(us / 1_000_000);
|
|
37
|
+
if (us < 3_600_000_000) {
|
|
38
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
39
|
+
const secs = totalSeconds % 60;
|
|
40
|
+
return secs > 0 ? `${minutes}m ${secs}s` : `${minutes}m`;
|
|
41
|
+
}
|
|
42
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
43
|
+
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
44
|
+
return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
|
|
45
|
+
}
|
package/dist/utils/icons.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Ensures consistent icon usage across all components
|
|
4
4
|
*/
|
|
5
5
|
import type { NodeCategory } from '../types/index.js';
|
|
6
|
+
import type { CategoriesStore } from '../stores/categoriesStore.svelte.js';
|
|
6
7
|
/**
|
|
7
8
|
* Default icons for different contexts
|
|
8
9
|
*/
|
|
@@ -72,19 +73,21 @@ export declare const DEFAULT_ICONS: {
|
|
|
72
73
|
export declare const CATEGORY_ICONS: Record<string, string>;
|
|
73
74
|
/**
|
|
74
75
|
* Get the appropriate icon for a node
|
|
76
|
+
* @param categories - The instance's categories store (e.g. `fd.categories`)
|
|
75
77
|
* @param nodeIcon - The node's specific icon
|
|
76
78
|
* @param category - The node's category
|
|
77
79
|
* @returns The icon to use
|
|
78
80
|
*/
|
|
79
|
-
export declare function getNodeIcon(nodeIcon?: string, category?: NodeCategory): string;
|
|
81
|
+
export declare function getNodeIcon(categories: CategoriesStore, nodeIcon?: string, category?: NodeCategory): string;
|
|
80
82
|
/**
|
|
81
83
|
* Get the appropriate icon for a category.
|
|
82
84
|
* Checks the categories store first (which includes API overrides),
|
|
83
85
|
* then falls back to the static CATEGORY_ICONS map, then to the default.
|
|
86
|
+
* @param categories - The instance's categories store (e.g. `fd.categories`)
|
|
84
87
|
* @param category - The category
|
|
85
88
|
* @returns The icon to use
|
|
86
89
|
*/
|
|
87
|
-
export declare function getCategoryIcon(category: NodeCategory): string;
|
|
90
|
+
export declare function getCategoryIcon(categories: CategoriesStore, category: NodeCategory): string;
|
|
88
91
|
/**
|
|
89
92
|
* Get a default icon by key
|
|
90
93
|
* @param key - The icon key from DEFAULT_ICONS
|
package/dist/utils/icons.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Centralized icon management for FlowDrop
|
|
3
3
|
* Ensures consistent icon usage across all components
|
|
4
4
|
*/
|
|
5
|
-
import { getCategoryIcon as getCategoryIconFromStore } from '../stores/categoriesStore.svelte.js';
|
|
6
5
|
/**
|
|
7
6
|
* Default icons for different contexts
|
|
8
7
|
*/
|
|
@@ -103,18 +102,19 @@ export const CATEGORY_ICONS = {
|
|
|
103
102
|
};
|
|
104
103
|
/**
|
|
105
104
|
* Get the appropriate icon for a node
|
|
105
|
+
* @param categories - The instance's categories store (e.g. `fd.categories`)
|
|
106
106
|
* @param nodeIcon - The node's specific icon
|
|
107
107
|
* @param category - The node's category
|
|
108
108
|
* @returns The icon to use
|
|
109
109
|
*/
|
|
110
|
-
export function getNodeIcon(nodeIcon, category) {
|
|
110
|
+
export function getNodeIcon(categories, nodeIcon, category) {
|
|
111
111
|
// If node has a specific icon, use it
|
|
112
112
|
if (nodeIcon) {
|
|
113
113
|
return nodeIcon;
|
|
114
114
|
}
|
|
115
115
|
// If category is provided, use category icon from store (which includes API overrides)
|
|
116
116
|
if (category) {
|
|
117
|
-
return
|
|
117
|
+
return categories.getIcon(category);
|
|
118
118
|
}
|
|
119
119
|
// Fallback to default node icon
|
|
120
120
|
return DEFAULT_ICONS.NODE;
|
|
@@ -123,11 +123,12 @@ export function getNodeIcon(nodeIcon, category) {
|
|
|
123
123
|
* Get the appropriate icon for a category.
|
|
124
124
|
* Checks the categories store first (which includes API overrides),
|
|
125
125
|
* then falls back to the static CATEGORY_ICONS map, then to the default.
|
|
126
|
+
* @param categories - The instance's categories store (e.g. `fd.categories`)
|
|
126
127
|
* @param category - The category
|
|
127
128
|
* @returns The icon to use
|
|
128
129
|
*/
|
|
129
|
-
export function getCategoryIcon(category) {
|
|
130
|
-
return
|
|
130
|
+
export function getCategoryIcon(categories, category) {
|
|
131
|
+
return categories.getIcon(category);
|
|
131
132
|
}
|
|
132
133
|
/**
|
|
133
134
|
* Get a default icon by key
|
package/dist/utils/nodeSwap.d.ts
CHANGED
|
@@ -161,6 +161,10 @@ export declare function mapConfig(oldConfig: ConfigValues, newConfigSchema: Conf
|
|
|
161
161
|
*
|
|
162
162
|
* This does NOT mutate anything — it returns a preview that can be displayed
|
|
163
163
|
* to the user for confirmation before executing the swap.
|
|
164
|
+
*
|
|
165
|
+
* Thin wrapper over {@link computeSwapPreviewWithOptions} — with no strategies
|
|
166
|
+
* or overrides the cascade reduces to the built-in exact matching, so both
|
|
167
|
+
* entry points share one implementation.
|
|
164
168
|
*/
|
|
165
169
|
export declare function computeSwapPreview(oldNode: WorkflowNode, newMetadata: NodeMetadata, edges: WorkflowEdge[], allNodes: WorkflowNode[], checker?: PortCompatibilityChecker | null): SwapPreview;
|
|
166
170
|
/**
|
|
@@ -183,7 +187,7 @@ export declare function getVersionUpgrade(currentMetadata: NodeMetadata, allNode
|
|
|
183
187
|
*
|
|
184
188
|
* Resolution order:
|
|
185
189
|
* 1. Check strategies — first canHandle() match wins for mapPorts()/mapConfig()
|
|
186
|
-
* 2. Fall through to built-in
|
|
190
|
+
* 2. Fall through to built-in exact matching (ID, then name) for ports not covered by strategy
|
|
187
191
|
* 3. Apply portOverrides on top (highest priority — user's manual overrides)
|
|
188
192
|
* 4. Same cascade for config
|
|
189
193
|
*/
|
|
@@ -199,7 +203,7 @@ export declare function computeInteractiveState(oldNode: WorkflowNode, newMetada
|
|
|
199
203
|
* Convert user-edited InteractiveSwapState back into a SwapPreview
|
|
200
204
|
* for executeSwap(). Pure function, no side effects.
|
|
201
205
|
*/
|
|
202
|
-
export declare function buildSwapPreviewFromState(state: InteractiveSwapState,
|
|
206
|
+
export declare function buildSwapPreviewFromState(state: InteractiveSwapState, _allEdges: WorkflowEdge[]): SwapPreview;
|
|
203
207
|
/**
|
|
204
208
|
* Headless one-shot swap with full validation.
|
|
205
209
|
*
|
package/dist/utils/nodeSwap.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module utils/nodeSwap
|
|
8
8
|
*/
|
|
9
|
-
import { buildHandleId, extractPortId
|
|
9
|
+
import { buildHandleId, extractPortId } from './handleIds.js';
|
|
10
10
|
import { generateNodeId } from './nodeIds.js';
|
|
11
11
|
/** Error class for swap validation failures. */
|
|
12
12
|
export class SwapValidationError extends Error {
|
|
@@ -86,16 +86,17 @@ export function mapConfig(oldConfig, newConfigSchema, newDefaults = {}) {
|
|
|
86
86
|
}
|
|
87
87
|
return { config, carriedOver, reset };
|
|
88
88
|
}
|
|
89
|
-
// =========================================================================
|
|
90
|
-
// Port matching
|
|
91
|
-
// =========================================================================
|
|
92
89
|
/**
|
|
93
90
|
* Find the best matching port on the new node for a given old port.
|
|
94
91
|
*
|
|
95
|
-
*
|
|
92
|
+
* Two-pass strategy — exact matches only:
|
|
96
93
|
* 1. Exact port ID match with compatible dataType
|
|
97
|
-
* 2.
|
|
98
|
-
*
|
|
94
|
+
* 2. Exact port name match (case-insensitive) with compatible dataType
|
|
95
|
+
*
|
|
96
|
+
* There is deliberately no fuzzy "first compatible dataType" fallback:
|
|
97
|
+
* it silently rewired edges to the wrong port (e.g. a `text` edge landing
|
|
98
|
+
* on `assistant_message`). If neither ID nor name matches, the edge is
|
|
99
|
+
* dropped and reported instead.
|
|
99
100
|
*/
|
|
100
101
|
function findMatchingPort(oldPort, newPorts, usedPortIds, checker) {
|
|
101
102
|
const available = newPorts.filter((p) => p.type === oldPort.type && !usedPortIds.has(p.id));
|
|
@@ -116,11 +117,7 @@ function findMatchingPort(oldPort, newPorts, usedPortIds, checker) {
|
|
|
116
117
|
// Pass 2: name match (case-insensitive)
|
|
117
118
|
const oldNameLower = oldPort.name.toLowerCase();
|
|
118
119
|
const nameMatch = available.find((p) => p.name.toLowerCase() === oldNameLower && isCompatible(oldPort, p));
|
|
119
|
-
|
|
120
|
-
return nameMatch;
|
|
121
|
-
// Pass 3: first compatible dataType
|
|
122
|
-
const typeMatch = available.find((p) => isCompatible(oldPort, p));
|
|
123
|
-
return typeMatch ?? null;
|
|
120
|
+
return nameMatch ?? null;
|
|
124
121
|
}
|
|
125
122
|
/**
|
|
126
123
|
* Resolve the port metadata for an edge endpoint on a given node.
|
|
@@ -142,65 +139,13 @@ function resolvePort(node, handleId, direction) {
|
|
|
142
139
|
*
|
|
143
140
|
* This does NOT mutate anything — it returns a preview that can be displayed
|
|
144
141
|
* to the user for confirmation before executing the swap.
|
|
142
|
+
*
|
|
143
|
+
* Thin wrapper over {@link computeSwapPreviewWithOptions} — with no strategies
|
|
144
|
+
* or overrides the cascade reduces to the built-in exact matching, so both
|
|
145
|
+
* entry points share one implementation.
|
|
145
146
|
*/
|
|
146
147
|
export function computeSwapPreview(oldNode, newMetadata, edges, allNodes, checker = null) {
|
|
147
|
-
|
|
148
|
-
const newNodeId = generateNodeId(newMetadata.id, allNodes);
|
|
149
|
-
// Collect all edges connected to the old node
|
|
150
|
-
const connectedEdges = edges.filter((e) => e.source === oldNodeId || e.target === oldNodeId);
|
|
151
|
-
// Track which ports on the new node have been claimed
|
|
152
|
-
const usedInputPortIds = new Set();
|
|
153
|
-
const usedOutputPortIds = new Set();
|
|
154
|
-
const keptEdges = [];
|
|
155
|
-
const droppedEdges = [];
|
|
156
|
-
for (const edge of connectedEdges) {
|
|
157
|
-
const isSource = edge.source === oldNodeId;
|
|
158
|
-
const direction = isSource ? 'output' : 'input';
|
|
159
|
-
const handleId = isSource ? edge.sourceHandle : edge.targetHandle;
|
|
160
|
-
const usedPorts = isSource ? usedOutputPortIds : usedInputPortIds;
|
|
161
|
-
// Resolve the old port
|
|
162
|
-
const oldPort = resolvePort(oldNode, handleId, direction);
|
|
163
|
-
if (!oldPort) {
|
|
164
|
-
droppedEdges.push({
|
|
165
|
-
edge,
|
|
166
|
-
reason: `Port not found on original node`
|
|
167
|
-
});
|
|
168
|
-
continue;
|
|
169
|
-
}
|
|
170
|
-
// Find matching port on new node
|
|
171
|
-
const newPorts = direction === 'input' ? newMetadata.inputs : newMetadata.outputs;
|
|
172
|
-
const match = findMatchingPort(oldPort, newPorts, usedPorts, checker);
|
|
173
|
-
if (!match) {
|
|
174
|
-
droppedEdges.push({
|
|
175
|
-
edge,
|
|
176
|
-
reason: `No compatible ${direction} port found on "${newMetadata.name}"`
|
|
177
|
-
});
|
|
178
|
-
continue;
|
|
179
|
-
}
|
|
180
|
-
usedPorts.add(match.id);
|
|
181
|
-
// Build the rewritten edge
|
|
182
|
-
const newHandleId = buildHandleId(newNodeId, direction, match.id);
|
|
183
|
-
const newEdge = { ...edge };
|
|
184
|
-
if (isSource) {
|
|
185
|
-
newEdge.source = newNodeId;
|
|
186
|
-
newEdge.sourceHandle = newHandleId;
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
newEdge.target = newNodeId;
|
|
190
|
-
newEdge.targetHandle = newHandleId;
|
|
191
|
-
}
|
|
192
|
-
keptEdges.push({ edge, newEdge });
|
|
193
|
-
}
|
|
194
|
-
// Config mapping preview
|
|
195
|
-
const { carriedOver, reset } = mapConfig(oldNode.data.config, newMetadata.configSchema, newMetadata.config);
|
|
196
|
-
return {
|
|
197
|
-
keptEdges,
|
|
198
|
-
droppedEdges,
|
|
199
|
-
hasDataLoss: droppedEdges.length > 0,
|
|
200
|
-
newNodeId,
|
|
201
|
-
configCarriedOver: carriedOver,
|
|
202
|
-
configReset: reset
|
|
203
|
-
};
|
|
148
|
+
return computeSwapPreviewWithOptions(oldNode, newMetadata, edges, allNodes, { checker });
|
|
204
149
|
}
|
|
205
150
|
// =========================================================================
|
|
206
151
|
// Swap execution
|
|
@@ -231,6 +176,9 @@ export function executeSwap(oldNode, newMetadata, preview, allNodes, allEdges) {
|
|
|
231
176
|
label: newMetadata.name,
|
|
232
177
|
config: mappedConfig,
|
|
233
178
|
metadata: newMetadata,
|
|
179
|
+
// Node components derive their handle IDs from data.nodeId — without it
|
|
180
|
+
// every edge anchored to this node silently disappears from the canvas.
|
|
181
|
+
nodeId: newNodeId,
|
|
234
182
|
extensions
|
|
235
183
|
}
|
|
236
184
|
};
|
|
@@ -298,7 +246,7 @@ function classifyMatch(oldPort, matchedPort) {
|
|
|
298
246
|
*
|
|
299
247
|
* Resolution order:
|
|
300
248
|
* 1. Check strategies — first canHandle() match wins for mapPorts()/mapConfig()
|
|
301
|
-
* 2. Fall through to built-in
|
|
249
|
+
* 2. Fall through to built-in exact matching (ID, then name) for ports not covered by strategy
|
|
302
250
|
* 3. Apply portOverrides on top (highest priority — user's manual overrides)
|
|
303
251
|
* 4. Same cascade for config
|
|
304
252
|
*/
|
|
@@ -332,84 +280,73 @@ export function computeSwapPreviewWithOptions(oldNode, newMetadata, edges, allNo
|
|
|
332
280
|
for (const override of options.portOverrides ?? []) {
|
|
333
281
|
portOverrideLookup.set(`${override.direction}:${override.oldPortId}`, override.newPortId);
|
|
334
282
|
}
|
|
335
|
-
// Track
|
|
283
|
+
// Track ports on the new node claimed by a DIFFERENT old port
|
|
336
284
|
const usedInputPortIds = new Set();
|
|
337
285
|
const usedOutputPortIds = new Set();
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
const
|
|
344
|
-
const usedPorts = isSource ? usedOutputPortIds : usedInputPortIds;
|
|
345
|
-
const oldPort = resolvePort(oldNode, handleId, direction);
|
|
346
|
-
if (!oldPort) {
|
|
347
|
-
droppedEdges.push({ edge, reason: 'Port not found on original node' });
|
|
348
|
-
continue;
|
|
349
|
-
}
|
|
286
|
+
// Memoized old-port → new-port resolutions so every edge anchored on the
|
|
287
|
+
// same old port maps to the same new port (multi-connection ports, fan-outs).
|
|
288
|
+
const portResolutions = new Map();
|
|
289
|
+
/** Resolve a new port for an old port through the priority cascade. */
|
|
290
|
+
const resolveNewPort = (oldPort, direction, usedPorts) => {
|
|
291
|
+
const newPorts = direction === 'input' ? newMetadata.inputs : newMetadata.outputs;
|
|
350
292
|
// Priority 1: Manual port override
|
|
351
293
|
const overrideKey = `${direction}:${oldPort.id}`;
|
|
352
294
|
if (portOverrideLookup.has(overrideKey)) {
|
|
353
295
|
const overrideNewPortId = portOverrideLookup.get(overrideKey);
|
|
354
296
|
if (overrideNewPortId === null) {
|
|
355
|
-
|
|
356
|
-
continue;
|
|
297
|
+
return { port: null, reason: 'Manually dropped' };
|
|
357
298
|
}
|
|
358
|
-
const newPorts = direction === 'input' ? newMetadata.inputs : newMetadata.outputs;
|
|
359
299
|
const overridePort = newPorts.find((p) => p.id === overrideNewPortId);
|
|
360
300
|
if (overridePort) {
|
|
361
|
-
|
|
362
|
-
const newHandleId = buildHandleId(newNodeId, direction, overridePort.id);
|
|
363
|
-
const newEdge = { ...edge };
|
|
364
|
-
if (isSource) {
|
|
365
|
-
newEdge.source = newNodeId;
|
|
366
|
-
newEdge.sourceHandle = newHandleId;
|
|
367
|
-
}
|
|
368
|
-
else {
|
|
369
|
-
newEdge.target = newNodeId;
|
|
370
|
-
newEdge.targetHandle = newHandleId;
|
|
371
|
-
}
|
|
372
|
-
keptEdges.push({ edge, newEdge });
|
|
373
|
-
continue;
|
|
301
|
+
return { port: overridePort };
|
|
374
302
|
}
|
|
375
303
|
}
|
|
376
304
|
// Priority 2: Strategy port mapping
|
|
377
305
|
if (strategyPortMap && oldPort.id in strategyPortMap) {
|
|
378
306
|
const strategyNewPortId = strategyPortMap[oldPort.id];
|
|
379
307
|
if (strategyNewPortId === null) {
|
|
380
|
-
|
|
381
|
-
continue;
|
|
308
|
+
return { port: null, reason: 'Dropped by strategy' };
|
|
382
309
|
}
|
|
383
|
-
const newPorts = direction === 'input' ? newMetadata.inputs : newMetadata.outputs;
|
|
384
310
|
const strategyPort = newPorts.find((p) => p.id === strategyNewPortId);
|
|
385
311
|
if (strategyPort && !usedPorts.has(strategyPort.id)) {
|
|
386
|
-
|
|
387
|
-
const newHandleId = buildHandleId(newNodeId, direction, strategyPort.id);
|
|
388
|
-
const newEdge = { ...edge };
|
|
389
|
-
if (isSource) {
|
|
390
|
-
newEdge.source = newNodeId;
|
|
391
|
-
newEdge.sourceHandle = newHandleId;
|
|
392
|
-
}
|
|
393
|
-
else {
|
|
394
|
-
newEdge.target = newNodeId;
|
|
395
|
-
newEdge.targetHandle = newHandleId;
|
|
396
|
-
}
|
|
397
|
-
keptEdges.push({ edge, newEdge });
|
|
398
|
-
continue;
|
|
312
|
+
return { port: strategyPort };
|
|
399
313
|
}
|
|
400
314
|
}
|
|
401
|
-
// Priority 3: Built-in
|
|
402
|
-
const newPorts = direction === 'input' ? newMetadata.inputs : newMetadata.outputs;
|
|
315
|
+
// Priority 3: Built-in exact matching (ID, then name)
|
|
403
316
|
const match = findMatchingPort(oldPort, newPorts, usedPorts, checker);
|
|
404
317
|
if (!match) {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
reason: `No
|
|
408
|
-
}
|
|
318
|
+
return {
|
|
319
|
+
port: null,
|
|
320
|
+
reason: `No matching ${direction} port for "${oldPort.id}" on "${newMetadata.name}"`
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
return { port: match };
|
|
324
|
+
};
|
|
325
|
+
const keptEdges = [];
|
|
326
|
+
const droppedEdges = [];
|
|
327
|
+
for (const edge of connectedEdges) {
|
|
328
|
+
const isSource = edge.source === oldNodeId;
|
|
329
|
+
const direction = isSource ? 'output' : 'input';
|
|
330
|
+
const handleId = isSource ? edge.sourceHandle : edge.targetHandle;
|
|
331
|
+
const usedPorts = isSource ? usedOutputPortIds : usedInputPortIds;
|
|
332
|
+
const oldPort = resolvePort(oldNode, handleId, direction);
|
|
333
|
+
if (!oldPort) {
|
|
334
|
+
droppedEdges.push({ edge, reason: 'Port not found on original node' });
|
|
409
335
|
continue;
|
|
410
336
|
}
|
|
411
|
-
|
|
412
|
-
|
|
337
|
+
const matchKey = `${direction}:${oldPort.id}`;
|
|
338
|
+
let resolved = portResolutions.get(matchKey);
|
|
339
|
+
if (!resolved) {
|
|
340
|
+
resolved = resolveNewPort(oldPort, direction, usedPorts);
|
|
341
|
+
portResolutions.set(matchKey, resolved);
|
|
342
|
+
if (resolved.port)
|
|
343
|
+
usedPorts.add(resolved.port.id);
|
|
344
|
+
}
|
|
345
|
+
if (!resolved.port) {
|
|
346
|
+
droppedEdges.push({ edge, reason: resolved.reason });
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
const newHandleId = buildHandleId(newNodeId, direction, resolved.port.id);
|
|
413
350
|
const newEdge = { ...edge };
|
|
414
351
|
if (isSource) {
|
|
415
352
|
newEdge.source = newNodeId;
|
|
@@ -422,7 +359,7 @@ export function computeSwapPreviewWithOptions(oldNode, newMetadata, edges, allNo
|
|
|
422
359
|
keptEdges.push({ edge, newEdge });
|
|
423
360
|
}
|
|
424
361
|
// Config mapping — apply strategy then overrides
|
|
425
|
-
const {
|
|
362
|
+
const { carriedOver, reset } = mapConfig(oldNode.data.config, newMetadata.configSchema, newMetadata.config);
|
|
426
363
|
// Apply strategy config overrides
|
|
427
364
|
if (strategyConfigMap) {
|
|
428
365
|
for (const [key, mapping] of Object.entries(strategyConfigMap)) {
|
|
@@ -482,7 +419,6 @@ export function computeSwapPreviewWithOptions(oldNode, newMetadata, edges, allNo
|
|
|
482
419
|
* with match quality annotations and isFlat flags.
|
|
483
420
|
*/
|
|
484
421
|
export function computeInteractiveState(oldNode, newMetadata, edges, allNodes, options = {}) {
|
|
485
|
-
const checker = options.checker ?? null;
|
|
486
422
|
const oldNodeId = oldNode.id;
|
|
487
423
|
const newNodeId = generateNodeId(newMetadata.id, allNodes);
|
|
488
424
|
const connectedEdges = edges.filter((e) => e.source === oldNodeId || e.target === oldNodeId);
|
|
@@ -567,7 +503,7 @@ function isPrimitive(value) {
|
|
|
567
503
|
* Convert user-edited InteractiveSwapState back into a SwapPreview
|
|
568
504
|
* for executeSwap(). Pure function, no side effects.
|
|
569
505
|
*/
|
|
570
|
-
export function buildSwapPreviewFromState(state,
|
|
506
|
+
export function buildSwapPreviewFromState(state, _allEdges) {
|
|
571
507
|
const keptEdges = [];
|
|
572
508
|
const droppedEdges = [];
|
|
573
509
|
for (const mapping of state.portMappings) {
|
|
@@ -10,14 +10,16 @@
|
|
|
10
10
|
* Works with both built-in types and custom registered types.
|
|
11
11
|
*/
|
|
12
12
|
import type { NodeType, NodeMetadata } from '../types/index.js';
|
|
13
|
+
import type { NodeComponentRegistry } from '../registry/nodeComponentRegistry.js';
|
|
13
14
|
/**
|
|
14
15
|
* Gets the SvelteFlow component name for a given NodeType.
|
|
15
16
|
* Uses the node component registry to resolve types.
|
|
16
17
|
*
|
|
18
|
+
* @param registry - The instance's node component registry (e.g. `fd.nodes`)
|
|
17
19
|
* @param nodeType - The node type identifier
|
|
18
20
|
* @returns The component name to use
|
|
19
21
|
*/
|
|
20
|
-
export declare function getComponentNameForNodeType(nodeType: NodeType | string): string;
|
|
22
|
+
export declare function getComponentNameForNodeType(registry: NodeComponentRegistry, nodeType: NodeType | string): string;
|
|
21
23
|
/**
|
|
22
24
|
* Gets the available node types for a given NodeMetadata.
|
|
23
25
|
* Priority: supportedTypes > type > "default"
|
|
@@ -43,28 +45,31 @@ export declare function getPrimaryNodeType(metadata: NodeMetadata): NodeType | s
|
|
|
43
45
|
* 3. First supportedType
|
|
44
46
|
* 4. "default"
|
|
45
47
|
*
|
|
48
|
+
* @param registry - The instance's node component registry (e.g. `fd.nodes`)
|
|
46
49
|
* @param metadata - The node metadata
|
|
47
50
|
* @param configNodeType - Optional type from user config
|
|
48
51
|
* @returns The resolved node type
|
|
49
52
|
*/
|
|
50
|
-
export declare function resolveNodeType(metadata: NodeMetadata, configNodeType?: string): NodeType | string;
|
|
53
|
+
export declare function resolveNodeType(registry: NodeComponentRegistry, metadata: NodeMetadata, configNodeType?: string): NodeType | string;
|
|
51
54
|
/**
|
|
52
55
|
* Gets the SvelteFlow component name for resolved node type.
|
|
53
56
|
* This is the main function used by UniversalNode to determine which component to render.
|
|
54
57
|
*
|
|
58
|
+
* @param registry - The instance's node component registry (e.g. `fd.nodes`)
|
|
55
59
|
* @param metadata - The node metadata
|
|
56
60
|
* @param configNodeType - Optional type from user config
|
|
57
61
|
* @returns The component name to use
|
|
58
62
|
*/
|
|
59
|
-
export declare function resolveComponentName(metadata: NodeMetadata, configNodeType?: string): string;
|
|
63
|
+
export declare function resolveComponentName(registry: NodeComponentRegistry, metadata: NodeMetadata, configNodeType?: string): string;
|
|
60
64
|
/**
|
|
61
65
|
* Validates if a node type is supported by the given metadata.
|
|
62
66
|
*
|
|
67
|
+
* @param registry - The instance's node component registry (e.g. `fd.nodes`)
|
|
63
68
|
* @param metadata - The node metadata
|
|
64
69
|
* @param nodeType - The type to check
|
|
65
70
|
* @returns true if the type is supported
|
|
66
71
|
*/
|
|
67
|
-
export declare function isNodeTypeSupported(metadata: NodeMetadata, nodeType: NodeType | string): boolean;
|
|
72
|
+
export declare function isNodeTypeSupported(registry: NodeComponentRegistry, metadata: NodeMetadata, nodeType: NodeType | string): boolean;
|
|
68
73
|
/**
|
|
69
74
|
* Gets oneOf options for node type configuration.
|
|
70
75
|
* Used in config schemas to show available options with labels.
|
|
@@ -73,11 +78,12 @@ export declare function isNodeTypeSupported(metadata: NodeMetadata, nodeType: No
|
|
|
73
78
|
* - Types specified in metadata.supportedTypes
|
|
74
79
|
* - Registered custom types (optionally filtered)
|
|
75
80
|
*
|
|
81
|
+
* @param registry - The instance's node component registry (e.g. `fd.nodes`)
|
|
76
82
|
* @param metadata - The node metadata
|
|
77
83
|
* @param includeCustomTypes - Whether to include registered custom types
|
|
78
84
|
* @returns Array of oneOf items with const (type value) and title (display name)
|
|
79
85
|
*/
|
|
80
|
-
export declare function getNodeTypeOneOfOptions(metadata: NodeMetadata, includeCustomTypes?: boolean): Array<{
|
|
86
|
+
export declare function getNodeTypeOneOfOptions(registry: NodeComponentRegistry, metadata: NodeMetadata, includeCustomTypes?: boolean): Array<{
|
|
81
87
|
const: string;
|
|
82
88
|
title: string;
|
|
83
89
|
}>;
|
|
@@ -88,11 +94,12 @@ export declare function getNodeTypeOneOfOptions(metadata: NodeMetadata, includeC
|
|
|
88
94
|
* Uses JSON Schema `oneOf` pattern with `const`/`title` for labeled options,
|
|
89
95
|
* which is the standard approach supported by form components.
|
|
90
96
|
*
|
|
97
|
+
* @param registry - The instance's node component registry (e.g. `fd.nodes`)
|
|
91
98
|
* @param metadata - The node metadata
|
|
92
99
|
* @param defaultType - Optional default type override
|
|
93
100
|
* @returns Config schema property object with oneOf for labeled options
|
|
94
101
|
*/
|
|
95
|
-
export declare function createNodeTypeConfigProperty(metadata: NodeMetadata, defaultType?: NodeType | string): {
|
|
102
|
+
export declare function createNodeTypeConfigProperty(registry: NodeComponentRegistry, metadata: NodeMetadata, defaultType?: NodeType | string): {
|
|
96
103
|
type: "string";
|
|
97
104
|
title: string;
|
|
98
105
|
description: string;
|
|
@@ -105,13 +112,15 @@ export declare function createNodeTypeConfigProperty(metadata: NodeMetadata, def
|
|
|
105
112
|
/**
|
|
106
113
|
* Check if a type string represents a valid registered or built-in type.
|
|
107
114
|
*
|
|
115
|
+
* @param registry - The instance's node component registry (e.g. `fd.nodes`)
|
|
108
116
|
* @param type - The type to check
|
|
109
117
|
* @returns true if the type is valid
|
|
110
118
|
*/
|
|
111
|
-
export declare function isValidNodeType(type: string): boolean;
|
|
119
|
+
export declare function isValidNodeType(registry: NodeComponentRegistry, type: string): boolean;
|
|
112
120
|
/**
|
|
113
121
|
* Get all available node types (built-in + registered).
|
|
114
122
|
*
|
|
123
|
+
* @param registry - The instance's node component registry (e.g. `fd.nodes`)
|
|
115
124
|
* @returns Array of all valid node type identifiers
|
|
116
125
|
*/
|
|
117
|
-
export declare function getAllNodeTypes(): string[];
|
|
126
|
+
export declare function getAllNodeTypes(registry: NodeComponentRegistry): string[];
|