@d34dman/flowdrop 0.0.1 → 0.0.2

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 (119) hide show
  1. package/README.md +307 -215
  2. package/dist/adapters/WorkflowAdapter.d.ts +1 -1
  3. package/dist/adapters/WorkflowAdapter.js +30 -30
  4. package/dist/api/client.d.ts +24 -1
  5. package/dist/api/client.js +55 -38
  6. package/dist/api/enhanced-client.d.ts +46 -0
  7. package/dist/api/enhanced-client.js +211 -0
  8. package/dist/clients/ApiClient.d.ts +19 -23
  9. package/dist/clients/ApiClient.js +36 -34
  10. package/dist/components/App.svelte +1299 -230
  11. package/dist/components/App.svelte.d.ts +21 -1
  12. package/dist/components/CanvasBanner.svelte +50 -44
  13. package/dist/components/CanvasBanner.svelte.d.ts +5 -19
  14. package/dist/components/ConfigForm.svelte +555 -0
  15. package/dist/components/ConfigForm.svelte.d.ts +32 -0
  16. package/dist/components/ConfigModal.svelte +261 -0
  17. package/dist/components/ConfigModal.svelte.d.ts +31 -0
  18. package/dist/components/ConfigSidebar.svelte +934 -0
  19. package/dist/components/ConfigSidebar.svelte.d.ts +51 -0
  20. package/dist/components/ConnectionLine.svelte +32 -0
  21. package/dist/components/ConnectionLine.svelte.d.ts +3 -0
  22. package/dist/components/GatewayNode.svelte +471 -0
  23. package/dist/components/GatewayNode.svelte.d.ts +15 -0
  24. package/dist/components/LoadingSpinner.svelte +23 -23
  25. package/dist/components/LoadingSpinner.svelte.d.ts +1 -1
  26. package/dist/components/Logo.svelte +82 -0
  27. package/dist/components/Logo.svelte.d.ts +26 -0
  28. package/dist/components/LogsSidebar.svelte +565 -0
  29. package/dist/components/LogsSidebar.svelte.d.ts +34 -0
  30. package/dist/components/MarkdownDisplay.svelte +28 -0
  31. package/dist/components/MarkdownDisplay.svelte.d.ts +7 -0
  32. package/dist/components/Navbar.svelte +663 -0
  33. package/dist/components/Navbar.svelte.d.ts +21 -0
  34. package/dist/components/NodeSidebar.svelte +629 -488
  35. package/dist/components/NodeSidebar.svelte.d.ts +1 -2
  36. package/dist/components/NodeStatusOverlay.svelte +327 -0
  37. package/dist/components/NodeStatusOverlay.svelte.d.ts +11 -0
  38. package/dist/components/NotesNode.svelte +566 -0
  39. package/dist/components/NotesNode.svelte.d.ts +43 -0
  40. package/dist/components/PipelineStatus.svelte +331 -0
  41. package/dist/components/PipelineStatus.svelte.d.ts +18 -0
  42. package/dist/components/SimpleNode.svelte +447 -0
  43. package/dist/components/SimpleNode.svelte.d.ts +24 -0
  44. package/dist/components/SquareNode.svelte +346 -0
  45. package/dist/components/SquareNode.svelte.d.ts +24 -0
  46. package/dist/components/StatusIcon.svelte +112 -0
  47. package/dist/components/StatusIcon.svelte.d.ts +10 -0
  48. package/dist/components/StatusLabel.svelte +33 -0
  49. package/dist/components/StatusLabel.svelte.d.ts +7 -0
  50. package/dist/components/ToolNode.svelte +385 -0
  51. package/dist/components/ToolNode.svelte.d.ts +36 -0
  52. package/dist/components/UniversalNode.svelte +126 -0
  53. package/dist/components/UniversalNode.svelte.d.ts +15 -0
  54. package/dist/components/WorkflowEditor.svelte +871 -528
  55. package/dist/components/WorkflowEditor.svelte.d.ts +15 -5
  56. package/dist/components/WorkflowNode.svelte +428 -542
  57. package/dist/components/WorkflowNode.svelte.d.ts +7 -3
  58. package/dist/config/apiConfig.d.ts +33 -0
  59. package/dist/config/apiConfig.js +39 -0
  60. package/dist/config/defaultPortConfig.d.ts +6 -0
  61. package/dist/config/defaultPortConfig.js +192 -0
  62. package/dist/config/demo.d.ts +58 -0
  63. package/dist/config/demo.js +142 -0
  64. package/dist/config/endpoints.d.ts +106 -0
  65. package/dist/config/endpoints.js +128 -0
  66. package/dist/data/samples.d.ts +38 -4
  67. package/dist/data/samples.js +2789 -737
  68. package/dist/examples/adapter-usage.d.ts +4 -4
  69. package/dist/examples/adapter-usage.js +21 -26
  70. package/dist/examples/api-client-usage.d.ts +6 -6
  71. package/dist/examples/api-client-usage.js +55 -54
  72. package/dist/index.d.ts +23 -15
  73. package/dist/index.js +23 -15
  74. package/dist/mocks/app-environment.d.ts +8 -0
  75. package/dist/mocks/app-environment.js +16 -0
  76. package/dist/mocks/app-forms.d.ts +2 -0
  77. package/dist/mocks/app-forms.js +21 -0
  78. package/dist/mocks/app-navigation.d.ts +5 -0
  79. package/dist/mocks/app-navigation.js +34 -0
  80. package/dist/mocks/app-stores.d.ts +14 -0
  81. package/dist/mocks/app-stores.js +26 -0
  82. package/dist/services/api.d.ts +13 -3
  83. package/dist/services/api.js +91 -36
  84. package/dist/services/globalSave.d.ts +20 -0
  85. package/dist/services/globalSave.js +165 -0
  86. package/dist/services/nodeExecutionService.d.ts +63 -0
  87. package/dist/services/nodeExecutionService.js +261 -0
  88. package/dist/services/portConfigApi.d.ts +14 -0
  89. package/dist/services/portConfigApi.js +69 -0
  90. package/dist/services/toastService.d.ts +147 -0
  91. package/dist/services/toastService.js +235 -0
  92. package/dist/services/workflowStorage.d.ts +2 -2
  93. package/dist/services/workflowStorage.js +10 -10
  94. package/dist/stores/workflowStore.d.ts +53 -0
  95. package/dist/stores/workflowStore.js +264 -0
  96. package/dist/styles/base.css +896 -363
  97. package/dist/svelte-app.d.ts +52 -5
  98. package/dist/svelte-app.js +128 -6
  99. package/dist/types/config.d.ts +291 -0
  100. package/dist/types/config.js +4 -0
  101. package/dist/types/index.d.ts +231 -19
  102. package/dist/types/index.js +1 -1
  103. package/dist/utils/colors.d.ts +67 -33
  104. package/dist/utils/colors.js +183 -118
  105. package/dist/utils/config.d.ts +41 -0
  106. package/dist/utils/config.js +248 -0
  107. package/dist/utils/connections.d.ts +40 -3
  108. package/dist/utils/connections.js +115 -44
  109. package/dist/utils/icons.d.ts +1 -1
  110. package/dist/utils/icons.js +71 -70
  111. package/dist/utils/nodeStatus.d.ts +53 -0
  112. package/dist/utils/nodeStatus.js +183 -0
  113. package/dist/utils/nodeTypes.d.ts +57 -0
  114. package/dist/utils/nodeTypes.js +109 -0
  115. package/dist/utils/nodeWrapper.d.ts +39 -0
  116. package/dist/utils/nodeWrapper.js +62 -0
  117. package/package.json +129 -97
  118. package/dist/components/Node.svelte +0 -38
  119. package/dist/components/Node.svelte.d.ts +0 -4
@@ -0,0 +1,385 @@
1
+ <!--
2
+ Tool Node Component
3
+ A specialized node for tools with metadata port
4
+ Styled with BEM syntax
5
+ -->
6
+
7
+ <script lang="ts">
8
+ import { Position, Handle } from '@xyflow/svelte';
9
+ import Icon from '@iconify/svelte';
10
+ import { getDataTypeColor } from '../utils/colors';
11
+ import type { NodeMetadata } from '../types/index.js';
12
+
13
+ interface ToolNodeParameter {
14
+ name: string;
15
+ type?: string;
16
+ description?: string;
17
+ }
18
+
19
+ const props = $props<{
20
+ data: {
21
+ label: string;
22
+ config: {
23
+ icon?: string;
24
+ color?: string;
25
+ toolName?: string;
26
+ toolDescription?: string;
27
+ toolVersion?: string;
28
+ parameters?: ToolNodeParameter[];
29
+ };
30
+ metadata: NodeMetadata;
31
+ nodeId?: string;
32
+ onConfigOpen?: (node: {
33
+ id: string;
34
+ type: string;
35
+ data: { label: string; config: Record<string, unknown>; metadata: NodeMetadata };
36
+ }) => void;
37
+ };
38
+ selected?: boolean;
39
+ isProcessing?: boolean;
40
+ isError?: boolean;
41
+ }>();
42
+
43
+ // Prioritize metadata over config for tool nodes (metadata is the node definition)
44
+ let toolIcon = $derived(
45
+ (props.data.metadata?.icon as string) || (props.data.config?.icon as string) || 'mdi:tools'
46
+ );
47
+ let toolColor = $derived(
48
+ (props.data.metadata?.color as string) || (props.data.config?.color as string) || '#f59e0b'
49
+ );
50
+ let toolName = $derived(
51
+ (props.data.metadata?.name as string) ||
52
+ (props.data.config?.toolName as string) ||
53
+ props.data.label ||
54
+ 'Tool'
55
+ );
56
+ let toolDescription = $derived(
57
+ (props.data.metadata?.description as string) ||
58
+ (props.data.config?.toolDescription as string) ||
59
+ 'A configurable tool for agents'
60
+ );
61
+ let toolVersion = $derived(
62
+ (props.data.metadata?.version as string) ||
63
+ (props.data.config?.toolVersion as string) ||
64
+ '1.0.0'
65
+ );
66
+
67
+ // Check for tool interface ports in metadata
68
+ let hasToolInputPort = $derived(
69
+ props.data.metadata?.inputs?.some((port) => port.dataType === 'tool') || false
70
+ );
71
+ let hasToolOutputPort = $derived(
72
+ props.data.metadata?.outputs?.some((port) => port.dataType === 'tool') || false
73
+ );
74
+
75
+ // Get the actual tool ports for proper handle generation
76
+ let toolInputPort = $derived(
77
+ props.data.metadata?.inputs?.find((port) => port.dataType === 'tool')
78
+ );
79
+ let toolOutputPort = $derived(
80
+ props.data.metadata?.outputs?.find((port) => port.dataType === 'tool')
81
+ );
82
+
83
+ // Handle configuration sidebar - using global ConfigSidebar
84
+ function openConfigSidebar(): void {
85
+ if (props.data.onConfigOpen) {
86
+ // Create a WorkflowNodeType-like object for the global ConfigSidebar
87
+ const nodeForConfig = {
88
+ id: props.data.nodeId || 'unknown',
89
+ type: 'tool',
90
+ data: props.data
91
+ };
92
+ props.data.onConfigOpen(nodeForConfig);
93
+ }
94
+ }
95
+
96
+ // Handle double-click to open config
97
+ function handleDoubleClick(): void {
98
+ openConfigSidebar();
99
+ }
100
+
101
+ // Handle click events
102
+ function handleClick(): void {
103
+ // Node selection is handled by Svelte Flow
104
+ }
105
+
106
+ // Handle keyboard events for accessibility
107
+ function handleKeydown(event: KeyboardEvent): void {
108
+ if (event.key === 'Enter' || event.key === ' ') {
109
+ event.preventDefault();
110
+ handleDoubleClick();
111
+ }
112
+ }
113
+ </script>
114
+
115
+ <!-- Tool Input Handle (optional) -->
116
+ {#if hasToolInputPort && toolInputPort}
117
+ <Handle
118
+ type="target"
119
+ position={Position.Left}
120
+ id={`${props.data.nodeId}-input-${toolInputPort.id}`}
121
+ style="background-color: {getDataTypeColor('tool')}; border-color: '#ffffff';"
122
+ />
123
+ {/if}
124
+
125
+ <!-- Tool Node -->
126
+ <div
127
+ class="flowdrop-tool-node"
128
+ class:flowdrop-tool-node--selected={props.selected}
129
+ class:flowdrop-tool-node--processing={props.isProcessing}
130
+ class:flowdrop-tool-node--error={props.isError}
131
+ onclick={handleClick}
132
+ ondblclick={handleDoubleClick}
133
+ onkeydown={handleKeydown}
134
+ role="button"
135
+ tabindex="0"
136
+ >
137
+ <!-- Node Header -->
138
+ <div class="flowdrop-tool-node__header">
139
+ <div class="flowdrop-tool-node__header-content">
140
+ <!-- Tool Icon -->
141
+ <div class="flowdrop-tool-node__icon-container" style="background-color: {toolColor}">
142
+ <Icon icon={toolIcon} class="flowdrop-tool-node__icon" />
143
+ </div>
144
+
145
+ <!-- Tool Info -->
146
+ <div class="flowdrop-tool-node__info">
147
+ <h3 class="flowdrop-tool-node__title">
148
+ {toolName}
149
+ </h3>
150
+ <div class="flowdrop-tool-node__version">
151
+ v{toolVersion}
152
+ </div>
153
+ </div>
154
+
155
+ <!-- Tool Badge -->
156
+ <div class="flowdrop-tool-node__badge">TOOL</div>
157
+ </div>
158
+
159
+ <!-- Tool Description -->
160
+ <p class="flowdrop-tool-node__description">
161
+ {toolDescription}
162
+ </p>
163
+ </div>
164
+
165
+ <!-- Processing indicator -->
166
+ {#if props.isProcessing}
167
+ <div class="flowdrop-tool-node__processing">
168
+ <div class="flowdrop-tool-node__spinner"></div>
169
+ </div>
170
+ {/if}
171
+
172
+ <!-- Error indicator -->
173
+ {#if props.isError}
174
+ <div class="flowdrop-tool-node__error">
175
+ <Icon icon="mdi:alert-circle" class="flowdrop-tool-node__error-icon" />
176
+ </div>
177
+ {/if}
178
+
179
+ <!-- Config button -->
180
+ <button class="flowdrop-tool-node__config-btn" onclick={openConfigSidebar} title="Configure tool">
181
+ <Icon icon="mdi:cog" />
182
+ </button>
183
+ </div>
184
+
185
+ <!-- Tool Output Handle (optional) -->
186
+ {#if hasToolOutputPort && toolOutputPort}
187
+ <Handle
188
+ type="source"
189
+ position={Position.Right}
190
+ id={`${props.data.nodeId}-output-${toolOutputPort.id}`}
191
+ style="background-color: {getDataTypeColor('tool')}; border-color: '#ffffff';"
192
+ />
193
+ {/if}
194
+
195
+ <style>
196
+ .flowdrop-tool-node {
197
+ position: relative;
198
+ background-color: #ffffff;
199
+ border: 2px solid #e5e7eb;
200
+ border-radius: 0.75rem;
201
+ width: 18rem;
202
+ display: flex;
203
+ flex-direction: column;
204
+ cursor: pointer;
205
+ transition: all 0.2s ease-in-out;
206
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
207
+ overflow: visible;
208
+ z-index: 10;
209
+ }
210
+
211
+ .flowdrop-tool-node:hover {
212
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
213
+ }
214
+
215
+ .flowdrop-tool-node--selected {
216
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
217
+ border: 2px solid #f59e0b;
218
+ }
219
+
220
+ .flowdrop-tool-node--processing {
221
+ opacity: 0.7;
222
+ }
223
+
224
+ .flowdrop-tool-node--error {
225
+ border-color: #ef4444 !important;
226
+ background-color: #fef2f2 !important;
227
+ }
228
+
229
+ .flowdrop-tool-node__header {
230
+ padding: 1rem;
231
+ background-color: #fffbeb;
232
+ border-radius: 0.75rem;
233
+ border: 1px solid #fcd34d;
234
+ }
235
+
236
+ .flowdrop-tool-node__header-content {
237
+ display: flex;
238
+ align-items: center;
239
+ gap: 0.75rem;
240
+ margin-bottom: 0.5rem;
241
+ }
242
+
243
+ .flowdrop-tool-node__icon-container {
244
+ display: flex;
245
+ align-items: center;
246
+ justify-content: center;
247
+ width: 2.5rem;
248
+ height: 2.5rem;
249
+ border-radius: 0.5rem;
250
+ flex-shrink: 0;
251
+ }
252
+
253
+ .flowdrop-tool-node__info {
254
+ flex: 1;
255
+ min-width: 0;
256
+ }
257
+
258
+ .flowdrop-tool-node__title {
259
+ font-size: 1rem;
260
+ font-weight: 600;
261
+ color: #1f2937;
262
+ margin: 0;
263
+ line-height: 1.4;
264
+ }
265
+
266
+ .flowdrop-tool-node__version {
267
+ font-size: 0.75rem;
268
+ color: #6b7280;
269
+ font-weight: 500;
270
+ margin-top: 0.125rem;
271
+ }
272
+
273
+ .flowdrop-tool-node__badge {
274
+ background-color: #f59e0b;
275
+ color: white;
276
+ font-size: 0.625rem;
277
+ font-weight: 700;
278
+ padding: 0.25rem 0.5rem;
279
+ border-radius: 0.25rem;
280
+ letter-spacing: 0.05em;
281
+ }
282
+
283
+ .flowdrop-tool-node__description {
284
+ font-size: 0.75rem;
285
+ color: #6b7280;
286
+ margin: 0;
287
+ line-height: 1.3;
288
+ }
289
+
290
+ :global(.flowdrop-tool-node__icon) {
291
+ color: white;
292
+ font-size: 1.25rem;
293
+ filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.2));
294
+ }
295
+
296
+ .flowdrop-tool-node__processing {
297
+ position: absolute;
298
+ top: 4px;
299
+ right: 4px;
300
+ }
301
+
302
+ .flowdrop-tool-node__spinner {
303
+ width: 12px;
304
+ height: 12px;
305
+ border: 1px solid rgba(255, 255, 255, 0.3);
306
+ border-top: 1px solid white;
307
+ border-radius: 50%;
308
+ animation: spin 1s linear infinite;
309
+ }
310
+
311
+ .flowdrop-tool-node__error {
312
+ position: absolute;
313
+ top: 4px;
314
+ right: 4px;
315
+ color: #ef4444;
316
+ }
317
+
318
+ :global(.flowdrop-tool-node__error-icon) {
319
+ width: 12px;
320
+ height: 12px;
321
+ }
322
+
323
+ .flowdrop-tool-node__config-btn {
324
+ position: absolute;
325
+ top: 0.5rem;
326
+ right: 0.5rem;
327
+ width: 1.5rem;
328
+ height: 1.5rem;
329
+ background-color: rgba(255, 255, 255, 0.9);
330
+ border: 1px solid #e5e7eb;
331
+ border-radius: 0.25rem;
332
+ color: #6b7280;
333
+ cursor: pointer;
334
+ display: flex;
335
+ align-items: center;
336
+ justify-content: center;
337
+ opacity: 0;
338
+ transition: all 0.2s ease-in-out;
339
+ backdrop-filter: blur(4px);
340
+ z-index: 15;
341
+ font-size: 0.875rem;
342
+ }
343
+
344
+ .flowdrop-tool-node:hover .flowdrop-tool-node__config-btn {
345
+ opacity: 1;
346
+ }
347
+
348
+ .flowdrop-tool-node__config-btn:hover {
349
+ background-color: #f9fafb;
350
+ border-color: #d1d5db;
351
+ color: #374151;
352
+ }
353
+
354
+ @keyframes spin {
355
+ to {
356
+ transform: rotate(360deg);
357
+ }
358
+ }
359
+
360
+ /* Handle styles - special metadata port styling */
361
+ :global(.svelte-flow__node-tool .svelte-flow__handle) {
362
+ width: 16px !important;
363
+ height: 16px !important;
364
+ border: 2px solid #ffffff !important;
365
+ border-radius: 50% !important;
366
+ transition: all 0.2s ease-in-out !important;
367
+ cursor: pointer !important;
368
+ z-index: 20 !important;
369
+ pointer-events: auto !important;
370
+ }
371
+
372
+ :global(.svelte-flow__node-tool .svelte-flow__handle-right) {
373
+ right: -6px !important;
374
+ }
375
+
376
+ /* Metadata port hover effects */
377
+ :global(.svelte-flow__node-tool .svelte-flow__handle:hover) {
378
+ box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.3) !important;
379
+ }
380
+
381
+ :global(.svelte-flow__node-tool .svelte-flow__handle:focus) {
382
+ outline: 2px solid #f59e0b !important;
383
+ outline-offset: 2px !important;
384
+ }
385
+ </style>
@@ -0,0 +1,36 @@
1
+ import type { NodeMetadata } from '../types/index.js';
2
+ interface ToolNodeParameter {
3
+ name: string;
4
+ type?: string;
5
+ description?: string;
6
+ }
7
+ type $$ComponentProps = {
8
+ data: {
9
+ label: string;
10
+ config: {
11
+ icon?: string;
12
+ color?: string;
13
+ toolName?: string;
14
+ toolDescription?: string;
15
+ toolVersion?: string;
16
+ parameters?: ToolNodeParameter[];
17
+ };
18
+ metadata: NodeMetadata;
19
+ nodeId?: string;
20
+ onConfigOpen?: (node: {
21
+ id: string;
22
+ type: string;
23
+ data: {
24
+ label: string;
25
+ config: Record<string, unknown>;
26
+ metadata: NodeMetadata;
27
+ };
28
+ }) => void;
29
+ };
30
+ selected?: boolean;
31
+ isProcessing?: boolean;
32
+ isError?: boolean;
33
+ };
34
+ declare const ToolNode: import("svelte").Component<$$ComponentProps, {}, "">;
35
+ type ToolNode = ReturnType<typeof ToolNode>;
36
+ export default ToolNode;
@@ -0,0 +1,126 @@
1
+ <!--
2
+ Universal Node Component
3
+ Renders any node type with automatic status overlay injection
4
+ This component can replace individual node components in SvelteFlow
5
+ -->
6
+
7
+ <script lang="ts">
8
+ import type { WorkflowNode } from '../types/index.js';
9
+ import WorkflowNodeComponent from './WorkflowNode.svelte';
10
+ import NotesNode from './NotesNode.svelte';
11
+ import SimpleNode from './SimpleNode.svelte';
12
+ import SquareNode from './SquareNode.svelte';
13
+ import ToolNode from './ToolNode.svelte';
14
+ import GatewayNode from './GatewayNode.svelte';
15
+ import NodeStatusOverlay from './NodeStatusOverlay.svelte';
16
+ import {
17
+ shouldShowNodeStatus,
18
+ getOptimalStatusPosition,
19
+ getOptimalStatusSize
20
+ } from '../utils/nodeWrapper.js';
21
+ import { resolveComponentName } from '../utils/nodeTypes.js';
22
+
23
+ interface Props {
24
+ data: WorkflowNode['data'] & {
25
+ nodeId?: string;
26
+ onConfigOpen?: (node: { id: string; type: string; data: WorkflowNode['data'] }) => void;
27
+ };
28
+ selected?: boolean;
29
+ }
30
+
31
+ let {
32
+ data,
33
+ selected = false
34
+ }: {
35
+ data: WorkflowNode['data'] & {
36
+ nodeId?: string;
37
+ onConfigOpen?: (node: { id: string; type: string; data: WorkflowNode['data'] }) => void;
38
+ };
39
+ selected?: boolean;
40
+ } = $props();
41
+
42
+ // Determine which node component to render based on node type
43
+ // Priority: config.nodeType > metadata.type
44
+ // Explicitly track config.nodeType to ensure reactivity
45
+ let configNodeType = $derived(data.config?.nodeType as string | undefined);
46
+ let resolvedComponentName = $derived(
47
+ data.metadata ? resolveComponentName(data.metadata, configNodeType) : 'workflowNode'
48
+ );
49
+ let nodeComponent = $derived(getNodeComponent(resolvedComponentName));
50
+
51
+ // Get execution info
52
+ let executionInfo = $derived(data.executionInfo);
53
+ let shouldShowStatus = $derived(
54
+ shouldShowNodeStatus(executionInfo) && resolvedComponentName !== 'note'
55
+ );
56
+
57
+ /**
58
+ * Get the appropriate node component based on type
59
+ */
60
+ function getNodeComponent(nodeType: string) {
61
+ switch (nodeType) {
62
+ case 'note':
63
+ return NotesNode;
64
+ case 'simple':
65
+ return SimpleNode;
66
+ case 'square':
67
+ return SquareNode;
68
+ case 'tool':
69
+ return ToolNode;
70
+ case 'gateway':
71
+ return GatewayNode;
72
+ case 'workflowNode':
73
+ default:
74
+ return WorkflowNodeComponent;
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Get optimal status position for this node type
80
+ */
81
+ function getStatusPosition(): 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' {
82
+ return getOptimalStatusPosition(resolvedComponentName);
83
+ }
84
+
85
+ /**
86
+ * Get optimal status size for this node type
87
+ */
88
+ function getStatusSize(): 'sm' | 'md' | 'lg' {
89
+ return getOptimalStatusSize(resolvedComponentName);
90
+ }
91
+ </script>
92
+
93
+ <div class="universal-node">
94
+ <!-- Render the appropriate node component -->
95
+ {#if nodeComponent === WorkflowNodeComponent}
96
+ <WorkflowNodeComponent {data} {selected} />
97
+ {:else if nodeComponent === NotesNode}
98
+ <NotesNode {data} {selected} />
99
+ {:else if nodeComponent === SimpleNode}
100
+ <SimpleNode {data} {selected} />
101
+ {:else if nodeComponent === SquareNode}
102
+ <SquareNode {data} {selected} />
103
+ {:else if nodeComponent === ToolNode}
104
+ <ToolNode {data} {selected} />
105
+ {:else if nodeComponent === GatewayNode}
106
+ <GatewayNode {data} {selected} />
107
+ {/if}
108
+
109
+ <!-- Status overlay - only show if there's meaningful status information -->
110
+ {#if shouldShowStatus}
111
+ <NodeStatusOverlay
112
+ nodeId={data.nodeId || 'unknown'}
113
+ {executionInfo}
114
+ position={getStatusPosition()}
115
+ size={getStatusSize()}
116
+ showDetails={true}
117
+ />
118
+ {/if}
119
+ </div>
120
+
121
+ <style>
122
+ .universal-node {
123
+ position: relative;
124
+ display: inline-block;
125
+ }
126
+ </style>
@@ -0,0 +1,15 @@
1
+ import type { WorkflowNode } from '../types/index.js';
2
+ type $$ComponentProps = {
3
+ data: WorkflowNode['data'] & {
4
+ nodeId?: string;
5
+ onConfigOpen?: (node: {
6
+ id: string;
7
+ type: string;
8
+ data: WorkflowNode['data'];
9
+ }) => void;
10
+ };
11
+ selected?: boolean;
12
+ };
13
+ declare const UniversalNode: import("svelte").Component<$$ComponentProps, {}, "">;
14
+ type UniversalNode = ReturnType<typeof UniversalNode>;
15
+ export default UniversalNode;