Constant HMR_CLIENT_SCRIPT

Source
pub const HMR_CLIENT_SCRIPT: &str = "// HMR client-side script for Orbit Framework\n// This is injected into HTML during development to enable hot module reloading\n\n(function() {\n    // Configuration\n    const config = {\n        reconnectInterval: 2000,  // Reconnection interval in ms\n        reconnectMaxAttempts: 10,\n        debug: true\n    };\n\n    // HMR state\n    let socket = null;\n    let reconnectAttempts = 0;\n    let isConnected = false;\n\n    // Create a logger that respects the debug setting\n    const log = {\n        info: (message) => {\n            if (config.debug) console.info(`[Orbit HMR] ${message}`);\n        },\n        warn: (message) => {\n            if (config.debug) console.warn(`[Orbit HMR] ${message}`);\n        },\n        error: (message) => {\n            if (config.debug) console.error(`[Orbit HMR] ${message}`);\n        }\n    };\n\n    // Initialize the HMR system\n    function init() {\n        log.info(\"Initializing HMR system\");\n        \n        // Connect to the WebSocket server\n        const protocol = window.location.protocol === \'https:\' ? \'wss:\' : \'ws:\';\n        const port = parseInt(window.location.port) + 1; // WebSocket server port\n        const wsUrl = `${protocol}//${window.location.hostname}:${port}`;\n        \n        connectWebSocket(wsUrl);\n        \n        // Listen for page unload to close the socket\n        window.addEventListener(\'beforeunload\', () => {\n            if (socket && socket.readyState === WebSocket.OPEN) {\n                socket.close();\n            }\n        });\n    }\n\n    // Connect to the WebSocket server\n    function connectWebSocket(url) {\n        if (socket) {\n            socket.close();\n        }\n\n        try {\n            log.info(`Connecting to WebSocket server: ${url}`);\n            socket = new WebSocket(url);\n\n            socket.onopen = () => {\n                log.info(\'WebSocket connection established\');\n                isConnected = true;\n                reconnectAttempts = 0;\n                \n                // Register the client\n                socket.send(JSON.stringify({\n                    type: \'register\',\n                    url: window.location.pathname\n                }));\n            };\n\n            socket.onclose = () => {\n                log.info(\'WebSocket connection closed\');\n                isConnected = false;\n                attemptReconnect(url);\n            };\n\n            socket.onerror = (error) => {\n                log.error(`WebSocket error: ${error}`);\n                isConnected = false;\n            };\n\n            socket.onmessage = (event) => {\n                handleMessage(event.data);\n            };\n        } catch (error) {\n            log.error(`Failed to connect to WebSocket: ${error}`);\n            attemptReconnect(url);\n        }\n    }\n\n    // Handle incoming WebSocket messages\n    function handleMessage(data) {\n        try {\n            const message = JSON.parse(data);\n            \n            switch (message.type) {\n                case \'fileChange\':\n                    log.info(`File change detected: ${message.paths.join(\', \')}`);\n                    break;\n                    \n                case \'rebuild\':\n                    handleRebuild(message);\n                    break;\n                    \n                case \'hmr\':\n                    handleHmrUpdate(message);\n                    break;\n                    \n                default:\n                    log.warn(`Unknown message type: ${message.type}`);\n            }\n        } catch (error) {\n            log.error(`Error handling message: ${error}`);\n        }\n    }\n\n    // Handle rebuild messages\n    function handleRebuild(message) {\n        const statusIndicator = document.getElementById(\'orbit-hmr-status\') || \n            createStatusIndicator();\n        \n        if (message.status === \'started\') {\n            log.info(\'Project rebuild started\');\n            statusIndicator.textContent = \'Rebuilding...\';\n            statusIndicator.className = \'orbit-hmr-status rebuilding\';\n        }\n        else if (message.status === \'completed\') {\n            log.info(\'Project rebuild completed successfully\');\n            statusIndicator.textContent = \'Rebuild successful\';\n            statusIndicator.className = \'orbit-hmr-status success\';\n            \n            // Hide the indicator after a delay\n            setTimeout(() => {\n                statusIndicator.className = \'orbit-hmr-status hidden\';\n            }, 3000);\n        }\n        else if (message.status === \'failed\') {\n            log.error(\'Project rebuild failed\');\n            statusIndicator.textContent = \'Rebuild failed\';\n            statusIndicator.className = \'orbit-hmr-status error\';\n        }\n    }    // Handle HMR updates\n    function handleHmrUpdate(message) {\n        log.info(`HMR update for modules: ${message.modules.join(\', \')}`);\n        \n        // Create a status indicator to show HMR activity\n        const statusIndicator = document.getElementById(\'orbit-hmr-status\') || \n            createStatusIndicator();\n        \n        statusIndicator.textContent = \'Applying HMR updates...\';\n        statusIndicator.className = \'orbit-hmr-status rebuilding\';\n        \n        try {\n            // Apply HMR updates - the actual implementation depends on your framework\n            if (window.__ORBIT_APPLY_HMR) {\n                const result = window.__ORBIT_APPLY_HMR(message.modules);\n                \n                // Handle Promise or direct result\n                if (result instanceof Promise) {\n                    result.then(() => {\n                        statusIndicator.textContent = \'HMR update successful\';\n                        statusIndicator.className = \'orbit-hmr-status success\';\n                        setTimeout(() => {\n                            statusIndicator.className = \'orbit-hmr-status hidden\';\n                        }, 3000);\n                    }).catch((error) => {\n                        log.error(`HMR update failed: ${error}`);\n                        statusIndicator.textContent = \'HMR failed, reloading page...\';\n                        statusIndicator.className = \'orbit-hmr-status error\';\n                        setTimeout(() => {\n                            window.location.reload();\n                        }, 1000);\n                    });\n                } else {\n                    statusIndicator.textContent = \'HMR update successful\';\n                    statusIndicator.className = \'orbit-hmr-status success\';\n                    setTimeout(() => {\n                        statusIndicator.className = \'orbit-hmr-status hidden\';\n                    }, 3000);\n                }\n            } else {\n                // If no HMR handler is registered, perform a full reload\n                log.warn(\'No HMR handler registered, performing full page reload\');\n                statusIndicator.textContent = \'No HMR handler, reloading page...\';\n                statusIndicator.className = \'orbit-hmr-status rebuilding\';\n                setTimeout(() => {\n                    window.location.reload();\n                }, 500);\n            }\n        } catch (error) {\n            log.error(`Error during HMR update: ${error}`);\n            statusIndicator.textContent = \'HMR error, reloading page...\';\n            statusIndicator.className = \'orbit-hmr-status error\';\n            setTimeout(() => {\n                window.location.reload();\n            }, 1000);\n        }\n    }\n\n    // Create a status indicator element\n    function createStatusIndicator() {\n        const indicator = document.createElement(\'div\');\n        indicator.id = \'orbit-hmr-status\';\n        indicator.className = \'orbit-hmr-status hidden\';\n        \n        const style = document.createElement(\'style\');\n        style.textContent = `\n            .orbit-hmr-status {\n                position: fixed;\n                bottom: 20px;\n                right: 20px;\n                padding: 8px 12px;\n                border-radius: 4px;\n                font-family: sans-serif;\n                font-size: 14px;\n                z-index: 9999;\n                transition: opacity 0.3s ease;\n                color: white;\n                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n            }\n            .orbit-hmr-status.hidden {\n                opacity: 0;\n                pointer-events: none;\n            }\n            .orbit-hmr-status.rebuilding {\n                background-color: #f39c12;\n            }\n            .orbit-hmr-status.success {\n                background-color: #2ecc71;\n            }\n            .orbit-hmr-status.error {\n                background-color: #e74c3c;\n            }\n        `;\n        \n        document.head.appendChild(style);\n        document.body.appendChild(indicator);\n        return indicator;\n    }\n\n    // Attempt to reconnect to the WebSocket server\n    function attemptReconnect(url) {\n        if (reconnectAttempts >= config.reconnectMaxAttempts) {\n            log.error(\'Maximum reconnection attempts reached\');\n            return;\n        }\n        \n        reconnectAttempts++;\n        \n        const delay = config.reconnectInterval;\n        log.info(`Attempting to reconnect in ${delay}ms (attempt ${reconnectAttempts}/${config.reconnectMaxAttempts})`);\n        \n        setTimeout(() => {\n            connectWebSocket(url);\n        }, delay);\n    }\n\n    // Register an HMR update handler\n    window.__ORBIT_REGISTER_HMR_HANDLER = function(handler) {\n        window.__ORBIT_APPLY_HMR = handler;\n        log.info(\'HMR handler registered\');\n    };\n\n    // Initialize on page load\n    if (document.readyState === \'complete\') {\n        init();\n    } else {\n        window.addEventListener(\'load\', init);\n    }\n})();\n";
Expand description

The HMR client script as a static string