@atlaskit/collab-provider 8.4.0 → 8.6.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 (88) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/cjs/analytics/analytics-helper.js +135 -0
  3. package/dist/cjs/analytics/performance.js +6 -5
  4. package/dist/cjs/channel.js +242 -223
  5. package/dist/cjs/document/catchup.js +142 -0
  6. package/dist/cjs/document/document-service.js +587 -0
  7. package/dist/cjs/document/step-queue-state.js +56 -0
  8. package/dist/cjs/errors/error-code-mapper.js +86 -67
  9. package/dist/cjs/errors/error-types.js +329 -21
  10. package/dist/cjs/helpers/utils.js +1 -12
  11. package/dist/cjs/index.js +8 -1
  12. package/dist/cjs/metadata/metadata-service.js +82 -0
  13. package/dist/cjs/participants/participants-helper.js +52 -0
  14. package/dist/cjs/participants/participants-service.js +259 -0
  15. package/dist/cjs/participants/participants-state.js +56 -0
  16. package/dist/cjs/{provider/telepointers.js → participants/telepointers-helper.js} +6 -6
  17. package/dist/cjs/provider/commit-step.js +14 -6
  18. package/dist/cjs/provider/index.js +291 -780
  19. package/dist/cjs/types.js +6 -1
  20. package/dist/cjs/version-wrapper.js +1 -1
  21. package/dist/cjs/version.json +1 -1
  22. package/dist/es2019/analytics/{index.js → analytics-helper.js} +15 -4
  23. package/dist/es2019/analytics/performance.js +5 -6
  24. package/dist/es2019/channel.js +140 -113
  25. package/dist/es2019/{provider → document}/catchup.js +6 -4
  26. package/dist/es2019/document/document-service.js +472 -0
  27. package/dist/es2019/document/step-queue-state.js +35 -0
  28. package/dist/es2019/errors/error-code-mapper.js +87 -63
  29. package/dist/es2019/errors/error-types.js +221 -5
  30. package/dist/es2019/helpers/utils.js +0 -10
  31. package/dist/es2019/index.js +2 -1
  32. package/dist/es2019/metadata/metadata-service.js +61 -0
  33. package/dist/es2019/participants/participants-helper.js +25 -0
  34. package/dist/es2019/participants/participants-service.js +207 -0
  35. package/dist/es2019/participants/participants-state.js +30 -0
  36. package/dist/es2019/{provider/telepointers.js → participants/telepointers-helper.js} +2 -2
  37. package/dist/es2019/provider/commit-step.js +12 -5
  38. package/dist/es2019/provider/index.js +240 -640
  39. package/dist/es2019/types.js +8 -1
  40. package/dist/es2019/version-wrapper.js +1 -1
  41. package/dist/es2019/version.json +1 -1
  42. package/dist/esm/analytics/analytics-helper.js +128 -0
  43. package/dist/esm/analytics/performance.js +5 -6
  44. package/dist/esm/channel.js +243 -224
  45. package/dist/esm/document/catchup.js +133 -0
  46. package/dist/esm/document/document-service.js +579 -0
  47. package/dist/esm/document/step-queue-state.js +48 -0
  48. package/dist/esm/errors/error-code-mapper.js +87 -64
  49. package/dist/esm/errors/error-types.js +321 -18
  50. package/dist/esm/helpers/utils.js +0 -10
  51. package/dist/esm/index.js +2 -1
  52. package/dist/esm/metadata/metadata-service.js +74 -0
  53. package/dist/esm/participants/participants-helper.js +44 -0
  54. package/dist/esm/participants/participants-service.js +251 -0
  55. package/dist/esm/participants/participants-state.js +48 -0
  56. package/dist/esm/{provider/telepointers.js → participants/telepointers-helper.js} +4 -4
  57. package/dist/esm/provider/commit-step.js +12 -5
  58. package/dist/esm/provider/index.js +291 -779
  59. package/dist/esm/types.js +8 -1
  60. package/dist/esm/version-wrapper.js +1 -1
  61. package/dist/esm/version.json +1 -1
  62. package/dist/types/analytics/{index.d.ts → analytics-helper.d.ts} +3 -1
  63. package/dist/types/analytics/performance.d.ts +3 -1
  64. package/dist/types/analytics/ufo.d.ts +1 -1
  65. package/dist/types/channel.d.ts +13 -6
  66. package/dist/types/document/document-service.d.ts +86 -0
  67. package/dist/types/document/step-queue-state.d.ts +16 -0
  68. package/dist/types/errors/error-code-mapper.d.ts +2 -36
  69. package/dist/types/errors/error-types.d.ts +439 -4
  70. package/dist/types/helpers/const.d.ts +2 -2
  71. package/dist/types/helpers/utils.d.ts +0 -6
  72. package/dist/types/index.d.ts +3 -1
  73. package/dist/types/metadata/metadata-service.d.ts +25 -0
  74. package/dist/types/participants/participants-helper.d.ts +15 -0
  75. package/dist/types/participants/participants-service.d.ts +74 -0
  76. package/dist/types/participants/participants-state.d.ts +13 -0
  77. package/dist/types/participants/telepointers-helper.d.ts +4 -0
  78. package/dist/types/provider/commit-step.d.ts +17 -6
  79. package/dist/types/provider/index.d.ts +81 -78
  80. package/dist/types/types.d.ts +56 -31
  81. package/package.json +6 -6
  82. package/report.api.md +187 -21
  83. package/dist/cjs/analytics/index.js +0 -95
  84. package/dist/cjs/provider/catchup.js +0 -139
  85. package/dist/esm/analytics/index.js +0 -88
  86. package/dist/esm/provider/catchup.js +0 -130
  87. package/dist/types/provider/telepointers.d.ts +0 -5
  88. /package/dist/types/{provider → document}/catchup.d.ts +0 -0
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
5
  Object.defineProperty(exports, "__esModule", {
5
6
  value: true
6
7
  });
7
8
  exports.Channel = void 0;
8
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
9
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
11
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
@@ -16,7 +16,6 @@ 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("./errors/error-code-mapper");
20
19
  var _utils = require("./helpers/utils");
21
20
  var _performance = require("./analytics/performance");
22
21
  var _const = require("./helpers/const");
@@ -25,6 +24,7 @@ var _ufo = require("./analytics/ufo");
25
24
  var _disconnectedReasonMapper = require("./disconnected-reason-mapper");
26
25
  var _network = _interopRequireDefault(require("./connectivity/network"));
27
26
  var _errorTypes = require("./errors/error-types");
27
+ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, defineProperty = Object.defineProperty || function (obj, key, desc) { obj[key] = desc.value; }, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return defineProperty(generator, "_invoke", { value: makeInvokeMethod(innerFn, self, context) }), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; defineProperty(this, "_invoke", { value: function value(method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; } function maybeInvokeDelegate(delegate, context) { var methodName = context.method, method = delegate.iterator[methodName]; if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel; var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), defineProperty(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (val) { var object = Object(val), keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, catch: function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; }
28
28
  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; }
29
29
  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; }
30
30
  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); }; }
@@ -74,7 +74,7 @@ var Channel = /*#__PURE__*/function (_Emitter) {
74
74
  _this.unsetToken();
75
75
  });
76
76
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onConnectError", function (error) {
77
- var _this$analyticsHelper2, _this$analyticsHelper3;
77
+ var _this$analyticsHelper2, _this$analyticsHelper3, _message, _errorData$code;
78
78
  var measure = (0, _performance.stopMeasure)(_performance.MEASURE_NAME.SOCKET_CONNECT, _this.analyticsHelper);
79
79
  (_this$analyticsHelper2 = _this.analyticsHelper) === null || _this$analyticsHelper2 === void 0 ? void 0 : _this$analyticsHelper2.sendActionEvent(_const.EVENT_ACTION.CONNECTION, _const.EVENT_STATUS.FAILURE, {
80
80
  latency: measure === null || measure === void 0 ? void 0 : measure.duration,
@@ -91,16 +91,21 @@ var Channel = /*#__PURE__*/function (_Emitter) {
91
91
  if (errorData) {
92
92
  var _this$socket;
93
93
  // We only want to refresh the token if only its invalid
94
+ // @ts-expect-error we should be more explicit about which type of errors we expect here, so they always have a status
94
95
  if ([401, 403].includes(errorData.status)) {
95
96
  //nullify token so it is forced to generate new token on reconnect
96
97
  _this.unsetToken();
97
98
  }
98
99
  (_this$socket = _this.socket) === null || _this$socket === void 0 ? void 0 : _this$socket.close();
99
100
  }
100
- _this.emit('error', {
101
- message: error.message,
102
- data: errorData
103
- });
101
+ var connectionError = {
102
+ message: (_message = error.message) !== null && _message !== void 0 ? _message : 'Connection error without message',
103
+ data: _objectSpread({
104
+ // @ts-expect-error I bet we'll see some connection errors, for the Socket IO errors
105
+ 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
106
+ }, errorData)
107
+ };
108
+ _this.emit('error', connectionError);
104
109
  });
105
110
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onReconnectError", function (error) {
106
111
  var _this$reconnectHelper, _this$reconnectHelper2;
@@ -108,13 +113,13 @@ var Channel = /*#__PURE__*/function (_Emitter) {
108
113
  if ((_this$reconnectHelper2 = _this.reconnectHelper) !== null && _this$reconnectHelper2 !== void 0 && _this$reconnectHelper2.isLikelyNetworkIssue()) {
109
114
  var _this$analyticsHelper4;
110
115
  (_this$analyticsHelper4 = _this.analyticsHelper) === null || _this$analyticsHelper4 === void 0 ? void 0 : _this$analyticsHelper4.sendErrorEvent(error, 'Likely network issue while reconnecting the channel');
111
- _this.emit('error', {
112
- message: 'Reconnection failed 8 times when browser was offline, likely there was a network issue.',
116
+ var reconnectionError = {
117
+ message: 'Reconnection failed 8 times when browser was offline, likely there was a network issue',
113
118
  data: {
114
- status: 400,
115
- code: 'RECONNECTION_NETWORK_ISSUE'
119
+ code: _errorTypes.INTERNAL_ERROR_CODE.RECONNECTION_NETWORK_ISSUE
116
120
  }
117
- });
121
+ };
122
+ _this.emit('error', reconnectionError);
118
123
  }
119
124
  });
120
125
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onConnect", function () {
@@ -176,6 +181,167 @@ var Channel = /*#__PURE__*/function (_Emitter) {
176
181
  _this.emit('steps:added', data);
177
182
  }
178
183
  });
184
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "fetchCatchup", /*#__PURE__*/function () {
185
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(fromVersion) {
186
+ var _ref2, _this$token, _yield$utils$requestS, doc, version, stepMaps, metadata, errorNotFound, errorCatchup;
187
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
188
+ while (1) {
189
+ switch (_context.prev = _context.next) {
190
+ case 0:
191
+ _context.prev = 0;
192
+ _context.t0 = _utilServiceSupport.utils;
193
+ _context.t1 = _this.config;
194
+ _context.t2 = "document/".concat(encodeURIComponent(_this.config.documentAri), "/catchup");
195
+ _context.t3 = {
196
+ version: fromVersion
197
+ };
198
+ _context.t4 = _objectSpread;
199
+ _context.t5 = _objectSpread;
200
+ _context.t6 = {};
201
+ if (!_this.config.permissionTokenRefresh) {
202
+ _context.next = 29;
203
+ break;
204
+ }
205
+ if (!((_this$token = _this.token) !== null && _this$token !== void 0)) {
206
+ _context.next = 13;
207
+ break;
208
+ }
209
+ _context.t9 = _this$token;
210
+ _context.next = 16;
211
+ break;
212
+ case 13:
213
+ _context.next = 15;
214
+ return _this.config.permissionTokenRefresh().then(function (token) {
215
+ if (token) {
216
+ _this.setToken(token);
217
+ }
218
+ return token;
219
+ });
220
+ case 15:
221
+ _context.t9 = _context.sent;
222
+ case 16:
223
+ _context.t10 = _ref2 = _context.t9;
224
+ _context.t8 = _context.t10 !== null;
225
+ if (!_context.t8) {
226
+ _context.next = 20;
227
+ break;
228
+ }
229
+ _context.t8 = _ref2 !== void 0;
230
+ case 20:
231
+ if (!_context.t8) {
232
+ _context.next = 24;
233
+ break;
234
+ }
235
+ _context.t11 = _ref2;
236
+ _context.next = 25;
237
+ break;
238
+ case 24:
239
+ _context.t11 = undefined;
240
+ case 25:
241
+ _context.t12 = _context.t11;
242
+ _context.t7 = {
243
+ 'x-token': _context.t12
244
+ };
245
+ _context.next = 30;
246
+ break;
247
+ case 29:
248
+ _context.t7 = {};
249
+ case 30:
250
+ _context.t13 = _context.t7;
251
+ _context.t14 = (0, _context.t5)(_context.t6, _context.t13);
252
+ _context.t15 = {};
253
+ _context.t16 = {
254
+ 'x-product': (0, _utils.getProduct)(_this.config.productInfo),
255
+ 'x-subproduct': (0, _utils.getSubProduct)(_this.config.productInfo)
256
+ };
257
+ _context.t17 = (0, _context.t4)(_context.t14, _context.t15, _context.t16);
258
+ _context.t18 = {
259
+ headers: _context.t17
260
+ };
261
+ _context.t19 = {
262
+ path: _context.t2,
263
+ queryParams: _context.t3,
264
+ requestInit: _context.t18
265
+ };
266
+ _context.next = 39;
267
+ return _context.t0.requestService.call(_context.t0, _context.t1, _context.t19);
268
+ case 39:
269
+ _yield$utils$requestS = _context.sent;
270
+ doc = _yield$utils$requestS.doc;
271
+ version = _yield$utils$requestS.version;
272
+ stepMaps = _yield$utils$requestS.stepMaps;
273
+ metadata = _yield$utils$requestS.metadata;
274
+ return _context.abrupt("return", {
275
+ doc: doc,
276
+ version: version,
277
+ stepMaps: stepMaps,
278
+ metadata: metadata
279
+ });
280
+ case 47:
281
+ _context.prev = 47;
282
+ _context.t20 = _context["catch"](0);
283
+ if (!(_context.t20.code === 404)) {
284
+ _context.next = 53;
285
+ break;
286
+ }
287
+ errorNotFound = {
288
+ message: 'The requested document is not found',
289
+ data: {
290
+ status: _context.t20.code,
291
+ code: _errorTypes.INTERNAL_ERROR_CODE.DOCUMENT_NOT_FOUND
292
+ }
293
+ };
294
+ _this.emit('error', errorNotFound);
295
+ return _context.abrupt("return", {});
296
+ case 53:
297
+ //nullify token so it is forced to generate new token on reconnect
298
+ _this.unsetToken();
299
+ logger("Can't fetch the catchup", _context.t20.message);
300
+ errorCatchup = {
301
+ message: 'Cannot fetch catchup from collab service',
302
+ data: {
303
+ status: _context.t20.status,
304
+ code: _errorTypes.INTERNAL_ERROR_CODE.CATCHUP_FAILED
305
+ }
306
+ };
307
+ _this.emit('error', errorCatchup);
308
+ throw _context.t20;
309
+ case 58:
310
+ case "end":
311
+ return _context.stop();
312
+ }
313
+ }
314
+ }, _callee, null, [[0, 47]]);
315
+ }));
316
+ return function (_x) {
317
+ return _ref.apply(this, arguments);
318
+ };
319
+ }());
320
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "broadcast", function (type, data, callback) {
321
+ if (!_this.socket) {
322
+ throw new _errorTypes.NotInitializedError('Cannot broadcast, not initialized yet');
323
+ }
324
+ if (!_this.connected) {
325
+ if (_this.config.throwOnNotConnected) {
326
+ throw new _errorTypes.NotConnectedError('Cannot broadcast, currently offline.');
327
+ }
328
+ return;
329
+ }
330
+ _this.socket.emit('broadcast', _objectSpread({
331
+ type: type
332
+ }, data), callback);
333
+ });
334
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "sendMetadata", function (metadata) {
335
+ if (!_this.socket) {
336
+ throw new _errorTypes.NotInitializedError('Cannot send metadata, not initialized yet');
337
+ }
338
+ if (!_this.connected) {
339
+ if (_this.config.throwOnNotConnected) {
340
+ throw new _errorTypes.NotConnectedError('Cannot send metadata, currently offline.');
341
+ }
342
+ }
343
+ _this.socket.emit('metadata', metadata);
344
+ });
179
345
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onOnlineHandler", function () {
180
346
  // Force an immediate reconnect, the socket must first be closed to reset reconnection delay logic
181
347
  if (!_this.connected) {
@@ -191,6 +357,8 @@ var Channel = /*#__PURE__*/function (_Emitter) {
191
357
  }
192
358
 
193
359
  // read-only getters used for tests
360
+
361
+ // sets the token as undefined
194
362
  (0, _createClass2.default)(Channel, [{
195
363
  key: "connect",
196
364
  value:
@@ -199,7 +367,13 @@ var Channel = /*#__PURE__*/function (_Emitter) {
199
367
  */
200
368
  function connect() {
201
369
  var _this2 = this;
370
+ var shouldInitialize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
202
371
  (0, _performance.startMeasure)(_performance.MEASURE_NAME.SOCKET_CONNECT, this.analyticsHelper);
372
+ // If provider already has access to the initial draft, explicitly set channel as initialized
373
+ // to bypass BE doc retrieval
374
+ if (shouldInitialize) {
375
+ this.initialized = true;
376
+ }
203
377
  if (!this.initialized) {
204
378
  var _this$initExperience2;
205
379
  (0, _performance.startMeasure)(_performance.MEASURE_NAME.DOCUMENT_INIT, this.analyticsHelper);
@@ -221,58 +395,62 @@ var Channel = /*#__PURE__*/function (_Emitter) {
221
395
  };
222
396
  if (permissionTokenRefresh) {
223
397
  auth = /*#__PURE__*/function () {
224
- var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(cb) {
225
- var token, newErr;
226
- return _regenerator.default.wrap(function _callee$(_context) {
398
+ var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(cb) {
399
+ var token, _err, _err$data, _err$data$meta, authenticationError;
400
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
227
401
  while (1) {
228
- switch (_context.prev = _context.next) {
402
+ switch (_context2.prev = _context2.next) {
229
403
  case 0:
230
404
  if (!(cacheToken && _this2.token)) {
231
- _context.next = 5;
405
+ _context2.next = 5;
232
406
  break;
233
407
  }
234
408
  authData.token = _this2.token;
235
409
  cb(authData);
236
- _context.next = 17;
410
+ _context2.next = 17;
237
411
  break;
238
412
  case 5:
239
- _context.prev = 5;
240
- _context.next = 8;
413
+ _context2.prev = 5;
414
+ _context2.next = 8;
241
415
  return permissionTokenRefresh();
242
416
  case 8:
243
- token = _context.sent;
417
+ token = _context2.sent;
244
418
  if (token) {
245
419
  // save token locally
246
420
  _this2.setToken(token);
247
421
  authData.token = token;
248
422
  }
249
423
  cb(authData);
250
- _context.next = 17;
424
+ _context2.next = 17;
251
425
  break;
252
426
  case 13:
253
- _context.prev = 13;
254
- _context.t0 = _context["catch"](5);
255
- newErr = {
256
- message: _context.t0.message ? _context.t0.message : 'Content not found',
427
+ _context2.prev = 13;
428
+ _context2.t0 = _context2["catch"](5);
429
+ // Pass the error back to the consumers so they can deal with exceptional cases themselves (eg. no permissions because the page was deleted)
430
+ authenticationError = {
431
+ message: 'Insufficient editing permissions',
257
432
  data: {
258
433
  status: 403,
259
- code: _context.t0.data.code ? _context.t0.data.code : 'INSUFFICIENT_EDITING_PERMISSION',
434
+ code: _errorTypes.INTERNAL_ERROR_CODE.TOKEN_PERMISSION_ERROR,
260
435
  meta: {
261
- description: _context.t0.data.meta.description ? _context.t0.data.meta.description : 'RESOURCE_DELETED',
262
- reason: _context.t0.data.meta.reason ? _context.t0.data.meta.reason : 'RESOURCE_DELETED'
436
+ originalError: _context2.t0,
437
+ // @ts-expect-error we know the error structure passed in this hack
438
+ 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
439
+ // https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/browse/next/packages/native-collab/src/fetchCollabPermissionToken.ts#37
263
440
  }
264
441
  }
265
442
  };
266
- _this2.emit('error', newErr);
443
+
444
+ _this2.emit('error', authenticationError);
267
445
  case 17:
268
446
  case "end":
269
- return _context.stop();
447
+ return _context2.stop();
270
448
  }
271
449
  }
272
- }, _callee, null, [[5, 13]]);
450
+ }, _callee2, null, [[5, 13]]);
273
451
  }));
274
- return function auth(_x) {
275
- return _ref.apply(this, arguments);
452
+ return function auth(_x2) {
453
+ return _ref3.apply(this, arguments);
276
454
  };
277
455
  }();
278
456
  } else {
@@ -300,11 +478,11 @@ var Channel = /*#__PURE__*/function (_Emitter) {
300
478
  this.socket.on('participant:left', function (data) {
301
479
  _this2.emit('participant:left', data);
302
480
  });
303
- this.socket.on('participant:updated', function (_ref2) {
304
- var sessionId = _ref2.sessionId,
305
- timestamp = _ref2.timestamp,
306
- data = _ref2.data,
307
- clientId = _ref2.clientId;
481
+ this.socket.on('participant:updated', function (_ref4) {
482
+ var sessionId = _ref4.sessionId,
483
+ timestamp = _ref4.timestamp,
484
+ data = _ref4.data,
485
+ clientId = _ref4.clientId;
308
486
  _this2.emit('participant:updated', _objectSpread({
309
487
  sessionId: sessionId,
310
488
  timestamp: timestamp,
@@ -320,11 +498,11 @@ var Channel = /*#__PURE__*/function (_Emitter) {
320
498
  _this2.emit('status', data);
321
499
  });
322
500
  this.socket.on('disconnect', /*#__PURE__*/function () {
323
- var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(reason) {
324
- var _this2$analyticsHelpe;
325
- return _regenerator.default.wrap(function _callee2$(_context2) {
501
+ var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(reason) {
502
+ var _this2$analyticsHelpe, reconnectionError;
503
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
326
504
  while (1) {
327
- switch (_context2.prev = _context2.next) {
505
+ switch (_context3.prev = _context3.next) {
328
506
  case 0:
329
507
  _this2.connected = false;
330
508
  logger("disconnect reason: ".concat(reason));
@@ -337,30 +515,31 @@ var Channel = /*#__PURE__*/function (_Emitter) {
337
515
  _this2.socket.connect();
338
516
  } catch (error) {
339
517
  (_this2$analyticsHelpe = _this2.analyticsHelper) === null || _this2$analyticsHelpe === void 0 ? void 0 : _this2$analyticsHelpe.sendErrorEvent(error, 'Error while reconnecting the channel');
340
- _this2.emit('error', {
341
- message: 'Caught error during reconnection.',
518
+ reconnectionError = {
519
+ message: 'Caught error during reconnection',
342
520
  data: {
343
521
  status: 500,
344
- code: 'RECONNECTION_ERROR'
522
+ code: _errorTypes.INTERNAL_ERROR_CODE.RECONNECTION_ERROR
345
523
  }
346
- });
524
+ };
525
+ _this2.emit('error', reconnectionError);
347
526
  }
348
527
  }
349
528
  case 4:
350
529
  case "end":
351
- return _context2.stop();
530
+ return _context3.stop();
352
531
  }
353
532
  }
354
- }, _callee2);
533
+ }, _callee3);
355
534
  }));
356
- return function (_x2) {
357
- return _ref3.apply(this, arguments);
535
+ return function (_x3) {
536
+ return _ref5.apply(this, arguments);
358
537
  };
359
538
  }());
360
539
 
361
540
  // Socket error, including errors from `packetMiddleware`, `controllers` and `onconnect` and more. Parameter is a plain JSON object.
362
- this.socket.on('error', function (error) {
363
- _this2.emit('error', error);
541
+ this.socket.on('error', function (socketError) {
542
+ _this2.emit('error', socketError);
364
543
  });
365
544
 
366
545
  // `connect_error`'s parameter type is `Error`.
@@ -380,178 +559,18 @@ var Channel = /*#__PURE__*/function (_Emitter) {
380
559
  // Fired upon a reconnection attempt error (from Socket.IO Manager)
381
560
  this.socket.io.on('reconnect_error', this.onReconnectError);
382
561
  }
383
- }, {
384
- key: "fetchCatchup",
385
- value: function () {
386
- var _fetchCatchup = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(fromVersion) {
387
- var _this3 = this;
388
- var _ref4, _this$token, _yield$utils$requestS, doc, version, stepMaps, metadata, errorNotFound, errorCatchup;
389
- return _regenerator.default.wrap(function _callee3$(_context3) {
390
- while (1) {
391
- switch (_context3.prev = _context3.next) {
392
- case 0:
393
- _context3.prev = 0;
394
- _context3.t0 = _utilServiceSupport.utils;
395
- _context3.t1 = this.config;
396
- _context3.t2 = "document/".concat(encodeURIComponent(this.config.documentAri), "/catchup");
397
- _context3.t3 = {
398
- version: fromVersion
399
- };
400
- _context3.t4 = _objectSpread;
401
- _context3.t5 = _objectSpread;
402
- _context3.t6 = {};
403
- if (!this.config.permissionTokenRefresh) {
404
- _context3.next = 29;
405
- break;
406
- }
407
- if (!((_this$token = this.token) !== null && _this$token !== void 0)) {
408
- _context3.next = 13;
409
- break;
410
- }
411
- _context3.t9 = _this$token;
412
- _context3.next = 16;
413
- break;
414
- case 13:
415
- _context3.next = 15;
416
- return this.config.permissionTokenRefresh().then(function (token) {
417
- if (token) {
418
- _this3.setToken(token);
419
- }
420
- return token;
421
- });
422
- case 15:
423
- _context3.t9 = _context3.sent;
424
- case 16:
425
- _context3.t10 = _ref4 = _context3.t9;
426
- _context3.t8 = _context3.t10 !== null;
427
- if (!_context3.t8) {
428
- _context3.next = 20;
429
- break;
430
- }
431
- _context3.t8 = _ref4 !== void 0;
432
- case 20:
433
- if (!_context3.t8) {
434
- _context3.next = 24;
435
- break;
436
- }
437
- _context3.t11 = _ref4;
438
- _context3.next = 25;
439
- break;
440
- case 24:
441
- _context3.t11 = undefined;
442
- case 25:
443
- _context3.t12 = _context3.t11;
444
- _context3.t7 = {
445
- 'x-token': _context3.t12
446
- };
447
- _context3.next = 30;
448
- break;
449
- case 29:
450
- _context3.t7 = {};
451
- case 30:
452
- _context3.t13 = _context3.t7;
453
- _context3.t14 = (0, _context3.t5)(_context3.t6, _context3.t13);
454
- _context3.t15 = {};
455
- _context3.t16 = {
456
- 'x-product': (0, _utils.getProduct)(this.config.productInfo),
457
- 'x-subproduct': (0, _utils.getSubProduct)(this.config.productInfo)
458
- };
459
- _context3.t17 = (0, _context3.t4)(_context3.t14, _context3.t15, _context3.t16);
460
- _context3.t18 = {
461
- headers: _context3.t17
462
- };
463
- _context3.t19 = {
464
- path: _context3.t2,
465
- queryParams: _context3.t3,
466
- requestInit: _context3.t18
467
- };
468
- _context3.next = 39;
469
- return _context3.t0.requestService.call(_context3.t0, _context3.t1, _context3.t19);
470
- case 39:
471
- _yield$utils$requestS = _context3.sent;
472
- doc = _yield$utils$requestS.doc;
473
- version = _yield$utils$requestS.version;
474
- stepMaps = _yield$utils$requestS.stepMaps;
475
- metadata = _yield$utils$requestS.metadata;
476
- return _context3.abrupt("return", {
477
- doc: doc,
478
- version: version,
479
- stepMaps: stepMaps,
480
- metadata: metadata
481
- });
482
- case 47:
483
- _context3.prev = 47;
484
- _context3.t20 = _context3["catch"](0);
485
- if (!(_context3.t20.code === 404)) {
486
- _context3.next = 53;
487
- break;
488
- }
489
- errorNotFound = {
490
- message: _errorCodeMapper.ErrorCodeMapper.documentNotFound.message,
491
- data: {
492
- status: _context3.t20.code,
493
- code: _errorCodeMapper.ErrorCodeMapper.documentNotFound.code
494
- }
495
- };
496
- this.emit('error', errorNotFound);
497
- return _context3.abrupt("return", {});
498
- case 53:
499
- //nullify token so it is forced to generate new token on reconnect
500
- this.unsetToken();
501
- logger("Can't fetch the catchup", _context3.t20.message);
502
- errorCatchup = {
503
- message: _errorCodeMapper.ErrorCodeMapper.catchupFail.message,
504
- data: {
505
- status: _context3.t20.status,
506
- code: _errorCodeMapper.ErrorCodeMapper.catchupFail.code
507
- }
508
- };
509
- this.emit('error', errorCatchup);
510
- throw _context3.t20;
511
- case 58:
512
- case "end":
513
- return _context3.stop();
514
- }
515
- }
516
- }, _callee3, this, [[0, 47]]);
517
- }));
518
- function fetchCatchup(_x3) {
519
- return _fetchCatchup.apply(this, arguments);
520
- }
521
- return fetchCatchup;
522
- }()
562
+
523
563
  /**
524
- * Send message to service. Timestamp will be added server side.
564
+ * Send message to the back-end service over the channel. Timestamp will be added server side.
565
+ * @throws {NotInitializedError} Channel not initialized
566
+ * @throws {NotConnectedError} Channel not connected
567
+ */
568
+
569
+ /**
570
+ * Send metadata to to the back-end service over the channel
571
+ * @throws {NotInitializedError} Channel not initialized
572
+ * @throws {NotConnectedError} Channel not connected
525
573
  */
526
- }, {
527
- key: "broadcast",
528
- value: function broadcast(type, data, callback) {
529
- if (!this.socket) {
530
- throw new _errorTypes.NotInitializedError('Cannot broadcast, not initialized yet');
531
- }
532
- if (!this.connected) {
533
- if (this.config.throwOnNotConnected) {
534
- throw new _errorTypes.NotConnectedError('Cannot broadcast, currently offline.');
535
- }
536
- return;
537
- }
538
- this.socket.emit('broadcast', _objectSpread({
539
- type: type
540
- }, data), callback);
541
- }
542
- }, {
543
- key: "sendMetadata",
544
- value: function sendMetadata(metadata) {
545
- if (!this.socket) {
546
- throw new _errorTypes.NotInitializedError('Cannot send metadata, not initialized yet');
547
- }
548
- if (!this.connected) {
549
- if (this.config.throwOnNotConnected) {
550
- throw new _errorTypes.NotConnectedError('Cannot send metadata, currently offline.');
551
- }
552
- }
553
- this.socket.emit('metadata', metadata);
554
- }
555
574
  }, {
556
575
  key: "sendPresenceJoined",
557
576
  value: function sendPresenceJoined() {