@serwist/precaching 9.0.0-preview.5 → 9.0.0-preview.7
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/PrecacheController.d.ts +11 -3
- package/dist/PrecacheController.d.ts.map +1 -1
- package/dist/addRoute.d.ts +1 -2
- package/dist/addRoute.d.ts.map +1 -1
- package/dist/cleanupOutdatedCaches.d.ts +1 -2
- package/dist/cleanupOutdatedCaches.d.ts.map +1 -1
- package/dist/index.js +51 -16
- package/dist/precache.d.ts +1 -2
- package/dist/precache.d.ts.map +1 -1
- package/dist/precacheAndRoute.d.ts +1 -2
- package/dist/precacheAndRoute.d.ts.map +1 -1
- package/dist/utils/deleteOutdatedCaches.d.ts +1 -2
- package/dist/utils/deleteOutdatedCaches.d.ts.map +1 -1
- package/package.json +6 -5
- package/src/PrecacheController.ts +31 -19
- package/src/addRoute.ts +2 -4
- package/src/cleanupOutdatedCaches.ts +7 -8
- package/src/precache.ts +2 -4
- package/src/precacheAndRoute.ts +2 -4
- package/src/utils/deleteOutdatedCaches.ts +1 -3
|
@@ -16,12 +16,20 @@ interface PrecacheControllerOptions {
|
|
|
16
16
|
* a precache miss.
|
|
17
17
|
*/
|
|
18
18
|
fallbackToNetwork?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* A number of how many precache requests should be made concurrently.
|
|
21
|
+
* By default, this value is set to 1, but this can be overriden by
|
|
22
|
+
* setting this option or `self.__WB_CONCURRENT_PRECACHING`. The former takes
|
|
23
|
+
* precedence over the latter.
|
|
24
|
+
*/
|
|
25
|
+
concurrentPrecaching?: number;
|
|
19
26
|
}
|
|
20
27
|
/**
|
|
21
28
|
* Performs efficient precaching of assets.
|
|
22
29
|
*/
|
|
23
|
-
declare class PrecacheController {
|
|
30
|
+
export declare class PrecacheController {
|
|
24
31
|
private _installAndActiveListenersAdded?;
|
|
32
|
+
private _concurrentPrecaching;
|
|
25
33
|
private readonly _strategy;
|
|
26
34
|
private readonly _urlsToCacheKeys;
|
|
27
35
|
private readonly _urlsToCacheModes;
|
|
@@ -31,7 +39,7 @@ declare class PrecacheController {
|
|
|
31
39
|
*
|
|
32
40
|
* @param options
|
|
33
41
|
*/
|
|
34
|
-
constructor({ cacheName, plugins, fallbackToNetwork }?: PrecacheControllerOptions);
|
|
42
|
+
constructor({ cacheName, plugins, fallbackToNetwork, concurrentPrecaching }?: PrecacheControllerOptions);
|
|
35
43
|
/**
|
|
36
44
|
* The strategy created by this controller and
|
|
37
45
|
* used to cache assets and respond to fetch events.
|
|
@@ -134,5 +142,5 @@ declare class PrecacheController {
|
|
|
134
142
|
*/
|
|
135
143
|
createHandlerBoundToURL(url: string): RouteHandlerCallback;
|
|
136
144
|
}
|
|
137
|
-
export {
|
|
145
|
+
export {};
|
|
138
146
|
//# sourceMappingURL=PrecacheController.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PrecacheController.d.ts","sourceRoot":"","sources":["../src/PrecacheController.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"PrecacheController.d.ts","sourceRoot":"","sources":["../src/PrecacheController.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAIpD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAU/E,UAAU,yBAAyB;IACjC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,+BAA+B,CAAC,CAAU;IAClD,OAAO,CAAC,qBAAqB,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkC;IACnE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA6G;IAC/I,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAkC;IAE1E;;;;OAIG;gBACS,EAAE,SAAS,EAAE,OAAY,EAAE,iBAAwB,EAAE,oBAAoB,EAAE,GAAE,yBAA8B;IAavH;;;OAGG;IACH,IAAI,QAAQ,IAAI,QAAQ,CAEvB;IAED;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI;IAUnD;;;;;OAKG;IACH,cAAc,CAAC,OAAO,EAAE,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI;IAwDzD;;;;;;;;;OASG;IACH,OAAO,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC;IA2CvD;;;;;;;;;OASG;IACH,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC;IAuBxD;;;;;OAKG;IACH,kBAAkB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAIzC;;;;;OAKG;IACH,aAAa,IAAI,MAAM,EAAE;IAIzB;;;;;;;;OAQG;IACH,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKlD;;;;OAIG;IACH,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI7D;;;;;;;;;;;;;;;;;OAiBG;IACG,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAU7E;;;;;;OAMG;IACH,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB;CAY3D"}
|
package/dist/addRoute.d.ts
CHANGED
|
@@ -11,6 +11,5 @@ import type { PrecacheRouteOptions } from "./_types.js";
|
|
|
11
11
|
*
|
|
12
12
|
* @param options See the `@serwist/precaching.PrecacheRoute` options.
|
|
13
13
|
*/
|
|
14
|
-
declare
|
|
15
|
-
export { addRoute };
|
|
14
|
+
export declare const addRoute: (options?: PrecacheRouteOptions) => void;
|
|
16
15
|
//# sourceMappingURL=addRoute.d.ts.map
|
package/dist/addRoute.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addRoute.d.ts","sourceRoot":"","sources":["../src/addRoute.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGxD;;;;;;;;;;;GAWG;AACH,
|
|
1
|
+
{"version":3,"file":"addRoute.d.ts","sourceRoot":"","sources":["../src/addRoute.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGxD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ,aAAc,oBAAoB,KAAG,IAKzD,CAAC"}
|
|
@@ -2,6 +2,5 @@
|
|
|
2
2
|
* Adds an `activate` event listener which will clean up incompatible
|
|
3
3
|
* precaches that were created by older versions of Serwist.
|
|
4
4
|
*/
|
|
5
|
-
declare
|
|
6
|
-
export { cleanupOutdatedCaches };
|
|
5
|
+
export declare const cleanupOutdatedCaches: () => void;
|
|
7
6
|
//# sourceMappingURL=cleanupOutdatedCaches.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cleanupOutdatedCaches.d.ts","sourceRoot":"","sources":["../src/cleanupOutdatedCaches.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cleanupOutdatedCaches.d.ts","sourceRoot":"","sources":["../src/cleanupOutdatedCaches.ts"],"names":[],"mappings":"AAcA;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAAO,IAcxC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,32 @@ import { copyResponse } from '@serwist/core';
|
|
|
3
3
|
import { Strategy } from '@serwist/strategies';
|
|
4
4
|
import { Route, registerRoute } from '@serwist/routing';
|
|
5
5
|
|
|
6
|
+
const parallel = async (limit, array, func)=>{
|
|
7
|
+
const work = array.map((item, index)=>({
|
|
8
|
+
index,
|
|
9
|
+
item
|
|
10
|
+
}));
|
|
11
|
+
const processor = async (res)=>{
|
|
12
|
+
const results = [];
|
|
13
|
+
while(true){
|
|
14
|
+
const next = work.pop();
|
|
15
|
+
if (!next) {
|
|
16
|
+
return res(results);
|
|
17
|
+
}
|
|
18
|
+
const result = await func(next.item);
|
|
19
|
+
results.push({
|
|
20
|
+
result: result,
|
|
21
|
+
index: next.index
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const queues = Array.from({
|
|
26
|
+
length: limit
|
|
27
|
+
}, ()=>new Promise(processor));
|
|
28
|
+
const results = (await Promise.all(queues)).flat().sort((a, b)=>a.index < b.index ? -1 : 1).map((res)=>res.result);
|
|
29
|
+
return results;
|
|
30
|
+
};
|
|
31
|
+
|
|
6
32
|
class PrecacheStrategy extends Strategy {
|
|
7
33
|
_fallbackToNetwork;
|
|
8
34
|
static defaultPrecacheCacheabilityPlugin = {
|
|
@@ -225,11 +251,12 @@ function printInstallDetails(urlsToPrecache, urlsAlreadyPrecached) {
|
|
|
225
251
|
|
|
226
252
|
class PrecacheController {
|
|
227
253
|
_installAndActiveListenersAdded;
|
|
254
|
+
_concurrentPrecaching;
|
|
228
255
|
_strategy;
|
|
229
256
|
_urlsToCacheKeys = new Map();
|
|
230
257
|
_urlsToCacheModes = new Map();
|
|
231
258
|
_cacheKeysToIntegrities = new Map();
|
|
232
|
-
constructor({ cacheName, plugins = [], fallbackToNetwork = true } = {}){
|
|
259
|
+
constructor({ cacheName, plugins = [], fallbackToNetwork = true, concurrentPrecaching } = {}){
|
|
233
260
|
this._strategy = new PrecacheStrategy({
|
|
234
261
|
cacheName: privateCacheNames.getPrecacheName(cacheName),
|
|
235
262
|
plugins: [
|
|
@@ -240,6 +267,7 @@ class PrecacheController {
|
|
|
240
267
|
],
|
|
241
268
|
fallbackToNetwork
|
|
242
269
|
});
|
|
270
|
+
this._concurrentPrecaching = concurrentPrecaching;
|
|
243
271
|
this.install = this.install.bind(this);
|
|
244
272
|
this.activate = this.activate.bind(this);
|
|
245
273
|
}
|
|
@@ -302,7 +330,14 @@ class PrecacheController {
|
|
|
302
330
|
return waitUntil(event, async ()=>{
|
|
303
331
|
const installReportPlugin = new PrecacheInstallReportPlugin();
|
|
304
332
|
this.strategy.plugins.push(installReportPlugin);
|
|
305
|
-
|
|
333
|
+
let concurrents = this._concurrentPrecaching;
|
|
334
|
+
if (concurrents === undefined) {
|
|
335
|
+
if (!("__WB_CONCURRENT_PRECACHING" in globalThis)) {
|
|
336
|
+
self.__WB_CONCURRENT_PRECACHING = 1;
|
|
337
|
+
}
|
|
338
|
+
concurrents = self.__WB_CONCURRENT_PRECACHING;
|
|
339
|
+
}
|
|
340
|
+
await parallel(concurrents, Array.from(this._urlsToCacheKeys.entries()), async ([url, cacheKey])=>{
|
|
306
341
|
const integrity = this._cacheKeysToIntegrities.get(cacheKey);
|
|
307
342
|
const cacheMode = this._urlsToCacheModes.get(url);
|
|
308
343
|
const request = new Request(url, {
|
|
@@ -317,7 +352,7 @@ class PrecacheController {
|
|
|
317
352
|
request,
|
|
318
353
|
event
|
|
319
354
|
}));
|
|
320
|
-
}
|
|
355
|
+
});
|
|
321
356
|
const { updatedURLs, notUpdatedURLs } = installReportPlugin;
|
|
322
357
|
if (process.env.NODE_ENV !== "production") {
|
|
323
358
|
printInstallDetails(updatedURLs, notUpdatedURLs);
|
|
@@ -333,18 +368,18 @@ class PrecacheController {
|
|
|
333
368
|
const cache = await self.caches.open(this.strategy.cacheName);
|
|
334
369
|
const currentlyCachedRequests = await cache.keys();
|
|
335
370
|
const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());
|
|
336
|
-
const
|
|
371
|
+
const deletedCacheRequests = [];
|
|
337
372
|
for (const request of currentlyCachedRequests){
|
|
338
373
|
if (!expectedCacheKeys.has(request.url)) {
|
|
339
374
|
await cache.delete(request);
|
|
340
|
-
|
|
375
|
+
deletedCacheRequests.push(request.url);
|
|
341
376
|
}
|
|
342
377
|
}
|
|
343
378
|
if (process.env.NODE_ENV !== "production") {
|
|
344
|
-
printCleanupDetails(
|
|
379
|
+
printCleanupDetails(deletedCacheRequests);
|
|
345
380
|
}
|
|
346
381
|
return {
|
|
347
|
-
|
|
382
|
+
deletedCacheRequests
|
|
348
383
|
};
|
|
349
384
|
});
|
|
350
385
|
}
|
|
@@ -491,11 +526,11 @@ function addPlugins(plugins) {
|
|
|
491
526
|
precacheController.strategy.plugins.push(...plugins);
|
|
492
527
|
}
|
|
493
528
|
|
|
494
|
-
|
|
529
|
+
const addRoute = (options)=>{
|
|
495
530
|
const precacheController = getOrCreatePrecacheController();
|
|
496
531
|
const precacheRoute = new PrecacheRoute(precacheController, options);
|
|
497
532
|
registerRoute(precacheRoute);
|
|
498
|
-
}
|
|
533
|
+
};
|
|
499
534
|
|
|
500
535
|
const SUBSTRING_TO_FIND = "-precache-";
|
|
501
536
|
const deleteOutdatedCaches = async (currentPrecacheName, substringToFind = SUBSTRING_TO_FIND)=>{
|
|
@@ -507,18 +542,18 @@ const deleteOutdatedCaches = async (currentPrecacheName, substringToFind = SUBST
|
|
|
507
542
|
return cacheNamesToDelete;
|
|
508
543
|
};
|
|
509
544
|
|
|
510
|
-
|
|
545
|
+
const cleanupOutdatedCaches = ()=>{
|
|
511
546
|
self.addEventListener("activate", (event)=>{
|
|
512
547
|
const cacheName = privateCacheNames.getPrecacheName();
|
|
513
548
|
event.waitUntil(deleteOutdatedCaches(cacheName).then((cachesDeleted)=>{
|
|
514
549
|
if (process.env.NODE_ENV !== "production") {
|
|
515
550
|
if (cachesDeleted.length > 0) {
|
|
516
|
-
logger.log("The following out-of-date precaches were cleaned up
|
|
551
|
+
logger.log("The following out-of-date precaches were cleaned up automatically:", cachesDeleted);
|
|
517
552
|
}
|
|
518
553
|
}
|
|
519
554
|
}));
|
|
520
555
|
});
|
|
521
|
-
}
|
|
556
|
+
};
|
|
522
557
|
|
|
523
558
|
function createHandlerBoundToURL(url) {
|
|
524
559
|
const precacheController = getOrCreatePrecacheController();
|
|
@@ -535,14 +570,14 @@ function matchPrecache(request) {
|
|
|
535
570
|
return precacheController.matchPrecache(request);
|
|
536
571
|
}
|
|
537
572
|
|
|
538
|
-
|
|
573
|
+
const precache = (entries)=>{
|
|
539
574
|
const precacheController = getOrCreatePrecacheController();
|
|
540
575
|
precacheController.precache(entries);
|
|
541
|
-
}
|
|
576
|
+
};
|
|
542
577
|
|
|
543
|
-
|
|
578
|
+
const precacheAndRoute = (entries, options)=>{
|
|
544
579
|
precache(entries);
|
|
545
580
|
addRoute(options);
|
|
546
|
-
}
|
|
581
|
+
};
|
|
547
582
|
|
|
548
583
|
export { PrecacheController, PrecacheFallbackPlugin, PrecacheRoute, PrecacheStrategy, addPlugins, addRoute, cleanupOutdatedCaches, createHandlerBoundToURL, getCacheKeyForURL, matchPrecache, precache, precacheAndRoute };
|
package/dist/precache.d.ts
CHANGED
|
@@ -15,6 +15,5 @@ import type { PrecacheEntry } from "./_types.js";
|
|
|
15
15
|
*
|
|
16
16
|
* @param entries Array of entries to precache.
|
|
17
17
|
*/
|
|
18
|
-
declare
|
|
19
|
-
export { precache };
|
|
18
|
+
export declare const precache: (entries: (PrecacheEntry | string)[]) => void;
|
|
20
19
|
//# sourceMappingURL=precache.d.ts.map
|
package/dist/precache.d.ts.map
CHANGED
|
@@ -1 +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,
|
|
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,eAAO,MAAM,QAAQ,YAAa,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,KAAG,IAG9D,CAAC"}
|
|
@@ -10,6 +10,5 @@ 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
|
|
14
|
-
export { precacheAndRoute };
|
|
13
|
+
export declare const precacheAndRoute: (entries: (PrecacheEntry | string)[], options?: PrecacheRouteOptions) => void;
|
|
15
14
|
//# sourceMappingURL=precacheAndRoute.d.ts.map
|
|
@@ -1 +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,
|
|
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,eAAO,MAAM,gBAAgB,YAAa,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,YAAY,oBAAoB,KAAG,IAGtG,CAAC"}
|
|
@@ -14,6 +14,5 @@
|
|
|
14
14
|
* @returns A list of all the cache names that were deleted.
|
|
15
15
|
* @private
|
|
16
16
|
*/
|
|
17
|
-
declare const deleteOutdatedCaches: (currentPrecacheName: string, substringToFind?: string) => Promise<string[]>;
|
|
18
|
-
export { deleteOutdatedCaches };
|
|
17
|
+
export declare const deleteOutdatedCaches: (currentPrecacheName: string, substringToFind?: string) => Promise<string[]>;
|
|
19
18
|
//# sourceMappingURL=deleteOutdatedCaches.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deleteOutdatedCaches.d.ts","sourceRoot":"","sources":["../../src/utils/deleteOutdatedCaches.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;GAeG;AACH,
|
|
1
|
+
{"version":3,"file":"deleteOutdatedCaches.d.ts","sourceRoot":"","sources":["../../src/utils/deleteOutdatedCaches.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,wBAA+B,MAAM,oBAAmB,MAAM,KAAuB,QAAQ,MAAM,EAAE,CAUrI,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serwist/precaching",
|
|
3
|
-
"version": "9.0.0-preview.
|
|
3
|
+
"version": "9.0.0-preview.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "This module efficiently precaches assets.",
|
|
6
6
|
"files": [
|
|
@@ -28,14 +28,15 @@
|
|
|
28
28
|
"./package.json": "./package.json"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@serwist/core": "9.0.0-preview.
|
|
32
|
-
"@serwist/routing": "9.0.0-preview.
|
|
33
|
-
"@serwist/strategies": "9.0.0-preview.
|
|
31
|
+
"@serwist/core": "9.0.0-preview.7",
|
|
32
|
+
"@serwist/routing": "9.0.0-preview.7",
|
|
33
|
+
"@serwist/strategies": "9.0.0-preview.7"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"rollup": "4.9.6",
|
|
37
37
|
"typescript": "5.4.0-dev.20240206",
|
|
38
|
-
"@serwist/constants": "9.0.0-preview.
|
|
38
|
+
"@serwist/constants": "9.0.0-preview.7",
|
|
39
|
+
"@serwist/utils": "9.0.0-preview.7"
|
|
39
40
|
},
|
|
40
41
|
"peerDependencies": {
|
|
41
42
|
"typescript": ">=5.0.0"
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type { RouteHandlerCallback, SerwistPlugin } from "@serwist/core";
|
|
10
10
|
import { assert, SerwistError, logger, privateCacheNames, waitUntil } from "@serwist/core/internal";
|
|
11
11
|
import type { Strategy } from "@serwist/strategies";
|
|
12
|
+
import { parallel } from "@serwist/utils";
|
|
12
13
|
|
|
13
14
|
import { PrecacheStrategy } from "./PrecacheStrategy.js";
|
|
14
15
|
import type { CleanupResult, InstallResult, PrecacheEntry } from "./_types.js";
|
|
@@ -19,7 +20,7 @@ import { printCleanupDetails } from "./utils/printCleanupDetails.js";
|
|
|
19
20
|
import { printInstallDetails } from "./utils/printInstallDetails.js";
|
|
20
21
|
|
|
21
22
|
// Give TypeScript the correct global.
|
|
22
|
-
declare
|
|
23
|
+
declare const self: ServiceWorkerGlobalScope;
|
|
23
24
|
|
|
24
25
|
interface PrecacheControllerOptions {
|
|
25
26
|
/**
|
|
@@ -36,13 +37,21 @@ interface PrecacheControllerOptions {
|
|
|
36
37
|
* a precache miss.
|
|
37
38
|
*/
|
|
38
39
|
fallbackToNetwork?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* A number of how many precache requests should be made concurrently.
|
|
42
|
+
* By default, this value is set to 1, but this can be overriden by
|
|
43
|
+
* setting this option or `self.__WB_CONCURRENT_PRECACHING`. The former takes
|
|
44
|
+
* precedence over the latter.
|
|
45
|
+
*/
|
|
46
|
+
concurrentPrecaching?: number;
|
|
39
47
|
}
|
|
40
48
|
|
|
41
49
|
/**
|
|
42
50
|
* Performs efficient precaching of assets.
|
|
43
51
|
*/
|
|
44
|
-
class PrecacheController {
|
|
52
|
+
export class PrecacheController {
|
|
45
53
|
private _installAndActiveListenersAdded?: boolean;
|
|
54
|
+
private _concurrentPrecaching: number | undefined;
|
|
46
55
|
private readonly _strategy: Strategy;
|
|
47
56
|
private readonly _urlsToCacheKeys: Map<string, string> = new Map();
|
|
48
57
|
private readonly _urlsToCacheModes: Map<string, "reload" | "default" | "no-store" | "no-cache" | "force-cache" | "only-if-cached"> = new Map();
|
|
@@ -53,12 +62,13 @@ class PrecacheController {
|
|
|
53
62
|
*
|
|
54
63
|
* @param options
|
|
55
64
|
*/
|
|
56
|
-
constructor({ cacheName, plugins = [], fallbackToNetwork = true }: PrecacheControllerOptions = {}) {
|
|
65
|
+
constructor({ cacheName, plugins = [], fallbackToNetwork = true, concurrentPrecaching }: PrecacheControllerOptions = {}) {
|
|
57
66
|
this._strategy = new PrecacheStrategy({
|
|
58
67
|
cacheName: privateCacheNames.getPrecacheName(cacheName),
|
|
59
68
|
plugins: [...plugins, new PrecacheCacheKeyPlugin({ precacheController: this })],
|
|
60
69
|
fallbackToNetwork,
|
|
61
70
|
});
|
|
71
|
+
this._concurrentPrecaching = concurrentPrecaching;
|
|
62
72
|
|
|
63
73
|
// Bind the install and activate methods to the instance.
|
|
64
74
|
this.install = this.install.bind(this);
|
|
@@ -165,15 +175,20 @@ class PrecacheController {
|
|
|
165
175
|
* @returns
|
|
166
176
|
*/
|
|
167
177
|
install(event: ExtendableEvent): Promise<InstallResult> {
|
|
168
|
-
|
|
169
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
170
|
-
return waitUntil(event, async () => {
|
|
178
|
+
return waitUntil<InstallResult>(event, async () => {
|
|
171
179
|
const installReportPlugin = new PrecacheInstallReportPlugin();
|
|
172
180
|
this.strategy.plugins.push(installReportPlugin);
|
|
173
181
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
182
|
+
let concurrents = this._concurrentPrecaching;
|
|
183
|
+
|
|
184
|
+
if (concurrents === undefined) {
|
|
185
|
+
if (!("__WB_CONCURRENT_PRECACHING" in globalThis)) {
|
|
186
|
+
self.__WB_CONCURRENT_PRECACHING = 1;
|
|
187
|
+
}
|
|
188
|
+
concurrents = self.__WB_CONCURRENT_PRECACHING;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
await parallel(concurrents, Array.from(this._urlsToCacheKeys.entries()), async ([url, cacheKey]) => {
|
|
177
192
|
const integrity = this._cacheKeysToIntegrities.get(cacheKey);
|
|
178
193
|
const cacheMode = this._urlsToCacheModes.get(url);
|
|
179
194
|
|
|
@@ -190,7 +205,7 @@ class PrecacheController {
|
|
|
190
205
|
event,
|
|
191
206
|
}),
|
|
192
207
|
);
|
|
193
|
-
}
|
|
208
|
+
});
|
|
194
209
|
|
|
195
210
|
const { updatedURLs, notUpdatedURLs } = installReportPlugin;
|
|
196
211
|
|
|
@@ -213,26 +228,25 @@ class PrecacheController {
|
|
|
213
228
|
* @returns
|
|
214
229
|
*/
|
|
215
230
|
activate(event: ExtendableEvent): Promise<CleanupResult> {
|
|
216
|
-
|
|
217
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
218
|
-
return waitUntil(event, async () => {
|
|
231
|
+
return waitUntil<CleanupResult>(event, async () => {
|
|
219
232
|
const cache = await self.caches.open(this.strategy.cacheName);
|
|
220
233
|
const currentlyCachedRequests = await cache.keys();
|
|
221
234
|
const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());
|
|
222
235
|
|
|
223
|
-
const
|
|
236
|
+
const deletedCacheRequests: string[] = [];
|
|
237
|
+
|
|
224
238
|
for (const request of currentlyCachedRequests) {
|
|
225
239
|
if (!expectedCacheKeys.has(request.url)) {
|
|
226
240
|
await cache.delete(request);
|
|
227
|
-
|
|
241
|
+
deletedCacheRequests.push(request.url);
|
|
228
242
|
}
|
|
229
243
|
}
|
|
230
244
|
|
|
231
245
|
if (process.env.NODE_ENV !== "production") {
|
|
232
|
-
printCleanupDetails(
|
|
246
|
+
printCleanupDetails(deletedCacheRequests);
|
|
233
247
|
}
|
|
234
248
|
|
|
235
|
-
return {
|
|
249
|
+
return { deletedCacheRequests };
|
|
236
250
|
});
|
|
237
251
|
}
|
|
238
252
|
|
|
@@ -327,5 +341,3 @@ class PrecacheController {
|
|
|
327
341
|
};
|
|
328
342
|
}
|
|
329
343
|
}
|
|
330
|
-
|
|
331
|
-
export { PrecacheController };
|
package/src/addRoute.ts
CHANGED
|
@@ -23,11 +23,9 @@ import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheContro
|
|
|
23
23
|
*
|
|
24
24
|
* @param options See the `@serwist/precaching.PrecacheRoute` options.
|
|
25
25
|
*/
|
|
26
|
-
|
|
26
|
+
export const addRoute = (options?: PrecacheRouteOptions): void => {
|
|
27
27
|
const precacheController = getOrCreatePrecacheController();
|
|
28
28
|
|
|
29
29
|
const precacheRoute = new PrecacheRoute(precacheController, options);
|
|
30
30
|
registerRoute(precacheRoute);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export { addRoute };
|
|
31
|
+
};
|
|
@@ -10,25 +10,24 @@ import { logger, privateCacheNames } from "@serwist/core/internal";
|
|
|
10
10
|
|
|
11
11
|
import { deleteOutdatedCaches } from "./utils/deleteOutdatedCaches.js";
|
|
12
12
|
|
|
13
|
+
declare const self: ServiceWorkerGlobalScope;
|
|
14
|
+
|
|
13
15
|
/**
|
|
14
16
|
* Adds an `activate` event listener which will clean up incompatible
|
|
15
17
|
* precaches that were created by older versions of Serwist.
|
|
16
18
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
self.addEventListener("activate", ((event: ExtendableEvent) => {
|
|
19
|
+
export const cleanupOutdatedCaches = (): void => {
|
|
20
|
+
self.addEventListener("activate", (event: ExtendableEvent) => {
|
|
20
21
|
const cacheName = privateCacheNames.getPrecacheName();
|
|
21
22
|
|
|
22
23
|
event.waitUntil(
|
|
23
24
|
deleteOutdatedCaches(cacheName).then((cachesDeleted) => {
|
|
24
25
|
if (process.env.NODE_ENV !== "production") {
|
|
25
26
|
if (cachesDeleted.length > 0) {
|
|
26
|
-
logger.log("The following out-of-date precaches were cleaned up
|
|
27
|
+
logger.log("The following out-of-date precaches were cleaned up automatically:", cachesDeleted);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
}),
|
|
30
31
|
);
|
|
31
|
-
})
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export { cleanupOutdatedCaches };
|
|
32
|
+
});
|
|
33
|
+
};
|
package/src/precache.ts
CHANGED
|
@@ -25,9 +25,7 @@ import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheContro
|
|
|
25
25
|
*
|
|
26
26
|
* @param entries Array of entries to precache.
|
|
27
27
|
*/
|
|
28
|
-
|
|
28
|
+
export const precache = (entries: (PrecacheEntry | string)[]): void => {
|
|
29
29
|
const precacheController = getOrCreatePrecacheController();
|
|
30
30
|
precacheController.precache(entries);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export { precache };
|
|
31
|
+
};
|
package/src/precacheAndRoute.ts
CHANGED
|
@@ -21,9 +21,7 @@ import { precache } from "./precache.js";
|
|
|
21
21
|
* @param entries Array of entries to precache.
|
|
22
22
|
* @param options See the `@serwist/precaching.PrecacheRoute` options.
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
export const precacheAndRoute = (entries: (PrecacheEntry | string)[], options?: PrecacheRouteOptions): void => {
|
|
25
25
|
precache(entries);
|
|
26
26
|
addRoute(options);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export { precacheAndRoute };
|
|
27
|
+
};
|
|
@@ -27,7 +27,7 @@ const SUBSTRING_TO_FIND = "-precache-";
|
|
|
27
27
|
* @returns A list of all the cache names that were deleted.
|
|
28
28
|
* @private
|
|
29
29
|
*/
|
|
30
|
-
const deleteOutdatedCaches = async (currentPrecacheName: string, substringToFind: string = SUBSTRING_TO_FIND): Promise<string[]> => {
|
|
30
|
+
export const deleteOutdatedCaches = async (currentPrecacheName: string, substringToFind: string = SUBSTRING_TO_FIND): Promise<string[]> => {
|
|
31
31
|
const cacheNames = await self.caches.keys();
|
|
32
32
|
|
|
33
33
|
const cacheNamesToDelete = cacheNames.filter((cacheName) => {
|
|
@@ -38,5 +38,3 @@ const deleteOutdatedCaches = async (currentPrecacheName: string, substringToFind
|
|
|
38
38
|
|
|
39
39
|
return cacheNamesToDelete;
|
|
40
40
|
};
|
|
41
|
-
|
|
42
|
-
export { deleteOutdatedCaches };
|