@serwist/broadcast-update 9.0.0-preview.9 → 9.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1 +1 @@
1
- This module's documentation can be found at https://developers.google.com/web/tools/workbox/modules/workbox-broadcast-update
1
+ This module's documentation can be found at https://serwist.pages.dev/docs/broadcast-update
package/dist/index.d.ts CHANGED
@@ -1,7 +1,3 @@
1
- import { BroadcastCacheUpdate } from "./BroadcastCacheUpdate.js";
2
- import { BroadcastUpdatePlugin } from "./BroadcastUpdatePlugin.js";
3
- import { CACHE_UPDATED_MESSAGE_META, CACHE_UPDATED_MESSAGE_TYPE, defaultHeadersToCheck } from "./constants.js";
4
- import { responsesAreSame } from "./responsesAreSame.js";
5
- export { BroadcastCacheUpdate, BroadcastUpdatePlugin, responsesAreSame, CACHE_UPDATED_MESSAGE_META, CACHE_UPDATED_MESSAGE_TYPE, defaultHeadersToCheck, };
6
- export type * from "./types.js";
1
+ export { BroadcastCacheUpdate, BroadcastUpdatePlugin, responsesAreSame, BROADCAST_UPDATE_DEFAULT_HEADERS as defaultHeadersToCheck, } from "serwist";
2
+ export type { BroadcastCacheUpdateOptions, BroadcastPayload, BroadcastPayloadGenerator, BroadcastMessage } from "serwist";
7
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC/G,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,0BAA0B,EAC1B,0BAA0B,EAC1B,qBAAqB,GACtB,CAAC;AAEF,mBAAmB,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,gCAAgC,IAAI,qBAAqB,GAC1D,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,2BAA2B,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,121 +1 @@
1
- import { SerwistError, logger, assert, resultingClientExists, timeout } from '@serwist/core/internal';
2
-
3
- const CACHE_UPDATED_MESSAGE_TYPE = "CACHE_UPDATED";
4
- const CACHE_UPDATED_MESSAGE_META = "serwist-broadcast-update";
5
- const defaultNotifyAllClients = true;
6
- const defaultHeadersToCheck = [
7
- "content-length",
8
- "etag",
9
- "last-modified"
10
- ];
11
-
12
- const responsesAreSame = (firstResponse, secondResponse, headersToCheck)=>{
13
- if (process.env.NODE_ENV !== "production") {
14
- if (!(firstResponse instanceof Response && secondResponse instanceof Response)) {
15
- throw new SerwistError("invalid-responses-are-same-args");
16
- }
17
- }
18
- const atLeastOneHeaderAvailable = headersToCheck.some((header)=>{
19
- return firstResponse.headers.has(header) && secondResponse.headers.has(header);
20
- });
21
- if (!atLeastOneHeaderAvailable) {
22
- if (process.env.NODE_ENV !== "production") {
23
- logger.warn("Unable to determine where the response has been updated " + "because none of the headers that would be checked are present.");
24
- logger.debug("Attempting to compare the following: ", firstResponse, secondResponse, headersToCheck);
25
- }
26
- return true;
27
- }
28
- return headersToCheck.every((header)=>{
29
- const headerStateComparison = firstResponse.headers.has(header) === secondResponse.headers.has(header);
30
- const headerValueComparison = firstResponse.headers.get(header) === secondResponse.headers.get(header);
31
- return headerStateComparison && headerValueComparison;
32
- });
33
- };
34
-
35
- const isSafari = typeof navigator !== "undefined" && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
36
- const defaultPayloadGenerator = (data)=>{
37
- return {
38
- cacheName: data.cacheName,
39
- updatedURL: data.request.url
40
- };
41
- };
42
- class BroadcastCacheUpdate {
43
- _headersToCheck;
44
- _generatePayload;
45
- _notifyAllClients;
46
- constructor({ generatePayload, headersToCheck, notifyAllClients } = {}){
47
- this._headersToCheck = headersToCheck || defaultHeadersToCheck;
48
- this._generatePayload = generatePayload || defaultPayloadGenerator;
49
- this._notifyAllClients = notifyAllClients ?? defaultNotifyAllClients;
50
- }
51
- async notifyIfUpdated(options) {
52
- if (process.env.NODE_ENV !== "production") {
53
- assert.isType(options.cacheName, "string", {
54
- moduleName: "@serwist/broadcast-update",
55
- className: "BroadcastCacheUpdate",
56
- funcName: "notifyIfUpdated",
57
- paramName: "cacheName"
58
- });
59
- assert.isInstance(options.newResponse, Response, {
60
- moduleName: "@serwist/broadcast-update",
61
- className: "BroadcastCacheUpdate",
62
- funcName: "notifyIfUpdated",
63
- paramName: "newResponse"
64
- });
65
- assert.isInstance(options.request, Request, {
66
- moduleName: "@serwist/broadcast-update",
67
- className: "BroadcastCacheUpdate",
68
- funcName: "notifyIfUpdated",
69
- paramName: "request"
70
- });
71
- }
72
- if (!options.oldResponse) {
73
- return;
74
- }
75
- if (!responsesAreSame(options.oldResponse, options.newResponse, this._headersToCheck)) {
76
- if (process.env.NODE_ENV !== "production") {
77
- logger.log("Newer response found (and cached) for:", options.request.url);
78
- }
79
- const messageData = {
80
- type: CACHE_UPDATED_MESSAGE_TYPE,
81
- meta: CACHE_UPDATED_MESSAGE_META,
82
- payload: this._generatePayload(options)
83
- };
84
- if (options.request.mode === "navigate") {
85
- let resultingClientId;
86
- if (options.event instanceof FetchEvent) {
87
- resultingClientId = options.event.resultingClientId;
88
- }
89
- const resultingWin = await resultingClientExists(resultingClientId);
90
- if (!resultingWin || isSafari) {
91
- await timeout(3500);
92
- }
93
- }
94
- if (this._notifyAllClients) {
95
- const windows = await self.clients.matchAll({
96
- type: "window"
97
- });
98
- for (const win of windows){
99
- win.postMessage(messageData);
100
- }
101
- } else {
102
- if (options.event instanceof FetchEvent) {
103
- const client = await self.clients.get(options.event.clientId);
104
- client?.postMessage(messageData);
105
- }
106
- }
107
- }
108
- }
109
- }
110
-
111
- class BroadcastUpdatePlugin {
112
- _broadcastUpdate;
113
- constructor(options){
114
- this._broadcastUpdate = new BroadcastCacheUpdate(options);
115
- }
116
- cacheDidUpdate(options) {
117
- void this._broadcastUpdate.notifyIfUpdated(options);
118
- }
119
- }
120
-
121
- export { BroadcastCacheUpdate, BroadcastUpdatePlugin, CACHE_UPDATED_MESSAGE_META, CACHE_UPDATED_MESSAGE_TYPE, defaultHeadersToCheck, responsesAreSame };
1
+ export { BroadcastCacheUpdate, BroadcastUpdatePlugin, BROADCAST_UPDATE_DEFAULT_HEADERS as defaultHeadersToCheck, responsesAreSame } from 'serwist';
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@serwist/broadcast-update",
3
- "version": "9.0.0-preview.9",
3
+ "version": "9.0.1",
4
4
  "type": "module",
5
- "description": "A module that uses the Broadcast Channel API to announce when a cached response has updated",
5
+ "description": "A module that uses the Broadcast Channel API to announce when a cached response has updated.",
6
6
  "files": [
7
7
  "src",
8
8
  "dist"
@@ -17,7 +17,7 @@
17
17
  ],
18
18
  "author": "Google's Web DevRel Team, Serwist's Team",
19
19
  "license": "MIT",
20
- "repository": "serwist/serwist",
20
+ "repository": "https://github.com/serwist/serwist",
21
21
  "bugs": "https://github.com/serwist/serwist/issues",
22
22
  "homepage": "https://serwist.pages.dev",
23
23
  "main": "./dist/index.js",
@@ -29,12 +29,12 @@
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@serwist/core": "9.0.0-preview.9"
32
+ "serwist": "9.0.0"
33
33
  },
34
34
  "devDependencies": {
35
- "rollup": "4.9.6",
36
- "typescript": "5.4.0-dev.20240206",
37
- "@serwist/constants": "9.0.0-preview.9"
35
+ "rollup": "4.14.3",
36
+ "typescript": "5.5.0-dev.20240415",
37
+ "@serwist/configs": "9.0.1"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "typescript": ">=5.0.0"
package/src/index.ts CHANGED
@@ -6,18 +6,10 @@
6
6
  https://opensource.org/licenses/MIT.
7
7
  */
8
8
 
9
- import { BroadcastCacheUpdate } from "./BroadcastCacheUpdate.js";
10
- import { BroadcastUpdatePlugin } from "./BroadcastUpdatePlugin.js";
11
- import { CACHE_UPDATED_MESSAGE_META, CACHE_UPDATED_MESSAGE_TYPE, defaultHeadersToCheck } from "./constants.js";
12
- import { responsesAreSame } from "./responsesAreSame.js";
13
-
14
9
  export {
15
10
  BroadcastCacheUpdate,
16
11
  BroadcastUpdatePlugin,
17
12
  responsesAreSame,
18
- CACHE_UPDATED_MESSAGE_META,
19
- CACHE_UPDATED_MESSAGE_TYPE,
20
- defaultHeadersToCheck,
21
- };
22
-
23
- export type * from "./types.js";
13
+ BROADCAST_UPDATE_DEFAULT_HEADERS as defaultHeadersToCheck,
14
+ } from "serwist";
15
+ export type { BroadcastCacheUpdateOptions, BroadcastPayload, BroadcastPayloadGenerator, BroadcastMessage } from "serwist";
@@ -1,47 +0,0 @@
1
- import type { CacheDidUpdateCallbackParam } from "@serwist/core";
2
- import type { BroadcastCacheUpdateOptions } from "./types.js";
3
- /**
4
- * Uses the `postMessage()` API to inform any open windows/tabs when a cached
5
- * response has been updated.
6
- *
7
- * For efficiency's sake, the underlying response bodies are not compared;
8
- * only specific response headers are checked.
9
- */
10
- export declare class BroadcastCacheUpdate {
11
- private readonly _headersToCheck;
12
- private readonly _generatePayload;
13
- private readonly _notifyAllClients;
14
- /**
15
- * Construct a BroadcastCacheUpdate instance with a specific `channelName` to
16
- * broadcast messages on
17
- *
18
- * @param options
19
- */
20
- constructor({ generatePayload, headersToCheck, notifyAllClients }?: BroadcastCacheUpdateOptions);
21
- /**
22
- * Compares two [Responses](https://developer.mozilla.org/en-US/docs/Web/API/Response)
23
- * and sends a message (via `postMessage()`) to all window clients if the
24
- * responses differ. Neither of the Responses can be
25
- * [opaque](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses).
26
- *
27
- * The message that's posted has the following format (where `payload` can
28
- * be customized via the `generatePayload` option the instance is created
29
- * with):
30
- *
31
- * ```
32
- * {
33
- * type: 'CACHE_UPDATED',
34
- * meta: 'workbox-broadcast-update',
35
- * payload: {
36
- * cacheName: 'the-cache-name',
37
- * updatedURL: 'https://example.com/'
38
- * }
39
- * }
40
- * ```
41
- *
42
- * @param options
43
- * @returns Resolves once the update is sent.
44
- */
45
- notifyIfUpdated(options: CacheDidUpdateCallbackParam): Promise<void>;
46
- }
47
- //# sourceMappingURL=BroadcastCacheUpdate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BroadcastCacheUpdate.d.ts","sourceRoot":"","sources":["../src/BroadcastCacheUpdate.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC;AAKjE,OAAO,KAAK,EAAE,2BAA2B,EAAiE,MAAM,YAAY,CAAC;AAuB7H;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAW;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4B;IAC7D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAU;IAE5C;;;;;OAKG;gBACS,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,GAAE,2BAAgC;IAMnG;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACG,eAAe,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC;CA4E3E"}
@@ -1,27 +0,0 @@
1
- import type { CacheDidUpdateCallbackParam, SerwistPlugin } from "@serwist/core";
2
- import type { BroadcastCacheUpdateOptions } from "./types.js";
3
- /**
4
- * This plugin will automatically broadcast a message whenever a cached response
5
- * is updated.
6
- */
7
- export declare class BroadcastUpdatePlugin implements SerwistPlugin {
8
- private readonly _broadcastUpdate;
9
- /**
10
- * Construct a `@serwist/broadcast-update.BroadcastCacheUpdate` instance with
11
- * the passed options and calls its `notifyIfUpdated` method whenever the
12
- * plugin's `cacheDidUpdate` callback is invoked.
13
- *
14
- * @param options
15
- */
16
- constructor(options?: BroadcastCacheUpdateOptions);
17
- /**
18
- * A "lifecycle" callback that will be triggered automatically by
19
- * `@serwist/build.RuntimeCaching` handlers when an entry is
20
- * added to a cache.
21
- *
22
- * @private
23
- * @param options The input object to this function.
24
- */
25
- cacheDidUpdate(options: CacheDidUpdateCallbackParam): void;
26
- }
27
- //# sourceMappingURL=BroadcastUpdatePlugin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BroadcastUpdatePlugin.d.ts","sourceRoot":"","sources":["../src/BroadcastUpdatePlugin.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,2BAA2B,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGhF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAE9D;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACzD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuB;IAExD;;;;;;OAMG;gBACS,OAAO,CAAC,EAAE,2BAA2B;IAIjD;;;;;;;OAOG;IACH,cAAc,CAAC,OAAO,EAAE,2BAA2B;CAGpD"}
@@ -1,5 +0,0 @@
1
- export declare const CACHE_UPDATED_MESSAGE_TYPE = "CACHE_UPDATED";
2
- export declare const CACHE_UPDATED_MESSAGE_META = "serwist-broadcast-update";
3
- export declare const defaultNotifyAllClients = true;
4
- export declare const defaultHeadersToCheck: string[];
5
- //# sourceMappingURL=constants.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,0BAA0B,kBAAkB,CAAC;AAC1D,eAAO,MAAM,0BAA0B,6BAA6B,CAAC;AACrE,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAC5C,eAAO,MAAM,qBAAqB,UAA8C,CAAC"}
@@ -1,12 +0,0 @@
1
- /**
2
- * Given two `Response's`, compares several header values to see if they are
3
- * the same or not.
4
- *
5
- * @param firstResponse
6
- * @param secondResponse
7
- * @param headersToCheck
8
- * @returns
9
- */
10
- declare const responsesAreSame: (firstResponse: Response, secondResponse: Response, headersToCheck: string[]) => boolean;
11
- export { responsesAreSame };
12
- //# sourceMappingURL=responsesAreSame.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"responsesAreSame.d.ts","sourceRoot":"","sources":["../src/responsesAreSame.ts"],"names":[],"mappings":"AAUA;;;;;;;;GAQG;AACH,QAAA,MAAM,gBAAgB,kBAAmB,QAAQ,kBAAkB,QAAQ,kBAAkB,MAAM,EAAE,KAAG,OA4BvG,CAAC;AAEF,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
package/dist/types.d.ts DELETED
@@ -1,36 +0,0 @@
1
- import type { CacheDidUpdateCallbackParam } from "@serwist/core";
2
- import type { CACHE_UPDATED_MESSAGE_META, CACHE_UPDATED_MESSAGE_TYPE } from "./constants.js";
3
- export interface BroadcastCacheUpdateOptions {
4
- /**
5
- * A list of headers that will be used to determine whether the responses
6
- * differ.
7
- *
8
- * @default ['content-length', 'etag', 'last-modified']
9
- */
10
- headersToCheck?: string[];
11
- /**
12
- * A function whose return value
13
- * will be used as the `payload` field in any cache update messages sent
14
- * to the window clients.
15
- * @param options
16
- * @returns
17
- */
18
- generatePayload?: (options: CacheDidUpdateCallbackParam) => Record<string, any>;
19
- /**
20
- * If true (the default) then all open clients will receive a message. If false,
21
- * then only the client that make the original request will be notified of the update.
22
- *
23
- * @default true
24
- */
25
- notifyAllClients?: boolean;
26
- }
27
- export type BroadcastPayload = Record<string, any>;
28
- export interface BroadcastPayloadGenerator {
29
- (options: CacheDidUpdateCallbackParam): BroadcastPayload;
30
- }
31
- export interface BroadcastMessage {
32
- type: typeof CACHE_UPDATED_MESSAGE_TYPE;
33
- meta: typeof CACHE_UPDATED_MESSAGE_META;
34
- payload: BroadcastPayload;
35
- }
36
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,KAAK,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAE7F,MAAM,WAAW,2BAA2B;IAC1C;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,2BAA2B,KAAK,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChF;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEnD,MAAM,WAAW,yBAAyB;IACxC,CAAC,OAAO,EAAE,2BAA2B,GAAG,gBAAgB,CAAC;CAC1D;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,0BAA0B,CAAC;IACxC,IAAI,EAAE,OAAO,0BAA0B,CAAC;IACxC,OAAO,EAAE,gBAAgB,CAAC;CAC3B"}
@@ -1,161 +0,0 @@
1
- /*
2
- Copyright 2018 Google LLC
3
-
4
- Use of this source code is governed by an MIT-style
5
- license that can be found in the LICENSE file or at
6
- https://opensource.org/licenses/MIT.
7
- */
8
-
9
- import type { CacheDidUpdateCallbackParam } from "@serwist/core";
10
- import { assert, logger, resultingClientExists, timeout } from "@serwist/core/internal";
11
-
12
- import { CACHE_UPDATED_MESSAGE_META, CACHE_UPDATED_MESSAGE_TYPE, defaultHeadersToCheck, defaultNotifyAllClients } from "./constants.js";
13
- import { responsesAreSame } from "./responsesAreSame.js";
14
- import type { BroadcastCacheUpdateOptions, BroadcastMessage, BroadcastPayload, BroadcastPayloadGenerator } from "./types.js";
15
-
16
- // UA-sniff Safari: https://stackoverflow.com/questions/7944460/detect-safari-browser
17
- // TODO(philipwalton): remove once this Safari bug fix has been released.
18
- // https://bugs.webkit.org/show_bug.cgi?id=201169
19
- const isSafari = typeof navigator !== "undefined" && /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
20
-
21
- // Give TypeScript the correct global.
22
- declare let self: ServiceWorkerGlobalScope;
23
- /**
24
- * Generates the default payload used in update messages. By default the
25
- * payload includes the `cacheName` and `updatedURL` fields.
26
- *
27
- * @returns
28
- * @private
29
- */
30
- const defaultPayloadGenerator = (data: CacheDidUpdateCallbackParam): BroadcastPayload => {
31
- return {
32
- cacheName: data.cacheName,
33
- updatedURL: data.request.url,
34
- };
35
- };
36
-
37
- /**
38
- * Uses the `postMessage()` API to inform any open windows/tabs when a cached
39
- * response has been updated.
40
- *
41
- * For efficiency's sake, the underlying response bodies are not compared;
42
- * only specific response headers are checked.
43
- */
44
- export class BroadcastCacheUpdate {
45
- private readonly _headersToCheck: string[];
46
- private readonly _generatePayload: BroadcastPayloadGenerator;
47
- private readonly _notifyAllClients: boolean;
48
-
49
- /**
50
- * Construct a BroadcastCacheUpdate instance with a specific `channelName` to
51
- * broadcast messages on
52
- *
53
- * @param options
54
- */
55
- constructor({ generatePayload, headersToCheck, notifyAllClients }: BroadcastCacheUpdateOptions = {}) {
56
- this._headersToCheck = headersToCheck || defaultHeadersToCheck;
57
- this._generatePayload = generatePayload || defaultPayloadGenerator;
58
- this._notifyAllClients = notifyAllClients ?? defaultNotifyAllClients;
59
- }
60
-
61
- /**
62
- * Compares two [Responses](https://developer.mozilla.org/en-US/docs/Web/API/Response)
63
- * and sends a message (via `postMessage()`) to all window clients if the
64
- * responses differ. Neither of the Responses can be
65
- * [opaque](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses).
66
- *
67
- * The message that's posted has the following format (where `payload` can
68
- * be customized via the `generatePayload` option the instance is created
69
- * with):
70
- *
71
- * ```
72
- * {
73
- * type: 'CACHE_UPDATED',
74
- * meta: 'workbox-broadcast-update',
75
- * payload: {
76
- * cacheName: 'the-cache-name',
77
- * updatedURL: 'https://example.com/'
78
- * }
79
- * }
80
- * ```
81
- *
82
- * @param options
83
- * @returns Resolves once the update is sent.
84
- */
85
- async notifyIfUpdated(options: CacheDidUpdateCallbackParam): Promise<void> {
86
- if (process.env.NODE_ENV !== "production") {
87
- assert!.isType(options.cacheName, "string", {
88
- moduleName: "@serwist/broadcast-update",
89
- className: "BroadcastCacheUpdate",
90
- funcName: "notifyIfUpdated",
91
- paramName: "cacheName",
92
- });
93
- assert!.isInstance(options.newResponse, Response, {
94
- moduleName: "@serwist/broadcast-update",
95
- className: "BroadcastCacheUpdate",
96
- funcName: "notifyIfUpdated",
97
- paramName: "newResponse",
98
- });
99
- assert!.isInstance(options.request, Request, {
100
- moduleName: "@serwist/broadcast-update",
101
- className: "BroadcastCacheUpdate",
102
- funcName: "notifyIfUpdated",
103
- paramName: "request",
104
- });
105
- }
106
-
107
- // Without two responses there is nothing to compare.
108
- if (!options.oldResponse) {
109
- return;
110
- }
111
-
112
- if (!responsesAreSame(options.oldResponse, options.newResponse, this._headersToCheck)) {
113
- if (process.env.NODE_ENV !== "production") {
114
- logger.log("Newer response found (and cached) for:", options.request.url);
115
- }
116
-
117
- const messageData = {
118
- type: CACHE_UPDATED_MESSAGE_TYPE,
119
- meta: CACHE_UPDATED_MESSAGE_META,
120
- payload: this._generatePayload(options),
121
- } satisfies BroadcastMessage;
122
-
123
- // For navigation requests, wait until the new window client exists
124
- // before sending the message
125
- if (options.request.mode === "navigate") {
126
- let resultingClientId: string | undefined;
127
- if (options.event instanceof FetchEvent) {
128
- resultingClientId = options.event.resultingClientId;
129
- }
130
-
131
- const resultingWin = await resultingClientExists(resultingClientId);
132
-
133
- // Safari does not currently implement postMessage buffering and
134
- // there's no good way to feature detect that, so to increase the
135
- // chances of the message being delivered in Safari, we add a timeout.
136
- // We also do this if `resultingClientExists()` didn't return a client,
137
- // which means it timed out, so it's worth waiting a bit longer.
138
- if (!resultingWin || isSafari) {
139
- // 3500 is chosen because (according to CrUX data) 80% of mobile
140
- // websites hit the DOMContentLoaded event in less than 3.5 seconds.
141
- // And presumably sites implementing service worker are on the
142
- // higher end of the performance spectrum.
143
- await timeout(3500);
144
- }
145
- }
146
-
147
- if (this._notifyAllClients) {
148
- const windows = await self.clients.matchAll({ type: "window" });
149
- for (const win of windows) {
150
- win.postMessage(messageData);
151
- }
152
- } else {
153
- // See https://github.com/GoogleChrome/workbox/issues/2895
154
- if (options.event instanceof FetchEvent) {
155
- const client = await self.clients.get(options.event.clientId);
156
- client?.postMessage(messageData);
157
- }
158
- }
159
- }
160
- }
161
- }
@@ -1,43 +0,0 @@
1
- /*
2
- Copyright 2018 Google LLC
3
-
4
- Use of this source code is governed by an MIT-style
5
- license that can be found in the LICENSE file or at
6
- https://opensource.org/licenses/MIT.
7
- */
8
-
9
- import type { CacheDidUpdateCallbackParam, SerwistPlugin } from "@serwist/core";
10
-
11
- import { BroadcastCacheUpdate } from "./BroadcastCacheUpdate.js";
12
- import type { BroadcastCacheUpdateOptions } from "./types.js";
13
-
14
- /**
15
- * This plugin will automatically broadcast a message whenever a cached response
16
- * is updated.
17
- */
18
- export class BroadcastUpdatePlugin implements SerwistPlugin {
19
- private readonly _broadcastUpdate: BroadcastCacheUpdate;
20
-
21
- /**
22
- * Construct a `@serwist/broadcast-update.BroadcastCacheUpdate` instance with
23
- * the passed options and calls its `notifyIfUpdated` method whenever the
24
- * plugin's `cacheDidUpdate` callback is invoked.
25
- *
26
- * @param options
27
- */
28
- constructor(options?: BroadcastCacheUpdateOptions) {
29
- this._broadcastUpdate = new BroadcastCacheUpdate(options);
30
- }
31
-
32
- /**
33
- * A "lifecycle" callback that will be triggered automatically by
34
- * `@serwist/build.RuntimeCaching` handlers when an entry is
35
- * added to a cache.
36
- *
37
- * @private
38
- * @param options The input object to this function.
39
- */
40
- cacheDidUpdate(options: CacheDidUpdateCallbackParam) {
41
- void this._broadcastUpdate.notifyIfUpdated(options);
42
- }
43
- }
package/src/constants.ts DELETED
@@ -1,12 +0,0 @@
1
- /*
2
- Copyright 2018 Google LLC
3
-
4
- Use of this source code is governed by an MIT-style
5
- license that can be found in the LICENSE file or at
6
- https://opensource.org/licenses/MIT.
7
- */
8
-
9
- export const CACHE_UPDATED_MESSAGE_TYPE = "CACHE_UPDATED";
10
- export const CACHE_UPDATED_MESSAGE_META = "serwist-broadcast-update";
11
- export const defaultNotifyAllClients = true;
12
- export const defaultHeadersToCheck = ["content-length", "etag", "last-modified"];
@@ -1,50 +0,0 @@
1
- /*
2
- Copyright 2018 Google LLC
3
-
4
- Use of this source code is governed by an MIT-style
5
- license that can be found in the LICENSE file or at
6
- https://opensource.org/licenses/MIT.
7
- */
8
-
9
- import { SerwistError, logger } from "@serwist/core/internal";
10
-
11
- /**
12
- * Given two `Response's`, compares several header values to see if they are
13
- * the same or not.
14
- *
15
- * @param firstResponse
16
- * @param secondResponse
17
- * @param headersToCheck
18
- * @returns
19
- */
20
- const responsesAreSame = (firstResponse: Response, secondResponse: Response, headersToCheck: string[]): boolean => {
21
- if (process.env.NODE_ENV !== "production") {
22
- if (!(firstResponse instanceof Response && secondResponse instanceof Response)) {
23
- throw new SerwistError("invalid-responses-are-same-args");
24
- }
25
- }
26
-
27
- const atLeastOneHeaderAvailable = headersToCheck.some((header) => {
28
- return firstResponse.headers.has(header) && secondResponse.headers.has(header);
29
- });
30
-
31
- if (!atLeastOneHeaderAvailable) {
32
- if (process.env.NODE_ENV !== "production") {
33
- logger.warn("Unable to determine where the response has been updated " + "because none of the headers that would be checked are present.");
34
- logger.debug("Attempting to compare the following: ", firstResponse, secondResponse, headersToCheck);
35
- }
36
-
37
- // Just return true, indicating the that responses are the same, since we
38
- // can't determine otherwise.
39
- return true;
40
- }
41
-
42
- return headersToCheck.every((header) => {
43
- const headerStateComparison = firstResponse.headers.has(header) === secondResponse.headers.has(header);
44
- const headerValueComparison = firstResponse.headers.get(header) === secondResponse.headers.get(header);
45
-
46
- return headerStateComparison && headerValueComparison;
47
- });
48
- };
49
-
50
- export { responsesAreSame };
package/src/types.ts DELETED
@@ -1,39 +0,0 @@
1
- import type { CacheDidUpdateCallbackParam } from "@serwist/core";
2
- import type { CACHE_UPDATED_MESSAGE_META, CACHE_UPDATED_MESSAGE_TYPE } from "./constants.js";
3
-
4
- export interface BroadcastCacheUpdateOptions {
5
- /**
6
- * A list of headers that will be used to determine whether the responses
7
- * differ.
8
- *
9
- * @default ['content-length', 'etag', 'last-modified']
10
- */
11
- headersToCheck?: string[];
12
- /**
13
- * A function whose return value
14
- * will be used as the `payload` field in any cache update messages sent
15
- * to the window clients.
16
- * @param options
17
- * @returns
18
- */
19
- generatePayload?: (options: CacheDidUpdateCallbackParam) => Record<string, any>;
20
- /**
21
- * If true (the default) then all open clients will receive a message. If false,
22
- * then only the client that make the original request will be notified of the update.
23
- *
24
- * @default true
25
- */
26
- notifyAllClients?: boolean;
27
- }
28
-
29
- export type BroadcastPayload = Record<string, any>;
30
-
31
- export interface BroadcastPayloadGenerator {
32
- (options: CacheDidUpdateCallbackParam): BroadcastPayload;
33
- }
34
-
35
- export interface BroadcastMessage {
36
- type: typeof CACHE_UPDATED_MESSAGE_TYPE;
37
- meta: typeof CACHE_UPDATED_MESSAGE_META;
38
- payload: BroadcastPayload;
39
- }