diff --git a/package.json b/package.json index 031b129..a819195 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "typescript": "5.9.3" }, "scripts": { - "dev": "bun scripts/dev_watch.ts", + "dev": "bun --watch src/app.ts", "start": "bun src/app.ts", "build": "rimraf ./dist && tsc && cp-cli ./src/static ./dist/static", "docs": "typedoc --out docs src", diff --git a/scripts/dev_watch.ts b/scripts/dev_watch.ts deleted file mode 100644 index 88a9253..0000000 --- a/scripts/dev_watch.ts +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env bun -/** - * Development watch script for Bun - * - * Watches src/ for changes, rebuilds on change, and restarts the server. - * This is necessary because we must compile TypeScript first due to circular - * TypeORM entity dependencies that Bun's TS loader cannot handle directly. - */ - -import { watch } from "fs"; -import { spawn } from "child_process"; -import consola from "consola"; - -let serverProcess: ReturnType | null = null; -let isRebuilding = false; -let pendingRestart = false; -let debounceTimer: NodeJS.Timeout | null = null; -let watcherReady = false; - -function killServer() { - return new Promise((resolve) => { - if (serverProcess) { - consola.info("Stopping server..."); - serverProcess.kill(); - serverProcess = null; - // Wait for port to be fully released (longer on Windows) - setTimeout(resolve, 2000); - } else { - resolve(); - } - }); -} - -function startServer() { - consola.info("Starting server..."); - serverProcess = spawn("bun", ["dist/app.js"], { - stdio: "inherit", - shell: true, - }); - - serverProcess.on("error", (err) => { - consola.error("Server process error:", err); - }); - - serverProcess.on("exit", (code) => { - if (code !== null && code !== 0 && code !== 143) { - consola.error(`Server exited with code ${code}`); - } - }); - - // Enable watcher after initial server start - if (!watcherReady) { - setTimeout(() => { - watcherReady = true; - consola.success("👀 Watching for file changes..."); - }, 1000); - } -} - -async function rebuild() { - if (isRebuilding) { - pendingRestart = true; - return; - } - - isRebuilding = true; - pendingRestart = false; - - consola.info("Rebuilding..."); - await killServer(); - - const buildProcess = spawn("bun", ["run", "build"], { - stdio: "inherit", - shell: true, - }); - - buildProcess.on("exit", (code) => { - isRebuilding = false; - - if (code === 0) { - consola.success("Build complete!"); - startServer(); - - if (pendingRestart) { - consola.info("Change detected during build, rebuilding again..."); - setTimeout(() => rebuild(), 100); - } - } else { - consola.error(`Build failed with code ${code}`); - } - }); -} - -// Initial build and start -consola.info("🔄 Development mode - watching for changes..."); -rebuild(); - -// Watch src/ for changes (including subdirectories) -const watcher = watch( - "./src", - { recursive: true }, - (eventType, filename) => { - if (!watcherReady) return; // Ignore changes during initial build - - if (filename && filename.endsWith(".ts")) { - // Ignore test files and declaration files - if (filename.endsWith(".spec.ts") || filename.endsWith(".d.ts")) { - return; - } - - // Debounce: wait 500ms for multiple rapid changes - if (debounceTimer) { - clearTimeout(debounceTimer); - } - - debounceTimer = setTimeout(() => { - consola.info(`File changed: ${filename}`); - rebuild(); - }, 500); - } - } -); - -// Cleanup on exit -process.on("SIGINT", () => { - consola.info("\nShutting down..."); - if (debounceTimer) clearTimeout(debounceTimer); - killServer(); - watcher.close(); - process.exit(0); -}); - -process.on("SIGTERM", () => { - if (debounceTimer) clearTimeout(debounceTimer); - killServer(); - watcher.close(); - process.exit(0); -});