@@ -943,6 +943,44 @@ export class BlockNoteEditor<
943
943
} ;
944
944
}
945
945
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
+
946
984
private yjsState :
947
985
| {
948
986
prevFragment : Y . XmlFragment ;
@@ -951,15 +989,22 @@ export class BlockNoteEditor<
951
989
| undefined ;
952
990
953
991
public pauseYjsSync ( ) {
992
+ if ( this . isRemoteSyncing ) {
993
+ return ;
994
+ }
995
+
954
996
const prevFragment = this . options . collaboration ?. fragment ;
955
997
956
998
if ( ! prevFragment ) {
957
999
throw new Error ( "No Yjs document found" ) ;
958
1000
}
959
1001
960
- const nextFragment = prevFragment . clone ( ) ;
1002
+ const update = Y . encodeStateAsUpdate ( prevFragment . doc ! ) ;
1003
+
961
1004
const doc = new Y . Doc ( ) ;
962
- doc . getMap ( ) . set ( "cpy" , nextFragment ) ;
1005
+ Y . applyUpdate ( doc , update ) ;
1006
+
1007
+ const nextFragment = this . findTypeInOtherYdoc ( prevFragment , doc ) ;
963
1008
964
1009
this . yjsState = {
965
1010
prevFragment,
@@ -971,17 +1016,21 @@ export class BlockNoteEditor<
971
1016
this . _tiptapEditor . registerPlugin ( ySyncPlugin ( nextFragment ) ) ;
972
1017
}
973
1018
974
- public resumeYjsSync ( ) {
1019
+ public resumeYjsSync ( mergeChanges = false ) {
975
1020
if ( ! this . yjsState ) {
976
1021
throw new Error ( "No Yjs document found" ) ;
977
1022
}
978
1023
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 ) ;
982
1030
this . cursorPlugin = new CursorPlugin ( this . options . collaboration ! ) ;
983
1031
this . _tiptapEditor . registerPlugin ( this . cursorPlugin . plugin ) ;
984
1032
this . _tiptapEditor . registerPlugin ( new UndoPlugin ( ) . plugin ) ;
1033
+ this . yjsState = undefined ;
985
1034
}
986
1035
987
1036
/**
0 commit comments