@@ -92,36 +92,73 @@ 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 (
115143 origin : CollabOrigin ,
116144 collab_doc_state : DataSource ,
117145 workspace_id : & str ,
118146 client_id : ClientID ,
119- ) -> Result < Self , CollabError > {
147+ ) -> Result < FolderOpenResult , CollabError > {
148+ Self :: from_collab_doc_state_with_update ( origin, collab_doc_state, workspace_id, client_id)
149+ }
150+
151+ pub fn from_collab_doc_state_with_update (
152+ origin : CollabOrigin ,
153+ collab_doc_state : DataSource ,
154+ workspace_id : & str ,
155+ client_id : ClientID ,
156+ ) -> Result < FolderOpenResult , CollabError > {
120157 let workspace_uuid = Uuid :: parse_str ( workspace_id)
121158 . map_err ( |_| CollabError :: Internal ( anyhow ! ( "Invalid workspace id format" ) ) ) ?;
122159 let options = CollabOptions :: new ( workspace_uuid, client_id) . with_data_source ( collab_doc_state) ;
123160 let collab = Collab :: new_with_options ( origin, options) ?;
124- Self :: open ( collab, None )
161+ Self :: open_with_update ( collab, None )
125162 }
126163
127164 pub fn close ( & self ) {
@@ -1216,7 +1253,10 @@ pub struct FolderBody {
12161253}
12171254
12181255impl FolderBody {
1219- pub fn open ( collab : & mut Collab , notifier : Option < FolderNotify > ) -> Result < Self , CollabError > {
1256+ pub fn open (
1257+ collab : & mut Collab ,
1258+ notifier : Option < FolderNotify > ,
1259+ ) -> Result < FolderBodyOpenResult , CollabError > {
12201260 CollabType :: Folder . validate_require_data ( collab) ?;
12211261 Ok ( Self :: open_with ( collab, notifier, None ) )
12221262 }
@@ -1225,7 +1265,8 @@ impl FolderBody {
12251265 collab : & mut Collab ,
12261266 notifier : Option < FolderNotify > ,
12271267 folder_data : Option < FolderData > ,
1228- ) -> Self {
1268+ ) -> FolderBodyOpenResult {
1269+ let sv = collab. transact ( ) . state_vector ( ) ;
12291270 let mut txn = collab. context . transact_mut ( ) ;
12301271 // create the folder
12311272 let root = collab. data . get_or_init_map ( & mut txn, FOLDER ) ;
@@ -1292,12 +1333,23 @@ impl FolderBody {
12921333 }
12931334 }
12941335 }
1295- Self {
1296- root,
1297- views,
1298- section,
1299- meta,
1300- notifier,
1336+ let update = {
1337+ let encoded = txn. encode_diff_v1 ( & sv) ;
1338+ if encoded. is_empty ( ) {
1339+ None
1340+ } else {
1341+ Some ( encoded)
1342+ }
1343+ } ;
1344+ FolderBodyOpenResult {
1345+ body : Self {
1346+ root,
1347+ views,
1348+ section,
1349+ meta,
1350+ notifier,
1351+ } ,
1352+ update,
13011353 }
13021354 }
13031355
@@ -1632,6 +1684,7 @@ mod tests {
16321684
16331685 use crate :: core:: collab:: default_client_id;
16341686 use crate :: core:: { collab:: CollabOptions , origin:: CollabOrigin } ;
1687+
16351688 use crate :: folder:: {
16361689 Folder , FolderData , RepeatedViewIdentifier , SectionItem , SpaceInfo , UserId , View ,
16371690 ViewIdentifier , ViewLayout , Workspace ,
0 commit comments