Cache the assembled packument output in KV#37
Merged
Conversation
Void does not edge-cache the Worker response (confirmed: the packument carries no cf-cache-status), so the ~440KB packument was re-assembled and re-serialized on every request, the dominant per-request CPU + memory cost. Cache the assembled body in KV, keyed by the refs-index etag plus a hash of the static env refs. getConfiguredRefsWithEtag exposes the R2 index etag; the handler reads refs+etag first, checks the cache, and on a hit serves the stored string directly (no rebuild, no 440KB stringify, no per-ref meta reads). Any ref mutation rewrites the index so the etag changes, the key changes, and the entry is invalidated with no explicit purge; R2 is strongly consistent read-after-write, so a just-published preview appears on the very next request. The envHash covers deploy-time ref changes (KV persists across deploys); a 60s TTL bounds npm stable-version drift (preview freshness comes from the etag, not the TTL). Stores the raw string (not via kvCached) so a hit serves without a parse + re-stringify round-trip.
e20c327 to
ecc6697
Compare
The handler hand-rolled the KV get-or-compute-then-put-with-TTL + degrade-on-error pattern that kvCached already factors, just for a raw string instead of JSON (to avoid a parse + re-stringify of the ~440KB body on hits). Add a kvCachedText sibling next to kvCached and route the output cache through it: the inline try/catch read + write blocks collapse into one call, the assembly becomes the fetcher closure, and the KV degrade policy + warn-message convention now live in one place for both cache variants.
fengmk2
added a commit
that referenced
this pull request
Jul 1, 2026
Stacked on #37 (base `cache-packument-output`; retargets to `main` once #37 merges). Merge order: #37 → this. ## Why Refs are registered dynamically now (the publish action calls `/-/refs` + `/-/publish` → R2 index), so the static `VITE_PLUS_PREVIEW_REFS` var is redundant for the actual preview flow. Its only remaining roles were a never-expiring default ref and a bootstrap for the deploy tooling, and neither needs a production config var. ## What - **Production:** drop the var from `config.ts`/`env.ts`, drop the env-merge in `getConfiguredRefs` (now R2-only), and simplify the F5 output-cache key to `pkgt/<name>/<etag>` (the env-refs hash is gone). Removed the orphaned `parseConfiguredPreviewRefsSafe`. - **Smoke test (the deploy gate):** no change needed beyond a comment , verified its checks don't depend on a registered ref (the packument check passes on npm's stable versions; download/HEAD resolve any sha without a registry lookup; `/-/refs` accepts an empty array). - **e2e:** derives the ref to install from the live `/-/refs` instead of the env var (skips if the bridge lists none). - **warm.mjs:** now a manual publish helper (`pnpm warm <sha>`); dropped from the `pnpm deploy` chain since there's nothing static to seed. - **Tests:** the suite registers its fixture ref (`commit.a832a55`) dynamically in `beforeEach`. ## Verify `tsc` clean, 76 tests pass, action bundle unaffected. Net −9 lines. The `rfcs/0001` design doc keeps its original references (historical record).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #36 (base
cache-npm-packument; will retarget tomainonce #36 merges).Why
Void doesn't edge-cache the Worker response (the packument carries no
cf-cache-status), so the ~440KB packument was re-assembled and re-serialized on every request , the dominant per-request CPU + memory cost. #36 removed the npm network fetch; this removes the rebuild.What
Cache the assembled body in KV, keyed by
pkgt/<name>/<refs-index-etag>.<envHash>:getConfiguredRefsWithEtagexposes the R2 index etag. The handler reads refs+etag first, checks the cache, and on a hit serves the stored string directly , no rebuild, no 440KB stringify, no per-ref meta reads.envHashcovers deploy-timeVITE_PLUS_PREVIEW_REFSchanges (KV persists across deploys); a 60s TTL bounds npm stable-version drift (preview freshness comes from the etag, not the TTL).kvCached, which stores parsed JSON) so a hit avoids a parse + re-stringify.Verify
tscclean, 76 tests pass , added an explicit "rebuilds on etag change" invalidation test; the existing publish/register→fetch tests also fail loudly if a stale body were served. The staging smoke gate exercises it on the real runtime before prod.