@jupyter/docprovider 4.3.0-rc.0 → 4.4.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
- import { User } from '@jupyterlab/services';
2
- import { IDisposable } from '@lumino/disposable';
1
+ import { WebsocketProvider as YWebsocketProvider } from 'y-websocket';
3
2
  import { IAwareness } from '@jupyter/ydoc';
4
- import { WebsocketProvider } from 'y-websocket';
3
+ import { User } from '@jupyterlab/services';
4
+ import { IAwarenessProvider } from './tokens';
5
5
  export interface IContent {
6
6
  type: string;
7
7
  body: string;
@@ -12,7 +12,7 @@ export interface IContent {
12
12
  * We specify custom messages that the server can interpret. For reference please look in yjs_ws_server.
13
13
  *
14
14
  */
15
- export declare class WebSocketAwarenessProvider extends WebsocketProvider implements IDisposable {
15
+ export declare class WebSocketAwarenessProvider extends YWebsocketProvider implements IAwarenessProvider {
16
16
  /**
17
17
  * Construct a new WebSocketAwarenessProvider
18
18
  *
@@ -22,9 +22,9 @@ export declare class WebSocketAwarenessProvider extends WebsocketProvider implem
22
22
  get isDisposed(): boolean;
23
23
  dispose(): void;
24
24
  private _onUserChanged;
25
+ readonly awareness: IAwareness;
25
26
  private _isDisposed;
26
27
  private _user;
27
- private _awareness;
28
28
  }
29
29
  /**
30
30
  * A namespace for WebSocketAwarenessProvider statics.
package/lib/awareness.js CHANGED
@@ -1,15 +1,15 @@
1
- /* -----------------------------------------------------------------------------
2
- | Copyright (c) Jupyter Development Team.
3
- | Distributed under the terms of the Modified BSD License.
4
- |----------------------------------------------------------------------------*/
5
- import { WebsocketProvider } from 'y-websocket';
1
+ /*
2
+ * Copyright (c) Jupyter Development Team.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ import { WebsocketProvider as YWebsocketProvider } from 'y-websocket';
6
6
  /**
7
7
  * A class to provide Yjs synchronization over WebSocket.
8
8
  *
9
9
  * We specify custom messages that the server can interpret. For reference please look in yjs_ws_server.
10
10
  *
11
11
  */
12
- export class WebSocketAwarenessProvider extends WebsocketProvider {
12
+ export class WebSocketAwarenessProvider extends YWebsocketProvider {
13
13
  /**
14
14
  * Construct a new WebSocketAwarenessProvider
15
15
  *
@@ -20,7 +20,7 @@ export class WebSocketAwarenessProvider extends WebsocketProvider {
20
20
  awareness: options.awareness
21
21
  });
22
22
  this._isDisposed = false;
23
- this._awareness = options.awareness;
23
+ this.awareness = options.awareness;
24
24
  this._user = options.user;
25
25
  this._user.ready
26
26
  .then(() => this._onUserChanged(this._user))
@@ -39,6 +39,6 @@ export class WebSocketAwarenessProvider extends WebsocketProvider {
39
39
  this.destroy();
40
40
  }
41
41
  _onUserChanged(user) {
42
- this._awareness.setLocalStateField('user', user.identity);
42
+ this.awareness.setLocalStateField('user', user.identity);
43
43
  }
44
44
  }
package/lib/tokens.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ import { TranslationBundle } from '@jupyterlab/translation';
2
+ import { ServerConnection, User, Contents } from '@jupyterlab/services';
3
+ import { DocumentChange, YDocument, IAwareness } from '@jupyter/ydoc';
4
+ import { IDocumentProvider } from '@jupyter/collaborative-drive';
1
5
  import { Token } from '@lumino/coreutils';
2
6
  import { IDisposable } from '@lumino/disposable';
3
7
  import { ISignal } from '@lumino/signaling';
@@ -101,6 +105,119 @@ export interface IForkManager extends IDisposable {
101
105
  * Token providing a fork manager instance.
102
106
  */
103
107
  export declare const IForkManagerToken: Token<IForkManager>;
108
+ /**
109
+ * A factory for creating document providers.
110
+ */
111
+ export interface IDocumentProviderFactory {
112
+ /**
113
+ * Create a new document provider.
114
+ *
115
+ * @param options - The instantiation options for a document provider.
116
+ * @returns The document provider.
117
+ */
118
+ create(options: IDocumentProviderFactory.IOptions): IDocumentProvider & IForkProvider;
119
+ }
120
+ /**
121
+ * A namespace for IDocumentProviderFactory.
122
+ */
123
+ export declare namespace IDocumentProviderFactory {
124
+ /**
125
+ * The instantiation options for a document provider.
126
+ */
127
+ interface IOptions {
128
+ /**
129
+ * The server URL
130
+ */
131
+ url?: string;
132
+ /**
133
+ * The document file path
134
+ */
135
+ path: string;
136
+ /**
137
+ * Content type
138
+ */
139
+ contentType: string;
140
+ /**
141
+ * The source format
142
+ */
143
+ format: string;
144
+ /**
145
+ * The shared model
146
+ */
147
+ model: YDocument<DocumentChange>;
148
+ /**
149
+ * The user data
150
+ */
151
+ user: User.IManager;
152
+ /**
153
+ * The jupyterlab translator
154
+ */
155
+ translator: TranslationBundle;
156
+ /**
157
+ * The server settings.
158
+ */
159
+ serverSettings?: ServerConnection.ISettings;
160
+ /**
161
+ * The drive to use for loading and saving document content.
162
+ */
163
+ drive: Contents.IDrive;
164
+ }
165
+ }
166
+ /**
167
+ * Token providing a document provider factory instance.
168
+ */
169
+ export declare const IDocumentProviderFactory: Token<IDocumentProviderFactory>;
170
+ /**
171
+ * An interface for an awareness provider.
172
+ */
173
+ export interface IAwarenessProvider extends IDisposable {
174
+ /**
175
+ * The awareness object.
176
+ */
177
+ readonly awareness: IAwareness;
178
+ }
179
+ /**
180
+ * A factory for creating awareness providers.
181
+ */
182
+ export interface IAwarenessProviderFactory {
183
+ /**
184
+ * Create a new awareness provider.
185
+ *
186
+ * @param options - The instantiation options for an awareness provider.
187
+ * @returns The awareness provider.
188
+ */
189
+ create(options: IAwarenessProviderFactory.IOptions): IAwarenessProvider;
190
+ }
191
+ /**
192
+ * A namespace for IAwarenessProviderFactory.
193
+ */
194
+ export declare namespace IAwarenessProviderFactory {
195
+ /**
196
+ * The instantiation options for an awareness provider.
197
+ */
198
+ interface IOptions {
199
+ /**
200
+ * The room ID
201
+ */
202
+ roomID: string;
203
+ /**
204
+ * The awareness object
205
+ */
206
+ awareness: IAwareness;
207
+ /**
208
+ * The user data
209
+ */
210
+ user: User.IManager;
211
+ /**
212
+ * The server settings.
213
+ */
214
+ serverSettings: ServerConnection.ISettings;
215
+ }
216
+ }
217
+ /**
218
+ * Token providing an awareness provider factory instance.
219
+ */
220
+ export declare const IAwarenessProviderFactory: Token<IAwarenessProviderFactory>;
104
221
  export interface ISessionClosePayload {
105
222
  reason: 'unknown_session' | 'version_mismatch' | 'initialization_error';
106
223
  sessionId?: string;
package/lib/tokens.js CHANGED
@@ -7,3 +7,11 @@ import { Token } from '@lumino/coreutils';
7
7
  * Token providing a fork manager instance.
8
8
  */
9
9
  export const IForkManagerToken = new Token('@jupyter/docprovider:IForkManagerToken');
10
+ /**
11
+ * Token providing a document provider factory instance.
12
+ */
13
+ export const IDocumentProviderFactory = new Token('@jupyter/docprovider:IDocumentProviderFactory');
14
+ /**
15
+ * Token providing an awareness provider factory instance.
16
+ */
17
+ export const IAwarenessProviderFactory = new Token('@jupyter/docprovider:IAwarenessProviderFactory');
package/lib/ydrive.d.ts CHANGED
@@ -1,14 +1,17 @@
1
+ import { IDocumentManager } from '@jupyterlab/docmanager';
2
+ import { ISettingRegistry } from '@jupyterlab/settingregistry';
1
3
  import { TranslationBundle } from '@jupyterlab/translation';
2
4
  import { Contents, IContentProvider, ServerConnection, User } from '@jupyterlab/services';
3
5
  import { ISignal } from '@lumino/signaling';
4
6
  import { IDocumentProvider, ISharedModelFactory } from '@jupyter/collaborative-drive';
7
+ import { IDocumentProviderFactory } from './tokens';
5
8
  import { Awareness } from 'y-protocols/awareness';
6
- import { ISettingRegistry } from '@jupyterlab/settingregistry';
7
9
  export interface IForkProvider {
8
10
  connectToForkDoc: (forkRoomId: string, sessionId: string) => Promise<void>;
9
11
  reconnect: () => Promise<void>;
10
12
  contentType: string;
11
13
  format: string;
14
+ save?: () => Promise<void>;
12
15
  }
13
16
  declare namespace RtcContentProvider {
14
17
  interface IOptions {
@@ -16,9 +19,17 @@ declare namespace RtcContentProvider {
16
19
  trans: TranslationBundle;
17
20
  globalAwareness: Awareness | null;
18
21
  serverSettings: ServerConnection.ISettings;
19
- docmanagerSettings: ISettingRegistry.ISettings | null;
22
+ documentManager?: IDocumentManager | null;
20
23
  currentDrive: Contents.IDrive;
21
24
  fileChanged?: ISignal<Contents.IDrive, Contents.IChangedArgs>;
25
+ providerFactory: IDocumentProviderFactory;
26
+ /**
27
+ * @deprecated Pass `documentManager` instead. Used as a fallback when
28
+ * `documentManager` is not provided. Will be removed in a future major
29
+ * release.
30
+ * @see {@link IOptions.documentManager}
31
+ */
32
+ docmanagerSettings?: ISettingRegistry.ISettings | null;
22
33
  }
23
34
  }
24
35
  export declare class RtcContentProvider implements IContentProvider {
@@ -55,7 +66,6 @@ export declare class RtcContentProvider implements IContentProvider {
55
66
  get fileChanged(): ISignal<this, Contents.IChangedArgs>;
56
67
  private _onCreate;
57
68
  private _user;
58
- private _saveCounter;
59
69
  private _currentDrive;
60
70
  private _trans;
61
71
  private _globalAwareness;
@@ -63,6 +73,8 @@ export declare class RtcContentProvider implements IContentProvider {
63
73
  private _providerFileChanged;
64
74
  private _driveFileChanged?;
65
75
  private _serverSettings;
76
+ private _documentManager;
66
77
  private _docmanagerSettings;
78
+ private _providerFactory;
67
79
  }
68
80
  export {};
package/lib/ydrive.js CHANGED
@@ -1,45 +1,67 @@
1
1
  // Copyright (c) Jupyter Development Team.
2
2
  // Distributed under the terms of the Modified BSD License.
3
3
  import { PageConfig } from '@jupyterlab/coreutils';
4
- import { PromiseDelegate } from '@lumino/coreutils';
5
4
  import { Signal } from '@lumino/signaling';
6
- import { WebSocketProvider } from './yprovider';
7
- import * as decoding from 'lib0/decoding';
8
- import * as encoding from 'lib0/encoding';
9
5
  const DISABLE_RTC = PageConfig.getOption('disableRTC') === 'true' ? true : false;
10
- const RAW_MESSAGE_TYPE = 2;
11
6
  export class RtcContentProvider {
12
7
  constructor(options) {
8
+ var _a, _b;
13
9
  this._onCreate = (options, sharedModel) => {
14
- var _a, _b, _c, _d, _e, _f, _g;
10
+ var _a, _b, _c;
15
11
  if (typeof options.format !== 'string') {
16
12
  return;
17
13
  }
18
14
  // Set initial autosave value, used to determine backend autosave (default: true)
19
- const autosave = (_c = (_b = (_a = this._docmanagerSettings) === null || _a === void 0 ? void 0 : _a.composite) === null || _b === void 0 ? void 0 : _b['autosave']) !== null && _c !== void 0 ? _c : true;
20
- sharedModel.awareness.setLocalStateField('autosave', autosave);
21
- // Watch for changes in settings
22
- (_d = this._docmanagerSettings) === null || _d === void 0 ? void 0 : _d.changed.connect(() => {
23
- var _a, _b, _c;
24
- const newAutosave = (_c = (_b = (_a = this._docmanagerSettings) === null || _a === void 0 ? void 0 : _a.composite) === null || _b === void 0 ? void 0 : _b['autosave']) !== null && _c !== void 0 ? _c : true;
25
- sharedModel.awareness.setLocalStateField('autosave', newAutosave);
26
- });
15
+ const getAutosave = () => {
16
+ var _a, _b, _c, _d;
17
+ if (this._documentManager) {
18
+ return (_a = this._documentManager.autosave) !== null && _a !== void 0 ? _a : true;
19
+ }
20
+ return ((_d = (_c = (_b = this._docmanagerSettings) === null || _b === void 0 ? void 0 : _b.composite) === null || _c === void 0 ? void 0 : _c['autosave']) !== null && _d !== void 0 ? _d : true);
21
+ };
22
+ sharedModel.awareness.setLocalStateField('autosave', getAutosave());
23
+ if (this._documentManager) {
24
+ // Watch for autosave changes on the document manager.
25
+ const handleStateChanged = (_, args) => {
26
+ if (args.name === 'autosave') {
27
+ sharedModel.awareness.setLocalStateField('autosave', getAutosave());
28
+ }
29
+ };
30
+ this._documentManager.stateChanged.connect(handleStateChanged);
31
+ sharedModel.disposed.connect(() => {
32
+ var _a;
33
+ (_a = this._documentManager) === null || _a === void 0 ? void 0 : _a.stateChanged.disconnect(handleStateChanged);
34
+ });
35
+ }
36
+ else if (this._docmanagerSettings) {
37
+ // Fall back to watching the deprecated docmanager settings.
38
+ const handleSettingsChanged = () => {
39
+ sharedModel.awareness.setLocalStateField('autosave', getAutosave());
40
+ };
41
+ this._docmanagerSettings.changed.connect(handleSettingsChanged);
42
+ sharedModel.disposed.connect(() => {
43
+ var _a;
44
+ (_a = this._docmanagerSettings) === null || _a === void 0 ? void 0 : _a.changed.disconnect(handleSettingsChanged);
45
+ });
46
+ }
27
47
  try {
28
- const provider = new WebSocketProvider({
48
+ const providerOptions = {
29
49
  path: options.path,
30
50
  format: options.format,
31
51
  contentType: options.contentType,
32
52
  model: sharedModel,
33
53
  user: this._user,
34
54
  translator: this._trans,
35
- serverSettings: this._serverSettings
36
- });
55
+ serverSettings: this._serverSettings,
56
+ drive: this._currentDrive
57
+ };
58
+ const provider = this._providerFactory.create(providerOptions);
37
59
  // Add the document path in the list of opened ones for this user.
38
- const state = ((_e = this._globalAwareness) === null || _e === void 0 ? void 0 : _e.getLocalState()) || {};
60
+ const state = ((_a = this._globalAwareness) === null || _a === void 0 ? void 0 : _a.getLocalState()) || {};
39
61
  const documents = state.documents || [];
40
62
  if (!documents.includes(options.path)) {
41
63
  documents.push(options.path);
42
- (_f = this._globalAwareness) === null || _f === void 0 ? void 0 : _f.setLocalStateField('documents', documents);
64
+ (_b = this._globalAwareness) === null || _b === void 0 ? void 0 : _b.setLocalStateField('documents', documents);
43
65
  }
44
66
  let path = options.path;
45
67
  let key = `${options.format}:${options.contentType}:${path}`;
@@ -105,7 +127,7 @@ export class RtcContentProvider {
105
127
  name: 'path'
106
128
  });
107
129
  };
108
- (_g = this._driveFileChanged) === null || _g === void 0 ? void 0 : _g.connect(handleFileChangedSignal);
130
+ (_c = this._driveFileChanged) === null || _c === void 0 ? void 0 : _c.connect(handleFileChangedSignal);
109
131
  sharedModel.changed.connect(async (_, change) => {
110
132
  var _a;
111
133
  if (!change.stateChange) {
@@ -161,7 +183,6 @@ export class RtcContentProvider {
161
183
  console.error(`Failed to open websocket connection for ${options.path}.\n:${error}`);
162
184
  }
163
185
  };
164
- this._saveCounter = 0;
165
186
  // This is for emitting signals to be proxied to `Drive.fileChanged`
166
187
  this._providerFileChanged = new Signal(this);
167
188
  this._user = options.user;
@@ -171,8 +192,10 @@ export class RtcContentProvider {
171
192
  this._currentDrive = options.currentDrive;
172
193
  this.sharedModelFactory = new SharedModelFactory(this._onCreate);
173
194
  this._providers = new Map();
174
- this._docmanagerSettings = options.docmanagerSettings;
195
+ this._documentManager = (_a = options.documentManager) !== null && _a !== void 0 ? _a : null;
196
+ this._docmanagerSettings = (_b = options.docmanagerSettings) !== null && _b !== void 0 ? _b : null;
175
197
  this._driveFileChanged = options.fileChanged;
198
+ this._providerFactory = options.providerFactory;
176
199
  }
177
200
  get providers() {
178
201
  return this._providers;
@@ -233,62 +256,13 @@ export class RtcContentProvider {
233
256
  * file is saved.
234
257
  */
235
258
  async save(localPath, options = {}) {
236
- var _a;
237
259
  // Check that there is a provider - it won't e.g. if the document model is not collaborative.
238
260
  if (options.format && options.type) {
239
261
  const key = `${options.format}:${options.type}:${localPath}`;
240
262
  const provider = this._providers.get(key);
241
- const saveId = ++this._saveCounter;
242
263
  if (provider) {
243
- const ws = (_a = provider.wsProvider) === null || _a === void 0 ? void 0 : _a.ws;
244
- if (ws) {
245
- const delegate = new PromiseDelegate();
246
- const handler = (event) => {
247
- const data = new Uint8Array(event.data);
248
- const decoder = decoding.createDecoder(data);
249
- try {
250
- const messageType = decoding.readVarUint(decoder);
251
- if (messageType !== RAW_MESSAGE_TYPE) {
252
- return;
253
- }
254
- }
255
- catch (_a) {
256
- return;
257
- }
258
- const rawReply = decoding.readVarString(decoder);
259
- let reply = null;
260
- try {
261
- reply = JSON.parse(rawReply);
262
- }
263
- catch (e) {
264
- console.debug('The raw reply received was not a JSON reply');
265
- }
266
- if (reply &&
267
- reply['type'] === 'save' &&
268
- reply['responseTo'] === saveId) {
269
- if (reply.status === 'success') {
270
- delegate.resolve();
271
- }
272
- else if (reply.status === 'failed') {
273
- delegate.reject('Saving failed');
274
- }
275
- else if (reply.status === 'skipped') {
276
- delegate.reject('Saving already in progress');
277
- }
278
- else {
279
- delegate.reject('Unrecognised save reply status');
280
- }
281
- }
282
- };
283
- ws.addEventListener('message', handler);
284
- const encoder = encoding.createEncoder();
285
- encoding.writeVarUint(encoder, RAW_MESSAGE_TYPE);
286
- encoding.writeVarString(encoder, 'save');
287
- encoding.writeVarUint(encoder, saveId);
288
- const saveMessage = encoding.toUint8Array(encoder);
289
- ws.send(saveMessage);
290
- await delegate.promise;
291
- ws.removeEventListener('message', handler);
264
+ if (provider.save) {
265
+ await provider.save();
292
266
  }
293
267
  const fetchOptions = {
294
268
  type: options.type,
@@ -359,6 +333,9 @@ class SharedModelFactory {
359
333
  }
360
334
  if (this.documentFactories.has(options.contentType)) {
361
335
  const factory = this.documentFactories.get(options.contentType);
336
+ if (!factory) {
337
+ return;
338
+ }
362
339
  const sharedModel = factory(options);
363
340
  this._onCreate(options, sharedModel);
364
341
  return sharedModel;
@@ -1,8 +1,8 @@
1
+ import { WebsocketProvider as YWebsocketProvider } from 'y-websocket';
2
+ import { DocumentChange, YDocument } from '@jupyter/ydoc';
1
3
  import { IDocumentProvider } from '@jupyter/collaborative-drive';
2
4
  import { ServerConnection, User } from '@jupyterlab/services';
3
5
  import { TranslationBundle } from '@jupyterlab/translation';
4
- import { DocumentChange, YDocument } from '@jupyter/ydoc';
5
- import { WebsocketProvider as YWebsocketProvider } from 'y-websocket';
6
6
  import { IForkProvider } from './ydrive';
7
7
  /**
8
8
  * A class to provide Yjs synchronization over WebSocket.
@@ -32,6 +32,7 @@ export declare class WebSocketProvider implements IDocumentProvider, IForkProvid
32
32
  */
33
33
  dispose(): void;
34
34
  reconnect(): Promise<void>;
35
+ save(): Promise<void>;
35
36
  private get _serverUrl();
36
37
  private _connect;
37
38
  connectToForkDoc(forkRoomId: string, sessionId: string): Promise<void>;
@@ -54,6 +55,7 @@ export declare class WebSocketProvider implements IDocumentProvider, IForkProvid
54
55
  private _serverSettings;
55
56
  private _trans;
56
57
  private _hasSynced;
58
+ private _saveCounter;
57
59
  }
58
60
  /**
59
61
  * A namespace for WebSocketProvider statics.
package/lib/yprovider.js CHANGED
@@ -1,18 +1,24 @@
1
- /* -----------------------------------------------------------------------------
2
- | Copyright (c) Jupyter Development Team.
3
- | Distributed under the terms of the Modified BSD License.
4
- |----------------------------------------------------------------------------*/
5
- import { Dialog, showDialog } from '@jupyterlab/apputils';
6
- import { ServerConnection } from '@jupyterlab/services';
7
- import { PromiseDelegate } from '@lumino/coreutils';
8
- import { Signal } from '@lumino/signaling';
1
+ /*
2
+ * Copyright (c) Jupyter Development Team.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
9
5
  import { WebsocketProvider as YWebsocketProvider } from 'y-websocket';
10
- import { requestDocSession } from './requests';
6
+ import * as decoding from 'lib0/decoding';
7
+ import * as encoding from 'lib0/encoding';
8
+ import { Signal } from '@lumino/signaling';
9
+ import { PromiseDelegate } from '@lumino/coreutils';
10
+ import { ServerConnection } from '@jupyterlab/services';
11
11
  import { URLExt } from '@jupyterlab/coreutils';
12
+ import { Dialog, showDialog } from '@jupyterlab/apputils';
13
+ import { requestDocSession } from './requests';
12
14
  /**
13
15
  * The url for the default drive service.
14
16
  */
15
17
  const DOCUMENT_PROVIDER_URL = 'api/collaboration/room';
18
+ /**
19
+ * The raw message type.
20
+ */
21
+ const RAW_MESSAGE_TYPE = 2;
16
22
  /**
17
23
  * A class to provide Yjs synchronization over WebSocket.
18
24
  *
@@ -85,6 +91,7 @@ export class WebSocketProvider {
85
91
  };
86
92
  this._ready = new PromiseDelegate();
87
93
  this._hasSynced = false;
94
+ this._saveCounter = 0;
88
95
  this._isDisposed = false;
89
96
  this._path = options.path;
90
97
  this._contentType = options.contentType;
@@ -142,6 +149,64 @@ export class WebSocketProvider {
142
149
  this._disconnect();
143
150
  this._connect();
144
151
  }
152
+ async save() {
153
+ var _a;
154
+ const ws = (_a = this._yWebsocketProvider) === null || _a === void 0 ? void 0 : _a.ws;
155
+ if (ws) {
156
+ const saveId = ++this._saveCounter;
157
+ const delegate = new PromiseDelegate();
158
+ const handler = (event) => {
159
+ const data = new Uint8Array(event.data);
160
+ const decoder = decoding.createDecoder(data);
161
+ try {
162
+ const messageType = decoding.readVarUint(decoder);
163
+ if (messageType !== RAW_MESSAGE_TYPE) {
164
+ return;
165
+ }
166
+ }
167
+ catch (_a) {
168
+ return;
169
+ }
170
+ const rawReply = decoding.readVarString(decoder);
171
+ let reply = null;
172
+ try {
173
+ reply = JSON.parse(rawReply);
174
+ }
175
+ catch (e) {
176
+ console.debug('The raw reply received was not a JSON reply');
177
+ }
178
+ if (reply &&
179
+ reply['type'] === 'save' &&
180
+ reply['responseTo'] === saveId) {
181
+ if (reply.status === 'success') {
182
+ delegate.resolve();
183
+ }
184
+ else if (reply.status === 'failed') {
185
+ delegate.reject('Saving failed');
186
+ }
187
+ else if (reply.status === 'skipped') {
188
+ delegate.reject('Saving already in progress');
189
+ }
190
+ else {
191
+ delegate.reject('Unrecognised save reply status');
192
+ }
193
+ }
194
+ };
195
+ ws.addEventListener('message', handler);
196
+ const encoder = encoding.createEncoder();
197
+ encoding.writeVarUint(encoder, RAW_MESSAGE_TYPE);
198
+ encoding.writeVarString(encoder, 'save');
199
+ encoding.writeVarUint(encoder, saveId);
200
+ const saveMessage = encoding.toUint8Array(encoder);
201
+ ws.send(saveMessage);
202
+ try {
203
+ await delegate.promise;
204
+ }
205
+ finally {
206
+ ws.removeEventListener('message', handler);
207
+ }
208
+ }
209
+ }
145
210
  get _serverUrl() {
146
211
  var _a;
147
212
  return ((_a = this._customServerUrl) !== null && _a !== void 0 ? _a : URLExt.join(this._serverSettings.wsUrl, DOCUMENT_PROVIDER_URL));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyter/docprovider",
3
- "version": "4.3.0-rc.0",
3
+ "version": "4.4.0-alpha.0",
4
4
  "description": "JupyterLab - Document Provider",
5
5
  "homepage": "https://github.com/jupyterlab/jupyter-collaboration",
6
6
  "bugs": {
@@ -41,11 +41,12 @@
41
41
  "watch": "tsc -b --watch"
42
42
  },
43
43
  "dependencies": {
44
- "@jupyter/collaborative-drive": "^4.3.0-rc.0",
44
+ "@jupyter/collaborative-drive": "^4.4.0-alpha.0",
45
45
  "@jupyter/ydoc": "^2.1.3 || ^3.0.0",
46
46
  "@jupyterlab/apputils": "^4.5.0",
47
47
  "@jupyterlab/cells": "^4.5.0",
48
48
  "@jupyterlab/coreutils": "^6.5.0",
49
+ "@jupyterlab/docmanager": "^4.5.0",
49
50
  "@jupyterlab/notebook": "^4.5.0",
50
51
  "@jupyterlab/services": "^7.5.0",
51
52
  "@jupyterlab/translation": "^4.5.0",
@@ -63,7 +64,7 @@
63
64
  "@types/jest": "^29.2.0",
64
65
  "jest": "^29.5.0",
65
66
  "rimraf": "^4.1.2",
66
- "typescript": "~5.1.6"
67
+ "typescript": "~5.9.3"
67
68
  },
68
69
  "publishConfig": {
69
70
  "access": "public"