Zodiac API Documentation - v0.0.3
    Preparing search index...

    Class PeerChannel

    Basic peer-to-peer setup:

    import { PeerChannel, defineMessage, z } from '@xtr-dev/zodiac';

    // Define message types
    const chatMessage = defineMessage('chat', z.object({
    text: z.string(),
    sender: z.string()
    }));

    // Create peer channel
    const channel = new PeerChannel('peer-1', {
    iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
    });

    // Set up signaling (you provide this transport)
    channel.setSignalingHandler((message) => {
    signalingSocket.emit('webrtc-signal', message);
    });

    // Listen for messages
    channel.on(chatMessage, (data) => {
    console.log(`${data.sender}: ${data.text}`);
    });

    // Create offer to connect to another peer
    const offer = await channel.createOffer('peer-2');
    signalingSocket.emit('webrtc-signal', {
    ...offer,
    type: 'offer',
    to: 'peer-2'
    });

    Handle incoming signaling messages:

    signalingSocket.on('webrtc-signal', async (message) => {
    if (message.type === 'offer') {
    const answer = await channel.handleOffer(message.data, message.from);
    signalingSocket.emit('webrtc-signal', {
    ...answer,
    type: 'answer',
    to: message.from
    });
    } else if (message.type === 'answer') {
    await channel.handleAnswer(message.data);
    } else if (message.type === 'ice-candidate') {
    await channel.handleIceCandidate(message.data);
    }
    });
    • Lower Latency: Direct connection eliminates server round-trip
    • Reduced Server Load: No message forwarding through servers
    • Privacy: Messages don't pass through third-party servers
    • Scalability: Server only handles initial signaling
    • Offline Capability: Works on local networks without internet

    Hierarchy

    • BaseChannel
      • PeerChannel
    Index

    Constructors

    Methods

    • Sends a type-safe, validated message using a message definition.

      This is the preferred way to send messages as it provides:

      • Compile-time type checking
      • Runtime validation with Zod
      • Automatic message ID handling

      Type Parameters

      Parameters

      • definition: T

        Message definition created with defineMessage()

      • data: InferMessageData<T>

        Message data that matches the definition's schema

      Returns Promise<void>

      When data doesn't match the schema

      const userMsg = defineMessage('user', z.object({
      name: z.string(),
      age: z.number().min(0)
      }));

      // Type-safe and validated
      await channel.sendMessage(userMsg, {
      name: 'Alice',
      age: 25
      });

      // TypeScript error: missing required field
      await channel.sendMessage(userMsg, { name: 'Bob' }); // Error!

      // Runtime error: validation fails
      await channel.sendMessage(userMsg, { name: 'Charlie', age: -1 }); // Throws!
    • Registers a message handler for a specific message type (by string ID).

      Type Parameters

      • T

      Parameters

      • id: string

        String identifier for the message type

      • handler: MessageHandler<T>

        Function to handle incoming messages

      Returns void

    • Registers a type-safe message handler using a message definition. This is the preferred method as it provides full type safety.

      Type Parameters

      Parameters

      Returns void

      const chatMsg = defineMessage('chat', z.object({
      user: z.string(),
      text: z.string()
      }));

      // Fully typed handler - data.user and data.text are known
      channel.on(chatMsg, (data, message) => {
      console.log(`${data.user}: ${data.text}`);
      console.log(`Sent at: ${message.timestamp}`);
      });
    • Removes a message handler for a specific message type (by string ID).

      Type Parameters

      • T

      Parameters

      • id: string

        String identifier for the message type

      • handler: MessageHandler<T>

        The exact handler function to remove

      Returns void

    • Removes a type-safe message handler using a message definition.

      Type Parameters

      Parameters

      Returns void

      const handler = (data) => console.log(data.text);

      // Register handler
      channel.on(chatMsg, handler);

      // Remove the same handler instance
      channel.off(chatMsg, handler);
    • Checks if the channel is currently connected and ready for communication.

      Returns boolean

      true if connected, false otherwise

      if (channel.isOpen()) {
      await channel.sendMessage(someMessage, data);
      } else {
      console.log('Channel is not connected');
      }
    • Sets the signaling handler for exchanging WebRTC signaling messages. This should connect to your signaling mechanism (WebSocket, Socket.IO, etc.)

      The handler will be called whenever this peer needs to send signaling messages to remote peers during connection establishment.

      Parameters

      • handler: (message: SignalingMessage) => void

        Function to handle outgoing signaling messages

      Returns void

      channel.setSignalingHandler((message) => {
      // Send via your signaling transport
      signalingSocket.emit('webrtc-signal', message);
      });
    • Creates a WebRTC offer to initiate connection with a remote peer. Call this method when you want to start a connection to another peer.

      Parameters

      • remotePeerId: string

        The ID of the peer you want to connect to

      Returns Promise<RTCSessionDescriptionInit>

      A WebRTC offer that should be sent to the remote peer via signaling

      const offer = await channel.createOffer('remote-peer-id');
      signalingSocket.emit('offer', { offer, to: 'remote-peer-id' });
    • Handles an incoming WebRTC offer and creates an answer. Call this when you receive an offer from another peer via signaling.

      Parameters

      • offer: RTCSessionDescriptionInit

        The WebRTC offer received from remote peer

      • fromPeerId: string

        The ID of the peer sending the offer

      Returns Promise<RTCSessionDescriptionInit>

      A WebRTC answer that should be sent back to the offering peer

      signalingSocket.on('offer', async ({offer, from}) => {
      const answer = await channel.handleOffer(offer, from);
      signalingSocket.emit('answer', { answer, to: from });
      });
    • Handles an incoming WebRTC answer from a remote peer. Call this when you receive an answer to your offer via signaling.

      Parameters

      • answer: RTCSessionDescriptionInit

        The WebRTC answer received from remote peer

      Returns Promise<void>

      signalingSocket.on('answer', async ({answer}) => {
      await channel.handleAnswer(answer);
      });
    • Handles an incoming ICE candidate from a remote peer. ICE candidates are exchanged during connection establishment to find the best network path between peers.

      Parameters

      • candidate: RTCIceCandidate

        The ICE candidate received from remote peer

      Returns Promise<void>

      signalingSocket.on('ice-candidate', async ({candidate}) => {
      await channel.handleIceCandidate(candidate);
      });
    • Establishes connection to the specified endpoint. Implementation varies by transport (WebSocket URL, WebRTC signaling, etc.)

      Returns Promise<void>

    • Closes the connection and cleans up resources.

      Returns Promise<void>

    • Sends raw data over the channel. Use sendMessage() for type-safe validated sending instead.

      Type Parameters

      • T

      Parameters

      • id: string

        Message type identifier

      • data: T

        Raw message data

      Returns Promise<void>

    • Get the peer ID of the remote peer (if connected)

      Returns null | string

    • Get the current WebRTC connection state

      Returns null | RTCPeerConnectionState

    • Get the current data channel state

      Returns null | RTCDataChannelState