{"version":3,"file":"workbox-background-sync.prod.js","sources":["../node_modules/idb/build/wrap-idb-value.js","../node_modules/idb/build/index.js","../_version.js","../lib/QueueDb.js","../lib/QueueStore.js","../lib/StorableRequest.js","../Queue.js","../BackgroundSyncPlugin.js"],"sourcesContent":["const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);\n\nlet idbProxyableTypes;\nlet cursorAdvanceMethods;\n// This is a function to prevent it throwing up in node environments.\nfunction getIdbProxyableTypes() {\n    return (idbProxyableTypes ||\n        (idbProxyableTypes = [\n            IDBDatabase,\n            IDBObjectStore,\n            IDBIndex,\n            IDBCursor,\n            IDBTransaction,\n        ]));\n}\n// This is a function to prevent it throwing up in node environments.\nfunction getCursorAdvanceMethods() {\n    return (cursorAdvanceMethods ||\n        (cursorAdvanceMethods = [\n            IDBCursor.prototype.advance,\n            IDBCursor.prototype.continue,\n            IDBCursor.prototype.continuePrimaryKey,\n        ]));\n}\nconst cursorRequestMap = new WeakMap();\nconst transactionDoneMap = new WeakMap();\nconst transactionStoreNamesMap = new WeakMap();\nconst transformCache = new WeakMap();\nconst reverseTransformCache = new WeakMap();\nfunction promisifyRequest(request) {\n    const promise = new Promise((resolve, reject) => {\n        const unlisten = () => {\n            request.removeEventListener('success', success);\n            request.removeEventListener('error', error);\n        };\n        const success = () => {\n            resolve(wrap(request.result));\n            unlisten();\n        };\n        const error = () => {\n            reject(request.error);\n            unlisten();\n        };\n        request.addEventListener('success', success);\n        request.addEventListener('error', error);\n    });\n    promise\n        .then((value) => {\n        // Since cursoring reuses the IDBRequest (*sigh*), we cache it for later retrieval\n        // (see wrapFunction).\n        if (value instanceof IDBCursor) {\n            cursorRequestMap.set(value, request);\n        }\n        // Catching to avoid \"Uncaught Promise exceptions\"\n    })\n        .catch(() => { });\n    // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This\n    // is because we create many promises from a single IDBRequest.\n    reverseTransformCache.set(promise, request);\n    return promise;\n}\nfunction cacheDonePromiseForTransaction(tx) {\n    // Early bail if we've already created a done promise for this transaction.\n    if (transactionDoneMap.has(tx))\n        return;\n    const done = new Promise((resolve, reject) => {\n        const unlisten = () => {\n            tx.removeEventListener('complete', complete);\n            tx.removeEventListener('error', error);\n            tx.removeEventListener('abort', error);\n        };\n        const complete = () => {\n            resolve();\n            unlisten();\n        };\n        const error = () => {\n            reject(tx.error || new DOMException('AbortError', 'AbortError'));\n            unlisten();\n        };\n        tx.addEventListener('complete', complete);\n        tx.addEventListener('error', error);\n        tx.addEventListener('abort', error);\n    });\n    // Cache it for later retrieval.\n    transactionDoneMap.set(tx, done);\n}\nlet idbProxyTraps = {\n    get(target, prop, receiver) {\n        if (target instanceof IDBTransaction) {\n            // Special handling for transaction.done.\n            if (prop === 'done')\n                return transactionDoneMap.get(target);\n            // Polyfill for objectStoreNames because of Edge.\n            if (prop === 'objectStoreNames') {\n                return target.objectStoreNames || transactionStoreNamesMap.get(target);\n            }\n            // Make tx.store return the only store in the transaction, or undefined if there are many.\n            if (prop === 'store') {\n                return receiver.objectStoreNames[1]\n                    ? undefined\n                    : receiver.objectStore(receiver.objectStoreNames[0]);\n            }\n        }\n        // Else transform whatever we get back.\n        return wrap(target[prop]);\n    },\n    set(target, prop, value) {\n        target[prop] = value;\n        return true;\n    },\n    has(target, prop) {\n        if (target instanceof IDBTransaction &&\n            (prop === 'done' || prop === 'store')) {\n            return true;\n        }\n        return prop in target;\n    },\n};\nfunction replaceTraps(callback) {\n    idbProxyTraps = callback(idbProxyTraps);\n}\nfunction wrapFunction(func) {\n    // Due to expected object equality (which is enforced by the caching in `wrap`), we\n    // only create one new func per func.\n    // Edge doesn't support objectStoreNames (booo), so we polyfill it here.\n    if (func === IDBDatabase.prototype.transaction &&\n        !('objectStoreNames' in IDBTransaction.prototype)) {\n        return function (storeNames, ...args) {\n            const tx = func.call(unwrap(this), storeNames, ...args);\n            transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);\n            return wrap(tx);\n        };\n    }\n    // Cursor methods are special, as the behaviour is a little more different to standard IDB. In\n    // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the\n    // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense\n    // with real promises, so each advance methods returns a new promise for the cursor object, or\n    // undefined if the end of the cursor has been reached.\n    if (getCursorAdvanceMethods().includes(func)) {\n        return function (...args) {\n            // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n            // the original object.\n            func.apply(unwrap(this), args);\n            return wrap(cursorRequestMap.get(this));\n        };\n    }\n    return function (...args) {\n        // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n        // the original object.\n        return wrap(func.apply(unwrap(this), args));\n    };\n}\nfunction transformCachableValue(value) {\n    if (typeof value === 'function')\n        return wrapFunction(value);\n    // This doesn't return, it just creates a 'done' promise for the transaction,\n    // which is later returned for transaction.done (see idbObjectHandler).\n    if (value instanceof IDBTransaction)\n        cacheDonePromiseForTransaction(value);\n    if (instanceOfAny(value, getIdbProxyableTypes()))\n        return new Proxy(value, idbProxyTraps);\n    // Return the same value back if we're not going to transform it.\n    return value;\n}\nfunction wrap(value) {\n    // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because\n    // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.\n    if (value instanceof IDBRequest)\n        return promisifyRequest(value);\n    // If we've already transformed this value before, reuse the transformed value.\n    // This is faster, but it also provides object equality.\n    if (transformCache.has(value))\n        return transformCache.get(value);\n    const newValue = transformCachableValue(value);\n    // Not all types are transformed.\n    // These may be primitive types, so they can't be WeakMap keys.\n    if (newValue !== value) {\n        transformCache.set(value, newValue);\n        reverseTransformCache.set(newValue, value);\n    }\n    return newValue;\n}\nconst unwrap = (value) => reverseTransformCache.get(value);\n\nexport { reverseTransformCache as a, instanceOfAny as i, replaceTraps as r, unwrap as u, wrap as w };\n","import { w as wrap, r as replaceTraps } from './wrap-idb-value.js';\nexport { u as unwrap, w as wrap } from './wrap-idb-value.js';\n\n/**\n * Open a database.\n *\n * @param name Name of the database.\n * @param version Schema version.\n * @param callbacks Additional callbacks.\n */\nfunction openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {\n    const request = indexedDB.open(name, version);\n    const openPromise = wrap(request);\n    if (upgrade) {\n        request.addEventListener('upgradeneeded', (event) => {\n            upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction));\n        });\n    }\n    if (blocked)\n        request.addEventListener('blocked', () => blocked());\n    openPromise\n        .then((db) => {\n        if (terminated)\n            db.addEventListener('close', () => terminated());\n        if (blocking)\n            db.addEventListener('versionchange', () => blocking());\n    })\n        .catch(() => { });\n    return openPromise;\n}\n/**\n * Delete a database.\n *\n * @param name Name of the database.\n */\nfunction deleteDB(name, { blocked } = {}) {\n    const request = indexedDB.deleteDatabase(name);\n    if (blocked)\n        request.addEventListener('blocked', () => blocked());\n    return wrap(request).then(() => undefined);\n}\n\nconst readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];\nconst writeMethods = ['put', 'add', 'delete', 'clear'];\nconst cachedMethods = new Map();\nfunction getMethod(target, prop) {\n    if (!(target instanceof IDBDatabase &&\n        !(prop in target) &&\n        typeof prop === 'string')) {\n        return;\n    }\n    if (cachedMethods.get(prop))\n        return cachedMethods.get(prop);\n    const targetFuncName = prop.replace(/FromIndex$/, '');\n    const useIndex = prop !== targetFuncName;\n    const isWrite = writeMethods.includes(targetFuncName);\n    if (\n    // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.\n    !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) ||\n        !(isWrite || readMethods.includes(targetFuncName))) {\n        return;\n    }\n    const method = async function (storeName, ...args) {\n        // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(\n        const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');\n        let target = tx.store;\n        if (useIndex)\n            target = target.index(args.shift());\n        // Must reject if op rejects.\n        // If it's a write operation, must reject if tx.done rejects.\n        // Must reject with op rejection first.\n        // Must resolve with op value.\n        // Must handle both promises (no unhandled rejections)\n        return (await Promise.all([\n            target[targetFuncName](...args),\n            isWrite && tx.done,\n        ]))[0];\n    };\n    cachedMethods.set(prop, method);\n    return method;\n}\nreplaceTraps((oldTraps) => ({\n    ...oldTraps,\n    get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),\n    has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),\n}));\n\nexport { deleteDB, openDB };\n","\"use strict\";\n// @ts-ignore\ntry {\n    self['workbox:background-sync:7.4.0'] && _();\n}\ncatch (e) { }\n","/*\n  Copyright 2021 Google LLC\n\n  Use of this source code is governed by an MIT-style\n  license that can be found in the LICENSE file or at\n  https://opensource.org/licenses/MIT.\n*/\nimport { openDB } from 'idb';\nimport '../_version.js';\nconst DB_VERSION = 3;\nconst DB_NAME = 'workbox-background-sync';\nconst REQUEST_OBJECT_STORE_NAME = 'requests';\nconst QUEUE_NAME_INDEX = 'queueName';\n/**\n * A class to interact directly an IndexedDB created specifically to save and\n * retrieve QueueStoreEntries. This class encapsulates all the schema details\n * to store the representation of a Queue.\n *\n * @private\n */\nexport class QueueDb {\n    constructor() {\n        this._db = null;\n    }\n    /**\n     * Add QueueStoreEntry to underlying db.\n     *\n     * @param {UnidentifiedQueueStoreEntry} entry\n     */\n    async addEntry(entry) {\n        const db = await this.getDb();\n        const tx = db.transaction(REQUEST_OBJECT_STORE_NAME, 'readwrite', {\n            durability: 'relaxed',\n        });\n        await tx.store.add(entry);\n        await tx.done;\n    }\n    /**\n     * Returns the first entry id in the ObjectStore.\n     *\n     * @return {number | undefined}\n     */\n    async getFirstEntryId() {\n        const db = await this.getDb();\n        const cursor = await db\n            .transaction(REQUEST_OBJECT_STORE_NAME)\n            .store.openCursor();\n        return cursor === null || cursor === void 0 ? void 0 : cursor.value.id;\n    }\n    /**\n     * Get all the entries filtered by index\n     *\n     * @param queueName\n     * @return {Promise<QueueStoreEntry[]>}\n     */\n    async getAllEntriesByQueueName(queueName) {\n        const db = await this.getDb();\n        const results = await db.getAllFromIndex(REQUEST_OBJECT_STORE_NAME, QUEUE_NAME_INDEX, IDBKeyRange.only(queueName));\n        return results ? results : new Array();\n    }\n    /**\n     * Returns the number of entries filtered by index\n     *\n     * @param queueName\n     * @return {Promise<number>}\n     */\n    async getEntryCountByQueueName(queueName) {\n        const db = await this.getDb();\n        return db.countFromIndex(REQUEST_OBJECT_STORE_NAME, QUEUE_NAME_INDEX, IDBKeyRange.only(queueName));\n    }\n    /**\n     * Deletes a single entry by id.\n     *\n     * @param {number} id the id of the entry to be deleted\n     */\n    async deleteEntry(id) {\n        const db = await this.getDb();\n        await db.delete(REQUEST_OBJECT_STORE_NAME, id);\n    }\n    /**\n     *\n     * @param queueName\n     * @returns {Promise<QueueStoreEntry | undefined>}\n     */\n    async getFirstEntryByQueueName(queueName) {\n        return await this.getEndEntryFromIndex(IDBKeyRange.only(queueName), 'next');\n    }\n    /**\n     *\n     * @param queueName\n     * @returns {Promise<QueueStoreEntry | undefined>}\n     */\n    async getLastEntryByQueueName(queueName) {\n        return await this.getEndEntryFromIndex(IDBKeyRange.only(queueName), 'prev');\n    }\n    /**\n     * Returns either the first or the last entries, depending on direction.\n     * Filtered by index.\n     *\n     * @param {IDBCursorDirection} direction\n     * @param {IDBKeyRange} query\n     * @return {Promise<QueueStoreEntry | undefined>}\n     * @private\n     */\n    async getEndEntryFromIndex(query, direction) {\n        const db = await this.getDb();\n        const cursor = await db\n            .transaction(REQUEST_OBJECT_STORE_NAME)\n            .store.index(QUEUE_NAME_INDEX)\n            .openCursor(query, direction);\n        return cursor === null || cursor === void 0 ? void 0 : cursor.value;\n    }\n    /**\n     * Returns an open connection to the database.\n     *\n     * @private\n     */\n    async getDb() {\n        if (!this._db) {\n            this._db = await openDB(DB_NAME, DB_VERSION, {\n                upgrade: this._upgradeDb,\n            });\n        }\n        return this._db;\n    }\n    /**\n     * Upgrades QueueDB\n     *\n     * @param {IDBPDatabase<QueueDBSchema>} db\n     * @param {number} oldVersion\n     * @private\n     */\n    _upgradeDb(db, oldVersion) {\n        if (oldVersion > 0 && oldVersion < DB_VERSION) {\n            if (db.objectStoreNames.contains(REQUEST_OBJECT_STORE_NAME)) {\n                db.deleteObjectStore(REQUEST_OBJECT_STORE_NAME);\n            }\n        }\n        const objStore = db.createObjectStore(REQUEST_OBJECT_STORE_NAME, {\n            autoIncrement: true,\n            keyPath: 'id',\n        });\n        objStore.createIndex(QUEUE_NAME_INDEX, QUEUE_NAME_INDEX, { unique: false });\n    }\n}\n","/*\n  Copyright 2018 Google LLC\n\n  Use of this source code is governed by an MIT-style\n  license that can be found in the LICENSE file or at\n  https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { QueueDb, } from './QueueDb.js';\nimport '../_version.js';\n/**\n * A class to manage storing requests from a Queue in IndexedDB,\n * indexed by their queue name for easier access.\n *\n * Most developers will not need to access this class directly;\n * it is exposed for advanced use cases.\n */\nexport class QueueStore {\n    /**\n     * Associates this instance with a Queue instance, so entries added can be\n     * identified by their queue name.\n     *\n     * @param {string} queueName\n     */\n    constructor(queueName) {\n        this._queueName = queueName;\n        this._queueDb = new QueueDb();\n    }\n    /**\n     * Append an entry last in the queue.\n     *\n     * @param {Object} entry\n     * @param {Object} entry.requestData\n     * @param {number} [entry.timestamp]\n     * @param {Object} [entry.metadata]\n     */\n    async pushEntry(entry) {\n        if (process.env.NODE_ENV !== 'production') {\n            assert.isType(entry, 'object', {\n                moduleName: 'workbox-background-sync',\n                className: 'QueueStore',\n                funcName: 'pushEntry',\n                paramName: 'entry',\n            });\n            assert.isType(entry.requestData, 'object', {\n                moduleName: 'workbox-background-sync',\n                className: 'QueueStore',\n                funcName: 'pushEntry',\n                paramName: 'entry.requestData',\n            });\n        }\n        // Don't specify an ID since one is automatically generated.\n        delete entry.id;\n        entry.queueName = this._queueName;\n        await this._queueDb.addEntry(entry);\n    }\n    /**\n     * Prepend an entry first in the queue.\n     *\n     * @param {Object} entry\n     * @param {Object} entry.requestData\n     * @param {number} [entry.timestamp]\n     * @param {Object} [entry.metadata]\n     */\n    async unshiftEntry(entry) {\n        if (process.env.NODE_ENV !== 'production') {\n            assert.isType(entry, 'object', {\n                moduleName: 'workbox-background-sync',\n                className: 'QueueStore',\n                funcName: 'unshiftEntry',\n                paramName: 'entry',\n            });\n            assert.isType(entry.requestData, 'object', {\n                moduleName: 'workbox-background-sync',\n                className: 'QueueStore',\n                funcName: 'unshiftEntry',\n                paramName: 'entry.requestData',\n            });\n        }\n        const firstId = await this._queueDb.getFirstEntryId();\n        if (firstId) {\n            // Pick an ID one less than the lowest ID in the object store.\n            entry.id = firstId - 1;\n        }\n        else {\n            // Otherwise let the auto-incrementor assign the ID.\n            delete entry.id;\n        }\n        entry.queueName = this._queueName;\n        await this._queueDb.addEntry(entry);\n    }\n    /**\n     * Removes and returns the last entry in the queue matching the `queueName`.\n     *\n     * @return {Promise<QueueStoreEntry|undefined>}\n     */\n    async popEntry() {\n        return this._removeEntry(await this._queueDb.getLastEntryByQueueName(this._queueName));\n    }\n    /**\n     * Removes and returns the first entry in the queue matching the `queueName`.\n     *\n     * @return {Promise<QueueStoreEntry|undefined>}\n     */\n    async shiftEntry() {\n        return this._removeEntry(await this._queueDb.getFirstEntryByQueueName(this._queueName));\n    }\n    /**\n     * Returns all entries in the store matching the `queueName`.\n     *\n     * @param {Object} options See {@link workbox-background-sync.Queue~getAll}\n     * @return {Promise<Array<Object>>}\n     */\n    async getAll() {\n        return await this._queueDb.getAllEntriesByQueueName(this._queueName);\n    }\n    /**\n     * Returns the number of entries in the store matching the `queueName`.\n     *\n     * @param {Object} options See {@link workbox-background-sync.Queue~size}\n     * @return {Promise<number>}\n     */\n    async size() {\n        return await this._queueDb.getEntryCountByQueueName(this._queueName);\n    }\n    /**\n     * Deletes the entry for the given ID.\n     *\n     * WARNING: this method does not ensure the deleted entry belongs to this\n     * queue (i.e. matches the `queueName`). But this limitation is acceptable\n     * as this class is not publicly exposed. An additional check would make\n     * this method slower than it needs to be.\n     *\n     * @param {number} id\n     */\n    async deleteEntry(id) {\n        await this._queueDb.deleteEntry(id);\n    }\n    /**\n     * Removes and returns the first or last entry in the queue (based on the\n     * `direction` argument) matching the `queueName`.\n     *\n     * @return {Promise<QueueStoreEntry|undefined>}\n     * @private\n     */\n    async _removeEntry(entry) {\n        if (entry) {\n            await this.deleteEntry(entry.id);\n        }\n        return entry;\n    }\n}\n","/*\n  Copyright 2018 Google LLC\n\n  Use of this source code is governed by an MIT-style\n  license that can be found in the LICENSE file or at\n  https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport '../_version.js';\nconst serializableProperties = [\n    'method',\n    'referrer',\n    'referrerPolicy',\n    'mode',\n    'credentials',\n    'cache',\n    'redirect',\n    'integrity',\n    'keepalive',\n];\n/**\n * A class to make it easier to serialize and de-serialize requests so they\n * can be stored in IndexedDB.\n *\n * Most developers will not need to access this class directly;\n * it is exposed for advanced use cases.\n */\nclass StorableRequest {\n    /**\n     * Converts a Request object to a plain object that can be structured\n     * cloned or JSON-stringified.\n     *\n     * @param {Request} request\n     * @return {Promise<StorableRequest>}\n     */\n    static async fromRequest(request) {\n        const requestData = {\n            url: request.url,\n            headers: {},\n        };\n        // Set the body if present.\n        if (request.method !== 'GET') {\n            // Use ArrayBuffer to support non-text request bodies.\n            // NOTE: we can't use Blobs becuse Safari doesn't support storing\n            // Blobs in IndexedDB in some cases:\n            // https://github.com/dfahlander/Dexie.js/issues/618#issuecomment-398348457\n            requestData.body = await request.clone().arrayBuffer();\n        }\n        // Convert the headers from an iterable to an object.\n        for (const [key, value] of request.headers.entries()) {\n            requestData.headers[key] = value;\n        }\n        // Add all other serializable request properties\n        for (const prop of serializableProperties) {\n            if (request[prop] !== undefined) {\n                requestData[prop] = request[prop];\n            }\n        }\n        return new StorableRequest(requestData);\n    }\n    /**\n     * Accepts an object of request data that can be used to construct a\n     * `Request` but can also be stored in IndexedDB.\n     *\n     * @param {Object} requestData An object of request data that includes the\n     *     `url` plus any relevant properties of\n     *     [requestInit]{@link https://fetch.spec.whatwg.org/#requestinit}.\n     */\n    constructor(requestData) {\n        if (process.env.NODE_ENV !== 'production') {\n            assert.isType(requestData, 'object', {\n                moduleName: 'workbox-background-sync',\n                className: 'StorableRequest',\n                funcName: 'constructor',\n                paramName: 'requestData',\n            });\n            assert.isType(requestData.url, 'string', {\n                moduleName: 'workbox-background-sync',\n                className: 'StorableRequest',\n                funcName: 'constructor',\n                paramName: 'requestData.url',\n            });\n        }\n        // If the request's mode is `navigate`, convert it to `same-origin` since\n        // navigation requests can't be constructed via script.\n        if (requestData['mode'] === 'navigate') {\n            requestData['mode'] = 'same-origin';\n        }\n        this._requestData = requestData;\n    }\n    /**\n     * Returns a deep clone of the instances `_requestData` object.\n     *\n     * @return {Object}\n     */\n    toObject() {\n        const requestData = Object.assign({}, this._requestData);\n        requestData.headers = Object.assign({}, this._requestData.headers);\n        if (requestData.body) {\n            requestData.body = requestData.body.slice(0);\n        }\n        return requestData;\n    }\n    /**\n     * Converts this instance to a Request.\n     *\n     * @return {Request}\n     */\n    toRequest() {\n        return new Request(this._requestData.url, this._requestData);\n    }\n    /**\n     * Creates and returns a deep clone of the instance.\n     *\n     * @return {StorableRequest}\n     */\n    clone() {\n        return new StorableRequest(this.toObject());\n    }\n}\nexport { StorableRequest };\n","/*\n  Copyright 2018 Google LLC\n\n  Use of this source code is governed by an MIT-style\n  license that can be found in the LICENSE file or at\n  https://opensource.org/licenses/MIT.\n*/\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { QueueStore } from './lib/QueueStore.js';\nimport { StorableRequest } from './lib/StorableRequest.js';\nimport './_version.js';\nconst TAG_PREFIX = 'workbox-background-sync';\nconst MAX_RETENTION_TIME = 60 * 24 * 7; // 7 days in minutes\nconst queueNames = new Set();\n/**\n * Converts a QueueStore entry into the format exposed by Queue. This entails\n * converting the request data into a real request and omitting the `id` and\n * `queueName` properties.\n *\n * @param {UnidentifiedQueueStoreEntry} queueStoreEntry\n * @return {Queue}\n * @private\n */\nconst convertEntry = (queueStoreEntry) => {\n    const queueEntry = {\n        request: new StorableRequest(queueStoreEntry.requestData).toRequest(),\n        timestamp: queueStoreEntry.timestamp,\n    };\n    if (queueStoreEntry.metadata) {\n        queueEntry.metadata = queueStoreEntry.metadata;\n    }\n    return queueEntry;\n};\n/**\n * A class to manage storing failed requests in IndexedDB and retrying them\n * later. All parts of the storing and replaying process are observable via\n * callbacks.\n *\n * @memberof workbox-background-sync\n */\nclass Queue {\n    /**\n     * Creates an instance of Queue with the given options\n     *\n     * @param {string} name The unique name for this queue. This name must be\n     *     unique as it's used to register sync events and store requests\n     *     in IndexedDB specific to this instance. An error will be thrown if\n     *     a duplicate name is detected.\n     * @param {Object} [options]\n     * @param {Function} [options.onSync] A function that gets invoked whenever\n     *     the 'sync' event fires. The function is invoked with an object\n     *     containing the `queue` property (referencing this instance), and you\n     *     can use the callback to customize the replay behavior of the queue.\n     *     When not set the `replayRequests()` method is called.\n     *     Note: if the replay fails after a sync event, make sure you throw an\n     *     error, so the browser knows to retry the sync event later.\n     * @param {number} [options.maxRetentionTime=7 days] The amount of time (in\n     *     minutes) a request may be retried. After this amount of time has\n     *     passed, the request will be deleted from the queue.\n     * @param {boolean} [options.forceSyncFallback=false] If `true`, instead\n     *     of attempting to use background sync events, always attempt to replay\n     *     queued request at service worker startup. Most folks will not need\n     *     this, unless you explicitly target a runtime like Electron that\n     *     exposes the interfaces for background sync, but does not have a working\n     *     implementation.\n     */\n    constructor(name, { forceSyncFallback, onSync, maxRetentionTime } = {}) {\n        this._syncInProgress = false;\n        this._requestsAddedDuringSync = false;\n        // Ensure the store name is not already being used\n        if (queueNames.has(name)) {\n            throw new WorkboxError('duplicate-queue-name', { name });\n        }\n        else {\n            queueNames.add(name);\n        }\n        this._name = name;\n        this._onSync = onSync || this.replayRequests;\n        this._maxRetentionTime = maxRetentionTime || MAX_RETENTION_TIME;\n        this._forceSyncFallback = Boolean(forceSyncFallback);\n        this._queueStore = new QueueStore(this._name);\n        this._addSyncListener();\n    }\n    /**\n     * @return {string}\n     */\n    get name() {\n        return this._name;\n    }\n    /**\n     * Stores the passed request in IndexedDB (with its timestamp and any\n     * metadata) at the end of the queue.\n     *\n     * @param {QueueEntry} entry\n     * @param {Request} entry.request The request to store in the queue.\n     * @param {Object} [entry.metadata] Any metadata you want associated with the\n     *     stored request. When requests are replayed you'll have access to this\n     *     metadata object in case you need to modify the request beforehand.\n     * @param {number} [entry.timestamp] The timestamp (Epoch time in\n     *     milliseconds) when the request was first added to the queue. This is\n     *     used along with `maxRetentionTime` to remove outdated requests. In\n     *     general you don't need to set this value, as it's automatically set\n     *     for you (defaulting to `Date.now()`), but you can update it if you\n     *     don't want particular requests to expire.\n     */\n    async pushRequest(entry) {\n        if (process.env.NODE_ENV !== 'production') {\n            assert.isType(entry, 'object', {\n                moduleName: 'workbox-background-sync',\n                className: 'Queue',\n                funcName: 'pushRequest',\n                paramName: 'entry',\n            });\n            assert.isInstance(entry.request, Request, {\n                moduleName: 'workbox-background-sync',\n                className: 'Queue',\n                funcName: 'pushRequest',\n                paramName: 'entry.request',\n            });\n        }\n        await this._addRequest(entry, 'push');\n    }\n    /**\n     * Stores the passed request in IndexedDB (with its timestamp and any\n     * metadata) at the beginning of the queue.\n     *\n     * @param {QueueEntry} entry\n     * @param {Request} entry.request The request to store in the queue.\n     * @param {Object} [entry.metadata] Any metadata you want associated with the\n     *     stored request. When requests are replayed you'll have access to this\n     *     metadata object in case you need to modify the request beforehand.\n     * @param {number} [entry.timestamp] The timestamp (Epoch time in\n     *     milliseconds) when the request was first added to the queue. This is\n     *     used along with `maxRetentionTime` to remove outdated requests. In\n     *     general you don't need to set this value, as it's automatically set\n     *     for you (defaulting to `Date.now()`), but you can update it if you\n     *     don't want particular requests to expire.\n     */\n    async unshiftRequest(entry) {\n        if (process.env.NODE_ENV !== 'production') {\n            assert.isType(entry, 'object', {\n                moduleName: 'workbox-background-sync',\n                className: 'Queue',\n                funcName: 'unshiftRequest',\n                paramName: 'entry',\n            });\n            assert.isInstance(entry.request, Request, {\n                moduleName: 'workbox-background-sync',\n                className: 'Queue',\n                funcName: 'unshiftRequest',\n                paramName: 'entry.request',\n            });\n        }\n        await this._addRequest(entry, 'unshift');\n    }\n    /**\n     * Removes and returns the last request in the queue (along with its\n     * timestamp and any metadata). The returned object takes the form:\n     * `{request, timestamp, metadata}`.\n     *\n     * @return {Promise<QueueEntry | undefined>}\n     */\n    async popRequest() {\n        return this._removeRequest('pop');\n    }\n    /**\n     * Removes and returns the first request in the queue (along with its\n     * timestamp and any metadata). The returned object takes the form:\n     * `{request, timestamp, metadata}`.\n     *\n     * @return {Promise<QueueEntry | undefined>}\n     */\n    async shiftRequest() {\n        return this._removeRequest('shift');\n    }\n    /**\n     * Returns all the entries that have not expired (per `maxRetentionTime`).\n     * Any expired entries are removed from the queue.\n     *\n     * @return {Promise<Array<QueueEntry>>}\n     */\n    async getAll() {\n        const allEntries = await this._queueStore.getAll();\n        const now = Date.now();\n        const unexpiredEntries = [];\n        for (const entry of allEntries) {\n            // Ignore requests older than maxRetentionTime. Call this function\n            // recursively until an unexpired request is found.\n            const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;\n            if (now - entry.timestamp > maxRetentionTimeInMs) {\n                await this._queueStore.deleteEntry(entry.id);\n            }\n            else {\n                unexpiredEntries.push(convertEntry(entry));\n            }\n        }\n        return unexpiredEntries;\n    }\n    /**\n     * Returns the number of entries present in the queue.\n     * Note that expired entries (per `maxRetentionTime`) are also included in this count.\n     *\n     * @return {Promise<number>}\n     */\n    async size() {\n        return await this._queueStore.size();\n    }\n    /**\n     * Adds the entry to the QueueStore and registers for a sync event.\n     *\n     * @param {Object} entry\n     * @param {Request} entry.request\n     * @param {Object} [entry.metadata]\n     * @param {number} [entry.timestamp=Date.now()]\n     * @param {string} operation ('push' or 'unshift')\n     * @private\n     */\n    async _addRequest({ request, metadata, timestamp = Date.now() }, operation) {\n        const storableRequest = await StorableRequest.fromRequest(request.clone());\n        const entry = {\n            requestData: storableRequest.toObject(),\n            timestamp,\n        };\n        // Only include metadata if it's present.\n        if (metadata) {\n            entry.metadata = metadata;\n        }\n        switch (operation) {\n            case 'push':\n                await this._queueStore.pushEntry(entry);\n                break;\n            case 'unshift':\n                await this._queueStore.unshiftEntry(entry);\n                break;\n        }\n        if (process.env.NODE_ENV !== 'production') {\n            logger.log(`Request for '${getFriendlyURL(request.url)}' has ` +\n                `been added to background sync queue '${this._name}'.`);\n        }\n        // Don't register for a sync if we're in the middle of a sync. Instead,\n        // we wait until the sync is complete and call register if\n        // `this._requestsAddedDuringSync` is true.\n        if (this._syncInProgress) {\n            this._requestsAddedDuringSync = true;\n        }\n        else {\n            await this.registerSync();\n        }\n    }\n    /**\n     * Removes and returns the first or last (depending on `operation`) entry\n     * from the QueueStore that's not older than the `maxRetentionTime`.\n     *\n     * @param {string} operation ('pop' or 'shift')\n     * @return {Object|undefined}\n     * @private\n     */\n    async _removeRequest(operation) {\n        const now = Date.now();\n        let entry;\n        switch (operation) {\n            case 'pop':\n                entry = await this._queueStore.popEntry();\n                break;\n            case 'shift':\n                entry = await this._queueStore.shiftEntry();\n                break;\n        }\n        if (entry) {\n            // Ignore requests older than maxRetentionTime. Call this function\n            // recursively until an unexpired request is found.\n            const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;\n            if (now - entry.timestamp > maxRetentionTimeInMs) {\n                return this._removeRequest(operation);\n            }\n            return convertEntry(entry);\n        }\n        else {\n            return undefined;\n        }\n    }\n    /**\n     * Loops through each request in the queue and attempts to re-fetch it.\n     * If any request fails to re-fetch, it's put back in the same position in\n     * the queue (which registers a retry for the next sync event).\n     */\n    async replayRequests() {\n        let entry;\n        while ((entry = await this.shiftRequest())) {\n            try {\n                await fetch(entry.request.clone());\n                if (process.env.NODE_ENV !== 'production') {\n                    logger.log(`Request for '${getFriendlyURL(entry.request.url)}' ` +\n                        `has been replayed in queue '${this._name}'`);\n                }\n            }\n            catch (error) {\n                await this.unshiftRequest(entry);\n                if (process.env.NODE_ENV !== 'production') {\n                    logger.log(`Request for '${getFriendlyURL(entry.request.url)}' ` +\n                        `failed to replay, putting it back in queue '${this._name}'`);\n                }\n                throw new WorkboxError('queue-replay-failed', { name: this._name });\n            }\n        }\n        if (process.env.NODE_ENV !== 'production') {\n            logger.log(`All requests in queue '${this.name}' have successfully ` +\n                `replayed; the queue is now empty!`);\n        }\n    }\n    /**\n     * Registers a sync event with a tag unique to this instance.\n     */\n    async registerSync() {\n        // See https://github.com/GoogleChrome/workbox/issues/2393\n        if ('sync' in self.registration && !this._forceSyncFallback) {\n            try {\n                await self.registration.sync.register(`${TAG_PREFIX}:${this._name}`);\n            }\n            catch (err) {\n                // This means the registration failed for some reason, possibly due to\n                // the user disabling it.\n                if (process.env.NODE_ENV !== 'production') {\n                    logger.warn(`Unable to register sync event for '${this._name}'.`, err);\n                }\n            }\n        }\n    }\n    /**\n     * In sync-supporting browsers, this adds a listener for the sync event.\n     * In non-sync-supporting browsers, or if _forceSyncFallback is true, this\n     * will retry the queue on service worker startup.\n     *\n     * @private\n     */\n    _addSyncListener() {\n        // See https://github.com/GoogleChrome/workbox/issues/2393\n        if ('sync' in self.registration && !this._forceSyncFallback) {\n            self.addEventListener('sync', (event) => {\n                if (event.tag === `${TAG_PREFIX}:${this._name}`) {\n                    if (process.env.NODE_ENV !== 'production') {\n                        logger.log(`Background sync for tag '${event.tag}' ` + `has been received`);\n                    }\n                    const syncComplete = async () => {\n                        this._syncInProgress = true;\n                        let syncError;\n                        try {\n                            await this._onSync({ queue: this });\n                        }\n                        catch (error) {\n                            if (error instanceof Error) {\n                                syncError = error;\n                                // Rethrow the error. Note: the logic in the finally clause\n                                // will run before this gets rethrown.\n                                throw syncError;\n                            }\n                        }\n                        finally {\n                            // New items may have been added to the queue during the sync,\n                            // so we need to register for a new sync if that's happened...\n                            // Unless there was an error during the sync, in which\n                            // case the browser will automatically retry later, as long\n                            // as `event.lastChance` is not true.\n                            if (this._requestsAddedDuringSync &&\n                                !(syncError && !event.lastChance)) {\n                                await this.registerSync();\n                            }\n                            this._syncInProgress = false;\n                            this._requestsAddedDuringSync = false;\n                        }\n                    };\n                    event.waitUntil(syncComplete());\n                }\n            });\n        }\n        else {\n            if (process.env.NODE_ENV !== 'production') {\n                logger.log(`Background sync replaying without background sync event`);\n            }\n            // If the browser doesn't support background sync, or the developer has\n            // opted-in to not using it, retry every time the service worker starts up\n            // as a fallback.\n            void this._onSync({ queue: this });\n        }\n    }\n    /**\n     * Returns the set of queue names. This is primarily used to reset the list\n     * of queue names in tests.\n     *\n     * @return {Set<string>}\n     *\n     * @private\n     */\n    static get _queueNames() {\n        return queueNames;\n    }\n}\nexport { Queue };\n","/*\n  Copyright 2018 Google LLC\n\n  Use of this source code is governed by an MIT-style\n  license that can be found in the LICENSE file or at\n  https://opensource.org/licenses/MIT.\n*/\nimport { Queue } from './Queue.js';\nimport './_version.js';\n/**\n * A class implementing the `fetchDidFail` lifecycle callback. This makes it\n * easier to add failed requests to a background sync Queue.\n *\n * @memberof workbox-background-sync\n */\nclass BackgroundSyncPlugin {\n    /**\n     * @param {string} name See the {@link workbox-background-sync.Queue}\n     *     documentation for parameter details.\n     * @param {Object} [options] See the\n     *     {@link workbox-background-sync.Queue} documentation for\n     *     parameter details.\n     */\n    constructor(name, options) {\n        /**\n         * @param {Object} options\n         * @param {Request} options.request\n         * @private\n         */\n        this.fetchDidFail = async ({ request }) => {\n            await this._queue.pushRequest({ request });\n        };\n        this._queue = new Queue(name, options);\n    }\n}\nexport { BackgroundSyncPlugin };\n"],"names":["instanceOfAny","object","constructors","some","c","idbProxyableTypes","cursorAdvanceMethods","cursorRequestMap","WeakMap","transactionDoneMap","transactionStoreNamesMap","transformCache","reverseTransformCache","idbProxyTraps","get","target","prop","receiver","IDBTransaction","objectStoreNames","undefined","objectStore","wrap","set","value","has","wrapFunction","func","IDBDatabase","prototype","transaction","IDBCursor","advance","continue","continuePrimaryKey","includes","args","apply","unwrap","this","storeNames","tx","call","sort","transformCachableValue","done","Promise","resolve","reject","unlisten","removeEventListener","complete","error","DOMException","addEventListener","cacheDonePromiseForTransaction","IDBObjectStore","IDBIndex","Proxy","IDBRequest","request","promise","success","result","then","catch","promisifyRequest","newValue","readMethods","writeMethods","cachedMethods","Map","getMethod","targetFuncName","replace","useIndex","isWrite","method","async","storeName","store","index","shift","all","oldTraps","_extends","callback","self","_","e","REQUEST_OBJECT_STORE_NAME","QUEUE_NAME_INDEX","QueueDb","constructor","_db","entry","getDb","durability","add","db","cursor","openCursor","id","queueName","results","getAllFromIndex","IDBKeyRange","only","Array","countFromIndex","delete","getEndEntryFromIndex","query","direction","name","version","blocked","upgrade","blocking","terminated","indexedDB","open","openPromise","event","oldVersion","newVersion","openDB","_upgradeDb","contains","deleteObjectStore","createObjectStore","autoIncrement","keyPath","createIndex","unique","QueueStore","_queueName","_queueDb","addEntry","firstId","getFirstEntryId","_removeEntry","getLastEntryByQueueName","getFirstEntryByQueueName","getAllEntriesByQueueName","getEntryCountByQueueName","deleteEntry","serializableProperties","StorableRequest","static","requestData","url","headers","body","clone","arrayBuffer","key","entries","_requestData","toObject","Object","assign","slice","toRequest","Request","TAG_PREFIX","queueNames","Set","convertEntry","queueStoreEntry","queueEntry","timestamp","metadata","Queue","forceSyncFallback","onSync","maxRetentionTime","_syncInProgress","_requestsAddedDuringSync","WorkboxError","_name","_onSync","replayRequests","_maxRetentionTime","_forceSyncFallback","Boolean","_queueStore","_addSyncListener","_addRequest","_removeRequest","allEntries","getAll","now","Date","unexpiredEntries","maxRetentionTimeInMs","push","size","operation","fromRequest","pushEntry","unshiftEntry","registerSync","popEntry","shiftEntry","shiftRequest","fetch","unshiftRequest","registration","sync","register","err","tag","syncComplete","syncError","queue","Error","lastChance","waitUntil","_queueNames","options","fetchDidFail","_queue","pushRequest"],"mappings":"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","x_google_ignoreList":[0,1]}