Skip to content
This repository was archived by the owner on Jul 21, 2023. It is now read-only.
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: libp2p/js-libp2p-mplex
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 4eb4d1e55430288e14b959db32c68ddb06fd86ac
Choose a base ref
...
head repository: libp2p/js-libp2p-mplex
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2a90b889344f32b41b86952845631f768626dc7b
Choose a head ref
  • 4 commits
  • 29 files changed
  • 3 contributors

Commits on Apr 12, 2019

  1. Copy the full SHA
    567bddf View commit details

Commits on Sep 18, 2019

  1. refactor: async iterators (#94)

    BREAKING CHANGE: All places in the API that used callbacks are now replaced with async/await while pull-streams are replaced with async iterators. The API has also been updated according to the latest `interface-stream-muxer` version, https://github.com/libp2p/interface-stream-muxer/tree/v0.7.0.
    
    License: MIT
    Signed-off-by: Alan Shaw <alan.shaw@protocol.ai>
    Alan Shaw authored and vasco-santos committed Sep 18, 2019
    Copy the full SHA
    c9bede5 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    2dff14d View commit details
  3. Copy the full SHA
    2a90b88 View commit details
Showing with 1,407 additions and 1,630 deletions.
  1. +0 −35 .aegir.js
  2. +3 −9 .gitignore
  3. +18 −0 CHANGELOG.md
  4. +117 −71 README.md
  5. +35 −14 examples/dialer.js
  6. +25 −18 examples/listener.js
  7. +18 −0 examples/util.js
  8. +23 −19 package.json
  9. +0 −3 src/codec.js
  10. +71 −0 src/coder/decode.js
  11. +54 −0 src/coder/encode.js
  12. +4 −0 src/coder/index.js
  13. +1 −27 src/index.js
  14. +0 −192 src/internals/channel.js
  15. +0 −477 src/internals/index.js
  16. +33 −0 src/message-types.js
  17. +213 −0 src/mplex.js
  18. +0 −108 src/muxer.js
  19. +32 −0 src/restrict-size.js
  20. +89 −0 src/stream.js
  21. +0 −43 test/browser.js
  22. +110 −0 test/coder.spec.js
  23. +3 −7 test/compliance.spec.js
  24. +0 −460 test/internals.node.js
  25. +0 −70 test/mplex.spec.js
  26. +0 −74 test/muxer.spec.js
  27. +0 −3 test/node.js
  28. +52 −0 test/restrict-size.spec.js
  29. +506 −0 test/stream.spec.js
35 changes: 0 additions & 35 deletions .aegir.js

This file was deleted.

12 changes: 3 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
node_modules
coverage
.nyc_output
package-lock.json
yarn.lock
docs

**/node_modules
**/*.log
test/setup/tmp-disposable-nodes-addrs.json
dist
coverage
**/*.swp
examples/sub-module/**/bundle.js
examples/sub-module/**/*-minified.js
examples/sub-module/*-bundle.js
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
<a name="0.9.0"></a>
# [0.9.0](https://github.com/libp2p/js-libp2p-mplex/compare/v0.8.5...v0.9.0) (2019-09-18)


### Code Refactoring

* async iterators ([#94](https://github.com/libp2p/js-libp2p-mplex/issues/94)) ([c9bede5](https://github.com/libp2p/js-libp2p-mplex/commit/c9bede5))


### BREAKING CHANGES

* All places in the API that used callbacks are now replaced with async/await while pull-streams are replaced with async iterators. The API has also been updated according to the latest `interface-stream-muxer` version, https://github.com/libp2p/interface-stream-muxer/tree/v0.7.0.

License: MIT
Signed-off-by: Alan Shaw <alan.shaw@protocol.ai>



<a name="0.8.5"></a>
## [0.8.5](https://github.com/libp2p/js-libp2p-mplex/compare/v0.8.4...v0.8.5) (2019-03-18)

188 changes: 117 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,110 +1,156 @@
js-libp2p-mplex
===================
# js-libp2p-mplex

[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://protocol.ai)
[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/)
[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p)
[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io)
[![](https://img.shields.io/codecov/c/github/libp2p/js-libp2p-mplex.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p-mplex)
[![](https://img.shields.io/travis/libp2p/js-libp2p-mplex.svg?style=flat-square)](https://travis-ci.com/libp2p/js-libp2p-mplex)
[![Dependency Status](https://david-dm.org/libp2p/js-libp2p-mplex.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-mplex)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard)
![](https://img.shields.io/badge/npm-%3E%3D6.0.0-orange.svg?style=flat-square)
![](https://img.shields.io/badge/Node.js-%3E%3D10.0.0-orange.svg?style=flat-square)

> JavaScript implementation of https://github.com/libp2p/mplex
> JavaScript implementation of [mplex](https://github.com/libp2p/specs/tree/master/mplex).
[![](https://github.com/libp2p/interface-stream-muxer/raw/master/img/badge.png)](https://github.com/libp2p/interface-stream-muxer)

## Lead Maintainer

[Vasco Santos](https://github.com/vasco-santos).
[Vasco Santos](https://github.com/vasco-santos)

## Install

```sh
npm install libp2p-mplex
```

## Usage

Let's define a `listener.js`, which starts a TCP server on port 9999 and waits for a connection. Once we get a connection, we wait for a stream. And finally, once we have the stream, we pull the data from that stream, and printing it to the console.

```JavaScript
const mplex = require('libp2p-mplex')
const tcp = require('net')
const pull = require('pull-stream')
const toPull = require('stream-to-pull-stream')

const listener = tcp.createServer((socket) => {
console.log('[listener] Got connection!')

const muxer = mplex.listener(toPull(socket))

muxer.on('stream', (stream) => {
console.log('[listener] Got stream!')
pull(
stream,
pull.drain((data) => {
console.log('[listener] Received:')
console.log(data.toString())
})
)
})
})
```js
const Mplex = require('libp2p-mplex')
const pipe = require('it-pipe')

listener.listen(9999, () => {
console.log('[listener] listening on 9999')
const muxer = new Mplex({
onStream: stream => { // Receive a duplex stream from the remote
// ...receive data from the remote and optionally send data back
}
})

pipe(conn, muxer, conn) // conn is duplex connection to another peer

const stream = muxer.newStream() // Create a new duplex stream to the remote

// Use the duplex stream to send some data to the remote...
pipe([1, 2, 3], stream)
```

Now, let's define `dialer.js` who will connect to our `listener` over a TCP socket. Once we have that, we'll put a message in the stream for our `listener`.
## API

```JavaScript
const mplex = require('libp2p-mplex')
const tcp = require('net')
const pull = require('pull-stream')
const toPull = require('stream-to-pull-stream')
### `const muxer = new Mplex([options])`

const socket = tcp.connect(9999)
Create a new _duplex_ stream that can be piped together with a connection in order to allow multiplexed communications.

const muxer = mplex.dialer(toPull(socket))
e.g.

console.log('[dialer] opening stream')
const stream = muxer.newStream((err) => {
console.log('[dialer] opened stream')
if (err) throw err
})
```js
const Mplex = require('libp2p-mplex')
const pipe = require('it-pipe')

pull(
pull.values(['hey, how is it going. I am the dialer']),
stream
)
// Create a duplex muxer
const muxer = new Mplex()

// Use the muxer in a pipeline
pipe(conn, muxer, conn) // conn is duplex connection to another peer
```

Now we can first run `listener.js` and then `dialer.js` to see the
following output:
`options` is an optional `Object` that may have the following properties:

* `onStream` - A function called when receiving a new stream from the remote. e.g.
```js
// Receive a new stream on the muxed connection
const onStream = stream => {
// Read from this stream and write back to it (echo server)
pipe(
stream,
source => (async function * () {
for await (const data of source) yield data
})(),
stream
)
}
const muxer = new Mplex({ onStream })
// ...
```
**Note:** The `onStream` function can be passed in place of the `options` object. i.e.
```js
new Mplex(stream => { /* ... */ })
```
* `signal` - An [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) which can be used to abort the muxer, _including_ all of it's multiplexed connections. e.g.
```js
const controller = new AbortController()
const muxer = new Mplex({ signal: controller.signal })

pipe(conn, muxer, conn)

controller.abort()
```
* `maxMsgSize` - The maximum size in bytes the data field of multiplexed messages may contain (default 1MB)

### `muxer.onStream`

Use this property as an alternative to passing `onStream` as an option to the `Mplex` constructor.

### `const stream = muxer.newStream([options])`

Initiate a new stream with the remote. Returns a [duplex stream](https://gist.github.com/alanshaw/591dc7dd54e4f99338a347ef568d6ee9#duplex-it).

e.g.

*listener.js*
```js
// Create a new stream on the muxed connection
const stream = muxer.newStream()

```
$ node listener.js
[listener] listening on 9999
[listener] Got connection!
[listener] Got stream!
[listener] Received:
hey, how is it going. I am the dialer
// Use this new stream like any other duplex stream:
pipe([1, 2, 3], stream, consume)
```

*dialer.js*
In addition to `sink` and `source` properties, this stream also has the following API, that will **normally _not_ be used by stream consumers**.

```
$ node dialer.js
[dialer] opening stream
[dialer] opened stream
```
#### `stream.close()`

## Install
Closes the stream for **reading**. If iterating over the source of this stream in a `for await of` loop, it will return (exit the loop) after any buffered data has been consumed.

```sh
> npm install libp2p-mplex
```
This function is called automatically by the muxer when it receives a `CLOSE` message from the remote.

## API
The source will return normally, the sink will continue to consume.

```js
const mplex = require('libp2p-mplex')
```
#### `stream.abort([err])`

Closes the stream for **reading** _and_ **writing**. This should be called when a _local error_ has occurred.

Note, if called without an error any buffered data in the source can still be consumed and the stream will end normally.

This will cause a `RESET` message to be sent to the remote, _unless_ the sink has already ended.

The sink will return and the source will throw if an error is passed or return normally if not.

#### `stream.reset()`

Closes the stream _immediately_ for **reading** _and_ **writing**. This should be called when a _remote error_ has occurred.

This function is called automatically by the muxer when it receives a `RESET` message from the remote.

The sink will return and the source will throw.

## Contribute

The libp2p implementation in JavaScript is a work in progress. As such, there are a few things you can do right now to help out:

- Go through the modules and **check out existing issues**. This is especially useful for modules in active development. Some knowledge of IPFS/libp2p may be required, as well as the infrastructure behind it - for instance, you may need to read up on p2p and more complex operations like muxing to be able to help technically.
- **Perform code reviews**. More eyes will help a) speed the project along b) ensure quality and c) reduce possible future bugs.
- **Add tests**. There can never be enough tests.

## License

[MIT](LICENSE) © Protocol Labs
49 changes: 35 additions & 14 deletions examples/dialer.js
Original file line number Diff line number Diff line change
@@ -2,21 +2,42 @@
'use strict'

const tcp = require('net')
const pull = require('pull-stream')
const toPull = require('stream-to-pull-stream')
const multiplex = require('../src')
const pipe = require('it-pipe')
const AbortController = require('abort-controller')
const { toIterable } = require('./util')
const Mplex = require('../src')

const socket = tcp.connect(9999)
const socket = toIterable(tcp.connect(9999))
console.log('[dialer] socket stream opened')

const muxer = multiplex.dialer(toPull(socket))
const controller = new AbortController()

console.log('[dialer] opening stream')
const stream = muxer.newStream((err) => {
console.log('[dialer] opened stream')
if (err) throw err
})
const muxer = new Mplex({ signal: controller.signal })

pull(
pull.values(['hey, how is it going. I am the dialer']),
stream
)
const pipeMuxerToSocket = async () => {
await pipe(muxer, socket, muxer)
console.log('[dialer] socket stream closed')
}

const sendAndReceive = async () => {
const muxedStream = muxer.newStream()
console.log('[dialer] muxed stream opened')

await pipe(
['hey, how is it going. I am the dialer'],
muxedStream,
async source => {
for await (const chunk of source) {
console.log('[dialer] received:')
console.log(chunk.toString())
}
}
)
console.log('[dialer] muxed stream closed')

// Close the socket stream after 1s
setTimeout(() => controller.abort(), 1000)
}

pipeMuxerToSocket()
sendAndReceive()
Loading