LearnUse it in your language
Caching and refresh
Cache manifests by checksum, refresh rules on a schedule, and keep serving the last good rules.
A checksum names a ruleset exactly, so caching is safe: the same checksum is the same rules. Clients revalidate with the ETag. Services hold a ruleset in memory and reload it on a schedule; a reload that fails keeps the last good rules, and an unchanged checksum swaps nothing.
What to do. Fetch the client manifest with createManifestClient. It revalidates with the ETag (the checksum), keeps working from its cache while the server is down, and can refresh on a schedule (mode: 'ttl', 'permanent', refreshCron).
The code.
// step: caching
// The browser fetches the client manifest from the rule server and revalidates it with its ETag.
// A stand-in for the server here: it answers 200 with an ETag, 304 when nothing changed, then goes down.
const manifest = rules.manifest('client');
let up = true;
const fakeFetch = async (url, init) => {
if (!up) throw new Error('connection refused');
const etag = `"${manifest.checksum}-client"`;
const hit = new Headers(init?.headers).get('If-None-Match') === etag;
console.log('GET', new URL(url).pathname, '->', hit ? 304 : 200);
return hit ? new Response(null, { status: 304, headers: { ETag: etag } }) : Response.json(manifest, { headers: { ETag: etag } });
};
const manifests = createManifestClient({ baseUrl: 'https://rules.example', fetch: fakeFetch, mode: 'revalidate' });
await manifests.get('acme.payments.transfer'); // 200: fetched
await manifests.get('acme.payments.transfer'); // 304: the cached copy
up = false;
const offline = await manifests.get('acme.payments.transfer'); // server down: the cached copy, marked stale
console.log('offline:', offline.checksum === manifest.checksum, 'stale:', manifests.stale('acme.payments.transfer')?.error.message);
manifests.close();
// end: cachingRun it.
npm ci && npm run build # at the repository root, once
node site/learn/languages/typescript-node/tour.mjsThe output.
GET /rulesets/acme.payments.transfer/manifest -> 200
GET /rulesets/acme.payments.transfer/manifest -> 304
offline: true stale: connection refused