@jupyter/docprovider 1.0.0-alpha.7 → 1.0.0-alpha.9

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.
package/lib/requests.d.ts CHANGED
@@ -1,8 +1,23 @@
1
1
  import { Contents } from '@jupyterlab/services';
2
+ /**
3
+ * Document session model
4
+ */
2
5
  export interface ISessionModel {
6
+ /**
7
+ * Document format; 'text', 'base64',...
8
+ */
3
9
  format: Contents.FileFormat;
10
+ /**
11
+ * Document type
12
+ */
4
13
  type: Contents.ContentType;
14
+ /**
15
+ * File unique identifier
16
+ */
5
17
  fileId: string;
18
+ /**
19
+ * Server session identifier
20
+ */
6
21
  sessionId: string;
7
22
  }
8
23
  export declare function requestDocSession(format: string, type: string, path: string): Promise<ISessionModel>;
package/lib/requests.js CHANGED
@@ -10,16 +10,30 @@ import { ServerConnection } from '@jupyterlab/services';
10
10
  */
11
11
  const DOC_SESSION_URL = 'api/collaboration/session';
12
12
  export async function requestDocSession(format, type, path) {
13
- const { makeSettings, makeRequest, ResponseError } = ServerConnection;
14
- const settings = makeSettings();
13
+ const settings = ServerConnection.makeSettings();
15
14
  const url = URLExt.join(settings.baseUrl, DOC_SESSION_URL, encodeURIComponent(path));
16
- const data = {
15
+ const body = {
17
16
  method: 'PUT',
18
17
  body: JSON.stringify({ format, type })
19
18
  };
20
- const response = await makeRequest(url, data, settings);
21
- if (response.status !== 200 && response.status !== 201) {
22
- throw new ResponseError(response);
19
+ let response;
20
+ try {
21
+ response = await ServerConnection.makeRequest(url, body, settings);
23
22
  }
24
- return response.json();
23
+ catch (error) {
24
+ throw new ServerConnection.NetworkError(error);
25
+ }
26
+ let data = await response.text();
27
+ if (data.length > 0) {
28
+ try {
29
+ data = JSON.parse(data);
30
+ }
31
+ catch (error) {
32
+ console.log('Not a JSON response body.', response);
33
+ }
34
+ }
35
+ if (!response.ok) {
36
+ throw new ServerConnection.ResponseError(response, data.message || data);
37
+ }
38
+ return data;
25
39
  }
package/lib/ydrive.js CHANGED
@@ -135,6 +135,9 @@ class SharedModelFactory {
135
135
  * @param factory Document factory
136
136
  */
137
137
  registerDocumentFactory(type, factory) {
138
+ if (this._documentFactories.has(type)) {
139
+ throw new Error(`The content type ${type} already exists`);
140
+ }
138
141
  this._documentFactories.set(type, factory);
139
142
  }
140
143
  /**
@@ -39,6 +39,7 @@ export declare class WebSocketProvider implements IDocumentProvider {
39
39
  private _connect;
40
40
  private _onUserChanged;
41
41
  private _onConnectionClosed;
42
+ private _onSync;
42
43
  private _awareness;
43
44
  private _contentType;
44
45
  private _format;
package/lib/yprovider.js CHANGED
@@ -23,18 +23,21 @@ export class WebSocketProvider {
23
23
  this._onConnectionClosed = (event) => {
24
24
  if (event.code === 1003) {
25
25
  console.error('Document provider closed:', event.reason);
26
- showErrorMessage(this._trans.__('Session expired'), this._trans.__('The document session expired. You need to reload this browser tab.'), [Dialog.okButton({ label: this._trans.__('Reload') })])
27
- .then((r) => {
28
- if (r.button.accept) {
29
- window.location.reload();
30
- }
31
- })
32
- .catch(e => window.location.reload());
26
+ showErrorMessage(this._trans.__('Document session error'), event.reason, [
27
+ Dialog.okButton()
28
+ ]);
33
29
  // Dispose shared model immediately. Better break the document model,
34
30
  // than overriding data on disk.
35
31
  this._sharedModel.dispose();
36
32
  }
37
33
  };
34
+ this._onSync = (isSynced) => {
35
+ var _a;
36
+ if (isSynced) {
37
+ this._ready.resolve();
38
+ (_a = this._yWebsocketProvider) === null || _a === void 0 ? void 0 : _a.off('sync', this._onSync);
39
+ }
40
+ };
38
41
  this._ready = new PromiseDelegate();
39
42
  this._isDisposed = false;
40
43
  this._path = options.path;
@@ -52,7 +55,7 @@ export class WebSocketProvider {
52
55
  })
53
56
  .catch(e => console.error(e));
54
57
  user.userChanged.connect(this._onUserChanged, this);
55
- this._connect();
58
+ this._connect().catch(e => console.warn(e));
56
59
  }
57
60
  /**
58
61
  * Test whether the object has been disposed.
@@ -70,27 +73,25 @@ export class WebSocketProvider {
70
73
  * Dispose of the resources held by the object.
71
74
  */
72
75
  dispose() {
73
- var _a, _b;
76
+ var _a, _b, _c;
74
77
  if (this.isDisposed) {
75
78
  return;
76
79
  }
77
80
  this._isDisposed = true;
78
81
  (_a = this._yWebsocketProvider) === null || _a === void 0 ? void 0 : _a.off('connection-close', this._onConnectionClosed);
79
- (_b = this._yWebsocketProvider) === null || _b === void 0 ? void 0 : _b.destroy();
82
+ (_b = this._yWebsocketProvider) === null || _b === void 0 ? void 0 : _b.off('sync', this._onSync);
83
+ (_c = this._yWebsocketProvider) === null || _c === void 0 ? void 0 : _c.destroy();
80
84
  Signal.clearData(this);
81
85
  }
82
- _connect() {
83
- requestDocSession(this._format, this._contentType, this._path)
84
- .then((session) => {
85
- this._yWebsocketProvider = new YWebsocketProvider(this._serverUrl, `${session.format}:${session.type}:${session.fileId}`, this._sharedModel.ydoc, {
86
- disableBc: true,
87
- params: { sessionId: session.sessionId },
88
- awareness: this._awareness
89
- });
90
- this._yWebsocketProvider.on('connection-close', this._onConnectionClosed);
91
- })
92
- .then(r => this._ready.resolve())
93
- .catch(e => console.warn(e));
86
+ async _connect() {
87
+ const session = await requestDocSession(this._format, this._contentType, this._path);
88
+ this._yWebsocketProvider = new YWebsocketProvider(this._serverUrl, `${session.format}:${session.type}:${session.fileId}`, this._sharedModel.ydoc, {
89
+ disableBc: true,
90
+ params: { sessionId: session.sessionId },
91
+ awareness: this._awareness
92
+ });
93
+ this._yWebsocketProvider.on('sync', this._onSync);
94
+ this._yWebsocketProvider.on('connection-close', this._onConnectionClosed);
94
95
  }
95
96
  _onUserChanged(user) {
96
97
  this._awareness.setLocalStateField('user', user.identity);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyter/docprovider",
3
- "version": "1.0.0-alpha.7",
3
+ "version": "1.0.0-alpha.9",
4
4
  "description": "JupyterLab - Document Provider",
5
5
  "homepage": "https://github.com/jupyterlab/jupyter_collaboration",
6
6
  "bugs": {
@@ -41,21 +41,22 @@
41
41
  "watch": "tsc -b --watch"
42
42
  },
43
43
  "dependencies": {
44
- "@jupyter/ydoc": "^0.3.4",
45
- "@jupyterlab/coreutils": "^6.0.0-beta.0",
46
- "@jupyterlab/services": "^7.0.0-beta.0",
47
- "@lumino/coreutils": "^2.0.0",
48
- "@lumino/disposable": "^2.0.0",
49
- "@lumino/signaling": "^2.0.0",
44
+ "@jupyter/ydoc": "^1.0.2",
45
+ "@jupyterlab/coreutils": "^6.0.0",
46
+ "@jupyterlab/services": "^7.0.0",
47
+ "@lumino/coreutils": "^2.1.0",
48
+ "@lumino/disposable": "^2.1.0",
49
+ "@lumino/signaling": "^2.1.0",
50
50
  "y-protocols": "^1.0.5",
51
51
  "y-websocket": "^1.3.15",
52
52
  "yjs": "^13.5.40"
53
53
  },
54
54
  "devDependencies": {
55
- "@jupyterlab/testing": "^4.0.0-beta.0",
55
+ "@jupyterlab/testing": "^4.0.0",
56
56
  "@types/jest": "^29.2.0",
57
+ "jest": "^29.5.0",
57
58
  "rimraf": "^4.1.2",
58
- "typescript": "~5.0.2"
59
+ "typescript": "~5.0.4"
59
60
  },
60
61
  "publishConfig": {
61
62
  "access": "public"