2023-08-13 18:33:41 +05:30
|
|
|
import express from 'express';
|
2023-08-13 18:51:02 +05:30
|
|
|
import type { NextFunction, Request, Response } from 'express';
|
2023-08-13 18:33:41 +05:30
|
|
|
import cors from 'cors';
|
|
|
|
import { getBuildConfig } from './util.js';
|
|
|
|
import { context } from 'esbuild';
|
2023-08-13 18:51:02 +05:30
|
|
|
import chokidar from 'chokidar';
|
2023-08-14 08:30:51 +05:30
|
|
|
import { defaultOptions } from './util';
|
2023-08-13 18:51:02 +05:30
|
|
|
|
|
|
|
const mermaidCtx = await context(
|
2023-08-14 08:30:51 +05:30
|
|
|
getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: 'mermaid' })
|
2023-08-13 18:51:02 +05:30
|
|
|
);
|
|
|
|
const mermaidIIFECtx = await context(
|
2023-08-14 08:30:51 +05:30
|
|
|
getBuildConfig({
|
|
|
|
...defaultOptions,
|
|
|
|
minify: false,
|
|
|
|
core: false,
|
|
|
|
entryName: 'mermaid',
|
|
|
|
format: 'iife',
|
|
|
|
})
|
2023-08-13 18:51:02 +05:30
|
|
|
);
|
|
|
|
const externalCtx = await context(
|
2023-08-14 08:30:51 +05:30
|
|
|
getBuildConfig({
|
|
|
|
...defaultOptions,
|
|
|
|
minify: false,
|
|
|
|
core: false,
|
|
|
|
entryName: 'mermaid-example-diagram',
|
|
|
|
})
|
2023-08-13 18:51:02 +05:30
|
|
|
);
|
|
|
|
const zenumlCtx = await context(
|
2023-08-14 08:30:51 +05:30
|
|
|
getBuildConfig({ ...defaultOptions, minify: false, core: false, entryName: 'mermaid-zenuml' })
|
2023-08-13 18:51:02 +05:30
|
|
|
);
|
|
|
|
const contexts = [mermaidCtx, mermaidIIFECtx, externalCtx, zenumlCtx];
|
|
|
|
|
|
|
|
const rebuildAll = async () => {
|
2023-08-14 00:40:48 +05:30
|
|
|
console.time('Rebuild time');
|
2023-08-13 18:51:02 +05:30
|
|
|
await Promise.all(contexts.map((ctx) => ctx.rebuild()));
|
2023-08-14 00:40:48 +05:30
|
|
|
console.timeEnd('Rebuild time');
|
2023-08-13 18:51:02 +05:30
|
|
|
};
|
|
|
|
|
|
|
|
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`));
|
|
|
|
}
|
2023-08-13 18:33:41 +05:30
|
|
|
|
|
|
|
async function createServer() {
|
2023-08-14 00:40:48 +05:30
|
|
|
handleFileChange();
|
2023-08-13 18:33:41 +05:30
|
|
|
const app = express();
|
2023-08-13 18:51:02 +05:30
|
|
|
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();
|
|
|
|
});
|
2023-08-13 18:33:41 +05:30
|
|
|
|
|
|
|
app.use(cors());
|
2023-08-13 18:51:02 +05:30
|
|
|
app.get('/events', eventsHandler);
|
2023-08-13 18:33:41 +05:30
|
|
|
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();
|