npm package: @sejatordev/ws-client-node
Description: WebSocket client khusus **Node.js (server-to-server)** dengan konsep **channel-based** (mirip Pusher), dirancang untuk:
Latest version: 1.0.0

# @sejator/ws-client-node

WebSocket client khusus **Node.js (server-to-server)** dengan konsep **channel-based** (mirip Pusher), dirancang untuk:

- Worker / background service
- Backend service listener
- Microservice real-time
- Bot / automation
- Internal event consumer

> 🔒 **Tidak untuk browser**  
> Package ini hanya berjalan di Node.js runtime.

---

## ✨ Fitur

- 🔌 Auto connect & auto reconnect
- 🔁 Manual reconnect
- ❤️ Heartbeat + pong timeout
- 📡 Channel & event system
- 🔄 Auto re-subscribe saat reconnect
- 🔐 Private & presence channel (HMAC server-side)
- 🧠 Fully typed (TypeScript)
- 🌐 URL auto normalize (http → ws, `/ws`)

---

## 🔗 SDK Resmi untuk `@sejator/ws-server`

`@sejator/ws-client-node` adalah **SDK resmi backend** untuk:

- [@sejator/ws-server](https://github.com/sejator/ws-server)

Kompatibel penuh dengan:

- Channel protocol
- Event format
- Private channel auth (`APP_KEY:signature`)
- Heartbeat & reconnect strategy

❌ **Tidak ditujukan untuk WebSocket server lain**

---

## 🏗️ Arsitektur

```
Backend Service / Worker
        │
        │  @sejator/ws-client-node
        ▼
WebSocket Protocol (Channel-based)
        │
        │  @sejator/ws-server
        ▼
Main Application / API
```

---

## 📦 Instalasi

```bash
git clone https://github.com/sejator/ws-client-node.git
cd ws-client-node
npm install
npm run build
```

---

## ⚙️ Environment Variable

```env
WS_APP_KEY=your_app_key
WS_APP_SECRET=your_app_secret
WS_APP_URL=http://localhost:3000
```

---

## 🚀 Penggunaan Dasar

```ts
import "dotenv/config";
import { WSClient } from "@sejator/ws-client-node";

const client = new WSClient(process.env.WS_APP_URL!, {
  key: process.env.WS_APP_KEY!,
  secret: process.env.WS_APP_SECRET!,
  logger: true,
});

client.on("connect_success", ({ socket_id }) => {
  console.log("Connected:", socket_id);
});

const channel = client.subscribe("orders");

channel.bind("order.created", (payload) => {
  console.log("Order created:", payload);
});
```

---

## 🔐 Private Channel (Server Auth Otomatis)

Tidak perlu `authEndpoint` atau HTTP request.

SDK akan menghasilkan **HMAC signature secara lokal**.

```ts
const privateChannel = client.subscribe("private-orders");

privateChannel.bind("order.updated", (data) => {
  console.log("Order updated:", data);
});
```

### Cara Kerja Signature

Signature dibuat dengan format:

```
HMAC_SHA256(APP_SECRET, `${socketId}:${channel}`)
```

Lalu dikirim ke server sebagai:

```
APP_KEY:signature_hash
```

---

## 🧩 Custom Signature Utility (Opsional)

Jika ingin kontrol manual:

```ts
import { generateAuthString } from "./utils/signature";

auth: async ({ socketId, channel }) => {
  return {
    auth: generateAuthString(socketId, channel, process.env.WS_APP_KEY!, process.env.WS_APP_SECRET!),
  };
};
```

---

## 🔌 Client Options

```ts
interface WSClientNodeOptions {
  key: string; // APP_KEY (required)
  secret: string; // APP_SECRET (required)

  logger?: boolean;
  reconnect?: boolean;
  maxReconnectDelay?: number;
}
```

---

## 📌 Tidak tersedia di versi Node

- ❌ Cookie
- ❌ CSRF
- ❌ authEndpoint
- ❌ Browser headers

---

## 📡 Event Client

| Event           | Payload                           | Deskripsi          |
| --------------- | --------------------------------- | ------------------ |
| connect_success | `{ socket_id, activity_timeout }` | Koneksi berhasil   |
| disconnected    | `void`                            | Koneksi terputus   |
| reconnecting    | `{ manual: boolean }`             | Reconnect dimulai  |
| auth_failed     | `string`                          | Auth channel gagal |
| state_change    | `{ previous, current }`           | State transition   |
| error           | `unknown`                         | Error WebSocket    |

---

## 🔁 Manual Reconnect

```ts
client.reconnect();
```

---

## ❤️ Heartbeat & Pong Timeout

- Client mengirim **ping**
- Server membalas **pong**
- Timeout → reconnect otomatis

---

## 🌐 URL Normalization

Input:

```ts
new WSClient('http://localhost:3000', {...})
```

Akan menjadi:

```
ws://localhost:3000/ws
```

Didukung:

- `http` / `https`
- `ws` / `wss`
- tanpa protocol

---

## 🔐 Kapan Menggunakan `ws-client` vs `ws-client-node`?

| Use Case                 | Package                   |
| ------------------------ | ------------------------- |
| Browser / Frontend       | `@sejator/ws-client`      |
| Next.js Client Component | `@sejator/ws-client`      |
| Backend / Worker / Bot   | `@sejator/ws-client-node` |
| Server-to-server         | `@sejator/ws-client-node` |

---

## ⚠️ Security Notes

- **JANGAN** gunakan `ws-client-node` di browser
- `APP_SECRET` hanya untuk server
- Pastikan channel private divalidasi di server

---

## Kontak & Dukungan

Maintainer: [@sejator](https://github.com/sejator)\
Email: [sejatordev@gmail.com](sejatordev@gmail.com)\
Donasi: [https://saweria.co/sejator](https://saweria.co/sejator)