Files
octoturge 9cb59d723e Fix desktop crate build; simplify tray/menu and telemetry reconnect
Real bugs found by actually compiling the Tauri crate for the first time:
- Cargo.toml declared a [lib] with no src/lib.rs (cargo refused to parse
  the manifest) — added the standard Tauri 2 main.rs/lib.rs split.
- generate_context!() needs real icon files; icons/ only had a .gitkeep.
  Added placeholder PNG/ICO/ICNS icons.

Also simplified: dropped the tray icon + menu (one more moving part not
needed yet), and the telemetry store's exponential backoff is now a fixed
3s retry, matching the same simplification made to continuum-proxy's
uplink client.

Fixed two real TS bugs while typechecking apps/web for the first time
(missing @types/node for nuxt.config.ts's process.env access, untyped
useFetch call inferring 'never'). Verified: cargo check (desktop),
vue-tsc --noEmit (web + ui packages) all clean.
2026-08-28 18:33:40 +00:00

84 lines
1.9 KiB
TypeScript

import { defineStore } from "pinia";
export interface PrinterTelemetry {
printerId: string;
farmId: string;
state: "idle" | "printing" | "paused" | "error" | "offline";
nozzleTempC: number;
bedTempC: number;
progressPct: number;
updatedAt: string;
}
interface TelemetryState {
socket: WebSocket | null;
connected: boolean;
printers: Record<string, PrinterTelemetry>;
}
const RECONNECT_DELAY_MS = 3_000;
export const useTelemetryStore = defineStore("telemetry", {
state: (): TelemetryState => ({
socket: null,
connected: false,
printers: {},
}),
getters: {
printerList: (state) => Object.values(state.printers),
},
actions: {
connect() {
if (this.socket) return;
const config = useRuntimeConfig();
const client = useSupabaseClient();
client.auth.getSession().then(({ data }) => {
const token = data.session?.access_token ?? "";
const url = `${config.public.wsBase}/ws/telemetry?token=${encodeURIComponent(token)}`;
this.open(url);
});
},
open(url: string) {
const socket = new WebSocket(url);
socket.onopen = () => {
this.connected = true;
};
socket.onmessage = (event) => {
try {
const payload = JSON.parse(event.data) as { type: string; data: PrinterTelemetry };
if (payload.type === "printer.telemetry") {
this.printers[payload.data.printerId] = payload.data;
}
} catch {
// Ignore malformed frames rather than crashing the UI.
}
};
socket.onclose = () => {
this.connected = false;
this.socket = null;
setTimeout(() => this.connect(), RECONNECT_DELAY_MS);
};
socket.onerror = () => {
socket.close();
};
this.socket = socket;
},
disconnect() {
this.socket?.close();
this.socket = null;
this.connected = false;
},
},
});