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

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 (40) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/clients/block-service/blockSubscription.js +3 -53
  3. package/dist/cjs/clients/block-service/sharedSubscriptionUtils.js +82 -0
  4. package/dist/cjs/index.js +33 -0
  5. package/dist/cjs/providers/block-service/blockServiceAPI.js +22 -6
  6. package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +52 -85
  7. package/dist/cjs/utils/__generated__/relaySubscriptionUtilsSubscription.graphql.js +94 -0
  8. package/dist/cjs/utils/relayResponseConverter.js +76 -0
  9. package/dist/cjs/utils/relaySubscriptionUtils.js +130 -0
  10. package/dist/es2019/clients/block-service/blockSubscription.js +2 -67
  11. package/dist/es2019/clients/block-service/sharedSubscriptionUtils.js +91 -0
  12. package/dist/es2019/index.js +4 -0
  13. package/dist/es2019/providers/block-service/blockServiceAPI.js +22 -6
  14. package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +41 -62
  15. package/dist/es2019/utils/__generated__/relaySubscriptionUtilsSubscription.graphql.js +88 -0
  16. package/dist/es2019/utils/relayResponseConverter.js +69 -0
  17. package/dist/es2019/utils/relaySubscriptionUtils.js +125 -0
  18. package/dist/esm/clients/block-service/blockSubscription.js +2 -52
  19. package/dist/esm/clients/block-service/sharedSubscriptionUtils.js +76 -0
  20. package/dist/esm/index.js +4 -0
  21. package/dist/esm/providers/block-service/blockServiceAPI.js +22 -6
  22. package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +52 -85
  23. package/dist/esm/utils/__generated__/relaySubscriptionUtilsSubscription.graphql.js +88 -0
  24. package/dist/esm/utils/relayResponseConverter.js +69 -0
  25. package/dist/esm/utils/relaySubscriptionUtils.js +123 -0
  26. package/dist/types/clients/block-service/blockSubscription.d.ts +1 -26
  27. package/dist/types/clients/block-service/sharedSubscriptionUtils.d.ts +61 -0
  28. package/dist/types/index.d.ts +4 -0
  29. package/dist/types/providers/block-service/blockServiceAPI.d.ts +7 -2
  30. package/dist/types/utils/__generated__/relaySubscriptionUtilsSubscription.graphql.d.ts +31 -0
  31. package/dist/types/utils/relayResponseConverter.d.ts +47 -0
  32. package/dist/types/utils/relaySubscriptionUtils.d.ts +61 -0
  33. package/dist/types-ts4.5/clients/block-service/blockSubscription.d.ts +1 -26
  34. package/dist/types-ts4.5/clients/block-service/sharedSubscriptionUtils.d.ts +61 -0
  35. package/dist/types-ts4.5/index.d.ts +4 -0
  36. package/dist/types-ts4.5/providers/block-service/blockServiceAPI.d.ts +7 -2
  37. package/dist/types-ts4.5/utils/__generated__/relaySubscriptionUtilsSubscription.graphql.d.ts +31 -0
  38. package/dist/types-ts4.5/utils/relayResponseConverter.d.ts +47 -0
  39. package/dist/types-ts4.5/utils/relaySubscriptionUtils.d.ts +61 -0
  40. package/package.json +3 -5
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.convertParsedDataToSyncBlockInstance = convertParsedDataToSyncBlockInstance;
7
+ exports.convertRelayResponseToSyncBlockInstance = convertRelayResponseToSyncBlockInstance;
8
+ var _sharedSubscriptionUtils = require("../clients/block-service/sharedSubscriptionUtils");
9
+ var _validValue = require("./validValue");
10
+ /**
11
+ * Converts parsed subscription data to SyncBlockInstance format.
12
+ *
13
+ * @param parsed - The parsed subscription data
14
+ * @param resourceId - The resource ID for the block
15
+ * @returns A SyncBlockInstance
16
+ */
17
+ function convertParsedDataToSyncBlockInstance(parsed, resourceId) {
18
+ return {
19
+ data: {
20
+ content: parsed.content,
21
+ contentUpdatedAt: parsed.contentUpdatedAt,
22
+ resourceId: parsed.blockAri,
23
+ blockInstanceId: parsed.blockInstanceId,
24
+ sourceAri: parsed.sourceAri,
25
+ product: parsed.product,
26
+ createdAt: parsed.createdAt,
27
+ createdBy: parsed.createdBy,
28
+ status: (0, _validValue.normaliseSyncBlockStatus)(parsed.status)
29
+ },
30
+ resourceId: resourceId
31
+ };
32
+ }
33
+
34
+ /**
35
+ * Converts a Relay subscription response to SyncBlockInstance format using shared parsing logic.
36
+
37
+ * @param response - The Relay subscription response containing block update data
38
+ * @param resourceId - The resource ID for the block
39
+ * @returns A SyncBlockInstance or null if parsing fails
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * // In a Relay subscription handler
44
+ * onNext: (response) => {
45
+ * if (response?.blockService_onBlockUpdated) {
46
+ * const syncBlockInstance = convertRelayResponseToSyncBlockInstance(
47
+ * response.blockService_onBlockUpdated,
48
+ * resourceId,
49
+ * );
50
+ * if (syncBlockInstance) {
51
+ * onUpdate(syncBlockInstance);
52
+ * }
53
+ * }
54
+ * }
55
+ * ```
56
+ */
57
+ function convertRelayResponseToSyncBlockInstance(response, resourceId) {
58
+ var _response$contentUpda, _response$deletionRea;
59
+ var payload = {
60
+ blockAri: response.blockAri,
61
+ blockInstanceId: response.blockInstanceId,
62
+ content: response.content,
63
+ contentUpdatedAt: (_response$contentUpda = response.contentUpdatedAt) !== null && _response$contentUpda !== void 0 ? _response$contentUpda : undefined,
64
+ createdAt: response.createdAt,
65
+ createdBy: response.createdBy,
66
+ deletionReason: (_response$deletionRea = response.deletionReason) !== null && _response$deletionRea !== void 0 ? _response$deletionRea : undefined,
67
+ product: response.product,
68
+ sourceAri: response.sourceAri,
69
+ status: response.status
70
+ };
71
+ var parsed = (0, _sharedSubscriptionUtils.parseSubscriptionPayload)(payload);
72
+ if (!parsed) {
73
+ return null;
74
+ }
75
+ return convertParsedDataToSyncBlockInstance(parsed, resourceId);
76
+ }
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.createRelayBlockSubscription = createRelayBlockSubscription;
8
+ exports.createRelaySubscriptionFunction = createRelaySubscriptionFunction;
9
+ var _relayRuntime = require("relay-runtime");
10
+ var _ari = require("../clients/block-service/ari");
11
+ var _blockSubscription = require("../clients/block-service/blockSubscription");
12
+ var _relaySubscriptionUtilsSubscription = _interopRequireDefault(require("./__generated__/relaySubscriptionUtilsSubscription.graphql"));
13
+ var _relayResponseConverter = require("./relayResponseConverter");
14
+ /**
15
+ * Configuration for creating a Relay block subscription.
16
+ */
17
+
18
+ /**
19
+ * Creates a Relay-based block subscription without needing to wrap providers.
20
+ * This is a clean utility function that can be used directly in components or hooks.
21
+ *
22
+ * @param config - Configuration for the subscription
23
+ * @returns An unsubscribe function to dispose the subscription
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const unsubscribe = createRelayBlockSubscription({
28
+ * relayEnvironment: environment,
29
+ * cloudId: 'my-cloud-id',
30
+ * resourceId: 'my-resource-id',
31
+ * onUpdate: (blockInstance) => {
32
+ * console.log('Block updated:', blockInstance);
33
+ * },
34
+ * onError: (error) => {
35
+ * console.error('Subscription error:', error);
36
+ * }
37
+ * });
38
+ *
39
+ * // Later, when component unmounts or subscription is no longer needed
40
+ * unsubscribe();
41
+ * ```
42
+ */
43
+ function createRelayBlockSubscription(config) {
44
+ var relayEnvironment = config.relayEnvironment,
45
+ cloudId = config.cloudId,
46
+ resourceId = config.resourceId,
47
+ onUpdate = config.onUpdate,
48
+ _onError = config.onError;
49
+
50
+ // Convert resourceId to blockAri for the subscription
51
+ var blockAri = (0, _ari.generateBlockAriFromReference)({
52
+ cloudId: cloudId,
53
+ resourceId: resourceId
54
+ });
55
+ var subscriptionQuery = _relaySubscriptionUtilsSubscription.default;
56
+
57
+ // Try to use Relay subscription first
58
+ try {
59
+ var disposable = (0, _relayRuntime.requestSubscription)(relayEnvironment, {
60
+ subscription: subscriptionQuery,
61
+ variables: {
62
+ resourceId: blockAri
63
+ },
64
+ onNext: function onNext(response) {
65
+ if (response !== null && response !== void 0 && response.blockService_onBlockUpdated) {
66
+ var syncBlockInstance = (0, _relayResponseConverter.convertRelayResponseToSyncBlockInstance)(response.blockService_onBlockUpdated, resourceId);
67
+ if (syncBlockInstance) {
68
+ onUpdate(syncBlockInstance);
69
+ } else {
70
+ _onError === null || _onError === void 0 || _onError(new Error('Failed to parse Relay block subscription payload'));
71
+ }
72
+ }
73
+ },
74
+ onError: function onError(error) {
75
+ _onError === null || _onError === void 0 || _onError(error);
76
+ }
77
+ });
78
+
79
+ // If subscription was successfully created, return the unsubscribe function
80
+ if (disposable) {
81
+ return function () {
82
+ disposable.dispose();
83
+ };
84
+ }
85
+ } catch (error) {
86
+ // If requestSubscription throws, fall back to WebSocket
87
+ _onError === null || _onError === void 0 || _onError(error instanceof Error ? error : new Error('Relay subscription failed'));
88
+ }
89
+
90
+ // Fallback to WebSocket subscription when Relay subscriptions aren't available
91
+ return (0, _blockSubscription.subscribeToBlockUpdates)(blockAri, function (parsedData) {
92
+ var syncBlockInstance = (0, _relayResponseConverter.convertParsedDataToSyncBlockInstance)(parsedData, parsedData.resourceId);
93
+ onUpdate(syncBlockInstance);
94
+ }, function (error) {
95
+ _onError === null || _onError === void 0 || _onError(error);
96
+ });
97
+ }
98
+
99
+ /**
100
+ * Hook-like function to create a subscription function that can be passed to providers.
101
+ * This creates a function with the same signature as subscribeToBlockUpdates that uses Relay.
102
+ *
103
+ * @param cloudId - Cloud ID for generating block ARIs
104
+ * @param relayEnvironment - Optional Relay environment. If not provided, will attempt to use global environment
105
+ * @returns A function that can be used as subscribeToBlockUpdates in provider configurations
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * const relaySubscribeToBlockUpdates = createRelaySubscriptionFunction(cloudId, environment);
110
+ *
111
+ * // Can be used directly as a subscribeToBlockUpdates replacement
112
+ * const unsubscribe = relaySubscribeToBlockUpdates(resourceId, onUpdate, onError);
113
+ * ```
114
+ */
115
+ function createRelaySubscriptionFunction(cloudId, relayEnvironment) {
116
+ return function (resourceId, onUpdate, onError) {
117
+ var environment = relayEnvironment;
118
+ if (!environment) {
119
+ onError === null || onError === void 0 || onError(new Error('Relay environment not available'));
120
+ return function () {};
121
+ }
122
+ return createRelayBlockSubscription({
123
+ relayEnvironment: environment,
124
+ cloudId: cloudId,
125
+ resourceId: resourceId,
126
+ onUpdate: onUpdate,
127
+ onError: onError
128
+ });
129
+ };
130
+ }
@@ -1,6 +1,6 @@
1
1
  import { createClient } from 'graphql-ws';
2
2
  import { isSSR } from '@atlaskit/editor-common/core-utils';
3
- import { convertContentUpdatedAt } from '../../utils/utils';
3
+ import { BLOCK_SERVICE_SUBSCRIPTION_QUERY, parseSubscriptionPayload } from './sharedSubscriptionUtils';
4
4
  const GRAPHQL_WS_ENDPOINT = '/gateway/api/graphql/subscriptions';
5
5
  let blockServiceClient = null;
6
6
  const getBlockServiceClient = () => {
@@ -19,71 +19,6 @@ const getBlockServiceClient = () => {
19
19
  }
20
20
  return blockServiceClient;
21
21
  };
22
- const SUBSCRIPTION_QUERY = `
23
- subscription EDITOR_SYNCED_BLOCK_ON_BLOCK_UPDATED($resourceId: ID!) {
24
- blockService_onBlockUpdated(resourceId: $resourceId) {
25
- blockAri
26
- blockInstanceId
27
- content
28
- contentUpdatedAt
29
- createdAt
30
- createdBy
31
- deletionReason
32
- product
33
- sourceAri
34
- status
35
- }
36
- }
37
- `;
38
- /**
39
- * Extracts the resourceId from a block ARI.
40
- * Block ARI format: ari:cloud:blocks:<cloudId>:synced-block/<resourceId>
41
- * @param blockAri - The block ARI string
42
- * @returns The resourceId portion of the ARI
43
- */
44
- const extractResourceIdFromBlockAri = blockAri => {
45
- // eslint-disable-next-line require-unicode-regexp
46
- const match = blockAri.match(/ari:cloud:blocks:[^:]+:synced-block\/(.+)$/);
47
- return (match === null || match === void 0 ? void 0 : match[1]) || null;
48
- };
49
-
50
- /**
51
- * Parses the subscription payload into a standardized format.
52
- * @param payload - The raw subscription payload
53
- * @returns Parsed block data or null if parsing fails
54
- */
55
- const parseSubscriptionPayload = payload => {
56
- try {
57
- const resourceId = extractResourceIdFromBlockAri(payload.blockAri);
58
- if (!resourceId) {
59
- return null;
60
- }
61
- let createdAt;
62
- if (payload.createdAt !== undefined && payload.createdAt !== null) {
63
- try {
64
- // BE returns microseconds, convert to milliseconds
65
- createdAt = new Date(payload.createdAt / 1000).toISOString();
66
- } catch {
67
- createdAt = undefined;
68
- }
69
- }
70
- return {
71
- blockAri: payload.blockAri,
72
- blockInstanceId: payload.blockInstanceId,
73
- content: JSON.parse(payload.content),
74
- contentUpdatedAt: convertContentUpdatedAt(payload.contentUpdatedAt),
75
- createdAt,
76
- createdBy: payload.createdBy,
77
- product: payload.product,
78
- resourceId,
79
- sourceAri: payload.sourceAri,
80
- status: payload.status
81
- };
82
- } catch {
83
- return null;
84
- }
85
- };
86
-
87
22
  /**
88
23
  * Creates a GraphQL subscription to block updates using the shared graphql-ws client.
89
24
  *
@@ -99,7 +34,7 @@ export const subscribeToBlockUpdates = (blockAri, onData, onError) => {
99
34
  return () => {};
100
35
  }
101
36
  const unsubscribe = client.subscribe({
102
- query: SUBSCRIPTION_QUERY,
37
+ query: BLOCK_SERVICE_SUBSCRIPTION_QUERY,
103
38
  variables: {
104
39
  resourceId: blockAri
105
40
  },
@@ -0,0 +1,91 @@
1
+ import { convertContentUpdatedAt } from '../../utils/utils';
2
+ /**
3
+ * Shared GraphQL subscription query for block updates.
4
+ * This is the canonical subscription query used across all implementations.
5
+ */
6
+ export const BLOCK_SERVICE_SUBSCRIPTION_QUERY = `
7
+ subscription EDITOR_SYNCED_BLOCK_ON_BLOCK_UPDATED($resourceId: ID!) {
8
+ blockService_onBlockUpdated(resourceId: $resourceId) {
9
+ blockAri
10
+ blockInstanceId
11
+ content
12
+ contentUpdatedAt
13
+ createdAt
14
+ createdBy
15
+ deletionReason
16
+ product
17
+ sourceAri
18
+ status
19
+ }
20
+ }
21
+ `;
22
+
23
+ /**
24
+ * Raw subscription payload from the GraphQL subscription.
25
+ * This represents the exact shape returned by the blockService_onBlockUpdated subscription.
26
+ */
27
+
28
+ /**
29
+ * Parsed and normalized block subscription data.
30
+ * This is the standardized format used across different subscription implementations.
31
+ */
32
+
33
+ /**
34
+ * Extracts the resourceId from a block ARI.
35
+ * Block ARI format: ari:cloud:blocks:<cloudId>:synced-block/<resourceId>
36
+ * @param blockAri - The block ARI string
37
+ * @returns The resourceId portion of the ARI
38
+ */
39
+ export const extractResourceIdFromBlockAri = blockAri => {
40
+ // eslint-disable-next-line require-unicode-regexp
41
+ const match = blockAri.match(/ari:cloud:blocks:[^:]+:synced-block\/(.+)$/);
42
+ return (match === null || match === void 0 ? void 0 : match[1]) || null;
43
+ };
44
+
45
+ /**
46
+ * Converts a timestamp to ISO string.
47
+ * @param timestamp - Timestamp in milliseconds
48
+ * @returns ISO string or undefined if conversion fails
49
+ */
50
+ export const convertTimestampToISOString = timestamp => {
51
+ if (timestamp === undefined || timestamp === null) {
52
+ return undefined;
53
+ }
54
+ try {
55
+ return new Date(timestamp).toISOString();
56
+ } catch {
57
+ return undefined;
58
+ }
59
+ };
60
+
61
+ /**
62
+ * Parses the raw subscription payload into a standardized format.
63
+ * This function handles all the data transformation and error handling consistently
64
+ * across different subscription implementations.
65
+ *
66
+ * @param payload - The raw subscription payload
67
+ * @returns Parsed block data or null if parsing fails
68
+ */
69
+ export const parseSubscriptionPayload = payload => {
70
+ try {
71
+ const resourceId = extractResourceIdFromBlockAri(payload.blockAri);
72
+ if (!resourceId) {
73
+ return null;
74
+ }
75
+ const createdAt = convertTimestampToISOString(payload.createdAt);
76
+ return {
77
+ blockAri: payload.blockAri,
78
+ blockInstanceId: payload.blockInstanceId,
79
+ content: JSON.parse(payload.content),
80
+ contentUpdatedAt: convertContentUpdatedAt(payload.contentUpdatedAt),
81
+ createdAt,
82
+ createdBy: payload.createdBy,
83
+ product: payload.product,
84
+ resourceId,
85
+ sourceAri: payload.sourceAri,
86
+ status: payload.status
87
+ };
88
+ } catch {
89
+ return null;
90
+ }
91
+ };
@@ -25,6 +25,10 @@ export { SyncBlockInMemorySessionCache, syncBlockInMemorySessionCache } from './
25
25
  export { SyncBlockStoreManager, useMemoizedSyncBlockStoreManager } from './store-manager/syncBlockStoreManager';
26
26
 
27
27
  // utils
28
+ export { BLOCK_SERVICE_SUBSCRIPTION_QUERY } from './clients/block-service/sharedSubscriptionUtils';
29
+ export { parseSubscriptionPayload } from './clients/block-service/sharedSubscriptionUtils';
30
+ export { convertRelayResponseToSyncBlockInstance } from './utils/relayResponseConverter';
31
+ export { createRelayBlockSubscription, createRelaySubscriptionFunction } from './utils/relaySubscriptionUtils';
28
32
  export { resolveSyncBlockInstance } from './utils/resolveSyncBlockInstance';
29
33
  export { parseResourceId, createResourceIdForReference } from './utils/resourceId';
30
34
  export { createSyncBlockNode, convertSyncBlockPMNodeToSyncBlockData, convertSyncBlockJSONNodeToSyncBlockNode, convertPMNodesToSyncBlockNodes, getContentIdAndProductFromResourceId } from './utils/utils';
@@ -6,6 +6,7 @@ import { batchRetrieveSyncedBlocks, BlockError, createSyncedBlock, deleteSyncedB
6
6
  import { subscribeToBlockUpdates as subscribeToBlockUpdatesWS } from '../../clients/block-service/blockSubscription';
7
7
  import { SyncBlockError } from '../../common/types';
8
8
  import { stringifyError } from '../../utils/errorHandling';
9
+ import { createRelaySubscriptionFunction } from '../../utils/relaySubscriptionUtils';
9
10
  import { createResourceIdForReference } from '../../utils/resourceId';
10
11
  import { convertContentUpdatedAt } from '../../utils/utils';
11
12
  const mapBlockError = error => {
@@ -313,10 +314,12 @@ export const batchFetchData = async (cloudId, parentAri, blockNodeIdentifiers) =
313
314
  class BlockServiceADFFetchProvider {
314
315
  constructor({
315
316
  cloudId,
316
- parentAri
317
+ parentAri,
318
+ relayEnvironment
317
319
  }) {
318
320
  this.cloudId = cloudId;
319
321
  this.parentAri = parentAri;
322
+ this.relayEnvironment = relayEnvironment;
320
323
  }
321
324
 
322
325
  // resourceId of the reference synced block.
@@ -442,6 +445,7 @@ class BlockServiceADFFetchProvider {
442
445
 
443
446
  /**
444
447
  * Subscribes to real-time updates for a specific block using GraphQL WebSocket subscriptions.
448
+ * If a Relay environment is provided, uses Relay subscriptions; otherwise falls back to WebSocket.
445
449
  * @param resourceId - The resource ID of the block to subscribe to
446
450
  * @param onUpdate - Callback function invoked when the block is updated
447
451
  * @param onError - Optional callback function invoked on subscription errors
@@ -452,6 +456,14 @@ class BlockServiceADFFetchProvider {
452
456
  cloudId: this.cloudId,
453
457
  resourceId
454
458
  });
459
+
460
+ // If Relay environment is available, use Relay subscriptions
461
+ if (this.relayEnvironment && fg('platform_synced_block_patch_3')) {
462
+ const relaySubscribeToBlockUpdates = createRelaySubscriptionFunction(this.cloudId, this.relayEnvironment);
463
+ return relaySubscribeToBlockUpdates(resourceId, onUpdate, onError);
464
+ }
465
+
466
+ // Fall back to WebSocket subscriptions
455
467
  return subscribeToBlockUpdatesWS(blockAri, parsedData => {
456
468
  // Convert ParsedBlockSubscriptionData to SyncBlockInstance
457
469
  const syncBlockInstance = {
@@ -672,12 +684,14 @@ const createBlockServiceAPIProviders = ({
672
684
  parentAri,
673
685
  parentId,
674
686
  product,
675
- getVersion
687
+ getVersion,
688
+ relayEnvironment
676
689
  }) => {
677
690
  return {
678
691
  fetchProvider: new BlockServiceADFFetchProvider({
679
692
  cloudId,
680
- parentAri
693
+ parentAri,
694
+ relayEnvironment
681
695
  }),
682
696
  writeProvider: new BlockServiceADFWriteProvider({
683
697
  cloudId,
@@ -693,7 +707,8 @@ export const useMemoizedBlockServiceAPIProviders = ({
693
707
  parentAri,
694
708
  parentId,
695
709
  product,
696
- getVersion
710
+ getVersion,
711
+ relayEnvironment
697
712
  }) => {
698
713
  return useMemo(() => {
699
714
  return createBlockServiceAPIProviders({
@@ -701,9 +716,10 @@ export const useMemoizedBlockServiceAPIProviders = ({
701
716
  parentAri,
702
717
  parentId,
703
718
  product,
704
- getVersion
719
+ getVersion,
720
+ relayEnvironment
705
721
  });
706
- }, [cloudId, parentAri, parentId, product, getVersion]);
722
+ }, [cloudId, parentAri, parentId, product, getVersion, relayEnvironment]);
707
723
  };
708
724
  const createBlockServiceFetchOnlyAPIProvider = ({
709
725
  cloudId,
@@ -659,17 +659,12 @@ export class ReferenceSyncBlockStoreManager {
659
659
  this.providerFactories.delete(resourceId);
660
660
  }
661
661
  debouncedBatchedFetchSyncBlocks(resourceId) {
662
- if (fg('platform_synced_block_patch_2')) {
663
- // Only add to pending requests if there are active subscriptions for this resource
664
- if (this.subscriptions.has(resourceId) && Object.keys(this.subscriptions.get(resourceId) || {}).length > 0) {
665
- this.pendingFetchRequests.add(resourceId);
666
- this.scheduledBatchFetch();
667
- } else {
668
- this.pendingFetchRequests.delete(resourceId);
669
- }
670
- } else {
662
+ // Only add to pending requests if there are active subscriptions for this resource
663
+ if (this.subscriptions.has(resourceId) && Object.keys(this.subscriptions.get(resourceId) || {}).length > 0) {
671
664
  this.pendingFetchRequests.add(resourceId);
672
665
  this.scheduledBatchFetch();
666
+ } else {
667
+ this.pendingFetchRequests.delete(resourceId);
673
668
  }
674
669
  }
675
670
  setSSRDataInSessionCache(resourceIds) {
@@ -979,16 +974,14 @@ export class ReferenceSyncBlockStoreManager {
979
974
  }
980
975
 
981
976
  // Prevent concurrent flushes to avoid race conditions with lastFlushedSyncedBlocks
982
- if (fg('platform_synced_block_patch_2')) {
983
- if (this.isFlushInProgress) {
984
- // Mark that another flush is needed after the current one completes
985
- this.flushNeededAfterCurrent = true;
977
+ if (this.isFlushInProgress) {
978
+ // Mark that another flush is needed after the current one completes
979
+ this.flushNeededAfterCurrent = true;
986
980
 
987
- // We return true here because we know the pending flush will handle the dirty cache
988
- return true;
989
- } else {
990
- this.isFlushInProgress = true;
991
- }
981
+ // We return true here because we know the pending flush will handle the dirty cache
982
+ return true;
983
+ } else {
984
+ this.isFlushInProgress = true;
992
985
  }
993
986
  let success = true;
994
987
  // a copy of the subscriptions STRUCTURE (without the callbacks)
@@ -1000,39 +993,28 @@ export class ReferenceSyncBlockStoreManager {
1000
993
  throw new Error('Data provider not set');
1001
994
  }
1002
995
  const blocks = [];
1003
- if (fg('platform_synced_block_patch_2')) {
1004
- // First, build the complete subscription structure
1005
- for (const [resourceId, callbacks] of this.subscriptions.entries()) {
1006
- syncedBlocksToFlush[resourceId] = {};
1007
- Object.keys(callbacks).forEach(localId => {
1008
- blocks.push({
1009
- resourceId,
1010
- localId
1011
- });
1012
- syncedBlocksToFlush[resourceId][localId] = true;
1013
- });
1014
- }
1015
996
 
1016
- // Then, compare with the last flushed structure to detect changes
1017
- // We check against the last flushed structure to prevent unnecessary flushes
1018
- // Note that we will always flush at least once when editor starts
1019
- // This is useful for eventual consistency between the editor and the BE.
1020
- if (isEqual(syncedBlocksToFlush, this.lastFlushedSyncedBlocks)) {
1021
- this.isCacheDirty = false; // Reset since we're considering this a successful no-op flush
1022
- return true;
1023
- }
1024
- } else {
1025
- // Collect all reference synced blocks on the current document
1026
- Array.from(this.subscriptions.entries()).forEach(([resourceId, callbacks]) => {
1027
- Object.keys(callbacks).forEach(localId => {
1028
- blocks.push({
1029
- resourceId,
1030
- localId
1031
- });
997
+ // First, build the complete subscription structure
998
+ for (const [resourceId, callbacks] of this.subscriptions.entries()) {
999
+ syncedBlocksToFlush[resourceId] = {};
1000
+ Object.keys(callbacks).forEach(localId => {
1001
+ blocks.push({
1002
+ resourceId,
1003
+ localId
1032
1004
  });
1005
+ syncedBlocksToFlush[resourceId][localId] = true;
1033
1006
  });
1034
1007
  }
1035
1008
 
1009
+ // Then, compare with the last flushed structure to detect changes
1010
+ // We check against the last flushed structure to prevent unnecessary flushes
1011
+ // Note that we will always flush at least once when editor starts
1012
+ // This is useful for eventual consistency between the editor and the BE.
1013
+ if (isEqual(syncedBlocksToFlush, this.lastFlushedSyncedBlocks)) {
1014
+ this.isCacheDirty = false; // Reset since we're considering this a successful no-op flush
1015
+ return true;
1016
+ }
1017
+
1036
1018
  // reset isCacheDirty early to prevent race condition
1037
1019
  // There is a race condition where if a user makes changes (create/delete) to a reference sync block
1038
1020
  // on a live page and the reference sync block is being saved while the user
@@ -1065,25 +1047,22 @@ export class ReferenceSyncBlockStoreManager {
1065
1047
  this.isCacheDirty = true;
1066
1048
  } else {
1067
1049
  var _this$saveExperience4;
1068
- if (fg('platform_synced_block_patch_2')) {
1069
- this.lastFlushedSyncedBlocks = syncedBlocksToFlush;
1070
- }
1050
+ this.lastFlushedSyncedBlocks = syncedBlocksToFlush;
1071
1051
  (_this$saveExperience4 = this.saveExperience) === null || _this$saveExperience4 === void 0 ? void 0 : _this$saveExperience4.success();
1072
1052
  }
1073
- if (fg('platform_synced_block_patch_2')) {
1074
- // Always reset isFlushInProgress regardless of feature flag
1075
- this.isFlushInProgress = false;
1076
1053
 
1077
- // If another flush was requested while this one was in progress, execute it now
1078
- if (this.flushNeededAfterCurrent) {
1079
- this.flushNeededAfterCurrent = false;
1080
- // Use setTimeout to avoid deep recursion and run queued flush asynchronously
1081
- // Note: flush() handles all exceptions internally and never rejects
1082
- this.queuedFlushTimeout = setTimeout(() => {
1083
- this.queuedFlushTimeout = undefined;
1084
- void this.flush();
1085
- }, 0);
1086
- }
1054
+ // Always reset isFlushInProgress
1055
+ this.isFlushInProgress = false;
1056
+
1057
+ // If another flush was requested while this one was in progress, execute it now
1058
+ if (this.flushNeededAfterCurrent) {
1059
+ this.flushNeededAfterCurrent = false;
1060
+ // Use setTimeout to avoid deep recursion and run queued flush asynchronously
1061
+ // Note: flush() handles all exceptions internally and never rejects
1062
+ this.queuedFlushTimeout = setTimeout(() => {
1063
+ this.queuedFlushTimeout = undefined;
1064
+ void this.flush();
1065
+ }, 0);
1087
1066
  }
1088
1067
  }
1089
1068
  return success;