@@ -28,6 +28,58 @@ function setupTwoWaySync(doc1: Y.Doc, doc2: Y.Doc) {
2828}
2929
3030describe ( "RelativePositionMapping (yjs)" , ( ) => {
31+ it ( "should return the same position when no changes are made" , ( ) => {
32+ const ydoc = new Y . Doc ( ) ;
33+ const remoteYdoc = new Y . Doc ( ) ;
34+
35+ const localEditor = BlockNoteEditor . create (
36+ withCollaboration ( {
37+ collaboration : {
38+ fragment : ydoc . getXmlFragment ( "doc" ) ,
39+ user : { color : "#ff0000" , name : "Local User" } ,
40+ provider : undefined ,
41+ } ,
42+ } ) ,
43+ ) ;
44+ const div = document . createElement ( "div" ) ;
45+ localEditor . mount ( div ) ;
46+
47+ const remoteEditor = BlockNoteEditor . create (
48+ withCollaboration ( {
49+ collaboration : {
50+ fragment : remoteYdoc . getXmlFragment ( "doc" ) ,
51+ user : { color : "#ff0000" , name : "Remote User" } ,
52+ provider : undefined ,
53+ } ,
54+ } ) ,
55+ ) ;
56+
57+ const remoteDiv = document . createElement ( "div" ) ;
58+ remoteEditor . mount ( remoteDiv ) ;
59+ setupTwoWaySync ( ydoc , remoteYdoc ) ;
60+
61+ const nodeSize = localEditor . prosemirrorState . doc . nodeSize ;
62+ const positions : number [ ] = [ ] ;
63+ for ( let i = 0 ; i < nodeSize ; i ++ ) {
64+ positions . push ( trackPosition ( localEditor , i ) ( ) ) ;
65+ }
66+
67+ expect ( positions ) . toMatchInlineSnapshot ( `
68+ [
69+ 0,
70+ 1,
71+ 2,
72+ 3,
73+ 4,
74+ 5,
75+ 6,
76+ 7,
77+ ]
78+ ` ) ;
79+
80+ localEditor . unmount ( ) ;
81+ remoteEditor . unmount ( ) ;
82+ } ) ;
3183 it ( "should update the local position when collaborating" , ( ) => {
3284 const ydoc = new Y . Doc ( ) ;
3385 const remoteYdoc = new Y . Doc ( ) ;
@@ -92,6 +144,80 @@ describe("RelativePositionMapping (yjs)", () => {
92144 remoteEditor . unmount ( ) ;
93145 } ) ;
94146
147+ it ( "should match the same positions" , ( ) => {
148+ const ydoc = new Y . Doc ( ) ;
149+ const remoteYdoc = new Y . Doc ( ) ;
150+
151+ const localEditor = BlockNoteEditor . create (
152+ withCollaboration ( {
153+ collaboration : {
154+ fragment : ydoc . getXmlFragment ( "doc" ) ,
155+ user : { color : "#ff0000" , name : "Local User" } ,
156+ provider : undefined ,
157+ } ,
158+ } ) ,
159+ ) ;
160+ const div = document . createElement ( "div" ) ;
161+ localEditor . mount ( div ) ;
162+
163+ const remoteEditor = BlockNoteEditor . create (
164+ withCollaboration ( {
165+ collaboration : {
166+ fragment : remoteYdoc . getXmlFragment ( "doc" ) ,
167+ user : { color : "#ff0000" , name : "Remote User" } ,
168+ provider : undefined ,
169+ } ,
170+ } ) ,
171+ ) ;
172+
173+ const remoteDiv = document . createElement ( "div" ) ;
174+ remoteEditor . mount ( remoteDiv ) ;
175+ setupTwoWaySync ( ydoc , remoteYdoc ) ;
176+
177+ localEditor . replaceBlocks ( localEditor . document , [
178+ {
179+ type : "paragraph" ,
180+ content : "Hello World" ,
181+ } ,
182+ ] ) ;
183+
184+ const nodeSize = localEditor . prosemirrorState . doc . nodeSize ;
185+ const positions : ( ( ) => number ) [ ] = [ ] ;
186+ for ( let i = 0 ; i < nodeSize ; i ++ ) {
187+ positions . push ( trackPosition ( localEditor , i ) ) ;
188+ }
189+
190+ localEditor . _tiptapEditor . commands . insertContentAt ( 3 , "Test " ) ;
191+
192+ expect ( positions . map ( ( getPos ) => getPos ( ) ) ) . toMatchInlineSnapshot ( `
193+ [
194+ 0,
195+ 1,
196+ 2,
197+ 3,
198+ 9,
199+ 10,
200+ 11,
201+ 12,
202+ 13,
203+ 14,
204+ 15,
205+ 16,
206+ 17,
207+ 18,
208+ 19,
209+ 20,
210+ 21,
211+ 22,
212+ 23,
213+ ]
214+ ` ) ;
215+ ydoc . destroy ( ) ;
216+ remoteYdoc . destroy ( ) ;
217+ localEditor . unmount ( ) ;
218+ remoteEditor . unmount ( ) ;
219+ } ) ;
220+
95221 it ( "should handle multiple transactions when collaborating" , ( ) => {
96222 const ydoc = new Y . Doc ( ) ;
97223 const remoteYdoc = new Y . Doc ( ) ;
0 commit comments