1#!/usr/bin/env node 2// `buck2 run //:preview`: what `nix run .#deploy` would publish, served 3// locally on http://localhost:4324/ for a last listen before deploying. 4// 5// It is the deploy's own inputs: the flake's `static` build (the same 6// derivation the deploy uploads as assets) and worker/ in its production 7// environment (`--env ""`: the Jev relay, no MCP hub), under `wrangler dev` 8// and supervised like the dev server's Worker (supervise.mjs). No hot 9// reload: rerun it after a change. 10import { execFileSync } from 'node:child_process'; 11import { migrateLocal } from './migrate.mjs'; 12import { has, superviseWorker } from './supervise.mjs'; 13 14// The one place the preview's port is set. Not 4322/4323 (the dev server) 15// or 8080 (Gerrit on this host). 16export const PREVIEW_PORT = 4324; 17 18process.chdir(execFileSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf8' }).trim()); 19 20for (const tool of ['nix', 'pnpm', 'wrangler', 'setpriv']) { 21 if (!has(tool)) { 22 console.error(`preview: ${tool} is not on PATH; run inside the devshell (nix develop, or direnv)`); 23 process.exit(1); 24 } 25} 26 27// worker/ is a workspace package with dependencies of its own (the 28// WebAuthn library); the deploy bundles them from the same lockfile 29// (nix/worker-closure.mjs). 30execFileSync('pnpm', ['install', '--frozen-lockfile', '--prefer-offline', '--filter', '@jevstrudel/worker'], { 31 stdio: 'inherit', 32}); 33 34console.error('preview: building .#static, the site the deploy uploads'); 35const assets = execFileSync('nix', ['build', '-L', '.#static', '--no-link', '--print-out-paths'], { 36 encoding: 'utf8', 37 stdio: ['ignore', 'pipe', 'inherit'], 38}).trim(); 39 40// its own local state, apart from the dev server's Worker 41const PERSIST = 'worker/.wrangler/preview'; 42migrateLocal({ env: '', persistTo: PERSIST }); 43 44const worker = superviseWorker({ 45 name: 'preview', 46 port: PREVIEW_PORT, 47 args: [ 48 '--env', 49 '', 50 '--assets', 51 assets, 52 '--port', 53 String(PREVIEW_PORT), 54 '--persist-to', 55 PERSIST, 56 ], 57}); 58console.error(`preview: ${assets} with the production Worker on http://localhost:${PREVIEW_PORT}/`); 59 60for (const signal of ['SIGINT', 'SIGTERM']) 61 process.on(signal, () => { 62 worker.stop(); 63 setTimeout(() => process.exit(0), 500).unref(); 64 });