Skip to content

Commit

Permalink
refactor: Upgrade svelvet (#358)
Browse files Browse the repository at this point in the history
# Description

- Upgrade `svelvet` to v8(using new `Anchor`, `Edge` and `Node`
components)
- Maintain Node positions, so running workflow one after workflow two
will no long cause the Nodes to jump up to the first row

## Link to issue

#337

## Type of change

- [x] Bug fix (non-breaking change that fixes an issue)
- [x] Refactor (non-breaking change that updates existing functionality)

## Test plan (required)

1. Run `cargo run -- start -c config/settings.toml` from
`homestar/examples/websocket-relay`
2. Run `npm run dev` from `homestar/examples/websocket-relay/relay-app`
3. Visit http://localhost:5173/
4. Run workflow one and expect the Nodes and edges to appear mostly as
they did before(black edges with arrows and labels describing the
associated tasks)
5. Run workflow two and expect the grayscale Node to appear in the
bottom row with an edge connected to its north side
6. Refresh the page
7. Run workflow two and expect the Nodes, Edges and labels to appear
correctly in the bottom row
8. Run workflow one and expect the Nodes that have already been executed
to stay in the bottom row, but also have the blurred Node rendered in
the top row with an Edge connected to it

## Screenshots/Screencaps


https://www.loom.com/share/acc35d252e8b4d5a94a6f0d53aecfa91?sid=54cdb36b-1837-4082-b759-f8e80f36503e

---------

Co-authored-by: Brian Ginsburg <[email protected]>
  • Loading branch information
avivash and bgins committed Oct 9, 2023
1 parent 0eeb0bf commit 15de823
Show file tree
Hide file tree
Showing 11 changed files with 445 additions and 1,263 deletions.
1,364 changes: 175 additions & 1,189 deletions examples/websocket-relay/relay-app/package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions examples/websocket-relay/relay-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@
"tailwindcss": "^3.3.1",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^4.2.0",
"vite": "^4.4.2",
"vitest": "^0.25.3"
},
"type": "module",
"dependencies": {
"@zerodevx/svelte-json-view": "^1.0.3",
"clipboard-copy": "^4.0.1",
"svelvet": "github:bgins/Svelvet#custom-for-homestar"
"svelvet": "8.1.0"
}
}
6 changes: 6 additions & 0 deletions examples/websocket-relay/relay-app/src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@
font-weight: 400;
src: url("/IBMPlexMono-Regular.ttf") format("truetype");
}


/* Svelvet */
.label-wrapper .default-label {
@apply font-sans text-xs !important;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script lang="ts">
import { Anchor, type Connections, type Direction } from "svelvet";
import Edge from "./Edge.svelte";
export let connections: Connections | null = null
export let direction: Direction
export let edgeLabel: string | null = null
export let id: string
</script>

<Anchor
{direction}
dynamic
{...(connections ? { connections }: {})}
{...(edgeLabel ? { edgeLabel }: {})}
{id}
invisible
multiple
>
<Edge slot="edge" />
</Anchor>
33 changes: 33 additions & 0 deletions examples/websocket-relay/relay-app/src/components/node/Edge.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<script lang="ts">
import { Edge } from "svelvet";
export let arrowDirection: string = 'left'
</script>

<Edge let:path labelColor="white">
<defs>
<marker
id="arrow"
viewBox="0 0 10 10"
refX="11"
refY="5"
markerWidth="6"
markerHeight="6"
orient="auto-start-reverse"
fill="#000000"
>
<path d="M 0 0 L 10 5 L 0 10 z" />
</marker>
</defs>
<path
d={path}
{...(arrowDirection === 'right' ? { 'marker-end': "url(#arrow)" } : { 'marker-start': "url(#arrow)" })}
/>
</Edge>

<style>
path {
stroke: #000000;
stroke-width: 2px;
}
</style>
116 changes: 116 additions & 0 deletions examples/websocket-relay/relay-app/src/components/node/Node.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<script lang="ts">
import { Node } from "svelvet";
import type { CSSColorString } from "svelvet";
import { base64CatStore, edgeStore } from "../../stores";
import type { Position } from "$lib/node";
import type { Task } from "$lib/task";
import Anchor from "./Anchor.svelte";
export let base64Cat: string = $base64CatStore;
export let bgColor: CSSColorString = "white";
export let borderColor: CSSColorString = "transparent";
export let dimensions = {
height: 150,
width: 150,
};
export let label = "Default Node";
export let tempcat = false;
export let id: string;
export let position: Position;
export let task: Task | null = null;
const matchingEdge = $edgeStore.find((edge) => edge?.target === id)
</script>

<Node
{id}
{...dimensions}
{bgColor}
{borderColor}
{label}
{position}
>
<div class="relative w-full h-full">
{#if task === null}
{#if !tempcat}
<img
src={`data:image/png;base64,${base64Cat}`}
draggable="false"
alt="A cat in space chilling on a synth."
/>
<Anchor
id="1-east"
direction="east"
/>
{:else}
<img
src={`data:image/png;base64,${base64Cat}`}
draggable="false"
alt="A cat in space chilling on a synth."
/>
<Anchor
id="1-east"
direction="east"
/>
{/if}
{:else if task.status === "replayed"}
<img
src={`data:image/png;base64,${task.receipt?.out[1]}`}
draggable="false"
style="filter: opacity(75%)"
alt={`A cat image after a ${task.operation} performed by Homestar. The operation was replayed.`}
/>
{#if matchingEdge}
<!-- If difference between `target` and `source` is greater than 1, we're breaking to a new row, so we'll use north/south directions -->
{#if (matchingEdge.target - matchingEdge.source) > 1}
<Anchor
id={`${id}-north`}
direction="north"
connections={[[`${matchingEdge.source}`, `${matchingEdge.source}-south`]]}
edgeLabel={matchingEdge.label}
/>
{:else}
<Anchor
id={`${id}-west`}
direction="west"
connections={[[`${matchingEdge.source}`, `${matchingEdge.source}-east`]]}
edgeLabel={matchingEdge.label}
/>
{/if}
{/if}
{:else}
<img
src={`data:image/png;base64,${task.receipt?.out[1]}`}
draggable="false"
alt={`A cat image after a ${task.operation} performed by Homestar`}
/>
{#if matchingEdge}
<!-- If difference between `target` and `source` is greater than 1, we're breaking to a new row, so we'll use north/south directions -->
{#if (matchingEdge.target - matchingEdge.source) > 1}
<Anchor
id={`${id}-north`}
direction="north"
connections={[[`${matchingEdge.source}`, `${matchingEdge.source}-south`]]}
edgeLabel={matchingEdge.label}
/>
{:else}
<Anchor
id={`${id}-west`}
direction="west"
connections={[[`${matchingEdge.source}`, `${matchingEdge.source}-east`]]}
edgeLabel={matchingEdge.label}
/>
{/if}
{/if}
{/if}
<Anchor
id={`${id}-east`}
direction="east"
/>
<Anchor
id={`${id}-south`}
direction="south"
/>
</div>
</Node>
4 changes: 4 additions & 0 deletions examples/websocket-relay/relay-app/src/lib/node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type Position = {
x: number;
y: number;
};
8 changes: 7 additions & 1 deletion examples/websocket-relay/relay-app/src/lib/workflow.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { get as getStore } from "svelte/store";

import { base64CatStore } from "../stores";
import { base64CatStore, firstWorkflowToRunStore } from "../stores";
import type { Receipt, TaskOperation, TaskStatus, Meta } from "$lib/task";

import {
Expand Down Expand Up @@ -29,6 +29,7 @@ export type WorkflowId = "one" | "two";
// RUN
export async function run(workflowId: WorkflowId) {
let channel = getStore(channelStore);
const firstWorkflowToRun = getStore(firstWorkflowToRunStore);
const tasks = getStore(taskStore);

if (!channel) {
Expand All @@ -47,6 +48,11 @@ export async function run(workflowId: WorkflowId) {
failedPingCount: 0,
});

// Record the first workflow that ran
if (!firstWorkflowToRun) {
firstWorkflowToRunStore.set(workflowId)
}

// Set workflow status to working
workflowStore.update((workflows) => ({
...workflows,
Expand Down
37 changes: 17 additions & 20 deletions examples/websocket-relay/relay-app/src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
<script lang="ts">
import type { NodeType } from "svelvet";
import { onDestroy } from "svelte";
import Svelvet from "svelvet";
import { Svelvet } from "svelvet";
import { connect } from "$lib/channel";
import { base64CatStore, edgeStore, nodeStore } from "../stores";
import { base64CatStore, nodeStore, taskStore } from "../stores";
import Controls from "$components/Controls.svelte";
import Header from "$components/Header.svelte";
import WorkflowDetail from "$components/WorkflowDetail.svelte";
import Node from "$components/node/Node.svelte";
let nodes: any[] = [];
let edges: any[] = [];
let showWorkflowModal = false;
let windowHeight = window.innerHeight;
let windowWidth = window.innerWidth;
Expand All @@ -19,11 +18,7 @@
nodes = store;
});
const unsubscribeEdgeStore = edgeStore.subscribe((store) => {
edges = store;
});
function handleWindowResize(event: Event) {
function handleWindowResize() {
windowHeight = window.innerHeight;
windowWidth = window.innerWidth;
}
Expand All @@ -40,30 +35,32 @@
}
// Set spacecat unmodified image
initializeSpaceCat();
const fetchCat = initializeSpaceCat();
// Connect to websocket server
connect();
onDestroy(() => {
unsubscribeNodeStore();
unsubscribeEdgeStore();
});
</script>

<svelte:window on:resize={handleWindowResize} />

<Header on:workflow={toggleWorflowModal} />

{#if showWorkflowModal}
<WorkflowDetail />
{/if}

<Controls />
<Svelvet
{nodes}
{edges}
width={windowWidth}
height={windowHeight}
initialZoom={1.25}
initialLocation={{ x: 0, y: 0 }}
boundary={{ x: windowWidth + 200, y: windowHeight + 200 }}
/>

{#await fetchCat then _}
<Svelvet width={windowWidth} height={windowHeight} zoom={1.25}>
{#key nodes}
{#each nodes as node}
<Node {...node} />
{/each}
{/key}
</Svelvet>
{/await}
Loading

0 comments on commit 15de823

Please sign in to comment.