@atlaskit/collab-provider 9.0.0 → 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 +14 -0
- package/dist/cjs/channel.js +6 -8
- package/dist/cjs/document/catchup.js +8 -1
- package/dist/cjs/document/document-service.js +33 -17
- package/dist/cjs/helpers/const.js +5 -1
- package/dist/cjs/participants/participants-service.js +11 -5
- package/dist/cjs/provider/commit-step.js +22 -1
- package/dist/cjs/provider/index.js +20 -7
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/channel.js +6 -6
- package/dist/es2019/document/catchup.js +8 -0
- package/dist/es2019/document/document-service.js +23 -8
- package/dist/es2019/helpers/const.js +5 -1
- package/dist/es2019/participants/participants-service.js +10 -6
- package/dist/es2019/provider/commit-step.js +22 -1
- package/dist/es2019/provider/index.js +13 -3
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/es2019/version.json +1 -1
- package/dist/esm/channel.js +6 -8
- package/dist/esm/document/catchup.js +8 -1
- package/dist/esm/document/document-service.js +33 -17
- package/dist/esm/helpers/const.js +5 -1
- package/dist/esm/participants/participants-service.js +11 -5
- package/dist/esm/provider/commit-step.js +22 -1
- package/dist/esm/provider/index.js +20 -7
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/esm/version.json +1 -1
- package/dist/types/channel.d.ts +1 -1
- package/dist/types/document/document-service.d.ts +5 -2
- package/dist/types/helpers/const.d.ts +30 -4
- package/dist/types/participants/participants-helper.d.ts +3 -1
- package/dist/types/participants/participants-service.d.ts +4 -2
- package/dist/types/provider/commit-step.d.ts +5 -3
- package/dist/types/provider/index.d.ts +2 -0
- package/dist/types/types.d.ts +15 -1
- package/dist/types-ts4.5/channel.d.ts +1 -1
- package/dist/types-ts4.5/document/document-service.d.ts +5 -2
- package/dist/types-ts4.5/helpers/const.d.ts +30 -4
- package/dist/types-ts4.5/participants/participants-helper.d.ts +3 -1
- package/dist/types-ts4.5/participants/participants-service.d.ts +4 -2
- package/dist/types-ts4.5/provider/commit-step.d.ts +5 -3
- package/dist/types-ts4.5/provider/index.d.ts +2 -0
- package/dist/types-ts4.5/types.d.ts +15 -1
- package/package.json +3 -3
- package/report.api.md +9 -0
|
@@ -18,7 +18,7 @@ const SEND_PRESENCE_INTERVAL = 150 * 1000; // 150 seconds
|
|
|
18
18
|
* @param sendPresenceJoined Callback to Channel class
|
|
19
19
|
*/
|
|
20
20
|
export class ParticipantsService {
|
|
21
|
-
constructor(analyticsHelper, participantsState = new ParticipantsState(), emit, getUser, channelBroadcast, sendPresenceJoined) {
|
|
21
|
+
constructor(analyticsHelper, participantsState = new ParticipantsState(), emit, getUser, channelBroadcast, sendPresenceJoined, getPresenceData, setUserId) {
|
|
22
22
|
/**
|
|
23
23
|
* Carries out 3 things: 1) enriches the participant with user data, 2) updates the participantsState, 3) emits the presence event
|
|
24
24
|
* @param payload Payload from incoming socket event
|
|
@@ -187,11 +187,12 @@ export class ParticipantsService {
|
|
|
187
187
|
_defineProperty(this, "clearTimers", () => {
|
|
188
188
|
clearTimeout(this.participantUpdateTimeout);
|
|
189
189
|
});
|
|
190
|
-
_defineProperty(this, "sendPresence",
|
|
190
|
+
_defineProperty(this, "sendPresence", () => {
|
|
191
191
|
try {
|
|
192
192
|
clearTimeout(this.presenceUpdateTimeout);
|
|
193
|
-
this.
|
|
194
|
-
this.
|
|
193
|
+
const data = this.getPresenceData();
|
|
194
|
+
this.channelBroadcast('participant:updated', data);
|
|
195
|
+
this.presenceUpdateTimeout = window.setTimeout(() => this.sendPresence(), SEND_PRESENCE_INTERVAL);
|
|
195
196
|
} catch (error) {
|
|
196
197
|
var _this$analyticsHelper7;
|
|
197
198
|
// We don't want to throw errors for Presence features as they tend to self-restore
|
|
@@ -209,7 +210,7 @@ export class ParticipantsService {
|
|
|
209
210
|
try {
|
|
210
211
|
logger('Participant joined with session: ', payload.sessionId);
|
|
211
212
|
// This expose existing users to the newly joined user
|
|
212
|
-
this.sendPresence(
|
|
213
|
+
this.sendPresence();
|
|
213
214
|
} catch (error) {
|
|
214
215
|
var _this$analyticsHelper8;
|
|
215
216
|
// We don't want to throw errors for Presence features as they tend to self-restore
|
|
@@ -225,7 +226,8 @@ export class ParticipantsService {
|
|
|
225
226
|
_defineProperty(this, "onPresence", payload => {
|
|
226
227
|
try {
|
|
227
228
|
logger('onPresence userId: ', payload.userId);
|
|
228
|
-
this.
|
|
229
|
+
this.setUserId(payload.userId);
|
|
230
|
+
this.sendPresence();
|
|
229
231
|
this.sendPresenceJoined();
|
|
230
232
|
} catch (error) {
|
|
231
233
|
var _this$analyticsHelper9;
|
|
@@ -239,6 +241,8 @@ export class ParticipantsService {
|
|
|
239
241
|
this.getUser = getUser;
|
|
240
242
|
this.channelBroadcast = channelBroadcast;
|
|
241
243
|
this.sendPresenceJoined = sendPresenceJoined;
|
|
244
|
+
this.getPresenceData = getPresenceData;
|
|
245
|
+
this.setUserId = setUserId;
|
|
242
246
|
}
|
|
243
247
|
/**
|
|
244
248
|
* Called on receiving steps, emits each step's telepointer
|
|
@@ -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, {
|
|
@@ -91,6 +91,16 @@ export class Provider extends Emitter {
|
|
|
91
91
|
this.isProviderInitialized = true;
|
|
92
92
|
}).on('restore', this.documentService.onRestore).on('steps:added', this.documentService.onStepsAdded).on('metadata:changed', this.metadataService.onMetadataChanged).on('participant:telepointer', payload => this.participantsService.onParticipantTelepointer(payload, this.sessionId)).on('presence:joined', this.participantsService.onPresenceJoined).on('presence', this.participantsService.onPresence).on('participant:left', this.participantsService.onParticipantLeft).on('participant:updated', this.participantsService.onParticipantUpdated).on('disconnect', this.onDisconnected.bind(this)).on('error', this.onErrorHandled).on('status', this.namespaceService.onNamespaceStatusChanged).connect(shouldInitialize);
|
|
93
93
|
});
|
|
94
|
+
_defineProperty(this, "setUserId", id => {
|
|
95
|
+
this.userId = id;
|
|
96
|
+
});
|
|
97
|
+
_defineProperty(this, "getPresenceData", () => {
|
|
98
|
+
return {
|
|
99
|
+
sessionId: this.sessionId,
|
|
100
|
+
userId: this.userId,
|
|
101
|
+
clientId: this.clientId
|
|
102
|
+
};
|
|
103
|
+
});
|
|
94
104
|
/**
|
|
95
105
|
* @param {InternalError} error The error to handle
|
|
96
106
|
*/
|
|
@@ -147,7 +157,7 @@ export class Provider extends Emitter {
|
|
|
147
157
|
*/
|
|
148
158
|
_defineProperty(this, "getFinalAcknowledgedState", async () => {
|
|
149
159
|
try {
|
|
150
|
-
return this.documentService.getFinalAcknowledgedState();
|
|
160
|
+
return await this.documentService.getFinalAcknowledgedState();
|
|
151
161
|
} catch (error) {
|
|
152
162
|
var _this$analyticsHelper4;
|
|
153
163
|
(_this$analyticsHelper4 = this.analyticsHelper) === null || _this$analyticsHelper4 === void 0 ? void 0 : _this$analyticsHelper4.sendErrorEvent(error, 'Error while returning ADF version of the final draft document');
|
|
@@ -171,9 +181,9 @@ export class Provider extends Emitter {
|
|
|
171
181
|
this.initialDraft = this.config.initialDraft;
|
|
172
182
|
this.isProviderInitialized = false;
|
|
173
183
|
this.isPreinitializing = false;
|
|
174
|
-
this.participantsService = new ParticipantsService(this.analyticsHelper, undefined, this.emitCallback, this.config.getUser, this.channel.broadcast, this.channel.sendPresenceJoined);
|
|
184
|
+
this.participantsService = new ParticipantsService(this.analyticsHelper, undefined, this.emitCallback, this.config.getUser, this.channel.broadcast, this.channel.sendPresenceJoined, this.getPresenceData, this.setUserId);
|
|
175
185
|
this.metadataService = new MetadataService(this.emitCallback, this.channel.sendMetadata);
|
|
176
|
-
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);
|
|
177
187
|
this.getStatePromise = new Promise(resolve => {
|
|
178
188
|
this.getStatePromiseResolve = resolve;
|
|
179
189
|
});
|
package/dist/es2019/version.json
CHANGED
package/dist/esm/channel.js
CHANGED
|
@@ -343,6 +343,12 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
343
343
|
}
|
|
344
344
|
_this.socket.emit('metadata', metadata);
|
|
345
345
|
});
|
|
346
|
+
_defineProperty(_assertThisInitialized(_this), "sendPresenceJoined", function () {
|
|
347
|
+
if (!_this.connected || !_this.socket) {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
_this.socket.emit('presence:joined');
|
|
351
|
+
});
|
|
346
352
|
_defineProperty(_assertThisInitialized(_this), "onOnlineHandler", function () {
|
|
347
353
|
// Force an immediate reconnect, the socket must first be closed to reset reconnection delay logic
|
|
348
354
|
if (!_this.connected) {
|
|
@@ -559,14 +565,6 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
559
565
|
// Fired upon a reconnection attempt error (from Socket.IO Manager)
|
|
560
566
|
this.socket.io.on('reconnect_error', this.onReconnectError);
|
|
561
567
|
}
|
|
562
|
-
}, {
|
|
563
|
-
key: "sendPresenceJoined",
|
|
564
|
-
value: function sendPresenceJoined() {
|
|
565
|
-
if (!this.connected || !this.socket) {
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
this.socket.emit('presence:joined');
|
|
569
|
-
}
|
|
570
568
|
}, {
|
|
571
569
|
key: "disconnect",
|
|
572
570
|
value: function disconnect() {
|
|
@@ -3,6 +3,7 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
|
3
3
|
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
4
4
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
5
5
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
6
|
+
import { EVENT_ACTION, EVENT_STATUS } from '../helpers/const';
|
|
6
7
|
import { createLogger } from '../helpers/utils';
|
|
7
8
|
import { StepMap, Mapping } from 'prosemirror-transform';
|
|
8
9
|
var logger = createLogger('Catchup', 'red');
|
|
@@ -34,7 +35,7 @@ export function rebaseSteps(steps, mapping) {
|
|
|
34
35
|
}
|
|
35
36
|
export var catchup = /*#__PURE__*/function () {
|
|
36
37
|
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(opt) {
|
|
37
|
-
var _yield$opt$fetchCatch, doc, serverStepMaps, serverVersion, metadata, currentPmVersion, unconfirmedSteps, _unconfirmedSteps, stepMaps, mapping, newUnconfirmedSteps;
|
|
38
|
+
var _yield$opt$fetchCatch, doc, serverStepMaps, serverVersion, metadata, currentPmVersion, unconfirmedSteps, _unconfirmedSteps, stepMaps, mapping, newUnconfirmedSteps, _opt$analyticsHelper;
|
|
38
39
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
39
40
|
while (1) switch (_context.prev = _context.next) {
|
|
40
41
|
case 0:
|
|
@@ -112,6 +113,12 @@ export var catchup = /*#__PURE__*/function () {
|
|
|
112
113
|
mapping = new Mapping(stepMaps);
|
|
113
114
|
logger("".concat(_unconfirmedSteps.length, " unconfirmed steps before rebased: ").concat(JSON.stringify(_unconfirmedSteps)));
|
|
114
115
|
newUnconfirmedSteps = rebaseSteps(_unconfirmedSteps, mapping);
|
|
116
|
+
if ((newUnconfirmedSteps === null || newUnconfirmedSteps === void 0 ? void 0 : newUnconfirmedSteps.length) < _unconfirmedSteps.length) {
|
|
117
|
+
// Log the dropped steps after rebase
|
|
118
|
+
(_opt$analyticsHelper = opt.analyticsHelper) === null || _opt$analyticsHelper === void 0 ? void 0 : _opt$analyticsHelper.sendActionEvent(EVENT_ACTION.DROPPED_STEPS, EVENT_STATUS.SUCCESS, {
|
|
119
|
+
numOfDroppedSteps: _unconfirmedSteps.length - (newUnconfirmedSteps === null || newUnconfirmedSteps === void 0 ? void 0 : newUnconfirmedSteps.length)
|
|
120
|
+
});
|
|
121
|
+
}
|
|
115
122
|
logger("Re-aply ".concat(newUnconfirmedSteps.length, " mapped unconfirmed steps: ").concat(JSON.stringify(newUnconfirmedSteps)));
|
|
116
123
|
// Re-apply local steps
|
|
117
124
|
opt.applyLocalSteps(newUnconfirmedSteps);
|
|
@@ -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
|
*/
|
|
@@ -78,7 +81,8 @@ export var DocumentService = /*#__PURE__*/function () {
|
|
|
78
81
|
filterQueue: _this.stepQueue.filterQueue,
|
|
79
82
|
applyLocalSteps: _this.applyLocalSteps,
|
|
80
83
|
updateDocument: _this.updateDocument,
|
|
81
|
-
updateMetadata: _this.metadataService.updateMetadata
|
|
84
|
+
updateMetadata: _this.metadataService.updateMetadata,
|
|
85
|
+
analyticsHelper: _this.analyticsHelper
|
|
82
86
|
});
|
|
83
87
|
case 8:
|
|
84
88
|
latency = new Date().getTime() - start;
|
|
@@ -273,34 +277,37 @@ export var DocumentService = /*#__PURE__*/function () {
|
|
|
273
277
|
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
274
278
|
while (1) switch (_context3.prev = _context3.next) {
|
|
275
279
|
case 0:
|
|
276
|
-
|
|
280
|
+
_this.aggressiveCatchup = true;
|
|
281
|
+
_context3.prev = 1;
|
|
277
282
|
startMeasure(MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
|
|
278
|
-
_context3.next =
|
|
283
|
+
_context3.next = 5;
|
|
279
284
|
return _this.commitUnconfirmedSteps();
|
|
280
|
-
case
|
|
281
|
-
_context3.next =
|
|
285
|
+
case 5:
|
|
286
|
+
_context3.next = 7;
|
|
282
287
|
return _this.getCurrentState();
|
|
283
|
-
case
|
|
288
|
+
case 7:
|
|
284
289
|
currentState = _context3.sent;
|
|
285
290
|
measure = stopMeasure(MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
|
|
286
291
|
(_this$analyticsHelper14 = _this.analyticsHelper) === null || _this$analyticsHelper14 === void 0 ? void 0 : _this$analyticsHelper14.sendActionEvent(EVENT_ACTION.PUBLISH_PAGE, EVENT_STATUS.SUCCESS, {
|
|
287
292
|
latency: measure === null || measure === void 0 ? void 0 : measure.duration
|
|
288
293
|
});
|
|
294
|
+
_this.aggressiveCatchup = false;
|
|
289
295
|
return _context3.abrupt("return", currentState);
|
|
290
|
-
case
|
|
291
|
-
_context3.prev =
|
|
292
|
-
_context3.t0 = _context3["catch"](
|
|
296
|
+
case 14:
|
|
297
|
+
_context3.prev = 14;
|
|
298
|
+
_context3.t0 = _context3["catch"](1);
|
|
299
|
+
_this.aggressiveCatchup = false;
|
|
293
300
|
_measure2 = stopMeasure(MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
|
|
294
301
|
(_this$analyticsHelper15 = _this.analyticsHelper) === null || _this$analyticsHelper15 === void 0 ? void 0 : _this$analyticsHelper15.sendActionEvent(EVENT_ACTION.PUBLISH_PAGE, EVENT_STATUS.FAILURE, {
|
|
295
302
|
latency: _measure2 === null || _measure2 === void 0 ? void 0 : _measure2.duration
|
|
296
303
|
});
|
|
297
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');
|
|
298
305
|
throw _context3.t0;
|
|
299
|
-
case
|
|
306
|
+
case 21:
|
|
300
307
|
case "end":
|
|
301
308
|
return _context3.stop();
|
|
302
309
|
}
|
|
303
|
-
}, _callee3, null, [[
|
|
310
|
+
}, _callee3, null, [[1, 14]]);
|
|
304
311
|
})));
|
|
305
312
|
_defineProperty(this, "updateDocument", function (_ref6) {
|
|
306
313
|
var doc = _ref6.doc,
|
|
@@ -345,7 +352,7 @@ export var DocumentService = /*#__PURE__*/function () {
|
|
|
345
352
|
}
|
|
346
353
|
_this.sendStepsFromCurrentState();
|
|
347
354
|
_context4.next = 12;
|
|
348
|
-
return sleep(
|
|
355
|
+
return sleep(500);
|
|
349
356
|
case 12:
|
|
350
357
|
nextUnconfirmedSteps = _this.getUnconfirmedSteps();
|
|
351
358
|
if (nextUnconfirmedSteps !== null && nextUnconfirmedSteps !== void 0 && nextUnconfirmedSteps.length) {
|
|
@@ -401,10 +408,17 @@ export var DocumentService = /*#__PURE__*/function () {
|
|
|
401
408
|
}, _callee4, null, [[1, 23]]);
|
|
402
409
|
})));
|
|
403
410
|
_defineProperty(this, "onStepRejectedError", function () {
|
|
411
|
+
var _this$analyticsHelper20;
|
|
404
412
|
_this.stepRejectCounter++;
|
|
405
413
|
logger("Steps rejected (tries=".concat(_this.stepRejectCounter, ")"));
|
|
406
|
-
|
|
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;
|
|
407
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);
|
|
408
422
|
_this.throttledCatchup();
|
|
409
423
|
} else {
|
|
410
424
|
// If committing steps failed try again automatically in 1s
|
|
@@ -424,6 +438,7 @@ export var DocumentService = /*#__PURE__*/function () {
|
|
|
424
438
|
this.getUserId = getUserId;
|
|
425
439
|
this.onErrorHandled = onErrorHandled;
|
|
426
440
|
this.metadataService = metadataService;
|
|
441
|
+
this.failedStepsBeforeCatchupOnPublish = failedStepsBeforeCatchupOnPublish;
|
|
427
442
|
this.stepQueue = new StepQueueState();
|
|
428
443
|
}
|
|
429
444
|
_createClass(DocumentService, [{
|
|
@@ -475,9 +490,9 @@ export var DocumentService = /*#__PURE__*/function () {
|
|
|
475
490
|
}, 100);
|
|
476
491
|
}
|
|
477
492
|
} catch (error) {
|
|
478
|
-
var _this$
|
|
493
|
+
var _this$analyticsHelper22;
|
|
479
494
|
logger("Processing steps failed with error: ".concat(error, ". Triggering catch up call."));
|
|
480
|
-
(_this$
|
|
495
|
+
(_this$analyticsHelper22 = this.analyticsHelper) === null || _this$analyticsHelper22 === void 0 ? void 0 : _this$analyticsHelper22.sendErrorEvent(error, 'Error while processing steps');
|
|
481
496
|
this.throttledCatchup();
|
|
482
497
|
}
|
|
483
498
|
}
|
|
@@ -542,7 +557,8 @@ export var DocumentService = /*#__PURE__*/function () {
|
|
|
542
557
|
version: version,
|
|
543
558
|
onStepsAdded: this.onStepsAdded,
|
|
544
559
|
onErrorHandled: this.onErrorHandled,
|
|
545
|
-
analyticsHelper: this.analyticsHelper
|
|
560
|
+
analyticsHelper: this.analyticsHelper,
|
|
561
|
+
emit: this.providerEmitCallback
|
|
546
562
|
});
|
|
547
563
|
}
|
|
548
564
|
}]);
|
|
@@ -10,11 +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";
|
|
15
|
+
EVENT_ACTION["DROPPED_STEPS"] = "droppedStepInCatchup";
|
|
13
16
|
return EVENT_ACTION;
|
|
14
17
|
}({});
|
|
15
18
|
export var EVENT_STATUS = /*#__PURE__*/function (EVENT_STATUS) {
|
|
16
19
|
EVENT_STATUS["SUCCESS"] = "SUCCESS";
|
|
17
20
|
EVENT_STATUS["FAILURE"] = "FAILURE";
|
|
21
|
+
EVENT_STATUS["INFO"] = "INFO";
|
|
18
22
|
return EVENT_STATUS;
|
|
19
23
|
}({});
|
|
20
24
|
export var ADD_STEPS_TYPE = /*#__PURE__*/function (ADD_STEPS_TYPE) {
|
|
@@ -23,5 +27,5 @@ export var ADD_STEPS_TYPE = /*#__PURE__*/function (ADD_STEPS_TYPE) {
|
|
|
23
27
|
ADD_STEPS_TYPE["ERROR"] = "ERROR";
|
|
24
28
|
return ADD_STEPS_TYPE;
|
|
25
29
|
}({});
|
|
26
|
-
export var ACK_MAX_TRY =
|
|
30
|
+
export var ACK_MAX_TRY = 60;
|
|
27
31
|
export var CONFLUENCE = 'confluence';
|
|
@@ -31,6 +31,8 @@ export var ParticipantsService = /*#__PURE__*/function () {
|
|
|
31
31
|
var getUser = arguments.length > 3 ? arguments[3] : undefined;
|
|
32
32
|
var channelBroadcast = arguments.length > 4 ? arguments[4] : undefined;
|
|
33
33
|
var sendPresenceJoined = arguments.length > 5 ? arguments[5] : undefined;
|
|
34
|
+
var getPresenceData = arguments.length > 6 ? arguments[6] : undefined;
|
|
35
|
+
var setUserId = arguments.length > 7 ? arguments[7] : undefined;
|
|
34
36
|
_classCallCheck(this, ParticipantsService);
|
|
35
37
|
/**
|
|
36
38
|
* Carries out 3 things: 1) enriches the participant with user data, 2) updates the participantsState, 3) emits the presence event
|
|
@@ -227,12 +229,13 @@ export var ParticipantsService = /*#__PURE__*/function () {
|
|
|
227
229
|
_defineProperty(this, "clearTimers", function () {
|
|
228
230
|
clearTimeout(_this.participantUpdateTimeout);
|
|
229
231
|
});
|
|
230
|
-
_defineProperty(this, "sendPresence", function (
|
|
232
|
+
_defineProperty(this, "sendPresence", function () {
|
|
231
233
|
try {
|
|
232
234
|
clearTimeout(_this.presenceUpdateTimeout);
|
|
233
|
-
_this.
|
|
235
|
+
var _data = _this.getPresenceData();
|
|
236
|
+
_this.channelBroadcast('participant:updated', _data);
|
|
234
237
|
_this.presenceUpdateTimeout = window.setTimeout(function () {
|
|
235
|
-
return _this.sendPresence(
|
|
238
|
+
return _this.sendPresence();
|
|
236
239
|
}, SEND_PRESENCE_INTERVAL);
|
|
237
240
|
} catch (error) {
|
|
238
241
|
var _this$analyticsHelper7;
|
|
@@ -251,7 +254,7 @@ export var ParticipantsService = /*#__PURE__*/function () {
|
|
|
251
254
|
try {
|
|
252
255
|
logger('Participant joined with session: ', payload.sessionId);
|
|
253
256
|
// This expose existing users to the newly joined user
|
|
254
|
-
_this.sendPresence(
|
|
257
|
+
_this.sendPresence();
|
|
255
258
|
} catch (error) {
|
|
256
259
|
var _this$analyticsHelper8;
|
|
257
260
|
// We don't want to throw errors for Presence features as they tend to self-restore
|
|
@@ -267,7 +270,8 @@ export var ParticipantsService = /*#__PURE__*/function () {
|
|
|
267
270
|
_defineProperty(this, "onPresence", function (payload) {
|
|
268
271
|
try {
|
|
269
272
|
logger('onPresence userId: ', payload.userId);
|
|
270
|
-
_this.
|
|
273
|
+
_this.setUserId(payload.userId);
|
|
274
|
+
_this.sendPresence();
|
|
271
275
|
_this.sendPresenceJoined();
|
|
272
276
|
} catch (error) {
|
|
273
277
|
var _this$analyticsHelper9;
|
|
@@ -281,6 +285,8 @@ export var ParticipantsService = /*#__PURE__*/function () {
|
|
|
281
285
|
this.getUser = getUser;
|
|
282
286
|
this.channelBroadcast = channelBroadcast;
|
|
283
287
|
this.sendPresenceJoined = sendPresenceJoined;
|
|
288
|
+
this.getPresenceData = getPresenceData;
|
|
289
|
+
this.setUserId = setUserId;
|
|
284
290
|
}
|
|
285
291
|
_createClass(ParticipantsService, [{
|
|
286
292
|
key: "emitTelepointersFromSteps",
|
|
@@ -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, {
|
|
@@ -107,6 +107,16 @@ export var Provider = /*#__PURE__*/function (_Emitter) {
|
|
|
107
107
|
return _this.participantsService.onParticipantTelepointer(payload, _this.sessionId);
|
|
108
108
|
}).on('presence:joined', _this.participantsService.onPresenceJoined).on('presence', _this.participantsService.onPresence).on('participant:left', _this.participantsService.onParticipantLeft).on('participant:updated', _this.participantsService.onParticipantUpdated).on('disconnect', _this.onDisconnected.bind(_assertThisInitialized(_this))).on('error', _this.onErrorHandled).on('status', _this.namespaceService.onNamespaceStatusChanged).connect(shouldInitialize);
|
|
109
109
|
});
|
|
110
|
+
_defineProperty(_assertThisInitialized(_this), "setUserId", function (id) {
|
|
111
|
+
_this.userId = id;
|
|
112
|
+
});
|
|
113
|
+
_defineProperty(_assertThisInitialized(_this), "getPresenceData", function () {
|
|
114
|
+
return {
|
|
115
|
+
sessionId: _this.sessionId,
|
|
116
|
+
userId: _this.userId,
|
|
117
|
+
clientId: _this.clientId
|
|
118
|
+
};
|
|
119
|
+
});
|
|
110
120
|
/**
|
|
111
121
|
* @param {InternalError} error The error to handle
|
|
112
122
|
*/
|
|
@@ -175,17 +185,20 @@ export var Provider = /*#__PURE__*/function (_Emitter) {
|
|
|
175
185
|
while (1) switch (_context2.prev = _context2.next) {
|
|
176
186
|
case 0:
|
|
177
187
|
_context2.prev = 0;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
188
|
+
_context2.next = 3;
|
|
189
|
+
return _this.documentService.getFinalAcknowledgedState();
|
|
190
|
+
case 3:
|
|
191
|
+
return _context2.abrupt("return", _context2.sent);
|
|
192
|
+
case 6:
|
|
193
|
+
_context2.prev = 6;
|
|
181
194
|
_context2.t0 = _context2["catch"](0);
|
|
182
195
|
(_this$analyticsHelper4 = _this.analyticsHelper) === null || _this$analyticsHelper4 === void 0 ? void 0 : _this$analyticsHelper4.sendErrorEvent(_context2.t0, 'Error while returning ADF version of the final draft document');
|
|
183
196
|
throw new GetFinalAcknowledgedStateError('Error while returning the final acknowledged state of the draft document', _context2.t0);
|
|
184
|
-
case
|
|
197
|
+
case 10:
|
|
185
198
|
case "end":
|
|
186
199
|
return _context2.stop();
|
|
187
200
|
}
|
|
188
|
-
}, _callee2, null, [[0,
|
|
201
|
+
}, _callee2, null, [[0, 6]]);
|
|
189
202
|
})));
|
|
190
203
|
_defineProperty(_assertThisInitialized(_this), "getUnconfirmedSteps", function () {
|
|
191
204
|
return _this.documentService.getUnconfirmedSteps();
|
|
@@ -204,11 +217,11 @@ export var Provider = /*#__PURE__*/function (_Emitter) {
|
|
|
204
217
|
_this.initialDraft = _this.config.initialDraft;
|
|
205
218
|
_this.isProviderInitialized = false;
|
|
206
219
|
_this.isPreinitializing = false;
|
|
207
|
-
_this.participantsService = new ParticipantsService(_this.analyticsHelper, undefined, _this.emitCallback, _this.config.getUser, _this.channel.broadcast, _this.channel.sendPresenceJoined);
|
|
220
|
+
_this.participantsService = new ParticipantsService(_this.analyticsHelper, undefined, _this.emitCallback, _this.config.getUser, _this.channel.broadcast, _this.channel.sendPresenceJoined, _this.getPresenceData, _this.setUserId);
|
|
208
221
|
_this.metadataService = new MetadataService(_this.emitCallback, _this.channel.sendMetadata);
|
|
209
222
|
_this.documentService = new DocumentService(_this.participantsService, _this.analyticsHelper, _this.channel.fetchCatchup, _this.emitCallback, _this.channel.broadcast, function () {
|
|
210
223
|
return _this.userId;
|
|
211
|
-
}, _this.onErrorHandled, _this.metadataService);
|
|
224
|
+
}, _this.onErrorHandled, _this.metadataService, _this.config.failedStepLimitBeforeCatchupOnPublish);
|
|
212
225
|
_this.getStatePromise = new Promise(function (resolve) {
|
|
213
226
|
_this.getStatePromiseResolve = resolve;
|
|
214
227
|
});
|
package/dist/esm/version.json
CHANGED
package/dist/types/channel.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export declare class Channel extends Emitter<ChannelEvent> {
|
|
|
41
41
|
* @throws {NotConnectedError} Channel not connected
|
|
42
42
|
*/
|
|
43
43
|
sendMetadata: (metadata: Metadata) => void;
|
|
44
|
-
sendPresenceJoined()
|
|
44
|
+
sendPresenceJoined: () => void;
|
|
45
45
|
onOnlineHandler: () => void;
|
|
46
46
|
disconnect(): void;
|
|
47
47
|
}
|
|
@@ -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
|
*/
|