ssb-conn-hub
Advanced tools
Comparing version 0.0.4 to 0.0.5
@@ -5,3 +5,4 @@ import { ConnectionData as Data, Address } from './types'; | ||
private readonly _peers; | ||
private readonly _notify; | ||
private readonly _notifyEvent; | ||
private readonly _notifyEntries; | ||
private _closed; | ||
@@ -11,2 +12,5 @@ private readonly _connectRetries; | ||
private _init; | ||
private _assertNotClosed; | ||
private _assertValidAddress; | ||
private _updateLiveEntries; | ||
private _setPeer; | ||
@@ -23,2 +27,3 @@ private _getPeerByKey; | ||
}>]>; | ||
liveEntries(): any; | ||
getState(address: Address): Data['state'] | undefined; | ||
@@ -25,0 +30,0 @@ listen(): any; |
@@ -75,2 +75,4 @@ "use strict"; | ||
var run = require("promisify-tuple"); | ||
var pull = require('pull-stream'); | ||
var cat = require('pull-cat'); | ||
var Notify = require('pull-notify'); | ||
@@ -127,3 +129,3 @@ var msAddress = require('multiserver-address'); | ||
debug('connected to %s', address); | ||
_this._notify({ | ||
_this._notifyEvent({ | ||
type: state, | ||
@@ -134,6 +136,8 @@ address: address, | ||
}); | ||
_this._updateLiveEntries(); | ||
rpc.on('closed', function () { | ||
_this._peers.delete(address); | ||
debug('disconnected from %s', address); | ||
_this._notify({ type: 'disconnected', address: address, key: key }); | ||
_this._notifyEvent({ type: 'disconnected', address: address, key: key }); | ||
_this._updateLiveEntries(); | ||
}); | ||
@@ -145,3 +149,4 @@ }; | ||
this._peers = new Map(); | ||
this._notify = Notify(); | ||
this._notifyEvent = Notify(); | ||
this._notifyEntries = Notify(); | ||
this._init(); | ||
@@ -152,2 +157,15 @@ } | ||
}; | ||
ConnHub.prototype._assertNotClosed = function () { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
}; | ||
ConnHub.prototype._assertValidAddress = function (address) { | ||
if (!msAddress.check(address)) { | ||
throw new Error('The given address is not a valid multiserver-address'); | ||
} | ||
}; | ||
ConnHub.prototype._updateLiveEntries = function () { | ||
this._notifyEntries(Array.from(this._peers.entries())); | ||
}; | ||
ConnHub.prototype._setPeer = function (address, data) { | ||
@@ -194,8 +212,4 @@ var previousData = this._peers.get(address); | ||
case 0: | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
if (!msAddress.check(address)) { | ||
throw new Error('The given address is not a valid multiserver-address'); | ||
} | ||
this._assertNotClosed(); | ||
this._assertValidAddress(address); | ||
if (this._peers.has(address)) { | ||
@@ -218,3 +232,4 @@ peer_1 = this._peers.get(address); | ||
debug('connecting to %s', address); | ||
this._notify({ type: state, address: address, key: key }); | ||
this._notifyEvent({ type: state, address: address, key: key }); | ||
this._updateLiveEntries(); | ||
return [4, run(this._server.connect)(address)]; | ||
@@ -226,3 +241,3 @@ case 1: | ||
debug('failed to connect to %s', address); | ||
this._notify({ | ||
this._notifyEvent({ | ||
type: 'connecting-failed', | ||
@@ -233,2 +248,3 @@ address: address, | ||
}); | ||
this._updateLiveEntries(); | ||
throw err; | ||
@@ -241,3 +257,9 @@ } | ||
debug('connected to %s', address); | ||
this._notify({ type: state_1, address: address, key: key, details: { rpc: rpc } }); | ||
this._notifyEvent({ | ||
type: state_1, | ||
address: address, | ||
key: key, | ||
details: { rpc: rpc }, | ||
}); | ||
this._updateLiveEntries(); | ||
} | ||
@@ -255,8 +277,4 @@ return [2, rpc]; | ||
case 0: | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
if (!msAddress.check(address)) { | ||
throw new Error('The given address is not a valid multiserver-address'); | ||
} | ||
this._assertNotClosed(); | ||
this._assertValidAddress(address); | ||
if (!this._peers.has(address)) | ||
@@ -270,3 +288,4 @@ return [2, false]; | ||
debug('disconnecting from %s', address); | ||
this._notify({ type: state, address: address, key: key }); | ||
this._notifyEvent({ type: state, address: address, key: key }); | ||
this._updateLiveEntries(); | ||
} | ||
@@ -279,3 +298,3 @@ if (!peer.disconnect) return [3, 2]; | ||
debug('failed to disconnect from %s', address); | ||
this._notify({ | ||
this._notifyEvent({ | ||
type: 'disconnecting-failed', | ||
@@ -292,3 +311,4 @@ address: address, | ||
debug('disconnected from %s', address); | ||
this._notify({ type: 'disconnected', address: address, key: key }); | ||
this._notifyEvent({ type: 'disconnected', address: address, key: key }); | ||
this._updateLiveEntries(); | ||
if (this._connectRetries.has(address)) { | ||
@@ -305,5 +325,3 @@ this._connectRetries.delete(address); | ||
var e_2, _a; | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
this._assertNotClosed(); | ||
for (var id in this._server.peers) { | ||
@@ -328,14 +346,15 @@ if (id !== this._server.id) { | ||
ConnHub.prototype.entries = function () { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
this._assertNotClosed(); | ||
return this._peers.entries(); | ||
}; | ||
ConnHub.prototype.liveEntries = function () { | ||
this._assertNotClosed(); | ||
return cat([ | ||
pull.values([Array.from(this._peers.entries())]), | ||
this._notifyEntries.listen(), | ||
]); | ||
}; | ||
ConnHub.prototype.getState = function (address) { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
if (!msAddress.check(address)) { | ||
throw new Error('The given address is not a valid multiserver-address'); | ||
} | ||
this._assertNotClosed(); | ||
this._assertValidAddress(address); | ||
if (!this._peers.has(address)) | ||
@@ -346,6 +365,4 @@ return undefined; | ||
ConnHub.prototype.listen = function () { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
return this._notify.listen(); | ||
this._assertNotClosed(); | ||
return this._notifyEvent.listen(); | ||
}; | ||
@@ -356,3 +373,4 @@ ConnHub.prototype.close = function () { | ||
this._peers.clear(); | ||
this._notify.end(); | ||
this._notifyEvent.end(); | ||
this._notifyEntries.end(); | ||
debug('closed the ConnHub instance'); | ||
@@ -359,0 +377,0 @@ }; |
{ | ||
"name": "ssb-conn-hub", | ||
"description": "Module that manages active connections to SSB peers", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"homepage": "https://github.com/staltz/ssb-conn-hub", | ||
@@ -16,2 +16,4 @@ "main": "lib/index.js", | ||
"debug": "^4.1.1", | ||
"pull-cat": "~1.1.11", | ||
"pull-stream": "~3.6.9", | ||
"pull-notify": "~0.1.1", | ||
@@ -18,0 +20,0 @@ "ssb-ref": "~2.13.9" |
@@ -11,30 +11,6 @@ # ssb-conn-hub | ||
This module is only used to create an SSB CONN plugin, not used directly by applications. | ||
This module is only used to create an SSB CONN plugin, not used directly by applications. A ConnHub instance should be available on the CONN plugin, with the following API: | ||
```js | ||
const ConnHub = require('ssb-conn-hub') | ||
const connPlugin = { | ||
name: 'conn', | ||
version: '1.0.0', | ||
manifest: { | ||
add: 'sync' | ||
}, | ||
init: function(server) { | ||
const connHub = new ConnHub(server); | ||
return { | ||
connect: function(address, data) { | ||
// NOTICE THIS | ||
connHub.connect(address).then(connected => { | ||
// ... | ||
}); | ||
}, | ||
}; | ||
} | ||
}; | ||
``` | ||
## API | ||
* `new ConnHub(server)`: constructor for a connHub instance, accepting an `ssb-server` instance as argument | ||
* `connHub.connect(address)`: connect to a peer known by its `address` (string, must conform to the [multiserver address convention](https://github.com/dominictarr/multiserver-address)). Returns a Promise, with the three possible outcomes: | ||
@@ -50,2 +26,3 @@ - Resolves with an RPC object that represents the successfully connected peer | ||
* `connHub.entries()`: returns a new `Iterator` object that gives `[address, data]` pairs, where data has the state and key of the peer | ||
* `connHub.liveEntries()`: returns a pull-stream that emits an array of entries (like `connHub.entries()`, but an array instead of an `Iterator`) everytime there are updates to connections. | ||
* `connDB.listen()`: returns a pull stream that notifies of connection events, as an object `{type, address, key, details}` where: | ||
@@ -52,0 +29,0 @@ - `type` is either `'connecting'`, `'connecting-failed'`, `'connected'`, `'disconnecting'`, `'disconnecting-failed'`, `'disconnected'` |
115
src/index.ts
import {ConnectionData as Data, ListenEvent, Address} from './types'; | ||
import run = require('promisify-tuple'); | ||
import {EventEmitter} from 'events'; | ||
const pull = require('pull-stream'); | ||
const cat = require('pull-cat'); | ||
const Notify = require('pull-notify'); | ||
@@ -32,3 +34,4 @@ const msAddress = require('multiserver-address'); | ||
private readonly _peers: Map<Address, Data>; | ||
private readonly _notify: any; | ||
private readonly _notifyEvent: any; | ||
private readonly _notifyEntries: any; | ||
private _closed: boolean; | ||
@@ -46,6 +49,9 @@ | ||
this._peers = new Map<Address, Data>(); | ||
this._notify = Notify(); | ||
this._notifyEvent = Notify(); | ||
this._notifyEntries = Notify(); | ||
this._init(); | ||
} | ||
//#region PRIVATE | ||
private _init() { | ||
@@ -58,2 +64,18 @@ (this._server as EventEmitter).addListener( | ||
private _assertNotClosed() { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
} | ||
private _assertValidAddress(address: Address) { | ||
if (!msAddress.check(address)) { | ||
throw new Error('The given address is not a valid multiserver-address'); | ||
} | ||
} | ||
private _updateLiveEntries() { | ||
this._notifyEntries(Array.from(this._peers.entries())); | ||
} | ||
private _setPeer(address: Address, data: Partial<Data>) { | ||
@@ -112,3 +134,3 @@ const previousData = this._peers.get(address); | ||
debug('connected to %s', address); | ||
this._notify({ | ||
this._notifyEvent({ | ||
type: state, | ||
@@ -119,2 +141,3 @@ address, | ||
} as ListenEvent); | ||
this._updateLiveEntries(); | ||
@@ -124,17 +147,14 @@ rpc.on('closed', () => { | ||
debug('disconnected from %s', address); | ||
this._notify({type: 'disconnected', address, key} as ListenEvent); | ||
this._notifyEvent({type: 'disconnected', address, key} as ListenEvent); | ||
this._updateLiveEntries(); | ||
}); | ||
}; | ||
/////////////// | ||
//// PUBLIC API | ||
/////////////// | ||
//#endregion | ||
//#region PUBLIC API | ||
public async connect(address: Address): Promise<false | object> { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
if (!msAddress.check(address)) { | ||
throw new Error('The given address is not a valid multiserver-address'); | ||
} | ||
this._assertNotClosed(); | ||
this._assertValidAddress(address); | ||
@@ -158,3 +178,4 @@ if (this._peers.has(address)) { | ||
debug('connecting to %s', address); | ||
this._notify({type: state, address, key} as ListenEvent); | ||
this._notifyEvent({type: state, address, key} as ListenEvent); | ||
this._updateLiveEntries(); | ||
@@ -165,3 +186,3 @@ const [err, rpc] = await run<any>(this._server.connect)(address); | ||
debug('failed to connect to %s', address); | ||
this._notify({ | ||
this._notifyEvent({ | ||
type: 'connecting-failed', | ||
@@ -172,2 +193,3 @@ address, | ||
} as ListenEvent); | ||
this._updateLiveEntries(); | ||
throw err; | ||
@@ -181,3 +203,9 @@ } | ||
debug('connected to %s', address); | ||
this._notify({type: state, address, key, details: {rpc}} as ListenEvent); | ||
this._notifyEvent({ | ||
type: state, | ||
address, | ||
key, | ||
details: {rpc}, | ||
} as ListenEvent); | ||
this._updateLiveEntries(); | ||
} | ||
@@ -188,8 +216,4 @@ return rpc; | ||
public async disconnect(address: Address): Promise<boolean> { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
if (!msAddress.check(address)) { | ||
throw new Error('The given address is not a valid multiserver-address'); | ||
} | ||
this._assertNotClosed(); | ||
this._assertValidAddress(address); | ||
@@ -205,3 +229,4 @@ if (!this._peers.has(address)) return false; | ||
debug('disconnecting from %s', address); | ||
this._notify({type: state, address, key} as ListenEvent); | ||
this._notifyEvent({type: state, address, key} as ListenEvent); | ||
this._updateLiveEntries(); | ||
} | ||
@@ -213,3 +238,3 @@ | ||
debug('failed to disconnect from %s', address); | ||
this._notify({ | ||
this._notifyEvent({ | ||
type: 'disconnecting-failed', | ||
@@ -226,3 +251,4 @@ address, | ||
debug('disconnected from %s', address); | ||
this._notify({type: 'disconnected', address, key} as ListenEvent); | ||
this._notifyEvent({type: 'disconnected', address, key} as ListenEvent); | ||
this._updateLiveEntries(); | ||
@@ -240,5 +266,4 @@ // Re-connect because while disconnect() was running, | ||
public reset() { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
this._assertNotClosed(); | ||
for (var id in this._server.peers) { | ||
@@ -254,15 +279,19 @@ if (id !== this._server.id) { | ||
public entries() { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
this._assertNotClosed(); | ||
return this._peers.entries(); | ||
} | ||
public liveEntries() { | ||
this._assertNotClosed(); | ||
return cat([ | ||
pull.values([Array.from(this._peers.entries())]), | ||
this._notifyEntries.listen(), | ||
]); | ||
} | ||
public getState(address: Address): Data['state'] | undefined { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
if (!msAddress.check(address)) { | ||
throw new Error('The given address is not a valid multiserver-address'); | ||
} | ||
this._assertNotClosed(); | ||
this._assertValidAddress(address); | ||
@@ -276,6 +305,5 @@ if (!this._peers.has(address)) return undefined; | ||
public listen() { | ||
if (this._closed) { | ||
throw new Error('This ConnHub instance is closed, create a new one.'); | ||
} | ||
return this._notify.listen(); | ||
this._assertNotClosed(); | ||
return this._notifyEvent.listen(); | ||
} | ||
@@ -290,7 +318,10 @@ | ||
this._peers.clear(); | ||
this._notify.end(); | ||
this._notifyEvent.end(); | ||
this._notifyEntries.end(); | ||
debug('closed the ConnHub instance'); | ||
} | ||
//#endregion | ||
} | ||
export = ConnHub; |
@@ -65,2 +65,38 @@ const tape = require('tape'); | ||
tape('liveEntries() emits all entries as they update', t => { | ||
const connHub = new ConnHub(ssbServer); | ||
let i = 0; | ||
pull( | ||
connHub.liveEntries(), | ||
pull.drain(entries => { | ||
++i; | ||
if (i === 1) { | ||
t.pass('FIRST EMISSION'); | ||
t.equals(entries.length, 0, 'entries === []'); | ||
} else if (i === 2) { | ||
t.pass('SECOND EMISSION'); | ||
t.equals(entries.length, 1, 'there is one entry'); | ||
const entry = entries[0]; | ||
t.equals(entry[0], TEST_ADDR, 'left is the address'); | ||
t.equals(typeof entry[1], 'object', 'right is the data'); | ||
t.equals(entry[1].state, 'connecting', 'state is connecting'); | ||
} else if (i === 3) { | ||
t.pass('THIRD EMISSION'); | ||
t.equals(entries.length, 0, 'entries === []'); | ||
t.end(); | ||
} else { | ||
t.fail('listen() should not emit further events'); | ||
} | ||
}), | ||
); | ||
connHub.connect(TEST_ADDR).then( | ||
() => { | ||
t.fail('The connection should not succeed'); | ||
}, | ||
_err => {}, | ||
); | ||
}); | ||
tape('disconnect() resolves with false when there was no connection', t => { | ||
@@ -67,0 +103,0 @@ const connHub = new ConnHub(ssbServer); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
112482
879
7
37
+ Addedpull-cat@~1.1.11
+ Addedpull-stream@~3.6.9
+ Addedpull-cat@1.1.11(transitive)
+ Addedpull-stream@3.6.14(transitive)