Created
May 3, 2025 13:57
-
-
Save shripadk/f1b28cb92b00b7ac45625d211fa5f7c8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let host = window.location.hostname; | |
// --- Exponential Backoff Configuration --- | |
const baseRetryDelay = 1000; // Initial delay: 1 second | |
const maxRetryDelay = 30000; // Maximum delay: 30 seconds | |
let currentRetryDelay = baseRetryDelay; | |
let reconnectTimerId = null; // To hold the setTimeout ID | |
function connect() { | |
// Clear any pending reconnect timer if connect is called manually or rapidly | |
if (reconnectTimerId) { | |
clearTimeout(reconnectTimerId); | |
reconnectTimerId = null; | |
} | |
// Ensure protocol and reload_port are defined before attempting connection | |
if (typeof protocol === 'undefined' || typeof reload_port === 'undefined') { | |
console.error("Live Reload Error: 'protocol' or 'reload_port' is not defined."); | |
// Optional: Implement a fallback or stop trying if config is missing | |
// For now, we'll log the error and let the backoff handle retries, | |
// though they will likely fail until config is fixed. | |
} | |
let wsUrl = `${protocol}${host}:${reload_port}/live_reload`; | |
console.log(`Attempting to connect to ${wsUrl}...`); | |
let ws = new WebSocket(wsUrl); | |
ws.onopen = () => { | |
console.log('Hot-reload connection established.'); | |
// Reset retry delay on successful connection | |
currentRetryDelay = baseRetryDelay; | |
}; | |
ws.onmessage = (ev) => { | |
try { | |
let msg = JSON.parse(ev.data); | |
if (msg.css) { | |
let found = false; | |
document.querySelectorAll("link").forEach((link) => { | |
if (link.getAttribute('href').includes(msg.css)) { | |
let newHref = '/' + msg.css + '?version=' + new Date().getMilliseconds(); | |
link.setAttribute('href', newHref); | |
found = true; | |
} | |
}); | |
if (!found) console.warn(`CSS hot-reload: Could not find a <link href=/\"${msg.css}\"> element`); | |
} | |
if(msg.view) { | |
patch(msg.view); | |
if (msg.view.search("SetAttribute") !== -1 && msg.view.search("class") !== -1) { | |
// Tailwind typically takes few milliseconds to less than a second | |
// to generate output styles. So waiting 1 second before replacing | |
// stylesheet seems fine for now. But need a more robust solution | |
// later. Perhaps track mtime of CSS file and use that for notification? | |
setTimeout(() => { | |
let link = document.querySelector("#leptos"); | |
let href = link.href; | |
link.remove(); | |
link = document.createElement("link"); | |
link.setAttribute("id", "leptos"); | |
link.setAttribute("rel", "stylesheet"); | |
link.href = href; | |
document.head.appendChild(link); | |
}, 1000); | |
} | |
} | |
} catch (e) { | |
console.error("Error processing live-reload message:", e); | |
} | |
}; | |
ws.onerror = (error) => { | |
// Log WebSocket errors (e.g., connection refused) | |
console.error('WebSocket Error:', error); | |
// Note: 'onerror' is usually followed by 'onclose', so backoff logic is handled there. | |
}; | |
ws.onclose = (event) => { | |
// event.code provides reason for closure (e.g., 1006 for abnormal closure) | |
console.warn(`Live-reload connection closed (Code: ${event.code}). Reconnecting in ${currentRetryDelay / 1000} seconds...`); | |
// Schedule the next connection attempt with the current delay | |
reconnectTimerId = setTimeout(connect, currentRetryDelay); | |
// Calculate the next delay for the *subsequent* attempt (exponential backoff) | |
currentRetryDelay = Math.min(currentRetryDelay * 2, maxRetryDelay); | |
}; | |
} | |
// --- Initial Connection Attempt --- | |
// Make sure 'protocol' and 'reload_port' are defined before the first call | |
if (typeof protocol !== 'undefined' && typeof reload_port !== 'undefined') { | |
connect(); | |
} else { | |
console.error("Live Reload disabled: 'protocol' or 'reload_port' is not defined globally."); | |
// Optionally, you could try to define defaults here if appropriate | |
// protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://'; | |
// reload_port = 3001; // Example default | |
// connect(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment