@vzn/vx-reapi 0.0.644 → 0.0.646

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 vx contributors
3
+ Copyright (c) 2026 VZN
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -8,7 +8,7 @@ BuildBuddy, Buildbarn, bazel-remote: mature server implementations, none of
8
8
  which we had to write, because a REAPI server is deliberately dumb.
9
9
 
10
10
  ```sh
11
- npm install -D @vzn/vx @vzn/vx-reapi # or: pnpm add -D -w · yarn add -D (-W on Yarn 1) · bun add -d
11
+ bun add -d @vzn/vx @vzn/vx-reapi
12
12
  ```
13
13
 
14
14
  ```ts
@@ -344,20 +344,15 @@ without its inputs and caches the result.
344
344
 
345
345
  ## Tests
346
346
 
347
- `bun test` runs the unit suite anywhere. The round-trip suite needs a real
348
- server:
347
+ `bun test` runs the unit suite anywhere. The round-trip suites need real
348
+ servers, which `vx run test.live --filter @vzn/vx-reapi` brings with Docker:
349
+ `services.cache` (bazel-remote on `:19092`) and `services.exec` (NativeLink on
350
+ `:51051`) run in the foreground until the run ends. CI runs it in the Linux
351
+ distributed run, where they start on the agent that runs `test.live`.
349
352
 
350
- ```sh
351
- docker run -d -p 19092:9092 buchgr/bazel-remote-cache:latest \
352
- --dir /data --max_size 1 --grpc_address 0.0.0.0:9092 --http_address 0.0.0.0:8080
353
-
354
- VX_REAPI_TEST_ENDPOINT=grpc://127.0.0.1:19092 bun test
355
- ```
356
-
357
- Without an endpoint those tests skip; CI sets `VX_REQUIRE_REAPI=1`, which turns
358
- an absent endpoint into a failure so the suite cannot silently vanish. The
359
- remote-execution suites need an execution server in `VX_REAPI_EXEC_ENDPOINT`;
360
- CI sets it with `VX_REQUIRE_REAPI_EXEC=1`.
353
+ Without an endpoint those tests skip; `test.live` sets `VX_REQUIRE_REAPI=1` and
354
+ `VX_REQUIRE_REAPI_EXEC=1`, which turn an absent endpoint into a failure so the
355
+ suites cannot silently vanish.
361
356
 
362
357
  ## Protocol coverage
363
358
 
@@ -443,8 +438,8 @@ the packages a build needs. The answer is the design doc's §7.4 recipe,
443
438
 
444
439
  ```ts
445
440
  install: {
446
- exec: { command: 'pnpm install --frozen-lockfile', remote: 'only' },
447
- inputs: { files: ['package.json', 'pnpm-lock.yaml'] },
441
+ exec: { command: 'bun install --frozen-lockfile', remote: 'only' },
442
+ inputs: { files: ['package.json', 'bun.lock'] },
448
443
  cache: {
449
444
  outputs: { files: ['node_modules/**'] },
450
445
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx-reapi",
3
- "version": "0.0.644",
3
+ "version": "0.0.646",
4
4
  "license": "MIT",
5
5
  "description": "Bazel Remote Execution API plugin for vx — remote cache (ActionCache + CAS) against NativeLink, BuildBuddy, Buildbarn or bazel-remote.",
6
6
  "keywords": [
@@ -39,7 +39,7 @@
39
39
  "access": "public"
40
40
  },
41
41
  "peerDependencies": {
42
- "@vzn/vx": "^0.0.644"
42
+ "@vzn/vx": "^0.0.646"
43
43
  },
44
44
  "repository": {
45
45
  "type": "git",
package/src/cache.ts CHANGED
@@ -96,12 +96,18 @@ export class ReapiRemoteCache {
96
96
  * hit vs miss. Costs one extra round trip, and only for a PREDICTED HIT:
97
97
  * a miss still answers in one call.
98
98
  */
99
- async has(hash: string): Promise<boolean> {
99
+ async has(hash: string): Promise<{ size: number; durationMs?: number } | null> {
100
100
  const result = await this.client.getActionResult(actionDigestFor(hash))
101
- if (result === null) return false
101
+ if (result === null) return null
102
102
  const file = result.output_files?.find((f) => f.path === ARTIFACT_PATH)
103
- if (file === undefined) return false
104
- return (await this.client.findMissingBlobs([file.digest])).length === 0
103
+ if (file === undefined) return null
104
+ if ((await this.client.findMissingBlobs([file.digest])).length > 0) return null
105
+ // The duration only when it rode inline: a CAS read for it is a round trip.
106
+ const durationMs = decodeDuration(result.stdout_raw)
107
+ return {
108
+ size: Number(file.digest.size_bytes),
109
+ ...(durationMs === undefined ? {} : { durationMs }),
110
+ }
105
111
  }
106
112
 
107
113
  /**