aboutsummaryrefslogtreecommitdiffhomepage
path: root/public/workbox-v4.3.1/workbox-broadcast-update.prod.js.map
blob: 537aee0197f145194341fd09b9499c1e354204fd (plain) (blame)
1
{"version":3,"file":"workbox-broadcast-update.prod.js","sources":["../_version.mjs","../responsesAreSame.mjs","../utils/constants.mjs","../broadcastUpdate.mjs","../BroadcastCacheUpdate.mjs","../Plugin.mjs"],"sourcesContent":["try{self['workbox:broadcast-update: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 {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport './_version.mjs';\n\n/**\n * Given two `Response's`, compares several header values to see if they are\n * the same or not.\n *\n * @param {Response} firstResponse\n * @param {Response} secondResponse\n * @param {Array<string>} headersToCheck\n * @return {boolean}\n *\n * @memberof workbox.broadcastUpdate\n * @private\n */\nconst responsesAreSame = (firstResponse, secondResponse, headersToCheck) => {\n  if (process.env.NODE_ENV !== 'production') {\n    if (!(firstResponse instanceof Response &&\n      secondResponse instanceof Response)) {\n      throw new WorkboxError('invalid-responses-are-same-args');\n    }\n  }\n\n  const atLeastOneHeaderAvailable = headersToCheck.some((header) => {\n    return firstResponse.headers.has(header) &&\n      secondResponse.headers.has(header);\n  });\n\n  if (!atLeastOneHeaderAvailable) {\n    if (process.env.NODE_ENV !== 'production') {\n      logger.warn(`Unable to determine where the response has been updated ` +\n        `because none of the headers that would be checked are present.`);\n      logger.debug(`Attempting to compare the following: `,\n          firstResponse, secondResponse, headersToCheck);\n    }\n\n    // Just return true, indicating the that responses are the same, since we\n    // can't determine otherwise.\n    return true;\n  }\n\n  return headersToCheck.every((header) => {\n    const headerStateComparison = firstResponse.headers.has(header) ===\n      secondResponse.headers.has(header);\n    const headerValueComparison = firstResponse.headers.get(header) ===\n      secondResponse.headers.get(header);\n\n    return headerStateComparison && headerValueComparison;\n  });\n};\n\nexport {responsesAreSame};\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 '../_version.mjs';\n\nexport const CACHE_UPDATED_MESSAGE_TYPE = 'CACHE_UPDATED';\nexport const CACHE_UPDATED_MESSAGE_META = 'workbox-broadcast-update';\nexport const DEFAULT_BROADCAST_CHANNEL_NAME = 'workbox';\nexport const DEFAULT_DEFER_NOTIFICATION_TIMEOUT = 10000;\nexport const DEFAULT_HEADERS_TO_CHECK = [\n  'content-length',\n  'etag',\n  'last-modified',\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 {CACHE_UPDATED_MESSAGE_TYPE, CACHE_UPDATED_MESSAGE_META}\n  from './utils/constants.mjs';\n\nimport './_version.mjs';\n\n/**\n * You would not normally call this method directly; it's called automatically\n * by an instance of the {@link BroadcastCacheUpdate} class. It's exposed here\n * for the benefit of developers who would rather not use the full\n * `BroadcastCacheUpdate` implementation.\n *\n * Calling this will dispatch a message on the provided\n * {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel}\n * to notify interested subscribers about a change to a cached resource.\n *\n * The message that's posted has a formation inspired by the\n * [Flux standard action](https://github.com/acdlite/flux-standard-action#introduction)\n * format like so:\n *\n * ```\n * {\n *   type: 'CACHE_UPDATED',\n *   meta: 'workbox-broadcast-update',\n *   payload: {\n *     cacheName: 'the-cache-name',\n *     updatedURL: 'https://example.com/'\n *   }\n * }\n * ```\n *\n * (Usage of [Flux](https://facebook.github.io/flux/) itself is not at\n * all required.)\n *\n * @param {Object} options\n * @param {string} options.cacheName The name of the cache in which the updated\n *     `Response` was stored.\n * @param {string} options.url The URL associated with the updated `Response`.\n * @param {BroadcastChannel} [options.channel] The `BroadcastChannel` to use.\n *     If no channel is set or the browser doesn't support the BroadcastChannel\n *     api, then an attempt will be made to `postMessage` each window client.\n *\n * @memberof workbox.broadcastUpdate\n */\nconst broadcastUpdate = async ({channel, cacheName, url}) => {\n  if (process.env.NODE_ENV !== 'production') {\n    assert.isType(cacheName, 'string', {\n      moduleName: 'workbox-broadcast-update',\n      className: '~',\n      funcName: 'broadcastUpdate',\n      paramName: 'cacheName',\n    });\n    assert.isType(url, 'string', {\n      moduleName: 'workbox-broadcast-update',\n      className: '~',\n      funcName: 'broadcastUpdate',\n      paramName: 'url',\n    });\n  }\n\n  const data = {\n    type: CACHE_UPDATED_MESSAGE_TYPE,\n    meta: CACHE_UPDATED_MESSAGE_META,\n    payload: {\n      cacheName: cacheName,\n      updatedURL: url,\n    },\n  };\n\n  if (channel) {\n    channel.postMessage(data);\n  } else {\n    const windows = await clients.matchAll({type: 'window'});\n    for (const win of windows) {\n      win.postMessage(data);\n    }\n  }\n};\n\nexport {broadcastUpdate};\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 {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport {Deferred} from 'workbox-core/_private/Deferred.mjs';\nimport {responsesAreSame} from './responsesAreSame.mjs';\nimport {broadcastUpdate} from './broadcastUpdate.mjs';\n\nimport {DEFAULT_HEADERS_TO_CHECK, DEFAULT_BROADCAST_CHANNEL_NAME,\n  DEFAULT_DEFER_NOTIFICATION_TIMEOUT} from './utils/constants.mjs';\n\nimport './_version.mjs';\n\n/**\n * Uses the [Broadcast Channel API]{@link https://developers.google.com/web/updates/2016/09/broadcastchannel}\n * to notify interested parties when a cached response has been updated.\n * In browsers that do not support the Broadcast Channel API, the instance\n * falls back to sending the update via `postMessage()` to all window clients.\n *\n * For efficiency's sake, the underlying response bodies are not compared;\n * only specific response headers are checked.\n *\n * @memberof workbox.broadcastUpdate\n */\nclass BroadcastCacheUpdate {\n  /**\n   * Construct a BroadcastCacheUpdate instance with a specific `channelName` to\n   * broadcast messages on\n   *\n   * @param {Object} options\n   * @param {Array<string>}\n   *     [options.headersToCheck=['content-length', 'etag', 'last-modified']]\n   *     A list of headers that will be used to determine whether the responses\n   *     differ.\n   * @param {string} [options.channelName='workbox'] The name that will be used\n   *.    when creating the `BroadcastChannel`, which defaults to 'workbox' (the\n   *     channel name used by the `workbox-window` package).\n   * @param {string} [options.deferNoticationTimeout=10000] The amount of time\n   *     to wait for a ready message from the window on navigation requests\n   *     before sending the update.\n   */\n  constructor({headersToCheck, channelName, deferNoticationTimeout} = {}) {\n    this._headersToCheck = headersToCheck || DEFAULT_HEADERS_TO_CHECK;\n    this._channelName = channelName || DEFAULT_BROADCAST_CHANNEL_NAME;\n    this._deferNoticationTimeout =\n        deferNoticationTimeout || DEFAULT_DEFER_NOTIFICATION_TIMEOUT;\n\n    if (process.env.NODE_ENV !== 'production') {\n      assert.isType(this._channelName, 'string', {\n        moduleName: 'workbox-broadcast-update',\n        className: 'BroadcastCacheUpdate',\n        funcName: 'constructor',\n        paramName: 'channelName',\n      });\n      assert.isArray(this._headersToCheck, {\n        moduleName: 'workbox-broadcast-update',\n        className: 'BroadcastCacheUpdate',\n        funcName: 'constructor',\n        paramName: 'headersToCheck',\n      });\n    }\n\n    this._initWindowReadyDeferreds();\n  }\n\n  /**\n   * Compare two [Responses](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n   * and send a message via the\n   * {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel API}\n   * if they differ.\n   *\n   * Neither of the Responses can be {@link http://stackoverflow.com/questions/39109789|opaque}.\n   *\n   * @param {Object} options\n   * @param {Response} options.oldResponse Cached response to compare.\n   * @param {Response} options.newResponse Possibly updated response to compare.\n   * @param {string} options.url The URL of the request.\n   * @param {string} options.cacheName Name of the cache the responses belong\n   *     to. This is included in the broadcast message.\n   * @param {Event} [options.event] event An optional event that triggered\n   *     this possible cache update.\n   * @return {Promise} Resolves once the update is sent.\n   */\n  notifyIfUpdated({oldResponse, newResponse, url, cacheName, event}) {\n    if (!responsesAreSame(oldResponse, newResponse, this._headersToCheck)) {\n      if (process.env.NODE_ENV !== 'production') {\n        logger.log(`Newer response found (and cached) for:`, url);\n      }\n\n      const sendUpdate = async () => {\n        // In the case of a navigation request, the requesting page will likely\n        // not have loaded its JavaScript in time to recevied the update\n        // notification, so we defer it until ready (or we timeout waiting).\n        if (event && event.request && event.request.mode === 'navigate') {\n          if (process.env.NODE_ENV !== 'production') {\n            logger.debug(`Original request was a navigation request, ` +\n                `waiting for a ready message from the window`, event.request);\n          }\n          await this._windowReadyOrTimeout(event);\n        }\n        await this._broadcastUpdate({\n          channel: this._getChannel(),\n          cacheName,\n          url,\n        });\n      };\n\n      // Send the update and ensure the SW stays alive until it's sent.\n      const done = sendUpdate();\n\n      if (event) {\n        try {\n          event.waitUntil(done);\n        } catch (error) {\n          if (process.env.NODE_ENV !== 'production') {\n            logger.warn(`Unable to ensure service worker stays alive ` +\n                `when broadcasting cache update for ` +\n                `${getFriendlyURL(event.request.url)}'.`);\n          }\n        }\n      }\n      return done;\n    }\n  }\n\n  /**\n   * NOTE: this is exposed on the instance primarily so it can be spied on\n   * in tests.\n   *\n   * @param {Object} opts\n   * @private\n   */\n  async _broadcastUpdate(opts) {\n    await broadcastUpdate(opts);\n  }\n\n  /**\n   * @return {BroadcastChannel|undefined} The BroadcastChannel instance used for\n   * broadcasting updates, or undefined if the browser doesn't support the\n   * Broadcast Channel API.\n   *\n   * @private\n   */\n  _getChannel() {\n    if (('BroadcastChannel' in self) && !this._channel) {\n      this._channel = new BroadcastChannel(this._channelName);\n    }\n    return this._channel;\n  }\n\n  /**\n   * Waits for a message from the window indicating that it's capable of\n   * receiving broadcasts. By default, this will only wait for the amount of\n   * time specified via the `deferNoticationTimeout` option.\n   *\n   * @param {Event} event The navigation fetch event.\n   * @return {Promise}\n   * @private\n   */\n  _windowReadyOrTimeout(event) {\n    if (!this._navigationEventsDeferreds.has(event)) {\n      const deferred = new Deferred();\n\n      // Set the deferred on the `_navigationEventsDeferreds` map so it will\n      // be resolved when the next ready message event comes.\n      this._navigationEventsDeferreds.set(event, deferred);\n\n      // But don't wait too long for the message since it may never come.\n      const timeout = setTimeout(() => {\n        if (process.env.NODE_ENV !== 'production') {\n          logger.debug(`Timed out after ${this._deferNoticationTimeout}` +\n              `ms waiting for message from window`);\n        }\n        deferred.resolve();\n      }, this._deferNoticationTimeout);\n\n      // Ensure the timeout is cleared if the deferred promise is resolved.\n      deferred.promise.then(() => clearTimeout(timeout));\n    }\n    return this._navigationEventsDeferreds.get(event).promise;\n  }\n\n  /**\n   * Creates a mapping between navigation fetch events and deferreds, and adds\n   * a listener for message events from the window. When message events arrive,\n   * all deferreds in the mapping are resolved.\n   *\n   * Note: it would be easier if we could only resolve the deferred of\n   * navigation fetch event whose client ID matched the source ID of the\n   * message event, but currently client IDs are not exposed on navigation\n   * fetch events: https://www.chromestatus.com/feature/4846038800138240\n   *\n   * @private\n   */\n  _initWindowReadyDeferreds() {\n    // A mapping between navigation events and their deferreds.\n    this._navigationEventsDeferreds = new Map();\n\n    // The message listener needs to be added in the initial run of the\n    // service worker, but since we don't actually need to be listening for\n    // messages until the cache updates, we only invoke the callback if set.\n    self.addEventListener('message', (event) => {\n      if (event.data.type === 'WINDOW_READY' &&\n          event.data.meta === 'workbox-window' &&\n          this._navigationEventsDeferreds.size > 0) {\n        if (process.env.NODE_ENV !== 'production') {\n          logger.debug(`Received WINDOW_READY event: `, event);\n        }\n        // Resolve any pending deferreds.\n        for (const deferred of this._navigationEventsDeferreds.values()) {\n          deferred.resolve();\n        }\n        this._navigationEventsDeferreds.clear();\n      }\n    });\n  }\n}\n\nexport {BroadcastCacheUpdate};\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 {BroadcastCacheUpdate} from './BroadcastCacheUpdate.mjs';\nimport './_version.mjs';\n\n/**\n * This plugin will automatically broadcast a message whenever a cached response\n * is updated.\n *\n * @memberof workbox.broadcastUpdate\n */\nclass Plugin {\n  /**\n   * Construct a BroadcastCacheUpdate instance with the passed options and\n   * calls its `notifyIfUpdated()` method whenever the plugin's\n   * `cacheDidUpdate` callback is invoked.\n   *\n   * @param {Object} options\n   * @param {Array<string>}\n   *     [options.headersToCheck=['content-length', 'etag', 'last-modified']]\n   *     A list of headers that will be used to determine whether the responses\n   *     differ.\n   * @param {string} [options.channelName='workbox'] The name that will be used\n   *.    when creating the `BroadcastChannel`, which defaults to 'workbox' (the\n   *     channel name used by the `workbox-window` package).\n   * @param {string} [options.deferNoticationTimeout=10000] The amount of time\n   *     to wait for a ready message from the window on navigation requests\n   *     before sending the update.\n   */\n  constructor(options) {\n    this._broadcastUpdate = new BroadcastCacheUpdate(options);\n  }\n\n  /**\n   * A \"lifecycle\" callback that will be triggered automatically by the\n   * `workbox-sw` and `workbox-runtime-caching` handlers when an entry is\n   * added to a cache.\n   *\n   * @private\n   * @param {Object} options The input object to this function.\n   * @param {string} options.cacheName Name of the cache being updated.\n   * @param {Response} [options.oldResponse] The previous cached value, if any.\n   * @param {Response} options.newResponse The new value in the cache.\n   * @param {Request} options.request The request that triggered the udpate.\n   * @param {Request} [options.event] The event that triggered the update.\n   */\n  cacheDidUpdate({cacheName, oldResponse, newResponse, request, event}) {\n    if (process.env.NODE_ENV !== 'production') {\n      assert.isType(cacheName, 'string', {\n        moduleName: 'workbox-broadcast-update',\n        className: 'Plugin',\n        funcName: 'cacheDidUpdate',\n        paramName: 'cacheName',\n      });\n      assert.isInstance(newResponse, Response, {\n        moduleName: 'workbox-broadcast-update',\n        className: 'Plugin',\n        funcName: 'cacheDidUpdate',\n        paramName: 'newResponse',\n      });\n      assert.isInstance(request, Request, {\n        moduleName: 'workbox-broadcast-update',\n        className: 'Plugin',\n        funcName: 'cacheDidUpdate',\n        paramName: 'request',\n      });\n    }\n\n    if (!oldResponse) {\n      // Without a two responses there is nothing to compare.\n      return;\n    }\n    this._broadcastUpdate.notifyIfUpdated({\n      cacheName,\n      oldResponse,\n      newResponse,\n      event,\n      url: request.url,\n    });\n  }\n}\n\nexport {Plugin};\n"],"names":["self","_","e","responsesAreSame","firstResponse","secondResponse","headersToCheck","some","header","headers","has","every","headerStateComparison","headerValueComparison","get","DEFAULT_BROADCAST_CHANNEL_NAME","DEFAULT_DEFER_NOTIFICATION_TIMEOUT","DEFAULT_HEADERS_TO_CHECK","broadcastUpdate","async","channel","cacheName","url","data","type","meta","payload","updatedURL","postMessage","windows","clients","matchAll","win","BroadcastCacheUpdate","constructor","channelName","deferNoticationTimeout","_headersToCheck","_channelName","_deferNoticationTimeout","_initWindowReadyDeferreds","notifyIfUpdated","oldResponse","newResponse","event","this","done","request","mode","_windowReadyOrTimeout","_broadcastUpdate","_getChannel","sendUpdate","waitUntil","error","opts","_channel","BroadcastChannel","_navigationEventsDeferreds","deferred","Deferred","set","timeout","setTimeout","resolve","promise","then","clearTimeout","Map","addEventListener","size","values","clear","options","cacheDidUpdate"],"mappings":"sFAAA,IAAIA,KAAK,mCAAmCC,IAAI,MAAMC,UCwBhDC,EAAmB,CAACC,EAAeC,EAAgBC,YAQrBA,EAAeC,KAAMC,GAC9CJ,EAAcK,QAAQC,IAAIF,IAC/BH,EAAeI,QAAQC,IAAIF,KAgBxBF,EAAeK,MAAOH,UACrBI,EAAwBR,EAAcK,QAAQC,IAAIF,KACtDH,EAAeI,QAAQC,IAAIF,GACvBK,EAAwBT,EAAcK,QAAQK,IAAIN,KACtDH,EAAeI,QAAQK,IAAIN,UAEtBI,GAAyBC,KC5CvBE,EAAiC,UACjCC,EAAqC,IACrCC,EAA2B,CACtC,iBACA,OACA,iBCmCIC,EAAkBC,OAAQC,QAAAA,EAASC,UAAAA,EAAWC,IAAAA,YAgB5CC,EAAO,CACXC,KD3DsC,gBC4DtCC,KD3DsC,2BC4DtCC,QAAS,CACPL,UAAWA,EACXM,WAAYL,OAIZF,EACFA,EAAQQ,YAAYL,OACf,OACCM,QAAgBC,QAAQC,SAAS,CAACP,KAAM,eACzC,MAAMQ,KAAOH,EAChBG,EAAIJ,YAAYL,KCnDtB,MAAMU,EAiBJC,aAAY5B,eAACA,EAAD6B,YAAiBA,EAAjBC,uBAA8BA,GAA0B,SAC7DC,EAAkB/B,GAAkBW,OACpCqB,EAAeH,GAAepB,OAC9BwB,EACDH,GAA0BpB,OAiBzBwB,IAqBPC,iBAAgBC,YAACA,EAADC,YAAcA,EAAdrB,IAA2BA,EAA3BD,UAAgCA,EAAhCuB,MAA2CA,QACpDzC,EAAiBuC,EAAaC,EAAaE,KAAKR,GAAkB,OAwB/DS,EAnBa3B,WAIbyB,GAASA,EAAMG,SAAkC,aAAvBH,EAAMG,QAAQC,YAKpCH,KAAKI,EAAsBL,SAE7BC,KAAKK,EAAiB,CAC1B9B,QAASyB,KAAKM,IACd9B,UAAAA,EACAC,IAAAA,KAKS8B,MAETR,MAEAA,EAAMS,UAAUP,GAChB,MAAOQ,WAQJR,WAWYS,SACfrC,EAAgBqC,GAUxBJ,UACO,qBAAsBnD,OAAU6C,KAAKW,SACnCA,EAAW,IAAIC,iBAAiBZ,KAAKP,IAErCO,KAAKW,EAYdP,EAAsBL,OACfC,KAAKa,EAA2BhD,IAAIkC,GAAQ,OACzCe,EAAW,IAAIC,gBAIhBF,EAA2BG,IAAIjB,EAAOe,SAGrCG,EAAUC,WAAW,KAKzBJ,EAASK,WACRnB,KAAKN,GAGRoB,EAASM,QAAQC,KAAK,IAAMC,aAAaL,WAEpCjB,KAAKa,EAA2B5C,IAAI8B,GAAOqB,QAepDzB,SAEOkB,EAA6B,IAAIU,IAKtCpE,KAAKqE,iBAAiB,UAAYzB,OACR,iBAApBA,EAAMrB,KAAKC,MACS,mBAApBoB,EAAMrB,KAAKE,MACXoB,KAAKa,EAA2BY,KAAO,EAAG,KAKvC,MAAMX,KAAYd,KAAKa,EAA2Ba,SACrDZ,EAASK,eAENN,EAA2Bc,qDCzMxC,MAkBEtC,YAAYuC,QACLvB,EAAmB,IAAIjB,EAAqBwC,GAgBnDC,gBAAerD,UAACA,EAADqB,YAAYA,EAAZC,YAAyBA,EAAzBI,QAAsCA,EAAtCH,MAA+CA,IAsBvDF,QAIAQ,EAAiBT,gBAAgB,CACpCpB,UAAAA,EACAqB,YAAAA,EACAC,YAAAA,EACAC,MAAAA,EACAtB,IAAKyB,EAAQzB"}