@atlaskit/collab-provider 39.0.1 → 39.0.3

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,19 @@
1
1
  # @atlaskit/collab-provider
2
2
 
3
+ ## 39.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 39.0.2
10
+
11
+ ### Patch Changes
12
+
13
+ - [`1f937e76a1cea`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/1f937e76a1cea) -
14
+ Presence goes back to WebSocket first after the upgrade from polling succeeds, and network errors
15
+ no longer trigger the polling fallback, behind `platform_editor_presence_ws_restore_after_upgrade`
16
+
3
17
  ## 39.0.1
4
18
 
5
19
  ### Patch Changes
@@ -16,6 +16,9 @@ var _utils = require("./helpers/utils");
16
16
  var _provider = require("./provider");
17
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; }
18
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; }
19
+ /**
20
+ * Creates the Socket.IO client for collab editing or presence, with the transports for that connection case.
21
+ */
19
22
  function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, analyticsHelper, path, documentAri) {
20
23
  var _URL = new URL(url),
21
24
  pathname = _URL.pathname,
@@ -94,6 +97,10 @@ var WEBSOCKET_CONNECT_TIMEOUT_MS = exports.WEBSOCKET_CONNECT_TIMEOUT_MS = 8000;
94
97
  * drop every frame, and then no error fires. Switch to polling-first when WebSocket does not connect in time,
95
98
  * or fails at the transport level. A server rejection (error with `data`) proves WebSocket works, so it never
96
99
  * triggers the fallback. Once switched, all reconnects of this socket use polling-first.
100
+ *
101
+ * With `platform_editor_presence_ws_restore_after_upgrade`, the fallback is no longer sticky and errors no longer
102
+ * trigger it. Errors that reach `connect_error` mean polling failed too (network down), or WebSocket already opened.
103
+ * Once WebSocket carries data, on open or after an upgrade from polling, go back to WebSocket-first.
97
104
  */
98
105
  function addPollingFallback(client, url, analyticsHelper) {
99
106
  var timer;
@@ -102,6 +109,11 @@ function addPollingFallback(client, url, analyticsHelper) {
102
109
  var _client$io$opts$trans;
103
110
  return !webSocketWorks && ((_client$io$opts$trans = client.io.opts.transports) === null || _client$io$opts$trans === void 0 ? void 0 : _client$io$opts$trans[0]) === 'websocket';
104
111
  };
112
+ var markWebSocketWorks = function markWebSocketWorks() {
113
+ webSocketWorks = true;
114
+ client.io.opts.transports = ['websocket', 'polling'];
115
+ client.io.opts.tryAllTransports = true;
116
+ };
105
117
  var fallbackToPolling = function fallbackToPolling(reason) {
106
118
  clearTimeout(timer);
107
119
  if (!isWebSocketFirst() || typeof navigator !== 'undefined' && navigator.onLine === false) {
@@ -125,6 +137,21 @@ function addPollingFallback(client, url, analyticsHelper) {
125
137
  };
126
138
  startTimer();
127
139
  client.io.on('reconnect_attempt', startTimer);
140
+ if ((0, _fg.fg)('platform_editor_presence_ws_restore_after_upgrade')) {
141
+ // The engine opens when the server handshake arrives, so the auth token fetch is not timed
142
+ client.io.on('open', function () {
143
+ clearTimeout(timer);
144
+ var engine = client.io.engine;
145
+ if (engine.transport.name === 'websocket') {
146
+ markWebSocketWorks();
147
+ } else {
148
+ engine.once('upgrade', function (transport) {
149
+ return transport.name === 'websocket' && markWebSocketWorks();
150
+ });
151
+ }
152
+ });
153
+ return;
154
+ }
128
155
  client.on('connect', function () {
129
156
  clearTimeout(timer);
130
157
  webSocketWorks || (webSocketWorks = client.io.engine.transport.name === 'websocket');
@@ -139,6 +166,10 @@ function addPollingFallback(client, url, analyticsHelper) {
139
166
  }
140
167
  });
141
168
  }
169
+
170
+ /**
171
+ * Creates a collab provider that connects with Socket.IO.
172
+ */
142
173
  function createSocketIOCollabProvider(config) {
143
174
  return new _provider.Provider(_objectSpread(_objectSpread({}, config), {}, {
144
175
  createSocket: createSocketIOSocket
@@ -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 = "39.0.0";
8
+ var version = exports.version = "39.0.2";
9
9
  var nextMajorVersion = exports.nextMajorVersion = function nextMajorVersion() {
10
10
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
11
11
  };
@@ -4,6 +4,9 @@ import { SOCKET_IO_OPTIONS, SOCKET_IO_OPTIONS_WITH_HIGH_JITTER } from './config'
4
4
  import { EVENT_ACTION, EVENT_STATUS } from './helpers/const';
5
5
  import { getProduct, getSubProduct, isGCPtenant } from './helpers/utils';
6
6
  import { Provider } from './provider';
7
+ /**
8
+ * Creates the Socket.IO client for collab editing or presence, with the transports for that connection case.
9
+ */
7
10
  export function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, analyticsHelper, path, documentAri) {
8
11
  const {
9
12
  pathname,
@@ -85,6 +88,10 @@ export const WEBSOCKET_CONNECT_TIMEOUT_MS = 8000;
85
88
  * drop every frame, and then no error fires. Switch to polling-first when WebSocket does not connect in time,
86
89
  * or fails at the transport level. A server rejection (error with `data`) proves WebSocket works, so it never
87
90
  * triggers the fallback. Once switched, all reconnects of this socket use polling-first.
91
+ *
92
+ * With `platform_editor_presence_ws_restore_after_upgrade`, the fallback is no longer sticky and errors no longer
93
+ * trigger it. Errors that reach `connect_error` mean polling failed too (network down), or WebSocket already opened.
94
+ * Once WebSocket carries data, on open or after an upgrade from polling, go back to WebSocket-first.
88
95
  */
89
96
  function addPollingFallback(client, url, analyticsHelper) {
90
97
  let timer;
@@ -93,6 +100,11 @@ function addPollingFallback(client, url, analyticsHelper) {
93
100
  var _client$io$opts$trans;
94
101
  return !webSocketWorks && ((_client$io$opts$trans = client.io.opts.transports) === null || _client$io$opts$trans === void 0 ? void 0 : _client$io$opts$trans[0]) === 'websocket';
95
102
  };
103
+ const markWebSocketWorks = () => {
104
+ webSocketWorks = true;
105
+ client.io.opts.transports = ['websocket', 'polling'];
106
+ client.io.opts.tryAllTransports = true;
107
+ };
96
108
  const fallbackToPolling = reason => {
97
109
  clearTimeout(timer);
98
110
  if (!isWebSocketFirst() || typeof navigator !== 'undefined' && navigator.onLine === false) {
@@ -114,6 +126,21 @@ function addPollingFallback(client, url, analyticsHelper) {
114
126
  };
115
127
  startTimer();
116
128
  client.io.on('reconnect_attempt', startTimer);
129
+ if (fg('platform_editor_presence_ws_restore_after_upgrade')) {
130
+ // The engine opens when the server handshake arrives, so the auth token fetch is not timed
131
+ client.io.on('open', () => {
132
+ clearTimeout(timer);
133
+ const {
134
+ engine
135
+ } = client.io;
136
+ if (engine.transport.name === 'websocket') {
137
+ markWebSocketWorks();
138
+ } else {
139
+ engine.once('upgrade', transport => transport.name === 'websocket' && markWebSocketWorks());
140
+ }
141
+ });
142
+ return;
143
+ }
117
144
  client.on('connect', () => {
118
145
  clearTimeout(timer);
119
146
  webSocketWorks ||= client.io.engine.transport.name === 'websocket';
@@ -128,6 +155,10 @@ function addPollingFallback(client, url, analyticsHelper) {
128
155
  }
129
156
  });
130
157
  }
158
+
159
+ /**
160
+ * Creates a collab provider that connects with Socket.IO.
161
+ */
131
162
  export function createSocketIOCollabProvider(config) {
132
163
  return new Provider({
133
164
  ...config,
@@ -1,5 +1,5 @@
1
1
  export const name = "@atlaskit/collab-provider";
2
- export const version = "39.0.0";
2
+ export const version = "39.0.2";
3
3
  export const nextMajorVersion = () => {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -7,6 +7,9 @@ import { SOCKET_IO_OPTIONS, SOCKET_IO_OPTIONS_WITH_HIGH_JITTER } from './config'
7
7
  import { EVENT_ACTION, EVENT_STATUS } from './helpers/const';
8
8
  import { getProduct, getSubProduct, isGCPtenant } from './helpers/utils';
9
9
  import { Provider } from './provider';
10
+ /**
11
+ * Creates the Socket.IO client for collab editing or presence, with the transports for that connection case.
12
+ */
10
13
  export function createSocketIOSocket(url, auth, productInfo, isPresenceOnly, analyticsHelper, path, documentAri) {
11
14
  var _URL = new URL(url),
12
15
  pathname = _URL.pathname,
@@ -85,6 +88,10 @@ export var WEBSOCKET_CONNECT_TIMEOUT_MS = 8000;
85
88
  * drop every frame, and then no error fires. Switch to polling-first when WebSocket does not connect in time,
86
89
  * or fails at the transport level. A server rejection (error with `data`) proves WebSocket works, so it never
87
90
  * triggers the fallback. Once switched, all reconnects of this socket use polling-first.
91
+ *
92
+ * With `platform_editor_presence_ws_restore_after_upgrade`, the fallback is no longer sticky and errors no longer
93
+ * trigger it. Errors that reach `connect_error` mean polling failed too (network down), or WebSocket already opened.
94
+ * Once WebSocket carries data, on open or after an upgrade from polling, go back to WebSocket-first.
88
95
  */
89
96
  function addPollingFallback(client, url, analyticsHelper) {
90
97
  var timer;
@@ -93,6 +100,11 @@ function addPollingFallback(client, url, analyticsHelper) {
93
100
  var _client$io$opts$trans;
94
101
  return !webSocketWorks && ((_client$io$opts$trans = client.io.opts.transports) === null || _client$io$opts$trans === void 0 ? void 0 : _client$io$opts$trans[0]) === 'websocket';
95
102
  };
103
+ var markWebSocketWorks = function markWebSocketWorks() {
104
+ webSocketWorks = true;
105
+ client.io.opts.transports = ['websocket', 'polling'];
106
+ client.io.opts.tryAllTransports = true;
107
+ };
96
108
  var fallbackToPolling = function fallbackToPolling(reason) {
97
109
  clearTimeout(timer);
98
110
  if (!isWebSocketFirst() || typeof navigator !== 'undefined' && navigator.onLine === false) {
@@ -116,6 +128,21 @@ function addPollingFallback(client, url, analyticsHelper) {
116
128
  };
117
129
  startTimer();
118
130
  client.io.on('reconnect_attempt', startTimer);
131
+ if (fg('platform_editor_presence_ws_restore_after_upgrade')) {
132
+ // The engine opens when the server handshake arrives, so the auth token fetch is not timed
133
+ client.io.on('open', function () {
134
+ clearTimeout(timer);
135
+ var engine = client.io.engine;
136
+ if (engine.transport.name === 'websocket') {
137
+ markWebSocketWorks();
138
+ } else {
139
+ engine.once('upgrade', function (transport) {
140
+ return transport.name === 'websocket' && markWebSocketWorks();
141
+ });
142
+ }
143
+ });
144
+ return;
145
+ }
119
146
  client.on('connect', function () {
120
147
  clearTimeout(timer);
121
148
  webSocketWorks || (webSocketWorks = client.io.engine.transport.name === 'websocket');
@@ -130,6 +157,10 @@ function addPollingFallback(client, url, analyticsHelper) {
130
157
  }
131
158
  });
132
159
  }
160
+
161
+ /**
162
+ * Creates a collab provider that connects with Socket.IO.
163
+ */
133
164
  export function createSocketIOCollabProvider(config) {
134
165
  return new Provider(_objectSpread(_objectSpread({}, config), {}, {
135
166
  createSocket: createSocketIOSocket
@@ -1,5 +1,5 @@
1
1
  export var name = "@atlaskit/collab-provider";
2
- export var version = "39.0.0";
2
+ export var version = "39.0.2";
3
3
  export var nextMajorVersion = function nextMajorVersion() {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -2,6 +2,12 @@ import type { Socket } from 'socket.io-client';
2
2
  import type AnalyticsHelper from './analytics/analytics-helper';
3
3
  import { Provider } from './provider';
4
4
  import type { Config, ProductInformation, InitAndAuthData, AuthCallback } from './types';
5
+ /**
6
+ * Creates the Socket.IO client for collab editing or presence, with the transports for that connection case.
7
+ */
5
8
  export declare function createSocketIOSocket(url: string, auth?: AuthCallback | InitAndAuthData, productInfo?: ProductInformation, isPresenceOnly?: boolean, analyticsHelper?: AnalyticsHelper, path?: string, documentAri?: string): Socket;
6
9
  export declare const WEBSOCKET_CONNECT_TIMEOUT_MS = 8000;
10
+ /**
11
+ * Creates a collab provider that connects with Socket.IO.
12
+ */
7
13
  export declare function createSocketIOCollabProvider(config: Omit<Config, 'createSocket'>): Provider;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/collab-provider",
3
- "version": "39.0.1",
3
+ "version": "39.0.3",
4
4
  "description": "A provider for collaborative editing.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -30,7 +30,7 @@
30
30
  "@atlaskit/platform-feature-flags": "^2.2.0",
31
31
  "@atlaskit/prosemirror-collab": "^1.1.0",
32
32
  "@atlaskit/react-ufo": "^8.3.0",
33
- "@atlaskit/tmp-editor-statsig": "^247.0.0",
33
+ "@atlaskit/tmp-editor-statsig": "^248.0.0",
34
34
  "@atlaskit/ufo": "^2.0.0",
35
35
  "@atlaskit/util-service-support": "^7.4.0",
36
36
  "@babel/runtime": "^7.0.0",
@@ -67,11 +67,14 @@
67
67
  "platform_editor_presence_ws_first_with_fallback": {
68
68
  "type": "boolean"
69
69
  },
70
+ "platform_editor_presence_ws_restore_after_upgrade": {
71
+ "type": "boolean"
72
+ },
70
73
  "collab_edit_via_websocket_only_for_gcp": {
71
74
  "type": "boolean"
72
75
  }
73
76
  },
74
77
  "peerDependencies": {
75
- "@atlaskit/editor-common": "^134.0.0"
78
+ "@atlaskit/editor-common": "^134.1.0"
76
79
  }
77
80
  }