@atlaskit/collab-provider 9.17.3 → 9.17.4
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 +7 -0
- package/dist/cjs/document/document-service.js +5 -4
- package/dist/cjs/provider/commit-step.js +106 -3
- package/dist/cjs/provider/index.js +12 -0
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/es2019/document/document-service.js +6 -5
- package/dist/es2019/provider/commit-step.js +102 -1
- package/dist/es2019/provider/index.js +12 -0
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/esm/document/document-service.js +6 -5
- package/dist/esm/provider/commit-step.js +105 -2
- package/dist/esm/provider/index.js +12 -0
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/types/document/document-service.d.ts +1 -0
- package/dist/types/provider/commit-step.d.ts +13 -2
- package/dist/types/provider/index.d.ts +1 -0
- package/dist/types-ts4.5/document/document-service.d.ts +1 -0
- package/dist/types-ts4.5/provider/commit-step.d.ts +13 -2
- package/dist/types-ts4.5/provider/index.d.ts +1 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @atlaskit/collab-provider
|
|
2
2
|
|
|
3
|
+
## 9.17.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#57317](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/57317) [`d989b4568594`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/d989b4568594) - ESS-4149: Add send steps queue under FF
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
|
|
3
10
|
## 9.17.3
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
|
@@ -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(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
25
26
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
@@ -43,11 +44,12 @@ var DocumentService = exports.DocumentService = /*#__PURE__*/function () {
|
|
|
43
44
|
* @param onErrorHandled - Callback to handle
|
|
44
45
|
* @param metadataService
|
|
45
46
|
* @param enableErrorOnFailedDocumentApply - Enable failed document update exceptions.
|
|
47
|
+
* @param enableSendStepsQueue - Enable send steps queue.
|
|
46
48
|
*/
|
|
47
49
|
function DocumentService(participantsService, analyticsHelper, fetchCatchup, fetchReconcile, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService) {
|
|
48
50
|
var _this = this;
|
|
49
51
|
var enableErrorOnFailedDocumentApply = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false;
|
|
50
|
-
var enableSendStepsQueue = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] :
|
|
52
|
+
var enableSendStepsQueue = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : (0, _featureFlags.getCollabProviderFeatureFlag)('sendStepsQueueFF');
|
|
51
53
|
(0, _classCallCheck2.default)(this, DocumentService);
|
|
52
54
|
// Fires analytics to editor when collab editor cannot sync up
|
|
53
55
|
(0, _defineProperty2.default)(this, "stepRejectCounter", 0);
|
|
@@ -112,7 +114,7 @@ var DocumentService = exports.DocumentService = /*#__PURE__*/function () {
|
|
|
112
114
|
_context.prev = 16;
|
|
113
115
|
_this.stepQueue.resumeQueue();
|
|
114
116
|
_this.processQueue();
|
|
115
|
-
_this.sendStepsFromCurrentState(); // this will eventually retry catchup as it calls
|
|
117
|
+
_this.sendStepsFromCurrentState(); // this will eventually retry catchup as it calls throttledCommitStep which will either catchup on onStepsAdded or onErrorHandled
|
|
116
118
|
_this.stepRejectCounter = 0;
|
|
117
119
|
return _context.finish(16);
|
|
118
120
|
case 22:
|
|
@@ -663,7 +665,6 @@ var DocumentService = exports.DocumentService = /*#__PURE__*/function () {
|
|
|
663
665
|
return;
|
|
664
666
|
}
|
|
665
667
|
if (this.enableSendStepsQueue) {
|
|
666
|
-
// This is where we would call the sendStepsQueue instead of throttledCommitStep
|
|
667
668
|
// Only send 1% of events to avoid useless logging
|
|
668
669
|
if (Math.random() < 0.01) {
|
|
669
670
|
var _this$analyticsHelper29;
|
|
@@ -672,7 +673,7 @@ var DocumentService = exports.DocumentService = /*#__PURE__*/function () {
|
|
|
672
673
|
// Avoid reference issues using a
|
|
673
674
|
// method outside of the provider
|
|
674
675
|
// scope
|
|
675
|
-
(0, _commitStep.
|
|
676
|
+
(0, _commitStep.commitStepQueue)({
|
|
676
677
|
broadcast: this.broadcast,
|
|
677
678
|
userId: this.getUserId(),
|
|
678
679
|
clientId: this.clientId,
|
|
@@ -4,18 +4,20 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.throttledCommitStep = exports.commitStep = void 0;
|
|
7
|
+
exports.throttledCommitStep = exports.commitStepQueue = exports.commitStep = void 0;
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
9
|
var _countBy = _interopRequireDefault(require("lodash/countBy"));
|
|
10
10
|
var _throttle = _interopRequireDefault(require("lodash/throttle"));
|
|
11
11
|
var _const = require("../helpers/const");
|
|
12
12
|
var _types = require("../types");
|
|
13
13
|
var _errorTypes = require("../errors/error-types");
|
|
14
|
+
var _utils = require("../helpers/utils");
|
|
14
15
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
15
16
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
16
17
|
var SEND_STEPS_THROTTLE = 500; // 0.5 second
|
|
17
|
-
|
|
18
|
-
var
|
|
18
|
+
var logger = (0, _utils.createLogger)('commit-step', 'black');
|
|
19
|
+
var readyToCommit = true;
|
|
20
|
+
var commitStepQueue = exports.commitStepQueue = function commitStepQueue(_ref) {
|
|
19
21
|
var broadcast = _ref.broadcast,
|
|
20
22
|
steps = _ref.steps,
|
|
21
23
|
version = _ref.version,
|
|
@@ -25,6 +27,107 @@ var commitStep = exports.commitStep = function commitStep(_ref) {
|
|
|
25
27
|
onErrorHandled = _ref.onErrorHandled,
|
|
26
28
|
analyticsHelper = _ref.analyticsHelper,
|
|
27
29
|
emit = _ref.emit;
|
|
30
|
+
if (!readyToCommit) {
|
|
31
|
+
logger('Not ready to commit, skip');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Block other sending request, before ACK
|
|
35
|
+
readyToCommit = false;
|
|
36
|
+
var timer = setTimeout(function () {
|
|
37
|
+
readyToCommit = true;
|
|
38
|
+
logger('reset readyToCommit by timer');
|
|
39
|
+
}, 5000);
|
|
40
|
+
var stepsWithClientAndUserId = steps.map(function (step) {
|
|
41
|
+
return _objectSpread(_objectSpread({}, step.toJSON()), {}, {
|
|
42
|
+
clientId: clientId,
|
|
43
|
+
userId: userId
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
var start = new Date().getTime();
|
|
47
|
+
emit('commit-status', {
|
|
48
|
+
status: 'attempt',
|
|
49
|
+
version: version
|
|
50
|
+
});
|
|
51
|
+
try {
|
|
52
|
+
broadcast('steps:commit', {
|
|
53
|
+
steps: stepsWithClientAndUserId,
|
|
54
|
+
version: version,
|
|
55
|
+
userId: userId
|
|
56
|
+
}, function (response) {
|
|
57
|
+
var latency = new Date().getTime() - start;
|
|
58
|
+
if (timer) {
|
|
59
|
+
clearTimeout(timer);
|
|
60
|
+
if (latency <= 400) {
|
|
61
|
+
setTimeout(function () {
|
|
62
|
+
readyToCommit = true;
|
|
63
|
+
logger('reset readyToCommit');
|
|
64
|
+
}, 100);
|
|
65
|
+
} else {
|
|
66
|
+
readyToCommit = true;
|
|
67
|
+
logger('reset readyToCommit');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (response.type === _types.AcknowledgementResponseTypes.SUCCESS) {
|
|
71
|
+
onStepsAdded({
|
|
72
|
+
steps: stepsWithClientAndUserId,
|
|
73
|
+
version: response.version
|
|
74
|
+
});
|
|
75
|
+
// Sample only 10% of add steps events to avoid overwhelming the analytics
|
|
76
|
+
if (Math.random() < 0.1) {
|
|
77
|
+
analyticsHelper === null || analyticsHelper === void 0 || analyticsHelper.sendActionEvent(_const.EVENT_ACTION.ADD_STEPS, _const.EVENT_STATUS.SUCCESS_10x_SAMPLED, {
|
|
78
|
+
type: _const.ADD_STEPS_TYPE.ACCEPTED,
|
|
79
|
+
latency: latency,
|
|
80
|
+
stepType: (0, _countBy.default)(stepsWithClientAndUserId, function (stepWithClientAndUserId) {
|
|
81
|
+
return stepWithClientAndUserId.stepType;
|
|
82
|
+
})
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
emit('commit-status', {
|
|
86
|
+
status: 'success',
|
|
87
|
+
version: response.version
|
|
88
|
+
});
|
|
89
|
+
} else if (response.type === _types.AcknowledgementResponseTypes.ERROR) {
|
|
90
|
+
onErrorHandled(response.error);
|
|
91
|
+
analyticsHelper === null || analyticsHelper === void 0 || analyticsHelper.sendActionEvent(_const.EVENT_ACTION.ADD_STEPS, _const.EVENT_STATUS.FAILURE, {
|
|
92
|
+
// User tried committing steps but they were rejected because:
|
|
93
|
+
// - HEAD_VERSION_UPDATE_FAILED: the collab service's latest stored step tail version didn't correspond to the head version of the first step submitted
|
|
94
|
+
// - VERSION_NUMBER_ALREADY_EXISTS: while storing the steps there was a conflict meaning someone else wrote steps into the database more quickly
|
|
95
|
+
type: response.error.data.code === _errorTypes.NCS_ERROR_CODE.HEAD_VERSION_UPDATE_FAILED || response.error.data.code === _errorTypes.NCS_ERROR_CODE.VERSION_NUMBER_ALREADY_EXISTS ? _const.ADD_STEPS_TYPE.REJECTED : _const.ADD_STEPS_TYPE.ERROR,
|
|
96
|
+
latency: latency
|
|
97
|
+
});
|
|
98
|
+
analyticsHelper === null || analyticsHelper === void 0 || analyticsHelper.sendErrorEvent(response.error, 'Error while adding steps - Acknowledgement Error');
|
|
99
|
+
emit('commit-status', {
|
|
100
|
+
status: 'failure',
|
|
101
|
+
version: version
|
|
102
|
+
});
|
|
103
|
+
} else {
|
|
104
|
+
analyticsHelper === null || analyticsHelper === void 0 || analyticsHelper.sendErrorEvent(
|
|
105
|
+
// @ts-expect-error We didn't type the invalid type case
|
|
106
|
+
new Error("Response type: ".concat((response === null || response === void 0 ? void 0 : response.type) || 'No response type')), 'Error while adding steps - Invalid Acknowledgement');
|
|
107
|
+
emit('commit-status', {
|
|
108
|
+
status: 'failure',
|
|
109
|
+
version: version
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
} catch (error) {
|
|
114
|
+
analyticsHelper === null || analyticsHelper === void 0 || analyticsHelper.sendErrorEvent(error, 'Error while adding steps - Broadcast threw exception');
|
|
115
|
+
emit('commit-status', {
|
|
116
|
+
status: 'failure',
|
|
117
|
+
version: version
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
var commitStep = exports.commitStep = function commitStep(_ref2) {
|
|
122
|
+
var broadcast = _ref2.broadcast,
|
|
123
|
+
steps = _ref2.steps,
|
|
124
|
+
version = _ref2.version,
|
|
125
|
+
userId = _ref2.userId,
|
|
126
|
+
clientId = _ref2.clientId,
|
|
127
|
+
onStepsAdded = _ref2.onStepsAdded,
|
|
128
|
+
onErrorHandled = _ref2.onErrorHandled,
|
|
129
|
+
analyticsHelper = _ref2.analyticsHelper,
|
|
130
|
+
emit = _ref2.emit;
|
|
28
131
|
var stepsWithClientAndUserId = steps.map(function (step) {
|
|
29
132
|
return _objectSpread(_objectSpread({}, step.toJSON()), {}, {
|
|
30
133
|
clientId: clientId,
|
|
@@ -274,6 +274,12 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
|
|
|
274
274
|
return _this.userId;
|
|
275
275
|
}, _this.onErrorHandled, _this.metadataService, _this.config.enableErrorOnFailedDocumentApply, (0, _featureFlags.getCollabProviderFeatureFlag)('sendStepsQueueFF', _this.config.featureFlags));
|
|
276
276
|
_this.namespaceService = new _namespaceService.NamespaceService();
|
|
277
|
+
if ((0, _featureFlags.getCollabProviderFeatureFlag)('sendStepsQueueFF', _this.config.featureFlags)) {
|
|
278
|
+
_this.sendStepsTimer = setInterval(function () {
|
|
279
|
+
logger('Intervally sendStepsFromCurrentState');
|
|
280
|
+
_this.documentService.sendStepsFromCurrentState(true);
|
|
281
|
+
}, 5000);
|
|
282
|
+
}
|
|
277
283
|
return _this;
|
|
278
284
|
}
|
|
279
285
|
(0, _createClass2.default)(Provider, [{
|
|
@@ -468,6 +474,12 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
|
|
|
468
474
|
try {
|
|
469
475
|
(0, _get2.default)((0, _getPrototypeOf2.default)(Provider.prototype), "unsubscribeAll", this).call(this);
|
|
470
476
|
this.channel.disconnect();
|
|
477
|
+
if ((0, _featureFlags.getCollabProviderFeatureFlag)('sendStepsQueueFF', this.config.featureFlags)) {
|
|
478
|
+
if (this.sendStepsTimer) {
|
|
479
|
+
clearInterval(this.sendStepsTimer);
|
|
480
|
+
this.sendStepsTimer = undefined;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
471
483
|
} catch (error) {
|
|
472
484
|
var _this$analyticsHelper11;
|
|
473
485
|
(_this$analyticsHelper11 = this.analyticsHelper) === null || _this$analyticsHelper11 === void 0 || _this$analyticsHelper11.sendErrorEvent(error, 'Error while shutting down the collab provider');
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.version = exports.nextMajorVersion = exports.name = void 0;
|
|
7
7
|
var name = exports.name = "@atlaskit/collab-provider";
|
|
8
|
-
var version = exports.version = "9.17.
|
|
8
|
+
var version = exports.version = "9.17.4";
|
|
9
9
|
var nextMajorVersion = exports.nextMajorVersion = function nextMajorVersion() {
|
|
10
10
|
return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
|
|
11
11
|
};
|
|
@@ -3,12 +3,13 @@ import { ACK_MAX_TRY, EVENT_ACTION, EVENT_STATUS } from '../helpers/const';
|
|
|
3
3
|
import { getVersion, sendableSteps } from '@atlaskit/prosemirror-collab';
|
|
4
4
|
import { createLogger, getStepUGCFreeDetails, sleep } from '../helpers/utils';
|
|
5
5
|
import throttle from 'lodash/throttle';
|
|
6
|
-
import { throttledCommitStep } from '../provider/commit-step';
|
|
6
|
+
import { throttledCommitStep, commitStepQueue } from '../provider/commit-step';
|
|
7
7
|
import { MEASURE_NAME, startMeasure, stopMeasure } from '../analytics/performance';
|
|
8
8
|
import { JSONTransformer } from '@atlaskit/editor-json-transformer';
|
|
9
9
|
import { MAX_STEP_REJECTED_ERROR, MAX_STEP_REJECTED_ERROR_AGGRESSIVE } from '../provider';
|
|
10
10
|
import { catchup } from './catchup';
|
|
11
11
|
import { StepQueueState } from './step-queue-state';
|
|
12
|
+
import { getCollabProviderFeatureFlag } from '../feature-flags';
|
|
12
13
|
import { CantSyncUpError, INTERNAL_ERROR_CODE, UpdateDocumentError } from '../errors/error-types';
|
|
13
14
|
const CATCHUP_THROTTLE = 1 * 1000; // 1 second
|
|
14
15
|
|
|
@@ -30,8 +31,9 @@ export class DocumentService {
|
|
|
30
31
|
* @param onErrorHandled - Callback to handle
|
|
31
32
|
* @param metadataService
|
|
32
33
|
* @param enableErrorOnFailedDocumentApply - Enable failed document update exceptions.
|
|
34
|
+
* @param enableSendStepsQueue - Enable send steps queue.
|
|
33
35
|
*/
|
|
34
|
-
constructor(participantsService, analyticsHelper, fetchCatchup, fetchReconcile, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService, enableErrorOnFailedDocumentApply = false, enableSendStepsQueue =
|
|
36
|
+
constructor(participantsService, analyticsHelper, fetchCatchup, fetchReconcile, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService, enableErrorOnFailedDocumentApply = false, enableSendStepsQueue = getCollabProviderFeatureFlag('sendStepsQueueFF')) {
|
|
35
37
|
// Fires analytics to editor when collab editor cannot sync up
|
|
36
38
|
_defineProperty(this, "stepRejectCounter", 0);
|
|
37
39
|
_defineProperty(this, "aggressiveCatchup", false);
|
|
@@ -82,7 +84,7 @@ export class DocumentService {
|
|
|
82
84
|
} finally {
|
|
83
85
|
this.stepQueue.resumeQueue();
|
|
84
86
|
this.processQueue();
|
|
85
|
-
this.sendStepsFromCurrentState(); // this will eventually retry catchup as it calls
|
|
87
|
+
this.sendStepsFromCurrentState(); // this will eventually retry catchup as it calls throttledCommitStep which will either catchup on onStepsAdded or onErrorHandled
|
|
86
88
|
this.stepRejectCounter = 0;
|
|
87
89
|
}
|
|
88
90
|
});
|
|
@@ -561,7 +563,6 @@ export class DocumentService {
|
|
|
561
563
|
return;
|
|
562
564
|
}
|
|
563
565
|
if (this.enableSendStepsQueue) {
|
|
564
|
-
// This is where we would call the sendStepsQueue instead of throttledCommitStep
|
|
565
566
|
// Only send 1% of events to avoid useless logging
|
|
566
567
|
if (Math.random() < 0.01) {
|
|
567
568
|
var _this$analyticsHelper29;
|
|
@@ -570,7 +571,7 @@ export class DocumentService {
|
|
|
570
571
|
// Avoid reference issues using a
|
|
571
572
|
// method outside of the provider
|
|
572
573
|
// scope
|
|
573
|
-
|
|
574
|
+
commitStepQueue({
|
|
574
575
|
broadcast: this.broadcast,
|
|
575
576
|
userId: this.getUserId(),
|
|
576
577
|
clientId: this.clientId,
|
|
@@ -3,8 +3,109 @@ import throttle from 'lodash/throttle';
|
|
|
3
3
|
import { ADD_STEPS_TYPE, EVENT_ACTION, EVENT_STATUS } from '../helpers/const';
|
|
4
4
|
import { AcknowledgementResponseTypes } from '../types';
|
|
5
5
|
import { NCS_ERROR_CODE } from '../errors/error-types';
|
|
6
|
+
import { createLogger } from '../helpers/utils';
|
|
6
7
|
const SEND_STEPS_THROTTLE = 500; // 0.5 second
|
|
7
|
-
|
|
8
|
+
const logger = createLogger('commit-step', 'black');
|
|
9
|
+
let readyToCommit = true;
|
|
10
|
+
export const commitStepQueue = ({
|
|
11
|
+
broadcast,
|
|
12
|
+
steps,
|
|
13
|
+
version,
|
|
14
|
+
userId,
|
|
15
|
+
clientId,
|
|
16
|
+
onStepsAdded,
|
|
17
|
+
onErrorHandled,
|
|
18
|
+
analyticsHelper,
|
|
19
|
+
emit
|
|
20
|
+
}) => {
|
|
21
|
+
if (!readyToCommit) {
|
|
22
|
+
logger('Not ready to commit, skip');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Block other sending request, before ACK
|
|
26
|
+
readyToCommit = false;
|
|
27
|
+
const timer = setTimeout(() => {
|
|
28
|
+
readyToCommit = true;
|
|
29
|
+
logger('reset readyToCommit by timer');
|
|
30
|
+
}, 5000);
|
|
31
|
+
const stepsWithClientAndUserId = steps.map(step => ({
|
|
32
|
+
...step.toJSON(),
|
|
33
|
+
clientId,
|
|
34
|
+
userId
|
|
35
|
+
}));
|
|
36
|
+
const start = new Date().getTime();
|
|
37
|
+
emit('commit-status', {
|
|
38
|
+
status: 'attempt',
|
|
39
|
+
version
|
|
40
|
+
});
|
|
41
|
+
try {
|
|
42
|
+
broadcast('steps:commit', {
|
|
43
|
+
steps: stepsWithClientAndUserId,
|
|
44
|
+
version,
|
|
45
|
+
userId
|
|
46
|
+
}, response => {
|
|
47
|
+
const latency = new Date().getTime() - start;
|
|
48
|
+
if (timer) {
|
|
49
|
+
clearTimeout(timer);
|
|
50
|
+
if (latency <= 400) {
|
|
51
|
+
setTimeout(() => {
|
|
52
|
+
readyToCommit = true;
|
|
53
|
+
logger('reset readyToCommit');
|
|
54
|
+
}, 100);
|
|
55
|
+
} else {
|
|
56
|
+
readyToCommit = true;
|
|
57
|
+
logger('reset readyToCommit');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (response.type === AcknowledgementResponseTypes.SUCCESS) {
|
|
61
|
+
onStepsAdded({
|
|
62
|
+
steps: stepsWithClientAndUserId,
|
|
63
|
+
version: response.version
|
|
64
|
+
});
|
|
65
|
+
// Sample only 10% of add steps events to avoid overwhelming the analytics
|
|
66
|
+
if (Math.random() < 0.1) {
|
|
67
|
+
analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendActionEvent(EVENT_ACTION.ADD_STEPS, EVENT_STATUS.SUCCESS_10x_SAMPLED, {
|
|
68
|
+
type: ADD_STEPS_TYPE.ACCEPTED,
|
|
69
|
+
latency,
|
|
70
|
+
stepType: countBy(stepsWithClientAndUserId, stepWithClientAndUserId => stepWithClientAndUserId.stepType)
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
emit('commit-status', {
|
|
74
|
+
status: 'success',
|
|
75
|
+
version: response.version
|
|
76
|
+
});
|
|
77
|
+
} else if (response.type === AcknowledgementResponseTypes.ERROR) {
|
|
78
|
+
onErrorHandled(response.error);
|
|
79
|
+
analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendActionEvent(EVENT_ACTION.ADD_STEPS, EVENT_STATUS.FAILURE, {
|
|
80
|
+
// User tried committing steps but they were rejected because:
|
|
81
|
+
// - HEAD_VERSION_UPDATE_FAILED: the collab service's latest stored step tail version didn't correspond to the head version of the first step submitted
|
|
82
|
+
// - VERSION_NUMBER_ALREADY_EXISTS: while storing the steps there was a conflict meaning someone else wrote steps into the database more quickly
|
|
83
|
+
type: response.error.data.code === NCS_ERROR_CODE.HEAD_VERSION_UPDATE_FAILED || response.error.data.code === NCS_ERROR_CODE.VERSION_NUMBER_ALREADY_EXISTS ? ADD_STEPS_TYPE.REJECTED : ADD_STEPS_TYPE.ERROR,
|
|
84
|
+
latency
|
|
85
|
+
});
|
|
86
|
+
analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(response.error, 'Error while adding steps - Acknowledgement Error');
|
|
87
|
+
emit('commit-status', {
|
|
88
|
+
status: 'failure',
|
|
89
|
+
version
|
|
90
|
+
});
|
|
91
|
+
} else {
|
|
92
|
+
analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(
|
|
93
|
+
// @ts-expect-error We didn't type the invalid type case
|
|
94
|
+
new Error(`Response type: ${(response === null || response === void 0 ? void 0 : response.type) || 'No response type'}`), 'Error while adding steps - Invalid Acknowledgement');
|
|
95
|
+
emit('commit-status', {
|
|
96
|
+
status: 'failure',
|
|
97
|
+
version
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
} catch (error) {
|
|
102
|
+
analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(error, 'Error while adding steps - Broadcast threw exception');
|
|
103
|
+
emit('commit-status', {
|
|
104
|
+
status: 'failure',
|
|
105
|
+
version
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
};
|
|
8
109
|
export const commitStep = ({
|
|
9
110
|
broadcast,
|
|
10
111
|
steps,
|
|
@@ -227,6 +227,12 @@ export class Provider extends Emitter {
|
|
|
227
227
|
this.metadataService = new MetadataService(this.emitCallback, this.channel.sendMetadata);
|
|
228
228
|
this.documentService = new DocumentService(this.participantsService, this.analyticsHelper, this.channel.fetchCatchup, this.channel.fetchReconcile, this.emitCallback, this.channel.broadcast, () => this.userId, this.onErrorHandled, this.metadataService, this.config.enableErrorOnFailedDocumentApply, getCollabProviderFeatureFlag('sendStepsQueueFF', this.config.featureFlags));
|
|
229
229
|
this.namespaceService = new NamespaceService();
|
|
230
|
+
if (getCollabProviderFeatureFlag('sendStepsQueueFF', this.config.featureFlags)) {
|
|
231
|
+
this.sendStepsTimer = setInterval(() => {
|
|
232
|
+
logger('Intervally sendStepsFromCurrentState');
|
|
233
|
+
this.documentService.sendStepsFromCurrentState(true);
|
|
234
|
+
}, 5000);
|
|
235
|
+
}
|
|
230
236
|
}
|
|
231
237
|
/**
|
|
232
238
|
* Initialisation logic, called by Jira with a dummy getState function, deprecated in favour of the setup method which allows more configuration
|
|
@@ -398,6 +404,12 @@ export class Provider extends Emitter {
|
|
|
398
404
|
try {
|
|
399
405
|
super.unsubscribeAll();
|
|
400
406
|
this.channel.disconnect();
|
|
407
|
+
if (getCollabProviderFeatureFlag('sendStepsQueueFF', this.config.featureFlags)) {
|
|
408
|
+
if (this.sendStepsTimer) {
|
|
409
|
+
clearInterval(this.sendStepsTimer);
|
|
410
|
+
this.sendStepsTimer = undefined;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
401
413
|
} catch (error) {
|
|
402
414
|
var _this$analyticsHelper11;
|
|
403
415
|
(_this$analyticsHelper11 = this.analyticsHelper) === null || _this$analyticsHelper11 === void 0 ? void 0 : _this$analyticsHelper11.sendErrorEvent(error, 'Error while shutting down the collab provider');
|
|
@@ -9,12 +9,13 @@ import { ACK_MAX_TRY, EVENT_ACTION, EVENT_STATUS } from '../helpers/const';
|
|
|
9
9
|
import { getVersion, sendableSteps } from '@atlaskit/prosemirror-collab';
|
|
10
10
|
import { createLogger, getStepUGCFreeDetails, sleep } from '../helpers/utils';
|
|
11
11
|
import throttle from 'lodash/throttle';
|
|
12
|
-
import { throttledCommitStep } from '../provider/commit-step';
|
|
12
|
+
import { throttledCommitStep, commitStepQueue } from '../provider/commit-step';
|
|
13
13
|
import { MEASURE_NAME, startMeasure, stopMeasure } from '../analytics/performance';
|
|
14
14
|
import { JSONTransformer } from '@atlaskit/editor-json-transformer';
|
|
15
15
|
import { MAX_STEP_REJECTED_ERROR, MAX_STEP_REJECTED_ERROR_AGGRESSIVE } from '../provider';
|
|
16
16
|
import { catchup } from './catchup';
|
|
17
17
|
import { StepQueueState } from './step-queue-state';
|
|
18
|
+
import { getCollabProviderFeatureFlag } from '../feature-flags';
|
|
18
19
|
import { CantSyncUpError, INTERNAL_ERROR_CODE, UpdateDocumentError } from '../errors/error-types';
|
|
19
20
|
var CATCHUP_THROTTLE = 1 * 1000; // 1 second
|
|
20
21
|
|
|
@@ -36,11 +37,12 @@ export var DocumentService = /*#__PURE__*/function () {
|
|
|
36
37
|
* @param onErrorHandled - Callback to handle
|
|
37
38
|
* @param metadataService
|
|
38
39
|
* @param enableErrorOnFailedDocumentApply - Enable failed document update exceptions.
|
|
40
|
+
* @param enableSendStepsQueue - Enable send steps queue.
|
|
39
41
|
*/
|
|
40
42
|
function DocumentService(participantsService, analyticsHelper, fetchCatchup, fetchReconcile, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService) {
|
|
41
43
|
var _this = this;
|
|
42
44
|
var enableErrorOnFailedDocumentApply = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false;
|
|
43
|
-
var enableSendStepsQueue = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] :
|
|
45
|
+
var enableSendStepsQueue = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : getCollabProviderFeatureFlag('sendStepsQueueFF');
|
|
44
46
|
_classCallCheck(this, DocumentService);
|
|
45
47
|
// Fires analytics to editor when collab editor cannot sync up
|
|
46
48
|
_defineProperty(this, "stepRejectCounter", 0);
|
|
@@ -105,7 +107,7 @@ export var DocumentService = /*#__PURE__*/function () {
|
|
|
105
107
|
_context.prev = 16;
|
|
106
108
|
_this.stepQueue.resumeQueue();
|
|
107
109
|
_this.processQueue();
|
|
108
|
-
_this.sendStepsFromCurrentState(); // this will eventually retry catchup as it calls
|
|
110
|
+
_this.sendStepsFromCurrentState(); // this will eventually retry catchup as it calls throttledCommitStep which will either catchup on onStepsAdded or onErrorHandled
|
|
109
111
|
_this.stepRejectCounter = 0;
|
|
110
112
|
return _context.finish(16);
|
|
111
113
|
case 22:
|
|
@@ -656,7 +658,6 @@ export var DocumentService = /*#__PURE__*/function () {
|
|
|
656
658
|
return;
|
|
657
659
|
}
|
|
658
660
|
if (this.enableSendStepsQueue) {
|
|
659
|
-
// This is where we would call the sendStepsQueue instead of throttledCommitStep
|
|
660
661
|
// Only send 1% of events to avoid useless logging
|
|
661
662
|
if (Math.random() < 0.01) {
|
|
662
663
|
var _this$analyticsHelper29;
|
|
@@ -665,7 +666,7 @@ export var DocumentService = /*#__PURE__*/function () {
|
|
|
665
666
|
// Avoid reference issues using a
|
|
666
667
|
// method outside of the provider
|
|
667
668
|
// scope
|
|
668
|
-
|
|
669
|
+
commitStepQueue({
|
|
669
670
|
broadcast: this.broadcast,
|
|
670
671
|
userId: this.getUserId(),
|
|
671
672
|
clientId: this.clientId,
|
|
@@ -6,9 +6,11 @@ import throttle from 'lodash/throttle';
|
|
|
6
6
|
import { ADD_STEPS_TYPE, EVENT_ACTION, EVENT_STATUS } from '../helpers/const';
|
|
7
7
|
import { AcknowledgementResponseTypes } from '../types';
|
|
8
8
|
import { NCS_ERROR_CODE } from '../errors/error-types';
|
|
9
|
+
import { createLogger } from '../helpers/utils';
|
|
9
10
|
var SEND_STEPS_THROTTLE = 500; // 0.5 second
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
var logger = createLogger('commit-step', 'black');
|
|
12
|
+
var readyToCommit = true;
|
|
13
|
+
export var commitStepQueue = function commitStepQueue(_ref) {
|
|
12
14
|
var broadcast = _ref.broadcast,
|
|
13
15
|
steps = _ref.steps,
|
|
14
16
|
version = _ref.version,
|
|
@@ -18,6 +20,107 @@ export var commitStep = function commitStep(_ref) {
|
|
|
18
20
|
onErrorHandled = _ref.onErrorHandled,
|
|
19
21
|
analyticsHelper = _ref.analyticsHelper,
|
|
20
22
|
emit = _ref.emit;
|
|
23
|
+
if (!readyToCommit) {
|
|
24
|
+
logger('Not ready to commit, skip');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
// Block other sending request, before ACK
|
|
28
|
+
readyToCommit = false;
|
|
29
|
+
var timer = setTimeout(function () {
|
|
30
|
+
readyToCommit = true;
|
|
31
|
+
logger('reset readyToCommit by timer');
|
|
32
|
+
}, 5000);
|
|
33
|
+
var stepsWithClientAndUserId = steps.map(function (step) {
|
|
34
|
+
return _objectSpread(_objectSpread({}, step.toJSON()), {}, {
|
|
35
|
+
clientId: clientId,
|
|
36
|
+
userId: userId
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
var start = new Date().getTime();
|
|
40
|
+
emit('commit-status', {
|
|
41
|
+
status: 'attempt',
|
|
42
|
+
version: version
|
|
43
|
+
});
|
|
44
|
+
try {
|
|
45
|
+
broadcast('steps:commit', {
|
|
46
|
+
steps: stepsWithClientAndUserId,
|
|
47
|
+
version: version,
|
|
48
|
+
userId: userId
|
|
49
|
+
}, function (response) {
|
|
50
|
+
var latency = new Date().getTime() - start;
|
|
51
|
+
if (timer) {
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
if (latency <= 400) {
|
|
54
|
+
setTimeout(function () {
|
|
55
|
+
readyToCommit = true;
|
|
56
|
+
logger('reset readyToCommit');
|
|
57
|
+
}, 100);
|
|
58
|
+
} else {
|
|
59
|
+
readyToCommit = true;
|
|
60
|
+
logger('reset readyToCommit');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (response.type === AcknowledgementResponseTypes.SUCCESS) {
|
|
64
|
+
onStepsAdded({
|
|
65
|
+
steps: stepsWithClientAndUserId,
|
|
66
|
+
version: response.version
|
|
67
|
+
});
|
|
68
|
+
// Sample only 10% of add steps events to avoid overwhelming the analytics
|
|
69
|
+
if (Math.random() < 0.1) {
|
|
70
|
+
analyticsHelper === null || analyticsHelper === void 0 || analyticsHelper.sendActionEvent(EVENT_ACTION.ADD_STEPS, EVENT_STATUS.SUCCESS_10x_SAMPLED, {
|
|
71
|
+
type: ADD_STEPS_TYPE.ACCEPTED,
|
|
72
|
+
latency: latency,
|
|
73
|
+
stepType: countBy(stepsWithClientAndUserId, function (stepWithClientAndUserId) {
|
|
74
|
+
return stepWithClientAndUserId.stepType;
|
|
75
|
+
})
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
emit('commit-status', {
|
|
79
|
+
status: 'success',
|
|
80
|
+
version: response.version
|
|
81
|
+
});
|
|
82
|
+
} else if (response.type === AcknowledgementResponseTypes.ERROR) {
|
|
83
|
+
onErrorHandled(response.error);
|
|
84
|
+
analyticsHelper === null || analyticsHelper === void 0 || analyticsHelper.sendActionEvent(EVENT_ACTION.ADD_STEPS, EVENT_STATUS.FAILURE, {
|
|
85
|
+
// User tried committing steps but they were rejected because:
|
|
86
|
+
// - HEAD_VERSION_UPDATE_FAILED: the collab service's latest stored step tail version didn't correspond to the head version of the first step submitted
|
|
87
|
+
// - VERSION_NUMBER_ALREADY_EXISTS: while storing the steps there was a conflict meaning someone else wrote steps into the database more quickly
|
|
88
|
+
type: response.error.data.code === NCS_ERROR_CODE.HEAD_VERSION_UPDATE_FAILED || response.error.data.code === NCS_ERROR_CODE.VERSION_NUMBER_ALREADY_EXISTS ? ADD_STEPS_TYPE.REJECTED : ADD_STEPS_TYPE.ERROR,
|
|
89
|
+
latency: latency
|
|
90
|
+
});
|
|
91
|
+
analyticsHelper === null || analyticsHelper === void 0 || analyticsHelper.sendErrorEvent(response.error, 'Error while adding steps - Acknowledgement Error');
|
|
92
|
+
emit('commit-status', {
|
|
93
|
+
status: 'failure',
|
|
94
|
+
version: version
|
|
95
|
+
});
|
|
96
|
+
} else {
|
|
97
|
+
analyticsHelper === null || analyticsHelper === void 0 || analyticsHelper.sendErrorEvent(
|
|
98
|
+
// @ts-expect-error We didn't type the invalid type case
|
|
99
|
+
new Error("Response type: ".concat((response === null || response === void 0 ? void 0 : response.type) || 'No response type')), 'Error while adding steps - Invalid Acknowledgement');
|
|
100
|
+
emit('commit-status', {
|
|
101
|
+
status: 'failure',
|
|
102
|
+
version: version
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
} catch (error) {
|
|
107
|
+
analyticsHelper === null || analyticsHelper === void 0 || analyticsHelper.sendErrorEvent(error, 'Error while adding steps - Broadcast threw exception');
|
|
108
|
+
emit('commit-status', {
|
|
109
|
+
status: 'failure',
|
|
110
|
+
version: version
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
export var commitStep = function commitStep(_ref2) {
|
|
115
|
+
var broadcast = _ref2.broadcast,
|
|
116
|
+
steps = _ref2.steps,
|
|
117
|
+
version = _ref2.version,
|
|
118
|
+
userId = _ref2.userId,
|
|
119
|
+
clientId = _ref2.clientId,
|
|
120
|
+
onStepsAdded = _ref2.onStepsAdded,
|
|
121
|
+
onErrorHandled = _ref2.onErrorHandled,
|
|
122
|
+
analyticsHelper = _ref2.analyticsHelper,
|
|
123
|
+
emit = _ref2.emit;
|
|
21
124
|
var stepsWithClientAndUserId = steps.map(function (step) {
|
|
22
125
|
return _objectSpread(_objectSpread({}, step.toJSON()), {}, {
|
|
23
126
|
clientId: clientId,
|
|
@@ -267,6 +267,12 @@ export var Provider = /*#__PURE__*/function (_Emitter) {
|
|
|
267
267
|
return _this.userId;
|
|
268
268
|
}, _this.onErrorHandled, _this.metadataService, _this.config.enableErrorOnFailedDocumentApply, getCollabProviderFeatureFlag('sendStepsQueueFF', _this.config.featureFlags));
|
|
269
269
|
_this.namespaceService = new NamespaceService();
|
|
270
|
+
if (getCollabProviderFeatureFlag('sendStepsQueueFF', _this.config.featureFlags)) {
|
|
271
|
+
_this.sendStepsTimer = setInterval(function () {
|
|
272
|
+
logger('Intervally sendStepsFromCurrentState');
|
|
273
|
+
_this.documentService.sendStepsFromCurrentState(true);
|
|
274
|
+
}, 5000);
|
|
275
|
+
}
|
|
270
276
|
return _this;
|
|
271
277
|
}
|
|
272
278
|
_createClass(Provider, [{
|
|
@@ -461,6 +467,12 @@ export var Provider = /*#__PURE__*/function (_Emitter) {
|
|
|
461
467
|
try {
|
|
462
468
|
_get(_getPrototypeOf(Provider.prototype), "unsubscribeAll", this).call(this);
|
|
463
469
|
this.channel.disconnect();
|
|
470
|
+
if (getCollabProviderFeatureFlag('sendStepsQueueFF', this.config.featureFlags)) {
|
|
471
|
+
if (this.sendStepsTimer) {
|
|
472
|
+
clearInterval(this.sendStepsTimer);
|
|
473
|
+
this.sendStepsTimer = undefined;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
464
476
|
} catch (error) {
|
|
465
477
|
var _this$analyticsHelper11;
|
|
466
478
|
(_this$analyticsHelper11 = this.analyticsHelper) === null || _this$analyticsHelper11 === void 0 || _this$analyticsHelper11.sendErrorEvent(error, 'Error while shutting down the collab provider');
|
|
@@ -39,6 +39,7 @@ export declare class DocumentService {
|
|
|
39
39
|
* @param onErrorHandled - Callback to handle
|
|
40
40
|
* @param metadataService
|
|
41
41
|
* @param enableErrorOnFailedDocumentApply - Enable failed document update exceptions.
|
|
42
|
+
* @param enableSendStepsQueue - Enable send steps queue.
|
|
42
43
|
*/
|
|
43
44
|
constructor(participantsService: ParticipantsService, analyticsHelper: AnalyticsHelper | undefined, fetchCatchup: (fromVersion: number, clientId: number | string | undefined) => Promise<CatchupResponse>, fetchReconcile: (currentStateDoc: string) => Promise<ReconcileResponse>, 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, enableErrorOnFailedDocumentApply?: boolean, enableSendStepsQueue?: boolean);
|
|
44
45
|
/**
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
/// <reference types="lodash" />
|
|
2
|
-
import { ChannelEvent, StepsPayload } from '../types';
|
|
2
|
+
import type { ChannelEvent, StepsPayload } from '../types';
|
|
3
3
|
import type { CollabCommitStatusEventPayload, CollabEvents } from '@atlaskit/editor-common/collab';
|
|
4
4
|
import type { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
|
|
5
|
-
import AnalyticsHelper from '../analytics/analytics-helper';
|
|
5
|
+
import type AnalyticsHelper from '../analytics/analytics-helper';
|
|
6
6
|
import type { InternalError } from '../errors/error-types';
|
|
7
|
+
export declare const commitStepQueue: ({ broadcast, steps, version, userId, clientId, onStepsAdded, onErrorHandled, analyticsHelper, emit, }: {
|
|
8
|
+
broadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], "timestamp">, callback?: Function) => void;
|
|
9
|
+
steps: readonly ProseMirrorStep[];
|
|
10
|
+
version: number;
|
|
11
|
+
userId: string;
|
|
12
|
+
clientId: number | string;
|
|
13
|
+
onStepsAdded: (data: StepsPayload) => void;
|
|
14
|
+
onErrorHandled: (error: InternalError) => void;
|
|
15
|
+
analyticsHelper?: AnalyticsHelper | undefined;
|
|
16
|
+
emit: (evt: keyof CollabEvents, data: CollabCommitStatusEventPayload) => void;
|
|
17
|
+
}) => void;
|
|
7
18
|
export declare const commitStep: ({ broadcast, steps, version, userId, clientId, onStepsAdded, onErrorHandled, analyticsHelper, emit, }: {
|
|
8
19
|
broadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], "timestamp">, callback?: Function) => void;
|
|
9
20
|
steps: readonly ProseMirrorStep[];
|
|
@@ -21,6 +21,7 @@ export declare class Provider extends Emitter<CollabEvents> implements BaseEvent
|
|
|
21
21
|
private userId?;
|
|
22
22
|
private presenceUpdateTimeout?;
|
|
23
23
|
private disconnectedAt?;
|
|
24
|
+
private sendStepsTimer?;
|
|
24
25
|
private readonly participantsService;
|
|
25
26
|
private readonly metadataService;
|
|
26
27
|
private readonly documentService;
|
|
@@ -39,6 +39,7 @@ export declare class DocumentService {
|
|
|
39
39
|
* @param onErrorHandled - Callback to handle
|
|
40
40
|
* @param metadataService
|
|
41
41
|
* @param enableErrorOnFailedDocumentApply - Enable failed document update exceptions.
|
|
42
|
+
* @param enableSendStepsQueue - Enable send steps queue.
|
|
42
43
|
*/
|
|
43
44
|
constructor(participantsService: ParticipantsService, analyticsHelper: AnalyticsHelper | undefined, fetchCatchup: (fromVersion: number, clientId: number | string | undefined) => Promise<CatchupResponse>, fetchReconcile: (currentStateDoc: string) => Promise<ReconcileResponse>, 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, enableErrorOnFailedDocumentApply?: boolean, enableSendStepsQueue?: boolean);
|
|
44
45
|
/**
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
/// <reference types="lodash" />
|
|
2
|
-
import { ChannelEvent, StepsPayload } from '../types';
|
|
2
|
+
import type { ChannelEvent, StepsPayload } from '../types';
|
|
3
3
|
import type { CollabCommitStatusEventPayload, CollabEvents } from '@atlaskit/editor-common/collab';
|
|
4
4
|
import type { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
|
|
5
|
-
import AnalyticsHelper from '../analytics/analytics-helper';
|
|
5
|
+
import type AnalyticsHelper from '../analytics/analytics-helper';
|
|
6
6
|
import type { InternalError } from '../errors/error-types';
|
|
7
|
+
export declare const commitStepQueue: ({ broadcast, steps, version, userId, clientId, onStepsAdded, onErrorHandled, analyticsHelper, emit, }: {
|
|
8
|
+
broadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], "timestamp">, callback?: Function) => void;
|
|
9
|
+
steps: readonly ProseMirrorStep[];
|
|
10
|
+
version: number;
|
|
11
|
+
userId: string;
|
|
12
|
+
clientId: number | string;
|
|
13
|
+
onStepsAdded: (data: StepsPayload) => void;
|
|
14
|
+
onErrorHandled: (error: InternalError) => void;
|
|
15
|
+
analyticsHelper?: AnalyticsHelper | undefined;
|
|
16
|
+
emit: (evt: keyof CollabEvents, data: CollabCommitStatusEventPayload) => void;
|
|
17
|
+
}) => void;
|
|
7
18
|
export declare const commitStep: ({ broadcast, steps, version, userId, clientId, onStepsAdded, onErrorHandled, analyticsHelper, emit, }: {
|
|
8
19
|
broadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], "timestamp">, callback?: Function) => void;
|
|
9
20
|
steps: readonly ProseMirrorStep[];
|
|
@@ -21,6 +21,7 @@ export declare class Provider extends Emitter<CollabEvents> implements BaseEvent
|
|
|
21
21
|
private userId?;
|
|
22
22
|
private presenceUpdateTimeout?;
|
|
23
23
|
private disconnectedAt?;
|
|
24
|
+
private sendStepsTimer?;
|
|
24
25
|
private readonly participantsService;
|
|
25
26
|
private readonly metadataService;
|
|
26
27
|
private readonly documentService;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/collab-provider",
|
|
3
|
-
"version": "9.17.
|
|
3
|
+
"version": "9.17.4",
|
|
4
4
|
"description": "A provider for collaborative editing.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@atlaskit/analytics-gas-types": "^5.1.0",
|
|
38
38
|
"@atlaskit/analytics-listeners": "^8.7.0",
|
|
39
|
-
"@atlaskit/editor-common": "^76.
|
|
39
|
+
"@atlaskit/editor-common": "^76.24.0",
|
|
40
40
|
"@atlaskit/editor-json-transformer": "^8.10.0",
|
|
41
41
|
"@atlaskit/editor-prosemirror": "1.1.0",
|
|
42
42
|
"@atlaskit/prosemirror-collab": "^0.2.0",
|