@vzn/vx-history-server 0.0.650 → 0.0.651

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/PROTOCOL.md CHANGED
@@ -25,8 +25,9 @@ is `403`. A token writes its own ref (`refs/heads/<branch>`; a
25
25
  `head_ref`; a `merge_group` run,
26
26
  `refs/heads/gh-readonly-queue/<base>/pr-<n>-<sha>`, its base branch); a
27
27
  `pull_request_target`, `issue_comment` or `workflow_run` run reads only,
28
- and so does a GitLab merge request pipeline whose `source_project_path` (GitLab 19.5+)
29
- does not name its own project. A query names its
28
+ and so does a GitLab run whose `source_project_path` or `job_project_path`
29
+ names another project, or a merge request pipeline naming no source project
30
+ (GitLab before 19.5). A query names its
30
31
  repository; a token of another is `403`. A server whose `READ_ACCESS`
31
32
  is `public` takes a query with no token for a repository `ALLOW` names;
32
33
  an upload with none is `403`.
@@ -57,7 +58,7 @@ the row's. A row not reported for `TIMING_DAYS` (30) is deleted.
57
58
 
58
59
  One request a run: `POST /v1/timings/query` with
59
60
  `{ "issuer", "repository", "refs": ["refs/heads/feature", "refs/heads/main"], "hashes": [ … ] }`,
60
- 1 to 8 refs and up to 10 000 hashes: each hash's row in the first ref
61
+ 1 to 8 refs of up to 512 characters each and up to 10 000 hashes: each hash's row in the first ref
61
62
  named that holds one. A hash none holds is absent. The numbers are the
62
63
  scheduler's as they are:
63
64
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx-history-server",
3
- "version": "0.0.650",
3
+ "version": "0.0.651",
4
4
  "license": "MIT",
5
5
  "description": "The task timings a vx scheduler asks for, one folded row per task, that you host: on Bun with SQLite, on Cloudflare Workers with D1, or as a Docker image.",
6
6
  "keywords": [
@@ -45,7 +45,7 @@
45
45
  "miniflare: tests/worker.test.ts runs src/worker.ts in workerd with D1, as Workers deploy it."
46
46
  ],
47
47
  "dependencies": {
48
- "@vzn/vx-devtools": "0.0.650"
48
+ "@vzn/vx-devtools": "0.0.651"
49
49
  },
50
50
  "repository": {
51
51
  "type": "git",
package/src/worker.ts CHANGED
@@ -2,11 +2,20 @@
2
2
  // `wrangler.jsonc` deploys it; ALLOW, AUDIENCE, READ_ACCESS and TIMING_DAYS
3
3
  // are vars in it.
4
4
 
5
- import { errorJson, oidcTokenAuth, parseAllow } from '@vzn/vx-devtools'
5
+ import {
6
+ cachedFetchJson,
7
+ errorJson,
8
+ type KeysCache,
9
+ oidcTokenAuth,
10
+ parseAllow,
11
+ } from '@vzn/vx-devtools'
6
12
  import { timingDaysOf } from './days.js'
7
13
  import { createHistoryServer } from './server.js'
8
14
  import { type Db, sqliteStore } from './store.js'
9
15
 
16
+ /** The data center's cache (Workers Cache API). */
17
+ declare const caches: { default: KeysCache }
18
+
10
19
  /** The parts of the Workers runtime this file uses, so it needs no types package. */
11
20
  interface D1Statement {
12
21
  bind(...values: unknown[]): D1Statement
@@ -51,6 +60,16 @@ function d1Db(d1: D1Database): Db {
51
60
  /** One handler per isolate and settings: the schema is made once per isolate. */
52
61
  let made: { key: string; handle: (req: Request) => Promise<Response> } | undefined
53
62
 
63
+ /**
64
+ * The issuer's keys through the data center's cache: a fresh isolate read
65
+ * GitHub on its first token, and one slow answer failed it 502 (2026-10-29).
66
+ * `caches.default` is read at each call, as the bucket is per request.
67
+ */
68
+ const edgeKeys = cachedFetchJson({
69
+ match: (url) => caches.default.match(url),
70
+ put: (url, res) => caches.default.put(url, res),
71
+ })
72
+
54
73
  export default {
55
74
  async fetch(req: Request, env: Env): Promise<Response> {
56
75
  // A deploy's mistake: unbound, capabilities answered and every upload failed.
@@ -83,6 +102,7 @@ export default {
83
102
  authorize = oidcTokenAuth({
84
103
  allow,
85
104
  readAccess: env.READ_ACCESS,
105
+ fetchJson: edgeKeys,
86
106
  // jose matches aud exactly: a pasted newline refused every
87
107
  // token as the wrong audience.
88
108
  ...(env.AUDIENCE ? { audience: env.AUDIENCE.trim() } : {}),