@@ -153,95 +153,78 @@ export class MySharedDrive extends Drive implements ICollaborativeDrive {
153
153
154
154
private _onCreate = (
155
155
options : Contents . ISharedFactoryOptions ,
156
- sharedModel : YDocument < DocumentChange >
157
- ) => {
156
+ ) : YDocument < DocumentChange > => {
158
157
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 ;
160
163
}
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
- } ) ;
170
164
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 } ` ;
175
166
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
+ }
178
172
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
+ } ) ;
198
182
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 ) ;
213
211
}
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 ( ) ;
228
215
} ) ;
229
216
} ) ;
217
+ } ) ;
230
218
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 ;
245
228
} ;
246
229
247
230
private _app : JupyterFrontEnd ;
@@ -266,8 +249,7 @@ class SharedModelFactory implements ISharedModelFactory {
266
249
constructor (
267
250
private _onCreate : (
268
251
options : Contents . ISharedFactoryOptions ,
269
- sharedModel : YDocument < DocumentChange >
270
- ) => void
252
+ ) => YDocument < DocumentChange >
271
253
) {
272
254
this . documentFactories = new Map ( ) ;
273
255
}
@@ -311,10 +293,9 @@ class SharedModelFactory implements ISharedModelFactory {
311
293
// the `sharedModel` will be the default one.
312
294
return ;
313
295
}
296
+
314
297
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 ) ;
318
299
return sharedModel ;
319
300
}
320
301
0 commit comments