@atlaskit/editor-synced-block-provider 3.30.5 → 3.30.6

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 (44) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cjs/clients/block-service/blockService.js +23 -16
  3. package/dist/cjs/clients/confluence/fetchMediaToken.js +7 -5
  4. package/dist/cjs/hooks/useFetchSyncBlockTitle.js +40 -2
  5. package/dist/cjs/hooks/useHandleContentChanges.js +3 -0
  6. package/dist/cjs/providers/syncBlockProvider.js +32 -2
  7. package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +3 -0
  8. package/dist/cjs/store-manager/syncBlockStoreManager.js +20 -5
  9. package/dist/cjs/utils/experienceTracking.js +10 -10
  10. package/dist/cjs/utils/resourceId.js +2 -2
  11. package/dist/cjs/utils/retry.js +33 -7
  12. package/dist/cjs/utils/utils.js +1 -1
  13. package/dist/cjs/utils/validValue.js +2 -1
  14. package/dist/es2019/clients/block-service/blockService.js +20 -13
  15. package/dist/es2019/clients/confluence/fetchMediaToken.js +5 -3
  16. package/dist/es2019/hooks/useFetchSyncBlockTitle.js +36 -3
  17. package/dist/es2019/hooks/useHandleContentChanges.js +3 -0
  18. package/dist/es2019/providers/syncBlockProvider.js +30 -3
  19. package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +3 -0
  20. package/dist/es2019/store-manager/syncBlockStoreManager.js +19 -6
  21. package/dist/es2019/utils/experienceTracking.js +10 -10
  22. package/dist/es2019/utils/resourceId.js +2 -2
  23. package/dist/es2019/utils/retry.js +26 -6
  24. package/dist/es2019/utils/utils.js +1 -1
  25. package/dist/es2019/utils/validValue.js +2 -1
  26. package/dist/esm/clients/block-service/blockService.js +23 -16
  27. package/dist/esm/clients/confluence/fetchMediaToken.js +7 -5
  28. package/dist/esm/hooks/useFetchSyncBlockTitle.js +41 -3
  29. package/dist/esm/hooks/useHandleContentChanges.js +3 -0
  30. package/dist/esm/providers/syncBlockProvider.js +33 -3
  31. package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +3 -0
  32. package/dist/esm/store-manager/syncBlockStoreManager.js +21 -6
  33. package/dist/esm/utils/experienceTracking.js +10 -10
  34. package/dist/esm/utils/resourceId.js +2 -2
  35. package/dist/esm/utils/retry.js +33 -7
  36. package/dist/esm/utils/utils.js +1 -1
  37. package/dist/esm/utils/validValue.js +2 -1
  38. package/dist/types/providers/syncBlockProvider.d.ts +1 -1
  39. package/dist/types/store-manager/syncBlockStoreManager.d.ts +1 -1
  40. package/dist/types/utils/experienceTracking.d.ts +10 -10
  41. package/dist/types-ts4.5/providers/syncBlockProvider.d.ts +1 -1
  42. package/dist/types-ts4.5/store-manager/syncBlockStoreManager.d.ts +1 -1
  43. package/dist/types-ts4.5/utils/experienceTracking.d.ts +10 -10
  44. package/package.json +5 -1
@@ -1,5 +1,7 @@
1
- import { useEffect, useState } from 'react';
2
- export const useFetchSyncBlockTitle = (manager, syncBlockNode) => {
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react';
4
+ const useFetchSyncBlockTitleBase = (manager, syncBlockNode) => {
3
5
  // Initialize state from cache to prevent flickering during re-renders
4
6
  const [sourceTitle, setSourceTitle] = useState(() => {
5
7
  var _cachedData$data;
@@ -24,4 +26,35 @@ export const useFetchSyncBlockTitle = (manager, syncBlockNode) => {
24
26
  };
25
27
  }, [manager, syncBlockNode]);
26
28
  return sourceTitle;
27
- };
29
+ };
30
+ const useFetchSyncBlockTitlePatched = (manager, syncBlockNode) => {
31
+ var _syncBlockNode$attrs, _syncBlockNode$attrs2;
32
+ const nodeRef = useRef(syncBlockNode);
33
+ nodeRef.current = syncBlockNode;
34
+ const nodeTypeName = syncBlockNode.type.name;
35
+ const resourceId = (_syncBlockNode$attrs = syncBlockNode.attrs) === null || _syncBlockNode$attrs === void 0 ? void 0 : _syncBlockNode$attrs.resourceId;
36
+ const localId = (_syncBlockNode$attrs2 = syncBlockNode.attrs) === null || _syncBlockNode$attrs2 === void 0 ? void 0 : _syncBlockNode$attrs2.localId;
37
+
38
+ // Initialize state from cache to prevent flickering during re-renders
39
+ const [sourceTitle, setSourceTitle] = useState(() => {
40
+ var _cachedData$data2;
41
+ if (nodeTypeName !== 'syncBlock') {
42
+ return undefined;
43
+ }
44
+ if (!resourceId) {
45
+ return undefined;
46
+ }
47
+ const cachedData = manager.referenceManager.getFromCache(resourceId);
48
+ return cachedData === null || cachedData === void 0 ? void 0 : (_cachedData$data2 = cachedData.data) === null || _cachedData$data2 === void 0 ? void 0 : _cachedData$data2.sourceTitle;
49
+ });
50
+ useEffect(() => {
51
+ const unsubscribe = manager.referenceManager.subscribeToSourceTitle(nodeRef.current, title => {
52
+ setSourceTitle(title);
53
+ });
54
+ return () => {
55
+ unsubscribe();
56
+ };
57
+ }, [manager, nodeTypeName, resourceId, localId]);
58
+ return sourceTitle;
59
+ };
60
+ export const useFetchSyncBlockTitle = conditionalHooksFactory(() => fg('platform_synced_block_patch_4'), useFetchSyncBlockTitlePatched, useFetchSyncBlockTitleBase);
@@ -1,5 +1,8 @@
1
1
  import { useEffect } from 'react';
2
2
  export const useHandleContentChanges = (manager, syncBlockNode) => {
3
+ // syncBlockNode is intentionally in deps — its reference changes when the
4
+ // node content is modified by a ProseMirror transaction, which is exactly
5
+ // when the source manager cache needs to be updated.
3
6
  useEffect(() => {
4
7
  manager.sourceManager.updateSyncBlockData(syncBlockNode);
5
8
  }, [manager, syncBlockNode]);
@@ -1,6 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import { useMemo } from 'react';
2
+ import { useMemo, useRef } from 'react';
3
3
  import { fg } from '@atlaskit/platform-feature-flags';
4
+ import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react';
4
5
  import { getProductFromSourceAri } from '../clients/block-service/ari';
5
6
  import { getPageIdAndTypeFromConfluencePageAri } from '../clients/confluence/ari';
6
7
  import { fetchConfluencePageInfo } from '../clients/confluence/sourceInfo';
@@ -289,7 +290,7 @@ const createSyncedBlockProvider = ({
289
290
  }) => {
290
291
  return new SyncedBlockProvider(fetchProvider, writeProvider);
291
292
  };
292
- export const useMemoizedSyncedBlockProvider = ({
293
+ const useMemoizedSyncedBlockProviderBase = ({
293
294
  fetchProvider,
294
295
  writeProvider,
295
296
  providerOptions,
@@ -305,4 +306,30 @@ export const useMemoizedSyncedBlockProvider = ({
305
306
  syncBlockProvider.setSSRData(ssrData);
306
307
  }
307
308
  return syncBlockProvider;
308
- };
309
+ };
310
+ const useMemoizedSyncedBlockProviderPatched = ({
311
+ fetchProvider,
312
+ writeProvider,
313
+ providerOptions,
314
+ getSSRData
315
+ }) => {
316
+ const syncBlockProvider = useMemo(() => createSyncedBlockProvider({
317
+ fetchProvider,
318
+ writeProvider
319
+ }), [fetchProvider, writeProvider]);
320
+ const prevProviderOptionsRef = useRef(undefined);
321
+ if (providerOptions !== prevProviderOptionsRef.current) {
322
+ prevProviderOptionsRef.current = providerOptions;
323
+ syncBlockProvider.setProviderOptions(providerOptions);
324
+ }
325
+ const prevSSRDataRef = useRef(undefined);
326
+ const ssrData = getSSRData === null || getSSRData === void 0 ? void 0 : getSSRData();
327
+ if (ssrData !== prevSSRDataRef.current) {
328
+ prevSSRDataRef.current = ssrData;
329
+ if (ssrData) {
330
+ syncBlockProvider.setSSRData(ssrData);
331
+ }
332
+ }
333
+ return syncBlockProvider;
334
+ };
335
+ export const useMemoizedSyncedBlockProvider = conditionalHooksFactory(() => fg('platform_synced_block_patch_4'), useMemoizedSyncedBlockProviderPatched, useMemoizedSyncedBlockProviderBase);
@@ -277,6 +277,9 @@ export class ReferenceSyncBlockStoreManager {
277
277
  */
278
278
  handleGraphQLSubscriptionUpdate(syncBlockInstance) {
279
279
  if (!syncBlockInstance.resourceId) {
280
+ if (fg('platform_synced_block_patch_4')) {
281
+ return;
282
+ }
280
283
  throw new Error('Sync block instance provided to graphql subscription update missing resource id');
281
284
  }
282
285
  const existingSyncBlock = this.getFromCache(syncBlockInstance.resourceId);
@@ -1,5 +1,7 @@
1
- import { useMemo } from 'react';
1
+ import { useMemo, useRef } from 'react';
2
2
  import { logException } from '@atlaskit/editor-common/monitoring';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
4
+ import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react';
3
5
  import { getProductFromSourceAri } from '../clients/block-service/ari';
4
6
  import { SyncBlockError } from '../common/types';
5
7
  import { fetchReferencesErrorPayload } from '../utils/errorHandling';
@@ -14,7 +16,7 @@ import { SourceSyncBlockStoreManager } from './sourceSyncBlockStoreManager';
14
16
  // Can be used in both editor and renderer contexts.
15
17
  export class SyncBlockStoreManager {
16
18
  constructor(dataProvider) {
17
- // In future, if reference manager needs to reach to source manager and read it's current in memorey cache
19
+ // In future, if reference manager needs to reach to source manager and read its current in memory cache
18
20
  // we can pass the source manager as a parameter to the reference manager constructor
19
21
  this.sourceSyncBlockStoreManager = new SourceSyncBlockStoreManager(dataProvider);
20
22
  this.referenceSyncBlockStoreManager = new ReferenceSyncBlockStoreManager(dataProvider);
@@ -128,11 +130,22 @@ export class SyncBlockStoreManager {
128
130
  const createSyncBlockStoreManager = dataProvider => {
129
131
  return new SyncBlockStoreManager(dataProvider);
130
132
  };
131
- export const useMemoizedSyncBlockStoreManager = (dataProvider, fireAnalyticsEvent) => {
133
+ const useMemoizedSyncBlockStoreManagerBase = (dataProvider, fireAnalyticsEvent) => {
132
134
  const syncBlockStoreManager = useMemo(() => {
133
- const syncBlockStoreManager = createSyncBlockStoreManager(dataProvider);
134
- return syncBlockStoreManager;
135
+ return createSyncBlockStoreManager(dataProvider);
135
136
  }, [dataProvider]);
136
137
  syncBlockStoreManager.setFireAnalyticsEvent(fireAnalyticsEvent);
137
138
  return syncBlockStoreManager;
138
- };
139
+ };
140
+ const useMemoizedSyncBlockStoreManagerPatched = (dataProvider, fireAnalyticsEvent) => {
141
+ const syncBlockStoreManager = useMemo(() => {
142
+ return createSyncBlockStoreManager(dataProvider);
143
+ }, [dataProvider]);
144
+ const prevFireAnalyticsEventRef = useRef(undefined);
145
+ if (fireAnalyticsEvent !== prevFireAnalyticsEventRef.current) {
146
+ prevFireAnalyticsEventRef.current = fireAnalyticsEvent;
147
+ syncBlockStoreManager.setFireAnalyticsEvent(fireAnalyticsEvent);
148
+ }
149
+ return syncBlockStoreManager;
150
+ };
151
+ export const useMemoizedSyncBlockStoreManager = conditionalHooksFactory(() => fg('platform_synced_block_patch_4'), useMemoizedSyncBlockStoreManagerPatched, useMemoizedSyncBlockStoreManagerBase);
@@ -81,9 +81,9 @@ export const getFetchSourceInfoExperience = fireAnalyticsEvent => {
81
81
  /**
82
82
  * This experience tracks when a source sync block is deleted from the BE.
83
83
  *
84
- * Start: When the fetchSourceInfo function is called.
85
- * Success: When the fetching the data is successful within the timeout duration of start.
86
- * Failure: When the timeout duration passes without the data being successfully fetched, or the fetch fails
84
+ * Start: When the delete source sync block function is called.
85
+ * Success: When the sync block deletion is successful within the timeout duration of start.
86
+ * Failure: When the timeout duration passes without the sync block being successfully deleted, or the deletion fails
87
87
  */
88
88
  export const getDeleteSourceExperience = fireAnalyticsEvent => {
89
89
  return new Experience(EXPERIENCE_ID.ASYNC_OPERATION, {
@@ -98,9 +98,9 @@ export const getDeleteSourceExperience = fireAnalyticsEvent => {
98
98
  /**
99
99
  * This experience tracks when a source sync block is created and registered to the BE.
100
100
  *
101
- * Start: When the fetchSourceInfo function is called.
102
- * Success: When the fetching the data is successful within the timeout duration of start.
103
- * Failure: When the timeout duration passes without the data being successfully fetched, or the fetch fails
101
+ * Start: When the create source sync block function is called.
102
+ * Success: When the sync block creation is successful within the timeout duration of start.
103
+ * Failure: When the timeout duration passes without the sync block being successfully created, or the creation fails
104
104
  */
105
105
  export const getCreateSourceExperience = fireAnalyticsEvent => {
106
106
  return new Experience(EXPERIENCE_ID.ASYNC_OPERATION, {
@@ -113,11 +113,11 @@ export const getCreateSourceExperience = fireAnalyticsEvent => {
113
113
  };
114
114
 
115
115
  /**
116
- * This experience tracks when a source sync block is created and registered to the BE.
116
+ * This experience tracks when references for a sync block are fetched from the BE.
117
117
  *
118
- * Start: When the fetchSourceInfo function is called.
119
- * Success: When the fetching the data is successful within the timeout duration of start.
120
- * Failure: When the timeout duration passes without the data being successfully fetched, or the fetch fails
118
+ * Start: When the fetchReferences function is called.
119
+ * Success: When the fetching of references is successful within the timeout duration of start.
120
+ * Failure: When the timeout duration passes without references being successfully fetched, or the fetch fails
121
121
  */
122
122
  export const getFetchReferencesExperience = fireAnalyticsEvent => {
123
123
  return new Experience(EXPERIENCE_ID.ASYNC_OPERATION, {
@@ -11,7 +11,7 @@ const isSyncBlockProduct = product => {
11
11
  *
12
12
  * Format
13
13
  * - {product}/{contentId}/{uuid}
14
- * - product: a recognized `SyncBlockProduct` (e.g. 'confluence-page', 'jira-issue')
14
+ * - product: a recognized `SyncBlockProduct` (e.g. 'confluence-page', 'jira-work-item')
15
15
  * - contentId: the host content identifier (e.g. page ID or issue ID)
16
16
  * - uuid: the UUID for the specific synced block instance
17
17
  *
@@ -24,7 +24,7 @@ const isSyncBlockProduct = product => {
24
24
  * - No extra segments; returns `undefined` on any invalid input
25
25
  *
26
26
  * Notes
27
- * - `product` is a qualified domain like 'confluence-page' or 'jira-issue',
27
+ * - `product` is a qualified domain like 'confluence-page' or 'jira-work-item',
28
28
  * not just 'confluence' or 'jira'.
29
29
  */
30
30
 
@@ -1,7 +1,10 @@
1
- const parseRetryAfter = retryAfter => {
1
+ import { fg } from '@atlaskit/platform-feature-flags';
2
+ import { functionWithCondition } from '@atlaskit/platform-feature-flags-react';
3
+ const MAX_RETRY_DELAY = 30000;
4
+ const parseRetryAfterBase = retryAfter => {
2
5
  let newDelay;
3
6
 
4
- // retryAfter can either be in ms or HTTP date
7
+ // retryAfter can either be in seconds or HTTP date
5
8
  const parsedRetryAfter = parseInt(retryAfter);
6
9
  if (!isNaN(parsedRetryAfter)) {
7
10
  newDelay = parsedRetryAfter * 1000;
@@ -14,16 +17,33 @@ const parseRetryAfter = retryAfter => {
14
17
  }
15
18
  return newDelay;
16
19
  };
20
+ const parseRetryAfterPatched = retryAfter => {
21
+ // retryAfter can either be in seconds or HTTP date
22
+ const parsedRetryAfter = parseInt(retryAfter, 10);
23
+ if (!isNaN(parsedRetryAfter) && parsedRetryAfter > 0) {
24
+ return parsedRetryAfter * 1000;
25
+ }
26
+ const retryDate = new Date(retryAfter);
27
+ if (isNaN(retryDate.getTime())) {
28
+ return undefined;
29
+ }
30
+ const delayFromDate = retryDate.getTime() - Date.now();
31
+ if (delayFromDate > 0) {
32
+ return delayFromDate;
33
+ }
34
+ return undefined;
35
+ };
36
+ const parseRetryAfter = functionWithCondition(() => fg('platform_synced_block_patch_4'), parseRetryAfterPatched, parseRetryAfterBase);
17
37
  export const fetchWithRetry = async (url, options, retriesRemaining = 3, delay = 1000) => {
38
+ var _ref;
18
39
  const response = await fetch(url, options);
19
40
  const shouldRetry = !response.ok && response.status === 429 && retriesRemaining > 1;
20
41
  if (!shouldRetry) {
21
42
  return response;
22
43
  }
23
44
  const retryAfter = response.headers.get('Retry-After');
24
- await new Promise(resolve => {
25
- var _ref;
26
- return setTimeout(resolve, (_ref = retryAfter ? parseRetryAfter(retryAfter) : undefined) !== null && _ref !== void 0 ? _ref : delay);
27
- });
45
+ const parsedDelay = (_ref = retryAfter ? parseRetryAfter(retryAfter) : undefined) !== null && _ref !== void 0 ? _ref : delay;
46
+ const retryDelay = fg('platform_synced_block_patch_4') ? Math.min(parsedDelay, MAX_RETRY_DELAY) : parsedDelay;
47
+ await new Promise(resolve => setTimeout(resolve, retryDelay));
28
48
  return fetchWithRetry(url, options, retriesRemaining - 1, delay * 2);
29
49
  };
@@ -30,7 +30,7 @@ export const convertPMNodeToSyncBlockNode = node => {
30
30
  return createSyncBlockNode(node.attrs.localId, node.attrs.resourceId);
31
31
  };
32
32
  export const convertPMNodesToSyncBlockNodes = nodes => {
33
- return nodes.map(node => convertPMNodeToSyncBlockNode(node)).filter(node => node !== undefined) || [];
33
+ return nodes.map(node => convertPMNodeToSyncBlockNode(node)).filter(node => node !== undefined);
34
34
  };
35
35
 
36
36
  /*
@@ -1,5 +1,6 @@
1
+ import { SYNC_BLOCK_PRODUCTS } from '../common/consts';
1
2
  export const normaliseSyncBlockProduct = value => {
2
- return value === 'confluence-page' || value === 'jira-work-item' ? value : undefined;
3
+ return SYNC_BLOCK_PRODUCTS.includes(value) ? value : undefined;
3
4
  };
4
5
  export const normaliseSyncBlockStatus = value => {
5
6
  return value === 'active' || value === 'unpublished' || value === 'deleted' ? value : undefined;
@@ -123,7 +123,7 @@ var BATCH_RETRIEVE_BLOCKS_OPERATION_NAME = 'EDITOR_SYNCED_BLOCK_BATCH_RETRIEVE_B
123
123
  var GET_BLOCK_REFERENCES_OPERATION_NAME = 'EDITOR_SYNCED_BLOCK_GET_REFERENCES';
124
124
  var GET_BLOCK_OPERATION_NAME = 'EDITOR_SYNCED_BLOCK_GET_BLOCK';
125
125
  var buildGetDocumentReferenceBlocksQuery = function buildGetDocumentReferenceBlocksQuery(documentAri) {
126
- return "query ".concat(GET_DOCUMENT_REFERENCE_BLOCKS_OPERATION_NAME, " {\n\tblockService_getDocumentReferenceBlocks(documentAri: \"").concat(documentAri, "\") {\n\t\tblocks {\n\t\t\tblockAri\n\t\t\tblockInstanceId\n\t\t\tcontent\n\t\t\tcontentUpdatedAt\n\t\t\tcreatedAt\n\t\t\tcreatedBy\n\t\t\tproduct\n\t\t\tsourceAri\n\t\t\tstatus\n\t\t\tversion\n\t\t}\n\t\terrors {\n\t\t\tblockAri\n\t\t\tcode\n\t\t\treason\n\t\t}\n\t}\n}");
126
+ return "query ".concat(GET_DOCUMENT_REFERENCE_BLOCKS_OPERATION_NAME, " {\n\tblockService_getDocumentReferenceBlocks(documentAri: ").concat(fg('platform_synced_block_patch_4') ? JSON.stringify(documentAri) : "\"".concat(documentAri, "\""), ") {\n\t\tblocks {\n\t\t\tblockAri\n\t\t\tblockInstanceId\n\t\t\tcontent\n\t\t\tcontentUpdatedAt\n\t\t\tcreatedAt\n\t\t\tcreatedBy\n\t\t\tproduct\n\t\t\tsourceAri\n\t\t\tstatus\n\t\t\tversion\n\t\t}\n\t\terrors {\n\t\t\tblockAri\n\t\t\tcode\n\t\t\treason\n\t\t}\n\t}\n}");
127
127
  };
128
128
  var buildGetBlockQuery = function buildGetBlockQuery(blockAri) {
129
129
  return "query ".concat(GET_BLOCK_OPERATION_NAME, " {\n\tblockService_getBlock(blockAri: ").concat(JSON.stringify(blockAri), ") {\n\t\tblockAri\n\t\tblockInstanceId\n\t\tcontent\n\t\tcontentUpdatedAt\n\t\tcreatedAt\n\t\tcreatedBy\n\t\tdeletionReason\n\t\tproduct\n\t\tsourceAri\n\t\tstatus\n\t\tversion\n\t}\n}");
@@ -154,11 +154,17 @@ var buildDeleteBlockMutation = function buildDeleteBlockMutation(blockAri, delet
154
154
  * 'jira-work-item' -> 'JIRA_WORK_ITEM'
155
155
  */
156
156
  var convertProductToGraphQLEnum = function convertProductToGraphQLEnum(product) {
157
- if (product === 'confluence-page') {
158
- return 'CONFLUENCE_PAGE';
157
+ switch (product) {
158
+ case 'confluence-page':
159
+ return 'CONFLUENCE_PAGE';
160
+ case 'jira-work-item':
161
+ return 'JIRA_WORK_ITEM';
162
+ default:
163
+ {
164
+ var exhaustiveCheck = product;
165
+ throw new Error("Unsupported product: ".concat(exhaustiveCheck));
166
+ }
159
167
  }
160
- // product must be 'jira-work-item' at this point
161
- return 'JIRA_WORK_ITEM';
162
168
  };
163
169
  var buildCreateBlockMutation = function buildCreateBlockMutation(blockAri, blockInstanceId, content, product, sourceAri, stepVersion, status) {
164
170
  var inputParts = ["blockAri: ".concat(JSON.stringify(blockAri)), "blockInstanceId: ".concat(JSON.stringify(blockInstanceId)), "content: ".concat(JSON.stringify(content)), "product: ".concat(convertProductToGraphQLEnum(product)), "sourceAri: ".concat(JSON.stringify(sourceAri))];
@@ -329,8 +335,8 @@ export var batchRetrieveSyncedBlocks = /*#__PURE__*/function () {
329
335
  }();
330
336
  export var deleteSyncedBlock = /*#__PURE__*/function () {
331
337
  var _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(_ref6) {
332
- var _result$data3;
333
- var blockAri, deleteReason, bodyData, url, response, result;
338
+ var _result$data3, _result$data4;
339
+ var blockAri, deleteReason, bodyData, url, response, result, isDeleted;
334
340
  return _regeneratorRuntime.wrap(function _callee4$(_context4) {
335
341
  while (1) switch (_context4.prev = _context4.next) {
336
342
  case 0:
@@ -366,12 +372,13 @@ export var deleteSyncedBlock = /*#__PURE__*/function () {
366
372
  return e.message;
367
373
  }).join(', '));
368
374
  case 13:
369
- if ((_result$data3 = result.data) !== null && _result$data3 !== void 0 && _result$data3.blockService_deleteBlock.deleted) {
370
- _context4.next = 15;
375
+ isDeleted = fg('platform_synced_block_patch_4') ? (_result$data3 = result.data) === null || _result$data3 === void 0 || (_result$data3 = _result$data3.blockService_deleteBlock) === null || _result$data3 === void 0 ? void 0 : _result$data3.deleted : (_result$data4 = result.data) === null || _result$data4 === void 0 ? void 0 : _result$data4.blockService_deleteBlock.deleted;
376
+ if (isDeleted) {
377
+ _context4.next = 16;
371
378
  break;
372
379
  }
373
380
  throw new Error('Block deletion failed; deleted flag is false');
374
- case 15:
381
+ case 16:
375
382
  case "end":
376
383
  return _context4.stop();
377
384
  }
@@ -430,7 +437,7 @@ export var updateSyncedBlock = /*#__PURE__*/function () {
430
437
  }();
431
438
  export var createSyncedBlock = /*#__PURE__*/function () {
432
439
  var _ref1 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6(_ref0) {
433
- var _result$data4;
440
+ var _result$data5;
434
441
  var blockAri, blockInstanceId, sourceAri, product, content, stepVersion, status, bodyData, url, response, result;
435
442
  return _regeneratorRuntime.wrap(function _callee6$(_context6) {
436
443
  while (1) switch (_context6.prev = _context6.next) {
@@ -467,7 +474,7 @@ export var createSyncedBlock = /*#__PURE__*/function () {
467
474
  return e.message;
468
475
  }).join(', '));
469
476
  case 13:
470
- if ((_result$data4 = result.data) !== null && _result$data4 !== void 0 && _result$data4.blockService_createBlock) {
477
+ if ((_result$data5 = result.data) !== null && _result$data5 !== void 0 && _result$data5.blockService_createBlock) {
471
478
  _context6.next = 15;
472
479
  break;
473
480
  }
@@ -486,7 +493,7 @@ export var createSyncedBlock = /*#__PURE__*/function () {
486
493
  }();
487
494
  export var updateReferenceSyncedBlockOnDocument = /*#__PURE__*/function () {
488
495
  var _ref11 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee7(_ref10) {
489
- var documentAri, blocks, _ref10$noContent, noContent, bodyData, url, response, result, _result$data5;
496
+ var documentAri, blocks, _ref10$noContent, noContent, bodyData, url, response, result, _result$data6;
490
497
  return _regeneratorRuntime.wrap(function _callee7$(_context7) {
491
498
  while (1) switch (_context7.prev = _context7.next) {
492
499
  case 0:
@@ -527,7 +534,7 @@ export var updateReferenceSyncedBlockOnDocument = /*#__PURE__*/function () {
527
534
  _context7.next = 17;
528
535
  break;
529
536
  }
530
- if ((_result$data5 = result.data) !== null && _result$data5 !== void 0 && _result$data5.blockService_updateDocumentReferences) {
537
+ if ((_result$data6 = result.data) !== null && _result$data6 !== void 0 && _result$data6.blockService_updateDocumentReferences) {
531
538
  _context7.next = 16;
532
539
  break;
533
540
  }
@@ -546,7 +553,7 @@ export var updateReferenceSyncedBlockOnDocument = /*#__PURE__*/function () {
546
553
  }();
547
554
  export var getReferenceSyncedBlocksByBlockAri = /*#__PURE__*/function () {
548
555
  var _ref13 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8(_ref12) {
549
- var _result$data6;
556
+ var _result$data7;
550
557
  var blockAri, bodyData, url, response, result, graphqlResponse;
551
558
  return _regeneratorRuntime.wrap(function _callee8$(_context8) {
552
559
  while (1) switch (_context8.prev = _context8.next) {
@@ -583,7 +590,7 @@ export var getReferenceSyncedBlocksByBlockAri = /*#__PURE__*/function () {
583
590
  return e.message;
584
591
  }).join(', '));
585
592
  case 13:
586
- if ((_result$data6 = result.data) !== null && _result$data6 !== void 0 && _result$data6.blockService_getReferences) {
593
+ if ((_result$data7 = result.data) !== null && _result$data7 !== void 0 && _result$data7.blockService_getReferences) {
587
594
  _context8.next = 15;
588
595
  break;
589
596
  }
@@ -4,6 +4,7 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
4
4
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5
5
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
6
6
  import { logException } from '@atlaskit/editor-common/monitoring';
7
+ import { fg } from '@atlaskit/platform-feature-flags';
7
8
  import { fetchWithRetry } from '../../utils/retry';
8
9
  var COMMON_HEADERS = {
9
10
  'Content-Type': 'application/json',
@@ -59,7 +60,7 @@ var getContentMediaSession = /*#__PURE__*/function () {
59
60
  }();
60
61
  export var fetchMediaToken = /*#__PURE__*/function () {
61
62
  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(contentId) {
62
- var _response$data, _contentData$token, response, contentData, token, configuration, collection;
63
+ var _response$data, _contentData$token, response, contentData, token, configuration, collection, errorMsg;
63
64
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
64
65
  while (1) switch (_context2.prev = _context2.next) {
65
66
  case 0:
@@ -78,19 +79,20 @@ export var fetchMediaToken = /*#__PURE__*/function () {
78
79
  }
79
80
  throw new Error('Failed to get content media session data');
80
81
  case 10:
81
- return _context2.abrupt("return", Promise.resolve({
82
+ return _context2.abrupt("return", {
82
83
  config: configuration,
83
84
  token: token,
84
85
  collectionId: collection
85
- }));
86
+ });
86
87
  case 13:
87
88
  _context2.prev = 13;
88
89
  _context2.t0 = _context2["catch"](0);
89
90
  logException(_context2.t0, {
90
91
  location: 'editor-synced-block-provider/fetchMediaToken'
91
92
  });
92
- throw new Error("Failed to get content media session: ".concat(_context2.t0));
93
- case 17:
93
+ errorMsg = fg('platform_synced_block_patch_4') ? _context2.t0 instanceof Error ? _context2.t0.message : String(_context2.t0) : String(_context2.t0);
94
+ throw new Error("Failed to get content media session: ".concat(errorMsg));
95
+ case 18:
94
96
  case "end":
95
97
  return _context2.stop();
96
98
  }
@@ -1,6 +1,8 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
- import { useEffect, useState } from 'react';
3
- export var useFetchSyncBlockTitle = function useFetchSyncBlockTitle(manager, syncBlockNode) {
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
4
+ import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react';
5
+ var useFetchSyncBlockTitleBase = function useFetchSyncBlockTitleBase(manager, syncBlockNode) {
4
6
  // Initialize state from cache to prevent flickering during re-renders
5
7
  var _useState = useState(function () {
6
8
  var _cachedData$data;
@@ -26,4 +28,40 @@ export var useFetchSyncBlockTitle = function useFetchSyncBlockTitle(manager, syn
26
28
  };
27
29
  }, [manager, syncBlockNode]);
28
30
  return sourceTitle;
29
- };
31
+ };
32
+ var useFetchSyncBlockTitlePatched = function useFetchSyncBlockTitlePatched(manager, syncBlockNode) {
33
+ var _syncBlockNode$attrs, _syncBlockNode$attrs2;
34
+ var nodeRef = useRef(syncBlockNode);
35
+ nodeRef.current = syncBlockNode;
36
+ var nodeTypeName = syncBlockNode.type.name;
37
+ var resourceId = (_syncBlockNode$attrs = syncBlockNode.attrs) === null || _syncBlockNode$attrs === void 0 ? void 0 : _syncBlockNode$attrs.resourceId;
38
+ var localId = (_syncBlockNode$attrs2 = syncBlockNode.attrs) === null || _syncBlockNode$attrs2 === void 0 ? void 0 : _syncBlockNode$attrs2.localId;
39
+
40
+ // Initialize state from cache to prevent flickering during re-renders
41
+ var _useState3 = useState(function () {
42
+ var _cachedData$data2;
43
+ if (nodeTypeName !== 'syncBlock') {
44
+ return undefined;
45
+ }
46
+ if (!resourceId) {
47
+ return undefined;
48
+ }
49
+ var cachedData = manager.referenceManager.getFromCache(resourceId);
50
+ return cachedData === null || cachedData === void 0 || (_cachedData$data2 = cachedData.data) === null || _cachedData$data2 === void 0 ? void 0 : _cachedData$data2.sourceTitle;
51
+ }),
52
+ _useState4 = _slicedToArray(_useState3, 2),
53
+ sourceTitle = _useState4[0],
54
+ setSourceTitle = _useState4[1];
55
+ useEffect(function () {
56
+ var unsubscribe = manager.referenceManager.subscribeToSourceTitle(nodeRef.current, function (title) {
57
+ setSourceTitle(title);
58
+ });
59
+ return function () {
60
+ unsubscribe();
61
+ };
62
+ }, [manager, nodeTypeName, resourceId, localId]);
63
+ return sourceTitle;
64
+ };
65
+ export var useFetchSyncBlockTitle = conditionalHooksFactory(function () {
66
+ return fg('platform_synced_block_patch_4');
67
+ }, useFetchSyncBlockTitlePatched, useFetchSyncBlockTitleBase);
@@ -1,5 +1,8 @@
1
1
  import { useEffect } from 'react';
2
2
  export var useHandleContentChanges = function useHandleContentChanges(manager, syncBlockNode) {
3
+ // syncBlockNode is intentionally in deps — its reference changes when the
4
+ // node content is modified by a ProseMirror transaction, which is exactly
5
+ // when the source manager cache needs to be updated.
3
6
  useEffect(function () {
4
7
  manager.sourceManager.updateSyncBlockData(syncBlockNode);
5
8
  }, [manager, syncBlockNode]);
@@ -10,8 +10,9 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
10
10
  import _regeneratorRuntime from "@babel/runtime/regenerator";
11
11
  function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
12
12
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
13
- import { useMemo } from 'react';
13
+ import { useMemo, useRef } from 'react';
14
14
  import { fg } from '@atlaskit/platform-feature-flags';
15
+ import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react';
15
16
  import { getProductFromSourceAri } from '../clients/block-service/ari';
16
17
  import { getPageIdAndTypeFromConfluencePageAri } from '../clients/confluence/ari';
17
18
  import { fetchConfluencePageInfo } from '../clients/confluence/sourceInfo';
@@ -444,7 +445,7 @@ var createSyncedBlockProvider = function createSyncedBlockProvider(_ref) {
444
445
  writeProvider = _ref.writeProvider;
445
446
  return new SyncedBlockProvider(fetchProvider, writeProvider);
446
447
  };
447
- export var useMemoizedSyncedBlockProvider = function useMemoizedSyncedBlockProvider(_ref2) {
448
+ var useMemoizedSyncedBlockProviderBase = function useMemoizedSyncedBlockProviderBase(_ref2) {
448
449
  var fetchProvider = _ref2.fetchProvider,
449
450
  writeProvider = _ref2.writeProvider,
450
451
  providerOptions = _ref2.providerOptions,
@@ -461,4 +462,33 @@ export var useMemoizedSyncedBlockProvider = function useMemoizedSyncedBlockProvi
461
462
  syncBlockProvider.setSSRData(ssrData);
462
463
  }
463
464
  return syncBlockProvider;
464
- };
465
+ };
466
+ var useMemoizedSyncedBlockProviderPatched = function useMemoizedSyncedBlockProviderPatched(_ref3) {
467
+ var fetchProvider = _ref3.fetchProvider,
468
+ writeProvider = _ref3.writeProvider,
469
+ providerOptions = _ref3.providerOptions,
470
+ getSSRData = _ref3.getSSRData;
471
+ var syncBlockProvider = useMemo(function () {
472
+ return createSyncedBlockProvider({
473
+ fetchProvider: fetchProvider,
474
+ writeProvider: writeProvider
475
+ });
476
+ }, [fetchProvider, writeProvider]);
477
+ var prevProviderOptionsRef = useRef(undefined);
478
+ if (providerOptions !== prevProviderOptionsRef.current) {
479
+ prevProviderOptionsRef.current = providerOptions;
480
+ syncBlockProvider.setProviderOptions(providerOptions);
481
+ }
482
+ var prevSSRDataRef = useRef(undefined);
483
+ var ssrData = getSSRData === null || getSSRData === void 0 ? void 0 : getSSRData();
484
+ if (ssrData !== prevSSRDataRef.current) {
485
+ prevSSRDataRef.current = ssrData;
486
+ if (ssrData) {
487
+ syncBlockProvider.setSSRData(ssrData);
488
+ }
489
+ }
490
+ return syncBlockProvider;
491
+ };
492
+ export var useMemoizedSyncedBlockProvider = conditionalHooksFactory(function () {
493
+ return fg('platform_synced_block_patch_4');
494
+ }, useMemoizedSyncedBlockProviderPatched, useMemoizedSyncedBlockProviderBase);
@@ -385,6 +385,9 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
385
385
  value: function handleGraphQLSubscriptionUpdate(syncBlockInstance) {
386
386
  var _this5 = this;
387
387
  if (!syncBlockInstance.resourceId) {
388
+ if (fg('platform_synced_block_patch_4')) {
389
+ return;
390
+ }
388
391
  throw new Error('Sync block instance provided to graphql subscription update missing resource id');
389
392
  }
390
393
  var existingSyncBlock = this.getFromCache(syncBlockInstance.resourceId);
@@ -5,8 +5,10 @@ import _createClass from "@babel/runtime/helpers/createClass";
5
5
  import _regeneratorRuntime from "@babel/runtime/regenerator";
6
6
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
7
7
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
- import { useMemo } from 'react';
8
+ import { useMemo, useRef } from 'react';
9
9
  import { logException } from '@atlaskit/editor-common/monitoring';
10
+ import { fg } from '@atlaskit/platform-feature-flags';
11
+ import { conditionalHooksFactory } from '@atlaskit/platform-feature-flags-react';
10
12
  import { getProductFromSourceAri } from '../clients/block-service/ari';
11
13
  import { SyncBlockError } from '../common/types';
12
14
  import { fetchReferencesErrorPayload } from '../utils/errorHandling';
@@ -22,7 +24,7 @@ import { SourceSyncBlockStoreManager } from './sourceSyncBlockStoreManager';
22
24
  export var SyncBlockStoreManager = /*#__PURE__*/function () {
23
25
  function SyncBlockStoreManager(dataProvider) {
24
26
  _classCallCheck(this, SyncBlockStoreManager);
25
- // In future, if reference manager needs to reach to source manager and read it's current in memorey cache
27
+ // In future, if reference manager needs to reach to source manager and read its current in memory cache
26
28
  // we can pass the source manager as a parameter to the reference manager constructor
27
29
  this.sourceSyncBlockStoreManager = new SourceSyncBlockStoreManager(dataProvider);
28
30
  this.referenceSyncBlockStoreManager = new ReferenceSyncBlockStoreManager(dataProvider);
@@ -194,11 +196,24 @@ export var SyncBlockStoreManager = /*#__PURE__*/function () {
194
196
  var createSyncBlockStoreManager = function createSyncBlockStoreManager(dataProvider) {
195
197
  return new SyncBlockStoreManager(dataProvider);
196
198
  };
197
- export var useMemoizedSyncBlockStoreManager = function useMemoizedSyncBlockStoreManager(dataProvider, fireAnalyticsEvent) {
199
+ var useMemoizedSyncBlockStoreManagerBase = function useMemoizedSyncBlockStoreManagerBase(dataProvider, fireAnalyticsEvent) {
198
200
  var syncBlockStoreManager = useMemo(function () {
199
- var syncBlockStoreManager = createSyncBlockStoreManager(dataProvider);
200
- return syncBlockStoreManager;
201
+ return createSyncBlockStoreManager(dataProvider);
201
202
  }, [dataProvider]);
202
203
  syncBlockStoreManager.setFireAnalyticsEvent(fireAnalyticsEvent);
203
204
  return syncBlockStoreManager;
204
- };
205
+ };
206
+ var useMemoizedSyncBlockStoreManagerPatched = function useMemoizedSyncBlockStoreManagerPatched(dataProvider, fireAnalyticsEvent) {
207
+ var syncBlockStoreManager = useMemo(function () {
208
+ return createSyncBlockStoreManager(dataProvider);
209
+ }, [dataProvider]);
210
+ var prevFireAnalyticsEventRef = useRef(undefined);
211
+ if (fireAnalyticsEvent !== prevFireAnalyticsEventRef.current) {
212
+ prevFireAnalyticsEventRef.current = fireAnalyticsEvent;
213
+ syncBlockStoreManager.setFireAnalyticsEvent(fireAnalyticsEvent);
214
+ }
215
+ return syncBlockStoreManager;
216
+ };
217
+ export var useMemoizedSyncBlockStoreManager = conditionalHooksFactory(function () {
218
+ return fg('platform_synced_block_patch_4');
219
+ }, useMemoizedSyncBlockStoreManagerPatched, useMemoizedSyncBlockStoreManagerBase);