-
-
Notifications
You must be signed in to change notification settings - Fork 7
Cursor awareness #60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Cursor awareness #60
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| // Listen to awareness changes on the cursor provider (where element awareness is stored) | ||
| // Fall back to doc provider if cursors are disabled | ||
| const awarenessProvider = cursorClient?.getProvider() ?? yprovider; | ||
| awarenessProvider.awareness.on("change", () => onChangeAwareness()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Element awareness rebuilds on every cursor movement
Medium Severity
The onChangeAwareness function is now registered on the cursor provider's awareness change event. Since the cursor client also writes to this same provider on every mouse move (at up to 60fps per user), onChangeAwareness fires on every cursor movement from any connected user — even though only __playhtml_cursors__ changed and element awareness data is unchanged. Each invocation rebuilds new array and Map references for every element with awareness, unconditionally calling handler.updateAwareness, which in the React layer triggers state updates and re-renders for all awareness-consuming components.
Additional Locations (1)
| return userAwareness?.drunkLevel ?? 0; | ||
| }, | ||
| [drunkLevel], | ||
| [drunkLevel, awarenessByStableId], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Animation loop restarts on every awareness change
Medium Severity
getUserDrunkLevel now depends on awarenessByStableId (React state), which gets a new Map reference on every awareness change — including cursor movements from all users. Since the animation useEffect at line 492 has getUserDrunkLevel as a dependency, the smooth cursor interpolation loop (smoothStep) restarts on every remote awareness change, causing visible animation jitter. The old code read directly from the provider (avoiding React state), keeping the callback stable across awareness changes.


Add cursor presence and stable awareness APIs with improved element awareness scoping
This release adds new APIs for accessing cursor positions and per-user awareness data keyed by stable user IDs, eliminating the need to access internal providers directly.
New Cursor Presence APIs:
New Awareness API - awarenessByStableId:
Element awareness is now provided keyed by stable user ID in addition to the array format:
New React Hook:
Breaking Change - Awareness Scope:
Element awareness now follows cursor scope instead of always being page-specific:
room: "domain", element awareness is domain-wideroom: "page", element awareness is page-specificroom: "section", element awareness is section-specificThis is more intuitive (your user state follows you) but may affect apps that relied on the old behavior. To restore page-specific awareness when cursors are domain-wide, you can configure cursors to use page scope separately.
Benefits:
playerIdentity.publicKey) persist across page refreshes(playhtml.cursorClient as any).provider- use clean public APIsNote
Medium Risk
Changes cursor coordinate storage/rendering and moves element awareness onto the cursor provider, which can change awareness scope/behavior across rooms and affect existing integrations.
Overview
Adds stable, public cursor/awareness APIs.
CursorClientAwarenessnow exposesgetMyPlayerIdentity(),getCursorPresences()(slimCursorPresenceViewkeyed byplayerIdentity.publicKey), andonCursorPresencesChange(), and common types addCursorPresenceView.Changes element awareness behavior (breaking). Element awareness is now read/written via the cursor provider (matching cursor room scope) and is delivered to element handlers as both the existing
awarenessarray and newawarenessByStableId: Map<stableId, awareness>, usinggetStableIdForAwareness()for stable-ID resolution.Updates cursor rendering/coords + React surface area. Cursor tracking adds optional
coordinateMode(relativeviewport % vsabsolutedocument px) with coordinate conversions and spring-smoothed cursor movement;@playhtml/reactexposescursorPresencesvia context + newuseCursorPresences()hook, updateswithSharedStateto passawarenessByStableId, and migrates thedrunk-cursorexperiment off internal provider access.Also adjusts CI test command and adds targeted unit tests for stable-ID awareness resolution and handler awareness updates.
Written by Cursor Bugbot for commit b653b93. This will update automatically on new commits. Configure here.