Spaces:
Runtime error
Runtime error
Flexible inputs!
Browse files- server/main.py +1 -1
- server/ops.py +6 -3
- server/workspace.py +3 -0
- web/index.html +1 -1
- web/src/LynxKiteFlow.svelte +4 -1
- web/src/LynxKiteNode.svelte +13 -6
- web/src/Workspace.svelte +2 -1
server/main.py
CHANGED
|
@@ -28,7 +28,7 @@ def save(req: SaveRequest):
|
|
| 28 |
@app.post("/api/save")
|
| 29 |
def save_and_execute(req: SaveRequest):
|
| 30 |
save(req)
|
| 31 |
-
execute(req.ws)
|
| 32 |
save(req)
|
| 33 |
return req.ws
|
| 34 |
|
|
|
|
| 28 |
@app.post("/api/save")
|
| 29 |
def save_and_execute(req: SaveRequest):
|
| 30 |
save(req)
|
| 31 |
+
workspace.execute(req.ws)
|
| 32 |
save(req)
|
| 33 |
return req.ws
|
| 34 |
|
server/ops.py
CHANGED
|
@@ -57,9 +57,12 @@ class Op:
|
|
| 57 |
def to_json(self):
|
| 58 |
return {
|
| 59 |
'type': self.type,
|
| 60 |
-
'data': {
|
| 61 |
-
|
| 62 |
-
|
|
|
|
|
|
|
|
|
|
| 63 |
'sub_nodes': [sub.to_json() for sub in self.sub_nodes.values()] if self.sub_nodes else None,
|
| 64 |
}
|
| 65 |
|
|
|
|
| 57 |
def to_json(self):
|
| 58 |
return {
|
| 59 |
'type': self.type,
|
| 60 |
+
'data': {
|
| 61 |
+
'title': self.name,
|
| 62 |
+
'inputs': {i: str(type) for i, type in self.inputs.items()},
|
| 63 |
+
'outputs': {o: str(type) for o, type in self.outputs.items()},
|
| 64 |
+
'params': [p.to_json() for p in self.params.values()],
|
| 65 |
+
},
|
| 66 |
'sub_nodes': [sub.to_json() for sub in self.sub_nodes.values()] if self.sub_nodes else None,
|
| 67 |
}
|
| 68 |
|
server/workspace.py
CHANGED
|
@@ -71,6 +71,9 @@ def execute(ws):
|
|
| 71 |
data.error = str(e)
|
| 72 |
failed += 1
|
| 73 |
continue
|
|
|
|
|
|
|
|
|
|
| 74 |
data.error = None
|
| 75 |
outputs[node.id] = output
|
| 76 |
if op.type == 'graph_view' or op.type == 'table_view':
|
|
|
|
| 71 |
data.error = str(e)
|
| 72 |
failed += 1
|
| 73 |
continue
|
| 74 |
+
if len(op.inputs) == 1 and op.inputs.get('multi') == '*':
|
| 75 |
+
# It's a flexible input. Create n+1 handles.
|
| 76 |
+
data.inputs = {f'input{i}': None for i in range(len(inputs) + 1)}
|
| 77 |
data.error = None
|
| 78 |
outputs[node.id] = output
|
| 79 |
if op.type == 'graph_view' or op.type == 'table_view':
|
web/index.html
CHANGED
|
@@ -2,7 +2,7 @@
|
|
| 2 |
<html lang="en">
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8" />
|
| 5 |
-
<link rel="icon" type="image/png" href="/
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
<title>LynxKite 2024</title>
|
| 8 |
</head>
|
|
|
|
| 2 |
<html lang="en">
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8" />
|
| 5 |
+
<link rel="icon" type="image/png" href="/favicon.ico" />
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
<title>LynxKite 2024</title>
|
| 8 |
</head>
|
web/src/LynxKiteFlow.svelte
CHANGED
|
@@ -133,7 +133,10 @@
|
|
| 133 |
function onconnect(connection: Connection) {
|
| 134 |
edges.update((edges) => {
|
| 135 |
// Only one source can connect to a given target.
|
| 136 |
-
return edges.filter((e) =>
|
|
|
|
|
|
|
|
|
|
| 137 |
});
|
| 138 |
}
|
| 139 |
function nodeClick(e) {
|
|
|
|
| 133 |
function onconnect(connection: Connection) {
|
| 134 |
edges.update((edges) => {
|
| 135 |
// Only one source can connect to a given target.
|
| 136 |
+
return edges.filter((e) =>
|
| 137 |
+
e.source === connection.source
|
| 138 |
+
|| e.target !== connection.target
|
| 139 |
+
|| e.targetHandle !== connection.targetHandle);
|
| 140 |
});
|
| 141 |
}
|
| 142 |
function nodeClick(e) {
|
web/src/LynxKiteNode.svelte
CHANGED
|
@@ -29,6 +29,9 @@
|
|
| 29 |
function asPx(n: number) {
|
| 30 |
return n ? n + 'px' : undefined;
|
| 31 |
}
|
|
|
|
|
|
|
|
|
|
| 32 |
</script>
|
| 33 |
|
| 34 |
<div class="node-container" style:width={asPx(width)} style:height={asPx(height)} style={containerStyle}>
|
|
@@ -43,12 +46,16 @@
|
|
| 43 |
{/if}
|
| 44 |
<slot />
|
| 45 |
{/if}
|
| 46 |
-
{#
|
| 47 |
-
<Handle
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
{
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
</div>
|
| 53 |
</div>
|
| 54 |
|
|
|
|
| 29 |
function asPx(n: number) {
|
| 30 |
return n ? n + 'px' : undefined;
|
| 31 |
}
|
| 32 |
+
$: inputs = Object.entries(data.inputs || {});
|
| 33 |
+
$: outputs = Object.entries(data.outputs || {});
|
| 34 |
+
const handleOffsetDirection = { top: 'left', bottom: 'left', left: 'top', right: 'top' };
|
| 35 |
</script>
|
| 36 |
|
| 37 |
<div class="node-container" style:width={asPx(width)} style:height={asPx(height)} style={containerStyle}>
|
|
|
|
| 46 |
{/if}
|
| 47 |
<slot />
|
| 48 |
{/if}
|
| 49 |
+
{#each inputs as [name, input], i}
|
| 50 |
+
<Handle
|
| 51 |
+
id={name} type="target" position={targetPosition || 'left'}
|
| 52 |
+
style="{handleOffsetDirection[targetPosition || 'left']}: {100 * (i + 1) / (inputs.length + 1)}%" />
|
| 53 |
+
{/each}
|
| 54 |
+
{#each outputs as [name, output], i}
|
| 55 |
+
<Handle
|
| 56 |
+
id={name} type="source" position={sourcePosition || 'right'}
|
| 57 |
+
style="{handleOffsetDirection[sourcePosition || 'right']}: {100 * (i + 1) / (outputs.length + 1)}%" />
|
| 58 |
+
{/each}
|
| 59 |
</div>
|
| 60 |
</div>
|
| 61 |
|
web/src/Workspace.svelte
CHANGED
|
@@ -52,7 +52,8 @@
|
|
| 52 |
align-items: center;
|
| 53 |
}
|
| 54 |
.tools a {
|
| 55 |
-
color:
|
| 56 |
font-size: 1.5em;
|
|
|
|
| 57 |
}
|
| 58 |
</style>
|
|
|
|
| 52 |
align-items: center;
|
| 53 |
}
|
| 54 |
.tools a {
|
| 55 |
+
color: #39bcf3;
|
| 56 |
font-size: 1.5em;
|
| 57 |
+
padding: 0 10px;
|
| 58 |
}
|
| 59 |
</style>
|