@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
@@ -0,0 +1,579 @@
1
+ import _typeof from "@babel/runtime/helpers/typeof";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
4
+ import _createClass from "@babel/runtime/helpers/createClass";
5
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
6
+ 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; }
7
+ 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) { _defineProperty(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; }
8
+ 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; }
9
+ import { ACK_MAX_TRY, EVENT_ACTION, EVENT_STATUS } from '../helpers/const';
10
+ import { getVersion, sendableSteps } from '@atlaskit/prosemirror-collab';
11
+ import { createLogger, sleep } from '../helpers/utils';
12
+ import throttle from 'lodash/throttle';
13
+ import { throttledCommitStep } from '../provider/commit-step';
14
+ import { MEASURE_NAME, startMeasure, stopMeasure } from '../analytics/performance';
15
+ import { JSONTransformer } from '@atlaskit/editor-json-transformer';
16
+ import { MAX_STEP_REJECTED_ERROR } from '../provider';
17
+ import { catchup } from './catchup';
18
+ import { StepQueueState } from './step-queue-state';
19
+ import { INTERNAL_ERROR_CODE } from '../errors/error-types';
20
+ var CATCHUP_THROTTLE = 1 * 1000; // 1 second
21
+
22
+ var noop = function noop() {};
23
+ var logger = createLogger('documentService', 'black');
24
+ export var DocumentService = /*#__PURE__*/function () {
25
+ // Fires analytics to editor when collab editor cannot sync up
26
+
27
+ // ClientID is the unique ID for a prosemirror client. Used for step-rebasing.
28
+
29
+ /**
30
+ *
31
+ * @param participantsService - The participants service, used when users are detected active when making changes to the document
32
+ * and to emit their telepointers from steps they add
33
+ * @param analyticsHelper - Helper for analytics events
34
+ * @param fetchCatchup - Function to fetch "catchup" data, data required to rebase current steps to the latest version.
35
+ * @param providerEmitCallback - Callback for emitting events to listeners on the provider
36
+ * @param broadcastMetadata - Callback for broadcasting metadata changes to other clients
37
+ * @param broadcast - Callback for broadcasting events to other clients
38
+ * @param getUserId - Callback to fetch the current user's ID
39
+ * @param onErrorHandled - Callback to handle
40
+ */
41
+ function DocumentService(participantsService, analyticsHelper, fetchCatchup, providerEmitCallback, broadcast, getUserId, onErrorHandled, metadataService) {
42
+ var _this = this;
43
+ _classCallCheck(this, DocumentService);
44
+ _defineProperty(this, "stepRejectCounter", 0);
45
+ _defineProperty(this, "throttledCatchup", throttle(function () {
46
+ return _this.catchup();
47
+ }, CATCHUP_THROTTLE, {
48
+ leading: false,
49
+ // TODO: why shouldn't this be leading?
50
+ trailing: true
51
+ }));
52
+ _defineProperty(this, "catchup", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
53
+ var start, _this$analyticsHelper, latency, _this$analyticsHelper2, _this$analyticsHelper3, _latency;
54
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
55
+ while (1) {
56
+ switch (_context.prev = _context.next) {
57
+ case 0:
58
+ start = new Date().getTime(); // if the queue is already paused, we are busy with something else, so don't proceed.
59
+ if (!_this.stepQueue.isPaused()) {
60
+ _context.next = 4;
61
+ break;
62
+ }
63
+ logger("Queue is paused. Aborting.");
64
+ return _context.abrupt("return");
65
+ case 4:
66
+ _this.stepQueue.pauseQueue();
67
+ _context.prev = 5;
68
+ _context.next = 8;
69
+ return catchup({
70
+ getCurrentPmVersion: _this.getCurrentPmVersion,
71
+ fetchCatchup: _this.fetchCatchup,
72
+ getUnconfirmedSteps: _this.getUnconfirmedSteps,
73
+ filterQueue: _this.stepQueue.filterQueue,
74
+ applyLocalSteps: _this.applyLocalSteps,
75
+ updateDocument: _this.updateDocument,
76
+ updateMetadata: _this.metadataService.updateMetadata
77
+ });
78
+ case 8:
79
+ latency = new Date().getTime() - start;
80
+ (_this$analyticsHelper = _this.analyticsHelper) === null || _this$analyticsHelper === void 0 ? void 0 : _this$analyticsHelper.sendActionEvent(EVENT_ACTION.CATCHUP, EVENT_STATUS.SUCCESS, {
81
+ latency: latency
82
+ });
83
+ _context.next = 18;
84
+ break;
85
+ case 12:
86
+ _context.prev = 12;
87
+ _context.t0 = _context["catch"](5);
88
+ _latency = new Date().getTime() - start;
89
+ (_this$analyticsHelper2 = _this.analyticsHelper) === null || _this$analyticsHelper2 === void 0 ? void 0 : _this$analyticsHelper2.sendActionEvent(EVENT_ACTION.CATCHUP, EVENT_STATUS.FAILURE, {
90
+ latency: _latency
91
+ });
92
+ (_this$analyticsHelper3 = _this.analyticsHelper) === null || _this$analyticsHelper3 === void 0 ? void 0 : _this$analyticsHelper3.sendErrorEvent(_context.t0, 'Error while catching up');
93
+ logger("Catch-Up Failed:", _context.t0.message);
94
+ case 18:
95
+ _context.prev = 18;
96
+ _this.stepQueue.resumeQueue();
97
+ _this.processQueue();
98
+ _this.sendStepsFromCurrentState(); // this will eventually retry catchup as it calls commitStep which will either catchup on onStepsAdded or onErrorHandled
99
+ _this.stepRejectCounter = 0;
100
+ return _context.finish(18);
101
+ case 24:
102
+ case "end":
103
+ return _context.stop();
104
+ }
105
+ }
106
+ }, _callee, null, [[5, 12, 18, 24]]);
107
+ })));
108
+ _defineProperty(this, "getCurrentPmVersion", function () {
109
+ var _this$getState;
110
+ var state = (_this$getState = _this.getState) === null || _this$getState === void 0 ? void 0 : _this$getState.call(_this);
111
+ if (!state) {
112
+ var _this$analyticsHelper4;
113
+ (_this$analyticsHelper4 = _this.analyticsHelper) === null || _this$analyticsHelper4 === void 0 ? void 0 : _this$analyticsHelper4.sendErrorEvent(new Error('No editor state when calling ProseMirror function'), 'getCurrentPmVersion called without state');
114
+ return 0;
115
+ }
116
+ return getVersion(state);
117
+ });
118
+ _defineProperty(this, "getCurrentState", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
119
+ var _this$analyticsHelper5, state, adfDocument, currentState, measure, _this$analyticsHelper6, _this$analyticsHelper7, _measure;
120
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
121
+ while (1) {
122
+ switch (_context2.prev = _context2.next) {
123
+ case 0:
124
+ _context2.prev = 0;
125
+ startMeasure(MEASURE_NAME.GET_CURRENT_STATE, _this.analyticsHelper);
126
+
127
+ // Convert ProseMirror document in Editor state to ADF document
128
+ state = _this.getState();
129
+ adfDocument = new JSONTransformer().encode(state.doc);
130
+ currentState = {
131
+ content: adfDocument,
132
+ title: _this.metadataService.getTitle(),
133
+ stepVersion: getVersion(state)
134
+ };
135
+ measure = stopMeasure(MEASURE_NAME.GET_CURRENT_STATE, _this.analyticsHelper);
136
+ (_this$analyticsHelper5 = _this.analyticsHelper) === null || _this$analyticsHelper5 === void 0 ? void 0 : _this$analyticsHelper5.sendActionEvent(EVENT_ACTION.GET_CURRENT_STATE, EVENT_STATUS.SUCCESS, {
137
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration
138
+ });
139
+ return _context2.abrupt("return", currentState);
140
+ case 10:
141
+ _context2.prev = 10;
142
+ _context2.t0 = _context2["catch"](0);
143
+ _measure = stopMeasure(MEASURE_NAME.GET_CURRENT_STATE, _this.analyticsHelper);
144
+ (_this$analyticsHelper6 = _this.analyticsHelper) === null || _this$analyticsHelper6 === void 0 ? void 0 : _this$analyticsHelper6.sendActionEvent(EVENT_ACTION.GET_CURRENT_STATE, EVENT_STATUS.FAILURE, {
145
+ latency: _measure === null || _measure === void 0 ? void 0 : _measure.duration
146
+ });
147
+ (_this$analyticsHelper7 = _this.analyticsHelper) === null || _this$analyticsHelper7 === void 0 ? void 0 : _this$analyticsHelper7.sendErrorEvent(_context2.t0, 'Error while returning ADF version of current draft document');
148
+ throw _context2.t0;
149
+ case 16:
150
+ case "end":
151
+ return _context2.stop();
152
+ }
153
+ }
154
+ }, _callee2, null, [[0, 10]]);
155
+ })));
156
+ _defineProperty(this, "getUnconfirmedStepsOrigins", function () {
157
+ var _this$getState2, _sendableSteps;
158
+ var state = (_this$getState2 = _this.getState) === null || _this$getState2 === void 0 ? void 0 : _this$getState2.call(_this);
159
+ if (!state) {
160
+ var _this$analyticsHelper8;
161
+ (_this$analyticsHelper8 = _this.analyticsHelper) === null || _this$analyticsHelper8 === void 0 ? void 0 : _this$analyticsHelper8.sendErrorEvent(new Error('No editor state when calling ProseMirror function'), 'getUnconfirmedStepsOrigins called without state');
162
+ return;
163
+ }
164
+ return (_sendableSteps = sendableSteps(state)) === null || _sendableSteps === void 0 ? void 0 : _sendableSteps.origins;
165
+ });
166
+ _defineProperty(this, "getUnconfirmedSteps", function () {
167
+ var _this$getState3, _sendableSteps2;
168
+ var state = (_this$getState3 = _this.getState) === null || _this$getState3 === void 0 ? void 0 : _this$getState3.call(_this);
169
+ if (!state) {
170
+ var _this$analyticsHelper9;
171
+ (_this$analyticsHelper9 = _this.analyticsHelper) === null || _this$analyticsHelper9 === void 0 ? void 0 : _this$analyticsHelper9.sendErrorEvent(new Error('No editor state when calling ProseMirror function'), 'getUnconfirmedSteps called without state');
172
+ return;
173
+ }
174
+ return (_sendableSteps2 = sendableSteps(state)) === null || _sendableSteps2 === void 0 ? void 0 : _sendableSteps2.steps;
175
+ });
176
+ _defineProperty(this, "applyLocalSteps", function (steps) {
177
+ // Re-apply local steps
178
+ _this.providerEmitCallback('local-steps', {
179
+ steps: steps
180
+ });
181
+ });
182
+ _defineProperty(this, "onStepsAdded", function (data) {
183
+ logger("Received steps", {
184
+ steps: data.steps,
185
+ version: data.version
186
+ });
187
+ if (!data.steps) {
188
+ logger("No steps.. waiting..");
189
+ return;
190
+ }
191
+ try {
192
+ var currentVersion = _this.getCurrentPmVersion();
193
+ var expectedVersion = currentVersion + data.steps.length;
194
+ if (data.version <= currentVersion) {
195
+ logger("Received steps we already have. Ignoring.");
196
+ } else if (data.version === expectedVersion) {
197
+ _this.processSteps(data);
198
+ } else if (data.version > expectedVersion) {
199
+ logger("Version too high. Expected \"".concat(expectedVersion, "\" but got \"").concat(data.version, ". Current local version is ").concat(currentVersion, "."));
200
+ _this.stepQueue.queueSteps(data);
201
+ _this.throttledCatchup();
202
+ }
203
+ _this.participantsService.updateLastActive(data.steps.map(function (_ref3) {
204
+ var userId = _ref3.userId;
205
+ return userId;
206
+ }));
207
+ } catch (stepsAddedError) {
208
+ var _this$analyticsHelper10;
209
+ (_this$analyticsHelper10 = _this.analyticsHelper) === null || _this$analyticsHelper10 === void 0 ? void 0 : _this$analyticsHelper10.sendErrorEvent(stepsAddedError, 'Error while adding steps in the provider');
210
+ _this.onErrorHandled({
211
+ message: 'Error while adding steps in the provider',
212
+ data: {
213
+ status: 500,
214
+ // Meaningless, remove when we review error structure
215
+ code: INTERNAL_ERROR_CODE.ADD_STEPS_ERROR
216
+ }
217
+ });
218
+ }
219
+ });
220
+ _defineProperty(this, "onRestore", function (_ref4) {
221
+ var doc = _ref4.doc,
222
+ version = _ref4.version,
223
+ metadata = _ref4.metadata;
224
+ // Preserve the unconfirmed steps to prevent data loss.
225
+ var unconfirmedSteps = _this.getUnconfirmedSteps();
226
+ try {
227
+ var _this$analyticsHelper11;
228
+ // Reset the editor,
229
+ // - Replace the document, keep in sync with the server
230
+ // - Replace the version number, so editor is in sync with NCS server and can commit new changes.
231
+ // - Replace the metadata
232
+ // - Reserve the cursor position, in case a cursor jump.
233
+
234
+ _this.updateDocument({
235
+ doc: doc,
236
+ version: version,
237
+ metadata: metadata,
238
+ reserveCursor: true
239
+ });
240
+ _this.metadataService.updateMetadata(metadata);
241
+
242
+ // Re-apply the unconfirmed steps, not 100% of them can be applied, if document is changed significantly.
243
+ if (unconfirmedSteps !== null && unconfirmedSteps !== void 0 && unconfirmedSteps.length) {
244
+ _this.applyLocalSteps(unconfirmedSteps);
245
+ }
246
+ (_this$analyticsHelper11 = _this.analyticsHelper) === null || _this$analyticsHelper11 === void 0 ? void 0 : _this$analyticsHelper11.sendActionEvent(EVENT_ACTION.REINITIALISE_DOCUMENT, EVENT_STATUS.SUCCESS, {
247
+ numUnconfirmedSteps: unconfirmedSteps === null || unconfirmedSteps === void 0 ? void 0 : unconfirmedSteps.length
248
+ });
249
+ } catch (restoreError) {
250
+ var _this$analyticsHelper12, _this$analyticsHelper13;
251
+ (_this$analyticsHelper12 = _this.analyticsHelper) === null || _this$analyticsHelper12 === void 0 ? void 0 : _this$analyticsHelper12.sendActionEvent(EVENT_ACTION.REINITIALISE_DOCUMENT, EVENT_STATUS.FAILURE, {
252
+ numUnconfirmedSteps: unconfirmedSteps === null || unconfirmedSteps === void 0 ? void 0 : unconfirmedSteps.length
253
+ });
254
+ (_this$analyticsHelper13 = _this.analyticsHelper) === null || _this$analyticsHelper13 === void 0 ? void 0 : _this$analyticsHelper13.sendErrorEvent(restoreError, 'Error while reinitialising document');
255
+ _this.onErrorHandled({
256
+ message: 'Caught error while trying to recover the document',
257
+ data: {
258
+ status: 500,
259
+ // Meaningless, remove when we review error structure
260
+ code: INTERNAL_ERROR_CODE.DOCUMENT_RESTORE_ERROR
261
+ }
262
+ });
263
+ }
264
+ });
265
+ _defineProperty(this, "getFinalAcknowledgedState", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
266
+ var _this$analyticsHelper14, currentState, measure, _this$analyticsHelper15, _this$analyticsHelper16, _measure2;
267
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
268
+ while (1) {
269
+ switch (_context3.prev = _context3.next) {
270
+ case 0:
271
+ _context3.prev = 0;
272
+ startMeasure(MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
273
+ _context3.next = 4;
274
+ return _this.commitUnconfirmedSteps();
275
+ case 4:
276
+ _context3.next = 6;
277
+ return _this.getCurrentState();
278
+ case 6:
279
+ currentState = _context3.sent;
280
+ measure = stopMeasure(MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
281
+ (_this$analyticsHelper14 = _this.analyticsHelper) === null || _this$analyticsHelper14 === void 0 ? void 0 : _this$analyticsHelper14.sendActionEvent(EVENT_ACTION.PUBLISH_PAGE, EVENT_STATUS.SUCCESS, {
282
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration
283
+ });
284
+ return _context3.abrupt("return", currentState);
285
+ case 12:
286
+ _context3.prev = 12;
287
+ _context3.t0 = _context3["catch"](0);
288
+ _measure2 = stopMeasure(MEASURE_NAME.PUBLISH_PAGE, _this.analyticsHelper);
289
+ (_this$analyticsHelper15 = _this.analyticsHelper) === null || _this$analyticsHelper15 === void 0 ? void 0 : _this$analyticsHelper15.sendActionEvent(EVENT_ACTION.PUBLISH_PAGE, EVENT_STATUS.FAILURE, {
290
+ latency: _measure2 === null || _measure2 === void 0 ? void 0 : _measure2.duration
291
+ });
292
+ (_this$analyticsHelper16 = _this.analyticsHelper) === null || _this$analyticsHelper16 === void 0 ? void 0 : _this$analyticsHelper16.sendErrorEvent(_context3.t0, 'Error while returning ADF version of the final draft document');
293
+ throw _context3.t0;
294
+ case 18:
295
+ case "end":
296
+ return _context3.stop();
297
+ }
298
+ }
299
+ }, _callee3, null, [[0, 12]]);
300
+ })));
301
+ _defineProperty(this, "updateDocument", function (_ref6) {
302
+ var doc = _ref6.doc,
303
+ version = _ref6.version,
304
+ metadata = _ref6.metadata,
305
+ reserveCursor = _ref6.reserveCursor;
306
+ _this.providerEmitCallback('init', _objectSpread({
307
+ doc: doc,
308
+ version: version,
309
+ metadata: metadata
310
+ }, reserveCursor ? {
311
+ reserveCursor: reserveCursor
312
+ } : {}));
313
+ });
314
+ _defineProperty(this, "commitUnconfirmedSteps", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
315
+ var unconfirmedSteps, _this$analyticsHelper18, _this$analyticsHelper19, measure;
316
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
317
+ while (1) {
318
+ switch (_context5.prev = _context5.next) {
319
+ case 0:
320
+ unconfirmedSteps = _this.getUnconfirmedSteps();
321
+ _context5.prev = 1;
322
+ if (!(unconfirmedSteps !== null && unconfirmedSteps !== void 0 && unconfirmedSteps.length)) {
323
+ _context5.next = 4;
324
+ break;
325
+ }
326
+ return _context5.delegateYield( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
327
+ var _this$analyticsHelper17;
328
+ var count, unconfirmedTrs, lastTr, isLastTrConfirmed, nextUnconfirmedSteps, nextUnconfirmedTrs, state, measure;
329
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
330
+ while (1) {
331
+ switch (_context4.prev = _context4.next) {
332
+ case 0:
333
+ startMeasure(MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, _this.analyticsHelper);
334
+ count = 0; // We use origins here as steps can be rebased. When steps are rebased a new step is created.
335
+ // This means that we can not track if it has been removed from the unconfirmed array or not.
336
+ // Origins points to the original transaction that the step was created in. This is never changed
337
+ // and gets passed down when a step is rebased.
338
+ unconfirmedTrs = _this.getUnconfirmedStepsOrigins();
339
+ lastTr = unconfirmedTrs === null || unconfirmedTrs === void 0 ? void 0 : unconfirmedTrs[unconfirmedTrs.length - 1];
340
+ isLastTrConfirmed = false;
341
+ case 5:
342
+ if (isLastTrConfirmed) {
343
+ _context4.next = 16;
344
+ break;
345
+ }
346
+ _this.sendStepsFromCurrentState();
347
+ _context4.next = 9;
348
+ return sleep(1000);
349
+ case 9:
350
+ nextUnconfirmedSteps = _this.getUnconfirmedSteps();
351
+ if (nextUnconfirmedSteps !== null && nextUnconfirmedSteps !== void 0 && nextUnconfirmedSteps.length) {
352
+ nextUnconfirmedTrs = _this.getUnconfirmedStepsOrigins();
353
+ isLastTrConfirmed = !(nextUnconfirmedTrs !== null && nextUnconfirmedTrs !== void 0 && nextUnconfirmedTrs.some(function (tr) {
354
+ return tr === lastTr;
355
+ }));
356
+ } else {
357
+ isLastTrConfirmed = true;
358
+ }
359
+ if (!(!isLastTrConfirmed && count++ >= ACK_MAX_TRY)) {
360
+ _context4.next = 14;
361
+ break;
362
+ }
363
+ if (_this.onSyncUpError) {
364
+ state = _this.getState();
365
+ _this.onSyncUpError({
366
+ lengthOfUnconfirmedSteps: nextUnconfirmedSteps === null || nextUnconfirmedSteps === void 0 ? void 0 : nextUnconfirmedSteps.length,
367
+ tries: count,
368
+ maxRetries: ACK_MAX_TRY,
369
+ clientId: _this.clientId,
370
+ version: getVersion(state)
371
+ });
372
+ }
373
+ throw new Error("Can't sync up with Collab Service");
374
+ case 14:
375
+ _context4.next = 5;
376
+ break;
377
+ case 16:
378
+ measure = stopMeasure(MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, _this.analyticsHelper);
379
+ (_this$analyticsHelper17 = _this.analyticsHelper) === null || _this$analyticsHelper17 === void 0 ? void 0 : _this$analyticsHelper17.sendActionEvent(EVENT_ACTION.COMMIT_UNCONFIRMED_STEPS, EVENT_STATUS.SUCCESS, {
380
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration,
381
+ // upon success, emit the total number of unconfirmed steps we synced
382
+ numUnconfirmedSteps: unconfirmedSteps === null || unconfirmedSteps === void 0 ? void 0 : unconfirmedSteps.length
383
+ });
384
+ case 18:
385
+ case "end":
386
+ return _context4.stop();
387
+ }
388
+ }
389
+ }, _callee4);
390
+ })(), "t0", 4);
391
+ case 4:
392
+ _context5.next = 12;
393
+ break;
394
+ case 6:
395
+ _context5.prev = 6;
396
+ _context5.t1 = _context5["catch"](1);
397
+ measure = stopMeasure(MEASURE_NAME.COMMIT_UNCONFIRMED_STEPS, _this.analyticsHelper);
398
+ (_this$analyticsHelper18 = _this.analyticsHelper) === null || _this$analyticsHelper18 === void 0 ? void 0 : _this$analyticsHelper18.sendActionEvent(EVENT_ACTION.COMMIT_UNCONFIRMED_STEPS, EVENT_STATUS.FAILURE, {
399
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration,
400
+ numUnconfirmedSteps: unconfirmedSteps === null || unconfirmedSteps === void 0 ? void 0 : unconfirmedSteps.length
401
+ });
402
+ (_this$analyticsHelper19 = _this.analyticsHelper) === null || _this$analyticsHelper19 === void 0 ? void 0 : _this$analyticsHelper19.sendErrorEvent(_context5.t1, 'Error while committing unconfirmed steps');
403
+ throw _context5.t1;
404
+ case 12:
405
+ case "end":
406
+ return _context5.stop();
407
+ }
408
+ }
409
+ }, _callee5, null, [[1, 6]]);
410
+ })));
411
+ _defineProperty(this, "onStepRejectedError", function () {
412
+ _this.stepRejectCounter++;
413
+ logger("Steps rejected (tries=".concat(_this.stepRejectCounter, ")"));
414
+ if (_this.stepRejectCounter >= MAX_STEP_REJECTED_ERROR) {
415
+ logger("The steps were rejected too many times (tries=".concat(_this.stepRejectCounter, ", limit=").concat(MAX_STEP_REJECTED_ERROR, "). Trying to catch-up."));
416
+ _this.throttledCatchup();
417
+ } else {
418
+ // If committing steps failed try again automatically in 1s
419
+ // This makes it more likely that unconfirmed steps trigger a catch-up
420
+ // within 15s even if there is no one editing actively (or draft sync polling)
421
+ // reducing the risk of data loss at the expense of step commits
422
+ setTimeout(function () {
423
+ return _this.sendStepsFromCurrentState();
424
+ }, 1000);
425
+ }
426
+ });
427
+ this.participantsService = participantsService;
428
+ this.analyticsHelper = analyticsHelper;
429
+ this.fetchCatchup = fetchCatchup;
430
+ this.providerEmitCallback = providerEmitCallback;
431
+ this.broadcast = broadcast;
432
+ this.getUserId = getUserId;
433
+ this.onErrorHandled = onErrorHandled;
434
+ this.metadataService = metadataService;
435
+ this.stepQueue = new StepQueueState();
436
+ }
437
+
438
+ /**
439
+ * To prevent calling catchup to often, use lodash throttle to reduce the frequency
440
+ */
441
+
442
+ /**
443
+ * Called when:
444
+ * * session established(offline -> online)
445
+ * * try to accept steps but version is behind.
446
+ */
447
+ _createClass(DocumentService, [{
448
+ key: "processQueue",
449
+ value: function processQueue() {
450
+ if (this.stepQueue.isPaused()) {
451
+ logger("Queue is paused. Aborting.");
452
+ return;
453
+ }
454
+ logger("Looking for processable data.");
455
+ if (this.stepQueue.getQueue().length > 0) {
456
+ var firstItem = this.stepQueue.shift();
457
+ var currentVersion = this.getCurrentPmVersion();
458
+ var expectedVersion = currentVersion + firstItem.steps.length;
459
+ if (firstItem.version === expectedVersion) {
460
+ logger("Applying data from queue!");
461
+ this.processSteps(firstItem);
462
+ // recur
463
+ this.processQueue();
464
+ }
465
+ }
466
+ }
467
+ }, {
468
+ key: "processSteps",
469
+ value: function processSteps(data) {
470
+ var _this2 = this;
471
+ var version = data.version,
472
+ steps = data.steps;
473
+ logger("Processing data. Version \"".concat(version, "\"."));
474
+ if (steps !== null && steps !== void 0 && steps.length) {
475
+ try {
476
+ var clientIds = steps.map(function (_ref8) {
477
+ var clientId = _ref8.clientId;
478
+ return clientId;
479
+ });
480
+ this.providerEmitCallback('data', {
481
+ json: steps,
482
+ version: version,
483
+ userIds: clientIds
484
+ });
485
+ // If steps can apply to local editor successfully, no need to accumulate the error counter.
486
+ this.stepRejectCounter = 0;
487
+ this.participantsService.emitTelepointersFromSteps(steps, this.providerEmitCallback);
488
+
489
+ // Resend local steps if none of the received steps originated with us!
490
+ if (clientIds.indexOf(this.clientId) === -1) {
491
+ setTimeout(function () {
492
+ return _this2.sendStepsFromCurrentState();
493
+ }, 100);
494
+ }
495
+ } catch (error) {
496
+ var _this$analyticsHelper20;
497
+ logger("Processing steps failed with error: ".concat(error, ". Triggering catch up call."));
498
+ (_this$analyticsHelper20 = this.analyticsHelper) === null || _this$analyticsHelper20 === void 0 ? void 0 : _this$analyticsHelper20.sendErrorEvent(error, 'Error while processing steps');
499
+ this.throttledCatchup();
500
+ }
501
+ }
502
+ }
503
+
504
+ /**
505
+ * Called when we receive steps from the service
506
+ */
507
+
508
+ // Triggered when page recovery has emitted an 'init' event on a page client is currently connected to.
509
+
510
+ /**
511
+ * Commit the unconfirmed local steps to the back-end service
512
+ * @throws {Error} Couldn't sync the steps after retrying 30 times
513
+ */
514
+ }, {
515
+ key: "setup",
516
+ value: function setup(_ref9) {
517
+ var getState = _ref9.getState,
518
+ onSyncUpError = _ref9.onSyncUpError,
519
+ clientId = _ref9.clientId;
520
+ this.getState = getState;
521
+ this.onSyncUpError = onSyncUpError || noop;
522
+ this.clientId = clientId;
523
+ return this;
524
+ }
525
+
526
+ /**
527
+ * We can use this function to throttle/delay
528
+ * Any send steps operation
529
+ *
530
+ * The getState function will return the current EditorState
531
+ * from the EditorView.
532
+ */
533
+ }, {
534
+ key: "sendStepsFromCurrentState",
535
+ value: function sendStepsFromCurrentState() {
536
+ var _this$getState4;
537
+ var state = (_this$getState4 = this.getState) === null || _this$getState4 === void 0 ? void 0 : _this$getState4.call(this);
538
+ if (!state) {
539
+ return;
540
+ }
541
+ this.send(null, null, state);
542
+ }
543
+ }, {
544
+ key: "send",
545
+ value:
546
+ /**
547
+ * Send steps from transaction to other participants
548
+ * It needs the superfluous arguments because we keep the interface of the send API the same as the Synchrony plugin
549
+ */
550
+ function send(_tr, _oldState, newState) {
551
+ var unconfirmedStepsData = sendableSteps(newState);
552
+ var version = getVersion(newState);
553
+
554
+ // Don't send any steps before we're ready.
555
+ if (!unconfirmedStepsData) {
556
+ return;
557
+ }
558
+ var unconfirmedSteps = unconfirmedStepsData.steps;
559
+ if (!(unconfirmedSteps !== null && unconfirmedSteps !== void 0 && unconfirmedSteps.length)) {
560
+ return;
561
+ }
562
+
563
+ // Avoid reference issues using a
564
+ // method outside of the provider
565
+ // scope
566
+ throttledCommitStep({
567
+ broadcast: this.broadcast,
568
+ userId: this.getUserId(),
569
+ clientId: this.clientId,
570
+ steps: unconfirmedSteps,
571
+ version: version,
572
+ onStepsAdded: this.onStepsAdded,
573
+ onErrorHandled: this.onErrorHandled,
574
+ analyticsHelper: this.analyticsHelper
575
+ });
576
+ }
577
+ }]);
578
+ return DocumentService;
579
+ }();
@@ -0,0 +1,48 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
+ import _createClass from "@babel/runtime/helpers/createClass";
4
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
+ import { createLogger } from '../helpers/utils';
6
+ var logger = createLogger('documentService-queue', 'black');
7
+ export var StepQueueState = /*#__PURE__*/function () {
8
+ function StepQueueState() {
9
+ var _this = this;
10
+ _classCallCheck(this, StepQueueState);
11
+ _defineProperty(this, "queuePaused", false);
12
+ _defineProperty(this, "queue", []);
13
+ _defineProperty(this, "getQueue", function () {
14
+ return _this.queue;
15
+ });
16
+ _defineProperty(this, "filterQueue", function (condition) {
17
+ _this.queue = _this.queue.filter(condition);
18
+ });
19
+ _defineProperty(this, "isPaused", function () {
20
+ return _this.queuePaused;
21
+ });
22
+ _defineProperty(this, "pauseQueue", function () {
23
+ _this.queuePaused = true;
24
+ });
25
+ _defineProperty(this, "resumeQueue", function () {
26
+ _this.queuePaused = false;
27
+ });
28
+ _defineProperty(this, "shift", function () {
29
+ return _this.queue.shift();
30
+ });
31
+ }
32
+ _createClass(StepQueueState, [{
33
+ key: "queueSteps",
34
+ value: function queueSteps(data) {
35
+ logger("Queueing data for version \"".concat(data.version, "\"."));
36
+ var orderedQueue = [].concat(_toConsumableArray(this.queue), [data]).sort(function (a, b) {
37
+ return a.version > b.version ? 1 : -1;
38
+ });
39
+ this.queue = orderedQueue;
40
+ }
41
+
42
+ /**
43
+ * Get whether the document service has stopped processing new steps whilst it carries out processes such as catchup.
44
+ * Exposed for testing
45
+ */
46
+ }]);
47
+ return StepQueueState;
48
+ }();