mirror of
				https://github.com/mickael-kerjean/filestash.git
				synced 2025-10-31 18:16:00 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			123 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| const CACHE_NAME = "v0.3";
 | |
| 
 | |
| /*
 | |
|  * Control everything going through the wire, applying different
 | |
|  * strategy for caching, fetching resources
 | |
|  */
 | |
| self.addEventListener("fetch", function(event){
 | |
|     if(is_a_ressource(event.request)){
 | |
|         return event.respondWith(cacheFirstStrategy(event));
 | |
|     }else if(is_an_api_call(event.request)){
 | |
|         return event;
 | |
|     }else if(is_an_index(event.request)){
 | |
|         return event.respondWith(cacheFirstStrategy(event));
 | |
|     }else{
 | |
|         return event;
 | |
|     }
 | |
| });
 | |
| 
 | |
| /*
 | |
|  * When a new service worker is coming in, we need to do a bit of
 | |
|  * cleanup to get rid of the rotten cache
 | |
|  */
 | |
| self.addEventListener("activate", function(event){
 | |
|     vacuum(event);
 | |
| });
 | |
| 
 | |
| self.addEventListener("error", function(err){
 | |
|     console.error(err);
 | |
| });
 | |
| 
 | |
| /*
 | |
|  * When a newly installed service worker is coming in, we want to use it
 | |
|  * straight away (make it active). By default it would be in a "waiting state"
 | |
|  */
 | |
| self.addEventListener("install", function(){
 | |
|     caches.open(CACHE_NAME).then(function(cache) {
 | |
|         return cache.addAll([
 | |
|             "/",
 | |
|             "/api/config"
 | |
|         ]);
 | |
|     });
 | |
| 
 | |
|     if (self.skipWaiting) { self.skipWaiting(); }
 | |
| });
 | |
| 
 | |
| 
 | |
| 
 | |
| function is_a_ressource(request){
 | |
|     const p = _pathname(request);
 | |
|     if(["assets", "manifest.json", "favicon.ico"].indexOf(p[0]) !== -1){
 | |
|         return true;
 | |
|     } else if(p[0] === "api" && (p[1] === "config")){
 | |
|         return true;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| function is_an_api_call(request){
 | |
|     return _pathname(request)[0] === "api" ? true : false;
 | |
| }
 | |
| function is_an_index(request){
 | |
|     return ["files", "view", "login", "logout", ""].indexOf(_pathname(request)[0]) >= 0? true : false;
 | |
| }
 | |
| 
 | |
| 
 | |
| ////////////////////////////////////////
 | |
| // HELPERS
 | |
| ////////////////////////////////////////
 | |
| 
 | |
| function vacuum(event){
 | |
|     return event.waitUntil(
 | |
|         caches.keys().then(function(cachesName){
 | |
|             return Promise.all(cachesName.map(function(cacheName){
 | |
|                 if(cacheName !== CACHE_NAME){
 | |
|                     return caches.delete(cacheName);
 | |
|                 }
 | |
|             }));
 | |
|         })
 | |
|     );
 | |
| }
 | |
| 
 | |
| function _pathname(request){
 | |
|     //eslint-disable-next-line no-useless-escape
 | |
|     return request.url.replace(/^http[s]?:\/\/[^\/]*\//, "").split("/");
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * strategy is cache first:
 | |
|  * 1. use whatever is in the cache
 | |
|  * 2. perform the network call to update the cache
 | |
|  */
 | |
| function cacheFirstStrategy(event){
 | |
|     return caches.open(CACHE_NAME).then(function(cache){
 | |
|         return cache.match(event.request).then(function(response){
 | |
|             if(!response){
 | |
|                 return fetchAndCache(event);
 | |
|             }
 | |
| 
 | |
|             fetchAndCache(event).catch(nil);
 | |
|             return response;
 | |
|         });
 | |
|     });
 | |
| 
 | |
|     function fetchAndCache(event){
 | |
|         // A request is a stream and can only be consumed once. Since we are consuming this
 | |
|         // once by cache and once by the browser for fetch, we need to clone the response as
 | |
|         // seen on https://developers.google.com/web/fundamentals/getting-started/primers/service-workers
 | |
|         return fetch(event.request)
 | |
|             .then(function(response){
 | |
|                 if(!response || response.status !== 200){ return response; }
 | |
| 
 | |
|                 // A response is a stream and can only because we want the browser to consume the
 | |
|                 // response as well as the cache consuming the response, we need to clone it
 | |
|                 const responseClone = response.clone();
 | |
|                 caches.open(CACHE_NAME).then(function(cache){
 | |
|                     cache.put(event.request, responseClone);
 | |
|                 });
 | |
|                 return response;
 | |
|             });
 | |
|     }
 | |
|     function nil(){}
 | |
| }
 | 
