// file: Web/game-snake-poc/frontend/ts/main.ts // version: 3 import ResizeObserver from "resize-observer-polyfill"; import "simplebar"; import { loadSnakeWebAssets } from "./assets"; import { startGame } from "./game"; import { bindInputs } from "./input"; import { bindBrowserLifecycle } from "./lifecycle"; import { webError, webInfo } from "./logging"; (window as Window & typeof globalThis & { ResizeObserver?: typeof ResizeObserver }).ResizeObserver = ResizeObserver; function requireElement(selector: string): T { const element = document.querySelector(selector); if (element === null) { throw new Error(`Élément frontend requis absent : ${selector}`); } return element; } async function main(): Promise { const canvas = requireElement("#game"); const stage = requireElement(".game-stage"); const score = requireElement("#score"); const length = requireElement("#length"); const provenance = requireElement("#runtime-provenance"); const assets = requireElement("#asset-status"); const status = requireElement("#runtime-status"); const error = requireElement("#startup-error"); const buttons = Array.from(document.querySelectorAll("[data-direction]")); status.textContent = "Chargement assets…"; const assetMetadata = await loadSnakeWebAssets(); assets.value = `${assetMetadata.gameKind} / engine-v${assetMetadata.engineGeneration}`; webInfo("snake-web-assets", "runtime_assets_loaded", { engineGeneration: assetMetadata.engineGeneration, game: assetMetadata.game, gameKind: assetMetadata.gameKind, }); status.textContent = "Chargement WASM…"; const session = await startGame(canvas, score, length, provenance); bindInputs(session, buttons); bindBrowserLifecycle(session, stage); status.className = "badge text-bg-success"; status.textContent = "Prêt"; error.hidden = true; canvas.focus(); webInfo("snake-web-main", "runtime_ready"); } void main().catch(caughtError => { const status = document.querySelector("#runtime-status"); const error = document.querySelector("#startup-error"); const message = caughtError instanceof Error ? caughtError.stack ?? caughtError.message : String(caughtError); if (status !== null) { status.className = "badge text-bg-danger"; status.textContent = "Erreur"; } if (error !== null) { error.textContent = `Impossible de démarrer Snake : ${message}`; error.hidden = false; } webError("snake-web-main", "runtime_start_failed", { message }); });