Last active
July 19, 2020 07:48
-
-
Save GautamPanickar/fa7f6dc5a5ce8bf45dc2327dbf2125bd to your computer and use it in GitHub Desktop.
Service worker with Google's Workbox for Angular App - handler file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const BG_IMAGES_CACHE = 'bg-images-cache'; | |
export class ServiceWorkerHandler { | |
private dbPromise: IDBOpenDBRequest; | |
constructor(dbPromise: IDBOpenDBRequest) { | |
this.dbPromise = dbPromise; | |
} | |
/** | |
* Handler for caching background images. | |
*/ | |
public bgImagesCacheHandler = async ({ request, url, event }) => { | |
const cacheURL = this.getCacheImageURL(url); | |
return caches.match(cacheURL).then(respFromCache => { | |
if (respFromCache) { | |
// If the image was available in cache return it from cache. | |
return respFromCache; | |
} | |
// Fetch the response from server and cache it. | |
return fetch(event.request).then(respFromServer => { | |
let respClone = respFromServer.clone(); | |
caches.open(BG_IMAGES_CACHE).then(bgCache => { | |
bgCache.put(cacheURL, respClone); | |
}); | |
return respFromServer; | |
}); | |
}); | |
} | |
/** | |
* Handler for fetching/putting bg images in IndexedDB. | |
*/ | |
public bgImagesDBHandler = async ({ request, url, event }) => { | |
const imageID = this.getImageIdFromURL(url); | |
return this.fetchImageFromDB(imageID).then((imageResult: Blob) => { | |
if (imageResult) { | |
// If image is directly available in DB then return the blob as the response. | |
return new Response(imageResult); | |
} else { | |
// If the image is unavailable, fetch the image by resuming the intercepted request to the server. | |
return fetch(event.request).then(response => { | |
const respClone = response.clone(); | |
return respClone.blob() | |
}).then(imageBlob => { | |
return this.putImageInDB(imageID, imageBlob).then((resolvedImage: Blob) => { | |
return new Response(resolvedImage); | |
}); | |
}); | |
} | |
}); | |
} | |
/** | |
* Fetches the image from DB. | |
*/ | |
private fetchImageFromDB(imageId: string) { | |
return new Promise((resolve, reject) => { | |
const tx = this.dbPromise.result.transaction('images', 'readonly'); | |
const store = tx.objectStore('images'); | |
const imageInStoreReq = store.get(imageId); | |
imageInStoreReq.onsuccess = (evt) => { | |
resolve(imageInStoreReq.result); | |
}; | |
imageInStoreReq.onerror = (evt) => { | |
reject('Something went wrong while fetching image from DB '); | |
}; | |
}); | |
} | |
/** | |
* Puts the image in DB. And returns the image. | |
*/ | |
private putImageInDB(imageId: string, blob: Blob) { | |
return new Promise((resolve, reject) => { | |
const tx = this.dbPromise.result.transaction('images', 'readwrite'); | |
const store = tx.objectStore('images'); | |
const imagePutReq = store.put(blob, imageId); | |
imagePutReq.onsuccess = (evt) => { | |
const imageInStoreReq = store.get(imageId); | |
imageInStoreReq.onsuccess = (evt) => { | |
resolve(imageInStoreReq.result); | |
}; | |
}; | |
imagePutReq.onerror = (evt) => { | |
reject('Something went wrong while putting image in DB '); | |
}; | |
}); | |
} | |
/** | |
* Returns the formatted URL which will be used as the key for caching images. | |
* Strips of any query params if present. | |
*/ | |
private getCacheImageURL(url: URL): string { | |
const urlString = url.toString(); | |
if (urlString.indexOf('?') >= 0) { | |
return urlString.substring(0, urlString.indexOf('?')); | |
} else { | |
return urlString; | |
} | |
} | |
/** | |
* Returns the image Id to be saved in the DB. | |
*/ | |
private getImageIdFromURL(url: URL): string { | |
const urlString = url.toString(); | |
const start = urlString.lastIndexOf('/') + 1; | |
const end = urlString.indexOf('?') >= 0 ? urlString.indexOf('?') : urlString.length; | |
const imageId = urlString.substring(start, end); | |
const imagePrefix = urlString.indexOf('bg_images') >= 0 | |
? ' BG-' : ' IMG-; | |
return imagePrefix + imageId; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment