Brunobkr/llama.cpp_AlgMor24_github
ΩFFFΣLLIa • llama.cpp • AlgMor24 ██████╗ ███████╗███████╗███████╗██╗ ██╗ ██╗ █████╗ ██╔═══██╗██╔════╝██╔════╝██╔════╝██║ ██║ ██║██╔══██╗ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║███████║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║██╔══██║ ╚██████╔╝██║ ██║ ███████╗███████╗███████╗██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ High-Performance LLM / VLM Inference & Autonomous Agentic Ecosystem… See the full description on the dataset page: https://huggingface.co/datasets/Brunobkr/llama.cpp_AlgMor24_github.
03.1k
1this.workbox = this.workbox || {};2this.workbox.expiration = (function (exports, assert_js, dontWaitFor_js, logger_js, WorkboxError_js, cacheNames_js, getFriendlyURL_js, registerQuotaErrorCallback_js) {3 'use strict';4 5 function _extends() {6 return _extends = Object.assign ? Object.assign.bind() : function (n) {7 for (var e = 1; e < arguments.length; e++) {8 var t = arguments[e];9 for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);10 }11 return n;12 }, _extends.apply(null, arguments);13 }14 15 const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);16 let idbProxyableTypes;17 let cursorAdvanceMethods;18 // This is a function to prevent it throwing up in node environments.19 function getIdbProxyableTypes() {20 return idbProxyableTypes || (idbProxyableTypes = [IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction]);21 }22 // This is a function to prevent it throwing up in node environments.23 function getCursorAdvanceMethods() {24 return cursorAdvanceMethods || (cursorAdvanceMethods = [IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey]);25 }26 const cursorRequestMap = new WeakMap();27 const transactionDoneMap = new WeakMap();28 const transactionStoreNamesMap = new WeakMap();29 const transformCache = new WeakMap();30 const reverseTransformCache = new WeakMap();31 function promisifyRequest(request) {32 const promise = new Promise((resolve, reject) => {33 const unlisten = () => {34 request.removeEventListener('success', success);35 request.removeEventListener('error', error);36 };37 const success = () => {38 resolve(wrap(request.result));39 unlisten();40 };41 const error = () => {42 reject(request.error);43 unlisten();44 };45 request.addEventListener('success', success);46 request.addEventListener('error', error);47 });48 promise.then(value => {49 // Since cursoring reuses the IDBRequest (*sigh*), we cache it for later retrieval50 // (see wrapFunction).51 if (value instanceof IDBCursor) {52 cursorRequestMap.set(value, request);53 }54 // Catching to avoid "Uncaught Promise exceptions"55 }).catch(() => {});56 // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This57 // is because we create many promises from a single IDBRequest.58 reverseTransformCache.set(promise, request);59 return promise;60 }61 function cacheDonePromiseForTransaction(tx) {62 // Early bail if we've already created a done promise for this transaction.63 if (transactionDoneMap.has(tx)) return;64 const done = new Promise((resolve, reject) => {65 const unlisten = () => {66 tx.removeEventListener('complete', complete);67 tx.removeEventListener('error', error);68 tx.removeEventListener('abort', error);69 };70 const complete = () => {71 resolve();72 unlisten();73 };74 const error = () => {75 reject(tx.error || new DOMException('AbortError', 'AbortError'));76 unlisten();77 };78 tx.addEventListener('complete', complete);79 tx.addEventListener('error', error);80 tx.addEventListener('abort', error);81 });82 // Cache it for later retrieval.83 transactionDoneMap.set(tx, done);84 }85 let idbProxyTraps = {86 get(target, prop, receiver) {87 if (target instanceof IDBTransaction) {88 // Special handling for transaction.done.89 if (prop === 'done') return transactionDoneMap.get(target);90 // Polyfill for objectStoreNames because of Edge.91 if (prop === 'objectStoreNames') {92 return target.objectStoreNames || transactionStoreNamesMap.get(target);93 }94 // Make tx.store return the only store in the transaction, or undefined if there are many.95 if (prop === 'store') {96 return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]);97 }98 }99 // Else transform whatever we get back.100 return wrap(target[prop]);101 },102 set(target, prop, value) {103 target[prop] = value;104 return true;105 },106 has(target, prop) {107 if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) {108 return true;109 }110 return prop in target;111 }112 };113 function replaceTraps(callback) {114 idbProxyTraps = callback(idbProxyTraps);115 }116 function wrapFunction(func) {117 // Due to expected object equality (which is enforced by the caching in `wrap`), we118 // only create one new func per func.119 // Edge doesn't support objectStoreNames (booo), so we polyfill it here.120 if (func === IDBDatabase.prototype.transaction && !('objectStoreNames' in IDBTransaction.prototype)) {121 return function (storeNames, ...args) {122 const tx = func.call(unwrap(this), storeNames, ...args);123 transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);124 return wrap(tx);125 };126 }127 // Cursor methods are special, as the behaviour is a little more different to standard IDB. In128 // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the129 // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense130 // with real promises, so each advance methods returns a new promise for the cursor object, or131 // undefined if the end of the cursor has been reached.132 if (getCursorAdvanceMethods().includes(func)) {133 return function (...args) {134 // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use135 // the original object.136 func.apply(unwrap(this), args);137 return wrap(cursorRequestMap.get(this));138 };139 }140 return function (...args) {141 // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use142 // the original object.143 return wrap(func.apply(unwrap(this), args));144 };145 }146 function transformCachableValue(value) {147 if (typeof value === 'function') return wrapFunction(value);148 // This doesn't return, it just creates a 'done' promise for the transaction,149 // which is later returned for transaction.done (see idbObjectHandler).150 if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value);151 if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps);152 // Return the same value back if we're not going to transform it.153 return value;154 }155 function wrap(value) {156 // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because157 // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.158 if (value instanceof IDBRequest) return promisifyRequest(value);159 // If we've already transformed this value before, reuse the transformed value.160 // This is faster, but it also provides object equality.161 if (transformCache.has(value)) return transformCache.get(value);162 const newValue = transformCachableValue(value);163 // Not all types are transformed.164 // These may be primitive types, so they can't be WeakMap keys.165 if (newValue !== value) {166 transformCache.set(value, newValue);167 reverseTransformCache.set(newValue, value);168 }169 return newValue;170 }171 const unwrap = value => reverseTransformCache.get(value);172 173 /**174 * Open a database.175 *176 * @param name Name of the database.177 * @param version Schema version.178 * @param callbacks Additional callbacks.179 */180 function openDB(name, version, {181 blocked,182 upgrade,183 blocking,184 terminated185 } = {}) {186 const request = indexedDB.open(name, version);187 const openPromise = wrap(request);188 if (upgrade) {189 request.addEventListener('upgradeneeded', event => {190 upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction));191 });192 }193 if (blocked) request.addEventListener('blocked', () => blocked());194 openPromise.then(db => {195 if (terminated) db.addEventListener('close', () => terminated());196 if (blocking) db.addEventListener('versionchange', () => blocking());197 }).catch(() => {});198 return openPromise;199 }200 /**201 * Delete a database.202 *203 * @param name Name of the database.204 */205 function deleteDB(name, {206 blocked207 } = {}) {208 const request = indexedDB.deleteDatabase(name);209 if (blocked) request.addEventListener('blocked', () => blocked());210 return wrap(request).then(() => undefined);211 }212 const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];213 const writeMethods = ['put', 'add', 'delete', 'clear'];214 const cachedMethods = new Map();215 function getMethod(target, prop) {216 if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) {217 return;218 }219 if (cachedMethods.get(prop)) return cachedMethods.get(prop);220 const targetFuncName = prop.replace(/FromIndex$/, '');221 const useIndex = prop !== targetFuncName;222 const isWrite = writeMethods.includes(targetFuncName);223 if (224 // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.225 !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) {226 return;227 }228 const method = async function (storeName, ...args) {229 // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(230 const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');231 let target = tx.store;232 if (useIndex) target = target.index(args.shift());233 // Must reject if op rejects.234 // If it's a write operation, must reject if tx.done rejects.235 // Must reject with op rejection first.236 // Must resolve with op value.237 // Must handle both promises (no unhandled rejections)238 return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0];239 };240 cachedMethods.set(prop, method);241 return method;242 }243 replaceTraps(oldTraps => _extends({}, oldTraps, {244 get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),245 has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)246 }));247 248 // @ts-ignore249 try {250 self['workbox:expiration:7.4.0'] && _();251 } catch (e) {}252 253 /*254 Copyright 2018 Google LLC255 256 Use of this source code is governed by an MIT-style257 license that can be found in the LICENSE file or at258 https://opensource.org/licenses/MIT.259 */260 const DB_NAME = 'workbox-expiration';261 const CACHE_OBJECT_STORE = 'cache-entries';262 const normalizeURL = unNormalizedUrl => {263 const url = new URL(unNormalizedUrl, location.href);264 url.hash = '';265 return url.href;266 };267 /**268 * Returns the timestamp model.269 *270 * @private271 */272 class CacheTimestampsModel {273 /**274 *275 * @param {string} cacheName276 *277 * @private278 */279 constructor(cacheName) {280 this._db = null;281 this._cacheName = cacheName;282 }283 /**284 * Performs an upgrade of indexedDB.285 *286 * @param {IDBPDatabase<CacheDbSchema>} db287 *288 * @private289 */290 _upgradeDb(db) {291 // TODO(philipwalton): EdgeHTML doesn't support arrays as a keyPath, so we292 // have to use the `id` keyPath here and create our own values (a293 // concatenation of `url + cacheName`) instead of simply using294 // `keyPath: ['url', 'cacheName']`, which is supported in other browsers.295 const objStore = db.createObjectStore(CACHE_OBJECT_STORE, {296 keyPath: 'id'297 });298 // TODO(philipwalton): once we don't have to support EdgeHTML, we can299 // create a single index with the keyPath `['cacheName', 'timestamp']`300 // instead of doing both these indexes.301 objStore.createIndex('cacheName', 'cacheName', {302 unique: false303 });304 objStore.createIndex('timestamp', 'timestamp', {305 unique: false306 });307 }308 /**309 * Performs an upgrade of indexedDB and deletes deprecated DBs.310 *311 * @param {IDBPDatabase<CacheDbSchema>} db312 *313 * @private314 */315 _upgradeDbAndDeleteOldDbs(db) {316 this._upgradeDb(db);317 if (this._cacheName) {318 void deleteDB(this._cacheName);319 }320 }321 /**322 * @param {string} url323 * @param {number} timestamp324 *325 * @private326 */327 async setTimestamp(url, timestamp) {328 url = normalizeURL(url);329 const entry = {330 url,331 timestamp,332 cacheName: this._cacheName,333 // Creating an ID from the URL and cache name won't be necessary once334 // Edge switches to Chromium and all browsers we support work with335 // array keyPaths.336 id: this._getId(url)337 };338 const db = await this.getDb();339 const tx = db.transaction(CACHE_OBJECT_STORE, 'readwrite', {340 durability: 'relaxed'341 });342 await tx.store.put(entry);343 await tx.done;344 }345 /**346 * Returns the timestamp stored for a given URL.347 *348 * @param {string} url349 * @return {number | undefined}350 *351 * @private352 */353 async getTimestamp(url) {354 const db = await this.getDb();355 const entry = await db.get(CACHE_OBJECT_STORE, this._getId(url));356 return entry === null || entry === void 0 ? void 0 : entry.timestamp;357 }358 /**359 * Iterates through all the entries in the object store (from newest to360 * oldest) and removes entries once either `maxCount` is reached or the361 * entry's timestamp is less than `minTimestamp`.362 *363 * @param {number} minTimestamp364 * @param {number} maxCount365 * @return {Array<string>}366 *367 * @private368 */369 async expireEntries(minTimestamp, maxCount) {370 const db = await this.getDb();371 let cursor = await db.transaction(CACHE_OBJECT_STORE).store.index('timestamp').openCursor(null, 'prev');372 const entriesToDelete = [];373 let entriesNotDeletedCount = 0;374 while (cursor) {375 const result = cursor.value;376 // TODO(philipwalton): once we can use a multi-key index, we377 // won't have to check `cacheName` here.378 if (result.cacheName === this._cacheName) {379 // Delete an entry if it's older than the max age or380 // if we already have the max number allowed.381 if (minTimestamp && result.timestamp < minTimestamp || maxCount && entriesNotDeletedCount >= maxCount) {382 // TODO(philipwalton): we should be able to delete the383 // entry right here, but doing so causes an iteration384 // bug in Safari stable (fixed in TP). Instead we can385 // store the keys of the entries to delete, and then386 // delete the separate transactions.387 // https://github.com/GoogleChrome/workbox/issues/1978388 // cursor.delete();389 // We only need to return the URL, not the whole entry.390 entriesToDelete.push(cursor.value);391 } else {392 entriesNotDeletedCount++;393 }394 }395 cursor = await cursor.continue();396 }397 // TODO(philipwalton): once the Safari bug in the following issue is fixed,398 // we should be able to remove this loop and do the entry deletion in the399 // cursor loop above:400 // https://github.com/GoogleChrome/workbox/issues/1978401 const urlsDeleted = [];402 for (const entry of entriesToDelete) {403 await db.delete(CACHE_OBJECT_STORE, entry.id);404 urlsDeleted.push(entry.url);405 }406 return urlsDeleted;407 }408 /**409 * Takes a URL and returns an ID that will be unique in the object store.410 *411 * @param {string} url412 * @return {string}413 *414 * @private415 */416 _getId(url) {417 // Creating an ID from the URL and cache name won't be necessary once418 // Edge switches to Chromium and all browsers we support work with419 // array keyPaths.420 return this._cacheName + '|' + normalizeURL(url);421 }422 /**423 * Returns an open connection to the database.424 *425 * @private426 */427 async getDb() {428 if (!this._db) {429 this._db = await openDB(DB_NAME, 1, {430 upgrade: this._upgradeDbAndDeleteOldDbs.bind(this)431 });432 }433 return this._db;434 }435 }436 437 /*438 Copyright 2018 Google LLC439 440 Use of this source code is governed by an MIT-style441 license that can be found in the LICENSE file or at442 https://opensource.org/licenses/MIT.443 */444 /**445 * The `CacheExpiration` class allows you define an expiration and / or446 * limit on the number of responses stored in a447 * [`Cache`](https://developer.mozilla.org/en-US/docs/Web/API/Cache).448 *449 * @memberof workbox-expiration450 */451 class CacheExpiration {452 /**453 * To construct a new CacheExpiration instance you must provide at least454 * one of the `config` properties.455 *456 * @param {string} cacheName Name of the cache to apply restrictions to.457 * @param {Object} config458 * @param {number} [config.maxEntries] The maximum number of entries to cache.459 * Entries used the least will be removed as the maximum is reached.460 * @param {number} [config.maxAgeSeconds] The maximum age of an entry before461 * it's treated as stale and removed.462 * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters)463 * that will be used when calling `delete()` on the cache.464 */465 constructor(cacheName, config = {}) {466 this._isRunning = false;467 this._rerunRequested = false;468 {469 assert_js.assert.isType(cacheName, 'string', {470 moduleName: 'workbox-expiration',471 className: 'CacheExpiration',472 funcName: 'constructor',473 paramName: 'cacheName'474 });475 if (!(config.maxEntries || config.maxAgeSeconds)) {476 throw new WorkboxError_js.WorkboxError('max-entries-or-age-required', {477 moduleName: 'workbox-expiration',478 className: 'CacheExpiration',479 funcName: 'constructor'480 });481 }482 if (config.maxEntries) {483 assert_js.assert.isType(config.maxEntries, 'number', {484 moduleName: 'workbox-expiration',485 className: 'CacheExpiration',486 funcName: 'constructor',487 paramName: 'config.maxEntries'488 });489 }490 if (config.maxAgeSeconds) {491 assert_js.assert.isType(config.maxAgeSeconds, 'number', {492 moduleName: 'workbox-expiration',493 className: 'CacheExpiration',494 funcName: 'constructor',495 paramName: 'config.maxAgeSeconds'496 });497 }498 }499 this._maxEntries = config.maxEntries;500 this._maxAgeSeconds = config.maxAgeSeconds;501 this._matchOptions = config.matchOptions;502 this._cacheName = cacheName;503 this._timestampModel = new CacheTimestampsModel(cacheName);504 }505 /**506 * Expires entries for the given cache and given criteria.507 */508 async expireEntries() {509 if (this._isRunning) {510 this._rerunRequested = true;511 return;512 }513 this._isRunning = true;514 const minTimestamp = this._maxAgeSeconds ? Date.now() - this._maxAgeSeconds * 1000 : 0;515 const urlsExpired = await this._timestampModel.expireEntries(minTimestamp, this._maxEntries);516 // Delete URLs from the cache517 const cache = await self.caches.open(this._cacheName);518 for (const url of urlsExpired) {519 await cache.delete(url, this._matchOptions);520 }521 {522 if (urlsExpired.length > 0) {523 logger_js.logger.groupCollapsed(`Expired ${urlsExpired.length} ` + `${urlsExpired.length === 1 ? 'entry' : 'entries'} and removed ` + `${urlsExpired.length === 1 ? 'it' : 'them'} from the ` + `'${this._cacheName}' cache.`);524 logger_js.logger.log(`Expired the following ${urlsExpired.length === 1 ? 'URL' : 'URLs'}:`);525 urlsExpired.forEach(url => logger_js.logger.log(` ${url}`));526 logger_js.logger.groupEnd();527 } else {528 logger_js.logger.debug(`Cache expiration ran and found no entries to remove.`);529 }530 }531 this._isRunning = false;532 if (this._rerunRequested) {533 this._rerunRequested = false;534 dontWaitFor_js.dontWaitFor(this.expireEntries());535 }536 }537 /**538 * Update the timestamp for the given URL. This ensures the when539 * removing entries based on maximum entries, most recently used540 * is accurate or when expiring, the timestamp is up-to-date.541 *542 * @param {string} url543 */544 async updateTimestamp(url) {545 {546 assert_js.assert.isType(url, 'string', {547 moduleName: 'workbox-expiration',548 className: 'CacheExpiration',549 funcName: 'updateTimestamp',550 paramName: 'url'551 });552 }553 await this._timestampModel.setTimestamp(url, Date.now());554 }555 /**556 * Can be used to check if a URL has expired or not before it's used.557 *558 * This requires a look up from IndexedDB, so can be slow.559 *560 * Note: This method will not remove the cached entry, call561 * `expireEntries()` to remove indexedDB and Cache entries.562 *563 * @param {string} url564 * @return {boolean}565 */566 async isURLExpired(url) {567 if (!this._maxAgeSeconds) {568 {569 throw new WorkboxError_js.WorkboxError(`expired-test-without-max-age`, {570 methodName: 'isURLExpired',571 paramName: 'maxAgeSeconds'572 });573 }574 } else {575 const timestamp = await this._timestampModel.getTimestamp(url);576 const expireOlderThan = Date.now() - this._maxAgeSeconds * 1000;577 return timestamp !== undefined ? timestamp < expireOlderThan : true;578 }579 }580 /**581 * Removes the IndexedDB object store used to keep track of cache expiration582 * metadata.583 */584 async delete() {585 // Make sure we don't attempt another rerun if we're called in the middle of586 // a cache expiration.587 this._rerunRequested = false;588 await this._timestampModel.expireEntries(Infinity); // Expires all.589 }590 }591 592 /*593 Copyright 2018 Google LLC594 595 Use of this source code is governed by an MIT-style596 license that can be found in the LICENSE file or at597 https://opensource.org/licenses/MIT.598 */599 /**600 * This plugin can be used in a `workbox-strategy` to regularly enforce a601 * limit on the age and / or the number of cached requests.602 *603 * It can only be used with `workbox-strategy` instances that have a604 * [custom `cacheName` property set](/web/tools/workbox/guides/configure-workbox#custom_cache_names_in_strategies).605 * In other words, it can't be used to expire entries in strategy that uses the606 * default runtime cache name.607 *608 * Whenever a cached response is used or updated, this plugin will look609 * at the associated cache and remove any old or extra responses.610 *611 * When using `maxAgeSeconds`, responses may be used *once* after expiring612 * because the expiration clean up will not have occurred until *after* the613 * cached response has been used. If the response has a "Date" header, then614 * a light weight expiration check is performed and the response will not be615 * used immediately.616 *617 * When using `maxEntries`, the entry least-recently requested will be removed618 * from the cache first.619 *620 * @memberof workbox-expiration621 */622 class ExpirationPlugin {623 /**624 * @param {ExpirationPluginOptions} config625 * @param {number} [config.maxEntries] The maximum number of entries to cache.626 * Entries used the least will be removed as the maximum is reached.627 * @param {number} [config.maxAgeSeconds] The maximum age of an entry before628 * it's treated as stale and removed.629 * @param {Object} [config.matchOptions] The [`CacheQueryOptions`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/delete#Parameters)630 * that will be used when calling `delete()` on the cache.631 * @param {boolean} [config.purgeOnQuotaError] Whether to opt this cache in to632 * automatic deletion if the available storage quota has been exceeded.633 */634 constructor(config = {}) {635 /**636 * A "lifecycle" callback that will be triggered automatically by the637 * `workbox-strategies` handlers when a `Response` is about to be returned638 * from a [Cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache) to639 * the handler. It allows the `Response` to be inspected for freshness and640 * prevents it from being used if the `Response`'s `Date` header value is641 * older than the configured `maxAgeSeconds`.642 *643 * @param {Object} options644 * @param {string} options.cacheName Name of the cache the response is in.645 * @param {Response} options.cachedResponse The `Response` object that's been646 * read from a cache and whose freshness should be checked.647 * @return {Response} Either the `cachedResponse`, if it's648 * fresh, or `null` if the `Response` is older than `maxAgeSeconds`.649 *650 * @private651 */652 this.cachedResponseWillBeUsed = async ({653 event,654 request,655 cacheName,656 cachedResponse657 }) => {658 if (!cachedResponse) {659 return null;660 }661 const isFresh = this._isResponseDateFresh(cachedResponse);662 // Expire entries to ensure that even if the expiration date has663 // expired, it'll only be used once.664 const cacheExpiration = this._getCacheExpiration(cacheName);665 dontWaitFor_js.dontWaitFor(cacheExpiration.expireEntries());666 // Update the metadata for the request URL to the current timestamp,667 // but don't `await` it as we don't want to block the response.668 const updateTimestampDone = cacheExpiration.updateTimestamp(request.url);669 if (event) {670 try {671 event.waitUntil(updateTimestampDone);672 } catch (error) {673 {674 // The event may not be a fetch event; only log the URL if it is.675 if ('request' in event) {676 logger_js.logger.warn(`Unable to ensure service worker stays alive when ` + `updating cache entry for ` + `'${getFriendlyURL_js.getFriendlyURL(event.request.url)}'.`);677 }678 }679 }680 }681 return isFresh ? cachedResponse : null;682 };683 /**684 * A "lifecycle" callback that will be triggered automatically by the685 * `workbox-strategies` handlers when an entry is added to a cache.686 *687 * @param {Object} options688 * @param {string} options.cacheName Name of the cache that was updated.689 * @param {string} options.request The Request for the cached entry.690 *691 * @private692 */693 this.cacheDidUpdate = async ({694 cacheName,695 request696 }) => {697 {698 assert_js.assert.isType(cacheName, 'string', {699 moduleName: 'workbox-expiration',700 className: 'Plugin',701 funcName: 'cacheDidUpdate',702 paramName: 'cacheName'703 });704 assert_js.assert.isInstance(request, Request, {705 moduleName: 'workbox-expiration',706 className: 'Plugin',707 funcName: 'cacheDidUpdate',708 paramName: 'request'709 });710 }711 const cacheExpiration = this._getCacheExpiration(cacheName);712 await cacheExpiration.updateTimestamp(request.url);713 await cacheExpiration.expireEntries();714 };715 {716 if (!(config.maxEntries || config.maxAgeSeconds)) {717 throw new WorkboxError_js.WorkboxError('max-entries-or-age-required', {718 moduleName: 'workbox-expiration',719 className: 'Plugin',720 funcName: 'constructor'721 });722 }723 if (config.maxEntries) {724 assert_js.assert.isType(config.maxEntries, 'number', {725 moduleName: 'workbox-expiration',726 className: 'Plugin',727 funcName: 'constructor',728 paramName: 'config.maxEntries'729 });730 }731 if (config.maxAgeSeconds) {732 assert_js.assert.isType(config.maxAgeSeconds, 'number', {733 moduleName: 'workbox-expiration',734 className: 'Plugin',735 funcName: 'constructor',736 paramName: 'config.maxAgeSeconds'737 });738 }739 }740 this._config = config;741 this._maxAgeSeconds = config.maxAgeSeconds;742 this._cacheExpirations = new Map();743 if (config.purgeOnQuotaError) {744 registerQuotaErrorCallback_js.registerQuotaErrorCallback(() => this.deleteCacheAndMetadata());745 }746 }747 /**748 * A simple helper method to return a CacheExpiration instance for a given749 * cache name.750 *751 * @param {string} cacheName752 * @return {CacheExpiration}753 *754 * @private755 */756 _getCacheExpiration(cacheName) {757 if (cacheName === cacheNames_js.cacheNames.getRuntimeName()) {758 throw new WorkboxError_js.WorkboxError('expire-custom-caches-only');759 }760 let cacheExpiration = this._cacheExpirations.get(cacheName);761 if (!cacheExpiration) {762 cacheExpiration = new CacheExpiration(cacheName, this._config);763 this._cacheExpirations.set(cacheName, cacheExpiration);764 }765 return cacheExpiration;766 }767 /**768 * @param {Response} cachedResponse769 * @return {boolean}770 *771 * @private772 */773 _isResponseDateFresh(cachedResponse) {774 if (!this._maxAgeSeconds) {775 // We aren't expiring by age, so return true, it's fresh776 return true;777 }778 // Check if the 'date' header will suffice a quick expiration check.779 // See https://github.com/GoogleChromeLabs/sw-toolbox/issues/164 for780 // discussion.781 const dateHeaderTimestamp = this._getDateHeaderTimestamp(cachedResponse);782 if (dateHeaderTimestamp === null) {783 // Unable to parse date, so assume it's fresh.784 return true;785 }786 // If we have a valid headerTime, then our response is fresh iff the787 // headerTime plus maxAgeSeconds is greater than the current time.788 const now = Date.now();789 return dateHeaderTimestamp >= now - this._maxAgeSeconds * 1000;790 }791 /**792 * This method will extract the data header and parse it into a useful793 * value.794 *795 * @param {Response} cachedResponse796 * @return {number|null}797 *798 * @private799 */800 _getDateHeaderTimestamp(cachedResponse) {801 if (!cachedResponse.headers.has('date')) {802 return null;803 }804 const dateHeader = cachedResponse.headers.get('date');805 const parsedDate = new Date(dateHeader);806 const headerTime = parsedDate.getTime();807 // If the Date header was invalid for some reason, parsedDate.getTime()808 // will return NaN.809 if (isNaN(headerTime)) {810 return null;811 }812 return headerTime;813 }814 /**815 * This is a helper method that performs two operations:816 *817 * - Deletes *all* the underlying Cache instances associated with this plugin818 * instance, by calling caches.delete() on your behalf.819 * - Deletes the metadata from IndexedDB used to keep track of expiration820 * details for each Cache instance.821 *822 * When using cache expiration, calling this method is preferable to calling823 * `caches.delete()` directly, since this will ensure that the IndexedDB824 * metadata is also cleanly removed and open IndexedDB instances are deleted.825 *826 * Note that if you're *not* using cache expiration for a given cache, calling827 * `caches.delete()` and passing in the cache's name should be sufficient.828 * There is no Workbox-specific method needed for cleanup in that case.829 */830 async deleteCacheAndMetadata() {831 // Do this one at a time instead of all at once via `Promise.all()` to832 // reduce the chance of inconsistency if a promise rejects.833 for (const [cacheName, cacheExpiration] of this._cacheExpirations) {834 await self.caches.delete(cacheName);835 await cacheExpiration.delete();836 }837 // Reset this._cacheExpirations to its initial state.838 this._cacheExpirations = new Map();839 }840 }841 842 exports.CacheExpiration = CacheExpiration;843 exports.ExpirationPlugin = ExpirationPlugin;844 845 return exports;846 847})({}, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core);848//# sourceMappingURL=workbox-expiration.dev.js.map849 