Compare commits

..

1 Commits

Author SHA1 Message Date
e82385d4b9 feat: add types per jsdoc and types for testing interfaces 2020-12-01 12:03:13 +01:00
35 changed files with 924 additions and 799 deletions

View File

@ -18,7 +18,6 @@
- [Crypto](./src/crypto)
- [Peer Discovery](./src/peer-discovery)
- [Peer Routing](./src/peer-routing)
- [Pubsub](./src/pubsub)
- [Record](./src/record)
- [Stream Muxer](./src/stream-muxer)
- [Topology](./src/topology)
@ -31,7 +30,6 @@ For posterity, here are links to the original repositories for each of the inter
- [Content Routing](https://github.com/libp2p/interface-content-routing)
- [Peer Discovery](https://github.com/libp2p/interface-peer-discovery)
- [Peer Routing](https://github.com/libp2p/interface-peer-routing)
- [Pubsub](https://github.com/libp2p/js-libp2p-pubsub)
- [Stream Muxer](https://github.com/libp2p/interface-stream-muxer)
- [Transport](https://github.com/libp2p/interface-transport)

View File

@ -12,15 +12,15 @@
"scripts": {
"lint": "aegir lint",
"build": "aegir build",
"pregenerate:types": "rimraf './src/**/*.d.ts'",
"generate:types": "tsc --build",
"test": "aegir test",
"test:node": "aegir test --target node",
"test:browser": "aegir test --target browser",
"test:types": "aegir ts -p check",
"prepublishOnly": "npm run generate:types",
"release": "aegir release -t node -t browser",
"release-minor": "aegir release --type minor -t node -t browser",
"release-major": "aegir release --type major -t node -t browser"
"release-major": "aegir release --type major -t node -t browser",
"remove:types": "rimraf './src/**/*.d.ts'"
},
"repository": {
"type": "git",
@ -41,6 +41,7 @@
"abortable-iterator": "^3.0.0",
"chai": "^4.2.0",
"chai-checkmark": "^1.0.1",
"class-is": "^1.1.0",
"debug": "^4.1.1",
"delay": "^4.3.0",
"detect-node": "^2.0.4",
@ -66,10 +67,12 @@
"uint8arrays": "^1.1.0"
},
"devDependencies": {
"aegir": "^25.0.0",
"aegir": "^29.2.0",
"it-handshake": "^1.0.1",
"rimraf": "^3.0.2",
"typescript": "^4.0.5"
"rimraf": "^3.0.2"
},
"eslintConfig": {
"extends": "ipfs"
},
"contributors": [
"Alan Shaw <alan.shaw@protocol.ai>",

View File

@ -1,160 +0,0 @@
export = Connection;
/**
* An implementation of the js-libp2p connection.
* Any libp2p transport should use an upgrader to return this connection.
*/
declare class Connection {
/**
* Checks if the given value is a `Connection` instance.
*
* @param {any} other
* @returns {other is Connection}
*/
static isConnection(other: any): other is Connection;
/**
* Creates an instance of Connection.
* @param {object} properties properties of the connection.
* @param {multiaddr} [properties.localAddr] local multiaddr of the connection if known.
* @param {multiaddr} [properties.remoteAddr] remote multiaddr of the connection.
* @param {PeerId} properties.localPeer local peer-id.
* @param {PeerId} properties.remotePeer remote peer-id.
* @param {function} properties.newStream new stream muxer function.
* @param {function} properties.close close raw connection function.
* @param {function(): Stream[]} properties.getStreams get streams from muxer function.
* @param {object} properties.stat metadata of the connection.
* @param {string} properties.stat.direction connection establishment direction ("inbound" or "outbound").
* @param {object} properties.stat.timeline connection relevant events timestamp.
* @param {string} properties.stat.timeline.open connection opening timestamp.
* @param {string} properties.stat.timeline.upgraded connection upgraded timestamp.
* @param {string} [properties.stat.multiplexer] connection multiplexing identifier.
* @param {string} [properties.stat.encryption] connection encryption method identifier.
*/
constructor({ localAddr, remoteAddr, localPeer, remotePeer, newStream, close, getStreams, stat }: {
localAddr: multiaddr | undefined;
remoteAddr: multiaddr | undefined;
localPeer: PeerId;
remotePeer: PeerId;
newStream: Function;
close: Function;
getStreams: () => any[];
stat: {
direction: string;
timeline: {
open: string;
upgraded: string;
};
multiplexer: string | undefined;
encryption: string | undefined;
};
});
/**
* Connection identifier.
*/
id: string;
/**
* Observed multiaddr of the local peer
*/
localAddr: multiaddr | undefined;
/**
* Observed multiaddr of the remote peer
*/
remoteAddr: multiaddr | undefined;
/**
* Local peer id.
*/
localPeer: PeerId;
/**
* Remote peer id.
*/
remotePeer: PeerId;
/**
* Connection metadata.
*/
_stat: {
status: "open";
direction: string;
timeline: {
open: string;
upgraded: string;
};
multiplexer?: string | undefined;
encryption?: string | undefined;
};
/**
* Reference to the new stream function of the multiplexer
*/
_newStream: Function;
/**
* Reference to the close function of the raw connection
*/
_close: Function;
/**
* Reference to the getStreams function of the muxer
*/
_getStreams: () => any[];
/**
* Connection streams registry
*/
registry: Map<any, any>;
/**
* User provided tags
* @type {string[]}
*/
tags: string[];
get [Symbol.toStringTag](): string;
/**
* Get connection metadata
* @this {Connection}
*/
get stat(): {
status: "open";
direction: string;
timeline: {
open: string;
upgraded: string;
};
multiplexer?: string | undefined;
encryption?: string | undefined;
};
/**
* Get all the streams of the muxer.
* @this {Connection}
*/
get streams(): any[];
/**
* Create a new stream from this connection
* @param {string[]} protocols intended protocol for the stream
* @return {Promise<{stream: Stream, protocol: string}>} with muxed+multistream-selected stream and selected protocol
*/
newStream(protocols: string[]): Promise<{
stream: any;
protocol: string;
}>;
/**
* Add a stream when it is opened to the registry.
* @param {*} muxedStream a muxed stream
* @param {object} properties the stream properties to be registered
* @param {string} properties.protocol the protocol used by the stream
* @param {object} properties.metadata metadata of the stream
* @return {void}
*/
addStream(muxedStream: any, { protocol, metadata }: {
protocol: string;
metadata: object;
}): void;
/**
* Remove stream registry after it is closed.
* @param {string} id identifier of the stream
*/
removeStream(id: string): void;
/**
* Close the connection.
* @return {Promise<void>}
*/
close(): Promise<void>;
_closing: any;
get [connectionSymbol](): boolean;
}
import multiaddr = require("multiaddr");
import PeerId = require("peer-id");
declare const connectionSymbol: unique symbol;

View File

@ -1,250 +0,0 @@
'use strict'
/* eslint-disable valid-jsdoc */
const PeerId = require('peer-id')
const multiaddr = require('multiaddr')
const errCode = require('err-code')
const Status = require('./status')
const connectionSymbol = Symbol.for('@libp2p/interface-connection/connection')
function validateArgs (localAddr, localPeer, remotePeer, newStream, close, getStreams, stat) {
if (localAddr && !multiaddr.isMultiaddr(localAddr)) {
throw errCode(new Error('localAddr must be an instance of multiaddr'), 'ERR_INVALID_PARAMETERS')
}
if (!PeerId.isPeerId(localPeer)) {
throw errCode(new Error('localPeer must be an instance of peer-id'), 'ERR_INVALID_PARAMETERS')
}
if (!PeerId.isPeerId(remotePeer)) {
throw errCode(new Error('remotePeer must be an instance of peer-id'), 'ERR_INVALID_PARAMETERS')
}
if (typeof newStream !== 'function') {
throw errCode(new Error('new stream must be a function'), 'ERR_INVALID_PARAMETERS')
}
if (typeof close !== 'function') {
throw errCode(new Error('close must be a function'), 'ERR_INVALID_PARAMETERS')
}
if (typeof getStreams !== 'function') {
throw errCode(new Error('getStreams must be a function'), 'ERR_INVALID_PARAMETERS')
}
if (!stat) {
throw errCode(new Error('connection metadata object must be provided'), 'ERR_INVALID_PARAMETERS')
}
if (stat.direction !== 'inbound' && stat.direction !== 'outbound') {
throw errCode(new Error('direction must be "inbound" or "outbound"'), 'ERR_INVALID_PARAMETERS')
}
if (!stat.timeline) {
throw errCode(new Error('connection timeline object must be provided in the stat object'), 'ERR_INVALID_PARAMETERS')
}
if (!stat.timeline.open) {
throw errCode(new Error('connection open timestamp must be provided'), 'ERR_INVALID_PARAMETERS')
}
if (!stat.timeline.upgraded) {
throw errCode(new Error('connection upgraded timestamp must be provided'), 'ERR_INVALID_PARAMETERS')
}
}
/**
* An implementation of the js-libp2p connection.
* Any libp2p transport should use an upgrader to return this connection.
*/
class Connection {
/**
* Creates an instance of Connection.
* @param {object} properties properties of the connection.
* @param {multiaddr} [properties.localAddr] local multiaddr of the connection if known.
* @param {multiaddr} [properties.remoteAddr] remote multiaddr of the connection.
* @param {PeerId} properties.localPeer local peer-id.
* @param {PeerId} properties.remotePeer remote peer-id.
* @param {function} properties.newStream new stream muxer function.
* @param {function} properties.close close raw connection function.
* @param {function(): Stream[]} properties.getStreams get streams from muxer function.
* @param {object} properties.stat metadata of the connection.
* @param {string} properties.stat.direction connection establishment direction ("inbound" or "outbound").
* @param {object} properties.stat.timeline connection relevant events timestamp.
* @param {string} properties.stat.timeline.open connection opening timestamp.
* @param {string} properties.stat.timeline.upgraded connection upgraded timestamp.
* @param {string} [properties.stat.multiplexer] connection multiplexing identifier.
* @param {string} [properties.stat.encryption] connection encryption method identifier.
*/
constructor ({ localAddr, remoteAddr, localPeer, remotePeer, newStream, close, getStreams, stat }) {
validateArgs(localAddr, localPeer, remotePeer, newStream, close, getStreams, stat)
/**
* Connection identifier.
*/
this.id = (parseInt(Math.random() * 1e9)).toString(36) + Date.now()
/**
* Observed multiaddr of the local peer
*/
this.localAddr = localAddr
/**
* Observed multiaddr of the remote peer
*/
this.remoteAddr = remoteAddr
/**
* Local peer id.
*/
this.localPeer = localPeer
/**
* Remote peer id.
*/
this.remotePeer = remotePeer
/**
* Connection metadata.
*/
this._stat = {
...stat,
status: Status.OPEN
}
/**
* Reference to the new stream function of the multiplexer
*/
this._newStream = newStream
/**
* Reference to the close function of the raw connection
*/
this._close = close
/**
* Reference to the getStreams function of the muxer
*/
this._getStreams = getStreams
/**
* Connection streams registry
*/
this.registry = new Map()
/**
* User provided tags
* @type {string[]}
*/
this.tags = []
}
get [Symbol.toStringTag] () {
return 'Connection'
}
get [connectionSymbol] () {
return true
}
/**
* Checks if the given value is a `Connection` instance.
*
* @param {any} other
* @returns {other is Connection}
*/
static isConnection (other) {
return Boolean(other && other[connectionSymbol])
}
/**
* Get connection metadata
* @this {Connection}
*/
get stat () {
return this._stat
}
/**
* Get all the streams of the muxer.
* @this {Connection}
*/
get streams () {
return this._getStreams()
}
/**
* Create a new stream from this connection
* @param {string[]} protocols intended protocol for the stream
* @return {Promise<{stream: Stream, protocol: string}>} with muxed+multistream-selected stream and selected protocol
*/
async newStream (protocols) {
if (this.stat.status === Status.CLOSING) {
throw errCode(new Error('the connection is being closed'), 'ERR_CONNECTION_BEING_CLOSED')
}
if (this.stat.status === Status.CLOSED) {
throw errCode(new Error('the connection is closed'), 'ERR_CONNECTION_CLOSED')
}
if (!Array.isArray(protocols)) protocols = [protocols]
const { stream, protocol } = await this._newStream(protocols)
this.addStream(stream, { protocol })
return {
stream,
protocol
}
}
/**
* Add a stream when it is opened to the registry.
* @param {*} muxedStream a muxed stream
* @param {object} properties the stream properties to be registered
* @param {string} properties.protocol the protocol used by the stream
* @param {object} properties.metadata metadata of the stream
* @return {void}
*/
addStream (muxedStream, { protocol, metadata = {} }) {
// Add metadata for the stream
this.registry.set(muxedStream.id, {
protocol,
...metadata
})
}
/**
* Remove stream registry after it is closed.
* @param {string} id identifier of the stream
*/
removeStream (id) {
this.registry.delete(id)
}
/**
* Close the connection.
* @return {Promise<void>}
*/
async close () {
if (this.stat.status === Status.CLOSED) {
return
}
if (this._closing) {
return this._closing
}
this.stat.status = Status.CLOSING
// Close raw connection
this._closing = await this._close()
this._stat.timeline.close = Date.now()
this.stat.status = Status.CLOSED
}
}
module.exports = Connection

View File

@ -1 +1,230 @@
export var Connection: typeof import('./connection');
export = Connection;
/**
* @typedef {Object} ConectionStat
* @property {string} direction - connection establishment direction ("inbound" or "outbound").
* @property {object} timeline - connection relevant events timestamp.
* @property {string} timeline.open - connection opening timestamp.
* @property {string} timeline.upgraded - connection upgraded timestamp.
* @property {string} [multiplexer] - connection multiplexing identifier.
* @property {string} [encryption] - connection encryption method identifier.
*
* @typedef {Object} ConnectionOptions
* @property {multiaddr} [localAddr] - local multiaddr of the connection if known.
* @property {multiaddr} [remoteAddr] - remote multiaddr of the connection.
* @property {PeerId} localPeer - local peer-id.
* @property {PeerId} remotePeer - remote peer-id.
* @property {(protocols: string[]) => Promise<{stream: Stream, protocol: string}>} newStream - new stream muxer function.
* @property {() => Promise<void>} close - close raw connection function.
* @property {() => Stream[]} getStreams - get streams from muxer function.
* @property {ConectionStat} stat - metadata of the connection.
*/
declare class Connection {
/**
* An implementation of the js-libp2p connection.
* Any libp2p transport should use an upgrader to return this connection.
*
* @class
* @param {ConnectionOptions} options
*/
constructor({ localAddr, remoteAddr, localPeer, remotePeer, newStream, close, getStreams, stat }: ConnectionOptions);
/**
* Connection identifier.
*/
id: string;
/**
* Observed multiaddr of the local peer
*/
localAddr: import("multiaddr");
/**
* Observed multiaddr of the remote peer
*/
remoteAddr: import("multiaddr");
/**
* Local peer id.
*/
localPeer: import("peer-id");
/**
* Remote peer id.
*/
remotePeer: import("peer-id");
/**
* Connection metadata.
*/
_stat: {
status: string;
/**
* - connection establishment direction ("inbound" or "outbound").
*/
direction: string;
/**
* - connection relevant events timestamp.
*/
timeline: {
open: string;
upgraded: string;
};
/**
* - connection multiplexing identifier.
*/
multiplexer?: string;
/**
* - connection encryption method identifier.
*/
encryption?: string;
};
/**
* Reference to the new stream function of the multiplexer
*/
_newStream: (protocols: string[]) => Promise<{
stream: any;
protocol: string;
}>;
/**
* Reference to the close function of the raw connection
*/
_close: () => Promise<void>;
/**
* Reference to the getStreams function of the muxer
*/
_getStreams: () => any[];
/**
* Connection streams registry
*/
registry: Map<any, any>;
/**
* User provided tags
*
* @type {string[]}
*/
tags: string[];
/**
* Get connection metadata
*
* @this {Connection}
*/
get stat(): {
status: string;
/**
* - connection establishment direction ("inbound" or "outbound").
*/
direction: string;
/**
* - connection relevant events timestamp.
*/
timeline: {
open: string;
upgraded: string;
};
/**
* - connection multiplexing identifier.
*/
multiplexer?: string;
/**
* - connection encryption method identifier.
*/
encryption?: string;
};
/**
* Get all the streams of the muxer.
*
* @this {Connection}
*/
get streams(): any[];
/**
* Create a new stream from this connection
*
* @param {string[]|string} protocols - intended protocol for the stream
* @returns {Promise<{stream: Stream, protocol: string}>} with muxed+multistream-selected stream and selected protocol
*/
newStream(protocols: string[] | string): Promise<{
stream: any;
protocol: string;
}>;
/**
* Add a stream when it is opened to the registry.
*
* @param {*} muxedStream - a muxed stream
* @param {object} properties - the stream properties to be registered
* @param {string} properties.protocol - the protocol used by the stream
* @param {object} properties.metadata - metadata of the stream
* @returns {void}
*/
addStream(muxedStream: any, { protocol, metadata }: {
protocol: string;
metadata: object;
}): void;
/**
* Remove stream registry after it is closed.
*
* @param {string} id - identifier of the stream
*/
removeStream(id: string): void;
/**
* Close the connection.
*
* @returns {Promise<void>}
*/
close(): Promise<void>;
_closing: void;
}
declare namespace Connection {
export { ConectionStat, ConnectionOptions };
}
type ConnectionOptions = {
/**
* - local multiaddr of the connection if known.
*/
localAddr?: import("multiaddr");
/**
* - remote multiaddr of the connection.
*/
remoteAddr?: import("multiaddr");
/**
* - local peer-id.
*/
localPeer: import("peer-id");
/**
* - remote peer-id.
*/
remotePeer: import("peer-id");
/**
* - new stream muxer function.
*/
newStream: (protocols: string[]) => Promise<{
stream: any;
protocol: string;
}>;
/**
* - close raw connection function.
*/
close: () => Promise<void>;
/**
* - get streams from muxer function.
*/
getStreams: () => any[];
/**
* - metadata of the connection.
*/
stat: ConectionStat;
};
type ConectionStat = {
/**
* - connection establishment direction ("inbound" or "outbound").
*/
direction: string;
/**
* - connection relevant events timestamp.
*/
timeline: {
open: string;
upgraded: string;
};
/**
* - connection multiplexing identifier.
*/
multiplexer?: string;
/**
* - connection encryption method identifier.
*/
encryption?: string;
};

View File

@ -1,7 +1,242 @@
'use strict'
const PeerId = require('peer-id')
const multiaddr = require('multiaddr')
const withIs = require('class-is')
const errCode = require('err-code')
const Status = require('./status')
/**
* @module connection/index
* @type {typeof import('./connection')}
* @typedef {Object} ConectionStat
* @property {string} direction - connection establishment direction ("inbound" or "outbound").
* @property {object} timeline - connection relevant events timestamp.
* @property {string} timeline.open - connection opening timestamp.
* @property {string} timeline.upgraded - connection upgraded timestamp.
* @property {string} [multiplexer] - connection multiplexing identifier.
* @property {string} [encryption] - connection encryption method identifier.
*
* @typedef {Object} ConnectionOptions
* @property {multiaddr} [localAddr] - local multiaddr of the connection if known.
* @property {multiaddr} [remoteAddr] - remote multiaddr of the connection.
* @property {PeerId} localPeer - local peer-id.
* @property {PeerId} remotePeer - remote peer-id.
* @property {(protocols: string[]) => Promise<{stream: Stream, protocol: string}>} newStream - new stream muxer function.
* @property {() => Promise<void>} close - close raw connection function.
* @property {() => Stream[]} getStreams - get streams from muxer function.
* @property {ConectionStat} stat - metadata of the connection.
*/
exports.Connection = require('./connection')
class Connection {
/**
* An implementation of the js-libp2p connection.
* Any libp2p transport should use an upgrader to return this connection.
*
* @class
* @param {ConnectionOptions} options
*/
constructor ({ localAddr, remoteAddr, localPeer, remotePeer, newStream, close, getStreams, stat }) {
validateArgs(localAddr, localPeer, remotePeer, newStream, close, getStreams, stat)
/**
* Connection identifier.
*/
this.id = (parseInt(Math.random() * 1e9)).toString(36) + Date.now()
/**
* Observed multiaddr of the local peer
*/
this.localAddr = localAddr
/**
* Observed multiaddr of the remote peer
*/
this.remoteAddr = remoteAddr
/**
* Local peer id.
*/
this.localPeer = localPeer
/**
* Remote peer id.
*/
this.remotePeer = remotePeer
/**
* Connection metadata.
*/
this._stat = {
...stat,
status: Status.OPEN
}
/**
* Reference to the new stream function of the multiplexer
*/
this._newStream = newStream
/**
* Reference to the close function of the raw connection
*/
this._close = close
/**
* Reference to the getStreams function of the muxer
*/
this._getStreams = getStreams
/**
* Connection streams registry
*/
this.registry = new Map()
/**
* User provided tags
*
* @type {string[]}
*/
this.tags = []
}
/**
* Get connection metadata
*
* @this {Connection}
*/
get stat () {
return this._stat
}
/**
* Get all the streams of the muxer.
*
* @this {Connection}
*/
get streams () {
return this._getStreams()
}
/**
* Create a new stream from this connection
*
* @param {string[]|string} protocols - intended protocol for the stream
* @returns {Promise<{stream: Stream, protocol: string}>} with muxed+multistream-selected stream and selected protocol
*/
async newStream (protocols) {
if (this.stat.status === Status.CLOSING) {
throw errCode(new Error('the connection is being closed'), 'ERR_CONNECTION_BEING_CLOSED')
}
if (this.stat.status === Status.CLOSED) {
throw errCode(new Error('the connection is closed'), 'ERR_CONNECTION_CLOSED')
}
if (!Array.isArray(protocols)) protocols = [protocols]
const { stream, protocol } = await this._newStream(protocols)
this.addStream(stream, { protocol })
return {
stream,
protocol
}
}
/**
* Add a stream when it is opened to the registry.
*
* @param {*} muxedStream - a muxed stream
* @param {object} properties - the stream properties to be registered
* @param {string} properties.protocol - the protocol used by the stream
* @param {object} properties.metadata - metadata of the stream
* @returns {void}
*/
addStream (muxedStream, { protocol, metadata = {} }) {
// Add metadata for the stream
this.registry.set(muxedStream.id, {
protocol,
...metadata
})
}
/**
* Remove stream registry after it is closed.
*
* @param {string} id - identifier of the stream
*/
removeStream (id) {
this.registry.delete(id)
}
/**
* Close the connection.
*
* @returns {Promise<void>}
*/
async close () {
if (this.stat.status === Status.CLOSED) {
return
}
if (this._closing) {
return this._closing
}
this.stat.status = Status.CLOSING
// Close raw connection
this._closing = await this._close()
this._stat.timeline.close = Date.now()
this.stat.status = Status.CLOSED
}
}
module.exports = Connection
function validateArgs (localAddr, localPeer, remotePeer, newStream, close, getStreams, stat) {
if (localAddr && !multiaddr.isMultiaddr(localAddr)) {
throw errCode(new Error('localAddr must be an instance of multiaddr'), 'ERR_INVALID_PARAMETERS')
}
if (!PeerId.isPeerId(localPeer)) {
throw errCode(new Error('localPeer must be an instance of peer-id'), 'ERR_INVALID_PARAMETERS')
}
if (!PeerId.isPeerId(remotePeer)) {
throw errCode(new Error('remotePeer must be an instance of peer-id'), 'ERR_INVALID_PARAMETERS')
}
if (typeof newStream !== 'function') {
throw errCode(new Error('new stream must be a function'), 'ERR_INVALID_PARAMETERS')
}
if (typeof close !== 'function') {
throw errCode(new Error('close must be a function'), 'ERR_INVALID_PARAMETERS')
}
if (typeof getStreams !== 'function') {
throw errCode(new Error('getStreams must be a function'), 'ERR_INVALID_PARAMETERS')
}
if (!stat) {
throw errCode(new Error('connection metadata object must be provided'), 'ERR_INVALID_PARAMETERS')
}
if (stat.direction !== 'inbound' && stat.direction !== 'outbound') {
throw errCode(new Error('direction must be "inbound" or "outbound"'), 'ERR_INVALID_PARAMETERS')
}
if (!stat.timeline) {
throw errCode(new Error('connection timeline object must be provided in the stat object'), 'ERR_INVALID_PARAMETERS')
}
if (!stat.timeline.open) {
throw errCode(new Error('connection open timestamp must be provided'), 'ERR_INVALID_PARAMETERS')
}
if (!stat.timeline.upgraded) {
throw errCode(new Error('connection upgraded timestamp must be provided'), 'ERR_INVALID_PARAMETERS')
}
}

View File

@ -1,3 +1,3 @@
export const OPEN: 'open';
export const CLOSING: 'closing';
export const CLOSED: 'closed';
export const OPEN: string;
export const CLOSING: string;
export const CLOSED: string;

View File

@ -1,7 +1,7 @@
'use strict'
module.exports = {
OPEN: /** @type {'open'} */('open'),
CLOSING: /** @type {'closing'} */('closing'),
CLOSED: /** @type {'closed'} */('closed')
OPEN: 'open',
CLOSING: 'closing',
CLOSED: 'closed'
}

View File

@ -0,0 +1,6 @@
export = ContentRouting;
declare class ContentRouting {
findProviders(cid);
provide(cid);
}

0
src/crypto/types.ts Normal file
View File

View File

View File

163
src/pubsub/index.d.ts vendored
View File

@ -1,14 +1,40 @@
export = PubsubBaseProtocol;
/**
* PubsubBaseProtocol handles the peers and connections logic for pubsub routers
* and specifies the API that pubsub routers should have.
*/
* @typedef {Object} InMessage
* @property {string} [from]
* @property {string} receivedFrom
* @property {string[]} topicIDs
* @property {Uint8Array} [seqno]
* @property {Uint8Array} data
* @property {Uint8Array} [signature]
* @property {Uint8Array} [key]
*
* @typedef PeerId
* @type import('peer-id')
*/
/**
* PubsubBaseProtocol handles the peers and connections logic for pubsub routers
* and specifies the API that pubsub routers should have.
*/
declare class PubsubBaseProtocol {
/**
* @param {Object} props
* @param {string} props.debugName - log namespace
* @param {Array<string>|string} props.multicodecs - protocol identificers to connect
* @param {Libp2p} props.libp2p
* @param {SignaturePolicy} [props.globalSignaturePolicy = SignaturePolicy.StrictSign] - defines how signatures should be handled
* @param {boolean} [props.canRelayMessage = false] - if can relay messages not subscribed
* @param {boolean} [props.emitSelf = false] - if publish should emit to self, if subscribed
* @abstract
* @param {Options} options
*/
constructor({ debugName, multicodecs, libp2p, globalSignaturePolicy, canRelayMessage, emitSelf }: Options);
constructor({ debugName, multicodecs, libp2p, globalSignaturePolicy, canRelayMessage, emitSelf }: {
debugName: string;
multicodecs: Array<string> | string;
libp2p: any;
globalSignaturePolicy: any;
canRelayMessage: boolean;
emitSelf: boolean;
});
log: any;
/**
* @type {Array<string>}
@ -29,6 +55,7 @@ declare class PubsubBaseProtocol {
topics: Map<string, Set<string>>;
/**
* List of our subscriptions
*
* @type {Set<string>}
*/
subscriptions: Set<string>;
@ -46,16 +73,19 @@ declare class PubsubBaseProtocol {
globalSignaturePolicy: string;
/**
* If router can relay received messages, even if not subscribed
*
* @type {boolean}
*/
canRelayMessage: boolean;
/**
* if publish should emit to self, if subscribed
*
* @type {boolean}
*/
emitSelf: boolean;
/**
* Topic validator function
*
* @typedef {function(string, InMessage): Promise<void>} validator
*/
/**
@ -63,6 +93,7 @@ declare class PubsubBaseProtocol {
*
* Keyed by topic
* Topic validators are functions with the following input:
*
* @type {Map<string, validator>}
*/
topicValidators: Map<string, (arg0: string, arg1: InMessage) => Promise<void>>;
@ -70,103 +101,108 @@ declare class PubsubBaseProtocol {
/**
* On an inbound stream opened.
*
* @protected
* @private
* @param {Object} props
* @param {string} props.protocol
* @param {DuplexIterableStream} props.stream
* @param {Connection} props.connection connection
* @param {Connection} props.connection - connection
*/
protected _onIncomingStream({ protocol, stream, connection }: {
protocol: string;
stream: any;
connection: any;
}): void;
private _onIncomingStream;
/**
* Registrar notifies an established connection with pubsub protocol.
*
* @protected
* @param {PeerId} peerId remote peer-id
* @param {Connection} conn connection to the peer
* @private
* @param {PeerId} peerId - remote peer-id
* @param {Connection} conn - connection to the peer
*/
protected _onPeerConnected(peerId: PeerId, conn: any): Promise<void>;
private _onPeerConnected;
/**
* Registrar notifies a closing connection with pubsub protocol.
*
* @protected
* @param {PeerId} peerId peerId
* @param {Error} err error for connection end
* @private
* @param {PeerId} peerId - peerId
* @param {Error} err - error for connection end
*/
protected _onPeerDisconnected(peerId: PeerId, err: Error): void;
private _onPeerDisconnected;
/**
* Register the pubsub protocol onto the libp2p node.
*
* @returns {void}
*/
start(): void;
/**
* Unregister the pubsub protocol and the streams with other peers will be closed.
*
* @returns {void}
*/
stop(): void;
/**
* Notifies the router that a peer has been connected
*
* @protected
* @private
* @param {PeerId} peerId
* @param {string} protocol
* @returns {PeerStreams}
*/
protected _addPeer(peerId: PeerId, protocol: string): PeerStreams;
private _addPeer;
/**
* Notifies the router that a peer has been disconnected.
*
* @protected
* @private
* @param {PeerId} peerId
* @returns {PeerStreams | undefined}
*/
protected _removePeer(peerId: PeerId): PeerStreams | undefined;
private _removePeer;
/**
* Responsible for processing each RPC message received by other peers.
* @param {string} idB58Str peer id string in base58
* @param {DuplexIterableStream} stream inbound stream
* @param {PeerStreams} peerStreams PubSub peer
*
* @param {string} idB58Str - peer id string in base58
* @param {DuplexIterableStream} stream - inbound stream
* @param {PeerStreams} peerStreams - PubSub peer
* @returns {Promise<void>}
*/
_processMessages(idB58Str: string, stream: any, peerStreams: PeerStreams): Promise<void>;
_processMessages(idB58Str: string, stream: any, peerStreams: import("./peer-streams")): Promise<void>;
/**
* Handles an rpc request from a peer
* @param {String} idB58Str
*
* @param {string} idB58Str
* @param {PeerStreams} peerStreams
* @param {RPC} rpc
* @returns {boolean}
*/
_processRpc(idB58Str: string, peerStreams: PeerStreams, rpc: any): boolean;
_processRpc(idB58Str: string, peerStreams: import("./peer-streams"), rpc: any): boolean;
/**
* Handles a subscription change from a peer
*
* @param {string} id
* @param {RPC.SubOpt} subOpt
*/
_processRpcSubOpt(id: string, subOpt: any): void;
/**
* Handles an message from a peer
*
* @param {InMessage} msg
* @returns {Promise<void>}
*/
_processRpcMessage(msg: InMessage): Promise<void>;
/**
* Emit a message from a peer
*
* @param {InMessage} message
*/
_emitMessage(message: InMessage): void;
/**
* The default msgID implementation
* Child class can override this.
* @param {RPC.Message} msg the message object
*
* @param {RPC.Message} msg - the message object
* @returns {Uint8Array} message id as bytes
*/
getMsgId(msg: any): Uint8Array;
/**
* Whether to accept a message from a peer
* Override to create a graylist
*
* @override
* @param {string} id
* @returns {boolean}
@ -175,6 +211,7 @@ declare class PubsubBaseProtocol {
/**
* Decode Uint8Array into an RPC object.
* This can be override to use a custom router protobuf.
*
* @param {Uint8Array} bytes
* @returns {RPC}
*/
@ -182,28 +219,32 @@ declare class PubsubBaseProtocol {
/**
* Encode RPC object into a Uint8Array.
* This can be override to use a custom router protobuf.
*
* @param {RPC} rpc
* @returns {Uint8Array}
*/
_encodeRpc(rpc: any): Uint8Array;
/**
* Send an rpc object to a peer
* @param {string} id peer id
*
* @param {string} id - peer id
* @param {RPC} rpc
* @returns {void}
*/
_sendRpc(id: string, rpc: any): void;
/**
* Send subscroptions to a peer
* @param {string} id peer id
*
* @param {string} id - peer id
* @param {string[]} topics
* @param {boolean} subscribe set to false for unsubscriptions
* @param {boolean} subscribe - set to false for unsubscriptions
* @returns {void}
*/
_sendSubscriptions(id: string, topics: string[], subscribe: boolean): void;
/**
* Validates the given message. The signature will be checked for authenticity.
* Throws an error on invalid messages
*
* @param {InMessage} message
* @returns {Promise<void>}
*/
@ -212,19 +253,21 @@ declare class PubsubBaseProtocol {
* Normalizes the message and signs it, if signing is enabled.
* Should be used by the routers to create the message to send.
*
* @protected
* @private
* @param {Message} message
* @returns {Promise<Message>}
*/
protected _buildMessage(message: any): Promise<any>;
private _buildMessage;
/**
* Get a list of the peer-ids that are subscribed to one topic.
*
* @param {string} topic
* @returns {Array<string>}
*/
getSubscribers(topic: string): Array<string>;
/**
* Publishes messages to all subscribed peers
*
* @override
* @param {string} topic
* @param {Buffer} message
@ -234,6 +277,7 @@ declare class PubsubBaseProtocol {
/**
* Overriding the implementation of publish should handle the appropriate algorithms for the publish/subscriber implementation.
* For example, a Floodsub implementation might simply publish each message to each topic for every peer
*
* @abstract
* @param {InMessage} message
* @returns {Promise<void>}
@ -242,6 +286,7 @@ declare class PubsubBaseProtocol {
_publish(message: InMessage): Promise<void>;
/**
* Subscribes to a given topic.
*
* @abstract
* @param {string} topic
* @returns {void}
@ -249,6 +294,7 @@ declare class PubsubBaseProtocol {
subscribe(topic: string): void;
/**
* Unsubscribe from the given topic.
*
* @override
* @param {string} topic
* @returns {void}
@ -256,52 +302,31 @@ declare class PubsubBaseProtocol {
unsubscribe(topic: string): void;
/**
* Get the list of topics which the peer is subscribed to.
*
* @override
* @returns {Array<String>}
* @returns {Array<string>}
*/
getTopics(): Array<string>;
}
declare namespace PubsubBaseProtocol {
export { message, utils, SignaturePolicy, Options, InMessage, PeerId, SignaturePolicyType };
export { message, utils, SignaturePolicy, InMessage, PeerId };
}
type PeerId = import("peer-id");
type InMessage = {
from?: string | undefined;
from?: string;
receivedFrom: string;
topicIDs: string[];
seqno?: Uint8Array | undefined;
seqno?: Uint8Array;
data: Uint8Array;
signature?: Uint8Array | undefined;
key?: Uint8Array | undefined;
};
import PeerStreams = require("./peer-streams");
type Options = {
/**
* - log namespace
*/
debugName?: string | undefined;
/**
* - protocol identificers to connect
*/
multicodecs?: string | string[] | undefined;
libp2p: any;
/**
* - defines how signatures should be handled
*/
globalSignaturePolicy?: "StrictSign" | "StrictNoSign" | undefined;
/**
* - if can relay messages not subscribed
*/
canRelayMessage?: boolean | undefined;
/**
* - if publish should emit to self, if subscribed
*/
emitSelf?: boolean | undefined;
signature?: Uint8Array;
key?: Uint8Array;
};
/**
* @type {typeof import('./message')}
*/
declare const message: typeof import('./message');
import utils = require("./utils");
import { SignaturePolicy } from "./signature-policy";
type SignaturePolicyType = "StrictSign" | "StrictNoSign";
declare const utils: typeof import("./utils");
declare const SignaturePolicy: {
StrictSign: string;
StrictNoSign: string;
};

View File

@ -1,5 +1,4 @@
'use strict'
/* eslint-disable valid-jsdoc */
const debug = require('debug')
const EventEmitter = require('events')
@ -23,13 +22,33 @@ const {
} = require('./message/sign')
/**
* PubsubBaseProtocol handles the peers and connections logic for pubsub routers
* and specifies the API that pubsub routers should have.
*/
* @typedef {Object} InMessage
* @property {string} [from]
* @property {string} receivedFrom
* @property {string[]} topicIDs
* @property {Uint8Array} [seqno]
* @property {Uint8Array} data
* @property {Uint8Array} [signature]
* @property {Uint8Array} [key]
*
* @typedef PeerId
* @type import('peer-id')
*/
/**
* PubsubBaseProtocol handles the peers and connections logic for pubsub routers
* and specifies the API that pubsub routers should have.
*/
class PubsubBaseProtocol extends EventEmitter {
/**
* @param {Object} props
* @param {string} props.debugName - log namespace
* @param {Array<string>|string} props.multicodecs - protocol identificers to connect
* @param {Libp2p} props.libp2p
* @param {SignaturePolicy} [props.globalSignaturePolicy = SignaturePolicy.StrictSign] - defines how signatures should be handled
* @param {boolean} [props.canRelayMessage = false] - if can relay messages not subscribed
* @param {boolean} [props.emitSelf = false] - if publish should emit to self, if subscribed
* @abstract
* @param {Options} options
*/
constructor ({
debugName,
@ -78,6 +97,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* List of our subscriptions
*
* @type {Set<string>}
*/
this.subscriptions = new Set()
@ -103,18 +123,21 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* If router can relay received messages, even if not subscribed
*
* @type {boolean}
*/
this.canRelayMessage = canRelayMessage
/**
* if publish should emit to self, if subscribed
*
* @type {boolean}
*/
this.emitSelf = emitSelf
/**
* Topic validator function
*
* @typedef {function(string, InMessage): Promise<void>} validator
*/
/**
@ -122,6 +145,7 @@ class PubsubBaseProtocol extends EventEmitter {
*
* Keyed by topic
* Topic validators are functions with the following input:
*
* @type {Map<string, validator>}
*/
this.topicValidators = new Map()
@ -136,6 +160,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Register the pubsub protocol onto the libp2p node.
*
* @returns {void}
*/
start () {
@ -165,6 +190,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Unregister the pubsub protocol and the streams with other peers will be closed.
*
* @returns {void}
*/
stop () {
@ -187,11 +213,11 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* On an inbound stream opened.
*
* @protected
* @private
* @param {Object} props
* @param {string} props.protocol
* @param {DuplexIterableStream} props.stream
* @param {Connection} props.connection connection
* @param {Connection} props.connection - connection
*/
_onIncomingStream ({ protocol, stream, connection }) {
const peerId = connection.remotePeer
@ -205,9 +231,9 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Registrar notifies an established connection with pubsub protocol.
*
* @protected
* @param {PeerId} peerId remote peer-id
* @param {Connection} conn connection to the peer
* @private
* @param {PeerId} peerId - remote peer-id
* @param {Connection} conn - connection to the peer
*/
async _onPeerConnected (peerId, conn) {
const idB58Str = peerId.toB58String()
@ -228,9 +254,9 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Registrar notifies a closing connection with pubsub protocol.
*
* @protected
* @param {PeerId} peerId peerId
* @param {Error} err error for connection end
* @private
* @param {PeerId} peerId - peerId
* @param {Error} err - error for connection end
*/
_onPeerDisconnected (peerId, err) {
const idB58Str = peerId.toB58String()
@ -242,7 +268,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Notifies the router that a peer has been connected
*
* @protected
* @private
* @param {PeerId} peerId
* @param {string} protocol
* @returns {PeerStreams}
@ -273,7 +299,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Notifies the router that a peer has been disconnected.
*
* @protected
* @private
* @param {PeerId} peerId
* @returns {PeerStreams | undefined}
*/
@ -303,9 +329,10 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Responsible for processing each RPC message received by other peers.
* @param {string} idB58Str peer id string in base58
* @param {DuplexIterableStream} stream inbound stream
* @param {PeerStreams} peerStreams PubSub peer
*
* @param {string} idB58Str - peer id string in base58
* @param {DuplexIterableStream} stream - inbound stream
* @param {PeerStreams} peerStreams - PubSub peer
* @returns {Promise<void>}
*/
async _processMessages (idB58Str, stream, peerStreams) {
@ -328,7 +355,8 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Handles an rpc request from a peer
* @param {String} idB58Str
*
* @param {string} idB58Str
* @param {PeerStreams} peerStreams
* @param {RPC} rpc
* @returns {boolean}
@ -364,6 +392,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Handles a subscription change from a peer
*
* @param {string} id
* @param {RPC.SubOpt} subOpt
*/
@ -387,6 +416,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Handles an message from a peer
*
* @param {InMessage} msg
* @returns {Promise<void>}
*/
@ -411,6 +441,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Emit a message from a peer
*
* @param {InMessage} message
*/
_emitMessage (message) {
@ -424,7 +455,8 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* The default msgID implementation
* Child class can override this.
* @param {RPC.Message} msg the message object
*
* @param {RPC.Message} msg - the message object
* @returns {Uint8Array} message id as bytes
*/
getMsgId (msg) {
@ -442,6 +474,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Whether to accept a message from a peer
* Override to create a graylist
*
* @override
* @param {string} id
* @returns {boolean}
@ -453,6 +486,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Decode Uint8Array into an RPC object.
* This can be override to use a custom router protobuf.
*
* @param {Uint8Array} bytes
* @returns {RPC}
*/
@ -463,6 +497,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Encode RPC object into a Uint8Array.
* This can be override to use a custom router protobuf.
*
* @param {RPC} rpc
* @returns {Uint8Array}
*/
@ -472,7 +507,8 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Send an rpc object to a peer
* @param {string} id peer id
*
* @param {string} id - peer id
* @param {RPC} rpc
* @returns {void}
*/
@ -489,9 +525,10 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Send subscroptions to a peer
* @param {string} id peer id
*
* @param {string} id - peer id
* @param {string[]} topics
* @param {boolean} subscribe set to false for unsubscriptions
* @param {boolean} subscribe - set to false for unsubscriptions
* @returns {void}
*/
_sendSubscriptions (id, topics, subscribe) {
@ -503,6 +540,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Validates the given message. The signature will be checked for authenticity.
* Throws an error on invalid messages
*
* @param {InMessage} message
* @returns {Promise<void>}
*/
@ -550,7 +588,7 @@ class PubsubBaseProtocol extends EventEmitter {
* Normalizes the message and signs it, if signing is enabled.
* Should be used by the routers to create the message to send.
*
* @protected
* @private
* @param {Message} message
* @returns {Promise<Message>}
*/
@ -572,6 +610,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Get a list of the peer-ids that are subscribed to one topic.
*
* @param {string} topic
* @returns {Array<string>}
*/
@ -593,6 +632,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Publishes messages to all subscribed peers
*
* @override
* @param {string} topic
* @param {Buffer} message
@ -626,6 +666,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Overriding the implementation of publish should handle the appropriate algorithms for the publish/subscriber implementation.
* For example, a Floodsub implementation might simply publish each message to each topic for every peer
*
* @abstract
* @param {InMessage} message
* @returns {Promise<void>}
@ -637,6 +678,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Subscribes to a given topic.
*
* @abstract
* @param {string} topic
* @returns {void}
@ -654,6 +696,7 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Unsubscribe from the given topic.
*
* @override
* @param {string} topic
* @returns {void}
@ -671,8 +714,9 @@ class PubsubBaseProtocol extends EventEmitter {
/**
* Get the list of topics which the peer is subscribed to.
*
* @override
* @returns {Array<String>}
* @returns {Array<string>}
*/
getTopics () {
if (!this.started) {
@ -683,27 +727,6 @@ class PubsubBaseProtocol extends EventEmitter {
}
}
/**
* @typedef {Object} Options
* @property {string} [debugName] - log namespace
* @property {string[]|string} [multicodecs] - protocol identificers to connect
* @property {Libp2p} libp2p
* @property {SignaturePolicyType} [globalSignaturePolicy = SignaturePolicy.StrictSign] - defines how signatures should be handled
* @property {boolean} [canRelayMessage = false] - if can relay messages not subscribed
* @property {boolean} [emitSelf = false] - if publish should emit to self, if subscribed
*
* @typedef {Object} InMessage
* @property {string} [from]
* @property {string} receivedFrom
* @property {string[]} topicIDs
* @property {Uint8Array} [seqno]
* @property {Uint8Array} data
* @property {Uint8Array} [signature]
* @property {Uint8Array} [key]
*
* @typedef {import('peer-id')} PeerId
* @typedef {import('./signature-policy').SignaturePolicyType} SignaturePolicyType
*/
module.exports = PubsubBaseProtocol
module.exports.message = message
module.exports.utils = utils

View File

@ -1,4 +1,5 @@
declare const rpcProto: any;
declare const topicDescriptorProto: any;
export const RPC: any;
export { rpcProto as rpc, topicDescriptorProto as td };
export var rpc: any;
export var td: any;
export var RPC: any;
export var Message: any;
export var SubOpts: any;

View File

@ -13,12 +13,12 @@ export function messagePublicKey(message: any): Promise<any>;
* @param {Message} message
* @returns {Promise<Message>}
*/
export function signMessage(peerId: PeerId, message: any): Promise<any>;
export function signMessage(peerId: import("peer-id"), message: any): Promise<any>;
export const SignPrefix: any;
/**
* Verifies the signature of the given message
*
* @param {InMessage} message
* @returns {Promise<Boolean>}
* @returns {Promise<boolean>}
*/
export function verifySignature(message: any): Promise<boolean>;
import PeerId = require("peer-id");

View File

@ -31,8 +31,9 @@ async function signMessage (peerId, message) {
/**
* Verifies the signature of the given message
*
* @param {InMessage} message
* @returns {Promise<Boolean>}
* @returns {Promise<boolean>}
*/
async function verifySignature (message) {
// Get message sans the signature

View File

@ -16,7 +16,7 @@ export = PeerStreams;
*/
declare class PeerStreams {
/**
* @param {object} properties properties of the PeerStreams.
* @param {object} properties - properties of the PeerStreams.
* @param {PeerId} properties.id
* @param {string} properties.protocol
*/
@ -30,37 +30,40 @@ declare class PeerStreams {
id: import('peer-id');
/**
* Established protocol
*
* @type {string}
*/
protocol: string;
/**
* The raw outbound stream, as retrieved from conn.newStream
*
* @protected
* @private
* @type {DuplexIterableStream}
*/
protected _rawOutboundStream: DuplexIterableStream;
private _rawOutboundStream;
/**
* The raw inbound stream, as retrieved from the callback from libp2p.handle
*
* @protected
* @private
* @type {DuplexIterableStream}
*/
protected _rawInboundStream: DuplexIterableStream;
private _rawInboundStream;
/**
* An AbortController for controlled shutdown of the inbound stream
*
* @protected
* @private
* @type {typeof AbortController}
*/
protected _inboundAbortController: typeof AbortController;
private _inboundAbortController;
/**
* Write stream -- its preferable to use the write method
*
* @type {import('it-pushable').Pushable<Uint8Array>>}
*/
outboundStream: import('it-pushable').Pushable<Uint8Array>;
/**
* Read stream
*
* @type {DuplexIterableStream}
*/
inboundStream: DuplexIterableStream;
@ -100,6 +103,7 @@ declare class PeerStreams {
attachOutboundStream(stream: any): Promise<void>;
/**
* Closes the open connection to peer
*
* @returns {void}
*/
close(): void;
@ -111,6 +115,5 @@ type DuplexIterableStream = {
sink: Sink;
source: () => AsyncIterator<Uint8Array>;
};
import AbortController = require("abort-controller");
type PeerId = import("peer-id");
type Sink = (source: Uint8Array) => Promise<Uint8Array>;

View File

@ -30,7 +30,7 @@ log.error = debug('libp2p-pubsub:peer-streams:error')
*/
class PeerStreams extends EventEmitter {
/**
* @param {object} properties properties of the PeerStreams.
* @param {object} properties - properties of the PeerStreams.
* @param {PeerId} properties.id
* @param {string} properties.protocol
*/
@ -43,37 +43,40 @@ class PeerStreams extends EventEmitter {
this.id = id
/**
* Established protocol
*
* @type {string}
*/
this.protocol = protocol
/**
* The raw outbound stream, as retrieved from conn.newStream
*
* @protected
* @private
* @type {DuplexIterableStream}
*/
this._rawOutboundStream = null
/**
* The raw inbound stream, as retrieved from the callback from libp2p.handle
*
* @protected
* @private
* @type {DuplexIterableStream}
*/
this._rawInboundStream = null
/**
* An AbortController for controlled shutdown of the inbound stream
*
* @protected
* @private
* @type {typeof AbortController}
*/
this._inboundAbortController = null
/**
* Write stream -- its preferable to use the write method
*
* @type {import('it-pushable').Pushable<Uint8Array>>}
*/
this.outboundStream = null
/**
* Read stream
*
* @type {DuplexIterableStream}
*/
this.inboundStream = null
@ -182,6 +185,7 @@ class PeerStreams extends EventEmitter {
/**
* Closes the open connection to peer
*
* @returns {void}
*/
close () {

View File

@ -1,5 +1,4 @@
export type SignaturePolicyType = "StrictSign" | "StrictNoSign";
export namespace SignaturePolicy {
const StrictSign: 'StrictSign';
const StrictNoSign: 'StrictNoSign';
const StrictSign: string;
const StrictNoSign: string;
}

View File

@ -4,7 +4,7 @@
* Enum for Signature Policy
* Details how message signatures are produced/consumed
*/
const SignaturePolicy = {
exports.SignaturePolicy = {
/**
* On the producing side:
* * Build messages with the signature, key (from may be enough for certain inlineable public key types), from and seqno fields.
@ -13,7 +13,7 @@ const SignaturePolicy = {
* * Enforce the fields to be present, reject otherwise.
* * Propagate only if the fields are valid and signature can be verified, reject otherwise.
*/
StrictSign: /** @type {'StrictSign'} */ ('StrictSign'),
StrictSign: 'StrictSign',
/**
* On the producing side:
* * Build messages without the signature, key, from and seqno fields.
@ -24,10 +24,5 @@ const SignaturePolicy = {
* * Propagate only if the fields are absent, reject otherwise.
* * A message_id function will not be able to use the above fields, and should instead rely on the data field. A commonplace strategy is to calculate a hash.
*/
StrictNoSign: /** @type {'StrictNoSign'} */ ('StrictNoSign')
StrictNoSign: 'StrictNoSign'
}
exports.SignaturePolicy = SignaturePolicy
/**
* @typedef {SignaturePolicy[keyof SignaturePolicy]} SignaturePolicyType
*/

12
src/pubsub/utils.d.ts vendored
View File

@ -2,12 +2,6 @@ export function randomSeqno(): Uint8Array;
export function msgId(from: string, seqno: Uint8Array): Uint8Array;
export function noSignMsgId(data: Uint8Array): Uint8Array;
export function anyMatch(a: Set<any> | any[], b: Set<any> | any[]): boolean;
export function ensureArray<T>(maybeArray: T | T[]): T[];
export function normalizeInRpcMessage<T extends unknown>(message: T, peerId?: string | undefined): T & {
from?: string | undefined;
peerId?: string | undefined;
};
export function normalizeOutRpcMessage<T extends unknown>(message: T): T & {
from?: Uint8Array | undefined;
data?: Uint8Array | undefined;
};
export function ensureArray(maybeArray: any): any[];
export function normalizeInRpcMessage(message: object, peerId: string): object;
export function normalizeOutRpcMessage(message: object): object;

View File

@ -1,5 +1,4 @@
'use strict'
/* eslint-disable valid-jsdoc */
const randomBytes = require('libp2p-crypto/src/random-bytes')
const uint8ArrayToString = require('uint8arrays/to-string')
@ -72,9 +71,8 @@ exports.anyMatch = (a, b) => {
/**
* Make everything an array.
*
* @template T
* @param {T|T[]} maybeArray
* @returns {T[]}
* @param {any} maybeArray
* @returns {Array}
* @private
*/
exports.ensureArray = (maybeArray) => {
@ -88,10 +86,9 @@ exports.ensureArray = (maybeArray) => {
/**
* Ensures `message.from` is base58 encoded
*
* @template {Object} T
* @param {T} message
* @param {string} [peerId]
* @return {T & {from?: string, peerId?: string }}
* @param {object} message
* @param {string} peerId
* @returns {object}
*/
exports.normalizeInRpcMessage = (message, peerId) => {
const m = Object.assign({}, message)
@ -105,10 +102,8 @@ exports.normalizeInRpcMessage = (message, peerId) => {
}
/**
* @template {Object} T
*
* @param {T} message
* @return {T & {from?: Uint8Array, data?: Uint8Array}}
* @param {object} message
* @returns {object}
*/
exports.normalizeOutRpcMessage = (message) => {
const m = Object.assign({}, message)

View File

@ -4,9 +4,9 @@ export = Record;
*/
declare class Record {
/**
* @constructor
* @param {String} domain signature domain
* @param {Uint8Array} codec identifier of the type of record
* @class
* @param {string} domain - signature domain
* @param {Uint8Array} codec - identifier of the type of record
*/
constructor(domain: string, codec: Uint8Array);
domain: string;
@ -17,6 +17,7 @@ declare class Record {
marshal(): void;
/**
* Verifies if the other provided Record is identical to this one.
*
* @param {Record} other
*/
equals(other: Record): void;

View File

@ -7,9 +7,9 @@ const errcode = require('err-code')
*/
class Record {
/**
* @constructor
* @param {String} domain signature domain
* @param {Uint8Array} codec identifier of the type of record
* @class
* @param {string} domain - signature domain
* @param {Uint8Array} codec - identifier of the type of record
*/
constructor (domain, codec) {
this.domain = domain
@ -25,6 +25,7 @@ class Record {
/**
* Verifies if the other provided Record is identical to this one.
*
* @param {Record} other
*/
equals (other) {

View File

@ -20,8 +20,9 @@ async function closeAndWait (stream) {
/**
* A tick is considered valid if it happened between now
* and `ms` milliseconds ago
* @param {number} date Time in ticks
* @param {number} ms max milliseconds that should have expired
*
* @param {number} date - Time in ticks
* @param {number} ms - max milliseconds that should have expired
* @returns {boolean}
*/
function isValidTick (date, ms = 5000) {

View File

View File

@ -1,62 +1,63 @@
export = Topology;
declare class Topology {
/**
* Checks if the given value is a Topology instance.
*
* @param {any} other
* @returns {other is Topology}
*/
static isTopology(other: any): other is Topology;
/**
* @param {Options} options
*/
constructor({ min, max, handlers }: Options);
min: number;
max: number;
_onConnect: Function;
_onDisconnect: Function;
/**
* Set of peers that support the protocol.
* @type {Set<string>}
*/
peers: Set<string>;
get [Symbol.toStringTag](): string;
set registrar(arg: any);
_registrar: any;
/**
* @typedef PeerId
* @type {import('peer-id')}
*/
/**
* Notify about peer disconnected event.
* @param {PeerId} peerId
* @returns {void}
*/
disconnect(peerId: import("peer-id")): void;
get [topologySymbol](): boolean;
}
declare namespace Topology {
export { Options, Handlers };
}
declare const topologySymbol: unique symbol;
type Options = {
/**
* - minimum needed connections.
*/
min?: number | undefined;
/**
* - maximum needed connections.
*/
max?: number | undefined;
handlers?: Handlers | undefined;
};
type Handlers = {
declare const _exports: Topology;
export = _exports;
export type PeerId = import("peer-id");
export type TopologyHandlers = {
/**
* - protocol "onConnect" handler
*/
onConnect?: Function | undefined;
onConnect?: (peerId: PeerId, conn: import('../connection')) => void;
/**
* - protocol "onDisconnect" handler
*/
onDisconnect?: Function | undefined;
onDisconnect?: (peerId: PeerId) => void;
};
export type TopologyOptions = {
/**
* - minimum needed connections
*/
min?: number;
/**
* - maximum needed connections
*/
max?: number;
handlers?: TopologyHandlers;
};
/**
* @typedef {import('peer-id')} PeerId
*/
/**
* @typedef {Object} TopologyHandlers
* @property {(peerId: PeerId, conn: import('../connection')) => void} [handlers.onConnect] - protocol "onConnect" handler
* @property {(peerId: PeerId) => void} [handlers.onDisconnect] - protocol "onDisconnect" handler
*
* @typedef {Object} TopologyOptions
* @property {number} [props.min = 0] - minimum needed connections
* @property {number} [props.max = Infinity] - maximum needed connections
* @property {TopologyHandlers} [props.handlers]
*/
declare class Topology {
/**
* @class
* @param {TopologyHandlers} options
*/
constructor({ min, max, handlers }: TopologyHandlers);
min: any;
max: any;
_onConnect: any;
_onDisconnect: any;
/**
* Set of peers that support the protocol.
*
* @type {Set<string>}
*/
peers: Set<string>;
set registrar(arg: any);
_registrar: any;
/**
* Notify about peer disconnected event.
*
* @param {PeerId} peerId
* @returns {void}
*/
disconnect(peerId: PeerId): void;
}

View File

@ -1,12 +1,27 @@
'use strict'
/* eslint-disable valid-jsdoc */
const withIs = require('class-is')
const noop = () => {}
const topologySymbol = Symbol.for('@libp2p/js-interfaces/topology')
/**
* @typedef {import('peer-id')} PeerId
*/
/**
* @typedef {Object} TopologyHandlers
* @property {(peerId: PeerId, conn: import('../connection')) => void} [handlers.onConnect] - protocol "onConnect" handler
* @property {(peerId: PeerId) => void} [handlers.onDisconnect] - protocol "onDisconnect" handler
*
* @typedef {Object} TopologyOptions
* @property {number} [props.min = 0] - minimum needed connections
* @property {number} [props.max = Infinity] - maximum needed connections
* @property {TopologyHandlers} [props.handlers]
*/
class Topology {
/**
* @param {Options} options
* @class
* @param {TopologyHandlers} options
*/
constructor ({
min = 0,
@ -22,40 +37,19 @@ class Topology {
/**
* Set of peers that support the protocol.
*
* @type {Set<string>}
*/
this.peers = new Set()
}
get [Symbol.toStringTag] () {
return 'Topology'
}
get [topologySymbol] () {
return true
}
/**
* Checks if the given value is a Topology instance.
*
* @param {any} other
* @returns {other is Topology}
*/
static isTopology (other) {
return Boolean(other && other[topologySymbol])
}
set registrar (registrar) {
set registrar (registrar) { // eslint-disable-line
this._registrar = registrar
}
/**
* @typedef PeerId
* @type {import('peer-id')}
*/
/**
* Notify about peer disconnected event.
*
* @param {PeerId} peerId
* @returns {void}
*/
@ -65,14 +59,7 @@ class Topology {
}
/**
* @typedef {Object} Options
* @property {number} [min=0] - minimum needed connections.
* @property {number} [max=Infinity] - maximum needed connections.
* @property {Handlers} [handlers]
*
* @typedef {Object} Handlers
* @property {Function} [onConnect] - protocol "onConnect" handler
* @property {Function} [onDisconnect] - protocol "onDisconnect" handler
* @module
* @type {Topology}
*/
module.exports = Topology
module.exports = withIs(Topology, { className: 'Topology', symbolName: '@libp2p/js-interfaces/topology' })

View File

@ -1,78 +1,41 @@
export = MulticodecTopology;
declare class MulticodecTopology extends Topology {
declare const _exports: MulticodecTopology;
export = _exports;
declare class MulticodecTopology {
/**
* Checks if the given value is a `MulticodecTopology` instance.
*
* @param {any} other
* @returns {other is MulticodecTopology}
* @class
* @param {import('./').TopologyOptions} options
*/
static isMulticodecTopology(other: any): other is MulticodecTopology;
/**
* @param {TopologyOptions & MulticodecOptions} props
*/
constructor({ min, max, multicodecs, handlers }: TopologyOptions & MulticodecOptions);
multicodecs: string[];
constructor({ min, max, handlers, multicodecs, }: import('./').TopologyOptions);
multicodecs: any[];
_registrar: any;
/**
* Check if a new peer support the multicodecs for this topology.
*
* @param {Object} props
* @param {PeerId} props.peerId
* @param {Array<string>} props.protocols
*/
_onProtocolChange({ peerId, protocols }: {
peerId: PeerId;
peerId: any;
protocols: Array<string>;
}): void;
/**
* Verify if a new connected peer has a topology multicodec and call _onConnect.
*
* @param {Connection} connection
* @returns {void}
*/
_onPeerConnect(connection: Connection): void;
_onPeerConnect(connection: any): void;
set registrar(arg: any);
/**
* Update topology.
*
* @param {Array<{id: PeerId, multiaddrs: Array<Multiaddr>, protocols: Array<string>}>} peerDataIterable
* @returns {void}
*/
_updatePeers(peerDataIterable: Array<{
id: PeerId;
multiaddrs: Array<Multiaddr>;
id: any;
multiaddrs: Array<any>;
protocols: Array<string>;
}>): void;
get [multicodecTopologySymbol](): boolean;
}
declare namespace MulticodecTopology {
export { PeerId, Multiaddr, Connection, TopologyOptions, MulticodecOptions, Handlers };
}
import Topology = require(".");
type PeerId = import("peer-id");
type Connection = typeof import("../connection");
type Multiaddr = import("multiaddr");
declare const multicodecTopologySymbol: unique symbol;
type TopologyOptions = {
/**
* - minimum needed connections.
*/
min?: number | undefined;
/**
* - maximum needed connections.
*/
max?: number | undefined;
handlers?: Topology.Handlers | undefined;
};
type MulticodecOptions = {
/**
* - protocol multicodecs
*/
multicodecs: string[];
handlers: Required<Handlers>;
};
type Handlers = {
/**
* - protocol "onConnect" handler
*/
onConnect?: Function | undefined;
/**
* - protocol "onDisconnect" handler
*/
onDisconnect?: Function | undefined;
};

View File

@ -1,18 +1,19 @@
'use strict'
/* eslint-disable valid-jsdoc */
const withIs = require('class-is')
const Topology = require('./index')
const multicodecTopologySymbol = Symbol.for('@libp2p/js-interfaces/topology/multicodec-topology')
class MulticodecTopology extends Topology {
/**
* @param {TopologyOptions & MulticodecOptions} props
* @class
* @param {import('./').TopologyOptions} options
*/
constructor ({
min,
max,
min = 0,
max = Infinity,
handlers = {},
multicodecs,
handlers
}) {
super({ min, max, handlers })
@ -39,25 +40,7 @@ class MulticodecTopology extends Topology {
this._onPeerConnect = this._onPeerConnect.bind(this)
}
get [Symbol.toStringTag] () {
return 'Topology'
}
get [multicodecTopologySymbol] () {
return true
}
/**
* Checks if the given value is a `MulticodecTopology` instance.
*
* @param {any} other
* @returns {other is MulticodecTopology}
*/
static isMulticodecTopology (other) {
return Boolean(other && other[multicodecTopologySymbol])
}
set registrar (registrar) {
set registrar (registrar) { // eslint-disable-line
this._registrar = registrar
this._registrar.peerStore.on('change:protocols', this._onProtocolChange)
this._registrar.connectionManager.on('peer:connect', this._onPeerConnect)
@ -68,6 +51,7 @@ class MulticodecTopology extends Topology {
/**
* Update topology.
*
* @param {Array<{id: PeerId, multiaddrs: Array<Multiaddr>, protocols: Array<string>}>} peerDataIterable
* @returns {void}
*/
@ -88,6 +72,7 @@ class MulticodecTopology extends Topology {
/**
* Check if a new peer support the multicodecs for this topology.
*
* @param {Object} props
* @param {PeerId} props.peerId
* @param {Array<string>} props.protocols
@ -113,11 +98,11 @@ class MulticodecTopology extends Topology {
/**
* Verify if a new connected peer has a topology multicodec and call _onConnect.
*
* @param {Connection} connection
* @returns {void}
*/
_onPeerConnect (connection) {
// @ts-ignore - remotePeer does not existist on Connection
const peerId = connection.remotePeer
const protocols = this._registrar.peerStore.protoBook.get(peerId)
@ -133,13 +118,7 @@ class MulticodecTopology extends Topology {
}
/**
* @typedef {import('peer-id')} PeerId
* @typedef {import('multiaddr')} Multiaddr
* @typedef {import('../connection')} Connection
* @typedef {import('.').Options} TopologyOptions
* @typedef {Object} MulticodecOptions
* @property {string[]} multicodecs - protocol multicodecs
* @property {Required<Handlers>} handlers
* @typedef {import('.').Handlers} Handlers
* @module
* @type {MulticodecTopology}
*/
module.exports = MulticodecTopology
module.exports = withIs(MulticodecTopology, { className: 'MulticodecTopology', symbolName: '@libp2p/js-interfaces/topology/multicodec-topology' })

View File

@ -4,8 +4,9 @@ module.exports = {
/**
* A tick is considered valid if it happened between now
* and `ms` milliseconds ago
* @param {number} date Time in ticks
* @param {number} ms max milliseconds that should have expired
*
* @param {number} date - Time in ticks
* @param {number} ms - max milliseconds that should have expired
* @returns {boolean}
*/
isValidTick: function isValidTick (date, ms = 5000) {

103
src/transport/types.ts Normal file
View File

@ -0,0 +1,103 @@
export default Transport;
declare class Transport implements TransportInterface {
constructor({ upgrader, ...others }: {
upgrader: Upgrader;
others: any;
});
/**
* Dial a given multiaddr.
* @param {Multiaddr} ma
* @param {Object} [options]
* @returns {Promise<Connection>}
*/
dial(ma: Multiaddr, options?: Object): Promise<Connection>;
/**
* Create transport listeners.
* @param {Object} options
* @param {(Connection) => void} handler
*/
createListener(options: Object, handler: Function): Listener;
/**
* Takes a list of `Multiaddr`s and returns only valid addresses for the transport
* @param {Multiaddr[]} multiaddrs
* @returns {Multiaddr[]}
*/
filter(multiaddrs: Multiaddr[]): Multiaddr[];
}
/**
* A libp2p transport is understood as something that offers a dial and listen interface to establish connections.
*/
interface TransportInterface {
/**
* Dial a given multiaddr.
* @param {Multiaddr} ma
* @param {Object} [options]
* @returns {Promise<Connection>}
*/
dial(ma: Multiaddr, options?: Object): Promise<Connection>;
/**
* Create transport listeners.
* @param {Object} options
* @param {(Connection) => void} handler
*/
createListener(options: Object, handler: Function): Listener;
/**
* Takes a list of `Multiaddr`s and returns only valid addresses for the transport
* @param {Multiaddr[]} multiaddrs
* @returns {Multiaddr[]}
*/
filter(multiaddrs: Multiaddr[]): Multiaddr[];
}
interface Listener {
/**
* Start a listener
* @param {Multiaddr} multiaddr
* @returns {Promise<void>}
*/
listen(multiaddr: Multiaddr): Promise<void>;
/**
* Get listen addresses
* @returns {Multiaddr[]}
*/
getAddrs(): Multiaddr[];
/**
* Close listener
* @returns {Promise<void>}
*/
close(): Promise<void>;
}
interface Upgrader {
/**
* Upgrades an outbound connection on `transport.dial`.
* @param {MultiaddrConnection} maConn
* @returns {Promise<Connection>}
*/
upgradeOutbound(maConn: MultiaddrConnection): Promise<Connection>;
/**
* Upgrades an inbound connection on transport listener.
* @param {MultiaddrConnection} maConn
* @returns {Promise<Connection>}
*/
upgradeInbound(maConn: MultiaddrConnection): Promise<Connection>;
}
type MultiaddrConnection = {
connection: any;
remoteAddr: Multiaddr;
sink: Sink;
source: () => AsyncIterator<Uint8Array, any, undefined>;
}
type Sink = (source: Uint8Array) => Promise<Uint8Array>;
type Connection = typeof import('../connection')
type Multiaddr = import('multiaddr');
declare namespace Transport {
export { Upgrader, Listener, MultiaddrConnection };
}

View File

@ -13,6 +13,7 @@ describe('compliance tests', () => {
/**
* Test setup. `properties` allows the compliance test to override
* certain values for testing.
*
* @param {*} properties
*/
async setup (properties) {

View File

@ -6,20 +6,6 @@
// Tells TypeScript to read JS files, as
// normally they are ignored as source files
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": false,
"noImplicitAny": false,
"noImplicitThis": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": false,
"strictFunctionTypes": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"strict": true,
"alwaysStrict": true,
"stripInternal": true,
// Generate d.ts files
"declaration": true,
// This compiler run should