Bumps all 47 packages, the root manifest and the VS Code extension to 0.8.6, and rebuilds the editor compiler, language server and extension bundles that embed the version. The release carries the output delivery fix: camelCase outputs now reach parent bindings, and 18 components emit through output.* instead of hand-built CustomEvents. See the 0.8.6 migration entry for what changes for consumers. 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.