Files
hyperframes/packages/cli/tsup.config.ts
T
Miguel Ángel 434ad8c41c perf(cli): a repeat check starts with the CLI and Chrome already up (#5943)
* fix(cli): the browser the CLI launches exits with it, even on kill -9

* fix(build): the root build runs on Windows

* perf(cli): a repeat check runs in a process that already has the CLI and Chrome up

* fix(cli): a warm check delivers all its output before it exits

* fix(cli): the warm check only talks to a server that proves it is the user's

The warm socket now lives in a private, owner-verified directory (XDG_RUNTIME_DIR,
~/.cache or LOCALAPPDATA) next to a 0600 token. Client and server prove the token to
each other over fresh nonces before any request is sent, the request carries an
HMAC of the environment instead of the environment itself, and frames are capped.

* fix(cli): a warm check prints its stdout even after something went to stderr

The client stopped writing frames once any frame had been written, so a check that
printed a notice to stderr first lost its JSON report.

* test(cli): list the warm-check client fixture as a fallow entry instead of an inline ignore

* fix(cli): a check started while a warm one is busy runs cold at once on Windows

The warm server stopped listening when it accepted a client. On Windows the pipe name stays alive through the served connection, so a second client's connect saw a busy pipe and waited 30 s for a free instance before running cold. It now keeps listening while serving (accept already declines anyone else) and stops when the served check finishes.

* test(cli): the orphan test reads the check's own Chrome and watchdog instead of racing a poll

On Windows each process listing is a PowerShell call of about a second, so a check that finishes quickly could start and close Chrome between two polls, and the test failed its own 'Chrome was seen' precondition. A fixture now records the Chrome tree and the watchdog from inside the check when its first page opens.
2026-10-20 19:09:11 +00:00

112 lines
3.9 KiB
TypeScript

import { defineConfig } from "tsup";
import { resolve } from "node:path";
import { readFileSync } from "node:fs";
import { sourceAliases } from "../../scripts/package-subpaths.mjs";
const pkg = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf-8")) as {
version: string;
};
const producerPkg = JSON.parse(
readFileSync(new URL("../producer/package.json", import.meta.url), "utf-8"),
) as { version: string };
export default defineConfig({
entry: {
cli: "src/cli.ts",
fontLocalizeCli: "src/fontLocalizeCli.ts",
runtimeVersion: "src/runtimeVersion.ts",
warmCheck: "src/warmCheck.ts",
warmCheckClient: "src/warmCheckClient.ts",
renderSetupWorker: "src/renderSetupWorker.ts",
backgroundChecksWorker: "src/backgroundChecksWorker.ts",
sherpaWorker: "src/whisper/sherpaWorker.ts",
shaderTransitionWorker: "../producer/src/services/shaderTransitionWorker.ts",
api: "src/api.ts",
},
format: ["esm"],
outDir: "dist",
target: "node22",
platform: "node",
bundle: true,
splitting: true,
sourcemap: false,
// Types for the `./api` export only; the other entries are programs, not libraries.
dts: { entry: { api: "src/api.ts" } },
clean: true,
banner: {
js: `import { createRequire as __hf_createRequire } from "node:module";
import { fileURLToPath as __hf_fileURLToPath } from "node:url";
import { dirname as __hf_dirname } from "node:path";
var require = __hf_createRequire(import.meta.url);
var __filename = __hf_fileURLToPath(import.meta.url);
var __dirname = __hf_dirname(__filename);`,
},
external: [
"puppeteer-core",
"puppeteer",
"@puppeteer/browsers",
// Native module — its platform binary (@img/sharp-<os>-<arch>) must be
// resolved from node_modules at runtime, never bundled. Loaded lazily by
// the capture pipeline; runtime resolution comes from the `dependencies`
// entry in package.json.
"sharp",
"open",
"hono",
"hono/*",
"@hono/node-server",
"adm-zip",
"esbuild",
"giget",
"postcss",
// aws-lambda transitively pulls @aws-sdk/* + @smithy/* which include
// .browser.js conditional exports esbuild can't bundle cleanly into
// a node binary. Keep it external; the lambda subverb files dynamic-
// import it only when the user runs `hyperframes lambda *`, so the
// CLI's cold start doesn't load it. Runtime resolution comes from
// @hyperframes/aws-lambda being a `dependencies` entry in package.json.
"@hyperframes/aws-lambda",
"@hyperframes/aws-lambda/sdk",
// Same treatment for the GCP adapter: the cloudrun subverb files
// dynamic-import `@hyperframes/gcp-cloud-run/sdk` only when the user runs
// `hyperframes cloudrun *`. Keep it external; runtime resolution comes
// from the `dependencies`/workspace entry, not the bundled CLI.
"@hyperframes/gcp-cloud-run",
"@hyperframes/gcp-cloud-run/sdk",
"@hyperframes/gcp-cloud-run/terraform",
],
noExternal: [
"@hyperframes/core",
"@hyperframes/parsers",
"@hyperframes/studio-server",
"@hyperframes/lint",
"@hyperframes/producer",
"@hyperframes/engine",
"@clack/prompts",
"@clack/core",
"picocolors",
"linkedom",
"sisteransi",
"is-unicode-supported",
"citty",
],
define: {
__CLI_VERSION__: JSON.stringify(pkg.version),
__PRODUCER_VERSION__: JSON.stringify(producerPkg.version),
},
esbuildOptions(options) {
options.alias = {
// Exact subpaths are generated from the same contracts as package
// exports, avoiding esbuild's root-alias prefix substitution trap.
...sourceAliases(resolve(__dirname, "../producer"), [".", "./distributed"]),
...sourceAliases(resolve(__dirname, "../engine"), [
".",
"./chrome-host-ceiling",
"./shader-transitions",
"./system-memory",
"./wsl-host",
]),
};
options.loader = { ...options.loader, ".browser.js": "text" };
},
});