diff --git a/frontend/.gitignore b/frontend/.gitignore
index 8b466fd..3187a0f 100644
--- a/frontend/.gitignore
+++ b/frontend/.gitignore
@@ -7,6 +7,8 @@ yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
+.svelte-kit/
+
vite.config.ts.timestamp*
node_modules
diff --git a/frontend/histoire.config.ts b/frontend/histoire.config.ts
new file mode 100644
index 0000000..d7d0f18
--- /dev/null
+++ b/frontend/histoire.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'histoire'
+import { HstSvelte } from '@histoire/plugin-svelte'
+
+export default defineConfig({
+ plugins: [
+ HstSvelte(),
+ ],
+})
diff --git a/frontend/package.json b/frontend/package.json
index 3f5d67f..ff24d6c 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -7,8 +7,10 @@
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
- "check": "svelte-check --tsconfig ./tsconfig.json",
- "tauri": "tauri"
+ "tauri:dev": "tauri dev",
+ "story:dev": "histoire dev",
+ "story:build": "histoire build",
+ "story:preview": "histoire preview"
},
"dependencies": {
"@sveltejs/kit": "^2.5.0",
@@ -21,10 +23,12 @@
"three": "^0.159.0"
},
"devDependencies": {
+ "@histoire/plugin-svelte": "^0.17.9",
"@sveltejs/adapter-static": "^3.0.1",
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"@tauri-apps/cli": "2.0.0-beta.3",
"@tsconfig/svelte": "^5.0.2",
+ "histoire": "^0.17.9",
"internal-ip": "^7.0.0",
"svelte": "^4.2.8",
"svelte-check": "^3.4.6",
diff --git a/frontend/src/lib/components/App.svelte b/frontend/src/lib/components/App.svelte
deleted file mode 100644
index df17bcc..0000000
--- a/frontend/src/lib/components/App.svelte
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
diff --git a/frontend/src/lib/components/Background.story.svelte b/frontend/src/lib/components/Background.story.svelte
new file mode 100644
index 0000000..f88f68a
--- /dev/null
+++ b/frontend/src/lib/components/Background.story.svelte
@@ -0,0 +1,28 @@
+
+
+
output
diff --git a/frontend/src/lib/components/nodes/Test.svelte b/frontend/src/lib/components/nodes/Test.svelte deleted file mode 100644 index 93e784c..0000000 --- a/frontend/src/lib/components/nodes/Test.svelte +++ /dev/null @@ -1,11 +0,0 @@ - - - - - diff --git a/frontend/src/lib/components/nodes/index.ts b/frontend/src/lib/components/nodes/index.ts deleted file mode 100644 index a53f827..0000000 --- a/frontend/src/lib/components/nodes/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Test from './Test.svelte'; -import Output from './Output.svelte'; -export const nodes = { - test: Test, - output: Output, -} as const; diff --git a/frontend/src/lib/graph-manager.ts b/frontend/src/lib/graph-manager.ts new file mode 100644 index 0000000..214dcb0 --- /dev/null +++ b/frontend/src/lib/graph-manager.ts @@ -0,0 +1,114 @@ +import { writable, type Writable } from "svelte/store"; +import type { Graph, NodeRegistry as INodeRegistry, NodeType, Node } from "./types"; +import { snapToGrid } from "./helpers"; + +const nodeTypes: NodeType[] = [ + { + id: "input/float", + inputs: { + "value": { type: "float" }, + }, + outputs: ["float"], + }, + { + id: "math", + inputs: { + "a": { type: "float" }, + "b": { type: "float" }, + }, + outputs: ["float"], + }, +] + +export class NodeRegistry implements INodeRegistry { + getNode(id: string): NodeType | undefined { + return nodeTypes.find((nodeType) => nodeType.id === id); + } +} + + +export class GraphManager { + + status: Writable<"loading" | "idle" | "error"> = writable("loading"); + + nodes: Node[] = []; + edges: { from: string, to: string }[] = []; + + private constructor(private graph: Graph, private nodeRegistry: NodeRegistry = new NodeRegistry()) { + } + + async load() { + + const nodes = this.graph.nodes; + + for (const node of nodes) { + const nodeType = this.getNodeType(node.type); + if (!nodeType) { + console.error(`Node type not found: ${node.type}`); + this.status.set("error"); + return; + } + } + + this.nodes = this.graph.nodes; + this.edges = this.graph.edges; + this.status.set("idle"); + } + + getNode(id: string) { + return this.nodes.find((node) => node.id === id); + } + + public getNodeType(id: string): NodeType { + return this.nodeRegistry.getNode(id)!; + } + + public getEdges() { + return this.edges + .map((edge) => { + const from = this.nodes.find((node) => node.id === edge.from); + const to = this.nodes.find((node) => node.id === edge.to); + if (!from || !to) return; + return [from, to] as const; + }) + .filter(Boolean) as unknown as [Node, Node][]; + } + + + static createEmptyGraph(): GraphManager { + + const graph: Graph = { + edges: [], + nodes: [], + }; + + for (let i = 0; i < 40; i++) { + const x = i % 20; + const y = Math.floor(i / 20); + + graph.nodes.push({ + id: `${i.toString()}`, + tmp: { + visible: false, + }, + position: { + x: x * 7.5, + y: y * 5, + }, + props: i == 0 ? { value: 0 } : {}, + type: i == 0 ? "input/float" : "math", + }); + + graph.edges.push({ + from: i.toString(), + to: (i + 1).toString(), + }); + } + + return new GraphManager(graph); + } + + +} + + diff --git a/frontend/src/lib/helpers.ts b/frontend/src/lib/helpers.ts new file mode 100644 index 0000000..87c43f1 --- /dev/null +++ b/frontend/src/lib/helpers.ts @@ -0,0 +1,3 @@ +export function snapToGrid(value: number, gridSize: number = 10) { + return Math.round(value / gridSize) * gridSize; + } diff --git a/frontend/src/lib/types.ts b/frontend/src/lib/types.ts index 337fd51..4046b2a 100644 --- a/frontend/src/lib/types.ts +++ b/frontend/src/lib/types.ts @@ -1,8 +1,7 @@ -import { nodes } from "$lib/components/nodes" export type Node = { id: string; - type: keyof typeof nodes; + type: string; props?: Record