mermaid/.esbuild/server.ts

109 lines
2.9 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';
import { getBuildConfig } from './util.js';
import { context } from 'esbuild';
2023-08-13 15:21:02 +02:00
import chokidar from 'chokidar';
2023-08-14 05:00:51 +02:00
import { defaultOptions } from './util';
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 = [mermaidCtx, mermaidIIFECtx, externalCtx, zenumlCtx];
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() {
handleFileChange();
const app = express();
2023-08-13 15:21:02 +02:00
chokidar
.watch('**/src/**/*.{js,ts,yaml,json}', {
ignoreInitial: true,
ignored: [/node_modules/, /dist/, /docs/, /coverage/],
})
.on('all', async (event, path) => {
// Ignore other events.
if (!['add', 'change'].includes(event)) {
return;
}
console.log(`${path} changed. Rebuilding...`);
handleFileChange();
});
app.use(cors());
2023-08-13 15:21:02 +02:00
app.get('/events', eventsHandler);
app.use(express.static('./packages/mermaid/dist'));
app.use(express.static('./packages/mermaid-zenuml/dist'));
app.use(express.static('./packages/mermaid-example-diagram/dist'));
app.use(express.static('demos'));
app.use(express.static('cypress/platform'));
app.listen(9000, () => {
console.log(`Listening on http://localhost:9000`);
});
}
createServer();