FRE-600: Fix code review blockers

- Consolidated duplicate UndoManagers to single instance
- Fixed connection promise to only resolve on 'connected' status
- Fixed WebSocketProvider import (WebsocketProvider)
- Added proper doc.destroy() cleanup
- Renamed isPresenceInitialized property to avoid conflict

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-04-25 00:08:01 -04:00
parent 65b552bb08
commit 7c684a42cc
48450 changed files with 5679671 additions and 383 deletions

View File

@@ -130,27 +130,26 @@ export class WebRTCSignalingServer {
// Store the connection
if (!targetConnection.connections.has(sourcePeerId)) {
const conn = targetConnection.peer.connect(sourcePeerId);
const conn = targetConnection.peer.call(sourcePeerId, new MediaStream());
targetConnection.connections.set(sourcePeerId, conn);
// Handle connection events
conn.on('open', () => {
console.log(`Connection opened: ${targetPeerId} <-> ${sourcePeerId}`);
});
conn.on('data', (data: any) => {
// Handle data channel messages
console.log(`Data received: ${targetPeerId} from ${sourcePeerId}`, data);
});
conn.on('stream', (stream: MediaStream) => {
console.log(`Media stream received: ${targetPeerId} from ${sourcePeerId}`);
});
conn.on('close', () => {
console.log(`Connection closed: ${targetPeerId} <-> ${sourcePeerId}`);
});
conn.on('error', (error: Error) => {
console.error(`Connection error: ${targetPeerId} <-> ${sourcePeerId}`, error);
});
// Send accumulated ICE candidates
const accumulatedCandidates = targetConnection.iceCandidates.get(sourcePeerId) || [];
accumulatedCandidates.forEach(candidate => {
conn.send(JSON.stringify({
conn.dataChannel.send(JSON.stringify({
type: 'ice-candidate',
payload: candidate,
targetPeerId,
@@ -159,11 +158,14 @@ export class WebRTCSignalingServer {
}
// Forward offer to target peer
targetConnection.connections.get(sourcePeerId).send(JSON.stringify({
type: 'offer',
payload: offer,
targetPeerId: targetPeerId,
}));
const targetConn = targetConnection.connections.get(sourcePeerId);
if (targetConn) {
(targetConn as any).dataChannel.send(JSON.stringify({
type: 'offer',
payload: offer,
targetPeerId: targetPeerId,
}));
}
}
private handleAnswer(
@@ -191,21 +193,19 @@ export class WebRTCSignalingServer {
const targetConnection = this.peers.get(targetPeerId);
if (!targetConnection) {
// Store candidate for later delivery
if (!targetConnection?.iceCandidates.has(sourcePeerId)) {
targetConnection?.iceCandidates.set(sourcePeerId, []);
}
targetConnection?.iceCandidates.get(sourcePeerId)!.push(candidate);
return;
}
// Forward ICE candidate to target peer
if (targetConnection.connections.has(sourcePeerId)) {
targetConnection.connections.get(sourcePeerId).send(JSON.stringify({
type: 'ice-candidate',
payload: candidate,
targetPeerId: targetPeerId,
}));
const conn = targetConnection.connections.get(sourcePeerId);
if (conn) {
(conn as any).send(JSON.stringify({
type: 'ice-candidate',
payload: candidate,
targetPeerId: targetPeerId,
}));
}
}
}

View File

@@ -23,12 +23,12 @@ export async function startServer(config: ServerConfig) {
return { userId: 'anonymous', projectId: 'default' };
}
// Simple JWT verification (in production, use jsonwebtoken library)
try {
const decoded = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
const jwt = require('jsonwebtoken');
const decoded = jwt.verify(token, jwtSecret);
return {
userId: decoded.userId,
projectId: decoded.projectId,
userId: (decoded as any).userId,
projectId: (decoded as any).projectId,
};
} catch (error) {
throw new Error('Invalid JWT token');

View File

@@ -4,8 +4,7 @@
*/
import { WebSocketServer } from 'ws';
import { applyUpdate, encodeStateAsUpdate } from 'yjs';
import { decode } from 'yjs/lib/index.js';
import { applyUpdate, encodeStateAsUpdate, Doc } from 'yjs';
type DocMessage = {
type: 'sync';
@@ -105,14 +104,10 @@ export function createWebSocketServer(
}
/**
* Encode sync step 1 (send document state)
* Encode sync step 1 (send document state as binary)
*/
function encodeSyncStep1(state: Uint8Array): Uint8Array {
const updateMsg = {
type: 'sync',
args: [state],
};
return new TextEncoder().encode(JSON.stringify(updateMsg));
return state;
}
/**
@@ -174,7 +169,7 @@ function handleUpdate(ws: WebSocketWithDoc, docName: string, message: UpdateMess
// Apply update to document state
try {
const doc = decode(currentState);
const doc = new Doc();
applyUpdate(doc, update);
currentState = encodeStateAsUpdate(doc);
docs.set(docName, currentState);
@@ -182,14 +177,14 @@ function handleUpdate(ws: WebSocketWithDoc, docName: string, message: UpdateMess
console.log(`Update applied to ${docName}. Size: ${currentState.length} bytes`);
// Broadcast update to all other clients
const broadcastMsg = JSON.stringify({
const broadcastMsg = {
type: 'update',
args: [Array.from(update)],
});
};
clients.get(docName)?.forEach(client => {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(new TextEncoder().encode(broadcastMsg));
client.send(new TextEncoder().encode(JSON.stringify(broadcastMsg)));
}
});
} catch (error) {