@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.
@@ -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 { PrecacheController };
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;AAGpD,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;CAC7B;AAED;;GAEG;AACH,cAAM,kBAAkB;IACtB,OAAO,CAAC,+BAA+B,CAAC,CAAU;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,GAAE,yBAA8B;IAYjG;;;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;IAsCvD;;;;;;;;;OASG;IACH,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC;IAwBxD;;;;;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;AAED,OAAO,EAAE,kBAAkB,EAAE,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"}
@@ -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 function addRoute(options?: PrecacheRouteOptions): void;
15
- export { addRoute };
14
+ export declare const addRoute: (options?: PrecacheRouteOptions) => void;
16
15
  //# sourceMappingURL=addRoute.d.ts.map
@@ -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,iBAAS,QAAQ,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAKtD;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
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 function cleanupOutdatedCaches(): void;
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":"AAYA;;;GAGG;AACH,iBAAS,qBAAqB,IAAI,IAAI,CAerC;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAC"}
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
- for (const [url, cacheKey] of this._urlsToCacheKeys){
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 deletedURLs = [];
371
+ const deletedCacheRequests = [];
337
372
  for (const request of currentlyCachedRequests){
338
373
  if (!expectedCacheKeys.has(request.url)) {
339
374
  await cache.delete(request);
340
- deletedURLs.push(request.url);
375
+ deletedCacheRequests.push(request.url);
341
376
  }
342
377
  }
343
378
  if (process.env.NODE_ENV !== "production") {
344
- printCleanupDetails(deletedURLs);
379
+ printCleanupDetails(deletedCacheRequests);
345
380
  }
346
381
  return {
347
- deletedURLs
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
- function addRoute(options) {
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
- function cleanupOutdatedCaches() {
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 " + "automatically:", cachesDeleted);
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
- function precache(entries) {
573
+ const precache = (entries)=>{
539
574
  const precacheController = getOrCreatePrecacheController();
540
575
  precacheController.precache(entries);
541
- }
576
+ };
542
577
 
543
- function precacheAndRoute(entries, options) {
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 };
@@ -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 function precache(entries: (PrecacheEntry | string)[]): void;
19
- export { precache };
18
+ export declare const precache: (entries: (PrecacheEntry | string)[]) => void;
20
19
  //# sourceMappingURL=precache.d.ts.map
@@ -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,iBAAS,QAAQ,CAAC,OAAO,EAAE,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI,CAG3D;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
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 function precacheAndRoute(entries: (PrecacheEntry | string)[], options?: PrecacheRouteOptions): void;
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,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"}
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,QAAA,MAAM,oBAAoB,wBAA+B,MAAM,oBAAmB,MAAM,KAAuB,QAAQ,MAAM,EAAE,CAU9H,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
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.5",
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.5",
32
- "@serwist/routing": "9.0.0-preview.5",
33
- "@serwist/strategies": "9.0.0-preview.5"
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.5"
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 let self: ServiceWorkerGlobalScope;
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
- // waitUntil returns Promise<any>
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
- // Cache entries one at a time.
175
- // See https://github.com/GoogleChrome/workbox/issues/2528
176
- for (const [url, cacheKey] of this._urlsToCacheKeys) {
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
- // waitUntil returns Promise<any>
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 deletedURLs = [];
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
- deletedURLs.push(request.url);
241
+ deletedCacheRequests.push(request.url);
228
242
  }
229
243
  }
230
244
 
231
245
  if (process.env.NODE_ENV !== "production") {
232
- printCleanupDetails(deletedURLs);
246
+ printCleanupDetails(deletedCacheRequests);
233
247
  }
234
248
 
235
- return { deletedURLs };
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
- function addRoute(options?: PrecacheRouteOptions): void {
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
- function cleanupOutdatedCaches(): void {
18
- // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705
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 " + "automatically:", cachesDeleted);
27
+ logger.log("The following out-of-date precaches were cleaned up automatically:", cachesDeleted);
27
28
  }
28
29
  }
29
30
  }),
30
31
  );
31
- }) as EventListener);
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
- function precache(entries: (PrecacheEntry | string)[]): void {
28
+ export const precache = (entries: (PrecacheEntry | string)[]): void => {
29
29
  const precacheController = getOrCreatePrecacheController();
30
30
  precacheController.precache(entries);
31
- }
32
-
33
- export { precache };
31
+ };
@@ -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
- function precacheAndRoute(entries: (PrecacheEntry | string)[], options?: PrecacheRouteOptions): void {
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 };