Run an IPFS node inside a service worker and serve all your IPFS Urls directly from IPFS!
JavaScript
Switch branches/tags
Nothing to show
Clone or download
Latest commit b20b06a Jun 4, 2018

README.md

Use js-ipfs within a service worker

standard-readme compliant Build Status Coverage Status Dependency Status js-standard-style

Run an IPFS node inside a service worker and serve all your IPFS Urls directly from IPFS!

BEWARE BEWARE there may be dragons! 🐉

This module is still experimental because it is indeed an experiment part of the https://github.com/ipfs/in-web-browsers endeavour.

Usage

This project is a how to, that you can use as a basis for building an application with js-ipfs (>=0.24.0) running in a service worker.

Note, the following code snippets are edited from the actual source code for brevity.

Service worker code

The service worker code lives in src/index.js. This is the code that will run as a service worker. It boots up an IPFS node, responds to requests and exposes the running node for use by web pages within the scope of the service worker.

The IPFS node is created when the service worker 'activate' event is fired:

const IPFS = require('ipfs')

self.addEventListener('activate', () => {
  ipfs = new IPFS({ /* ...config... */ })
})

The service worker listens for 'fetch' events so that it can respond to requests:

self.addEventListener('fetch', (event) => {
  const hash = event.request.url.split('/ipfs/')[1]
  event.respondWith(catAndRespond(hash))
})

async function catAndRespond (hash) {
  const data = await ipfs.files.cat(hash)
  return new Response(data, { status: 200, statusText: 'OK', headers: {} })
}

Finally, the IPFS node is exposed for use by web pages/apps. Service workers are permitted to talk to web pages via a messaging API so we can use ipfs-postmsg-proxy to talk to the IPFS node running in the worker. We create a "proxy server" for this purpose:

const { createProxyServer } = require('ipfs-postmsg-proxy')
// Setup a proxy server that talks to our real IPFS node
createProxyServer(() => ipfs, { /* ...config... */ })

Application code

The application code lives in examples/use-from-another-page/public+sw. It registers the service worker and talks to the IPFS node that runs in it.

First we feature detect that the client's browser supports service workers, and then we register the service worker.

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('service-worker-bundle.js')
    .then((reg) => console.log('Successful service worker register'))
    .catch((err) => console.error('Failed service worker register', err))
}

Once the service worker is registered, we can start talking to the IPFS node that it is running. To do this we create a "proxy client" which can talk to our "proxy server" over the messaging API:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('service-worker-bundle.js')
    .then(async () => {
      ipfs = createProxyClient({ /* ...config... */ })

      // Now use `ipfs` as usual! e.g.
      const { agentVersion, id } = await ipfs.id()
    })
}