1#!/usr/bin/env node
buck2 run //:dev: the dev server, as two supervised processes.
- The jevstrudel Worker (worker/) under
wrangler dev --env dev, on the port in worker/wrangler.json: the Jev relay and the MCP hub, supervised by supervise.mjs, its local D1 database migrated first (migrate.mjs). - Astro's dev server for the site, on http://localhost:4322/, which proxies the Worker's paths to it (website/astro.config.mjs).
When Astro exits, or this process is stopped, the Worker goes too.
17process.chdir(execFileSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf8' }).trim()); 18 19for (const tool of ['pnpm', 'wrangler', 'setpriv']) { 20 if (!has(tool)) { 21 console.error(`dev: ${tool} is not on PATH; run inside the devshell (nix develop, or direnv)`); 22 process.exit(1); 23 } 24} 25 26const run = (cmd, args) => execFileSync(cmd, args, { stdio: 'inherit' }); 27run('pnpm', ['install', '--frozen-lockfile', '--prefer-offline']);
The REPL's autocompletion and reference tab read doc.json; upstream's prestart regenerates it the same way.
30run('pnpm', ['run', 'jsdoc-json']);
32const port = JSON.parse(readFileSync('worker/wrangler.json', 'utf8')).dev.port;
wrangler.json's assets (production's ASSETS binding, which the votes
read the song list through) is inherited by env.dev and needs a
directory. Dev has no built site: Astro serves it, and the Worker reads
the song list from Astro (SONGS_URL), so its assets are an empty folder.
The Worker's local D1 (worker/.wrangler/state), migrated before it starts.
40migrateLocal({ env: 'dev' });
--test-scheduled: wrangler dev fires no cron triggers by itself, so the
Worker's every-minute sweep of what Jev owes listeners' content
(worker/src/content-jobs.ts) runs on curl localhost:4323/__scheduled.
50const astro = spawn('setpriv', ['--pdeathsig', 'TERM', '--', 'pnpm', 'exec', 'astro', 'dev'], { 51 cwd: 'website', 52 stdio: 'inherit', 53}); 54 55function shutdown(code) { 56 worker.stop(); 57 if (astro.exitCode === null) astro.kill('SIGTERM'); 58 setTimeout(() => process.exit(code), 500).unref(); 59} 60astro.on('exit', (code) => shutdown(code ?? 1)); 61for (const signal of ['SIGINT', 'SIGTERM']) process.on(signal, () => shutdown(0));