aboutsummaryrefslogtreecommitdiffhomepage
path: root/public/workbox-v4.3.1/workbox-background-sync.prod.js.map
blob: 4064edb64911334b5f292b5511cb7bb0f9a1abb3 (plain) (blame)
1
{"version":3,"file":"workbox-background-sync.prod.js","sources":["../_version.mjs","../lib/QueueStore.mjs","../lib/StorableRequest.mjs","../Queue.mjs","../Plugin.mjs"],"sourcesContent":["try{self['workbox:background-sync:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {DBWrapper} from 'workbox-core/_private/DBWrapper.mjs';\nimport '../_version.mjs';\n\n\nconst DB_VERSION = 3;\nconst DB_NAME = 'workbox-background-sync';\nconst OBJECT_STORE_NAME = 'requests';\nconst INDEXED_PROP = 'queueName';\n\n/**\n * A class to manage storing requests from a Queue in IndexedbDB,\n * indexed by their queue name for easier access.\n *\n * @private\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   * @private\n   */\n  constructor(queueName) {\n    this._queueName = queueName;\n    this._db = new DBWrapper(DB_NAME, DB_VERSION, {\n      onupgradeneeded: this._upgradeDb,\n    });\n  }\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   * @private\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\n    // Don't specify an ID since one is automatically generated.\n    delete entry.id;\n    entry.queueName = this._queueName;\n\n    await this._db.add(OBJECT_STORE_NAME, entry);\n  }\n\n  /**\n   * Preppend 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   * @private\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\n    const [firstEntry] = await this._db.getAllMatching(OBJECT_STORE_NAME, {\n      count: 1,\n    });\n\n    if (firstEntry) {\n      // Pick an ID one less than the lowest ID in the object store.\n      entry.id = firstEntry.id - 1;\n    } else {\n      // Otherwise let the auto-incrementor assign the ID.\n      delete entry.id;\n    }\n    entry.queueName = this._queueName;\n\n    await this._db.add(OBJECT_STORE_NAME, entry);\n  }\n\n  /**\n   * Removes and returns the last entry in the queue matching the `queueName`.\n   *\n   * @return {Promise<Object>}\n   * @private\n   */\n  async popEntry() {\n    return this._removeEntry({direction: 'prev'});\n  }\n\n  /**\n   * Removes and returns the first entry in the queue matching the `queueName`.\n   *\n   * @return {Promise<Object>}\n   * @private\n   */\n  async shiftEntry() {\n    return this._removeEntry({direction: 'next'});\n  }\n\n  /**\n   * Returns all entries in the store matching the `queueName`.\n   *\n   * @param {Object} options See workbox.backgroundSync.Queue~getAll}\n   * @return {Promise<Array<Object>>}\n   * @private\n   */\n  async getAll() {\n    return await this._db.getAllMatching(OBJECT_STORE_NAME, {\n      index: INDEXED_PROP,\n      query: IDBKeyRange.only(this._queueName),\n    });\n  }\n\n  /**\n   * Deletes the entry for the given ID.\n   *\n   * WARNING: this method does not ensure the deleted enry 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   * @private\n   * @param {number} id\n   */\n  async deleteEntry(id) {\n    await this._db.delete(OBJECT_STORE_NAME, id);\n  }\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<Object>}\n   * @private\n   */\n  async _removeEntry({direction}) {\n    const [entry] = await this._db.getAllMatching(OBJECT_STORE_NAME, {\n      direction,\n      index: INDEXED_PROP,\n      query: IDBKeyRange.only(this._queueName),\n      count: 1,\n    });\n\n    if (entry) {\n      await this.deleteEntry(entry.id);\n      return entry;\n    }\n  }\n\n  /**\n   * Upgrades the database given an `upgradeneeded` event.\n   *\n   * @param {Event} event\n   * @private\n   */\n  _upgradeDb(event) {\n    const db = event.target.result;\n\n    if (event.oldVersion > 0 && event.oldVersion < DB_VERSION) {\n      if (db.objectStoreNames.contains(OBJECT_STORE_NAME)) {\n        db.deleteObjectStore(OBJECT_STORE_NAME);\n      }\n    }\n\n    const objStore = db.createObjectStore(OBJECT_STORE_NAME, {\n      autoIncrement: true,\n      keyPath: 'id',\n    });\n    objStore.createIndex(INDEXED_PROP, INDEXED_PROP, {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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport '../_version.mjs';\n\n\nconst serializableProperties = [\n  'method',\n  'referrer',\n  'referrerPolicy',\n  'mode',\n  'credentials',\n  'cache',\n  'redirect',\n  'integrity',\n  'keepalive',\n];\n\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 * @private\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   * @private\n   */\n  static async fromRequest(request) {\n    const requestData = {\n      url: request.url,\n      headers: {},\n    };\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\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\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\n    return new StorableRequest(requestData);\n  }\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   * @private\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\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\n    this._requestData = requestData;\n  }\n\n  /**\n   * Returns a deep clone of the instances `_requestData` object.\n   *\n   * @return {Object}\n   *\n   * @private\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\n    return requestData;\n  }\n\n  /**\n   * Converts this instance to a Request.\n   *\n   * @return {Request}\n   *\n   * @private\n   */\n  toRequest() {\n    return new Request(this._requestData.url, this._requestData);\n  }\n\n  /**\n   * Creates and returns a deep clone of the instance.\n   *\n   * @return {StorableRequest}\n   *\n   * @private\n   */\n  clone() {\n    return new StorableRequest(this.toObject());\n  }\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {QueueStore} from './lib/QueueStore.mjs';\nimport {StorableRequest} from './lib/StorableRequest.mjs';\nimport './_version.mjs';\n\n\nconst TAG_PREFIX = 'workbox-background-sync';\nconst MAX_RETENTION_TIME = 60 * 24 * 7; // 7 days in minutes\n\nconst queueNames = new Set();\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.backgroundSync\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   */\n  constructor(name, {onSync, maxRetentionTime} = {}) {\n    // Ensure the store name is not already being used\n    if (queueNames.has(name)) {\n      throw new WorkboxError('duplicate-queue-name', {name});\n    } else {\n      queueNames.add(name);\n    }\n\n    this._name = name;\n    this._onSync = onSync || this.replayRequests;\n    this._maxRetentionTime = maxRetentionTime || MAX_RETENTION_TIME;\n    this._queueStore = new QueueStore(this._name);\n\n    this._addSyncListener();\n  }\n\n  /**\n   * @return {string}\n   */\n  get name() {\n    return this._name;\n  }\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 {Object} 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\n    await this._addRequest(entry, 'push');\n  }\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 {Object} 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\n    await this._addRequest(entry, 'unshift');\n  }\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<Object>}\n   */\n  async popRequest() {\n    return this._removeRequest('pop');\n  }\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<Object>}\n   */\n  async shiftRequest() {\n    return this._removeRequest('shift');\n  }\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<Object>>}\n   */\n  async getAll() {\n    const allEntries = await this._queueStore.getAll();\n    const now = Date.now();\n\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      } else {\n        unexpiredEntries.push(convertEntry(entry));\n      }\n    }\n\n    return unexpiredEntries;\n  }\n\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(\n      {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\n    // Only include metadata if it's present.\n    if (metadata) {\n      entry.metadata = metadata;\n    }\n\n    await this._queueStore[`${operation}Entry`](entry);\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\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    } else {\n      await this.registerSync();\n    }\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    const entry = await this._queueStore[`${operation}Entry`]();\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\n      return convertEntry(entry);\n    }\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\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      } catch (error) {\n        await this.unshiftRequest(entry);\n\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  /**\n   * Registers a sync event with a tag unique to this instance.\n   */\n  async registerSync() {\n    if ('sync' in registration) {\n      try {\n        await registration.sync.register(`${TAG_PREFIX}:${this._name}`);\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(\n              `Unable to register sync event for '${this._name}'.`, err);\n        }\n      }\n    }\n  }\n\n  /**\n   * In sync-supporting browsers, this adds a listener for the sync event.\n   * In non-sync-supporting browsers, this will retry the queue on service\n   * worker startup.\n   *\n   * @private\n   */\n  _addSyncListener() {\n    if ('sync' in registration) {\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}'` +\n                `has been received`);\n          }\n\n          const syncComplete = async () => {\n            this._syncInProgress = true;\n\n            let syncError;\n            try {\n              await this._onSync({queue: this});\n            } catch (error) {\n              syncError = error;\n\n              // Rethrow the error. Note: the logic in the finally clause\n              // will run before this gets rethrown.\n              throw syncError;\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\n              this._syncInProgress = false;\n              this._requestsAddedDuringSync = false;\n            }\n          };\n          event.waitUntil(syncComplete());\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, retry\n      // every time the service worker starts up as a fallback.\n      this._onSync({queue: this});\n    }\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}\n   *\n   * @private\n   */\n  static get _queueNames() {\n    return queueNames;\n  }\n}\n\n\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 {Object} queueStoreEntry\n * @return {Object}\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\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*/\n\nimport {Queue} from './Queue.mjs';\nimport './_version.mjs';\n\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.backgroundSync\n */\nclass Plugin {\n  /**\n   * @param {...*} queueArgs Args to forward to the composed Queue instance.\n   *    See the [Queue]{@link workbox.backgroundSync.Queue} documentation for\n   *    parameter details.\n   */\n  constructor(...queueArgs) {\n    this._queue = new Queue(...queueArgs);\n    this.fetchDidFail = this.fetchDidFail.bind(this);\n  }\n\n  /**\n   * @param {Object} options\n   * @param {Request} options.request\n   * @private\n   */\n  async fetchDidFail({request}) {\n    await this._queue.pushRequest({request});\n  }\n}\n\nexport {Plugin};\n"],"names":["self","_","e","DB_VERSION","DB_NAME","OBJECT_STORE_NAME","INDEXED_PROP","QueueStore","constructor","queueName","_queueName","_db","DBWrapper","onupgradeneeded","this","_upgradeDb","entry","id","add","firstEntry","getAllMatching","count","_removeEntry","direction","index","query","IDBKeyRange","only","delete","deleteEntry","event","db","target","result","oldVersion","objectStoreNames","contains","deleteObjectStore","createObjectStore","autoIncrement","keyPath","createIndex","unique","serializableProperties","StorableRequest","request","requestData","url","headers","method","body","clone","arrayBuffer","key","value","entries","prop","undefined","mode","_requestData","toObject","Object","assign","slice","toRequest","Request","TAG_PREFIX","MAX_RETENTION_TIME","queueNames","Set","Queue","name","onSync","maxRetentionTime","has","WorkboxError","_name","_onSync","replayRequests","_maxRetentionTime","_queueStore","_addSyncListener","_addRequest","_removeRequest","allEntries","getAll","now","Date","unexpiredEntries","maxRetentionTimeInMs","timestamp","push","convertEntry","metadata","operation","fromRequest","_syncInProgress","_requestsAddedDuringSync","registerSync","shiftRequest","fetch","error","unshiftRequest","registration","sync","register","err","addEventListener","tag","syncComplete","async","syncError","queue","lastChance","waitUntil","queueStoreEntry","queueEntry","queueArgs","_queue","fetchDidFail","bind","pushRequest"],"mappings":"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"}