@atlaskit/collab-provider 14.1.1 → 14.2.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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # @atlaskit/collab-provider
2
2
 
3
+ ## 14.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`081b4e257529b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/081b4e257529b) -
8
+ Support sharded routing for collab presence socket connections
9
+
10
+ ### Patch Changes
11
+
12
+ - Updated dependencies
13
+
14
+ ## 14.1.2
15
+
16
+ ### Patch Changes
17
+
18
+ - [`0d4df322f7f0b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0d4df322f7f0b) -
19
+ Add additional offline analytics on reconnection
20
+
3
21
  ## 14.1.1
4
22
 
5
23
  ### Patch Changes
@@ -5,7 +5,8 @@
5
5
  "target": "es5",
6
6
  "outDir": "../../../../../confluence/tsDist/@atlaskit__collab-provider",
7
7
  "rootDir": "../",
8
- "composite": true
8
+ "composite": true,
9
+ "noCheck": true
9
10
  },
10
11
  "include": [
11
12
  "../src/**/*.ts",
@@ -35,6 +36,9 @@
35
36
  {
36
37
  "path": "../../../elements/anonymous-assets/afm-cc/tsconfig.json"
37
38
  },
39
+ {
40
+ "path": "../../../uip/atlassian-context/afm-cc/tsconfig.json"
41
+ },
38
42
  {
39
43
  "path": "../../editor-json-transformer/afm-cc/tsconfig.json"
40
44
  },
@@ -5,7 +5,8 @@
5
5
  "target": "es5",
6
6
  "outDir": "../../../../../jira/tsDist/@atlaskit__collab-provider/app",
7
7
  "rootDir": "../",
8
- "composite": true
8
+ "composite": true,
9
+ "noCheck": true
9
10
  },
10
11
  "include": [
11
12
  "../src/**/*.ts",
@@ -35,6 +36,9 @@
35
36
  {
36
37
  "path": "../../../elements/anonymous-assets/afm-jira/tsconfig.json"
37
38
  },
39
+ {
40
+ "path": "../../../uip/atlassian-context/afm-jira/tsconfig.json"
41
+ },
38
42
  {
39
43
  "path": "../../editor-json-transformer/afm-jira/tsconfig.json"
40
44
  },
@@ -546,10 +546,10 @@ var Channel = exports.Channel = /*#__PURE__*/function (_Emitter) {
546
546
  }
547
547
  var _this$config = this.config,
548
548
  documentAri = _this$config.documentAri,
549
- url = _this$config.url;
550
- var _this$config2 = this.config,
551
- createSocket = _this$config2.createSocket,
552
- permissionTokenRefresh = _this$config2.permissionTokenRefresh;
549
+ url = _this$config.url,
550
+ path = _this$config.path,
551
+ createSocket = _this$config.createSocket,
552
+ permissionTokenRefresh = _this$config.permissionTokenRefresh;
553
553
  var auth;
554
554
  if (permissionTokenRefresh) {
555
555
  auth = /*#__PURE__*/function () {
@@ -635,7 +635,7 @@ var Channel = exports.Channel = /*#__PURE__*/function (_Emitter) {
635
635
  };
636
636
  }();
637
637
  }
638
- this.socket = createSocket("".concat(url, "/session/").concat(documentAri), auth, this.config.productInfo, this.config.isPresenceOnly, this.analyticsHelper);
638
+ this.socket = createSocket("".concat(url, "/session/").concat(documentAri), auth, this.config.productInfo, this.config.isPresenceOnly, this.analyticsHelper, path);
639
639
 
640
640
  // Due to https://github.com/socketio/socket.io-client/issues/1473,
641
641
  // reconnect no longer fired on the socket.
@@ -733,7 +733,7 @@ var Channel = exports.Channel = /*#__PURE__*/function (_Emitter) {
733
733
  // Ensure the error emit to the provider has the same structure, so we can handle them unified.
734
734
  this.socket.on('connect_error', this.onConnectError);
735
735
  this.socket.on('permission:invalidateToken', this.handlePermissionInvalidateToken);
736
- this.socket.onAnyOutgoing(function (_event) {
736
+ this.socket.onAnyOutgoing(function (_) {
737
737
  for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
738
738
  args[_key - 1] = arguments[_key];
739
739
  }
@@ -59,6 +59,11 @@ var NullDocumentService = exports.NullDocumentService = /*#__PURE__*/function ()
59
59
  value: function getUnconfirmedSteps() {
60
60
  return undefined;
61
61
  }
62
+ }, {
63
+ key: "getUnconfirmedStepsOrigins",
64
+ value: function getUnconfirmedStepsOrigins() {
65
+ return undefined;
66
+ }
62
67
  }, {
63
68
  key: "getCurrentPmVersion",
64
69
  value: function getCurrentPmVersion() {
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getOfflineReplaceStepsLength = getOfflineReplaceStepsLength;
7
+ exports.getOfflineStepsLength = getOfflineStepsLength;
8
+ var _transform = require("@atlaskit/editor-prosemirror/transform");
9
+ function getOfflineSteps(steps, origins) {
10
+ if (!steps || !origins || steps.length !== origins.length) {
11
+ return undefined;
12
+ }
13
+ if (origins.some(function (s) {
14
+ return (s === null || s === void 0 ? void 0 : s.getMeta('isOffline')) === true || (s === null || s === void 0 ? void 0 : s.getMeta('wasOffline')) === true;
15
+ })) {
16
+ var mapped = steps.filter(function (step, idx) {
17
+ var origin = origins[idx];
18
+ if (!origin) {
19
+ return false;
20
+ }
21
+ var createdOffline = origin.getMeta('isOffline') || origin.getMeta('wasOffline');
22
+ return createdOffline;
23
+ });
24
+ return mapped;
25
+ }
26
+ }
27
+ function getOfflineStepsLength(steps, origins) {
28
+ var _getOfflineSteps;
29
+ return (_getOfflineSteps = getOfflineSteps(steps, origins)) === null || _getOfflineSteps === void 0 ? void 0 : _getOfflineSteps.length;
30
+ }
31
+ function getOfflineReplaceStepsLength(steps, origins) {
32
+ var _getOfflineSteps2;
33
+ return (_getOfflineSteps2 = getOfflineSteps(steps, origins)) === null || _getOfflineSteps2 === void 0 ? void 0 : _getOfflineSteps2.filter(function (s) {
34
+ return s instanceof _transform.ReplaceStep;
35
+ }).length;
36
+ }
@@ -17,6 +17,7 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
17
17
  var _uuid = require("uuid");
18
18
  var _emitter = require("../emitter");
19
19
  var _channel = require("../channel");
20
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
20
21
  var _utils = require("../helpers/utils");
21
22
  var _analyticsHelper = _interopRequireDefault(require("../analytics/analytics-helper"));
22
23
  var _telepointersHelper = require("../participants/telepointers-helper");
@@ -34,6 +35,7 @@ var _api = require("../api/api");
34
35
  var _performance = require("../analytics/performance");
35
36
  var _nullApi = require("../api/null-api");
36
37
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
38
+ var _getOfflineStepsLength = require("./get-offline-steps-length");
37
39
  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; }
38
40
  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; }
39
41
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
@@ -146,6 +148,8 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
146
148
  Date.now() - _this.disconnectedAt >= OUT_OF_SYNC_PERIOD) {
147
149
  _this.documentService.throttledCatchupv2(_const.CatchupEventReason.RECONNECTED, {
148
150
  disconnectionPeriodSeconds: Math.floor((Date.now() - _this.disconnectedAt) / 1000),
151
+ offlineStepsLength: (0, _experiments.editorExperiment)('platform_editor_offline_editing_web', true) ? (0, _getOfflineStepsLength.getOfflineStepsLength)(_this.documentService.getUnconfirmedSteps(), _this.documentService.getUnconfirmedStepsOrigins()) : undefined,
152
+ offlineReplaceStepsLength: (0, _experiments.editorExperiment)('platform_editor_offline_editing_web', true) ? (0, _getOfflineStepsLength.getOfflineReplaceStepsLength)(_this.documentService.getUnconfirmedSteps(), _this.documentService.getUnconfirmedStepsOrigins()) : undefined,
149
153
  unconfirmedStepsLength: unconfirmedStepsLength
150
154
  }, (0, _platformFeatureFlags.fg)('add_session_id_to_catchup_query') ? _this.sessionId : undefined);
151
155
  }
@@ -9,17 +9,21 @@ exports.createSocketIOSocket = createSocketIOSocket;
9
9
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
10
  var _socket = require("socket.io-client");
11
11
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
12
+ var _atlassianContext = require("@atlaskit/atlassian-context");
13
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
12
14
  var _provider = require("./provider");
13
15
  var _utils = require("./helpers/utils");
14
16
  var _config = require("./config");
15
17
  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; }
16
18
  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; }
17
- function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, analyticsHelper) {
19
+ function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, analyticsHelper, path) {
18
20
  var _URL = new URL(url),
19
21
  pathname = _URL.pathname;
20
22
  var socketIOOptions = _config.SOCKET_IO_OPTIONS;
21
23
  // Polling first
22
24
  var transports = ['polling', 'websocket'];
25
+ var usePMR = false;
26
+
23
27
  // Limit this change to Presence only
24
28
  if (isPresenceOnly) {
25
29
  if ((0, _platformFeatureFlags.fg)('platform-editor-presence-websocket-only')) {
@@ -28,6 +32,9 @@ function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, analyticsH
28
32
  transports = ['websocket'];
29
33
  }
30
34
  socketIOOptions = _config.SOCKET_IO_OPTIONS_WITH_HIGH_JITTER;
35
+ if ((0, _atlassianContext.isIsolatedCloud)() && (0, _expValEquals.expValEquals)('platform_editor_use_pmr_for_collab_presence_in_ic', 'isEnabled', true, false) || !(0, _atlassianContext.isIsolatedCloud)() && (0, _expValEquals.expValEquals)('platform_editor_use_pmr_for_collab_presence_non_ic', 'isEnabled', true, false)) {
36
+ usePMR = true;
37
+ }
31
38
  }
32
39
  var client = (0, _socket.io)(url, {
33
40
  reconnectionDelayMax: socketIOOptions.RECONNECTION_DELAY_MAX,
@@ -36,7 +43,7 @@ function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, analyticsH
36
43
  closeOnBeforeunload: false,
37
44
  withCredentials: true,
38
45
  transports: transports,
39
- path: "/".concat(pathname.split('/')[1], "/socket.io"),
46
+ path: usePMR && path ? "".concat(path, "/socket.io") : "/".concat(pathname.split('/')[1], "/socket.io"),
40
47
  auth: auth,
41
48
  extraHeaders: {
42
49
  'x-product': (0, _utils.getProduct)(productInfo),
@@ -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 = "0.0.0-development";
8
+ var version = exports.version = "14.1.2";
9
9
  var nextMajorVersion = exports.nextMajorVersion = function nextMajorVersion() {
10
10
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
11
11
  };
@@ -389,9 +389,8 @@ export class Channel extends Emitter {
389
389
  }
390
390
  const {
391
391
  documentAri,
392
- url
393
- } = this.config;
394
- const {
392
+ url,
393
+ path,
395
394
  createSocket,
396
395
  permissionTokenRefresh
397
396
  } = this.config;
@@ -447,7 +446,7 @@ export class Channel extends Emitter {
447
446
  cb(authData);
448
447
  };
449
448
  }
450
- this.socket = createSocket(`${url}/session/${documentAri}`, auth, this.config.productInfo, this.config.isPresenceOnly, this.analyticsHelper);
449
+ this.socket = createSocket(`${url}/session/${documentAri}`, auth, this.config.productInfo, this.config.isPresenceOnly, this.analyticsHelper, path);
451
450
 
452
451
  // Due to https://github.com/socketio/socket.io-client/issues/1473,
453
452
  // reconnect no longer fired on the socket.
@@ -536,7 +535,7 @@ export class Channel extends Emitter {
536
535
  // Ensure the error emit to the provider has the same structure, so we can handle them unified.
537
536
  this.socket.on('connect_error', this.onConnectError);
538
537
  this.socket.on('permission:invalidateToken', this.handlePermissionInvalidateToken);
539
- this.socket.onAnyOutgoing((_event, ...args) => this.onAnyOutgoingHandler(Date.now(), args));
538
+ this.socket.onAnyOutgoing((_, ...args) => this.onAnyOutgoingHandler(Date.now(), args));
540
539
 
541
540
  // To trigger reconnection when browser comes back online
542
541
  if (!this.network) {
@@ -26,6 +26,9 @@ export class NullDocumentService {
26
26
  getUnconfirmedSteps() {
27
27
  return undefined;
28
28
  }
29
+ getUnconfirmedStepsOrigins() {
30
+ return undefined;
31
+ }
29
32
  getCurrentPmVersion() {
30
33
  return -1;
31
34
  }
@@ -0,0 +1,25 @@
1
+ import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
2
+ function getOfflineSteps(steps, origins) {
3
+ if (!steps || !origins || steps.length !== origins.length) {
4
+ return undefined;
5
+ }
6
+ if (origins.some(s => (s === null || s === void 0 ? void 0 : s.getMeta('isOffline')) === true || (s === null || s === void 0 ? void 0 : s.getMeta('wasOffline')) === true)) {
7
+ const mapped = steps.filter((step, idx) => {
8
+ const origin = origins[idx];
9
+ if (!origin) {
10
+ return false;
11
+ }
12
+ const createdOffline = origin.getMeta('isOffline') || origin.getMeta('wasOffline');
13
+ return createdOffline;
14
+ });
15
+ return mapped;
16
+ }
17
+ }
18
+ export function getOfflineStepsLength(steps, origins) {
19
+ var _getOfflineSteps;
20
+ return (_getOfflineSteps = getOfflineSteps(steps, origins)) === null || _getOfflineSteps === void 0 ? void 0 : _getOfflineSteps.length;
21
+ }
22
+ export function getOfflineReplaceStepsLength(steps, origins) {
23
+ var _getOfflineSteps2;
24
+ return (_getOfflineSteps2 = getOfflineSteps(steps, origins)) === null || _getOfflineSteps2 === void 0 ? void 0 : _getOfflineSteps2.filter(s => s instanceof ReplaceStep).length;
25
+ }
@@ -3,6 +3,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
3
  import { v4 as uuidv4 } from 'uuid';
4
4
  import { Emitter } from '../emitter';
5
5
  import { Channel } from '../channel';
6
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
6
7
  import { createLogger, logObfuscatedSteps } from '../helpers/utils';
7
8
  import AnalyticsHelper from '../analytics/analytics-helper';
8
9
  import { telepointerCallback } from '../participants/telepointers-helper';
@@ -20,6 +21,7 @@ import { Api } from '../api/api';
20
21
  import { shouldTelepointerBeSampled } from '../analytics/performance';
21
22
  import { NullApi } from '../api/null-api';
22
23
  import { fg } from '@atlaskit/platform-feature-flags';
24
+ import { getOfflineStepsLength, getOfflineReplaceStepsLength } from './get-offline-steps-length';
23
25
  const logger = createLogger('Provider', 'black');
24
26
  const OUT_OF_SYNC_PERIOD = 3 * 1000; // 3 seconds
25
27
 
@@ -126,6 +128,8 @@ export class Provider extends Emitter {
126
128
  Date.now() - this.disconnectedAt >= OUT_OF_SYNC_PERIOD) {
127
129
  this.documentService.throttledCatchupv2(CatchupEventReason.RECONNECTED, {
128
130
  disconnectionPeriodSeconds: Math.floor((Date.now() - this.disconnectedAt) / 1000),
131
+ offlineStepsLength: editorExperiment('platform_editor_offline_editing_web', true) ? getOfflineStepsLength(this.documentService.getUnconfirmedSteps(), this.documentService.getUnconfirmedStepsOrigins()) : undefined,
132
+ offlineReplaceStepsLength: editorExperiment('platform_editor_offline_editing_web', true) ? getOfflineReplaceStepsLength(this.documentService.getUnconfirmedSteps(), this.documentService.getUnconfirmedStepsOrigins()) : undefined,
129
133
  unconfirmedStepsLength: unconfirmedStepsLength
130
134
  }, fg('add_session_id_to_catchup_query') ? this.sessionId : undefined);
131
135
  }
@@ -1,15 +1,19 @@
1
1
  import { io } from 'socket.io-client';
2
2
  import { fg } from '@atlaskit/platform-feature-flags';
3
+ import { isIsolatedCloud } from '@atlaskit/atlassian-context';
4
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
3
5
  import { Provider } from './provider';
4
6
  import { getProduct, getSubProduct } from './helpers/utils';
5
7
  import { SOCKET_IO_OPTIONS, SOCKET_IO_OPTIONS_WITH_HIGH_JITTER } from './config';
6
- export function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, analyticsHelper) {
8
+ export function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, analyticsHelper, path) {
7
9
  const {
8
10
  pathname
9
11
  } = new URL(url);
10
12
  let socketIOOptions = SOCKET_IO_OPTIONS;
11
13
  // Polling first
12
14
  let transports = ['polling', 'websocket'];
15
+ let usePMR = false;
16
+
13
17
  // Limit this change to Presence only
14
18
  if (isPresenceOnly) {
15
19
  if (fg('platform-editor-presence-websocket-only')) {
@@ -18,6 +22,9 @@ export function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, ana
18
22
  transports = ['websocket'];
19
23
  }
20
24
  socketIOOptions = SOCKET_IO_OPTIONS_WITH_HIGH_JITTER;
25
+ if (isIsolatedCloud() && expValEquals('platform_editor_use_pmr_for_collab_presence_in_ic', 'isEnabled', true, false) || !isIsolatedCloud() && expValEquals('platform_editor_use_pmr_for_collab_presence_non_ic', 'isEnabled', true, false)) {
26
+ usePMR = true;
27
+ }
21
28
  }
22
29
  const client = io(url, {
23
30
  reconnectionDelayMax: socketIOOptions.RECONNECTION_DELAY_MAX,
@@ -26,7 +33,7 @@ export function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, ana
26
33
  closeOnBeforeunload: false,
27
34
  withCredentials: true,
28
35
  transports,
29
- path: `/${pathname.split('/')[1]}/socket.io`,
36
+ path: usePMR && path ? `${path}/socket.io` : `/${pathname.split('/')[1]}/socket.io`,
30
37
  auth,
31
38
  extraHeaders: {
32
39
  'x-product': getProduct(productInfo),
@@ -1,5 +1,5 @@
1
1
  export const name = "@atlaskit/collab-provider";
2
- export const version = "0.0.0-development";
2
+ export const version = "14.1.2";
3
3
  export const nextMajorVersion = () => {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -539,10 +539,10 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
539
539
  }
540
540
  var _this$config = this.config,
541
541
  documentAri = _this$config.documentAri,
542
- url = _this$config.url;
543
- var _this$config2 = this.config,
544
- createSocket = _this$config2.createSocket,
545
- permissionTokenRefresh = _this$config2.permissionTokenRefresh;
542
+ url = _this$config.url,
543
+ path = _this$config.path,
544
+ createSocket = _this$config.createSocket,
545
+ permissionTokenRefresh = _this$config.permissionTokenRefresh;
546
546
  var auth;
547
547
  if (permissionTokenRefresh) {
548
548
  auth = /*#__PURE__*/function () {
@@ -628,7 +628,7 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
628
628
  };
629
629
  }();
630
630
  }
631
- this.socket = createSocket("".concat(url, "/session/").concat(documentAri), auth, this.config.productInfo, this.config.isPresenceOnly, this.analyticsHelper);
631
+ this.socket = createSocket("".concat(url, "/session/").concat(documentAri), auth, this.config.productInfo, this.config.isPresenceOnly, this.analyticsHelper, path);
632
632
 
633
633
  // Due to https://github.com/socketio/socket.io-client/issues/1473,
634
634
  // reconnect no longer fired on the socket.
@@ -726,7 +726,7 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
726
726
  // Ensure the error emit to the provider has the same structure, so we can handle them unified.
727
727
  this.socket.on('connect_error', this.onConnectError);
728
728
  this.socket.on('permission:invalidateToken', this.handlePermissionInvalidateToken);
729
- this.socket.onAnyOutgoing(function (_event) {
729
+ this.socket.onAnyOutgoing(function (_) {
730
730
  for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
731
731
  args[_key - 1] = arguments[_key];
732
732
  }
@@ -52,6 +52,11 @@ export var NullDocumentService = /*#__PURE__*/function () {
52
52
  value: function getUnconfirmedSteps() {
53
53
  return undefined;
54
54
  }
55
+ }, {
56
+ key: "getUnconfirmedStepsOrigins",
57
+ value: function getUnconfirmedStepsOrigins() {
58
+ return undefined;
59
+ }
55
60
  }, {
56
61
  key: "getCurrentPmVersion",
57
62
  value: function getCurrentPmVersion() {
@@ -0,0 +1,29 @@
1
+ import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
2
+ function getOfflineSteps(steps, origins) {
3
+ if (!steps || !origins || steps.length !== origins.length) {
4
+ return undefined;
5
+ }
6
+ if (origins.some(function (s) {
7
+ return (s === null || s === void 0 ? void 0 : s.getMeta('isOffline')) === true || (s === null || s === void 0 ? void 0 : s.getMeta('wasOffline')) === true;
8
+ })) {
9
+ var mapped = steps.filter(function (step, idx) {
10
+ var origin = origins[idx];
11
+ if (!origin) {
12
+ return false;
13
+ }
14
+ var createdOffline = origin.getMeta('isOffline') || origin.getMeta('wasOffline');
15
+ return createdOffline;
16
+ });
17
+ return mapped;
18
+ }
19
+ }
20
+ export function getOfflineStepsLength(steps, origins) {
21
+ var _getOfflineSteps;
22
+ return (_getOfflineSteps = getOfflineSteps(steps, origins)) === null || _getOfflineSteps === void 0 ? void 0 : _getOfflineSteps.length;
23
+ }
24
+ export function getOfflineReplaceStepsLength(steps, origins) {
25
+ var _getOfflineSteps2;
26
+ return (_getOfflineSteps2 = getOfflineSteps(steps, origins)) === null || _getOfflineSteps2 === void 0 ? void 0 : _getOfflineSteps2.filter(function (s) {
27
+ return s instanceof ReplaceStep;
28
+ }).length;
29
+ }
@@ -16,6 +16,7 @@ function _superPropGet(t, o, e, r) { var p = _get(_getPrototypeOf(1 & r ? t.prot
16
16
  import { v4 as uuidv4 } from 'uuid';
17
17
  import { Emitter } from '../emitter';
18
18
  import { Channel } from '../channel';
19
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
19
20
  import { createLogger, logObfuscatedSteps } from '../helpers/utils';
20
21
  import AnalyticsHelper from '../analytics/analytics-helper';
21
22
  import { telepointerCallback } from '../participants/telepointers-helper';
@@ -33,6 +34,7 @@ import { Api } from '../api/api';
33
34
  import { shouldTelepointerBeSampled } from '../analytics/performance';
34
35
  import { NullApi } from '../api/null-api';
35
36
  import { fg } from '@atlaskit/platform-feature-flags';
37
+ import { getOfflineStepsLength, getOfflineReplaceStepsLength } from './get-offline-steps-length';
36
38
  var logger = createLogger('Provider', 'black');
37
39
  var OUT_OF_SYNC_PERIOD = 3 * 1000; // 3 seconds
38
40
 
@@ -140,6 +142,8 @@ export var Provider = /*#__PURE__*/function (_Emitter) {
140
142
  Date.now() - _this.disconnectedAt >= OUT_OF_SYNC_PERIOD) {
141
143
  _this.documentService.throttledCatchupv2(CatchupEventReason.RECONNECTED, {
142
144
  disconnectionPeriodSeconds: Math.floor((Date.now() - _this.disconnectedAt) / 1000),
145
+ offlineStepsLength: editorExperiment('platform_editor_offline_editing_web', true) ? getOfflineStepsLength(_this.documentService.getUnconfirmedSteps(), _this.documentService.getUnconfirmedStepsOrigins()) : undefined,
146
+ offlineReplaceStepsLength: editorExperiment('platform_editor_offline_editing_web', true) ? getOfflineReplaceStepsLength(_this.documentService.getUnconfirmedSteps(), _this.documentService.getUnconfirmedStepsOrigins()) : undefined,
143
147
  unconfirmedStepsLength: unconfirmedStepsLength
144
148
  }, fg('add_session_id_to_catchup_query') ? _this.sessionId : undefined);
145
149
  }
@@ -3,15 +3,19 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
3
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
4
  import { io } from 'socket.io-client';
5
5
  import { fg } from '@atlaskit/platform-feature-flags';
6
+ import { isIsolatedCloud } from '@atlaskit/atlassian-context';
7
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
6
8
  import { Provider } from './provider';
7
9
  import { getProduct, getSubProduct } from './helpers/utils';
8
10
  import { SOCKET_IO_OPTIONS, SOCKET_IO_OPTIONS_WITH_HIGH_JITTER } from './config';
9
- export function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, analyticsHelper) {
11
+ export function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, analyticsHelper, path) {
10
12
  var _URL = new URL(url),
11
13
  pathname = _URL.pathname;
12
14
  var socketIOOptions = SOCKET_IO_OPTIONS;
13
15
  // Polling first
14
16
  var transports = ['polling', 'websocket'];
17
+ var usePMR = false;
18
+
15
19
  // Limit this change to Presence only
16
20
  if (isPresenceOnly) {
17
21
  if (fg('platform-editor-presence-websocket-only')) {
@@ -20,6 +24,9 @@ export function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, ana
20
24
  transports = ['websocket'];
21
25
  }
22
26
  socketIOOptions = SOCKET_IO_OPTIONS_WITH_HIGH_JITTER;
27
+ if (isIsolatedCloud() && expValEquals('platform_editor_use_pmr_for_collab_presence_in_ic', 'isEnabled', true, false) || !isIsolatedCloud() && expValEquals('platform_editor_use_pmr_for_collab_presence_non_ic', 'isEnabled', true, false)) {
28
+ usePMR = true;
29
+ }
23
30
  }
24
31
  var client = io(url, {
25
32
  reconnectionDelayMax: socketIOOptions.RECONNECTION_DELAY_MAX,
@@ -28,7 +35,7 @@ export function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, ana
28
35
  closeOnBeforeunload: false,
29
36
  withCredentials: true,
30
37
  transports: transports,
31
- path: "/".concat(pathname.split('/')[1], "/socket.io"),
38
+ path: usePMR && path ? "".concat(path, "/socket.io") : "/".concat(pathname.split('/')[1], "/socket.io"),
32
39
  auth: auth,
33
40
  extraHeaders: {
34
41
  'x-product': getProduct(productInfo),
@@ -1,5 +1,5 @@
1
1
  export var name = "@atlaskit/collab-provider";
2
- export var version = "0.0.0-development";
2
+ export var version = "14.1.2";
3
3
  export var nextMajorVersion = function nextMajorVersion() {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -14,6 +14,7 @@ export declare class NullDocumentService implements DocumentServiceInterface {
14
14
  getFinalAcknowledgedState(reason: GetResolvedEditorStateReason): Promise<ResolvedEditorState>;
15
15
  getIsNamespaceLocked(): boolean;
16
16
  getUnconfirmedSteps(): undefined;
17
+ getUnconfirmedStepsOrigins(): undefined;
17
18
  getCurrentPmVersion(): number;
18
19
  onErrorHandled: () => void;
19
20
  }
@@ -0,0 +1,4 @@
1
+ import type { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
2
+ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ export declare function getOfflineStepsLength(steps: readonly ProseMirrorStep[] | undefined, origins: readonly Transaction[] | undefined): number | undefined;
4
+ export declare function getOfflineReplaceStepsLength(steps: readonly ProseMirrorStep[] | undefined, origins: readonly Transaction[] | undefined): number | undefined;
@@ -1,6 +1,6 @@
1
1
  import type { Socket } from 'socket.io-client';
2
2
  import { Provider } from './provider';
3
- import type AnalyticsHelper from './analytics/analytics-helper';
4
3
  import type { Config, ProductInformation, InitAndAuthData, AuthCallback } from './types';
5
- export declare function createSocketIOSocket(url: string, auth?: AuthCallback | InitAndAuthData, productInfo?: ProductInformation, isPresenceOnly?: boolean, analyticsHelper?: AnalyticsHelper): Socket;
4
+ import type AnalyticsHelper from './analytics/analytics-helper';
5
+ export declare function createSocketIOSocket(url: string, auth?: AuthCallback | InitAndAuthData, productInfo?: ProductInformation, isPresenceOnly?: boolean, analyticsHelper?: AnalyticsHelper, path?: string): Socket;
6
6
  export declare function createSocketIOCollabProvider(config: Omit<Config, 'createSocket'>): Provider;
@@ -39,7 +39,7 @@ export interface Config {
39
39
  */
40
40
  analyticsClient?: AnalyticsWebClient;
41
41
  batchProps?: BatchProps;
42
- createSocket: (path: string, auth?: AuthCallback | InitAndAuthData, productInfo?: ProductInformation, isPresenceOnly?: boolean, analyticsHelper?: AnalyticsHelper) => SocketIOSocket;
42
+ createSocket: (url: string, auth?: AuthCallback | InitAndAuthData, productInfo?: ProductInformation, isPresenceOnly?: boolean, analyticsHelper?: AnalyticsHelper, path?: string) => SocketIOSocket;
43
43
  documentAri: string;
44
44
  /**
45
45
  * Enable checking if a document update from collab-provider is being dropped by the editor,
@@ -62,6 +62,11 @@ export interface Config {
62
62
  isPresenceOnly?: boolean;
63
63
  lifecycle?: Lifecycle;
64
64
  need404?: boolean;
65
+ /**
66
+ * Used for sharded routing, product passes route to collab provider
67
+ * e.g. /ncs-presence/{cloudId}/{activationId}/confluence
68
+ */
69
+ path?: string;
65
70
  /**
66
71
  * If provided, permissionTokenRefresh is called whenever a new JWT token is required.
67
72
  */
@@ -238,6 +243,8 @@ export interface Catchupv2Options {
238
243
  }
239
244
  export type ReconnectionMetadata = {
240
245
  disconnectionPeriodSeconds: number | undefined;
246
+ offlineReplaceStepsLength: number | undefined;
247
+ offlineStepsLength: number | undefined;
241
248
  unconfirmedStepsLength: number | undefined;
242
249
  };
243
250
  export type ProductInformation = {
@@ -14,6 +14,7 @@ export declare class NullDocumentService implements DocumentServiceInterface {
14
14
  getFinalAcknowledgedState(reason: GetResolvedEditorStateReason): Promise<ResolvedEditorState>;
15
15
  getIsNamespaceLocked(): boolean;
16
16
  getUnconfirmedSteps(): undefined;
17
+ getUnconfirmedStepsOrigins(): undefined;
17
18
  getCurrentPmVersion(): number;
18
19
  onErrorHandled: () => void;
19
20
  }
@@ -0,0 +1,4 @@
1
+ import type { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
2
+ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ export declare function getOfflineStepsLength(steps: readonly ProseMirrorStep[] | undefined, origins: readonly Transaction[] | undefined): number | undefined;
4
+ export declare function getOfflineReplaceStepsLength(steps: readonly ProseMirrorStep[] | undefined, origins: readonly Transaction[] | undefined): number | undefined;
@@ -1,6 +1,6 @@
1
1
  import type { Socket } from 'socket.io-client';
2
2
  import { Provider } from './provider';
3
- import type AnalyticsHelper from './analytics/analytics-helper';
4
3
  import type { Config, ProductInformation, InitAndAuthData, AuthCallback } from './types';
5
- export declare function createSocketIOSocket(url: string, auth?: AuthCallback | InitAndAuthData, productInfo?: ProductInformation, isPresenceOnly?: boolean, analyticsHelper?: AnalyticsHelper): Socket;
4
+ import type AnalyticsHelper from './analytics/analytics-helper';
5
+ export declare function createSocketIOSocket(url: string, auth?: AuthCallback | InitAndAuthData, productInfo?: ProductInformation, isPresenceOnly?: boolean, analyticsHelper?: AnalyticsHelper, path?: string): Socket;
6
6
  export declare function createSocketIOCollabProvider(config: Omit<Config, 'createSocket'>): Provider;
@@ -39,7 +39,7 @@ export interface Config {
39
39
  */
40
40
  analyticsClient?: AnalyticsWebClient;
41
41
  batchProps?: BatchProps;
42
- createSocket: (path: string, auth?: AuthCallback | InitAndAuthData, productInfo?: ProductInformation, isPresenceOnly?: boolean, analyticsHelper?: AnalyticsHelper) => SocketIOSocket;
42
+ createSocket: (url: string, auth?: AuthCallback | InitAndAuthData, productInfo?: ProductInformation, isPresenceOnly?: boolean, analyticsHelper?: AnalyticsHelper, path?: string) => SocketIOSocket;
43
43
  documentAri: string;
44
44
  /**
45
45
  * Enable checking if a document update from collab-provider is being dropped by the editor,
@@ -62,6 +62,11 @@ export interface Config {
62
62
  isPresenceOnly?: boolean;
63
63
  lifecycle?: Lifecycle;
64
64
  need404?: boolean;
65
+ /**
66
+ * Used for sharded routing, product passes route to collab provider
67
+ * e.g. /ncs-presence/{cloudId}/{activationId}/confluence
68
+ */
69
+ path?: string;
65
70
  /**
66
71
  * If provided, permissionTokenRefresh is called whenever a new JWT token is required.
67
72
  */
@@ -238,6 +243,8 @@ export interface Catchupv2Options {
238
243
  }
239
244
  export type ReconnectionMetadata = {
240
245
  disconnectionPeriodSeconds: number | undefined;
246
+ offlineReplaceStepsLength: number | undefined;
247
+ offlineStepsLength: number | undefined;
241
248
  unconfirmedStepsLength: number | undefined;
242
249
  };
243
250
  export type ProductInformation = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/collab-provider",
3
- "version": "14.1.1",
3
+ "version": "14.2.0",
4
4
  "description": "A provider for collaborative editing.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -30,13 +30,14 @@
30
30
  "@atlaskit/analytics-gas-types": "^5.1.0",
31
31
  "@atlaskit/analytics-listeners": "^9.1.0",
32
32
  "@atlaskit/anonymous-assets": "^0.0.14",
33
+ "@atlaskit/atlassian-context": "^0.6.0",
33
34
  "@atlaskit/editor-json-transformer": "^8.31.0",
34
35
  "@atlaskit/editor-prosemirror": "7.0.0",
35
36
  "@atlaskit/feature-gate-js-client": "^5.5.0",
36
37
  "@atlaskit/platform-feature-flags": "^1.1.0",
37
38
  "@atlaskit/prosemirror-collab": "^0.22.0",
38
39
  "@atlaskit/react-ufo": "^4.15.0",
39
- "@atlaskit/tmp-editor-statsig": "^15.0.0",
40
+ "@atlaskit/tmp-editor-statsig": "^15.5.0",
40
41
  "@atlaskit/ufo": "^0.4.0",
41
42
  "@atlaskit/util-service-support": "^6.3.0",
42
43
  "@babel/runtime": "^7.0.0",
@@ -74,6 +75,6 @@
74
75
  }
75
76
  },
76
77
  "peerDependencies": {
77
- "@atlaskit/editor-common": "^110.40.0"
78
+ "@atlaskit/editor-common": "^110.41.0"
78
79
  }
79
80
  }