Skip to content

feat(core): purge Workers Caching on content/chrome writes#1380

Draft
scottbuscemi wants to merge 1 commit into
mainfrom
feat/workers-cache-purge
Draft

feat(core): purge Workers Caching on content/chrome writes#1380
scottbuscemi wants to merge 1 commit into
mainfrom
feat/workers-cache-purge

Conversation

@scottbuscemi

Copy link
Copy Markdown
Collaborator

What does this PR do?

Adds optional purging of Cloudflare Workers Caching on content and chrome writes.

Workers Caching (the platform cache enabled with cache: { enabled: true } in Wrangler) sits in front of the Worker and serves HITs without running it — so a long Cache-Control max-age on public pages would otherwise serve stale HTML until the TTL lapses. When configured, EmDash now purges that cache on writes, so edits appear without waiting for TTL.

Off by default. Enable with the edgeCache adapter:

import { workersCache } from "@emdash-cms/cloudflare";

emdash({
	database: d1({ binding: "DB" }),
	edgeCache: workersCache(), // mode: "purgeEverything" (default)
});

and enable the platform cache in wrangler.jsonc ("cache": { "enabled": true }) with a cacheable Cache-Control on public responses.

v1 uses purgeEverything: any content or chrome write (content create/update/delete/publish/unpublish/schedule, settings, taxonomies, menus, bylines, slug-change redirects) triggers a single cache.purge({ purgeEverything: true }). Purges are deferred via after() (never block the write response) and coalesced (a bulk import collapses into one purge, respecting the zone purge rate limit). On non-Cloudflare runtimes or older runtimes without cache.purge, it's a safe no-op. Tag-based purging (purge only affected pages) is planned behind the same config.

Independent of, and complementary to, the Astro route cache (cloudflareCache()) and the data/object cache: Workers Caching (HTML, in front) → Worker → data cache → DB. Existing sites are unaffected until they opt in.

Closes #

Type of change

  • Bug fix
  • Feature (requires maintainer-approved Discussion)
  • Refactor (no behavior change)
  • Translation
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes (or targeted tests for my change) — core edge-cache + cloudflare edge-purge suites (10 passed)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • User-visible strings in the admin UI are wrapped for translation (if applicable). n/a — no admin UI strings.
  • I have added a changeset (if this PR changes a published package)
  • New features link to an approved Discussion: https://github.com/emdash-cms/emdash/discussions/... Draft — Discussion to be linked before review.

AI-generated code disclosure

  • This PR includes AI-generated code — model/tool: Claude Opus 4.8 (opencode)

Screenshots / test output

core edge-cache.test.ts — 6 passed
cloudflare edge-purge.test.ts — 4 passed
pnpm lint — 0 diagnostics; pnpm typecheck — clean

Cloudflare Workers Caching (cache: { enabled: true } in Wrangler) sits
in front of the Worker and serves HITs without running it, so a long
Cache-Control max-age on public pages would serve stale HTML after edits
until the TTL lapsed — EmDash had no hook into that platform cache.

Add an optional, opt-in edge-cache invalidator that purges Workers
Caching on writes, the HTML-layer analogue of the existing data-cache
invalidation. Off by default; enable with the `edgeCache` adapter:

    import { workersCache } from "@emdash-cms/cloudflare";
    emdash({ database: d1({ binding: "DB" }), edgeCache: workersCache() });

- Core: EdgeCacheInvalidator interface + descriptor + virtual:emdash/edge-cache
  module + EmDashConfig.edgeCache. invalidateEdgeCache() is coalesced (one
  purge per tick) and deferred via after() (never blocks the write), and
  no-ops when unconfigured.
- Cloudflare: workersCache() config + a runtime backend that calls
  cache.purge({ purgeEverything: true }) from cloudflare:workers, with
  feature-detection so it's a safe no-op on Node/older runtimes. The purge
  runs from the default entrypoint (where writes and public pages live), so
  it hits the page cache.
- Wired at the write seams: content (ContentRepository), menus and bylines
  (their repositories), and piggybacked onto the existing settings,
  taxonomy, and redirect/slug invalidations.

v1 uses purgeEverything; tag-based purging is planned behind the same
config. Independent of cloudflareCache() (Astro route cache) and the
data/object cache.

Tests: purge is deferred and coalesced, fires on content create and on a
settings write, no-ops when unconfigured; the CF backend calls
cache.purge and no-ops when cache.purge is unavailable.
@changeset-bot

changeset-bot Bot commented Jun 8, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9cd41d1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 14 packages
Name Type
emdash Minor
@emdash-cms/cloudflare Minor
@emdash-cms/sandbox-workerd Patch
@emdash-cms/fixture-perf-site Patch
@emdash-cms/perf-demo-site Patch
@emdash-cms/cache-demo-site Patch
@emdash-cms/admin Minor
@emdash-cms/auth Minor
@emdash-cms/blocks Minor
@emdash-cms/gutenberg-to-portable-text Minor
@emdash-cms/x402 Minor
create-emdash Minor
@emdash-cms/auth-atproto Patch
@emdash-cms/plugin-embeds Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 8, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
emdash-playground 9cd41d1 Jun 08 2026, 05:13 AM

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
docs 9cd41d1 Jun 08 2026, 05:10 AM

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Scope check

This PR changes 631 lines across 20 files. Large PRs are harder to review and more likely to be closed without review.

If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs.

See CONTRIBUTING.md for contribution guidelines.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-demo-cache 9cd41d1 Jun 08 2026, 05:11 AM

@pkg-pr-new

pkg-pr-new Bot commented Jun 8, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@1380

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@1380

@emdash-cms/auth-atproto

npm i https://pkg.pr.new/@emdash-cms/auth-atproto@1380

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@1380

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@1380

@emdash-cms/contentful-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/contentful-to-portable-text@1380

emdash

npm i https://pkg.pr.new/emdash@1380

create-emdash

npm i https://pkg.pr.new/create-emdash@1380

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@1380

@emdash-cms/plugin-cli

npm i https://pkg.pr.new/@emdash-cms/plugin-cli@1380

@emdash-cms/plugin-types

npm i https://pkg.pr.new/@emdash-cms/plugin-types@1380

@emdash-cms/registry-client

npm i https://pkg.pr.new/@emdash-cms/registry-client@1380

@emdash-cms/registry-lexicons

npm i https://pkg.pr.new/@emdash-cms/registry-lexicons@1380

@emdash-cms/sandbox-workerd

npm i https://pkg.pr.new/@emdash-cms/sandbox-workerd@1380

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@1380

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@1380

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@1380

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@1380

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@1380

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@1380

@emdash-cms/plugin-field-kit

npm i https://pkg.pr.new/@emdash-cms/plugin-field-kit@1380

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@1380

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@1380

commit: 9cd41d1

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

PR template validation failed

Please fix the following issues by editing your PR description:

See CONTRIBUTING.md for the full contribution policy.

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Overlapping PRs

This PR modifies files that are also changed by other open PRs:

This may cause merge conflicts or duplicated work. A maintainer will coordinate.

@ascorbic

ascorbic commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Is this just the same as the Astro route cache? withastro/astro#16335

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants