Home

Awesome

msgr

Nifty service worker/client message utility

Made with ❤ at @outlandish

<a href="http://badge.fury.io/js/msgr"><img alt="npm version" src="https://badge.fury.io/js/msgr.svg"></a> js-standard-style

Makes communication between a client and service worker super easy...

To see it being used in the wild, check out the source code of fetch-sync.

Table of Contents

Import

Client

// ES6
import msgr from 'msgr'

// CommonJS
var msgr = require('msgr')

// RequireJS
define(['msgr'], function (msgr) {/*...*/})
<!-- Script, available as `window.msgr` -->
<script src="/node_modules/msgr/index.js"></script>

Worker

If you are bundling your SW then you can use the Import methods above.

Otherwise...

// importScripts
importScripts('/node_modules/msgr/index.js')

Initialise & Example

Client: msgr.client()

Pass in reference to the worker and a collection of message handlers:

const recipient = navigator.serviceWorker.controller

const channel = msgr.client(recipient, {
  // Predefined message handlers
  SAY_HELLO: (data) => console.log('Hello, ' + data) //=> 'Hello, World!'
})

// Send something "unknown" to the worker.
// Notice it does not have a tag.
channel.send({
  username: 'Flanders',
  location: 'Springfield'
})

// Send a "known" message to the worker
channel.send('CACHE_ASSET', '/cat.gif').then(function (message) {
  console.log(message) //=> 'Caching complete!'
})

Worker: msgr.worker()

On the worker you just pass in your message handlers:

const channel = msgr.worker({
  CACHE_ASSET: (url, respond) => {
    cache(url).then(function () {
      respond('Caching complete!')
    })
  }
})

channel.receive(function (data) {
  // Do something with an "unknown" message
  // that does not have a predefined handler.
  console.log(data) //=> { username: 'Flanders', ... }
})

// Send something "known" to the client using a tag.
channel.send('SAY_HELLO', 'World!')

Sending Messages

Receiving Messages

The API for receiving messages is the same for both the worker and client.

msgr API

msgr.client(serviceWorker, handlers) : Channel

Initialise a msgr client.

Returns a Channel. See the Channel API Docs for more details.

Example:

msgr.client(navigator.serviceWorker.controller, {
  NOTIFY: function (respond) {
    new Notification('You have a notification!')
    respond('GOT_THE_NOTIFICATION')
  }
})

msgr.worker(handlers) : Channel

Initialise a msgr worker.

Returns a Channel. See the Channel API Docs for more details.

Example:

msgr.worker({
  NOTIFY: function (respond) {
    new Notification('You have a notification!')
    respond('GOT_THE_NOTIFICATION')
  }
})

Channel API

channel.ready(handler)

Register a handler to be called when the channel is opened between client and worker.

Although you can register ready handlers, you can send messages before the channel is open using channel.send() and these will be queued and sent as soon as the channel is ready.

Example:

channel.ready(function () {
  application.start()
})

channel.send([type,] data) : Promise

Send a message through the channel to the worker/client.

Returns a Message. See the Message API Docs for more details.

If called before the channel is ready the message will be queued and sent as soon as the channel is open.

Example:

// Typed message, will invoke registered type handlers
channel.send('NOTIFY_USER')

// Typed message with data, will invoke registered type handlers
channel.send('NOTIFY_USER', { message: 'Update complete' })

// Anonymous, will invoke `receive` handlers
channel.send('This is the untagged data')

channel.receive(handler)

Handle an "unknown" message that is not tagged.

The handler receives two arguments: the data of the message and a respond function.

Example:

channel.receive(function (data, respond) {
  console.log('Got some unknown data: ' + data)
})

Message API

message.then(handler)

Register a handler to receive the response to a message.

Example:

// In client message handlers
msgr({
  NOTIFY_USER: function (data, respond) {
    new Notification('Job ' + data.id + ' was completed')
    respond('From worker: job deleted') // ACK
  }
})

// In worker
channel.send('NOTIFY_USER', { id: 1337 }).then((data) => {
  console.log(data) //=> 'From worker: job deleted'
})

respond([data])

Send a response to a received message.

This function is passed as the second argument to both "known" and "unknown" message handlers.

Contributing

All pull requests and issues welcome!

If you're not sure how, check out Kent C. Dodds' great video tutorials on egghead.io!

Author & License

msgr was created by Sam Gluck and is released under the MIT license.