Files
pistation/apps/kiosk-client/src/lib/api.ts
T
SirBlob 7d0a973638 Add kiosk desktop app
Tauri app for the Pi. Media runs through the native LiveKit SDK because
WebKitGTK has no WebRTC, with frames encoded in Rust and drawn to a canvas
under the annotation overlay.
2026-08-09 17:09:16 -04:00

87 lines
2.4 KiB
TypeScript

import type { KioskLayout, KioskPinResponse, KioskSessionResponse } from "@pistation/shared-types";
export interface RegisterResult {
kioskId: string;
kioskToken: string;
roomName: string;
livekitUrl: string;
rotationSeconds: number;
}
export class KioskApiError extends Error {
readonly status: number;
constructor(status: number, message: string) {
super(message);
this.status = status;
}
}
async function request<T>(
serverUrl: string,
path: string,
options: { method?: string; token?: string; body?: unknown } = {}
): Promise<T> {
const headers: Record<string, string> = {};
if (options.body !== undefined) headers["content-type"] = "application/json";
if (options.token) headers["authorization"] = `Bearer ${options.token}`;
let response: Response;
try {
response = await fetch(`${serverUrl.replace(/\/$/, "")}${path}`, {
method: options.method ?? "GET",
headers,
body: options.body === undefined ? undefined : JSON.stringify(options.body)
});
} catch {
throw new KioskApiError(0, `could not reach the server at ${serverUrl}`);
}
if (response.status === 204) return undefined as T;
const payload = await response.json().catch(() => null);
if (!response.ok) {
const message = (payload as { message?: string })?.message ?? `request failed: ${path}`;
throw new KioskApiError(response.status, message);
}
return payload as T;
}
export function registerKiosk(
serverUrl: string,
enrollmentToken: string,
hardwareId: string
): Promise<RegisterResult> {
return request<RegisterResult>(serverUrl, "/api/kiosk/register", {
method: "POST",
body: { enrollmentToken, hardwareId }
});
}
export function fetchPin(serverUrl: string, token: string): Promise<KioskPinResponse> {
return request<KioskPinResponse>(serverUrl, "/api/kiosk/pin", { token });
}
export function fetchSession(serverUrl: string, token: string): Promise<KioskSessionResponse> {
return request<KioskSessionResponse>(serverUrl, "/api/kiosk/session", { token });
}
export function fetchLayout(serverUrl: string, token: string): Promise<KioskLayout> {
return request<KioskLayout>(serverUrl, "/api/kiosk/layout", { token });
}
export function sendHeartbeat(
serverUrl: string,
token: string,
metrics: unknown
): Promise<void> {
return request<void>(serverUrl, "/api/kiosk/heartbeat", {
method: "POST",
token,
body: { metrics }
});
}