diff --git a/app/src/lib/graph-interface/node/NodeParameter.svelte b/app/src/lib/graph-interface/node/NodeParameter.svelte
index 180f98b..824acee 100644
--- a/app/src/lib/graph-interface/node/NodeParameter.svelte
+++ b/app/src/lib/graph-interface/node/NodeParameter.svelte
@@ -73,6 +73,8 @@
{#key id && graphId}
@@ -87,12 +89,14 @@
{#if node?.tmp?.type?.inputs?.[id]?.internal !== true}
* {
pointer-events: none;
}
diff --git a/app/src/lib/node-registry-client.ts b/app/src/lib/node-registry-client.ts
index 8fc35e0..4c6afda 100644
--- a/app/src/lib/node-registry-client.ts
+++ b/app/src/lib/node-registry-client.ts
@@ -10,10 +10,12 @@ export class RemoteNodeRegistry implements NodeRegistry {
status: "loading" | "ready" | "error" = "loading";
private nodes: Map = new Map();
+ fetch: typeof fetch = globalThis.fetch.bind(globalThis);
+
constructor(private url: string) { }
async fetchUsers() {
- const response = await fetch(`${this.url}/nodes/users.json`);
+ const response = await this.fetch(`${this.url}/nodes/users.json`);
if (!response.ok) {
throw new Error(`Failed to load users`);
}
@@ -21,7 +23,7 @@ export class RemoteNodeRegistry implements NodeRegistry {
}
async fetchUser(userId: `${string}`) {
- const response = await fetch(`${this.url}/nodes/${userId}.json`);
+ const response = await this.fetch(`${this.url}/nodes/${userId}.json`);
if (!response.ok) {
throw new Error(`Failed to load user ${userId}`);
}
@@ -29,23 +31,15 @@ export class RemoteNodeRegistry implements NodeRegistry {
}
async fetchCollection(userCollectionId: `${string}/${string}`) {
- const response = await fetch(`${this.url}/nodes/${userCollectionId}.json`);
+ const response = await this.fetch(`${this.url}/nodes/${userCollectionId}.json`);
if (!response.ok) {
throw new Error(`Failed to load collection ${userCollectionId}`);
}
return response.json();
}
- async fetchNode(nodeId: `${string}/${string}/${string}`) {
- const response = await fetch(`${this.url}/nodes/${nodeId}.wasm`);
- if (!response.ok) {
- throw new Error(`Failed to load node wasm ${nodeId}`);
- }
- return response.arrayBuffer();
- }
-
async fetchNodeDefinition(nodeId: `${string}/${string}/${string}`) {
- const response = await fetch(`${this.url}/nodes/${nodeId}.json`);
+ const response = await this.fetch(`${this.url}/nodes/${nodeId}.json`);
if (!response.ok) {
throw new Error(`Failed to load node definition ${nodeId}`);
}
@@ -58,18 +52,22 @@ export class RemoteNodeRegistry implements NodeRegistry {
const nodes = await Promise.all(nodeIds.map(async id => {
if (this.nodes.has(id)) {
- return this.nodes.get(id);
+ return this.nodes.get(id)!;
}
- const wasmResponse = await this.fetchNode(id);
+ const response = await this.fetch(`${this.url}/nodes/${id}.wasm`);
+ if (!response.ok) {
+ throw new Error(`Failed to load node wasm ${id}`);
+ }
- const wrapper = createWasmWrapper(wasmResponse);
+ const wasmBuffer = await response.arrayBuffer();
+
+ const wrapper = createWasmWrapper(wasmBuffer);
const definition = wrapper.get_definition();
return {
...definition,
- id,
execute: wrapper.execute
};
}));
@@ -80,7 +78,10 @@ export class RemoteNodeRegistry implements NodeRegistry {
const duration = performance.now() - a;
- log.log("loaded nodes in", duration, "ms");
+ log.group("loaded nodes in", duration, "ms");
+ log.info(nodeIds);
+ log.info(nodes);
+ log.groupEnd();
this.status = "ready";
return nodes
diff --git a/app/src/lib/remote-runtime-executor.ts b/app/src/lib/remote-runtime-executor.ts
new file mode 100644
index 0000000..9640730
--- /dev/null
+++ b/app/src/lib/remote-runtime-executor.ts
@@ -0,0 +1,18 @@
+import type { Graph, RuntimeExecutor } from "@nodes/types";
+
+export class RemoteRuntimeExecutor implements RuntimeExecutor {
+
+ constructor(private url: string) { }
+
+ async execute(graph: Graph, settings: Record): Promise {
+
+ const res = await fetch(this.url, { method: "POST", body: JSON.stringify({ graph, settings }) });
+
+ if (!res.ok) {
+ throw new Error(`Failed to execute graph`);
+ }
+
+ return new Int32Array(await res.arrayBuffer());
+
+ }
+}
diff --git a/app/src/lib/runtime-executor.ts b/app/src/lib/runtime-executor.ts
index 7a33af7..6e740de 100644
--- a/app/src/lib/runtime-executor.ts
+++ b/app/src/lib/runtime-executor.ts
@@ -47,12 +47,14 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
constructor(private registry: NodeRegistry, private cache?: RuntimeCache) { }
- private getNodeDefinitions(graph: Graph) {
+ private async getNodeDefinitions(graph: Graph) {
if (this.registry.status !== "ready") {
throw new Error("Node registry is not ready");
}
+ await this.registry.load(graph.nodes.map(node => node.type));
+
const typeMap = new Map();
for (const node of graph.nodes) {
if (!typeMap.has(node.type)) {
@@ -65,10 +67,10 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
return typeMap;
}
- private addMetaData(graph: Graph) {
+ private async addMetaData(graph: Graph) {
// First, lets check if all nodes have a definition
- this.definitionMap = this.getNodeDefinitions(graph);
+ this.definitionMap = await this.getNodeDefinitions(graph);
const outputNode = graph.nodes.find(node => node.type.endsWith("/output"));
if (!outputNode) {
@@ -124,7 +126,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
return [outputNode, nodes] as const;
}
- execute(graph: Graph, settings: Record) {
+ async execute(graph: Graph, settings: Record) {
this.perf?.startRun();
@@ -133,7 +135,7 @@ export class MemoryRuntimeExecutor implements RuntimeExecutor {
let a = performance.now();
// Then we add some metadata to the graph
- const [outputNode, nodes] = this.addMetaData(graph);
+ const [outputNode, nodes] = await this.addMetaData(graph);
let b = performance.now();
this.perf?.addPoint("metadata", b - a);
diff --git a/app/src/lib/settings/app-settings.ts b/app/src/lib/settings/app-settings.ts
index c7c92dc..3d4439d 100644
--- a/app/src/lib/settings/app-settings.ts
+++ b/app/src/lib/settings/app-settings.ts
@@ -5,6 +5,7 @@ export const AppSettings = localStore("node-settings", {
showGrid: true,
showNodeGrid: true,
snapToGrid: true,
+ showHelp: false,
wireframe: false,
showIndices: false,
showVertices: false,
@@ -55,6 +56,11 @@ export const AppSettingTypes = {
type: "boolean",
label: "Snap to Grid",
value: true
+ },
+ showHelp: {
+ type: "boolean",
+ label: "Show Help",
+ value: false
}
},
debug: {
diff --git a/app/src/routes/+page.svelte b/app/src/routes/+page.svelte
index e5dbe9b..f045a5f 100644
--- a/app/src/routes/+page.svelte
+++ b/app/src/routes/+page.svelte
@@ -26,9 +26,11 @@
import NestedSettings from "$lib/settings/panels/NestedSettings.svelte";
import { createPerformanceStore } from "$lib/performance";
import { type PerformanceData } from "$lib/performance/store";
+ import { RemoteRuntimeExecutor } from "$lib/remote-runtime-executor";
const nodeRegistry = new RemoteNodeRegistry("");
const workerRuntime = new WorkerRuntimeExecutor();
+ // const remoteRuntime = new RemoteRuntimeExecutor("/runtime");
let performanceData: PerformanceData;
let viewerPerformance = createPerformanceStore();
@@ -44,6 +46,8 @@
? JSON.parse(localStorage.getItem("graph")!)
: templates.plant;
+ console.log({ graph });
+
let manager: GraphManager;
let managerStatus: Writable<"loading" | "error" | "idle">;
$: if (manager) {
@@ -75,6 +79,7 @@
isWorking = true;
try {
let a = performance.now();
+ // res = await remoteRuntime.execute(_graph, _settings);
res = await workerRuntime.execute(_graph, _settings);
let b = performance.now();
let perfData = await workerRuntime.getPerformanceData();
@@ -120,9 +125,9 @@
@@ -133,8 +138,9 @@
bind:manager
bind:activeNode
bind:keymap
- showGrid={$AppSettings?.showNodeGrid}
- snapToGrid={$AppSettings?.snapToGrid}
+ showGrid={$AppSettings.showNodeGrid}
+ snapToGrid={$AppSettings.snapToGrid}
+ bind:showHelp={$AppSettings.showHelp}
bind:settings={graphSettings}
bind:settingTypes={graphSettingTypes}
on:result={(ev) => handleResult(ev.detail, $graphSettings)}
diff --git a/app/src/routes/runtime/+server.ts b/app/src/routes/runtime/+server.ts
new file mode 100644
index 0000000..673f7c3
--- /dev/null
+++ b/app/src/routes/runtime/+server.ts
@@ -0,0 +1,29 @@
+import type { RequestHandler } from "./$types";
+import { MemoryRuntimeExecutor } from "$lib/runtime-executor";
+import { RemoteNodeRegistry } from "$lib/node-registry-client";
+import { createPerformanceStore } from "$lib/performance";
+
+const registry = new RemoteNodeRegistry("");
+const runtime = new MemoryRuntimeExecutor(registry);
+const performanceStore = createPerformanceStore();
+runtime.perf = performanceStore;
+
+
+export const POST: RequestHandler = async ({ request, fetch }) => {
+
+ const { graph, settings } = await request.json();
+
+ registry.fetch = fetch;
+
+ await registry.load(graph.nodes.map(node => node.type))
+
+ const res = await runtime.execute(graph, settings);
+
+ let headers: Record = { "Content-Type": "application/octet-stream" };
+ if (runtime.perf) {
+ headers["performance"] = JSON.stringify(runtime.perf.get());
+ }
+
+ return new Response(res, { headers });
+
+}
diff --git a/nodes/max/plantarium/branch/src/input.json b/nodes/max/plantarium/branch/src/input.json
index b42e9cf..c518e1b 100644
--- a/nodes/max/plantarium/branch/src/input.json
+++ b/nodes/max/plantarium/branch/src/input.json
@@ -1,5 +1,5 @@
{
- "id": "max/plantarium/branches",
+ "id": "max/plantarium/branch",
"outputs": [
"path"
],
diff --git a/packages/types/src/components.ts b/packages/types/src/components.ts
index df8c0d5..f941f18 100644
--- a/packages/types/src/components.ts
+++ b/packages/types/src/components.ts
@@ -13,13 +13,13 @@ export interface NodeRegistry {
* @throws An error if the nodes could not be loaded
* @remarks This method should be called before calling getNode or getAllNodes
*/
- load: (nodeIds: NodeId[]) => Promise;
+ load: (nodeIds: (NodeId | string)[]) => Promise;
/**
* Get a node by id
* @param id - The id of the node to get
* @returns The node with the given id, or undefined if no such node exists
*/
- getNode: (id: NodeId) => NodeDefinition | undefined;
+ getNode: (id: NodeId | string) => NodeDefinition | undefined;
/**
* Get all nodes
* @returns An array of all nodes
@@ -33,7 +33,7 @@ export interface RuntimeExecutor {
* @param graph - The graph to execute
* @returns The result of the execution
*/
- execute: (graph: Graph, settings: Record) => Int32Array;
+ execute: (graph: Graph, settings: Record) => Promise;
}
export interface RuntimeCache {