import React from 'react'; import ReactDOM from 'react-dom/client'; import { BrowserRouter } from 'react-router-dom'; import { App } from './App'; import { startPendingMessageOrchestrator } from './stores/pendingMessageRehydrate'; import './styles/globals.css'; class ErrorBoundary extends React.Component< { children: React.ReactNode }, { hasError: boolean; error: Error | null; showStack: boolean } > { constructor(props: { children: React.ReactNode }) { super(props); this.state = { hasError: false, error: null, showStack: false }; } static getDerivedStateFromError(error: Error) { return { hasError: true, error }; } componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { console.error('[ErrorBoundary]', error, errorInfo.componentStack); // Renderer is alive enough to show the fallback UI — disarm the boot timer. // Without this, the timer fires 20s after a caught render error and // overrides the in-app error UI with native recovery, which is wrong. // Gated on VITE_FORCE_BOOT_STALL so the smoke harness can suppress both // ping paths simultaneously when testing the renderer-stalled recovery path. if (import.meta.env.VITE_FORCE_BOOT_STALL) return; if (typeof window.backspace?.rendererReady === 'function') { window.backspace.rendererReady(); } } render() { if (this.state.hasError) { return (

Something went wrong

{this.state.error?.message}

{this.state.error?.stack && (
this.setState({ showStack: (e.target as HTMLDetailsElement).open })} style={{ maxWidth: '600px', width: '100%', marginTop: '8px' }} > Error details
                {this.state.error.stack}
              
)}
); } return this.props.children; } } const root = document.getElementById('root'); if (!root) throw new Error('Root element not found'); startPendingMessageOrchestrator(); ReactDOM.createRoot(root).render( );