service-worker.js 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import { captureException } from '../../../infrastructure/error-reporter'
  2. const OError = require('@overleaf/o-error')
  3. let pendingWorkerSetup = Promise.resolve()
  4. function supportsServiceWorker() {
  5. return 'serviceWorker' in navigator
  6. }
  7. export function waitForServiceWorker() {
  8. return pendingWorkerSetup
  9. }
  10. export function loadServiceWorker(options) {
  11. if (supportsServiceWorker()) {
  12. const workerSetup = navigator.serviceWorker
  13. .register('/serviceWorker.js', {
  14. scope: '/project/',
  15. })
  16. .then(() => {
  17. navigator.serviceWorker.addEventListener('message', event => {
  18. let ctx
  19. try {
  20. ctx = JSON.parse(event.data)
  21. } catch (e) {
  22. return
  23. }
  24. if (!ctx || !ctx.error || !ctx.extra) return
  25. const err = OError.tag(ctx.error, 'Error in serviceWorker')
  26. const fullError = new Error()
  27. fullError.name = err.name
  28. fullError.message = err.message
  29. fullError.stack = OError.getFullStack(err)
  30. captureException(fullError, { extra: ctx.extra })
  31. })
  32. })
  33. .catch(error =>
  34. captureException(OError.tag(error, 'Cannot register serviceWorker'))
  35. )
  36. if (options && options.timeout > 0) {
  37. const workerTimeout = new Promise(resolve => {
  38. setTimeout(resolve, options.timeout)
  39. })
  40. pendingWorkerSetup = Promise.race([workerSetup, workerTimeout])
  41. } else {
  42. pendingWorkerSetup = workerSetup
  43. }
  44. }
  45. }
  46. export function unregisterServiceWorker() {
  47. if (supportsServiceWorker()) {
  48. if (navigator.serviceWorker.controller) {
  49. navigator.serviceWorker.controller.postMessage({
  50. type: 'disable',
  51. })
  52. }
  53. navigator.serviceWorker
  54. .getRegistrations()
  55. .catch(error => {
  56. // fail silently if permission not given (e.g. SecurityError)
  57. console.error('error listing service worker registrations', error)
  58. return []
  59. })
  60. .then(registrations => {
  61. registrations.forEach(worker => {
  62. worker.unregister()
  63. })
  64. })
  65. }
  66. }