import React, { Suspense, lazy } from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; // One SPA, served from every *.amerc.ai docroot; pick the app by hostname. const host = window.location.hostname; const DocsApp = lazy(() => import('./DocsApp.jsx')); const PmApp = lazy(() => import('./PmApp.jsx')); const Scene2DApp = lazy(() => import('./Scene2D.jsx')); let App = Scene2DApp; if (host.startsWith('docs.')) { App = DocsApp; document.title = 'Docs · amerc'; } else if (host.startsWith('pm.')) { App = PmApp; document.title = 'PM · amerc'; } // Preload the tavern's canvas tiles on the main domain so the scene paints as // soon as the app mounts — they download in parallel with the JS chunk instead // of only after TavernGame runs. Not needed on docs/pm. if (App === Scene2DApp) { for (const n of ['inside', 'castlefloors', 'victoria', 'barrel', 'princess', 'soldier', 'soldier_altcolor']) { const im = new Image(); im.src = `/scene2d/lpc/${n}.png`; } } // Catch render errors so a single bad component can't blank the whole app. class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { error: null }; } static getDerivedStateFromError(error) { return { error }; } render() { if (this.state.error) { return (
); } return this.props.children; } } const Loading = () => (
); createRoot(document.getElementById('root')).render( }> , ); // Progressive Web App: register the service worker on production amerc.ai hosts only // (skip the Vite dev server so HMR keeps working). if ('serviceWorker' in navigator && host.endsWith('amerc.ai')) { window.addEventListener('load', () => { navigator.serviceWorker.register('/sw.js').catch(() => {}); }); }