Rule Cascade
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.

site/learn/languages/typescript-node/tour.mjs
// 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: caching

Run it.

Run it
npm ci && npm run build      # at the repository root, once
node site/learn/languages/typescript-node/tour.mjs

The output.

Output
GET /rulesets/acme.payments.transfer/manifest -> 200
GET /rulesets/acme.payments.transfer/manifest -> 304
offline: true stale: connection refused
Course overview