npm package: @olivvein/superhub-sdk
Description: TypeScript client SDK for SuperHub over WebSocket/HTTPS.
Latest version: 0.1.2

# superhub-sdk

TypeScript client SDK for SuperHub over WebSocket/HTTPS.

npm package: `@olivvein/superhub-sdk`

## Install

```bash
npm install @olivvein/superhub-sdk
```

```ts
import { HubClient } from "@olivvein/superhub-sdk";
```

## Quickstart (Node.js)

```ts
import { randomUUID } from "node:crypto";
import { HubClient } from "@olivvein/superhub-sdk";

const client = new HubClient({
  httpUrl: "https://code.samlepirate.org",
  token: process.env.HUB_TOKEN,
  clientId: randomUUID(),
  serviceName: "demo-node-client",
  consumes: ["demo.*"],
  debug: true
});

client.onOpen(() => {
  console.log("connected");

  const stopSub = client.subscribe({ namePrefix: "demo." }, (msg) => {
    console.log("event", msg.name, msg.payload);
  });

  client.publish("demo.ping", { at: Date.now() });

  setTimeout(() => {
    stopSub();
    client.disconnect();
  }, 10_000);
});

client.onError((err) => console.error("hub error", err));
client.onClose(() => console.log("disconnected"));

void client.connect();
```

## Quickstart (Browser)

```ts
import { HubClient } from "@olivvein/superhub-sdk";

const client = new HubClient({
  httpUrl: "https://code.samlepirate.org",
  token: "<hub-token>",
  clientId: `web-${crypto.randomUUID()}`,
  serviceName: "demo-web-client",
  consumes: ["demo.*"]
});

await client.connect();
client.publish("demo.hello", { from: "browser" });
```

## Configuration

`HubClient` options:

- `httpUrl` (required): Hub base URL, for example `https://code.samlepirate.org`.
- `clientId` (required): stable or random client ID.
- `token`: hub token (`X-Hub-Token` equivalent, sent in WS query string).
- `wsUrl`: override WebSocket URL (default derived from `httpUrl` as `/ws`).
- `serviceName`: logical service name for routing/RPC.
- `version`: advertised version in presence payload.
- `provides`: service capabilities this client provides.
- `consumes`: event patterns this client consumes.
- `tags`: free-form metadata tags.
- `debug`: verbose SDK logs for parsing/reconnect issues.
- `defaultRpcTimeoutMs`: default RPC timeout (default `15000`).
- `reconnect.enabled`: auto reconnect toggle (default `true`).
- `reconnect.minDelayMs`, `maxDelayMs`, `factor`, `jitterRatio`: reconnect backoff tuning.
- `tls.caFile` (Node only): path to CA certificate file.
- `tls.rejectUnauthorized` (Node only): set `false` only for local/debug environments.

## Core API

### Connection lifecycle

- `await client.connect()`
- `client.disconnect()`
- `client.onOpen(listener)`
- `client.onClose(listener)`
- `client.onError(listener)`

### Pub/Sub

- `client.publish(name, payload, target = "*", schemaVersion = 1)`
- `const unsubscribe = client.subscribe({ names? | namePrefix? }, handler)`

Target can be:

- `"*"` (broadcast)
- `{ clientId: "..." }`
- `{ serviceName: "..." }`

### RPC client

```ts
const result = await client.rpc<{ accepted: boolean }>(
  "music",
  "music.play",
  { trackId: "track-1", positionMs: 0 },
  5000
);
```

### RPC server/provider

```ts
const unregister = client.onRpc("music.play", async (args, ctx) => {
  return {
    accepted: true,
    args,
    from: ctx.source
  };
});
```

### State helpers

- `await client.getState<T>(path)`
- `client.setState(path, value)`
- `client.patchState(path, patchOps)`
- `const unwatch = client.watchState(prefix, (path, value, source) => { ... })`

## Important behavior

- Calls that send messages (`publish`, `subscribe`, `setState`, `patchState`, `watchState`, `rpc`) require an open socket.
- If the socket is not connected, the SDK throws `Error("Socket is not connected")`.
- On reconnect, existing subscriptions and state watches are replayed automatically.

## Examples

Scaffold bundled examples into your project:

```bash
npx --no-install superhub-examples ./superhub-examples
```

Generated files include Node and React examples.

## Release / Publish (maintainers)

From monorepo root:

```bash
npm_config_cache=/tmp/.npm-cache npm whoami || npm_config_cache=/tmp/.npm-cache npm login
npm run release:sdk:patch
# or: npm run release:sdk:minor
# or: npm run release:sdk:major
```

Publish only (already version-bumped):

```bash
npm run publish:sdk
```

Full runbook:

- `docs/SDK_NPM_PUBLISH_GUIDE.md`