diff --git a/packages/collaboration/README.md b/packages/collaboration/README.md
index caedd6fa80..aace287ae9 100644
--- a/packages/collaboration/README.md
+++ b/packages/collaboration/README.md
@@ -30,24 +30,31 @@ import {
LiveCursors,
PresenceAvatars,
CommentThread,
+ type Comment,
+ type PresenceUser,
} from '@object-ui/collaboration';
+declare const broadcastPresence: (user: PresenceUser) => void;
+declare const comments: Comment[];
+declare const currentUser: { id: string; name: string };
+
function CollaborativeEditor() {
- const { users, updatePresence } = usePresence({
- channel: 'document-123',
+ const { users, updateCursor } = usePresence(broadcastPresence, {
+ user: { id: 'user-1', name: 'Alice' },
});
- const { data, connectionState } = useRealtimeSubscription({
+ const { lastMessage, connectionState } = useRealtimeSubscription({
channel: 'document-123',
- event: 'update',
});
return (
-
+
-
updatePresence({ cursor: pos })} />
-
+ updateCursor({ x: event.clientX, y: event.clientY })}>
+ {lastMessage ? lastMessage.channel : 'waiting for updates'}
+
+
);
}
@@ -57,34 +64,41 @@ function CollaborativeEditor() {
### useRealtimeSubscription
-Hook for WebSocket data subscriptions:
+Hook for WebSocket data subscriptions. `channel` is the only required key, and the
+result carries the connection state plus the messages received so far:
```tsx
-const { data, connectionState, error } = useRealtimeSubscription({
+import { useRealtimeSubscription } from '@object-ui/collaboration';
+
+const { lastMessage, messages, connectionState, error } = useRealtimeSubscription({
channel: 'orders',
- event: 'update',
});
```
### usePresence
-Hook for tracking user presence:
+Hook for tracking user presence. The broadcast callback comes first and the
+configuration second; the configuration carries the current user:
```tsx
-const { users, updatePresence } = usePresence({
- channel: 'document-123',
+import { usePresence, type PresenceUser } from '@object-ui/collaboration';
+
+declare const broadcastPresence: (user: PresenceUser) => void;
+
+const { users, updateCursor, currentUser } = usePresence(broadcastPresence, {
user: { id: 'user-1', name: 'Alice' },
});
```
### useConflictResolution
-Hook for version history and conflict management:
+Hook for version history and conflict management. It is called with the current
+user's id, optionally their name:
```tsx
-const { versions, conflicts, resolve } = useConflictResolution({
- resourceId: 'doc-123',
-});
+import { useConflictResolution } from '@object-ui/collaboration';
+
+const { versions, conflicts, resolveConflict } = useConflictResolution('user-1', 'Alice');
```
### LiveCursors
@@ -92,7 +106,11 @@ const { versions, conflicts, resolve } = useConflictResolution({
Displays remote user cursors on the page:
```tsx
-
+import { LiveCursors, type PresenceUser } from '@object-ui/collaboration';
+
+declare const presenceUsers: PresenceUser[];
+
+const cursors =
;
```
### PresenceAvatars
@@ -100,19 +118,33 @@ Displays remote user cursors on the page:
Shows avatar badges for active users:
```tsx
-
+import { PresenceAvatars, type PresenceUser } from '@object-ui/collaboration';
+
+declare const presenceUsers: PresenceUser[];
+
+const avatars =
;
```
### CommentThread
-Threaded comment component with @mentions:
+Threaded comment component with @mentions. `comments` and `currentUser` are
+required; new comments arrive through `onAddComment`:
```tsx
-
saveComment(comment)}
-/>
+import { CommentThread, type Comment } from '@object-ui/collaboration';
+
+declare const comments: Comment[];
+declare const currentUser: { id: string; name: string };
+declare const saveComment: (content: string, mentions: string[]) => void;
+
+const thread = (
+ saveComment(content, mentions)}
+ />
+);
```
## Links
diff --git a/scripts/check-doc-snippet-types.mjs b/scripts/check-doc-snippet-types.mjs
index 2351b38343..67d7a763de 100644
--- a/scripts/check-doc-snippet-types.mjs
+++ b/scripts/check-doc-snippet-types.mjs
@@ -705,8 +705,6 @@ const UNGATED_DOCS = {
'what is left is fragment shape, and no gate reads this page\'s import names.',
'packages/auth/README.md':
'1 parse diagnostic(s) — blocks fenced `ts` that are bare object literals or elided bodies; 15 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines; plus TS2741x1 — candidate real defects, un-triaged',
- 'packages/collaboration/README.md':
- '13 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines; plus TS2339x2 TS2353x1 TS2554x1 TS2739x1 — candidate real defects, un-triaged',
'packages/core/README.md':
'5 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the ' +
'page never defines; plus TS2339x1 — TRIAGED, and NOT a defect: the remaining one is ' +