@atlaskit/collab-provider 8.0.1 → 8.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/cjs/analytics/index.js +2 -11
  3. package/dist/cjs/analytics/performance.js +2 -16
  4. package/dist/cjs/channel.js +66 -115
  5. package/dist/cjs/disconnected-reason-mapper.js +0 -2
  6. package/dist/cjs/emitter.js +3 -11
  7. package/dist/cjs/error-code-mapper.js +4 -17
  8. package/dist/cjs/feature-flags/__test__/index.unit.js +27 -0
  9. package/dist/cjs/feature-flags/index.js +52 -0
  10. package/dist/cjs/feature-flags/types.js +12 -0
  11. package/dist/cjs/helpers/const.js +6 -10
  12. package/dist/cjs/helpers/utils.js +0 -12
  13. package/dist/cjs/index.js +0 -1
  14. package/dist/cjs/provider/catchup.js +38 -42
  15. package/dist/cjs/provider/index.js +153 -283
  16. package/dist/cjs/socket-io-provider.js +2 -12
  17. package/dist/cjs/types.js +0 -1
  18. package/dist/cjs/version-wrapper.js +1 -3
  19. package/dist/cjs/version.json +1 -1
  20. package/dist/es2019/analytics/index.js +2 -3
  21. package/dist/es2019/analytics/performance.js +2 -13
  22. package/dist/es2019/channel.js +57 -65
  23. package/dist/es2019/disconnected-reason-mapper.js +1 -2
  24. package/dist/es2019/emitter.js +3 -8
  25. package/dist/es2019/error-code-mapper.js +4 -12
  26. package/dist/es2019/feature-flags/__test__/index.unit.js +25 -0
  27. package/dist/es2019/feature-flags/index.js +31 -0
  28. package/dist/es2019/feature-flags/types.js +5 -0
  29. package/dist/es2019/helpers/const.js +4 -9
  30. package/dist/es2019/helpers/utils.js +0 -2
  31. package/dist/es2019/provider/catchup.js +33 -17
  32. package/dist/es2019/provider/index.js +119 -189
  33. package/dist/es2019/socket-io-provider.js +4 -2
  34. package/dist/es2019/types.js +1 -1
  35. package/dist/es2019/version-wrapper.js +1 -1
  36. package/dist/es2019/version.json +1 -1
  37. package/dist/esm/analytics/index.js +2 -6
  38. package/dist/esm/analytics/performance.js +2 -13
  39. package/dist/esm/channel.js +68 -108
  40. package/dist/esm/disconnected-reason-mapper.js +1 -2
  41. package/dist/esm/emitter.js +3 -6
  42. package/dist/esm/error-code-mapper.js +4 -12
  43. package/dist/esm/feature-flags/__test__/index.unit.js +25 -0
  44. package/dist/esm/feature-flags/index.js +43 -0
  45. package/dist/esm/feature-flags/types.js +5 -0
  46. package/dist/esm/helpers/const.js +4 -9
  47. package/dist/esm/helpers/utils.js +0 -3
  48. package/dist/esm/provider/catchup.js +38 -35
  49. package/dist/esm/provider/index.js +153 -285
  50. package/dist/esm/socket-io-provider.js +2 -5
  51. package/dist/esm/types.js +1 -1
  52. package/dist/esm/version-wrapper.js +1 -1
  53. package/dist/esm/version.json +1 -1
  54. package/dist/types/channel.d.ts +1 -0
  55. package/dist/types/error-code-mapper.d.ts +1 -1
  56. package/dist/types/feature-flags/__test__/index.unit.d.ts +1 -0
  57. package/dist/types/feature-flags/index.d.ts +9 -0
  58. package/dist/types/feature-flags/types.d.ts +11 -0
  59. package/dist/types/helpers/const.d.ts +19 -3
  60. package/dist/types/provider/catchup.d.ts +1 -1
  61. package/dist/types/provider/index.d.ts +1 -0
  62. package/dist/types/types.d.ts +9 -4
  63. package/package.json +10 -9
  64. package/report.api.md +11 -1
@@ -5,8 +5,9 @@ import { SOCKET_IO_OPTIONS } from './config';
5
5
  export function createSocketIOSocket(url, auth, productInfo) {
6
6
  const {
7
7
  pathname
8
- } = new URL(url); // to limit the reconnection flooding towards collab service, here we set the reconnectionDelayMax to 128s.
8
+ } = new URL(url);
9
9
 
10
+ // to limit the reconnection flooding towards collab service, here we set the reconnectionDelayMax to 128s.
10
11
  return io(url, {
11
12
  reconnectionDelayMax: SOCKET_IO_OPTIONS.RECONNECTION_DELAY_MAX,
12
13
  reconnectionDelay: SOCKET_IO_OPTIONS.RECONNECTION_DELAY,
@@ -23,7 +24,8 @@ export function createSocketIOSocket(url, auth, productInfo) {
23
24
  });
24
25
  }
25
26
  export function createSocketIOCollabProvider(config) {
26
- return new Provider({ ...config,
27
+ return new Provider({
28
+ ...config,
27
29
  createSocket: createSocketIOSocket
28
30
  });
29
31
  }
@@ -1,6 +1,6 @@
1
1
  // Channel
2
- export let AcknowledgementResponseTypes;
3
2
 
3
+ export let AcknowledgementResponseTypes;
4
4
  (function (AcknowledgementResponseTypes) {
5
5
  AcknowledgementResponseTypes["SUCCESS"] = "SUCCESS";
6
6
  AcknowledgementResponseTypes["ERROR"] = "ERROR";
@@ -1,5 +1,5 @@
1
1
  export const name = "@atlaskit/collab-provider";
2
- export const version = "8.0.1";
2
+ export const version = "8.2.0";
3
3
  export const nextMajorVersion = () => {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/collab-provider",
3
- "version": "8.0.1",
3
+ "version": "8.2.0",
4
4
  "sideEffects": false
5
5
  }
@@ -1,16 +1,12 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
-
3
2
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
4
-
5
3
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
6
-
7
4
  import { EVENT_SUBJECT, COLLAB_SERVICE } from '../helpers/const';
8
5
  import { name as packageName, version as packageVersion } from '../version-wrapper';
9
6
  export var triggerAnalyticsEvent = function triggerAnalyticsEvent(analyticsEvent, analyticsClient) {
10
7
  if (!analyticsClient) {
11
8
  return;
12
9
  }
13
-
14
10
  var payload = {
15
11
  actionSubject: EVENT_SUBJECT,
16
12
  attributes: _objectSpread({
@@ -21,10 +17,10 @@ export var triggerAnalyticsEvent = function triggerAnalyticsEvent(analyticsEvent
21
17
  tags: ['editor'],
22
18
  action: analyticsEvent.eventAction,
23
19
  source: 'unknown' // Adds zero analytics value, but event validation throws an error if you don't add it :-(
20
+ };
24
21
 
25
- }; // Let the browser figure out
22
+ // Let the browser figure out
26
23
  // when it should send those events
27
-
28
24
  var requestIdleCallbackFunction = window.requestIdleCallback;
29
25
  var runItLater = typeof requestIdleCallbackFunction === 'function' ? requestIdleCallbackFunction : window.requestAnimationFrame;
30
26
  runItLater(function () {
@@ -1,49 +1,41 @@
1
1
  export var MEASURE_NAME;
2
-
3
2
  (function (MEASURE_NAME) {
4
3
  MEASURE_NAME["SOCKET_CONNECT"] = "socketConnect";
5
4
  MEASURE_NAME["DOCUMENT_INIT"] = "documentInit";
6
5
  MEASURE_NAME["CONVERT_PM_TO_ADF"] = "convertPMToADF";
7
6
  MEASURE_NAME["COMMIT_UNCONFIRMED_STEPS"] = "commitUnconfirmedSteps";
8
7
  })(MEASURE_NAME || (MEASURE_NAME = {}));
9
-
10
8
  var isPerformanceAPIAvailable = function isPerformanceAPIAvailable() {
11
9
  return typeof window !== 'undefined' && 'performance' in window && ['measure', 'clearMeasures', 'clearMarks', 'getEntriesByName', 'getEntriesByType'].every(function (api) {
12
10
  return !!performance[api];
13
11
  });
14
12
  };
15
-
16
13
  var hasPerformanceAPIAvailable = isPerformanceAPIAvailable();
17
14
  var measureMap = new Map();
18
15
  export function startMeasure(measureName) {
19
16
  if (!hasPerformanceAPIAvailable) {
20
17
  return;
21
18
  }
22
-
23
19
  performance.mark("".concat(measureName, "::start"));
24
20
  measureMap.set(measureName, performance.now());
25
21
  }
26
22
  export function stopMeasure(measureName, onMeasureComplete) {
27
23
  if (!hasPerformanceAPIAvailable) {
28
24
  return;
29
- } // `startMeasure` is not called with `measureName` before.
30
-
25
+ }
31
26
 
27
+ // `startMeasure` is not called with `measureName` before.
32
28
  if (!measureMap.get(measureName)) {
33
29
  return;
34
30
  }
35
-
36
31
  performance.mark("".concat(measureName, "::end"));
37
32
  var start = onMeasureComplete ? measureMap.get(measureName) : undefined;
38
-
39
33
  try {
40
34
  performance.measure(measureName, "".concat(measureName, "::start"), "".concat(measureName, "::end"));
41
35
  } catch (e) {}
42
-
43
36
  var entry = performance.getEntriesByName(measureName).pop();
44
37
  clearMeasure(measureName);
45
38
  var measure;
46
-
47
39
  if (entry) {
48
40
  measure = {
49
41
  duration: entry.duration,
@@ -55,18 +47,15 @@ export function stopMeasure(measureName, onMeasureComplete) {
55
47
  startTime: start
56
48
  };
57
49
  }
58
-
59
50
  if (measure && onMeasureComplete) {
60
51
  onMeasureComplete(measure.duration, measure.startTime);
61
52
  }
62
-
63
53
  return measure;
64
54
  }
65
55
  export function clearMeasure(measureName) {
66
56
  if (!hasPerformanceAPIAvailable) {
67
57
  return;
68
58
  }
69
-
70
59
  measureMap.delete(measureName);
71
60
  performance.clearMarks("".concat(measureName, "::start"));
72
61
  performance.clearMarks("".concat(measureName, "::end"));
@@ -7,16 +7,12 @@ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstruct
7
7
  import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
8
8
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
9
9
  import _regeneratorRuntime from "@babel/runtime/regenerator";
10
-
11
10
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
12
-
13
11
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
14
-
15
12
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
16
-
17
13
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
18
-
19
- import { utils } from '@atlaskit/util-service-support'; // TODO: Validate if this is actually equivalent to the AnalyticsWebClient in @atlassiansox/analytics-web-client
14
+ import { utils } from '@atlaskit/util-service-support';
15
+ // TODO: Validate if this is actually equivalent to the AnalyticsWebClient in @atlassiansox/analytics-web-client
20
16
 
21
17
  import { Emitter } from './emitter';
22
18
  import { ErrorCodeMapper } from './error-code-mapper';
@@ -28,22 +24,14 @@ import { ExperiencePerformanceTypes, ExperienceTypes, UFOExperience } from '@atl
28
24
  var logger = createLogger('Channel', 'green');
29
25
  export var Channel = /*#__PURE__*/function (_Emitter) {
30
26
  _inherits(Channel, _Emitter);
31
-
32
27
  var _super = _createSuper(Channel);
33
-
34
28
  function Channel(config) {
35
29
  var _this;
36
-
37
30
  _classCallCheck(this, Channel);
38
-
39
31
  _this = _super.call(this);
40
-
41
32
  _defineProperty(_assertThisInitialized(_this), "connected", false);
42
-
43
33
  _defineProperty(_assertThisInitialized(_this), "socket", null);
44
-
45
34
  _defineProperty(_assertThisInitialized(_this), "initialized", false);
46
-
47
35
  _defineProperty(_assertThisInitialized(_this), "initExperience", new UFOExperience('collab-provider.document-init', {
48
36
  type: ExperienceTypes.Load,
49
37
  performanceType: ExperiencePerformanceTypes.Custom,
@@ -53,19 +41,39 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
53
41
  })
54
42
  }
55
43
  }));
56
-
57
44
  _defineProperty(_assertThisInitialized(_this), "getInitialized", function () {
58
45
  return _this.initialized;
59
46
  });
60
-
61
47
  _defineProperty(_assertThisInitialized(_this), "getConnected", function () {
62
48
  return _this.connected;
63
49
  });
64
-
65
50
  _defineProperty(_assertThisInitialized(_this), "getSocket", function () {
66
51
  return _this.socket;
67
52
  });
68
-
53
+ _defineProperty(_assertThisInitialized(_this), "onConnectError", function (error) {
54
+ var measure = stopMeasure(MEASURE_NAME.SOCKET_CONNECT);
55
+ triggerAnalyticsEvent({
56
+ eventAction: EVENT_ACTION.CONNECTION,
57
+ attributes: {
58
+ eventStatus: EVENT_STATUS.FAILURE,
59
+ error: error,
60
+ latency: measure === null || measure === void 0 ? void 0 : measure.duration,
61
+ documentAri: _this.config.documentAri
62
+ }
63
+ }, _this.analyticsClient);
64
+ // If error received with `data`, it means the connection is rejected
65
+ // by the server on purpose for example no permission, so no need to
66
+ // keep the underneath connection, need to close. But some error like
67
+ // `xhr polling error` needs to retry.
68
+ if (!!error.data) {
69
+ var _this$socket;
70
+ (_this$socket = _this.socket) === null || _this$socket === void 0 ? void 0 : _this$socket.close();
71
+ }
72
+ _this.emit('error', {
73
+ message: error.message,
74
+ data: error.data
75
+ });
76
+ });
69
77
  _defineProperty(_assertThisInitialized(_this), "onConnect", function () {
70
78
  _this.connected = true;
71
79
  logger('Connected.', _this.socket.id);
@@ -78,38 +86,34 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
78
86
  documentAri: _this.config.documentAri
79
87
  }
80
88
  }, _this.analyticsClient);
81
-
82
89
  _this.emit('connected', {
83
90
  sid: _this.socket.id,
84
91
  initialized: _this.initialized
85
92
  });
86
93
  });
87
-
88
94
  _defineProperty(_assertThisInitialized(_this), "onReceiveData", function (data) {
89
95
  logger('Received data', data);
90
96
  logger('Session ID is', _this.socket.id);
91
-
92
97
  if (data.type === 'initial') {
93
98
  if (!_this.initialized) {
94
99
  var measure = stopMeasure(MEASURE_NAME.DOCUMENT_INIT);
95
-
96
100
  _this.initExperience.success();
97
-
98
101
  triggerAnalyticsEvent({
99
102
  eventAction: EVENT_ACTION.DOCUMENT_INIT,
100
103
  attributes: {
101
104
  eventStatus: EVENT_STATUS.SUCCESS,
102
105
  // TODO: detect when document init fails and fire corresponding event for it
103
106
  latency: measure === null || measure === void 0 ? void 0 : measure.duration,
104
- documentAri: _this.config.documentAri
107
+ documentAri: _this.config.documentAri,
108
+ requiredPageRecovery: data === null || data === void 0 ? void 0 : data.requiredPageRecovery,
109
+ ttlEnabled: data === null || data === void 0 ? void 0 : data.ttlEnabled
105
110
  }
106
111
  }, _this.analyticsClient);
107
112
  var doc = data.doc,
108
- version = data.version,
109
- userId = data.userId,
110
- metadata = data.metadata;
113
+ version = data.version,
114
+ userId = data.userId,
115
+ metadata = data.metadata;
111
116
  _this.initialized = true;
112
-
113
117
  _this.emit('init', {
114
118
  doc: doc,
115
119
  version: version,
@@ -119,10 +123,9 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
119
123
  } else {
120
124
  // Page is been just restored, need to fix all the participants as well.
121
125
  var _doc = data.doc,
122
- _version = data.version,
123
- _userId = data.userId,
124
- _metadata = data.metadata;
125
-
126
+ _version = data.version,
127
+ _userId = data.userId,
128
+ _metadata = data.metadata;
126
129
  _this.emit('restore', {
127
130
  doc: _doc,
128
131
  version: _version,
@@ -134,17 +137,14 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
134
137
  _this.emit('steps:added', data);
135
138
  }
136
139
  });
137
-
138
140
  _this.config = config;
139
-
140
141
  if (config.analyticsClient) {
141
142
  _this.analyticsClient = config.analyticsClient;
142
143
  }
143
-
144
144
  return _this;
145
- } // read-only getters used for tests
146
-
145
+ }
147
146
 
147
+ // read-only getters used for tests
148
148
  _createClass(Channel, [{
149
149
  key: "connect",
150
150
  value:
@@ -153,21 +153,17 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
153
153
  */
154
154
  function connect() {
155
155
  var _this2 = this;
156
-
157
156
  startMeasure(MEASURE_NAME.SOCKET_CONNECT);
158
-
159
157
  if (!this.initialized) {
160
158
  startMeasure(MEASURE_NAME.DOCUMENT_INIT);
161
159
  this.initExperience.start();
162
160
  }
163
-
164
161
  var _this$config = this.config,
165
- documentAri = _this$config.documentAri,
166
- url = _this$config.url;
162
+ documentAri = _this$config.documentAri,
163
+ url = _this$config.url;
167
164
  var createSocket = this.config.createSocket;
168
165
  var permissionTokenRefresh = this.config.permissionTokenRefresh;
169
166
  var authCb = null;
170
-
171
167
  if (permissionTokenRefresh) {
172
168
  authCb = function authCb(cb) {
173
169
  permissionTokenRefresh().then(function (token) {
@@ -193,11 +189,11 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
193
189
  });
194
190
  };
195
191
  }
192
+ this.socket = createSocket("".concat(url, "/session/").concat(documentAri), authCb, this.config.productInfo);
196
193
 
197
- this.socket = createSocket("".concat(url, "/session/").concat(documentAri), authCb, this.config.productInfo); // Due to https://github.com/socketio/socket.io-client/issues/1473,
194
+ // Due to https://github.com/socketio/socket.io-client/issues/1473,
198
195
  // reconnect no longer fired on the socket.
199
196
  // We should use `connect` for better cross platform compatibility(Mobile/Web).
200
-
201
197
  this.socket.on('connect', this.onConnect);
202
198
  this.socket.on('data', this.onReceiveData);
203
199
  this.socket.on('steps:added', function (data) {
@@ -217,10 +213,9 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
217
213
  });
218
214
  this.socket.on('participant:updated', function (_ref) {
219
215
  var sessionId = _ref.sessionId,
220
- timestamp = _ref.timestamp,
221
- data = _ref.data,
222
- clientId = _ref.clientId;
223
-
216
+ timestamp = _ref.timestamp,
217
+ data = _ref.data,
218
+ clientId = _ref.clientId;
224
219
  _this2.emit('participant:updated', _objectSpread({
225
220
  sessionId: sessionId,
226
221
  timestamp: timestamp,
@@ -229,8 +224,9 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
229
224
  });
230
225
  this.socket.on('metadata:changed', function (payload) {
231
226
  _this2.emit('metadata:changed', payload);
232
- }); // ESS-2916 namespace status event - lock/unlock
227
+ });
233
228
 
229
+ // ESS-2916 namespace status event - lock/unlock
234
230
  this.socket.on('status', function (data) {
235
231
  _this2.emit('status', data);
236
232
  });
@@ -242,16 +238,13 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
242
238
  case 0:
243
239
  _this2.connected = false;
244
240
  logger("disconnect reason: ".concat(reason));
245
-
246
241
  _this2.emit('disconnect', {
247
242
  reason: reason
248
243
  });
249
-
250
244
  if (reason === 'io server disconnect' && _this2.socket) {
251
245
  // The disconnection was initiated by the server, we need to reconnect manually.
252
246
  _this2.socket.connect();
253
247
  }
254
-
255
248
  case 4:
256
249
  case "end":
257
250
  return _context.stop();
@@ -259,50 +252,25 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
259
252
  }
260
253
  }, _callee);
261
254
  }));
262
-
263
255
  return function (_x) {
264
256
  return _ref2.apply(this, arguments);
265
257
  };
266
- }()); // Socket error, including errors from `packetMiddleware`, `controllers` and `onconnect` and more. Paramter is a plain JSON object.
258
+ }());
267
259
 
260
+ // Socket error, including errors from `packetMiddleware`, `controllers` and `onconnect` and more. Paramter is a plain JSON object.
268
261
  this.socket.on('error', function (error) {
269
262
  _this2.emit('error', error);
270
- }); // `connect_error`'s paramter type is `Error`.
271
- // Ensure the error emit to the provider has the same structure, so we can handle them unified.
272
-
273
- this.socket.on('connect_error', function (error) {
274
- var measure = stopMeasure(MEASURE_NAME.SOCKET_CONNECT);
275
- triggerAnalyticsEvent({
276
- eventAction: EVENT_ACTION.CONNECTION,
277
- attributes: {
278
- eventStatus: EVENT_STATUS.FAILURE,
279
- error: error,
280
- latency: measure === null || measure === void 0 ? void 0 : measure.duration,
281
- documentAri: _this2.config.documentAri
282
- }
283
- }, _this2.analyticsClient); // If error received with `data`, it means the connection is rejected
284
- // by the server on purpose for example no permission, so no need to
285
- // keep the underneath connection, need to close. But some error like
286
- // `xhr polling error` needs to retry.
287
-
288
- if (!!error.data) {
289
- var _this2$socket;
290
-
291
- (_this2$socket = _this2.socket) === null || _this2$socket === void 0 ? void 0 : _this2$socket.close();
292
- }
293
-
294
- _this2.emit('error', {
295
- message: error.message,
296
- data: error.data
297
- });
298
263
  });
264
+
265
+ // `connect_error`'s paramter type is `Error`.
266
+ // Ensure the error emit to the provider has the same structure, so we can handle them unified.
267
+ this.socket.on('connect_error', this.onConnectError);
299
268
  }
300
269
  }, {
301
270
  key: "fetchCatchup",
302
271
  value: function () {
303
272
  var _fetchCatchup = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(fromVersion) {
304
- var _yield$this$config$pe, _yield$utils$requestS, doc, version, stepMaps, metadata, errorCatchup;
305
-
273
+ var _yield$this$config$pe, _yield$utils$requestS, doc, version, stepMaps, metadata, errorNotFound, errorCatchup;
306
274
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
307
275
  while (1) {
308
276
  switch (_context2.prev = _context2.next) {
@@ -317,39 +285,30 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
317
285
  _context2.t4 = _objectSpread;
318
286
  _context2.t5 = _objectSpread;
319
287
  _context2.t6 = {};
320
-
321
288
  if (!this.config.permissionTokenRefresh) {
322
289
  _context2.next = 24;
323
290
  break;
324
291
  }
325
-
326
292
  _context2.next = 11;
327
293
  return this.config.permissionTokenRefresh();
328
-
329
294
  case 11:
330
295
  _context2.t9 = _yield$this$config$pe = _context2.sent;
331
296
  _context2.t8 = _context2.t9 !== null;
332
-
333
297
  if (!_context2.t8) {
334
298
  _context2.next = 15;
335
299
  break;
336
300
  }
337
-
338
301
  _context2.t8 = _yield$this$config$pe !== void 0;
339
-
340
302
  case 15:
341
303
  if (!_context2.t8) {
342
304
  _context2.next = 19;
343
305
  break;
344
306
  }
345
-
346
307
  _context2.t10 = _yield$this$config$pe;
347
308
  _context2.next = 20;
348
309
  break;
349
-
350
310
  case 19:
351
311
  _context2.t10 = undefined;
352
-
353
312
  case 20:
354
313
  _context2.t11 = _context2.t10;
355
314
  _context2.t7 = {
@@ -357,10 +316,8 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
357
316
  };
358
317
  _context2.next = 25;
359
318
  break;
360
-
361
319
  case 24:
362
320
  _context2.t7 = {};
363
-
364
321
  case 25:
365
322
  _context2.t12 = _context2.t7;
366
323
  _context2.t13 = (0, _context2.t5)(_context2.t6, _context2.t12);
@@ -380,7 +337,6 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
380
337
  };
381
338
  _context2.next = 34;
382
339
  return _context2.t0.requestService.call(_context2.t0, _context2.t1, _context2.t18);
383
-
384
340
  case 34:
385
341
  _yield$utils$requestS = _context2.sent;
386
342
  doc = _yield$utils$requestS.doc;
@@ -393,10 +349,23 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
393
349
  stepMaps: stepMaps,
394
350
  metadata: metadata
395
351
  });
396
-
397
352
  case 42:
398
353
  _context2.prev = 42;
399
354
  _context2.t19 = _context2["catch"](0);
355
+ if (!(_context2.t19.code === 404)) {
356
+ _context2.next = 48;
357
+ break;
358
+ }
359
+ errorNotFound = {
360
+ message: ErrorCodeMapper.documentNotFound.message,
361
+ data: {
362
+ status: _context2.t19.code,
363
+ code: ErrorCodeMapper.documentNotFound.code
364
+ }
365
+ };
366
+ this.emit('error', errorNotFound);
367
+ return _context2.abrupt("return", {});
368
+ case 48:
400
369
  logger("Can't fetch the catchup", _context2.t19.message);
401
370
  errorCatchup = {
402
371
  message: ErrorCodeMapper.catchupFail.message,
@@ -407,32 +376,27 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
407
376
  };
408
377
  this.emit('error', errorCatchup);
409
378
  return _context2.abrupt("return", {});
410
-
411
- case 48:
379
+ case 52:
412
380
  case "end":
413
381
  return _context2.stop();
414
382
  }
415
383
  }
416
384
  }, _callee2, this, [[0, 42]]);
417
385
  }));
418
-
419
386
  function fetchCatchup(_x2) {
420
387
  return _fetchCatchup.apply(this, arguments);
421
388
  }
422
-
423
389
  return fetchCatchup;
424
390
  }()
425
391
  /**
426
392
  * Send message to service. Timestamp will be added server side.
427
393
  */
428
-
429
394
  }, {
430
395
  key: "broadcast",
431
396
  value: function broadcast(type, data, callback) {
432
397
  if (!this.connected || !this.socket) {
433
398
  return;
434
399
  }
435
-
436
400
  this.socket.emit('broadcast', _objectSpread({
437
401
  type: type
438
402
  }, data), callback);
@@ -443,7 +407,6 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
443
407
  if (!this.connected || !this.socket) {
444
408
  return;
445
409
  }
446
-
447
410
  this.socket.emit('metadata', metadata);
448
411
  }
449
412
  }, {
@@ -452,20 +415,17 @@ export var Channel = /*#__PURE__*/function (_Emitter) {
452
415
  if (!this.connected || !this.socket) {
453
416
  return;
454
417
  }
455
-
456
418
  this.socket.emit('presence:joined');
457
419
  }
458
420
  }, {
459
421
  key: "disconnect",
460
422
  value: function disconnect() {
461
423
  this.unsubscribeAll();
462
-
463
424
  if (this.socket) {
464
425
  this.socket.close();
465
426
  this.socket = null;
466
427
  }
467
428
  }
468
429
  }]);
469
-
470
430
  return Channel;
471
431
  }(Emitter);
@@ -9,10 +9,9 @@ export var socketIOReasons = {
9
9
  TRANSPORT_ERROR: 'transport error',
10
10
  // The connection was closed (example: the user has lost connection, or the network was changed from WiFi to 4G)
11
11
  PING_TIMEOUT: 'ping timeout' // The connection has encountered an error (example: the server was killed during a HTTP long-polling cycle)
12
-
13
12
  };
14
- export var DisconnectReason;
15
13
 
14
+ export var DisconnectReason;
16
15
  (function (DisconnectReason) {
17
16
  DisconnectReason["CLIENT_DISCONNECT"] = "CLIENT_DISCONNECT";
18
17
  DisconnectReason["SERVER_DISCONNECT"] = "SERVER_DISCONNECT";
@@ -5,10 +5,8 @@ import { EventEmitter2 } from 'eventemitter2';
5
5
  export var Emitter = /*#__PURE__*/function () {
6
6
  function Emitter() {
7
7
  _classCallCheck(this, Emitter);
8
-
9
8
  _defineProperty(this, "eventEmitter", new EventEmitter2());
10
9
  }
11
-
12
10
  _createClass(Emitter, [{
13
11
  key: "emit",
14
12
  value:
@@ -19,30 +17,30 @@ export var Emitter = /*#__PURE__*/function () {
19
17
  this.eventEmitter.emit(evt, data);
20
18
  return this;
21
19
  }
20
+
22
21
  /**
23
22
  * Subscribe to events emitted by this provider
24
23
  */
25
-
26
24
  }, {
27
25
  key: "on",
28
26
  value: function on(evt, handler) {
29
27
  this.eventEmitter.on(evt, handler);
30
28
  return this;
31
29
  }
30
+
32
31
  /**
33
32
  * Unsubscribe from events emitted by this provider
34
33
  */
35
-
36
34
  }, {
37
35
  key: "off",
38
36
  value: function off(evt, handler) {
39
37
  this.eventEmitter.off(evt, handler);
40
38
  return this;
41
39
  }
40
+
42
41
  /**
43
42
  * Unsubscribe from all events emitted by this provider.
44
43
  */
45
-
46
44
  }, {
47
45
  key: "unsubscribeAll",
48
46
  value: function unsubscribeAll(evt) {
@@ -50,6 +48,5 @@ export var Emitter = /*#__PURE__*/function () {
50
48
  return this;
51
49
  }
52
50
  }]);
53
-
54
51
  return Emitter;
55
52
  }();