DEVEX-1485: Consolidate cache profiles ahead of Cloudflare compatibility work - #25
Merged
Merged
Conversation
Groundwork for Cloudflare compatibility. The Cloudflare target can't run
Cache Components (its staged-render path corrupts streamed HTML on
workerd), so that build caches at the fetch level instead. To keep the two
implementations as close as possible, the parts that don't depend on
*where* caching attaches now live in the same module, with the same name
and shape, in both.
lib/bc-api-client/cache-profiles.ts holds the lifetime profiles and the
enable switch. cacheLife accepts an inline { stale, revalidate, expire }
object as well as a named profile, so the profiles no longer need a
cacheLife block in next.config.ts — call sites select one with
cacheLife(cacheProfile("standard")).
Also renames CACHE_COMPONENTS_ENABLED to CACHE_ENABLED, matching the
Cloudflare branch, where there is no cacheComponents flag for the name to
refer to. CHANGELOG keeps the old name, since that entry records a
released version.
Caching behavior is unchanged. Verified against unmodified main: same
upstream request counts with caching on (a repeat page load adds none) and
off (it re-fetches all three), and the same 12 routes still build as PPR.
CacheLifetimeProfile types both the profile constants and cacheProfile's return value. It requires all three fields, unlike Next's own CacheLife where each is optional: every profile here sets all of them, and leaving one implicit would silently inherit Next's default rather than this app's intent. CACHE_PROFILE_STANDARD and CACHE_PROFILE_EXTENDED let call sites select a profile by constant instead of repeating a bare string. PROFILES is keyed by those constants and checked with `satisfies`, so CacheProfile still derives from the map and an unknown name remains a type error. No behavior change: same durations, same enable switch, same 12 PPR routes, same upstream request counts with caching on and off.
The profiles and the enable switch aren't specific to the BigCommerce API client. On this branch the `use cache` boundaries that select a profile include component render boundaries and fetchStoreExtensionStatus, which reads the credentials store rather than calling the API at all, so lib/bc-api-client was the wrong home for it. Import paths and the prose references in next.config.ts, .env.example, and docs/ARCHITECTURE.md updated to match. No behavior change.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
Description
Groundwork for hosting this app on Cloudflare Workers. Cloudflare can't run Cache Components: the PPR staged-render path corrupts streamed HTML on
workerdvia@opennextjs/cloudflare— chunks of the RSC flight payload get emitted outside their<script>wrapper and render as raw JSON on the page. That's tracked upstream in opennextjs-cloudflare#1225 and #1318, and no released adapter version fixes it. A Cloudflare build therefore has to cache at the fetch level instead.This PR changes no caching behavior. It moves the parts that don't depend on where caching attaches into one module with the same name and shape it has on the Cloudflare branch, so the two implementations differ only where they genuinely must.
Consolidates the profiles and the enable switch into
lib/cache/cache-profiles.ts.cacheLifeaccepts an inline{ stale, revalidate, expire }object as well as a named profile, so the durations no longer need acacheLifeblock innext.config.ts. Eachuse cacheboundary now selects one withcacheLife(cacheProfile(CACHE_PROFILE_STANDARD)), andisCachingEnabledlives beside the profiles it gates rather than in the Next config. The module sits underlib/cacherather thanlib/bc-api-clientbecause it describes the app's caching policy, not that client — one of the boundaries selecting a profile isfetchStoreExtensionStatus, which reads the credentials store and never calls the API.Renames
CACHE_COMPONENTS_ENABLEDtoCACHE_ENABLED. The old name described thecacheComponentsflag it used to work around by overriding profiles. It now simply switches caching on and off, and the Cloudflare branch has no such flag for the name to refer to.CHANGELOG.mdkeeps the old name, since that entry records a released version.Adds a real profile interface and name constants.
CacheLifetimeProfiletypes the profile constants andcacheProfile's return value. All three fields are required, unlike Next's ownCacheLifewhere each is optional: every profile here sets all three, and leaving one implicit would silently inherit Next's default rather than this app's intent.CACHE_PROFILE_STANDARD/CACHE_PROFILE_EXTENDEDlet call sites name a profile by constant instead of repeating a bare string;PROFILESis keyed by those constants and checked withsatisfies, soCacheProfilestill derives from the map and an unknown name remains a type error.Every
"use cache: remote"directive, everycacheTag/updateTagcall, and all four duration values are unchanged.Verification
tsc --noEmit— cleaneslint src/— 0 errors (11 pre-existing warnings inpostgres-driver-loader.unavailable.ts, unrelated)next build— succeeds; all 12 PPR routes still build as◐, confirming Cache Components is untouchedType enforcement checked with a throwaway type-test: an unknown profile name and an incomplete profile object are both rejected
Behavioral equivalence against unmodified
main, measured side by side in a separate worktree:main(baseline)CACHE_ENABLED=true:/gift-certsreq 1 / repeat //customersCACHE_ENABLED=false: sameIdentical in every cell. (Counts are upstream BigCommerce API requests. Note the app's own request logger runs inside Next's patched
fetch, so it also logs cache-served responses — hit/miss flags and sub-millisecond durations are the reliable signal, not raw log counts.)Follow-up
AGENTS.md, these changes still need replicating onto the progressive history viabcedu-lab-sync+validate-sync. Not included here.feature/gift-certs-manager-cloudflare-no-remote-cache, which is not part of this PR.