Facebook
From Hot Sloth, 3 Years ago, written in JavaScript.
Embed
Download Paste or View Raw
Hits: 70
  1. const STATIC = "static";
  2. const RESOURCES = "resources";
  3.  
  4. self.addEventListener("install", event => event.waitUntil(
  5.     Promise.all([
  6.         self.skipWaiting(),
  7.         caches.delete(STATIC),
  8.         caches.delete(RESOURCES),
  9.     ]).then(() => Promise.all([
  10.         caches.open(STATIC).then(cache => cache.addAll([
  11.             "/main.js",
  12.             "/index.html",
  13.         ])),
  14.     ]))));
  15.  
  16. self.addEventListener("activate", event => event.waitUntil(clients.claim()));
  17.  
  18. self.addEventListener("sync", event =>
  19.     event.waitUntil(
  20.         Promise.all([
  21.             clients.claim(),
  22.             caches.delete(RESOURCES),
  23.         ])
  24.     )
  25. )
  26.  
  27. const base64Fixer = c => c.charCodeAt(0);
  28.  
  29. const utf8base64ToUint8Array = payload => {
  30.     const brokenPayload = atob(payload);
  31.     return Uint8Array.from(brokenPayload, base64Fixer);
  32. };
  33.  
  34. const responseFromBuffer = (
  35.     buffer,
  36.     contentType,
  37.     etag
  38. ) => {
  39.     const headers = new Headers({
  40.         "Content-Length": buffer.length.toString(),
  41.         "Content-Type": contentType,
  42.     });
  43.     if (etag) {
  44.         headers.append("ETag", etag);
  45.     }
  46.     return new Response(buffer, { status: 200, headers });
  47. };
  48.  
  49. const createResponseFromAttachment = (
  50.     {
  51.         data,
  52.         contentType = "application/javascript",
  53.     },
  54.     etag
  55. ) => responseFromBuffer(utf8base64ToUint8Array(data), contentType, etag);
  56.  
  57. const handleEntryRequest = async event => {
  58.     try {
  59.         const base = event.request.url.substring(event.request.url.indexOf("/entries/"));
  60.         const nextSeparator = base.indexOf("/", 9);
  61.         const nextDot = base.indexOf(".", 9);
  62.         let endIndex;
  63.         if (nextSeparator !== -1 && nextDot !== -1) {
  64.             endIndex = Math.min(nextSeparator, nextDot);
  65.         } else if (nextSeparator !== -1) {
  66.             endIndex = nextSeparator
  67.         } else if (nextDot !== -1) {
  68.             endIndex = nextDot;
  69.         }
  70.         const response = await fetch(`${base.substring(0, endIndex).replace("/entries/", "/resources/")}.json`);
  71.         const data = await response.json();
  72.         const cache = await caches.open(RESOURCES);
  73.  
  74.         /*for (const requestUrl in data) {
  75.             console.log(requestUrl)
  76.             const contentType = requestUrl.endsWith(".css") ? "text/css" : "application/javascript";
  77.             await cache.put(requestUrl, createResponseFromAttachment({
  78.                 data: data[requestUrl],
  79.                 contentType,
  80.             }, response.headers.get("ETag")));
  81.         }*/
  82.         console.log('matching', base);
  83.         return cache.match(base).then(async resp => {
  84.             console.log('opening', base);
  85.             if (!resp && data[base]) {
  86.                 let requestUrl = base;
  87.                 const contentType = requestUrl.endsWith(".css") ? "text/css" : "application/javascript";
  88.                 resp = createResponseFromAttachment({
  89.                     data: data[requestUrl],
  90.                     contentType,
  91.                 }, response.headers.get("ETag"));
  92.                 cache.put(requestUrl, resp.clone())
  93.                 //await cache.put(requestUrl, resp);
  94.                // resp = await cache.match(base);
  95.  
  96.             }
  97.             console.log('opened', base);
  98.             return resp || new Response(undefined, { status: 404 })
  99.         });
  100.  
  101.        // return cache.then(cache => cache.match(base)).then(resp => resp || new Response(undefined, { status: 404 }));
  102.  
  103.     } catch (e) {
  104.         console.log(e)
  105.     }
  106. };
  107.  
  108. self.addEventListener("fetch", event => {
  109.     if (event.request.url.includes("/entries/")) {
  110.         event.respondWith(handleEntryRequest(event));
  111.     } else if (event.request.url.endsWith("/main.js") || event.request.url.endsWith("/index.html")) {
  112.         return event.respondWith(
  113.             caches.open(STATIC)
  114.                 .then(cache => cache.match(event.request))
  115.                 .then(match => match || fetch(event.request))
  116.         );
  117.     } else {
  118.         console.log('error', event.request.url)
  119.     }
  120. });