@atlaskit/editor-synced-block-provider 10.0.3 → 10.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/common/types.js +2 -3
  3. package/dist/cjs/hooks/useFetchSyncBlockData.js +4 -4
  4. package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +27 -56
  5. package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +22 -41
  6. package/dist/cjs/store-manager/syncBlockBatchFetcher.js +6 -12
  7. package/dist/cjs/store-manager/syncBlockProviderFactoryManager.js +3 -3
  8. package/dist/cjs/store-manager/syncBlockStoreManager.js +1 -5
  9. package/dist/cjs/store-manager/syncBlockSubscriptionManager.js +20 -85
  10. package/dist/cjs/utils/errorHandling.js +13 -32
  11. package/dist/es2019/common/types.js +2 -3
  12. package/dist/es2019/hooks/useFetchSyncBlockData.js +4 -5
  13. package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +26 -50
  14. package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +23 -42
  15. package/dist/es2019/store-manager/syncBlockBatchFetcher.js +6 -12
  16. package/dist/es2019/store-manager/syncBlockProviderFactoryManager.js +3 -3
  17. package/dist/es2019/store-manager/syncBlockStoreManager.js +1 -5
  18. package/dist/es2019/store-manager/syncBlockSubscriptionManager.js +25 -81
  19. package/dist/es2019/utils/errorHandling.js +13 -32
  20. package/dist/esm/common/types.js +2 -3
  21. package/dist/esm/hooks/useFetchSyncBlockData.js +4 -4
  22. package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +27 -56
  23. package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +22 -41
  24. package/dist/esm/store-manager/syncBlockBatchFetcher.js +6 -12
  25. package/dist/esm/store-manager/syncBlockProviderFactoryManager.js +3 -3
  26. package/dist/esm/store-manager/syncBlockStoreManager.js +1 -5
  27. package/dist/esm/store-manager/syncBlockSubscriptionManager.js +20 -85
  28. package/dist/esm/utils/errorHandling.js +13 -32
  29. package/dist/types/common/types.d.ts +2 -3
  30. package/dist/types/store-manager/referenceSyncBlockStoreManager.d.ts +3 -3
  31. package/dist/types/store-manager/sourceSyncBlockStoreManager.d.ts +5 -7
  32. package/dist/types/store-manager/syncBlockSubscriptionManager.d.ts +2 -5
  33. package/dist/types/utils/errorHandling.d.ts +11 -24
  34. package/package.json +3 -15
@@ -9,7 +9,6 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
9
9
  import { bind } from 'bind-event-listener';
10
10
  import { getDocument } from '@atlaskit/browser-apis';
11
11
  import { logException } from '@atlaskit/editor-common/monitoring';
12
- import { fg } from '@atlaskit/platform-feature-flags';
13
12
  import { buildFetchErrorAttribution, fetchErrorPayload, fetchSuccessPayload } from '../utils/errorHandling';
14
13
  import { resolveSyncBlockInstance } from '../utils/resolveSyncBlockInstance';
15
14
  import { getSourceProductFromResourceIdSafe } from '../utils/utils';
@@ -29,12 +28,7 @@ export var SyncBlockSubscriptionManager = /*#__PURE__*/function () {
29
28
  _defineProperty(this, "graphqlSubscriptions", new Map());
30
29
  _defineProperty(this, "subscriptionChangeListeners", new Set());
31
30
  _defineProperty(this, "useRealTimeSubscriptions", false);
32
- // Track pending cache deletions to handle block moves (unmount/remount)
33
- // When a block is moved, the old component unmounts before the new one mounts,
34
- // causing the cache to be deleted prematurely. We delay deletion to allow
35
- // the new component to subscribe and cancel the pending deletion.
36
- _defineProperty(this, "pendingCacheDeletions", new Map());
37
- // backoff cap (gate ON)
31
+ // backoff cap
38
32
  _defineProperty(this, "retryAttempts", new Map());
39
33
  _defineProperty(this, "pendingRetries", new Map());
40
34
  // Resources whose reconnection exhausted while the tab was hidden: parked here and
@@ -68,21 +62,17 @@ export var SyncBlockSubscriptionManager = /*#__PURE__*/function () {
68
62
  // EDITOR-7861: higher ceiling lets transient WS-gateway drops self-heal
69
63
  // before a terminal failure is surfaced.
70
64
  function getMaxRetryAttempts() {
71
- return fg('platform_editor_blocks_patch_3') ? SyncBlockSubscriptionManager.MAX_RETRY_ATTEMPTS_HARDENED : SyncBlockSubscriptionManager.MAX_RETRY_ATTEMPTS;
65
+ return SyncBlockSubscriptionManager.MAX_RETRY_ATTEMPTS_HARDENED;
72
66
  }
73
67
 
74
- // Backoff delay for the given attempt.
75
- // Gate OFF: pure exponential (1s, 2s, 4s, 8s, 16s).
76
- // Gate ON (EDITOR-7861): exponential capped at MAX_RETRY_DELAY_MS with equal
77
- // jitter (capped/2 + random*capped/2) — de-synchronises simultaneous
78
- // reconnects while guaranteeing a non-zero delay (full jitter could hit 0).
68
+ // Backoff delay for the given attempt (EDITOR-7861): exponential capped at
69
+ // MAX_RETRY_DELAY_MS with equal jitter (capped/2 + random*capped/2)
70
+ // de-synchronises simultaneous reconnects while guaranteeing a non-zero delay
71
+ // (full jitter could hit 0).
79
72
  }, {
80
73
  key: "getReconnectionDelay",
81
74
  value: function getReconnectionDelay(attempts) {
82
75
  var exponential = SyncBlockSubscriptionManager.INITIAL_RETRY_DELAY_MS * Math.pow(SyncBlockSubscriptionManager.RETRY_BACKOFF_MULTIPLIER, attempts);
83
- if (!fg('platform_editor_blocks_patch_3')) {
84
- return exponential;
85
- }
86
76
  var half = Math.min(exponential, SyncBlockSubscriptionManager.MAX_RETRY_DELAY_MS) / 2;
87
77
  return Math.round(half + Math.random() * half);
88
78
  }
@@ -135,7 +125,7 @@ export var SyncBlockSubscriptionManager = /*#__PURE__*/function () {
135
125
  logException(error, {
136
126
  location: 'editor-synced-block-provider/syncBlockSubscriptionManager/notifySubscriptionChangeListeners'
137
127
  });
138
- (_this3$deps$getFireAn = _this3.deps.getFireAnalyticsEvent()) === null || _this3$deps$getFireAn === void 0 || _this3$deps$getFireAn(fetchErrorPayload(error.message, undefined, undefined, buildFetchErrorAttribution(fg('platform_editor_blocks_patch_3'), error.message)));
128
+ (_this3$deps$getFireAn = _this3.deps.getFireAnalyticsEvent()) === null || _this3$deps$getFireAn === void 0 || _this3$deps$getFireAn(fetchErrorPayload(error.message, undefined, undefined, buildFetchErrorAttribution(error.message)));
139
129
  }
140
130
  });
141
131
  }
@@ -160,16 +150,7 @@ export var SyncBlockSubscriptionManager = /*#__PURE__*/function () {
160
150
  // This handles the case where a block is moved - the old component unmounts
161
151
  // (scheduling deletion) but the new component mounts and subscribes before
162
152
  // the deletion timeout fires.
163
- //
164
- // Under the flag, cache deletion is owned by the store manager.
165
- // With the flag off, the legacy 1s timer path is preserved.
166
- var pendingDeletion = this.pendingCacheDeletions.get(resourceId);
167
- if (fg('platform_synced_block_patch_14')) {
168
- this.deps.cancelPendingCacheDeletion(resourceId);
169
- } else if (pendingDeletion) {
170
- clearTimeout(pendingDeletion);
171
- this.pendingCacheDeletions.delete(resourceId);
172
- }
153
+ this.deps.cancelPendingCacheDeletion(resourceId);
173
154
 
174
155
  // add to subscriptions map
175
156
  var resourceSubscriptions = this.subscriptions.get(resourceId) || {};
@@ -210,30 +191,9 @@ export var SyncBlockSubscriptionManager = /*#__PURE__*/function () {
210
191
  // Notify listeners that subscription was removed
211
192
  _this4.notifySubscriptionChangeListeners();
212
193
 
213
- // Under the flag, delegate cache deletion to the store manager
194
+ // Delegate cache deletion to the store manager
214
195
  // which uses a 30s grace period with guard re-checks.
215
- if (fg('platform_synced_block_patch_14')) {
216
- _this4.deps.scheduleCacheDeletion(resourceId);
217
- } else {
218
- // Legacy path (unchanged): delay cache deletion to handle
219
- // block moves (unmount/remount). When a block is moved, the
220
- // old component unmounts before the new one mounts. By
221
- // delaying deletion, we give the new component time to
222
- // subscribe and cancel this pending deletion, preserving
223
- // the cached data.
224
- // TODO: EDITOR-4152 - Rework this logic (superseded by
225
- // `platform_synced_block_patch_14`).
226
- var deletionTimeout = setTimeout(function () {
227
- var hasSubscribers = _this4.subscriptions.has(resourceId);
228
-
229
- // Only delete if still no subscribers (wasn't re-subscribed)
230
- if (!hasSubscribers) {
231
- _this4.deps.deleteFromCache(resourceId);
232
- }
233
- _this4.pendingCacheDeletions.delete(resourceId);
234
- }, 1000);
235
- _this4.pendingCacheDeletions.set(resourceId, deletionTimeout);
236
- }
196
+ _this4.deps.scheduleCacheDeletion(resourceId);
237
197
  } else {
238
198
  _this4.subscriptions.set(resourceId, resourceSubscriptions);
239
199
  }
@@ -316,17 +276,10 @@ export var SyncBlockSubscriptionManager = /*#__PURE__*/function () {
316
276
  logException(error, {
317
277
  location: 'editor-synced-block-provider/syncBlockSubscriptionManager/graphql-subscription'
318
278
  });
319
- // EDITOR-7861: a single socket drop is usually transient and
320
- // recovers on reconnect, so under the gate we don't fire a
321
- // user-facing error here it's only surfaced on exhaustion (see
322
- // scheduleReconnection). Gate OFF keeps the legacy fire-on-drop.
323
- // This branch only runs when the gate is OFF, so buildFetchErrorAttribution
324
- // would return undefined; the structured attribution (EDITOR-7862) is therefore
325
- // applied at the gate-ON exhaustion site in scheduleReconnection instead.
326
- if (!fg('platform_editor_blocks_patch_3')) {
327
- var _this6$deps$getFireAn;
328
- (_this6$deps$getFireAn = _this6.deps.getFireAnalyticsEvent()) === null || _this6$deps$getFireAn === void 0 || _this6$deps$getFireAn(fetchErrorPayload(error.message, resourceId, getSourceProductFromResourceIdSafe(resourceId)));
329
- }
279
+ // EDITOR-7861: a single socket drop is usually transient and recovers
280
+ // on reconnect, so we don't fire a user-facing error here — it's only
281
+ // surfaced on exhaustion, where the structured attribution
282
+ // (EDITOR-7862) is applied too. See scheduleReconnection.
330
283
  _this6.handleSubscriptionTerminated(resourceId);
331
284
  }, function () {
332
285
  _this6.handleSubscriptionTerminated(resourceId);
@@ -369,24 +322,23 @@ export var SyncBlockSubscriptionManager = /*#__PURE__*/function () {
369
322
  if (attempts >= maxAttempts) {
370
323
  var _this$deps$getFireAna2;
371
324
  // Exhausted all attempts — the only place a WS drop surfaces as a
372
- // fetch error under the gate (EDITOR-7861).
325
+ // fetch error (EDITOR-7861).
373
326
  var errorMessage = "Subscription reconnection failed after ".concat(attempts, " attempts");
374
327
 
375
328
  // Tab hidden at exhaustion: don't surface a terminal failure (user isn't
376
329
  // looking, and most exhaustions self-recover once foregrounded). Park + re-arm
377
330
  // on wake, emitting a benign `deferred` signal so suppression stays auditable.
378
- var shouldDefer = fg('platform_editor_blocks_patch_3') && this.isDocumentHidden();
379
- if (shouldDefer) {
331
+ if (this.isDocumentHidden()) {
380
332
  var _this$deps$getFireAna;
381
333
  this.deferredExhausted.add(resourceId);
382
334
  this.registerWakeListeners();
383
- (_this$deps$getFireAna = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna === void 0 || _this$deps$getFireAna(fetchErrorPayload(errorMessage, resourceId, getSourceProductFromResourceIdSafe(resourceId), buildFetchErrorAttribution(true, errorMessage, undefined, /* deferred */true)));
335
+ (_this$deps$getFireAna = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna === void 0 || _this$deps$getFireAna(fetchErrorPayload(errorMessage, resourceId, getSourceProductFromResourceIdSafe(resourceId), buildFetchErrorAttribution(errorMessage, undefined, /* deferred */true)));
384
336
  return;
385
337
  }
386
338
  logException(new Error(errorMessage), {
387
339
  location: 'editor-synced-block-provider/syncBlockSubscriptionManager/max-retries-exhausted'
388
340
  });
389
- (_this$deps$getFireAna2 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna2 === void 0 || _this$deps$getFireAna2(fetchErrorPayload(errorMessage, resourceId, getSourceProductFromResourceIdSafe(resourceId), buildFetchErrorAttribution(fg('platform_editor_blocks_patch_3'), errorMessage)));
341
+ (_this$deps$getFireAna2 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna2 === void 0 || _this$deps$getFireAna2(fetchErrorPayload(errorMessage, resourceId, getSourceProductFromResourceIdSafe(resourceId), buildFetchErrorAttribution(errorMessage)));
390
342
  return;
391
343
  }
392
344
  var delay = this.getReconnectionDelay(attempts);
@@ -607,21 +559,6 @@ export var SyncBlockSubscriptionManager = /*#__PURE__*/function () {
607
559
  this.titleSubscriptions.clear();
608
560
  this.subscriptionChangeListeners.clear();
609
561
  this.useRealTimeSubscriptions = false;
610
-
611
- // Clear any pending cache deletions
612
- var _iterator5 = _createForOfIteratorHelper(this.pendingCacheDeletions.values()),
613
- _step5;
614
- try {
615
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
616
- var timeout = _step5.value;
617
- clearTimeout(timeout);
618
- }
619
- } catch (err) {
620
- _iterator5.e(err);
621
- } finally {
622
- _iterator5.f();
623
- }
624
- this.pendingCacheDeletions.clear();
625
562
  }
626
563
  }, {
627
564
  key: "shouldUseRealTime",
@@ -661,7 +598,7 @@ export var SyncBlockSubscriptionManager = /*#__PURE__*/function () {
661
598
  // Prefer the structured `type` (a `SyncBlockError` enum value) for classification
662
599
  // and fall back to the free-text `reason` so source-state/permission strings are
663
600
  // still bucketed (EDITOR-7862). The emitted free-text `error` attribute is unchanged.
664
- (_this$deps$getFireAna3 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna3 === void 0 || _this$deps$getFireAna3(fetchErrorPayload(errorMessage, syncBlockInstance.resourceId, (_syncBlockInstance$da3 = (_syncBlockInstance$da4 = syncBlockInstance.data) === null || _syncBlockInstance$da4 === void 0 ? void 0 : _syncBlockInstance$da4.product) !== null && _syncBlockInstance$da3 !== void 0 ? _syncBlockInstance$da3 : getSourceProductFromResourceIdSafe(syncBlockInstance.resourceId), buildFetchErrorAttribution(fg('platform_editor_blocks_patch_3'), ((_syncBlockInstance$er3 = syncBlockInstance.error) === null || _syncBlockInstance$er3 === void 0 ? void 0 : _syncBlockInstance$er3.type) || ((_syncBlockInstance$er4 = syncBlockInstance.error) === null || _syncBlockInstance$er4 === void 0 ? void 0 : _syncBlockInstance$er4.reason), (_syncBlockInstance$er5 = syncBlockInstance.error) === null || _syncBlockInstance$er5 === void 0 ? void 0 : _syncBlockInstance$er5.statusCode)));
601
+ (_this$deps$getFireAna3 = this.deps.getFireAnalyticsEvent()) === null || _this$deps$getFireAna3 === void 0 || _this$deps$getFireAna3(fetchErrorPayload(errorMessage, syncBlockInstance.resourceId, (_syncBlockInstance$da3 = (_syncBlockInstance$da4 = syncBlockInstance.data) === null || _syncBlockInstance$da4 === void 0 ? void 0 : _syncBlockInstance$da4.product) !== null && _syncBlockInstance$da3 !== void 0 ? _syncBlockInstance$da3 : getSourceProductFromResourceIdSafe(syncBlockInstance.resourceId), buildFetchErrorAttribution(((_syncBlockInstance$er3 = syncBlockInstance.error) === null || _syncBlockInstance$er3 === void 0 ? void 0 : _syncBlockInstance$er3.type) || ((_syncBlockInstance$er4 = syncBlockInstance.error) === null || _syncBlockInstance$er4 === void 0 ? void 0 : _syncBlockInstance$er4.reason), (_syncBlockInstance$er5 = syncBlockInstance.error) === null || _syncBlockInstance$er5 === void 0 ? void 0 : _syncBlockInstance$er5.statusCode)));
665
602
  }
666
603
  }
667
604
  }]);
@@ -669,10 +606,8 @@ export var SyncBlockSubscriptionManager = /*#__PURE__*/function () {
669
606
  // Reconnection with exponential backoff.
670
607
  _defineProperty(SyncBlockSubscriptionManager, "INITIAL_RETRY_DELAY_MS", 1000);
671
608
  _defineProperty(SyncBlockSubscriptionManager, "RETRY_BACKOFF_MULTIPLIER", 2);
672
- _defineProperty(SyncBlockSubscriptionManager, "MAX_RETRY_ATTEMPTS", 5);
673
- // legacy (gate OFF)
674
609
  _defineProperty(SyncBlockSubscriptionManager, "MAX_RETRY_ATTEMPTS_HARDENED", 8);
675
- // gate ON (EDITOR-7861)
610
+ // EDITOR-7861
676
611
  _defineProperty(SyncBlockSubscriptionManager, "MAX_RETRY_DELAY_MS", 30000);
677
612
  // Coalesce wake-event bursts into one re-arm sweep to avoid a reconnection storm.
678
613
  _defineProperty(SyncBlockSubscriptionManager, "WAKE_DEBOUNCE_MS", 1000);
@@ -61,17 +61,9 @@ export var classifyErrorReason = function classifyErrorReason(error) {
61
61
 
62
62
  /**
63
63
  * Builds the {@link ErrorAttributionAttributes} for a failed synced-block operation from
64
- * the raw result `error` field and optional backend `statusCode`. Returns `undefined`
65
- * when the `platform_editor_blocks_patch_3` gate is OFF, so the new `reason`/`statusCode`
66
- * attributes are only emitted once the gate is rolled out (EDITOR-7796).
67
- *
68
- * `gateEnabled` is injected by the caller (the store managers evaluate `fg(...)`) so this
69
- * helper stays pure and trivially unit-testable for both gate states.
64
+ * the raw result `error` field and optional backend `statusCode` (EDITOR-7796).
70
65
  */
71
- export var buildErrorAttribution = function buildErrorAttribution(gateEnabled, error, statusCode) {
72
- if (!gateEnabled) {
73
- return undefined;
74
- }
66
+ export var buildErrorAttribution = function buildErrorAttribution(error, statusCode) {
75
67
  return _objectSpread({
76
68
  reason: classifyErrorReason(error)
77
69
  }, statusCode !== undefined && {
@@ -186,17 +178,10 @@ export var classifyFetchErrorReason = function classifyFetchErrorReason(error) {
186
178
  /**
187
179
  * Builds the {@link FetchErrorAttributionAttributes} for a failed fetch/subscribe
188
180
  * synced-block operation from the raw `error` field and optional backend `statusCode`.
189
- * Returns `undefined` when the `platform_editor_blocks_patch_3` gate is OFF, so the new
190
- * `reason`/`statusCode`/`benign` attributes are only emitted once the gate is rolled out
191
- * (EDITOR-7862). The existing free-text `error` attribute is always left unchanged.
192
- *
193
- * `gateEnabled` is injected by the caller (the store managers evaluate `fg(...)`) so this
194
- * helper stays pure and trivially unit-testable for both gate states.
181
+ * Emits the `reason`/`statusCode`/`benign` attributes (EDITOR-7862). The existing
182
+ * free-text `error` attribute is always left unchanged.
195
183
  */
196
- export var buildFetchErrorAttribution = function buildFetchErrorAttribution(gateEnabled, error, statusCode, deferred) {
197
- if (!gateEnabled) {
198
- return undefined;
199
- }
184
+ export var buildFetchErrorAttribution = function buildFetchErrorAttribution(error, statusCode, deferred) {
200
185
  var reason = classifyFetchErrorReason(error);
201
186
  return _objectSpread(_objectSpread({
202
187
  reason: reason,
@@ -253,8 +238,8 @@ export function getErrorPayload(actionSubjectId, error, resourceId, sourceProduc
253
238
  export var fetchErrorPayload = function fetchErrorPayload(error, resourceId, sourceProduct, attribution) {
254
239
  return (
255
240
  // Branch on attribution presence so each call resolves to a concrete overload: with
256
- // attribution it hits the fetch overload (wider `reason`); without it (gate OFF) it
257
- // hits the no-attribution overload. Both produce a fetch event regardless.
241
+ // attribution it hits the fetch overload (wider `reason`); without it, the
242
+ // no-attribution overload. Both produce a fetch event regardless.
258
243
  attribution ? getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_FETCH, error, resourceId, sourceProduct, attribution) : getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_FETCH, error, resourceId, sourceProduct)
259
244
  );
260
245
  };
@@ -278,8 +263,7 @@ export var updateCacheErrorPayload = function updateCacheErrorPayload(error, res
278
263
  };
279
264
  /**
280
265
  * Payload for `SYNCED_BLOCK_SOURCE_INFO_ORPHANED`. Fired when source-info
281
- * resolves into a cache that has already been deleted — should be unreachable
282
- * under `platform_synced_block_patch_14`.
266
+ * resolves into a cache that has already been deleted — should be unreachable.
283
267
  */
284
268
  export var sourceInfoOrphanedPayload = function sourceInfoOrphanedPayload(resourceId, sourceProduct, context) {
285
269
  return {
@@ -354,14 +338,13 @@ export var createSuccessPayload = function createSuccessPayload(resourceId, sour
354
338
 
355
339
  /**
356
340
  * Optional enrichment for the `syncedBlockCreate` success event. All fields
357
- * optional so gate-off/legacy payloads are unchanged. `inputMethod`: creating
341
+ * optional so legacy payloads are unchanged. `inputMethod`: creating
358
342
  * surface (enum, PII-safe). `createdEmpty`: true from an empty selection, false
359
343
  * when content was converted.
360
344
  */
361
345
 
362
346
  /**
363
- * Operational `syncedBlockCreate` success event, behind
364
- * `platform_editor_blocks_patch_4`, with the `blockInstanceId` join key and,
347
+ * Operational `syncedBlockCreate` success event with the `blockInstanceId` join key and,
365
348
  * when available, the `inputMethod` + `createdEmpty` creation-type signals.
366
349
  */
367
350
  export var createSuccessOperationalPayload = function createSuccessOperationalPayload(resourceId, blockInstanceId, sourceProduct, enrichment) {
@@ -385,8 +368,7 @@ export var createSuccessOperationalPayload = function createSuccessOperationalPa
385
368
  };
386
369
 
387
370
  /**
388
- * Operational first-content-added event, behind
389
- * `platform_editor_blocks_patch_4`. Fired once when a block created empty first
371
+ * Operational first-content-added event. Fired once when a block created empty first
390
372
  * gains user content. Join keys only (`resourceId` + `blockInstanceId`), no user
391
373
  * content (PII-safe).
392
374
  */
@@ -422,9 +404,8 @@ export var updateSuccessPayload = function updateSuccessPayload(resourceId, hasR
422
404
  };
423
405
 
424
406
  /**
425
- * Optional enrichment for the `syncedBlockDelete` success event behind
426
- * `platform_editor_blocks_patch_4`. All fields optional so the gate-off payload
427
- * is unchanged; `blockInstanceId` is the bare-uuid join key.
407
+ * Optional enrichment for the `syncedBlockDelete` success event. All fields are
408
+ * optional for extensibility; `blockInstanceId` is the bare-uuid join key.
428
409
  */
429
410
 
430
411
  export var deleteSuccessPayload = function deleteSuccessPayload(resourceId, sourceProduct, enrichment) {
@@ -101,13 +101,12 @@ export type SyncBlockPrefetchData = {
101
101
  * asynchronously and `destroy()` nulls it on orphaned managers, so queued/
102
102
  * in-flight ops throw `Data provider not set` — previously mis-logged as a real
103
103
  * error. These let throw and catch sites agree on one non-string-matched signal
104
- * so the residual false errors are suppressed. Gated by
105
- * `platform_editor_blocks_patch_3`.
104
+ * so the residual false errors are suppressed.
106
105
  *
107
106
  * NB: these intentionally live here rather than in a dedicated module to avoid
108
107
  * adding a downstream file to consuming Jira packages' Thunderstone complexity.
109
108
  */
110
- /** Legacy message — kept identical for gate-off and historical events. */
109
+ /** Legacy message — kept identical for historical events. */
111
110
  export declare const PROVIDER_NOT_READY_MESSAGE = "Data provider not set";
112
111
  /**
113
112
  * Thrown when a fetch/subscribe runs against a manager whose provider is not
@@ -104,19 +104,19 @@ export declare class ReferenceSyncBlockStoreManager {
104
104
  /**
105
105
  * Returns true if the cache entry for `resourceId` is safe to delete:
106
106
  * no active subscribers, no in-flight source-info request, and no
107
- * queued/in-flight batch fetch (gated by `platform_synced_block_patch_14`).
107
+ * queued/in-flight batch fetch.
108
108
  */
109
109
  private canDeleteCache;
110
110
  /**
111
111
  * Schedules cache deletion for `resourceId` after the grace period
112
- * (gated by `platform_synced_block_patch_14`). Called when the last
112
+ * Called when the last
113
113
  * subscriber unsubscribes. Guards are re-checked at fire time; if any
114
114
  * are positive the timer is rescheduled up to MAX_RESCHEDULES times.
115
115
  */
116
116
  scheduleCacheDeletion(resourceId: ResourceId): void;
117
117
  /**
118
118
  * Cancels any pending cache deletion timer for `resourceId` and resets the
119
- * reschedule counter (gated by `platform_synced_block_patch_14`). Called
119
+ * reschedule counter. Called
120
120
  * when a new subscriber arrives.
121
121
  */
122
122
  cancelPendingCacheDeletion(resourceId: ResourceId): void;
@@ -63,8 +63,7 @@ export declare class SourceSyncBlockStoreManager {
63
63
  private fetchSourceInfoExperience;
64
64
  /**
65
65
  * resourceId -> timestamp (ms) of the last `syncedBlockDelete` emission, used
66
- * to suppress duplicates within {@link DELETE_DEDUPE_WINDOW_MS}. Only consulted
67
- * behind `platform_editor_blocks_patch_4`.
66
+ * to suppress duplicates within {@link DELETE_DEDUPE_WINDOW_MS}.
68
67
  */
69
68
  private recentDeleteEmissions;
70
69
  constructor(dataProvider?: SyncBlockDataProviderInterface, viewMode?: ViewMode, isLivePage?: boolean);
@@ -116,7 +115,6 @@ export declare class SourceSyncBlockStoreManager {
116
115
  * Fire the first-content-added event once when a block created empty this
117
116
  * session first gains content. The caller detects the in-block edit; this owns
118
117
  * dedupe + emission (fires at most once per block, only for empty→content).
119
- * Gated behind `platform_editor_blocks_patch_4`.
120
118
  */
121
119
  maybeEmitFirstContentAdded(resourceId: ResourceId, blockInstanceId?: BlockInstanceId): void;
122
120
  registerConfirmationCallback(callback: ConfirmationCallback): () => void;
@@ -143,10 +141,10 @@ export declare class SourceSyncBlockStoreManager {
143
141
  */
144
142
  private pruneRecentDeleteEmissions;
145
143
  /**
146
- * Emit the `syncedBlockDelete` success event. Gate off: legacy payload. Gate
147
- * on: attaches `deletionReason`, `mechanism` and `blockInstanceId`, and
148
- * suppresses repeat emissions within {@link DELETE_DEDUPE_WINDOW_MS}. Must run
149
- * while the cache entry still exists so `blockInstanceId` is available.
144
+ * Emit the `syncedBlockDelete` success event. Attaches `deletionReason`,
145
+ * `mechanism` and `blockInstanceId`, and suppresses repeat emissions within
146
+ * {@link DELETE_DEDUPE_WINDOW_MS}. Must run while the cache entry still exists
147
+ * so `blockInstanceId` is available.
150
148
  */
151
149
  private emitDeleteSuccess;
152
150
  private delete;
@@ -3,16 +3,15 @@ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
3
  import type { ResourceId, BlockInstanceId } from '../common/types';
4
4
  import type { SyncBlockInstance, SubscriptionCallback, SyncBlockDataProviderInterface, SyncBlockSourceInfo, TitleSubscriptionCallback } from '../providers/types';
5
5
  export interface SyncBlockSubscriptionManagerDeps {
6
- /** Cancels any pending cache deletion timer for `resourceId` (gated). */
6
+ /** Cancels any pending cache deletion timer for `resourceId`. */
7
7
  cancelPendingCacheDeletion: (resourceId: ResourceId) => void;
8
8
  debouncedBatchedFetchSyncBlocks: (resourceId: string) => void;
9
- deleteFromCache: (resourceId: ResourceId) => void;
10
9
  fetchSyncBlockSourceInfo: (resourceId: ResourceId) => Promise<SyncBlockSourceInfo | undefined>;
11
10
  getDataProvider: () => SyncBlockDataProviderInterface | undefined;
12
11
  getFireAnalyticsEvent: () => ((payload: RendererSyncBlockEventPayload) => void) | undefined;
13
12
  getFromCache: (resourceId: ResourceId) => SyncBlockInstance | undefined;
14
13
  markCacheDirty: () => void;
15
- /** Schedules guarded cache deletion for `resourceId` after a grace period (gated). */
14
+ /** Schedules guarded cache deletion for `resourceId` after a grace period. */
16
15
  scheduleCacheDeletion: (resourceId: ResourceId) => void;
17
16
  updateCache: (syncBlockInstance: SyncBlockInstance) => void;
18
17
  }
@@ -29,10 +28,8 @@ export declare class SyncBlockSubscriptionManager {
29
28
  private graphqlSubscriptions;
30
29
  private subscriptionChangeListeners;
31
30
  private useRealTimeSubscriptions;
32
- private pendingCacheDeletions;
33
31
  private static readonly INITIAL_RETRY_DELAY_MS;
34
32
  private static readonly RETRY_BACKOFF_MULTIPLIER;
35
- private static readonly MAX_RETRY_ATTEMPTS;
36
33
  private static readonly MAX_RETRY_ATTEMPTS_HARDENED;
37
34
  private static readonly MAX_RETRY_DELAY_MS;
38
35
  private retryAttempts;
@@ -42,14 +42,9 @@ export type ErrorAttributionAttributes = {
42
42
  };
43
43
  /**
44
44
  * Builds the {@link ErrorAttributionAttributes} for a failed synced-block operation from
45
- * the raw result `error` field and optional backend `statusCode`. Returns `undefined`
46
- * when the `platform_editor_blocks_patch_3` gate is OFF, so the new `reason`/`statusCode`
47
- * attributes are only emitted once the gate is rolled out (EDITOR-7796).
48
- *
49
- * `gateEnabled` is injected by the caller (the store managers evaluate `fg(...)`) so this
50
- * helper stays pure and trivially unit-testable for both gate states.
45
+ * the raw result `error` field and optional backend `statusCode` (EDITOR-7796).
51
46
  */
52
- export declare const buildErrorAttribution: (gateEnabled: boolean, error?: string, statusCode?: number) => ErrorAttributionAttributes | undefined;
47
+ export declare const buildErrorAttribution: (error?: string, statusCode?: number) => ErrorAttributionAttributes;
53
48
  /**
54
49
  * The set of categorical failure reasons emitted on synced-block fetch/subscribe
55
50
  * operational error events (EDITOR-7862). Extends the write-path
@@ -122,14 +117,10 @@ export type FetchErrorAttributionAttributes = {
122
117
  /**
123
118
  * Builds the {@link FetchErrorAttributionAttributes} for a failed fetch/subscribe
124
119
  * synced-block operation from the raw `error` field and optional backend `statusCode`.
125
- * Returns `undefined` when the `platform_editor_blocks_patch_3` gate is OFF, so the new
126
- * `reason`/`statusCode`/`benign` attributes are only emitted once the gate is rolled out
127
- * (EDITOR-7862). The existing free-text `error` attribute is always left unchanged.
128
- *
129
- * `gateEnabled` is injected by the caller (the store managers evaluate `fg(...)`) so this
130
- * helper stays pure and trivially unit-testable for both gate states.
120
+ * Emits the `reason`/`statusCode`/`benign` attributes (EDITOR-7862). The existing
121
+ * free-text `error` attribute is always left unchanged.
131
122
  */
132
- export declare const buildFetchErrorAttribution: (gateEnabled: boolean, error?: string, statusCode?: number, deferred?: boolean) => FetchErrorAttributionAttributes | undefined;
123
+ export declare const buildFetchErrorAttribution: (error?: string, statusCode?: number, deferred?: boolean) => FetchErrorAttributionAttributes;
133
124
  /**
134
125
  * Shared operational ERROR payload builder for synced-block events.
135
126
  *
@@ -166,8 +157,7 @@ export declare const deleteErrorPayload: (error: string, resourceId?: string, so
166
157
  export declare const updateCacheErrorPayload: (error: string, resourceId?: string, sourceProduct?: string) => SyncBlockEventPayload;
167
158
  /**
168
159
  * Payload for `SYNCED_BLOCK_SOURCE_INFO_ORPHANED`. Fired when source-info
169
- * resolves into a cache that has already been deleted — should be unreachable
170
- * under `platform_synced_block_patch_14`.
160
+ * resolves into a cache that has already been deleted — should be unreachable.
171
161
  */
172
162
  export declare const sourceInfoOrphanedPayload: (resourceId?: string, sourceProduct?: string, context?: {
173
163
  hasPendingDeletion?: boolean;
@@ -184,7 +174,7 @@ export declare const fetchSuccessPayload: (resourceId: string, blockInstanceId?:
184
174
  export declare const createSuccessPayload: (resourceId: string, sourceProduct?: string) => SyncBlockEventPayload;
185
175
  /**
186
176
  * Optional enrichment for the `syncedBlockCreate` success event. All fields
187
- * optional so gate-off/legacy payloads are unchanged. `inputMethod`: creating
177
+ * optional so legacy payloads are unchanged. `inputMethod`: creating
188
178
  * surface (enum, PII-safe). `createdEmpty`: true from an empty selection, false
189
179
  * when content was converted.
190
180
  */
@@ -193,23 +183,20 @@ export type CreateSuccessEnrichment = {
193
183
  inputMethod?: INPUT_METHOD;
194
184
  };
195
185
  /**
196
- * Operational `syncedBlockCreate` success event, behind
197
- * `platform_editor_blocks_patch_4`, with the `blockInstanceId` join key and,
186
+ * Operational `syncedBlockCreate` success event with the `blockInstanceId` join key and,
198
187
  * when available, the `inputMethod` + `createdEmpty` creation-type signals.
199
188
  */
200
189
  export declare const createSuccessOperationalPayload: (resourceId: string, blockInstanceId?: string, sourceProduct?: string, enrichment?: CreateSuccessEnrichment) => SyncBlockEventPayload;
201
190
  /**
202
- * Operational first-content-added event, behind
203
- * `platform_editor_blocks_patch_4`. Fired once when a block created empty first
191
+ * Operational first-content-added event. Fired once when a block created empty first
204
192
  * gains user content. Join keys only (`resourceId` + `blockInstanceId`), no user
205
193
  * content (PII-safe).
206
194
  */
207
195
  export declare const addContentSuccessPayload: (resourceId: string, blockInstanceId?: string, sourceProduct?: string) => SyncBlockEventPayload;
208
196
  export declare const updateSuccessPayload: (resourceId: string, hasReference?: boolean, sourceProduct?: string) => SyncBlockEventPayload;
209
197
  /**
210
- * Optional enrichment for the `syncedBlockDelete` success event behind
211
- * `platform_editor_blocks_patch_4`. All fields optional so the gate-off payload
212
- * is unchanged; `blockInstanceId` is the bare-uuid join key.
198
+ * Optional enrichment for the `syncedBlockDelete` success event. All fields are
199
+ * optional for extensibility; `blockInstanceId` is the bare-uuid join key.
213
200
  */
214
201
  export type DeleteSuccessEnrichment = {
215
202
  blockInstanceId?: string;
package/package.json CHANGED
@@ -22,7 +22,7 @@
22
22
  "@atlaskit/editor-prosemirror": "^8.0.0",
23
23
  "@atlaskit/node-data-provider": "^15.0.0",
24
24
  "@atlaskit/platform-feature-flags": "^2.1.0",
25
- "@atlaskit/tmp-editor-statsig": "^145.0.0",
25
+ "@atlaskit/tmp-editor-statsig": "^146.0.0",
26
26
  "@babel/runtime": "^7.0.0",
27
27
  "@compiled/react": "^1.0.0",
28
28
  "bind-event-listener": "^3.0.0",
@@ -32,7 +32,7 @@
32
32
  "uuid": "^3.1.0"
33
33
  },
34
34
  "peerDependencies": {
35
- "@atlaskit/editor-common": "^118.2.0",
35
+ "@atlaskit/editor-common": "^118.4.0",
36
36
  "react": "^18.2.0 || ^19.2.0"
37
37
  },
38
38
  "devDependencies": {
@@ -76,7 +76,7 @@
76
76
  }
77
77
  },
78
78
  "name": "@atlaskit/editor-synced-block-provider",
79
- "version": "10.0.3",
79
+ "version": "10.0.5",
80
80
  "description": "Synced Block Provider for @atlaskit/editor-plugin-synced-block",
81
81
  "author": "Atlassian Pty Ltd",
82
82
  "license": "Apache-2.0",
@@ -84,18 +84,6 @@
84
84
  "registry": "https://registry.npmjs.org/"
85
85
  },
86
86
  "platform-feature-flags": {
87
- "platform_editor_blocks_patch_3": {
88
- "type": "boolean"
89
- },
90
- "platform_editor_blocks_patch_4": {
91
- "type": "boolean"
92
- },
93
- "platform_synced_block_patch_13": {
94
- "type": "boolean"
95
- },
96
- "platform_synced_block_patch_14": {
97
- "type": "boolean"
98
- },
99
87
  "platform_editor_blocks_patch_7": {
100
88
  "type": "boolean"
101
89
  }