hyperdrive

A file sharing network based on rabin file chunking and append only feeds of data verified by merkle trees.

hyperdrive

A file sharing network based on rabin file chunking and append only feeds of data verified by merkle trees.

npm install hyperdrive

For a more detailed technical information on how it works see SPECIFICATION.md. If you are interested in only using the feed part of the spec see hypercore which implements that.

First create a new feed to share

var hyperdrive = require('hyperdrive')
var level = require('level')
 
var db = level('./hyperdrive.db')
var drive = hyperdrive(db)
 
var pack = drive.add('./some-folder')
 
pack.appendFile('my-file.txt', function (err) {
  if (err) throw err
  pack.finalize(function () {
    var link = pack.id.toString('hex')
    console.log(link, '<-- this is your hyperdrive link')
  })
})

Then to share it

var disc = require('discovery-channel')()
var hyperdrive = require('hyperdrive')
var net = require('net')
var level = require('level')
var db = levelup('./another-hyperdrive.db')
var drive = hyperdrive(db)
 
var link = new Buffer({your-hyperdrive-link-from-the-above-example}, 'hex')
 
var server = net.createServer(function (socket) {
  socket.pipe(drive.createPeerStream()).pipe(socket)
})
 
server.listen(0, function () {
  disc.add(link, server.address().port)
  disc.on('peer', function (hashpeer) {
    var socket = net.connect(peer.port, peer.host)
    socket.pipe(drive.createPeerStream()).pipe(socket)
  })
})

If you run this code on multiple computers you should be able to access the content in the feed by doing

var archive = drive.get(link, './folder-to-store-data-in') // the link identifies/verifies the content 
 
archive.entry(0, function (errentry) { // get the first entry 
  console.log(entry) // prints {name: 'my-file.txt', ...} 
  var stream = archive.createFileStream(0)
  stream.on('data', function (data) {
    console.log(data) // <-- file data 
  })
  stream.on('end', function () {
    console.log('no more data')
  })
})

Create a new hyperdrive instance. db should be a levelup instance. You can add a folder to store the file data in as the second argument.

Create a new peer replication duplex stream. This stream should be piped together with another peer stream somewhere else to start replicating the feeds

Add a new archive to share. basefolder will be the root of this archive.

Retrive a finalized archive.

archive.on('file-download', entry, data)

Emitted when a data block if downloaded for a file.

archive.on('file-downloaded', entry)

Emitted when a file is fully downloaded.

Append a file to a non-finalized archive. If you don't specify name the entry will be called filename.

Finalize an archive. After an archive is finalized it will be sharable and will have a .id property.

Wait for the archive to be ready. Afterwards archive.entries will contain the total amount of entries available.

Read the entry metadata stored at index. An metadata entry looks like this

{
  type: 'file-or-directory',
  name: 'filename',
  mode: fileMode,
  size: fileSize,
  uid: optionalUid,
  gid: optionalGid,
  mtime: optionalMtimeInSeconds,
  ctime: optionalCtimeInSeconds
}

Downloads the file specified by index and calls the callback when done. You have to call this or create a file stream to download a file.

Create a stream to a file.

Stream out all metadata entries

MIT