@atlaskit/collab-provider 8.5.0 → 8.7.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 (76) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/cjs/analytics/analytics-helper.js +22 -24
  3. package/dist/cjs/analytics/performance.js +4 -4
  4. package/dist/cjs/channel.js +218 -203
  5. package/dist/cjs/connectivity/network.js +4 -4
  6. package/dist/cjs/disconnected-reason-mapper.js +4 -4
  7. package/dist/cjs/document/catchup.js +81 -81
  8. package/dist/cjs/document/document-service.js +226 -285
  9. package/dist/cjs/document/step-queue-state.js +4 -0
  10. package/dist/cjs/errors/error-types.js +102 -23
  11. package/dist/cjs/helpers/const.js +12 -12
  12. package/dist/cjs/index.js +8 -1
  13. package/dist/cjs/metadata/metadata-service.js +77 -0
  14. package/dist/cjs/participants/participants-helper.js +19 -28
  15. package/dist/cjs/participants/participants-service.js +90 -60
  16. package/dist/cjs/participants/participants-state.js +1 -0
  17. package/dist/cjs/provider/commit-step.js +10 -2
  18. package/dist/cjs/provider/index.js +168 -101
  19. package/dist/cjs/types.js +12 -4
  20. package/dist/cjs/version-wrapper.js +1 -1
  21. package/dist/cjs/version.json +1 -1
  22. package/dist/es2019/analytics/analytics-helper.js +3 -3
  23. package/dist/es2019/analytics/performance.js +3 -3
  24. package/dist/es2019/channel.js +27 -6
  25. package/dist/es2019/connectivity/network.js +3 -3
  26. package/dist/es2019/disconnected-reason-mapper.js +3 -3
  27. package/dist/es2019/document/catchup.js +4 -2
  28. package/dist/es2019/document/document-service.js +45 -76
  29. package/dist/es2019/document/step-queue-state.js +4 -0
  30. package/dist/es2019/errors/error-types.js +104 -25
  31. package/dist/es2019/helpers/const.js +9 -9
  32. package/dist/es2019/index.js +2 -1
  33. package/dist/es2019/metadata/metadata-service.js +57 -0
  34. package/dist/es2019/participants/participants-helper.js +3 -8
  35. package/dist/es2019/participants/participants-service.js +46 -15
  36. package/dist/es2019/participants/participants-state.js +1 -0
  37. package/dist/es2019/provider/commit-step.js +8 -1
  38. package/dist/es2019/provider/index.js +111 -39
  39. package/dist/es2019/types.js +16 -3
  40. package/dist/es2019/version-wrapper.js +1 -1
  41. package/dist/es2019/version.json +1 -1
  42. package/dist/esm/analytics/analytics-helper.js +22 -24
  43. package/dist/esm/analytics/performance.js +3 -3
  44. package/dist/esm/channel.js +218 -203
  45. package/dist/esm/connectivity/network.js +3 -3
  46. package/dist/esm/disconnected-reason-mapper.js +3 -3
  47. package/dist/esm/document/catchup.js +81 -81
  48. package/dist/esm/document/document-service.js +226 -285
  49. package/dist/esm/document/step-queue-state.js +4 -0
  50. package/dist/esm/errors/error-types.js +104 -25
  51. package/dist/esm/helpers/const.js +9 -9
  52. package/dist/esm/index.js +2 -1
  53. package/dist/esm/metadata/metadata-service.js +69 -0
  54. package/dist/esm/participants/participants-helper.js +19 -28
  55. package/dist/esm/participants/participants-service.js +90 -60
  56. package/dist/esm/participants/participants-state.js +1 -0
  57. package/dist/esm/provider/commit-step.js +8 -1
  58. package/dist/esm/provider/index.js +167 -99
  59. package/dist/esm/types.js +16 -3
  60. package/dist/esm/version-wrapper.js +1 -1
  61. package/dist/esm/version.json +1 -1
  62. package/dist/types/channel.d.ts +2 -2
  63. package/dist/types/document/document-service.d.ts +5 -24
  64. package/dist/types/index.d.ts +2 -1
  65. package/dist/types/metadata/metadata-service.d.ts +25 -0
  66. package/dist/types/participants/participants-helper.d.ts +2 -3
  67. package/dist/types/participants/participants-service.d.ts +8 -8
  68. package/dist/types/provider/commit-step.d.ts +11 -0
  69. package/dist/types/provider/index.d.ts +15 -13
  70. package/dist/types/types.d.ts +24 -10
  71. package/package.json +12 -7
  72. package/report.api.md +26 -7
  73. package/channel/package.json +0 -15
  74. package/config/package.json +0 -15
  75. package/disconnected-reason-mapper/package.json +0 -15
  76. package/emitter/package.json +0 -15
@@ -9,9 +9,7 @@ import _wrapNativeSuper from "@babel/runtime/helpers/wrapNativeSuper";
9
9
  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); }; }
10
10
  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; } }
11
11
  // Internal error codes (generated by collab provider)
12
- export var INTERNAL_ERROR_CODE;
13
- // NCS error coded (generated by NCS)
14
- (function (INTERNAL_ERROR_CODE) {
12
+ export var INTERNAL_ERROR_CODE = /*#__PURE__*/function (INTERNAL_ERROR_CODE) {
15
13
  INTERNAL_ERROR_CODE["TOKEN_PERMISSION_ERROR"] = "TOKEN_PERMISSION_ERROR";
16
14
  INTERNAL_ERROR_CODE["RECONNECTION_NETWORK_ISSUE"] = "RECONNECTION_NETWORK_ISSUE";
17
15
  INTERNAL_ERROR_CODE["CONNECTION_ERROR"] = "CONNECTION_ERROR";
@@ -20,14 +18,10 @@ export var INTERNAL_ERROR_CODE;
20
18
  INTERNAL_ERROR_CODE["CATCHUP_FAILED"] = "CATCHUP_FAILED";
21
19
  INTERNAL_ERROR_CODE["DOCUMENT_RESTORE_ERROR"] = "DOCUMENT_RESTORE_ERROR";
22
20
  INTERNAL_ERROR_CODE["ADD_STEPS_ERROR"] = "ADD_STEPS_ERROR";
23
- })(INTERNAL_ERROR_CODE || (INTERNAL_ERROR_CODE = {}));
24
- export var NCS_ERROR_CODE;
25
-
26
- // TODO: Import emitted error codes from NCS
27
-
28
- // NCS Errors
29
- // - Step rejection errors
30
- (function (NCS_ERROR_CODE) {
21
+ return INTERNAL_ERROR_CODE;
22
+ }({});
23
+ // NCS error coded (generated by NCS)
24
+ export var NCS_ERROR_CODE = /*#__PURE__*/function (NCS_ERROR_CODE) {
31
25
  NCS_ERROR_CODE["HEAD_VERSION_UPDATE_FAILED"] = "HEAD_VERSION_UPDATE_FAILED";
32
26
  NCS_ERROR_CODE["VERSION_NUMBER_ALREADY_EXISTS"] = "VERSION_NUMBER_ALREADY_EXISTS";
33
27
  NCS_ERROR_CODE["INSUFFICIENT_EDITING_PERMISSION"] = "INSUFFICIENT_EDITING_PERMISSION";
@@ -44,9 +38,36 @@ export var NCS_ERROR_CODE;
44
38
  NCS_ERROR_CODE["INVALID_ACTIVATION_ID"] = "INVALID_ACTIVATION_ID";
45
39
  NCS_ERROR_CODE["INVALID_DOCUMENT_ARI"] = "INVALID_DOCUMENT_ARI";
46
40
  NCS_ERROR_CODE["INVALID_CLOUD_ID"] = "INVALID_CLOUD_ID";
47
- })(NCS_ERROR_CODE || (NCS_ERROR_CODE = {}));
41
+ return NCS_ERROR_CODE;
42
+ }({});
43
+
44
+ // TODO: Import emitted error codes from NCS
45
+
46
+ // NCS Errors
47
+ // - Step rejection errors
48
+ // - Permission errors
49
+ // - Page missing / TTL errors
50
+ // - Server errors
51
+ // - Less common back-end errors
52
+ // Provider Errors
53
+ // Channel Errors
54
+ /**
55
+ * A union of all possible internal errors, that are mapped to another error if being emitted to the editor.
56
+ */
48
57
  // Emitted errors
49
- export var PROVIDER_ERROR_CODE;
58
+ export var PROVIDER_ERROR_CODE = /*#__PURE__*/function (PROVIDER_ERROR_CODE) {
59
+ PROVIDER_ERROR_CODE["NO_PERMISSION_ERROR"] = "NO_PERMISSION_ERROR";
60
+ PROVIDER_ERROR_CODE["INVALID_USER_TOKEN"] = "INVALID_USER_TOKEN";
61
+ PROVIDER_ERROR_CODE["DOCUMENT_NOT_FOUND"] = "DOCUMENT_NOT_FOUND";
62
+ PROVIDER_ERROR_CODE["LOCKED"] = "LOCKED";
63
+ PROVIDER_ERROR_CODE["FAIL_TO_SAVE"] = "FAIL_TO_SAVE";
64
+ PROVIDER_ERROR_CODE["DOCUMENT_RESTORE_ERROR"] = "DOCUMENT_RESTORE_ERROR";
65
+ PROVIDER_ERROR_CODE["INITIALISATION_ERROR"] = "INITIALISATION_ERROR";
66
+ PROVIDER_ERROR_CODE["NETWORK_ISSUE"] = "NETWORK_ISSUE";
67
+ PROVIDER_ERROR_CODE["INVALID_PROVIDER_CONFIGURATION"] = "INVALID_PROVIDER_CONFIGURATION";
68
+ PROVIDER_ERROR_CODE["INTERNAL_SERVICE_ERROR"] = "INTERNAL_SERVICE_ERROR";
69
+ return PROVIDER_ERROR_CODE;
70
+ }({});
50
71
 
51
72
  /*
52
73
  * This is what a generic ProviderError type would look like:
@@ -71,18 +92,76 @@ export var PROVIDER_ERROR_CODE;
71
92
  * @message Message returned to editor, i.e User does not have permissions to access this document or document is not found
72
93
  * @recoverable It is recoverable, as we will try to refresh the token.
73
94
  */
74
- (function (PROVIDER_ERROR_CODE) {
75
- PROVIDER_ERROR_CODE["NO_PERMISSION_ERROR"] = "NO_PERMISSION_ERROR";
76
- PROVIDER_ERROR_CODE["INVALID_USER_TOKEN"] = "INVALID_USER_TOKEN";
77
- PROVIDER_ERROR_CODE["DOCUMENT_NOT_FOUND"] = "DOCUMENT_NOT_FOUND";
78
- PROVIDER_ERROR_CODE["LOCKED"] = "LOCKED";
79
- PROVIDER_ERROR_CODE["FAIL_TO_SAVE"] = "FAIL_TO_SAVE";
80
- PROVIDER_ERROR_CODE["DOCUMENT_RESTORE_ERROR"] = "DOCUMENT_RESTORE_ERROR";
81
- PROVIDER_ERROR_CODE["INITIALISATION_ERROR"] = "INITIALISATION_ERROR";
82
- PROVIDER_ERROR_CODE["NETWORK_ISSUE"] = "NETWORK_ISSUE";
83
- PROVIDER_ERROR_CODE["INVALID_PROVIDER_CONFIGURATION"] = "INVALID_PROVIDER_CONFIGURATION";
84
- PROVIDER_ERROR_CODE["INTERNAL_SERVICE_ERROR"] = "INTERNAL_SERVICE_ERROR";
85
- })(PROVIDER_ERROR_CODE || (PROVIDER_ERROR_CODE = {}));
95
+ /**
96
+ * Similiar to InsufficientEditingPermission, but the user token is invalid because it has expired or been revoked.
97
+ * It may also be an invalid token format.
98
+ * This error is given to the provider by NCS.
99
+ * @message Message returned to editor, i.e. The user token was invalid
100
+ * @recoverable It is recoverable, as we will try to refresh the token.
101
+ */
102
+ /**
103
+ * Document not found error, thrown when the provider is unable to find a document with the given ARI and user token.
104
+ * It occurs during fetchCatchup, a function that fetches the latest document state during catchup.
105
+ * We need to recieve a 404 from the document service to throw this error.
106
+ * @message Message returned to editor, i.e. The requested document is not found
107
+ * @recoverable It is recoverable, as the provider can try again later.
108
+ */
109
+ /**
110
+ * This error is thrown when the document is locked by another user.
111
+ * The error is passed to us by NCS.
112
+ * @message Message returned to editor, i.e. The document is currently not available, please try again later
113
+ * @recoverable It is recoverable, as the provider can try again later.
114
+ */
115
+ /**
116
+ * This error is thrown when the provider is unable to save the document.
117
+ * This can happen when the connection to dynamoDB is lost, or when we do not have sufficient permissions (DYNAMO ERROR).
118
+ * This error is given to us by NCS.
119
+ * @message Message returned to editor, i.e. Collab service is not able to save changes
120
+ * @recoverable It is not recoverable, as we don't want the user to continue editing a document that is not being saved.
121
+ */
122
+ /**
123
+ * This error is thrown when the provider is unable to restore the document.
124
+ * It occurs during onRestore, a function that restores the document to a previous version and reapplies unconfirmed steps.
125
+ * onRestore is called when page recovery has emitted an 'init' event on a page client is currently connected to.
126
+ * It could mean we failed to update the page metadata, or we failed to reapply unconfirmed steps.
127
+ * @message Message returned to editor, i.e. Collab service unable to restore document
128
+ * @recoverable It is not recoverable, as the provider has no further options after this.
129
+ * The user will need to refresh the page to try again.
130
+ */
131
+ /**
132
+ * The initial document couldn't be loaded from the collab service.
133
+ * This error is given to us by NCS.
134
+ * It could indicate either a network issue, or an internal service error in NCS.
135
+ * @message Message returned to editor, i.e. The initial document couldn't be loaded from the collab service
136
+ * @recoverable It is not recoverable, as the provider cannot do anything to fix it.
137
+ * The user will need to refresh the page to try again.
138
+ */
139
+ /**
140
+ * Couldn't reconnect to the collab service (NCS) due to network issues.
141
+ * NCS could be down, or the user could be offline. It's also possible the url is incorrect, or the user is behind a proxy blocking the connection.
142
+ * Fired upon a reconnection attempt error (from Socket.IO Manager)
143
+ * @message Message returned to editor, i.e. Couldn't reconnect to the collab service due to network issues
144
+ * @recoverable It is recoverable, as the provider will try to reconnect.
145
+ */
146
+ /**
147
+ * This error is thrown when the provider has an invalid configuration.
148
+ * It could happen due to these errors from NCS:
149
+ * NAMESPACE_INVALID
150
+ INVALID_ACTIVATION_ID
151
+ INVALID_DOCUMENT_ARI
152
+ INVALID_CLOUD_ID
153
+ * @message Message returned to editor, i.e. Invalid provider configuration
154
+ * @recoverable It is not recoverable, as the provider cannot do anything to fix it.
155
+ * The service using the provider will need to fix the configuration.
156
+ */
157
+ /**
158
+ * This error is thrown when the provider encounters an internal service error, not otherwise accounted for.
159
+ * @message Message returned to editor, i.e. Collab Provider experienced an unrecoverable error
160
+ * @recoverable It is not recoverable, as the provider cannot do anything to fix it.
161
+ */
162
+ /**
163
+ * A union of all possible provider errors that can be emitted back to the editor.
164
+ */
86
165
  // Custom Errors
87
166
  var CustomError = /*#__PURE__*/function (_Error) {
88
167
  _inherits(CustomError, _Error);
@@ -1,5 +1,4 @@
1
- export var EVENT_ACTION;
2
- (function (EVENT_ACTION) {
1
+ export var EVENT_ACTION = /*#__PURE__*/function (EVENT_ACTION) {
3
2
  EVENT_ACTION["CONNECTION"] = "connection";
4
3
  EVENT_ACTION["CATCHUP"] = "catchup";
5
4
  EVENT_ACTION["DOCUMENT_INIT"] = "documentInit";
@@ -11,17 +10,18 @@ export var EVENT_ACTION;
11
10
  EVENT_ACTION["PUBLISH_PAGE"] = "publishPage";
12
11
  EVENT_ACTION["GET_CURRENT_STATE"] = "getCurrentState";
13
12
  EVENT_ACTION["INVALIDATE_TOKEN"] = "invalidateToken";
14
- })(EVENT_ACTION || (EVENT_ACTION = {}));
15
- export var EVENT_STATUS;
16
- (function (EVENT_STATUS) {
13
+ return EVENT_ACTION;
14
+ }({});
15
+ export var EVENT_STATUS = /*#__PURE__*/function (EVENT_STATUS) {
17
16
  EVENT_STATUS["SUCCESS"] = "SUCCESS";
18
17
  EVENT_STATUS["FAILURE"] = "FAILURE";
19
- })(EVENT_STATUS || (EVENT_STATUS = {}));
20
- export var ADD_STEPS_TYPE;
21
- (function (ADD_STEPS_TYPE) {
18
+ return EVENT_STATUS;
19
+ }({});
20
+ export var ADD_STEPS_TYPE = /*#__PURE__*/function (ADD_STEPS_TYPE) {
22
21
  ADD_STEPS_TYPE["ACCEPTED"] = "ACCEPTED";
23
22
  ADD_STEPS_TYPE["REJECTED"] = "REJECTED";
24
23
  ADD_STEPS_TYPE["ERROR"] = "ERROR";
25
- })(ADD_STEPS_TYPE || (ADD_STEPS_TYPE = {}));
24
+ return ADD_STEPS_TYPE;
25
+ }({});
26
26
  export var ACK_MAX_TRY = 30;
27
27
  export var CONFLUENCE = 'confluence';
package/dist/esm/index.js CHANGED
@@ -1 +1,2 @@
1
- export { Provider } from './provider';
1
+ export { Provider } from './provider';
2
+ export { PROVIDER_ERROR_CODE } from './errors/error-types';
@@ -0,0 +1,69 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/createClass";
3
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
+ import isEqual from 'lodash/isEqual';
5
+ export var MetadataService = /*#__PURE__*/function () {
6
+ function MetadataService(providerEmitCallback, broadcastMetadata) {
7
+ var _this = this;
8
+ _classCallCheck(this, MetadataService);
9
+ _defineProperty(this, "metadata", {});
10
+ _defineProperty(this, "getMetaData", function () {
11
+ return _this.metadata;
12
+ });
13
+ _defineProperty(this, "getTitle", function () {
14
+ var _this$metadata$title;
15
+ return (_this$metadata$title = _this.metadata.title) === null || _this$metadata$title === void 0 ? void 0 : _this$metadata$title.toString();
16
+ });
17
+ /**
18
+ * Called when a metadata is changed externally from other clients/backend.
19
+ */
20
+ _defineProperty(this, "onMetadataChanged", function (metadata) {
21
+ if (metadata !== undefined && !isEqual(_this.metadata, metadata) && Object.keys(metadata).length > 0) {
22
+ _this.metadata = metadata;
23
+ _this.providerEmitCallback('metadata:changed', metadata);
24
+ }
25
+ });
26
+ /**
27
+ * Updates the local metadata and broadcasts the metadata to other clients/backend.
28
+ * @param metadata
29
+ */
30
+ _defineProperty(this, "setMetadata", function (metadata) {
31
+ _this.broadcastMetadata(metadata);
32
+ _this.metadata = metadata;
33
+ });
34
+ /**
35
+ * Emits a change in document's metadata
36
+ * @param metadata
37
+ */
38
+ _defineProperty(this, "updateMetadata", function (metadata) {
39
+ if (metadata && Object.keys(metadata).length > 0) {
40
+ _this.metadata = metadata;
41
+ _this.providerEmitCallback('metadata:changed', metadata);
42
+ }
43
+ });
44
+ this.providerEmitCallback = providerEmitCallback;
45
+ this.broadcastMetadata = broadcastMetadata;
46
+ }
47
+ _createClass(MetadataService, [{
48
+ key: "setTitle",
49
+ value: function setTitle(title, broadcast) {
50
+ if (broadcast) {
51
+ this.broadcastMetadata({
52
+ title: title
53
+ });
54
+ }
55
+ this.metadata.title = title;
56
+ }
57
+ }, {
58
+ key: "setEditorWidth",
59
+ value: function setEditorWidth(editorWidth, broadcast) {
60
+ if (broadcast) {
61
+ this.broadcastMetadata({
62
+ editorWidth: editorWidth
63
+ });
64
+ }
65
+ this.metadata.editorWidth = editorWidth;
66
+ }
67
+ }]);
68
+ return MetadataService;
69
+ }();
@@ -4,36 +4,27 @@ export var PARTICIPANT_UPDATE_INTERVAL = 300 * 1000; // 300 seconds
4
4
 
5
5
  export var createParticipantFromPayload = /*#__PURE__*/function () {
6
6
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(payload, getUser) {
7
- var _user, _user2, _user3;
8
7
  var sessionId, timestamp, clientId, userId, user, participant;
9
8
  return _regeneratorRuntime.wrap(function _callee$(_context) {
10
- while (1) {
11
- switch (_context.prev = _context.next) {
12
- case 0:
13
- sessionId = payload.sessionId, timestamp = payload.timestamp, clientId = payload.clientId, userId = payload.userId;
14
- if (!getUser) {
15
- _context.next = 5;
16
- break;
17
- }
18
- _context.next = 4;
19
- return getUser(userId);
20
- case 4:
21
- user = _context.sent;
22
- case 5:
23
- participant = {
24
- name: ((_user = user) === null || _user === void 0 ? void 0 : _user.name) || '',
25
- email: ((_user2 = user) === null || _user2 === void 0 ? void 0 : _user2.email) || '',
26
- avatar: ((_user3 = user) === null || _user3 === void 0 ? void 0 : _user3.avatar) || '',
27
- sessionId: sessionId,
28
- lastActive: timestamp,
29
- userId: userId,
30
- clientId: clientId
31
- };
32
- return _context.abrupt("return", participant);
33
- case 7:
34
- case "end":
35
- return _context.stop();
36
- }
9
+ while (1) switch (_context.prev = _context.next) {
10
+ case 0:
11
+ sessionId = payload.sessionId, timestamp = payload.timestamp, clientId = payload.clientId, userId = payload.userId;
12
+ _context.next = 3;
13
+ return getUser === null || getUser === void 0 ? void 0 : getUser(userId);
14
+ case 3:
15
+ user = _context.sent;
16
+ participant = {
17
+ name: (user === null || user === void 0 ? void 0 : user.name) || '',
18
+ avatar: (user === null || user === void 0 ? void 0 : user.avatar) || '',
19
+ sessionId: sessionId,
20
+ lastActive: timestamp,
21
+ userId: userId,
22
+ clientId: clientId
23
+ };
24
+ return _context.abrupt("return", participant);
25
+ case 6:
26
+ case "end":
27
+ return _context.stop();
37
28
  }
38
29
  }, _callee);
39
30
  }));
@@ -15,57 +15,62 @@ export var ParticipantsService = /*#__PURE__*/function () {
15
15
  var _this = this;
16
16
  var participantsState = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new ParticipantsState();
17
17
  _classCallCheck(this, ParticipantsService);
18
+ /**
19
+ * Carries out 3 things: 1) enriches the participant with user data, 2) updates the participantsState, 3) emits the presence event
20
+ * @param payload Payload from incoming socket event
21
+ * @param getUser Function to get user data from confluence
22
+ * @param emit Function to execute emit from provider socket
23
+ * @returns Awaitable Promise, due to getUser
24
+ */
18
25
  _defineProperty(this, "updateParticipant", /*#__PURE__*/function () {
19
26
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(payload, getUser, emit) {
20
27
  var userId, participant, _this$analyticsHelper, isNewParticipant;
21
28
  return _regeneratorRuntime.wrap(function _callee$(_context) {
22
- while (1) {
23
- switch (_context.prev = _context.next) {
24
- case 0:
25
- userId = payload.userId; // If userId does not exist, does nothing here to prevent duplication.
26
- if (userId) {
27
- _context.next = 3;
28
- break;
29
- }
30
- return _context.abrupt("return");
31
- case 3:
32
- _context.prev = 3;
33
- _context.next = 6;
34
- return enrichParticipant( // userId _must_ be defined, this lets the compiler know
35
- _objectSpread(_objectSpread({}, payload), {}, {
36
- userId: userId
37
- }), getUser);
38
- case 6:
39
- participant = _context.sent;
40
- _context.next = 12;
29
+ while (1) switch (_context.prev = _context.next) {
30
+ case 0:
31
+ userId = payload.userId; // If userId does not exist, does nothing here to prevent duplication.
32
+ if (userId) {
33
+ _context.next = 3;
34
+ break;
35
+ }
36
+ return _context.abrupt("return");
37
+ case 3:
38
+ _context.prev = 3;
39
+ _context.next = 6;
40
+ return enrichParticipant( // userId _must_ be defined, this lets the compiler know
41
+ _objectSpread(_objectSpread({}, payload), {}, {
42
+ userId: userId
43
+ }), getUser);
44
+ case 6:
45
+ participant = _context.sent;
46
+ _context.next = 12;
47
+ break;
48
+ case 9:
49
+ _context.prev = 9;
50
+ _context.t0 = _context["catch"](3);
51
+ // We don't want to throw errors for Presence features as they tend to self-restore
52
+ (_this$analyticsHelper = _this.analyticsHelper) === null || _this$analyticsHelper === void 0 ? void 0 : _this$analyticsHelper.sendErrorEvent(_context.t0, 'enriching participant');
53
+ case 12:
54
+ if (participant) {
55
+ _context.next = 14;
56
+ break;
57
+ }
58
+ return _context.abrupt("return");
59
+ case 14:
60
+ isNewParticipant = _this.participantsState.doesntHave(participant.sessionId);
61
+ _this.participantsState.setBySessionId(participant.sessionId, participant);
62
+ if (isNewParticipant) {
63
+ _context.next = 18;
41
64
  break;
42
- case 9:
43
- _context.prev = 9;
44
- _context.t0 = _context["catch"](3);
45
- // We don't want to throw errors for Presence features as they tend to self-restore
46
- (_this$analyticsHelper = _this.analyticsHelper) === null || _this$analyticsHelper === void 0 ? void 0 : _this$analyticsHelper.sendErrorEvent(_context.t0, 'enriching participant');
47
- case 12:
48
- if (participant) {
49
- _context.next = 14;
50
- break;
51
- }
52
- return _context.abrupt("return");
53
- case 14:
54
- isNewParticipant = _this.participantsState.doesntHave(participant.sessionId);
55
- _this.participantsState.setBySessionId(participant.sessionId, participant);
56
- if (isNewParticipant) {
57
- _context.next = 18;
58
- break;
59
- }
60
- return _context.abrupt("return");
61
- case 18:
62
- _this.emitPresence({
63
- joined: [participant]
64
- }, emit, 'handling participant updated event');
65
- case 19:
66
- case "end":
67
- return _context.stop();
68
- }
65
+ }
66
+ return _context.abrupt("return");
67
+ case 18:
68
+ _this.emitPresence({
69
+ joined: [participant]
70
+ }, emit, 'handling participant updated event');
71
+ case 19:
72
+ case "end":
73
+ return _context.stop();
69
74
  }
70
75
  }, _callee, null, [[3, 9]]);
71
76
  }));
@@ -73,6 +78,11 @@ export var ParticipantsService = /*#__PURE__*/function () {
73
78
  return _ref.apply(this, arguments);
74
79
  };
75
80
  }());
81
+ /**
82
+ * Called when a participant leaves the session.
83
+ *
84
+ * We emit the `presence` event to update the active avatars in the editor.
85
+ */
76
86
  _defineProperty(this, "participantLeft", function (_ref2, emit) {
77
87
  var sessionId = _ref2.sessionId;
78
88
  _this.participantsState.removeBySessionId(sessionId);
@@ -101,10 +111,18 @@ export var ParticipantsService = /*#__PURE__*/function () {
101
111
  }, emit, 'emitting presence update on disconnect');
102
112
  }
103
113
  });
114
+ /**
115
+ * Updates when users were last active
116
+ * @param userIds Users in most recent steps
117
+ */
104
118
  _defineProperty(this, "updateLastActive", function () {
105
119
  var userIds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
106
120
  return _this.participantsState.updateLastActive(Date.now(), userIds);
107
121
  });
122
+ /**
123
+ * Called when we receive a telepointer update from another
124
+ * participant.
125
+ */
108
126
  _defineProperty(this, "participantTelepointer", function (payload, thisSessionId, getUser, emit) {
109
127
  var sessionId = payload.sessionId,
110
128
  selection = payload.selection,
@@ -125,6 +143,12 @@ export var ParticipantsService = /*#__PURE__*/function () {
125
143
  sessionId: sessionId
126
144
  }, emit, 'handling participant telepointer event');
127
145
  });
146
+ /**
147
+ * Every 5 minutes (PARTICIPANT_UPDATE_INTERVAL), removes inactive participants and emits the update to other participants.
148
+ * Needs to be kicked off in the Provider.
149
+ * @param sessionId SessionId from provider's connection
150
+ * @param emit Function to execute emit from provider socket
151
+ */
128
152
  _defineProperty(this, "removeInactiveParticipants", function (sessionId, emit) {
129
153
  clearTimeout(_this.participantUpdateTimeout);
130
154
  try {
@@ -137,6 +161,9 @@ export var ParticipantsService = /*#__PURE__*/function () {
137
161
  return _this.removeInactiveParticipants(sessionId, emit);
138
162
  }, PARTICIPANT_UPDATE_INTERVAL);
139
163
  });
164
+ /**
165
+ * Keep list of participants up to date. Filter out inactive users etc.
166
+ */
140
167
  _defineProperty(this, "filterInactive", function (sessionId, emit) {
141
168
  var now = Date.now();
142
169
  var left = _this.participantsState.getParticipants().filter(function (p) {
@@ -145,10 +172,15 @@ export var ParticipantsService = /*#__PURE__*/function () {
145
172
  left.forEach(function (p) {
146
173
  return _this.participantsState.removeBySessionId(p.sessionId);
147
174
  });
148
- _this.emitPresence({
175
+ left.length && _this.emitPresence({
149
176
  left: left
150
177
  }, emit, 'filtering inactive participants');
151
178
  });
179
+ /**
180
+ * Wrapper function to emit with error handling and analytics
181
+ * @param data Data to emit
182
+ * @param emit Emit function from Provider
183
+ */
152
184
  _defineProperty(this, "emitPresence", function (data, emit, errorMessage) {
153
185
  try {
154
186
  var _this$analyticsHelper4;
@@ -162,6 +194,11 @@ export var ParticipantsService = /*#__PURE__*/function () {
162
194
  (_this$analyticsHelper5 = _this.analyticsHelper) === null || _this$analyticsHelper5 === void 0 ? void 0 : _this$analyticsHelper5.sendErrorEvent(error, "Error while ".concat(errorMessage));
163
195
  }
164
196
  });
197
+ /**
198
+ * Wrapper function to emit with error handling and analytics
199
+ * @param data Data to emit
200
+ * @param emit Emit function from Provider
201
+ */
165
202
  _defineProperty(this, "emitTelepointer", function (data, emit, errorMessage) {
166
203
  try {
167
204
  emit('telepointer', data);
@@ -171,17 +208,15 @@ export var ParticipantsService = /*#__PURE__*/function () {
171
208
  (_this$analyticsHelper6 = _this.analyticsHelper) === null || _this$analyticsHelper6 === void 0 ? void 0 : _this$analyticsHelper6.sendErrorEvent(error, "Error while ".concat(errorMessage));
172
209
  }
173
210
  });
211
+ /**
212
+ * Used when the provider is disconnected or destroyed to prevent perpetual timers from continuously running
213
+ */
214
+ _defineProperty(this, "clearTimers", function () {
215
+ clearTimeout(_this.participantUpdateTimeout);
216
+ });
174
217
  this.participantsState = participantsState;
175
218
  this.analyticsHelper = analyticsHelper;
176
219
  }
177
-
178
- /**
179
- * Carries out 3 things: 1) enriches the participant with user data, 2) updates the participantsState, 3) emits the presence event
180
- * @param payload Payload from incoming socket event
181
- * @param getUser Function to get user data from confluence
182
- * @param emit Function to execute emit from provider socket
183
- * @returns Awaitable Promise, due to getUser
184
- */
185
220
  _createClass(ParticipantsService, [{
186
221
  key: "emitTelepointersFromSteps",
187
222
  value:
@@ -199,11 +234,6 @@ export var ParticipantsService = /*#__PURE__*/function () {
199
234
  }
200
235
  });
201
236
  }
202
-
203
- /**
204
- * Called when we receive a telepointer update from another
205
- * participant.
206
- */
207
237
  }]);
208
238
  return ParticipantsService;
209
239
  }();
@@ -36,6 +36,7 @@ export var ParticipantsState = /*#__PURE__*/_createClass(function ParticipantsSt
36
36
  _defineProperty(this, "size", function () {
37
37
  return _this.participants.size;
38
38
  });
39
+ // If userId of participant in userIds, set lastActive to now
39
40
  _defineProperty(this, "updateLastActive", function (now, userIds) {
40
41
  return _this.participants.forEach(function (p) {
41
42
  p.lastActive = userIds.includes(p.userId) ? now : p.lastActive;
@@ -2,9 +2,12 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
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; }
3
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; }
4
4
  import countBy from 'lodash/countBy';
5
+ import throttle from 'lodash/throttle';
5
6
  import { ADD_STEPS_TYPE, EVENT_ACTION, EVENT_STATUS } from '../helpers/const';
6
7
  import { AcknowledgementResponseTypes } from '../types';
7
8
  import { NCS_ERROR_CODE } from '../errors/error-types';
9
+ var SEND_STEPS_THROTTLE = 500; // 0.5 second
10
+
8
11
  export var commitStep = function commitStep(_ref) {
9
12
  var broadcast = _ref.broadcast,
10
13
  steps = _ref.steps,
@@ -59,4 +62,8 @@ export var commitStep = function commitStep(_ref) {
59
62
  } catch (error) {
60
63
  analyticsHelper === null || analyticsHelper === void 0 ? void 0 : analyticsHelper.sendErrorEvent(error, 'Error while adding steps - Broadcast threw exception');
61
64
  }
62
- };
65
+ };
66
+ export var throttledCommitStep = throttle(commitStep, SEND_STEPS_THROTTLE, {
67
+ leading: false,
68
+ trailing: true
69
+ });