@atlaskit/collab-provider 7.4.4 → 7.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/config/package.json +8 -0
  3. package/dist/cjs/analytics/performance.js +10 -0
  4. package/dist/cjs/channel.js +50 -44
  5. package/dist/cjs/config.js +12 -0
  6. package/dist/cjs/error-code-mapper.js +39 -31
  7. package/dist/cjs/helpers/const.js +1 -0
  8. package/dist/cjs/helpers/utils.js +18 -2
  9. package/dist/cjs/provider/index.js +35 -7
  10. package/dist/cjs/socket-io-provider.js +15 -3
  11. package/dist/cjs/version.json +1 -1
  12. package/dist/es2019/analytics/performance.js +9 -0
  13. package/dist/es2019/channel.js +20 -20
  14. package/dist/es2019/config.js +5 -0
  15. package/dist/es2019/error-code-mapper.js +34 -31
  16. package/dist/es2019/helpers/const.js +1 -0
  17. package/dist/es2019/helpers/utils.js +11 -1
  18. package/dist/es2019/provider/index.js +34 -6
  19. package/dist/es2019/socket-io-provider.js +13 -3
  20. package/dist/es2019/version.json +1 -1
  21. package/dist/esm/analytics/performance.js +9 -0
  22. package/dist/esm/channel.js +54 -47
  23. package/dist/esm/config.js +5 -0
  24. package/dist/esm/error-code-mapper.js +35 -31
  25. package/dist/esm/helpers/const.js +1 -0
  26. package/dist/esm/helpers/utils.js +11 -1
  27. package/dist/esm/provider/index.js +35 -8
  28. package/dist/esm/socket-io-provider.js +13 -3
  29. package/dist/esm/version.json +1 -1
  30. package/dist/types/analytics/performance.d.ts +8 -4
  31. package/dist/types/config.d.ts +5 -0
  32. package/dist/types/helpers/const.d.ts +2 -1
  33. package/dist/types/helpers/utils.d.ts +3 -0
  34. package/dist/types/socket-io-provider.d.ts +2 -2
  35. package/dist/types/types.d.ts +11 -2
  36. package/package.json +3 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/collab-provider
2
2
 
3
+ ## 7.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`1c555e79e56`](https://bitbucket.org/atlassian/atlassian-frontend/commits/1c555e79e56) - Added the capability to pass product information (product & sub-product) to the collab service
8
+ - [`247420a48f7`](https://bitbucket.org/atlassian/atlassian-frontend/commits/247420a48f7) - [ESS-1050] Return ADF document from getFinalAcknowledgedState
9
+ - [`17f1b0b87cc`](https://bitbucket.org/atlassian/atlassian-frontend/commits/17f1b0b87cc) - ESS-1019 changes the reconnectionDelayMax to 128s to reduce the reconnection storm.
10
+
11
+ ### Patch Changes
12
+
13
+ - [`bf848f39cb1`](https://bitbucket.org/atlassian/atlassian-frontend/commits/bf848f39cb1) - ESS-2419 Emit the reason of permission errors to the consumers of collab-provider
14
+ - [`680dc155ebc`](https://bitbucket.org/atlassian/atlassian-frontend/commits/680dc155ebc) - Raise errors in the collab provider when the server fails loading initilisation data
15
+ - Updated dependencies
16
+
3
17
  ## 7.4.4
4
18
 
5
19
  ### Patch Changes
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "@atlaskit/collab-provider/config",
3
+ "main": "../dist/cjs/config.js",
4
+ "module": "../dist/esm/config.js",
5
+ "module:es2019": "../dist/es2019/config.js",
6
+ "sideEffects": false,
7
+ "types": "../dist/types/config.d.ts"
8
+ }
@@ -3,9 +3,19 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.MEASURE_NAME = void 0;
6
7
  exports.clearMeasure = clearMeasure;
7
8
  exports.startMeasure = startMeasure;
8
9
  exports.stopMeasure = stopMeasure;
10
+ var MEASURE_NAME;
11
+ exports.MEASURE_NAME = MEASURE_NAME;
12
+
13
+ (function (MEASURE_NAME) {
14
+ MEASURE_NAME["CALLING_CATCHUP_API"] = "callingCatchupApi";
15
+ MEASURE_NAME["SOCKET_CONNECT"] = "socketConnect";
16
+ MEASURE_NAME["DOCUMENT_INIT"] = "documentInit";
17
+ MEASURE_NAME["CONVERT_PM_TO_ADF"] = "convertPMToADF";
18
+ })(MEASURE_NAME || (exports.MEASURE_NAME = MEASURE_NAME = {}));
9
19
 
10
20
  var isPerformanceAPIAvailable = function isPerformanceAPIAvailable() {
11
21
  return typeof window !== 'undefined' && 'performance' in window && ['measure', 'clearMeasures', 'clearMarks', 'getEntriesByName', 'getEntriesByType'].every(function (api) {
@@ -74,7 +74,7 @@ var Channel = /*#__PURE__*/function (_Emitter) {
74
74
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onConnect", function () {
75
75
  _this.connected = true;
76
76
  logger('Connected.', _this.socket.id);
77
- var measure = (0, _performance.stopMeasure)('socketConnect');
77
+ var measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.SOCKET_CONNECT);
78
78
  (0, _analytics.triggerCollabAnalyticsEvent)({
79
79
  eventAction: _const.EVENT_ACTION.CONNECTION,
80
80
  attributes: {
@@ -94,7 +94,7 @@ var Channel = /*#__PURE__*/function (_Emitter) {
94
94
 
95
95
  if (data.type === 'initial') {
96
96
  if (!_this.initialized) {
97
- var measure = (0, _performance.stopMeasure)('documentInit');
97
+ var measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.DOCUMENT_INIT);
98
98
  (0, _analytics.triggerCollabAnalyticsEvent)({
99
99
  eventAction: _const.EVENT_ACTION.DOCUMENT_INIT,
100
100
  attributes: {
@@ -139,10 +139,10 @@ var Channel = /*#__PURE__*/function (_Emitter) {
139
139
  function connect() {
140
140
  var _this2 = this;
141
141
 
142
- (0, _performance.startMeasure)('socketConnect');
142
+ (0, _performance.startMeasure)(_performance.MEASURE_NAME.SOCKET_CONNECT);
143
143
 
144
144
  if (!this.initialized) {
145
- (0, _performance.startMeasure)('documentInit');
145
+ (0, _performance.startMeasure)(_performance.MEASURE_NAME.DOCUMENT_INIT);
146
146
  }
147
147
 
148
148
  var _this$config = this.config,
@@ -150,9 +150,10 @@ var Channel = /*#__PURE__*/function (_Emitter) {
150
150
  url = _this$config.url;
151
151
  var createSocket = this.config.createSocket;
152
152
  var permissionTokenRefresh = this.config.permissionTokenRefresh;
153
+ var authCb = null;
153
154
 
154
155
  if (permissionTokenRefresh) {
155
- var authCb = function authCb(cb) {
156
+ authCb = function authCb(cb) {
156
157
  permissionTokenRefresh().then(function (token) {
157
158
  cb({
158
159
  // The permission token.
@@ -166,10 +167,8 @@ var Channel = /*#__PURE__*/function (_Emitter) {
166
167
  _this2.emit('error', err);
167
168
  });
168
169
  };
169
-
170
- this.socket = createSocket("".concat(url, "/session/").concat(documentAri), authCb);
171
170
  } else {
172
- var _authCb = function _authCb(cb) {
171
+ authCb = function authCb(cb) {
173
172
  cb({
174
173
  // The initialized status. If false, BE will send document, otherwise not.
175
174
  initialized: _this2.initialized,
@@ -177,13 +176,12 @@ var Channel = /*#__PURE__*/function (_Emitter) {
177
176
  need404: _this2.config.need404
178
177
  });
179
178
  };
179
+ }
180
180
 
181
- this.socket = createSocket("".concat(url, "/session/").concat(documentAri), _authCb);
182
- } // Due to https://github.com/socketio/socket.io-client/issues/1473,
181
+ this.socket = createSocket("".concat(url, "/session/").concat(documentAri), authCb, this.config.productInfo); // Due to https://github.com/socketio/socket.io-client/issues/1473,
183
182
  // reconnect no longer fired on the socket.
184
183
  // We should use `connect` for better cross platform compatibility(Mobile/Web).
185
184
 
186
-
187
185
  this.socket.on('connect', this.onConnect);
188
186
  this.socket.on('data', this.onReceiveData);
189
187
  this.socket.on('steps:added', function (data) {
@@ -253,7 +251,7 @@ var Channel = /*#__PURE__*/function (_Emitter) {
253
251
  // Ensure the error emit to the provider has the same structure, so we can handle them unified.
254
252
 
255
253
  this.socket.on('connect_error', function (error) {
256
- var measure = (0, _performance.stopMeasure)('socketConnect');
254
+ var measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.SOCKET_CONNECT);
257
255
  (0, _analytics.triggerCollabAnalyticsEvent)({
258
256
  eventAction: _const.EVENT_ACTION.CONNECTION,
259
257
  attributes: {
@@ -291,46 +289,54 @@ var Channel = /*#__PURE__*/function (_Emitter) {
291
289
  _context2.prev = 0;
292
290
  _context2.t0 = _utilServiceSupport.utils;
293
291
  _context2.t1 = this.config;
294
- _context2.t2 = _objectSpread;
292
+ _context2.t2 = "document/".concat(encodeURIComponent(this.config.documentAri), "/catchup");
295
293
  _context2.t3 = {
296
- path: "document/".concat(encodeURIComponent(this.config.documentAri), "/catchup"),
297
- queryParams: {
298
- version: fromVersion
299
- }
294
+ version: fromVersion
300
295
  };
296
+ _context2.t4 = _objectSpread;
297
+ _context2.t5 = _objectSpread;
298
+ _context2.t6 = {};
301
299
 
302
300
  if (!this.config.permissionTokenRefresh) {
303
- _context2.next = 14;
301
+ _context2.next = 15;
304
302
  break;
305
303
  }
306
304
 
307
- _context2.next = 8;
305
+ _context2.next = 11;
308
306
  return this.config.permissionTokenRefresh();
309
307
 
310
- case 8:
311
- _context2.t5 = _context2.sent;
312
- _context2.t6 = {
313
- 'x-token': _context2.t5
314
- };
308
+ case 11:
309
+ _context2.t8 = _context2.sent;
315
310
  _context2.t7 = {
316
- headers: _context2.t6
317
- };
318
- _context2.t4 = {
319
- requestInit: _context2.t7
311
+ 'x-token': _context2.t8
320
312
  };
321
- _context2.next = 15;
313
+ _context2.next = 16;
322
314
  break;
323
315
 
324
- case 14:
325
- _context2.t4 = {};
326
-
327
316
  case 15:
328
- _context2.t8 = _context2.t4;
329
- _context2.t9 = (0, _context2.t2)(_context2.t3, _context2.t8);
330
- _context2.next = 19;
331
- return _context2.t0.requestService.call(_context2.t0, _context2.t1, _context2.t9);
317
+ _context2.t7 = {};
318
+
319
+ case 16:
320
+ _context2.t9 = _context2.t7;
321
+ _context2.t10 = (0, _context2.t5)(_context2.t6, _context2.t9);
322
+ _context2.t11 = {};
323
+ _context2.t12 = {
324
+ 'x-product': (0, _utils.getProduct)(this.config.productInfo),
325
+ 'x-subproduct': (0, _utils.getSubProduct)(this.config.productInfo)
326
+ };
327
+ _context2.t13 = (0, _context2.t4)(_context2.t10, _context2.t11, _context2.t12);
328
+ _context2.t14 = {
329
+ headers: _context2.t13
330
+ };
331
+ _context2.t15 = {
332
+ path: _context2.t2,
333
+ queryParams: _context2.t3,
334
+ requestInit: _context2.t14
335
+ };
336
+ _context2.next = 25;
337
+ return _context2.t0.requestService.call(_context2.t0, _context2.t1, _context2.t15);
332
338
 
333
- case 19:
339
+ case 25:
334
340
  _yield$utils$requestS = _context2.sent;
335
341
  doc = _yield$utils$requestS.doc;
336
342
  version = _yield$utils$requestS.version;
@@ -343,26 +349,26 @@ var Channel = /*#__PURE__*/function (_Emitter) {
343
349
  metadata: metadata
344
350
  });
345
351
 
346
- case 27:
347
- _context2.prev = 27;
348
- _context2.t10 = _context2["catch"](0);
349
- logger("Can't fetch the catchup", _context2.t10.message);
352
+ case 33:
353
+ _context2.prev = 33;
354
+ _context2.t16 = _context2["catch"](0);
355
+ logger("Can't fetch the catchup", _context2.t16.message);
350
356
  errorCatchup = {
351
357
  message: _errorCodeMapper.ErrorCodeMapper.catchupFail.message,
352
358
  data: {
353
- status: _context2.t10.status,
359
+ status: _context2.t16.status,
354
360
  code: _errorCodeMapper.ErrorCodeMapper.catchupFail.code
355
361
  }
356
362
  };
357
363
  this.emit('error', errorCatchup);
358
364
  return _context2.abrupt("return", {});
359
365
 
360
- case 33:
366
+ case 39:
361
367
  case "end":
362
368
  return _context2.stop();
363
369
  }
364
370
  }
365
- }, _callee2, this, [[0, 27]]);
371
+ }, _callee2, this, [[0, 33]]);
366
372
  }));
367
373
 
368
374
  function fetchCatchup(_x2) {
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.SOCKET_IO_OPTIONS = void 0;
7
+ var SOCKET_IO_OPTIONS = {
8
+ RECONNECTION_DELAY_MAX: 128 * 1000,
9
+ RECONNECTION_DELAY: 1000,
10
+ RANDOMIZATION_FACTOR: 0.1
11
+ };
12
+ exports.SOCKET_IO_OPTIONS = SOCKET_IO_OPTIONS;
@@ -1,9 +1,14 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
3
5
  Object.defineProperty(exports, "__esModule", {
4
6
  value: true
5
7
  });
6
8
  exports.errorCodeMapper = exports.ErrorCodeMapper = void 0;
9
+
10
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
11
+
7
12
  var ErrorCodeMapper = {
8
13
  noPermissionError: {
9
14
  code: 'NO_PERMISSION_ERROR',
@@ -37,41 +42,44 @@ var ErrorCodeMapper = {
37
42
  exports.ErrorCodeMapper = ErrorCodeMapper;
38
43
 
39
44
  var errorCodeMapper = function errorCodeMapper(error) {
40
- if (error.data) {
41
- switch (error.data.code) {
42
- case 'INSUFFICIENT_EDITING_PERMISSION':
43
- return {
44
- status: 403,
45
- code: ErrorCodeMapper.noPermissionError.code,
46
- message: ErrorCodeMapper.noPermissionError.message
47
- };
45
+ var _error$data;
46
+
47
+ switch ((_error$data = error.data) === null || _error$data === void 0 ? void 0 : _error$data.code) {
48
+ case 'INSUFFICIENT_EDITING_PERMISSION':
49
+ return {
50
+ status: 403,
51
+ code: ErrorCodeMapper.noPermissionError.code,
52
+ message: ErrorCodeMapper.noPermissionError.message,
53
+ reason: // Typescript magic so it detects the union type
54
+ (0, _typeof2.default)(error.data.meta) === 'object' ? error.data.meta.reason : undefined
55
+ };
48
56
 
49
- case 'DOCUMENT_NOT_FOUND':
50
- return {
51
- status: 404,
52
- code: ErrorCodeMapper.documentNotFound.code,
53
- message: ErrorCodeMapper.documentNotFound.message
54
- };
57
+ case 'DOCUMENT_NOT_FOUND':
58
+ return {
59
+ status: 404,
60
+ code: ErrorCodeMapper.documentNotFound.code,
61
+ message: ErrorCodeMapper.documentNotFound.message
62
+ };
55
63
 
56
- case 'FAILED_ON_S3':
57
- case 'DYNAMO_ERROR':
58
- return {
59
- status: 500,
60
- code: ErrorCodeMapper.failToSave.code,
61
- message: ErrorCodeMapper.failToSave.message
62
- };
64
+ case 'FAILED_ON_S3':
65
+ case 'DYNAMO_ERROR':
66
+ return {
67
+ status: 500,
68
+ code: ErrorCodeMapper.failToSave.code,
69
+ message: ErrorCodeMapper.failToSave.message
70
+ };
63
71
 
64
- case 'CATCHUP_FAILED':
65
- case 'GET_QUERY_TIME_OUT':
66
- return {
67
- status: 500,
68
- code: ErrorCodeMapper.internalError.code,
69
- message: ErrorCodeMapper.internalError.message
70
- };
72
+ case 'CATCHUP_FAILED':
73
+ case 'GET_QUERY_TIME_OUT':
74
+ case 'INIT_DATA_LOAD_FAILED':
75
+ return {
76
+ status: 500,
77
+ code: ErrorCodeMapper.internalError.code,
78
+ message: ErrorCodeMapper.internalError.message
79
+ };
71
80
 
72
- default:
73
- break;
74
- }
81
+ default:
82
+ break;
75
83
  }
76
84
  };
77
85
 
@@ -16,6 +16,7 @@ exports.EVENT_ACTION = EVENT_ACTION;
16
16
  EVENT_ACTION["CATCHUP"] = "catchup";
17
17
  EVENT_ACTION["DOCUMENT_INIT"] = "documentInit";
18
18
  EVENT_ACTION["ADD_STEPS"] = "addSteps";
19
+ EVENT_ACTION["CONVERT_PM_TO_ADF"] = "convertPMToADF";
19
20
  })(EVENT_ACTION || (exports.EVENT_ACTION = EVENT_ACTION = {}));
20
21
 
21
22
  var EVENT_STATUS;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getParticipant = exports.createLogger = void 0;
6
+ exports.getSubProduct = exports.getProduct = exports.getParticipant = exports.createLogger = void 0;
7
7
  exports.sleep = sleep;
8
8
 
9
9
  var createLogger = function createLogger(prefix) {
@@ -37,4 +37,20 @@ function sleep(ms) {
37
37
  return new Promise(function (resolve) {
38
38
  setTimeout(resolve, ms);
39
39
  });
40
- }
40
+ }
41
+
42
+ var getProduct = function getProduct(productInfo) {
43
+ var _productInfo$product;
44
+
45
+ return (_productInfo$product = productInfo === null || productInfo === void 0 ? void 0 : productInfo.product) !== null && _productInfo$product !== void 0 ? _productInfo$product : 'unknown';
46
+ };
47
+
48
+ exports.getProduct = getProduct;
49
+
50
+ var getSubProduct = function getSubProduct(productInfo) {
51
+ var _productInfo$subProdu;
52
+
53
+ return (_productInfo$subProdu = productInfo === null || productInfo === void 0 ? void 0 : productInfo.subProduct) !== null && _productInfo$subProdu !== void 0 ? _productInfo$subProdu : !!(productInfo !== null && productInfo !== void 0 && productInfo.product) ? 'none' : 'unknown';
54
+ };
55
+
56
+ exports.getSubProduct = getSubProduct;
@@ -39,6 +39,8 @@ var _throttle = _interopRequireDefault(require("lodash/throttle"));
39
39
 
40
40
  var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
41
41
 
42
+ var _editorJsonTransformer = require("@atlaskit/editor-json-transformer");
43
+
42
44
  var _emitter = require("../emitter");
43
45
 
44
46
  var _channel = require("../channel");
@@ -232,7 +234,7 @@ var Provider = /*#__PURE__*/function (_Emitter) {
232
234
  while (1) {
233
235
  switch (_context.prev = _context.next) {
234
236
  case 0:
235
- (0, _performance.startMeasure)('callingCatchupApi'); // if the queue is already paused, we are busy with something else, so don't proceed.
237
+ (0, _performance.startMeasure)(_performance.MEASURE_NAME.CALLING_CATCHUP_API); // if the queue is already paused, we are busy with something else, so don't proceed.
236
238
 
237
239
  if (!_this.pauseQueue) {
238
240
  _context.next = 4;
@@ -256,7 +258,7 @@ var Provider = /*#__PURE__*/function (_Emitter) {
256
258
  });
257
259
 
258
260
  case 8:
259
- measure = (0, _performance.stopMeasure)('callingCatchupApi');
261
+ measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.CALLING_CATCHUP_API);
260
262
  (0, _analytics.triggerCollabAnalyticsEvent)({
261
263
  eventAction: _const.EVENT_ACTION.CATCHUP,
262
264
  attributes: {
@@ -270,7 +272,7 @@ var Provider = /*#__PURE__*/function (_Emitter) {
270
272
  case 12:
271
273
  _context.prev = 12;
272
274
  _context.t0 = _context["catch"](5);
273
- _measure = (0, _performance.stopMeasure)('callingCatchupApi');
275
+ _measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.CALLING_CATCHUP_API);
274
276
  (0, _analytics.triggerCollabAnalyticsEvent)({
275
277
  eventAction: _const.EVENT_ACTION.CATCHUP,
276
278
  attributes: {
@@ -566,7 +568,8 @@ var Provider = /*#__PURE__*/function (_Emitter) {
566
568
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getFinalAcknowledgedState", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
567
569
  var _this$metadata$title;
568
570
 
569
- var maxAttemptsToSync, count, unconfirmedState, state;
571
+ var maxAttemptsToSync, count, unconfirmedState, state, adfDocument, measure, _measure2;
572
+
570
573
  return _regenerator.default.wrap(function _callee4$(_context4) {
571
574
  while (1) {
572
575
  switch (_context4.prev = _context4.next) {
@@ -650,14 +653,39 @@ var Provider = /*#__PURE__*/function (_Emitter) {
650
653
  })(), "t0", 5);
651
654
 
652
655
  case 5:
653
- state = _this.getState();
656
+ state = _this.getState(); // Convert ProseMirror document in Editor state to ADF document
657
+
658
+ try {
659
+ (0, _performance.startMeasure)(_performance.MEASURE_NAME.CONVERT_PM_TO_ADF);
660
+ adfDocument = new _editorJsonTransformer.JSONTransformer().encode(state.doc);
661
+ measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.CONVERT_PM_TO_ADF);
662
+ (0, _analytics.triggerCollabAnalyticsEvent)({
663
+ eventAction: _const.EVENT_ACTION.CONVERT_PM_TO_ADF,
664
+ attributes: {
665
+ eventStatus: _const.EVENT_STATUS.SUCCESS,
666
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration
667
+ }
668
+ }, _this.analyticsClient);
669
+ } catch (error) {
670
+ _measure2 = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.CONVERT_PM_TO_ADF);
671
+ (0, _analytics.triggerCollabAnalyticsEvent)({
672
+ eventAction: _const.EVENT_ACTION.CONVERT_PM_TO_ADF,
673
+ attributes: {
674
+ eventStatus: _const.EVENT_STATUS.FAILURE,
675
+ latency: _measure2 === null || _measure2 === void 0 ? void 0 : _measure2.duration,
676
+ error: error
677
+ }
678
+ }, _this.analyticsClient);
679
+ logger("Error when converting PM document to ADF: ", error);
680
+ }
681
+
654
682
  return _context4.abrupt("return", {
655
- content: state.doc.toJSON(),
683
+ content: adfDocument,
656
684
  title: (_this$metadata$title = _this.metadata.title) === null || _this$metadata$title === void 0 ? void 0 : _this$metadata$title.toString(),
657
685
  stepVersion: (0, _prosemirrorCollab.getVersion)(state)
658
686
  });
659
687
 
660
- case 7:
688
+ case 8:
661
689
  case "end":
662
690
  return _context4.stop();
663
691
  }
@@ -14,19 +14,31 @@ var _provider = require("./provider");
14
14
 
15
15
  var _socket = require("socket.io-client");
16
16
 
17
+ var _utils = require("./helpers/utils");
18
+
19
+ var _config = require("./config");
20
+
17
21
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
18
22
 
19
23
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
20
24
 
21
- function createSocketIOSocket(url, auth) {
25
+ function createSocketIOSocket(url, auth, productInfo) {
22
26
  var _URL = new URL(url),
23
- pathname = _URL.pathname;
27
+ pathname = _URL.pathname; // to limit the reconnection flooding towards collab service, here we set the reconnectionDelayMax to 128s.
28
+
24
29
 
25
30
  return (0, _socket.io)(url, {
31
+ reconnectionDelayMax: _config.SOCKET_IO_OPTIONS.RECONNECTION_DELAY_MAX,
32
+ reconnectionDelay: _config.SOCKET_IO_OPTIONS.RECONNECTION_DELAY,
33
+ randomizationFactor: _config.SOCKET_IO_OPTIONS.RANDOMIZATION_FACTOR,
26
34
  withCredentials: true,
27
35
  transports: ['polling', 'websocket'],
28
36
  path: "/".concat(pathname.split('/')[1], "/socket.io"),
29
- auth: auth
37
+ auth: auth,
38
+ extraHeaders: {
39
+ 'x-product': (0, _utils.getProduct)(productInfo),
40
+ 'x-subproduct': (0, _utils.getSubProduct)(productInfo)
41
+ }
30
42
  });
31
43
  }
32
44
 
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/collab-provider",
3
- "version": "7.4.4",
3
+ "version": "7.5.0",
4
4
  "sideEffects": false
5
5
  }
@@ -1,3 +1,12 @@
1
+ export let MEASURE_NAME;
2
+
3
+ (function (MEASURE_NAME) {
4
+ MEASURE_NAME["CALLING_CATCHUP_API"] = "callingCatchupApi";
5
+ MEASURE_NAME["SOCKET_CONNECT"] = "socketConnect";
6
+ MEASURE_NAME["DOCUMENT_INIT"] = "documentInit";
7
+ MEASURE_NAME["CONVERT_PM_TO_ADF"] = "convertPMToADF";
8
+ })(MEASURE_NAME || (MEASURE_NAME = {}));
9
+
1
10
  const isPerformanceAPIAvailable = () => {
2
11
  return typeof window !== 'undefined' && 'performance' in window && ['measure', 'clearMeasures', 'clearMarks', 'getEntriesByName', 'getEntriesByType'].every(api => !!performance[api]);
3
12
  };
@@ -1,9 +1,10 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import { utils } from '@atlaskit/util-service-support';
2
+ import { utils } from '@atlaskit/util-service-support'; // TODO: Validate if this is actually equivalent to the AnalyticsWebClient in @atlassiansox/analytics-web-client
3
+
3
4
  import { Emitter } from './emitter';
4
5
  import { ErrorCodeMapper } from './error-code-mapper';
5
- import { createLogger } from './helpers/utils';
6
- import { startMeasure, stopMeasure } from './analytics/performance';
6
+ import { createLogger, getProduct, getSubProduct } from './helpers/utils';
7
+ import { MEASURE_NAME, startMeasure, stopMeasure } from './analytics/performance';
7
8
  import { triggerCollabAnalyticsEvent } from './analytics';
8
9
  import { EVENT_ACTION, EVENT_STATUS } from './helpers/const';
9
10
  const logger = createLogger('Channel', 'green');
@@ -26,7 +27,7 @@ export class Channel extends Emitter {
26
27
  _defineProperty(this, "onConnect", () => {
27
28
  this.connected = true;
28
29
  logger('Connected.', this.socket.id);
29
- const measure = stopMeasure('socketConnect');
30
+ const measure = stopMeasure(MEASURE_NAME.SOCKET_CONNECT);
30
31
  triggerCollabAnalyticsEvent({
31
32
  eventAction: EVENT_ACTION.CONNECTION,
32
33
  attributes: {
@@ -46,7 +47,7 @@ export class Channel extends Emitter {
46
47
 
47
48
  if (data.type === 'initial') {
48
49
  if (!this.initialized) {
49
- const measure = stopMeasure('documentInit');
50
+ const measure = stopMeasure(MEASURE_NAME.DOCUMENT_INIT);
50
51
  triggerCollabAnalyticsEvent({
51
52
  eventAction: EVENT_ACTION.DOCUMENT_INIT,
52
53
  attributes: {
@@ -86,10 +87,10 @@ export class Channel extends Emitter {
86
87
  * Connect to collab service using websockets
87
88
  */
88
89
  connect() {
89
- startMeasure('socketConnect');
90
+ startMeasure(MEASURE_NAME.SOCKET_CONNECT);
90
91
 
91
92
  if (!this.initialized) {
92
- startMeasure('documentInit');
93
+ startMeasure(MEASURE_NAME.DOCUMENT_INIT);
93
94
  }
94
95
 
95
96
  const {
@@ -102,9 +103,10 @@ export class Channel extends Emitter {
102
103
  const {
103
104
  permissionTokenRefresh
104
105
  } = this.config;
106
+ let authCb = null;
105
107
 
106
108
  if (permissionTokenRefresh) {
107
- const authCb = cb => {
109
+ authCb = cb => {
108
110
  permissionTokenRefresh().then(token => {
109
111
  cb({
110
112
  // The permission token.
@@ -118,10 +120,8 @@ export class Channel extends Emitter {
118
120
  this.emit('error', err);
119
121
  });
120
122
  };
121
-
122
- this.socket = createSocket(`${url}/session/${documentAri}`, authCb);
123
123
  } else {
124
- const authCb = cb => {
124
+ authCb = cb => {
125
125
  cb({
126
126
  // The initialized status. If false, BE will send document, otherwise not.
127
127
  initialized: this.initialized,
@@ -129,13 +129,12 @@ export class Channel extends Emitter {
129
129
  need404: this.config.need404
130
130
  });
131
131
  };
132
+ }
132
133
 
133
- this.socket = createSocket(`${url}/session/${documentAri}`, authCb);
134
- } // Due to https://github.com/socketio/socket.io-client/issues/1473,
134
+ this.socket = createSocket(`${url}/session/${documentAri}`, authCb, this.config.productInfo); // Due to https://github.com/socketio/socket.io-client/issues/1473,
135
135
  // reconnect no longer fired on the socket.
136
136
  // We should use `connect` for better cross platform compatibility(Mobile/Web).
137
137
 
138
-
139
138
  this.socket.on('connect', this.onConnect);
140
139
  this.socket.on('data', this.onReceiveData);
141
140
  this.socket.on('steps:added', data => {
@@ -188,7 +187,7 @@ export class Channel extends Emitter {
188
187
  // Ensure the error emit to the provider has the same structure, so we can handle them unified.
189
188
 
190
189
  this.socket.on('connect_error', error => {
191
- const measure = stopMeasure('socketConnect');
190
+ const measure = stopMeasure(MEASURE_NAME.SOCKET_CONNECT);
192
191
  triggerCollabAnalyticsEvent({
193
192
  eventAction: EVENT_ACTION.CONNECTION,
194
193
  attributes: {
@@ -226,13 +225,14 @@ export class Channel extends Emitter {
226
225
  queryParams: {
227
226
  version: fromVersion
228
227
  },
229
- ...(this.config.permissionTokenRefresh ? {
230
- requestInit: {
231
- headers: {
228
+ requestInit: {
229
+ headers: { ...(this.config.permissionTokenRefresh ? {
232
230
  'x-token': await this.config.permissionTokenRefresh()
233
- }
231
+ } : {}),
232
+ 'x-product': getProduct(this.config.productInfo),
233
+ 'x-subproduct': getSubProduct(this.config.productInfo)
234
234
  }
235
- } : {})
235
+ }
236
236
  });
237
237
  return {
238
238
  doc,
@@ -0,0 +1,5 @@
1
+ export const SOCKET_IO_OPTIONS = {
2
+ RECONNECTION_DELAY_MAX: 128 * 1000,
3
+ RECONNECTION_DELAY: 1000,
4
+ RANDOMIZATION_FACTOR: 0.1
5
+ };