import { useEffect, useState } from 'react'; /** * Dynamically remounts the Vite virtual live module when the harness changes. */ export function LivePreview() { const [revision, setRevision] = useState(0); const [Comp, setComp] = useState(null); const [error, setError] = useState(null); useEffect(() => { const onUpdate = () => setRevision((n) => n + 1); const handler = () => onUpdate(); // Vite custom event from liveTsxPlugin if (import.meta.hot) { import.meta.hot.on('playground:live-updated', handler); } return () => { if (import.meta.hot) { import.meta.hot.off('playground:live-updated', handler); } }; }, []); useEffect(() => { let cancelled = false; setError(null); setComp(null); import(/* @vite-ignore */ `/@playground/live.tsx?t=${revision}`) .then((mod) => { if (cancelled) return; const candidate = mod.default; if (typeof candidate !== 'function') { setError('Live module must `export default` a React component.'); return; } setComp(() => candidate); }) .catch((err: unknown) => { if (cancelled) return; const message = err instanceof Error ? `${err.message}\n\n${err.stack ?? ''}` : String(err); setError(message); }); return () => { cancelled = true; }; }, [revision]); if (error) return
{error}
; if (!Comp) return
Compiling harness…
; return ; }