87 lines
2.2 KiB
JavaScript
87 lines
2.2 KiB
JavaScript
var WebSocketServer = require('ws').Server
|
|
var log = require('bole')('budo')
|
|
var path = require('path')
|
|
var isAbsolute = require('path-is-absolute')
|
|
var color = require('term-color')
|
|
|
|
module.exports = function (server, opts) {
|
|
opts = opts || {}
|
|
log.info({ message: 'LiveReload running' })
|
|
|
|
// get a list of static folders to use as base dirs
|
|
var cwd = path.resolve(opts.cwd || process.cwd())
|
|
var staticDirs = Array.isArray(opts.dir) ? opts.dir : [ opts.dir ]
|
|
staticDirs = staticDirs.map(function (dir) {
|
|
return path.resolve(dir)
|
|
})
|
|
if (staticDirs.indexOf(cwd) === -1) staticDirs.push(cwd)
|
|
|
|
var closed = false
|
|
var wss = new WebSocketServer({
|
|
server: server,
|
|
perMessageDeflate: false
|
|
})
|
|
|
|
return {
|
|
webSocketServer: wss,
|
|
reload: reload,
|
|
errorPopup: errorPopup,
|
|
close: function () {
|
|
if (closed) return
|
|
wss.close()
|
|
closed = true
|
|
}
|
|
}
|
|
|
|
function errorPopup (message) {
|
|
message = message || ''
|
|
broadcast({ event: 'error-popup', message: message })
|
|
}
|
|
|
|
function reload (file) {
|
|
if (closed) return
|
|
var url, ext
|
|
|
|
if (file && typeof file === 'string') {
|
|
// absolute file path
|
|
file = isAbsolute(file) ? path.normalize(file) : path.resolve(cwd, file)
|
|
|
|
// make it relative, removing the static folder parts
|
|
for (var i = 0; i < staticDirs.length; i++) {
|
|
var dir = staticDirs[i]
|
|
url = path.relative(dir, file)
|
|
// if the path doesn't starts with "../", then
|
|
// it should be relative to this folder
|
|
if (!/^(\.\.[/\\]|[/\\])/.test(url)) break
|
|
}
|
|
|
|
// turn it into a URL
|
|
url = url.replace(/\\/g, '/')
|
|
|
|
// ensure it starts at root of app
|
|
if (url.charAt(0) !== '/') url = '/' + url
|
|
|
|
ext = path.extname(file)
|
|
}
|
|
|
|
broadcast({ event: 'reload', ext: ext, url: url })
|
|
}
|
|
|
|
function broadcast (data) {
|
|
if (closed) return
|
|
data = JSON.stringify(data)
|
|
try {
|
|
wss.clients.forEach(function (client) {
|
|
if (client.readyState === client.OPEN) {
|
|
client.send(data, {
|
|
binary: false
|
|
})
|
|
}
|
|
})
|
|
} catch (err) {
|
|
console.error(color.red('ERROR'), 'Error sending LiveReload event to client:')
|
|
console.error(err)
|
|
}
|
|
}
|
|
}
|