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