@devxcommerce/bff-core
v2.1.0
Published
Schema-agnostic primitives shared across every brand's BFF. No Hono, no brand-specific Strapi / Shopify schema — just the infrastructure that every brand reuses unchanged.
Readme
@devxcommerce/bff-core
Schema-agnostic primitives shared across every brand's BFF. No Hono, no brand-specific Strapi / Shopify schema — just the infrastructure that every brand reuses unchanged.
Full API reference:
docs/reference/core-api.md. Architecture:docs/architecture.md(core is the "read / write / invalidate" layer). Key ADRs: 0002, 0006, 0009, 0013.
What's here
- Cache (
cache.ts) —cached()with SWR + singleflight + envelope{ d, r, w };cachedWithMeta()for handlers that need{ data, status, refreshedAt }. Cache presets live indocs/reference/cache-presets.md. - Tags (
tags.ts) —tagFor,tagForSingleton,extractTags(walks response trees emitting per-entity tags on cache write). - Invalidation (
cache.ts+ Redis SETs) —invalidateTags(tags)(DEL for unpublish/delete) andmarkTagsStale(tags)(rewrite envelopes withr = 0for publish, per ADR-0013). - Cascade engine (
cascade.ts,snapshot.ts,webhook.ts) —computeCascade+handleStrapiWebhook; persistent per-entity relation snapshots (ADR-0007) power bidirectional cascade (ADR-0008) onentry.publish/entry.unpublish/entry.delete. - Strapi transport (
strapi-client.ts) —initStrapi({ apiUrl, apiToken, concurrency })+strapiGraphQL()with AbortController timeout +p-limitconcurrency gate. - Shopify transport (
shopify-client.ts) —initShopify(config)+shopifyGraphQL(); identifier helpers inshopify-identifiers.ts. hydrateShopify(hydrate-shopify.ts) — walks a response tree and pairs Product / Collection nodes as{ strapi, shopify }via the brand's registered fetchers (ADR-0009). Called by brands'ok()helpers.- Registry (
registry.ts,types.ts) —createRegistry(BrandConfig)loads entity declarations for the cascade engine. - Redis singleton + Pino logger (
redis.ts,logger.ts) —initRedis,getRedis,setLogger,getLogger. Tests callinitRedisin their setup andFLUSHDBbetween each.
Using it
Brands import from @devxcommerce/bff-core:
import {
cached, cachedWithMeta, tagFor, extractTags,
initStrapi, strapiGraphQL, initShopify, shopifyGraphQL,
hydrateShopify, handleStrapiWebhook, createRegistry,
initRedis, setLogger,
} from '@devxcommerce/bff-core'Brand-local code (Hono routes, response helpers, per-brand Strapi / Shopify queries) lives in apps/<brand>/bff/, never here.
Tests
cd packages/bff-core
bun test # 130 tests, no env needed
bun test --coverageRedis runs from docker compose up -d in the repo root; tests connect to localhost:6380.
