@atlaskit/collab-provider 9.45.0 → 9.46.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 (31) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/afm-cc/tsconfig.json +3 -0
  3. package/afm-jira/tsconfig.json +3 -0
  4. package/dist/cjs/helpers/utils.js +4 -1
  5. package/dist/cjs/participants/participants-service.js +51 -2
  6. package/dist/cjs/participants/participants-state.js +14 -1
  7. package/dist/cjs/provider/index.js +9 -1
  8. package/dist/cjs/version-wrapper.js +1 -1
  9. package/dist/es2019/helpers/utils.js +1 -0
  10. package/dist/es2019/participants/participants-service.js +50 -4
  11. package/dist/es2019/participants/participants-state.js +7 -1
  12. package/dist/es2019/provider/index.js +12 -1
  13. package/dist/es2019/version-wrapper.js +1 -1
  14. package/dist/esm/helpers/utils.js +3 -0
  15. package/dist/esm/participants/participants-service.js +52 -3
  16. package/dist/esm/participants/participants-state.js +14 -1
  17. package/dist/esm/provider/index.js +9 -1
  18. package/dist/esm/version-wrapper.js +1 -1
  19. package/dist/types/helpers/utils.d.ts +1 -0
  20. package/dist/types/participants/participants-helper.d.ts +1 -0
  21. package/dist/types/participants/participants-service.d.ts +11 -2
  22. package/dist/types/participants/participants-state.d.ts +1 -0
  23. package/dist/types/provider/index.d.ts +7 -3
  24. package/dist/types/types.d.ts +1 -0
  25. package/dist/types-ts4.5/helpers/utils.d.ts +1 -0
  26. package/dist/types-ts4.5/participants/participants-helper.d.ts +1 -0
  27. package/dist/types-ts4.5/participants/participants-service.d.ts +11 -2
  28. package/dist/types-ts4.5/participants/participants-state.d.ts +1 -0
  29. package/dist/types-ts4.5/provider/index.d.ts +7 -3
  30. package/dist/types-ts4.5/types.d.ts +1 -0
  31. package/package.json +3 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atlaskit/collab-provider
2
2
 
3
+ ## 9.46.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#163507](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/163507)
8
+ [`2fe2661c3c1e0`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/2fe2661c3c1e0) -
9
+ EDF-1842 Push agent information to collab session
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+
3
15
  ## 9.45.0
4
16
 
5
17
  ### 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
  },
@@ -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
  );
@@ -278,6 +278,9 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
278
278
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getParticipants", function () {
279
279
  return _this.participantsService.getParticipants();
280
280
  });
281
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getAIProviderParticipants", function () {
282
+ return _this.participantsService.getAIProviderParticipants();
283
+ });
281
284
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getSessionId", function () {
282
285
  return _this.sessionId;
283
286
  });
@@ -460,8 +463,11 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
460
463
  }
461
464
 
462
465
  /**
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.
466
+ * Send messages, such as telepointers, and AI provider changes to NCS and other participants.
467
+ * Only used for telepointer data (text and node selections) in the editor and JWM.
468
+ * JWM does some weird serialisation stuff on the node selections.
464
469
  * Silently fails if an error occurs, since Presence isn't a critical functionality and self-restores over time.
470
+ *
465
471
  * @param {CollabTelepointerPayload} data Data you want to send to NCS / the other participants
466
472
  * @param {string} data.type Can only be 'telepointer' for now, we don't support anything else yet
467
473
  * @param {CollabSendableSelection} data.selection Object representing the selected element
@@ -485,6 +491,8 @@ var Provider = exports.Provider = /*#__PURE__*/function (_Emitter) {
485
491
  this.channel.broadcast((data === null || data === void 0 ? void 0 : data.type) === 'activity:join' ? 'participant:activity-join' : 'participant:activity-ack', _objectSpread(_objectSpread({}, basePayload), {}, {
486
492
  activity: data.activity
487
493
  }), activityCallback());
494
+ } else if ((data === null || data === void 0 ? void 0 : data.type) === 'ai-provider:change') {
495
+ this.participantsService.sendAIProviderChanged(_objectSpread(_objectSpread({}, basePayload), data));
488
496
  }
489
497
  } catch (error) {
490
498
  var _this$analyticsHelper12;
@@ -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 = "9.46.0";
9
9
  var nextMajorVersion = exports.nextMajorVersion = function nextMajorVersion() {
10
10
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
11
11
  };
@@ -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';
@@ -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));
@@ -231,6 +231,9 @@ export class Provider extends Emitter {
231
231
  _defineProperty(this, "getParticipants", () => {
232
232
  return this.participantsService.getParticipants();
233
233
  });
234
+ _defineProperty(this, "getAIProviderParticipants", () => {
235
+ return this.participantsService.getAIProviderParticipants();
236
+ });
234
237
  _defineProperty(this, "getSessionId", () => {
235
238
  return this.sessionId;
236
239
  });
@@ -397,8 +400,11 @@ export class Provider extends Emitter {
397
400
  }
398
401
 
399
402
  /**
400
- * 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.
403
+ * Send messages, such as telepointers, and AI provider changes to NCS and other participants.
404
+ * Only used for telepointer data (text and node selections) in the editor and JWM.
405
+ * JWM does some weird serialisation stuff on the node selections.
401
406
  * Silently fails if an error occurs, since Presence isn't a critical functionality and self-restores over time.
407
+ *
402
408
  * @param {CollabTelepointerPayload} data Data you want to send to NCS / the other participants
403
409
  * @param {string} data.type Can only be 'telepointer' for now, we don't support anything else yet
404
410
  * @param {CollabSendableSelection} data.selection Object representing the selected element
@@ -422,6 +428,11 @@ export class Provider extends Emitter {
422
428
  ...basePayload,
423
429
  activity: data.activity
424
430
  }, activityCallback());
431
+ } else if ((data === null || data === void 0 ? void 0 : data.type) === 'ai-provider:change') {
432
+ this.participantsService.sendAIProviderChanged({
433
+ ...basePayload,
434
+ ...data
435
+ });
425
436
  }
426
437
  } catch (error) {
427
438
  var _this$analyticsHelper12;
@@ -1,5 +1,5 @@
1
1
  export const name = "@atlaskit/collab-provider";
2
- export const version = "9.45.0";
2
+ export const version = "9.46.0";
3
3
  export const nextMajorVersion = () => {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -13,6 +13,9 @@ export function sleep(ms) {
13
13
  setTimeout(resolve, ms);
14
14
  });
15
15
  }
16
+ export var isAIProviderID = function isAIProviderID(id) {
17
+ return typeof id === 'string' && id.startsWith('agent:');
18
+ };
16
19
  export var getProduct = function getProduct(productInfo) {
17
20
  var _productInfo$product;
18
21
  return (_productInfo$product = productInfo === null || productInfo === void 0 ? void 0 : productInfo.product) !== null && _productInfo$product !== void 0 ? _productInfo$product : 'unknown';
@@ -8,9 +8,10 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
8
8
  import { disconnectedReasonMapper } from '../disconnected-reason-mapper';
9
9
  import { EVENT_ACTION, EVENT_STATUS } from '../helpers/const';
10
10
  import { telepointerFromStep } from './telepointers-helper';
11
+ import FeatureGates from '@atlaskit/feature-gate-js-client';
11
12
  import { createParticipantFromPayload as enrichParticipant, PARTICIPANT_UPDATE_INTERVAL } from './participants-helper';
12
13
  import { ParticipantsState } from './participants-state';
13
- import { createLogger } from '../helpers/utils';
14
+ import { createLogger, isAIProviderID } from '../helpers/utils';
14
15
  var logger = createLogger('PresenceService', 'pink');
15
16
  var SEND_PRESENCE_INTERVAL = 150 * 1000; // 150 seconds
16
17
 
@@ -34,6 +35,28 @@ export var ParticipantsService = /*#__PURE__*/function () {
34
35
  var getPresenceData = arguments.length > 6 ? arguments[6] : undefined;
35
36
  var setUserId = arguments.length > 7 ? arguments[7] : undefined;
36
37
  _classCallCheck(this, ParticipantsService);
38
+ _defineProperty(this, "sendAIProviderChanged", function (payload) {
39
+ var isFacepileExperimentEnabled = FeatureGates.getExperimentValue('platform_editor_ai_facepile', 'isEnabled', false);
40
+ if (isFacepileExperimentEnabled && payload.providerId) {
41
+ for (var propKey in payload.permit) {
42
+ if (payload.permit.hasOwnProperty(propKey)) {
43
+ payload.permit[propKey] = false;
44
+ }
45
+ }
46
+ var presencePayload = {
47
+ sessionId: "".concat(payload.providerId, "::").concat(payload.sessionId),
48
+ userId: payload.providerId,
49
+ clientId: "".concat(payload.providerId, "::").concat(payload.clientId),
50
+ permit: payload.permit,
51
+ timestamp: Date.now()
52
+ };
53
+ if (payload.action === 'add') {
54
+ _this.channelBroadcast('participant:updated', presencePayload);
55
+ } else if (payload.action === 'remove') {
56
+ _this.channelBroadcast('participant:left', presencePayload);
57
+ }
58
+ }
59
+ });
37
60
  /**
38
61
  * Carries out 3 things: 1) enriches the participant with user data, 2) updates the participantsState, 3) emits the presence event
39
62
  * @param payload Payload from incoming socket event
@@ -99,8 +122,31 @@ export var ParticipantsService = /*#__PURE__*/function () {
99
122
  * Called when a participant leaves the session.
100
123
  * We emit the `presence` event to update the active avatars in the editor.
101
124
  */
102
- _defineProperty(this, "onParticipantLeft", function (_ref2) {
103
- var sessionId = _ref2.sessionId;
125
+ _defineProperty(this, "onParticipantLeft", function (payload) {
126
+ var sessionId = payload.sessionId;
127
+ var isFacepileExperimentEnabled = FeatureGates.getExperimentValue('platform_editor_ai_facepile', 'isEnabled', false);
128
+ if (isFacepileExperimentEnabled) {
129
+ var _payload$data;
130
+ // When an agent leaves a session, the backend service returns the original user's
131
+ // session ID accompanied by a payload containing the agent's session ID.
132
+ // If the user session leaves, we also want to remove all agent sessions associated.
133
+ if (payload !== null && payload !== void 0 && (_payload$data = payload.data) !== null && _payload$data !== void 0 && _payload$data.sessionId && isAIProviderID(payload.data.sessionId)) {
134
+ sessionId = payload.data.sessionId;
135
+ } else {
136
+ var associatedAgents = _this.getAIProviderParticipants().filter(function (ap) {
137
+ return ap.sessionId.endsWith(sessionId);
138
+ });
139
+ associatedAgents.forEach(function (agent) {
140
+ _this.onParticipantLeft({
141
+ sessionId: sessionId,
142
+ timestamp: payload.timestamp,
143
+ data: agent,
144
+ userId: undefined,
145
+ clientId: ''
146
+ });
147
+ });
148
+ }
149
+ }
104
150
  _this.participantsState.removeBySessionId(sessionId);
105
151
  _this.emitPresence({
106
152
  left: [{
@@ -311,6 +357,9 @@ export var ParticipantsService = /*#__PURE__*/function () {
311
357
  _defineProperty(this, "getParticipants", function () {
312
358
  return _this.participantsState.getParticipants();
313
359
  });
360
+ _defineProperty(this, "getAIProviderParticipants", function () {
361
+ return _this.participantsState.getAIProviderParticipants();
362
+ });
314
363
  this.analyticsHelper = analyticsHelper;
315
364
  this.participantsState = participantsState;
316
365
  this.emit = emit;
@@ -4,6 +4,7 @@ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
4
4
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
5
  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; }
6
6
  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) { _defineProperty(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; }
7
+ import { isAIProviderID } from '../helpers/utils';
7
8
  export var ParticipantsState = /*#__PURE__*/_createClass(function ParticipantsState() {
8
9
  var _this = this;
9
10
  var baseParticipants = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Map();
@@ -19,7 +20,19 @@ export var ParticipantsState = /*#__PURE__*/_createClass(function ParticipantsSt
19
20
  _defineProperty(this, "getParticipants", function () {
20
21
  return (
21
22
  // Spread to get deep copy
22
- _toConsumableArray(_this.participants.values()).map(function (p) {
23
+ _toConsumableArray(_this.participants.values()).filter(function (p) {
24
+ return !isAIProviderID(p.userId);
25
+ }).map(function (p) {
26
+ return _objectSpread({}, p);
27
+ })
28
+ );
29
+ });
30
+ _defineProperty(this, "getAIProviderParticipants", function () {
31
+ return (
32
+ // Spread to get deep copy
33
+ _toConsumableArray(_this.participants.values()).filter(function (p) {
34
+ return isAIProviderID(p.userId);
35
+ }).map(function (p) {
23
36
  return _objectSpread({}, p);
24
37
  })
25
38
  );
@@ -271,6 +271,9 @@ export var Provider = /*#__PURE__*/function (_Emitter) {
271
271
  _defineProperty(_assertThisInitialized(_this), "getParticipants", function () {
272
272
  return _this.participantsService.getParticipants();
273
273
  });
274
+ _defineProperty(_assertThisInitialized(_this), "getAIProviderParticipants", function () {
275
+ return _this.participantsService.getAIProviderParticipants();
276
+ });
274
277
  _defineProperty(_assertThisInitialized(_this), "getSessionId", function () {
275
278
  return _this.sessionId;
276
279
  });
@@ -453,8 +456,11 @@ export var Provider = /*#__PURE__*/function (_Emitter) {
453
456
  }
454
457
 
455
458
  /**
456
- * 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.
459
+ * Send messages, such as telepointers, and AI provider changes to NCS and other participants.
460
+ * Only used for telepointer data (text and node selections) in the editor and JWM.
461
+ * JWM does some weird serialisation stuff on the node selections.
457
462
  * Silently fails if an error occurs, since Presence isn't a critical functionality and self-restores over time.
463
+ *
458
464
  * @param {CollabTelepointerPayload} data Data you want to send to NCS / the other participants
459
465
  * @param {string} data.type Can only be 'telepointer' for now, we don't support anything else yet
460
466
  * @param {CollabSendableSelection} data.selection Object representing the selected element
@@ -478,6 +484,8 @@ export var Provider = /*#__PURE__*/function (_Emitter) {
478
484
  this.channel.broadcast((data === null || data === void 0 ? void 0 : data.type) === 'activity:join' ? 'participant:activity-join' : 'participant:activity-ack', _objectSpread(_objectSpread({}, basePayload), {}, {
479
485
  activity: data.activity
480
486
  }), activityCallback());
487
+ } else if ((data === null || data === void 0 ? void 0 : data.type) === 'ai-provider:change') {
488
+ this.participantsService.sendAIProviderChanged(_objectSpread(_objectSpread({}, basePayload), data));
481
489
  }
482
490
  } catch (error) {
483
491
  var _this$analyticsHelper12;
@@ -1,5 +1,5 @@
1
1
  export var name = "@atlaskit/collab-provider";
2
- export var version = "9.45.0";
2
+ export var version = "9.46.0";
3
3
  export var nextMajorVersion = function nextMajorVersion() {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -2,6 +2,7 @@ import type { ProductInformation } from '../types';
2
2
  import type { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
3
3
  export declare const createLogger: (prefix: string, color?: string) => (msg: string, data?: any) => void;
4
4
  export declare function sleep(ms: number): Promise<unknown>;
5
+ export declare const isAIProviderID: (id: string) => boolean;
5
6
  export declare const getProduct: (productInfo?: ProductInformation) => string;
6
7
  export declare const getSubProduct: (productInfo?: ProductInformation) => string;
7
8
  export type UGCFreeStepDetails = {
@@ -5,6 +5,7 @@ export type ParticipantsMap = Map<string, ProviderParticipant>;
5
5
  export type GetUserType = ((userId: string) => Promise<Pick<ProviderParticipant, 'name' | 'avatar' | 'userId' | 'email' | 'isGuest'>>) | undefined;
6
6
  export declare const createParticipantFromPayload: (payload: import("../types").PresenceData & {
7
7
  timestamp: number;
8
+ data?: Record<string, any> | undefined;
8
9
  } & {
9
10
  userId: string;
10
11
  }, getUser: GetUserType) => Promise<ProviderParticipant>;
@@ -1,6 +1,6 @@
1
1
  import type AnalyticsHelper from '../analytics/analytics-helper';
2
2
  import type { CollabEventDisconnectedData, ChannelEvent, PresenceData, PresencePayload, TelepointerPayload, ActivityPayload } from '../types';
3
- import type { CollabActivityData, CollabEventPresenceData, CollabTelepointerPayload, ProviderParticipant, StepJson } from '@atlaskit/editor-common/collab';
3
+ import type { CollabActivityData, CollabEventPresenceData, CollabTelepointerPayload, ProviderParticipant, StepJson, UserPermitType } from '@atlaskit/editor-common/collab';
4
4
  import type { GetUserType } from './participants-helper';
5
5
  import { ParticipantsState } from './participants-state';
6
6
  /**
@@ -24,6 +24,14 @@ export declare class ParticipantsService {
24
24
  private participantUpdateTimeout;
25
25
  private presenceUpdateTimeout;
26
26
  constructor(analyticsHelper: AnalyticsHelper | undefined, participantsState: ParticipantsState, emit: (evt: 'presence' | 'telepointer' | 'disconnected' | 'activity:join' | 'activity:ack', data: CollabEventPresenceData | CollabTelepointerPayload | CollabEventDisconnectedData | CollabActivityData) => void, getUser: GetUserType, channelBroadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], 'timestamp'>, callback?: Function) => void, sendPresenceJoined: () => void, getPresenceData: () => PresenceData, setUserId: (id: string) => void);
27
+ sendAIProviderChanged: (payload: {
28
+ userId: string;
29
+ sessionId: string;
30
+ clientId: string | number;
31
+ providerId?: string;
32
+ action: 'add' | 'remove';
33
+ permit?: UserPermitType;
34
+ }) => void;
27
35
  /**
28
36
  * Carries out 3 things: 1) enriches the participant with user data, 2) updates the participantsState, 3) emits the presence event
29
37
  * @param payload Payload from incoming socket event
@@ -34,7 +42,7 @@ export declare class ParticipantsService {
34
42
  * Called when a participant leaves the session.
35
43
  * We emit the `presence` event to update the active avatars in the editor.
36
44
  */
37
- onParticipantLeft: ({ sessionId }: PresencePayload) => void;
45
+ onParticipantLeft: (payload: PresencePayload) => void;
38
46
  disconnect: (reason: string, sessionId: string | undefined) => void;
39
47
  /**
40
48
  * Updates when users were last active
@@ -105,4 +113,5 @@ export declare class ParticipantsService {
105
113
  *
106
114
  */
107
115
  getParticipants: () => ProviderParticipant[];
116
+ getAIProviderParticipants: () => ProviderParticipant[];
108
117
  }
@@ -6,6 +6,7 @@ export declare class ParticipantsState {
6
6
  getBySessionId: (sessionId: string) => ProviderParticipant | undefined;
7
7
  setBySessionId: (sessionId: string, participant: ProviderParticipant) => void;
8
8
  getParticipants: () => ProviderParticipant[];
9
+ getAIProviderParticipants: () => ProviderParticipant[];
9
10
  removeBySessionId: (sessionId: string) => boolean;
10
11
  clear: () => void;
11
12
  doesntHave: (sessionId: string) => boolean;
@@ -2,7 +2,7 @@ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/stat
2
2
  import type { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
3
3
  import { Emitter } from '../emitter';
4
4
  import type { Config } from '../types';
5
- import type { CollabEditProvider, CollabEvents, CollabTelepointerPayload, ResolvedEditorState, Metadata, SyncUpErrorFunction, CollabActivityJoinPayload, CollabActivityAckPayload } from '@atlaskit/editor-common/collab';
5
+ import type { CollabEditProvider, CollabEvents, CollabTelepointerPayload, ResolvedEditorState, Metadata, SyncUpErrorFunction, CollabActivityJoinPayload, CollabActivityAckPayload, CollabActivityAIProviderChangedPayload } from '@atlaskit/editor-common/collab';
6
6
  import { Api } from '../api/api';
7
7
  import { NullApi } from '../api/null-api';
8
8
  export declare const MAX_STEP_REJECTED_ERROR = 15;
@@ -82,14 +82,17 @@ export declare class Provider extends Emitter<CollabEvents> implements BaseEvent
82
82
  private onErrorHandled;
83
83
  private isViewOnly;
84
84
  /**
85
- * 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.
85
+ * Send messages, such as telepointers, and AI provider changes to NCS and other participants.
86
+ * Only used for telepointer data (text and node selections) in the editor and JWM.
87
+ * JWM does some weird serialisation stuff on the node selections.
86
88
  * Silently fails if an error occurs, since Presence isn't a critical functionality and self-restores over time.
89
+ *
87
90
  * @param {CollabTelepointerPayload} data Data you want to send to NCS / the other participants
88
91
  * @param {string} data.type Can only be 'telepointer' for now, we don't support anything else yet
89
92
  * @param {CollabSendableSelection} data.selection Object representing the selected element
90
93
  * @param {string} data.sessionId Identifier identifying the session
91
94
  */
92
- sendMessage(data: CollabTelepointerPayload | CollabActivityJoinPayload | CollabActivityAckPayload): void;
95
+ sendMessage(data: CollabTelepointerPayload | CollabActivityJoinPayload | CollabActivityAckPayload | CollabActivityAIProviderChangedPayload): void;
93
96
  private onDisconnected;
94
97
  /**
95
98
  * "Destroy" the provider, disconnect it's connection to the back-end service and unsubscribe all event listeners on the provider.
@@ -163,6 +166,7 @@ export declare class Provider extends Emitter<CollabEvents> implements BaseEvent
163
166
  *
164
167
  */
165
168
  getParticipants: () => import("@atlaskit/editor-common/collab").ProviderParticipant[];
169
+ getAIProviderParticipants: () => import("@atlaskit/editor-common/collab").ProviderParticipant[];
166
170
  getSessionId: () => string | undefined;
167
171
  }
168
172
  export {};
@@ -128,6 +128,7 @@ export type PresenceData = {
128
128
  };
129
129
  export type PresencePayload = PresenceData & {
130
130
  timestamp: number;
131
+ data?: Record<string, any>;
131
132
  };
132
133
  export type ActivityPayload = {
133
134
  userId: string | undefined;
@@ -2,6 +2,7 @@ import type { ProductInformation } from '../types';
2
2
  import type { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
3
3
  export declare const createLogger: (prefix: string, color?: string) => (msg: string, data?: any) => void;
4
4
  export declare function sleep(ms: number): Promise<unknown>;
5
+ export declare const isAIProviderID: (id: string) => boolean;
5
6
  export declare const getProduct: (productInfo?: ProductInformation) => string;
6
7
  export declare const getSubProduct: (productInfo?: ProductInformation) => string;
7
8
  export type UGCFreeStepDetails = {
@@ -5,6 +5,7 @@ export type ParticipantsMap = Map<string, ProviderParticipant>;
5
5
  export type GetUserType = ((userId: string) => Promise<Pick<ProviderParticipant, 'name' | 'avatar' | 'userId' | 'email' | 'isGuest'>>) | undefined;
6
6
  export declare const createParticipantFromPayload: (payload: import("../types").PresenceData & {
7
7
  timestamp: number;
8
+ data?: Record<string, any> | undefined;
8
9
  } & {
9
10
  userId: string;
10
11
  }, getUser: GetUserType) => Promise<ProviderParticipant>;
@@ -1,6 +1,6 @@
1
1
  import type AnalyticsHelper from '../analytics/analytics-helper';
2
2
  import type { CollabEventDisconnectedData, ChannelEvent, PresenceData, PresencePayload, TelepointerPayload, ActivityPayload } from '../types';
3
- import type { CollabActivityData, CollabEventPresenceData, CollabTelepointerPayload, ProviderParticipant, StepJson } from '@atlaskit/editor-common/collab';
3
+ import type { CollabActivityData, CollabEventPresenceData, CollabTelepointerPayload, ProviderParticipant, StepJson, UserPermitType } from '@atlaskit/editor-common/collab';
4
4
  import type { GetUserType } from './participants-helper';
5
5
  import { ParticipantsState } from './participants-state';
6
6
  /**
@@ -24,6 +24,14 @@ export declare class ParticipantsService {
24
24
  private participantUpdateTimeout;
25
25
  private presenceUpdateTimeout;
26
26
  constructor(analyticsHelper: AnalyticsHelper | undefined, participantsState: ParticipantsState, emit: (evt: 'presence' | 'telepointer' | 'disconnected' | 'activity:join' | 'activity:ack', data: CollabEventPresenceData | CollabTelepointerPayload | CollabEventDisconnectedData | CollabActivityData) => void, getUser: GetUserType, channelBroadcast: <K extends keyof ChannelEvent>(type: K, data: Omit<ChannelEvent[K], 'timestamp'>, callback?: Function) => void, sendPresenceJoined: () => void, getPresenceData: () => PresenceData, setUserId: (id: string) => void);
27
+ sendAIProviderChanged: (payload: {
28
+ userId: string;
29
+ sessionId: string;
30
+ clientId: string | number;
31
+ providerId?: string;
32
+ action: 'add' | 'remove';
33
+ permit?: UserPermitType;
34
+ }) => void;
27
35
  /**
28
36
  * Carries out 3 things: 1) enriches the participant with user data, 2) updates the participantsState, 3) emits the presence event
29
37
  * @param payload Payload from incoming socket event
@@ -34,7 +42,7 @@ export declare class ParticipantsService {
34
42
  * Called when a participant leaves the session.
35
43
  * We emit the `presence` event to update the active avatars in the editor.
36
44
  */
37
- onParticipantLeft: ({ sessionId }: PresencePayload) => void;
45
+ onParticipantLeft: (payload: PresencePayload) => void;
38
46
  disconnect: (reason: string, sessionId: string | undefined) => void;
39
47
  /**
40
48
  * Updates when users were last active
@@ -105,4 +113,5 @@ export declare class ParticipantsService {
105
113
  *
106
114
  */
107
115
  getParticipants: () => ProviderParticipant[];
116
+ getAIProviderParticipants: () => ProviderParticipant[];
108
117
  }
@@ -6,6 +6,7 @@ export declare class ParticipantsState {
6
6
  getBySessionId: (sessionId: string) => ProviderParticipant | undefined;
7
7
  setBySessionId: (sessionId: string, participant: ProviderParticipant) => void;
8
8
  getParticipants: () => ProviderParticipant[];
9
+ getAIProviderParticipants: () => ProviderParticipant[];
9
10
  removeBySessionId: (sessionId: string) => boolean;
10
11
  clear: () => void;
11
12
  doesntHave: (sessionId: string) => boolean;
@@ -2,7 +2,7 @@ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/stat
2
2
  import type { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
3
3
  import { Emitter } from '../emitter';
4
4
  import type { Config } from '../types';
5
- import type { CollabEditProvider, CollabEvents, CollabTelepointerPayload, ResolvedEditorState, Metadata, SyncUpErrorFunction, CollabActivityJoinPayload, CollabActivityAckPayload } from '@atlaskit/editor-common/collab';
5
+ import type { CollabEditProvider, CollabEvents, CollabTelepointerPayload, ResolvedEditorState, Metadata, SyncUpErrorFunction, CollabActivityJoinPayload, CollabActivityAckPayload, CollabActivityAIProviderChangedPayload } from '@atlaskit/editor-common/collab';
6
6
  import { Api } from '../api/api';
7
7
  import { NullApi } from '../api/null-api';
8
8
  export declare const MAX_STEP_REJECTED_ERROR = 15;
@@ -82,14 +82,17 @@ export declare class Provider extends Emitter<CollabEvents> implements BaseEvent
82
82
  private onErrorHandled;
83
83
  private isViewOnly;
84
84
  /**
85
- * 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.
85
+ * Send messages, such as telepointers, and AI provider changes to NCS and other participants.
86
+ * Only used for telepointer data (text and node selections) in the editor and JWM.
87
+ * JWM does some weird serialisation stuff on the node selections.
86
88
  * Silently fails if an error occurs, since Presence isn't a critical functionality and self-restores over time.
89
+ *
87
90
  * @param {CollabTelepointerPayload} data Data you want to send to NCS / the other participants
88
91
  * @param {string} data.type Can only be 'telepointer' for now, we don't support anything else yet
89
92
  * @param {CollabSendableSelection} data.selection Object representing the selected element
90
93
  * @param {string} data.sessionId Identifier identifying the session
91
94
  */
92
- sendMessage(data: CollabTelepointerPayload | CollabActivityJoinPayload | CollabActivityAckPayload): void;
95
+ sendMessage(data: CollabTelepointerPayload | CollabActivityJoinPayload | CollabActivityAckPayload | CollabActivityAIProviderChangedPayload): void;
93
96
  private onDisconnected;
94
97
  /**
95
98
  * "Destroy" the provider, disconnect it's connection to the back-end service and unsubscribe all event listeners on the provider.
@@ -163,6 +166,7 @@ export declare class Provider extends Emitter<CollabEvents> implements BaseEvent
163
166
  *
164
167
  */
165
168
  getParticipants: () => import("@atlaskit/editor-common/collab").ProviderParticipant[];
169
+ getAIProviderParticipants: () => import("@atlaskit/editor-common/collab").ProviderParticipant[];
166
170
  getSessionId: () => string | undefined;
167
171
  }
168
172
  export {};
@@ -128,6 +128,7 @@ export type PresenceData = {
128
128
  };
129
129
  export type PresencePayload = PresenceData & {
130
130
  timestamp: number;
131
+ data?: Record<string, any>;
131
132
  };
132
133
  export type ActivityPayload = {
133
134
  userId: string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/collab-provider",
3
- "version": "9.45.0",
3
+ "version": "9.46.0",
4
4
  "description": "A provider for collaborative editing.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -34,9 +34,10 @@
34
34
  "dependencies": {
35
35
  "@atlaskit/analytics-gas-types": "^5.1.0",
36
36
  "@atlaskit/analytics-listeners": "^8.11.0",
37
- "@atlaskit/editor-common": "^94.20.0",
37
+ "@atlaskit/editor-common": "^94.24.0",
38
38
  "@atlaskit/editor-json-transformer": "^8.21.0",
39
39
  "@atlaskit/editor-prosemirror": "6.0.0",
40
+ "@atlaskit/feature-gate-js-client": "^4.22.0",
40
41
  "@atlaskit/platform-feature-flags": "^0.3.0",
41
42
  "@atlaskit/prosemirror-collab": "^0.10.0",
42
43
  "@atlaskit/ufo": "^0.3.0",