diff options
Diffstat (limited to 'packages/web-util/src/serve.ts')
-rw-r--r-- | packages/web-util/src/serve.ts | 167 |
1 files changed, 81 insertions, 86 deletions
diff --git a/packages/web-util/src/serve.ts b/packages/web-util/src/serve.ts index f37ef90ce..93d8082fe 100644 --- a/packages/web-util/src/serve.ts +++ b/packages/web-util/src/serve.ts @@ -21,7 +21,6 @@ const logger = new Logger("serve.ts"); const PATHS = { WS: "/ws", - NOTIFY: "/notify", EXAMPLE: "/examples", APP: "/app", }; @@ -30,101 +29,97 @@ export async function serve(opts: { folder: string; port: number; source?: string; - development?: boolean; examplesLocationJs?: string; examplesLocationCss?: string; - onUpdate?: () => Promise<void>; + onSourceUpdate?: () => Promise<void>; }): Promise<void> { const app = express(); app.use(PATHS.APP, express.static(opts.folder)); - const servers = [ - http.createServer(app), - https.createServer(httpServerOptions, app), - ]; - logger.info(` ${PATHS.APP}: application`); - logger.info(` ${PATHS.EXAMPLE}: examples`); - logger.info(` ${PATHS.WS}: websocket`); - logger.info(` ${PATHS.NOTIFY}: broadcast`); - - if (opts.development) { - const wss = new WebSocket.Server({ noServer: true }); - - wss.on("connection", function connection(ws) { - ws.send("welcome"); - }); - - servers.forEach(function addWSHandler(server) { - server.on("upgrade", function upgrade(request, socket, head) { - const { pathname } = parse(request.url || ""); - if (pathname === PATHS.WS) { - wss.handleUpgrade(request, socket, head, function done(ws) { - wss.emit("connection", ws, request); - }); - } else { - socket.destroy(); - } - }); - }); - const sendToAllClients = function (data: object): void { - wss.clients.forEach(function each(client) { - if (client.readyState === WebSocket.OPEN) { - client.send(JSON.stringify(data)); - } - }); - }; - const watchingFolder = opts.source ?? opts.folder; - logger.info(`watching ${watchingFolder} for change`); - - chokidar.watch(watchingFolder).on("change", (path, stats) => { - logger.info(`changed ${path}`); - - if (opts.onUpdate) { - sendToAllClients({ type: "file-updated-start", data: { path } }); - opts - .onUpdate() - .then((result) => { - sendToAllClients({ - type: "file-updated-done", - data: { path, result }, - }); - }) - .catch((error) => { - sendToAllClients({ - type: "file-updated-failed", - data: { path, error }, - }); - }); + const httpServer = http.createServer(app); + const httpPort = opts.port; + const httpsServer = https.createServer(httpServerOptions, app); + const httpsPort = opts.port + 1; + const servers = [httpServer, httpsServer]; + + logger.info(`Dev server. Endpoints:`); + logger.info(` ${PATHS.APP}: where root application can be tested`); + logger.info(` ${PATHS.EXAMPLE}: where examples can be found and browse`); + logger.info(` ${PATHS.WS}: websocket for live reloading`); + + const wss = new WebSocket.Server({ noServer: true }); + + wss.on("connection", function connection(ws) { + ws.send("welcome"); + }); + + servers.forEach(function addWSHandler(server) { + server.on("upgrade", function upgrade(request, socket, head) { + const { pathname } = parse(request.url || ""); + if (pathname === PATHS.WS) { + wss.handleUpgrade(request, socket, head, function done(ws) { + wss.emit("connection", ws, request); + }); } else { - sendToAllClients({ type: "file-change", data: { path } }); + socket.destroy(); } }); + }); - if (opts.onUpdate) opts.onUpdate(); - - app.get(PATHS.EXAMPLE, function (req: any, res: any) { - res.set("Content-Type", "text/html"); - res.send( - storiesHtml - .replace( - "__EXAMPLES_JS_FILE_LOCATION__", - opts.examplesLocationJs ?? `.${PATHS.APP}/stories.js`, - ) - .replace( - "__EXAMPLES_CSS_FILE_LOCATION__", - opts.examplesLocationCss ?? `.${PATHS.APP}/stories.css`, - ), - ); - }); - - app.get(PATHS.NOTIFY, function (req: any, res: any) { - res.send("ok"); - }); - - servers.forEach(function startServer(server, index) { - logger.info(`serving ${opts.folder} on ${opts.port + index}`); - server.listen(opts.port + index); + const sendToAllClients = function (data: object): void { + wss.clients.forEach(function each(client) { + if (client.readyState === WebSocket.OPEN) { + client.send(JSON.stringify(data)); + } }); - } + }; + const watchingFolder = opts.source ?? opts.folder; + logger.info(`watching ${watchingFolder} for changes`); + + chokidar.watch(watchingFolder).on("change", (path, stats) => { + logger.info(`changed: ${path}`); + + if (opts.onSourceUpdate) { + sendToAllClients({ type: "file-updated-start", data: { path } }); + opts + .onSourceUpdate() + .then((result) => { + sendToAllClients({ + type: "file-updated-done", + data: { path, result }, + }); + }) + .catch((error) => { + sendToAllClients({ + type: "file-updated-failed", + data: { path, error }, + }); + }); + } else { + sendToAllClients({ type: "file-change", data: { path } }); + } + }); + + if (opts.onSourceUpdate) opts.onSourceUpdate(); + + app.get(PATHS.EXAMPLE, function (req: any, res: any) { + res.set("Content-Type", "text/html"); + res.send( + storiesHtml + .replace( + "__EXAMPLES_JS_FILE_LOCATION__", + opts.examplesLocationJs ?? `.${PATHS.APP}/stories.js`, + ) + .replace( + "__EXAMPLES_CSS_FILE_LOCATION__", + opts.examplesLocationCss ?? `.${PATHS.APP}/stories.css`, + ), + ); + }); + + logger.info(`Serving ${opts.folder} on ${httpPort}: plain HTTP`); + httpServer.listen(httpPort); + logger.info(`Serving ${opts.folder} on ${httpsPort}: HTTP + TLS`); + httpsServer.listen(httpsPort); } |