Chore/cloudflare - #1502
Merged
Merged
Conversation
Cloudflare PreviewURL: https://effectwebsite-websiteworker-pr-1502-yu4eeuc5au3ma34a.matechs.workers.dev Built from commit 8de80c6. This comment updates automatically with each deployment. |
IMax153
marked this pull request as ready for review
August 21, 2026 19:32
IMax153
enabled auto-merge (squash)
August 21, 2026 19:32
IMax153
force-pushed
the
chore/cloudflare
branch
from
August 31, 2026 15:33
c5088bc to
f8d32c8
Compare
IMax153
disabled auto-merge
August 31, 2026 18:27
IMax153
force-pushed
the
chore/cloudflare
branch
from
September 3, 2026 16:05
2dc51d8 to
2667b2d
Compare
Turn on Astro 7.2's experimental `incrementalBuild` and give every prerendered route a cache key, so a build re-renders only the pages whose data or code actually changed. A fully cached build drops from 1m33s to 25s, and the remainder is Vite bundling rather than page rendering. Astro disables the cache when `build.concurrency > 1`, so concurrency goes to 1. That costs ~11s on a cold build (1m22s to 1m33s), which the warm case pays back many times over. `cacheDir` moves out of `node_modules` to `apps/web/.astro-cache` so CI can restore and save it without caching the dependency tree. Two things blocked the API reference from ever hitting the cache. Every module page baked the global Effect git revision into its `og:image` URL, and the content loader mixes the same revision into `entry.digest` — both change on every snapshot, so all 1,090 pages changed even when their module did not. Pages now use their own `reflectionDigest`, which busts a module's social card exactly when that module's docs change. Those pages never call `render()`, so Astro's automatic content-entry tracking does not cover them and the cache key is the only correctness mechanism. Keying on the module alone would be wrong: each page also renders a package-scoped sidebar, a version-wide package switcher, version-wide `module:Foo` link resolution, and a v3/v4 switcher. The digests in features/api-reference/cache-key.ts cover each of those and are derived from metadata only, which moves far less often than reflection content. Verified a fully cached build is byte-identical to a full render across 1,793 files, and that the existing link verifier passes against the restored HTML. Targeted checks: one blog post body invalidates 1 page, one docs sidebar label invalidates the 110 pages of that version and no v3 page, one reflection invalidates 1 of 1,090 API pages, and editing DocShell.astro invalidates docs and API pages but no blog post. `astro build --force` is unreachable because alchemy invokes the build itself, so the escape hatch is discarding the cache directory, exposed as a `force_full_build` input on the production workflow. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TEsRhqRu7xjNbZNjAm1vbj
A preview stage that sits idle longer than its store's TTL cannot deploy:
`SynchronizePreviewSearch` fails with `404 Stores with identifiers '...'
not found`, taking `WebsiteWorker` and the preview comment down with it.
Preview stores are created with `expiresAfter: { anchor: "last_active_at",
days: 7 }`, so Mixedbread deletes them on its own while alchemy state
keeps holding the id. `reconcile` already recovers from a missing store,
but it never ran, because `diff` decided purely from input equality — and
the inputs of an untouched PR do not change. The store noop'd and the
following sync inherited a dead id.
`diff` now confirms the store still exists before returning noop, and
routes to `reconcile` when it is gone. Non-404 failures still surface
rather than being swallowed, matching `read` and `reconcile`.
This only shows up on a PR that both predates the TTL and touches a path
`SearchChanges` watches, which is why it stayed latent.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TEsRhqRu7xjNbZNjAm1vbj
The previous commit made `diff` notice an expired store, but the deploy still failed on the same dead id: alchemy resolves attributes listed in `provider.stables` straight from previous state, without waiting for `reconcile`. `SynchronizePreviewSearch` therefore started 100ms before `PreviewSearchStore` finished updating and inherited the id of the store that had just been replaced. `id` is only stable when the store is updated in place. When it has to be recreated the replacement gets a new id, so the diff now returns an empty `stables`, which Plan treats as authoritative over the provider list and holds dependents until the real output lands. Move the existence check ahead of the input comparison too, so a run that changes props against a store that has already expired takes the same path rather than reporting `id` as stable. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TEsRhqRu7xjNbZNjAm1vbj
Moving `cacheDir` out of `node_modules` relocated the content layer's `data-store.json`, but `openGraphMetadataPlugin` still resolved the old default, so the build died bundling the SSR open-graph route: NotFound: FileSystem.readFile (apps/web/node_modules/.astro/data-store.json) The config now derives `cacheDir` once and hands the same URL to both astro and the plugin, so the two cannot drift again. This only reproduced on a clean checkout: any machine that had built before the move still had a stale store at the old path, which is exactly where it was being read from. Cover it with a test that drives the plugin's load hook against a temporary cacheDir, since neither of the existing gates would have caught it — `astro check` does not bundle, and the SSR route that pulls in the virtual module is only reachable through a real adapter. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TEsRhqRu7xjNbZNjAm1vbj
IMax153
force-pushed
the
chore/cloudflare
branch
from
September 4, 2026 14:11
90129cf to
ced6e06
Compare
IMax153
enabled auto-merge (squash)
September 4, 2026 14:31
IMax153
disabled auto-merge
September 4, 2026 14:31
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.
Type
Description
Migrates the Effect Website from Vercel to Cloudflare
Related