forked from cybrespace/pinafore
		
	more work on service worker
This commit is contained in:
		
							parent
							
								
									0b442bb2a6
								
							
						
					
					
						commit
						01243ba4c1
					
				
					 3 changed files with 84 additions and 28 deletions
				
			
		
							
								
								
									
										14
									
								
								routes/_utils/asyncModules.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								routes/_utils/asyncModules.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					const importURLSearchParams = () => import(
 | 
				
			||||||
 | 
					  /* webpackChunkName: 'url-search-params' */ 'url-search-params'
 | 
				
			||||||
 | 
					  ).then(Params => {
 | 
				
			||||||
 | 
					  window.URLSearchParams = Params
 | 
				
			||||||
 | 
					  Object.defineProperty(window.URL.prototype, 'searchParams', {
 | 
				
			||||||
 | 
					    get() {
 | 
				
			||||||
 | 
					      return new Params(this.search)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
					  importURLSearchParams
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,16 +1,19 @@
 | 
				
			||||||
import { init } from 'sapper/runtime.js';
 | 
					import { init } from 'sapper/runtime.js'
 | 
				
			||||||
 | 
					import toast from '../routes/_utils/toast.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// polyfills
 | 
					// polyfills
 | 
				
			||||||
Promise.all([
 | 
					Promise.all([
 | 
				
			||||||
  typeof URLSearchParams === 'undefined' && import(/* webpackChunkName: 'url-search-params' */ 'url-search-params').then(Params => {
 | 
					  typeof URLSearchParams === 'undefined' && importURLParams()
 | 
				
			||||||
    window.URLSearchParams = Params
 | 
					 | 
				
			||||||
    Object.defineProperty(window.URL.prototype, 'searchParams', {
 | 
					 | 
				
			||||||
      get() {
 | 
					 | 
				
			||||||
        return new Params(this.search)
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
]).then(() => {
 | 
					]).then(() => {
 | 
				
			||||||
  // `routes` is an array of route objects injected by Sapper
 | 
					  // `routes` is an array of route objects injected by Sapper
 | 
				
			||||||
  init(document.querySelector('#sapper'), __routes__)
 | 
					  init(document.querySelector('#sapper'), __routes__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (navigator.serviceWorker && navigator.serviceWorker.controller) {
 | 
				
			||||||
 | 
					    navigator.serviceWorker.controller.onstatechange = (e) => {
 | 
				
			||||||
 | 
					      if (e.target.state === 'redundant') {
 | 
				
			||||||
 | 
					        toast.say('App update available. Reload to update.');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
| 
						 | 
					@ -36,8 +36,18 @@ self.addEventListener('activate', event => {
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const NETWORK_ONLY = [
 | 
				
			||||||
 | 
					  '/oauth'
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const CACHE_FIRST = [
 | 
				
			||||||
 | 
					  '/api/v1/accounts/verify_credentials',
 | 
				
			||||||
 | 
					  '/system/accounts/avatars'
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
self.addEventListener('fetch', event => {
 | 
					self.addEventListener('fetch', event => {
 | 
				
			||||||
  const url = new URL(event.request.url)
 | 
					  const req = event.request
 | 
				
			||||||
 | 
					  const url = new URL(req.url)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // don't try to handle e.g. data: URIs
 | 
					  // don't try to handle e.g. data: URIs
 | 
				
			||||||
  if (!url.protocol.startsWith('http')) {
 | 
					  if (!url.protocol.startsWith('http')) {
 | 
				
			||||||
| 
						 | 
					@ -46,7 +56,7 @@ self.addEventListener('fetch', event => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // always serve assets and webpack-generated files from cache
 | 
					  // always serve assets and webpack-generated files from cache
 | 
				
			||||||
  if (cached.has(url.pathname)) {
 | 
					  if (cached.has(url.pathname)) {
 | 
				
			||||||
    event.respondWith(caches.match(event.request))
 | 
					    event.respondWith(caches.match(req))
 | 
				
			||||||
    return
 | 
					    return
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,30 +65,59 @@ self.addEventListener('fetch', event => {
 | 
				
			||||||
  // app, but if it's right for yours then uncomment this section
 | 
					  // app, but if it's right for yours then uncomment this section
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) {
 | 
					  if (url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) {
 | 
				
			||||||
    event.respondWith(caches.match('/index.html'));
 | 
					    event.respondWith(caches.match('/index.html'))
 | 
				
			||||||
    return;
 | 
					    return
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Non-GET and for certain endpoints (e.g. OAuth), go network-only
 | 
				
			||||||
 | 
					  if (req.method !== 'GET' ||
 | 
				
			||||||
 | 
					      NETWORK_ONLY.some(pattern => url.pathname.startsWith(pattern))) {
 | 
				
			||||||
 | 
					    console.log('Using network-only for', url.href)
 | 
				
			||||||
 | 
					    event.respondWith(fetch(req))
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // For these, go cache-first.
 | 
				
			||||||
 | 
					  if (CACHE_FIRST.some(pattern => url.pathname.startsWith(pattern))) {
 | 
				
			||||||
 | 
					    console.log('Using cache-first for', url.href)
 | 
				
			||||||
 | 
					    event.respondWith(caches
 | 
				
			||||||
 | 
					      .open(`offline${timestamp}`)
 | 
				
			||||||
 | 
					      .then(async cache => {
 | 
				
			||||||
 | 
					        let response = await cache.match(req)
 | 
				
			||||||
 | 
					        if (response) {
 | 
				
			||||||
 | 
					          // update asynchronously
 | 
				
			||||||
 | 
					          fetch(req).then(response => {
 | 
				
			||||||
 | 
					            cache.put(req, response.clone())
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					          return response
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        response = await fetch(req)
 | 
				
			||||||
 | 
					        cache.put(req, response.clone())
 | 
				
			||||||
 | 
					        return response
 | 
				
			||||||
 | 
					      }))
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // for everything else, try the network first, falling back to
 | 
					  // for everything else, try the network first, falling back to
 | 
				
			||||||
  // cache if the user is offline. (If the pages never change, you
 | 
					  // cache if the user is offline. (If the pages never change, you
 | 
				
			||||||
  // might prefer a cache-first approach to a network-first one.)
 | 
					  // might prefer a cache-first approach to a network-first one.)
 | 
				
			||||||
  event.respondWith(
 | 
					  event.respondWith(caches
 | 
				
			||||||
    caches
 | 
					    .open(`offline${timestamp}`)
 | 
				
			||||||
      .open(`offline${timestamp}`)
 | 
					    .then(async cache => {
 | 
				
			||||||
      .then(async cache => {
 | 
					      try {
 | 
				
			||||||
        try {
 | 
					        console.log('Using network-first for', url.href)
 | 
				
			||||||
          const response = await fetch(event.request)
 | 
					        const response = await fetch(req)
 | 
				
			||||||
          cache.put(event.request, response.clone())
 | 
					        cache.put(req, response.clone())
 | 
				
			||||||
 | 
					        return response
 | 
				
			||||||
 | 
					      } catch (err) {
 | 
				
			||||||
 | 
					        const response = await cache.match(req)
 | 
				
			||||||
 | 
					        if (response) {
 | 
				
			||||||
          return response
 | 
					          return response
 | 
				
			||||||
        } catch (err) {
 | 
					 | 
				
			||||||
          const response = await cache.match(event.request)
 | 
					 | 
				
			||||||
          if (response) {
 | 
					 | 
				
			||||||
            return response
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          throw err
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      })
 | 
					
 | 
				
			||||||
 | 
					        throw err
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue