mermaid/.esbuild/server.ts

117 lines
3.2 KiB
TypeScript
Raw Normal View History

import express from 'express';
2023-08-13 15:21:02 +02:00
import type { NextFunction, Request, Response } from 'express';
import cors from 'cors';
2023-08-14 05:54:34 +02:00
import { getBuildConfig, defaultOptions } from './util.js';
import { context } from 'esbuild';
2023-08-13 15:21:02 +02:00
import chokidar from 'chokidar';
import { generateLangium } from '../.build/generateLangium.js';
2023-11-18 20:14:44 +01:00
import { packageOptions } from '../.build/common.js';
2023-08-13 15:21:02 +02:00
const parserCtx = await context(
getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: 'parser' })
);
2023-08-13 15:21:02 +02:00
const mermaidCtx = await context(
2023-08-14 05:00:51 +02:00
getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: 'mermaid' })
2023-08-13 15:21:02 +02:00
);
const mermaidIIFECtx = await context(
2023-08-14 05:00:51 +02:00
getBuildConfig({
...defaultOptions,
minify: false,
core: false,
entryName: 'mermaid',
format: 'iife',
})
2023-08-13 15:21:02 +02:00
);
const externalCtx = await context(
2023-08-14 05:00:51 +02:00
getBuildConfig({
...defaultOptions,
minify: false,
core: false,
entryName: 'mermaid-example-diagram',
})
2023-08-13 15:21:02 +02:00
);
const zenumlCtx = await context(
2023-08-14 05:00:51 +02:00
getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: 'mermaid-zenuml' })
2023-08-13 15:21:02 +02:00
);
const contexts = [parserCtx, mermaidCtx, mermaidIIFECtx, externalCtx, zenumlCtx];
2023-08-13 15:21:02 +02:00
const rebuildAll = async () => {
console.time('Rebuild time');
2023-08-13 15:21:02 +02:00
await Promise.all(contexts.map((ctx) => ctx.rebuild()));
console.timeEnd('Rebuild time');
2023-08-13 15:21:02 +02:00
};
let clients: { id: number; response: Response }[] = [];
function eventsHandler(request: Request, response: Response, next: NextFunction) {
const headers = {
'Content-Type': 'text/event-stream',
Connection: 'keep-alive',
'Cache-Control': 'no-cache',
};
response.writeHead(200, headers);
const clientId = Date.now();
clients.push({
id: clientId,
response,
});
request.on('close', () => {
clients = clients.filter((client) => client.id !== clientId);
});
}
let timeoutId: NodeJS.Timeout | undefined = undefined;
/**
* Debounce file change events to avoid rebuilding multiple times.
*/
function handleFileChange() {
if (timeoutId !== undefined) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(async () => {
await rebuildAll();
sendEventsToAll();
timeoutId = undefined;
}, 100);
}
function sendEventsToAll() {
clients.forEach(({ response }) => response.write(`data: ${Date.now()}\n\n`));
}
async function createServer() {
await generateLangium();
handleFileChange();
const app = express();
2023-08-13 15:21:02 +02:00
chokidar
.watch('**/src/**/*.{js,ts,langium,yaml,json}', {
2023-08-13 15:21:02 +02:00
ignoreInitial: true,
ignored: [/node_modules/, /dist/, /docs/, /coverage/],
})
.on('all', async (event, path) => {
// Ignore other events.
if (!['add', 'change'].includes(event)) {
return;
}
if (/\.langium$/.test(path)) {
await generateLangium();
}
2023-08-13 15:21:02 +02:00
console.log(`${path} changed. Rebuilding...`);
handleFileChange();
});
app.use(cors());
2023-08-13 15:21:02 +02:00
app.get('/events', eventsHandler);
2023-11-18 20:14:44 +01:00
for (const { packageName } of Object.values(packageOptions)) {
app.use(express.static(`./packages/${packageName}/dist`));
}
app.use(express.static('demos'));
app.use(express.static('cypress/platform'));
app.listen(9000, () => {
console.log(`Listening on http://localhost:9000`);
});
}
createServer();