@@ -92,23 +92,51 @@ pub struct Folder {
9292 pub body : FolderBody ,
9393}
9494
95+ /// Result of opening a folder, including any migration update produced while initializing.
96+ pub struct FolderOpenResult {
97+ pub folder : Folder ,
98+ /// Encoded Yrs update v1 representing changes made during initialization (if any).
99+ pub update : Option < Vec < u8 > > ,
100+ }
101+
102+ pub struct FolderBodyOpenResult {
103+ pub body : FolderBody ,
104+ pub update : Option < Vec < u8 > > ,
105+ }
106+
95107impl Folder {
96- pub fn open ( mut collab : Collab , notifier : Option < FolderNotify > ) -> Result < Self , CollabError > {
97- let body = FolderBody :: open ( & mut collab, notifier) ?;
98- let folder = Folder { collab, body } ;
108+ pub fn open ( collab : Collab , notifier : Option < FolderNotify > ) -> Result < Self , CollabError > {
109+ Self :: open_with_update ( collab, notifier) . map ( |result| result. folder )
110+ }
111+
112+ pub fn open_with_update (
113+ mut collab : Collab ,
114+ notifier : Option < FolderNotify > ,
115+ ) -> Result < FolderOpenResult , CollabError > {
116+ let open_result = FolderBody :: open ( & mut collab, notifier) ?;
117+ let folder = Folder {
118+ collab,
119+ body : open_result. body ,
120+ } ;
99121 if folder. get_workspace_id ( ) . is_none ( ) {
100122 // When the folder is opened, the workspace id must be present.
101123 Err ( CollabError :: FolderMissingRequiredData (
102124 "missing workspace id" . into ( ) ,
103125 ) )
104126 } else {
105- Ok ( folder)
127+ Ok ( FolderOpenResult {
128+ folder,
129+ update : open_result. update ,
130+ } )
106131 }
107132 }
108133
109134 pub fn create ( mut collab : Collab , notifier : Option < FolderNotify > , data : FolderData ) -> Self {
110- let body = FolderBody :: open_with ( & mut collab, notifier, Some ( data) ) ;
111- Folder { collab, body }
135+ let result = FolderBody :: open_with ( & mut collab, notifier, Some ( data) ) ;
136+ Folder {
137+ collab,
138+ body : result. body ,
139+ }
112140 }
113141
114142 pub fn from_collab_doc_state (
@@ -117,11 +145,21 @@ impl Folder {
117145 workspace_id : & str ,
118146 client_id : ClientID ,
119147 ) -> Result < Self , CollabError > {
148+ Self :: from_collab_doc_state_with_update ( origin, collab_doc_state, workspace_id, client_id)
149+ . map ( |result| result. folder )
150+ }
151+
152+ pub fn from_collab_doc_state_with_update (
153+ origin : CollabOrigin ,
154+ collab_doc_state : DataSource ,
155+ workspace_id : & str ,
156+ client_id : ClientID ,
157+ ) -> Result < FolderOpenResult , CollabError > {
120158 let workspace_uuid = Uuid :: parse_str ( workspace_id)
121159 . map_err ( |_| CollabError :: Internal ( anyhow ! ( "Invalid workspace id format" ) ) ) ?;
122160 let options = CollabOptions :: new ( workspace_uuid, client_id) . with_data_source ( collab_doc_state) ;
123161 let collab = Collab :: new_with_options ( origin, options) ?;
124- Self :: open ( collab, None )
162+ Self :: open_with_update ( collab, None )
125163 }
126164
127165 pub fn close ( & self ) {
@@ -1216,7 +1254,10 @@ pub struct FolderBody {
12161254}
12171255
12181256impl FolderBody {
1219- pub fn open ( collab : & mut Collab , notifier : Option < FolderNotify > ) -> Result < Self , CollabError > {
1257+ pub fn open (
1258+ collab : & mut Collab ,
1259+ notifier : Option < FolderNotify > ,
1260+ ) -> Result < FolderBodyOpenResult , CollabError > {
12201261 CollabType :: Folder . validate_require_data ( collab) ?;
12211262 Ok ( Self :: open_with ( collab, notifier, None ) )
12221263 }
@@ -1225,7 +1266,8 @@ impl FolderBody {
12251266 collab : & mut Collab ,
12261267 notifier : Option < FolderNotify > ,
12271268 folder_data : Option < FolderData > ,
1228- ) -> Self {
1269+ ) -> FolderBodyOpenResult {
1270+ let sv = collab. transact ( ) . state_vector ( ) ;
12291271 let mut txn = collab. context . transact_mut ( ) ;
12301272 // create the folder
12311273 let root = collab. data . get_or_init_map ( & mut txn, FOLDER ) ;
@@ -1292,12 +1334,23 @@ impl FolderBody {
12921334 }
12931335 }
12941336 }
1295- Self {
1296- root,
1297- views,
1298- section,
1299- meta,
1300- notifier,
1337+ let update = {
1338+ let encoded = txn. encode_diff_v1 ( & sv) ;
1339+ if encoded. is_empty ( ) {
1340+ None
1341+ } else {
1342+ Some ( encoded)
1343+ }
1344+ } ;
1345+ FolderBodyOpenResult {
1346+ body : Self {
1347+ root,
1348+ views,
1349+ section,
1350+ meta,
1351+ notifier,
1352+ } ,
1353+ update,
13011354 }
13021355 }
13031356
@@ -1632,6 +1685,7 @@ mod tests {
16321685
16331686 use crate :: core:: collab:: default_client_id;
16341687 use crate :: core:: { collab:: CollabOptions , origin:: CollabOrigin } ;
1688+
16351689 use crate :: folder:: {
16361690 Folder , FolderData , RepeatedViewIdentifier , SectionItem , SpaceInfo , UserId , View ,
16371691 ViewIdentifier , ViewLayout , Workspace ,
0 commit comments