0
# Workbox Broadcast Update
1
2
A service worker helper library that uses the Broadcast Channel API to announce when a cached response has been updated. This library enables applications to automatically notify users when cached content is refreshed, providing real-time feedback about content freshness in cache-first strategies.
3
4
## Package Information
5
6
- **Package Name**: workbox-broadcast-update
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install workbox-broadcast-update`
10
11
## Core Imports
12
13
```typescript
14
import {
15
BroadcastCacheUpdate,
16
BroadcastCacheUpdateOptions,
17
BroadcastUpdatePlugin,
18
responsesAreSame
19
} from "workbox-broadcast-update";
20
```
21
22
For CommonJS:
23
24
```javascript
25
const {
26
BroadcastCacheUpdate,
27
BroadcastUpdatePlugin,
28
responsesAreSame
29
} = require("workbox-broadcast-update");
30
```
31
32
## Basic Usage
33
34
```typescript
35
import { BroadcastUpdatePlugin } from "workbox-broadcast-update";
36
import { StaleWhileRevalidate } from "workbox-strategies";
37
38
// Use as a plugin with Workbox strategies
39
const strategy = new StaleWhileRevalidate({
40
cacheName: "api-cache",
41
plugins: [
42
new BroadcastUpdatePlugin({
43
headersToCheck: ["etag", "last-modified"],
44
}),
45
],
46
});
47
48
// Direct usage for manual cache updates
49
import { BroadcastCacheUpdate } from "workbox-broadcast-update";
50
51
const broadcastUpdate = new BroadcastCacheUpdate({
52
headersToCheck: ["content-length", "etag"],
53
notifyAllClients: true,
54
});
55
56
await broadcastUpdate.notifyIfUpdated({
57
cacheName: "my-cache",
58
oldResponse,
59
newResponse,
60
request,
61
event,
62
});
63
```
64
65
## Architecture
66
67
Workbox Broadcast Update is built around several key components:
68
69
- **BroadcastCacheUpdate**: Core class that compares responses and sends broadcast messages
70
- **BroadcastUpdatePlugin**: Workbox plugin that integrates with caching strategies
71
- **Response Comparison**: Efficient header-based comparison to detect content changes
72
- **Broadcast Channel API**: Uses native web APIs to communicate between service worker and main thread
73
- **Client Targeting**: Supports both all-client and single-client notification modes
74
75
The library uses header comparison rather than full response body comparison for efficiency, making it suitable for high-traffic applications.
76
77
## Capabilities
78
79
### Cache Update Broadcasting
80
81
Core functionality for detecting and broadcasting cache updates using the Broadcast Channel API.
82
83
```typescript { .api }
84
class BroadcastCacheUpdate {
85
/**
86
* Creates a new BroadcastCacheUpdate instance
87
* @param options - Configuration options for the broadcast update behavior
88
*/
89
constructor(options?: BroadcastCacheUpdateOptions);
90
91
/**
92
* Compares two responses and broadcasts an update message if they differ
93
* @param options - Parameters containing old/new responses and cache metadata
94
* @returns Promise that resolves when broadcast is complete
95
*/
96
notifyIfUpdated(options: CacheDidUpdateCallbackParam): Promise<void>;
97
}
98
99
interface BroadcastCacheUpdateOptions {
100
/** Headers to check for differences (default: ['content-length', 'etag', 'last-modified']) */
101
headersToCheck?: string[];
102
/** Custom function to generate message payload */
103
generatePayload?: (options: CacheDidUpdateCallbackParam) => Record<string, any>;
104
/** Whether to notify all clients or just the requesting client (default: true) */
105
notifyAllClients?: boolean;
106
}
107
108
interface CacheDidUpdateCallbackParam {
109
/** Name of the cache being updated */
110
cacheName: string;
111
/** The previous cached response */
112
oldResponse?: Response;
113
/** The new response being cached */
114
newResponse: Response;
115
/** The request that triggered the update */
116
request: Request;
117
/** The event that triggered the update */
118
event?: ExtendableEvent;
119
}
120
```
121
122
### Workbox Plugin Integration
123
124
Plugin that automatically broadcasts cache updates when integrated with Workbox caching strategies.
125
126
```typescript { .api }
127
class BroadcastUpdatePlugin implements WorkboxPlugin {
128
/**
129
* Creates a new BroadcastUpdatePlugin instance
130
* @param options - Configuration options passed to internal BroadcastCacheUpdate
131
*/
132
constructor(options?: BroadcastCacheUpdateOptions);
133
134
/**
135
* Workbox plugin lifecycle method triggered when cache entries are updated
136
* @param options - Cache update parameters from Workbox
137
*/
138
cacheDidUpdate: WorkboxPlugin['cacheDidUpdate'];
139
}
140
141
interface WorkboxPlugin {
142
cacheDidUpdate?: (param: CacheDidUpdateCallbackParam) => Promise<void> | void;
143
}
144
```
145
146
### Response Comparison Utility
147
148
Utility function for comparing Response objects based on specific headers.
149
150
```typescript { .api }
151
/**
152
* Compares two Response objects by checking specified headers
153
* @param firstResponse - First response to compare
154
* @param secondResponse - Second response to compare
155
* @param headersToCheck - Array of header names to check for differences
156
* @returns True if responses are considered the same, false otherwise
157
*/
158
function responsesAreSame(
159
firstResponse: Response,
160
secondResponse: Response,
161
headersToCheck: string[]
162
): boolean;
163
```
164
165
## Types
166
167
### Configuration Options
168
169
Configuration interface for BroadcastCacheUpdate behavior.
170
171
```typescript { .api }
172
interface BroadcastCacheUpdateOptions {
173
/** Headers to check for differences (default: ['content-length', 'etag', 'last-modified']) */
174
headersToCheck?: string[];
175
/** Custom function to generate message payload */
176
generatePayload?: (options: CacheDidUpdateCallbackParam) => Record<string, any>;
177
/** Whether to notify all clients or just the requesting client (default: true) */
178
notifyAllClients?: boolean;
179
}
180
```
181
182
## Message Format
183
184
When a cache update is detected, the library broadcasts a message with the following structure:
185
186
```typescript { .api }
187
interface BroadcastMessage {
188
/** Always 'CACHE_UPDATED' */
189
type: "CACHE_UPDATED";
190
/** Always 'workbox-broadcast-update' */
191
meta: "workbox-broadcast-update";
192
/** Update details - customizable via generatePayload option */
193
payload: {
194
/** Name of the updated cache */
195
cacheName: string;
196
/** URL of the updated resource */
197
updatedURL: string;
198
/** Additional custom fields from generatePayload function */
199
[key: string]: any;
200
};
201
}
202
```
203
204
## Error Handling
205
206
The library includes built-in error handling for common scenarios:
207
208
- **Invalid Response Types**: Throws `WorkboxError` for non-Response objects in development
209
- **Missing Required Parameters**: Validates `cacheName`, `newResponse`, and `request` parameters
210
- **Missing Headers**: Returns `true` (no update) when none of the specified headers are present
211
- **Safari Compatibility**: Includes timeout handling for Safari's postMessage limitations
212
213
## Usage Examples
214
215
### Basic Plugin Usage
216
217
```typescript
218
import { BroadcastUpdatePlugin } from "workbox-broadcast-update";
219
import { registerRoute } from "workbox-routing";
220
import { StaleWhileRevalidate } from "workbox-strategies";
221
222
// Register a route with automatic broadcast updates
223
registerRoute(
224
({ request }) => request.destination === "document",
225
new StaleWhileRevalidate({
226
cacheName: "pages-cache",
227
plugins: [
228
new BroadcastUpdatePlugin({
229
headersToCheck: ["etag", "last-modified"],
230
}),
231
],
232
})
233
);
234
```
235
236
### Custom Payload Generation
237
238
```typescript
239
import { BroadcastCacheUpdate } from "workbox-broadcast-update";
240
241
const broadcastUpdate = new BroadcastCacheUpdate({
242
generatePayload: ({ cacheName, request, newResponse }) => ({
243
cacheName,
244
updatedURL: request.url,
245
timestamp: Date.now(),
246
responseSize: newResponse.headers.get("content-length"),
247
contentType: newResponse.headers.get("content-type"),
248
}),
249
});
250
```
251
252
### Single Client Notification
253
254
```typescript
255
import { BroadcastUpdatePlugin } from "workbox-broadcast-update";
256
257
// Only notify the client that made the original request
258
const plugin = new BroadcastUpdatePlugin({
259
notifyAllClients: false,
260
});
261
```
262
263
### Manual Response Comparison
264
265
```typescript
266
import { responsesAreSame } from "workbox-broadcast-update";
267
268
const hasChanged = !responsesAreSame(
269
oldResponse,
270
newResponse,
271
["etag", "content-length", "last-modified"]
272
);
273
274
if (hasChanged) {
275
console.log("Content has been updated!");
276
}
277
```
278
279
### Listening for Updates in Client Code
280
281
```javascript
282
// In your main thread (window) code
283
navigator.serviceWorker.addEventListener("message", (event) => {
284
if (
285
event.data.type === "CACHE_UPDATED" &&
286
event.data.meta === "workbox-broadcast-update"
287
) {
288
const { cacheName, updatedURL } = event.data.payload;
289
290
// Show notification to user
291
showUpdateNotification(`New content available for ${updatedURL}`);
292
293
// Optionally reload the page
294
if (confirm("New content is available. Reload now?")) {
295
window.location.reload();
296
}
297
}
298
});
299
```