dev.ts
| 1 | import { watch } from 'fs'; |
| 2 | |
| 3 | const SRC_DIR = 'src'; |
| 4 | |
| 5 | async function spawnServer() { |
| 6 | return Bun.spawn(['bun', 'run', 'src/index.tsx'], { |
| 7 | stdio: ['inherit', 'inherit', 'inherit'], |
| 8 | }); |
| 9 | } |
| 10 | |
| 11 | async function restart(current: ReturnType<typeof Bun.spawn>) { |
| 12 | current.kill(); |
| 13 | await current.exited; |
| 14 | return spawnServer(); |
| 15 | } |
| 16 | |
| 17 | let server = await spawnServer(); |
| 18 | |
| 19 | // Debounce rapid file-save bursts (e.g. formatter touching many files at once) |
| 20 | let debounce: ReturnType<typeof setTimeout> | null = null; |
| 21 | watch(SRC_DIR, { recursive: true }, (_, filename) => { |
| 22 | if (filename?.endsWith('.css')) return; // CSS is handled by build-css.ts --watch |
| 23 | if (debounce) clearTimeout(debounce); |
| 24 | debounce = setTimeout(async () => { |
| 25 | console.clear(); |
| 26 | console.log(`[dev] ${filename} changed — restarting…`); |
| 27 | server = await restart(server); |
| 28 | }, 50); |
| 29 | }); |
| 30 | |
| 31 | const css = Bun.spawn(['bun', 'scripts/build-css.ts', '--watch'], { |
| 32 | stdio: ['inherit', 'inherit', 'inherit'], |
| 33 | }); |
| 34 | |
| 35 | process.on('SIGINT', async () => { |
| 36 | server.kill(); |
| 37 | css.kill(); |
| 38 | await Promise.all([server.exited, css.exited]); |
| 39 | process.exit(0); |
| 40 | }); |
| 41 | |
| 42 | await Promise.all([server.exited, css.exited]); |
| 43 |