fix dev server

This commit is contained in:
evilchili 2026-05-15 15:18:31 -07:00
parent c61b8e2f8b
commit 80c34a1483
4 changed files with 4313 additions and 141 deletions

4321
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -24,10 +24,14 @@
"devDependencies": { "devDependencies": {
"@types/jest": "^29.5.14", "@types/jest": "^29.5.14",
"esbuild": "^0.28.0", "esbuild": "^0.28.0",
"happy-dom": "^14.12.3", "happy-dom": "^20.9.0",
"jest": "^29.7.0", "jest": "^29.7.0",
"selenium-webdriver": "^4.43.0", "selenium-webdriver": "^4.43.0",
"ts-jest": "^29.4.9", "ts-jest": "^29.4.9",
"typescript": "^6.0.3" "typescript": "^6.0.3",
"live-server": "^1.2.0",
"node-watch": "^0.7.4"
},
"dependencies": {
} }
} }

View File

@ -1,106 +1,16 @@
/** var liveServer = require("live-server");
* Development server with livereload.
*
* Serves the test page and ribbit dist files. Watches src/ for
* changes, rebuilds automatically, and notifies connected browsers
* to reload via a simple EventSource stream.
*
* Run: npm run dev
*/
const { createServer } = require('./server');
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const PORT = 8080; var params = {
const WATCH_DIRS = [ port: 5023,
path.join(__dirname, '..', '..', 'src'), host: "0.0.0.0",
path.join(__dirname, '..', '..', 'test', 'integration'), open: true,
]; root: "test/integration",
const DEBOUNCE_MS = 300; mount: [
['/static', 'dist/ribbit'],
],
logLevel: 2, // 0 = errors only, 1 = some, 2 = lots
};
const server = createServer(PORT);
const reloadClients = [];
// Patch the server to add the livereload endpoint console.log(`\n🐸 Ribbit dev server running on http://localhost:${params['port']}`);
const originalServer = require('http').createServer; liveServer.start(params);
const httpServer = server._server || (() => {
// Access the internal server by starting and intercepting
let captured = null;
const origListen = require('http').Server.prototype.listen;
require('http').Server.prototype.listen = function (...args) {
captured = this;
return origListen.apply(this, args);
};
server.start();
require('http').Server.prototype.listen = origListen;
return captured;
})();
// Simpler approach: create a standalone livereload server
const reloadServer = require('http').createServer((request, response) => {
response.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': '*',
});
reloadClients.push(response);
request.on('close', () => {
const index = reloadClients.indexOf(response);
if (index >= 0) {
reloadClients.splice(index, 1);
}
});
});
function notifyReload() {
for (const client of reloadClients) {
client.write('data: reload\n\n');
}
}
function rebuild() {
try {
console.log('\n🔨 Rebuilding...');
execSync('npm run build:js && npm run build:css', {
cwd: path.join(__dirname, '..', '..'),
stdio: 'pipe',
});
console.log('✅ Build complete');
notifyReload();
} catch (error) {
console.error('❌ Build failed:', error.stderr?.toString().slice(0, 500));
}
}
let debounceTimer = null;
function onFileChange(filename) {
if (debounceTimer) {
clearTimeout(debounceTimer);
}
console.log(`📝 Changed: ${filename}`);
debounceTimer = setTimeout(rebuild, DEBOUNCE_MS);
}
// Watch source directories
for (const directory of WATCH_DIRS) {
if (fs.existsSync(directory)) {
fs.watch(directory, { recursive: true }, (eventType, filename) => {
if (filename && !filename.includes('node_modules')) {
onFileChange(filename);
}
});
}
}
server.start().then(() => {
reloadServer.listen(PORT + 1, () => {
console.log(`\n🐸 Ribbit dev server`);
console.log(` Editor: http://localhost:${PORT}`);
console.log(` Livereload: http://localhost:${PORT + 1} (EventSource)`);
console.log(` Watching: src/, test/integration/`);
console.log(`\n Add this to the page to enable livereload:`);
console.log(` <script>new EventSource('http://localhost:${PORT + 1}').onmessage = () => location.reload()</script>\n`);
});
});

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Ribbit Integration Test Page</title> <title>Ribbit Integration Test Page</title>
<link rel="stylesheet" href="/ribbit/themes/ribbit-default/theme.css"> <link rel="stylesheet" href="/static/themes/ribbit-default/theme.css">
<style> <style>
body { font-family: sans-serif; margin: 20px; } body { font-family: sans-serif; margin: 20px; }
#ribbit { border: 1px solid #ccc; padding: 20px; min-height: 200px; } #ribbit { border: 1px solid #ccc; padding: 20px; min-height: 200px; }
@ -32,7 +32,7 @@
| 1 | 2 | | 1 | 2 |
</article> </article>
<script src="/ribbit/ribbit.js"></script> <script src="/static/ribbit.js"></script>
<script> <script>
const editor = new ribbit.Editor({ const editor = new ribbit.Editor({
on: { on: {
@ -42,10 +42,5 @@
editor.run(); editor.run();
window.__ribbitEditor = editor; window.__ribbitEditor = editor;
</script> </script>
<script>
// Livereload — connects to dev server's EventSource endpoint.
// Silently fails if the dev server isn't running.
try { new EventSource('http://localhost:8081').onmessage = () => location.reload(); } catch(e) {}
</script>
</body> </body>
</html> </html>