release: WRNexusJS 0.8.0
This commit is contained in:
Vendored
+65
-1
@@ -3,7 +3,71 @@
|
||||
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.
|
||||
|
||||
```ts
|
||||
import { TagCache, responseCache } from "@wrnexus/cache";
|
||||
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.
|
||||
|
||||
```ts
|
||||
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.data` caches loader/query results.
|
||||
- `coordinator.component` caches reusable rendered fragments.
|
||||
- `coordinator.page` caches 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:
|
||||
|
||||
```wrn
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user