@atlaskit/collab-provider 8.5.0 → 8.7.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.
Files changed (76) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/cjs/analytics/analytics-helper.js +22 -24
  3. package/dist/cjs/analytics/performance.js +4 -4
  4. package/dist/cjs/channel.js +218 -203
  5. package/dist/cjs/connectivity/network.js +4 -4
  6. package/dist/cjs/disconnected-reason-mapper.js +4 -4
  7. package/dist/cjs/document/catchup.js +81 -81
  8. package/dist/cjs/document/document-service.js +226 -285
  9. package/dist/cjs/document/step-queue-state.js +4 -0
  10. package/dist/cjs/errors/error-types.js +102 -23
  11. package/dist/cjs/helpers/const.js +12 -12
  12. package/dist/cjs/index.js +8 -1
  13. package/dist/cjs/metadata/metadata-service.js +77 -0
  14. package/dist/cjs/participants/participants-helper.js +19 -28
  15. package/dist/cjs/participants/participants-service.js +90 -60
  16. package/dist/cjs/participants/participants-state.js +1 -0
  17. package/dist/cjs/provider/commit-step.js +10 -2
  18. package/dist/cjs/provider/index.js +168 -101
  19. package/dist/cjs/types.js +12 -4
  20. package/dist/cjs/version-wrapper.js +1 -1
  21. package/dist/cjs/version.json +1 -1
  22. package/dist/es2019/analytics/analytics-helper.js +3 -3
  23. package/dist/es2019/analytics/performance.js +3 -3
  24. package/dist/es2019/channel.js +27 -6
  25. package/dist/es2019/connectivity/network.js +3 -3
  26. package/dist/es2019/disconnected-reason-mapper.js +3 -3
  27. package/dist/es2019/document/catchup.js +4 -2
  28. package/dist/es2019/document/document-service.js +45 -76
  29. package/dist/es2019/document/step-queue-state.js +4 -0
  30. package/dist/es2019/errors/error-types.js +104 -25
  31. package/dist/es2019/helpers/const.js +9 -9
  32. package/dist/es2019/index.js +2 -1
  33. package/dist/es2019/metadata/metadata-service.js +57 -0
  34. package/dist/es2019/participants/participants-helper.js +3 -8
  35. package/dist/es2019/participants/participants-service.js +46 -15
  36. package/dist/es2019/participants/participants-state.js +1 -0
  37. package/dist/es2019/provider/commit-step.js +8 -1
  38. package/dist/es2019/provider/index.js +111 -39
  39. package/dist/es2019/types.js +16 -3
  40. package/dist/es2019/version-wrapper.js +1 -1
  41. package/dist/es2019/version.json +1 -1
  42. package/dist/esm/analytics/analytics-helper.js +22 -24
  43. package/dist/esm/analytics/performance.js +3 -3
  44. package/dist/esm/channel.js +218 -203
  45. package/dist/esm/connectivity/network.js +3 -3
  46. package/dist/esm/disconnected-reason-mapper.js +3 -3
  47. package/dist/esm/document/catchup.js +81 -81
  48. package/dist/esm/document/document-service.js +226 -285
  49. package/dist/esm/document/step-queue-state.js +4 -0
  50. package/dist/esm/errors/error-types.js +104 -25
  51. package/dist/esm/helpers/const.js +9 -9
  52. package/dist/esm/index.js +2 -1
  53. package/dist/esm/metadata/metadata-service.js +69 -0
  54. package/dist/esm/participants/participants-helper.js +19 -28
  55. package/dist/esm/participants/participants-service.js +90 -60
  56. package/dist/esm/participants/participants-state.js +1 -0
  57. package/dist/esm/provider/commit-step.js +8 -1
  58. package/dist/esm/provider/index.js +167 -99
  59. package/dist/esm/types.js +16 -3
  60. package/dist/esm/version-wrapper.js +1 -1
  61. package/dist/esm/version.json +1 -1
  62. package/dist/types/channel.d.ts +2 -2
  63. package/dist/types/document/document-service.d.ts +5 -24
  64. package/dist/types/index.d.ts +2 -1
  65. package/dist/types/metadata/metadata-service.d.ts +25 -0
  66. package/dist/types/participants/participants-helper.d.ts +2 -3
  67. package/dist/types/participants/participants-service.d.ts +8 -8
  68. package/dist/types/provider/commit-step.d.ts +11 -0
  69. package/dist/types/provider/index.d.ts +15 -13
  70. package/dist/types/types.d.ts +24 -10
  71. package/package.json +12 -7
  72. package/report.api.md +26 -7
  73. package/channel/package.json +0 -15
  74. package/config/package.json +0 -15
  75. package/disconnected-reason-mapper/package.json +0 -15
  76. package/emitter/package.json +0 -15
@@ -14,11 +14,11 @@ var _const = require("../helpers/const");
14
14
  var _prosemirrorCollab = require("@atlaskit/prosemirror-collab");
15
15
  var _utils = require("../helpers/utils");
16
16
  var _throttle = _interopRequireDefault(require("lodash/throttle"));
17
+ var _commitStep = require("../provider/commit-step");
17
18
  var _performance = require("../analytics/performance");
18
19
  var _editorJsonTransformer = require("@atlaskit/editor-json-transformer");
19
20
  var _provider = require("../provider");
20
21
  var _catchup = require("./catchup");
21
- var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
22
22
  var _stepQueueState = require("./step-queue-state");
23
23
  var _errorTypes = require("../errors/error-types");
24
24
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
@@ -28,7 +28,7 @@ var CATCHUP_THROTTLE = 1 * 1000; // 1 second
28
28
  var noop = function noop() {};
29
29
  var logger = (0, _utils.createLogger)('documentService', 'black');
30
30
  var DocumentService = /*#__PURE__*/function () {
31
- // Fires analytics to editor when collab editor cannot sync up
31
+ // ClientID is the unique ID for a prosemirror client. Used for step-rebasing.
32
32
 
33
33
  /**
34
34
  *
@@ -42,20 +42,14 @@ var DocumentService = /*#__PURE__*/function () {
42
42
  * @param getUserId - Callback to fetch the current user's ID
43
43
  * @param onErrorHandled - Callback to handle
44
44
  */
45
- function DocumentService(participantsService, analyticsHelper, fetchCatchup, providerEmitCallback, broadcastMetadata, broadcast, getUserId, onErrorHandled) {
45
+ function DocumentService(participantsService, analyticsHelper, fetchCatchup, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService) {
46
46
  var _this = this;
47
47
  (0, _classCallCheck2.default)(this, DocumentService);
48
+ // Fires analytics to editor when collab editor cannot sync up
48
49
  (0, _defineProperty2.default)(this, "stepRejectCounter", 0);
49
- (0, _defineProperty2.default)(this, "metadata", {});
50
- (0, _defineProperty2.default)(this, "onMetadataChanged", function (metadata) {
51
- if (metadata !== undefined && !(0, _isEqual.default)(_this.metadata, metadata)) {
52
- _this.metadata = metadata;
53
- _this.providerEmitCallback('metadata:changed', metadata);
54
- }
55
- });
56
- (0, _defineProperty2.default)(this, "getMetaData", function () {
57
- return _this.metadata;
58
- });
50
+ /**
51
+ * To prevent calling catchup to often, use lodash throttle to reduce the frequency
52
+ */
59
53
  (0, _defineProperty2.default)(this, "throttledCatchup", (0, _throttle.default)(function () {
60
54
  return _this.catchup();
61
55
  }, CATCHUP_THROTTLE, {
@@ -63,58 +57,62 @@ var DocumentService = /*#__PURE__*/function () {
63
57
  // TODO: why shouldn't this be leading?
64
58
  trailing: true
65
59
  }));
60
+ /**
61
+ * Called when:
62
+ * * session established(offline -> online)
63
+ * * try to accept steps but version is behind.
64
+ */
66
65
  (0, _defineProperty2.default)(this, "catchup", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
67
66
  var start, _this$analyticsHelper, latency, _this$analyticsHelper2, _this$analyticsHelper3, _latency;
68
67
  return _regenerator.default.wrap(function _callee$(_context) {
69
- while (1) {
70
- switch (_context.prev = _context.next) {
71
- case 0:
72
- start = new Date().getTime(); // if the queue is already paused, we are busy with something else, so don't proceed.
73
- if (!_this.stepQueue.isPaused()) {
74
- _context.next = 4;
75
- break;
76
- }
77
- logger("Queue is paused. Aborting.");
78
- return _context.abrupt("return");
79
- case 4:
80
- _this.stepQueue.pauseQueue();
81
- _context.prev = 5;
82
- _context.next = 8;
83
- return (0, _catchup.catchup)({
84
- getCurrentPmVersion: _this.getCurrentPmVersion,
85
- fetchCatchup: _this.fetchCatchup,
86
- getUnconfirmedSteps: _this.getUnconfirmedSteps,
87
- filterQueue: _this.stepQueue.filterQueue,
88
- updateDocumentWithMetadata: _this.updateDocumentWithMetadata,
89
- applyLocalSteps: _this.applyLocalSteps
90
- });
91
- case 8:
92
- latency = new Date().getTime() - start;
93
- (_this$analyticsHelper = _this.analyticsHelper) === null || _this$analyticsHelper === void 0 ? void 0 : _this$analyticsHelper.sendActionEvent(_const.EVENT_ACTION.CATCHUP, _const.EVENT_STATUS.SUCCESS, {
94
- latency: latency
95
- });
96
- _context.next = 18;
68
+ while (1) switch (_context.prev = _context.next) {
69
+ case 0:
70
+ start = new Date().getTime(); // if the queue is already paused, we are busy with something else, so don't proceed.
71
+ if (!_this.stepQueue.isPaused()) {
72
+ _context.next = 4;
97
73
  break;
98
- case 12:
99
- _context.prev = 12;
100
- _context.t0 = _context["catch"](5);
101
- _latency = new Date().getTime() - start;
102
- (_this$analyticsHelper2 = _this.analyticsHelper) === null || _this$analyticsHelper2 === void 0 ? void 0 : _this$analyticsHelper2.sendActionEvent(_const.EVENT_ACTION.CATCHUP, _const.EVENT_STATUS.FAILURE, {
103
- latency: _latency
104
- });
105
- (_this$analyticsHelper3 = _this.analyticsHelper) === null || _this$analyticsHelper3 === void 0 ? void 0 : _this$analyticsHelper3.sendErrorEvent(_context.t0, 'Error while catching up');
106
- logger("Catch-Up Failed:", _context.t0.message);
107
- case 18:
108
- _context.prev = 18;
109
- _this.stepQueue.resumeQueue();
110
- _this.processQueue();
111
- _this.sendStepsFromCurrentState(); // this will eventually retry catchup as it calls commitStep which will either catchup on onStepsAdded or onErrorHandled
112
- _this.stepRejectCounter = 0;
113
- return _context.finish(18);
114
- case 24:
115
- case "end":
116
- return _context.stop();
117
- }
74
+ }
75
+ logger("Queue is paused. Aborting.");
76
+ return _context.abrupt("return");
77
+ case 4:
78
+ _this.stepQueue.pauseQueue();
79
+ _context.prev = 5;
80
+ _context.next = 8;
81
+ return (0, _catchup.catchup)({
82
+ getCurrentPmVersion: _this.getCurrentPmVersion,
83
+ fetchCatchup: _this.fetchCatchup,
84
+ getUnconfirmedSteps: _this.getUnconfirmedSteps,
85
+ filterQueue: _this.stepQueue.filterQueue,
86
+ applyLocalSteps: _this.applyLocalSteps,
87
+ updateDocument: _this.updateDocument,
88
+ updateMetadata: _this.metadataService.updateMetadata
89
+ });
90
+ case 8:
91
+ latency = new Date().getTime() - start;
92
+ (_this$analyticsHelper = _this.analyticsHelper) === null || _this$analyticsHelper === void 0 ? void 0 : _this$analyticsHelper.sendActionEvent(_const.EVENT_ACTION.CATCHUP, _const.EVENT_STATUS.SUCCESS, {
93
+ latency: latency
94
+ });
95
+ _context.next = 18;
96
+ break;
97
+ case 12:
98
+ _context.prev = 12;
99
+ _context.t0 = _context["catch"](5);
100
+ _latency = new Date().getTime() - start;
101
+ (_this$analyticsHelper2 = _this.analyticsHelper) === null || _this$analyticsHelper2 === void 0 ? void 0 : _this$analyticsHelper2.sendActionEvent(_const.EVENT_ACTION.CATCHUP, _const.EVENT_STATUS.FAILURE, {
102
+ latency: _latency
103
+ });
104
+ (_this$analyticsHelper3 = _this.analyticsHelper) === null || _this$analyticsHelper3 === void 0 ? void 0 : _this$analyticsHelper3.sendErrorEvent(_context.t0, 'Error while catching up');
105
+ logger("Catch-Up Failed:", _context.t0.message);
106
+ case 18:
107
+ _context.prev = 18;
108
+ _this.stepQueue.resumeQueue();
109
+ _this.processQueue();
110
+ _this.sendStepsFromCurrentState(); // this will eventually retry catchup as it calls commitStep which will either catchup on onStepsAdded or onErrorHandled
111
+ _this.stepRejectCounter = 0;
112
+ return _context.finish(18);
113
+ case 24:
114
+ case "end":
115
+ return _context.stop();
118
116
  }
119
117
  }, _callee, null, [[5, 12, 18, 24]]);
120
118
  })));
@@ -129,40 +127,38 @@ var DocumentService = /*#__PURE__*/function () {
129
127
  return (0, _prosemirrorCollab.getVersion)(state);
130
128
  });
131
129
  (0, _defineProperty2.default)(this, "getCurrentState", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
132
- var _this$metadata$title, _this$analyticsHelper5, state, adfDocument, currentState, measure, _this$analyticsHelper6, _this$analyticsHelper7, _measure;
130
+ var _this$analyticsHelper5, state, adfDocument, currentState, measure, _this$analyticsHelper6, _this$analyticsHelper7, _measure;
133
131
  return _regenerator.default.wrap(function _callee2$(_context2) {
134
- while (1) {
135
- switch (_context2.prev = _context2.next) {
136
- case 0:
137
- _context2.prev = 0;
138
- (0, _performance.startMeasure)(_performance.MEASURE_NAME.GET_CURRENT_STATE, _this.analyticsHelper);
132
+ while (1) switch (_context2.prev = _context2.next) {
133
+ case 0:
134
+ _context2.prev = 0;
135
+ (0, _performance.startMeasure)(_performance.MEASURE_NAME.GET_CURRENT_STATE, _this.analyticsHelper);
139
136
 
140
- // Convert ProseMirror document in Editor state to ADF document
141
- state = _this.getState();
142
- adfDocument = new _editorJsonTransformer.JSONTransformer().encode(state.doc);
143
- currentState = {
144
- content: adfDocument,
145
- title: (_this$metadata$title = _this.metadata.title) === null || _this$metadata$title === void 0 ? void 0 : _this$metadata$title.toString(),
146
- stepVersion: (0, _prosemirrorCollab.getVersion)(state)
147
- };
148
- measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.GET_CURRENT_STATE, _this.analyticsHelper);
149
- (_this$analyticsHelper5 = _this.analyticsHelper) === null || _this$analyticsHelper5 === void 0 ? void 0 : _this$analyticsHelper5.sendActionEvent(_const.EVENT_ACTION.GET_CURRENT_STATE, _const.EVENT_STATUS.SUCCESS, {
150
- latency: measure === null || measure === void 0 ? void 0 : measure.duration
151
- });
152
- return _context2.abrupt("return", currentState);
153
- case 10:
154
- _context2.prev = 10;
155
- _context2.t0 = _context2["catch"](0);
156
- _measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.GET_CURRENT_STATE, _this.analyticsHelper);
157
- (_this$analyticsHelper6 = _this.analyticsHelper) === null || _this$analyticsHelper6 === void 0 ? void 0 : _this$analyticsHelper6.sendActionEvent(_const.EVENT_ACTION.GET_CURRENT_STATE, _const.EVENT_STATUS.FAILURE, {
158
- latency: _measure === null || _measure === void 0 ? void 0 : _measure.duration
159
- });
160
- (_this$analyticsHelper7 = _this.analyticsHelper) === null || _this$analyticsHelper7 === void 0 ? void 0 : _this$analyticsHelper7.sendErrorEvent(_context2.t0, 'Error while returning ADF version of current draft document');
161
- throw _context2.t0;
162
- case 16:
163
- case "end":
164
- return _context2.stop();
165
- }
137
+ // Convert ProseMirror document in Editor state to ADF document
138
+ state = _this.getState();
139
+ adfDocument = new _editorJsonTransformer.JSONTransformer().encode(state.doc);
140
+ currentState = {
141
+ content: adfDocument,
142
+ title: _this.metadataService.getTitle(),
143
+ stepVersion: (0, _prosemirrorCollab.getVersion)(state)
144
+ };
145
+ measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.GET_CURRENT_STATE, _this.analyticsHelper);
146
+ (_this$analyticsHelper5 = _this.analyticsHelper) === null || _this$analyticsHelper5 === void 0 ? void 0 : _this$analyticsHelper5.sendActionEvent(_const.EVENT_ACTION.GET_CURRENT_STATE, _const.EVENT_STATUS.SUCCESS, {
147
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration
148
+ });
149
+ return _context2.abrupt("return", currentState);
150
+ case 10:
151
+ _context2.prev = 10;
152
+ _context2.t0 = _context2["catch"](0);
153
+ _measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.GET_CURRENT_STATE, _this.analyticsHelper);
154
+ (_this$analyticsHelper6 = _this.analyticsHelper) === null || _this$analyticsHelper6 === void 0 ? void 0 : _this$analyticsHelper6.sendActionEvent(_const.EVENT_ACTION.GET_CURRENT_STATE, _const.EVENT_STATUS.FAILURE, {
155
+ latency: _measure === null || _measure === void 0 ? void 0 : _measure.duration
156
+ });
157
+ (_this$analyticsHelper7 = _this.analyticsHelper) === null || _this$analyticsHelper7 === void 0 ? void 0 : _this$analyticsHelper7.sendErrorEvent(_context2.t0, 'Error while returning ADF version of current draft document');
158
+ throw _context2.t0;
159
+ case 16:
160
+ case "end":
161
+ return _context2.stop();
166
162
  }
167
163
  }, _callee2, null, [[0, 10]]);
168
164
  })));
@@ -192,23 +188,9 @@ var DocumentService = /*#__PURE__*/function () {
192
188
  steps: steps
193
189
  });
194
190
  });
195
- (0, _defineProperty2.default)(this, "updateDocumentWithMetadata", function (_ref3) {
196
- var doc = _ref3.doc,
197
- version = _ref3.version,
198
- metadata = _ref3.metadata,
199
- reserveCursor = _ref3.reserveCursor;
200
- _this.providerEmitCallback('init', _objectSpread({
201
- doc: doc,
202
- version: version,
203
- metadata: metadata
204
- }, reserveCursor ? {
205
- reserveCursor: reserveCursor
206
- } : {}));
207
- if (metadata && Object.keys(metadata).length > 0) {
208
- _this.metadata = metadata;
209
- _this.providerEmitCallback('metadata:changed', metadata);
210
- }
211
- });
191
+ /**
192
+ * Called when we receive steps from the service
193
+ */
212
194
  (0, _defineProperty2.default)(this, "onStepsAdded", function (data) {
213
195
  logger("Received steps", {
214
196
  steps: data.steps,
@@ -230,8 +212,8 @@ var DocumentService = /*#__PURE__*/function () {
230
212
  _this.stepQueue.queueSteps(data);
231
213
  _this.throttledCatchup();
232
214
  }
233
- _this.participantsService.updateLastActive(data.steps.map(function (_ref4) {
234
- var userId = _ref4.userId;
215
+ _this.participantsService.updateLastActive(data.steps.map(function (_ref3) {
216
+ var userId = _ref3.userId;
235
217
  return userId;
236
218
  }));
237
219
  } catch (stepsAddedError) {
@@ -247,10 +229,11 @@ var DocumentService = /*#__PURE__*/function () {
247
229
  });
248
230
  }
249
231
  });
250
- (0, _defineProperty2.default)(this, "onRestore", function (_ref5) {
251
- var doc = _ref5.doc,
252
- version = _ref5.version,
253
- metadata = _ref5.metadata;
232
+ // Triggered when page recovery has emitted an 'init' event on a page client is currently connected to.
233
+ (0, _defineProperty2.default)(this, "onRestore", function (_ref4) {
234
+ var doc = _ref4.doc,
235
+ version = _ref4.version,
236
+ metadata = _ref4.metadata;
254
237
  // Preserve the unconfirmed steps to prevent data loss.
255
238
  var unconfirmedSteps = _this.getUnconfirmedSteps();
256
239
  try {
@@ -260,12 +243,14 @@ var DocumentService = /*#__PURE__*/function () {
260
243
  // - Replace the version number, so editor is in sync with NCS server and can commit new changes.
261
244
  // - Replace the metadata
262
245
  // - Reserve the cursor position, in case a cursor jump.
263
- _this.updateDocumentWithMetadata({
246
+
247
+ _this.updateDocument({
264
248
  doc: doc,
265
249
  version: version,
266
250
  metadata: metadata,
267
251
  reserveCursor: true
268
252
  });
253
+ _this.metadataService.updateMetadata(metadata);
269
254
 
270
255
  // Re-apply the unconfirmed steps, not 100% of them can be applied, if document is changed significantly.
271
256
  if (unconfirmedSteps !== null && unconfirmedSteps !== void 0 && unconfirmedSteps.length) {
@@ -293,135 +278,134 @@ var DocumentService = /*#__PURE__*/function () {
293
278
  (0, _defineProperty2.default)(this, "getFinalAcknowledgedState", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
294
279
  var _this$analyticsHelper14, currentState, measure, _this$analyticsHelper15, _this$analyticsHelper16, _measure2;
295
280
  return _regenerator.default.wrap(function _callee3$(_context3) {
296
- while (1) {
297
- switch (_context3.prev = _context3.next) {
298
- case 0:
299
- _context3.prev = 0;
300
- (0, _performance.startMeasure)(_performance.MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
301
- _context3.next = 4;
302
- return _this.commitUnconfirmedSteps();
303
- case 4:
304
- _context3.next = 6;
305
- return _this.getCurrentState();
306
- case 6:
307
- currentState = _context3.sent;
308
- measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
309
- (_this$analyticsHelper14 = _this.analyticsHelper) === null || _this$analyticsHelper14 === void 0 ? void 0 : _this$analyticsHelper14.sendActionEvent(_const.EVENT_ACTION.PUBLISH_PAGE, _const.EVENT_STATUS.SUCCESS, {
310
- latency: measure === null || measure === void 0 ? void 0 : measure.duration
311
- });
312
- return _context3.abrupt("return", currentState);
313
- case 12:
314
- _context3.prev = 12;
315
- _context3.t0 = _context3["catch"](0);
316
- _measure2 = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
317
- (_this$analyticsHelper15 = _this.analyticsHelper) === null || _this$analyticsHelper15 === void 0 ? void 0 : _this$analyticsHelper15.sendActionEvent(_const.EVENT_ACTION.PUBLISH_PAGE, _const.EVENT_STATUS.FAILURE, {
318
- latency: _measure2 === null || _measure2 === void 0 ? void 0 : _measure2.duration
319
- });
320
- (_this$analyticsHelper16 = _this.analyticsHelper) === null || _this$analyticsHelper16 === void 0 ? void 0 : _this$analyticsHelper16.sendErrorEvent(_context3.t0, 'Error while returning ADF version of the final draft document');
321
- throw _context3.t0;
322
- case 18:
323
- case "end":
324
- return _context3.stop();
325
- }
281
+ while (1) switch (_context3.prev = _context3.next) {
282
+ case 0:
283
+ _context3.prev = 0;
284
+ (0, _performance.startMeasure)(_performance.MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
285
+ _context3.next = 4;
286
+ return _this.commitUnconfirmedSteps();
287
+ case 4:
288
+ _context3.next = 6;
289
+ return _this.getCurrentState();
290
+ case 6:
291
+ currentState = _context3.sent;
292
+ measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
293
+ (_this$analyticsHelper14 = _this.analyticsHelper) === null || _this$analyticsHelper14 === void 0 ? void 0 : _this$analyticsHelper14.sendActionEvent(_const.EVENT_ACTION.PUBLISH_PAGE, _const.EVENT_STATUS.SUCCESS, {
294
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration
295
+ });
296
+ return _context3.abrupt("return", currentState);
297
+ case 12:
298
+ _context3.prev = 12;
299
+ _context3.t0 = _context3["catch"](0);
300
+ _measure2 = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
301
+ (_this$analyticsHelper15 = _this.analyticsHelper) === null || _this$analyticsHelper15 === void 0 ? void 0 : _this$analyticsHelper15.sendActionEvent(_const.EVENT_ACTION.PUBLISH_PAGE, _const.EVENT_STATUS.FAILURE, {
302
+ latency: _measure2 === null || _measure2 === void 0 ? void 0 : _measure2.duration
303
+ });
304
+ (_this$analyticsHelper16 = _this.analyticsHelper) === null || _this$analyticsHelper16 === void 0 ? void 0 : _this$analyticsHelper16.sendErrorEvent(_context3.t0, 'Error while returning ADF version of the final draft document');
305
+ throw _context3.t0;
306
+ case 18:
307
+ case "end":
308
+ return _context3.stop();
326
309
  }
327
310
  }, _callee3, null, [[0, 12]]);
328
311
  })));
329
- (0, _defineProperty2.default)(this, "commitUnconfirmedSteps", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
330
- var unconfirmedSteps, _this$analyticsHelper18, _this$analyticsHelper19, measure;
331
- return _regenerator.default.wrap(function _callee5$(_context5) {
332
- while (1) {
333
- switch (_context5.prev = _context5.next) {
334
- case 0:
335
- unconfirmedSteps = _this.getUnconfirmedSteps();
336
- _context5.prev = 1;
337
- if (!(unconfirmedSteps !== null && unconfirmedSteps !== void 0 && unconfirmedSteps.length)) {
338
- _context5.next = 4;
339
- break;
340
- }
341
- return _context5.delegateYield( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
342
- var _this$analyticsHelper17;
343
- var count, unconfirmedTrs, lastTr, isLastTrConfirmed, nextUnconfirmedSteps, nextUnconfirmedTrs, state, measure;
344
- return _regenerator.default.wrap(function _callee4$(_context4) {
345
- while (1) {
346
- switch (_context4.prev = _context4.next) {
347
- case 0:
348
- (0, _performance.startMeasure)(_performance.MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, _this.analyticsHelper);
349
- count = 0; // We use origins here as steps can be rebased. When steps are rebased a new step is created.
350
- // This means that we can not track if it has been removed from the unconfirmed array or not.
351
- // Origins points to the original transaction that the step was created in. This is never changed
352
- // and gets passed down when a step is rebased.
353
- unconfirmedTrs = _this.getUnconfirmedStepsOrigins();
354
- lastTr = unconfirmedTrs === null || unconfirmedTrs === void 0 ? void 0 : unconfirmedTrs[unconfirmedTrs.length - 1];
355
- isLastTrConfirmed = false;
356
- case 5:
357
- if (isLastTrConfirmed) {
358
- _context4.next = 16;
359
- break;
360
- }
361
- _this.sendStepsFromCurrentState();
362
- _context4.next = 9;
363
- return (0, _utils.sleep)(1000);
364
- case 9:
365
- nextUnconfirmedSteps = _this.getUnconfirmedSteps();
366
- if (nextUnconfirmedSteps !== null && nextUnconfirmedSteps !== void 0 && nextUnconfirmedSteps.length) {
367
- nextUnconfirmedTrs = _this.getUnconfirmedStepsOrigins();
368
- isLastTrConfirmed = !(nextUnconfirmedTrs !== null && nextUnconfirmedTrs !== void 0 && nextUnconfirmedTrs.some(function (tr) {
369
- return tr === lastTr;
370
- }));
371
- } else {
372
- isLastTrConfirmed = true;
373
- }
374
- if (!(!isLastTrConfirmed && count++ >= _const.ACK_MAX_TRY)) {
375
- _context4.next = 14;
376
- break;
377
- }
378
- if (_this.onSyncUpError) {
379
- state = _this.getState();
380
- _this.onSyncUpError({
381
- lengthOfUnconfirmedSteps: nextUnconfirmedSteps === null || nextUnconfirmedSteps === void 0 ? void 0 : nextUnconfirmedSteps.length,
382
- tries: count,
383
- maxRetries: _const.ACK_MAX_TRY,
384
- clientId: _this.clientId,
385
- version: (0, _prosemirrorCollab.getVersion)(state)
386
- });
387
- }
388
- throw new Error("Can't sync up with Collab Service");
389
- case 14:
390
- _context4.next = 5;
391
- break;
392
- case 16:
393
- measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, _this.analyticsHelper);
394
- (_this$analyticsHelper17 = _this.analyticsHelper) === null || _this$analyticsHelper17 === void 0 ? void 0 : _this$analyticsHelper17.sendActionEvent(_const.EVENT_ACTION.COMMIT_UNCONFIRMED_STEPS, _const.EVENT_STATUS.SUCCESS, {
395
- latency: measure === null || measure === void 0 ? void 0 : measure.duration,
396
- // upon success, emit the total number of unconfirmed steps we synced
397
- numUnconfirmedSteps: unconfirmedSteps === null || unconfirmedSteps === void 0 ? void 0 : unconfirmedSteps.length
398
- });
399
- case 18:
400
- case "end":
401
- return _context4.stop();
402
- }
403
- }
404
- }, _callee4);
405
- })(), "t0", 4);
406
- case 4:
407
- _context5.next = 12;
312
+ (0, _defineProperty2.default)(this, "updateDocument", function (_ref6) {
313
+ var doc = _ref6.doc,
314
+ version = _ref6.version,
315
+ metadata = _ref6.metadata,
316
+ reserveCursor = _ref6.reserveCursor;
317
+ _this.providerEmitCallback('init', _objectSpread({
318
+ doc: doc,
319
+ version: version,
320
+ metadata: metadata
321
+ }, reserveCursor ? {
322
+ reserveCursor: reserveCursor
323
+ } : {}));
324
+ });
325
+ /**
326
+ * Commit the unconfirmed local steps to the back-end service
327
+ * @throws {Error} Couldn't sync the steps after retrying 30 times
328
+ */
329
+ (0, _defineProperty2.default)(this, "commitUnconfirmedSteps", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
330
+ var unconfirmedSteps, _this$analyticsHelper17, count, unconfirmedTrs, lastTr, isLastTrConfirmed, nextUnconfirmedSteps, nextUnconfirmedTrs, state, measure, _this$analyticsHelper18, _this$analyticsHelper19, _measure3;
331
+ return _regenerator.default.wrap(function _callee4$(_context4) {
332
+ while (1) switch (_context4.prev = _context4.next) {
333
+ case 0:
334
+ unconfirmedSteps = _this.getUnconfirmedSteps();
335
+ _context4.prev = 1;
336
+ if (!(unconfirmedSteps !== null && unconfirmedSteps !== void 0 && unconfirmedSteps.length)) {
337
+ _context4.next = 21;
338
+ break;
339
+ }
340
+ (0, _performance.startMeasure)(_performance.MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, _this.analyticsHelper);
341
+ count = 0; // We use origins here as steps can be rebased. When steps are rebased a new step is created.
342
+ // This means that we can not track if it has been removed from the unconfirmed array or not.
343
+ // Origins points to the original transaction that the step was created in. This is never changed
344
+ // and gets passed down when a step is rebased.
345
+ unconfirmedTrs = _this.getUnconfirmedStepsOrigins();
346
+ lastTr = unconfirmedTrs === null || unconfirmedTrs === void 0 ? void 0 : unconfirmedTrs[unconfirmedTrs.length - 1];
347
+ isLastTrConfirmed = false;
348
+ case 8:
349
+ if (isLastTrConfirmed) {
350
+ _context4.next = 19;
351
+ break;
352
+ }
353
+ _this.sendStepsFromCurrentState();
354
+ _context4.next = 12;
355
+ return (0, _utils.sleep)(1000);
356
+ case 12:
357
+ nextUnconfirmedSteps = _this.getUnconfirmedSteps();
358
+ if (nextUnconfirmedSteps !== null && nextUnconfirmedSteps !== void 0 && nextUnconfirmedSteps.length) {
359
+ nextUnconfirmedTrs = _this.getUnconfirmedStepsOrigins();
360
+ isLastTrConfirmed = !(nextUnconfirmedTrs !== null && nextUnconfirmedTrs !== void 0 && nextUnconfirmedTrs.some(function (tr) {
361
+ return tr === lastTr;
362
+ }));
363
+ } else {
364
+ isLastTrConfirmed = true;
365
+ }
366
+ if (!(!isLastTrConfirmed && count++ >= _const.ACK_MAX_TRY)) {
367
+ _context4.next = 17;
408
368
  break;
409
- case 6:
410
- _context5.prev = 6;
411
- _context5.t1 = _context5["catch"](1);
412
- measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, _this.analyticsHelper);
413
- (_this$analyticsHelper18 = _this.analyticsHelper) === null || _this$analyticsHelper18 === void 0 ? void 0 : _this$analyticsHelper18.sendActionEvent(_const.EVENT_ACTION.COMMIT_UNCONFIRMED_STEPS, _const.EVENT_STATUS.FAILURE, {
414
- latency: measure === null || measure === void 0 ? void 0 : measure.duration,
415
- numUnconfirmedSteps: unconfirmedSteps === null || unconfirmedSteps === void 0 ? void 0 : unconfirmedSteps.length
369
+ }
370
+ if (_this.onSyncUpError) {
371
+ state = _this.getState();
372
+ _this.onSyncUpError({
373
+ lengthOfUnconfirmedSteps: nextUnconfirmedSteps === null || nextUnconfirmedSteps === void 0 ? void 0 : nextUnconfirmedSteps.length,
374
+ tries: count,
375
+ maxRetries: _const.ACK_MAX_TRY,
376
+ clientId: _this.clientId,
377
+ version: (0, _prosemirrorCollab.getVersion)(state)
416
378
  });
417
- (_this$analyticsHelper19 = _this.analyticsHelper) === null || _this$analyticsHelper19 === void 0 ? void 0 : _this$analyticsHelper19.sendErrorEvent(_context5.t1, 'Error while committing unconfirmed steps');
418
- throw _context5.t1;
419
- case 12:
420
- case "end":
421
- return _context5.stop();
422
- }
379
+ }
380
+ throw new Error("Can't sync up with Collab Service");
381
+ case 17:
382
+ _context4.next = 8;
383
+ break;
384
+ case 19:
385
+ measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, _this.analyticsHelper);
386
+ (_this$analyticsHelper17 = _this.analyticsHelper) === null || _this$analyticsHelper17 === void 0 ? void 0 : _this$analyticsHelper17.sendActionEvent(_const.EVENT_ACTION.COMMIT_UNCONFIRMED_STEPS, _const.EVENT_STATUS.SUCCESS, {
387
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration,
388
+ // upon success, emit the total number of unconfirmed steps we synced
389
+ numUnconfirmedSteps: unconfirmedSteps === null || unconfirmedSteps === void 0 ? void 0 : unconfirmedSteps.length
390
+ });
391
+ case 21:
392
+ _context4.next = 29;
393
+ break;
394
+ case 23:
395
+ _context4.prev = 23;
396
+ _context4.t0 = _context4["catch"](1);
397
+ _measure3 = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, _this.analyticsHelper);
398
+ (_this$analyticsHelper18 = _this.analyticsHelper) === null || _this$analyticsHelper18 === void 0 ? void 0 : _this$analyticsHelper18.sendActionEvent(_const.EVENT_ACTION.COMMIT_UNCONFIRMED_STEPS, _const.EVENT_STATUS.FAILURE, {
399
+ latency: _measure3 === null || _measure3 === void 0 ? void 0 : _measure3.duration,
400
+ numUnconfirmedSteps: unconfirmedSteps === null || unconfirmedSteps === void 0 ? void 0 : unconfirmedSteps.length
401
+ });
402
+ (_this$analyticsHelper19 = _this.analyticsHelper) === null || _this$analyticsHelper19 === void 0 ? void 0 : _this$analyticsHelper19.sendErrorEvent(_context4.t0, 'Error while committing unconfirmed steps');
403
+ throw _context4.t0;
404
+ case 29:
405
+ case "end":
406
+ return _context4.stop();
423
407
  }
424
- }, _callee5, null, [[1, 6]]);
408
+ }, _callee4, null, [[1, 23]]);
425
409
  })));
426
410
  (0, _defineProperty2.default)(this, "onStepRejectedError", function () {
427
411
  _this.stepRejectCounter++;
@@ -443,56 +427,13 @@ var DocumentService = /*#__PURE__*/function () {
443
427
  this.analyticsHelper = analyticsHelper;
444
428
  this.fetchCatchup = fetchCatchup;
445
429
  this.providerEmitCallback = providerEmitCallback;
446
- this.broadcastMetadata = broadcastMetadata;
447
430
  this.broadcast = broadcast;
448
431
  this.getUserId = getUserId;
449
432
  this.onErrorHandled = onErrorHandled;
433
+ this.metadataService = metadataService;
450
434
  this.stepQueue = new _stepQueueState.StepQueueState();
451
435
  }
452
-
453
- /**
454
- * Called when a metadata is changed externally from other clients/backend.
455
- */
456
436
  (0, _createClass2.default)(DocumentService, [{
457
- key: "setTitle",
458
- value: function setTitle(title, broadcast) {
459
- if (broadcast) {
460
- this.broadcastMetadata({
461
- title: title
462
- });
463
- }
464
- Object.assign(this.metadata, {
465
- title: title
466
- });
467
- }
468
- }, {
469
- key: "setEditorWidth",
470
- value: function setEditorWidth(editorWidth, broadcast) {
471
- if (broadcast) {
472
- this.broadcastMetadata({
473
- editorWidth: editorWidth
474
- });
475
- }
476
- Object.assign(this.metadata, {
477
- editorWidth: editorWidth
478
- });
479
- }
480
-
481
- /**
482
- * Updates the local metadata and broadcasts the metadata to other clients/backend.
483
- * @param metadata
484
- */
485
- }, {
486
- key: "setMetadata",
487
- value: function setMetadata(metadata) {
488
- this.broadcastMetadata(metadata);
489
- Object.assign(this.metadata, metadata);
490
- }
491
-
492
- /**
493
- * To prevent calling catchup to often, use lodash throttle to reduce the frequency
494
- */
495
- }, {
496
437
  key: "processQueue",
497
438
  value: function processQueue() {
498
439
  if (this.stepQueue.isPaused()) {
@@ -600,7 +541,7 @@ var DocumentService = /*#__PURE__*/function () {
600
541
  // Avoid reference issues using a
601
542
  // method outside of the provider
602
543
  // scope
603
- (0, _provider.throttledCommitStep)({
544
+ (0, _commitStep.throttledCommitStep)({
604
545
  broadcast: this.broadcast,
605
546
  userId: this.getUserId(),
606
547
  clientId: this.clientId,
@@ -23,6 +23,10 @@ var StepQueueState = /*#__PURE__*/function () {
23
23
  (0, _defineProperty2.default)(this, "filterQueue", function (condition) {
24
24
  _this.queue = _this.queue.filter(condition);
25
25
  });
26
+ /**
27
+ * Get whether the document service has stopped processing new steps whilst it carries out processes such as catchup.
28
+ * Exposed for testing
29
+ */
26
30
  (0, _defineProperty2.default)(this, "isPaused", function () {
27
31
  return _this.queuePaused;
28
32
  });