@jupyter/docprovider 4.4.0-rc.0 → 4.4.1

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.
@@ -41,6 +41,8 @@ export declare class WebSocketProvider implements IDocumentProvider, IForkProvid
41
41
  private _onUserChanged;
42
42
  private _buildSessionExpiredMessage;
43
43
  private _onConnectionClosed;
44
+ private _attachConflictListener;
45
+ private _handleConflictMessage;
44
46
  private _onSync;
45
47
  private _getCloseReasonMessage;
46
48
  private _awareness;
@@ -56,6 +58,9 @@ export declare class WebSocketProvider implements IDocumentProvider, IForkProvid
56
58
  private _trans;
57
59
  private _hasSynced;
58
60
  private _saveCounter;
61
+ private _conflictWs;
62
+ private _onConflictSaveAs?;
63
+ private _onConflictRevert?;
59
64
  }
60
65
  /**
61
66
  * A namespace for WebSocketProvider statics.
@@ -97,5 +102,13 @@ export declare namespace WebSocketProvider {
97
102
  * The server settings.
98
103
  */
99
104
  serverSettings?: ServerConnection.ISettings;
105
+ /**
106
+ * Called when the user chooses "Save As" from the conflict dialog.
107
+ */
108
+ onConflictSaveAs?: () => Promise<void>;
109
+ /**
110
+ * Called when the user chooses "Revert" from the conflict dialog.
111
+ */
112
+ onConflictRevert?: () => Promise<void>;
100
113
  }
101
114
  }
package/lib/yprovider.js CHANGED
@@ -78,6 +78,58 @@ export class WebSocketProvider {
78
78
  this._sharedModel.dispose();
79
79
  }
80
80
  };
81
+ this._handleConflictMessage = async (event) => {
82
+ var _a, _b;
83
+ if (!(event.data instanceof ArrayBuffer)) {
84
+ return;
85
+ }
86
+ const data = new Uint8Array(event.data);
87
+ if (data.length === 0) {
88
+ return;
89
+ }
90
+ const decoder = decoding.createDecoder(data);
91
+ try {
92
+ if (decoding.readVarUint(decoder) !== RAW_MESSAGE_TYPE) {
93
+ return;
94
+ }
95
+ const payload = JSON.parse(decoding.readVarString(decoder));
96
+ if (!payload || payload.type !== 'conflict') {
97
+ return;
98
+ }
99
+ }
100
+ catch (_c) {
101
+ return;
102
+ }
103
+ const buttons = [
104
+ Dialog.cancelButton({ label: this._trans.__('Dismiss') })
105
+ ];
106
+ if (this._onConflictRevert) {
107
+ buttons.push(Dialog.warnButton({
108
+ label: this._trans.__('Revert'),
109
+ actions: ['revert']
110
+ }));
111
+ }
112
+ if (this._onConflictSaveAs) {
113
+ buttons.push(Dialog.okButton({
114
+ label: this._trans.__('Save As'),
115
+ actions: ['save-as']
116
+ }));
117
+ }
118
+ const result = await showDialog({
119
+ title: this._trans.__('Edit Conflict'),
120
+ body: this._trans.__('Your recent changes could not be applied because the document ' +
121
+ 'structure changed while you were disconnected (for example, another ' +
122
+ 'user or external tool modified the file). Your edits were not ' +
123
+ 'saved to the shared document.'),
124
+ buttons
125
+ });
126
+ if (result.button.actions.includes('revert')) {
127
+ await ((_a = this._onConflictRevert) === null || _a === void 0 ? void 0 : _a.call(this));
128
+ }
129
+ else if (result.button.actions.includes('save-as')) {
130
+ await ((_b = this._onConflictSaveAs) === null || _b === void 0 ? void 0 : _b.call(this));
131
+ }
132
+ };
81
133
  this._onSync = (isSynced) => {
82
134
  if (isSynced) {
83
135
  this._hasSynced = true;
@@ -92,6 +144,7 @@ export class WebSocketProvider {
92
144
  this._ready = new PromiseDelegate();
93
145
  this._hasSynced = false;
94
146
  this._saveCounter = 0;
147
+ this._conflictWs = null;
95
148
  this._isDisposed = false;
96
149
  this._path = options.path;
97
150
  this._contentType = options.contentType;
@@ -103,6 +156,8 @@ export class WebSocketProvider {
103
156
  this._serverSettings =
104
157
  (_a = options.serverSettings) !== null && _a !== void 0 ? _a : ServerConnection.makeSettings();
105
158
  this._trans = options.translator;
159
+ this._onConflictSaveAs = options.onConflictSaveAs;
160
+ this._onConflictRevert = options.onConflictRevert;
106
161
  const user = options.user;
107
162
  user.ready
108
163
  .then(() => {
@@ -139,6 +194,10 @@ export class WebSocketProvider {
139
194
  return;
140
195
  }
141
196
  this._isDisposed = true;
197
+ if (this._conflictWs) {
198
+ this._conflictWs.removeEventListener('message', this._handleConflictMessage);
199
+ this._conflictWs = null;
200
+ }
142
201
  (_a = this._yWebsocketProvider) === null || _a === void 0 ? void 0 : _a.off('connection-close', this._onConnectionClosed);
143
202
  (_b = this._yWebsocketProvider) === null || _b === void 0 ? void 0 : _b.off('sync', this._onSync);
144
203
  (_c = this._yWebsocketProvider) === null || _c === void 0 ? void 0 : _c.destroy();
@@ -226,6 +285,11 @@ export class WebSocketProvider {
226
285
  });
227
286
  this._yWebsocketProvider.on('sync', this._onSync);
228
287
  this._yWebsocketProvider.on('connection-close', this._onConnectionClosed);
288
+ this._yWebsocketProvider.on('status', ({ status }) => {
289
+ if (status === 'connected') {
290
+ this._attachConflictListener();
291
+ }
292
+ });
229
293
  }
230
294
  async connectToForkDoc(forkRoomId, sessionId) {
231
295
  const token = this._serverSettings.token;
@@ -276,6 +340,17 @@ export class WebSocketProvider {
276
340
  };
277
341
  }
278
342
  }
343
+ _attachConflictListener() {
344
+ var _a;
345
+ if (this._conflictWs) {
346
+ this._conflictWs.removeEventListener('message', this._handleConflictMessage);
347
+ }
348
+ const ws = (_a = this._yWebsocketProvider) === null || _a === void 0 ? void 0 : _a.ws;
349
+ if (ws) {
350
+ ws.addEventListener('message', this._handleConflictMessage);
351
+ this._conflictWs = ws;
352
+ }
353
+ }
279
354
  _getCloseReasonMessage(code) {
280
355
  switch (code) {
281
356
  case 4400: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyter/docprovider",
3
- "version": "4.4.0-rc.0",
3
+ "version": "4.4.1",
4
4
  "description": "JupyterLab - Document Provider",
5
5
  "homepage": "https://github.com/jupyterlab/jupyter-collaboration",
6
6
  "bugs": {
@@ -41,7 +41,7 @@
41
41
  "watch": "tsc -b --watch"
42
42
  },
43
43
  "dependencies": {
44
- "@jupyter/collaborative-drive": "^4.4.0-rc.0",
44
+ "@jupyter/collaborative-drive": "^4.4.1",
45
45
  "@jupyter/ydoc": "^2.1.3 || ^3.0.0",
46
46
  "@jupyterlab/apputils": "^4.5.0",
47
47
  "@jupyterlab/cells": "^4.5.0",