@d34dman/flowdrop 0.0.15 → 0.0.17

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 (40) hide show
  1. package/README.md +64 -1
  2. package/dist/api/enhanced-client.d.ts +119 -3
  3. package/dist/api/enhanced-client.js +233 -54
  4. package/dist/components/App.svelte +145 -33
  5. package/dist/components/App.svelte.d.ts +27 -1
  6. package/dist/components/FlowDropZone.svelte +4 -5
  7. package/dist/components/FlowDropZone.svelte.d.ts +1 -1
  8. package/dist/components/UniversalNode.svelte +94 -34
  9. package/dist/components/WorkflowEditor.svelte +63 -3
  10. package/dist/config/runtimeConfig.d.ts +2 -2
  11. package/dist/config/runtimeConfig.js +7 -7
  12. package/dist/data/samples.js +9 -9
  13. package/dist/examples/adapter-usage.js +1 -1
  14. package/dist/helpers/workflowEditorHelper.d.ts +44 -4
  15. package/dist/helpers/workflowEditorHelper.js +161 -30
  16. package/dist/index.d.ts +12 -2
  17. package/dist/index.js +20 -1
  18. package/dist/registry/builtinNodes.d.ts +77 -0
  19. package/dist/registry/builtinNodes.js +181 -0
  20. package/dist/registry/index.d.ts +7 -0
  21. package/dist/registry/index.js +10 -0
  22. package/dist/registry/nodeComponentRegistry.d.ts +307 -0
  23. package/dist/registry/nodeComponentRegistry.js +315 -0
  24. package/dist/registry/plugin.d.ts +215 -0
  25. package/dist/registry/plugin.js +249 -0
  26. package/dist/services/draftStorage.d.ts +171 -0
  27. package/dist/services/draftStorage.js +298 -0
  28. package/dist/stores/workflowStore.d.ts +103 -0
  29. package/dist/stores/workflowStore.js +249 -29
  30. package/dist/styles/base.css +15 -0
  31. package/dist/svelte-app.d.ts +110 -28
  32. package/dist/svelte-app.js +150 -27
  33. package/dist/types/auth.d.ts +278 -0
  34. package/dist/types/auth.js +244 -0
  35. package/dist/types/events.d.ts +163 -0
  36. package/dist/types/events.js +30 -0
  37. package/dist/types/index.d.ts +38 -3
  38. package/dist/utils/nodeTypes.d.ts +76 -21
  39. package/dist/utils/nodeTypes.js +180 -32
  40. package/package.json +1 -2
@@ -1,9 +1,60 @@
1
+ /**
2
+ * Workflow Store for FlowDrop
3
+ *
4
+ * Provides global state management for workflows with dirty state tracking.
5
+ *
6
+ * @module stores/workflowStore
7
+ */
1
8
  import type { Workflow, WorkflowNode, WorkflowEdge } from '../types';
9
+ import type { WorkflowChangeType } from '../types/events.js';
10
+ /** Global workflow state */
2
11
  export declare const workflowStore: import("svelte/store").Writable<Workflow>;
12
+ /**
13
+ * Store for tracking if there are unsaved changes
14
+ *
15
+ * This is set to true whenever the workflow changes after initialization.
16
+ * It can be reset to false by calling markAsSaved().
17
+ */
18
+ export declare const isDirtyStore: import("svelte/store").Writable<boolean>;
19
+ /**
20
+ * Set the dirty state change callback
21
+ *
22
+ * @param callback - Function to call when dirty state changes
23
+ */
24
+ export declare function setOnDirtyStateChange(callback: ((isDirty: boolean) => void) | null): void;
25
+ /**
26
+ * Set the workflow change callback
27
+ *
28
+ * @param callback - Function to call when workflow changes
29
+ */
30
+ export declare function setOnWorkflowChange(callback: ((workflow: Workflow, changeType: WorkflowChangeType) => void) | null): void;
31
+ /**
32
+ * Mark the current workflow state as saved
33
+ *
34
+ * Clears the dirty state by updating the saved snapshot.
35
+ */
36
+ export declare function markAsSaved(): void;
37
+ /**
38
+ * Check if there are unsaved changes
39
+ *
40
+ * @returns true if there are unsaved changes
41
+ */
42
+ export declare function isDirty(): boolean;
43
+ /**
44
+ * Get the current workflow
45
+ *
46
+ * @returns The current workflow or null
47
+ */
48
+ export declare function getWorkflow(): Workflow | null;
49
+ /** Derived store for workflow ID */
3
50
  export declare const workflowId: import("svelte/store").Readable<string>;
51
+ /** Derived store for workflow name */
4
52
  export declare const workflowName: import("svelte/store").Readable<string>;
53
+ /** Derived store for workflow nodes */
5
54
  export declare const workflowNodes: import("svelte/store").Readable<WorkflowNode[]>;
55
+ /** Derived store for workflow edges */
6
56
  export declare const workflowEdges: import("svelte/store").Readable<WorkflowEdge[]>;
57
+ /** Derived store for workflow metadata */
7
58
  export declare const workflowMetadata: import("svelte/store").Readable<{
8
59
  version: string;
9
60
  createdAt: string;
@@ -13,19 +64,68 @@ export declare const workflowMetadata: import("svelte/store").Readable<{
13
64
  versionId?: string;
14
65
  updateNumber?: number;
15
66
  }>;
67
+ /**
68
+ * Actions for updating the workflow
69
+ *
70
+ * All actions that modify the workflow will trigger dirty state updates
71
+ * and emit change events.
72
+ */
16
73
  export declare const workflowActions: {
74
+ /**
75
+ * Initialize workflow (from load or new)
76
+ *
77
+ * This sets the initial saved snapshot and clears dirty state.
78
+ */
17
79
  initialize: (workflow: Workflow) => void;
80
+ /**
81
+ * Update the entire workflow
82
+ */
18
83
  updateWorkflow: (workflow: Workflow) => void;
84
+ /**
85
+ * Update nodes
86
+ */
19
87
  updateNodes: (nodes: WorkflowNode[]) => void;
88
+ /**
89
+ * Update edges
90
+ */
20
91
  updateEdges: (edges: WorkflowEdge[]) => void;
92
+ /**
93
+ * Update workflow name
94
+ */
21
95
  updateName: (name: string) => void;
96
+ /**
97
+ * Add a node
98
+ */
22
99
  addNode: (node: WorkflowNode) => void;
100
+ /**
101
+ * Remove a node
102
+ */
23
103
  removeNode: (nodeId: string) => void;
104
+ /**
105
+ * Add an edge
106
+ */
24
107
  addEdge: (edge: WorkflowEdge) => void;
108
+ /**
109
+ * Remove an edge
110
+ */
25
111
  removeEdge: (edgeId: string) => void;
112
+ /**
113
+ * Update a specific node
114
+ */
26
115
  updateNode: (nodeId: string, updates: Partial<WorkflowNode>) => void;
116
+ /**
117
+ * Clear the workflow
118
+ */
27
119
  clear: () => void;
120
+ /**
121
+ * Update workflow metadata
122
+ */
28
123
  updateMetadata: (metadata: Partial<Workflow["metadata"]>) => void;
124
+ /**
125
+ * Batch update nodes and edges
126
+ *
127
+ * Useful for complex operations that update multiple things at once.
128
+ */
29
129
  batchUpdate: (updates: {
30
130
  nodes?: WorkflowNode[];
31
131
  edges?: WorkflowEdge[];
@@ -34,11 +134,13 @@ export declare const workflowActions: {
34
134
  metadata?: Partial<Workflow["metadata"]>;
35
135
  }) => void;
36
136
  };
137
+ /** Derived store for workflow changes (useful for triggering saves) */
37
138
  export declare const workflowChanged: import("svelte/store").Readable<{
38
139
  nodes: WorkflowNode[];
39
140
  edges: WorkflowEdge[];
40
141
  name: string;
41
142
  }>;
143
+ /** Derived store for workflow validation */
42
144
  export declare const workflowValidation: import("svelte/store").Readable<{
43
145
  hasNodes: boolean;
44
146
  hasEdges: boolean;
@@ -46,6 +148,7 @@ export declare const workflowValidation: import("svelte/store").Readable<{
46
148
  edgeCount: number;
47
149
  isValid: boolean;
48
150
  }>;
151
+ /** Derived store for workflow metadata changes */
49
152
  export declare const workflowMetadataChanged: import("svelte/store").Readable<{
50
153
  createdAt: string;
51
154
  updatedAt: string;
@@ -1,19 +1,176 @@
1
- import { writable, derived } from 'svelte/store';
2
- // Global workflow state
1
+ /**
2
+ * Workflow Store for FlowDrop
3
+ *
4
+ * Provides global state management for workflows with dirty state tracking.
5
+ *
6
+ * @module stores/workflowStore
7
+ */
8
+ import { writable, derived, get } from 'svelte/store';
9
+ // =========================================================================
10
+ // Core Workflow Store
11
+ // =========================================================================
12
+ /** Global workflow state */
3
13
  export const workflowStore = writable(null);
4
- // Derived stores for individual workflow properties
5
- export const workflowId = derived(workflowStore, ($workflow) => $workflow?.id || null);
6
- export const workflowName = derived(workflowStore, ($workflow) => $workflow?.name || 'Untitled Workflow');
7
- export const workflowNodes = derived(workflowStore, ($workflow) => $workflow?.nodes || []);
8
- export const workflowEdges = derived(workflowStore, ($workflow) => $workflow?.edges || []);
9
- export const workflowMetadata = derived(workflowStore, ($workflow) => $workflow?.metadata || {
14
+ // =========================================================================
15
+ // Dirty State Tracking
16
+ // =========================================================================
17
+ /**
18
+ * Store for tracking if there are unsaved changes
19
+ *
20
+ * This is set to true whenever the workflow changes after initialization.
21
+ * It can be reset to false by calling markAsSaved().
22
+ */
23
+ export const isDirtyStore = writable(false);
24
+ /**
25
+ * Snapshot of the workflow when it was last saved
26
+ *
27
+ * Used to compare current state with saved state.
28
+ */
29
+ let savedSnapshot = null;
30
+ /**
31
+ * Callback for dirty state changes
32
+ *
33
+ * Set by the App component to notify parent application.
34
+ */
35
+ let onDirtyStateChangeCallback = null;
36
+ /**
37
+ * Callback for workflow changes
38
+ *
39
+ * Set by the App component to notify parent application.
40
+ */
41
+ let onWorkflowChangeCallback = null;
42
+ /**
43
+ * Set the dirty state change callback
44
+ *
45
+ * @param callback - Function to call when dirty state changes
46
+ */
47
+ export function setOnDirtyStateChange(callback) {
48
+ onDirtyStateChangeCallback = callback;
49
+ }
50
+ /**
51
+ * Set the workflow change callback
52
+ *
53
+ * @param callback - Function to call when workflow changes
54
+ */
55
+ export function setOnWorkflowChange(callback) {
56
+ onWorkflowChangeCallback = callback;
57
+ }
58
+ /**
59
+ * Create a snapshot of the workflow for comparison
60
+ *
61
+ * @param workflow - The workflow to snapshot
62
+ * @returns A JSON string representation for comparison
63
+ */
64
+ function createSnapshot(workflow) {
65
+ if (!workflow)
66
+ return null;
67
+ // Only include the parts that matter for "dirty" detection
68
+ const toSnapshot = {
69
+ name: workflow.name,
70
+ description: workflow.description,
71
+ nodes: workflow.nodes.map((n) => ({
72
+ id: n.id,
73
+ position: n.position,
74
+ data: {
75
+ label: n.data.label,
76
+ config: n.data.config
77
+ }
78
+ })),
79
+ edges: workflow.edges.map((e) => ({
80
+ id: e.id,
81
+ source: e.source,
82
+ target: e.target,
83
+ sourceHandle: e.sourceHandle,
84
+ targetHandle: e.targetHandle
85
+ }))
86
+ };
87
+ return JSON.stringify(toSnapshot);
88
+ }
89
+ /**
90
+ * Update dirty state based on current workflow
91
+ *
92
+ * Compares current workflow with saved snapshot.
93
+ */
94
+ function updateDirtyState() {
95
+ const currentWorkflow = get(workflowStore);
96
+ const currentSnapshot = createSnapshot(currentWorkflow);
97
+ const isDirty = currentSnapshot !== savedSnapshot;
98
+ const previousDirty = get(isDirtyStore);
99
+ if (isDirty !== previousDirty) {
100
+ isDirtyStore.set(isDirty);
101
+ if (onDirtyStateChangeCallback) {
102
+ onDirtyStateChangeCallback(isDirty);
103
+ }
104
+ }
105
+ }
106
+ /**
107
+ * Mark the workflow change and update dirty state
108
+ *
109
+ * @param changeType - The type of change that occurred
110
+ */
111
+ function notifyWorkflowChange(changeType) {
112
+ const workflow = get(workflowStore);
113
+ if (workflow && onWorkflowChangeCallback) {
114
+ onWorkflowChangeCallback(workflow, changeType);
115
+ }
116
+ updateDirtyState();
117
+ }
118
+ /**
119
+ * Mark the current workflow state as saved
120
+ *
121
+ * Clears the dirty state by updating the saved snapshot.
122
+ */
123
+ export function markAsSaved() {
124
+ const currentWorkflow = get(workflowStore);
125
+ savedSnapshot = createSnapshot(currentWorkflow);
126
+ isDirtyStore.set(false);
127
+ if (onDirtyStateChangeCallback) {
128
+ onDirtyStateChangeCallback(false);
129
+ }
130
+ }
131
+ /**
132
+ * Check if there are unsaved changes
133
+ *
134
+ * @returns true if there are unsaved changes
135
+ */
136
+ export function isDirty() {
137
+ return get(isDirtyStore);
138
+ }
139
+ /**
140
+ * Get the current workflow
141
+ *
142
+ * @returns The current workflow or null
143
+ */
144
+ export function getWorkflow() {
145
+ return get(workflowStore);
146
+ }
147
+ // =========================================================================
148
+ // Derived Stores
149
+ // =========================================================================
150
+ /** Derived store for workflow ID */
151
+ export const workflowId = derived(workflowStore, ($workflow) => $workflow?.id ?? null);
152
+ /** Derived store for workflow name */
153
+ export const workflowName = derived(workflowStore, ($workflow) => $workflow?.name ?? 'Untitled Workflow');
154
+ /** Derived store for workflow nodes */
155
+ export const workflowNodes = derived(workflowStore, ($workflow) => $workflow?.nodes ?? []);
156
+ /** Derived store for workflow edges */
157
+ export const workflowEdges = derived(workflowStore, ($workflow) => $workflow?.edges ?? []);
158
+ /** Derived store for workflow metadata */
159
+ export const workflowMetadata = derived(workflowStore, ($workflow) => $workflow?.metadata ?? {
10
160
  version: '1.0.0',
11
161
  createdAt: new Date().toISOString(),
12
162
  updatedAt: new Date().toISOString(),
13
163
  versionId: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
14
164
  updateNumber: 0
15
165
  });
16
- // Helper function to check if workflow data has actually changed
166
+ // =========================================================================
167
+ // Helper Functions
168
+ // =========================================================================
169
+ /**
170
+ * Check if workflow data has actually changed
171
+ *
172
+ * Used to prevent unnecessary updates and infinite loops.
173
+ */
17
174
  function hasWorkflowDataChanged(currentWorkflow, newNodes, newEdges) {
18
175
  if (!currentWorkflow)
19
176
  return true;
@@ -48,17 +205,40 @@ function hasWorkflowDataChanged(currentWorkflow, newNodes, newEdges) {
48
205
  }
49
206
  return false;
50
207
  }
51
- // Actions for updating the workflow
208
+ // =========================================================================
209
+ // Workflow Actions
210
+ // =========================================================================
211
+ /**
212
+ * Actions for updating the workflow
213
+ *
214
+ * All actions that modify the workflow will trigger dirty state updates
215
+ * and emit change events.
216
+ */
52
217
  export const workflowActions = {
53
- // Initialize workflow
218
+ /**
219
+ * Initialize workflow (from load or new)
220
+ *
221
+ * This sets the initial saved snapshot and clears dirty state.
222
+ */
54
223
  initialize: (workflow) => {
55
224
  workflowStore.set(workflow);
225
+ // Set the saved snapshot - workflow is "clean" after initialization
226
+ savedSnapshot = createSnapshot(workflow);
227
+ isDirtyStore.set(false);
228
+ if (onDirtyStateChangeCallback) {
229
+ onDirtyStateChangeCallback(false);
230
+ }
56
231
  },
57
- // Update the entire workflow
232
+ /**
233
+ * Update the entire workflow
234
+ */
58
235
  updateWorkflow: (workflow) => {
59
236
  workflowStore.set(workflow);
237
+ notifyWorkflowChange('metadata');
60
238
  },
61
- // Update nodes
239
+ /**
240
+ * Update nodes
241
+ */
62
242
  updateNodes: (nodes) => {
63
243
  workflowStore.update(($workflow) => {
64
244
  if (!$workflow)
@@ -76,12 +256,15 @@ export const workflowActions = {
76
256
  ...$workflow.metadata,
77
257
  updatedAt: new Date().toISOString(),
78
258
  versionId,
79
- updateNumber: ($workflow.metadata?.updateNumber || 0) + 1
259
+ updateNumber: ($workflow.metadata?.updateNumber ?? 0) + 1
80
260
  }
81
261
  };
82
262
  });
263
+ notifyWorkflowChange('node_move');
83
264
  },
84
- // Update edges
265
+ /**
266
+ * Update edges
267
+ */
85
268
  updateEdges: (edges) => {
86
269
  workflowStore.update(($workflow) => {
87
270
  if (!$workflow)
@@ -99,12 +282,15 @@ export const workflowActions = {
99
282
  ...$workflow.metadata,
100
283
  updatedAt: new Date().toISOString(),
101
284
  versionId,
102
- updateNumber: ($workflow.metadata?.updateNumber || 0) + 1
285
+ updateNumber: ($workflow.metadata?.updateNumber ?? 0) + 1
103
286
  }
104
287
  };
105
288
  });
289
+ notifyWorkflowChange('edge_add');
106
290
  },
107
- // Update workflow name
291
+ /**
292
+ * Update workflow name
293
+ */
108
294
  updateName: (name) => {
109
295
  workflowStore.update(($workflow) => {
110
296
  if (!$workflow)
@@ -118,8 +304,11 @@ export const workflowActions = {
118
304
  }
119
305
  };
120
306
  });
307
+ notifyWorkflowChange('name');
121
308
  },
122
- // Add a node
309
+ /**
310
+ * Add a node
311
+ */
123
312
  addNode: (node) => {
124
313
  workflowStore.update(($workflow) => {
125
314
  if (!$workflow)
@@ -133,8 +322,11 @@ export const workflowActions = {
133
322
  }
134
323
  };
135
324
  });
325
+ notifyWorkflowChange('node_add');
136
326
  },
137
- // Remove a node
327
+ /**
328
+ * Remove a node
329
+ */
138
330
  removeNode: (nodeId) => {
139
331
  workflowStore.update(($workflow) => {
140
332
  if (!$workflow)
@@ -149,8 +341,11 @@ export const workflowActions = {
149
341
  }
150
342
  };
151
343
  });
344
+ notifyWorkflowChange('node_remove');
152
345
  },
153
- // Add an edge
346
+ /**
347
+ * Add an edge
348
+ */
154
349
  addEdge: (edge) => {
155
350
  workflowStore.update(($workflow) => {
156
351
  if (!$workflow)
@@ -164,8 +359,11 @@ export const workflowActions = {
164
359
  }
165
360
  };
166
361
  });
362
+ notifyWorkflowChange('edge_add');
167
363
  },
168
- // Remove an edge
364
+ /**
365
+ * Remove an edge
366
+ */
169
367
  removeEdge: (edgeId) => {
170
368
  workflowStore.update(($workflow) => {
171
369
  if (!$workflow)
@@ -179,8 +377,11 @@ export const workflowActions = {
179
377
  }
180
378
  };
181
379
  });
380
+ notifyWorkflowChange('edge_remove');
182
381
  },
183
- // Update a specific node
382
+ /**
383
+ * Update a specific node
384
+ */
184
385
  updateNode: (nodeId, updates) => {
185
386
  workflowStore.update(($workflow) => {
186
387
  if (!$workflow)
@@ -194,12 +395,22 @@ export const workflowActions = {
194
395
  }
195
396
  };
196
397
  });
398
+ notifyWorkflowChange('node_config');
197
399
  },
198
- // Clear the workflow
400
+ /**
401
+ * Clear the workflow
402
+ */
199
403
  clear: () => {
200
404
  workflowStore.set(null);
405
+ savedSnapshot = null;
406
+ isDirtyStore.set(false);
407
+ if (onDirtyStateChangeCallback) {
408
+ onDirtyStateChangeCallback(false);
409
+ }
201
410
  },
202
- // Update workflow metadata
411
+ /**
412
+ * Update workflow metadata
413
+ */
203
414
  updateMetadata: (metadata) => {
204
415
  workflowStore.update(($workflow) => {
205
416
  if (!$workflow)
@@ -213,8 +424,13 @@ export const workflowActions = {
213
424
  }
214
425
  };
215
426
  });
427
+ notifyWorkflowChange('metadata');
216
428
  },
217
- // Batch update nodes and edges (useful for complex operations)
429
+ /**
430
+ * Batch update nodes and edges
431
+ *
432
+ * Useful for complex operations that update multiple things at once.
433
+ */
218
434
  batchUpdate: (updates) => {
219
435
  workflowStore.update(($workflow) => {
220
436
  if (!$workflow)
@@ -232,11 +448,15 @@ export const workflowActions = {
232
448
  }
233
449
  };
234
450
  });
451
+ notifyWorkflowChange('metadata');
235
452
  }
236
453
  };
237
- // Derived store for workflow changes (useful for triggering saves)
454
+ // =========================================================================
455
+ // Additional Derived Stores
456
+ // =========================================================================
457
+ /** Derived store for workflow changes (useful for triggering saves) */
238
458
  export const workflowChanged = derived([workflowNodes, workflowEdges, workflowName], ([nodes, edges, name]) => ({ nodes, edges, name }));
239
- // Derived store for workflow validation
459
+ /** Derived store for workflow validation */
240
460
  export const workflowValidation = derived([workflowNodes, workflowEdges], ([nodes, edges]) => ({
241
461
  hasNodes: nodes.length > 0,
242
462
  hasEdges: edges.length > 0,
@@ -244,9 +464,9 @@ export const workflowValidation = derived([workflowNodes, workflowEdges], ([node
244
464
  edgeCount: edges.length,
245
465
  isValid: nodes.length > 0 && edges.length >= 0
246
466
  }));
247
- // Derived store for workflow metadata changes
467
+ /** Derived store for workflow metadata changes */
248
468
  export const workflowMetadataChanged = derived(workflowMetadata, (metadata) => ({
249
469
  createdAt: metadata.createdAt,
250
470
  updatedAt: metadata.updatedAt,
251
- version: metadata.version || '1.0.0'
471
+ version: metadata.version ?? '1.0.0'
252
472
  }));
@@ -1141,6 +1141,21 @@
1141
1141
  --cmp-node-color-slate: var(--color-ref-slate-500);
1142
1142
  --cmp-node-color-purple: var(--color-ref-purple-600);
1143
1143
 
1144
+ /* Edge styling tokens */
1145
+ --flowdrop-edge-trigger-color: var(--color-ref-gray-900);
1146
+ --flowdrop-edge-trigger-color-hover: var(--color-ref-gray-900);
1147
+ --flowdrop-edge-trigger-color-selected: var(--color-ref-violet-600);
1148
+ --flowdrop-edge-trigger-width: 2px;
1149
+ --flowdrop-edge-trigger-width-hover: 3px;
1150
+
1151
+ --flowdrop-edge-tool-color: var(--color-ref-amber-500);
1152
+ --flowdrop-edge-tool-color-hover: var(--color-ref-amber-600);
1153
+ --flowdrop-edge-tool-color-selected: var(--color-ref-violet-600);
1154
+
1155
+ --flowdrop-edge-data-color: var(--color-ref-gray-400);
1156
+ --flowdrop-edge-data-color-hover: var(--color-ref-gray-500);
1157
+ --flowdrop-edge-data-color-selected: var(--color-ref-violet-600);
1158
+
1144
1159
  /* NotesNode component variables */
1145
1160
  --notes-node-width: 500px;
1146
1161
  --notes-node-min-width: 250px;