b7f3061be3
- Tauri 2 + Svelte 5 hub in ODIAN dark: patch notes and roadmap, install and update progress, local stack status, settings with DHP and MCP addresses. - crates/odian-packs: Rust installer for pack format v1 (signed manifests, resumable verified downloads from a DHP or an ODIAN drive), byte-compatible with ODIAN_MCP_Server's Python odian_packs. - Local stack on 127.0.0.1: Postgres -> Engine API -> tile server -> Odian.exe, one Job Object, clean shutdown; database snapshot restore on a fresh PC only. - Keycloak sign-in through the DHP's MCP, remembered until Sign out with a launcher session that renews the Engine token silently. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
5.2 KiB
5.2 KiB
UI ↔ backend contract
The Svelte UI (src/) talks to the Rust backend (src-tauri/) only through the
Tauri commands and events below. src/lib/backend.ts is the single place that
calls them. When the page runs outside Tauri (a plain browser, for design work),
it falls back to a mock with the same shapes.
All names are snake_case on the wire (serde defaults), and timestamps are Unix seconds.
Types
type Phase =
| "idle" // nothing running
| "checking" // probing the site
| "signing_in" // browser sign-in in progress
| "installing" // downloading + verifying a version
| "restoring" // loading the database snapshot into local Postgres
| "launching" // starting Postgres → API → tile server → Odian.exe
| "running" // Odian.exe is open
| "error"; // the last long operation failed; see `error`
interface Status {
online: boolean; // the site's update service answered /v1/health
site: { url: string; name: string | null };
operator: string | null; // last signed-in ODIAN username (cached; valid offline)
signed_in: boolean; // this PC remembers the operator's site sign-in until Sign out: the
// launcher renews the short Engine token by itself (launcher session)
installed: string | null; // installed version, e.g. "0.51.0"
available: string | null; // the site's CURRENT version (online only)
update_required: boolean; // online && installed !== null && available !== null && installed !== available
// (never true when nothing is installed: that is a first install)
can_launch: boolean; // installed && !update_required && phase is idle or error
phase: Phase;
error: string | null; // set with phase "error"; cleared by the next command or `refresh`
install_dir: string; // e.g. "D:\\ODIAN"
}
interface Settings {
site_url: string; // e.g. "http://192.168.1.41:30097"
mcp_url: string; // site MCP, for Keycloak sign-in
install_dir: string;
}
interface InstallProgress {
stage: "manifest" | "app" | "db" | "src" | "tiles" | "restore" | "finalize";
stage_index: number; // 1-based
stage_count: number;
done_bytes: number; // within the current stage
total_bytes: number; // of the current stage; 0 when unknown
done_items: number; // within the current stage
total_items: number;
bytes_per_sec: number;
message: string | null; // e.g. "tiles dark/protomaps_20260423: 412/1402 blocks"
}
interface StackEvent {
component: "postgres" | "api" | "tiles" | "odian";
state: "starting" | "ready" | "stopped" | "failed";
message: string | null;
}
interface LogEvent { level: "info" | "warn" | "error"; message: string; at: number }
Commands (invoke)
| Command | Args | Returns | Notes |
|---|---|---|---|
get_status |
— | Status |
cheap; no network |
refresh |
— | Status |
re-probes the site (2 s timeout); also clears an error phase |
sign_in |
— | { username: string } |
opens the system browser (MCP desktop flow) and waits for the loopback callback. Rejects with "Sign-in was cancelled." after cancel_sign_in (phase returns to idle, not error). |
cancel_sign_in |
— | void |
abandons a sign-in that is waiting for the browser |
sign_out |
— | Status |
forgets the operator on this PC: the site sign-in, its launcher session (ended on the site when reachable) and the cached operator. Offline launch needs a new sign-in afterwards, so the UI confirms first |
get_notes |
{ version?: string } |
string |
Markdown. From the site when online; the cached copy of the installed version offline. Untrusted: the UI must sanitize. |
open_external |
{ url: string } |
void |
opens an http/https link in the system browser (links in patch notes); anything else is refused |
start_install |
— | void |
installs or updates to available; needs signed_in (the site checks the token); progress arrives as events |
start_install_from_drive |
{ path: string } |
void |
same, reading an ODIAN drive (SSD) instead of the site; no sign-in needed |
cancel_install |
— | void |
stops at the next file boundary; everything already verified is kept |
launch |
— | void |
starts the local stack; stack events follow |
stop |
— | void |
stops Odian.exe's stack cleanly |
get_stack |
— | StackEvent[] |
the latest event per component of the current or last launch (for a reloaded UI) |
get_settings |
— | Settings |
|
set_settings |
{ settings: Settings } |
Status |
|
pick_folder |
— | string | null |
native folder picker |
Errors reject the promise with a string message.
Planned, not yet available: the size of available for the Install button, and
inspecting a drive (its version and size) before installing from it.
Events (listen)
| Event | Payload | When |
|---|---|---|
status |
Status |
whenever any field changes |
install-progress |
InstallProgress |
at most ~10 per second while installing |
stack |
StackEvent |
on each component state change |
log |
LogEvent |
notable backend messages, for the activity panel |