@atlaskit/editor-synced-block-provider 0.3.0 → 0.5.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 (32) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/common/rebase-transaction.js +31 -0
  3. package/dist/cjs/common/syncBlockProvider.js +19 -2
  4. package/dist/cjs/common/syncBlockStoreManager.js +16 -11
  5. package/dist/cjs/index.js +14 -1
  6. package/dist/cjs/providers/confluenceContentAPI.js +32 -48
  7. package/dist/cjs/providers/inMemory.js +9 -7
  8. package/dist/es2019/common/rebase-transaction.js +26 -0
  9. package/dist/es2019/common/syncBlockProvider.js +18 -1
  10. package/dist/es2019/common/syncBlockStoreManager.js +10 -7
  11. package/dist/es2019/index.js +3 -2
  12. package/dist/es2019/providers/confluenceContentAPI.js +45 -57
  13. package/dist/es2019/providers/inMemory.js +9 -7
  14. package/dist/esm/common/rebase-transaction.js +26 -0
  15. package/dist/esm/common/syncBlockProvider.js +18 -1
  16. package/dist/esm/common/syncBlockStoreManager.js +16 -11
  17. package/dist/esm/index.js +3 -2
  18. package/dist/esm/providers/confluenceContentAPI.js +32 -48
  19. package/dist/esm/providers/inMemory.js +9 -7
  20. package/dist/types/common/rebase-transaction.d.ts +11 -0
  21. package/dist/types/common/syncBlockProvider.d.ts +1 -0
  22. package/dist/types/common/syncBlockStoreManager.d.ts +3 -1
  23. package/dist/types/common/types.d.ts +9 -2
  24. package/dist/types/index.d.ts +2 -1
  25. package/dist/types/providers/confluenceContentAPI.d.ts +1 -1
  26. package/dist/types-ts4.5/common/rebase-transaction.d.ts +11 -0
  27. package/dist/types-ts4.5/common/syncBlockProvider.d.ts +1 -0
  28. package/dist/types-ts4.5/common/syncBlockStoreManager.d.ts +3 -1
  29. package/dist/types-ts4.5/common/types.d.ts +9 -2
  30. package/dist/types-ts4.5/index.d.ts +2 -1
  31. package/dist/types-ts4.5/providers/confluenceContentAPI.d.ts +1 -1
  32. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/editor-synced-block-provider
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`3ebbf8e97e2d9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3ebbf8e97e2d9) -
8
+ Simplify provider API
9
+
10
+ ## 0.4.0
11
+
12
+ ### Minor Changes
13
+
14
+ - [`acb8231bc9e0c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/acb8231bc9e0c) -
15
+ EDITOR-1779 - "rebase" the transaction to reflect the latest document state
16
+
3
17
  ## 0.3.0
4
18
 
5
19
  ### Minor Changes
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.rebaseTransaction = void 0;
7
+ var _transform = require("@atlaskit/editor-prosemirror/transform");
8
+ /**
9
+ * Rebase `currentTr` over `incomingTr` based on the provided `state`.
10
+ * This function adjusts the steps in `currentTr` to account for the changes made by `incomingTr`.
11
+ *
12
+ * @param currentTr - The transaction to be rebased.
13
+ * @param incomingTr - The transaction that has already been applied to the state.
14
+ * @param state - The editor state after applying `incomingTr`.
15
+ * @returns A new transaction that represents `currentTr` rebased over `incomingTr`.
16
+ */
17
+ var rebaseTransaction = exports.rebaseTransaction = function rebaseTransaction(currentTr, incomingTr, state) {
18
+ if (!incomingTr.docChanged) {
19
+ return currentTr;
20
+ }
21
+ var currentMapping = new _transform.Mapping(incomingTr.mapping.maps);
22
+ var rebasedTransaction = state.tr;
23
+ currentTr.steps.forEach(function (step) {
24
+ var mappedStep = step.map(currentMapping);
25
+ if (mappedStep) {
26
+ rebasedTransaction.step(mappedStep);
27
+ currentMapping.appendMap(mappedStep.getMap());
28
+ }
29
+ });
30
+ return rebasedTransaction;
31
+ };
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.useMemoizedSyncedBlockProvider = exports.useFetchDocNode = exports.SyncBlockProvider = void 0;
7
+ exports.useMemoizedSyncedBlockProvider = exports.useHandleContentChanges = exports.useFetchDocNode = exports.SyncBlockProvider = void 0;
8
8
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
9
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
@@ -50,7 +50,7 @@ var SyncBlockProvider = exports.SyncBlockProvider = /*#__PURE__*/function (_Sync
50
50
  resourceIds.push(Promise.reject('No Synced Blockcontent to write'));
51
51
  return;
52
52
  }
53
- var resourceId = _this.writeProvider.writeData(_this.sourceId, node.attrs.localId, data[index].content, node.attrs.resourceId);
53
+ var resourceId = _this.writeProvider.writeData(data[index]);
54
54
  resourceIds.push(resourceId);
55
55
  });
56
56
  return Promise.all(resourceIds);
@@ -101,4 +101,21 @@ var useMemoizedSyncedBlockProvider = exports.useMemoizedSyncedBlockProvider = fu
101
101
  return (0, _react.useMemo)(function () {
102
102
  return new SyncBlockProvider(fetchProvider, writeProvider, sourceId);
103
103
  }, [fetchProvider, writeProvider, sourceId]);
104
+ };
105
+ var useHandleContentChanges = exports.useHandleContentChanges = function useHandleContentChanges(updatedDoc, isSource, node, provider) {
106
+ (0, _react.useEffect)(function () {
107
+ if (!isSource) {
108
+ return;
109
+ }
110
+ if (!provider) {
111
+ return;
112
+ }
113
+ var syncBlockNode = (0, _utils.convertSyncBlockPMNodeToSyncBlockData)(node, false);
114
+ var data = {
115
+ content: updatedDoc.toJSON(),
116
+ resourceId: node.attrs.resourceId,
117
+ localId: node.attrs.localId
118
+ };
119
+ provider === null || provider === void 0 || provider.writeNodesData([syncBlockNode], [data]);
120
+ }, [isSource, node, provider, updatedDoc]);
104
121
  };
@@ -10,6 +10,7 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
10
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
11
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
12
12
  var _uuid = _interopRequireDefault(require("uuid"));
13
+ var _rebaseTransaction2 = require("./rebase-transaction");
13
14
  // Do this typedef to make it clear that
14
15
  // this is a local identifier for a resource for local use
15
16
  // A store manager responsible for the lifecycle and state management of sync blocks in an editor instance.
@@ -57,11 +58,6 @@ var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/functio
57
58
  key: "createSyncBlockNode",
58
59
  value: function createSyncBlockNode() {
59
60
  var _this$dataProvider;
60
- // TODO: EDITOR-1644 - properly implement creation of the synced block
61
- // below is a temporary implementation for the creation of the synced block
62
- // the resource id needs to have pageId and content property key in it
63
- // Note: If the data provider is not set, the resource id will be the local id
64
-
65
61
  var localId = (0, _uuid.default)();
66
62
  var sourceId = (_this$dataProvider = this.dataProvider) === null || _this$dataProvider === void 0 ? void 0 : _this$dataProvider.getSourceId();
67
63
  var resourceId = sourceId ? "".concat(sourceId, "/").concat(localId) : localId;
@@ -88,23 +84,24 @@ var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/functio
88
84
  while (1) switch (_context.prev = _context.next) {
89
85
  case 0:
90
86
  if (!this.confirmationCallback) {
91
- _context.next = 5;
87
+ _context.next = 7;
92
88
  break;
93
89
  }
94
- _context.next = 3;
90
+ this.confirmationTransaction = tr;
91
+ _context.next = 4;
95
92
  return this.confirmationCallback();
96
- case 3:
93
+ case 4:
97
94
  confirmed = _context.sent;
98
95
  if (confirmed) {
99
- // TODO: EDITOR-1779 - "rebase" the transaction to reflect the latest document state
100
- (_this$editorView = this.editorView) === null || _this$editorView === void 0 || _this$editorView.dispatch(tr.setMeta('isConfirmedSyncBlockDeletion', true));
96
+ (_this$editorView = this.editorView) === null || _this$editorView === void 0 || _this$editorView.dispatch(this.confirmationTransaction.setMeta('isConfirmedSyncBlockDeletion', true));
101
97
  // Need to update the BE on deletion
102
98
  syncBlockIds.forEach(function (_ref) {
103
99
  var resourceId = _ref.resourceId;
104
100
  return _this2.syncBlocks.delete(resourceId);
105
101
  });
106
102
  }
107
- case 5:
103
+ this.confirmationTransaction = undefined;
104
+ case 7:
108
105
  case "end":
109
106
  return _context.stop();
110
107
  }
@@ -115,5 +112,13 @@ var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/functio
115
112
  }
116
113
  return deleteSyncBlocksWithConfirmation;
117
114
  }()
115
+ }, {
116
+ key: "rebaseTransaction",
117
+ value: function rebaseTransaction(incomingTr, state) {
118
+ if (!this.confirmationTransaction) {
119
+ return;
120
+ }
121
+ this.confirmationTransaction = (0, _rebaseTransaction2.rebaseTransaction)(this.confirmationTransaction, incomingTr, state);
122
+ }
118
123
  }]);
119
124
  }();
package/dist/cjs/index.js CHANGED
@@ -57,12 +57,24 @@ Object.defineProperty(exports, "inMemoryWriteProvider", {
57
57
  return _inMemory.inMemoryWriteProvider;
58
58
  }
59
59
  });
60
+ Object.defineProperty(exports, "rebaseTransaction", {
61
+ enumerable: true,
62
+ get: function get() {
63
+ return _rebaseTransaction.rebaseTransaction;
64
+ }
65
+ });
60
66
  Object.defineProperty(exports, "useFetchDocNode", {
61
67
  enumerable: true,
62
68
  get: function get() {
63
69
  return _syncBlockProvider.useFetchDocNode;
64
70
  }
65
71
  });
72
+ Object.defineProperty(exports, "useHandleContentChanges", {
73
+ enumerable: true,
74
+ get: function get() {
75
+ return _syncBlockProvider.useHandleContentChanges;
76
+ }
77
+ });
66
78
  Object.defineProperty(exports, "useMemoizedContentAPIProviders", {
67
79
  enumerable: true,
68
80
  get: function get() {
@@ -81,4 +93,5 @@ var _inMemory = require("./providers/inMemory");
81
93
  var _schema = require("./common/schema");
82
94
  var _confluenceContentAPI = require("./providers/confluenceContentAPI");
83
95
  var _ari = require("./utils/ari");
84
- var _utils = require("./utils/utils");
96
+ var _utils = require("./utils/utils");
97
+ var _rebaseTransaction = require("./common/rebase-transaction");
@@ -47,11 +47,11 @@ var ConfluenceADFFetchProvider = /*#__PURE__*/function () {
47
47
  key: "fetchData",
48
48
  value: function () {
49
49
  var _fetchData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(resourceId) {
50
- var _contentProperty$data, pageId, localId, key, options, contentProperty, value, syncedBlockData;
50
+ var _contentProperty$data;
51
+ var pageId, localId, key, options, contentProperty, value, syncedBlockData;
51
52
  return _regenerator.default.wrap(function _callee$(_context) {
52
53
  while (1) switch (_context.prev = _context.next) {
53
54
  case 0:
54
- _context.prev = 0;
55
55
  pageId = (0, _ari.getPageIdFromAri)(resourceId);
56
56
  localId = (0, _ari.getLocalIdFromAri)(resourceId);
57
57
  key = getContentPropertyKey(this.config.contentPropertyKey, localId);
@@ -60,35 +60,29 @@ var ConfluenceADFFetchProvider = /*#__PURE__*/function () {
60
60
  key: key,
61
61
  cloudId: this.config.cloudId
62
62
  };
63
- _context.next = 7;
63
+ _context.next = 6;
64
64
  return (0, _contentProperty.getContentProperty)(options);
65
- case 7:
65
+ case 6:
66
66
  contentProperty = _context.sent;
67
67
  value = (_contentProperty$data = contentProperty.data.confluence.page.properties) === null || _contentProperty$data === void 0 || (_contentProperty$data = _contentProperty$data[0]) === null || _contentProperty$data === void 0 ? void 0 : _contentProperty$data.value;
68
68
  if (value) {
69
- _context.next = 11;
69
+ _context.next = 10;
70
70
  break;
71
71
  }
72
72
  throw new Error('Content property value does not exist');
73
- case 11:
73
+ case 10:
74
74
  // Parse the synced block content from the property value
75
75
  syncedBlockData = parseSyncedBlockContentPropertyValue(value);
76
76
  return _context.abrupt("return", {
77
- content: syncedBlockData.content
78
- });
79
- case 15:
80
- _context.prev = 15;
81
- _context.t0 = _context["catch"](0);
82
- // eslint-disable-next-line no-console
83
- console.error('Failed to fetch synced block data:', _context.t0);
84
- return _context.abrupt("return", {
85
- content: undefined
77
+ content: syncedBlockData.content,
78
+ resourceId: resourceId,
79
+ localId: localId
86
80
  });
87
- case 19:
81
+ case 12:
88
82
  case "end":
89
83
  return _context.stop();
90
84
  }
91
- }, _callee, this, [[0, 15]]);
85
+ }, _callee, this);
92
86
  }));
93
87
  function fetchData(_x) {
94
88
  return _fetchData.apply(this, arguments);
@@ -142,68 +136,58 @@ var ConfluenceADFWriteProvider = /*#__PURE__*/function () {
142
136
  return (0, _createClass2.default)(ConfluenceADFWriteProvider, [{
143
137
  key: "writeData",
144
138
  value: function () {
145
- var _writeData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(sourceId, localId, data, resourceId) {
146
- var pageId, syncedBlockValue, _contentProperty$data3, _localId, key, contentProperty, _key;
139
+ var _writeData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(data) {
140
+ var pageId, syncedBlockValue, _contentProperty$data3, localId, key, contentProperty, _key;
147
141
  return _regenerator.default.wrap(function _callee3$(_context3) {
148
142
  while (1) switch (_context3.prev = _context3.next) {
149
143
  case 0:
150
- _context3.prev = 0;
151
- pageId = (0, _ari.getPageIdFromAri)(sourceId);
144
+ pageId = (0, _ari.getPageIdFromAri)(data.resourceId);
152
145
  syncedBlockValue = JSON.stringify({
153
- content: data
146
+ content: data.content
154
147
  });
155
- if (!resourceId) {
156
- _context3.next = 20;
148
+ if (!data.resourceId) {
149
+ _context3.next = 19;
157
150
  break;
158
151
  }
159
152
  // Update existing content property
160
- _localId = (0, _ari.getLocalIdFromAri)(resourceId);
161
- key = getContentPropertyKey(this.config.contentPropertyKey, _localId);
162
- _context3.next = 8;
153
+ localId = (0, _ari.getLocalIdFromAri)(data.resourceId);
154
+ key = getContentPropertyKey(this.config.contentPropertyKey, localId);
155
+ _context3.next = 7;
163
156
  return (0, _contentProperty.updateContentProperty)({
164
157
  pageId: pageId,
165
158
  key: key,
166
159
  value: syncedBlockValue,
167
160
  cloudId: this.config.cloudId
168
161
  });
169
- case 8:
162
+ case 7:
170
163
  contentProperty = _context3.sent;
171
164
  if (!(((_contentProperty$data3 = contentProperty.data.confluence.updateValuePageProperty.pageProperty) === null || _contentProperty$data3 === void 0 ? void 0 : _contentProperty$data3.key) === key)) {
172
- _context3.next = 13;
165
+ _context3.next = 12;
173
166
  break;
174
167
  }
175
168
  return _context3.abrupt("return", key);
176
- case 13:
169
+ case 12:
177
170
  if (!(contentProperty.data.confluence.updateValuePageProperty.pageProperty === null)) {
178
- _context3.next = 17;
171
+ _context3.next = 16;
179
172
  break;
180
173
  }
181
174
  return _context3.abrupt("return", this.createNewContentProperty(pageId, key, syncedBlockValue));
182
- case 17:
175
+ case 16:
183
176
  throw new Error('Failed to update content property');
184
- case 18:
185
- _context3.next = 22;
177
+ case 17:
178
+ _context3.next = 21;
186
179
  break;
187
- case 20:
180
+ case 19:
188
181
  // Create new content property
189
- _key = getContentPropertyKey(this.config.contentPropertyKey, localId);
182
+ _key = getContentPropertyKey(this.config.contentPropertyKey, data.localId);
190
183
  return _context3.abrupt("return", this.createNewContentProperty(pageId, _key, syncedBlockValue));
191
- case 22:
192
- _context3.next = 28;
193
- break;
194
- case 24:
195
- _context3.prev = 24;
196
- _context3.t0 = _context3["catch"](0);
197
- // eslint-disable-next-line no-console
198
- console.error('Failed to write synced block data:', _context3.t0);
199
- return _context3.abrupt("return", Promise.reject(_context3.t0));
200
- case 28:
184
+ case 21:
201
185
  case "end":
202
186
  return _context3.stop();
203
187
  }
204
- }, _callee3, this, [[0, 24]]);
188
+ }, _callee3, this);
205
189
  }));
206
- function writeData(_x5, _x6, _x7, _x8) {
190
+ function writeData(_x5) {
207
191
  return _writeData.apply(this, arguments);
208
192
  }
209
193
  return writeData;
@@ -7,16 +7,18 @@ exports.inMemoryWriteProvider = exports.inMemoryFetchProvider = void 0;
7
7
  var inMemStore = new Map();
8
8
  var inMemoryFetchProvider = exports.inMemoryFetchProvider = {
9
9
  fetchData: function fetchData(resourceId) {
10
- return Promise.resolve({
11
- content: inMemStore.get(resourceId)
12
- });
10
+ var data = inMemStore.get(resourceId);
11
+ if (!data) {
12
+ return Promise.reject(new Error('Data not found'));
13
+ }
14
+ return Promise.resolve(data);
13
15
  }
14
16
  };
15
17
  var inMemoryWriteProvider = exports.inMemoryWriteProvider = {
16
- writeData: function writeData(_sourceId, _localId, data, resourceId) {
17
- if (resourceId) {
18
- inMemStore.set(resourceId, data);
19
- return Promise.resolve(resourceId);
18
+ writeData: function writeData(data) {
19
+ if (data.resourceId) {
20
+ inMemStore.set(data.resourceId, data);
21
+ return Promise.resolve(data.resourceId);
20
22
  } else {
21
23
  var uuid = crypto.randomUUID();
22
24
  inMemStore.set(uuid, data);
@@ -0,0 +1,26 @@
1
+ import { Mapping } from '@atlaskit/editor-prosemirror/transform';
2
+
3
+ /**
4
+ * Rebase `currentTr` over `incomingTr` based on the provided `state`.
5
+ * This function adjusts the steps in `currentTr` to account for the changes made by `incomingTr`.
6
+ *
7
+ * @param currentTr - The transaction to be rebased.
8
+ * @param incomingTr - The transaction that has already been applied to the state.
9
+ * @param state - The editor state after applying `incomingTr`.
10
+ * @returns A new transaction that represents `currentTr` rebased over `incomingTr`.
11
+ */
12
+ export const rebaseTransaction = (currentTr, incomingTr, state) => {
13
+ if (!incomingTr.docChanged) {
14
+ return currentTr;
15
+ }
16
+ const currentMapping = new Mapping(incomingTr.mapping.maps);
17
+ const rebasedTransaction = state.tr;
18
+ currentTr.steps.forEach(step => {
19
+ const mappedStep = step.map(currentMapping);
20
+ if (mappedStep) {
21
+ rebasedTransaction.step(mappedStep);
22
+ currentMapping.appendMap(mappedStep.getMap());
23
+ }
24
+ });
25
+ return rebasedTransaction;
26
+ };
@@ -27,7 +27,7 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
27
27
  resourceIds.push(Promise.reject('No Synced Blockcontent to write'));
28
28
  return;
29
29
  }
30
- const resourceId = this.writeProvider.writeData(this.sourceId, node.attrs.localId, data[index].content, node.attrs.resourceId);
30
+ const resourceId = this.writeProvider.writeData(data[index]);
31
31
  resourceIds.push(resourceId);
32
32
  });
33
33
  return Promise.all(resourceIds);
@@ -73,4 +73,21 @@ export const useMemoizedSyncedBlockProvider = (fetchProvider, writeProvider, sou
73
73
  return useMemo(() => {
74
74
  return new SyncBlockProvider(fetchProvider, writeProvider, sourceId);
75
75
  }, [fetchProvider, writeProvider, sourceId]);
76
+ };
77
+ export const useHandleContentChanges = (updatedDoc, isSource, node, provider) => {
78
+ useEffect(() => {
79
+ if (!isSource) {
80
+ return;
81
+ }
82
+ if (!provider) {
83
+ return;
84
+ }
85
+ const syncBlockNode = convertSyncBlockPMNodeToSyncBlockData(node, false);
86
+ const data = {
87
+ content: updatedDoc.toJSON(),
88
+ resourceId: node.attrs.resourceId,
89
+ localId: node.attrs.localId
90
+ };
91
+ provider === null || provider === void 0 ? void 0 : provider.writeNodesData([syncBlockNode], [data]);
92
+ }, [isSource, node, provider, updatedDoc]);
76
93
  };
@@ -1,4 +1,5 @@
1
1
  import uuid from 'uuid';
2
+ import { rebaseTransaction } from './rebase-transaction';
2
3
 
3
4
  // Do this typedef to make it clear that
4
5
  // this is a local identifier for a resource for local use
@@ -37,11 +38,6 @@ export class SyncBlockStoreManager {
37
38
  }
38
39
  createSyncBlockNode() {
39
40
  var _this$dataProvider;
40
- // TODO: EDITOR-1644 - properly implement creation of the synced block
41
- // below is a temporary implementation for the creation of the synced block
42
- // the resource id needs to have pageId and content property key in it
43
- // Note: If the data provider is not set, the resource id will be the local id
44
-
45
41
  const localId = uuid();
46
42
  const sourceId = (_this$dataProvider = this.dataProvider) === null || _this$dataProvider === void 0 ? void 0 : _this$dataProvider.getSourceId();
47
43
  const resourceId = sourceId ? `${sourceId}/${localId}` : localId;
@@ -60,16 +56,23 @@ export class SyncBlockStoreManager {
60
56
  }
61
57
  async deleteSyncBlocksWithConfirmation(tr, syncBlockIds) {
62
58
  if (this.confirmationCallback) {
59
+ this.confirmationTransaction = tr;
63
60
  const confirmed = await this.confirmationCallback();
64
61
  if (confirmed) {
65
62
  var _this$editorView;
66
- // TODO: EDITOR-1779 - "rebase" the transaction to reflect the latest document state
67
- (_this$editorView = this.editorView) === null || _this$editorView === void 0 ? void 0 : _this$editorView.dispatch(tr.setMeta('isConfirmedSyncBlockDeletion', true));
63
+ (_this$editorView = this.editorView) === null || _this$editorView === void 0 ? void 0 : _this$editorView.dispatch(this.confirmationTransaction.setMeta('isConfirmedSyncBlockDeletion', true));
68
64
  // Need to update the BE on deletion
69
65
  syncBlockIds.forEach(({
70
66
  resourceId
71
67
  }) => this.syncBlocks.delete(resourceId));
72
68
  }
69
+ this.confirmationTransaction = undefined;
70
+ }
71
+ }
72
+ rebaseTransaction(incomingTr, state) {
73
+ if (!this.confirmationTransaction) {
74
+ return;
73
75
  }
76
+ this.confirmationTransaction = rebaseTransaction(this.confirmationTransaction, incomingTr, state);
74
77
  }
75
78
  }
@@ -1,9 +1,10 @@
1
1
  /* eslint-disable @atlaskit/editor/no-re-export */
2
2
 
3
- export { SyncBlockProvider as SyncedBlockProvider, useFetchDocNode, useMemoizedSyncedBlockProvider } from './common/syncBlockProvider';
3
+ export { SyncBlockProvider as SyncedBlockProvider, useFetchDocNode, useHandleContentChanges, useMemoizedSyncedBlockProvider } from './common/syncBlockProvider';
4
4
  export { SyncBlockStoreManager } from './common/syncBlockStoreManager';
5
5
  export { inMemoryFetchProvider, inMemoryWriteProvider } from './providers/inMemory';
6
6
  export { getDefaultSyncBlockSchema } from './common/schema';
7
7
  export { createContentAPIProvidersWithDefaultKey, useMemoizedContentAPIProviders } from './providers/confluenceContentAPI';
8
8
  export { getConfluencePageAri } from './utils/ari';
9
- export { convertSyncBlockPMNodeToSyncBlockData, generateSyncBlockSourceUrl } from './utils/utils';
9
+ export { convertSyncBlockPMNodeToSyncBlockData, generateSyncBlockSourceUrl } from './utils/utils';
10
+ export { rebaseTransaction } from './common/rebase-transaction';
@@ -33,34 +33,28 @@ class ConfluenceADFFetchProvider {
33
33
  this.config = config;
34
34
  }
35
35
  async fetchData(resourceId) {
36
- try {
37
- var _contentProperty$data, _contentProperty$data2;
38
- const pageId = getPageIdFromAri(resourceId);
39
- const localId = getLocalIdFromAri(resourceId);
40
- const key = getContentPropertyKey(this.config.contentPropertyKey, localId);
41
- const options = {
42
- pageId,
43
- key,
44
- cloudId: this.config.cloudId
45
- };
46
- const contentProperty = await getContentProperty(options);
47
- const value = (_contentProperty$data = contentProperty.data.confluence.page.properties) === null || _contentProperty$data === void 0 ? void 0 : (_contentProperty$data2 = _contentProperty$data[0]) === null || _contentProperty$data2 === void 0 ? void 0 : _contentProperty$data2.value;
48
- if (!value) {
49
- throw new Error('Content property value does not exist');
50
- }
51
-
52
- // Parse the synced block content from the property value
53
- const syncedBlockData = parseSyncedBlockContentPropertyValue(value);
54
- return {
55
- content: syncedBlockData.content
56
- };
57
- } catch (error) {
58
- // eslint-disable-next-line no-console
59
- console.error('Failed to fetch synced block data:', error);
60
- return {
61
- content: undefined
62
- };
36
+ var _contentProperty$data, _contentProperty$data2;
37
+ const pageId = getPageIdFromAri(resourceId);
38
+ const localId = getLocalIdFromAri(resourceId);
39
+ const key = getContentPropertyKey(this.config.contentPropertyKey, localId);
40
+ const options = {
41
+ pageId,
42
+ key,
43
+ cloudId: this.config.cloudId
44
+ };
45
+ const contentProperty = await getContentProperty(options);
46
+ const value = (_contentProperty$data = contentProperty.data.confluence.page.properties) === null || _contentProperty$data === void 0 ? void 0 : (_contentProperty$data2 = _contentProperty$data[0]) === null || _contentProperty$data2 === void 0 ? void 0 : _contentProperty$data2.value;
47
+ if (!value) {
48
+ throw new Error('Content property value does not exist');
63
49
  }
50
+
51
+ // Parse the synced block content from the property value
52
+ const syncedBlockData = parseSyncedBlockContentPropertyValue(value);
53
+ return {
54
+ content: syncedBlockData.content,
55
+ resourceId,
56
+ localId
57
+ };
64
58
  }
65
59
  }
66
60
 
@@ -85,39 +79,33 @@ class ConfluenceADFWriteProvider {
85
79
  });
86
80
  this.config = config;
87
81
  }
88
- async writeData(sourceId, localId, data, resourceId) {
89
- try {
90
- const pageId = getPageIdFromAri(sourceId);
91
- const syncedBlockValue = JSON.stringify({
92
- content: data
82
+ async writeData(data) {
83
+ const pageId = getPageIdFromAri(data.resourceId);
84
+ const syncedBlockValue = JSON.stringify({
85
+ content: data.content
86
+ });
87
+ if (data.resourceId) {
88
+ var _contentProperty$data4;
89
+ // Update existing content property
90
+ const localId = getLocalIdFromAri(data.resourceId);
91
+ const key = getContentPropertyKey(this.config.contentPropertyKey, localId);
92
+ const contentProperty = await updateContentProperty({
93
+ pageId,
94
+ key,
95
+ value: syncedBlockValue,
96
+ cloudId: this.config.cloudId
93
97
  });
94
- if (resourceId) {
95
- var _contentProperty$data4;
96
- // Update existing content property
97
- const localId = getLocalIdFromAri(resourceId);
98
- const key = getContentPropertyKey(this.config.contentPropertyKey, localId);
99
- const contentProperty = await updateContentProperty({
100
- pageId,
101
- key,
102
- value: syncedBlockValue,
103
- cloudId: this.config.cloudId
104
- });
105
- if (((_contentProperty$data4 = contentProperty.data.confluence.updateValuePageProperty.pageProperty) === null || _contentProperty$data4 === void 0 ? void 0 : _contentProperty$data4.key) === key) {
106
- return key;
107
- } else if (contentProperty.data.confluence.updateValuePageProperty.pageProperty === null) {
108
- return this.createNewContentProperty(pageId, key, syncedBlockValue);
109
- } else {
110
- throw new Error('Failed to update content property');
111
- }
112
- } else {
113
- // Create new content property
114
- const key = getContentPropertyKey(this.config.contentPropertyKey, localId);
98
+ if (((_contentProperty$data4 = contentProperty.data.confluence.updateValuePageProperty.pageProperty) === null || _contentProperty$data4 === void 0 ? void 0 : _contentProperty$data4.key) === key) {
99
+ return key;
100
+ } else if (contentProperty.data.confluence.updateValuePageProperty.pageProperty === null) {
115
101
  return this.createNewContentProperty(pageId, key, syncedBlockValue);
102
+ } else {
103
+ throw new Error('Failed to update content property');
116
104
  }
117
- } catch (error) {
118
- // eslint-disable-next-line no-console
119
- console.error('Failed to write synced block data:', error);
120
- return Promise.reject(error);
105
+ } else {
106
+ // Create new content property
107
+ const key = getContentPropertyKey(this.config.contentPropertyKey, data.localId);
108
+ return this.createNewContentProperty(pageId, key, syncedBlockValue);
121
109
  }
122
110
  }
123
111
  }
@@ -1,16 +1,18 @@
1
1
  const inMemStore = new Map();
2
2
  export const inMemoryFetchProvider = {
3
3
  fetchData: resourceId => {
4
- return Promise.resolve({
5
- content: inMemStore.get(resourceId)
6
- });
4
+ const data = inMemStore.get(resourceId);
5
+ if (!data) {
6
+ return Promise.reject(new Error('Data not found'));
7
+ }
8
+ return Promise.resolve(data);
7
9
  }
8
10
  };
9
11
  export const inMemoryWriteProvider = {
10
- writeData: (_sourceId, _localId, data, resourceId) => {
11
- if (resourceId) {
12
- inMemStore.set(resourceId, data);
13
- return Promise.resolve(resourceId);
12
+ writeData: data => {
13
+ if (data.resourceId) {
14
+ inMemStore.set(data.resourceId, data);
15
+ return Promise.resolve(data.resourceId);
14
16
  } else {
15
17
  const uuid = crypto.randomUUID();
16
18
  inMemStore.set(uuid, data);
@@ -0,0 +1,26 @@
1
+ import { Mapping } from '@atlaskit/editor-prosemirror/transform';
2
+
3
+ /**
4
+ * Rebase `currentTr` over `incomingTr` based on the provided `state`.
5
+ * This function adjusts the steps in `currentTr` to account for the changes made by `incomingTr`.
6
+ *
7
+ * @param currentTr - The transaction to be rebased.
8
+ * @param incomingTr - The transaction that has already been applied to the state.
9
+ * @param state - The editor state after applying `incomingTr`.
10
+ * @returns A new transaction that represents `currentTr` rebased over `incomingTr`.
11
+ */
12
+ export var rebaseTransaction = function rebaseTransaction(currentTr, incomingTr, state) {
13
+ if (!incomingTr.docChanged) {
14
+ return currentTr;
15
+ }
16
+ var currentMapping = new Mapping(incomingTr.mapping.maps);
17
+ var rebasedTransaction = state.tr;
18
+ currentTr.steps.forEach(function (step) {
19
+ var mappedStep = step.map(currentMapping);
20
+ if (mappedStep) {
21
+ rebasedTransaction.step(mappedStep);
22
+ currentMapping.appendMap(mappedStep.getMap());
23
+ }
24
+ });
25
+ return rebasedTransaction;
26
+ };
@@ -43,7 +43,7 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
43
43
  resourceIds.push(Promise.reject('No Synced Blockcontent to write'));
44
44
  return;
45
45
  }
46
- var resourceId = _this.writeProvider.writeData(_this.sourceId, node.attrs.localId, data[index].content, node.attrs.resourceId);
46
+ var resourceId = _this.writeProvider.writeData(data[index]);
47
47
  resourceIds.push(resourceId);
48
48
  });
49
49
  return Promise.all(resourceIds);
@@ -94,4 +94,21 @@ export var useMemoizedSyncedBlockProvider = function useMemoizedSyncedBlockProvi
94
94
  return useMemo(function () {
95
95
  return new SyncBlockProvider(fetchProvider, writeProvider, sourceId);
96
96
  }, [fetchProvider, writeProvider, sourceId]);
97
+ };
98
+ export var useHandleContentChanges = function useHandleContentChanges(updatedDoc, isSource, node, provider) {
99
+ useEffect(function () {
100
+ if (!isSource) {
101
+ return;
102
+ }
103
+ if (!provider) {
104
+ return;
105
+ }
106
+ var syncBlockNode = convertSyncBlockPMNodeToSyncBlockData(node, false);
107
+ var data = {
108
+ content: updatedDoc.toJSON(),
109
+ resourceId: node.attrs.resourceId,
110
+ localId: node.attrs.localId
111
+ };
112
+ provider === null || provider === void 0 || provider.writeNodesData([syncBlockNode], [data]);
113
+ }, [isSource, node, provider, updatedDoc]);
97
114
  };
@@ -3,6 +3,7 @@ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
3
  import _createClass from "@babel/runtime/helpers/createClass";
4
4
  import _regeneratorRuntime from "@babel/runtime/regenerator";
5
5
  import uuid from 'uuid';
6
+ import { rebaseTransaction as _rebaseTransaction } from './rebase-transaction';
6
7
 
7
8
  // Do this typedef to make it clear that
8
9
  // this is a local identifier for a resource for local use
@@ -52,11 +53,6 @@ export var SyncBlockStoreManager = /*#__PURE__*/function () {
52
53
  key: "createSyncBlockNode",
53
54
  value: function createSyncBlockNode() {
54
55
  var _this$dataProvider;
55
- // TODO: EDITOR-1644 - properly implement creation of the synced block
56
- // below is a temporary implementation for the creation of the synced block
57
- // the resource id needs to have pageId and content property key in it
58
- // Note: If the data provider is not set, the resource id will be the local id
59
-
60
56
  var localId = uuid();
61
57
  var sourceId = (_this$dataProvider = this.dataProvider) === null || _this$dataProvider === void 0 ? void 0 : _this$dataProvider.getSourceId();
62
58
  var resourceId = sourceId ? "".concat(sourceId, "/").concat(localId) : localId;
@@ -83,23 +79,24 @@ export var SyncBlockStoreManager = /*#__PURE__*/function () {
83
79
  while (1) switch (_context.prev = _context.next) {
84
80
  case 0:
85
81
  if (!this.confirmationCallback) {
86
- _context.next = 5;
82
+ _context.next = 7;
87
83
  break;
88
84
  }
89
- _context.next = 3;
85
+ this.confirmationTransaction = tr;
86
+ _context.next = 4;
90
87
  return this.confirmationCallback();
91
- case 3:
88
+ case 4:
92
89
  confirmed = _context.sent;
93
90
  if (confirmed) {
94
- // TODO: EDITOR-1779 - "rebase" the transaction to reflect the latest document state
95
- (_this$editorView = this.editorView) === null || _this$editorView === void 0 || _this$editorView.dispatch(tr.setMeta('isConfirmedSyncBlockDeletion', true));
91
+ (_this$editorView = this.editorView) === null || _this$editorView === void 0 || _this$editorView.dispatch(this.confirmationTransaction.setMeta('isConfirmedSyncBlockDeletion', true));
96
92
  // Need to update the BE on deletion
97
93
  syncBlockIds.forEach(function (_ref) {
98
94
  var resourceId = _ref.resourceId;
99
95
  return _this2.syncBlocks.delete(resourceId);
100
96
  });
101
97
  }
102
- case 5:
98
+ this.confirmationTransaction = undefined;
99
+ case 7:
103
100
  case "end":
104
101
  return _context.stop();
105
102
  }
@@ -110,5 +107,13 @@ export var SyncBlockStoreManager = /*#__PURE__*/function () {
110
107
  }
111
108
  return deleteSyncBlocksWithConfirmation;
112
109
  }()
110
+ }, {
111
+ key: "rebaseTransaction",
112
+ value: function rebaseTransaction(incomingTr, state) {
113
+ if (!this.confirmationTransaction) {
114
+ return;
115
+ }
116
+ this.confirmationTransaction = _rebaseTransaction(this.confirmationTransaction, incomingTr, state);
117
+ }
113
118
  }]);
114
119
  }();
package/dist/esm/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  /* eslint-disable @atlaskit/editor/no-re-export */
2
2
 
3
- export { SyncBlockProvider as SyncedBlockProvider, useFetchDocNode, useMemoizedSyncedBlockProvider } from './common/syncBlockProvider';
3
+ export { SyncBlockProvider as SyncedBlockProvider, useFetchDocNode, useHandleContentChanges, useMemoizedSyncedBlockProvider } from './common/syncBlockProvider';
4
4
  export { SyncBlockStoreManager } from './common/syncBlockStoreManager';
5
5
  export { inMemoryFetchProvider, inMemoryWriteProvider } from './providers/inMemory';
6
6
  export { getDefaultSyncBlockSchema } from './common/schema';
7
7
  export { createContentAPIProvidersWithDefaultKey, useMemoizedContentAPIProviders } from './providers/confluenceContentAPI';
8
8
  export { getConfluencePageAri } from './utils/ari';
9
- export { convertSyncBlockPMNodeToSyncBlockData, generateSyncBlockSourceUrl } from './utils/utils';
9
+ export { convertSyncBlockPMNodeToSyncBlockData, generateSyncBlockSourceUrl } from './utils/utils';
10
+ export { rebaseTransaction } from './common/rebase-transaction';
@@ -41,11 +41,11 @@ var ConfluenceADFFetchProvider = /*#__PURE__*/function () {
41
41
  key: "fetchData",
42
42
  value: function () {
43
43
  var _fetchData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(resourceId) {
44
- var _contentProperty$data, pageId, localId, key, options, contentProperty, value, syncedBlockData;
44
+ var _contentProperty$data;
45
+ var pageId, localId, key, options, contentProperty, value, syncedBlockData;
45
46
  return _regeneratorRuntime.wrap(function _callee$(_context) {
46
47
  while (1) switch (_context.prev = _context.next) {
47
48
  case 0:
48
- _context.prev = 0;
49
49
  pageId = getPageIdFromAri(resourceId);
50
50
  localId = getLocalIdFromAri(resourceId);
51
51
  key = getContentPropertyKey(this.config.contentPropertyKey, localId);
@@ -54,35 +54,29 @@ var ConfluenceADFFetchProvider = /*#__PURE__*/function () {
54
54
  key: key,
55
55
  cloudId: this.config.cloudId
56
56
  };
57
- _context.next = 7;
57
+ _context.next = 6;
58
58
  return getContentProperty(options);
59
- case 7:
59
+ case 6:
60
60
  contentProperty = _context.sent;
61
61
  value = (_contentProperty$data = contentProperty.data.confluence.page.properties) === null || _contentProperty$data === void 0 || (_contentProperty$data = _contentProperty$data[0]) === null || _contentProperty$data === void 0 ? void 0 : _contentProperty$data.value;
62
62
  if (value) {
63
- _context.next = 11;
63
+ _context.next = 10;
64
64
  break;
65
65
  }
66
66
  throw new Error('Content property value does not exist');
67
- case 11:
67
+ case 10:
68
68
  // Parse the synced block content from the property value
69
69
  syncedBlockData = parseSyncedBlockContentPropertyValue(value);
70
70
  return _context.abrupt("return", {
71
- content: syncedBlockData.content
72
- });
73
- case 15:
74
- _context.prev = 15;
75
- _context.t0 = _context["catch"](0);
76
- // eslint-disable-next-line no-console
77
- console.error('Failed to fetch synced block data:', _context.t0);
78
- return _context.abrupt("return", {
79
- content: undefined
71
+ content: syncedBlockData.content,
72
+ resourceId: resourceId,
73
+ localId: localId
80
74
  });
81
- case 19:
75
+ case 12:
82
76
  case "end":
83
77
  return _context.stop();
84
78
  }
85
- }, _callee, this, [[0, 15]]);
79
+ }, _callee, this);
86
80
  }));
87
81
  function fetchData(_x) {
88
82
  return _fetchData.apply(this, arguments);
@@ -136,68 +130,58 @@ var ConfluenceADFWriteProvider = /*#__PURE__*/function () {
136
130
  return _createClass(ConfluenceADFWriteProvider, [{
137
131
  key: "writeData",
138
132
  value: function () {
139
- var _writeData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(sourceId, localId, data, resourceId) {
140
- var pageId, syncedBlockValue, _contentProperty$data3, _localId, key, contentProperty, _key;
133
+ var _writeData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(data) {
134
+ var pageId, syncedBlockValue, _contentProperty$data3, localId, key, contentProperty, _key;
141
135
  return _regeneratorRuntime.wrap(function _callee3$(_context3) {
142
136
  while (1) switch (_context3.prev = _context3.next) {
143
137
  case 0:
144
- _context3.prev = 0;
145
- pageId = getPageIdFromAri(sourceId);
138
+ pageId = getPageIdFromAri(data.resourceId);
146
139
  syncedBlockValue = JSON.stringify({
147
- content: data
140
+ content: data.content
148
141
  });
149
- if (!resourceId) {
150
- _context3.next = 20;
142
+ if (!data.resourceId) {
143
+ _context3.next = 19;
151
144
  break;
152
145
  }
153
146
  // Update existing content property
154
- _localId = getLocalIdFromAri(resourceId);
155
- key = getContentPropertyKey(this.config.contentPropertyKey, _localId);
156
- _context3.next = 8;
147
+ localId = getLocalIdFromAri(data.resourceId);
148
+ key = getContentPropertyKey(this.config.contentPropertyKey, localId);
149
+ _context3.next = 7;
157
150
  return updateContentProperty({
158
151
  pageId: pageId,
159
152
  key: key,
160
153
  value: syncedBlockValue,
161
154
  cloudId: this.config.cloudId
162
155
  });
163
- case 8:
156
+ case 7:
164
157
  contentProperty = _context3.sent;
165
158
  if (!(((_contentProperty$data3 = contentProperty.data.confluence.updateValuePageProperty.pageProperty) === null || _contentProperty$data3 === void 0 ? void 0 : _contentProperty$data3.key) === key)) {
166
- _context3.next = 13;
159
+ _context3.next = 12;
167
160
  break;
168
161
  }
169
162
  return _context3.abrupt("return", key);
170
- case 13:
163
+ case 12:
171
164
  if (!(contentProperty.data.confluence.updateValuePageProperty.pageProperty === null)) {
172
- _context3.next = 17;
165
+ _context3.next = 16;
173
166
  break;
174
167
  }
175
168
  return _context3.abrupt("return", this.createNewContentProperty(pageId, key, syncedBlockValue));
176
- case 17:
169
+ case 16:
177
170
  throw new Error('Failed to update content property');
178
- case 18:
179
- _context3.next = 22;
171
+ case 17:
172
+ _context3.next = 21;
180
173
  break;
181
- case 20:
174
+ case 19:
182
175
  // Create new content property
183
- _key = getContentPropertyKey(this.config.contentPropertyKey, localId);
176
+ _key = getContentPropertyKey(this.config.contentPropertyKey, data.localId);
184
177
  return _context3.abrupt("return", this.createNewContentProperty(pageId, _key, syncedBlockValue));
185
- case 22:
186
- _context3.next = 28;
187
- break;
188
- case 24:
189
- _context3.prev = 24;
190
- _context3.t0 = _context3["catch"](0);
191
- // eslint-disable-next-line no-console
192
- console.error('Failed to write synced block data:', _context3.t0);
193
- return _context3.abrupt("return", Promise.reject(_context3.t0));
194
- case 28:
178
+ case 21:
195
179
  case "end":
196
180
  return _context3.stop();
197
181
  }
198
- }, _callee3, this, [[0, 24]]);
182
+ }, _callee3, this);
199
183
  }));
200
- function writeData(_x5, _x6, _x7, _x8) {
184
+ function writeData(_x5) {
201
185
  return _writeData.apply(this, arguments);
202
186
  }
203
187
  return writeData;
@@ -1,16 +1,18 @@
1
1
  var inMemStore = new Map();
2
2
  export var inMemoryFetchProvider = {
3
3
  fetchData: function fetchData(resourceId) {
4
- return Promise.resolve({
5
- content: inMemStore.get(resourceId)
6
- });
4
+ var data = inMemStore.get(resourceId);
5
+ if (!data) {
6
+ return Promise.reject(new Error('Data not found'));
7
+ }
8
+ return Promise.resolve(data);
7
9
  }
8
10
  };
9
11
  export var inMemoryWriteProvider = {
10
- writeData: function writeData(_sourceId, _localId, data, resourceId) {
11
- if (resourceId) {
12
- inMemStore.set(resourceId, data);
13
- return Promise.resolve(resourceId);
12
+ writeData: function writeData(data) {
13
+ if (data.resourceId) {
14
+ inMemStore.set(data.resourceId, data);
15
+ return Promise.resolve(data.resourceId);
14
16
  } else {
15
17
  var uuid = crypto.randomUUID();
16
18
  inMemStore.set(uuid, data);
@@ -0,0 +1,11 @@
1
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
2
+ /**
3
+ * Rebase `currentTr` over `incomingTr` based on the provided `state`.
4
+ * This function adjusts the steps in `currentTr` to account for the changes made by `incomingTr`.
5
+ *
6
+ * @param currentTr - The transaction to be rebased.
7
+ * @param incomingTr - The transaction that has already been applied to the state.
8
+ * @param state - The editor state after applying `incomingTr`.
9
+ * @returns A new transaction that represents `currentTr` rebased over `incomingTr`.
10
+ */
11
+ export declare const rebaseTransaction: (currentTr: Transaction, incomingTr: Transaction, state: EditorState) => Transaction;
@@ -24,3 +24,4 @@ export declare class SyncBlockProvider extends SyncBlockDataProvider {
24
24
  }
25
25
  export declare const useFetchDocNode: (editorView: EditorView, node: PMNode, defaultDocNode: DocNode, provider?: SyncBlockDataProvider) => DocNode;
26
26
  export declare const useMemoizedSyncedBlockProvider: (fetchProvider: ADFFetchProvider, writeProvider: ADFWriteProvider, sourceId: string) => SyncBlockProvider;
27
+ export declare const useHandleContentChanges: (updatedDoc: PMNode, isSource: boolean, node: PMNode, provider?: SyncBlockDataProvider) => void;
@@ -1,6 +1,6 @@
1
1
  import type { ADFEntity } from '@atlaskit/adf-utils/types';
2
2
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
- import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
4
4
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
5
5
  import type { SyncBlockAttrs, SyncBlockDataProvider, SyncBlockNode } from './types';
6
6
  export interface SyncBlock {
@@ -18,6 +18,7 @@ export declare class SyncBlockStoreManager {
18
18
  private confirmationCallback?;
19
19
  private editorView?;
20
20
  private dataProvider?;
21
+ private confirmationTransaction?;
21
22
  constructor(dataProvider?: SyncBlockDataProvider);
22
23
  setEditorView(editorView: EditorView | undefined): void;
23
24
  isSourceBlock(node: PMNode): boolean;
@@ -25,5 +26,6 @@ export declare class SyncBlockStoreManager {
25
26
  requireConfirmationBeforeDelete(): boolean;
26
27
  createSyncBlockNode(): SyncBlockNode;
27
28
  deleteSyncBlocksWithConfirmation(tr: Transaction, syncBlockIds: SyncBlockAttrs[]): Promise<void>;
29
+ rebaseTransaction(incomingTr: Transaction, state: EditorState): void;
28
30
  }
29
31
  export {};
@@ -12,13 +12,20 @@ export type SyncBlockNode = {
12
12
  };
13
13
  export type SyncBlockData = {
14
14
  content: ADFEntity | undefined;
15
- resourceId?: string;
15
+ createdAt?: string;
16
+ createdBy?: string;
17
+ isSynced?: boolean;
18
+ localId: string;
19
+ resourceId: string;
20
+ sourceDocumentAri?: string;
21
+ status?: 'deleted' | 'active';
22
+ updatedAt?: string;
16
23
  };
17
24
  export interface ADFFetchProvider {
18
25
  fetchData: (resourceId: string) => Promise<SyncBlockData>;
19
26
  }
20
27
  export interface ADFWriteProvider {
21
- writeData: (sourceId: string, localId: string, data: ADFEntity, resourceId?: string) => Promise<string>;
28
+ writeData: (data: SyncBlockData) => Promise<string>;
22
29
  }
23
30
  export declare abstract class SyncBlockDataProvider extends NodeDataProvider<SyncBlockNode, SyncBlockData> {
24
31
  abstract writeNodesData: (nodes: SyncBlockNode[], data: SyncBlockData[]) => Promise<Array<string | undefined>>;
@@ -1,4 +1,4 @@
1
- export { SyncBlockProvider as SyncedBlockProvider, useFetchDocNode, useMemoizedSyncedBlockProvider, } from './common/syncBlockProvider';
1
+ export { SyncBlockProvider as SyncedBlockProvider, useFetchDocNode, useHandleContentChanges, useMemoizedSyncedBlockProvider, } from './common/syncBlockProvider';
2
2
  export { SyncBlockStoreManager } from './common/syncBlockStoreManager';
3
3
  export type { SyncBlockDataProvider, ADFFetchProvider, ADFWriteProvider, SyncBlockData, SyncBlockNode, } from './common/types';
4
4
  export { inMemoryFetchProvider, inMemoryWriteProvider } from './providers/inMemory';
@@ -6,3 +6,4 @@ export { getDefaultSyncBlockSchema } from './common/schema';
6
6
  export { createContentAPIProvidersWithDefaultKey, useMemoizedContentAPIProviders, } from './providers/confluenceContentAPI';
7
7
  export { getConfluencePageAri } from './utils/ari';
8
8
  export { convertSyncBlockPMNodeToSyncBlockData, generateSyncBlockSourceUrl } from './utils/utils';
9
+ export { rebaseTransaction } from './common/rebase-transaction';
@@ -25,7 +25,7 @@ declare class ConfluenceADFWriteProvider implements ADFWriteProvider {
25
25
  private config;
26
26
  constructor(config: ContentAPIConfig);
27
27
  private createNewContentProperty;
28
- writeData(sourceId: string, localId: string, data: ADFEntity, resourceId?: string): Promise<string>;
28
+ writeData(data: SyncBlockData): Promise<string>;
29
29
  }
30
30
  /**
31
31
  * Convenience function to create providers with default content property key
@@ -0,0 +1,11 @@
1
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
2
+ /**
3
+ * Rebase `currentTr` over `incomingTr` based on the provided `state`.
4
+ * This function adjusts the steps in `currentTr` to account for the changes made by `incomingTr`.
5
+ *
6
+ * @param currentTr - The transaction to be rebased.
7
+ * @param incomingTr - The transaction that has already been applied to the state.
8
+ * @param state - The editor state after applying `incomingTr`.
9
+ * @returns A new transaction that represents `currentTr` rebased over `incomingTr`.
10
+ */
11
+ export declare const rebaseTransaction: (currentTr: Transaction, incomingTr: Transaction, state: EditorState) => Transaction;
@@ -24,3 +24,4 @@ export declare class SyncBlockProvider extends SyncBlockDataProvider {
24
24
  }
25
25
  export declare const useFetchDocNode: (editorView: EditorView, node: PMNode, defaultDocNode: DocNode, provider?: SyncBlockDataProvider) => DocNode;
26
26
  export declare const useMemoizedSyncedBlockProvider: (fetchProvider: ADFFetchProvider, writeProvider: ADFWriteProvider, sourceId: string) => SyncBlockProvider;
27
+ export declare const useHandleContentChanges: (updatedDoc: PMNode, isSource: boolean, node: PMNode, provider?: SyncBlockDataProvider) => void;
@@ -1,6 +1,6 @@
1
1
  import type { ADFEntity } from '@atlaskit/adf-utils/types';
2
2
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
- import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
4
4
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
5
5
  import type { SyncBlockAttrs, SyncBlockDataProvider, SyncBlockNode } from './types';
6
6
  export interface SyncBlock {
@@ -18,6 +18,7 @@ export declare class SyncBlockStoreManager {
18
18
  private confirmationCallback?;
19
19
  private editorView?;
20
20
  private dataProvider?;
21
+ private confirmationTransaction?;
21
22
  constructor(dataProvider?: SyncBlockDataProvider);
22
23
  setEditorView(editorView: EditorView | undefined): void;
23
24
  isSourceBlock(node: PMNode): boolean;
@@ -25,5 +26,6 @@ export declare class SyncBlockStoreManager {
25
26
  requireConfirmationBeforeDelete(): boolean;
26
27
  createSyncBlockNode(): SyncBlockNode;
27
28
  deleteSyncBlocksWithConfirmation(tr: Transaction, syncBlockIds: SyncBlockAttrs[]): Promise<void>;
29
+ rebaseTransaction(incomingTr: Transaction, state: EditorState): void;
28
30
  }
29
31
  export {};
@@ -12,13 +12,20 @@ export type SyncBlockNode = {
12
12
  };
13
13
  export type SyncBlockData = {
14
14
  content: ADFEntity | undefined;
15
- resourceId?: string;
15
+ createdAt?: string;
16
+ createdBy?: string;
17
+ isSynced?: boolean;
18
+ localId: string;
19
+ resourceId: string;
20
+ sourceDocumentAri?: string;
21
+ status?: 'deleted' | 'active';
22
+ updatedAt?: string;
16
23
  };
17
24
  export interface ADFFetchProvider {
18
25
  fetchData: (resourceId: string) => Promise<SyncBlockData>;
19
26
  }
20
27
  export interface ADFWriteProvider {
21
- writeData: (sourceId: string, localId: string, data: ADFEntity, resourceId?: string) => Promise<string>;
28
+ writeData: (data: SyncBlockData) => Promise<string>;
22
29
  }
23
30
  export declare abstract class SyncBlockDataProvider extends NodeDataProvider<SyncBlockNode, SyncBlockData> {
24
31
  abstract writeNodesData: (nodes: SyncBlockNode[], data: SyncBlockData[]) => Promise<Array<string | undefined>>;
@@ -1,4 +1,4 @@
1
- export { SyncBlockProvider as SyncedBlockProvider, useFetchDocNode, useMemoizedSyncedBlockProvider, } from './common/syncBlockProvider';
1
+ export { SyncBlockProvider as SyncedBlockProvider, useFetchDocNode, useHandleContentChanges, useMemoizedSyncedBlockProvider, } from './common/syncBlockProvider';
2
2
  export { SyncBlockStoreManager } from './common/syncBlockStoreManager';
3
3
  export type { SyncBlockDataProvider, ADFFetchProvider, ADFWriteProvider, SyncBlockData, SyncBlockNode, } from './common/types';
4
4
  export { inMemoryFetchProvider, inMemoryWriteProvider } from './providers/inMemory';
@@ -6,3 +6,4 @@ export { getDefaultSyncBlockSchema } from './common/schema';
6
6
  export { createContentAPIProvidersWithDefaultKey, useMemoizedContentAPIProviders, } from './providers/confluenceContentAPI';
7
7
  export { getConfluencePageAri } from './utils/ari';
8
8
  export { convertSyncBlockPMNodeToSyncBlockData, generateSyncBlockSourceUrl } from './utils/utils';
9
+ export { rebaseTransaction } from './common/rebase-transaction';
@@ -25,7 +25,7 @@ declare class ConfluenceADFWriteProvider implements ADFWriteProvider {
25
25
  private config;
26
26
  constructor(config: ContentAPIConfig);
27
27
  private createNewContentProperty;
28
- writeData(sourceId: string, localId: string, data: ADFEntity, resourceId?: string): Promise<string>;
28
+ writeData(data: SyncBlockData): Promise<string>;
29
29
  }
30
30
  /**
31
31
  * Convenience function to create providers with default content property key
package/package.json CHANGED
@@ -82,7 +82,7 @@
82
82
  }
83
83
  },
84
84
  "name": "@atlaskit/editor-synced-block-provider",
85
- "version": "0.3.0",
85
+ "version": "0.5.0",
86
86
  "description": "Synced Block Provider for @atlaskit/editor-plugin-synced-block",
87
87
  "author": "Atlassian Pty Ltd",
88
88
  "license": "Apache-2.0",