@xtr-dev/rondevu-client 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Rondevu
2
2
 
3
- 🎯 **Simple WebRTC peer signaling and discovery**
3
+ 🎯 **Simple WebRTC peer signaling**
4
4
 
5
- Meet peers by topic, by peer ID, or by connection ID.
5
+ Connect peers directly by ID with automatic WebRTC negotiation.
6
6
 
7
7
  **Related repositories:**
8
8
  - [rondevu-server](https://github.com/xtr-dev/rondevu-server) - HTTP signaling server
@@ -30,68 +30,57 @@ npm install @xtr-dev/rondevu-client
30
30
  import { Rondevu } from '@xtr-dev/rondevu-client';
31
31
 
32
32
  const rdv = new Rondevu({
33
- baseUrl: 'https://server.com',
33
+ baseUrl: 'https://api.ronde.vu',
34
34
  rtcConfig: {
35
35
  iceServers: [
36
- // your ICE servers here
37
36
  { urls: 'stun:stun.l.google.com:19302' },
38
- { urls: 'stun:stun1.l.google.com:19302' },
39
- {
40
- urls: 'turn:relay1.example.com:3480',
41
- username: 'example',
42
- credential: 'example'
43
- }
37
+ { urls: 'stun:stun1.l.google.com:19302' }
44
38
  ]
45
39
  }
46
40
  });
47
41
 
48
- // Connect by topic
49
- const conn = await rdv.join('room');
42
+ // Create a connection with custom ID
43
+ const connection = await rdv.create('my-room-123');
50
44
 
51
- // Or connect by ID
52
- const conn = await rdv.connect('meeting-123');
45
+ // Or connect to an existing connection
46
+ const connection = await rdv.connect('my-room-123');
53
47
 
54
- // Use the connection
55
- conn.on('connect', () => {
56
- const channel = conn.dataChannel('chat');
48
+ // Use data channels
49
+ connection.on('connect', () => {
50
+ const channel = connection.dataChannel('chat');
57
51
  channel.send('Hello!');
58
52
  });
53
+
54
+ connection.on('datachannel', (channel) => {
55
+ if (channel.label === 'chat') {
56
+ channel.onmessage = (event) => {
57
+ console.log('Received:', event.data);
58
+ };
59
+ }
60
+ });
59
61
  ```
60
62
 
61
63
  #### Node.js
62
64
 
63
- In Node.js, you need to provide a WebRTC polyfill since WebRTC APIs are not natively available:
64
-
65
- ```bash
66
- npm install @roamhq/wrtc
67
- # or
68
- npm install wrtc
69
- ```
70
-
71
65
  ```typescript
72
66
  import { Rondevu } from '@xtr-dev/rondevu-client';
73
67
  import wrtc from '@roamhq/wrtc';
74
68
  import fetch from 'node-fetch';
75
69
 
76
70
  const rdv = new Rondevu({
77
- baseUrl: 'https://server.com',
71
+ baseUrl: 'https://api.ronde.vu',
78
72
  fetch: fetch as any,
79
73
  wrtc: {
80
74
  RTCPeerConnection: wrtc.RTCPeerConnection,
81
75
  RTCSessionDescription: wrtc.RTCSessionDescription,
82
76
  RTCIceCandidate: wrtc.RTCIceCandidate,
83
- },
84
- rtcConfig: {
85
- iceServers: [
86
- { urls: 'stun:stun.l.google.com:19302' }
87
- ]
88
77
  }
89
78
  });
90
79
 
91
- // Rest is the same as browser usage
92
- const conn = await rdv.join('room');
93
- conn.on('connect', () => {
94
- const channel = conn.dataChannel('chat');
80
+ const connection = await rdv.create('my-room-123');
81
+
82
+ connection.on('connect', () => {
83
+ const channel = connection.dataChannel('chat');
95
84
  channel.send('Hello from Node.js!');
96
85
  });
97
86
  ```
@@ -99,23 +88,24 @@ conn.on('connect', () => {
99
88
  ### API
100
89
 
101
90
  **Main Methods:**
102
- - `rdv.join(topic)` - Auto-connect to first peer in topic
103
- - `rdv.join(topic, {filter})` - Connect to specific peer by ID
104
- - `rdv.create(id, topic)` - Create connection for others to join
105
- - `rdv.connect(id)` - Join connection by ID
91
+ - `rdv.create(id)` - Create connection with custom ID
92
+ - `rdv.connect(id)` - Connect to existing connection by ID
106
93
 
107
94
  **Connection Events:**
108
95
  - `connect` - Connection established
109
96
  - `disconnect` - Connection closed
110
- - `datachannel` - Remote peer created data channel
111
- - `stream` - Remote media stream received
112
- - `error` - Error occurred
97
+ - `error` - Connection error
98
+ - `datachannel` - New data channel received
99
+ - `stream` - Media stream received
113
100
 
114
101
  **Connection Methods:**
115
- - `conn.dataChannel(label)` - Get or create data channel
116
- - `conn.addStream(stream)` - Add media stream
117
- - `conn.getPeerConnection()` - Get underlying RTCPeerConnection
118
- - `conn.close()` - Close connection
102
+ - `connection.dataChannel(label)` - Get or create data channel
103
+ - `connection.addStream(stream)` - Add media stream
104
+ - `connection.close()` - Close connection
105
+
106
+ ### Version Compatibility
107
+
108
+ The client automatically checks server compatibility via the `/health` endpoint. If the server version is incompatible, an error will be thrown during initialization.
119
109
 
120
110
  ### License
121
111
 
package/dist/client.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { RondevuClientOptions, ListTopicsResponse, ListSessionsResponse, CreateOfferRequest, CreateOfferResponse, AnswerRequest, AnswerResponse, PollOffererResponse, PollAnswererResponse, VersionResponse, HealthResponse, Side } from './types.js';
1
+ import { RondevuClientOptions, CreateOfferRequest, CreateOfferResponse, AnswerRequest, AnswerResponse, PollOffererResponse, PollAnswererResponse, VersionResponse, HealthResponse, Side } from './types.js';
2
2
  /**
3
- * HTTP API client for Rondevu peer signaling and discovery server
3
+ * HTTP API client for Rondevu peer signaling server
4
4
  */
5
5
  export declare class RondevuAPI {
6
6
  private readonly baseUrl;
@@ -17,7 +17,7 @@ export declare class RondevuAPI {
17
17
  /**
18
18
  * Gets server version information
19
19
  *
20
- * @returns Server version (git commit hash)
20
+ * @returns Server version
21
21
  *
22
22
  * @example
23
23
  * ```typescript
@@ -28,56 +28,27 @@ export declare class RondevuAPI {
28
28
  */
29
29
  getVersion(): Promise<VersionResponse>;
30
30
  /**
31
- * Lists all topics with peer counts
31
+ * Creates a new offer
32
32
  *
33
- * @param page - Page number (starting from 1)
34
- * @param limit - Results per page (max 1000)
35
- * @returns List of topics with pagination info
33
+ * @param request - Offer details including peer ID, signaling data, and optional custom code
34
+ * @returns Unique offer code (UUID or custom code)
36
35
  *
37
36
  * @example
38
37
  * ```typescript
39
38
  * const api = new RondevuAPI({ baseUrl: 'https://example.com' });
40
- * const { topics, pagination } = await api.listTopics();
41
- * console.log(`Found ${topics.length} topics`);
42
- * ```
43
- */
44
- listTopics(page?: number, limit?: number): Promise<ListTopicsResponse>;
45
- /**
46
- * Discovers available peers for a given topic
47
- *
48
- * @param topic - Topic identifier
49
- * @returns List of available sessions
50
- *
51
- * @example
52
- * ```typescript
53
- * const api = new RondevuAPI({ baseUrl: 'https://example.com' });
54
- * const { sessions } = await api.listSessions('my-room');
55
- * const otherPeers = sessions.filter(s => s.peerId !== myPeerId);
56
- * ```
57
- */
58
- listSessions(topic: string): Promise<ListSessionsResponse>;
59
- /**
60
- * Announces peer availability and creates a new session
61
- *
62
- * @param topic - Topic identifier for grouping peers (max 1024 characters)
63
- * @param request - Offer details including peer ID and signaling data
64
- * @returns Unique session code (UUID)
65
- *
66
- * @example
67
- * ```typescript
68
- * const api = new RondevuAPI({ baseUrl: 'https://example.com' });
69
- * const { code } = await api.createOffer('my-room', {
39
+ * const { code } = await api.createOffer({
70
40
  * peerId: 'peer-123',
71
- * offer: signalingData
41
+ * offer: signalingData,
42
+ * code: 'my-custom-code' // optional
72
43
  * });
73
- * console.log('Session code:', code);
44
+ * console.log('Offer code:', code);
74
45
  * ```
75
46
  */
76
- createOffer(topic: string, request: CreateOfferRequest): Promise<CreateOfferResponse>;
47
+ createOffer(request: CreateOfferRequest): Promise<CreateOfferResponse>;
77
48
  /**
78
- * Sends an answer or candidate to an existing session
49
+ * Sends an answer or candidate to an existing offer
79
50
  *
80
- * @param request - Answer details including session code and signaling data
51
+ * @param request - Answer details including offer code and signaling data
81
52
  * @returns Success confirmation
82
53
  *
83
54
  * @example
@@ -86,14 +57,14 @@ export declare class RondevuAPI {
86
57
  *
87
58
  * // Send answer
88
59
  * await api.sendAnswer({
89
- * code: sessionCode,
60
+ * code: offerCode,
90
61
  * answer: answerData,
91
62
  * side: 'answerer'
92
63
  * });
93
64
  *
94
65
  * // Send candidate
95
66
  * await api.sendAnswer({
96
- * code: sessionCode,
67
+ * code: offerCode,
97
68
  * candidate: candidateData,
98
69
  * side: 'offerer'
99
70
  * });
@@ -101,38 +72,39 @@ export declare class RondevuAPI {
101
72
  */
102
73
  sendAnswer(request: AnswerRequest): Promise<AnswerResponse>;
103
74
  /**
104
- * Polls for session data from the other peer
75
+ * Polls for offer data from the other peer
105
76
  *
106
- * @param code - Session UUID
77
+ * @param code - Offer code
107
78
  * @param side - Which side is polling ('offerer' or 'answerer')
108
- * @returns Session data including offers, answers, and candidates
79
+ * @returns Offer data including offers, answers, and candidates
109
80
  *
110
81
  * @example
111
82
  * ```typescript
112
83
  * const api = new RondevuAPI({ baseUrl: 'https://example.com' });
113
84
  *
114
85
  * // Offerer polls for answer
115
- * const offererData = await api.poll(sessionCode, 'offerer');
86
+ * const offererData = await api.poll(offerCode, 'offerer');
116
87
  * if (offererData.answer) {
117
88
  * console.log('Received answer:', offererData.answer);
118
89
  * }
119
90
  *
120
91
  * // Answerer polls for offer
121
- * const answererData = await api.poll(sessionCode, 'answerer');
92
+ * const answererData = await api.poll(offerCode, 'answerer');
122
93
  * console.log('Received offer:', answererData.offer);
123
94
  * ```
124
95
  */
125
96
  poll(code: string, side: Side): Promise<PollOffererResponse | PollAnswererResponse>;
126
97
  /**
127
- * Checks server health
98
+ * Checks server health and version
128
99
  *
129
- * @returns Health status and timestamp
100
+ * @returns Health status, timestamp, and version
130
101
  *
131
102
  * @example
132
103
  * ```typescript
133
104
  * const api = new RondevuAPI({ baseUrl: 'https://example.com' });
134
105
  * const health = await api.health();
135
106
  * console.log('Server status:', health.status);
107
+ * console.log('Server version:', health.version);
136
108
  * ```
137
109
  */
138
110
  health(): Promise<HealthResponse>;
package/dist/client.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * HTTP API client for Rondevu peer signaling and discovery server
2
+ * HTTP API client for Rondevu peer signaling server
3
3
  */
4
4
  export class RondevuAPI {
5
5
  /**
@@ -35,7 +35,7 @@ export class RondevuAPI {
35
35
  /**
36
36
  * Gets server version information
37
37
  *
38
- * @returns Server version (git commit hash)
38
+ * @returns Server version
39
39
  *
40
40
  * @example
41
41
  * ```typescript
@@ -50,73 +50,32 @@ export class RondevuAPI {
50
50
  });
51
51
  }
52
52
  /**
53
- * Lists all topics with peer counts
53
+ * Creates a new offer
54
54
  *
55
- * @param page - Page number (starting from 1)
56
- * @param limit - Results per page (max 1000)
57
- * @returns List of topics with pagination info
55
+ * @param request - Offer details including peer ID, signaling data, and optional custom code
56
+ * @returns Unique offer code (UUID or custom code)
58
57
  *
59
58
  * @example
60
59
  * ```typescript
61
60
  * const api = new RondevuAPI({ baseUrl: 'https://example.com' });
62
- * const { topics, pagination } = await api.listTopics();
63
- * console.log(`Found ${topics.length} topics`);
64
- * ```
65
- */
66
- async listTopics(page = 1, limit = 100) {
67
- const params = new URLSearchParams({
68
- page: page.toString(),
69
- limit: limit.toString(),
70
- });
71
- return this.request(`/topics?${params}`, {
72
- method: 'GET',
73
- });
74
- }
75
- /**
76
- * Discovers available peers for a given topic
77
- *
78
- * @param topic - Topic identifier
79
- * @returns List of available sessions
80
- *
81
- * @example
82
- * ```typescript
83
- * const api = new RondevuAPI({ baseUrl: 'https://example.com' });
84
- * const { sessions } = await api.listSessions('my-room');
85
- * const otherPeers = sessions.filter(s => s.peerId !== myPeerId);
86
- * ```
87
- */
88
- async listSessions(topic) {
89
- return this.request(`/${encodeURIComponent(topic)}/sessions`, {
90
- method: 'GET',
91
- });
92
- }
93
- /**
94
- * Announces peer availability and creates a new session
95
- *
96
- * @param topic - Topic identifier for grouping peers (max 1024 characters)
97
- * @param request - Offer details including peer ID and signaling data
98
- * @returns Unique session code (UUID)
99
- *
100
- * @example
101
- * ```typescript
102
- * const api = new RondevuAPI({ baseUrl: 'https://example.com' });
103
- * const { code } = await api.createOffer('my-room', {
61
+ * const { code } = await api.createOffer({
104
62
  * peerId: 'peer-123',
105
- * offer: signalingData
63
+ * offer: signalingData,
64
+ * code: 'my-custom-code' // optional
106
65
  * });
107
- * console.log('Session code:', code);
66
+ * console.log('Offer code:', code);
108
67
  * ```
109
68
  */
110
- async createOffer(topic, request) {
111
- return this.request(`/${encodeURIComponent(topic)}/offer`, {
69
+ async createOffer(request) {
70
+ return this.request('/offer', {
112
71
  method: 'POST',
113
72
  body: JSON.stringify(request),
114
73
  });
115
74
  }
116
75
  /**
117
- * Sends an answer or candidate to an existing session
76
+ * Sends an answer or candidate to an existing offer
118
77
  *
119
- * @param request - Answer details including session code and signaling data
78
+ * @param request - Answer details including offer code and signaling data
120
79
  * @returns Success confirmation
121
80
  *
122
81
  * @example
@@ -125,14 +84,14 @@ export class RondevuAPI {
125
84
  *
126
85
  * // Send answer
127
86
  * await api.sendAnswer({
128
- * code: sessionCode,
87
+ * code: offerCode,
129
88
  * answer: answerData,
130
89
  * side: 'answerer'
131
90
  * });
132
91
  *
133
92
  * // Send candidate
134
93
  * await api.sendAnswer({
135
- * code: sessionCode,
94
+ * code: offerCode,
136
95
  * candidate: candidateData,
137
96
  * side: 'offerer'
138
97
  * });
@@ -145,24 +104,24 @@ export class RondevuAPI {
145
104
  });
146
105
  }
147
106
  /**
148
- * Polls for session data from the other peer
107
+ * Polls for offer data from the other peer
149
108
  *
150
- * @param code - Session UUID
109
+ * @param code - Offer code
151
110
  * @param side - Which side is polling ('offerer' or 'answerer')
152
- * @returns Session data including offers, answers, and candidates
111
+ * @returns Offer data including offers, answers, and candidates
153
112
  *
154
113
  * @example
155
114
  * ```typescript
156
115
  * const api = new RondevuAPI({ baseUrl: 'https://example.com' });
157
116
  *
158
117
  * // Offerer polls for answer
159
- * const offererData = await api.poll(sessionCode, 'offerer');
118
+ * const offererData = await api.poll(offerCode, 'offerer');
160
119
  * if (offererData.answer) {
161
120
  * console.log('Received answer:', offererData.answer);
162
121
  * }
163
122
  *
164
123
  * // Answerer polls for offer
165
- * const answererData = await api.poll(sessionCode, 'answerer');
124
+ * const answererData = await api.poll(offerCode, 'answerer');
166
125
  * console.log('Received offer:', answererData.offer);
167
126
  * ```
168
127
  */
@@ -174,15 +133,16 @@ export class RondevuAPI {
174
133
  });
175
134
  }
176
135
  /**
177
- * Checks server health
136
+ * Checks server health and version
178
137
  *
179
- * @returns Health status and timestamp
138
+ * @returns Health status, timestamp, and version
180
139
  *
181
140
  * @example
182
141
  * ```typescript
183
142
  * const api = new RondevuAPI({ baseUrl: 'https://example.com' });
184
143
  * const health = await api.health();
185
144
  * console.log('Server status:', health.status);
145
+ * console.log('Server version:', health.version);
186
146
  * ```
187
147
  */
188
148
  async health() {
@@ -6,7 +6,6 @@ import { RondevuConnectionParams } from './types.js';
6
6
  */
7
7
  export declare class RondevuConnection extends EventEmitter {
8
8
  readonly id: string;
9
- readonly topic: string;
10
9
  readonly role: 'offerer' | 'answerer';
11
10
  readonly remotePeerId: string;
12
11
  private pc;
@@ -8,7 +8,6 @@ export class RondevuConnection extends EventEmitter {
8
8
  this.isPolling = false;
9
9
  this.isClosed = false;
10
10
  this.id = params.id;
11
- this.topic = params.topic;
12
11
  this.role = params.role;
13
12
  this.pc = params.pc;
14
13
  this.localPeerId = params.localPeerId;
package/dist/index.d.ts CHANGED
@@ -5,4 +5,4 @@
5
5
  export { Rondevu } from './rondevu.js';
6
6
  export { RondevuConnection } from './connection.js';
7
7
  export { RondevuAPI } from './client.js';
8
- export type { RondevuOptions, JoinOptions, ConnectionRole, RondevuConnectionParams, RondevuConnectionEvents, WebRTCPolyfill, Side, Session, TopicInfo, Pagination, ListTopicsResponse, ListSessionsResponse, CreateOfferRequest, CreateOfferResponse, AnswerRequest, AnswerResponse, PollRequest, PollOffererResponse, PollAnswererResponse, PollResponse, VersionResponse, HealthResponse, ErrorResponse, RondevuClientOptions, } from './types.js';
8
+ export type { RondevuOptions, ConnectionRole, RondevuConnectionParams, RondevuConnectionEvents, WebRTCPolyfill, Side, CreateOfferRequest, CreateOfferResponse, AnswerRequest, AnswerResponse, PollRequest, PollOffererResponse, PollAnswererResponse, PollResponse, VersionResponse, HealthResponse, ErrorResponse, RondevuClientOptions, } from './types.js';
package/dist/rondevu.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { RondevuAPI } from './client.js';
2
2
  import { RondevuConnection } from './connection.js';
3
- import { RondevuOptions, JoinOptions } from './types.js';
3
+ import { RondevuOptions } from './types.js';
4
4
  /**
5
5
  * Main Rondevu WebRTC client with automatic connection management
6
6
  */
@@ -20,6 +20,15 @@ export declare class Rondevu {
20
20
  * @param options - Client configuration options
21
21
  */
22
22
  constructor(options?: RondevuOptions);
23
+ /**
24
+ * Check server version compatibility
25
+ */
26
+ private checkServerVersion;
27
+ /**
28
+ * Check if client and server versions are compatible
29
+ * For now, just check major version compatibility
30
+ */
31
+ private isVersionCompatible;
23
32
  /**
24
33
  * Generate a unique peer ID
25
34
  */
@@ -30,35 +39,22 @@ export declare class Rondevu {
30
39
  updatePeerId(newPeerId: string): void;
31
40
  /**
32
41
  * Create a new connection (offerer role)
33
- * @param id - Connection identifier
34
- * @param topic - Topic name for grouping connections
42
+ * @param id - Connection identifier (custom code)
35
43
  * @returns Promise that resolves to RondevuConnection
36
44
  */
37
- create(id: string, topic: string): Promise<RondevuConnection>;
45
+ create(id: string): Promise<RondevuConnection>;
38
46
  /**
39
- * Connect to an existing connection by ID (answerer role)
40
- * @param id - Connection identifier
47
+ * Connect to an existing offer by ID (answerer role)
48
+ * @param id - Offer code
41
49
  * @returns Promise that resolves to RondevuConnection
42
50
  */
43
51
  connect(id: string): Promise<RondevuConnection>;
44
- /**
45
- * Join a topic and discover available peers (answerer role)
46
- * @param topic - Topic name
47
- * @param options - Optional join options for filtering and selection
48
- * @returns Promise that resolves to RondevuConnection
49
- */
50
- join(topic: string, options?: JoinOptions): Promise<RondevuConnection>;
51
- /**
52
- * Select a session based on strategy
53
- */
54
- private selectSession;
55
52
  /**
56
53
  * Wait for ICE gathering to complete
57
54
  */
58
55
  private waitForIceGathering;
59
56
  /**
60
- * Find a session by connection ID
61
- * This requires polling since we don't know which topic it's in
57
+ * Find an offer by code
62
58
  */
63
- private findSessionByIdWithClient;
59
+ private findOfferById;
64
60
  }
package/dist/rondevu.js CHANGED
@@ -9,7 +9,7 @@ export class Rondevu {
9
9
  * @param options - Client configuration options
10
10
  */
11
11
  constructor(options = {}) {
12
- this.baseUrl = options.baseUrl || 'https://rondevu.xtrdev.workers.dev';
12
+ this.baseUrl = options.baseUrl || 'https://api.ronde.vu';
13
13
  this.fetchImpl = options.fetch;
14
14
  this.wrtc = options.wrtc;
15
15
  this.api = new RondevuAPI({
@@ -29,6 +29,37 @@ export class Rondevu {
29
29
  'In Node.js, provide a WebRTC polyfill via the wrtc option. ' +
30
30
  'Install: npm install @roamhq/wrtc or npm install wrtc');
31
31
  }
32
+ // Check server version compatibility (async, don't block constructor)
33
+ this.checkServerVersion().catch(() => {
34
+ // Silently fail version check - connection will work even if version check fails
35
+ });
36
+ }
37
+ /**
38
+ * Check server version compatibility
39
+ */
40
+ async checkServerVersion() {
41
+ try {
42
+ const { version: serverVersion } = await this.api.health();
43
+ const clientVersion = '0.3.2'; // Should match package.json
44
+ if (!this.isVersionCompatible(clientVersion, serverVersion)) {
45
+ console.warn(`[Rondevu] Version mismatch: client v${clientVersion}, server v${serverVersion}. ` +
46
+ 'This may cause compatibility issues.');
47
+ }
48
+ }
49
+ catch (error) {
50
+ // Version check failed - server might not support /health endpoint
51
+ console.debug('[Rondevu] Could not check server version');
52
+ }
53
+ }
54
+ /**
55
+ * Check if client and server versions are compatible
56
+ * For now, just check major version compatibility
57
+ */
58
+ isVersionCompatible(clientVersion, serverVersion) {
59
+ const clientMajor = parseInt(clientVersion.split('.')[0]);
60
+ const serverMajor = parseInt(serverVersion.split('.')[0]);
61
+ // Major versions must match
62
+ return clientMajor === serverMajor;
32
63
  }
33
64
  /**
34
65
  * Generate a unique peer ID
@@ -44,11 +75,10 @@ export class Rondevu {
44
75
  }
45
76
  /**
46
77
  * Create a new connection (offerer role)
47
- * @param id - Connection identifier
48
- * @param topic - Topic name for grouping connections
78
+ * @param id - Connection identifier (custom code)
49
79
  * @returns Promise that resolves to RondevuConnection
50
80
  */
51
- async create(id, topic) {
81
+ async create(id) {
52
82
  // Create peer connection
53
83
  const pc = new this.RTCPeerConnection(this.rtcConfig);
54
84
  // Create initial data channel for negotiation (required for offer creation)
@@ -58,8 +88,8 @@ export class Rondevu {
58
88
  await pc.setLocalDescription(offer);
59
89
  // Wait for ICE gathering to complete
60
90
  await this.waitForIceGathering(pc);
61
- // Create session on server with custom code
62
- await this.api.createOffer(topic, {
91
+ // Create offer on server with custom code
92
+ await this.api.createOffer({
63
93
  peerId: this.peerId,
64
94
  offer: pc.localDescription.sdp,
65
95
  code: id,
@@ -67,7 +97,6 @@ export class Rondevu {
67
97
  // Create connection object
68
98
  const connectionParams = {
69
99
  id,
70
- topic,
71
100
  role: 'offerer',
72
101
  pc,
73
102
  localPeerId: this.peerId,
@@ -82,22 +111,22 @@ export class Rondevu {
82
111
  return connection;
83
112
  }
84
113
  /**
85
- * Connect to an existing connection by ID (answerer role)
86
- * @param id - Connection identifier
114
+ * Connect to an existing offer by ID (answerer role)
115
+ * @param id - Offer code
87
116
  * @returns Promise that resolves to RondevuConnection
88
117
  */
89
118
  async connect(id) {
90
- // Poll server to get session by ID
91
- const sessionData = await this.findSessionByIdWithClient(id, this.api);
92
- if (!sessionData) {
93
- throw new Error(`Connection ${id} not found or expired`);
119
+ // Poll server to get offer by ID
120
+ const offerData = await this.findOfferById(id);
121
+ if (!offerData) {
122
+ throw new Error(`Offer ${id} not found or expired`);
94
123
  }
95
124
  // Create peer connection
96
125
  const pc = new this.RTCPeerConnection(this.rtcConfig);
97
126
  // Set remote offer
98
127
  await pc.setRemoteDescription({
99
128
  type: 'offer',
100
- sdp: sessionData.offer,
129
+ sdp: offerData.offer,
101
130
  });
102
131
  // Generate answer
103
132
  const answer = await pc.createAnswer();
@@ -113,11 +142,10 @@ export class Rondevu {
113
142
  // Create connection object
114
143
  const connectionParams = {
115
144
  id,
116
- topic: sessionData.topic || 'unknown',
117
145
  role: 'answerer',
118
146
  pc,
119
147
  localPeerId: this.peerId,
120
- remotePeerId: sessionData.peerId,
148
+ remotePeerId: '', // Will be determined from peerId in offer
121
149
  pollingInterval: this.pollingInterval,
122
150
  connectionTimeout: this.connectionTimeout,
123
151
  wrtc: this.wrtc,
@@ -127,46 +155,6 @@ export class Rondevu {
127
155
  connection.startPolling();
128
156
  return connection;
129
157
  }
130
- /**
131
- * Join a topic and discover available peers (answerer role)
132
- * @param topic - Topic name
133
- * @param options - Optional join options for filtering and selection
134
- * @returns Promise that resolves to RondevuConnection
135
- */
136
- async join(topic, options) {
137
- // List sessions in topic
138
- const { sessions } = await this.api.listSessions(topic);
139
- // Filter out self (sessions with our peer ID)
140
- let availableSessions = sessions.filter(session => session.peerId !== this.peerId);
141
- // Apply custom filter if provided
142
- if (options?.filter) {
143
- availableSessions = availableSessions.filter(options.filter);
144
- }
145
- if (availableSessions.length === 0) {
146
- throw new Error(`No available peers in topic: ${topic}`);
147
- }
148
- // Select session based on strategy
149
- const selectedSession = this.selectSession(availableSessions, options?.select || 'first');
150
- // Connect to selected session
151
- return this.connect(selectedSession.code);
152
- }
153
- /**
154
- * Select a session based on strategy
155
- */
156
- selectSession(sessions, strategy) {
157
- switch (strategy) {
158
- case 'first':
159
- return sessions[0];
160
- case 'newest':
161
- return sessions.reduce((newest, session) => session.createdAt > newest.createdAt ? session : newest);
162
- case 'oldest':
163
- return sessions.reduce((oldest, session) => session.createdAt < oldest.createdAt ? session : oldest);
164
- case 'random':
165
- return sessions[Math.floor(Math.random() * sessions.length)];
166
- default:
167
- return sessions[0];
168
- }
169
- }
170
158
  /**
171
159
  * Wait for ICE gathering to complete
172
160
  */
@@ -190,27 +178,22 @@ export class Rondevu {
190
178
  });
191
179
  }
192
180
  /**
193
- * Find a session by connection ID
194
- * This requires polling since we don't know which topic it's in
181
+ * Find an offer by code
195
182
  */
196
- async findSessionByIdWithClient(id, client) {
183
+ async findOfferById(id) {
197
184
  try {
198
- // Try to poll for the session directly
199
- // The poll endpoint should return the session data
200
- const response = await client.poll(id, 'answerer');
185
+ // Poll for the offer directly
186
+ const response = await this.api.poll(id, 'answerer');
201
187
  const answererResponse = response;
202
188
  if (answererResponse.offer) {
203
189
  return {
204
- code: id,
205
- peerId: '', // Will be populated from session data
206
190
  offer: answererResponse.offer,
207
- topic: undefined,
208
191
  };
209
192
  }
210
193
  return null;
211
194
  }
212
195
  catch (err) {
213
- throw new Error(`Failed to find session ${id}: ${err.message}`);
196
+ throw new Error(`Failed to find offer ${id}: ${err.message}`);
214
197
  }
215
198
  }
216
199
  }
package/dist/types.d.ts CHANGED
@@ -3,59 +3,7 @@
3
3
  */
4
4
  export type Side = 'offerer' | 'answerer';
5
5
  /**
6
- * Session information returned from discovery endpoints
7
- */
8
- export interface Session {
9
- /** Unique session identifier (UUID) */
10
- code: string;
11
- /** Peer identifier/metadata */
12
- peerId: string;
13
- /** Signaling data for peer connection */
14
- offer: string;
15
- /** Additional signaling data from offerer */
16
- offerCandidates: string[];
17
- /** Unix timestamp when session was created */
18
- createdAt: number;
19
- /** Unix timestamp when session expires */
20
- expiresAt: number;
21
- }
22
- /**
23
- * Topic information with peer count
24
- */
25
- export interface TopicInfo {
26
- /** Topic identifier */
27
- topic: string;
28
- /** Number of available peers in this topic */
29
- count: number;
30
- }
31
- /**
32
- * Pagination information
33
- */
34
- export interface Pagination {
35
- /** Current page number */
36
- page: number;
37
- /** Results per page */
38
- limit: number;
39
- /** Total number of results */
40
- total: number;
41
- /** Whether there are more results available */
42
- hasMore: boolean;
43
- }
44
- /**
45
- * Response from GET / - list all topics
46
- */
47
- export interface ListTopicsResponse {
48
- topics: TopicInfo[];
49
- pagination: Pagination;
50
- }
51
- /**
52
- * Response from GET /:topic/sessions - list sessions in a topic
53
- */
54
- export interface ListSessionsResponse {
55
- sessions: Session[];
56
- }
57
- /**
58
- * Request body for POST /:topic/offer
6
+ * Request body for POST /offer
59
7
  */
60
8
  export interface CreateOfferRequest {
61
9
  /** Peer identifier/metadata (max 1024 characters) */
@@ -66,7 +14,7 @@ export interface CreateOfferRequest {
66
14
  code?: string;
67
15
  }
68
16
  /**
69
- * Response from POST /:topic/offer
17
+ * Response from POST /offer
70
18
  */
71
19
  export interface CreateOfferResponse {
72
20
  /** Unique session identifier (UUID) */
@@ -135,6 +83,7 @@ export interface VersionResponse {
135
83
  export interface HealthResponse {
136
84
  status: 'ok';
137
85
  timestamp: number;
86
+ version: string;
138
87
  }
139
88
  /**
140
89
  * Error response structure
@@ -163,7 +112,7 @@ export interface WebRTCPolyfill {
163
112
  * Configuration options for Rondevu WebRTC client
164
113
  */
165
114
  export interface RondevuOptions {
166
- /** Base URL of the Rondevu server (defaults to 'https://rondevu.xtrdev.workers.dev') */
115
+ /** Base URL of the Rondevu server (defaults to 'https://api.ronde.vu') */
167
116
  baseUrl?: string;
168
117
  /** Peer identifier (optional, auto-generated if not provided) */
169
118
  peerId?: string;
@@ -178,18 +127,6 @@ export interface RondevuOptions {
178
127
  /** WebRTC polyfill for Node.js (e.g., wrtc or @roamhq/wrtc) */
179
128
  wrtc?: WebRTCPolyfill;
180
129
  }
181
- /**
182
- * Options for joining a topic
183
- */
184
- export interface JoinOptions {
185
- /** Filter function to select specific sessions */
186
- filter?: (session: {
187
- code: string;
188
- peerId: string;
189
- }) => boolean;
190
- /** Selection strategy for choosing a session */
191
- select?: 'first' | 'newest' | 'oldest' | 'random';
192
- }
193
130
  /**
194
131
  * Connection role - whether this peer is creating or answering
195
132
  */
@@ -199,7 +136,7 @@ export type ConnectionRole = 'offerer' | 'answerer';
199
136
  */
200
137
  export interface RondevuConnectionParams {
201
138
  id: string;
202
- topic: string;
139
+ topic?: string;
203
140
  role: ConnectionRole;
204
141
  pc: RTCPeerConnection;
205
142
  localPeerId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xtr-dev/rondevu-client",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "TypeScript client for Rondevu peer signaling and discovery server",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",