@vzn/vx 0.0.190 → 0.0.191

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/README.md CHANGED
@@ -148,21 +148,22 @@ the tool it ships with, same machine and tasks per row, medians.
148
148
 
149
149
  <!-- repos:start — generated by packages/vx-bench/update-site.ts from real-repos.json; do not hand-edit -->
150
150
 
151
- | Repo | Against | Cold build | Restore outputs | Nothing to do |
152
- | ----------------------------------------------------------- | ------- | --------------------- | ------------------- | ---------------------- |
153
- | [solidjs/solid](https://github.com/solidjs/solid) | Turbo | 40.6 s / 45.5 s | 66 ms / 127 ms | 51 ms / 95 ms |
154
- | [withastro/astro](https://github.com/withastro/astro) | Turbo | 48.0 s / 57.9 s | 478 ms / 1.43 s | 249 ms / 1.38 s |
155
- | [payloadcms/payload](https://github.com/payloadcms/payload) | Turbo | 126.9 s / 127.5 s | 3.44 s / 3.46 s | 256 ms / **237 ms** |
156
- | [medusajs/medusa](https://github.com/medusajs/medusa) | Turbo | 308 s / 315 s | 3.86 s / 7.16 s | 947 ms / 3.29 s |
157
- | [n8n-io/n8n](https://github.com/n8n-io/n8n) | Turbo | 137.2 s / **133.7 s** | 8.27 s / 12.5 s | 842 ms / 1.36 s |
158
- | [calcom/cal.com](https://github.com/calcom/cal.com) | Turbo | 245.7 s / 250.7 s | 17.4 s / 19.9 s | 14.7 s / 18.5 s |
159
- | [unocss/unocss](https://github.com/unocss/unocss) | Turbo | 45.1 s / 47.3 s | 859 ms / **185 ms** | 770 ms / **126 ms** |
160
- | [vueuse/vueuse](https://github.com/vueuse/vueuse) | Turbo | 21.4 s / 29.2 s | 263 ms / **128 ms** | 246 ms / **51–161 ms** |
161
- | [TanStack/query](https://github.com/TanStack/query) | Nx | 34.6 s / 37.1 s | 910 ms / 1.62 s | 291 ms / 1.60 s |
162
- | [strapi/strapi](https://github.com/strapi/strapi) | Nx | 238.2 s / 245.7 s | 1.61 s / 3.94 s | 341 ms / 4.02 s |
163
- | [novuhq/novu](https://github.com/novuhq/novu) | Nx | 291.2 s / 299.4 s | 3.10 s / 9.05 s | 655 ms / 8.55 s |
164
- | [TanStack/router](https://github.com/TanStack/router) | Nx | 123.0 s / 138.0 s | 1.27 s / 3.82 s | 626 ms / 3.91 s |
165
- | [refinedev/refine](https://github.com/refinedev/refine) | Nx | 96.2 s / 105.9 s | 1.06 s / 1.19 s | 303 ms / 1.16 s |
151
+ | Repo | Against | Cold build | Restore outputs | Nothing to do |
152
+ | ------------------------------------------------------------------- | ------- | --------------------- | ------------------- | ---------------------- |
153
+ | [solidjs/solid](https://github.com/solidjs/solid) | Turbo | 40.6 s / 45.5 s | 66 ms / 127 ms | 51 ms / 95 ms |
154
+ | [withastro/astro](https://github.com/withastro/astro) | Turbo | 48.0 s / 57.9 s | 478 ms / 1.43 s | 249 ms / 1.38 s |
155
+ | [payloadcms/payload](https://github.com/payloadcms/payload) | Turbo | 126.9 s / 127.5 s | 3.44 s / 3.46 s | 256 ms / **237 ms** |
156
+ | [medusajs/medusa](https://github.com/medusajs/medusa) | Turbo | 308 s / 315 s | 3.86 s / 7.16 s | 947 ms / 3.29 s |
157
+ | [n8n-io/n8n](https://github.com/n8n-io/n8n) | Turbo | 137.2 s / **133.7 s** | 8.27 s / 12.5 s | 842 ms / 1.36 s |
158
+ | [calcom/cal.com](https://github.com/calcom/cal.com) | Turbo | 245.7 s / 250.7 s | 17.4 s / 19.9 s | 14.7 s / 18.5 s |
159
+ | [unocss/unocss](https://github.com/unocss/unocss) | Turbo | 45.1 s / 47.3 s | 859 ms / **185 ms** | 770 ms / **126 ms** |
160
+ | [vueuse/vueuse](https://github.com/vueuse/vueuse) | Turbo | 21.4 s / 29.2 s | 263 ms / **128 ms** | 246 ms / **51–161 ms** |
161
+ | [t3-oss/create-t3-turbo](https://github.com/t3-oss/create-t3-turbo) | Turbo | 27.2 s / 29.6 s | 199 ms / 340 ms | 174 ms / 342 ms |
162
+ | [TanStack/query](https://github.com/TanStack/query) | Nx | 34.6 s / 37.1 s | 910 ms / 1.62 s | 291 ms / 1.60 s |
163
+ | [strapi/strapi](https://github.com/strapi/strapi) | Nx | 238.2 s / 245.7 s | 1.61 s / 3.94 s | 341 ms / 4.02 s |
164
+ | [novuhq/novu](https://github.com/novuhq/novu) | Nx | 291.2 s / 299.4 s | 3.10 s / 9.05 s | 655 ms / 8.55 s |
165
+ | [TanStack/router](https://github.com/TanStack/router) | Nx | 123.0 s / 138.0 s | 1.27 s / 3.82 s | 626 ms / 3.91 s |
166
+ | [refinedev/refine](https://github.com/refinedev/refine) | Nx | 96.2 s / 105.9 s | 1.06 s / 1.19 s | 303 ms / 1.16 s |
166
167
 
167
168
  vx first, theirs second; **bold** marks the other tool winning. How each
168
169
  repo was run, versions, dates and why a tool wins where it does:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx",
3
- "version": "0.0.190",
3
+ "version": "0.0.191",
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.190",
21
- "@vzn/vx-linux-arm64": "0.0.190",
22
- "@vzn/vx-darwin-x64": "0.0.190",
23
- "@vzn/vx-darwin-arm64": "0.0.190"
20
+ "@vzn/vx-linux-x64": "0.0.191",
21
+ "@vzn/vx-linux-arm64": "0.0.191",
22
+ "@vzn/vx-darwin-x64": "0.0.191",
23
+ "@vzn/vx-darwin-arm64": "0.0.191"
24
24
  },
25
25
  "dependencies": {
26
26
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
@@ -197,7 +197,8 @@ export interface PackArgs {
197
197
  * The project directory a symlinked output must resolve inside. vx reads
198
198
  * outputs outside the task's sandbox, so a link a sandboxed task planted
199
199
  * to a file it could not read (another project's, the user's home) packed
200
- * that file into the artifact and the remote (L-23).
200
+ * that file into the artifact and the remote (L-23). A link to another
201
+ * output of the same artifact is packed wherever it is.
201
202
  */
202
203
  within?: string
203
204
  }
@@ -219,6 +220,17 @@ export interface ArtifactPlan {
219
220
  export async function planArtifact(args: PackArgs): Promise<ArtifactPlan> {
220
221
  const meta: MetaFile = { version: 1, files: {} }
221
222
  let withinReal: Promise<string> | undefined
223
+ // Where this artifact's own non-link outputs really are: a link to one of
224
+ // them packs bytes the task wrote itself. A root-anchored output tree is
225
+ // outside every project, so `gen/latest -> v2.txt` there was refused and
226
+ // the task never cached (J's lead).
227
+ let ownReal: Promise<Set<string>> | undefined
228
+ const ownOutputs = (): Promise<Set<string>> =>
229
+ (ownReal ??= Promise.all(
230
+ [...args.outputs.values()].map(async (abs) =>
231
+ (await lstat(abs)).isSymbolicLink() ? null : realpath(abs),
232
+ ),
233
+ ).then((all) => new Set(all.filter((p): p is string => p !== null))))
222
234
  if (args.key !== undefined) meta.key = args.key
223
235
  const exec = usageOf(args.exec)
224
236
  if (exec !== undefined) meta.exec = exec
@@ -246,7 +258,7 @@ export async function planArtifact(args: PackArgs): Promise<ArtifactPlan> {
246
258
  if (args.within !== undefined) {
247
259
  withinReal ??= realpath(args.within)
248
260
  const root = await withinReal
249
- if (!src.startsWith(root + path.sep)) {
261
+ if (!src.startsWith(root + path.sep) && !(await ownOutputs()).has(src)) {
250
262
  throw new UserError(
251
263
  `output ${shown} is a symlink to ${src}, outside the project: vx packs a symlinked output as its target's bytes, and a project's outputs come from its own directory — emit a file there, or take it back with a '!' entry`,
252
264
  )
@@ -272,7 +272,7 @@ export function formatSummarySection(
272
272
  /**
273
273
  * `42 tasks · 38 cached (90%) · 3.2s`, `2 tasks · all cached · 23ms`,
274
274
  * with the failures first when there are any. Cached is every hit (up to
275
- * date, restored locally or remotely) over every counted task.
275
+ * date, restored locally or remotely) over every task that has a cache.
276
276
  */
277
277
  function resultLine(
278
278
  stats: SummaryStats,
@@ -282,11 +282,17 @@ function resultLine(
282
282
  ): string {
283
283
  const parts = [`${stats.total} task${stats.total === 1 ? '' : 's'}`]
284
284
  if (stats.failed > 0) parts.push(paint(ERROR, `${stats.failed} failed`, colors, { bold: true }))
285
- parts.push(
286
- hits === stats.total
287
- ? paint(SUCCESS, 'all cached', colors, { bold: true })
288
- : `${hits} cached (${Math.floor((hits / stats.total) * 100)}%)`,
289
- )
285
+ // A task with no `cache` block could never hit: it is counted apart, not
286
+ // as a miss, or `vx run dev` would read "0 cached (0%)".
287
+ const noCache = stats.noCache ?? 0
288
+ const cacheable = stats.total - noCache
289
+ if (cacheable > 0)
290
+ parts.push(
291
+ hits === cacheable
292
+ ? paint(SUCCESS, 'all cached', colors, { bold: true })
293
+ : `${hits} cached (${Math.floor((hits / cacheable) * 100)}%)`,
294
+ )
295
+ if (noCache > 0) parts.push(paint('', `${noCache} no-cache`, colors, { dim: true }))
290
296
  parts.push(formatDuration(totalMs))
291
297
  return parts.join(` ${paint('', '\u00b7', colors, { dim: true })} `)
292
298
  }
@@ -48,10 +48,12 @@ const nonJsonPaths = ${nonJsonPaths.toString()}
48
48
  // config printing on a repeat load wrote into it: the server's own redirect
49
49
  // covers the parent thread only (D-64). This worker only evaluates configs,
50
50
  // so every route to fd 1 is stderr's, Bun's own included (item 1069).
51
- const quiet = (async () => {
51
+ // Synchronous, before any message: an awaited import of the Console left
52
+ // the first evaluation racing its own redirect (D-73).
53
+ {
52
54
  const P = globalThis.process
53
55
  const B = globalThis.Bun
54
- const { Console } = await import('node:console')
56
+ const Console = globalThis.console.Console
55
57
  globalThis.console = Object.assign(new Console(P.stderr, P.stderr), {
56
58
  write: (...data) => {
57
59
  const text = data.join('')
@@ -68,9 +70,8 @@ const quiet = (async () => {
68
70
  P.exit = (code) => {
69
71
  throw new Error('process.exit(' + (code ?? '') + ') in a config: ' + ${JSON.stringify(CONFIG_EXIT)})
70
72
  }
71
- })()
73
+ }
72
74
  self.onmessage = async (e) => {
73
- await quiet
74
75
  const { id, path, env } = e.data
75
76
  // A Worker starts with the process's STARTUP environment, not the
76
77
  // parent's process.env as written since (probed): a config reading an