@atlaskit/collab-provider 9.0.1 → 9.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @atlaskit/collab-provider
2
2
 
3
+ ## 9.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`2c0c19cc14b`](https://bitbucket.org/atlassian/atlassian-frontend/commits/2c0c19cc14b) - ESS-3609: add step commit status events for confl save indicator feature
8
+ - [`470c3a7e8c6`](https://bitbucket.org/atlassian/atlassian-frontend/commits/470c3a7e8c6) - ESS-3644: allow max steps retry param to be passed thru collab provider to allow getFinalAcknowledgeState to catch up sooner on publish
9
+
3
10
  ## 9.0.1
4
11
 
5
12
  ### Patch Changes
@@ -37,16 +37,19 @@ var DocumentService = /*#__PURE__*/function () {
37
37
  * @param analyticsHelper - Helper for analytics events
38
38
  * @param fetchCatchup - Function to fetch "catchup" data, data required to rebase current steps to the latest version.
39
39
  * @param providerEmitCallback - Callback for emitting events to listeners on the provider
40
- * @param broadcastMetadata - Callback for broadcasting metadata changes to other clients
41
40
  * @param broadcast - Callback for broadcasting events to other clients
42
41
  * @param getUserId - Callback to fetch the current user's ID
43
42
  * @param onErrorHandled - Callback to handle
43
+ * @param metadataService
44
+ * @param failedStepsBeforeCatchupOnPublish - Control MAX_STEP_REJECTED_ERROR during page publishes.
44
45
  */
45
46
  function DocumentService(participantsService, analyticsHelper, fetchCatchup, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService) {
46
47
  var _this = this;
48
+ var failedStepsBeforeCatchupOnPublish = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : _provider.MAX_STEP_REJECTED_ERROR;
47
49
  (0, _classCallCheck2.default)(this, DocumentService);
48
50
  // Fires analytics to editor when collab editor cannot sync up
49
51
  (0, _defineProperty2.default)(this, "stepRejectCounter", 0);
52
+ (0, _defineProperty2.default)(this, "aggressiveCatchup", false);
50
53
  /**
51
54
  * To prevent calling catchup to often, use lodash throttle to reduce the frequency
52
55
  */
@@ -281,34 +284,37 @@ var DocumentService = /*#__PURE__*/function () {
281
284
  return _regenerator.default.wrap(function _callee3$(_context3) {
282
285
  while (1) switch (_context3.prev = _context3.next) {
283
286
  case 0:
284
- _context3.prev = 0;
287
+ _this.aggressiveCatchup = true;
288
+ _context3.prev = 1;
285
289
  (0, _performance.startMeasure)(_performance.MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
286
- _context3.next = 4;
290
+ _context3.next = 5;
287
291
  return _this.commitUnconfirmedSteps();
288
- case 4:
289
- _context3.next = 6;
292
+ case 5:
293
+ _context3.next = 7;
290
294
  return _this.getCurrentState();
291
- case 6:
295
+ case 7:
292
296
  currentState = _context3.sent;
293
297
  measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
294
298
  (_this$analyticsHelper14 = _this.analyticsHelper) === null || _this$analyticsHelper14 === void 0 ? void 0 : _this$analyticsHelper14.sendActionEvent(_const.EVENT_ACTION.PUBLISH_PAGE, _const.EVENT_STATUS.SUCCESS, {
295
299
  latency: measure === null || measure === void 0 ? void 0 : measure.duration
296
300
  });
301
+ _this.aggressiveCatchup = false;
297
302
  return _context3.abrupt("return", currentState);
298
- case 12:
299
- _context3.prev = 12;
300
- _context3.t0 = _context3["catch"](0);
303
+ case 14:
304
+ _context3.prev = 14;
305
+ _context3.t0 = _context3["catch"](1);
306
+ _this.aggressiveCatchup = false;
301
307
  _measure2 = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
302
308
  (_this$analyticsHelper15 = _this.analyticsHelper) === null || _this$analyticsHelper15 === void 0 ? void 0 : _this$analyticsHelper15.sendActionEvent(_const.EVENT_ACTION.PUBLISH_PAGE, _const.EVENT_STATUS.FAILURE, {
303
309
  latency: _measure2 === null || _measure2 === void 0 ? void 0 : _measure2.duration
304
310
  });
305
311
  (_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');
306
312
  throw _context3.t0;
307
- case 18:
313
+ case 21:
308
314
  case "end":
309
315
  return _context3.stop();
310
316
  }
311
- }, _callee3, null, [[0, 12]]);
317
+ }, _callee3, null, [[1, 14]]);
312
318
  })));
313
319
  (0, _defineProperty2.default)(this, "updateDocument", function (_ref6) {
314
320
  var doc = _ref6.doc,
@@ -409,10 +415,17 @@ var DocumentService = /*#__PURE__*/function () {
409
415
  }, _callee4, null, [[1, 23]]);
410
416
  })));
411
417
  (0, _defineProperty2.default)(this, "onStepRejectedError", function () {
418
+ var _this$analyticsHelper20;
412
419
  _this.stepRejectCounter++;
413
420
  logger("Steps rejected (tries=".concat(_this.stepRejectCounter, ")"));
414
- if (_this.stepRejectCounter >= _provider.MAX_STEP_REJECTED_ERROR) {
421
+ (_this$analyticsHelper20 = _this.analyticsHelper) === null || _this$analyticsHelper20 === void 0 ? void 0 : _this$analyticsHelper20.sendActionEvent(_const.EVENT_ACTION.SEND_STEPS_RETRY, _const.EVENT_STATUS.INFO, {
422
+ count: _this.stepRejectCounter
423
+ });
424
+ var maxRetries = _this.aggressiveCatchup ? _this.failedStepsBeforeCatchupOnPublish : _provider.MAX_STEP_REJECTED_ERROR;
425
+ if (_this.stepRejectCounter >= maxRetries) {
426
+ var _this$analyticsHelper21;
415
427
  logger("The steps were rejected too many times (tries=".concat(_this.stepRejectCounter, ", limit=").concat(_provider.MAX_STEP_REJECTED_ERROR, "). Trying to catch-up."));
428
+ (_this$analyticsHelper21 = _this.analyticsHelper) === null || _this$analyticsHelper21 === void 0 ? void 0 : _this$analyticsHelper21.sendActionEvent(_const.EVENT_ACTION.CATCHUP_AFTER_MAX_SEND_STEPS_RETRY, _const.EVENT_STATUS.INFO);
416
429
  _this.throttledCatchup();
417
430
  } else {
418
431
  // If committing steps failed try again automatically in 1s
@@ -432,6 +445,7 @@ var DocumentService = /*#__PURE__*/function () {
432
445
  this.getUserId = getUserId;
433
446
  this.onErrorHandled = onErrorHandled;
434
447
  this.metadataService = metadataService;
448
+ this.failedStepsBeforeCatchupOnPublish = failedStepsBeforeCatchupOnPublish;
435
449
  this.stepQueue = new _stepQueueState.StepQueueState();
436
450
  }
437
451
  (0, _createClass2.default)(DocumentService, [{
@@ -483,9 +497,9 @@ var DocumentService = /*#__PURE__*/function () {
483
497
  }, 100);
484
498
  }
485
499
  } catch (error) {
486
- var _this$analyticsHelper20;
500
+ var _this$analyticsHelper22;
487
501
  logger("Processing steps failed with error: ".concat(error, ". Triggering catch up call."));
488
- (_this$analyticsHelper20 = this.analyticsHelper) === null || _this$analyticsHelper20 === void 0 ? void 0 : _this$analyticsHelper20.sendErrorEvent(error, 'Error while processing steps');
502
+ (_this$analyticsHelper22 = this.analyticsHelper) === null || _this$analyticsHelper22 === void 0 ? void 0 : _this$analyticsHelper22.sendErrorEvent(error, 'Error while processing steps');
489
503
  this.throttledCatchup();
490
504
  }
491
505
  }
@@ -550,7 +564,8 @@ var DocumentService = /*#__PURE__*/function () {
550
564
  version: version,
551
565
  onStepsAdded: this.onStepsAdded,
552
566
  onErrorHandled: this.onErrorHandled,
553
- analyticsHelper: this.analyticsHelper
567
+ analyticsHelper: this.analyticsHelper,
568
+ emit: this.providerEmitCallback
554
569
  });
555
570
  }
556
571
  }]);
@@ -16,6 +16,8 @@ var EVENT_ACTION = /*#__PURE__*/function (EVENT_ACTION) {
16
16
  EVENT_ACTION["PUBLISH_PAGE"] = "publishPage";
17
17
  EVENT_ACTION["GET_CURRENT_STATE"] = "getCurrentState";
18
18
  EVENT_ACTION["INVALIDATE_TOKEN"] = "invalidateToken";
19
+ EVENT_ACTION["SEND_STEPS_RETRY"] = "sendStepsRetry";
20
+ EVENT_ACTION["CATCHUP_AFTER_MAX_SEND_STEPS_RETRY"] = "catchupAfterMaxSendStepsRetry";
19
21
  EVENT_ACTION["DROPPED_STEPS"] = "droppedStepInCatchup";
20
22
  return EVENT_ACTION;
21
23
  }({});
@@ -23,6 +25,7 @@ exports.EVENT_ACTION = EVENT_ACTION;
23
25
  var EVENT_STATUS = /*#__PURE__*/function (EVENT_STATUS) {
24
26
  EVENT_STATUS["SUCCESS"] = "SUCCESS";
25
27
  EVENT_STATUS["FAILURE"] = "FAILURE";
28
+ EVENT_STATUS["INFO"] = "INFO";
26
29
  return EVENT_STATUS;
27
30
  }({});
28
31
  exports.EVENT_STATUS = EVENT_STATUS;
@@ -23,7 +23,8 @@ var commitStep = function commitStep(_ref) {
23
23
  clientId = _ref.clientId,
24
24
  onStepsAdded = _ref.onStepsAdded,
25
25
  onErrorHandled = _ref.onErrorHandled,
26
- analyticsHelper = _ref.analyticsHelper;
26
+ analyticsHelper = _ref.analyticsHelper,
27
+ emit = _ref.emit;
27
28
  var stepsWithClientAndUserId = steps.map(function (step) {
28
29
  return _objectSpread(_objectSpread({}, step.toJSON()), {}, {
29
30
  clientId: clientId,
@@ -31,6 +32,10 @@ var commitStep = function commitStep(_ref) {
31
32
  });
32
33
  });
33
34
  var start = new Date().getTime();
35
+ emit('commit-status', {
36
+ status: 'attempt',
37
+ version: version
38
+ });
34
39
  try {
35
40
  broadcast('steps:commit', {
36
41
  steps: stepsWithClientAndUserId,
@@ -50,6 +55,10 @@ var commitStep = function commitStep(_ref) {
50
55
  return stepWithClientAndUserId.stepType;
51
56
  })
52
57
  });
58
+ emit('commit-status', {
59
+ status: 'success',
60
+ version: response.version
61
+ });
53
62
  } else if (response.type === _types.AcknowledgementResponseTypes.ERROR) {
54
63
  onErrorHandled(response.error);
55
64
  analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendActionEvent(_const.EVENT_ACTION.ADD_STEPS, _const.EVENT_STATUS.FAILURE, {
@@ -60,14 +69,26 @@ var commitStep = function commitStep(_ref) {
60
69
  latency: latency
61
70
  });
62
71
  analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(response.error, 'Error while adding steps - Acknowledgement Error');
72
+ emit('commit-status', {
73
+ status: 'failure',
74
+ version: version
75
+ });
63
76
  } else {
64
77
  analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(
65
78
  // @ts-expect-error We didn't type the invalid type case
66
79
  new Error("Response type: ".concat((response === null || response === void 0 ? void 0 : response.type) || 'No response type')), 'Error while adding steps - Invalid Acknowledgement');
80
+ emit('commit-status', {
81
+ status: 'failure',
82
+ version: version
83
+ });
67
84
  }
68
85
  });
69
86
  } catch (error) {
70
87
  analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(error, 'Error while adding steps - Broadcast threw exception');
88
+ emit('commit-status', {
89
+ status: 'failure',
90
+ version: version
91
+ });
71
92
  }
72
93
  };
73
94
  exports.commitStep = commitStep;
@@ -229,7 +229,7 @@ var Provider = /*#__PURE__*/function (_Emitter) {
229
229
  _this.metadataService = new _metadataService.MetadataService(_this.emitCallback, _this.channel.sendMetadata);
230
230
  _this.documentService = new _documentService.DocumentService(_this.participantsService, _this.analyticsHelper, _this.channel.fetchCatchup, _this.emitCallback, _this.channel.broadcast, function () {
231
231
  return _this.userId;
232
- }, _this.onErrorHandled, _this.metadataService);
232
+ }, _this.onErrorHandled, _this.metadataService, _this.config.failedStepLimitBeforeCatchupOnPublish);
233
233
  _this.getStatePromise = new Promise(function (resolve) {
234
234
  _this.getStatePromiseResolve = resolve;
235
235
  });
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.version = exports.nextMajorVersion = exports.name = void 0;
7
7
  var name = "@atlaskit/collab-provider";
8
8
  exports.name = name;
9
- var version = "9.0.1";
9
+ var version = "9.1.0";
10
10
  exports.version = version;
11
11
  var nextMajorVersion = function nextMajorVersion() {
12
12
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/collab-provider",
3
- "version": "9.0.1",
3
+ "version": "9.1.0",
4
4
  "sideEffects": false
5
5
  }
@@ -24,14 +24,16 @@ export class DocumentService {
24
24
  * @param analyticsHelper - Helper for analytics events
25
25
  * @param fetchCatchup - Function to fetch "catchup" data, data required to rebase current steps to the latest version.
26
26
  * @param providerEmitCallback - Callback for emitting events to listeners on the provider
27
- * @param broadcastMetadata - Callback for broadcasting metadata changes to other clients
28
27
  * @param broadcast - Callback for broadcasting events to other clients
29
28
  * @param getUserId - Callback to fetch the current user's ID
30
29
  * @param onErrorHandled - Callback to handle
30
+ * @param metadataService
31
+ * @param failedStepsBeforeCatchupOnPublish - Control MAX_STEP_REJECTED_ERROR during page publishes.
31
32
  */
32
- constructor(participantsService, analyticsHelper, fetchCatchup, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService) {
33
+ constructor(participantsService, analyticsHelper, fetchCatchup, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService, failedStepsBeforeCatchupOnPublish = MAX_STEP_REJECTED_ERROR) {
33
34
  // Fires analytics to editor when collab editor cannot sync up
34
35
  _defineProperty(this, "stepRejectCounter", 0);
36
+ _defineProperty(this, "aggressiveCatchup", false);
35
37
  /**
36
38
  * To prevent calling catchup to often, use lodash throttle to reduce the frequency
37
39
  */
@@ -236,6 +238,7 @@ export class DocumentService {
236
238
  }
237
239
  });
238
240
  _defineProperty(this, "getFinalAcknowledgedState", async () => {
241
+ this.aggressiveCatchup = true;
239
242
  try {
240
243
  var _this$analyticsHelper14;
241
244
  startMeasure(MEASURE_NAME.PUBLISH_PAGE, this.analyticsHelper);
@@ -245,9 +248,11 @@ export class DocumentService {
245
248
  (_this$analyticsHelper14 = this.analyticsHelper) === null || _this$analyticsHelper14 === void 0 ? void 0 : _this$analyticsHelper14.sendActionEvent(EVENT_ACTION.PUBLISH_PAGE, EVENT_STATUS.SUCCESS, {
246
249
  latency: measure === null || measure === void 0 ? void 0 : measure.duration
247
250
  });
251
+ this.aggressiveCatchup = false;
248
252
  return currentState;
249
253
  } catch (error) {
250
254
  var _this$analyticsHelper15, _this$analyticsHelper16;
255
+ this.aggressiveCatchup = false;
251
256
  const measure = stopMeasure(MEASURE_NAME.PUBLISH_PAGE, this.analyticsHelper);
252
257
  (_this$analyticsHelper15 = this.analyticsHelper) === null || _this$analyticsHelper15 === void 0 ? void 0 : _this$analyticsHelper15.sendActionEvent(EVENT_ACTION.PUBLISH_PAGE, EVENT_STATUS.FAILURE, {
253
258
  latency: measure === null || measure === void 0 ? void 0 : measure.duration
@@ -332,10 +337,17 @@ export class DocumentService {
332
337
  }
333
338
  });
334
339
  _defineProperty(this, "onStepRejectedError", () => {
340
+ var _this$analyticsHelper20;
335
341
  this.stepRejectCounter++;
336
342
  logger(`Steps rejected (tries=${this.stepRejectCounter})`);
337
- if (this.stepRejectCounter >= MAX_STEP_REJECTED_ERROR) {
343
+ (_this$analyticsHelper20 = this.analyticsHelper) === null || _this$analyticsHelper20 === void 0 ? void 0 : _this$analyticsHelper20.sendActionEvent(EVENT_ACTION.SEND_STEPS_RETRY, EVENT_STATUS.INFO, {
344
+ count: this.stepRejectCounter
345
+ });
346
+ let maxRetries = this.aggressiveCatchup ? this.failedStepsBeforeCatchupOnPublish : MAX_STEP_REJECTED_ERROR;
347
+ if (this.stepRejectCounter >= maxRetries) {
348
+ var _this$analyticsHelper21;
338
349
  logger(`The steps were rejected too many times (tries=${this.stepRejectCounter}, limit=${MAX_STEP_REJECTED_ERROR}). Trying to catch-up.`);
350
+ (_this$analyticsHelper21 = this.analyticsHelper) === null || _this$analyticsHelper21 === void 0 ? void 0 : _this$analyticsHelper21.sendActionEvent(EVENT_ACTION.CATCHUP_AFTER_MAX_SEND_STEPS_RETRY, EVENT_STATUS.INFO);
339
351
  this.throttledCatchup();
340
352
  } else {
341
353
  // If committing steps failed try again automatically in 1s
@@ -353,6 +365,7 @@ export class DocumentService {
353
365
  this.getUserId = getUserId;
354
366
  this.onErrorHandled = onErrorHandled;
355
367
  this.metadataService = metadataService;
368
+ this.failedStepsBeforeCatchupOnPublish = failedStepsBeforeCatchupOnPublish;
356
369
  this.stepQueue = new StepQueueState();
357
370
  }
358
371
  processQueue() {
@@ -398,9 +411,9 @@ export class DocumentService {
398
411
  setTimeout(() => this.sendStepsFromCurrentState(), 100);
399
412
  }
400
413
  } catch (error) {
401
- var _this$analyticsHelper20;
414
+ var _this$analyticsHelper22;
402
415
  logger(`Processing steps failed with error: ${error}. Triggering catch up call.`);
403
- (_this$analyticsHelper20 = this.analyticsHelper) === null || _this$analyticsHelper20 === void 0 ? void 0 : _this$analyticsHelper20.sendErrorEvent(error, 'Error while processing steps');
416
+ (_this$analyticsHelper22 = this.analyticsHelper) === null || _this$analyticsHelper22 === void 0 ? void 0 : _this$analyticsHelper22.sendErrorEvent(error, 'Error while processing steps');
404
417
  this.throttledCatchup();
405
418
  }
406
419
  }
@@ -459,7 +472,8 @@ export class DocumentService {
459
472
  version,
460
473
  onStepsAdded: this.onStepsAdded,
461
474
  onErrorHandled: this.onErrorHandled,
462
- analyticsHelper: this.analyticsHelper
475
+ analyticsHelper: this.analyticsHelper,
476
+ emit: this.providerEmitCallback
463
477
  });
464
478
  }
465
479
  }
@@ -10,12 +10,15 @@ export let EVENT_ACTION = /*#__PURE__*/function (EVENT_ACTION) {
10
10
  EVENT_ACTION["PUBLISH_PAGE"] = "publishPage";
11
11
  EVENT_ACTION["GET_CURRENT_STATE"] = "getCurrentState";
12
12
  EVENT_ACTION["INVALIDATE_TOKEN"] = "invalidateToken";
13
+ EVENT_ACTION["SEND_STEPS_RETRY"] = "sendStepsRetry";
14
+ EVENT_ACTION["CATCHUP_AFTER_MAX_SEND_STEPS_RETRY"] = "catchupAfterMaxSendStepsRetry";
13
15
  EVENT_ACTION["DROPPED_STEPS"] = "droppedStepInCatchup";
14
16
  return EVENT_ACTION;
15
17
  }({});
16
18
  export let EVENT_STATUS = /*#__PURE__*/function (EVENT_STATUS) {
17
19
  EVENT_STATUS["SUCCESS"] = "SUCCESS";
18
20
  EVENT_STATUS["FAILURE"] = "FAILURE";
21
+ EVENT_STATUS["INFO"] = "INFO";
19
22
  return EVENT_STATUS;
20
23
  }({});
21
24
  export let ADD_STEPS_TYPE = /*#__PURE__*/function (ADD_STEPS_TYPE) {
@@ -13,7 +13,8 @@ export const commitStep = ({
13
13
  clientId,
14
14
  onStepsAdded,
15
15
  onErrorHandled,
16
- analyticsHelper
16
+ analyticsHelper,
17
+ emit
17
18
  }) => {
18
19
  const stepsWithClientAndUserId = steps.map(step => ({
19
20
  ...step.toJSON(),
@@ -21,6 +22,10 @@ export const commitStep = ({
21
22
  userId
22
23
  }));
23
24
  const start = new Date().getTime();
25
+ emit('commit-status', {
26
+ status: 'attempt',
27
+ version
28
+ });
24
29
  try {
25
30
  broadcast('steps:commit', {
26
31
  steps: stepsWithClientAndUserId,
@@ -38,6 +43,10 @@ export const commitStep = ({
38
43
  latency,
39
44
  stepType: countBy(stepsWithClientAndUserId, stepWithClientAndUserId => stepWithClientAndUserId.stepType)
40
45
  });
46
+ emit('commit-status', {
47
+ status: 'success',
48
+ version: response.version
49
+ });
41
50
  } else if (response.type === AcknowledgementResponseTypes.ERROR) {
42
51
  onErrorHandled(response.error);
43
52
  analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendActionEvent(EVENT_ACTION.ADD_STEPS, EVENT_STATUS.FAILURE, {
@@ -48,14 +57,26 @@ export const commitStep = ({
48
57
  latency
49
58
  });
50
59
  analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(response.error, 'Error while adding steps - Acknowledgement Error');
60
+ emit('commit-status', {
61
+ status: 'failure',
62
+ version
63
+ });
51
64
  } else {
52
65
  analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(
53
66
  // @ts-expect-error We didn't type the invalid type case
54
67
  new Error(`Response type: ${(response === null || response === void 0 ? void 0 : response.type) || 'No response type'}`), 'Error while adding steps - Invalid Acknowledgement');
68
+ emit('commit-status', {
69
+ status: 'failure',
70
+ version
71
+ });
55
72
  }
56
73
  });
57
74
  } catch (error) {
58
75
  analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(error, 'Error while adding steps - Broadcast threw exception');
76
+ emit('commit-status', {
77
+ status: 'failure',
78
+ version
79
+ });
59
80
  }
60
81
  };
61
82
  export const throttledCommitStep = throttle(commitStep, SEND_STEPS_THROTTLE, {
@@ -183,7 +183,7 @@ export class Provider extends Emitter {
183
183
  this.isPreinitializing = false;
184
184
  this.participantsService = new ParticipantsService(this.analyticsHelper, undefined, this.emitCallback, this.config.getUser, this.channel.broadcast, this.channel.sendPresenceJoined, this.getPresenceData, this.setUserId);
185
185
  this.metadataService = new MetadataService(this.emitCallback, this.channel.sendMetadata);
186
- this.documentService = new DocumentService(this.participantsService, this.analyticsHelper, this.channel.fetchCatchup, this.emitCallback, this.channel.broadcast, () => this.userId, this.onErrorHandled, this.metadataService);
186
+ this.documentService = new DocumentService(this.participantsService, this.analyticsHelper, this.channel.fetchCatchup, this.emitCallback, this.channel.broadcast, () => this.userId, this.onErrorHandled, this.metadataService, this.config.failedStepLimitBeforeCatchupOnPublish);
187
187
  this.getStatePromise = new Promise(resolve => {
188
188
  this.getStatePromiseResolve = resolve;
189
189
  });
@@ -1,5 +1,5 @@
1
1
  export const name = "@atlaskit/collab-provider";
2
- export const version = "9.0.1";
2
+ export const version = "9.1.0";
3
3
  export const nextMajorVersion = () => {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/collab-provider",
3
- "version": "9.0.1",
3
+ "version": "9.1.0",
4
4
  "sideEffects": false
5
5
  }
@@ -30,16 +30,19 @@ export var DocumentService = /*#__PURE__*/function () {
30
30
  * @param analyticsHelper - Helper for analytics events
31
31
  * @param fetchCatchup - Function to fetch "catchup" data, data required to rebase current steps to the latest version.
32
32
  * @param providerEmitCallback - Callback for emitting events to listeners on the provider
33
- * @param broadcastMetadata - Callback for broadcasting metadata changes to other clients
34
33
  * @param broadcast - Callback for broadcasting events to other clients
35
34
  * @param getUserId - Callback to fetch the current user's ID
36
35
  * @param onErrorHandled - Callback to handle
36
+ * @param metadataService
37
+ * @param failedStepsBeforeCatchupOnPublish - Control MAX_STEP_REJECTED_ERROR during page publishes.
37
38
  */
38
39
  function DocumentService(participantsService, analyticsHelper, fetchCatchup, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService) {
39
40
  var _this = this;
41
+ var failedStepsBeforeCatchupOnPublish = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : MAX_STEP_REJECTED_ERROR;
40
42
  _classCallCheck(this, DocumentService);
41
43
  // Fires analytics to editor when collab editor cannot sync up
42
44
  _defineProperty(this, "stepRejectCounter", 0);
45
+ _defineProperty(this, "aggressiveCatchup", false);
43
46
  /**
44
47
  * To prevent calling catchup to often, use lodash throttle to reduce the frequency
45
48
  */
@@ -274,34 +277,37 @@ export var DocumentService = /*#__PURE__*/function () {
274
277
  return _regeneratorRuntime.wrap(function _callee3$(_context3) {
275
278
  while (1) switch (_context3.prev = _context3.next) {
276
279
  case 0:
277
- _context3.prev = 0;
280
+ _this.aggressiveCatchup = true;
281
+ _context3.prev = 1;
278
282
  startMeasure(MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
279
- _context3.next = 4;
283
+ _context3.next = 5;
280
284
  return _this.commitUnconfirmedSteps();
281
- case 4:
282
- _context3.next = 6;
285
+ case 5:
286
+ _context3.next = 7;
283
287
  return _this.getCurrentState();
284
- case 6:
288
+ case 7:
285
289
  currentState = _context3.sent;
286
290
  measure = stopMeasure(MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
287
291
  (_this$analyticsHelper14 = _this.analyticsHelper) === null || _this$analyticsHelper14 === void 0 ? void 0 : _this$analyticsHelper14.sendActionEvent(EVENT_ACTION.PUBLISH_PAGE, EVENT_STATUS.SUCCESS, {
288
292
  latency: measure === null || measure === void 0 ? void 0 : measure.duration
289
293
  });
294
+ _this.aggressiveCatchup = false;
290
295
  return _context3.abrupt("return", currentState);
291
- case 12:
292
- _context3.prev = 12;
293
- _context3.t0 = _context3["catch"](0);
296
+ case 14:
297
+ _context3.prev = 14;
298
+ _context3.t0 = _context3["catch"](1);
299
+ _this.aggressiveCatchup = false;
294
300
  _measure2 = stopMeasure(MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
295
301
  (_this$analyticsHelper15 = _this.analyticsHelper) === null || _this$analyticsHelper15 === void 0 ? void 0 : _this$analyticsHelper15.sendActionEvent(EVENT_ACTION.PUBLISH_PAGE, EVENT_STATUS.FAILURE, {
296
302
  latency: _measure2 === null || _measure2 === void 0 ? void 0 : _measure2.duration
297
303
  });
298
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');
299
305
  throw _context3.t0;
300
- case 18:
306
+ case 21:
301
307
  case "end":
302
308
  return _context3.stop();
303
309
  }
304
- }, _callee3, null, [[0, 12]]);
310
+ }, _callee3, null, [[1, 14]]);
305
311
  })));
306
312
  _defineProperty(this, "updateDocument", function (_ref6) {
307
313
  var doc = _ref6.doc,
@@ -402,10 +408,17 @@ export var DocumentService = /*#__PURE__*/function () {
402
408
  }, _callee4, null, [[1, 23]]);
403
409
  })));
404
410
  _defineProperty(this, "onStepRejectedError", function () {
411
+ var _this$analyticsHelper20;
405
412
  _this.stepRejectCounter++;
406
413
  logger("Steps rejected (tries=".concat(_this.stepRejectCounter, ")"));
407
- if (_this.stepRejectCounter >= MAX_STEP_REJECTED_ERROR) {
414
+ (_this$analyticsHelper20 = _this.analyticsHelper) === null || _this$analyticsHelper20 === void 0 ? void 0 : _this$analyticsHelper20.sendActionEvent(EVENT_ACTION.SEND_STEPS_RETRY, EVENT_STATUS.INFO, {
415
+ count: _this.stepRejectCounter
416
+ });
417
+ var maxRetries = _this.aggressiveCatchup ? _this.failedStepsBeforeCatchupOnPublish : MAX_STEP_REJECTED_ERROR;
418
+ if (_this.stepRejectCounter >= maxRetries) {
419
+ var _this$analyticsHelper21;
408
420
  logger("The steps were rejected too many times (tries=".concat(_this.stepRejectCounter, ", limit=").concat(MAX_STEP_REJECTED_ERROR, "). Trying to catch-up."));
421
+ (_this$analyticsHelper21 = _this.analyticsHelper) === null || _this$analyticsHelper21 === void 0 ? void 0 : _this$analyticsHelper21.sendActionEvent(EVENT_ACTION.CATCHUP_AFTER_MAX_SEND_STEPS_RETRY, EVENT_STATUS.INFO);
409
422
  _this.throttledCatchup();
410
423
  } else {
411
424
  // If committing steps failed try again automatically in 1s
@@ -425,6 +438,7 @@ export var DocumentService = /*#__PURE__*/function () {
425
438
  this.getUserId = getUserId;
426
439
  this.onErrorHandled = onErrorHandled;
427
440
  this.metadataService = metadataService;
441
+ this.failedStepsBeforeCatchupOnPublish = failedStepsBeforeCatchupOnPublish;
428
442
  this.stepQueue = new StepQueueState();
429
443
  }
430
444
  _createClass(DocumentService, [{
@@ -476,9 +490,9 @@ export var DocumentService = /*#__PURE__*/function () {
476
490
  }, 100);
477
491
  }
478
492
  } catch (error) {
479
- var _this$analyticsHelper20;
493
+ var _this$analyticsHelper22;
480
494
  logger("Processing steps failed with error: ".concat(error, ". Triggering catch up call."));
481
- (_this$analyticsHelper20 = this.analyticsHelper) === null || _this$analyticsHelper20 === void 0 ? void 0 : _this$analyticsHelper20.sendErrorEvent(error, 'Error while processing steps');
495
+ (_this$analyticsHelper22 = this.analyticsHelper) === null || _this$analyticsHelper22 === void 0 ? void 0 : _this$analyticsHelper22.sendErrorEvent(error, 'Error while processing steps');
482
496
  this.throttledCatchup();
483
497
  }
484
498
  }
@@ -543,7 +557,8 @@ export var DocumentService = /*#__PURE__*/function () {
543
557
  version: version,
544
558
  onStepsAdded: this.onStepsAdded,
545
559
  onErrorHandled: this.onErrorHandled,
546
- analyticsHelper: this.analyticsHelper
560
+ analyticsHelper: this.analyticsHelper,
561
+ emit: this.providerEmitCallback
547
562
  });
548
563
  }
549
564
  }]);
@@ -10,12 +10,15 @@ export var EVENT_ACTION = /*#__PURE__*/function (EVENT_ACTION) {
10
10
  EVENT_ACTION["PUBLISH_PAGE"] = "publishPage";
11
11
  EVENT_ACTION["GET_CURRENT_STATE"] = "getCurrentState";
12
12
  EVENT_ACTION["INVALIDATE_TOKEN"] = "invalidateToken";
13
+ EVENT_ACTION["SEND_STEPS_RETRY"] = "sendStepsRetry";
14
+ EVENT_ACTION["CATCHUP_AFTER_MAX_SEND_STEPS_RETRY"] = "catchupAfterMaxSendStepsRetry";
13
15
  EVENT_ACTION["DROPPED_STEPS"] = "droppedStepInCatchup";
14
16
  return EVENT_ACTION;
15
17
  }({});
16
18
  export var EVENT_STATUS = /*#__PURE__*/function (EVENT_STATUS) {
17
19
  EVENT_STATUS["SUCCESS"] = "SUCCESS";
18
20
  EVENT_STATUS["FAILURE"] = "FAILURE";
21
+ EVENT_STATUS["INFO"] = "INFO";
19
22
  return EVENT_STATUS;
20
23
  }({});
21
24
  export var ADD_STEPS_TYPE = /*#__PURE__*/function (ADD_STEPS_TYPE) {
@@ -16,7 +16,8 @@ export var commitStep = function commitStep(_ref) {
16
16
  clientId = _ref.clientId,
17
17
  onStepsAdded = _ref.onStepsAdded,
18
18
  onErrorHandled = _ref.onErrorHandled,
19
- analyticsHelper = _ref.analyticsHelper;
19
+ analyticsHelper = _ref.analyticsHelper,
20
+ emit = _ref.emit;
20
21
  var stepsWithClientAndUserId = steps.map(function (step) {
21
22
  return _objectSpread(_objectSpread({}, step.toJSON()), {}, {
22
23
  clientId: clientId,
@@ -24,6 +25,10 @@ export var commitStep = function commitStep(_ref) {
24
25
  });
25
26
  });
26
27
  var start = new Date().getTime();
28
+ emit('commit-status', {
29
+ status: 'attempt',
30
+ version: version
31
+ });
27
32
  try {
28
33
  broadcast('steps:commit', {
29
34
  steps: stepsWithClientAndUserId,
@@ -43,6 +48,10 @@ export var commitStep = function commitStep(_ref) {
43
48
  return stepWithClientAndUserId.stepType;
44
49
  })
45
50
  });
51
+ emit('commit-status', {
52
+ status: 'success',
53
+ version: response.version
54
+ });
46
55
  } else if (response.type === AcknowledgementResponseTypes.ERROR) {
47
56
  onErrorHandled(response.error);
48
57
  analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendActionEvent(EVENT_ACTION.ADD_STEPS, EVENT_STATUS.FAILURE, {
@@ -53,14 +62,26 @@ export var commitStep = function commitStep(_ref) {
53
62
  latency: latency
54
63
  });
55
64
  analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(response.error, 'Error while adding steps - Acknowledgement Error');
65
+ emit('commit-status', {
66
+ status: 'failure',
67
+ version: version
68
+ });
56
69
  } else {
57
70
  analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(
58
71
  // @ts-expect-error We didn't type the invalid type case
59
72
  new Error("Response type: ".concat((response === null || response === void 0 ? void 0 : response.type) || 'No response type')), 'Error while adding steps - Invalid Acknowledgement');
73
+ emit('commit-status', {
74
+ status: 'failure',
75
+ version: version
76
+ });
60
77
  }
61
78
  });
62
79
  } catch (error) {
63
80
  analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(error, 'Error while adding steps - Broadcast threw exception');
81
+ emit('commit-status', {
82
+ status: 'failure',
83
+ version: version
84
+ });
64
85
  }
65
86
  };
66
87
  export var throttledCommitStep = throttle(commitStep, SEND_STEPS_THROTTLE, {
@@ -221,7 +221,7 @@ export var Provider = /*#__PURE__*/function (_Emitter) {
221
221
  _this.metadataService = new MetadataService(_this.emitCallback, _this.channel.sendMetadata);
222
222
  _this.documentService = new DocumentService(_this.participantsService, _this.analyticsHelper, _this.channel.fetchCatchup, _this.emitCallback, _this.channel.broadcast, function () {
223
223
  return _this.userId;
224
- }, _this.onErrorHandled, _this.metadataService);
224
+ }, _this.onErrorHandled, _this.metadataService, _this.config.failedStepLimitBeforeCatchupOnPublish);
225
225
  _this.getStatePromise = new Promise(function (resolve) {
226
226
  _this.getStatePromiseResolve = resolve;
227
227
  });
@@ -1,5 +1,5 @@
1
1
  export var name = "@atlaskit/collab-provider";
2
- export var version = "9.0.1";
2
+ export var version = "9.1.0";
3
3
  export var nextMajorVersion = function nextMajorVersion() {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/collab-provider",
3
- "version": "9.0.1",
3
+ "version": "9.1.0",
4
4
  "sideEffects": false
5
5
  }
@@ -16,10 +16,12 @@ export declare class DocumentService {
16
16
  private getUserId;
17
17
  private onErrorHandled;
18
18
  private metadataService;
19
+ private failedStepsBeforeCatchupOnPublish;
19
20
  private getState;
20
21
  private onSyncUpError?;
21
22
  private stepQueue;
22
23
  private stepRejectCounter;
24
+ private aggressiveCatchup;
23
25
  private clientId?;
24
26
  /**
25
27
  *
@@ -28,12 +30,13 @@ export declare class DocumentService {
28
30
  * @param analyticsHelper - Helper for analytics events
29
31
  * @param fetchCatchup - Function to fetch "catchup" data, data required to rebase current steps to the latest version.
30
32
  * @param providerEmitCallback - Callback for emitting events to listeners on the provider
31
- * @param broadcastMetadata - Callback for broadcasting metadata changes to other clients
32
33
  * @param broadcast - Callback for broadcasting events to other clients
33
34
  * @param getUserId - Callback to fetch the current user's ID
34
35
  * @param onErrorHandled - Callback to handle
36
+ * @param metadataService
37
+ * @param failedStepsBeforeCatchupOnPublish - Control MAX_STEP_REJECTED_ERROR during page publishes.
35
38
  */
36
- constructor(participantsService: ParticipantsService, analyticsHelper: AnalyticsHelper | undefined, fetchCatchup: (fromVersion: number) => Promise<CatchupResponse>, providerEmitCallback: (evt: keyof CollabEvents, data: any) => void, broadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], 'timestamp'>, callback?: Function) => void, getUserId: () => string | undefined, onErrorHandled: (error: InternalError) => void, metadataService: MetadataService);
39
+ constructor(participantsService: ParticipantsService, analyticsHelper: AnalyticsHelper | undefined, fetchCatchup: (fromVersion: number) => Promise<CatchupResponse>, providerEmitCallback: (evt: keyof CollabEvents, data: any) => void, broadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], 'timestamp'>, callback?: Function) => void, getUserId: () => string | undefined, onErrorHandled: (error: InternalError) => void, metadataService: MetadataService, failedStepsBeforeCatchupOnPublish?: number);
37
40
  /**
38
41
  * To prevent calling catchup to often, use lodash throttle to reduce the frequency
39
42
  */
@@ -11,11 +11,14 @@ export declare enum EVENT_ACTION {
11
11
  PUBLISH_PAGE = "publishPage",
12
12
  GET_CURRENT_STATE = "getCurrentState",
13
13
  INVALIDATE_TOKEN = "invalidateToken",
14
+ SEND_STEPS_RETRY = "sendStepsRetry",
15
+ CATCHUP_AFTER_MAX_SEND_STEPS_RETRY = "catchupAfterMaxSendStepsRetry",
14
16
  DROPPED_STEPS = "droppedStepInCatchup"
15
17
  }
16
18
  export declare enum EVENT_STATUS {
17
19
  SUCCESS = "SUCCESS",
18
- FAILURE = "FAILURE"
20
+ FAILURE = "FAILURE",
21
+ INFO = "INFO"
19
22
  }
20
23
  export declare enum ADD_STEPS_TYPE {
21
24
  ACCEPTED = "ACCEPTED",
@@ -185,7 +188,22 @@ type GetCurrentStateFailureAnalyticsEvent = {
185
188
  latency?: number;
186
189
  };
187
190
  };
188
- export type ActionAnalyticsEvent = AddStepsSuccessAnalyticsEvent | AddStepsFailureAnalyticsEvent | ReInitDocFailAnalyticsEvent | ReInitDocSuccessAnalyticsEvent | ConnectionSuccessAnalyticsEvent | ConnectionFailureAnalyticsEvent | CatchUpSuccessAnalyticsEvent | CatchUpFailureAnalyticsEvent | DocumentInitSuccessAnalyticsEvent | UpdateParticipantsSuccessAnalyticsEvent | CommitUnconfirmedStepsSuccessAnalyticsEvent | CommitUnconfirmedStepsFailureAnalyticsEvent | PublishPageSuccessAnalyticsEvent | PublishPageFailureAnalyticsEvent | GetCurrentStateSuccessAnalyticsEvent | GetCurrentStateFailureAnalyticsEvent | InvalidateTokenAnalyticsEvent | CatchUpDroppedStepsEvent;
191
+ type SendStepsRetryAnalyticsEvent = {
192
+ eventAction: EVENT_ACTION.SEND_STEPS_RETRY;
193
+ attributes: {
194
+ documentAri: string;
195
+ eventStatus: EVENT_STATUS.SUCCESS;
196
+ count: number;
197
+ };
198
+ };
199
+ type CatchupAfterMaxSendStepsRetryAnalyticsEvent = {
200
+ eventAction: EVENT_ACTION.CATCHUP_AFTER_MAX_SEND_STEPS_RETRY;
201
+ attributes: {
202
+ documentAri: string;
203
+ eventStatus: EVENT_STATUS.SUCCESS;
204
+ };
205
+ };
206
+ export type ActionAnalyticsEvent = AddStepsSuccessAnalyticsEvent | AddStepsFailureAnalyticsEvent | ReInitDocFailAnalyticsEvent | ReInitDocSuccessAnalyticsEvent | ConnectionSuccessAnalyticsEvent | ConnectionFailureAnalyticsEvent | CatchUpSuccessAnalyticsEvent | CatchUpFailureAnalyticsEvent | DocumentInitSuccessAnalyticsEvent | UpdateParticipantsSuccessAnalyticsEvent | CommitUnconfirmedStepsSuccessAnalyticsEvent | CommitUnconfirmedStepsFailureAnalyticsEvent | PublishPageSuccessAnalyticsEvent | PublishPageFailureAnalyticsEvent | GetCurrentStateSuccessAnalyticsEvent | GetCurrentStateFailureAnalyticsEvent | InvalidateTokenAnalyticsEvent | SendStepsRetryAnalyticsEvent | CatchupAfterMaxSendStepsRetryAnalyticsEvent | CatchUpDroppedStepsEvent;
189
207
  export declare const ACK_MAX_TRY = 60;
190
208
  export declare const CONFLUENCE = "confluence";
191
209
  export {};
@@ -1,9 +1,9 @@
1
1
  /// <reference types="lodash" />
2
- import { ChannelEvent, StepsPayload } from '../types';
2
+ import { ChannelEvent, CollabCommitStatusEventPayload, CollabEvents, StepsPayload } from '../types';
3
3
  import type { Step as ProseMirrorStep } from 'prosemirror-transform';
4
4
  import AnalyticsHelper from '../analytics/analytics-helper';
5
5
  import type { InternalError } from '../errors/error-types';
6
- export declare const commitStep: ({ broadcast, steps, version, userId, clientId, onStepsAdded, onErrorHandled, analyticsHelper, }: {
6
+ export declare const commitStep: ({ broadcast, steps, version, userId, clientId, onStepsAdded, onErrorHandled, analyticsHelper, emit, }: {
7
7
  broadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], "timestamp">, callback?: Function) => void;
8
8
  steps: readonly ProseMirrorStep[];
9
9
  version: number;
@@ -12,8 +12,9 @@ export declare const commitStep: ({ broadcast, steps, version, userId, clientId,
12
12
  onStepsAdded: (data: StepsPayload) => void;
13
13
  onErrorHandled: (error: InternalError) => void;
14
14
  analyticsHelper?: AnalyticsHelper | undefined;
15
+ emit: (evt: keyof CollabEvents, data: CollabCommitStatusEventPayload) => void;
15
16
  }) => void;
16
- export declare const throttledCommitStep: import("lodash").DebouncedFunc<({ broadcast, steps, version, userId, clientId, onStepsAdded, onErrorHandled, analyticsHelper, }: {
17
+ export declare const throttledCommitStep: import("lodash").DebouncedFunc<({ broadcast, steps, version, userId, clientId, onStepsAdded, onErrorHandled, analyticsHelper, emit, }: {
17
18
  broadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], "timestamp">, callback?: Function) => void;
18
19
  steps: readonly ProseMirrorStep[];
19
20
  version: number;
@@ -22,4 +23,5 @@ export declare const throttledCommitStep: import("lodash").DebouncedFunc<({ broa
22
23
  onStepsAdded: (data: StepsPayload) => void;
23
24
  onErrorHandled: (error: InternalError) => void;
24
25
  analyticsHelper?: AnalyticsHelper | undefined;
26
+ emit: (evt: keyof CollabEvents, data: CollabCommitStatusEventPayload) => void;
25
27
  }) => void>;
@@ -90,6 +90,11 @@ export interface Config {
90
90
  */
91
91
  throwOnNotConnected?: boolean;
92
92
  initialDraft?: InitialDraft;
93
+ /**
94
+ * When a page is being published this number can control the number of failed steps until a catchup is triggered.
95
+ * The default value is MAX_STEP_REJECTED_ERROR (15).
96
+ */
97
+ failedStepLimitBeforeCatchupOnPublish?: number;
93
98
  }
94
99
  export interface InitAndAuthData {
95
100
  initialized: boolean;
@@ -135,6 +140,10 @@ export type CollabMetadataPayload = Metadata;
135
140
  export type CollabLocalStepsPayload = {
136
141
  steps: readonly Step[];
137
142
  };
143
+ export type CollabCommitStatusEventPayload = {
144
+ status: 'attempt' | 'success' | 'failure';
145
+ version: number;
146
+ };
138
147
  export interface CollabEvents {
139
148
  'metadata:changed': CollabMetadataPayload;
140
149
  init: CollabInitPayload;
@@ -147,6 +156,7 @@ export interface CollabEvents {
147
156
  error: ProviderError;
148
157
  entity: any;
149
158
  connecting: CollabConnectingPayload;
159
+ 'commit-status': CollabCommitStatusEventPayload;
150
160
  }
151
161
  export interface Metadata {
152
162
  [key: string]: string | number | boolean;
@@ -16,10 +16,12 @@ export declare class DocumentService {
16
16
  private getUserId;
17
17
  private onErrorHandled;
18
18
  private metadataService;
19
+ private failedStepsBeforeCatchupOnPublish;
19
20
  private getState;
20
21
  private onSyncUpError?;
21
22
  private stepQueue;
22
23
  private stepRejectCounter;
24
+ private aggressiveCatchup;
23
25
  private clientId?;
24
26
  /**
25
27
  *
@@ -28,12 +30,13 @@ export declare class DocumentService {
28
30
  * @param analyticsHelper - Helper for analytics events
29
31
  * @param fetchCatchup - Function to fetch "catchup" data, data required to rebase current steps to the latest version.
30
32
  * @param providerEmitCallback - Callback for emitting events to listeners on the provider
31
- * @param broadcastMetadata - Callback for broadcasting metadata changes to other clients
32
33
  * @param broadcast - Callback for broadcasting events to other clients
33
34
  * @param getUserId - Callback to fetch the current user's ID
34
35
  * @param onErrorHandled - Callback to handle
36
+ * @param metadataService
37
+ * @param failedStepsBeforeCatchupOnPublish - Control MAX_STEP_REJECTED_ERROR during page publishes.
35
38
  */
36
- constructor(participantsService: ParticipantsService, analyticsHelper: AnalyticsHelper | undefined, fetchCatchup: (fromVersion: number) => Promise<CatchupResponse>, providerEmitCallback: (evt: keyof CollabEvents, data: any) => void, broadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], 'timestamp'>, callback?: Function) => void, getUserId: () => string | undefined, onErrorHandled: (error: InternalError) => void, metadataService: MetadataService);
39
+ constructor(participantsService: ParticipantsService, analyticsHelper: AnalyticsHelper | undefined, fetchCatchup: (fromVersion: number) => Promise<CatchupResponse>, providerEmitCallback: (evt: keyof CollabEvents, data: any) => void, broadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], 'timestamp'>, callback?: Function) => void, getUserId: () => string | undefined, onErrorHandled: (error: InternalError) => void, metadataService: MetadataService, failedStepsBeforeCatchupOnPublish?: number);
37
40
  /**
38
41
  * To prevent calling catchup to often, use lodash throttle to reduce the frequency
39
42
  */
@@ -11,11 +11,14 @@ export declare enum EVENT_ACTION {
11
11
  PUBLISH_PAGE = "publishPage",
12
12
  GET_CURRENT_STATE = "getCurrentState",
13
13
  INVALIDATE_TOKEN = "invalidateToken",
14
+ SEND_STEPS_RETRY = "sendStepsRetry",
15
+ CATCHUP_AFTER_MAX_SEND_STEPS_RETRY = "catchupAfterMaxSendStepsRetry",
14
16
  DROPPED_STEPS = "droppedStepInCatchup"
15
17
  }
16
18
  export declare enum EVENT_STATUS {
17
19
  SUCCESS = "SUCCESS",
18
- FAILURE = "FAILURE"
20
+ FAILURE = "FAILURE",
21
+ INFO = "INFO"
19
22
  }
20
23
  export declare enum ADD_STEPS_TYPE {
21
24
  ACCEPTED = "ACCEPTED",
@@ -185,7 +188,22 @@ type GetCurrentStateFailureAnalyticsEvent = {
185
188
  latency?: number;
186
189
  };
187
190
  };
188
- export type ActionAnalyticsEvent = AddStepsSuccessAnalyticsEvent | AddStepsFailureAnalyticsEvent | ReInitDocFailAnalyticsEvent | ReInitDocSuccessAnalyticsEvent | ConnectionSuccessAnalyticsEvent | ConnectionFailureAnalyticsEvent | CatchUpSuccessAnalyticsEvent | CatchUpFailureAnalyticsEvent | DocumentInitSuccessAnalyticsEvent | UpdateParticipantsSuccessAnalyticsEvent | CommitUnconfirmedStepsSuccessAnalyticsEvent | CommitUnconfirmedStepsFailureAnalyticsEvent | PublishPageSuccessAnalyticsEvent | PublishPageFailureAnalyticsEvent | GetCurrentStateSuccessAnalyticsEvent | GetCurrentStateFailureAnalyticsEvent | InvalidateTokenAnalyticsEvent | CatchUpDroppedStepsEvent;
191
+ type SendStepsRetryAnalyticsEvent = {
192
+ eventAction: EVENT_ACTION.SEND_STEPS_RETRY;
193
+ attributes: {
194
+ documentAri: string;
195
+ eventStatus: EVENT_STATUS.SUCCESS;
196
+ count: number;
197
+ };
198
+ };
199
+ type CatchupAfterMaxSendStepsRetryAnalyticsEvent = {
200
+ eventAction: EVENT_ACTION.CATCHUP_AFTER_MAX_SEND_STEPS_RETRY;
201
+ attributes: {
202
+ documentAri: string;
203
+ eventStatus: EVENT_STATUS.SUCCESS;
204
+ };
205
+ };
206
+ export type ActionAnalyticsEvent = AddStepsSuccessAnalyticsEvent | AddStepsFailureAnalyticsEvent | ReInitDocFailAnalyticsEvent | ReInitDocSuccessAnalyticsEvent | ConnectionSuccessAnalyticsEvent | ConnectionFailureAnalyticsEvent | CatchUpSuccessAnalyticsEvent | CatchUpFailureAnalyticsEvent | DocumentInitSuccessAnalyticsEvent | UpdateParticipantsSuccessAnalyticsEvent | CommitUnconfirmedStepsSuccessAnalyticsEvent | CommitUnconfirmedStepsFailureAnalyticsEvent | PublishPageSuccessAnalyticsEvent | PublishPageFailureAnalyticsEvent | GetCurrentStateSuccessAnalyticsEvent | GetCurrentStateFailureAnalyticsEvent | InvalidateTokenAnalyticsEvent | SendStepsRetryAnalyticsEvent | CatchupAfterMaxSendStepsRetryAnalyticsEvent | CatchUpDroppedStepsEvent;
189
207
  export declare const ACK_MAX_TRY = 60;
190
208
  export declare const CONFLUENCE = "confluence";
191
209
  export {};
@@ -1,9 +1,9 @@
1
1
  /// <reference types="lodash" />
2
- import { ChannelEvent, StepsPayload } from '../types';
2
+ import { ChannelEvent, CollabCommitStatusEventPayload, CollabEvents, StepsPayload } from '../types';
3
3
  import type { Step as ProseMirrorStep } from 'prosemirror-transform';
4
4
  import AnalyticsHelper from '../analytics/analytics-helper';
5
5
  import type { InternalError } from '../errors/error-types';
6
- export declare const commitStep: ({ broadcast, steps, version, userId, clientId, onStepsAdded, onErrorHandled, analyticsHelper, }: {
6
+ export declare const commitStep: ({ broadcast, steps, version, userId, clientId, onStepsAdded, onErrorHandled, analyticsHelper, emit, }: {
7
7
  broadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], "timestamp">, callback?: Function) => void;
8
8
  steps: readonly ProseMirrorStep[];
9
9
  version: number;
@@ -12,8 +12,9 @@ export declare const commitStep: ({ broadcast, steps, version, userId, clientId,
12
12
  onStepsAdded: (data: StepsPayload) => void;
13
13
  onErrorHandled: (error: InternalError) => void;
14
14
  analyticsHelper?: AnalyticsHelper | undefined;
15
+ emit: (evt: keyof CollabEvents, data: CollabCommitStatusEventPayload) => void;
15
16
  }) => void;
16
- export declare const throttledCommitStep: import("lodash").DebouncedFunc<({ broadcast, steps, version, userId, clientId, onStepsAdded, onErrorHandled, analyticsHelper, }: {
17
+ export declare const throttledCommitStep: import("lodash").DebouncedFunc<({ broadcast, steps, version, userId, clientId, onStepsAdded, onErrorHandled, analyticsHelper, emit, }: {
17
18
  broadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], "timestamp">, callback?: Function) => void;
18
19
  steps: readonly ProseMirrorStep[];
19
20
  version: number;
@@ -22,4 +23,5 @@ export declare const throttledCommitStep: import("lodash").DebouncedFunc<({ broa
22
23
  onStepsAdded: (data: StepsPayload) => void;
23
24
  onErrorHandled: (error: InternalError) => void;
24
25
  analyticsHelper?: AnalyticsHelper | undefined;
26
+ emit: (evt: keyof CollabEvents, data: CollabCommitStatusEventPayload) => void;
25
27
  }) => void>;
@@ -90,6 +90,11 @@ export interface Config {
90
90
  */
91
91
  throwOnNotConnected?: boolean;
92
92
  initialDraft?: InitialDraft;
93
+ /**
94
+ * When a page is being published this number can control the number of failed steps until a catchup is triggered.
95
+ * The default value is MAX_STEP_REJECTED_ERROR (15).
96
+ */
97
+ failedStepLimitBeforeCatchupOnPublish?: number;
93
98
  }
94
99
  export interface InitAndAuthData {
95
100
  initialized: boolean;
@@ -135,6 +140,10 @@ export type CollabMetadataPayload = Metadata;
135
140
  export type CollabLocalStepsPayload = {
136
141
  steps: readonly Step[];
137
142
  };
143
+ export type CollabCommitStatusEventPayload = {
144
+ status: 'attempt' | 'success' | 'failure';
145
+ version: number;
146
+ };
138
147
  export interface CollabEvents {
139
148
  'metadata:changed': CollabMetadataPayload;
140
149
  init: CollabInitPayload;
@@ -147,6 +156,7 @@ export interface CollabEvents {
147
156
  error: ProviderError;
148
157
  entity: any;
149
158
  connecting: CollabConnectingPayload;
159
+ 'commit-status': CollabCommitStatusEventPayload;
150
160
  }
151
161
  export interface Metadata {
152
162
  [key: string]: string | number | boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/collab-provider",
3
- "version": "9.0.1",
3
+ "version": "9.1.0",
4
4
  "description": "A provider for collaborative editing.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -61,7 +61,7 @@
61
61
  }
62
62
  },
63
63
  "devDependencies": {
64
- "@atlaskit/adf-schema": "^25.7.0",
64
+ "@atlaskit/adf-schema": "^25.8.0",
65
65
  "@atlaskit/analytics-listeners": "^8.7.0",
66
66
  "@atlaskit/editor-test-helpers": "^18.5.0",
67
67
  "@atlassian/atlassian-frontend-prettier-config-1.0.1": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.1",
package/report.api.md CHANGED
@@ -31,6 +31,12 @@ type BaseEvents = Pick<
31
31
  'send' | 'sendMessage' | 'setup'
32
32
  >;
33
33
 
34
+ // @public (undocumented)
35
+ type CollabCommitStatusEventPayload = {
36
+ status: 'attempt' | 'failure' | 'success';
37
+ version: number;
38
+ };
39
+
34
40
  // @public (undocumented)
35
41
  export type CollabConnectedPayload = CollabEventConnectionData;
36
42
 
@@ -154,6 +160,8 @@ export interface CollabEventRemoteData {
154
160
 
155
161
  // @public (undocumented)
156
162
  export interface CollabEvents {
163
+ // (undocumented)
164
+ 'commit-status': CollabCommitStatusEventPayload;
157
165
  // (undocumented)
158
166
  'local-steps': CollabLocalStepsPayload;
159
167
  // (undocumented)
@@ -251,6 +259,7 @@ interface Config {
251
259
  ) => Socket;
252
260
  // (undocumented)
253
261
  documentAri: string;
262
+ failedStepLimitBeforeCatchupOnPublish?: number;
254
263
  // (undocumented)
255
264
  featureFlags?: {
256
265
  [key: string]: boolean;