@liveblocks/react 2.7.0-beta2 → 2.7.0-versions2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/version.ts","../src/ClientSideSuspense.tsx","../src/comments/lib/selected-threads.ts","../src/comments/errors.ts","../src/room.tsx","../src/comments/lib/select-notification-settings.ts","../src/comments/lib/selected-inbox-notifications.ts","../src/lib/retry-error.ts","../src/lib/use-initial.ts","../src/lib/use-latest.ts","../src/lib/use-polyfill.ts","../src/liveblocks.tsx","../src/use-scroll-to-comment-on-load-effect.ts"],"names":["shallow","console","kInternal","makePoller","nanoid","React","useSyncExternalStoreWithSelector","applyOptimisticUpdates","useEffect","useCallback","useInboxNotificationThread","useMarkInboxNotificationAsRead","useMarkAllInboxNotificationsAsRead","useDeleteInboxNotification","useDeleteAllInboxNotifications","LiveblocksProvider","useClient","comment","noop","useSyncExternalStore","POLLING_INTERVAL","_extras","_bundles","getExtrasForClient","makeExtrasForClient","subscribers","version","room","other","rootOrNull","state","err","metadata","inboxNotification","settings"],"mappings":"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","sourcesContent":["declare const __VERSION__: string;\ndeclare const TSUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof TSUP_FORMAT === \"string\" && TSUP_FORMAT;\n","import type { ReactNode } from \"react\";\nimport * as React from \"react\";\n\ntype Props = {\n fallback: ReactNode;\n children: (() => ReactNode | undefined) | ReactNode | undefined;\n};\n\n/**\n * Almost like a normal <Suspense> component, except that for server-side\n * renders, the fallback will be used.\n *\n * The child props will have to be provided in a function, i.e. change:\n *\n * <Suspense fallback={<Loading />}>\n * <MyRealComponent a={1} />\n * </Suspense>\n *\n * To:\n *\n * <ClientSideSuspense fallback={<Loading />}>\n * <MyRealComponent a={1} />\n * </ClientSideSuspense>\n *\n */\nexport function ClientSideSuspense(props: Props) {\n const [mounted, setMounted] = React.useState(false);\n\n React.useEffect(() => {\n // Effects are never executed on the server side. The point of this is to\n // delay the flipping of this boolean until after hydration has happened.\n setMounted(true);\n }, []);\n\n return (\n <React.Suspense fallback={props.fallback}>\n {mounted\n ? typeof props.children === \"function\"\n ? props.children()\n : props.children\n : props.fallback}\n </React.Suspense>\n );\n}\n","import {\n applyOptimisticUpdates,\n type BaseMetadata,\n type CacheState,\n type ThreadData,\n} from \"@liveblocks/core\";\n\nimport type { UseThreadsOptions } from \"../../types\";\n\nexport function selectedUserThreads<M extends BaseMetadata>(\n state: CacheState<M>\n) {\n const result = applyOptimisticUpdates(state);\n\n // Filter threads to only include the non-deleted threads\n const threads = Object.values(result.threads).filter<ThreadData<M>>(\n (thread): thread is ThreadData<M> => {\n // We do not want to include threads that have been marked as deleted\n if (thread.deletedAt !== undefined) {\n return false;\n }\n\n return true;\n }\n );\n\n // Sort threads by updated date (newest first) and then created date\n return threads.sort(\n (a, b) =>\n (b.updatedAt ?? b.createdAt).getTime() -\n (a.updatedAt ?? a.createdAt).getTime()\n );\n}\n\n/**\n * @private Do not rely on this internal API.\n */\nexport function selectedThreads<M extends BaseMetadata>(\n roomId: string,\n state: CacheState<M>,\n options: UseThreadsOptions<M>\n): ThreadData<M>[] {\n const result = applyOptimisticUpdates(state);\n\n // Filter threads to only include the non-deleted threads from the specified room and that match the specified filter options\n const threads = Object.values(result.threads).filter<ThreadData<M>>(\n (thread): thread is ThreadData<M> => {\n if (thread.roomId !== roomId) return false;\n\n // We do not want to include threads that have been marked as deleted\n if (thread.deletedAt !== undefined) {\n return false;\n }\n\n const query = options.query;\n if (!query) return true;\n\n // If the query includes 'resolved' filter and the thread's 'resolved' value does not match the query's 'resolved' value, exclude the thread\n if (query.resolved !== undefined && thread.resolved !== query.resolved) {\n return false;\n }\n\n for (const key in query.metadata) {\n const metadataValue = thread.metadata[key];\n const filterValue = query.metadata[key];\n\n if (\n assertFilterIsStartsWithOperator(filterValue) &&\n assertMetadataValueIsString(metadataValue)\n ) {\n if (metadataValue.startsWith(filterValue.startsWith)) {\n return true;\n }\n }\n\n if (metadataValue !== filterValue) {\n return false;\n }\n }\n\n return true;\n }\n );\n\n // Sort threads by creation date (oldest first)\n return threads.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());\n}\n\nconst assertFilterIsStartsWithOperator = (\n filter: boolean | string | number | undefined | { startsWith: string }\n): filter is { startsWith: string } => {\n if (typeof filter === \"object\" && typeof filter.startsWith === \"string\") {\n return true;\n } else {\n return false;\n }\n};\n\nconst assertMetadataValueIsString = (value: any): value is string => {\n return typeof value === \"string\";\n};\n","import type { BaseMetadata, CommentBody, Patchable } from \"@liveblocks/core\";\n\n/**\n * @private Internal API, do not rely on it.\n */\nexport class CreateThreadError<M extends BaseMetadata> extends Error {\n constructor(\n public cause: Error,\n public context: {\n roomId: string;\n threadId: string;\n commentId: string;\n body: CommentBody;\n metadata: M;\n }\n ) {\n super(\"Create thread failed.\");\n this.name = \"CreateThreadError\";\n }\n}\n\nexport class DeleteThreadError extends Error {\n constructor(\n public cause: Error,\n public context: {\n roomId: string;\n threadId: string;\n }\n ) {\n super(\"Delete thread failed.\");\n this.name = \"DeleteThreadError\";\n }\n}\n\nexport class EditThreadMetadataError<M extends BaseMetadata> extends Error {\n constructor(\n public cause: Error,\n public context: {\n roomId: string;\n threadId: string;\n metadata: Patchable<M>;\n }\n ) {\n super(\"Edit thread metadata failed.\");\n this.name = \"EditThreadMetadataError\";\n }\n}\n\nexport class MarkThreadAsResolvedError extends Error {\n constructor(\n public cause: Error,\n public context: {\n roomId: string;\n threadId: string;\n }\n ) {\n super(\"Mark thread as resolved failed.\");\n this.name = \"MarkThreadAsResolvedError\";\n }\n}\n\nexport class MarkThreadAsUnresolvedError extends Error {\n constructor(\n public cause: Error,\n public context: {\n roomId: string;\n threadId: string;\n }\n ) {\n super(\"Mark thread as unresolved failed.\");\n this.name = \"MarkThreadAsUnresolvedError\";\n }\n}\n\nexport class CreateCommentError extends Error {\n constructor(\n public cause: Error,\n public context: {\n roomId: string;\n threadId: string;\n commentId: string;\n body: CommentBody;\n }\n ) {\n super(\"Create comment failed.\");\n this.name = \"CreateCommentError\";\n }\n}\n\nexport class EditCommentError extends Error {\n constructor(\n public cause: Error,\n public context: {\n roomId: string;\n threadId: string;\n commentId: string;\n body: CommentBody;\n }\n ) {\n super(\"Edit comment failed.\");\n this.name = \"EditCommentError\";\n }\n}\n\nexport class DeleteCommentError extends Error {\n constructor(\n public cause: Error,\n public context: {\n roomId: string;\n threadId: string;\n commentId: string;\n }\n ) {\n super(\"Delete comment failed.\");\n this.name = \"DeleteCommentError\";\n }\n}\n\nexport class AddReactionError extends Error {\n constructor(\n public cause: Error,\n public context: {\n roomId: string;\n threadId: string;\n commentId: string;\n emoji: string;\n }\n ) {\n super(\"Add reaction failed.\");\n this.name = \"AddReactionError\";\n }\n}\n\nexport class RemoveReactionError extends Error {\n constructor(\n public cause: Error,\n public context: {\n roomId: string;\n threadId: string;\n commentId: string;\n emoji: string;\n }\n ) {\n super(\"Remove reaction failed.\");\n this.name = \"RemoveReactionError\";\n }\n}\n\nexport class MarkInboxNotificationAsReadError extends Error {\n constructor(\n public cause: Error,\n public context: {\n inboxNotificationId: string;\n }\n ) {\n super(\"Mark inbox notification as read failed.\");\n this.name = \"MarkInboxNotificationAsReadError\";\n }\n}\n\nexport class UpdateNotificationSettingsError extends Error {\n constructor(\n public cause: Error,\n public context: {\n roomId: string;\n }\n ) {\n super(\"Update notification settings failed.\");\n this.name = \"UpdateNotificationSettingsError\";\n }\n}\n\nexport type CommentsError<M extends BaseMetadata> =\n | CreateThreadError<M>\n | EditThreadMetadataError<M>\n | CreateCommentError\n | EditCommentError\n | DeleteCommentError\n | MarkInboxNotificationAsReadError\n | UpdateNotificationSettingsError;\n","import type {\n BaseMetadata,\n BaseUserMeta,\n BroadcastOptions,\n Client,\n History,\n Json,\n JsonObject,\n LiveObject,\n LostConnectionEvent,\n LsonObject,\n OthersEvent,\n Room,\n Status,\n User,\n} from \"@liveblocks/client\";\nimport { shallow } from \"@liveblocks/client\";\nimport type {\n CacheState,\n CacheStore,\n CommentData,\n CommentsEventServerMsg,\n DE,\n DM,\n DP,\n DS,\n DU,\n EnterOptions,\n HistoryVersion,\n LiveblocksError,\n OpaqueClient,\n OpaqueRoom,\n RoomEventMessage,\n RoomNotificationSettings,\n StorageStatus,\n ThreadData,\n ToImmutable,\n} from \"@liveblocks/core\";\nimport {\n addReaction,\n CommentsApiError,\n console,\n createCommentId,\n createThreadId,\n deleteComment,\n deprecateIf,\n errorIf,\n kInternal,\n makeEventSource,\n makePoller,\n nanoid,\n NotificationsApiError,\n removeReaction,\n ServerMsgCode,\n stringify,\n upsertComment,\n} from \"@liveblocks/core\";\nimport * as React from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport {\n AddReactionError,\n type CommentsError,\n CreateCommentError,\n CreateThreadError,\n DeleteCommentError,\n DeleteThreadError,\n EditCommentError,\n EditThreadMetadataError,\n MarkInboxNotificationAsReadError,\n MarkThreadAsResolvedError,\n MarkThreadAsUnresolvedError,\n RemoveReactionError,\n UpdateNotificationSettingsError,\n} from \"./comments/errors\";\nimport { selectNotificationSettings } from \"./comments/lib/select-notification-settings\";\nimport { selectedInboxNotifications } from \"./comments/lib/selected-inbox-notifications\";\nimport { selectedThreads } from \"./comments/lib/selected-threads\";\nimport { retryError } from \"./lib/retry-error\";\nimport { useInitial } from \"./lib/use-initial\";\nimport { useLatest } from \"./lib/use-latest\";\nimport { use } from \"./lib/use-polyfill\";\nimport {\n createSharedContext,\n LiveblocksProviderWithClient,\n useClient,\n useClientOrNull,\n} from \"./liveblocks\";\nimport type {\n CommentReactionOptions,\n CreateCommentOptions,\n CreateThreadOptions,\n DeleteCommentOptions,\n EditCommentOptions,\n EditThreadMetadataOptions,\n HistoryVersionDataState,\n HistoryVersionsState,\n HistoryVersionsStateResolved,\n MutationContext,\n OmitFirstArg,\n RoomContextBundle,\n RoomNotificationSettingsState,\n RoomNotificationSettingsStateSuccess,\n RoomProviderProps,\n StorageStatusSuccess,\n ThreadsState,\n ThreadsStateSuccess,\n ThreadSubscription,\n UseStorageStatusOptions,\n UseThreadsOptions,\n} from \"./types\";\nimport { useScrollToCommentOnLoadEffect } from \"./use-scroll-to-comment-on-load-effect\";\n\nconst SMOOTH_DELAY = 1000;\n\nconst noop = () => { };\nconst identity: <T>(x: T) => T = (x) => x;\n\nconst missing_unstable_batchedUpdates = (\n reactVersion: number,\n roomId: string\n) =>\n `We noticed you’re using React ${reactVersion}. Please pass unstable_batchedUpdates at the RoomProvider level until you’re ready to upgrade to React 18:\n\n import { unstable_batchedUpdates } from \"react-dom\"; // or \"react-native\"\n\n <RoomProvider id=${JSON.stringify(\n roomId\n )} ... unstable_batchedUpdates={unstable_batchedUpdates}>\n ...\n </RoomProvider>\n\nWhy? Please see https://liveblocks.io/docs/platform/troubleshooting#stale-props-zombie-child for more information`;\n\nconst superfluous_unstable_batchedUpdates =\n \"You don’t need to pass unstable_batchedUpdates to RoomProvider anymore, since you’re on React 18+ already.\";\n\nfunction useSyncExternalStore<Snapshot>(\n s: (onStoreChange: () => void) => () => void,\n gs: () => Snapshot,\n gss: undefined | null | (() => Snapshot)\n): Snapshot {\n return useSyncExternalStoreWithSelector(s, gs, gss, identity);\n}\n\nconst STABLE_EMPTY_LIST = Object.freeze([]);\n\nexport const POLLING_INTERVAL = 5 * 60 * 1000; // 5 minutes\n\nfunction makeNotificationSettingsQueryKey(roomId: string) {\n return `${roomId}:NOTIFICATION_SETTINGS`;\n}\n\n// Don't try to inline this. This function is intended to be a stable\n// reference, to avoid a React.useCallback() wrapper.\nfunction alwaysEmptyList() {\n return STABLE_EMPTY_LIST;\n}\n\n// Don't try to inline this. This function is intended to be a stable\n// reference, to avoid a React.useCallback() wrapper.\nfunction alwaysNull() {\n return null;\n}\n\nfunction selectorFor_useOthersConnectionIds(\n others: readonly User<JsonObject, BaseUserMeta>[]\n): number[] {\n return others.map((user) => user.connectionId);\n}\n\nfunction makeMutationContext<\n P extends JsonObject,\n S extends LsonObject,\n U extends BaseUserMeta,\n E extends Json,\n M extends BaseMetadata,\n>(room: Room<P, S, U, E, M>): MutationContext<P, S, U> {\n const cannotUseUntil = \"This mutation cannot be used until\";\n const needsPresence = `${cannotUseUntil} connected to the Liveblocks room`;\n const needsStorage = `${cannotUseUntil} storage has been loaded`;\n\n return {\n get storage() {\n const mutableRoot = room.getStorageSnapshot();\n if (mutableRoot === null) {\n throw new Error(needsStorage);\n }\n return mutableRoot;\n },\n\n get self() {\n const self = room.getSelf();\n if (self === null) {\n throw new Error(needsPresence);\n }\n return self;\n },\n\n get others() {\n const others = room.getOthers();\n if (room.getSelf() === null) {\n throw new Error(needsPresence);\n }\n return others;\n },\n\n setMyPresence: room.updatePresence,\n };\n}\n\nfunction getCurrentUserId(room: OpaqueRoom): string {\n const self = room.getSelf();\n if (self === null || self.id === undefined) {\n return \"anonymous\";\n } else {\n return self.id;\n }\n}\n\nfunction handleApiError(err: CommentsApiError | NotificationsApiError): Error {\n const message = `Request failed with status ${err.status}: ${err.message}`;\n\n // Log details about FORBIDDEN errors\n if (err.details?.error === \"FORBIDDEN\") {\n const detailedMessage = [message, err.details.suggestion, err.details.docs]\n .filter(Boolean)\n .join(\"\\n\");\n\n console.error(detailedMessage);\n }\n\n return new Error(message);\n}\n\nconst _extras = new WeakMap<\n OpaqueClient,\n ReturnType<typeof makeExtrasForClient>\n>();\nconst _bundles = new WeakMap<\n OpaqueClient,\n RoomContextBundle<JsonObject, LsonObject, BaseUserMeta, Json, BaseMetadata>\n>();\n\nfunction getOrCreateRoomContextBundle<\n P extends JsonObject,\n S extends LsonObject,\n U extends BaseUserMeta,\n E extends Json,\n M extends BaseMetadata,\n>(client: OpaqueClient): RoomContextBundle<P, S, U, E, M> {\n let bundle = _bundles.get(client);\n if (!bundle) {\n bundle = makeRoomContextBundle(client);\n _bundles.set(client, bundle);\n }\n return bundle as unknown as RoomContextBundle<P, S, U, E, M>;\n}\n\n// TODO: Likely a better / more clear name for this helper will arise. I'll\n// rename this later. All of these are implementation details to support inbox\n// notifications on a per-client basis.\nfunction getExtrasForClient<M extends BaseMetadata>(client: OpaqueClient) {\n let extras = _extras.get(client);\n if (!extras) {\n extras = makeExtrasForClient(client);\n _extras.set(client, extras);\n }\n\n return extras as unknown as Omit<typeof extras, \"store\"> & {\n store: CacheStore<M>;\n };\n}\n\nfunction makeExtrasForClient<M extends BaseMetadata>(client: OpaqueClient) {\n const store = client[kInternal].cacheStore as unknown as CacheStore<M>;\n\n const DEFAULT_DEDUPING_INTERVAL = 2000; // 2 seconds\n\n const lastRequestedAtByRoom = new Map<string, Date>(); // A map of room ids to the timestamp when the last request for threads updates was made\n const requestsByQuery = new Map<string, Promise<unknown>>(); // A map of query keys to the promise of the request for that query\n const requestStatusByRoom = new Map<string, boolean>(); // A map of room ids to a boolean indicating whether a request to retrieve threads updates is in progress\n const subscribersByQuery = new Map<string, number>(); // A map of query keys to the number of subscribers for that query\n\n const poller = makePoller(refreshThreadsAndNotifications);\n\n async function refreshThreadsAndNotifications() {\n const requests: Promise<unknown>[] = [];\n\n client[kInternal].getRoomIds().map((roomId) => {\n const room = client.getRoom(roomId);\n if (room === null) return;\n\n // Retrieve threads that have been updated/deleted since the last requestedAt value\n requests.push(getThreadsUpdates(room.id));\n });\n\n await Promise.allSettled(requests);\n }\n\n function incrementQuerySubscribers(queryKey: string) {\n const subscribers = subscribersByQuery.get(queryKey) ?? 0;\n subscribersByQuery.set(queryKey, subscribers + 1);\n\n poller.start(POLLING_INTERVAL);\n\n // Decrement in the unsub function\n return () => {\n const subscribers = subscribersByQuery.get(queryKey);\n\n if (subscribers === undefined || subscribers <= 0) {\n console.warn(\n `Internal unexpected behavior. Cannot decrease subscriber count for query \"${queryKey}\"`\n );\n return;\n }\n\n subscribersByQuery.set(queryKey, subscribers - 1);\n\n let totalSubscribers = 0;\n for (const subscribers of subscribersByQuery.values()) {\n totalSubscribers += subscribers;\n }\n\n if (totalSubscribers <= 0) {\n poller.stop();\n }\n };\n }\n\n /**\n * Retrieve threads that have been updated/deleted since the last time the room requested threads updates and update the local cache with the new data\n * @param roomId The id of the room for which to retrieve threads updates\n */\n async function getThreadsUpdates(roomId: string) {\n const room = client.getRoom(roomId) as Room<\n never,\n never,\n never,\n never,\n M\n > | null; // TODO: Figure out how to remove this casting\n if (room === null) return;\n\n const since = lastRequestedAtByRoom.get(room.id);\n if (since === undefined) return;\n\n const isFetchingThreadsUpdates = requestStatusByRoom.get(room.id) ?? false;\n // If another request to retrieve threads updates for the room is in progress, we do not start a new one\n if (isFetchingThreadsUpdates === true) return;\n\n try {\n // Set the isFetchingThreadsUpdates flag to true to prevent multiple requests to fetch threads updates for the room from being made at the same time\n requestStatusByRoom.set(room.id, true);\n\n const updates = await room.getThreadsSince({ since });\n\n // Set the isFetchingThreadsUpdates flag to false after a certain interval to prevent multiple requests from being made at the same time\n setTimeout(() => {\n requestStatusByRoom.set(room.id, false);\n }, DEFAULT_DEDUPING_INTERVAL);\n\n store.updateThreadsAndNotifications(\n updates.threads.updated,\n updates.inboxNotifications.updated,\n updates.threads.deleted,\n updates.inboxNotifications.deleted\n );\n\n // Update the `lastRequestedAt` value for the room to the timestamp returned by the current request\n lastRequestedAtByRoom.set(room.id, updates.requestedAt);\n } catch (err) {\n requestStatusByRoom.set(room.id, false);\n // TODO: Implement error handling\n return;\n }\n }\n\n async function getRoomVersions(\n room: OpaqueRoom,\n { retryCount }: { retryCount: number } = { retryCount: 0 }\n ) {\n const queryKey = getVersionsQueryKey(room.id);\n const existingRequest = requestsByQuery.get(queryKey);\n if (existingRequest !== undefined) return existingRequest;\n const request = room[kInternal].listTextVersions();\n requestsByQuery.set(queryKey, request);\n store.setQueryState(queryKey, {\n isLoading: true,\n });\n try {\n const result = await request;\n const data = (await result.json()) as {\n versions: HistoryVersion[];\n };\n const versions = data.versions.map(({ createdAt, ...version }) => {\n return {\n createdAt: new Date(createdAt),\n ...version,\n };\n });\n store.updateRoomVersions(room.id, versions, queryKey);\n requestsByQuery.delete(queryKey);\n } catch (err) {\n requestsByQuery.delete(queryKey);\n // Retry the action using the exponential backoff algorithm\n retryError(() => {\n void getRoomVersions(room, {\n retryCount: retryCount + 1,\n });\n }, retryCount);\n store.setQueryState(queryKey, {\n isLoading: false,\n error: err as Error,\n });\n }\n return;\n }\n\n async function getThreadsAndInboxNotifications(\n room: OpaqueRoom,\n queryKey: string,\n options: UseThreadsOptions<M>,\n { retryCount }: { retryCount: number } = { retryCount: 0 }\n ) {\n const existingRequest = requestsByQuery.get(queryKey);\n\n // If a request was already made for the query, we do not make another request and return the existing promise of the request\n if (existingRequest !== undefined) return existingRequest;\n\n const request = room.getThreads(options);\n\n // Store the promise of the request for the query so that we do not make another request for the same query\n requestsByQuery.set(queryKey, request);\n\n store.setQueryState(queryKey, {\n isLoading: true,\n });\n\n try {\n const result = await request;\n\n store.updateThreadsAndNotifications(\n result.threads as ThreadData<M>[], // TODO: Figure out how to remove this casting\n result.inboxNotifications,\n [],\n [],\n queryKey\n );\n\n const lastRequestedAt = lastRequestedAtByRoom.get(room.id);\n\n /**\n * We set the `lastRequestedAt` value for the room to the timestamp returned by the current request if:\n * 1. The `lastRequestedAt` value for the room has not been set\n * OR\n * 2. The `lastRequestedAt` value for the room is older than the timestamp returned by the current request\n */\n if (\n lastRequestedAt === undefined ||\n lastRequestedAt > result.requestedAt\n ) {\n lastRequestedAtByRoom.set(room.id, result.requestedAt);\n }\n\n poller.start(POLLING_INTERVAL);\n } catch (err) {\n requestsByQuery.delete(queryKey);\n\n // Retry the action using the exponential backoff algorithm\n retryError(() => {\n void getThreadsAndInboxNotifications(room, queryKey, options, {\n retryCount: retryCount + 1,\n });\n }, retryCount);\n\n // Set the query state to the error state\n store.setQueryState(queryKey, {\n isLoading: false,\n error: err as Error,\n });\n }\n return;\n }\n\n async function getInboxNotificationSettings(\n room: OpaqueRoom,\n queryKey: string,\n { retryCount }: { retryCount: number } = { retryCount: 0 }\n ) {\n const existingRequest = requestsByQuery.get(queryKey);\n\n // If a request was already made for the notifications query, we do not make another request and return the existing promise\n if (existingRequest !== undefined) return existingRequest;\n\n try {\n const request = room.getNotificationSettings();\n\n requestsByQuery.set(queryKey, request);\n\n store.setQueryState(queryKey, {\n isLoading: true,\n });\n\n const settings = await request;\n store.updateRoomInboxNotificationSettings(room.id, settings, queryKey);\n } catch (err) {\n requestsByQuery.delete(queryKey);\n\n retryError(() => {\n void getInboxNotificationSettings(room, queryKey, {\n retryCount: retryCount + 1,\n });\n }, retryCount);\n\n store.setQueryState(queryKey, {\n isLoading: false,\n error: err as Error,\n });\n }\n return;\n }\n\n const commentsErrorEventSource = makeEventSource<CommentsError<M>>();\n\n function onMutationFailure(\n innerError: Error,\n optimisticUpdateId: string,\n createPublicError: (error: Error) => CommentsError<M>\n ) {\n store.set((state) => ({\n ...state,\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n }));\n\n if (innerError instanceof CommentsApiError) {\n const error = handleApiError(innerError);\n commentsErrorEventSource.notify(createPublicError(error));\n return;\n }\n\n if (innerError instanceof NotificationsApiError) {\n handleApiError(innerError);\n // TODO: Create public error and notify via notificationsErrorEventSource?\n return;\n }\n\n throw innerError;\n }\n\n return {\n store,\n incrementQuerySubscribers,\n commentsErrorEventSource,\n getThreadsUpdates,\n getThreadsAndInboxNotifications,\n getInboxNotificationSettings,\n getRoomVersions,\n onMutationFailure,\n };\n}\n\ntype RoomLeavePair<\n P extends JsonObject,\n S extends LsonObject,\n U extends BaseUserMeta,\n E extends Json,\n M extends BaseMetadata,\n> = {\n room: Room<P, S, U, E, M>;\n leave: () => void;\n};\n\n/**\n * Raw access to the React context where the RoomProvider stores the current\n * room. Exposed for advanced use cases only.\n *\n * @private This is a private/advanced API. Do not rely on it.\n */\nconst RoomContext = React.createContext<OpaqueRoom | null>(null);\n\nfunction makeRoomContextBundle<\n P extends JsonObject,\n S extends LsonObject,\n U extends BaseUserMeta,\n E extends Json,\n M extends BaseMetadata,\n>(client: Client<U>): RoomContextBundle<P, S, U, E, M> {\n type TRoom = Room<P, S, U, E, M>;\n\n function RoomProvider_withImplicitLiveblocksProvider(\n props: RoomProviderProps<P, S>\n ) {\n // NOTE: Normally, nesting LiveblocksProvider is not allowed. This\n // factory-bound version of the RoomProvider will create an implicit\n // LiveblocksProvider. This means that if an end user nests this\n // RoomProvider under a LiveblocksProvider context, that would be an error.\n // However, we'll allow that nesting only in this specific situation, and\n // only because this wrapper will keep the Liveblocks context and the Room\n // context consistent internally.\n return (\n <LiveblocksProviderWithClient client={client} allowNesting>\n <RoomProvider {...props} />\n </LiveblocksProviderWithClient>\n );\n }\n\n const shared = createSharedContext<U>(client);\n\n const bundle: RoomContextBundle<P, S, U, E, M> = {\n RoomContext: RoomContext as React.Context<TRoom | null>,\n RoomProvider: RoomProvider_withImplicitLiveblocksProvider,\n\n useRoom,\n useStatus,\n useStorageStatus,\n\n useBatch,\n useBroadcastEvent,\n useOthersListener,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n useStorageRoot,\n useStorage,\n\n useSelf,\n useMyPresence,\n useUpdateMyPresence,\n useOthers,\n useOthersMapped,\n useOthersConnectionIds,\n useOther,\n\n useMutation: useMutation as RoomContextBundle<P, S, U, E, M>[\"useMutation\"],\n\n useThreads,\n\n useCreateThread,\n useDeleteThread,\n useEditThreadMetadata,\n useMarkThreadAsResolved,\n useMarkThreadAsUnresolved,\n useCreateComment,\n useEditComment,\n useDeleteComment,\n useAddReaction,\n useRemoveReaction,\n useMarkThreadAsRead,\n useThreadSubscription,\n\n useHistoryVersions,\n useHistoryVersionData,\n\n useRoomNotificationSettings,\n useUpdateRoomNotificationSettings,\n\n ...shared.classic,\n\n suspense: {\n RoomContext: RoomContext as React.Context<TRoom | null>,\n RoomProvider: RoomProvider_withImplicitLiveblocksProvider,\n\n useRoom,\n useStatus,\n useStorageStatus: useStorageStatusSuspense,\n\n useBatch,\n useBroadcastEvent,\n useOthersListener,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n useStorageRoot,\n useStorage: useStorageSuspense,\n\n useSelf: useSelfSuspense,\n useMyPresence,\n useUpdateMyPresence,\n useOthers: useOthersSuspense,\n useOthersMapped: useOthersMappedSuspense,\n useOthersConnectionIds: useOthersConnectionIdsSuspense,\n useOther: useOtherSuspense,\n\n useMutation: useMutation as RoomContextBundle<\n P,\n S,\n U,\n E,\n M\n >[\"suspense\"][\"useMutation\"],\n\n useThreads: useThreadsSuspense,\n\n useCreateThread,\n useDeleteThread,\n useEditThreadMetadata,\n useMarkThreadAsResolved,\n useMarkThreadAsUnresolved,\n useCreateComment,\n useEditComment,\n useDeleteComment,\n useAddReaction,\n useRemoveReaction,\n useMarkThreadAsRead,\n useThreadSubscription,\n\n // TODO: useHistoryVersionData: useHistoryVersionDataSuspense,\n useHistoryVersions: useHistoryVersionsSuspense,\n\n useRoomNotificationSettings: useRoomNotificationSettingsSuspense,\n useUpdateRoomNotificationSettings,\n\n ...shared.suspense,\n },\n\n useCommentsErrorListener,\n };\n\n return Object.defineProperty(bundle, kInternal, {\n enumerable: false,\n });\n}\n\nfunction RoomProvider<\n P extends JsonObject,\n S extends LsonObject,\n U extends BaseUserMeta,\n E extends Json,\n M extends BaseMetadata,\n>(props: RoomProviderProps<P, S>) {\n const client = useClient<U>();\n const [cache] = React.useState(\n () => new Map<string, RoomLeavePair<P, S, U, E, M>>()\n );\n\n // Produce a version of client.enterRoom() that when called for the same\n // room ID multiple times, will not keep producing multiple leave\n // functions, but instead return the cached one.\n const stableEnterRoom: typeof client.enterRoom<P, S, E, M> =\n React.useCallback(\n (\n roomId: string,\n options: EnterOptions<P, S>\n ): RoomLeavePair<P, S, U, E, M> => {\n const cached = cache.get(roomId);\n if (cached) return cached;\n\n const rv = client.enterRoom<P, S, E, M>(roomId, options);\n\n // Wrap the leave function to also delete the cached value\n const origLeave = rv.leave;\n rv.leave = () => {\n origLeave();\n cache.delete(roomId);\n };\n\n cache.set(roomId, rv);\n return rv;\n },\n [client, cache]\n );\n\n //\n // RATIONALE:\n // At the \"Outer\" RoomProvider level, we keep a cache and produce\n // a stableEnterRoom function, which we pass down to the real \"Inner\"\n // RoomProvider level.\n //\n // The purpose is to ensure that if `stableEnterRoom(\"my-room\")` is called\n // multiple times for the same room ID, it will always return the exact same\n // (cached) value, so that in total only a single \"leave\" function gets\n // produced and registered in the client.\n //\n // If we didn't use this cache, then in React StrictMode\n // stableEnterRoom(\"my-room\") might get called multiple (at least 4) times,\n // causing more leave functions to be produced in the client, some of which\n // we cannot get a hold on (because StrictMode would discard those results by\n // design). This would make it appear to the Client that the Room is still in\n // use by some party that hasn't called `leave()` on it yet, thus causing the\n // Room to not be freed and destroyed when the component unmounts later.\n //\n return (\n <RoomProviderInner<P, S, U, E, M>\n {...(props as any)}\n stableEnterRoom={stableEnterRoom}\n />\n );\n}\n\ntype EnterRoomType<\n P extends JsonObject,\n S extends LsonObject,\n U extends BaseUserMeta,\n E extends Json,\n M extends BaseMetadata,\n> = (\n roomId: string,\n options: EnterOptions<P, S>\n) => RoomLeavePair<P, S, U, E, M>;\n\n/** @internal */\nfunction RoomProviderInner<\n P extends JsonObject,\n S extends LsonObject,\n U extends BaseUserMeta,\n E extends Json,\n M extends BaseMetadata,\n>(\n props: RoomProviderProps<P, S> & {\n stableEnterRoom: EnterRoomType<P, S, U, E, M>;\n }\n) {\n const client = useClient<U>();\n const { id: roomId, stableEnterRoom } = props;\n\n if (process.env.NODE_ENV !== \"production\") {\n if (!roomId) {\n throw new Error(\n \"RoomProvider id property is required. For more information: https://liveblocks.io/docs/errors/liveblocks-react/RoomProvider-id-property-is-required\"\n );\n }\n\n if (typeof roomId !== \"string\") {\n throw new Error(\"RoomProvider id property should be a string.\");\n }\n\n const majorReactVersion = parseInt(React.version) || 1;\n const oldReactVersion = majorReactVersion < 18;\n errorIf(\n oldReactVersion && props.unstable_batchedUpdates === undefined,\n missing_unstable_batchedUpdates(majorReactVersion, roomId)\n );\n deprecateIf(\n !oldReactVersion && props.unstable_batchedUpdates !== undefined,\n superfluous_unstable_batchedUpdates\n );\n }\n\n // Note: We'll hold on to the initial value given here, and ignore any\n // changes to this argument in subsequent renders\n const frozenProps = useInitial({\n initialPresence: props.initialPresence,\n initialStorage: props.initialStorage,\n unstable_batchedUpdates: props.unstable_batchedUpdates,\n autoConnect: props.autoConnect ?? typeof window !== \"undefined\",\n }) as EnterOptions<P, S>;\n\n const [{ room }, setRoomLeavePair] = React.useState(() =>\n stableEnterRoom(roomId, {\n ...frozenProps,\n autoConnect: false, // Deliberately using false here on the first render, see below\n })\n );\n\n React.useEffect(() => {\n const { store } = getExtrasForClient(client);\n\n async function handleCommentEvent(message: CommentsEventServerMsg) {\n // If thread deleted event is received, we remove the thread from the local cache\n // no need for more processing\n if (message.type === ServerMsgCode.THREAD_DELETED) {\n store.deleteThread(message.threadId);\n return;\n }\n\n // TODO: Error handling\n const info = await room.getThread(message.threadId);\n\n // If no thread info was returned (i.e., 404), we remove the thread and relevant inbox notifications from local cache.\n if (!info.thread) {\n store.deleteThread(message.threadId);\n return;\n }\n const { thread, inboxNotification } = info;\n\n const existingThread = store.get().threads[message.threadId];\n\n switch (message.type) {\n case ServerMsgCode.COMMENT_EDITED:\n case ServerMsgCode.THREAD_METADATA_UPDATED:\n case ServerMsgCode.THREAD_UPDATED:\n case ServerMsgCode.COMMENT_REACTION_ADDED:\n case ServerMsgCode.COMMENT_REACTION_REMOVED:\n case ServerMsgCode.COMMENT_DELETED:\n // If the thread doesn't exist in the local cache, we do not update it with the server data as an optimistic update could have deleted the thread locally.\n if (!existingThread) break;\n\n store.updateThreadAndNotification(thread, inboxNotification);\n break;\n case ServerMsgCode.COMMENT_CREATED:\n store.updateThreadAndNotification(thread, inboxNotification);\n break;\n default:\n break;\n }\n }\n\n return room.events.comments.subscribe(\n (message) => void handleCommentEvent(message)\n );\n }, [client, room]);\n\n React.useEffect(() => {\n const { getThreadsUpdates } = getExtrasForClient(client);\n // Retrieve threads that have been updated/deleted since the last time the room requested threads updates\n void getThreadsUpdates(room.id);\n }, [client, room.id]);\n\n /**\n * Subscribe to the 'online' event to fetch threads/notifications updates when the browser goes back online.\n */\n React.useEffect(() => {\n function handleIsOnline() {\n const { getThreadsUpdates } = getExtrasForClient(client);\n void getThreadsUpdates(room.id);\n }\n\n window.addEventListener(\"online\", handleIsOnline);\n return () => {\n window.removeEventListener(\"online\", handleIsOnline);\n };\n }, [client, room.id]);\n\n React.useEffect(() => {\n const pair = stableEnterRoom(roomId, frozenProps);\n\n setRoomLeavePair(pair);\n const { room, leave } = pair;\n\n // In React, it's important to start connecting to the room as an effect,\n // rather than doing this during the initial render. This means that\n // during the initial render (both on the server-side, and on the first\n // hydration on the client-side), the value of the `useStatus()` hook\n // will correctly be \"initial\", and transition to \"connecting\" as an\n // effect.\n if (frozenProps.autoConnect) {\n room.connect();\n }\n\n return () => {\n leave();\n };\n }, [roomId, frozenProps, stableEnterRoom]);\n\n return (\n <RoomContext.Provider value={room}>{props.children}</RoomContext.Provider>\n );\n}\n\nfunction useRoom<\n P extends JsonObject = DP,\n S extends LsonObject = DS,\n U extends BaseUserMeta = DU,\n E extends Json = DE,\n M extends BaseMetadata = DM,\n>(): Room<P, S, U, E, M> {\n const room = useRoomOrNull<P, S, U, E, M>();\n if (room === null) {\n throw new Error(\"RoomProvider is missing from the React tree.\");\n }\n return room;\n}\n\n/**\n * Returns whether the hook is called within a RoomProvider context.\n *\n * @example\n * const isInsideRoom = useIsInsideRoom();\n */\nfunction useIsInsideRoom(): boolean {\n const room = useRoomOrNull();\n return room !== null;\n}\n\n/**\n * Returns the current connection status for the Room, and triggers\n * a re-render whenever it changes. Can be used to render a status badge.\n */\nfunction useStatus(): Status {\n const room = useRoom();\n const subscribe = room.events.status.subscribe;\n const getSnapshot = room.getStatus;\n const getServerSnapshot = room.getStatus;\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\n/**\n * Returns the current storage status for the Room, and triggers\n * a re-render whenever it changes. Can be used to render a \"Saving...\"\n * indicator.\n */\nfunction useStorageStatus(options?: UseStorageStatusOptions): StorageStatus {\n // Normally the Rules of Hooks™ dictate that you should not call hooks\n // conditionally. In this case, we're good here, because the same code path\n // will always be taken on every subsequent render here, because we've frozen\n // the value.\n /* eslint-disable react-hooks/rules-of-hooks */\n const smooth = useInitial(options?.smooth ?? false);\n if (smooth) {\n return useStorageStatusSmooth();\n } else {\n return useStorageStatusImmediate();\n }\n /* eslint-enable react-hooks/rules-of-hooks */\n}\n\nfunction useStorageStatusImmediate(): StorageStatus {\n const room = useRoom();\n const subscribe = room.events.storageStatus.subscribe;\n const getSnapshot = room.getStorageStatus;\n const getServerSnapshot = room.getStorageStatus;\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\nfunction useStorageStatusSmooth(): StorageStatus {\n const room = useRoom();\n const [status, setStatus] = React.useState(room.getStorageStatus);\n const oldStatus = useLatest(room.getStorageStatus());\n\n React.useEffect(() => {\n let timeoutId: ReturnType<typeof setTimeout>;\n const unsub = room.events.storageStatus.subscribe((newStatus) => {\n if (\n oldStatus.current === \"synchronizing\" &&\n newStatus === \"synchronized\"\n ) {\n // Delay delivery of the \"synchronized\" event\n timeoutId = setTimeout(() => setStatus(newStatus), SMOOTH_DELAY);\n } else {\n clearTimeout(timeoutId);\n setStatus(newStatus);\n }\n });\n\n // Clean up\n return () => {\n clearTimeout(timeoutId);\n unsub();\n };\n }, [room, oldStatus]);\n\n return status;\n}\n\n/**\n * @deprecated It's recommended to use `useMutation` for writing to Storage,\n * which will automatically batch all mutations.\n *\n * Returns a function that batches modifications made during the given function.\n * All the modifications are sent to other clients in a single message.\n * All the modifications are merged in a single history item (undo/redo).\n * All the subscribers are called only after the batch is over.\n */\nfunction useBatch<T>(): (callback: () => T) => T {\n return useRoom().batch;\n}\n\nfunction useBroadcastEvent<E extends Json>(): (\n event: E,\n options?: BroadcastOptions\n) => void {\n const room = useRoom<never, never, never, E, never>();\n return React.useCallback(\n (\n event: E,\n options: BroadcastOptions = { shouldQueueEventIfNotReady: false }\n ) => {\n room.broadcastEvent(event, options);\n },\n [room]\n );\n}\n\nfunction useOthersListener<P extends JsonObject, U extends BaseUserMeta>(\n callback: (event: OthersEvent<P, U>) => void\n) {\n const room = useRoom<P, never, U, never, never>();\n const savedCallback = useLatest(callback);\n React.useEffect(\n () => room.events.others.subscribe((event) => savedCallback.current(event)),\n [room, savedCallback]\n );\n}\n\n/**\n * Get informed when reconnecting to the Liveblocks servers is taking\n * longer than usual. This typically is a sign of a client that has lost\n * internet connectivity.\n *\n * This isn't problematic (because the Liveblocks client is still trying to\n * reconnect), but it's typically a good idea to inform users about it if\n * the connection takes too long to recover.\n *\n * @example\n * useLostConnectionListener(event => {\n * if (event === 'lost') {\n * toast.warn('Reconnecting to the Liveblocks servers is taking longer than usual...')\n * } else if (event === 'failed') {\n * toast.warn('Reconnecting to the Liveblocks servers failed.')\n * } else if (event === 'restored') {\n * toast.clear();\n * }\n * })\n */\nfunction useLostConnectionListener(\n callback: (event: LostConnectionEvent) => void\n): void {\n const room = useRoom();\n const savedCallback = useLatest(callback);\n React.useEffect(\n () =>\n room.events.lostConnection.subscribe((event) =>\n savedCallback.current(event)\n ),\n [room, savedCallback]\n );\n}\n\n/**\n * useErrorListener is a React hook that allows you to respond to potential room\n * connection errors.\n *\n * @example\n * useErrorListener(er => {\n * console.error(er);\n * })\n */\nfunction useErrorListener(callback: (err: LiveblocksError) => void): void {\n const room = useRoom();\n const savedCallback = useLatest(callback);\n React.useEffect(\n () => room.events.error.subscribe((e) => savedCallback.current(e)),\n [room, savedCallback]\n );\n}\n\nfunction useEventListener<\n P extends JsonObject,\n U extends BaseUserMeta,\n E extends Json,\n>(callback: (data: RoomEventMessage<P, U, E>) => void): void {\n const room = useRoom<P, never, U, E, never>();\n const savedCallback = useLatest(callback);\n React.useEffect(() => {\n const listener = (eventData: RoomEventMessage<P, U, E>) => {\n savedCallback.current(eventData);\n };\n\n return room.events.customEvent.subscribe(listener);\n }, [room, savedCallback]);\n}\n\n/**\n * Returns the room.history\n */\nfunction useHistory(): History {\n return useRoom().history;\n}\n\n/**\n * Returns a function that undoes the last operation executed by the current\n * client. It does not impact operations made by other clients.\n */\nfunction useUndo(): () => void {\n return useHistory().undo;\n}\n\n/**\n * Returns a function that redoes the last operation executed by the current\n * client. It does not impact operations made by other clients.\n */\nfunction useRedo(): () => void {\n return useHistory().redo;\n}\n\n/**\n * Returns whether there are any operations to undo.\n */\nfunction useCanUndo(): boolean {\n const room = useRoom();\n const subscribe = room.events.history.subscribe;\n const canUndo = room.history.canUndo;\n return useSyncExternalStore(subscribe, canUndo, canUndo);\n}\n\n/**\n * Returns whether there are any operations to redo.\n */\nfunction useCanRedo(): boolean {\n const room = useRoom();\n const subscribe = room.events.history.subscribe;\n const canRedo = room.history.canRedo;\n return useSyncExternalStore(subscribe, canRedo, canRedo);\n}\n\nfunction useSelf<P extends JsonObject, U extends BaseUserMeta>(): User<\n P,\n U\n> | null;\nfunction useSelf<P extends JsonObject, U extends BaseUserMeta, T>(\n selector: (me: User<P, U>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n): T | null;\nfunction useSelf<P extends JsonObject, U extends BaseUserMeta, T>(\n maybeSelector?: (me: User<P, U>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n): T | User<P, U> | null {\n type Snapshot = User<P, U> | null;\n type Selection = T | null;\n\n const room = useRoom<P, never, U, never, never>();\n const subscribe = room.events.self.subscribe;\n const getSnapshot: () => Snapshot = room.getSelf;\n\n const selector = maybeSelector ?? (identity as (me: User<P, U>) => T);\n const wrappedSelector = React.useCallback(\n (me: Snapshot): Selection => (me !== null ? selector(me) : null),\n [selector]\n );\n\n const getServerSnapshot = alwaysNull;\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n}\n\nfunction useMyPresence<P extends JsonObject>(): [\n P,\n (patch: Partial<P>, options?: { addToHistory: boolean }) => void,\n] {\n const room = useRoom<P, never, never, never, never>();\n const subscribe = room.events.myPresence.subscribe;\n const getSnapshot = room.getPresence;\n const presence = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n const setPresence = room.updatePresence;\n return [presence, setPresence];\n}\n\nfunction useUpdateMyPresence<P extends JsonObject>(): (\n patch: Partial<P>,\n options?: { addToHistory: boolean }\n) => void {\n return useRoom<P, never, never, never, never>().updatePresence;\n}\n\nfunction useOthers<\n P extends JsonObject,\n U extends BaseUserMeta,\n>(): readonly User<P, U>[];\nfunction useOthers<P extends JsonObject, U extends BaseUserMeta, T>(\n selector: (others: readonly User<P, U>[]) => T,\n isEqual?: (prev: T, curr: T) => boolean\n): T;\nfunction useOthers<P extends JsonObject, U extends BaseUserMeta, T>(\n selector?: (others: readonly User<P, U>[]) => T,\n isEqual?: (prev: T, curr: T) => boolean\n): T | readonly User<P, U>[] {\n const room = useRoom<P, never, U, never, never>();\n const subscribe = room.events.others.subscribe;\n const getSnapshot = room.getOthers;\n const getServerSnapshot = alwaysEmptyList;\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n selector ?? (identity as (others: readonly User<P, U>[]) => T),\n isEqual\n );\n}\n\nfunction useOthersMapped<P extends JsonObject, U extends BaseUserMeta, T>(\n itemSelector: (other: User<P, U>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n): ReadonlyArray<readonly [connectionId: number, data: T]> {\n const wrappedSelector = React.useCallback(\n (others: readonly User<P, U>[]) =>\n others.map((other) => [other.connectionId, itemSelector(other)] as const),\n [itemSelector]\n );\n\n const wrappedIsEqual = React.useCallback(\n (\n a: ReadonlyArray<readonly [connectionId: number, data: T]>,\n b: ReadonlyArray<readonly [connectionId: number, data: T]>\n ): boolean => {\n const eq = itemIsEqual ?? Object.is;\n return (\n a.length === b.length &&\n a.every((atuple, index) => {\n // We know btuple always exist because we checked the array length on the previous line\n const btuple = b[index];\n return atuple[0] === btuple[0] && eq(atuple[1], btuple[1]);\n })\n );\n },\n [itemIsEqual]\n );\n\n return useOthers(wrappedSelector, wrappedIsEqual);\n}\n\n/**\n * Returns an array of connection IDs. This matches the values you'll get by\n * using the `useOthers()` hook.\n *\n * Roughly equivalent to:\n * useOthers((others) => others.map(other => other.connectionId), shallow)\n *\n * This is useful in particular to implement efficiently rendering components\n * for each user in the room, e.g. cursors.\n *\n * @example\n * const ids = useOthersConnectionIds();\n * // [2, 4, 7]\n */\nfunction useOthersConnectionIds(): readonly number[] {\n return useOthers(selectorFor_useOthersConnectionIds, shallow);\n}\n\nconst NOT_FOUND = Symbol();\n\ntype NotFound = typeof NOT_FOUND;\n\nfunction useOther<P extends JsonObject, U extends BaseUserMeta, T>(\n connectionId: number,\n selector: (other: User<P, U>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n): T {\n const wrappedSelector = React.useCallback(\n (others: readonly User<P, U>[]) => {\n // TODO: Make this O(1) instead of O(n)?\n const other = others.find((other) => other.connectionId === connectionId);\n return other !== undefined ? selector(other) : NOT_FOUND;\n },\n [connectionId, selector]\n );\n\n const wrappedIsEqual = React.useCallback(\n (prev: T | NotFound, curr: T | NotFound): boolean => {\n if (prev === NOT_FOUND || curr === NOT_FOUND) {\n return prev === curr;\n }\n\n const eq = isEqual ?? Object.is;\n return eq(prev, curr);\n },\n [isEqual]\n );\n\n const other = useOthers(wrappedSelector, wrappedIsEqual);\n if (other === NOT_FOUND) {\n throw new Error(\n `No such other user with connection id ${connectionId} exists`\n );\n }\n\n return other;\n}\n\n/** @internal */\nfunction useMutableStorageRoot<S extends LsonObject>(): LiveObject<S> | null {\n const room = useRoom<never, S, never, never, never>();\n const subscribe = room.events.storageDidLoad.subscribeOnce;\n const getSnapshot = room.getStorageSnapshot;\n const getServerSnapshot = alwaysNull;\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\n// NOTE: This API exists for backward compatible reasons\nfunction useStorageRoot<S extends LsonObject>(): [root: LiveObject<S> | null] {\n return [useMutableStorageRoot<S>()];\n}\n\nfunction useStorage<S extends LsonObject, T>(\n selector: (root: ToImmutable<S>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n): T | null {\n type Snapshot = ToImmutable<S> | null;\n type Selection = T | null;\n\n const room = useRoom<never, S, never, never, never>();\n const rootOrNull = useMutableStorageRoot<S>();\n\n const wrappedSelector = React.useCallback(\n (rootOrNull: Snapshot): Selection =>\n rootOrNull !== null ? selector(rootOrNull) : null,\n [selector]\n );\n\n const subscribe = React.useCallback(\n (onStoreChange: () => void) =>\n rootOrNull !== null\n ? room.subscribe(rootOrNull, onStoreChange, { isDeep: true })\n : noop,\n [room, rootOrNull]\n );\n\n const getSnapshot = React.useCallback((): Snapshot => {\n if (rootOrNull === null) {\n return null;\n } else {\n const root = rootOrNull;\n const imm = root.toImmutable();\n return imm;\n }\n }, [rootOrNull]);\n\n const getServerSnapshot = alwaysNull;\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n}\n\nfunction useMutation<\n P extends JsonObject,\n S extends LsonObject,\n U extends BaseUserMeta,\n E extends Json,\n M extends BaseMetadata,\n F extends (context: MutationContext<P, S, U>, ...args: any[]) => any,\n>(callback: F, deps: readonly unknown[]): OmitFirstArg<F> {\n const room = useRoom<P, S, U, E, M>();\n return React.useMemo(\n () => {\n return ((...args) =>\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n room.batch(() =>\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n callback(\n makeMutationContext<P, S, U, E, M>(room),\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n ...args\n )\n )) as OmitFirstArg<F>;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [room, ...deps]\n );\n}\n\nfunction useThreads<M extends BaseMetadata>(\n options: UseThreadsOptions<M> = {\n query: { metadata: {} },\n }\n): ThreadsState<M> {\n const { scrollOnLoad = true } = options;\n const client = useClient();\n const room = useRoom();\n const queryKey = React.useMemo(\n () => generateQueryKey(room.id, options.query),\n [room, options]\n );\n\n const { store, getThreadsAndInboxNotifications, incrementQuerySubscribers } =\n getExtrasForClient<M>(client);\n\n React.useEffect(() => {\n void getThreadsAndInboxNotifications(room, queryKey, options);\n return incrementQuerySubscribers(queryKey);\n }, [room, queryKey]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const selector = React.useCallback(\n (state: CacheState<M>): ThreadsState<M> => {\n const query = state.queries[queryKey];\n if (query === undefined || query.isLoading) {\n return {\n isLoading: true,\n };\n }\n\n return {\n threads: selectedThreads(room.id, state, options),\n isLoading: false,\n error: query.error,\n };\n },\n [room, queryKey] // eslint-disable-line react-hooks/exhaustive-deps\n );\n\n const state = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n selector\n );\n\n useScrollToCommentOnLoadEffect(scrollOnLoad, state);\n\n return state;\n}\n\n/**\n * @private Internal API, do not rely on it.\n */\nfunction useCommentsErrorListener<M extends BaseMetadata>(\n callback: (error: CommentsError<M>) => void\n) {\n const client = useClient();\n const savedCallback = useLatest(callback);\n const { commentsErrorEventSource } = getExtrasForClient<M>(client);\n\n React.useEffect(() => {\n return commentsErrorEventSource.subscribe(savedCallback.current);\n }, [savedCallback, commentsErrorEventSource]);\n}\n\nfunction useCreateThread<M extends BaseMetadata>(): (\n options: CreateThreadOptions<M>\n) => ThreadData<M> {\n const client = useClient();\n const room = useRoom();\n\n return React.useCallback(\n (options: CreateThreadOptions<M>): ThreadData<M> => {\n const body = options.body;\n const metadata = options.metadata ?? ({} as M);\n\n const threadId = createThreadId();\n const commentId = createCommentId();\n const createdAt = new Date();\n\n const newComment: CommentData = {\n id: commentId,\n threadId,\n roomId: room.id,\n createdAt,\n type: \"comment\",\n userId: getCurrentUserId(room),\n body,\n reactions: [],\n };\n const newThread: ThreadData<M> = {\n id: threadId,\n type: \"thread\",\n createdAt,\n updatedAt: createdAt,\n roomId: room.id,\n metadata,\n comments: [newComment],\n resolved: false,\n };\n\n const optimisticUpdateId = nanoid();\n\n const { store, onMutationFailure } = getExtrasForClient(client);\n store.pushOptimisticUpdate({\n type: \"create-thread\",\n thread: newThread,\n id: optimisticUpdateId,\n roomId: room.id,\n });\n\n room.createThread({ threadId, commentId, body, metadata }).then(\n (thread) => {\n store.set((state) => ({\n ...state,\n threads: {\n ...state.threads,\n [threadId]: thread,\n },\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n }));\n },\n (err: Error) =>\n onMutationFailure(\n err,\n optimisticUpdateId,\n (err) =>\n new CreateThreadError(err, {\n roomId: room.id,\n threadId,\n commentId,\n body,\n metadata,\n })\n )\n );\n\n return newThread;\n },\n [client, room]\n );\n}\n\nfunction useDeleteThread(): (threadId: string) => void {\n const client = useClient();\n const room = useRoom();\n return React.useCallback(\n (threadId: string): void => {\n const optimisticUpdateId = nanoid();\n\n const { store, onMutationFailure } = getExtrasForClient(client);\n\n const thread = store.get().threads[threadId];\n\n const userId = getCurrentUserId(room);\n\n if (thread?.comments?.[0]?.userId !== userId) {\n throw new Error(\"Only the thread creator can delete the thread\");\n }\n\n store.pushOptimisticUpdate({\n type: \"delete-thread\",\n id: optimisticUpdateId,\n roomId: room.id,\n threadId,\n deletedAt: new Date(),\n });\n\n room.deleteThread(threadId).then(\n () => {\n store.set((state) => {\n const existingThread = state.threads[threadId];\n if (existingThread === undefined) {\n return state;\n }\n\n return {\n ...state,\n threads: {\n ...state.threads,\n [threadId]: {\n ...existingThread,\n updatedAt: new Date(),\n deletedAt: new Date(),\n },\n },\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n };\n });\n },\n (err: Error) =>\n onMutationFailure(\n err,\n optimisticUpdateId,\n (err) => new DeleteThreadError(err, { roomId: room.id, threadId })\n )\n );\n },\n [client, room]\n );\n}\n\nfunction useEditThreadMetadata<M extends BaseMetadata>() {\n const client = useClient();\n const room = useRoom();\n return React.useCallback(\n (options: EditThreadMetadataOptions<M>): void => {\n if (!options.metadata) {\n return;\n }\n\n const threadId = options.threadId;\n const metadata = options.metadata;\n const updatedAt = new Date();\n\n const optimisticUpdateId = nanoid();\n\n const { store, onMutationFailure } = getExtrasForClient(client);\n store.pushOptimisticUpdate({\n type: \"edit-thread-metadata\",\n metadata,\n id: optimisticUpdateId,\n threadId,\n updatedAt,\n });\n\n room.editThreadMetadata({ metadata, threadId }).then(\n (metadata) => {\n store.set((state) => {\n const existingThread = state.threads[threadId];\n const updatedOptimisticUpdates = state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n );\n\n // If the thread doesn't exist in the cache, we do not update the metadata\n if (existingThread === undefined) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n // If the thread has been deleted, we do not update the metadata\n if (existingThread.deletedAt !== undefined) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n if (\n existingThread.updatedAt &&\n existingThread.updatedAt > updatedAt\n ) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n return {\n ...state,\n threads: {\n ...state.threads,\n [threadId]: {\n ...existingThread,\n metadata,\n },\n },\n optimisticUpdates: updatedOptimisticUpdates,\n };\n });\n },\n (err: Error) =>\n onMutationFailure(\n err,\n optimisticUpdateId,\n (error) =>\n new EditThreadMetadataError(error, {\n roomId: room.id,\n threadId,\n metadata,\n })\n )\n );\n },\n [client, room]\n );\n}\n\n/**\n * Returns a function that adds a comment to a thread.\n *\n * @example\n * const createComment = useCreateComment();\n * createComment({ threadId: \"th_xxx\", body: {} });\n */\nfunction useCreateComment(): (options: CreateCommentOptions) => CommentData {\n const client = useClient();\n const room = useRoom();\n return React.useCallback(\n ({ threadId, body }: CreateCommentOptions): CommentData => {\n const commentId = createCommentId();\n const createdAt = new Date();\n\n const comment: CommentData = {\n id: commentId,\n threadId,\n roomId: room.id,\n type: \"comment\",\n createdAt,\n userId: getCurrentUserId(room),\n body,\n reactions: [],\n };\n\n const optimisticUpdateId = nanoid();\n\n const { store, onMutationFailure } = getExtrasForClient(client);\n store.pushOptimisticUpdate({\n type: \"create-comment\",\n comment,\n id: optimisticUpdateId,\n });\n\n room.createComment({ threadId, commentId, body }).then(\n (newComment) => {\n store.set((state) => {\n const existingThread = state.threads[threadId];\n const updatedOptimisticUpdates = state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n );\n\n if (existingThread === undefined) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n const inboxNotification = Object.values(\n state.inboxNotifications\n ).find(\n (notification) =>\n notification.kind === \"thread\" &&\n notification.threadId === threadId\n );\n\n // If the thread has an inbox notification associated with it, we update the notification's `notifiedAt` and `readAt` values\n const updatedInboxNotifications =\n inboxNotification !== undefined\n ? {\n ...state.inboxNotifications,\n [inboxNotification.id]: {\n ...inboxNotification,\n notifiedAt: newComment.createdAt,\n readAt: newComment.createdAt,\n },\n }\n : state.inboxNotifications;\n\n return {\n ...state,\n threads: {\n ...state.threads,\n [threadId]: upsertComment(existingThread, newComment), // Upsert the new comment into the thread comments list (if applicable)\n },\n inboxNotifications: updatedInboxNotifications,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n });\n },\n (err: Error) =>\n onMutationFailure(\n err,\n optimisticUpdateId,\n (err) =>\n new CreateCommentError(err, {\n roomId: room.id,\n threadId,\n commentId,\n body,\n })\n )\n );\n\n return comment;\n },\n [client, room]\n );\n}\n\n/**\n * Returns a function that edits a comment's body.\n *\n * @example\n * const editComment = useEditComment()\n * editComment({ threadId: \"th_xxx\", commentId: \"cm_xxx\", body: {} })\n */\nfunction useEditComment(): (options: EditCommentOptions) => void {\n const client = useClient();\n const room = useRoom();\n return React.useCallback(\n ({ threadId, commentId, body }: EditCommentOptions): void => {\n const editedAt = new Date();\n const optimisticUpdateId = nanoid();\n\n const { store, onMutationFailure } = getExtrasForClient(client);\n const thread = store.get().threads[threadId];\n if (thread === undefined) {\n console.warn(\n `Internal unexpected behavior. Cannot edit comment in thread \"${threadId}\" because the thread does not exist in the cache.`\n );\n return;\n }\n\n const comment = thread.comments.find(\n (comment) => comment.id === commentId\n );\n\n if (comment === undefined || comment.deletedAt !== undefined) {\n console.warn(\n `Internal unexpected behavior. Cannot edit comment \"${commentId}\" in thread \"${threadId}\" because the comment does not exist in the cache.`\n );\n return;\n }\n\n store.pushOptimisticUpdate({\n type: \"edit-comment\",\n comment: {\n ...comment,\n editedAt,\n body,\n },\n id: optimisticUpdateId,\n });\n\n room.editComment({ threadId, commentId, body }).then(\n (editedComment) => {\n store.set((state) => {\n const existingThread = state.threads[threadId];\n const updatedOptimisticUpdates = state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n );\n\n if (existingThread === undefined) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n return {\n ...state,\n threads: {\n ...state.threads,\n [threadId]: upsertComment(existingThread, editedComment), // Upsert the edited comment into the thread comments list (if applicable)\n },\n optimisticUpdates: updatedOptimisticUpdates,\n };\n });\n },\n (err: Error) =>\n onMutationFailure(\n err,\n optimisticUpdateId,\n (error) =>\n new EditCommentError(error, {\n roomId: room.id,\n threadId,\n commentId,\n body,\n })\n )\n );\n },\n [client, room]\n );\n}\n\n/**\n * Returns a function that deletes a comment.\n * If it is the last non-deleted comment, the thread also gets deleted.\n *\n * @example\n * const deleteComment = useDeleteComment();\n * deleteComment({ threadId: \"th_xxx\", commentId: \"cm_xxx\" })\n */\nfunction useDeleteComment() {\n const client = useClient();\n const room = useRoom();\n\n return React.useCallback(\n ({ threadId, commentId }: DeleteCommentOptions): void => {\n const deletedAt = new Date();\n\n const optimisticUpdateId = nanoid();\n\n const { store, onMutationFailure } = getExtrasForClient(client);\n store.pushOptimisticUpdate({\n type: \"delete-comment\",\n threadId,\n commentId,\n deletedAt,\n id: optimisticUpdateId,\n roomId: room.id,\n });\n\n room.deleteComment({ threadId, commentId }).then(\n () => {\n store.set((state) => {\n const existingThread = state.threads[threadId];\n const updatedOptimisticUpdates = state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n );\n\n // If thread does not exist, we return the existing state\n if (existingThread === undefined) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n return {\n ...state,\n threads: {\n ...state.threads,\n [threadId]: deleteComment(existingThread, commentId, deletedAt),\n },\n optimisticUpdates: updatedOptimisticUpdates,\n };\n });\n },\n (err: Error) =>\n onMutationFailure(\n err,\n optimisticUpdateId,\n (error) =>\n new DeleteCommentError(error, {\n roomId: room.id,\n threadId,\n commentId,\n })\n )\n );\n },\n [client, room]\n );\n}\n\nfunction useAddReaction<M extends BaseMetadata>() {\n const client = useClient();\n const room = useRoom();\n return React.useCallback(\n ({ threadId, commentId, emoji }: CommentReactionOptions): void => {\n const createdAt = new Date();\n const userId = getCurrentUserId(room);\n\n const optimisticUpdateId = nanoid();\n\n const { store, onMutationFailure } = getExtrasForClient<M>(client);\n store.pushOptimisticUpdate({\n type: \"add-reaction\",\n threadId,\n commentId,\n reaction: {\n emoji,\n userId,\n createdAt,\n },\n id: optimisticUpdateId,\n });\n\n room.addReaction({ threadId, commentId, emoji }).then(\n (addedReaction) => {\n store.set((state): CacheState<M> => {\n const existingThread = state.threads[threadId];\n const updatedOptimisticUpdates = state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n );\n\n // If the thread doesn't exist in the cache, we do not update the metadata\n if (existingThread === undefined) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n return {\n ...state,\n threads: {\n ...state.threads,\n [threadId]: addReaction(\n existingThread,\n commentId,\n addedReaction\n ),\n },\n optimisticUpdates: updatedOptimisticUpdates,\n };\n });\n },\n (err: Error) =>\n onMutationFailure(\n err,\n optimisticUpdateId,\n (error) =>\n new AddReactionError(error, {\n roomId: room.id,\n threadId,\n commentId,\n emoji,\n })\n )\n );\n },\n [client, room]\n );\n}\n\n/**\n * Returns a function that removes a reaction on a comment.\n *\n * @example\n * const removeReaction = useRemoveReaction();\n * removeReaction({ threadId: \"th_xxx\", commentId: \"cm_xxx\", emoji: \"👍\" })\n */\nfunction useRemoveReaction() {\n const client = useClient();\n const room = useRoom();\n return React.useCallback(\n ({ threadId, commentId, emoji }: CommentReactionOptions): void => {\n const userId = getCurrentUserId(room);\n\n const removedAt = new Date();\n const optimisticUpdateId = nanoid();\n\n const { store, onMutationFailure } = getExtrasForClient(client);\n store.pushOptimisticUpdate({\n type: \"remove-reaction\",\n threadId,\n commentId,\n emoji,\n userId,\n removedAt,\n id: optimisticUpdateId,\n });\n\n room.removeReaction({ threadId, commentId, emoji }).then(\n () => {\n store.set((state) => {\n const existingThread = state.threads[threadId];\n const updatedOptimisticUpdates = state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n );\n\n // If the thread doesn't exist in the cache, we do not update the metadata\n if (existingThread === undefined) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n return {\n ...state,\n threads: {\n ...state.threads,\n [threadId]: removeReaction(\n existingThread,\n commentId,\n emoji,\n userId,\n removedAt\n ),\n },\n optimisticUpdates: updatedOptimisticUpdates,\n };\n });\n },\n (err: Error) =>\n onMutationFailure(\n err,\n optimisticUpdateId,\n (error) =>\n new RemoveReactionError(error, {\n roomId: room.id,\n threadId,\n commentId,\n emoji,\n })\n )\n );\n },\n [client, room]\n );\n}\n\n/**\n * Returns a function that marks a thread as read.\n *\n * @example\n * const markThreadAsRead = useMarkThreadAsRead();\n * markThreadAsRead(\"th_xxx\");\n */\nfunction useMarkThreadAsRead() {\n const client = useClient();\n const room = useRoom();\n return React.useCallback(\n (threadId: string) => {\n const { store, onMutationFailure } = getExtrasForClient(client);\n const inboxNotification = Object.values(\n store.get().inboxNotifications\n ).find(\n (inboxNotification) =>\n inboxNotification.kind === \"thread\" &&\n inboxNotification.threadId === threadId\n );\n\n if (!inboxNotification) return;\n\n const optimisticUpdateId = nanoid();\n const now = new Date();\n\n store.pushOptimisticUpdate({\n type: \"mark-inbox-notification-as-read\",\n id: optimisticUpdateId,\n inboxNotificationId: inboxNotification.id,\n readAt: now,\n });\n\n room.markInboxNotificationAsRead(inboxNotification.id).then(\n () => {\n store.set((state) => ({\n ...state,\n inboxNotifications: {\n ...state.inboxNotifications,\n [inboxNotification.id]: {\n ...inboxNotification,\n readAt: now,\n },\n },\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n }));\n },\n (err: Error) => {\n onMutationFailure(\n err,\n optimisticUpdateId,\n (error) =>\n new MarkInboxNotificationAsReadError(error, {\n inboxNotificationId: inboxNotification.id,\n })\n );\n return;\n }\n );\n },\n [client, room]\n );\n}\n\n/**\n * Returns a function that marks a thread as resolved.\n *\n * @example\n * const markThreadAsResolved = useMarkThreadAsResolved();\n * markThreadAsResolved(\"th_xxx\");\n */\nfunction useMarkThreadAsResolved() {\n const client = useClient();\n const room = useRoom();\n return React.useCallback(\n (threadId: string) => {\n const optimisticUpdateId = nanoid();\n const updatedAt = new Date();\n\n const { store, onMutationFailure } = getExtrasForClient(client);\n store.pushOptimisticUpdate({\n type: \"mark-thread-as-resolved\",\n id: optimisticUpdateId,\n threadId,\n updatedAt,\n });\n\n room.markThreadAsResolved(threadId).then(\n () => {\n store.set((state) => {\n const existingThread = state.threads[threadId];\n const updatedOptimisticUpdates = state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n );\n\n // If the thread doesn't exist in the cache, we do not update the resolved property\n if (existingThread === undefined) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n // If the thread has been deleted, we do not update the resolved property\n if (existingThread.deletedAt !== undefined) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n if (\n existingThread.updatedAt &&\n existingThread.updatedAt > updatedAt\n ) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n return {\n ...state,\n threads: {\n ...state.threads,\n [threadId]: {\n ...existingThread,\n resolved: true,\n },\n },\n optimisticUpdates: updatedOptimisticUpdates,\n };\n });\n },\n (err: Error) =>\n onMutationFailure(\n err,\n optimisticUpdateId,\n (error) =>\n new MarkThreadAsResolvedError(error, {\n roomId: room.id,\n threadId,\n })\n )\n );\n },\n [client, room]\n );\n}\n\n/**\n * Returns a function that marks a thread as unresolved.\n *\n * @example\n * const markThreadAsUnresolved = useMarkThreadAsUnresolved();\n * markThreadAsUnresolved(\"th_xxx\");\n */\nfunction useMarkThreadAsUnresolved() {\n const client = useClient();\n const room = useRoom();\n return React.useCallback(\n (threadId: string) => {\n const optimisticUpdateId = nanoid();\n const updatedAt = new Date();\n\n const { store, onMutationFailure } = getExtrasForClient(client);\n store.pushOptimisticUpdate({\n type: \"mark-thread-as-unresolved\",\n id: optimisticUpdateId,\n threadId,\n updatedAt,\n });\n\n room.markThreadAsUnresolved(threadId).then(\n () => {\n store.set((state) => {\n const existingThread = state.threads[threadId];\n const updatedOptimisticUpdates = state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n );\n\n // If the thread doesn't exist in the cache, we do not update the resolved property\n if (existingThread === undefined) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n // If the thread has been deleted, we do not update the resolved property\n if (existingThread.deletedAt !== undefined) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n if (\n existingThread.updatedAt &&\n existingThread.updatedAt > updatedAt\n ) {\n return {\n ...state,\n optimisticUpdates: updatedOptimisticUpdates,\n };\n }\n\n return {\n ...state,\n threads: {\n ...state.threads,\n [threadId]: {\n ...existingThread,\n resolved: false,\n },\n },\n optimisticUpdates: updatedOptimisticUpdates,\n };\n });\n },\n (err: Error) =>\n onMutationFailure(\n err,\n optimisticUpdateId,\n (error) =>\n new MarkThreadAsUnresolvedError(error, {\n roomId: room.id,\n threadId,\n })\n )\n );\n },\n [client, room]\n );\n}\n\n/**\n * Returns the subscription status of a thread.\n *\n * @example\n * const { status, unreadSince } = useThreadSubscription(\"th_xxx\");\n */\nfunction useThreadSubscription(threadId: string): ThreadSubscription {\n const client = useClient();\n const { store } = getExtrasForClient(client);\n\n const selector = React.useCallback(\n (state: CacheState<BaseMetadata>): ThreadSubscription => {\n const inboxNotification = selectedInboxNotifications(state).find(\n (inboxNotification) =>\n inboxNotification.kind === \"thread\" &&\n inboxNotification.threadId === threadId\n );\n\n const thread = state.threads[threadId];\n\n if (inboxNotification === undefined || thread === undefined) {\n return {\n status: \"not-subscribed\",\n };\n }\n\n return {\n status: \"subscribed\",\n unreadSince: inboxNotification.readAt,\n };\n },\n [threadId]\n );\n\n return useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n selector\n );\n}\n\n/**\n * Returns the user's notification settings for the current room\n * and a function to update them.\n *\n * @example\n * const [{ settings }, updateSettings] = useRoomNotificationSettings();\n */\nfunction useRoomNotificationSettings(): [\n RoomNotificationSettingsState,\n (settings: Partial<RoomNotificationSettings>) => void,\n] {\n const client = useClient();\n const room = useRoom();\n const { store } = getExtrasForClient(client);\n\n React.useEffect(() => {\n const { getInboxNotificationSettings } = getExtrasForClient(client);\n const queryKey = makeNotificationSettingsQueryKey(room.id);\n void getInboxNotificationSettings(room, queryKey);\n }, [client, room]);\n\n const updateRoomNotificationSettings = useUpdateRoomNotificationSettings();\n\n const selector = React.useCallback(\n (state: CacheState<BaseMetadata>): RoomNotificationSettingsState => {\n const query = state.queries[makeNotificationSettingsQueryKey(room.id)];\n\n if (query === undefined || query.isLoading) {\n return { isLoading: true };\n }\n\n if (query.error !== undefined) {\n return { isLoading: false, error: query.error };\n }\n\n return {\n isLoading: false,\n settings: selectNotificationSettings(room.id, state),\n };\n },\n [room]\n );\n\n const settings = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n selector\n );\n\n return React.useMemo(() => {\n return [settings, updateRoomNotificationSettings];\n }, [settings, updateRoomNotificationSettings]);\n}\n\nfunction useHistoryVersionData(versionId: string): HistoryVersionDataState {\n const [state, setState] = React.useState<HistoryVersionDataState>({\n isLoading: true,\n });\n const room = useRoom();\n React.useEffect(() => {\n setState({ isLoading: true });\n const load = async () => {\n try {\n const response = await room[kInternal].getTextVersion(versionId);\n const buffer = await response.arrayBuffer();\n const data = new Uint8Array(buffer);\n setState({\n isLoading: false,\n data,\n });\n } catch (error) {\n setState({\n isLoading: false,\n error:\n error instanceof Error\n ? error\n : new Error(\n \"An unknown error occurred while loading this version\"\n ),\n });\n }\n };\n void load();\n }, [room, versionId]);\n return state;\n}\n\n/**\n * Returns a history of versions of the current room.\n *\n * @example\n * const { versions, error, isLoading } = useHistoryVersions();\n */\nfunction useHistoryVersions(): HistoryVersionsState {\n const client = useClient();\n const room = useRoom();\n const queryKey = getVersionsQueryKey(room.id);\n\n const { store, getRoomVersions } = getExtrasForClient(client);\n\n React.useEffect(() => {\n void getRoomVersions(room);\n }, [room]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const selector = React.useCallback(\n (state: CacheState<BaseMetadata>): HistoryVersionsState => {\n const query = state.queries[queryKey];\n if (query === undefined || query.isLoading) {\n return {\n isLoading: true,\n };\n }\n\n return {\n versions: state.versions[room.id],\n isLoading: false,\n error: query.error,\n };\n },\n [room, queryKey] // eslint-disable-line react-hooks/exhaustive-deps\n );\n\n const state = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n selector\n );\n\n return state;\n}\n\n/**\n * Returns a function that updates the user's notification settings\n * for the current room.\n *\n * @example\n * const updateRoomNotificationSettings = useUpdateRoomNotificationSettings();\n * updateRoomNotificationSettings({ threads: \"all\" });\n */\nfunction useUpdateRoomNotificationSettings() {\n const client = useClient();\n const room = useRoom();\n return React.useCallback(\n (settings: Partial<RoomNotificationSettings>) => {\n const optimisticUpdateId = nanoid();\n\n const { store, onMutationFailure } = getExtrasForClient(client);\n store.pushOptimisticUpdate({\n id: optimisticUpdateId,\n type: \"update-notification-settings\",\n roomId: room.id,\n settings,\n });\n\n room.updateNotificationSettings(settings).then(\n (settings) => {\n store.set((state) => ({\n ...state,\n notificationSettings: {\n [room.id]: settings,\n },\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n }));\n },\n (err: Error) =>\n onMutationFailure(\n err,\n optimisticUpdateId,\n (error) =>\n new UpdateNotificationSettingsError(error, {\n roomId: room.id,\n })\n )\n );\n },\n [client, room]\n );\n}\n\nfunction ensureNotServerSide(): void {\n // Error early if suspense is used in a server-side context\n if (typeof window === \"undefined\") {\n throw new Error(\n \"You cannot use the Suspense version of this hook on the server side. Make sure to only call them on the client side.\\nFor tips, see https://liveblocks.io/docs/api-reference/liveblocks-react#suspense-avoid-ssr\"\n );\n }\n}\n\nfunction useSuspendUntilPresenceReady(): void {\n // Throw an error if we're calling this on the server side\n ensureNotServerSide();\n\n const room = useRoom();\n use(room.waitUntilPresenceReady());\n}\n\nfunction useSelfSuspense<P extends JsonObject, U extends BaseUserMeta>(): User<\n P,\n U\n>;\nfunction useSelfSuspense<P extends JsonObject, U extends BaseUserMeta, T>(\n selector: (me: User<P, U>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n): T;\nfunction useSelfSuspense<P extends JsonObject, U extends BaseUserMeta, T>(\n selector?: (me: User<P, U>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n): T | User<P, U> {\n useSuspendUntilPresenceReady();\n return useSelf(\n selector as (me: User<P, U>) => T,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T | User<P, U>;\n}\n\nfunction useOthersSuspense<\n P extends JsonObject,\n U extends BaseUserMeta,\n>(): readonly User<P, U>[];\nfunction useOthersSuspense<P extends JsonObject, U extends BaseUserMeta, T>(\n selector: (others: readonly User<P, U>[]) => T,\n isEqual?: (prev: T, curr: T) => boolean\n): T;\nfunction useOthersSuspense<P extends JsonObject, U extends BaseUserMeta, T>(\n selector?: (others: readonly User<P, U>[]) => T,\n isEqual?: (prev: T, curr: T) => boolean\n): T | readonly User<P, U>[] {\n useSuspendUntilPresenceReady();\n return useOthers(\n selector as (others: readonly User<P, U>[]) => T,\n isEqual as (prev: T, curr: T) => boolean\n ) as T | readonly User<P, U>[];\n}\n\n/**\n * Returns an array of connection IDs. This matches the values you'll get by\n * using the `useOthers()` hook.\n *\n * Roughly equivalent to:\n * useOthers((others) => others.map(other => other.connectionId), shallow)\n *\n * This is useful in particular to implement efficiently rendering components\n * for each user in the room, e.g. cursors.\n *\n * @example\n * const ids = useOthersConnectionIds();\n * // [2, 4, 7]\n */\nfunction useOthersConnectionIdsSuspense(): readonly number[] {\n useSuspendUntilPresenceReady();\n return useOthersConnectionIds();\n}\n\nfunction useOthersMappedSuspense<\n P extends JsonObject,\n U extends BaseUserMeta,\n T,\n>(\n itemSelector: (other: User<P, U>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n): ReadonlyArray<readonly [connectionId: number, data: T]> {\n useSuspendUntilPresenceReady();\n return useOthersMapped(itemSelector, itemIsEqual);\n}\n\nfunction useOtherSuspense<P extends JsonObject, U extends BaseUserMeta, T>(\n connectionId: number,\n selector: (other: User<P, U>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n): T {\n useSuspendUntilPresenceReady();\n return useOther(connectionId, selector, isEqual);\n}\n\nfunction useSuspendUntilStorageReady(): void {\n // Throw an error if we're calling this on the server side\n ensureNotServerSide();\n\n const room = useRoom();\n use(room.waitUntilStorageReady());\n}\n\nfunction useStorageSuspense<S extends LsonObject, T>(\n selector: (root: ToImmutable<S>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n): T {\n useSuspendUntilStorageReady();\n return useStorage(\n selector,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T;\n}\n\n/**\n * Returns the current storage status for the Room, and triggers\n * a re-render whenever it changes. Can be used to render a \"Saving...\"\n * indicator.\n */\nfunction useStorageStatusSuspense(\n options?: UseStorageStatusOptions\n): StorageStatusSuccess {\n useSuspendUntilStorageReady();\n return useStorageStatus(options) as StorageStatusSuccess;\n}\n\nfunction useThreadsSuspense<M extends BaseMetadata>(\n options: UseThreadsOptions<M> = {\n query: { metadata: {} },\n }\n): ThreadsStateSuccess<M> {\n const { scrollOnLoad = true } = options;\n\n const client = useClient();\n const room = useRoom();\n const queryKey = React.useMemo(\n () => generateQueryKey(room.id, options.query),\n [room, options]\n );\n\n const { store, getThreadsAndInboxNotifications } =\n getExtrasForClient<M>(client);\n\n const query = store.get().queries[queryKey];\n\n if (query === undefined || query.isLoading) {\n throw getThreadsAndInboxNotifications(room, queryKey, options);\n }\n\n if (query.error) {\n throw query.error;\n }\n\n const selector = React.useCallback(\n (state: CacheState<M>): ThreadsStateSuccess<M> => {\n return {\n threads: selectedThreads(room.id, state, options),\n isLoading: false,\n };\n },\n [room, queryKey] // eslint-disable-line react-hooks/exhaustive-deps\n );\n\n React.useEffect(() => {\n const { incrementQuerySubscribers } = getExtrasForClient(client);\n return incrementQuerySubscribers(queryKey);\n }, [client, queryKey]);\n\n const state = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n selector\n );\n\n useScrollToCommentOnLoadEffect(scrollOnLoad, state);\n\n return state;\n}\n\n/**\n * Returns a history of versions of the current room.\n *\n * @example\n * const { versions } = useHistoryVersions();\n */\nfunction useHistoryVersionsSuspense(): HistoryVersionsStateResolved {\n const client = useClient();\n const room = useRoom();\n const queryKey = getVersionsQueryKey(room.id);\n\n const { store, getRoomVersions } = getExtrasForClient(client);\n\n const query = store.get().queries[queryKey];\n\n if (query === undefined || query.isLoading) {\n throw getRoomVersions(room);\n }\n\n if (query.error) {\n throw query.error;\n }\n\n const selector = React.useCallback(\n (state: CacheState<BaseMetadata>): HistoryVersionsStateResolved => {\n return {\n versions: state.versions[room.id],\n isLoading: false,\n };\n },\n [room, queryKey] // eslint-disable-line react-hooks/exhaustive-deps\n );\n\n const state = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n selector\n );\n\n return state;\n}\n\n/**\n * Returns the user's notification settings for the current room\n * and a function to update them.\n *\n * @example\n * const [{ settings }, updateSettings] = useRoomNotificationSettings();\n */\nfunction useRoomNotificationSettingsSuspense(): [\n RoomNotificationSettingsStateSuccess,\n (settings: Partial<RoomNotificationSettings>) => void,\n] {\n const updateRoomNotificationSettings = useUpdateRoomNotificationSettings();\n const client = useClient();\n const room = useRoom();\n const queryKey = makeNotificationSettingsQueryKey(room.id);\n\n const { store, getInboxNotificationSettings } = getExtrasForClient(client);\n const query = store.get().queries[queryKey];\n\n if (query === undefined || query.isLoading) {\n throw getInboxNotificationSettings(room, queryKey);\n }\n\n if (query.error) {\n throw query.error;\n }\n\n const selector = React.useCallback(\n (state: CacheState<BaseMetadata>): RoomNotificationSettingsStateSuccess => {\n return {\n isLoading: false,\n settings: selectNotificationSettings(room.id, state),\n };\n },\n [room]\n );\n\n const settings = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n selector\n );\n\n return React.useMemo(() => {\n return [settings, updateRoomNotificationSettings];\n }, [settings, updateRoomNotificationSettings]);\n}\n\n/** @internal */\nexport function useRoomOrNull<\n P extends JsonObject,\n S extends LsonObject,\n U extends BaseUserMeta,\n E extends Json,\n M extends BaseMetadata,\n>(): Room<P, S, U, E, M> | null {\n return React.useContext(RoomContext) as Room<P, S, U, E, M> | null;\n}\n\n/**\n * @private\n *\n * This is an internal API, use `createRoomContext` instead.\n */\nexport function useRoomContextBundleOrNull() {\n const client = useClientOrNull();\n const room = useRoomOrNull<never, never, never, never, never>();\n return client && room ? getOrCreateRoomContextBundle(client) : null;\n}\n\n/**\n * @private\n *\n * This is an internal API, use `createRoomContext` instead.\n */\nexport function useRoomContextBundle() {\n const client = useClient();\n return getOrCreateRoomContextBundle(client);\n}\n\n/**\n * Creates a RoomProvider and a set of typed hooks to use in your app. Note\n * that any RoomProvider created in this way does not need to be nested in\n * LiveblocksProvider, as it already has access to the client.\n */\nexport function createRoomContext<\n P extends JsonObject = DP,\n S extends LsonObject = DS,\n U extends BaseUserMeta = DU,\n E extends Json = DE,\n M extends BaseMetadata = DM,\n>(client: OpaqueClient): RoomContextBundle<P, S, U, E, M> {\n return getOrCreateRoomContextBundle<P, S, U, E, M>(client);\n}\n\nexport function generateQueryKey(\n roomId: string,\n options: UseThreadsOptions<BaseMetadata>[\"query\"]\n) {\n return `${roomId}-${stringify(options ?? {})}`;\n}\n\nexport function getVersionsQueryKey(roomId: string) {\n return `${roomId}-VERSIONS`;\n}\n\ntype TypedBundle = RoomContextBundle<DP, DS, DU, DE, DM>;\n\n/**\n * Makes a Room available in the component hierarchy below.\n * Joins the room when the component is mounted, and automatically leaves\n * the room when the component is unmounted.\n */\nconst _RoomProvider: TypedBundle[\"RoomProvider\"] = RoomProvider;\n\n/**\n * Returns a callback that lets you broadcast custom events to other users in the room\n *\n * @example\n * const broadcast = useBroadcastEvent();\n *\n * broadcast({ type: \"CUSTOM_EVENT\", data: { x: 0, y: 0 } });\n */\nconst _useBroadcastEvent: TypedBundle[\"useBroadcastEvent\"] = useBroadcastEvent;\n\n/**\n * Get informed when users enter or leave the room, as an event.\n *\n * @example\n * useOthersListener({ type, user, others }) => {\n * if (type === 'enter') {\n * // `user` has joined the room\n * } else if (type === 'leave') {\n * // `user` has left the room\n * }\n * })\n */\nconst _useOthersListener: TypedBundle[\"useOthersListener\"] = useOthersListener;\n\n/**\n * Returns the Room of the nearest RoomProvider above in the React component\n * tree.\n */\nconst _useRoom: TypedBundle[\"useRoom\"] = useRoom;\n\n/**\n * Returns whether the hook is called within a RoomProvider context.\n *\n * @example\n * const isInsideRoom = useIsInsideRoom();\n */\nconst _useIsInsideRoom: TypedBundle[\"useIsInsideRoom\"] = useIsInsideRoom;\n\n/**\n * Returns a function that adds a reaction from a comment.\n *\n * @example\n * const addReaction = useAddReaction();\n * addReaction({ threadId: \"th_xxx\", commentId: \"cm_xxx\", emoji: \"👍\" })\n */\nconst _useAddReaction: TypedBundle[\"useAddReaction\"] = useAddReaction;\n\n/**\n * Create a callback function that lets you mutate Liveblocks state.\n *\n * The first argument that gets passed into your callback will be\n * a \"mutation context\", which exposes the following:\n *\n * - `storage` - The mutable Storage root.\n * You can mutate any Live structures with this, for example:\n * `storage.get('layers').get('layer1').set('fill', 'red')`\n *\n * - `setMyPresence` - Call this with a new (partial) Presence value.\n *\n * - `self` - A read-only version of the latest self, if you need it to\n * compute the next state.\n *\n * - `others` - A read-only version of the latest others list, if you\n * need it to compute the next state.\n *\n * useMutation is like React's useCallback, except that the first argument\n * that gets passed into your callback will be a \"mutation context\".\n *\n * If you want get access to the immutable root somewhere in your mutation,\n * you can use `storage.ToImmutable()`.\n *\n * @example\n * const fillLayers = useMutation(\n * ({ storage }, color: Color) => {\n * ...\n * },\n * [],\n * );\n *\n * fillLayers('red');\n *\n * const deleteLayers = useMutation(\n * ({ storage }) => {\n * ...\n * },\n * [],\n * );\n *\n * deleteLayers();\n */\nconst _useMutation: TypedBundle[\"useMutation\"] = useMutation;\n\n/**\n * Returns a function that creates a thread with an initial comment, and optionally some metadata.\n *\n * @example\n * const createThread = useCreateThread();\n * createThread({ body: {}, metadata: {} });\n */\nconst _useCreateThread: TypedBundle[\"useCreateThread\"] = useCreateThread;\n\n/**\n * Returns a function that deletes a thread and its associated comments.\n * Only the thread creator can delete a thread, it will throw otherwise.\n *\n * @example\n * const deleteThread = useDeleteThread();\n * deleteThread(\"th_xxx\");\n */\nconst _useDeleteThread: TypedBundle[\"useDeleteThread\"] = useDeleteThread;\n\n/**\n * Returns a function that edits a thread's metadata.\n * To delete an existing metadata property, set its value to `null`.\n *\n * @example\n * const editThreadMetadata = useEditThreadMetadata();\n * editThreadMetadata({ threadId: \"th_xxx\", metadata: {} })\n */\nconst _useEditThreadMetadata: TypedBundle[\"useEditThreadMetadata\"] =\n useEditThreadMetadata;\n\n/**\n * useEventListener is a React hook that allows you to respond to events broadcast\n * by other users in the room.\n *\n * The `user` argument will indicate which `User` instance sent the message.\n * This will be equal to one of the others in the room, but it can be `null`\n * in case this event was broadcasted from the server.\n *\n * @example\n * useEventListener(({ event, user, connectionId }) => {\n * // ^^^^ Will be Client A\n * if (event.type === \"CUSTOM_EVENT\") {\n * // Do something\n * }\n * });\n */\nconst _useEventListener: TypedBundle[\"useEventListener\"] = useEventListener;\n\n/**\n * Returns the presence of the current user of the current room, and a function to update it.\n * It is different from the setState function returned by the useState hook from React.\n * You don't need to pass the full presence object to update it.\n *\n * @example\n * const [myPresence, updateMyPresence] = useMyPresence();\n * updateMyPresence({ x: 0 });\n * updateMyPresence({ y: 0 });\n *\n * // At the next render, \"myPresence\" will be equal to \"{ x: 0, y: 0 }\"\n */\nconst _useMyPresence: TypedBundle[\"useMyPresence\"] = useMyPresence;\n\n/**\n * Related to useOthers(), but optimized for selecting only \"subsets\" of\n * others. This is useful for performance reasons in particular, because\n * selecting only a subset of users also means limiting the number of\n * re-renders that will be triggered.\n *\n * @example\n * const avatars = useOthersMapped(user => user.info.avatar);\n * // ^^^^^^^\n * // { connectionId: number; data: string }[]\n *\n * The selector function you pass to useOthersMapped() is called an \"item\n * selector\", and operates on a single user at a time. If you provide an\n * (optional) \"item comparison\" function, it will be used to compare each\n * item pairwise.\n *\n * For example, to select multiple properties:\n *\n * @example\n * const avatarsAndCursors = useOthersMapped(\n * user => [u.info.avatar, u.presence.cursor],\n * shallow, // 👈\n * );\n */\nconst _useOthersMapped: TypedBundle[\"useOthersMapped\"] = useOthersMapped;\n\n/**\n * Related to useOthers(), but optimized for selecting only \"subsets\" of\n * others. This is useful for performance reasons in particular, because\n * selecting only a subset of users also means limiting the number of\n * re-renders that will be triggered.\n *\n * @example\n * const avatars = useOthersMapped(user => user.info.avatar);\n * // ^^^^^^^\n * // { connectionId: number; data: string }[]\n *\n * The selector function you pass to useOthersMapped() is called an \"item\n * selector\", and operates on a single user at a time. If you provide an\n * (optional) \"item comparison\" function, it will be used to compare each\n * item pairwise.\n *\n * For example, to select multiple properties:\n *\n * @example\n * const avatarsAndCursors = useOthersMapped(\n * user => [u.info.avatar, u.presence.cursor],\n * shallow, // 👈\n * );\n */\nconst _useOthersMappedSuspense: TypedBundle[\"suspense\"][\"useOthersMapped\"] =\n useOthersMappedSuspense;\n\n/**\n * Returns the threads within the current room.\n *\n * @example\n * const { threads, error, isLoading } = useThreads();\n */\nconst _useThreads: TypedBundle[\"useThreads\"] = useThreads;\n\n/**\n * Returns the threads within the current room.\n *\n * @example\n * const { threads } = useThreads();\n */\nconst _useThreadsSuspense: TypedBundle[\"suspense\"][\"useThreads\"] =\n useThreadsSuspense;\n\n/**\n * Returns a history of versions of the current room.\n *\n * @example\n * const { versions, error, isLoading } = useHistoryVersions();\n */\nconst _useHistoryVersions: TypedBundle[\"useHistoryVersions\"] =\n useHistoryVersions;\n\n/**\n * Returns a history of versions of the current room.\n *\n * @example\n * const { versions } = useHistoryVersions();\n */\nconst _useHistoryVersionsSuspense: TypedBundle[\"suspense\"][\"useHistoryVersions\"] =\n useHistoryVersionsSuspense;\n\n/**\n * Given a connection ID (as obtained by using `useOthersConnectionIds`), you\n * can call this selector deep down in your component stack to only have the\n * component re-render if properties for this particular user change.\n *\n * @example\n * // Returns only the selected values re-renders whenever that selection changes)\n * const { x, y } = useOther(2, user => user.presence.cursor);\n */\nconst _useOther: TypedBundle[\"useOther\"] = useOther;\n\n/**\n * Returns an array with information about all the users currently connected in\n * the room (except yourself).\n *\n * @example\n * const others = useOthers();\n *\n * // Example to map all cursors in JSX\n * return (\n * <>\n * {others.map((user) => {\n * if (user.presence.cursor == null) {\n * return null;\n * }\n * return <Cursor key={user.connectionId} cursor={user.presence.cursor} />\n * })}\n * </>\n * )\n */\nfunction _useOthers(): readonly User<DP, DU>[];\n/**\n * Extract arbitrary data based on all the users currently connected in the\n * room (except yourself).\n *\n * The selector function will get re-evaluated any time a user enters or\n * leaves the room, as well as whenever their presence data changes.\n *\n * The component that uses this hook will automatically re-render if your\n * selector function returns a different value from its previous run.\n *\n * By default `useOthers()` uses strict `===` to check for equality. Take\n * extra care when returning a computed object or list, for example when you\n * return the result of a .map() or .filter() call from the selector. In\n * those cases, you'll probably want to use a `shallow` comparison check.\n *\n * @example\n * const avatars = useOthers(users => users.map(u => u.info.avatar), shallow);\n * const cursors = useOthers(users => users.map(u => u.presence.cursor), shallow);\n * const someoneIsTyping = useOthers(users => users.some(u => u.presence.isTyping));\n *\n */\nfunction _useOthers<T>(\n selector: (others: readonly User<DP, DU>[]) => T,\n isEqual?: (prev: T, curr: T) => boolean\n): T;\nfunction _useOthers(...args: any[]) {\n return useOthers(...(args as []));\n}\n\n/**\n * Given a connection ID (as obtained by using `useOthersConnectionIds`), you\n * can call this selector deep down in your component stack to only have the\n * component re-render if properties for this particular user change.\n *\n * @example\n * // Returns only the selected values re-renders whenever that selection changes)\n * const { x, y } = useOther(2, user => user.presence.cursor);\n */\nconst _useOtherSuspense: TypedBundle[\"suspense\"][\"useOther\"] = useOtherSuspense;\n\n/**\n * Returns an array with information about all the users currently connected in\n * the room (except yourself).\n *\n * @example\n * const others = useOthers();\n *\n * // Example to map all cursors in JSX\n * return (\n * <>\n * {others.map((user) => {\n * if (user.presence.cursor == null) {\n * return null;\n * }\n * return <Cursor key={user.connectionId} cursor={user.presence.cursor} />\n * })}\n * </>\n * )\n */\nfunction _useOthersSuspense(): readonly User<DP, DU>[];\n/**\n * Extract arbitrary data based on all the users currently connected in the\n * room (except yourself).\n *\n * The selector function will get re-evaluated any time a user enters or\n * leaves the room, as well as whenever their presence data changes.\n *\n * The component that uses this hook will automatically re-render if your\n * selector function returns a different value from its previous run.\n *\n * By default `useOthers()` uses strict `===` to check for equality. Take\n * extra care when returning a computed object or list, for example when you\n * return the result of a .map() or .filter() call from the selector. In\n * those cases, you'll probably want to use a `shallow` comparison check.\n *\n * @example\n * const avatars = useOthers(users => users.map(u => u.info.avatar), shallow);\n * const cursors = useOthers(users => users.map(u => u.presence.cursor), shallow);\n * const someoneIsTyping = useOthers(users => users.some(u => u.presence.isTyping));\n *\n */\nfunction _useOthersSuspense<T>(\n selector: (others: readonly User<DP, DU>[]) => T,\n isEqual?: (prev: T, curr: T) => boolean\n): T;\nfunction _useOthersSuspense(...args: any[]) {\n return useOthersSuspense(...(args as []));\n}\n\n/**\n * Extract arbitrary data from the Liveblocks Storage state, using an\n * arbitrary selector function.\n *\n * The selector function will get re-evaluated any time something changes in\n * Storage. The value returned by your selector function will also be the\n * value returned by the hook.\n *\n * The `root` value that gets passed to your selector function is\n * a immutable/readonly version of your Liveblocks storage root.\n *\n * The component that uses this hook will automatically re-render if the\n * returned value changes.\n *\n * By default `useStorage()` uses strict `===` to check for equality. Take\n * extra care when returning a computed object or list, for example when you\n * return the result of a .map() or .filter() call from the selector. In\n * those cases, you'll probably want to use a `shallow` comparison check.\n */\nconst _useStorage: TypedBundle[\"useStorage\"] = useStorage;\n\n/**\n * Extract arbitrary data from the Liveblocks Storage state, using an\n * arbitrary selector function.\n *\n * The selector function will get re-evaluated any time something changes in\n * Storage. The value returned by your selector function will also be the\n * value returned by the hook.\n *\n * The `root` value that gets passed to your selector function is\n * a immutable/readonly version of your Liveblocks storage root.\n *\n * The component that uses this hook will automatically re-render if the\n * returned value changes.\n *\n * By default `useStorage()` uses strict `===` to check for equality. Take\n * extra care when returning a computed object or list, for example when you\n * return the result of a .map() or .filter() call from the selector. In\n * those cases, you'll probably want to use a `shallow` comparison check.\n */\nconst _useStorageSuspense: TypedBundle[\"suspense\"][\"useStorage\"] =\n useStorageSuspense;\n\n/**\n * Gets the current user once it is connected to the room.\n *\n * @example\n * const me = useSelf();\n * if (me !== null) {\n * const { x, y } = me.presence.cursor;\n * }\n */\nfunction _useSelf(): User<DP, DU> | null;\n/**\n * Extract arbitrary data based on the current user.\n *\n * The selector function will get re-evaluated any time your presence data\n * changes.\n *\n * The component that uses this hook will automatically re-render if your\n * selector function returns a different value from its previous run.\n *\n * By default `useSelf()` uses strict `===` to check for equality. Take extra\n * care when returning a computed object or list, for example when you return\n * the result of a .map() or .filter() call from the selector. In those\n * cases, you'll probably want to use a `shallow` comparison check.\n *\n * Will return `null` while Liveblocks isn't connected to a room yet.\n *\n * @example\n * const cursor = useSelf(me => me.presence.cursor);\n * if (cursor !== null) {\n * const { x, y } = cursor;\n * }\n *\n */\nfunction _useSelf<T>(\n selector: (me: User<DP, DU>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n): T | null;\nfunction _useSelf(...args: any[]) {\n return useSelf(...(args as []));\n}\n\n/**\n * Gets the current user once it is connected to the room.\n *\n * @example\n * const me = useSelf();\n * const { x, y } = me.presence.cursor;\n */\nfunction _useSelfSuspense(): User<DP, DU>;\n/**\n * Extract arbitrary data based on the current user.\n *\n * The selector function will get re-evaluated any time your presence data\n * changes.\n *\n * The component that uses this hook will automatically re-render if your\n * selector function returns a different value from its previous run.\n *\n * By default `useSelf()` uses strict `===` to check for equality. Take extra\n * care when returning a computed object or list, for example when you return\n * the result of a .map() or .filter() call from the selector. In those\n * cases, you'll probably want to use a `shallow` comparison check.\n *\n * @example\n * const cursor = useSelf(me => me.presence.cursor);\n * const { x, y } = cursor;\n *\n */\nfunction _useSelfSuspense<T>(\n selector: (me: User<DP, DU>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n): T;\nfunction _useSelfSuspense(...args: any[]) {\n return useSelfSuspense(...(args as []));\n}\n\n/**\n * Returns the mutable (!) Storage root. This hook exists for\n * backward-compatible reasons.\n *\n * @example\n * const [root] = useStorageRoot();\n */\nconst _useStorageRoot: TypedBundle[\"useStorageRoot\"] = useStorageRoot;\n\n/**\n * useUpdateMyPresence is similar to useMyPresence but it only returns the function to update the current user presence.\n * If you don't use the current user presence in your component, but you need to update it (e.g. live cursor), it's better to use useUpdateMyPresence to avoid unnecessary renders.\n *\n * @example\n * const updateMyPresence = useUpdateMyPresence();\n * updateMyPresence({ x: 0 });\n * updateMyPresence({ y: 0 });\n *\n * // At the next render, the presence of the current user will be equal to \"{ x: 0, y: 0 }\"\n */\nconst _useUpdateMyPresence: TypedBundle[\"useUpdateMyPresence\"] =\n useUpdateMyPresence;\n\nexport {\n CreateThreadError,\n RoomContext,\n _RoomProvider as RoomProvider,\n _useAddReaction as useAddReaction,\n useBatch,\n _useBroadcastEvent as useBroadcastEvent,\n useCanRedo,\n useCanUndo,\n // TODO: Move to `liveblocks-react-lexical`\n useCommentsErrorListener,\n useCreateComment,\n _useCreateThread as useCreateThread,\n useDeleteComment,\n _useDeleteThread as useDeleteThread,\n useEditComment,\n _useEditThreadMetadata as useEditThreadMetadata,\n useErrorListener,\n _useEventListener as useEventListener,\n useHistory,\n useHistoryVersionData,\n _useHistoryVersions as useHistoryVersions,\n _useHistoryVersionsSuspense as useHistoryVersionsSuspense,\n _useIsInsideRoom as useIsInsideRoom,\n useLostConnectionListener,\n useMarkThreadAsRead,\n useMarkThreadAsResolved,\n useMarkThreadAsUnresolved,\n _useMutation as useMutation,\n _useMyPresence as useMyPresence,\n _useOther as useOther,\n _useOthers as useOthers,\n useOthersConnectionIds,\n useOthersConnectionIdsSuspense,\n _useOthersListener as useOthersListener,\n _useOthersMapped as useOthersMapped,\n _useOthersMappedSuspense as useOthersMappedSuspense,\n _useOthersSuspense as useOthersSuspense,\n _useOtherSuspense as useOtherSuspense,\n useRedo,\n useRemoveReaction,\n _useRoom as useRoom,\n useRoomNotificationSettings,\n _useSelf as useSelf,\n _useSelfSuspense as useSelfSuspense,\n useStatus,\n _useStorage as useStorage,\n _useStorageRoot as useStorageRoot,\n useStorageStatus,\n useStorageStatusSuspense,\n _useStorageSuspense as useStorageSuspense,\n _useThreads as useThreads,\n _useThreadsSuspense as useThreadsSuspense,\n useThreadSubscription,\n useUndo,\n _useUpdateMyPresence as useUpdateMyPresence,\n useUpdateRoomNotificationSettings,\n};\n","import {\n applyOptimisticUpdates,\n type BaseMetadata,\n type CacheState,\n nn,\n type RoomNotificationSettings,\n} from \"@liveblocks/core\";\n\nexport function selectNotificationSettings<M extends BaseMetadata>(\n roomId: string,\n state: CacheState<M>\n): RoomNotificationSettings {\n const { notificationSettings } = applyOptimisticUpdates(state);\n return nn(notificationSettings[roomId]);\n}\n","import type {\n BaseMetadata,\n CacheState,\n InboxNotificationData,\n} from \"@liveblocks/core\";\nimport { applyOptimisticUpdates } from \"@liveblocks/core\";\n\nexport function selectedInboxNotifications<M extends BaseMetadata>(\n state: CacheState<M>\n): InboxNotificationData[] {\n const result = applyOptimisticUpdates(state);\n\n return Object.values(result.inboxNotifications).sort(\n // Sort so that the most recent notifications are first\n (a, b) => b.notifiedAt.getTime() - a.notifiedAt.getTime()\n );\n}\n","import { wait } from \"@liveblocks/core\";\n\nconst MAX_ERROR_RETRY_COUNT = 5;\n\nconst ERROR_RETRY_INTERVAL = 5000; // 5 seconds\n\n/**\n * Retries an action using the exponential backoff algorithm\n * @param action The action to retry\n * @param retryCount The number of times the action has been retried\n */\nexport function retryError(action: () => void, retryCount: number) {\n if (retryCount >= MAX_ERROR_RETRY_COUNT) return;\n\n const timeout = Math.pow(2, retryCount) * ERROR_RETRY_INTERVAL;\n\n setTimeout(() => {\n void action();\n }, timeout);\n}\n\n/**\n * Wraps a promise factory. Will create promises until one succeeds. If\n * a promise rejects, it will retry calling the factory for at most `maxTries`\n * times. Between each attempt, it will inject a a backoff delay (in millis)\n * from the given array. If the array contains fewer items then `maxTries`,\n * then the last backoff number will be used indefinitely.\n *\n * If the last attempt is rejected too, the returned promise will fail too.\n *\n * @param promiseFn The promise factory to execute\n * @param maxTries The number of total tries (must be >=1)\n * @param backoff An array of timings to inject between each promise attempt\n */\nexport async function autoRetry<T>(\n promiseFn: () => Promise<T>,\n maxTries: number,\n backoff: number[]\n): Promise<T> {\n const fallbackBackoff = backoff.length > 0 ? backoff[backoff.length - 1] : 0;\n\n let attempt = 0;\n\n while (true) {\n attempt++;\n\n const promise = promiseFn();\n try {\n return await promise;\n } catch (err) {\n if (attempt >= maxTries) {\n // Fail the entire promise right now\n throw new Error(`Failed after ${maxTries} attempts: ${String(err)}`);\n }\n }\n\n // Do another retry\n const delay = backoff[attempt - 1] ?? fallbackBackoff;\n await wait(delay);\n }\n}\n","import type { Reducer } from \"react\";\nimport { useCallback, useReducer } from \"react\";\n\nimport { useLatest } from \"./use-latest\";\n\nconst noop = <T>(state: T) => state;\n\n/**\n * \"Freezes\" a given value, so that it will return the same value/instance on\n * each subsequent render. This can be used to freeze \"initial\" values for\n * custom hooks, much like how `useState(initialState)` or\n * `useRef(initialValue)` works.\n */\nexport function useInitial<T>(value: T): T {\n // Equivalent to useState(() => value)[0], but slightly more low-level\n return useReducer<Reducer<T, unknown>>(noop, value)[0];\n}\n\n/**\n * Like `useInitial`, but if the provided value is a function instance, will\n * instead return a stable wrapper that _is_ a stable reference itself between\n * re-renders, but one which will always call the _latest_ provided callback\n * instance.\n */\nexport function useInitialUnlessFunction<T>(latestValue: T): T {\n const frozenValue = useInitial(latestValue);\n\n // Normally the Rules of Hooks™ dictate that you should not call hooks\n // conditionally. In this case, we're good here, because the same code path\n // will always be taken on every subsequent render here, because we've frozen\n // the value.\n /* eslint-disable react-hooks/rules-of-hooks */\n if (typeof frozenValue === \"function\") {\n type Fn = T & ((...args: unknown[]) => unknown);\n const ref = useLatest(latestValue as Fn);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useCallback(((...args: unknown[]) => ref.current(...args)) as Fn, [\n ref,\n ]);\n } else {\n return frozenValue;\n }\n /* eslint-enable react-hooks/rules-of-hooks */\n}\n","import { useEffect, useRef } from \"react\";\n\n/**\n * Keeps a ref in sync with a given value that may or may not change on\n * every render.\n *\n * The purpose of this hook is to return a stable ref that can be passed\n * to a callback function so the callback can be registered but still can\n * access the latest value at a later point in time.\n */\nexport function useLatest<T>(value: T): { readonly current: T } {\n const ref = useRef(value);\n useEffect(() => {\n ref.current = value;\n }, [value]);\n return ref;\n}\n","// import React from \"react\";\n\n/**\n * Drop-in replacement for React 19's `use` hook.\n */\nexport const use =\n // React.use ||\n <T>(\n promise: Promise<T> & {\n status?: \"pending\" | \"fulfilled\" | \"rejected\";\n value?: T;\n reason?: unknown;\n }\n ): T => {\n if (promise.status === \"pending\") {\n throw promise;\n } else if (promise.status === \"fulfilled\") {\n return promise.value as T;\n } else if (promise.status === \"rejected\") {\n throw promise.reason;\n } else {\n promise.status = \"pending\";\n promise.then(\n (v) => {\n promise.status = \"fulfilled\";\n promise.value = v;\n },\n (e) => {\n promise.status = \"rejected\";\n promise.reason = e;\n }\n );\n throw promise;\n }\n };\n","import type {\n BaseMetadata,\n BaseUserMeta,\n Client,\n ThreadData,\n} from \"@liveblocks/client\";\nimport type {\n AsyncResult,\n BaseRoomInfo,\n CacheState,\n CacheStore,\n ClientOptions,\n DM,\n DU,\n OpaqueClient,\n PrivateClientApi,\n} from \"@liveblocks/core\";\nimport {\n assert,\n createClient,\n kInternal,\n makePoller,\n memoizeOnSuccess,\n nanoid,\n raise,\n shallow,\n} from \"@liveblocks/core\";\nimport type { PropsWithChildren } from \"react\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport { selectedInboxNotifications } from \"./comments/lib/selected-inbox-notifications\";\nimport { selectedUserThreads } from \"./comments/lib/selected-threads\";\nimport { autoRetry } from \"./lib/retry-error\";\nimport { useInitial, useInitialUnlessFunction } from \"./lib/use-initial\";\nimport { use } from \"./lib/use-polyfill\";\nimport { useIsInsideRoom } from \"./room\";\nimport type {\n InboxNotificationsState,\n LiveblocksContextBundle,\n RoomInfoAsyncResult,\n RoomInfoAsyncSuccess,\n SharedContextBundle,\n ThreadsState,\n ThreadsStateSuccess,\n UnreadInboxNotificationsCountState,\n UserAsyncResult,\n UserAsyncSuccess,\n} from \"./types\";\n\n/**\n * Raw access to the React context where the LiveblocksProvider stores the\n * current client. Exposed for advanced use cases only.\n *\n * @private This is a private/advanced API. Do not rely on it.\n */\nexport const ClientContext = createContext<OpaqueClient | null>(null);\n\nfunction missingUserError(userId: string) {\n return new Error(`resolveUsers didn't return anything for user '${userId}'`);\n}\n\nfunction missingRoomInfoError(roomId: string) {\n return new Error(\n `resolveRoomsInfo didn't return anything for room '${roomId}'`\n );\n}\n\nconst _extras = new WeakMap<\n OpaqueClient,\n ReturnType<typeof makeExtrasForClient>\n>();\nconst _bundles = new WeakMap<\n OpaqueClient,\n LiveblocksContextBundle<BaseUserMeta, BaseMetadata>\n>();\n\nexport const POLLING_INTERVAL = 60 * 1000; // 1 minute\nexport const INBOX_NOTIFICATIONS_QUERY = \"INBOX_NOTIFICATIONS\";\nexport const USER_THREADS_QUERY = \"USER_THREADS\";\n\nfunction selectorFor_useInboxNotifications(\n state: CacheState<BaseMetadata>\n): InboxNotificationsState {\n const query = state.queries[INBOX_NOTIFICATIONS_QUERY];\n\n if (query === undefined || query.isLoading) {\n return {\n isLoading: true,\n };\n }\n\n if (query.error !== undefined) {\n return {\n error: query.error,\n isLoading: false,\n };\n }\n\n return {\n inboxNotifications: selectedInboxNotifications(state),\n isLoading: false,\n };\n}\n\nfunction selectorFor_useUserThreads<M extends BaseMetadata>(\n state: CacheState<M>\n): ThreadsState<M> {\n const query = state.queries[USER_THREADS_QUERY];\n\n if (query === undefined || query.isLoading) {\n return {\n isLoading: true,\n };\n }\n\n if (query.error !== undefined) {\n return {\n threads: [],\n error: query.error,\n isLoading: false,\n };\n }\n\n return {\n threads: selectedUserThreads(state),\n isLoading: false,\n };\n}\n\nfunction selectUnreadInboxNotificationsCount(state: CacheState<BaseMetadata>) {\n let count = 0;\n\n for (const notification of selectedInboxNotifications(state)) {\n if (\n notification.readAt === null ||\n notification.readAt < notification.notifiedAt\n ) {\n count++;\n }\n }\n\n return count;\n}\n\nfunction selectorFor_useUnreadInboxNotificationsCount(\n state: CacheState<BaseMetadata>\n): UnreadInboxNotificationsCountState {\n const query = state.queries[INBOX_NOTIFICATIONS_QUERY];\n\n if (query === undefined || query.isLoading) {\n return {\n isLoading: true,\n };\n }\n\n if (query.error !== undefined) {\n return {\n error: query.error,\n isLoading: false,\n };\n }\n\n return {\n isLoading: false,\n count: selectUnreadInboxNotificationsCount(state),\n };\n}\n\nfunction selectorFor_useUser<U extends BaseUserMeta>(\n state: AsyncResult<U[\"info\"] | undefined> | undefined,\n userId: string\n): UserAsyncResult<U[\"info\"]> {\n if (state === undefined || state?.isLoading) {\n return state ?? { isLoading: true };\n }\n\n if (state.error) {\n return state;\n }\n\n // If this is a \"success\" state, but there still is no data, then it means\n // the \"resolving of this user\" returned undefined. In that case, still treat\n // this as an error state.\n if (!state.data) {\n return {\n isLoading: false,\n error: missingUserError(userId),\n };\n }\n\n return {\n isLoading: false,\n user: state.data,\n };\n}\n\nfunction selectorFor_useRoomInfo(\n state: AsyncResult<BaseRoomInfo | undefined> | undefined,\n roomId: string\n): RoomInfoAsyncResult {\n if (state === undefined || state?.isLoading) {\n return state ?? { isLoading: true };\n }\n\n if (state.error) {\n return state;\n }\n\n // If this is a \"success\" state, but there still is no data, then it means\n // the \"resolving of this user\" returned undefined. In that case, still treat\n // this as an error state.\n if (!state.data) {\n return {\n isLoading: false,\n error: missingRoomInfoError(roomId),\n };\n }\n\n return {\n isLoading: false,\n info: state.data,\n };\n}\n\nfunction getOrCreateContextBundle<\n U extends BaseUserMeta,\n M extends BaseMetadata,\n>(client: OpaqueClient): LiveblocksContextBundle<U, M> {\n let bundle = _bundles.get(client);\n if (!bundle) {\n bundle = makeLiveblocksContextBundle(client);\n _bundles.set(client, bundle);\n }\n return bundle as LiveblocksContextBundle<U, M>;\n}\n\n// TODO: Likely a better / more clear name for this helper will arise. I'll\n// rename this later. All of these are implementation details to support inbox\n// notifications on a per-client basis.\nfunction getExtrasForClient<M extends BaseMetadata>(client: OpaqueClient) {\n let extras = _extras.get(client);\n if (!extras) {\n extras = makeExtrasForClient(client);\n _extras.set(client, extras);\n }\n\n return extras as unknown as Omit<typeof extras, \"store\"> & {\n store: CacheStore<M>;\n };\n}\n\nfunction makeExtrasForClient<U extends BaseUserMeta, M extends BaseMetadata>(\n client: OpaqueClient\n) {\n const internals = client[kInternal] as PrivateClientApi<U, M>;\n const store = internals.cacheStore;\n\n let lastRequestedAt: Date | undefined;\n\n /**\n * Performs one network fetch, and updates the store and last requested at\n * date if successful. If unsuccessful, will throw.\n */\n async function fetchInboxNotifications() {\n // If inbox notifications have not been fetched yet, we get all of them\n // Else, we fetch only what changed since the last request\n if (lastRequestedAt === undefined) {\n const result = await client.getInboxNotifications();\n\n store.updateThreadsAndNotifications(\n result.threads,\n result.inboxNotifications,\n [],\n [],\n INBOX_NOTIFICATIONS_QUERY\n );\n\n lastRequestedAt = result.requestedAt;\n } else {\n const result = await client.getInboxNotificationsSince({\n since: lastRequestedAt,\n });\n\n store.updateThreadsAndNotifications(\n result.threads.updated,\n result.inboxNotifications.updated,\n result.threads.deleted,\n result.inboxNotifications.deleted,\n INBOX_NOTIFICATIONS_QUERY\n );\n\n if (lastRequestedAt < result.requestedAt) {\n lastRequestedAt = result.requestedAt;\n }\n }\n }\n\n let pollerSubscribers = 0;\n const poller = makePoller(async () => {\n try {\n await waitUntilInboxNotificationsLoaded();\n await fetchInboxNotifications();\n } catch (err) {\n // When polling, we don't want to throw errors, ever\n console.warn(`Polling new inbox notifications failed: ${String(err)}`);\n }\n });\n\n /**\n * Will trigger an initial fetch of inbox notifications if this hasn't\n * already happened. Will resolve once there is initial data. Will retry\n * a few times automatically in case fetching fails, with incremental backoff\n * delays. Will throw eventually only if all retries fail.\n */\n const waitUntilInboxNotificationsLoaded = memoizeOnSuccess(async () => {\n store.setQueryState(INBOX_NOTIFICATIONS_QUERY, {\n isLoading: true,\n });\n\n try {\n await autoRetry(\n () => fetchInboxNotifications(),\n 5,\n [5000, 5000, 10000, 15000]\n );\n } catch (err) {\n // Store the error in the cache as a side-effect, for non-Suspense\n store.setQueryState(INBOX_NOTIFICATIONS_QUERY, {\n isLoading: false,\n error: err as Error,\n });\n\n // Rethrow it for Suspense, where this promise must fail\n throw err;\n }\n });\n\n /**\n * Triggers an initial fetch of inbox notifications if this hasn't\n * already happened.\n */\n function loadInboxNotifications(): void {\n void waitUntilInboxNotificationsLoaded().catch(() => {\n // Deliberately catch and ignore any errors here\n });\n }\n\n /**\n * Enables polling for inbox notifications when the component mounts. Stops\n * polling on unmount.\n *\n * Safe to be called multiple times from different components. The first\n * component to mount starts the polling. The last component to unmount stops\n * the polling.\n */\n function useEnableInboxNotificationsPolling() {\n useEffect(() => {\n // Increment\n pollerSubscribers++;\n poller.start(POLLING_INTERVAL);\n\n return () => {\n // Decrement\n if (pollerSubscribers <= 0) {\n console.warn(\n `Internal unexpected behavior. Cannot decrease subscriber count for query \"${INBOX_NOTIFICATIONS_QUERY}\"`\n );\n return;\n }\n\n pollerSubscribers--;\n if (pollerSubscribers <= 0) {\n poller.stop();\n }\n };\n }, []);\n }\n\n /**\n * BEGIN USER THREADS CODE DUPLICATION\n *\n * This code is duplicated from the inbox notifications code above.\n * Code could be dried up, but we're not 100% we will support useUserThreads officially,\n * so until then, we keep it as is for easier removal.\n */\n\n let userThreadsPollerSubscribers = 0;\n const userThreadsPoller = makePoller(async () => {\n try {\n await waitUntilUserThreadsLoaded();\n await fetchUserThreads();\n } catch (err) {\n // When polling, we don't want to throw errors, ever\n console.warn(`Polling new user threads failed: ${String(err)}`);\n }\n });\n\n let userThreadslastRequestedAt: Date | undefined;\n\n /**\n * Triggers an initial fetch of user threads if this hasn't\n * already happened.\n */\n function loadUserThreads(): void {\n void waitUntilUserThreadsLoaded().catch(() => {\n // Deliberately catch and ignore any errors here\n });\n }\n\n /**\n * Will trigger an initial fetch of user threads if this hasn't\n * already happened. Will resolve once there is initial data. Will retry\n * a few times automatically in case fetching fails, with incremental backoff\n * delays. Will throw eventually only if all retries fail.\n */\n const waitUntilUserThreadsLoaded = memoizeOnSuccess(async () => {\n store.setQueryState(USER_THREADS_QUERY, {\n isLoading: true,\n });\n\n try {\n await autoRetry(() => fetchUserThreads(), 5, [5000, 5000, 10000, 15000]);\n } catch (err) {\n // Store the error in the cache as a side-effect, for non-Suspense\n store.setQueryState(USER_THREADS_QUERY, {\n isLoading: false,\n error: err as Error,\n });\n\n // Rethrow it for Suspense, where this promise must fail\n throw err;\n }\n });\n\n /**\n * Performs one network fetch, and updates the store and last requested at\n * date if successful. If unsuccessful, will throw.\n */\n async function fetchUserThreads() {\n // If inbox notifications have not been fetched yet, we get all of them\n // Else, we fetch only what changed since the last request\n if (userThreadslastRequestedAt === undefined) {\n const result = await client[kInternal].getThreads();\n\n store.updateThreadsAndNotifications(\n result.threads,\n result.inboxNotifications,\n [],\n [],\n USER_THREADS_QUERY\n );\n\n userThreadslastRequestedAt = result.requestedAt;\n } else {\n const result = await client[kInternal].getThreadsSince({\n since: userThreadslastRequestedAt,\n });\n\n store.updateThreadsAndNotifications(\n result.threads.updated,\n result.inboxNotifications.updated,\n result.threads.deleted,\n result.inboxNotifications.deleted,\n USER_THREADS_QUERY\n );\n\n if (userThreadslastRequestedAt < result.requestedAt) {\n userThreadslastRequestedAt = result.requestedAt;\n }\n }\n }\n\n /**\n * Enables polling for inbox notifications when the component mounts. Stops\n * polling on unmount.\n *\n * Safe to be called multiple times from different components. The first\n * component to mount starts the polling. The last component to unmount stops\n * the polling.\n */\n function useEnableUserThreadsPolling() {\n useEffect(() => {\n // Increment\n userThreadsPollerSubscribers++;\n userThreadsPoller.start(POLLING_INTERVAL);\n\n return () => {\n // Decrement\n if (userThreadsPollerSubscribers <= 0) {\n console.warn(\n `Internal unexpected behavior. Cannot decrease subscriber count for query \"${USER_THREADS_QUERY}\"`\n );\n return;\n }\n\n userThreadsPollerSubscribers--;\n if (userThreadsPollerSubscribers <= 0) {\n userThreadsPoller.stop();\n }\n };\n }, []);\n\n /**\n * END USER THREADS CODE DUPLICATION\n */\n }\n\n return {\n store,\n useEnableInboxNotificationsPolling,\n waitUntilInboxNotificationsLoaded,\n loadInboxNotifications,\n\n useEnableUserThreadsPolling,\n waitUntilUserThreadsLoaded,\n loadUserThreads,\n };\n}\n\nfunction makeLiveblocksContextBundle<\n U extends BaseUserMeta,\n M extends BaseMetadata,\n>(client: Client<U>): LiveblocksContextBundle<U, M> {\n // Bind all hooks to the current client instance\n const useInboxNotificationThread = (inboxNotificationId: string) =>\n useInboxNotificationThread_withClient<M>(client, inboxNotificationId);\n\n const useMarkInboxNotificationAsRead = () =>\n useMarkInboxNotificationAsRead_withClient(client);\n\n const useMarkAllInboxNotificationsAsRead = () =>\n useMarkAllInboxNotificationsAsRead_withClient(client);\n\n const useDeleteInboxNotification = () =>\n useDeleteInboxNotification_withClient(client);\n\n const useDeleteAllInboxNotifications = () =>\n useDeleteAllInboxNotifications_withClient(client);\n\n // NOTE: This version of the LiveblocksProvider does _not_ take any props.\n // This is because we already have a client bound to it.\n function LiveblocksProvider(props: PropsWithChildren) {\n useEnsureNoLiveblocksProvider();\n return (\n <ClientContext.Provider value={client}>\n {props.children}\n </ClientContext.Provider>\n );\n }\n\n const shared = createSharedContext<U>(client);\n\n const bundle: LiveblocksContextBundle<U, M> = {\n LiveblocksProvider,\n\n useInboxNotifications: () => useInboxNotifications_withClient(client),\n useUnreadInboxNotificationsCount: () =>\n useUnreadInboxNotificationsCount_withClient(client),\n\n useMarkInboxNotificationAsRead,\n useMarkAllInboxNotificationsAsRead,\n\n useDeleteInboxNotification,\n useDeleteAllInboxNotifications,\n\n useInboxNotificationThread,\n useUserThreads_experimental: () => useUserThreads_withClient<M>(client),\n\n ...shared.classic,\n\n suspense: {\n LiveblocksProvider,\n\n useInboxNotifications: () =>\n useInboxNotificationsSuspense_withClient(client),\n useUnreadInboxNotificationsCount: () =>\n useUnreadInboxNotificationsCountSuspense_withClient(client),\n\n useMarkInboxNotificationAsRead,\n useMarkAllInboxNotificationsAsRead,\n\n useDeleteInboxNotification,\n useDeleteAllInboxNotifications,\n\n useInboxNotificationThread,\n\n useUserThreads_experimental: () =>\n useUserThreadsSuspense_withClient(client),\n\n ...shared.suspense,\n },\n };\n return bundle;\n}\n\nfunction useUserThreads_withClient<M extends BaseMetadata>(\n client: OpaqueClient\n): ThreadsState<M> {\n const { loadUserThreads, store, useEnableUserThreadsPolling } =\n getExtrasForClient<M>(client);\n\n // Trigger initial loading of user threads if it hasn't started\n // already, but don't await its promise.\n useEffect(() => {\n loadUserThreads();\n }, [loadUserThreads]);\n\n useEnableUserThreadsPolling();\n return useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n selectorFor_useUserThreads,\n shallow\n );\n}\n\nfunction useUserThreadsSuspense_withClient<M extends BaseMetadata>(\n client: OpaqueClient\n): ThreadsStateSuccess<M> {\n const { waitUntilUserThreadsLoaded } = getExtrasForClient(client);\n\n // Suspend until there are at least some user threads\n use(waitUntilUserThreadsLoaded());\n\n // We're in a Suspense world here, and as such, the useUserThreads()\n // hook is expected to only return success results when we're here.\n const result = useUserThreads_withClient<M>(client);\n assert(!result.error, \"Did not expect error\");\n assert(!result.isLoading, \"Did not expect loading\");\n return result as ThreadsStateSuccess<M>; // TODO: Remove casting\n}\n\nfunction useInboxNotifications_withClient(client: OpaqueClient) {\n const { loadInboxNotifications, store, useEnableInboxNotificationsPolling } =\n getExtrasForClient(client);\n\n // Trigger initial loading of inbox notifications if it hasn't started\n // already, but don't await its promise.\n useEffect(() => {\n loadInboxNotifications();\n }, [loadInboxNotifications]);\n\n useEnableInboxNotificationsPolling();\n return useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n selectorFor_useInboxNotifications,\n shallow\n );\n}\n\nfunction useInboxNotificationsSuspense_withClient(client: OpaqueClient) {\n const { waitUntilInboxNotificationsLoaded } = getExtrasForClient(client);\n\n // Suspend until there are at least some inbox notifications\n use(waitUntilInboxNotificationsLoaded());\n\n // We're in a Suspense world here, and as such, the useInboxNotifications()\n // hook is expected to only return success results when we're here.\n const result = useInboxNotifications_withClient(client);\n assert(!result.error, \"Did not expect error\");\n assert(!result.isLoading, \"Did not expect loading\");\n return result;\n}\n\nfunction useUnreadInboxNotificationsCount_withClient(client: OpaqueClient) {\n const { store, loadInboxNotifications, useEnableInboxNotificationsPolling } =\n getExtrasForClient(client);\n\n // Trigger initial loading of inbox notifications if it hasn't started\n // already, but don't await its promise.\n useEffect(() => {\n loadInboxNotifications();\n }, [loadInboxNotifications]);\n\n useEnableInboxNotificationsPolling();\n return useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n selectorFor_useUnreadInboxNotificationsCount,\n shallow\n );\n}\n\nfunction useUnreadInboxNotificationsCountSuspense_withClient(\n client: OpaqueClient\n) {\n const { waitUntilInboxNotificationsLoaded } = getExtrasForClient(client);\n\n // Suspend until there are at least some inbox notifications\n use(waitUntilInboxNotificationsLoaded());\n\n const result = useUnreadInboxNotificationsCount_withClient(client);\n assert(!result.isLoading, \"Did not expect loading\");\n assert(!result.error, \"Did not expect error\");\n return result;\n}\n\nfunction useMarkInboxNotificationAsRead_withClient(client: OpaqueClient) {\n return useCallback(\n (inboxNotificationId: string) => {\n const { store } = getExtrasForClient(client);\n\n const optimisticUpdateId = nanoid();\n const readAt = new Date();\n store.pushOptimisticUpdate({\n type: \"mark-inbox-notification-as-read\",\n id: optimisticUpdateId,\n inboxNotificationId,\n readAt,\n });\n\n client.markInboxNotificationAsRead(inboxNotificationId).then(\n () => {\n store.set((state) => {\n const existingNotification =\n state.inboxNotifications[inboxNotificationId];\n\n // If existing notification has been deleted, we return the existing state\n if (existingNotification === undefined) {\n return {\n ...state,\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n };\n }\n\n return {\n ...state,\n inboxNotifications: {\n ...state.inboxNotifications,\n [inboxNotificationId]: {\n ...existingNotification,\n readAt,\n },\n },\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n };\n });\n },\n () => {\n // TODO: Broadcast errors to client\n store.set((state) => ({\n ...state,\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n }));\n }\n );\n },\n [client]\n );\n}\n\nfunction useMarkAllInboxNotificationsAsRead_withClient(client: OpaqueClient) {\n return useCallback(() => {\n const { store } = getExtrasForClient(client);\n const optimisticUpdateId = nanoid();\n const readAt = new Date();\n store.pushOptimisticUpdate({\n type: \"mark-all-inbox-notifications-as-read\",\n id: optimisticUpdateId,\n readAt,\n });\n\n client.markAllInboxNotificationsAsRead().then(\n () => {\n store.set((state) => ({\n ...state,\n inboxNotifications: Object.fromEntries(\n Array.from(Object.entries(state.inboxNotifications)).map(\n ([id, inboxNotification]) => [\n id,\n { ...inboxNotification, readAt },\n ]\n )\n ),\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n }));\n },\n () => {\n // TODO: Broadcast errors to client\n store.set((state) => ({\n ...state,\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n }));\n }\n );\n }, [client]);\n}\n\nfunction useDeleteInboxNotification_withClient(client: OpaqueClient) {\n return useCallback(\n (inboxNotificationId: string) => {\n const { store } = getExtrasForClient(client);\n\n const optimisticUpdateId = nanoid();\n const deletedAt = new Date();\n store.pushOptimisticUpdate({\n type: \"delete-inbox-notification\",\n id: optimisticUpdateId,\n inboxNotificationId,\n deletedAt,\n });\n\n client.deleteInboxNotification(inboxNotificationId).then(\n () => {\n store.set((state) => {\n const existingNotification =\n state.inboxNotifications[inboxNotificationId];\n\n // If existing notification has been deleted, we return the existing state\n if (existingNotification === undefined) {\n return {\n ...state,\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n };\n }\n\n const { [inboxNotificationId]: _, ...inboxNotifications } =\n state.inboxNotifications;\n\n return {\n ...state,\n inboxNotifications,\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n };\n });\n },\n () => {\n // TODO: Broadcast errors to client\n store.set((state) => ({\n ...state,\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n }));\n }\n );\n },\n [client]\n );\n}\n\nfunction useDeleteAllInboxNotifications_withClient(client: OpaqueClient) {\n return useCallback(() => {\n const { store } = getExtrasForClient(client);\n const optimisticUpdateId = nanoid();\n const deletedAt = new Date();\n store.pushOptimisticUpdate({\n type: \"delete-all-inbox-notifications\",\n id: optimisticUpdateId,\n deletedAt,\n });\n\n client.deleteAllInboxNotifications().then(\n () => {\n store.set((state) => ({\n ...state,\n inboxNotifications: {},\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n }));\n },\n () => {\n // TODO: Broadcast errors to client\n store.set((state) => ({\n ...state,\n optimisticUpdates: state.optimisticUpdates.filter(\n (update) => update.id !== optimisticUpdateId\n ),\n }));\n }\n );\n }, [client]);\n}\n\nfunction useInboxNotificationThread_withClient<M extends BaseMetadata>(\n client: OpaqueClient,\n inboxNotificationId: string\n): ThreadData<M> {\n const { store } = getExtrasForClient<M>(client);\n\n const selector = useCallback(\n (state: CacheState<M>) => {\n const inboxNotification =\n state.inboxNotifications[inboxNotificationId] ??\n raise(`Inbox notification with ID \"${inboxNotificationId}\" not found`);\n\n if (inboxNotification.kind !== \"thread\") {\n raise(\n `Inbox notification with ID \"${inboxNotificationId}\" is not of kind \"thread\"`\n );\n }\n\n const thread =\n state.threads[inboxNotification.threadId] ??\n raise(\n `Thread with ID \"${inboxNotification.threadId}\" not found, this inbox notification might not be of kind \"thread\"`\n );\n\n return thread;\n },\n [inboxNotificationId]\n );\n\n return useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n selector\n );\n}\n\nfunction useUser_withClient<U extends BaseUserMeta>(\n client: Client<U>,\n userId: string\n): UserAsyncResult<U[\"info\"]> {\n const usersStore = client[kInternal].usersStore;\n\n const getUserState = useCallback(\n () => usersStore.getState(userId),\n [usersStore, userId]\n );\n\n useEffect(() => {\n // NOTE: .get() will trigger any actual fetches, whereas .getState() will not\n void usersStore.get(userId);\n }, [usersStore, userId]);\n\n const selector = useCallback(\n (state: ReturnType<typeof getUserState>) =>\n selectorFor_useUser(state, userId),\n [userId]\n );\n\n return useSyncExternalStoreWithSelector(\n usersStore.subscribe,\n getUserState,\n getUserState,\n selector,\n shallow\n );\n}\n\nfunction useUserSuspense_withClient<U extends BaseUserMeta>(\n client: Client<U>,\n userId: string\n) {\n const usersStore = client[kInternal].usersStore;\n\n const getUserState = useCallback(\n () => usersStore.getState(userId),\n [usersStore, userId]\n );\n const userState = getUserState();\n\n if (!userState || userState.isLoading) {\n throw usersStore.get(userId);\n }\n\n if (userState.error) {\n throw userState.error;\n }\n\n // Throw an error if `undefined` was returned by `resolveUsers` for this user ID\n if (!userState.data) {\n throw missingUserError(userId);\n }\n\n const state = useSyncExternalStore(\n usersStore.subscribe,\n getUserState,\n getUserState\n );\n assert(state !== undefined, \"Unexpected missing state\");\n assert(!state.isLoading, \"Unexpected loading state\");\n assert(!state.error, \"Unexpected error state\");\n return {\n isLoading: false,\n user: state.data,\n error: undefined,\n } as const;\n}\n\nfunction useRoomInfo_withClient(\n client: OpaqueClient,\n roomId: string\n): RoomInfoAsyncResult {\n const roomsInfoStore = client[kInternal].roomsInfoStore;\n\n const getRoomInfoState = useCallback(\n () => roomsInfoStore.getState(roomId),\n [roomsInfoStore, roomId]\n );\n\n const selector = useCallback(\n (state: ReturnType<typeof getRoomInfoState>) =>\n selectorFor_useRoomInfo(state, roomId),\n [roomId]\n );\n\n useEffect(() => {\n void roomsInfoStore.get(roomId);\n }, [roomsInfoStore, roomId]);\n\n return useSyncExternalStoreWithSelector(\n roomsInfoStore.subscribe,\n getRoomInfoState,\n getRoomInfoState,\n selector,\n shallow\n );\n}\n\nfunction useRoomInfoSuspense_withClient(client: OpaqueClient, roomId: string) {\n const roomsInfoStore = client[kInternal].roomsInfoStore;\n\n const getRoomInfoState = useCallback(\n () => roomsInfoStore.getState(roomId),\n [roomsInfoStore, roomId]\n );\n const roomInfoState = getRoomInfoState();\n\n if (!roomInfoState || roomInfoState.isLoading) {\n throw roomsInfoStore.get(roomId);\n }\n\n if (roomInfoState.error) {\n throw roomInfoState.error;\n }\n\n // Throw an error if `undefined` was returned by `resolveRoomsInfo` for this room ID\n if (!roomInfoState.data) {\n throw missingRoomInfoError(roomId);\n }\n\n const state = useSyncExternalStore(\n roomsInfoStore.subscribe,\n getRoomInfoState,\n getRoomInfoState\n );\n assert(state !== undefined, \"Unexpected missing state\");\n assert(!state.isLoading, \"Unexpected loading state\");\n assert(!state.error, \"Unexpected error state\");\n assert(state.data !== undefined, \"Unexpected missing room info data\");\n return {\n isLoading: false,\n info: state.data,\n error: undefined,\n } as const;\n}\n\n/** @internal */\nexport function createSharedContext<U extends BaseUserMeta>(\n client: Client<U>\n): SharedContextBundle<U> {\n const useClient = () => client;\n return {\n classic: {\n useClient,\n useUser: (userId: string) => useUser_withClient(client, userId),\n useRoomInfo: (roomId: string) => useRoomInfo_withClient(client, roomId),\n useIsInsideRoom,\n },\n suspense: {\n useClient,\n useUser: (userId: string) => useUserSuspense_withClient(client, userId),\n useRoomInfo: (roomId: string) =>\n useRoomInfoSuspense_withClient(client, roomId),\n useIsInsideRoom,\n },\n };\n}\n\n/**\n * @private This is an internal API.\n */\nfunction useEnsureNoLiveblocksProvider(options?: { allowNesting?: boolean }) {\n const existing = useClientOrNull();\n if (!options?.allowNesting && existing !== null) {\n throw new Error(\n \"You cannot nest multiple LiveblocksProvider instances in the same React tree.\"\n );\n }\n}\n\n/**\n * @private This is an internal API.\n */\nexport function useClientOrNull<U extends BaseUserMeta>() {\n return useContext(ClientContext) as Client<U> | null;\n}\n\n/**\n * Obtains a reference to the current Liveblocks client.\n */\nexport function useClient<U extends BaseUserMeta>() {\n return (\n useClientOrNull<U>() ??\n raise(\"LiveblocksProvider is missing from the React tree.\")\n );\n}\n\n/**\n * @private This is a private API.\n */\nexport function LiveblocksProviderWithClient(\n props: PropsWithChildren<{\n client: OpaqueClient;\n\n // Private flag, used only to skip the nesting check if this is\n // a LiveblocksProvider created implicitly by a factory-bound RoomProvider.\n allowNesting?: boolean;\n }>\n) {\n useEnsureNoLiveblocksProvider(props);\n return (\n <ClientContext.Provider value={props.client}>\n {props.children}\n </ClientContext.Provider>\n );\n}\n\n/**\n * Sets up a client for connecting to Liveblocks, and is the recommended way to do\n * this for React apps. You must define either `authEndpoint` or `publicApiKey`.\n * Resolver functions should be placed inside here, and a number of other options\n * are available, which correspond with those passed to `createClient`.\n * Unlike `RoomProvider`, `LiveblocksProvider` doesn’t call Liveblocks servers when mounted,\n * and it should be placed higher in your app’s component tree.\n */\nexport function LiveblocksProvider<U extends BaseUserMeta = DU>(\n props: PropsWithChildren<ClientOptions<U>>\n) {\n const { children, ...o } = props;\n\n // It's important that the static options remain stable, otherwise we'd be\n // creating new client instances on every render.\n const options = {\n publicApiKey: useInitial(o.publicApiKey),\n throttle: useInitial(o.throttle),\n lostConnectionTimeout: useInitial(o.lostConnectionTimeout),\n backgroundKeepAliveTimeout: useInitial(o.backgroundKeepAliveTimeout),\n polyfills: useInitial(o.polyfills),\n unstable_fallbackToHTTP: useInitial(o.unstable_fallbackToHTTP),\n unstable_streamData: useInitial(o.unstable_streamData),\n\n authEndpoint: useInitialUnlessFunction(o.authEndpoint),\n resolveMentionSuggestions: useInitialUnlessFunction(\n o.resolveMentionSuggestions\n ),\n resolveUsers: useInitialUnlessFunction(o.resolveUsers),\n resolveRoomsInfo: useInitialUnlessFunction(o.resolveRoomsInfo),\n\n baseUrl: useInitial(\n // @ts-expect-error - Hidden config options\n o.baseUrl as string | undefined\n ),\n enableDebugLogging: useInitial(\n // @ts-expect-error - Hidden config options\n o.enableDebugLogging as boolean | undefined\n ),\n } as ClientOptions<U>;\n\n // NOTE: Deliberately not passing any deps here, because we'll _never_ want\n // to recreate a client instance after the first render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const client = useMemo(() => createClient<U>(options), []);\n return (\n <LiveblocksProviderWithClient client={client}>\n {children}\n </LiveblocksProviderWithClient>\n );\n}\n\n/**\n * Creates a LiveblocksProvider and a set of typed hooks. Note that any\n * LiveblocksProvider created in this way takes no props, because it uses\n * settings from the given client instead.\n */\nexport function createLiveblocksContext<\n U extends BaseUserMeta = DU,\n M extends BaseMetadata = DM,\n>(client: OpaqueClient): LiveblocksContextBundle<U, M> {\n return getOrCreateContextBundle<U, M>(client);\n}\n\n/**\n * @experimental\n *\n * This hook is experimental and could be removed or changed at any time!\n * Do not use unless explicitely recommended by the Liveblocks team.\n */\nfunction useUserThreads_experimental() {\n return useUserThreads_withClient(useClient());\n}\n\n/**\n * @experimental\n *\n * This hook is experimental and could be removed or changed at any time!\n * Do not use unless explicitely recommended by the Liveblocks team.\n */\nfunction useUserThreadsSuspense_experimental<\n M extends BaseMetadata,\n>(): ThreadsStateSuccess<M> {\n return useUserThreadsSuspense_withClient<M>(useClient());\n}\n\n/**\n * Returns the inbox notifications for the current user.\n *\n * @example\n * const { inboxNotifications, error, isLoading } = useInboxNotifications();\n */\nfunction useInboxNotifications() {\n return useInboxNotifications_withClient(useClient());\n}\n\n/**\n * Returns the inbox notifications for the current user.\n *\n * @example\n * const { inboxNotifications } = useInboxNotifications();\n */\nfunction useInboxNotificationsSuspense() {\n return useInboxNotificationsSuspense_withClient(useClient());\n}\n\nfunction useInboxNotificationThread<M extends BaseMetadata>(\n inboxNotificationId: string\n) {\n return useInboxNotificationThread_withClient<M>(\n useClient(),\n inboxNotificationId\n );\n}\n\n/**\n * Returns a function that marks all of the current user's inbox notifications as read.\n *\n * @example\n * const markAllInboxNotificationsAsRead = useMarkAllInboxNotificationsAsRead();\n * markAllInboxNotificationsAsRead();\n */\nfunction useMarkAllInboxNotificationsAsRead() {\n return useMarkAllInboxNotificationsAsRead_withClient(useClient());\n}\n\n/**\n * Returns a function that marks an inbox notification as read for the current user.\n *\n * @example\n * const markInboxNotificationAsRead = useMarkInboxNotificationAsRead();\n * markInboxNotificationAsRead(\"in_xxx\");\n */\nfunction useMarkInboxNotificationAsRead() {\n return useMarkInboxNotificationAsRead_withClient(useClient());\n}\n\n/**\n * Returns a function that deletes all of the current user's inbox notifications.\n *\n * @example\n * const deleteAllInboxNotifications = useDeleteAllInboxNotifications();\n * deleteAllInboxNotifications();\n */\nfunction useDeleteAllInboxNotifications() {\n return useDeleteAllInboxNotifications_withClient(useClient());\n}\n\n/**\n * Returns a function that deletes an inbox notification for the current user.\n *\n * @example\n * const deleteInboxNotification = useDeleteInboxNotification();\n * deleteInboxNotification(\"in_xxx\");\n */\nfunction useDeleteInboxNotification() {\n return useDeleteInboxNotification_withClient(useClient());\n}\n\n/**\n * Returns the number of unread inbox notifications for the current user.\n *\n * @example\n * const { count, error, isLoading } = useUnreadInboxNotificationsCount();\n */\nfunction useUnreadInboxNotificationsCount() {\n return useUnreadInboxNotificationsCount_withClient(useClient());\n}\n\n/**\n * Returns the number of unread inbox notifications for the current user.\n *\n * @example\n * const { count } = useUnreadInboxNotificationsCount();\n */\nfunction useUnreadInboxNotificationsCountSuspense() {\n return useUnreadInboxNotificationsCountSuspense_withClient(useClient());\n}\n\nfunction useUser<U extends BaseUserMeta>(userId: string) {\n const client = useClient<U>();\n return useUser_withClient(client, userId);\n}\n\nfunction useUserSuspense<U extends BaseUserMeta>(\n userId: string\n): UserAsyncSuccess<U[\"info\"]> {\n const client = useClient<U>();\n return useUserSuspense_withClient(client, userId);\n}\n\n/**\n * Returns room info from a given room ID.\n *\n * @example\n * const { info, error, isLoading } = useRoomInfo(\"room-id\");\n */\nfunction useRoomInfo(roomId: string): RoomInfoAsyncResult {\n return useRoomInfo_withClient(useClient(), roomId);\n}\n\n/**\n * Returns room info from a given room ID.\n *\n * @example\n * const { info } = useRoomInfo(\"room-id\");\n */\nfunction useRoomInfoSuspense(roomId: string): RoomInfoAsyncSuccess {\n return useRoomInfoSuspense_withClient(useClient(), roomId);\n}\n\ntype TypedBundle = LiveblocksContextBundle<DU, DM>;\n\n/**\n * Returns the thread associated with a `\"thread\"` inbox notification.\n *\n * It can **only** be called with IDs of `\"thread\"` inbox notifications,\n * so we recommend only using it when customizing the rendering or in other\n * situations where you can guarantee the kind of the notification.\n *\n * When `useInboxNotifications` returns `\"thread\"` inbox notifications,\n * it also receives the associated threads and caches them behind the scenes.\n * When you call `useInboxNotificationThread`, it simply returns the cached thread\n * for the inbox notification ID you passed to it, without any fetching or waterfalls.\n *\n * @example\n * const thread = useInboxNotificationThread(\"in_xxx\");\n */\nconst _useInboxNotificationThread: TypedBundle[\"useInboxNotificationThread\"] =\n useInboxNotificationThread;\n\n/**\n * Returns user info from a given user ID.\n *\n * @example\n * const { user, error, isLoading } = useUser(\"user-id\");\n */\nconst _useUser: TypedBundle[\"useUser\"] = useUser;\n\n/**\n * Returns user info from a given user ID.\n *\n * @example\n * const { user } = useUser(\"user-id\");\n */\nconst _useUserSuspense: TypedBundle[\"suspense\"][\"useUser\"] = useUserSuspense;\n\n/**\n * @experimental\n *\n * This hook is experimental and could be removed or changed at any time!\n * Do not use unless explicitely recommended by the Liveblocks team.\n */\nconst _useUserThreads_experimental: TypedBundle[\"useUserThreads_experimental\"] =\n useUserThreads_experimental;\n\n/**\n * @experimental\n *\n * This hook is experimental and could be removed or changed at any time!\n * Do not use unless explicitely recommended by the Liveblocks team.\n */\nconst _useUserThreadsSuspense_experimental: TypedBundle[\"suspense\"][\"useUserThreads_experimental\"] =\n useUserThreadsSuspense_experimental;\n\n// eslint-disable-next-line simple-import-sort/exports\nexport {\n _useInboxNotificationThread as useInboxNotificationThread,\n _useUser as useUser,\n _useUserSuspense as useUserSuspense,\n useInboxNotifications,\n useInboxNotificationsSuspense,\n useMarkAllInboxNotificationsAsRead,\n useMarkInboxNotificationAsRead,\n useDeleteAllInboxNotifications,\n useDeleteInboxNotification,\n useRoomInfo,\n useRoomInfoSuspense,\n useUnreadInboxNotificationsCount,\n useUnreadInboxNotificationsCountSuspense,\n _useUserThreads_experimental as useUserThreads_experimental,\n _useUserThreadsSuspense_experimental as useUserThreadsSuspense_experimental,\n};\n","import type { BaseMetadata } from \"@liveblocks/client\";\nimport * as React from \"react\";\n\nimport type { ThreadsState } from \"./types\";\n\nfunction handleScrollToCommentOnLoad(\n shouldScrollOnLoad: boolean,\n state: ThreadsState<BaseMetadata>\n) {\n if (shouldScrollOnLoad === false) return;\n\n if (state.isLoading) return;\n\n const isWindowDefined = typeof window !== \"undefined\";\n if (!isWindowDefined) return;\n\n const hash = window.location.hash;\n const commentId = hash.slice(1);\n\n // If the hash is not a comment ID, we do not scroll to it\n if (!commentId.startsWith(\"cm_\")) return;\n\n // If a comment with the ID does not exist in the DOM, we do not scroll to it\n const comment = document.getElementById(commentId);\n if (comment === null) return;\n\n const comments = state.threads.flatMap((thread) => thread.comments);\n const isCommentInThreads = comments.some(\n (comment) => comment.id === commentId\n );\n\n // If the comment is not in the threads for this hook, we do not scroll to it\n if (!isCommentInThreads) return;\n\n comment.scrollIntoView();\n}\n\n/**\n * Scroll to the comment with the ID in the hash of the URL based on whether\n * the query is loading and whether the hook should scroll to the comment on load.\n */\nexport function useScrollToCommentOnLoadEffect(\n shouldScrollOnLoad: boolean,\n state: ThreadsState<BaseMetadata>\n) {\n React.useEffect(\n () => {\n handleScrollToCommentOnLoad(shouldScrollOnLoad, state);\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps -- We only want to run this effect once\n [state.isLoading]\n );\n}\n"]}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { U as UseThreadsOptions } from './suspense-JsIIJujn.mjs';
2
- export { b as ClientContext, C as ClientSideSuspense, W as CreateThreadError, L as LiveblocksProvider, M as MutationContext, R as RoomContext, i as RoomProvider, a as UseStorageStatusOptions, c as createLiveblocksContext, h as createRoomContext, j as useAddReaction, a4 as useAttachmentUrl, k as useBatch, l as useBroadcastEvent, m as useCanRedo, n as useCanUndo, u as useClient, V as useCommentsErrorListener, o as useCreateComment, p as useCreateThread, f as useDeleteAllInboxNotifications, q as useDeleteComment, g as useDeleteInboxNotification, r as useDeleteThread, s as useEditComment, t as useEditThreadMetadata, x as useErrorListener, y as useEventListener, z as useHistory, _ as useInboxNotificationThread, a5 as useInboxNotifications, A as useIsInsideRoom, B as useLostConnectionListener, d as useMarkAllInboxNotificationsAsRead, e as useMarkInboxNotificationAsRead, D as useMarkThreadAsRead, v as useMarkThreadAsResolved, w as useMarkThreadAsUnresolved, E as useMutation, F as useMyPresence, X as useOther, Y as useOthers, Z as useOthersConnectionIds, G as useOthersListener, $ as useOthersMapped, H as useRedo, I as useRemoveReaction, J as useRoom, a7 as useRoomInfo, K as useRoomNotificationSettings, a0 as useSelf, N as useStatus, a1 as useStorage, O as useStorageRoot, a2 as useStorageStatus, P as useThreadSubscription, a3 as useThreads, Q as useUndo, a8 as useUnreadInboxNotificationsCount, S as useUpdateMyPresence, T as useUpdateRoomNotificationSettings, a9 as useUser, a6 as useUserThreads_experimental } from './suspense-JsIIJujn.mjs';
1
+ import { U as UseThreadsOptions } from './suspense-2UL0jBvg.mjs';
2
+ export { b as ClientContext, C as ClientSideSuspense, X as CreateThreadError, L as LiveblocksProvider, M as MutationContext, R as RoomContext, i as RoomProvider, a as UseStorageStatusOptions, c as createLiveblocksContext, h as createRoomContext, j as useAddReaction, k as useBatch, l as useBroadcastEvent, m as useCanRedo, n as useCanUndo, u as useClient, W as useCommentsErrorListener, o as useCreateComment, p as useCreateThread, f as useDeleteAllInboxNotifications, q as useDeleteComment, g as useDeleteInboxNotification, r as useDeleteThread, s as useEditComment, t as useEditThreadMetadata, x as useErrorListener, y as useEventListener, z as useHistory, V as useHistoryVersionData, a5 as useHistoryVersions, _ as useInboxNotificationThread, a6 as useInboxNotifications, A as useIsInsideRoom, B as useLostConnectionListener, d as useMarkAllInboxNotificationsAsRead, e as useMarkInboxNotificationAsRead, D as useMarkThreadAsRead, v as useMarkThreadAsResolved, w as useMarkThreadAsUnresolved, E as useMutation, F as useMyPresence, Y as useOther, Z as useOthers, $ as useOthersConnectionIds, G as useOthersListener, a0 as useOthersMapped, H as useRedo, I as useRemoveReaction, J as useRoom, a8 as useRoomInfo, K as useRoomNotificationSettings, a1 as useSelf, N as useStatus, a2 as useStorage, O as useStorageRoot, a3 as useStorageStatus, P as useThreadSubscription, a4 as useThreads, Q as useUndo, a9 as useUnreadInboxNotificationsCount, S as useUpdateMyPresence, T as useUpdateRoomNotificationSettings, aa as useUser, a7 as useUserThreads_experimental } from './suspense-2UL0jBvg.mjs';
3
3
  export { Json, JsonObject, shallow } from '@liveblocks/client';
4
4
  import { BaseMetadata, CacheState, ThreadData } from '@liveblocks/core';
5
5
  import 'react';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { U as UseThreadsOptions } from './suspense-JsIIJujn.js';
2
- export { b as ClientContext, C as ClientSideSuspense, W as CreateThreadError, L as LiveblocksProvider, M as MutationContext, R as RoomContext, i as RoomProvider, a as UseStorageStatusOptions, c as createLiveblocksContext, h as createRoomContext, j as useAddReaction, a4 as useAttachmentUrl, k as useBatch, l as useBroadcastEvent, m as useCanRedo, n as useCanUndo, u as useClient, V as useCommentsErrorListener, o as useCreateComment, p as useCreateThread, f as useDeleteAllInboxNotifications, q as useDeleteComment, g as useDeleteInboxNotification, r as useDeleteThread, s as useEditComment, t as useEditThreadMetadata, x as useErrorListener, y as useEventListener, z as useHistory, _ as useInboxNotificationThread, a5 as useInboxNotifications, A as useIsInsideRoom, B as useLostConnectionListener, d as useMarkAllInboxNotificationsAsRead, e as useMarkInboxNotificationAsRead, D as useMarkThreadAsRead, v as useMarkThreadAsResolved, w as useMarkThreadAsUnresolved, E as useMutation, F as useMyPresence, X as useOther, Y as useOthers, Z as useOthersConnectionIds, G as useOthersListener, $ as useOthersMapped, H as useRedo, I as useRemoveReaction, J as useRoom, a7 as useRoomInfo, K as useRoomNotificationSettings, a0 as useSelf, N as useStatus, a1 as useStorage, O as useStorageRoot, a2 as useStorageStatus, P as useThreadSubscription, a3 as useThreads, Q as useUndo, a8 as useUnreadInboxNotificationsCount, S as useUpdateMyPresence, T as useUpdateRoomNotificationSettings, a9 as useUser, a6 as useUserThreads_experimental } from './suspense-JsIIJujn.js';
1
+ import { U as UseThreadsOptions } from './suspense-2UL0jBvg.js';
2
+ export { b as ClientContext, C as ClientSideSuspense, X as CreateThreadError, L as LiveblocksProvider, M as MutationContext, R as RoomContext, i as RoomProvider, a as UseStorageStatusOptions, c as createLiveblocksContext, h as createRoomContext, j as useAddReaction, k as useBatch, l as useBroadcastEvent, m as useCanRedo, n as useCanUndo, u as useClient, W as useCommentsErrorListener, o as useCreateComment, p as useCreateThread, f as useDeleteAllInboxNotifications, q as useDeleteComment, g as useDeleteInboxNotification, r as useDeleteThread, s as useEditComment, t as useEditThreadMetadata, x as useErrorListener, y as useEventListener, z as useHistory, V as useHistoryVersionData, a5 as useHistoryVersions, _ as useInboxNotificationThread, a6 as useInboxNotifications, A as useIsInsideRoom, B as useLostConnectionListener, d as useMarkAllInboxNotificationsAsRead, e as useMarkInboxNotificationAsRead, D as useMarkThreadAsRead, v as useMarkThreadAsResolved, w as useMarkThreadAsUnresolved, E as useMutation, F as useMyPresence, Y as useOther, Z as useOthers, $ as useOthersConnectionIds, G as useOthersListener, a0 as useOthersMapped, H as useRedo, I as useRemoveReaction, J as useRoom, a8 as useRoomInfo, K as useRoomNotificationSettings, a1 as useSelf, N as useStatus, a2 as useStorage, O as useStorageRoot, a3 as useStorageStatus, P as useThreadSubscription, a4 as useThreads, Q as useUndo, a9 as useUnreadInboxNotificationsCount, S as useUpdateMyPresence, T as useUpdateRoomNotificationSettings, aa as useUser, a7 as useUserThreads_experimental } from './suspense-2UL0jBvg.js';
3
3
  export { Json, JsonObject, shallow } from '@liveblocks/client';
4
4
  import { BaseMetadata, CacheState, ThreadData } from '@liveblocks/core';
5
5
  import 'react';