@libp2p/echo 0.0.0-cad9cf007
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +4 -0
- package/README.md +94 -0
- package/dist/index.min.js +3 -0
- package/dist/src/constants.d.ts +3 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +3 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/echo.d.ts +17 -0
- package/dist/src/echo.d.ts.map +1 -0
- package/dist/src/echo.js +39 -0
- package/dist/src/echo.js.map +1 -0
- package/dist/src/index.d.ts +60 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +48 -0
- package/dist/src/index.js.map +1 -0
- package/package.json +69 -0
- package/src/constants.ts +2 -0
- package/src/echo.ts +45 -0
- package/src/index.ts +67 -0
package/LICENSE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# @libp2p/echo
|
|
2
|
+
|
|
3
|
+
[](http://libp2p.io/)
|
|
4
|
+
[](https://discuss.libp2p.io)
|
|
5
|
+
[](https://codecov.io/gh/libp2p/js-libp2p)
|
|
6
|
+
[](https://github.com/libp2p/js-libp2p/actions/workflows/main.yml?query=branch%3Amain)
|
|
7
|
+
|
|
8
|
+
> Implementation of an Echo protocol
|
|
9
|
+
|
|
10
|
+
# About
|
|
11
|
+
|
|
12
|
+
<!--
|
|
13
|
+
|
|
14
|
+
!IMPORTANT!
|
|
15
|
+
|
|
16
|
+
Everything in this README between "# About" and "# Install" is automatically
|
|
17
|
+
generated and will be overwritten the next time the doc generator is run.
|
|
18
|
+
|
|
19
|
+
To make changes to this section, please update the @packageDocumentation section
|
|
20
|
+
of src/index.js or src/index.ts
|
|
21
|
+
|
|
22
|
+
To experiment with formatting, please run "npm run docs" from the root of this
|
|
23
|
+
repo and examine the changes made.
|
|
24
|
+
|
|
25
|
+
-->
|
|
26
|
+
|
|
27
|
+
An implementation of a simple Echo protocol.
|
|
28
|
+
|
|
29
|
+
Any data received by the receiver will be sent back to the sender.
|
|
30
|
+
|
|
31
|
+
## Example
|
|
32
|
+
|
|
33
|
+
```TypeScript
|
|
34
|
+
import { noise } from '@chainsafe/libp2p-noise'
|
|
35
|
+
import { yamux } from '@chainsafe/libp2p-yamux'
|
|
36
|
+
import { echo } from '@libp2p/echo'
|
|
37
|
+
import { peerIdFromString } from '@libp2p/peer-id'
|
|
38
|
+
import { createLibp2p } from 'libp2p'
|
|
39
|
+
|
|
40
|
+
const receiver = await createLibp2p({
|
|
41
|
+
addresses: {
|
|
42
|
+
listen: ['/ip4/0.0.0.0/tcp/0']
|
|
43
|
+
},
|
|
44
|
+
connectionEncryption: [noise()],
|
|
45
|
+
streamMuxers: [yamux()],
|
|
46
|
+
services: {
|
|
47
|
+
echo: echo()
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const sender = await createLibp2p({
|
|
52
|
+
addresses: {
|
|
53
|
+
listen: ['/ip4/0.0.0.0/tcp/0']
|
|
54
|
+
},
|
|
55
|
+
connectionEncryption: [noise()],
|
|
56
|
+
streamMuxers: [yamux()],
|
|
57
|
+
services: {
|
|
58
|
+
echo: echo()
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
const stream = await sender.dialProtocol(receiver.getMultiaddrs(), sender.services.echo.protocol)
|
|
63
|
+
|
|
64
|
+
// write/read stream
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
# Install
|
|
68
|
+
|
|
69
|
+
```console
|
|
70
|
+
$ npm i @libp2p/echo
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Browser `<script>` tag
|
|
74
|
+
|
|
75
|
+
Loading this module through a script tag will make it's exports available as `Libp2pEcho` in the global namespace.
|
|
76
|
+
|
|
77
|
+
```html
|
|
78
|
+
<script src="https://unpkg.com/@libp2p/echo/dist/index.min.js"></script>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
# API Docs
|
|
82
|
+
|
|
83
|
+
- <https://libp2p.github.io/js-libp2p/modules/_libp2p_echo.html>
|
|
84
|
+
|
|
85
|
+
# License
|
|
86
|
+
|
|
87
|
+
Licensed under either of
|
|
88
|
+
|
|
89
|
+
- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / <http://www.apache.org/licenses/LICENSE-2.0>)
|
|
90
|
+
- MIT ([LICENSE-MIT](LICENSE-MIT) / <http://opensource.org/licenses/MIT>)
|
|
91
|
+
|
|
92
|
+
# Contribution
|
|
93
|
+
|
|
94
|
+
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
(function (root, factory) {(typeof module === 'object' && module.exports) ? module.exports = factory() : root.Libp2PEcho = factory()}(typeof self !== 'undefined' ? self : this, function () {
|
|
2
|
+
"use strict";var Libp2PEcho=(()=>{var x=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var j=Object.prototype.hasOwnProperty;var V=(r,e)=>{for(var t in e)x(r,t,{get:e[t],enumerable:!0})},B=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of T(e))!j.call(r,s)&&s!==t&&x(r,s,{get:()=>e[s],enumerable:!(n=C(e,s))||n.enumerable});return r};var D=r=>B(x({},"__esModule",{value:!0}),r);var H={};V(H,{echo:()=>G});function d(){let r={};return r.promise=new Promise((e,t)=>{r.resolve=e,r.reject=t}),r}var p=class{buffer;mask;top;btm;next;constructor(e){if(!(e>0)||e-1&e)throw new Error("Max size for a FixedFIFO should be a power of two");this.buffer=new Array(e),this.mask=e-1,this.top=0,this.btm=0,this.next=null}push(e){return this.buffer[this.top]!==void 0?!1:(this.buffer[this.top]=e,this.top=this.top+1&this.mask,!0)}shift(){let e=this.buffer[this.btm];if(e!==void 0)return this.buffer[this.btm]=void 0,this.btm=this.btm+1&this.mask,e}isEmpty(){return this.buffer[this.btm]===void 0}},c=class{size;hwm;head;tail;constructor(e={}){this.hwm=e.splitLimit??16,this.head=new p(this.hwm),this.tail=this.head,this.size=0}calculateSize(e){return e?.byteLength!=null?e.byteLength:1}push(e){if(e?.value!=null&&(this.size+=this.calculateSize(e.value)),!this.head.push(e)){let t=this.head;this.head=t.next=new p(2*this.head.buffer.length),this.head.push(e)}}shift(){let e=this.tail.shift();if(e===void 0&&this.tail.next!=null){let t=this.tail.next;this.tail.next=null,this.tail=t,e=this.tail.shift()}return e?.value!=null&&(this.size-=this.calculateSize(e.value)),e}isEmpty(){return this.head.isEmpty()}};var g=class extends Error{type;code;constructor(e,t){super(e??"The operation was aborted"),this.type="aborted",this.code=t??"ABORT_ERR"}};function m(r={}){return U(t=>{let n=t.shift();if(n==null)return{done:!0};if(n.error!=null)throw n.error;return{done:n.done===!0,value:n.value}},r)}function U(r,e){e=e??{};let t=e.onEnd,n=new c,s,i,l,y=d(),z=async()=>{try{return n.isEmpty()?l?{done:!0}:await new Promise((o,u)=>{i=f=>{i=null,n.push(f);try{o(r(n))}catch(h){u(h)}return s}}):r(n)}finally{n.isEmpty()&&queueMicrotask(()=>{y.resolve(),y=d()})}},v=o=>i!=null?i(o):(n.push(o),s),R=o=>(n=new c,i!=null?i({error:o}):(n.push({error:o}),s)),O=o=>{if(l)return s;if(e?.objectMode!==!0&&o?.byteLength==null)throw new Error("objectMode was not true but tried to push non-Uint8Array value");return v({done:!1,value:o})},w=o=>l?s:(l=!0,o!=null?R(o):v({done:!0})),_=()=>(n=new c,w(),{done:!0}),A=o=>(w(o),{done:!0});if(s={[Symbol.asyncIterator](){return this},next:z,return:_,throw:A,push:O,end:w,get readableLength(){return n.size},onEmpty:async o=>{let u=o?.signal;if(u?.throwIfAborted(),n.isEmpty())return;let f,h;u!=null&&(f=new Promise((J,M)=>{h=()=>{M(new g)},u.addEventListener("abort",h)}));try{await Promise.race([y.promise,f])}finally{h!=null&&u!=null&&u?.removeEventListener("abort",h)}}},t==null)return s;let a=s;return s={[Symbol.asyncIterator](){return this},next(){return a.next()},throw(o){return a.throw(o),t!=null&&(t(o),t=void 0),{done:!0}},return(){return a.return(),t!=null&&(t(),t=void 0),{done:!0}},push:O,end(o){return a.end(o),t!=null&&(t(o),t=void 0),s},get readableLength(){return a.readableLength},onEmpty:o=>a.onEmpty(o)},s}function q(r){return r[Symbol.asyncIterator]!=null}function F(...r){let e=[];for(let t of r)q(t)||e.push(t);return e.length===r.length?function*(){for(let t of e)yield*t}():async function*(){let t=m({objectMode:!0});Promise.resolve().then(async()=>{try{await Promise.all(r.map(async n=>{for await(let s of n)t.push(s)})),t.end()}catch(n){t.end(n)}}),yield*t}()}var S=F;function I(r,...e){if(r==null)throw new Error("Empty pipeline");if(E(r)){let n=r;r=()=>n.source}else if(P(r)||L(r)){let n=r;r=()=>n}let t=[r,...e];if(t.length>1&&E(t[t.length-1])&&(t[t.length-1]=t[t.length-1].sink),t.length>2)for(let n=1;n<t.length-1;n++)E(t[n])&&(t[n]=$(t[n]));return W(...t)}var W=(...r)=>{let e;for(;r.length>0;)e=r.shift()(e);return e},L=r=>r?.[Symbol.asyncIterator]!=null,P=r=>r?.[Symbol.iterator]!=null,E=r=>r==null?!1:r.sink!=null&&r.source!=null,$=r=>e=>{let t=r.sink(e);if(t?.then!=null){let n=m({objectMode:!0});t.then(()=>{n.end()},l=>{n.end(l)});let s,i=r.source;if(L(i))s=async function*(){yield*i,n.end()};else if(P(i))s=function*(){yield*i,n.end()};else throw new Error("Unknown duplex source type - must be Iterable or AsyncIterable");return S(n,s())}return r.source};var k="1.0.0",N="echo";var b=class{protocol;components;started;init;log;constructor(e,t={}){this.log=e.logger.forComponent("libp2p:echo"),this.started=!1,this.components=e,this.protocol=`/${[t.protocolPrefix,N,k].filter(Boolean).join("/")}`,this.init=t}async start(){await this.components.registrar.handle(this.protocol,({stream:e})=>{I(e,e).catch(t=>{this.log.error("error piping stream",t)})},{maxInboundStreams:this.init.maxInboundStreams,maxOutboundStreams:this.init.maxOutboundStreams}),this.started=!0}async stop(){await this.components.registrar.unhandle(this.protocol),this.started=!1}isStarted(){return this.started}};function G(r={}){return e=>new b(e,r)}return D(H);})();
|
|
3
|
+
return Libp2PEcho}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,UAAU,CAAA;AACvC,eAAO,MAAM,aAAa,SAAS,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAA;AACvC,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Echo as EchoInterface, EchoComponents, EchoInit } from './index.js';
|
|
2
|
+
import type { Startable } from '@libp2p/interface';
|
|
3
|
+
/**
|
|
4
|
+
* A simple echo stream, any data received will be sent back to the sender
|
|
5
|
+
*/
|
|
6
|
+
export declare class Echo implements Startable, EchoInterface {
|
|
7
|
+
readonly protocol: string;
|
|
8
|
+
private readonly components;
|
|
9
|
+
private started;
|
|
10
|
+
private readonly init;
|
|
11
|
+
private readonly log;
|
|
12
|
+
constructor(components: EchoComponents, init?: EchoInit);
|
|
13
|
+
start(): Promise<void>;
|
|
14
|
+
stop(): Promise<void>;
|
|
15
|
+
isStarted(): boolean;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=echo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"echo.d.ts","sourceRoot":"","sources":["../../src/echo.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,IAAI,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACjF,OAAO,KAAK,EAAU,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAE1D;;GAEG;AACH,qBAAa,IAAK,YAAW,SAAS,EAAE,aAAa;IACnD,SAAgB,QAAQ,EAAE,MAAM,CAAA;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAC3C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAU;IAC/B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;gBAEf,UAAU,EAAE,cAAc,EAAE,IAAI,GAAE,QAAa;IAQtD,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;IAavB,IAAI,IAAK,OAAO,CAAC,IAAI,CAAC;IAK5B,SAAS,IAAK,OAAO;CAGtB"}
|
package/dist/src/echo.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { pipe } from 'it-pipe';
|
|
2
|
+
import { PROTOCOL_NAME, PROTOCOL_VERSION } from './constants.js';
|
|
3
|
+
/**
|
|
4
|
+
* A simple echo stream, any data received will be sent back to the sender
|
|
5
|
+
*/
|
|
6
|
+
export class Echo {
|
|
7
|
+
protocol;
|
|
8
|
+
components;
|
|
9
|
+
started;
|
|
10
|
+
init;
|
|
11
|
+
log;
|
|
12
|
+
constructor(components, init = {}) {
|
|
13
|
+
this.log = components.logger.forComponent('libp2p:echo');
|
|
14
|
+
this.started = false;
|
|
15
|
+
this.components = components;
|
|
16
|
+
this.protocol = `/${[init.protocolPrefix, PROTOCOL_NAME, PROTOCOL_VERSION].filter(Boolean).join('/')}`;
|
|
17
|
+
this.init = init;
|
|
18
|
+
}
|
|
19
|
+
async start() {
|
|
20
|
+
await this.components.registrar.handle(this.protocol, ({ stream }) => {
|
|
21
|
+
void pipe(stream, stream)
|
|
22
|
+
.catch((err) => {
|
|
23
|
+
this.log.error('error piping stream', err);
|
|
24
|
+
});
|
|
25
|
+
}, {
|
|
26
|
+
maxInboundStreams: this.init.maxInboundStreams,
|
|
27
|
+
maxOutboundStreams: this.init.maxOutboundStreams
|
|
28
|
+
});
|
|
29
|
+
this.started = true;
|
|
30
|
+
}
|
|
31
|
+
async stop() {
|
|
32
|
+
await this.components.registrar.unhandle(this.protocol);
|
|
33
|
+
this.started = false;
|
|
34
|
+
}
|
|
35
|
+
isStarted() {
|
|
36
|
+
return this.started;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=echo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"echo.js","sourceRoot":"","sources":["../../src/echo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAC9B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAIhE;;GAEG;AACH,MAAM,OAAO,IAAI;IACC,QAAQ,CAAQ;IACf,UAAU,CAAgB;IACnC,OAAO,CAAS;IACP,IAAI,CAAU;IACd,GAAG,CAAQ;IAE5B,YAAa,UAA0B,EAAE,OAAiB,EAAE;QAC1D,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAA;QACxD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QACpB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,aAAa,EAAE,gBAAgB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;QACtG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;YACnE,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;iBACtB,KAAK,CAAC,CAAC,GAAQ,EAAE,EAAE;gBAClB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAA;YAC5C,CAAC,CAAC,CAAA;QACN,CAAC,EAAE;YACD,iBAAiB,EAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB;YAC9C,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,kBAAkB;SACjD,CAAC,CAAA;QACF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;IACrB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACvD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;IACtB,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;CACF"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
*
|
|
4
|
+
* An implementation of a simple Echo protocol.
|
|
5
|
+
*
|
|
6
|
+
* Any data received by the receiver will be sent back to the sender.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
*
|
|
10
|
+
* ```TypeScript
|
|
11
|
+
* import { noise } from '@chainsafe/libp2p-noise'
|
|
12
|
+
* import { yamux } from '@chainsafe/libp2p-yamux'
|
|
13
|
+
* import { echo } from '@libp2p/echo'
|
|
14
|
+
* import { peerIdFromString } from '@libp2p/peer-id'
|
|
15
|
+
* import { createLibp2p } from 'libp2p'
|
|
16
|
+
*
|
|
17
|
+
* const receiver = await createLibp2p({
|
|
18
|
+
* addresses: {
|
|
19
|
+
* listen: ['/ip4/0.0.0.0/tcp/0']
|
|
20
|
+
* },
|
|
21
|
+
* connectionEncryption: [noise()],
|
|
22
|
+
* streamMuxers: [yamux()],
|
|
23
|
+
* services: {
|
|
24
|
+
* echo: echo()
|
|
25
|
+
* }
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* const sender = await createLibp2p({
|
|
29
|
+
* addresses: {
|
|
30
|
+
* listen: ['/ip4/0.0.0.0/tcp/0']
|
|
31
|
+
* },
|
|
32
|
+
* connectionEncryption: [noise()],
|
|
33
|
+
* streamMuxers: [yamux()],
|
|
34
|
+
* services: {
|
|
35
|
+
* echo: echo()
|
|
36
|
+
* }
|
|
37
|
+
* })
|
|
38
|
+
*
|
|
39
|
+
* const stream = await sender.dialProtocol(receiver.getMultiaddrs(), sender.services.echo.protocol)
|
|
40
|
+
*
|
|
41
|
+
* // write/read stream
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
import type { ComponentLogger } from '@libp2p/interface';
|
|
45
|
+
import type { ConnectionManager, Registrar } from '@libp2p/interface-internal';
|
|
46
|
+
export interface EchoInit {
|
|
47
|
+
protocolPrefix?: string;
|
|
48
|
+
maxInboundStreams?: number;
|
|
49
|
+
maxOutboundStreams?: number;
|
|
50
|
+
}
|
|
51
|
+
export interface EchoComponents {
|
|
52
|
+
registrar: Registrar;
|
|
53
|
+
connectionManager: ConnectionManager;
|
|
54
|
+
logger: ComponentLogger;
|
|
55
|
+
}
|
|
56
|
+
export interface Echo {
|
|
57
|
+
protocol: string;
|
|
58
|
+
}
|
|
59
|
+
export declare function echo(init?: EchoInit): (components: EchoComponents) => Echo;
|
|
60
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAE9E,MAAM,WAAW,QAAQ;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,SAAS,CAAA;IACpB,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,MAAM,EAAE,eAAe,CAAA;CACxB;AAED,MAAM,WAAW,IAAI;IACnB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,IAAI,CAAE,IAAI,GAAE,QAAa,GAAG,CAAC,UAAU,EAAE,cAAc,KAAK,IAAI,CAE/E"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
*
|
|
4
|
+
* An implementation of a simple Echo protocol.
|
|
5
|
+
*
|
|
6
|
+
* Any data received by the receiver will be sent back to the sender.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
*
|
|
10
|
+
* ```TypeScript
|
|
11
|
+
* import { noise } from '@chainsafe/libp2p-noise'
|
|
12
|
+
* import { yamux } from '@chainsafe/libp2p-yamux'
|
|
13
|
+
* import { echo } from '@libp2p/echo'
|
|
14
|
+
* import { peerIdFromString } from '@libp2p/peer-id'
|
|
15
|
+
* import { createLibp2p } from 'libp2p'
|
|
16
|
+
*
|
|
17
|
+
* const receiver = await createLibp2p({
|
|
18
|
+
* addresses: {
|
|
19
|
+
* listen: ['/ip4/0.0.0.0/tcp/0']
|
|
20
|
+
* },
|
|
21
|
+
* connectionEncryption: [noise()],
|
|
22
|
+
* streamMuxers: [yamux()],
|
|
23
|
+
* services: {
|
|
24
|
+
* echo: echo()
|
|
25
|
+
* }
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* const sender = await createLibp2p({
|
|
29
|
+
* addresses: {
|
|
30
|
+
* listen: ['/ip4/0.0.0.0/tcp/0']
|
|
31
|
+
* },
|
|
32
|
+
* connectionEncryption: [noise()],
|
|
33
|
+
* streamMuxers: [yamux()],
|
|
34
|
+
* services: {
|
|
35
|
+
* echo: echo()
|
|
36
|
+
* }
|
|
37
|
+
* })
|
|
38
|
+
*
|
|
39
|
+
* const stream = await sender.dialProtocol(receiver.getMultiaddrs(), sender.services.echo.protocol)
|
|
40
|
+
*
|
|
41
|
+
* // write/read stream
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
import { Echo as EchoClass } from './echo.js';
|
|
45
|
+
export function echo(init = {}) {
|
|
46
|
+
return (components) => new EchoClass(components, init);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,WAAW,CAAA;AAoB7C,MAAM,UAAU,IAAI,CAAE,OAAiB,EAAE;IACvC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;AACxD,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@libp2p/echo",
|
|
3
|
+
"version": "0.0.0-cad9cf007",
|
|
4
|
+
"description": "Implementation of an Echo protocol",
|
|
5
|
+
"license": "Apache-2.0 OR MIT",
|
|
6
|
+
"homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/protocol-echo#readme",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/libp2p/js-libp2p.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/libp2p/js-libp2p/issues"
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public",
|
|
16
|
+
"provenance": true
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"types": "./dist/src/index.d.ts",
|
|
20
|
+
"files": [
|
|
21
|
+
"src",
|
|
22
|
+
"dist",
|
|
23
|
+
"!dist/test",
|
|
24
|
+
"!**/*.tsbuildinfo"
|
|
25
|
+
],
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/src/index.d.ts",
|
|
29
|
+
"import": "./dist/src/index.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"eslintConfig": {
|
|
33
|
+
"extends": "ipfs",
|
|
34
|
+
"parserOptions": {
|
|
35
|
+
"project": true,
|
|
36
|
+
"sourceType": "module"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"start": "node dist/src/main.js",
|
|
41
|
+
"build": "aegir build",
|
|
42
|
+
"test": "aegir test",
|
|
43
|
+
"clean": "aegir clean",
|
|
44
|
+
"generate": "protons ./src/pb/index.proto",
|
|
45
|
+
"lint": "aegir lint",
|
|
46
|
+
"test:chrome": "aegir test -t browser --cov",
|
|
47
|
+
"test:chrome-webworker": "aegir test -t webworker",
|
|
48
|
+
"test:firefox": "aegir test -t browser -- --browser firefox",
|
|
49
|
+
"test:firefox-webworker": "aegir test -t webworker -- --browser firefox",
|
|
50
|
+
"test:node": "aegir test -t node --cov",
|
|
51
|
+
"dep-check": "aegir dep-check",
|
|
52
|
+
"doc-check": "aegir doc-check"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@libp2p/interface": "1.1.4-cad9cf007",
|
|
56
|
+
"@libp2p/interface-internal": "1.0.9-cad9cf007",
|
|
57
|
+
"it-pipe": "^3.0.1"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@libp2p/logger": "4.0.7-cad9cf007",
|
|
61
|
+
"aegir": "^42.2.4",
|
|
62
|
+
"it-all": "^3.0.4",
|
|
63
|
+
"it-pair": "^2.0.6",
|
|
64
|
+
"sinon": "^17.0.1",
|
|
65
|
+
"sinon-ts": "^2.0.0",
|
|
66
|
+
"uint8arraylist": "^2.4.8"
|
|
67
|
+
},
|
|
68
|
+
"sideEffects": false
|
|
69
|
+
}
|
package/src/constants.ts
ADDED
package/src/echo.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { pipe } from 'it-pipe'
|
|
2
|
+
import { PROTOCOL_NAME, PROTOCOL_VERSION } from './constants.js'
|
|
3
|
+
import type { Echo as EchoInterface, EchoComponents, EchoInit } from './index.js'
|
|
4
|
+
import type { Logger, Startable } from '@libp2p/interface'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A simple echo stream, any data received will be sent back to the sender
|
|
8
|
+
*/
|
|
9
|
+
export class Echo implements Startable, EchoInterface {
|
|
10
|
+
public readonly protocol: string
|
|
11
|
+
private readonly components: EchoComponents
|
|
12
|
+
private started: boolean
|
|
13
|
+
private readonly init: EchoInit
|
|
14
|
+
private readonly log: Logger
|
|
15
|
+
|
|
16
|
+
constructor (components: EchoComponents, init: EchoInit = {}) {
|
|
17
|
+
this.log = components.logger.forComponent('libp2p:echo')
|
|
18
|
+
this.started = false
|
|
19
|
+
this.components = components
|
|
20
|
+
this.protocol = `/${[init.protocolPrefix, PROTOCOL_NAME, PROTOCOL_VERSION].filter(Boolean).join('/')}`
|
|
21
|
+
this.init = init
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async start (): Promise<void> {
|
|
25
|
+
await this.components.registrar.handle(this.protocol, ({ stream }) => {
|
|
26
|
+
void pipe(stream, stream)
|
|
27
|
+
.catch((err: any) => {
|
|
28
|
+
this.log.error('error piping stream', err)
|
|
29
|
+
})
|
|
30
|
+
}, {
|
|
31
|
+
maxInboundStreams: this.init.maxInboundStreams,
|
|
32
|
+
maxOutboundStreams: this.init.maxOutboundStreams
|
|
33
|
+
})
|
|
34
|
+
this.started = true
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async stop (): Promise<void> {
|
|
38
|
+
await this.components.registrar.unhandle(this.protocol)
|
|
39
|
+
this.started = false
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
isStarted (): boolean {
|
|
43
|
+
return this.started
|
|
44
|
+
}
|
|
45
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
*
|
|
4
|
+
* An implementation of a simple Echo protocol.
|
|
5
|
+
*
|
|
6
|
+
* Any data received by the receiver will be sent back to the sender.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
*
|
|
10
|
+
* ```TypeScript
|
|
11
|
+
* import { noise } from '@chainsafe/libp2p-noise'
|
|
12
|
+
* import { yamux } from '@chainsafe/libp2p-yamux'
|
|
13
|
+
* import { echo } from '@libp2p/echo'
|
|
14
|
+
* import { peerIdFromString } from '@libp2p/peer-id'
|
|
15
|
+
* import { createLibp2p } from 'libp2p'
|
|
16
|
+
*
|
|
17
|
+
* const receiver = await createLibp2p({
|
|
18
|
+
* addresses: {
|
|
19
|
+
* listen: ['/ip4/0.0.0.0/tcp/0']
|
|
20
|
+
* },
|
|
21
|
+
* connectionEncryption: [noise()],
|
|
22
|
+
* streamMuxers: [yamux()],
|
|
23
|
+
* services: {
|
|
24
|
+
* echo: echo()
|
|
25
|
+
* }
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* const sender = await createLibp2p({
|
|
29
|
+
* addresses: {
|
|
30
|
+
* listen: ['/ip4/0.0.0.0/tcp/0']
|
|
31
|
+
* },
|
|
32
|
+
* connectionEncryption: [noise()],
|
|
33
|
+
* streamMuxers: [yamux()],
|
|
34
|
+
* services: {
|
|
35
|
+
* echo: echo()
|
|
36
|
+
* }
|
|
37
|
+
* })
|
|
38
|
+
*
|
|
39
|
+
* const stream = await sender.dialProtocol(receiver.getMultiaddrs(), sender.services.echo.protocol)
|
|
40
|
+
*
|
|
41
|
+
* // write/read stream
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
import { Echo as EchoClass } from './echo.js'
|
|
46
|
+
import type { ComponentLogger } from '@libp2p/interface'
|
|
47
|
+
import type { ConnectionManager, Registrar } from '@libp2p/interface-internal'
|
|
48
|
+
|
|
49
|
+
export interface EchoInit {
|
|
50
|
+
protocolPrefix?: string
|
|
51
|
+
maxInboundStreams?: number
|
|
52
|
+
maxOutboundStreams?: number
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface EchoComponents {
|
|
56
|
+
registrar: Registrar
|
|
57
|
+
connectionManager: ConnectionManager
|
|
58
|
+
logger: ComponentLogger
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface Echo {
|
|
62
|
+
protocol: string
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function echo (init: EchoInit = {}): (components: EchoComponents) => Echo {
|
|
66
|
+
return (components) => new EchoClass(components, init)
|
|
67
|
+
}
|