@liveblocks/react 1.2.2-comments5 → 1.2.2-comments6
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.
- package/dist/index.d.mts +7 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +72 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +76 -35
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/version.ts","../src/ClientSideSuspense.tsx","../src/factory.tsx","../src/comments/CommentsRoom.ts","../src/comments/errors.ts","../src/comments/lib/store.ts","../src/comments/lib/use-async-cache.ts","../src/comments/lib/use-initial.ts","../src/comments/lib/use-debounce.ts","../src/hooks.ts"],"names":["makeEventSource","React","useEffect","useRef","useSyncExternalStore","cacheItem","useState","useInitial","noop","room","other","options","rootOrNull","shallow"],"mappings":"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","sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport { ClientSideSuspense } from \"./ClientSideSuspense\";\nexport { createRoomContext, useRoomContextBundle } from \"./factory\";\nexport type {\n MutationContext,\n ResolveMentionSuggestionsOptions,\n ResolveUserOptions,\n} from \"./types\";\n\n// Re-exports from @liveblocks/client, for convenience\nexport type { Json, JsonObject } from \"@liveblocks/client\";\nexport { shallow } from \"@liveblocks/client\";\n","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 { ReactElement, ReactNode } from \"react\";\nimport * as React from \"react\";\n\ntype Props = {\n fallback: NonNullable<ReactNode> | null;\n children: () => 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): ReactElement {\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 ? props.children() : props.fallback}\n </React.Suspense>\n );\n}\n","import type {\n BaseUserMeta,\n BroadcastOptions,\n Client,\n History,\n Json,\n JsonObject,\n LiveObject,\n LostConnectionEvent,\n LsonObject,\n Others,\n Room,\n Status,\n User,\n} from \"@liveblocks/client\";\nimport { shallow } from \"@liveblocks/client\";\nimport type {\n AsyncCache,\n BaseMetadata,\n CommentData,\n ToImmutable,\n} from \"@liveblocks/core\";\nimport {\n asArrayWithLegacyMethods,\n createAsyncCache,\n deprecateIf,\n errorIf,\n makeEventSource,\n} from \"@liveblocks/core\";\nimport * as React from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport type {\n CommentsRoom,\n CreateCommentOptions,\n CreateThreadOptions,\n DeleteCommentOptions,\n EditCommentOptions,\n EditThreadMetadataOptions,\n RoomThreads,\n} from \"./comments/CommentsRoom\";\nimport { createCommentsRoom } from \"./comments/CommentsRoom\";\nimport type { CommentsApiError } from \"./comments/errors\";\nimport { useAsyncCache } from \"./comments/lib/use-async-cache\";\nimport { useDebounce } from \"./comments/lib/use-debounce\";\nimport { useInitial, useRerender } from \"./hooks\";\nimport type {\n MutationContext,\n OmitFirstArg,\n ResolveMentionSuggestionsOptions,\n ResolveUserOptions,\n RoomContextBundle,\n RoomProviderProps,\n UserState,\n UserStateSuspense,\n} from \"./types\";\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/guides/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 EMPTY_OTHERS =\n // NOTE: asArrayWithLegacyMethods() wrapping should no longer be necessary in 0.19\n asArrayWithLegacyMethods([]);\n\nfunction getEmptyOthers() {\n return EMPTY_OTHERS;\n}\n\nfunction makeMutationContext<\n TPresence extends JsonObject,\n TStorage extends LsonObject,\n TUserMeta extends BaseUserMeta,\n TRoomEvent extends Json,\n>(\n room: Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n): MutationContext<TPresence, TStorage, TUserMeta> {\n const errmsg =\n \"This mutation cannot be used until connected to the Liveblocks room\";\n\n return {\n get storage() {\n const mutableRoot = room.getStorageSnapshot();\n if (mutableRoot === null) {\n throw new Error(errmsg);\n }\n return mutableRoot;\n },\n\n get self() {\n const self = room.getSelf();\n if (self === null) {\n throw new Error(errmsg);\n }\n return self;\n },\n\n get others() {\n const others = room.getOthers();\n if (room.getSelf() === null) {\n throw new Error(errmsg);\n }\n return others;\n },\n\n setMyPresence: room.updatePresence,\n };\n}\n\ntype Options<TUserMeta extends BaseUserMeta> = {\n /**\n * An asynchronous function that returns user info from a user ID.\n */\n resolveUser?: (\n options: ResolveUserOptions\n ) => Promise<TUserMeta[\"info\"] | undefined>;\n\n /**\n * An asynchronous function that returns a list of user IDs matching a string.\n */\n resolveMentionSuggestions?: (\n options: ResolveMentionSuggestionsOptions\n ) => Promise<string[]>;\n\n /**\n * @internal Internal endpoint\n */\n serverEndpoint?: string;\n};\n\nlet hasWarnedIfNoResolveUser = false;\n\nfunction warnIfNoResolveUser(usersCache?: AsyncCache<unknown, unknown>) {\n if (\n !hasWarnedIfNoResolveUser &&\n !usersCache &&\n process.env.NODE_ENV !== \"production\"\n ) {\n console.warn(\n \"Set the resolveUser option in createRoomContext to specify user info.\"\n );\n hasWarnedIfNoResolveUser = true;\n }\n}\n\nconst ContextBundle = React.createContext<RoomContextBundle<\n JsonObject,\n LsonObject,\n BaseUserMeta,\n never,\n BaseMetadata\n> | null>(null);\n\n// TODO: Internal?\nexport function useRoomContextBundle() {\n return React.useContext(ContextBundle)!;\n}\n\nexport function createRoomContext<\n TPresence extends JsonObject,\n TStorage extends LsonObject = LsonObject,\n TUserMeta extends BaseUserMeta = BaseUserMeta,\n TRoomEvent extends Json = never,\n TThreadMetadata extends BaseMetadata = never,\n>(\n client: Client,\n options?: Options<TUserMeta>\n): RoomContextBundle<\n TPresence,\n TStorage,\n TUserMeta,\n TRoomEvent,\n TThreadMetadata\n> {\n const RoomContext = React.createContext<Room<\n TPresence,\n TStorage,\n TUserMeta,\n TRoomEvent\n > | null>(null);\n\n function RoomProvider(props: RoomProviderProps<TPresence, TStorage>) {\n const {\n id: roomId,\n initialPresence,\n initialStorage,\n unstable_batchedUpdates,\n shouldInitiallyConnect,\n } = 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 frozen = useInitial({\n initialPresence,\n initialStorage,\n unstable_batchedUpdates,\n shouldInitiallyConnect:\n shouldInitiallyConnect === undefined\n ? typeof window !== \"undefined\"\n : shouldInitiallyConnect,\n });\n\n const [room, setRoom] = React.useState<\n Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n >(() =>\n client.enter(roomId, {\n initialPresence: frozen.initialPresence,\n initialStorage: frozen.initialStorage,\n shouldInitiallyConnect: frozen.shouldInitiallyConnect,\n unstable_batchedUpdates: frozen.unstable_batchedUpdates,\n })\n );\n\n React.useEffect(() => {\n const room = client.enter<TPresence, TStorage, TUserMeta, TRoomEvent>(\n roomId,\n {\n initialPresence: frozen.initialPresence,\n initialStorage: frozen.initialStorage,\n shouldInitiallyConnect: frozen.shouldInitiallyConnect,\n unstable_batchedUpdates: frozen.unstable_batchedUpdates,\n }\n );\n\n setRoom(room);\n\n const unsubscribe = getCommentsRoom(room).subscribe();\n\n return () => {\n unsubscribe();\n commentsRooms.delete(room.id);\n client.leave(roomId);\n };\n }, [roomId, frozen]);\n\n return (\n <RoomContext.Provider value={room}>\n <ContextBundle.Provider value={bundle as any}>\n {props.children}\n </ContextBundle.Provider>\n </RoomContext.Provider>\n );\n }\n\n function connectionIdSelector(\n others: Others<TPresence, TUserMeta>\n ): number[] {\n return others.map((user) => user.connectionId);\n }\n\n function useRoom(): Room<TPresence, TStorage, TUserMeta, TRoomEvent> {\n const room = React.useContext(RoomContext);\n if (room === null) {\n throw new Error(\"RoomProvider is missing from the React tree.\");\n }\n return room;\n }\n\n function useStatus(): Status {\n const room = useRoom();\n const subscribe = room.events.status.subscribe;\n const getSnapshot = room.getStatus;\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n }\n\n function useMyPresence(): [\n TPresence,\n (patch: Partial<TPresence>, options?: { addToHistory: boolean }) => void,\n ] {\n const room = useRoom();\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\n function useUpdateMyPresence(): (\n patch: Partial<TPresence>,\n options?: { addToHistory: boolean }\n ) => void {\n return useRoom().updatePresence;\n }\n\n function useOthers(): Others<TPresence, TUserMeta>;\n function useOthers<T>(\n selector: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T;\n function useOthers<T>(\n selector?: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | Others<TPresence, TUserMeta> {\n const room = useRoom();\n const subscribe = room.events.others.subscribe;\n const getSnapshot = room.getOthers;\n const getServerSnapshot = getEmptyOthers;\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n selector ?? (identity as (others: Others<TPresence, TUserMeta>) => T),\n isEqual\n );\n }\n\n function useOthersConnectionIds(): readonly number[] {\n return useOthers(connectionIdSelector, shallow);\n }\n\n function useOthersMapped<T>(\n itemSelector: (other: User<TPresence, TUserMeta>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n ): ReadonlyArray<readonly [connectionId: number, data: T]> {\n const wrappedSelector = React.useCallback(\n (others: Others<TPresence, TUserMeta>) =>\n others.map(\n (other) => [other.connectionId, itemSelector(other)] as const\n ),\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 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 const NOT_FOUND = Symbol();\n\n type NotFound = typeof NOT_FOUND;\n\n function useOther<T>(\n connectionId: number,\n selector: (other: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n const wrappedSelector = React.useCallback(\n (others: Others<TPresence, TUserMeta>) => {\n // TODO: Make this O(1) instead of O(n)?\n const other = others.find(\n (other) => other.connectionId === connectionId\n );\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 function useBroadcastEvent(): (\n event: TRoomEvent,\n options?: BroadcastOptions\n ) => void {\n const room = useRoom();\n\n return React.useCallback(\n (\n event: TRoomEvent,\n options: BroadcastOptions = { shouldQueueEventIfNotReady: false }\n ) => {\n room.broadcastEvent(event, options);\n },\n [room]\n );\n }\n\n function useLostConnectionListener(\n callback: (event: LostConnectionEvent) => void\n ): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(\n () =>\n room.events.lostConnection.subscribe((event: LostConnectionEvent) =>\n savedCallback.current(event)\n ),\n [room]\n );\n }\n\n function useErrorListener(callback: (err: Error) => void): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(\n () => room.events.error.subscribe((e: Error) => savedCallback.current(e)),\n [room]\n );\n }\n\n function useEventListener(\n callback: (eventData: { connectionId: number; event: TRoomEvent }) => void\n ): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(() => {\n const listener = (eventData: {\n connectionId: number;\n event: TRoomEvent;\n }) => {\n savedCallback.current(eventData);\n };\n\n return room.events.customEvent.subscribe(listener);\n }, [room]);\n }\n\n function useSelf(): User<TPresence, TUserMeta> | null;\n function useSelf<T>(\n selector: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | null;\n function useSelf<T>(\n maybeSelector?: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | User<TPresence, TUserMeta> | null {\n type Snapshot = User<TPresence, TUserMeta> | null;\n type Selection = T | null;\n\n const room = useRoom();\n const subscribe = room.events.self.subscribe;\n const getSnapshot: () => Snapshot = room.getSelf;\n\n const selector =\n maybeSelector ?? (identity as (me: User<TPresence, TUserMeta>) => T);\n const wrappedSelector = React.useCallback(\n (me: Snapshot): Selection => (me !== null ? selector(me) : null),\n [selector]\n );\n\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n }\n\n function useMutableStorageRoot(): LiveObject<TStorage> | null {\n type Snapshot = LiveObject<TStorage> | null;\n const room = useRoom();\n const subscribe = room.events.storageDidLoad.subscribeOnce;\n const getSnapshot = room.getStorageSnapshot;\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n }\n\n // NOTE: This API exists for backward compatible reasons\n function useStorageRoot(): [root: LiveObject<TStorage> | null] {\n return [useMutableStorageRoot()];\n }\n\n function useHistory(): History {\n return useRoom().history;\n }\n\n function useUndo(): () => void {\n return useHistory().undo;\n }\n\n function useRedo(): () => void {\n return useHistory().redo;\n }\n\n function 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 function 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\n function useBatch<T>(): (callback: () => T) => T {\n return useRoom().batch;\n }\n\n function useLegacyKey<TKey extends Extract<keyof TStorage, string>>(\n key: TKey\n ): TStorage[TKey] | null {\n const room = useRoom();\n const root = useMutableStorageRoot();\n const rerender = useRerender();\n\n React.useEffect(() => {\n if (root === null) {\n return;\n }\n\n let liveValue = root.get(key);\n\n function onRootChange() {\n const newCrdt = root!.get(key);\n if (newCrdt !== liveValue) {\n unsubscribeCrdt();\n liveValue = newCrdt;\n unsubscribeCrdt = room.subscribe(\n liveValue as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n rerender\n );\n rerender();\n }\n }\n\n let unsubscribeCrdt = room.subscribe(\n liveValue as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n rerender\n );\n const unsubscribeRoot = room.subscribe(\n root as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n onRootChange\n );\n\n rerender();\n\n return () => {\n unsubscribeRoot();\n unsubscribeCrdt();\n };\n }, [root, room, key, rerender]);\n\n if (root === null) {\n return null;\n } else {\n return root.get(key);\n }\n }\n\n function useStorage<T>(\n selector: (root: ToImmutable<TStorage>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | null {\n type Snapshot = ToImmutable<TStorage> | null;\n type Selection = T | null;\n\n const room = useRoom();\n const rootOrNull = useMutableStorageRoot();\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 = React.useCallback((): Snapshot => null, []);\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n }\n\n function 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\n function useSuspendUntilStorageLoaded(): void {\n const room = useRoom();\n if (room.getStorageSnapshot() !== null) {\n return;\n }\n\n ensureNotServerSide();\n\n // Throw a _promise_. Suspense will suspend the component tree until this\n // promise resolves (aka until storage has loaded). After that, it will\n // render this component tree again.\n throw new Promise<void>((res) => {\n room.events.storageDidLoad.subscribeOnce(() => res());\n });\n }\n\n function useSuspendUntilPresenceLoaded(): void {\n const room = useRoom();\n if (room.getSelf() !== null) {\n return;\n }\n\n ensureNotServerSide();\n\n // Throw a _promise_. Suspense will suspend the component tree until this\n // promise resolves (aka until storage has loaded). After that, it will\n // render this component tree again.\n throw new Promise<void>((res) => {\n room.events.status.subscribeOnce(() => res());\n });\n }\n\n function useMutation<\n F extends (\n context: MutationContext<TPresence, TStorage, TUserMeta>,\n ...args: any[]\n ) => any,\n >(callback: F, deps: readonly unknown[]): OmitFirstArg<F> {\n const room = useRoom();\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(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\n function useStorageSuspense<T>(\n selector: (root: ToImmutable<TStorage>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n useSuspendUntilStorageLoaded();\n return useStorage(\n selector,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T;\n }\n\n function useSelfSuspense(): User<TPresence, TUserMeta>;\n function useSelfSuspense<T>(\n selector: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T;\n function useSelfSuspense<T>(\n selector?: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | User<TPresence, TUserMeta> {\n useSuspendUntilPresenceLoaded();\n return useSelf(\n selector as (me: User<TPresence, TUserMeta>) => T,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T | User<TPresence, TUserMeta>;\n }\n\n function useOthersSuspense<T>(\n selector?: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | Others<TPresence, TUserMeta> {\n useSuspendUntilPresenceLoaded();\n return useOthers(\n selector as (others: Others<TPresence, TUserMeta>) => T,\n isEqual as (prev: T, curr: T) => boolean\n ) as T | Others<TPresence, TUserMeta>;\n }\n\n function useOthersConnectionIdsSuspense(): readonly number[] {\n useSuspendUntilPresenceLoaded();\n return useOthersConnectionIds();\n }\n\n function useOthersMappedSuspense<T>(\n itemSelector: (other: User<TPresence, TUserMeta>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n ): ReadonlyArray<readonly [connectionId: number, data: T]> {\n useSuspendUntilPresenceLoaded();\n return useOthersMapped(itemSelector, itemIsEqual);\n }\n\n function useOtherSuspense<T>(\n connectionId: number,\n selector: (other: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n useSuspendUntilPresenceLoaded();\n return useOther(connectionId, selector, isEqual);\n }\n\n function useLegacyKeySuspense<TKey extends Extract<keyof TStorage, string>>(\n key: TKey\n ): TStorage[TKey] {\n useSuspendUntilStorageLoaded();\n return useLegacyKey(key) as TStorage[TKey];\n }\n\n /*\n * START COMMMENTS\n */\n\n const errorEventSource = makeEventSource<CommentsApiError<TThreadMetadata>>();\n\n const commentsRooms = new Map<string, CommentsRoom<TThreadMetadata>>();\n\n function getCommentsRoom(\n room: Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n ) {\n let commentsRoom = commentsRooms.get(room.id);\n if (commentsRoom === undefined) {\n commentsRoom = createCommentsRoom(room, errorEventSource);\n commentsRooms.set(room.id, commentsRoom);\n }\n return commentsRoom;\n }\n\n function useThreads(): RoomThreads<TThreadMetadata> {\n const room = useRoom();\n return getCommentsRoom(room).useThreads();\n }\n\n function useThreadsSuspense() {\n const room = useRoom();\n return getCommentsRoom(room).useThreadsSuspense();\n }\n\n function useCreateThread() {\n const room = useRoom();\n\n return React.useCallback(\n (options: CreateThreadOptions<TThreadMetadata>) =>\n getCommentsRoom(room).createThread(options),\n [room]\n );\n }\n\n function useEditThreadMetadata() {\n const room = useRoom();\n\n return React.useCallback(\n (options: EditThreadMetadataOptions<TThreadMetadata>) =>\n getCommentsRoom(room).editThreadMetadata(options),\n [room]\n );\n }\n\n function useCreateComment(): (options: CreateCommentOptions) => CommentData {\n const room = useRoom();\n\n return React.useCallback(\n (options: CreateCommentOptions) =>\n getCommentsRoom(room).createComment(options),\n [room]\n );\n }\n\n function useEditComment(): (options: EditCommentOptions) => void {\n const room = useRoom();\n\n return React.useCallback(\n (options: EditCommentOptions) =>\n getCommentsRoom(room).editComment(options),\n [room]\n );\n }\n\n function useDeleteComment() {\n const room = useRoom();\n\n return React.useCallback(\n (options: DeleteCommentOptions) =>\n getCommentsRoom(room).deleteComment(options),\n [room]\n );\n }\n\n const { resolveUser, resolveMentionSuggestions } = options ?? {};\n\n const usersCache = resolveUser\n ? createAsyncCache((stringifiedOptions: string) => {\n return resolveUser(\n JSON.parse(stringifiedOptions) as ResolveUserOptions\n );\n })\n : undefined;\n\n function useUser(userId: string) {\n const resolverKey = React.useMemo(\n () => JSON.stringify({ userId }),\n [userId]\n );\n const state = useAsyncCache(usersCache, resolverKey);\n\n React.useEffect(() => warnIfNoResolveUser(usersCache), []);\n\n if (state.isLoading) {\n return {\n isLoading: true,\n } as UserState<TUserMeta[\"info\"]>;\n } else {\n return {\n user: state.data,\n error: state.error,\n isLoading: false,\n } as UserState<TUserMeta[\"info\"]>;\n }\n }\n\n function useUserSuspense(userId: string) {\n const resolverKey = React.useMemo(\n () => JSON.stringify({ userId }),\n [userId]\n );\n const state = useAsyncCache(usersCache, resolverKey, {\n suspense: true,\n });\n\n React.useEffect(() => warnIfNoResolveUser(usersCache), []);\n\n return {\n user: state.data,\n error: state.error,\n isLoading: false,\n } as UserStateSuspense<TUserMeta[\"info\"]>;\n }\n\n const mentionSuggestionsCache = createAsyncCache<string[], unknown>(\n resolveMentionSuggestions\n ? (stringifiedOptions: string) => {\n return resolveMentionSuggestions(\n JSON.parse(stringifiedOptions) as ResolveMentionSuggestionsOptions\n );\n }\n : () => Promise.resolve([])\n );\n\n function useMentionSuggestions(search?: string) {\n const room = useRoom();\n const debouncedSearch = useDebounce(search, 500);\n const resolverKey = React.useMemo(\n () =>\n debouncedSearch !== undefined\n ? JSON.stringify({ text: debouncedSearch, roomId: room.id })\n : null,\n [debouncedSearch, room.id]\n );\n const { data } = useAsyncCache(mentionSuggestionsCache, resolverKey, {\n keepPreviousDataWhileLoading: true,\n });\n\n return data;\n }\n\n /*\n * END COMMENTS\n */\n\n const bundle = {\n RoomContext,\n RoomProvider,\n\n useRoom,\n useStatus,\n\n useBatch,\n useBroadcastEvent,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n // These are just aliases. The passed-in key will define their return values.\n useList: useLegacyKey,\n useMap: useLegacyKey,\n useObject: useLegacyKey,\n\n useStorageRoot,\n useStorage,\n\n useSelf,\n useMyPresence,\n useUpdateMyPresence,\n useOthers,\n useOthersMapped,\n useOthersConnectionIds,\n useOther,\n\n useMutation,\n\n useThreads,\n useUser,\n\n useCreateThread,\n useEditThreadMetadata,\n useCreateComment,\n useEditComment,\n useDeleteComment,\n\n useMentionSuggestions,\n\n suspense: {\n RoomContext,\n RoomProvider,\n\n useRoom,\n useStatus,\n\n useBatch,\n useBroadcastEvent,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n // Legacy hooks\n useList: useLegacyKeySuspense,\n useMap: useLegacyKeySuspense,\n useObject: useLegacyKeySuspense,\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,\n\n useThreads: useThreadsSuspense,\n useUser: useUserSuspense,\n\n useCreateThread,\n useEditThreadMetadata,\n useCreateComment,\n useEditComment,\n useDeleteComment,\n },\n };\n\n return bundle;\n}\n","import type {\n BaseMetadata,\n BaseUserMeta,\n CommentBody,\n CommentData,\n EventSource,\n Json,\n JsonObject,\n LsonObject,\n Room,\n ThreadData,\n} from \"@liveblocks/core\";\nimport { makePoller } from \"@liveblocks/core\";\nimport { nanoid } from \"nanoid\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\n\nimport type { CommentsApiError } from \"./errors\";\nimport {\n CreateCommentError,\n CreateThreadError,\n DeleteCommentError,\n EditCommentError,\n EditThreadMetadataError,\n} from \"./errors\";\nimport { createStore } from \"./lib/store\";\n\nconst POLLING_INTERVAL_REALTIME = 30000;\nconst POLLING_INTERVAL = 5000;\nconst THREAD_ID_PREFIX = \"th\";\nconst COMMENT_ID_PREFIX = \"cm\";\n\nexport type CommentsRoom<TThreadMetadata extends BaseMetadata> = {\n useThreads(): RoomThreads<TThreadMetadata>;\n useThreadsSuspense(): ThreadData<TThreadMetadata>[];\n createThread(\n options: CreateThreadOptions<TThreadMetadata>\n ): ThreadData<TThreadMetadata>;\n editThreadMetadata(options: EditThreadMetadataOptions<TThreadMetadata>): void;\n createComment(options: CreateCommentOptions): CommentData;\n editComment(options: EditCommentOptions): void;\n deleteComment(options: DeleteCommentOptions): void;\n subscribe(): () => void;\n};\n\nexport type CreateThreadOptions<TMetadata extends BaseMetadata> = [\n TMetadata,\n] extends [never]\n ? {\n body: CommentBody;\n }\n : { body: CommentBody; metadata: TMetadata };\n\nexport type EditThreadMetadataOptions<TMetadata extends BaseMetadata> = [\n TMetadata,\n] extends [never]\n ? {\n threadId: string;\n }\n : { threadId: string; metadata: Partial<TMetadata> };\n\nexport type CreateCommentOptions = {\n threadId: string;\n body: CommentBody;\n};\n\nexport type EditCommentOptions = {\n threadId: string;\n commentId: string;\n body: CommentBody;\n};\n\nexport type DeleteCommentOptions = {\n threadId: string;\n commentId: string;\n};\n\nfunction createOptimisticId(prefix: string) {\n return `${prefix}_${nanoid()}`;\n}\n\nexport type RoomThreads<TThreadMetadata extends BaseMetadata> =\n | {\n isLoading: true;\n threads?: never;\n error?: never;\n }\n | {\n isLoading: false;\n threads?: never;\n error: Error;\n }\n | {\n isLoading: false;\n threads: ThreadData<TThreadMetadata>[];\n error?: never;\n };\n\nexport function createCommentsRoom<TThreadMetadata extends BaseMetadata>(\n room: Room<JsonObject, LsonObject, BaseUserMeta, Json>,\n errorEventSource: EventSource<CommentsApiError<TThreadMetadata>>\n): CommentsRoom<TThreadMetadata> {\n const store = createStore<RoomThreads<TThreadMetadata>>({\n isLoading: true,\n });\n\n // Temporary solution\n // The most basic conflict resolution\n // If there are any pending mutation, we simply ignore any threads coming from the server\n // When all mutations are finished, we pull the source of truth from the backend\n\n let numberOfMutations = 0;\n function endMutation() {\n numberOfMutations--;\n if (numberOfMutations === 0) {\n revalidateThreads();\n }\n }\n\n function startMutation() {\n pollingHub.threads.stop();\n numberOfMutations++;\n }\n\n const pollingHub = {\n // TODO: If there's an error, it will currently infinitely retry at the current polling rate → add retry logic\n threads: makePoller(revalidateThreads),\n };\n let unsubscribeRealtimeEvents: (() => void) | undefined;\n let unsubscribeRealtimeConnection: (() => void) | undefined;\n let realtimeClientConnected = false;\n\n function getPollingInterval() {\n return realtimeClientConnected\n ? POLLING_INTERVAL_REALTIME\n : POLLING_INTERVAL;\n }\n\n function ensureThreadsAreLoadedForMutations() {\n const state = store.get();\n if (state.isLoading || state.error) {\n throw new Error(\n \"Cannot update threads or comments before they are loaded\"\n );\n }\n return state.threads;\n }\n\n async function revalidateThreads() {\n pollingHub.threads.pause();\n\n if (numberOfMutations === 0) {\n setThreads(await room.getThreads());\n }\n\n pollingHub.threads.resume();\n }\n\n function subscribe() {\n if (!unsubscribeRealtimeEvents) {\n unsubscribeRealtimeEvents = room.events.comments.subscribe(() => {\n pollingHub.threads.restart(getPollingInterval());\n revalidateThreads();\n });\n }\n\n if (!unsubscribeRealtimeConnection) {\n unsubscribeRealtimeConnection = room.events.status.subscribe((status) => {\n const nextRealtimeClientConnected = status === \"connected\";\n\n if (nextRealtimeClientConnected !== realtimeClientConnected) {\n realtimeClientConnected = nextRealtimeClientConnected;\n pollingHub.threads.restart(getPollingInterval());\n }\n });\n }\n\n // Will only start if not already started\n pollingHub.threads.start(getPollingInterval());\n\n // TODO: improve thread revalidation\n revalidateThreads();\n\n return () => {\n pollingHub.threads.stop();\n unsubscribeRealtimeEvents?.();\n unsubscribeRealtimeEvents = undefined;\n unsubscribeRealtimeConnection?.();\n unsubscribeRealtimeConnection = undefined;\n };\n }\n\n function setThreads(newThreads: ThreadData<TThreadMetadata>[]) {\n store.set({\n threads: newThreads,\n isLoading: false,\n });\n }\n\n function getCurrentUserId() {\n const self = room.getSelf();\n if (self === null || self.id === undefined) {\n return \"anonymous\";\n } else {\n return self.id;\n }\n }\n\n function createThread(\n options: CreateThreadOptions<TThreadMetadata>\n ): ThreadData<TThreadMetadata> {\n const body = options.body;\n const metadata: TThreadMetadata =\n \"metadata\" in options ? options.metadata : ({} as TThreadMetadata);\n const threads = ensureThreadsAreLoadedForMutations();\n\n const threadId = createOptimisticId(THREAD_ID_PREFIX);\n const commentId = createOptimisticId(COMMENT_ID_PREFIX);\n const now = new Date().toISOString();\n\n const newThread = {\n id: threadId,\n type: \"thread\",\n createdAt: now,\n roomId: room.id,\n metadata,\n comments: [\n {\n id: commentId,\n createdAt: now,\n type: \"comment\",\n userId: getCurrentUserId(),\n body,\n },\n ],\n } as ThreadData<TThreadMetadata>; // TODO: Figure out metadata typing\n\n setThreads([...threads, newThread]);\n\n startMutation();\n room\n .createThread({ threadId, commentId, body, metadata })\n .catch((er: Error) =>\n errorEventSource.notify(\n new CreateThreadError(er, {\n roomId: room.id,\n threadId,\n commentId,\n body,\n metadata,\n })\n )\n )\n .finally(endMutation);\n\n return newThread;\n }\n\n function editThreadMetadata(\n options: EditThreadMetadataOptions<TThreadMetadata>\n ): void {\n const threadId = options.threadId;\n const metadata: Partial<TThreadMetadata> =\n \"metadata\" in options ? options.metadata : {};\n const threads = ensureThreadsAreLoadedForMutations();\n\n setThreads(\n threads.map((thread) =>\n thread.id === threadId\n ? {\n ...thread,\n metadata: {\n ...thread.metadata,\n ...metadata,\n },\n }\n : thread\n )\n );\n\n startMutation();\n room\n .editThreadMetadata({ metadata, threadId })\n .catch((er: Error) =>\n errorEventSource.notify(\n new EditThreadMetadataError(er, {\n roomId: room.id,\n threadId,\n metadata,\n })\n )\n )\n .finally(endMutation);\n }\n\n function createComment({\n threadId,\n body,\n }: CreateCommentOptions): CommentData {\n const threads = ensureThreadsAreLoadedForMutations();\n\n const commentId = createOptimisticId(COMMENT_ID_PREFIX);\n const now = new Date().toISOString();\n\n const comment: CommentData = {\n id: commentId,\n threadId,\n roomId: room.id,\n type: \"comment\",\n createdAt: now,\n userId: getCurrentUserId(),\n body,\n };\n\n setThreads(\n threads.map((thread) =>\n thread.id === threadId\n ? {\n ...thread,\n comments: [...thread.comments, comment],\n }\n : thread\n )\n );\n\n startMutation();\n room\n .createComment({ threadId, commentId, body })\n .catch((er: Error) =>\n errorEventSource.notify(\n new CreateCommentError(er, {\n roomId: room.id,\n threadId,\n commentId,\n body,\n })\n )\n )\n .finally(endMutation);\n\n return comment;\n }\n\n function editComment({ threadId, commentId, body }: EditCommentOptions) {\n const threads = ensureThreadsAreLoadedForMutations();\n const now = new Date().toISOString();\n\n setThreads(\n threads.map((thread) =>\n thread.id === threadId\n ? {\n ...thread,\n comments: thread.comments.map((comment) =>\n comment.id === commentId\n ? ({\n ...comment,\n editedAt: now,\n body,\n } as CommentData)\n : comment\n ),\n }\n : thread\n )\n );\n\n startMutation();\n room\n .editComment({ threadId, commentId, body })\n .catch((er: Error) =>\n errorEventSource.notify(\n new EditCommentError(er, {\n roomId: room.id,\n threadId,\n commentId,\n body,\n })\n )\n )\n .finally(endMutation);\n }\n\n function deleteComment({ threadId, commentId }: DeleteCommentOptions): void {\n const threads = ensureThreadsAreLoadedForMutations();\n const now = new Date().toISOString();\n\n const newThreads: ThreadData<TThreadMetadata>[] = [];\n\n for (const thread of threads) {\n if (thread.id === threadId) {\n const newThread: ThreadData<TThreadMetadata> = {\n ...thread,\n comments: thread.comments.map((comment) =>\n comment.id === commentId\n ? {\n ...comment,\n deletedAt: now,\n body: undefined,\n }\n : comment\n ),\n };\n\n if (\n newThread.comments.some((comment) => comment.deletedAt === undefined)\n ) {\n newThreads.push(newThread);\n }\n } else {\n newThreads.push(thread);\n }\n }\n\n setThreads(newThreads);\n\n startMutation();\n room\n .deleteComment({ threadId, commentId })\n .catch((er: Error) =>\n errorEventSource.notify(\n new DeleteCommentError(er, {\n roomId: room.id,\n threadId,\n commentId,\n })\n )\n )\n .finally(endMutation);\n }\n\n function useThreads(): RoomThreads<TThreadMetadata> {\n return useSyncExternalStore<RoomThreads<TThreadMetadata>>(\n store.subscribe,\n store.get,\n store.get\n );\n }\n\n function useThreadsSuspense() {\n const result = useThreads();\n\n if (result.isLoading) {\n throw new Promise(store.subscribeOnce);\n }\n\n if (result.error) {\n throw result.error;\n }\n\n return result.threads;\n }\n\n return {\n useThreads,\n useThreadsSuspense,\n createThread,\n editThreadMetadata,\n createComment,\n editComment,\n deleteComment,\n subscribe,\n };\n}\n","import type { BaseMetadata, CommentBody } from \"@liveblocks/core\";\n\nexport class CreateThreadError<TMetadata 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: TMetadata;\n }\n ) {\n super(\"Create thread failed.\");\n this.name = \"CreateThreadError\";\n }\n}\n\nexport class EditThreadMetadataError<\n TMetadata extends BaseMetadata,\n> extends Error {\n constructor(\n public cause: Error,\n public context: {\n roomId: string;\n threadId: string;\n metadata: Partial<TMetadata>;\n }\n ) {\n super(\"Edit thread metadata failed.\");\n this.name = \"EditThreadMetadataError\";\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 type CommentsApiError<TThreadMetadata extends BaseMetadata> =\n | CreateThreadError<TThreadMetadata>\n | EditThreadMetadataError<TThreadMetadata>\n | CreateCommentError\n | EditCommentError\n | DeleteCommentError;\n","import type { UnsubscribeCallback } from \"@liveblocks/core\";\nimport { makeEventSource } from \"@liveblocks/core\";\n\n/**\n * Create a store that keep a state and let consumers subscribe to updates\n * The store assume that the provided state is immutable\n */\nexport function createStore<T>(initialState: T) {\n let state = initialState;\n const eventSource = makeEventSource<T>();\n\n return {\n get(): T {\n return state;\n },\n set(newState: T) {\n state = newState;\n eventSource.notify(state);\n },\n subscribe(callback: (state: T) => void): UnsubscribeCallback {\n return eventSource.subscribe(callback);\n },\n subscribeOnce(callback: (state: T) => void): UnsubscribeCallback {\n return eventSource.subscribeOnce(callback);\n },\n subscribersCount() {\n return eventSource.count();\n },\n destroy() {\n return eventSource.clear();\n },\n };\n}\n","import type {\n AsyncCache,\n AsyncState,\n AsyncStateInitial,\n AsyncStateResolved,\n} from \"@liveblocks/core\";\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\n\nimport { useInitial } from \"./use-initial\";\n\nconst INITIAL_ASYNC_STATE: AsyncStateInitial = {\n isLoading: false,\n data: undefined,\n error: undefined,\n};\n\ntype AsyncFunction<T, A extends any[] = any[]> = (...args: A) => Promise<T>;\n\nexport type UseAsyncCacheOptions<T> = {\n overrideFunction?: AsyncFunction<T, [string]>;\n keepPreviousDataWhileLoading?: boolean;\n suspense?: boolean;\n};\n\ntype UseAsyncCacheState<\n T,\n E,\n O extends UseAsyncCacheOptions<T> = UseAsyncCacheOptions<T>,\n> = O extends {\n suspense: true;\n}\n ? Exclude<AsyncState<T, E>, { isLoading: true }>\n : AsyncState<T, E>;\n\nexport type UseAsyncCacheResponse<\n T,\n E,\n O extends UseAsyncCacheOptions<T> = UseAsyncCacheOptions<T>,\n> = UseAsyncCacheState<T, E, O> & {\n /**\n * Returns the current state of the key synchronously.\n */\n getState: () => AsyncState<T, E>;\n\n /**\n * Revalidates the key.\n */\n revalidate(): Promise<AsyncStateResolved<T, E>>;\n};\n\ntype PreviousData<T> = {\n key: string | null;\n data?: T;\n};\n\nconst noop = () => {};\n\nexport function useAsyncCache<T, E, O extends UseAsyncCacheOptions<T>>(\n cache: AsyncCache<T, E> | undefined,\n key: string | null,\n options?: O\n): UseAsyncCacheResponse<T, E, O> {\n const frozenOptions = useInitial(options);\n const cacheItem = useMemo(() => {\n if (key === null || !cache) {\n return null;\n }\n\n const cacheItem = cache.create(key, frozenOptions?.overrideFunction);\n void cacheItem.get();\n\n return cacheItem;\n }, [cache, frozenOptions, key]);\n\n const subscribe = useCallback(\n (callback: () => void) => cacheItem?.subscribe(callback) ?? noop,\n [cacheItem]\n );\n\n const getState = useCallback(\n () => cacheItem?.getState() ?? INITIAL_ASYNC_STATE,\n [cacheItem]\n );\n\n const revalidate = useCallback(() => cacheItem?.revalidate(), [cacheItem]);\n\n const state = useSyncExternalStore(subscribe, getState, getState);\n const previousData = useRef<PreviousData<T>>();\n let data = state.data;\n\n useEffect(() => {\n previousData.current = { key, data: state.data };\n }, [key, state]);\n\n if (frozenOptions?.suspense && state.isLoading && cacheItem) {\n throw new Promise<void>((resolve) => {\n cacheItem.subscribeOnce(() => resolve());\n });\n }\n\n if (\n state.isLoading &&\n frozenOptions?.keepPreviousDataWhileLoading &&\n typeof state.data === \"undefined\" &&\n previousData.current?.key !== key &&\n typeof previousData.current?.data !== \"undefined\"\n ) {\n data = previousData.current.data;\n }\n\n return {\n isLoading: state.isLoading,\n data,\n error: state.error,\n getState,\n revalidate,\n } as UseAsyncCacheResponse<T, E, O>;\n}\n","import { useRef } from \"react\";\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)): T {\n return useRef(value instanceof Function ? value() : value).current;\n}\n","import { useEffect, useRef, useState } from \"react\";\n\nconst DEFAULT_DELAY = 500;\n\nexport function useDebounce<T>(\n value: T,\n delay: number | false = DEFAULT_DELAY\n): T {\n const timeout = useRef<number>();\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n if (delay === false) {\n return;\n }\n\n if (timeout.current === undefined) {\n setDebouncedValue(value);\n }\n\n timeout.current = window.setTimeout(() => {\n setDebouncedValue(value);\n timeout.current = undefined;\n }, delay);\n\n return () => {\n window.clearTimeout(timeout.current);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}\n","import { useReducer, useRef } from \"react\";\n\n/**\n * Trigger a re-render programmatically, without changing the component's\n * state.\n *\n * @example\n * const rerender = useRerender();\n *\n * return (\n * <button onClick={rerender}>\n * {Math.random()}\n * </button>\n * )\n */\nexport function useRerender(): () => void {\n const [, update] = useReducer(\n // This implementation works by incrementing a hidden counter value that is\n // never consumed. Simply incrementing the counter changes the component's\n // state and, thus, trigger a re-render.\n (x: number): number => x + 1,\n 0\n );\n return update;\n}\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 return useRef(value).current;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/version.ts","../src/ClientSideSuspense.tsx","../src/factory.tsx","../src/comments/CommentsRoom.ts","../src/comments/errors.ts","../src/comments/lib/store.ts","../src/comments/lib/use-async-cache.ts","../src/comments/lib/use-initial.ts","../src/comments/lib/use-debounce.ts","../src/hooks.ts","../src/lib/stable-stringify.ts"],"names":["makeEventSource","React","useEffect","useRef","useSyncExternalStore","cacheItem","useState","useInitial","sortedObject","noop","room","other","options","rootOrNull","shallow"],"mappings":"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","sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport { ClientSideSuspense } from \"./ClientSideSuspense\";\nexport { createRoomContext, useRoomContextBundle } from \"./factory\";\nexport type {\n MutationContext,\n ResolveMentionSuggestionsOptions,\n ResolveUserOptions,\n} from \"./types\";\n\n// Re-exports from @liveblocks/client, for convenience\nexport type { Json, JsonObject } from \"@liveblocks/client\";\nexport { shallow } from \"@liveblocks/client\";\n","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 { ReactElement, ReactNode } from \"react\";\nimport * as React from \"react\";\n\ntype Props = {\n fallback: NonNullable<ReactNode> | null;\n children: () => 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): ReactElement {\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 ? props.children() : props.fallback}\n </React.Suspense>\n );\n}\n","import type {\n BaseUserMeta,\n BroadcastOptions,\n Client,\n History,\n Json,\n JsonObject,\n LiveObject,\n LostConnectionEvent,\n LsonObject,\n Others,\n Room,\n Status,\n User,\n} from \"@liveblocks/client\";\nimport { shallow } from \"@liveblocks/client\";\nimport type {\n AsyncCache,\n BaseMetadata,\n CommentData,\n ToImmutable,\n} from \"@liveblocks/core\";\nimport {\n asArrayWithLegacyMethods,\n createAsyncCache,\n deprecateIf,\n errorIf,\n makeEventSource,\n} from \"@liveblocks/core\";\nimport * as React from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport type {\n CommentsRoom,\n CreateCommentOptions,\n CreateThreadOptions,\n DeleteCommentOptions,\n EditCommentOptions,\n EditThreadMetadataOptions,\n RoomThreads,\n} from \"./comments/CommentsRoom\";\nimport { createCommentsRoom } from \"./comments/CommentsRoom\";\nimport type { CommentsApiError } from \"./comments/errors\";\nimport { useAsyncCache } from \"./comments/lib/use-async-cache\";\nimport { useDebounce } from \"./comments/lib/use-debounce\";\nimport { useInitial, useRerender } from \"./hooks\";\nimport { stableStringify } from \"./lib/stable-stringify\";\nimport type {\n InternalRoomContextBundle,\n MutationContext,\n OmitFirstArg,\n ResolveMentionSuggestionsOptions,\n ResolveUserOptions,\n RoomContextBundle,\n RoomProviderProps,\n UserState,\n UserStateSuspense,\n} from \"./types\";\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/guides/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 EMPTY_OTHERS =\n // NOTE: asArrayWithLegacyMethods() wrapping should no longer be necessary in 0.19\n asArrayWithLegacyMethods([]);\n\nfunction getEmptyOthers() {\n return EMPTY_OTHERS;\n}\n\nfunction makeMutationContext<\n TPresence extends JsonObject,\n TStorage extends LsonObject,\n TUserMeta extends BaseUserMeta,\n TRoomEvent extends Json,\n>(\n room: Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n): MutationContext<TPresence, TStorage, TUserMeta> {\n const errmsg =\n \"This mutation cannot be used until connected to the Liveblocks room\";\n\n return {\n get storage() {\n const mutableRoot = room.getStorageSnapshot();\n if (mutableRoot === null) {\n throw new Error(errmsg);\n }\n return mutableRoot;\n },\n\n get self() {\n const self = room.getSelf();\n if (self === null) {\n throw new Error(errmsg);\n }\n return self;\n },\n\n get others() {\n const others = room.getOthers();\n if (room.getSelf() === null) {\n throw new Error(errmsg);\n }\n return others;\n },\n\n setMyPresence: room.updatePresence,\n };\n}\n\ntype Options<TUserMeta extends BaseUserMeta> = {\n /**\n * An asynchronous function that returns user info from a user ID.\n */\n resolveUser?: (\n options: ResolveUserOptions\n ) => Promise<TUserMeta[\"info\"] | undefined>;\n\n /**\n * An asynchronous function that returns a list of user IDs matching a string.\n */\n resolveMentionSuggestions?: (\n options: ResolveMentionSuggestionsOptions\n ) => Promise<string[]>;\n\n /**\n * @internal Internal endpoint\n */\n serverEndpoint?: string;\n};\n\nlet hasWarnedIfNoResolveUser = false;\n\nfunction warnIfNoResolveUser(usersCache?: AsyncCache<unknown, unknown>) {\n if (\n !hasWarnedIfNoResolveUser &&\n !usersCache &&\n process.env.NODE_ENV !== \"production\"\n ) {\n console.warn(\n \"Set the resolveUser option in createRoomContext to specify user info.\"\n );\n hasWarnedIfNoResolveUser = true;\n }\n}\n\nconst ContextBundle = React.createContext<InternalRoomContextBundle<\n JsonObject,\n LsonObject,\n BaseUserMeta,\n never,\n BaseMetadata\n> | null>(null);\n\n/**\n * @private\n *\n * This is an internal API, use `createRoomContext` instead.\n */\nexport function useRoomContextBundle() {\n const bundle = React.useContext(ContextBundle);\n if (bundle === null) {\n throw new Error(\"RoomProvider is missing from the React tree.\");\n }\n return bundle;\n}\n\nexport function createRoomContext<\n TPresence extends JsonObject,\n TStorage extends LsonObject = LsonObject,\n TUserMeta extends BaseUserMeta = BaseUserMeta,\n TRoomEvent extends Json = never,\n TThreadMetadata extends BaseMetadata = never,\n>(\n client: Client,\n options?: Options<TUserMeta>\n): RoomContextBundle<\n TPresence,\n TStorage,\n TUserMeta,\n TRoomEvent,\n TThreadMetadata\n> {\n const RoomContext = React.createContext<Room<\n TPresence,\n TStorage,\n TUserMeta,\n TRoomEvent\n > | null>(null);\n\n function RoomProvider(props: RoomProviderProps<TPresence, TStorage>) {\n const {\n id: roomId,\n initialPresence,\n initialStorage,\n unstable_batchedUpdates,\n shouldInitiallyConnect,\n } = 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 frozen = useInitial({\n initialPresence,\n initialStorage,\n unstable_batchedUpdates,\n shouldInitiallyConnect:\n shouldInitiallyConnect === undefined\n ? typeof window !== \"undefined\"\n : shouldInitiallyConnect,\n });\n\n const [room, setRoom] = React.useState<\n Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n >(() =>\n client.enter(roomId, {\n initialPresence: frozen.initialPresence,\n initialStorage: frozen.initialStorage,\n shouldInitiallyConnect: frozen.shouldInitiallyConnect,\n unstable_batchedUpdates: frozen.unstable_batchedUpdates,\n })\n );\n\n React.useEffect(() => {\n const room = client.enter<TPresence, TStorage, TUserMeta, TRoomEvent>(\n roomId,\n {\n initialPresence: frozen.initialPresence,\n initialStorage: frozen.initialStorage,\n shouldInitiallyConnect: frozen.shouldInitiallyConnect,\n unstable_batchedUpdates: frozen.unstable_batchedUpdates,\n }\n );\n\n setRoom(room);\n\n return () => {\n const commentsRoom = commentsRooms.get(roomId);\n if (commentsRoom) {\n commentsRooms.delete(roomId);\n }\n client.leave(roomId);\n };\n }, [roomId, frozen]);\n\n return (\n <RoomContext.Provider value={room}>\n <ContextBundle.Provider\n value={\n internalBundle as unknown as InternalRoomContextBundle<\n JsonObject,\n LsonObject,\n BaseUserMeta,\n never,\n BaseMetadata\n >\n }\n >\n {props.children}\n </ContextBundle.Provider>\n </RoomContext.Provider>\n );\n }\n\n function connectionIdSelector(\n others: Others<TPresence, TUserMeta>\n ): number[] {\n return others.map((user) => user.connectionId);\n }\n\n function useRoom(): Room<TPresence, TStorage, TUserMeta, TRoomEvent> {\n const room = React.useContext(RoomContext);\n if (room === null) {\n throw new Error(\"RoomProvider is missing from the React tree.\");\n }\n return room;\n }\n\n function useStatus(): Status {\n const room = useRoom();\n const subscribe = room.events.status.subscribe;\n const getSnapshot = room.getStatus;\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n }\n\n function useMyPresence(): [\n TPresence,\n (patch: Partial<TPresence>, options?: { addToHistory: boolean }) => void,\n ] {\n const room = useRoom();\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\n function useUpdateMyPresence(): (\n patch: Partial<TPresence>,\n options?: { addToHistory: boolean }\n ) => void {\n return useRoom().updatePresence;\n }\n\n function useOthers(): Others<TPresence, TUserMeta>;\n function useOthers<T>(\n selector: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T;\n function useOthers<T>(\n selector?: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | Others<TPresence, TUserMeta> {\n const room = useRoom();\n const subscribe = room.events.others.subscribe;\n const getSnapshot = room.getOthers;\n const getServerSnapshot = getEmptyOthers;\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n selector ?? (identity as (others: Others<TPresence, TUserMeta>) => T),\n isEqual\n );\n }\n\n function useOthersConnectionIds(): readonly number[] {\n return useOthers(connectionIdSelector, shallow);\n }\n\n function useOthersMapped<T>(\n itemSelector: (other: User<TPresence, TUserMeta>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n ): ReadonlyArray<readonly [connectionId: number, data: T]> {\n const wrappedSelector = React.useCallback(\n (others: Others<TPresence, TUserMeta>) =>\n others.map(\n (other) => [other.connectionId, itemSelector(other)] as const\n ),\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 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 const NOT_FOUND = Symbol();\n\n type NotFound = typeof NOT_FOUND;\n\n function useOther<T>(\n connectionId: number,\n selector: (other: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n const wrappedSelector = React.useCallback(\n (others: Others<TPresence, TUserMeta>) => {\n // TODO: Make this O(1) instead of O(n)?\n const other = others.find(\n (other) => other.connectionId === connectionId\n );\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 function useBroadcastEvent(): (\n event: TRoomEvent,\n options?: BroadcastOptions\n ) => void {\n const room = useRoom();\n\n return React.useCallback(\n (\n event: TRoomEvent,\n options: BroadcastOptions = { shouldQueueEventIfNotReady: false }\n ) => {\n room.broadcastEvent(event, options);\n },\n [room]\n );\n }\n\n function useLostConnectionListener(\n callback: (event: LostConnectionEvent) => void\n ): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(\n () =>\n room.events.lostConnection.subscribe((event: LostConnectionEvent) =>\n savedCallback.current(event)\n ),\n [room]\n );\n }\n\n function useErrorListener(callback: (err: Error) => void): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(\n () => room.events.error.subscribe((e: Error) => savedCallback.current(e)),\n [room]\n );\n }\n\n function useEventListener(\n callback: (eventData: { connectionId: number; event: TRoomEvent }) => void\n ): void {\n const room = useRoom();\n const savedCallback = React.useRef(callback);\n\n React.useEffect(() => {\n savedCallback.current = callback;\n });\n\n React.useEffect(() => {\n const listener = (eventData: {\n connectionId: number;\n event: TRoomEvent;\n }) => {\n savedCallback.current(eventData);\n };\n\n return room.events.customEvent.subscribe(listener);\n }, [room]);\n }\n\n function useSelf(): User<TPresence, TUserMeta> | null;\n function useSelf<T>(\n selector: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | null;\n function useSelf<T>(\n maybeSelector?: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | User<TPresence, TUserMeta> | null {\n type Snapshot = User<TPresence, TUserMeta> | null;\n type Selection = T | null;\n\n const room = useRoom();\n const subscribe = room.events.self.subscribe;\n const getSnapshot: () => Snapshot = room.getSelf;\n\n const selector =\n maybeSelector ?? (identity as (me: User<TPresence, TUserMeta>) => T);\n const wrappedSelector = React.useCallback(\n (me: Snapshot): Selection => (me !== null ? selector(me) : null),\n [selector]\n );\n\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n }\n\n function useMutableStorageRoot(): LiveObject<TStorage> | null {\n type Snapshot = LiveObject<TStorage> | null;\n const room = useRoom();\n const subscribe = room.events.storageDidLoad.subscribeOnce;\n const getSnapshot = room.getStorageSnapshot;\n const getServerSnapshot = React.useCallback((): Snapshot => null, []);\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n }\n\n // NOTE: This API exists for backward compatible reasons\n function useStorageRoot(): [root: LiveObject<TStorage> | null] {\n return [useMutableStorageRoot()];\n }\n\n function useHistory(): History {\n return useRoom().history;\n }\n\n function useUndo(): () => void {\n return useHistory().undo;\n }\n\n function useRedo(): () => void {\n return useHistory().redo;\n }\n\n function 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 function 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\n function useBatch<T>(): (callback: () => T) => T {\n return useRoom().batch;\n }\n\n function useLegacyKey<TKey extends Extract<keyof TStorage, string>>(\n key: TKey\n ): TStorage[TKey] | null {\n const room = useRoom();\n const root = useMutableStorageRoot();\n const rerender = useRerender();\n\n React.useEffect(() => {\n if (root === null) {\n return;\n }\n\n let liveValue = root.get(key);\n\n function onRootChange() {\n const newCrdt = root!.get(key);\n if (newCrdt !== liveValue) {\n unsubscribeCrdt();\n liveValue = newCrdt;\n unsubscribeCrdt = room.subscribe(\n liveValue as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n rerender\n );\n rerender();\n }\n }\n\n let unsubscribeCrdt = room.subscribe(\n liveValue as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n rerender\n );\n const unsubscribeRoot = room.subscribe(\n root as any /* AbstractCrdt */, // TODO: This is hiding a bug! If `liveValue` happens to be the string `\"event\"` this actually subscribes an event handler!\n onRootChange\n );\n\n rerender();\n\n return () => {\n unsubscribeRoot();\n unsubscribeCrdt();\n };\n }, [root, room, key, rerender]);\n\n if (root === null) {\n return null;\n } else {\n return root.get(key);\n }\n }\n\n function useStorage<T>(\n selector: (root: ToImmutable<TStorage>) => T,\n isEqual?: (prev: T | null, curr: T | null) => boolean\n ): T | null {\n type Snapshot = ToImmutable<TStorage> | null;\n type Selection = T | null;\n\n const room = useRoom();\n const rootOrNull = useMutableStorageRoot();\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 = React.useCallback((): Snapshot => null, []);\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getServerSnapshot,\n wrappedSelector,\n isEqual\n );\n }\n\n function 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\n function useSuspendUntilStorageLoaded(): void {\n const room = useRoom();\n if (room.getStorageSnapshot() !== null) {\n return;\n }\n\n ensureNotServerSide();\n\n // Throw a _promise_. Suspense will suspend the component tree until this\n // promise resolves (aka until storage has loaded). After that, it will\n // render this component tree again.\n throw new Promise<void>((res) => {\n room.events.storageDidLoad.subscribeOnce(() => res());\n });\n }\n\n function useSuspendUntilPresenceLoaded(): void {\n const room = useRoom();\n if (room.getSelf() !== null) {\n return;\n }\n\n ensureNotServerSide();\n\n // Throw a _promise_. Suspense will suspend the component tree until this\n // promise resolves (aka until storage has loaded). After that, it will\n // render this component tree again.\n throw new Promise<void>((res) => {\n room.events.status.subscribeOnce(() => res());\n });\n }\n\n function useMutation<\n F extends (\n context: MutationContext<TPresence, TStorage, TUserMeta>,\n ...args: any[]\n ) => any,\n >(callback: F, deps: readonly unknown[]): OmitFirstArg<F> {\n const room = useRoom();\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(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\n function useStorageSuspense<T>(\n selector: (root: ToImmutable<TStorage>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n useSuspendUntilStorageLoaded();\n return useStorage(\n selector,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T;\n }\n\n function useSelfSuspense(): User<TPresence, TUserMeta>;\n function useSelfSuspense<T>(\n selector: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T;\n function useSelfSuspense<T>(\n selector?: (me: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | User<TPresence, TUserMeta> {\n useSuspendUntilPresenceLoaded();\n return useSelf(\n selector as (me: User<TPresence, TUserMeta>) => T,\n isEqual as (prev: T | null, curr: T | null) => boolean\n ) as T | User<TPresence, TUserMeta>;\n }\n\n function useOthersSuspense<T>(\n selector?: (others: Others<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T | Others<TPresence, TUserMeta> {\n useSuspendUntilPresenceLoaded();\n return useOthers(\n selector as (others: Others<TPresence, TUserMeta>) => T,\n isEqual as (prev: T, curr: T) => boolean\n ) as T | Others<TPresence, TUserMeta>;\n }\n\n function useOthersConnectionIdsSuspense(): readonly number[] {\n useSuspendUntilPresenceLoaded();\n return useOthersConnectionIds();\n }\n\n function useOthersMappedSuspense<T>(\n itemSelector: (other: User<TPresence, TUserMeta>) => T,\n itemIsEqual?: (prev: T, curr: T) => boolean\n ): ReadonlyArray<readonly [connectionId: number, data: T]> {\n useSuspendUntilPresenceLoaded();\n return useOthersMapped(itemSelector, itemIsEqual);\n }\n\n function useOtherSuspense<T>(\n connectionId: number,\n selector: (other: User<TPresence, TUserMeta>) => T,\n isEqual?: (prev: T, curr: T) => boolean\n ): T {\n useSuspendUntilPresenceLoaded();\n return useOther(connectionId, selector, isEqual);\n }\n\n function useLegacyKeySuspense<TKey extends Extract<keyof TStorage, string>>(\n key: TKey\n ): TStorage[TKey] {\n useSuspendUntilStorageLoaded();\n return useLegacyKey(key) as TStorage[TKey];\n }\n\n /*\n * START COMMMENTS\n */\n\n const errorEventSource = makeEventSource<CommentsApiError<TThreadMetadata>>();\n\n const commentsRooms = new Map<string, CommentsRoom<TThreadMetadata>>();\n\n function getCommentsRoom(\n room: Room<TPresence, TStorage, TUserMeta, TRoomEvent>\n ) {\n let commentsRoom = commentsRooms.get(room.id);\n if (commentsRoom === undefined) {\n commentsRoom = createCommentsRoom(room, errorEventSource);\n commentsRooms.set(room.id, commentsRoom);\n }\n return commentsRoom;\n }\n\n function useThreads(): RoomThreads<TThreadMetadata> {\n const room = useRoom();\n return getCommentsRoom(room).useThreads();\n }\n\n function useThreadsSuspense() {\n const room = useRoom();\n return getCommentsRoom(room).useThreadsSuspense();\n }\n\n function useCreateThread() {\n const room = useRoom();\n\n return React.useCallback(\n (options: CreateThreadOptions<TThreadMetadata>) =>\n getCommentsRoom(room).createThread(options),\n [room]\n );\n }\n\n function useEditThreadMetadata() {\n const room = useRoom();\n\n return React.useCallback(\n (options: EditThreadMetadataOptions<TThreadMetadata>) =>\n getCommentsRoom(room).editThreadMetadata(options),\n [room]\n );\n }\n\n function useCreateComment(): (options: CreateCommentOptions) => CommentData {\n const room = useRoom();\n\n return React.useCallback(\n (options: CreateCommentOptions) =>\n getCommentsRoom(room).createComment(options),\n [room]\n );\n }\n\n function useEditComment(): (options: EditCommentOptions) => void {\n const room = useRoom();\n\n return React.useCallback(\n (options: EditCommentOptions) =>\n getCommentsRoom(room).editComment(options),\n [room]\n );\n }\n\n function useDeleteComment() {\n const room = useRoom();\n\n return React.useCallback(\n (options: DeleteCommentOptions) =>\n getCommentsRoom(room).deleteComment(options),\n [room]\n );\n }\n\n const { resolveUser, resolveMentionSuggestions } = options ?? {};\n\n const usersCache = resolveUser\n ? createAsyncCache((stringifiedOptions: string) => {\n return resolveUser(\n JSON.parse(stringifiedOptions) as ResolveUserOptions\n );\n })\n : undefined;\n\n function useUser(userId: string) {\n const resolverKey = React.useMemo(\n () => stableStringify({ userId }),\n [userId]\n );\n const state = useAsyncCache(usersCache, resolverKey);\n\n React.useEffect(() => warnIfNoResolveUser(usersCache), []);\n\n if (state.isLoading) {\n return {\n isLoading: true,\n } as UserState<TUserMeta[\"info\"]>;\n } else {\n return {\n user: state.data,\n error: state.error,\n isLoading: false,\n } as UserState<TUserMeta[\"info\"]>;\n }\n }\n\n function useUserSuspense(userId: string) {\n const resolverKey = React.useMemo(\n () => stableStringify({ userId }),\n [userId]\n );\n const state = useAsyncCache(usersCache, resolverKey, {\n suspense: true,\n });\n\n React.useEffect(() => warnIfNoResolveUser(usersCache), []);\n\n return {\n user: state.data,\n error: state.error,\n isLoading: false,\n } as UserStateSuspense<TUserMeta[\"info\"]>;\n }\n\n const mentionSuggestionsCache = createAsyncCache<string[], unknown>(\n resolveMentionSuggestions\n ? (stringifiedOptions: string) => {\n return resolveMentionSuggestions(\n JSON.parse(stringifiedOptions) as ResolveMentionSuggestionsOptions\n );\n }\n : () => Promise.resolve([])\n );\n\n function useMentionSuggestions(search?: string) {\n const room = useRoom();\n const debouncedSearch = useDebounce(search, 500);\n const resolverKey = React.useMemo(\n () =>\n debouncedSearch !== undefined\n ? stableStringify({ text: debouncedSearch, roomId: room.id })\n : null,\n [debouncedSearch, room.id]\n );\n const { data } = useAsyncCache(mentionSuggestionsCache, resolverKey, {\n keepPreviousDataWhileLoading: true,\n });\n\n return data;\n }\n\n /*\n * END COMMENTS\n */\n\n const bundle: RoomContextBundle<\n TPresence,\n TStorage,\n TUserMeta,\n TRoomEvent,\n TThreadMetadata\n > = {\n RoomContext,\n RoomProvider,\n\n useRoom,\n useStatus,\n\n useBatch,\n useBroadcastEvent,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n // These are just aliases. The passed-in key will define their return values.\n useList: useLegacyKey,\n useMap: useLegacyKey,\n useObject: useLegacyKey,\n\n useStorageRoot,\n useStorage,\n\n useSelf,\n useMyPresence,\n useUpdateMyPresence,\n useOthers,\n useOthersMapped,\n useOthersConnectionIds,\n useOther,\n\n useMutation,\n\n useThreads,\n useUser,\n\n useCreateThread,\n useEditThreadMetadata,\n useCreateComment,\n useEditComment,\n useDeleteComment,\n\n suspense: {\n RoomContext,\n RoomProvider,\n\n useRoom,\n useStatus,\n\n useBatch,\n useBroadcastEvent,\n useLostConnectionListener,\n useErrorListener,\n useEventListener,\n\n useHistory,\n useUndo,\n useRedo,\n useCanRedo,\n useCanUndo,\n\n // Legacy hooks\n useList: useLegacyKeySuspense,\n useMap: useLegacyKeySuspense,\n useObject: useLegacyKeySuspense,\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,\n\n useThreads: useThreadsSuspense,\n useUser: useUserSuspense,\n\n useCreateThread,\n useEditThreadMetadata,\n useCreateComment,\n useEditComment,\n useDeleteComment,\n },\n };\n\n const internalBundle: InternalRoomContextBundle<\n TPresence,\n TStorage,\n TUserMeta,\n TRoomEvent,\n TThreadMetadata\n > = {\n ...bundle,\n hasResolveMentionSuggestions: resolveMentionSuggestions !== undefined,\n useMentionSuggestions,\n };\n\n return bundle;\n}\n","/// <reference types=\"react/experimental\" />\n\nimport type {\n BaseMetadata,\n BaseUserMeta,\n CommentBody,\n CommentData,\n EventSource,\n Json,\n JsonObject,\n LsonObject,\n Room,\n ThreadData,\n} from \"@liveblocks/core\";\nimport { makePoller } from \"@liveblocks/core\";\nimport { nanoid } from \"nanoid\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\n\nimport type { CommentsApiError } from \"./errors\";\nimport {\n CreateCommentError,\n CreateThreadError,\n DeleteCommentError,\n EditCommentError,\n EditThreadMetadataError,\n} from \"./errors\";\nimport { createStore } from \"./lib/store\";\nimport { useEffect } from \"react\";\n\nconst POLLING_INTERVAL_REALTIME = 30000;\nconst POLLING_INTERVAL = 5000;\nconst THREAD_ID_PREFIX = \"th\";\nconst COMMENT_ID_PREFIX = \"cm\";\n\nexport type CommentsRoom<TThreadMetadata extends BaseMetadata> = {\n useThreads(): RoomThreads<TThreadMetadata>;\n useThreadsSuspense(): ThreadData<TThreadMetadata>[];\n createThread(\n options: CreateThreadOptions<TThreadMetadata>\n ): ThreadData<TThreadMetadata>;\n editThreadMetadata(options: EditThreadMetadataOptions<TThreadMetadata>): void;\n createComment(options: CreateCommentOptions): CommentData;\n editComment(options: EditCommentOptions): void;\n deleteComment(options: DeleteCommentOptions): void;\n};\n\nexport type CreateThreadOptions<TMetadata extends BaseMetadata> = [\n TMetadata,\n] extends [never]\n ? {\n body: CommentBody;\n }\n : { body: CommentBody; metadata: TMetadata };\n\nexport type EditThreadMetadataOptions<TMetadata extends BaseMetadata> = [\n TMetadata,\n] extends [never]\n ? {\n threadId: string;\n }\n : { threadId: string; metadata: Partial<TMetadata> };\n\nexport type CreateCommentOptions = {\n threadId: string;\n body: CommentBody;\n};\n\nexport type EditCommentOptions = {\n threadId: string;\n commentId: string;\n body: CommentBody;\n};\n\nexport type DeleteCommentOptions = {\n threadId: string;\n commentId: string;\n};\n\nfunction createOptimisticId(prefix: string) {\n return `${prefix}_${nanoid()}`;\n}\n\nexport type RoomThreads<TThreadMetadata extends BaseMetadata> =\n | {\n isLoading: true;\n threads?: never;\n error?: never;\n }\n | {\n isLoading: false;\n threads?: never;\n error: Error;\n }\n | {\n isLoading: false;\n threads: ThreadData<TThreadMetadata>[];\n error?: never;\n };\n\nexport function createCommentsRoom<TThreadMetadata extends BaseMetadata>(\n room: Room<JsonObject, LsonObject, BaseUserMeta, Json>,\n errorEventSource: EventSource<CommentsApiError<TThreadMetadata>>\n): CommentsRoom<TThreadMetadata> {\n const store = createStore<RoomThreads<TThreadMetadata>>({\n isLoading: true,\n });\n\n let fetchThreadsPromise: Promise<any> | null = null;\n\n // Temporary solution\n // The most basic conflict resolution\n // If there are any pending mutation, we simply ignore any threads coming from the server\n // When all mutations are finished, we pull the source of truth from the backend\n\n let numberOfMutations = 0;\n function endMutation() {\n numberOfMutations--;\n if (numberOfMutations === 0) {\n revalidateThreads();\n }\n }\n\n function startMutation() {\n pollingHub.threads.stop();\n numberOfMutations++;\n }\n\n const pollingHub = {\n // TODO: If there's an error, it will currently infinitely retry at the current polling rate → add retry logic\n threads: makePoller(revalidateThreads),\n };\n let unsubscribeRealtimeEvents: (() => void) | undefined;\n let unsubscribeRealtimeConnection: (() => void) | undefined;\n let realtimeClientConnected = false;\n\n function getPollingInterval() {\n return realtimeClientConnected\n ? POLLING_INTERVAL_REALTIME\n : POLLING_INTERVAL;\n }\n\n function ensureThreadsAreLoadedForMutations() {\n const state = store.get();\n if (state.isLoading || state.error) {\n throw new Error(\n \"Cannot update threads or comments before they are loaded\"\n );\n }\n return state.threads;\n }\n\n async function revalidateThreads() {\n pollingHub.threads.pause();\n\n if (numberOfMutations === 0) {\n if (fetchThreadsPromise === null) {\n fetchThreadsPromise = room.getThreads();\n }\n setThreads(await fetchThreadsPromise);\n fetchThreadsPromise = null;\n }\n\n pollingHub.threads.resume();\n }\n\n function subscribe() {\n if (!unsubscribeRealtimeEvents) {\n unsubscribeRealtimeEvents = room.events.comments.subscribe(() => {\n pollingHub.threads.restart(getPollingInterval());\n revalidateThreads();\n });\n }\n\n if (!unsubscribeRealtimeConnection) {\n unsubscribeRealtimeConnection = room.events.status.subscribe((status) => {\n const nextRealtimeClientConnected = status === \"connected\";\n\n if (nextRealtimeClientConnected !== realtimeClientConnected) {\n realtimeClientConnected = nextRealtimeClientConnected;\n pollingHub.threads.restart(getPollingInterval());\n }\n });\n }\n\n // Will only start if not already started\n pollingHub.threads.start(getPollingInterval());\n\n return () => {\n if (store.subscribersCount() > 1) {\n return;\n }\n\n pollingHub.threads.stop();\n unsubscribeRealtimeEvents?.();\n unsubscribeRealtimeEvents = undefined;\n unsubscribeRealtimeConnection?.();\n unsubscribeRealtimeConnection = undefined;\n };\n }\n\n function setThreads(newThreads: ThreadData<TThreadMetadata>[]) {\n store.set({\n threads: newThreads,\n isLoading: false,\n });\n }\n\n function useThreadsInternal(): RoomThreads<TThreadMetadata> {\n useEffect(subscribe, []);\n\n return useSyncExternalStore<RoomThreads<TThreadMetadata>>(\n store.subscribe,\n store.get,\n store.get\n );\n }\n\n function useThreads(): RoomThreads<TThreadMetadata> {\n useEffect(() => {\n void revalidateThreads();\n }, []);\n\n return useThreadsInternal();\n }\n\n function useThreadsSuspense() {\n const result = useThreadsInternal();\n\n if (result.isLoading) {\n throw revalidateThreads();\n }\n\n if (result.error) {\n throw result.error;\n }\n\n return result.threads;\n }\n\n function getCurrentUserId() {\n const self = room.getSelf();\n if (self === null || self.id === undefined) {\n return \"anonymous\";\n } else {\n return self.id;\n }\n }\n\n function createThread(\n options: CreateThreadOptions<TThreadMetadata>\n ): ThreadData<TThreadMetadata> {\n const body = options.body;\n const metadata: TThreadMetadata =\n \"metadata\" in options ? options.metadata : ({} as TThreadMetadata);\n const threads = ensureThreadsAreLoadedForMutations();\n\n const threadId = createOptimisticId(THREAD_ID_PREFIX);\n const commentId = createOptimisticId(COMMENT_ID_PREFIX);\n const now = new Date().toISOString();\n\n const newThread = {\n id: threadId,\n type: \"thread\",\n createdAt: now,\n roomId: room.id,\n metadata,\n comments: [\n {\n id: commentId,\n createdAt: now,\n type: \"comment\",\n userId: getCurrentUserId(),\n body,\n },\n ],\n } as ThreadData<TThreadMetadata>; // TODO: Figure out metadata typing\n\n setThreads([...threads, newThread]);\n\n startMutation();\n room\n .createThread({ threadId, commentId, body, metadata })\n .catch((er: Error) =>\n errorEventSource.notify(\n new CreateThreadError(er, {\n roomId: room.id,\n threadId,\n commentId,\n body,\n metadata,\n })\n )\n )\n .finally(endMutation);\n\n return newThread;\n }\n\n function editThreadMetadata(\n options: EditThreadMetadataOptions<TThreadMetadata>\n ): void {\n const threadId = options.threadId;\n const metadata: Partial<TThreadMetadata> =\n \"metadata\" in options ? options.metadata : {};\n const threads = ensureThreadsAreLoadedForMutations();\n\n setThreads(\n threads.map((thread) =>\n thread.id === threadId\n ? {\n ...thread,\n metadata: {\n ...thread.metadata,\n ...metadata,\n },\n }\n : thread\n )\n );\n\n startMutation();\n room\n .editThreadMetadata({ metadata, threadId })\n .catch((er: Error) =>\n errorEventSource.notify(\n new EditThreadMetadataError(er, {\n roomId: room.id,\n threadId,\n metadata,\n })\n )\n )\n .finally(endMutation);\n }\n\n function createComment({\n threadId,\n body,\n }: CreateCommentOptions): CommentData {\n const threads = ensureThreadsAreLoadedForMutations();\n\n const commentId = createOptimisticId(COMMENT_ID_PREFIX);\n const now = new Date().toISOString();\n\n const comment: CommentData = {\n id: commentId,\n threadId,\n roomId: room.id,\n type: \"comment\",\n createdAt: now,\n userId: getCurrentUserId(),\n body,\n };\n\n setThreads(\n threads.map((thread) =>\n thread.id === threadId\n ? {\n ...thread,\n comments: [...thread.comments, comment],\n }\n : thread\n )\n );\n\n startMutation();\n room\n .createComment({ threadId, commentId, body })\n .catch((er: Error) =>\n errorEventSource.notify(\n new CreateCommentError(er, {\n roomId: room.id,\n threadId,\n commentId,\n body,\n })\n )\n )\n .finally(endMutation);\n\n return comment;\n }\n\n function editComment({ threadId, commentId, body }: EditCommentOptions) {\n const threads = ensureThreadsAreLoadedForMutations();\n const now = new Date().toISOString();\n\n setThreads(\n threads.map((thread) =>\n thread.id === threadId\n ? {\n ...thread,\n comments: thread.comments.map((comment) =>\n comment.id === commentId\n ? ({\n ...comment,\n editedAt: now,\n body,\n } as CommentData)\n : comment\n ),\n }\n : thread\n )\n );\n\n startMutation();\n room\n .editComment({ threadId, commentId, body })\n .catch((er: Error) =>\n errorEventSource.notify(\n new EditCommentError(er, {\n roomId: room.id,\n threadId,\n commentId,\n body,\n })\n )\n )\n .finally(endMutation);\n }\n\n function deleteComment({ threadId, commentId }: DeleteCommentOptions): void {\n const threads = ensureThreadsAreLoadedForMutations();\n const now = new Date().toISOString();\n\n const newThreads: ThreadData<TThreadMetadata>[] = [];\n\n for (const thread of threads) {\n if (thread.id === threadId) {\n const newThread: ThreadData<TThreadMetadata> = {\n ...thread,\n comments: thread.comments.map((comment) =>\n comment.id === commentId\n ? {\n ...comment,\n deletedAt: now,\n body: undefined,\n }\n : comment\n ),\n };\n\n if (\n newThread.comments.some((comment) => comment.deletedAt === undefined)\n ) {\n newThreads.push(newThread);\n }\n } else {\n newThreads.push(thread);\n }\n }\n\n setThreads(newThreads);\n\n startMutation();\n room\n .deleteComment({ threadId, commentId })\n .catch((er: Error) =>\n errorEventSource.notify(\n new DeleteCommentError(er, {\n roomId: room.id,\n threadId,\n commentId,\n })\n )\n )\n .finally(endMutation);\n }\n\n return {\n useThreads,\n useThreadsSuspense,\n createThread,\n editThreadMetadata,\n createComment,\n editComment,\n deleteComment,\n };\n}\n","import type { BaseMetadata, CommentBody } from \"@liveblocks/core\";\n\nexport class CreateThreadError<TMetadata 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: TMetadata;\n }\n ) {\n super(\"Create thread failed.\");\n this.name = \"CreateThreadError\";\n }\n}\n\nexport class EditThreadMetadataError<\n TMetadata extends BaseMetadata,\n> extends Error {\n constructor(\n public cause: Error,\n public context: {\n roomId: string;\n threadId: string;\n metadata: Partial<TMetadata>;\n }\n ) {\n super(\"Edit thread metadata failed.\");\n this.name = \"EditThreadMetadataError\";\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 type CommentsApiError<TThreadMetadata extends BaseMetadata> =\n | CreateThreadError<TThreadMetadata>\n | EditThreadMetadataError<TThreadMetadata>\n | CreateCommentError\n | EditCommentError\n | DeleteCommentError;\n","import type { UnsubscribeCallback } from \"@liveblocks/core\";\nimport { makeEventSource } from \"@liveblocks/core\";\n\n/**\n * Create a store that keep a state and let consumers subscribe to updates\n * The store assume that the provided state is immutable\n */\nexport function createStore<T>(initialState: T) {\n let state = initialState;\n const eventSource = makeEventSource<T>();\n\n return {\n get(): T {\n return state;\n },\n set(newState: T) {\n state = newState;\n eventSource.notify(state);\n },\n subscribe(callback: (state: T) => void): UnsubscribeCallback {\n return eventSource.subscribe(callback);\n },\n subscribeOnce(callback: (state: T) => void): UnsubscribeCallback {\n return eventSource.subscribeOnce(callback);\n },\n subscribersCount() {\n return eventSource.count();\n },\n destroy() {\n return eventSource.clear();\n },\n };\n}\n","import type {\n AsyncCache,\n AsyncState,\n AsyncStateInitial,\n AsyncStateResolved,\n} from \"@liveblocks/core\";\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\n\nimport { useInitial } from \"./use-initial\";\n\nconst INITIAL_ASYNC_STATE: AsyncStateInitial = {\n isLoading: false,\n data: undefined,\n error: undefined,\n};\n\ntype AsyncFunction<T, A extends any[] = any[]> = (...args: A) => Promise<T>;\n\nexport type UseAsyncCacheOptions<T> = {\n overrideFunction?: AsyncFunction<T, [string]>;\n keepPreviousDataWhileLoading?: boolean;\n suspense?: boolean;\n};\n\ntype UseAsyncCacheState<\n T,\n E,\n O extends UseAsyncCacheOptions<T> = UseAsyncCacheOptions<T>,\n> = O extends {\n suspense: true;\n}\n ? Exclude<AsyncState<T, E>, { isLoading: true }>\n : AsyncState<T, E>;\n\nexport type UseAsyncCacheResponse<\n T,\n E,\n O extends UseAsyncCacheOptions<T> = UseAsyncCacheOptions<T>,\n> = UseAsyncCacheState<T, E, O> & {\n /**\n * Returns the current state of the key synchronously.\n */\n getState: () => AsyncState<T, E>;\n\n /**\n * Revalidates the key.\n */\n revalidate(): Promise<AsyncStateResolved<T, E>>;\n};\n\ntype PreviousData<T> = {\n key: string | null;\n data?: T;\n};\n\nconst noop = () => {};\n\nexport function useAsyncCache<T, E, O extends UseAsyncCacheOptions<T>>(\n cache: AsyncCache<T, E> | undefined,\n key: string | null,\n options?: O\n): UseAsyncCacheResponse<T, E, O> {\n const frozenOptions = useInitial(options);\n const cacheItem = useMemo(() => {\n if (key === null || !cache) {\n return null;\n }\n\n const cacheItem = cache.create(key, frozenOptions?.overrideFunction);\n void cacheItem.get();\n\n return cacheItem;\n }, [cache, frozenOptions, key]);\n\n const subscribe = useCallback(\n (callback: () => void) => cacheItem?.subscribe(callback) ?? noop,\n [cacheItem]\n );\n\n const getState = useCallback(\n () => cacheItem?.getState() ?? INITIAL_ASYNC_STATE,\n [cacheItem]\n );\n\n const revalidate = useCallback(() => cacheItem?.revalidate(), [cacheItem]);\n\n const state = useSyncExternalStore(subscribe, getState, getState);\n const previousData = useRef<PreviousData<T>>();\n let data = state.data;\n\n useEffect(() => {\n previousData.current = { key, data: state.data };\n }, [key, state]);\n\n if (frozenOptions?.suspense && state.isLoading && cacheItem) {\n throw new Promise<void>((resolve) => {\n cacheItem.subscribeOnce(() => resolve());\n });\n }\n\n if (\n state.isLoading &&\n frozenOptions?.keepPreviousDataWhileLoading &&\n typeof state.data === \"undefined\" &&\n previousData.current?.key !== key &&\n typeof previousData.current?.data !== \"undefined\"\n ) {\n data = previousData.current.data;\n }\n\n return {\n isLoading: state.isLoading,\n data,\n error: state.error,\n getState,\n revalidate,\n } as UseAsyncCacheResponse<T, E, O>;\n}\n","import { useRef } from \"react\";\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)): T {\n return useRef(value instanceof Function ? value() : value).current;\n}\n","import { useEffect, useRef, useState } from \"react\";\n\nconst DEFAULT_DELAY = 500;\n\nexport function useDebounce<T>(\n value: T,\n delay: number | false = DEFAULT_DELAY\n): T {\n const timeout = useRef<number>();\n const [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n useEffect(() => {\n if (delay === false) {\n return;\n }\n\n if (timeout.current === undefined) {\n setDebouncedValue(value);\n }\n\n timeout.current = window.setTimeout(() => {\n setDebouncedValue(value);\n timeout.current = undefined;\n }, delay);\n\n return () => {\n window.clearTimeout(timeout.current);\n };\n }, [value, delay]);\n\n return debouncedValue;\n}\n","import { useReducer, useRef } from \"react\";\n\n/**\n * Trigger a re-render programmatically, without changing the component's\n * state.\n *\n * @example\n * const rerender = useRerender();\n *\n * return (\n * <button onClick={rerender}>\n * {Math.random()}\n * </button>\n * )\n */\nexport function useRerender(): () => void {\n const [, update] = useReducer(\n // This implementation works by incrementing a hidden counter value that is\n // never consumed. Simply incrementing the counter changes the component's\n // state and, thus, trigger a re-render.\n (x: number): number => x + 1,\n 0\n );\n return update;\n}\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 return useRef(value).current;\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\ntype OmitFirstTupleElement<T extends any[]> = T extends [any, ...infer R]\n ? R\n : never;\n\nexport function stableStringify(\n object: Parameters<typeof JSON.stringify>[0],\n ...args: OmitFirstTupleElement<Parameters<typeof JSON.stringify>>\n) {\n const sortedObject = Object.keys(object)\n .sort()\n .reduce(\n (sortedObject, key) => {\n sortedObject[key] = object[key];\n\n return sortedObject;\n },\n {} as Record<string, any>\n );\n\n return JSON.stringify(sortedObject, ...args);\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { detectDupes } from "@liveblocks/core";
|
|
|
5
5
|
|
|
6
6
|
// src/version.ts
|
|
7
7
|
var PKG_NAME = "@liveblocks/react";
|
|
8
|
-
var PKG_VERSION = "1.2.2-
|
|
8
|
+
var PKG_VERSION = "1.2.2-comments6";
|
|
9
9
|
var PKG_FORMAT = "esm";
|
|
10
10
|
|
|
11
11
|
// src/ClientSideSuspense.tsx
|
|
@@ -106,6 +106,7 @@ function createStore(initialState) {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
// src/comments/CommentsRoom.ts
|
|
109
|
+
import { useEffect as useEffect2 } from "react";
|
|
109
110
|
var POLLING_INTERVAL_REALTIME = 3e4;
|
|
110
111
|
var POLLING_INTERVAL = 5e3;
|
|
111
112
|
var THREAD_ID_PREFIX = "th";
|
|
@@ -117,6 +118,7 @@ function createCommentsRoom(room, errorEventSource) {
|
|
|
117
118
|
const store = createStore({
|
|
118
119
|
isLoading: true
|
|
119
120
|
});
|
|
121
|
+
let fetchThreadsPromise = null;
|
|
120
122
|
let numberOfMutations = 0;
|
|
121
123
|
function endMutation() {
|
|
122
124
|
numberOfMutations--;
|
|
@@ -150,7 +152,11 @@ function createCommentsRoom(room, errorEventSource) {
|
|
|
150
152
|
async function revalidateThreads() {
|
|
151
153
|
pollingHub.threads.pause();
|
|
152
154
|
if (numberOfMutations === 0) {
|
|
153
|
-
|
|
155
|
+
if (fetchThreadsPromise === null) {
|
|
156
|
+
fetchThreadsPromise = room.getThreads();
|
|
157
|
+
}
|
|
158
|
+
setThreads(await fetchThreadsPromise);
|
|
159
|
+
fetchThreadsPromise = null;
|
|
154
160
|
}
|
|
155
161
|
pollingHub.threads.resume();
|
|
156
162
|
}
|
|
@@ -171,8 +177,10 @@ function createCommentsRoom(room, errorEventSource) {
|
|
|
171
177
|
});
|
|
172
178
|
}
|
|
173
179
|
pollingHub.threads.start(getPollingInterval());
|
|
174
|
-
revalidateThreads();
|
|
175
180
|
return () => {
|
|
181
|
+
if (store.subscribersCount() > 1) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
176
184
|
pollingHub.threads.stop();
|
|
177
185
|
unsubscribeRealtimeEvents?.();
|
|
178
186
|
unsubscribeRealtimeEvents = void 0;
|
|
@@ -186,6 +194,30 @@ function createCommentsRoom(room, errorEventSource) {
|
|
|
186
194
|
isLoading: false
|
|
187
195
|
});
|
|
188
196
|
}
|
|
197
|
+
function useThreadsInternal() {
|
|
198
|
+
useEffect2(subscribe, []);
|
|
199
|
+
return useSyncExternalStore(
|
|
200
|
+
store.subscribe,
|
|
201
|
+
store.get,
|
|
202
|
+
store.get
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
function useThreads() {
|
|
206
|
+
useEffect2(() => {
|
|
207
|
+
void revalidateThreads();
|
|
208
|
+
}, []);
|
|
209
|
+
return useThreadsInternal();
|
|
210
|
+
}
|
|
211
|
+
function useThreadsSuspense() {
|
|
212
|
+
const result = useThreadsInternal();
|
|
213
|
+
if (result.isLoading) {
|
|
214
|
+
throw revalidateThreads();
|
|
215
|
+
}
|
|
216
|
+
if (result.error) {
|
|
217
|
+
throw result.error;
|
|
218
|
+
}
|
|
219
|
+
return result.threads;
|
|
220
|
+
}
|
|
189
221
|
function getCurrentUserId() {
|
|
190
222
|
const self = room.getSelf();
|
|
191
223
|
if (self === null || self.id === void 0) {
|
|
@@ -359,23 +391,6 @@ function createCommentsRoom(room, errorEventSource) {
|
|
|
359
391
|
)
|
|
360
392
|
).finally(endMutation);
|
|
361
393
|
}
|
|
362
|
-
function useThreads() {
|
|
363
|
-
return useSyncExternalStore(
|
|
364
|
-
store.subscribe,
|
|
365
|
-
store.get,
|
|
366
|
-
store.get
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
function useThreadsSuspense() {
|
|
370
|
-
const result = useThreads();
|
|
371
|
-
if (result.isLoading) {
|
|
372
|
-
throw new Promise(store.subscribeOnce);
|
|
373
|
-
}
|
|
374
|
-
if (result.error) {
|
|
375
|
-
throw result.error;
|
|
376
|
-
}
|
|
377
|
-
return result.threads;
|
|
378
|
-
}
|
|
379
394
|
return {
|
|
380
395
|
useThreads,
|
|
381
396
|
useThreadsSuspense,
|
|
@@ -383,13 +398,12 @@ function createCommentsRoom(room, errorEventSource) {
|
|
|
383
398
|
editThreadMetadata,
|
|
384
399
|
createComment,
|
|
385
400
|
editComment,
|
|
386
|
-
deleteComment
|
|
387
|
-
subscribe
|
|
401
|
+
deleteComment
|
|
388
402
|
};
|
|
389
403
|
}
|
|
390
404
|
|
|
391
405
|
// src/comments/lib/use-async-cache.ts
|
|
392
|
-
import { useCallback, useEffect as
|
|
406
|
+
import { useCallback, useEffect as useEffect3, useMemo, useRef as useRef2 } from "react";
|
|
393
407
|
import { useSyncExternalStore as useSyncExternalStore2 } from "use-sync-external-store/shim/index.js";
|
|
394
408
|
|
|
395
409
|
// src/comments/lib/use-initial.ts
|
|
@@ -428,7 +442,7 @@ function useAsyncCache(cache, key, options) {
|
|
|
428
442
|
const state = useSyncExternalStore2(subscribe, getState, getState);
|
|
429
443
|
const previousData = useRef2();
|
|
430
444
|
let data = state.data;
|
|
431
|
-
|
|
445
|
+
useEffect3(() => {
|
|
432
446
|
previousData.current = { key, data: state.data };
|
|
433
447
|
}, [key, state]);
|
|
434
448
|
if (frozenOptions?.suspense && state.isLoading && cacheItem) {
|
|
@@ -449,12 +463,12 @@ function useAsyncCache(cache, key, options) {
|
|
|
449
463
|
}
|
|
450
464
|
|
|
451
465
|
// src/comments/lib/use-debounce.ts
|
|
452
|
-
import { useEffect as
|
|
466
|
+
import { useEffect as useEffect4, useRef as useRef3, useState as useState2 } from "react";
|
|
453
467
|
var DEFAULT_DELAY = 500;
|
|
454
468
|
function useDebounce(value, delay = DEFAULT_DELAY) {
|
|
455
469
|
const timeout = useRef3();
|
|
456
470
|
const [debouncedValue, setDebouncedValue] = useState2(value);
|
|
457
|
-
|
|
471
|
+
useEffect4(() => {
|
|
458
472
|
if (delay === false) {
|
|
459
473
|
return;
|
|
460
474
|
}
|
|
@@ -488,6 +502,18 @@ function useInitial2(value) {
|
|
|
488
502
|
return useRef4(value).current;
|
|
489
503
|
}
|
|
490
504
|
|
|
505
|
+
// src/lib/stable-stringify.ts
|
|
506
|
+
function stableStringify(object, ...args) {
|
|
507
|
+
const sortedObject = Object.keys(object).sort().reduce(
|
|
508
|
+
(sortedObject2, key) => {
|
|
509
|
+
sortedObject2[key] = object[key];
|
|
510
|
+
return sortedObject2;
|
|
511
|
+
},
|
|
512
|
+
{}
|
|
513
|
+
);
|
|
514
|
+
return JSON.stringify(sortedObject, ...args);
|
|
515
|
+
}
|
|
516
|
+
|
|
491
517
|
// src/factory.tsx
|
|
492
518
|
var noop2 = () => {
|
|
493
519
|
};
|
|
@@ -552,7 +578,11 @@ function warnIfNoResolveUser(usersCache) {
|
|
|
552
578
|
}
|
|
553
579
|
var ContextBundle = React2.createContext(null);
|
|
554
580
|
function useRoomContextBundle() {
|
|
555
|
-
|
|
581
|
+
const bundle = React2.useContext(ContextBundle);
|
|
582
|
+
if (bundle === null) {
|
|
583
|
+
throw new Error("RoomProvider is missing from the React tree.");
|
|
584
|
+
}
|
|
585
|
+
return bundle;
|
|
556
586
|
}
|
|
557
587
|
function createRoomContext(client, options) {
|
|
558
588
|
const RoomContext = React2.createContext(null);
|
|
@@ -609,14 +639,21 @@ function createRoomContext(client, options) {
|
|
|
609
639
|
}
|
|
610
640
|
);
|
|
611
641
|
setRoom(room2);
|
|
612
|
-
const unsubscribe = getCommentsRoom(room2).subscribe();
|
|
613
642
|
return () => {
|
|
614
|
-
|
|
615
|
-
|
|
643
|
+
const commentsRoom = commentsRooms.get(roomId);
|
|
644
|
+
if (commentsRoom) {
|
|
645
|
+
commentsRooms.delete(roomId);
|
|
646
|
+
}
|
|
616
647
|
client.leave(roomId);
|
|
617
648
|
};
|
|
618
649
|
}, [roomId, frozen]);
|
|
619
|
-
return /* @__PURE__ */ React2.createElement(RoomContext.Provider, { value: room }, /* @__PURE__ */ React2.createElement(
|
|
650
|
+
return /* @__PURE__ */ React2.createElement(RoomContext.Provider, { value: room }, /* @__PURE__ */ React2.createElement(
|
|
651
|
+
ContextBundle.Provider,
|
|
652
|
+
{
|
|
653
|
+
value: internalBundle
|
|
654
|
+
},
|
|
655
|
+
props.children
|
|
656
|
+
));
|
|
620
657
|
}
|
|
621
658
|
function connectionIdSelector(others) {
|
|
622
659
|
return others.map((user) => user.connectionId);
|
|
@@ -1026,7 +1063,7 @@ function createRoomContext(client, options) {
|
|
|
1026
1063
|
}) : void 0;
|
|
1027
1064
|
function useUser(userId) {
|
|
1028
1065
|
const resolverKey = React2.useMemo(
|
|
1029
|
-
() =>
|
|
1066
|
+
() => stableStringify({ userId }),
|
|
1030
1067
|
[userId]
|
|
1031
1068
|
);
|
|
1032
1069
|
const state = useAsyncCache(usersCache, resolverKey);
|
|
@@ -1045,7 +1082,7 @@ function createRoomContext(client, options) {
|
|
|
1045
1082
|
}
|
|
1046
1083
|
function useUserSuspense(userId) {
|
|
1047
1084
|
const resolverKey = React2.useMemo(
|
|
1048
|
-
() =>
|
|
1085
|
+
() => stableStringify({ userId }),
|
|
1049
1086
|
[userId]
|
|
1050
1087
|
);
|
|
1051
1088
|
const state = useAsyncCache(usersCache, resolverKey, {
|
|
@@ -1069,7 +1106,7 @@ function createRoomContext(client, options) {
|
|
|
1069
1106
|
const room = useRoom();
|
|
1070
1107
|
const debouncedSearch = useDebounce(search, 500);
|
|
1071
1108
|
const resolverKey = React2.useMemo(
|
|
1072
|
-
() => debouncedSearch !== void 0 ?
|
|
1109
|
+
() => debouncedSearch !== void 0 ? stableStringify({ text: debouncedSearch, roomId: room.id }) : null,
|
|
1073
1110
|
[debouncedSearch, room.id]
|
|
1074
1111
|
);
|
|
1075
1112
|
const { data } = useAsyncCache(mentionSuggestionsCache, resolverKey, {
|
|
@@ -1113,7 +1150,6 @@ function createRoomContext(client, options) {
|
|
|
1113
1150
|
useCreateComment,
|
|
1114
1151
|
useEditComment,
|
|
1115
1152
|
useDeleteComment,
|
|
1116
|
-
useMentionSuggestions,
|
|
1117
1153
|
suspense: {
|
|
1118
1154
|
RoomContext,
|
|
1119
1155
|
RoomProvider,
|
|
@@ -1152,6 +1188,11 @@ function createRoomContext(client, options) {
|
|
|
1152
1188
|
useDeleteComment
|
|
1153
1189
|
}
|
|
1154
1190
|
};
|
|
1191
|
+
const internalBundle = {
|
|
1192
|
+
...bundle,
|
|
1193
|
+
hasResolveMentionSuggestions: resolveMentionSuggestions !== void 0,
|
|
1194
|
+
useMentionSuggestions
|
|
1195
|
+
};
|
|
1155
1196
|
return bundle;
|
|
1156
1197
|
}
|
|
1157
1198
|
|