Add readme
This commit is contained in:
parent
428852d619
commit
ee05704493
3
LICENSE
Normal file
3
LICENSE
Normal file
|
@ -0,0 +1,3 @@
|
|||
Licensed under CC BY-NC-SA 4.0.
|
||||
|
||||
To view a copy of this license, visit https://creativecommons.org/licenses/by-nc-sa/4.0/
|
147
README.md
147
README.md
|
@ -1,15 +1,146 @@
|
|||
# socket-speak
|
||||
# @endeavorance/socket
|
||||
|
||||
To install dependencies:
|
||||
Lightweight reconnecting websocket interface
|
||||
|
||||
```bash
|
||||
bun install
|
||||
## ManagedSocket
|
||||
|
||||
A self-reconnecting wrapped WebSocket with built-in heartbeats
|
||||
|
||||
### `new ManagedSocket(url: string): ManagedSocket`
|
||||
|
||||
Create a new `ManagedSocket` instance and connect to the provided URL via WebSocket.
|
||||
|
||||
The provided URL should use the `ws://` or `wss://` protocol.
|
||||
|
||||
```typescript
|
||||
import { ManagedSocket } from "@endeavorance/socket";
|
||||
|
||||
const mySocket = new ManagedSocket("wss://socket.my-server.web");
|
||||
```
|
||||
|
||||
To run:
|
||||
|
||||
```bash
|
||||
bun run src/index.ts
|
||||
### `.send<T>(data: T)`
|
||||
|
||||
Sends the provided data over the socket.
|
||||
|
||||
The data can be of any shaoe as long as it can be serialized (using `JSON.stringify` under the hood).
|
||||
|
||||
If `send()` is called on a `ManagedSocket` instance that is not currently connected, it will be enqueued to be sent once the connection is reestablished.
|
||||
|
||||
```typescript
|
||||
const mySocket = new ManagedSocket("...");
|
||||
mySocket.send("hello!");
|
||||
mySocket.send({
|
||||
command: "do-something",
|
||||
args: ["hello", "world"],
|
||||
});
|
||||
```
|
||||
|
||||
This project was created using `bun init` in bun v1.1.42. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
|
||||
### `.onMessage(handler: SocketDataHandler)`
|
||||
|
||||
Provide a function to invoke whenever the socket receives a message meant to be handled by your application.
|
||||
|
||||
This handler will be passed the blob of data contained within the message, which is typed as `unknown`.
|
||||
|
||||
Your handler function should parse the incoming data to ensure it is of the shape you expect.
|
||||
|
||||
```typescript
|
||||
const handler = (data: unknown) => {
|
||||
console.log("Got some data: " + data);
|
||||
}
|
||||
|
||||
const mySocket = new ManagedSocket("...");
|
||||
mySocket.onMessage(handler);
|
||||
```
|
||||
|
||||
### `.onError(handler: SocketErrorHandler)`
|
||||
|
||||
Provide a function to invoke when the socket encounters a non-catastrophic error.
|
||||
|
||||
Not catastrophic errors may occur during the lifecycle of the WebSocket connection, but are different from Catastrophic errors which only occur if the connection was terminated with a non-reconnect code.
|
||||
|
||||
This function will be passed a `ManagedSocketError`. If no error handler is set, errors will instead be thrown.
|
||||
|
||||
```typescript
|
||||
const errorHandler = (error: ManagedSocketError) => {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
const mySocket = new ManagedSocket("...");
|
||||
mySocket.onError(handler);
|
||||
```
|
||||
|
||||
### `.onCatastrophicError(handler: SocketCatastrophicErrorHandler)`
|
||||
|
||||
Provide a function to invoke when the socket is terminated with a non-reconnect code. When this handler is invoked, it means the socket connection is terminated and unable to be recovered automatically. Your handler will be passed the `SocketDisconnectCode` associated with the connection termination.
|
||||
|
||||
You may still attempt to manuall reconnect using the `.reconnect()` method, but it will not be automatic.
|
||||
|
||||
```typescript
|
||||
const bigOops = (code) => {
|
||||
console.error(`Welp, we're done here. Closed with code: ${code}`);
|
||||
}
|
||||
|
||||
const mySocket = new ManagedSocket("...");
|
||||
mySocket.onCatastrophicError(bigOops);
|
||||
```
|
||||
|
||||
### `.onOpen(SocketOpenHandler)`
|
||||
|
||||
Provide a function to be invoked when the connection is opened.
|
||||
|
||||
No arguments are provided to this handler.
|
||||
|
||||
### `.onClose(SocketCloseHandler)`
|
||||
|
||||
Provide a function to be invoked when the connection closes cleanly.
|
||||
|
||||
No arguments are provided to this handler.
|
||||
|
||||
### `.reconnect()`
|
||||
|
||||
Attempts to reconnect the socket using an exponential backoff algorithm. Each failed connection attempt will wait a bit longer before the next try.
|
||||
|
||||
### `.close()`
|
||||
|
||||
Safely close the socket connection.
|
||||
|
||||
## `SocketSpeak`
|
||||
|
||||
`SocketSpeak` is a set of utilities for working with the `ManagedSocket` data interface. It is lower-level and meant primarily for writing servers.
|
||||
|
||||
All methods are defined on the `SocketSpeak` object, exported by the library.
|
||||
|
||||
```typescript
|
||||
import { SocketSpeak } from "@endeavorance/socket"
|
||||
```
|
||||
|
||||
### `createDataMessage<T>(data: T): SocketDataMessage`
|
||||
|
||||
Wraps the provided data in a well formatted message ready to serialize and send over the socket.
|
||||
|
||||
A `SocketDataMessage` is used for sending application data over the socket.
|
||||
|
||||
### `createHeartbeatMessage(): SocketHeartbeatMessage`
|
||||
|
||||
Creates a well formatted heartbeat message to serialize and send over the socket.
|
||||
|
||||
A `SocketHeartbeatMessage` is used internally to keep the connection alive and carries a data payload of the current timestamp as a string.
|
||||
|
||||
### `serialize(message: SocketMessage): SerializedSocketMessage`
|
||||
|
||||
Serialize any `SocketMessage`. Returns a `SerializedSocketMessage` which is a branded `string` type for type safety.
|
||||
|
||||
### `deserialize(data: string): SocketMessage`
|
||||
|
||||
Attempts to deserialize the provided string into a `SocketMessage`. Throws a `ManagedSocketError` if the deserialization fails or the deserialized shape is invalid.
|
||||
|
||||
Note: This is not to deserialize your application data messages. The managed socket handles wrapping and unwrapping messages before handing the payload to your application.
|
||||
|
||||
### `prepare<T>(data: T)`
|
||||
|
||||
Shorthand for `serialize(createDataMessage(data))
|
||||
|
||||
### `isCatastrophicCloseCode(code: SocketCloseCode)`
|
||||
|
||||
Returns `true` if the provided `SocketCloseCode` is a non-reconnect close code, or `false` otherwise.
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@endeavorance/socket-speak",
|
||||
"name": "@endeavorance/socket",
|
||||
"description": "Lightweight reconnecting websocket interface",
|
||||
"version": "0.0.1",
|
||||
"exports": "./dist/index.js",
|
||||
|
|
|
@ -158,7 +158,7 @@ export class ManagedSocket {
|
|||
return this.ws;
|
||||
}
|
||||
|
||||
handleCatastrophicError(code: SocketDisconnectCode) {
|
||||
private handleCatastrophicError(code: SocketDisconnectCode) {
|
||||
this.state = "terminated";
|
||||
this.attemptReconnect = false;
|
||||
this.debugMessage(
|
||||
|
@ -182,18 +182,22 @@ export class ManagedSocket {
|
|||
this.onMessageHandler = handler;
|
||||
}
|
||||
|
||||
onError(handler: (error: ManagedSocketError) => void) {
|
||||
onError(handler: SocketErrorHandler) {
|
||||
this.onErrorHandler = handler;
|
||||
}
|
||||
|
||||
onOpen(handler: () => void) {
|
||||
onOpen(handler: SocketOpenHandler) {
|
||||
this.onOpenHandler = handler;
|
||||
}
|
||||
|
||||
onClose(handler: () => void) {
|
||||
onClose(handler: SocketCloseHandler) {
|
||||
this.onCloseHandler = handler;
|
||||
}
|
||||
|
||||
onCatastrophicError(handler: SocketCatastrophicErrorHandler) {
|
||||
this.onCatastrophicErrorHandler = handler;
|
||||
}
|
||||
|
||||
reconnect() {
|
||||
this.attemptReconnect = true;
|
||||
this.state = "reconnecting";
|
||||
|
|
Loading…
Reference in a new issue