Skip to content

Commit 6db26ba

Browse files
committed
fix: terminals sharing again
1 parent c313f86 commit 6db26ba

3 files changed

Lines changed: 32 additions & 3 deletions

File tree

app/components/TerminalPanel.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ watch(isSharing, (sharing) => {
124124
}
125125
});
126126
127-
watch(sharedTerminals, (list) => {
127+
watch(() => sharedTerminals.value, (list) => {
128128
if (!isSharing.value) return;
129129
// Add new terminals we don't have yet
130130
for (const t of list) {

app/composables/useShare.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ const sharedTerminals = ref<{id: string, name: string}[]>([]);
2828
let controlWs: WebSocket | null = null;
2929
// Relay WebSocket (desktop host only — forwards guest requests)
3030
let relayWs: WebSocket | null = null;
31+
// Buffered messages waiting for relay WS to be ready
32+
let relayMsgQueue: any[] = [];
3133
// Remote server URL (desktop host sharing via Railway)
3234
let remoteServerUrl: string | null = null;
3335

@@ -249,6 +251,13 @@ export function useShare() {
249251
relayWs.onmessage = (ev) => {
250252
try {
251253
const msg = JSON.parse(ev.data);
254+
if (msg.type === "auth-ok") {
255+
// Flush any messages that were queued before the relay was ready
256+
const queued = relayMsgQueue.splice(0);
257+
for (const m of queued) {
258+
relayWs?.send(JSON.stringify(m));
259+
}
260+
}
252261
handleRelayMessage(msg);
253262
} catch {}
254263
};
@@ -309,7 +318,12 @@ export function useShare() {
309318
}
310319

311320
function sendRelayMessage(msg: any) {
312-
relayWs?.send(JSON.stringify(msg));
321+
if (relayWs?.readyState === WebSocket.OPEN) {
322+
relayWs.send(JSON.stringify(msg));
323+
} else {
324+
// Buffer until relay WS is connected and authenticated
325+
relayMsgQueue.push(msg);
326+
}
313327
}
314328

315329
// --- Shared terminal WebSocket URL ---
@@ -332,6 +346,7 @@ export function useShare() {
332346

333347
if (controlWs) { controlWs.close(); controlWs = null; }
334348
if (relayWs) { relayWs.close(); relayWs = null; }
349+
relayMsgQueue = [];
335350
remoteServerUrl = null;
336351
}
337352

server/utils/share.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,17 +255,24 @@ export function resolveRelayResponse(reqId: string, status: number, body: any):
255255
// --- Shared terminal peer registry ---
256256
// Centralized here to avoid circular imports between _share-terminal.ts and _share-relay.ts
257257

258+
const MAX_TERMINAL_BUFFER = 50 * 1024; // 50KB rolling replay buffer per terminal
259+
258260
interface SharedTerminalEntry {
259261
peers: Set<Peer>;
262+
outputBuffer: string; // rolling buffer for late subscribers
260263
}
261264
const sharedTerminals = new Map<string, SharedTerminalEntry>();
262265

263266
export function registerTerminalPeer(terminalId: string, peer: Peer): void {
264267
let entry = sharedTerminals.get(terminalId);
265268
if (!entry) {
266-
entry = { peers: new Set() };
269+
entry = { peers: new Set(), outputBuffer: "" };
267270
sharedTerminals.set(terminalId, entry);
268271
}
272+
// Replay buffered output to late subscriber
273+
if (entry.outputBuffer.length > 0) {
274+
try { peer.send(JSON.stringify({ type: "output", terminalId, data: entry.outputBuffer })); } catch {}
275+
}
269276
entry.peers.add(peer);
270277
}
271278

@@ -280,6 +287,13 @@ export function unregisterTerminalPeer(terminalId: string, peer: Peer): void {
280287
export function broadcastToTerminalPeers(terminalId: string, message: any): void {
281288
const entry = sharedTerminals.get(terminalId);
282289
if (!entry) return;
290+
// Accumulate output in rolling replay buffer for late subscribers
291+
if (message.type === "output" && typeof message.data === "string") {
292+
entry.outputBuffer += message.data;
293+
if (entry.outputBuffer.length > MAX_TERMINAL_BUFFER) {
294+
entry.outputBuffer = entry.outputBuffer.slice(entry.outputBuffer.length - MAX_TERMINAL_BUFFER);
295+
}
296+
}
283297
const msg = JSON.stringify(message);
284298
for (const peer of entry.peers) {
285299
try { peer.send(msg); } catch {}

0 commit comments

Comments
 (0)