worker-commands
v1.1.0
Published
A library wrapping up commonly-used service worker commands, primarily for use with notifications
Downloads
3
Readme
worker-commands
A library of useful Service Worker commands, wrapped up in an interface that can be called from a page, or in response to a push or notification event.
Why would I want to use it?
Service workers can be shut down at any time, at which point they lose any variables and listeners attached to it. So, while you might think you can do this:
function notifyUser() {
self.registration.showNotification({ body : "test" })
self.addEventListener("notificationclick", () => {
// act on the notification click
})
}
Hours might pass between the time you show the notification and the time the user clicks on it - at which point, the worker will be re-initialised with no listener attached. However, notifications have a data
property allowing you to store information along with a notification, and retrieve it later. worker-commands
uses this to attach declarative events when showing a notification. It isn't as flexible as a custom function, but it does allow you to, for example, update the worker in response to a push event without having to set up a specific listener.
Setup
To start using the library, just run the setup()
function in the script that starts your worker:
import { setup } from 'worker-commands';
setup();
Command structure
At the centre of worker-commands
is the RunCommand
interface, which is simply an object with two properties, command
and options
:
const commandToRun = {
command: "notification.show",
options: {
title: "Alert!",
body: "This is an alert"
}
}
Firing a command in the worker
To fire a command, you just use the fireCommand
method inside your worker:
import { fireCommand } from 'worker-commands';
await fireCommand(commandToRun);
You can also provide an array of RunCommand
s to fireCommand
(and all of the other options listed below) and it will execute all of them, unless one encounters an error. It returns a promise.
Firing from a client web page
Although things like the Cache API are available on clients the worker-commands
library only works when set up inside a service worker. But you can call a command from a page, by running this:
import { sendClient } from 'worker-commands';
await sendClient({
command: "notification.show",
options: {
title: "Alert from client"
}
})
If your build process doesn't involve tree-shaking you'll end up with the entire worker-commands
library in your client JS. If you'd like to avoid that extra processing, just call the specially constructed send-command.js
file:
const workerClient = require('workercommands/send-command');
await workerClient.sendClient({
command: "notification.show",
options: {
title: "Alert from client"
}
})
Commands via push events
By default worker-commands
hooks into a worker's push
event to execute commands sent via push message. To use it, send a JSON payload with a __workerCommandPayload
, like so:
{
__workerCommandPayload: {
command: "notification.show",
options: {
title: "Push alert received!"
}
}
}
Commands as events
Because RunCommand
is a serialisable object, we can store in the data
attribute of a notification. This allows us to run commands in response to events, by adding additional options like so:
fireCommand({
command: "notification.show",
options: {
title: "Alert!",
body: "This is an alert",
actions: [
{
action: "openlink",
title: "Open Link"
}
],
events: {
onclick: {
command: "notification.close"
},
onopenlink: [
{
command: "notification.close"
},
{
command: "client.open",
options: {
url: "http://www.example.org"
}
}
]
}
}
});
These handlers can survive the worker being destroyed and recreated, because they are stored with the notification.
Available commands
There aren't too many yet, but:
- Notifications
notification.show
: the options parameter accepts all values used in the Notification constructor as well as atitle
attribute, and anevents
object with commands to be triggeredonclick
,onclose
andon[id of action]
.notification.close
: if this is called in response to a notification event (i.e.notificationclick
ornotificationclose
) it will remove the active notification. Options has one parameter -tag
. If provided, it'll close all notifications with this tag instead of the active notification.
- Cache
cache.add
: options has two parameters -cacheName
to control which cache to add to,urls
, which is an array of URLs to cache.cache.delete
: same as above, except it removes items from the cache.
- Client
client.open
: opens a new browser window with the URL specified inoptions.url
. Ifoptions.focusIfExisting
istrue
and a window already exists with this URL, it will focus instead of opening a new window.client.focus
: the reverse of the above. Focuses an active window. If there isn't one with this URL andoptions.openIfNotExisting
istrue
, it'll open a new one.client.post-message
: runspostMessage()
on all clients matching the URL provided inoptions.url
. Sendsoptions.message
to the clients.
- Registration
registration.update
: tries to update the current worker by runningself.registration.update()
. Any subsequent commands on this command chain will still run in the old worker, though.registration.unregister
: remove this worker registration from the browser.
Tests
There's a small library for testing the parts of the library we can easily test. Just run
npm run test
and point your browser to http://localhost:4567
to load them.