CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-workbox-expiration

A service worker helper library that expires cached responses based on age or maximum number of entries.

Pending
Overview
Eval results
Files

expiration-plugin.mddocs/

Plugin-Based Expiration

Workbox plugin for seamless integration with caching strategies, providing automatic expiration based on age and entry limits during cache operations.

Capabilities

ExpirationPlugin Class

Workbox plugin that automatically handles expiration during cache operations.

/**
 * Plugin for workbox-strategy to regularly enforce limits on age and/or number of cached requests.
 * Can only be used with workbox-strategy instances that have a custom cacheName property set.
 * Cannot be used to expire entries in strategies that use the default runtime cache name.
 */
class ExpirationPlugin {
  /**
   * Constructs a new ExpirationPlugin. At least one of maxEntries or maxAgeSeconds must be provided.
   * @param config - Plugin configuration options
   */
  constructor(config: ExpirationPluginOptions = {});

  /**
   * Deletes all underlying Cache instances associated with this plugin and
   * removes metadata from IndexedDB. Preferable to calling caches.delete() directly
   * when using cache expiration as it ensures IndexedDB cleanup.
   */
  deleteCacheAndMetadata(): Promise<void>;

  // Plugin lifecycle methods (automatically called by Workbox strategies)
  cachedResponseWillBeUsed?: WorkboxPlugin['cachedResponseWillBeUsed'];
  cacheDidUpdate?: WorkboxPlugin['cacheDidUpdate'];
}

interface ExpirationPluginOptions {
  /** Maximum number of entries to cache. Entries used least recently will be removed first. */
  maxEntries?: number;
  /** Maximum age of an entry in seconds before it's treated as stale and removed. */
  maxAgeSeconds?: number;
  /** CacheQueryOptions that will be used when calling delete() on the cache. */
  matchOptions?: CacheQueryOptions;
  /** Whether to opt this cache into automatic deletion if available storage quota has been exceeded. */
  purgeOnQuotaError?: boolean;
}

Usage Examples:

import { ExpirationPlugin } from "workbox-expiration";
import { StaleWhileRevalidate, CacheFirst } from "workbox-strategies";

// Basic usage with a caching strategy
const strategy = new StaleWhileRevalidate({
  cacheName: "api-cache",
  plugins: [
    new ExpirationPlugin({
      maxEntries: 50,
      maxAgeSeconds: 60 * 60 * 24, // 24 hours
    }),
  ],
});

// With automatic quota error cleanup
const limitedStrategy = new CacheFirst({
  cacheName: "images",
  plugins: [
    new ExpirationPlugin({
      maxEntries: 100,
      maxAgeSeconds: 60 * 60 * 24 * 30, // 30 days
      purgeOnQuotaError: true,
    }),
  ],
});

// Custom cache query options
const customStrategy = new StaleWhileRevalidate({
  cacheName: "custom-cache",
  plugins: [
    new ExpirationPlugin({
      maxEntries: 25,
      matchOptions: {
        ignoreSearch: true,
        ignoreVary: true,
      },
    }),
  ],
});

// Manual cleanup of all caches managed by plugin
const plugin = new ExpirationPlugin({
  maxEntries: 50,
  maxAgeSeconds: 60 * 60,
});

// Later, when needed
await plugin.deleteCacheAndMetadata();

Plugin Lifecycle Behavior

The plugin automatically integrates with Workbox strategy lifecycle:

cachedResponseWillBeUsed:

  • Triggered when a cached response is about to be returned
  • Checks response freshness using HTTP Date header if maxAgeSeconds is configured
  • Returns null for expired responses (causing strategy to fetch fresh)
  • Updates entry timestamp and triggers background expiration

cacheDidUpdate:

  • Triggered when an entry is added or updated in the cache
  • Updates the entry's timestamp for accurate LRU tracking
  • Runs expiration process to remove old/excess entries

Error Conditions

Constructor Errors:

  • Throws WorkboxError with code max-entries-or-age-required if neither maxEntries nor maxAgeSeconds is provided

Runtime Errors:

  • Throws WorkboxError with code expire-custom-caches-only if used with the default runtime cache name

Implementation Details

  • Automatically manages CacheExpiration instances for each cache
  • Integrates with registerQuotaErrorCallback when purgeOnQuotaError is enabled
  • Performs lightweight HTTP Date header validation before IndexedDB checks
  • Uses dontWaitFor pattern to avoid blocking cache operations during expiration
  • Handles service worker event lifecycle with event.waitUntil() when available

Quota Error Handling

When purgeOnQuotaError is enabled:

  • Registers a callback with Workbox core quota error handling
  • Automatically calls deleteCacheAndMetadata() when storage quota is exceeded
  • Helps prevent persistent quota exceeded errors by cleaning up expired data

Install with Tessl CLI

npx tessl i tessl/npm-workbox-expiration

docs

cache-expiration.md

expiration-plugin.md

index.md

tile.json