@atlaskit/collab-provider 10.5.1 → 10.6.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @atlaskit/collab-provider
2
2
 
3
+ ## 10.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#105322](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/105322)
8
+ [`8876083532adc`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/8876083532adc) -
9
+ Bumped editor-prosemirror version to 7.0.0
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+
15
+ ## 10.5.2
16
+
17
+ ### Patch Changes
18
+
19
+ - [#109636](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/109636)
20
+ [`2eadf04054ac2`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/2eadf04054ac2) -
21
+ [ux] Introduces way to retrieve the document from offline if there is a possible conflict event on
22
+ reconnection.
23
+ - Updated dependencies
24
+
3
25
  ## 10.5.1
4
26
 
5
27
  ### Patch Changes
@@ -120,6 +120,7 @@ var DocumentService = exports.DocumentService = /*#__PURE__*/function () {
120
120
  (_this$analyticsHelper = _this.analyticsHelper) === null || _this$analyticsHelper === void 0 || _this$analyticsHelper.sendActionEvent(_const.EVENT_ACTION.RECONNECTION, _const.EVENT_STATUS.INFO, _objectSpread(_objectSpread({}, reconnectionMetadata), {}, {
121
121
  remoteStepsLength: (_steps$length = steps === null || steps === void 0 ? void 0 : steps.length) !== null && _steps$length !== void 0 ? _steps$length : 0
122
122
  }));
123
+ _this.notifyReconnectionConflict(steps);
123
124
  }
124
125
  },
125
126
  getState: _this.getState
@@ -128,7 +129,8 @@ var DocumentService = exports.DocumentService = /*#__PURE__*/function () {
128
129
  _this.catchUpOutofSync = _context.sent;
129
130
  latency = new Date().getTime() - start;
130
131
  (_this$analyticsHelper2 = _this.analyticsHelper) === null || _this$analyticsHelper2 === void 0 || _this$analyticsHelper2.sendActionEvent(_const.EVENT_ACTION.CATCHUP, _const.EVENT_STATUS.SUCCESS, {
131
- latency: latency
132
+ latency: latency,
133
+ version: _this.getCurrentPmVersion()
132
134
  });
133
135
  _context.next = 20;
134
136
  break;
@@ -724,6 +726,29 @@ var DocumentService = exports.DocumentService = /*#__PURE__*/function () {
724
726
  }
725
727
  return collabState.version;
726
728
  }
729
+ }, {
730
+ key: "notifyReconnectionConflict",
731
+ value:
732
+ /**
733
+ * In the event we reconnect check if we have existing unconfirmed steps and if so
734
+ * notify the editor that we have a potential conflict to resolve on the frontend.
735
+ *
736
+ * @param data remote steps payload
737
+ */
738
+ function notifyReconnectionConflict(steps) {
739
+ var _this$getState7, _getCollabState;
740
+ if (!(0, _platformFeatureFlags.fg)('platform_editor_offline_conflict_resolution')) {
741
+ return;
742
+ }
743
+ var state = (_this$getState7 = this.getState) === null || _this$getState7 === void 0 ? void 0 : _this$getState7.call(this);
744
+ var unconfirmedSteps = state ? (_getCollabState = (0, _prosemirrorCollab.getCollabState)(state)) === null || _getCollabState === void 0 ? void 0 : _getCollabState.unconfirmed : undefined;
745
+ if (steps.length > 0 && state && unconfirmedSteps && unconfirmedSteps.length > 0) {
746
+ // In the future we can determine the type of conflict
747
+ this.providerEmitCallback('data:conflict', {
748
+ offlineDoc: state.doc
749
+ });
750
+ }
751
+ }
727
752
  }, {
728
753
  key: "processQueue",
729
754
  value: function processQueue() {
@@ -817,8 +842,8 @@ var DocumentService = exports.DocumentService = /*#__PURE__*/function () {
817
842
  }, {
818
843
  key: "sendStepsFromCurrentState",
819
844
  value: function sendStepsFromCurrentState(sendAnalyticsEvent) {
820
- var _this$getState7;
821
- var state = (_this$getState7 = this.getState) === null || _this$getState7 === void 0 ? void 0 : _this$getState7.call(this);
845
+ var _this$getState8;
846
+ var state = (_this$getState8 = this.getState) === null || _this$getState8 === void 0 ? void 0 : _this$getState8.call(this);
822
847
  if (!state) {
823
848
  var _this$analyticsHelper33;
824
849
  (_this$analyticsHelper33 = this.analyticsHelper) === null || _this$analyticsHelper33 === void 0 || _this$analyticsHelper33.sendErrorEvent(new Error('Editor state is undefined'), 'sendStepsFromCurrentState called without state');
@@ -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 = "10.5.1";
8
+ var version = exports.version = "10.6.0";
9
9
  var nextMajorVersion = exports.nextMajorVersion = function nextMajorVersion() {
10
10
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
11
11
  };
@@ -114,13 +114,15 @@ export class DocumentService {
114
114
  ...reconnectionMetadata,
115
115
  remoteStepsLength: (_steps$length = steps === null || steps === void 0 ? void 0 : steps.length) !== null && _steps$length !== void 0 ? _steps$length : 0
116
116
  });
117
+ this.notifyReconnectionConflict(steps);
117
118
  }
118
119
  },
119
120
  getState: this.getState
120
121
  });
121
122
  const latency = new Date().getTime() - start;
122
123
  (_this$analyticsHelper2 = this.analyticsHelper) === null || _this$analyticsHelper2 === void 0 ? void 0 : _this$analyticsHelper2.sendActionEvent(EVENT_ACTION.CATCHUP, EVENT_STATUS.SUCCESS, {
123
- latency
124
+ latency,
125
+ version: this.getCurrentPmVersion()
124
126
  });
125
127
  } catch (error) {
126
128
  var _this$analyticsHelper3;
@@ -611,6 +613,26 @@ export class DocumentService {
611
613
  }
612
614
  return collabState.version;
613
615
  }
616
+ /**
617
+ * In the event we reconnect check if we have existing unconfirmed steps and if so
618
+ * notify the editor that we have a potential conflict to resolve on the frontend.
619
+ *
620
+ * @param data remote steps payload
621
+ */
622
+ notifyReconnectionConflict(steps) {
623
+ var _this$getState7, _getCollabState;
624
+ if (!fg('platform_editor_offline_conflict_resolution')) {
625
+ return;
626
+ }
627
+ const state = (_this$getState7 = this.getState) === null || _this$getState7 === void 0 ? void 0 : _this$getState7.call(this);
628
+ const unconfirmedSteps = state ? (_getCollabState = getCollabState(state)) === null || _getCollabState === void 0 ? void 0 : _getCollabState.unconfirmed : undefined;
629
+ if (steps.length > 0 && state && unconfirmedSteps && unconfirmedSteps.length > 0) {
630
+ // In the future we can determine the type of conflict
631
+ this.providerEmitCallback('data:conflict', {
632
+ offlineDoc: state.doc
633
+ });
634
+ }
635
+ }
614
636
  processQueue() {
615
637
  if (this.stepQueue.isPaused()) {
616
638
  logger(`Queue is paused. Aborting.`);
@@ -693,8 +715,8 @@ export class DocumentService {
693
715
  * from the EditorView.
694
716
  */
695
717
  sendStepsFromCurrentState(sendAnalyticsEvent) {
696
- var _this$getState7;
697
- const state = (_this$getState7 = this.getState) === null || _this$getState7 === void 0 ? void 0 : _this$getState7.call(this);
718
+ var _this$getState8;
719
+ const state = (_this$getState8 = this.getState) === null || _this$getState8 === void 0 ? void 0 : _this$getState8.call(this);
698
720
  if (!state) {
699
721
  var _this$analyticsHelper33;
700
722
  (_this$analyticsHelper33 = this.analyticsHelper) === null || _this$analyticsHelper33 === void 0 ? void 0 : _this$analyticsHelper33.sendErrorEvent(new Error('Editor state is undefined'), 'sendStepsFromCurrentState called without state');
@@ -1,5 +1,5 @@
1
1
  export const name = "@atlaskit/collab-provider";
2
- export const version = "10.5.1";
2
+ export const version = "10.6.0";
3
3
  export const nextMajorVersion = () => {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -113,6 +113,7 @@ export var DocumentService = /*#__PURE__*/function () {
113
113
  (_this$analyticsHelper = _this.analyticsHelper) === null || _this$analyticsHelper === void 0 || _this$analyticsHelper.sendActionEvent(EVENT_ACTION.RECONNECTION, EVENT_STATUS.INFO, _objectSpread(_objectSpread({}, reconnectionMetadata), {}, {
114
114
  remoteStepsLength: (_steps$length = steps === null || steps === void 0 ? void 0 : steps.length) !== null && _steps$length !== void 0 ? _steps$length : 0
115
115
  }));
116
+ _this.notifyReconnectionConflict(steps);
116
117
  }
117
118
  },
118
119
  getState: _this.getState
@@ -121,7 +122,8 @@ export var DocumentService = /*#__PURE__*/function () {
121
122
  _this.catchUpOutofSync = _context.sent;
122
123
  latency = new Date().getTime() - start;
123
124
  (_this$analyticsHelper2 = _this.analyticsHelper) === null || _this$analyticsHelper2 === void 0 || _this$analyticsHelper2.sendActionEvent(EVENT_ACTION.CATCHUP, EVENT_STATUS.SUCCESS, {
124
- latency: latency
125
+ latency: latency,
126
+ version: _this.getCurrentPmVersion()
125
127
  });
126
128
  _context.next = 20;
127
129
  break;
@@ -717,6 +719,29 @@ export var DocumentService = /*#__PURE__*/function () {
717
719
  }
718
720
  return collabState.version;
719
721
  }
722
+ }, {
723
+ key: "notifyReconnectionConflict",
724
+ value:
725
+ /**
726
+ * In the event we reconnect check if we have existing unconfirmed steps and if so
727
+ * notify the editor that we have a potential conflict to resolve on the frontend.
728
+ *
729
+ * @param data remote steps payload
730
+ */
731
+ function notifyReconnectionConflict(steps) {
732
+ var _this$getState7, _getCollabState;
733
+ if (!fg('platform_editor_offline_conflict_resolution')) {
734
+ return;
735
+ }
736
+ var state = (_this$getState7 = this.getState) === null || _this$getState7 === void 0 ? void 0 : _this$getState7.call(this);
737
+ var unconfirmedSteps = state ? (_getCollabState = getCollabState(state)) === null || _getCollabState === void 0 ? void 0 : _getCollabState.unconfirmed : undefined;
738
+ if (steps.length > 0 && state && unconfirmedSteps && unconfirmedSteps.length > 0) {
739
+ // In the future we can determine the type of conflict
740
+ this.providerEmitCallback('data:conflict', {
741
+ offlineDoc: state.doc
742
+ });
743
+ }
744
+ }
720
745
  }, {
721
746
  key: "processQueue",
722
747
  value: function processQueue() {
@@ -810,8 +835,8 @@ export var DocumentService = /*#__PURE__*/function () {
810
835
  }, {
811
836
  key: "sendStepsFromCurrentState",
812
837
  value: function sendStepsFromCurrentState(sendAnalyticsEvent) {
813
- var _this$getState7;
814
- var state = (_this$getState7 = this.getState) === null || _this$getState7 === void 0 ? void 0 : _this$getState7.call(this);
838
+ var _this$getState8;
839
+ var state = (_this$getState8 = this.getState) === null || _this$getState8 === void 0 ? void 0 : _this$getState8.call(this);
815
840
  if (!state) {
816
841
  var _this$analyticsHelper33;
817
842
  (_this$analyticsHelper33 = this.analyticsHelper) === null || _this$analyticsHelper33 === void 0 || _this$analyticsHelper33.sendErrorEvent(new Error('Editor state is undefined'), 'sendStepsFromCurrentState called without state');
@@ -1,5 +1,5 @@
1
1
  export var name = "@atlaskit/collab-provider";
2
- export var version = "10.5.1";
2
+ export var version = "10.6.0";
3
3
  export var nextMajorVersion = function nextMajorVersion() {
4
4
  return [Number(version.split('.')[0]) + 1, 0, 0].join('.');
5
5
  };
@@ -62,6 +62,13 @@ export declare class DocumentService implements DocumentServiceInterface {
62
62
  private catchupv2;
63
63
  private getVersionFromCollabState;
64
64
  getCurrentPmVersion: () => number;
65
+ /**
66
+ * In the event we reconnect check if we have existing unconfirmed steps and if so
67
+ * notify the editor that we have a potential conflict to resolve on the frontend.
68
+ *
69
+ * @param data remote steps payload
70
+ */
71
+ private notifyReconnectionConflict;
65
72
  private processQueue;
66
73
  getCurrentState: () => Promise<ResolvedEditorState>;
67
74
  private isStepsFromNewClientIdForSameUserId;
@@ -62,6 +62,13 @@ export declare class DocumentService implements DocumentServiceInterface {
62
62
  private catchupv2;
63
63
  private getVersionFromCollabState;
64
64
  getCurrentPmVersion: () => number;
65
+ /**
66
+ * In the event we reconnect check if we have existing unconfirmed steps and if so
67
+ * notify the editor that we have a potential conflict to resolve on the frontend.
68
+ *
69
+ * @param data remote steps payload
70
+ */
71
+ private notifyReconnectionConflict;
65
72
  private processQueue;
66
73
  getCurrentState: () => Promise<ResolvedEditorState>;
67
74
  private isStepsFromNewClientIdForSameUserId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/collab-provider",
3
- "version": "10.5.1",
3
+ "version": "10.6.0",
4
4
  "description": "A provider for collaborative editing.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -35,12 +35,12 @@
35
35
  "@atlaskit/adf-utils": "^19.18.0",
36
36
  "@atlaskit/analytics-gas-types": "^5.1.0",
37
37
  "@atlaskit/analytics-listeners": "^8.14.0",
38
- "@atlaskit/editor-common": "^99.7.0",
39
- "@atlaskit/editor-json-transformer": "^8.22.0",
40
- "@atlaskit/editor-prosemirror": "6.2.1",
38
+ "@atlaskit/editor-common": "^99.10.0",
39
+ "@atlaskit/editor-json-transformer": "^8.23.0",
40
+ "@atlaskit/editor-prosemirror": "7.0.0",
41
41
  "@atlaskit/feature-gate-js-client": "^4.22.0",
42
42
  "@atlaskit/platform-feature-flags": "^1.0.0",
43
- "@atlaskit/prosemirror-collab": "^0.11.0",
43
+ "@atlaskit/prosemirror-collab": "^0.12.0",
44
44
  "@atlaskit/react-ufo": "^2.14.0",
45
45
  "@atlaskit/ufo": "^0.3.0",
46
46
  "@atlaskit/util-service-support": "^6.2.0",
@@ -85,6 +85,9 @@
85
85
  "tag_unconfirmed_steps_after_recovery": {
86
86
  "type": "boolean"
87
87
  },
88
+ "platform_editor_offline_conflict_resolution": {
89
+ "type": "boolean"
90
+ },
88
91
  "platform_collab_provider_tracingheaders": {
89
92
  "type": "boolean"
90
93
  },