import { useEffect, useMemo, useState, type ReactNode } from 'react' import { GameAPIProvider } from '@/shared/api/GameAPIContext' import { AnalyticsProvider } from '@/shared/analytics' export default function Wrapper({ children }: { children: ReactNode }) { // Determine platform based on build-time define const isDesktop = typeof __DESKTOP__ !== 'undefined' ? __DESKTOP__ : false const [gameAPI, setGameAPI] = useState(null) const [analytics, setAnalytics] = useState(null) // Dynamically import the appropriate platform implementation // Use build-time constant for tree-shaking useEffect(() => { if (__DESKTOP__) { Promise.all([ import('@/desktop/api/tauriAPI'), import('@/desktop/analytics/tauriAnalytics'), ]).then(([{ tauriAPI }, { tauriAnalytics }]) => { setGameAPI(tauriAPI) setAnalytics(tauriAnalytics) }) } else { Promise.all([ import('@/browser/api/wasmBridge'), import('@/browser/analytics'), ]).then(([{ wasmBridge }, { wasmAnalytics }]) => { setGameAPI(wasmBridge) setAnalytics(wasmAnalytics) }) } }, []) // Browser-specific setup (must be before early return to satisfy Rules of Hooks) useEffect(() => { if (!__DESKTOP__) { // Disable context menu to prevent interference with right-click controls const handleContextMenu = (e: MouseEvent) => { e.preventDefault() return false } document.addEventListener('contextmenu', handleContextMenu) // Handle user ID storage from worker const userIdChannel = new BroadcastChannel('user_id_storage') userIdChannel.onmessage = (event) => { try { const msg = JSON.parse(event.data as string) if (msg.action === 'save') { localStorage.setItem('app_session_id', msg.id) } else if (msg.action === 'load') { const id = localStorage.getItem('app_session_id') if (id) { userIdChannel.postMessage(JSON.stringify({ action: 'load_response', id })) } } } catch {} } // Create canvas element for the game renderer const canvas = document.createElement('canvas') canvas.id = 'game-canvas' document.body.appendChild(canvas) return () => { document.removeEventListener('contextmenu', handleContextMenu) userIdChannel.close() if (canvas.parentElement) { canvas.remove() } } } }, []) // Wait for platform-specific modules to load if (!gameAPI || !analytics) { return null } return ( {children} ) }