@electrum-cash/web-socket
Electrum-Cash Web Socket
This package provides a configurable ElectrumSocket that works in both NodeJS and browser settings, with consistent behavior across various environments by default.
Features
the ElectrumSocket is a wrapper for a WebSocket with the following added features:
- Has promise-based and idempotent interfaces.
- Uses the
debugpackage for configurable logging levels. - Initial connections time out rather than linger in a stalled state.
- Can automatically suspend to save battery based on browser visibility and connectivity.
Usage
Imports
Before using this package, you need to import it:
import { ElectrumWebSocket } from '@electrum-cash/web-socket';
To properly handle all possible errors, also import the custom error types:
import type {
SocketInternalError,
SocketTimeoutError,
SocketConnectionError,
SocketWriteError,
} from '@electrum-cash/web-socket`;
Creating an ElectrumWebSocket
First, create an instance of the socket with:
// Create the web socket with default behavior.
const socket = new ElectrumWebSocket('hostNameOrIPNumber');
Alternatively, you can configure the socket behavior by providing one or more options:
// Optionally configure socket behavior with one or more of the ElectrumSocketOptions properties.
const options =
{
enforceConsistentBrowserBehavior: false,
}
// Create the web socket with customized behavior.
const socket = new ElectrumWebSocket('hostNameOrIPNumber', options);
Connecting to the host
After you have created an ElectrumWebSocket, you can connect with the host:
await socket.connect();
Disconnecting from a host
When you no longer need the ElectrumWebSocket, you can disconnect from the host:
await socket.disconnect();
Sending messages
While connected, you can send messages with:
await socket.write('YourTextMessageHere');
Receiving messages
To receive messages from the socket, listen to the data emitted events.
// Set up handler for incoming data.
const onSocketData = async function(data: string)
{
console.log(data);
}
// Register handler for incoming data.
socket.addEventListener('data', onSocketData);
Managing connection
The socket also emits connected and disconnected event over its lifetime:
// Signal indicating that the socket has connected.
socket.addEventListener('connected', onSocketConnected);
// Signal indicating that the socket has disconnected.
socket.addEventListener('disconnected', onSocketDisconnected);
Handling errors
When connecting the socket, you might get a promise rejection containing an error:
try
{
await socket.connect();
}
catch (error)
{
// Internal errors are bugs in the implementation, simply log and move on.
if(error instanceof SocketInternalError)
{
console.error(error);
}
// Timeout during connection could be network or host problems, try again later?
if(error instanceof SocketTimeoutError)
{
// Code to try again later
}
// Connection errors range from being something you can handle, to things outside of your control.
if(error instanceof SocketConnectionError)
{
// Inspect error.message for more details, or just log, like this:
console.error(error);
}
}
When writing to the socket, you might get a promise rejection containing an error:
try
{
await socket.write('message');
}
catch (error)
{
// Internal errors are bugs in the implementation, simply log and move on.
if(error instanceof SocketInternalError)
{
console.error(error);
}
// Write errors means the data was not sent, so maybe try again later?
if(error instanceof SocketWriteError)
{
// Code to try again later
}
}
Change Log
v4.0
Safety
- The following calls are now idempotent:
connect(),disconnect(),write(). - The following calls now return a promise that resolves or reject when the action is completed:
connect(),disconnect(). - The following calls are now safe to use concurrently:
connect(),disconnect(),write(). - There is now four new custom errors:
SocketInternalError,SocketTimeoutError,SocketConnectionErrorandSocketWriteError - Event listeners are now assigned in only one place, and ensured not to create duplicates.
- Added edge-case and error handling tests.
- Added @throws to all calls that can throw.
Features
- There is now four new utility functions to return current state:
isConnecting(),isConnected(),isDisconnectingandisDisconnected. - Self-signed certificates are now allowed when
enforceBrowserConsistencyis set tofalse, and running in a non-browser environment.
Cleanups
- removed
errorevents as these are now handled with promise rejections. - removed support for sending
Uint8Arrays, as the electrum protocol only sends strings.
v1.2
- Handle browser visibilty and connectivity events consistently.
- Added basic happy-path tests.
v1.1
- Changed library bundler to tsdown
v1.0
- Initial release