@vzn/vx 0.0.179 → 0.0.180

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx",
3
- "version": "0.0.179",
3
+ "version": "0.0.180",
4
4
  "description": "A fast, correct task runner and build cache for JavaScript monorepos.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -17,10 +17,10 @@
17
17
  "node": ">=18"
18
18
  },
19
19
  "optionalDependencies": {
20
- "@vzn/vx-linux-x64": "0.0.179",
21
- "@vzn/vx-linux-arm64": "0.0.179",
22
- "@vzn/vx-darwin-x64": "0.0.179",
23
- "@vzn/vx-darwin-arm64": "0.0.179"
20
+ "@vzn/vx-linux-x64": "0.0.180",
21
+ "@vzn/vx-linux-arm64": "0.0.180",
22
+ "@vzn/vx-darwin-x64": "0.0.180",
23
+ "@vzn/vx-darwin-arm64": "0.0.180"
24
24
  },
25
25
  "dependencies": {
26
26
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
@@ -39,6 +39,9 @@ import path from 'node:path'
39
39
  import { MAX_TIMEOUT_MS, UserError } from '../util/index.js'
40
40
  import { nonJsonMessage, nonJsonPaths, type NonJsonValue } from './json-data.js'
41
41
 
42
+ /** Why a config's `process.exit` throws, on both load paths (D-65). */
43
+ export const CONFIG_EXIT = 'a config exports its object; it cannot end the run'
44
+
42
45
  const WORKER_SRC = `
43
46
  const nonJsonPaths = ${nonJsonPaths.toString()}
44
47
  // The parent's stdout is a verb's JSON or vx mcp's JSON-RPC stream, and a
@@ -60,6 +63,11 @@ const quiet = (async () => {
60
63
  const ownBunWrite = B.write
61
64
  B.write = (dest, ...rest) => ownBunWrite(dest === B.stdout ? B.stderr : dest, ...rest)
62
65
  B.stdout.writer = (...args) => B.stderr.writer(...args)
66
+ // An exit here ended the worker unheard, and the load waited out its
67
+ // whole deadline to say the worker did not answer (D-65).
68
+ P.exit = (code) => {
69
+ throw new Error('process.exit(' + (code ?? '') + ') in a config: ' + ${JSON.stringify(CONFIG_EXIT)})
70
+ }
63
71
  })()
64
72
  self.onmessage = async (e) => {
65
73
  await quiet
@@ -3,7 +3,7 @@ import path from 'node:path'
3
3
  import type { ProjectConfig, WorkspaceConfig } from '../config.js'
4
4
  import { UserError, xxh3hex } from '../util/index.js'
5
5
  import { validateProjectConfig, validateWorkspace } from './config-schema.js'
6
- import { beginEvalRound, evaluateConfigFresh } from './config-eval.js'
6
+ import { beginEvalRound, CONFIG_EXIT, evaluateConfigFresh } from './config-eval.js'
7
7
  import { hasEsmExport, unprovidedBareImports } from './config-imports.js'
8
8
  import {
9
9
  configEvalKey,
@@ -136,6 +136,7 @@ async function loadDefaultExport(
136
136
  holdSource(hash, source)
137
137
  }
138
138
  let ns: { default?: unknown }
139
+ const unguard = guardExit()
139
140
  try {
140
141
  ns = (await import(specifier)) as { default?: unknown }
141
142
  } catch (err) {
@@ -145,6 +146,7 @@ async function loadDefaultExport(
145
146
  }
146
147
  throw configLoadError(err, configPath, kind) ?? err
147
148
  } finally {
149
+ unguard()
148
150
  if (source !== null) releaseSource(hash)
149
151
  }
150
152
  const mod = ns?.default
@@ -152,6 +154,28 @@ async function loadDefaultExport(
152
154
  return mod
153
155
  }
154
156
 
157
+ /**
158
+ * A config's `process.exit` ended vx mid-load: `exit(0)` was a green run
159
+ * that ran nothing and printed nothing (D-65). While any config evaluates
160
+ * in process it throws instead, at the config's line. vx's own exit is
161
+ * signal forwarding's, which a run installs after its load and removes
162
+ * when it ends.
163
+ */
164
+ let evaluating = 0
165
+ let ownExit: typeof process.exit = process.exit
166
+ function guardExit(): () => void {
167
+ if (evaluating++ === 0) {
168
+ ownExit = process.exit
169
+ process.exit = configExit
170
+ }
171
+ return () => {
172
+ if (--evaluating === 0) process.exit = ownExit
173
+ }
174
+ }
175
+ const configExit = ((code?: number | string | null) => {
176
+ throw new Error(`process.exit(${code ?? ''}) in a config: ${CONFIG_EXIT}`)
177
+ }) as typeof process.exit
178
+
155
179
  /**
156
180
  * A bare import nothing above the config provides is refused BEFORE the
157
181
  * evaluation: left to Bun, a workspace with no `node_modules` would have