Skip to content

Conversation

@waleedlatif1
Copy link
Collaborator

Summary

  • use selection-update as the source of truth for presence, ignore other socket ops

Type of Change

  • Bug fix

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link

vercel bot commented Jan 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Review Updated (UTC)
docs Skipped Skipped Jan 17, 2026 4:17am

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 17, 2026

Greptile Summary

Changed cursor-update and selection-update socket handlers to only update existing users rather than creating new presence entries. The presence-update event (broadcast during join-workflow) is now the single source of truth for adding users to the presence list.

Key changes:

  • Inverted the conditional logic in both handlers - now returns early if user doesn't exist
  • Removed code that would create new PresenceUser entries with incomplete data
  • Aligns with the server-side architecture where broadcastPresenceUpdate() is called when users join/leave workflows

Rationale:
This prevents race conditions and ensures user presence always has complete information (userId, userName, avatarUrl) from the authoritative presence-update event rather than partial data from cursor/selection events.

Confidence Score: 4/5

  • This PR is safe to merge with minimal risk - it improves data consistency by establishing a clear source of truth for presence
  • Score reflects solid architectural improvement with clear intent. Reduced one point because there's a minor edge case where cursor/selection updates arriving before presence-update will be silently dropped (though unlikely in practice since presence-update is sent immediately on join). The change aligns well with the server-side implementation.
  • No files require special attention - the change is focused and well-scoped

Important Files Changed

Filename Overview
apps/sim/app/workspace/providers/socket-provider.tsx Refactored cursor and selection update handlers to only update existing users instead of creating new entries, making presence-update the authoritative source for user presence

Sequence Diagram

sequenceDiagram
    participant Client as Client Socket
    participant Provider as SocketProvider
    participant Server as Socket Server
    participant Room as RoomManager

    Note over Client,Room: User Joins Workflow
    Client->>Server: join-workflow(workflowId)
    Server->>Room: createUserPresence(userId, userName, avatarUrl)
    Room->>Room: room.users.set(socketId, userPresence)
    Server->>Room: broadcastPresenceUpdate(workflowId)
    Room->>Client: presence-update([...allUsers])
    Client->>Provider: setPresenceUsers(users)
    Note over Provider: User presence list initialized

    Note over Client,Room: Cursor Movement (After PR)
    Client->>Server: cursor-update({x, y})
    Server->>Client: cursor-update(data)
    Client->>Provider: Check if user exists
    alt User exists in presenceUsers
        Provider->>Provider: Update cursor for existing user
    else User NOT in presenceUsers
        Provider->>Provider: Return early, ignore update
    end

    Note over Client,Room: Selection Change (After PR)
    Client->>Server: selection-update({type, id})
    Server->>Client: selection-update(data)
    Client->>Provider: Check if user exists
    alt User exists in presenceUsers
        Provider->>Provider: Update selection for existing user
    else User NOT in presenceUsers
        Provider->>Provider: Return early, ignore update
    end
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

1 file reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines 407 to 411
setPresenceUsers((prev) => {
const existingIndex = prev.findIndex((user) => user.socketId === data.socketId)
if (existingIndex !== -1) {
return prev.map((user) =>
user.socketId === data.socketId ? { ...user, cursor: data.cursor } : user
)
if (existingIndex === -1) {
return prev
}
Copy link
Contributor

Choose a reason for hiding this comment

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

style: If a cursor-update arrives before presence-update (timing issue during connection), cursor position will be silently dropped. Consider logging when this occurs for debugging.

Suggested change
setPresenceUsers((prev) => {
const existingIndex = prev.findIndex((user) => user.socketId === data.socketId)
if (existingIndex !== -1) {
return prev.map((user) =>
user.socketId === data.socketId ? { ...user, cursor: data.cursor } : user
)
if (existingIndex === -1) {
return prev
}
setPresenceUsers((prev) => {
const existingIndex = prev.findIndex((user) => user.socketId === data.socketId)
if (existingIndex === -1) {
logger.debug('Received cursor-update for unknown user', { socketId: data.socketId })
return prev
}

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/app/workspace/providers/socket-provider.tsx
Line: 407:411

Comment:
**style:** If a `cursor-update` arrives before `presence-update` (timing issue during connection), cursor position will be silently dropped. Consider logging when this occurs for debugging.

```suggestion
          setPresenceUsers((prev) => {
            const existingIndex = prev.findIndex((user) => user.socketId === data.socketId)
            if (existingIndex === -1) {
              logger.debug('Received cursor-update for unknown user', { socketId: data.socketId })
              return prev
            }
```

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines 420 to 424
setPresenceUsers((prev) => {
const existingIndex = prev.findIndex((user) => user.socketId === data.socketId)
if (existingIndex !== -1) {
return prev.map((user) =>
user.socketId === data.socketId ? { ...user, selection: data.selection } : user
)
if (existingIndex === -1) {
return prev
}
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Same as the cursor-update handler - consider adding debug logging for dropped selection updates.

Suggested change
setPresenceUsers((prev) => {
const existingIndex = prev.findIndex((user) => user.socketId === data.socketId)
if (existingIndex !== -1) {
return prev.map((user) =>
user.socketId === data.socketId ? { ...user, selection: data.selection } : user
)
if (existingIndex === -1) {
return prev
}
setPresenceUsers((prev) => {
const existingIndex = prev.findIndex((user) => user.socketId === data.socketId)
if (existingIndex === -1) {
logger.debug('Received selection-update for unknown user', { socketId: data.socketId })
return prev
}

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/sim/app/workspace/providers/socket-provider.tsx
Line: 420:424

Comment:
**style:** Same as the cursor-update handler - consider adding debug logging for dropped selection updates.

```suggestion
          setPresenceUsers((prev) => {
            const existingIndex = prev.findIndex((user) => user.socketId === data.socketId)
            if (existingIndex === -1) {
              logger.debug('Received selection-update for unknown user', { socketId: data.socketId })
              return prev
            }
```

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

@waleedlatif1 waleedlatif1 merged commit 5de7228 into staging Jan 17, 2026
6 checks passed
@waleedlatif1 waleedlatif1 deleted the fix/avatar branch January 17, 2026 04:17
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