@d34dman/flowdrop 0.0.10 → 0.0.11
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/dist/components/App.svelte +20 -385
- package/dist/components/ConfigForm.svelte +299 -448
- package/dist/components/ConfigForm.svelte.d.ts +6 -29
- package/dist/components/PipelineStatus.svelte +5 -0
- package/dist/components/WorkflowEditor.svelte +23 -10
- package/dist/utils/performanceUtils.d.ts +30 -0
- package/dist/utils/performanceUtils.js +109 -0
- package/package.json +2 -2
|
@@ -1,32 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { WorkflowNode } from "../types/index.js";
|
|
2
2
|
interface Props {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
node: WorkflowNode;
|
|
4
|
+
onSave: (config: Record<string, unknown>) => void;
|
|
5
|
+
onCancel: () => void;
|
|
6
6
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
$$bindings?: Bindings;
|
|
10
|
-
} & Exports;
|
|
11
|
-
(internal: unknown, props: Props & {
|
|
12
|
-
$$events?: Events;
|
|
13
|
-
$$slots?: Slots;
|
|
14
|
-
}): Exports & {
|
|
15
|
-
$set?: any;
|
|
16
|
-
$on?: any;
|
|
17
|
-
};
|
|
18
|
-
z_$$bindings?: Bindings;
|
|
19
|
-
}
|
|
20
|
-
declare const ConfigForm: $$__sveltets_2_IsomorphicComponent<Props, {
|
|
21
|
-
change: CustomEvent<{
|
|
22
|
-
values: ConfigValues;
|
|
23
|
-
}>;
|
|
24
|
-
validate: CustomEvent<{
|
|
25
|
-
isValid: boolean;
|
|
26
|
-
errors: string[];
|
|
27
|
-
}>;
|
|
28
|
-
} & {
|
|
29
|
-
[evt: string]: CustomEvent<any>;
|
|
30
|
-
}, {}, {}, "">;
|
|
31
|
-
type ConfigForm = InstanceType<typeof ConfigForm>;
|
|
7
|
+
declare const ConfigForm: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type ConfigForm = ReturnType<typeof ConfigForm>;
|
|
32
9
|
export default ConfigForm;
|
|
@@ -34,6 +34,11 @@
|
|
|
34
34
|
ConfigurationHelper
|
|
35
35
|
} from '../helpers/workflowEditorHelper.js';
|
|
36
36
|
import type { NodeExecutionInfo } from '../types/index.js';
|
|
37
|
+
import {
|
|
38
|
+
areNodeArraysEqual,
|
|
39
|
+
areEdgeArraysEqual,
|
|
40
|
+
throttle
|
|
41
|
+
} from '../utils/performanceUtils.js';
|
|
37
42
|
|
|
38
43
|
interface Props {
|
|
39
44
|
nodes?: NodeMetadata[];
|
|
@@ -127,12 +132,16 @@
|
|
|
127
132
|
}
|
|
128
133
|
});
|
|
129
134
|
|
|
130
|
-
|
|
131
|
-
|
|
135
|
+
/**
|
|
136
|
+
* Throttled function to update the global store
|
|
137
|
+
* Reduces update frequency during rapid changes (e.g., node dragging)
|
|
138
|
+
* Uses 16ms throttle (~60fps) for smooth performance
|
|
139
|
+
*/
|
|
140
|
+
const updateGlobalStore = throttle((): void => {
|
|
132
141
|
if (currentWorkflow) {
|
|
133
142
|
workflowActions.updateWorkflow(currentWorkflow);
|
|
134
143
|
}
|
|
135
|
-
}
|
|
144
|
+
}, 16);
|
|
136
145
|
|
|
137
146
|
/**
|
|
138
147
|
* Load node execution information for all nodes in the workflow
|
|
@@ -206,18 +215,22 @@
|
|
|
206
215
|
let previousNodes = $state<WorkflowNodeType[]>([]);
|
|
207
216
|
let previousEdges = $state<WorkflowEdge[]>([]);
|
|
208
217
|
|
|
209
|
-
|
|
218
|
+
/**
|
|
219
|
+
* Watch for changes from SvelteFlow and update currentWorkflow
|
|
220
|
+
* Uses efficient comparison instead of expensive JSON.stringify
|
|
221
|
+
* This reduces event handler time from 290-310ms to <50ms
|
|
222
|
+
*/
|
|
210
223
|
$effect(() => {
|
|
211
|
-
// Check if nodes have changed from SvelteFlow
|
|
212
|
-
const nodesChanged =
|
|
213
|
-
const edgesChanged =
|
|
224
|
+
// Check if nodes have changed from SvelteFlow using fast comparison
|
|
225
|
+
const nodesChanged = !areNodeArraysEqual(flowNodes, previousNodes);
|
|
226
|
+
const edgesChanged = !areEdgeArraysEqual(flowEdges, previousEdges);
|
|
214
227
|
|
|
215
228
|
if ((nodesChanged || edgesChanged) && currentWorkflow) {
|
|
216
229
|
updateCurrentWorkflowFromSvelteFlow();
|
|
217
230
|
|
|
218
|
-
// Update previous values
|
|
219
|
-
previousNodes =
|
|
220
|
-
previousEdges =
|
|
231
|
+
// Update previous values with shallow copies
|
|
232
|
+
previousNodes = [...flowNodes];
|
|
233
|
+
previousEdges = [...flowEdges];
|
|
221
234
|
}
|
|
222
235
|
});
|
|
223
236
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance Utilities
|
|
3
|
+
* Helper functions for optimizing performance in the FlowDrop app
|
|
4
|
+
*/
|
|
5
|
+
import type { WorkflowNode, WorkflowEdge } from "../types/index.js";
|
|
6
|
+
/**
|
|
7
|
+
* Fast shallow comparison for workflow nodes
|
|
8
|
+
* Avoids expensive JSON.stringify operations
|
|
9
|
+
*/
|
|
10
|
+
export declare function areNodeArraysEqual(nodes1: WorkflowNode[], nodes2: WorkflowNode[]): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Fast shallow comparison for workflow edges
|
|
13
|
+
* Avoids expensive JSON.stringify operations
|
|
14
|
+
*/
|
|
15
|
+
export declare function areEdgeArraysEqual(edges1: WorkflowEdge[], edges2: WorkflowEdge[]): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Throttle function execution to reduce frequency
|
|
18
|
+
* Uses requestAnimationFrame for smooth UI updates
|
|
19
|
+
*/
|
|
20
|
+
export declare function throttle<T extends (...args: any[]) => void>(func: T, wait: number): (...args: Parameters<T>) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Debounce function execution to reduce frequency
|
|
23
|
+
* Waits for a pause in calls before executing
|
|
24
|
+
*/
|
|
25
|
+
export declare function debounce<T extends (...args: any[]) => void>(func: T, wait: number): (...args: Parameters<T>) => void;
|
|
26
|
+
/**
|
|
27
|
+
* RequestAnimationFrame-based throttle for smooth animations
|
|
28
|
+
* Better for visual updates like node dragging
|
|
29
|
+
*/
|
|
30
|
+
export declare function rafThrottle<T extends (...args: any[]) => void>(func: T): (...args: Parameters<T>) => void;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance Utilities
|
|
3
|
+
* Helper functions for optimizing performance in the FlowDrop app
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Fast shallow comparison for workflow nodes
|
|
7
|
+
* Avoids expensive JSON.stringify operations
|
|
8
|
+
*/
|
|
9
|
+
export function areNodeArraysEqual(nodes1, nodes2) {
|
|
10
|
+
if (nodes1.length !== nodes2.length)
|
|
11
|
+
return false;
|
|
12
|
+
for (let i = 0; i < nodes1.length; i++) {
|
|
13
|
+
const node1 = nodes1[i];
|
|
14
|
+
const node2 = nodes2[i];
|
|
15
|
+
// Quick ID check
|
|
16
|
+
if (node1?.id !== node2?.id)
|
|
17
|
+
return false;
|
|
18
|
+
// Check position (most common change during drag)
|
|
19
|
+
if (node1?.position?.x !== node2?.position?.x ||
|
|
20
|
+
node1?.position?.y !== node2?.position?.y) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
// Check selected state
|
|
24
|
+
if (node1?.selected !== node2?.selected)
|
|
25
|
+
return false;
|
|
26
|
+
// Skip deep config comparison unless we need to
|
|
27
|
+
// Most updates are position-based
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Fast shallow comparison for workflow edges
|
|
33
|
+
* Avoids expensive JSON.stringify operations
|
|
34
|
+
*/
|
|
35
|
+
export function areEdgeArraysEqual(edges1, edges2) {
|
|
36
|
+
if (edges1.length !== edges2.length)
|
|
37
|
+
return false;
|
|
38
|
+
for (let i = 0; i < edges1.length; i++) {
|
|
39
|
+
const edge1 = edges1[i];
|
|
40
|
+
const edge2 = edges2[i];
|
|
41
|
+
if (edge1?.id !== edge2?.id ||
|
|
42
|
+
edge1?.source !== edge2?.source ||
|
|
43
|
+
edge1?.target !== edge2?.target ||
|
|
44
|
+
edge1?.sourceHandle !== edge2?.sourceHandle ||
|
|
45
|
+
edge1?.targetHandle !== edge2?.targetHandle) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Throttle function execution to reduce frequency
|
|
53
|
+
* Uses requestAnimationFrame for smooth UI updates
|
|
54
|
+
*/
|
|
55
|
+
export function throttle(func, wait) {
|
|
56
|
+
let timeout = null;
|
|
57
|
+
let lastRan = 0;
|
|
58
|
+
return function (...args) {
|
|
59
|
+
const now = Date.now();
|
|
60
|
+
if (!lastRan || now - lastRan >= wait) {
|
|
61
|
+
func(...args);
|
|
62
|
+
lastRan = now;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
if (timeout) {
|
|
66
|
+
clearTimeout(timeout);
|
|
67
|
+
}
|
|
68
|
+
timeout = setTimeout(() => {
|
|
69
|
+
func(...args);
|
|
70
|
+
lastRan = Date.now();
|
|
71
|
+
}, wait - (now - lastRan));
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Debounce function execution to reduce frequency
|
|
77
|
+
* Waits for a pause in calls before executing
|
|
78
|
+
*/
|
|
79
|
+
export function debounce(func, wait) {
|
|
80
|
+
let timeout = null;
|
|
81
|
+
return function (...args) {
|
|
82
|
+
if (timeout) {
|
|
83
|
+
clearTimeout(timeout);
|
|
84
|
+
}
|
|
85
|
+
timeout = setTimeout(() => {
|
|
86
|
+
func(...args);
|
|
87
|
+
}, wait);
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* RequestAnimationFrame-based throttle for smooth animations
|
|
92
|
+
* Better for visual updates like node dragging
|
|
93
|
+
*/
|
|
94
|
+
export function rafThrottle(func) {
|
|
95
|
+
let rafId = null;
|
|
96
|
+
let lastArgs = null;
|
|
97
|
+
return function (...args) {
|
|
98
|
+
lastArgs = args;
|
|
99
|
+
if (rafId === null) {
|
|
100
|
+
rafId = requestAnimationFrame(() => {
|
|
101
|
+
if (lastArgs) {
|
|
102
|
+
func(...lastArgs);
|
|
103
|
+
}
|
|
104
|
+
rafId = null;
|
|
105
|
+
lastArgs = null;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@d34dman/flowdrop",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"private": false,
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.11",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite dev",
|
|
8
8
|
"build": "vite build && npm run prepack",
|
|
@@ -136,4 +136,4 @@
|
|
|
136
136
|
"svelte-5-french-toast": "^2.0.6",
|
|
137
137
|
"uuid": "^11.1.0"
|
|
138
138
|
}
|
|
139
|
-
}
|
|
139
|
+
}
|