@serwist/core 8.0.0

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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/_private/Deferred.d.ts +19 -0
  4. package/dist/_private/Deferred.d.ts.map +1 -0
  5. package/dist/_private/SerwistError.d.ts +24 -0
  6. package/dist/_private/SerwistError.d.ts.map +1 -0
  7. package/dist/_private/assert.d.ts +11 -0
  8. package/dist/_private/assert.d.ts.map +1 -0
  9. package/dist/_private/cacheMatchIgnoreParams.d.ts +15 -0
  10. package/dist/_private/cacheMatchIgnoreParams.d.ts.map +1 -0
  11. package/dist/_private/cacheNames.d.ts +40 -0
  12. package/dist/_private/cacheNames.d.ts.map +1 -0
  13. package/dist/_private/canConstructReadableStream.d.ts +12 -0
  14. package/dist/_private/canConstructReadableStream.d.ts.map +1 -0
  15. package/dist/_private/canConstructResponseFromBodyStream.d.ts +11 -0
  16. package/dist/_private/canConstructResponseFromBodyStream.d.ts.map +1 -0
  17. package/dist/_private/dontWaitFor.d.ts +7 -0
  18. package/dist/_private/dontWaitFor.d.ts.map +1 -0
  19. package/dist/_private/executeQuotaErrorCallbacks.d.ts +9 -0
  20. package/dist/_private/executeQuotaErrorCallbacks.d.ts.map +1 -0
  21. package/dist/_private/getFriendlyURL.d.ts +3 -0
  22. package/dist/_private/getFriendlyURL.d.ts.map +1 -0
  23. package/dist/_private/logger.d.ts +11 -0
  24. package/dist/_private/logger.d.ts.map +1 -0
  25. package/dist/_private/resultingClientExists.d.ts +12 -0
  26. package/dist/_private/resultingClientExists.d.ts.map +1 -0
  27. package/dist/_private/timeout.d.ts +10 -0
  28. package/dist/_private/timeout.d.ts.map +1 -0
  29. package/dist/_private/waitUntil.d.ts +12 -0
  30. package/dist/_private/waitUntil.d.ts.map +1 -0
  31. package/dist/cacheNames.d.ts +21 -0
  32. package/dist/cacheNames.d.ts.map +1 -0
  33. package/dist/clientsClaim.d.ts +7 -0
  34. package/dist/clientsClaim.d.ts.map +1 -0
  35. package/dist/copyResponse.d.ts +21 -0
  36. package/dist/copyResponse.d.ts.map +1 -0
  37. package/dist/index.d.ts +12 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.internal.d.ts +16 -0
  40. package/dist/index.internal.d.ts.map +1 -0
  41. package/dist/index.internal.js +652 -0
  42. package/dist/index.internal.old.cjs +667 -0
  43. package/dist/index.js +571 -0
  44. package/dist/index.old.cjs +577 -0
  45. package/dist/models/messages/messageGenerator.d.ts +2 -0
  46. package/dist/models/messages/messageGenerator.d.ts.map +1 -0
  47. package/dist/models/messages/messages.d.ts +9 -0
  48. package/dist/models/messages/messages.d.ts.map +1 -0
  49. package/dist/models/pluginEvents.d.ts +10 -0
  50. package/dist/models/pluginEvents.d.ts.map +1 -0
  51. package/dist/models/quotaErrorCallbacks.d.ts +3 -0
  52. package/dist/models/quotaErrorCallbacks.d.ts.map +1 -0
  53. package/dist/registerQuotaErrorCallback.d.ts +9 -0
  54. package/dist/registerQuotaErrorCallback.d.ts.map +1 -0
  55. package/dist/setCacheNameDetails.d.ts +10 -0
  56. package/dist/setCacheNameDetails.d.ts.map +1 -0
  57. package/dist/types.d.ts +273 -0
  58. package/dist/types.d.ts.map +1 -0
  59. package/dist/utils/pluginUtils.d.ts +5 -0
  60. package/dist/utils/pluginUtils.d.ts.map +1 -0
  61. package/dist/utils/welcome.d.ts +2 -0
  62. package/dist/utils/welcome.d.ts.map +1 -0
  63. package/package.json +59 -0
@@ -0,0 +1,667 @@
1
+ 'use strict';
2
+
3
+ /*
4
+ Copyright 2018 Google LLC
5
+
6
+ Use of this source code is governed by an MIT-style
7
+ license that can be found in the LICENSE file or at
8
+ https://opensource.org/licenses/MIT.
9
+ */ const messages = {
10
+ "invalid-value": ({ paramName, validValueDescription, value })=>{
11
+ if (!paramName || !validValueDescription) {
12
+ throw new Error(`Unexpected input to 'invalid-value' error.`);
13
+ }
14
+ return `The '${paramName}' parameter was given a value with an ` + `unexpected value. ${validValueDescription} Received a value of ` + `${JSON.stringify(value)}.`;
15
+ },
16
+ "not-an-array": ({ moduleName, className, funcName, paramName })=>{
17
+ if (!moduleName || !className || !funcName || !paramName) {
18
+ throw new Error(`Unexpected input to 'not-an-array' error.`);
19
+ }
20
+ return `The parameter '${paramName}' passed into ` + `'${moduleName}.${className}.${funcName}()' must be an array.`;
21
+ },
22
+ "incorrect-type": ({ expectedType, paramName, moduleName, className, funcName })=>{
23
+ if (!expectedType || !paramName || !moduleName || !funcName) {
24
+ throw new Error(`Unexpected input to 'incorrect-type' error.`);
25
+ }
26
+ const classNameStr = className ? `${className}.` : "";
27
+ return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}` + `${funcName}()' must be of type ${expectedType}.`;
28
+ },
29
+ "incorrect-class": ({ expectedClassName, paramName, moduleName, className, funcName, isReturnValueProblem })=>{
30
+ if (!expectedClassName || !moduleName || !funcName) {
31
+ throw new Error(`Unexpected input to 'incorrect-class' error.`);
32
+ }
33
+ const classNameStr = className ? `${className}.` : "";
34
+ if (isReturnValueProblem) {
35
+ return `The return value from ` + `'${moduleName}.${classNameStr}${funcName}()' ` + `must be an instance of class ${expectedClassName}.`;
36
+ }
37
+ return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}${funcName}()' ` + `must be an instance of class ${expectedClassName}.`;
38
+ },
39
+ "missing-a-method": ({ expectedMethod, paramName, moduleName, className, funcName })=>{
40
+ if (!expectedMethod || !paramName || !moduleName || !className || !funcName) {
41
+ throw new Error(`Unexpected input to 'missing-a-method' error.`);
42
+ }
43
+ return `${moduleName}.${className}.${funcName}() expected the ` + `'${paramName}' parameter to expose a '${expectedMethod}' method.`;
44
+ },
45
+ "add-to-cache-list-unexpected-type": ({ entry })=>{
46
+ return `An unexpected entry was passed to ` + `'@serwist/precaching.PrecacheController.addToCacheList()' The entry ` + `'${JSON.stringify(entry)}' isn't supported. You must supply an array of ` + `strings with one or more characters, objects with a url property or ` + `Request objects.`;
47
+ },
48
+ "add-to-cache-list-conflicting-entries": ({ firstEntry, secondEntry })=>{
49
+ if (!firstEntry || !secondEntry) {
50
+ throw new Error(`Unexpected input to ` + `'add-to-cache-list-duplicate-entries' error.`);
51
+ }
52
+ return `Two of the entries passed to ` + `'@serwist/precaching.PrecacheController.addToCacheList()' had the URL ` + `${firstEntry} but different revision details. Serwist is ` + `unable to cache and version the asset correctly. Please remove one ` + `of the entries.`;
53
+ },
54
+ "plugin-error-request-will-fetch": ({ thrownErrorMessage })=>{
55
+ if (!thrownErrorMessage) {
56
+ throw new Error(`Unexpected input to ` + `'plugin-error-request-will-fetch', error.`);
57
+ }
58
+ return `An error was thrown by a plugins 'requestWillFetch()' method. ` + `The thrown error message was: '${thrownErrorMessage}'.`;
59
+ },
60
+ "invalid-cache-name": ({ cacheNameId, value })=>{
61
+ if (!cacheNameId) {
62
+ throw new Error(`Expected a 'cacheNameId' for error 'invalid-cache-name'`);
63
+ }
64
+ return `You must provide a name containing at least one character for ` + `setCacheDetails({${cacheNameId}: '...'}). Received a value of ` + `'${JSON.stringify(value)}'`;
65
+ },
66
+ "unregister-route-but-not-found-with-method": ({ method })=>{
67
+ if (!method) {
68
+ throw new Error(`Unexpected input to ` + `'unregister-route-but-not-found-with-method' error.`);
69
+ }
70
+ return `The route you're trying to unregister was not previously ` + `registered for the method type '${method}'.`;
71
+ },
72
+ "unregister-route-route-not-registered": ()=>{
73
+ return `The route you're trying to unregister was not previously ` + `registered.`;
74
+ },
75
+ "queue-replay-failed": ({ name })=>{
76
+ return `Replaying the background sync queue '${name}' failed.`;
77
+ },
78
+ "duplicate-queue-name": ({ name })=>{
79
+ return `The Queue name '${name}' is already being used. ` + `All instances of backgroundSync.Queue must be given unique names.`;
80
+ },
81
+ "expired-test-without-max-age": ({ methodName, paramName })=>{
82
+ return `The '${methodName}()' method can only be used when the ` + `'${paramName}' is used in the constructor.`;
83
+ },
84
+ "unsupported-route-type": ({ moduleName, className, funcName, paramName })=>{
85
+ return `The supplied '${paramName}' parameter was an unsupported type. ` + `Please check the docs for ${moduleName}.${className}.${funcName} for ` + `valid input types.`;
86
+ },
87
+ "not-array-of-class": ({ value, expectedClass, moduleName, className, funcName, paramName })=>{
88
+ return `The supplied '${paramName}' parameter must be an array of ` + `'${expectedClass}' objects. Received '${JSON.stringify(value)},'. ` + `Please check the call to ${moduleName}.${className}.${funcName}() ` + `to fix the issue.`;
89
+ },
90
+ "max-entries-or-age-required": ({ moduleName, className, funcName })=>{
91
+ return `You must define either config.maxEntries or config.maxAgeSeconds` + `in ${moduleName}.${className}.${funcName}`;
92
+ },
93
+ "statuses-or-headers-required": ({ moduleName, className, funcName })=>{
94
+ return `You must define either config.statuses or config.headers` + `in ${moduleName}.${className}.${funcName}`;
95
+ },
96
+ "invalid-string": ({ moduleName, funcName, paramName })=>{
97
+ if (!paramName || !moduleName || !funcName) {
98
+ throw new Error(`Unexpected input to 'invalid-string' error.`);
99
+ }
100
+ return `When using strings, the '${paramName}' parameter must start with ` + `'http' (for cross-origin matches) or '/' (for same-origin matches). ` + `Please see the docs for ${moduleName}.${funcName}() for ` + `more info.`;
101
+ },
102
+ "channel-name-required": ()=>{
103
+ return `You must provide a channelName to construct a ` + `BroadcastCacheUpdate instance.`;
104
+ },
105
+ "invalid-responses-are-same-args": ()=>{
106
+ return `The arguments passed into responsesAreSame() appear to be ` + `invalid. Please ensure valid Responses are used.`;
107
+ },
108
+ "expire-custom-caches-only": ()=>{
109
+ return `You must provide a 'cacheName' property when using the ` + `expiration plugin with a runtime caching strategy.`;
110
+ },
111
+ "unit-must-be-bytes": ({ normalizedRangeHeader })=>{
112
+ if (!normalizedRangeHeader) {
113
+ throw new Error(`Unexpected input to 'unit-must-be-bytes' error.`);
114
+ }
115
+ return `The 'unit' portion of the Range header must be set to 'bytes'. ` + `The Range header provided was "${normalizedRangeHeader}"`;
116
+ },
117
+ "single-range-only": ({ normalizedRangeHeader })=>{
118
+ if (!normalizedRangeHeader) {
119
+ throw new Error(`Unexpected input to 'single-range-only' error.`);
120
+ }
121
+ return `Multiple ranges are not supported. Please use a single start ` + `value, and optional end value. The Range header provided was ` + `"${normalizedRangeHeader}"`;
122
+ },
123
+ "invalid-range-values": ({ normalizedRangeHeader })=>{
124
+ if (!normalizedRangeHeader) {
125
+ throw new Error(`Unexpected input to 'invalid-range-values' error.`);
126
+ }
127
+ return `The Range header is missing both start and end values. At least ` + `one of those values is needed. The Range header provided was ` + `"${normalizedRangeHeader}"`;
128
+ },
129
+ "no-range-header": ()=>{
130
+ return `No Range header was found in the Request provided.`;
131
+ },
132
+ "range-not-satisfiable": ({ size, start, end })=>{
133
+ return `The start (${start}) and end (${end}) values in the Range are ` + `not satisfiable by the cached response, which is ${size} bytes.`;
134
+ },
135
+ "attempt-to-cache-non-get-request": ({ url, method })=>{
136
+ return `Unable to cache '${url}' because it is a '${method}' request and ` + `only 'GET' requests can be cached.`;
137
+ },
138
+ "cache-put-with-no-response": ({ url })=>{
139
+ return `There was an attempt to cache '${url}' but the response was not ` + `defined.`;
140
+ },
141
+ "no-response": ({ url, error })=>{
142
+ let message = `The strategy could not generate a response for '${url}'.`;
143
+ if (error) {
144
+ message += ` The underlying error is ${error}.`;
145
+ }
146
+ return message;
147
+ },
148
+ "bad-precaching-response": ({ url, status })=>{
149
+ return `The precaching request for '${url}' failed` + (status ? ` with an HTTP status of ${status}.` : `.`);
150
+ },
151
+ "non-precached-url": ({ url })=>{
152
+ return `createHandlerBoundToURL('${url}') was called, but that URL is ` + `not precached. Please pass in a URL that is precached instead.`;
153
+ },
154
+ "add-to-cache-list-conflicting-integrities": ({ url })=>{
155
+ return `Two of the entries passed to ` + `'@serwist/precaching.PrecacheController.addToCacheList()' had the URL ` + `${url} with different integrity values. Please remove one of them.`;
156
+ },
157
+ "missing-precache-entry": ({ cacheName, url })=>{
158
+ return `Unable to find a precached response in ${cacheName} for ${url}.`;
159
+ },
160
+ "cross-origin-copy-response": ({ origin })=>{
161
+ return `@serwist/core.copyResponse() can only be used with same-origin ` + `responses. It was passed a response with origin ${origin}.`;
162
+ },
163
+ "opaque-streams-source": ({ type })=>{
164
+ const message = `One of the @serwist/streams sources resulted in an ` + `'${type}' response.`;
165
+ if (type === "opaqueredirect") {
166
+ return `${message} Please do not use a navigation request that results ` + `in a redirect as a source.`;
167
+ }
168
+ return `${message} Please ensure your sources are CORS-enabled.`;
169
+ }
170
+ };
171
+
172
+ const fallback = (code, ...args)=>{
173
+ let msg = code;
174
+ if (args.length > 0) {
175
+ msg += ` :: ${JSON.stringify(args)}`;
176
+ }
177
+ return msg;
178
+ };
179
+ const generatorFunction = (code, details = {})=>{
180
+ const message = messages[code];
181
+ if (!message) {
182
+ throw new Error(`Unable to find message for code '${code}'.`);
183
+ }
184
+ return message(details);
185
+ };
186
+ const messageGenerator = process.env.NODE_ENV === "production" ? fallback : generatorFunction;
187
+
188
+ /**
189
+ * Serwist errors should be thrown with this class.
190
+ * This allows use to ensure the type easily in tests,
191
+ * helps developers identify errors from Serwist
192
+ * easily and allows use to optimise error
193
+ * messages correctly.
194
+ *
195
+ * @private
196
+ */ class SerwistError extends Error {
197
+ details;
198
+ /**
199
+ *
200
+ * @param errorCode The error code that
201
+ * identifies this particular error.
202
+ * @param details Any relevant arguments
203
+ * that will help developers identify issues should
204
+ * be added as a key on the context object.
205
+ */ constructor(errorCode, details){
206
+ const message = messageGenerator(errorCode, details);
207
+ super(message);
208
+ this.name = errorCode;
209
+ this.details = details;
210
+ }
211
+ }
212
+
213
+ /*
214
+ * This method throws if the supplied value is not an array.
215
+ * The destructed values are required to produce a meaningful error for users.
216
+ * The destructed and restructured object is so it's clear what is
217
+ * needed.
218
+ */ const isArray = (value, details)=>{
219
+ if (!Array.isArray(value)) {
220
+ throw new SerwistError("not-an-array", details);
221
+ }
222
+ };
223
+ const hasMethod = (object, expectedMethod, details)=>{
224
+ const type = typeof object[expectedMethod];
225
+ if (type !== "function") {
226
+ details["expectedMethod"] = expectedMethod;
227
+ throw new SerwistError("missing-a-method", details);
228
+ }
229
+ };
230
+ const isType = (object, expectedType, details)=>{
231
+ if (typeof object !== expectedType) {
232
+ details["expectedType"] = expectedType;
233
+ throw new SerwistError("incorrect-type", details);
234
+ }
235
+ };
236
+ const isInstance = (object, // Need the general type to do the check later.
237
+ // eslint-disable-next-line @typescript-eslint/ban-types
238
+ expectedClass, details)=>{
239
+ if (!(object instanceof expectedClass)) {
240
+ details["expectedClassName"] = expectedClass.name;
241
+ throw new SerwistError("incorrect-class", details);
242
+ }
243
+ };
244
+ const isOneOf = (value, validValues, details)=>{
245
+ if (!validValues.includes(value)) {
246
+ details["validValueDescription"] = `Valid values are ${JSON.stringify(validValues)}.`;
247
+ throw new SerwistError("invalid-value", details);
248
+ }
249
+ };
250
+ const isArrayOfClass = (value, // Need general type to do check later.
251
+ expectedClass, details)=>{
252
+ const error = new SerwistError("not-array-of-class", details);
253
+ if (!Array.isArray(value)) {
254
+ throw error;
255
+ }
256
+ for (const item of value){
257
+ if (!(item instanceof expectedClass)) {
258
+ throw error;
259
+ }
260
+ }
261
+ };
262
+ const finalAssertExports = process.env.NODE_ENV === "production" ? null : {
263
+ hasMethod,
264
+ isArray,
265
+ isInstance,
266
+ isOneOf,
267
+ isType,
268
+ isArrayOfClass
269
+ };
270
+
271
+ /*
272
+ Copyright 2020 Google LLC
273
+ Use of this source code is governed by an MIT-style
274
+ license that can be found in the LICENSE file or at
275
+ https://opensource.org/licenses/MIT.
276
+ */ function stripParams(fullURL, ignoreParams) {
277
+ const strippedURL = new URL(fullURL);
278
+ for (const param of ignoreParams){
279
+ strippedURL.searchParams.delete(param);
280
+ }
281
+ return strippedURL.href;
282
+ }
283
+ /**
284
+ * Matches an item in the cache, ignoring specific URL params. This is similar
285
+ * to the `ignoreSearch` option, but it allows you to ignore just specific
286
+ * params (while continuing to match on the others).
287
+ *
288
+ * @private
289
+ * @param cache
290
+ * @param request
291
+ * @param matchOptions
292
+ * @param ignoreParams
293
+ * @returns
294
+ */ async function cacheMatchIgnoreParams(cache, request, ignoreParams, matchOptions) {
295
+ const strippedRequestURL = stripParams(request.url, ignoreParams);
296
+ // If the request doesn't include any ignored params, match as normal.
297
+ if (request.url === strippedRequestURL) {
298
+ return cache.match(request, matchOptions);
299
+ }
300
+ // Otherwise, match by comparing keys
301
+ const keysOptions = {
302
+ ...matchOptions,
303
+ ignoreSearch: true
304
+ };
305
+ const cacheKeys = await cache.keys(request, keysOptions);
306
+ for (const cacheKey of cacheKeys){
307
+ const strippedCacheKeyURL = stripParams(cacheKey.url, ignoreParams);
308
+ if (strippedRequestURL === strippedCacheKeyURL) {
309
+ return cache.match(cacheKey, matchOptions);
310
+ }
311
+ }
312
+ return;
313
+ }
314
+
315
+ /*
316
+ Copyright 2018 Google LLC
317
+
318
+ Use of this source code is governed by an MIT-style
319
+ license that can be found in the LICENSE file or at
320
+ https://opensource.org/licenses/MIT.
321
+ */ const _cacheNameDetails = {
322
+ googleAnalytics: "googleAnalytics",
323
+ precache: "precache-v2",
324
+ prefix: "serwist",
325
+ runtime: "runtime",
326
+ suffix: typeof registration !== "undefined" ? registration.scope : ""
327
+ };
328
+ const _createCacheName = (cacheName)=>{
329
+ return [
330
+ _cacheNameDetails.prefix,
331
+ cacheName,
332
+ _cacheNameDetails.suffix
333
+ ].filter((value)=>value && value.length > 0).join("-");
334
+ };
335
+ const eachCacheNameDetail = (fn)=>{
336
+ for (const key of Object.keys(_cacheNameDetails)){
337
+ fn(key);
338
+ }
339
+ };
340
+ const cacheNames = {
341
+ updateDetails: (details)=>{
342
+ eachCacheNameDetail((key)=>{
343
+ const detail = details[key];
344
+ if (typeof detail === "string") {
345
+ _cacheNameDetails[key] = detail;
346
+ }
347
+ });
348
+ },
349
+ getGoogleAnalyticsName: (userCacheName)=>{
350
+ return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics);
351
+ },
352
+ getPrecacheName: (userCacheName)=>{
353
+ return userCacheName || _createCacheName(_cacheNameDetails.precache);
354
+ },
355
+ getPrefix: ()=>{
356
+ return _cacheNameDetails.prefix;
357
+ },
358
+ getRuntimeName: (userCacheName)=>{
359
+ return userCacheName || _createCacheName(_cacheNameDetails.runtime);
360
+ },
361
+ getSuffix: ()=>{
362
+ return _cacheNameDetails.suffix;
363
+ }
364
+ };
365
+
366
+ /*
367
+ Copyright 2019 Google LLC
368
+
369
+ Use of this source code is governed by an MIT-style
370
+ license that can be found in the LICENSE file or at
371
+ https://opensource.org/licenses/MIT.
372
+ */ let supportStatus$1;
373
+ /**
374
+ * A utility function that determines whether the current browser supports
375
+ * constructing a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/ReadableStream)
376
+ * object.
377
+ *
378
+ * @returns `true`, if the current browser can successfully construct a `ReadableStream`, `false` otherwise.
379
+ *
380
+ * @private
381
+ */ function canConstructReadableStream() {
382
+ if (supportStatus$1 === undefined) {
383
+ // See https://github.com/GoogleChrome/workbox/issues/1473
384
+ try {
385
+ new ReadableStream({
386
+ start () {}
387
+ });
388
+ supportStatus$1 = true;
389
+ } catch (error) {
390
+ supportStatus$1 = false;
391
+ }
392
+ }
393
+ return supportStatus$1;
394
+ }
395
+
396
+ /*
397
+ Copyright 2019 Google LLC
398
+
399
+ Use of this source code is governed by an MIT-style
400
+ license that can be found in the LICENSE file or at
401
+ https://opensource.org/licenses/MIT.
402
+ */ let supportStatus;
403
+ /**
404
+ * A utility function that determines whether the current browser supports
405
+ * constructing a new `Response` from a `response.body` stream.
406
+ *
407
+ * @returns `true`, if the current browser can successfully construct
408
+ * a `Response` from a `response.body` stream, `false` otherwise.
409
+ * @private
410
+ */ function canConstructResponseFromBodyStream() {
411
+ if (supportStatus === undefined) {
412
+ const testResponse = new Response("");
413
+ if ("body" in testResponse) {
414
+ try {
415
+ new Response(testResponse.body);
416
+ supportStatus = true;
417
+ } catch (error) {
418
+ supportStatus = false;
419
+ }
420
+ }
421
+ supportStatus = false;
422
+ }
423
+ return supportStatus;
424
+ }
425
+
426
+ /*
427
+ Copyright 2018 Google LLC
428
+
429
+ Use of this source code is governed by an MIT-style
430
+ license that can be found in the LICENSE file or at
431
+ https://opensource.org/licenses/MIT.
432
+ */ /**
433
+ * The Deferred class composes Promises in a way that allows for them to be
434
+ * resolved or rejected from outside the constructor. In most cases promises
435
+ * should be used directly, but Deferreds can be necessary when the logic to
436
+ * resolve a promise must be separate.
437
+ *
438
+ * @private
439
+ */ class Deferred {
440
+ promise;
441
+ resolve;
442
+ reject;
443
+ /**
444
+ * Creates a promise and exposes its resolve and reject functions as methods.
445
+ */ constructor(){
446
+ this.promise = new Promise((resolve, reject)=>{
447
+ this.resolve = resolve;
448
+ this.reject = reject;
449
+ });
450
+ }
451
+ }
452
+
453
+ /*
454
+ Copyright 2019 Google LLC
455
+ Use of this source code is governed by an MIT-style
456
+ license that can be found in the LICENSE file or at
457
+ https://opensource.org/licenses/MIT.
458
+ */ /**
459
+ * A helper function that prevents a promise from being flagged as unused.
460
+ *
461
+ * @private
462
+ **/ function dontWaitFor(promise) {
463
+ // Effective no-op.
464
+ void promise.then(()=>{});
465
+ }
466
+
467
+ /*
468
+ Copyright 2019 Google LLC
469
+ Use of this source code is governed by an MIT-style
470
+ license that can be found in the LICENSE file or at
471
+ https://opensource.org/licenses/MIT.
472
+ */ // logger is used inside of both service workers and the window global scope.
473
+ const logger = process.env.NODE_ENV === "production" ? null : (()=>{
474
+ // Don't overwrite this value if it's already set.
475
+ // See https://github.com/GoogleChrome/workbox/pull/2284#issuecomment-560470923
476
+ if (!("__WB_DISABLE_DEV_LOGS" in globalThis)) {
477
+ self.__WB_DISABLE_DEV_LOGS = false;
478
+ }
479
+ let inGroup = false;
480
+ const methodToColorMap = {
481
+ debug: `#7f8c8d`,
482
+ log: `#2ecc71`,
483
+ warn: `#f39c12`,
484
+ error: `#c0392b`,
485
+ groupCollapsed: `#3498db`,
486
+ groupEnd: null
487
+ };
488
+ const print = function(method, args) {
489
+ if (self.__WB_DISABLE_DEV_LOGS) {
490
+ return;
491
+ }
492
+ if (method === "groupCollapsed") {
493
+ // Safari doesn't print all console.groupCollapsed() arguments:
494
+ // https://bugs.webkit.org/show_bug.cgi?id=182754
495
+ if (typeof navigator !== "undefined" && /^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
496
+ console[method](...args);
497
+ return;
498
+ }
499
+ }
500
+ const styles = [
501
+ `background: ${methodToColorMap[method]}`,
502
+ `border-radius: 0.5em`,
503
+ `color: white`,
504
+ `font-weight: bold`,
505
+ `padding: 2px 0.5em`
506
+ ];
507
+ // When in a group, the serwist prefix is not displayed.
508
+ const logPrefix = inGroup ? [] : [
509
+ "%cserwist",
510
+ styles.join(";")
511
+ ];
512
+ console[method](...logPrefix, ...args);
513
+ if (method === "groupCollapsed") {
514
+ inGroup = true;
515
+ }
516
+ if (method === "groupEnd") {
517
+ inGroup = false;
518
+ }
519
+ };
520
+ // eslint-disable-next-line @typescript-eslint/ban-types
521
+ const api = {};
522
+ const loggerMethods = Object.keys(methodToColorMap);
523
+ for (const key of loggerMethods){
524
+ const method = key;
525
+ api[method] = (...args)=>{
526
+ print(method, args);
527
+ };
528
+ }
529
+ return api;
530
+ })();
531
+
532
+ /*
533
+ Copyright 2018 Google LLC
534
+
535
+ Use of this source code is governed by an MIT-style
536
+ license that can be found in the LICENSE file or at
537
+ https://opensource.org/licenses/MIT.
538
+ */ // Callbacks to be executed whenever there's a quota error.
539
+ // Can't change Function type right now.
540
+ // eslint-disable-next-line @typescript-eslint/ban-types
541
+ const quotaErrorCallbacks = new Set();
542
+
543
+ /**
544
+ * Runs all of the callback functions, one at a time sequentially, in the order
545
+ * in which they were registered.
546
+ *
547
+ * @private
548
+ */ async function executeQuotaErrorCallbacks() {
549
+ if (process.env.NODE_ENV !== "production") {
550
+ logger.log(`About to run ${quotaErrorCallbacks.size} ` + `callbacks to clean up caches.`);
551
+ }
552
+ for (const callback of quotaErrorCallbacks){
553
+ await callback();
554
+ if (process.env.NODE_ENV !== "production") {
555
+ logger.log(callback, "is complete.");
556
+ }
557
+ }
558
+ if (process.env.NODE_ENV !== "production") {
559
+ logger.log("Finished running callbacks.");
560
+ }
561
+ }
562
+
563
+ /*
564
+ Copyright 2018 Google LLC
565
+
566
+ Use of this source code is governed by an MIT-style
567
+ license that can be found in the LICENSE file or at
568
+ https://opensource.org/licenses/MIT.
569
+ */ const getFriendlyURL = (url)=>{
570
+ const urlObj = new URL(String(url), location.href);
571
+ // See https://github.com/GoogleChrome/workbox/issues/2323
572
+ // We want to include everything, except for the origin if it's same-origin.
573
+ return urlObj.href.replace(new RegExp(`^${location.origin}`), "");
574
+ };
575
+
576
+ /*
577
+ Copyright 2019 Google LLC
578
+ Use of this source code is governed by an MIT-style
579
+ license that can be found in the LICENSE file or at
580
+ https://opensource.org/licenses/MIT.
581
+ */ /**
582
+ * Returns a promise that resolves and the passed number of milliseconds.
583
+ * This utility is an async/await-friendly version of `setTimeout`.
584
+ *
585
+ * @param ms
586
+ * @returns
587
+ * @private
588
+ */ function timeout(ms) {
589
+ return new Promise((resolve)=>setTimeout(resolve, ms));
590
+ }
591
+
592
+ const MAX_RETRY_TIME = 2000;
593
+ /**
594
+ * Returns a promise that resolves to a window client matching the passed
595
+ * `resultingClientId`. For browsers that don't support `resultingClientId`
596
+ * or if waiting for the resulting client to apper takes too long, resolve to
597
+ * `undefined`.
598
+ *
599
+ * @param resultingClientId
600
+ * @returns
601
+ * @private
602
+ */ async function resultingClientExists(resultingClientId) {
603
+ if (!resultingClientId) {
604
+ return;
605
+ }
606
+ let existingWindows = await self.clients.matchAll({
607
+ type: "window"
608
+ });
609
+ const existingWindowIds = new Set(existingWindows.map((w)=>w.id));
610
+ let resultingWindow;
611
+ const startTime = performance.now();
612
+ // Only wait up to `MAX_RETRY_TIME` to find a matching client.
613
+ while(performance.now() - startTime < MAX_RETRY_TIME){
614
+ existingWindows = await self.clients.matchAll({
615
+ type: "window"
616
+ });
617
+ resultingWindow = existingWindows.find((w)=>{
618
+ if (resultingClientId) {
619
+ // If we have a `resultingClientId`, we can match on that.
620
+ return w.id === resultingClientId;
621
+ } else {
622
+ // Otherwise match on finding a window not in `existingWindowIds`.
623
+ return !existingWindowIds.has(w.id);
624
+ }
625
+ });
626
+ if (resultingWindow) {
627
+ break;
628
+ }
629
+ // Sleep for 100ms and retry.
630
+ await timeout(100);
631
+ }
632
+ return resultingWindow;
633
+ }
634
+
635
+ /*
636
+ Copyright 2020 Google LLC
637
+ Use of this source code is governed by an MIT-style
638
+ license that can be found in the LICENSE file or at
639
+ https://opensource.org/licenses/MIT.
640
+ */ /**
641
+ * A utility method that makes it easier to use `event.waitUntil` with
642
+ * async functions and return the result.
643
+ *
644
+ * @param event
645
+ * @param asyncFn
646
+ * @returns
647
+ * @private
648
+ */ function waitUntil(event, asyncFn) {
649
+ const returnPromise = asyncFn();
650
+ event.waitUntil(returnPromise);
651
+ return returnPromise;
652
+ }
653
+
654
+ exports.Deferred = Deferred;
655
+ exports.SerwistError = SerwistError;
656
+ exports.assert = finalAssertExports;
657
+ exports.cacheMatchIgnoreParams = cacheMatchIgnoreParams;
658
+ exports.canConstructReadableStream = canConstructReadableStream;
659
+ exports.canConstructResponseFromBodyStream = canConstructResponseFromBodyStream;
660
+ exports.dontWaitFor = dontWaitFor;
661
+ exports.executeQuotaErrorCallbacks = executeQuotaErrorCallbacks;
662
+ exports.getFriendlyURL = getFriendlyURL;
663
+ exports.logger = logger;
664
+ exports.privateCacheNames = cacheNames;
665
+ exports.resultingClientExists = resultingClientExists;
666
+ exports.timeout = timeout;
667
+ exports.waitUntil = waitUntil;