@atlaskit/collab-provider 10.3.3 → 10.4.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 +18 -0
- package/afm-cc/tsconfig.json +3 -0
- package/dist/cjs/document/catchupv2.js +23 -6
- package/dist/cjs/document/document-service.js +2 -1
- package/dist/cjs/helpers/const.js +2 -1
- package/dist/cjs/helpers/utils.js +136 -1
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/es2019/document/catchupv2.js +19 -2
- package/dist/es2019/document/document-service.js +2 -1
- package/dist/es2019/helpers/const.js +2 -1
- package/dist/es2019/helpers/utils.js +129 -0
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/esm/document/catchupv2.js +24 -7
- package/dist/esm/document/document-service.js +2 -1
- package/dist/esm/helpers/const.js +2 -1
- package/dist/esm/helpers/utils.js +134 -0
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/types/helpers/const.d.ts +16 -2
- package/dist/types/helpers/utils.d.ts +41 -0
- package/dist/types/types.d.ts +3 -2
- package/dist/types-ts4.5/helpers/const.d.ts +16 -2
- package/dist/types-ts4.5/helpers/utils.d.ts +41 -0
- package/dist/types-ts4.5/types.d.ts +3 -2
- package/package.json +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @atlaskit/collab-provider
|
|
2
2
|
|
|
3
|
+
## 10.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#102499](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/102499)
|
|
8
|
+
[`c1bfe8b68a35e`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/c1bfe8b68a35e) -
|
|
9
|
+
log obfuscated steps in collab provider when catchup out of sync
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
|
|
15
|
+
## 10.3.4
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies
|
|
20
|
+
|
|
3
21
|
## 10.3.3
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/afm-cc/tsconfig.json
CHANGED
|
@@ -7,11 +7,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.isOutOfSync = exports.catchupv2 = void 0;
|
|
8
8
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
9
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
10
|
+
var _const = require("../helpers/const");
|
|
10
11
|
var _utils = require("../helpers/utils");
|
|
12
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
11
13
|
var logger = (0, _utils.createLogger)('Catchupv2', 'red');
|
|
12
14
|
var catchupv2 = exports.catchupv2 = /*#__PURE__*/function () {
|
|
13
15
|
var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(opt) {
|
|
14
|
-
var steps, metadata, fromVersion, _yield$opt$fetchCatch, _opt$analyticsHelper, _opt$onCatchupComplet, version, stepsPayload, _opt$analyticsHelper2;
|
|
16
|
+
var steps, metadata, fromVersion, _yield$opt$fetchCatch, _opt$analyticsHelper, _opt$onCatchupComplet, version, stepsPayload, clientOutOfSync, _opt$analyticsHelper2;
|
|
15
17
|
return _regenerator.default.wrap(function _callee$(_context) {
|
|
16
18
|
while (1) switch (_context.prev = _context.next) {
|
|
17
19
|
case 0:
|
|
@@ -53,23 +55,38 @@ var catchupv2 = exports.catchupv2 = /*#__PURE__*/function () {
|
|
|
53
55
|
};
|
|
54
56
|
opt.onStepsAdded(stepsPayload);
|
|
55
57
|
opt.updateMetadata(metadata);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
clientOutOfSync = Boolean(opt.clientId && isOutOfSync(fromVersion, opt.getCurrentPmVersion(), steps, opt.clientId));
|
|
59
|
+
if (clientOutOfSync) {
|
|
60
|
+
logObfuscatedSteps(steps, opt);
|
|
61
|
+
}
|
|
62
|
+
return _context.abrupt("return", clientOutOfSync);
|
|
63
|
+
case 28:
|
|
64
|
+
_context.prev = 28;
|
|
59
65
|
_context.t1 = _context["catch"](14);
|
|
60
66
|
(_opt$analyticsHelper2 = opt.analyticsHelper) === null || _opt$analyticsHelper2 === void 0 || _opt$analyticsHelper2.sendErrorEvent(_context.t1, 'Failed to apply catchupv2 result in the editor');
|
|
61
67
|
logger("Apply catchupv2 steps failed:", _context.t1.message);
|
|
62
68
|
throw _context.t1;
|
|
63
|
-
case
|
|
69
|
+
case 33:
|
|
64
70
|
case "end":
|
|
65
71
|
return _context.stop();
|
|
66
72
|
}
|
|
67
|
-
}, _callee, null, [[1, 9], [14,
|
|
73
|
+
}, _callee, null, [[1, 9], [14, 28]]);
|
|
68
74
|
}));
|
|
69
75
|
return function catchupv2(_x) {
|
|
70
76
|
return _ref.apply(this, arguments);
|
|
71
77
|
};
|
|
72
78
|
}();
|
|
79
|
+
var logObfuscatedSteps = function logObfuscatedSteps(steps, opt) {
|
|
80
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_log_obfuscated_steps')) {
|
|
81
|
+
var _opt$getState, _opt$analyticsHelper3;
|
|
82
|
+
var state = (_opt$getState = opt.getState) === null || _opt$getState === void 0 ? void 0 : _opt$getState.call(opt);
|
|
83
|
+
(_opt$analyticsHelper3 = opt.analyticsHelper) === null || _opt$analyticsHelper3 === void 0 || _opt$analyticsHelper3.sendActionEvent(_const.EVENT_ACTION.OUT_OF_SYNC, _const.EVENT_STATUS.FAILURE, {
|
|
84
|
+
obfuscatedSteps: (0, _utils.getObfuscatedSteps)(steps),
|
|
85
|
+
obfuscatedDoc: state ? (0, _utils.getDocAdfWithObfuscation)(state.doc) : null,
|
|
86
|
+
catchupReason: opt.reason
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
};
|
|
73
90
|
|
|
74
91
|
/**
|
|
75
92
|
* Checks if we're out of sync with the backend because catchup failed to apply, and thus the doc should be reset.
|
|
@@ -122,7 +122,8 @@ var DocumentService = exports.DocumentService = /*#__PURE__*/function () {
|
|
|
122
122
|
remoteStepsLength: (_steps$length = steps === null || steps === void 0 ? void 0 : steps.length) !== null && _steps$length !== void 0 ? _steps$length : 0
|
|
123
123
|
}));
|
|
124
124
|
}
|
|
125
|
-
}
|
|
125
|
+
},
|
|
126
|
+
getState: _this.getState
|
|
126
127
|
});
|
|
127
128
|
case 11:
|
|
128
129
|
_this.catchUpOutofSync = _context.sent;
|
|
@@ -25,8 +25,9 @@ var EVENT_ACTION = exports.EVENT_ACTION = /*#__PURE__*/function (EVENT_ACTION) {
|
|
|
25
25
|
EVENT_ACTION["RECONNECTION"] = "providerReconnection";
|
|
26
26
|
EVENT_ACTION["PROVIDER_SETUP"] = "providerSetup";
|
|
27
27
|
EVENT_ACTION["HAS_UNCONFIRMED_STEPS"] = "hasUnconfirmedSteps";
|
|
28
|
+
EVENT_ACTION["OUT_OF_SYNC"] = "outOfSync";
|
|
28
29
|
return EVENT_ACTION;
|
|
29
|
-
}({}); // https://data-portal.internal.atlassian.com/analytics/registry/
|
|
30
|
+
}({}); // https://data-portal.internal.atlassian.com/analytics/registry/74993
|
|
30
31
|
var EVENT_STATUS = exports.EVENT_STATUS = /*#__PURE__*/function (EVENT_STATUS) {
|
|
31
32
|
EVENT_STATUS["SUCCESS"] = "SUCCESS";
|
|
32
33
|
EVENT_STATUS["FAILURE"] = "FAILURE";
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
3
4
|
Object.defineProperty(exports, "__esModule", {
|
|
4
5
|
value: true
|
|
5
6
|
});
|
|
6
|
-
exports.isAIProviderID = exports.getSubProduct = exports.getStepUGCFreeDetails = exports.getProduct = exports.createLogger = void 0;
|
|
7
|
+
exports.isAIProviderID = exports.getSubProduct = exports.getStepsAdfWithObfuscation = exports.getStepUGCFreeDetails = exports.getStepTypes = exports.getStepPositions = exports.getProduct = exports.getObfuscatedSteps = exports.getDocAdfWithObfuscation = exports.createLogger = void 0;
|
|
7
8
|
exports.sleep = sleep;
|
|
9
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
10
|
+
var _scrub = require("@atlaskit/adf-utils/scrub");
|
|
11
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
12
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
8
13
|
var createLogger = exports.createLogger = function createLogger(prefix) {
|
|
9
14
|
var color = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'blue';
|
|
10
15
|
return (
|
|
@@ -64,4 +69,134 @@ var getStepUGCFreeDetails = exports.getStepUGCFreeDetails = function getStepUGCF
|
|
|
64
69
|
contentTypes: contentTypes,
|
|
65
70
|
stepSizeInBytes: Buffer.byteLength(JSON.stringify(step))
|
|
66
71
|
};
|
|
72
|
+
};
|
|
73
|
+
var stepWithNextDocument = function stepWithNextDocument(stepJson) {
|
|
74
|
+
return stepJson.stepType === 'override-document' && 'nextDocument' in stepJson;
|
|
75
|
+
};
|
|
76
|
+
var stepWithMark = function stepWithMark(stepJson) {
|
|
77
|
+
return stepJson.stepType === 'addMark' || stepJson.stepType === 'addNodeMark';
|
|
78
|
+
};
|
|
79
|
+
var stepWithAttrs = function stepWithAttrs(stepJson) {
|
|
80
|
+
return stepJson.stepType === 'setAttrs' && 'attrs' in stepJson;
|
|
81
|
+
};
|
|
82
|
+
var stepWithBatchAttrs = function stepWithBatchAttrs(stepJson) {
|
|
83
|
+
return stepJson.stepType === 'batchAttrs' && 'data' in stepJson;
|
|
84
|
+
};
|
|
85
|
+
var stepWithFromTo = function stepWithFromTo(stepJson) {
|
|
86
|
+
return 'from' in stepJson && typeof stepJson.from === 'number' && 'to' in stepJson && typeof stepJson.to === 'number';
|
|
87
|
+
};
|
|
88
|
+
var stepWithGapFromTo = function stepWithGapFromTo(stepJson) {
|
|
89
|
+
return 'gapFrom' in stepJson && typeof stepJson.gapFrom === 'number' && 'gapTo' in stepJson && typeof stepJson.gapTo === 'number';
|
|
90
|
+
};
|
|
91
|
+
var stepWithInsert = function stepWithInsert(stepJson) {
|
|
92
|
+
return 'insert' in stepJson && typeof stepJson.insert === 'number';
|
|
93
|
+
};
|
|
94
|
+
var stepWithPos = function stepWithPos(stepJson) {
|
|
95
|
+
return 'pos' in stepJson && typeof stepJson.pos === 'number';
|
|
96
|
+
};
|
|
97
|
+
var stepWithSlice = function stepWithSlice(stepJson) {
|
|
98
|
+
var _stepJson$slice3;
|
|
99
|
+
return 'slice' in stepJson && Array.isArray((_stepJson$slice3 = stepJson.slice) === null || _stepJson$slice3 === void 0 ? void 0 : _stepJson$slice3.content);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// Get as step info which is known not to contain user generated content.
|
|
103
|
+
var getStepTypes = exports.getStepTypes = function getStepTypes(stepJson) {
|
|
104
|
+
var contentTypes = null;
|
|
105
|
+
if (stepWithSlice(stepJson)) {
|
|
106
|
+
contentTypes = stepJson.slice.content.map(function (c) {
|
|
107
|
+
return (c === null || c === void 0 ? void 0 : c.type) || 'unknown';
|
|
108
|
+
}).join(', ');
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
type: stepJson.stepType || 'unknown',
|
|
112
|
+
contentTypes: contentTypes
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
var getStepsAdfWithObfuscation = exports.getStepsAdfWithObfuscation = function getStepsAdfWithObfuscation(stepJson) {
|
|
116
|
+
var stepContentAsAdf = stepToAdf(stepJson);
|
|
117
|
+
if (!stepContentAsAdf) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
var scrubbedSteps = stepContentAsAdf.map(function (adf) {
|
|
121
|
+
return (0, _scrub.scrubAdf)(adf);
|
|
122
|
+
}).filter(function (adf) {
|
|
123
|
+
return !!adf;
|
|
124
|
+
});
|
|
125
|
+
return scrubbedSteps;
|
|
126
|
+
};
|
|
127
|
+
var getDocAdfWithObfuscation = exports.getDocAdfWithObfuscation = function getDocAdfWithObfuscation(doc) {
|
|
128
|
+
var docJson = doc.toJSON();
|
|
129
|
+
var scrubbedDoc = (0, _scrub.scrubAdf)(docJson);
|
|
130
|
+
if (!scrubbedDoc) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
return scrubbedDoc;
|
|
134
|
+
};
|
|
135
|
+
var getStepPositions = exports.getStepPositions = function getStepPositions(stepJson) {
|
|
136
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, stepWithFromTo(stepJson) && {
|
|
137
|
+
from: stepJson.from,
|
|
138
|
+
to: stepJson.to
|
|
139
|
+
}), stepWithGapFromTo(stepJson) && {
|
|
140
|
+
gapFrom: stepJson.gapFrom,
|
|
141
|
+
gapTo: stepJson.gapTo
|
|
142
|
+
}), stepWithInsert(stepJson) && {
|
|
143
|
+
insert: stepJson.insert
|
|
144
|
+
}), stepWithPos(stepJson) && {
|
|
145
|
+
pos: stepJson.pos
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Returns the metadata for Step
|
|
151
|
+
* @description metadata is applied by transform overrides [here](https://bitbucket.org/atlassian/adf-schema/src/e13bbece84ede8f245067dc53dd7ce694f427eda/packages/editor-prosemirror/src/transform-override.ts#lines-12)
|
|
152
|
+
*/
|
|
153
|
+
var getStepMetadata = function getStepMetadata(stepJson) {
|
|
154
|
+
return stepJson.metadata;
|
|
155
|
+
};
|
|
156
|
+
var getObfuscatedSteps = exports.getObfuscatedSteps = function getObfuscatedSteps(steps) {
|
|
157
|
+
var endIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
|
|
158
|
+
return steps.slice(0, endIndex).map(function (step) {
|
|
159
|
+
return {
|
|
160
|
+
stepType: getStepTypes(step),
|
|
161
|
+
stepContent: getStepsAdfWithObfuscation(step),
|
|
162
|
+
stepPositions: getStepPositions(step),
|
|
163
|
+
stepMetadata: getStepMetadata(step)
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
var stepToAdf = function stepToAdf(step) {
|
|
168
|
+
if (stepWithSlice(step)) {
|
|
169
|
+
return [{
|
|
170
|
+
type: 'doc',
|
|
171
|
+
content: step.slice.content.filter(function (el) {
|
|
172
|
+
return el !== null;
|
|
173
|
+
})
|
|
174
|
+
}];
|
|
175
|
+
} else if (stepWithNextDocument(step)) {
|
|
176
|
+
return [{
|
|
177
|
+
type: 'doc',
|
|
178
|
+
content: step.nextDocument.content
|
|
179
|
+
}];
|
|
180
|
+
} else if (stepWithMark(step) && step.mark) {
|
|
181
|
+
return [{
|
|
182
|
+
type: 'doc',
|
|
183
|
+
marks: [{
|
|
184
|
+
type: step.mark.type || 'unknown',
|
|
185
|
+
attrs: step.mark.attrs
|
|
186
|
+
}]
|
|
187
|
+
}];
|
|
188
|
+
} else if (stepWithAttrs(step)) {
|
|
189
|
+
return [{
|
|
190
|
+
type: 'doc',
|
|
191
|
+
attrs: step.attrs
|
|
192
|
+
}];
|
|
193
|
+
} else if (stepWithBatchAttrs(step)) {
|
|
194
|
+
return step.data.map(function (stepData) {
|
|
195
|
+
return {
|
|
196
|
+
type: 'doc',
|
|
197
|
+
attrs: stepData.attrs
|
|
198
|
+
};
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return [];
|
|
67
202
|
};
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.version = exports.nextMajorVersion = exports.name = void 0;
|
|
7
7
|
var name = exports.name = "@atlaskit/collab-provider";
|
|
8
|
-
var version = exports.version = "10.
|
|
8
|
+
var version = exports.version = "10.4.0";
|
|
9
9
|
var nextMajorVersion = exports.nextMajorVersion = function nextMajorVersion() {
|
|
10
10
|
return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
|
|
11
11
|
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EVENT_ACTION, EVENT_STATUS } from '../helpers/const';
|
|
2
|
+
import { createLogger, getObfuscatedSteps, getDocAdfWithObfuscation } from '../helpers/utils';
|
|
3
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
4
|
const logger = createLogger('Catchupv2', 'red');
|
|
3
5
|
export const catchupv2 = async opt => {
|
|
4
6
|
// Ignored via go/ees005
|
|
@@ -34,7 +36,11 @@ export const catchupv2 = async opt => {
|
|
|
34
36
|
};
|
|
35
37
|
opt.onStepsAdded(stepsPayload);
|
|
36
38
|
opt.updateMetadata(metadata);
|
|
37
|
-
|
|
39
|
+
const clientOutOfSync = Boolean(opt.clientId && isOutOfSync(fromVersion, opt.getCurrentPmVersion(), steps, opt.clientId));
|
|
40
|
+
if (clientOutOfSync) {
|
|
41
|
+
logObfuscatedSteps(steps, opt);
|
|
42
|
+
}
|
|
43
|
+
return clientOutOfSync;
|
|
38
44
|
} catch (error) {
|
|
39
45
|
var _opt$analyticsHelper2;
|
|
40
46
|
(_opt$analyticsHelper2 = opt.analyticsHelper) === null || _opt$analyticsHelper2 === void 0 ? void 0 : _opt$analyticsHelper2.sendErrorEvent(error, 'Failed to apply catchupv2 result in the editor');
|
|
@@ -42,6 +48,17 @@ export const catchupv2 = async opt => {
|
|
|
42
48
|
throw error;
|
|
43
49
|
}
|
|
44
50
|
};
|
|
51
|
+
const logObfuscatedSteps = (steps, opt) => {
|
|
52
|
+
if (fg('platform_editor_log_obfuscated_steps')) {
|
|
53
|
+
var _opt$getState, _opt$analyticsHelper3;
|
|
54
|
+
const state = (_opt$getState = opt.getState) === null || _opt$getState === void 0 ? void 0 : _opt$getState.call(opt);
|
|
55
|
+
(_opt$analyticsHelper3 = opt.analyticsHelper) === null || _opt$analyticsHelper3 === void 0 ? void 0 : _opt$analyticsHelper3.sendActionEvent(EVENT_ACTION.OUT_OF_SYNC, EVENT_STATUS.FAILURE, {
|
|
56
|
+
obfuscatedSteps: getObfuscatedSteps(steps),
|
|
57
|
+
obfuscatedDoc: state ? getDocAdfWithObfuscation(state.doc) : null,
|
|
58
|
+
catchupReason: opt.reason
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
};
|
|
45
62
|
|
|
46
63
|
/**
|
|
47
64
|
* Checks if we're out of sync with the backend because catchup failed to apply, and thus the doc should be reset.
|
|
@@ -116,7 +116,8 @@ export class DocumentService {
|
|
|
116
116
|
remoteStepsLength: (_steps$length = steps === null || steps === void 0 ? void 0 : steps.length) !== null && _steps$length !== void 0 ? _steps$length : 0
|
|
117
117
|
});
|
|
118
118
|
}
|
|
119
|
-
}
|
|
119
|
+
},
|
|
120
|
+
getState: this.getState
|
|
120
121
|
});
|
|
121
122
|
const latency = new Date().getTime() - start;
|
|
122
123
|
(_this$analyticsHelper2 = this.analyticsHelper) === null || _this$analyticsHelper2 === void 0 ? void 0 : _this$analyticsHelper2.sendActionEvent(EVENT_ACTION.CATCHUP, EVENT_STATUS.SUCCESS, {
|
|
@@ -19,8 +19,9 @@ export let EVENT_ACTION = /*#__PURE__*/function (EVENT_ACTION) {
|
|
|
19
19
|
EVENT_ACTION["RECONNECTION"] = "providerReconnection";
|
|
20
20
|
EVENT_ACTION["PROVIDER_SETUP"] = "providerSetup";
|
|
21
21
|
EVENT_ACTION["HAS_UNCONFIRMED_STEPS"] = "hasUnconfirmedSteps";
|
|
22
|
+
EVENT_ACTION["OUT_OF_SYNC"] = "outOfSync";
|
|
22
23
|
return EVENT_ACTION;
|
|
23
|
-
}({}); // https://data-portal.internal.atlassian.com/analytics/registry/
|
|
24
|
+
}({}); // https://data-portal.internal.atlassian.com/analytics/registry/74993
|
|
24
25
|
export let EVENT_STATUS = /*#__PURE__*/function (EVENT_STATUS) {
|
|
25
26
|
EVENT_STATUS["SUCCESS"] = "SUCCESS";
|
|
26
27
|
EVENT_STATUS["FAILURE"] = "FAILURE";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { scrubAdf } from '@atlaskit/adf-utils/scrub';
|
|
1
2
|
export const createLogger = (prefix, color = 'blue') =>
|
|
2
3
|
// Ignored via go/ees005
|
|
3
4
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -50,4 +51,132 @@ export const getStepUGCFreeDetails = step => {
|
|
|
50
51
|
contentTypes,
|
|
51
52
|
stepSizeInBytes: Buffer.byteLength(JSON.stringify(step))
|
|
52
53
|
};
|
|
54
|
+
};
|
|
55
|
+
const stepWithNextDocument = stepJson => {
|
|
56
|
+
return stepJson.stepType === 'override-document' && 'nextDocument' in stepJson;
|
|
57
|
+
};
|
|
58
|
+
const stepWithMark = stepJson => {
|
|
59
|
+
return stepJson.stepType === 'addMark' || stepJson.stepType === 'addNodeMark';
|
|
60
|
+
};
|
|
61
|
+
const stepWithAttrs = stepJson => {
|
|
62
|
+
return stepJson.stepType === 'setAttrs' && 'attrs' in stepJson;
|
|
63
|
+
};
|
|
64
|
+
const stepWithBatchAttrs = stepJson => {
|
|
65
|
+
return stepJson.stepType === 'batchAttrs' && 'data' in stepJson;
|
|
66
|
+
};
|
|
67
|
+
const stepWithFromTo = stepJson => {
|
|
68
|
+
return 'from' in stepJson && typeof stepJson.from === 'number' && 'to' in stepJson && typeof stepJson.to === 'number';
|
|
69
|
+
};
|
|
70
|
+
const stepWithGapFromTo = stepJson => {
|
|
71
|
+
return 'gapFrom' in stepJson && typeof stepJson.gapFrom === 'number' && 'gapTo' in stepJson && typeof stepJson.gapTo === 'number';
|
|
72
|
+
};
|
|
73
|
+
const stepWithInsert = stepJson => {
|
|
74
|
+
return 'insert' in stepJson && typeof stepJson.insert === 'number';
|
|
75
|
+
};
|
|
76
|
+
const stepWithPos = stepJson => {
|
|
77
|
+
return 'pos' in stepJson && typeof stepJson.pos === 'number';
|
|
78
|
+
};
|
|
79
|
+
const stepWithSlice = stepJson => {
|
|
80
|
+
var _stepJson$slice3;
|
|
81
|
+
return 'slice' in stepJson && Array.isArray((_stepJson$slice3 = stepJson.slice) === null || _stepJson$slice3 === void 0 ? void 0 : _stepJson$slice3.content);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// Get as step info which is known not to contain user generated content.
|
|
85
|
+
export const getStepTypes = stepJson => {
|
|
86
|
+
let contentTypes = null;
|
|
87
|
+
if (stepWithSlice(stepJson)) {
|
|
88
|
+
contentTypes = stepJson.slice.content.map(c => {
|
|
89
|
+
return (c === null || c === void 0 ? void 0 : c.type) || 'unknown';
|
|
90
|
+
}).join(', ');
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
type: stepJson.stepType || 'unknown',
|
|
94
|
+
contentTypes
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
export const getStepsAdfWithObfuscation = stepJson => {
|
|
98
|
+
const stepContentAsAdf = stepToAdf(stepJson);
|
|
99
|
+
if (!stepContentAsAdf) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
const scrubbedSteps = stepContentAsAdf.map(adf => scrubAdf(adf)).filter(adf => !!adf);
|
|
103
|
+
return scrubbedSteps;
|
|
104
|
+
};
|
|
105
|
+
export const getDocAdfWithObfuscation = doc => {
|
|
106
|
+
const docJson = doc.toJSON();
|
|
107
|
+
const scrubbedDoc = scrubAdf(docJson);
|
|
108
|
+
if (!scrubbedDoc) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
return scrubbedDoc;
|
|
112
|
+
};
|
|
113
|
+
export const getStepPositions = stepJson => {
|
|
114
|
+
return {
|
|
115
|
+
...(stepWithFromTo(stepJson) && {
|
|
116
|
+
from: stepJson.from,
|
|
117
|
+
to: stepJson.to
|
|
118
|
+
}),
|
|
119
|
+
...(stepWithGapFromTo(stepJson) && {
|
|
120
|
+
gapFrom: stepJson.gapFrom,
|
|
121
|
+
gapTo: stepJson.gapTo
|
|
122
|
+
}),
|
|
123
|
+
...(stepWithInsert(stepJson) && {
|
|
124
|
+
insert: stepJson.insert
|
|
125
|
+
}),
|
|
126
|
+
...(stepWithPos(stepJson) && {
|
|
127
|
+
pos: stepJson.pos
|
|
128
|
+
})
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Returns the metadata for Step
|
|
134
|
+
* @description metadata is applied by transform overrides [here](https://bitbucket.org/atlassian/adf-schema/src/e13bbece84ede8f245067dc53dd7ce694f427eda/packages/editor-prosemirror/src/transform-override.ts#lines-12)
|
|
135
|
+
*/
|
|
136
|
+
const getStepMetadata = stepJson => {
|
|
137
|
+
return stepJson.metadata;
|
|
138
|
+
};
|
|
139
|
+
export const getObfuscatedSteps = (steps, endIndex = undefined) => {
|
|
140
|
+
return steps.slice(0, endIndex).map(step => {
|
|
141
|
+
return {
|
|
142
|
+
stepType: getStepTypes(step),
|
|
143
|
+
stepContent: getStepsAdfWithObfuscation(step),
|
|
144
|
+
stepPositions: getStepPositions(step),
|
|
145
|
+
stepMetadata: getStepMetadata(step)
|
|
146
|
+
};
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
const stepToAdf = step => {
|
|
150
|
+
if (stepWithSlice(step)) {
|
|
151
|
+
return [{
|
|
152
|
+
type: 'doc',
|
|
153
|
+
content: step.slice.content.filter(el => el !== null)
|
|
154
|
+
}];
|
|
155
|
+
} else if (stepWithNextDocument(step)) {
|
|
156
|
+
return [{
|
|
157
|
+
type: 'doc',
|
|
158
|
+
content: step.nextDocument.content
|
|
159
|
+
}];
|
|
160
|
+
} else if (stepWithMark(step) && step.mark) {
|
|
161
|
+
return [{
|
|
162
|
+
type: 'doc',
|
|
163
|
+
marks: [{
|
|
164
|
+
type: step.mark.type || 'unknown',
|
|
165
|
+
attrs: step.mark.attrs
|
|
166
|
+
}]
|
|
167
|
+
}];
|
|
168
|
+
} else if (stepWithAttrs(step)) {
|
|
169
|
+
return [{
|
|
170
|
+
type: 'doc',
|
|
171
|
+
attrs: step.attrs
|
|
172
|
+
}];
|
|
173
|
+
} else if (stepWithBatchAttrs(step)) {
|
|
174
|
+
return step.data.map(stepData => {
|
|
175
|
+
return {
|
|
176
|
+
type: 'doc',
|
|
177
|
+
attrs: stepData.attrs
|
|
178
|
+
};
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return [];
|
|
53
182
|
};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
2
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
3
|
-
import {
|
|
3
|
+
import { EVENT_ACTION, EVENT_STATUS } from '../helpers/const';
|
|
4
|
+
import { createLogger, getObfuscatedSteps, getDocAdfWithObfuscation } from '../helpers/utils';
|
|
5
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
4
6
|
var logger = createLogger('Catchupv2', 'red');
|
|
5
7
|
export var catchupv2 = /*#__PURE__*/function () {
|
|
6
8
|
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(opt) {
|
|
7
|
-
var steps, metadata, fromVersion, _yield$opt$fetchCatch, _opt$analyticsHelper, _opt$onCatchupComplet, version, stepsPayload, _opt$analyticsHelper2;
|
|
9
|
+
var steps, metadata, fromVersion, _yield$opt$fetchCatch, _opt$analyticsHelper, _opt$onCatchupComplet, version, stepsPayload, clientOutOfSync, _opt$analyticsHelper2;
|
|
8
10
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
9
11
|
while (1) switch (_context.prev = _context.next) {
|
|
10
12
|
case 0:
|
|
@@ -46,23 +48,38 @@ export var catchupv2 = /*#__PURE__*/function () {
|
|
|
46
48
|
};
|
|
47
49
|
opt.onStepsAdded(stepsPayload);
|
|
48
50
|
opt.updateMetadata(metadata);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
clientOutOfSync = Boolean(opt.clientId && isOutOfSync(fromVersion, opt.getCurrentPmVersion(), steps, opt.clientId));
|
|
52
|
+
if (clientOutOfSync) {
|
|
53
|
+
logObfuscatedSteps(steps, opt);
|
|
54
|
+
}
|
|
55
|
+
return _context.abrupt("return", clientOutOfSync);
|
|
56
|
+
case 28:
|
|
57
|
+
_context.prev = 28;
|
|
52
58
|
_context.t1 = _context["catch"](14);
|
|
53
59
|
(_opt$analyticsHelper2 = opt.analyticsHelper) === null || _opt$analyticsHelper2 === void 0 || _opt$analyticsHelper2.sendErrorEvent(_context.t1, 'Failed to apply catchupv2 result in the editor');
|
|
54
60
|
logger("Apply catchupv2 steps failed:", _context.t1.message);
|
|
55
61
|
throw _context.t1;
|
|
56
|
-
case
|
|
62
|
+
case 33:
|
|
57
63
|
case "end":
|
|
58
64
|
return _context.stop();
|
|
59
65
|
}
|
|
60
|
-
}, _callee, null, [[1, 9], [14,
|
|
66
|
+
}, _callee, null, [[1, 9], [14, 28]]);
|
|
61
67
|
}));
|
|
62
68
|
return function catchupv2(_x) {
|
|
63
69
|
return _ref.apply(this, arguments);
|
|
64
70
|
};
|
|
65
71
|
}();
|
|
72
|
+
var logObfuscatedSteps = function logObfuscatedSteps(steps, opt) {
|
|
73
|
+
if (fg('platform_editor_log_obfuscated_steps')) {
|
|
74
|
+
var _opt$getState, _opt$analyticsHelper3;
|
|
75
|
+
var state = (_opt$getState = opt.getState) === null || _opt$getState === void 0 ? void 0 : _opt$getState.call(opt);
|
|
76
|
+
(_opt$analyticsHelper3 = opt.analyticsHelper) === null || _opt$analyticsHelper3 === void 0 || _opt$analyticsHelper3.sendActionEvent(EVENT_ACTION.OUT_OF_SYNC, EVENT_STATUS.FAILURE, {
|
|
77
|
+
obfuscatedSteps: getObfuscatedSteps(steps),
|
|
78
|
+
obfuscatedDoc: state ? getDocAdfWithObfuscation(state.doc) : null,
|
|
79
|
+
catchupReason: opt.reason
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
};
|
|
66
83
|
|
|
67
84
|
/**
|
|
68
85
|
* Checks if we're out of sync with the backend because catchup failed to apply, and thus the doc should be reset.
|
|
@@ -115,7 +115,8 @@ export var DocumentService = /*#__PURE__*/function () {
|
|
|
115
115
|
remoteStepsLength: (_steps$length = steps === null || steps === void 0 ? void 0 : steps.length) !== null && _steps$length !== void 0 ? _steps$length : 0
|
|
116
116
|
}));
|
|
117
117
|
}
|
|
118
|
-
}
|
|
118
|
+
},
|
|
119
|
+
getState: _this.getState
|
|
119
120
|
});
|
|
120
121
|
case 11:
|
|
121
122
|
_this.catchUpOutofSync = _context.sent;
|
|
@@ -19,8 +19,9 @@ export var EVENT_ACTION = /*#__PURE__*/function (EVENT_ACTION) {
|
|
|
19
19
|
EVENT_ACTION["RECONNECTION"] = "providerReconnection";
|
|
20
20
|
EVENT_ACTION["PROVIDER_SETUP"] = "providerSetup";
|
|
21
21
|
EVENT_ACTION["HAS_UNCONFIRMED_STEPS"] = "hasUnconfirmedSteps";
|
|
22
|
+
EVENT_ACTION["OUT_OF_SYNC"] = "outOfSync";
|
|
22
23
|
return EVENT_ACTION;
|
|
23
|
-
}({}); // https://data-portal.internal.atlassian.com/analytics/registry/
|
|
24
|
+
}({}); // https://data-portal.internal.atlassian.com/analytics/registry/74993
|
|
24
25
|
export var EVENT_STATUS = /*#__PURE__*/function (EVENT_STATUS) {
|
|
25
26
|
EVENT_STATUS["SUCCESS"] = "SUCCESS";
|
|
26
27
|
EVENT_STATUS["FAILURE"] = "FAILURE";
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
import { scrubAdf } from '@atlaskit/adf-utils/scrub';
|
|
1
5
|
export var createLogger = function createLogger(prefix) {
|
|
2
6
|
var color = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'blue';
|
|
3
7
|
return (
|
|
@@ -57,4 +61,134 @@ export var getStepUGCFreeDetails = function getStepUGCFreeDetails(step) {
|
|
|
57
61
|
contentTypes: contentTypes,
|
|
58
62
|
stepSizeInBytes: Buffer.byteLength(JSON.stringify(step))
|
|
59
63
|
};
|
|
64
|
+
};
|
|
65
|
+
var stepWithNextDocument = function stepWithNextDocument(stepJson) {
|
|
66
|
+
return stepJson.stepType === 'override-document' && 'nextDocument' in stepJson;
|
|
67
|
+
};
|
|
68
|
+
var stepWithMark = function stepWithMark(stepJson) {
|
|
69
|
+
return stepJson.stepType === 'addMark' || stepJson.stepType === 'addNodeMark';
|
|
70
|
+
};
|
|
71
|
+
var stepWithAttrs = function stepWithAttrs(stepJson) {
|
|
72
|
+
return stepJson.stepType === 'setAttrs' && 'attrs' in stepJson;
|
|
73
|
+
};
|
|
74
|
+
var stepWithBatchAttrs = function stepWithBatchAttrs(stepJson) {
|
|
75
|
+
return stepJson.stepType === 'batchAttrs' && 'data' in stepJson;
|
|
76
|
+
};
|
|
77
|
+
var stepWithFromTo = function stepWithFromTo(stepJson) {
|
|
78
|
+
return 'from' in stepJson && typeof stepJson.from === 'number' && 'to' in stepJson && typeof stepJson.to === 'number';
|
|
79
|
+
};
|
|
80
|
+
var stepWithGapFromTo = function stepWithGapFromTo(stepJson) {
|
|
81
|
+
return 'gapFrom' in stepJson && typeof stepJson.gapFrom === 'number' && 'gapTo' in stepJson && typeof stepJson.gapTo === 'number';
|
|
82
|
+
};
|
|
83
|
+
var stepWithInsert = function stepWithInsert(stepJson) {
|
|
84
|
+
return 'insert' in stepJson && typeof stepJson.insert === 'number';
|
|
85
|
+
};
|
|
86
|
+
var stepWithPos = function stepWithPos(stepJson) {
|
|
87
|
+
return 'pos' in stepJson && typeof stepJson.pos === 'number';
|
|
88
|
+
};
|
|
89
|
+
var stepWithSlice = function stepWithSlice(stepJson) {
|
|
90
|
+
var _stepJson$slice3;
|
|
91
|
+
return 'slice' in stepJson && Array.isArray((_stepJson$slice3 = stepJson.slice) === null || _stepJson$slice3 === void 0 ? void 0 : _stepJson$slice3.content);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// Get as step info which is known not to contain user generated content.
|
|
95
|
+
export var getStepTypes = function getStepTypes(stepJson) {
|
|
96
|
+
var contentTypes = null;
|
|
97
|
+
if (stepWithSlice(stepJson)) {
|
|
98
|
+
contentTypes = stepJson.slice.content.map(function (c) {
|
|
99
|
+
return (c === null || c === void 0 ? void 0 : c.type) || 'unknown';
|
|
100
|
+
}).join(', ');
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
type: stepJson.stepType || 'unknown',
|
|
104
|
+
contentTypes: contentTypes
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
export var getStepsAdfWithObfuscation = function getStepsAdfWithObfuscation(stepJson) {
|
|
108
|
+
var stepContentAsAdf = stepToAdf(stepJson);
|
|
109
|
+
if (!stepContentAsAdf) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
var scrubbedSteps = stepContentAsAdf.map(function (adf) {
|
|
113
|
+
return scrubAdf(adf);
|
|
114
|
+
}).filter(function (adf) {
|
|
115
|
+
return !!adf;
|
|
116
|
+
});
|
|
117
|
+
return scrubbedSteps;
|
|
118
|
+
};
|
|
119
|
+
export var getDocAdfWithObfuscation = function getDocAdfWithObfuscation(doc) {
|
|
120
|
+
var docJson = doc.toJSON();
|
|
121
|
+
var scrubbedDoc = scrubAdf(docJson);
|
|
122
|
+
if (!scrubbedDoc) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
return scrubbedDoc;
|
|
126
|
+
};
|
|
127
|
+
export var getStepPositions = function getStepPositions(stepJson) {
|
|
128
|
+
return _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, stepWithFromTo(stepJson) && {
|
|
129
|
+
from: stepJson.from,
|
|
130
|
+
to: stepJson.to
|
|
131
|
+
}), stepWithGapFromTo(stepJson) && {
|
|
132
|
+
gapFrom: stepJson.gapFrom,
|
|
133
|
+
gapTo: stepJson.gapTo
|
|
134
|
+
}), stepWithInsert(stepJson) && {
|
|
135
|
+
insert: stepJson.insert
|
|
136
|
+
}), stepWithPos(stepJson) && {
|
|
137
|
+
pos: stepJson.pos
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Returns the metadata for Step
|
|
143
|
+
* @description metadata is applied by transform overrides [here](https://bitbucket.org/atlassian/adf-schema/src/e13bbece84ede8f245067dc53dd7ce694f427eda/packages/editor-prosemirror/src/transform-override.ts#lines-12)
|
|
144
|
+
*/
|
|
145
|
+
var getStepMetadata = function getStepMetadata(stepJson) {
|
|
146
|
+
return stepJson.metadata;
|
|
147
|
+
};
|
|
148
|
+
export var getObfuscatedSteps = function getObfuscatedSteps(steps) {
|
|
149
|
+
var endIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
|
|
150
|
+
return steps.slice(0, endIndex).map(function (step) {
|
|
151
|
+
return {
|
|
152
|
+
stepType: getStepTypes(step),
|
|
153
|
+
stepContent: getStepsAdfWithObfuscation(step),
|
|
154
|
+
stepPositions: getStepPositions(step),
|
|
155
|
+
stepMetadata: getStepMetadata(step)
|
|
156
|
+
};
|
|
157
|
+
});
|
|
158
|
+
};
|
|
159
|
+
var stepToAdf = function stepToAdf(step) {
|
|
160
|
+
if (stepWithSlice(step)) {
|
|
161
|
+
return [{
|
|
162
|
+
type: 'doc',
|
|
163
|
+
content: step.slice.content.filter(function (el) {
|
|
164
|
+
return el !== null;
|
|
165
|
+
})
|
|
166
|
+
}];
|
|
167
|
+
} else if (stepWithNextDocument(step)) {
|
|
168
|
+
return [{
|
|
169
|
+
type: 'doc',
|
|
170
|
+
content: step.nextDocument.content
|
|
171
|
+
}];
|
|
172
|
+
} else if (stepWithMark(step) && step.mark) {
|
|
173
|
+
return [{
|
|
174
|
+
type: 'doc',
|
|
175
|
+
marks: [{
|
|
176
|
+
type: step.mark.type || 'unknown',
|
|
177
|
+
attrs: step.mark.attrs
|
|
178
|
+
}]
|
|
179
|
+
}];
|
|
180
|
+
} else if (stepWithAttrs(step)) {
|
|
181
|
+
return [{
|
|
182
|
+
type: 'doc',
|
|
183
|
+
attrs: step.attrs
|
|
184
|
+
}];
|
|
185
|
+
} else if (stepWithBatchAttrs(step)) {
|
|
186
|
+
return step.data.map(function (stepData) {
|
|
187
|
+
return {
|
|
188
|
+
type: 'doc',
|
|
189
|
+
attrs: stepData.attrs
|
|
190
|
+
};
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
return [];
|
|
60
194
|
};
|
|
@@ -19,7 +19,8 @@ export declare enum EVENT_ACTION {
|
|
|
19
19
|
PROVIDER_INITIALIZED = "providerInitialized",// https://data-portal.internal.atlassian.com/analytics/registry/54714
|
|
20
20
|
RECONNECTION = "providerReconnection",// https://data-portal.internal.atlassian.com/analytics/registry/73992
|
|
21
21
|
PROVIDER_SETUP = "providerSetup",// https://data-portal.internal.atlassian.com/analytics/registry/54715
|
|
22
|
-
HAS_UNCONFIRMED_STEPS = "hasUnconfirmedSteps"
|
|
22
|
+
HAS_UNCONFIRMED_STEPS = "hasUnconfirmedSteps",// https://data-portal.internal.atlassian.com/analytics/registry/56141
|
|
23
|
+
OUT_OF_SYNC = "outOfSync"
|
|
23
24
|
}
|
|
24
25
|
export declare enum EVENT_STATUS {
|
|
25
26
|
SUCCESS = "SUCCESS",
|
|
@@ -261,7 +262,20 @@ type ReconnectionAnalyticsEvent = {
|
|
|
261
262
|
disconnectionPeriodSeconds: number;
|
|
262
263
|
} & BaseActionAnalyticsEventAttributes;
|
|
263
264
|
};
|
|
264
|
-
|
|
265
|
+
type OutOfSyncAnalyticsEvent = {
|
|
266
|
+
eventAction: EVENT_ACTION.OUT_OF_SYNC;
|
|
267
|
+
attributes: {
|
|
268
|
+
eventStatus: EVENT_STATUS.FAILURE;
|
|
269
|
+
obfuscatedSteps: {
|
|
270
|
+
[key: string]: number;
|
|
271
|
+
}[];
|
|
272
|
+
obfuscatedDoc: {
|
|
273
|
+
[key: string]: number;
|
|
274
|
+
};
|
|
275
|
+
catchupReason: CatchupEventReason | undefined;
|
|
276
|
+
} & BaseActionAnalyticsEventAttributes;
|
|
277
|
+
};
|
|
278
|
+
export type ActionAnalyticsEvent = AddStepsSuccessAnalyticsEvent | AddStepsFailureAnalyticsEvent | ReInitDocFailAnalyticsEvent | ReInitDocSuccessAnalyticsEvent | ConnectionSuccessAnalyticsEvent | ConnectionFailureAnalyticsEvent | CatchUpSuccessAnalyticsEvent | CatchUpFailureAnalyticsEvent | DocumentInitSuccessAnalyticsEvent | UpdateParticipantsSuccessAnalyticsEvent | CommitUnconfirmedStepsSuccessAnalyticsEvent | CommitUnconfirmedStepsFailureAnalyticsEvent | PublishPageSuccessAnalyticsEvent | PublishPageFailureAnalyticsEvent | GetCurrentStateSuccessAnalyticsEvent | GetCurrentStateFailureAnalyticsEvent | InvalidateTokenAnalyticsEvent | SendStepsRetryAnalyticsEvent | CatchupAfterMaxSendStepsRetryAnalyticsEvent | CatchUpDroppedStepsEvent | WebsocketMessageVolumeMetricEvent | ProviderInitializedAnalyticsEvent | ProviderSetupAnalyticsEvent | ProviderHasUnconfirmedStepsAnalyticsEvent | UpdateDocumentAnalyticsEvent | ReconnectionAnalyticsEvent | OutOfSyncAnalyticsEvent;
|
|
265
279
|
export declare const ACK_MAX_TRY = 60;
|
|
266
280
|
export declare const CONFLUENCE = "confluence";
|
|
267
281
|
/** Enumerable for attaching a reason to catchup (v2) call(s) */
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { type ADFEntity } from '@atlaskit/adf-utils/types';
|
|
1
2
|
import type { ProductInformation } from '../types';
|
|
2
3
|
import type { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
|
|
4
|
+
import type { StepJson } from '@atlaskit/editor-common/collab';
|
|
5
|
+
import type { Node as ProseMirrorNode } from '@atlaskit/editor-prosemirror/model';
|
|
3
6
|
export declare const createLogger: (prefix: string, color?: string) => (msg: string, data?: any) => void;
|
|
4
7
|
export declare function sleep(ms: number): Promise<unknown>;
|
|
5
8
|
export declare const isAIProviderID: (id: string) => boolean;
|
|
@@ -11,3 +14,41 @@ export type UGCFreeStepDetails = {
|
|
|
11
14
|
stepSizeInBytes?: number;
|
|
12
15
|
};
|
|
13
16
|
export declare const getStepUGCFreeDetails: (step: ProseMirrorStep) => UGCFreeStepDetails;
|
|
17
|
+
export declare const getStepTypes: (stepJson: StepJson) => {
|
|
18
|
+
type: string;
|
|
19
|
+
contentTypes: string | null;
|
|
20
|
+
};
|
|
21
|
+
export declare const getStepsAdfWithObfuscation: (stepJson: StepJson) => ADFEntity[] | null;
|
|
22
|
+
export declare const getDocAdfWithObfuscation: (doc: ProseMirrorNode) => ADFEntity | null;
|
|
23
|
+
export declare const getStepPositions: (stepJson: StepJson) => {
|
|
24
|
+
pos?: number | undefined;
|
|
25
|
+
insert?: number | undefined;
|
|
26
|
+
gapFrom?: number | undefined;
|
|
27
|
+
gapTo?: number | undefined;
|
|
28
|
+
from?: number | undefined;
|
|
29
|
+
to?: number | undefined;
|
|
30
|
+
};
|
|
31
|
+
export declare const getObfuscatedSteps: (steps: StepJson[], endIndex?: number | undefined) => {
|
|
32
|
+
stepType: {
|
|
33
|
+
type: string;
|
|
34
|
+
contentTypes: string | null;
|
|
35
|
+
};
|
|
36
|
+
stepContent: ADFEntity[] | null;
|
|
37
|
+
stepPositions: {
|
|
38
|
+
pos?: number | undefined;
|
|
39
|
+
insert?: number | undefined;
|
|
40
|
+
gapFrom?: number | undefined;
|
|
41
|
+
gapTo?: number | undefined;
|
|
42
|
+
from?: number | undefined;
|
|
43
|
+
to?: number | undefined;
|
|
44
|
+
};
|
|
45
|
+
stepMetadata: {
|
|
46
|
+
source?: string | undefined;
|
|
47
|
+
stepId?: string | undefined;
|
|
48
|
+
prevStepId?: string | undefined;
|
|
49
|
+
rebased?: boolean | undefined;
|
|
50
|
+
traceId?: string | undefined;
|
|
51
|
+
reqId?: string | undefined;
|
|
52
|
+
schemaVersion?: string | undefined;
|
|
53
|
+
} | undefined;
|
|
54
|
+
}[];
|
package/dist/types/types.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Step } from '@atlaskit/editor-prosemirror/transform';
|
|
2
1
|
import type { AnalyticsWebClient } from '@atlaskit/analytics-listeners';
|
|
3
2
|
import type { Manager, Socket as SocketIOSocket } from 'socket.io-client';
|
|
4
3
|
import type { InternalError } from './errors/internal-errors';
|
|
@@ -7,6 +6,7 @@ import type { GetUserType } from './participants/participants-helper';
|
|
|
7
6
|
import type AnalyticsHelper from './analytics/analytics-helper';
|
|
8
7
|
import type { StepJson, CollabSendableSelection, Metadata, UserPermitType, Activity, PresenceActivity } from '@atlaskit/editor-common/collab';
|
|
9
8
|
import { type CatchupEventReason } from './helpers/const';
|
|
9
|
+
import type { EditorState } from '@atlaskit/editor-prosemirror/state';
|
|
10
10
|
export interface CollabEventDisconnectedData {
|
|
11
11
|
sid: string;
|
|
12
12
|
reason: 'CLIENT_DISCONNECT' | 'SERVER_DISCONNECT' | 'SOCKET_CLOSED' | 'SOCKET_ERROR' | 'SOCKET_TIMEOUT' | 'UNKNOWN_DISCONNECT';
|
|
@@ -199,7 +199,7 @@ export type ChannelEvent = {
|
|
|
199
199
|
status: NamespaceStatus;
|
|
200
200
|
};
|
|
201
201
|
export interface Catchupv2Response {
|
|
202
|
-
steps?:
|
|
202
|
+
steps?: StepJson[];
|
|
203
203
|
metadata?: Metadata;
|
|
204
204
|
}
|
|
205
205
|
export interface ReconcileResponse {
|
|
@@ -218,6 +218,7 @@ export interface Catchupv2Options {
|
|
|
218
218
|
catchUpOutofSync: boolean;
|
|
219
219
|
reason?: CatchupEventReason;
|
|
220
220
|
onCatchupComplete?: (steps: StepJson[]) => void;
|
|
221
|
+
getState: (() => EditorState) | undefined;
|
|
221
222
|
}
|
|
222
223
|
export type ReconnectionMetadata = {
|
|
223
224
|
unconfirmedStepsLength: number | undefined;
|
|
@@ -19,7 +19,8 @@ export declare enum EVENT_ACTION {
|
|
|
19
19
|
PROVIDER_INITIALIZED = "providerInitialized",// https://data-portal.internal.atlassian.com/analytics/registry/54714
|
|
20
20
|
RECONNECTION = "providerReconnection",// https://data-portal.internal.atlassian.com/analytics/registry/73992
|
|
21
21
|
PROVIDER_SETUP = "providerSetup",// https://data-portal.internal.atlassian.com/analytics/registry/54715
|
|
22
|
-
HAS_UNCONFIRMED_STEPS = "hasUnconfirmedSteps"
|
|
22
|
+
HAS_UNCONFIRMED_STEPS = "hasUnconfirmedSteps",// https://data-portal.internal.atlassian.com/analytics/registry/56141
|
|
23
|
+
OUT_OF_SYNC = "outOfSync"
|
|
23
24
|
}
|
|
24
25
|
export declare enum EVENT_STATUS {
|
|
25
26
|
SUCCESS = "SUCCESS",
|
|
@@ -261,7 +262,20 @@ type ReconnectionAnalyticsEvent = {
|
|
|
261
262
|
disconnectionPeriodSeconds: number;
|
|
262
263
|
} & BaseActionAnalyticsEventAttributes;
|
|
263
264
|
};
|
|
264
|
-
|
|
265
|
+
type OutOfSyncAnalyticsEvent = {
|
|
266
|
+
eventAction: EVENT_ACTION.OUT_OF_SYNC;
|
|
267
|
+
attributes: {
|
|
268
|
+
eventStatus: EVENT_STATUS.FAILURE;
|
|
269
|
+
obfuscatedSteps: {
|
|
270
|
+
[key: string]: number;
|
|
271
|
+
}[];
|
|
272
|
+
obfuscatedDoc: {
|
|
273
|
+
[key: string]: number;
|
|
274
|
+
};
|
|
275
|
+
catchupReason: CatchupEventReason | undefined;
|
|
276
|
+
} & BaseActionAnalyticsEventAttributes;
|
|
277
|
+
};
|
|
278
|
+
export type ActionAnalyticsEvent = AddStepsSuccessAnalyticsEvent | AddStepsFailureAnalyticsEvent | ReInitDocFailAnalyticsEvent | ReInitDocSuccessAnalyticsEvent | ConnectionSuccessAnalyticsEvent | ConnectionFailureAnalyticsEvent | CatchUpSuccessAnalyticsEvent | CatchUpFailureAnalyticsEvent | DocumentInitSuccessAnalyticsEvent | UpdateParticipantsSuccessAnalyticsEvent | CommitUnconfirmedStepsSuccessAnalyticsEvent | CommitUnconfirmedStepsFailureAnalyticsEvent | PublishPageSuccessAnalyticsEvent | PublishPageFailureAnalyticsEvent | GetCurrentStateSuccessAnalyticsEvent | GetCurrentStateFailureAnalyticsEvent | InvalidateTokenAnalyticsEvent | SendStepsRetryAnalyticsEvent | CatchupAfterMaxSendStepsRetryAnalyticsEvent | CatchUpDroppedStepsEvent | WebsocketMessageVolumeMetricEvent | ProviderInitializedAnalyticsEvent | ProviderSetupAnalyticsEvent | ProviderHasUnconfirmedStepsAnalyticsEvent | UpdateDocumentAnalyticsEvent | ReconnectionAnalyticsEvent | OutOfSyncAnalyticsEvent;
|
|
265
279
|
export declare const ACK_MAX_TRY = 60;
|
|
266
280
|
export declare const CONFLUENCE = "confluence";
|
|
267
281
|
/** Enumerable for attaching a reason to catchup (v2) call(s) */
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { type ADFEntity } from '@atlaskit/adf-utils/types';
|
|
1
2
|
import type { ProductInformation } from '../types';
|
|
2
3
|
import type { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
|
|
4
|
+
import type { StepJson } from '@atlaskit/editor-common/collab';
|
|
5
|
+
import type { Node as ProseMirrorNode } from '@atlaskit/editor-prosemirror/model';
|
|
3
6
|
export declare const createLogger: (prefix: string, color?: string) => (msg: string, data?: any) => void;
|
|
4
7
|
export declare function sleep(ms: number): Promise<unknown>;
|
|
5
8
|
export declare const isAIProviderID: (id: string) => boolean;
|
|
@@ -11,3 +14,41 @@ export type UGCFreeStepDetails = {
|
|
|
11
14
|
stepSizeInBytes?: number;
|
|
12
15
|
};
|
|
13
16
|
export declare const getStepUGCFreeDetails: (step: ProseMirrorStep) => UGCFreeStepDetails;
|
|
17
|
+
export declare const getStepTypes: (stepJson: StepJson) => {
|
|
18
|
+
type: string;
|
|
19
|
+
contentTypes: string | null;
|
|
20
|
+
};
|
|
21
|
+
export declare const getStepsAdfWithObfuscation: (stepJson: StepJson) => ADFEntity[] | null;
|
|
22
|
+
export declare const getDocAdfWithObfuscation: (doc: ProseMirrorNode) => ADFEntity | null;
|
|
23
|
+
export declare const getStepPositions: (stepJson: StepJson) => {
|
|
24
|
+
pos?: number | undefined;
|
|
25
|
+
insert?: number | undefined;
|
|
26
|
+
gapFrom?: number | undefined;
|
|
27
|
+
gapTo?: number | undefined;
|
|
28
|
+
from?: number | undefined;
|
|
29
|
+
to?: number | undefined;
|
|
30
|
+
};
|
|
31
|
+
export declare const getObfuscatedSteps: (steps: StepJson[], endIndex?: number | undefined) => {
|
|
32
|
+
stepType: {
|
|
33
|
+
type: string;
|
|
34
|
+
contentTypes: string | null;
|
|
35
|
+
};
|
|
36
|
+
stepContent: ADFEntity[] | null;
|
|
37
|
+
stepPositions: {
|
|
38
|
+
pos?: number | undefined;
|
|
39
|
+
insert?: number | undefined;
|
|
40
|
+
gapFrom?: number | undefined;
|
|
41
|
+
gapTo?: number | undefined;
|
|
42
|
+
from?: number | undefined;
|
|
43
|
+
to?: number | undefined;
|
|
44
|
+
};
|
|
45
|
+
stepMetadata: {
|
|
46
|
+
source?: string | undefined;
|
|
47
|
+
stepId?: string | undefined;
|
|
48
|
+
prevStepId?: string | undefined;
|
|
49
|
+
rebased?: boolean | undefined;
|
|
50
|
+
traceId?: string | undefined;
|
|
51
|
+
reqId?: string | undefined;
|
|
52
|
+
schemaVersion?: string | undefined;
|
|
53
|
+
} | undefined;
|
|
54
|
+
}[];
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Step } from '@atlaskit/editor-prosemirror/transform';
|
|
2
1
|
import type { AnalyticsWebClient } from '@atlaskit/analytics-listeners';
|
|
3
2
|
import type { Manager, Socket as SocketIOSocket } from 'socket.io-client';
|
|
4
3
|
import type { InternalError } from './errors/internal-errors';
|
|
@@ -7,6 +6,7 @@ import type { GetUserType } from './participants/participants-helper';
|
|
|
7
6
|
import type AnalyticsHelper from './analytics/analytics-helper';
|
|
8
7
|
import type { StepJson, CollabSendableSelection, Metadata, UserPermitType, Activity, PresenceActivity } from '@atlaskit/editor-common/collab';
|
|
9
8
|
import { type CatchupEventReason } from './helpers/const';
|
|
9
|
+
import type { EditorState } from '@atlaskit/editor-prosemirror/state';
|
|
10
10
|
export interface CollabEventDisconnectedData {
|
|
11
11
|
sid: string;
|
|
12
12
|
reason: 'CLIENT_DISCONNECT' | 'SERVER_DISCONNECT' | 'SOCKET_CLOSED' | 'SOCKET_ERROR' | 'SOCKET_TIMEOUT' | 'UNKNOWN_DISCONNECT';
|
|
@@ -199,7 +199,7 @@ export type ChannelEvent = {
|
|
|
199
199
|
status: NamespaceStatus;
|
|
200
200
|
};
|
|
201
201
|
export interface Catchupv2Response {
|
|
202
|
-
steps?:
|
|
202
|
+
steps?: StepJson[];
|
|
203
203
|
metadata?: Metadata;
|
|
204
204
|
}
|
|
205
205
|
export interface ReconcileResponse {
|
|
@@ -218,6 +218,7 @@ export interface Catchupv2Options {
|
|
|
218
218
|
catchUpOutofSync: boolean;
|
|
219
219
|
reason?: CatchupEventReason;
|
|
220
220
|
onCatchupComplete?: (steps: StepJson[]) => void;
|
|
221
|
+
getState: (() => EditorState) | undefined;
|
|
221
222
|
}
|
|
222
223
|
export type ReconnectionMetadata = {
|
|
223
224
|
unconfirmedStepsLength: number | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/collab-provider",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.4.0",
|
|
4
4
|
"description": "A provider for collaborative editing.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -32,9 +32,10 @@
|
|
|
32
32
|
"./version-wrapper": "./src/version-wrapper.ts"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
+
"@atlaskit/adf-utils": "^19.17.0",
|
|
35
36
|
"@atlaskit/analytics-gas-types": "^5.1.0",
|
|
36
37
|
"@atlaskit/analytics-listeners": "^8.13.0",
|
|
37
|
-
"@atlaskit/editor-common": "^
|
|
38
|
+
"@atlaskit/editor-common": "^99.2.0",
|
|
38
39
|
"@atlaskit/editor-json-transformer": "^8.21.0",
|
|
39
40
|
"@atlaskit/editor-prosemirror": "6.2.1",
|
|
40
41
|
"@atlaskit/feature-gate-js-client": "^4.22.0",
|
|
@@ -71,6 +72,9 @@
|
|
|
71
72
|
"platform.editor.live-pages-expand-divergence": {
|
|
72
73
|
"type": "boolean"
|
|
73
74
|
},
|
|
75
|
+
"platform_editor_log_obfuscated_steps": {
|
|
76
|
+
"type": "boolean"
|
|
77
|
+
},
|
|
74
78
|
"platform_editor_merge_unconfirmed_steps": {
|
|
75
79
|
"type": "boolean"
|
|
76
80
|
},
|