2021-10-15 09:09:54 +02:00
|
|
|
let source: WebSocket
|
|
|
|
const eventCallbacks: ((event: any) => void)[] = []
|
|
|
|
let lastActivity = Date.now()
|
|
|
|
|
2021-11-09 22:26:55 +01:00
|
|
|
function getSocketProtocol(assetPrefix: string): string {
|
|
|
|
let protocol = location.protocol
|
|
|
|
|
|
|
|
try {
|
|
|
|
// assetPrefix is a url
|
|
|
|
protocol = new URL(assetPrefix).protocol
|
|
|
|
} catch (_) {}
|
|
|
|
|
|
|
|
return protocol === 'http:' ? 'ws' : 'wss'
|
|
|
|
}
|
|
|
|
|
2021-10-15 09:09:54 +02:00
|
|
|
export function addMessageListener(cb: (event: any) => void) {
|
|
|
|
eventCallbacks.push(cb)
|
|
|
|
}
|
|
|
|
|
|
|
|
export function sendMessage(data: any) {
|
|
|
|
if (!source || source.readyState !== source.OPEN) return
|
|
|
|
return source.send(data)
|
|
|
|
}
|
|
|
|
|
|
|
|
export function connectHMR(options: {
|
|
|
|
path: string
|
2021-11-04 10:34:37 +01:00
|
|
|
assetPrefix: string
|
2021-10-15 09:09:54 +02:00
|
|
|
timeout: number
|
|
|
|
log?: boolean
|
|
|
|
}) {
|
|
|
|
if (!options.timeout) {
|
|
|
|
options.timeout = 5 * 1000
|
|
|
|
}
|
|
|
|
|
2022-08-15 16:29:51 +02:00
|
|
|
function init() {
|
|
|
|
if (source) source.close()
|
2021-10-15 09:09:54 +02:00
|
|
|
|
2022-08-15 16:29:51 +02:00
|
|
|
function handleOnline() {
|
|
|
|
if (options.log) console.log('[HMR] connected')
|
|
|
|
lastActivity = Date.now()
|
2021-10-15 09:09:54 +02:00
|
|
|
}
|
|
|
|
|
2022-08-15 16:29:51 +02:00
|
|
|
function handleMessage(event: any) {
|
|
|
|
lastActivity = Date.now()
|
|
|
|
|
|
|
|
eventCallbacks.forEach((cb) => {
|
|
|
|
cb(event)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
let timer: NodeJS.Timeout
|
|
|
|
function handleDisconnect() {
|
|
|
|
clearInterval(timer)
|
|
|
|
source.close()
|
|
|
|
setTimeout(init, options.timeout)
|
|
|
|
}
|
|
|
|
timer = setInterval(function () {
|
|
|
|
if (Date.now() - lastActivity > options.timeout) {
|
|
|
|
handleDisconnect()
|
|
|
|
}
|
|
|
|
}, options.timeout / 2)
|
|
|
|
|
2021-11-04 10:34:37 +01:00
|
|
|
const { hostname, port } = location
|
2021-11-09 22:26:55 +01:00
|
|
|
const protocol = getSocketProtocol(options.assetPrefix || '')
|
2021-11-04 10:34:37 +01:00
|
|
|
const assetPrefix = options.assetPrefix.replace(/^\/+/, '')
|
|
|
|
|
|
|
|
let url = `${protocol}://${hostname}:${port}${
|
|
|
|
assetPrefix ? `/${assetPrefix}` : ''
|
|
|
|
}`
|
|
|
|
|
|
|
|
if (assetPrefix.startsWith('http')) {
|
|
|
|
url = `${protocol}://${assetPrefix.split('://')[1]}`
|
|
|
|
}
|
|
|
|
|
2021-10-15 09:09:54 +02:00
|
|
|
source = new window.WebSocket(`${url}${options.path}`)
|
|
|
|
source.onopen = handleOnline
|
|
|
|
source.onerror = handleDisconnect
|
|
|
|
source.onmessage = handleMessage
|
|
|
|
}
|
|
|
|
|
2022-08-15 16:29:51 +02:00
|
|
|
init()
|
2021-10-15 09:09:54 +02:00
|
|
|
}
|