service-worker.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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.getRegistrations().then(registrations => {
  54. registrations.forEach(worker => {
  55. worker.unregister()
  56. })
  57. })
  58. }
  59. }