mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-14 06:43:25 +08:00
chore: Add live-reload
This commit is contained in:
parent
01b2f80a95
commit
9fb9bed806
@ -1,29 +1,84 @@
|
||||
import express from 'express';
|
||||
import type { NextFunction, Request, Response } from 'express';
|
||||
import cors from 'cors';
|
||||
import { getBuildConfig } from './util.js';
|
||||
import { context } from 'esbuild';
|
||||
import chokidar from 'chokidar';
|
||||
|
||||
const mermaidCtx = await context(
|
||||
getBuildConfig({ minify: false, core: false, entryName: 'mermaid' })
|
||||
);
|
||||
const mermaidIIFECtx = await context(
|
||||
getBuildConfig({ minify: false, core: false, entryName: 'mermaid', format: 'iife' })
|
||||
);
|
||||
const externalCtx = await context(
|
||||
getBuildConfig({ minify: false, core: false, entryName: 'mermaid-example-diagram' })
|
||||
);
|
||||
const zenumlCtx = await context(
|
||||
getBuildConfig({ minify: false, core: false, entryName: 'mermaid-zenuml' })
|
||||
);
|
||||
const contexts = [mermaidCtx, mermaidIIFECtx, externalCtx, zenumlCtx];
|
||||
|
||||
const rebuildAll = async () => {
|
||||
await Promise.all(contexts.map((ctx) => ctx.rebuild()));
|
||||
};
|
||||
|
||||
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() {
|
||||
const app = express();
|
||||
const mermaidCtx = await context(
|
||||
getBuildConfig({ minify: false, core: false, entryName: 'mermaid' })
|
||||
);
|
||||
const mermaidIIFECtx = await context(
|
||||
getBuildConfig({ minify: false, core: false, entryName: 'mermaid', format: 'iife' })
|
||||
);
|
||||
const externalCtx = await context(
|
||||
getBuildConfig({ minify: false, core: false, entryName: 'mermaid-example-diagram' })
|
||||
);
|
||||
const zenuml = await context(
|
||||
getBuildConfig({ minify: false, core: false, entryName: 'mermaid-zenuml' })
|
||||
);
|
||||
|
||||
mermaidCtx.watch();
|
||||
mermaidIIFECtx.watch();
|
||||
externalCtx.watch();
|
||||
zenuml.watch();
|
||||
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());
|
||||
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'));
|
||||
|
@ -30,5 +30,33 @@ graph TB
|
||||
console.log(svg);
|
||||
el.innerHTML = svg;
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Set to false to disable live reload
|
||||
const liveReload = true;
|
||||
// Connect to the server and reload the page if the server sends a reload message
|
||||
const connectToEvents = () => {
|
||||
const events = new EventSource('/events');
|
||||
const loadTime = Date.now();
|
||||
events.onmessage = (event) => {
|
||||
const time = JSON.parse(event.data);
|
||||
if (time && time > loadTime) {
|
||||
location.reload();
|
||||
}
|
||||
};
|
||||
events.onerror = (error) => {
|
||||
console.error(error);
|
||||
events.close();
|
||||
// Try to reconnect after 1 second in case of errors
|
||||
setTimeout(connectToEvents, 1000);
|
||||
};
|
||||
events.onopen = () => {
|
||||
console.log('Connected to live reload server');
|
||||
};
|
||||
};
|
||||
if (liveReload) {
|
||||
connectToEvents();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -15,7 +15,7 @@
|
||||
"git graph"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "pnpm build:esbuild && pnpm build:types",
|
||||
"build": "pnpm run -r clean && pnpm build:esbuild && pnpm build:types",
|
||||
"build:esbuild": "pnpm run -r clean && ts-node-esm --transpileOnly .esbuild/build.ts",
|
||||
"build:mermaid": "pnpm build:esbuild --mermaid",
|
||||
"build:viz": "pnpm build:esbuild --visualize",
|
||||
@ -82,6 +82,7 @@
|
||||
"@vitest/spy": "^0.33.0",
|
||||
"@vitest/ui": "^0.33.0",
|
||||
"ajv": "^8.12.0",
|
||||
"chokidar": "^3.5.3",
|
||||
"concurrently": "^8.0.1",
|
||||
"cors": "^2.8.5",
|
||||
"cypress": "^12.10.0",
|
||||
|
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@ -74,6 +74,9 @@ importers:
|
||||
ajv:
|
||||
specifier: ^8.12.0
|
||||
version: 8.12.0
|
||||
chokidar:
|
||||
specifier: ^3.5.3
|
||||
version: 3.5.3
|
||||
concurrently:
|
||||
specifier: ^8.0.1
|
||||
version: 8.0.1
|
||||
|
Loading…
x
Reference in New Issue
Block a user