@atlaskit/editor-synced-block-provider 3.12.0 → 3.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +25 -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 +393 -204
  7. package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +95 -124
  8. package/dist/cjs/store-manager/syncBlockStoreManager.js +2 -2
  9. package/dist/cjs/utils/errorHandling.js +79 -19
  10. package/dist/cjs/utils/experienceTracking.js +119 -0
  11. package/dist/cjs/utils/resolveSyncBlockInstance.js +1 -1
  12. package/dist/es2019/clients/block-service/blockSubscription.js +125 -0
  13. package/dist/es2019/clients/jira/sourceInfo.js +87 -0
  14. package/dist/es2019/providers/block-service/blockServiceAPI.js +40 -5
  15. package/dist/es2019/providers/syncBlockProvider.js +26 -2
  16. package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +286 -139
  17. package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +80 -89
  18. package/dist/es2019/store-manager/syncBlockStoreManager.js +2 -2
  19. package/dist/es2019/utils/errorHandling.js +61 -10
  20. package/dist/es2019/utils/experienceTracking.js +113 -0
  21. package/dist/es2019/utils/resolveSyncBlockInstance.js +1 -1
  22. package/dist/esm/clients/block-service/blockSubscription.js +118 -0
  23. package/dist/esm/clients/jira/sourceInfo.js +147 -0
  24. package/dist/esm/providers/block-service/blockServiceAPI.js +43 -6
  25. package/dist/esm/providers/syncBlockProvider.js +38 -6
  26. package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +394 -205
  27. package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +96 -125
  28. package/dist/esm/store-manager/syncBlockStoreManager.js +2 -2
  29. package/dist/esm/utils/errorHandling.js +77 -18
  30. package/dist/esm/utils/experienceTracking.js +113 -0
  31. package/dist/esm/utils/resolveSyncBlockInstance.js +1 -1
  32. package/dist/types/clients/block-service/blockService.d.ts +2 -2
  33. package/dist/types/clients/block-service/blockSubscription.d.ts +38 -0
  34. package/dist/types/clients/jira/sourceInfo.d.ts +2 -0
  35. package/dist/types/common/types.d.ts +4 -2
  36. package/dist/types/index.d.ts +2 -2
  37. package/dist/types/providers/block-service/blockServiceAPI.d.ts +8 -0
  38. package/dist/types/providers/syncBlockProvider.d.ts +9 -1
  39. package/dist/types/providers/types.d.ts +22 -6
  40. package/dist/types/store-manager/referenceSyncBlockStoreManager.d.ts +59 -1
  41. package/dist/types/store-manager/sourceSyncBlockStoreManager.d.ts +1 -5
  42. package/dist/types/utils/errorHandling.d.ts +14 -9
  43. package/dist/types/utils/experienceTracking.d.ts +51 -0
  44. package/dist/types-ts4.5/clients/block-service/blockService.d.ts +2 -2
  45. package/dist/types-ts4.5/clients/block-service/blockSubscription.d.ts +38 -0
  46. package/dist/types-ts4.5/clients/jira/sourceInfo.d.ts +2 -0
  47. package/dist/types-ts4.5/common/types.d.ts +4 -2
  48. package/dist/types-ts4.5/index.d.ts +2 -2
  49. package/dist/types-ts4.5/providers/block-service/blockServiceAPI.d.ts +8 -0
  50. package/dist/types-ts4.5/providers/syncBlockProvider.d.ts +9 -1
  51. package/dist/types-ts4.5/providers/types.d.ts +22 -6
  52. package/dist/types-ts4.5/store-manager/referenceSyncBlockStoreManager.d.ts +59 -1
  53. package/dist/types-ts4.5/store-manager/sourceSyncBlockStoreManager.d.ts +1 -5
  54. package/dist/types-ts4.5/utils/errorHandling.d.ts +14 -9
  55. package/dist/types-ts4.5/utils/experienceTracking.d.ts +51 -0
  56. package/package.json +2 -1
@@ -13,7 +13,8 @@ import { logException } from '@atlaskit/editor-common/monitoring';
13
13
  import { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
14
14
  import { fg } from '@atlaskit/platform-feature-flags';
15
15
  import { SyncBlockError } from '../common/types';
16
- import { fetchErrorPayload, getSourceInfoErrorPayload, updateReferenceErrorPayload } from '../utils/errorHandling';
16
+ import { fetchErrorPayload, fetchSuccessPayload, getSourceInfoErrorPayload, updateReferenceErrorPayload } from '../utils/errorHandling';
17
+ import { getFetchExperience, getFetchSourceInfoExperience, getSaveReferenceExperience } from '../utils/experienceTracking';
17
18
  import { resolveSyncBlockInstance } from '../utils/resolveSyncBlockInstance';
18
19
  import { parseResourceId } from '../utils/resourceId';
19
20
  import { createSyncBlockNode } from '../utils/utils';
@@ -24,18 +25,17 @@ import { createSyncBlockNode } from '../utils/utils';
24
25
  // Handles fetching source URL and title for sync blocks.
25
26
  // Can be used in both editor and renderer contexts.
26
27
  export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
27
- // Track pending cache deletions to handle block moves (unmount/remount)
28
- // When a block is moved, the old component unmounts before the new one mounts,
29
- // causing the cache to be deleted prematurely. We delay deletion to allow
30
- // the new component to subscribe and cancel the pending deletion.
28
+ // Listeners for subscription changes (used by React components to know when to update)
31
29
 
32
30
  function ReferenceSyncBlockStoreManager(dataProvider) {
33
31
  _classCallCheck(this, ReferenceSyncBlockStoreManager);
34
32
  // Keeps track of addition and deletion of reference synced blocks on the document
35
33
  // This starts as true to always flush the cache when document is saved for the first time
36
- // 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
37
35
  _defineProperty(this, "isCacheDirty", true);
38
36
  _defineProperty(this, "isRefreshingSubscriptions", false);
37
+ // Flag to indicate if real-time subscriptions are enabled
38
+ _defineProperty(this, "useRealTimeSubscriptions", false);
39
39
  this.syncBlockCache = new Map();
40
40
  this.subscriptions = new Map();
41
41
  this.titleSubscriptions = new Map();
@@ -45,22 +45,112 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
45
45
  this.syncBlockSourceInfoRequests = new Map();
46
46
  this.providerFactories = new Map();
47
47
  this.pendingCacheDeletions = new Map();
48
+ this.graphqlSubscriptions = new Map();
49
+ this.subscriptionChangeListeners = new Set();
48
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
+ */
49
58
  return _createClass(ReferenceSyncBlockStoreManager, [{
50
- key: "setFireAnalyticsEvent",
51
- value: function setFireAnalyticsEvent(fireAnalyticsEvent) {
52
- this.fireAnalyticsEvent = fireAnalyticsEvent;
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
+ }
53
72
  }
73
+
74
+ /**
75
+ * Checks if real-time subscriptions are currently enabled.
76
+ */
54
77
  }, {
55
- key: "setExperiences",
56
- value: function setExperiences(fetchExperience, fetchSourceInfoExperience, saveExperience) {
57
- // don't reset experiences after they have already been set
58
- if (!this.fetchExperience || !this.fetchSourceInfoExperience || !this.saveExperience) {
59
- this.fetchExperience = fetchExperience;
60
- this.fetchSourceInfoExperience = fetchSourceInfoExperience;
61
- this.saveExperience = saveExperience;
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);
62
144
  }
63
145
  }
146
+ }, {
147
+ key: "setFireAnalyticsEvent",
148
+ value: function setFireAnalyticsEvent(fireAnalyticsEvent) {
149
+ this.fireAnalyticsEvent = fireAnalyticsEvent;
150
+ this.fetchExperience = getFetchExperience(fireAnalyticsEvent);
151
+ this.fetchSourceInfoExperience = getFetchSourceInfoExperience(fireAnalyticsEvent);
152
+ this.saveExperience = getSaveReferenceExperience(fireAnalyticsEvent);
153
+ }
64
154
  }, {
65
155
  key: "generateResourceIdForReference",
66
156
  value: function generateResourceIdForReference(sourceId) {
@@ -84,26 +174,33 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
84
174
 
85
175
  /**
86
176
  * Refreshes the subscriptions for all sync blocks.
177
+ * This is a fallback polling mechanism when real-time subscriptions are not enabled.
87
178
  * @returns {Promise<void>}
88
179
  */
89
180
  }, {
90
181
  key: "refreshSubscriptions",
91
182
  value: (function () {
92
183
  var _refreshSubscriptions = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
93
- var syncBlocks, _iterator, _step, _loop, _this$fetchExperience, _this$fireAnalyticsEv;
184
+ var syncBlocks, _iterator, _step, _loop, _this$fireAnalyticsEv;
94
185
  return _regeneratorRuntime.wrap(function _callee$(_context2) {
95
186
  while (1) switch (_context2.prev = _context2.next) {
96
187
  case 0:
97
- if (!this.isRefreshingSubscriptions) {
188
+ if (!this.useRealTimeSubscriptions) {
98
189
  _context2.next = 2;
99
190
  break;
100
191
  }
101
192
  return _context2.abrupt("return");
102
193
  case 2:
194
+ if (!this.isRefreshingSubscriptions) {
195
+ _context2.next = 4;
196
+ break;
197
+ }
198
+ return _context2.abrupt("return");
199
+ case 4:
103
200
  this.isRefreshingSubscriptions = true;
104
201
  syncBlocks = [];
105
202
  _iterator = _createForOfIteratorHelper(this.subscriptions.entries());
106
- _context2.prev = 5;
203
+ _context2.prev = 7;
107
204
  _loop = /*#__PURE__*/_regeneratorRuntime.mark(function _loop() {
108
205
  var _step$value, resourceId, callbacks;
109
206
  return _regeneratorRuntime.wrap(function _loop$(_context) {
@@ -120,72 +217,165 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
120
217
  }, _loop);
121
218
  });
122
219
  _iterator.s();
123
- case 8:
220
+ case 10:
124
221
  if ((_step = _iterator.n()).done) {
125
- _context2.next = 12;
222
+ _context2.next = 14;
126
223
  break;
127
224
  }
128
- return _context2.delegateYield(_loop(), "t0", 10);
129
- case 10:
130
- _context2.next = 8;
131
- break;
225
+ return _context2.delegateYield(_loop(), "t0", 12);
132
226
  case 12:
133
- _context2.next = 17;
227
+ _context2.next = 10;
134
228
  break;
135
229
  case 14:
136
- _context2.prev = 14;
137
- _context2.t1 = _context2["catch"](5);
230
+ _context2.next = 19;
231
+ break;
232
+ case 16:
233
+ _context2.prev = 16;
234
+ _context2.t1 = _context2["catch"](7);
138
235
  _iterator.e(_context2.t1);
139
- case 17:
140
- _context2.prev = 17;
236
+ case 19:
237
+ _context2.prev = 19;
141
238
  _iterator.f();
142
- return _context2.finish(17);
143
- case 20:
144
- _context2.prev = 20;
145
- _context2.next = 23;
239
+ return _context2.finish(19);
240
+ case 22:
241
+ _context2.prev = 22;
242
+ _context2.next = 25;
146
243
  return this.fetchSyncBlocksData(syncBlocks);
147
- case 23:
148
- _context2.next = 29;
149
- break;
150
244
  case 25:
151
- _context2.prev = 25;
152
- _context2.t2 = _context2["catch"](20);
245
+ _context2.next = 31;
246
+ break;
247
+ case 27:
248
+ _context2.prev = 27;
249
+ _context2.t2 = _context2["catch"](22);
153
250
  logException(_context2.t2, {
154
251
  location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
155
252
  });
156
- if (fg('platform_synced_block_dogfooding')) {
157
- (_this$fetchExperience = this.fetchExperience) === null || _this$fetchExperience === void 0 || _this$fetchExperience.failure({
158
- reason: _context2.t2.message
159
- });
160
- } else {
161
- (_this$fireAnalyticsEv = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv === void 0 || _this$fireAnalyticsEv.call(this, fetchErrorPayload(_context2.t2.message));
162
- }
163
- case 29:
164
- _context2.prev = 29;
253
+ (_this$fireAnalyticsEv = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv === void 0 || _this$fireAnalyticsEv.call(this, fetchErrorPayload(_context2.t2.message));
254
+ case 31:
255
+ _context2.prev = 31;
165
256
  this.isRefreshingSubscriptions = false;
166
- return _context2.finish(29);
167
- case 32:
257
+ return _context2.finish(31);
258
+ case 34:
168
259
  case "end":
169
260
  return _context2.stop();
170
261
  }
171
- }, _callee, this, [[5, 14, 17, 20], [20, 25, 29, 32]]);
262
+ }, _callee, this, [[7, 16, 19, 22], [22, 27, 31, 34]]);
172
263
  }));
173
264
  function refreshSubscriptions() {
174
265
  return _refreshSubscriptions.apply(this, arguments);
175
266
  }
176
267
  return refreshSubscriptions;
177
- }())
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
+ }
178
373
  }, {
179
374
  key: "fetchSyncBlockSourceInfo",
180
375
  value: function fetchSyncBlockSourceInfo(resourceId) {
181
- var _this = this;
376
+ var _this4 = this;
182
377
  try {
183
378
  if (!resourceId || !this.dataProvider) {
184
- // make sure experience has been started before throwing error
185
- if (fg('platform_synced_block_dogfooding')) {
186
- var _this$fetchSourceInfo;
187
- (_this$fetchSourceInfo = this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo === void 0 || _this$fetchSourceInfo.start({});
188
- }
189
379
  throw new Error('Data provider or resourceId not set');
190
380
  }
191
381
  if (fg('platform_synced_block_dogfooding')) {
@@ -198,10 +388,6 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
198
388
  }
199
389
  var existingSyncBlock = this.getFromCache(resourceId);
200
390
  if (!existingSyncBlock) {
201
- if (fg('platform_synced_block_dogfooding')) {
202
- var _this$fetchSourceInfo2;
203
- (_this$fetchSourceInfo2 = this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo2 === void 0 || _this$fetchSourceInfo2.start({});
204
- }
205
391
  throw new Error('No existing sync block to fetch source info for');
206
392
  }
207
393
  var _ref = existingSyncBlock.data || {},
@@ -210,7 +396,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
210
396
  blockInstanceId = _ref.blockInstanceId,
211
397
  sourceURL = _ref.sourceURL,
212
398
  sourceTitle = _ref.sourceTitle,
213
- onSamePage = _ref.onSamePage,
399
+ onSameDocument = _ref.onSameDocument,
214
400
  sourceSubType = _ref.sourceSubType;
215
401
  // skip if source URL and title are already present
216
402
  if (sourceURL && sourceTitle) {
@@ -220,73 +406,65 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
220
406
  url: sourceURL,
221
407
  subType: sourceSubType,
222
408
  sourceAri: sourceAri || '',
223
- onSamePage: onSamePage,
409
+ onSameDocument: onSameDocument,
224
410
  productType: product
225
411
  });
226
412
  } else {
227
413
  return Promise.resolve(undefined);
228
414
  }
229
415
  }
230
-
231
- // only start experience if there is data to fetch
232
- if (fg('platform_synced_block_dogfooding')) {
233
- var _this$fetchSourceInfo3;
234
- (_this$fetchSourceInfo3 = this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo3 === void 0 || _this$fetchSourceInfo3.start({});
235
- }
236
416
  if (!sourceAri || !product || !blockInstanceId) {
237
- if (fg('platform_synced_block_dogfooding')) {
238
- var _this$fetchSourceInfo4;
239
- (_this$fetchSourceInfo4 = this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo4 === void 0 || _this$fetchSourceInfo4.failure({
240
- reason: 'SourceAri, product or blockInstanceId missing'
241
- });
242
- } else {
243
- var _this$fireAnalyticsEv2;
244
- (_this$fireAnalyticsEv2 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv2 === void 0 || _this$fireAnalyticsEv2.call(this, getSourceInfoErrorPayload('SourceAri, product or blockInstanceId missing'));
245
- }
417
+ var _this$fireAnalyticsEv2;
418
+ (_this$fireAnalyticsEv2 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv2 === void 0 || _this$fireAnalyticsEv2.call(this, getSourceInfoErrorPayload('SourceAri, product or blockInstanceId missing', resourceId));
246
419
  return Promise.resolve(undefined);
247
420
  }
421
+ if (fg('platform_synced_block_dogfooding')) {
422
+ var _this$fetchSourceInfo;
423
+ (_this$fetchSourceInfo = this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo === void 0 || _this$fetchSourceInfo.start({});
424
+ }
248
425
  var sourceInfoPromise = this.dataProvider.fetchSyncBlockSourceInfo(blockInstanceId, sourceAri, product, this.fireAnalyticsEvent).then(function (sourceInfo) {
249
426
  if (!sourceInfo) {
250
427
  if (fg('platform_synced_block_dogfooding')) {
251
- var _this$fetchSourceInfo5;
252
- (_this$fetchSourceInfo5 = _this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo5 === void 0 || _this$fetchSourceInfo5.failure({
428
+ var _this4$fetchSourceInf, _this4$fireAnalyticsE;
429
+ (_this4$fetchSourceInf = _this4.fetchSourceInfoExperience) === null || _this4$fetchSourceInf === void 0 || _this4$fetchSourceInf.failure({
253
430
  reason: 'No source info returned'
254
431
  });
432
+ (_this4$fireAnalyticsE = _this4.fireAnalyticsEvent) === null || _this4$fireAnalyticsE === void 0 || _this4$fireAnalyticsE.call(_this4, getSourceInfoErrorPayload('No source info returned', resourceId));
255
433
  }
256
434
  return undefined;
257
435
  }
258
- _this.updateCacheWithSourceInfo(resourceId, sourceInfo);
436
+ _this4.updateCacheWithSourceInfo(resourceId, sourceInfo);
259
437
  if (sourceInfo.title) {
260
- _this.updateSourceTitleSubscriptions(resourceId, sourceInfo.title);
438
+ _this4.updateSourceTitleSubscriptions(resourceId, sourceInfo.title);
261
439
  }
262
440
  if (fg('platform_synced_block_dogfooding')) {
263
441
  if (sourceInfo.title && sourceInfo.url) {
264
- var _this$fetchSourceInfo6;
265
- (_this$fetchSourceInfo6 = _this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo6 === void 0 || _this$fetchSourceInfo6.success();
442
+ var _this4$fetchSourceInf2;
443
+ (_this4$fetchSourceInf2 = _this4.fetchSourceInfoExperience) === null || _this4$fetchSourceInf2 === void 0 || _this4$fetchSourceInf2.success();
266
444
  } else {
267
- var _this$fetchSourceInfo7;
268
- (_this$fetchSourceInfo7 = _this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo7 === void 0 || _this$fetchSourceInfo7.failure({
445
+ var _this4$fetchSourceInf3, _this4$fireAnalyticsE2;
446
+ (_this4$fetchSourceInf3 = _this4.fetchSourceInfoExperience) === null || _this4$fetchSourceInf3 === void 0 || _this4$fetchSourceInf3.failure({
269
447
  reason: 'Missing title or url'
270
448
  });
449
+ (_this4$fireAnalyticsE2 = _this4.fireAnalyticsEvent) === null || _this4$fireAnalyticsE2 === void 0 || _this4$fireAnalyticsE2.call(_this4, getSourceInfoErrorPayload('Missing title or url', resourceId));
271
450
  }
272
451
  return sourceInfo;
273
452
  }
274
453
  }).catch(function (error) {
454
+ var _this4$fireAnalyticsE3;
275
455
  if (fg('platform_synced_block_dogfooding')) {
276
- var _this$fetchSourceInfo8;
277
- (_this$fetchSourceInfo8 = _this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo8 === void 0 || _this$fetchSourceInfo8.failure({
456
+ var _this4$fetchSourceInf4;
457
+ (_this4$fetchSourceInf4 = _this4.fetchSourceInfoExperience) === null || _this4$fetchSourceInf4 === void 0 || _this4$fetchSourceInf4.failure({
278
458
  reason: error.message
279
459
  });
280
- } else {
281
- var _this$fireAnalyticsEv3;
282
- (_this$fireAnalyticsEv3 = _this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv3 === void 0 || _this$fireAnalyticsEv3.call(_this, getSourceInfoErrorPayload(error.message));
283
460
  }
461
+ (_this4$fireAnalyticsE3 = _this4.fireAnalyticsEvent) === null || _this4$fireAnalyticsE3 === void 0 || _this4$fireAnalyticsE3.call(_this4, getSourceInfoErrorPayload(error.message, resourceId));
284
462
  return undefined;
285
463
  }).finally(function () {
286
464
  if (fg('platform_synced_block_dogfooding')) {
287
- _this.syncBlockSourceInfoRequests.delete(resourceId);
465
+ _this4.syncBlockSourceInfoRequests.delete(resourceId);
288
466
  } else {
289
- _this.syncBlockSourceInfoRequestsOld.delete(resourceId);
467
+ _this4.syncBlockSourceInfoRequestsOld.delete(resourceId);
290
468
  }
291
469
  });
292
470
  if (fg('platform_synced_block_dogfooding')) {
@@ -296,18 +474,11 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
296
474
  this.syncBlockSourceInfoRequestsOld.set(resourceId, true);
297
475
  }
298
476
  } catch (error) {
477
+ var _this$fireAnalyticsEv3;
299
478
  logException(error, {
300
479
  location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
301
480
  });
302
- if (fg('platform_synced_block_dogfooding')) {
303
- var _this$fetchSourceInfo9;
304
- (_this$fetchSourceInfo9 = this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo9 === void 0 || _this$fetchSourceInfo9.failure({
305
- reason: error.message
306
- });
307
- } else {
308
- var _this$fireAnalyticsEv4;
309
- (_this$fireAnalyticsEv4 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv4 === void 0 || _this$fireAnalyticsEv4.call(this, getSourceInfoErrorPayload(error.message));
310
- }
481
+ (_this$fireAnalyticsEv3 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv3 === void 0 || _this$fireAnalyticsEv3.call(this, getSourceInfoErrorPayload(error.message, resourceId));
311
482
  }
312
483
  return Promise.resolve(undefined);
313
484
  }
@@ -321,8 +492,8 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
321
492
  key: "fetchSyncBlocksData",
322
493
  value: (function () {
323
494
  var _fetchSyncBlocksData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(syncBlockNodes) {
324
- var _this2 = this;
325
- var nodesToFetch, _this$fetchExperience2, data, resolvedData, successfulFetched, failedFetch, _this$fetchExperience3, _this$fetchExperience4;
495
+ var _this5 = this;
496
+ var nodesToFetch, _this$fetchExperience, data, resolvedData, hasUnexpectedError, hasExpectedError, _this$fetchExperience2, _this$fetchExperience3, _this$fetchExperience4;
326
497
  return _regeneratorRuntime.wrap(function _callee2$(_context3) {
327
498
  while (1) switch (_context3.prev = _context3.next) {
328
499
  case 0:
@@ -335,10 +506,10 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
335
506
  // Don't fetch for not_found error since the source is already deleted
336
507
  nodesToFetch = [];
337
508
  syncBlockNodes.forEach(function (node) {
338
- if (_this2.syncBlockFetchDataRequests.get(node.attrs.resourceId)) {
509
+ if (_this5.syncBlockFetchDataRequests.get(node.attrs.resourceId)) {
339
510
  return;
340
511
  }
341
- var existingSyncBlock = _this2.getFromCache(node.attrs.resourceId);
512
+ var existingSyncBlock = _this5.getFromCache(node.attrs.resourceId);
342
513
  if ((existingSyncBlock === null || existingSyncBlock === void 0 ? void 0 : existingSyncBlock.error) === SyncBlockError.NotFound) {
343
514
  return;
344
515
  }
@@ -350,77 +521,65 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
350
521
  }
351
522
  return _context3.abrupt("return");
352
523
  case 6:
353
- // only start fetch experience if there is data to fetch
354
- if (fg('platform_synced_block_dogfooding')) {
355
- (_this$fetchExperience2 = this.fetchExperience) === null || _this$fetchExperience2 === void 0 || _this$fetchExperience2.start({});
356
- }
357
524
  if (this.dataProvider) {
358
- _context3.next = 9;
525
+ _context3.next = 8;
359
526
  break;
360
527
  }
361
528
  throw new Error('Data provider not set');
362
- case 9:
529
+ case 8:
363
530
  nodesToFetch.forEach(function (node) {
364
- _this2.syncBlockFetchDataRequests.set(node.attrs.resourceId, true);
531
+ _this5.syncBlockFetchDataRequests.set(node.attrs.resourceId, true);
365
532
  });
533
+ if (fg('platform_synced_block_dogfooding')) {
534
+ (_this$fetchExperience = this.fetchExperience) === null || _this$fetchExperience === void 0 || _this$fetchExperience.start({});
535
+ }
366
536
  _context3.next = 12;
367
537
  return this.dataProvider.fetchNodesData(nodesToFetch).finally(function () {
368
538
  nodesToFetch.forEach(function (node) {
369
- _this2.syncBlockFetchDataRequests.delete(node.attrs.resourceId);
539
+ _this5.syncBlockFetchDataRequests.delete(node.attrs.resourceId);
370
540
  });
371
541
  });
372
542
  case 12:
373
543
  data = _context3.sent;
374
544
  resolvedData = [];
375
- successfulFetched = [];
376
- failedFetch = [];
545
+ hasUnexpectedError = false;
546
+ hasExpectedError = false;
377
547
  data.forEach(function (syncBlockInstance) {
378
548
  if (!syncBlockInstance.resourceId) {
379
- if (fg('platform_synced_block_dogfooding')) {
380
- failedFetch.push({
381
- reason: syncBlockInstance.error || 'Returned sync block instance does not have resource id'
382
- });
383
- } else {
384
- var _this2$fireAnalyticsE;
385
- (_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'));
386
- }
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'));
387
551
  return;
388
552
  }
389
- var existingSyncBlock = _this2.getFromCache(syncBlockInstance.resourceId);
553
+ var existingSyncBlock = _this5.getFromCache(syncBlockInstance.resourceId);
390
554
  var resolvedSyncBlockInstance = existingSyncBlock ? resolveSyncBlockInstance(existingSyncBlock, syncBlockInstance) : syncBlockInstance;
391
- _this2.updateCache(resolvedSyncBlockInstance);
555
+ _this5.updateCache(resolvedSyncBlockInstance);
392
556
  resolvedData.push(resolvedSyncBlockInstance);
393
557
  if (syncBlockInstance.error) {
394
- if (fg('platform_synced_block_dogfooding')) {
395
- failedFetch.push({
396
- reason: syncBlockInstance.error,
397
- resourceId: syncBlockInstance.resourceId
398
- });
399
- } else {
400
- var _this2$fireAnalyticsE2;
401
- (_this2$fireAnalyticsE2 = _this2.fireAnalyticsEvent) === null || _this2$fireAnalyticsE2 === void 0 || _this2$fireAnalyticsE2.call(_this2, fetchErrorPayload(syncBlockInstance.error));
558
+ var _this5$fireAnalyticsE2;
559
+ (_this5$fireAnalyticsE2 = _this5.fireAnalyticsEvent) === null || _this5$fireAnalyticsE2 === void 0 || _this5$fireAnalyticsE2.call(_this5, fetchErrorPayload(syncBlockInstance.error, syncBlockInstance.resourceId));
560
+ if (syncBlockInstance.error === SyncBlockError.NotFound || syncBlockInstance.error === SyncBlockError.Forbidden) {
561
+ hasExpectedError = true;
562
+ } else if (syncBlockInstance.error) {
563
+ hasUnexpectedError = true;
402
564
  }
403
565
  return;
566
+ } else if (fg('platform_synced_block_dogfooding')) {
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));
404
569
  }
405
- successfulFetched.push(syncBlockInstance.resourceId);
406
- _this2.fetchSyncBlockSourceInfo(resolvedSyncBlockInstance.resourceId);
570
+ _this5.fetchSyncBlockSourceInfo(resolvedSyncBlockInstance.resourceId);
407
571
  });
408
572
  if (fg('platform_synced_block_dogfooding')) {
409
- if (data.every(function (syncBlockInstance) {
410
- return syncBlockInstance.resourceId && !syncBlockInstance.error;
411
- })) {
412
- (_this$fetchExperience3 = this.fetchExperience) === null || _this$fetchExperience3 === void 0 || _this$fetchExperience3.success({
413
- metadata: {
414
- successfulFetched: successfulFetched
415
- }
573
+ if (hasUnexpectedError) {
574
+ (_this$fetchExperience2 = this.fetchExperience) === null || _this$fetchExperience2 === void 0 || _this$fetchExperience2.failure({
575
+ reason: 'Unexpected error during fetch'
416
576
  });
417
- } else {
418
- (_this$fetchExperience4 = this.fetchExperience) === null || _this$fetchExperience4 === void 0 || _this$fetchExperience4.failure({
419
- metadata: {
420
- successfulFetched: successfulFetched,
421
- failedFetch: failedFetch
422
- }
577
+ } else if (hasExpectedError) {
578
+ (_this$fetchExperience3 = this.fetchExperience) === null || _this$fetchExperience3 === void 0 || _this$fetchExperience3.abort({
579
+ reason: 'Expected error: NotFound or PermissionDenied'
423
580
  });
581
+ } else {
582
+ (_this$fetchExperience4 = this.fetchExperience) === null || _this$fetchExperience4 === void 0 || _this$fetchExperience4.success();
424
583
  }
425
584
  }
426
585
  case 18:
@@ -443,7 +602,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
443
602
  existingSyncBlock.data = _objectSpread(_objectSpread({}, existingSyncBlock.data), {}, {
444
603
  sourceURL: sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.url,
445
604
  sourceTitle: sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.title,
446
- onSamePage: sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.onSamePage,
605
+ onSameDocument: sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.onSameDocument,
447
606
  sourceSubType: sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.subType
448
607
  });
449
608
  this.updateCache(existingSyncBlock);
@@ -487,8 +646,8 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
487
646
  }, {
488
647
  key: "subscribeToSyncBlock",
489
648
  value: function subscribeToSyncBlock(resourceId, localId, callback) {
490
- var _this$dataProvider2,
491
- _this3 = this;
649
+ var _this$dataProvider3,
650
+ _this6 = this;
492
651
  // Cancel any pending cache deletion for this resourceId.
493
652
  // This handles the case where a block is moved - the old component unmounts
494
653
  // (scheduling deletion) but the new component mounts and subscribes before
@@ -501,41 +660,52 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
501
660
 
502
661
  // add to subscriptions map
503
662
  var resourceSubscriptions = this.subscriptions.get(resourceId) || {};
663
+ var isNewResourceSubscription = Object.keys(resourceSubscriptions).length === 0;
504
664
  this.subscriptions.set(resourceId, _objectSpread(_objectSpread({}, resourceSubscriptions), {}, _defineProperty({}, localId, callback)));
505
665
 
506
666
  // New subscription means new reference synced block is added to the document
507
667
  this.isCacheDirty = true;
668
+
669
+ // Notify listeners if this is a new resource subscription
670
+ if (isNewResourceSubscription) {
671
+ this.notifySubscriptionChangeListeners();
672
+ }
508
673
  var syncBlockNode = createSyncBlockNode(localId, resourceId);
509
674
 
510
675
  // call the callback immediately if we have cached data
511
676
  // prefer cache from store manager first, should update data provider to use the same cache
512
- 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);
513
678
  if (cachedData) {
514
679
  callback(cachedData);
515
680
  } else {
516
681
  this.fetchSyncBlocksData([syncBlockNode]).catch(function (error) {
682
+ var _this6$fireAnalyticsE;
517
683
  logException(error, {
518
684
  location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
519
685
  });
520
- if (fg('platform_synced_block_dogfooding')) {
521
- var _this3$fetchExperienc;
522
- (_this3$fetchExperienc = _this3.fetchExperience) === null || _this3$fetchExperienc === void 0 || _this3$fetchExperienc.failure({
523
- reason: error.message
524
- });
525
- } else {
526
- var _this3$fireAnalyticsE;
527
- (_this3$fireAnalyticsE = _this3.fireAnalyticsEvent) === null || _this3$fireAnalyticsE === void 0 || _this3$fireAnalyticsE.call(_this3, fetchErrorPayload(error.message));
528
- }
686
+ (_this6$fireAnalyticsE = _this6.fireAnalyticsEvent) === null || _this6$fireAnalyticsE === void 0 || _this6$fireAnalyticsE.call(_this6, fetchErrorPayload(error.message, resourceId));
529
687
  });
530
688
  }
689
+
690
+ // Set up GraphQL subscription if real-time subscriptions are enabled
691
+ if (this.useRealTimeSubscriptions) {
692
+ this.setupGraphQLSubscription(resourceId);
693
+ }
531
694
  return function () {
532
- var resourceSubscriptions = _this3.subscriptions.get(resourceId);
695
+ var resourceSubscriptions = _this6.subscriptions.get(resourceId);
533
696
  if (resourceSubscriptions) {
534
697
  // Unsubscription means a reference synced block is removed from the document
535
- _this3.isCacheDirty = true;
698
+ _this6.isCacheDirty = true;
536
699
  delete resourceSubscriptions[localId];
537
700
  if (Object.keys(resourceSubscriptions).length === 0) {
538
- _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
+
539
709
  // Delay cache deletion to handle block moves (unmount/remount).
540
710
  // When a block is moved, the old component unmounts before the new one mounts.
541
711
  // By delaying deletion, we give the new component time to subscribe and
@@ -543,14 +713,14 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
543
713
  // TODO: EDITOR-4152 - Rework this logic
544
714
  var deletionTimeout = setTimeout(function () {
545
715
  // Only delete if still no subscribers (wasn't re-subscribed)
546
- if (!_this3.subscriptions.has(resourceId)) {
547
- _this3.deleteFromCache(resourceId);
716
+ if (!_this6.subscriptions.has(resourceId)) {
717
+ _this6.deleteFromCache(resourceId);
548
718
  }
549
- _this3.pendingCacheDeletions.delete(resourceId);
719
+ _this6.pendingCacheDeletions.delete(resourceId);
550
720
  }, 1000);
551
- _this3.pendingCacheDeletions.set(resourceId, deletionTimeout);
721
+ _this6.pendingCacheDeletions.set(resourceId, deletionTimeout);
552
722
  } else {
553
- _this3.subscriptions.set(resourceId, resourceSubscriptions);
723
+ _this6.subscriptions.set(resourceId, resourceSubscriptions);
554
724
  }
555
725
  }
556
726
  };
@@ -559,7 +729,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
559
729
  key: "subscribeToSourceTitle",
560
730
  value: function subscribeToSourceTitle(node, callback) {
561
731
  var _cachedData$data,
562
- _this4 = this;
732
+ _this7 = this;
563
733
  // check node is a sync block, as we only support sync block subscriptions
564
734
  if (node.type.name !== 'syncBlock') {
565
735
  return function () {};
@@ -579,13 +749,13 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
579
749
  var resourceSubscriptions = this.titleSubscriptions.get(resourceId) || {};
580
750
  this.titleSubscriptions.set(resourceId, _objectSpread(_objectSpread({}, resourceSubscriptions), {}, _defineProperty({}, localId, callback)));
581
751
  return function () {
582
- var resourceSubscriptions = _this4.titleSubscriptions.get(resourceId);
752
+ var resourceSubscriptions = _this7.titleSubscriptions.get(resourceId);
583
753
  if (resourceSubscriptions) {
584
754
  delete resourceSubscriptions[localId];
585
755
  if (Object.keys(resourceSubscriptions).length === 0) {
586
- _this4.titleSubscriptions.delete(resourceId);
756
+ _this7.titleSubscriptions.delete(resourceId);
587
757
  } else {
588
- _this4.titleSubscriptions.set(resourceId, resourceSubscriptions);
758
+ _this7.titleSubscriptions.set(resourceId, resourceSubscriptions);
589
759
  }
590
760
  }
591
761
  };
@@ -606,11 +776,11 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
606
776
  }
607
777
  return this.subscribeToSyncBlock(resourceId, localId, callback);
608
778
  } catch (error) {
609
- var _this$fireAnalyticsEv5;
779
+ var _this$fireAnalyticsEv4;
610
780
  logException(error, {
611
781
  location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
612
782
  });
613
- (_this$fireAnalyticsEv5 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv5 === void 0 || _this$fireAnalyticsEv5.call(this, fetchErrorPayload(error.message));
783
+ (_this$fireAnalyticsEv4 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv4 === void 0 || _this$fireAnalyticsEv4.call(this, fetchErrorPayload(error.message));
614
784
  return function () {};
615
785
  }
616
786
  }
@@ -634,12 +804,12 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
634
804
  key: "getProviderFactory",
635
805
  value: function getProviderFactory(resourceId) {
636
806
  if (!this.dataProvider) {
637
- var _this$fireAnalyticsEv6;
807
+ var _this$fireAnalyticsEv5;
638
808
  var error = new Error('Data provider not set');
639
809
  logException(error, {
640
810
  location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
641
811
  });
642
- (_this$fireAnalyticsEv6 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv6 === void 0 || _this$fireAnalyticsEv6.call(this, fetchErrorPayload(error.message));
812
+ (_this$fireAnalyticsEv5 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv5 === void 0 || _this$fireAnalyticsEv5.call(this, fetchErrorPayload(error.message));
643
813
  return undefined;
644
814
  }
645
815
  var _this$dataProvider$ge = this.dataProvider.getSyncedBlockRendererProviderOptions(),
@@ -668,11 +838,11 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
668
838
  try {
669
839
  this.retrieveDynamicProviders(resourceId, providerFactory, providerCreator);
670
840
  } catch (error) {
671
- var _this$fireAnalyticsEv7;
841
+ var _this$fireAnalyticsEv6;
672
842
  logException(error, {
673
843
  location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
674
844
  });
675
- (_this$fireAnalyticsEv7 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv7 === void 0 || _this$fireAnalyticsEv7.call(this, fetchErrorPayload(error.message));
845
+ (_this$fireAnalyticsEv6 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv6 === void 0 || _this$fireAnalyticsEv6.call(this, fetchErrorPayload(error.message, resourceId));
676
846
  }
677
847
  }
678
848
  return providerFactory;
@@ -728,9 +898,12 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
728
898
  return;
729
899
  }
730
900
  var syncBlock = this.getFromCache(resourceId);
731
- if (!syncBlock || !((_syncBlock$data2 = syncBlock.data) !== null && _syncBlock$data2 !== void 0 && _syncBlock$data2.sourceAri) || !((_syncBlock$data3 = syncBlock.data) !== null && _syncBlock$data3 !== void 0 && _syncBlock$data3.product)) {
732
- var _this$fireAnalyticsEv8;
733
- (_this$fireAnalyticsEv8 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv8 === void 0 || _this$fireAnalyticsEv8.call(this, fetchErrorPayload('Sync block or source ari or product not found'));
901
+ if (!syncBlock) {
902
+ return;
903
+ }
904
+ 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)) {
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'));
734
907
  return;
735
908
  }
736
909
  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);
@@ -780,7 +953,7 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
780
953
  key: "flush",
781
954
  value: (function () {
782
955
  var _flush = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
783
- var success, blocks, _this$saveExperience, updateResult, _this$saveExperience2, _this$fireAnalyticsEv9, _this$saveExperience3, _this$fireAnalyticsEv0, _this$saveExperience4;
956
+ var success, blocks, _this$saveExperience, updateResult, _this$fireAnalyticsEv8, _this$saveExperience2, _this$fireAnalyticsEv9, _this$saveExperience3, _this$saveExperience4;
784
957
  return _regeneratorRuntime.wrap(function _callee3$(_context4) {
785
958
  while (1) switch (_context4.prev = _context4.next) {
786
959
  case 0:
@@ -804,16 +977,17 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
804
977
  });
805
978
  });
806
979
  });
980
+ if (fg('platform_synced_block_dogfooding')) {
981
+ _context4.next = 10;
982
+ break;
983
+ }
807
984
  if (!(blocks.length === 0)) {
808
- _context4.next = 9;
985
+ _context4.next = 10;
809
986
  break;
810
987
  }
811
988
  this.isCacheDirty = false;
812
989
  return _context4.abrupt("return", true);
813
- case 9:
814
- if (fg('platform_synced_block_dogfooding')) {
815
- (_this$saveExperience = this.saveExperience) === null || _this$saveExperience === void 0 || _this$saveExperience.start();
816
- }
990
+ case 10:
817
991
  if (this.dataProvider) {
818
992
  _context4.next = 12;
819
993
  break;
@@ -826,9 +1000,12 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
826
1000
  // is still making changes, the new changes might not be saved if they all happen
827
1001
  // exactly at a time when the updateReferenceData is being executed asynchronously.
828
1002
  this.isCacheDirty = false;
829
- _context4.next = 15;
1003
+ if (fg('platform_synced_block_dogfooding')) {
1004
+ (_this$saveExperience = this.saveExperience) === null || _this$saveExperience === void 0 || _this$saveExperience.start();
1005
+ }
1006
+ _context4.next = 16;
830
1007
  return this.dataProvider.updateReferenceData(blocks);
831
- case 15:
1008
+ case 16:
832
1009
  updateResult = _context4.sent;
833
1010
  if (!updateResult.success) {
834
1011
  success = false;
@@ -836,14 +1013,13 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
836
1013
  (_this$saveExperience2 = this.saveExperience) === null || _this$saveExperience2 === void 0 || _this$saveExperience2.failure({
837
1014
  reason: updateResult.error || 'Failed to update reference synced blocks on the document'
838
1015
  });
839
- } else {
840
- (_this$fireAnalyticsEv9 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv9 === void 0 || _this$fireAnalyticsEv9.call(this, updateReferenceErrorPayload(updateResult.error || 'Failed to update reference synced blocks on the document'));
841
1016
  }
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'));
842
1018
  }
843
- _context4.next = 24;
1019
+ _context4.next = 26;
844
1020
  break;
845
- case 19:
846
- _context4.prev = 19;
1021
+ case 20:
1022
+ _context4.prev = 20;
847
1023
  _context4.t0 = _context4["catch"](3);
848
1024
  success = false;
849
1025
  logException(_context4.t0, {
@@ -853,25 +1029,24 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
853
1029
  (_this$saveExperience3 = this.saveExperience) === null || _this$saveExperience3 === void 0 || _this$saveExperience3.failure({
854
1030
  reason: _context4.t0.message
855
1031
  });
856
- } else {
857
- (_this$fireAnalyticsEv0 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv0 === void 0 || _this$fireAnalyticsEv0.call(this, updateReferenceErrorPayload(_context4.t0.message));
858
1032
  }
859
- case 24:
860
- _context4.prev = 24;
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;
861
1036
  if (!success) {
862
1037
  // set isCacheDirty back to true for cases where it failed to update the reference synced blocks on the BE
863
1038
  this.isCacheDirty = true;
864
1039
  } else if (fg('platform_synced_block_dogfooding')) {
865
1040
  (_this$saveExperience4 = this.saveExperience) === null || _this$saveExperience4 === void 0 || _this$saveExperience4.success();
866
1041
  }
867
- return _context4.finish(24);
868
- case 27:
1042
+ return _context4.finish(26);
1043
+ case 29:
869
1044
  return _context4.abrupt("return", success);
870
- case 28:
1045
+ case 30:
871
1046
  case "end":
872
1047
  return _context4.stop();
873
1048
  }
874
- }, _callee3, this, [[3, 19, 24, 27]]);
1049
+ }, _callee3, this, [[3, 20, 26, 29]]);
875
1050
  }));
876
1051
  function flush() {
877
1052
  return _flush.apply(this, arguments);
@@ -881,6 +1056,9 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
881
1056
  }, {
882
1057
  key: "destroy",
883
1058
  value: function destroy() {
1059
+ var _this$saveExperience5, _this$fetchExperience5, _this$fetchSourceInfo2;
1060
+ // Clean up all GraphQL subscriptions first
1061
+ this.cleanupAllGraphQLSubscriptions();
884
1062
  this.dataProvider = undefined;
885
1063
  this.syncBlockCache.clear();
886
1064
  this.subscriptions.clear();
@@ -890,10 +1068,21 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
890
1068
  this.syncBlockSourceInfoRequests.clear();
891
1069
  this.providerFactories.clear();
892
1070
  this.isRefreshingSubscriptions = false;
1071
+ this.useRealTimeSubscriptions = false;
1072
+ this.subscriptionChangeListeners.clear();
893
1073
  this.providerFactories.forEach(function (providerFactory) {
894
1074
  providerFactory.destroy();
895
1075
  });
896
1076
  this.providerFactories.clear();
1077
+ (_this$saveExperience5 = this.saveExperience) === null || _this$saveExperience5 === void 0 || _this$saveExperience5.abort({
1078
+ reason: 'editor-destroyed'
1079
+ });
1080
+ (_this$fetchExperience5 = this.fetchExperience) === null || _this$fetchExperience5 === void 0 || _this$fetchExperience5.abort({
1081
+ reason: 'editor-destroyed'
1082
+ });
1083
+ (_this$fetchSourceInfo2 = this.fetchSourceInfoExperience) === null || _this$fetchSourceInfo2 === void 0 || _this$fetchSourceInfo2.abort({
1084
+ reason: 'editor-destroyed'
1085
+ });
897
1086
  this.fireAnalyticsEvent = undefined;
898
1087
  }
899
1088
  }]);