Skip to content
Demo: run an IPFS node inside a Service Worker and serve all your IPFS URLs directly from IPFS!
JavaScript
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples/use-from-another-page
src
.gitignore
LICENSE Initial commit May 12, 2017
README.md fix: restore demo to functional state with js-ipfs 0.33.1 Nov 19, 2018
package-lock.json chore(package): fix gh security alert Dec 25, 2018
package.json fix: restore demo to functional state with js-ipfs 0.33.1 Nov 19, 2018

README.md

Demo: use js-ipfs within a Service Worker

standard-readme compliant

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 ipfs/in-web-browsers endeavour.

Follow latest developments in in-web-browsers/issues/55.

Usage

This project is a how to, that you can use as a basis for building an application with js-ipfs (>=0.33.1) 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()
    })
}
You can’t perform that action at this time.