npm package: @seamos/websocket
Description: Simple WebSocket utilities for SeamOS (JavaScript only)
Author: Sungmin Cho
Latest version: 0.1.3

# @seamos/websocket

Small, dependency-free helpers that wrap the browser `WebSocket` with auto reconnect, dynamic port selection (manual or CCU-provided), and JSON-friendly utilities. Ships as both ESM and CommonJS bundles for seamless use in modern build pipelines.

## Features

- Create resilient sockets that retry after unexpected disconnects
- Resolve ports manually or by querying a CCU endpoint with automatic fallback
- Hook into all native WebSocket events without re-writing boilerplate
- Send JSON payloads safely and close sockets defensively
- Written in plain JavaScript so it runs anywhere a browser-like `WebSocket` exists

## Installation

```bash
npm install @seamos/websocket
```

## Quick Start

### Manual Port Connection

```js
import {
  createWebSocketClient,
  sendJson,
  closeWebSocketSafe,
} from '@seamos/websocket';

const client = createWebSocketClient('ws://192.168.0.10/socket', {
  useCCUPort: false,
  manualPort: 8080,
  autoReconnect: true,
  reconnectInterval: 3000,
  events: {
    open: () => console.log('connected'),
    message: (event) => console.log('message', event.data),
    close: () => console.log('socket closed'),
  },
});

sendJson(client.socket, { type: 'ping' });
closeWebSocketSafe(client.socket, 1000, 'done');
```

### CCU-Based Port Resolution

```js
const client = createWebSocketClient('ws://192.168.32.1/socket', {
  useCCUPort: true,
  defaultPort: 1456,
  ccuPortEndpoint: 'get_assigned_ports',
  autoReconnect: true,
});
```

The CCU endpoint should respond with a JSON object mapping the defaultPort to the assigned port, for example `{ "1456": 9000 }`. The client automatically falls back to `defaultPort` when the lookup fails.

## API

### `createWebSocketClient(baseUrl, options)`

Creates and immediately connects a WebSocket using the provided base URL (host + path without port). Returns an object with two properties:

- `socket`: the latest `WebSocket` instance (or `null` until connected)
- `close(code?, reason?)`: manually closes the socket and stops auto reconnect

`options` (all optional):

- `protocols`: string or string[] passed to the native constructor
- `events`: `{ open, message, close, error }` listeners invoked when events fire
- `autoReconnect`: `true` to retry after unexpected closures (default `false`)
- `reconnectInterval`: delay in ms between retries (default `3000`)
- `useCCUPort`: `true` to fetch the port from a CCU endpoint
- `defaultPort`: base/fallback port and lookup key (default `1456`)
- `ccuPortEndpoint`: URL used when resolving the CCU port (default `"get_assigned_ports"`)
- `manualPort`: number to use when `useCCUPort` is `false` (required in that case)

Errors early when neither `useCCUPort` nor `manualPort` provide a valid port configuration.

### `sendJson(socket, payload)`

Serializes the payload and sends it through an open socket. Throws if the socket is `null` or not in the `OPEN` state.

### `closeWebSocketSafe(socket, code?, reason?)`

Closes the socket only when it exists and is not already closing/closed.

### `isProperJson(payload)`

Returns `true` if the input is already an object or a JSON string that can be parsed into an object. Useful for quick payload guards.

## License

MIT