Files
launcher/src/lib/backend.ts
T
Kelorastus 4d620fc5ad update
2026-09-23 16:05:19 +02:00

75 lines
3.1 KiB
TypeScript

// The ONLY module that touches Tauri. Everything else talks to `backend`.
// Inside the Tauri webview this is a thin typed wrapper over invoke/listen
// (docs/CONTRACT.md); in a plain browser it is the timer-driven mock.
import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { createMockBackend } from "./mock";
import type {
Backend,
InstallProgress,
LogEvent,
Market,
Settings,
SignInResult,
StackEvent,
Status,
SyncConflict,
Unlisten,
} from "./types";
export const IN_TAURI = typeof window !== "undefined" && "__TAURI_INTERNALS__" in window;
function subscribe<T>(event: string, handler: (payload: T) => void): Promise<Unlisten> {
return listen<T>(event, (e) => handler(e.payload));
}
function createTauriBackend(): Backend {
const win = getCurrentWindow();
return {
kind: "tauri",
mock: null,
window: {
minimize: () => win.minimize(),
toggleMaximize: () => win.toggleMaximize(),
close: () => win.close(),
isMaximized: () => win.isMaximized(),
onResized: (handler) => win.onResized(() => handler()),
},
getStatus: () => invoke<Status>("get_status"),
refresh: () => invoke<Status>("refresh"),
signIn: () => invoke<SignInResult>("sign_in"),
cancelSignIn: () => invoke<void>("cancel_sign_in"),
signOut: () => invoke<Status>("sign_out"),
getNotes: (version) => invoke<string>("get_notes", version === undefined ? {} : { version }),
openExternal: (url) => invoke<void>("open_external", { url }),
getStack: () => invoke<StackEvent[]>("get_stack"),
startInstall: () => invoke<void>("start_install"),
startInstallFromDrive: (path) => invoke<void>("start_install_from_drive", { path }),
getMarket: (drive) => invoke<Market>("get_market", drive === undefined ? {} : { drive }),
applyMarket: (selected) => invoke<void>("apply_market", { selected }),
setMarket: (selected, drive) => invoke<void>("set_market", drive === undefined ? { selected } : { selected, drive }),
cancelInstall: () => invoke<void>("cancel_install"),
launch: () => invoke<void>("launch"),
stop: () => invoke<void>("stop"),
getSettings: () => invoke<Settings>("get_settings"),
setSettings: (settings) => invoke<Status>("set_settings", { settings }),
pickFolder: () => invoke<string | null>("pick_folder"),
syncNow: () => invoke<void>("sync_now"),
getSyncConflicts: () => invoke<SyncConflict[]>("get_sync_conflicts"),
resolveSyncConflict: (tbl, key, choice, value) =>
invoke<SyncConflict[]>("resolve_sync_conflict", { tbl, key, choice, value: value === undefined ? null : value }),
onStatus: (handler) => subscribe<Status>("status", handler),
onInstallProgress: (handler) => subscribe<InstallProgress>("install-progress", handler),
onStack: (handler) => subscribe<StackEvent>("stack", handler),
onLog: (handler) => subscribe<LogEvent>("log", handler),
};
}
export const backend: Backend = IN_TAURI
? createTauriBackend()
: createMockBackend(new URLSearchParams(window.location.search));