vendor: 25 bytes, lines 1-3
1"use strict"; 2(() => { 3
vendor: 111 bytes, lines 3-9
3// node_modules/workbox-core/_version.js 4 try { 5 self["workbox:core:7.3.0"] && _(); 6 } catch (e) { 7 } 8 9
vendor: 286 bytes, lines 9-19
9// node_modules/workbox-core/models/messages/messageGenerator.js 10 var fallback = (code, ...args) => { 11 let msg = code; 12 if (args.length > 0) { 13 msg += ` :: ${JSON.stringify(args)}`; 14 } 15 return msg; 16 }; 17 var messageGenerator = true ? fallback : generatorFunction; 18 19
vendor: 566 bytes, lines 19-37
19// node_modules/workbox-core/_private/WorkboxError.js 20 var WorkboxError = class extends Error { 21 /** 22 * 23 * @param {string} errorCode The error code that 24 * identifies this particular error. 25 * @param {Object=} details Any relevant arguments 26 * that will help developers identify issues should 27 * be added as a key on the context object. 28 */ 29 constructor(errorCode, details) { 30 const message = messageGenerator(errorCode, details); 31 super(message); 32 this.name = errorCode; 33 this.details = details; 34 } 35 }; 36 37
vendor: 1,440 bytes, lines 37-89
37// node_modules/workbox-core/_private/logger.js 38 var logger = true ? null : (() => { 39 if (!("__WB_DISABLE_DEV_LOGS" in globalThis)) { 40 self.__WB_DISABLE_DEV_LOGS = false; 41 } 42 let inGroup = false; 43 const methodToColorMap = { 44 debug: `#7f8c8d`, 45 log: `#2ecc71`, 46 warn: `#f39c12`, 47 error: `#c0392b`, 48 groupCollapsed: `#3498db`, 49 groupEnd: null 50 // No colored prefix on groupEnd 51 }; 52 const print = function(method, args) { 53 if (self.__WB_DISABLE_DEV_LOGS) { 54 return; 55 } 56 if (method === "groupCollapsed") { 57 if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { 58 console[method](...args); 59 return; 60 } 61 } 62 const styles = [ 63 `background: ${methodToColorMap[method]}`, 64 `border-radius: 0.5em`, 65 `color: white`, 66 `font-weight: bold`, 67 `padding: 2px 0.5em` 68 ]; 69 const logPrefix = inGroup ? [] : ["%cworkbox", styles.join(";")]; 70 console[method](...logPrefix, ...args); 71 if (method === "groupCollapsed") { 72 inGroup = true; 73 } 74 if (method === "groupEnd") { 75 inGroup = false; 76 } 77 }; 78 const api = {}; 79 const loggerMethods = Object.keys(methodToColorMap); 80 for (const key of loggerMethods) { 81 const method = key; 82 api[method] = (...args) => { 83 print(method, args); 84 }; 85 } 86 return api; 87 })(); 88 89
vendor: 117 bytes, lines 89-95
89// node_modules/workbox-routing/_version.js 90 try { 91 self["workbox:routing:7.3.0"] && _(); 92 } catch (e) { 93 } 94 95
vendor: 83 bytes, lines 95-98
95// node_modules/workbox-routing/utils/constants.js 96 var defaultMethod = "GET"; 97 98
vendor: 698 bytes, lines 98-123
98// node_modules/workbox-routing/utils/normalizeHandler.js 99 var normalizeHandler = (handler) => { 100 if (handler && typeof handler === "object") { 101 if (false) { 102 finalAssertExports.hasMethod(handler, "handle", { 103 moduleName: "workbox-routing", 104 className: "Route", 105 funcName: "constructor", 106 paramName: "handler" 107 }); 108 } 109 return handler; 110 } else { 111 if (false) { 112 finalAssertExports.isType(handler, "function", { 113 moduleName: "workbox-routing", 114 className: "Route", 115 funcName: "constructor", 116 paramName: "handler" 117 }); 118 } 119 return { handle: handler }; 120 } 121 }; 122 123
vendor: 1,287 bytes, lines 123-162
123// node_modules/workbox-routing/Route.js 124 var Route = class { 125 /** 126 * Constructor for Route class. 127 * 128 * @param {workbox-routing~matchCallback} match 129 * A callback function that determines whether the route matches a given 130 * `fetch` event by returning a non-falsy value. 131 * @param {workbox-routing~handlerCallback} handler A callback 132 * function that returns a Promise resolving to a Response. 133 * @param {string} [method='GET'] The HTTP method to match the Route 134 * against. 135 */ 136 constructor(match, handler, method = defaultMethod) { 137 if (false) { 138 finalAssertExports.isType(match, "function", { 139 moduleName: "workbox-routing", 140 className: "Route", 141 funcName: "constructor", 142 paramName: "match" 143 }); 144 if (method) { 145 finalAssertExports.isOneOf(method, validMethods, { paramName: "method" }); 146 } 147 } 148 this.handler = normalizeHandler(handler); 149 this.match = match; 150 this.method = method; 151 } 152 /** 153 * 154 * @param {workbox-routing-handlerCallback} handler A callback 155 * function that returns a Promise resolving to a Response 156 */ 157 setCatchHandler(handler) { 158 this.catchHandler = normalizeHandler(handler); 159 } 160 }; 161 162
vendor: 1,584 bytes, lines 162-203
162// node_modules/workbox-routing/RegExpRoute.js 163 var RegExpRoute = class extends Route { 164 /** 165 * If the regular expression contains 166 * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references}, 167 * the captured values will be passed to the 168 * {@link workbox-routing~handlerCallback} `params` 169 * argument. 170 * 171 * @param {RegExp} regExp The regular expression to match against URLs. 172 * @param {workbox-routing~handlerCallback} handler A callback 173 * function that returns a Promise resulting in a Response. 174 * @param {string} [method='GET'] The HTTP method to match the Route 175 * against. 176 */ 177 constructor(regExp, handler, method) { 178 if (false) { 179 finalAssertExports.isInstance(regExp, RegExp, { 180 moduleName: "workbox-routing", 181 className: "RegExpRoute", 182 funcName: "constructor", 183 paramName: "pattern" 184 }); 185 } 186 const match = ({ url }) => { 187 const result = regExp.exec(url.href); 188 if (!result) { 189 return; 190 } 191 if (url.origin !== location.origin && result.index !== 0) { 192 if (false) { 193 logger.debug(`The regular expression '${regExp.toString()}' only partially matched against the cross-origin URL '${url.toString()}'. RegExpRoute's will only handle cross-origin requests if they match the entire URL.`); 194 } 195 return; 196 } 197 return result.slice(1); 198 }; 199 super(match, handler, method); 200 } 201 }; 202 203
vendor: 225 bytes, lines 203-209
203// node_modules/workbox-core/_private/getFriendlyURL.js 204 var getFriendlyURL = (url) => { 205 const urlObj = new URL(String(url), location.href); 206 return urlObj.href.replace(new RegExp(`^${location.origin}`), ""); 207 }; 208 209
vendor: 11,236 bytes, lines 209-522
209// node_modules/workbox-routing/Router.js 210 var Router = class { 211 /** 212 * Initializes a new Router. 213 */ 214 constructor() { 215 this._routes = /* @__PURE__ */ new Map(); 216 this._defaultHandlerMap = /* @__PURE__ */ new Map(); 217 } 218 /** 219 * @return {Map<string, Array<workbox-routing.Route>>} routes A `Map` of HTTP 220 * method name ('GET', etc.) to an array of all the corresponding `Route` 221 * instances that are registered. 222 */ 223 get routes() { 224 return this._routes; 225 } 226 /** 227 * Adds a fetch event listener to respond to events when a route matches 228 * the event's request. 229 */ 230 addFetchListener() { 231 self.addEventListener("fetch", ((event) => { 232 const { request } = event; 233 const responsePromise = this.handleRequest({ request, event }); 234 if (responsePromise) { 235 event.respondWith(responsePromise); 236 } 237 })); 238 } 239 /** 240 * Adds a message event listener for URLs to cache from the window. 241 * This is useful to cache resources loaded on the page prior to when the 242 * service worker started controlling it. 243 * 244 * The format of the message data sent from the window should be as follows. 245 * Where the `urlsToCache` array may consist of URL strings or an array of 246 * URL string + `requestInit` object (the same as you'd pass to `fetch()`). 247 * 248 * ``` 249 * { 250 * type: 'CACHE_URLS', 251 * payload: { 252 * urlsToCache: [ 253 * './script1.js', 254 * './script2.js', 255 * ['./script3.js', {mode: 'no-cors'}], 256 * ], 257 * }, 258 * } 259 * ``` 260 */ 261 addCacheListener() { 262 self.addEventListener("message", ((event) => { 263 if (event.data && event.data.type === "CACHE_URLS") { 264 const { payload } = event.data; 265 if (false) { 266 logger.debug(`Caching URLs from the window`, payload.urlsToCache); 267 } 268 const requestPromises = Promise.all(payload.urlsToCache.map((entry) => { 269 if (typeof entry === "string") { 270 entry = [entry]; 271 } 272 const request = new Request(...entry); 273 return this.handleRequest({ request, event }); 274 })); 275 event.waitUntil(requestPromises); 276 if (event.ports && event.ports[0]) { 277 void requestPromises.then(() => event.ports[0].postMessage(true)); 278 } 279 } 280 })); 281 } 282 /** 283 * Apply the routing rules to a FetchEvent object to get a Response from an 284 * appropriate Route's handler. 285 * 286 * @param {Object} options 287 * @param {Request} options.request The request to handle. 288 * @param {ExtendableEvent} options.event The event that triggered the 289 * request. 290 * @return {Promise<Response>|undefined} A promise is returned if a 291 * registered route can handle the request. If there is no matching 292 * route and there's no `defaultHandler`, `undefined` is returned. 293 */ 294 handleRequest({ request, event }) { 295 if (false) { 296 finalAssertExports.isInstance(request, Request, { 297 moduleName: "workbox-routing", 298 className: "Router", 299 funcName: "handleRequest", 300 paramName: "options.request" 301 }); 302 } 303 const url = new URL(request.url, location.href); 304 if (!url.protocol.startsWith("http")) { 305 if (false) { 306 logger.debug(`Workbox Router only supports URLs that start with 'http'.`); 307 } 308 return; 309 } 310 const sameOrigin = url.origin === location.origin; 311 const { params, route } = this.findMatchingRoute({ 312 event, 313 request, 314 sameOrigin, 315 url 316 }); 317 let handler = route && route.handler; 318 const debugMessages = []; 319 if (false) { 320 if (handler) { 321 debugMessages.push([`Found a route to handle this request:`, route]); 322 if (params) { 323 debugMessages.push([ 324 `Passing the following params to the route's handler:`, 325 params 326 ]); 327 } 328 } 329 } 330 const method = request.method; 331 if (!handler && this._defaultHandlerMap.has(method)) { 332 if (false) { 333 debugMessages.push(`Failed to find a matching route. Falling back to the default handler for ${method}.`); 334 } 335 handler = this._defaultHandlerMap.get(method); 336 } 337 if (!handler) { 338 if (false) { 339 logger.debug(`No route found for: ${getFriendlyURL(url)}`); 340 } 341 return; 342 } 343 if (false) { 344 logger.groupCollapsed(`Router is responding to: ${getFriendlyURL(url)}`); 345 debugMessages.forEach((msg) => { 346 if (Array.isArray(msg)) { 347 logger.log(...msg); 348 } else { 349 logger.log(msg); 350 } 351 }); 352 logger.groupEnd(); 353 } 354 let responsePromise; 355 try { 356 responsePromise = handler.handle({ url, request, event, params }); 357 } catch (err) { 358 responsePromise = Promise.reject(err); 359 } 360 const catchHandler = route && route.catchHandler; 361 if (responsePromise instanceof Promise && (this._catchHandler || catchHandler)) { 362 responsePromise = responsePromise.catch(async (err) => { 363 if (catchHandler) { 364 if (false) { 365 logger.groupCollapsed(`Error thrown when responding to: ${getFriendlyURL(url)}. Falling back to route's Catch Handler.`); 366 logger.error(`Error thrown by:`, route); 367 logger.error(err); 368 logger.groupEnd(); 369 } 370 try { 371 return await catchHandler.handle({ url, request, event, params }); 372 } catch (catchErr) { 373 if (catchErr instanceof Error) { 374 err = catchErr; 375 } 376 } 377 } 378 if (this._catchHandler) { 379 if (false) { 380 logger.groupCollapsed(`Error thrown when responding to: ${getFriendlyURL(url)}. Falling back to global Catch Handler.`); 381 logger.error(`Error thrown by:`, route); 382 logger.error(err); 383 logger.groupEnd(); 384 } 385 return this._catchHandler.handle({ url, request, event }); 386 } 387 throw err; 388 }); 389 } 390 return responsePromise; 391 } 392 /** 393 * Checks a request and URL (and optionally an event) against the list of 394 * registered routes, and if there's a match, returns the corresponding 395 * route along with any params generated by the match. 396 * 397 * @param {Object} options 398 * @param {URL} options.url 399 * @param {boolean} options.sameOrigin The result of comparing `url.origin` 400 * against the current origin. 401 * @param {Request} options.request The request to match. 402 * @param {Event} options.event The corresponding event. 403 * @return {Object} An object with `route` and `params` properties. 404 * They are populated if a matching route was found or `undefined` 405 * otherwise. 406 */ 407 findMatchingRoute({ url, sameOrigin, request, event }) { 408 const routes = this._routes.get(request.method) || []; 409 for (const route of routes) { 410 let params; 411 const matchResult = route.match({ url, sameOrigin, request, event }); 412 if (matchResult) { 413 if (false) { 414 if (matchResult instanceof Promise) { 415 logger.warn(`While routing ${getFriendlyURL(url)}, an async matchCallback function was used. Please convert the following route to use a synchronous matchCallback function:`, route); 416 } 417 } 418 params = matchResult; 419 if (Array.isArray(params) && params.length === 0) { 420 params = void 0; 421 } else if (matchResult.constructor === Object && // eslint-disable-line 422 Object.keys(matchResult).length === 0) { 423 params = void 0; 424 } else if (typeof matchResult === "boolean") { 425 params = void 0; 426 } 427 return { route, params }; 428 } 429 } 430 return {}; 431 } 432 /** 433 * Define a default `handler` that's called when no routes explicitly 434 * match the incoming request. 435 * 436 * Each HTTP method ('GET', 'POST', etc.) gets its own default handler. 437 * 438 * Without a default handler, unmatched requests will go against the 439 * network as if there were no service worker present. 440 * 441 * @param {workbox-routing~handlerCallback} handler A callback 442 * function that returns a Promise resulting in a Response. 443 * @param {string} [method='GET'] The HTTP method to associate with this 444 * default handler. Each method has its own default. 445 */ 446 setDefaultHandler(handler, method = defaultMethod) { 447 this._defaultHandlerMap.set(method, normalizeHandler(handler)); 448 } 449 /** 450 * If a Route throws an error while handling a request, this `handler` 451 * will be called and given a chance to provide a response. 452 * 453 * @param {workbox-routing~handlerCallback} handler A callback 454 * function that returns a Promise resulting in a Response. 455 */ 456 setCatchHandler(handler) { 457 this._catchHandler = normalizeHandler(handler); 458 } 459 /** 460 * Registers a route with the router. 461 * 462 * @param {workbox-routing.Route} route The route to register. 463 */ 464 registerRoute(route) { 465 if (false) { 466 finalAssertExports.isType(route, "object", { 467 moduleName: "workbox-routing", 468 className: "Router", 469 funcName: "registerRoute", 470 paramName: "route" 471 }); 472 finalAssertExports.hasMethod(route, "match", { 473 moduleName: "workbox-routing", 474 className: "Router", 475 funcName: "registerRoute", 476 paramName: "route" 477 }); 478 finalAssertExports.isType(route.handler, "object", { 479 moduleName: "workbox-routing", 480 className: "Router", 481 funcName: "registerRoute", 482 paramName: "route" 483 }); 484 finalAssertExports.hasMethod(route.handler, "handle", { 485 moduleName: "workbox-routing", 486 className: "Router", 487 funcName: "registerRoute", 488 paramName: "route.handler" 489 }); 490 finalAssertExports.isType(route.method, "string", { 491 moduleName: "workbox-routing", 492 className: "Router", 493 funcName: "registerRoute", 494 paramName: "route.method" 495 }); 496 } 497 if (!this._routes.has(route.method)) { 498 this._routes.set(route.method, []); 499 } 500 this._routes.get(route.method).push(route); 501 } 502 /** 503 * Unregisters a route with the router. 504 * 505 * @param {workbox-routing.Route} route The route to unregister. 506 */ 507 unregisterRoute(route) { 508 if (!this._routes.has(route.method)) { 509 throw new WorkboxError("unregister-route-but-not-found-with-method", { 510 method: route.method 511 }); 512 } 513 const routeIndex = this._routes.get(route.method).indexOf(route); 514 if (routeIndex > -1) { 515 this._routes.get(route.method).splice(routeIndex, 1); 516 } else { 517 throw new WorkboxError("unregister-route-route-not-registered"); 518 } 519 } 520 }; 521 522
vendor: 310 bytes, lines 522-533
522// node_modules/workbox-routing/utils/getOrCreateDefaultRouter.js 523 var defaultRouter; 524 var getOrCreateDefaultRouter = () => { 525 if (!defaultRouter) { 526 defaultRouter = new Router(); 527 defaultRouter.addFetchListener(); 528 defaultRouter.addCacheListener(); 529 } 530 return defaultRouter; 531 }; 532 533
vendor: 1,959 bytes, lines 533-579
533// node_modules/workbox-routing/registerRoute.js 534 function registerRoute(capture, handler, method) { 535 let route; 536 if (typeof capture === "string") { 537 const captureUrl = new URL(capture, location.href); 538 if (false) { 539 if (!(capture.startsWith("/") || capture.startsWith("http"))) { 540 throw new WorkboxError("invalid-string", { 541 moduleName: "workbox-routing", 542 funcName: "registerRoute", 543 paramName: "capture" 544 }); 545 } 546 const valueToCheck = capture.startsWith("http") ? captureUrl.pathname : capture; 547 const wildcards = "[*:?+]"; 548 if (new RegExp(`${wildcards}`).exec(valueToCheck)) { 549 logger.debug(`The '$capture' parameter contains an Express-style wildcard character (${wildcards}). Strings are now always interpreted as exact matches; use a RegExp for partial or wildcard matches.`); 550 } 551 } 552 const matchCallback = ({ url }) => { 553 if (false) { 554 if (url.pathname === captureUrl.pathname && url.origin !== captureUrl.origin) { 555 logger.debug(`${capture} only partially matches the cross-origin URL ${url.toString()}. This route will only handle cross-origin requests if they match the entire URL.`); 556 } 557 } 558 return url.href === captureUrl.href; 559 }; 560 route = new Route(matchCallback, handler, method); 561 } else if (capture instanceof RegExp) { 562 route = new RegExpRoute(capture, handler, method); 563 } else if (typeof capture === "function") { 564 route = new Route(capture, handler, method); 565 } else if (capture instanceof Route) { 566 route = capture; 567 } else { 568 throw new WorkboxError("unsupported-route-type", { 569 moduleName: "workbox-routing", 570 funcName: "registerRoute", 571 paramName: "capture" 572 }); 573 } 574 const defaultRouter2 = getOrCreateDefaultRouter(); 575 defaultRouter2.registerRoute(route); 576 return route; 577 } 578 579
vendor: 1,321 bytes, lines 579-620
579// node_modules/workbox-core/_private/cacheNames.js 580 var _cacheNameDetails = { 581 googleAnalytics: "googleAnalytics", 582 precache: "precache-v2", 583 prefix: "workbox", 584 runtime: "runtime", 585 suffix: typeof registration !== "undefined" ? registration.scope : "" 586 }; 587 var _createCacheName = (cacheName) => { 588 return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix].filter((value) => value && value.length > 0).join("-"); 589 }; 590 var eachCacheNameDetail = (fn) => { 591 for (const key of Object.keys(_cacheNameDetails)) { 592 fn(key); 593 } 594 }; 595 var cacheNames = { 596 updateDetails: (details) => { 597 eachCacheNameDetail((key) => { 598 if (typeof details[key] === "string") { 599 _cacheNameDetails[key] = details[key]; 600 } 601 }); 602 }, 603 getGoogleAnalyticsName: (userCacheName) => { 604 return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics); 605 }, 606 getPrecacheName: (userCacheName) => { 607 return userCacheName || _createCacheName(_cacheNameDetails.precache); 608 }, 609 getPrefix: () => { 610 return _cacheNameDetails.prefix; 611 }, 612 getRuntimeName: (userCacheName) => { 613 return userCacheName || _createCacheName(_cacheNameDetails.runtime); 614 }, 615 getSuffix: () => { 616 return _cacheNameDetails.suffix; 617 } 618 }; 619 620
vendor: 951 bytes, lines 620-644
620// node_modules/workbox-core/_private/cacheMatchIgnoreParams.js 621 function stripParams(fullURL, ignoreParams) { 622 const strippedURL = new URL(fullURL); 623 for (const param of ignoreParams) { 624 strippedURL.searchParams.delete(param); 625 } 626 return strippedURL.href; 627 } 628 async function cacheMatchIgnoreParams(cache, request, ignoreParams, matchOptions) { 629 const strippedRequestURL = stripParams(request.url, ignoreParams); 630 if (request.url === strippedRequestURL) { 631 return cache.match(request, matchOptions); 632 } 633 const keysOptions = Object.assign(Object.assign({}, matchOptions), { ignoreSearch: true }); 634 const cacheKeys = await cache.keys(request, keysOptions); 635 for (const cacheKey of cacheKeys) { 636 const strippedCacheKeyURL = stripParams(cacheKey.url, ignoreParams); 637 if (strippedRequestURL === strippedCacheKeyURL) { 638 return cache.match(cacheKey, matchOptions); 639 } 640 } 641 return; 642 } 643 644
vendor: 335 bytes, lines 644-657
644// node_modules/workbox-core/_private/Deferred.js 645 var Deferred = class { 646 /** 647 * Creates a promise and exposes its resolve and reject functions as methods. 648 */ 649 constructor() { 650 this.promise = new Promise((resolve, reject) => { 651 this.resolve = resolve; 652 this.reject = reject; 653 }); 654 } 655 }; 656 657
vendor: 117 bytes, lines 657-660
657// node_modules/workbox-core/models/quotaErrorCallbacks.js 658 var quotaErrorCallbacks = /* @__PURE__ */ new Set(); 659 660
vendor: 463 bytes, lines 660-676
660// node_modules/workbox-core/_private/executeQuotaErrorCallbacks.js 661 async function executeQuotaErrorCallbacks() { 662 if (false) { 663 logger.log(`About to run ${quotaErrorCallbacks.size} callbacks to clean up caches.`); 664 } 665 for (const callback of quotaErrorCallbacks) { 666 await callback(); 667 if (false) { 668 logger.log(callback, "is complete."); 669 } 670 } 671 if (false) { 672 logger.log("Finished running callbacks."); 673 } 674 } 675 676
vendor: 143 bytes, lines 676-681
676// node_modules/workbox-core/_private/timeout.js 677 function timeout(ms) { 678 return new Promise((resolve) => setTimeout(resolve, ms)); 679 } 680 681
vendor: 123 bytes, lines 681-687
681// node_modules/workbox-strategies/_version.js 682 try { 683 self["workbox:strategies:7.3.0"] && _(); 684 } catch (e) { 685 } 686 687
vendor: 16,120 bytes, lines 687-1106
687// node_modules/workbox-strategies/StrategyHandler.js 688 function toRequest(input) { 689 return typeof input === "string" ? new Request(input) : input; 690 } 691 var StrategyHandler = class { 692 /** 693 * Creates a new instance associated with the passed strategy and event 694 * that's handling the request. 695 * 696 * The constructor also initializes the state that will be passed to each of 697 * the plugins handling this request. 698 * 699 * @param {workbox-strategies.Strategy} strategy 700 * @param {Object} options 701 * @param {Request|string} options.request A request to run this strategy for. 702 * @param {ExtendableEvent} options.event The event associated with the 703 * request. 704 * @param {URL} [options.url] 705 * @param {*} [options.params] The return value from the 706 * {@link workbox-routing~matchCallback} (if applicable). 707 */ 708 constructor(strategy, options) { 709 this._cacheKeys = {}; 710 if (false) { 711 finalAssertExports.isInstance(options.event, ExtendableEvent, { 712 moduleName: "workbox-strategies", 713 className: "StrategyHandler", 714 funcName: "constructor", 715 paramName: "options.event" 716 }); 717 } 718 Object.assign(this, options); 719 this.event = options.event; 720 this._strategy = strategy; 721 this._handlerDeferred = new Deferred(); 722 this._extendLifetimePromises = []; 723 this._plugins = [...strategy.plugins]; 724 this._pluginStateMap = /* @__PURE__ */ new Map(); 725 for (const plugin of this._plugins) { 726 this._pluginStateMap.set(plugin, {}); 727 } 728 this.event.waitUntil(this._handlerDeferred.promise); 729 } 730 /** 731 * Fetches a given request (and invokes any applicable plugin callback 732 * methods) using the `fetchOptions` (for non-navigation requests) and 733 * `plugins` defined on the `Strategy` object. 734 * 735 * The following plugin lifecycle methods are invoked when using this method: 736 * - `requestWillFetch()` 737 * - `fetchDidSucceed()` 738 * - `fetchDidFail()` 739 * 740 * @param {Request|string} input The URL or request to fetch. 741 * @return {Promise<Response>} 742 */ 743 async fetch(input) { 744 const { event } = this; 745 let request = toRequest(input); 746 if (request.mode === "navigate" && event instanceof FetchEvent && event.preloadResponse) { 747 const possiblePreloadResponse = await event.preloadResponse; 748 if (possiblePreloadResponse) { 749 if (false) { 750 logger.log(`Using a preloaded navigation response for '${getFriendlyURL(request.url)}'`); 751 } 752 return possiblePreloadResponse; 753 } 754 } 755 const originalRequest = this.hasCallback("fetchDidFail") ? request.clone() : null; 756 try { 757 for (const cb of this.iterateCallbacks("requestWillFetch")) { 758 request = await cb({ request: request.clone(), event }); 759 } 760 } catch (err) { 761 if (err instanceof Error) { 762 throw new WorkboxError("plugin-error-request-will-fetch", { 763 thrownErrorMessage: err.message 764 }); 765 } 766 } 767 const pluginFilteredRequest = request.clone(); 768 try { 769 let fetchResponse; 770 fetchResponse = await fetch(request, request.mode === "navigate" ? void 0 : this._strategy.fetchOptions); 771 if (false) { 772 logger.debug(`Network request for '${getFriendlyURL(request.url)}' returned a response with status '${fetchResponse.status}'.`); 773 } 774 for (const callback of this.iterateCallbacks("fetchDidSucceed")) { 775 fetchResponse = await callback({ 776 event, 777 request: pluginFilteredRequest, 778 response: fetchResponse 779 }); 780 } 781 return fetchResponse; 782 } catch (error) { 783 if (false) { 784 logger.log(`Network request for '${getFriendlyURL(request.url)}' threw an error.`, error); 785 } 786 if (originalRequest) { 787 await this.runCallbacks("fetchDidFail", { 788 error, 789 event, 790 originalRequest: originalRequest.clone(), 791 request: pluginFilteredRequest.clone() 792 }); 793 } 794 throw error; 795 } 796 } 797 /** 798 * Calls `this.fetch()` and (in the background) runs `this.cachePut()` on 799 * the response generated by `this.fetch()`. 800 * 801 * The call to `this.cachePut()` automatically invokes `this.waitUntil()`, 802 * so you do not have to manually call `waitUntil()` on the event. 803 * 804 * @param {Request|string} input The request or URL to fetch and cache. 805 * @return {Promise<Response>} 806 */ 807 async fetchAndCachePut(input) { 808 const response = await this.fetch(input); 809 const responseClone = response.clone(); 810 void this.waitUntil(this.cachePut(input, responseClone)); 811 return response; 812 } 813 /** 814 * Matches a request from the cache (and invokes any applicable plugin 815 * callback methods) using the `cacheName`, `matchOptions`, and `plugins` 816 * defined on the strategy object. 817 * 818 * The following plugin lifecycle methods are invoked when using this method: 819 * - cacheKeyWillBeUsed() 820 * - cachedResponseWillBeUsed() 821 * 822 * @param {Request|string} key The Request or URL to use as the cache key. 823 * @return {Promise<Response|undefined>} A matching response, if found. 824 */ 825 async cacheMatch(key) { 826 const request = toRequest(key); 827 let cachedResponse; 828 const { cacheName, matchOptions } = this._strategy; 829 const effectiveRequest = await this.getCacheKey(request, "read"); 830 const multiMatchOptions = Object.assign(Object.assign({}, matchOptions), { cacheName }); 831 cachedResponse = await caches.match(effectiveRequest, multiMatchOptions); 832 if (false) { 833 if (cachedResponse) { 834 logger.debug(`Found a cached response in '${cacheName}'.`); 835 } else { 836 logger.debug(`No cached response found in '${cacheName}'.`); 837 } 838 } 839 for (const callback of this.iterateCallbacks("cachedResponseWillBeUsed")) { 840 cachedResponse = await callback({ 841 cacheName, 842 matchOptions, 843 cachedResponse, 844 request: effectiveRequest, 845 event: this.event 846 }) || void 0; 847 } 848 return cachedResponse; 849 } 850 /** 851 * Puts a request/response pair in the cache (and invokes any applicable 852 * plugin callback methods) using the `cacheName` and `plugins` defined on 853 * the strategy object. 854 * 855 * The following plugin lifecycle methods are invoked when using this method: 856 * - cacheKeyWillBeUsed() 857 * - cacheWillUpdate() 858 * - cacheDidUpdate() 859 * 860 * @param {Request|string} key The request or URL to use as the cache key. 861 * @param {Response} response The response to cache. 862 * @return {Promise<boolean>} `false` if a cacheWillUpdate caused the response 863 * not be cached, and `true` otherwise. 864 */ 865 async cachePut(key, response) { 866 const request = toRequest(key); 867 await timeout(0); 868 const effectiveRequest = await this.getCacheKey(request, "write"); 869 if (false) { 870 if (effectiveRequest.method && effectiveRequest.method !== "GET") { 871 throw new WorkboxError("attempt-to-cache-non-get-request", { 872 url: getFriendlyURL(effectiveRequest.url), 873 method: effectiveRequest.method 874 }); 875 } 876 const vary = response.headers.get("Vary"); 877 if (vary) { 878 logger.debug(`The response for ${getFriendlyURL(effectiveRequest.url)} has a 'Vary: ${vary}' header. Consider setting the {ignoreVary: true} option on your strategy to ensure cache matching and deletion works as expected.`); 879 } 880 } 881 if (!response) { 882 if (false) { 883 logger.error(`Cannot cache non-existent response for '${getFriendlyURL(effectiveRequest.url)}'.`); 884 } 885 throw new WorkboxError("cache-put-with-no-response", { 886 url: getFriendlyURL(effectiveRequest.url) 887 }); 888 } 889 const responseToCache = await this._ensureResponseSafeToCache(response); 890 if (!responseToCache) { 891 if (false) { 892 logger.debug(`Response '${getFriendlyURL(effectiveRequest.url)}' will not be cached.`, responseToCache); 893 } 894 return false; 895 } 896 const { cacheName, matchOptions } = this._strategy; 897 const cache = await self.caches.open(cacheName); 898 const hasCacheUpdateCallback = this.hasCallback("cacheDidUpdate"); 899 const oldResponse = hasCacheUpdateCallback ? await cacheMatchIgnoreParams( 900 // TODO(philipwalton): the `__WB_REVISION__` param is a precaching 901 // feature. Consider into ways to only add this behavior if using 902 // precaching. 903 cache, 904 effectiveRequest.clone(), 905 ["__WB_REVISION__"], 906 matchOptions 907 ) : null; 908 if (false) { 909 logger.debug(`Updating the '${cacheName}' cache with a new Response for ${getFriendlyURL(effectiveRequest.url)}.`); 910 } 911 try { 912 await cache.put(effectiveRequest, hasCacheUpdateCallback ? responseToCache.clone() : responseToCache); 913 } catch (error) { 914 if (error instanceof Error) { 915 if (error.name === "QuotaExceededError") { 916 await executeQuotaErrorCallbacks(); 917 } 918 throw error; 919 } 920 } 921 for (const callback of this.iterateCallbacks("cacheDidUpdate")) { 922 await callback({ 923 cacheName, 924 oldResponse, 925 newResponse: responseToCache.clone(), 926 request: effectiveRequest, 927 event: this.event 928 }); 929 } 930 return true; 931 } 932 /** 933 * Checks the list of plugins for the `cacheKeyWillBeUsed` callback, and 934 * executes any of those callbacks found in sequence. The final `Request` 935 * object returned by the last plugin is treated as the cache key for cache 936 * reads and/or writes. If no `cacheKeyWillBeUsed` plugin callbacks have 937 * been registered, the passed request is returned unmodified 938 * 939 * @param {Request} request 940 * @param {string} mode 941 * @return {Promise<Request>} 942 */ 943 async getCacheKey(request, mode) { 944 const key = `${request.url} | ${mode}`; 945 if (!this._cacheKeys[key]) { 946 let effectiveRequest = request; 947 for (const callback of this.iterateCallbacks("cacheKeyWillBeUsed")) { 948 effectiveRequest = toRequest(await callback({ 949 mode, 950 request: effectiveRequest, 951 event: this.event, 952 // params has a type any can't change right now. 953 params: this.params 954 // eslint-disable-line 955 })); 956 } 957 this._cacheKeys[key] = effectiveRequest; 958 } 959 return this._cacheKeys[key]; 960 } 961 /** 962 * Returns true if the strategy has at least one plugin with the given 963 * callback. 964 * 965 * @param {string} name The name of the callback to check for. 966 * @return {boolean} 967 */ 968 hasCallback(name) { 969 for (const plugin of this._strategy.plugins) { 970 if (name in plugin) { 971 return true; 972 } 973 } 974 return false; 975 } 976 /** 977 * Runs all plugin callbacks matching the given name, in order, passing the 978 * given param object (merged ith the current plugin state) as the only 979 * argument. 980 * 981 * Note: since this method runs all plugins, it's not suitable for cases 982 * where the return value of a callback needs to be applied prior to calling 983 * the next callback. See 984 * {@link workbox-strategies.StrategyHandler#iterateCallbacks} 985 * below for how to handle that case. 986 * 987 * @param {string} name The name of the callback to run within each plugin. 988 * @param {Object} param The object to pass as the first (and only) param 989 * when executing each callback. This object will be merged with the 990 * current plugin state prior to callback execution. 991 */ 992 async runCallbacks(name, param) { 993 for (const callback of this.iterateCallbacks(name)) { 994 await callback(param); 995 } 996 } 997 /** 998 * Accepts a callback and returns an iterable of matching plugin callbacks, 999 * where each callback is wrapped with the current handler state (i.e. when 1000 * you call each callback, whatever object parameter you pass it will 1001 * be merged with the plugin's current state). 1002 * 1003 * @param {string} name The name fo the callback to run 1004 * @return {Array<Function>} 1005 */ 1006 *iterateCallbacks(name) { 1007 for (const plugin of this._strategy.plugins) { 1008 if (typeof plugin[name] === "function") { 1009 const state = this._pluginStateMap.get(plugin); 1010 const statefulCallback = (param) => { 1011 const statefulParam = Object.assign(Object.assign({}, param), { state }); 1012 return plugin[name](statefulParam); 1013 }; 1014 yield statefulCallback; 1015 } 1016 } 1017 } 1018 /** 1019 * Adds a promise to the 1020 * [extend lifetime promises]{@link https://w3c.github.io/ServiceWorker/#extendableevent-extend-lifetime-promises} 1021 * of the event associated with the request being handled (usually a 1022 * `FetchEvent`). 1023 * 1024 * Note: you can await 1025 * {@link workbox-strategies.StrategyHandler~doneWaiting} 1026 * to know when all added promises have settled. 1027 * 1028 * @param {Promise} promise A promise to add to the extend lifetime promises 1029 * of the event that triggered the request. 1030 */ 1031 waitUntil(promise) { 1032 this._extendLifetimePromises.push(promise); 1033 return promise; 1034 } 1035 /** 1036 * Returns a promise that resolves once all promises passed to 1037 * {@link workbox-strategies.StrategyHandler~waitUntil} 1038 * have settled. 1039 * 1040 * Note: any work done after `doneWaiting()` settles should be manually 1041 * passed to an event's `waitUntil()` method (not this handler's 1042 * `waitUntil()` method), otherwise the service worker thread may be killed 1043 * prior to your work completing. 1044 */ 1045 async doneWaiting() { 1046 while (this._extendLifetimePromises.length) { 1047 const promises = this._extendLifetimePromises.splice(0); 1048 const result = await Promise.allSettled(promises); 1049 const firstRejection = result.find((i) => i.status === "rejected"); 1050 if (firstRejection) { 1051 throw firstRejection.reason; 1052 } 1053 } 1054 } 1055 /** 1056 * Stops running the strategy and immediately resolves any pending 1057 * `waitUntil()` promises. 1058 */ 1059 destroy() { 1060 this._handlerDeferred.resolve(null); 1061 } 1062 /** 1063 * This method will call cacheWillUpdate on the available plugins (or use 1064 * status === 200) to determine if the Response is safe and valid to cache. 1065 * 1066 * @param {Request} options.request 1067 * @param {Response} options.response 1068 * @return {Promise<Response|undefined>} 1069 * 1070 * @private 1071 */ 1072 async _ensureResponseSafeToCache(response) { 1073 let responseToCache = response; 1074 let pluginsUsed = false; 1075 for (const callback of this.iterateCallbacks("cacheWillUpdate")) { 1076 responseToCache = await callback({ 1077 request: this.request, 1078 response: responseToCache, 1079 event: this.event 1080 }) || void 0; 1081 pluginsUsed = true; 1082 if (!responseToCache) { 1083 break; 1084 } 1085 } 1086 if (!pluginsUsed) { 1087 if (responseToCache && responseToCache.status !== 200) { 1088 responseToCache = void 0; 1089 } 1090 if (false) { 1091 if (responseToCache) { 1092 if (responseToCache.status !== 200) { 1093 if (responseToCache.status === 0) { 1094 logger.warn(`The response for '${this.request.url}' is an opaque response. The caching strategy that you're using will not cache opaque responses by default.`); 1095 } else { 1096 logger.debug(`The response for '${this.request.url}' returned a status code of '${response.status}' and won't be cached as a result.`); 1097 } 1098 } 1099 } 1100 } 1101 } 1102 return responseToCache; 1103 } 1104 }; 1105 1106
vendor: 6,247 bytes, lines 1106-1256
1106// node_modules/workbox-strategies/Strategy.js 1107 var Strategy = class { 1108 /** 1109 * Creates a new instance of the strategy and sets all documented option 1110 * properties as public instance properties. 1111 * 1112 * Note: if a custom strategy class extends the base Strategy class and does 1113 * not need more than these properties, it does not need to define its own 1114 * constructor. 1115 * 1116 * @param {Object} [options] 1117 * @param {string} [options.cacheName] Cache name to store and retrieve 1118 * requests. Defaults to the cache names provided by 1119 * {@link workbox-core.cacheNames}. 1120 * @param {Array<Object>} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} 1121 * to use in conjunction with this caching strategy. 1122 * @param {Object} [options.fetchOptions] Values passed along to the 1123 * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) 1124 * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796) 1125 * `fetch()` requests made by this strategy. 1126 * @param {Object} [options.matchOptions] The 1127 * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions} 1128 * for any `cache.match()` or `cache.put()` calls made by this strategy. 1129 */ 1130 constructor(options = {}) { 1131 this.cacheName = cacheNames.getRuntimeName(options.cacheName); 1132 this.plugins = options.plugins || []; 1133 this.fetchOptions = options.fetchOptions; 1134 this.matchOptions = options.matchOptions; 1135 } 1136 /** 1137 * Perform a request strategy and returns a `Promise` that will resolve with 1138 * a `Response`, invoking all relevant plugin callbacks. 1139 * 1140 * When a strategy instance is registered with a Workbox 1141 * {@link workbox-routing.Route}, this method is automatically 1142 * called when the route matches. 1143 * 1144 * Alternatively, this method can be used in a standalone `FetchEvent` 1145 * listener by passing it to `event.respondWith()`. 1146 * 1147 * @param {FetchEvent|Object} options A `FetchEvent` or an object with the 1148 * properties listed below. 1149 * @param {Request|string} options.request A request to run this strategy for. 1150 * @param {ExtendableEvent} options.event The event associated with the 1151 * request. 1152 * @param {URL} [options.url] 1153 * @param {*} [options.params] 1154 */ 1155 handle(options) { 1156 const [responseDone] = this.handleAll(options); 1157 return responseDone; 1158 } 1159 /** 1160 * Similar to {@link workbox-strategies.Strategy~handle}, but 1161 * instead of just returning a `Promise` that resolves to a `Response` it 1162 * it will return an tuple of `[response, done]` promises, where the former 1163 * (`response`) is equivalent to what `handle()` returns, and the latter is a 1164 * Promise that will resolve once any promises that were added to 1165 * `event.waitUntil()` as part of performing the strategy have completed. 1166 * 1167 * You can await the `done` promise to ensure any extra work performed by 1168 * the strategy (usually caching responses) completes successfully. 1169 * 1170 * @param {FetchEvent|Object} options A `FetchEvent` or an object with the 1171 * properties listed below. 1172 * @param {Request|string} options.request A request to run this strategy for. 1173 * @param {ExtendableEvent} options.event The event associated with the 1174 * request. 1175 * @param {URL} [options.url] 1176 * @param {*} [options.params] 1177 * @return {Array<Promise>} A tuple of [response, done] 1178 * promises that can be used to determine when the response resolves as 1179 * well as when the handler has completed all its work. 1180 */ 1181 handleAll(options) { 1182 if (options instanceof FetchEvent) { 1183 options = { 1184 event: options, 1185 request: options.request 1186 }; 1187 } 1188 const event = options.event; 1189 const request = typeof options.request === "string" ? new Request(options.request) : options.request; 1190 const params = "params" in options ? options.params : void 0; 1191 const handler = new StrategyHandler(this, { event, request, params }); 1192 const responseDone = this._getResponse(handler, request, event); 1193 const handlerDone = this._awaitComplete(responseDone, handler, request, event); 1194 return [responseDone, handlerDone]; 1195 } 1196 async _getResponse(handler, request, event) { 1197 await handler.runCallbacks("handlerWillStart", { event, request }); 1198 let response = void 0; 1199 try { 1200 response = await this._handle(request, handler); 1201 if (!response || response.type === "error") { 1202 throw new WorkboxError("no-response", { url: request.url }); 1203 } 1204 } catch (error) { 1205 if (error instanceof Error) { 1206 for (const callback of handler.iterateCallbacks("handlerDidError")) { 1207 response = await callback({ error, event, request }); 1208 if (response) { 1209 break; 1210 } 1211 } 1212 } 1213 if (!response) { 1214 throw error; 1215 } else if (false) { 1216 logger.log(`While responding to '${getFriendlyURL(request.url)}', an ${error instanceof Error ? error.toString() : ""} error occurred. Using a fallback response provided by a handlerDidError plugin.`); 1217 } 1218 } 1219 for (const callback of handler.iterateCallbacks("handlerWillRespond")) { 1220 response = await callback({ event, request, response }); 1221 } 1222 return response; 1223 } 1224 async _awaitComplete(responseDone, handler, request, event) { 1225 let response; 1226 let error; 1227 try { 1228 response = await responseDone; 1229 } catch (error2) { 1230 } 1231 try { 1232 await handler.runCallbacks("handlerDidRespond", { 1233 event, 1234 request, 1235 response 1236 }); 1237 await handler.doneWaiting(); 1238 } catch (waitUntilError) { 1239 if (waitUntilError instanceof Error) { 1240 error = waitUntilError; 1241 } 1242 } 1243 await handler.runCallbacks("handlerDidComplete", { 1244 event, 1245 request, 1246 response, 1247 error 1248 }); 1249 handler.destroy(); 1250 if (error) { 1251 throw error; 1252 } 1253 } 1254 }; 1255 1256
vendor: 1,840 bytes, lines 1256-1315
1256// node_modules/workbox-strategies/CacheFirst.js 1257 var CacheFirst = class extends Strategy { 1258 /** 1259 * @private 1260 * @param {Request|string} request A request to run this strategy for. 1261 * @param {workbox-strategies.StrategyHandler} handler The event that 1262 * triggered the request. 1263 * @return {Promise<Response>} 1264 */ 1265 async _handle(request, handler) { 1266 const logs = []; 1267 if (false) { 1268 finalAssertExports.isInstance(request, Request, { 1269 moduleName: "workbox-strategies", 1270 className: this.constructor.name, 1271 funcName: "makeRequest", 1272 paramName: "request" 1273 }); 1274 } 1275 let response = await handler.cacheMatch(request); 1276 let error = void 0; 1277 if (!response) { 1278 if (false) { 1279 logs.push(`No response found in the '${this.cacheName}' cache. Will respond with a network request.`); 1280 } 1281 try { 1282 response = await handler.fetchAndCachePut(request); 1283 } catch (err) { 1284 if (err instanceof Error) { 1285 error = err; 1286 } 1287 } 1288 if (false) { 1289 if (response) { 1290 logs.push(`Got response from network.`); 1291 } else { 1292 logs.push(`Unable to get a response from the network.`); 1293 } 1294 } 1295 } else { 1296 if (false) { 1297 logs.push(`Found a cached response in the '${this.cacheName}' cache.`); 1298 } 1299 } 1300 if (false) { 1301 logger.groupCollapsed(messages2.strategyStart(this.constructor.name, request)); 1302 for (const log of logs) { 1303 logger.log(log); 1304 } 1305 messages2.printFinalResponse(response); 1306 logger.groupEnd(); 1307 } 1308 if (!response) { 1309 throw new WorkboxError("no-response", { url: request.url, error }); 1310 } 1311 return response; 1312 } 1313 }; 1314 1315
vendor: 526 bytes, lines 1315-1335
1315// node_modules/workbox-strategies/plugins/cacheOkAndOpaquePlugin.js 1316 var cacheOkAndOpaquePlugin = { 1317 /** 1318 * Returns a valid response (to allow caching) if the status is 200 (OK) or 1319 * 0 (opaque). 1320 * 1321 * @param {Object} options 1322 * @param {Response} options.response 1323 * @return {Response|null} 1324 * 1325 * @private 1326 */ 1327 cacheWillUpdate: async ({ response }) => { 1328 if (response.status === 200 || response.status === 0) { 1329 return response; 1330 } 1331 return null; 1332 } 1333 }; 1334 1335
vendor: 5,853 bytes, lines 1335-1494
1335// node_modules/workbox-strategies/NetworkFirst.js 1336 var NetworkFirst = class extends Strategy { 1337 /** 1338 * @param {Object} [options] 1339 * @param {string} [options.cacheName] Cache name to store and retrieve 1340 * requests. Defaults to cache names provided by 1341 * {@link workbox-core.cacheNames}. 1342 * @param {Array<Object>} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} 1343 * to use in conjunction with this caching strategy. 1344 * @param {Object} [options.fetchOptions] Values passed along to the 1345 * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) 1346 * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796) 1347 * `fetch()` requests made by this strategy. 1348 * @param {Object} [options.matchOptions] [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions) 1349 * @param {number} [options.networkTimeoutSeconds] If set, any network requests 1350 * that fail to respond within the timeout will fallback to the cache. 1351 * 1352 * This option can be used to combat 1353 * "[lie-fi]{@link https://developers.google.com/web/fundamentals/performance/poor-connectivity/#lie-fi}" 1354 * scenarios. 1355 */ 1356 constructor(options = {}) { 1357 super(options); 1358 if (!this.plugins.some((p) => "cacheWillUpdate" in p)) { 1359 this.plugins.unshift(cacheOkAndOpaquePlugin); 1360 } 1361 this._networkTimeoutSeconds = options.networkTimeoutSeconds || 0; 1362 if (false) { 1363 if (this._networkTimeoutSeconds) { 1364 finalAssertExports.isType(this._networkTimeoutSeconds, "number", { 1365 moduleName: "workbox-strategies", 1366 className: this.constructor.name, 1367 funcName: "constructor", 1368 paramName: "networkTimeoutSeconds" 1369 }); 1370 } 1371 } 1372 } 1373 /** 1374 * @private 1375 * @param {Request|string} request A request to run this strategy for. 1376 * @param {workbox-strategies.StrategyHandler} handler The event that 1377 * triggered the request. 1378 * @return {Promise<Response>} 1379 */ 1380 async _handle(request, handler) { 1381 const logs = []; 1382 if (false) { 1383 finalAssertExports.isInstance(request, Request, { 1384 moduleName: "workbox-strategies", 1385 className: this.constructor.name, 1386 funcName: "handle", 1387 paramName: "makeRequest" 1388 }); 1389 } 1390 const promises = []; 1391 let timeoutId; 1392 if (this._networkTimeoutSeconds) { 1393 const { id, promise } = this._getTimeoutPromise({ request, logs, handler }); 1394 timeoutId = id; 1395 promises.push(promise); 1396 } 1397 const networkPromise = this._getNetworkPromise({ 1398 timeoutId, 1399 request, 1400 logs, 1401 handler 1402 }); 1403 promises.push(networkPromise); 1404 const response = await handler.waitUntil((async () => { 1405 return await handler.waitUntil(Promise.race(promises)) || // If Promise.race() resolved with null, it might be due to a network 1406 // timeout + a cache miss. If that were to happen, we'd rather wait until 1407 // the networkPromise resolves instead of returning null. 1408 // Note that it's fine to await an already-resolved promise, so we don't 1409 // have to check to see if it's still "in flight". 1410 await networkPromise; 1411 })()); 1412 if (false) { 1413 logger.groupCollapsed(messages2.strategyStart(this.constructor.name, request)); 1414 for (const log of logs) { 1415 logger.log(log); 1416 } 1417 messages2.printFinalResponse(response); 1418 logger.groupEnd(); 1419 } 1420 if (!response) { 1421 throw new WorkboxError("no-response", { url: request.url }); 1422 } 1423 return response; 1424 } 1425 /** 1426 * @param {Object} options 1427 * @param {Request} options.request 1428 * @param {Array} options.logs A reference to the logs array 1429 * @param {Event} options.event 1430 * @return {Promise<Response>} 1431 * 1432 * @private 1433 */ 1434 _getTimeoutPromise({ request, logs, handler }) { 1435 let timeoutId; 1436 const timeoutPromise = new Promise((resolve) => { 1437 const onNetworkTimeout = async () => { 1438 if (false) { 1439 logs.push(`Timing out the network response at ${this._networkTimeoutSeconds} seconds.`); 1440 } 1441 resolve(await handler.cacheMatch(request)); 1442 }; 1443 timeoutId = setTimeout(onNetworkTimeout, this._networkTimeoutSeconds * 1e3); 1444 }); 1445 return { 1446 promise: timeoutPromise, 1447 id: timeoutId 1448 }; 1449 } 1450 /** 1451 * @param {Object} options 1452 * @param {number|undefined} options.timeoutId 1453 * @param {Request} options.request 1454 * @param {Array} options.logs A reference to the logs Array. 1455 * @param {Event} options.event 1456 * @return {Promise<Response>} 1457 * 1458 * @private 1459 */ 1460 async _getNetworkPromise({ timeoutId, request, logs, handler }) { 1461 let error; 1462 let response; 1463 try { 1464 response = await handler.fetchAndCachePut(request); 1465 } catch (fetchError) { 1466 if (fetchError instanceof Error) { 1467 error = fetchError; 1468 } 1469 } 1470 if (timeoutId) { 1471 clearTimeout(timeoutId); 1472 } 1473 if (false) { 1474 if (response) { 1475 logs.push(`Got response from network.`); 1476 } else { 1477 logs.push(`Unable to get a response from the network. Will respond with a cached response.`); 1478 } 1479 } 1480 if (error || !response) { 1481 response = await handler.cacheMatch(request); 1482 if (false) { 1483 if (response) { 1484 logs.push(`Found a cached response in the '${this.cacheName}' cache.`); 1485 } else { 1486 logs.push(`No response found in the '${this.cacheName}' cache.`); 1487 } 1488 } 1489 } 1490 return response; 1491 } 1492 }; 1493 1494
vendor: 2,860 bytes, lines 1494-1568
1494// node_modules/workbox-strategies/StaleWhileRevalidate.js 1495 var StaleWhileRevalidate = class extends Strategy { 1496 /** 1497 * @param {Object} [options] 1498 * @param {string} [options.cacheName] Cache name to store and retrieve 1499 * requests. Defaults to cache names provided by 1500 * {@link workbox-core.cacheNames}. 1501 * @param {Array<Object>} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} 1502 * to use in conjunction with this caching strategy. 1503 * @param {Object} [options.fetchOptions] Values passed along to the 1504 * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) 1505 * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796) 1506 * `fetch()` requests made by this strategy. 1507 * @param {Object} [options.matchOptions] [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions) 1508 */ 1509 constructor(options = {}) { 1510 super(options); 1511 if (!this.plugins.some((p) => "cacheWillUpdate" in p)) { 1512 this.plugins.unshift(cacheOkAndOpaquePlugin); 1513 } 1514 } 1515 /** 1516 * @private 1517 * @param {Request|string} request A request to run this strategy for. 1518 * @param {workbox-strategies.StrategyHandler} handler The event that 1519 * triggered the request. 1520 * @return {Promise<Response>} 1521 */ 1522 async _handle(request, handler) { 1523 const logs = []; 1524 if (false) { 1525 finalAssertExports.isInstance(request, Request, { 1526 moduleName: "workbox-strategies", 1527 className: this.constructor.name, 1528 funcName: "handle", 1529 paramName: "request" 1530 }); 1531 } 1532 const fetchAndCachePromise = handler.fetchAndCachePut(request).catch(() => { 1533 }); 1534 void handler.waitUntil(fetchAndCachePromise); 1535 let response = await handler.cacheMatch(request); 1536 let error; 1537 if (response) { 1538 if (false) { 1539 logs.push(`Found a cached response in the '${this.cacheName}' cache. Will update with the network response in the background.`); 1540 } 1541 } else { 1542 if (false) { 1543 logs.push(`No response found in the '${this.cacheName}' cache. Will wait for the network response.`); 1544 } 1545 try { 1546 response = await fetchAndCachePromise; 1547 } catch (err) { 1548 if (err instanceof Error) { 1549 error = err; 1550 } 1551 } 1552 } 1553 if (false) { 1554 logger.groupCollapsed(messages2.strategyStart(this.constructor.name, request)); 1555 for (const log of logs) { 1556 logger.log(log); 1557 } 1558 messages2.printFinalResponse(response); 1559 logger.groupEnd(); 1560 } 1561 if (!response) { 1562 throw new WorkboxError("no-response", { url: request.url, error }); 1563 } 1564 return response; 1565 } 1566 }; 1567 1568
vendor: 132 bytes, lines 1568-1574
1568// node_modules/workbox-core/_private/dontWaitFor.js 1569 function dontWaitFor(promise) { 1570 void promise.then(() => { 1571 }); 1572 } 1573 1574
vendor: 4,739 bytes, lines 1574-1717
1574// node_modules/workbox-expiration/node_modules/idb/build/wrap-idb-value.js 1575 var instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c); 1576 var idbProxyableTypes; 1577 var cursorAdvanceMethods; 1578 function getIdbProxyableTypes() { 1579 return idbProxyableTypes || (idbProxyableTypes = [ 1580 IDBDatabase, 1581 IDBObjectStore, 1582 IDBIndex, 1583 IDBCursor, 1584 IDBTransaction 1585 ]); 1586 } 1587 function getCursorAdvanceMethods() { 1588 return cursorAdvanceMethods || (cursorAdvanceMethods = [ 1589 IDBCursor.prototype.advance, 1590 IDBCursor.prototype.continue, 1591 IDBCursor.prototype.continuePrimaryKey 1592 ]); 1593 } 1594 var cursorRequestMap = /* @__PURE__ */ new WeakMap(); 1595 var transactionDoneMap = /* @__PURE__ */ new WeakMap(); 1596 var transactionStoreNamesMap = /* @__PURE__ */ new WeakMap(); 1597 var transformCache = /* @__PURE__ */ new WeakMap(); 1598 var reverseTransformCache = /* @__PURE__ */ new WeakMap(); 1599 function promisifyRequest(request) { 1600 const promise = new Promise((resolve, reject) => { 1601 const unlisten = () => { 1602 request.removeEventListener("success", success); 1603 request.removeEventListener("error", error); 1604 }; 1605 const success = () => { 1606 resolve(wrap(request.result)); 1607 unlisten(); 1608 }; 1609 const error = () => { 1610 reject(request.error); 1611 unlisten(); 1612 }; 1613 request.addEventListener("success", success); 1614 request.addEventListener("error", error); 1615 }); 1616 promise.then((value) => { 1617 if (value instanceof IDBCursor) { 1618 cursorRequestMap.set(value, request); 1619 } 1620 }).catch(() => { 1621 }); 1622 reverseTransformCache.set(promise, request); 1623 return promise; 1624 } 1625 function cacheDonePromiseForTransaction(tx) { 1626 if (transactionDoneMap.has(tx)) 1627 return; 1628 const done = new Promise((resolve, reject) => { 1629 const unlisten = () => { 1630 tx.removeEventListener("complete", complete); 1631 tx.removeEventListener("error", error); 1632 tx.removeEventListener("abort", error); 1633 }; 1634 const complete = () => { 1635 resolve(); 1636 unlisten(); 1637 }; 1638 const error = () => { 1639 reject(tx.error || new DOMException("AbortError", "AbortError")); 1640 unlisten(); 1641 }; 1642 tx.addEventListener("complete", complete); 1643 tx.addEventListener("error", error); 1644 tx.addEventListener("abort", error); 1645 }); 1646 transactionDoneMap.set(tx, done); 1647 } 1648 var idbProxyTraps = { 1649 get(target, prop, receiver) { 1650 if (target instanceof IDBTransaction) { 1651 if (prop === "done") 1652 return transactionDoneMap.get(target); 1653 if (prop === "objectStoreNames") { 1654 return target.objectStoreNames || transactionStoreNamesMap.get(target); 1655 } 1656 if (prop === "store") { 1657 return receiver.objectStoreNames[1] ? void 0 : receiver.objectStore(receiver.objectStoreNames[0]); 1658 } 1659 } 1660 return wrap(target[prop]); 1661 }, 1662 set(target, prop, value) { 1663 target[prop] = value; 1664 return true; 1665 }, 1666 has(target, prop) { 1667 if (target instanceof IDBTransaction && (prop === "done" || prop === "store")) { 1668 return true; 1669 } 1670 return prop in target; 1671 } 1672 }; 1673 function replaceTraps(callback) { 1674 idbProxyTraps = callback(idbProxyTraps); 1675 } 1676 function wrapFunction(func) { 1677 if (func === IDBDatabase.prototype.transaction && !("objectStoreNames" in IDBTransaction.prototype)) { 1678 return function(storeNames, ...args) { 1679 const tx = func.call(unwrap(this), storeNames, ...args); 1680 transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]); 1681 return wrap(tx); 1682 }; 1683 } 1684 if (getCursorAdvanceMethods().includes(func)) { 1685 return function(...args) { 1686 func.apply(unwrap(this), args); 1687 return wrap(cursorRequestMap.get(this)); 1688 }; 1689 } 1690 return function(...args) { 1691 return wrap(func.apply(unwrap(this), args)); 1692 }; 1693 } 1694 function transformCachableValue(value) { 1695 if (typeof value === "function") 1696 return wrapFunction(value); 1697 if (value instanceof IDBTransaction) 1698 cacheDonePromiseForTransaction(value); 1699 if (instanceOfAny(value, getIdbProxyableTypes())) 1700 return new Proxy(value, idbProxyTraps); 1701 return value; 1702 } 1703 function wrap(value) { 1704 if (value instanceof IDBRequest) 1705 return promisifyRequest(value); 1706 if (transformCache.has(value)) 1707 return transformCache.get(value); 1708 const newValue = transformCachableValue(value); 1709 if (newValue !== value) { 1710 transformCache.set(value, newValue); 1711 reverseTransformCache.set(newValue, value); 1712 } 1713 return newValue; 1714 } 1715 var unwrap = (value) => reverseTransformCache.get(value); 1716 1717
vendor: 2,864 bytes, lines 1717-1792
1717// node_modules/workbox-expiration/node_modules/idb/build/index.js 1718 function openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) { 1719 const request = indexedDB.open(name, version); 1720 const openPromise = wrap(request); 1721 if (upgrade) { 1722 request.addEventListener("upgradeneeded", (event) => { 1723 upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event); 1724 }); 1725 } 1726 if (blocked) { 1727 request.addEventListener("blocked", (event) => blocked( 1728 // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405 1729 event.oldVersion, 1730 event.newVersion, 1731 event 1732 )); 1733 } 1734 openPromise.then((db) => { 1735 if (terminated) 1736 db.addEventListener("close", () => terminated()); 1737 if (blocking) { 1738 db.addEventListener("versionchange", (event) => blocking(event.oldVersion, event.newVersion, event)); 1739 } 1740 }).catch(() => { 1741 }); 1742 return openPromise; 1743 } 1744 function deleteDB(name, { blocked } = {}) { 1745 const request = indexedDB.deleteDatabase(name); 1746 if (blocked) { 1747 request.addEventListener("blocked", (event) => blocked( 1748 // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405 1749 event.oldVersion, 1750 event 1751 )); 1752 } 1753 return wrap(request).then(() => void 0); 1754 } 1755 var readMethods = ["get", "getKey", "getAll", "getAllKeys", "count"]; 1756 var writeMethods = ["put", "add", "delete", "clear"]; 1757 var cachedMethods = /* @__PURE__ */ new Map(); 1758 function getMethod(target, prop) { 1759 if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === "string")) { 1760 return; 1761 } 1762 if (cachedMethods.get(prop)) 1763 return cachedMethods.get(prop); 1764 const targetFuncName = prop.replace(/FromIndex$/, ""); 1765 const useIndex = prop !== targetFuncName; 1766 const isWrite = writeMethods.includes(targetFuncName); 1767 if ( 1768 // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge. 1769 !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName)) 1770 ) { 1771 return; 1772 } 1773 const method = async function(storeName, ...args) { 1774 const tx = this.transaction(storeName, isWrite ? "readwrite" : "readonly"); 1775 let target2 = tx.store; 1776 if (useIndex) 1777 target2 = target2.index(args.shift()); 1778 return (await Promise.all([ 1779 target2[targetFuncName](...args), 1780 isWrite && tx.done 1781 ]))[0]; 1782 }; 1783 cachedMethods.set(prop, method); 1784 return method; 1785 } 1786 replaceTraps((oldTraps) => ({ 1787 ...oldTraps, 1788 get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver), 1789 has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop) 1790 })); 1791 1792
vendor: 123 bytes, lines 1792-1798
1792// node_modules/workbox-expiration/_version.js 1793 try { 1794 self["workbox:expiration:7.3.0"] && _(); 1795 } catch (e) { 1796 } 1797 1798
vendor: 4,051 bytes, lines 1798-1939
1798// node_modules/workbox-expiration/models/CacheTimestampsModel.js 1799 var DB_NAME = "workbox-expiration"; 1800 var CACHE_OBJECT_STORE = "cache-entries"; 1801 var normalizeURL = (unNormalizedUrl) => { 1802 const url = new URL(unNormalizedUrl, location.href); 1803 url.hash = ""; 1804 return url.href; 1805 }; 1806 var CacheTimestampsModel = class { 1807 /** 1808 * 1809 * @param {string} cacheName 1810 * 1811 * @private 1812 */ 1813 constructor(cacheName) { 1814 this._db = null; 1815 this._cacheName = cacheName; 1816 } 1817 /** 1818 * Performs an upgrade of indexedDB. 1819 * 1820 * @param {IDBPDatabase<CacheDbSchema>} db 1821 * 1822 * @private 1823 */ 1824 _upgradeDb(db) { 1825 const objStore = db.createObjectStore(CACHE_OBJECT_STORE, { keyPath: "id" }); 1826 objStore.createIndex("cacheName", "cacheName", { unique: false }); 1827 objStore.createIndex("timestamp", "timestamp", { unique: false }); 1828 } 1829 /** 1830 * Performs an upgrade of indexedDB and deletes deprecated DBs. 1831 * 1832 * @param {IDBPDatabase<CacheDbSchema>} db 1833 * 1834 * @private 1835 */ 1836 _upgradeDbAndDeleteOldDbs(db) { 1837 this._upgradeDb(db); 1838 if (this._cacheName) { 1839 void deleteDB(this._cacheName); 1840 } 1841 } 1842 /** 1843 * @param {string} url 1844 * @param {number} timestamp 1845 * 1846 * @private 1847 */ 1848 async setTimestamp(url, timestamp) { 1849 url = normalizeURL(url); 1850 const entry = { 1851 url, 1852 timestamp, 1853 cacheName: this._cacheName, 1854 // Creating an ID from the URL and cache name won't be necessary once 1855 // Edge switches to Chromium and all browsers we support work with 1856 // array keyPaths. 1857 id: this._getId(url) 1858 }; 1859 const db = await this.getDb(); 1860 const tx = db.transaction(CACHE_OBJECT_STORE, "readwrite", { 1861 durability: "relaxed" 1862 }); 1863 await tx.store.put(entry); 1864 await tx.done; 1865 } 1866 /** 1867 * Returns the timestamp stored for a given URL. 1868 * 1869 * @param {string} url 1870 * @return {number | undefined} 1871 * 1872 * @private 1873 */ 1874 async getTimestamp(url) { 1875 const db = await this.getDb(); 1876 const entry = await db.get(CACHE_OBJECT_STORE, this._getId(url)); 1877 return entry === null || entry === void 0 ? void 0 : entry.timestamp; 1878 } 1879 /** 1880 * Iterates through all the entries in the object store (from newest to 1881 * oldest) and removes entries once either `maxCount` is reached or the 1882 * entry's timestamp is less than `minTimestamp`. 1883 * 1884 * @param {number} minTimestamp 1885 * @param {number} maxCount 1886 * @return {Array<string>} 1887 * 1888 * @private 1889 */ 1890 async expireEntries(minTimestamp, maxCount) { 1891 const db = await this.getDb(); 1892 let cursor = await db.transaction(CACHE_OBJECT_STORE).store.index("timestamp").openCursor(null, "prev"); 1893 const entriesToDelete = []; 1894 let entriesNotDeletedCount = 0; 1895 while (cursor) { 1896 const result = cursor.value; 1897 if (result.cacheName === this._cacheName) { 1898 if (minTimestamp && result.timestamp < minTimestamp || maxCount && entriesNotDeletedCount >= maxCount) { 1899 entriesToDelete.push(cursor.value); 1900 } else { 1901 entriesNotDeletedCount++; 1902 } 1903 } 1904 cursor = await cursor.continue(); 1905 } 1906 const urlsDeleted = []; 1907 for (const entry of entriesToDelete) { 1908 await db.delete(CACHE_OBJECT_STORE, entry.id); 1909 urlsDeleted.push(entry.url); 1910 } 1911 return urlsDeleted; 1912 } 1913 /** 1914 * Takes a URL and returns an ID that will be unique in the object store. 1915 * 1916 * @param {string} url 1917 * @return {string} 1918 * 1919 * @private 1920 */ 1921 _getId(url) { 1922 return this._cacheName + "|" + normalizeURL(url); 1923 } 1924 /** 1925 * Returns an open connection to the database. 1926 * 1927 * @private 1928 */ 1929 async getDb() { 1930 if (!this._db) { 1931 this._db = await openDB(DB_NAME, 1, { 1932 upgrade: this._upgradeDbAndDeleteOldDbs.bind(this) 1933 }); 1934 } 1935 return this._db; 1936 } 1937 }; 1938 1939
vendor: 5,320 bytes, lines 1939-2079
1939// node_modules/workbox-expiration/CacheExpiration.js 1940 var CacheExpiration = class { 1941 /** 1942 * To construct a new CacheExpiration instance you must provide at least 1943 * one of the `config` properties. 1944 * 1945 * @param {string} cacheName Name of the cache to apply restrictions to. 1946 * @param {Object} config 1947 * @param {number} [config.maxEntries] The maximum number of entries to cache. 1948 * Entries used the least will be removed as the maximum is reached. 1949 * @param {number} [config.maxAgeSeconds] The maximum age of an entry before 1950 * it's treated as stale and removed. 1951 * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters) 1952 * that will be used when calling `delete()` on the cache. 1953 */ 1954 constructor(cacheName, config = {}) { 1955 this._isRunning = false; 1956 this._rerunRequested = false; 1957 if (false) { 1958 finalAssertExports.isType(cacheName, "string", { 1959 moduleName: "workbox-expiration", 1960 className: "CacheExpiration", 1961 funcName: "constructor", 1962 paramName: "cacheName" 1963 }); 1964 if (!(config.maxEntries || config.maxAgeSeconds)) { 1965 throw new WorkboxError("max-entries-or-age-required", { 1966 moduleName: "workbox-expiration", 1967 className: "CacheExpiration", 1968 funcName: "constructor" 1969 }); 1970 } 1971 if (config.maxEntries) { 1972 finalAssertExports.isType(config.maxEntries, "number", { 1973 moduleName: "workbox-expiration", 1974 className: "CacheExpiration", 1975 funcName: "constructor", 1976 paramName: "config.maxEntries" 1977 }); 1978 } 1979 if (config.maxAgeSeconds) { 1980 finalAssertExports.isType(config.maxAgeSeconds, "number", { 1981 moduleName: "workbox-expiration", 1982 className: "CacheExpiration", 1983 funcName: "constructor", 1984 paramName: "config.maxAgeSeconds" 1985 }); 1986 } 1987 } 1988 this._maxEntries = config.maxEntries; 1989 this._maxAgeSeconds = config.maxAgeSeconds; 1990 this._matchOptions = config.matchOptions; 1991 this._cacheName = cacheName; 1992 this._timestampModel = new CacheTimestampsModel(cacheName); 1993 } 1994 /** 1995 * Expires entries for the given cache and given criteria. 1996 */ 1997 async expireEntries() { 1998 if (this._isRunning) { 1999 this._rerunRequested = true; 2000 return; 2001 } 2002 this._isRunning = true; 2003 const minTimestamp = this._maxAgeSeconds ? Date.now() - this._maxAgeSeconds * 1e3 : 0; 2004 const urlsExpired = await this._timestampModel.expireEntries(minTimestamp, this._maxEntries); 2005 const cache = await self.caches.open(this._cacheName); 2006 for (const url of urlsExpired) { 2007 await cache.delete(url, this._matchOptions); 2008 } 2009 if (false) { 2010 if (urlsExpired.length > 0) { 2011 logger.groupCollapsed(`Expired ${urlsExpired.length} ${urlsExpired.length === 1 ? "entry" : "entries"} and removed ${urlsExpired.length === 1 ? "it" : "them"} from the '${this._cacheName}' cache.`); 2012 logger.log(`Expired the following ${urlsExpired.length === 1 ? "URL" : "URLs"}:`); 2013 urlsExpired.forEach((url) => logger.log(` ${url}`)); 2014 logger.groupEnd(); 2015 } else { 2016 logger.debug(`Cache expiration ran and found no entries to remove.`); 2017 } 2018 } 2019 this._isRunning = false; 2020 if (this._rerunRequested) { 2021 this._rerunRequested = false; 2022 dontWaitFor(this.expireEntries()); 2023 } 2024 } 2025 /** 2026 * Update the timestamp for the given URL. This ensures the when 2027 * removing entries based on maximum entries, most recently used 2028 * is accurate or when expiring, the timestamp is up-to-date. 2029 * 2030 * @param {string} url 2031 */ 2032 async updateTimestamp(url) { 2033 if (false) { 2034 finalAssertExports.isType(url, "string", { 2035 moduleName: "workbox-expiration", 2036 className: "CacheExpiration", 2037 funcName: "updateTimestamp", 2038 paramName: "url" 2039 }); 2040 } 2041 await this._timestampModel.setTimestamp(url, Date.now()); 2042 } 2043 /** 2044 * Can be used to check if a URL has expired or not before it's used. 2045 * 2046 * This requires a look up from IndexedDB, so can be slow. 2047 * 2048 * Note: This method will not remove the cached entry, call 2049 * `expireEntries()` to remove indexedDB and Cache entries. 2050 * 2051 * @param {string} url 2052 * @return {boolean} 2053 */ 2054 async isURLExpired(url) { 2055 if (!this._maxAgeSeconds) { 2056 if (false) { 2057 throw new WorkboxError(`expired-test-without-max-age`, { 2058 methodName: "isURLExpired", 2059 paramName: "maxAgeSeconds" 2060 }); 2061 } 2062 return false; 2063 } else { 2064 const timestamp = await this._timestampModel.getTimestamp(url); 2065 const expireOlderThan = Date.now() - this._maxAgeSeconds * 1e3; 2066 return timestamp !== void 0 ? timestamp < expireOlderThan : true; 2067 } 2068 } 2069 /** 2070 * Removes the IndexedDB object store used to keep track of cache expiration 2071 * metadata. 2072 */ 2073 async delete() { 2074 this._rerunRequested = false; 2075 await this._timestampModel.expireEntries(Infinity); 2076 } 2077 }; 2078 2079
vendor: 444 bytes, lines 2079-2094
2079// node_modules/workbox-core/registerQuotaErrorCallback.js 2080 function registerQuotaErrorCallback(callback) { 2081 if (false) { 2082 finalAssertExports.isType(callback, "function", { 2083 moduleName: "workbox-core", 2084 funcName: "register", 2085 paramName: "callback" 2086 }); 2087 } 2088 quotaErrorCallbacks.add(callback); 2089 if (false) { 2090 logger.log("Registered a callback to respond to quota errors.", callback); 2091 } 2092 } 2093 2094
vendor: 6,359 bytes, lines 2094-2263
2094// node_modules/workbox-expiration/ExpirationPlugin.js 2095 var ExpirationPlugin = class { 2096 /** 2097 * @param {ExpirationPluginOptions} config 2098 * @param {number} [config.maxEntries] The maximum number of entries to cache. 2099 * Entries used the least will be removed as the maximum is reached. 2100 * @param {number} [config.maxAgeSeconds] The maximum age of an entry before 2101 * it's treated as stale and removed. 2102 * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters) 2103 * that will be used when calling `delete()` on the cache. 2104 * @param {boolean} [config.purgeOnQuotaError] Whether to opt this cache in to 2105 * automatic deletion if the available storage quota has been exceeded. 2106 */ 2107 constructor(config = {}) { 2108 this.cachedResponseWillBeUsed = async ({ event, request, cacheName, cachedResponse }) => { 2109 if (!cachedResponse) { 2110 return null; 2111 } 2112 const isFresh = this._isResponseDateFresh(cachedResponse); 2113 const cacheExpiration = this._getCacheExpiration(cacheName); 2114 dontWaitFor(cacheExpiration.expireEntries()); 2115 const updateTimestampDone = cacheExpiration.updateTimestamp(request.url); 2116 if (event) { 2117 try { 2118 event.waitUntil(updateTimestampDone); 2119 } catch (error) { 2120 if (false) { 2121 if ("request" in event) { 2122 logger.warn(`Unable to ensure service worker stays alive when updating cache entry for '${getFriendlyURL(event.request.url)}'.`); 2123 } 2124 } 2125 } 2126 } 2127 return isFresh ? cachedResponse : null; 2128 }; 2129 this.cacheDidUpdate = async ({ cacheName, request }) => { 2130 if (false) { 2131 finalAssertExports.isType(cacheName, "string", { 2132 moduleName: "workbox-expiration", 2133 className: "Plugin", 2134 funcName: "cacheDidUpdate", 2135 paramName: "cacheName" 2136 }); 2137 finalAssertExports.isInstance(request, Request, { 2138 moduleName: "workbox-expiration", 2139 className: "Plugin", 2140 funcName: "cacheDidUpdate", 2141 paramName: "request" 2142 }); 2143 } 2144 const cacheExpiration = this._getCacheExpiration(cacheName); 2145 await cacheExpiration.updateTimestamp(request.url); 2146 await cacheExpiration.expireEntries(); 2147 }; 2148 if (false) { 2149 if (!(config.maxEntries || config.maxAgeSeconds)) { 2150 throw new WorkboxError("max-entries-or-age-required", { 2151 moduleName: "workbox-expiration", 2152 className: "Plugin", 2153 funcName: "constructor" 2154 }); 2155 } 2156 if (config.maxEntries) { 2157 finalAssertExports.isType(config.maxEntries, "number", { 2158 moduleName: "workbox-expiration", 2159 className: "Plugin", 2160 funcName: "constructor", 2161 paramName: "config.maxEntries" 2162 }); 2163 } 2164 if (config.maxAgeSeconds) { 2165 finalAssertExports.isType(config.maxAgeSeconds, "number", { 2166 moduleName: "workbox-expiration", 2167 className: "Plugin", 2168 funcName: "constructor", 2169 paramName: "config.maxAgeSeconds" 2170 }); 2171 } 2172 } 2173 this._config = config; 2174 this._maxAgeSeconds = config.maxAgeSeconds; 2175 this._cacheExpirations = /* @__PURE__ */ new Map(); 2176 if (config.purgeOnQuotaError) { 2177 registerQuotaErrorCallback(() => this.deleteCacheAndMetadata()); 2178 } 2179 } 2180 /** 2181 * A simple helper method to return a CacheExpiration instance for a given 2182 * cache name. 2183 * 2184 * @param {string} cacheName 2185 * @return {CacheExpiration} 2186 * 2187 * @private 2188 */ 2189 _getCacheExpiration(cacheName) { 2190 if (cacheName === cacheNames.getRuntimeName()) { 2191 throw new WorkboxError("expire-custom-caches-only"); 2192 } 2193 let cacheExpiration = this._cacheExpirations.get(cacheName); 2194 if (!cacheExpiration) { 2195 cacheExpiration = new CacheExpiration(cacheName, this._config); 2196 this._cacheExpirations.set(cacheName, cacheExpiration); 2197 } 2198 return cacheExpiration; 2199 } 2200 /** 2201 * @param {Response} cachedResponse 2202 * @return {boolean} 2203 * 2204 * @private 2205 */ 2206 _isResponseDateFresh(cachedResponse) { 2207 if (!this._maxAgeSeconds) { 2208 return true; 2209 } 2210 const dateHeaderTimestamp = this._getDateHeaderTimestamp(cachedResponse); 2211 if (dateHeaderTimestamp === null) { 2212 return true; 2213 } 2214 const now = Date.now(); 2215 return dateHeaderTimestamp >= now - this._maxAgeSeconds * 1e3; 2216 } 2217 /** 2218 * This method will extract the data header and parse it into a useful 2219 * value. 2220 * 2221 * @param {Response} cachedResponse 2222 * @return {number|null} 2223 * 2224 * @private 2225 */ 2226 _getDateHeaderTimestamp(cachedResponse) { 2227 if (!cachedResponse.headers.has("date")) { 2228 return null; 2229 } 2230 const dateHeader = cachedResponse.headers.get("date"); 2231 const parsedDate = new Date(dateHeader); 2232 const headerTime = parsedDate.getTime(); 2233 if (isNaN(headerTime)) { 2234 return null; 2235 } 2236 return headerTime; 2237 } 2238 /** 2239 * This is a helper method that performs two operations: 2240 * 2241 * - Deletes *all* the underlying Cache instances associated with this plugin 2242 * instance, by calling caches.delete() on your behalf. 2243 * - Deletes the metadata from IndexedDB used to keep track of expiration 2244 * details for each Cache instance. 2245 * 2246 * When using cache expiration, calling this method is preferable to calling 2247 * `caches.delete()` directly, since this will ensure that the IndexedDB 2248 * metadata is also cleanly removed and open IndexedDB instances are deleted. 2249 * 2250 * Note that if you're *not* using cache expiration for a given cache, calling 2251 * `caches.delete()` and passing in the cache's name should be sufficient. 2252 * There is no Workbox-specific method needed for cleanup in that case. 2253 */ 2254 async deleteCacheAndMetadata() { 2255 for (const [cacheName, cacheExpiration] of this._cacheExpirations) { 2256 await self.caches.delete(cacheName); 2257 await cacheExpiration.delete(); 2258 } 2259 this._cacheExpirations = /* @__PURE__ */ new Map(); 2260 } 2261 }; 2262 2263
vendor: 139 bytes, lines 2263-2269
2263// node_modules/workbox-cacheable-response/_version.js 2264 try { 2265 self["workbox:cacheable-response:7.3.0"] && _(); 2266 } catch (e) { 2267 } 2268 2269
vendor: 3,872 bytes, lines 2269-2367
2269// node_modules/workbox-cacheable-response/CacheableResponse.js 2270 var CacheableResponse = class { 2271 /** 2272 * To construct a new CacheableResponse instance you must provide at least 2273 * one of the `config` properties. 2274 * 2275 * If both `statuses` and `headers` are specified, then both conditions must 2276 * be met for the `Response` to be considered cacheable. 2277 * 2278 * @param {Object} config 2279 * @param {Array<number>} [config.statuses] One or more status codes that a 2280 * `Response` can have and be considered cacheable. 2281 * @param {Object<string,string>} [config.headers] A mapping of header names 2282 * and expected values that a `Response` can have and be considered cacheable. 2283 * If multiple headers are provided, only one needs to be present. 2284 */ 2285 constructor(config = {}) { 2286 if (false) { 2287 if (!(config.statuses || config.headers)) { 2288 throw new WorkboxError("statuses-or-headers-required", { 2289 moduleName: "workbox-cacheable-response", 2290 className: "CacheableResponse", 2291 funcName: "constructor" 2292 }); 2293 } 2294 if (config.statuses) { 2295 finalAssertExports.isArray(config.statuses, { 2296 moduleName: "workbox-cacheable-response", 2297 className: "CacheableResponse", 2298 funcName: "constructor", 2299 paramName: "config.statuses" 2300 }); 2301 } 2302 if (config.headers) { 2303 finalAssertExports.isType(config.headers, "object", { 2304 moduleName: "workbox-cacheable-response", 2305 className: "CacheableResponse", 2306 funcName: "constructor", 2307 paramName: "config.headers" 2308 }); 2309 } 2310 } 2311 this._statuses = config.statuses; 2312 this._headers = config.headers; 2313 } 2314 /** 2315 * Checks a response to see whether it's cacheable or not, based on this 2316 * object's configuration. 2317 * 2318 * @param {Response} response The response whose cacheability is being 2319 * checked. 2320 * @return {boolean} `true` if the `Response` is cacheable, and `false` 2321 * otherwise. 2322 */ 2323 isResponseCacheable(response) { 2324 if (false) { 2325 finalAssertExports.isInstance(response, Response, { 2326 moduleName: "workbox-cacheable-response", 2327 className: "CacheableResponse", 2328 funcName: "isResponseCacheable", 2329 paramName: "response" 2330 }); 2331 } 2332 let cacheable = true; 2333 if (this._statuses) { 2334 cacheable = this._statuses.includes(response.status); 2335 } 2336 if (this._headers && cacheable) { 2337 cacheable = Object.keys(this._headers).some((headerName) => { 2338 return response.headers.get(headerName) === this._headers[headerName]; 2339 }); 2340 } 2341 if (false) { 2342 if (!cacheable) { 2343 logger.groupCollapsed(`The request for '${getFriendlyURL(response.url)}' returned a response that does not meet the criteria for being cached.`); 2344 logger.groupCollapsed(`View cacheability criteria here.`); 2345 logger.log(`Cacheable statuses: ` + JSON.stringify(this._statuses)); 2346 logger.log(`Cacheable headers: ` + JSON.stringify(this._headers, null, 2)); 2347 logger.groupEnd(); 2348 const logFriendlyHeaders = {}; 2349 response.headers.forEach((value, key) => { 2350 logFriendlyHeaders[key] = value; 2351 }); 2352 logger.groupCollapsed(`View response status and headers here.`); 2353 logger.log(`Response status: ${response.status}`); 2354 logger.log(`Response headers: ` + JSON.stringify(logFriendlyHeaders, null, 2)); 2355 logger.groupEnd(); 2356 logger.groupCollapsed(`View full response details here.`); 2357 logger.log(response.headers); 2358 logger.log(response); 2359 logger.groupEnd(); 2360 logger.groupEnd(); 2361 } 2362 } 2363 return cacheable; 2364 } 2365 }; 2366 2367
vendor: 1,101 bytes, lines 2367-2394
2367// node_modules/workbox-cacheable-response/CacheableResponsePlugin.js 2368 var CacheableResponsePlugin = class { 2369 /** 2370 * To construct a new CacheableResponsePlugin instance you must provide at 2371 * least one of the `config` properties. 2372 * 2373 * If both `statuses` and `headers` are specified, then both conditions must 2374 * be met for the `Response` to be considered cacheable. 2375 * 2376 * @param {Object} config 2377 * @param {Array<number>} [config.statuses] One or more status codes that a 2378 * `Response` can have and be considered cacheable. 2379 * @param {Object<string,string>} [config.headers] A mapping of header names 2380 * and expected values that a `Response` can have and be considered cacheable. 2381 * If multiple headers are provided, only one needs to be present. 2382 */ 2383 constructor(config) { 2384 this.cacheWillUpdate = async ({ response }) => { 2385 if (this._cacheableResponse.isResponseCacheable(response)) { 2386 return response; 2387 } 2388 return null; 2389 }; 2390 this._cacheableResponse = new CacheableResponse(config); 2391 } 2392 }; 2393 2394
vendor: 123 bytes, lines 2394-2400
2394// node_modules/workbox-precaching/_version.js 2395 try { 2396 self["workbox:precaching:7.3.0"] && _(); 2397 } catch (e) { 2398 } 2399 2400
vendor: 498 bytes, lines 2400-2418
2400// node_modules/workbox-core/_private/canConstructResponseFromBodyStream.js 2401 var supportStatus; 2402 function canConstructResponseFromBodyStream() { 2403 if (supportStatus === void 0) { 2404 const testResponse = new Response(""); 2405 if ("body" in testResponse) { 2406 try { 2407 new Response(testResponse.body); 2408 supportStatus = true; 2409 } catch (error) { 2410 supportStatus = false; 2411 } 2412 } 2413 supportStatus = false; 2414 } 2415 return supportStatus; 2416 } 2417 2418
vendor: 817 bytes, lines 2418-2439
2418// node_modules/workbox-core/copyResponse.js 2419 async function copyResponse(response, modifier) { 2420 let origin = null; 2421 if (response.url) { 2422 const responseURL = new URL(response.url); 2423 origin = responseURL.origin; 2424 } 2425 if (origin !== self.location.origin) { 2426 throw new WorkboxError("cross-origin-copy-response", { origin }); 2427 } 2428 const clonedResponse = response.clone(); 2429 const responseInit = { 2430 headers: new Headers(clonedResponse.headers), 2431 status: clonedResponse.status, 2432 statusText: clonedResponse.statusText 2433 }; 2434 const modifiedResponseInit = modifier ? modifier(responseInit) : responseInit; 2435 const body = canConstructResponseFromBodyStream() ? clonedResponse.body : await clonedResponse.blob(); 2436 return new Response(body, modifiedResponseInit); 2437 } 2438 2439
vendor: 6,962 bytes, lines 2439-2597
2439// node_modules/workbox-precaching/PrecacheStrategy.js 2440 var PrecacheStrategy = class _PrecacheStrategy extends Strategy { 2441 /** 2442 * 2443 * @param {Object} [options] 2444 * @param {string} [options.cacheName] Cache name to store and retrieve 2445 * requests. Defaults to the cache names provided by 2446 * {@link workbox-core.cacheNames}. 2447 * @param {Array<Object>} [options.plugins] {@link https://developers.google.com/web/tools/workbox/guides/using-plugins|Plugins} 2448 * to use in conjunction with this caching strategy. 2449 * @param {Object} [options.fetchOptions] Values passed along to the 2450 * {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters|init} 2451 * of all fetch() requests made by this strategy. 2452 * @param {Object} [options.matchOptions] The 2453 * {@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions|CacheQueryOptions} 2454 * for any `cache.match()` or `cache.put()` calls made by this strategy. 2455 * @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to 2456 * get the response from the network if there's a precache miss. 2457 */ 2458 constructor(options = {}) { 2459 options.cacheName = cacheNames.getPrecacheName(options.cacheName); 2460 super(options); 2461 this._fallbackToNetwork = options.fallbackToNetwork === false ? false : true; 2462 this.plugins.push(_PrecacheStrategy.copyRedirectedCacheableResponsesPlugin); 2463 } 2464 /** 2465 * @private 2466 * @param {Request|string} request A request to run this strategy for. 2467 * @param {workbox-strategies.StrategyHandler} handler The event that 2468 * triggered the request. 2469 * @return {Promise<Response>} 2470 */ 2471 async _handle(request, handler) { 2472 const response = await handler.cacheMatch(request); 2473 if (response) { 2474 return response; 2475 } 2476 if (handler.event && handler.event.type === "install") { 2477 return await this._handleInstall(request, handler); 2478 } 2479 return await this._handleFetch(request, handler); 2480 } 2481 async _handleFetch(request, handler) { 2482 let response; 2483 const params = handler.params || {}; 2484 if (this._fallbackToNetwork) { 2485 if (false) { 2486 logger.warn(`The precached response for ${getFriendlyURL(request.url)} in ${this.cacheName} was not found. Falling back to the network.`); 2487 } 2488 const integrityInManifest = params.integrity; 2489 const integrityInRequest = request.integrity; 2490 const noIntegrityConflict = !integrityInRequest || integrityInRequest === integrityInManifest; 2491 response = await handler.fetch(new Request(request, { 2492 integrity: request.mode !== "no-cors" ? integrityInRequest || integrityInManifest : void 0 2493 })); 2494 if (integrityInManifest && noIntegrityConflict && request.mode !== "no-cors") { 2495 this._useDefaultCacheabilityPluginIfNeeded(); 2496 const wasCached = await handler.cachePut(request, response.clone()); 2497 if (false) { 2498 if (wasCached) { 2499 logger.log(`A response for ${getFriendlyURL(request.url)} was used to "repair" the precache.`); 2500 } 2501 } 2502 } 2503 } else { 2504 throw new WorkboxError("missing-precache-entry", { 2505 cacheName: this.cacheName, 2506 url: request.url 2507 }); 2508 } 2509 if (false) { 2510 const cacheKey = params.cacheKey || await handler.getCacheKey(request, "read"); 2511 logger.groupCollapsed(`Precaching is responding to: ` + getFriendlyURL(request.url)); 2512 logger.log(`Serving the precached url: ${getFriendlyURL(cacheKey instanceof Request ? cacheKey.url : cacheKey)}`); 2513 logger.groupCollapsed(`View request details here.`); 2514 logger.log(request); 2515 logger.groupEnd(); 2516 logger.groupCollapsed(`View response details here.`); 2517 logger.log(response); 2518 logger.groupEnd(); 2519 logger.groupEnd(); 2520 } 2521 return response; 2522 } 2523 async _handleInstall(request, handler) { 2524 this._useDefaultCacheabilityPluginIfNeeded(); 2525 const response = await handler.fetch(request); 2526 const wasCached = await handler.cachePut(request, response.clone()); 2527 if (!wasCached) { 2528 throw new WorkboxError("bad-precaching-response", { 2529 url: request.url, 2530 status: response.status 2531 }); 2532 } 2533 return response; 2534 } 2535 /** 2536 * This method is complex, as there a number of things to account for: 2537 * 2538 * The `plugins` array can be set at construction, and/or it might be added to 2539 * to at any time before the strategy is used. 2540 * 2541 * At the time the strategy is used (i.e. during an `install` event), there 2542 * needs to be at least one plugin that implements `cacheWillUpdate` in the 2543 * array, other than `copyRedirectedCacheableResponsesPlugin`. 2544 * 2545 * - If this method is called and there are no suitable `cacheWillUpdate` 2546 * plugins, we need to add `defaultPrecacheCacheabilityPlugin`. 2547 * 2548 * - If this method is called and there is exactly one `cacheWillUpdate`, then 2549 * we don't have to do anything (this might be a previously added 2550 * `defaultPrecacheCacheabilityPlugin`, or it might be a custom plugin). 2551 * 2552 * - If this method is called and there is more than one `cacheWillUpdate`, 2553 * then we need to check if one is `defaultPrecacheCacheabilityPlugin`. If so, 2554 * we need to remove it. (This situation is unlikely, but it could happen if 2555 * the strategy is used multiple times, the first without a `cacheWillUpdate`, 2556 * and then later on after manually adding a custom `cacheWillUpdate`.) 2557 * 2558 * See https://github.com/GoogleChrome/workbox/issues/2737 for more context. 2559 * 2560 * @private 2561 */ 2562 _useDefaultCacheabilityPluginIfNeeded() { 2563 let defaultPluginIndex = null; 2564 let cacheWillUpdatePluginCount = 0; 2565 for (const [index, plugin] of this.plugins.entries()) { 2566 if (plugin === _PrecacheStrategy.copyRedirectedCacheableResponsesPlugin) { 2567 continue; 2568 } 2569 if (plugin === _PrecacheStrategy.defaultPrecacheCacheabilityPlugin) { 2570 defaultPluginIndex = index; 2571 } 2572 if (plugin.cacheWillUpdate) { 2573 cacheWillUpdatePluginCount++; 2574 } 2575 } 2576 if (cacheWillUpdatePluginCount === 0) { 2577 this.plugins.push(_PrecacheStrategy.defaultPrecacheCacheabilityPlugin); 2578 } else if (cacheWillUpdatePluginCount > 1 && defaultPluginIndex !== null) { 2579 this.plugins.splice(defaultPluginIndex, 1); 2580 } 2581 } 2582 }; 2583 PrecacheStrategy.defaultPrecacheCacheabilityPlugin = { 2584 async cacheWillUpdate({ response }) { 2585 if (!response || response.status >= 400) { 2586 return null; 2587 } 2588 return response; 2589 } 2590 }; 2591 PrecacheStrategy.copyRedirectedCacheableResponsesPlugin = { 2592 async cacheWillUpdate({ response }) { 2593 return response.redirected ? await copyResponse(response) : response; 2594 } 2595 }; 2596 2597
vendor: 595 bytes, lines 2597-2608
2597// node_modules/workbox-precaching/utils/deleteOutdatedCaches.js 2598 var SUBSTRING_TO_FIND = "-precache-"; 2599 var deleteOutdatedCaches = async (currentPrecacheName, substringToFind = SUBSTRING_TO_FIND) => { 2600 const cacheNames2 = await self.caches.keys(); 2601 const cacheNamesToDelete = cacheNames2.filter((cacheName) => { 2602 return cacheName.includes(substringToFind) && cacheName.includes(self.registration.scope) && cacheName !== currentPrecacheName; 2603 }); 2604 await Promise.all(cacheNamesToDelete.map((cacheName) => self.caches.delete(cacheName))); 2605 return cacheNamesToDelete; 2606 }; 2607 2608
vendor: 504 bytes, lines 2608-2622
2608// node_modules/workbox-precaching/cleanupOutdatedCaches.js 2609 function cleanupOutdatedCaches() { 2610 self.addEventListener("activate", ((event) => { 2611 const cacheName = cacheNames.getPrecacheName(); 2612 event.waitUntil(deleteOutdatedCaches(cacheName).then((cachesDeleted) => { 2613 if (false) { 2614 if (cachesDeleted.length > 0) { 2615 logger.log(`The following out-of-date precaches were cleaned up automatically:`, cachesDeleted); 2616 } 2617 } 2618 })); 2619 })); 2620 } 2621 2622
2622// src/sw/service-worker.ts 2623 var CACHE_NAMES = { 2624 fonts: "fonts-v1", 2625 audio: "audio-v1", 2626 quranData: "quran-data-v1", 2627 images: "images-v1", 2628 pages: "pages-v1", 2629 staticAssets: "static-assets-v1" 2630 }; 2631 cleanupOutdatedCaches(); 2632 registerRoute( 2633 ({ url }) => url.pathname.includes("/fonts/") || url.pathname.endsWith(".woff2") || url.pathname.endsWith(".woff") || url.pathname.endsWith(".ttf"), 2634 new CacheFirst({ 2635 cacheName: CACHE_NAMES.fonts, 2636 plugins: [ 2637 new CacheableResponsePlugin({ statuses: [0, 200] }), 2638 new ExpirationPlugin({ 2639 maxEntries: 500, 2640 // QCF fonts can be many pages 2641 maxAgeSeconds: 365 * 24 * 60 * 60 2642 // 1 year 2643 }) 2644 ] 2645 }) 2646 ); 2647 registerRoute( 2648 ({ url }) => url.hostname.includes("cdn.isl.am") && url.pathname.includes("/fonts/"), 2649 new CacheFirst({ 2650 cacheName: CACHE_NAMES.fonts, 2651 plugins: [ 2652 new CacheableResponsePlugin({ statuses: [0, 200] }), 2653 new ExpirationPlugin({ 2654 maxEntries: 500, 2655 maxAgeSeconds: 365 * 24 * 60 * 60 2656 }) 2657 ] 2658 }) 2659 ); 2660 registerRoute( 2661 ({ url }) => url.pathname.includes("/audio/") || url.pathname.endsWith(".mp3"), 2662 new CacheFirst({ 2663 cacheName: CACHE_NAMES.audio, 2664 plugins: [ 2665 new CacheableResponsePlugin({ statuses: [0, 200] }), 2666 new ExpirationPlugin({ 2667 maxEntries: 2e3, 2668 maxAgeSeconds: 10 * 365 * 24 * 60 * 60 2669 // 10 years 2670 }) 2671 ] 2672 }) 2673 ); 2674 registerRoute( 2675 ({ url }) => url.pathname.endsWith(".json.gz") || url.pathname.endsWith(".json"), 2676 new CacheFirst({ 2677 cacheName: CACHE_NAMES.quranData, 2678 plugins: [ 2679 new CacheableResponsePlugin({ statuses: [0, 200] }), 2680 new ExpirationPlugin({ 2681 maxEntries: 2e3, 2682 maxAgeSeconds: 365 * 24 * 60 * 60 2683 // 1 year 2684 }) 2685 ] 2686 }) 2687 ); 2688 registerRoute( 2689 ({ url }) => url.hostname.includes("cdn.isl.am") && url.pathname.includes("/data/"), 2690 new CacheFirst({ 2691 cacheName: CACHE_NAMES.quranData, 2692 plugins: [ 2693 new CacheableResponsePlugin({ statuses: [0, 200] }), 2694 new ExpirationPlugin({ 2695 maxEntries: 2e3, 2696 maxAgeSeconds: 365 * 24 * 60 * 60 2697 }) 2698 ] 2699 }) 2700 ); 2701 registerRoute( 2702 ({ request }) => request.destination === "image", 2703 new CacheFirst({ 2704 cacheName: CACHE_NAMES.images, 2705 plugins: [ 2706 new CacheableResponsePlugin({ statuses: [0, 200] }), 2707 new ExpirationPlugin({ 2708 maxEntries: 200, 2709 maxAgeSeconds: 30 * 24 * 60 * 60 2710 // 30 days 2711 }) 2712 ] 2713 }) 2714 ); 2715 registerRoute( 2716 ({ request }) => request.destination === "script" || request.destination === "style", 2717 new StaleWhileRevalidate({ 2718 cacheName: CACHE_NAMES.staticAssets, 2719 plugins: [new CacheableResponsePlugin({ statuses: [0, 200] })] 2720 }) 2721 ); 2722 registerRoute( 2723 ({ url }) => url.pathname.startsWith("/_next/static/"), 2724 new CacheFirst({ 2725 cacheName: CACHE_NAMES.staticAssets, 2726 plugins: [ 2727 new CacheableResponsePlugin({ statuses: [0, 200] }), 2728 new ExpirationPlugin({ 2729 maxEntries: 200, 2730 maxAgeSeconds: 365 * 24 * 60 * 60 2731 // 1 year (immutable) 2732 }) 2733 ] 2734 }) 2735 ); 2736 registerRoute( 2737 ({ request }) => request.mode === "navigate", 2738 new NetworkFirst({ 2739 cacheName: CACHE_NAMES.pages, 2740 plugins: [ 2741 new CacheableResponsePlugin({ statuses: [0, 200] }), 2742 new ExpirationPlugin({ 2743 maxEntries: 50, 2744 maxAgeSeconds: 24 * 60 * 60 2745 // 1 day 2746 }) 2747 ], 2748 networkTimeoutSeconds: 3 2749 }) 2750 ); 2751 self.addEventListener("install", (event) => { 2752 event.waitUntil( 2753 caches.open(CACHE_NAMES.pages).then((cache) => { 2754 return cache.addAll([ 2755 "/", 2756 "/quran", 2757 "/quran/1", 2758 "/offline" 2759 ]).catch((error) => { 2760 console.warn("[SW] Precache error:", error); 2761 }); 2762 }) 2763 ); 2764 self.skipWaiting(); 2765 }); 2766 self.addEventListener("activate", (event) => { 2767 event.waitUntil( 2768 Promise.all([ 2769 self.clients.claim(), 2770 // Clean up old cache versions 2771 caches.keys().then((cacheNames2) => { 2772 return Promise.all( 2773 cacheNames2.filter((name) => { 2774 return !Object.values(CACHE_NAMES).includes(name); 2775 }).map((name) => caches.delete(name)) 2776 ); 2777 }) 2778 ]) 2779 ); 2780 }); 2781 self.addEventListener("fetch", (event) => { 2782 if (event.request.mode === "navigate") { 2783 event.respondWith( 2784 fetch(event.request).catch(async () => { 2785 const cached = await caches.match(event.request); 2786 if (cached) return cached; 2787 const offlinePage = await caches.match("/offline"); 2788 if (offlinePage) return offlinePage; 2789 const quranPage = await caches.match("/quran"); 2790 if (quranPage) return quranPage; 2791 return new Response("Offline - please connect to the internet", { 2792 status: 503, 2793 headers: { "Content-Type": "text/plain" } 2794 }); 2795 }) 2796 ); 2797 } 2798 }); 2799 self.addEventListener("message", (event) => { 2800 if (event.data.type === "SKIP_WAITING") {
2801 self.skipWaiting(); 2802 } 2803 if (event.data.type === "CACHE_URLS") { 2804 event.waitUntil( 2805 caches.open(CACHE_NAMES.quranData).then((cache) => { 2806 return cache.addAll(event.data.urls).catch((error) => { 2807 console.warn("[SW] Cache URLs error:", error); 2808 }); 2809 }) 2810 ); 2811 } 2812 if (event.data.type === "CLEAR_CACHE") { 2813 event.waitUntil( 2814 caches.keys().then((names) => { 2815 return Promise.all( 2816 names.filter((name) => { 2817 if (event.data.prefix) { 2818 return name.startsWith(event.data.prefix); 2819 } 2820 return true; 2821 }).map((name) => caches.delete(name)) 2822 ); 2823 }) 2824 ); 2825 } 2826 if (event.data.type === "GET_CACHE_SIZE") { 2827 event.waitUntil( 2828 (async () => { 2829 const cacheNames2 = await caches.keys(); 2830 let totalSize = 0; 2831 for (const cacheName of cacheNames2) { 2832 const cache = await caches.open(cacheName); 2833 const keys = await cache.keys(); 2834 totalSize += keys.length; 2835 } 2836 event.source?.postMessage({ 2837 type: "CACHE_SIZE", 2838 count: totalSize 2839 }); 2840 })() 2841 ); 2842 } 2843 }); 2844 self.addEventListener("sync", (event) => { 2845 if (event.tag === "sync-user-data") { 2846 event.waitUntil(syncUserData()); 2847 } 2848 }); 2849 async function syncUserData() { 2850 console.log("[SW] Background sync triggered"); 2851 } 2852 console.log("[SW] Service Worker loaded"); 2853})(); 2854//# sourceMappingURL=sw.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.