97 lines
2.6 KiB
TypeScript
97 lines
2.6 KiB
TypeScript
import {Router} from 'express';
|
|
import {DefaultConfig, Logger, urlJoin} from '.';
|
|
import {v4} from 'uuid';
|
|
import Timeout = NodeJS.Timeout;
|
|
|
|
export type ReloaderConfig = {
|
|
// frontend directories to watch
|
|
frontendDirs: string|string[],
|
|
// auto reloader sub path (defaults to '/auto-reload')
|
|
subPath?: string,
|
|
// auto reloader js name (defaults to 'client.js')
|
|
jsName?: string,
|
|
}
|
|
|
|
type IntReloaderConfig = {
|
|
// frontend directories to watch
|
|
frontendDirs: string[],
|
|
// auto reloader sub path (defaults to '/auto-reload')
|
|
subPath: string,
|
|
// auto reloader js name (defaults to 'client.js')
|
|
jsName: string,
|
|
}
|
|
|
|
function getRouter(opts: ReloaderConfig): Router {
|
|
const config: IntReloaderConfig = {
|
|
frontendDirs: Array.isArray(opts.frontendDirs) ? opts.frontendDirs : [opts.frontendDirs],
|
|
subPath: opts.subPath || '/auto-reload',
|
|
jsName: opts.jsName || 'client.js',
|
|
};
|
|
|
|
const router = Router();
|
|
if (!DefaultConfig.isProduction) {
|
|
let uuid = v4();
|
|
let updateTimeout: Timeout|undefined = undefined;
|
|
import('node-watch').then((watch) => {
|
|
for (const frontendDir of config.frontendDirs) {
|
|
watch.default(frontendDir, {recursive: true}, () => {
|
|
if (updateTimeout !== undefined) clearTimeout(updateTimeout);
|
|
updateTimeout = setTimeout(() => {
|
|
uuid = v4();
|
|
}, 200);
|
|
});
|
|
}
|
|
}).catch((err) => { Logger.error(err); });
|
|
|
|
// /auto-reload/client.js
|
|
router.get(urlJoin(config.subPath, config.jsName), (req, res) => {
|
|
Logger.debug(req.url, req.originalUrl, req.baseUrl);
|
|
res.setHeader('Content-Type', 'application/javascript');
|
|
// language=JavaScript
|
|
res.send(`
|
|
const loc = window.location;
|
|
const url = loc.protocol+'//'+loc.host+'${urlJoin(req.baseUrl, config.subPath)}';
|
|
// const parse = async res => (await res.json()).uuid;
|
|
const parse = function(res) {
|
|
return res.json()
|
|
.then(function(json) {return json.uuid;}) }
|
|
let hash = undefined;
|
|
let hadError = false;
|
|
setInterval(function() {
|
|
try {
|
|
fetch(url)
|
|
.then(function(res) { return parse(res) })
|
|
.then(function(data) {
|
|
if (data) {
|
|
hash = hash === undefined ? data : hash;
|
|
if (hash !== data) {
|
|
window.location.reload();
|
|
}
|
|
}
|
|
});
|
|
} catch (e) {
|
|
if (hadError === false) {
|
|
console.log(e);
|
|
hadError = true;
|
|
}
|
|
}
|
|
}, 3000);
|
|
`.replace(/\t/g, ''));
|
|
});
|
|
|
|
// /auto-reload
|
|
router.get(urlJoin(config.subPath), (req, res) => {
|
|
req.noHttpLogging = true;
|
|
res.json({uuid});
|
|
});
|
|
}
|
|
|
|
return router;
|
|
}
|
|
|
|
|
|
|
|
export const AutoReloader = {
|
|
getRouter,
|
|
};
|