@atlaskit/editor-synced-block-provider 8.5.7 → 8.6.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.
@@ -12,7 +12,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
12
12
  import { logException } from '@atlaskit/editor-common/monitoring';
13
13
  import { fg } from '@atlaskit/platform-feature-flags';
14
14
  import { SyncBlockError } from '../common/types';
15
- import { updateErrorPayload, createErrorPayload, deleteErrorPayload, updateCacheErrorPayload, getSourceInfoErrorPayload, updateSuccessPayload, createSuccessPayload, createSuccessOperationalPayload, deleteSuccessPayload, fetchReferencesErrorPayload, buildErrorAttribution } from '../utils/errorHandling';
15
+ import { updateErrorPayload, createErrorPayload, deleteErrorPayload, updateCacheErrorPayload, getSourceInfoErrorPayload, updateSuccessPayload, createSuccessPayload, createSuccessOperationalPayload, addContentSuccessPayload, deleteSuccessPayload, fetchReferencesErrorPayload, buildErrorAttribution } from '../utils/errorHandling';
16
16
  import { getCreateSourceExperience, getDeleteSourceExperience, getSaveSourceExperience, getFetchSourceInfoExperience } from '../utils/experienceTracking';
17
17
  import { convertSyncBlockPMNodeToSyncBlockData, getSourceProductFromResourceIdSafe } from '../utils/utils';
18
18
  /** Maximum time (ms) flush() will wait for in-flight block creations before proceeding. */
@@ -52,6 +52,20 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
52
52
  * multiple blocks are created concurrently. See EDITOR-7112.
53
53
  */
54
54
  _defineProperty(this, "creationsTimedOutDuringFlush", new Set());
55
+ /**
56
+ * Creation-type signals captured at `createBodiedSyncBlockNode` time and read
57
+ * back in `commitPendingCreation` to enrich the `syncedBlockCreate` event.
58
+ * Kept out of the flushed cache record so it never leaks into Block Service /
59
+ * ADF; removed once consumed.
60
+ */
61
+ _defineProperty(this, "creationEnrichment", new Map());
62
+ /**
63
+ * Resource IDs of blocks created empty this session that have not yet fired
64
+ * the first-content-added event. Added on empty creation, removed when the
65
+ * block first gains content (the event fires once). Blocks created with
66
+ * content or not created this session are never tracked.
67
+ */
68
+ _defineProperty(this, "awaitingFirstContent", new Set());
55
69
  /**
56
70
  * resourceId -> timestamp (ms) of the last `syncedBlockDelete` emission, used
57
71
  * to suppress duplicates within {@link DELETE_DEDUPE_WINDOW_MS}. Only consulted
@@ -404,17 +418,48 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
404
418
  var _this$fireAnalyticsEv4;
405
419
  var sourceProduct = getSourceProductFromResourceIdSafe(resourceId);
406
420
  (_this$fireAnalyticsEv4 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv4 === void 0 || _this$fireAnalyticsEv4.call(this, createSuccessPayload(resourceId || '', sourceProduct));
407
- // Operational create-success event with the join key.
421
+ // Operational create-success event with the join key + creation-type
422
+ // signals (inputMethod / createdEmpty) captured at the command layer.
408
423
  if (fg('platform_editor_blocks_patch_4')) {
409
424
  var _this$fireAnalyticsEv5, _this$syncBlockCache$;
410
- (_this$fireAnalyticsEv5 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv5 === void 0 || _this$fireAnalyticsEv5.call(this, createSuccessOperationalPayload(resourceId || '', (_this$syncBlockCache$ = this.syncBlockCache.get(resourceId)) === null || _this$syncBlockCache$ === void 0 ? void 0 : _this$syncBlockCache$.blockInstanceId, sourceProduct));
425
+ (_this$fireAnalyticsEv5 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv5 === void 0 || _this$fireAnalyticsEv5.call(this, createSuccessOperationalPayload(resourceId || '', (_this$syncBlockCache$ = this.syncBlockCache.get(resourceId)) === null || _this$syncBlockCache$ === void 0 ? void 0 : _this$syncBlockCache$.blockInstanceId, sourceProduct, this.creationEnrichment.get(resourceId)));
411
426
  }
412
427
  } else {
413
428
  var _this$fireAnalyticsEv6;
414
429
  // Delete the node from cache if fail to create so it's not flushed to BE
415
430
  this.syncBlockCache.delete(resourceId || '');
431
+ // Creation failed, so there is no block to add content to — drop the
432
+ // first-content tracking entry so a later unrelated edit cannot fire it.
433
+ this.awaitingFirstContent.delete(resourceId || '');
416
434
  (_this$fireAnalyticsEv6 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv6 === void 0 || _this$fireAnalyticsEv6.call(this, createErrorPayload('Fail to create bodied sync block', resourceId, getSourceProductFromResourceIdSafe(resourceId)));
417
435
  }
436
+ // Enrichment is single-use — drop it once the create has resolved either way.
437
+ this.creationEnrichment.delete(resourceId || '');
438
+ }
439
+
440
+ /**
441
+ * Fire the first-content-added event once when a block created empty this
442
+ * session first gains content. The caller detects the in-block edit; this owns
443
+ * dedupe + emission (fires at most once per block, only for empty→content).
444
+ * Gated behind `platform_editor_blocks_patch_4`.
445
+ */
446
+ }, {
447
+ key: "maybeEmitFirstContentAdded",
448
+ value: function maybeEmitFirstContentAdded(resourceId, blockInstanceId) {
449
+ var _this$fireAnalyticsEv7;
450
+ if (this.viewMode === 'view') {
451
+ return;
452
+ }
453
+ if (!fg('platform_editor_blocks_patch_4')) {
454
+ return;
455
+ }
456
+ // `delete` returns false when the id was not tracked (already emitted, or
457
+ // the block was not created empty this session), so this both dedupes and
458
+ // scopes emission to genuine first-content transitions in one check.
459
+ if (!this.awaitingFirstContent.delete(resourceId)) {
460
+ return;
461
+ }
462
+ (_this$fireAnalyticsEv7 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv7 === void 0 || _this$fireAnalyticsEv7.call(this, addContentSuccessPayload(resourceId, blockInstanceId, getSourceProductFromResourceIdSafe(resourceId)));
418
463
  }
419
464
  }, {
420
465
  key: "registerConfirmationCallback",
@@ -454,16 +499,28 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
454
499
  * @param attrs attributes Ids of the node
455
500
  * @param node the ProseMirror node to cache
456
501
  * @param onCompletion callback invoked when creation completes
502
+ * @param enrichment optional creation-type signals stashed and attached to the
503
+ * `syncedBlockCreate` event when the async create resolves. When
504
+ * `createdEmpty` is true the block is also registered for the
505
+ * first-content-added event.
457
506
  */
458
507
  }, {
459
508
  key: "createBodiedSyncBlockNode",
460
- value: function createBodiedSyncBlockNode(attrs, node, onCompletion) {
509
+ value: function createBodiedSyncBlockNode(attrs, node, onCompletion, enrichment) {
461
510
  var _this4 = this;
462
511
  if (this.viewMode === 'view') {
463
512
  return;
464
513
  }
465
514
  var resourceId = attrs.resourceId,
466
515
  blockInstanceId = attrs.localId;
516
+ // Stash creation-type signals for commitPendingCreation to read.
517
+ if (enrichment) {
518
+ this.creationEnrichment.set(resourceId, enrichment);
519
+ // Only empty-created blocks can produce an empty→content transition.
520
+ if (enrichment.createdEmpty) {
521
+ this.awaitingFirstContent.add(resourceId);
522
+ }
523
+ }
467
524
  try {
468
525
  var _this$createExperienc;
469
526
  if (!this.dataProvider) {
@@ -513,14 +570,14 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
513
570
  });
514
571
  this.pendingCreationPromises.set(resourceId, creationPromise);
515
572
  } catch (error) {
516
- var _this$fireAnalyticsEv7;
573
+ var _this$fireAnalyticsEv8;
517
574
  if (this.isPendingCreation(resourceId)) {
518
575
  this.commitPendingCreation(false, resourceId);
519
576
  }
520
577
  logException(error, {
521
578
  location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
522
579
  });
523
- (_this$fireAnalyticsEv7 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv7 === void 0 || _this$fireAnalyticsEv7.call(this, createErrorPayload(error.message, resourceId, getSourceProductFromResourceIdSafe(resourceId)));
580
+ (_this$fireAnalyticsEv8 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv8 === void 0 || _this$fireAnalyticsEv8.call(this, createErrorPayload(error.message, resourceId, getSourceProductFromResourceIdSafe(resourceId)));
524
581
  }
525
582
  }
526
583
  }, {
@@ -558,11 +615,11 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
558
615
  }, {
559
616
  key: "emitDeleteSuccess",
560
617
  value: function emitDeleteSuccess(resourceId, reason, mechanism) {
561
- var _this$syncBlockCache$2, _this$fireAnalyticsEv9;
618
+ var _this$syncBlockCache$2, _this$fireAnalyticsEv0;
562
619
  var sourceProduct = getSourceProductFromResourceIdSafe(resourceId);
563
620
  if (!fg('platform_editor_blocks_patch_4')) {
564
- var _this$fireAnalyticsEv8;
565
- (_this$fireAnalyticsEv8 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv8 === void 0 || _this$fireAnalyticsEv8.call(this, deleteSuccessPayload(resourceId, sourceProduct));
621
+ var _this$fireAnalyticsEv9;
622
+ (_this$fireAnalyticsEv9 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv9 === void 0 || _this$fireAnalyticsEv9.call(this, deleteSuccessPayload(resourceId, sourceProduct));
566
623
  return;
567
624
  }
568
625
  var now = Date.now();
@@ -577,7 +634,7 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
577
634
  deletionReason: reason,
578
635
  mechanism: mechanism
579
636
  };
580
- (_this$fireAnalyticsEv9 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv9 === void 0 || _this$fireAnalyticsEv9.call(this, deleteSuccessPayload(resourceId, sourceProduct, enrichment));
637
+ (_this$fireAnalyticsEv0 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv0 === void 0 || _this$fireAnalyticsEv0.call(this, deleteSuccessPayload(resourceId, sourceProduct, enrichment));
581
638
  }
582
639
  }, {
583
640
  key: "delete",
@@ -926,11 +983,11 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
926
983
  return sourceInfo;
927
984
  });
928
985
  } catch (error) {
929
- var _this$fireAnalyticsEv0;
986
+ var _this$fireAnalyticsEv1;
930
987
  logException(error, {
931
988
  location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
932
989
  });
933
- (_this$fireAnalyticsEv0 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv0 === void 0 || _this$fireAnalyticsEv0.call(this, getSourceInfoErrorPayload(error.message));
990
+ (_this$fireAnalyticsEv1 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv1 === void 0 || _this$fireAnalyticsEv1.call(this, getSourceInfoErrorPayload(error.message));
934
991
  return Promise.resolve(undefined);
935
992
  }
936
993
  }
@@ -943,11 +1000,11 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
943
1000
  }
944
1001
  return this.dataProvider.fetchReferences(resourceId, true);
945
1002
  } catch (error) {
946
- var _this$fireAnalyticsEv1;
1003
+ var _this$fireAnalyticsEv10;
947
1004
  logException(error, {
948
1005
  location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
949
1006
  });
950
- (_this$fireAnalyticsEv1 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv1 === void 0 || _this$fireAnalyticsEv1.call(this, fetchReferencesErrorPayload(error.message, resourceId, getSourceProductFromResourceIdSafe(resourceId)));
1007
+ (_this$fireAnalyticsEv10 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv10 === void 0 || _this$fireAnalyticsEv10.call(this, fetchReferencesErrorPayload(error.message, resourceId, getSourceProductFromResourceIdSafe(resourceId)));
951
1008
  return Promise.resolve({
952
1009
  error: SyncBlockError.Errored
953
1010
  });
@@ -964,6 +1021,8 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
964
1021
  this.postCreationFlushCallback = undefined;
965
1022
  this.pendingCreationPromises.clear();
966
1023
  this.creationsTimedOutDuringFlush.clear();
1024
+ this.creationEnrichment.clear();
1025
+ this.awaitingFirstContent.clear();
967
1026
  this.recentDeleteEmissions.clear();
968
1027
  this.dataProvider = undefined;
969
1028
  (_this$saveExperience4 = this.saveExperience) === null || _this$saveExperience4 === void 0 || _this$saveExperience4.abort({