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 (hash, peer) {
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 (err, entry) { // 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.
Emitted when a data block is downloaded for a file.
Emitted when a data block is uploaded for a file.
Emitted when a file is fully downloaded.
Either returns a write stream if entry is a file or returns null if it is directory. Calls callback when the entry has finished writing.
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