2017-12-21 05:52:58 +00:00
// Forked from https://github.com/ipfs/ipfs-service-worker which does not work with recent versions
// of js-ipfs.
/* global self, Response */
'use strict'
const IPFS = require ( 'ipfs' )
let node
// https://redfin.engineering/how-to-fix-the-refresh-button-when-using-service-workers-a8e27af6df68
self . skipWaiting ( )
self . addEventListener ( 'install' , ( event ) => {
console . log ( 'install step' )
event . waitUntil ( self . skipWaiting ( ) )
} )
self . addEventListener ( 'activate' , ( event ) => {
console . log ( 'activate step' )
event . waitUntil ( self . clients . claim ( ) )
} )
function initialize _ipfs ( ) {
return new Promise ( ( resolve , reject ) => {
node = new IPFS ( )
node . on ( 'ready' , ( ) => {
console . log ( 'js-ipfs node is ready' )
resolve ( )
} )
node . on ( 'error' , ( err ) => {
console . log ( 'js-ipfs node errored' , err )
reject ( err )
} )
} )
}
let ipfs _initialized
2017-12-22 06:16:53 +00:00
function response ( status _code , status _text , body , headers = { } ) {
// Return a promise for a response with the given HTTP status code, status text, and HTML body.
return new Promise ( ( resolve , reject ) => {
resolve (
new Response (
body ,
{
status : status _code ,
statusText : status _text ,
headers : headers
}
)
)
} )
}
2017-12-21 05:52:58 +00:00
self . addEventListener ( 'fetch' , ( event ) => {
if ( ! event . request . url . startsWith ( self . location . origin + '/ipfs' ) ) {
return console . log ( 'Fetch not in scope:' , event . request . url )
}
console . log ( 'Handling fetch event:' , event . request . url )
if ( ! ipfs _initialized ) {
ipfs _initialized = initialize _ipfs ( )
}
event . respondWith (
2017-12-22 06:16:53 +00:00
ipfs _initialized . then ( ( ) => {
2017-12-21 05:52:58 +00:00
const url = new URL ( event . request . url )
const multihash = url . pathname
2017-12-22 06:52:52 +00:00
return node . files . get ( multihash )
} ) . then ( ( files ) => {
// If there's just one result, return it.
if ( files . length == 1 && files [ 0 ] . content ) {
return response ( 200 , 'OK' , files [ 0 ] . content )
}
// If there are multiple results (and so this appears to be a directory), but this URL
// doesn't have a trailing slash, redirect. This ensures relative paths work correctly
// for any resources pulled in on the page.
if ( files . length > 1 && event . request . url . slice ( - 1 ) != '/' ) {
return response ( 302 , 'Found' , '' , { 'Location' : event . request . url + '/' } )
}
// If there are multiple results, look for an index.html page to return.
for ( let file of files ) {
if ( file . path . endsWith ( '/index.html' ) ) {
return response ( 200 , 'OK' , file . content )
}
}
2017-12-22 06:16:53 +00:00
return response (
404 , 'Not Found' ,
Buffer . from ( '<html><head><title>404 Not Found</title></head><body bgcolor="white"><center><h1>404 Not Found</h1></center><hr><center>Intergalactic</center></body></html>' ) ,
{ 'Content-Type' : 'text/html; charset=utf-8' }
)
2017-12-22 06:52:52 +00:00
} ) . catch ( ( error ) => {
console . log ( error )
2017-12-21 05:52:58 +00:00
} )
)
} )