// file: crates/apps/game-snake-poc-tauri/frontend/ts/main.ts // version: 2 import "../css/main.css"; import { loadSnakeTauriAssets } from "./assets"; import { getRuntimeDescriptor, reportFrontendReady } from "./bridge"; import { startGame } from "./game"; import { bindInputs } from "./input"; import { frontendError, frontendInfo, initializeFrontendTracing } from "./logging"; function requiredElement(identifier: string): T { const element = document.getElementById(identifier); if (element === null) { throw new Error(`Élément frontend requis absent : ${identifier}`); } return element as T; } async function bootstrap(): Promise { await initializeFrontendTracing(); frontendInfo("Snake Tauri frontend bootstrap started"); const descriptor = await getRuntimeDescriptor(); const canvas = requiredElement("game"); const score = requiredElement("score"); const length = requiredElement("length"); const provenance = requiredElement("runtime-provenance"); const assets = requiredElement("asset-status"); const status = requiredElement("runtime-status"); const error = requiredElement("startup-error"); const buttons = Array.from(document.querySelectorAll("[data-direction]")); status.textContent = "Chargement assets…"; const assetMetadata = await loadSnakeTauriAssets(); assets.value = `${assetMetadata.gameKind} / engine-v${assetMetadata.engineGeneration}`; frontendInfo(`Snake Tauri assets ready: ${assetMetadata.game} / ${assets.value}`); status.textContent = "Chargement WASM…"; const session = await startGame(canvas, score, length, provenance, descriptor); bindInputs(session, buttons); window.addEventListener("resize", () => { session.refreshDeviceClass(); session.renderNow(); }); window.addEventListener("pagehide", () => session.dispose(), { once: true }); document.body.dataset.runtimeState = "ready"; status.textContent = "Prêt"; error.hidden = true; canvas.focus(); await reportFrontendReady(); frontendInfo(`Snake Tauri frontend ready: ${provenance.value}`); } void bootstrap().catch(reason => { const message = reason instanceof Error ? reason.stack ?? reason.message : String(reason); document.body.dataset.runtimeState = "error"; const status = document.getElementById("runtime-status"); const error = document.getElementById("startup-error"); if (status !== null) { status.textContent = "Erreur"; } if (error !== null) { error.textContent = `Impossible de démarrer Snake : ${message}`; error.hidden = false; } frontendError(`Snake Tauri frontend bootstrap failed: ${message}`); });