@atlaskit/collab-provider 8.3.0 → 8.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 (86) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/cjs/analytics/{index.js → analytics-helper.js} +45 -5
  3. package/dist/cjs/analytics/performance.js +7 -5
  4. package/dist/cjs/channel.js +318 -210
  5. package/dist/cjs/{provider → document}/catchup.js +2 -2
  6. package/dist/cjs/document/document-service.js +617 -0
  7. package/dist/cjs/document/step-queue-state.js +51 -0
  8. package/dist/cjs/errors/error-code-mapper.js +107 -0
  9. package/dist/cjs/errors/error-types.js +273 -0
  10. package/dist/cjs/helpers/const.js +2 -4
  11. package/dist/cjs/helpers/utils.js +1 -12
  12. package/dist/cjs/participants/participants-helper.js +51 -0
  13. package/dist/cjs/participants/participants-service.js +217 -0
  14. package/dist/cjs/participants/participants-state.js +53 -0
  15. package/dist/cjs/{provider/telepointers.js → participants/telepointers-helper.js} +6 -6
  16. package/dist/cjs/provider/commit-step.js +40 -36
  17. package/dist/cjs/provider/index.js +215 -762
  18. package/dist/cjs/types.js +3 -0
  19. package/dist/cjs/version-wrapper.js +1 -1
  20. package/dist/cjs/version.json +1 -1
  21. package/dist/es2019/analytics/{index.js → analytics-helper.js} +17 -5
  22. package/dist/es2019/analytics/performance.js +6 -6
  23. package/dist/es2019/channel.js +204 -129
  24. package/dist/es2019/{provider → document}/catchup.js +2 -2
  25. package/dist/es2019/document/document-service.js +495 -0
  26. package/dist/es2019/document/step-queue-state.js +30 -0
  27. package/dist/es2019/errors/error-code-mapper.js +102 -0
  28. package/dist/es2019/errors/error-types.js +151 -0
  29. package/dist/es2019/helpers/const.js +2 -4
  30. package/dist/es2019/helpers/utils.js +0 -10
  31. package/dist/es2019/participants/participants-helper.js +25 -0
  32. package/dist/es2019/participants/participants-service.js +166 -0
  33. package/dist/es2019/participants/participants-state.js +28 -0
  34. package/dist/es2019/{provider/telepointers.js → participants/telepointers-helper.js} +2 -2
  35. package/dist/es2019/provider/commit-step.js +38 -34
  36. package/dist/es2019/provider/index.js +163 -626
  37. package/dist/es2019/types.js +4 -0
  38. package/dist/es2019/version-wrapper.js +1 -1
  39. package/dist/es2019/version.json +1 -1
  40. package/dist/esm/analytics/{index.js → analytics-helper.js} +45 -5
  41. package/dist/esm/analytics/performance.js +6 -6
  42. package/dist/esm/channel.js +318 -210
  43. package/dist/esm/{provider → document}/catchup.js +2 -2
  44. package/dist/esm/document/document-service.js +609 -0
  45. package/dist/esm/document/step-queue-state.js +43 -0
  46. package/dist/esm/errors/error-code-mapper.js +102 -0
  47. package/dist/esm/errors/error-types.js +259 -0
  48. package/dist/esm/helpers/const.js +2 -4
  49. package/dist/esm/helpers/utils.js +0 -10
  50. package/dist/esm/participants/participants-helper.js +43 -0
  51. package/dist/esm/participants/participants-service.js +209 -0
  52. package/dist/esm/participants/participants-state.js +45 -0
  53. package/dist/esm/{provider/telepointers.js → participants/telepointers-helper.js} +4 -4
  54. package/dist/esm/provider/commit-step.js +40 -36
  55. package/dist/esm/provider/index.js +214 -762
  56. package/dist/esm/types.js +4 -0
  57. package/dist/esm/version-wrapper.js +1 -1
  58. package/dist/esm/version.json +1 -1
  59. package/dist/types/analytics/{index.d.ts → analytics-helper.d.ts} +3 -1
  60. package/dist/types/analytics/performance.d.ts +5 -2
  61. package/dist/types/analytics/ufo.d.ts +1 -1
  62. package/dist/types/channel.d.ts +17 -5
  63. package/dist/types/document/document-service.d.ts +105 -0
  64. package/dist/types/document/step-queue-state.d.ts +16 -0
  65. package/dist/types/errors/error-code-mapper.d.ts +2 -0
  66. package/dist/types/errors/error-types.d.ts +443 -0
  67. package/dist/types/helpers/const.d.ts +31 -8
  68. package/dist/types/helpers/utils.d.ts +0 -6
  69. package/dist/types/index.d.ts +2 -1
  70. package/dist/types/participants/participants-helper.d.ts +15 -0
  71. package/dist/types/participants/participants-service.d.ts +70 -0
  72. package/dist/types/participants/participants-state.d.ts +13 -0
  73. package/dist/types/participants/telepointers-helper.d.ts +4 -0
  74. package/dist/types/provider/commit-step.d.ts +6 -6
  75. package/dist/types/provider/index.d.ts +86 -65
  76. package/dist/types/socket-io-provider.d.ts +2 -2
  77. package/dist/types/types.d.ts +65 -33
  78. package/package.json +4 -4
  79. package/report.api.md +193 -23
  80. package/dist/cjs/error-code-mapper.js +0 -88
  81. package/dist/es2019/error-code-mapper.js +0 -78
  82. package/dist/esm/error-code-mapper.js +0 -79
  83. package/dist/types/error-code-mapper.d.ts +0 -36
  84. package/dist/types/provider/telepointers.d.ts +0 -5
  85. package/error-code-mapper/package.json +0 -15
  86. /package/dist/types/{provider → document}/catchup.d.ts +0 -0
@@ -16,13 +16,14 @@ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/ge
16
16
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
17
17
  var _utilServiceSupport = require("@atlaskit/util-service-support");
18
18
  var _emitter = require("./emitter");
19
- var _errorCodeMapper = require("./error-code-mapper");
20
19
  var _utils = require("./helpers/utils");
21
20
  var _performance = require("./analytics/performance");
22
21
  var _const = require("./helpers/const");
23
22
  var _reconnectHelper = _interopRequireDefault(require("./connectivity/reconnect-helper"));
24
23
  var _ufo = require("./analytics/ufo");
24
+ var _disconnectedReasonMapper = require("./disconnected-reason-mapper");
25
25
  var _network = _interopRequireDefault(require("./connectivity/network"));
26
+ var _errorTypes = require("./errors/error-types");
26
27
  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; }
27
28
  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; }
28
29
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
@@ -49,48 +50,87 @@ var Channel = /*#__PURE__*/function (_Emitter) {
49
50
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getSocket", function () {
50
51
  return _this.socket;
51
52
  });
53
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getToken", function () {
54
+ return _this.token;
55
+ });
56
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "setToken", function (value) {
57
+ if (_this.config.cacheToken) {
58
+ _this.token = value;
59
+ }
60
+ });
61
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "unsetToken", function () {
62
+ return _this.setToken();
63
+ });
64
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handlePermissionInvalidateToken", function (data) {
65
+ var _this$analyticsHelper;
66
+ logger('Received permission invalidate event ', data);
67
+ (_this$analyticsHelper = _this.analyticsHelper) === null || _this$analyticsHelper === void 0 ? void 0 : _this$analyticsHelper.sendActionEvent(_const.EVENT_ACTION.INVALIDATE_TOKEN, _const.EVENT_STATUS.SUCCESS, {
68
+ reason: data.reason,
69
+ // Potentially incorrect when value of token changes between connecting and connect.
70
+ // See: https://bitbucket.org/atlassian/%7Bc8e2f021-38d2-46d0-9b7a-b3f7b428f724%7D/pull-requests/29905#comment-375308874
71
+ usedCachedToken: _this.token ? true : false
72
+ });
73
+ _this.unsetToken();
74
+ });
52
75
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onConnectError", function (error) {
53
- var _this$analyticsHelper, _this$analyticsHelper2;
76
+ var _this$analyticsHelper2, _this$analyticsHelper3, _message, _errorData$code;
54
77
  var measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.SOCKET_CONNECT, _this.analyticsHelper);
55
- (_this$analyticsHelper = _this.analyticsHelper) === null || _this$analyticsHelper === void 0 ? void 0 : _this$analyticsHelper.sendActionEvent(_const.EVENT_ACTION.CONNECTION, _const.EVENT_STATUS.FAILURE, {
56
- latency: measure === null || measure === void 0 ? void 0 : measure.duration
78
+ (_this$analyticsHelper2 = _this.analyticsHelper) === null || _this$analyticsHelper2 === void 0 ? void 0 : _this$analyticsHelper2.sendActionEvent(_const.EVENT_ACTION.CONNECTION, _const.EVENT_STATUS.FAILURE, {
79
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration,
80
+ // Potentially incorrect when value of token changes between connecting and connect.
81
+ // See: https://bitbucket.org/atlassian/%7Bc8e2f021-38d2-46d0-9b7a-b3f7b428f724%7D/pull-requests/29905#comment-375308874
82
+ usedCachedToken: _this.token ? true : false
57
83
  });
58
- (_this$analyticsHelper2 = _this.analyticsHelper) === null || _this$analyticsHelper2 === void 0 ? void 0 : _this$analyticsHelper2.sendErrorEvent(error, 'Error while establishing connection');
84
+ (_this$analyticsHelper3 = _this.analyticsHelper) === null || _this$analyticsHelper3 === void 0 ? void 0 : _this$analyticsHelper3.sendErrorEvent(error, 'Error while establishing connection');
59
85
  // If error received with `data`, it means the connection is rejected
60
86
  // by the server on purpose for example no permission, so no need to
61
87
  // keep the underneath connection, need to close. But some error like
62
88
  // `xhr polling error` needs to retry.
63
- if (!!error.data) {
89
+ var errorData = error.data;
90
+ if (errorData) {
64
91
  var _this$socket;
92
+ // We only want to refresh the token if only its invalid
93
+ // @ts-expect-error we should be more explicit about which type of errors we expect here, so they always have a status
94
+ if ([401, 403].includes(errorData.status)) {
95
+ //nullify token so it is forced to generate new token on reconnect
96
+ _this.unsetToken();
97
+ }
65
98
  (_this$socket = _this.socket) === null || _this$socket === void 0 ? void 0 : _this$socket.close();
66
99
  }
67
- _this.emit('error', {
68
- message: error.message,
69
- data: error.data
70
- });
100
+ var connectionError = {
101
+ message: (_message = error.message) !== null && _message !== void 0 ? _message : 'Connection error without message',
102
+ data: _objectSpread({
103
+ // @ts-expect-error I bet we'll see some connection errors, for the Socket IO errors
104
+ code: (_errorData$code = errorData === null || errorData === void 0 ? void 0 : errorData.code) !== null && _errorData$code !== void 0 ? _errorData$code : _errorTypes.INTERNAL_ERROR_CODE.CONNECTION_ERROR
105
+ }, errorData)
106
+ };
107
+ _this.emit('error', connectionError);
71
108
  });
72
109
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onReconnectError", function (error) {
73
110
  var _this$reconnectHelper, _this$reconnectHelper2;
74
111
  (_this$reconnectHelper = _this.reconnectHelper) === null || _this$reconnectHelper === void 0 ? void 0 : _this$reconnectHelper.countReconnectError();
75
112
  if ((_this$reconnectHelper2 = _this.reconnectHelper) !== null && _this$reconnectHelper2 !== void 0 && _this$reconnectHelper2.isLikelyNetworkIssue()) {
76
- var _this$analyticsHelper3;
77
- (_this$analyticsHelper3 = _this.analyticsHelper) === null || _this$analyticsHelper3 === void 0 ? void 0 : _this$analyticsHelper3.sendErrorEvent(error, 'Likely network issue while reconnecting the channel');
78
- _this.emit('error', {
79
- message: 'Reconnection failed 8 times when browser was offline, likely there was a network issue.',
113
+ var _this$analyticsHelper4;
114
+ (_this$analyticsHelper4 = _this.analyticsHelper) === null || _this$analyticsHelper4 === void 0 ? void 0 : _this$analyticsHelper4.sendErrorEvent(error, 'Likely network issue while reconnecting the channel');
115
+ var reconnectionError = {
116
+ message: 'Reconnection failed 8 times when browser was offline, likely there was a network issue',
80
117
  data: {
81
- status: 400,
82
- code: 'RECONNECTION_NETWORK_ISSUE'
118
+ code: _errorTypes.INTERNAL_ERROR_CODE.RECONNECTION_NETWORK_ISSUE
83
119
  }
84
- });
120
+ };
121
+ _this.emit('error', reconnectionError);
85
122
  }
86
123
  });
87
124
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onConnect", function () {
88
- var _this$analyticsHelper4;
125
+ var _this$analyticsHelper5;
89
126
  _this.connected = true;
90
127
  logger('Connected.', _this.socket.id);
91
128
  var measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.SOCKET_CONNECT, _this.analyticsHelper);
92
- (_this$analyticsHelper4 = _this.analyticsHelper) === null || _this$analyticsHelper4 === void 0 ? void 0 : _this$analyticsHelper4.sendActionEvent(_const.EVENT_ACTION.CONNECTION, _const.EVENT_STATUS.SUCCESS, {
93
- latency: measure === null || measure === void 0 ? void 0 : measure.duration
129
+ (_this$analyticsHelper5 = _this.analyticsHelper) === null || _this$analyticsHelper5 === void 0 ? void 0 : _this$analyticsHelper5.sendActionEvent(_const.EVENT_ACTION.CONNECTION, _const.EVENT_STATUS.SUCCESS, {
130
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration,
131
+ // Potentially incorrect when value of token changes between connecting and connect.
132
+ // See: https://bitbucket.org/atlassian/%7Bc8e2f021-38d2-46d0-9b7a-b3f7b428f724%7D/pull-requests/29905#comment-375308874
133
+ usedCachedToken: _this.token ? true : false
94
134
  });
95
135
  _this.emit('connected', {
96
136
  sid: _this.socket.id,
@@ -102,10 +142,10 @@ var Channel = /*#__PURE__*/function (_Emitter) {
102
142
  logger('Session ID is', _this.socket.id);
103
143
  if (data.type === 'initial') {
104
144
  if (!_this.initialized) {
105
- var _this$initExperience, _this$analyticsHelper5;
145
+ var _this$initExperience, _this$analyticsHelper6;
106
146
  var measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.DOCUMENT_INIT, _this.analyticsHelper);
107
147
  (_this$initExperience = _this.initExperience) === null || _this$initExperience === void 0 ? void 0 : _this$initExperience.success();
108
- (_this$analyticsHelper5 = _this.analyticsHelper) === null || _this$analyticsHelper5 === void 0 ? void 0 : _this$analyticsHelper5.sendActionEvent(_const.EVENT_ACTION.DOCUMENT_INIT,
148
+ (_this$analyticsHelper6 = _this.analyticsHelper) === null || _this$analyticsHelper6 === void 0 ? void 0 : _this$analyticsHelper6.sendActionEvent(_const.EVENT_ACTION.DOCUMENT_INIT,
109
149
  // TODO: detect when document init fails and fire corresponding event for it
110
150
  _const.EVENT_STATUS.SUCCESS, {
111
151
  latency: measure === null || measure === void 0 ? void 0 : measure.duration,
@@ -140,6 +180,167 @@ var Channel = /*#__PURE__*/function (_Emitter) {
140
180
  _this.emit('steps:added', data);
141
181
  }
142
182
  });
183
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "fetchCatchup", /*#__PURE__*/function () {
184
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(fromVersion) {
185
+ var _ref2, _this$token, _yield$utils$requestS, doc, version, stepMaps, metadata, errorNotFound, errorCatchup;
186
+ return _regenerator.default.wrap(function _callee$(_context) {
187
+ while (1) {
188
+ switch (_context.prev = _context.next) {
189
+ case 0:
190
+ _context.prev = 0;
191
+ _context.t0 = _utilServiceSupport.utils;
192
+ _context.t1 = _this.config;
193
+ _context.t2 = "document/".concat(encodeURIComponent(_this.config.documentAri), "/catchup");
194
+ _context.t3 = {
195
+ version: fromVersion
196
+ };
197
+ _context.t4 = _objectSpread;
198
+ _context.t5 = _objectSpread;
199
+ _context.t6 = {};
200
+ if (!_this.config.permissionTokenRefresh) {
201
+ _context.next = 29;
202
+ break;
203
+ }
204
+ if (!((_this$token = _this.token) !== null && _this$token !== void 0)) {
205
+ _context.next = 13;
206
+ break;
207
+ }
208
+ _context.t9 = _this$token;
209
+ _context.next = 16;
210
+ break;
211
+ case 13:
212
+ _context.next = 15;
213
+ return _this.config.permissionTokenRefresh().then(function (token) {
214
+ if (token) {
215
+ _this.setToken(token);
216
+ }
217
+ return token;
218
+ });
219
+ case 15:
220
+ _context.t9 = _context.sent;
221
+ case 16:
222
+ _context.t10 = _ref2 = _context.t9;
223
+ _context.t8 = _context.t10 !== null;
224
+ if (!_context.t8) {
225
+ _context.next = 20;
226
+ break;
227
+ }
228
+ _context.t8 = _ref2 !== void 0;
229
+ case 20:
230
+ if (!_context.t8) {
231
+ _context.next = 24;
232
+ break;
233
+ }
234
+ _context.t11 = _ref2;
235
+ _context.next = 25;
236
+ break;
237
+ case 24:
238
+ _context.t11 = undefined;
239
+ case 25:
240
+ _context.t12 = _context.t11;
241
+ _context.t7 = {
242
+ 'x-token': _context.t12
243
+ };
244
+ _context.next = 30;
245
+ break;
246
+ case 29:
247
+ _context.t7 = {};
248
+ case 30:
249
+ _context.t13 = _context.t7;
250
+ _context.t14 = (0, _context.t5)(_context.t6, _context.t13);
251
+ _context.t15 = {};
252
+ _context.t16 = {
253
+ 'x-product': (0, _utils.getProduct)(_this.config.productInfo),
254
+ 'x-subproduct': (0, _utils.getSubProduct)(_this.config.productInfo)
255
+ };
256
+ _context.t17 = (0, _context.t4)(_context.t14, _context.t15, _context.t16);
257
+ _context.t18 = {
258
+ headers: _context.t17
259
+ };
260
+ _context.t19 = {
261
+ path: _context.t2,
262
+ queryParams: _context.t3,
263
+ requestInit: _context.t18
264
+ };
265
+ _context.next = 39;
266
+ return _context.t0.requestService.call(_context.t0, _context.t1, _context.t19);
267
+ case 39:
268
+ _yield$utils$requestS = _context.sent;
269
+ doc = _yield$utils$requestS.doc;
270
+ version = _yield$utils$requestS.version;
271
+ stepMaps = _yield$utils$requestS.stepMaps;
272
+ metadata = _yield$utils$requestS.metadata;
273
+ return _context.abrupt("return", {
274
+ doc: doc,
275
+ version: version,
276
+ stepMaps: stepMaps,
277
+ metadata: metadata
278
+ });
279
+ case 47:
280
+ _context.prev = 47;
281
+ _context.t20 = _context["catch"](0);
282
+ if (!(_context.t20.code === 404)) {
283
+ _context.next = 53;
284
+ break;
285
+ }
286
+ errorNotFound = {
287
+ message: 'The requested document is not found',
288
+ data: {
289
+ status: _context.t20.code,
290
+ code: _errorTypes.INTERNAL_ERROR_CODE.DOCUMENT_NOT_FOUND
291
+ }
292
+ };
293
+ _this.emit('error', errorNotFound);
294
+ return _context.abrupt("return", {});
295
+ case 53:
296
+ //nullify token so it is forced to generate new token on reconnect
297
+ _this.unsetToken();
298
+ logger("Can't fetch the catchup", _context.t20.message);
299
+ errorCatchup = {
300
+ message: 'Cannot fetch catchup from collab service',
301
+ data: {
302
+ status: _context.t20.status,
303
+ code: _errorTypes.INTERNAL_ERROR_CODE.CATCHUP_FAILED
304
+ }
305
+ };
306
+ _this.emit('error', errorCatchup);
307
+ throw _context.t20;
308
+ case 58:
309
+ case "end":
310
+ return _context.stop();
311
+ }
312
+ }
313
+ }, _callee, null, [[0, 47]]);
314
+ }));
315
+ return function (_x) {
316
+ return _ref.apply(this, arguments);
317
+ };
318
+ }());
319
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "broadcast", function (type, data, callback) {
320
+ if (!_this.socket) {
321
+ throw new _errorTypes.NotInitializedError('Cannot broadcast, not initialized yet');
322
+ }
323
+ if (!_this.connected) {
324
+ if (_this.config.throwOnNotConnected) {
325
+ throw new _errorTypes.NotConnectedError('Cannot broadcast, currently offline.');
326
+ }
327
+ return;
328
+ }
329
+ _this.socket.emit('broadcast', _objectSpread({
330
+ type: type
331
+ }, data), callback);
332
+ });
333
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "sendMetadata", function (metadata) {
334
+ if (!_this.socket) {
335
+ throw new _errorTypes.NotInitializedError('Cannot send metadata, not initialized yet');
336
+ }
337
+ if (!_this.connected) {
338
+ if (_this.config.throwOnNotConnected) {
339
+ throw new _errorTypes.NotConnectedError('Cannot send metadata, currently offline.');
340
+ }
341
+ }
342
+ _this.socket.emit('metadata', metadata);
343
+ });
143
344
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onOnlineHandler", function () {
144
345
  // Force an immediate reconnect, the socket must first be closed to reset reconnection delay logic
145
346
  if (!_this.connected) {
@@ -173,34 +374,80 @@ var Channel = /*#__PURE__*/function (_Emitter) {
173
374
  documentAri = _this$config.documentAri,
174
375
  url = _this$config.url;
175
376
  var createSocket = this.config.createSocket;
176
- var permissionTokenRefresh = this.config.permissionTokenRefresh;
177
- var authCb = null;
377
+ var _this$config2 = this.config,
378
+ permissionTokenRefresh = _this$config2.permissionTokenRefresh,
379
+ cacheToken = _this$config2.cacheToken;
380
+ var auth;
381
+ var authData = {
382
+ // The initialized status. If false, BE will send document, otherwise not.
383
+ initialized: this.initialized,
384
+ // ESS-1009 Allow to opt-in into 404 response
385
+ need404: this.config.need404
386
+ };
178
387
  if (permissionTokenRefresh) {
179
- authCb = function authCb(cb) {
180
- permissionTokenRefresh().then(function (token) {
181
- cb(_objectSpread(_objectSpread({}, token ? {
182
- token: token
183
- } : {}), {}, {
184
- // The initialized status. If false, BE will send document, otherwise not.
185
- initialized: _this2.initialized,
186
- // ESS-1009 Allow to opt-in into 404 response
187
- need404: _this2.config.need404
188
- }));
189
- }).catch(function (err) {
190
- _this2.emit('error', err);
191
- });
192
- };
388
+ auth = /*#__PURE__*/function () {
389
+ var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(cb) {
390
+ var token, _err, _err$data, _err$data$meta, authenticationError;
391
+ return _regenerator.default.wrap(function _callee2$(_context2) {
392
+ while (1) {
393
+ switch (_context2.prev = _context2.next) {
394
+ case 0:
395
+ if (!(cacheToken && _this2.token)) {
396
+ _context2.next = 5;
397
+ break;
398
+ }
399
+ authData.token = _this2.token;
400
+ cb(authData);
401
+ _context2.next = 17;
402
+ break;
403
+ case 5:
404
+ _context2.prev = 5;
405
+ _context2.next = 8;
406
+ return permissionTokenRefresh();
407
+ case 8:
408
+ token = _context2.sent;
409
+ if (token) {
410
+ // save token locally
411
+ _this2.setToken(token);
412
+ authData.token = token;
413
+ }
414
+ cb(authData);
415
+ _context2.next = 17;
416
+ break;
417
+ case 13:
418
+ _context2.prev = 13;
419
+ _context2.t0 = _context2["catch"](5);
420
+ // Pass the error back to the consumers so they can deal with exceptional cases themselves (eg. no permissions because the page was deleted)
421
+ authenticationError = {
422
+ message: 'Insufficient editing permissions',
423
+ data: {
424
+ status: 403,
425
+ code: _errorTypes.INTERNAL_ERROR_CODE.TOKEN_PERMISSION_ERROR,
426
+ meta: {
427
+ originalError: _context2.t0,
428
+ // @ts-expect-error we know the error structure passed in this hack
429
+ reason: (_err = err) === null || _err === void 0 ? void 0 : (_err$data = _err.data) === null || _err$data === void 0 ? void 0 : (_err$data$meta = _err$data.meta) === null || _err$data$meta === void 0 ? void 0 : _err$data$meta.reason // Should always be 'RESOURCE_DELETED' Temporary, until Confluence Cloud removes their hack
430
+ // https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/browse/next/packages/native-collab/src/fetchCollabPermissionToken.ts#37
431
+ }
432
+ }
433
+ };
434
+
435
+ _this2.emit('error', authenticationError);
436
+ case 17:
437
+ case "end":
438
+ return _context2.stop();
439
+ }
440
+ }
441
+ }, _callee2, null, [[5, 13]]);
442
+ }));
443
+ return function auth(_x2) {
444
+ return _ref3.apply(this, arguments);
445
+ };
446
+ }();
193
447
  } else {
194
- authCb = function authCb(cb) {
195
- cb({
196
- // The initialized status. If false, BE will send document, otherwise not.
197
- initialized: _this2.initialized,
198
- // ESS-1009 Allow to opt-in into 404 response
199
- need404: _this2.config.need404
200
- });
201
- };
448
+ auth = authData;
202
449
  }
203
- this.socket = createSocket("".concat(url, "/session/").concat(documentAri), authCb, this.config.productInfo);
450
+ this.socket = createSocket("".concat(url, "/session/").concat(documentAri), auth, this.config.productInfo);
204
451
 
205
452
  // Due to https://github.com/socketio/socket.io-client/issues/1473,
206
453
  // reconnect no longer fired on the socket.
@@ -222,11 +469,11 @@ var Channel = /*#__PURE__*/function (_Emitter) {
222
469
  this.socket.on('participant:left', function (data) {
223
470
  _this2.emit('participant:left', data);
224
471
  });
225
- this.socket.on('participant:updated', function (_ref) {
226
- var sessionId = _ref.sessionId,
227
- timestamp = _ref.timestamp,
228
- data = _ref.data,
229
- clientId = _ref.clientId;
472
+ this.socket.on('participant:updated', function (_ref4) {
473
+ var sessionId = _ref4.sessionId,
474
+ timestamp = _ref4.timestamp,
475
+ data = _ref4.data,
476
+ clientId = _ref4.clientId;
230
477
  _this2.emit('participant:updated', _objectSpread({
231
478
  sessionId: sessionId,
232
479
  timestamp: timestamp,
@@ -242,52 +489,54 @@ var Channel = /*#__PURE__*/function (_Emitter) {
242
489
  _this2.emit('status', data);
243
490
  });
244
491
  this.socket.on('disconnect', /*#__PURE__*/function () {
245
- var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(reason) {
246
- var _this2$analyticsHelpe;
247
- return _regenerator.default.wrap(function _callee$(_context) {
492
+ var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(reason) {
493
+ var _this2$analyticsHelpe, reconnectionError;
494
+ return _regenerator.default.wrap(function _callee3$(_context3) {
248
495
  while (1) {
249
- switch (_context.prev = _context.next) {
496
+ switch (_context3.prev = _context3.next) {
250
497
  case 0:
251
498
  _this2.connected = false;
252
499
  logger("disconnect reason: ".concat(reason));
253
500
  _this2.emit('disconnect', {
254
501
  reason: reason
255
502
  });
256
- if (reason === 'io server disconnect' && _this2.socket) {
503
+ if (reason === _disconnectedReasonMapper.socketIOReasons.IO_SERVER_DISCONNECT && _this2.socket) {
257
504
  // The disconnection was initiated by the server, we need to reconnect manually.
258
505
  try {
259
506
  _this2.socket.connect();
260
507
  } catch (error) {
261
508
  (_this2$analyticsHelpe = _this2.analyticsHelper) === null || _this2$analyticsHelpe === void 0 ? void 0 : _this2$analyticsHelpe.sendErrorEvent(error, 'Error while reconnecting the channel');
262
- _this2.emit('error', {
263
- message: 'Caught error during reconnection.',
509
+ reconnectionError = {
510
+ message: 'Caught error during reconnection',
264
511
  data: {
265
512
  status: 500,
266
- code: 'RECONNECTION_ERROR'
513
+ code: _errorTypes.INTERNAL_ERROR_CODE.RECONNECTION_ERROR
267
514
  }
268
- });
515
+ };
516
+ _this2.emit('error', reconnectionError);
269
517
  }
270
518
  }
271
519
  case 4:
272
520
  case "end":
273
- return _context.stop();
521
+ return _context3.stop();
274
522
  }
275
523
  }
276
- }, _callee);
524
+ }, _callee3);
277
525
  }));
278
- return function (_x) {
279
- return _ref2.apply(this, arguments);
526
+ return function (_x3) {
527
+ return _ref5.apply(this, arguments);
280
528
  };
281
529
  }());
282
530
 
283
531
  // Socket error, including errors from `packetMiddleware`, `controllers` and `onconnect` and more. Parameter is a plain JSON object.
284
- this.socket.on('error', function (error) {
285
- _this2.emit('error', error);
532
+ this.socket.on('error', function (socketError) {
533
+ _this2.emit('error', socketError);
286
534
  });
287
535
 
288
536
  // `connect_error`'s parameter type is `Error`.
289
537
  // Ensure the error emit to the provider has the same structure, so we can handle them unified.
290
538
  this.socket.on('connect_error', this.onConnectError);
539
+ this.socket.on('permission:invalidateToken', this.handlePermissionInvalidateToken);
291
540
 
292
541
  // To trigger reconnection when browser comes back online
293
542
  if (!this.network) {
@@ -301,149 +550,6 @@ var Channel = /*#__PURE__*/function (_Emitter) {
301
550
  // Fired upon a reconnection attempt error (from Socket.IO Manager)
302
551
  this.socket.io.on('reconnect_error', this.onReconnectError);
303
552
  }
304
- }, {
305
- key: "fetchCatchup",
306
- value: function () {
307
- var _fetchCatchup = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(fromVersion) {
308
- var _yield$this$config$pe, _yield$utils$requestS, doc, version, stepMaps, metadata, errorNotFound, errorCatchup;
309
- return _regenerator.default.wrap(function _callee2$(_context2) {
310
- while (1) {
311
- switch (_context2.prev = _context2.next) {
312
- case 0:
313
- _context2.prev = 0;
314
- _context2.t0 = _utilServiceSupport.utils;
315
- _context2.t1 = this.config;
316
- _context2.t2 = "document/".concat(encodeURIComponent(this.config.documentAri), "/catchup");
317
- _context2.t3 = {
318
- version: fromVersion
319
- };
320
- _context2.t4 = _objectSpread;
321
- _context2.t5 = _objectSpread;
322
- _context2.t6 = {};
323
- if (!this.config.permissionTokenRefresh) {
324
- _context2.next = 24;
325
- break;
326
- }
327
- _context2.next = 11;
328
- return this.config.permissionTokenRefresh();
329
- case 11:
330
- _context2.t9 = _yield$this$config$pe = _context2.sent;
331
- _context2.t8 = _context2.t9 !== null;
332
- if (!_context2.t8) {
333
- _context2.next = 15;
334
- break;
335
- }
336
- _context2.t8 = _yield$this$config$pe !== void 0;
337
- case 15:
338
- if (!_context2.t8) {
339
- _context2.next = 19;
340
- break;
341
- }
342
- _context2.t10 = _yield$this$config$pe;
343
- _context2.next = 20;
344
- break;
345
- case 19:
346
- _context2.t10 = undefined;
347
- case 20:
348
- _context2.t11 = _context2.t10;
349
- _context2.t7 = {
350
- 'x-token': _context2.t11
351
- };
352
- _context2.next = 25;
353
- break;
354
- case 24:
355
- _context2.t7 = {};
356
- case 25:
357
- _context2.t12 = _context2.t7;
358
- _context2.t13 = (0, _context2.t5)(_context2.t6, _context2.t12);
359
- _context2.t14 = {};
360
- _context2.t15 = {
361
- 'x-product': (0, _utils.getProduct)(this.config.productInfo),
362
- 'x-subproduct': (0, _utils.getSubProduct)(this.config.productInfo)
363
- };
364
- _context2.t16 = (0, _context2.t4)(_context2.t13, _context2.t14, _context2.t15);
365
- _context2.t17 = {
366
- headers: _context2.t16
367
- };
368
- _context2.t18 = {
369
- path: _context2.t2,
370
- queryParams: _context2.t3,
371
- requestInit: _context2.t17
372
- };
373
- _context2.next = 34;
374
- return _context2.t0.requestService.call(_context2.t0, _context2.t1, _context2.t18);
375
- case 34:
376
- _yield$utils$requestS = _context2.sent;
377
- doc = _yield$utils$requestS.doc;
378
- version = _yield$utils$requestS.version;
379
- stepMaps = _yield$utils$requestS.stepMaps;
380
- metadata = _yield$utils$requestS.metadata;
381
- return _context2.abrupt("return", {
382
- doc: doc,
383
- version: version,
384
- stepMaps: stepMaps,
385
- metadata: metadata
386
- });
387
- case 42:
388
- _context2.prev = 42;
389
- _context2.t19 = _context2["catch"](0);
390
- if (!(_context2.t19.code === 404)) {
391
- _context2.next = 48;
392
- break;
393
- }
394
- errorNotFound = {
395
- message: _errorCodeMapper.ErrorCodeMapper.documentNotFound.message,
396
- data: {
397
- status: _context2.t19.code,
398
- code: _errorCodeMapper.ErrorCodeMapper.documentNotFound.code
399
- }
400
- };
401
- this.emit('error', errorNotFound);
402
- return _context2.abrupt("return", {});
403
- case 48:
404
- logger("Can't fetch the catchup", _context2.t19.message);
405
- errorCatchup = {
406
- message: _errorCodeMapper.ErrorCodeMapper.catchupFail.message,
407
- data: {
408
- status: _context2.t19.status,
409
- code: _errorCodeMapper.ErrorCodeMapper.catchupFail.code
410
- }
411
- };
412
- this.emit('error', errorCatchup);
413
- throw _context2.t19;
414
- case 52:
415
- case "end":
416
- return _context2.stop();
417
- }
418
- }
419
- }, _callee2, this, [[0, 42]]);
420
- }));
421
- function fetchCatchup(_x2) {
422
- return _fetchCatchup.apply(this, arguments);
423
- }
424
- return fetchCatchup;
425
- }()
426
- /**
427
- * Send message to service. Timestamp will be added server side.
428
- */
429
- }, {
430
- key: "broadcast",
431
- value: function broadcast(type, data, callback) {
432
- if (!this.connected || !this.socket) {
433
- return;
434
- }
435
- this.socket.emit('broadcast', _objectSpread({
436
- type: type
437
- }, data), callback);
438
- }
439
- }, {
440
- key: "sendMetadata",
441
- value: function sendMetadata(metadata) {
442
- if (!this.connected || !this.socket) {
443
- return;
444
- }
445
- this.socket.emit('metadata', metadata);
446
- }
447
553
  }, {
448
554
  key: "sendPresenceJoined",
449
555
  value: function sendPresenceJoined() {
@@ -459,6 +565,8 @@ var Channel = /*#__PURE__*/function (_Emitter) {
459
565
  this.unsubscribeAll();
460
566
  (_this$network = this.network) === null || _this$network === void 0 ? void 0 : _this$network.destroy();
461
567
  this.network = null;
568
+ //nullify token so it is forced to generate new token on reconnect
569
+ this.unsetToken();
462
570
  if (this.socket) {
463
571
  var _this$reconnectHelper3;
464
572
  this.socket.close();
@@ -115,12 +115,12 @@ var catchup = /*#__PURE__*/function () {
115
115
  var stepMap = new _prosemirrorTransform.StepMap(ranges);
116
116
  stepMap.inverted = inverted;
117
117
  return stepMap;
118
- }); // create Mappng used for Step.map
118
+ }); // create Mapping used for Step.map
119
119
  mapping = new _prosemirrorTransform.Mapping(stepMaps);
120
120
  logger("".concat(_unconfirmedSteps.length, " unconfirmed steps before rebased: ").concat(JSON.stringify(_unconfirmedSteps)));
121
121
  newUnconfirmedSteps = rebaseSteps(_unconfirmedSteps, mapping);
122
122
  logger("Re-aply ".concat(newUnconfirmedSteps.length, " mapped unconfirmed steps: ").concat(JSON.stringify(newUnconfirmedSteps)));
123
- // Re-aply local steps
123
+ // Re-apply local steps
124
124
  opt.applyLocalSteps(newUnconfirmedSteps);
125
125
  }
126
126
  }