Skip to content

Instantly share code, notes, and snippets.

@benjaminhoffman
Created December 22, 2017 23:34
Show Gist options
  • Save benjaminhoffman/f28374553919f4d10517949e68ceb32c to your computer and use it in GitHub Desktop.
Save benjaminhoffman/f28374553919f4d10517949e68ceb32c to your computer and use it in GitHub Desktop.

Revisions

  1. benjaminhoffman created this gist Dec 22, 2017.
    166 changes: 166 additions & 0 deletions sw.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,166 @@
    // from https://classroom.udacity.com/courses/ud899/lessons/6381510082/concepts/63774101620923

    // registers a service worker; returns a promise
    navigator.serviceWorker('sw.js')
    .then(reg => {
    // methods:
    reg.unregister()
    reg.update()

    // properties: waiting, installing, active
    // points to a sw object or null
    // gives an insight into sw lifecycle

    if (reg.waiting) {
    // update ready and waiting
    }

    if (reg.installing) {
    // update in progress
    // but that update may fail so we have to listen for a state change
    // this fires when sw.state has changed
    reg.installing.addEventListener('statechange', () => {
    if (this.state === 'installed') {
    // there's an update ready!
    }
    })
    }

    if (reg.active) {
    //
    }

    // fires when an update has been found
    reg.addEventListener('updatefound', () => {
    // reg.installing has changed
    reg.installing.addEventListener('statechange', () => {
    if (this.state === 'installed') {
    // there's an update ready!
    }
    })
    })

    var sw = reg.installing
    sw.state
    // 'installing', sw install event has fired but not yet completed
    // 'installed', sw installation has completed successfully but hasn't yet activated
    // 'activating', sw activate event has fired but not yet complete
    // 'activated', sw is ready to receive fetch events
    // 'redundant', sw has been thrown away; happens when the sw been superceded or failed to install
    })

    // refers to the sw that controls this page
    navigator.serviceWorker.controller

    // do something when a new sw takes control
    // for ex: reload page w new content in cache
    navigator.serviceWorker.addEventListener('controllerchange', () => {})

    // runs at install time, when the browser sets up a new server worker for the first time
    // use to add resources to the cache
    self.addEventListener("install", function(event) {
    var urlsToCache = [
    "/",
    "js/main.js",
    "css/main.css",
    "imgs/icon.png",
    "https://fonts.gstatic.com/s/roboto/v15/2UX7WLTfW3W8TclTUvlFyQ.woff",
    "https://fonts.gstatic.com/s/roboto/v15/d-6IYplOFocCacKzxwXSOD8E0i7KZn-EPnyo3HZu7kw.woff"
    ];

    // event.waitUntil takes a promise
    // classroom.udacity.com/courses/ud899/lessons/6381510081/concepts/63885494500923
    event.waitUntil(
    // open a cache named 'wittr-static-v1'
    // caches.open returns a promise
    caches
    .open("wittr-static-v1")
    .then(cache => {
    // add cache the urls from urlsToCache
    cache.addAll(urlsToCache);
    })
    .catch(() => {
    console.log("NOOOOOOOOO");
    })
    );
    });


    // fires when this server worker becomes active; when its ready to control pages when the previous server worker is gone
    // perfect for getting rid of old caches
    self.addEventListener("install", function(event) {})


    // respond to a fetch/request
    self.addEventListener("fetch", (event) => {
    event.respondWith(
    fetch(event.request)
    .then(response => {
    // if 404, return a gif
    if (response.status === 404) {
    return fetch("/imgs/dr-evil.gif");
    }

    // if 400, return some html
    if (response.status === 400) {
    return new Response('<div>hello!</div>', {
    headers: { "Content-type": "text/html" }
    })
    }

    // respond with an entry from the cache if there is one.
    // If there isn't, fetch from the network.
    // https://classroom.udacity.com/courses/ud899/lessons/6381510081/concepts/63885494530923
    event.respondWith(
    caches.match(event.request)
    .then(res => {
    // reply with asset from the cache, if exists
    if (res) return res;
    // else, hit fetch the asset from the server
    return fetch(event.request);
    })
    );

    // else, return a fetch to the network w/ the original request
    return new Response(event.request);
    })
    .catch(() => {
    return new Response("Uh oh, that totally failed!");
    })
    );
    });


    Cache API
    window.cache

    caches.open('my-stuff')
    .then((cache) => {
    // returns a cache of my-stuff
    // or if one hasn't been created yet, it creates one
    })


    // add cache items
    cache.put(request/url, response)

    // takes an array of URLs, fetches them, and puts them in the response cache
    // atomic: if any fail to cache, none are added
    // uses fetch under the hood
    cache.addAll(['/foo', '/bar'])

    // pulls something out of the cache if a response is found; otherwise null
    // returns a promise
    cache.match(request/url)

    // tries to find a match in any of the caches, starting from the oldest
    caches.match(request/url)

    // deletes a cache
    // returns a promise
    caches.delete(cacheName)

    // gets the names of your caches
    // returns a promise
    caches.keys()