uniwrtc 1.5.0 → 1.7.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uniwrtc",
3
- "version": "1.5.0",
3
+ "version": "1.7.0",
4
4
  "description": "A universal WebRTC signaling service",
5
5
  "main": "server.js",
6
6
  "type": "module",
package/src/main.js CHANGED
@@ -171,6 +171,25 @@ if (ICE_SERVERS.length === 0) {
171
171
  }
172
172
 
173
173
  function log(message, type = 'info') {
174
+ // Reduce noise in the Activity Log by default.
175
+ // Use ?debug=1 to see everything.
176
+ const debugMode = (params.get('debug') || '').toLowerCase();
177
+ const noisy =
178
+ message.startsWith('Dropped ') ||
179
+ message.startsWith('ICE state (') ||
180
+ message.startsWith('Conn state (') ||
181
+ message.startsWith('Relay NOTICE') ||
182
+ message.includes('Failed to add ICE candidate') ||
183
+ message.includes('Failed to add queued ICE candidate') ||
184
+ message.includes('Failed to send ICE batch') ||
185
+ message.startsWith('Disconnected');
186
+
187
+ if (noisy && debugMode !== '1' && debugMode !== 'true') {
188
+ // Keep available for debugging without spamming the UI.
189
+ console.debug(message);
190
+ return;
191
+ }
192
+
174
193
  const logContainer = document.getElementById('logContainer');
175
194
  const entry = document.createElement('div');
176
195
  entry.className = `log-entry ${type}`;
@@ -213,16 +232,37 @@ function updateStatus(connected) {
213
232
 
214
233
  function updatePeerList() {
215
234
  const peerList = document.getElementById('peerList');
216
- if (peerConnections.size === 0) {
235
+ if (!peerList) return;
236
+
237
+ const connectedPeerIds = [];
238
+ for (const [peerId, pc] of peerConnections.entries()) {
239
+ if (!(pc instanceof RTCPeerConnection)) continue;
240
+
241
+ // Prefer data channel state when available.
242
+ const dc = dataChannels.get(peerId);
243
+ const hasOpenDataChannel = dc && dc.readyState === 'open';
244
+
245
+ const connState = pc.connectionState;
246
+ const isActive = connState === 'connected' || connState === 'connecting' || hasOpenDataChannel;
247
+
248
+ // Explicitly hide failed/disconnected/closed peers.
249
+ if (!isActive) continue;
250
+ if (connState === 'failed' || connState === 'disconnected' || connState === 'closed') continue;
251
+
252
+ connectedPeerIds.push(peerId);
253
+ }
254
+
255
+ if (connectedPeerIds.length === 0) {
217
256
  peerList.innerHTML = '<p style="color: #94a3b8;">No peers connected</p>';
218
- } else {
219
- peerList.innerHTML = '';
220
- peerConnections.forEach((pc, peerId) => {
221
- const peerItem = document.createElement('div');
222
- peerItem.className = 'peer-item';
223
- peerItem.textContent = peerId.substring(0, 8) + '...';
224
- peerList.appendChild(peerItem);
225
- });
257
+ return;
258
+ }
259
+
260
+ peerList.innerHTML = '';
261
+ for (const peerId of connectedPeerIds) {
262
+ const peerItem = document.createElement('div');
263
+ peerItem.className = 'peer-item';
264
+ peerItem.textContent = peerId.substring(0, 8) + '...';
265
+ peerList.appendChild(peerItem);
226
266
  }
227
267
  }
228
268
 
@@ -927,10 +967,12 @@ async function createPeerConnection(peerId, shouldInitiate) {
927
967
 
928
968
  pc.oniceconnectionstatechange = () => {
929
969
  log(`ICE state (${peerId.substring(0, 6)}...): ${pc.iceConnectionState}`, 'info');
970
+ updatePeerList();
930
971
  };
931
972
 
932
973
  pc.onconnectionstatechange = () => {
933
974
  log(`Conn state (${peerId.substring(0, 6)}...): ${pc.connectionState}`, 'info');
975
+ updatePeerList();
934
976
  };
935
977
 
936
978
  pc.ondatachannel = (event) => {
package/tests/e2e.spec.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { test, expect } from '@playwright/test';
2
2
 
3
3
  test.describe('UniWRTC Demo - Full Integration Tests', () => {
4
- const ROOM_ID = 'test';
4
+ const randomRoomId = (prefix = 'e2e') => {
5
+ return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
6
+ };
5
7
 
6
8
  test.describe('Connection and Session Management', () => {
7
9
  test('should load demo page and display UI', async ({ page }) => {
@@ -18,6 +20,9 @@ test.describe('UniWRTC Demo - Full Integration Tests', () => {
18
20
  test('should connect to relay and join room', async ({ page }) => {
19
21
  test.setTimeout(60_000);
20
22
  await page.goto('/');
23
+
24
+ // Use a unique room per test run to avoid interference from relay history.
25
+ await page.getByTestId('roomId').fill(randomRoomId('connect'));
21
26
 
22
27
  // Click connect
23
28
  await page.getByTestId('connectBtn').click();
@@ -40,6 +45,9 @@ test.describe('UniWRTC Demo - Full Integration Tests', () => {
40
45
  test('should handle disconnect', async ({ page }) => {
41
46
  test.setTimeout(60_000);
42
47
  await page.goto('/');
48
+
49
+ // Use a unique room per test run to avoid interference from relay history.
50
+ await page.getByTestId('roomId').fill(randomRoomId('disconnect'));
43
51
 
44
52
  // Connect first
45
53
  await page.getByTestId('connectBtn').click();
@@ -56,6 +64,8 @@ test.describe('UniWRTC Demo - Full Integration Tests', () => {
56
64
 
57
65
  test.describe('Multi-peer Session', () => {
58
66
  test('should connect three peers and see peer-joined notifications', async ({ browser }) => {
67
+ const roomId = randomRoomId('multi');
68
+
59
69
  // Open three browser contexts (simulating three users)
60
70
  const context1 = await browser.newContext();
61
71
  const page1 = await context1.newPage();
@@ -73,9 +83,9 @@ test.describe('UniWRTC Demo - Full Integration Tests', () => {
73
83
  await page3.goto('/?ice=host');
74
84
 
75
85
  // Use shared room ID for all three peers
76
- await page1.getByTestId('roomId').fill(ROOM_ID);
77
- await page2.getByTestId('roomId').fill(ROOM_ID);
78
- await page3.getByTestId('roomId').fill(ROOM_ID);
86
+ await page1.getByTestId('roomId').fill(roomId);
87
+ await page2.getByTestId('roomId').fill(roomId);
88
+ await page3.getByTestId('roomId').fill(roomId);
79
89
 
80
90
  // Connect peer 1
81
91
  await page1.getByTestId('connectBtn').click();
@@ -95,14 +105,9 @@ test.describe('UniWRTC Demo - Full Integration Tests', () => {
95
105
  // Peer 2 should see peer 3 joined (use first() to avoid strict mode with multiple peer-joined logs)
96
106
  await expect(page2.getByTestId('log-peer-joined').first()).toBeVisible({ timeout: 10000 });
97
107
 
98
- // All three should show peers in connected peers list
99
- const peerList1 = page1.getByTestId('peerList');
100
- const peerList2 = page2.getByTestId('peerList');
101
- const peerList3 = page3.getByTestId('peerList');
102
-
103
- await expect(peerList1).not.toContainText('No peers connected');
104
- await expect(peerList2).not.toContainText('No peers connected');
105
- await expect(peerList3).not.toContainText('No peers connected');
108
+ // The UI no longer shows a peer list; rely on peer discovery logs instead.
109
+ await expect(page1.getByTestId('log-peer-joined').first()).toBeVisible({ timeout: 20000 });
110
+ await expect(page2.getByTestId('log-peer-joined').first()).toBeVisible({ timeout: 20000 });
106
111
 
107
112
  } finally {
108
113
  await context1.close();
@@ -113,6 +118,7 @@ test.describe('UniWRTC Demo - Full Integration Tests', () => {
113
118
 
114
119
  test('should open P2P data channels between three peers', async ({ browser }) => {
115
120
  test.setTimeout(90_000);
121
+ const roomId = randomRoomId('dc');
116
122
  const context1 = await browser.newContext();
117
123
  const page1 = await context1.newPage();
118
124
 
@@ -128,9 +134,9 @@ test.describe('UniWRTC Demo - Full Integration Tests', () => {
128
134
  await page2.goto('/?ice=host');
129
135
  await page3.goto('/?ice=host');
130
136
 
131
- await page1.getByTestId('roomId').fill(ROOM_ID);
132
- await page2.getByTestId('roomId').fill(ROOM_ID);
133
- await page3.getByTestId('roomId').fill(ROOM_ID);
137
+ await page1.getByTestId('roomId').fill(roomId);
138
+ await page2.getByTestId('roomId').fill(roomId);
139
+ await page3.getByTestId('roomId').fill(roomId);
134
140
 
135
141
  await page1.getByTestId('connectBtn').click();
136
142
  await expect(page1.getByTestId('log-connected')).toBeVisible({ timeout: 20000 });
@@ -182,6 +188,7 @@ test.describe('UniWRTC Demo - Full Integration Tests', () => {
182
188
 
183
189
  test('should send P2P chat messages between three peers', async ({ browser }) => {
184
190
  test.setTimeout(90_000);
191
+ const roomId = randomRoomId('chat');
185
192
  const context1 = await browser.newContext();
186
193
  const page1 = await context1.newPage();
187
194
 
@@ -197,9 +204,9 @@ test.describe('UniWRTC Demo - Full Integration Tests', () => {
197
204
  await page2.goto('/?ice=host');
198
205
  await page3.goto('/?ice=host');
199
206
 
200
- await page1.getByTestId('roomId').fill(ROOM_ID);
201
- await page2.getByTestId('roomId').fill(ROOM_ID);
202
- await page3.getByTestId('roomId').fill(ROOM_ID);
207
+ await page1.getByTestId('roomId').fill(roomId);
208
+ await page2.getByTestId('roomId').fill(roomId);
209
+ await page3.getByTestId('roomId').fill(roomId);
203
210
 
204
211
  await page1.getByTestId('connectBtn').click();
205
212
  await expect(page1.getByTestId('log-connected')).toBeVisible({ timeout: 20000 });
@@ -292,13 +299,10 @@ test.describe('UniWRTC Demo - Full Integration Tests', () => {
292
299
 
293
300
  // Wait a bit to see if peer-joined appears (it shouldn't)
294
301
  await page1.waitForTimeout(3000);
295
-
296
- // Neither should see the other's peer-joined
297
- const peerList1 = page1.getByTestId('peerList');
298
- const peerList2 = page2.getByTestId('peerList');
299
-
300
- await expect(peerList1).toContainText('No peers connected');
301
- await expect(peerList2).toContainText('No peers connected');
302
+
303
+ // Neither should see a peer join log (they're in different rooms).
304
+ await expect(page1.getByTestId('logContainer').locator('[data-testid="log-peer-joined"]')).toHaveCount(0);
305
+ await expect(page2.getByTestId('logContainer').locator('[data-testid="log-peer-joined"]')).toHaveCount(0);
302
306
 
303
307
  } finally {
304
308
  await context1.close();