@d34dman/flowdrop 0.0.22 → 0.0.24

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.
Files changed (44) hide show
  1. package/dist/components/App.svelte +26 -25
  2. package/dist/components/ConfigForm.svelte +141 -520
  3. package/dist/components/ConfigForm.svelte.d.ts +5 -3
  4. package/dist/components/form/FormArray.svelte +1049 -0
  5. package/dist/components/form/FormArray.svelte.d.ts +22 -0
  6. package/dist/components/form/FormCheckboxGroup.svelte +152 -0
  7. package/dist/components/form/FormCheckboxGroup.svelte.d.ts +15 -0
  8. package/dist/components/form/FormField.svelte +297 -0
  9. package/dist/components/form/FormField.svelte.d.ts +18 -0
  10. package/dist/components/form/FormFieldWrapper.svelte +133 -0
  11. package/dist/components/form/FormFieldWrapper.svelte.d.ts +18 -0
  12. package/dist/components/form/FormNumberField.svelte +109 -0
  13. package/dist/components/form/FormNumberField.svelte.d.ts +23 -0
  14. package/dist/components/form/FormRangeField.svelte +252 -0
  15. package/dist/components/form/FormRangeField.svelte.d.ts +21 -0
  16. package/dist/components/form/FormSelect.svelte +126 -0
  17. package/dist/components/form/FormSelect.svelte.d.ts +18 -0
  18. package/dist/components/form/FormTextField.svelte +88 -0
  19. package/dist/components/form/FormTextField.svelte.d.ts +17 -0
  20. package/dist/components/form/FormTextarea.svelte +94 -0
  21. package/dist/components/form/FormTextarea.svelte.d.ts +19 -0
  22. package/dist/components/form/FormToggle.svelte +123 -0
  23. package/dist/components/form/FormToggle.svelte.d.ts +17 -0
  24. package/dist/components/form/index.d.ts +42 -0
  25. package/dist/components/form/index.js +46 -0
  26. package/dist/components/form/types.d.ts +224 -0
  27. package/dist/components/form/types.js +29 -0
  28. package/dist/components/nodes/GatewayNode.svelte +76 -16
  29. package/dist/components/nodes/SimpleNode.svelte +41 -5
  30. package/dist/components/nodes/SimpleNode.svelte.d.ts +2 -1
  31. package/dist/components/nodes/SquareNode.svelte +41 -5
  32. package/dist/components/nodes/SquareNode.svelte.d.ts +2 -1
  33. package/dist/components/nodes/WorkflowNode.svelte +88 -5
  34. package/dist/index.d.ts +2 -3
  35. package/dist/index.js +1 -3
  36. package/dist/stores/workflowStore.d.ts +15 -0
  37. package/dist/stores/workflowStore.js +28 -0
  38. package/dist/types/index.d.ts +176 -1
  39. package/dist/types/index.js +16 -0
  40. package/package.json +3 -3
  41. package/dist/config/demo.d.ts +0 -58
  42. package/dist/config/demo.js +0 -142
  43. package/dist/data/samples.d.ts +0 -51
  44. package/dist/data/samples.js +0 -3245
@@ -3,20 +3,18 @@
3
3
  Visual representation of gateway/branch nodes with branching flow indicators
4
4
  Shows active branches and execution paths
5
5
  Styled with BEM syntax following WorkflowNode pattern
6
+
7
+ UI Extensions Support:
8
+ - hideUnconnectedHandles: Hides ports that are not connected to reduce visual clutter
6
9
  -->
7
10
 
8
11
  <script lang="ts">
9
12
  import { Position, Handle } from '@xyflow/svelte';
10
- import type { WorkflowNode } from '../../types/index.js';
13
+ import type { WorkflowNode, NodePort, Branch } from '../../types/index.js';
11
14
  import Icon from '@iconify/svelte';
12
15
  import { getNodeIcon } from '../../utils/icons.js';
13
16
  import { getDataTypeColorToken, getCategoryColorToken } from '../../utils/colors.js';
14
-
15
- // Define simplified branch interface - conditions are handled by backend
16
- interface Branch {
17
- name: string;
18
- label: string;
19
- }
17
+ import { connectedHandles } from '../../stores/workflowStore.js';
20
18
 
21
19
  interface Props {
22
20
  data: WorkflowNode['data'] & {
@@ -28,10 +26,70 @@
28
26
 
29
27
  let props: Props = $props();
30
28
 
29
+ /**
30
+ * Get the hideUnconnectedHandles setting from extensions
31
+ * Merges node type defaults with instance overrides
32
+ */
33
+ const hideUnconnectedHandles = $derived(() => {
34
+ const typeDefault = props.data.metadata?.extensions?.ui?.hideUnconnectedHandles ?? false;
35
+ const instanceOverride = props.data.extensions?.ui?.hideUnconnectedHandles;
36
+ return instanceOverride ?? typeDefault;
37
+ });
38
+
39
+ /**
40
+ * Check if a port should be visible based on connection state and settings
41
+ * @param port - The port to check
42
+ * @param type - Whether this is an 'input' or 'output' port
43
+ * @returns true if the port should be visible
44
+ */
45
+ function isPortVisible(port: NodePort, type: 'input' | 'output'): boolean {
46
+ // Always show if hideUnconnectedHandles is disabled
47
+ if (!hideUnconnectedHandles()) {
48
+ return true;
49
+ }
50
+
51
+ // Always show required ports
52
+ if (port.required) {
53
+ return true;
54
+ }
55
+
56
+ // Check if port is connected
57
+ const handleId = `${props.data.nodeId}-${type}-${port.id}`;
58
+ return $connectedHandles.has(handleId);
59
+ }
60
+
61
+ /**
62
+ * Derived list of visible input ports based on hideUnconnectedHandles setting
63
+ */
64
+ const visibleInputPorts = $derived(
65
+ props.data.metadata.inputs.filter((port) => isPortVisible(port, 'input'))
66
+ );
67
+
68
+ /**
69
+ * Check if a branch output should be visible based on connection state
70
+ * @param branchName - The branch name to check
71
+ * @returns true if the branch should be visible
72
+ */
73
+ function isBranchVisible(branchName: string): boolean {
74
+ // Always show if hideUnconnectedHandles is disabled
75
+ if (!hideUnconnectedHandles()) {
76
+ return true;
77
+ }
78
+
79
+ // Check if branch output is connected
80
+ const handleId = `${props.data.nodeId}-output-${branchName}`;
81
+ return $connectedHandles.has(handleId);
82
+ }
83
+
31
84
  // Gateway-specific data - branches are calculated at runtime from config
32
85
  let branches = $derived((props.data.config?.branches as Branch[]) || []);
33
86
  let activeBranches = $derived((props.data.executionInfo as any)?.output?.active_branches || []);
34
87
 
88
+ /**
89
+ * Derived list of visible branches based on hideUnconnectedHandles setting
90
+ */
91
+ const visibleBranches = $derived(branches.filter((branch) => isBranchVisible(branch.name)));
92
+
35
93
  /**
36
94
  * Handle node click - only handle selection, no config opening
37
95
  */
@@ -107,14 +165,14 @@
107
165
  </p>
108
166
  </div>
109
167
 
110
- <!-- Input Ports Container -->
111
- {#if props.data.metadata.inputs.length > 0}
168
+ <!-- Input Ports Container (filtered based on hideUnconnectedHandles) -->
169
+ {#if visibleInputPorts.length > 0}
112
170
  <div class="flowdrop-workflow-node__ports">
113
171
  <div class="flowdrop-workflow-node__ports-header">
114
172
  <h5 class="flowdrop-workflow-node__ports-title">Inputs</h5>
115
173
  </div>
116
174
  <div class="flowdrop-workflow-node__ports-list">
117
- {#each props.data.metadata.inputs as port (port.id)}
175
+ {#each visibleInputPorts as port (port.id)}
118
176
  <div class="flowdrop-workflow-node__port">
119
177
  <!-- Input Handle -->
120
178
  <Handle
@@ -158,17 +216,17 @@
158
216
  </div>
159
217
  {/if}
160
218
 
161
- <!-- Branches Section (Output Ports) -->
162
- {#if branches.length > 0}
219
+ <!-- Branches Section (Output Ports) - filtered based on hideUnconnectedHandles -->
220
+ {#if visibleBranches.length > 0}
163
221
  <div class="flowdrop-workflow-node__ports">
164
222
  <div class="flowdrop-workflow-node__ports-header">
165
223
  <h5 class="flowdrop-workflow-node__ports-title">
166
224
  <Icon icon="mdi:source-branch" />
167
- <span>Branches ({branches.length})</span>
225
+ <span>Branches ({visibleBranches.length})</span>
168
226
  </h5>
169
227
  </div>
170
228
  <div class="flowdrop-workflow-node__ports-list">
171
- {#each branches as branch (branch.name)}
229
+ {#each visibleBranches as branch (branch.name)}
172
230
  {@const isActive = isBranchActive(branch.name)}
173
231
  <div class="flowdrop-workflow-node__port">
174
232
  <!-- Port Info -->
@@ -185,7 +243,7 @@
185
243
  class="flowdrop-text--xs flowdrop-font--medium"
186
244
  class:flowdrop-text--active={isActive}
187
245
  >
188
- {branch.name}
246
+ {branch.label || branch.name}
189
247
  </span>
190
248
  <span
191
249
  class="flowdrop-badge flowdrop-badge--sm"
@@ -213,7 +271,8 @@
213
271
  {/each}
214
272
  </div>
215
273
  </div>
216
- {:else}
274
+ {:else if branches.length === 0}
275
+ <!-- No branches configured at all -->
217
276
  <div class="flowdrop-workflow-node__ports">
218
277
  <div class="workflow-node__no-branches">
219
278
  <Icon icon="mdi:alert-circle-outline" />
@@ -221,6 +280,7 @@
221
280
  </div>
222
281
  </div>
223
282
  {/if}
283
+ <!-- Note: When all branches are hidden due to hideUnconnectedHandles, we don't show anything -->
224
284
 
225
285
  <!-- Config button -->
226
286
  <button
@@ -2,13 +2,17 @@
2
2
  Simple Node Component
3
3
  A simple node with optional input and output ports
4
4
  Styled with BEM syntax
5
+
6
+ UI Extensions Support:
7
+ - hideUnconnectedHandles: Hides trigger ports that are not connected to reduce visual clutter
5
8
  -->
6
9
 
7
10
  <script lang="ts">
8
11
  import { Position, Handle } from '@xyflow/svelte';
9
- import type { ConfigValues, NodeMetadata } from '../../types/index.js';
12
+ import type { ConfigValues, NodeMetadata, NodeExtensions } from '../../types/index.js';
10
13
  import Icon from '@iconify/svelte';
11
14
  import { getDataTypeColor } from '../../utils/colors.js';
15
+ import { connectedHandles } from '../../stores/workflowStore.js';
12
16
 
13
17
  const props = $props<{
14
18
  data: {
@@ -16,6 +20,7 @@
16
20
  config: ConfigValues;
17
21
  metadata: NodeMetadata;
18
22
  nodeId?: string;
23
+ extensions?: NodeExtensions;
19
24
  onConfigOpen?: (node: {
20
25
  id: string;
21
26
  type: string;
@@ -27,6 +32,37 @@
27
32
  isError?: boolean;
28
33
  }>();
29
34
 
35
+ /**
36
+ * Get the hideUnconnectedHandles setting from extensions
37
+ * Merges node type defaults with instance overrides
38
+ */
39
+ const hideUnconnectedHandles = $derived(() => {
40
+ const typeDefault = props.data.metadata?.extensions?.ui?.hideUnconnectedHandles ?? false;
41
+ const instanceOverride = props.data.extensions?.ui?.hideUnconnectedHandles;
42
+ return instanceOverride ?? typeDefault;
43
+ });
44
+
45
+ /**
46
+ * Check if a trigger port is connected
47
+ * @param portId - The port ID to check
48
+ * @param type - Whether this is an 'input' or 'output' port
49
+ */
50
+ function isTriggerPortConnected(portId: string, type: 'input' | 'output'): boolean {
51
+ const handleId = `${props.data.nodeId}-${type}-${portId}`;
52
+ return $connectedHandles.has(handleId);
53
+ }
54
+
55
+ /**
56
+ * Check if a trigger port should be visible
57
+ * Always shows if hideUnconnectedHandles is disabled or if port is connected
58
+ */
59
+ function shouldShowTriggerPort(portId: string, type: 'input' | 'output'): boolean {
60
+ if (!hideUnconnectedHandles()) {
61
+ return true;
62
+ }
63
+ return isTriggerPortConnected(portId, type);
64
+ }
65
+
30
66
  // Removed local config state - now using global ConfigSidebar
31
67
 
32
68
  // Prioritize metadata icon over config icon for simple nodes (metadata is the node definition)
@@ -124,8 +160,8 @@
124
160
  id={`${props.data.nodeId}-input-${firstDataInputPort.id}`}
125
161
  />
126
162
  {/if}
127
- {#if triggerInputPort}
128
- <!-- Trigger Input - positioned at bottom-left -->
163
+ {#if triggerInputPort && shouldShowTriggerPort(triggerInputPort.id, 'input')}
164
+ <!-- Trigger Input - positioned at bottom-left (hidden if hideUnconnectedHandles enabled and not connected) -->
129
165
  <Handle
130
166
  type="target"
131
167
  position={Position.Left}
@@ -217,8 +253,8 @@
217
253
  )}; border-color: '#ffffff'; top: {hasBothOutputTypes ? '25%' : '50%'}; z-index: 30;"
218
254
  />
219
255
  {/if}
220
- {#if triggerOutputPort}
221
- <!-- Trigger Output - positioned at bottom-right -->
256
+ {#if triggerOutputPort && shouldShowTriggerPort(triggerOutputPort.id, 'output')}
257
+ <!-- Trigger Output - positioned at bottom-right (hidden if hideUnconnectedHandles enabled and not connected) -->
222
258
  <Handle
223
259
  type="source"
224
260
  position={Position.Right}
@@ -1,10 +1,11 @@
1
- import type { ConfigValues, NodeMetadata } from '../../types/index.js';
1
+ import type { ConfigValues, NodeMetadata, NodeExtensions } from '../../types/index.js';
2
2
  type $$ComponentProps = {
3
3
  data: {
4
4
  label: string;
5
5
  config: ConfigValues;
6
6
  metadata: NodeMetadata;
7
7
  nodeId?: string;
8
+ extensions?: NodeExtensions;
8
9
  onConfigOpen?: (node: {
9
10
  id: string;
10
11
  type: string;
@@ -2,13 +2,17 @@
2
2
  Square Node Component
3
3
  A simple square node with optional input and output ports
4
4
  Styled with BEM syntax
5
+
6
+ UI Extensions Support:
7
+ - hideUnconnectedHandles: Hides trigger ports that are not connected to reduce visual clutter
5
8
  -->
6
9
 
7
10
  <script lang="ts">
8
11
  import { Position, Handle } from '@xyflow/svelte';
9
- import type { ConfigValues, NodeMetadata } from '../../types/index.js';
12
+ import type { ConfigValues, NodeMetadata, NodeExtensions } from '../../types/index.js';
10
13
  import Icon from '@iconify/svelte';
11
14
  import { getDataTypeColor } from '../../utils/colors.js';
15
+ import { connectedHandles } from '../../stores/workflowStore.js';
12
16
 
13
17
  const props = $props<{
14
18
  data: {
@@ -16,6 +20,7 @@
16
20
  config: ConfigValues;
17
21
  metadata: NodeMetadata;
18
22
  nodeId?: string;
23
+ extensions?: NodeExtensions;
19
24
  onConfigOpen?: (node: {
20
25
  id: string;
21
26
  type: string;
@@ -27,6 +32,37 @@
27
32
  isError?: boolean;
28
33
  }>();
29
34
 
35
+ /**
36
+ * Get the hideUnconnectedHandles setting from extensions
37
+ * Merges node type defaults with instance overrides
38
+ */
39
+ const hideUnconnectedHandles = $derived(() => {
40
+ const typeDefault = props.data.metadata?.extensions?.ui?.hideUnconnectedHandles ?? false;
41
+ const instanceOverride = props.data.extensions?.ui?.hideUnconnectedHandles;
42
+ return instanceOverride ?? typeDefault;
43
+ });
44
+
45
+ /**
46
+ * Check if a trigger port is connected
47
+ * @param portId - The port ID to check
48
+ * @param type - Whether this is an 'input' or 'output' port
49
+ */
50
+ function isTriggerPortConnected(portId: string, type: 'input' | 'output'): boolean {
51
+ const handleId = `${props.data.nodeId}-${type}-${portId}`;
52
+ return $connectedHandles.has(handleId);
53
+ }
54
+
55
+ /**
56
+ * Check if a trigger port should be visible
57
+ * Always shows if hideUnconnectedHandles is disabled or if port is connected
58
+ */
59
+ function shouldShowTriggerPort(portId: string, type: 'input' | 'output'): boolean {
60
+ if (!hideUnconnectedHandles()) {
61
+ return true;
62
+ }
63
+ return isTriggerPortConnected(portId, type);
64
+ }
65
+
30
66
  // Removed local config state - now using global ConfigSidebar
31
67
 
32
68
  // Prioritize metadata icon over config icon for square nodes (metadata is the node definition)
@@ -110,8 +146,8 @@
110
146
  id={`${props.data.nodeId}-input-${firstDataInputPort.id}`}
111
147
  />
112
148
  {/if}
113
- {#if triggerInputPort}
114
- <!-- Trigger Input - positioned at bottom-left -->
149
+ {#if triggerInputPort && shouldShowTriggerPort(triggerInputPort.id, 'input')}
150
+ <!-- Trigger Input - positioned at bottom-left (hidden if hideUnconnectedHandles enabled and not connected) -->
115
151
  <Handle
116
152
  type="target"
117
153
  position={Position.Left}
@@ -179,8 +215,8 @@
179
215
  )}; border-color: '#ffffff'; top: {hasBothOutputTypes ? '25%' : '50%'}; z-index: 30;"
180
216
  />
181
217
  {/if}
182
- {#if triggerOutputPort}
183
- <!-- Trigger Output - positioned at bottom-right -->
218
+ {#if triggerOutputPort && shouldShowTriggerPort(triggerOutputPort.id, 'output')}
219
+ <!-- Trigger Output - positioned at bottom-right (hidden if hideUnconnectedHandles enabled and not connected) -->
184
220
  <Handle
185
221
  type="source"
186
222
  position={Position.Right}
@@ -1,10 +1,11 @@
1
- import type { ConfigValues, NodeMetadata } from '../../types/index.js';
1
+ import type { ConfigValues, NodeMetadata, NodeExtensions } from '../../types/index.js';
2
2
  type $$ComponentProps = {
3
3
  data: {
4
4
  label: string;
5
5
  config: ConfigValues;
6
6
  metadata: NodeMetadata;
7
7
  nodeId?: string;
8
+ extensions?: NodeExtensions;
8
9
  onConfigOpen?: (node: {
9
10
  id: string;
10
11
  type: string;
@@ -3,14 +3,19 @@
3
3
  Renders individual nodes in the workflow editor with full functionality
4
4
  Uses SvelteFlow's Handle for connection ports
5
5
  Styled with BEM syntax
6
+
7
+ UI Extensions Support:
8
+ - hideUnconnectedHandles: Hides ports that are not connected to reduce visual clutter
6
9
  -->
7
10
 
8
11
  <script lang="ts">
9
12
  import { Position, Handle } from '@xyflow/svelte';
10
- import type { WorkflowNode } from '../../types/index.js';
13
+ import type { WorkflowNode, NodePort, DynamicPort } from '../../types/index.js';
14
+ import { dynamicPortToNodePort } from '../../types/index.js';
11
15
  import Icon from '@iconify/svelte';
12
16
  import { getNodeIcon } from '../../utils/icons.js';
13
17
  import { getDataTypeColorToken, getCategoryColorToken } from '../../utils/colors.js';
18
+ import { connectedHandles } from '../../stores/workflowStore.js';
14
19
 
15
20
  interface Props {
16
21
  data: WorkflowNode['data'] & {
@@ -23,6 +28,84 @@
23
28
  let props: Props = $props();
24
29
  let isHandleInteraction = $state(false);
25
30
 
31
+ /**
32
+ * Get the hideUnconnectedHandles setting from extensions
33
+ * Merges node type defaults with instance overrides
34
+ */
35
+ const hideUnconnectedHandles = $derived(() => {
36
+ const typeDefault = props.data.metadata?.extensions?.ui?.hideUnconnectedHandles ?? false;
37
+ const instanceOverride = props.data.extensions?.ui?.hideUnconnectedHandles;
38
+ return instanceOverride ?? typeDefault;
39
+ });
40
+
41
+ /**
42
+ * Dynamic inputs from config - user-defined input ports
43
+ * Similar to how branches work in GatewayNode
44
+ */
45
+ const dynamicInputs = $derived(
46
+ ((props.data.config?.dynamicInputs as DynamicPort[]) || []).map((port) =>
47
+ dynamicPortToNodePort(port, 'input')
48
+ )
49
+ );
50
+
51
+ /**
52
+ * Dynamic outputs from config - user-defined output ports
53
+ * Similar to how branches work in GatewayNode
54
+ */
55
+ const dynamicOutputs = $derived(
56
+ ((props.data.config?.dynamicOutputs as DynamicPort[]) || []).map((port) =>
57
+ dynamicPortToNodePort(port, 'output')
58
+ )
59
+ );
60
+
61
+ /**
62
+ * Combined input ports: static metadata inputs + dynamic config inputs
63
+ */
64
+ const allInputPorts = $derived([...props.data.metadata.inputs, ...dynamicInputs]);
65
+
66
+ /**
67
+ * Combined output ports: static metadata outputs + dynamic config outputs
68
+ */
69
+ const allOutputPorts = $derived([...props.data.metadata.outputs, ...dynamicOutputs]);
70
+
71
+ /**
72
+ * Check if a port should be visible based on connection state and settings
73
+ * @param port - The port to check
74
+ * @param type - Whether this is an 'input' or 'output' port
75
+ * @returns true if the port should be visible
76
+ */
77
+ function isPortVisible(port: NodePort, type: 'input' | 'output'): boolean {
78
+ // Always show if hideUnconnectedHandles is disabled
79
+ if (!hideUnconnectedHandles()) {
80
+ return true;
81
+ }
82
+
83
+ // Always show required ports
84
+ if (port.required) {
85
+ return true;
86
+ }
87
+
88
+ // Check if port is connected
89
+ const handleId = `${props.data.nodeId}-${type}-${port.id}`;
90
+ return $connectedHandles.has(handleId);
91
+ }
92
+
93
+ /**
94
+ * Derived list of visible input ports based on hideUnconnectedHandles setting
95
+ * Now includes both static and dynamic inputs
96
+ */
97
+ const visibleInputPorts = $derived(
98
+ allInputPorts.filter((port) => isPortVisible(port, 'input'))
99
+ );
100
+
101
+ /**
102
+ * Derived list of visible output ports based on hideUnconnectedHandles setting
103
+ * Now includes both static and dynamic outputs
104
+ */
105
+ const visibleOutputPorts = $derived(
106
+ allOutputPorts.filter((port) => isPortVisible(port, 'output'))
107
+ );
108
+
26
109
  /**
27
110
  * Handle configuration value changes - now handled by global ConfigSidebar
28
111
  */
@@ -110,13 +193,13 @@
110
193
  </div>
111
194
 
112
195
  <!-- Input Ports Container -->
113
- {#if props.data.metadata.inputs.length > 0}
196
+ {#if visibleInputPorts.length > 0}
114
197
  <div class="flowdrop-workflow-node__ports">
115
198
  <div class="flowdrop-workflow-node__ports-header">
116
199
  <h5 class="flowdrop-workflow-node__ports-title">Inputs</h5>
117
200
  </div>
118
201
  <div class="flowdrop-workflow-node__ports-list">
119
- {#each props.data.metadata.inputs as port (port.id)}
202
+ {#each visibleInputPorts as port (port.id)}
120
203
  <div class="flowdrop-workflow-node__port">
121
204
  <!-- Input Handle -->
122
205
  <Handle
@@ -161,13 +244,13 @@
161
244
  {/if}
162
245
 
163
246
  <!-- Output Ports Container -->
164
- {#if props.data.metadata.outputs.length > 0}
247
+ {#if visibleOutputPorts.length > 0}
165
248
  <div class="flowdrop-workflow-node__ports">
166
249
  <div class="flowdrop-workflow-node__ports-header">
167
250
  <h5 class="flowdrop-workflow-node__ports-title">Outputs</h5>
168
251
  </div>
169
252
  <div class="flowdrop-workflow-node__ports-list">
170
- {#each props.data.metadata.outputs as port (port.id)}
253
+ {#each visibleOutputPorts as port (port.id)}
171
254
  <div class="flowdrop-workflow-node__port">
172
255
  <!-- Port Info -->
173
256
  <div class="flowdrop-flex--1 flowdrop-min-w--0 flowdrop-text--right">
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import './styles/base.css';
6
6
  import './registry/builtinNodes.js';
7
- export type { NodeCategory, NodeDataType, NodePort, NodeMetadata, ConfigValues, WorkflowNode, WorkflowEdge, Workflow, ApiResponse, NodesResponse, WorkflowResponse, WorkflowsResponse, ExecutionStatus, ExecutionResult, FlowDropConfig, WorkflowEvents, BuiltinNodeType } from './types/index.js';
7
+ export type { NodeCategory, NodeDataType, NodePort, DynamicPort, Branch, NodeMetadata, NodeExtensions, NodeUIExtensions, ConfigValues, WorkflowNode, WorkflowEdge, Workflow, ApiResponse, NodesResponse, WorkflowResponse, WorkflowsResponse, ExecutionStatus, ExecutionResult, FlowDropConfig, WorkflowEvents, BuiltinNodeType } from './types/index.js';
8
8
  export type { WorkflowEditorConfig, EditorFeatures, UIConfig, APIConfig, ExecutionConfig, StorageConfig } from './types/config.js';
9
9
  export type { AuthProvider, StaticAuthConfig, CallbackAuthConfig } from './types/auth.js';
10
10
  export { StaticAuthProvider, CallbackAuthProvider, NoAuthProvider } from './types/auth.js';
@@ -36,7 +36,6 @@ export { default as LogsSidebar } from './components/LogsSidebar.svelte';
36
36
  export { default as PipelineStatus } from './components/PipelineStatus.svelte';
37
37
  export { default as Navbar } from './components/Navbar.svelte';
38
38
  export { default as Logo } from './components/Logo.svelte';
39
- export { sampleNodes, sampleWorkflow } from './data/samples.js';
40
39
  export * from './utils/icons.js';
41
40
  export * from './utils/colors.js';
42
41
  export * from './utils/connections.js';
@@ -56,7 +55,7 @@ export { globalSaveWorkflow, globalExportWorkflow, initializeGlobalSave } from '
56
55
  export { fetchPortConfig, validatePortConfig } from './services/portConfigApi.js';
57
56
  export { getDraftStorageKey, saveDraft, loadDraft, deleteDraft, hasDraft, getDraftMetadata, DraftAutoSaveManager } from './services/draftStorage.js';
58
57
  export { EdgeStylingHelper, NodeOperationsHelper, WorkflowOperationsHelper, ConfigurationHelper } from './helpers/workflowEditorHelper.js';
59
- export { workflowStore, workflowActions, workflowId, workflowName, workflowNodes, workflowEdges, workflowMetadata, workflowChanged, workflowValidation, workflowMetadataChanged, isDirtyStore, isDirty, markAsSaved, getWorkflow as getWorkflowFromStore, setOnDirtyStateChange, setOnWorkflowChange } from './stores/workflowStore.js';
58
+ export { workflowStore, workflowActions, workflowId, workflowName, workflowNodes, workflowEdges, workflowMetadata, workflowChanged, workflowValidation, workflowMetadataChanged, connectedHandles, isDirtyStore, isDirty, markAsSaved, getWorkflow as getWorkflowFromStore, setOnDirtyStateChange, setOnWorkflowChange } from './stores/workflowStore.js';
60
59
  export * from './config/endpoints.js';
61
60
  export { DEFAULT_PORT_CONFIG } from './config/defaultPortConfig.js';
62
61
  export * from './config/runtimeConfig.js';
package/dist/index.js CHANGED
@@ -37,8 +37,6 @@ export { default as LogsSidebar } from './components/LogsSidebar.svelte';
37
37
  export { default as PipelineStatus } from './components/PipelineStatus.svelte';
38
38
  export { default as Navbar } from './components/Navbar.svelte';
39
39
  export { default as Logo } from './components/Logo.svelte';
40
- // Export sample data for development
41
- export { sampleNodes, sampleWorkflow } from './data/samples.js';
42
40
  // Export utilities
43
41
  export * from './utils/icons.js';
44
42
  export * from './utils/colors.js';
@@ -67,7 +65,7 @@ export { getDraftStorageKey, saveDraft, loadDraft, deleteDraft, hasDraft, getDra
67
65
  // Export helpers
68
66
  export { EdgeStylingHelper, NodeOperationsHelper, WorkflowOperationsHelper, ConfigurationHelper } from './helpers/workflowEditorHelper.js';
69
67
  // Export stores
70
- export { workflowStore, workflowActions, workflowId, workflowName, workflowNodes, workflowEdges, workflowMetadata, workflowChanged, workflowValidation, workflowMetadataChanged,
68
+ export { workflowStore, workflowActions, workflowId, workflowName, workflowNodes, workflowEdges, workflowMetadata, workflowChanged, workflowValidation, workflowMetadataChanged, connectedHandles,
71
69
  // Dirty state tracking
72
70
  isDirtyStore, isDirty, markAsSaved, getWorkflow as getWorkflowFromStore, setOnDirtyStateChange, setOnWorkflowChange } from './stores/workflowStore.js';
73
71
  // Export endpoint configuration
@@ -154,3 +154,18 @@ export declare const workflowMetadataChanged: import("svelte/store").Readable<{
154
154
  updatedAt: string;
155
155
  version: string;
156
156
  }>;
157
+ /**
158
+ * Derived store for connected handles
159
+ *
160
+ * Provides a Set of all handle IDs that are currently connected to edges.
161
+ * Used by node components to implement hideUnconnectedHandles functionality.
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * import { connectedHandles } from './workflowStore.js';
166
+ *
167
+ * // Check if a specific handle is connected
168
+ * const isConnected = $connectedHandles.has('node-1-input-data');
169
+ * ```
170
+ */
171
+ export declare const connectedHandles: import("svelte/store").Readable<Set<string>>;
@@ -470,3 +470,31 @@ export const workflowMetadataChanged = derived(workflowMetadata, (metadata) => (
470
470
  updatedAt: metadata.updatedAt,
471
471
  version: metadata.version ?? '1.0.0'
472
472
  }));
473
+ /**
474
+ * Derived store for connected handles
475
+ *
476
+ * Provides a Set of all handle IDs that are currently connected to edges.
477
+ * Used by node components to implement hideUnconnectedHandles functionality.
478
+ *
479
+ * @example
480
+ * ```typescript
481
+ * import { connectedHandles } from './workflowStore.js';
482
+ *
483
+ * // Check if a specific handle is connected
484
+ * const isConnected = $connectedHandles.has('node-1-input-data');
485
+ * ```
486
+ */
487
+ export const connectedHandles = derived(workflowEdges, (edges) => {
488
+ const handles = new Set();
489
+ edges.forEach((edge) => {
490
+ // Add source handle (output port)
491
+ if (edge.sourceHandle) {
492
+ handles.add(edge.sourceHandle);
493
+ }
494
+ // Add target handle (input port)
495
+ if (edge.targetHandle) {
496
+ handles.add(edge.targetHandle);
497
+ }
498
+ });
499
+ return handles;
500
+ });