Browse docs

Runtime

Updates & Invalidation

ReactVanilla

Update checks compare per-namespace content hashes against a freshly fetched catalog.json — one ping detects every change. The hashes cover the compiled .dat bytes, so the check works offline and works in dev (the plugin serves the identical compiled catalog.json + .dat through the dev-server middleware).

The refresh cycle

const report = await Stift.pack.checkForUpdates(locale) // StaleNamespaceReport { stale, current }
await Stift.pack.refreshStale(locale) // re-fetch only stale namespaces

Production single-ping pattern — one catalog fetch diffed against every persisted locale (per-locale checkForUpdates costs one fetch each):

const reports = await Stift.pack.checkAllForUpdates()

Pattern: on load, boot from cache instantly (offline-first), then run checkAllForUpdates in the background; if the catalog is newer, refreshStale swaps the cached packs and re-renders. Guard with navigator.onLine + a cooldown so it only runs while online, not on every mount. Boot sequence: Offline & Persistence.

Honest statuses

Statuses that lie are bugs: install/refreshStale write __meta per namespace (a failed write never corrupts the previous good pack), wipes report error instead of fake idle, and byte-true bytesReceived/bytesTotal come from the catalog.

Freshness budget (optional)

createStift({ persisterTtlMs }) treats packs older than the budget as stale (reason: 'ttl-expired', still fully usable offline) and refreshes them in the background on activate. Content-hash staleness stays the real invalidation signal — TTL is cache hygiene.

Next