@flowdrop/flowdrop 2.0.0-beta.3 → 2.0.0-beta.4
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/CHANGELOG.md +25 -0
- package/README.md +5 -5
- package/dist/components/App.svelte +15 -146
- package/dist/components/Button.stories.svelte +65 -0
- package/dist/components/Button.stories.svelte.d.ts +19 -0
- package/dist/components/Button.svelte +62 -0
- package/dist/components/Button.svelte.d.ts +24 -0
- package/dist/components/ConfigForm.svelte +4 -4
- package/dist/components/EditorStatusBar.stories.svelte +44 -0
- package/dist/components/EditorStatusBar.stories.svelte.d.ts +27 -0
- package/dist/components/EditorStatusBar.svelte +99 -0
- package/dist/components/EditorStatusBar.svelte.d.ts +15 -0
- package/dist/components/IconButton.svelte +80 -0
- package/dist/components/IconButton.svelte.d.ts +30 -0
- package/dist/components/Input.svelte +74 -0
- package/dist/components/Input.svelte.d.ts +17 -0
- package/dist/components/Navbar.svelte +9 -4
- package/dist/components/Navbar.svelte.d.ts +3 -0
- package/dist/components/NodeSidebar.svelte +13 -111
- package/dist/components/NodeSwapPicker.svelte +10 -26
- package/dist/components/Select.svelte +53 -0
- package/dist/components/Select.svelte.d.ts +15 -0
- package/dist/components/Textarea.svelte +39 -0
- package/dist/components/Textarea.svelte.d.ts +12 -0
- package/dist/components/ThemeToggle.svelte +15 -89
- package/dist/components/form/FormArray.svelte +37 -157
- package/dist/components/form/FormCheckboxGroup.svelte +1 -1
- package/dist/components/form/FormField.svelte +5 -44
- package/dist/components/form/FormFieldLight.svelte +5 -44
- package/dist/components/form/FormFieldset.svelte +1 -1
- package/dist/components/form/FormNumberField.svelte +4 -32
- package/dist/components/form/FormRangeField.svelte +17 -7
- package/dist/components/form/FormSelect.svelte +13 -79
- package/dist/components/form/FormTextField.svelte +3 -39
- package/dist/components/form/FormTextarea.svelte +4 -43
- package/dist/components/form/resolveFieldType.d.ts +24 -0
- package/dist/components/form/resolveFieldType.js +55 -0
- package/dist/components/icons/CloseIcon.svelte +6 -0
- package/dist/components/icons/CloseIcon.svelte.d.ts +26 -0
- package/dist/components/playground/InputCollector.svelte +11 -46
- package/dist/messages/index.d.ts +1 -1
- package/dist/messages/index.js +1 -1
- package/dist/openapi/v1/openapi.yaml +2 -2
- package/dist/skins/drafter.js +41 -28
- package/dist/styles/base.css +247 -5
- package/dist/styles/tokens.css +6 -0
- package/dist/svelte-app.js +68 -107
- package/dist/utils/connections.js +14 -50
- package/package.json +1 -1
|
@@ -253,8 +253,17 @@ export function getConnectionSuggestions(checker, nodeId, nodes, nodeTypes) {
|
|
|
253
253
|
* @returns True if any cycle exists in the workflow
|
|
254
254
|
*/
|
|
255
255
|
export function hasCycles(nodes, edges) {
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
return detectCycles(nodes, edges);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Detect whether a directed graph contains a cycle, using DFS over a pre-built
|
|
260
|
+
* adjacency map (O(E) build, O(1) per neighbour lookup — avoids the O(V*E) of
|
|
261
|
+
* re-scanning every edge on each recursive call).
|
|
262
|
+
*
|
|
263
|
+
* Shared by `hasCycles` (all edges) and `hasInvalidCycles` (loopback edges
|
|
264
|
+
* pre-filtered out by the caller).
|
|
265
|
+
*/
|
|
266
|
+
function detectCycles(nodes, edges) {
|
|
258
267
|
const adjacencyMap = new Map();
|
|
259
268
|
for (const node of nodes) {
|
|
260
269
|
adjacencyMap.set(node.id, []);
|
|
@@ -274,7 +283,6 @@ export function hasCycles(nodes, edges) {
|
|
|
274
283
|
return false;
|
|
275
284
|
visited.add(nodeId);
|
|
276
285
|
recursionStack.add(nodeId);
|
|
277
|
-
// Use pre-built adjacency map instead of filtering all edges each call
|
|
278
286
|
const neighbors = adjacencyMap.get(nodeId) || [];
|
|
279
287
|
for (const target of neighbors) {
|
|
280
288
|
if (hasCycleUtil(target))
|
|
@@ -283,7 +291,6 @@ export function hasCycles(nodes, edges) {
|
|
|
283
291
|
recursionStack.delete(nodeId);
|
|
284
292
|
return false;
|
|
285
293
|
}
|
|
286
|
-
// Check each node
|
|
287
294
|
for (const node of nodes) {
|
|
288
295
|
if (!visited.has(node.id)) {
|
|
289
296
|
if (hasCycleUtil(node.id))
|
|
@@ -309,53 +316,10 @@ export function hasCycles(nodes, edges) {
|
|
|
309
316
|
* ```
|
|
310
317
|
*/
|
|
311
318
|
export function hasInvalidCycles(nodes, edges) {
|
|
312
|
-
// Filter out loopback edges - these create valid cycles for loop iteration
|
|
319
|
+
// Filter out loopback edges - these create valid cycles for loop iteration,
|
|
320
|
+
// then reuse the shared detector over the remaining edges.
|
|
313
321
|
const nonLoopbackEdges = edges.filter((edge) => !isLoopbackEdge(edge));
|
|
314
|
-
|
|
315
|
-
// loop is O(1) per lookup instead of scanning all edges on every recursive
|
|
316
|
-
// call (which was O(V*E)).
|
|
317
|
-
const adjacencyMap = new Map();
|
|
318
|
-
for (const node of nodes) {
|
|
319
|
-
adjacencyMap.set(node.id, []);
|
|
320
|
-
}
|
|
321
|
-
for (const edge of nonLoopbackEdges) {
|
|
322
|
-
const neighbors = adjacencyMap.get(edge.source);
|
|
323
|
-
if (neighbors) {
|
|
324
|
-
neighbors.push(edge.target);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
// Check for cycles using only non-loopback edges
|
|
328
|
-
const visited = new Set();
|
|
329
|
-
const recursionStack = new Set();
|
|
330
|
-
/**
|
|
331
|
-
* DFS utility to detect cycles in the graph
|
|
332
|
-
* @param nodeId - Current node being visited
|
|
333
|
-
* @returns True if a cycle is found from this node
|
|
334
|
-
*/
|
|
335
|
-
function hasCycleUtil(nodeId) {
|
|
336
|
-
if (recursionStack.has(nodeId))
|
|
337
|
-
return true;
|
|
338
|
-
if (visited.has(nodeId))
|
|
339
|
-
return false;
|
|
340
|
-
visited.add(nodeId);
|
|
341
|
-
recursionStack.add(nodeId);
|
|
342
|
-
// Use pre-built adjacency map instead of filtering all edges each call
|
|
343
|
-
const neighbors = adjacencyMap.get(nodeId) || [];
|
|
344
|
-
for (const target of neighbors) {
|
|
345
|
-
if (hasCycleUtil(target))
|
|
346
|
-
return true;
|
|
347
|
-
}
|
|
348
|
-
recursionStack.delete(nodeId);
|
|
349
|
-
return false;
|
|
350
|
-
}
|
|
351
|
-
// Check each node for cycles
|
|
352
|
-
for (const node of nodes) {
|
|
353
|
-
if (!visited.has(node.id)) {
|
|
354
|
-
if (hasCycleUtil(node.id))
|
|
355
|
-
return true;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
return false;
|
|
322
|
+
return detectCycles(nodes, nonLoopbackEdges);
|
|
359
323
|
}
|
|
360
324
|
/**
|
|
361
325
|
* Get the execution order for a workflow (topological sort)
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "A drop-in visual workflow editor for any web application. You own the backend. You own the data. You own the orchestration.",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"private": false,
|
|
6
|
-
"version": "2.0.0-beta.
|
|
6
|
+
"version": "2.0.0-beta.4",
|
|
7
7
|
"author": "Shibin Das (D34dMan)",
|
|
8
8
|
"bugs": {
|
|
9
9
|
"url": "https://github.com/flowdrop-io/flowdrop/issues"
|