Skip to content

feat(sdk): CDN bundle preload mode for @contentrain/query#70

Merged
ABB65 merged 1 commit into
mainfrom
feat/query-bundle-preload
Jul 10, 2026
Merged

feat(sdk): CDN bundle preload mode for @contentrain/query#70
ABB65 merged 1 commit into
mainfrom
feat/query-bundle-preload

Conversation

@ABB65

@ABB65 ABB65 commented Jul 10, 2026

Copy link
Copy Markdown
Member

Summary

Adds an opt-in bundle preload mode to the CDN transport: createContentrain({ bundle: true }) fetches _bundle/{locale}.json (one artifact containing every JSON model for the locale, produced by Studio #125) and serves all collection/singleton/dictionary/document-index reads from memory. Per-render cost drops from N content fetches + include waterfall to 1 conditional GET.

Default off → non-breaking minor (6.1.1 → 6.2.0, changeset included).

Design

  • Existing fetch<T>() body moved verbatim to _networkFetch<T>() — per-path ETag cache, If-None-Match/304 and ContentrainError semantics unchanged. The bundle request itself revalidates via 304 for free.
  • _ensureBundle(locale): inflight dedupe (concurrent first reads → one request), revalidateMs freshness window (default 60s), stale-path eviction when a fresh bundle drops entries, missing state on 404/invalid/version !== "1" with retry after the window.
  • Scope guard: only content/, documents/, meta/ paths consult the bundle — _manifest.json, models/*, _media_manifest.json have no locale segment and would otherwise trigger spurious _bundle/... requests. Doc bodies (bySlug()) and withMeta() stay per-path, as speced.
  • Non-i18n content/{model}/data.json bundle keys resolve via defaultLocale; revalidateMs: 0 means revalidate-on-every-fetch; client.preload(locale?) gives eager SSR warmup and is a network-free false when bundle mode is off.
  • Query classes, _resolveIncludes, forms/conversation clients untouched — everything routes through transport.fetch(), so include resolution is covered automatically.

Rollout

Safe to publish before Studio #125: while the CDN returns 404 for _bundle/..., behavior is identical to per-path fetching today. Full win starts after the first bundle-producing rebuild.

Testing

  • 15 new tests in tests/cdn/bundle-preload.test.ts: single-GET priming, out-of-scope fallback, 404 → retry after revalidateMs, 304 keeps primed data, eviction of removed paths, unknown-version rejection, data.json → defaultLocale mapping, concurrent inflight dedupe, manifest/models guard, preload() semantics (found/missing/mode-off), revalidateMs: 0.
  • Full suite: 250/250 passing, oxlint 0/0, tsc --noEmit clean, pnpm build (dts) clean.
  • Docs: README + docs/packages/sdk.md gained a "Bundle Preload" section; CDN-vs-Local tables updated.

🤖 Generated with Claude Code

createContentrain({ bundle: true }) fetches _bundle/{locale}.json once and
serves all content/document-index/dictionary reads from memory, collapsing
per-render fetch waterfalls into a single conditional GET. Default off —
non-breaking minor.

Key decisions:
- Bundle logic scoped to content/, documents/, meta/ paths; manifest and
  models/* paths never derive a locale, avoiding spurious _bundle requests
- Existing fetch() body moved verbatim to _networkFetch(); per-path ETag
  cache, 304 handling and ContentrainError semantics unchanged, so the
  bundle request itself revalidates via 304 for free
- Stale primed paths evicted when a fresh bundle drops them; 404/invalid/
  network error → transparent per-path fallback retried after revalidateMs
- revalidateMs: 0 supported (revalidate every fetch); non-i18n data.json
  entries resolve via defaultLocale
- client.preload(locale?) for eager SSR warmup; concurrent first reads
  dedupe into one inflight bundle request

Tests: 15 new cases in tests/cdn/bundle-preload.test.ts covering priming,
out-of-scope fallback, 404 retry, 304 revalidation, eviction, version
guard, data.json locale mapping, inflight dedupe, manifest guard, preload
semantics and revalidateMs: 0. Full suite: 250 passing, oxlint/tsc clean.
@netlify

netlify Bot commented Jul 10, 2026

Copy link
Copy Markdown

Deploy Preview for contentrain-ai ready!

Name Link
🔨 Latest commit d8caad3
🔍 Latest deploy log https://app.netlify.com/projects/contentrain-ai/deploys/6a50d103fea97300087a17c7
😎 Deploy Preview https://deploy-preview-70--contentrain-ai.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@ABB65
ABB65 merged commit c754eaa into main Jul 10, 2026
6 checks passed
@ABB65
ABB65 deleted the feat/query-bundle-preload branch July 10, 2026 11:10
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 10, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant