@@ -153,95 +153,78 @@ export class MySharedDrive extends Drive implements ICollaborativeDrive {
153153
154154 private _onCreate = (
155155 options : Contents . ISharedFactoryOptions ,
156- sharedModel : YDocument < DocumentChange >
157- ) => {
156+ ) : YDocument < DocumentChange > => {
158157 if ( typeof options . format !== 'string' ) {
159- return ;
158+ const factory = (
159+ this . sharedModelFactory as SharedModelFactory
160+ ) . documentFactories . get ( options . contentType ) ! ;
161+ const sharedModel = factory ( options ) ;
162+ return sharedModel ;
160163 }
161- try {
162- const provider = new MyProvider ( {
163- path : options . path ,
164- format : options . format ,
165- contentType : options . contentType ,
166- model : sharedModel ,
167- user : this . _user ,
168- translator : this . _trans
169- } ) ;
170164
171- this . _app . serviceManager . contents . get ( options . path , { content : true } ) . then ( model => {
172- const content = model . format === 'base64' ? atob ( model . content ) : model . content ;
173- provider . setSource ( content ) ;
174- } ) ;
165+ const key = `${ options . format } :${ options . contentType } :${ options . path } ` ;
175166
176- const key = `${ options . format } :${ options . contentType } :${ options . path } ` ;
177- this . _providers . set ( key , provider ) ;
167+ // Check if shared model alread exists.
168+ const _provider = this . _providers . get ( key ) ;
169+ if ( _provider ) {
170+ return _provider . model ;
171+ }
178172
179- sharedModel . ydoc . on ( 'update' , ( update , origin ) => {
180- if ( origin === this ) {
181- return ;
182- }
183- this . _saveLock . promise . then ( ( ) => {
184- this . _saveLock . enable ( ) ;
185- let content = sharedModel . getSource ( ) ;
186- sharedModel . ydoc . transact ( ( ) => {
187- sharedModel . ystate . set ( 'dirty' , false ) ;
188- } , this ) ;
189- if ( options . format === 'text' && typeof content === 'object' ) {
190- content = JSON . stringify ( content ) ;
191- }
192- this . _app . serviceManager . contents . save ( options . path , { content, format : options . format , type : options . contentType } )
193- . then ( ( ) => {
194- this . _saveLock . disable ( ) ;
195- } ) ;
196- } ) ;
197- } ) ;
173+ const factory = (
174+ this . sharedModelFactory as SharedModelFactory
175+ ) . documentFactories . get ( options . contentType ) ! ;
176+ const sharedModel = factory ( options ) ;
177+ sharedModel . changed . connect ( ( _ : any , event : any ) => {
178+ if ( ! event . stateChange ) {
179+ sharedModel . ystate . set ( 'dirty' , false ) ;
180+ }
181+ } ) ;
198182
199- sharedModel . changed . connect ( async ( _ , change ) => {
200- if ( ! change . stateChange ) {
201- return ;
202- }
203- const hashChanges = change . stateChange . filter (
204- change => change . name === 'hash'
205- ) ;
206- if ( hashChanges . length === 0 ) {
207- return ;
208- }
209- if ( hashChanges . length > 1 ) {
210- console . error (
211- 'Unexpected multiple changes to hash value in a single transaction'
212- ) ;
183+ const provider = new MyProvider ( {
184+ path : options . path ,
185+ format : options . format ,
186+ contentType : options . contentType ,
187+ model : sharedModel ,
188+ user : this . _user ,
189+ translator : this . _trans
190+ } ) ;
191+
192+ this . _providers . set ( key , provider ) ;
193+
194+ this . _app . serviceManager . contents . get ( options . path , { content : true } ) . then ( model => {
195+ const content = model . format === 'base64' ? atob ( model . content ) : model . content ;
196+ provider . setSource ( content ) ;
197+ } ) ;
198+
199+ sharedModel . ydoc . on ( 'update' , ( update , origin ) => {
200+ if ( origin === this ) {
201+ return ;
202+ }
203+ this . _saveLock . promise . then ( ( ) => {
204+ this . _saveLock . enable ( ) ;
205+ let content = sharedModel . getSource ( ) ;
206+ sharedModel . ydoc . transact ( ( ) => {
207+ sharedModel . ystate . set ( 'dirty' , false ) ;
208+ } , this ) ;
209+ if ( options . format === 'text' && typeof content === 'object' ) {
210+ content = JSON . stringify ( content ) ;
213211 }
214- const hashChange = hashChanges [ 0 ] ;
215-
216- // A change in hash signifies that a save occurred on the server-side
217- // (e.g. a collaborator performed the save) - we want to notify the
218- // observers about this change so that they can store the new hash value.
219- const newPath = sharedModel . state . path ?? options . path ;
220- const model = await this . get ( newPath as string , { content : false } ) ;
221-
222- this . _ydriveFileChanged . emit ( {
223- type : 'save' ,
224- newValue : { ...model , hash : hashChange . newValue } ,
225- // we do not have the old model because it was discarded when server made the change,
226- // we only have the old hash here (which may be empty if the file was newly created!)
227- oldValue : { hash : hashChange . oldValue }
212+ this . _app . serviceManager . contents . save ( options . path , { content, format : options . format , type : options . contentType } )
213+ . then ( ( ) => {
214+ this . _saveLock . disable ( ) ;
228215 } ) ;
229216 } ) ;
217+ } ) ;
230218
231- sharedModel . disposed . connect ( ( ) => {
232- const provider = this . _providers . get ( key ) ;
233- if ( provider ) {
234- provider . dispose ( ) ;
235- this . _providers . delete ( key ) ;
236- }
237- } ) ;
238- } catch ( error ) {
239- // Falling back to the contents API if opening the websocket failed
240- // This may happen if the shared document is not a YDocument.
241- console . error (
242- `Failed to open connection for ${ options . path } .\n:${ error } `
243- ) ;
244- }
219+ sharedModel . disposed . connect ( ( ) => {
220+ const provider = this . _providers . get ( key ) ;
221+ if ( provider ) {
222+ provider . dispose ( ) ;
223+ this . _providers . delete ( key ) ;
224+ }
225+ } ) ;
226+
227+ return sharedModel ;
245228 } ;
246229
247230 private _app : JupyterFrontEnd ;
@@ -266,8 +249,7 @@ class SharedModelFactory implements ISharedModelFactory {
266249 constructor (
267250 private _onCreate : (
268251 options : Contents . ISharedFactoryOptions ,
269- sharedModel : YDocument < DocumentChange >
270- ) => void
252+ ) => YDocument < DocumentChange >
271253 ) {
272254 this . documentFactories = new Map ( ) ;
273255 }
@@ -311,10 +293,9 @@ class SharedModelFactory implements ISharedModelFactory {
311293 // the `sharedModel` will be the default one.
312294 return ;
313295 }
296+
314297 if ( this . documentFactories . has ( options . contentType ) ) {
315- const factory = this . documentFactories . get ( options . contentType ) ! ;
316- const sharedModel = factory ( options ) ;
317- this . _onCreate ( options , sharedModel ) ;
298+ const sharedModel = this . _onCreate ( options ) ;
318299 return sharedModel ;
319300 }
320301
0 commit comments