From f2e537688201673302a72e782098060bd6f8962d Mon Sep 17 00:00:00 2001 From: Artem Zakharchenko Date: Sun, 24 Mar 2024 14:56:51 +0100 Subject: [PATCH] docs: write api docs for websocket --- README.md | 137 ++++++++++++++++++++++++++---------------------------- 1 file changed, 65 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index 5171219b..f8987b9f 100644 --- a/README.md +++ b/README.md @@ -315,121 +315,114 @@ intereceptor.on('connection', ({ client }) => { The `connection` event exposes the following arguments: -| Name | Type | Description | -| -------- | -------- | ---------------------------------------------------------------- | -| `client` | `object` | An object representing a connected WebSocket client instance. | -| `server` | `object` | An object representing the original WebSocket server connection. | +| Name | Type | Description | +| -------- | --------------------------------------------------------- | ---------------------------------------------------------------- | +| `client` | [`WebSocketClientConnection`](#websocketclientconnection) | An object representing a connected WebSocket client instance. | +| `server` | [`WebSocketServerConnection`](#websocketserverconnection) | An object representing the original WebSocket server connection. | -### Intercepting outgoing client events +### `WebSocketClientConnection` -To intercept an event sent by the WebSocket client, add a `message` listener to the `client` object. +#### `.addEventListener(type, listener)` -```js -interceptor.on('connection', ({ client }) => { - // Intercept all outgoing events from the client. - client.addEventListener('message', (event) => { - console.log('received:', event.data) - }) -}) -``` +- `type`, `"message"` +- `listener`, `(event: MessageEvent) => void` -### Mocking incoming server events +Adds an event listener to the given event type of the WebSocket client. -To mock an event sent from the server to the client, call `client.send()` with the event payload. +| Event name | Description | +| ---------- | ----------------------------------------------------------------- | +| `message` | Dispatched when data is sent by the intercepted WebSocket client. | ```js -interceptor.on('connection', ({ client }) => { - // Send a mocked "MessageEvent" to the client - // with the given "hello" string as the data. - client.send('hello') +client.addEventListener('message', (event) => { + console.log('outgoing:', event.data) }) ``` -> The WebSocket interceptor respects the [WebSocket WHATWG standard](https://websockets.spec.whatwg.org/) and supports sending all supported data types (string, Blob, ArrayBuffer, etc). +#### `.removeEventListener(type, listener)` -### Bypassing events +- `type`, `"message"` +- `listener`, `(event: MessageEvent) => void` -By default, the WebSocket interceptor **prevents all the outgoing client events from hitting the production server**. This is a sensible default to support mocking a WebSocket communication when a WebSocket server doesn't exist. +Removes the listener for the given event type. -To bypass an event, first establish the actual server connection by calling `server.connect()`, and then call `server.send()` with the data you wish to forward to the original server. +#### `.send(data)` -```js -interceptor.on('connection', ({ client, server }) => { - // First, connect to the original server. - server.connect() +- `data`, `string | Blob | ArrayBuffer` - // Forward all outgoing client events to the original server. - client.addEventListener('message', (event) => server.send(event.data)) -}) +Sends the data to the intercepted WebSocket client. + +```js +client.send('text') +client.send(new Blob(['blob'])) +client.send(new TextEncoder().encode('array buffer')) ``` -### Intercepting incoming server events +#### `.close(code, reason)` -The WebSocket communication is duplex and the WebSocket interceptor allows you to intercept both outgoing (client) events and incoming (original server) events. +- `code`, close [status code](https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1). +- `reason`, [close reason](https://www.rfc-editor.org/rfc/rfc6455#section-7.1.6). -To intercept an incoming event from the original server, first establish the original connection by calling `server.connect()`, and then add a `message` listener to the `server` object. +Closes the client connection. Unlike the regular `WebSocket.prototype.close()`, the `client.close()` method can accept a non-configurable status codes, such as 1001, 1003, etc. ```js -interceptor.on('connection', ({ server }) => { - server.connect() +// Gracefully close the connection with the +// intercepted WebSocket client. +client.close() +``` - server.addEventListener('message', (event) => { - console.log('original server sent:', event.data) - }) -}) +```js +// Terminate the connection by emulating +// the server unable to process the received data. +client.close(1003) ``` -Unlike the outgoing client events, incoming server events **are automatically forwarded to the client as soon as you call `server.connect()`**. This keeps the original server connection authentic if you ever decide to open one. +### `WebSocketServerConnection` -If you wish to prevent the automatic forwarding of the server events to the client, call `event.preventDefault()` on the incoming event you wish to prevent. This can be handy for observing as well as modifying incoming events. +#### `.connect()` -```js -interceptor.on('connection', ({ client, server }) => { - server.connect() +Establishes the connection to the original WebSocket server. Connection cannot be awaited. Any data sent via `server.send()` while connecting is buffered and flushed once the connection is open. - server.addEventListener('message', (event) => { - if (event.data === 'hello from server') { - // Never forward this event to the client. - event.preventDefault() +#### `.addEventListener(type, listener)` - // Instead, send this mock data. - client.send('greetings, client') - return - } - }) -}) -``` +- `type`, `"message"` +- `listener`, `(event: MessageEvent) => void` -### Closing the connection +Adds an event listener to the given event type of the WebSocket server. -You can terminate the open WebSocket client connection by calling `client.close()`. +| Event name | Description | +| ---------- | -------------------------------------------------------------------- | +| `message` | Dispatched when data is received from the original WebSocket server. | ```js -interceptor.on('connection', ({ client }) => { - client.close() +server.addEventListener('message', (event) => { + console.log('incoming:', event.data) }) ``` -By default, this will close the connection with the `1000` code, meaning a graceful disconnect. +#### `.removeEventListener(type, listener)` -You can provide a custom close [Status code](https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1) and [Close reason](https://www.rfc-editor.org/rfc/rfc6455#section-7.1.6) to the `client.close()` to mock different connection close scenarios. +- `type`, `"message"` +- `listener`, `(event: MessageEvent) => void` -```js -interceptor.on('connection', ({ client }) => { - client.close(3000, 'Close reason') -}) -``` +Removes the listener for the given event type. + +#### `.send(data)` + +- `data`, `string | Blob | ArrayBuffer` -You can also close the connection with the termination status code (1001 - 1015), which are not configurable by the user otherwise. +Sends the data to the original WebSocket server. Useful in a combination with the client-sent events forwarding: ```js -interceptor.on('connection', ({ client }) => { - // Terminate the connection because the "server" - // cannot accept the data sent from the client. - client.close(1003) +client.addEventListener('message', (event) => { + server.send(event.data) }) ``` +#### `.close()` + +Closes the connection with the original WebSocket server. Unlike `client.close()`, closing the server connection does not accept any arguments and always asumes a graceful closure. Sending data via `server.send()` after the connection has been closed will have no effect. + ## API ### `Interceptor`