serwist 9.0.12 → 10.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.
- package/dist/Serwist.d.ts +74 -52
- package/dist/Serwist.d.ts.map +1 -1
- package/dist/chunks/resultingClientExists.js +426 -2
- package/dist/{legacy/utils → controllers/PrecacheController}/PrecacheCacheKeyPlugin.d.ts +4 -4
- package/dist/controllers/PrecacheController/PrecacheCacheKeyPlugin.d.ts.map +1 -0
- package/dist/{legacy → controllers/PrecacheController}/PrecacheController.d.ts +73 -64
- package/dist/controllers/PrecacheController/PrecacheController.d.ts.map +1 -0
- package/dist/controllers/PrecacheController/PrecacheInstallReportPlugin.d.ts +14 -0
- package/dist/controllers/PrecacheController/PrecacheInstallReportPlugin.d.ts.map +1 -0
- package/dist/{PrecacheRoute.d.ts → controllers/PrecacheController/PrecacheRoute.d.ts} +4 -5
- package/dist/controllers/PrecacheController/PrecacheRoute.d.ts.map +1 -0
- package/dist/{lib/strategies → controllers/PrecacheController}/PrecacheStrategy.d.ts +6 -6
- package/dist/controllers/PrecacheController/PrecacheStrategy.d.ts.map +1 -0
- package/dist/controllers/PrecacheController/parsePrecacheOptions.d.ts +25 -0
- package/dist/controllers/PrecacheController/parsePrecacheOptions.d.ts.map +1 -0
- package/dist/controllers/RuntimeCacheController.d.ts +65 -0
- package/dist/controllers/RuntimeCacheController.d.ts.map +1 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.internal.js +25 -3
- package/dist/index.js +1868 -211
- package/dist/lib/backgroundSync/BackgroundSyncPlugin.d.ts +2 -2
- package/dist/lib/backgroundSync/BackgroundSyncPlugin.d.ts.map +1 -1
- package/dist/lib/broadcastUpdate/BroadcastUpdatePlugin.d.ts +2 -2
- package/dist/lib/broadcastUpdate/BroadcastUpdatePlugin.d.ts.map +1 -1
- package/dist/lib/cacheableResponse/CacheableResponsePlugin.d.ts +3 -3
- package/dist/lib/cacheableResponse/CacheableResponsePlugin.d.ts.map +1 -1
- package/dist/lib/expiration/ExpirationPlugin.d.ts +2 -2
- package/dist/lib/expiration/ExpirationPlugin.d.ts.map +1 -1
- package/dist/lib/precaching/PrecacheFallbackPlugin.d.ts +7 -7
- package/dist/lib/precaching/PrecacheFallbackPlugin.d.ts.map +1 -1
- package/dist/lib/rangeRequests/RangeRequestsPlugin.d.ts +3 -3
- package/dist/lib/rangeRequests/RangeRequestsPlugin.d.ts.map +1 -1
- package/dist/lib/strategies/Strategy.d.ts +3 -3
- package/dist/lib/strategies/Strategy.d.ts.map +1 -1
- package/dist/lib/strategies/StrategyHandler.d.ts +4 -4
- package/dist/lib/strategies/StrategyHandler.d.ts.map +1 -1
- package/dist/lib/strategies/plugins/cacheOkAndOpaquePlugin.d.ts +2 -2
- package/dist/lib/strategies/plugins/cacheOkAndOpaquePlugin.d.ts.map +1 -1
- package/dist/types.d.ts +16 -64
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/pluginUtils.d.ts +2 -2
- package/dist/utils/pluginUtils.d.ts.map +1 -1
- package/package.json +5 -12
- package/src/Serwist.ts +157 -262
- package/src/{legacy/utils → controllers/PrecacheController}/PrecacheCacheKeyPlugin.ts +5 -6
- package/src/{legacy → controllers/PrecacheController}/PrecacheController.ts +143 -155
- package/src/{utils → controllers/PrecacheController}/PrecacheInstallReportPlugin.ts +5 -5
- package/src/{PrecacheRoute.ts → controllers/PrecacheController/PrecacheRoute.ts} +11 -12
- package/src/{lib/strategies → controllers/PrecacheController}/PrecacheStrategy.ts +7 -7
- package/src/controllers/PrecacheController/parsePrecacheOptions.ts +46 -0
- package/src/controllers/RuntimeCacheController.ts +119 -0
- package/src/index.ts +5 -2
- package/src/lib/backgroundSync/BackgroundSyncPlugin.ts +2 -2
- package/src/lib/broadcastUpdate/BroadcastUpdatePlugin.ts +2 -2
- package/src/lib/cacheableResponse/CacheableResponsePlugin.ts +3 -3
- package/src/lib/expiration/ExpirationPlugin.ts +2 -2
- package/src/lib/precaching/PrecacheFallbackPlugin.ts +10 -10
- package/src/lib/rangeRequests/RangeRequestsPlugin.ts +3 -3
- package/src/lib/strategies/Strategy.ts +3 -3
- package/src/lib/strategies/StrategyHandler.ts +9 -9
- package/src/lib/strategies/plugins/cacheOkAndOpaquePlugin.ts +2 -2
- package/src/types.ts +24 -67
- package/src/utils/pluginUtils.ts +2 -2
- package/dist/PrecacheRoute.d.ts.map +0 -1
- package/dist/chunks/printInstallDetails.js +0 -1601
- package/dist/chunks/waitUntil.js +0 -449
- package/dist/index.legacy.d.ts +0 -28
- package/dist/index.legacy.d.ts.map +0 -1
- package/dist/index.legacy.js +0 -790
- package/dist/legacy/PrecacheController.d.ts.map +0 -1
- package/dist/legacy/PrecacheFallbackPlugin.d.ts +0 -61
- package/dist/legacy/PrecacheFallbackPlugin.d.ts.map +0 -1
- package/dist/legacy/PrecacheRoute.d.ts +0 -19
- package/dist/legacy/PrecacheRoute.d.ts.map +0 -1
- package/dist/legacy/Router.d.ts +0 -151
- package/dist/legacy/Router.d.ts.map +0 -1
- package/dist/legacy/addPlugins.d.ts +0 -9
- package/dist/legacy/addPlugins.d.ts.map +0 -1
- package/dist/legacy/addRoute.d.ts +0 -14
- package/dist/legacy/addRoute.d.ts.map +0 -1
- package/dist/legacy/constants.d.ts +0 -10
- package/dist/legacy/constants.d.ts.map +0 -1
- package/dist/legacy/createHandlerBoundToURL.d.ts +0 -17
- package/dist/legacy/createHandlerBoundToURL.d.ts.map +0 -1
- package/dist/legacy/fallbacks.d.ts +0 -59
- package/dist/legacy/fallbacks.d.ts.map +0 -1
- package/dist/legacy/getCacheKeyForURL.d.ts +0 -20
- package/dist/legacy/getCacheKeyForURL.d.ts.map +0 -1
- package/dist/legacy/handlePrecaching.d.ts +0 -54
- package/dist/legacy/handlePrecaching.d.ts.map +0 -1
- package/dist/legacy/initializeGoogleAnalytics.d.ts +0 -38
- package/dist/legacy/initializeGoogleAnalytics.d.ts.map +0 -1
- package/dist/legacy/installSerwist.d.ts +0 -81
- package/dist/legacy/installSerwist.d.ts.map +0 -1
- package/dist/legacy/matchPrecache.d.ts +0 -15
- package/dist/legacy/matchPrecache.d.ts.map +0 -1
- package/dist/legacy/precache.d.ts +0 -20
- package/dist/legacy/precache.d.ts.map +0 -1
- package/dist/legacy/precacheAndRoute.d.ts +0 -14
- package/dist/legacy/precacheAndRoute.d.ts.map +0 -1
- package/dist/legacy/registerRoute.d.ts +0 -16
- package/dist/legacy/registerRoute.d.ts.map +0 -1
- package/dist/legacy/registerRuntimeCaching.d.ts +0 -11
- package/dist/legacy/registerRuntimeCaching.d.ts.map +0 -1
- package/dist/legacy/setCatchHandler.d.ts +0 -10
- package/dist/legacy/setCatchHandler.d.ts.map +0 -1
- package/dist/legacy/setDefaultHandler.d.ts +0 -13
- package/dist/legacy/setDefaultHandler.d.ts.map +0 -1
- package/dist/legacy/singletonPrecacheController.d.ts +0 -34
- package/dist/legacy/singletonPrecacheController.d.ts.map +0 -1
- package/dist/legacy/singletonRouter.d.ts +0 -41
- package/dist/legacy/singletonRouter.d.ts.map +0 -1
- package/dist/legacy/unregisterRoute.d.ts +0 -9
- package/dist/legacy/unregisterRoute.d.ts.map +0 -1
- package/dist/legacy/utils/PrecacheCacheKeyPlugin.d.ts.map +0 -1
- package/dist/legacy/utils/getCacheKeyForURL.d.ts +0 -14
- package/dist/legacy/utils/getCacheKeyForURL.d.ts.map +0 -1
- package/dist/lib/strategies/PrecacheStrategy.d.ts.map +0 -1
- package/dist/utils/PrecacheCacheKeyPlugin.d.ts +0 -16
- package/dist/utils/PrecacheCacheKeyPlugin.d.ts.map +0 -1
- package/dist/utils/PrecacheInstallReportPlugin.d.ts +0 -14
- package/dist/utils/PrecacheInstallReportPlugin.d.ts.map +0 -1
- package/dist/utils/parsePrecacheOptions.d.ts +0 -26
- package/dist/utils/parsePrecacheOptions.d.ts.map +0 -1
- package/src/index.legacy.ts +0 -62
- package/src/legacy/PrecacheFallbackPlugin.ts +0 -92
- package/src/legacy/PrecacheRoute.ts +0 -48
- package/src/legacy/Router.ts +0 -484
- package/src/legacy/addPlugins.ts +0 -21
- package/src/legacy/addRoute.ts +0 -27
- package/src/legacy/constants.ts +0 -22
- package/src/legacy/createHandlerBoundToURL.ts +0 -30
- package/src/legacy/fallbacks.ts +0 -94
- package/src/legacy/getCacheKeyForURL.ts +0 -32
- package/src/legacy/handlePrecaching.ts +0 -86
- package/src/legacy/initializeGoogleAnalytics.ts +0 -218
- package/src/legacy/installSerwist.ts +0 -170
- package/src/legacy/matchPrecache.ts +0 -27
- package/src/legacy/precache.ts +0 -33
- package/src/legacy/precacheAndRoute.ts +0 -27
- package/src/legacy/registerRoute.ts +0 -28
- package/src/legacy/registerRuntimeCaching.ts +0 -17
- package/src/legacy/setCatchHandler.ts +0 -21
- package/src/legacy/setDefaultHandler.ts +0 -24
- package/src/legacy/singletonPrecacheController.ts +0 -53
- package/src/legacy/singletonRouter.ts +0 -70
- package/src/legacy/unregisterRoute.ts +0 -13
- package/src/legacy/utils/getCacheKeyForURL.ts +0 -36
- package/src/utils/PrecacheCacheKeyPlugin.ts +0 -33
- package/src/utils/parsePrecacheOptions.ts +0 -47
|
@@ -1,82 +1,110 @@
|
|
|
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
1
|
import { parallel } from "@serwist/utils";
|
|
10
|
-
import {
|
|
11
|
-
import type {
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
2
|
+
import type { Strategy } from "../../lib/strategies/Strategy.js";
|
|
3
|
+
import type { Controller, RouteHandlerCallback, UrlManipulation } from "../../types.js";
|
|
4
|
+
import { assert } from "../../utils/assert.js";
|
|
5
|
+
import { createCacheKey } from "../../utils/createCacheKey.js";
|
|
6
|
+
import { logger } from "../../utils/logger.js";
|
|
7
|
+
import { PrecacheInstallReportPlugin } from "./PrecacheInstallReportPlugin.js";
|
|
8
|
+
import { SerwistError } from "../../utils/SerwistError.js";
|
|
9
|
+
import { printInstallDetails } from "../../utils/printInstallDetails.js";
|
|
10
|
+
import { printCleanupDetails } from "../../utils/printCleanupDetails.js";
|
|
11
|
+
import { PrecacheStrategy } from "./PrecacheStrategy.js";
|
|
12
|
+
import { PrecacheRoute } from "./PrecacheRoute.js";
|
|
13
|
+
import type { Serwist } from "../../Serwist.js";
|
|
14
|
+
import { NavigationRoute } from "../../NavigationRoute.js";
|
|
15
|
+
import type { PrecacheStrategyOptions } from "./PrecacheStrategy.js";
|
|
16
|
+
import { parsePrecacheOptions } from "./parsePrecacheOptions.js";
|
|
17
|
+
|
|
18
|
+
export interface PrecacheEntry {
|
|
19
|
+
integrity?: string;
|
|
20
|
+
url: string;
|
|
21
|
+
revision?: string | null;
|
|
22
|
+
}
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
export interface PrecacheRouteOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Tells Serwist to check the precache for an entry whose URL is the request URL appended
|
|
27
|
+
* with the specified value. Only applies if the request URL ends with "/".
|
|
28
|
+
*
|
|
29
|
+
* @default "index.html"
|
|
30
|
+
*/
|
|
31
|
+
directoryIndex?: string | null;
|
|
32
|
+
/**
|
|
33
|
+
* An array of `RegExp` objects matching search params that should be removed when looking
|
|
34
|
+
* for a precache match.
|
|
35
|
+
*/
|
|
36
|
+
ignoreURLParametersMatching?: RegExp[];
|
|
37
|
+
/**
|
|
38
|
+
* Tells Serwist to check the precache for an entry whose URL is the request URL appended
|
|
39
|
+
* with ".html".
|
|
40
|
+
*
|
|
41
|
+
* @default true
|
|
42
|
+
*/
|
|
43
|
+
cleanURLs?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* A function that should take a URL and return an array of alternative URLs that should
|
|
46
|
+
* be checked for precache matches.
|
|
47
|
+
*/
|
|
48
|
+
urlManipulation?: UrlManipulation;
|
|
49
|
+
}
|
|
27
50
|
|
|
28
|
-
interface PrecacheControllerOptions {
|
|
51
|
+
export interface PrecacheControllerOptions {
|
|
29
52
|
/**
|
|
30
53
|
* The cache to use for precaching.
|
|
31
54
|
*/
|
|
32
55
|
cacheName?: string;
|
|
33
56
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
|
|
37
|
-
plugins?: SerwistPlugin[];
|
|
38
|
-
/**
|
|
39
|
-
* Whether to attempt to get the response from the network if there's
|
|
40
|
-
* a precache miss.
|
|
57
|
+
* Whether outdated caches should be removed.
|
|
58
|
+
*
|
|
59
|
+
* @default false
|
|
41
60
|
*/
|
|
42
|
-
|
|
61
|
+
cleanupOutdatedCaches?: boolean;
|
|
43
62
|
/**
|
|
44
63
|
* The number of precache requests that should be made concurrently.
|
|
45
64
|
*
|
|
46
|
-
* @default
|
|
65
|
+
* @default 10
|
|
66
|
+
*/
|
|
67
|
+
concurrency?: number;
|
|
68
|
+
/**
|
|
69
|
+
* An URL that should point to a HTML file with which navigation requests for URLs that aren't
|
|
70
|
+
* precached will be fulfilled.
|
|
71
|
+
*/
|
|
72
|
+
navigateFallback?: string;
|
|
73
|
+
/**
|
|
74
|
+
* URLs that should be allowed to use the `navigateFallback` handler.
|
|
75
|
+
*/
|
|
76
|
+
navigateFallbackAllowlist?: RegExp[];
|
|
77
|
+
/**
|
|
78
|
+
* URLs that should not be allowed to use the `navigateFallback` handler. This takes precedence
|
|
79
|
+
* over `navigateFallbackAllowlist`.
|
|
47
80
|
*/
|
|
48
|
-
|
|
81
|
+
navigateFallbackDenylist?: RegExp[];
|
|
49
82
|
}
|
|
50
83
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
*/
|
|
55
|
-
export class PrecacheController {
|
|
56
|
-
private _installAndActiveListenersAdded?: boolean;
|
|
57
|
-
private _concurrentPrecaching: number;
|
|
58
|
-
private readonly _strategy: Strategy;
|
|
84
|
+
export interface PrecacheOptions extends PrecacheStrategyOptions, PrecacheRouteOptions, PrecacheControllerOptions {}
|
|
85
|
+
|
|
86
|
+
export class PrecacheController implements Controller {
|
|
59
87
|
private readonly _urlsToCacheKeys: Map<string, string> = new Map();
|
|
60
88
|
private readonly _urlsToCacheModes: Map<string, "reload" | "default" | "no-store" | "no-cache" | "force-cache" | "only-if-cached"> = new Map();
|
|
61
89
|
private readonly _cacheKeysToIntegrities: Map<string, string> = new Map();
|
|
62
|
-
|
|
90
|
+
private readonly _strategy: Strategy;
|
|
91
|
+
private _options: PrecacheControllerOptions;
|
|
92
|
+
private _routeOptions: PrecacheRouteOptions;
|
|
63
93
|
/**
|
|
64
94
|
* Create a new PrecacheController.
|
|
65
95
|
*
|
|
66
96
|
* @param options
|
|
67
97
|
*/
|
|
68
|
-
constructor(
|
|
69
|
-
|
|
70
|
-
this.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
});
|
|
98
|
+
constructor(entries: (PrecacheEntry | string)[], precacheOptions?: PrecacheOptions) {
|
|
99
|
+
const { strategyOptions, routeOptions, controllerOptions } = parsePrecacheOptions(this, precacheOptions);
|
|
100
|
+
this.addToCacheList(entries);
|
|
101
|
+
this._strategy = new PrecacheStrategy(strategyOptions);
|
|
102
|
+
this._options = controllerOptions;
|
|
103
|
+
this._routeOptions = routeOptions;
|
|
75
104
|
// Bind the install and activate methods to the instance.
|
|
76
105
|
this.install = this.install.bind(this);
|
|
77
106
|
this.activate = this.activate.bind(this);
|
|
78
107
|
}
|
|
79
|
-
|
|
80
108
|
/**
|
|
81
109
|
* The strategy created by this controller and
|
|
82
110
|
* used to cache assets and respond to `fetch` events.
|
|
@@ -84,38 +112,17 @@ export class PrecacheController {
|
|
|
84
112
|
get strategy(): Strategy {
|
|
85
113
|
return this._strategy;
|
|
86
114
|
}
|
|
87
|
-
|
|
88
115
|
/**
|
|
89
|
-
* Adds items to the
|
|
90
|
-
* stores the files in the precache cache when the service
|
|
91
|
-
* worker installs.
|
|
92
|
-
*
|
|
93
|
-
* This method can be called multiple times.
|
|
94
|
-
*
|
|
95
|
-
* @param entries Array of entries to precache.
|
|
96
|
-
*/
|
|
97
|
-
precache(entries: (PrecacheEntry | string)[]): void {
|
|
98
|
-
this.addToCacheList(entries);
|
|
99
|
-
|
|
100
|
-
if (!this._installAndActiveListenersAdded) {
|
|
101
|
-
self.addEventListener("install", this.install);
|
|
102
|
-
self.addEventListener("activate", this.activate);
|
|
103
|
-
this._installAndActiveListenersAdded = true;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* This method will add items to the precache list, removing duplicates
|
|
109
|
-
* and ensuring the information is valid.
|
|
116
|
+
* Adds items to the cache list, removing duplicates and ensuring the information is valid.
|
|
110
117
|
*
|
|
111
118
|
* @param entries Array of entries to precache.
|
|
112
119
|
*/
|
|
113
120
|
addToCacheList(entries: (PrecacheEntry | string)[]): void {
|
|
114
121
|
if (process.env.NODE_ENV !== "production") {
|
|
115
122
|
assert!.isArray(entries, {
|
|
116
|
-
moduleName: "serwist
|
|
123
|
+
moduleName: "serwist",
|
|
117
124
|
className: "PrecacheController",
|
|
118
|
-
funcName: "
|
|
125
|
+
funcName: "addEntries",
|
|
119
126
|
paramName: "entries",
|
|
120
127
|
});
|
|
121
128
|
}
|
|
@@ -154,7 +161,7 @@ export class PrecacheController {
|
|
|
154
161
|
if (urlsToWarnAbout.length > 0) {
|
|
155
162
|
const warningMessage = `Serwist is precaching URLs without revision info: ${urlsToWarnAbout.join(
|
|
156
163
|
", ",
|
|
157
|
-
)}\nThis is generally NOT safe
|
|
164
|
+
)}\nThis is generally NOT safe, as you risk serving outdated assets.`;
|
|
158
165
|
if (process.env.NODE_ENV === "production") {
|
|
159
166
|
// Use console directly to display this warning without bloating
|
|
160
167
|
// bundle sizes by pulling in all of the logger codebase in prod.
|
|
@@ -165,83 +172,64 @@ export class PrecacheController {
|
|
|
165
172
|
}
|
|
166
173
|
}
|
|
167
174
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
credentials: "same-origin",
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
await Promise.all(
|
|
195
|
-
this.strategy.handleAll({
|
|
196
|
-
event,
|
|
197
|
-
request,
|
|
198
|
-
url: new URL(request.url),
|
|
199
|
-
params: { cacheKey },
|
|
200
|
-
}),
|
|
201
|
-
);
|
|
175
|
+
init(serwist: Serwist) {
|
|
176
|
+
serwist.registerRoute(new PrecacheRoute(this, this._routeOptions));
|
|
177
|
+
|
|
178
|
+
if (this._options.navigateFallback) {
|
|
179
|
+
serwist.registerRoute(
|
|
180
|
+
new NavigationRoute(this.createHandlerBoundToUrl(this._options.navigateFallback), {
|
|
181
|
+
allowlist: this._options.navigateFallbackAllowlist,
|
|
182
|
+
denylist: this._options.navigateFallbackDenylist,
|
|
183
|
+
}),
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
async install(event: ExtendableEvent): Promise<void> {
|
|
188
|
+
const installReportPlugin = new PrecacheInstallReportPlugin();
|
|
189
|
+
this._strategy.plugins.push(installReportPlugin);
|
|
190
|
+
await parallel(this._options.concurrency!, Array.from(this._urlsToCacheKeys.entries()), async ([url, cacheKey]): Promise<void> => {
|
|
191
|
+
const integrity = this._cacheKeysToIntegrities.get(cacheKey);
|
|
192
|
+
const cacheMode = this._urlsToCacheModes.get(url);
|
|
193
|
+
|
|
194
|
+
const request = new Request(url, {
|
|
195
|
+
integrity,
|
|
196
|
+
cache: cacheMode,
|
|
197
|
+
credentials: "same-origin",
|
|
202
198
|
});
|
|
203
199
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
200
|
+
await Promise.all(
|
|
201
|
+
this._strategy.handleAll({
|
|
202
|
+
event,
|
|
203
|
+
request,
|
|
204
|
+
url: new URL(request.url),
|
|
205
|
+
params: { cacheKey },
|
|
206
|
+
}),
|
|
207
|
+
);
|
|
211
208
|
});
|
|
212
|
-
}
|
|
213
209
|
|
|
214
|
-
|
|
215
|
-
* Deletes assets that are no longer present in the current precache manifest.
|
|
216
|
-
* Call this method from the service worker activate event.
|
|
217
|
-
*
|
|
218
|
-
* Note: this method calls `event.waitUntil()` for you, so you do not need
|
|
219
|
-
* to call it yourself in your event handlers.
|
|
220
|
-
*
|
|
221
|
-
* @param event
|
|
222
|
-
* @returns
|
|
223
|
-
*/
|
|
224
|
-
activate(event: ExtendableEvent): Promise<CleanupResult> {
|
|
225
|
-
return waitUntil<CleanupResult>(event, async () => {
|
|
226
|
-
const cache = await self.caches.open(this.strategy.cacheName);
|
|
227
|
-
const currentlyCachedRequests = await cache.keys();
|
|
228
|
-
const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());
|
|
210
|
+
const { updatedURLs, notUpdatedURLs } = installReportPlugin;
|
|
229
211
|
|
|
230
|
-
|
|
212
|
+
if (process.env.NODE_ENV !== "production") {
|
|
213
|
+
printInstallDetails(updatedURLs, notUpdatedURLs);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
async activate(): Promise<void> {
|
|
217
|
+
const cache = await self.caches.open(this._strategy.cacheName);
|
|
218
|
+
const currentlyCachedRequests = await cache.keys();
|
|
219
|
+
const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());
|
|
231
220
|
|
|
232
|
-
|
|
233
|
-
if (!expectedCacheKeys.has(request.url)) {
|
|
234
|
-
await cache.delete(request);
|
|
235
|
-
deletedCacheRequests.push(request.url);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
221
|
+
const deletedCacheRequests: string[] = [];
|
|
238
222
|
|
|
239
|
-
|
|
240
|
-
|
|
223
|
+
for (const request of currentlyCachedRequests) {
|
|
224
|
+
if (!expectedCacheKeys.has(request.url)) {
|
|
225
|
+
await cache.delete(request);
|
|
226
|
+
deletedCacheRequests.push(request.url);
|
|
241
227
|
}
|
|
228
|
+
}
|
|
242
229
|
|
|
243
|
-
|
|
244
|
-
|
|
230
|
+
if (process.env.NODE_ENV !== "production") {
|
|
231
|
+
printCleanupDetails(deletedCacheRequests);
|
|
232
|
+
}
|
|
245
233
|
}
|
|
246
234
|
|
|
247
235
|
/**
|
|
@@ -250,7 +238,7 @@ export class PrecacheController {
|
|
|
250
238
|
*
|
|
251
239
|
* @returns A URL to cache key mapping.
|
|
252
240
|
*/
|
|
253
|
-
|
|
241
|
+
getUrlsToPrecacheKeys(): Map<string, string> {
|
|
254
242
|
return this._urlsToCacheKeys;
|
|
255
243
|
}
|
|
256
244
|
|
|
@@ -260,20 +248,20 @@ export class PrecacheController {
|
|
|
260
248
|
*
|
|
261
249
|
* @returns The precached URLs.
|
|
262
250
|
*/
|
|
263
|
-
|
|
251
|
+
getPrecachedUrls(): string[] {
|
|
264
252
|
return [...this._urlsToCacheKeys.keys()];
|
|
265
253
|
}
|
|
266
254
|
|
|
267
255
|
/**
|
|
268
256
|
* Returns the cache key used for storing a given URL. If that URL is
|
|
269
|
-
* unversioned, like
|
|
257
|
+
* unversioned, like "/index.html", then the cache key will be the original
|
|
270
258
|
* URL with a search parameter appended to it.
|
|
271
259
|
*
|
|
272
260
|
* @param url A URL whose cache key you want to look up.
|
|
273
261
|
* @returns The versioned URL that corresponds to a cache key
|
|
274
262
|
* for the original URL, or undefined if that URL isn't precached.
|
|
275
263
|
*/
|
|
276
|
-
|
|
264
|
+
getPrecacheKeyForUrl(url: string): string | undefined {
|
|
277
265
|
const urlObject = new URL(url, location.href);
|
|
278
266
|
return this._urlsToCacheKeys.get(urlObject.href);
|
|
279
267
|
}
|
|
@@ -283,7 +271,7 @@ export class PrecacheController {
|
|
|
283
271
|
* @returns The subresource integrity associated with the cache key,
|
|
284
272
|
* or undefined if it's not set.
|
|
285
273
|
*/
|
|
286
|
-
|
|
274
|
+
getIntegrityForPrecacheKey(cacheKey: string): string | undefined {
|
|
287
275
|
return this._cacheKeysToIntegrities.get(cacheKey);
|
|
288
276
|
}
|
|
289
277
|
|
|
@@ -307,9 +295,9 @@ export class PrecacheController {
|
|
|
307
295
|
*/
|
|
308
296
|
async matchPrecache(request: string | Request): Promise<Response | undefined> {
|
|
309
297
|
const url = request instanceof Request ? request.url : request;
|
|
310
|
-
const cacheKey = this.
|
|
298
|
+
const cacheKey = this.getPrecacheKeyForUrl(url);
|
|
311
299
|
if (cacheKey) {
|
|
312
|
-
const cache = await self.caches.open(this.
|
|
300
|
+
const cache = await self.caches.open(this._strategy.cacheName);
|
|
313
301
|
return cache.match(cacheKey);
|
|
314
302
|
}
|
|
315
303
|
return undefined;
|
|
@@ -322,8 +310,8 @@ export class PrecacheController {
|
|
|
322
310
|
* @param url The precached URL which will be used to lookup the response.
|
|
323
311
|
* @return
|
|
324
312
|
*/
|
|
325
|
-
|
|
326
|
-
const cacheKey = this.
|
|
313
|
+
createHandlerBoundToUrl(url: string): RouteHandlerCallback {
|
|
314
|
+
const cacheKey = this.getPrecacheKeyForUrl(url);
|
|
327
315
|
if (!cacheKey) {
|
|
328
316
|
throw new SerwistError("non-precached-url", { url });
|
|
329
317
|
}
|
|
@@ -331,7 +319,7 @@ export class PrecacheController {
|
|
|
331
319
|
options.request = new Request(url);
|
|
332
320
|
options.params = { cacheKey, ...options.params };
|
|
333
321
|
|
|
334
|
-
return this.
|
|
322
|
+
return this._strategy.handle(options);
|
|
335
323
|
};
|
|
336
324
|
}
|
|
337
325
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
https://opensource.org/licenses/MIT.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type {
|
|
9
|
+
import type { StrategyPlugin, StrategyPluginCallbackParam } from "../../types.js";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* A plugin designed to determine the number of assets that were updated (or not updated)
|
|
@@ -14,22 +14,22 @@ import type { SerwistPlugin, SerwistPluginCallbackParam } from "../types.js";
|
|
|
14
14
|
*
|
|
15
15
|
* @private
|
|
16
16
|
*/
|
|
17
|
-
export class PrecacheInstallReportPlugin implements
|
|
17
|
+
export class PrecacheInstallReportPlugin implements StrategyPlugin {
|
|
18
18
|
updatedURLs: string[] = [];
|
|
19
19
|
notUpdatedURLs: string[] = [];
|
|
20
20
|
|
|
21
|
-
handlerWillStart:
|
|
21
|
+
handlerWillStart: StrategyPlugin["handlerWillStart"] = async ({ request, state }: StrategyPluginCallbackParam["handlerWillStart"]) => {
|
|
22
22
|
// TODO: `state` should never be undefined...
|
|
23
23
|
if (state) {
|
|
24
24
|
state.originalRequest = request;
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
cachedResponseWillBeUsed:
|
|
28
|
+
cachedResponseWillBeUsed: StrategyPlugin["cachedResponseWillBeUsed"] = async ({
|
|
29
29
|
event,
|
|
30
30
|
state,
|
|
31
31
|
cachedResponse,
|
|
32
|
-
}:
|
|
32
|
+
}: StrategyPluginCallbackParam["cachedResponseWillBeUsed"]) => {
|
|
33
33
|
if (event.type === "install") {
|
|
34
34
|
if (state?.originalRequest && state.originalRequest instanceof Request) {
|
|
35
35
|
// TODO: `state` should never be undefined...
|
|
@@ -6,13 +6,12 @@
|
|
|
6
6
|
https://opensource.org/licenses/MIT.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { Route } from "
|
|
10
|
-
import type {
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import { logger } from "./utils/logger.js";
|
|
9
|
+
import { Route } from "../../Route.js";
|
|
10
|
+
import type { RouteMatchCallback, RouteMatchCallbackOptions } from "../../types.js";
|
|
11
|
+
import { generateURLVariations } from "../../utils/generateURLVariations.js";
|
|
12
|
+
import { getFriendlyURL } from "../../utils/getFriendlyURL.js";
|
|
13
|
+
import { logger } from "../../utils/logger.js";
|
|
14
|
+
import type { PrecacheController, PrecacheRouteOptions } from "./PrecacheController.js";
|
|
16
15
|
|
|
17
16
|
/**
|
|
18
17
|
* A subclass of {@linkcode Route} that takes a {@linkcode Serwist} instance and uses it to match
|
|
@@ -20,17 +19,17 @@ import { logger } from "./utils/logger.js";
|
|
|
20
19
|
*/
|
|
21
20
|
export class PrecacheRoute extends Route {
|
|
22
21
|
/**
|
|
23
|
-
* @param
|
|
22
|
+
* @param controller A {@linkcode PrecacheController} instance.
|
|
24
23
|
* @param options Options to control how requests are matched
|
|
25
24
|
* against the list of precached URLs.
|
|
26
25
|
*/
|
|
27
|
-
constructor(
|
|
26
|
+
constructor(controller: PrecacheController, options?: PrecacheRouteOptions) {
|
|
28
27
|
const match: RouteMatchCallback = ({ request }: RouteMatchCallbackOptions) => {
|
|
29
|
-
const urlsToCacheKeys =
|
|
28
|
+
const urlsToCacheKeys = controller.getUrlsToPrecacheKeys();
|
|
30
29
|
for (const possibleURL of generateURLVariations(request.url, options)) {
|
|
31
30
|
const cacheKey = urlsToCacheKeys.get(possibleURL);
|
|
32
31
|
if (cacheKey) {
|
|
33
|
-
const integrity =
|
|
32
|
+
const integrity = controller.getIntegrityForPrecacheKey(cacheKey);
|
|
34
33
|
return { cacheKey, integrity };
|
|
35
34
|
}
|
|
36
35
|
}
|
|
@@ -40,6 +39,6 @@ export class PrecacheRoute extends Route {
|
|
|
40
39
|
return;
|
|
41
40
|
};
|
|
42
41
|
|
|
43
|
-
super(match,
|
|
42
|
+
super(match, controller.strategy);
|
|
44
43
|
}
|
|
45
44
|
}
|
|
@@ -7,15 +7,15 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { copyResponse } from "../../copyResponse.js";
|
|
10
|
-
import type {
|
|
10
|
+
import type { StrategyPlugin } from "../../types.js";
|
|
11
11
|
import { SerwistError } from "../../utils/SerwistError.js";
|
|
12
12
|
import { cacheNames as privateCacheNames } from "../../utils/cacheNames.js";
|
|
13
13
|
import { getFriendlyURL } from "../../utils/getFriendlyURL.js";
|
|
14
14
|
import { logger } from "../../utils/logger.js";
|
|
15
15
|
import type { Serwist } from "../../Serwist.js";
|
|
16
|
-
import type { StrategyOptions } from "
|
|
17
|
-
import { Strategy } from "
|
|
18
|
-
import type { StrategyHandler } from "
|
|
16
|
+
import type { StrategyOptions } from "../../lib/strategies/Strategy.js";
|
|
17
|
+
import { Strategy } from "../../lib/strategies/Strategy.js";
|
|
18
|
+
import type { StrategyHandler } from "../../lib/strategies/StrategyHandler.js";
|
|
19
19
|
|
|
20
20
|
export interface PrecacheStrategyOptions extends StrategyOptions {
|
|
21
21
|
/**
|
|
@@ -39,7 +39,7 @@ export interface PrecacheStrategyOptions extends StrategyOptions {
|
|
|
39
39
|
export class PrecacheStrategy extends Strategy {
|
|
40
40
|
private readonly _fallbackToNetwork: boolean;
|
|
41
41
|
|
|
42
|
-
static readonly defaultPrecacheCacheabilityPlugin:
|
|
42
|
+
static readonly defaultPrecacheCacheabilityPlugin: StrategyPlugin = {
|
|
43
43
|
async cacheWillUpdate({ response }) {
|
|
44
44
|
if (!response || response.status >= 400) {
|
|
45
45
|
return null;
|
|
@@ -49,7 +49,7 @@ export class PrecacheStrategy extends Strategy {
|
|
|
49
49
|
},
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
-
static readonly copyRedirectedCacheableResponsesPlugin:
|
|
52
|
+
static readonly copyRedirectedCacheableResponsesPlugin: StrategyPlugin = {
|
|
53
53
|
async cacheWillUpdate({ response }) {
|
|
54
54
|
return response.redirected ? await copyResponse(response) : response;
|
|
55
55
|
},
|
|
@@ -63,7 +63,7 @@ export class PrecacheStrategy extends Strategy {
|
|
|
63
63
|
|
|
64
64
|
super(options);
|
|
65
65
|
|
|
66
|
-
this._fallbackToNetwork = options.fallbackToNetwork
|
|
66
|
+
this._fallbackToNetwork = options.fallbackToNetwork !== false;
|
|
67
67
|
|
|
68
68
|
// Redirected responses cannot be used to satisfy a navigation request, so
|
|
69
69
|
// any redirected response must be "copied" rather than cloned, so the new
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { PrecacheStrategyOptions } from "./PrecacheStrategy.js";
|
|
2
|
+
import type { PrecacheController, PrecacheControllerOptions, PrecacheOptions, PrecacheRouteOptions } from "./PrecacheController.js";
|
|
3
|
+
import type { Require } from "@serwist/utils";
|
|
4
|
+
import { privateCacheNames } from "../../index.internal.js";
|
|
5
|
+
import { PrecacheCacheKeyPlugin } from "./PrecacheCacheKeyPlugin.js";
|
|
6
|
+
|
|
7
|
+
export const parsePrecacheOptions = (
|
|
8
|
+
controller: PrecacheController,
|
|
9
|
+
{
|
|
10
|
+
cacheName,
|
|
11
|
+
plugins,
|
|
12
|
+
fetchOptions,
|
|
13
|
+
matchOptions,
|
|
14
|
+
fallbackToNetwork,
|
|
15
|
+
directoryIndex,
|
|
16
|
+
ignoreURLParametersMatching,
|
|
17
|
+
cleanURLs,
|
|
18
|
+
urlManipulation,
|
|
19
|
+
cleanupOutdatedCaches,
|
|
20
|
+
concurrency,
|
|
21
|
+
navigateFallback,
|
|
22
|
+
navigateFallbackAllowlist,
|
|
23
|
+
navigateFallbackDenylist,
|
|
24
|
+
}: PrecacheOptions = {},
|
|
25
|
+
) => ({
|
|
26
|
+
strategyOptions: {
|
|
27
|
+
cacheName: privateCacheNames.getPrecacheName(cacheName),
|
|
28
|
+
plugins: [...(plugins ?? []), new PrecacheCacheKeyPlugin({ precacheController: controller })],
|
|
29
|
+
fetchOptions,
|
|
30
|
+
matchOptions,
|
|
31
|
+
fallbackToNetwork,
|
|
32
|
+
} satisfies Require<PrecacheStrategyOptions, "cacheName" | "plugins">,
|
|
33
|
+
routeOptions: {
|
|
34
|
+
directoryIndex,
|
|
35
|
+
ignoreURLParametersMatching,
|
|
36
|
+
cleanURLs,
|
|
37
|
+
urlManipulation,
|
|
38
|
+
} satisfies PrecacheRouteOptions,
|
|
39
|
+
controllerOptions: {
|
|
40
|
+
cleanupOutdatedCaches,
|
|
41
|
+
concurrency: concurrency ?? 10,
|
|
42
|
+
navigateFallback,
|
|
43
|
+
navigateFallbackAllowlist,
|
|
44
|
+
navigateFallbackDenylist,
|
|
45
|
+
} satisfies Require<PrecacheControllerOptions, "concurrency">,
|
|
46
|
+
});
|