@liveblocks/react-lexical 2.11.1 → 2.12.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.
package/dist/index.d.mts CHANGED
@@ -130,8 +130,15 @@ declare type EditorStatus = "not-loaded" | "loading"
130
130
  * - `loading`: Once the editor state has been requested by LiveblocksPlugin.
131
131
  * - `synchronizing`: Not working yet! Will be available in a future release.
132
132
  * - `synchronized`: The editor state is sync with Liveblocks servers.
133
+ *
134
+ * @deprecated Prefer `useIsEditorReady` or `useSyncStatus` (from @liveblocks/react)
133
135
  */
134
136
  declare function useEditorStatus(): EditorStatus;
137
+ /**
138
+ * Returns whether the editor has loaded the initial text contents from the
139
+ * server and is ready to be used.
140
+ */
141
+ declare function useIsEditorReady(): boolean;
135
142
  declare type LiveblocksPluginProps = {
136
143
  children?: React.ReactNode;
137
144
  };
@@ -182,4 +189,4 @@ interface HistoryVersionPreviewProps extends ComponentPropsWithoutRef<"div"> {
182
189
  */
183
190
  declare const HistoryVersionPreview: React.ForwardRefExoticComponent<HistoryVersionPreviewProps & React.RefAttributes<HTMLDivElement>>;
184
191
 
185
- export { AnchoredThreads, AnchoredThreadsProps, FloatingComposer, FloatingComposerProps, FloatingThreads, FloatingThreadsProps, HistoryVersionPreview, HistoryVersionPreviewProps, LiveblocksPlugin, OPEN_FLOATING_COMPOSER_COMMAND, liveblocksConfig, useEditorStatus, useIsThreadActive };
192
+ export { AnchoredThreads, AnchoredThreadsProps, FloatingComposer, FloatingComposerProps, FloatingThreads, FloatingThreadsProps, HistoryVersionPreview, HistoryVersionPreviewProps, LiveblocksPlugin, OPEN_FLOATING_COMPOSER_COMMAND, liveblocksConfig, useEditorStatus, useIsEditorReady, useIsThreadActive };
package/dist/index.d.ts CHANGED
@@ -130,8 +130,15 @@ declare type EditorStatus = "not-loaded" | "loading"
130
130
  * - `loading`: Once the editor state has been requested by LiveblocksPlugin.
131
131
  * - `synchronizing`: Not working yet! Will be available in a future release.
132
132
  * - `synchronized`: The editor state is sync with Liveblocks servers.
133
+ *
134
+ * @deprecated Prefer `useIsEditorReady` or `useSyncStatus` (from @liveblocks/react)
133
135
  */
134
136
  declare function useEditorStatus(): EditorStatus;
137
+ /**
138
+ * Returns whether the editor has loaded the initial text contents from the
139
+ * server and is ready to be used.
140
+ */
141
+ declare function useIsEditorReady(): boolean;
135
142
  declare type LiveblocksPluginProps = {
136
143
  children?: React.ReactNode;
137
144
  };
@@ -182,4 +189,4 @@ interface HistoryVersionPreviewProps extends ComponentPropsWithoutRef<"div"> {
182
189
  */
183
190
  declare const HistoryVersionPreview: React.ForwardRefExoticComponent<HistoryVersionPreviewProps & React.RefAttributes<HTMLDivElement>>;
184
191
 
185
- export { AnchoredThreads, AnchoredThreadsProps, FloatingComposer, FloatingComposerProps, FloatingThreads, FloatingThreadsProps, HistoryVersionPreview, HistoryVersionPreviewProps, LiveblocksPlugin, OPEN_FLOATING_COMPOSER_COMMAND, liveblocksConfig, useEditorStatus, useIsThreadActive };
192
+ export { AnchoredThreads, AnchoredThreadsProps, FloatingComposer, FloatingComposerProps, FloatingThreads, FloatingThreadsProps, HistoryVersionPreview, HistoryVersionPreviewProps, LiveblocksPlugin, OPEN_FLOATING_COMPOSER_COMMAND, liveblocksConfig, useEditorStatus, useIsEditorReady, useIsThreadActive };
package/dist/index.js CHANGED
@@ -20,5 +20,6 @@ exports.FloatingThreads = floatingThreads.FloatingThreads;
20
20
  exports.liveblocksConfig = liveblocksConfig.liveblocksConfig;
21
21
  exports.LiveblocksPlugin = liveblocksPluginProvider.LiveblocksPlugin;
22
22
  exports.useEditorStatus = liveblocksPluginProvider.useEditorStatus;
23
+ exports.useIsEditorReady = liveblocksPluginProvider.useIsEditorReady;
23
24
  exports.HistoryVersionPreview = historyVersionPreview.HistoryVersionPreview;
24
25
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type { AnchoredThreadsProps } from \"./comments/anchored-threads\";\nexport { AnchoredThreads } from \"./comments/anchored-threads\";\nexport { useIsThreadActive } from \"./comments/comment-plugin-provider\";\nexport type { FloatingComposerProps } from \"./comments/floating-composer\";\nexport {\n FloatingComposer,\n OPEN_FLOATING_COMPOSER_COMMAND,\n} from \"./comments/floating-composer\";\nexport type { FloatingThreadsProps } from \"./comments/floating-threads\";\nexport { FloatingThreads } from \"./comments/floating-threads\";\nexport { liveblocksConfig } from \"./liveblocks-config\";\nexport {\n LiveblocksPlugin,\n useEditorStatus,\n} from \"./liveblocks-plugin-provider\";\nexport type { HistoryVersionPreviewProps } from \"./version-history/history-version-preview\";\nexport { HistoryVersionPreview } from \"./version-history/history-version-preview\";\n"],"names":["detectDupes","PKG_NAME","PKG_VERSION","PKG_FORMAT"],"mappings":";;;;;;;;;;;;AAIAA,gBAAY,CAAAC,gBAAA,EAAUC,qBAAaC,kBAAU,CAAA;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type { AnchoredThreadsProps } from \"./comments/anchored-threads\";\nexport { AnchoredThreads } from \"./comments/anchored-threads\";\nexport { useIsThreadActive } from \"./comments/comment-plugin-provider\";\nexport type { FloatingComposerProps } from \"./comments/floating-composer\";\nexport {\n FloatingComposer,\n OPEN_FLOATING_COMPOSER_COMMAND,\n} from \"./comments/floating-composer\";\nexport type { FloatingThreadsProps } from \"./comments/floating-threads\";\nexport { FloatingThreads } from \"./comments/floating-threads\";\nexport { liveblocksConfig } from \"./liveblocks-config\";\nexport {\n LiveblocksPlugin,\n useEditorStatus,\n useIsEditorReady,\n} from \"./liveblocks-plugin-provider\";\nexport type { HistoryVersionPreviewProps } from \"./version-history/history-version-preview\";\nexport { HistoryVersionPreview } from \"./version-history/history-version-preview\";\n"],"names":["detectDupes","PKG_NAME","PKG_VERSION","PKG_FORMAT"],"mappings":";;;;;;;;;;;;AAIAA,gBAAY,CAAAC,gBAAA,EAAUC,qBAAaC,kBAAU,CAAA;;;;;;;;;;;;;"}
package/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ export { useIsThreadActive } from './comments/comment-plugin-provider.mjs';
5
5
  export { FloatingComposer, OPEN_FLOATING_COMPOSER_COMMAND } from './comments/floating-composer.mjs';
6
6
  export { FloatingThreads } from './comments/floating-threads.mjs';
7
7
  export { liveblocksConfig } from './liveblocks-config.mjs';
8
- export { LiveblocksPlugin, useEditorStatus } from './liveblocks-plugin-provider.mjs';
8
+ export { LiveblocksPlugin, useEditorStatus, useIsEditorReady } from './liveblocks-plugin-provider.mjs';
9
9
  export { HistoryVersionPreview } from './version-history/history-version-preview.mjs';
10
10
 
11
11
  detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type { AnchoredThreadsProps } from \"./comments/anchored-threads\";\nexport { AnchoredThreads } from \"./comments/anchored-threads\";\nexport { useIsThreadActive } from \"./comments/comment-plugin-provider\";\nexport type { FloatingComposerProps } from \"./comments/floating-composer\";\nexport {\n FloatingComposer,\n OPEN_FLOATING_COMPOSER_COMMAND,\n} from \"./comments/floating-composer\";\nexport type { FloatingThreadsProps } from \"./comments/floating-threads\";\nexport { FloatingThreads } from \"./comments/floating-threads\";\nexport { liveblocksConfig } from \"./liveblocks-config\";\nexport {\n LiveblocksPlugin,\n useEditorStatus,\n} from \"./liveblocks-plugin-provider\";\nexport type { HistoryVersionPreviewProps } from \"./version-history/history-version-preview\";\nexport { HistoryVersionPreview } from \"./version-history/history-version-preview\";\n"],"names":[],"mappings":";;;;;;;;;;AAIA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type { AnchoredThreadsProps } from \"./comments/anchored-threads\";\nexport { AnchoredThreads } from \"./comments/anchored-threads\";\nexport { useIsThreadActive } from \"./comments/comment-plugin-provider\";\nexport type { FloatingComposerProps } from \"./comments/floating-composer\";\nexport {\n FloatingComposer,\n OPEN_FLOATING_COMPOSER_COMMAND,\n} from \"./comments/floating-composer\";\nexport type { FloatingThreadsProps } from \"./comments/floating-threads\";\nexport { FloatingThreads } from \"./comments/floating-threads\";\nexport { liveblocksConfig } from \"./liveblocks-config\";\nexport {\n LiveblocksPlugin,\n useEditorStatus,\n useIsEditorReady,\n} from \"./liveblocks-plugin-provider\";\nexport type { HistoryVersionPreviewProps } from \"./version-history/history-version-preview\";\nexport { HistoryVersionPreview } from \"./version-history/history-version-preview\";\n"],"names":[],"mappings":";;;;;;;;;;AAIA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
@@ -15,21 +15,21 @@ var mentionNode = require('./mentions/mention-node.js');
15
15
  var mentionPlugin = require('./mentions/mention-plugin.js');
16
16
 
17
17
  const providersMap = /* @__PURE__ */ new Map();
18
- function useProvider() {
18
+ function useYjsProvider() {
19
19
  const room = react.useRoom();
20
20
  const subscribe = React.useCallback(
21
21
  (onStoreChange) => {
22
- return room[core.kInternal].onProviderUpdate.subscribe(onStoreChange);
22
+ return room[core.kInternal].yjsProviderDidChange.subscribe(onStoreChange);
23
23
  },
24
24
  [room]
25
25
  );
26
26
  const getSnapshot = React.useCallback(() => {
27
- return room[core.kInternal].getProvider();
27
+ return room[core.kInternal].getYjsProvider();
28
28
  }, [room]);
29
29
  return index_js.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
30
30
  }
31
31
  function useEditorStatus() {
32
- const provider = useProvider();
32
+ const provider = useYjsProvider();
33
33
  const subscribe = React.useCallback(
34
34
  (onStoreChange) => {
35
35
  if (provider === void 0)
@@ -50,6 +50,26 @@ function useEditorStatus() {
50
50
  }, [provider]);
51
51
  return index_js.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
52
52
  }
53
+ function useIsEditorReady() {
54
+ const yjsProvider = useYjsProvider();
55
+ const getSnapshot = React.useCallback(() => {
56
+ const status = yjsProvider?.getStatus();
57
+ return status === "synchronizing" || status === "synchronized";
58
+ }, [yjsProvider]);
59
+ const subscribe = React.useCallback(
60
+ (callback) => {
61
+ if (yjsProvider === void 0)
62
+ return () => {
63
+ };
64
+ yjsProvider.on("status", callback);
65
+ return () => {
66
+ yjsProvider.off("status", callback);
67
+ };
68
+ },
69
+ [yjsProvider]
70
+ );
71
+ return index_js.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
72
+ }
53
73
  const LiveblocksPlugin = ({
54
74
  children
55
75
  }) => {
@@ -163,5 +183,6 @@ function useRootElement() {
163
183
 
164
184
  exports.LiveblocksPlugin = LiveblocksPlugin;
165
185
  exports.useEditorStatus = useEditorStatus;
186
+ exports.useIsEditorReady = useIsEditorReady;
166
187
  exports.useRootElement = useRootElement;
167
188
  //# sourceMappingURL=liveblocks-plugin-provider.js.map
@@ -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, TextEditorType } 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(TextEditorType.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","TextEditorType","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, TextEditorType } 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 useYjsProvider() {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return room[kInternal].yjsProviderDidChange.subscribe(onStoreChange);\n },\n [room]\n );\n\n const getSnapshot = useCallback(() => {\n return room[kInternal].getYjsProvider();\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 *\n * @deprecated Prefer `useIsEditorReady` or `useSyncStatus` (from @liveblocks/react)\n */\nexport function useEditorStatus(): EditorStatus {\n const provider = useYjsProvider();\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\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => {};\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\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(TextEditorType.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","TextEditorType","useSelf","Doc","LiveblocksYjsProvider","nn","useLayoutEffect","CollaborationPlugin","MentionPlugin","CommentPluginProvider"],"mappings":"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"}
@@ -13,21 +13,21 @@ import { MentionNode } from './mentions/mention-node.mjs';
13
13
  import { MentionPlugin } from './mentions/mention-plugin.mjs';
14
14
 
15
15
  const providersMap = /* @__PURE__ */ new Map();
16
- function useProvider() {
16
+ function useYjsProvider() {
17
17
  const room = useRoom();
18
18
  const subscribe = useCallback(
19
19
  (onStoreChange) => {
20
- return room[kInternal].onProviderUpdate.subscribe(onStoreChange);
20
+ return room[kInternal].yjsProviderDidChange.subscribe(onStoreChange);
21
21
  },
22
22
  [room]
23
23
  );
24
24
  const getSnapshot = useCallback(() => {
25
- return room[kInternal].getProvider();
25
+ return room[kInternal].getYjsProvider();
26
26
  }, [room]);
27
27
  return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
28
28
  }
29
29
  function useEditorStatus() {
30
- const provider = useProvider();
30
+ const provider = useYjsProvider();
31
31
  const subscribe = useCallback(
32
32
  (onStoreChange) => {
33
33
  if (provider === void 0)
@@ -48,6 +48,26 @@ function useEditorStatus() {
48
48
  }, [provider]);
49
49
  return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
50
50
  }
51
+ function useIsEditorReady() {
52
+ const yjsProvider = useYjsProvider();
53
+ const getSnapshot = useCallback(() => {
54
+ const status = yjsProvider?.getStatus();
55
+ return status === "synchronizing" || status === "synchronized";
56
+ }, [yjsProvider]);
57
+ const subscribe = useCallback(
58
+ (callback) => {
59
+ if (yjsProvider === void 0)
60
+ return () => {
61
+ };
62
+ yjsProvider.on("status", callback);
63
+ return () => {
64
+ yjsProvider.off("status", callback);
65
+ };
66
+ },
67
+ [yjsProvider]
68
+ );
69
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
70
+ }
51
71
  const LiveblocksPlugin = ({
52
72
  children
53
73
  }) => {
@@ -159,5 +179,5 @@ function useRootElement() {
159
179
  return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
160
180
  }
161
181
 
162
- export { LiveblocksPlugin, useEditorStatus, useRootElement };
182
+ export { LiveblocksPlugin, useEditorStatus, useIsEditorReady, useRootElement };
163
183
  //# sourceMappingURL=liveblocks-plugin-provider.mjs.map
@@ -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, TextEditorType } 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(TextEditorType.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, TextEditorType } 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 useYjsProvider() {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => {\n return room[kInternal].yjsProviderDidChange.subscribe(onStoreChange);\n },\n [room]\n );\n\n const getSnapshot = useCallback(() => {\n return room[kInternal].getYjsProvider();\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 *\n * @deprecated Prefer `useIsEditorReady` or `useSyncStatus` (from @liveblocks/react)\n */\nexport function useEditorStatus(): EditorStatus {\n const provider = useYjsProvider();\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\n/**\n * Returns whether the editor has loaded the initial text contents from the\n * server and is ready to be used.\n */\nexport function useIsEditorReady(): boolean {\n const yjsProvider = useYjsProvider();\n\n const getSnapshot = useCallback(() => {\n const status = yjsProvider?.getStatus();\n return status === \"synchronizing\" || status === \"synchronized\";\n }, [yjsProvider]);\n\n const subscribe = useCallback(\n (callback: () => void) => {\n if (yjsProvider === undefined) return () => {};\n yjsProvider.on(\"status\", callback);\n return () => {\n yjsProvider.off(\"status\", callback);\n };\n },\n [yjsProvider]\n );\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(TextEditorType.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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"}
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.11.1" === "string" && "2.11.1";
4
+ const PKG_VERSION = typeof "2.12.0" === "string" && "2.12.0";
5
5
  const PKG_FORMAT = typeof "cjs" === "string" && "cjs";
6
6
 
7
7
  exports.PKG_FORMAT = PKG_FORMAT;
package/dist/version.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  const PKG_NAME = "@liveblocks/react-lexical";
2
- const PKG_VERSION = typeof "2.11.1" === "string" && "2.11.1";
2
+ const PKG_VERSION = typeof "2.12.0" === "string" && "2.12.0";
3
3
  const PKG_FORMAT = typeof "esm" === "string" && "esm";
4
4
 
5
5
  export { PKG_FORMAT, PKG_NAME, PKG_VERSION };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liveblocks/react-lexical",
3
- "version": "2.11.1",
3
+ "version": "2.12.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",
@@ -42,11 +42,11 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@floating-ui/react-dom": "^2.1.1",
45
- "@liveblocks/client": "2.11.1",
46
- "@liveblocks/core": "2.11.1",
47
- "@liveblocks/react": "2.11.1",
48
- "@liveblocks/react-ui": "2.11.1",
49
- "@liveblocks/yjs": "2.11.1",
45
+ "@liveblocks/client": "2.12.0",
46
+ "@liveblocks/core": "2.12.0",
47
+ "@liveblocks/react": "2.12.0",
48
+ "@liveblocks/react-ui": "2.12.0",
49
+ "@liveblocks/yjs": "2.12.0",
50
50
  "use-sync-external-store": "^1.2.2",
51
51
  "yjs": "^13.6.18"
52
52
  },