@atlaskit/collab-provider 9.45.0 → 10.0.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 (41) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/afm-cc/tsconfig.json +3 -0
  3. package/afm-jira/tsconfig.json +3 -0
  4. package/dist/cjs/helpers/const.js +1 -0
  5. package/dist/cjs/helpers/utils.js +4 -1
  6. package/dist/cjs/participants/participants-service.js +51 -2
  7. package/dist/cjs/participants/participants-state.js +14 -1
  8. package/dist/cjs/provider/index.js +43 -31
  9. package/dist/cjs/types.js +0 -1
  10. package/dist/cjs/version-wrapper.js +1 -1
  11. package/dist/es2019/helpers/const.js +1 -0
  12. package/dist/es2019/helpers/utils.js +1 -0
  13. package/dist/es2019/index.js +3 -0
  14. package/dist/es2019/participants/participants-service.js +50 -4
  15. package/dist/es2019/participants/participants-state.js +7 -1
  16. package/dist/es2019/provider/index.js +46 -31
  17. package/dist/es2019/types.js +0 -2
  18. package/dist/es2019/version-wrapper.js +1 -1
  19. package/dist/esm/helpers/const.js +1 -0
  20. package/dist/esm/helpers/utils.js +3 -0
  21. package/dist/esm/index.js +3 -0
  22. package/dist/esm/participants/participants-service.js +52 -3
  23. package/dist/esm/participants/participants-state.js +14 -1
  24. package/dist/esm/provider/index.js +43 -31
  25. package/dist/esm/types.js +0 -2
  26. package/dist/esm/version-wrapper.js +1 -1
  27. package/dist/types/helpers/const.d.ts +9 -1
  28. package/dist/types/helpers/utils.d.ts +1 -0
  29. package/dist/types/participants/participants-helper.d.ts +1 -0
  30. package/dist/types/participants/participants-service.d.ts +11 -2
  31. package/dist/types/participants/participants-state.d.ts +1 -0
  32. package/dist/types/provider/index.d.ts +7 -3
  33. package/dist/types/types.d.ts +2 -1
  34. package/dist/types-ts4.5/helpers/const.d.ts +9 -1
  35. package/dist/types-ts4.5/helpers/utils.d.ts +1 -0
  36. package/dist/types-ts4.5/participants/participants-helper.d.ts +1 -0
  37. package/dist/types-ts4.5/participants/participants-service.d.ts +11 -2
  38. package/dist/types-ts4.5/participants/participants-state.d.ts +1 -0
  39. package/dist/types-ts4.5/provider/index.d.ts +7 -3
  40. package/dist/types-ts4.5/types.d.ts +2 -1
  41. package/package.json +3 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,82 @@
1
1
  # @atlaskit/collab-provider
2
2
 
3
+ ## 10.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [#165049](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/165049)
8
+ [`febce5463e07f`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/febce5463e07f) -
9
+ Enable no-re-export rule for a subset of editor packages
10
+
11
+ ### Major
12
+
13
+ #### @atlaskit/collab-provider
14
+
15
+ @atlaskit/collab-provider doesn't export following types anymore:
16
+
17
+ ```
18
+ CollabParticipant,
19
+ CollabEventInitData,
20
+ CollabEventRemoteData,
21
+ CollabEventConnectionData,
22
+ CollabEventConnectingData,
23
+ CollabEventPresenceData,
24
+ ResolvedEditorState,
25
+ CollabConnectedPayload,
26
+ CollabConnectingPayload,
27
+ CollabDisconnectedPayload,
28
+ CollabInitPayload,
29
+ CollabDataPayload,
30
+ CollabTelepointerPayload,
31
+ CollabPresencePayload,
32
+ CollabMetadataPayload,
33
+ CollabLocalStepsPayload,
34
+ CollabCommitStatusEventPayload,
35
+ CollabPermissionEventPayload,
36
+ UserPermitType,
37
+ CollabEvents,
38
+ Metadata,
39
+ StepJson,
40
+ CollabEventTelepointerData,
41
+ CollabSendableSelection,
42
+ CollabEditProvider,
43
+ NewCollabSyncUpErrorAttributes,
44
+ SyncUpErrorFunction,
45
+ CollabEventLocalStepData,
46
+ ```
47
+
48
+ Import them from `@atlaskit/editor-common/collab`.
49
+
50
+ #### @atlaskit/editor-common
51
+
52
+ `@atlaskit/editor-common/provider-factory` doesn't export following types anymore:
53
+
54
+ ```
55
+ CardAdf,
56
+ DatasourceAdf,
57
+ ```
58
+
59
+ Import them from `@atlaskit/smart-card`.
60
+
61
+ ### Patch Changes
62
+
63
+ - [#166394](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/166394)
64
+ [`ec83c51a9acba`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/ec83c51a9acba) -
65
+ Add analytics on reconnection events
66
+ - Updated dependencies
67
+
68
+ ## 9.46.0
69
+
70
+ ### Minor Changes
71
+
72
+ - [#163507](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/163507)
73
+ [`2fe2661c3c1e0`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/2fe2661c3c1e0) -
74
+ EDF-1842 Push agent information to collab session
75
+
76
+ ### Patch Changes
77
+
78
+ - Updated dependencies
79
+
3
80
  ## 9.45.0
4
81
 
5
82
  ### Minor Changes
@@ -29,6 +29,9 @@
29
29
  {
30
30
  "path": "../../editor-json-transformer/afm-cc/tsconfig.json"
31
31
  },
32
+ {
33
+ "path": "../../../measurement/feature-gate-js-client/afm-cc/tsconfig.json"
34
+ },
32
35
  {
33
36
  "path": "../../../platform/feature-flags/afm-cc/tsconfig.json"
34
37
  },
@@ -29,6 +29,9 @@
29
29
  {
30
30
  "path": "../../editor-json-transformer/afm-jira/tsconfig.json"
31
31
  },
32
+ {
33
+ "path": "../../../measurement/feature-gate-js-client/afm-jira/tsconfig.json"
34
+ },
32
35
  {
33
36
  "path": "../../../platform/feature-flags/afm-jira/tsconfig.json"
34
37
  },
@@ -22,6 +22,7 @@ var EVENT_ACTION = exports.EVENT_ACTION = /*#__PURE__*/function (EVENT_ACTION) {
22
22
  EVENT_ACTION["DROPPED_STEPS"] = "droppedStepInCatchup";
23
23
  EVENT_ACTION["WEBSOCKET_MESSAGE_VOLUME_METRIC"] = "websocketMessageVolumeMetric";
24
24
  EVENT_ACTION["PROVIDER_INITIALIZED"] = "providerInitialized";
25
+ EVENT_ACTION["RECONNECTION"] = "providerReconnection";
25
26
  EVENT_ACTION["PROVIDER_SETUP"] = "providerSetup";
26
27
  EVENT_ACTION["HAS_UNCONFIRMED_STEPS"] = "hasUnconfirmedSteps";
27
28
  return EVENT_ACTION;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getSubProduct = exports.getStepUGCFreeDetails = exports.getProduct = exports.createLogger = void 0;
6
+ exports.isAIProviderID = exports.getSubProduct = exports.getStepUGCFreeDetails = exports.getProduct = exports.createLogger = void 0;
7
7
  exports.sleep = sleep;
8
8
  var createLogger = exports.createLogger = function createLogger(prefix) {
9
9
  var color = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'blue';
@@ -20,6 +20,9 @@ function sleep(ms) {
20
20
  setTimeout(resolve, ms);
21
21
  });
22
22
  }
23
+ var isAIProviderID = exports.isAIProviderID = function isAIProviderID(id) {
24
+ return typeof id === 'string' && id.startsWith('agent:');
25
+ };
23
26
  var getProduct = exports.getProduct = function getProduct(productInfo) {
24
27
  var _productInfo$product;
25
28
  return (_productInfo$product = productInfo === null || productInfo === void 0 ? void 0 : productInfo.product) !== null && _productInfo$product !== void 0 ? _productInfo$product : 'unknown';
@@ -13,6 +13,7 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
13
13
  var _disconnectedReasonMapper = require("../disconnected-reason-mapper");
14
14
  var _const = require("../helpers/const");
15
15
  var _telepointersHelper = require("./telepointers-helper");
16
+ var _featureGateJsClient = _interopRequireDefault(require("@atlaskit/feature-gate-js-client"));
16
17
  var _participantsHelper = require("./participants-helper");
17
18
  var _participantsState = require("./participants-state");
18
19
  var _utils = require("../helpers/utils");
@@ -41,6 +42,28 @@ var ParticipantsService = exports.ParticipantsService = /*#__PURE__*/function ()
41
42
  var getPresenceData = arguments.length > 6 ? arguments[6] : undefined;
42
43
  var setUserId = arguments.length > 7 ? arguments[7] : undefined;
43
44
  (0, _classCallCheck2.default)(this, ParticipantsService);
45
+ (0, _defineProperty2.default)(this, "sendAIProviderChanged", function (payload) {
46
+ var isFacepileExperimentEnabled = _featureGateJsClient.default.getExperimentValue('platform_editor_ai_facepile', 'isEnabled', false);
47
+ if (isFacepileExperimentEnabled && payload.providerId) {
48
+ for (var propKey in payload.permit) {
49
+ if (payload.permit.hasOwnProperty(propKey)) {
50
+ payload.permit[propKey] = false;
51
+ }
52
+ }
53
+ var presencePayload = {
54
+ sessionId: "".concat(payload.providerId, "::").concat(payload.sessionId),
55
+ userId: payload.providerId,
56
+ clientId: "".concat(payload.providerId, "::").concat(payload.clientId),
57
+ permit: payload.permit,
58
+ timestamp: Date.now()
59
+ };
60
+ if (payload.action === 'add') {
61
+ _this.channelBroadcast('participant:updated', presencePayload);
62
+ } else if (payload.action === 'remove') {
63
+ _this.channelBroadcast('participant:left', presencePayload);
64
+ }
65
+ }
66
+ });
44
67
  /**
45
68
  * Carries out 3 things: 1) enriches the participant with user data, 2) updates the participantsState, 3) emits the presence event
46
69
  * @param payload Payload from incoming socket event
@@ -106,8 +129,31 @@ var ParticipantsService = exports.ParticipantsService = /*#__PURE__*/function ()
106
129
  * Called when a participant leaves the session.
107
130
  * We emit the `presence` event to update the active avatars in the editor.
108
131
  */
109
- (0, _defineProperty2.default)(this, "onParticipantLeft", function (_ref2) {
110
- var sessionId = _ref2.sessionId;
132
+ (0, _defineProperty2.default)(this, "onParticipantLeft", function (payload) {
133
+ var sessionId = payload.sessionId;
134
+ var isFacepileExperimentEnabled = _featureGateJsClient.default.getExperimentValue('platform_editor_ai_facepile', 'isEnabled', false);
135
+ if (isFacepileExperimentEnabled) {
136
+ var _payload$data;
137
+ // When an agent leaves a session, the backend service returns the original user's
138
+ // session ID accompanied by a payload containing the agent's session ID.
139
+ // If the user session leaves, we also want to remove all agent sessions associated.
140
+ if (payload !== null && payload !== void 0 && (_payload$data = payload.data) !== null && _payload$data !== void 0 && _payload$data.sessionId && (0, _utils.isAIProviderID)(payload.data.sessionId)) {
141
+ sessionId = payload.data.sessionId;
142
+ } else {
143
+ var associatedAgents = _this.getAIProviderParticipants().filter(function (ap) {
144
+ return ap.sessionId.endsWith(sessionId);
145
+ });
146
+ associatedAgents.forEach(function (agent) {
147
+ _this.onParticipantLeft({
148
+ sessionId: sessionId,
149
+ timestamp: payload.timestamp,
150
+ data: agent,
151
+ userId: undefined,
152
+ clientId: ''
153
+ });
154
+ });
155
+ }
156
+ }
111
157
  _this.participantsState.removeBySessionId(sessionId);
112
158
  _this.emitPresence({
113
159
  left: [{
@@ -318,6 +364,9 @@ var ParticipantsService = exports.ParticipantsService = /*#__PURE__*/function ()
318
364
  (0, _defineProperty2.default)(this, "getParticipants", function () {
319
365
  return _this.participantsState.getParticipants();
320
366
  });
367
+ (0, _defineProperty2.default)(this, "getAIProviderParticipants", function () {
368
+ return _this.participantsState.getAIProviderParticipants();
369
+ });
321
370
  this.analyticsHelper = analyticsHelper;
322
371
  this.participantsState = participantsState;
323
372
  this.emit = emit;
@@ -9,6 +9,7 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
9
9
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
11
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
12
+ var _utils = require("../helpers/utils");
12
13
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
13
14
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
14
15
  var ParticipantsState = exports.ParticipantsState = /*#__PURE__*/(0, _createClass2.default)(function ParticipantsState() {
@@ -26,7 +27,19 @@ var ParticipantsState = exports.ParticipantsState = /*#__PURE__*/(0, _createClas
26
27
  (0, _defineProperty2.default)(this, "getParticipants", function () {
27
28
  return (
28
29
  // Spread to get deep copy
29
- (0, _toConsumableArray2.default)(_this.participants.values()).map(function (p) {
30
+ (0, _toConsumableArray2.default)(_this.participants.values()).filter(function (p) {
31
+ return !(0, _utils.isAIProviderID)(p.userId);
32
+ }).map(function (p) {
33
+ return _objectSpread({}, p);
34
+ })
35
+ );
36
+ });
37
+ (0, _defineProperty2.default)(this, "getAIProviderParticipants", function () {
38
+ return (
39
+ // Spread to get deep copy
40
+ (0, _toConsumableArray2.default)(_this.participants.values()).filter(function (p) {
41
+ return (0, _utils.isAIProviderID)(p.userId);
42
+ }).map(function (p) {
30
43
  return _objectSpread({}, p);
31
44
  })
32
45
  );
@@ -136,6 +136,10 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
136
136
  if (initialized && _this.disconnectedAt &&
137
137
  // Offline longer than `OUT_OF_SYNC_PERIOD`
138
138
  Date.now() - _this.disconnectedAt >= OUT_OF_SYNC_PERIOD) {
139
+ var _this$analyticsHelper2;
140
+ (_this$analyticsHelper2 = _this.analyticsHelper) === null || _this$analyticsHelper2 === void 0 || _this$analyticsHelper2.sendActionEvent(_const.EVENT_ACTION.RECONNECTION, _const.EVENT_STATUS.INFO, {
141
+ disconnectionPeriodSeconds: Math.floor((Date.now() - _this.disconnectedAt) / 1000)
142
+ });
139
143
  _this.documentService.throttledCatchupv2(_const.CatchupEventReason.RECONNECTED);
140
144
  }
141
145
  _this.participantsService.startInactiveRemover(_this.sessionId);
@@ -179,13 +183,13 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
179
183
  if (((_error$data = error.data) === null || _error$data === void 0 ? void 0 : _error$data.code) === _ncsErrors.NCS_ERROR_CODE.HEAD_VERSION_UPDATE_FAILED || ((_error$data2 = error.data) === null || _error$data2 === void 0 ? void 0 : _error$data2.code) === _ncsErrors.NCS_ERROR_CODE.VERSION_NUMBER_ALREADY_EXISTS) {
180
184
  _this.documentService.onStepRejectedError();
181
185
  } else {
182
- var _this$analyticsHelper2;
183
- (_this$analyticsHelper2 = _this.analyticsHelper) === null || _this$analyticsHelper2 === void 0 || _this$analyticsHelper2.sendErrorEvent(error, 'Error handled');
186
+ var _this$analyticsHelper3;
187
+ (_this$analyticsHelper3 = _this.analyticsHelper) === null || _this$analyticsHelper3 === void 0 || _this$analyticsHelper3.sendErrorEvent(error, 'Error handled');
184
188
  var mappedError = (0, _errorCodeMapper.errorCodeMapper)(error);
185
189
  // Only emit errors to Confluence very intentionally because they will disconnect the collab provider
186
190
  if (mappedError) {
187
- var _this$analyticsHelper3;
188
- (_this$analyticsHelper3 = _this.analyticsHelper) === null || _this$analyticsHelper3 === void 0 || _this$analyticsHelper3.sendProviderErrorEvent(mappedError);
191
+ var _this$analyticsHelper4;
192
+ (_this$analyticsHelper4 = _this.analyticsHelper) === null || _this$analyticsHelper4 === void 0 || _this$analyticsHelper4.sendProviderErrorEvent(mappedError);
189
193
  _this.emit('error', mappedError);
190
194
  }
191
195
  }
@@ -208,7 +212,7 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
208
212
  * @throws {GetCurrentStateError} Something went wrong while returning the current state
209
213
  */
210
214
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getCurrentState", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
211
- var _this$analyticsHelper4;
215
+ var _this$analyticsHelper5;
212
216
  return _regenerator.default.wrap(function _callee$(_context) {
213
217
  while (1) switch (_context.prev = _context.next) {
214
218
  case 0:
@@ -220,7 +224,7 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
220
224
  case 6:
221
225
  _context.prev = 6;
222
226
  _context.t0 = _context["catch"](0);
223
- (_this$analyticsHelper4 = _this.analyticsHelper) === null || _this$analyticsHelper4 === void 0 || _this$analyticsHelper4.sendErrorEvent(_context.t0, 'Error while returning ADF version of current draft document');
227
+ (_this$analyticsHelper5 = _this.analyticsHelper) === null || _this$analyticsHelper5 === void 0 || _this$analyticsHelper5.sendErrorEvent(_context.t0, 'Error while returning ADF version of current draft document');
224
228
  throw new _customErrors.GetCurrentStateError('Error while returning the current state of the draft document', _context.t0);
225
229
  case 10:
226
230
  case "end":
@@ -234,7 +238,7 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
234
238
  * @throws {GetFinalAcknowledgedStateError} Something went wrong while returning the acknowledged state
235
239
  */
236
240
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getFinalAcknowledgedState", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
237
- var _this$analyticsHelper5;
241
+ var _this$analyticsHelper6;
238
242
  return _regenerator.default.wrap(function _callee2$(_context2) {
239
243
  while (1) switch (_context2.prev = _context2.next) {
240
244
  case 0:
@@ -246,7 +250,7 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
246
250
  case 6:
247
251
  _context2.prev = 6;
248
252
  _context2.t0 = _context2["catch"](0);
249
- (_this$analyticsHelper5 = _this.analyticsHelper) === null || _this$analyticsHelper5 === void 0 || _this$analyticsHelper5.sendErrorEvent(_context2.t0, 'Error while returning ADF version of the final draft document');
253
+ (_this$analyticsHelper6 = _this.analyticsHelper) === null || _this$analyticsHelper6 === void 0 || _this$analyticsHelper6.sendErrorEvent(_context2.t0, 'Error while returning ADF version of the final draft document');
250
254
  throw new _customErrors.GetFinalAcknowledgedStateError('Error while returning the final acknowledged state of the draft document', _context2.t0);
251
255
  case 10:
252
256
  case "end":
@@ -278,6 +282,9 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
278
282
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getParticipants", function () {
279
283
  return _this.participantsService.getParticipants();
280
284
  });
285
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getAIProviderParticipants", function () {
286
+ return _this.participantsService.getAIProviderParticipants();
287
+ });
281
288
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getSessionId", function () {
282
289
  return _this.sessionId;
283
290
  });
@@ -360,7 +367,7 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
360
367
  clientId: this.clientId
361
368
  });
362
369
  if (this.isBufferingEnabled && this.initialDraft && !this.isProviderInitialized) {
363
- var _this$analyticsHelper6;
370
+ var _this$analyticsHelper7;
364
371
  var _this$initialDraft2 = this.initialDraft,
365
372
  document = _this$initialDraft2.document,
366
373
  version = _this$initialDraft2.version,
@@ -370,7 +377,7 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
370
377
  version: version,
371
378
  metadata: metadata
372
379
  });
373
- (_this$analyticsHelper6 = this.analyticsHelper) === null || _this$analyticsHelper6 === void 0 || _this$analyticsHelper6.sendActionEvent(_const.EVENT_ACTION.PROVIDER_INITIALIZED, _const.EVENT_STATUS.INFO, {
380
+ (_this$analyticsHelper7 = this.analyticsHelper) === null || _this$analyticsHelper7 === void 0 || _this$analyticsHelper7.sendActionEvent(_const.EVENT_ACTION.PROVIDER_INITIALIZED, _const.EVENT_STATUS.INFO, {
374
381
  isBuffered: true
375
382
  });
376
383
  }
@@ -379,8 +386,8 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
379
386
  this.isChannelInitialized = true;
380
387
  }
381
388
  } catch (initError) {
382
- var _this$analyticsHelper7;
383
- (_this$analyticsHelper7 = this.analyticsHelper) === null || _this$analyticsHelper7 === void 0 || _this$analyticsHelper7.sendErrorEvent(initError, 'Error while initialising the provider');
389
+ var _this$analyticsHelper8;
390
+ (_this$analyticsHelper8 = this.analyticsHelper) === null || _this$analyticsHelper8 === void 0 || _this$analyticsHelper8.sendErrorEvent(initError, 'Error while initialising the provider');
384
391
  // Throw error so consumers are aware the initialisation failed when initialising themselves
385
392
  throw new _customErrors.ProviderInitialisationError('Provider initialisation error', initError);
386
393
  }
@@ -399,8 +406,8 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
399
406
  this.isChannelInitialized = true;
400
407
  }
401
408
  } catch (initError) {
402
- var _this$analyticsHelper8;
403
- (_this$analyticsHelper8 = this.analyticsHelper) === null || _this$analyticsHelper8 === void 0 || _this$analyticsHelper8.sendErrorEvent(initError, 'Error while initialising the provider');
409
+ var _this$analyticsHelper9;
410
+ (_this$analyticsHelper9 = this.analyticsHelper) === null || _this$analyticsHelper9 === void 0 || _this$analyticsHelper9.sendErrorEvent(initError, 'Error while initialising the provider');
404
411
  // Throw error so consumers are aware the initialisation failed when initialising themselves
405
412
  throw new _customErrors.ProviderInitialisationError('Provider initialisation error', initError);
406
413
  }
@@ -410,9 +417,9 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
410
417
  key: "checkForCookies",
411
418
  value: function checkForCookies() {
412
419
  if (!global.navigator.cookieEnabled) {
413
- var _this$analyticsHelper9;
420
+ var _this$analyticsHelper10;
414
421
  var initError = new _customErrors.ProviderInitialisationError('Cookies are not enabled. Please enable cookies to use collaborative editing.');
415
- (_this$analyticsHelper9 = this.analyticsHelper) === null || _this$analyticsHelper9 === void 0 || _this$analyticsHelper9.sendErrorEvent(initError, 'Error while initialising the provider - cookies disabled');
422
+ (_this$analyticsHelper10 = this.analyticsHelper) === null || _this$analyticsHelper10 === void 0 || _this$analyticsHelper10.sendErrorEvent(initError, 'Error while initialising the provider - cookies disabled');
416
423
  throw new _customErrors.ProviderInitialisationError('Provider initialisation error - cookies disabled', initError);
417
424
  }
418
425
  }
@@ -429,14 +436,14 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
429
436
  value: function send(_tr, _oldState, newState) {
430
437
  try {
431
438
  if (this.isViewOnly()) {
432
- var _this$analyticsHelper10;
439
+ var _this$analyticsHelper11;
433
440
  var error = {
434
441
  message: 'Attempted to send steps in view only mode',
435
442
  data: {
436
443
  code: _internalErrors.INTERNAL_ERROR_CODE.VIEW_ONLY_STEPS_ERROR
437
444
  }
438
445
  };
439
- (_this$analyticsHelper10 = this.analyticsHelper) === null || _this$analyticsHelper10 === void 0 || _this$analyticsHelper10.sendErrorEvent(error, error.message);
446
+ (_this$analyticsHelper11 = this.analyticsHelper) === null || _this$analyticsHelper11 === void 0 || _this$analyticsHelper11.sendErrorEvent(error, error.message);
440
447
  return;
441
448
  }
442
449
  // Don't send steps while the document is locked (eg. when restoring the document)
@@ -446,8 +453,8 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
446
453
  }
447
454
  this.documentService.send(_tr, _oldState, newState);
448
455
  } catch (error) {
449
- var _this$analyticsHelper11;
450
- (_this$analyticsHelper11 = this.analyticsHelper) === null || _this$analyticsHelper11 === void 0 || _this$analyticsHelper11.sendErrorEvent(error, 'Error while sending steps for a transaction');
456
+ var _this$analyticsHelper12;
457
+ (_this$analyticsHelper12 = this.analyticsHelper) === null || _this$analyticsHelper12 === void 0 || _this$analyticsHelper12.sendErrorEvent(error, 'Error while sending steps for a transaction');
451
458
  throw new _customErrors.SendTransactionError('Error while sending steps for a transaction', error);
452
459
  }
453
460
  }
@@ -460,8 +467,11 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
460
467
  }
461
468
 
462
469
  /**
463
- * Send messages, such as telepointers, to NCS and other participants. Only used for telepointer data (text and node selections) in the editor and JWM. JWM does some weird serialisation stuff on the node selections.
470
+ * Send messages, such as telepointers, and AI provider changes to NCS and other participants.
471
+ * Only used for telepointer data (text and node selections) in the editor and JWM.
472
+ * JWM does some weird serialisation stuff on the node selections.
464
473
  * Silently fails if an error occurs, since Presence isn't a critical functionality and self-restores over time.
474
+ *
465
475
  * @param {CollabTelepointerPayload} data Data you want to send to NCS / the other participants
466
476
  * @param {string} data.type Can only be 'telepointer' for now, we don't support anything else yet
467
477
  * @param {CollabSendableSelection} data.selection Object representing the selected element
@@ -485,11 +495,13 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
485
495
  this.channel.broadcast((data === null || data === void 0 ? void 0 : data.type) === 'activity:join' ? 'participant:activity-join' : 'participant:activity-ack', _objectSpread(_objectSpread({}, basePayload), {}, {
486
496
  activity: data.activity
487
497
  }), activityCallback());
498
+ } else if ((data === null || data === void 0 ? void 0 : data.type) === 'ai-provider:change') {
499
+ this.participantsService.sendAIProviderChanged(_objectSpread(_objectSpread({}, basePayload), data));
488
500
  }
489
501
  } catch (error) {
490
- var _this$analyticsHelper12;
502
+ var _this$analyticsHelper13;
491
503
  // We don't want to throw errors for Presence features as they tend to self-restore
492
- (_this$analyticsHelper12 = this.analyticsHelper) === null || _this$analyticsHelper12 === void 0 || _this$analyticsHelper12.sendErrorEvent(error, 'Error while sending message - telepointer');
504
+ (_this$analyticsHelper13 = this.analyticsHelper) === null || _this$analyticsHelper13 === void 0 || _this$analyticsHelper13.sendErrorEvent(error, 'Error while sending message - telepointer');
493
505
  }
494
506
  }
495
507
  }, {
@@ -532,8 +544,8 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
532
544
  this.sendStepsTimer = undefined;
533
545
  }
534
546
  } catch (error) {
535
- var _this$analyticsHelper13;
536
- (_this$analyticsHelper13 = this.analyticsHelper) === null || _this$analyticsHelper13 === void 0 || _this$analyticsHelper13.sendErrorEvent(error, 'Error while shutting down the collab provider');
547
+ var _this$analyticsHelper14;
548
+ (_this$analyticsHelper14 = this.analyticsHelper) === null || _this$analyticsHelper14 === void 0 || _this$analyticsHelper14.sendErrorEvent(error, 'Error while shutting down the collab provider');
537
549
  throw new _customErrors.DestroyError('Error while shutting down the collab provider', error);
538
550
  }
539
551
  this.clearTimers();
@@ -556,8 +568,8 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
556
568
  }
557
569
  this.metadataService.setTitle(title, broadcast);
558
570
  } catch (error) {
559
- var _this$analyticsHelper14;
560
- (_this$analyticsHelper14 = this.analyticsHelper) === null || _this$analyticsHelper14 === void 0 || _this$analyticsHelper14.sendErrorEvent(error, 'Error while setting title');
571
+ var _this$analyticsHelper15;
572
+ (_this$analyticsHelper15 = this.analyticsHelper) === null || _this$analyticsHelper15 === void 0 || _this$analyticsHelper15.sendErrorEvent(error, 'Error while setting title');
561
573
  throw new _customErrors.SetTitleError('Error while setting title', error);
562
574
  }
563
575
  }
@@ -575,8 +587,8 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
575
587
  try {
576
588
  this.metadataService.setEditorWidth(editorWidth, broadcast);
577
589
  } catch (error) {
578
- var _this$analyticsHelper15;
579
- (_this$analyticsHelper15 = this.analyticsHelper) === null || _this$analyticsHelper15 === void 0 || _this$analyticsHelper15.sendErrorEvent(error, 'Error while setting editor width');
590
+ var _this$analyticsHelper16;
591
+ (_this$analyticsHelper16 = this.analyticsHelper) === null || _this$analyticsHelper16 === void 0 || _this$analyticsHelper16.sendErrorEvent(error, 'Error while setting editor width');
580
592
  throw new _customErrors.SetEditorWidthError('Error while setting editor width', error);
581
593
  }
582
594
  }
@@ -595,8 +607,8 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
595
607
  }
596
608
  this.metadataService.setMetadata(metadata);
597
609
  } catch (error) {
598
- var _this$analyticsHelper16;
599
- (_this$analyticsHelper16 = this.analyticsHelper) === null || _this$analyticsHelper16 === void 0 || _this$analyticsHelper16.sendErrorEvent(error, 'Error while setting metadata');
610
+ var _this$analyticsHelper17;
611
+ (_this$analyticsHelper17 = this.analyticsHelper) === null || _this$analyticsHelper17 === void 0 || _this$analyticsHelper17.sendErrorEvent(error, 'Error while setting metadata');
600
612
  throw new _customErrors.SetMetadataError('Error while setting metadata', error);
601
613
  }
602
614
  }
package/dist/cjs/types.js CHANGED
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.AcknowledgementResponseTypes = void 0;
7
- // Re-export values for the /types entry point to this package
8
7
  // types from editor common end
9
8
  // Initial draft
10
9
  // Channel
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.version = exports.nextMajorVersion = exports.name = void 0;
7
7
  var name = exports.name = "@atlaskit/collab-provider";
8
- var version = exports.version = "9.45.0";
8
+ var version = exports.version = "10.0.0";
9
9
  var nextMajorVersion = exports.nextMajorVersion = function nextMajorVersion() {
10
10
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
11
11
  };
@@ -16,6 +16,7 @@ export let EVENT_ACTION = /*#__PURE__*/function (EVENT_ACTION) {
16
16
  EVENT_ACTION["DROPPED_STEPS"] = "droppedStepInCatchup";
17
17
  EVENT_ACTION["WEBSOCKET_MESSAGE_VOLUME_METRIC"] = "websocketMessageVolumeMetric";
18
18
  EVENT_ACTION["PROVIDER_INITIALIZED"] = "providerInitialized";
19
+ EVENT_ACTION["RECONNECTION"] = "providerReconnection";
19
20
  EVENT_ACTION["PROVIDER_SETUP"] = "providerSetup";
20
21
  EVENT_ACTION["HAS_UNCONFIRMED_STEPS"] = "hasUnconfirmedSteps";
21
22
  return EVENT_ACTION;
@@ -9,6 +9,7 @@ export function sleep(ms) {
9
9
  setTimeout(resolve, ms);
10
10
  });
11
11
  }
12
+ export const isAIProviderID = id => typeof id === 'string' && id.startsWith('agent:');
12
13
  export const getProduct = productInfo => {
13
14
  var _productInfo$product;
14
15
  return (_productInfo$product = productInfo === null || productInfo === void 0 ? void 0 : productInfo.product) !== null && _productInfo$product !== void 0 ? _productInfo$product : 'unknown';
@@ -1,2 +1,5 @@
1
+ // Disable no-re-export rule for entry point files
2
+ /* eslint-disable @atlaskit/editor/no-re-export */
3
+
1
4
  export { Provider } from './provider';
2
5
  export { PROVIDER_ERROR_CODE } from '@atlaskit/editor-common/collab';
@@ -2,9 +2,10 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { disconnectedReasonMapper } from '../disconnected-reason-mapper';
3
3
  import { EVENT_ACTION, EVENT_STATUS } from '../helpers/const';
4
4
  import { telepointerFromStep } from './telepointers-helper';
5
+ import FeatureGates from '@atlaskit/feature-gate-js-client';
5
6
  import { createParticipantFromPayload as enrichParticipant, PARTICIPANT_UPDATE_INTERVAL } from './participants-helper';
6
7
  import { ParticipantsState } from './participants-state';
7
- import { createLogger } from '../helpers/utils';
8
+ import { createLogger, isAIProviderID } from '../helpers/utils';
8
9
  const logger = createLogger('PresenceService', 'pink');
9
10
  const SEND_PRESENCE_INTERVAL = 150 * 1000; // 150 seconds
10
11
 
@@ -19,6 +20,28 @@ const SEND_PRESENCE_INTERVAL = 150 * 1000; // 150 seconds
19
20
  */
20
21
  export class ParticipantsService {
21
22
  constructor(analyticsHelper, participantsState = new ParticipantsState(), emit, getUser, channelBroadcast, sendPresenceJoined, getPresenceData, setUserId) {
23
+ _defineProperty(this, "sendAIProviderChanged", payload => {
24
+ const isFacepileExperimentEnabled = FeatureGates.getExperimentValue('platform_editor_ai_facepile', 'isEnabled', false);
25
+ if (isFacepileExperimentEnabled && payload.providerId) {
26
+ for (const propKey in payload.permit) {
27
+ if (payload.permit.hasOwnProperty(propKey)) {
28
+ payload.permit[propKey] = false;
29
+ }
30
+ }
31
+ const presencePayload = {
32
+ sessionId: `${payload.providerId}::${payload.sessionId}`,
33
+ userId: payload.providerId,
34
+ clientId: `${payload.providerId}::${payload.clientId}`,
35
+ permit: payload.permit,
36
+ timestamp: Date.now()
37
+ };
38
+ if (payload.action === 'add') {
39
+ this.channelBroadcast('participant:updated', presencePayload);
40
+ } else if (payload.action === 'remove') {
41
+ this.channelBroadcast('participant:left', presencePayload);
42
+ }
43
+ }
44
+ });
22
45
  /**
23
46
  * Carries out 3 things: 1) enriches the participant with user data, 2) updates the participantsState, 3) emits the presence event
24
47
  * @param payload Payload from incoming socket event
@@ -63,9 +86,29 @@ export class ParticipantsService {
63
86
  * Called when a participant leaves the session.
64
87
  * We emit the `presence` event to update the active avatars in the editor.
65
88
  */
66
- _defineProperty(this, "onParticipantLeft", ({
67
- sessionId
68
- }) => {
89
+ _defineProperty(this, "onParticipantLeft", payload => {
90
+ let sessionId = payload.sessionId;
91
+ const isFacepileExperimentEnabled = FeatureGates.getExperimentValue('platform_editor_ai_facepile', 'isEnabled', false);
92
+ if (isFacepileExperimentEnabled) {
93
+ var _payload$data;
94
+ // When an agent leaves a session, the backend service returns the original user's
95
+ // session ID accompanied by a payload containing the agent's session ID.
96
+ // If the user session leaves, we also want to remove all agent sessions associated.
97
+ if (payload !== null && payload !== void 0 && (_payload$data = payload.data) !== null && _payload$data !== void 0 && _payload$data.sessionId && isAIProviderID(payload.data.sessionId)) {
98
+ sessionId = payload.data.sessionId;
99
+ } else {
100
+ const associatedAgents = this.getAIProviderParticipants().filter(ap => ap.sessionId.endsWith(sessionId));
101
+ associatedAgents.forEach(agent => {
102
+ this.onParticipantLeft({
103
+ sessionId,
104
+ timestamp: payload.timestamp,
105
+ data: agent,
106
+ userId: undefined,
107
+ clientId: ''
108
+ });
109
+ });
110
+ }
111
+ }
69
112
  this.participantsState.removeBySessionId(sessionId);
70
113
  this.emitPresence({
71
114
  left: [{
@@ -267,6 +310,9 @@ export class ParticipantsService {
267
310
  _defineProperty(this, "getParticipants", () => {
268
311
  return this.participantsState.getParticipants();
269
312
  });
313
+ _defineProperty(this, "getAIProviderParticipants", () => {
314
+ return this.participantsState.getAIProviderParticipants();
315
+ });
270
316
  this.analyticsHelper = analyticsHelper;
271
317
  this.participantsState = participantsState;
272
318
  this.emit = emit;
@@ -1,4 +1,5 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import { isAIProviderID } from '../helpers/utils';
2
3
  export class ParticipantsState {
3
4
  constructor(baseParticipants = new Map()) {
4
5
  _defineProperty(this, "getBySessionId", sessionId => {
@@ -13,7 +14,12 @@ export class ParticipantsState {
13
14
  });
14
15
  _defineProperty(this, "getParticipants", () =>
15
16
  // Spread to get deep copy
16
- [...this.participants.values()].map(p => ({
17
+ [...this.participants.values()].filter(p => !isAIProviderID(p.userId)).map(p => ({
18
+ ...p
19
+ })));
20
+ _defineProperty(this, "getAIProviderParticipants", () =>
21
+ // Spread to get deep copy
22
+ [...this.participants.values()].filter(p => isAIProviderID(p.userId)).map(p => ({
17
23
  ...p
18
24
  })));
19
25
  _defineProperty(this, "removeBySessionId", sessionId => this.participants.delete(sessionId));