# @hiyve/react-semantic-relay

React provider + hooks for the [Hiyve Semantic Relay](../semantic-relay-client) — high-frequency, fire-and-forget, room-scoped messaging via WebTransport datagrams.

## Installation

```bash
npm install @hiyve/react-semantic-relay @hiyve/semantic-relay-client
```

## Quick start

```tsx
import { SemanticRelayProvider, useRelayTopic } from '@hiyve/react-semantic-relay';

function App() {
  return (
    <SemanticRelayProvider
      url="https://semantic.hiyve.tv:4443/relay"
      roomId="lesson-abc"
      userId="alice@example.com"
      token={jwtFromBackend}
      serverCertificateHashes={certHashes}
    >
      <Instruments />
    </SemanticRelayProvider>
  );
}

function Instruments() {
  const { publish, subscribe, isConnected } = useRelayTopic<{ midi: number; on: boolean }>(
    'instrument-notes',
  );

  useEffect(() => subscribe(({ payload, userId }) => {
    console.log(`${userId} played`, payload);
  }), [subscribe]);

  return (
    <button disabled={!isConnected} onClick={() => publish({ midi: 60, on: true })}>
      Play C
    </button>
  );
}
```

## Requirements

- A running Hiyve Semantic Relay server reachable over WebTransport (HTTPS/3).
- A short-lived JWT minted by your backend, scoped to a `roomId` + `userId`.
- For self-signed development certs, the SHA-256 certificate hashes (`serverCertificateHashes`) — browsers refuse to connect over WebTransport without this when not using a public CA.
- Modern browser with WebTransport support (Chrome / Edge stable; Firefox / Safari support varies — check current compatibility).
- Peer dependencies: `react ^18`, `@hiyve/semantic-relay-client`.

## API

### `<SemanticRelayProvider>`

Provides a relay connection to descendants. Reconnects automatically when connection identity (`url` / `roomId` / `userId` / `token`) changes.

| Prop | Type | Required | Description |
|---|---|---|---|
| `url` | `string` | yes | Base WebTransport URL. |
| `roomId` | `string` | yes | Room identifier. |
| `userId` | `string` | yes | Sender identity attached to every published message. |
| `token` | `string` | yes | Short-lived auth token minted by your backend. |
| `serverCertificateHashes` | `RelayCertHash[]` | no | SHA-256 certificate hashes for self-signed dev certs. See [WebTransport docs](https://developer.mozilla.org/docs/Web/API/WebTransport/WebTransport) for derivation. |
| `disabled` | `boolean` | no | When `true`, the provider does not connect. |
| `onError` | `(error: Error) => void` | no | Called on connection or transport errors. |
| `onConnectionChange` | `(state: RelayConnectionState) => void` | no | Called whenever the connection state changes. |
| `onDebug` | `(message: string) => void` | no | Optional debug callback for diagnostic output. |
| `maxSeenMessages` | `number` | no | Cap for the deduplication ring buffer. |
| `pruneCount` | `number` | no | Number of entries pruned when the ring buffer is full. |
| `retryDelaysMs` | `number[]` | no | Custom backoff schedule for reconnection attempts. |

### `useSemanticRelay()`

Returns `{ client, state, session, isConnected, error }`. Use this for lower-level access — most consumers only need `useRelayTopic`.

### `useRelayTopic<T>(topic)`

Returns `{ publish, subscribe, isConnected }`. The `subscribe` callback returns an unsubscribe function suitable for a `useEffect` cleanup.

## Key Types

| Type | Description |
|---|---|
| `SemanticRelayProviderProps` | Props accepted by `<SemanticRelayProvider>`. |
| `UseSemanticRelayResult` | Return shape of `useSemanticRelay()`. |
| `UseRelayTopicResult<T>` | Return shape of `useRelayTopic<T>()`. |
| `RelayConnectionState` | Connection state reported by the provider (`'idle' \| 'connecting' \| 'connected' \| 'error' \| 'closed'`). |
| `RelayMessage<T>` | Shape of a received message: `{ topic, payload, userId, ... }`. |
| `RelaySubscribeHandler<T>` | Callback signature for `subscribe`. |
| `SessionInfo` | Session metadata returned by the relay (e.g. server-stamped session id). |

## License

MIT
