Bumps every @wrnexus package 0.8.4 -> 0.8.5 and adds the matching update migration. The migration is documentation only: moving off <Table> to <DataTable> and off the @wrnexus/ui main entry to @wrnexus/ui/registry are source changes no codemod can make safely. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@wrnexus/cache
Bounded in-memory/tag caching and HTTP response caching for WRNexusJS. Supports request deduplication, tag invalidation, ETags, fresh/stale states, and optional detached stale revalidation.
import { connectCacheInvalidation, TagCache, responseCache } from "@wrnexus/cache";
const cache = new TagCache({ ttlMs: 60_000, staleWhileRevalidateMs: 300_000 });
export default responseCache({ cache, tags: ["products"] });
TagCache bounds entries with LRU-style eviction, deduplicates concurrent
loaders, and prevents an invalidated in-flight loader from repopulating stale
data. Use lookup() when fresh/stale state matters, or getOrLoad() for
stampede-safe loading.
For multi-instance applications, connect the cache to any compatible pub/sub
bus (including @wrnexus/pubsub). Namespaces isolate applications sharing the
same broker. Local invalidation happens first and the returned promise confirms
cross-instance publication; failures remain visible to the caller.
import { connectCacheInvalidation, TagCache } from "@wrnexus/cache";
import { createPubSub } from "@wrnexus/pubsub";
import { redisDriver } from "@wrnexus/pubsub/redis";
const cache = new TagCache({ maxEntries: 10_000 });
const bus = createPubSub(redisDriver(process.env.REDIS_URL));
const invalidation = connectCacheInvalidation(cache, bus, {
namespace: "storefront-production",
onError: (error) => logger.error("cache invalidation failed", { error }),
});
await invalidation.invalidateTag("products");
await invalidation.delete("product:42");
// Unsubscribes this cache only; the shared bus remains owned by the app.
invalidation.close();
await bus.close();
Framework cache layers
CacheCoordinator keeps the four cache lifetimes explicit:
coordinator.request()creates request-only deduplication.coordinator.datacaches loader/query results.coordinator.componentcaches reusable rendered fragments.coordinator.pagecaches complete safe documents.
All cross-request layers are bounded, tag-aware, stale-while-revalidate capable,
stampede-safe, and expose withLock() for exclusive per-key work. inspect()
returns metadata without cached values. Development applications expose that
inspection through the Cache panel and GET /__wrnexus/cache.
Pages and components can opt in declaratively:
cache {
scope = "page"
strategy = "stale-while-revalidate"
ttl = "5m"
stale = "10m"
tags = ["catalog", "marketing"]
vary = ["tenant", "language"]
}
Omit scope to cache named loader data. Use scope = "page" for full-page
caching. Component policies cache their rendered fragment. Authenticated user
and tenant identities are always included automatically; page caches also vary
by language, theme, and accent. Add header names or cookie:name entries for
other application-specific variation. Pages containing CSRF forms are never
stored in the full-page cache.