@panyam/massrelay
v0.0.11
Published
TypeScript client for the [Massrelay](https://github.com/panyam/massrelay) real-time collaboration relay server.
Readme
@panyam/massrelay
TypeScript client for the Massrelay real-time collaboration relay server.
Installation
npm install @panyam/massrelayPeer dependencies:
@bufbuild/protobuf ^2.0.0@panyam/servicekit-client ^0.0.6
Exports
| Import Path | Contents |
|-------------|----------|
| @panyam/massrelay/client | CollabClient — WebSocket client for the relay |
| @panyam/massrelay/sync | SyncAdapter interface, SyncActions, SyncConnection, and related types |
| @panyam/massrelay/url | URL helpers: resolveRelayUrl, encodeJoinCode, decodeJoinCode, etc. |
| @panyam/massrelay/models | Generated protobuf types (PeerInfo, CollabAction, CollabEvent, etc.) |
| @panyam/massrelay/services | Generated service definitions |
This is an ESM package ("type": "module").
Quick Start
import { CollabClient } from '@panyam/massrelay/client';
const client = new CollabClient({
onConnect: (clientId) => console.log('Connected as', clientId),
onPeerJoined: (peer) => console.log('Peer joined:', peer.username),
onPeerLeft: (clientId) => console.log('Peer left:', clientId),
onEvent: (event) => { /* handle scene/text/cursor updates */ },
onDisconnect: () => console.log('Disconnected'),
onErrorEvent: (code, msg) => console.error('Relay error:', code, msg),
});
// Join or create a session
client.connect(
'ws://localhost:8787', // relayUrl (or relative path like "/relay")
'', // sessionId (empty = relay generates one)
'Alice', // username
{ tool: 'whiteboard' }, // metadata (application-defined key-value pairs)
true, // isOwner
);
// Send updates to peers
client.send({
sceneUpdate: {
elements: [
{ id: 'rect1', version: 1, data: '{"type":"rectangle",...}' }
]
}
});
// Disconnect
client.disconnect();SyncAdapter
Implement this interface to integrate your editor with massrelay's sync layer:
import type { SyncAdapter } from '@panyam/massrelay/sync';
class MyEditorSyncAdapter implements SyncAdapter {
readonly metadata = { tool: 'my-editor' };
computeOutgoing() { /* diff local changes */ }
applyRemote(fromClientId, payload) { /* merge remote changes */ }
getSceneSnapshot() { /* full state for new joiners */ }
applySceneInit(payload) { /* load full state from peer */ }
getCursorData() { /* current cursor position */ }
applyRemoteCursor(peer) { /* show remote cursor */ }
removePeerCursor(clientId) { /* hide disconnected cursor */ }
}URL Helpers
import { resolveRelayUrl, encodeJoinCode, decodeJoinCode } from '@panyam/massrelay/url';
// Resolve relative relay URL to WebSocket URL
resolveRelayUrl('/relay') // → 'wss://currenthost/relay'
// Create shareable join codes
const code = encodeJoinCode('wss://relay.example.com', 'session-123');
const parsed = decodeJoinCode(code);
// → { relayUrl: 'wss://relay.example.com', sessionId: 'session-123' }Full Documentation
See the main README for complete protocol reference, server configuration, message flows, and Go API docs.
