/** * Game Processor * * Fetches and processes archive.org game HTML for embedding in MCP Apps. * Uses for relative URL resolution, * and rewrites ES module import() calls to classic `, ); } // Convert inline ES module scripts to classic scripts html = convertModuleScripts(html); // Fetch the emulation script server-side and serve from local endpoint html = await rewriteEmulationScript(html, serverPort); return html; } /** * Fetches emulation.min.js server-side, rewrites import() → loadScript(), * caches it, and points the HTML `); } catch { // If fetch fails, leave the original script tag } return html; } /** * Converts ES module scripts to classic scripts and rewrites inline * import() calls to use window.loadScript(). */ function convertModuleScripts(html: string): string { return html.replace( /(]*>)([\s\S]*?)(<\/script[^>]*>)/gi, (match, openTag: string, content: string, closeTag: string) => { // Skip our injected scripts if (content.includes("window.loadScript")) return match; // Remove type="module" const newOpenTag = openTag.replace(/\s*type\s*=\s*["']module["']/gi, ""); // Rewrite dynamic import() to loadScript() let newContent = content.replace( /import\s*\(\s*(["'`])([^"'`]+)\1\s*\)/g, (_m: string, quote: string, path: string) => { if (path.startsWith("http://") || path.startsWith("https://")) return _m; return `window.loadScript(${quote}${path}${quote})`; }, ); // Convert static import statements newContent = newContent.replace( /import\s+(\{[^}]*\}|[^"']+)\s+from\s+(["'])([^"']+)\2/g, (_m: string, _imports: string, quote: string, path: string) => { if (path.startsWith("http://") || path.startsWith("https://")) return _m; return `window.loadScript(${quote}${path}${quote})`; }, ); return newOpenTag + newContent + closeTag; }, ); }