UNPKG

winterspec

Version:

Write Winter-CG compatible routes with filesystem routing and tons of features

74 lines (73 loc) 2.82 kB
import { Command, Option } from "clipanion"; import { durationFormatter } from "human-readable"; import ora from "ora"; import { startDevServer } from "../../dev/dev-server.js"; import { BaseCommand } from "../base-command.js"; export class DevCommand extends BaseCommand { constructor() { super(...arguments); this.port = Option.String("--port,-p", "3000", { description: "The port to serve your app on", }); // todo: better syntax for this flag, seems to need --no-emulate-wintercg this.emulateWinterCG = Option.Boolean("--emulate-wintercg", true, { description: "Emulate the WinterCG runtime. When true, native APIs are unavailable.", }); } async run(config) { const configWithOverrides = { emulateWinterCG: this.emulateWinterCG, ...config, }; const listenSpinner = ora({ text: "Starting server...", hideCursor: false, discardStdin: false, }).start(); let buildStartedAt; const spinner = ora({ hideCursor: false, discardStdin: false, text: "Building...", }).start(); const timeFormatter = durationFormatter({ allowMultiples: ["m", "s", "ms"], }); // Prevents the build spinner from displaying before the listening message // No spinner collision plz! 🙈 let resolveOnListeningPromise; const listeningPromise = new Promise((resolve) => { resolveOnListeningPromise = resolve; }); await startDevServer({ port: parseInt(this.port, 10), config: configWithOverrides, onListening(port) { listenSpinner.stopAndPersist({ symbol: "☃️", text: ` listening on port ${port}: http://localhost:${port}\n`, }); resolveOnListeningPromise(); }, async onBuildStart() { buildStartedAt = performance.now(); await listeningPromise; spinner.start("Building..."); }, async onBuildEnd(build) { const durationMs = performance.now() - buildStartedAt; await listeningPromise; if (build.type === "success") { spinner.succeed(`Built in ${timeFormatter(durationMs)}`); } else { spinner.fail(`Build failed.\n${build.errorMessage}`); } }, }); } } DevCommand.paths = [[`dev`]]; DevCommand.usage = Command.Usage({ description: `Start a development server. It watches your source code and will automatically rebuild upon changes.`, });