Three scheduled jobs keep this site’s feeds current: the social feed every hour, the Mello Zone community articles every six hours and the Twitch live status every ten minutes. Each one ran the full test suite, built the site, committed its data file to the repository and waited for Cloudflare to deploy the result. A feed update was a site release.
That coupling has a cost beyond build minutes. On 24 October an unrelated lockfile problem stopped Cloudflare from deploying anything, and the same failing checks stopped every feed job before it could commit, so the feeds froze along with the code. The live status page cannot be more current than a build either, however often it is polled.
The plan is to keep the latest snapshot of each feed in Workers KV and have the site’s Worker render it into pages as they are served. This release lands the first two pieces. Nothing a visitor sees changes yet.
One renderer for feed cards
The social cards on the home and work pages and the Mello Zone cards on the community page were
rendered by two build-time modules. The Worker will need to render the same cards from newer data,
and two copies of that markup would drift. The markup now lives once, in
src/lib/feed-render.js, which has no file-system or network code so both the build and the
Worker can use it, and the build modules call it.
The move changes no output. The site was built before and after it, and all 262 files in the build are byte-for-byte identical.
A read path for the latest snapshots
The Worker gains a FEEDS KV namespace and an endpoint at /api/feeds/social,
/api/feeds/community and /api/feeds/live. It serves the newest snapshot from KV, and says so
in an x-feed-source: kv header.
A snapshot from KV will be rendered into public pages without a build in between, so it is held to the same rules the build applies before it is served: a supported version, a real and non-future generation date, at least one item, HTTPS links, a known platform for social posts, Mello Zone as the origin of community articles, images either cached on this site or, for community articles, linked from Mello Zone, with dimensions, and a true-or-false live flag. A snapshot that fails any of them is logged and ignored.
When KV is empty, unreachable, not bound, or holding a snapshot that fails those rules, the
endpoint serves the snapshot packaged in the build instead, labelled x-feed-source: build. It
answers 503 only if neither is usable. Responses carry an ETag and answer a matching
If-None-Match with 304, are cached for 60 seconds (social), 5 minutes (community) or 30 seconds
(live), and are marked noindex.
Until the pollers are switched over in the next part, KV is empty and the endpoint serves the packaged snapshots.
Verification
- A build before the renderer moved and a build after it were compared file by file: all 262 files identical.
tools/test-feeds-api.mjs, new innpm run test:worker, covers serving from KV, the fallback for empty, unreachable and unbound KV, eight kinds of snapshot that must be refused, a community article from another origin, a non-boolean live flag, 304 revalidation, HEAD, and the 405, 404 and 503 answers. Disabling the social item checks on purpose made it fail, as it should.npm run test:delivery187 of 187,npm run build40 pages,npm run test:worker84 of 84,npm run test:built293 of 293, the release audit across 39 canonical pages, andnpm run check:feeds.npx wrangler deploy --dry-runresolves theFEEDSbinding.- Against
npm run preview, with local KV: all three feeds answered from the build while KV was empty, a seeded social snapshot was served from KV, and a seeded snapshot with a plain-HTTP link was refused in favour of the build.npm run test:browserreported 0 failures across 39 routes andnpm run test:a11y0 failures across 88 checks. tools/indexing-surface.jsonwas rewritten deliberately; its only change is this entry’s route.
