Cache fetch (next.revalidate)
fetch(url, { next: { revalidate: 10, tags: ["echo-demo"] } }) côté serveur met en cache la réponse amont pendant 10 secondes. L'horodatage externe s'actualise à chaque rechargement ; le receivedAt interne issu du fetch mis en cache reste figé pendant la fenêtre de fraîcheur.
Résultat
Externe (direct): 2026-09-06T03:48:24.459Z
receivedAt mis en cache: 2026-09-06T03:48:24.485Z
Réponse JSON complète
{"method":"GET","path":"/api/echo","query":{"key":"fetch-cache-demo"},"headers":{"user-agent":"ureq/2.12.1","content-type":null},"body":null,"receivedAt":"2026-09-06T03:48:24.485Z"}Fonctionnement
Le polyfill fetch dans l'hôte V8 transmet options.next à __httpFetch, qui consulte bext_core::cache::fetch_cache::FetchCache avant de toucher le réseau. En cas de HIT, l'enveloppe JSON mise en cache est retournée directement. En cas de MISS, l'appel amont s'exécute et la réponse est stockée sous hash(url, method, body), indexée par chaque tag dans next.tags.
revalidateTag(tag) de @bext-stack/framework/cache appelle __bextRevalidateTag sur l'hôte, qui parcourt l'index des tags et supprime chaque entrée marquée avec cette chaîne. La propagation inter-workers via le cadre PURGE existant est une suite ; aujourd'hui l'invalidation est locale au processus.
import { revalidateTag } from "@bext-stack/framework/cache";
// Fetch with cache config — response is stored for 10 s,
// indexed under the tag "echo-demo" for targeted invalidation.
const r = await fetch("/api/echo?key=demo", {
next: { revalidate: 10, tags: ["echo-demo"] },
});
const data = await r.json();
// Elsewhere — drop every cached entry tagged "echo-demo".
revalidateTag("echo-demo");