@silicaclaw/cli 1.0.0-beta.20 → 1.0.0-beta.22

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.
@@ -6,7 +6,7 @@ const port = Number(process.env.PORT || process.env.WEBRTC_SIGNALING_PORT || 451
6
6
  const PEER_STALE_MS = Number(process.env.WEBRTC_SIGNALING_PEER_STALE_MS || 120000);
7
7
  const SIGNAL_DEDUPE_WINDOW_MS = Number(process.env.WEBRTC_SIGNALING_DEDUPE_WINDOW_MS || 60000);
8
8
 
9
- /** @type {Map<string, {peers: Map<string, {last_seen_at:number}>, queues: Map<string, any[]>, signal_fingerprints: Map<string, number>}>} */
9
+ /** @type {Map<string, {peers: Map<string, {last_seen_at:number}>, queues: Map<string, any[]>, relay_queues: Map<string, any[]>, signal_fingerprints: Map<string, number>}>} */
10
10
  const rooms = new Map();
11
11
 
12
12
  const counters = {
@@ -24,6 +24,7 @@ function getRoom(roomId) {
24
24
  rooms.set(id, {
25
25
  peers: new Map(),
26
26
  queues: new Map(),
27
+ relay_queues: new Map(),
27
28
  signal_fingerprints: new Map(),
28
29
  });
29
30
  }
@@ -73,6 +74,7 @@ function cleanupRoom(roomId) {
73
74
  if (peer.last_seen_at < threshold) {
74
75
  room.peers.delete(peerId);
75
76
  room.queues.delete(peerId);
77
+ room.relay_queues.delete(peerId);
76
78
  counters.stale_peers_cleaned_total += 1;
77
79
  }
78
80
  }
@@ -96,6 +98,9 @@ function touchPeer(room, peerId) {
96
98
  if (!room.queues.has(peerId)) {
97
99
  room.queues.set(peerId, []);
98
100
  }
101
+ if (!room.relay_queues.has(peerId)) {
102
+ room.relay_queues.set(peerId, []);
103
+ }
99
104
  }
100
105
 
101
106
  function isValidSignalPayload(body) {
@@ -168,6 +173,23 @@ const server = http.createServer(async (req, res) => {
168
173
  return json(res, 200, { ok: true, messages: queue });
169
174
  }
170
175
 
176
+ if (req.method === 'GET' && url.pathname === '/relay/poll') {
177
+ const roomId = String(url.searchParams.get('room') || 'silicaclaw-room');
178
+ const peerId = String(url.searchParams.get('peer_id') || '');
179
+ if (!peerId) {
180
+ counters.invalid_payload_total += 1;
181
+ return json(res, 400, { ok: false, error: 'missing_peer_id' });
182
+ }
183
+
184
+ const room = getRoom(roomId);
185
+ touchPeer(room, peerId);
186
+ cleanupRoom(roomId);
187
+
188
+ const queue = room.relay_queues.get(peerId) || [];
189
+ room.relay_queues.set(peerId, []);
190
+ return json(res, 200, { ok: true, messages: queue });
191
+ }
192
+
171
193
  if (req.method === 'POST' && url.pathname === '/join') {
172
194
  const body = await parseBody(req);
173
195
  const roomId = String(body.room || 'silicaclaw-room');
@@ -193,6 +215,7 @@ const server = http.createServer(async (req, res) => {
193
215
  if (peerId) {
194
216
  room.peers.delete(peerId);
195
217
  room.queues.delete(peerId);
218
+ room.relay_queues.delete(peerId);
196
219
  counters.leave_total += 1;
197
220
  } else {
198
221
  counters.invalid_payload_total += 1;
@@ -240,6 +263,34 @@ const server = http.createServer(async (req, res) => {
240
263
  return json(res, 200, { ok: true });
241
264
  }
242
265
 
266
+ if (req.method === 'POST' && url.pathname === '/relay/publish') {
267
+ const body = await parseBody(req);
268
+ const roomId = String(body.room || 'silicaclaw-room');
269
+ const peerId = String(body.peer_id || '');
270
+ const envelope = body.envelope;
271
+ if (!peerId || typeof envelope !== 'object' || envelope === null) {
272
+ counters.invalid_payload_total += 1;
273
+ return json(res, 400, { ok: false, error: 'invalid_relay_payload' });
274
+ }
275
+
276
+ const room = getRoom(roomId);
277
+ touchPeer(room, peerId);
278
+
279
+ for (const targetPeerId of room.peers.keys()) {
280
+ if (targetPeerId === peerId) continue;
281
+ if (!room.relay_queues.has(targetPeerId)) room.relay_queues.set(targetPeerId, []);
282
+ room.relay_queues.get(targetPeerId).push({
283
+ id: String(body.id || randomUUID()),
284
+ room: roomId,
285
+ from_peer_id: peerId,
286
+ envelope,
287
+ at: now(),
288
+ });
289
+ }
290
+
291
+ return json(res, 200, { ok: true, delivered_to: Math.max(0, room.peers.size - 1) });
292
+ }
293
+
243
294
  return json(res, 404, { ok: false, error: 'not_found' });
244
295
  });
245
296