@d34dman/flowdrop 0.0.5 → 0.0.7
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 +107 -104
- package/dist/api/client.js +17 -17
- package/dist/components/App.svelte +72 -66
- package/dist/components/App.svelte.d.ts +1 -0
- package/dist/components/Navbar.svelte +1 -11
- package/dist/components/NodeSidebar.svelte +2 -1
- package/dist/components/NodeStatusOverlay.svelte +0 -1
- package/dist/components/NodeStatusOverlay.svelte.d.ts +0 -1
- package/dist/components/PipelineStatus.svelte +1 -38
- package/dist/components/SimpleNode.svelte +0 -7
- package/dist/components/SquareNode.svelte +0 -7
- package/dist/components/UniversalNode.svelte +0 -8
- package/dist/components/WorkflowEditor.svelte +63 -456
- package/dist/components/WorkflowNode.svelte +1 -8
- package/dist/helpers/workflowEditorHelper.d.ts +87 -0
- package/dist/helpers/workflowEditorHelper.js +365 -0
- package/dist/index.d.ts +31 -1
- package/dist/index.js +30 -1
- package/dist/mocks/app-navigation.d.ts +4 -4
- package/dist/mocks/app-navigation.js +4 -4
- package/dist/services/api.js +13 -18
- package/dist/services/globalSave.js +4 -4
- package/dist/svelte-app.js +2 -3
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -42,34 +42,34 @@ npm install @d34dman/flowdrop
|
|
|
42
42
|
### Basic Import
|
|
43
43
|
|
|
44
44
|
```javascript
|
|
45
|
-
import { WorkflowEditor } from
|
|
46
|
-
import
|
|
45
|
+
import { WorkflowEditor } from '@d34dman/flowdrop';
|
|
46
|
+
import '@d34dman/flowdrop/styles/base.css';
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
### Using the WorkflowEditor Component
|
|
50
50
|
|
|
51
51
|
```svelte
|
|
52
52
|
<script lang="ts">
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
53
|
+
import { WorkflowEditor } from '@d34dman/flowdrop';
|
|
54
|
+
import type { NodeMetadata, Workflow } from '@d34dman/flowdrop';
|
|
55
|
+
|
|
56
|
+
let nodes: NodeMetadata[] = [
|
|
57
|
+
{
|
|
58
|
+
id: 'text_input',
|
|
59
|
+
name: 'Text Input',
|
|
60
|
+
category: 'input_output',
|
|
61
|
+
description: 'User input field',
|
|
62
|
+
inputs: [],
|
|
63
|
+
outputs: [{ id: 'value', name: 'Value', type: 'output', dataType: 'string' }]
|
|
64
|
+
}
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
let workflow: Workflow = {
|
|
68
|
+
id: 'workflow_1',
|
|
69
|
+
name: 'My Workflow',
|
|
70
|
+
nodes: [],
|
|
71
|
+
edges: []
|
|
72
|
+
};
|
|
73
73
|
</script>
|
|
74
74
|
|
|
75
75
|
<WorkflowEditor {nodes} />
|
|
@@ -81,34 +81,34 @@ import "@d34dman/flowdrop/styles/base.css";
|
|
|
81
81
|
|
|
82
82
|
```svelte
|
|
83
83
|
<script>
|
|
84
|
-
|
|
84
|
+
import { WorkflowEditor, NodeSidebar } from '@d34dman/flowdrop';
|
|
85
85
|
</script>
|
|
86
86
|
|
|
87
87
|
<div class="editor-container">
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
<NodeSidebar {nodes} />
|
|
89
|
+
<WorkflowEditor {nodes} />
|
|
90
90
|
</div>
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
#### 2. Using Mount Functions (Vanilla JS/Other Frameworks)
|
|
94
94
|
|
|
95
95
|
```javascript
|
|
96
|
-
import { mountWorkflowEditor } from
|
|
96
|
+
import { mountWorkflowEditor } from '@d34dman/flowdrop';
|
|
97
97
|
|
|
98
|
-
const container = document.getElementById(
|
|
98
|
+
const container = document.getElementById('workflow-container');
|
|
99
99
|
const editor = mountWorkflowEditor(container, {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
100
|
+
nodes: availableNodes,
|
|
101
|
+
endpointConfig: {
|
|
102
|
+
baseUrl: '/api/flowdrop',
|
|
103
|
+
endpoints: {
|
|
104
|
+
workflows: {
|
|
105
|
+
list: '/workflows',
|
|
106
|
+
get: '/workflows/{id}',
|
|
107
|
+
create: '/workflows',
|
|
108
|
+
update: '/workflows/{id}'
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
112
|
});
|
|
113
113
|
|
|
114
114
|
// Cleanup
|
|
@@ -121,15 +121,15 @@ editor.destroy();
|
|
|
121
121
|
|
|
122
122
|
```javascript
|
|
123
123
|
Drupal.behaviors.flowdropEditor = {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
124
|
+
attach: function (context, settings) {
|
|
125
|
+
const container = context.querySelector('.flowdrop-container');
|
|
126
|
+
if (container && window.FlowDrop) {
|
|
127
|
+
window.FlowDrop.mountWorkflowEditor(container, {
|
|
128
|
+
endpointConfig: settings.flowdrop.endpointConfig,
|
|
129
|
+
nodes: settings.flowdrop.nodes
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
133
|
};
|
|
134
134
|
```
|
|
135
135
|
|
|
@@ -140,6 +140,7 @@ Drupal.behaviors.flowdropEditor = {
|
|
|
140
140
|
Main editor component for creating and editing workflows.
|
|
141
141
|
|
|
142
142
|
**Props:**
|
|
143
|
+
|
|
143
144
|
- `nodes`: Array of available node types
|
|
144
145
|
- `endpointConfig`: API endpoint configuration
|
|
145
146
|
- `height`: Editor height (default: "100vh")
|
|
@@ -152,6 +153,7 @@ Main editor component for creating and editing workflows.
|
|
|
152
153
|
Sidebar displaying available node types.
|
|
153
154
|
|
|
154
155
|
**Props:**
|
|
156
|
+
|
|
155
157
|
- `nodes`: Array of node types to display
|
|
156
158
|
|
|
157
159
|
### ConfigSidebar
|
|
@@ -159,6 +161,7 @@ Sidebar displaying available node types.
|
|
|
159
161
|
Configuration panel for selected nodes.
|
|
160
162
|
|
|
161
163
|
**Props:**
|
|
164
|
+
|
|
162
165
|
- `isOpen`: Sidebar visibility
|
|
163
166
|
- `configSchema`: JSON schema for configuration
|
|
164
167
|
- `configValues`: Current configuration values
|
|
@@ -170,29 +173,29 @@ Configuration panel for selected nodes.
|
|
|
170
173
|
Configure the API client to connect to your backend:
|
|
171
174
|
|
|
172
175
|
```typescript
|
|
173
|
-
import { createEndpointConfig } from
|
|
176
|
+
import { createEndpointConfig } from '@d34dman/flowdrop';
|
|
174
177
|
|
|
175
178
|
const config = createEndpointConfig({
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
179
|
+
baseUrl: 'https://api.example.com',
|
|
180
|
+
endpoints: {
|
|
181
|
+
nodes: {
|
|
182
|
+
list: '/nodes',
|
|
183
|
+
get: '/nodes/{id}'
|
|
184
|
+
},
|
|
185
|
+
workflows: {
|
|
186
|
+
list: '/workflows',
|
|
187
|
+
get: '/workflows/{id}',
|
|
188
|
+
create: '/workflows',
|
|
189
|
+
update: '/workflows/{id}',
|
|
190
|
+
delete: '/workflows/{id}',
|
|
191
|
+
execute: '/workflows/{id}/execute'
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
timeout: 30000,
|
|
195
|
+
auth: {
|
|
196
|
+
type: 'bearer',
|
|
197
|
+
token: 'your-token'
|
|
198
|
+
}
|
|
196
199
|
});
|
|
197
200
|
```
|
|
198
201
|
|
|
@@ -204,10 +207,10 @@ Override CSS custom properties:
|
|
|
204
207
|
|
|
205
208
|
```css
|
|
206
209
|
:root {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
210
|
+
--flowdrop-background-color: #f9fafb;
|
|
211
|
+
--flowdrop-primary-color: #3b82f6;
|
|
212
|
+
--flowdrop-border-color: #e5e7eb;
|
|
213
|
+
--flowdrop-text-color: #1f2937;
|
|
211
214
|
}
|
|
212
215
|
```
|
|
213
216
|
|
|
@@ -217,37 +220,37 @@ Define custom node types:
|
|
|
217
220
|
|
|
218
221
|
```typescript
|
|
219
222
|
const customNode: NodeMetadata = {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
223
|
+
id: 'custom_processor',
|
|
224
|
+
name: 'Custom Processor',
|
|
225
|
+
category: 'data_processing',
|
|
226
|
+
description: 'Process data with custom logic',
|
|
227
|
+
icon: 'mdi:cog',
|
|
228
|
+
color: '#3b82f6',
|
|
229
|
+
inputs: [
|
|
230
|
+
{
|
|
231
|
+
id: 'input',
|
|
232
|
+
name: 'Input',
|
|
233
|
+
type: 'input',
|
|
234
|
+
dataType: 'mixed'
|
|
235
|
+
}
|
|
236
|
+
],
|
|
237
|
+
outputs: [
|
|
238
|
+
{
|
|
239
|
+
id: 'output',
|
|
240
|
+
name: 'Output',
|
|
241
|
+
type: 'output',
|
|
242
|
+
dataType: 'mixed'
|
|
243
|
+
}
|
|
244
|
+
],
|
|
245
|
+
configSchema: {
|
|
246
|
+
type: 'object',
|
|
247
|
+
properties: {
|
|
248
|
+
operation: {
|
|
249
|
+
type: 'string',
|
|
250
|
+
title: 'Operation'
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
251
254
|
};
|
|
252
255
|
```
|
|
253
256
|
|
package/dist/api/client.js
CHANGED
|
@@ -42,7 +42,7 @@ export class FlowDropApiClient {
|
|
|
42
42
|
* Fetch available node types and their metadata
|
|
43
43
|
*/
|
|
44
44
|
async getAvailableNodes() {
|
|
45
|
-
const response = await this.request('/
|
|
45
|
+
const response = await this.request('/nodes');
|
|
46
46
|
if (!response.success || !response.data) {
|
|
47
47
|
throw new Error(response.error || 'Failed to fetch available nodes');
|
|
48
48
|
}
|
|
@@ -52,7 +52,7 @@ export class FlowDropApiClient {
|
|
|
52
52
|
* Fetch nodes by category
|
|
53
53
|
*/
|
|
54
54
|
async getNodesByCategory(category) {
|
|
55
|
-
const response = await this.request(`/
|
|
55
|
+
const response = await this.request(`/nodes?category=${encodeURIComponent(category)}`);
|
|
56
56
|
if (!response.success || !response.data) {
|
|
57
57
|
throw new Error(response.error || 'Failed to fetch nodes by category');
|
|
58
58
|
}
|
|
@@ -62,7 +62,7 @@ export class FlowDropApiClient {
|
|
|
62
62
|
* Fetch a specific node's metadata
|
|
63
63
|
*/
|
|
64
64
|
async getNodeMetadata(nodeId) {
|
|
65
|
-
const response = await this.request(`/
|
|
65
|
+
const response = await this.request(`/nodes/${encodeURIComponent(nodeId)}`);
|
|
66
66
|
if (!response.success || !response.data) {
|
|
67
67
|
throw new Error(response.error || 'Failed to fetch node metadata');
|
|
68
68
|
}
|
|
@@ -72,7 +72,7 @@ export class FlowDropApiClient {
|
|
|
72
72
|
* Save a workflow
|
|
73
73
|
*/
|
|
74
74
|
async saveWorkflow(workflow) {
|
|
75
|
-
const response = await this.request('/
|
|
75
|
+
const response = await this.request('/workflows', {
|
|
76
76
|
method: 'POST',
|
|
77
77
|
body: JSON.stringify(workflow)
|
|
78
78
|
});
|
|
@@ -85,7 +85,7 @@ export class FlowDropApiClient {
|
|
|
85
85
|
* Update an existing workflow
|
|
86
86
|
*/
|
|
87
87
|
async updateWorkflow(workflowId, workflow) {
|
|
88
|
-
const response = await this.request(`/
|
|
88
|
+
const response = await this.request(`/workflows/${encodeURIComponent(workflowId)}`, {
|
|
89
89
|
method: 'PUT',
|
|
90
90
|
body: JSON.stringify(workflow)
|
|
91
91
|
});
|
|
@@ -98,7 +98,7 @@ export class FlowDropApiClient {
|
|
|
98
98
|
* Load a workflow by ID
|
|
99
99
|
*/
|
|
100
100
|
async loadWorkflow(workflowId) {
|
|
101
|
-
const response = await this.request(`/
|
|
101
|
+
const response = await this.request(`/workflows/${encodeURIComponent(workflowId)}`);
|
|
102
102
|
if (!response.success || !response.data) {
|
|
103
103
|
throw new Error(response.error || 'Failed to load workflow');
|
|
104
104
|
}
|
|
@@ -108,7 +108,7 @@ export class FlowDropApiClient {
|
|
|
108
108
|
* List all workflows
|
|
109
109
|
*/
|
|
110
110
|
async listWorkflows() {
|
|
111
|
-
const response = await this.request('/
|
|
111
|
+
const response = await this.request('/workflows');
|
|
112
112
|
if (!response.success || !response.data) {
|
|
113
113
|
throw new Error(response.error || 'Failed to list workflows');
|
|
114
114
|
}
|
|
@@ -118,7 +118,7 @@ export class FlowDropApiClient {
|
|
|
118
118
|
* Delete a workflow
|
|
119
119
|
*/
|
|
120
120
|
async deleteWorkflow(workflowId) {
|
|
121
|
-
const response = await this.request(`/
|
|
121
|
+
const response = await this.request(`/workflows/${encodeURIComponent(workflowId)}`, {
|
|
122
122
|
method: 'DELETE'
|
|
123
123
|
});
|
|
124
124
|
if (!response.success) {
|
|
@@ -129,7 +129,7 @@ export class FlowDropApiClient {
|
|
|
129
129
|
* Execute a workflow
|
|
130
130
|
*/
|
|
131
131
|
async executeWorkflow(workflowId, inputs) {
|
|
132
|
-
const response = await this.request(`/
|
|
132
|
+
const response = await this.request(`/workflows/${encodeURIComponent(workflowId)}/execute`, {
|
|
133
133
|
method: 'POST',
|
|
134
134
|
body: JSON.stringify({ inputs })
|
|
135
135
|
});
|
|
@@ -142,7 +142,7 @@ export class FlowDropApiClient {
|
|
|
142
142
|
* Get execution status
|
|
143
143
|
*/
|
|
144
144
|
async getExecutionStatus(executionId) {
|
|
145
|
-
const response = await this.request(`/
|
|
145
|
+
const response = await this.request(`/executions/${encodeURIComponent(executionId)}`);
|
|
146
146
|
if (!response.success || !response.data) {
|
|
147
147
|
throw new Error(response.error || 'Failed to get execution status');
|
|
148
148
|
}
|
|
@@ -152,7 +152,7 @@ export class FlowDropApiClient {
|
|
|
152
152
|
* Cancel workflow execution
|
|
153
153
|
*/
|
|
154
154
|
async cancelExecution(executionId) {
|
|
155
|
-
const response = await this.request(`/
|
|
155
|
+
const response = await this.request(`/executions/${encodeURIComponent(executionId)}/cancel`, {
|
|
156
156
|
method: 'POST'
|
|
157
157
|
});
|
|
158
158
|
if (!response.success) {
|
|
@@ -163,7 +163,7 @@ export class FlowDropApiClient {
|
|
|
163
163
|
* Get execution logs
|
|
164
164
|
*/
|
|
165
165
|
async getExecutionLogs(executionId) {
|
|
166
|
-
const response = await this.request(`/
|
|
166
|
+
const response = await this.request(`/executions/${encodeURIComponent(executionId)}/logs`);
|
|
167
167
|
if (!response.success || !response.data) {
|
|
168
168
|
throw new Error(response.error || 'Failed to get execution logs');
|
|
169
169
|
}
|
|
@@ -173,7 +173,7 @@ export class FlowDropApiClient {
|
|
|
173
173
|
* Validate workflow configuration
|
|
174
174
|
*/
|
|
175
175
|
async validateWorkflow(workflow) {
|
|
176
|
-
const response = await this.request('/
|
|
176
|
+
const response = await this.request('/workflows/validate', {
|
|
177
177
|
method: 'POST',
|
|
178
178
|
body: JSON.stringify(workflow)
|
|
179
179
|
});
|
|
@@ -186,7 +186,7 @@ export class FlowDropApiClient {
|
|
|
186
186
|
* Export workflow as JSON
|
|
187
187
|
*/
|
|
188
188
|
async exportWorkflow(workflowId) {
|
|
189
|
-
const response = await this.request(`/
|
|
189
|
+
const response = await this.request(`/workflows/${encodeURIComponent(workflowId)}/export`);
|
|
190
190
|
if (!response.success || !response.data) {
|
|
191
191
|
throw new Error(response.error || 'Failed to export workflow');
|
|
192
192
|
}
|
|
@@ -196,7 +196,7 @@ export class FlowDropApiClient {
|
|
|
196
196
|
* Import workflow from JSON
|
|
197
197
|
*/
|
|
198
198
|
async importWorkflow(workflowJson) {
|
|
199
|
-
const response = await this.request('/
|
|
199
|
+
const response = await this.request('/workflows/import', {
|
|
200
200
|
method: 'POST',
|
|
201
201
|
body: JSON.stringify({ workflow: workflowJson })
|
|
202
202
|
});
|
|
@@ -209,7 +209,7 @@ export class FlowDropApiClient {
|
|
|
209
209
|
* Fetch port configuration
|
|
210
210
|
*/
|
|
211
211
|
async getPortConfig() {
|
|
212
|
-
const response = await this.request('/
|
|
212
|
+
const response = await this.request('/port-config');
|
|
213
213
|
if (!response.success || !response.data) {
|
|
214
214
|
throw new Error(response.error || 'Failed to fetch port configuration');
|
|
215
215
|
}
|
|
@@ -219,7 +219,7 @@ export class FlowDropApiClient {
|
|
|
219
219
|
* Fetch pipeline data including job information and status
|
|
220
220
|
*/
|
|
221
221
|
async getPipelineData(pipelineId) {
|
|
222
|
-
const response = await this.request(`/
|
|
222
|
+
const response = await this.request(`/pipeline/${encodeURIComponent(pipelineId)}`);
|
|
223
223
|
return response;
|
|
224
224
|
}
|
|
225
225
|
}
|