Skip to content

LEAN-3843 - #1044

Open
fwaisi wants to merge 1 commit into
masterfrom
LEAN-3843
Open

fwaisi wants to merge 1 commit into
masterfrom
LEAN-3843

Conversation

@fwaisi

@fwaisi fwaisi commented Jan 14, 2026

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements WebSocket support for real-time collaboration in the document editor, enabling bidirectional communication for sending and receiving editing steps. The changes add WebSocket-based step synchronization with HTTP fallback, error handling for conflicts and failures, and connection state management.

Changes:

  • Added WebSocket connection management with send/receive capabilities and automatic reconnection
  • Implemented error handling for WebSocket conflicts and failures with retry logic
  • Added code formatting improvements (line breaks, semicolons) for better readability

Reviewed changes

Copilot reviewed 6 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/api/types.ts Defines new StepsErrorListener type for WebSocket error callbacks
src/api/Api.ts Implements WebSocket connection with send/receive methods, error handling, and connection state tracking
src/api/StepsExchanger.ts Integrates WebSocket for sending/receiving steps with HTTP fallback and conflict resolution
src/components/comments/CommentActions.tsx Adds semicolon before type assertion to prevent ASI issues
src/components/comments/ReplyBox.tsx Reformats PrimaryButton props across multiple lines
src/components/track-changes/suggestion-list/SuggestionList.tsx Reformats arrow function across multiple lines

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/api/Api.ts
Comment on lines +314 to +339
return new Promise((resolve) => {
pendingStepsResolve = resolve

const timeout = setTimeout(() => {
if (pendingStepsResolve === resolve) {
pendingStepsResolve = null
resolve(undefined)
}
}, 10000)

this.getAuthToken()
.then((token) => {
return ws.send(
JSON.stringify({
type: 'getSteps',
version,
token,
})
)
})
.catch(() => {
clearTimeout(timeout)
pendingStepsResolve = null
resolve(undefined)
})
})

Copilot AI Jan 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeout is not cleared when the promise resolves successfully. If a 'stepsResponse' arrives and resolves the promise, the timeout callback will still fire after 10 seconds, potentially causing issues. Add clearTimeout(timeout) in the onMessage handler when resolving pendingStepsResolve.

Copilot uses AI. Check for mistakes.
Comment thread src/api/StepsExchanger.ts
Comment on lines +274 to 287
private handleWebSocketError(error: 'conflict' | 'failed') {
if (error === 'conflict') {
if (this.attempt < MAX_ATTEMPTS) {
this.newStepsListener()
this.attempt++
} else {
this.saveStatus.setValue('failed')
this.attempt = 0
}
} else {
this.saveStatus.setValue('failed')
this.attempt = 0
}
}

Copilot AI Jan 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a conflict error occurs and retries are attempted, this.newStepsListener() is called without arguments. However, looking at the class structure, this appears to be a listener that should receive steps data, not trigger a retry. The retry logic should likely call a method to refetch steps or resend pending changes instead.

Copilot uses AI. Check for mistakes.
Comment thread src/api/Api.ts
Comment on lines +326 to +332
return ws.send(
JSON.stringify({
type: 'getSteps',
version,
token,
})
)

Copilot AI Jan 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The WebSocket send operation is not checked for success. ws.send() returns void but can throw an error if the connection is closed. This could cause unhandled exceptions. Wrap the send call in a try-catch block.

Suggested change
return ws.send(
JSON.stringify({
type: 'getSteps',
version,
token,
})
)
try {
ws.send(
JSON.stringify({
type: 'getSteps',
version,
token,
})
)
} catch {
clearTimeout(timeout)
pendingStepsResolve = null
resolve(undefined)
}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants