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 ' +