Frontend Architecture
The Ganimede frontend is built with Svelte and uses Yjs for real-time state synchronization. The UI consists of a 2D canvas where cells can be positioned, dragged, and organized into tissue groups.Component Hierarchy
Core Components
App.svelte
Location:ui/src/App.svelte
Responsibilities:
- Application entry point
- Load configuration
- Render Canvas
Canvas.svelte
Location:ui/src/components/Canvas.svelte
Responsibilities:
- 2D scrollable workspace (20000x20000px)
- Pan with mouse drag
- Zoom with mouse wheel
- Context menu for creating cells
- Socket initialization
Notebook.svelte
Location:ui/src/components/Notebook.svelte
Responsibilities:
- Render all cells from YDoc
- Render edges (connections) between cells
- Manage collaboration cursors
- Auto-align cells on first load
- If
cell_idis inpc_graph, it’s a parent (heading) → render asTissue - Otherwise, render as standalone
Cell
Cell.svelte
Location:ui/src/components/Cell.svelte
Responsibilities:
- Individual cell rendering
- Drag and drop positioning
- Cell toolbar and actions
- Auto-positioning within tissue groups
- Reactive YDoc binding
Tissue.svelte
Location:ui/src/components/Tissue.svelte
Responsibilities:
- Render heading cells with child dropzone
- Group multiple cells under a heading
- Auto-calculate dropzone size from children
- Drag and drop for entire group
CodeEditor.svelte (Monaco Integration)
Location:ui/src/components/cell_components/CodeEditor.svelte
Responsibilities:
- Monaco editor instance
- Bind to YText for collaborative editing
- Syntax highlighting
- Keyboard shortcuts (Shift+Enter to run)
Stores
Ganimede uses Svelte stores for reactive state management.Notebook Store (_notebook.js)
Location:ui/src/stores/_notebook.js
Responsibilities:
- Create and connect to YDoc
- Expose Yjs shared types as stores
- Provide cell operations (create, delete, move)
Socket Store (socket.js)
Location:ui/src/stores/socket.js
Responsibilities:
- WebSocket connection to Comms (port 8000)
- Send control messages to backend
Other Stores
- zoom.js: Zoom level (scale transform)
- mouse.js: Global mouse position
- config.js: Configuration fetched from
/config - notifications.js: Toast notifications
Reactivity Patterns
YDoc to Svelte Reactivity
Two-way Binding
Collaboration Features
Awareness (Cursors)
Location:stores/_notebook.js and Notebook.svelte
Key Patterns
- YDoc as state: All persistent state lives in YDoc shared types
- Reactive proxies: Cell objects wrap YDoc maps with getters/setters
- Observer pattern: YDoc changes trigger Svelte reactivity
- Derived state: cp_graph derived from pc_graph, pn_graph from np_graph
- Canvas positioning: Absolute positioning with top/left in px
- Drag and drop: Element detection with
elementsFromPoint - Auto-layout: Reactive statements for tissue child positioning
Related
- Backend Architecture - Python managers and kernel
- Yjs Integration - CRDT synchronization details