@@ -93,6 +93,7 @@ import {
9393import { Dictionary } from "../i18n/dictionary.js" ;
9494import { en } from "../i18n/locales/index.js" ;
9595
96+ import { redo , undo } from "@tiptap/pm/history" ;
9697import {
9798 TextSelection ,
9899 type Command ,
@@ -101,8 +102,14 @@ import {
101102} from "@tiptap/pm/state" ;
102103import { dropCursor } from "prosemirror-dropcursor" ;
103104import { EditorView } from "prosemirror-view" ;
104- import { undoCommand , redoCommand , ySyncPluginKey } from "y-prosemirror" ;
105- import { undo , redo } from "@tiptap/pm/history" ;
105+ import {
106+ redoCommand ,
107+ undoCommand ,
108+ yCursorPluginKey ,
109+ ySyncPlugin ,
110+ ySyncPluginKey ,
111+ yUndoPluginKey ,
112+ } from "y-prosemirror" ;
106113import { createInternalHTMLSerializer } from "../api/exporters/html/internalHTMLSerializer.js" ;
107114import { inlineContentToNodes } from "../api/nodeConversions/blockToNode.js" ;
108115import { nodeToBlock } from "../api/nodeConversions/nodeToBlock.js" ;
@@ -113,9 +120,11 @@ import {
113120import { nestedListsToBlockNoteStructure } from "../api/parsers/html/util/nestedLists.js" ;
114121import { CodeBlockOptions } from "../blocks/CodeBlockContent/CodeBlockContent.js" ;
115122import type { ThreadStore , User } from "../comments/index.js" ;
123+ import { CursorPlugin } from "../extensions/Collaboration/CursorPlugin.js" ;
116124import "../style.css" ;
117125import { EventEmitter } from "../util/EventEmitter.js" ;
118- import { CursorPlugin } from "../extensions/Collaboration/CursorPlugin.js" ;
126+ import { SyncPlugin } from "../extensions/Collaboration/SyncPlugin.js" ;
127+ import { UndoPlugin } from "../extensions/Collaboration/UndoPlugin.js" ;
119128
120129export type BlockNoteExtensionFactory = (
121130 editor : BlockNoteEditor < any , any , any > ,
@@ -473,7 +482,7 @@ export class BlockNoteEditor<
473482
474483 private readonly showSelectionPlugin : ShowSelectionPlugin ;
475484
476- private readonly cursorPlugin : CursorPlugin ;
485+ private cursorPlugin : CursorPlugin ;
477486
478487 /**
479488 * The `uploadFile` method is what the editor uses when files need to be uploaded (for example when selecting an image to upload).
@@ -933,6 +942,46 @@ export class BlockNoteEditor<
933942 } ;
934943 }
935944
945+ private yjsState :
946+ | {
947+ prevFragment : Y . XmlFragment ;
948+ nextFragment : Y . XmlFragment ;
949+ }
950+ | undefined ;
951+
952+ public pauseYjsSync ( ) {
953+ const prevFragment = this . options . collaboration ?. fragment ;
954+
955+ if ( ! prevFragment ) {
956+ throw new Error ( "No Yjs document found" ) ;
957+ }
958+ const nextFragment = prevFragment . clone ( ) ;
959+ const doc = new Y . Doc ( ) ;
960+ nextFragment . _integrate ( doc , nextFragment . _item ! ) ;
961+
962+ this . yjsState = {
963+ prevFragment,
964+ nextFragment,
965+ } ;
966+ this . _tiptapEditor . unregisterPlugin ( yCursorPluginKey ) ;
967+ this . _tiptapEditor . unregisterPlugin ( yUndoPluginKey ) ;
968+ this . _tiptapEditor . unregisterPlugin ( ySyncPluginKey ) ;
969+ this . _tiptapEditor . registerPlugin ( ySyncPlugin ( nextFragment ) ) ;
970+ }
971+
972+ public resumeYjsSync ( ) {
973+ if ( ! this . yjsState ) {
974+ throw new Error ( "No Yjs document found" ) ;
975+ }
976+ this . _tiptapEditor . unregisterPlugin ( ySyncPluginKey ) ;
977+ this . _tiptapEditor . registerPlugin (
978+ new SyncPlugin ( this . yjsState . prevFragment ) . plugin
979+ ) ;
980+ this . cursorPlugin = new CursorPlugin ( this . options . collaboration ! ) ;
981+ this . _tiptapEditor . registerPlugin ( this . cursorPlugin . plugin ) ;
982+ this . _tiptapEditor . registerPlugin ( new UndoPlugin ( ) . plugin ) ;
983+ }
984+
936985 /**
937986 * @deprecated , use `editor.document` instead
938987 */
0 commit comments