hypercore
Advanced tools
Comparing version 1.1.0 to 1.2.0
@@ -65,2 +65,6 @@ var subleveldown = require('subleveldown') | ||
Hypercore.prototype.use = function (extension) { | ||
this.swarm.use(extension) | ||
} | ||
Hypercore.prototype._close = function (link) { | ||
@@ -67,0 +71,0 @@ var id = link.toString('hex') |
@@ -44,2 +44,3 @@ var flat = require('flat-tree') | ||
this._sync = low(sync) | ||
this._extensions = core._extensions | ||
@@ -46,0 +47,0 @@ this.setMaxListeners(0) |
@@ -12,2 +12,3 @@ var lpstream = require('length-prefixed-stream') | ||
var MAX_MESSAGE = 5 * 1024 * 1024 | ||
var EXTENSION_OFFSET = 64 | ||
@@ -186,5 +187,13 @@ var ENCODINGS = [ | ||
this._extensions = opts.extensions | ||
this._remoteExtensions = new Array(this._extensions.length) | ||
this._localExtensions = new Array(this._extensions.length) | ||
for (var i = 0; i < this._extensions.length; i++) { | ||
this._remoteExtensions[i] = this._localExtensions[i] = -1 | ||
} | ||
var handshake = { | ||
protocol: 'hypercore', | ||
id: this.id | ||
id: this.id, | ||
extensions: opts.extensions | ||
} | ||
@@ -204,2 +213,21 @@ | ||
Protocol.prototype.remoteSupports = function (id) { | ||
var i = typeof id === 'number' ? id : this._extensions.indexOf(id) | ||
return this._localExtensions[i] > -1 | ||
} | ||
Protocol.prototype.send = function (id, buf) { | ||
var i = typeof id === 'number' ? id : this._extensions.indexOf(id) | ||
if (!this.remoteSupports(i)) return false | ||
if (typeof buf === 'string') buf = new Buffer(buf) | ||
var msg = new Buffer(buf.length + 1) | ||
msg[0] = i + EXTENSION_OFFSET | ||
buf.copy(msg, 1) | ||
this._generator.write(msg) | ||
return true | ||
} | ||
Protocol.prototype._onhandshake = function (handshake) { | ||
@@ -209,2 +237,20 @@ if (handshake.protocol !== 'hyperdrive' && handshake.protocol !== 'hypercore') { | ||
} | ||
// extensions *must* be sorted | ||
var local = 0 | ||
var remote = 0 | ||
while (local < this._extensions.length && remote < handshake.extensions.length) { | ||
if (this._extensions[local] === handshake.extensions[remote]) { | ||
this._localExtensions[local] = remote | ||
this._remoteExtensions[remote] = local | ||
local++ | ||
remote++ | ||
} else if (this._extensions[local] < handshake.extensions[remote]) { | ||
local++ | ||
} else { | ||
remote++ | ||
} | ||
} | ||
this.remoteId = handshake.id | ||
@@ -229,2 +275,3 @@ this.emit('handshake') | ||
var type = data[0] | ||
if (type >= EXTENSION_OFFSET) return this._onextension(type, data) | ||
if (type >= ENCODINGS.length) return // unknown message | ||
@@ -249,2 +296,7 @@ | ||
Protocol.prototype._onextension = function (type, message) { | ||
var ext = this._remoteExtensions[type - EXTENSION_OFFSET] | ||
if (ext > -1) this.emit(this._extensions[ext], message.slice(1)) | ||
} | ||
Protocol.prototype._onjoin = function (message) { | ||
@@ -251,0 +303,0 @@ if (message.channel > this._remote.length) { |
@@ -17,4 +17,11 @@ var protocol = require('./protocol') | ||
this.kicking = false | ||
this.extensions = [] | ||
this._streaming = false | ||
} | ||
Swarm.prototype.use = function (name) { | ||
if (this._streaming) throw new Error('Add all extensions before creating peer streams') | ||
this.extensions.push(name) | ||
} | ||
Swarm.prototype._kick = function () { | ||
@@ -142,4 +149,9 @@ if (this.kicking) return | ||
Swarm.prototype.createStream = function () { | ||
if (!this._streaming) { | ||
this._streaming = true | ||
this.extensions.sort() | ||
} | ||
var self = this | ||
var peer = protocol() | ||
var peer = protocol({extensions: self.extensions}) | ||
@@ -146,0 +158,0 @@ debug('new peer stream') |
{ | ||
"name": "hypercore", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "Hypercore is a protocol and network for distributing and replicating static feeds of binary data.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -120,6 +120,2 @@ # hypercore | ||
#### `var stream = core.createPeerStream()` | ||
Create a new peer replication duplex stream. This stream should be piped together with a remote peer's stream to the start replicating feeds. | ||
#### `core.on('interested', id)` | ||
@@ -133,2 +129,7 @@ | ||
#### `var stream = core.createPeerStream()` | ||
Create a new peer replication duplex stream. This stream should be piped together with a remote peer's stream to the start replicating feeds. | ||
When the stream receives a handshake from the remote peer a `handshake` event is emitted. | ||
## Feeds | ||
@@ -171,4 +172,44 @@ | ||
## Extension API | ||
Hypercore supports sending and receiving custom messages using an extension api. | ||
You can use this to implement various additions to the protocol. | ||
#### `core.use(extension)` | ||
Use an extension to the protocol. `extension` should be a string containing the name of your extension. | ||
#### `var bool = stream.remoteSupports(extension)` | ||
Check if the remote stream supports an extension. Should be called after handshake has been emitted | ||
#### `stream.send(extension, buffer)` | ||
Send an extension message | ||
#### `stream.on(extension, onmessage)` | ||
Set a handler for an extension message. `onmessage` should be a function and is called with `(messageAsBuffer)` when a message for the extension is received. | ||
An example extension would be a simple ping / pong messaging scheme | ||
``` js | ||
core.use('ping') // we call the extension ping | ||
var stream = core.createPeerStream() | ||
// connect the stream to someone else | ||
stream.on('handshake', function () { | ||
if (!stream.remoteSupports('ping')) return | ||
stream.on('ping', function (message) { | ||
if (message[0] === 0) return stream.send('ping', new Buffer([1])) // send pong | ||
if (message[1] === 1) console.log('got pong!') | ||
}) | ||
stream.send('ping', new Buffer([0])) // send ping | ||
}) | ||
``` | ||
## License | ||
MIT |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
50048
18
1294
213