{ "version": 3, "sources": ["../../../node_modules/.aspect_rules_js/@fullstory+service-worker-registration@0.0.0/node_modules/@fullstory/service-worker-registration/client.ts", "../../../node_modules/.aspect_rules_js/@fullstory+service-worker-registration@0.0.0/node_modules/@fullstory/service-worker-registration/iframe.ts", "../src/register-playback-service-worker.main.ts"], "sourcesContent": ["import type { ClientMessage, IFrameMessage } from './messages';\n\n/**\n * Reasons why registration can fail\n */\nexport enum FailureReason {\n StorageAccessError,\n UnknownError,\n}\n\n// Register a cross-origin service worker inside an iframe. The provided\n// registration page must be a document running on the appropriate origin which\n// will call registerServiceWorkerAndNotifyOuterDocument(); that function\n// implements the other half of the protocol. Returns a promise that resolves\n// when the service worker is registered and ready. See `iframe.ts` for the\n// other half of the protocol.\nexport function registerCrossOriginServiceWorker(\n registrationPageHref: string,\n parentDoc: Document = document,\n): Promise {\n return new Promise((resolve, reject) => {\n const iframe: HTMLIFrameElement = parentDoc.createElement('iframe');\n\n const channel = new MessageChannel();\n channel.port1.onmessage = (message: MessageEvent) => {\n if (message.data === 'ready') {\n console.debug(`Received message that the cross-origin service worker is ready.`);\n parentDoc.body.removeChild(iframe);\n resolve();\n return;\n }\n\n if (message.data === 'storageAccessError') {\n reject({\n message: 'Storage access is required',\n reason: FailureReason.StorageAccessError,\n });\n }\n\n if (message.data === 'unknownError') {\n reject({\n message: 'An unknown error occurred',\n reason: FailureReason.UnknownError,\n });\n }\n\n reject({\n message: `Received unexpected message: ${message.data}`,\n reason: FailureReason.UnknownError,\n });\n };\n\n iframe.setAttribute('style', 'display: none');\n iframe.src = registrationPageHref;\n iframe.addEventListener('load', () => {\n console.debug(`Got load event for registration page. Sending MessagePort`);\n // NOTE: this typed const helps ensure message type safety\n const message: ClientMessage = 'init';\n iframe.contentWindow!.postMessage(message, '*', [channel.port2]);\n });\n console.debug(`Attached iframe that will register service worker`);\n parentDoc.body.appendChild(iframe);\n });\n}\n", "import '@fullstory/typeutils';\nimport type { ClientMessage, IFrameMessage } from './messages';\n\n// Register a service worker for the given scope (which doesn't need to include\n// the current document). Returns a promise that resolves when the new service\n// worker is either active or has been made redundant by a newer active service\n// worker.\nexport async function registerServiceWorker(\n workerHref: string,\n scope?: string,\n): Promise {\n if (!navigator.serviceWorker) {\n throw new Error(`The service worker API is unavailable`);\n }\n\n const registration = await navigator.serviceWorker.register(workerHref, { scope });\n console.log(`Service worker registration succeeded for scope '${scope ? scope : 'default'}'.`);\n\n // Trigger an update if a (possibly out-of-date) service worker is already\n // active. (When there's no active service worker, update() throws.)\n const existingServiceWorker = registration.active;\n if (existingServiceWorker) {\n await registration.update();\n }\n console.log(`Service worker updated.`);\n\n if (existingServiceWorker) {\n return registration;\n }\n\n const serviceWorkerReady = new Promise(resolve => {\n // Find the newest service worker - in other words, the one which is at the\n // earliest stage of the life cycle. That should be the one we just\n // registered. Because service worker installation happens in parallel, it\n // may already be active.\n const newServiceWorker = registration.installing || registration.waiting || registration.active;\n if (!newServiceWorker) {\n throw new Error(`No pending or active service worker`);\n }\n\n // Wait for the new service worker to be either activated, in which case\n // it's ready for use, or redundant, which may happen if an even newer\n // service worker gets loaded in parallel in another tab. The latter isn't a\n // problem; the main thing we want to ensure is that *some* service worker\n // is active and it's at least as new as the one we just registered.\n const onStateChange = () => {\n console.debug(`New service worker is now ${newServiceWorker.state}.`);\n switch (newServiceWorker.state) {\n case 'activated':\n case 'redundant':\n newServiceWorker.removeEventListener('statechange', onStateChange);\n resolve();\n break;\n }\n };\n newServiceWorker.addEventListener('statechange', onStateChange);\n\n // Check the initial state.\n onStateChange();\n });\n\n await serviceWorkerReady;\n return registration;\n}\n\n// Register a service worker and then notify the outer page that it's ready.\n// This function implements the half of the registerCrossOriginServiceWorker()\n// protocol that runs inside the cross-domain iframe; it should be called from a\n// top-level, synchronous script in that iframe. See `client.ts` for the other\n// half of the protocol.\nexport function registerServiceWorkerAndNotifyOuterDocument(workerHref: string, scope: string) {\n // Wait for an 'init' message from the outer document. The message will contain\n // a MessagePort that we'll use to notify the outer document when the service\n // worker is ready.\n const portReady = new Promise(resolve => {\n window.addEventListener('message', (message: MessageEvent) => {\n if (message.data !== 'init') {\n console.debug(\n `Received unexpected message during service worker registration: ${message.data}`,\n );\n return;\n }\n\n const parentPort = message.ports[0];\n if (!parentPort) {\n throw new Error(`Expected to receive message port`);\n }\n\n resolve(parentPort);\n });\n });\n\n // Register the service worker. If the service worker is already running, this\n // will update it to the latest version. It's important that the scope doesn't\n // include this page! Otherwise, a bug in the service worker could prevent\n // this page from loading and make it difficult to deliver updates.\n const currentPath = window.location.pathname;\n if (currentPath.startsWith(scope)) {\n throw new Error(\n `Refusing to register service worker with scope '${scope}', ` +\n `which includes the registering document ${currentPath}`,\n );\n }\n\n const workerReady = registerServiceWorker(workerHref, scope);\n\n const storageAccessCheck =\n (document.hasStorageAccess && document.hasStorageAccess()) ?? Promise.resolve(true);\n\n // Once all the pieces fall into place, notify the outer document.\n Promise.allSettled([portReady, workerReady, storageAccessCheck]).then(\n ([portResult, workerResult, storageAccessCheckResult]) => {\n if (portResult.status === 'rejected') {\n console.debug('Service worker installation failed.');\n throw new Error('Unable to register port to outer document');\n }\n\n if (workerResult.status === 'rejected') {\n console.debug('Service worker installation failed.');\n const granted =\n storageAccessCheckResult.status === 'fulfilled' ? storageAccessCheckResult.value : true;\n // NOTE: this typed const helps ensure message type safety\n const errorMessage: IFrameMessage = granted ? 'unknownError' : 'storageAccessError';\n portResult.value.postMessage(errorMessage);\n return;\n }\n\n console.debug('Service worker installed.');\n // NOTE: this typed const helps ensure message type safety\n const message: IFrameMessage = 'ready';\n portResult.value.postMessage(message);\n },\n );\n}\n", "import { registerServiceWorkerAndNotifyOuterDocument } from '@fullstory/service-worker-registration';\n\nconst workerHref = '/s/playback-service-worker.js';\nconst scope = '/s/playback/';\nregisterServiceWorkerAndNotifyOuterDocument(workerHref, scope);\n"], "mappings": "MAKA,IAAYA,GAAZ,SAAYA,EAAa,CACvBA,EAAAA,EAAA,mBAAA,CAAA,EAAA,qBACAA,EAAAA,EAAA,aAAA,CAAA,EAAA,cACF,GAHYA,IAAAA,EAAa,CAAA,EAAA,ECEzB,eAAsBC,EACpBC,EACAC,EAAc,CAEd,GAAI,CAAC,UAAU,cACb,MAAM,IAAI,MAAM,uCAAuC,EAGzD,IAAMC,EAAe,MAAM,UAAU,cAAc,SAASF,EAAY,CAAE,MAAAC,CAAK,CAAE,EACjF,QAAQ,IAAI,oDAAoDA,GAAgB,aAAa,EAI7F,IAAME,EAAwBD,EAAa,OAM3C,OALIC,GACF,MAAMD,EAAa,OAAM,EAE3B,QAAQ,IAAI,yBAAyB,EAEjCC,GAmCJ,MA/B2B,IAAI,QAAcC,GAAU,CAKrD,IAAMC,EAAmBH,EAAa,YAAcA,EAAa,SAAWA,EAAa,OACzF,GAAI,CAACG,EACH,MAAM,IAAI,MAAM,qCAAqC,EAQvD,IAAMC,EAAgB,IAAK,CAEzB,OADA,QAAQ,MAAM,6BAA6BD,EAAiB,QAAQ,EAC5DA,EAAiB,MAAO,CAC9B,IAAK,YACL,IAAK,YACHA,EAAiB,oBAAoB,cAAeC,CAAa,EACjEF,EAAO,EACP,KACJ,CACF,EACAC,EAAiB,iBAAiB,cAAeC,CAAa,EAG9DA,EAAa,CACf,CAAC,EAGMJ,CACT,CAOM,SAAUK,EAA4CP,EAAoBC,EAAa,OAI3F,IAAMO,EAAY,IAAI,QAAqBJ,GAAU,CACnD,OAAO,iBAAiB,UAAYK,GAAwC,CAC1E,GAAIA,EAAQ,OAAS,OAAQ,CAC3B,QAAQ,MACN,mEAAmEA,EAAQ,MAAM,EAEnF,MACF,CAEA,IAAMC,EAAaD,EAAQ,MAAM,CAAC,EAClC,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,kCAAkC,EAGpDN,EAAQM,CAAU,CACpB,CAAC,CACH,CAAC,EAMKC,EAAc,OAAO,SAAS,SACpC,GAAIA,EAAY,WAAWV,CAAK,EAC9B,MAAM,IAAI,MACR,mDAAmDA,+CACNU,GAAa,EAI9D,IAAMC,EAAcb,EAAsBC,EAAYC,CAAK,EAErDY,GACJC,EAAC,SAAS,kBAAoB,SAAS,iBAAgB,KAAG,MAAAA,IAAA,OAAAA,EAAI,QAAQ,QAAQ,EAAI,EAGpF,QAAQ,WAAW,CAACN,EAAWI,EAAaC,CAAkB,CAAC,EAAE,KAC/D,CAAC,CAACE,EAAYC,EAAcC,CAAwB,IAAK,CACvD,GAAIF,EAAW,SAAW,WACxB,cAAQ,MAAM,qCAAqC,EAC7C,IAAI,MAAM,2CAA2C,EAG7D,GAAIC,EAAa,SAAW,WAAY,CACtC,QAAQ,MAAM,qCAAqC,EAInD,IAAME,GAFJD,EAAyB,SAAW,YAAcA,EAAyB,MAAQ,IAEvC,eAAiB,qBAC/DF,EAAW,MAAM,YAAYG,CAAY,EACzC,MACF,CAEA,QAAQ,MAAM,2BAA2B,EAEzC,IAAMT,EAAyB,QAC/BM,EAAW,MAAM,YAAYN,CAAO,CACtC,CAAC,CAEL,CCnIA,IAAMU,EAAa,gCACbC,EAAQ,eACdC,EAA4CF,EAAYC,CAAK", "names": ["FailureReason", "registerServiceWorker", "workerHref", "scope", "registration", "existingServiceWorker", "resolve", "newServiceWorker", "onStateChange", "registerServiceWorkerAndNotifyOuterDocument", "portReady", "message", "parentPort", "currentPath", "workerReady", "storageAccessCheck", "_a", "portResult", "workerResult", "storageAccessCheckResult", "errorMessage", "workerHref", "scope", "registerServiceWorkerAndNotifyOuterDocument"] }