@d34dman/flowdrop 0.0.50 → 0.0.52
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/dist/api/client.d.ts +5 -1
- package/dist/api/client.js +10 -0
- package/dist/components/NodeSidebar.svelte +4 -21
- package/dist/components/SettingsPanel.svelte +15 -0
- package/dist/components/ThemeToggle.svelte +1 -2
- package/dist/components/WorkflowEditor.svelte +97 -1
- package/dist/components/form/FormField.svelte +1 -1
- package/dist/components/form/FormFieldLight.svelte +1 -1
- package/dist/components/nodes/ToolNode.svelte +12 -1
- package/dist/config/defaultCategories.d.ts +7 -0
- package/dist/config/defaultCategories.js +126 -0
- package/dist/config/endpoints.d.ts +1 -0
- package/dist/config/endpoints.js +1 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/editor/index.d.ts +1 -0
- package/dist/editor/index.js +1 -0
- package/dist/helpers/proximityConnect.d.ts +78 -0
- package/dist/helpers/proximityConnect.js +224 -0
- package/dist/helpers/workflowEditorHelper.js +9 -0
- package/dist/index.d.ts +1 -5
- package/dist/index.js +2 -11
- package/dist/services/categoriesApi.d.ts +14 -0
- package/dist/services/categoriesApi.js +41 -0
- package/dist/settings/index.d.ts +24 -0
- package/dist/settings/index.js +32 -0
- package/dist/stores/categoriesStore.d.ts +32 -0
- package/dist/stores/categoriesStore.js +80 -0
- package/dist/stores/settingsStore.d.ts +1 -30
- package/dist/stores/settingsStore.js +12 -17
- package/dist/svelte-app.d.ts +4 -1
- package/dist/svelte-app.js +30 -2
- package/dist/types/index.d.ts +38 -3
- package/dist/types/settings.d.ts +4 -0
- package/dist/types/settings.js +3 -1
- package/dist/utils/colors.d.ts +5 -2
- package/dist/utils/colors.js +7 -3
- package/dist/utils/icons.d.ts +7 -3
- package/dist/utils/icons.js +11 -6
- package/package.json +6 -1
package/dist/api/client.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* API Client for FlowDrop Workflow Library
|
|
3
3
|
*/
|
|
4
|
-
import type { NodeMetadata, Workflow, ExecutionResult, PortConfig } from '../types/index.js';
|
|
4
|
+
import type { NodeMetadata, Workflow, ExecutionResult, PortConfig, CategoryDefinition } from '../types/index.js';
|
|
5
5
|
/**
|
|
6
6
|
* HTTP API client for FlowDrop
|
|
7
7
|
*/
|
|
@@ -80,6 +80,10 @@ export declare class FlowDropApiClient {
|
|
|
80
80
|
* Fetch port configuration
|
|
81
81
|
*/
|
|
82
82
|
getPortConfig(): Promise<PortConfig>;
|
|
83
|
+
/**
|
|
84
|
+
* Fetch category definitions
|
|
85
|
+
*/
|
|
86
|
+
getCategories(): Promise<CategoryDefinition[]>;
|
|
83
87
|
/**
|
|
84
88
|
* Fetch pipeline data including job information and status
|
|
85
89
|
*/
|
package/dist/api/client.js
CHANGED
|
@@ -215,6 +215,16 @@ export class FlowDropApiClient {
|
|
|
215
215
|
}
|
|
216
216
|
return response.data;
|
|
217
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Fetch category definitions
|
|
220
|
+
*/
|
|
221
|
+
async getCategories() {
|
|
222
|
+
const response = await this.request('/categories');
|
|
223
|
+
if (!response.success || !response.data) {
|
|
224
|
+
throw new Error(response.error || 'Failed to fetch categories');
|
|
225
|
+
}
|
|
226
|
+
return response.data;
|
|
227
|
+
}
|
|
218
228
|
/**
|
|
219
229
|
* Fetch pipeline data including job information and status
|
|
220
230
|
*/
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import Icon from '@iconify/svelte';
|
|
11
11
|
import { getNodeIcon, getCategoryIcon } from '../utils/icons.js';
|
|
12
12
|
import { getCategoryColorToken } from '../utils/colors.js';
|
|
13
|
+
import { getCategoryLabel } from '../stores/categoriesStore.js';
|
|
13
14
|
import { SvelteSet } from 'svelte/reactivity';
|
|
14
15
|
import { uiSettings, updateSettings } from '../stores/settingsStore.js';
|
|
15
16
|
|
|
@@ -142,29 +143,11 @@
|
|
|
142
143
|
}
|
|
143
144
|
|
|
144
145
|
/**
|
|
145
|
-
* Get category display name
|
|
146
|
+
* Get category display name from the categories store.
|
|
147
|
+
* Falls back to auto-capitalizing the category machine name.
|
|
146
148
|
*/
|
|
147
149
|
function getCategoryDisplayName(category: NodeCategory): string {
|
|
148
|
-
|
|
149
|
-
triggers: 'Triggers',
|
|
150
|
-
inputs: 'Inputs',
|
|
151
|
-
outputs: 'Outputs',
|
|
152
|
-
prompts: 'Prompts',
|
|
153
|
-
models: 'Models',
|
|
154
|
-
processing: 'Processing',
|
|
155
|
-
logic: 'Logic',
|
|
156
|
-
data: 'Data',
|
|
157
|
-
tools: 'Tools',
|
|
158
|
-
helpers: 'Helpers',
|
|
159
|
-
'vector stores': 'Vector Stores',
|
|
160
|
-
embeddings: 'Embeddings',
|
|
161
|
-
memories: 'Memories',
|
|
162
|
-
agents: 'Agents',
|
|
163
|
-
ai: 'AI',
|
|
164
|
-
interrupts: 'Interrupts',
|
|
165
|
-
bundles: 'Bundles'
|
|
166
|
-
};
|
|
167
|
-
return names[category] || category;
|
|
150
|
+
return getCategoryLabel(category);
|
|
168
151
|
}
|
|
169
152
|
|
|
170
153
|
/**
|
|
@@ -140,6 +140,21 @@
|
|
|
140
140
|
title: 'Fit View on Load',
|
|
141
141
|
description: 'Automatically fit workflow to view when loading',
|
|
142
142
|
default: true
|
|
143
|
+
},
|
|
144
|
+
proximityConnect: {
|
|
145
|
+
type: 'boolean',
|
|
146
|
+
title: 'Proximity Connect',
|
|
147
|
+
description:
|
|
148
|
+
'Auto-connect compatible ports when dragging nodes near each other',
|
|
149
|
+
default: false
|
|
150
|
+
},
|
|
151
|
+
proximityConnectDistance: {
|
|
152
|
+
type: 'number',
|
|
153
|
+
title: 'Proximity Distance',
|
|
154
|
+
description: 'Distance threshold in pixels for proximity connect',
|
|
155
|
+
minimum: 50,
|
|
156
|
+
maximum: 500,
|
|
157
|
+
default: 150
|
|
143
158
|
}
|
|
144
159
|
}
|
|
145
160
|
},
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<script lang="ts">
|
|
9
9
|
import Icon from '@iconify/svelte';
|
|
10
|
-
|
|
11
|
-
import { theme, resolvedTheme, cycleTheme } from '../stores/settingsStore.js';
|
|
10
|
+
import { theme, resolvedTheme, cycleTheme } from '../stores/themeStore.js';
|
|
12
11
|
import type { ThemePreference } from '../types/settings.js';
|
|
13
12
|
|
|
14
13
|
/**
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
type ColorMode
|
|
17
17
|
} from '@xyflow/svelte';
|
|
18
18
|
import '@xyflow/svelte/dist/style.css';
|
|
19
|
-
import { resolvedTheme
|
|
19
|
+
import { resolvedTheme } from '../stores/themeStore.js';
|
|
20
|
+
import { editorSettings, behaviorSettings } from '../stores/settingsStore.js';
|
|
20
21
|
import type {
|
|
21
22
|
WorkflowNode as WorkflowNodeType,
|
|
22
23
|
NodeMetadata,
|
|
@@ -42,6 +43,10 @@
|
|
|
42
43
|
import { areNodeArraysEqual, areEdgeArraysEqual, throttle } from '../utils/performanceUtils.js';
|
|
43
44
|
import { Toaster } from 'svelte-5-french-toast';
|
|
44
45
|
import { flowdropToastOptions, FLOWDROP_TOASTER_CLASS } from '../services/toastService.js';
|
|
46
|
+
import {
|
|
47
|
+
ProximityConnectHelper,
|
|
48
|
+
type ProximityEdgeCandidate
|
|
49
|
+
} from '../helpers/proximityConnect.js';
|
|
45
50
|
|
|
46
51
|
interface Props {
|
|
47
52
|
nodes?: NodeMetadata[];
|
|
@@ -69,6 +74,9 @@
|
|
|
69
74
|
// Track if we're currently dragging a node (for history debouncing)
|
|
70
75
|
let isDraggingNode = $state(false);
|
|
71
76
|
|
|
77
|
+
// Proximity connect state
|
|
78
|
+
let currentProximityCandidates = $state<ProximityEdgeCandidate[]>([]);
|
|
79
|
+
|
|
72
80
|
// Track the workflow ID we're currently editing to detect workflow switches
|
|
73
81
|
let currentWorkflowId: string | null = null;
|
|
74
82
|
|
|
@@ -334,6 +342,46 @@
|
|
|
334
342
|
*/
|
|
335
343
|
function handleNodeDragStart(): void {
|
|
336
344
|
isDraggingNode = true;
|
|
345
|
+
// Clear any leftover proximity previews
|
|
346
|
+
currentProximityCandidates = [];
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Handle node drag - compute proximity connect preview edges
|
|
351
|
+
* Called continuously during drag if proximity connect is enabled
|
|
352
|
+
*/
|
|
353
|
+
function handleNodeDrag({
|
|
354
|
+
targetNode
|
|
355
|
+
}: {
|
|
356
|
+
targetNode: WorkflowNodeType | null;
|
|
357
|
+
nodes: WorkflowNodeType[];
|
|
358
|
+
event: MouseEvent | TouchEvent;
|
|
359
|
+
}): void {
|
|
360
|
+
if (!$editorSettings.proximityConnect || !targetNode || props.readOnly || props.lockWorkflow) {
|
|
361
|
+
if (currentProximityCandidates.length > 0) {
|
|
362
|
+
flowEdges = ProximityConnectHelper.removePreviewEdges(flowEdges);
|
|
363
|
+
currentProximityCandidates = [];
|
|
364
|
+
}
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Remove previous preview edges
|
|
369
|
+
const baseEdges = ProximityConnectHelper.removePreviewEdges(flowEdges);
|
|
370
|
+
|
|
371
|
+
// Find the best compatible edge with nearby nodes
|
|
372
|
+
const candidates = ProximityConnectHelper.findCompatibleEdges(
|
|
373
|
+
targetNode,
|
|
374
|
+
flowNodes,
|
|
375
|
+
baseEdges,
|
|
376
|
+
$editorSettings.proximityConnectDistance
|
|
377
|
+
);
|
|
378
|
+
|
|
379
|
+
// Create preview edges
|
|
380
|
+
const previews = ProximityConnectHelper.createPreviewEdges(candidates);
|
|
381
|
+
|
|
382
|
+
// Update state
|
|
383
|
+
currentProximityCandidates = candidates;
|
|
384
|
+
flowEdges = [...baseEdges, ...previews];
|
|
337
385
|
}
|
|
338
386
|
|
|
339
387
|
/**
|
|
@@ -344,6 +392,38 @@
|
|
|
344
392
|
*/
|
|
345
393
|
function handleNodeDragStop(): void {
|
|
346
394
|
isDraggingNode = false;
|
|
395
|
+
|
|
396
|
+
// Finalize proximity connect if there are candidates
|
|
397
|
+
if ($editorSettings.proximityConnect && currentProximityCandidates.length > 0) {
|
|
398
|
+
// Remove all preview edges
|
|
399
|
+
const baseEdges = ProximityConnectHelper.removePreviewEdges(flowEdges);
|
|
400
|
+
|
|
401
|
+
// Create permanent edges from candidates
|
|
402
|
+
const permanentEdges = ProximityConnectHelper.createPermanentEdges(
|
|
403
|
+
currentProximityCandidates
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
// Apply proper styling to each new permanent edge
|
|
407
|
+
for (const edge of permanentEdges) {
|
|
408
|
+
const sourceNode = flowNodes.find((n) => n.id === edge.source);
|
|
409
|
+
const targetNode = flowNodes.find((n) => n.id === edge.target);
|
|
410
|
+
if (sourceNode && targetNode) {
|
|
411
|
+
EdgeStylingHelper.applyConnectionStyling(edge, sourceNode, targetNode);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Set final edges
|
|
416
|
+
flowEdges = [...baseEdges, ...permanentEdges];
|
|
417
|
+
|
|
418
|
+
// Clear proximity state
|
|
419
|
+
currentProximityCandidates = [];
|
|
420
|
+
|
|
421
|
+
// Update workflow
|
|
422
|
+
if (currentWorkflow) {
|
|
423
|
+
updateCurrentWorkflowFromSvelteFlow();
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
347
427
|
// Push the current state AFTER the drag completed
|
|
348
428
|
if (currentWorkflow) {
|
|
349
429
|
workflowActions.pushHistory('Move node', currentWorkflow);
|
|
@@ -636,6 +716,7 @@
|
|
|
636
716
|
onbeforedelete={handleBeforeDelete}
|
|
637
717
|
ondelete={handleNodesDelete}
|
|
638
718
|
onnodedragstart={handleNodeDragStart}
|
|
719
|
+
onnodedrag={handleNodeDrag}
|
|
639
720
|
onnodedragstop={handleNodeDragStop}
|
|
640
721
|
minZoom={0.2}
|
|
641
722
|
maxZoom={3}
|
|
@@ -884,4 +965,19 @@
|
|
|
884
965
|
filter: drop-shadow(0 0 3px rgba(139, 92, 246, 0.4));
|
|
885
966
|
opacity: 1;
|
|
886
967
|
}
|
|
968
|
+
|
|
969
|
+
/* Proximity Connect Preview Edge: animated dashed line */
|
|
970
|
+
:global(.flowdrop--edge--proximity-preview path.svelte-flow__edge-path) {
|
|
971
|
+
stroke: var(--fd-primary);
|
|
972
|
+
stroke-width: 2;
|
|
973
|
+
stroke-dasharray: 5 5;
|
|
974
|
+
opacity: 0.6;
|
|
975
|
+
animation: flowdrop-proximity-dash 0.5s linear infinite;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
@keyframes flowdrop-proximity-dash {
|
|
979
|
+
to {
|
|
980
|
+
stroke-dashoffset: -10;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
887
983
|
</style>
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
import type { FieldSchema } from './types.js';
|
|
45
45
|
import { getSchemaOptions } from './types.js';
|
|
46
46
|
import type { WorkflowNode, WorkflowEdge, AuthProvider } from '../../types/index.js';
|
|
47
|
-
import { resolvedTheme } from '../../stores/
|
|
47
|
+
import { resolvedTheme } from '../../stores/themeStore.js';
|
|
48
48
|
|
|
49
49
|
interface Props {
|
|
50
50
|
/** Unique key/id for the field */
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
import FormCheckboxGroup from './FormCheckboxGroup.svelte';
|
|
44
44
|
import FormArray from './FormArray.svelte';
|
|
45
45
|
import { resolveFieldComponent } from '../../form/fieldRegistry.js';
|
|
46
|
-
import { resolvedTheme } from '../../stores/
|
|
46
|
+
import { resolvedTheme } from '../../stores/themeStore.js';
|
|
47
47
|
import type { FieldSchema } from './types.js';
|
|
48
48
|
import { getSchemaOptions } from './types.js';
|
|
49
49
|
|
|
@@ -61,6 +61,17 @@
|
|
|
61
61
|
'Tool'
|
|
62
62
|
);
|
|
63
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Instance-specific badge label override from config.
|
|
66
|
+
* Falls back to metadata badge or default 'TOOL' if not set.
|
|
67
|
+
* This allows users to customize the badge text per-instance via config.
|
|
68
|
+
*/
|
|
69
|
+
const displayBadge = $derived(
|
|
70
|
+
(props.data.config?.instanceBadge as string) ||
|
|
71
|
+
(props.data.metadata?.badge as string) ||
|
|
72
|
+
'TOOL'
|
|
73
|
+
);
|
|
74
|
+
|
|
64
75
|
/**
|
|
65
76
|
* Instance-specific description override from config.
|
|
66
77
|
* Falls back to metadata description or toolDescription config if not set.
|
|
@@ -185,7 +196,7 @@
|
|
|
185
196
|
</div>
|
|
186
197
|
|
|
187
198
|
<!-- Tool Badge - tinted style matching icon wrappers -->
|
|
188
|
-
<div class="flowdrop-tool-node__badge">
|
|
199
|
+
<div class="flowdrop-tool-node__badge">{displayBadge}</div>
|
|
189
200
|
</div>
|
|
190
201
|
|
|
191
202
|
<!-- Tool Description - uses instanceDescription override if set -->
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default category definitions for FlowDrop
|
|
3
|
+
* Provides built-in categories with icons, colors, and display labels.
|
|
4
|
+
* These serve as fallbacks when the /categories API endpoint is unavailable.
|
|
5
|
+
*/
|
|
6
|
+
import type { CategoryDefinition } from '../types/index.js';
|
|
7
|
+
export declare const DEFAULT_CATEGORIES: CategoryDefinition[];
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default category definitions for FlowDrop
|
|
3
|
+
* Provides built-in categories with icons, colors, and display labels.
|
|
4
|
+
* These serve as fallbacks when the /categories API endpoint is unavailable.
|
|
5
|
+
*/
|
|
6
|
+
export const DEFAULT_CATEGORIES = [
|
|
7
|
+
{
|
|
8
|
+
name: 'triggers',
|
|
9
|
+
label: 'Triggers',
|
|
10
|
+
icon: 'mdi:lightning-bolt',
|
|
11
|
+
color: 'var(--fd-node-cyan)',
|
|
12
|
+
weight: 0
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: 'inputs',
|
|
16
|
+
label: 'Inputs',
|
|
17
|
+
icon: 'mdi:arrow-down-circle',
|
|
18
|
+
color: 'var(--fd-node-emerald)',
|
|
19
|
+
weight: 1
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'outputs',
|
|
23
|
+
label: 'Outputs',
|
|
24
|
+
icon: 'mdi:arrow-up-circle',
|
|
25
|
+
color: 'var(--fd-node-blue)',
|
|
26
|
+
weight: 2
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'prompts',
|
|
30
|
+
label: 'Prompts',
|
|
31
|
+
icon: 'mdi:message-text',
|
|
32
|
+
color: 'var(--fd-node-amber)',
|
|
33
|
+
weight: 3
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'models',
|
|
37
|
+
label: 'Models',
|
|
38
|
+
icon: 'mdi:robot',
|
|
39
|
+
color: 'var(--fd-node-indigo)',
|
|
40
|
+
weight: 4
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'processing',
|
|
44
|
+
label: 'Processing',
|
|
45
|
+
icon: 'mdi:cog',
|
|
46
|
+
color: 'var(--fd-node-teal)',
|
|
47
|
+
weight: 5
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'logic',
|
|
51
|
+
label: 'Logic',
|
|
52
|
+
icon: 'mdi:source-branch',
|
|
53
|
+
color: 'var(--fd-node-purple)',
|
|
54
|
+
weight: 6
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'data',
|
|
58
|
+
label: 'Data',
|
|
59
|
+
icon: 'mdi:database',
|
|
60
|
+
color: 'var(--fd-node-orange)',
|
|
61
|
+
weight: 7
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'tools',
|
|
65
|
+
label: 'Tools',
|
|
66
|
+
icon: 'mdi:wrench',
|
|
67
|
+
color: 'var(--fd-node-amber)',
|
|
68
|
+
weight: 8
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: 'helpers',
|
|
72
|
+
label: 'Helpers',
|
|
73
|
+
icon: 'mdi:help-circle',
|
|
74
|
+
color: 'var(--fd-node-slate)',
|
|
75
|
+
weight: 9
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'vector stores',
|
|
79
|
+
label: 'Vector Stores',
|
|
80
|
+
icon: 'mdi:vector-square',
|
|
81
|
+
color: 'var(--fd-node-emerald)',
|
|
82
|
+
weight: 10
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: 'embeddings',
|
|
86
|
+
label: 'Embeddings',
|
|
87
|
+
icon: 'mdi:vector-polygon',
|
|
88
|
+
color: 'var(--fd-node-indigo)',
|
|
89
|
+
weight: 11
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'memories',
|
|
93
|
+
label: 'Memories',
|
|
94
|
+
icon: 'mdi:brain',
|
|
95
|
+
color: 'var(--fd-node-blue)',
|
|
96
|
+
weight: 12
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'agents',
|
|
100
|
+
label: 'Agents',
|
|
101
|
+
icon: 'mdi:account-cog',
|
|
102
|
+
color: 'var(--fd-node-teal)',
|
|
103
|
+
weight: 13
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: 'ai',
|
|
107
|
+
label: 'AI',
|
|
108
|
+
icon: 'mdi:shimmer',
|
|
109
|
+
color: 'var(--fd-node-purple)',
|
|
110
|
+
weight: 14
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'interrupts',
|
|
114
|
+
label: 'Interrupts',
|
|
115
|
+
icon: 'mdi:hand-back-left',
|
|
116
|
+
color: 'var(--fd-node-red)',
|
|
117
|
+
weight: 15
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: 'bundles',
|
|
121
|
+
label: 'Bundles',
|
|
122
|
+
icon: 'mdi:package-variant',
|
|
123
|
+
color: 'var(--fd-node-slate)',
|
|
124
|
+
weight: 16
|
|
125
|
+
}
|
|
126
|
+
];
|
package/dist/config/endpoints.js
CHANGED
package/dist/core/index.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* import { getStatusColor, createDefaultExecutionInfo } from "@d34dman/flowdrop/core";
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
|
-
export type { NodeCategory, NodeDataType, NodePort, DynamicPort, Branch, NodeMetadata, NodeExtensions, NodeUIExtensions, ConfigValues, WorkflowNode, WorkflowEdge, Workflow, ApiResponse, NodesResponse, WorkflowResponse, WorkflowsResponse, ExecutionStatus, ExecutionResult, FlowDropConfig, WorkflowEvents, BuiltinNodeType, PortConfig, PortCompatibilityRule, ConfigSchema, ConfigProperty, HttpMethod, DynamicSchemaEndpoint, ExternalEditLink, ConfigEditOptions, EdgeCategory } from '../types/index.js';
|
|
17
|
+
export type { NodeCategory, BuiltinNodeCategory, CategoryDefinition, NodeDataType, NodePort, DynamicPort, Branch, NodeMetadata, NodeExtensions, NodeUIExtensions, ConfigValues, WorkflowNode, WorkflowEdge, Workflow, ApiResponse, NodesResponse, WorkflowResponse, WorkflowsResponse, ExecutionStatus, ExecutionResult, FlowDropConfig, WorkflowEvents, BuiltinNodeType, PortConfig, PortCompatibilityRule, ConfigSchema, ConfigProperty, HttpMethod, DynamicSchemaEndpoint, ExternalEditLink, ConfigEditOptions, EdgeCategory } from '../types/index.js';
|
|
18
18
|
export type { WorkflowEditorConfig, EditorFeatures, UIConfig, APIConfig, ExecutionConfig, StorageConfig } from '../types/config.js';
|
|
19
19
|
export type { AuthProvider, StaticAuthConfig, CallbackAuthConfig } from '../types/auth.js';
|
|
20
20
|
export type { WorkflowChangeType, FlowDropEventHandlers, FlowDropFeatures } from '../types/events.js';
|
package/dist/editor/index.d.ts
CHANGED
|
@@ -74,6 +74,7 @@ export { currentSession, sessions, messages, isExecuting, isLoading, error as pl
|
|
|
74
74
|
export { saveWorkflow, updateWorkflow, getWorkflow, getWorkflows, deleteWorkflow, getWorkflowCount, initializeSampleWorkflows } from '../services/workflowStorage.js';
|
|
75
75
|
export { globalSaveWorkflow, globalExportWorkflow, initializeGlobalSave } from '../services/globalSave.js';
|
|
76
76
|
export { fetchPortConfig, validatePortConfig } from '../services/portConfigApi.js';
|
|
77
|
+
export { fetchCategories, validateCategories } from '../services/categoriesApi.js';
|
|
77
78
|
export { fetchDynamicSchema, resolveExternalEditUrl, getEffectiveConfigEditOptions, clearSchemaCache, invalidateSchemaCache, hasConfigEditOptions, shouldShowExternalEdit, shouldUseDynamicSchema } from '../services/dynamicSchemaService.js';
|
|
78
79
|
export { getDraftStorageKey, saveDraft, loadDraft, deleteDraft, hasDraft, getDraftMetadata, DraftAutoSaveManager } from '../services/draftStorage.js';
|
|
79
80
|
export { FlowDropApiClient } from '../api/client.js';
|
package/dist/editor/index.js
CHANGED
|
@@ -115,6 +115,7 @@ export { currentSession, sessions, messages, isExecuting, isLoading, error as pl
|
|
|
115
115
|
export { saveWorkflow, updateWorkflow, getWorkflow, getWorkflows, deleteWorkflow, getWorkflowCount, initializeSampleWorkflows } from '../services/workflowStorage.js';
|
|
116
116
|
export { globalSaveWorkflow, globalExportWorkflow, initializeGlobalSave } from '../services/globalSave.js';
|
|
117
117
|
export { fetchPortConfig, validatePortConfig } from '../services/portConfigApi.js';
|
|
118
|
+
export { fetchCategories, validateCategories } from '../services/categoriesApi.js';
|
|
118
119
|
export { fetchDynamicSchema, resolveExternalEditUrl, getEffectiveConfigEditOptions, clearSchemaCache, invalidateSchemaCache, hasConfigEditOptions, shouldShowExternalEdit, shouldUseDynamicSchema } from '../services/dynamicSchemaService.js';
|
|
119
120
|
export { getDraftStorageKey, saveDraft, loadDraft, deleteDraft, hasDraft, getDraftMetadata, DraftAutoSaveManager } from '../services/draftStorage.js';
|
|
120
121
|
// ============================================================================
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proximity Connect Helper
|
|
3
|
+
*
|
|
4
|
+
* Provides type-aware proximity connect logic for the workflow editor.
|
|
5
|
+
* When a node is dragged near another node, this helper finds the best
|
|
6
|
+
* compatible port pair and creates a preview/permanent edge.
|
|
7
|
+
*/
|
|
8
|
+
import type { WorkflowNode as WorkflowNodeType, WorkflowEdge, NodePort } from '../types/index.js';
|
|
9
|
+
/** A candidate proximity edge before it is finalized */
|
|
10
|
+
export interface ProximityEdgeCandidate {
|
|
11
|
+
id: string;
|
|
12
|
+
source: string;
|
|
13
|
+
target: string;
|
|
14
|
+
sourceHandle: string;
|
|
15
|
+
targetHandle: string;
|
|
16
|
+
sourcePortDataType: string;
|
|
17
|
+
targetPortDataType: string;
|
|
18
|
+
}
|
|
19
|
+
export declare class ProximityConnectHelper {
|
|
20
|
+
/**
|
|
21
|
+
* Get ALL ports (static + dynamic + gateway branches) for a node.
|
|
22
|
+
*/
|
|
23
|
+
static getAllPorts(node: WorkflowNodeType, direction: 'input' | 'output'): NodePort[];
|
|
24
|
+
/**
|
|
25
|
+
* Build handle ID in the standard format.
|
|
26
|
+
*/
|
|
27
|
+
static buildHandleId(nodeId: string, direction: 'input' | 'output', portId: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Calculate center-to-center Euclidean distance between two nodes.
|
|
30
|
+
*/
|
|
31
|
+
static getNodeDistance(nodeA: {
|
|
32
|
+
position: {
|
|
33
|
+
x: number;
|
|
34
|
+
y: number;
|
|
35
|
+
};
|
|
36
|
+
measured?: {
|
|
37
|
+
width?: number;
|
|
38
|
+
height?: number;
|
|
39
|
+
};
|
|
40
|
+
}, nodeB: {
|
|
41
|
+
position: {
|
|
42
|
+
x: number;
|
|
43
|
+
y: number;
|
|
44
|
+
};
|
|
45
|
+
measured?: {
|
|
46
|
+
width?: number;
|
|
47
|
+
height?: number;
|
|
48
|
+
};
|
|
49
|
+
}): number;
|
|
50
|
+
/**
|
|
51
|
+
* Find the single best compatible edge between a dragged node and nearby nodes.
|
|
52
|
+
*
|
|
53
|
+
* Algorithm:
|
|
54
|
+
* 1. Find the closest node within minDistance
|
|
55
|
+
* 2. Check both directions (dragged->nearby and nearby->dragged)
|
|
56
|
+
* 3. Return the first exact-type match, or first compatible match
|
|
57
|
+
* 4. Skip pairs where an edge already exists or input handle is already connected
|
|
58
|
+
*
|
|
59
|
+
* @returns Array with at most ONE ProximityEdgeCandidate
|
|
60
|
+
*/
|
|
61
|
+
static findCompatibleEdges(draggedNode: WorkflowNodeType, allNodes: WorkflowNodeType[], existingEdges: WorkflowEdge[], minDistance: number): ProximityEdgeCandidate[];
|
|
62
|
+
/**
|
|
63
|
+
* Convert candidates to temporary (preview) WorkflowEdge objects with dashed styling.
|
|
64
|
+
*/
|
|
65
|
+
static createPreviewEdges(candidates: ProximityEdgeCandidate[]): WorkflowEdge[];
|
|
66
|
+
/**
|
|
67
|
+
* Convert candidates to permanent WorkflowEdge objects.
|
|
68
|
+
*/
|
|
69
|
+
static createPermanentEdges(candidates: ProximityEdgeCandidate[]): WorkflowEdge[];
|
|
70
|
+
/**
|
|
71
|
+
* Check if an edge is a temporary proximity preview edge.
|
|
72
|
+
*/
|
|
73
|
+
static isProximityPreviewEdge(edge: WorkflowEdge): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Remove all proximity preview edges from an edge array.
|
|
76
|
+
*/
|
|
77
|
+
static removePreviewEdges(edges: WorkflowEdge[]): WorkflowEdge[];
|
|
78
|
+
}
|