@atlaskit/editor-synced-block-provider 3.12.1 → 3.13.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 (41) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/cjs/clients/block-service/blockSubscription.js +124 -0
  3. package/dist/cjs/clients/jira/sourceInfo.js +152 -0
  4. package/dist/cjs/providers/block-service/blockServiceAPI.js +43 -6
  5. package/dist/cjs/providers/syncBlockProvider.js +40 -8
  6. package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +351 -118
  7. package/dist/cjs/store-manager/syncBlockStoreManager.js +2 -2
  8. package/dist/cjs/utils/resolveSyncBlockInstance.js +1 -1
  9. package/dist/es2019/clients/block-service/blockSubscription.js +125 -0
  10. package/dist/es2019/clients/jira/sourceInfo.js +87 -0
  11. package/dist/es2019/providers/block-service/blockServiceAPI.js +40 -5
  12. package/dist/es2019/providers/syncBlockProvider.js +26 -2
  13. package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +237 -49
  14. package/dist/es2019/store-manager/syncBlockStoreManager.js +2 -2
  15. package/dist/es2019/utils/resolveSyncBlockInstance.js +1 -1
  16. package/dist/esm/clients/block-service/blockSubscription.js +118 -0
  17. package/dist/esm/clients/jira/sourceInfo.js +147 -0
  18. package/dist/esm/providers/block-service/blockServiceAPI.js +43 -6
  19. package/dist/esm/providers/syncBlockProvider.js +38 -6
  20. package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +351 -118
  21. package/dist/esm/store-manager/syncBlockStoreManager.js +2 -2
  22. package/dist/esm/utils/resolveSyncBlockInstance.js +1 -1
  23. package/dist/types/clients/block-service/blockService.d.ts +2 -2
  24. package/dist/types/clients/block-service/blockSubscription.d.ts +38 -0
  25. package/dist/types/clients/jira/sourceInfo.d.ts +2 -0
  26. package/dist/types/common/types.d.ts +4 -2
  27. package/dist/types/index.d.ts +2 -2
  28. package/dist/types/providers/block-service/blockServiceAPI.d.ts +8 -0
  29. package/dist/types/providers/syncBlockProvider.d.ts +9 -1
  30. package/dist/types/providers/types.d.ts +22 -6
  31. package/dist/types/store-manager/referenceSyncBlockStoreManager.d.ts +59 -0
  32. package/dist/types-ts4.5/clients/block-service/blockService.d.ts +2 -2
  33. package/dist/types-ts4.5/clients/block-service/blockSubscription.d.ts +38 -0
  34. package/dist/types-ts4.5/clients/jira/sourceInfo.d.ts +2 -0
  35. package/dist/types-ts4.5/common/types.d.ts +4 -2
  36. package/dist/types-ts4.5/index.d.ts +2 -2
  37. package/dist/types-ts4.5/providers/block-service/blockServiceAPI.d.ts +8 -0
  38. package/dist/types-ts4.5/providers/syncBlockProvider.d.ts +9 -1
  39. package/dist/types-ts4.5/providers/types.d.ts +22 -6
  40. package/dist/types-ts4.5/store-manager/referenceSyncBlockStoreManager.d.ts +59 -0
  41. package/package.json +2 -1
@@ -25,18 +25,17 @@ import { createSyncBlockNode } from '../utils/utils';
25
25
  // Handles fetching source URL and title for sync blocks.
26
26
  // Can be used in both editor and renderer contexts.
27
27
  export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
28
- // Track pending cache deletions to handle block moves (unmount/remount)
29
- // When a block is moved, the old component unmounts before the new one mounts,
30
- // causing the cache to be deleted prematurely. We delay deletion to allow
31
- // the new component to subscribe and cancel the pending deletion.
28
+ // Listeners for subscription changes (used by React components to know when to update)
32
29
 
33
30
  function ReferenceSyncBlockStoreManager(dataProvider) {
34
31
  _classCallCheck(this, ReferenceSyncBlockStoreManager);
35
32
  // Keeps track of addition and deletion of reference synced blocks on the document
36
33
  // This starts as true to always flush the cache when document is saved for the first time
37
- // to cater the case when a editor seesion is closed without document being updated right after reference block is deleted
34
+ // to cater the case when a editor session is closed without document being updated right after reference block is deleted
38
35
  _defineProperty(this, "isCacheDirty", true);
39
36
  _defineProperty(this, "isRefreshingSubscriptions", false);
37
+ // Flag to indicate if real-time subscriptions are enabled
38
+ _defineProperty(this, "useRealTimeSubscriptions", false);
40
39
  this.syncBlockCache = new Map();
41
40
  this.subscriptions = new Map();
42
41
  this.titleSubscriptions = new Map();
@@ -46,8 +45,105 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
46
45
  this.syncBlockSourceInfoRequests = new Map();
47
46
  this.providerFactories = new Map();
48
47
  this.pendingCacheDeletions = new Map();
48
+ this.graphqlSubscriptions = new Map();
49
+ this.subscriptionChangeListeners = new Set();
49
50
  }
51
+
52
+ /**
53
+ * Enables or disables real-time GraphQL subscriptions for block updates.
54
+ * When enabled, the store manager will subscribe to real-time updates
55
+ * instead of relying on polling.
56
+ * @param enabled - Whether to enable real-time subscriptions
57
+ */
50
58
  return _createClass(ReferenceSyncBlockStoreManager, [{
59
+ key: "setRealTimeSubscriptionsEnabled",
60
+ value: function setRealTimeSubscriptionsEnabled(enabled) {
61
+ if (this.useRealTimeSubscriptions === enabled) {
62
+ return;
63
+ }
64
+ this.useRealTimeSubscriptions = enabled;
65
+ if (enabled) {
66
+ // Set up subscriptions for all currently subscribed blocks
67
+ this.setupGraphQLSubscriptionsForAllBlocks();
68
+ } else {
69
+ // Clean up all GraphQL subscriptions
70
+ this.cleanupAllGraphQLSubscriptions();
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Checks if real-time subscriptions are currently enabled.
76
+ */
77
+ }, {
78
+ key: "isRealTimeSubscriptionsEnabled",
79
+ value: function isRealTimeSubscriptionsEnabled() {
80
+ return this.useRealTimeSubscriptions;
81
+ }
82
+
83
+ /**
84
+ * Returns all resource IDs that are currently subscribed to.
85
+ * Used by React components to render subscription components.
86
+ */
87
+ }, {
88
+ key: "getSubscribedResourceIds",
89
+ value: function getSubscribedResourceIds() {
90
+ return Array.from(this.subscriptions.keys());
91
+ }
92
+
93
+ /**
94
+ * Registers a listener that will be called when subscriptions change.
95
+ * @param listener - Callback function to invoke when subscriptions change
96
+ * @returns Unsubscribe function to remove the listener
97
+ */
98
+ }, {
99
+ key: "onSubscriptionsChanged",
100
+ value: function onSubscriptionsChanged(listener) {
101
+ var _this = this;
102
+ this.subscriptionChangeListeners.add(listener);
103
+ return function () {
104
+ _this.subscriptionChangeListeners.delete(listener);
105
+ };
106
+ }
107
+
108
+ /**
109
+ * Notifies all subscription change listeners.
110
+ */
111
+ }, {
112
+ key: "notifySubscriptionChangeListeners",
113
+ value: function notifySubscriptionChangeListeners() {
114
+ var _this2 = this;
115
+ this.subscriptionChangeListeners.forEach(function (listener) {
116
+ try {
117
+ listener();
118
+ } catch (error) {
119
+ var _this2$fireAnalyticsE;
120
+ logException(error, {
121
+ location: 'editor-synced-block-provider/referenceSyncBlockStoreManager/notifySubscriptionChangeListeners'
122
+ });
123
+ (_this2$fireAnalyticsE = _this2.fireAnalyticsEvent) === null || _this2$fireAnalyticsE === void 0 || _this2$fireAnalyticsE.call(_this2, fetchErrorPayload(error.message));
124
+ }
125
+ });
126
+ }
127
+
128
+ /**
129
+ * Handles incoming data from a GraphQL subscription.
130
+ * Called by React subscription components when they receive updates.
131
+ * @param syncBlockInstance - The updated sync block instance
132
+ */
133
+ }, {
134
+ key: "handleSubscriptionUpdate",
135
+ value: function handleSubscriptionUpdate(syncBlockInstance) {
136
+ if (!syncBlockInstance.resourceId) {
137
+ return;
138
+ }
139
+ var existingSyncBlock = this.getFromCache(syncBlockInstance.resourceId);
140
+ var resolvedSyncBlockInstance = existingSyncBlock ? resolveSyncBlockInstance(existingSyncBlock, syncBlockInstance) : syncBlockInstance;
141
+ this.updateCache(resolvedSyncBlockInstance);
142
+ if (!syncBlockInstance.error) {
143
+ this.fetchSyncBlockSourceInfo(resolvedSyncBlockInstance.resourceId);
144
+ }
145
+ }
146
+ }, {
51
147
  key: "setFireAnalyticsEvent",
52
148
  value: function setFireAnalyticsEvent(fireAnalyticsEvent) {
53
149
  this.fireAnalyticsEvent = fireAnalyticsEvent;
@@ -78,6 +174,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
78
174
 
79
175
  /**
80
176
  * Refreshes the subscriptions for all sync blocks.
177
+ * This is a fallback polling mechanism when real-time subscriptions are not enabled.
81
178
  * @returns {Promise<void>}
82
179
  */
83
180
  }, {
@@ -88,16 +185,22 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
88
185
  return _regeneratorRuntime.wrap(function _callee$(_context2) {
89
186
  while (1) switch (_context2.prev = _context2.next) {
90
187
  case 0:
91
- if (!this.isRefreshingSubscriptions) {
188
+ if (!this.useRealTimeSubscriptions) {
92
189
  _context2.next = 2;
93
190
  break;
94
191
  }
95
192
  return _context2.abrupt("return");
96
193
  case 2:
194
+ if (!this.isRefreshingSubscriptions) {
195
+ _context2.next = 4;
196
+ break;
197
+ }
198
+ return _context2.abrupt("return");
199
+ case 4:
97
200
  this.isRefreshingSubscriptions = true;
98
201
  syncBlocks = [];
99
202
  _iterator = _createForOfIteratorHelper(this.subscriptions.entries());
100
- _context2.prev = 5;
203
+ _context2.prev = 7;
101
204
  _loop = /*#__PURE__*/_regeneratorRuntime.mark(function _loop() {
102
205
  var _step$value, resourceId, callbacks;
103
206
  return _regeneratorRuntime.wrap(function _loop$(_context) {
@@ -114,59 +217,163 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
114
217
  }, _loop);
115
218
  });
116
219
  _iterator.s();
117
- case 8:
220
+ case 10:
118
221
  if ((_step = _iterator.n()).done) {
119
- _context2.next = 12;
222
+ _context2.next = 14;
120
223
  break;
121
224
  }
122
- return _context2.delegateYield(_loop(), "t0", 10);
123
- case 10:
124
- _context2.next = 8;
125
- break;
225
+ return _context2.delegateYield(_loop(), "t0", 12);
126
226
  case 12:
127
- _context2.next = 17;
227
+ _context2.next = 10;
128
228
  break;
129
229
  case 14:
130
- _context2.prev = 14;
131
- _context2.t1 = _context2["catch"](5);
230
+ _context2.next = 19;
231
+ break;
232
+ case 16:
233
+ _context2.prev = 16;
234
+ _context2.t1 = _context2["catch"](7);
132
235
  _iterator.e(_context2.t1);
133
- case 17:
134
- _context2.prev = 17;
236
+ case 19:
237
+ _context2.prev = 19;
135
238
  _iterator.f();
136
- return _context2.finish(17);
137
- case 20:
138
- _context2.prev = 20;
139
- _context2.next = 23;
239
+ return _context2.finish(19);
240
+ case 22:
241
+ _context2.prev = 22;
242
+ _context2.next = 25;
140
243
  return this.fetchSyncBlocksData(syncBlocks);
141
- case 23:
142
- _context2.next = 29;
143
- break;
144
244
  case 25:
145
- _context2.prev = 25;
146
- _context2.t2 = _context2["catch"](20);
245
+ _context2.next = 31;
246
+ break;
247
+ case 27:
248
+ _context2.prev = 27;
249
+ _context2.t2 = _context2["catch"](22);
147
250
  logException(_context2.t2, {
148
251
  location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
149
252
  });
150
253
  (_this$fireAnalyticsEv = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv === void 0 || _this$fireAnalyticsEv.call(this, fetchErrorPayload(_context2.t2.message));
151
- case 29:
152
- _context2.prev = 29;
254
+ case 31:
255
+ _context2.prev = 31;
153
256
  this.isRefreshingSubscriptions = false;
154
- return _context2.finish(29);
155
- case 32:
257
+ return _context2.finish(31);
258
+ case 34:
156
259
  case "end":
157
260
  return _context2.stop();
158
261
  }
159
- }, _callee, this, [[5, 14, 17, 20], [20, 25, 29, 32]]);
262
+ }, _callee, this, [[7, 16, 19, 22], [22, 27, 31, 34]]);
160
263
  }));
161
264
  function refreshSubscriptions() {
162
265
  return _refreshSubscriptions.apply(this, arguments);
163
266
  }
164
267
  return refreshSubscriptions;
165
- }())
268
+ }()
269
+ /**
270
+ * Sets up a GraphQL subscription for a specific block.
271
+ * @param resourceId - The resource ID of the block to subscribe to
272
+ */
273
+ )
274
+ }, {
275
+ key: "setupGraphQLSubscription",
276
+ value: function setupGraphQLSubscription(resourceId) {
277
+ var _this$dataProvider2,
278
+ _this3 = this;
279
+ // Don't set up duplicate subscriptions
280
+ if (this.graphqlSubscriptions.has(resourceId)) {
281
+ return;
282
+ }
283
+ if (!((_this$dataProvider2 = this.dataProvider) !== null && _this$dataProvider2 !== void 0 && _this$dataProvider2.subscribeToBlockUpdates)) {
284
+ return;
285
+ }
286
+ var unsubscribe = this.dataProvider.subscribeToBlockUpdates(resourceId, function (syncBlockInstance) {
287
+ // Handle the subscription update
288
+ _this3.handleGraphQLSubscriptionUpdate(syncBlockInstance);
289
+ }, function (error) {
290
+ var _this3$fireAnalyticsE;
291
+ logException(error, {
292
+ location: 'editor-synced-block-provider/referenceSyncBlockStoreManager/graphql-subscription'
293
+ });
294
+ (_this3$fireAnalyticsE = _this3.fireAnalyticsEvent) === null || _this3$fireAnalyticsE === void 0 || _this3$fireAnalyticsE.call(_this3, fetchErrorPayload(error.message));
295
+ });
296
+ if (unsubscribe) {
297
+ this.graphqlSubscriptions.set(resourceId, unsubscribe);
298
+ }
299
+ }
300
+
301
+ /**
302
+ * Handles updates received from GraphQL subscriptions.
303
+ * @param syncBlockInstance - The updated sync block instance
304
+ */
305
+ }, {
306
+ key: "handleGraphQLSubscriptionUpdate",
307
+ value: function handleGraphQLSubscriptionUpdate(syncBlockInstance) {
308
+ if (!syncBlockInstance.resourceId) {
309
+ return;
310
+ }
311
+ var existingSyncBlock = this.getFromCache(syncBlockInstance.resourceId);
312
+ var resolvedSyncBlockInstance = existingSyncBlock ? resolveSyncBlockInstance(existingSyncBlock, syncBlockInstance) : syncBlockInstance;
313
+ this.updateCache(resolvedSyncBlockInstance);
314
+ if (!syncBlockInstance.error) {
315
+ this.fetchSyncBlockSourceInfo(resolvedSyncBlockInstance.resourceId);
316
+ }
317
+ }
318
+
319
+ /**
320
+ * Cleans up the GraphQL subscription for a specific block.
321
+ * @param resourceId - The resource ID of the block to unsubscribe from
322
+ */
323
+ }, {
324
+ key: "cleanupGraphQLSubscription",
325
+ value: function cleanupGraphQLSubscription(resourceId) {
326
+ var unsubscribe = this.graphqlSubscriptions.get(resourceId);
327
+ if (unsubscribe) {
328
+ unsubscribe();
329
+ this.graphqlSubscriptions.delete(resourceId);
330
+ }
331
+ }
332
+
333
+ /**
334
+ * Sets up GraphQL subscriptions for all currently subscribed blocks.
335
+ */
336
+ }, {
337
+ key: "setupGraphQLSubscriptionsForAllBlocks",
338
+ value: function setupGraphQLSubscriptionsForAllBlocks() {
339
+ var _iterator2 = _createForOfIteratorHelper(this.subscriptions.keys()),
340
+ _step2;
341
+ try {
342
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
343
+ var resourceId = _step2.value;
344
+ this.setupGraphQLSubscription(resourceId);
345
+ }
346
+ } catch (err) {
347
+ _iterator2.e(err);
348
+ } finally {
349
+ _iterator2.f();
350
+ }
351
+ }
352
+
353
+ /**
354
+ * Cleans up all GraphQL subscriptions.
355
+ */
356
+ }, {
357
+ key: "cleanupAllGraphQLSubscriptions",
358
+ value: function cleanupAllGraphQLSubscriptions() {
359
+ var _iterator3 = _createForOfIteratorHelper(this.graphqlSubscriptions.values()),
360
+ _step3;
361
+ try {
362
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
363
+ var unsubscribe = _step3.value;
364
+ unsubscribe();
365
+ }
366
+ } catch (err) {
367
+ _iterator3.e(err);
368
+ } finally {
369
+ _iterator3.f();
370
+ }
371
+ this.graphqlSubscriptions.clear();
372
+ }
166
373
  }, {
167
374
  key: "fetchSyncBlockSourceInfo",
168
375
  value: function fetchSyncBlockSourceInfo(resourceId) {
169
- var _this = this;
376
+ var _this4 = this;
170
377
  try {
171
378
  if (!resourceId || !this.dataProvider) {
172
379
  throw new Error('Data provider or resourceId not set');
@@ -189,7 +396,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
189
396
  blockInstanceId = _ref.blockInstanceId,
190
397
  sourceURL = _ref.sourceURL,
191
398
  sourceTitle = _ref.sourceTitle,
192
- onSamePage = _ref.onSamePage,
399
+ onSameDocument = _ref.onSameDocument,
193
400
  sourceSubType = _ref.sourceSubType;
194
401
  // skip if source URL and title are already present
195
402
  if (sourceURL && sourceTitle) {
@@ -199,7 +406,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
199
406
  url: sourceURL,
200
407
  subType: sourceSubType,
201
408
  sourceAri: sourceAri || '',
202
- onSamePage: onSamePage,
409
+ onSameDocument: onSameDocument,
203
410
  productType: product
204
411
  });
205
412
  } else {
@@ -218,46 +425,46 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
218
425
  var sourceInfoPromise = this.dataProvider.fetchSyncBlockSourceInfo(blockInstanceId, sourceAri, product, this.fireAnalyticsEvent).then(function (sourceInfo) {
219
426
  if (!sourceInfo) {
220
427
  if (fg('platform_synced_block_dogfooding')) {
221
- var _this$fetchSourceInfo2, _this$fireAnalyticsEv3;
222
- (_this$fetchSourceInfo2 = _this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo2 === void 0 || _this$fetchSourceInfo2.failure({
428
+ var _this4$fetchSourceInf, _this4$fireAnalyticsE;
429
+ (_this4$fetchSourceInf = _this4.fetchSourceInfoExperience) === null || _this4$fetchSourceInf === void 0 || _this4$fetchSourceInf.failure({
223
430
  reason: 'No source info returned'
224
431
  });
225
- (_this$fireAnalyticsEv3 = _this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv3 === void 0 || _this$fireAnalyticsEv3.call(_this, getSourceInfoErrorPayload('No source info returned', resourceId));
432
+ (_this4$fireAnalyticsE = _this4.fireAnalyticsEvent) === null || _this4$fireAnalyticsE === void 0 || _this4$fireAnalyticsE.call(_this4, getSourceInfoErrorPayload('No source info returned', resourceId));
226
433
  }
227
434
  return undefined;
228
435
  }
229
- _this.updateCacheWithSourceInfo(resourceId, sourceInfo);
436
+ _this4.updateCacheWithSourceInfo(resourceId, sourceInfo);
230
437
  if (sourceInfo.title) {
231
- _this.updateSourceTitleSubscriptions(resourceId, sourceInfo.title);
438
+ _this4.updateSourceTitleSubscriptions(resourceId, sourceInfo.title);
232
439
  }
233
440
  if (fg('platform_synced_block_dogfooding')) {
234
441
  if (sourceInfo.title && sourceInfo.url) {
235
- var _this$fetchSourceInfo3;
236
- (_this$fetchSourceInfo3 = _this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo3 === void 0 || _this$fetchSourceInfo3.success();
442
+ var _this4$fetchSourceInf2;
443
+ (_this4$fetchSourceInf2 = _this4.fetchSourceInfoExperience) === null || _this4$fetchSourceInf2 === void 0 || _this4$fetchSourceInf2.success();
237
444
  } else {
238
- var _this$fetchSourceInfo4, _this$fireAnalyticsEv4;
239
- (_this$fetchSourceInfo4 = _this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo4 === void 0 || _this$fetchSourceInfo4.failure({
445
+ var _this4$fetchSourceInf3, _this4$fireAnalyticsE2;
446
+ (_this4$fetchSourceInf3 = _this4.fetchSourceInfoExperience) === null || _this4$fetchSourceInf3 === void 0 || _this4$fetchSourceInf3.failure({
240
447
  reason: 'Missing title or url'
241
448
  });
242
- (_this$fireAnalyticsEv4 = _this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv4 === void 0 || _this$fireAnalyticsEv4.call(_this, getSourceInfoErrorPayload('Missing title or url', resourceId));
449
+ (_this4$fireAnalyticsE2 = _this4.fireAnalyticsEvent) === null || _this4$fireAnalyticsE2 === void 0 || _this4$fireAnalyticsE2.call(_this4, getSourceInfoErrorPayload('Missing title or url', resourceId));
243
450
  }
244
451
  return sourceInfo;
245
452
  }
246
453
  }).catch(function (error) {
247
- var _this$fireAnalyticsEv5;
454
+ var _this4$fireAnalyticsE3;
248
455
  if (fg('platform_synced_block_dogfooding')) {
249
- var _this$fetchSourceInfo5;
250
- (_this$fetchSourceInfo5 = _this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo5 === void 0 || _this$fetchSourceInfo5.failure({
456
+ var _this4$fetchSourceInf4;
457
+ (_this4$fetchSourceInf4 = _this4.fetchSourceInfoExperience) === null || _this4$fetchSourceInf4 === void 0 || _this4$fetchSourceInf4.failure({
251
458
  reason: error.message
252
459
  });
253
460
  }
254
- (_this$fireAnalyticsEv5 = _this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv5 === void 0 || _this$fireAnalyticsEv5.call(_this, getSourceInfoErrorPayload(error.message, resourceId));
461
+ (_this4$fireAnalyticsE3 = _this4.fireAnalyticsEvent) === null || _this4$fireAnalyticsE3 === void 0 || _this4$fireAnalyticsE3.call(_this4, getSourceInfoErrorPayload(error.message, resourceId));
255
462
  return undefined;
256
463
  }).finally(function () {
257
464
  if (fg('platform_synced_block_dogfooding')) {
258
- _this.syncBlockSourceInfoRequests.delete(resourceId);
465
+ _this4.syncBlockSourceInfoRequests.delete(resourceId);
259
466
  } else {
260
- _this.syncBlockSourceInfoRequestsOld.delete(resourceId);
467
+ _this4.syncBlockSourceInfoRequestsOld.delete(resourceId);
261
468
  }
262
469
  });
263
470
  if (fg('platform_synced_block_dogfooding')) {
@@ -267,11 +474,11 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
267
474
  this.syncBlockSourceInfoRequestsOld.set(resourceId, true);
268
475
  }
269
476
  } catch (error) {
270
- var _this$fireAnalyticsEv6;
477
+ var _this$fireAnalyticsEv3;
271
478
  logException(error, {
272
479
  location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
273
480
  });
274
- (_this$fireAnalyticsEv6 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv6 === void 0 || _this$fireAnalyticsEv6.call(this, getSourceInfoErrorPayload(error.message, resourceId));
481
+ (_this$fireAnalyticsEv3 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv3 === void 0 || _this$fireAnalyticsEv3.call(this, getSourceInfoErrorPayload(error.message, resourceId));
275
482
  }
276
483
  return Promise.resolve(undefined);
277
484
  }
@@ -285,7 +492,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
285
492
  key: "fetchSyncBlocksData",
286
493
  value: (function () {
287
494
  var _fetchSyncBlocksData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(syncBlockNodes) {
288
- var _this2 = this;
495
+ var _this5 = this;
289
496
  var nodesToFetch, _this$fetchExperience, data, resolvedData, hasUnexpectedError, hasExpectedError, _this$fetchExperience2, _this$fetchExperience3, _this$fetchExperience4;
290
497
  return _regeneratorRuntime.wrap(function _callee2$(_context3) {
291
498
  while (1) switch (_context3.prev = _context3.next) {
@@ -299,10 +506,10 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
299
506
  // Don't fetch for not_found error since the source is already deleted
300
507
  nodesToFetch = [];
301
508
  syncBlockNodes.forEach(function (node) {
302
- if (_this2.syncBlockFetchDataRequests.get(node.attrs.resourceId)) {
509
+ if (_this5.syncBlockFetchDataRequests.get(node.attrs.resourceId)) {
303
510
  return;
304
511
  }
305
- var existingSyncBlock = _this2.getFromCache(node.attrs.resourceId);
512
+ var existingSyncBlock = _this5.getFromCache(node.attrs.resourceId);
306
513
  if ((existingSyncBlock === null || existingSyncBlock === void 0 ? void 0 : existingSyncBlock.error) === SyncBlockError.NotFound) {
307
514
  return;
308
515
  }
@@ -321,7 +528,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
321
528
  throw new Error('Data provider not set');
322
529
  case 8:
323
530
  nodesToFetch.forEach(function (node) {
324
- _this2.syncBlockFetchDataRequests.set(node.attrs.resourceId, true);
531
+ _this5.syncBlockFetchDataRequests.set(node.attrs.resourceId, true);
325
532
  });
326
533
  if (fg('platform_synced_block_dogfooding')) {
327
534
  (_this$fetchExperience = this.fetchExperience) === null || _this$fetchExperience === void 0 || _this$fetchExperience.start({});
@@ -329,7 +536,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
329
536
  _context3.next = 12;
330
537
  return this.dataProvider.fetchNodesData(nodesToFetch).finally(function () {
331
538
  nodesToFetch.forEach(function (node) {
332
- _this2.syncBlockFetchDataRequests.delete(node.attrs.resourceId);
539
+ _this5.syncBlockFetchDataRequests.delete(node.attrs.resourceId);
333
540
  });
334
541
  });
335
542
  case 12:
@@ -339,17 +546,17 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
339
546
  hasExpectedError = false;
340
547
  data.forEach(function (syncBlockInstance) {
341
548
  if (!syncBlockInstance.resourceId) {
342
- var _this2$fireAnalyticsE;
343
- (_this2$fireAnalyticsE = _this2.fireAnalyticsEvent) === null || _this2$fireAnalyticsE === void 0 || _this2$fireAnalyticsE.call(_this2, fetchErrorPayload(syncBlockInstance.error || 'Returned sync block instance does not have resource id'));
549
+ var _this5$fireAnalyticsE;
550
+ (_this5$fireAnalyticsE = _this5.fireAnalyticsEvent) === null || _this5$fireAnalyticsE === void 0 || _this5$fireAnalyticsE.call(_this5, fetchErrorPayload(syncBlockInstance.error || 'Returned sync block instance does not have resource id'));
344
551
  return;
345
552
  }
346
- var existingSyncBlock = _this2.getFromCache(syncBlockInstance.resourceId);
553
+ var existingSyncBlock = _this5.getFromCache(syncBlockInstance.resourceId);
347
554
  var resolvedSyncBlockInstance = existingSyncBlock ? resolveSyncBlockInstance(existingSyncBlock, syncBlockInstance) : syncBlockInstance;
348
- _this2.updateCache(resolvedSyncBlockInstance);
555
+ _this5.updateCache(resolvedSyncBlockInstance);
349
556
  resolvedData.push(resolvedSyncBlockInstance);
350
557
  if (syncBlockInstance.error) {
351
- var _this2$fireAnalyticsE2;
352
- (_this2$fireAnalyticsE2 = _this2.fireAnalyticsEvent) === null || _this2$fireAnalyticsE2 === void 0 || _this2$fireAnalyticsE2.call(_this2, fetchErrorPayload(syncBlockInstance.error, syncBlockInstance.resourceId));
558
+ var _this5$fireAnalyticsE2;
559
+ (_this5$fireAnalyticsE2 = _this5.fireAnalyticsEvent) === null || _this5$fireAnalyticsE2 === void 0 || _this5$fireAnalyticsE2.call(_this5, fetchErrorPayload(syncBlockInstance.error, syncBlockInstance.resourceId));
353
560
  if (syncBlockInstance.error === SyncBlockError.NotFound || syncBlockInstance.error === SyncBlockError.Forbidden) {
354
561
  hasExpectedError = true;
355
562
  } else if (syncBlockInstance.error) {
@@ -357,10 +564,10 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
357
564
  }
358
565
  return;
359
566
  } else if (fg('platform_synced_block_dogfooding')) {
360
- var _this2$fireAnalyticsE3, _syncBlockInstance$da, _syncBlockInstance$da2;
361
- (_this2$fireAnalyticsE3 = _this2.fireAnalyticsEvent) === null || _this2$fireAnalyticsE3 === void 0 || _this2$fireAnalyticsE3.call(_this2, fetchSuccessPayload(syncBlockInstance.resourceId, (_syncBlockInstance$da = syncBlockInstance.data) === null || _syncBlockInstance$da === void 0 ? void 0 : _syncBlockInstance$da.blockInstanceId, (_syncBlockInstance$da2 = syncBlockInstance.data) === null || _syncBlockInstance$da2 === void 0 ? void 0 : _syncBlockInstance$da2.product));
567
+ var _this5$fireAnalyticsE3, _syncBlockInstance$da, _syncBlockInstance$da2;
568
+ (_this5$fireAnalyticsE3 = _this5.fireAnalyticsEvent) === null || _this5$fireAnalyticsE3 === void 0 || _this5$fireAnalyticsE3.call(_this5, fetchSuccessPayload(syncBlockInstance.resourceId, (_syncBlockInstance$da = syncBlockInstance.data) === null || _syncBlockInstance$da === void 0 ? void 0 : _syncBlockInstance$da.blockInstanceId, (_syncBlockInstance$da2 = syncBlockInstance.data) === null || _syncBlockInstance$da2 === void 0 ? void 0 : _syncBlockInstance$da2.product));
362
569
  }
363
- _this2.fetchSyncBlockSourceInfo(resolvedSyncBlockInstance.resourceId);
570
+ _this5.fetchSyncBlockSourceInfo(resolvedSyncBlockInstance.resourceId);
364
571
  });
365
572
  if (fg('platform_synced_block_dogfooding')) {
366
573
  if (hasUnexpectedError) {
@@ -395,7 +602,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
395
602
  existingSyncBlock.data = _objectSpread(_objectSpread({}, existingSyncBlock.data), {}, {
396
603
  sourceURL: sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.url,
397
604
  sourceTitle: sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.title,
398
- onSamePage: sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.onSamePage,
605
+ onSameDocument: sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.onSameDocument,
399
606
  sourceSubType: sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.subType
400
607
  });
401
608
  this.updateCache(existingSyncBlock);
@@ -439,8 +646,8 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
439
646
  }, {
440
647
  key: "subscribeToSyncBlock",
441
648
  value: function subscribeToSyncBlock(resourceId, localId, callback) {
442
- var _this$dataProvider2,
443
- _this3 = this;
649
+ var _this$dataProvider3,
650
+ _this6 = this;
444
651
  // Cancel any pending cache deletion for this resourceId.
445
652
  // This handles the case where a block is moved - the old component unmounts
446
653
  // (scheduling deletion) but the new component mounts and subscribes before
@@ -453,34 +660,52 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
453
660
 
454
661
  // add to subscriptions map
455
662
  var resourceSubscriptions = this.subscriptions.get(resourceId) || {};
663
+ var isNewResourceSubscription = Object.keys(resourceSubscriptions).length === 0;
456
664
  this.subscriptions.set(resourceId, _objectSpread(_objectSpread({}, resourceSubscriptions), {}, _defineProperty({}, localId, callback)));
457
665
 
458
666
  // New subscription means new reference synced block is added to the document
459
667
  this.isCacheDirty = true;
668
+
669
+ // Notify listeners if this is a new resource subscription
670
+ if (isNewResourceSubscription) {
671
+ this.notifySubscriptionChangeListeners();
672
+ }
460
673
  var syncBlockNode = createSyncBlockNode(localId, resourceId);
461
674
 
462
675
  // call the callback immediately if we have cached data
463
676
  // prefer cache from store manager first, should update data provider to use the same cache
464
- var cachedData = this.getFromCache(resourceId) || ((_this$dataProvider2 = this.dataProvider) === null || _this$dataProvider2 === void 0 || (_this$dataProvider2 = _this$dataProvider2.getNodeDataFromCache(syncBlockNode)) === null || _this$dataProvider2 === void 0 ? void 0 : _this$dataProvider2.data);
677
+ var cachedData = this.getFromCache(resourceId) || ((_this$dataProvider3 = this.dataProvider) === null || _this$dataProvider3 === void 0 || (_this$dataProvider3 = _this$dataProvider3.getNodeDataFromCache(syncBlockNode)) === null || _this$dataProvider3 === void 0 ? void 0 : _this$dataProvider3.data);
465
678
  if (cachedData) {
466
679
  callback(cachedData);
467
680
  } else {
468
681
  this.fetchSyncBlocksData([syncBlockNode]).catch(function (error) {
469
- var _this3$fireAnalyticsE;
682
+ var _this6$fireAnalyticsE;
470
683
  logException(error, {
471
684
  location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
472
685
  });
473
- (_this3$fireAnalyticsE = _this3.fireAnalyticsEvent) === null || _this3$fireAnalyticsE === void 0 || _this3$fireAnalyticsE.call(_this3, fetchErrorPayload(error.message, resourceId));
686
+ (_this6$fireAnalyticsE = _this6.fireAnalyticsEvent) === null || _this6$fireAnalyticsE === void 0 || _this6$fireAnalyticsE.call(_this6, fetchErrorPayload(error.message, resourceId));
474
687
  });
475
688
  }
689
+
690
+ // Set up GraphQL subscription if real-time subscriptions are enabled
691
+ if (this.useRealTimeSubscriptions) {
692
+ this.setupGraphQLSubscription(resourceId);
693
+ }
476
694
  return function () {
477
- var resourceSubscriptions = _this3.subscriptions.get(resourceId);
695
+ var resourceSubscriptions = _this6.subscriptions.get(resourceId);
478
696
  if (resourceSubscriptions) {
479
697
  // Unsubscription means a reference synced block is removed from the document
480
- _this3.isCacheDirty = true;
698
+ _this6.isCacheDirty = true;
481
699
  delete resourceSubscriptions[localId];
482
700
  if (Object.keys(resourceSubscriptions).length === 0) {
483
- _this3.subscriptions.delete(resourceId);
701
+ _this6.subscriptions.delete(resourceId);
702
+
703
+ // Clean up GraphQL subscription when no more local subscribers
704
+ _this6.cleanupGraphQLSubscription(resourceId);
705
+
706
+ // Notify listeners that subscription was removed
707
+ _this6.notifySubscriptionChangeListeners();
708
+
484
709
  // Delay cache deletion to handle block moves (unmount/remount).
485
710
  // When a block is moved, the old component unmounts before the new one mounts.
486
711
  // By delaying deletion, we give the new component time to subscribe and
@@ -488,14 +713,14 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
488
713
  // TODO: EDITOR-4152 - Rework this logic
489
714
  var deletionTimeout = setTimeout(function () {
490
715
  // Only delete if still no subscribers (wasn't re-subscribed)
491
- if (!_this3.subscriptions.has(resourceId)) {
492
- _this3.deleteFromCache(resourceId);
716
+ if (!_this6.subscriptions.has(resourceId)) {
717
+ _this6.deleteFromCache(resourceId);
493
718
  }
494
- _this3.pendingCacheDeletions.delete(resourceId);
719
+ _this6.pendingCacheDeletions.delete(resourceId);
495
720
  }, 1000);
496
- _this3.pendingCacheDeletions.set(resourceId, deletionTimeout);
721
+ _this6.pendingCacheDeletions.set(resourceId, deletionTimeout);
497
722
  } else {
498
- _this3.subscriptions.set(resourceId, resourceSubscriptions);
723
+ _this6.subscriptions.set(resourceId, resourceSubscriptions);
499
724
  }
500
725
  }
501
726
  };
@@ -504,7 +729,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
504
729
  key: "subscribeToSourceTitle",
505
730
  value: function subscribeToSourceTitle(node, callback) {
506
731
  var _cachedData$data,
507
- _this4 = this;
732
+ _this7 = this;
508
733
  // check node is a sync block, as we only support sync block subscriptions
509
734
  if (node.type.name !== 'syncBlock') {
510
735
  return function () {};
@@ -524,13 +749,13 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
524
749
  var resourceSubscriptions = this.titleSubscriptions.get(resourceId) || {};
525
750
  this.titleSubscriptions.set(resourceId, _objectSpread(_objectSpread({}, resourceSubscriptions), {}, _defineProperty({}, localId, callback)));
526
751
  return function () {
527
- var resourceSubscriptions = _this4.titleSubscriptions.get(resourceId);
752
+ var resourceSubscriptions = _this7.titleSubscriptions.get(resourceId);
528
753
  if (resourceSubscriptions) {
529
754
  delete resourceSubscriptions[localId];
530
755
  if (Object.keys(resourceSubscriptions).length === 0) {
531
- _this4.titleSubscriptions.delete(resourceId);
756
+ _this7.titleSubscriptions.delete(resourceId);
532
757
  } else {
533
- _this4.titleSubscriptions.set(resourceId, resourceSubscriptions);
758
+ _this7.titleSubscriptions.set(resourceId, resourceSubscriptions);
534
759
  }
535
760
  }
536
761
  };
@@ -551,11 +776,11 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
551
776
  }
552
777
  return this.subscribeToSyncBlock(resourceId, localId, callback);
553
778
  } catch (error) {
554
- var _this$fireAnalyticsEv7;
779
+ var _this$fireAnalyticsEv4;
555
780
  logException(error, {
556
781
  location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
557
782
  });
558
- (_this$fireAnalyticsEv7 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv7 === void 0 || _this$fireAnalyticsEv7.call(this, fetchErrorPayload(error.message));
783
+ (_this$fireAnalyticsEv4 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv4 === void 0 || _this$fireAnalyticsEv4.call(this, fetchErrorPayload(error.message));
559
784
  return function () {};
560
785
  }
561
786
  }
@@ -579,12 +804,12 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
579
804
  key: "getProviderFactory",
580
805
  value: function getProviderFactory(resourceId) {
581
806
  if (!this.dataProvider) {
582
- var _this$fireAnalyticsEv8;
807
+ var _this$fireAnalyticsEv5;
583
808
  var error = new Error('Data provider not set');
584
809
  logException(error, {
585
810
  location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
586
811
  });
587
- (_this$fireAnalyticsEv8 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv8 === void 0 || _this$fireAnalyticsEv8.call(this, fetchErrorPayload(error.message));
812
+ (_this$fireAnalyticsEv5 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv5 === void 0 || _this$fireAnalyticsEv5.call(this, fetchErrorPayload(error.message));
588
813
  return undefined;
589
814
  }
590
815
  var _this$dataProvider$ge = this.dataProvider.getSyncedBlockRendererProviderOptions(),
@@ -613,11 +838,11 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
613
838
  try {
614
839
  this.retrieveDynamicProviders(resourceId, providerFactory, providerCreator);
615
840
  } catch (error) {
616
- var _this$fireAnalyticsEv9;
841
+ var _this$fireAnalyticsEv6;
617
842
  logException(error, {
618
843
  location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
619
844
  });
620
- (_this$fireAnalyticsEv9 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv9 === void 0 || _this$fireAnalyticsEv9.call(this, fetchErrorPayload(error.message, resourceId));
845
+ (_this$fireAnalyticsEv6 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv6 === void 0 || _this$fireAnalyticsEv6.call(this, fetchErrorPayload(error.message, resourceId));
621
846
  }
622
847
  }
623
848
  return providerFactory;
@@ -662,7 +887,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
662
887
  }, {
663
888
  key: "retrieveDynamicProviders",
664
889
  value: function retrieveDynamicProviders(resourceId, providerFactory, providerCreator) {
665
- var _syncBlock$data2, _syncBlock$data3, _syncBlock$data4, _syncBlock$data5;
890
+ var _syncBlock$data2, _syncBlock$data3;
666
891
  if (!this.dataProvider) {
667
892
  throw new Error('Data provider not set');
668
893
  }
@@ -673,15 +898,15 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
673
898
  return;
674
899
  }
675
900
  var syncBlock = this.getFromCache(resourceId);
676
- if (!syncBlock) {
901
+ if (!(syncBlock !== null && syncBlock !== void 0 && syncBlock.data)) {
677
902
  return;
678
903
  }
679
- if (!((_syncBlock$data2 = syncBlock.data) !== null && _syncBlock$data2 !== void 0 && _syncBlock$data2.sourceAri) || !((_syncBlock$data3 = syncBlock.data) !== null && _syncBlock$data3 !== void 0 && _syncBlock$data3.product)) {
680
- var _this$fireAnalyticsEv0;
681
- (_this$fireAnalyticsEv0 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv0 === void 0 || _this$fireAnalyticsEv0.call(this, fetchErrorPayload('Sync block source ari or product not found'));
904
+ if (!syncBlock.data.sourceAri || !syncBlock.data.product) {
905
+ var _this$fireAnalyticsEv7;
906
+ (_this$fireAnalyticsEv7 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv7 === void 0 || _this$fireAnalyticsEv7.call(this, fetchErrorPayload('Sync block source ari or product not found'));
682
907
  return;
683
908
  }
684
- var parentInfo = this.dataProvider.retrieveSyncBlockParentInfo((_syncBlock$data4 = syncBlock.data) === null || _syncBlock$data4 === void 0 ? void 0 : _syncBlock$data4.sourceAri, (_syncBlock$data5 = syncBlock.data) === null || _syncBlock$data5 === void 0 ? void 0 : _syncBlock$data5.product);
909
+ var parentInfo = this.dataProvider.retrieveSyncBlockParentInfo((_syncBlock$data2 = syncBlock.data) === null || _syncBlock$data2 === void 0 ? void 0 : _syncBlock$data2.sourceAri, (_syncBlock$data3 = syncBlock.data) === null || _syncBlock$data3 === void 0 ? void 0 : _syncBlock$data3.product);
685
910
  if (!parentInfo) {
686
911
  throw new Error('Unable to retrive sync block parent info');
687
912
  }
@@ -728,7 +953,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
728
953
  key: "flush",
729
954
  value: (function () {
730
955
  var _flush = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
731
- var success, blocks, _this$saveExperience, updateResult, _this$fireAnalyticsEv1, _this$saveExperience2, _this$fireAnalyticsEv10, _this$saveExperience3, _this$saveExperience4;
956
+ var success, blocks, _this$saveExperience, updateResult, _this$fireAnalyticsEv8, _this$saveExperience2, _this$fireAnalyticsEv9, _this$saveExperience3, _this$saveExperience4;
732
957
  return _regeneratorRuntime.wrap(function _callee3$(_context4) {
733
958
  while (1) switch (_context4.prev = _context4.next) {
734
959
  case 0:
@@ -752,19 +977,23 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
752
977
  });
753
978
  });
754
979
  });
980
+ if (fg('platform_synced_block_dogfooding')) {
981
+ _context4.next = 10;
982
+ break;
983
+ }
755
984
  if (!(blocks.length === 0)) {
756
- _context4.next = 9;
985
+ _context4.next = 10;
757
986
  break;
758
987
  }
759
988
  this.isCacheDirty = false;
760
989
  return _context4.abrupt("return", true);
761
- case 9:
990
+ case 10:
762
991
  if (this.dataProvider) {
763
- _context4.next = 11;
992
+ _context4.next = 12;
764
993
  break;
765
994
  }
766
995
  throw new Error('Data provider not set');
767
- case 11:
996
+ case 12:
768
997
  // reset isCacheDirty early to prevent race condition
769
998
  // There is a race condition where if a user makes changes (create/delete) to a reference sync block
770
999
  // on a live page and the reference sync block is being saved while the user
@@ -774,9 +1003,9 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
774
1003
  if (fg('platform_synced_block_dogfooding')) {
775
1004
  (_this$saveExperience = this.saveExperience) === null || _this$saveExperience === void 0 || _this$saveExperience.start();
776
1005
  }
777
- _context4.next = 15;
1006
+ _context4.next = 16;
778
1007
  return this.dataProvider.updateReferenceData(blocks);
779
- case 15:
1008
+ case 16:
780
1009
  updateResult = _context4.sent;
781
1010
  if (!updateResult.success) {
782
1011
  success = false;
@@ -785,12 +1014,12 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
785
1014
  reason: updateResult.error || 'Failed to update reference synced blocks on the document'
786
1015
  });
787
1016
  }
788
- (_this$fireAnalyticsEv1 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv1 === void 0 || _this$fireAnalyticsEv1.call(this, updateReferenceErrorPayload(updateResult.error || 'Failed to update reference synced blocks on the document'));
1017
+ (_this$fireAnalyticsEv8 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv8 === void 0 || _this$fireAnalyticsEv8.call(this, updateReferenceErrorPayload(updateResult.error || 'Failed to update reference synced blocks on the document'));
789
1018
  }
790
- _context4.next = 25;
1019
+ _context4.next = 26;
791
1020
  break;
792
- case 19:
793
- _context4.prev = 19;
1021
+ case 20:
1022
+ _context4.prev = 20;
794
1023
  _context4.t0 = _context4["catch"](3);
795
1024
  success = false;
796
1025
  logException(_context4.t0, {
@@ -801,23 +1030,23 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
801
1030
  reason: _context4.t0.message
802
1031
  });
803
1032
  }
804
- (_this$fireAnalyticsEv10 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv10 === void 0 || _this$fireAnalyticsEv10.call(this, updateReferenceErrorPayload(_context4.t0.message));
805
- case 25:
806
- _context4.prev = 25;
1033
+ (_this$fireAnalyticsEv9 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv9 === void 0 || _this$fireAnalyticsEv9.call(this, updateReferenceErrorPayload(_context4.t0.message));
1034
+ case 26:
1035
+ _context4.prev = 26;
807
1036
  if (!success) {
808
1037
  // set isCacheDirty back to true for cases where it failed to update the reference synced blocks on the BE
809
1038
  this.isCacheDirty = true;
810
1039
  } else if (fg('platform_synced_block_dogfooding')) {
811
1040
  (_this$saveExperience4 = this.saveExperience) === null || _this$saveExperience4 === void 0 || _this$saveExperience4.success();
812
1041
  }
813
- return _context4.finish(25);
814
- case 28:
815
- return _context4.abrupt("return", success);
1042
+ return _context4.finish(26);
816
1043
  case 29:
1044
+ return _context4.abrupt("return", success);
1045
+ case 30:
817
1046
  case "end":
818
1047
  return _context4.stop();
819
1048
  }
820
- }, _callee3, this, [[3, 19, 25, 28]]);
1049
+ }, _callee3, this, [[3, 20, 26, 29]]);
821
1050
  }));
822
1051
  function flush() {
823
1052
  return _flush.apply(this, arguments);
@@ -827,7 +1056,9 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
827
1056
  }, {
828
1057
  key: "destroy",
829
1058
  value: function destroy() {
830
- var _this$saveExperience5, _this$fetchExperience5, _this$fetchSourceInfo6;
1059
+ var _this$saveExperience5, _this$fetchExperience5, _this$fetchSourceInfo2;
1060
+ // Clean up all GraphQL subscriptions first
1061
+ this.cleanupAllGraphQLSubscriptions();
831
1062
  this.dataProvider = undefined;
832
1063
  this.syncBlockCache.clear();
833
1064
  this.subscriptions.clear();
@@ -837,6 +1068,8 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
837
1068
  this.syncBlockSourceInfoRequests.clear();
838
1069
  this.providerFactories.clear();
839
1070
  this.isRefreshingSubscriptions = false;
1071
+ this.useRealTimeSubscriptions = false;
1072
+ this.subscriptionChangeListeners.clear();
840
1073
  this.providerFactories.forEach(function (providerFactory) {
841
1074
  providerFactory.destroy();
842
1075
  });
@@ -847,7 +1080,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
847
1080
  (_this$fetchExperience5 = this.fetchExperience) === null || _this$fetchExperience5 === void 0 || _this$fetchExperience5.abort({
848
1081
  reason: 'editor-destroyed'
849
1082
  });
850
- (_this$fetchSourceInfo6 = this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo6 === void 0 || _this$fetchSourceInfo6.abort({
1083
+ (_this$fetchSourceInfo2 = this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo2 === void 0 || _this$fetchSourceInfo2.abort({
851
1084
  reason: 'editor-destroyed'
852
1085
  });
853
1086
  this.fireAnalyticsEvent = undefined;