# nanomessage

> Simple module that helps you to build a `request-response` abstraction on top of any other solution (e.g. streams).

Latest version **11.1.1** (published 2022-03-17) · MIT license · 0 weekly downloads

## Install

```sh
npm install nanomessage
pnpm add nanomessage
yarn add nanomessage
bun add nanomessage
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: esm support; no vulnerabilities.

Warnings: low downloads; no types.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 11.1.1 |
| Published | 2022-03-17 |
| First published | 2019-10-29 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM |
| Dependencies | 5 |
| Unpacked size | 21.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 8 |
| Author | GEUT |
| Maintainers | tinchoz49 |
| Keywords | nano, geut, request, request-response, websocket, socket, stream |

## Links

- npm: https://www.npmjs.com/package/nanomessage
- Repository: https://github.com/geut/nanomessage
- Homepage: https://github.com/geut/nanomessage#readme
- Issues: https://github.com/geut/nanomessage/issues
- npm.io page: https://npm.io/package/nanomessage

## Dependencies (5)

- [fastq](https://npm.io/package/fastq.md) ^1.8.0
- [varint](https://npm.io/package/varint.md) ^5.0.0
- [nanoerror](https://npm.io/package/nanoerror.md) ^1.1.0
- [nanocustomassert](https://npm.io/package/nanocustomassert.md) ^1.0.0
- [nanoresource-promise](https://npm.io/package/nanoresource-promise.md) ^3.0.3

## Alternatives

- [@opentelemetry/exporter-zipkin](https://npm.io/package/@opentelemetry/exporter-zipkin.md) — 14.8M weekly downloads
- [pusher-js](https://npm.io/package/pusher-js.md) — 2.0M weekly downloads
- [browserify](https://npm.io/package/browserify.md) — 1.7M weekly downloads
- [sqs-consumer](https://npm.io/package/sqs-consumer.md) — 1.7M weekly downloads
- [@sanity/eventsource](https://npm.io/package/@sanity/eventsource.md) — 930.8K weekly downloads

## Recent versions

- 11.1.1 (latest) — 2022-03-17
- 11.1.0 — 2022-03-17
- 11.0.3 — 2021-07-15
- 11.0.2 — 2021-07-05
- 11.0.1 — 2021-07-05
- 11.0.0 — 2021-07-02
- 10.1.0 — 2021-07-02
- 10.0.1 — 2021-06-30
- 10.0.0 — 2021-06-30
- 9.0.0 — 2021-05-12
- 8.4.0 — 2021-05-11
- 8.3.1 — 2021-02-04
- 8.3.0 — 2021-02-04
- 8.2.0 — 2020-08-06
- 8.1.2 — 2020-07-31
- … 27 more at https://npm.io/package/nanomessage/versions

## README

# nanomessage (aka nm)

[![Build Status](https://travis-ci.com/geut/nanomessage.svg?branch=master)](https://travis-ci.com/geut/nanomessage)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
[![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)

> Simple module that helps you to build a `request-response` abstraction on top of any other solution (e.g. streams).

## <a name="install"></a> Install

```
$ npm install nanomessage
```

## <a name="usage"></a> Usage

```javascript
import WebSocket from 'ws'

import { Nanomessage } from 'nanomessage'

// server.js
const server = new WebSocket.Server({ port: 3000 })
server.on('connection', function connection (ws) {
  const nm = new Nanomessage({
    subscribe (ondata) {
      // Define how to read data
      ws.on('message', ondata)
    },
    send (msg) {
      // Define how to send data
      ws.send(msg)
    },
    onMessage (msg, opts) {
      // Process the new request and return a response
      console.log(msg)
      return 'pong from Alice'
    }
  })

  nm.open().catch(err => console.error(err))
})

// client.js
const ws = new WebSocket('ws://127.0.0.1:3000')
const Bob = new Nanomessage({
  async open() {
    if (ws.readyState === 0) {
      await new Promise(resolve => ws.once('open', resolve))
    }
  },
  subscribe (ondata) {
    ws.on('message', ondata)
  },
  send (msg) {
    ws.send(msg)
  }
})

;(async () => {
  await Bob.open()
  console.log(await Bob.request('ping from Bob'))
})()
```

## <a name="api"></a> API

#### `const nm = new Nanomessage(options)`

Create a new nanomessage.

Options include:

- `send: (chunk: Buffer, info: Object) => (Promise|undefined)`: Defines how to send the messages provide it by nanomessage to the low level solution.
- `subscribe: (onData: buf => Promise) => UnsubscribeFunction`: Defines how to read data from the low level solution.
- `onMessage: (msg: *, info: Object) => Promise<Response>`: Async handler to process the incoming requests.
- `open: () => Promise`: Defines a function to run before the nanomessage instance is opened.
- `close: () => Promise`: Defines a function to run after the nanomessage instance was close.
- `timeout: null`: Time to wait for the response of a request. Disabled by default.
- `concurrency: { incoming: 256, outgoing: 256 }`: Defines how many requests do you want to run (outgoing) and process (incoming) in concurrent.
- `valueEncoding: buffer-json`: Defines a [compatible codec](https://github.com/mafintosh/codecs) to encode/decode messages in nanomessage.

`info` is an object with:

- `info.id: Number`: Incremental ID request.
- `info.data: *`: Plain data to send.
- `info.ephemeral: boolean`: It's true if the message is ephemeral.
- `info.response: boolean`: It's true if the message is a response.
- `info.responseData: *`: Plain data to response.

You can also extend from this prototype if you prefer:

```javascript
const { Nanomessage } = require('nanomessage')

class CustomNanomessage exports Nanomessage {
  constructor (...args) {
    super(...args)
  }

  _subscribe (onData) {}

  async _send (chunk, info) {}

  async _onMessage (msg, info) {}

  async _open() {
    await super._open()
  }

  async _close () {
    await super._close()
  }
}
```

#### `nm.requests: Array<Requests>`

Get the current list of requests (inflight and pending).

#### `nm.inflightRequests: Number`

Number of requests processing in the queue.

#### `nm.requestTimeout: Number`

Get the current request timeout.

#### `nm.concurrency: { incoming: Number, outgoing: Number }`

Get the current concurrency.

#### `nm.setRequestsTimeout(Number)`

Change the timeout for the future requests.

#### `nm.setConcurrency(Number | { incoming: Number, outgoing: Number })`

Update the concurrency number of operations for incoming and outgoing requests.

#### `nm.open() => Promise`

Opens nanomessage and start listening for incoming data.

#### `nm.close() => Promise`

Closes nanomessage and unsubscribe from incoming data.

#### `nm.request(data, [opts]) => Promise<Response>`

Send a request and wait for a response. `data` can be any serializable type supported by your codec.

- `opts.timeout: number`: Define a custom timeout for the current request.
- `opts.signal: AbortSignal`: Set an abort signal object to cancel the request.

#### `nm.send(data) => Promise<Response>`

Send a `ephemeral` message. `data` can be any serializable type supported by your codec.

#### `nm.processIncomingMessage(buf: Buffer) => Promise`

Access directly to the handler of incoming messages. It's recommended to use the subscription model instead.

#### `nm.setMessageHandler(handler) => Nanomessage`

Defines a request handler. It will override the old handler.

## <a name="issues"></a> Issues

:bug: If you found an issue we encourage you to report it on [github](https://github.com/geut/nanomessage/issues). Please specify your OS and the actions to reproduce it.

## <a name="contribute"></a> Contributing

:busts_in_silhouette: Ideas and contributions to the project are welcome. You must follow this [guideline](https://github.com/geut/nanomessage/blob/master/CONTRIBUTING.md).

## License

MIT © A [**GEUT**](http://geutstudio.com/) project

---
_Source: https://npm.io/package/nanomessage · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
