@atlaskit/collab-provider 7.0.0 → 7.1.2

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 (37) hide show
  1. package/.vscode/settings.json +3 -0
  2. package/CHANGELOG.md +40 -0
  3. package/disconnected-reason-mapper/package.json +7 -0
  4. package/dist/cjs/analytics/index.js +1 -1
  5. package/dist/cjs/analytics/performance.js +1 -1
  6. package/dist/cjs/channel.js +56 -19
  7. package/dist/cjs/disconnected-reason-mapper.js +31 -0
  8. package/dist/cjs/error-code-mapper.js +43 -2
  9. package/dist/cjs/helpers/const.js +1 -1
  10. package/dist/cjs/helpers/utils.js +9 -14
  11. package/dist/cjs/provider/catchup.js +147 -0
  12. package/dist/cjs/{provider.js → provider/index.js} +176 -265
  13. package/dist/cjs/socket-io-provider.js +1 -1
  14. package/dist/cjs/version.json +1 -1
  15. package/dist/es2019/channel.js +34 -7
  16. package/dist/es2019/disconnected-reason-mapper.js +23 -0
  17. package/dist/es2019/error-code-mapper.js +38 -0
  18. package/dist/es2019/helpers/utils.js +9 -14
  19. package/dist/es2019/provider/catchup.js +91 -0
  20. package/dist/es2019/{provider.js → provider/index.js} +126 -195
  21. package/dist/es2019/version.json +1 -1
  22. package/dist/esm/channel.js +54 -19
  23. package/dist/esm/disconnected-reason-mapper.js +23 -0
  24. package/dist/esm/error-code-mapper.js +38 -0
  25. package/dist/esm/helpers/utils.js +8 -13
  26. package/dist/esm/provider/catchup.js +131 -0
  27. package/dist/esm/{provider.js → provider/index.js} +180 -267
  28. package/dist/esm/version.json +1 -1
  29. package/dist/types/channel.d.ts +18 -26
  30. package/dist/types/disconnected-reason-mapper.d.ts +15 -0
  31. package/dist/types/error-code-mapper.d.ts +3 -0
  32. package/dist/types/helpers/utils.d.ts +2 -2
  33. package/dist/types/index.d.ts +1 -1
  34. package/dist/types/provider/catchup.d.ts +24 -0
  35. package/dist/types/{provider.d.ts → provider/index.d.ts} +22 -11
  36. package/package.json +11 -8
  37. package/provider/package.json +0 -7
@@ -35,33 +35,29 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
35
35
 
36
36
  var _prosemirrorCollab = require("prosemirror-collab");
37
37
 
38
- var _prosemirrorTransform = require("prosemirror-transform");
39
-
40
38
  var _throttle = _interopRequireDefault(require("lodash/throttle"));
41
39
 
42
- var _emitter = require("./emitter");
40
+ var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
43
41
 
44
- var _channel = require("./channel");
42
+ var _emitter = require("../emitter");
45
43
 
46
- var _utils = require("./helpers/utils");
44
+ var _channel = require("../channel");
47
45
 
48
- var _const = require("./helpers/const");
46
+ var _utils = require("../helpers/utils");
49
47
 
50
- var _performance = require("./analytics/performance");
48
+ var _const = require("../helpers/const");
51
49
 
52
- var _errorCodeMapper = require("./error-code-mapper");
50
+ var _analytics = require("../analytics");
53
51
 
54
- var _analytics = require("./analytics");
52
+ var _catchup = require("./catchup");
55
53
 
56
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
54
+ var _errorCodeMapper = require("../error-code-mapper");
57
55
 
58
- 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; } }
56
+ var _disconnectedReasonMapper = require("../disconnected-reason-mapper");
59
57
 
60
- function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
61
-
62
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
58
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
63
59
 
64
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
60
+ 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; } }
65
61
 
66
62
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
67
63
 
@@ -77,7 +73,7 @@ var SEND_STEPS_THROTTLE = 500; // 0.5 second
77
73
  var CATCHUP_THROTTLE = 1 * 1000; // 1 second
78
74
 
79
75
  exports.CATCHUP_THROTTLE = CATCHUP_THROTTLE;
80
- var OUT_OF_SYNC_PERIOD = 20 * 1000; // 20 seconds
76
+ var OUT_OF_SYNC_PERIOD = 3 * 1000; // 3 seconds
81
77
 
82
78
  var MAX_STEP_REJECTED_ERROR = 15;
83
79
  exports.MAX_STEP_REJECTED_ERROR = MAX_STEP_REJECTED_ERROR;
@@ -105,35 +101,6 @@ var throttledCommitStep = (0, _throttle.default)(commitStep, SEND_STEPS_THROTTLE
105
101
  leading: false,
106
102
  trailing: true
107
103
  });
108
- /**
109
- * Rebase the steps based on the mapping pipeline.
110
- * Some steps could be lost, if they are no longer
111
- * invalid after rebased.
112
- */
113
-
114
- function rebaseSteps(steps, mapping) {
115
- var newSteps = [];
116
-
117
- var _iterator = _createForOfIteratorHelper(steps),
118
- _step;
119
-
120
- try {
121
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
122
- var step = _step.value;
123
- var newStep = step.map(mapping); // newStep could be null(means invalid after rebase) when can't rebase.
124
-
125
- if (newStep) {
126
- newSteps.push(newStep);
127
- }
128
- }
129
- } catch (err) {
130
- _iterator.e(err);
131
- } finally {
132
- _iterator.f();
133
- }
134
-
135
- return newSteps;
136
- }
137
104
 
138
105
  var Provider = /*#__PURE__*/function (_Emitter) {
139
106
  (0, _inherits2.default)(Provider, _Emitter);
@@ -148,7 +115,7 @@ var Provider = /*#__PURE__*/function (_Emitter) {
148
115
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "participants", new Map());
149
116
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "metadata", {});
150
117
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "stepRejectCounter", 0);
151
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onStepsAdded", function (data, forceApply) {
118
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onStepsAdded", function (data) {
152
119
  logger("Received steps", {
153
120
  steps: data.steps,
154
121
  version: data.version
@@ -166,7 +133,7 @@ var Provider = /*#__PURE__*/function (_Emitter) {
166
133
  if (data.version === currentVersion) {
167
134
  logger("Received steps we already have. Ignoring.");
168
135
  } else if (data.version === expectedVersion) {
169
- _this.processSteps(data, forceApply);
136
+ _this.processSteps(data);
170
137
  } else if (data.version > expectedVersion) {
171
138
  logger("Version too high. Expected \"".concat(expectedVersion, "\" but got \"").concat(data.version, ". Current local version is ").concat(currentVersion, "."));
172
139
 
@@ -180,18 +147,48 @@ var Provider = /*#__PURE__*/function (_Emitter) {
180
147
  return userId;
181
148
  }));
182
149
  });
183
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getCurrentPmVersion", function () {
184
- return (0, _prosemirrorCollab.getVersion)(_this.getState());
185
- });
186
150
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "throttledCatchup", (0, _throttle.default)(function () {
187
151
  return _this.catchup();
188
152
  }, CATCHUP_THROTTLE, {
189
153
  leading: false,
190
154
  trailing: true
191
155
  }));
156
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "fitlerQueue", function (condition) {
157
+ _this.queue = _this.queue.filter(condition);
158
+ });
159
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updateDocumentWithMetadata", function (_ref3) {
160
+ var doc = _ref3.doc,
161
+ version = _ref3.version,
162
+ metadata = _ref3.metadata,
163
+ reserveCursor = _ref3.reserveCursor;
164
+
165
+ _this.emit('init', _objectSpread({
166
+ doc: doc,
167
+ version: version,
168
+ metadata: metadata
169
+ }, reserveCursor ? {
170
+ reserveCursor: reserveCursor
171
+ } : {}));
172
+
173
+ if (metadata && Object.keys(metadata).length > 0) {
174
+ _this.metadata = metadata;
175
+
176
+ _this.emit('metadata:changed', metadata);
177
+ }
178
+ });
179
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "applyLocalsteps", function (steps) {
180
+ // Re-aply local steps
181
+ _this.emit('local-steps', {
182
+ steps: steps
183
+ });
184
+ });
185
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getCurrentPmVersion", function () {
186
+ return (0, _prosemirrorCollab.getVersion)(_this.getState());
187
+ });
188
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getUnconfirmedSteps", function () {
189
+ return (0, _prosemirrorCollab.sendableSteps)(_this.getState());
190
+ });
192
191
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "catchup", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
193
- var _yield$_this$channel$, doc, serverStepMaps, serverVersion, metadata, currentPmVersion, _ref4, unconfirmedSteps, stepMaps, mapping, newUnconfirmedSteps;
194
-
195
192
  return _regenerator.default.wrap(function _callee$(_context) {
196
193
  while (1) {
197
194
  switch (_context.prev = _context.next) {
@@ -207,100 +204,28 @@ var Provider = /*#__PURE__*/function (_Emitter) {
207
204
  case 3:
208
205
  _this.pauseQueue = true;
209
206
  _context.prev = 4;
210
- (0, _performance.startMeasure)('callingCatchupApi');
211
- _context.next = 8;
212
- return _this.channel.fetchCatchup(_this.getCurrentPmVersion());
213
-
214
- case 8:
215
- _yield$_this$channel$ = _context.sent;
216
- doc = _yield$_this$channel$.doc;
217
- serverStepMaps = _yield$_this$channel$.stepMaps;
218
- serverVersion = _yield$_this$channel$.version;
219
- metadata = _yield$_this$channel$.metadata;
220
- (0, _performance.stopMeasure)('callingCatchupApi', function (duration, startTime) {
221
- (0, _analytics.triggerAnalyticsForCatchupSuccessfulWithLatency)(_this.analyticsClient, duration);
207
+ _context.next = 7;
208
+ return (0, _catchup.catchup)({
209
+ getCurrentPmVersion: _this.getCurrentPmVersion,
210
+ fetchCatchup: _this.channel.fetchCatchup.bind(_this.channel),
211
+ getUnconfirmedSteps: _this.getUnconfirmedSteps,
212
+ fitlerQueue: _this.fitlerQueue,
213
+ updateDocumentWithMetadata: _this.updateDocumentWithMetadata,
214
+ applyLocalsteps: _this.applyLocalsteps
222
215
  });
223
216
 
224
- if (doc) {
225
- currentPmVersion = _this.getCurrentPmVersion();
226
-
227
- if (typeof serverVersion === 'undefined') {
228
- logger("Could not determine server version");
229
- } else if (serverVersion <= currentPmVersion) {
230
- logger("Catchup steps we already have. Ignoring.");
231
- } else {
232
- // Please, do not use those steps inside of async
233
- // method. That will lead to outdated steps
234
- _ref4 = (0, _prosemirrorCollab.sendableSteps)(_this.getState()) || {
235
- steps: []
236
- }, unconfirmedSteps = _ref4.steps;
237
- logger("Too far behind[current: v".concat(currentPmVersion, ", server: v").concat(serverVersion, ". ").concat(serverStepMaps.length, " steps need to catchup]"));
238
- /**
239
- * Remove steps from queue where the version is older than
240
- * the version we received from service. Keep steps that might be
241
- * newer.
242
- */
243
-
244
- _this.queue = _this.queue.filter(function (data) {
245
- return data.version > serverVersion;
246
- }); // We are too far behind - replace the entire document
247
-
248
- logger("Replacing document: ".concat(doc));
249
- logger("getting metadata: ".concat(metadata)); // Replace local document and version number
250
-
251
- _this.emit('init', {
252
- doc: JSON.parse(doc),
253
- version: serverVersion,
254
- metadata: metadata,
255
- reserveCursor: true
256
- });
257
-
258
- if (metadata && Object.keys(metadata).length > 0) {
259
- _this.metadata = metadata;
260
-
261
- _this.emit('metadata:changed', metadata);
262
- } // After replacing the whole document in the editor, we need to reapply the unconfirmed
263
- // steps back into the editor, so we don't lose any data. But before that, we need to rebase
264
- // those steps since their position could be changed after replacing.
265
- // https://prosemirror.net/docs/guide/#transform.rebasing
266
-
267
-
268
- if (unconfirmedSteps.length) {
269
- // Create StepMap from StepMap JSON
270
- // eslint-disable-next-line no-unused-vars
271
- stepMaps = serverStepMaps.map(function (_ref5) {
272
- var ranges = _ref5.ranges,
273
- inverted = _ref5.inverted;
274
- // Due to @types/prosemirror-transform mismatch with the actual
275
- // constructor, hack to set the `inverted`.
276
- var stepMap = new _prosemirrorTransform.StepMap(ranges);
277
- stepMap.inverted = inverted;
278
- return stepMap;
279
- }); // create Mappng used for Step.map
280
-
281
- mapping = new _prosemirrorTransform.Mapping(stepMaps);
282
- logger("".concat(unconfirmedSteps.length, " unconfirmed steps before rebased: ").concat(JSON.stringify(unconfirmedSteps)));
283
- newUnconfirmedSteps = rebaseSteps(unconfirmedSteps, mapping);
284
- logger("Re-aply ".concat(newUnconfirmedSteps.length, " mapped unconfirmed steps: ").concat(JSON.stringify(newUnconfirmedSteps))); // Re-aply local steps
285
-
286
- _this.emit('local-steps', {
287
- steps: newUnconfirmedSteps
288
- });
289
- }
290
- }
291
- }
292
-
293
- _context.next = 21;
217
+ case 7:
218
+ _context.next = 13;
294
219
  break;
295
220
 
296
- case 17:
297
- _context.prev = 17;
221
+ case 9:
222
+ _context.prev = 9;
298
223
  _context.t0 = _context["catch"](4);
299
224
  (0, _analytics.triggerAnalyticsForCatchupFailed)(_this.analyticsClient, _context.t0);
300
225
  logger("Catch-Up Failed:", _context.t0.message);
301
226
 
302
- case 21:
303
- _context.prev = 21;
227
+ case 13:
228
+ _context.prev = 13;
304
229
  _this.pauseQueue = false;
305
230
 
306
231
  _this.processQueue();
@@ -308,53 +233,15 @@ var Provider = /*#__PURE__*/function (_Emitter) {
308
233
  _this.sendStepsFromCurrentState();
309
234
 
310
235
  _this.stepRejectCounter = 0;
311
- return _context.finish(21);
236
+ return _context.finish(13);
312
237
 
313
- case 27:
238
+ case 19:
314
239
  case "end":
315
240
  return _context.stop();
316
241
  }
317
242
  }
318
- }, _callee, null, [[4, 17, 21, 27]]);
243
+ }, _callee, null, [[4, 9, 13, 19]]);
319
244
  })));
320
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "errorCodeMapper", function (error) {
321
- if (error.data) {
322
- switch (error.data.code) {
323
- case 'INSUFFICIENT_EDITING_PERMISSION':
324
- return {
325
- status: 403,
326
- code: _errorCodeMapper.ErrorCodeMapper.noPermissionError.code,
327
- message: _errorCodeMapper.ErrorCodeMapper.noPermissionError.message
328
- };
329
-
330
- case 'DOCUMENT_NOT_FOUND':
331
- return {
332
- status: 404,
333
- code: _errorCodeMapper.ErrorCodeMapper.documentNotFound.code,
334
- message: _errorCodeMapper.ErrorCodeMapper.documentNotFound.message
335
- };
336
-
337
- case 'FAILED_ON_S3':
338
- case 'DYNAMO_ERROR':
339
- return {
340
- status: 500,
341
- code: _errorCodeMapper.ErrorCodeMapper.failToSave.code,
342
- message: _errorCodeMapper.ErrorCodeMapper.failToSave.message
343
- };
344
-
345
- case 'CATCHUP_FAILED':
346
- case 'GET_QUERY_TIME_OUT':
347
- return {
348
- status: 500,
349
- code: _errorCodeMapper.ErrorCodeMapper.internalError.code,
350
- message: _errorCodeMapper.ErrorCodeMapper.internalError.message
351
- };
352
-
353
- default:
354
- break;
355
- }
356
- }
357
- });
358
245
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onErrorHandled", function (error) {
359
246
  if (error && error.data) {
360
247
  if (error.data.code === 'HEAD_VERSION_UPDATE_FAILED' || error.data.code === 'VERSION_NUMBER_ALREADY_EXISTS') {
@@ -370,7 +257,7 @@ var Provider = /*#__PURE__*/function (_Emitter) {
370
257
  _this.throttledCatchup();
371
258
  }
372
259
 
373
- var errorToEmit = _this.errorCodeMapper(error);
260
+ var errorToEmit = (0, _errorCodeMapper.errorCodeMapper)(error);
374
261
 
375
262
  if (errorToEmit) {
376
263
  _this.emit('error', errorToEmit);
@@ -395,36 +282,28 @@ var Provider = /*#__PURE__*/function (_Emitter) {
395
282
  return _this.sendPresence();
396
283
  }, SEND_PRESENCE_INTERVAL);
397
284
  });
398
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onParticipantJoined", function (_ref6) {
399
- var sessionId = _ref6.sessionId;
285
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onPresenceJoined", function (_ref5) {
286
+ var sessionId = _ref5.sessionId;
400
287
  logger('Participant joined with session: ', sessionId); // This expose existing users to the newly joined user
401
288
 
402
289
  _this.sendPresence();
403
290
  });
404
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onTitleChanged", function (_ref7) {
405
- var title = _ref7.title;
291
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onPresence", function (_ref6) {
292
+ var userId = _ref6.userId;
293
+ logger('onPresence userId: ', userId);
294
+ _this.userId = userId;
406
295
 
407
- if (title !== undefined && _this.metadata.title !== title) {
408
- _this.metadata.title = title;
296
+ _this.sendPresence();
409
297
 
410
- _this.emit('metadata:changed', {
411
- title: title
412
- });
413
- }
298
+ _this.channel.sendPresenceJoined();
414
299
  });
415
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onWidthChanged", function (_ref8) {
416
- var editorWidth = _ref8.editorWidth;
417
-
418
- if (editorWidth !== undefined && _this.metadata.editorWidth !== editorWidth) {
419
- _this.metadata.editorWidth = editorWidth;
420
-
421
- _this.emit('metadata:changed', {
422
- editorWidth: editorWidth
423
- });
300
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onMetadataChanged", function (metadata) {
301
+ if (metadata !== undefined && !(0, _isEqual.default)(_this.metadata, metadata)) {
302
+ _this.emit('metadata:changed', metadata);
424
303
  }
425
304
  });
426
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onParticipantLeft", function (_ref9) {
427
- var sessionId = _ref9.sessionId;
305
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onParticipantLeft", function (_ref7) {
306
+ var sessionId = _ref7.sessionId;
428
307
  logger("Participant left");
429
308
 
430
309
  _this.participants.delete(sessionId);
@@ -435,11 +314,11 @@ var Provider = /*#__PURE__*/function (_Emitter) {
435
314
  }]
436
315
  });
437
316
  });
438
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onParticipantUpdated", function (_ref10) {
439
- var sessionId = _ref10.sessionId,
440
- timestamp = _ref10.timestamp,
441
- userId = _ref10.userId,
442
- clientId = _ref10.clientId;
317
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onParticipantUpdated", function (_ref8) {
318
+ var sessionId = _ref8.sessionId,
319
+ timestamp = _ref8.timestamp,
320
+ userId = _ref8.userId,
321
+ clientId = _ref8.clientId;
443
322
 
444
323
  _this.updateParticipant({
445
324
  sessionId: sessionId,
@@ -448,12 +327,12 @@ var Provider = /*#__PURE__*/function (_Emitter) {
448
327
  clientId: clientId
449
328
  });
450
329
  });
451
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onParticipantTelepointer", function (_ref11) {
452
- var sessionId = _ref11.sessionId,
453
- timestamp = _ref11.timestamp,
454
- selection = _ref11.selection,
455
- userId = _ref11.userId,
456
- clientId = _ref11.clientId;
330
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onParticipantTelepointer", function (_ref9) {
331
+ var sessionId = _ref9.sessionId,
332
+ timestamp = _ref9.timestamp,
333
+ selection = _ref9.selection,
334
+ userId = _ref9.userId,
335
+ clientId = _ref9.clientId;
457
336
 
458
337
  if (sessionId === _this.sessionId) {
459
338
  return;
@@ -481,19 +360,28 @@ var Provider = /*#__PURE__*/function (_Emitter) {
481
360
  });
482
361
  });
483
362
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updateParticipant", /*#__PURE__*/function () {
484
- var _ref13 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref12) {
363
+ var _ref11 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref10) {
485
364
  var sessionId, timestamp, userId, clientId, getUser, _yield, _yield$name, name, _yield$email, email, _yield$avatar, avatar, isNewParticipant;
486
365
 
487
366
  return _regenerator.default.wrap(function _callee2$(_context2) {
488
367
  while (1) {
489
368
  switch (_context2.prev = _context2.next) {
490
369
  case 0:
491
- sessionId = _ref12.sessionId, timestamp = _ref12.timestamp, userId = _ref12.userId, clientId = _ref12.clientId;
370
+ sessionId = _ref10.sessionId, timestamp = _ref10.timestamp, userId = _ref10.userId, clientId = _ref10.clientId;
371
+
372
+ if (userId) {
373
+ _context2.next = 3;
374
+ break;
375
+ }
376
+
377
+ return _context2.abrupt("return");
378
+
379
+ case 3:
492
380
  getUser = _this.config.getUser;
493
- _context2.next = 4;
381
+ _context2.next = 6;
494
382
  return getUser ? getUser(userId) : (0, _utils.getParticipant)(userId);
495
383
 
496
- case 4:
384
+ case 6:
497
385
  _yield = _context2.sent;
498
386
  _yield$name = _yield.name;
499
387
  name = _yield$name === void 0 ? '' : _yield$name;
@@ -523,7 +411,7 @@ var Provider = /*#__PURE__*/function (_Emitter) {
523
411
 
524
412
  _this.updateParticipants(isNewParticipant ? [_this.participants.get(sessionId)] : []);
525
413
 
526
- case 15:
414
+ case 17:
527
415
  case "end":
528
416
  return _context2.stop();
529
417
  }
@@ -532,7 +420,7 @@ var Provider = /*#__PURE__*/function (_Emitter) {
532
420
  }));
533
421
 
534
422
  return function (_x) {
535
- return _ref13.apply(this, arguments);
423
+ return _ref11.apply(this, arguments);
536
424
  };
537
425
  }());
538
426
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updateParticipants", function () {
@@ -571,13 +459,39 @@ var Provider = /*#__PURE__*/function (_Emitter) {
571
459
  return _this.updateParticipants();
572
460
  }, PARTICIPANT_UPDATE_INTERVAL);
573
461
  });
574
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onDisconnected", function (_ref14) {
575
- var reason = _ref14.reason;
462
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "disconnectedReasonMapper", function (reason) {
463
+ switch (reason) {
464
+ case _disconnectedReasonMapper.socketIOReasons.IO_CLIENT_DISCONNECT:
465
+ return _disconnectedReasonMapper.DisconnectReason.CLIENT_DISCONNECT;
466
+
467
+ case _disconnectedReasonMapper.socketIOReasons.IO_SERVER_DISCONNECT:
468
+ return _disconnectedReasonMapper.DisconnectReason.SERVER_DISCONNECT;
469
+
470
+ case _disconnectedReasonMapper.socketIOReasons.TRANSPORT_CLOSED:
471
+ return _disconnectedReasonMapper.DisconnectReason.SOCKET_CLOSED;
472
+
473
+ case _disconnectedReasonMapper.socketIOReasons.TRANSPORT_ERROR:
474
+ return _disconnectedReasonMapper.DisconnectReason.SOCKET_ERROR;
475
+
476
+ case _disconnectedReasonMapper.socketIOReasons.PING_TIMEOUT:
477
+ return _disconnectedReasonMapper.DisconnectReason.SOCKET_TIMEOUT;
478
+
479
+ default:
480
+ return _disconnectedReasonMapper.DisconnectReason.UNKNOWN_DISCONNECT;
481
+ }
482
+ });
483
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onDisconnected", function (_ref12) {
484
+ var reason = _ref12.reason;
576
485
  _this.disconnectedAt = Date.now();
577
486
  var left = Array.from(_this.participants.values());
578
487
 
579
488
  _this.participants.clear();
580
489
 
490
+ _this.emit('disconnected', {
491
+ reason: _this.disconnectedReasonMapper(reason),
492
+ sid: _this.sessionId
493
+ });
494
+
581
495
  if (left.length) {
582
496
  _this.emit('presence', {
583
497
  left: left
@@ -609,16 +523,14 @@ var Provider = /*#__PURE__*/function (_Emitter) {
609
523
  this.getState().plugins.find(function (p) {
610
524
  return p.key === 'collab$';
611
525
  }).spec.config.clientID : optionsOrGetState.clientId;
612
- this.channel.on('connected', function (_ref15) {
613
- var sid = _ref15.sid,
614
- initialized = _ref15.initialized;
526
+ this.channel.on('connected', function (_ref13) {
527
+ var sid = _ref13.sid,
528
+ initialized = _ref13.initialized;
615
529
  _this2.sessionId = sid;
616
530
 
617
531
  _this2.emit('connected', {
618
532
  sid: sid
619
- });
620
-
621
- _this2.sendPresence(); // If already initialized, `connected` means reconnected
533
+ }); // If already initialized, `connected` means reconnected
622
534
 
623
535
 
624
536
  if (initialized && _this2.disconnectedAt && // Offline longer than `OUT_OF_SYNC_PERIOD`
@@ -627,29 +539,18 @@ var Provider = /*#__PURE__*/function (_Emitter) {
627
539
  }
628
540
 
629
541
  _this2.disconnectedAt = undefined;
630
- }).on('init', function (_ref16) {
631
- var doc = _ref16.doc,
632
- version = _ref16.version,
633
- userId = _ref16.userId,
634
- metadata = _ref16.metadata;
635
- _this2.userId = userId;
636
-
637
- _this2.sendPresence();
542
+ }).on('init', function (_ref14) {
543
+ var doc = _ref14.doc,
544
+ version = _ref14.version,
545
+ metadata = _ref14.metadata;
638
546
 
639
- _this2.emit('init', {
547
+ // Initial document and version
548
+ _this2.updateDocumentWithMetadata({
640
549
  doc: doc,
641
550
  version: version,
642
551
  metadata: metadata
643
- }); // Initial document and version
644
- // Initialise metadata
645
-
646
-
647
- if (metadata) {
648
- _this2.metadata = metadata;
649
-
650
- _this2.emit('metadata:changed', metadata);
651
- }
652
- }).on('steps:added', this.onStepsAdded).on('participant:telepointer', this.onParticipantTelepointer).on('participant:joined', this.onParticipantJoined).on('participant:left', this.onParticipantLeft).on('participant:updated', this.onParticipantUpdated).on('title:changed', this.onTitleChanged).on('width:changed', this.onWidthChanged).on('disconnect', this.onDisconnected).on('error', this.onErrorHandled).connect();
552
+ });
553
+ }).on('steps:added', this.onStepsAdded).on('participant:telepointer', this.onParticipantTelepointer).on('presence:joined', this.onPresenceJoined).on('presence', this.onPresence).on('participant:left', this.onParticipantLeft).on('participant:updated', this.onParticipantUpdated).on('metadata:changed', this.onMetadataChanged).on('disconnect', this.onDisconnected).on('error', this.onErrorHandled).connect();
653
554
  return this;
654
555
  }
655
556
  /**
@@ -740,7 +641,7 @@ var Provider = /*#__PURE__*/function (_Emitter) {
740
641
  }
741
642
  }, {
742
643
  key: "processSteps",
743
- value: function processSteps(data, forceApply) {
644
+ value: function processSteps(data) {
744
645
  var _this3 = this;
745
646
 
746
647
  var version = data.version,
@@ -748,8 +649,8 @@ var Provider = /*#__PURE__*/function (_Emitter) {
748
649
  logger("Processing data. Version \"".concat(version, "\"."));
749
650
 
750
651
  if (steps && steps.length) {
751
- var clientIds = steps.map(function (_ref17) {
752
- var clientId = _ref17.clientId;
652
+ var clientIds = steps.map(function (_ref15) {
653
+ var clientId = _ref15.clientId;
753
654
  return clientId;
754
655
  });
755
656
  this.emit('data', {
@@ -811,14 +712,14 @@ var Provider = /*#__PURE__*/function (_Emitter) {
811
712
  participant = _Array$from$filter2[0];
812
713
 
813
714
  if (participant) {
814
- var _ref18 = step,
815
- stepType = _ref18.stepType,
816
- to = _ref18.to,
817
- from = _ref18.from,
818
- _ref18$slice = _ref18.slice,
819
- slice = _ref18$slice === void 0 ? {
715
+ var _ref16 = step,
716
+ stepType = _ref16.stepType,
717
+ to = _ref16.to,
718
+ from = _ref16.from,
719
+ _ref16$slice = _ref16.slice,
720
+ slice = _ref16$slice === void 0 ? {
820
721
  content: []
821
- } : _ref18$slice;
722
+ } : _ref16$slice;
822
723
 
823
724
  var _slice$content = (0, _slicedToArray2.default)(slice.content, 1),
824
725
  node = _slice$content[0];
@@ -850,24 +751,34 @@ var Provider = /*#__PURE__*/function (_Emitter) {
850
751
  }, {
851
752
  key: "setTitle",
852
753
  value: function setTitle(title, broadcast) {
853
- this.metadata.title = title;
854
-
855
754
  if (broadcast) {
856
- this.channel.broadcast('title:changed', {
755
+ this.channel.sendMetadata({
857
756
  title: title
858
757
  });
859
758
  }
759
+
760
+ Object.assign(this.metadata, {
761
+ title: title
762
+ });
860
763
  }
861
764
  }, {
862
765
  key: "setEditorWidth",
863
766
  value: function setEditorWidth(editorWidth, broadcast) {
864
- this.metadata.editorWidth = editorWidth;
865
-
866
767
  if (broadcast) {
867
- this.channel.broadcast('width:changed', {
768
+ this.channel.sendMetadata({
868
769
  editorWidth: editorWidth
869
770
  });
870
771
  }
772
+
773
+ Object.assign(this.metadata, {
774
+ editorWidth: editorWidth
775
+ });
776
+ }
777
+ }, {
778
+ key: "setMetadata",
779
+ value: function setMetadata(metadata) {
780
+ this.channel.sendMetadata(metadata);
781
+ Object.assign(this.metadata, metadata);
871
782
  }
872
783
  /**
873
784
  * Get latest state.
@@ -879,9 +790,9 @@ var Provider = /*#__PURE__*/function (_Emitter) {
879
790
  key: "getFinalAcknowledgedState",
880
791
  value: function () {
881
792
  var _getFinalAcknowledgedState = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
882
- var _sendableSteps;
793
+ var _this$getUnconfirmedS;
883
794
 
884
- var state, count, unconfirmedSteps, _sendableSteps2;
795
+ var state, count, unconfirmedSteps, _this$getUnconfirmedS2;
885
796
 
886
797
  return _regenerator.default.wrap(function _callee3$(_context3) {
887
798
  while (1) {
@@ -889,7 +800,7 @@ var Provider = /*#__PURE__*/function (_Emitter) {
889
800
  case 0:
890
801
  state = this.getState();
891
802
  count = 0;
892
- unconfirmedSteps = (0, _prosemirrorCollab.sendableSteps)(this.getState()) && ((_sendableSteps = (0, _prosemirrorCollab.sendableSteps)(this.getState())) === null || _sendableSteps === void 0 ? void 0 : _sendableSteps.steps);
803
+ unconfirmedSteps = this.getUnconfirmedSteps() && ((_this$getUnconfirmedS = this.getUnconfirmedSteps()) === null || _this$getUnconfirmedS === void 0 ? void 0 : _this$getUnconfirmedS.steps);
893
804
 
894
805
  case 3:
895
806
  if (!(unconfirmedSteps && unconfirmedSteps.length)) {
@@ -902,7 +813,7 @@ var Provider = /*#__PURE__*/function (_Emitter) {
902
813
  return (0, _utils.sleep)(500);
903
814
 
904
815
  case 7:
905
- unconfirmedSteps = (0, _prosemirrorCollab.sendableSteps)(this.getState()) && ((_sendableSteps2 = (0, _prosemirrorCollab.sendableSteps)(this.getState())) === null || _sendableSteps2 === void 0 ? void 0 : _sendableSteps2.steps);
816
+ unconfirmedSteps = this.getUnconfirmedSteps() && ((_this$getUnconfirmedS2 = this.getUnconfirmedSteps()) === null || _this$getUnconfirmedS2 === void 0 ? void 0 : _this$getUnconfirmedS2.steps);
906
817
 
907
818
  if (!(count++ >= _const.ACK_MAX_TRY)) {
908
819
  _context3.next = 10;