@d34dman/flowdrop 0.0.16 → 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.
- package/README.md +64 -0
- package/dist/api/enhanced-client.d.ts +3 -3
- package/dist/api/enhanced-client.js +57 -57
- package/dist/components/FlowDropZone.svelte +4 -5
- package/dist/components/FlowDropZone.svelte.d.ts +1 -1
- package/dist/components/UniversalNode.svelte +94 -34
- package/dist/components/WorkflowEditor.svelte +63 -3
- package/dist/config/runtimeConfig.d.ts +2 -2
- package/dist/config/runtimeConfig.js +7 -7
- package/dist/helpers/workflowEditorHelper.d.ts +44 -4
- package/dist/helpers/workflowEditorHelper.js +161 -30
- package/dist/index.d.ts +16 -13
- package/dist/index.js +19 -8
- package/dist/registry/builtinNodes.d.ts +77 -0
- package/dist/registry/builtinNodes.js +181 -0
- package/dist/registry/index.d.ts +7 -0
- package/dist/registry/index.js +10 -0
- package/dist/registry/nodeComponentRegistry.d.ts +307 -0
- package/dist/registry/nodeComponentRegistry.js +315 -0
- package/dist/registry/plugin.d.ts +215 -0
- package/dist/registry/plugin.js +249 -0
- package/dist/services/draftStorage.d.ts +1 -1
- package/dist/services/draftStorage.js +5 -5
- package/dist/stores/workflowStore.d.ts +2 -2
- package/dist/stores/workflowStore.js +16 -16
- package/dist/styles/base.css +15 -0
- package/dist/svelte-app.d.ts +6 -6
- package/dist/svelte-app.js +25 -25
- package/dist/types/auth.d.ts +2 -2
- package/dist/types/auth.js +7 -7
- package/dist/types/events.d.ts +2 -2
- package/dist/types/index.d.ts +38 -3
- package/dist/utils/nodeTypes.d.ts +76 -21
- package/dist/utils/nodeTypes.js +180 -32
- package/package.json +2 -2
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlowDrop Plugin System
|
|
3
|
+
* Provides APIs for external libraries to register custom node components.
|
|
4
|
+
*
|
|
5
|
+
* This enables a plugin ecosystem where:
|
|
6
|
+
* - Third-party libraries can provide custom node types
|
|
7
|
+
* - Custom nodes are namespaced to avoid conflicts
|
|
8
|
+
* - Registration is simplified with a clean API
|
|
9
|
+
*/
|
|
10
|
+
import { nodeComponentRegistry, createNamespacedType } from './nodeComponentRegistry.js';
|
|
11
|
+
/**
|
|
12
|
+
* Register a FlowDrop plugin with custom node components.
|
|
13
|
+
* All node types are automatically namespaced with the plugin namespace.
|
|
14
|
+
*
|
|
15
|
+
* @param config - Plugin configuration with namespace and node definitions
|
|
16
|
+
* @returns Result object with registered types and any errors
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { registerFlowDropPlugin } from "@flowdrop/lib";
|
|
21
|
+
* import FancyNode from "./FancyNode.svelte";
|
|
22
|
+
* import GlowNode from "./GlowNode.svelte";
|
|
23
|
+
*
|
|
24
|
+
* const result = registerFlowDropPlugin({
|
|
25
|
+
* namespace: "awesome",
|
|
26
|
+
* name: "Awesome Nodes",
|
|
27
|
+
* version: "1.0.0",
|
|
28
|
+
* nodes: [
|
|
29
|
+
* {
|
|
30
|
+
* type: "fancy",
|
|
31
|
+
* displayName: "Fancy Node",
|
|
32
|
+
* component: FancyNode,
|
|
33
|
+
* icon: "mdi:sparkles"
|
|
34
|
+
* },
|
|
35
|
+
* {
|
|
36
|
+
* type: "glow",
|
|
37
|
+
* displayName: "Glowing Node",
|
|
38
|
+
* component: GlowNode,
|
|
39
|
+
* icon: "mdi:lightbulb"
|
|
40
|
+
* }
|
|
41
|
+
* ]
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* // Result:
|
|
45
|
+
* // {
|
|
46
|
+
* // success: true,
|
|
47
|
+
* // namespace: "awesome",
|
|
48
|
+
* // registeredTypes: ["awesome:fancy", "awesome:glow"],
|
|
49
|
+
* // errors: []
|
|
50
|
+
* // }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export function registerFlowDropPlugin(config) {
|
|
54
|
+
const result = {
|
|
55
|
+
success: true,
|
|
56
|
+
namespace: config.namespace,
|
|
57
|
+
registeredTypes: [],
|
|
58
|
+
errors: []
|
|
59
|
+
};
|
|
60
|
+
// Validate namespace
|
|
61
|
+
if (!isValidNamespace(config.namespace)) {
|
|
62
|
+
result.success = false;
|
|
63
|
+
result.errors.push(`Invalid namespace "${config.namespace}". ` +
|
|
64
|
+
`Namespace must be lowercase alphanumeric with optional hyphens.`);
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
// Register each node
|
|
68
|
+
for (const nodeDef of config.nodes) {
|
|
69
|
+
try {
|
|
70
|
+
const namespacedType = createNamespacedType(config.namespace, nodeDef.type);
|
|
71
|
+
const registration = {
|
|
72
|
+
type: namespacedType,
|
|
73
|
+
displayName: nodeDef.displayName,
|
|
74
|
+
description: nodeDef.description,
|
|
75
|
+
component: nodeDef.component,
|
|
76
|
+
icon: nodeDef.icon,
|
|
77
|
+
category: nodeDef.category ?? 'custom',
|
|
78
|
+
source: config.namespace,
|
|
79
|
+
statusPosition: nodeDef.statusPosition,
|
|
80
|
+
statusSize: nodeDef.statusSize
|
|
81
|
+
};
|
|
82
|
+
nodeComponentRegistry.register(registration);
|
|
83
|
+
result.registeredTypes.push(namespacedType);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
result.success = false;
|
|
87
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
88
|
+
result.errors.push(`Failed to register ${config.namespace}:${nodeDef.type}: ${errorMessage}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Unregister all nodes from a plugin by namespace.
|
|
95
|
+
*
|
|
96
|
+
* @param namespace - The plugin namespace to unregister
|
|
97
|
+
* @returns Array of unregistered type identifiers
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* const removed = unregisterFlowDropPlugin("awesome");
|
|
102
|
+
* // Returns ["awesome:fancy", "awesome:glow"]
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export function unregisterFlowDropPlugin(namespace) {
|
|
106
|
+
const unregistered = [];
|
|
107
|
+
const types = nodeComponentRegistry.getTypes();
|
|
108
|
+
for (const type of types) {
|
|
109
|
+
if (type.startsWith(`${namespace}:`)) {
|
|
110
|
+
if (nodeComponentRegistry.unregister(type)) {
|
|
111
|
+
unregistered.push(type);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return unregistered;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Check if a namespace is valid.
|
|
119
|
+
* Must be lowercase alphanumeric with optional hyphens.
|
|
120
|
+
*
|
|
121
|
+
* @param namespace - The namespace to validate
|
|
122
|
+
* @returns true if valid
|
|
123
|
+
*/
|
|
124
|
+
export function isValidNamespace(namespace) {
|
|
125
|
+
return /^[a-z][a-z0-9-]*$/.test(namespace);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get all registered plugins (unique namespaces).
|
|
129
|
+
*
|
|
130
|
+
* @returns Array of namespace strings
|
|
131
|
+
*/
|
|
132
|
+
export function getRegisteredPlugins() {
|
|
133
|
+
const sources = new Set();
|
|
134
|
+
const registrations = nodeComponentRegistry.getAll();
|
|
135
|
+
for (const reg of registrations) {
|
|
136
|
+
if (reg.source && reg.source !== 'flowdrop') {
|
|
137
|
+
sources.add(reg.source);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return Array.from(sources);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get the count of nodes registered by a plugin.
|
|
144
|
+
*
|
|
145
|
+
* @param namespace - The plugin namespace
|
|
146
|
+
* @returns Number of nodes registered by this plugin
|
|
147
|
+
*/
|
|
148
|
+
export function getPluginNodeCount(namespace) {
|
|
149
|
+
return nodeComponentRegistry.getBySource(namespace).length;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Register a single custom node without a full plugin.
|
|
153
|
+
* Useful for project-specific custom nodes.
|
|
154
|
+
*
|
|
155
|
+
* @param type - Type identifier (can be namespaced or plain)
|
|
156
|
+
* @param displayName - Display name for UI
|
|
157
|
+
* @param component - Svelte component
|
|
158
|
+
* @param options - Additional options
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```typescript
|
|
162
|
+
* import { registerCustomNode } from "@flowdrop/lib";
|
|
163
|
+
* import MyNode from "./MyNode.svelte";
|
|
164
|
+
*
|
|
165
|
+
* registerCustomNode("myproject:special", "Special Node", MyNode, {
|
|
166
|
+
* icon: "mdi:star",
|
|
167
|
+
* description: "A special node for my project"
|
|
168
|
+
* });
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
export function registerCustomNode(type, displayName, component, options = {}) {
|
|
172
|
+
nodeComponentRegistry.register({
|
|
173
|
+
type,
|
|
174
|
+
displayName,
|
|
175
|
+
component,
|
|
176
|
+
description: options.description,
|
|
177
|
+
icon: options.icon,
|
|
178
|
+
category: options.category ?? 'custom',
|
|
179
|
+
source: options.source ?? 'custom',
|
|
180
|
+
statusPosition: options.statusPosition,
|
|
181
|
+
statusSize: options.statusSize
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Create a plugin builder for a fluent API experience.
|
|
186
|
+
*
|
|
187
|
+
* @param namespace - Plugin namespace
|
|
188
|
+
* @param name - Plugin name
|
|
189
|
+
* @returns Plugin builder with chainable methods
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* import { createPlugin } from "@flowdrop/lib";
|
|
194
|
+
*
|
|
195
|
+
* createPlugin("awesome", "Awesome Nodes")
|
|
196
|
+
* .version("1.0.0")
|
|
197
|
+
* .node("fancy", "Fancy Node", FancyNode)
|
|
198
|
+
* .node("glow", "Glowing Node", GlowNode, { icon: "mdi:lightbulb" })
|
|
199
|
+
* .register();
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
export function createPlugin(namespace, name) {
|
|
203
|
+
const config = {
|
|
204
|
+
namespace,
|
|
205
|
+
name,
|
|
206
|
+
nodes: []
|
|
207
|
+
};
|
|
208
|
+
const builder = {
|
|
209
|
+
/**
|
|
210
|
+
* Set plugin version
|
|
211
|
+
*/
|
|
212
|
+
version(v) {
|
|
213
|
+
config.version = v;
|
|
214
|
+
return builder;
|
|
215
|
+
},
|
|
216
|
+
/**
|
|
217
|
+
* Set plugin description
|
|
218
|
+
*/
|
|
219
|
+
description(desc) {
|
|
220
|
+
config.description = desc;
|
|
221
|
+
return builder;
|
|
222
|
+
},
|
|
223
|
+
/**
|
|
224
|
+
* Add a node to the plugin
|
|
225
|
+
*/
|
|
226
|
+
node(type, displayName, component, options = {}) {
|
|
227
|
+
config.nodes.push({
|
|
228
|
+
type,
|
|
229
|
+
displayName,
|
|
230
|
+
component,
|
|
231
|
+
...options
|
|
232
|
+
});
|
|
233
|
+
return builder;
|
|
234
|
+
},
|
|
235
|
+
/**
|
|
236
|
+
* Register the plugin
|
|
237
|
+
*/
|
|
238
|
+
register() {
|
|
239
|
+
return registerFlowDropPlugin(config);
|
|
240
|
+
},
|
|
241
|
+
/**
|
|
242
|
+
* Get the config without registering (for testing/inspection)
|
|
243
|
+
*/
|
|
244
|
+
getConfig() {
|
|
245
|
+
return { ...config };
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
return builder;
|
|
249
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
/**
|
|
10
10
|
* Default storage key prefix
|
|
11
11
|
*/
|
|
12
|
-
const STORAGE_KEY_PREFIX =
|
|
12
|
+
const STORAGE_KEY_PREFIX = 'flowdrop:draft';
|
|
13
13
|
/**
|
|
14
14
|
* Generate a storage key for a workflow
|
|
15
15
|
*
|
|
@@ -51,7 +51,7 @@ export function saveDraft(workflow, storageKey) {
|
|
|
51
51
|
}
|
|
52
52
|
catch (error) {
|
|
53
53
|
// localStorage might be full or disabled
|
|
54
|
-
console.warn(
|
|
54
|
+
console.warn('Failed to save draft to localStorage:', error);
|
|
55
55
|
return false;
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -70,13 +70,13 @@ export function loadDraft(storageKey) {
|
|
|
70
70
|
const draft = JSON.parse(stored);
|
|
71
71
|
// Validate the draft structure
|
|
72
72
|
if (!draft.workflow || !draft.metadata) {
|
|
73
|
-
console.warn(
|
|
73
|
+
console.warn('Invalid draft structure in localStorage');
|
|
74
74
|
return null;
|
|
75
75
|
}
|
|
76
76
|
return draft;
|
|
77
77
|
}
|
|
78
78
|
catch (error) {
|
|
79
|
-
console.warn(
|
|
79
|
+
console.warn('Failed to load draft from localStorage:', error);
|
|
80
80
|
return null;
|
|
81
81
|
}
|
|
82
82
|
}
|
|
@@ -90,7 +90,7 @@ export function deleteDraft(storageKey) {
|
|
|
90
90
|
localStorage.removeItem(storageKey);
|
|
91
91
|
}
|
|
92
92
|
catch (error) {
|
|
93
|
-
console.warn(
|
|
93
|
+
console.warn('Failed to delete draft from localStorage:', error);
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
/**
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module stores/workflowStore
|
|
7
7
|
*/
|
|
8
|
-
import type { Workflow, WorkflowNode, WorkflowEdge } from
|
|
9
|
-
import type { WorkflowChangeType } from
|
|
8
|
+
import type { Workflow, WorkflowNode, WorkflowEdge } from '../types';
|
|
9
|
+
import type { WorkflowChangeType } from '../types/events.js';
|
|
10
10
|
/** Global workflow state */
|
|
11
11
|
export declare const workflowStore: import("svelte/store").Writable<Workflow>;
|
|
12
12
|
/**
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module stores/workflowStore
|
|
7
7
|
*/
|
|
8
|
-
import { writable, derived, get } from
|
|
8
|
+
import { writable, derived, get } from 'svelte/store';
|
|
9
9
|
// =========================================================================
|
|
10
10
|
// Core Workflow Store
|
|
11
11
|
// =========================================================================
|
|
@@ -150,14 +150,14 @@ export function getWorkflow() {
|
|
|
150
150
|
/** Derived store for workflow ID */
|
|
151
151
|
export const workflowId = derived(workflowStore, ($workflow) => $workflow?.id ?? null);
|
|
152
152
|
/** Derived store for workflow name */
|
|
153
|
-
export const workflowName = derived(workflowStore, ($workflow) => $workflow?.name ??
|
|
153
|
+
export const workflowName = derived(workflowStore, ($workflow) => $workflow?.name ?? 'Untitled Workflow');
|
|
154
154
|
/** Derived store for workflow nodes */
|
|
155
155
|
export const workflowNodes = derived(workflowStore, ($workflow) => $workflow?.nodes ?? []);
|
|
156
156
|
/** Derived store for workflow edges */
|
|
157
157
|
export const workflowEdges = derived(workflowStore, ($workflow) => $workflow?.edges ?? []);
|
|
158
158
|
/** Derived store for workflow metadata */
|
|
159
159
|
export const workflowMetadata = derived(workflowStore, ($workflow) => $workflow?.metadata ?? {
|
|
160
|
-
version:
|
|
160
|
+
version: '1.0.0',
|
|
161
161
|
createdAt: new Date().toISOString(),
|
|
162
162
|
updatedAt: new Date().toISOString(),
|
|
163
163
|
versionId: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
@@ -234,7 +234,7 @@ export const workflowActions = {
|
|
|
234
234
|
*/
|
|
235
235
|
updateWorkflow: (workflow) => {
|
|
236
236
|
workflowStore.set(workflow);
|
|
237
|
-
notifyWorkflowChange(
|
|
237
|
+
notifyWorkflowChange('metadata');
|
|
238
238
|
},
|
|
239
239
|
/**
|
|
240
240
|
* Update nodes
|
|
@@ -260,7 +260,7 @@ export const workflowActions = {
|
|
|
260
260
|
}
|
|
261
261
|
};
|
|
262
262
|
});
|
|
263
|
-
notifyWorkflowChange(
|
|
263
|
+
notifyWorkflowChange('node_move');
|
|
264
264
|
},
|
|
265
265
|
/**
|
|
266
266
|
* Update edges
|
|
@@ -286,7 +286,7 @@ export const workflowActions = {
|
|
|
286
286
|
}
|
|
287
287
|
};
|
|
288
288
|
});
|
|
289
|
-
notifyWorkflowChange(
|
|
289
|
+
notifyWorkflowChange('edge_add');
|
|
290
290
|
},
|
|
291
291
|
/**
|
|
292
292
|
* Update workflow name
|
|
@@ -304,7 +304,7 @@ export const workflowActions = {
|
|
|
304
304
|
}
|
|
305
305
|
};
|
|
306
306
|
});
|
|
307
|
-
notifyWorkflowChange(
|
|
307
|
+
notifyWorkflowChange('name');
|
|
308
308
|
},
|
|
309
309
|
/**
|
|
310
310
|
* Add a node
|
|
@@ -322,7 +322,7 @@ export const workflowActions = {
|
|
|
322
322
|
}
|
|
323
323
|
};
|
|
324
324
|
});
|
|
325
|
-
notifyWorkflowChange(
|
|
325
|
+
notifyWorkflowChange('node_add');
|
|
326
326
|
},
|
|
327
327
|
/**
|
|
328
328
|
* Remove a node
|
|
@@ -341,7 +341,7 @@ export const workflowActions = {
|
|
|
341
341
|
}
|
|
342
342
|
};
|
|
343
343
|
});
|
|
344
|
-
notifyWorkflowChange(
|
|
344
|
+
notifyWorkflowChange('node_remove');
|
|
345
345
|
},
|
|
346
346
|
/**
|
|
347
347
|
* Add an edge
|
|
@@ -359,7 +359,7 @@ export const workflowActions = {
|
|
|
359
359
|
}
|
|
360
360
|
};
|
|
361
361
|
});
|
|
362
|
-
notifyWorkflowChange(
|
|
362
|
+
notifyWorkflowChange('edge_add');
|
|
363
363
|
},
|
|
364
364
|
/**
|
|
365
365
|
* Remove an edge
|
|
@@ -377,7 +377,7 @@ export const workflowActions = {
|
|
|
377
377
|
}
|
|
378
378
|
};
|
|
379
379
|
});
|
|
380
|
-
notifyWorkflowChange(
|
|
380
|
+
notifyWorkflowChange('edge_remove');
|
|
381
381
|
},
|
|
382
382
|
/**
|
|
383
383
|
* Update a specific node
|
|
@@ -388,14 +388,14 @@ export const workflowActions = {
|
|
|
388
388
|
return null;
|
|
389
389
|
return {
|
|
390
390
|
...$workflow,
|
|
391
|
-
nodes: $workflow.nodes.map((node) => node.id === nodeId ? { ...node, ...updates } : node),
|
|
391
|
+
nodes: $workflow.nodes.map((node) => (node.id === nodeId ? { ...node, ...updates } : node)),
|
|
392
392
|
metadata: {
|
|
393
393
|
...$workflow.metadata,
|
|
394
394
|
updatedAt: new Date().toISOString()
|
|
395
395
|
}
|
|
396
396
|
};
|
|
397
397
|
});
|
|
398
|
-
notifyWorkflowChange(
|
|
398
|
+
notifyWorkflowChange('node_config');
|
|
399
399
|
},
|
|
400
400
|
/**
|
|
401
401
|
* Clear the workflow
|
|
@@ -424,7 +424,7 @@ export const workflowActions = {
|
|
|
424
424
|
}
|
|
425
425
|
};
|
|
426
426
|
});
|
|
427
|
-
notifyWorkflowChange(
|
|
427
|
+
notifyWorkflowChange('metadata');
|
|
428
428
|
},
|
|
429
429
|
/**
|
|
430
430
|
* Batch update nodes and edges
|
|
@@ -448,7 +448,7 @@ export const workflowActions = {
|
|
|
448
448
|
}
|
|
449
449
|
};
|
|
450
450
|
});
|
|
451
|
-
notifyWorkflowChange(
|
|
451
|
+
notifyWorkflowChange('metadata');
|
|
452
452
|
}
|
|
453
453
|
};
|
|
454
454
|
// =========================================================================
|
|
@@ -468,5 +468,5 @@ export const workflowValidation = derived([workflowNodes, workflowEdges], ([node
|
|
|
468
468
|
export const workflowMetadataChanged = derived(workflowMetadata, (metadata) => ({
|
|
469
469
|
createdAt: metadata.createdAt,
|
|
470
470
|
updatedAt: metadata.updatedAt,
|
|
471
|
-
version: metadata.version ??
|
|
471
|
+
version: metadata.version ?? '1.0.0'
|
|
472
472
|
}));
|
package/dist/styles/base.css
CHANGED
|
@@ -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;
|
package/dist/svelte-app.d.ts
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module svelte-app
|
|
8
8
|
*/
|
|
9
|
-
import type { Workflow, NodeMetadata, PortConfig } from
|
|
10
|
-
import type { EndpointConfig } from
|
|
11
|
-
import type { AuthProvider } from
|
|
12
|
-
import type { FlowDropEventHandlers, FlowDropFeatures } from
|
|
9
|
+
import type { Workflow, NodeMetadata, PortConfig } from './types/index.js';
|
|
10
|
+
import type { EndpointConfig } from './config/endpoints.js';
|
|
11
|
+
import type { AuthProvider } from './types/auth.js';
|
|
12
|
+
import type { FlowDropEventHandlers, FlowDropFeatures } from './types/events.js';
|
|
13
13
|
declare global {
|
|
14
14
|
interface Window {
|
|
15
15
|
flowdropSave?: () => Promise<void>;
|
|
@@ -23,7 +23,7 @@ export interface NavbarAction {
|
|
|
23
23
|
label: string;
|
|
24
24
|
href: string;
|
|
25
25
|
icon?: string;
|
|
26
|
-
variant?:
|
|
26
|
+
variant?: 'primary' | 'secondary' | 'outline';
|
|
27
27
|
onclick?: (event: Event) => void;
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
@@ -53,7 +53,7 @@ export interface FlowDropMountOptions {
|
|
|
53
53
|
/** Pipeline ID for status display */
|
|
54
54
|
pipelineId?: string;
|
|
55
55
|
/** Node execution statuses */
|
|
56
|
-
nodeStatuses?: Record<string,
|
|
56
|
+
nodeStatuses?: Record<string, 'pending' | 'running' | 'completed' | 'error'>;
|
|
57
57
|
/** Custom navbar title */
|
|
58
58
|
navbarTitle?: string;
|
|
59
59
|
/** Custom navbar actions */
|
package/dist/svelte-app.js
CHANGED
|
@@ -6,15 +6,15 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module svelte-app
|
|
8
8
|
*/
|
|
9
|
-
import { mount, unmount } from
|
|
10
|
-
import WorkflowEditor from
|
|
11
|
-
import App from
|
|
12
|
-
import { initializePortCompatibility } from
|
|
13
|
-
import { DEFAULT_PORT_CONFIG } from
|
|
14
|
-
import { fetchPortConfig } from
|
|
15
|
-
import { isDirty, markAsSaved, getWorkflow as getWorkflowFromStore, setOnDirtyStateChange, setOnWorkflowChange } from
|
|
16
|
-
import { DraftAutoSaveManager, getDraftStorageKey } from
|
|
17
|
-
import { mergeFeatures } from
|
|
9
|
+
import { mount, unmount } from 'svelte';
|
|
10
|
+
import WorkflowEditor from './components/WorkflowEditor.svelte';
|
|
11
|
+
import App from './components/App.svelte';
|
|
12
|
+
import { initializePortCompatibility } from './utils/connections.js';
|
|
13
|
+
import { DEFAULT_PORT_CONFIG } from './config/defaultPortConfig.js';
|
|
14
|
+
import { fetchPortConfig } from './services/portConfigApi.js';
|
|
15
|
+
import { isDirty, markAsSaved, getWorkflow as getWorkflowFromStore, setOnDirtyStateChange, setOnWorkflowChange } from './stores/workflowStore.js';
|
|
16
|
+
import { DraftAutoSaveManager, getDraftStorageKey } from './services/draftStorage.js';
|
|
17
|
+
import { mergeFeatures } from './types/events.js';
|
|
18
18
|
/**
|
|
19
19
|
* Mount the full FlowDrop App with navbar, sidebars, and workflow editor
|
|
20
20
|
*
|
|
@@ -40,14 +40,14 @@ import { mergeFeatures } from "./types/events.js";
|
|
|
40
40
|
* ```
|
|
41
41
|
*/
|
|
42
42
|
export async function mountFlowDropApp(container, options = {}) {
|
|
43
|
-
const { workflow, nodes, endpointConfig, portConfig, height =
|
|
43
|
+
const { workflow, nodes, endpointConfig, portConfig, height = '100vh', width = '100%', showNavbar = false, disableSidebar, lockWorkflow, readOnly, nodeStatuses, pipelineId, navbarTitle, navbarActions, authProvider, eventHandlers, features: userFeatures, draftStorageKey: customDraftKey } = options;
|
|
44
44
|
// Merge features with defaults
|
|
45
45
|
const features = mergeFeatures(userFeatures);
|
|
46
46
|
// Create endpoint configuration
|
|
47
47
|
let config;
|
|
48
48
|
if (endpointConfig) {
|
|
49
49
|
// Merge with default configuration to ensure all required endpoints are present
|
|
50
|
-
const { defaultEndpointConfig } = await import(
|
|
50
|
+
const { defaultEndpointConfig } = await import('./config/endpoints.js');
|
|
51
51
|
config = {
|
|
52
52
|
...defaultEndpointConfig,
|
|
53
53
|
...endpointConfig,
|
|
@@ -59,7 +59,7 @@ export async function mountFlowDropApp(container, options = {}) {
|
|
|
59
59
|
}
|
|
60
60
|
else {
|
|
61
61
|
// Use default configuration if none provided
|
|
62
|
-
const { defaultEndpointConfig } = await import(
|
|
62
|
+
const { defaultEndpointConfig } = await import('./config/endpoints.js');
|
|
63
63
|
config = defaultEndpointConfig;
|
|
64
64
|
}
|
|
65
65
|
// Initialize port configuration
|
|
@@ -70,7 +70,7 @@ export async function mountFlowDropApp(container, options = {}) {
|
|
|
70
70
|
finalPortConfig = await fetchPortConfig(config);
|
|
71
71
|
}
|
|
72
72
|
catch (error) {
|
|
73
|
-
console.warn(
|
|
73
|
+
console.warn('Failed to fetch port config from API, using default:', error);
|
|
74
74
|
finalPortConfig = DEFAULT_PORT_CONFIG;
|
|
75
75
|
}
|
|
76
76
|
}
|
|
@@ -160,19 +160,19 @@ export async function mountFlowDropApp(container, options = {}) {
|
|
|
160
160
|
},
|
|
161
161
|
getWorkflow: () => getWorkflowFromStore(),
|
|
162
162
|
save: async () => {
|
|
163
|
-
if (typeof window !==
|
|
163
|
+
if (typeof window !== 'undefined' && window.flowdropSave) {
|
|
164
164
|
await window.flowdropSave();
|
|
165
165
|
}
|
|
166
166
|
else {
|
|
167
|
-
console.warn(
|
|
167
|
+
console.warn('⚠️ Save functionality not available');
|
|
168
168
|
}
|
|
169
169
|
},
|
|
170
170
|
export: () => {
|
|
171
|
-
if (typeof window !==
|
|
171
|
+
if (typeof window !== 'undefined' && window.flowdropExport) {
|
|
172
172
|
window.flowdropExport();
|
|
173
173
|
}
|
|
174
174
|
else {
|
|
175
|
-
console.warn(
|
|
175
|
+
console.warn('⚠️ Export functionality not available');
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
};
|
|
@@ -193,7 +193,7 @@ export async function mountWorkflowEditor(container, options = {}) {
|
|
|
193
193
|
let config;
|
|
194
194
|
if (endpointConfig) {
|
|
195
195
|
// Merge with default configuration to ensure all required endpoints are present
|
|
196
|
-
const { defaultEndpointConfig } = await import(
|
|
196
|
+
const { defaultEndpointConfig } = await import('./config/endpoints.js');
|
|
197
197
|
config = {
|
|
198
198
|
...defaultEndpointConfig,
|
|
199
199
|
...endpointConfig,
|
|
@@ -205,7 +205,7 @@ export async function mountWorkflowEditor(container, options = {}) {
|
|
|
205
205
|
}
|
|
206
206
|
else {
|
|
207
207
|
// Use default configuration if none provided
|
|
208
|
-
const { defaultEndpointConfig } = await import(
|
|
208
|
+
const { defaultEndpointConfig } = await import('./config/endpoints.js');
|
|
209
209
|
config = defaultEndpointConfig;
|
|
210
210
|
}
|
|
211
211
|
// Initialize port configuration
|
|
@@ -216,7 +216,7 @@ export async function mountWorkflowEditor(container, options = {}) {
|
|
|
216
216
|
finalPortConfig = await fetchPortConfig(config);
|
|
217
217
|
}
|
|
218
218
|
catch (error) {
|
|
219
|
-
console.warn(
|
|
219
|
+
console.warn('Failed to fetch port config from API, using default:', error);
|
|
220
220
|
finalPortConfig = DEFAULT_PORT_CONFIG;
|
|
221
221
|
}
|
|
222
222
|
}
|
|
@@ -241,19 +241,19 @@ export async function mountWorkflowEditor(container, options = {}) {
|
|
|
241
241
|
markAsSaved: () => markAsSaved(),
|
|
242
242
|
getWorkflow: () => getWorkflowFromStore(),
|
|
243
243
|
save: async () => {
|
|
244
|
-
if (typeof window !==
|
|
244
|
+
if (typeof window !== 'undefined' && window.flowdropSave) {
|
|
245
245
|
await window.flowdropSave();
|
|
246
246
|
}
|
|
247
247
|
else {
|
|
248
|
-
console.warn(
|
|
248
|
+
console.warn('⚠️ Save functionality not available');
|
|
249
249
|
}
|
|
250
250
|
},
|
|
251
251
|
export: () => {
|
|
252
|
-
if (typeof window !==
|
|
252
|
+
if (typeof window !== 'undefined' && window.flowdropExport) {
|
|
253
253
|
window.flowdropExport();
|
|
254
254
|
}
|
|
255
255
|
else {
|
|
256
|
-
console.warn(
|
|
256
|
+
console.warn('⚠️ Export functionality not available');
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
};
|
|
@@ -265,7 +265,7 @@ export async function mountWorkflowEditor(container, options = {}) {
|
|
|
265
265
|
* @param app - The mounted app to unmount
|
|
266
266
|
*/
|
|
267
267
|
export function unmountFlowDropApp(app) {
|
|
268
|
-
if (app && typeof app.destroy ===
|
|
268
|
+
if (app && typeof app.destroy === 'function') {
|
|
269
269
|
app.destroy();
|
|
270
270
|
}
|
|
271
271
|
}
|
package/dist/types/auth.d.ts
CHANGED
|
@@ -63,7 +63,7 @@ export interface AuthProvider {
|
|
|
63
63
|
*/
|
|
64
64
|
export interface StaticAuthConfig {
|
|
65
65
|
/** Authentication type */
|
|
66
|
-
type:
|
|
66
|
+
type: 'none' | 'bearer' | 'api_key' | 'custom';
|
|
67
67
|
/** Bearer token (used when type is "bearer") */
|
|
68
68
|
token?: string;
|
|
69
69
|
/** API key (used when type is "api_key") */
|
|
@@ -271,7 +271,7 @@ export declare class NoAuthProvider implements AuthProvider {
|
|
|
271
271
|
* @returns AuthProvider instance
|
|
272
272
|
*/
|
|
273
273
|
export declare function createAuthProviderFromLegacyConfig(authConfig?: {
|
|
274
|
-
type:
|
|
274
|
+
type: 'none' | 'bearer' | 'api_key' | 'custom';
|
|
275
275
|
token?: string;
|
|
276
276
|
apiKey?: string;
|
|
277
277
|
headers?: Record<string, string>;
|