Wires the native Save/Open and SVG/PNG export paths used by the frontend IO layer. Adds tauri-plugin-dialog and tauri-plugin-fs, initializes them in the builder, and grants open/save/read/write permissions in the default capability. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pipeline Network Diagram Editor
A desktop editor for designing pipeline networks (water, gas, power, steam …),
built with Tauri v2 + React + TypeScript + Vite and the JointJS
(@joint/core, MPL-2.0) diagramming engine.
Features
Canvas & modelling
- Grouped, searchable node palette of vector components (source, sink, pump, valve, tank, junction, filter, meter, heat-exchanger, compressor). Drag onto the canvas or double-click to add.
- Nodes are defined by an SVG icon set plus a port configuration (medium + direction + side).
- Clicking a node reveals its ports; drag from a port to draw a connector. Connections are validated by relation — mediums must be compatible (e.g. water↔water, water↔hot-water) and directions complementary (out→in).
- Grid (Manhattan) routing with a configurable arc-on-intersection
connector (JointJS
jumpover), plus orthogonal / straight routers. - Edge styles with source/target markers: arrow, open-arrow, circle, diamond, bar, and solid/dashed/dotted lines.
- Multiple color schemes (default, dark, blueprint, high-contrast) keyed by medium.
Properties
- Right panel shows grouped, typed properties for the selected node/edge: Identity, Geometry, Presentation, Physics.
- Editors for every type:
string, int, float, enum, color, catalogueItem, catalogueItems, list. Values are validated/coerced and written live to the canvas. Catalogues (pipes, pumps, materials) back the catalogue types.
Editing UX
- Undo/redo, delete, copy/cut/paste, duplicate, select-all.
- Keyboard shortcuts (Del, Ctrl+Z/Y, Ctrl+C/X/V/D/A, Esc, Ctrl+±).
- Zoom (buttons + Ctrl-wheel toward cursor), blank-drag pan, fit-to-content, reset. Snap-to-grid.
- Save / Open (
.json) and export SVG / PNG — native file dialogs under Tauri, browser download/upload as a fallback.
Mock calculation
- A deterministic flow-distribution solver computes per-edge flow from node supplies/demands, respecting conservation and splitting at junctions by downstream demand.
- Run simulation animates flow along each edge — dash direction follows the sign, speed and width follow the volume — and the status bar reports total supply/demand, balance and warnings (under-supplied / unbalanced).
Getting started
npm install
# Frontend dev server (browser) — http://localhost:1420
npm run dev
# Full desktop app (Tauri)
npm run tauri dev
If port 1420 is already in use, stop the other process or change
server.portinvite.config.tsandbuild.devUrlinsrc-tauri/tauri.conf.json.
Quality gates
npm run test:run # 47 unit + integration + component tests (Vitest)
npm run test:coverage
npm run typecheck # tsc --noEmit
npm run lint # oxlint
npm run build # tsc -b && vite build
Architecture
src/
model/ pure domain: mediums/relations, color schemes, property schema,
catalogues, node types + SVG icon set, edge styles (tested)
calc/ mock flow-distribution solver (tested)
canvas/ graphOps (paper-independent graph logic, tested) +
CanvasController (paper, selection, tools, undo, animation) + shapes
store/ Zustand editor store (config, selection, catalogues)
ui/ Toolbar, NodePalette, PropertiesPanel, ConfigPanel, StatusBar,
CanvasView, property-type editors
io/ document save/open, SVG/PNG export (Tauri + browser fallback)
src-tauri/ Tauri v2 Rust shell
docs/plan/ implementation plan & milestone checklist
The core logic is decoupled from the JointJS Paper (which needs a real DOM) so
it can be unit-tested in jsdom: model/, calc/ and canvas/graphOps.ts are
all covered directly.
Why JointJS
Chosen over React Flow / Rete / GoJS because it uniquely covers every hard
requirement out of the box: framework-agnostic custom SVG node markup, a
first-class port model with validateConnection, built-in grid routers,
the jumpover arc connector for the arc-on-intersection requirement, and
rich link markers for arrow/circle/diamond edge ends. See
docs/plan/README.md for the full rationale and plan.