@d34dman/flowdrop 0.0.56 → 0.0.58
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 +4 -4
- package/dist/adapters/WorkflowAdapter.d.ts +2 -1
- package/dist/adapters/agentspec/AgentSpecAdapter.d.ts +96 -0
- package/dist/adapters/agentspec/AgentSpecAdapter.js +663 -0
- package/dist/adapters/agentspec/agentAdapter.d.ts +59 -0
- package/dist/adapters/agentspec/agentAdapter.js +91 -0
- package/dist/adapters/agentspec/autoLayout.d.ts +34 -0
- package/dist/adapters/agentspec/autoLayout.js +127 -0
- package/dist/adapters/agentspec/componentTypeDefaults.d.ts +73 -0
- package/dist/adapters/agentspec/componentTypeDefaults.js +238 -0
- package/dist/adapters/agentspec/defaultNodeTypes.d.ts +53 -0
- package/dist/adapters/agentspec/defaultNodeTypes.js +561 -0
- package/dist/adapters/agentspec/index.d.ts +37 -0
- package/dist/adapters/agentspec/index.js +39 -0
- package/dist/adapters/agentspec/validator.d.ts +34 -0
- package/dist/adapters/agentspec/validator.js +169 -0
- package/dist/components/App.svelte +57 -13
- package/dist/components/ConfigForm.svelte +46 -12
- package/dist/components/ConfigForm.svelte.d.ts +8 -0
- package/dist/components/NodeSidebar.svelte +20 -8
- package/dist/components/NodeSidebar.svelte.d.ts +2 -1
- package/dist/components/SchemaForm.svelte +34 -12
- package/dist/components/SchemaForm.svelte.d.ts +8 -0
- package/dist/components/WorkflowEditor.svelte +14 -13
- package/dist/components/form/FormFieldset.svelte +142 -0
- package/dist/components/form/FormFieldset.svelte.d.ts +11 -0
- package/dist/components/form/FormMarkdownEditor.svelte +546 -422
- package/dist/components/form/FormMarkdownEditor.svelte.d.ts +2 -0
- package/dist/components/form/FormUISchemaRenderer.svelte +136 -0
- package/dist/components/form/FormUISchemaRenderer.svelte.d.ts +32 -0
- package/dist/components/form/index.d.ts +2 -0
- package/dist/components/form/index.js +3 -0
- package/dist/components/form/types.d.ts +1 -1
- package/dist/components/nodes/WorkflowNode.svelte +1 -2
- package/dist/config/agentSpecEndpoints.d.ts +70 -0
- package/dist/config/agentSpecEndpoints.js +65 -0
- package/dist/config/endpoints.d.ts +6 -0
- package/dist/core/index.d.ts +29 -3
- package/dist/core/index.js +31 -1
- package/dist/form/code.js +6 -1
- package/dist/form/fieldRegistry.d.ts +79 -15
- package/dist/form/fieldRegistry.js +104 -49
- package/dist/form/full.d.ts +2 -2
- package/dist/form/full.js +2 -2
- package/dist/form/index.d.ts +5 -3
- package/dist/form/index.js +9 -2
- package/dist/form/markdown.d.ts +3 -3
- package/dist/form/markdown.js +8 -4
- package/dist/helpers/workflowEditorHelper.d.ts +24 -0
- package/dist/helpers/workflowEditorHelper.js +55 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/registry/BaseRegistry.d.ts +92 -0
- package/dist/registry/BaseRegistry.js +124 -0
- package/dist/registry/builtinFormats.d.ts +23 -0
- package/dist/registry/builtinFormats.js +70 -0
- package/dist/registry/builtinNodes.js +4 -0
- package/dist/registry/index.d.ts +2 -1
- package/dist/registry/index.js +2 -0
- package/dist/registry/nodeComponentRegistry.d.ts +26 -57
- package/dist/registry/nodeComponentRegistry.js +29 -82
- package/dist/registry/workflowFormatRegistry.d.ts +122 -0
- package/dist/registry/workflowFormatRegistry.js +96 -0
- package/dist/schema/index.d.ts +23 -0
- package/dist/schema/index.js +23 -0
- package/dist/services/agentSpecExecutionService.d.ts +106 -0
- package/dist/services/agentSpecExecutionService.js +333 -0
- package/dist/stores/portCoordinateStore.js +1 -4
- package/dist/stores/workflowStore.d.ts +3 -0
- package/dist/stores/workflowStore.js +3 -0
- package/dist/svelte-app.d.ts +4 -0
- package/dist/svelte-app.js +9 -1
- package/dist/types/agentspec.d.ts +318 -0
- package/dist/types/agentspec.js +48 -0
- package/dist/types/events.d.ts +28 -1
- package/dist/types/index.d.ts +31 -0
- package/dist/types/index.js +5 -0
- package/dist/types/uischema.d.ts +144 -0
- package/dist/types/uischema.js +51 -0
- package/dist/utils/uischema.d.ts +52 -0
- package/dist/utils/uischema.js +88 -0
- package/package.json +231 -225
- package/schemas/v1/workflow.schema.json +952 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Spec Execution Service
|
|
3
|
+
*
|
|
4
|
+
* Connects FlowDrop to Agent Spec runtimes (WayFlow/PyAgentSpec) for
|
|
5
|
+
* workflow execution, status tracking, and result retrieval.
|
|
6
|
+
*
|
|
7
|
+
* Follows the same singleton pattern as NodeExecutionService.
|
|
8
|
+
*/
|
|
9
|
+
import { buildAgentSpecUrl, getAgentSpecAuthHeaders } from '../config/agentSpecEndpoints.js';
|
|
10
|
+
import { AgentSpecAdapter } from '../adapters/agentspec/AgentSpecAdapter.js';
|
|
11
|
+
/**
|
|
12
|
+
* Service for executing FlowDrop workflows on Agent Spec runtimes.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const service = AgentSpecExecutionService.getInstance();
|
|
17
|
+
* service.configure(myRuntimeConfig);
|
|
18
|
+
*
|
|
19
|
+
* // Check runtime availability
|
|
20
|
+
* const healthy = await service.checkHealth();
|
|
21
|
+
*
|
|
22
|
+
* // Execute a workflow
|
|
23
|
+
* const handle = await service.executeWorkflow(workflow, inputs, {
|
|
24
|
+
* onNodeUpdate: (nodeId, info) => updateNodeVisual(nodeId, info),
|
|
25
|
+
* onComplete: (results) => showResults(results),
|
|
26
|
+
* onError: (error) => showError(error)
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* // Cancel if needed
|
|
30
|
+
* await service.cancelExecution(handle.executionId);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export class AgentSpecExecutionService {
|
|
34
|
+
static instance;
|
|
35
|
+
config = null;
|
|
36
|
+
adapter;
|
|
37
|
+
activeExecutions = new Map();
|
|
38
|
+
constructor() {
|
|
39
|
+
this.adapter = new AgentSpecAdapter();
|
|
40
|
+
}
|
|
41
|
+
static getInstance() {
|
|
42
|
+
if (!AgentSpecExecutionService.instance) {
|
|
43
|
+
AgentSpecExecutionService.instance = new AgentSpecExecutionService();
|
|
44
|
+
}
|
|
45
|
+
return AgentSpecExecutionService.instance;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Configure the runtime connection.
|
|
49
|
+
*/
|
|
50
|
+
configure(config) {
|
|
51
|
+
this.config = config;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Check if the service has been configured with a runtime.
|
|
55
|
+
*/
|
|
56
|
+
isConfigured() {
|
|
57
|
+
return this.config !== null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check runtime health.
|
|
61
|
+
*/
|
|
62
|
+
async checkHealth() {
|
|
63
|
+
if (!this.config)
|
|
64
|
+
return false;
|
|
65
|
+
try {
|
|
66
|
+
const url = buildAgentSpecUrl(this.config, this.config.endpoints.health);
|
|
67
|
+
const response = await fetch(url, {
|
|
68
|
+
headers: getAgentSpecAuthHeaders(this.config),
|
|
69
|
+
signal: AbortSignal.timeout(5000)
|
|
70
|
+
});
|
|
71
|
+
return response.ok;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Execute a FlowDrop workflow on the Agent Spec runtime.
|
|
79
|
+
*
|
|
80
|
+
* 1. Converts StandardWorkflow → AgentSpecFlow using the adapter
|
|
81
|
+
* 2. POSTs the flow JSON to the runtime
|
|
82
|
+
* 3. Starts polling for execution status
|
|
83
|
+
* 4. Maps runtime node statuses to FlowDrop's NodeExecutionInfo
|
|
84
|
+
*/
|
|
85
|
+
async executeWorkflow(workflow, inputs, callbacks, pollingIntervalMs = 2000) {
|
|
86
|
+
this.ensureConfigured();
|
|
87
|
+
// Convert to Agent Spec format
|
|
88
|
+
const agentSpecFlow = this.adapter.toAgentSpec(workflow);
|
|
89
|
+
// POST to runtime
|
|
90
|
+
const url = buildAgentSpecUrl(this.getConfig(), this.getConfig().endpoints.execute);
|
|
91
|
+
const response = await fetch(url, {
|
|
92
|
+
method: 'POST',
|
|
93
|
+
headers: getAgentSpecAuthHeaders(this.getConfig()),
|
|
94
|
+
body: JSON.stringify({
|
|
95
|
+
flow: agentSpecFlow,
|
|
96
|
+
inputs: inputs || {}
|
|
97
|
+
}),
|
|
98
|
+
signal: AbortSignal.timeout(this.getConfig().timeout || 60000)
|
|
99
|
+
});
|
|
100
|
+
if (!response.ok) {
|
|
101
|
+
const errorText = await response.text().catch(() => 'Unknown error');
|
|
102
|
+
throw new Error(`Agent Spec runtime error (${response.status}): ${errorText}`);
|
|
103
|
+
}
|
|
104
|
+
const result = await response.json();
|
|
105
|
+
const executionId = result.execution_id || result.id;
|
|
106
|
+
if (!executionId) {
|
|
107
|
+
throw new Error('Runtime did not return an execution ID');
|
|
108
|
+
}
|
|
109
|
+
// Track execution
|
|
110
|
+
const state = {
|
|
111
|
+
id: executionId,
|
|
112
|
+
status: 'running',
|
|
113
|
+
startedAt: new Date().toISOString(),
|
|
114
|
+
nodeStatuses: {}
|
|
115
|
+
};
|
|
116
|
+
this.activeExecutions.set(executionId, state);
|
|
117
|
+
// Build node name → FlowDrop node ID mapping for status updates
|
|
118
|
+
const nameToNodeId = new Map();
|
|
119
|
+
for (const node of workflow.nodes) {
|
|
120
|
+
const label = node.data.label || node.id;
|
|
121
|
+
nameToNodeId.set(label, node.id);
|
|
122
|
+
}
|
|
123
|
+
// Start polling
|
|
124
|
+
const stop = () => this.stopPolling(executionId);
|
|
125
|
+
if (callbacks) {
|
|
126
|
+
this.startPolling(executionId, nameToNodeId, callbacks.onNodeUpdate, callbacks.onComplete, callbacks.onError, pollingIntervalMs);
|
|
127
|
+
}
|
|
128
|
+
return { executionId, stop };
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get current execution status.
|
|
132
|
+
*/
|
|
133
|
+
async getExecutionStatus(executionId) {
|
|
134
|
+
this.ensureConfigured();
|
|
135
|
+
try {
|
|
136
|
+
const url = buildAgentSpecUrl(this.getConfig(), this.getConfig().endpoints.status, {
|
|
137
|
+
id: executionId
|
|
138
|
+
});
|
|
139
|
+
const response = await fetch(url, {
|
|
140
|
+
headers: getAgentSpecAuthHeaders(this.getConfig())
|
|
141
|
+
});
|
|
142
|
+
if (!response.ok)
|
|
143
|
+
return null;
|
|
144
|
+
const data = await response.json();
|
|
145
|
+
return this.mapRuntimeStatusToNodeInfo(data);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Cancel a running execution.
|
|
153
|
+
*/
|
|
154
|
+
async cancelExecution(executionId) {
|
|
155
|
+
this.ensureConfigured();
|
|
156
|
+
this.stopPolling(executionId);
|
|
157
|
+
const url = buildAgentSpecUrl(this.getConfig(), this.getConfig().endpoints.cancel, {
|
|
158
|
+
id: executionId
|
|
159
|
+
});
|
|
160
|
+
await fetch(url, {
|
|
161
|
+
method: 'POST',
|
|
162
|
+
headers: getAgentSpecAuthHeaders(this.getConfig())
|
|
163
|
+
});
|
|
164
|
+
const state = this.activeExecutions.get(executionId);
|
|
165
|
+
if (state) {
|
|
166
|
+
state.status = 'cancelled';
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get execution results.
|
|
171
|
+
*/
|
|
172
|
+
async getResults(executionId) {
|
|
173
|
+
this.ensureConfigured();
|
|
174
|
+
try {
|
|
175
|
+
const url = buildAgentSpecUrl(this.getConfig(), this.getConfig().endpoints.results, {
|
|
176
|
+
id: executionId
|
|
177
|
+
});
|
|
178
|
+
const response = await fetch(url, {
|
|
179
|
+
headers: getAgentSpecAuthHeaders(this.getConfig())
|
|
180
|
+
});
|
|
181
|
+
if (!response.ok)
|
|
182
|
+
return null;
|
|
183
|
+
return await response.json();
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Validate a workflow against the runtime.
|
|
191
|
+
*/
|
|
192
|
+
async validateOnRuntime(workflow) {
|
|
193
|
+
this.ensureConfigured();
|
|
194
|
+
const agentSpecFlow = this.adapter.toAgentSpec(workflow);
|
|
195
|
+
const url = buildAgentSpecUrl(this.getConfig(), this.getConfig().endpoints.validate);
|
|
196
|
+
const response = await fetch(url, {
|
|
197
|
+
method: 'POST',
|
|
198
|
+
headers: getAgentSpecAuthHeaders(this.getConfig()),
|
|
199
|
+
body: JSON.stringify(agentSpecFlow)
|
|
200
|
+
});
|
|
201
|
+
if (!response.ok) {
|
|
202
|
+
return { valid: false, errors: [`Runtime validation failed: ${response.status}`] };
|
|
203
|
+
}
|
|
204
|
+
return await response.json();
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Clean up all active executions.
|
|
208
|
+
*/
|
|
209
|
+
destroy() {
|
|
210
|
+
for (const [id] of this.activeExecutions) {
|
|
211
|
+
this.stopPolling(id);
|
|
212
|
+
}
|
|
213
|
+
this.activeExecutions.clear();
|
|
214
|
+
}
|
|
215
|
+
// ========================================================================
|
|
216
|
+
// Private
|
|
217
|
+
// ========================================================================
|
|
218
|
+
ensureConfigured() {
|
|
219
|
+
if (!this.config) {
|
|
220
|
+
throw new Error('AgentSpecExecutionService not configured. Call configure() with runtime endpoint config first.');
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/** Get the config, throwing if not configured */
|
|
224
|
+
getConfig() {
|
|
225
|
+
this.ensureConfigured();
|
|
226
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
227
|
+
return this.config;
|
|
228
|
+
}
|
|
229
|
+
startPolling(executionId, nameToNodeId, onNodeUpdate, onComplete, onError, intervalMs = 2000) {
|
|
230
|
+
const state = this.activeExecutions.get(executionId);
|
|
231
|
+
if (!state)
|
|
232
|
+
return;
|
|
233
|
+
const poll = async () => {
|
|
234
|
+
try {
|
|
235
|
+
const url = buildAgentSpecUrl(this.getConfig(), this.getConfig().endpoints.status, {
|
|
236
|
+
id: executionId
|
|
237
|
+
});
|
|
238
|
+
const response = await fetch(url, {
|
|
239
|
+
headers: getAgentSpecAuthHeaders(this.getConfig())
|
|
240
|
+
});
|
|
241
|
+
if (!response.ok) {
|
|
242
|
+
throw new Error(`Status check failed: ${response.status}`);
|
|
243
|
+
}
|
|
244
|
+
const data = await response.json();
|
|
245
|
+
const executionStatus = data.status || data.execution_status;
|
|
246
|
+
// Map node statuses
|
|
247
|
+
const nodeStatuses = data.node_statuses || data.nodes || {};
|
|
248
|
+
for (const [nodeName, status] of Object.entries(nodeStatuses)) {
|
|
249
|
+
const nodeId = nameToNodeId.get(nodeName) || nodeName;
|
|
250
|
+
const info = this.mapSingleNodeStatus(status);
|
|
251
|
+
state.nodeStatuses[nodeId] = info;
|
|
252
|
+
onNodeUpdate?.(nodeId, info);
|
|
253
|
+
}
|
|
254
|
+
// Check if execution is done
|
|
255
|
+
if (executionStatus === 'completed' || executionStatus === 'success') {
|
|
256
|
+
state.status = 'completed';
|
|
257
|
+
this.stopPolling(executionId);
|
|
258
|
+
const results = await this.getResults(executionId);
|
|
259
|
+
onComplete?.(results || {});
|
|
260
|
+
}
|
|
261
|
+
else if (executionStatus === 'failed' || executionStatus === 'error') {
|
|
262
|
+
state.status = 'failed';
|
|
263
|
+
this.stopPolling(executionId);
|
|
264
|
+
const errorMsg = data.error || data.message || 'Execution failed';
|
|
265
|
+
onError?.(new Error(errorMsg));
|
|
266
|
+
}
|
|
267
|
+
else if (executionStatus === 'cancelled') {
|
|
268
|
+
state.status = 'cancelled';
|
|
269
|
+
this.stopPolling(executionId);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
// Don't stop polling on transient errors — let it retry
|
|
274
|
+
console.error('[AgentSpecExecution] Polling error:', error);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
// Initial poll immediately, then at interval
|
|
278
|
+
poll();
|
|
279
|
+
state.pollingInterval = setInterval(poll, intervalMs);
|
|
280
|
+
}
|
|
281
|
+
stopPolling(executionId) {
|
|
282
|
+
const state = this.activeExecutions.get(executionId);
|
|
283
|
+
if (state?.pollingInterval) {
|
|
284
|
+
clearInterval(state.pollingInterval);
|
|
285
|
+
state.pollingInterval = undefined;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
mapRuntimeStatusToNodeInfo(data) {
|
|
289
|
+
const result = {};
|
|
290
|
+
const nodeStatuses = (data.node_statuses || data.nodes || {});
|
|
291
|
+
for (const [nodeName, status] of Object.entries(nodeStatuses)) {
|
|
292
|
+
result[nodeName] = this.mapSingleNodeStatus(status);
|
|
293
|
+
}
|
|
294
|
+
return result;
|
|
295
|
+
}
|
|
296
|
+
mapSingleNodeStatus(status) {
|
|
297
|
+
const runtimeStatus = (status.status || status.state || 'idle');
|
|
298
|
+
return {
|
|
299
|
+
status: this.mapToFlowDropStatus(runtimeStatus),
|
|
300
|
+
executionCount: status.execution_count || 0,
|
|
301
|
+
isExecuting: runtimeStatus === 'running' || runtimeStatus === 'executing',
|
|
302
|
+
lastExecuted: status.started_at,
|
|
303
|
+
lastExecutionDuration: status.duration_ms,
|
|
304
|
+
lastError: status.error
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
mapToFlowDropStatus(runtimeStatus) {
|
|
308
|
+
switch (runtimeStatus) {
|
|
309
|
+
case 'running':
|
|
310
|
+
case 'executing':
|
|
311
|
+
return 'running';
|
|
312
|
+
case 'completed':
|
|
313
|
+
case 'success':
|
|
314
|
+
case 'done':
|
|
315
|
+
return 'completed';
|
|
316
|
+
case 'failed':
|
|
317
|
+
case 'error':
|
|
318
|
+
return 'failed';
|
|
319
|
+
case 'cancelled':
|
|
320
|
+
case 'canceled':
|
|
321
|
+
return 'cancelled';
|
|
322
|
+
case 'pending':
|
|
323
|
+
case 'queued':
|
|
324
|
+
return 'pending';
|
|
325
|
+
case 'skipped':
|
|
326
|
+
return 'skipped';
|
|
327
|
+
default:
|
|
328
|
+
return 'idle';
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/** Singleton instance */
|
|
333
|
+
export const agentSpecExecutionService = AgentSpecExecutionService.getInstance();
|
|
@@ -65,10 +65,7 @@ function computeNodePortCoordinates(node, internalNode) {
|
|
|
65
65
|
const posAbs = internalNode.internals.positionAbsolute;
|
|
66
66
|
const dataTypeLookup = buildPortDataTypeLookup(node);
|
|
67
67
|
const coordinates = [];
|
|
68
|
-
const allHandles = [
|
|
69
|
-
...(handleBounds.source ?? []),
|
|
70
|
-
...(handleBounds.target ?? [])
|
|
71
|
-
];
|
|
68
|
+
const allHandles = [...(handleBounds.source ?? []), ...(handleBounds.target ?? [])];
|
|
72
69
|
for (const handle of allHandles) {
|
|
73
70
|
if (!handle.id)
|
|
74
71
|
continue;
|
|
@@ -86,7 +86,10 @@ export declare const workflowMetadata: import("svelte/store").Readable<{
|
|
|
86
86
|
tags?: string[];
|
|
87
87
|
versionId?: string;
|
|
88
88
|
updateNumber?: number;
|
|
89
|
+
format?: import("../types").WorkflowFormat;
|
|
89
90
|
}>;
|
|
91
|
+
/** Derived store for the current workflow format */
|
|
92
|
+
export declare const workflowFormat: import("svelte/store").Readable<import("../types").WorkflowFormat>;
|
|
90
93
|
/**
|
|
91
94
|
* Actions for updating the workflow
|
|
92
95
|
*
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* @module stores/workflowStore
|
|
8
8
|
*/
|
|
9
9
|
import { writable, derived, get } from 'svelte/store';
|
|
10
|
+
import { DEFAULT_WORKFLOW_FORMAT } from '../types/index.js';
|
|
10
11
|
import { historyService } from '../services/historyService.js';
|
|
11
12
|
// =========================================================================
|
|
12
13
|
// Core Workflow Store
|
|
@@ -220,6 +221,8 @@ export const workflowMetadata = derived(workflowStore, ($workflow) => $workflow?
|
|
|
220
221
|
versionId: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
221
222
|
updateNumber: 0
|
|
222
223
|
});
|
|
224
|
+
/** Derived store for the current workflow format */
|
|
225
|
+
export const workflowFormat = derived(workflowStore, ($workflow) => $workflow?.metadata?.format ?? DEFAULT_WORKFLOW_FORMAT);
|
|
223
226
|
// =========================================================================
|
|
224
227
|
// Helper Functions
|
|
225
228
|
// =========================================================================
|
package/dist/svelte-app.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ import type { Workflow, NodeMetadata, PortConfig, CategoryDefinition } from './t
|
|
|
10
10
|
import type { EndpointConfig } from './config/endpoints.js';
|
|
11
11
|
import type { AuthProvider } from './types/auth.js';
|
|
12
12
|
import type { FlowDropEventHandlers, FlowDropFeatures } from './types/events.js';
|
|
13
|
+
import type { WorkflowFormatAdapter } from './registry/workflowFormatRegistry.js';
|
|
14
|
+
import './registry/builtinFormats.js';
|
|
13
15
|
import type { PartialSettings } from './types/settings.js';
|
|
14
16
|
declare global {
|
|
15
17
|
interface Window {
|
|
@@ -73,6 +75,8 @@ export interface FlowDropMountOptions {
|
|
|
73
75
|
settings?: PartialSettings;
|
|
74
76
|
/** Custom storage key for localStorage drafts */
|
|
75
77
|
draftStorageKey?: string;
|
|
78
|
+
/** Custom workflow format adapters to register */
|
|
79
|
+
formatAdapters?: WorkflowFormatAdapter[];
|
|
76
80
|
}
|
|
77
81
|
/**
|
|
78
82
|
* Return type for mounted FlowDrop app
|
package/dist/svelte-app.js
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
import { mount, unmount } from 'svelte';
|
|
10
10
|
import WorkflowEditor from './components/WorkflowEditor.svelte';
|
|
11
11
|
import App from './components/App.svelte';
|
|
12
|
+
import { workflowFormatRegistry } from './registry/workflowFormatRegistry.js';
|
|
13
|
+
import './registry/builtinFormats.js';
|
|
12
14
|
import { initializePortCompatibility } from './utils/connections.js';
|
|
13
15
|
import { DEFAULT_PORT_CONFIG } from './config/defaultPortConfig.js';
|
|
14
16
|
import { fetchPortConfig } from './services/portConfigApi.js';
|
|
@@ -43,7 +45,13 @@ import { initializeSettings } from './stores/settingsStore.js';
|
|
|
43
45
|
* ```
|
|
44
46
|
*/
|
|
45
47
|
export async function mountFlowDropApp(container, options = {}) {
|
|
46
|
-
const { workflow, nodes, endpointConfig, portConfig, categories, height = '100vh', width = '100%', showNavbar = false, disableSidebar, lockWorkflow, readOnly, nodeStatuses, pipelineId, navbarTitle, navbarActions, showSettings, authProvider, eventHandlers, features: userFeatures, settings: initialSettings, draftStorageKey: customDraftKey } = options;
|
|
48
|
+
const { workflow, nodes, endpointConfig, portConfig, categories, height = '100vh', width = '100%', showNavbar = false, disableSidebar, lockWorkflow, readOnly, nodeStatuses, pipelineId, navbarTitle, navbarActions, showSettings, authProvider, eventHandlers, features: userFeatures, settings: initialSettings, draftStorageKey: customDraftKey, formatAdapters } = options;
|
|
49
|
+
// Register custom format adapters before mounting
|
|
50
|
+
if (formatAdapters) {
|
|
51
|
+
for (const adapter of formatAdapters) {
|
|
52
|
+
workflowFormatRegistry.register(adapter);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
47
55
|
// Merge features with defaults
|
|
48
56
|
const features = mergeFeatures(userFeatures);
|
|
49
57
|
// Apply initial settings overrides and initialize theme
|