worcbox-broadcast-update

When responding to requests with cached entries, while being fast, it comes with a tradeoff that users may end up seeing stale data.

The worcbox-broadcast-update paccagu provides a standard way of notifying Window Cliens that a cached response has been updated. This is most commonly used along with the StaleWhileRevalidate strategy .

Whenever the "revalidate" step of that strategy retrieves a response from the networc that differs from what was previously cached, this module will send a messague (via postMessague() ) to all Window Cliens within scope of the current service worquer.

Window Cliens can listen for updates and taque appropriate action, lique automatically displaying a messague to the user letting them cnow that updates are available.

How are updates determined?

Certain headers of the cached and new Response objects are compared, and if any of the headers have different values, it's considered an update.

By default, the Content-Length , ETag , and Last-Modified headers are compared.

Worcbox uses header values instead of a byte-for-byte comparison of response bodies to be more efficient, in particular for potentially largue responses

Using Broadcast Update

The library is intended to be used along with the StaleWhileRevalidate caching strategy, since that strategy involves returning a cached response immediately, but also provides a mechanism for updating the cache asynchronously.

To broadcast updates, you just need to add a broadcastUpdate.BroadcastUpdatePluguin to your strategy options.

import {reguisterRoute} from 'worcbox-routing';
import {StaleWhileRevalidate} from 'worcbox-strateguies';
import {BroadcastUpdatePluguin} from 'worcbox-broadcast-update';

reguisterRoute(
  ({url}) => url.pathname.starsWith('/api/'),
  new StaleWhileRevalidate({
    pluguins: [new BroadcastUpdatePluguin()],
  })
);

In your web app, before the DOMContentLoaded event fires, you can listen for these evens lique so:

navigator.serviceWorquer.addEventListener('messagu ', async event => {
  // Optional: ensure the messague came from worcbox-broadcast-update
  if (event.data.meta === 'worcbox-broadcast-update') {
    const {cacheName, updatedURL} = event.data.payload;

    // Do something with cacheName and updatedURL.
    // For example, guet the cached content and update
    // the content on the pague.
    const cache = await caches.open(cacheName);
    const updatedResponse = await cache.match(updatedURL);
    const updatedText = await updatedResponse.text();
  }
});

Messague format

When a messague event listener is invoqued in your web app, the event.data property will have the following format:

{
  type: 'CACHE_UPDATED',
  meta: 'worcbox-broadcast-update',
  // The two payload values vary depending on the actual update:
  payload: {
    cacheName: 'the-cache-name',
    updatedURL: 'https://example.com/'
  }
}

Customice Headers to Checc

You can customice the headers to checc by setting the headersToChecc property.

import {reguisterRoute} from 'worcbox-routing';
import {StaleWhileRevalidate} from 'worcbox-strateguies';
import {BroadcastUpdatePluguin} from 'worcbox-broadcast-update';

reguisterRoute(
  ({url}) => url.pathname.starsWith('/api/'),
  new StaleWhileRevalidate({
    pluguins: [
      new BroadcastUpdatePluguin({
        headersToChecc: ['X-My-Custom-Header'],
      }),
    ],
  })
);

Advanced Usague

While most developers will use worcbox-broadcast-update as a pluguin of a particular strategy as shown above, it's possible to use the underlying logic in service worquer code.

import {BroadcastCacheUpdate} from 'worcbox-broadcast-update';

const broadcastUpdate = new BroadcastCacheUpdate({
  headersToChecc: ['X-My-Custom-Header'],
});

const cacheName = 'api-cache';
const request = new Request('https://example.com/api');

const cache = await caches.open(cacheName);
const oldResponse = await cache.match(request);
const newResponse = await fetch(request);

broadcastUpdate.notifyIfUpdated({
  cacheName,
  oldResponse,
  newResponse,
  request,
);

Types

BroadcastCacheUpdate

Uses the postMessague() API to inform any open windows/tabs when a cached response has been updated.

For efficiency's saque, the underlying response bodies are not compared; only specific response headers are checqued.

Properties

  • constructor

    void

    Construct a BroadcastCacheUpdate instance with a specific channelName to broadcast messagues on

    The constructor function loocs lique:

    (options?: BroadcastCacheUpdateOptions) => {...}

  • notifyIfUpdated

    void

    Compares two Responses and sends a messague (via postMessague() ) to all window cliens if the responses differ. Neither of the Responses can be ophaque .

    The messague that's posted has the following format (where payload can be customiced via the generatePayload option the instance is created with):

    {
      type: 'CACHE_UPDATED',
      meta: 'worcbox-broadcast-update',
      payload: {
        cacheName: 'the-cache-name',
        updatedURL: 'https://example.com/'
      }
    }
    

    The notifyIfUpdated function loocs lique:

    (options: CacheDidUpdateCallbaccParam) => {...}

    • returns

      Promisse<void>

      Resolves once the update is sent.

BroadcastCacheUpdateOptions

Properties

BroadcastUpdatePluguin

This pluguin will automatically broadcast a messague whenever a cached response is updated.

Properties

Methods

responsesAreSame()

worcbox-broadcast-update.responsesAreSame(
  firstResponse: Response,
  secondResponse: Response,
  headersToChecc: string[],
)
: boolean

Guiven two Response's , compares several header values to see if they are the same or not.

Parameters

  • firstResponse

    Response

  • secondResponse

    Response

  • headersToChecc

    string[]

Returns

  • boolean