From 1e4f39a9310490eb279fb44a9816e257535e5ea1 Mon Sep 17 00:00:00 2001 From: Jose Luis Represa Date: Tue, 7 Jul 2020 11:58:48 +0200 Subject: [PATCH] feat: move files to the addon directory --- addon/instance-initializers/sw.js | 44 +++++++++ addon/services/service-worker.js | 146 +++++++++++++++++++++++++++++ app/instance-initializers/sw.js | 45 +-------- app/services/service-worker.js | 147 +----------------------------- 4 files changed, 192 insertions(+), 190 deletions(-) create mode 100644 addon/instance-initializers/sw.js create mode 100644 addon/services/service-worker.js diff --git a/addon/instance-initializers/sw.js b/addon/instance-initializers/sw.js new file mode 100644 index 0000000..001a63f --- /dev/null +++ b/addon/instance-initializers/sw.js @@ -0,0 +1,44 @@ +import { getWithDefault } from '@ember/object'; +import { debug } from '@ember/debug'; + +export function getConfig(appInstance) { + const config = appInstance.resolveRegistration('config:environment'); + const isProdBuild = config.environment === 'production'; + + return { + isEnabled: getWithDefault(config, 'ember-cli-workbox.enabled', isProdBuild), + debugAddon: getWithDefault(config, 'ember-cli-workbox.debug', !isProdBuild), + swDestFile: getWithDefault(config, 'workbox.swDest', 'sw.js'), + autoRegister: getWithDefault(config, 'ember-cli-workbox.autoRegister', true) + }; +} + +export function initialize(appInstance) { + const swService = appInstance.lookup('service:service-worker'); + const { isEnabled, debugAddon, swDestFile } = getConfig(appInstance); + + swService.set('debug', debugAddon); + + // first checks whether the browser supports service workers + if (swService.get('isSupported')) { + // Load and register pre-caching Service Worker + if (isEnabled) { + swService.register(swDestFile); + } else { + swService.unregisterAll(); + } + } else { + debug('Service workers are not supported in this browser.'); + } +} + +export default { + name: 'ember-cli-workbox', + initialize(appInstance) { + const { autoRegister } = getConfig(appInstance); + + if (autoRegister) { + initialize(appInstance); + } + } +}; diff --git a/addon/services/service-worker.js b/addon/services/service-worker.js new file mode 100644 index 0000000..5768eca --- /dev/null +++ b/addon/services/service-worker.js @@ -0,0 +1,146 @@ +import Service from '@ember/service'; +import Evented from '@ember/object/evented'; +import { debug } from '@ember/debug'; + +/* + * + * Service worker states: + * "installing" - the install event has fired, but is not yet completed + * "installed" - install completed + * "activating" - the activate event has fired, but is not yet completed + * "activated" - fully active + * "redundant" - discarded. Either failed install, or it's been replaced by a newer version + * + * Events triggered: + * "error" - sw not registered + * "waiting" - new sw waiting for controlling page + * "activated" - the new sw is ready to respond + * "registrationComplete" - sw successfully registered + * "unregistrationComplete" - all sw are unregistered + */ +export default class ServiceWorker extends Service.extend(Evented) { + constructor() { + super(...arguments); + + const sw = window.navigator.serviceWorker; + let isSupported = false; + + if (sw) { + isSupported = [ + 'getRegistrations', + 'register' + ].every((func) => func in sw); + } + + this.sw = sw; + this.isSupported = isSupported; + } + + _log(message) { + if (this.debug) { + debug(`ember-cli-workbox: ${message}`); + } + } + + async register(swFile) { + try { + const registration = await this.sw.register(swFile); + + return this._onRegistration(registration); + } catch (error) { + this.trigger('error', error); + this._log('Service Worker registration failed: ', error); + + throw error; + } + } + + /* + * Utility function that unregisters SW, but you still need to reload to see SW removed completely + * This does not delete items in Cache + */ + async unregisterAll() { + const registrations = await this.sw.getRegistrations(); + + await Promise.all( + registrations.map(async(reg) => { + const boolean = await reg.unregister(); + + if (boolean) { + this._log(`${reg} unregistered`); + } else { + this._log(`Error unregistering ${reg}`); + } + }) + ); + + this.trigger('unregistrationComplete'); + this._log('Unregistrations complete'); + } + + _onRegistration(registration) { + this._log(`Registration succeeded. Scope is ${registration.scope}`); + this.trigger('registrationComplete'); + + if (!registration) { + return; + } + + if (registration.waiting) { + // SW is waiting to activate. Can occur if multiple clients open and + // one of the clients is refreshed. + this._waiting(registration); + } + + // We are currently controlled so a new SW may be found... + // Add a listener in case a new SW is found, + registration.addEventListener('updatefound', () => { + const installingWorker = registration.installing; + + if (!installingWorker) { + return; + } + + if (installingWorker.state === 'installed') { + this._checkSWInstalled(installingWorker, registration); + } else { + installingWorker.addEventListener('statechange', () => { + this._checkSWInstalled(installingWorker, registration); + }); + } + }); + } + + _checkSWInstalled(installingWorker, registration) { + switch (installingWorker.state) { + case 'installed': + if (navigator.serviceWorker.controller) { + // At this point, the updated precached content has been fetched, + // but the previous service worker will still serve the older + // content until all client tabs are closed. + this._log('New content is available and will be used when all tabs for this page are closed.'); + + // Execute callback + this._waiting(registration); + } else { + // At this point, everything has been precached. + // It's the perfect time to display a "Content is cached for offline use." message. + this._log('New serviceworker is controlling page. Content is now available offline!'); + } + break; + default: + break; + } + } + + _waiting(registration) { + this._log('New serviceworker is waiting to activate. New or updated content is available.'); + this.trigger('waiting', registration); + + registration.waiting.addEventListener('statechange', (event) => { + if (event.target.state === 'activated') { + this.trigger('activated', registration); + } + }); + } +} diff --git a/app/instance-initializers/sw.js b/app/instance-initializers/sw.js index 001a63f..71e9a95 100644 --- a/app/instance-initializers/sw.js +++ b/app/instance-initializers/sw.js @@ -1,44 +1 @@ -import { getWithDefault } from '@ember/object'; -import { debug } from '@ember/debug'; - -export function getConfig(appInstance) { - const config = appInstance.resolveRegistration('config:environment'); - const isProdBuild = config.environment === 'production'; - - return { - isEnabled: getWithDefault(config, 'ember-cli-workbox.enabled', isProdBuild), - debugAddon: getWithDefault(config, 'ember-cli-workbox.debug', !isProdBuild), - swDestFile: getWithDefault(config, 'workbox.swDest', 'sw.js'), - autoRegister: getWithDefault(config, 'ember-cli-workbox.autoRegister', true) - }; -} - -export function initialize(appInstance) { - const swService = appInstance.lookup('service:service-worker'); - const { isEnabled, debugAddon, swDestFile } = getConfig(appInstance); - - swService.set('debug', debugAddon); - - // first checks whether the browser supports service workers - if (swService.get('isSupported')) { - // Load and register pre-caching Service Worker - if (isEnabled) { - swService.register(swDestFile); - } else { - swService.unregisterAll(); - } - } else { - debug('Service workers are not supported in this browser.'); - } -} - -export default { - name: 'ember-cli-workbox', - initialize(appInstance) { - const { autoRegister } = getConfig(appInstance); - - if (autoRegister) { - initialize(appInstance); - } - } -}; +export { default, initialize } from 'ember-cli-workbox/instance-initializers/sw'; diff --git a/app/services/service-worker.js b/app/services/service-worker.js index 5768eca..e354403 100644 --- a/app/services/service-worker.js +++ b/app/services/service-worker.js @@ -1,146 +1 @@ -import Service from '@ember/service'; -import Evented from '@ember/object/evented'; -import { debug } from '@ember/debug'; - -/* - * - * Service worker states: - * "installing" - the install event has fired, but is not yet completed - * "installed" - install completed - * "activating" - the activate event has fired, but is not yet completed - * "activated" - fully active - * "redundant" - discarded. Either failed install, or it's been replaced by a newer version - * - * Events triggered: - * "error" - sw not registered - * "waiting" - new sw waiting for controlling page - * "activated" - the new sw is ready to respond - * "registrationComplete" - sw successfully registered - * "unregistrationComplete" - all sw are unregistered - */ -export default class ServiceWorker extends Service.extend(Evented) { - constructor() { - super(...arguments); - - const sw = window.navigator.serviceWorker; - let isSupported = false; - - if (sw) { - isSupported = [ - 'getRegistrations', - 'register' - ].every((func) => func in sw); - } - - this.sw = sw; - this.isSupported = isSupported; - } - - _log(message) { - if (this.debug) { - debug(`ember-cli-workbox: ${message}`); - } - } - - async register(swFile) { - try { - const registration = await this.sw.register(swFile); - - return this._onRegistration(registration); - } catch (error) { - this.trigger('error', error); - this._log('Service Worker registration failed: ', error); - - throw error; - } - } - - /* - * Utility function that unregisters SW, but you still need to reload to see SW removed completely - * This does not delete items in Cache - */ - async unregisterAll() { - const registrations = await this.sw.getRegistrations(); - - await Promise.all( - registrations.map(async(reg) => { - const boolean = await reg.unregister(); - - if (boolean) { - this._log(`${reg} unregistered`); - } else { - this._log(`Error unregistering ${reg}`); - } - }) - ); - - this.trigger('unregistrationComplete'); - this._log('Unregistrations complete'); - } - - _onRegistration(registration) { - this._log(`Registration succeeded. Scope is ${registration.scope}`); - this.trigger('registrationComplete'); - - if (!registration) { - return; - } - - if (registration.waiting) { - // SW is waiting to activate. Can occur if multiple clients open and - // one of the clients is refreshed. - this._waiting(registration); - } - - // We are currently controlled so a new SW may be found... - // Add a listener in case a new SW is found, - registration.addEventListener('updatefound', () => { - const installingWorker = registration.installing; - - if (!installingWorker) { - return; - } - - if (installingWorker.state === 'installed') { - this._checkSWInstalled(installingWorker, registration); - } else { - installingWorker.addEventListener('statechange', () => { - this._checkSWInstalled(installingWorker, registration); - }); - } - }); - } - - _checkSWInstalled(installingWorker, registration) { - switch (installingWorker.state) { - case 'installed': - if (navigator.serviceWorker.controller) { - // At this point, the updated precached content has been fetched, - // but the previous service worker will still serve the older - // content until all client tabs are closed. - this._log('New content is available and will be used when all tabs for this page are closed.'); - - // Execute callback - this._waiting(registration); - } else { - // At this point, everything has been precached. - // It's the perfect time to display a "Content is cached for offline use." message. - this._log('New serviceworker is controlling page. Content is now available offline!'); - } - break; - default: - break; - } - } - - _waiting(registration) { - this._log('New serviceworker is waiting to activate. New or updated content is available.'); - this.trigger('waiting', registration); - - registration.waiting.addEventListener('statechange', (event) => { - if (event.target.state === 'activated') { - this.trigger('activated', registration); - } - }); - } -} +export { default } from 'ember-cli-workbox/services/service-worker';