# @teamwork/websocket-json-stream

> Expose WebSockets with JSON as an object stream.

Latest version **2.0.0** (published 2019-03-05) · MIT license · 0 weekly downloads

## Install

```sh
npm install @teamwork/websocket-json-stream
pnpm add @teamwork/websocket-json-stream
yarn add @teamwork/websocket-json-stream
bun add @teamwork/websocket-json-stream
```

## Health

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

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.0.0 |
| Published | 2019-03-05 |
| First published | 2018-06-01 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 39.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Greg Kubisa |
| Maintainers | 0xor1, 1001hz, 4ver, abiosoft, adam-lynch, adriankelly, aetheon, aislingmor, aldercass, alexorteamwork, aodhom, arielpiecha-teamwork, bakaat, bmckay397, brendonald, c0mpressi0n, cbrohan-tw, cesartw, cianwoods, conorhiggins, daveohalloran, davidcannon, dawidmyslak, deejaytc, dmackey, dommurphytw, duncan1a, eamonnmg, eamonnmurphy, elgutierrez, emmetcampion, eointw, felipemrodrigues, felixls, gangleri, garycremen, gkubisa, gordonmurray, hollymc, hyxnat, i.dobrovolskyi, irltopper, jacknev, jamesdraper5, jasoncheung94, jatochnietdan, jessicaaferraz, jjog1, joansentisteamwork, jordanteamwork, jrdtw, keli711, kersh, l-campbell, lmel, lukeslattry, lussher, mabo89, mark-tw, matcmd, matt.savage, matteobandiera, miccc, michaelgallaghertw, michaelwebcork, michellemcgint, miguelbemartin, mike182uk, miralize, mjteamwork, morethanaprogrammer, myspotontheweb, nasheor, neayto, niall.ferguson, nmrshll, otherview, pshad0w, rafaeljusto, ripexz, rokasmikas, roryok, ryanlync, samternent, shanepm, shaydoc75, sheyla.marhuenda, sineadcullinane, smithalan2, smusick, stdiopt, steve.walsh, stevenadams, teamwork-dev, techfort, tgracchus, thegreyham, toffentoffen, trajber, yannig, yawlhead91 |
| Keywords | stream, websocket |

## Links

- npm: https://www.npmjs.com/package/@teamwork/websocket-json-stream
- Repository: https://github.com/teamwork/websocket-json-stream
- Homepage: https://github.com/teamwork/websocket-json-stream#readme
- Issues: https://github.com/teamwork/websocket-json-stream/issues
- npm.io page: https://npm.io/package/@teamwork/websocket-json-stream

## 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

- 2.0.0 (latest) — 2019-03-05
- 1.1.1 — 2018-11-05
- 1.1.0 — 2018-07-26
- 1.0.0 — 2018-06-01

## README

# WebSocketJSONStream

[![npm version](https://badge.fury.io/js/%40teamwork%2Fwebsocket-json-stream.svg)](https://badge.fury.io/js/%40teamwork%2Fwebsocket-json-stream)
[![Build Status](https://travis-ci.org/Teamwork/websocket-json-stream.svg?branch=master)](https://travis-ci.org/Teamwork/websocket-json-stream)
[![Coverage Status](https://coveralls.io/repos/github/Teamwork/websocket-json-stream/badge.svg)](https://coveralls.io/github/Teamwork/websocket-json-stream)

A nodejs stream wrapper for WebSocket connections. It works with browser WebSockets too.

## Usage

```js
const WebSocket = require('ws')
const WebSocketJSONStream = require('@teamwork/websocket-json-stream')

const stream = new WebSocketJSONStream(new WebSocket(url))
// ...

new WebSocket.Server({ server }).on('connection', ws => {
    const stream = new WebSocketJSONStream(ws)
    // ...
})
```

See [example.js](./example.js) for a working usage example.

## Error Handling

WebSocket error events are not handled by this module, so you should handle them yourself to avoid crashing the process unnecessarily in nodejs.

When writing to a stream when its associated WebSocket is already CLOSING or CLOSED, the stream emits an error event with the `name` property value equal to `Error [ERR_CLOSED]`.

## Closing a WebSocket via its stream

Calling [`stream.end()`](https://nodejs.org/api/stream.html#stream_writable_end_chunk_encoding_callback) or [`stream.destroy()`](https://nodejs.org/api/stream.html#stream_writable_destroy_error) will close the WebSocket connection.

When a WebSocket is closed either by the server or the client, a [`CloseEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent) will be emitted. CloseEvents have both a numeric `code` and a string `reason` property that may be used to indicate the type of closure.

### `stream.end()`

Calling `stream.end()` will close the WebSocket with the code `1000` and reason `'stream end'`. `1000` indicates a normal closure, meaning that the purpose for which the connection was established has been fulfilled. (https://tools.ietf.org/html/rfc6455#section-7.4.1)

Clients may implement this to mean that the server is closing the stream intentionally, and the client should not automatically reconnect.

```javascript
const stream = new WebSocketJSONStream(ws)
// Closes WebSocket with the code 1000 and the reason 'stream end'
stream.end()
```

The code `1000` may also be used when calling the [`webSocket.close(code)`](https://html.spec.whatwg.org/multipage/web-sockets.html#dom-websocket-close) method of WebSockets in browsers.

### `stream.destroy()`

Calling `stream.destroy()` without an error object will close the stream without a code. This results in the client emitting a CloseEvent that has code `1005` and reason `''`. `1005` is a reserved value and MUST NOT be set as a status code in a Close control frame by an endpoint. It is designated for use in applications expecting a status code to indicate that no status code was actually present. (https://tools.ietf.org/html/rfc6455#section-7.4.1)

```javascript
const stream = new WebSocketJSONStream(ws)
// Closes WebSocket with no status code (1005) and the reason ''
stream.destroy()
```

Calling `webSocket.close()` method of WebSockets in browsers without any arguments will produce a CloseEvent with the code `1005`. A reason string cannot be provided together with the code `1005`.

### `stream.destroy(error)`

Calling `stream.destroy(error)` with an error will emit an `'error'` event and close the stream with the code `1011` and reason `'stream error'` by default. `1011` indicates that a remote endpoint is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request. (http://www.rfc-editor.org/errata_search.php?eid=3227)

```javascript
const stream = new WebSocketJSONStream(ws)
stream.on('error', (error) => {
  // Error event must be handled, or it will be throw when calling
  // stream.destroy() with an error argument
})

// Closes WebSocket with the code 1011 and the reason 'stream error'
const error = new Error('Unexpected server error')
stream.destroy(error)
```

The code `1011` cannot be used when calling the `webSocket.close(code)` method of WebSockets in browsers.

### `error.closeCode` and `error.closeReason`

Custom close code and reason values may be sent by setting `error.closeCode` or `error.closeReason` properties on the error argument passed to `stream.destroy(error)`. For example:

```javascript
const stream = new WebSocketJSONStream(ws)
stream.on('error', (error) => {
  // Error event must be handled, or it will be throw when calling
  // stream.destroy() with an error argument
})

// Example of extending from Error and adding additional properties
class CustomStreamError extends Error {
    constructor(message) {
        super(message)
        this.name = this.constructor.name
        Error.captureStackTrace(this, this.constructor)
        this.closeCode = null
        this.closeReason = null
    }
}

// Closes WebSocket with the code 4000 and the reason 'custom reason'.
// error.message is not sent to the client
const error = new CustomStreamError('Example error')
error.closeCode = 4000
error.closeReason = 'custom reason'
stream.destroy(error)
```

Browser WebSockets allow custom close codes between 3000 and 4999.

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