@atlaskit/collab-provider 9.7.4 → 9.9.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 +12 -0
- package/dist/cjs/channel.js +140 -34
- package/dist/cjs/document/document-service.js +57 -16
- package/dist/cjs/feature-flags/__test__/index.unit.js +3 -2
- package/dist/cjs/feature-flags/index.js +5 -3
- package/dist/cjs/provider/index.js +27 -4
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/channel.js +40 -4
- package/dist/es2019/document/document-service.js +26 -4
- package/dist/es2019/feature-flags/__test__/index.unit.js +3 -2
- package/dist/es2019/feature-flags/index.js +5 -3
- package/dist/es2019/provider/index.js +25 -1
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/es2019/version.json +1 -1
- package/dist/esm/channel.js +140 -34
- package/dist/esm/document/document-service.js +57 -16
- package/dist/esm/feature-flags/__test__/index.unit.js +3 -2
- package/dist/esm/feature-flags/index.js +5 -3
- package/dist/esm/provider/index.js +27 -4
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/esm/version.json +1 -1
- package/dist/types/channel.d.ts +2 -1
- package/dist/types/document/document-service.d.ts +8 -2
- package/dist/types/feature-flags/types.d.ts +1 -0
- package/dist/types/provider/index.d.ts +1 -0
- package/dist/types/types.d.ts +7 -0
- package/dist/types-ts4.5/channel.d.ts +2 -1
- package/dist/types-ts4.5/document/document-service.d.ts +8 -2
- package/dist/types-ts4.5/feature-flags/types.d.ts +1 -0
- package/dist/types-ts4.5/provider/index.d.ts +1 -0
- package/dist/types-ts4.5/types.d.ts +7 -0
- package/package.json +2 -2
- package/report.api.md +2 -0
- package/tmp/api-report-tmp.d.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atlaskit/collab-provider
|
|
2
2
|
|
|
3
|
+
## 9.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`4c6ebd50aeb`](https://bitbucket.org/atlassian/atlassian-frontend/commits/4c6ebd50aeb) - call reconcile when commitUnconfirmedSteps fails (mitigation for 'can't sync up' errors)
|
|
8
|
+
|
|
9
|
+
## 9.8.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [`aceff84b101`](https://bitbucket.org/atlassian/atlassian-frontend/commits/aceff84b101) - initializing provider on setup if buffering is enabled
|
|
14
|
+
|
|
3
15
|
## 9.7.4
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/cjs/channel.js
CHANGED
|
@@ -332,6 +332,112 @@ var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
332
332
|
return _ref.apply(this, arguments);
|
|
333
333
|
};
|
|
334
334
|
}());
|
|
335
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "fetchReconcile", /*#__PURE__*/function () {
|
|
336
|
+
var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(currentStateDoc) {
|
|
337
|
+
var _ref4, _this$token2, reqBody, reconcileResponse, _this$analyticsHelper7;
|
|
338
|
+
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
339
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
340
|
+
case 0:
|
|
341
|
+
_context2.prev = 0;
|
|
342
|
+
reqBody = JSON.stringify({
|
|
343
|
+
doc: currentStateDoc,
|
|
344
|
+
productId: 'ccollab',
|
|
345
|
+
reason: 'UNKNOWN' // different reason here?
|
|
346
|
+
});
|
|
347
|
+
_context2.t0 = _utilServiceSupport.utils;
|
|
348
|
+
_context2.t1 = _this.config;
|
|
349
|
+
_context2.t2 = "document/".concat(encodeURIComponent(_this.config.documentAri), "/reconcile");
|
|
350
|
+
_context2.t3 = _objectSpread;
|
|
351
|
+
_context2.t4 = _objectSpread;
|
|
352
|
+
_context2.t5 = {};
|
|
353
|
+
if (!_this.config.permissionTokenRefresh) {
|
|
354
|
+
_context2.next = 29;
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
if (!((_this$token2 = _this.token) !== null && _this$token2 !== void 0)) {
|
|
358
|
+
_context2.next = 13;
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
_context2.t8 = _this$token2;
|
|
362
|
+
_context2.next = 16;
|
|
363
|
+
break;
|
|
364
|
+
case 13:
|
|
365
|
+
_context2.next = 15;
|
|
366
|
+
return _this.config.permissionTokenRefresh().then(function (token) {
|
|
367
|
+
if (token) {
|
|
368
|
+
_this.setToken(token);
|
|
369
|
+
}
|
|
370
|
+
return token;
|
|
371
|
+
});
|
|
372
|
+
case 15:
|
|
373
|
+
_context2.t8 = _context2.sent;
|
|
374
|
+
case 16:
|
|
375
|
+
_context2.t9 = _ref4 = _context2.t8;
|
|
376
|
+
_context2.t7 = _context2.t9 !== null;
|
|
377
|
+
if (!_context2.t7) {
|
|
378
|
+
_context2.next = 20;
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
_context2.t7 = _ref4 !== void 0;
|
|
382
|
+
case 20:
|
|
383
|
+
if (!_context2.t7) {
|
|
384
|
+
_context2.next = 24;
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
_context2.t10 = _ref4;
|
|
388
|
+
_context2.next = 25;
|
|
389
|
+
break;
|
|
390
|
+
case 24:
|
|
391
|
+
_context2.t10 = undefined;
|
|
392
|
+
case 25:
|
|
393
|
+
_context2.t11 = _context2.t10;
|
|
394
|
+
_context2.t6 = {
|
|
395
|
+
'x-token': _context2.t11
|
|
396
|
+
};
|
|
397
|
+
_context2.next = 30;
|
|
398
|
+
break;
|
|
399
|
+
case 29:
|
|
400
|
+
_context2.t6 = {};
|
|
401
|
+
case 30:
|
|
402
|
+
_context2.t12 = _context2.t6;
|
|
403
|
+
_context2.t13 = (0, _context2.t4)(_context2.t5, _context2.t12);
|
|
404
|
+
_context2.t14 = {};
|
|
405
|
+
_context2.t15 = {
|
|
406
|
+
'x-product': (0, _utils.getProduct)(_this.config.productInfo),
|
|
407
|
+
'x-subproduct': (0, _utils.getSubProduct)(_this.config.productInfo),
|
|
408
|
+
'Content-Type': 'application/json'
|
|
409
|
+
};
|
|
410
|
+
_context2.t16 = (0, _context2.t3)(_context2.t13, _context2.t14, _context2.t15);
|
|
411
|
+
_context2.t17 = reqBody;
|
|
412
|
+
_context2.t18 = {
|
|
413
|
+
headers: _context2.t16,
|
|
414
|
+
method: 'POST',
|
|
415
|
+
body: _context2.t17
|
|
416
|
+
};
|
|
417
|
+
_context2.t19 = {
|
|
418
|
+
path: _context2.t2,
|
|
419
|
+
requestInit: _context2.t18
|
|
420
|
+
};
|
|
421
|
+
_context2.next = 40;
|
|
422
|
+
return _context2.t0.requestService.call(_context2.t0, _context2.t1, _context2.t19);
|
|
423
|
+
case 40:
|
|
424
|
+
reconcileResponse = _context2.sent;
|
|
425
|
+
return _context2.abrupt("return", reconcileResponse);
|
|
426
|
+
case 44:
|
|
427
|
+
_context2.prev = 44;
|
|
428
|
+
_context2.t20 = _context2["catch"](0);
|
|
429
|
+
(_this$analyticsHelper7 = _this.analyticsHelper) === null || _this$analyticsHelper7 === void 0 ? void 0 : _this$analyticsHelper7.sendErrorEvent(_context2.t20, 'Error while fetching reconciled document');
|
|
430
|
+
throw _context2.t20;
|
|
431
|
+
case 48:
|
|
432
|
+
case "end":
|
|
433
|
+
return _context2.stop();
|
|
434
|
+
}
|
|
435
|
+
}, _callee2, null, [[0, 44]]);
|
|
436
|
+
}));
|
|
437
|
+
return function (_x2) {
|
|
438
|
+
return _ref3.apply(this, arguments);
|
|
439
|
+
};
|
|
440
|
+
}());
|
|
335
441
|
/**
|
|
336
442
|
* Send message to the back-end service over the channel. Timestamp will be added server side.
|
|
337
443
|
* @throws {NotInitializedError} Channel not initialized
|
|
@@ -416,10 +522,10 @@ var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
416
522
|
var auth;
|
|
417
523
|
if (permissionTokenRefresh) {
|
|
418
524
|
auth = /*#__PURE__*/function () {
|
|
419
|
-
var
|
|
525
|
+
var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(cb) {
|
|
420
526
|
var authData, token, _data, _data$meta, authenticationError;
|
|
421
|
-
return _regenerator.default.wrap(function
|
|
422
|
-
while (1) switch (
|
|
527
|
+
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
528
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
423
529
|
case 0:
|
|
424
530
|
// Rebuild authData to ensure values are current
|
|
425
531
|
authData = {
|
|
@@ -429,19 +535,19 @@ var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
429
535
|
need404: _this2.config.need404
|
|
430
536
|
}; // use the cached token if caching in enabled and token valid
|
|
431
537
|
if (!(cacheToken && _this2.token)) {
|
|
432
|
-
|
|
538
|
+
_context3.next = 6;
|
|
433
539
|
break;
|
|
434
540
|
}
|
|
435
541
|
authData.token = _this2.token;
|
|
436
542
|
cb(authData);
|
|
437
|
-
|
|
543
|
+
_context3.next = 18;
|
|
438
544
|
break;
|
|
439
545
|
case 6:
|
|
440
|
-
|
|
441
|
-
|
|
546
|
+
_context3.prev = 6;
|
|
547
|
+
_context3.next = 9;
|
|
442
548
|
return permissionTokenRefresh();
|
|
443
549
|
case 9:
|
|
444
|
-
token =
|
|
550
|
+
token = _context3.sent;
|
|
445
551
|
if (token) {
|
|
446
552
|
// save token locally
|
|
447
553
|
_this2.setToken(token);
|
|
@@ -451,11 +557,11 @@ var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
451
557
|
authData.token = undefined;
|
|
452
558
|
}
|
|
453
559
|
cb(authData);
|
|
454
|
-
|
|
560
|
+
_context3.next = 18;
|
|
455
561
|
break;
|
|
456
562
|
case 14:
|
|
457
|
-
|
|
458
|
-
|
|
563
|
+
_context3.prev = 14;
|
|
564
|
+
_context3.t0 = _context3["catch"](6);
|
|
459
565
|
// Pass the error back to the consumers so they can deal with exceptional cases themselves (eg. no permissions because the page was deleted)
|
|
460
566
|
authenticationError = {
|
|
461
567
|
message: 'Insufficient editing permissions',
|
|
@@ -463,8 +569,8 @@ var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
463
569
|
status: 403,
|
|
464
570
|
code: _errorTypes.INTERNAL_ERROR_CODE.TOKEN_PERMISSION_ERROR,
|
|
465
571
|
meta: {
|
|
466
|
-
originalError:
|
|
467
|
-
reason:
|
|
572
|
+
originalError: _context3.t0,
|
|
573
|
+
reason: _context3.t0 === null || _context3.t0 === void 0 ? void 0 : (_data = _context3.t0.data) === null || _data === void 0 ? void 0 : (_data$meta = _data.meta) === null || _data$meta === void 0 ? void 0 : _data$meta.reason // Should always be 'RESOURCE_DELETED' Temporary, until Confluence Cloud removes their hack
|
|
468
574
|
// https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/browse/next/packages/native-collab/src/fetchCollabPermissionToken.ts#37
|
|
469
575
|
}
|
|
470
576
|
}
|
|
@@ -473,12 +579,12 @@ var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
473
579
|
_this2.emit('error', authenticationError);
|
|
474
580
|
case 18:
|
|
475
581
|
case "end":
|
|
476
|
-
return
|
|
582
|
+
return _context3.stop();
|
|
477
583
|
}
|
|
478
|
-
},
|
|
584
|
+
}, _callee3, null, [[6, 14]]);
|
|
479
585
|
}));
|
|
480
|
-
return function auth(
|
|
481
|
-
return
|
|
586
|
+
return function auth(_x3) {
|
|
587
|
+
return _ref5.apply(this, arguments);
|
|
482
588
|
};
|
|
483
589
|
}();
|
|
484
590
|
} else {
|
|
@@ -502,9 +608,9 @@ var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
502
608
|
this.socket.on('steps:added', function (data) {
|
|
503
609
|
_this2.emit('steps:added', data);
|
|
504
610
|
});
|
|
505
|
-
this.socket.on('participant:telepointer', function (
|
|
506
|
-
var timestamp =
|
|
507
|
-
data =
|
|
611
|
+
this.socket.on('participant:telepointer', function (_ref6) {
|
|
612
|
+
var timestamp = _ref6.timestamp,
|
|
613
|
+
data = _ref6.data;
|
|
508
614
|
// data is TelepointerPayload without timestamp
|
|
509
615
|
_this2.emit('participant:telepointer', _objectSpread({
|
|
510
616
|
timestamp: timestamp
|
|
@@ -519,11 +625,11 @@ var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
519
625
|
this.socket.on('participant:left', function (data) {
|
|
520
626
|
_this2.emit('participant:left', data);
|
|
521
627
|
});
|
|
522
|
-
this.socket.on('participant:updated', function (
|
|
523
|
-
var sessionId =
|
|
524
|
-
timestamp =
|
|
525
|
-
data =
|
|
526
|
-
clientId =
|
|
628
|
+
this.socket.on('participant:updated', function (_ref7) {
|
|
629
|
+
var sessionId = _ref7.sessionId,
|
|
630
|
+
timestamp = _ref7.timestamp,
|
|
631
|
+
data = _ref7.data,
|
|
632
|
+
clientId = _ref7.clientId;
|
|
527
633
|
_this2.emit('participant:updated', _objectSpread({
|
|
528
634
|
sessionId: sessionId,
|
|
529
635
|
timestamp: timestamp,
|
|
@@ -539,10 +645,10 @@ var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
539
645
|
_this2.emit('status', data);
|
|
540
646
|
});
|
|
541
647
|
this.socket.on('disconnect', /*#__PURE__*/function () {
|
|
542
|
-
var
|
|
648
|
+
var _ref8 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(reason) {
|
|
543
649
|
var _this2$analyticsHelpe, reconnectionError;
|
|
544
|
-
return _regenerator.default.wrap(function
|
|
545
|
-
while (1) switch (
|
|
650
|
+
return _regenerator.default.wrap(function _callee4$(_context4) {
|
|
651
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
546
652
|
case 0:
|
|
547
653
|
if ((0, _featureFlags.getCollabProviderFeatureFlag)('socketMessageMetricsFF', _this2.config.featureFlags) && _this2.socketMessageMetrics) {
|
|
548
654
|
_this2.socketMessageMetrics.closeSocketMessageMetrics();
|
|
@@ -570,12 +676,12 @@ var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
570
676
|
}
|
|
571
677
|
case 5:
|
|
572
678
|
case "end":
|
|
573
|
-
return
|
|
679
|
+
return _context4.stop();
|
|
574
680
|
}
|
|
575
|
-
},
|
|
681
|
+
}, _callee4);
|
|
576
682
|
}));
|
|
577
|
-
return function (
|
|
578
|
-
return
|
|
683
|
+
return function (_x4) {
|
|
684
|
+
return _ref8.apply(this, arguments);
|
|
579
685
|
};
|
|
580
686
|
}());
|
|
581
687
|
|
|
@@ -665,8 +771,8 @@ var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
665
771
|
this.emit('error', rateLimitError);
|
|
666
772
|
throw new Error();
|
|
667
773
|
} else if (rateLimitType === this.RATE_LIMIT_TYPE_SOFT) {
|
|
668
|
-
var _this$
|
|
669
|
-
(_this$
|
|
774
|
+
var _this$analyticsHelper8;
|
|
775
|
+
(_this$analyticsHelper8 = this.analyticsHelper) === null || _this$analyticsHelper8 === void 0 ? void 0 : _this$analyticsHelper8.sendErrorEvent(rateLimitError, 'Rate limited');
|
|
670
776
|
}
|
|
671
777
|
}
|
|
672
778
|
}
|
|
@@ -20,6 +20,7 @@ var _editorJsonTransformer = require("@atlaskit/editor-json-transformer");
|
|
|
20
20
|
var _provider = require("../provider");
|
|
21
21
|
var _catchup = require("./catchup");
|
|
22
22
|
var _stepQueueState = require("./step-queue-state");
|
|
23
|
+
var _featureFlags = require("../feature-flags");
|
|
23
24
|
var _errorTypes = require("../errors/error-types");
|
|
24
25
|
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; }
|
|
25
26
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
@@ -36,6 +37,7 @@ var DocumentService = /*#__PURE__*/function () {
|
|
|
36
37
|
* and to emit their telepointers from steps they add
|
|
37
38
|
* @param analyticsHelper - Helper for analytics events
|
|
38
39
|
* @param fetchCatchup - Function to fetch "catchup" data, data required to rebase current steps to the latest version.
|
|
40
|
+
* @param fetchReconcile - Function to call "reconcile" from NCS backend
|
|
39
41
|
* @param providerEmitCallback - Callback for emitting events to listeners on the provider
|
|
40
42
|
* @param broadcast - Callback for broadcasting events to other clients
|
|
41
43
|
* @param getUserId - Callback to fetch the current user's ID
|
|
@@ -43,11 +45,13 @@ var DocumentService = /*#__PURE__*/function () {
|
|
|
43
45
|
* @param metadataService
|
|
44
46
|
* @param failedStepsBeforeCatchupOnPublish - Control MAX_STEP_REJECTED_ERROR during page publishes.
|
|
45
47
|
* @param enableErrorOnFailedDocumentApply - Enable failed document update exceptions.
|
|
48
|
+
* @param featureFlags - Feature flag config
|
|
46
49
|
*/
|
|
47
|
-
function DocumentService(participantsService, analyticsHelper, fetchCatchup, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService) {
|
|
50
|
+
function DocumentService(participantsService, analyticsHelper, fetchCatchup, fetchReconcile, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService) {
|
|
48
51
|
var _this = this;
|
|
49
|
-
var failedStepsBeforeCatchupOnPublish = arguments.length >
|
|
50
|
-
var enableErrorOnFailedDocumentApply = arguments.length >
|
|
52
|
+
var failedStepsBeforeCatchupOnPublish = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : _provider.MAX_STEP_REJECTED_ERROR;
|
|
53
|
+
var enableErrorOnFailedDocumentApply = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : false;
|
|
54
|
+
var featureFlags = arguments.length > 11 ? arguments[11] : undefined;
|
|
51
55
|
(0, _classCallCheck2.default)(this, DocumentService);
|
|
52
56
|
// Fires analytics to editor when collab editor cannot sync up
|
|
53
57
|
(0, _defineProperty2.default)(this, "stepRejectCounter", 0);
|
|
@@ -283,41 +287,76 @@ var DocumentService = /*#__PURE__*/function () {
|
|
|
283
287
|
}
|
|
284
288
|
});
|
|
285
289
|
(0, _defineProperty2.default)(this, "getFinalAcknowledgedState", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
|
|
286
|
-
var _this$analyticsHelper14, currentState, measure, _this$analyticsHelper15, _this$analyticsHelper16, _measure2;
|
|
290
|
+
var _this$analyticsHelper14, finalAcknowledgedState, currentState, reconcileResponse, measure, _this$analyticsHelper15, _this$analyticsHelper16, _measure2;
|
|
287
291
|
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
288
292
|
while (1) switch (_context3.prev = _context3.next) {
|
|
289
293
|
case 0:
|
|
290
294
|
_this.aggressiveCatchup = true;
|
|
291
295
|
_context3.prev = 1;
|
|
292
296
|
(0, _performance.startMeasure)(_performance.MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
297
|
+
if (!(0, _featureFlags.getCollabProviderFeatureFlag)('enableFallbackToReconcile', _this.featureFlags)) {
|
|
298
|
+
_context3.next = 23;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
_context3.prev = 4;
|
|
296
302
|
_context3.next = 7;
|
|
297
|
-
return _this.
|
|
303
|
+
return _this.commitUnconfirmedSteps();
|
|
298
304
|
case 7:
|
|
305
|
+
_context3.next = 9;
|
|
306
|
+
return _this.getCurrentState();
|
|
307
|
+
case 9:
|
|
308
|
+
finalAcknowledgedState = _context3.sent;
|
|
309
|
+
_context3.next = 21;
|
|
310
|
+
break;
|
|
311
|
+
case 12:
|
|
312
|
+
_context3.prev = 12;
|
|
313
|
+
_context3.t0 = _context3["catch"](4);
|
|
314
|
+
_context3.next = 16;
|
|
315
|
+
return _this.getCurrentState();
|
|
316
|
+
case 16:
|
|
299
317
|
currentState = _context3.sent;
|
|
318
|
+
_context3.next = 19;
|
|
319
|
+
return _this.fetchReconcile(JSON.stringify(currentState.content));
|
|
320
|
+
case 19:
|
|
321
|
+
reconcileResponse = _context3.sent;
|
|
322
|
+
finalAcknowledgedState = {
|
|
323
|
+
content: JSON.parse(reconcileResponse.document),
|
|
324
|
+
title: currentState.title,
|
|
325
|
+
stepVersion: reconcileResponse.version
|
|
326
|
+
};
|
|
327
|
+
case 21:
|
|
328
|
+
_context3.next = 28;
|
|
329
|
+
break;
|
|
330
|
+
case 23:
|
|
331
|
+
_context3.next = 25;
|
|
332
|
+
return _this.commitUnconfirmedSteps();
|
|
333
|
+
case 25:
|
|
334
|
+
_context3.next = 27;
|
|
335
|
+
return _this.getCurrentState();
|
|
336
|
+
case 27:
|
|
337
|
+
finalAcknowledgedState = _context3.sent;
|
|
338
|
+
case 28:
|
|
300
339
|
measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
|
|
301
340
|
(_this$analyticsHelper14 = _this.analyticsHelper) === null || _this$analyticsHelper14 === void 0 ? void 0 : _this$analyticsHelper14.sendActionEvent(_const.EVENT_ACTION.PUBLISH_PAGE, _const.EVENT_STATUS.SUCCESS, {
|
|
302
341
|
latency: measure === null || measure === void 0 ? void 0 : measure.duration
|
|
303
342
|
});
|
|
304
343
|
_this.aggressiveCatchup = false;
|
|
305
|
-
return _context3.abrupt("return",
|
|
306
|
-
case
|
|
307
|
-
_context3.prev =
|
|
308
|
-
_context3.
|
|
344
|
+
return _context3.abrupt("return", finalAcknowledgedState);
|
|
345
|
+
case 34:
|
|
346
|
+
_context3.prev = 34;
|
|
347
|
+
_context3.t1 = _context3["catch"](1);
|
|
309
348
|
_this.aggressiveCatchup = false;
|
|
310
349
|
_measure2 = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
|
|
311
350
|
(_this$analyticsHelper15 = _this.analyticsHelper) === null || _this$analyticsHelper15 === void 0 ? void 0 : _this$analyticsHelper15.sendActionEvent(_const.EVENT_ACTION.PUBLISH_PAGE, _const.EVENT_STATUS.FAILURE, {
|
|
312
351
|
latency: _measure2 === null || _measure2 === void 0 ? void 0 : _measure2.duration
|
|
313
352
|
});
|
|
314
|
-
(_this$analyticsHelper16 = _this.analyticsHelper) === null || _this$analyticsHelper16 === void 0 ? void 0 : _this$analyticsHelper16.sendErrorEvent(_context3.
|
|
315
|
-
throw _context3.
|
|
316
|
-
case
|
|
353
|
+
(_this$analyticsHelper16 = _this.analyticsHelper) === null || _this$analyticsHelper16 === void 0 ? void 0 : _this$analyticsHelper16.sendErrorEvent(_context3.t1, 'Error while returning ADF version of the final draft document');
|
|
354
|
+
throw _context3.t1;
|
|
355
|
+
case 41:
|
|
317
356
|
case "end":
|
|
318
357
|
return _context3.stop();
|
|
319
358
|
}
|
|
320
|
-
}, _callee3, null, [[1,
|
|
359
|
+
}, _callee3, null, [[1, 34], [4, 12]]);
|
|
321
360
|
})));
|
|
322
361
|
(0, _defineProperty2.default)(this, "updateDocument", function (_ref6) {
|
|
323
362
|
var doc = _ref6.doc,
|
|
@@ -495,6 +534,7 @@ var DocumentService = /*#__PURE__*/function () {
|
|
|
495
534
|
this.participantsService = participantsService;
|
|
496
535
|
this.analyticsHelper = analyticsHelper;
|
|
497
536
|
this.fetchCatchup = fetchCatchup;
|
|
537
|
+
this.fetchReconcile = fetchReconcile;
|
|
498
538
|
this.providerEmitCallback = providerEmitCallback;
|
|
499
539
|
this.broadcast = broadcast;
|
|
500
540
|
this.getUserId = getUserId;
|
|
@@ -502,6 +542,7 @@ var DocumentService = /*#__PURE__*/function () {
|
|
|
502
542
|
this.metadataService = metadataService;
|
|
503
543
|
this.failedStepsBeforeCatchupOnPublish = failedStepsBeforeCatchupOnPublish;
|
|
504
544
|
this.enableErrorOnFailedDocumentApply = enableErrorOnFailedDocumentApply;
|
|
545
|
+
this.featureFlags = featureFlags;
|
|
505
546
|
this.stepQueue = new _stepQueueState.StepQueueState();
|
|
506
547
|
}
|
|
507
548
|
(0, _createClass2.default)(DocumentService, [{
|
|
@@ -5,9 +5,10 @@ describe('Feature flags', function () {
|
|
|
5
5
|
it('getProductSpecificFeatureFlags', function () {
|
|
6
6
|
var result = (0, _index.getProductSpecificFeatureFlags)({
|
|
7
7
|
testFF: true,
|
|
8
|
-
socketMessageMetricsFF: true
|
|
8
|
+
socketMessageMetricsFF: true,
|
|
9
|
+
enableFallbackToReconcile: true
|
|
9
10
|
}, 'confluence');
|
|
10
|
-
expect(result).toEqual(['confluence.
|
|
11
|
+
expect(result).toEqual(['confluence.frontend.collab.provider.testFF', 'confluence.frontend.collab.provider.socketMessageMetricsFF', 'confluence.frontend.collab.provider.enable-fallback-to-reconcile']);
|
|
11
12
|
});
|
|
12
13
|
it('getCollabProviderFeatureFlag return true', function () {
|
|
13
14
|
var result = (0, _index.getCollabProviderFeatureFlag)('testFF', {
|
|
@@ -9,7 +9,8 @@ exports.getProductSpecificFeatureFlags = void 0;
|
|
|
9
9
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
10
10
|
var defaultNCSFeatureFlags = {
|
|
11
11
|
testFF: false,
|
|
12
|
-
socketMessageMetricsFF: false
|
|
12
|
+
socketMessageMetricsFF: false,
|
|
13
|
+
enableFallbackToReconcile: false
|
|
13
14
|
};
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -17,8 +18,9 @@ var defaultNCSFeatureFlags = {
|
|
|
17
18
|
*/
|
|
18
19
|
var productKeys = {
|
|
19
20
|
confluence: {
|
|
20
|
-
testFF: 'confluence.
|
|
21
|
-
socketMessageMetricsFF: 'confluence.
|
|
21
|
+
testFF: 'confluence.frontend.collab.provider.testFF',
|
|
22
|
+
socketMessageMetricsFF: 'confluence.frontend.collab.provider.socketMessageMetricsFF',
|
|
23
|
+
enableFallbackToReconcile: 'confluence.frontend.collab.provider.enable-fallback-to-reconcile'
|
|
22
24
|
}
|
|
23
25
|
};
|
|
24
26
|
var filterFeatureFlagNames = function filterFeatureFlagNames(flags) {
|
|
@@ -43,6 +43,10 @@ var Provider = /*#__PURE__*/function (_Emitter) {
|
|
|
43
43
|
_this = _super.call(this);
|
|
44
44
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isChannelInitialized", false);
|
|
45
45
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isProviderInitialized", false);
|
|
46
|
+
// isBufferingEnabled is a boolean value passed to the config during provider creation.
|
|
47
|
+
// It determines if the provider should initialize immediately and will only be true if:
|
|
48
|
+
// the feature flag is enabled and the initial draft fetched from NCS is also passed in the config.
|
|
49
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isBufferingEnabled", false);
|
|
46
50
|
// isPreinitializating acts as a feature flag to determine when the provider has been initialized early
|
|
47
51
|
// and also contains the initial draft
|
|
48
52
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isPreinitializing", false);
|
|
@@ -96,6 +100,13 @@ var Provider = /*#__PURE__*/function (_Emitter) {
|
|
|
96
100
|
var sid = _ref2.sid,
|
|
97
101
|
initialized = _ref2.initialized;
|
|
98
102
|
_this.sessionId = sid;
|
|
103
|
+
// if buffering is enabled and the provider is initialized before connection, call catchup
|
|
104
|
+
// once setup resolves with the defined editor state
|
|
105
|
+
if (_this.isBufferingEnabled && _this.isProviderInitialized) {
|
|
106
|
+
_this.onSetupPromise.then(function () {
|
|
107
|
+
_this.documentService.sendStepsFromCurrentState();
|
|
108
|
+
});
|
|
109
|
+
}
|
|
99
110
|
_this.emitCallback('connected', {
|
|
100
111
|
sid: sid,
|
|
101
112
|
initial: !initialized
|
|
@@ -271,13 +282,14 @@ var Provider = /*#__PURE__*/function (_Emitter) {
|
|
|
271
282
|
_this.channel = new _channel.Channel(config, _this.analyticsHelper);
|
|
272
283
|
_this.isChannelInitialized = false;
|
|
273
284
|
_this.initialDraft = _this.config.initialDraft;
|
|
285
|
+
_this.isBufferingEnabled = Boolean(_this.config.isBufferingEnabled);
|
|
274
286
|
_this.isProviderInitialized = false;
|
|
275
287
|
_this.isPreinitializing = false;
|
|
276
288
|
_this.participantsService = new _participantsService.ParticipantsService(_this.analyticsHelper, undefined, _this.emitCallback, _this.config.getUser, _this.channel.broadcast, _this.channel.sendPresenceJoined, _this.getPresenceData, _this.setUserId);
|
|
277
289
|
_this.metadataService = new _metadataService.MetadataService(_this.emitCallback, _this.channel.sendMetadata);
|
|
278
|
-
_this.documentService = new _documentService.DocumentService(_this.participantsService, _this.analyticsHelper, _this.channel.fetchCatchup, _this.emitCallback, _this.channel.broadcast, function () {
|
|
290
|
+
_this.documentService = new _documentService.DocumentService(_this.participantsService, _this.analyticsHelper, _this.channel.fetchCatchup, _this.channel.fetchReconcile, _this.emitCallback, _this.channel.broadcast, function () {
|
|
279
291
|
return _this.userId;
|
|
280
|
-
}, _this.onErrorHandled, _this.metadataService, _this.config.failedStepLimitBeforeCatchupOnPublish, _this.config.enableErrorOnFailedDocumentApply);
|
|
292
|
+
}, _this.onErrorHandled, _this.metadataService, _this.config.failedStepLimitBeforeCatchupOnPublish, _this.config.enableErrorOnFailedDocumentApply, _this.config.featureFlags);
|
|
281
293
|
_this.onSetupPromise = new Promise(function (resolve) {
|
|
282
294
|
_this.resolveOnSetupPromise = resolve;
|
|
283
295
|
});
|
|
@@ -341,6 +353,17 @@ var Provider = /*#__PURE__*/function (_Emitter) {
|
|
|
341
353
|
// a defined getState (ie editor state is ready) AND after documentService sets the editor state
|
|
342
354
|
if (this.isPreinitializing) {
|
|
343
355
|
this.resolveOnSetupPromise();
|
|
356
|
+
if (this.isBufferingEnabled && this.initialDraft && !this.isProviderInitialized) {
|
|
357
|
+
var _this$initialDraft2 = this.initialDraft,
|
|
358
|
+
document = _this$initialDraft2.document,
|
|
359
|
+
version = _this$initialDraft2.version,
|
|
360
|
+
metadata = _this$initialDraft2.metadata;
|
|
361
|
+
this.updateDocumentAndMetadata({
|
|
362
|
+
doc: document,
|
|
363
|
+
version: version,
|
|
364
|
+
metadata: metadata
|
|
365
|
+
});
|
|
366
|
+
}
|
|
344
367
|
}
|
|
345
368
|
}
|
|
346
369
|
if (!this.isChannelInitialized) {
|
|
@@ -374,8 +397,8 @@ var Provider = /*#__PURE__*/function (_Emitter) {
|
|
|
374
397
|
}, {
|
|
375
398
|
key: "isDraftTimestampStale",
|
|
376
399
|
value: function isDraftTimestampStale() {
|
|
377
|
-
var _this$
|
|
378
|
-
if (!((_this$
|
|
400
|
+
var _this$initialDraft3;
|
|
401
|
+
if (!((_this$initialDraft3 = this.initialDraft) !== null && _this$initialDraft3 !== void 0 && _this$initialDraft3.timestamp)) {
|
|
379
402
|
return false;
|
|
380
403
|
}
|
|
381
404
|
return Date.now() - this.initialDraft.timestamp >= PRELOAD_DRAFT_SYNC_PERIOD;
|
|
@@ -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.
|
|
9
|
+
var version = "9.9.0";
|
|
10
10
|
exports.version = version;
|
|
11
11
|
var nextMajorVersion = function nextMajorVersion() {
|
|
12
12
|
return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
|
package/dist/cjs/version.json
CHANGED
package/dist/es2019/channel.js
CHANGED
|
@@ -228,6 +228,42 @@ export class Channel extends Emitter {
|
|
|
228
228
|
throw error;
|
|
229
229
|
}
|
|
230
230
|
});
|
|
231
|
+
_defineProperty(this, "fetchReconcile", async currentStateDoc => {
|
|
232
|
+
try {
|
|
233
|
+
var _ref2, _this$token2;
|
|
234
|
+
const reqBody = JSON.stringify({
|
|
235
|
+
doc: currentStateDoc,
|
|
236
|
+
productId: 'ccollab',
|
|
237
|
+
reason: 'UNKNOWN' // different reason here?
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
const reconcileResponse = await utils.requestService(this.config, {
|
|
241
|
+
path: `document/${encodeURIComponent(this.config.documentAri)}/reconcile`,
|
|
242
|
+
requestInit: {
|
|
243
|
+
headers: {
|
|
244
|
+
...(this.config.permissionTokenRefresh ? {
|
|
245
|
+
'x-token': (_ref2 = (_this$token2 = this.token) !== null && _this$token2 !== void 0 ? _this$token2 : await this.config.permissionTokenRefresh().then(token => {
|
|
246
|
+
if (token) {
|
|
247
|
+
this.setToken(token);
|
|
248
|
+
}
|
|
249
|
+
return token;
|
|
250
|
+
})) !== null && _ref2 !== void 0 ? _ref2 : undefined
|
|
251
|
+
} : {}),
|
|
252
|
+
'x-product': getProduct(this.config.productInfo),
|
|
253
|
+
'x-subproduct': getSubProduct(this.config.productInfo),
|
|
254
|
+
'Content-Type': 'application/json'
|
|
255
|
+
},
|
|
256
|
+
method: 'POST',
|
|
257
|
+
body: reqBody
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
return reconcileResponse;
|
|
261
|
+
} catch (error) {
|
|
262
|
+
var _this$analyticsHelper7;
|
|
263
|
+
(_this$analyticsHelper7 = this.analyticsHelper) === null || _this$analyticsHelper7 === void 0 ? void 0 : _this$analyticsHelper7.sendErrorEvent(error, 'Error while fetching reconciled document');
|
|
264
|
+
throw error;
|
|
265
|
+
}
|
|
266
|
+
});
|
|
231
267
|
/**
|
|
232
268
|
* Send message to the back-end service over the channel. Timestamp will be added server side.
|
|
233
269
|
* @throws {NotInitializedError} Channel not initialized
|
|
@@ -429,8 +465,8 @@ export class Channel extends Emitter {
|
|
|
429
465
|
try {
|
|
430
466
|
this.socket.connect();
|
|
431
467
|
} catch (error) {
|
|
432
|
-
var _this$
|
|
433
|
-
(_this$
|
|
468
|
+
var _this$analyticsHelper8;
|
|
469
|
+
(_this$analyticsHelper8 = this.analyticsHelper) === null || _this$analyticsHelper8 === void 0 ? void 0 : _this$analyticsHelper8.sendErrorEvent(error, 'Error while reconnecting the channel');
|
|
434
470
|
const reconnectionError = {
|
|
435
471
|
message: 'Caught error during reconnection',
|
|
436
472
|
data: {
|
|
@@ -509,8 +545,8 @@ export class Channel extends Emitter {
|
|
|
509
545
|
this.emit('error', rateLimitError);
|
|
510
546
|
throw new Error();
|
|
511
547
|
} else if (rateLimitType === this.RATE_LIMIT_TYPE_SOFT) {
|
|
512
|
-
var _this$
|
|
513
|
-
(_this$
|
|
548
|
+
var _this$analyticsHelper9;
|
|
549
|
+
(_this$analyticsHelper9 = this.analyticsHelper) === null || _this$analyticsHelper9 === void 0 ? void 0 : _this$analyticsHelper9.sendErrorEvent(rateLimitError, 'Rate limited');
|
|
514
550
|
}
|
|
515
551
|
}
|
|
516
552
|
}
|