@d34dman/flowdrop 0.0.4 → 0.0.6

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.
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Workflow Editor Helper
3
+ * Contains business logic for workflow operations
4
+ */
5
+ import type { WorkflowNode as WorkflowNodeType, NodeMetadata, Workflow, WorkflowEdge, NodeExecutionInfo } from '../types/index.js';
6
+ import type { EndpointConfig } from '../config/endpoints.js';
7
+ /**
8
+ * Edge styling configuration
9
+ */
10
+ export declare class EdgeStylingHelper {
11
+ /**
12
+ * Apply custom styling to connection edges based on rules:
13
+ * - Dashed lines for connections to tool nodes
14
+ * - Arrow markers pointing towards input ports
15
+ */
16
+ static applyConnectionStyling(edge: WorkflowEdge, sourceNode: WorkflowNodeType, targetNode: WorkflowNodeType): void;
17
+ /**
18
+ * Update existing edges with custom styling rules
19
+ */
20
+ static updateEdgeStyles(edges: WorkflowEdge[], nodes: WorkflowNodeType[]): WorkflowEdge[];
21
+ }
22
+ /**
23
+ * Node operations helper
24
+ */
25
+ export declare class NodeOperationsHelper {
26
+ /**
27
+ * Load nodes from API
28
+ */
29
+ static loadNodesFromApi(providedNodes?: NodeMetadata[]): Promise<NodeMetadata[]>;
30
+ /**
31
+ * Load node execution information for all nodes in the workflow
32
+ */
33
+ static loadNodeExecutionInfo(workflow: Workflow | null, pipelineId?: string): Promise<Record<string, NodeExecutionInfo>>;
34
+ /**
35
+ * Create a new node from dropped data
36
+ */
37
+ static createNodeFromDrop(nodeTypeData: string, position: {
38
+ x: number;
39
+ y: number;
40
+ }): WorkflowNodeType | null;
41
+ }
42
+ /**
43
+ * Workflow operations helper
44
+ */
45
+ export declare class WorkflowOperationsHelper {
46
+ /**
47
+ * Generate workflow metadata for updates
48
+ */
49
+ static generateMetadata(existingMetadata?: Workflow['metadata']): Workflow['metadata'];
50
+ /**
51
+ * Update workflow with new nodes/edges and generate new metadata
52
+ */
53
+ static updateWorkflow(workflow: Workflow, nodes: WorkflowNodeType[], edges: WorkflowEdge[]): Workflow;
54
+ /**
55
+ * Clear workflow (remove all nodes and edges)
56
+ */
57
+ static clearWorkflow(workflow: Workflow): Workflow;
58
+ /**
59
+ * Update node configuration
60
+ */
61
+ static updateNodeConfig(workflow: Workflow, nodeId: string, newConfig: Record<string, unknown>): Workflow;
62
+ /**
63
+ * Add a new node to the workflow
64
+ */
65
+ static addNode(workflow: Workflow, node: WorkflowNodeType): Workflow;
66
+ /**
67
+ * Save workflow to backend
68
+ */
69
+ static saveWorkflow(workflow: Workflow | null): Promise<Workflow | null>;
70
+ /**
71
+ * Export workflow as JSON file
72
+ */
73
+ static exportWorkflow(workflow: Workflow | null): void;
74
+ /**
75
+ * Check if workflow has cycles
76
+ */
77
+ static checkWorkflowCycles(nodes: WorkflowNodeType[], edges: WorkflowEdge[]): boolean;
78
+ }
79
+ /**
80
+ * Configuration helper
81
+ */
82
+ export declare class ConfigurationHelper {
83
+ /**
84
+ * Configure API endpoints
85
+ */
86
+ static configureEndpoints(config: EndpointConfig): void;
87
+ }
@@ -0,0 +1,365 @@
1
+ /**
2
+ * Workflow Editor Helper
3
+ * Contains business logic for workflow operations
4
+ */
5
+ import { MarkerType } from '@xyflow/svelte';
6
+ import { hasCycles } from '../utils/connections.js';
7
+ import { workflowApi, nodeApi, setEndpointConfig } from '../services/api.js';
8
+ import { v4 as uuidv4 } from 'uuid';
9
+ import { workflowActions } from '../stores/workflowStore.js';
10
+ import { nodeExecutionService } from '../services/nodeExecutionService.js';
11
+ /**
12
+ * Edge styling configuration
13
+ */
14
+ export class EdgeStylingHelper {
15
+ /**
16
+ * Apply custom styling to connection edges based on rules:
17
+ * - Dashed lines for connections to tool nodes
18
+ * - Arrow markers pointing towards input ports
19
+ */
20
+ static applyConnectionStyling(edge, sourceNode, targetNode) {
21
+ // Rule 1: Dashed lines for tool nodes
22
+ // A node is a tool node when it uses the ToolNode component,
23
+ // which happens when sourceNode.type === "tool"
24
+ const isToolNode = sourceNode.type === 'tool';
25
+ // Use inline styles for dashed lines (more reliable than CSS classes)
26
+ if (isToolNode) {
27
+ edge.style = 'stroke-dasharray: 0 4 0; stroke: amber !important;';
28
+ edge.class = 'flowdrop--edge--tool';
29
+ }
30
+ else {
31
+ edge.style = 'stroke: grey;';
32
+ }
33
+ // Store metadata in edge data for debugging
34
+ edge.data = {
35
+ ...edge.data,
36
+ isToolConnection: isToolNode,
37
+ targetNodeType: targetNode.type,
38
+ targetCategory: targetNode.data.metadata.category
39
+ };
40
+ // Rule 2: Always add arrow pointing towards input port
41
+ // This replaces the default arrows we removed
42
+ if (!isToolNode) {
43
+ edge.markerEnd = {
44
+ type: MarkerType.ArrowClosed,
45
+ width: 16,
46
+ height: 16,
47
+ color: 'grey'
48
+ };
49
+ }
50
+ }
51
+ /**
52
+ * Update existing edges with custom styling rules
53
+ */
54
+ static updateEdgeStyles(edges, nodes) {
55
+ return edges.map((edge) => {
56
+ // Find source and target nodes
57
+ const sourceNode = nodes.find((node) => node.id === edge.source);
58
+ const targetNode = nodes.find((node) => node.id === edge.target);
59
+ if (!sourceNode || !targetNode) {
60
+ console.warn('Could not find nodes for edge:', edge.id);
61
+ return edge;
62
+ }
63
+ // Create a copy of the edge and apply styling
64
+ const updatedEdge = { ...edge };
65
+ this.applyConnectionStyling(updatedEdge, sourceNode, targetNode);
66
+ return updatedEdge;
67
+ });
68
+ }
69
+ }
70
+ /**
71
+ * Node operations helper
72
+ */
73
+ export class NodeOperationsHelper {
74
+ /**
75
+ * Load nodes from API
76
+ */
77
+ static async loadNodesFromApi(providedNodes) {
78
+ // If nodes are provided via props, use them
79
+ if (providedNodes && providedNodes.length > 0) {
80
+ return providedNodes;
81
+ }
82
+ // Otherwise, load from API
83
+ try {
84
+ const fetchedNodes = await nodeApi.getNodes();
85
+ return fetchedNodes;
86
+ }
87
+ catch (error) {
88
+ console.error('❌ Failed to load nodes from API:', error);
89
+ // Use fallback sample nodes
90
+ return [
91
+ {
92
+ id: 'text-input',
93
+ name: 'Text Input',
94
+ category: 'inputs',
95
+ description: 'Simple text input field',
96
+ version: '1.0.0',
97
+ icon: 'mdi:text-box',
98
+ inputs: [],
99
+ outputs: [{ id: 'text', name: 'text', type: 'output', dataType: 'string' }]
100
+ },
101
+ {
102
+ id: 'text-output',
103
+ name: 'Text Output',
104
+ category: 'outputs',
105
+ description: 'Display text output',
106
+ version: '1.0.0',
107
+ icon: 'mdi:text-box-outline',
108
+ inputs: [{ id: 'text', name: 'text', type: 'input', dataType: 'string' }],
109
+ outputs: []
110
+ }
111
+ ];
112
+ }
113
+ }
114
+ /**
115
+ * Load node execution information for all nodes in the workflow
116
+ */
117
+ static async loadNodeExecutionInfo(workflow, pipelineId) {
118
+ if (!workflow?.nodes)
119
+ return {};
120
+ // Only load execution info if we have a pipelineId (for pipeline status mode)
121
+ if (!pipelineId)
122
+ return {};
123
+ try {
124
+ const nodeIds = workflow.nodes.map((node) => node.id);
125
+ const executionInfo = await nodeExecutionService.getMultipleNodeExecutionInfo(nodeIds, pipelineId);
126
+ return executionInfo;
127
+ }
128
+ catch (error) {
129
+ console.error('Failed to load node execution info:', error);
130
+ return {};
131
+ }
132
+ }
133
+ /**
134
+ * Create a new node from dropped data
135
+ */
136
+ static createNodeFromDrop(nodeTypeData, position) {
137
+ try {
138
+ const parsedData = JSON.parse(nodeTypeData);
139
+ // Handle both old format (with type: "node") and new format (direct NodeMetadata)
140
+ let nodeType;
141
+ let nodeData;
142
+ if (parsedData.type === 'node') {
143
+ // Old format from sidebar
144
+ nodeType = parsedData.nodeData.metadata;
145
+ nodeData = parsedData.nodeData;
146
+ }
147
+ else {
148
+ // New format (direct NodeMetadata)
149
+ nodeType = parsedData;
150
+ // Extract initial config from configSchema
151
+ let initialConfig = {};
152
+ if (nodeType.configSchema && typeof nodeType.configSchema === 'object') {
153
+ // If configSchema is a JSON Schema, extract default values
154
+ if (nodeType.configSchema.properties) {
155
+ // JSON Schema format - extract defaults
156
+ Object.entries(nodeType.configSchema.properties).forEach(([key, prop]) => {
157
+ if (prop && typeof prop === 'object' && 'default' in prop) {
158
+ initialConfig[key] = prop.default;
159
+ }
160
+ });
161
+ }
162
+ else {
163
+ // Simple object format - use as is
164
+ initialConfig = { ...nodeType.configSchema };
165
+ }
166
+ }
167
+ nodeData = {
168
+ label: nodeType.name,
169
+ config: initialConfig,
170
+ metadata: nodeType
171
+ };
172
+ }
173
+ const newNodeId = uuidv4();
174
+ // All nodes use "universalNode" type
175
+ // UniversalNode component handles internal switching based on metadata and config
176
+ const newNode = {
177
+ id: newNodeId,
178
+ type: 'universalNode',
179
+ position, // Use the position calculated from the drop event
180
+ deletable: true,
181
+ data: {
182
+ ...nodeData,
183
+ nodeId: newNodeId // Use the same ID
184
+ }
185
+ };
186
+ return newNode;
187
+ }
188
+ catch (error) {
189
+ console.error('Error parsing node data:', error);
190
+ return null;
191
+ }
192
+ }
193
+ }
194
+ /**
195
+ * Workflow operations helper
196
+ */
197
+ export class WorkflowOperationsHelper {
198
+ /**
199
+ * Generate workflow metadata for updates
200
+ */
201
+ static generateMetadata(existingMetadata) {
202
+ return {
203
+ ...existingMetadata,
204
+ updatedAt: new Date().toISOString(),
205
+ versionId: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
206
+ updateNumber: (existingMetadata?.updateNumber || 0) + 1
207
+ };
208
+ }
209
+ /**
210
+ * Update workflow with new nodes/edges and generate new metadata
211
+ */
212
+ static updateWorkflow(workflow, nodes, edges) {
213
+ return {
214
+ ...workflow,
215
+ nodes,
216
+ edges,
217
+ metadata: this.generateMetadata(workflow.metadata)
218
+ };
219
+ }
220
+ /**
221
+ * Clear workflow (remove all nodes and edges)
222
+ */
223
+ static clearWorkflow(workflow) {
224
+ return {
225
+ ...workflow,
226
+ nodes: [],
227
+ edges: [],
228
+ metadata: this.generateMetadata(workflow.metadata)
229
+ };
230
+ }
231
+ /**
232
+ * Update node configuration
233
+ */
234
+ static updateNodeConfig(workflow, nodeId, newConfig) {
235
+ return {
236
+ ...workflow,
237
+ nodes: workflow.nodes.map((node) => node.id === nodeId
238
+ ? {
239
+ ...node,
240
+ data: { ...node.data, config: { ...newConfig } }
241
+ }
242
+ : node),
243
+ metadata: this.generateMetadata(workflow.metadata)
244
+ };
245
+ }
246
+ /**
247
+ * Add a new node to the workflow
248
+ */
249
+ static addNode(workflow, node) {
250
+ return {
251
+ ...workflow,
252
+ nodes: [...workflow.nodes, node],
253
+ metadata: this.generateMetadata(workflow.metadata)
254
+ };
255
+ }
256
+ /**
257
+ * Save workflow to backend
258
+ */
259
+ static async saveWorkflow(workflow) {
260
+ if (!workflow) {
261
+ console.warn('⚠️ No workflow data available to save');
262
+ return null;
263
+ }
264
+ try {
265
+ // Determine the workflow ID based on whether we have an existing workflow
266
+ let workflowId;
267
+ if (workflow.id) {
268
+ // Use the existing workflow ID
269
+ workflowId = workflow.id;
270
+ }
271
+ else {
272
+ // Generate a new UUID for a new workflow
273
+ workflowId = uuidv4();
274
+ }
275
+ const workflowToSave = {
276
+ id: workflowId,
277
+ name: workflow.name || 'Untitled Workflow',
278
+ nodes: workflow.nodes || [],
279
+ edges: workflow.edges || [],
280
+ metadata: {
281
+ version: '1.0.0',
282
+ createdAt: workflow.metadata?.createdAt || new Date().toISOString(),
283
+ updatedAt: new Date().toISOString()
284
+ }
285
+ };
286
+ console.log('💾 WorkflowEditor: Saving workflow to backend:');
287
+ console.log(' - ID:', workflowToSave.id);
288
+ console.log(' - Name:', workflowToSave.name);
289
+ console.log(' - Nodes count:', workflowToSave.nodes.length);
290
+ console.log(' - Edges count:', workflowToSave.edges.length);
291
+ console.log(' - Full workflow object:', JSON.stringify(workflowToSave, null, 2));
292
+ const savedWorkflow = await workflowApi.saveWorkflow(workflowToSave);
293
+ console.log('✅ WorkflowEditor: Received workflow from backend:');
294
+ console.log(' - ID:', savedWorkflow.id);
295
+ console.log(' - Name:', savedWorkflow.name);
296
+ console.log(' - Nodes count:', savedWorkflow.nodes?.length || 0);
297
+ console.log(' - Edges count:', savedWorkflow.edges?.length || 0);
298
+ // Update the workflow ID if it changed (new workflow)
299
+ if (savedWorkflow.id && savedWorkflow.id !== workflowToSave.id) {
300
+ console.log('🔄 Updating workflow ID from', workflowToSave.id, 'to', savedWorkflow.id);
301
+ workflowActions.batchUpdate({
302
+ nodes: workflowToSave.nodes,
303
+ edges: workflowToSave.edges,
304
+ name: workflowToSave.name,
305
+ metadata: {
306
+ ...workflowToSave.metadata,
307
+ ...savedWorkflow.metadata
308
+ }
309
+ });
310
+ }
311
+ return savedWorkflow;
312
+ }
313
+ catch (error) {
314
+ console.error('❌ Failed to save workflow:', error);
315
+ throw error;
316
+ }
317
+ }
318
+ /**
319
+ * Export workflow as JSON file
320
+ */
321
+ static exportWorkflow(workflow) {
322
+ if (!workflow) {
323
+ console.warn('⚠️ No workflow data available to export');
324
+ return;
325
+ }
326
+ // Use the same ID logic as saveWorkflow
327
+ const workflowId = workflow.id || uuidv4();
328
+ const workflowToExport = {
329
+ id: workflowId,
330
+ name: workflow.name || 'Untitled Workflow',
331
+ nodes: workflow.nodes || [],
332
+ edges: workflow.edges || [],
333
+ metadata: {
334
+ version: '1.0.0',
335
+ createdAt: workflow.metadata?.createdAt || new Date().toISOString(),
336
+ updatedAt: new Date().toISOString()
337
+ }
338
+ };
339
+ const dataStr = JSON.stringify(workflowToExport, null, 2);
340
+ const dataBlob = new Blob([dataStr], { type: 'application/json' });
341
+ const url = URL.createObjectURL(dataBlob);
342
+ const link = document.createElement('a');
343
+ link.href = url;
344
+ link.download = `${workflowToExport.name}.json`;
345
+ link.click();
346
+ URL.revokeObjectURL(url);
347
+ }
348
+ /**
349
+ * Check if workflow has cycles
350
+ */
351
+ static checkWorkflowCycles(nodes, edges) {
352
+ return hasCycles(nodes, edges);
353
+ }
354
+ }
355
+ /**
356
+ * Configuration helper
357
+ */
358
+ export class ConfigurationHelper {
359
+ /**
360
+ * Configure API endpoints
361
+ */
362
+ static configureEndpoints(config) {
363
+ setEndpointConfig(config);
364
+ }
365
+ }
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * FlowDrop - Visual Workflow Editor Library
3
3
  * A Svelte 5 component library built on @xyflow/svelte for creating node-based workflow editors
4
4
  */
5
- import "./styles/base.css";
5
+ import './styles/base.css';
6
6
  export type { NodeCategory, NodeDataType, NodePort, NodeMetadata, NodeConfig, WorkflowNode, WorkflowEdge, Workflow, ApiResponse, NodesResponse, WorkflowResponse, WorkflowsResponse, ExecutionStatus, ExecutionResult, FlowDropConfig, WorkflowEvents } from './types/index.js';
7
7
  export type { WorkflowEditorConfig, EditorFeatures, UIConfig, APIConfig, ExecutionConfig, StorageConfig, NodeType, WorkflowData, ExecutionResult as EditorExecutionResult, EditorState } from './types/config.js';
8
8
  export { FlowDropApiClient } from './api/client.js';
@@ -14,14 +14,44 @@ export { default as SimpleNodeComponent } from './components/SimpleNode.svelte';
14
14
  export { default as ToolNodeComponent } from './components/ToolNode.svelte';
15
15
  export { default as NotesNodeComponent } from './components/NotesNode.svelte';
16
16
  export { default as CanvasBanner } from './components/CanvasBanner.svelte';
17
+ export { default as UniversalNode } from './components/UniversalNode.svelte';
18
+ export { default as GatewayNode } from './components/GatewayNode.svelte';
19
+ export { default as SquareNode } from './components/SquareNode.svelte';
20
+ export { default as LoadingSpinner } from './components/LoadingSpinner.svelte';
21
+ export { default as StatusIcon } from './components/StatusIcon.svelte';
22
+ export { default as StatusLabel } from './components/StatusLabel.svelte';
23
+ export { default as NodeStatusOverlay } from './components/NodeStatusOverlay.svelte';
24
+ export { default as MarkdownDisplay } from './components/MarkdownDisplay.svelte';
25
+ export { default as ConfigForm } from './components/ConfigForm.svelte';
26
+ export { default as ConfigModal } from './components/ConfigModal.svelte';
27
+ export { default as ConfigSidebar } from './components/ConfigSidebar.svelte';
28
+ export { default as ConnectionLine } from './components/ConnectionLine.svelte';
29
+ export { default as LogsSidebar } from './components/LogsSidebar.svelte';
30
+ export { default as PipelineStatus } from './components/PipelineStatus.svelte';
31
+ export { default as Navbar } from './components/Navbar.svelte';
32
+ export { default as Logo } from './components/Logo.svelte';
17
33
  export { sampleNodes, sampleWorkflow } from './data/samples.js';
18
34
  export * from './utils/icons.js';
19
35
  export * from './utils/colors.js';
20
36
  export * from './utils/connections.js';
21
37
  export * from './utils/config.js';
22
38
  export * from './utils/nodeTypes.js';
39
+ export { getStatusColor, getStatusIcon, getStatusLabel, getStatusBackgroundColor, getStatusTextColor, createDefaultExecutionInfo, updateExecutionStart, updateExecutionComplete, updateExecutionFailed, resetExecutionInfo, formatExecutionDuration, formatLastExecuted } from './utils/nodeStatus.js';
40
+ export { createNodeWrapperConfig, shouldShowNodeStatus, getOptimalStatusPosition, getOptimalStatusSize, DEFAULT_NODE_STATUS_CONFIG } from './utils/nodeWrapper.js';
41
+ export type { NodeStatusConfig } from './utils/nodeWrapper.js';
23
42
  export * from './services/api.js';
43
+ export { showSuccess, showError, showWarning, showInfo, showLoading, dismissToast, dismissAllToasts, showPromise, showConfirmation, apiToasts, workflowToasts, pipelineToasts } from './services/toastService.js';
44
+ export type { ToastType, ToastOptions } from './services/toastService.js';
45
+ export { NodeExecutionService, nodeExecutionService } from './services/nodeExecutionService.js';
46
+ export { saveWorkflow, updateWorkflow, getWorkflow, getWorkflows, deleteWorkflow, getWorkflowCount, initializeSampleWorkflows } from './services/workflowStorage.js';
47
+ export { globalSaveWorkflow, globalExportWorkflow, initializeGlobalSave } from './services/globalSave.js';
48
+ export { fetchPortConfig, validatePortConfig } from './services/portConfigApi.js';
49
+ export { EdgeStylingHelper, NodeOperationsHelper, WorkflowOperationsHelper, ConfigurationHelper } from './helpers/workflowEditorHelper.js';
50
+ export { workflowStore, workflowActions, workflowId, workflowName, workflowNodes, workflowEdges, workflowMetadata, workflowChanged, workflowValidation, workflowMetadataChanged } from './stores/workflowStore.js';
24
51
  export * from './config/endpoints.js';
52
+ export { defaultApiConfig, getEndpointUrl } from './config/apiConfig.js';
53
+ export type { ApiConfig } from './config/apiConfig.js';
54
+ export { DEFAULT_PORT_CONFIG } from './config/defaultPortConfig.js';
25
55
  export * from './adapters/WorkflowAdapter.js';
26
56
  export * from './clients/ApiClient.js';
27
57
  export { mountWorkflowEditor, unmountWorkflowEditor, mountFlowDropApp, unmountFlowDropApp } from './svelte-app.js';
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * A Svelte 5 component library built on @xyflow/svelte for creating node-based workflow editors
4
4
  */
5
5
  // Import CSS to ensure styles are included in the library build
6
- import "./styles/base.css";
6
+ import './styles/base.css';
7
7
  // Export API clients
8
8
  export { FlowDropApiClient } from './api/client.js';
9
9
  export { EnhancedFlowDropApiClient } from './api/enhanced-client.js';
@@ -15,6 +15,22 @@ export { default as SimpleNodeComponent } from './components/SimpleNode.svelte';
15
15
  export { default as ToolNodeComponent } from './components/ToolNode.svelte';
16
16
  export { default as NotesNodeComponent } from './components/NotesNode.svelte';
17
17
  export { default as CanvasBanner } from './components/CanvasBanner.svelte';
18
+ export { default as UniversalNode } from './components/UniversalNode.svelte';
19
+ export { default as GatewayNode } from './components/GatewayNode.svelte';
20
+ export { default as SquareNode } from './components/SquareNode.svelte';
21
+ export { default as LoadingSpinner } from './components/LoadingSpinner.svelte';
22
+ export { default as StatusIcon } from './components/StatusIcon.svelte';
23
+ export { default as StatusLabel } from './components/StatusLabel.svelte';
24
+ export { default as NodeStatusOverlay } from './components/NodeStatusOverlay.svelte';
25
+ export { default as MarkdownDisplay } from './components/MarkdownDisplay.svelte';
26
+ export { default as ConfigForm } from './components/ConfigForm.svelte';
27
+ export { default as ConfigModal } from './components/ConfigModal.svelte';
28
+ export { default as ConfigSidebar } from './components/ConfigSidebar.svelte';
29
+ export { default as ConnectionLine } from './components/ConnectionLine.svelte';
30
+ export { default as LogsSidebar } from './components/LogsSidebar.svelte';
31
+ export { default as PipelineStatus } from './components/PipelineStatus.svelte';
32
+ export { default as Navbar } from './components/Navbar.svelte';
33
+ export { default as Logo } from './components/Logo.svelte';
18
34
  // Export sample data for development
19
35
  export { sampleNodes, sampleWorkflow } from './data/samples.js';
20
36
  // Export utilities
@@ -23,10 +39,23 @@ export * from './utils/colors.js';
23
39
  export * from './utils/connections.js';
24
40
  export * from './utils/config.js';
25
41
  export * from './utils/nodeTypes.js';
42
+ export { getStatusColor, getStatusIcon, getStatusLabel, getStatusBackgroundColor, getStatusTextColor, createDefaultExecutionInfo, updateExecutionStart, updateExecutionComplete, updateExecutionFailed, resetExecutionInfo, formatExecutionDuration, formatLastExecuted } from './utils/nodeStatus.js';
43
+ export { createNodeWrapperConfig, shouldShowNodeStatus, getOptimalStatusPosition, getOptimalStatusSize, DEFAULT_NODE_STATUS_CONFIG } from './utils/nodeWrapper.js';
26
44
  // Export services
27
45
  export * from './services/api.js';
46
+ export { showSuccess, showError, showWarning, showInfo, showLoading, dismissToast, dismissAllToasts, showPromise, showConfirmation, apiToasts, workflowToasts, pipelineToasts } from './services/toastService.js';
47
+ export { NodeExecutionService, nodeExecutionService } from './services/nodeExecutionService.js';
48
+ export { saveWorkflow, updateWorkflow, getWorkflow, getWorkflows, deleteWorkflow, getWorkflowCount, initializeSampleWorkflows } from './services/workflowStorage.js';
49
+ export { globalSaveWorkflow, globalExportWorkflow, initializeGlobalSave } from './services/globalSave.js';
50
+ export { fetchPortConfig, validatePortConfig } from './services/portConfigApi.js';
51
+ // Export helpers
52
+ export { EdgeStylingHelper, NodeOperationsHelper, WorkflowOperationsHelper, ConfigurationHelper } from './helpers/workflowEditorHelper.js';
53
+ // Export stores
54
+ export { workflowStore, workflowActions, workflowId, workflowName, workflowNodes, workflowEdges, workflowMetadata, workflowChanged, workflowValidation, workflowMetadataChanged } from './stores/workflowStore.js';
28
55
  // Export endpoint configuration
29
56
  export * from './config/endpoints.js';
57
+ export { defaultApiConfig, getEndpointUrl } from './config/apiConfig.js';
58
+ export { DEFAULT_PORT_CONFIG } from './config/defaultPortConfig.js';
30
59
  // Export adapters
31
60
  export * from './adapters/WorkflowAdapter.js';
32
61
  // Export API client
@@ -1,5 +1,5 @@
1
- export function goto(url: any, options?: {}): Promise<void>;
2
- export function invalidate(url: any): Promise<void>;
1
+ export function goto(): Promise<void>;
2
+ export function invalidate(): Promise<void>;
3
3
  export function invalidateAll(): Promise<void>;
4
- export function preloadData(url: any): Promise<{}>;
5
- export function preloadCode(url: any): Promise<void>;
4
+ export function preloadData(): Promise<{}>;
5
+ export function preloadCode(): Promise<void>;
@@ -4,13 +4,13 @@
4
4
  */
5
5
 
6
6
  // Mock goto function
7
- export const goto = async (url, options = {}) => {
7
+ export const goto = async () => {
8
8
  // No-op for library context
9
9
  console.warn('Navigation not available in library context');
10
10
  };
11
11
 
12
12
  // Mock invalidate function
13
- export const invalidate = async (url) => {
13
+ export const invalidate = async () => {
14
14
  // No-op for library context
15
15
  return Promise.resolve();
16
16
  };
@@ -22,13 +22,13 @@ export const invalidateAll = async () => {
22
22
  };
23
23
 
24
24
  // Mock preloadData function
25
- export const preloadData = async (url) => {
25
+ export const preloadData = async () => {
26
26
  // No-op for library context
27
27
  return Promise.resolve({});
28
28
  };
29
29
 
30
30
  // Mock preloadCode function
31
- export const preloadCode = async (url) => {
31
+ export const preloadCode = async () => {
32
32
  // No-op for library context
33
33
  return Promise.resolve();
34
34
  };
@@ -28,7 +28,7 @@ export function setApiBaseUrl(url) {
28
28
  .then(({ createEndpointConfig }) => {
29
29
  endpointConfig = createEndpointConfig(url);
30
30
  })
31
- .catch((error) => {
31
+ .catch(() => {
32
32
  // Failed to load endpoint config
33
33
  });
34
34
  }
@@ -43,24 +43,19 @@ async function apiRequest(endpointKey, endpointPath, params, options = {}) {
43
43
  if (!endpointConfig) {
44
44
  throw new Error('Endpoint configuration not set. Call setEndpointConfig() first.');
45
45
  }
46
- try {
47
- const url = buildEndpointUrl(endpointConfig, endpointPath, params);
48
- const method = getEndpointMethod(endpointConfig, endpointKey);
49
- const headers = getEndpointHeaders(endpointConfig, endpointKey);
50
- const response = await fetch(url, {
51
- method,
52
- headers,
53
- ...options
54
- });
55
- const data = await response.json();
56
- if (!response.ok) {
57
- throw new Error(data.error || `HTTP ${response.status}: ${response.statusText}`);
58
- }
59
- return data;
60
- }
61
- catch (error) {
62
- throw error;
46
+ const url = buildEndpointUrl(endpointConfig, endpointPath, params);
47
+ const method = getEndpointMethod(endpointConfig, endpointKey);
48
+ const headers = getEndpointHeaders(endpointConfig, endpointKey);
49
+ const response = await fetch(url, {
50
+ method,
51
+ headers,
52
+ ...options
53
+ });
54
+ const data = await response.json();
55
+ if (!response.ok) {
56
+ throw new Error(data.error || `HTTP ${response.status}: ${response.statusText}`);
63
57
  }
58
+ return data;
64
59
  }
65
60
  /**
66
61
  * Node API methods