diff --git a/package-lock.json b/package-lock.json index 438b2467..8322975f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "dependencies": { "@electron/remote": "^2.0.10", "@popperjs/core": "^2.11.8", - "blix_svelvet": "^1.0.7", + "blix_svelvet": "^1.0.13", "child_process": "^1.0.2", "chokidar": "^3.5.3", "cohere-ai": "^5.1.0", @@ -4822,9 +4822,9 @@ } }, "node_modules/blix_svelvet": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/blix_svelvet/-/blix_svelvet-1.0.7.tgz", - "integrity": "sha512-8hbz0M5oXTPTw4AUEgeg4j2D59h78gOyyJ5RLOpOzeYoEwfKPZfmL7/o77X2bFwdWQJ5hw+RPtKoeoo3jUgR7g==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/blix_svelvet/-/blix_svelvet-1.0.13.tgz", + "integrity": "sha512-nmOAY7q2OqlwaJjPqG4P221DHKyAc07vpvOfgUOyULeACziefhjJt76D70TL221edIqj9cPm1zFcfi96iPz9EQ==", "dependencies": { "abab": "^2.0.6", "acorn": "^8.9.0", diff --git a/package.json b/package.json index 10ee9fe9..418e117b 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "dependencies": { "@electron/remote": "^2.0.10", "@popperjs/core": "^2.11.8", - "blix_svelvet": "^1.0.7", + "blix_svelvet": "^1.0.13", "child_process": "^1.0.2", "chokidar": "^3.5.3", "cohere-ai": "^5.1.0", diff --git a/src/electron/lib/core-graph/CoreGraph.ts b/src/electron/lib/core-graph/CoreGraph.ts index 617e327f..6f538f70 100644 --- a/src/electron/lib/core-graph/CoreGraph.ts +++ b/src/electron/lib/core-graph/CoreGraph.ts @@ -1,11 +1,12 @@ import logger from "../../utils/logger"; import { type UUID, UniqueEntity } from "../../../shared/utils/UniqueEntity"; import type { CoreGraphSubscriber } from "./CoreGraphInteractors"; -import type { - AnchorType, +import { + type AnchorType, InputAnchorInstance, NodeInstance, OutputAnchorInstance, + checkEdgeDataTypesCompatible, } from "../registries/ToolboxRegistry"; import { get } from "http"; import type { EdgeToJSON, GraphToJSON, NodeToJSON } from "./CoreGraphExporter"; @@ -179,7 +180,7 @@ export class CoreGraph extends UniqueEntity { } // Data flowing through edge must be of same type for both anchors - if (ancFrom.type !== ancTo.type) { + if (!checkEdgeDataTypesCompatible(ancFrom.type, ancTo.type)) { return { status: "error", message: "Data flowing through edge must be of same type for both anchors", diff --git a/src/electron/lib/core-graph/CoreGraphManager.ts b/src/electron/lib/core-graph/CoreGraphManager.ts index bf88e7bd..e710da7c 100644 --- a/src/electron/lib/core-graph/CoreGraphManager.ts +++ b/src/electron/lib/core-graph/CoreGraphManager.ts @@ -29,24 +29,6 @@ export class CoreGraphManager { this._toolbox = toolbox; this._importer = new CoreGraphImporter(this._toolbox); // Test send dummy graph to frontend - this.testingSendToClient(); - } - - testingSendToClient() { - this.createGraph(); // TODO: REMOVE; This is just for testing - this.createGraph(); - this.createGraph(); - this.createGraph(); - - // There currently isn't proper implementation to map the CoreGraph to a - // UIGraph with the frontend nodes and anchors. Sorry that I didn't do this, - // not sure if Jake can help with this cause he made the CoreGraph - // setTimeout(() => { - // setInterval(() => { - // if (this._mainWindow) - // this._mainWindow?.apis.clientGraphApi.graphChanged(ids[0], { uuid: ids[0] } as UIGraph); - // }, 5000); - // }, 5000); } importGraph(format: string, data: GraphToJSON | string) { diff --git a/src/electron/lib/registries/ToolboxRegistry.ts b/src/electron/lib/registries/ToolboxRegistry.ts index 19257860..c12bbf53 100644 --- a/src/electron/lib/registries/ToolboxRegistry.ts +++ b/src/electron/lib/registries/ToolboxRegistry.ts @@ -126,3 +126,10 @@ export class InputAnchorInstance implements AnchorInstance { export class OutputAnchorInstance implements AnchorInstance { constructor(readonly type: AnchorType, readonly id: string, readonly displayName: string) {} } + +export function checkEdgeDataTypesCompatible(sourceDataType: string, targetDataType: string) { + const dataTypeA = sourceDataType.trim().split(/\s+/).join(" ") || ""; + const dataTypeB = targetDataType.trim().split(/\s+/).join(" ") || ""; + + return dataTypeA === "" || dataTypeB === "" || dataTypeA === dataTypeB; +} diff --git a/src/frontend/lib/stores/GraphStore.ts b/src/frontend/lib/stores/GraphStore.ts index 62edf82a..eaba0a4a 100644 --- a/src/frontend/lib/stores/GraphStore.ts +++ b/src/frontend/lib/stores/GraphStore.ts @@ -45,9 +45,9 @@ export class GraphStore { for (const node of Object.keys(oldNodes)) { if (graph.nodes[node]) { graph.nodes[node].styling = oldNodes[node].styling; + graph.nodes[node].inputUIValues = oldNodes[node].inputUIValues; } } - return graph; }); } diff --git a/src/frontend/ui/tiles/Graph.svelte b/src/frontend/ui/tiles/Graph.svelte index 37eb66cc..9da91280 100644 --- a/src/frontend/ui/tiles/Graph.svelte +++ b/src/frontend/ui/tiles/Graph.svelte @@ -8,7 +8,8 @@ import { projectsStore } from "lib/stores/ProjectStore"; import { graphMenuStore } from "../../lib/stores/GraphContextMenuStore"; import type { UUID } from "@shared/utils/UniqueEntity"; - import type { GraphEdge, GraphNode } from "@shared/ui/UIGraph"; + import { GraphNode, type GraphEdge } from "@shared/ui/UIGraph"; + import { tick } from "svelte"; // import { type Anchor } from "blix_svelvet/dist/types"; // TODO: Use to createEdge // TODO: Abstract panelId to use a generic UUID @@ -45,16 +46,19 @@ if ($thisGraphStore) { graphNodes = $thisGraphStore.getNodesReactive(); graphEdges = $thisGraphStore.getEdgesReactive(); + updateOnGraphEdges($graphEdges); } } - function updateOnGraphEdges(graphEdges: GraphEdge[]) { + async function updateOnGraphEdges(edges: GraphEdge[]) { + // When the tile first loads, `clearAllGraphEdges` and `connectAnchorIds` + // only work after the tick - when the new graph anchors have been created + await tick(); if (clearAllGraphEdges) clearAllGraphEdges(); - for (let edge in graphEdges) { - console.log("EDGE", edge, graphEdges[edge]); - if (!graphEdges.hasOwnProperty(edge)) continue; - const edgeData = graphEdges[edge]; + for (let edge in edges) { + if (!edges.hasOwnProperty(edge)) continue; + const edgeData = edges[edge]; // Skip if nodes don't exist // const fromNode = $graphNodes.find(node => node.id === edgeData.nodeFrom) @@ -78,11 +82,6 @@ // Only updates when _graphId_ changes $: updateOnGraphId(graphId); - function addNode() { - $thisGraphStore?.addNode("hello-plugin.hello", getGraphCenter()); - // $thisGraphStore?.addNode(); - } - function getGraphCenter() { return { x: $dimensions.width / 2 - $translation.x / $zoom, diff --git a/src/frontend/ui/utils/graph/PluginNode.svelte b/src/frontend/ui/utils/graph/PluginNode.svelte index 4ea34833..87ea9f08 100644 --- a/src/frontend/ui/utils/graph/PluginNode.svelte +++ b/src/frontend/ui/utils/graph/PluginNode.svelte @@ -1,9 +1,8 @@ {#if svelvetNodeId !== ""} @@ -41,8 +56,6 @@ height="{graphNode.dims.h}" --> borderColor="#ffffff" borderWidth="{3}" borderRadius="{10}" - inputs="{2}" - outputs="{1}" >
@@ -61,26 +74,63 @@ height="{graphNode.dims.h}" --> {#if $toolboxNode}
{#each $toolboxNode.inputs as input} + {@const color = stringToColor(input.type)} + on:connection="{() => dispatch('connection', { input })}" + on:disconnection="{() => dispatch('disconnection', { input })}" + let:connecting + let:hovering + > + {#if hovering} +
+ {input.type || "any"} +
+ {/if} + +
{/each}
{#each $toolboxNode.outputs as output} + {@const color = stringToColor(output.type)} + on:connection="{() => dispatch('connection', { output })}" + on:disconnection="{() => dispatch('disconnection', { output })}" + let:connecting + let:hovering + > + {#if hovering} +
+ {output.type || "any"} +
+ {/if} + +
{/each}
{/if} @@ -135,6 +185,15 @@ height="{graphNode.dims.h}" --> right: -24px; top: 40px; } + + .anchorTooltip { + position: absolute; + background: #444444; + color: white; + border-radius: 2px; + padding: 0.2em; + top: -1.5em; + } .header { display: flex; justify-content: space-between;