@atlaskit/collab-provider 8.1.0 → 8.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/dist/cjs/analytics/index.js +68 -20
- package/dist/cjs/analytics/performance.js +45 -49
- package/dist/cjs/analytics/ufo.js +33 -0
- package/dist/cjs/channel.js +138 -154
- package/dist/cjs/connectivity/network.js +53 -0
- package/dist/cjs/connectivity/reconnect-helper.js +48 -0
- package/dist/cjs/connectivity/singleton.js +15 -0
- package/dist/cjs/disconnected-reason-mapper.js +19 -4
- package/dist/cjs/emitter.js +3 -11
- package/dist/cjs/error-code-mapper.js +14 -12
- package/dist/cjs/feature-flags/__test__/index.unit.js +0 -1
- package/dist/cjs/feature-flags/index.js +5 -15
- package/dist/cjs/feature-flags/types.js +2 -0
- package/dist/cjs/helpers/const.js +7 -18
- package/dist/cjs/helpers/utils.js +0 -12
- package/dist/cjs/index.js +0 -1
- package/dist/cjs/provider/catchup.js +35 -43
- package/dist/cjs/provider/commit-step.js +66 -0
- package/dist/cjs/provider/index.js +533 -742
- package/dist/cjs/provider/telepointers.js +78 -0
- package/dist/cjs/socket-io-provider.js +2 -12
- package/dist/cjs/types.js +0 -1
- package/dist/cjs/version-wrapper.js +1 -3
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/analytics/index.js +59 -11
- package/dist/es2019/analytics/performance.js +46 -46
- package/dist/es2019/analytics/ufo.js +22 -0
- package/dist/es2019/channel.js +128 -107
- package/dist/es2019/connectivity/network.js +34 -0
- package/dist/es2019/connectivity/reconnect-helper.js +29 -0
- package/dist/es2019/connectivity/singleton.js +7 -0
- package/dist/es2019/disconnected-reason-mapper.js +18 -3
- package/dist/es2019/emitter.js +3 -8
- package/dist/es2019/error-code-mapper.js +14 -7
- package/dist/es2019/feature-flags/index.js +2 -5
- package/dist/es2019/feature-flags/types.js +2 -0
- package/dist/es2019/helpers/const.js +6 -15
- package/dist/es2019/helpers/utils.js +0 -2
- package/dist/es2019/provider/catchup.js +32 -23
- package/dist/es2019/provider/commit-step.js +53 -0
- package/dist/es2019/provider/index.js +446 -616
- package/dist/es2019/provider/telepointers.js +65 -0
- package/dist/es2019/socket-io-provider.js +4 -2
- package/dist/es2019/types.js +1 -1
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/es2019/version.json +1 -1
- package/dist/esm/analytics/index.js +69 -15
- package/dist/esm/analytics/performance.js +46 -46
- package/dist/esm/analytics/ufo.js +25 -0
- package/dist/esm/channel.js +139 -148
- package/dist/esm/connectivity/network.js +45 -0
- package/dist/esm/connectivity/reconnect-helper.js +42 -0
- package/dist/esm/connectivity/singleton.js +7 -0
- package/dist/esm/disconnected-reason-mapper.js +18 -3
- package/dist/esm/emitter.js +3 -6
- package/dist/esm/error-code-mapper.js +14 -7
- package/dist/esm/feature-flags/index.js +5 -10
- package/dist/esm/feature-flags/types.js +2 -0
- package/dist/esm/helpers/const.js +6 -15
- package/dist/esm/helpers/utils.js +0 -3
- package/dist/esm/provider/catchup.js +35 -36
- package/dist/esm/provider/commit-step.js +58 -0
- package/dist/esm/provider/index.js +535 -745
- package/dist/esm/provider/telepointers.js +69 -0
- package/dist/esm/socket-io-provider.js +2 -5
- package/dist/esm/types.js +1 -1
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/esm/version.json +1 -1
- package/dist/types/analytics/index.d.ts +8 -2
- package/dist/types/analytics/performance.d.ts +5 -5
- package/dist/types/analytics/ufo.d.ts +3 -0
- package/dist/types/channel.d.ts +12 -5
- package/dist/types/connectivity/network.d.ts +17 -0
- package/dist/types/connectivity/reconnect-helper.d.ts +8 -0
- package/dist/types/connectivity/singleton.d.ts +3 -0
- package/dist/types/disconnected-reason-mapper.d.ts +1 -0
- package/dist/types/error-code-mapper.d.ts +4 -0
- package/dist/types/helpers/const.d.ts +116 -19
- package/dist/types/provider/commit-step.d.ts +14 -0
- package/dist/types/provider/index.d.ts +9 -5
- package/dist/types/provider/telepointers.d.ts +5 -0
- package/dist/types/socket-io-provider.d.ts +2 -1
- package/dist/types/types.d.ts +30 -11
- package/package.json +7 -6
- package/report.api.md +35 -0
- package/.vscode/settings.json +0 -3
package/dist/esm/emitter.js
CHANGED
|
@@ -5,10 +5,8 @@ import { EventEmitter2 } from 'eventemitter2';
|
|
|
5
5
|
export var Emitter = /*#__PURE__*/function () {
|
|
6
6
|
function Emitter() {
|
|
7
7
|
_classCallCheck(this, Emitter);
|
|
8
|
-
|
|
9
8
|
_defineProperty(this, "eventEmitter", new EventEmitter2());
|
|
10
9
|
}
|
|
11
|
-
|
|
12
10
|
_createClass(Emitter, [{
|
|
13
11
|
key: "emit",
|
|
14
12
|
value:
|
|
@@ -19,30 +17,30 @@ export var Emitter = /*#__PURE__*/function () {
|
|
|
19
17
|
this.eventEmitter.emit(evt, data);
|
|
20
18
|
return this;
|
|
21
19
|
}
|
|
20
|
+
|
|
22
21
|
/**
|
|
23
22
|
* Subscribe to events emitted by this provider
|
|
24
23
|
*/
|
|
25
|
-
|
|
26
24
|
}, {
|
|
27
25
|
key: "on",
|
|
28
26
|
value: function on(evt, handler) {
|
|
29
27
|
this.eventEmitter.on(evt, handler);
|
|
30
28
|
return this;
|
|
31
29
|
}
|
|
30
|
+
|
|
32
31
|
/**
|
|
33
32
|
* Unsubscribe from events emitted by this provider
|
|
34
33
|
*/
|
|
35
|
-
|
|
36
34
|
}, {
|
|
37
35
|
key: "off",
|
|
38
36
|
value: function off(evt, handler) {
|
|
39
37
|
this.eventEmitter.off(evt, handler);
|
|
40
38
|
return this;
|
|
41
39
|
}
|
|
40
|
+
|
|
42
41
|
/**
|
|
43
42
|
* Unsubscribe from all events emitted by this provider.
|
|
44
43
|
*/
|
|
45
|
-
|
|
46
44
|
}, {
|
|
47
45
|
key: "unsubscribeAll",
|
|
48
46
|
value: function unsubscribeAll(evt) {
|
|
@@ -50,6 +48,5 @@ export var Emitter = /*#__PURE__*/function () {
|
|
|
50
48
|
return this;
|
|
51
49
|
}
|
|
52
50
|
}]);
|
|
53
|
-
|
|
54
51
|
return Emitter;
|
|
55
52
|
}();
|
|
@@ -24,31 +24,33 @@ export var ErrorCodeMapper = {
|
|
|
24
24
|
code: 'FAIL_TO_SAVE',
|
|
25
25
|
message: 'Collab service is not able to save changes'
|
|
26
26
|
},
|
|
27
|
+
restoreError: {
|
|
28
|
+
code: 'DOCUMENT_RESTORE_ERROR',
|
|
29
|
+
message: 'Collab service unable to restore document'
|
|
30
|
+
},
|
|
27
31
|
internalError: {
|
|
28
32
|
code: 'INTERNAL_SERVICE_ERROR',
|
|
29
|
-
message: 'Collab service has
|
|
33
|
+
message: 'Collab service has experienced an internal server error'
|
|
30
34
|
}
|
|
31
35
|
};
|
|
32
36
|
export var errorCodeMapper = function errorCodeMapper(error) {
|
|
33
37
|
var _error$data;
|
|
34
|
-
|
|
35
38
|
switch ((_error$data = error.data) === null || _error$data === void 0 ? void 0 : _error$data.code) {
|
|
36
39
|
case 'INSUFFICIENT_EDITING_PERMISSION':
|
|
37
40
|
return {
|
|
38
41
|
status: 403,
|
|
39
42
|
code: ErrorCodeMapper.noPermissionError.code,
|
|
40
43
|
message: ErrorCodeMapper.noPermissionError.message,
|
|
41
|
-
reason:
|
|
44
|
+
reason:
|
|
45
|
+
// Typescript magic so it detects the union type
|
|
42
46
|
_typeof(error.data.meta) === 'object' ? error.data.meta.reason : undefined
|
|
43
47
|
};
|
|
44
|
-
|
|
45
48
|
case 'DOCUMENT_NOT_FOUND':
|
|
46
49
|
return {
|
|
47
50
|
status: 404,
|
|
48
51
|
code: ErrorCodeMapper.documentNotFound.code,
|
|
49
52
|
message: ErrorCodeMapper.documentNotFound.message
|
|
50
53
|
};
|
|
51
|
-
|
|
52
54
|
case 'FAILED_ON_S3':
|
|
53
55
|
case 'DYNAMO_ERROR':
|
|
54
56
|
return {
|
|
@@ -56,7 +58,13 @@ export var errorCodeMapper = function errorCodeMapper(error) {
|
|
|
56
58
|
code: ErrorCodeMapper.failToSave.code,
|
|
57
59
|
message: ErrorCodeMapper.failToSave.message
|
|
58
60
|
};
|
|
59
|
-
|
|
61
|
+
case 'DOCUMENT_RESTORE_ERROR':
|
|
62
|
+
return {
|
|
63
|
+
status: 500,
|
|
64
|
+
code: ErrorCodeMapper.restoreError.code,
|
|
65
|
+
message: ErrorCodeMapper.restoreError.message
|
|
66
|
+
};
|
|
67
|
+
// Temporarily re-added so we don't emit errors to Confluence by default as they will disconnect the collab provider
|
|
60
68
|
case 'CATCHUP_FAILED':
|
|
61
69
|
case 'GET_QUERY_TIME_OUT':
|
|
62
70
|
case 'INIT_DATA_LOAD_FAILED':
|
|
@@ -65,7 +73,6 @@ export var errorCodeMapper = function errorCodeMapper(error) {
|
|
|
65
73
|
code: ErrorCodeMapper.internalError.code,
|
|
66
74
|
message: ErrorCodeMapper.internalError.message
|
|
67
75
|
};
|
|
68
|
-
|
|
69
76
|
default:
|
|
70
77
|
break;
|
|
71
78
|
}
|
|
@@ -2,37 +2,33 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
|
2
2
|
var defaultNCSFeatureFlags = {
|
|
3
3
|
testFF: false
|
|
4
4
|
};
|
|
5
|
+
|
|
5
6
|
/**
|
|
6
7
|
* Note that Confluence should have the same FF sets as NCS
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
9
|
var productKeys = {
|
|
10
10
|
confluence: {
|
|
11
11
|
testFF: 'confluence.fe.collab.provider.testFF'
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
|
-
|
|
15
14
|
var filterFeatureFlagNames = function filterFeatureFlagNames(flags) {
|
|
16
15
|
var pairs = Object.entries(flags);
|
|
17
16
|
return pairs.filter(function (_ref) {
|
|
18
17
|
var _ref2 = _slicedToArray(_ref, 2),
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
_key = _ref2[0],
|
|
19
|
+
value = _ref2[1];
|
|
22
20
|
return !!value;
|
|
23
21
|
}).map(function (_ref3) {
|
|
24
22
|
var _ref4 = _slicedToArray(_ref3, 1),
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
key = _ref4[0];
|
|
27
24
|
return key;
|
|
28
25
|
});
|
|
29
26
|
};
|
|
27
|
+
|
|
30
28
|
/**
|
|
31
29
|
* Takes a record of {NCS Feature Flag Names → boolean} and a supported product name.
|
|
32
30
|
* Returns the corresponding product’s Launch Darkly Keys for each of the flags set as true in the input record.
|
|
33
31
|
* */
|
|
34
|
-
|
|
35
|
-
|
|
36
32
|
export var getProductSpecificFeatureFlags = function getProductSpecificFeatureFlags(flags, product) {
|
|
37
33
|
var ncsFeatureFlags = filterFeatureFlagNames(flags);
|
|
38
34
|
return ncsFeatureFlags.map(function (key) {
|
|
@@ -43,6 +39,5 @@ export function getCollabProviderFeatureFlag(flagName, featureFlags) {
|
|
|
43
39
|
if (featureFlags) {
|
|
44
40
|
return flagName in featureFlags ? featureFlags[flagName] : defaultNCSFeatureFlags[flagName];
|
|
45
41
|
}
|
|
46
|
-
|
|
47
42
|
return defaultNCSFeatureFlags[flagName];
|
|
48
43
|
}
|
|
@@ -1,38 +1,29 @@
|
|
|
1
|
-
export var EVENT_SUBJECT = 'collab';
|
|
2
|
-
export var COLLAB_SERVICE;
|
|
3
|
-
|
|
4
|
-
(function (COLLAB_SERVICE) {
|
|
5
|
-
COLLAB_SERVICE["NCS"] = "ncs";
|
|
6
|
-
COLLAB_SERVICE["SYNCHRONY"] = "synchrony";
|
|
7
|
-
})(COLLAB_SERVICE || (COLLAB_SERVICE = {}));
|
|
8
|
-
|
|
9
1
|
export var EVENT_ACTION;
|
|
10
|
-
|
|
11
2
|
(function (EVENT_ACTION) {
|
|
12
3
|
EVENT_ACTION["CONNECTION"] = "connection";
|
|
4
|
+
EVENT_ACTION["RECONNECTION"] = "reconnection";
|
|
13
5
|
EVENT_ACTION["CATCHUP"] = "catchup";
|
|
14
6
|
EVENT_ACTION["DOCUMENT_INIT"] = "documentInit";
|
|
15
7
|
EVENT_ACTION["ADD_STEPS"] = "addSteps";
|
|
16
|
-
EVENT_ACTION["CONVERT_PM_TO_ADF"] = "convertPMToADF";
|
|
17
8
|
EVENT_ACTION["UPDATE_PARTICIPANTS"] = "updateParticipants";
|
|
18
9
|
EVENT_ACTION["COMMIT_UNCONFIRMED_STEPS"] = "commitUnconfirmedSteps";
|
|
19
10
|
EVENT_ACTION["REINITIALISE_DOCUMENT"] = "reinitialiseDocument";
|
|
11
|
+
EVENT_ACTION["INIT_PROVIDER"] = "initProvider";
|
|
12
|
+
EVENT_ACTION["ERROR"] = "error";
|
|
13
|
+
EVENT_ACTION["MEASURE_PERFORMANCE"] = "measurePerformance";
|
|
14
|
+
EVENT_ACTION["INIT_UFO_EXPERIENCE"] = "initUFOExperience";
|
|
15
|
+
EVENT_ACTION["PUBLISH_PAGE"] = "publishPage";
|
|
20
16
|
})(EVENT_ACTION || (EVENT_ACTION = {}));
|
|
21
|
-
|
|
22
17
|
export var EVENT_STATUS;
|
|
23
|
-
|
|
24
18
|
(function (EVENT_STATUS) {
|
|
25
19
|
EVENT_STATUS["SUCCESS"] = "SUCCESS";
|
|
26
20
|
EVENT_STATUS["FAILURE"] = "FAILURE";
|
|
27
21
|
})(EVENT_STATUS || (EVENT_STATUS = {}));
|
|
28
|
-
|
|
29
22
|
export var ADD_STEPS_TYPE;
|
|
30
|
-
|
|
31
23
|
(function (ADD_STEPS_TYPE) {
|
|
32
24
|
ADD_STEPS_TYPE["ACCEPTED"] = "ACCEPTED";
|
|
33
25
|
ADD_STEPS_TYPE["REJECTED"] = "REJECTED";
|
|
34
26
|
ADD_STEPS_TYPE["ERROR"] = "ERROR";
|
|
35
27
|
})(ADD_STEPS_TYPE || (ADD_STEPS_TYPE = {}));
|
|
36
|
-
|
|
37
28
|
export var ACK_MAX_TRY = 30;
|
|
38
29
|
export var CONFLUENCE = 'confluence';
|
|
@@ -2,7 +2,6 @@ export var createLogger = function createLogger(prefix) {
|
|
|
2
2
|
var color = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'blue';
|
|
3
3
|
return function (msg) {
|
|
4
4
|
var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
5
|
-
|
|
6
5
|
if (window.COLLAB_PROVIDER_LOGGER) {
|
|
7
6
|
// eslint-disable-next-line no-console
|
|
8
7
|
console.log("%cCollab-".concat(prefix, ": ").concat(msg), "color: ".concat(color, "; font-weight: bold"), data);
|
|
@@ -26,11 +25,9 @@ export function sleep(ms) {
|
|
|
26
25
|
}
|
|
27
26
|
export var getProduct = function getProduct(productInfo) {
|
|
28
27
|
var _productInfo$product;
|
|
29
|
-
|
|
30
28
|
return (_productInfo$product = productInfo === null || productInfo === void 0 ? void 0 : productInfo.product) !== null && _productInfo$product !== void 0 ? _productInfo$product : 'unknown';
|
|
31
29
|
};
|
|
32
30
|
export var getSubProduct = function getSubProduct(productInfo) {
|
|
33
31
|
var _productInfo$subProdu;
|
|
34
|
-
|
|
35
32
|
return (_productInfo$subProdu = productInfo === null || productInfo === void 0 ? void 0 : productInfo.subProduct) !== null && _productInfo$subProdu !== void 0 ? _productInfo$subProdu : !!(productInfo !== null && productInfo !== void 0 && productInfo.product) ? 'none' : 'unknown';
|
|
36
33
|
};
|
|
@@ -1,32 +1,26 @@
|
|
|
1
1
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
2
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
3
|
-
|
|
4
3
|
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
5
|
-
|
|
6
4
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
7
|
-
|
|
8
5
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
9
|
-
|
|
10
6
|
import { createLogger } from '../helpers/utils';
|
|
11
7
|
import { StepMap, Mapping } from 'prosemirror-transform';
|
|
12
8
|
var logger = createLogger('Catchup', 'red');
|
|
9
|
+
|
|
13
10
|
/**
|
|
14
11
|
* Rebase the steps based on the mapping pipeline.
|
|
15
12
|
* Some steps could be lost, if they are no longer
|
|
16
13
|
* invalid after rebased.
|
|
17
14
|
*/
|
|
18
|
-
|
|
19
15
|
export function rebaseSteps(steps, mapping) {
|
|
20
16
|
var newSteps = [];
|
|
21
|
-
|
|
22
17
|
var _iterator = _createForOfIteratorHelper(steps),
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
_step;
|
|
25
19
|
try {
|
|
26
20
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
27
21
|
var step = _step.value;
|
|
28
|
-
var newStep = step.map(mapping);
|
|
29
|
-
|
|
22
|
+
var newStep = step.map(mapping);
|
|
23
|
+
// newStep could be null(means invalid after rebase) when can't rebase.
|
|
30
24
|
if (newStep) {
|
|
31
25
|
newSteps.push(newStep);
|
|
32
26
|
}
|
|
@@ -36,87 +30,93 @@ export function rebaseSteps(steps, mapping) {
|
|
|
36
30
|
} finally {
|
|
37
31
|
_iterator.f();
|
|
38
32
|
}
|
|
39
|
-
|
|
40
33
|
return newSteps;
|
|
41
34
|
}
|
|
42
35
|
export var catchup = /*#__PURE__*/function () {
|
|
43
36
|
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(opt) {
|
|
44
|
-
var _yield$opt$fetchCatch, doc, serverStepMaps, serverVersion, metadata, currentPmVersion,
|
|
45
|
-
|
|
37
|
+
var _yield$opt$fetchCatch, doc, serverStepMaps, serverVersion, metadata, currentPmVersion, unconfirmedSteps, _unconfirmedSteps, stepMaps, mapping, newUnconfirmedSteps;
|
|
46
38
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
47
39
|
while (1) {
|
|
48
40
|
switch (_context.prev = _context.next) {
|
|
49
41
|
case 0:
|
|
50
42
|
_context.next = 2;
|
|
51
43
|
return opt.fetchCatchup(opt.getCurrentPmVersion());
|
|
52
|
-
|
|
53
44
|
case 2:
|
|
54
45
|
_yield$opt$fetchCatch = _context.sent;
|
|
55
46
|
doc = _yield$opt$fetchCatch.doc;
|
|
56
47
|
serverStepMaps = _yield$opt$fetchCatch.stepMaps;
|
|
57
48
|
serverVersion = _yield$opt$fetchCatch.version;
|
|
58
49
|
metadata = _yield$opt$fetchCatch.metadata;
|
|
59
|
-
|
|
60
50
|
if (doc) {
|
|
61
51
|
currentPmVersion = opt.getCurrentPmVersion();
|
|
62
|
-
|
|
63
52
|
if (typeof serverVersion === 'undefined') {
|
|
64
53
|
logger("Could not determine server version");
|
|
65
54
|
} else if (serverVersion <= currentPmVersion) {
|
|
66
|
-
|
|
55
|
+
// there are no step maps in this case after page recovery
|
|
56
|
+
unconfirmedSteps = opt.getUnconfirmedSteps(); // replace the entire document
|
|
57
|
+
logger("Replacing document: ".concat(doc));
|
|
58
|
+
logger("getting metadata: ".concat(metadata));
|
|
59
|
+
// Replace local document and version number
|
|
60
|
+
opt.updateDocumentWithMetadata({
|
|
61
|
+
doc: JSON.parse(doc),
|
|
62
|
+
version: serverVersion,
|
|
63
|
+
metadata: metadata,
|
|
64
|
+
reserveCursor: true
|
|
65
|
+
});
|
|
66
|
+
if (unconfirmedSteps !== null && unconfirmedSteps !== void 0 && unconfirmedSteps.length) {
|
|
67
|
+
opt.applyLocalSteps(unconfirmedSteps);
|
|
68
|
+
}
|
|
67
69
|
} else {
|
|
68
70
|
// Please, do not use those steps inside of async
|
|
69
71
|
// method. That will lead to outdated steps
|
|
70
|
-
|
|
71
|
-
steps: []
|
|
72
|
-
}, unconfirmedSteps = _ref2.steps;
|
|
72
|
+
_unconfirmedSteps = opt.getUnconfirmedSteps();
|
|
73
73
|
logger("Too far behind[current: v".concat(currentPmVersion, ", server: v").concat(serverVersion, ". ").concat(serverStepMaps.length, " steps need to catchup]"));
|
|
74
74
|
/**
|
|
75
75
|
* Remove steps from queue where the version is older than
|
|
76
76
|
* the version we received from service. Keep steps that might be
|
|
77
77
|
* newer.
|
|
78
78
|
*/
|
|
79
|
-
|
|
80
79
|
opt.filterQueue(function (data) {
|
|
81
80
|
return data.version > serverVersion;
|
|
82
|
-
});
|
|
81
|
+
});
|
|
83
82
|
|
|
83
|
+
// We are too far behind - replace the entire document
|
|
84
84
|
logger("Replacing document: ".concat(doc));
|
|
85
|
-
logger("getting metadata: ".concat(metadata));
|
|
85
|
+
logger("getting metadata: ".concat(metadata));
|
|
86
86
|
|
|
87
|
+
// Replace local document and version number
|
|
87
88
|
opt.updateDocumentWithMetadata({
|
|
88
89
|
doc: JSON.parse(doc),
|
|
89
90
|
version: serverVersion,
|
|
90
91
|
metadata: metadata,
|
|
91
92
|
reserveCursor: true
|
|
92
|
-
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// After replacing the whole document in the editor, we need to reapply the unconfirmed
|
|
93
96
|
// steps back into the editor, so we don't lose any data. But before that, we need to rebase
|
|
94
97
|
// those steps since their position could be changed after replacing.
|
|
95
98
|
// https://prosemirror.net/docs/guide/#transform.rebasing
|
|
96
|
-
|
|
97
|
-
if (unconfirmedSteps.length) {
|
|
99
|
+
if (_unconfirmedSteps !== null && _unconfirmedSteps !== void 0 && _unconfirmedSteps.length) {
|
|
98
100
|
// Create StepMap from StepMap JSON
|
|
99
101
|
// eslint-disable-next-line no-unused-vars
|
|
100
|
-
stepMaps = serverStepMaps.map(function (
|
|
101
|
-
var ranges =
|
|
102
|
-
|
|
102
|
+
stepMaps = serverStepMaps.map(function (_ref2) {
|
|
103
|
+
var ranges = _ref2.ranges,
|
|
104
|
+
inverted = _ref2.inverted;
|
|
103
105
|
// Due to @types/prosemirror-transform mismatch with the actual
|
|
104
106
|
// constructor, hack to set the `inverted`.
|
|
105
107
|
var stepMap = new StepMap(ranges);
|
|
106
108
|
stepMap.inverted = inverted;
|
|
107
109
|
return stepMap;
|
|
108
110
|
}); // create Mappng used for Step.map
|
|
109
|
-
|
|
110
111
|
mapping = new Mapping(stepMaps);
|
|
111
|
-
logger("".concat(
|
|
112
|
-
newUnconfirmedSteps = rebaseSteps(
|
|
113
|
-
logger("Re-aply ".concat(newUnconfirmedSteps.length, " mapped unconfirmed steps: ").concat(JSON.stringify(newUnconfirmedSteps)));
|
|
114
|
-
|
|
112
|
+
logger("".concat(_unconfirmedSteps.length, " unconfirmed steps before rebased: ").concat(JSON.stringify(_unconfirmedSteps)));
|
|
113
|
+
newUnconfirmedSteps = rebaseSteps(_unconfirmedSteps, mapping);
|
|
114
|
+
logger("Re-aply ".concat(newUnconfirmedSteps.length, " mapped unconfirmed steps: ").concat(JSON.stringify(newUnconfirmedSteps)));
|
|
115
|
+
// Re-aply local steps
|
|
115
116
|
opt.applyLocalSteps(newUnconfirmedSteps);
|
|
116
117
|
}
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
|
-
|
|
120
120
|
case 8:
|
|
121
121
|
case "end":
|
|
122
122
|
return _context.stop();
|
|
@@ -124,7 +124,6 @@ export var catchup = /*#__PURE__*/function () {
|
|
|
124
124
|
}
|
|
125
125
|
}, _callee);
|
|
126
126
|
}));
|
|
127
|
-
|
|
128
127
|
return function catchup(_x) {
|
|
129
128
|
return _ref.apply(this, arguments);
|
|
130
129
|
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
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; }
|
|
3
|
+
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; }
|
|
4
|
+
import countBy from 'lodash/countBy';
|
|
5
|
+
import { ADD_STEPS_TYPE, EVENT_ACTION, EVENT_STATUS } from '../helpers/const';
|
|
6
|
+
import { AcknowledgementResponseTypes } from '../types';
|
|
7
|
+
export var commitStep = function commitStep(_ref) {
|
|
8
|
+
var channel = _ref.channel,
|
|
9
|
+
steps = _ref.steps,
|
|
10
|
+
version = _ref.version,
|
|
11
|
+
userId = _ref.userId,
|
|
12
|
+
clientId = _ref.clientId,
|
|
13
|
+
onStepsAdded = _ref.onStepsAdded,
|
|
14
|
+
onErrorHandled = _ref.onErrorHandled,
|
|
15
|
+
analyticsHelper = _ref.analyticsHelper;
|
|
16
|
+
var stepsWithClientAndUserId = steps.map(function (step) {
|
|
17
|
+
return _objectSpread(_objectSpread({}, step.toJSON()), {}, {
|
|
18
|
+
clientId: clientId,
|
|
19
|
+
userId: userId
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
var start = new Date().getTime();
|
|
23
|
+
channel.broadcast('steps:commit', {
|
|
24
|
+
steps: stepsWithClientAndUserId,
|
|
25
|
+
version: version,
|
|
26
|
+
userId: userId
|
|
27
|
+
}, function (response) {
|
|
28
|
+
var latency = new Date().getTime() - start;
|
|
29
|
+
if (response.type === AcknowledgementResponseTypes.SUCCESS) {
|
|
30
|
+
onStepsAdded({
|
|
31
|
+
steps: stepsWithClientAndUserId,
|
|
32
|
+
version: response.version
|
|
33
|
+
});
|
|
34
|
+
analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendActionEvent(EVENT_ACTION.ADD_STEPS, EVENT_STATUS.SUCCESS, {
|
|
35
|
+
type: ADD_STEPS_TYPE.ACCEPTED,
|
|
36
|
+
latency: latency,
|
|
37
|
+
stepType: countBy(stepsWithClientAndUserId, function (stepWithClientAndUserId) {
|
|
38
|
+
return stepWithClientAndUserId.stepType;
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
} else if (response.type === AcknowledgementResponseTypes.ERROR) {
|
|
42
|
+
var _response$error, _response$error$data, _response$error2, _response$error2$data;
|
|
43
|
+
onErrorHandled(response.error);
|
|
44
|
+
analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendActionEvent(EVENT_ACTION.ADD_STEPS, EVENT_STATUS.FAILURE, {
|
|
45
|
+
// User tried committing steps but they were rejected because:
|
|
46
|
+
// - HEAD_VERSION_UPDATE_FAILED: the collab service's latest stored step tail version didn't correspond to the head version of the first step submitted
|
|
47
|
+
// - VERSION_NUMBER_ALREADY_EXISTS: while storing the steps there was a conflict meaning someone else wrote steps into the database more quickly
|
|
48
|
+
type: ((_response$error = response.error) === null || _response$error === void 0 ? void 0 : (_response$error$data = _response$error.data) === null || _response$error$data === void 0 ? void 0 : _response$error$data.code) === 'HEAD_VERSION_UPDATE_FAILED' || ((_response$error2 = response.error) === null || _response$error2 === void 0 ? void 0 : (_response$error2$data = _response$error2.data) === null || _response$error2$data === void 0 ? void 0 : _response$error2$data.code) === 'VERSION_NUMBER_ALREADY_EXISTS' ? ADD_STEPS_TYPE.REJECTED : ADD_STEPS_TYPE.ERROR,
|
|
49
|
+
latency: latency
|
|
50
|
+
});
|
|
51
|
+
analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(response.error, 'Error while adding steps - Acknowledgement Error');
|
|
52
|
+
} else {
|
|
53
|
+
analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(
|
|
54
|
+
// @ts-expect-error We didn't type the invalid type case
|
|
55
|
+
new Error("Response type: ".concat((response === null || response === void 0 ? void 0 : response.type) || 'No response type')), 'Error while adding steps - Invalid Acknowledgement');
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
};
|