@serwist/precaching 8.4.4 → 9.0.0-preview.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.
Files changed (75) hide show
  1. package/dist/PrecacheController.d.ts +4 -3
  2. package/dist/PrecacheController.d.ts.map +1 -0
  3. package/dist/PrecacheFallbackPlugin.d.ts +1 -0
  4. package/dist/PrecacheFallbackPlugin.d.ts.map +1 -0
  5. package/dist/PrecacheRoute.d.ts +1 -0
  6. package/dist/PrecacheRoute.d.ts.map +1 -0
  7. package/dist/PrecacheStrategy.d.ts +1 -0
  8. package/dist/PrecacheStrategy.d.ts.map +1 -0
  9. package/dist/_types.d.ts +3 -2
  10. package/dist/_types.d.ts.map +1 -0
  11. package/dist/addPlugins.d.ts +1 -0
  12. package/dist/addPlugins.d.ts.map +1 -0
  13. package/dist/addRoute.d.ts +1 -0
  14. package/dist/addRoute.d.ts.map +1 -0
  15. package/dist/cleanupOutdatedCaches.d.ts +1 -0
  16. package/dist/cleanupOutdatedCaches.d.ts.map +1 -0
  17. package/dist/createHandlerBoundToURL.d.ts +1 -0
  18. package/dist/createHandlerBoundToURL.d.ts.map +1 -0
  19. package/dist/getCacheKeyForURL.d.ts +1 -0
  20. package/dist/getCacheKeyForURL.d.ts.map +1 -0
  21. package/dist/index.d.ts +1 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +43 -427
  24. package/dist/matchPrecache.d.ts +1 -0
  25. package/dist/matchPrecache.d.ts.map +1 -0
  26. package/dist/precache.d.ts +2 -1
  27. package/dist/precache.d.ts.map +1 -0
  28. package/dist/precacheAndRoute.d.ts +2 -1
  29. package/dist/precacheAndRoute.d.ts.map +1 -0
  30. package/dist/utils/PrecacheCacheKeyPlugin.d.ts +1 -0
  31. package/dist/utils/PrecacheCacheKeyPlugin.d.ts.map +1 -0
  32. package/dist/utils/PrecacheInstallReportPlugin.d.ts +1 -0
  33. package/dist/utils/PrecacheInstallReportPlugin.d.ts.map +1 -0
  34. package/dist/utils/createCacheKey.d.ts +1 -0
  35. package/dist/utils/createCacheKey.d.ts.map +1 -0
  36. package/dist/utils/deleteOutdatedCaches.d.ts +1 -0
  37. package/dist/utils/deleteOutdatedCaches.d.ts.map +1 -0
  38. package/dist/utils/generateURLVariations.d.ts +1 -0
  39. package/dist/utils/generateURLVariations.d.ts.map +1 -0
  40. package/dist/utils/getCacheKeyForURL.d.ts +1 -0
  41. package/dist/utils/getCacheKeyForURL.d.ts.map +1 -0
  42. package/dist/utils/getOrCreatePrecacheController.d.ts +1 -0
  43. package/dist/utils/getOrCreatePrecacheController.d.ts.map +1 -0
  44. package/dist/utils/printCleanupDetails.d.ts +1 -0
  45. package/dist/utils/printCleanupDetails.d.ts.map +1 -0
  46. package/dist/utils/printInstallDetails.d.ts +1 -0
  47. package/dist/utils/printInstallDetails.d.ts.map +1 -0
  48. package/dist/utils/removeIgnoredSearchParams.d.ts +1 -0
  49. package/dist/utils/removeIgnoredSearchParams.d.ts.map +1 -0
  50. package/package.json +20 -18
  51. package/src/PrecacheController.ts +331 -0
  52. package/src/PrecacheFallbackPlugin.ts +61 -0
  53. package/src/PrecacheRoute.ts +50 -0
  54. package/src/PrecacheStrategy.ts +239 -0
  55. package/src/_types.ts +46 -0
  56. package/src/addPlugins.ts +23 -0
  57. package/src/addRoute.ts +33 -0
  58. package/src/cleanupOutdatedCaches.ts +34 -0
  59. package/src/createHandlerBoundToURL.ts +32 -0
  60. package/src/getCacheKeyForURL.ts +33 -0
  61. package/{dist/index.d.cts → src/index.ts} +25 -1
  62. package/src/matchPrecache.ts +28 -0
  63. package/src/precache.ts +33 -0
  64. package/src/precacheAndRoute.ts +29 -0
  65. package/src/utils/PrecacheCacheKeyPlugin.ts +36 -0
  66. package/src/utils/PrecacheInstallReportPlugin.ts +49 -0
  67. package/src/utils/createCacheKey.ts +68 -0
  68. package/src/utils/deleteOutdatedCaches.ts +42 -0
  69. package/src/utils/generateURLVariations.ts +55 -0
  70. package/src/utils/getCacheKeyForURL.ts +36 -0
  71. package/src/utils/getOrCreatePrecacheController.ts +22 -0
  72. package/src/utils/printCleanupDetails.ts +38 -0
  73. package/src/utils/printInstallDetails.ts +53 -0
  74. package/src/utils/removeIgnoredSearchParams.ts +29 -0
  75. package/dist/index.cjs +0 -930
@@ -12,3 +12,4 @@
12
12
  */
13
13
  declare function matchPrecache(request: string | Request): Promise<Response | undefined>;
14
14
  export { matchPrecache };
15
+ //# sourceMappingURL=matchPrecache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matchPrecache.d.ts","sourceRoot":"","sources":["../src/matchPrecache.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;GAWG;AACH,iBAAS,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAG/E;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -15,5 +15,6 @@ import type { PrecacheEntry } from "./_types.js";
15
15
  *
16
16
  * @param entries Array of entries to precache.
17
17
  */
18
- declare function precache(entries: Array<PrecacheEntry | string>): void;
18
+ declare function precache(entries: (PrecacheEntry | string)[]): void;
19
19
  export { precache };
20
+ //# sourceMappingURL=precache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"precache.d.ts","sourceRoot":"","sources":["../src/precache.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD;;;;;;;;;;;;;;;GAeG;AACH,iBAAS,QAAQ,CAAC,OAAO,EAAE,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI,CAG3D;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -10,5 +10,6 @@ import type { PrecacheEntry, PrecacheRouteOptions } from "./_types.js";
10
10
  * @param entries Array of entries to precache.
11
11
  * @param options See the `@serwist/precaching.PrecacheRoute` options.
12
12
  */
13
- declare function precacheAndRoute(entries: Array<PrecacheEntry | string>, options?: PrecacheRouteOptions): void;
13
+ declare function precacheAndRoute(entries: (PrecacheEntry | string)[], options?: PrecacheRouteOptions): void;
14
14
  export { precacheAndRoute };
15
+ //# sourceMappingURL=precacheAndRoute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"precacheAndRoute.d.ts","sourceRoot":"","sources":["../src/precacheAndRoute.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAIvE;;;;;;;;;;GAUG;AACH,iBAAS,gBAAgB,CAAC,OAAO,EAAE,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAGnG;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -14,3 +14,4 @@ declare class PrecacheCacheKeyPlugin implements SerwistPlugin {
14
14
  cacheKeyWillBeUsed: SerwistPlugin["cacheKeyWillBeUsed"];
15
15
  }
16
16
  export { PrecacheCacheKeyPlugin };
17
+ //# sourceMappingURL=PrecacheCacheKeyPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PrecacheCacheKeyPlugin.d.ts","sourceRoot":"","sources":["../../src/utils/PrecacheCacheKeyPlugin.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAA8B,MAAM,eAAe,CAAC;AAE/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE;;;;;GAKG;AACH,cAAM,sBAAuB,YAAW,aAAa;IACnD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;gBAE7C,EAAE,kBAAkB,EAAE,EAAE;QAAE,kBAAkB,EAAE,kBAAkB,CAAA;KAAE;IAI9E,kBAAkB,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAOrD;CACH;AAED,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -12,3 +12,4 @@ declare class PrecacheInstallReportPlugin implements SerwistPlugin {
12
12
  cachedResponseWillBeUsed: SerwistPlugin["cachedResponseWillBeUsed"];
13
13
  }
14
14
  export { PrecacheInstallReportPlugin };
15
+ //# sourceMappingURL=PrecacheInstallReportPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PrecacheInstallReportPlugin.d.ts","sourceRoot":"","sources":["../../src/utils/PrecacheInstallReportPlugin.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAA8B,MAAM,eAAe,CAAC;AAE/E;;;;;GAKG;AACH,cAAM,2BAA4B,YAAW,aAAa;IACxD,WAAW,EAAE,MAAM,EAAE,CAAM;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAM;IAE9B,gBAAgB,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAKjD;IAEF,wBAAwB,EAAE,aAAa,CAAC,0BAA0B,CAAC,CAkBjE;CACH;AAED,OAAO,EAAE,2BAA2B,EAAE,CAAC"}
@@ -13,3 +13,4 @@ interface CacheKey {
13
13
  */
14
14
  export declare function createCacheKey(entry: PrecacheEntry | string): CacheKey;
15
15
  export {};
16
+ //# sourceMappingURL=createCacheKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createCacheKey.d.ts","sourceRoot":"","sources":["../../src/utils/createCacheKey.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,UAAU,QAAQ;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAKD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,GAAG,QAAQ,CAuCtE"}
@@ -16,3 +16,4 @@
16
16
  */
17
17
  declare const deleteOutdatedCaches: (currentPrecacheName: string, substringToFind?: string) => Promise<string[]>;
18
18
  export { deleteOutdatedCaches };
19
+ //# sourceMappingURL=deleteOutdatedCaches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deleteOutdatedCaches.d.ts","sourceRoot":"","sources":["../../src/utils/deleteOutdatedCaches.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,oBAAoB,wBAA+B,MAAM,oBAAmB,MAAM,KAAuB,QAAQ,MAAM,EAAE,CAU9H,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
@@ -9,3 +9,4 @@ import type { PrecacheRouteOptions } from "../_types.js";
9
9
  * @private
10
10
  */
11
11
  export declare function generateURLVariations(url: string, { ignoreURLParametersMatching, directoryIndex, cleanURLs, urlManipulation, }?: PrecacheRouteOptions): Generator<string, void, unknown>;
12
+ //# sourceMappingURL=generateURLVariations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateURLVariations.d.ts","sourceRoot":"","sources":["../../src/utils/generateURLVariations.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGzD;;;;;;;;GAQG;AACH,wBAAiB,qBAAqB,CACpC,GAAG,EAAE,MAAM,EACX,EACE,2BAAmD,EACnD,cAA6B,EAC7B,SAAgB,EAChB,eAAe,GAChB,GAAE,oBAAyB,GAC3B,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CA0BlC"}
@@ -11,3 +11,4 @@ import type { PrecacheRouteOptions } from "../_types.js";
11
11
  * @private
12
12
  */
13
13
  export declare const getCacheKeyForURL: (url: string, options: PrecacheRouteOptions) => string | undefined;
14
+ //# sourceMappingURL=getCacheKeyForURL.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getCacheKeyForURL.d.ts","sourceRoot":"","sources":["../../src/utils/getCacheKeyForURL.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAIzD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,QAAS,MAAM,WAAW,oBAAoB,KAAG,MAAM,GAAG,SAYvF,CAAC"}
@@ -4,3 +4,4 @@ import { PrecacheController } from "../PrecacheController.js";
4
4
  * @private
5
5
  */
6
6
  export declare const getOrCreatePrecacheController: () => PrecacheController;
7
+ //# sourceMappingURL=getOrCreatePrecacheController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getOrCreatePrecacheController.d.ts","sourceRoot":"","sources":["../../src/utils/getOrCreatePrecacheController.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAI9D;;;GAGG;AACH,eAAO,MAAM,6BAA6B,QAAO,kBAKhD,CAAC"}
@@ -3,3 +3,4 @@
3
3
  * @private
4
4
  */
5
5
  export declare function printCleanupDetails(deletedURLs: string[]): void;
6
+ //# sourceMappingURL=printCleanupDetails.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"printCleanupDetails.d.ts","sourceRoot":"","sources":["../../src/utils/printCleanupDetails.ts"],"names":[],"mappings":"AA0BA;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,IAAI,CAO/D"}
@@ -4,3 +4,4 @@
4
4
  * @private
5
5
  */
6
6
  export declare function printInstallDetails(urlsToPrecache: string[], urlsAlreadyPrecached: string[]): void;
7
+ //# sourceMappingURL=printInstallDetails.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"printInstallDetails.d.ts","sourceRoot":"","sources":["../../src/utils/printInstallDetails.ts"],"names":[],"mappings":"AA8BA;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,oBAAoB,EAAE,MAAM,EAAE,GAAG,IAAI,CAiBlG"}
@@ -9,3 +9,4 @@
9
9
  * @private
10
10
  */
11
11
  export declare function removeIgnoredSearchParams(urlObject: URL, ignoreURLParametersMatching?: RegExp[]): URL;
12
+ //# sourceMappingURL=removeIgnoredSearchParams.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removeIgnoredSearchParams.d.ts","sourceRoot":"","sources":["../../src/utils/removeIgnoredSearchParams.ts"],"names":[],"mappings":"AAQA;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,GAAG,EAAE,2BAA2B,GAAE,MAAM,EAAO,GAAG,GAAG,CAUzG"}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@serwist/precaching",
3
- "version": "8.4.4",
3
+ "version": "9.0.0-preview.1",
4
4
  "type": "module",
5
5
  "description": "This module efficiently precaches assets.",
6
6
  "files": [
7
- "dist",
8
- "!dist/**/dts"
7
+ "src",
8
+ "dist"
9
9
  ],
10
10
  "keywords": [
11
11
  "serwist",
@@ -18,30 +18,32 @@
18
18
  "repository": "serwist/serwist",
19
19
  "bugs": "https://github.com/serwist/serwist/issues",
20
20
  "homepage": "https://serwist.pages.dev",
21
- "module": "./dist/index.js",
22
- "main": "./dist/index.cjs",
21
+ "main": "./dist/index.js",
23
22
  "types": "./dist/index.d.ts",
24
23
  "exports": {
25
24
  ".": {
26
- "import": {
27
- "types": "./dist/index.d.ts",
28
- "default": "./dist/index.js"
29
- },
30
- "require": {
31
- "types": "./dist/index.d.cts",
32
- "default": "./dist/index.cjs"
33
- }
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
34
27
  },
35
28
  "./package.json": "./package.json"
36
29
  },
37
30
  "dependencies": {
38
- "@serwist/core": "8.4.4",
39
- "@serwist/routing": "8.4.4",
40
- "@serwist/strategies": "8.4.4"
31
+ "@serwist/core": "9.0.0-preview.1",
32
+ "@serwist/routing": "9.0.0-preview.1",
33
+ "@serwist/strategies": "9.0.0-preview.1"
41
34
  },
42
35
  "devDependencies": {
43
- "rollup": "4.9.1",
44
- "@serwist/constants": "8.4.4"
36
+ "rollup": "4.9.6",
37
+ "typescript": "5.4.0-dev.20240203",
38
+ "@serwist/constants": "9.0.0-preview.1"
39
+ },
40
+ "peerDependencies": {
41
+ "typescript": ">=5.0.0"
42
+ },
43
+ "peerDependenciesMeta": {
44
+ "typescript": {
45
+ "optional": true
46
+ }
45
47
  },
46
48
  "scripts": {
47
49
  "build": "rimraf dist && cross-env NODE_ENV=production rollup --config rollup.config.js",
@@ -0,0 +1,331 @@
1
+ /*
2
+ Copyright 2019 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 { RouteHandlerCallback, SerwistPlugin } from "@serwist/core";
10
+ import { assert, SerwistError, logger, privateCacheNames, waitUntil } from "@serwist/core/internal";
11
+ import type { Strategy } from "@serwist/strategies";
12
+
13
+ import { PrecacheStrategy } from "./PrecacheStrategy.js";
14
+ import type { CleanupResult, InstallResult, PrecacheEntry } from "./_types.js";
15
+ import { PrecacheCacheKeyPlugin } from "./utils/PrecacheCacheKeyPlugin.js";
16
+ import { PrecacheInstallReportPlugin } from "./utils/PrecacheInstallReportPlugin.js";
17
+ import { createCacheKey } from "./utils/createCacheKey.js";
18
+ import { printCleanupDetails } from "./utils/printCleanupDetails.js";
19
+ import { printInstallDetails } from "./utils/printInstallDetails.js";
20
+
21
+ // Give TypeScript the correct global.
22
+ declare let self: ServiceWorkerGlobalScope;
23
+
24
+ interface PrecacheControllerOptions {
25
+ /**
26
+ * The cache to use for precaching.
27
+ */
28
+ cacheName?: string;
29
+ /**
30
+ * Plugins to use when precaching as well as responding to fetch
31
+ * events for precached assets.
32
+ */
33
+ plugins?: SerwistPlugin[];
34
+ /**
35
+ * Whether to attempt to get the response from the network if there's
36
+ * a precache miss.
37
+ */
38
+ fallbackToNetwork?: boolean;
39
+ }
40
+
41
+ /**
42
+ * Performs efficient precaching of assets.
43
+ */
44
+ class PrecacheController {
45
+ private _installAndActiveListenersAdded?: boolean;
46
+ private readonly _strategy: Strategy;
47
+ private readonly _urlsToCacheKeys: Map<string, string> = new Map();
48
+ private readonly _urlsToCacheModes: Map<string, "reload" | "default" | "no-store" | "no-cache" | "force-cache" | "only-if-cached"> = new Map();
49
+ private readonly _cacheKeysToIntegrities: Map<string, string> = new Map();
50
+
51
+ /**
52
+ * Create a new PrecacheController.
53
+ *
54
+ * @param options
55
+ */
56
+ constructor({ cacheName, plugins = [], fallbackToNetwork = true }: PrecacheControllerOptions = {}) {
57
+ this._strategy = new PrecacheStrategy({
58
+ cacheName: privateCacheNames.getPrecacheName(cacheName),
59
+ plugins: [...plugins, new PrecacheCacheKeyPlugin({ precacheController: this })],
60
+ fallbackToNetwork,
61
+ });
62
+
63
+ // Bind the install and activate methods to the instance.
64
+ this.install = this.install.bind(this);
65
+ this.activate = this.activate.bind(this);
66
+ }
67
+
68
+ /**
69
+ * The strategy created by this controller and
70
+ * used to cache assets and respond to fetch events.
71
+ */
72
+ get strategy(): Strategy {
73
+ return this._strategy;
74
+ }
75
+
76
+ /**
77
+ * Adds items to the precache list, removing any duplicates and
78
+ * stores the files in the precache cache when the service
79
+ * worker installs.
80
+ *
81
+ * This method can be called multiple times.
82
+ *
83
+ * @param entries Array of entries to precache.
84
+ */
85
+ precache(entries: (PrecacheEntry | string)[]): void {
86
+ this.addToCacheList(entries);
87
+
88
+ if (!this._installAndActiveListenersAdded) {
89
+ self.addEventListener("install", this.install);
90
+ self.addEventListener("activate", this.activate);
91
+ this._installAndActiveListenersAdded = true;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * This method will add items to the precache list, removing duplicates
97
+ * and ensuring the information is valid.
98
+ *
99
+ * @param entries Array of entries to precache.
100
+ */
101
+ addToCacheList(entries: (PrecacheEntry | string)[]): void {
102
+ if (process.env.NODE_ENV !== "production") {
103
+ assert!.isArray(entries, {
104
+ moduleName: "@serwist/precaching",
105
+ className: "PrecacheController",
106
+ funcName: "addToCacheList",
107
+ paramName: "entries",
108
+ });
109
+ }
110
+
111
+ const urlsToWarnAbout: string[] = [];
112
+ for (const entry of entries) {
113
+ // See https://github.com/GoogleChrome/workbox/issues/2259
114
+ if (typeof entry === "string") {
115
+ urlsToWarnAbout.push(entry);
116
+ } else if (entry && entry.revision === undefined) {
117
+ urlsToWarnAbout.push(entry.url);
118
+ }
119
+
120
+ const { cacheKey, url } = createCacheKey(entry);
121
+ const cacheMode = typeof entry !== "string" && entry.revision ? "reload" : "default";
122
+
123
+ if (this._urlsToCacheKeys.has(url) && this._urlsToCacheKeys.get(url) !== cacheKey) {
124
+ throw new SerwistError("add-to-cache-list-conflicting-entries", {
125
+ firstEntry: this._urlsToCacheKeys.get(url),
126
+ secondEntry: cacheKey,
127
+ });
128
+ }
129
+
130
+ if (typeof entry !== "string" && entry.integrity) {
131
+ if (this._cacheKeysToIntegrities.has(cacheKey) && this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) {
132
+ throw new SerwistError("add-to-cache-list-conflicting-integrities", {
133
+ url,
134
+ });
135
+ }
136
+ this._cacheKeysToIntegrities.set(cacheKey, entry.integrity);
137
+ }
138
+
139
+ this._urlsToCacheKeys.set(url, cacheKey);
140
+ this._urlsToCacheModes.set(url, cacheMode);
141
+
142
+ if (urlsToWarnAbout.length > 0) {
143
+ const warningMessage = `Serwist is precaching URLs without revision info: ${urlsToWarnAbout.join(
144
+ ", ",
145
+ )}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;
146
+ if (process.env.NODE_ENV === "production") {
147
+ // Use console directly to display this warning without bloating
148
+ // bundle sizes by pulling in all of the logger codebase in prod.
149
+ console.warn(warningMessage);
150
+ } else {
151
+ logger.warn(warningMessage);
152
+ }
153
+ }
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Precaches new and updated assets. Call this method from the service worker
159
+ * install event.
160
+ *
161
+ * Note: this method calls `event.waitUntil()` for you, so you do not need
162
+ * to call it yourself in your event handlers.
163
+ *
164
+ * @param event
165
+ * @returns
166
+ */
167
+ install(event: ExtendableEvent): Promise<InstallResult> {
168
+ // waitUntil returns Promise<any>
169
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
170
+ return waitUntil(event, async () => {
171
+ const installReportPlugin = new PrecacheInstallReportPlugin();
172
+ this.strategy.plugins.push(installReportPlugin);
173
+
174
+ // Cache entries one at a time.
175
+ // See https://github.com/GoogleChrome/workbox/issues/2528
176
+ for (const [url, cacheKey] of this._urlsToCacheKeys) {
177
+ const integrity = this._cacheKeysToIntegrities.get(cacheKey);
178
+ const cacheMode = this._urlsToCacheModes.get(url);
179
+
180
+ const request = new Request(url, {
181
+ integrity,
182
+ cache: cacheMode,
183
+ credentials: "same-origin",
184
+ });
185
+
186
+ await Promise.all(
187
+ this.strategy.handleAll({
188
+ params: { cacheKey },
189
+ request,
190
+ event,
191
+ }),
192
+ );
193
+ }
194
+
195
+ const { updatedURLs, notUpdatedURLs } = installReportPlugin;
196
+
197
+ if (process.env.NODE_ENV !== "production") {
198
+ printInstallDetails(updatedURLs, notUpdatedURLs);
199
+ }
200
+
201
+ return { updatedURLs, notUpdatedURLs };
202
+ });
203
+ }
204
+
205
+ /**
206
+ * Deletes assets that are no longer present in the current precache manifest.
207
+ * Call this method from the service worker activate event.
208
+ *
209
+ * Note: this method calls `event.waitUntil()` for you, so you do not need
210
+ * to call it yourself in your event handlers.
211
+ *
212
+ * @param event
213
+ * @returns
214
+ */
215
+ activate(event: ExtendableEvent): Promise<CleanupResult> {
216
+ // waitUntil returns Promise<any>
217
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
218
+ return waitUntil(event, async () => {
219
+ const cache = await self.caches.open(this.strategy.cacheName);
220
+ const currentlyCachedRequests = await cache.keys();
221
+ const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());
222
+
223
+ const deletedURLs = [];
224
+ for (const request of currentlyCachedRequests) {
225
+ if (!expectedCacheKeys.has(request.url)) {
226
+ await cache.delete(request);
227
+ deletedURLs.push(request.url);
228
+ }
229
+ }
230
+
231
+ if (process.env.NODE_ENV !== "production") {
232
+ printCleanupDetails(deletedURLs);
233
+ }
234
+
235
+ return { deletedURLs };
236
+ });
237
+ }
238
+
239
+ /**
240
+ * Returns a mapping of a precached URL to the corresponding cache key, taking
241
+ * into account the revision information for the URL.
242
+ *
243
+ * @returns A URL to cache key mapping.
244
+ */
245
+ getURLsToCacheKeys(): Map<string, string> {
246
+ return this._urlsToCacheKeys;
247
+ }
248
+
249
+ /**
250
+ * Returns a list of all the URLs that have been precached by the current
251
+ * service worker.
252
+ *
253
+ * @returns The precached URLs.
254
+ */
255
+ getCachedURLs(): string[] {
256
+ return [...this._urlsToCacheKeys.keys()];
257
+ }
258
+
259
+ /**
260
+ * Returns the cache key used for storing a given URL. If that URL is
261
+ * unversioned, like `/index.html', then the cache key will be the original
262
+ * URL with a search parameter appended to it.
263
+ *
264
+ * @param url A URL whose cache key you want to look up.
265
+ * @returns The versioned URL that corresponds to a cache key
266
+ * for the original URL, or undefined if that URL isn't precached.
267
+ */
268
+ getCacheKeyForURL(url: string): string | undefined {
269
+ const urlObject = new URL(url, location.href);
270
+ return this._urlsToCacheKeys.get(urlObject.href);
271
+ }
272
+
273
+ /**
274
+ * @param url A cache key whose SRI you want to look up.
275
+ * @returns The subresource integrity associated with the cache key,
276
+ * or undefined if it's not set.
277
+ */
278
+ getIntegrityForCacheKey(cacheKey: string): string | undefined {
279
+ return this._cacheKeysToIntegrities.get(cacheKey);
280
+ }
281
+
282
+ /**
283
+ * This acts as a drop-in replacement for
284
+ * [`cache.match()`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match)
285
+ * with the following differences:
286
+ *
287
+ * - It knows what the name of the precache is, and only checks in that cache.
288
+ * - It allows you to pass in an "original" URL without versioning parameters,
289
+ * and it will automatically look up the correct cache key for the currently
290
+ * active revision of that URL.
291
+ *
292
+ * E.g., `matchPrecache('index.html')` will find the correct precached
293
+ * response for the currently active service worker, even if the actual cache
294
+ * key is `'/index.html?__WB_REVISION__=1234abcd'`.
295
+ *
296
+ * @param request The key (without revisioning parameters)
297
+ * to look up in the precache.
298
+ * @returns
299
+ */
300
+ async matchPrecache(request: string | Request): Promise<Response | undefined> {
301
+ const url = request instanceof Request ? request.url : request;
302
+ const cacheKey = this.getCacheKeyForURL(url);
303
+ if (cacheKey) {
304
+ const cache = await self.caches.open(this.strategy.cacheName);
305
+ return cache.match(cacheKey);
306
+ }
307
+ return undefined;
308
+ }
309
+
310
+ /**
311
+ * Returns a function that looks up `url` in the precache (taking into
312
+ * account revision information), and returns the corresponding `Response`.
313
+ *
314
+ * @param url The precached URL which will be used to lookup the response.
315
+ * @return
316
+ */
317
+ createHandlerBoundToURL(url: string): RouteHandlerCallback {
318
+ const cacheKey = this.getCacheKeyForURL(url);
319
+ if (!cacheKey) {
320
+ throw new SerwistError("non-precached-url", { url });
321
+ }
322
+ return (options) => {
323
+ options.request = new Request(url);
324
+ options.params = { cacheKey, ...options.params };
325
+
326
+ return this.strategy.handle(options);
327
+ };
328
+ }
329
+ }
330
+
331
+ export { PrecacheController };
@@ -0,0 +1,61 @@
1
+ /*
2
+ Copyright 2020 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 { SerwistPlugin } from "@serwist/core";
10
+
11
+ import type { PrecacheController } from "./PrecacheController.js";
12
+ import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheController.js";
13
+
14
+ interface PrecacheFallbackPluginOptions {
15
+ /**
16
+ * A precached URL to use as the fallback
17
+ * if the associated strategy can't generate a response.
18
+ */
19
+ fallbackURL: string;
20
+ /**
21
+ * An optional
22
+ * PrecacheController instance. If not provided, the default
23
+ * PrecacheController will be used.
24
+ */
25
+ precacheController?: PrecacheController;
26
+ }
27
+
28
+ /**
29
+ * `PrecacheFallbackPlugin` allows you to specify an "offline fallback"
30
+ * response to be used when a given strategy is unable to generate a response.
31
+ *
32
+ * It does this by intercepting the `handlerDidError` plugin callback
33
+ * and returning a precached response, taking the expected revision parameter
34
+ * into account automatically.
35
+ *
36
+ * Unless you explicitly pass in a `PrecacheController` instance to the
37
+ * constructor, the default instance will be used. Generally speaking, most
38
+ * developers will end up using the default.
39
+ */
40
+ class PrecacheFallbackPlugin implements SerwistPlugin {
41
+ private readonly _fallbackURL: string;
42
+ private readonly _precacheController: PrecacheController;
43
+
44
+ /**
45
+ * Constructs a new PrecacheFallbackPlugin with the associated fallbackURL.
46
+ *
47
+ * @param config
48
+ */
49
+ constructor({ fallbackURL, precacheController }: PrecacheFallbackPluginOptions) {
50
+ this._fallbackURL = fallbackURL;
51
+ this._precacheController = precacheController || getOrCreatePrecacheController();
52
+ }
53
+
54
+ /**
55
+ * @returns The precache response for the fallback URL.
56
+ * @private
57
+ */
58
+ handlerDidError: SerwistPlugin["handlerDidError"] = () => this._precacheController.matchPrecache(this._fallbackURL);
59
+ }
60
+
61
+ export { PrecacheFallbackPlugin };
@@ -0,0 +1,50 @@
1
+ /*
2
+ Copyright 2020 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 { RouteMatchCallback, RouteMatchCallbackOptions } from "@serwist/core";
10
+ import { getFriendlyURL, logger } from "@serwist/core/internal";
11
+ import { Route } from "@serwist/routing";
12
+
13
+ import type { PrecacheController } from "./PrecacheController.js";
14
+ import type { PrecacheRouteOptions } from "./_types.js";
15
+ import { generateURLVariations } from "./utils/generateURLVariations.js";
16
+
17
+ /**
18
+ * A subclass of `@serwist/routing.Route` that takes a
19
+ * `@serwist/precaching.PrecacheController`
20
+ * instance and uses it to match incoming requests and handle fetching
21
+ * responses from the precache.
22
+ */
23
+ class PrecacheRoute extends Route {
24
+ /**
25
+ * @param precacheController A `PrecacheController`
26
+ * instance used to both match requests and respond to fetch events.
27
+ * @param options Options to control how requests are matched
28
+ * against the list of precached URLs.
29
+ */
30
+ constructor(precacheController: PrecacheController, options?: PrecacheRouteOptions) {
31
+ const match: RouteMatchCallback = ({ request }: RouteMatchCallbackOptions) => {
32
+ const urlsToCacheKeys = precacheController.getURLsToCacheKeys();
33
+ for (const possibleURL of generateURLVariations(request.url, options)) {
34
+ const cacheKey = urlsToCacheKeys.get(possibleURL);
35
+ if (cacheKey) {
36
+ const integrity = precacheController.getIntegrityForCacheKey(cacheKey);
37
+ return { cacheKey, integrity };
38
+ }
39
+ }
40
+ if (process.env.NODE_ENV !== "production") {
41
+ logger.debug(`Precaching did not find a match for ${getFriendlyURL(request.url)}`);
42
+ }
43
+ return;
44
+ };
45
+
46
+ super(match, precacheController.strategy);
47
+ }
48
+ }
49
+
50
+ export { PrecacheRoute };