collab/mermaid/.esbuild/server.tsblame
View source
6dd74de1/* eslint-disable no-console */
6dd74de2import chokidar from 'chokidar';
6dd74de3import cors from 'cors';
6dd74de4import { context } from 'esbuild';
6dd74de5import type { Request, Response } from 'express';
6dd74de6import express from 'express';
6dd74de7import { packageOptions } from '../.build/common.js';
6dd74de8import { generateLangium } from '../.build/generateLangium.js';
6dd74de9import { defaultOptions, getBuildConfig } from './util.js';
6dd74de10import 'dotenv/config';
6dd74de11
6dd74de12const configs = Object.values(packageOptions).map(({ packageName }) =>
6dd74de13 getBuildConfig({
6dd74de14 ...defaultOptions,
6dd74de15 minify: false,
6dd74de16 core: false,
6dd74de17 options: packageOptions[packageName],
6dd74de18 })
6dd74de19);
6dd74de20const mermaidIIFEConfig = getBuildConfig({
6dd74de21 ...defaultOptions,
6dd74de22 minify: false,
6dd74de23 core: false,
6dd74de24 options: packageOptions.mermaid,
6dd74de25 format: 'iife',
6dd74de26});
6dd74de27configs.push(mermaidIIFEConfig);
6dd74de28
6dd74de29const contexts = await Promise.all(
6dd74de30 configs.map(async (config) => ({ config, context: await context(config) }))
6dd74de31);
6dd74de32
6dd74de33let rebuildCounter = 1;
6dd74de34const rebuildAll = async () => {
6dd74de35 const buildNumber = rebuildCounter++;
6dd74de36 const timeLabel = `Rebuild ${buildNumber} Time (total)`;
6dd74de37 console.time(timeLabel);
6dd74de38 await Promise.all(
6dd74de39 contexts.map(async ({ config, context }) => {
6dd74de40 const buildVariant = `Rebuild ${buildNumber} Time (${Object.keys(config.entryPoints!)[0]} ${config.format})`;
6dd74de41 console.time(buildVariant);
6dd74de42 await context.rebuild();
6dd74de43 console.timeEnd(buildVariant);
6dd74de44 })
6dd74de45 ).catch((e) => console.error(e));
6dd74de46 console.timeEnd(timeLabel);
6dd74de47};
6dd74de48
6dd74de49let clients: { id: number; response: Response }[] = [];
6dd74de50function eventsHandler(request: Request, response: Response) {
6dd74de51 const headers = {
6dd74de52 'Content-Type': 'text/event-stream',
6dd74de53 Connection: 'keep-alive',
6dd74de54 'Cache-Control': 'no-cache',
6dd74de55 };
6dd74de56 response.writeHead(200, headers);
6dd74de57 const clientId = Date.now();
6dd74de58 clients.push({
6dd74de59 id: clientId,
6dd74de60 response,
6dd74de61 });
6dd74de62 request.on('close', () => {
6dd74de63 clients = clients.filter((client) => client.id !== clientId);
6dd74de64 });
6dd74de65}
6dd74de66
6dd74de67let timeoutID: NodeJS.Timeout | undefined = undefined;
6dd74de68
6dd74de69/**
6dd74de70 * Debounce file change events to avoid rebuilding multiple times.
6dd74de71 */
6dd74de72function handleFileChange() {
6dd74de73 if (timeoutID !== undefined) {
6dd74de74 clearTimeout(timeoutID);
6dd74de75 }
6dd74de76 // eslint-disable-next-line @typescript-eslint/no-misused-promises
6dd74de77 timeoutID = setTimeout(async () => {
6dd74de78 await rebuildAll();
6dd74de79 sendEventsToAll();
6dd74de80 timeoutID = undefined;
6dd74de81 }, 100);
6dd74de82}
6dd74de83
6dd74de84function sendEventsToAll() {
6dd74de85 clients.forEach(({ response }) => response.write(`data: ${Date.now()}\n\n`));
6dd74de86}
6dd74de87
6dd74de88async function createServer() {
6dd74de89 await generateLangium();
6dd74de90 handleFileChange();
6dd74de91 const app = express();
6dd74de92 const port = process.env.MERMAID_PORT ?? 9000;
6dd74de93 chokidar
6dd74de94 .watch('**/src/**/*.{js,ts,langium,yaml,json}', {
6dd74de95 ignoreInitial: true,
6dd74de96 ignored: [/node_modules/, /dist/, /docs/, /coverage/],
6dd74de97 })
6dd74de98 // eslint-disable-next-line @typescript-eslint/no-misused-promises
6dd74de99 .on('all', async (event, path) => {
6dd74de100 // Ignore other events.
6dd74de101 if (!['add', 'change'].includes(event)) {
6dd74de102 return;
6dd74de103 }
6dd74de104 console.log(`${path} changed. Rebuilding...`);
6dd74de105 if (path.endsWith('.langium')) {
6dd74de106 await generateLangium();
6dd74de107 }
6dd74de108 handleFileChange();
6dd74de109 });
6dd74de110
6dd74de111 app.use(cors());
6dd74de112 app.get('/events', eventsHandler);
6dd74de113 for (const { packageName } of Object.values(packageOptions)) {
6dd74de114 app.use(express.static(`./packages/${packageName}/dist`));
6dd74de115 }
6dd74de116 app.use(express.static('demos'));
6dd74de117 app.use(express.static('cypress/platform'));
6dd74de118
6dd74de119 app.listen(port, () => {
6dd74de120 console.log(`Listening on http://localhost:${port}`);
6dd74de121 });
6dd74de122}
6dd74de123
6dd74de124void createServer();