Spaces:
Running
Running
// Baklava feature requests: | |
// - Node search (https://github.com/newcat/baklavajs/issues/315) | |
// - Check out sidebar | |
// - Collapse node | |
// - Customize toolbar | |
// - Nicer styling for node palette, node categories | |
// - Group nodes, like in Litegraph. | |
// - Show param name for TextInputInterface. | |
// - Resizable nodes. (Horizontally.) | |
// - Put input and output on same line? | |
<template> | |
<div style="width: 100vw; height: 100vh"> | |
<BaklavaEditor :view-model="baklava" /> | |
</div> | |
</template> | |
<script setup lang="ts"> | |
import { BaklavaEditor, useBaklava } from "@baklavajs/renderer-vue"; | |
import * as BaklavaJS from "baklavajs"; | |
import "@baklavajs/themes/dist/syrup-dark.css"; | |
import { markRaw } from "vue"; | |
import { NodeInterface } from "baklavajs"; | |
import GraphViz from "./components/GraphViz.vue"; | |
const ops = [ | |
{ name: 'Create scale-free graph', type: 'Creation', inputs: [], outputs: ['graph'], params: ['Number of nodes'] }, | |
{ name: 'Compute PageRank', type: 'Algorithms', inputs: ['graph'], outputs: ['graph'], params: ['Damping factor', 'Max iterations'] }, | |
{ name: 'SQL', type: 'Algorithms', inputs: ['graph'], outputs: ['table'], params: ['Query'] }, | |
{ name: 'Visualize graph', type: 'Visualization', inputs: ['graph'], outputs: ['graph-viz'], | |
params: ['Color by', 'Size by'], | |
calculate(inputs) { | |
console.log('Visualize graph', inputs); | |
return { | |
'graph-viz': 15, | |
}; | |
} | |
}, | |
{ name: 'Num', type: 'Visualization', inputs: [], outputs: ['num'], params: [] }, | |
]; | |
function makeParam(param: string): NodeInterface { | |
return new BaklavaJS.TextInputInterface(param).setPort(false); | |
} | |
function makeOutput(output: string): NodeInterface { | |
if (output === 'graph-viz') { | |
return new NodeInterface(output, 0).setComponent(markRaw(GraphViz)).setPort(false); | |
} else if (output === 'num') { | |
return new BaklavaJS.NumberInterface(output, 0); | |
} else { | |
return new BaklavaJS.NodeInterface(output, 0); | |
} | |
} | |
const baklava = useBaklava(); | |
for (const op of ops) { | |
baklava.editor.registerNodeType(BaklavaJS.defineNode({ | |
type: op.name, | |
inputs: { | |
...op.inputs.reduce((acc, input) => ({ ...acc, [input]: () => new BaklavaJS.NodeInterface(input) }), {}), | |
...op.params.reduce((acc, param) => ({ ...acc, [param]: () => makeParam(param)}), {}), | |
}, | |
outputs: op.outputs.reduce((acc, output) => ({ ...acc, [output]: () => makeOutput(output) }), {}), | |
calculate: op.calculate, | |
}), { category: op.type }); | |
} | |
import { DependencyEngine } from "@baklavajs/engine"; | |
// Needed? | |
const engine = new DependencyEngine(baklava.editor); | |
engine.start(); | |
import { applyResult } from "@baklavajs/engine"; | |
// Needed? | |
const token = Symbol(); | |
engine.events.afterRun.subscribe(token, (result) => { | |
engine.pause(); | |
applyResult(result, baklava.editor); | |
engine.resume(); | |
}); | |
let lastSave; | |
baklava.editor.nodeEvents.update.subscribe(token, async (result) => { | |
const s = JSON.stringify(baklava.editor.save()); | |
if (s !== lastSave) { | |
lastSave = s; | |
console.log('save', JSON.parse(s)); | |
const res = await fetch('/api/save', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
body: s, | |
}); | |
const j = await res.json(); | |
console.log('save response', j); | |
} | |
}); | |
</script> | |