@atlaskit/editor-synced-block-provider 2.8.0 → 2.9.1

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 (49) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/hooks/useFetchSyncBlockData.js +3 -2
  3. package/dist/cjs/index.js +30 -0
  4. package/dist/cjs/providers/block-service/blockServiceAPI.js +14 -8
  5. package/dist/cjs/providers/confluence/confluenceContentAPI.js +5 -0
  6. package/dist/cjs/providers/syncBlockProvider.js +79 -7
  7. package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +26 -0
  8. package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +2 -5
  9. package/dist/cjs/store-manager/syncBlockStoreManager.js +5 -0
  10. package/dist/cjs/utils/ari.js +32 -4
  11. package/dist/es2019/hooks/useFetchSyncBlockData.js +3 -2
  12. package/dist/es2019/index.js +1 -1
  13. package/dist/es2019/providers/block-service/blockServiceAPI.js +12 -8
  14. package/dist/es2019/providers/confluence/confluenceContentAPI.js +4 -1
  15. package/dist/es2019/providers/syncBlockProvider.js +73 -5
  16. package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +25 -0
  17. package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +2 -5
  18. package/dist/es2019/store-manager/syncBlockStoreManager.js +3 -0
  19. package/dist/es2019/utils/ari.js +31 -1
  20. package/dist/esm/hooks/useFetchSyncBlockData.js +3 -2
  21. package/dist/esm/index.js +1 -1
  22. package/dist/esm/providers/block-service/blockServiceAPI.js +15 -9
  23. package/dist/esm/providers/confluence/confluenceContentAPI.js +6 -1
  24. package/dist/esm/providers/syncBlockProvider.js +79 -7
  25. package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +26 -0
  26. package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +2 -5
  27. package/dist/esm/store-manager/syncBlockStoreManager.js +5 -0
  28. package/dist/esm/utils/ari.js +31 -3
  29. package/dist/types/hooks/useFetchSyncBlockData.d.ts +2 -0
  30. package/dist/types/index.d.ts +1 -1
  31. package/dist/types/providers/block-service/blockServiceAPI.d.ts +1 -0
  32. package/dist/types/providers/confluence/confluenceContentAPI.d.ts +1 -0
  33. package/dist/types/providers/syncBlockProvider.d.ts +60 -3
  34. package/dist/types/providers/types.d.ts +23 -0
  35. package/dist/types/store-manager/referenceSyncBlockStoreManager.d.ts +3 -0
  36. package/dist/types/store-manager/syncBlockStoreManager.d.ts +2 -0
  37. package/dist/types/utils/ari.d.ts +15 -1
  38. package/dist/types/utils/blockService.d.ts +1 -1
  39. package/dist/types-ts4.5/hooks/useFetchSyncBlockData.d.ts +2 -0
  40. package/dist/types-ts4.5/index.d.ts +1 -1
  41. package/dist/types-ts4.5/providers/block-service/blockServiceAPI.d.ts +1 -0
  42. package/dist/types-ts4.5/providers/confluence/confluenceContentAPI.d.ts +1 -0
  43. package/dist/types-ts4.5/providers/syncBlockProvider.d.ts +60 -3
  44. package/dist/types-ts4.5/providers/types.d.ts +23 -0
  45. package/dist/types-ts4.5/store-manager/referenceSyncBlockStoreManager.d.ts +3 -0
  46. package/dist/types-ts4.5/store-manager/syncBlockStoreManager.d.ts +2 -0
  47. package/dist/types-ts4.5/utils/ari.d.ts +15 -1
  48. package/dist/types-ts4.5/utils/blockService.d.ts +1 -1
  49. package/package.json +8 -1
@@ -5,19 +5,52 @@ import { SyncBlockDataProvider } from '../providers/types';
5
5
  import { getLocalIdFromAri, getPageARIFromResourceId } from '../utils/ari';
6
6
  import { fetchSourceInfo } from '../utils/sourceInfo';
7
7
  export class SyncBlockProvider extends SyncBlockDataProvider {
8
- constructor(fetchProvider, writeProvider, sourceId) {
8
+ /**
9
+ * Constructor for the SyncBlockProvider
10
+ *
11
+ * @param fetchProvider
12
+ * @param writeProvider
13
+ * @param sourceId
14
+ * @param nestedRendererDataProviders
15
+ */
16
+ constructor(fetchProvider, writeProvider, sourceId, providerOptions) {
9
17
  super();
10
18
  _defineProperty(this, "name", 'syncBlockProvider');
11
19
  this.fetchProvider = fetchProvider;
12
20
  this.writeProvider = writeProvider;
13
21
  this.sourceId = sourceId;
22
+ this.providerOptions = providerOptions;
14
23
  }
24
+
25
+ /**
26
+ * Check if the node is supported by the provider
27
+ *
28
+ * @param node
29
+ *
30
+ * @returns True if the node is supported, false otherwise
31
+ */
15
32
  isNodeSupported(node) {
16
- return node.type === 'syncBlock';
33
+ return node.type === 'syncBlock' || node.type === 'bodiedSyncBlock';
17
34
  }
35
+
36
+ /**
37
+ * Get the data key for the node
38
+ *
39
+ * @param node
40
+ *
41
+ * @returns The data key
42
+ */
18
43
  nodeDataKey(node) {
19
44
  return node.attrs.localId;
20
45
  }
46
+
47
+ /**
48
+ * Fetch the data from the fetch provider
49
+ *
50
+ * @param nodes
51
+ *
52
+ * @returns Array of {resourceId?: string, error?: string}.
53
+ */
21
54
  fetchNodesData(nodes) {
22
55
  const resourceIdSet = new Set(nodes.map(node => node.attrs.resourceId));
23
56
  const resourceIds = [...resourceIdSet];
@@ -38,6 +71,7 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
38
71
  }
39
72
 
40
73
  /**
74
+ * Write the data to the write provider
41
75
  *
42
76
  * @param nodes
43
77
  * @param data
@@ -62,6 +96,14 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
62
96
  }
63
97
  });
64
98
  }
99
+
100
+ /**
101
+ * Delete the data from the write provider
102
+ *
103
+ * @param resourceIds
104
+ *
105
+ * @returns Array of {resourceId?: string, error?: string}.
106
+ */
65
107
  async deleteNodesData(resourceIds) {
66
108
  const results = await Promise.allSettled(resourceIds.map(resourceId => this.writeProvider.deleteData(resourceId)));
67
109
  return results.map((result, index) => {
@@ -76,9 +118,23 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
76
118
  }
77
119
  });
78
120
  }
121
+
122
+ /**
123
+ * Get the source id
124
+ *
125
+ * @returns The source id
126
+ */
79
127
  getSourceId() {
80
128
  return this.sourceId;
81
129
  }
130
+
131
+ /**
132
+ * Retrieve the source info from the source id
133
+ *
134
+ * @param node
135
+ *
136
+ * @returns The source info
137
+ */
82
138
  retrieveSyncBlockSourceInfo(node) {
83
139
  const {
84
140
  resourceId
@@ -99,9 +155,21 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
99
155
  }
100
156
  return pageARI ? fetchSourceInfo(pageARI, sourceLocalId) : Promise.resolve(undefined);
101
157
  }
158
+ generateResourceId(sourceId, localId) {
159
+ return this.writeProvider.generateResourceId(sourceId, localId);
160
+ }
161
+
162
+ /**
163
+ * Get the synced block renderer provider options
164
+ *
165
+ * @returns The synced block renderer provider options
166
+ */
167
+ getSyncedBlockRendererProviderOptions() {
168
+ return this.providerOptions;
169
+ }
102
170
  }
103
- export const useMemoizedSyncedBlockProvider = (fetchProvider, writeProvider, sourceId) => {
171
+ export const useMemoizedSyncedBlockProvider = (fetchProvider, writeProvider, sourceId, providerOptions) => {
104
172
  return useMemo(() => {
105
- return new SyncBlockProvider(fetchProvider, writeProvider, sourceId);
106
- }, [fetchProvider, writeProvider, sourceId]);
173
+ return new SyncBlockProvider(fetchProvider, writeProvider, sourceId, providerOptions);
174
+ }, [fetchProvider, writeProvider, sourceId, providerOptions]);
107
175
  };
@@ -1,4 +1,5 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
2
3
  import { SyncBlockError } from '../common/types';
3
4
  import { resolveSyncBlockInstance } from '../utils/resolveSyncBlockInstance';
4
5
  import { createSyncBlockNode } from '../utils/utils';
@@ -10,6 +11,7 @@ export class ReferenceSyncBlockStoreManager {
10
11
  this.titleSubscriptions = new Map();
11
12
  this.dataProvider = dataProvider;
12
13
  this.syncBlockURLRequests = new Map();
14
+ this.providerFactories = new Map();
13
15
  }
14
16
 
15
17
  /**
@@ -134,6 +136,7 @@ export class ReferenceSyncBlockStoreManager {
134
136
  }
135
137
  deleteFromCache(resourceId) {
136
138
  this.syncBlockCache.delete(resourceId);
139
+ this.providerFactories.delete(resourceId);
137
140
  }
138
141
  subscribeToSyncBlock(resourceId, localId, callback) {
139
142
  // add to subscriptions map
@@ -227,9 +230,31 @@ export class ReferenceSyncBlockStoreManager {
227
230
  }
228
231
  return (_syncBlock$data = syncBlock.data) === null || _syncBlock$data === void 0 ? void 0 : _syncBlock$data.sourceURL;
229
232
  }
233
+ getProviderFactory(resourceId) {
234
+ if (!this.dataProvider) {
235
+ return undefined;
236
+ }
237
+ const {
238
+ parentDataProviders
239
+ } = this.dataProvider.getSyncedBlockRendererProviderOptions();
240
+ if (!this.providerFactories.has(resourceId)) {
241
+ // TODO: EDITOR-2771 - In follow up PR, create media & emoji providers per ref sync block
242
+ // The media & emoji providers will be set later, once we get ref sync block data with page ID
243
+ // So we need to keep the reference to the Provider Factory so we can then set media & emoji providers later
244
+ this.providerFactories.set(resourceId, ProviderFactory.create({
245
+ emojiProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.emojiProvider,
246
+ mediaProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.mediaProvider,
247
+ mentionProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.mentionProvider,
248
+ profilecardProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.profilecardProvider,
249
+ taskDecisionProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.taskDecisionProvider
250
+ }));
251
+ }
252
+ return this.providerFactories.get(resourceId);
253
+ }
230
254
  destroy() {
231
255
  this.syncBlockCache.clear();
232
256
  this.subscriptions.clear();
233
257
  this.syncBlockURLRequests.clear();
258
+ this.providerFactories.clear();
234
259
  }
235
260
  }
@@ -2,7 +2,6 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
3
3
  import uuid from 'uuid';
4
4
  import { rebaseTransaction } from '../common/rebase-transaction';
5
- import { resourceIdFromSourceAndLocalId } from '../utils/ari';
6
5
  import { convertSyncBlockPMNodeToSyncBlockData, createBodiedSyncBlockNode } from '../utils/utils';
7
6
  export class SourceSyncBlockStoreManager {
8
7
  constructor(dataProvider) {
@@ -106,12 +105,10 @@ export class SourceSyncBlockStoreManager {
106
105
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
107
106
  const localId = uuid();
108
107
  const sourceId = (_this$dataProvider = this.dataProvider) === null || _this$dataProvider === void 0 ? void 0 : _this$dataProvider.getSourceId();
109
- if (!sourceId) {
108
+ if (!this.dataProvider || !sourceId) {
110
109
  throw new Error('Provider of sync block plugin is not set');
111
110
  }
112
-
113
- // This should be generated by the data provider implementation as it differs between data providers
114
- const resourceId = resourceIdFromSourceAndLocalId(sourceId, localId);
111
+ const resourceId = this.dataProvider.generateResourceId(sourceId, localId);
115
112
  return {
116
113
  resourceId,
117
114
  localId
@@ -122,6 +122,9 @@ export class SyncBlockStoreManager {
122
122
  // only applicable to source sync block, for now (will be refactored further)
123
123
  this.sourceSyncBlockStoreManager.rebaseTransaction(incomingTr, state);
124
124
  }
125
+ getReferenceSyncBlockProviderFactory(resourceId) {
126
+ return this.referenceSyncBlockStoreManager.getProviderFactory(resourceId);
127
+ }
125
128
  destroy() {
126
129
  this.referenceSyncBlockStoreManager.destroy();
127
130
  }
@@ -25,7 +25,37 @@ export const getPageARIFromResourceId = resourceId => {
25
25
  }
26
26
  throw new Error(`Invalid resourceId: ${resourceId}`);
27
27
  };
28
- export const getContentPropertyAri = (contentPropertyId, cloudId) => `ari:cloud:confluence:${cloudId}:content/${contentPropertyId}`;
29
28
  export const resourceIdFromSourceAndLocalId = (sourceId, localId) => {
30
29
  return sourceId + '/' + localId;
30
+ };
31
+
32
+ /**
33
+ * For the following functions, they are used for the block service API provider.
34
+ * The resourceId/blockResourceId always refers to the block ARI.
35
+ */
36
+
37
+ /**
38
+ * @param sourceId - the ARI of the document. E.G ari:cloud:confluence:cloudId:page/pageId
39
+ * @param localId - the localId of the block node. A randomly generated UUID
40
+ * @returns the block ARI. E.G ari:cloud:blocks:cloudId:synced-block/localId
41
+ */
42
+ export const blockResourceIdFromSourceAndLocalId = (sourceId, localId) => {
43
+ const match = sourceId.match(/ari:cloud:confluence:([^:]+):(page|blogpost)\/.*/);
44
+ if (!(match !== null && match !== void 0 && match[1])) {
45
+ throw new Error(`Invalid source ARI: ${sourceId}`);
46
+ }
47
+ const cloudId = match[1];
48
+ return `ari:cloud:blocks:${cloudId}:synced-block/${localId}`;
49
+ };
50
+
51
+ /**
52
+ * @param ari - the block ARI. E.G ari:cloud:blocks:cloudId:synced-block/localId
53
+ * @returns the localId of the block node. A randomly generated UUID
54
+ */
55
+ export const getLocalIdFromResourceId = ari => {
56
+ const match = ari.match(/ari:cloud:confluence:[^:]+:(page|blogpost)\/\d+\/([a-zA-Z0-9-]+)/);
57
+ if (match !== null && match !== void 0 && match[2]) {
58
+ return match[2];
59
+ }
60
+ throw new Error(`Invalid page ARI: ${ari}`);
31
61
  };
@@ -65,8 +65,9 @@ export var useFetchSyncBlockData = function useFetchSyncBlockData(manager, resou
65
65
  };
66
66
  }, [localId, referenceSyncBlockStoreManager, resourceId]);
67
67
  return {
68
- syncBlockInstance: syncBlockInstance,
69
68
  isLoading: isLoading,
70
- reloadData: reloadData
69
+ providerFactory: referenceSyncBlockStoreManager.getProviderFactory(resourceId || ''),
70
+ reloadData: reloadData,
71
+ syncBlockInstance: syncBlockInstance
71
72
  };
72
73
  };
package/dist/esm/index.js CHANGED
@@ -10,6 +10,6 @@ export { createContentAPIProvidersWithDefaultKey, useMemoizedContentAPIProviders
10
10
  export { SyncBlockProvider as SyncedBlockProvider, useMemoizedSyncedBlockProvider } from './providers/syncBlockProvider';
11
11
  export { ReferenceSyncBlockStoreManager } from './store-manager/referenceSyncBlockStoreManager';
12
12
  export { SyncBlockStoreManager } from './store-manager/syncBlockStoreManager';
13
- export { getConfluencePageAri, getPageIdAndTypeFromAri } from './utils/ari';
13
+ export { blockResourceIdFromSourceAndLocalId, getConfluencePageAri, getLocalIdFromAri, getLocalIdFromResourceId, getPageARIFromResourceId, getPageIdAndTypeFromAri, resourceIdFromSourceAndLocalId } from './utils/ari';
14
14
  export { createSyncBlockNode, convertSyncBlockPMNodeToSyncBlockData, convertSyncBlockJSONNodeToSyncBlockNode } from './utils/utils';
15
15
  export { resolveSyncBlockInstance } from './utils/resolveSyncBlockInstance';
@@ -4,7 +4,7 @@ import _createClass from "@babel/runtime/helpers/createClass";
4
4
  import _regeneratorRuntime from "@babel/runtime/regenerator";
5
5
  import { useMemo } from 'react';
6
6
  import { SyncBlockError } from '../../common/types';
7
- import { getLocalIdFromAri, resourceIdFromSourceAndLocalId } from '../../utils/ari';
7
+ import { blockResourceIdFromSourceAndLocalId, getLocalIdFromResourceId } from '../../utils/ari';
8
8
  import { BlockError, createSyncedBlock, deleteSyncedBlock, getSyncedBlockContent, updateSyncedBlock } from '../../utils/blockService';
9
9
  import { stringifyError } from '../../utils/errorHandling';
10
10
  var mapBlockError = function mapBlockError(error) {
@@ -27,21 +27,22 @@ var BlockServiceADFFetchProvider = /*#__PURE__*/function () {
27
27
  return _createClass(BlockServiceADFFetchProvider, [{
28
28
  key: "fetchData",
29
29
  value: // resourceId is the ARI of the block. E.G ari:cloud:blocks:site-123:synced-block/uuid-456
30
+ // in the content API provider, this was the concatenation of the source document's ARI and the local ID. E.G ari:cloud:confluence:site-123:page/pageId/uuid-456
30
31
  function () {
31
32
  var _fetchData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(resourceId) {
32
- var localId, contentProperty, value, syncedBlockData;
33
+ var localId, blockContentResponse, value, syncedBlockData;
33
34
  return _regeneratorRuntime.wrap(function _callee$(_context) {
34
35
  while (1) switch (_context.prev = _context.next) {
35
36
  case 0:
36
- localId = getLocalIdFromAri(resourceId);
37
+ localId = getLocalIdFromResourceId(resourceId);
37
38
  _context.prev = 1;
38
39
  _context.next = 4;
39
40
  return getSyncedBlockContent({
40
41
  blockAri: resourceId
41
42
  });
42
43
  case 4:
43
- contentProperty = _context.sent;
44
- value = contentProperty.content;
44
+ blockContentResponse = _context.sent;
45
+ value = blockContentResponse.content;
45
46
  if (value) {
46
47
  _context.next = 8;
47
48
  break;
@@ -51,7 +52,7 @@ var BlockServiceADFFetchProvider = /*#__PURE__*/function () {
51
52
  resourceId: resourceId
52
53
  });
53
54
  case 8:
54
- // Parse the synced block content from the property value
55
+ // Parse the synced block content from the response's content
55
56
  syncedBlockData = JSON.parse(value);
56
57
  return _context.abrupt("return", {
57
58
  data: {
@@ -99,7 +100,7 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
99
100
  }
100
101
  return _createClass(BlockServiceADFWriteProvider, [{
101
102
  key: "writeData",
102
- value: // it will first try to update and if it can't (404) then it will try to create
103
+ value: // it will first try to update and if it can't (404) then it will try to create
103
104
  function () {
104
105
  var _writeData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(data) {
105
106
  var resourceId;
@@ -130,7 +131,7 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
130
131
  }
131
132
  _context2.next = 13;
132
133
  return createSyncedBlock({
133
- blockAri: resourceIdFromSourceAndLocalId(resourceId, data.blockInstanceId),
134
+ blockAri: resourceId,
134
135
  blockInstanceId: data.blockInstanceId,
135
136
  sourceAri: resourceId,
136
137
  product: 'confluence-page',
@@ -159,7 +160,7 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
159
160
  return _writeData.apply(this, arguments);
160
161
  }
161
162
  return writeData;
162
- }() // soft deletes the source synced block
163
+ }() // soft deletes the source synced block
163
164
  }, {
164
165
  key: "deleteData",
165
166
  value: function () {
@@ -207,6 +208,11 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
207
208
  }
208
209
  return deleteData;
209
210
  }()
211
+ }, {
212
+ key: "generateResourceId",
213
+ value: function generateResourceId(sourceId, localId) {
214
+ return blockResourceIdFromSourceAndLocalId(sourceId, localId);
215
+ }
210
216
  }]);
211
217
  }();
212
218
  /**
@@ -6,7 +6,7 @@ import _typeof from "@babel/runtime/helpers/typeof";
6
6
  import _regeneratorRuntime from "@babel/runtime/regenerator";
7
7
  import { useMemo } from 'react';
8
8
  import { SyncBlockError } from '../../common/types';
9
- import { getLocalIdFromAri, getPageIdAndTypeFromAri } from '../../utils/ari';
9
+ import { getLocalIdFromAri, getPageIdAndTypeFromAri, resourceIdFromSourceAndLocalId } from '../../utils/ari';
10
10
  import { getContentProperty, createContentProperty, updateContentProperty, deleteContentProperty } from '../../utils/contentProperty';
11
11
  import { stringifyError } from '../../utils/errorHandling';
12
12
  import { isBlogPageType } from '../../utils/utils';
@@ -337,6 +337,11 @@ var ConfluenceADFWriteProvider = /*#__PURE__*/function () {
337
337
  }
338
338
  return deleteData;
339
339
  }()
340
+ }, {
341
+ key: "generateResourceId",
342
+ value: function generateResourceId(sourceId, localId) {
343
+ return resourceIdFromSourceAndLocalId(sourceId, localId);
344
+ }
340
345
  }]);
341
346
  }();
342
347
  /**
@@ -15,7 +15,15 @@ import { SyncBlockDataProvider } from '../providers/types';
15
15
  import { getLocalIdFromAri, getPageARIFromResourceId } from '../utils/ari';
16
16
  import { fetchSourceInfo } from '../utils/sourceInfo';
17
17
  export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
18
- function SyncBlockProvider(fetchProvider, writeProvider, sourceId) {
18
+ /**
19
+ * Constructor for the SyncBlockProvider
20
+ *
21
+ * @param fetchProvider
22
+ * @param writeProvider
23
+ * @param sourceId
24
+ * @param nestedRendererDataProviders
25
+ */
26
+ function SyncBlockProvider(fetchProvider, writeProvider, sourceId, providerOptions) {
19
27
  var _this;
20
28
  _classCallCheck(this, SyncBlockProvider);
21
29
  _this = _callSuper(this, SyncBlockProvider);
@@ -23,19 +31,44 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
23
31
  _this.fetchProvider = fetchProvider;
24
32
  _this.writeProvider = writeProvider;
25
33
  _this.sourceId = sourceId;
34
+ _this.providerOptions = providerOptions;
26
35
  return _this;
27
36
  }
37
+
38
+ /**
39
+ * Check if the node is supported by the provider
40
+ *
41
+ * @param node
42
+ *
43
+ * @returns True if the node is supported, false otherwise
44
+ */
28
45
  _inherits(SyncBlockProvider, _SyncBlockDataProvide);
29
46
  return _createClass(SyncBlockProvider, [{
30
47
  key: "isNodeSupported",
31
48
  value: function isNodeSupported(node) {
32
- return node.type === 'syncBlock';
49
+ return node.type === 'syncBlock' || node.type === 'bodiedSyncBlock';
33
50
  }
51
+
52
+ /**
53
+ * Get the data key for the node
54
+ *
55
+ * @param node
56
+ *
57
+ * @returns The data key
58
+ */
34
59
  }, {
35
60
  key: "nodeDataKey",
36
61
  value: function nodeDataKey(node) {
37
62
  return node.attrs.localId;
38
63
  }
64
+
65
+ /**
66
+ * Fetch the data from the fetch provider
67
+ *
68
+ * @param nodes
69
+ *
70
+ * @returns Array of {resourceId?: string, error?: string}.
71
+ */
39
72
  }, {
40
73
  key: "fetchNodesData",
41
74
  value: function fetchNodesData(nodes) {
@@ -63,6 +96,7 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
63
96
  }
64
97
 
65
98
  /**
99
+ * Write the data to the write provider
66
100
  *
67
101
  * @param nodes
68
102
  * @param data
@@ -107,10 +141,18 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
107
141
  return _writeNodesData.apply(this, arguments);
108
142
  }
109
143
  return writeNodesData;
110
- }())
144
+ }()
145
+ /**
146
+ * Delete the data from the write provider
147
+ *
148
+ * @param resourceIds
149
+ *
150
+ * @returns Array of {resourceId?: string, error?: string}.
151
+ */
152
+ )
111
153
  }, {
112
154
  key: "deleteNodesData",
113
- value: function () {
155
+ value: (function () {
114
156
  var _deleteNodesData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(resourceIds) {
115
157
  var _this4 = this;
116
158
  var results;
@@ -145,11 +187,25 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
145
187
  }
146
188
  return deleteNodesData;
147
189
  }()
190
+ /**
191
+ * Get the source id
192
+ *
193
+ * @returns The source id
194
+ */
195
+ )
148
196
  }, {
149
197
  key: "getSourceId",
150
198
  value: function getSourceId() {
151
199
  return this.sourceId;
152
200
  }
201
+
202
+ /**
203
+ * Retrieve the source info from the source id
204
+ *
205
+ * @param node
206
+ *
207
+ * @returns The source info
208
+ */
153
209
  }, {
154
210
  key: "retrieveSyncBlockSourceInfo",
155
211
  value: function retrieveSyncBlockSourceInfo(node) {
@@ -170,10 +226,26 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
170
226
  }
171
227
  return pageARI ? fetchSourceInfo(pageARI, sourceLocalId) : Promise.resolve(undefined);
172
228
  }
229
+ }, {
230
+ key: "generateResourceId",
231
+ value: function generateResourceId(sourceId, localId) {
232
+ return this.writeProvider.generateResourceId(sourceId, localId);
233
+ }
234
+
235
+ /**
236
+ * Get the synced block renderer provider options
237
+ *
238
+ * @returns The synced block renderer provider options
239
+ */
240
+ }, {
241
+ key: "getSyncedBlockRendererProviderOptions",
242
+ value: function getSyncedBlockRendererProviderOptions() {
243
+ return this.providerOptions;
244
+ }
173
245
  }]);
174
246
  }(SyncBlockDataProvider);
175
- export var useMemoizedSyncedBlockProvider = function useMemoizedSyncedBlockProvider(fetchProvider, writeProvider, sourceId) {
247
+ export var useMemoizedSyncedBlockProvider = function useMemoizedSyncedBlockProvider(fetchProvider, writeProvider, sourceId, providerOptions) {
176
248
  return useMemo(function () {
177
- return new SyncBlockProvider(fetchProvider, writeProvider, sourceId);
178
- }, [fetchProvider, writeProvider, sourceId]);
249
+ return new SyncBlockProvider(fetchProvider, writeProvider, sourceId, providerOptions);
250
+ }, [fetchProvider, writeProvider, sourceId, providerOptions]);
179
251
  };
@@ -9,6 +9,7 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
9
9
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
10
10
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
11
11
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
12
+ import { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
12
13
  import { SyncBlockError } from '../common/types';
13
14
  import { resolveSyncBlockInstance } from '../utils/resolveSyncBlockInstance';
14
15
  import { createSyncBlockNode } from '../utils/utils';
@@ -21,6 +22,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
21
22
  this.titleSubscriptions = new Map();
22
23
  this.dataProvider = dataProvider;
23
24
  this.syncBlockURLRequests = new Map();
25
+ this.providerFactories = new Map();
24
26
  }
25
27
 
26
28
  /**
@@ -236,6 +238,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
236
238
  key: "deleteFromCache",
237
239
  value: function deleteFromCache(resourceId) {
238
240
  this.syncBlockCache.delete(resourceId);
241
+ this.providerFactories.delete(resourceId);
239
242
  }
240
243
  }, {
241
244
  key: "subscribeToSyncBlock",
@@ -331,12 +334,35 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
331
334
  }
332
335
  return (_syncBlock$data = syncBlock.data) === null || _syncBlock$data === void 0 ? void 0 : _syncBlock$data.sourceURL;
333
336
  }
337
+ }, {
338
+ key: "getProviderFactory",
339
+ value: function getProviderFactory(resourceId) {
340
+ if (!this.dataProvider) {
341
+ return undefined;
342
+ }
343
+ var _this$dataProvider$ge = this.dataProvider.getSyncedBlockRendererProviderOptions(),
344
+ parentDataProviders = _this$dataProvider$ge.parentDataProviders;
345
+ if (!this.providerFactories.has(resourceId)) {
346
+ // TODO: EDITOR-2771 - In follow up PR, create media & emoji providers per ref sync block
347
+ // The media & emoji providers will be set later, once we get ref sync block data with page ID
348
+ // So we need to keep the reference to the Provider Factory so we can then set media & emoji providers later
349
+ this.providerFactories.set(resourceId, ProviderFactory.create({
350
+ emojiProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.emojiProvider,
351
+ mediaProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.mediaProvider,
352
+ mentionProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.mentionProvider,
353
+ profilecardProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.profilecardProvider,
354
+ taskDecisionProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.taskDecisionProvider
355
+ }));
356
+ }
357
+ return this.providerFactories.get(resourceId);
358
+ }
334
359
  }, {
335
360
  key: "destroy",
336
361
  value: function destroy() {
337
362
  this.syncBlockCache.clear();
338
363
  this.subscriptions.clear();
339
364
  this.syncBlockURLRequests.clear();
365
+ this.providerFactories.clear();
340
366
  }
341
367
  }]);
342
368
  }();
@@ -6,7 +6,6 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
6
6
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
7
7
  import uuid from 'uuid';
8
8
  import { rebaseTransaction as _rebaseTransaction } from '../common/rebase-transaction';
9
- import { resourceIdFromSourceAndLocalId } from '../utils/ari';
10
9
  import { convertSyncBlockPMNodeToSyncBlockData, createBodiedSyncBlockNode as _createBodiedSyncBlockNode } from '../utils/utils';
11
10
  export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
12
11
  function SourceSyncBlockStoreManager(dataProvider) {
@@ -158,12 +157,10 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
158
157
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
159
158
  var localId = uuid();
160
159
  var sourceId = (_this$dataProvider = this.dataProvider) === null || _this$dataProvider === void 0 ? void 0 : _this$dataProvider.getSourceId();
161
- if (!sourceId) {
160
+ if (!this.dataProvider || !sourceId) {
162
161
  throw new Error('Provider of sync block plugin is not set');
163
162
  }
164
-
165
- // This should be generated by the data provider implementation as it differs between data providers
166
- var resourceId = resourceIdFromSourceAndLocalId(sourceId, localId);
163
+ var resourceId = this.dataProvider.generateResourceId(sourceId, localId);
167
164
  return {
168
165
  resourceId: resourceId,
169
166
  localId: localId
@@ -165,6 +165,11 @@ export var SyncBlockStoreManager = /*#__PURE__*/function () {
165
165
  // only applicable to source sync block, for now (will be refactored further)
166
166
  this.sourceSyncBlockStoreManager.rebaseTransaction(incomingTr, state);
167
167
  }
168
+ }, {
169
+ key: "getReferenceSyncBlockProviderFactory",
170
+ value: function getReferenceSyncBlockProviderFactory(resourceId) {
171
+ return this.referenceSyncBlockStoreManager.getProviderFactory(resourceId);
172
+ }
168
173
  }, {
169
174
  key: "destroy",
170
175
  value: function destroy() {
@@ -28,9 +28,37 @@ export var getPageARIFromResourceId = function getPageARIFromResourceId(resource
28
28
  }
29
29
  throw new Error("Invalid resourceId: ".concat(resourceId));
30
30
  };
31
- export var getContentPropertyAri = function getContentPropertyAri(contentPropertyId, cloudId) {
32
- return "ari:cloud:confluence:".concat(cloudId, ":content/").concat(contentPropertyId);
33
- };
34
31
  export var resourceIdFromSourceAndLocalId = function resourceIdFromSourceAndLocalId(sourceId, localId) {
35
32
  return sourceId + '/' + localId;
33
+ };
34
+
35
+ /**
36
+ * For the following functions, they are used for the block service API provider.
37
+ * The resourceId/blockResourceId always refers to the block ARI.
38
+ */
39
+
40
+ /**
41
+ * @param sourceId - the ARI of the document. E.G ari:cloud:confluence:cloudId:page/pageId
42
+ * @param localId - the localId of the block node. A randomly generated UUID
43
+ * @returns the block ARI. E.G ari:cloud:blocks:cloudId:synced-block/localId
44
+ */
45
+ export var blockResourceIdFromSourceAndLocalId = function blockResourceIdFromSourceAndLocalId(sourceId, localId) {
46
+ var match = sourceId.match(/ari:cloud:confluence:([^:]+):(page|blogpost)\/.*/);
47
+ if (!(match !== null && match !== void 0 && match[1])) {
48
+ throw new Error("Invalid source ARI: ".concat(sourceId));
49
+ }
50
+ var cloudId = match[1];
51
+ return "ari:cloud:blocks:".concat(cloudId, ":synced-block/").concat(localId);
52
+ };
53
+
54
+ /**
55
+ * @param ari - the block ARI. E.G ari:cloud:blocks:cloudId:synced-block/localId
56
+ * @returns the localId of the block node. A randomly generated UUID
57
+ */
58
+ export var getLocalIdFromResourceId = function getLocalIdFromResourceId(ari) {
59
+ var match = ari.match(/ari:cloud:confluence:[^:]+:(page|blogpost)\/\d+\/([a-zA-Z0-9-]+)/);
60
+ if (match !== null && match !== void 0 && match[2]) {
61
+ return match[2];
62
+ }
63
+ throw new Error("Invalid page ARI: ".concat(ari));
36
64
  };