mirror of
https://github.com/xtr-dev/rondevu-client.git
synced 2025-12-10 02:43:25 +00:00
Remove global origin option and update README
- Remove origin option from RondevuClientOptions and RondevuOptions - Remove ConnectOptions interface with global flag - Remove all customHeaders logic for origin override - Update README with consistent Rondevu branding 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,16 @@
|
|||||||
# Rondevu
|
# Rondevu
|
||||||
|
|
||||||
🎯 Meet WebRTC peers by topic, by peer ID, or by connection ID.
|
🎯 **Simple WebRTC peer signaling and discovery**
|
||||||
|
|
||||||
|
Meet peers by topic, by peer ID, or by connection ID.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## @xtr-dev/rondevu-client
|
## @xtr-dev/rondevu-client
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/@xtr-dev/rondevu-client)
|
[](https://www.npmjs.com/package/@xtr-dev/rondevu-client)
|
||||||
|
|
||||||
TypeScript Rondevu HTTP and WebRTC client, for simple peer discovery and connection.
|
TypeScript client library for Rondevu peer signaling and WebRTC connection management. Handles automatic signaling, ICE candidate exchange, and connection establishment.
|
||||||
|
|
||||||
### Install
|
### Install
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import {
|
|||||||
*/
|
*/
|
||||||
export class RondevuClient {
|
export class RondevuClient {
|
||||||
private readonly baseUrl: string;
|
private readonly baseUrl: string;
|
||||||
private readonly origin: string;
|
|
||||||
private readonly fetchImpl: typeof fetch;
|
private readonly fetchImpl: typeof fetch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,7 +27,6 @@ export class RondevuClient {
|
|||||||
*/
|
*/
|
||||||
constructor(options: RondevuClientOptions) {
|
constructor(options: RondevuClientOptions) {
|
||||||
this.baseUrl = options.baseUrl.replace(/\/$/, ''); // Remove trailing slash
|
this.baseUrl = options.baseUrl.replace(/\/$/, ''); // Remove trailing slash
|
||||||
this.origin = options.origin || new URL(this.baseUrl).origin;
|
|
||||||
this.fetchImpl = options.fetch || globalThis.fetch.bind(globalThis);
|
this.fetchImpl = options.fetch || globalThis.fetch.bind(globalThis);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,15 +35,12 @@ export class RondevuClient {
|
|||||||
*/
|
*/
|
||||||
private async request<T>(
|
private async request<T>(
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
options: RequestInit = {},
|
options: RequestInit = {}
|
||||||
customHeaders?: Record<string, string>
|
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const url = `${this.baseUrl}${endpoint}`;
|
const url = `${this.baseUrl}${endpoint}`;
|
||||||
|
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
'Origin': this.origin,
|
|
||||||
...(options.headers as Record<string, string>),
|
...(options.headers as Record<string, string>),
|
||||||
...(customHeaders || {}),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (options.body) {
|
if (options.body) {
|
||||||
@@ -144,7 +139,6 @@ export class RondevuClient {
|
|||||||
* Sends an answer or candidate to an existing session
|
* Sends an answer or candidate to an existing session
|
||||||
*
|
*
|
||||||
* @param request - Answer details including session code and signaling data
|
* @param request - Answer details including session code and signaling data
|
||||||
* @param customHeaders - Optional custom headers to send with the request
|
|
||||||
* @returns Success confirmation
|
* @returns Success confirmation
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
@@ -166,11 +160,11 @@ export class RondevuClient {
|
|||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
async sendAnswer(request: AnswerRequest, customHeaders?: Record<string, string>): Promise<AnswerResponse> {
|
async sendAnswer(request: AnswerRequest): Promise<AnswerResponse> {
|
||||||
return this.request<AnswerResponse>('/answer', {
|
return this.request<AnswerResponse>('/answer', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(request),
|
body: JSON.stringify(request),
|
||||||
}, customHeaders);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -178,7 +172,6 @@ export class RondevuClient {
|
|||||||
*
|
*
|
||||||
* @param code - Session UUID
|
* @param code - Session UUID
|
||||||
* @param side - Which side is polling ('offerer' or 'answerer')
|
* @param side - Which side is polling ('offerer' or 'answerer')
|
||||||
* @param customHeaders - Optional custom headers to send with the request
|
|
||||||
* @returns Session data including offers, answers, and candidates
|
* @returns Session data including offers, answers, and candidates
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
@@ -198,14 +191,13 @@ export class RondevuClient {
|
|||||||
*/
|
*/
|
||||||
async poll(
|
async poll(
|
||||||
code: string,
|
code: string,
|
||||||
side: Side,
|
side: Side
|
||||||
customHeaders?: Record<string, string>
|
|
||||||
): Promise<PollOffererResponse | PollAnswererResponse> {
|
): Promise<PollOffererResponse | PollAnswererResponse> {
|
||||||
const request: PollRequest = { code, side };
|
const request: PollRequest = { code, side };
|
||||||
return this.request<PollOffererResponse | PollAnswererResponse>('/poll', {
|
return this.request<PollOffererResponse | PollAnswererResponse>('/poll', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(request),
|
body: JSON.stringify(request),
|
||||||
}, customHeaders);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -21,9 +21,8 @@ export class RondevuConnection extends EventEmitter {
|
|||||||
private connectionTimer?: ReturnType<typeof setTimeout>;
|
private connectionTimer?: ReturnType<typeof setTimeout>;
|
||||||
private isPolling: boolean = false;
|
private isPolling: boolean = false;
|
||||||
private isClosed: boolean = false;
|
private isClosed: boolean = false;
|
||||||
private customHeaders?: Record<string, string>;
|
|
||||||
|
|
||||||
constructor(params: RondevuConnectionParams, client: RondevuClient, customHeaders?: Record<string, string>) {
|
constructor(params: RondevuConnectionParams, client: RondevuClient) {
|
||||||
super();
|
super();
|
||||||
this.id = params.id;
|
this.id = params.id;
|
||||||
this.topic = params.topic;
|
this.topic = params.topic;
|
||||||
@@ -35,7 +34,6 @@ export class RondevuConnection extends EventEmitter {
|
|||||||
this.dataChannels = new Map();
|
this.dataChannels = new Map();
|
||||||
this.pollingIntervalMs = params.pollingInterval;
|
this.pollingIntervalMs = params.pollingInterval;
|
||||||
this.connectionTimeoutMs = params.connectionTimeout;
|
this.connectionTimeoutMs = params.connectionTimeout;
|
||||||
this.customHeaders = customHeaders;
|
|
||||||
|
|
||||||
this.setupEventHandlers();
|
this.setupEventHandlers();
|
||||||
this.startConnectionTimeout();
|
this.startConnectionTimeout();
|
||||||
@@ -121,7 +119,7 @@ export class RondevuConnection extends EventEmitter {
|
|||||||
code: this.id,
|
code: this.id,
|
||||||
candidate: JSON.stringify(candidate.toJSON()),
|
candidate: JSON.stringify(candidate.toJSON()),
|
||||||
side: this.role,
|
side: this.role,
|
||||||
}, this.customHeaders);
|
});
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
throw new Error(`Failed to send ICE candidate: ${err.message}`);
|
throw new Error(`Failed to send ICE candidate: ${err.message}`);
|
||||||
}
|
}
|
||||||
@@ -171,7 +169,7 @@ export class RondevuConnection extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await this.client.poll(this.id, this.role, this.customHeaders);
|
const response = await this.client.poll(this.id, this.role);
|
||||||
|
|
||||||
if (this.role === 'offerer') {
|
if (this.role === 'offerer') {
|
||||||
const offererResponse = response as { answer: string | null; answerCandidates: string[] };
|
const offererResponse = response as { answer: string | null; answerCandidates: string[] };
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { RondevuClient } from './client';
|
import { RondevuClient } from './client';
|
||||||
import { RondevuConnection } from './connection';
|
import { RondevuConnection } from './connection';
|
||||||
import { RondevuOptions, JoinOptions, ConnectOptions, RondevuConnectionParams } from './types';
|
import { RondevuOptions, JoinOptions, RondevuConnectionParams } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main Rondevu WebRTC client with automatic connection management
|
* Main Rondevu WebRTC client with automatic connection management
|
||||||
@@ -25,7 +25,6 @@ export class Rondevu {
|
|||||||
|
|
||||||
this.client = new RondevuClient({
|
this.client = new RondevuClient({
|
||||||
baseUrl: this.baseUrl,
|
baseUrl: this.baseUrl,
|
||||||
origin: options.origin,
|
|
||||||
fetch: options.fetch,
|
fetch: options.fetch,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -100,17 +99,11 @@ export class Rondevu {
|
|||||||
/**
|
/**
|
||||||
* Connect to an existing connection by ID (answerer role)
|
* Connect to an existing connection by ID (answerer role)
|
||||||
* @param id - Connection identifier
|
* @param id - Connection identifier
|
||||||
* @param options - Optional connection options (e.g., { global: true } for global origin)
|
|
||||||
* @returns Promise that resolves to RondevuConnection
|
* @returns Promise that resolves to RondevuConnection
|
||||||
*/
|
*/
|
||||||
async connect(id: string, options?: ConnectOptions): Promise<RondevuConnection> {
|
async connect(id: string): Promise<RondevuConnection> {
|
||||||
// Build custom headers if global option is set
|
|
||||||
const customHeaders = options?.global
|
|
||||||
? { 'X-Rondevu-Global': 'true' }
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
// Poll server to get session by ID
|
// Poll server to get session by ID
|
||||||
const sessionData = await this.findSessionByIdWithClient(id, this.client, customHeaders);
|
const sessionData = await this.findSessionByIdWithClient(id, this.client);
|
||||||
|
|
||||||
if (!sessionData) {
|
if (!sessionData) {
|
||||||
throw new Error(`Connection ${id} not found or expired`);
|
throw new Error(`Connection ${id} not found or expired`);
|
||||||
@@ -137,7 +130,7 @@ export class Rondevu {
|
|||||||
code: id,
|
code: id,
|
||||||
answer: pc.localDescription!.sdp,
|
answer: pc.localDescription!.sdp,
|
||||||
side: 'answerer',
|
side: 'answerer',
|
||||||
}, customHeaders);
|
});
|
||||||
|
|
||||||
// Create connection object
|
// Create connection object
|
||||||
const connectionParams: RondevuConnectionParams = {
|
const connectionParams: RondevuConnectionParams = {
|
||||||
@@ -151,7 +144,7 @@ export class Rondevu {
|
|||||||
connectionTimeout: this.connectionTimeout,
|
connectionTimeout: this.connectionTimeout,
|
||||||
};
|
};
|
||||||
|
|
||||||
const connection = new RondevuConnection(connectionParams, this.client, customHeaders);
|
const connection = new RondevuConnection(connectionParams, this.client);
|
||||||
|
|
||||||
// Start polling for ICE candidates
|
// Start polling for ICE candidates
|
||||||
connection.startPolling();
|
connection.startPolling();
|
||||||
@@ -250,8 +243,7 @@ export class Rondevu {
|
|||||||
*/
|
*/
|
||||||
private async findSessionByIdWithClient(
|
private async findSessionByIdWithClient(
|
||||||
id: string,
|
id: string,
|
||||||
client: RondevuClient,
|
client: RondevuClient
|
||||||
customHeaders?: Record<string, string>
|
|
||||||
): Promise<{
|
): Promise<{
|
||||||
code: string;
|
code: string;
|
||||||
peerId: string;
|
peerId: string;
|
||||||
@@ -261,7 +253,7 @@ export class Rondevu {
|
|||||||
try {
|
try {
|
||||||
// Try to poll for the session directly
|
// Try to poll for the session directly
|
||||||
// The poll endpoint should return the session data
|
// The poll endpoint should return the session data
|
||||||
const response = await client.poll(id, 'answerer', customHeaders);
|
const response = await client.poll(id, 'answerer');
|
||||||
const answererResponse = response as { offer: string; offerCandidates: string[] };
|
const answererResponse = response as { offer: string; offerCandidates: string[] };
|
||||||
|
|
||||||
if (answererResponse.offer) {
|
if (answererResponse.offer) {
|
||||||
|
|||||||
12
src/types.ts
12
src/types.ts
@@ -161,8 +161,6 @@ export interface ErrorResponse {
|
|||||||
export interface RondevuClientOptions {
|
export interface RondevuClientOptions {
|
||||||
/** Base URL of the Rondevu server (e.g., 'https://example.com') */
|
/** Base URL of the Rondevu server (e.g., 'https://example.com') */
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
/** Origin header value for session isolation (defaults to baseUrl origin) */
|
|
||||||
origin?: string;
|
|
||||||
/** Optional fetch implementation (for Node.js environments) */
|
/** Optional fetch implementation (for Node.js environments) */
|
||||||
fetch?: typeof fetch;
|
fetch?: typeof fetch;
|
||||||
}
|
}
|
||||||
@@ -179,8 +177,6 @@ export interface RondevuOptions {
|
|||||||
baseUrl?: string;
|
baseUrl?: string;
|
||||||
/** Peer identifier (optional, auto-generated if not provided) */
|
/** Peer identifier (optional, auto-generated if not provided) */
|
||||||
peerId?: string;
|
peerId?: string;
|
||||||
/** Origin header value for session isolation (defaults to baseUrl origin) */
|
|
||||||
origin?: string;
|
|
||||||
/** Optional fetch implementation (for Node.js environments) */
|
/** Optional fetch implementation (for Node.js environments) */
|
||||||
fetch?: typeof fetch;
|
fetch?: typeof fetch;
|
||||||
/** WebRTC configuration (ICE servers, etc.) */
|
/** WebRTC configuration (ICE servers, etc.) */
|
||||||
@@ -191,14 +187,6 @@ export interface RondevuOptions {
|
|||||||
connectionTimeout?: number;
|
connectionTimeout?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Options for connecting to a session
|
|
||||||
*/
|
|
||||||
export interface ConnectOptions {
|
|
||||||
/** Use global origin (https://ronde.vu) instead of request origin for session isolation */
|
|
||||||
global?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Options for joining a topic
|
* Options for joining a topic
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user