vendor: 903 bytes, lines 1-22
1(() => { 2 var __defProp = Object.defineProperty; 3 var __defProps = Object.defineProperties; 4 var __getOwnPropDescs = Object.getOwnPropertyDescriptors; 5 var __getOwnPropSymbols = Object.getOwnPropertySymbols; 6 var __hasOwnProp = Object.prototype.hasOwnProperty; 7 var __propIsEnum = Object.prototype.propertyIsEnumerable; 8 var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; 9 var __spreadValues = (a, b) => { 10 for (var prop in b || (b = {})) 11 if (__hasOwnProp.call(b, prop)) 12 __defNormalProp(a, prop, b[prop]); 13 if (__getOwnPropSymbols) 14 for (var prop of __getOwnPropSymbols(b)) { 15 if (__propIsEnum.call(b, prop)) 16 __defNormalProp(a, prop, b[prop]); 17 } 18 return a; 19 }; 20 var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); 21 22
22// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/named-cache-storage.mjs 23 var NamedCacheStorage = class { 24 constructor(original, cacheNamePrefix) { 25 this.original = original; 26 this.cacheNamePrefix = cacheNamePrefix; 27 } 28 delete(cacheName) { 29 return this.original.delete(`${this.cacheNamePrefix}:${cacheName}`); 30 } 31 has(cacheName) { 32 return this.original.has(`${this.cacheNamePrefix}:${cacheName}`); 33 } 34 async keys() { 35 const prefix = `${this.cacheNamePrefix}:`; 36 const allCacheNames = await this.original.keys(); 37 const ownCacheNames = allCacheNames.filter((name) => name.startsWith(prefix)); 38 return ownCacheNames.map((name) => name.slice(prefix.length)); 39 } 40 match(request, options) { 41 return this.original.match(request, options); 42 } 43 async open(cacheName) { 44 const cache = await this.original.open(`${this.cacheNamePrefix}:${cacheName}`); 45 return Object.assign(cache, { name: cacheName }); 46 } 47 }; 48 49
49// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/adapter.mjs 50 var Adapter = class { 51 constructor(scopeUrl, caches) { 52 this.scopeUrl = scopeUrl; 53 const parsedScopeUrl = this.parseUrl(this.scopeUrl); 54 this.origin = parsedScopeUrl.origin; 55 this.caches = new NamedCacheStorage(caches, `ngsw:${parsedScopeUrl.path}`); 56 } 57 newRequest(input, init) { 58 return new Request(input, init); 59 } 60 newResponse(body, init) { 61 return new Response(body, init); 62 } 63 newHeaders(headers) { 64 return new Headers(headers); 65 } 66 isClient(source) { 67 return source instanceof Client; 68 } 69 get time() { 70 return Date.now(); 71 } 72 normalizeUrl(url) { 73 const parsed = this.parseUrl(url, this.scopeUrl); 74 return parsed.origin === this.origin ? parsed.path : url; 75 } 76 parseUrl(url, relativeTo) { 77 const parsed = !relativeTo ? new URL(url) : new URL(url, relativeTo); 78 return { origin: parsed.origin, path: parsed.pathname, search: parsed.search }; 79 } 80 timeout(ms) { 81 return new Promise((resolve) => { 82 setTimeout(() => resolve(), ms); 83 }); 84 } 85 }; 86 87
87// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/database.mjs 88 var NotFound = class { 89 constructor(table, key) { 90 this.table = table; 91 this.key = key; 92 } 93 }; 94 95
95// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/db-cache.mjs 96 var CacheDatabase = class { 97 constructor(adapter2) { 98 this.adapter = adapter2; 99 this.cacheNamePrefix = "db"; 100 this.tables = /* @__PURE__ */ new Map(); 101 } 102 "delete"(name) { 103 if (this.tables.has(name)) { 104 this.tables.delete(name); 105 } 106 return this.adapter.caches.delete(`${this.cacheNamePrefix}:${name}`); 107 } 108 async list() { 109 const prefix = `${this.cacheNamePrefix}:`; 110 const allCacheNames = await this.adapter.caches.keys(); 111 const dbCacheNames = allCacheNames.filter((name) => name.startsWith(prefix)); 112 return dbCacheNames.map((name) => name.slice(prefix.length)); 113 } 114 async open(name, cacheQueryOptions) { 115 if (!this.tables.has(name)) { 116 const cache = await this.adapter.caches.open(`${this.cacheNamePrefix}:${name}`); 117 const table = new CacheTable(name, cache, this.adapter, cacheQueryOptions); 118 this.tables.set(name, table); 119 } 120 return this.tables.get(name); 121 } 122 }; 123 var CacheTable = class { 124 constructor(name, cache, adapter2, cacheQueryOptions) { 125 this.name = name; 126 this.cache = cache; 127 this.adapter = adapter2; 128 this.cacheQueryOptions = cacheQueryOptions; 129 this.cacheName = this.cache.name; 130 } 131 request(key) { 132 return this.adapter.newRequest("/" + key); 133 } 134 "delete"(key) { 135 return this.cache.delete(this.request(key), this.cacheQueryOptions); 136 } 137 keys() { 138 return this.cache.keys().then((requests) => requests.map((req) => req.url.slice(1))); 139 } 140 read(key) { 141 return this.cache.match(this.request(key), this.cacheQueryOptions).then((res) => { 142 if (res === void 0) { 143 return Promise.reject(new NotFound(this.name, key)); 144 } 145 return res.json(); 146 }); 147 } 148 write(key, value) { 149 return this.cache.put(this.request(key), this.adapter.newResponse(JSON.stringify(value))); 150 } 151 }; 152 153
153// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/api.mjs 154 var UpdateCacheStatus; 155 (function(UpdateCacheStatus2) { 156 UpdateCacheStatus2[UpdateCacheStatus2["NOT_CACHED"] = 0] = "NOT_CACHED"; 157 UpdateCacheStatus2[UpdateCacheStatus2["CACHED_BUT_UNUSED"] = 1] = "CACHED_BUT_UNUSED"; 158 UpdateCacheStatus2[UpdateCacheStatus2["CACHED"] = 2] = "CACHED"; 159 })(UpdateCacheStatus || (UpdateCacheStatus = {})); 160 161
161// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/error.mjs 162 var SwCriticalError = class extends Error { 163 constructor() { 164 super(...arguments); 165 this.isCritical = true; 166 } 167 }; 168 function errorToString(error) { 169 if (error instanceof Error) { 170 return `${error.message} 171${error.stack}`; 172 } else { 173 return `${error}`; 174 } 175 } 176 var SwUnrecoverableStateError = class extends SwCriticalError { 177 constructor() { 178 super(...arguments); 179 this.isUnrecoverableState = true; 180 } 181 }; 182 183
183// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/sha1.mjs 184 function sha1(str) { 185 const utf8 = str; 186 const words32 = stringToWords32(utf8, Endian.Big); 187 return _sha1(words32, utf8.length * 8); 188 } 189 function sha1Binary(buffer) { 190 const words32 = arrayBufferToWords32(buffer, Endian.Big); 191 return _sha1(words32, buffer.byteLength * 8); 192 } 193 function _sha1(words32, len) { 194 const w = []; 195 let [a, b, c, d, e] = [1732584193, 4023233417, 2562383102, 271733878, 3285377520]; 196 words32[len >> 5] |= 128 << 24 - len % 32; 197 words32[(len + 64 >> 9 << 4) + 15] = len; 198 for (let i = 0; i < words32.length; i += 16) { 199 const [h0, h1, h2, h3, h4] = [a, b, c, d, e]; 200 for (let j = 0; j < 80; j++) { 201 if (j < 16) { 202 w[j] = words32[i + j]; 203 } else { 204 w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); 205 } 206 const [f, k] = fk(j, b, c, d); 207 const temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32); 208 [e, d, c, b, a] = [d, c, rol32(b, 30), a, temp]; 209 } 210 [a, b, c, d, e] = [add32(a, h0), add32(b, h1), add32(c, h2), add32(d, h3), add32(e, h4)]; 211 } 212 return byteStringToHexString(words32ToByteString([a, b, c, d, e])); 213 } 214 function add32(a, b) { 215 return add32to64(a, b)[1]; 216 } 217 function add32to64(a, b) { 218 const low = (a & 65535) + (b & 65535); 219 const high = (a >>> 16) + (b >>> 16) + (low >>> 16); 220 return [high >>> 16, high << 16 | low & 65535]; 221 } 222 function rol32(a, count) { 223 return a << count | a >>> 32 - count; 224 } 225 var Endian; 226 (function(Endian2) { 227 Endian2[Endian2["Little"] = 0] = "Little"; 228 Endian2[Endian2["Big"] = 1] = "Big"; 229 })(Endian || (Endian = {})); 230 function fk(index, b, c, d) { 231 if (index < 20) { 232 return [b & c | ~b & d, 1518500249]; 233 } 234 if (index < 40) { 235 return [b ^ c ^ d, 1859775393]; 236 } 237 if (index < 60) { 238 return [b & c | b & d | c & d, 2400959708]; 239 } 240 return [b ^ c ^ d, 3395469782]; 241 } 242 function stringToWords32(str, endian) { 243 const size = str.length + 3 >>> 2; 244 const words32 = []; 245 for (let i = 0; i < size; i++) { 246 words32[i] = wordAt(str, i * 4, endian); 247 } 248 return words32; 249 } 250 function arrayBufferToWords32(buffer, endian) { 251 const size = buffer.byteLength + 3 >>> 2; 252 const words32 = []; 253 const view = new Uint8Array(buffer); 254 for (let i = 0; i < size; i++) { 255 words32[i] = wordAt(view, i * 4, endian); 256 } 257 return words32; 258 } 259 function byteAt(str, index) { 260 if (typeof str === "string") { 261 return index >= str.length ? 0 : str.charCodeAt(index) & 255; 262 } else { 263 return index >= str.byteLength ? 0 : str[index] & 255; 264 } 265 } 266 function wordAt(str, index, endian) { 267 let word = 0; 268 if (endian === Endian.Big) { 269 for (let i = 0; i < 4; i++) { 270 word += byteAt(str, index + i) << 24 - 8 * i; 271 } 272 } else { 273 for (let i = 0; i < 4; i++) { 274 word += byteAt(str, index + i) << 8 * i; 275 } 276 } 277 return word; 278 } 279 function words32ToByteString(words32) { 280 return words32.reduce((str, word) => str + word32ToByteString(word), ""); 281 } 282 function word32ToByteString(word) { 283 let str = ""; 284 for (let i = 0; i < 4; i++) { 285 str += String.fromCharCode(word >>> 8 * (3 - i) & 255); 286 } 287 return str; 288 } 289 function byteStringToHexString(str) { 290 let hex = ""; 291 for (let i = 0; i < str.length; i++) { 292 const b = byteAt(str, i); 293 hex += (b >>> 4).toString(16) + (b & 15).toString(16); 294 } 295 return hex.toLowerCase(); 296 } 297 298
298// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/assets.mjs 299 var AssetGroup = class { 300 constructor(scope2, adapter2, idle, config, hashes, db, cacheNamePrefix) { 301 this.scope = scope2; 302 this.adapter = adapter2; 303 this.idle = idle; 304 this.config = config; 305 this.hashes = hashes; 306 this.db = db; 307 this.inFlightRequests = /* @__PURE__ */ new Map(); 308 this.urls = []; 309 this.patterns = []; 310 this.name = config.name; 311 this.urls = config.urls.map((url) => adapter2.normalizeUrl(url)); 312 this.patterns = config.patterns.map((pattern) => new RegExp(pattern)); 313 this.cache = adapter2.caches.open(`${cacheNamePrefix}:${config.name}:cache`); 314 this.metadata = this.db.open(`${cacheNamePrefix}:${config.name}:meta`, config.cacheQueryOptions); 315 } 316 async cacheStatus(url) { 317 const cache = await this.cache; 318 const meta = await this.metadata; 319 const req = this.adapter.newRequest(url); 320 const res = await cache.match(req, this.config.cacheQueryOptions); 321 if (res === void 0) { 322 return UpdateCacheStatus.NOT_CACHED; 323 } 324 try { 325 const data = await meta.read(req.url); 326 if (!data.used) { 327 return UpdateCacheStatus.CACHED_BUT_UNUSED; 328 } 329 } catch (_) { 330 } 331 return UpdateCacheStatus.CACHED; 332 } 333 async getCacheNames() { 334 const [cache, metadata] = await Promise.all([ 335 this.cache, 336 this.metadata 337 ]); 338 return [cache.name, metadata.cacheName]; 339 } 340 async handleFetch(req, _event) { 341 const url = this.adapter.normalizeUrl(req.url); 342 if (this.urls.indexOf(url) !== -1 || this.patterns.some((pattern) => pattern.test(url))) { 343 const cache = await this.cache; 344 const cachedResponse = await cache.match(req, this.config.cacheQueryOptions); 345 if (cachedResponse !== void 0) { 346 if (this.hashes.has(url)) { 347 return cachedResponse; 348 } else { 349 if (await this.needToRevalidate(req, cachedResponse)) { 350 this.idle.schedule(`revalidate(${cache.name}): ${req.url}`, async () => { 351 await this.fetchAndCacheOnce(req); 352 }); 353 } 354 return cachedResponse; 355 } 356 } 357 const res = await this.fetchAndCacheOnce(this.newRequestWithMetadata(req.url, req)); 358 return res.clone(); 359 } else { 360 return null; 361 } 362 } 363 async needToRevalidate(req, res) { 364 if (res.headers.has("Cache-Control")) { 365 const cacheControl = res.headers.get("Cache-Control"); 366 const cacheDirectives = cacheControl.split(",").map((v) => v.trim()).map((v) => v.split("=")); 367 cacheDirectives.forEach((v) => v[0] = v[0].toLowerCase()); 368 const maxAgeDirective = cacheDirectives.find((v) => v[0] === "max-age"); 369 const cacheAge = maxAgeDirective ? maxAgeDirective[1] : void 0; 370 if (!cacheAge) { 371 return true; 372 } 373 try { 374 const maxAge = 1e3 * parseInt(cacheAge); 375 let ts; 376 try { 377 const metaTable = await this.metadata; 378 ts = (await metaTable.read(req.url)).ts; 379 } catch (e) { 380 const date = res.headers.get("Date"); 381 if (date === null) { 382 return true; 383 } 384 ts = Date.parse(date); 385 } 386 const age = this.adapter.time - ts; 387 return age < 0 || age > maxAge; 388 } catch (e) { 389 return true; 390 } 391 } else if (res.headers.has("Expires")) { 392 const expiresStr = res.headers.get("Expires"); 393 try { 394 return this.adapter.time > Date.parse(expiresStr); 395 } catch (e) { 396 return true; 397 } 398 } else { 399 return true; 400 } 401 } 402 async fetchFromCacheOnly(url) { 403 const cache = await this.cache; 404 const metaTable = await this.metadata; 405 const request = this.adapter.newRequest(url); 406 const response = await cache.match(request, this.config.cacheQueryOptions); 407 if (response === void 0) { 408 return null; 409 } 410 let metadata = void 0;
411 try { 412 metadata = await metaTable.read(request.url); 413 } catch (e) { 414 } 415 return { response, metadata }; 416 } 417 async unhashedResources() { 418 const cache = await this.cache; 419 return (await cache.keys()).map((request) => this.adapter.normalizeUrl(request.url)).filter((url) => !this.hashes.has(url)); 420 } 421 async fetchAndCacheOnce(req, used = true) { 422 if (this.inFlightRequests.has(req.url)) { 423 return this.inFlightRequests.get(req.url); 424 } 425 const fetchOp = this.fetchFromNetwork(req); 426 this.inFlightRequests.set(req.url, fetchOp); 427 try { 428 const res = await fetchOp; 429 if (!res.ok) { 430 throw new Error(`Response not Ok (fetchAndCacheOnce): request for ${req.url} returned response ${res.status} ${res.statusText}`); 431 } 432 try { 433 const cache = await this.cache; 434 await cache.put(req, res.clone()); 435 if (!this.hashes.has(this.adapter.normalizeUrl(req.url))) { 436 const meta = { ts: this.adapter.time, used }; 437 const metaTable = await this.metadata; 438 await metaTable.write(req.url, meta); 439 } 440 return res; 441 } catch (err) { 442 throw new SwCriticalError(`Failed to update the caches for request to '${req.url}' (fetchAndCacheOnce): ${errorToString(err)}`); 443 } 444 } finally { 445 this.inFlightRequests.delete(req.url); 446 } 447 } 448 async fetchFromNetwork(req, redirectLimit = 3) { 449 const res = await this.cacheBustedFetchFromNetwork(req); 450 if (res["redirected"] && !!res.url) { 451 if (redirectLimit === 0) { 452 throw new SwCriticalError(`Response hit redirect limit (fetchFromNetwork): request redirected too many times, next is ${res.url}`); 453 } 454 return this.fetchFromNetwork(this.newRequestWithMetadata(res.url, req), redirectLimit - 1); 455 } 456 return res; 457 } 458 async cacheBustedFetchFromNetwork(req) { 459 const url = this.adapter.normalizeUrl(req.url); 460 if (this.hashes.has(url)) { 461 const canonicalHash = this.hashes.get(url); 462 let response = await this.safeFetch(req); 463 let makeCacheBustedRequest = response.ok; 464 if (makeCacheBustedRequest) { 465 const fetchedHash = sha1Binary(await response.clone().arrayBuffer()); 466 makeCacheBustedRequest = fetchedHash !== canonicalHash; 467 } 468 if (makeCacheBustedRequest) { 469 const cacheBustReq = this.newRequestWithMetadata(this.cacheBust(req.url), req); 470 response = await this.safeFetch(cacheBustReq); 471 if (response.ok) { 472 const cacheBustedHash = sha1Binary(await response.clone().arrayBuffer()); 473 if (canonicalHash !== cacheBustedHash) { 474 throw new SwCriticalError(`Hash mismatch (cacheBustedFetchFromNetwork): ${req.url}: expected ${canonicalHash}, got ${cacheBustedHash} (after cache busting)`); 475 } 476 } 477 } 478 if (!response.ok && response.status === 404) { 479 throw new SwUnrecoverableStateError(`Failed to retrieve hashed resource from the server. (AssetGroup: ${this.config.name} | URL: ${url})`); 480 } 481 return response; 482 } else { 483 return this.safeFetch(req); 484 } 485 } 486 async maybeUpdate(updateFrom, req, cache) { 487 const url = this.adapter.normalizeUrl(req.url); 488 if (this.hashes.has(url)) { 489 const hash = this.hashes.get(url); 490 const res = await updateFrom.lookupResourceWithHash(url, hash); 491 if (res !== null) { 492 await cache.put(req, res); 493 return true; 494 } 495 } 496 return false; 497 } 498 newRequestWithMetadata(url, options) { 499 return this.adapter.newRequest(url, { headers: options.headers }); 500 } 501 cacheBust(url) { 502 return url + (url.indexOf("?") === -1 ? "?" : "&") + "ngsw-cache-bust=" + Math.random(); 503 } 504 async safeFetch(req) { 505 try { 506 return await this.scope.fetch(req); 507 } catch (e) { 508 return this.adapter.newResponse("", { 509 status: 504, 510 statusText: "Gateway Timeout" 511 }); 512 } 513 } 514 }; 515 var PrefetchAssetGroup = class extends AssetGroup { 516 async initializeFully(updateFrom) { 517 const cache = await this.cache; 518 await this.urls.reduce(async (previous, url) => { 519 await previous; 520 const req = this.adapter.newRequest(url); 521 const alreadyCached = await cache.match(req, this.config.cacheQueryOptions) !== void 0; 522 if (alreadyCached) { 523 return; 524 } 525 if (updateFrom !== void 0 && await this.maybeUpdate(updateFrom, req, cache)) { 526 return; 527 } 528 await this.fetchAndCacheOnce(req, false); 529 }, Promise.resolve()); 530 if (updateFrom !== void 0) { 531 const metaTable = await this.metadata; 532 await (await updateFrom.previouslyCachedResources()).filter((url) => this.urls.indexOf(url) !== -1 || this.patterns.some((pattern) => pattern.test(url))).reduce(async (previous, url) => { 533 await previous; 534 const req = this.adapter.newRequest(url); 535 const alreadyCached = await cache.match(req, this.config.cacheQueryOptions) !== void 0; 536 if (alreadyCached) { 537 return; 538 }
539 const res = await updateFrom.lookupResourceWithoutHash(url); 540 if (res === null || res.metadata === void 0) { 541 return; 542 } 543 await cache.put(req, res.response); 544 await metaTable.write(req.url, __spreadProps(__spreadValues({}, res.metadata), { used: false })); 545 }, Promise.resolve()); 546 } 547 } 548 }; 549 var LazyAssetGroup = class extends AssetGroup { 550 async initializeFully(updateFrom) { 551 if (updateFrom === void 0) { 552 return; 553 } 554 const cache = await this.cache; 555 await this.urls.reduce(async (previous, url) => { 556 await previous; 557 const req = this.adapter.newRequest(url); 558 const alreadyCached = await cache.match(req, this.config.cacheQueryOptions) !== void 0; 559 if (alreadyCached) { 560 return; 561 } 562 const updated = await this.maybeUpdate(updateFrom, req, cache); 563 if (this.config.updateMode === "prefetch" && !updated) { 564 const cacheStatus = await updateFrom.recentCacheStatus(url); 565 if (cacheStatus !== UpdateCacheStatus.CACHED) { 566 return; 567 } 568 await this.fetchAndCacheOnce(req, false); 569 } 570 }, Promise.resolve()); 571 } 572 }; 573 574
574// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/data.mjs 575 var LruList = class { 576 constructor(state) { 577 if (state === void 0) { 578 state = { 579 head: null, 580 tail: null, 581 map: {}, 582 count: 0 583 }; 584 } 585 this.state = state; 586 } 587 get size() { 588 return this.state.count; 589 } 590 pop() { 591 if (this.state.tail === null) { 592 return null; 593 } 594 const url = this.state.tail; 595 this.remove(url); 596 return url; 597 } 598 remove(url) { 599 const node = this.state.map[url]; 600 if (node === void 0) { 601 return false; 602 } 603 if (this.state.head === url) { 604 if (node.next === null) { 605 this.state.head = null; 606 this.state.tail = null; 607 this.state.map = {}; 608 this.state.count = 0; 609 return true; 610 } 611 const next = this.state.map[node.next]; 612 next.previous = null; 613 this.state.head = next.url; 614 node.next = null; 615 delete this.state.map[url]; 616 this.state.count--; 617 return true; 618 } 619 const previous = this.state.map[node.previous]; 620 previous.next = node.next; 621 if (node.next !== null) { 622 this.state.map[node.next].previous = node.previous; 623 } else { 624 this.state.tail = node.previous; 625 } 626 node.next = null; 627 node.previous = null; 628 delete this.state.map[url]; 629 this.state.count--; 630 return true; 631 } 632 accessed(url) { 633 if (this.state.head === url) { 634 return; 635 } 636 const node = this.state.map[url] || { url, next: null, previous: null }; 637 if (this.state.map[url] !== void 0) { 638 this.remove(url); 639 } 640 if (this.state.head !== null) { 641 this.state.map[this.state.head].previous = url; 642 } 643 node.next = this.state.head; 644 this.state.head = url; 645 if (this.state.tail === null) { 646 this.state.tail = url; 647 } 648 this.state.map[url] = node; 649 this.state.count++; 650 } 651 }; 652 var DataGroup = class { 653 constructor(scope2, adapter2, config, db, debugHandler, cacheNamePrefix) { 654 this.scope = scope2; 655 this.adapter = adapter2; 656 this.config = config; 657 this.db = db; 658 this.debugHandler = debugHandler; 659 this._lru = null; 660 this.patterns = config.patterns.map((pattern) => new RegExp(pattern)); 661 this.cache = adapter2.caches.open(`${cacheNamePrefix}:${config.name}:cache`); 662 this.lruTable = this.db.open(`${cacheNamePrefix}:${config.name}:lru`, config.cacheQueryOptions); 663 this.ageTable = this.db.open(`${cacheNamePrefix}:${config.name}:age`, config.cacheQueryOptions); 664 } 665 async lru() { 666 if (this._lru === null) { 667 const table = await this.lruTable; 668 try { 669 this._lru = new LruList(await table.read("lru")); 670 } catch (e) { 671 this._lru = new LruList(); 672 } 673 } 674 return this._lru; 675 } 676 async syncLru() { 677 if (this._lru === null) { 678 return; 679 } 680 const table = await this.lruTable; 681 try { 682 return table.write("lru", this._lru.state); 683 } catch (err) { 684 this.debugHandler.log(err, `DataGroup(${this.config.name}@${this.config.version}).syncLru()`); 685 } 686 } 687 async handleFetch(req, event) { 688 if (!this.patterns.some((pattern) => pattern.test(req.url))) { 689 return null; 690 } 691 const lru = await this.lru(); 692 switch (req.method) { 693 case "OPTIONS": 694 return null; 695 case "GET": 696 case "HEAD": 697 switch (this.config.strategy) { 698 case "freshness": 699 return this.handleFetchWithFreshness(req, event, lru); 700 case "performance": 701 return this.handleFetchWithPerformance(req, event, lru); 702 default: 703 throw new Error(`Unknown strategy: ${this.config.strategy}`); 704 } 705 default: 706 const wasCached = lru.remove(req.url); 707 if (wasCached) { 708 await this.clearCacheForUrl(req.url); 709 } 710 await this.syncLru(); 711 return this.safeFetch(req); 712 } 713 } 714 async handleFetchWithPerformance(req, event, lru) { 715 var _a; 716 const okToCacheOpaque = (_a = this.config.cacheOpaqueResponses) != null ? _a : false;
717 let res = null; 718 const fromCache = await this.loadFromCache(req, lru); 719 if (fromCache !== null) { 720 res = fromCache.res; 721 if (this.config.refreshAheadMs !== void 0 && fromCache.age >= this.config.refreshAheadMs) { 722 event.waitUntil(this.safeCacheResponse(req, this.safeFetch(req), lru, okToCacheOpaque)); 723 } 724 } 725 if (res !== null) { 726 return res; 727 } 728 const [timeoutFetch, networkFetch] = this.networkFetchWithTimeout(req); 729 res = await timeoutFetch; 730 if (res === void 0) { 731 res = this.adapter.newResponse(null, { status: 504, statusText: "Gateway Timeout" }); 732 event.waitUntil(this.safeCacheResponse(req, networkFetch, lru, okToCacheOpaque)); 733 } else { 734 await this.safeCacheResponse(req, res, lru, okToCacheOpaque); 735 } 736 return res; 737 } 738 async handleFetchWithFreshness(req, event, lru) { 739 var _a; 740 const okToCacheOpaque = (_a = this.config.cacheOpaqueResponses) != null ? _a : true; 741 const [timeoutFetch, networkFetch] = this.networkFetchWithTimeout(req); 742 let res; 743 try { 744 res = await timeoutFetch; 745 } catch (e) { 746 res = void 0; 747 } 748 if (res === void 0) { 749 event.waitUntil(this.safeCacheResponse(req, networkFetch, lru, okToCacheOpaque)); 750 const fromCache = await this.loadFromCache(req, lru); 751 res = fromCache !== null ? fromCache.res : null; 752 } else { 753 await this.safeCacheResponse(req, res, lru, okToCacheOpaque); 754 } 755 if (res !== null) { 756 return res; 757 } 758 return networkFetch; 759 } 760 networkFetchWithTimeout(req) { 761 if (this.config.timeoutMs !== void 0) { 762 const networkFetch = this.scope.fetch(req); 763 const safeNetworkFetch = (async () => { 764 try { 765 return await networkFetch; 766 } catch (e) { 767 return this.adapter.newResponse(null, { 768 status: 504, 769 statusText: "Gateway Timeout" 770 }); 771 } 772 })(); 773 const networkFetchUndefinedError = (async () => { 774 try { 775 return await networkFetch; 776 } catch (e) { 777 return void 0; 778 } 779 })(); 780 const timeout = this.adapter.timeout(this.config.timeoutMs); 781 return [Promise.race([networkFetchUndefinedError, timeout]), safeNetworkFetch]; 782 } else { 783 const networkFetch = this.safeFetch(req); 784 return [networkFetch, networkFetch]; 785 } 786 } 787 async safeCacheResponse(req, resOrPromise, lru, okToCacheOpaque) { 788 try { 789 const res = await resOrPromise; 790 try { 791 await this.cacheResponse(req, res, lru, okToCacheOpaque); 792 } catch (err) { 793 this.debugHandler.log(err, `DataGroup(${this.config.name}@${this.config.version}).safeCacheResponse(${req.url}, status: ${res.status})`); 794 } 795 } catch (e) { 796 } 797 } 798 async loadFromCache(req, lru) { 799 const cache = await this.cache; 800 let res = await cache.match(req, this.config.cacheQueryOptions); 801 if (res !== void 0) { 802 try { 803 const ageTable = await this.ageTable; 804 const age = this.adapter.time - (await ageTable.read(req.url)).age; 805 if (age <= this.config.maxAge) { 806 lru.accessed(req.url); 807 return { res, age }; 808 } 809 } catch (e) { 810 } 811 lru.remove(req.url); 812 await this.clearCacheForUrl(req.url); 813 await this.syncLru(); 814 } 815 return null; 816 } 817 async cacheResponse(req, res, lru, okToCacheOpaque = false) { 818 if (!(res.ok || okToCacheOpaque && res.type === "opaque")) { 819 return; 820 } 821 if (lru.size >= this.config.maxSize) { 822 const evictedUrl = lru.pop(); 823 if (evictedUrl !== null) { 824 await this.clearCacheForUrl(evictedUrl); 825 } 826 } 827 lru.accessed(req.url); 828 await (await this.cache).put(req, res.clone()); 829 const ageTable = await this.ageTable; 830 await ageTable.write(req.url, { age: this.adapter.time }); 831 await this.syncLru(); 832 } 833 async cleanup() { 834 await Promise.all([ 835 this.cache.then((cache) => this.adapter.caches.delete(cache.name)), 836 this.ageTable.then((table) => this.db.delete(table.name)), 837 this.lruTable.then((table) => this.db.delete(table.name)) 838 ]); 839 } 840 async getCacheNames() { 841 const [cache, ageTable, lruTable] = await Promise.all([ 842 this.cache, 843 this.ageTable, 844 this.lruTable 845 ]); 846 return [cache.name, ageTable.cacheName, lruTable.cacheName]; 847 } 848 async clearCacheForUrl(url) { 849 const [cache, ageTable] = await Promise.all([this.cache, this.ageTable]); 850 await Promise.all([ 851 cache.delete(this.adapter.newRequest(url, { method: "GET" }), this.config.cacheQueryOptions), 852 cache.delete(this.adapter.newRequest(url, { method: "HEAD" }), this.config.cacheQueryOptions), 853 ageTable.delete(url) 854 ]); 855 } 856 async safeFetch(req) {
857 try { 858 return this.scope.fetch(req); 859 } catch (e) { 860 return this.adapter.newResponse(null, { 861 status: 504, 862 statusText: "Gateway Timeout" 863 }); 864 } 865 } 866 }; 867 868
868// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/app-version.mjs 869 var BACKWARDS_COMPATIBILITY_NAVIGATION_URLS = [ 870 { positive: true, regex: "^/.*$" }, 871 { positive: false, regex: "^/.*\\.[^/]*$" }, 872 { positive: false, regex: "^/.*__" } 873 ]; 874 var AppVersion = class { 875 get okay() { 876 return this._okay; 877 } 878 constructor(scope2, adapter2, database, idle, debugHandler, manifest, manifestHash) { 879 this.scope = scope2; 880 this.adapter = adapter2; 881 this.database = database; 882 this.debugHandler = debugHandler; 883 this.manifest = manifest; 884 this.manifestHash = manifestHash; 885 this.hashTable = /* @__PURE__ */ new Map(); 886 this.indexUrl = this.adapter.normalizeUrl(this.manifest.index); 887 this._okay = true; 888 Object.keys(manifest.hashTable).forEach((url) => { 889 this.hashTable.set(adapter2.normalizeUrl(url), manifest.hashTable[url]); 890 }); 891 const assetCacheNamePrefix = `${manifestHash}:assets`; 892 this.assetGroups = (manifest.assetGroups || []).map((config) => { 893 switch (config.installMode) { 894 case "prefetch": 895 return new PrefetchAssetGroup(scope2, adapter2, idle, config, this.hashTable, database, assetCacheNamePrefix); 896 case "lazy": 897 return new LazyAssetGroup(scope2, adapter2, idle, config, this.hashTable, database, assetCacheNamePrefix); 898 } 899 }); 900 this.dataGroups = (manifest.dataGroups || []).map((config) => new DataGroup(scope2, adapter2, config, database, debugHandler, `${config.version}:data`)); 901 manifest.navigationUrls = manifest.navigationUrls || BACKWARDS_COMPATIBILITY_NAVIGATION_URLS; 902 const includeUrls = manifest.navigationUrls.filter((spec) => spec.positive); 903 const excludeUrls = manifest.navigationUrls.filter((spec) => !spec.positive); 904 this.navigationUrls = { 905 include: includeUrls.map((spec) => new RegExp(spec.regex)), 906 exclude: excludeUrls.map((spec) => new RegExp(spec.regex)) 907 }; 908 } 909 async initializeFully(updateFrom) { 910 try { 911 await this.assetGroups.reduce(async (previous, group) => { 912 await previous; 913 return group.initializeFully(updateFrom); 914 }, Promise.resolve()); 915 } catch (err) { 916 this._okay = false; 917 throw err; 918 } 919 } 920 async handleFetch(req, event) { 921 const asset = await this.assetGroups.reduce(async (potentialResponse, group) => { 922 const resp = await potentialResponse; 923 if (resp !== null) { 924 return resp; 925 } 926 return group.handleFetch(req, event); 927 }, Promise.resolve(null)); 928 if (asset !== null) { 929 return asset; 930 } 931 const data = await this.dataGroups.reduce(async (potentialResponse, group) => { 932 const resp = await potentialResponse; 933 if (resp !== null) { 934 return resp; 935 } 936 return group.handleFetch(req, event); 937 }, Promise.resolve(null)); 938 if (data !== null) { 939 return data; 940 } 941 if (this.adapter.normalizeUrl(req.url) !== this.indexUrl && this.isNavigationRequest(req)) { 942 if (this.manifest.navigationRequestStrategy === "freshness") { 943 try { 944 return await this.scope.fetch(req); 945 } catch (e) { 946 } 947 } 948 return this.handleFetch(this.adapter.newRequest(this.indexUrl), event); 949 } 950 return null; 951 } 952 isNavigationRequest(req) { 953 if (req.method !== "GET" || req.mode !== "navigate") { 954 return false; 955 } 956 if (!this.acceptsTextHtml(req)) { 957 return false; 958 } 959 const urlPrefix = this.scope.registration.scope.replace(/\/$/, ""); 960 const url = req.url.startsWith(urlPrefix) ? req.url.slice(urlPrefix.length) : req.url; 961 const urlWithoutQueryOrHash = url.replace(/[?#].*$/, ""); 962 return this.navigationUrls.include.some((regex) => regex.test(urlWithoutQueryOrHash)) && !this.navigationUrls.exclude.some((regex) => regex.test(urlWithoutQueryOrHash)); 963 } 964 async lookupResourceWithHash(url, hash) { 965 if (!this.hashTable.has(url)) { 966 return null; 967 } 968 if (this.hashTable.get(url) !== hash) { 969 return null; 970 }
971 const cacheState = await this.lookupResourceWithoutHash(url); 972 return cacheState && cacheState.response; 973 } 974 lookupResourceWithoutHash(url) { 975 return this.assetGroups.reduce(async (potentialResponse, group) => { 976 const resp = await potentialResponse; 977 if (resp !== null) { 978 return resp; 979 } 980 return group.fetchFromCacheOnly(url); 981 }, Promise.resolve(null)); 982 } 983 previouslyCachedResources() { 984 return this.assetGroups.reduce(async (resources, group) => (await resources).concat(await group.unhashedResources()), Promise.resolve([])); 985 } 986 async recentCacheStatus(url) { 987 return this.assetGroups.reduce(async (current, group) => { 988 const status = await current; 989 if (status === UpdateCacheStatus.CACHED) { 990 return status; 991 } 992 const groupStatus = await group.cacheStatus(url); 993 if (groupStatus === UpdateCacheStatus.NOT_CACHED) { 994 return status; 995 } 996 return groupStatus; 997 }, Promise.resolve(UpdateCacheStatus.NOT_CACHED)); 998 } 999 async getCacheNames() { 1000 const allGroupCacheNames = await Promise.all([ 1001 ...this.assetGroups.map((group) => group.getCacheNames()), 1002 ...this.dataGroups.map((group) => group.getCacheNames()) 1003 ]); 1004 return [].concat(...allGroupCacheNames); 1005 } 1006 get appData() { 1007 return this.manifest.appData || null; 1008 } 1009 acceptsTextHtml(req) { 1010 const accept = req.headers.get("Accept"); 1011 if (accept === null) { 1012 return false; 1013 } 1014 const values = accept.split(","); 1015 return values.some((value) => value.trim().toLowerCase() === "text/html"); 1016 } 1017 }; 1018 1019
1019// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/debug.mjs 1020 var SW_VERSION = "15.2.5"; 1021 var DEBUG_LOG_BUFFER_SIZE = 100; 1022 var DebugHandler = class { 1023 constructor(driver, adapter2) { 1024 this.driver = driver; 1025 this.adapter = adapter2; 1026 this.debugLogA = []; 1027 this.debugLogB = []; 1028 } 1029 async handleFetch(req) { 1030 const [state, versions, idle] = await Promise.all([ 1031 this.driver.debugState(), 1032 this.driver.debugVersions(), 1033 this.driver.debugIdleState() 1034 ]); 1035 const msgState = `NGSW Debug Info: 1036 1037Driver version: ${SW_VERSION} 1038Driver state: ${state.state} (${state.why}) 1039Latest manifest hash: ${state.latestHash || "none"} 1040Last update check: ${this.since(state.lastUpdateCheck)}`; 1041 const msgVersions = versions.map((version) => `=== Version ${version.hash} === 1042 1043Clients: ${version.clients.join(", ")}`).join("\n\n"); 1044 const msgIdle = `=== Idle Task Queue === 1045Last update tick: ${this.since(idle.lastTrigger)} 1046Last update run: ${this.since(idle.lastRun)} 1047Task queue: 1048${idle.queue.map((v) => " * " + v).join("\n")} 1049 1050Debug log: 1051${this.formatDebugLog(this.debugLogB)} 1052${this.formatDebugLog(this.debugLogA)} 1053`; 1054 return this.adapter.newResponse(`${msgState} 1055 1056${msgVersions} 1057 1058${msgIdle}`, { headers: this.adapter.newHeaders({ "Content-Type": "text/plain" }) }); 1059 } 1060 since(time) { 1061 if (time === null) { 1062 return "never"; 1063 } 1064 let age = this.adapter.time - time; 1065 const days = Math.floor(age / 864e5); 1066 age = age % 864e5; 1067 const hours = Math.floor(age / 36e5); 1068 age = age % 36e5; 1069 const minutes = Math.floor(age / 6e4); 1070 age = age % 6e4; 1071 const seconds = Math.floor(age / 1e3); 1072 const millis = age % 1e3; 1073 return (days > 0 ? `${days}d` : "") + (hours > 0 ? `${hours}h` : "") + (minutes > 0 ? `${minutes}m` : "") + (seconds > 0 ? `${seconds}s` : "") + (millis > 0 ? `${millis}u` : ""); 1074 } 1075 log(value, context = "") { 1076 if (this.debugLogA.length === DEBUG_LOG_BUFFER_SIZE) { 1077 this.debugLogB = this.debugLogA; 1078 this.debugLogA = []; 1079 } 1080 if (typeof value !== "string") { 1081 value = this.errorToString(value); 1082 } 1083 this.debugLogA.push({ value, time: this.adapter.time, context }); 1084 } 1085 errorToString(err) { 1086 return `${err.name}(${err.message}, ${err.stack})`; 1087 } 1088 formatDebugLog(log) { 1089 return log.map((entry) => `[${this.since(entry.time)}] ${entry.value} ${entry.context}`).join("\n"); 1090 } 1091 }; 1092 1093
1093// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/idle.mjs 1094 var IdleScheduler = class { 1095 constructor(adapter2, delay, maxDelay, debug) { 1096 this.adapter = adapter2; 1097 this.delay = delay; 1098 this.maxDelay = maxDelay; 1099 this.debug = debug; 1100 this.queue = []; 1101 this.scheduled = null; 1102 this.empty = Promise.resolve(); 1103 this.emptyResolve = null; 1104 this.lastTrigger = null; 1105 this.lastRun = null; 1106 this.oldestScheduledAt = null; 1107 } 1108 async trigger() { 1109 var _a; 1110 this.lastTrigger = this.adapter.time; 1111 if (this.queue.length === 0) { 1112 return; 1113 } 1114 if (this.scheduled !== null) { 1115 this.scheduled.cancel = true; 1116 } 1117 const scheduled = { 1118 cancel: false 1119 }; 1120 this.scheduled = scheduled; 1121 const now = this.adapter.time; 1122 const maxDelay = Math.max(0, ((_a = this.oldestScheduledAt) != null ? _a : now) + this.maxDelay - now); 1123 const delay = Math.min(maxDelay, this.delay); 1124 await this.adapter.timeout(delay); 1125 if (scheduled.cancel) { 1126 return; 1127 } 1128 this.scheduled = null; 1129 await this.execute(); 1130 } 1131 async execute() { 1132 this.lastRun = this.adapter.time; 1133 while (this.queue.length > 0) { 1134 const queue = this.queue; 1135 this.queue = []; 1136 await queue.reduce(async (previous, task) => { 1137 await previous; 1138 try { 1139 await task.run(); 1140 } catch (err) { 1141 this.debug.log(err, `while running idle task ${task.desc}`); 1142 } 1143 }, Promise.resolve()); 1144 } 1145 if (this.emptyResolve !== null) { 1146 this.emptyResolve(); 1147 this.emptyResolve = null; 1148 } 1149 this.empty = Promise.resolve(); 1150 this.oldestScheduledAt = null; 1151 } 1152 schedule(desc, run) { 1153 this.queue.push({ desc, run }); 1154 if (this.emptyResolve === null) { 1155 this.empty = new Promise((resolve) => { 1156 this.emptyResolve = resolve; 1157 }); 1158 } 1159 if (this.oldestScheduledAt === null) { 1160 this.oldestScheduledAt = this.adapter.time; 1161 } 1162 } 1163 get size() { 1164 return this.queue.length; 1165 } 1166 get taskDescriptions() { 1167 return this.queue.map((task) => task.desc); 1168 } 1169 }; 1170 1171
1171// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/manifest.mjs 1172 function hashManifest(manifest) { 1173 return sha1(JSON.stringify(manifest)); 1174 } 1175 1176
1176// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/msg.mjs 1177 function isMsgCheckForUpdates(msg) { 1178 return msg.action === "CHECK_FOR_UPDATES"; 1179 } 1180 function isMsgActivateUpdate(msg) { 1181 return msg.action === "ACTIVATE_UPDATE"; 1182 } 1183 1184
1184// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/src/driver.mjs 1185 var IDLE_DELAY = 5e3; 1186 var MAX_IDLE_DELAY = 3e4; 1187 var SUPPORTED_CONFIG_VERSION = 1; 1188 var NOTIFICATION_OPTION_NAMES = [ 1189 "actions", 1190 "badge", 1191 "body", 1192 "data", 1193 "dir", 1194 "icon", 1195 "image", 1196 "lang", 1197 "renotify", 1198 "requireInteraction", 1199 "silent", 1200 "tag", 1201 "timestamp", 1202 "title", 1203 "vibrate" 1204 ]; 1205 var DriverReadyState; 1206 (function(DriverReadyState2) { 1207 DriverReadyState2[DriverReadyState2["NORMAL"] = 0] = "NORMAL"; 1208 DriverReadyState2[DriverReadyState2["EXISTING_CLIENTS_ONLY"] = 1] = "EXISTING_CLIENTS_ONLY"; 1209 DriverReadyState2[DriverReadyState2["SAFE_MODE"] = 2] = "SAFE_MODE"; 1210 })(DriverReadyState || (DriverReadyState = {})); 1211 var Driver = class { 1212 constructor(scope2, adapter2, db) { 1213 this.scope = scope2; 1214 this.adapter = adapter2; 1215 this.db = db; 1216 this.state = DriverReadyState.NORMAL; 1217 this.stateMessage = "(nominal)"; 1218 this.initialized = null; 1219 this.clientVersionMap = /* @__PURE__ */ new Map(); 1220 this.versions = /* @__PURE__ */ new Map(); 1221 this.latestHash = null; 1222 this.lastUpdateCheck = null; 1223 this.scheduledNavUpdateCheck = false; 1224 this.loggedInvalidOnlyIfCachedRequest = false; 1225 this.ngswStatePath = this.adapter.parseUrl("ngsw/state", this.scope.registration.scope).path; 1226 this.controlTable = this.db.open("control"); 1227 this.scope.addEventListener("install", (event) => { 1228 event.waitUntil(this.scope.skipWaiting()); 1229 }); 1230 this.scope.addEventListener("activate", (event) => { 1231 event.waitUntil((async () => { 1232 await this.scope.clients.claim(); 1233 this.idle.schedule("activate: cleanup-old-sw-caches", async () => { 1234 try { 1235 await this.cleanupOldSwCaches(); 1236 } catch (err) { 1237 this.debugger.log(err, "cleanupOldSwCaches @ activate: cleanup-old-sw-caches"); 1238 } 1239 }); 1240 })()); 1241 if (this.scope.registration.active !== null) { 1242 this.scope.registration.active.postMessage({ action: "INITIALIZE" }); 1243 } 1244 }); 1245 this.scope.addEventListener("fetch", (event) => this.onFetch(event)); 1246 this.scope.addEventListener("message", (event) => this.onMessage(event)); 1247 this.scope.addEventListener("push", (event) => this.onPush(event)); 1248 this.scope.addEventListener("notificationclick", (event) => this.onClick(event)); 1249 this.debugger = new DebugHandler(this, this.adapter); 1250 this.idle = new IdleScheduler(this.adapter, IDLE_DELAY, MAX_IDLE_DELAY, this.debugger); 1251 } 1252 onFetch(event) { 1253 const req = event.request; 1254 const scopeUrl = this.scope.registration.scope; 1255 const requestUrlObj = this.adapter.parseUrl(req.url, scopeUrl); 1256 if (req.headers.has("ngsw-bypass") || /[?&]ngsw-bypass(?:[=&]|$)/i.test(requestUrlObj.search)) { 1257 return; 1258 } 1259 if (requestUrlObj.path === this.ngswStatePath) { 1260 event.respondWith(this.debugger.handleFetch(req)); 1261 return; 1262 } 1263 if (this.state === DriverReadyState.SAFE_MODE) { 1264 event.waitUntil(this.idle.trigger()); 1265 return; 1266 } 1267 if (requestUrlObj.origin.startsWith("http:") && scopeUrl.startsWith("https:")) { 1268 this.debugger.log(`Ignoring passive mixed content request: Driver.fetch(${req.url})`); 1269 return; 1270 } 1271 if (req.cache === "only-if-cached" && req.mode !== "same-origin") { 1272 if (!this.loggedInvalidOnlyIfCachedRequest) { 1273 this.loggedInvalidOnlyIfCachedRequest = true; 1274 this.debugger.log(`Ignoring invalid request: 'only-if-cached' can be set only with 'same-origin' mode`, `Driver.fetch(${req.url}, cache: ${req.cache}, mode: ${req.mode})`); 1275 } 1276 return; 1277 } 1278 event.respondWith(this.handleFetch(event)); 1279 } 1280 onMessage(event) { 1281 if (this.state === DriverReadyState.SAFE_MODE) { 1282 return; 1283 } 1284 const data = event.data; 1285 if (!data || !data.action) { 1286 return; 1287 } 1288 event.waitUntil((async () => { 1289 if (data.action === "INITIALIZE") { 1290 return this.ensureInitialized(event); 1291 } 1292 if (!this.adapter.isClient(event.source)) { 1293 return; 1294 } 1295 await this.ensureInitialized(event); 1296 await this.handleMessage(data, event.source); 1297 })()); 1298 } 1299 onPush(msg) { 1300 if (!msg.data) { 1301 return; 1302 } 1303 msg.waitUntil(this.handlePush(msg.data.json())); 1304 } 1305 onClick(event) {
1306 event.waitUntil(this.handleClick(event.notification, event.action)); 1307 } 1308 async ensureInitialized(event) { 1309 if (this.initialized !== null) { 1310 return this.initialized; 1311 } 1312 try { 1313 this.initialized = this.initialize(); 1314 await this.initialized; 1315 } catch (error) { 1316 this.state = DriverReadyState.SAFE_MODE; 1317 this.stateMessage = `Initialization failed due to error: ${errorToString(error)}`; 1318 throw error; 1319 } finally { 1320 event.waitUntil(this.idle.trigger()); 1321 } 1322 } 1323 async handleMessage(msg, from) { 1324 if (isMsgCheckForUpdates(msg)) { 1325 const action = this.checkForUpdate(); 1326 await this.completeOperation(from, action, msg.nonce); 1327 } else if (isMsgActivateUpdate(msg)) { 1328 const action = this.updateClient(from); 1329 await this.completeOperation(from, action, msg.nonce); 1330 } 1331 } 1332 async handlePush(data) { 1333 await this.broadcast({ 1334 type: "PUSH", 1335 data 1336 }); 1337 if (!data.notification || !data.notification.title) { 1338 return; 1339 } 1340 const desc = data.notification; 1341 let options = {}; 1342 NOTIFICATION_OPTION_NAMES.filter((name) => desc.hasOwnProperty(name)).forEach((name) => options[name] = desc[name]); 1343 await this.scope.registration.showNotification(desc["title"], options); 1344 } 1345 async handleClick(notification, action) { 1346 var _a, _b, _c; 1347 notification.close(); 1348 const options = {}; 1349 NOTIFICATION_OPTION_NAMES.filter((name) => name in notification).forEach((name) => options[name] = notification[name]); 1350 const notificationAction = action === "" || action === void 0 ? "default" : action; 1351 const onActionClick = (_b = (_a = notification == null ? void 0 : notification.data) == null ? void 0 : _a.onActionClick) == null ? void 0 : _b[notificationAction]; 1352 const urlToOpen = new URL((_c = onActionClick == null ? void 0 : onActionClick.url) != null ? _c : "", this.scope.registration.scope).href; 1353 switch (onActionClick == null ? void 0 : onActionClick.operation) { 1354 case "openWindow": 1355 await this.scope.clients.openWindow(urlToOpen); 1356 break; 1357 case "focusLastFocusedOrOpen": { 1358 let matchingClient = await this.getLastFocusedMatchingClient(this.scope); 1359 if (matchingClient) { 1360 await (matchingClient == null ? void 0 : matchingClient.focus()); 1361 } else { 1362 await this.scope.clients.openWindow(urlToOpen); 1363 } 1364 break; 1365 } 1366 case "navigateLastFocusedOrOpen": { 1367 let matchingClient = await this.getLastFocusedMatchingClient(this.scope); 1368 if (matchingClient) { 1369 matchingClient = await matchingClient.navigate(urlToOpen); 1370 await (matchingClient == null ? void 0 : matchingClient.focus()); 1371 } else { 1372 await this.scope.clients.openWindow(urlToOpen); 1373 } 1374 break; 1375 } 1376 case "sendRequest": { 1377 await this.scope.fetch(urlToOpen); 1378 break; 1379 } 1380 default: 1381 break; 1382 } 1383 await this.broadcast({ 1384 type: "NOTIFICATION_CLICK", 1385 data: { action, notification: options } 1386 }); 1387 } 1388 async getLastFocusedMatchingClient(scope2) { 1389 const windowClients = await scope2.clients.matchAll({ type: "window" }); 1390 return windowClients[0]; 1391 } 1392 async completeOperation(client, promise, nonce) { 1393 const response = { type: "OPERATION_COMPLETED", nonce }; 1394 try { 1395 client.postMessage(__spreadProps(__spreadValues({}, response), { 1396 result: await promise 1397 })); 1398 } catch (e) { 1399 client.postMessage(__spreadProps(__spreadValues({}, response), { 1400 error: e.toString() 1401 })); 1402 } 1403 } 1404 async updateClient(client) { 1405 const existing = this.clientVersionMap.get(client.id); 1406 if (existing === this.latestHash) { 1407 return false; 1408 } 1409 let previous = void 0; 1410 if (existing !== void 0) { 1411 const existingVersion = this.versions.get(existing); 1412 previous = this.mergeHashWithAppData(existingVersion.manifest, existing); 1413 } 1414 this.clientVersionMap.set(client.id, this.latestHash); 1415 await this.sync(); 1416 const current = this.versions.get(this.latestHash); 1417 const notice = { 1418 type: "UPDATE_ACTIVATED", 1419 previous, 1420 current: this.mergeHashWithAppData(current.manifest, this.latestHash) 1421 }; 1422 client.postMessage(notice); 1423 return true; 1424 } 1425 async handleFetch(event) {
1426 try { 1427 await this.ensureInitialized(event); 1428 } catch (e) { 1429 return this.safeFetch(event.request); 1430 } 1431 if (event.request.mode === "navigate" && !this.scheduledNavUpdateCheck) { 1432 this.scheduledNavUpdateCheck = true; 1433 this.idle.schedule("check-updates-on-navigation", async () => { 1434 this.scheduledNavUpdateCheck = false; 1435 await this.checkForUpdate(); 1436 }); 1437 } 1438 const appVersion = await this.assignVersion(event); 1439 let res = null; 1440 try { 1441 if (appVersion !== null) { 1442 try { 1443 res = await appVersion.handleFetch(event.request, event); 1444 } catch (err) { 1445 if (err.isUnrecoverableState) { 1446 await this.notifyClientsAboutUnrecoverableState(appVersion, err.message); 1447 } 1448 if (err.isCritical) { 1449 this.debugger.log(err, `Driver.handleFetch(version: ${appVersion.manifestHash})`); 1450 await this.versionFailed(appVersion, err); 1451 return this.safeFetch(event.request); 1452 } 1453 throw err; 1454 } 1455 } 1456 if (res === null) { 1457 return this.safeFetch(event.request); 1458 } 1459 return res; 1460 } finally { 1461 event.waitUntil(this.idle.trigger()); 1462 } 1463 } 1464 async initialize() { 1465 const table = await this.controlTable; 1466 let manifests, assignments, latest; 1467 try { 1468 [manifests, assignments, latest] = await Promise.all([ 1469 table.read("manifests"), 1470 table.read("assignments"), 1471 table.read("latest") 1472 ]); 1473 if (!this.versions.has(latest.latest) && !manifests.hasOwnProperty(latest.latest)) { 1474 this.debugger.log(`Missing manifest for latest version hash ${latest.latest}`, "initialize: read from DB"); 1475 throw new Error(`Missing manifest for latest hash ${latest.latest}`); 1476 } 1477 this.idle.schedule("init post-load (update)", async () => { 1478 await this.checkForUpdate(); 1479 }); 1480 } catch (_) { 1481 const manifest = await this.fetchLatestManifest(); 1482 const hash = hashManifest(manifest); 1483 manifests = { [hash]: manifest }; 1484 assignments = {}; 1485 latest = { latest: hash }; 1486 await Promise.all([ 1487 table.write("manifests", manifests), 1488 table.write("assignments", assignments), 1489 table.write("latest", latest) 1490 ]); 1491 } 1492 this.idle.schedule("init post-load (cleanup)", async () => { 1493 await this.cleanupCaches(); 1494 }); 1495 Object.keys(manifests).forEach((hash) => { 1496 const manifest = manifests[hash]; 1497 if (!this.versions.has(hash)) { 1498 this.versions.set(hash, new AppVersion(this.scope, this.adapter, this.db, this.idle, this.debugger, manifest, hash)); 1499 } 1500 }); 1501 Object.keys(assignments).forEach((clientId) => { 1502 const hash = assignments[clientId]; 1503 if (this.versions.has(hash)) { 1504 this.clientVersionMap.set(clientId, hash); 1505 } else { 1506 this.clientVersionMap.set(clientId, latest.latest); 1507 this.debugger.log(`Unknown version ${hash} mapped for client ${clientId}, using latest instead`, `initialize: map assignments`); 1508 } 1509 }); 1510 this.latestHash = latest.latest; 1511 if (!this.versions.has(latest.latest)) { 1512 throw new Error(`Invariant violated (initialize): latest hash ${latest.latest} has no known manifest`); 1513 } 1514 await Promise.all(Object.keys(manifests).map(async (hash) => { 1515 try { 1516 await this.scheduleInitialization(this.versions.get(hash)); 1517 } catch (err) { 1518 this.debugger.log(err, `initialize: schedule init of ${hash}`); 1519 return false; 1520 } 1521 })); 1522 } 1523 lookupVersionByHash(hash, debugName = "lookupVersionByHash") { 1524 if (!this.versions.has(hash)) { 1525 throw new Error(`Invariant violated (${debugName}): want AppVersion for ${hash} but not loaded`); 1526 } 1527 return this.versions.get(hash); 1528 } 1529 async assignVersion(event) { 1530 const clientId = event.resultingClientId || event.clientId; 1531 if (clientId) { 1532 if (this.clientVersionMap.has(clientId)) { 1533 const hash = this.clientVersionMap.get(clientId); 1534 let appVersion = this.lookupVersionByHash(hash, "assignVersion"); 1535 if (this.state === DriverReadyState.NORMAL && hash !== this.latestHash && appVersion.isNavigationRequest(event.request)) { 1536 if (this.latestHash === null) { 1537 throw new Error(`Invariant violated (assignVersion): latestHash was null`); 1538 } 1539 const client = await this.scope.clients.get(clientId); 1540 if (client) { 1541 await this.updateClient(client); 1542 } 1543 appVersion = this.lookupVersionByHash(this.latestHash, "assignVersion"); 1544 } 1545 return appVersion; 1546 } else { 1547 if (this.state !== DriverReadyState.NORMAL) { 1548 return null; 1549 } 1550 if (this.latestHash === null) { 1551 throw new Error(`Invariant violated (assignVersion): latestHash was null`); 1552 } 1553 this.clientVersionMap.set(clientId, this.latestHash); 1554 await this.sync(); 1555 return this.lookupVersionByHash(this.latestHash, "assignVersion"); 1556 } 1557 } else { 1558 if (this.state !== DriverReadyState.NORMAL) { 1559 return null; 1560 } 1561 if (this.latestHash === null) { 1562 throw new Error(`Invariant violated (assignVersion): latestHash was null`); 1563 } 1564 return this.lookupVersionByHash(this.latestHash, "assignVersion"); 1565 } 1566 } 1567 async fetchLatestManifest(ignoreOfflineError = false) { 1568 const res = await this.safeFetch(this.adapter.newRequest("ngsw.json?ngsw-cache-bust=" + Math.random())); 1569 if (!res.ok) { 1570 if (res.status === 404) { 1571 await this.deleteAllCaches(); 1572 await this.scope.registration.unregister(); 1573 } else if ((res.status === 503 || res.status === 504) && ignoreOfflineError) { 1574 return null; 1575 } 1576 throw new Error(`Manifest fetch failed! (status: ${res.status})`); 1577 } 1578 this.lastUpdateCheck = this.adapter.time; 1579 return res.json(); 1580 } 1581 async deleteAllCaches() { 1582 const cacheNames = await this.adapter.caches.keys(); 1583 await Promise.all(cacheNames.map((name) => this.adapter.caches.delete(name))); 1584 } 1585 async scheduleInitialization(appVersion) { 1586 const initialize = async () => { 1587 try { 1588 await appVersion.initializeFully(); 1589 } catch (err) { 1590 this.debugger.log(err, `initializeFully for ${appVersion.manifestHash}`); 1591 await this.versionFailed(appVersion, err); 1592 } 1593 }; 1594 if (this.scope.registration.scope.indexOf("://localhost") > -1) { 1595 return initialize(); 1596 } 1597 this.idle.schedule(`initialization(${appVersion.manifestHash})`, initialize); 1598 } 1599 async versionFailed(appVersion, err) { 1600 const broken = Array.from(this.versions.entries()).find(([hash, version]
1600) => version === appVersion); 1601 if (broken === void 0) { 1602 return; 1603 } 1604 const brokenHash = broken[0]; 1605 if (this.latestHash === brokenHash) { 1606 this.state = DriverReadyState.EXISTING_CLIENTS_ONLY; 1607 this.stateMessage = `Degraded due to: ${errorToString(err)}`; 1608 } 1609 } 1610 async setupUpdate(manifest, hash) { 1611 try { 1612 const newVersion = new AppVersion(this.scope, this.adapter, this.db, this.idle, this.debugger, manifest, hash); 1613 if (manifest.configVersion !== SUPPORTED_CONFIG_VERSION) { 1614 await this.deleteAllCaches(); 1615 await this.scope.registration.unregister(); 1616 throw new Error(`Invalid config version: expected ${SUPPORTED_CONFIG_VERSION}, got ${manifest.configVersion}.`); 1617 } 1618 await newVersion.initializeFully(this); 1619 this.versions.set(hash, newVersion); 1620 this.latestHash = hash; 1621 if (this.state === DriverReadyState.EXISTING_CLIENTS_ONLY) { 1622 this.state = DriverReadyState.NORMAL; 1623 this.stateMessage = "(nominal)"; 1624 } 1625 await this.sync(); 1626 await this.notifyClientsAboutVersionReady(manifest, hash); 1627 } catch (e) { 1628 await this.notifyClientsAboutVersionInstallationFailed(manifest, hash, e); 1629 throw e; 1630 } 1631 } 1632 async checkForUpdate() { 1633 let hash = "(unknown)"; 1634 try { 1635 const manifest = await this.fetchLatestManifest(true); 1636 if (manifest === null) { 1637 this.debugger.log("Check for update aborted. (Client or server offline.)"); 1638 return false; 1639 } 1640 hash = hashManifest(manifest); 1641 if (this.versions.has(hash)) { 1642 await this.notifyClientsAboutNoNewVersionDetected(manifest, hash); 1643 return false; 1644 } 1645 await this.notifyClientsAboutVersionDetected(manifest, hash); 1646 await this.setupUpdate(manifest, hash); 1647 return true; 1648 } catch (err) { 1649 this.debugger.log(err, `Error occurred while updating to manifest ${hash}`); 1650 this.state = DriverReadyState.EXISTING_CLIENTS_ONLY; 1651 this.stateMessage = `Degraded due to failed initialization: ${errorToString(err)}`; 1652 return false; 1653 } 1654 } 1655 async sync() { 1656 const table = await this.controlTable; 1657 const manifests = {}; 1658 this.versions.forEach((version, hash) => { 1659 manifests[hash] = version.manifest; 1660 }); 1661 const assignments = {}; 1662 this.clientVersionMap.forEach((hash, clientId) => { 1663 assignments[clientId] = hash; 1664 }); 1665 const latest = { 1666 latest: this.latestHash 1667 }; 1668 await Promise.all([ 1669 table.write("manifests", manifests), 1670 table.write("assignments", assignments), 1671 table.write("latest", latest) 1672 ]); 1673 } 1674 async cleanupCaches() { 1675 try { 1676 const activeClients = new Set((await this.scope.clients.matchAll()).map((client) => client.id)); 1677 const knownClients = Array.from(this.clientVersionMap.keys()); 1678 const obsoleteClients = knownClients.filter((id) => !activeClients.has(id)); 1679 obsoleteClients.forEach((id) => this.clientVersionMap.delete(id)); 1680 const usedVersions = new Set(this.clientVersionMap.values()); 1681 const obsoleteVersions = Array.from(this.versions.keys()).filter((version) => !usedVersions.has(version) && version !== this.latestHash); 1682 obsoleteVersions.forEach((version) => this.versions.delete(version)); 1683 await this.sync(); 1684 const allCaches = await this.adapter.caches.keys(); 1685 const usedCaches = new Set(await this.getCacheNames()); 1686 const cachesToDelete = allCaches.filter((name) => !usedCaches.has(name)); 1687 await Promise.all(cachesToDelete.map((name) => this.adapter.caches.delete(name))); 1688 } catch (err) { 1689 this.debugger.log(err, "cleanupCaches"); 1690 } 1691 } 1692 async cleanupOldSwCaches() { 1693 const caches = this.adapter.caches.original; 1694 const cacheNames = await caches.keys(); 1695 const oldSwCacheNames = cacheNames.filter((name) => /^ngsw:(?!\/)/.test(name)); 1696 await Promise.all(oldSwCacheNames.map((name) => caches.delete(name))); 1697 }
1698 lookupResourceWithHash(url, hash) { 1699 return Array.from(this.versions.values()).reduce(async (prev, version) => { 1700 if (await prev !== null) { 1701 return prev; 1702 } 1703 return version.lookupResourceWithHash(url, hash); 1704 }, Promise.resolve(null)); 1705 } 1706 async lookupResourceWithoutHash(url) { 1707 await this.initialized; 1708 const version = this.versions.get(this.latestHash); 1709 return version ? version.lookupResourceWithoutHash(url) : null; 1710 } 1711 async previouslyCachedResources() { 1712 await this.initialized; 1713 const version = this.versions.get(this.latestHash); 1714 return version ? version.previouslyCachedResources() : []; 1715 } 1716 async recentCacheStatus(url) { 1717 const version = this.versions.get(this.latestHash); 1718 return version ? version.recentCacheStatus(url) : UpdateCacheStatus.NOT_CACHED; 1719 } 1720 mergeHashWithAppData(manifest, hash) { 1721 return { 1722 hash, 1723 appData: manifest.appData 1724 }; 1725 } 1726 async notifyClientsAboutUnrecoverableState(appVersion, reason) { 1727 const broken = Array.from(this.versions.entries()).find(([hash, version]) => version === appVersion); 1728 if (broken === void 0) { 1729 return; 1730 } 1731 const brokenHash = broken[0]; 1732 const affectedClients = Array.from(this.clientVersionMap.entries()).filter(([clientId, hash]) => hash === brokenHash).map(([clientId]) => clientId); 1733 await Promise.all(affectedClients.map(async (clientId) => { 1734 const client = await this.scope.clients.get(clientId); 1735 if (client) { 1736 client.postMessage({ type: "UNRECOVERABLE_STATE", reason }); 1737 } 1738 })); 1739 } 1740 async notifyClientsAboutVersionInstallationFailed(manifest, hash, error) { 1741 await this.initialized; 1742 const clients = await this.scope.clients.matchAll(); 1743 await Promise.all(clients.map(async (client) => { 1744 client.postMessage({ 1745 type: "VERSION_INSTALLATION_FAILED", 1746 version: this.mergeHashWithAppData(manifest, hash), 1747 error: errorToString(error) 1748 }); 1749 })); 1750 } 1751 async notifyClientsAboutNoNewVersionDetected(manifest, hash) { 1752 await this.initialized; 1753 const clients = await this.scope.clients.matchAll(); 1754 await Promise.all(clients.map(async (client) => { 1755 client.postMessage({ type: "NO_NEW_VERSION_DETECTED", version: this.mergeHashWithAppData(manifest, hash) }); 1756 })); 1757 } 1758 async notifyClientsAboutVersionDetected(manifest, hash) { 1759 await this.initialized; 1760 const clients = await this.scope.clients.matchAll(); 1761 await Promise.all(clients.map(async (client) => { 1762 const version = this.clientVersionMap.get(client.id); 1763 if (version === void 0) { 1764 return; 1765 } 1766 client.postMessage({ type: "VERSION_DETECTED", version: this.mergeHashWithAppData(manifest, hash) }); 1767 })); 1768 } 1769 async notifyClientsAboutVersionReady(manifest, hash) { 1770 await this.initialized; 1771 const clients = await this.scope.clients.matchAll(); 1772 await Promise.all(clients.map(async (client) => { 1773 const version = this.clientVersionMap.get(client.id); 1774 if (version === void 0) { 1775 return; 1776 } 1777 if (version === this.latestHash) { 1778 return; 1779 } 1780 const current = this.versions.get(version); 1781 const notice = { 1782 type: "VERSION_READY", 1783 currentVersion: this.mergeHashWithAppData(current.manifest, version), 1784 latestVersion: this.mergeHashWithAppData(manifest, hash) 1785 }; 1786 client.postMessage(notice); 1787 })); 1788 } 1789 async broadcast(msg) { 1790 const clients = await this.scope.clients.matchAll(); 1791 clients.forEach((client) => { 1792 client.postMessage(msg); 1793 }); 1794 } 1795 async debugState() { 1796 return { 1797 state: DriverReadyState[this.state], 1798 why: this.stateMessage, 1799 latestHash: this.latestHash, 1800 lastUpdateCheck: this.lastUpdateCheck 1801 }; 1802 } 1803 async debugVersions() { 1804 return Array.from(this.versions.keys()).map((hash) => { 1805 const version = this.versions.get(hash); 1806 const clients = Array.from(this.clientVersionMap.entries()).filter(([clientId, version2]) => version2 === hash).map(([clientId, version2]) => clientId); 1807 return { 1808 hash, 1809 manifest: version.manifest, 1810 clients, 1811 status: "" 1812 }; 1813 }); 1814 } 1815 async debugIdleState() { 1816 return { 1817 queue: this.idle.taskDescriptions, 1818 lastTrigger: this.idle.lastTrigger, 1819 lastRun: this.idle.lastRun 1820 }; 1821 } 1822 async safeFetch(req) {
1823 try { 1824 return await this.scope.fetch(req); 1825 } catch (err) { 1826 this.debugger.log(err, `Driver.fetch(${req.url})`); 1827 return this.adapter.newResponse(null, { 1828 status: 504, 1829 statusText: "Gateway Timeout" 1830 }); 1831 } 1832 } 1833 async getCacheNames() { 1834 const controlTable = await this.controlTable; 1835 const appVersions = Array.from(this.versions.values()); 1836 const appVersionCacheNames = await Promise.all(appVersions.map((version) => version.getCacheNames())); 1837 return [controlTable.cacheName].concat(...appVersionCacheNames); 1838 } 1839 }; 1840 1841
1841// bazel-out/k8-fastbuild-ST-2e5f3376adb5/bin/packages/service-worker/worker/main.mjs 1842 var scope = self; 1843 var adapter = new Adapter(scope.registration.scope, self.caches); 1844 new Driver(scope, adapter, new CacheDatabase(adapter)); 1845})(); 1846/** 1847 * @license 1848 * Copyright Google LLC All Rights Reserved. 1849 * 1850 * Use of this source code is governed by an MIT-style license that can be 1851 * found in the LICENSE file at https://angular.io/license 1852 */
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.