@@ -943,6 +943,44 @@ export class BlockNoteEditor<
943943 } ;
944944 }
945945
946+ /**
947+ * To find a fragment in another ydoc, we need to search for it.
948+ */
949+ private findTypeInOtherYdoc < T extends Y . AbstractType < any > > (
950+ ytype : T ,
951+ otherYdoc : Y . Doc
952+ ) : T {
953+ const ydoc = ytype . doc ! ;
954+ if ( ytype . _item === null ) {
955+ /**
956+ * If is a root type, we need to find the root key in the original ydoc
957+ * and use it to get the type in the other ydoc.
958+ */
959+ const rootKey = Array . from ( ydoc . share . keys ( ) ) . find (
960+ ( key ) => ydoc . share . get ( key ) === ytype
961+ ) ;
962+ if ( rootKey == null ) {
963+ throw new Error ( "type does not exist in other ydoc" ) ;
964+ }
965+ return otherYdoc . get ( rootKey , ytype . constructor as new ( ) => T ) as T ;
966+ } else {
967+ /**
968+ * If it is a sub type, we use the item id to find the history type.
969+ */
970+ const ytypeItem = ytype . _item ;
971+ const otherStructs =
972+ otherYdoc . store . clients . get ( ytypeItem . id . client ) ?? [ ] ;
973+ const itemIndex = Y . findIndexSS ( otherStructs , ytypeItem . id . clock ) ;
974+ const otherItem = otherStructs [ itemIndex ] as Y . Item ;
975+ const otherContent = otherItem . content as Y . ContentType ;
976+ return otherContent . type as T ;
977+ }
978+ }
979+
980+ public get isRemoteSyncing ( ) {
981+ return this . yjsState !== undefined ;
982+ }
983+
946984 private yjsState :
947985 | {
948986 prevFragment : Y . XmlFragment ;
@@ -951,15 +989,22 @@ export class BlockNoteEditor<
951989 | undefined ;
952990
953991 public pauseYjsSync ( ) {
992+ if ( this . isRemoteSyncing ) {
993+ return ;
994+ }
995+
954996 const prevFragment = this . options . collaboration ?. fragment ;
955997
956998 if ( ! prevFragment ) {
957999 throw new Error ( "No Yjs document found" ) ;
9581000 }
9591001
960- const nextFragment = prevFragment . clone ( ) ;
1002+ const update = Y . encodeStateAsUpdate ( prevFragment . doc ! ) ;
1003+
9611004 const doc = new Y . Doc ( ) ;
962- doc . getMap ( ) . set ( "cpy" , nextFragment ) ;
1005+ Y . applyUpdate ( doc , update ) ;
1006+
1007+ const nextFragment = this . findTypeInOtherYdoc ( prevFragment , doc ) ;
9631008
9641009 this . yjsState = {
9651010 prevFragment,
@@ -971,17 +1016,21 @@ export class BlockNoteEditor<
9711016 this . _tiptapEditor . registerPlugin ( ySyncPlugin ( nextFragment ) ) ;
9721017 }
9731018
974- public resumeYjsSync ( ) {
1019+ public resumeYjsSync ( mergeChanges = false ) {
9751020 if ( ! this . yjsState ) {
9761021 throw new Error ( "No Yjs document found" ) ;
9771022 }
9781023 this . _tiptapEditor . unregisterPlugin ( ySyncPluginKey ) ;
979- this . _tiptapEditor . registerPlugin (
980- new SyncPlugin ( this . yjsState . prevFragment ) . plugin
981- ) ;
1024+ const fragment = this . yjsState . prevFragment ;
1025+ if ( mergeChanges ) {
1026+ const update = Y . encodeStateAsUpdate ( this . yjsState . nextFragment . doc ! ) ;
1027+ Y . applyUpdate ( fragment . doc ! , update ) ;
1028+ }
1029+ this . _tiptapEditor . registerPlugin ( new SyncPlugin ( fragment ) . plugin ) ;
9821030 this . cursorPlugin = new CursorPlugin ( this . options . collaboration ! ) ;
9831031 this . _tiptapEditor . registerPlugin ( this . cursorPlugin . plugin ) ;
9841032 this . _tiptapEditor . registerPlugin ( new UndoPlugin ( ) . plugin ) ;
1033+ this . yjsState = undefined ;
9851034 }
9861035
9871036 /**
0 commit comments