@atlaskit/editor-synced-block-provider 2.5.1 → 2.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/hooks/useFetchSyncBlockData.js +60 -6
  3. package/dist/cjs/hooks/useFetchSyncBlockTitle.js +24 -0
  4. package/dist/cjs/index.js +28 -7
  5. package/dist/cjs/providers/syncBlockProvider.js +12 -15
  6. package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +75 -21
  7. package/dist/cjs/store-manager/syncBlockStoreManager.js +10 -0
  8. package/dist/cjs/utils/resolveSyncBlockInstance.js +4 -3
  9. package/dist/es2019/hooks/useFetchSyncBlockData.js +35 -6
  10. package/dist/es2019/hooks/useFetchSyncBlockTitle.js +13 -0
  11. package/dist/es2019/index.js +10 -7
  12. package/dist/es2019/providers/syncBlockProvider.js +10 -8
  13. package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +71 -20
  14. package/dist/es2019/store-manager/syncBlockStoreManager.js +6 -0
  15. package/dist/es2019/utils/resolveSyncBlockInstance.js +4 -3
  16. package/dist/esm/hooks/useFetchSyncBlockData.js +60 -6
  17. package/dist/esm/hooks/useFetchSyncBlockTitle.js +17 -0
  18. package/dist/esm/index.js +10 -7
  19. package/dist/esm/providers/syncBlockProvider.js +12 -15
  20. package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +75 -21
  21. package/dist/esm/store-manager/syncBlockStoreManager.js +10 -0
  22. package/dist/esm/utils/resolveSyncBlockInstance.js +4 -3
  23. package/dist/types/common/schema.d.ts +1 -1
  24. package/dist/types/common/types.d.ts +1 -0
  25. package/dist/types/hooks/useFetchSyncBlockData.d.ts +6 -3
  26. package/dist/types/hooks/useFetchSyncBlockTitle.d.ts +3 -0
  27. package/dist/types/index.d.ts +12 -9
  28. package/dist/types/providers/syncBlockProvider.d.ts +2 -2
  29. package/dist/types/providers/types.d.ts +6 -1
  30. package/dist/types/store-manager/referenceSyncBlockStoreManager.d.ts +6 -2
  31. package/dist/types/store-manager/syncBlockStoreManager.d.ts +4 -1
  32. package/dist/types-ts4.5/common/schema.d.ts +1 -1
  33. package/dist/types-ts4.5/common/types.d.ts +1 -0
  34. package/dist/types-ts4.5/hooks/useFetchSyncBlockData.d.ts +6 -3
  35. package/dist/types-ts4.5/hooks/useFetchSyncBlockTitle.d.ts +3 -0
  36. package/dist/types-ts4.5/index.d.ts +12 -9
  37. package/dist/types-ts4.5/providers/syncBlockProvider.d.ts +2 -2
  38. package/dist/types-ts4.5/providers/types.d.ts +6 -1
  39. package/dist/types-ts4.5/store-manager/referenceSyncBlockStoreManager.d.ts +6 -2
  40. package/dist/types-ts4.5/store-manager/syncBlockStoreManager.d.ts +4 -1
  41. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/editor-synced-block-provider
2
2
 
3
+ ## 2.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`261fa27c56fd0`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/261fa27c56fd0) -
8
+ EDITOR-2533 implement retry function for sync-block renderer
9
+
10
+ ## 2.5.2
11
+
12
+ ### Patch Changes
13
+
14
+ - [`7e3353721fa66`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7e3353721fa66) -
15
+ [ux] EDITOR-1822 update sync blocks ui to new design
16
+
3
17
  ## 2.5.1
4
18
 
5
19
  ### Patch Changes
@@ -4,22 +4,76 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.useFetchSyncBlockData = exports.SYNC_BLOCK_FETCH_INTERVAL = void 0;
7
+ exports.useFetchSyncBlockData = void 0;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
8
10
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
11
  var _react = require("react");
10
- var SYNC_BLOCK_FETCH_INTERVAL = exports.SYNC_BLOCK_FETCH_INTERVAL = 3000;
11
- var useFetchSyncBlockData = exports.useFetchSyncBlockData = function useFetchSyncBlockData(manager, syncBlockNode) {
12
+ var _types = require("../common/types");
13
+ var _createSyncBlock = require("../utils/createSyncBlock");
14
+ var useFetchSyncBlockData = exports.useFetchSyncBlockData = function useFetchSyncBlockData(manager, resourceId, localId) {
12
15
  var _useState = (0, _react.useState)(null),
13
16
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
14
17
  syncBlockInstance = _useState2[0],
15
18
  setSyncBlockInstance = _useState2[1];
19
+ var _useState3 = (0, _react.useState)(true),
20
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
21
+ isLoading = _useState4[0],
22
+ setIsLoading = _useState4[1];
23
+ var referenceSyncBlockStoreManager = manager.getReferenceSyncBlockStoreManager();
24
+ var reloadData = (0, _react.useCallback)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
25
+ var syncBlockNode;
26
+ return _regenerator.default.wrap(function _callee$(_context) {
27
+ while (1) switch (_context.prev = _context.next) {
28
+ case 0:
29
+ if (!isLoading) {
30
+ _context.next = 2;
31
+ break;
32
+ }
33
+ return _context.abrupt("return");
34
+ case 2:
35
+ syncBlockNode = resourceId && localId ? (0, _createSyncBlock.createSyncBlockNode)(localId, resourceId) : null;
36
+ if (syncBlockNode) {
37
+ _context.next = 5;
38
+ break;
39
+ }
40
+ return _context.abrupt("return");
41
+ case 5:
42
+ setIsLoading(true);
43
+ _context.prev = 6;
44
+ _context.next = 9;
45
+ return referenceSyncBlockStoreManager.fetchSyncBlocksData([syncBlockNode]);
46
+ case 9:
47
+ _context.next = 14;
48
+ break;
49
+ case 11:
50
+ _context.prev = 11;
51
+ _context.t0 = _context["catch"](6);
52
+ // Set error state if fetching fails
53
+ setSyncBlockInstance({
54
+ resourceId: resourceId || '',
55
+ error: _types.SyncBlockError.Errored
56
+ });
57
+ case 14:
58
+ setIsLoading(false);
59
+ case 15:
60
+ case "end":
61
+ return _context.stop();
62
+ }
63
+ }, _callee, null, [[6, 11]]);
64
+ })), [isLoading, localId, referenceSyncBlockStoreManager, resourceId]);
16
65
  (0, _react.useEffect)(function () {
17
- var unsubscribe = manager.subscribeToSyncBlockData(syncBlockNode, function (data) {
66
+ var unsubscribe = referenceSyncBlockStoreManager.subscribeToSyncBlock(resourceId || '', localId || '', function (data) {
18
67
  setSyncBlockInstance(data);
68
+ setIsLoading(false);
19
69
  });
20
70
  return function () {
21
71
  unsubscribe();
22
72
  };
23
- }, [manager, syncBlockNode]);
24
- return syncBlockInstance;
73
+ }, [localId, referenceSyncBlockStoreManager, resourceId]);
74
+ return {
75
+ syncBlockInstance: syncBlockInstance,
76
+ isLoading: isLoading,
77
+ reloadData: reloadData
78
+ };
25
79
  };
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.useFetchSyncBlockTitle = void 0;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _react = require("react");
10
+ var useFetchSyncBlockTitle = exports.useFetchSyncBlockTitle = function useFetchSyncBlockTitle(manager, syncBlockNode) {
11
+ var _useState = (0, _react.useState)(undefined),
12
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
13
+ sourceTitle = _useState2[0],
14
+ setSourceTitle = _useState2[1];
15
+ (0, _react.useEffect)(function () {
16
+ var unsubscribe = manager.subscribeToSyncBlockSourceTitle(syncBlockNode, function (title) {
17
+ setSourceTitle(title);
18
+ });
19
+ return function () {
20
+ unsubscribe();
21
+ };
22
+ }, [manager, syncBlockNode]);
23
+ return sourceTitle;
24
+ };
package/dist/cjs/index.js CHANGED
@@ -3,6 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ Object.defineProperty(exports, "ReferenceSyncBlockStoreManager", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _referenceSyncBlockStoreManager.ReferenceSyncBlockStoreManager;
10
+ }
11
+ });
6
12
  Object.defineProperty(exports, "SyncBlockError", {
7
13
  enumerable: true,
8
14
  get: function get() {
@@ -33,6 +39,12 @@ Object.defineProperty(exports, "createContentAPIProvidersWithDefaultKey", {
33
39
  return _confluenceContentAPI.createContentAPIProvidersWithDefaultKey;
34
40
  }
35
41
  });
42
+ Object.defineProperty(exports, "createSyncBlockNode", {
43
+ enumerable: true,
44
+ get: function get() {
45
+ return _createSyncBlock.createSyncBlockNode;
46
+ }
47
+ });
36
48
  Object.defineProperty(exports, "getConfluencePageAri", {
37
49
  enumerable: true,
38
50
  get: function get() {
@@ -69,6 +81,12 @@ Object.defineProperty(exports, "useFetchSyncBlockData", {
69
81
  return _useFetchSyncBlockData.useFetchSyncBlockData;
70
82
  }
71
83
  });
84
+ Object.defineProperty(exports, "useFetchSyncBlockTitle", {
85
+ enumerable: true,
86
+ get: function get() {
87
+ return _useFetchSyncBlockTitle.useFetchSyncBlockTitle;
88
+ }
89
+ });
72
90
  Object.defineProperty(exports, "useHandleContentChanges", {
73
91
  enumerable: true,
74
92
  get: function get() {
@@ -87,14 +105,17 @@ Object.defineProperty(exports, "useMemoizedSyncedBlockProvider", {
87
105
  return _syncBlockProvider.useMemoizedSyncedBlockProvider;
88
106
  }
89
107
  });
90
- var _syncBlockProvider = require("./providers/syncBlockProvider");
91
- var _syncBlockStoreManager = require("./store-manager/syncBlockStoreManager");
108
+ var _rebaseTransaction = require("./common/rebase-transaction");
109
+ var _schema = require("./common/schema");
110
+ var _types = require("./common/types");
92
111
  var _useFetchSyncBlockData = require("./hooks/useFetchSyncBlockData");
112
+ var _useFetchSyncBlockTitle = require("./hooks/useFetchSyncBlockTitle");
93
113
  var _useHandleContentChanges = require("./hooks/useHandleContentChanges");
94
- var _types = require("./common/types");
95
- var _schema = require("./common/schema");
96
114
  var _confluenceContentAPI = require("./providers/confluence/confluenceContentAPI");
115
+ var _syncBlockProvider = require("./providers/syncBlockProvider");
116
+ var _referenceSyncBlockStoreManager = require("./store-manager/referenceSyncBlockStoreManager");
117
+ var _syncBlockStoreManager = require("./store-manager/syncBlockStoreManager");
97
118
  var _ari = require("./utils/ari");
98
- var _utils = require("./utils/utils");
99
- var _rebaseTransaction = require("./common/rebase-transaction");
100
- var _resolveSyncBlockInstance = require("./utils/resolveSyncBlockInstance");
119
+ var _createSyncBlock = require("./utils/createSyncBlock");
120
+ var _resolveSyncBlockInstance = require("./utils/resolveSyncBlockInstance");
121
+ var _utils = require("./utils/utils");
@@ -133,8 +133,8 @@ var SyncBlockProvider = exports.SyncBlockProvider = /*#__PURE__*/function (_Sync
133
133
  return this.sourceId;
134
134
  }
135
135
  }, {
136
- key: "retrieveSyncBlockSourceUrl",
137
- value: function retrieveSyncBlockSourceUrl(node) {
136
+ key: "retrieveSyncBlockSourceUrlAndTitle",
137
+ value: function retrieveSyncBlockSourceUrlAndTitle(node) {
138
138
  var resourceId = node.attrs.resourceId;
139
139
  var pageARI;
140
140
  var sourceLocalId;
@@ -150,7 +150,7 @@ var SyncBlockProvider = exports.SyncBlockProvider = /*#__PURE__*/function (_Sync
150
150
  // EDITOR-1921: log analytic here, safe to continue
151
151
  }
152
152
  }
153
- return pageARI ? fetchURLfromARI(pageARI, sourceLocalId) : Promise.resolve(undefined);
153
+ return pageARI ? fetchURLandTitlefromARI(pageARI, sourceLocalId) : Promise.resolve(undefined);
154
154
  }
155
155
  }]);
156
156
  }(_types2.SyncBlockDataProvider);
@@ -159,9 +159,9 @@ var useMemoizedSyncedBlockProvider = exports.useMemoizedSyncedBlockProvider = fu
159
159
  return new SyncBlockProvider(fetchProvider, writeProvider, sourceId);
160
160
  }, [fetchProvider, writeProvider, sourceId]);
161
161
  };
162
- var fetchURLfromARI = /*#__PURE__*/function () {
162
+ var fetchURLandTitlefromARI = /*#__PURE__*/function () {
163
163
  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(ari, sourceLocalId) {
164
- var response, _payload$data, payload, url;
164
+ var response, _payload$data, _payload$data2, payload, url, title;
165
165
  return _regenerator.default.wrap(function _callee2$(_context2) {
166
166
  while (1) switch (_context2.prev = _context2.next) {
167
167
  case 0:
@@ -187,17 +187,14 @@ var fetchURLfromARI = /*#__PURE__*/function () {
187
187
  case 6:
188
188
  payload = _context2.sent;
189
189
  url = payload === null || payload === void 0 || (_payload$data = payload.data) === null || _payload$data === void 0 ? void 0 : _payload$data.url;
190
- if (!(typeof url === 'string')) {
191
- _context2.next = 10;
192
- break;
193
- }
194
- return _context2.abrupt("return", sourceLocalId ? url + "?block=".concat(sourceLocalId) : url);
195
- case 10:
196
- _context2.next = 13;
197
- break;
190
+ title = payload === null || payload === void 0 || (_payload$data2 = payload.data) === null || _payload$data2 === void 0 ? void 0 : _payload$data2.name;
191
+ return _context2.abrupt("return", {
192
+ url: typeof url === 'string' ? sourceLocalId ? url + "?block=".concat(sourceLocalId) : url : undefined,
193
+ title: typeof title === 'string' ? title : undefined
194
+ });
198
195
  case 12:
199
196
  //eslint-disable-next-line no-console
200
- console.error('Failed to fetch URL from ARI', response.statusText);
197
+ console.error('Failed to fetch URL and title from ARI', response.statusText);
201
198
  case 13:
202
199
  return _context2.abrupt("return", undefined);
203
200
  case 14:
@@ -206,7 +203,7 @@ var fetchURLfromARI = /*#__PURE__*/function () {
206
203
  }
207
204
  }, _callee2);
208
205
  }));
209
- return function fetchURLfromARI(_x2, _x3) {
206
+ return function fetchURLandTitlefromARI(_x2, _x3) {
210
207
  return _ref.apply(this, arguments);
211
208
  };
212
209
  }();
@@ -24,6 +24,7 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
24
24
  (0, _defineProperty2.default)(this, "isRefreshingSubscriptions", false);
25
25
  this.syncBlockCache = new Map();
26
26
  this.subscriptions = new Map();
27
+ this.titleSubscriptions = new Map();
27
28
  this.dataProvider = dataProvider;
28
29
  this.syncBlockURLRequests = new Map();
29
30
  }
@@ -112,8 +113,8 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
112
113
  return refreshSubscriptions;
113
114
  }())
114
115
  }, {
115
- key: "fetchSyncBlockSourceURL",
116
- value: function fetchSyncBlockSourceURL(resourceId) {
116
+ key: "fetchSyncBlockSourceURLAndTitle",
117
+ value: function fetchSyncBlockSourceURLAndTitle(resourceId) {
117
118
  var _this = this;
118
119
  if (!resourceId || !this.dataProvider) {
119
120
  return;
@@ -123,13 +124,17 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
123
124
  // we could optimise this further by checking if the sync block is on the same page as the source
124
125
  if (!this.syncBlockURLRequests.get(resourceId)) {
125
126
  this.syncBlockURLRequests.set(resourceId, true);
126
- this.dataProvider.retrieveSyncBlockSourceUrl((0, _createSyncBlock.createSyncBlockNode)('', resourceId)).then(function (sourceURL) {
127
+ this.dataProvider.retrieveSyncBlockSourceUrlAndTitle((0, _createSyncBlock.createSyncBlockNode)('', resourceId)).then(function (sourceInfo) {
127
128
  var existingSyncBlock = _this.getFromCache(resourceId);
128
129
  if (existingSyncBlock && existingSyncBlock.data) {
129
130
  existingSyncBlock.data = _objectSpread(_objectSpread({}, existingSyncBlock.data), {}, {
130
- sourceURL: sourceURL
131
+ sourceURL: sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.url,
132
+ sourceTitle: sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.title
131
133
  });
132
134
  _this.updateCache(existingSyncBlock);
135
+ if (sourceInfo !== null && sourceInfo !== void 0 && sourceInfo.title) {
136
+ _this.updateSourceTitleSubscriptions(existingSyncBlock.resourceId, sourceInfo.title);
137
+ }
133
138
  }
134
139
  }).finally(function () {
135
140
  _this.syncBlockURLRequests.set(resourceId, false);
@@ -163,7 +168,7 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
163
168
  case 7:
164
169
  resolvedData = [];
165
170
  data.forEach(function (syncBlockInstance) {
166
- var _resolvedSyncBlockIns;
171
+ var _resolvedSyncBlockIns, _resolvedSyncBlockIns2;
167
172
  if (!syncBlockInstance.resourceId) {
168
173
  return;
169
174
  }
@@ -172,9 +177,9 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
172
177
  _this2.updateCache(resolvedSyncBlockInstance);
173
178
  resolvedData.push(resolvedSyncBlockInstance);
174
179
 
175
- // fetch source URL if not already present
176
- if (!((_resolvedSyncBlockIns = resolvedSyncBlockInstance.data) !== null && _resolvedSyncBlockIns !== void 0 && _resolvedSyncBlockIns.sourceURL) && resolvedSyncBlockInstance.resourceId) {
177
- _this2.fetchSyncBlockSourceURL(resolvedSyncBlockInstance.resourceId);
180
+ // fetch source URL and title if not already present
181
+ if ((!((_resolvedSyncBlockIns = resolvedSyncBlockInstance.data) !== null && _resolvedSyncBlockIns !== void 0 && _resolvedSyncBlockIns.sourceURL) || !((_resolvedSyncBlockIns2 = resolvedSyncBlockInstance.data) !== null && _resolvedSyncBlockIns2 !== void 0 && _resolvedSyncBlockIns2.sourceTitle)) && resolvedSyncBlockInstance.resourceId) {
182
+ _this2.fetchSyncBlockSourceURLAndTitle(resolvedSyncBlockInstance.resourceId);
178
183
  }
179
184
  });
180
185
  return _context3.abrupt("return", resolvedData);
@@ -203,6 +208,16 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
203
208
  }
204
209
  }
205
210
  }
211
+ }, {
212
+ key: "updateSourceTitleSubscriptions",
213
+ value: function updateSourceTitleSubscriptions(resourceId, title) {
214
+ var callbacks = this.titleSubscriptions.get(resourceId);
215
+ if (callbacks) {
216
+ Object.values(callbacks).forEach(function (callback) {
217
+ callback(title);
218
+ });
219
+ }
220
+ }
206
221
  }, {
207
222
  key: "getFromCache",
208
223
  value: function getFromCache(resourceId) {
@@ -214,20 +229,9 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
214
229
  this.syncBlockCache.delete(resourceId);
215
230
  }
216
231
  }, {
217
- key: "subscribe",
218
- value: function subscribe(node, callback) {
232
+ key: "subscribeToSyncBlock",
233
+ value: function subscribeToSyncBlock(resourceId, localId, callback) {
219
234
  var _this3 = this;
220
- // check node is a sync block, as we only support sync block subscriptions
221
- if (node.type.name !== 'syncBlock') {
222
- return function () {};
223
- }
224
- var _node$attrs = node.attrs,
225
- resourceId = _node$attrs.resourceId,
226
- localId = _node$attrs.localId;
227
- if (!localId || !resourceId) {
228
- return function () {};
229
- }
230
-
231
235
  // add to subscriptions map
232
236
  var resourceSubscriptions = this.subscriptions.get(resourceId) || {};
233
237
  this.subscriptions.set(resourceId, _objectSpread(_objectSpread({}, resourceSubscriptions), {}, (0, _defineProperty2.default)({}, localId, callback)));
@@ -252,6 +256,56 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
252
256
  }
253
257
  };
254
258
  }
259
+ }, {
260
+ key: "subscribeToSourceTitle",
261
+ value: function subscribeToSourceTitle(node, callback) {
262
+ var _cachedData$data,
263
+ _this4 = this;
264
+ // check node is a sync block, as we only support sync block subscriptions
265
+ if (node.type.name !== 'syncBlock') {
266
+ return function () {};
267
+ }
268
+ var _node$attrs = node.attrs,
269
+ resourceId = _node$attrs.resourceId,
270
+ localId = _node$attrs.localId;
271
+ if (!localId || !resourceId) {
272
+ return function () {};
273
+ }
274
+ var cachedData = this.getFromCache(resourceId);
275
+ if (cachedData !== null && cachedData !== void 0 && (_cachedData$data = cachedData.data) !== null && _cachedData$data !== void 0 && _cachedData$data.sourceTitle) {
276
+ callback(cachedData.data.sourceTitle);
277
+ }
278
+
279
+ // add to subscriptions map
280
+ var resourceSubscriptions = this.titleSubscriptions.get(resourceId) || {};
281
+ this.titleSubscriptions.set(resourceId, _objectSpread(_objectSpread({}, resourceSubscriptions), {}, (0, _defineProperty2.default)({}, localId, callback)));
282
+ return function () {
283
+ var resourceSubscriptions = _this4.titleSubscriptions.get(resourceId);
284
+ if (resourceSubscriptions) {
285
+ delete resourceSubscriptions[localId];
286
+ if (Object.keys(resourceSubscriptions).length === 0) {
287
+ _this4.titleSubscriptions.delete(resourceId);
288
+ } else {
289
+ _this4.titleSubscriptions.set(resourceId, resourceSubscriptions);
290
+ }
291
+ }
292
+ };
293
+ }
294
+ }, {
295
+ key: "subscribe",
296
+ value: function subscribe(node, callback) {
297
+ // check node is a sync block, as we only support sync block subscriptions
298
+ if (node.type.name !== 'syncBlock') {
299
+ return function () {};
300
+ }
301
+ var _node$attrs2 = node.attrs,
302
+ resourceId = _node$attrs2.resourceId,
303
+ localId = _node$attrs2.localId;
304
+ if (!localId || !resourceId) {
305
+ return function () {};
306
+ }
307
+ return this.subscribeToSyncBlock(resourceId, localId, callback);
308
+ }
255
309
 
256
310
  /**
257
311
  * Get the URL for a sync block.
@@ -40,6 +40,11 @@ var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/functio
40
40
  }
41
41
  return this.referenceSyncBlockStoreManager.fetchSyncBlocksData(syncBlockNodes);
42
42
  }
43
+ }, {
44
+ key: "getReferenceSyncBlockStoreManager",
45
+ value: function getReferenceSyncBlockStoreManager() {
46
+ return this.referenceSyncBlockStoreManager;
47
+ }
43
48
 
44
49
  /**
45
50
  * Add/update a sync block node to/from the local cache
@@ -111,6 +116,11 @@ var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/functio
111
116
  value: function subscribeToSyncBlockData(node, callback) {
112
117
  return this.referenceSyncBlockStoreManager.subscribe(node, callback);
113
118
  }
119
+ }, {
120
+ key: "subscribeToSyncBlockSourceTitle",
121
+ value: function subscribeToSyncBlockSourceTitle(node, callback) {
122
+ return this.referenceSyncBlockStoreManager.subscribeToSourceTitle(node, callback);
123
+ }
114
124
  }, {
115
125
  key: "refreshSubscriptions",
116
126
  value: function refreshSubscriptions() {
@@ -19,7 +19,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
19
19
  * @returns A merged SyncBlockInstance object.
20
20
  */
21
21
  var resolveSyncBlockInstance = exports.resolveSyncBlockInstance = function resolveSyncBlockInstance(oldResult, newResult) {
22
- var _newResult$data, _oldResult$data;
22
+ var _newResult$data, _oldResult$data, _newResult$data2, _oldResult$data2;
23
23
  // if the old result has no data, we simple return the new result
24
24
  if (!oldResult.data) {
25
25
  return newResult;
@@ -29,10 +29,11 @@ var resolveSyncBlockInstance = exports.resolveSyncBlockInstance = function resol
29
29
  return oldResult;
30
30
  }
31
31
 
32
- // otherwise, we merge the two results, preserving the sourceURL from the old result if it exists
32
+ // otherwise, we merge the two results, preserving the sourceURL and sourceTitle from the old result if it exists
33
33
  return _objectSpread(_objectSpread({}, newResult), {}, {
34
34
  data: _objectSpread(_objectSpread({}, newResult.data), {}, {
35
- sourceURL: ((_newResult$data = newResult.data) === null || _newResult$data === void 0 ? void 0 : _newResult$data.sourceURL) || ((_oldResult$data = oldResult.data) === null || _oldResult$data === void 0 ? void 0 : _oldResult$data.sourceURL) || undefined
35
+ sourceURL: ((_newResult$data = newResult.data) === null || _newResult$data === void 0 ? void 0 : _newResult$data.sourceURL) || ((_oldResult$data = oldResult.data) === null || _oldResult$data === void 0 ? void 0 : _oldResult$data.sourceURL) || undefined,
36
+ sourceTitle: ((_newResult$data2 = newResult.data) === null || _newResult$data2 === void 0 ? void 0 : _newResult$data2.sourceTitle) || ((_oldResult$data2 = oldResult.data) === null || _oldResult$data2 === void 0 ? void 0 : _oldResult$data2.sourceTitle) || undefined
36
37
  })
37
38
  });
38
39
  };
@@ -1,14 +1,43 @@
1
- import { useEffect, useState } from 'react';
2
- export const SYNC_BLOCK_FETCH_INTERVAL = 3000;
3
- export const useFetchSyncBlockData = (manager, syncBlockNode) => {
1
+ import { useCallback, useEffect, useState } from 'react';
2
+ import { SyncBlockError } from '../common/types';
3
+ import { createSyncBlockNode } from '../utils/createSyncBlock';
4
+ export const useFetchSyncBlockData = (manager, resourceId, localId) => {
4
5
  const [syncBlockInstance, setSyncBlockInstance] = useState(null);
6
+ const [isLoading, setIsLoading] = useState(true);
7
+ const referenceSyncBlockStoreManager = manager.getReferenceSyncBlockStoreManager();
8
+ const reloadData = useCallback(async () => {
9
+ if (isLoading) {
10
+ return;
11
+ }
12
+ const syncBlockNode = resourceId && localId ? createSyncBlockNode(localId, resourceId) : null;
13
+ if (!syncBlockNode) {
14
+ return;
15
+ }
16
+ setIsLoading(true);
17
+ try {
18
+ // Fetch sync block data, the `subscribeToSyncBlock` will update the state once data is fetched
19
+ await referenceSyncBlockStoreManager.fetchSyncBlocksData([syncBlockNode]);
20
+ } catch (error) {
21
+ // Set error state if fetching fails
22
+ setSyncBlockInstance({
23
+ resourceId: resourceId || '',
24
+ error: SyncBlockError.Errored
25
+ });
26
+ }
27
+ setIsLoading(false);
28
+ }, [isLoading, localId, referenceSyncBlockStoreManager, resourceId]);
5
29
  useEffect(() => {
6
- const unsubscribe = manager.subscribeToSyncBlockData(syncBlockNode, data => {
30
+ const unsubscribe = referenceSyncBlockStoreManager.subscribeToSyncBlock(resourceId || '', localId || '', data => {
7
31
  setSyncBlockInstance(data);
32
+ setIsLoading(false);
8
33
  });
9
34
  return () => {
10
35
  unsubscribe();
11
36
  };
12
- }, [manager, syncBlockNode]);
13
- return syncBlockInstance;
37
+ }, [localId, referenceSyncBlockStoreManager, resourceId]);
38
+ return {
39
+ syncBlockInstance,
40
+ isLoading,
41
+ reloadData
42
+ };
14
43
  };
@@ -0,0 +1,13 @@
1
+ import { useEffect, useState } from 'react';
2
+ export const useFetchSyncBlockTitle = (manager, syncBlockNode) => {
3
+ const [sourceTitle, setSourceTitle] = useState(undefined);
4
+ useEffect(() => {
5
+ const unsubscribe = manager.subscribeToSyncBlockSourceTitle(syncBlockNode, title => {
6
+ setSourceTitle(title);
7
+ });
8
+ return () => {
9
+ unsubscribe();
10
+ };
11
+ }, [manager, syncBlockNode]);
12
+ return sourceTitle;
13
+ };
@@ -1,13 +1,16 @@
1
1
  /* eslint-disable @atlaskit/editor/no-re-export */
2
2
 
3
- export { SyncBlockProvider as SyncedBlockProvider, useMemoizedSyncedBlockProvider } from './providers/syncBlockProvider';
4
- export { SyncBlockStoreManager } from './store-manager/syncBlockStoreManager';
3
+ export { rebaseTransaction } from './common/rebase-transaction';
4
+ export { getDefaultSyncBlockSchema } from './common/schema';
5
+ export { SyncBlockError } from './common/types';
5
6
  export { useFetchSyncBlockData } from './hooks/useFetchSyncBlockData';
7
+ export { useFetchSyncBlockTitle } from './hooks/useFetchSyncBlockTitle';
6
8
  export { useHandleContentChanges } from './hooks/useHandleContentChanges';
7
- export { SyncBlockError } from './common/types';
8
- export { getDefaultSyncBlockSchema } from './common/schema';
9
9
  export { createContentAPIProvidersWithDefaultKey, useMemoizedContentAPIProviders } from './providers/confluence/confluenceContentAPI';
10
+ export { SyncBlockProvider as SyncedBlockProvider, useMemoizedSyncedBlockProvider } from './providers/syncBlockProvider';
11
+ export { ReferenceSyncBlockStoreManager } from './store-manager/referenceSyncBlockStoreManager';
12
+ export { SyncBlockStoreManager } from './store-manager/syncBlockStoreManager';
10
13
  export { getConfluencePageAri, getPageIdAndTypeFromAri } from './utils/ari';
11
- export { convertSyncBlockPMNodeToSyncBlockData } from './utils/utils';
12
- export { rebaseTransaction } from './common/rebase-transaction';
13
- export { resolveSyncBlockInstance } from './utils/resolveSyncBlockInstance';
14
+ export { createSyncBlockNode } from './utils/createSyncBlock';
15
+ export { resolveSyncBlockInstance } from './utils/resolveSyncBlockInstance';
16
+ export { convertSyncBlockPMNodeToSyncBlockData } from './utils/utils';
@@ -72,7 +72,7 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
72
72
  getSourceId() {
73
73
  return this.sourceId;
74
74
  }
75
- retrieveSyncBlockSourceUrl(node) {
75
+ retrieveSyncBlockSourceUrlAndTitle(node) {
76
76
  const {
77
77
  resourceId
78
78
  } = node.attrs;
@@ -90,7 +90,7 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
90
90
  // EDITOR-1921: log analytic here, safe to continue
91
91
  }
92
92
  }
93
- return pageARI ? fetchURLfromARI(pageARI, sourceLocalId) : Promise.resolve(undefined);
93
+ return pageARI ? fetchURLandTitlefromARI(pageARI, sourceLocalId) : Promise.resolve(undefined);
94
94
  }
95
95
  }
96
96
  export const useMemoizedSyncedBlockProvider = (fetchProvider, writeProvider, sourceId) => {
@@ -98,7 +98,7 @@ export const useMemoizedSyncedBlockProvider = (fetchProvider, writeProvider, sou
98
98
  return new SyncBlockProvider(fetchProvider, writeProvider, sourceId);
99
99
  }, [fetchProvider, writeProvider, sourceId]);
100
100
  };
101
- const fetchURLfromARI = async (ari, sourceLocalId) => {
101
+ const fetchURLandTitlefromARI = async (ari, sourceLocalId) => {
102
102
  const response = await fetch('/gateway/api/object-resolver/resolve/ari', {
103
103
  method: 'POST',
104
104
  headers: {
@@ -110,15 +110,17 @@ const fetchURLfromARI = async (ari, sourceLocalId) => {
110
110
  })
111
111
  });
112
112
  if (response.ok) {
113
- var _payload$data;
113
+ var _payload$data, _payload$data2;
114
114
  const payload = await response.json();
115
115
  const url = payload === null || payload === void 0 ? void 0 : (_payload$data = payload.data) === null || _payload$data === void 0 ? void 0 : _payload$data.url;
116
- if (typeof url === 'string') {
117
- return sourceLocalId ? url + `?block=${sourceLocalId}` : url;
118
- }
116
+ const title = payload === null || payload === void 0 ? void 0 : (_payload$data2 = payload.data) === null || _payload$data2 === void 0 ? void 0 : _payload$data2.name;
117
+ return {
118
+ url: typeof url === 'string' ? sourceLocalId ? url + `?block=${sourceLocalId}` : url : undefined,
119
+ title: typeof title === 'string' ? title : undefined
120
+ };
119
121
  } else {
120
122
  //eslint-disable-next-line no-console
121
- console.error('Failed to fetch URL from ARI', response.statusText);
123
+ console.error('Failed to fetch URL and title from ARI', response.statusText);
122
124
  }
123
125
  return undefined;
124
126
  };