CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-simple-peer

Simple one-to-one WebRTC video/voice and data channels

Pending
Overview
Eval results
Files

connection.mddocs/

Connection Management

Core WebRTC peer connection functionality providing automatic negotiation, signaling handling, and connection lifecycle management.

Capabilities

Peer Constructor

Creates a new WebRTC peer connection with configurable options.

/**
 * Create a new WebRTC peer connection
 * @param opts - Configuration options for the peer
 */
class Peer extends Duplex {
  constructor(opts?: PeerOptions);
}

interface PeerOptions {
  /** Set to true if this is the initiating peer */
  initiator?: boolean;
  /** Custom WebRTC data channel configuration */
  channelConfig?: RTCDataChannelInit;
  /** Custom WebRTC data channel name */
  channelName?: string;
  /** Custom WebRTC configuration (ICE servers, etc.) */
  config?: RTCConfiguration;
  /** Custom offer options for createOffer */
  offerOptions?: RTCOfferOptions;
  /** Custom answer options for createAnswer */
  answerOptions?: RTCAnswerOptions;
  /** Function to transform generated SDP signaling data */
  sdpTransform?: (sdp: string) => string;
  /** MediaStream for video/voice (deprecated, use streams) */
  stream?: MediaStream;
  /** Array of MediaStreams for video/voice */
  streams?: MediaStream[];
  /** Enable trickle ICE candidates (default: true) */
  trickle?: boolean;
  /** Allow half trickle ICE (default: false) */
  allowHalfTrickle?: boolean;
  /** Timeout for ICE completion in milliseconds (default: 5000) */
  iceCompleteTimeout?: number;
  /** Custom WebRTC implementation (required in Node.js) */
  wrtc?: WebRTCImplementation;
  /** Create stream in Object Mode (default: false) */
  objectMode?: boolean;
  /** Allow half-open duplex streams (default: false) */
  allowHalfOpen?: boolean;
}

interface WebRTCImplementation {
  RTCPeerConnection: typeof RTCPeerConnection;
  RTCSessionDescription: typeof RTCSessionDescription;
  RTCIceCandidate: typeof RTCIceCandidate;
}

Usage Examples:

const Peer = require('simple-peer');

// Basic peer (browser)
const peer = new Peer({ initiator: true });

// Node.js peer with wrtc
const wrtc = require('wrtc');
const peer = new Peer({ 
  initiator: true,
  wrtc: wrtc 
});

// Peer with custom configuration
const peer = new Peer({
  initiator: false,
  config: {
    iceServers: [
      { urls: 'stun:stun.l.google.com:19302' },
      { urls: 'turn:turnserver.com', username: 'user', credential: 'pass' }
    ]
  },
  trickle: false,
  iceCompleteTimeout: 10000
});

Signal Processing

Process signaling data from the remote peer to establish and maintain the connection.

/**
 * Process signaling data from remote peer
 * @param data - Signaling data (offer/answer/ice candidate)
 * @throws {Error} ERR_DESTROYED - if peer is destroyed
 * @throws {Error} ERR_SIGNALING - if signaling data is invalid
 */
peer.signal(data: SignalData | string): void;

interface SignalData {
  /** Type of signaling message */
  type?: 'offer' | 'answer' | 'renegotiate' | 'transceiverRequest' | 'candidate';
  /** SDP data for offers/answers */
  sdp?: string;
  /** ICE candidate data */
  candidate?: RTCIceCandidateInit;
  /** Renegotiation request flag */
  renegotiate?: boolean;
  /** Transceiver request data */
  transceiverRequest?: {
    kind: string;
    init?: RTCRtpTransceiverInit;
  };
}

Usage Examples:

// Handle signaling between peers
peer1.on('signal', data => {
  // Send to peer2 via signaling server (websocket, etc.)
  signalingServer.send(JSON.stringify(data));
});

signalingServer.on('message', data => {
  const signalData = JSON.parse(data);
  peer1.signal(signalData);
});

// Direct signaling (same process, for testing)
peer1.on('signal', data => peer2.signal(data));
peer2.on('signal', data => peer1.signal(data));

Connection Lifecycle

Manage the peer connection lifecycle including negotiation and cleanup.

/**
 * Initiate renegotiation of the peer connection
 */
peer.negotiate(): void;

/**
 * Destroy and cleanup the peer connection
 * @param err - Optional error to emit
 */
peer.destroy(err?: Error): void;

Usage Examples:

// Manual renegotiation
peer.negotiate();

// Graceful cleanup
peer.on('close', () => {
  console.log('Peer connection closed');
});

peer.destroy();

// Cleanup with error
peer.destroy(new Error('Connection timeout'));

Connection Events

Events emitted during the connection lifecycle.

// Connection established and ready
peer.on('connect', () => void);

// Signaling data ready to send
peer.on('signal', (data: SignalData) => void);

// Connection closed
peer.on('close', () => void);

// Fatal error occurred
peer.on('error', (err: Error) => void);

// ICE connection state changed
peer.on('iceStateChange', (iceConnectionState: string, iceGatheringState: string) => void);

// Negotiation completed
peer.on('negotiated', () => void);

// Signaling state changed
peer.on('signalingStateChange', (signalingState: string) => void);

// ICE timeout reached
peer.on('iceTimeout', () => void);

Usage Examples:

const peer = new Peer({ initiator: true });

peer.on('signal', data => {
  console.log('Send this to remote peer:', JSON.stringify(data));
});

peer.on('connect', () => {
  console.log('Peer connected successfully');
  peer.send('Hello!');
});

peer.on('iceStateChange', (iceConnectionState, iceGatheringState) => {
  console.log('ICE state:', iceConnectionState, iceGatheringState);
});

peer.on('error', err => {
  console.error('Peer error:', err.message, err.code);
  peer.destroy();
});

peer.on('close', () => {
  console.log('Peer connection closed');
});

Error Handling

Simple Peer emits errors with specific error codes for different failure scenarios:

interface PeerError extends Error {
  code: string;
}

Common Error Codes:

  • ERR_WEBRTC_SUPPORT - No WebRTC support detected
  • ERR_PC_CONSTRUCTOR - RTCPeerConnection constructor failed
  • ERR_DESTROYED - Operation on destroyed peer
  • ERR_CREATE_OFFER - Failed to create offer
  • ERR_CREATE_ANSWER - Failed to create answer
  • ERR_SET_LOCAL_DESCRIPTION - Failed to set local description
  • ERR_SET_REMOTE_DESCRIPTION - Failed to set remote description
  • ERR_ADD_ICE_CANDIDATE - Failed to add ICE candidate
  • ERR_ICE_CONNECTION_FAILURE - ICE connection failed
  • ERR_CONNECTION_FAILURE - General connection failure
  • ERR_SIGNALING - Invalid signaling data
  • ERR_DATA_CHANNEL - Data channel operation failed
  • ERR_ADD_TRANSCEIVER - Failed to add transceiver
  • ERR_SENDER_REMOVED - Track sender was removed
  • ERR_SENDER_ALREADY_ADDED - Track already added to connection
  • ERR_TRACK_NOT_ADDED - Cannot remove track that was never added
  • ERR_REMOVE_TRACK - Failed to remove track
  • ERR_UNSUPPORTED_REPLACETRACK - replaceTrack not supported

Usage Examples:

peer.on('error', err => {
  switch (err.code) {
    case 'ERR_WEBRTC_SUPPORT':
      console.error('WebRTC not supported in this browser');
      break;
    case 'ERR_ICE_CONNECTION_FAILURE':
      console.error('ICE connection failed - check network/firewall');
      break;
    case 'ERR_SIGNALING':
      console.error('Invalid signaling data received');
      break;
    default:
      console.error('Peer error:', err.message);
  }
});

Install with Tessl CLI

npx tessl i tessl/npm-simple-peer

docs

connection.md

data.md

index.md

info.md

media.md

tile.json