@atlaskit/collab-provider 9.3.1 → 9.5.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 +17 -0
- package/dist/cjs/analytics/analytics-helper.js +7 -2
- package/dist/cjs/channel.js +26 -20
- package/dist/cjs/document/document-service.js +60 -11
- package/dist/cjs/errors/error-code-mapper.js +7 -0
- package/dist/cjs/errors/error-types.js +31 -5
- package/dist/cjs/participants/participants-helper.js +1 -0
- package/dist/cjs/provider/index.js +52 -38
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/analytics/analytics-helper.js +7 -1
- package/dist/es2019/channel.js +13 -7
- package/dist/es2019/document/document-service.js +61 -15
- package/dist/es2019/errors/error-code-mapper.js +7 -0
- package/dist/es2019/errors/error-types.js +20 -2
- package/dist/es2019/participants/participants-helper.js +1 -0
- package/dist/es2019/provider/index.js +52 -38
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/es2019/version.json +1 -1
- package/dist/esm/analytics/analytics-helper.js +7 -2
- package/dist/esm/channel.js +26 -20
- package/dist/esm/document/document-service.js +61 -12
- package/dist/esm/errors/error-code-mapper.js +7 -0
- package/dist/esm/errors/error-types.js +30 -4
- package/dist/esm/participants/participants-helper.js +1 -0
- package/dist/esm/provider/index.js +52 -38
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/esm/version.json +1 -1
- package/dist/types/document/document-service.d.ts +4 -1
- package/dist/types/errors/error-types.d.ts +47 -7
- package/dist/types/helpers/const.d.ts +8 -1
- package/dist/types/participants/participants-helper.d.ts +2 -1
- package/dist/types/types.d.ts +7 -2
- package/dist/types-ts4.5/document/document-service.d.ts +4 -1
- package/dist/types-ts4.5/errors/error-types.d.ts +47 -7
- package/dist/types-ts4.5/helpers/const.d.ts +8 -1
- package/dist/types-ts4.5/participants/participants-helper.d.ts +2 -1
- package/dist/types-ts4.5/types.d.ts +7 -2
- package/package.json +1 -1
- package/report.api.md +24 -4
- package/tmp/api-report-tmp.d.ts +17 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EVENT_ACTION } from '../helpers/const';
|
|
2
2
|
import { name as packageName, version as packageVersion } from '../version-wrapper';
|
|
3
3
|
import { network } from '../connectivity/singleton';
|
|
4
|
+
import { CustomError } from '../errors/error-types';
|
|
4
5
|
const EVENT_SUBJECT = 'collab';
|
|
5
6
|
var COLLAB_SERVICE = /*#__PURE__*/function (COLLAB_SERVICE) {
|
|
6
7
|
COLLAB_SERVICE["NCS"] = "ncs";
|
|
@@ -59,12 +60,17 @@ export default class AnalyticsHelper {
|
|
|
59
60
|
this.getAnalyticsClient = getAnalyticsClient;
|
|
60
61
|
}
|
|
61
62
|
sendErrorEvent(error, errorMessage) {
|
|
63
|
+
let errorExtraAttributes = {};
|
|
64
|
+
if (error instanceof CustomError) {
|
|
65
|
+
errorExtraAttributes = error.getExtraErrorEventAttributes() || {};
|
|
66
|
+
}
|
|
62
67
|
const errorAnalyticsEvent = {
|
|
63
68
|
eventAction: EVENT_ACTION.ERROR,
|
|
64
69
|
attributes: {
|
|
65
70
|
documentAri: this.documentAri,
|
|
66
71
|
errorMessage,
|
|
67
|
-
errorName: error instanceof Error ? error.name : undefined
|
|
72
|
+
errorName: error instanceof Error ? error.name : undefined,
|
|
73
|
+
...errorExtraAttributes
|
|
68
74
|
},
|
|
69
75
|
nonPrivacySafeAttributes: {
|
|
70
76
|
error
|
package/dist/es2019/channel.js
CHANGED
|
@@ -295,14 +295,15 @@ export class Channel extends Emitter {
|
|
|
295
295
|
cacheToken
|
|
296
296
|
} = this.config;
|
|
297
297
|
let auth;
|
|
298
|
-
const authData = {
|
|
299
|
-
// The initialized status. If false, BE will send document, otherwise not.
|
|
300
|
-
initialized: this.initialized,
|
|
301
|
-
// ESS-1009 Allow to opt-in into 404 response
|
|
302
|
-
need404: this.config.need404
|
|
303
|
-
};
|
|
304
298
|
if (permissionTokenRefresh) {
|
|
305
299
|
auth = async cb => {
|
|
300
|
+
// Rebuild authData to ensure values are current
|
|
301
|
+
const authData = {
|
|
302
|
+
// The initialized status. If false, BE will send document, otherwise not.
|
|
303
|
+
initialized: this.initialized,
|
|
304
|
+
// ESS-1009 Allow to opt-in into 404 response
|
|
305
|
+
need404: this.config.need404
|
|
306
|
+
};
|
|
306
307
|
// use the cached token if caching in enabled and token valid
|
|
307
308
|
if (cacheToken && this.token) {
|
|
308
309
|
authData.token = this.token;
|
|
@@ -340,7 +341,12 @@ export class Channel extends Emitter {
|
|
|
340
341
|
}
|
|
341
342
|
};
|
|
342
343
|
} else {
|
|
343
|
-
auth =
|
|
344
|
+
auth = {
|
|
345
|
+
// The initialized status. If false, BE will send document, otherwise not.
|
|
346
|
+
initialized: this.initialized,
|
|
347
|
+
// ESS-1009 Allow to opt-in into 404 response
|
|
348
|
+
need404: this.config.need404
|
|
349
|
+
};
|
|
344
350
|
}
|
|
345
351
|
this.socket = createSocket(`${url}/session/${documentAri}`, auth, this.config.productInfo);
|
|
346
352
|
|
|
@@ -9,7 +9,7 @@ import { JSONTransformer } from '@atlaskit/editor-json-transformer';
|
|
|
9
9
|
import { MAX_STEP_REJECTED_ERROR } from '../provider';
|
|
10
10
|
import { catchup } from './catchup';
|
|
11
11
|
import { StepQueueState } from './step-queue-state';
|
|
12
|
-
import { INTERNAL_ERROR_CODE } from '../errors/error-types';
|
|
12
|
+
import { INTERNAL_ERROR_CODE, UpdateDocumentError } from '../errors/error-types';
|
|
13
13
|
const CATCHUP_THROTTLE = 1 * 1000; // 1 second
|
|
14
14
|
|
|
15
15
|
const noop = () => {};
|
|
@@ -29,8 +29,9 @@ export class DocumentService {
|
|
|
29
29
|
* @param onErrorHandled - Callback to handle
|
|
30
30
|
* @param metadataService
|
|
31
31
|
* @param failedStepsBeforeCatchupOnPublish - Control MAX_STEP_REJECTED_ERROR during page publishes.
|
|
32
|
+
* @param enableErrorOnFailedDocumentApply - Enable failed document update exceptions.
|
|
32
33
|
*/
|
|
33
|
-
constructor(participantsService, analyticsHelper, fetchCatchup, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService, failedStepsBeforeCatchupOnPublish = MAX_STEP_REJECTED_ERROR) {
|
|
34
|
+
constructor(participantsService, analyticsHelper, fetchCatchup, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService, failedStepsBeforeCatchupOnPublish = MAX_STEP_REJECTED_ERROR, enableErrorOnFailedDocumentApply = false) {
|
|
34
35
|
// Fires analytics to editor when collab editor cannot sync up
|
|
35
36
|
_defineProperty(this, "stepRejectCounter", 0);
|
|
36
37
|
_defineProperty(this, "aggressiveCatchup", false);
|
|
@@ -275,6 +276,50 @@ export class DocumentService {
|
|
|
275
276
|
reserveCursor
|
|
276
277
|
} : {})
|
|
277
278
|
});
|
|
279
|
+
const updatedVersion = this.getCurrentPmVersion();
|
|
280
|
+
if (this.getCurrentPmVersion() !== version) {
|
|
281
|
+
var _doc$content, _this$analyticsHelper17;
|
|
282
|
+
const isDocContentValid = this.validatePMJSONDocument(doc);
|
|
283
|
+
const error = new UpdateDocumentError('Failed to update the document', {
|
|
284
|
+
newVersion: version,
|
|
285
|
+
editorVersion: updatedVersion,
|
|
286
|
+
isDocTruthy: !!doc,
|
|
287
|
+
docHasContent: (doc === null || doc === void 0 ? void 0 : (_doc$content = doc.content) === null || _doc$content === void 0 ? void 0 : _doc$content.length) >= 1,
|
|
288
|
+
isDocContentValid
|
|
289
|
+
});
|
|
290
|
+
(_this$analyticsHelper17 = this.analyticsHelper) === null || _this$analyticsHelper17 === void 0 ? void 0 : _this$analyticsHelper17.sendErrorEvent(error, 'Failed to update the document in document service');
|
|
291
|
+
if (this.enableErrorOnFailedDocumentApply) {
|
|
292
|
+
this.onErrorHandled({
|
|
293
|
+
message: 'The provider failed to apply changes to the editor',
|
|
294
|
+
data: {
|
|
295
|
+
code: INTERNAL_ERROR_CODE.DOCUMENT_UPDATE_ERROR,
|
|
296
|
+
meta: {
|
|
297
|
+
newVersion: version,
|
|
298
|
+
editorVersion: updatedVersion
|
|
299
|
+
},
|
|
300
|
+
status: 500
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
throw error;
|
|
304
|
+
}
|
|
305
|
+
// Otherwise just fail silently for now
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
_defineProperty(this, "validatePMJSONDocument", doc => {
|
|
309
|
+
try {
|
|
310
|
+
const state = this.getState();
|
|
311
|
+
const content = (doc.content || []).map(child => state.schema.nodeFromJSON(child));
|
|
312
|
+
return content.every(node => {
|
|
313
|
+
try {
|
|
314
|
+
node.check(); // this will throw an error if the node is invalid
|
|
315
|
+
} catch (error) {
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
return true;
|
|
319
|
+
});
|
|
320
|
+
} catch (e) {
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
278
323
|
});
|
|
279
324
|
/**
|
|
280
325
|
* Commit the unconfirmed local steps to the back-end service
|
|
@@ -284,7 +329,7 @@ export class DocumentService {
|
|
|
284
329
|
const unconfirmedSteps = this.getUnconfirmedSteps();
|
|
285
330
|
try {
|
|
286
331
|
if (unconfirmedSteps !== null && unconfirmedSteps !== void 0 && unconfirmedSteps.length) {
|
|
287
|
-
var _this$
|
|
332
|
+
var _this$analyticsHelper19;
|
|
288
333
|
startMeasure(MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, this.analyticsHelper);
|
|
289
334
|
let count = 0;
|
|
290
335
|
// We use origins here as steps can be rebased. When steps are rebased a new step is created.
|
|
@@ -305,7 +350,7 @@ export class DocumentService {
|
|
|
305
350
|
isLastTrConfirmed = true;
|
|
306
351
|
}
|
|
307
352
|
if (!isLastTrConfirmed && count++ >= ACK_MAX_TRY) {
|
|
308
|
-
var _this$getUnconfirmedS, _this$
|
|
353
|
+
var _this$getUnconfirmedS, _this$analyticsHelper18;
|
|
309
354
|
if (this.onSyncUpError) {
|
|
310
355
|
const state = this.getState();
|
|
311
356
|
this.onSyncUpError({
|
|
@@ -317,42 +362,42 @@ export class DocumentService {
|
|
|
317
362
|
});
|
|
318
363
|
}
|
|
319
364
|
const unconfirmedStepsInfoUGCRemoved = (_this$getUnconfirmedS = this.getUnconfirmedSteps()) === null || _this$getUnconfirmedS === void 0 ? void 0 : _this$getUnconfirmedS.map(step => getStepUGCFreeDetails(step));
|
|
320
|
-
(_this$
|
|
365
|
+
(_this$analyticsHelper18 = this.analyticsHelper) === null || _this$analyticsHelper18 === void 0 ? void 0 : _this$analyticsHelper18.sendErrorEvent({
|
|
321
366
|
unconfirmedStepsInfo: unconfirmedStepsInfoUGCRemoved
|
|
322
367
|
}, "Can't sync up with Collab Service: unable to send unconfirmed steps and max retry reached");
|
|
323
368
|
throw new Error("Can't sync up with Collab Service");
|
|
324
369
|
}
|
|
325
370
|
}
|
|
326
371
|
const measure = stopMeasure(MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, this.analyticsHelper);
|
|
327
|
-
(_this$
|
|
372
|
+
(_this$analyticsHelper19 = this.analyticsHelper) === null || _this$analyticsHelper19 === void 0 ? void 0 : _this$analyticsHelper19.sendActionEvent(EVENT_ACTION.COMMIT_UNCONFIRMED_STEPS, EVENT_STATUS.SUCCESS, {
|
|
328
373
|
latency: measure === null || measure === void 0 ? void 0 : measure.duration,
|
|
329
374
|
// upon success, emit the total number of unconfirmed steps we synced
|
|
330
375
|
numUnconfirmedSteps: unconfirmedSteps === null || unconfirmedSteps === void 0 ? void 0 : unconfirmedSteps.length
|
|
331
376
|
});
|
|
332
377
|
}
|
|
333
378
|
} catch (error) {
|
|
334
|
-
var _this$
|
|
379
|
+
var _this$analyticsHelper20, _this$analyticsHelper21;
|
|
335
380
|
const measure = stopMeasure(MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, this.analyticsHelper);
|
|
336
|
-
(_this$
|
|
381
|
+
(_this$analyticsHelper20 = this.analyticsHelper) === null || _this$analyticsHelper20 === void 0 ? void 0 : _this$analyticsHelper20.sendActionEvent(EVENT_ACTION.COMMIT_UNCONFIRMED_STEPS, EVENT_STATUS.FAILURE, {
|
|
337
382
|
latency: measure === null || measure === void 0 ? void 0 : measure.duration,
|
|
338
383
|
numUnconfirmedSteps: unconfirmedSteps === null || unconfirmedSteps === void 0 ? void 0 : unconfirmedSteps.length
|
|
339
384
|
});
|
|
340
|
-
(_this$
|
|
385
|
+
(_this$analyticsHelper21 = this.analyticsHelper) === null || _this$analyticsHelper21 === void 0 ? void 0 : _this$analyticsHelper21.sendErrorEvent(error, 'Error while committing unconfirmed steps');
|
|
341
386
|
throw error;
|
|
342
387
|
}
|
|
343
388
|
});
|
|
344
389
|
_defineProperty(this, "onStepRejectedError", () => {
|
|
345
|
-
var _this$
|
|
390
|
+
var _this$analyticsHelper22;
|
|
346
391
|
this.stepRejectCounter++;
|
|
347
392
|
logger(`Steps rejected (tries=${this.stepRejectCounter})`);
|
|
348
|
-
(_this$
|
|
393
|
+
(_this$analyticsHelper22 = this.analyticsHelper) === null || _this$analyticsHelper22 === void 0 ? void 0 : _this$analyticsHelper22.sendActionEvent(EVENT_ACTION.SEND_STEPS_RETRY, EVENT_STATUS.INFO, {
|
|
349
394
|
count: this.stepRejectCounter
|
|
350
395
|
});
|
|
351
396
|
let maxRetries = this.aggressiveCatchup ? this.failedStepsBeforeCatchupOnPublish : MAX_STEP_REJECTED_ERROR;
|
|
352
397
|
if (this.stepRejectCounter >= maxRetries) {
|
|
353
|
-
var _this$
|
|
398
|
+
var _this$analyticsHelper23;
|
|
354
399
|
logger(`The steps were rejected too many times (tries=${this.stepRejectCounter}, limit=${MAX_STEP_REJECTED_ERROR}). Trying to catch-up.`);
|
|
355
|
-
(_this$
|
|
400
|
+
(_this$analyticsHelper23 = this.analyticsHelper) === null || _this$analyticsHelper23 === void 0 ? void 0 : _this$analyticsHelper23.sendActionEvent(EVENT_ACTION.CATCHUP_AFTER_MAX_SEND_STEPS_RETRY, EVENT_STATUS.INFO);
|
|
356
401
|
this.throttledCatchup();
|
|
357
402
|
} else {
|
|
358
403
|
// If committing steps failed try again automatically in 1s
|
|
@@ -371,6 +416,7 @@ export class DocumentService {
|
|
|
371
416
|
this.onErrorHandled = onErrorHandled;
|
|
372
417
|
this.metadataService = metadataService;
|
|
373
418
|
this.failedStepsBeforeCatchupOnPublish = failedStepsBeforeCatchupOnPublish;
|
|
419
|
+
this.enableErrorOnFailedDocumentApply = enableErrorOnFailedDocumentApply;
|
|
374
420
|
this.stepQueue = new StepQueueState();
|
|
375
421
|
}
|
|
376
422
|
processQueue() {
|
|
@@ -416,9 +462,9 @@ export class DocumentService {
|
|
|
416
462
|
setTimeout(() => this.sendStepsFromCurrentState(), 100);
|
|
417
463
|
}
|
|
418
464
|
} catch (error) {
|
|
419
|
-
var _this$
|
|
465
|
+
var _this$analyticsHelper24;
|
|
420
466
|
logger(`Processing steps failed with error: ${error}. Triggering catch up call.`);
|
|
421
|
-
(_this$
|
|
467
|
+
(_this$analyticsHelper24 = this.analyticsHelper) === null || _this$analyticsHelper24 === void 0 ? void 0 : _this$analyticsHelper24.sendErrorEvent(error, 'Error while processing steps');
|
|
422
468
|
this.throttledCatchup();
|
|
423
469
|
}
|
|
424
470
|
}
|
|
@@ -67,6 +67,13 @@ export const errorCodeMapper = error => {
|
|
|
67
67
|
recoverable: false,
|
|
68
68
|
status: 500
|
|
69
69
|
};
|
|
70
|
+
case INTERNAL_ERROR_CODE.DOCUMENT_UPDATE_ERROR:
|
|
71
|
+
return {
|
|
72
|
+
code: PROVIDER_ERROR_CODE.DOCUMENT_UPDATE_ERROR,
|
|
73
|
+
message: 'The provider failed to apply changes to the editor',
|
|
74
|
+
recoverable: false,
|
|
75
|
+
status: 500
|
|
76
|
+
};
|
|
70
77
|
case INTERNAL_ERROR_CODE.RECONNECTION_NETWORK_ISSUE:
|
|
71
78
|
return {
|
|
72
79
|
code: PROVIDER_ERROR_CODE.NETWORK_ISSUE,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
// Internal error codes (generated by collab provider)
|
|
3
|
+
|
|
3
4
|
export let INTERNAL_ERROR_CODE = /*#__PURE__*/function (INTERNAL_ERROR_CODE) {
|
|
4
5
|
INTERNAL_ERROR_CODE["TOKEN_PERMISSION_ERROR"] = "TOKEN_PERMISSION_ERROR";
|
|
5
6
|
INTERNAL_ERROR_CODE["RECONNECTION_NETWORK_ISSUE"] = "RECONNECTION_NETWORK_ISSUE";
|
|
@@ -9,8 +10,10 @@ export let INTERNAL_ERROR_CODE = /*#__PURE__*/function (INTERNAL_ERROR_CODE) {
|
|
|
9
10
|
INTERNAL_ERROR_CODE["CATCHUP_FAILED"] = "CATCHUP_FAILED";
|
|
10
11
|
INTERNAL_ERROR_CODE["DOCUMENT_RESTORE_ERROR"] = "DOCUMENT_RESTORE_ERROR";
|
|
11
12
|
INTERNAL_ERROR_CODE["ADD_STEPS_ERROR"] = "ADD_STEPS_ERROR";
|
|
13
|
+
INTERNAL_ERROR_CODE["DOCUMENT_UPDATE_ERROR"] = "DOCUMENT_UPDATE_ERROR";
|
|
12
14
|
return INTERNAL_ERROR_CODE;
|
|
13
15
|
}({});
|
|
16
|
+
|
|
14
17
|
// NCS error coded (generated by NCS)
|
|
15
18
|
export let NCS_ERROR_CODE = /*#__PURE__*/function (NCS_ERROR_CODE) {
|
|
16
19
|
NCS_ERROR_CODE["HEAD_VERSION_UPDATE_FAILED"] = "HEAD_VERSION_UPDATE_FAILED";
|
|
@@ -42,6 +45,10 @@ export let NCS_ERROR_CODE = /*#__PURE__*/function (NCS_ERROR_CODE) {
|
|
|
42
45
|
// - Less common back-end errors
|
|
43
46
|
// Provider Errors
|
|
44
47
|
// Channel Errors
|
|
48
|
+
/**
|
|
49
|
+
* When we try to apply state updates to the editor, if that fails to apply the user can enter an invalid state where no
|
|
50
|
+
* changes can be saved to NCS.
|
|
51
|
+
*/
|
|
45
52
|
/**
|
|
46
53
|
* A union of all possible internal errors, that are mapped to another error if being emitted to the editor.
|
|
47
54
|
*/
|
|
@@ -57,6 +64,7 @@ export let PROVIDER_ERROR_CODE = /*#__PURE__*/function (PROVIDER_ERROR_CODE) {
|
|
|
57
64
|
PROVIDER_ERROR_CODE["NETWORK_ISSUE"] = "NETWORK_ISSUE";
|
|
58
65
|
PROVIDER_ERROR_CODE["INVALID_PROVIDER_CONFIGURATION"] = "INVALID_PROVIDER_CONFIGURATION";
|
|
59
66
|
PROVIDER_ERROR_CODE["INTERNAL_SERVICE_ERROR"] = "INTERNAL_SERVICE_ERROR";
|
|
67
|
+
PROVIDER_ERROR_CODE["DOCUMENT_UPDATE_ERROR"] = "DOCUMENT_UPDATE_ERROR";
|
|
60
68
|
return PROVIDER_ERROR_CODE;
|
|
61
69
|
}({});
|
|
62
70
|
|
|
@@ -154,12 +162,16 @@ export let PROVIDER_ERROR_CODE = /*#__PURE__*/function (PROVIDER_ERROR_CODE) {
|
|
|
154
162
|
* A union of all possible provider errors that can be emitted back to the editor.
|
|
155
163
|
*/
|
|
156
164
|
// Custom Errors
|
|
157
|
-
class CustomError extends Error {
|
|
158
|
-
constructor(message, error) {
|
|
165
|
+
export class CustomError extends Error {
|
|
166
|
+
constructor(message, error, extraEventAttributes) {
|
|
159
167
|
super(message);
|
|
168
|
+
_defineProperty(this, "getExtraErrorEventAttributes", () => this.extraEventAttributes);
|
|
160
169
|
if (typeof (error === null || error === void 0 ? void 0 : error.message) === 'string') {
|
|
161
170
|
this.message = error.message;
|
|
162
171
|
}
|
|
172
|
+
if (extraEventAttributes) {
|
|
173
|
+
this.extraEventAttributes = extraEventAttributes;
|
|
174
|
+
}
|
|
163
175
|
}
|
|
164
176
|
toJSON() {
|
|
165
177
|
return {
|
|
@@ -227,4 +239,10 @@ export class GetFinalAcknowledgedStateError extends CustomError {
|
|
|
227
239
|
super(...args);
|
|
228
240
|
_defineProperty(this, "name", 'GetFinalAcknowledgedStateError');
|
|
229
241
|
}
|
|
242
|
+
}
|
|
243
|
+
export class UpdateDocumentError extends CustomError {
|
|
244
|
+
constructor(message, extraAttributes) {
|
|
245
|
+
super(message, undefined, extraAttributes);
|
|
246
|
+
_defineProperty(this, "name", 'UpdateDocumentError');
|
|
247
|
+
}
|
|
230
248
|
}
|
|
@@ -13,6 +13,7 @@ export const createParticipantFromPayload = async (payload, getUser) => {
|
|
|
13
13
|
const participant = {
|
|
14
14
|
name: (user === null || user === void 0 ? void 0 : user.name) || '',
|
|
15
15
|
avatar: (user === null || user === void 0 ? void 0 : user.avatar) || '',
|
|
16
|
+
email: (user === null || user === void 0 ? void 0 : user.email) || '',
|
|
16
17
|
sessionId,
|
|
17
18
|
lastActive: timestamp,
|
|
18
19
|
userId,
|
|
@@ -66,12 +66,19 @@ export class Provider extends Emitter {
|
|
|
66
66
|
version,
|
|
67
67
|
metadata
|
|
68
68
|
} = this.initialDraft;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
try {
|
|
70
|
+
// Initial document, version, metadata from initial draft
|
|
71
|
+
this.documentService.updateDocument({
|
|
72
|
+
doc: document,
|
|
73
|
+
version,
|
|
74
|
+
metadata
|
|
75
|
+
});
|
|
76
|
+
} catch (e) {
|
|
77
|
+
var _this$analyticsHelper;
|
|
78
|
+
(_this$analyticsHelper = this.analyticsHelper) === null || _this$analyticsHelper === void 0 ? void 0 : _this$analyticsHelper.sendErrorEvent(e, 'Failed to update the document on reconnect, destroying provider');
|
|
79
|
+
// Stop events and connections to step us trying to talk to the backend with an invalid state.
|
|
80
|
+
this.destroy();
|
|
81
|
+
}
|
|
75
82
|
this.metadataService.updateMetadata(metadata);
|
|
76
83
|
}
|
|
77
84
|
this.isProviderInitialized = true;
|
|
@@ -90,13 +97,20 @@ export class Provider extends Emitter {
|
|
|
90
97
|
metadata
|
|
91
98
|
}) => {
|
|
92
99
|
// Initial document and version
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
+
try {
|
|
101
|
+
this.documentService.updateDocument({
|
|
102
|
+
doc,
|
|
103
|
+
version,
|
|
104
|
+
metadata
|
|
105
|
+
});
|
|
106
|
+
this.metadataService.updateMetadata(metadata);
|
|
107
|
+
this.isProviderInitialized = true;
|
|
108
|
+
} catch (e) {
|
|
109
|
+
var _this$analyticsHelper2;
|
|
110
|
+
(_this$analyticsHelper2 = this.analyticsHelper) === null || _this$analyticsHelper2 === void 0 ? void 0 : _this$analyticsHelper2.sendErrorEvent(e, 'Failed to update with the init document, destroying provider');
|
|
111
|
+
// Stop events and connections to step us trying to talk to the backend with an invalid state.
|
|
112
|
+
this.destroy();
|
|
113
|
+
}
|
|
100
114
|
}).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);
|
|
101
115
|
});
|
|
102
116
|
_defineProperty(this, "setUserId", id => {
|
|
@@ -120,13 +134,13 @@ export class Provider extends Emitter {
|
|
|
120
134
|
if (((_error$data = error.data) === null || _error$data === void 0 ? void 0 : _error$data.code) === NCS_ERROR_CODE.HEAD_VERSION_UPDATE_FAILED || ((_error$data2 = error.data) === null || _error$data2 === void 0 ? void 0 : _error$data2.code) === NCS_ERROR_CODE.VERSION_NUMBER_ALREADY_EXISTS) {
|
|
121
135
|
this.documentService.onStepRejectedError();
|
|
122
136
|
} else {
|
|
123
|
-
var _this$
|
|
124
|
-
(_this$
|
|
137
|
+
var _this$analyticsHelper3;
|
|
138
|
+
(_this$analyticsHelper3 = this.analyticsHelper) === null || _this$analyticsHelper3 === void 0 ? void 0 : _this$analyticsHelper3.sendErrorEvent(error, 'Error handled');
|
|
125
139
|
const mappedError = errorCodeMapper(error);
|
|
126
140
|
// Temporarily only emit errors to Confluence very intentionally because they will disconnect the collab provider
|
|
127
141
|
if (mappedError) {
|
|
128
|
-
var _this$
|
|
129
|
-
(_this$
|
|
142
|
+
var _this$analyticsHelper4;
|
|
143
|
+
(_this$analyticsHelper4 = this.analyticsHelper) === null || _this$analyticsHelper4 === void 0 ? void 0 : _this$analyticsHelper4.sendErrorEvent(mappedError, 'Error emitted');
|
|
130
144
|
this.emitCallback('error', mappedError);
|
|
131
145
|
}
|
|
132
146
|
}
|
|
@@ -153,8 +167,8 @@ export class Provider extends Emitter {
|
|
|
153
167
|
try {
|
|
154
168
|
return this.documentService.getCurrentState();
|
|
155
169
|
} catch (error) {
|
|
156
|
-
var _this$
|
|
157
|
-
(_this$
|
|
170
|
+
var _this$analyticsHelper5;
|
|
171
|
+
(_this$analyticsHelper5 = this.analyticsHelper) === null || _this$analyticsHelper5 === void 0 ? void 0 : _this$analyticsHelper5.sendErrorEvent(error, 'Error while returning ADF version of current draft document');
|
|
158
172
|
throw new GetCurrentStateError('Error while returning the current state of the draft document', error); // Reject the promise so the consumer can react to it failing
|
|
159
173
|
}
|
|
160
174
|
});
|
|
@@ -167,8 +181,8 @@ export class Provider extends Emitter {
|
|
|
167
181
|
try {
|
|
168
182
|
return await this.documentService.getFinalAcknowledgedState();
|
|
169
183
|
} catch (error) {
|
|
170
|
-
var _this$
|
|
171
|
-
(_this$
|
|
184
|
+
var _this$analyticsHelper6;
|
|
185
|
+
(_this$analyticsHelper6 = this.analyticsHelper) === null || _this$analyticsHelper6 === void 0 ? void 0 : _this$analyticsHelper6.sendErrorEvent(error, 'Error while returning ADF version of the final draft document');
|
|
172
186
|
throw new GetFinalAcknowledgedStateError('Error while returning the final acknowledged state of the draft document', error); // Reject the promise so the consumer can react to it failing
|
|
173
187
|
}
|
|
174
188
|
});
|
|
@@ -197,7 +211,7 @@ export class Provider extends Emitter {
|
|
|
197
211
|
this.isPreinitializing = false;
|
|
198
212
|
this.participantsService = new ParticipantsService(this.analyticsHelper, undefined, this.emitCallback, this.config.getUser, this.channel.broadcast, this.channel.sendPresenceJoined, this.getPresenceData, this.setUserId);
|
|
199
213
|
this.metadataService = new MetadataService(this.emitCallback, this.channel.sendMetadata);
|
|
200
|
-
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);
|
|
214
|
+
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, this.config.enableErrorOnFailedDocumentApply);
|
|
201
215
|
this.getStatePromise = new Promise(resolve => {
|
|
202
216
|
this.getStatePromiseResolve = resolve;
|
|
203
217
|
});
|
|
@@ -259,8 +273,8 @@ export class Provider extends Emitter {
|
|
|
259
273
|
this.isChannelInitialized = true;
|
|
260
274
|
}
|
|
261
275
|
} catch (initError) {
|
|
262
|
-
var _this$
|
|
263
|
-
(_this$
|
|
276
|
+
var _this$analyticsHelper7;
|
|
277
|
+
(_this$analyticsHelper7 = this.analyticsHelper) === null || _this$analyticsHelper7 === void 0 ? void 0 : _this$analyticsHelper7.sendErrorEvent(initError, 'Error while initialising the provider');
|
|
264
278
|
// Throw error so consumers are aware the initialisation failed when initialising themselves
|
|
265
279
|
throw new ProviderInitialisationError('Provider initialisation error', initError);
|
|
266
280
|
}
|
|
@@ -268,9 +282,9 @@ export class Provider extends Emitter {
|
|
|
268
282
|
}
|
|
269
283
|
checkForCookies() {
|
|
270
284
|
if (!global.navigator.cookieEnabled) {
|
|
271
|
-
var _this$
|
|
285
|
+
var _this$analyticsHelper8;
|
|
272
286
|
const initError = new ProviderInitialisationError('Cookies are not enabled. Please enable cookies to use collaborative editing.');
|
|
273
|
-
(_this$
|
|
287
|
+
(_this$analyticsHelper8 = this.analyticsHelper) === null || _this$analyticsHelper8 === void 0 ? void 0 : _this$analyticsHelper8.sendErrorEvent(initError, 'Error while initialising the provider - cookies disabled');
|
|
274
288
|
throw new ProviderInitialisationError('Provider initialisation error - cookies disabled', initError);
|
|
275
289
|
}
|
|
276
290
|
}
|
|
@@ -304,8 +318,8 @@ export class Provider extends Emitter {
|
|
|
304
318
|
}
|
|
305
319
|
this.documentService.send(_tr, _oldState, newState);
|
|
306
320
|
} catch (error) {
|
|
307
|
-
var _this$
|
|
308
|
-
(_this$
|
|
321
|
+
var _this$analyticsHelper9;
|
|
322
|
+
(_this$analyticsHelper9 = this.analyticsHelper) === null || _this$analyticsHelper9 === void 0 ? void 0 : _this$analyticsHelper9.sendErrorEvent(error, 'Error while sending steps for a transaction');
|
|
309
323
|
throw new SendTransactionError('Error while sending steps for a transaction', error);
|
|
310
324
|
}
|
|
311
325
|
}
|
|
@@ -330,9 +344,9 @@ export class Provider extends Emitter {
|
|
|
330
344
|
this.channel.broadcast('participant:telepointer', payload, callback);
|
|
331
345
|
}
|
|
332
346
|
} catch (error) {
|
|
333
|
-
var _this$
|
|
347
|
+
var _this$analyticsHelper10;
|
|
334
348
|
// We don't want to throw errors for Presence features as they tend to self-restore
|
|
335
|
-
(_this$
|
|
349
|
+
(_this$analyticsHelper10 = this.analyticsHelper) === null || _this$analyticsHelper10 === void 0 ? void 0 : _this$analyticsHelper10.sendErrorEvent(error, 'Error while sending message - telepointer');
|
|
336
350
|
}
|
|
337
351
|
}
|
|
338
352
|
/**
|
|
@@ -364,8 +378,8 @@ export class Provider extends Emitter {
|
|
|
364
378
|
super.unsubscribeAll();
|
|
365
379
|
this.channel.disconnect();
|
|
366
380
|
} catch (error) {
|
|
367
|
-
var _this$
|
|
368
|
-
(_this$
|
|
381
|
+
var _this$analyticsHelper11;
|
|
382
|
+
(_this$analyticsHelper11 = this.analyticsHelper) === null || _this$analyticsHelper11 === void 0 ? void 0 : _this$analyticsHelper11.sendErrorEvent(error, 'Error while shutting down the collab provider');
|
|
369
383
|
throw new DestroyError('Error while shutting down the collab provider', error);
|
|
370
384
|
}
|
|
371
385
|
this.clearTimers();
|
|
@@ -383,8 +397,8 @@ export class Provider extends Emitter {
|
|
|
383
397
|
try {
|
|
384
398
|
this.metadataService.setTitle(title, broadcast);
|
|
385
399
|
} catch (error) {
|
|
386
|
-
var _this$
|
|
387
|
-
(_this$
|
|
400
|
+
var _this$analyticsHelper12;
|
|
401
|
+
(_this$analyticsHelper12 = this.analyticsHelper) === null || _this$analyticsHelper12 === void 0 ? void 0 : _this$analyticsHelper12.sendErrorEvent(error, 'Error while setting title');
|
|
388
402
|
throw new SetTitleError('Error while setting title', error);
|
|
389
403
|
}
|
|
390
404
|
}
|
|
@@ -400,8 +414,8 @@ export class Provider extends Emitter {
|
|
|
400
414
|
try {
|
|
401
415
|
this.metadataService.setEditorWidth(editorWidth, broadcast);
|
|
402
416
|
} catch (error) {
|
|
403
|
-
var _this$
|
|
404
|
-
(_this$
|
|
417
|
+
var _this$analyticsHelper13;
|
|
418
|
+
(_this$analyticsHelper13 = this.analyticsHelper) === null || _this$analyticsHelper13 === void 0 ? void 0 : _this$analyticsHelper13.sendErrorEvent(error, 'Error while setting editor width');
|
|
405
419
|
throw new SetEditorWidthError('Error while setting editor width', error);
|
|
406
420
|
}
|
|
407
421
|
}
|
|
@@ -415,8 +429,8 @@ export class Provider extends Emitter {
|
|
|
415
429
|
try {
|
|
416
430
|
this.metadataService.setMetadata(metadata);
|
|
417
431
|
} catch (error) {
|
|
418
|
-
var _this$
|
|
419
|
-
(_this$
|
|
432
|
+
var _this$analyticsHelper14;
|
|
433
|
+
(_this$analyticsHelper14 = this.analyticsHelper) === null || _this$analyticsHelper14 === void 0 ? void 0 : _this$analyticsHelper14.sendErrorEvent(error, 'Error while setting metadata');
|
|
420
434
|
throw new SetMetadataError('Error while setting metadata', error);
|
|
421
435
|
}
|
|
422
436
|
}
|
package/dist/es2019/version.json
CHANGED
|
@@ -8,6 +8,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
8
8
|
import { EVENT_ACTION } from '../helpers/const';
|
|
9
9
|
import { name as packageName, version as packageVersion } from '../version-wrapper';
|
|
10
10
|
import { network } from '../connectivity/singleton';
|
|
11
|
+
import { CustomError } from '../errors/error-types';
|
|
11
12
|
var EVENT_SUBJECT = 'collab';
|
|
12
13
|
var COLLAB_SERVICE = /*#__PURE__*/function (COLLAB_SERVICE) {
|
|
13
14
|
COLLAB_SERVICE["NCS"] = "ncs";
|
|
@@ -68,13 +69,17 @@ var AnalyticsHelper = /*#__PURE__*/function () {
|
|
|
68
69
|
_createClass(AnalyticsHelper, [{
|
|
69
70
|
key: "sendErrorEvent",
|
|
70
71
|
value: function sendErrorEvent(error, errorMessage) {
|
|
72
|
+
var errorExtraAttributes = {};
|
|
73
|
+
if (error instanceof CustomError) {
|
|
74
|
+
errorExtraAttributes = error.getExtraErrorEventAttributes() || {};
|
|
75
|
+
}
|
|
71
76
|
var errorAnalyticsEvent = {
|
|
72
77
|
eventAction: EVENT_ACTION.ERROR,
|
|
73
|
-
attributes: {
|
|
78
|
+
attributes: _objectSpread({
|
|
74
79
|
documentAri: this.documentAri,
|
|
75
80
|
errorMessage: errorMessage,
|
|
76
81
|
errorName: error instanceof Error ? error.name : undefined
|
|
77
|
-
},
|
|
82
|
+
}, errorExtraAttributes),
|
|
78
83
|
nonPrivacySafeAttributes: {
|
|
79
84
|
error: error
|
|
80
85
|
}
|
package/dist/esm/channel.js
CHANGED
|
@@ -390,32 +390,33 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
390
390
|
permissionTokenRefresh = _this$config2.permissionTokenRefresh,
|
|
391
391
|
cacheToken = _this$config2.cacheToken;
|
|
392
392
|
var auth;
|
|
393
|
-
var authData = {
|
|
394
|
-
// The initialized status. If false, BE will send document, otherwise not.
|
|
395
|
-
initialized: this.initialized,
|
|
396
|
-
// ESS-1009 Allow to opt-in into 404 response
|
|
397
|
-
need404: this.config.need404
|
|
398
|
-
};
|
|
399
393
|
if (permissionTokenRefresh) {
|
|
400
394
|
auth = /*#__PURE__*/function () {
|
|
401
395
|
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(cb) {
|
|
402
|
-
var token, _data, _data$meta, authenticationError;
|
|
396
|
+
var authData, token, _data, _data$meta, authenticationError;
|
|
403
397
|
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
404
398
|
while (1) switch (_context2.prev = _context2.next) {
|
|
405
399
|
case 0:
|
|
400
|
+
// Rebuild authData to ensure values are current
|
|
401
|
+
authData = {
|
|
402
|
+
// The initialized status. If false, BE will send document, otherwise not.
|
|
403
|
+
initialized: _this2.initialized,
|
|
404
|
+
// ESS-1009 Allow to opt-in into 404 response
|
|
405
|
+
need404: _this2.config.need404
|
|
406
|
+
}; // use the cached token if caching in enabled and token valid
|
|
406
407
|
if (!(cacheToken && _this2.token)) {
|
|
407
|
-
_context2.next =
|
|
408
|
+
_context2.next = 6;
|
|
408
409
|
break;
|
|
409
410
|
}
|
|
410
411
|
authData.token = _this2.token;
|
|
411
412
|
cb(authData);
|
|
412
|
-
_context2.next =
|
|
413
|
+
_context2.next = 18;
|
|
413
414
|
break;
|
|
414
|
-
case
|
|
415
|
-
_context2.prev =
|
|
416
|
-
_context2.next =
|
|
415
|
+
case 6:
|
|
416
|
+
_context2.prev = 6;
|
|
417
|
+
_context2.next = 9;
|
|
417
418
|
return permissionTokenRefresh();
|
|
418
|
-
case
|
|
419
|
+
case 9:
|
|
419
420
|
token = _context2.sent;
|
|
420
421
|
if (token) {
|
|
421
422
|
// save token locally
|
|
@@ -426,11 +427,11 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
426
427
|
authData.token = undefined;
|
|
427
428
|
}
|
|
428
429
|
cb(authData);
|
|
429
|
-
_context2.next =
|
|
430
|
+
_context2.next = 18;
|
|
430
431
|
break;
|
|
431
|
-
case
|
|
432
|
-
_context2.prev =
|
|
433
|
-
_context2.t0 = _context2["catch"](
|
|
432
|
+
case 14:
|
|
433
|
+
_context2.prev = 14;
|
|
434
|
+
_context2.t0 = _context2["catch"](6);
|
|
434
435
|
// Pass the error back to the consumers so they can deal with exceptional cases themselves (eg. no permissions because the page was deleted)
|
|
435
436
|
authenticationError = {
|
|
436
437
|
message: 'Insufficient editing permissions',
|
|
@@ -446,18 +447,23 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
|
|
|
446
447
|
};
|
|
447
448
|
|
|
448
449
|
_this2.emit('error', authenticationError);
|
|
449
|
-
case
|
|
450
|
+
case 18:
|
|
450
451
|
case "end":
|
|
451
452
|
return _context2.stop();
|
|
452
453
|
}
|
|
453
|
-
}, _callee2, null, [[
|
|
454
|
+
}, _callee2, null, [[6, 14]]);
|
|
454
455
|
}));
|
|
455
456
|
return function auth(_x2) {
|
|
456
457
|
return _ref3.apply(this, arguments);
|
|
457
458
|
};
|
|
458
459
|
}();
|
|
459
460
|
} else {
|
|
460
|
-
auth =
|
|
461
|
+
auth = {
|
|
462
|
+
// The initialized status. If false, BE will send document, otherwise not.
|
|
463
|
+
initialized: this.initialized,
|
|
464
|
+
// ESS-1009 Allow to opt-in into 404 response
|
|
465
|
+
need404: this.config.need404
|
|
466
|
+
};
|
|
461
467
|
}
|
|
462
468
|
this.socket = createSocket("".concat(url, "/session/").concat(documentAri), auth, this.config.productInfo);
|
|
463
469
|
|