Progressively
Approaching
Service Workers

Code 2016

Service Workers are hard

Sorry, not sorry 👍


navigator.serviceWorker.register("sw.js");
        

Getting hold of the SW
Registration


navigator
  .serviceWorker
  .register("sw.js")
  .then(reg => console.log(reg));
        
        

Behold the
SW registration

  • Life cycle events
  • Push Registration
  • Sync Manager
  • And more in the future...

Amazing! But sounds like work...

"One weird trick"

  • Most APIs are available Window object.
  • Easy to experiment and get up and going.

Service Workers Building Blocks

  • Fetch API
  • Cache API
  • Notifications
  • Push API
  • And so on...

Fetch API (Basic)


fetch("https://example.com/some/text/")
  .then(response => handleResponse(response))
  .catch(err);
        

Fetch API (Fancy Request)


const request = new Request(url, opts);

fetch(request)
  .then(response => handleResponse(response))
  .catch(err);
        

Request objects

  • url
  • method (GET, POST, HEAD, etc.)
  • mode (CORS)
  • redirect ("follow", "error", "manual")
  • referrer
  • referrerPolicy (e.g., "origin")
  • headers (custom headers)

Request objects


var req = new Request("/test/", {
  referrer: "http://localhost:8080/foo/bar",
  referrerPolicy: "origin", //"unsafe-url"
});
fetch(req).then(lookAtAnotherExample);
        

Request objects


// Let's post some JSON
var req = new Request("./process", {
  method: "POST",
  body: JSON.stringify({greeting: "Hi"})
});
// Go, fetch!
fetch(req).then(letsLookAtResponse);
        

Response objects

  • url
  • type (basic, error, opaque, etc.)
  • redirected
  • status
  • ok
  • statusText
  • headers
  • bodyUsed

var body = "

Not found

"; var res = new Response(body, { status: 404, statusText: "Not Found", });

Body mixin
(Request and Response)

  • arrayBuffer()
  • blob()
  • formData()
  • json()
  • text()

Body mixin


var req = new Request("./process", {
  method: "POST",
  body: JSON.stringify({greeting: "Hi"})
});

// consumes the body
req.json()
  .then(json => console.log(json))
  .then(()=> console.log(req.bodyUsed))

Body mixin


var req = new Request("./process", {
  method: "POST",
  body: JSON.stringify({greeting: "Hi"})
});

// clone's body not consumed
req.clone().json()
  .then(json => console.log(json))
  .then(() => console.log(req.bodyUsed))

HTTP Headers objects

  • set(name, value);
  • delete(name);
  • get(name);
  • has(name);
  • Iterators: keys(), values()

HTTP Headers objects


req.headers.set("whatevs", "awesome");
res.headers.get("whatevs");
if(res.headers.has("whatevs")){
  doWhatevs()
}
        

Hardest problems in
computer science?

  • Does not respect HTTP cache directives.
  • Cache invalidation.
  • Naming things.
  • Volatile (e.g., overcome by addressable IDB).

CacheStorage API

window.caches

  • .open(name)
  • .delete(name)
  • .has(name)
  • .keys()
  • .match(request,{options})

CacheStorage API

window.caches


const urls = ["./", "images/dom.jpg"];
caches.open("v1")
  .then(cache => cache.addAll(urls));

caches.match("images/dom", {
  cacheName: "v1",
}).then(response => doSomething);
        

Viewing caches in browsers

Cache API

  • add()
  • addAll()
  • delete()
  • keys()
  • match()
  • matchAll()
  • put()

caches.open(cacheName)
  .then(cache => cache.put(request, response.clone())
  .then(doStuff);
  

Notifications ()


Notification.requestPermission()
  .then(perm => {
    if(perm !== "granted") {
      return;
    }
    const noti = new Notification("OMG HI");
    noti.onclick = () => console.log("click!");
  });
        

Push

Is a lot of work to set up...

Push - emulation

  • Firefox: about:debugging#workers
  • Chrome dev tools

Learn to ❤️ specs

wicg.io

Ok, ❤️ MDN

JS Workshops Meetup

Go, make stuff!