1921 Commits

Author SHA1 Message Date
James Anderson 8eccc20163 feat(cache): support self-contained response store (#3246) 2026-09-14 10:32:46 +01:00
James Anderson 71b7c82692 chore(cache): polish workers response store package (#3245) 2026-09-14 10:32:45 +01:00
James Anderson 601e098d60 perf(cache): reduce response store Durable Object load (#3213)
* perf(cache): reduce response store Durable Object load

* refactor(cache): remove response store compatibility shims

* fix(cache): batch response store purge parameters

* fix(cache): preserve coalesced response store writes

* fix(cache): preserve concurrent response store writes

* fix(cache): fence response store tag purges

* fix(cache): order tag purge fences durably

* fix(cache): migrate response store metadata schema

* fix(cache): preserve coalesced purge semantics

* fix(cache): isolate coalesced cleanup failures

* fix(cache): harden coalesced response store writes

* fix(cache): isolate coalesced purge failures

* fix(cache): isolate post-commit alarm failures

* fix(cache): continue cleanup after alarm errors

* fix(cache): fence expired response store cleanup

* fix(cache): retain durable cleanup ownership

* fix(cache): retain cleanup fences across deletion
2026-09-14 10:32:45 +01:00
James Anderson fddaf338f8 fix(cache): align response store HTML identity (#3209) 2026-09-14 10:32:45 +01:00
James Anderson b6b799eb47 feat(cache): lazily resolve response store tag expirations (#3203) 2026-09-14 10:32:44 +01:00
James Anderson 2c9eaf59a1 feat(cache): stream response-store cache misses (#3200) 2026-09-14 10:32:44 +01:00
James Anderson d496941605 feat(cache): seed RSC during response-store warmup (#3196) 2026-09-14 10:32:44 +01:00
James Anderson 3f14cb1039 refactor(cache): normalize RSC requests after routing (#3194) 2026-09-14 10:32:43 +01:00
James Anderson e32eb6a3d7 feat(cache): add Workers Response Store POC (#3192) 2026-09-14 10:32:43 +01:00
James Anderson 13e7d9ce5b fix(test): pin React in deploy suite fixtures (#3229) 2026-09-11 11:02:35 +01:00
James Anderson f103e80700 test: parallelize the integration suite (#3201) 2026-09-09 18:17:57 +01:00
Govind yadav 609d2227f3 test(app-router): cover shallow history traversal regressions (#2829)
Co-authored-by: James <james@eli.cx>
2026-09-09 10:17:37 +00:00
JamesbbBriz 56096fba75 fix(isr): ignore interception context on HTML renders (#2915)
* fix(isr): ignore interception context on HTML renders

* test(isr): cover interception cache writes

* test(isr): cover split response-stage interception context

---------

Co-authored-by: James <james@eli.cx>
2026-09-09 11:09:20 +01:00
JamesbbBriz 2e79661650 test(workerd): cover bundled dependency import.meta.url (#2910)
* fix(workerd): guard fileURLToPath(import.meta.url) for bundled modules

workerd does not provide import.meta.url for bundled modules (it is
undefined), so libraries that resolve paths from it at module init —
e.g. findUp-style package.json discovery — crash with "The path argument
must be of type string or an instance of URL". Node never sees this
(import.meta.url is always defined there).

Adds a narrow transform plugin that guards only the two crashing call
shapes — fileURLToPath(import.meta.url) and createRequire(import.meta.url)
— rewriting the argument to `import.meta.url ?? "file:///"`. All other
import.meta.url usage is untouched, and the guard is a no-op on Node.

Verified under local workerd (same binary as real Workers): unguarded
fileURLToPath(undefined) crashes module init; guarded, fileURLToPath("file:///")
yields "/" and findUp terminates safely. End-to-end: a full CMS stack
(Payload) passes its 25-check API suite with the app-level workaround
removed — 7 guard sites applied in the bundle, 0 missed.

* fix(workerd): unbounded filter window for annotated calls

Adversarial verification found the bounded 80-char window between the
callee and the argument silently misses calls separated by long block
comments (3+ lines), leaving them unguarded in real builds. Widen the
filter to an unbounded window — the AST handler remains authoritative,
so the cost is only an extra parseAst on false positives.

Adds a filter-level regression test for long-comment forms.

* test(workerd): add build integration coverage for the import-meta-url guard

Adds a fixture with a dependency that calls fileURLToPath(import.meta.url)
behind a long block comment (the window-escape shape), and a build-level
test asserting the guard lands in the emitted server bundle while no bare
call remains. Covers the filter+handler pipeline end to end — the unit
suite alone bypasses the filter gate.

* fix(workerd): cover annotated call filters

* fix(workerd): handle non-file import meta URLs

* test(workerd): cover bundled import.meta.url identity

---------

Co-authored-by: James <james@eli.cx>
2026-09-09 10:07:05 +00:00
pascoa-lab ecdfd64c7f test(link): ensure Enter activates focused links (#3183)
* fix(link): ensure Enter activates focused links

* test(link): remove ineffective Enter coverage

* test(link): cover native Enter activation

---------

Co-authored-by: James <james@eli.cx>
2026-09-09 09:59:30 +00:00
KeelTrace 53c3f26595 fix(app-router): dedupe next/dynamic module preloads (#3186)
* fix(app-router): dedupe next/dynamic module preloads

* test(app-router): cover module preload credentials

---------

Co-authored-by: James <james@eli.cx>
2026-09-09 10:49:35 +01:00
Lubomir Georgiev (Любомир Георгиев) 2bc9d542bc perf(cloudflare): cut KV data cache round trips from 3 to 2 per tagged hit (#3187)
* perf(cloudflare): cut KV data cache round trips

A cold get() made three sequential KV round trips: the entry, then the entry's
own tag markers, then the caller's soft-tag markers. Soft tags are known before
the entry read, so their markers now start with it, and the second hop reads
only the entry tags the first hop did not already cover. Markers go through KV's
bulk get() in chunks of 100, so a page with many tags costs one subrequest per
chunk instead of one per tag. A tagged hit now takes two round trips and an
untagged hit takes one.

Entry reads also gain an opt-in entryCacheTtlSeconds option that sets KV cacheTtl
on the entry key alone; it stays off by default because a colo that cached the
key can then serve a superseded value for that long. Tag markers never take it,
since a colo cache on a marker would hide a revalidateTag from that colo for the
same window.

* fix(cloudflare): stop a KV marker read failure from breaking a miss

- await the entry read alone, so a miss returns without the soft-tag batch and survives its failure
- attach a catch to the ignored marker promise to prevent an unhandled rejection
- check the locally cached entry tags before the second hop, which restores the short circuit the previous commit dropped
- correct the entryCacheTtlSeconds doc: markers keep the KV default cacheTtl of 60 s rather than always reaching the central store
- add a fail helper to the tracing KV double, with cases for the miss, hit, and cached invalidation paths

* fix(cloudflare): respect tagCacheTtlMs in the invalidation fast path

- check cached entry tags first, so a failed soft-tag batch cannot mask a known invalidation
- add requireFresh to _hasRevalidatedTag, so a pre-prime check ignores a marker past tagCacheTtlMs
- keep a marker written at or after the read start, so a detached prime cannot overwrite a newer revalidateTag
- snapshot the store at call time in the tracing KV double, so a held read cannot see a later write
- add four tests; all four fail against 7623ce3

* fix(cloudflare): keep speculative KV reads request-scoped

* fix(cloudflare): order concurrent KV tag primes

* fix(cloudflare): re-prime KV tags after cache reset

* fix(cloudflare): preserve KV tag validation across reset

* fix(cloudflare): avoid deleting newer KV entries

---------

Co-authored-by: James <james@eli.cx>
2026-09-09 10:39:42 +01:00
James Anderson 86afc11051 refactor(cache): delegate response policy to CDN adapters (#3191)
* refactor(cache): delegate response policy to CDN adapters

* fix(cache): keep adapter policy fail closed
2026-09-08 10:35:02 +01:00
Cameron ec4e0ea62f refactor(plugins): use ESTree types for AST transforms (#3172) 2026-09-08 10:10:31 +01:00
James Anderson bc606792e3 fix(cloudflare): restore bounded probe scheduling (#3171)
* fix(cloudflare): restore bounded probe scheduling

* fix(cloudflare): retry malformed cacheability probes

* fix(cloudflare): retry transient cacheability probes

* fix(cloudflare): remove probe scheduling barriers

* fix(cloudflare): preserve probe throughput and retry budgets

* fix(cloudflare): fill prunable probe slots

* fix(cloudflare): preserve probe no-progress timeout

* test(cloudflare): retain hung probe watchdog coverage
2026-09-07 21:48:30 +01:00
James Anderson 35af79106e fix(cloudflare): reduce staged CDN probe work (#3168)
* fix(cloudflare): reduce staged cacheability probes

* fix(cloudflare): isolate uncached response renders

* test(cloudflare): cover uncached entrypoint collisions

* fix(cloudflare): preserve i18n middleware probe scope

* fix(cloudflare): preserve purge routing in uncached renders

* fix(cloudflare): match runtime middleware probe paths

* fix(cloudflare): keep probe concurrency saturated

* fix(cloudflare): preserve encoded middleware probe paths

* fix(cloudflare): preserve websocket upgrade responses

* fix(cloudflare): preserve deferred probe route ownership

* fix(cache): preserve warmed responses on browser reload

* fix(cloudflare): preserve warmed cache on reload

* fix(cache): preserve App responses on browser reload

* test(cache): preserve full-stage coverage after reload parity
2026-09-07 21:48:30 +01:00
James Anderson f0b2f7b043 feat(build): support independently deployed worker stages (#3155)
* feat(build): support independently deployed worker stages

* fix(build): preserve array input entry names

* fix(build): preserve host inputs when emitting stages

* fix(build): isolate multi-stage server outputs

* fix(cache): reject unsupported HTTP stage variants

* docs(build): clarify shared transport variance

* refactor(cache): share staged Vary selectors

* fix(build): keep HTTP admission lazy

* test(build): cover remote-stage draft bypass

* fix(cache): key admitted HTTP response variants

* fix(build): colocate staged output sidecars

* fix(build): reuse published stage output type

* fix(build): reject classic multi-stage outputs

* fix(build): complete staged output validation

* test(build): cover commonjs stage output alias

* fix(build): colocate Pages stage sidecars
2026-09-07 21:48:29 +01:00
James Anderson 4e24e15651 docs(cloudflare): explain cached response entrypoint (#3154)
* docs(cloudflare): explain cached response entrypoints

* docs(cloudflare): distinguish private cache headers

* docs(cloudflare): clarify private gateway egress
2026-09-07 21:48:29 +01:00
James Anderson cf681a2e9b fix(cache): preserve staged cache invalidation parity (#3158)
* fix(cache): preserve response-stage invalidation parity

* test(cache): cover live tag invalidation
2026-09-07 21:48:29 +01:00
James Anderson e8eaec9f39 fix(cloudflare): prewarm routed response stages (#3153)
* fix(cloudflare): prewarm routed response stages

* test(cloudflare): own prewarm middleware fixtures

* test(cloudflare): cover config-personalized cache hits

* test(cloudflare): expose edge cache status mirrors

* test(cloudflare): cover cached Pages data isolation
2026-09-07 21:48:28 +01:00
James Anderson 9265f300cc feat(cloudflare): isolate cached response entrypoint (#3152)
* feat(cloudflare): isolate cached response entrypoint

* test(cloudflare): reuse generic stage facade coverage

* test(cloudflare): preserve composite CDN output config

* fix(cloudflare): track final shared response provenance

* fix(cloudflare): validate routed response artifacts

* test(build): follow response-stage sidecar closure

* test(build): validate response-stage manifest closure

* style(test): format stage closure assertion

* test(cache): assert uncached gateway policy for browser fetch

* fix(cloudflare): partition framework cache variants

* feat(cloudflare): expose entrypoint cache status

* fix(cloudflare): protect shared response provenance

* test(cloudflare): align local cache status mirrors

* test(cloudflare): align entrypoint gateway policy
2026-09-07 21:48:28 +01:00
James Anderson 91880b2e6d fix(build): preserve staged prerender routing (#3151)
* fix(build): preserve staged prerender routing

* fix(build): prerender the emitted application entry

* fix(build): preserve application entry across prerender workers

* fix(build): preserve nested prerender artifact roots

* fix(build): preserve nested server artifact roots

* fix(build): honor configured prerender output roots

* fix(build): keep staged prerender artifacts canonical
2026-09-07 21:48:27 +01:00
James Anderson d5392666ab feat(build): select adapter-owned worker stages (#3150)
* feat(build): select adapter-owned worker stages

* refactor(build): defer prerender entry resolver

* fix(build): keep staged activation self-contained

* fix(build): isolate every staged output member

* fix(build): exclude custom client environments from stages

* feat(build): publish selected worker stages

* test(build): assert staged exports when published

* fix(dev): keep multi-stage output build-only
2026-09-07 21:48:27 +01:00
James Anderson bcc8a47473 refactor(app): extract request stage (#3149)
* refactor(app): extract request stage

* fix(app): lazily register middleware data cache

* fix(app): keep request adapter facade lightweight

* fix(app): preserve staged header composition

* fix(app): resolve staged entry generators when introduced

* fix(build): emit App request-stage runtime sidecar

* test(build): require App runtime sidecar import

* fix(build): scope App runtime sidecar emission

* chore(build): register generated App request runtimes

* refactor(app): add request-stage middleware context
2026-09-07 21:48:27 +01:00
James Anderson 297863790c refactor(app): extract response-stage renderer (#3148)
* refactor(app): extract response-stage renderer

* fix(app): avoid replaying hybrid Pages headers

* fix(app): discard staged config content lengths

* fix(app): preserve the combined handler transition

* fix(app): preserve staged metadata draft transitions

* fix(app): export combined response-stage handler

* chore(build): register generated App response runtime

* refactor(app): defer request-stage middleware context
2026-09-07 21:48:26 +01:00
James Anderson 39a76919a3 refactor(app): define response-stage protocol (#3147)
* refactor(app): define response-stage protocol

* refactor(app): expose response contracts at first use
2026-09-07 21:48:26 +01:00
James Anderson 049f7e3628 refactor(pages): extract request stage (#3146)
* refactor(pages): extract request stage

* fix(pages): update server entry options call

* fix(pages): conservatively classify document mutation

* fix(pages): lazily register middleware data cache

* fix(pages): keep request adapter facade lightweight

* refactor(pages): conservatively bypass custom documents

* fix(pages): recompose shared page headers

* fix(pages): resolve staged entries when activated

* fix(build): finalize extracted Pages server output

* test(cache): prove Pages adapter initialization stays lazy

* test(build): defer staged export assertion
2026-09-07 21:48:25 +01:00
James Anderson f738ccf4b5 refactor(pages): extract response stage (#3145)
* refactor(pages): extract response stage

* fix(pages): avoid replaying staged response headers

* fix(pages): preserve staged cookie boundaries

* fix(pages): retain additive edge cookies

* fix(pages): bypass shared stages for WebSocket upgrades

* fix(pages): parse WebSocket upgrade tokens

* refactor(pages): expose response stage at first use

* fix(cache): classify Pages APIs by matched route kind

* test(cache): cover Pages admission without HTML accept

* test(cache): assert private Pages fallback policy

* test(cache): accept equivalent private fallback directives
2026-09-07 21:48:25 +01:00
James Anderson 5219f652ab refactor(cache): isolate response-stage admission (#3144)
* refactor(cache): isolate response-stage admission

* test(cache): cover staged policy helpers

* fix(cache): preserve provider policy during admission

* refactor(cache): unify staged response admission

* fix(cache): preserve provider route handler policies

* fix(cache): normalize Pages API admission at its owner
2026-09-07 21:48:25 +01:00
James Anderson 1db2669a89 refactor(cache): defer adapter initialization (#3143)
* refactor(cache): defer adapter initialization

* feat(cache): lazily load request-stage data adapters

* feat(cache): expose lazy data adapter capability

* types(cache): declare request-stage adapter facade
2026-09-07 21:48:24 +01:00
James Anderson 3fb6a51a59 feat(build): define adapter-owned worker stages (#3142)
* feat(build): define adapter-owned worker stages

* docs(build): require vary-aware stage transports

* docs(cache): keep probe contracts adapter-neutral

* refactor(build): defer staged output publication
2026-09-07 21:48:24 +01:00
James Anderson 80c5f59078 chore(deps): update Cloudflare Workers tooling (#3082)
* chore(deps): update Cloudflare Workers tooling

* fix(deps): repair tooling lockfile
2026-09-07 21:48:23 +01:00
dependabot[bot] 9b251303bb chore(deps): bump voidzero-dev/setup-vp from 1.18.0 to 1.19.0 (#3188)
Bumps [voidzero-dev/setup-vp](https://github.com/voidzero-dev/setup-vp) from 1.18.0 to 1.19.0.
- [Release notes](https://github.com/voidzero-dev/setup-vp/releases)
- [Commits](https://github.com/voidzero-dev/setup-vp/compare/1b32467adbe183473499fd9d5d372c3ed9641754...49c3e4e92c52e7f8392712a9267bbe71c5ab30e5)

---
updated-dependencies:
- dependency-name: voidzero-dev/setup-vp
  dependency-version: 1.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-07 21:04:50 +01:00
Cameron e91f3bd6b4 refactor(lint): use typescript for Oxlint plugins (#3170)
* chore(lint): type local Oxlint plugins

* fix(lint): track local plugins in Knip

* type resolved
2026-09-03 14:38:46 +01:00
dependabot[bot] f60afed4fb chore(deps): bump zizmorcore/zizmor-action from 0.6.2 to 0.6.3 (#3129)
Bumps [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) from 0.6.2 to 0.6.3.
- [Release notes](https://github.com/zizmorcore/zizmor-action/releases)
- [Commits](https://github.com/zizmorcore/zizmor-action/compare/3dc1ecc9bcb9e94e9b2c709687979e1298497054...70fb788f84895a7701f5643d103d587e460b5c99)

---
updated-dependencies:
- dependency-name: zizmorcore/zizmor-action
  dependency-version: 0.6.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-03 11:01:50 +01:00
James Anderson 13af970f62 feat(cloudflare): summarize CDN warmup by route (#3163)
* feat(cloudflare): summarize CDN warmup by route

* refactor(cloudflare): align CDN warm report columns
2026-09-03 11:01:26 +01:00
James Anderson a6931c0716 fix(cloudflare): wait for per-route version propagation (#3164) 2026-09-02 17:44:11 +01:00
James Anderson 9d16574de1 fix(cache): resolve CDN admission from matched route kind (#3160)
* fix(cache): resolve CDN admission from matched route kind

* test(cache): harden staged warmup verification

* test(cache): preserve default warmup coverage

* test(cache): verify reuse after regional warm misses

* test(cache): prove canonical one-pass warm requests

* test(cache): separate encoded edge variants

* test(cache): preserve native warmup logs
2026-09-02 16:59:14 +01:00
James Anderson 35344dd0b3 test(cloudflare): cover late-dynamic HTML isolation (#3159) 2026-09-02 14:35:15 +01:00
github-actions[bot] 9cf754fcc2 chore: version packages (beta) (#3074)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@vinext/cloudflare@1.0.0-beta.7 vinext@1.0.0-beta.9
2026-09-02 12:10:10 +00:00
James Anderson 8370369383 fix(cloudflare): finalize CDN version metadata output (#3137)
* fix(cloudflare): finalize CDN version metadata output

* test(cloudflare): validate generated version metadata deployment

* fix(cloudflare): finalize metadata from primary output
2026-09-02 12:55:40 +01:00
James Anderson 9d94dcdd5f fix(cloudflare): support explicit CDN warm targets (#3138) 2026-09-01 22:16:55 +00:00
James Anderson 6a18dbe3ff fix(cloudflare): harden post-deploy readiness checks (#3136) 2026-09-01 22:43:02 +01:00
James Anderson 04c4de7f81 fix(cloudflare): restore web CDN warmup deploy (#3135) 2026-09-01 22:00:50 +01:00
James Anderson 2a08fb7913 fix(cloudflare): classify CDN cacheability per concrete route (#3115)
* fix(cloudflare): scale cacheability probing

* fix(cloudflare): preserve cache policy probe identities

* test(cache): cover conditional response vetoes

* fix(cache): match header policy sources exactly

* perf(cache): compute probe safety per pattern

* fix(build): omit empty route ownership metadata

* fix(cloudflare): classify cacheability per concrete path

* fix(cloudflare): retain zero-path static fallbacks

* test(cloudflare): cover on-demand static fallbacks

* fix(cloudflare): admit custom vary cache variants

* fix(cloudflare): keep wildcard vary private

* fix(cloudflare): reject wildcard vary during probing

* fix(cloudflare): reject empty Cache Components params

* fix(cloudflare): scope empty params validation to pages

* fix(cloudflare): remove cacheability response size limits

* fix(cloudflare): bound completed cache admission

* fix(cloudflare): release failed admission captures

* fix(cloudflare): honor staged readiness retries

* fix(cloudflare): retain probed manifest in dist

* fix(cloudflare): probe staged readiness without rendering

* fix(cloudflare): verify staged readiness response

* fix(cloudflare): reserve staged readiness endpoint

* fix(cloudflare): relax cacheability manifest bounds

* perf(cloudflare): avoid duplicate deployment status check
2026-09-01 21:25:26 +01:00