(
private scope: ServiceWorkerGlobalScope,
private adapter: Adapter,
private db: Database,
)
| 159 | private controlTable: Promise<Table>; |
| 160 | |
| 161 | constructor( |
| 162 | private scope: ServiceWorkerGlobalScope, |
| 163 | private adapter: Adapter, |
| 164 | private db: Database, |
| 165 | ) { |
| 166 | this.controlTable = this.db.open('control'); |
| 167 | this.ngswStatePath = this.adapter.parseUrl('ngsw/state', this.scope.registration.scope).path; |
| 168 | |
| 169 | // Set up all the event handlers that the SW needs. |
| 170 | |
| 171 | // The install event is triggered when the service worker is first installed. |
| 172 | this.scope.addEventListener('install', (event) => { |
| 173 | // SW code updates are separate from application updates, so code updates are |
| 174 | // almost as straightforward as restarting the SW. Because of this, it's always |
| 175 | // safe to skip waiting until application tabs are closed, and activate the new |
| 176 | // SW version immediately. |
| 177 | event!.waitUntil(this.scope.skipWaiting()); |
| 178 | }); |
| 179 | |
| 180 | // The activate event is triggered when this version of the service worker is |
| 181 | // first activated. |
| 182 | this.scope.addEventListener('activate', (event) => { |
| 183 | event!.waitUntil( |
| 184 | (async () => { |
| 185 | // As above, it's safe to take over from existing clients immediately, since the new SW |
| 186 | // version will continue to serve the old application. |
| 187 | await this.scope.clients.claim(); |
| 188 | })(), |
| 189 | ); |
| 190 | |
| 191 | // Rather than wait for the first fetch event, which may not arrive until |
| 192 | // the next time the application is loaded, the SW takes advantage of the |
| 193 | // activation event to schedule initialization. However, if this were run |
| 194 | // in the context of the 'activate' event, waitUntil() here would cause fetch |
| 195 | // events to block until initialization completed. Thus, the SW does a |
| 196 | // postMessage() to itself, to schedule a new event loop iteration with an |
| 197 | // entirely separate event context. The SW will be kept alive by waitUntil() |
| 198 | // within that separate context while initialization proceeds, while at the |
| 199 | // same time the activation event is allowed to resolve and traffic starts |
| 200 | // being served. |
| 201 | if (this.scope.registration.active !== null) { |
| 202 | this.scope.registration.active.postMessage({action: 'INITIALIZE'}); |
| 203 | } |
| 204 | }); |
| 205 | |
| 206 | // Handle the fetch, message, push, notificationclick, |
| 207 | // notificationclose, pushsubscriptionchange, messageerror, rejectionhandled, |
| 208 | // and unhandledrejection events. |
| 209 | this.scope.addEventListener('fetch', (event) => this.onFetch(event!)); |
| 210 | this.scope.addEventListener('message', (event) => this.onMessage(event!)); |
| 211 | this.scope.addEventListener('push', (event) => this.onPush(event!)); |
| 212 | this.scope.addEventListener('notificationclick', (event) => this.onClick(event)); |
| 213 | this.scope.addEventListener('notificationclose', (event) => this.onClose(event)); |
| 214 | this.scope.addEventListener('pushsubscriptionchange', (event) => |
| 215 | this.onPushSubscriptionChange(event), |
| 216 | ); |
| 217 | this.scope.addEventListener('messageerror', (event) => this.onMessageError(event)); |
| 218 | this.scope.addEventListener('unhandledrejection', (event) => this.onUnhandledRejection(event)); |
nothing calls this directly
no test coverage detected