@liveblocks/react-lexical 2.7.0-versions2 → 2.7.0

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.
@@ -74,13 +74,13 @@ function CommentPluginProvider({ children }) {
74
74
  handleThreadDelete(error.context.threadId);
75
75
  }
76
76
  });
77
- const store = client[core.kInternal].cacheStore;
77
+ const store = react.getUmbrellaStoreForClient(client);
78
78
  const threads = withSelector_js.useSyncExternalStoreWithSelector(
79
79
  store.subscribe,
80
80
  store.get,
81
81
  store.get,
82
82
  React.useCallback(
83
- () => react.selectedThreads(room.id, store.get(), {}).map((thread) => thread.id),
83
+ () => react.selectRoomThreads(room.id, store.get(), {}).map((thread) => thread.id),
84
84
  [room.id, store]
85
85
  ),
86
86
  core.shallow
@@ -159,7 +159,7 @@ function CommentPluginProvider({ children }) {
159
159
  function $onStateRead() {
160
160
  const selection = lexical.$getSelection();
161
161
  const threadIds = $getThreadIds(selection).filter((id) => {
162
- return react.selectedThreads(room.id, store.get(), {}).some(
162
+ return react.selectRoomThreads(room.id, store.get(), {}).some(
163
163
  (thread) => thread.id === id
164
164
  );
165
165
  });
@@ -1 +1 @@
1
- {"version":3,"file":"comment-plugin-provider.js","sources":["../../src/comments/comment-plugin-provider.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n addClassNamesToElement,\n registerNestedElementResolver,\n removeClassNamesFromElement,\n} from \"@lexical/utils\";\nimport { kInternal, shallow } from \"@liveblocks/core\";\nimport {\n CreateThreadError,\n selectedThreads,\n useClient,\n useCommentsErrorListener,\n useRoom,\n} from \"@liveblocks/react\";\nimport type { BaseSelection, NodeKey, NodeMutation } from \"lexical\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n} from \"lexical\";\nimport type { PropsWithChildren } from \"react\";\nimport * as React from \"react\";\nimport { createContext, useCallback, useEffect, useState } from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport $getThreadMarkIds from \"./get-thread-mark-ids\";\nimport {\n $createThreadMarkNode,\n $isThreadMarkNode,\n ThreadMarkNode,\n} from \"./thread-mark-node\";\nimport $unwrapThreadMarkNode from \"./unwrap-thread-mark-node\";\n\nexport const OnDeleteThreadCallback = createContext<\n ((threadId: string) => void) | null\n>(null);\n\nexport const ActiveThreadsContext = createContext<string[] | null>(null);\n\nexport const IsActiveThreadContext = createContext<\n ((threadId: string) => boolean) | null\n>(null);\n\nexport type ThreadToNodesMap = Map<string, Set<NodeKey>>;\n\nexport const ThreadToNodesContext = createContext<ThreadToNodesMap | null>(\n null\n);\n\nexport function CommentPluginProvider({ children }: PropsWithChildren) {\n const [editor, context] = useLexicalComposerContext();\n\n const [threadToNodes, setThreadToNodes] = useState<ThreadToNodesMap>(\n new Map()\n ); // A map from thread id to a set of (thread mark) node keys that are associated with the thread\n\n const [activeThreads, setActiveThreads] = useState<string[]>([]); // The threads that are currently active (or selected) in the editor\n\n const client = useClient();\n\n const room = useRoom();\n\n const isThreadActive = useCallback(\n (threadId: string) => {\n return activeThreads.includes(threadId);\n },\n [activeThreads]\n );\n\n /**\n * Remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads.\n * @param threadId The id of the thread to remove\n */\n const handleThreadDelete = useCallback(\n (threadId: string) => {\n editor.update(() => {\n // Retrieve node keys associated with the thread\n const keys = threadToNodes.get(threadId);\n if (keys === undefined) return;\n\n // Iterate over each thread node and disassociate the thread if from the node and unwrap the node if it is no longer associated with any threads\n for (const key of keys) {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n node.deleteID(threadId);\n\n if (node.getIDs().length === 0) {\n $unwrapThreadMarkNode(node);\n }\n }\n });\n },\n [editor, threadToNodes]\n );\n\n useCommentsErrorListener((error) => {\n // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n if (error instanceof CreateThreadError) {\n handleThreadDelete(error.context.threadId);\n }\n });\n\n const store = client[kInternal].cacheStore;\n\n const threads = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n useCallback(\n () =>\n selectedThreads(room.id, store.get(), {}).map((thread) => thread.id),\n [room.id, store]\n ),\n shallow\n );\n\n /**\n * Only add styles to the thread mark elements that currently have threads associated with them.\n */\n useEffect(() => {\n function getThreadMarkElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const id of threads) {\n const keys = threadToNodes.get(id);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const elements = getThreadMarkElements();\n\n const theme = context.getTheme();\n\n const classNames = [\"lb-root\", \"lb-lexical-thread-mark\"];\n if (theme && theme.liveblocks && \"threadMark\" in theme.liveblocks) {\n classNames.push((theme.liveblocks as { threadMark: string }).threadMark);\n }\n\n elements.forEach((element) => {\n addClassNamesToElement(element, ...classNames);\n });\n\n return () => {\n elements.forEach((element) => {\n removeClassNamesFromElement(element, ...classNames);\n });\n };\n }, [context, editor, threadToNodes, threads]);\n\n /**\n * Register a mutation listener that listens for mutations on 'ThreadMarkNode's and updates the map of thread to node keys accordingly.\n */\n useEffect(() => {\n function onMutation(mutations: Map<string, NodeMutation>) {\n const state = editor.getEditorState();\n setThreadToNodes((prev) => {\n const updatedMap = new Map(prev);\n state.read(() => {\n for (const [key, mutation] of mutations) {\n // If the node is destroyed, we remove its key from the map of thread to node keys\n if (mutation === \"destroyed\") {\n for (const [, nodes] of updatedMap) {\n nodes.delete(key);\n }\n }\n // Otherwise, if a new node is created or an existing node is updated, we update the map of thread to node keys to include the new/updated node\n else if (mutation === \"created\" || mutation === \"updated\") {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n\n const threadIds = node.getIDs();\n\n for (const id of threadIds) {\n const keys = updatedMap.get(id) ?? new Set();\n keys.add(key);\n updatedMap.set(id, keys);\n }\n }\n }\n });\n return updatedMap;\n });\n }\n\n return editor.registerMutationListener(ThreadMarkNode, onMutation);\n }, [editor]);\n\n /**\n * Register an update listener that listens for changes in the selection and updates the active threads accordingly.\n */\n useEffect(() => {\n function $getThreadIds(selection: BaseSelection | null): string[] {\n if (selection === null) return [];\n\n if (!$isRangeSelection(selection)) return [];\n\n const anchor = selection.anchor.getNode();\n if (!$isTextNode(anchor)) return [];\n\n return $getThreadMarkIds(anchor, selection.anchor.offset) ?? [];\n }\n\n function $onStateRead() {\n const selection = $getSelection();\n\n const threadIds = $getThreadIds(selection).filter((id) => {\n return selectedThreads(room.id, store.get(), {}).some(\n (thread) => thread.id === id\n );\n });\n setActiveThreads(threadIds);\n }\n\n const unsubscribeCache = store.subscribe(() => {\n editor.getEditorState().read($onStateRead);\n });\n\n const unregisterUpdateListener = editor.registerUpdateListener(\n ({ editorState: state }) => {\n state.read($onStateRead);\n }\n );\n\n return () => {\n unregisterUpdateListener();\n unsubscribeCache();\n };\n }, [editor, client, room.id, store]);\n\n /**\n * When active threads change, we add a data-state attribute and set it to \"active\" for all HTML elements that are associated with the active threads.\n */\n useEffect(() => {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = threadToNodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n activeElements.forEach((element) => {\n element.setAttribute(\"data-state\", \"active\");\n });\n\n return () => {\n activeElements.forEach((element) => {\n element.removeAttribute(\"data-state\");\n });\n };\n }, [activeThreads, editor, threadToNodes]);\n\n useEffect(() => {\n return registerNestedElementResolver<ThreadMarkNode>(\n editor,\n ThreadMarkNode,\n (from: ThreadMarkNode) => {\n return $createThreadMarkNode(from.getIDs());\n },\n (from: ThreadMarkNode, to: ThreadMarkNode) => {\n const ids = from.getIDs();\n ids.forEach((id) => {\n to.addID(id);\n });\n }\n );\n }, [editor]);\n\n return (\n <OnDeleteThreadCallback.Provider value={handleThreadDelete}>\n <ActiveThreadsContext.Provider value={activeThreads}>\n <IsActiveThreadContext.Provider value={isThreadActive}>\n <ThreadToNodesContext.Provider value={threadToNodes}>\n {children}\n </ThreadToNodesContext.Provider>\n </IsActiveThreadContext.Provider>\n </ActiveThreadsContext.Provider>\n </OnDeleteThreadCallback.Provider>\n );\n}\n\n/**\n * Returns whether the associated thread annotation for the given thread id is selected or not in the editor.\n * @param threadId The id of the thread to check if the associated annotation is selected or not.\n * @returns true if the associated annotation for the thread is selected, false otherwise.\n */\nexport function useIsThreadActive(threadId: string): boolean {\n const isActive = React.useContext(IsActiveThreadContext);\n if (isActive === null) {\n throw new Error(\n \"useIsThreadActive must be used within LiveblocksPlugin. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#useIsThreadActive\"\n );\n }\n\n return isActive(threadId);\n}\n"],"names":["createContext","useLexicalComposerContext","useState","useClient","useRoom","useCallback","$getNodeByKey","$isThreadMarkNode","$unwrapThreadMarkNode","useCommentsErrorListener","CreateThreadError","kInternal","useSyncExternalStoreWithSelector","selectedThreads","shallow","useEffect","addClassNamesToElement","removeClassNamesFromElement","ThreadMarkNode","$isRangeSelection","$isTextNode","$getThreadMarkIds","$getSelection","activeElements","registerNestedElementResolver","$createThreadMarkNode","React"],"mappings":"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"}
1
+ {"version":3,"file":"comment-plugin-provider.js","sources":["../../src/comments/comment-plugin-provider.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n addClassNamesToElement,\n registerNestedElementResolver,\n removeClassNamesFromElement,\n} from \"@lexical/utils\";\nimport { shallow } from \"@liveblocks/core\";\nimport {\n CreateThreadError,\n getUmbrellaStoreForClient,\n selectRoomThreads,\n useClient,\n useCommentsErrorListener,\n useRoom,\n} from \"@liveblocks/react\";\nimport type { BaseSelection, NodeKey, NodeMutation } from \"lexical\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n} from \"lexical\";\nimport type { PropsWithChildren } from \"react\";\nimport * as React from \"react\";\nimport { createContext, useCallback, useEffect, useState } from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport $getThreadMarkIds from \"./get-thread-mark-ids\";\nimport {\n $createThreadMarkNode,\n $isThreadMarkNode,\n ThreadMarkNode,\n} from \"./thread-mark-node\";\nimport $unwrapThreadMarkNode from \"./unwrap-thread-mark-node\";\n\nexport const OnDeleteThreadCallback = createContext<\n ((threadId: string) => void) | null\n>(null);\n\nexport const ActiveThreadsContext = createContext<string[] | null>(null);\n\nexport const IsActiveThreadContext = createContext<\n ((threadId: string) => boolean) | null\n>(null);\n\nexport type ThreadToNodesMap = Map<string, Set<NodeKey>>;\n\nexport const ThreadToNodesContext = createContext<ThreadToNodesMap | null>(\n null\n);\n\nexport function CommentPluginProvider({ children }: PropsWithChildren) {\n const [editor, context] = useLexicalComposerContext();\n\n const [threadToNodes, setThreadToNodes] = useState<ThreadToNodesMap>(\n new Map()\n ); // A map from thread id to a set of (thread mark) node keys that are associated with the thread\n\n const [activeThreads, setActiveThreads] = useState<string[]>([]); // The threads that are currently active (or selected) in the editor\n\n const client = useClient();\n\n const room = useRoom();\n\n const isThreadActive = useCallback(\n (threadId: string) => {\n return activeThreads.includes(threadId);\n },\n [activeThreads]\n );\n\n /**\n * Remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads.\n * @param threadId The id of the thread to remove\n */\n const handleThreadDelete = useCallback(\n (threadId: string) => {\n editor.update(() => {\n // Retrieve node keys associated with the thread\n const keys = threadToNodes.get(threadId);\n if (keys === undefined) return;\n\n // Iterate over each thread node and disassociate the thread if from the node and unwrap the node if it is no longer associated with any threads\n for (const key of keys) {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n node.deleteID(threadId);\n\n if (node.getIDs().length === 0) {\n $unwrapThreadMarkNode(node);\n }\n }\n });\n },\n [editor, threadToNodes]\n );\n\n useCommentsErrorListener((error) => {\n // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n if (error instanceof CreateThreadError) {\n handleThreadDelete(error.context.threadId);\n }\n });\n\n const store = getUmbrellaStoreForClient(client);\n\n const threads = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n useCallback(\n () =>\n selectRoomThreads(room.id, store.get(), {}).map((thread) => thread.id),\n [room.id, store]\n ),\n shallow\n );\n\n /**\n * Only add styles to the thread mark elements that currently have threads associated with them.\n */\n useEffect(() => {\n function getThreadMarkElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const id of threads) {\n const keys = threadToNodes.get(id);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const elements = getThreadMarkElements();\n\n const theme = context.getTheme();\n\n const classNames = [\"lb-root\", \"lb-lexical-thread-mark\"];\n if (theme && theme.liveblocks && \"threadMark\" in theme.liveblocks) {\n classNames.push((theme.liveblocks as { threadMark: string }).threadMark);\n }\n\n elements.forEach((element) => {\n addClassNamesToElement(element, ...classNames);\n });\n\n return () => {\n elements.forEach((element) => {\n removeClassNamesFromElement(element, ...classNames);\n });\n };\n }, [context, editor, threadToNodes, threads]);\n\n /**\n * Register a mutation listener that listens for mutations on 'ThreadMarkNode's and updates the map of thread to node keys accordingly.\n */\n useEffect(() => {\n function onMutation(mutations: Map<string, NodeMutation>) {\n const state = editor.getEditorState();\n setThreadToNodes((prev) => {\n const updatedMap = new Map(prev);\n state.read(() => {\n for (const [key, mutation] of mutations) {\n // If the node is destroyed, we remove its key from the map of thread to node keys\n if (mutation === \"destroyed\") {\n for (const [, nodes] of updatedMap) {\n nodes.delete(key);\n }\n }\n // Otherwise, if a new node is created or an existing node is updated, we update the map of thread to node keys to include the new/updated node\n else if (mutation === \"created\" || mutation === \"updated\") {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n\n const threadIds = node.getIDs();\n\n for (const id of threadIds) {\n const keys = updatedMap.get(id) ?? new Set();\n keys.add(key);\n updatedMap.set(id, keys);\n }\n }\n }\n });\n return updatedMap;\n });\n }\n\n return editor.registerMutationListener(ThreadMarkNode, onMutation);\n }, [editor]);\n\n /**\n * Register an update listener that listens for changes in the selection and updates the active threads accordingly.\n */\n useEffect(() => {\n function $getThreadIds(selection: BaseSelection | null): string[] {\n if (selection === null) return [];\n\n if (!$isRangeSelection(selection)) return [];\n\n const anchor = selection.anchor.getNode();\n if (!$isTextNode(anchor)) return [];\n\n return $getThreadMarkIds(anchor, selection.anchor.offset) ?? [];\n }\n\n function $onStateRead() {\n const selection = $getSelection();\n\n const threadIds = $getThreadIds(selection).filter((id) => {\n return selectRoomThreads(room.id, store.get(), {}).some(\n (thread) => thread.id === id\n );\n });\n setActiveThreads(threadIds);\n }\n\n const unsubscribeCache = store.subscribe(() => {\n editor.getEditorState().read($onStateRead);\n });\n\n const unregisterUpdateListener = editor.registerUpdateListener(\n ({ editorState: state }) => {\n state.read($onStateRead);\n }\n );\n\n return () => {\n unregisterUpdateListener();\n unsubscribeCache();\n };\n }, [editor, client, room.id, store]);\n\n /**\n * When active threads change, we add a data-state attribute and set it to \"active\" for all HTML elements that are associated with the active threads.\n */\n useEffect(() => {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = threadToNodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n activeElements.forEach((element) => {\n element.setAttribute(\"data-state\", \"active\");\n });\n\n return () => {\n activeElements.forEach((element) => {\n element.removeAttribute(\"data-state\");\n });\n };\n }, [activeThreads, editor, threadToNodes]);\n\n useEffect(() => {\n return registerNestedElementResolver<ThreadMarkNode>(\n editor,\n ThreadMarkNode,\n (from: ThreadMarkNode) => {\n return $createThreadMarkNode(from.getIDs());\n },\n (from: ThreadMarkNode, to: ThreadMarkNode) => {\n const ids = from.getIDs();\n ids.forEach((id) => {\n to.addID(id);\n });\n }\n );\n }, [editor]);\n\n return (\n <OnDeleteThreadCallback.Provider value={handleThreadDelete}>\n <ActiveThreadsContext.Provider value={activeThreads}>\n <IsActiveThreadContext.Provider value={isThreadActive}>\n <ThreadToNodesContext.Provider value={threadToNodes}>\n {children}\n </ThreadToNodesContext.Provider>\n </IsActiveThreadContext.Provider>\n </ActiveThreadsContext.Provider>\n </OnDeleteThreadCallback.Provider>\n );\n}\n\n/**\n * Returns whether the associated thread annotation for the given thread id is selected or not in the editor.\n * @param threadId The id of the thread to check if the associated annotation is selected or not.\n * @returns true if the associated annotation for the thread is selected, false otherwise.\n */\nexport function useIsThreadActive(threadId: string): boolean {\n const isActive = React.useContext(IsActiveThreadContext);\n if (isActive === null) {\n throw new Error(\n \"useIsThreadActive must be used within LiveblocksPlugin. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#useIsThreadActive\"\n );\n }\n\n return isActive(threadId);\n}\n"],"names":["createContext","useLexicalComposerContext","useState","useClient","useRoom","useCallback","$getNodeByKey","$isThreadMarkNode","$unwrapThreadMarkNode","useCommentsErrorListener","CreateThreadError","getUmbrellaStoreForClient","useSyncExternalStoreWithSelector","selectRoomThreads","shallow","useEffect","addClassNamesToElement","removeClassNamesFromElement","ThreadMarkNode","$isRangeSelection","$isTextNode","$getThreadMarkIds","$getSelection","activeElements","registerNestedElementResolver","$createThreadMarkNode","React"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
2
2
  import { addClassNamesToElement, removeClassNamesFromElement, registerNestedElementResolver } from '@lexical/utils';
3
- import { kInternal, shallow } from '@liveblocks/core';
4
- import { useClient, useRoom, useCommentsErrorListener, CreateThreadError, selectedThreads } from '@liveblocks/react';
3
+ import { shallow } from '@liveblocks/core';
4
+ import { useClient, useRoom, useCommentsErrorListener, CreateThreadError, getUmbrellaStoreForClient, selectRoomThreads } from '@liveblocks/react';
5
5
  import { $getNodeByKey, $isRangeSelection, $isTextNode, $getSelection } from 'lexical';
6
6
  import * as React from 'react';
7
7
  import { createContext, useState, useCallback, useEffect } from 'react';
@@ -54,13 +54,13 @@ function CommentPluginProvider({ children }) {
54
54
  handleThreadDelete(error.context.threadId);
55
55
  }
56
56
  });
57
- const store = client[kInternal].cacheStore;
57
+ const store = getUmbrellaStoreForClient(client);
58
58
  const threads = useSyncExternalStoreWithSelector(
59
59
  store.subscribe,
60
60
  store.get,
61
61
  store.get,
62
62
  useCallback(
63
- () => selectedThreads(room.id, store.get(), {}).map((thread) => thread.id),
63
+ () => selectRoomThreads(room.id, store.get(), {}).map((thread) => thread.id),
64
64
  [room.id, store]
65
65
  ),
66
66
  shallow
@@ -139,7 +139,7 @@ function CommentPluginProvider({ children }) {
139
139
  function $onStateRead() {
140
140
  const selection = $getSelection();
141
141
  const threadIds = $getThreadIds(selection).filter((id) => {
142
- return selectedThreads(room.id, store.get(), {}).some(
142
+ return selectRoomThreads(room.id, store.get(), {}).some(
143
143
  (thread) => thread.id === id
144
144
  );
145
145
  });
@@ -1 +1 @@
1
- {"version":3,"file":"comment-plugin-provider.mjs","sources":["../../src/comments/comment-plugin-provider.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n addClassNamesToElement,\n registerNestedElementResolver,\n removeClassNamesFromElement,\n} from \"@lexical/utils\";\nimport { kInternal, shallow } from \"@liveblocks/core\";\nimport {\n CreateThreadError,\n selectedThreads,\n useClient,\n useCommentsErrorListener,\n useRoom,\n} from \"@liveblocks/react\";\nimport type { BaseSelection, NodeKey, NodeMutation } from \"lexical\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n} from \"lexical\";\nimport type { PropsWithChildren } from \"react\";\nimport * as React from \"react\";\nimport { createContext, useCallback, useEffect, useState } from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport $getThreadMarkIds from \"./get-thread-mark-ids\";\nimport {\n $createThreadMarkNode,\n $isThreadMarkNode,\n ThreadMarkNode,\n} from \"./thread-mark-node\";\nimport $unwrapThreadMarkNode from \"./unwrap-thread-mark-node\";\n\nexport const OnDeleteThreadCallback = createContext<\n ((threadId: string) => void) | null\n>(null);\n\nexport const ActiveThreadsContext = createContext<string[] | null>(null);\n\nexport const IsActiveThreadContext = createContext<\n ((threadId: string) => boolean) | null\n>(null);\n\nexport type ThreadToNodesMap = Map<string, Set<NodeKey>>;\n\nexport const ThreadToNodesContext = createContext<ThreadToNodesMap | null>(\n null\n);\n\nexport function CommentPluginProvider({ children }: PropsWithChildren) {\n const [editor, context] = useLexicalComposerContext();\n\n const [threadToNodes, setThreadToNodes] = useState<ThreadToNodesMap>(\n new Map()\n ); // A map from thread id to a set of (thread mark) node keys that are associated with the thread\n\n const [activeThreads, setActiveThreads] = useState<string[]>([]); // The threads that are currently active (or selected) in the editor\n\n const client = useClient();\n\n const room = useRoom();\n\n const isThreadActive = useCallback(\n (threadId: string) => {\n return activeThreads.includes(threadId);\n },\n [activeThreads]\n );\n\n /**\n * Remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads.\n * @param threadId The id of the thread to remove\n */\n const handleThreadDelete = useCallback(\n (threadId: string) => {\n editor.update(() => {\n // Retrieve node keys associated with the thread\n const keys = threadToNodes.get(threadId);\n if (keys === undefined) return;\n\n // Iterate over each thread node and disassociate the thread if from the node and unwrap the node if it is no longer associated with any threads\n for (const key of keys) {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n node.deleteID(threadId);\n\n if (node.getIDs().length === 0) {\n $unwrapThreadMarkNode(node);\n }\n }\n });\n },\n [editor, threadToNodes]\n );\n\n useCommentsErrorListener((error) => {\n // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n if (error instanceof CreateThreadError) {\n handleThreadDelete(error.context.threadId);\n }\n });\n\n const store = client[kInternal].cacheStore;\n\n const threads = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n useCallback(\n () =>\n selectedThreads(room.id, store.get(), {}).map((thread) => thread.id),\n [room.id, store]\n ),\n shallow\n );\n\n /**\n * Only add styles to the thread mark elements that currently have threads associated with them.\n */\n useEffect(() => {\n function getThreadMarkElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const id of threads) {\n const keys = threadToNodes.get(id);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const elements = getThreadMarkElements();\n\n const theme = context.getTheme();\n\n const classNames = [\"lb-root\", \"lb-lexical-thread-mark\"];\n if (theme && theme.liveblocks && \"threadMark\" in theme.liveblocks) {\n classNames.push((theme.liveblocks as { threadMark: string }).threadMark);\n }\n\n elements.forEach((element) => {\n addClassNamesToElement(element, ...classNames);\n });\n\n return () => {\n elements.forEach((element) => {\n removeClassNamesFromElement(element, ...classNames);\n });\n };\n }, [context, editor, threadToNodes, threads]);\n\n /**\n * Register a mutation listener that listens for mutations on 'ThreadMarkNode's and updates the map of thread to node keys accordingly.\n */\n useEffect(() => {\n function onMutation(mutations: Map<string, NodeMutation>) {\n const state = editor.getEditorState();\n setThreadToNodes((prev) => {\n const updatedMap = new Map(prev);\n state.read(() => {\n for (const [key, mutation] of mutations) {\n // If the node is destroyed, we remove its key from the map of thread to node keys\n if (mutation === \"destroyed\") {\n for (const [, nodes] of updatedMap) {\n nodes.delete(key);\n }\n }\n // Otherwise, if a new node is created or an existing node is updated, we update the map of thread to node keys to include the new/updated node\n else if (mutation === \"created\" || mutation === \"updated\") {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n\n const threadIds = node.getIDs();\n\n for (const id of threadIds) {\n const keys = updatedMap.get(id) ?? new Set();\n keys.add(key);\n updatedMap.set(id, keys);\n }\n }\n }\n });\n return updatedMap;\n });\n }\n\n return editor.registerMutationListener(ThreadMarkNode, onMutation);\n }, [editor]);\n\n /**\n * Register an update listener that listens for changes in the selection and updates the active threads accordingly.\n */\n useEffect(() => {\n function $getThreadIds(selection: BaseSelection | null): string[] {\n if (selection === null) return [];\n\n if (!$isRangeSelection(selection)) return [];\n\n const anchor = selection.anchor.getNode();\n if (!$isTextNode(anchor)) return [];\n\n return $getThreadMarkIds(anchor, selection.anchor.offset) ?? [];\n }\n\n function $onStateRead() {\n const selection = $getSelection();\n\n const threadIds = $getThreadIds(selection).filter((id) => {\n return selectedThreads(room.id, store.get(), {}).some(\n (thread) => thread.id === id\n );\n });\n setActiveThreads(threadIds);\n }\n\n const unsubscribeCache = store.subscribe(() => {\n editor.getEditorState().read($onStateRead);\n });\n\n const unregisterUpdateListener = editor.registerUpdateListener(\n ({ editorState: state }) => {\n state.read($onStateRead);\n }\n );\n\n return () => {\n unregisterUpdateListener();\n unsubscribeCache();\n };\n }, [editor, client, room.id, store]);\n\n /**\n * When active threads change, we add a data-state attribute and set it to \"active\" for all HTML elements that are associated with the active threads.\n */\n useEffect(() => {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = threadToNodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n activeElements.forEach((element) => {\n element.setAttribute(\"data-state\", \"active\");\n });\n\n return () => {\n activeElements.forEach((element) => {\n element.removeAttribute(\"data-state\");\n });\n };\n }, [activeThreads, editor, threadToNodes]);\n\n useEffect(() => {\n return registerNestedElementResolver<ThreadMarkNode>(\n editor,\n ThreadMarkNode,\n (from: ThreadMarkNode) => {\n return $createThreadMarkNode(from.getIDs());\n },\n (from: ThreadMarkNode, to: ThreadMarkNode) => {\n const ids = from.getIDs();\n ids.forEach((id) => {\n to.addID(id);\n });\n }\n );\n }, [editor]);\n\n return (\n <OnDeleteThreadCallback.Provider value={handleThreadDelete}>\n <ActiveThreadsContext.Provider value={activeThreads}>\n <IsActiveThreadContext.Provider value={isThreadActive}>\n <ThreadToNodesContext.Provider value={threadToNodes}>\n {children}\n </ThreadToNodesContext.Provider>\n </IsActiveThreadContext.Provider>\n </ActiveThreadsContext.Provider>\n </OnDeleteThreadCallback.Provider>\n );\n}\n\n/**\n * Returns whether the associated thread annotation for the given thread id is selected or not in the editor.\n * @param threadId The id of the thread to check if the associated annotation is selected or not.\n * @returns true if the associated annotation for the thread is selected, false otherwise.\n */\nexport function useIsThreadActive(threadId: string): boolean {\n const isActive = React.useContext(IsActiveThreadContext);\n if (isActive === null) {\n throw new Error(\n \"useIsThreadActive must be used within LiveblocksPlugin. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#useIsThreadActive\"\n );\n }\n\n return isActive(threadId);\n}\n"],"names":["activeElements"],"mappings":"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"}
1
+ {"version":3,"file":"comment-plugin-provider.mjs","sources":["../../src/comments/comment-plugin-provider.tsx"],"sourcesContent":["import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n addClassNamesToElement,\n registerNestedElementResolver,\n removeClassNamesFromElement,\n} from \"@lexical/utils\";\nimport { shallow } from \"@liveblocks/core\";\nimport {\n CreateThreadError,\n getUmbrellaStoreForClient,\n selectRoomThreads,\n useClient,\n useCommentsErrorListener,\n useRoom,\n} from \"@liveblocks/react\";\nimport type { BaseSelection, NodeKey, NodeMutation } from \"lexical\";\nimport {\n $getNodeByKey,\n $getSelection,\n $isRangeSelection,\n $isTextNode,\n} from \"lexical\";\nimport type { PropsWithChildren } from \"react\";\nimport * as React from \"react\";\nimport { createContext, useCallback, useEffect, useState } from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector.js\";\n\nimport $getThreadMarkIds from \"./get-thread-mark-ids\";\nimport {\n $createThreadMarkNode,\n $isThreadMarkNode,\n ThreadMarkNode,\n} from \"./thread-mark-node\";\nimport $unwrapThreadMarkNode from \"./unwrap-thread-mark-node\";\n\nexport const OnDeleteThreadCallback = createContext<\n ((threadId: string) => void) | null\n>(null);\n\nexport const ActiveThreadsContext = createContext<string[] | null>(null);\n\nexport const IsActiveThreadContext = createContext<\n ((threadId: string) => boolean) | null\n>(null);\n\nexport type ThreadToNodesMap = Map<string, Set<NodeKey>>;\n\nexport const ThreadToNodesContext = createContext<ThreadToNodesMap | null>(\n null\n);\n\nexport function CommentPluginProvider({ children }: PropsWithChildren) {\n const [editor, context] = useLexicalComposerContext();\n\n const [threadToNodes, setThreadToNodes] = useState<ThreadToNodesMap>(\n new Map()\n ); // A map from thread id to a set of (thread mark) node keys that are associated with the thread\n\n const [activeThreads, setActiveThreads] = useState<string[]>([]); // The threads that are currently active (or selected) in the editor\n\n const client = useClient();\n\n const room = useRoom();\n\n const isThreadActive = useCallback(\n (threadId: string) => {\n return activeThreads.includes(threadId);\n },\n [activeThreads]\n );\n\n /**\n * Remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads.\n * @param threadId The id of the thread to remove\n */\n const handleThreadDelete = useCallback(\n (threadId: string) => {\n editor.update(() => {\n // Retrieve node keys associated with the thread\n const keys = threadToNodes.get(threadId);\n if (keys === undefined) return;\n\n // Iterate over each thread node and disassociate the thread if from the node and unwrap the node if it is no longer associated with any threads\n for (const key of keys) {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n node.deleteID(threadId);\n\n if (node.getIDs().length === 0) {\n $unwrapThreadMarkNode(node);\n }\n }\n });\n },\n [editor, threadToNodes]\n );\n\n useCommentsErrorListener((error) => {\n // If thread creation fails, we remove the thread id from the associated nodes and unwrap the nodes if they are no longer associated with any threads\n if (error instanceof CreateThreadError) {\n handleThreadDelete(error.context.threadId);\n }\n });\n\n const store = getUmbrellaStoreForClient(client);\n\n const threads = useSyncExternalStoreWithSelector(\n store.subscribe,\n store.get,\n store.get,\n useCallback(\n () =>\n selectRoomThreads(room.id, store.get(), {}).map((thread) => thread.id),\n [room.id, store]\n ),\n shallow\n );\n\n /**\n * Only add styles to the thread mark elements that currently have threads associated with them.\n */\n useEffect(() => {\n function getThreadMarkElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const id of threads) {\n const keys = threadToNodes.get(id);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const elements = getThreadMarkElements();\n\n const theme = context.getTheme();\n\n const classNames = [\"lb-root\", \"lb-lexical-thread-mark\"];\n if (theme && theme.liveblocks && \"threadMark\" in theme.liveblocks) {\n classNames.push((theme.liveblocks as { threadMark: string }).threadMark);\n }\n\n elements.forEach((element) => {\n addClassNamesToElement(element, ...classNames);\n });\n\n return () => {\n elements.forEach((element) => {\n removeClassNamesFromElement(element, ...classNames);\n });\n };\n }, [context, editor, threadToNodes, threads]);\n\n /**\n * Register a mutation listener that listens for mutations on 'ThreadMarkNode's and updates the map of thread to node keys accordingly.\n */\n useEffect(() => {\n function onMutation(mutations: Map<string, NodeMutation>) {\n const state = editor.getEditorState();\n setThreadToNodes((prev) => {\n const updatedMap = new Map(prev);\n state.read(() => {\n for (const [key, mutation] of mutations) {\n // If the node is destroyed, we remove its key from the map of thread to node keys\n if (mutation === \"destroyed\") {\n for (const [, nodes] of updatedMap) {\n nodes.delete(key);\n }\n }\n // Otherwise, if a new node is created or an existing node is updated, we update the map of thread to node keys to include the new/updated node\n else if (mutation === \"created\" || mutation === \"updated\") {\n const node = $getNodeByKey(key);\n if (!$isThreadMarkNode(node)) continue;\n\n const threadIds = node.getIDs();\n\n for (const id of threadIds) {\n const keys = updatedMap.get(id) ?? new Set();\n keys.add(key);\n updatedMap.set(id, keys);\n }\n }\n }\n });\n return updatedMap;\n });\n }\n\n return editor.registerMutationListener(ThreadMarkNode, onMutation);\n }, [editor]);\n\n /**\n * Register an update listener that listens for changes in the selection and updates the active threads accordingly.\n */\n useEffect(() => {\n function $getThreadIds(selection: BaseSelection | null): string[] {\n if (selection === null) return [];\n\n if (!$isRangeSelection(selection)) return [];\n\n const anchor = selection.anchor.getNode();\n if (!$isTextNode(anchor)) return [];\n\n return $getThreadMarkIds(anchor, selection.anchor.offset) ?? [];\n }\n\n function $onStateRead() {\n const selection = $getSelection();\n\n const threadIds = $getThreadIds(selection).filter((id) => {\n return selectRoomThreads(room.id, store.get(), {}).some(\n (thread) => thread.id === id\n );\n });\n setActiveThreads(threadIds);\n }\n\n const unsubscribeCache = store.subscribe(() => {\n editor.getEditorState().read($onStateRead);\n });\n\n const unregisterUpdateListener = editor.registerUpdateListener(\n ({ editorState: state }) => {\n state.read($onStateRead);\n }\n );\n\n return () => {\n unregisterUpdateListener();\n unsubscribeCache();\n };\n }, [editor, client, room.id, store]);\n\n /**\n * When active threads change, we add a data-state attribute and set it to \"active\" for all HTML elements that are associated with the active threads.\n */\n useEffect(() => {\n function getActiveElements() {\n const activeElements = new Set<HTMLElement>();\n\n for (const thread of activeThreads) {\n const keys = threadToNodes.get(thread);\n if (keys === undefined) continue;\n\n for (const key of keys) {\n const element = editor.getElementByKey(key);\n if (element === null) continue;\n activeElements.add(element);\n }\n }\n return activeElements;\n }\n\n const activeElements = getActiveElements();\n\n activeElements.forEach((element) => {\n element.setAttribute(\"data-state\", \"active\");\n });\n\n return () => {\n activeElements.forEach((element) => {\n element.removeAttribute(\"data-state\");\n });\n };\n }, [activeThreads, editor, threadToNodes]);\n\n useEffect(() => {\n return registerNestedElementResolver<ThreadMarkNode>(\n editor,\n ThreadMarkNode,\n (from: ThreadMarkNode) => {\n return $createThreadMarkNode(from.getIDs());\n },\n (from: ThreadMarkNode, to: ThreadMarkNode) => {\n const ids = from.getIDs();\n ids.forEach((id) => {\n to.addID(id);\n });\n }\n );\n }, [editor]);\n\n return (\n <OnDeleteThreadCallback.Provider value={handleThreadDelete}>\n <ActiveThreadsContext.Provider value={activeThreads}>\n <IsActiveThreadContext.Provider value={isThreadActive}>\n <ThreadToNodesContext.Provider value={threadToNodes}>\n {children}\n </ThreadToNodesContext.Provider>\n </IsActiveThreadContext.Provider>\n </ActiveThreadsContext.Provider>\n </OnDeleteThreadCallback.Provider>\n );\n}\n\n/**\n * Returns whether the associated thread annotation for the given thread id is selected or not in the editor.\n * @param threadId The id of the thread to check if the associated annotation is selected or not.\n * @returns true if the associated annotation for the thread is selected, false otherwise.\n */\nexport function useIsThreadActive(threadId: string): boolean {\n const isActive = React.useContext(IsActiveThreadContext);\n if (isActive === null) {\n throw new Error(\n \"useIsThreadActive must be used within LiveblocksPlugin. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#useIsThreadActive\"\n );\n }\n\n return isActive(threadId);\n}\n"],"names":["activeElements"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"liveblocks-plugin-provider.js","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { autoUpdate, useFloating } from \"@floating-ui/react-dom\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { kInternal, nn } from \"@liveblocks/core\";\nimport { useClient, useRoom, useSelf } from \"@liveblocks/react\";\nimport { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport type { MutableRefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\n\n// TODO: Replace by ref once I understand why useRef is not stable (?!)\nconst providersMap = new Map<\n string,\n LiveblocksYjsProvider<never, never, never, never, never>\n>();\n\nexport type EditorStatus =\n /* The editor state is not loaded and has not been requested. */\n | \"not-loaded\"\n /* The editor state is loading from Liveblocks servers */\n | \"loading\"\n /**\n * Not working yet! Will be available in a future release.\n * Some editor state modifications has not been acknowledged yet by the server\n */\n | \"synchronizing\"\n /* The editor state is sync with Liveblocks servers */\n | \"synchronized\";\n\nfunction useProvider() {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return room[kInternal].onProviderUpdate.subscribe(onStoreChange);\n },\n [room]\n );\n\n const getSnapshot = useCallback(() => {\n return room[kInternal].getProvider();\n }, [room]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Get the storage status.\n *\n * - `not-loaded`: Initial state when entering the room.\n * - `loading`: Once the editor state has been requested by LiveblocksPlugin.\n * - `synchronizing`: Not working yet! Will be available in a future release.\n * - `synchronized`: The editor state is sync with Liveblocks servers.\n */\nexport function useEditorStatus(): EditorStatus {\n const provider = useProvider();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n if (provider === undefined) return () => { };\n provider.on(\"status\", onStoreChange);\n return () => {\n provider.off(\"status\", onStoreChange);\n };\n },\n [provider]\n );\n\n const getSnapshot = useCallback(() => {\n if (provider === undefined) {\n return \"not-loaded\";\n }\n return provider.getStatus();\n }, [provider]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport type LiveblocksPluginProps = {\n children?: React.ReactNode;\n};\n\n/**\n * Liveblocks plugin for Lexical that adds collaboration to your editor.\n *\n * `LiveblocksPlugin` should always be nested inside `LexicalComposer`.\n *\n * @example\n *\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const client = useClient();\n const hasResolveMentionSuggestions =\n client[kInternal].resolveMentionSuggestions !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n const previousRoomIdRef = useRef<string | null>(null);\n\n if (!editor.hasNodes([ThreadMarkNode, MentionNode])) {\n throw new Error(\n \"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig\"\n );\n }\n\n const [containerRef, setContainerRef] = useState<\n MutableRefObject<HTMLDivElement | null> | undefined\n >(undefined);\n\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n // Warn users if initialConfig.editorState, set on the composer, is not null\n useEffect(() => {\n // only in dev mode\n if (process.env.NODE_ENV !== \"production\") {\n // A user should not even be set an emptyState, but when passing null, getEditorState still has initial empty state\n if (!editor.getEditorState().isEmpty()) {\n console.warn(\n \"Warning: LiveblocksPlugin: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // we know editor is already defined as we're inside LexicalComposer, and we only want this running the first time\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n // Report that this is lexical and root is the rootKey\n room[kInternal].reportTextEditor(\"lexical\", \"root\");\n }, [room]);\n\n // Get user info or allow override from props\n const self = useSelf();\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n // Destroy previously used provider to avoid memory leaks\n // TODO: Find a way to destroy the last used provider on unmount (while working with StrictMode)\n if (\n previousRoomIdRef.current !== null &&\n previousRoomIdRef.current !== id\n ) {\n const previousProvider = providersMap.get(id);\n if (previousProvider !== undefined) {\n previousProvider.destroy();\n }\n }\n\n let doc = yjsDocMap.get(id);\n\n if (doc === undefined) {\n doc = new Doc();\n const provider = new LiveblocksYjsProvider(room, doc);\n yjsDocMap.set(id, doc);\n providersMap.set(id, provider);\n }\n\n return nn(\n providersMap.get(id),\n \"Internal error. Should never happen\"\n ) as Provider;\n },\n [room]\n );\n\n const root = useRootElement();\n\n useLayoutEffect(() => {\n if (root === null) return;\n setReference({\n getBoundingClientRect: () => root.getBoundingClientRect(),\n });\n }, [setReference, root]);\n\n const handleFloatingRef = useCallback(\n (node: HTMLDivElement) => {\n setFloating(node);\n setContainerRef({ current: node });\n },\n [setFloating, setContainerRef]\n );\n\n return (\n <>\n <div\n ref={handleFloatingRef}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n />\n\n {self && (\n <CollaborationPlugin\n // Setting the key allows us to reset the internal Y.doc used by useYjsCollaboration\n // without implementing `reload` event\n key={room.id}\n id={room.id}\n providerFactory={providerFactory}\n username={self.info?.name ?? \"\"} // use empty string to prevent random name\n cursorColor={self.info?.color as string | undefined}\n cursorsContainerRef={containerRef}\n shouldBootstrap={true}\n />\n )}\n\n {hasResolveMentionSuggestions && <MentionPlugin />}\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n\nexport function useRootElement(): HTMLElement | null {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerRootListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getRootElement();\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n"],"names":["useRoom","useCallback","kInternal","useSyncExternalStore","useClient","useLexicalComposerContext","useRef","ThreadMarkNode","MentionNode","useState","useFloating","autoUpdate","useEffect","useSelf","Doc","LiveblocksYjsProvider","nn","useLayoutEffect","CollaborationPlugin","MentionPlugin","CommentPluginProvider"],"mappings":"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"}
1
+ {"version":3,"file":"liveblocks-plugin-provider.js","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { autoUpdate, useFloating } from \"@floating-ui/react-dom\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { kInternal, nn } from \"@liveblocks/core\";\nimport { useClient, useRoom, useSelf } from \"@liveblocks/react\";\nimport { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport type { MutableRefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\n\n// TODO: Replace by ref once I understand why useRef is not stable (?!)\nconst providersMap = new Map<\n string,\n LiveblocksYjsProvider<never, never, never, never, never>\n>();\n\nexport type EditorStatus =\n /* The editor state is not loaded and has not been requested. */\n | \"not-loaded\"\n /* The editor state is loading from Liveblocks servers */\n | \"loading\"\n /**\n * Not working yet! Will be available in a future release.\n * Some editor state modifications has not been acknowledged yet by the server\n */\n | \"synchronizing\"\n /* The editor state is sync with Liveblocks servers */\n | \"synchronized\";\n\nfunction useProvider() {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return room[kInternal].onProviderUpdate.subscribe(onStoreChange);\n },\n [room]\n );\n\n const getSnapshot = useCallback(() => {\n return room[kInternal].getProvider();\n }, [room]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Get the storage status.\n *\n * - `not-loaded`: Initial state when entering the room.\n * - `loading`: Once the editor state has been requested by LiveblocksPlugin.\n * - `synchronizing`: Not working yet! Will be available in a future release.\n * - `synchronized`: The editor state is sync with Liveblocks servers.\n */\nexport function useEditorStatus(): EditorStatus {\n const provider = useProvider();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n if (provider === undefined) return () => {};\n provider.on(\"status\", onStoreChange);\n return () => {\n provider.off(\"status\", onStoreChange);\n };\n },\n [provider]\n );\n\n const getSnapshot = useCallback(() => {\n if (provider === undefined) {\n return \"not-loaded\";\n }\n return provider.getStatus();\n }, [provider]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport type LiveblocksPluginProps = {\n children?: React.ReactNode;\n};\n\n/**\n * Liveblocks plugin for Lexical that adds collaboration to your editor.\n *\n * `LiveblocksPlugin` should always be nested inside `LexicalComposer`.\n *\n * @example\n *\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const client = useClient();\n const hasResolveMentionSuggestions =\n client[kInternal].resolveMentionSuggestions !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n const previousRoomIdRef = useRef<string | null>(null);\n\n if (!editor.hasNodes([ThreadMarkNode, MentionNode])) {\n throw new Error(\n \"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig\"\n );\n }\n\n const [containerRef, setContainerRef] = useState<\n MutableRefObject<HTMLDivElement | null> | undefined\n >(undefined);\n\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n // Warn users if initialConfig.editorState, set on the composer, is not null\n useEffect(() => {\n // only in dev mode\n if (process.env.NODE_ENV !== \"production\") {\n // A user should not even be set an emptyState, but when passing null, getEditorState still has initial empty state\n if (!editor.getEditorState().isEmpty()) {\n console.warn(\n \"Warning: LiveblocksPlugin: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // we know editor is already defined as we're inside LexicalComposer, and we only want this running the first time\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n // Report that this is lexical and root is the rootKey\n room[kInternal].reportTextEditor(\"lexical\", \"root\");\n }, [room]);\n\n // Get user info or allow override from props\n const self = useSelf();\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n // Destroy previously used provider to avoid memory leaks\n // TODO: Find a way to destroy the last used provider on unmount (while working with StrictMode)\n if (\n previousRoomIdRef.current !== null &&\n previousRoomIdRef.current !== id\n ) {\n const previousProvider = providersMap.get(id);\n if (previousProvider !== undefined) {\n previousProvider.destroy();\n }\n }\n\n let doc = yjsDocMap.get(id);\n\n if (doc === undefined) {\n doc = new Doc();\n const provider = new LiveblocksYjsProvider(room, doc);\n yjsDocMap.set(id, doc);\n providersMap.set(id, provider);\n }\n\n return nn(\n providersMap.get(id),\n \"Internal error. Should never happen\"\n ) as Provider;\n },\n [room]\n );\n\n const root = useRootElement();\n\n useLayoutEffect(() => {\n if (root === null) return;\n setReference({\n getBoundingClientRect: () => root.getBoundingClientRect(),\n });\n }, [setReference, root]);\n\n const handleFloatingRef = useCallback(\n (node: HTMLDivElement) => {\n setFloating(node);\n setContainerRef({ current: node });\n },\n [setFloating, setContainerRef]\n );\n\n return (\n <>\n <div\n ref={handleFloatingRef}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n />\n\n {self && (\n <CollaborationPlugin\n // Setting the key allows us to reset the internal Y.doc used by useYjsCollaboration\n // without implementing `reload` event\n key={room.id}\n id={room.id}\n providerFactory={providerFactory}\n username={self.info?.name ?? \"\"} // use empty string to prevent random name\n cursorColor={self.info?.color as string | undefined}\n cursorsContainerRef={containerRef}\n shouldBootstrap={true}\n />\n )}\n\n {hasResolveMentionSuggestions && <MentionPlugin />}\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n\nexport function useRootElement(): HTMLElement | null {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerRootListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getRootElement();\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n"],"names":["useRoom","useCallback","kInternal","useSyncExternalStore","useClient","useLexicalComposerContext","useRef","ThreadMarkNode","MentionNode","useState","useFloating","autoUpdate","useEffect","useSelf","Doc","LiveblocksYjsProvider","nn","useLayoutEffect","CollaborationPlugin","MentionPlugin","CommentPluginProvider"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"liveblocks-plugin-provider.mjs","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { autoUpdate, useFloating } from \"@floating-ui/react-dom\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { kInternal, nn } from \"@liveblocks/core\";\nimport { useClient, useRoom, useSelf } from \"@liveblocks/react\";\nimport { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport type { MutableRefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\n\n// TODO: Replace by ref once I understand why useRef is not stable (?!)\nconst providersMap = new Map<\n string,\n LiveblocksYjsProvider<never, never, never, never, never>\n>();\n\nexport type EditorStatus =\n /* The editor state is not loaded and has not been requested. */\n | \"not-loaded\"\n /* The editor state is loading from Liveblocks servers */\n | \"loading\"\n /**\n * Not working yet! Will be available in a future release.\n * Some editor state modifications has not been acknowledged yet by the server\n */\n | \"synchronizing\"\n /* The editor state is sync with Liveblocks servers */\n | \"synchronized\";\n\nfunction useProvider() {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return room[kInternal].onProviderUpdate.subscribe(onStoreChange);\n },\n [room]\n );\n\n const getSnapshot = useCallback(() => {\n return room[kInternal].getProvider();\n }, [room]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Get the storage status.\n *\n * - `not-loaded`: Initial state when entering the room.\n * - `loading`: Once the editor state has been requested by LiveblocksPlugin.\n * - `synchronizing`: Not working yet! Will be available in a future release.\n * - `synchronized`: The editor state is sync with Liveblocks servers.\n */\nexport function useEditorStatus(): EditorStatus {\n const provider = useProvider();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n if (provider === undefined) return () => { };\n provider.on(\"status\", onStoreChange);\n return () => {\n provider.off(\"status\", onStoreChange);\n };\n },\n [provider]\n );\n\n const getSnapshot = useCallback(() => {\n if (provider === undefined) {\n return \"not-loaded\";\n }\n return provider.getStatus();\n }, [provider]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport type LiveblocksPluginProps = {\n children?: React.ReactNode;\n};\n\n/**\n * Liveblocks plugin for Lexical that adds collaboration to your editor.\n *\n * `LiveblocksPlugin` should always be nested inside `LexicalComposer`.\n *\n * @example\n *\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const client = useClient();\n const hasResolveMentionSuggestions =\n client[kInternal].resolveMentionSuggestions !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n const previousRoomIdRef = useRef<string | null>(null);\n\n if (!editor.hasNodes([ThreadMarkNode, MentionNode])) {\n throw new Error(\n \"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig\"\n );\n }\n\n const [containerRef, setContainerRef] = useState<\n MutableRefObject<HTMLDivElement | null> | undefined\n >(undefined);\n\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n // Warn users if initialConfig.editorState, set on the composer, is not null\n useEffect(() => {\n // only in dev mode\n if (process.env.NODE_ENV !== \"production\") {\n // A user should not even be set an emptyState, but when passing null, getEditorState still has initial empty state\n if (!editor.getEditorState().isEmpty()) {\n console.warn(\n \"Warning: LiveblocksPlugin: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // we know editor is already defined as we're inside LexicalComposer, and we only want this running the first time\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n // Report that this is lexical and root is the rootKey\n room[kInternal].reportTextEditor(\"lexical\", \"root\");\n }, [room]);\n\n // Get user info or allow override from props\n const self = useSelf();\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n // Destroy previously used provider to avoid memory leaks\n // TODO: Find a way to destroy the last used provider on unmount (while working with StrictMode)\n if (\n previousRoomIdRef.current !== null &&\n previousRoomIdRef.current !== id\n ) {\n const previousProvider = providersMap.get(id);\n if (previousProvider !== undefined) {\n previousProvider.destroy();\n }\n }\n\n let doc = yjsDocMap.get(id);\n\n if (doc === undefined) {\n doc = new Doc();\n const provider = new LiveblocksYjsProvider(room, doc);\n yjsDocMap.set(id, doc);\n providersMap.set(id, provider);\n }\n\n return nn(\n providersMap.get(id),\n \"Internal error. Should never happen\"\n ) as Provider;\n },\n [room]\n );\n\n const root = useRootElement();\n\n useLayoutEffect(() => {\n if (root === null) return;\n setReference({\n getBoundingClientRect: () => root.getBoundingClientRect(),\n });\n }, [setReference, root]);\n\n const handleFloatingRef = useCallback(\n (node: HTMLDivElement) => {\n setFloating(node);\n setContainerRef({ current: node });\n },\n [setFloating, setContainerRef]\n );\n\n return (\n <>\n <div\n ref={handleFloatingRef}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n />\n\n {self && (\n <CollaborationPlugin\n // Setting the key allows us to reset the internal Y.doc used by useYjsCollaboration\n // without implementing `reload` event\n key={room.id}\n id={room.id}\n providerFactory={providerFactory}\n username={self.info?.name ?? \"\"} // use empty string to prevent random name\n cursorColor={self.info?.color as string | undefined}\n cursorsContainerRef={containerRef}\n shouldBootstrap={true}\n />\n )}\n\n {hasResolveMentionSuggestions && <MentionPlugin />}\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n\nexport function useRootElement(): HTMLElement | null {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerRootListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getRootElement();\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n"],"names":["React"],"mappings":"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"}
1
+ {"version":3,"file":"liveblocks-plugin-provider.mjs","sources":["../src/liveblocks-plugin-provider.tsx"],"sourcesContent":["import { autoUpdate, useFloating } from \"@floating-ui/react-dom\";\nimport { CollaborationPlugin } from \"@lexical/react/LexicalCollaborationPlugin\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport type { Provider } from \"@lexical/yjs\";\nimport { kInternal, nn } from \"@liveblocks/core\";\nimport { useClient, useRoom, useSelf } from \"@liveblocks/react\";\nimport { LiveblocksYjsProvider } from \"@liveblocks/yjs\";\nimport type { MutableRefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport { Doc } from \"yjs\";\n\nimport { CommentPluginProvider } from \"./comments/comment-plugin-provider\";\nimport { ThreadMarkNode } from \"./comments/thread-mark-node\";\nimport { MentionNode } from \"./mentions/mention-node\";\nimport { MentionPlugin } from \"./mentions/mention-plugin\";\n\n// TODO: Replace by ref once I understand why useRef is not stable (?!)\nconst providersMap = new Map<\n string,\n LiveblocksYjsProvider<never, never, never, never, never>\n>();\n\nexport type EditorStatus =\n /* The editor state is not loaded and has not been requested. */\n | \"not-loaded\"\n /* The editor state is loading from Liveblocks servers */\n | \"loading\"\n /**\n * Not working yet! Will be available in a future release.\n * Some editor state modifications has not been acknowledged yet by the server\n */\n | \"synchronizing\"\n /* The editor state is sync with Liveblocks servers */\n | \"synchronized\";\n\nfunction useProvider() {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return room[kInternal].onProviderUpdate.subscribe(onStoreChange);\n },\n [room]\n );\n\n const getSnapshot = useCallback(() => {\n return room[kInternal].getProvider();\n }, [room]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\n/**\n * Get the storage status.\n *\n * - `not-loaded`: Initial state when entering the room.\n * - `loading`: Once the editor state has been requested by LiveblocksPlugin.\n * - `synchronizing`: Not working yet! Will be available in a future release.\n * - `synchronized`: The editor state is sync with Liveblocks servers.\n */\nexport function useEditorStatus(): EditorStatus {\n const provider = useProvider();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n if (provider === undefined) return () => {};\n provider.on(\"status\", onStoreChange);\n return () => {\n provider.off(\"status\", onStoreChange);\n };\n },\n [provider]\n );\n\n const getSnapshot = useCallback(() => {\n if (provider === undefined) {\n return \"not-loaded\";\n }\n return provider.getStatus();\n }, [provider]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n\nexport type LiveblocksPluginProps = {\n children?: React.ReactNode;\n};\n\n/**\n * Liveblocks plugin for Lexical that adds collaboration to your editor.\n *\n * `LiveblocksPlugin` should always be nested inside `LexicalComposer`.\n *\n * @example\n *\n * import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\n * import { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\n * import { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\n * import { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\n * import { liveblocksConfig, LiveblocksPlugin } from \"@liveblocks/react-lexical\";\n *\n * const initialConfig = liveblocksConfig({\n * namespace: \"MyEditor\",\n * theme: {},\n * nodes: [],\n * onError: (err) => console.error(err),\n * });\n *\n * function Editor() {\n * return (\n * <LexicalComposer initialConfig={initialConfig}>\n * <LiveblocksPlugin />\n * <RichTextPlugin\n * contentEditable={<ContentEditable />}\n * placeholder={<div>Enter some text...</div>}\n * ErrorBoundary={LexicalErrorBoundary}\n * />\n * </LexicalComposer>\n * );\n * }\n */\nexport const LiveblocksPlugin = ({\n children,\n}: LiveblocksPluginProps): JSX.Element => {\n const client = useClient();\n const hasResolveMentionSuggestions =\n client[kInternal].resolveMentionSuggestions !== undefined;\n const [editor] = useLexicalComposerContext();\n const room = useRoom();\n const previousRoomIdRef = useRef<string | null>(null);\n\n if (!editor.hasNodes([ThreadMarkNode, MentionNode])) {\n throw new Error(\n \"LiveblocksPlugin requires Lexical configuration to be wrapped in the `liveblocksConfig(options)` function. For more information: https://liveblocks.io/docs/api-reference/liveblocks-react-lexical#liveblocksConfig\"\n );\n }\n\n const [containerRef, setContainerRef] = useState<\n MutableRefObject<HTMLDivElement | null> | undefined\n >(undefined);\n\n const {\n refs: { setReference, setFloating },\n strategy,\n x,\n y,\n } = useFloating({\n strategy: \"fixed\",\n placement: \"bottom\",\n whileElementsMounted: (...args) => {\n return autoUpdate(...args, {\n animationFrame: true,\n });\n },\n });\n\n // Warn users if initialConfig.editorState, set on the composer, is not null\n useEffect(() => {\n // only in dev mode\n if (process.env.NODE_ENV !== \"production\") {\n // A user should not even be set an emptyState, but when passing null, getEditorState still has initial empty state\n if (!editor.getEditorState().isEmpty()) {\n console.warn(\n \"Warning: LiveblocksPlugin: editorState in initialConfig detected, but must be null.\"\n );\n }\n }\n\n // we know editor is already defined as we're inside LexicalComposer, and we only want this running the first time\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n // Report that this is lexical and root is the rootKey\n room[kInternal].reportTextEditor(\"lexical\", \"root\");\n }, [room]);\n\n // Get user info or allow override from props\n const self = useSelf();\n\n const providerFactory = useCallback(\n (id: string, yjsDocMap: Map<string, Doc>): Provider => {\n // Destroy previously used provider to avoid memory leaks\n // TODO: Find a way to destroy the last used provider on unmount (while working with StrictMode)\n if (\n previousRoomIdRef.current !== null &&\n previousRoomIdRef.current !== id\n ) {\n const previousProvider = providersMap.get(id);\n if (previousProvider !== undefined) {\n previousProvider.destroy();\n }\n }\n\n let doc = yjsDocMap.get(id);\n\n if (doc === undefined) {\n doc = new Doc();\n const provider = new LiveblocksYjsProvider(room, doc);\n yjsDocMap.set(id, doc);\n providersMap.set(id, provider);\n }\n\n return nn(\n providersMap.get(id),\n \"Internal error. Should never happen\"\n ) as Provider;\n },\n [room]\n );\n\n const root = useRootElement();\n\n useLayoutEffect(() => {\n if (root === null) return;\n setReference({\n getBoundingClientRect: () => root.getBoundingClientRect(),\n });\n }, [setReference, root]);\n\n const handleFloatingRef = useCallback(\n (node: HTMLDivElement) => {\n setFloating(node);\n setContainerRef({ current: node });\n },\n [setFloating, setContainerRef]\n );\n\n return (\n <>\n <div\n ref={handleFloatingRef}\n style={{\n position: strategy,\n top: 0,\n left: 0,\n transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n minWidth: \"max-content\",\n }}\n />\n\n {self && (\n <CollaborationPlugin\n // Setting the key allows us to reset the internal Y.doc used by useYjsCollaboration\n // without implementing `reload` event\n key={room.id}\n id={room.id}\n providerFactory={providerFactory}\n username={self.info?.name ?? \"\"} // use empty string to prevent random name\n cursorColor={self.info?.color as string | undefined}\n cursorsContainerRef={containerRef}\n shouldBootstrap={true}\n />\n )}\n\n {hasResolveMentionSuggestions && <MentionPlugin />}\n <CommentPluginProvider>{children}</CommentPluginProvider>\n </>\n );\n};\n\nexport function useRootElement(): HTMLElement | null {\n const [editor] = useLexicalComposerContext();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return editor.registerRootListener(onStoreChange);\n },\n [editor]\n );\n\n const getSnapshot = useCallback(() => {\n return editor.getRootElement();\n }, [editor]);\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n"],"names":["React"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"history-version-preview.js","sources":["../../src/version-history/history-version-preview.tsx"],"sourcesContent":["import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\nimport { EditorRefPlugin } from \"@lexical/react/LexicalEditorRefPlugin\";\nimport { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\nimport { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\nimport type { Binding, Provider } from \"@lexical/yjs\";\nimport {\n createBinding,\n syncLexicalUpdateToYjs,\n syncYjsChangesToLexical,\n} from \"@lexical/yjs\";\nimport type { HistoryVersion } from \"@liveblocks/core\";\nimport { useHistoryVersionData } from \"@liveblocks/react\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport {\n Button,\n List,\n RestoreIcon,\n SpinnerIcon,\n User,\n} from \"@liveblocks/react-ui/_private\";\nimport type { LexicalEditor } from \"lexical\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { Transaction, YEvent } from \"yjs\";\nimport { applyUpdate, Doc } from \"yjs\";\n\nimport { classNames } from \"../classnames\";\nimport { liveblocksConfig } from \"../liveblocks-config\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionPreviewProps\n extends ComponentPropsWithoutRef<\"div\"> {\n version: HistoryVersion;\n onVersionRestore?: (version: HistoryVersion) => void;\n}\n\nfunction createNoOpProvider(): Provider {\n const emptyFunction = () => { };\n\n return {\n awareness: {\n getLocalState: () => null,\n getStates: () => new Map(),\n off: emptyFunction,\n on: emptyFunction,\n setLocalState: emptyFunction,\n },\n connect: emptyFunction,\n disconnect: emptyFunction,\n off: emptyFunction,\n on: emptyFunction,\n };\n}\n\nfunction registerCollaborationListeners(\n editor: LexicalEditor,\n provider: Provider,\n binding: Binding\n): () => void {\n const unsubscribeUpdateListener = editor.registerUpdateListener(\n ({\n dirtyElements,\n dirtyLeaves,\n editorState,\n normalizedNodes,\n prevEditorState,\n tags,\n }) => {\n if (tags.has(\"skip-collab\") === false) {\n syncLexicalUpdateToYjs(\n binding,\n provider,\n prevEditorState,\n editorState,\n dirtyElements,\n dirtyLeaves,\n normalizedNodes,\n tags\n );\n }\n }\n );\n\n const observer = (events: Array<YEvent<any>>, transaction: Transaction) => {\n if (transaction.origin !== binding) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n syncYjsChangesToLexical(binding, provider, events, false);\n }\n };\n\n binding.root.getSharedType().observeDeep(observer);\n\n return () => {\n unsubscribeUpdateListener();\n binding.root.getSharedType().unobserveDeep(observer);\n };\n}\n\n/**\n * Displays a specific version of the current Lexical document.\n *\n * @example\n * <HistoryVersionPreview version={version} />\n */\nexport const HistoryVersionPreview = forwardRef<\n HTMLDivElement,\n HistoryVersionPreviewProps\n>(({ version, onVersionRestore, className, ...props }, forwardedRef) => {\n const [parentEditor, parentContext] = useLexicalComposerContext();\n const editor = useRef<LexicalEditor>();\n const $ = useOverrides();\n const { isLoading, data, error } = useHistoryVersionData(version.id);\n\n const initialConfig = useMemo(() => {\n const nodes = Array.from(parentEditor._nodes.values()).map((n) => n.klass);\n\n return liveblocksConfig({\n namespace: \"VersionPreview\",\n theme: parentContext.getTheme() || {},\n nodes,\n editable: false,\n onError: (err) => console.error(err),\n });\n }, [parentEditor, parentContext]);\n\n useEffect(() => {\n if (error || !data || !editor.current || !data.length) {\n return;\n }\n const doc = new Doc();\n const docMap = new Map([[version.id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(\n editor.current,\n provider,\n version.id,\n doc,\n docMap\n );\n const unsubscribe = registerCollaborationListeners(\n editor.current,\n provider,\n binding\n );\n\n try {\n applyUpdate(doc, data);\n } catch (err) {\n console.warn(err);\n }\n\n return unsubscribe;\n }, [data, version.id, isLoading, error]);\n\n const restore = useCallback(() => {\n if (!editor.current || !parentEditor) {\n return;\n }\n\n parentEditor.setEditorState(editor.current.getEditorState());\n onVersionRestore?.(version);\n }, [parentEditor, onVersionRestore, version]);\n\n return (\n <div\n {...props}\n className={classNames(\n \"lb-root lb-history-version-preview lb-lexical-version-preview\",\n className\n )}\n ref={forwardedRef}\n >\n {isLoading ? (\n <div className=\"lb-loading lb-history-version-preview-loading\">\n <SpinnerIcon />\n </div>\n ) : error ? (\n <div className=\"lb-error lb-history-version-preview-error\">\n {$.HISTORY_VERSION_PREVIEW_ERROR(error)}\n </div>\n ) : (\n <div className=\"lb-history-version-preview-content lb-lexical-editor-container lb-lexical-version-preview-editor-container\">\n <LexicalComposer initialConfig={initialConfig}>\n <EditorRefPlugin editorRef={editor} />\n <RichTextPlugin\n contentEditable={<ContentEditable />}\n placeholder={\n <div className=\"lb-empty lb-history-version-preview-empty\">\n {$.HISTORY_VERSION_PREVIEW_EMPTY}\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n </LexicalComposer>\n </div>\n )}\n <div className=\"lb-history-version-preview-footer\">\n <span className=\"lb-history-version-preview-authors\">\n {$.HISTORY_VERSION_PREVIEW_AUTHORS_LIST(\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n )}\n </span>\n <div className=\"lb-history-version-preview-actions\">\n <Button\n onClick={restore}\n disabled={!data || !parentEditor}\n variant=\"primary\"\n size=\"large\"\n className=\"lb-history-version-preview-action\"\n >\n <RestoreIcon className=\"lb-button-icon\" />\n <span className=\"lb-button-label\">\n {$.HISTORY_VERSION_PREVIEW_RESTORE}\n </span>\n </Button>\n </div>\n </div>\n </div>\n );\n});\n"],"names":["syncLexicalUpdateToYjs","syncYjsChangesToLexical","forwardRef","useLexicalComposerContext","useRef","useOverrides","useHistoryVersionData","useMemo","liveblocksConfig","useEffect","Doc","createBinding","applyUpdate","useCallback","classNames","SpinnerIcon","LexicalComposer","EditorRefPlugin","RichTextPlugin","ContentEditable","LexicalErrorBoundary","List","User","Button","RestoreIcon"],"mappings":"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"}
1
+ {"version":3,"file":"history-version-preview.js","sources":["../../src/version-history/history-version-preview.tsx"],"sourcesContent":["import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\nimport { EditorRefPlugin } from \"@lexical/react/LexicalEditorRefPlugin\";\nimport { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\nimport { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\nimport type { Binding, Provider } from \"@lexical/yjs\";\nimport {\n createBinding,\n syncLexicalUpdateToYjs,\n syncYjsChangesToLexical,\n} from \"@lexical/yjs\";\nimport type { HistoryVersion } from \"@liveblocks/core\";\nimport { useHistoryVersionData } from \"@liveblocks/react\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport {\n Button,\n List,\n RestoreIcon,\n SpinnerIcon,\n User,\n} from \"@liveblocks/react-ui/_private\";\nimport type { LexicalEditor } from \"lexical\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { Transaction, YEvent } from \"yjs\";\nimport { applyUpdate, Doc } from \"yjs\";\n\nimport { classNames } from \"../classnames\";\nimport { liveblocksConfig } from \"../liveblocks-config\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionPreviewProps\n extends ComponentPropsWithoutRef<\"div\"> {\n version: HistoryVersion;\n onVersionRestore?: (version: HistoryVersion) => void;\n}\n\nfunction createNoOpProvider(): Provider {\n const emptyFunction = () => {};\n\n return {\n awareness: {\n getLocalState: () => null,\n getStates: () => new Map(),\n off: emptyFunction,\n on: emptyFunction,\n setLocalState: emptyFunction,\n },\n connect: emptyFunction,\n disconnect: emptyFunction,\n off: emptyFunction,\n on: emptyFunction,\n };\n}\n\nfunction registerCollaborationListeners(\n editor: LexicalEditor,\n provider: Provider,\n binding: Binding\n): () => void {\n const unsubscribeUpdateListener = editor.registerUpdateListener(\n ({\n dirtyElements,\n dirtyLeaves,\n editorState,\n normalizedNodes,\n prevEditorState,\n tags,\n }) => {\n if (tags.has(\"skip-collab\") === false) {\n syncLexicalUpdateToYjs(\n binding,\n provider,\n prevEditorState,\n editorState,\n dirtyElements,\n dirtyLeaves,\n normalizedNodes,\n tags\n );\n }\n }\n );\n\n const observer = (events: Array<YEvent<any>>, transaction: Transaction) => {\n if (transaction.origin !== binding) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n syncYjsChangesToLexical(binding, provider, events, false);\n }\n };\n\n binding.root.getSharedType().observeDeep(observer);\n\n return () => {\n unsubscribeUpdateListener();\n binding.root.getSharedType().unobserveDeep(observer);\n };\n}\n\n/**\n * Displays a specific version of the current Lexical document.\n *\n * @example\n * <HistoryVersionPreview version={version} />\n */\nexport const HistoryVersionPreview = forwardRef<\n HTMLDivElement,\n HistoryVersionPreviewProps\n>(({ version, onVersionRestore, className, ...props }, forwardedRef) => {\n const [parentEditor, parentContext] = useLexicalComposerContext();\n const editor = useRef<LexicalEditor>();\n const $ = useOverrides();\n const { isLoading, data, error } = useHistoryVersionData(version.id);\n\n const initialConfig = useMemo(() => {\n const nodes = Array.from(parentEditor._nodes.values()).map((n) => n.klass);\n\n return liveblocksConfig({\n namespace: \"VersionPreview\",\n theme: parentContext.getTheme() || {},\n nodes,\n editable: false,\n onError: (err) => console.error(err),\n });\n }, [parentEditor, parentContext]);\n\n useEffect(() => {\n if (error || !data || !editor.current || !data.length) {\n return;\n }\n const doc = new Doc();\n const docMap = new Map([[version.id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(\n editor.current,\n provider,\n version.id,\n doc,\n docMap\n );\n const unsubscribe = registerCollaborationListeners(\n editor.current,\n provider,\n binding\n );\n\n try {\n applyUpdate(doc, data);\n } catch (err) {\n console.warn(err);\n }\n\n return unsubscribe;\n }, [data, version.id, isLoading, error]);\n\n const restore = useCallback(() => {\n if (!editor.current || !parentEditor) {\n return;\n }\n\n parentEditor.setEditorState(editor.current.getEditorState());\n onVersionRestore?.(version);\n }, [parentEditor, onVersionRestore, version]);\n\n return (\n <div\n {...props}\n className={classNames(\n \"lb-root lb-history-version-preview lb-lexical-version-preview\",\n className\n )}\n ref={forwardedRef}\n >\n {isLoading ? (\n <div className=\"lb-loading lb-history-version-preview-loading\">\n <SpinnerIcon />\n </div>\n ) : error ? (\n <div className=\"lb-error lb-history-version-preview-error\">\n {$.HISTORY_VERSION_PREVIEW_ERROR(error)}\n </div>\n ) : (\n <div className=\"lb-history-version-preview-content lb-lexical-editor-container lb-lexical-version-preview-editor-container\">\n <LexicalComposer initialConfig={initialConfig}>\n <EditorRefPlugin editorRef={editor} />\n <RichTextPlugin\n contentEditable={<ContentEditable />}\n placeholder={\n <div className=\"lb-empty lb-history-version-preview-empty\">\n {$.HISTORY_VERSION_PREVIEW_EMPTY}\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n </LexicalComposer>\n </div>\n )}\n <div className=\"lb-history-version-preview-footer\">\n <span className=\"lb-history-version-preview-authors\">\n {$.HISTORY_VERSION_PREVIEW_AUTHORS_LIST(\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n )}\n </span>\n <div className=\"lb-history-version-preview-actions\">\n <Button\n onClick={restore}\n disabled={!data || !parentEditor}\n variant=\"primary\"\n size=\"large\"\n className=\"lb-history-version-preview-action\"\n >\n <RestoreIcon className=\"lb-button-icon\" />\n <span className=\"lb-button-label\">\n {$.HISTORY_VERSION_PREVIEW_RESTORE}\n </span>\n </Button>\n </div>\n </div>\n </div>\n );\n});\n"],"names":["syncLexicalUpdateToYjs","syncYjsChangesToLexical","forwardRef","useLexicalComposerContext","useRef","useOverrides","useHistoryVersionData","useMemo","liveblocksConfig","useEffect","Doc","createBinding","applyUpdate","useCallback","classNames","SpinnerIcon","LexicalComposer","EditorRefPlugin","RichTextPlugin","ContentEditable","LexicalErrorBoundary","List","User","Button","RestoreIcon"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"history-version-preview.mjs","sources":["../../src/version-history/history-version-preview.tsx"],"sourcesContent":["import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\nimport { EditorRefPlugin } from \"@lexical/react/LexicalEditorRefPlugin\";\nimport { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\nimport { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\nimport type { Binding, Provider } from \"@lexical/yjs\";\nimport {\n createBinding,\n syncLexicalUpdateToYjs,\n syncYjsChangesToLexical,\n} from \"@lexical/yjs\";\nimport type { HistoryVersion } from \"@liveblocks/core\";\nimport { useHistoryVersionData } from \"@liveblocks/react\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport {\n Button,\n List,\n RestoreIcon,\n SpinnerIcon,\n User,\n} from \"@liveblocks/react-ui/_private\";\nimport type { LexicalEditor } from \"lexical\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { Transaction, YEvent } from \"yjs\";\nimport { applyUpdate, Doc } from \"yjs\";\n\nimport { classNames } from \"../classnames\";\nimport { liveblocksConfig } from \"../liveblocks-config\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionPreviewProps\n extends ComponentPropsWithoutRef<\"div\"> {\n version: HistoryVersion;\n onVersionRestore?: (version: HistoryVersion) => void;\n}\n\nfunction createNoOpProvider(): Provider {\n const emptyFunction = () => { };\n\n return {\n awareness: {\n getLocalState: () => null,\n getStates: () => new Map(),\n off: emptyFunction,\n on: emptyFunction,\n setLocalState: emptyFunction,\n },\n connect: emptyFunction,\n disconnect: emptyFunction,\n off: emptyFunction,\n on: emptyFunction,\n };\n}\n\nfunction registerCollaborationListeners(\n editor: LexicalEditor,\n provider: Provider,\n binding: Binding\n): () => void {\n const unsubscribeUpdateListener = editor.registerUpdateListener(\n ({\n dirtyElements,\n dirtyLeaves,\n editorState,\n normalizedNodes,\n prevEditorState,\n tags,\n }) => {\n if (tags.has(\"skip-collab\") === false) {\n syncLexicalUpdateToYjs(\n binding,\n provider,\n prevEditorState,\n editorState,\n dirtyElements,\n dirtyLeaves,\n normalizedNodes,\n tags\n );\n }\n }\n );\n\n const observer = (events: Array<YEvent<any>>, transaction: Transaction) => {\n if (transaction.origin !== binding) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n syncYjsChangesToLexical(binding, provider, events, false);\n }\n };\n\n binding.root.getSharedType().observeDeep(observer);\n\n return () => {\n unsubscribeUpdateListener();\n binding.root.getSharedType().unobserveDeep(observer);\n };\n}\n\n/**\n * Displays a specific version of the current Lexical document.\n *\n * @example\n * <HistoryVersionPreview version={version} />\n */\nexport const HistoryVersionPreview = forwardRef<\n HTMLDivElement,\n HistoryVersionPreviewProps\n>(({ version, onVersionRestore, className, ...props }, forwardedRef) => {\n const [parentEditor, parentContext] = useLexicalComposerContext();\n const editor = useRef<LexicalEditor>();\n const $ = useOverrides();\n const { isLoading, data, error } = useHistoryVersionData(version.id);\n\n const initialConfig = useMemo(() => {\n const nodes = Array.from(parentEditor._nodes.values()).map((n) => n.klass);\n\n return liveblocksConfig({\n namespace: \"VersionPreview\",\n theme: parentContext.getTheme() || {},\n nodes,\n editable: false,\n onError: (err) => console.error(err),\n });\n }, [parentEditor, parentContext]);\n\n useEffect(() => {\n if (error || !data || !editor.current || !data.length) {\n return;\n }\n const doc = new Doc();\n const docMap = new Map([[version.id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(\n editor.current,\n provider,\n version.id,\n doc,\n docMap\n );\n const unsubscribe = registerCollaborationListeners(\n editor.current,\n provider,\n binding\n );\n\n try {\n applyUpdate(doc, data);\n } catch (err) {\n console.warn(err);\n }\n\n return unsubscribe;\n }, [data, version.id, isLoading, error]);\n\n const restore = useCallback(() => {\n if (!editor.current || !parentEditor) {\n return;\n }\n\n parentEditor.setEditorState(editor.current.getEditorState());\n onVersionRestore?.(version);\n }, [parentEditor, onVersionRestore, version]);\n\n return (\n <div\n {...props}\n className={classNames(\n \"lb-root lb-history-version-preview lb-lexical-version-preview\",\n className\n )}\n ref={forwardedRef}\n >\n {isLoading ? (\n <div className=\"lb-loading lb-history-version-preview-loading\">\n <SpinnerIcon />\n </div>\n ) : error ? (\n <div className=\"lb-error lb-history-version-preview-error\">\n {$.HISTORY_VERSION_PREVIEW_ERROR(error)}\n </div>\n ) : (\n <div className=\"lb-history-version-preview-content lb-lexical-editor-container lb-lexical-version-preview-editor-container\">\n <LexicalComposer initialConfig={initialConfig}>\n <EditorRefPlugin editorRef={editor} />\n <RichTextPlugin\n contentEditable={<ContentEditable />}\n placeholder={\n <div className=\"lb-empty lb-history-version-preview-empty\">\n {$.HISTORY_VERSION_PREVIEW_EMPTY}\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n </LexicalComposer>\n </div>\n )}\n <div className=\"lb-history-version-preview-footer\">\n <span className=\"lb-history-version-preview-authors\">\n {$.HISTORY_VERSION_PREVIEW_AUTHORS_LIST(\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n )}\n </span>\n <div className=\"lb-history-version-preview-actions\">\n <Button\n onClick={restore}\n disabled={!data || !parentEditor}\n variant=\"primary\"\n size=\"large\"\n className=\"lb-history-version-preview-action\"\n >\n <RestoreIcon className=\"lb-button-icon\" />\n <span className=\"lb-button-label\">\n {$.HISTORY_VERSION_PREVIEW_RESTORE}\n </span>\n </Button>\n </div>\n </div>\n </div>\n );\n});\n"],"names":["React"],"mappings":";;;;;;;;;;;;;;;AAqCA,MAAM,gBAAmB,GAAA,CAAA,CAAA;AAQzB,SAAS,kBAA+B,GAAA;AACtC,EAAA,MAAM,gBAAgB,MAAM;AAAA,GAAE,CAAA;AAE9B,EAAO,OAAA;AAAA,IACL,SAAW,EAAA;AAAA,MACT,eAAe,MAAM,IAAA;AAAA,MACrB,SAAA,EAAW,sBAAM,IAAI,GAAI,EAAA;AAAA,MACzB,GAAK,EAAA,aAAA;AAAA,MACL,EAAI,EAAA,aAAA;AAAA,MACJ,aAAe,EAAA,aAAA;AAAA,KACjB;AAAA,IACA,OAAS,EAAA,aAAA;AAAA,IACT,UAAY,EAAA,aAAA;AAAA,IACZ,GAAK,EAAA,aAAA;AAAA,IACL,EAAI,EAAA,aAAA;AAAA,GACN,CAAA;AACF,CAAA;AAEA,SAAS,8BAAA,CACP,MACA,EAAA,QAAA,EACA,OACY,EAAA;AACZ,EAAA,MAAM,4BAA4B,MAAO,CAAA,sBAAA;AAAA,IACvC,CAAC;AAAA,MACC,aAAA;AAAA,MACA,WAAA;AAAA,MACA,WAAA;AAAA,MACA,eAAA;AAAA,MACA,eAAA;AAAA,MACA,IAAA;AAAA,KACI,KAAA;AACJ,MAAA,IAAI,IAAK,CAAA,GAAA,CAAI,aAAa,CAAA,KAAM,KAAO,EAAA;AACrC,QAAA,sBAAA;AAAA,UACE,OAAA;AAAA,UACA,QAAA;AAAA,UACA,eAAA;AAAA,UACA,WAAA;AAAA,UACA,aAAA;AAAA,UACA,WAAA;AAAA,UACA,eAAA;AAAA,UACA,IAAA;AAAA,SACF,CAAA;AAAA,OACF;AAAA,KACF;AAAA,GACF,CAAA;AAEA,EAAM,MAAA,QAAA,GAAW,CAAC,MAAA,EAA4B,WAA6B,KAAA;AACzE,IAAI,IAAA,WAAA,CAAY,WAAW,OAAS,EAAA;AAElC,MAAwB,uBAAA,CAAA,OAAA,EAAS,QAAU,EAAA,MAAA,EAAQ,KAAK,CAAA,CAAA;AAAA,KAC1D;AAAA,GACF,CAAA;AAEA,EAAA,OAAA,CAAQ,IAAK,CAAA,aAAA,EAAgB,CAAA,WAAA,CAAY,QAAQ,CAAA,CAAA;AAEjD,EAAA,OAAO,MAAM;AACX,IAA0B,yBAAA,EAAA,CAAA;AAC1B,IAAA,OAAA,CAAQ,IAAK,CAAA,aAAA,EAAgB,CAAA,aAAA,CAAc,QAAQ,CAAA,CAAA;AAAA,GACrD,CAAA;AACF,CAAA;AAQa,MAAA,qBAAA,GAAwB,WAGnC,CAAC,EAAE,SAAS,gBAAkB,EAAA,SAAA,EAAA,GAAc,KAAM,EAAA,EAAG,YAAiB,KAAA;AACtE,EAAA,MAAM,CAAC,YAAA,EAAc,aAAa,CAAA,GAAI,yBAA0B,EAAA,CAAA;AAChE,EAAA,MAAM,SAAS,MAAsB,EAAA,CAAA;AACrC,EAAA,MAAM,IAAI,YAAa,EAAA,CAAA;AACvB,EAAA,MAAM,EAAE,SAAW,EAAA,IAAA,EAAM,OAAU,GAAA,qBAAA,CAAsB,QAAQ,EAAE,CAAA,CAAA;AAEnE,EAAM,MAAA,aAAA,GAAgB,QAAQ,MAAM;AAClC,IAAA,MAAM,KAAQ,GAAA,KAAA,CAAM,IAAK,CAAA,YAAA,CAAa,MAAO,CAAA,MAAA,EAAQ,CAAA,CAAE,GAAI,CAAA,CAAC,CAAM,KAAA,CAAA,CAAE,KAAK,CAAA,CAAA;AAEzE,IAAA,OAAO,gBAAiB,CAAA;AAAA,MACtB,SAAW,EAAA,gBAAA;AAAA,MACX,KAAO,EAAA,aAAA,CAAc,QAAS,EAAA,IAAK,EAAC;AAAA,MACpC,KAAA;AAAA,MACA,QAAU,EAAA,KAAA;AAAA,MACV,OAAS,EAAA,CAAC,GAAQ,KAAA,OAAA,CAAQ,MAAM,GAAG,CAAA;AAAA,KACpC,CAAA,CAAA;AAAA,GACA,EAAA,CAAC,YAAc,EAAA,aAAa,CAAC,CAAA,CAAA;AAEhC,EAAA,SAAA,CAAU,MAAM;AACd,IAAI,IAAA,KAAA,IAAS,CAAC,IAAQ,IAAA,CAAC,OAAO,OAAW,IAAA,CAAC,KAAK,MAAQ,EAAA;AACrD,MAAA,OAAA;AAAA,KACF;AACA,IAAM,MAAA,GAAA,GAAM,IAAI,GAAI,EAAA,CAAA;AACpB,IAAM,MAAA,MAAA,uBAAa,GAAI,CAAA,CAAC,CAAC,OAAQ,CAAA,EAAA,EAAI,GAAG,CAAC,CAAC,CAAA,CAAA;AAC1C,IAAA,MAAM,WAAW,kBAAmB,EAAA,CAAA;AACpC,IAAA,MAAM,OAAU,GAAA,aAAA;AAAA,MACd,MAAO,CAAA,OAAA;AAAA,MACP,QAAA;AAAA,MACA,OAAQ,CAAA,EAAA;AAAA,MACR,GAAA;AAAA,MACA,MAAA;AAAA,KACF,CAAA;AACA,IAAA,MAAM,WAAc,GAAA,8BAAA;AAAA,MAClB,MAAO,CAAA,OAAA;AAAA,MACP,QAAA;AAAA,MACA,OAAA;AAAA,KACF,CAAA;AAEA,IAAI,IAAA;AACF,MAAA,WAAA,CAAY,KAAK,IAAI,CAAA,CAAA;AAAA,aACd,GAAP,EAAA;AACA,MAAA,OAAA,CAAQ,KAAK,GAAG,CAAA,CAAA;AAAA,KAClB;AAEA,IAAO,OAAA,WAAA,CAAA;AAAA,KACN,CAAC,IAAA,EAAM,QAAQ,EAAI,EAAA,SAAA,EAAW,KAAK,CAAC,CAAA,CAAA;AAEvC,EAAM,MAAA,OAAA,GAAU,YAAY,MAAM;AAChC,IAAA,IAAI,CAAC,MAAA,CAAO,OAAW,IAAA,CAAC,YAAc,EAAA;AACpC,MAAA,OAAA;AAAA,KACF;AAEA,IAAA,YAAA,CAAa,cAAe,CAAA,MAAA,CAAO,OAAQ,CAAA,cAAA,EAAgB,CAAA,CAAA;AAC3D,IAAA,gBAAA,GAAmB,OAAO,CAAA,CAAA;AAAA,GACzB,EAAA,CAAC,YAAc,EAAA,gBAAA,EAAkB,OAAO,CAAC,CAAA,CAAA;AAE5C,EAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,IACE,GAAG,KAAA;AAAA,IACJ,SAAW,EAAA,UAAA;AAAA,MACT,+DAAA;AAAA,MACA,SAAA;AAAA,KACF;AAAA,IACA,GAAK,EAAA,YAAA;AAAA,GAAA,EAEJ,4BACEA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,IAAI,SAAU,EAAA,+CAAA;AAAA,GAAA,kBACZA,cAAA,CAAA,aAAA,CAAA,WAAA,EAAA,IAAY,CACf,CAAA,GACE,wBACDA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,IAAI,SAAU,EAAA,2CAAA;AAAA,GAAA,EACZ,CAAE,CAAA,6BAAA,CAA8B,KAAK,CACxC,oBAECA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,IAAI,SAAU,EAAA,4GAAA;AAAA,GAAA,kBACZA,cAAA,CAAA,aAAA,CAAA,eAAA,EAAA;AAAA,IAAgB,aAAA;AAAA,GAAA,kBACdA,cAAA,CAAA,aAAA,CAAA,eAAA,EAAA;AAAA,IAAgB,SAAW,EAAA,MAAA;AAAA,GAAQ,mBACnCA,cAAA,CAAA,aAAA,CAAA,cAAA,EAAA;AAAA,IACC,eAAA,+CAAkB,eAAgB,EAAA,IAAA,CAAA;AAAA,IAClC,6BACGA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,MAAI,SAAU,EAAA,2CAAA;AAAA,KAAA,EACZ,EAAE,6BACL,CAAA;AAAA,IAEF,aAAe,EAAA,oBAAA;AAAA,GACjB,CACF,CACF,CAAA,kBAEDA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,IAAI,SAAU,EAAA,mCAAA;AAAA,GAAA,kBACZA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IAAK,SAAU,EAAA,oCAAA;AAAA,GAAA,EACb,CAAE,CAAA,oCAAA;AAAA,oBACAA,cAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,MACC,QAAQ,OAAQ,CAAA,OAAA,CAAQ,GAAI,CAAA,CAAC,2BAC1BA,cAAA,CAAA,aAAA,CAAA,IAAA,EAAA;AAAA,QAAK,KAAK,MAAO,CAAA,EAAA;AAAA,QAAI,QAAQ,MAAO,CAAA,EAAA;AAAA,QAAI,WAAW,EAAA,IAAA;AAAA,OAAC,CACtD,CAAA;AAAA,MACD,iBAAiB,CAAE,CAAA,oBAAA;AAAA,MACnB,QAAU,EAAA,gBAAA;AAAA,MACV,QAAQ,CAAE,CAAA,MAAA;AAAA,KACZ,CAAA;AAAA,GAEJ,mBACCA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA;AAAA,IAAI,SAAU,EAAA,oCAAA;AAAA,GAAA,kBACZA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IACC,OAAS,EAAA,OAAA;AAAA,IACT,QAAA,EAAU,CAAC,IAAA,IAAQ,CAAC,YAAA;AAAA,IACpB,OAAQ,EAAA,SAAA;AAAA,IACR,IAAK,EAAA,OAAA;AAAA,IACL,SAAU,EAAA,mCAAA;AAAA,GAAA,kBAETA,cAAA,CAAA,aAAA,CAAA,WAAA,EAAA;AAAA,IAAY,SAAU,EAAA,gBAAA;AAAA,GAAiB,mBACvCA,cAAA,CAAA,aAAA,CAAA,MAAA,EAAA;AAAA,IAAK,SAAU,EAAA,iBAAA;AAAA,GAAA,EACb,CAAE,CAAA,+BACL,CACF,CACF,CACF,CACF,CAAA,CAAA;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"history-version-preview.mjs","sources":["../../src/version-history/history-version-preview.tsx"],"sourcesContent":["import { LexicalComposer } from \"@lexical/react/LexicalComposer\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\nimport { EditorRefPlugin } from \"@lexical/react/LexicalEditorRefPlugin\";\nimport { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\nimport { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\nimport type { Binding, Provider } from \"@lexical/yjs\";\nimport {\n createBinding,\n syncLexicalUpdateToYjs,\n syncYjsChangesToLexical,\n} from \"@lexical/yjs\";\nimport type { HistoryVersion } from \"@liveblocks/core\";\nimport { useHistoryVersionData } from \"@liveblocks/react\";\nimport { useOverrides } from \"@liveblocks/react-ui\";\nimport {\n Button,\n List,\n RestoreIcon,\n SpinnerIcon,\n User,\n} from \"@liveblocks/react-ui/_private\";\nimport type { LexicalEditor } from \"lexical\";\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { Transaction, YEvent } from \"yjs\";\nimport { applyUpdate, Doc } from \"yjs\";\n\nimport { classNames } from \"../classnames\";\nimport { liveblocksConfig } from \"../liveblocks-config\";\n\nconst AUTHORS_TRUNCATE = 3;\n\nexport interface HistoryVersionPreviewProps\n extends ComponentPropsWithoutRef<\"div\"> {\n version: HistoryVersion;\n onVersionRestore?: (version: HistoryVersion) => void;\n}\n\nfunction createNoOpProvider(): Provider {\n const emptyFunction = () => {};\n\n return {\n awareness: {\n getLocalState: () => null,\n getStates: () => new Map(),\n off: emptyFunction,\n on: emptyFunction,\n setLocalState: emptyFunction,\n },\n connect: emptyFunction,\n disconnect: emptyFunction,\n off: emptyFunction,\n on: emptyFunction,\n };\n}\n\nfunction registerCollaborationListeners(\n editor: LexicalEditor,\n provider: Provider,\n binding: Binding\n): () => void {\n const unsubscribeUpdateListener = editor.registerUpdateListener(\n ({\n dirtyElements,\n dirtyLeaves,\n editorState,\n normalizedNodes,\n prevEditorState,\n tags,\n }) => {\n if (tags.has(\"skip-collab\") === false) {\n syncLexicalUpdateToYjs(\n binding,\n provider,\n prevEditorState,\n editorState,\n dirtyElements,\n dirtyLeaves,\n normalizedNodes,\n tags\n );\n }\n }\n );\n\n const observer = (events: Array<YEvent<any>>, transaction: Transaction) => {\n if (transaction.origin !== binding) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n syncYjsChangesToLexical(binding, provider, events, false);\n }\n };\n\n binding.root.getSharedType().observeDeep(observer);\n\n return () => {\n unsubscribeUpdateListener();\n binding.root.getSharedType().unobserveDeep(observer);\n };\n}\n\n/**\n * Displays a specific version of the current Lexical document.\n *\n * @example\n * <HistoryVersionPreview version={version} />\n */\nexport const HistoryVersionPreview = forwardRef<\n HTMLDivElement,\n HistoryVersionPreviewProps\n>(({ version, onVersionRestore, className, ...props }, forwardedRef) => {\n const [parentEditor, parentContext] = useLexicalComposerContext();\n const editor = useRef<LexicalEditor>();\n const $ = useOverrides();\n const { isLoading, data, error } = useHistoryVersionData(version.id);\n\n const initialConfig = useMemo(() => {\n const nodes = Array.from(parentEditor._nodes.values()).map((n) => n.klass);\n\n return liveblocksConfig({\n namespace: \"VersionPreview\",\n theme: parentContext.getTheme() || {},\n nodes,\n editable: false,\n onError: (err) => console.error(err),\n });\n }, [parentEditor, parentContext]);\n\n useEffect(() => {\n if (error || !data || !editor.current || !data.length) {\n return;\n }\n const doc = new Doc();\n const docMap = new Map([[version.id, doc]]);\n const provider = createNoOpProvider();\n const binding = createBinding(\n editor.current,\n provider,\n version.id,\n doc,\n docMap\n );\n const unsubscribe = registerCollaborationListeners(\n editor.current,\n provider,\n binding\n );\n\n try {\n applyUpdate(doc, data);\n } catch (err) {\n console.warn(err);\n }\n\n return unsubscribe;\n }, [data, version.id, isLoading, error]);\n\n const restore = useCallback(() => {\n if (!editor.current || !parentEditor) {\n return;\n }\n\n parentEditor.setEditorState(editor.current.getEditorState());\n onVersionRestore?.(version);\n }, [parentEditor, onVersionRestore, version]);\n\n return (\n <div\n {...props}\n className={classNames(\n \"lb-root lb-history-version-preview lb-lexical-version-preview\",\n className\n )}\n ref={forwardedRef}\n >\n {isLoading ? (\n <div className=\"lb-loading lb-history-version-preview-loading\">\n <SpinnerIcon />\n </div>\n ) : error ? (\n <div className=\"lb-error lb-history-version-preview-error\">\n {$.HISTORY_VERSION_PREVIEW_ERROR(error)}\n </div>\n ) : (\n <div className=\"lb-history-version-preview-content lb-lexical-editor-container lb-lexical-version-preview-editor-container\">\n <LexicalComposer initialConfig={initialConfig}>\n <EditorRefPlugin editorRef={editor} />\n <RichTextPlugin\n contentEditable={<ContentEditable />}\n placeholder={\n <div className=\"lb-empty lb-history-version-preview-empty\">\n {$.HISTORY_VERSION_PREVIEW_EMPTY}\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n </LexicalComposer>\n </div>\n )}\n <div className=\"lb-history-version-preview-footer\">\n <span className=\"lb-history-version-preview-authors\">\n {$.HISTORY_VERSION_PREVIEW_AUTHORS_LIST(\n <List\n values={version.authors.map((author) => (\n <User key={author.id} userId={author.id} replaceSelf />\n ))}\n formatRemaining={$.LIST_REMAINING_USERS}\n truncate={AUTHORS_TRUNCATE}\n locale={$.locale}\n />\n )}\n </span>\n <div className=\"lb-history-version-preview-actions\">\n <Button\n onClick={restore}\n disabled={!data || !parentEditor}\n variant=\"primary\"\n size=\"large\"\n className=\"lb-history-version-preview-action\"\n >\n <RestoreIcon className=\"lb-button-icon\" />\n <span className=\"lb-button-label\">\n {$.HISTORY_VERSION_PREVIEW_RESTORE}\n </span>\n </Button>\n </div>\n </div>\n </div>\n );\n});\n"],"names":["React"],"mappings":"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"}
package/dist/version.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const PKG_NAME = "@liveblocks/react-lexical";
4
- const PKG_VERSION = typeof "2.7.0-versions2" === "string" && "2.7.0-versions2";
4
+ const PKG_VERSION = typeof "2.7.0" === "string" && "2.7.0";
5
5
  const PKG_FORMAT = typeof "cjs" === "string" && "cjs";
6
6
 
7
7
  exports.PKG_FORMAT = PKG_FORMAT;
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-lexical\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":";;AAGO,MAAM,QAAW,GAAA,4BAAA;AACX,MAAA,WAAA,GAAc,OAAO,iBAAA,KAAgB,QAAY,IAAA,kBAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;;;"}
1
+ {"version":3,"file":"version.js","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-lexical\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":";;AAGO,MAAM,QAAW,GAAA,4BAAA;AACX,MAAA,WAAA,GAAc,OAAO,OAAA,KAAgB,QAAY,IAAA,QAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;;;"}
package/dist/version.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  const PKG_NAME = "@liveblocks/react-lexical";
2
- const PKG_VERSION = typeof "2.7.0-versions2" === "string" && "2.7.0-versions2";
2
+ const PKG_VERSION = typeof "2.7.0" === "string" && "2.7.0";
3
3
  const PKG_FORMAT = typeof "esm" === "string" && "esm";
4
4
 
5
5
  export { PKG_FORMAT, PKG_NAME, PKG_VERSION };
@@ -1 +1 @@
1
- {"version":3,"file":"version.mjs","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-lexical\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":"AAGO,MAAM,QAAW,GAAA,4BAAA;AACX,MAAA,WAAA,GAAc,OAAO,iBAAA,KAAgB,QAAY,IAAA,kBAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;"}
1
+ {"version":3,"file":"version.mjs","sources":["../src/version.ts"],"sourcesContent":["declare const __VERSION__: string;\ndeclare const ROLLUP_FORMAT: string;\n\nexport const PKG_NAME = \"@liveblocks/react-lexical\";\nexport const PKG_VERSION = typeof __VERSION__ === \"string\" && __VERSION__;\nexport const PKG_FORMAT = typeof ROLLUP_FORMAT === \"string\" && ROLLUP_FORMAT;\n"],"names":[],"mappings":"AAGO,MAAM,QAAW,GAAA,4BAAA;AACX,MAAA,WAAA,GAAc,OAAO,OAAA,KAAgB,QAAY,IAAA,QAAA;AACjD,MAAA,UAAA,GAAa,OAAO,KAAA,KAAkB,QAAY,IAAA;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liveblocks/react-lexical",
3
- "version": "2.7.0-versions2",
3
+ "version": "2.7.0",
4
4
  "description": "A lexical react plugin to enable collaboration, comments, live cursors, and more.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "commonjs",
@@ -41,12 +41,12 @@
41
41
  "test:watch": "jest --silent --verbose --color=always --watch"
42
42
  },
43
43
  "dependencies": {
44
- "@floating-ui/react-dom": "^2.1.0",
45
- "@liveblocks/client": "2.7.0-versions2",
46
- "@liveblocks/core": "2.7.0-versions2",
47
- "@liveblocks/react": "2.7.0-versions2",
48
- "@liveblocks/react-ui": "2.7.0-versions2",
49
- "@liveblocks/yjs": "2.7.0-versions2",
44
+ "@floating-ui/react-dom": "^2.1.1",
45
+ "@liveblocks/client": "2.7.0",
46
+ "@liveblocks/core": "2.7.0",
47
+ "@liveblocks/react": "2.7.0",
48
+ "@liveblocks/react-ui": "2.7.0",
49
+ "@liveblocks/yjs": "2.7.0",
50
50
  "use-sync-external-store": "^1.2.2",
51
51
  "yjs": "^13.6.18"
52
52
  },