sw-toolbox – A Collection of Tools for Service Workers

Service Worker Toolbox provides some simple helpers for use in creating your own service workers. Specifically, it provides common caching strategies for dynamic content, such as API calls, third-party resources, and large or infrequently used local resources that you don’t want precached.

The code itself is very readable I must say:

importScripts('sw-toolbox.js');

toolbox.precache([
  '/css/app.css',
  '/img/logo.png'
]);

toolbox.router.get('/css*', toolbox.cacheFirst);
toolbox.router.get('/img*', toolbox.cacheFirst);
toolbox.router.get('/(.*)', toolbox.networkFirst, { networkTimeoutSeconds: 5});

A bit more advanced is to precache a “you’re offline” page first, and return that in case a user is offline (src):

importScripts('sw-toolbox.js');

toolbox.precache([
  '/offline',
  '/img/offline.png',
   // …
]);

// …

toolbox.router.get('/(.*)', function(request, values, options) {
  // networkFirst will attempt to return a response from the network,
  // then attempt to return a response from the cache.
  return toolbox.networkFirst(request, values, options).catch(function(error) {
    // If both the network and the cache fail, then `.catch()` will be triggered,
    // and we get a chance to respond with our cached fallback page.
    if (request.method === 'GET' && request.headers.get('accept').includes('text/html')) {
      return toolbox.cacheOnly(new Request('/offline'), values, options);
    }
    throw error;
  });
});

sw-toolbox
sw-toolbox (GitHub) →

A beginner’s guide to making Progressive Web Apps forms a nice introduction to implementing Service Workers using sw-toolbox.

If you’re looking for a non-library version I’d recommend starting with Implementing “Save For Offline” with Service Workers.

Elsewhere , , Leave a comment

CSS is simple, but not easy

Good observation by Jeremy Keith, after having attended (the magnificent) CSS Day:

Unlike a programming language that requires knowledge of loops, variables, and other concepts, CSS is pretty easy to pick up. Maybe it’s because of this that it has gained the reputation of being simple. It is simple in the sense of “not complex”, but that doesn’t mean it’s easy. Mistaking “simple” for “easy” will only lead to heartache.

Be sure to read the whole thing.

CSS →

Elsewhere , Leave a comment

Jamie xx Boiler Room Reykjavík DJ Set

Quite enjoyed this set during work today 🙂

Elsewhere , , Leave a comment

The Hidden Oil Patterns on Bowling Lanes

There’s more to the oil on a bowling lane than meets the eye. Knowing what it is, and knowing how it affects things makes you look at it – and play – differently. Seasoned players recognise it automatically, like a sort of instinct, whilst I just see a shiny surface.

Elsewhere , Leave a comment

justify-content: space-evenly; for Flexbox

A new alignment mode for Flex-containers is justify-content: space-evenly;

The alignment subjects are distributed so that the spacing between any two adjacent alignment subjects, before the first alignment subject, and after the last alignment subject is the same.

Currently supported in Firefox, and in Chrome Canary.

Box Alignment justify-content: space-evenly; for Flex-Containers →

Elsewhere , , 2 Comments

What’s new in JavaScript? ES2017/“ES8” Language Features

The ECMAScript 2017 Language Specification – the 8th edition of the spec – was officially released at the end of June by TC39.

💁‍♂️ ICYWW: Should we say ES2017 or ES8?

→ Say ES2017. Back in the day ES6 was (and still is) used a lot to refer to ES2015, but one should be referring to the standard using the year references (or refer to a language feature using its name)

One of the top additions – which I’ve been using for quite a while now thanks to babel-polyfill and its included core-js – is Object.entries()/Object.values(), as they have rather big effect on the way I write my code.

const obj = { x: 'xxx', y: 1 };
Object.values(obj); // ['xxx', 1]

const obj = { x: 'xxx’, y: 1 };
Object.entries(obj); // [[’x’, 'xxx’], [’y’, 1]]

As it’s an array, one can easily append a .forEach(…) to each one of these beauties to get going … And don’t forget about map/reduce/filter either 😉

Async functions is also at the top of my list of influential features:

function fetchTextByPromise() {
  return new Promise(resolve => { 
    setTimeout(() => { 
      resolve("es8");
    }, 2000);
  });
}
async function sayHello() { 
  const externalFetchedText = await fetchTextByPromise();
  console.log(`Hello, ${externalFetchedText}`); // Hello, es8
}
sayHello();

Furthermore some new string padding functions, Object.getOwnPropertyDescriptors(obj), “Trailing commas in function parameter lists and calls”, and “Shared memory and atomics” has been added.

ES8 was Released and here are its Main New Features →
ECMAScript 2017 Language Specification (PDF) →

Elsewhere , Leave a comment

PngPong Image Manipulation Library

For the recent UK Elections the folks The Guardian wanted to show big images along with their push notifications. Being bandwidth-aware they wanted a solution in which they could use a template image (which could then be cached) and then draw some stuff onto it. Only problem: Service Workers don’t have access to the Canvas API.

Enter PngPong, an basic image manipulation library, they’ve created:

PngPong is a very, very basic replacement for the Canvas API in environments that do not support it – primarily, service workers. Instead, it manually manipulates the bytes of a PNG file to copy the contents of another image, or draw basic shapes (currently only rectangles).

Their code to handle push notifications looked something like this:

self.addEventListener('push', (e) => {
    e.waitUntil(
        caches.match('/notification_template.png')
        .then((res) => res.arrayBuffer())
        .then((arrayBuffer) => {
            addResultsToTemplate(arrayBuffer, e.data);
            return blobToDataURL(new Blob([arrayBuffer]))
        })
        .then((imageURL) => {
            return self.registration.showNotification("Title", {
                image: imageURL
            })
        })
    )
})

Inside addResultsToTemplate they heavy lifting would be done by PngPong, drawing some small rectangles onto the template pictured below, yielding a push notification as pictured at the top of this post.


The template used

Example PngPong usage:

import {
  PngPong,
  PngPongShapeTransformer,
  PngPongImageCopyTransformer
} from 'png-pong';

// Create new PngPong instance
const pngPong = new PngPong(imageArrayBuffer);

// Draw a 30px red square 10px from the top and 10px from the left
const shape = new PngPongShapeTransformer(pngPong);
shape.drawRect(10, 10, 30, 30, [255, 0, 0])

// Copy a 50x50 image 10px from the top left of the source image,
// and draw it 30px into our target image. 
const toCopyFrom = new ArrayBuffer();
const imageCopy = new PngPongImageCopyTransformer(toCopyFrom, pngPong);
imageCopy.copy(10, 10, 50, 50, 30, 30);

// Run the transforms
pngPong.run();

PngPong (GitHub) →
PngPong Use Case: Generating Images in JavaScript Without Using the Canvas API →

Elsewhere , , , Leave a comment

Introducing npx: an NPM package runner

Included with npm@5.2.0 is an extra binary named npx:

npx is a tool intended to help round out the experience of using packages from the NPM registry — the same way npm makes it super easy to install and manage dependencies hosted on the registry, npx makes it easy to use CLI tools and other executables hosted on the registry.

Above that it’s smart too:

Calling npx <command> when <command> isn’t already in your $PATH will automatically install a package with that name from the NPM registry for you, and invoke it. When it’s done, the installed package won’t be anywhere in your globals, so you won’t have to worry about pollution in the long-term.

Introducing npx: an NPM package runner →

Elsewhere , , Leave a comment

😎 Emoji Compositions

In succession to Split emoji text effect with CSS (which has received an update by now BTW), PixelAmbacht has created a nice Emoji composition using the U+1F60E Smiling Face With Sunglasses emoji (😎) as the key modifier.

Note: For some mysterious reason the original demo yielded a blank page for me. Changing the font-size to anything lower than the originally set 8em fixed this issue. Therefore I’ve embedding a fork of the original demo.

Here’s how it works: The 😎 emoji is injected using generated content. It is positioned on top of the original emoji, and cut off (in height) so that only the sunglasses remain. In the end mix-blend-mode: darken; is added to make ‘m a bit transparent. Only works with the default Mac Emoji BTW.

Alternatively the 🕶 could’ve been used instead, of course 😉

Sidenote: Marcin Wichary has also been busy mocking up some emoji variations, and compositions using the ❤️ emoji:

Workshopped a bunch of emoji ligatures for more complex and underrepresented feelings.

The emoji ligature Rorschach test →

Elsewhere , , Leave a comment

WTF is The Blockchain?

Mohit Mamoria has written a 3500-word guide in plain English to understanding Blockchain.

Unlike every other post on the internet, instead of first defining the Blockchain, we’ll understand the problem it solves.

Best explanation I’ve read so far.

WTF is The Blockchain? →

Speaking of Blockchain, things could go very wrong for Bitcoin on August 1st due to a chain split:

Do not trust any payments you receive after Tue Aug 01 2017 00:00:00 GMT until the situation is resolved. No matter how many confirmations the new payment says it has, it can disappear from your wallet at any point up until the situation is resolved.

Bitcoin.org: Potential network disruption →

Elsewhere , , Leave a comment