freertc 0.1.1 → 0.1.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +57 -36
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "freertc",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Cloudflare Worker signaling relay for WebRTC peers with D1 storage.",
5
5
  "keywords": [
6
6
  "webrtc",
package/src/index.js CHANGED
@@ -260,6 +260,41 @@ async function listRelays(db) {
260
260
  return (result.results || []).map(r => ({ url: r.url, name: r.name }));
261
261
  }
262
262
 
263
+ function mergeDiscoveredPeers(...peerGroups) {
264
+ const merged = new Map();
265
+
266
+ for (const peers of peerGroups) {
267
+ if (!Array.isArray(peers)) continue;
268
+ for (const peer of peers) {
269
+ const peerId = peer?.peer_id;
270
+ if (typeof peerId !== "string" || !peerId) continue;
271
+
272
+ const existing = merged.get(peerId);
273
+ const nextTimestamp = Number(peer?.timestamp || 0);
274
+ const existingTimestamp = Number(existing?.timestamp || 0);
275
+ if (!existing || nextTimestamp >= existingTimestamp) {
276
+ merged.set(peerId, peer);
277
+ }
278
+ }
279
+ }
280
+
281
+ return Array.from(merged.values()).sort((left, right) => left.peer_id.localeCompare(right.peer_id));
282
+ }
283
+
284
+ function sendPeerList(socket, network, peers, to = null, from = "bootstrap-relay") {
285
+ socket.send(JSON.stringify({
286
+ psp_version: PSP_VERSION,
287
+ type: "peer_list",
288
+ network,
289
+ from,
290
+ to,
291
+ message_id: crypto.randomUUID(),
292
+ timestamp: Date.now(),
293
+ ttl_ms: DEFAULT_TTL_MS,
294
+ body: { peers }
295
+ }));
296
+ }
297
+
263
298
  // Broadcast peer list to all connected peers in a network
264
299
  async function broadcastPeerList(db, network) {
265
300
  const sockets = networkSubscribers.get(network);
@@ -279,23 +314,9 @@ async function broadcastPeerList(db, network) {
279
314
  session_id: row.session_id,
280
315
  timestamp: row.updated_at_ms
281
316
  }));
282
-
283
- const message = {
284
- psp_version: PSP_VERSION,
285
- type: "peer_list",
286
- network,
287
- from: "bootstrap-relay",
288
- to: null,
289
- message_id: crypto.randomUUID(),
290
- timestamp: Date.now(),
291
- ttl_ms: DEFAULT_TTL_MS,
292
- body: { peers }
293
- };
294
-
295
- const payload = JSON.stringify(message);
296
317
  for (const socket of sockets) {
297
318
  try {
298
- socket.send(payload);
319
+ sendPeerList(socket, network, peers);
299
320
  } catch (e) {
300
321
  sockets.delete(socket);
301
322
  }
@@ -566,36 +587,36 @@ async function handleClientMessage(socket, rawData, env, ctx, prevPeerKey = null
566
587
  }
567
588
 
568
589
  } else if (type === "discover") {
569
- // Local peers first
590
+ let localPeers = [];
570
591
  if (db) {
571
- broadcastPeerList(db, network).catch(() => {});
592
+ localPeers = await findPeers(db, network, peerId);
572
593
  }
573
- // Fan out to all known peer relays, exchanging relay lists bidirectionally
594
+
595
+ let remotePeers = [];
574
596
  if (env.RELAY_URL && env.DB) {
575
- ctx.waitUntil((async () => {
576
- const selfRelayId = env.RELAY_PEER_ID || "relay-bridge";
577
- const selfUrl = normalizeRelayUrl(env.RELAY_URL);
578
- const allRelays = await listRelays(env.DB);
579
- const remoteUrls = allRelays.map(r => r.url).filter(u => u !== selfUrl);
580
- if (!remoteUrls.length) return;
597
+ const selfRelayId = env.RELAY_PEER_ID || "relay-bridge";
598
+ const selfUrl = normalizeRelayUrl(env.RELAY_URL);
599
+ const allRelays = await listRelays(env.DB);
600
+ const remoteUrls = allRelays.map(r => r.url).filter(u => u !== selfUrl);
581
601
 
602
+ if (remoteUrls.length) {
582
603
  const results = await Promise.all(
583
604
  remoteUrls.map(u => queryRelayForPeers(u, network, selfRelayId, env.DB, allRelays))
584
605
  );
585
- const remotePeers = results.flat();
586
- if (!remotePeers.length) return;
587
-
588
- const message = {
589
- psp_version: PSP_VERSION, type: "peer_list", network,
590
- from: selfRelayId, to: peerId,
591
- message_id: crypto.randomUUID(), timestamp: Date.now(),
592
- ttl_ms: DEFAULT_TTL_MS,
593
- body: { peers: remotePeers }
594
- };
595
- try { socket.send(JSON.stringify(message)); } catch {}
596
- })());
606
+ remotePeers = results.flat();
607
+ }
597
608
  }
598
609
 
610
+ try {
611
+ sendPeerList(
612
+ socket,
613
+ network,
614
+ mergeDiscoveredPeers(localPeers, remotePeers).filter(peer => peer.peer_id !== peerId),
615
+ peerId,
616
+ env.RELAY_PEER_ID || "bootstrap-relay"
617
+ );
618
+ } catch {}
619
+
599
620
  } else if (type === "ext" && message.body?.action === "relay_list") {
600
621
  // Remote relay is sharing its known relay list — cache any new entries
601
622
  if (db) {