diff --git a/src/cli.ts b/src/cli.ts index cbc252b..a9f72fd 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,3 +1,4 @@ +import { type ChildProcess, fork } from "node:child_process"; import * as fs from "node:fs"; import * as posix from "node:path/posix"; import { prettify, htmlDocument } from "antihtml"; @@ -6,6 +7,9 @@ import type { Page } from "./types.js"; import { resolveRefs } from "./utils/resolve-refs.js"; import { createServer } from "./utils/http-server.js"; +const srcDir = "build/node"; +const webDir = "web"; + function pageToHtml(page: Page) { if (!page.ref.startsWith("/")) { throw new Error(`ref "${page.ref}" for "${page.title}" is not absolute.`); @@ -21,7 +25,6 @@ function pageToHtml(page: Page) { } function assembleResources() { - const webDir = "web"; const resources = new Map(); for (const entry of fs.readdirSync(webDir, { recursive: true, withFileTypes: true })) { if (!entry.isFile()) @@ -77,10 +80,34 @@ function serve() { console.log("Listening on http://localhost:8080"); } +function watch(script: string) { + let child: ChildProcess; + function start() { + child = fork(script, ["serve"]); + } + function restart() { + if (child.exitCode === null) { + child.kill(); + child.once("close", start); + } else { + start(); + } + } + let restartTimeout: ReturnType; + function onChange() { + clearTimeout(restartTimeout); + restartTimeout = setTimeout(restart, 100) + } + fs.watch(webDir, { recursive: true }, onChange); + fs.watch(srcDir, { recursive: true }, onChange); + start(); +} + function printUsage() { console.log("Usage: cli.js "); console.log(" build - Copy resources and generated pages to build directory."); console.log(" serve - Host website on localhost:8080 for development purposes."); + console.log(" watch - Run serve and automatically restart it on changes."); } function main(runtime: string, script: string, args: string[]) { @@ -95,6 +122,8 @@ function main(runtime: string, script: string, args: string[]) { build(); } else if (command === "serve") { serve(); + } else if (command === "watch") { + watch(script); } else { console.log(`Error: Unkown sub-command ${command}`); printUsage();