Framework-agnostic browser client for the Hiyve Semantic Relay — built for high-frequency, fire-and-forget, room-scoped messaging.
Connects over WebTransport (HTTP/3 / QUIC datagrams, preferred) with automatic WebSocket fallback: when WebTransport is missing or cannot connect (e.g. networks that block UDP), the client transparently retries over WebSocket against the same relay endpoint. Consumers use one API either way; the active transport is reported via client.transportKind.
For React applications, use @hiyve/react-semantic-relay which wraps this client with a context provider and topic-scoped pub/sub hooks.
npm install @hiyve/semantic-relay-client
import { SemanticRelayClient } from '@hiyve/semantic-relay-client';
const client = new SemanticRelayClient({
url: 'https://semantic.hiyve.tv:4443/relay',
roomId: 'lesson-abc',
userId: 'alice@example.com',
token: jwtFromBackend,
serverCertificateHashes, // optional; required for self-signed dev/prod certs
});
const session = await client.connect();
console.log('session id', session.sessionId, 'peers', session.peers);
const unsubscribe = client.subscribe('instrument-notes', ({ payload, userId }) => {
console.log(`${userId} played`, payload);
});
client.publish('instrument-notes', { midi: 60, on: true, velocity: 100 });
// Later:
unsubscribe();
client.dispose();
serverCertificateHashesis aRelayCertHash[]of SHA-256 fingerprints — see the WebTransport docs for derivation. Production deployments using a public CA can omit it.
| Option | Required | Description |
|---|---|---|
url |
yes | Base WebTransport URL (https://...:4443/relay). |
roomId |
yes | Room identifier — relay-side broadcast scope. |
userId |
yes | Sender identity attached to every published message. |
token |
yes | Short-lived auth token minted by the app backend. |
serverCertificateHashes |
no | SHA-256 certificate hashes for self-signed certs. |
onError |
no | Connection / publish / decode errors. |
onConnectionChange |
no | Notification when the connection state changes (connecting, connected, closed, error). |
onDebug |
no | Debug logger; pairs with createDebugLogger('hiyve:semantic-relay'). |
maxSeenMessages |
no | Per-topic dedupe cache size (default 200). |
pruneCount |
no | Dedupe entries dropped when the cache is full (default 50). |
retryDelaysMs |
no | Connect-retry backoff (default [200, 800, 2000]). Auth failures bypass. |
transport |
no | 'auto' (default), 'webtransport', or 'websocket'. In 'auto', WebTransport is tried first when available; any non-auth connect failure falls through to WebSocket. |
wsBufferedAmountHighWater |
no | WebSocket congestion threshold in bytes (default 16 KB). While the socket is congested, outbound messages coalesce latest-wins per topic so fresh state is never queued behind stale state. Ignored on WebTransport. |
The client wraps relay messages in a small envelope; serialization, framing, and identity stamping are handled internally.
MAX_DATAGRAM_BYTES); larger messages should fragment at the application layer.Every current browser is supported. WebTransport (the preferred transport) is available in Chrome/Edge 97+, Firefox 114+, and Safari 26.4+; everywhere else — including older Safari/iOS and networks that block UDP — the client falls back to WebSocket automatically. No consumer-side capability gating is required.
Delivery semantics are fire-and-forget on both transports: messages may be dropped under network congestion (natively on WebTransport; via latest-wins coalescing on WebSocket), so protocols built on this client should tolerate loss — exactly as they must for datagrams.
| Export | Description |
|---|---|
SemanticRelayClient |
The client class. |
RelayCertHash |
Shape of a single SHA-256 cert hash entry. |
RelayConnectionState |
'idle' | 'connecting' | 'connected' | 'error' | 'closed'. |
RelayEnvelope<T> |
Wire envelope shape. |
RelayMessage<T> |
Subscriber-visible message: { topic, payload, userId, messageId, timestamp }. |
RelayOptions |
Constructor options shape. |
RelayTransportPolicy |
'auto' | 'webtransport' | 'websocket'. |
RelayTransportKind |
'webtransport' | 'websocket' — see client.transportKind. |
DefaultedRelayOptions |
Options after defaults are applied. |
RelaySubscribeHandler<T> |
Callback signature for subscribe. |
SessionInfo |
Session metadata returned by connect(). |
hasWebTransport() / hasWebSocket() |
Runtime capability probes. |
deriveWebSocketUrl(url) |
Maps the relay's https:// URL to its wss:// equivalent. |
DEFAULT_OPTIONS |
The full default options object. |
mergeOptions(user) |
Merge user options on top of DEFAULT_OPTIONS. |
MAX_DATAGRAM_BYTES |
Max envelope size (~1200). |
SESSION_ID_HEADER_BYTES |
Bytes reserved for the session-id header in each datagram. |
DEFAULT_MAX_SEEN_MESSAGES |
Default dedupe cache size. |
DEFAULT_PRUNE_COUNT |
Default prune count when the cache is full. |
DEFAULT_RETRY_DELAYS_MS |
Default reconnect backoff schedule. |
DEFAULT_CONNECT_TIMEOUT_MS |
Default connect timeout. |
DEFAULT_WS_BUFFERED_HIGH_WATER |
Default WebSocket congestion threshold (bytes). |
WS_FLUSH_INTERVAL_MS |
Congestion re-check cadence for coalesced sends. |
SESSION_INFO_TYPE |
Tag for SessionInfo messages on the control topic. |
MIT
@hiyve/semantic-relay-client— framework-agnostic browser client for the Hiyve Semantic Relay (Go WebTransport datagram service).Designed for high-frequency, fire-and-forget, room-scoped messaging where the WebRTC data channel's per-message overhead (negotiation, peer-to-peer routing, JSON snapshot envelopes) is too heavy. Typical use cases: instrument note events, semantic-avatar blendshape streams, spatial audio cues.
For React applications, use
@hiyve/react-semantic-relaywhich wraps this client with a context provider and topic-scoped pub/sub hooks.Example