@atlaskit/editor-synced-block-provider 23.0.5 → 23.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cjs/clients/jira/ari.js +2 -2
  3. package/dist/cjs/common/types.js +1 -0
  4. package/dist/cjs/providers/block-service/blockServiceAPI.js +32 -10
  5. package/dist/cjs/providers/syncBlockProvider.js +11 -5
  6. package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +41 -23
  7. package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +15 -7
  8. package/dist/cjs/utils/errorHandling.js +16 -10
  9. package/dist/cjs/utils/fieldAwareLocations.js +26 -1
  10. package/dist/es2019/clients/jira/ari.js +1 -1
  11. package/dist/es2019/common/types.js +2 -0
  12. package/dist/es2019/providers/block-service/blockServiceAPI.js +27 -7
  13. package/dist/es2019/providers/syncBlockProvider.js +9 -3
  14. package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +41 -24
  15. package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +15 -9
  16. package/dist/es2019/utils/errorHandling.js +14 -5
  17. package/dist/es2019/utils/fieldAwareLocations.js +27 -2
  18. package/dist/esm/clients/jira/ari.js +1 -1
  19. package/dist/esm/common/types.js +2 -0
  20. package/dist/esm/providers/block-service/blockServiceAPI.js +32 -10
  21. package/dist/esm/providers/syncBlockProvider.js +11 -5
  22. package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +41 -23
  23. package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +15 -7
  24. package/dist/esm/utils/errorHandling.js +16 -10
  25. package/dist/esm/utils/fieldAwareLocations.js +26 -1
  26. package/dist/types/clients/jira/ari.d.ts +1 -0
  27. package/dist/types/common/types.d.ts +2 -0
  28. package/dist/types/providers/block-service/blockServiceAPI.d.ts +9 -2
  29. package/dist/types/providers/syncBlockProvider.d.ts +1 -1
  30. package/dist/types/providers/types.d.ts +6 -1
  31. package/dist/types/store-manager/sourceSyncBlockStoreManager.d.ts +1 -0
  32. package/dist/types/utils/errorHandling.d.ts +9 -7
  33. package/dist/types/utils/fieldAwareLocations.d.ts +9 -1
  34. package/package.json +7 -2
@@ -17,6 +17,7 @@ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-e
17
17
  import { SyncBlockError } from '../common/types';
18
18
  import { updateErrorPayload, createErrorPayload, deleteErrorPayload, updateCacheErrorPayload, getSourceInfoErrorPayload, updateSuccessPayload, createSuccessPayload, createSuccessOperationalPayload, addContentSuccessPayload, deleteSuccessPayload, fetchReferencesErrorPayload, buildErrorAttribution } from '../utils/errorHandling';
19
19
  import { getCreateSourceExperience, getDeleteSourceExperience, getSaveSourceExperience, getFetchSourceInfoExperience } from '../utils/experienceTracking';
20
+ import { getSourceLocation as _getSourceLocation } from '../utils/fieldAwareLocations';
20
21
  import { convertSyncBlockPMNodeToSyncBlockData, getSourceProductFromResourceIdSafe } from '../utils/utils';
21
22
  /** Maximum time (ms) flush() will wait for in-flight block creations before proceeding. */
22
23
  var FLUSH_CREATION_AWAIT_TIMEOUT_MS = 1000;
@@ -487,16 +488,17 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
487
488
  }
488
489
  } else {
489
490
  var _this$fireAnalyticsEv3;
490
- (_this$fireAnalyticsEv3 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv3 === void 0 || _this$fireAnalyticsEv3.call(this, createErrorPayload('creation complete callback missing', resourceId, getSourceProductFromResourceIdSafe(resourceId)));
491
+ (_this$fireAnalyticsEv3 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv3 === void 0 || _this$fireAnalyticsEv3.call(this, createErrorPayload('creation complete callback missing', resourceId, getSourceProductFromResourceIdSafe(resourceId), undefined, this.getSourceLocation()));
491
492
  }
492
493
  if (success) {
493
494
  var _this$dataProvider$ge, _this$dataProvider, _this$fireAnalyticsEv4, _this$fireAnalyticsEv5, _this$syncBlockCache$2;
494
495
  var sourceProduct = getSourceProductFromResourceIdSafe(resourceId);
496
+ var sourceLocation = this.getSourceLocation();
495
497
  var documentInsertedResourceId = (_this$dataProvider$ge = (_this$dataProvider = this.dataProvider) === null || _this$dataProvider === void 0 ? void 0 : _this$dataProvider.generateResourceIdForReference(resourceId)) !== null && _this$dataProvider$ge !== void 0 ? _this$dataProvider$ge : resourceId;
496
- (_this$fireAnalyticsEv4 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv4 === void 0 || _this$fireAnalyticsEv4.call(this, createSuccessPayload(documentInsertedResourceId || '', sourceProduct));
498
+ (_this$fireAnalyticsEv4 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv4 === void 0 || _this$fireAnalyticsEv4.call(this, createSuccessPayload(documentInsertedResourceId || '', sourceProduct, sourceLocation));
497
499
  // Operational create-success event with the join key + creation-type
498
500
  // signals (inputMethod / createdEmpty / nodeTypes) captured at the command layer.
499
- (_this$fireAnalyticsEv5 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv5 === void 0 || _this$fireAnalyticsEv5.call(this, createSuccessOperationalPayload(resourceId || '', (_this$syncBlockCache$2 = this.syncBlockCache.get(resourceId)) === null || _this$syncBlockCache$2 === void 0 ? void 0 : _this$syncBlockCache$2.blockInstanceId, sourceProduct, this.creationEnrichment.get(resourceId)));
501
+ (_this$fireAnalyticsEv5 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv5 === void 0 || _this$fireAnalyticsEv5.call(this, createSuccessOperationalPayload(resourceId || '', (_this$syncBlockCache$2 = this.syncBlockCache.get(resourceId)) === null || _this$syncBlockCache$2 === void 0 ? void 0 : _this$syncBlockCache$2.blockInstanceId, sourceProduct, this.creationEnrichment.get(resourceId), sourceLocation));
500
502
  } else {
501
503
  var _this$fireAnalyticsEv6;
502
504
  // Delete the node from cache if fail to create so it's not flushed to BE
@@ -506,7 +508,7 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
506
508
  // Creation failed, so there is no block to add content to — drop the
507
509
  // first-content tracking entry so a later unrelated edit cannot fire it.
508
510
  this.awaitingFirstContent.delete(resourceId || '');
509
- (_this$fireAnalyticsEv6 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv6 === void 0 || _this$fireAnalyticsEv6.call(this, createErrorPayload('Fail to create bodied sync block', resourceId, getSourceProductFromResourceIdSafe(resourceId)));
511
+ (_this$fireAnalyticsEv6 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv6 === void 0 || _this$fireAnalyticsEv6.call(this, createErrorPayload('Fail to create bodied sync block', resourceId, getSourceProductFromResourceIdSafe(resourceId), undefined, this.getSourceLocation()));
510
512
  }
511
513
  // Enrichment is single-use — drop it once the create has resolved either way.
512
514
  this.creationEnrichment.delete(resourceId || '');
@@ -628,7 +630,7 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
628
630
  (_this5$createExperien2 = _this5.createExperience) === null || _this5$createExperien2 === void 0 || _this5$createExperien2.failure({
629
631
  reason: result.error || 'Failed to create bodied sync block'
630
632
  });
631
- (_this5$fireAnalyticsE = _this5.fireAnalyticsEvent) === null || _this5$fireAnalyticsE === void 0 || _this5$fireAnalyticsE.call(_this5, createErrorPayload(result.error || 'Failed to create bodied sync block', resourceId, getSourceProductFromResourceIdSafe(resourceId), buildErrorAttribution(result.error, result.statusCode)));
633
+ (_this5$fireAnalyticsE = _this5.fireAnalyticsEvent) === null || _this5$fireAnalyticsE === void 0 || _this5$fireAnalyticsE.call(_this5, createErrorPayload(result.error || 'Failed to create bodied sync block', resourceId, getSourceProductFromResourceIdSafe(resourceId), buildErrorAttribution(result.error, result.statusCode), _this5.getSourceLocation()));
632
634
  }
633
635
  }).catch(function (error) {
634
636
  var _this5$createExperien3, _this5$fireAnalyticsE2;
@@ -639,7 +641,7 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
639
641
  (_this5$createExperien3 = _this5.createExperience) === null || _this5$createExperien3 === void 0 || _this5$createExperien3.failure({
640
642
  reason: error.message
641
643
  });
642
- (_this5$fireAnalyticsE2 = _this5.fireAnalyticsEvent) === null || _this5$fireAnalyticsE2 === void 0 || _this5$fireAnalyticsE2.call(_this5, createErrorPayload(error.message, resourceId, getSourceProductFromResourceIdSafe(resourceId)));
644
+ (_this5$fireAnalyticsE2 = _this5.fireAnalyticsEvent) === null || _this5$fireAnalyticsE2 === void 0 || _this5$fireAnalyticsE2.call(_this5, createErrorPayload(error.message, resourceId, getSourceProductFromResourceIdSafe(resourceId), undefined, _this5.getSourceLocation()));
643
645
  }).finally(function () {
644
646
  _this5.pendingCreationPromises.delete(resourceId);
645
647
  });
@@ -653,9 +655,15 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
653
655
  logException(error, {
654
656
  location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
655
657
  });
656
- (_this$fireAnalyticsEv8 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv8 === void 0 || _this$fireAnalyticsEv8.call(this, createErrorPayload(error.message, resourceId, getSourceProductFromResourceIdSafe(resourceId)));
658
+ (_this$fireAnalyticsEv8 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv8 === void 0 || _this$fireAnalyticsEv8.call(this, createErrorPayload(error.message, resourceId, getSourceProductFromResourceIdSafe(resourceId), undefined, this.getSourceLocation()));
657
659
  }
658
660
  }
661
+ }, {
662
+ key: "getSourceLocation",
663
+ value: function getSourceLocation() {
664
+ var _this$dataProvider2, _this$dataProvider2$g;
665
+ return _getSourceLocation((_this$dataProvider2 = this.dataProvider) === null || _this$dataProvider2 === void 0 || (_this$dataProvider2$g = _this$dataProvider2.getParentAri) === null || _this$dataProvider2$g === void 0 ? void 0 : _this$dataProvider2$g.call(_this$dataProvider2));
666
+ }
659
667
  }, {
660
668
  key: "pruneRecentDeleteEmissions",
661
669
  value:
@@ -212,18 +212,20 @@ export var buildFetchErrorAttribution = function buildFetchErrorAttribution(erro
212
212
  * buckets like `source_deleted` they never emit.
213
213
  */
214
214
 
215
- export function getErrorPayload(actionSubjectId, error, resourceId, sourceProduct, attribution) {
215
+ export function getErrorPayload(actionSubjectId, error, resourceId, sourceProduct, attribution, sourceLocation) {
216
216
  return {
217
217
  action: ACTION.ERROR,
218
218
  actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
219
219
  actionSubjectId: actionSubjectId,
220
220
  eventType: EVENT_TYPE.OPERATIONAL,
221
- attributes: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
221
+ attributes: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
222
222
  error: error
223
223
  }, resourceId && {
224
224
  resourceId: resourceId
225
225
  }), sourceProduct && {
226
226
  sourceProduct: sourceProduct
227
+ }), sourceLocation && {
228
+ sourceLocation: sourceLocation
227
229
  }), (attribution === null || attribution === void 0 ? void 0 : attribution.reason) && {
228
230
  reason: attribution.reason
229
231
  }), (attribution === null || attribution === void 0 ? void 0 : attribution.statusCode) !== undefined && {
@@ -243,8 +245,8 @@ export var fetchErrorPayload = function fetchErrorPayload(error, resourceId, sou
243
245
  attribution ? getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_FETCH, error, resourceId, sourceProduct, attribution) : getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_FETCH, error, resourceId, sourceProduct)
244
246
  );
245
247
  };
246
- export var getSourceInfoErrorPayload = function getSourceInfoErrorPayload(error, resourceId, sourceProduct) {
247
- return getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_GET_SOURCE_INFO, error, resourceId, sourceProduct);
248
+ export var getSourceInfoErrorPayload = function getSourceInfoErrorPayload(error, resourceId, sourceProduct, sourceLocation) {
249
+ return getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_GET_SOURCE_INFO, error, resourceId, sourceProduct, undefined, sourceLocation);
248
250
  };
249
251
  export var updateErrorPayload = function updateErrorPayload(error, resourceId, sourceProduct, attribution) {
250
252
  return getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_UPDATE, error, resourceId, sourceProduct, attribution);
@@ -252,8 +254,8 @@ export var updateErrorPayload = function updateErrorPayload(error, resourceId, s
252
254
  export var updateReferenceErrorPayload = function updateReferenceErrorPayload(error, resourceId, sourceProduct, attribution) {
253
255
  return getErrorPayload(ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_UPDATE, error, resourceId, sourceProduct, attribution);
254
256
  };
255
- export var createErrorPayload = function createErrorPayload(error, resourceId, sourceProduct, attribution) {
256
- return getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_CREATE, error, resourceId, sourceProduct, attribution);
257
+ export var createErrorPayload = function createErrorPayload(error, resourceId, sourceProduct, attribution, sourceLocation) {
258
+ return getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_CREATE, error, resourceId, sourceProduct, attribution, sourceLocation);
257
259
  };
258
260
  export var deleteErrorPayload = function deleteErrorPayload(error, resourceId, sourceProduct, attribution) {
259
261
  return getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_DELETE, error, resourceId, sourceProduct, attribution);
@@ -322,16 +324,18 @@ export var fetchSuccessPayload = function fetchSuccessPayload(resourceId, blockI
322
324
  })
323
325
  };
324
326
  };
325
- export var createSuccessPayload = function createSuccessPayload(resourceId, sourceProduct) {
327
+ export var createSuccessPayload = function createSuccessPayload(resourceId, sourceProduct, sourceLocation) {
326
328
  return {
327
329
  action: ACTION.INSERTED,
328
330
  actionSubject: ACTION_SUBJECT.DOCUMENT,
329
331
  actionSubjectId: ACTION_SUBJECT_ID.BODIED_SYNCED_BLOCK,
330
332
  eventType: EVENT_TYPE.TRACK,
331
- attributes: _objectSpread({
333
+ attributes: _objectSpread(_objectSpread({
332
334
  resourceId: resourceId
333
335
  }, sourceProduct && {
334
336
  sourceProduct: sourceProduct
337
+ }), sourceLocation && {
338
+ sourceLocation: sourceLocation
335
339
  })
336
340
  };
337
341
  };
@@ -348,14 +352,14 @@ export var createSuccessPayload = function createSuccessPayload(resourceId, sour
348
352
  * Operational `syncedBlockCreate` success event with the `blockInstanceId` join key and,
349
353
  * when available, the `inputMethod`, `createdEmpty`, and `nodeTypes` creation signals.
350
354
  */
351
- export var createSuccessOperationalPayload = function createSuccessOperationalPayload(resourceId, blockInstanceId, sourceProduct, enrichment) {
355
+ export var createSuccessOperationalPayload = function createSuccessOperationalPayload(resourceId, blockInstanceId, sourceProduct, enrichment, sourceLocation) {
352
356
  var _enrichment$nodeTypes;
353
357
  return {
354
358
  action: ACTION.INSERTED,
355
359
  actionSubject: ACTION_SUBJECT.SYNCED_BLOCK,
356
360
  actionSubjectId: ACTION_SUBJECT_ID.SYNCED_BLOCK_CREATE,
357
361
  eventType: EVENT_TYPE.OPERATIONAL,
358
- attributes: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
362
+ attributes: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
359
363
  resourceId: resourceId
360
364
  }, blockInstanceId && {
361
365
  blockInstanceId: blockInstanceId
@@ -367,6 +371,8 @@ export var createSuccessOperationalPayload = function createSuccessOperationalPa
367
371
  createdEmpty: enrichment.createdEmpty
368
372
  }), (enrichment === null || enrichment === void 0 || (_enrichment$nodeTypes = enrichment.nodeTypes) === null || _enrichment$nodeTypes === void 0 ? void 0 : _enrichment$nodeTypes.length) && {
369
373
  nodeTypes: enrichment.nodeTypes
374
+ }), sourceLocation && {
375
+ sourceLocation: sourceLocation
370
376
  })
371
377
  };
372
378
  };
@@ -1,5 +1,7 @@
1
1
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
2
- import { getLocationScope } from '../clients/block-service/ari';
2
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
3
+ import { getLocationScope, getProductFromSourceAri } from '../clients/block-service/ari';
4
+ import { JIRA_DESCRIPTION_FIELD_ID, parseJiraFieldLocation } from '../clients/jira/ari';
3
5
  /**
4
6
  * The product check runs first so a Confluence-only document never reads the experiment.
5
7
  */
@@ -21,4 +23,27 @@ export var getFieldAwareLocationScope = function getFieldAwareLocationScope(_ref
21
23
  hostAri: hostAri
22
24
  })
23
25
  } : undefined;
26
+ };
27
+
28
+ /**
29
+ * Analytics `sourceLocation` for a source ARI: `undefined` for non-Jira sources and for the
30
+ * control cohort, so events outside the experiment keep their current shape.
31
+ *
32
+ * The `platform_editor_blocks_patch_13` gate runs first: with it off this returns `undefined`
33
+ * without the product check or the experiment read, so no new exposure is logged.
34
+ */
35
+ export var getSourceLocation = function getSourceLocation(sourceAri) {
36
+ if (!fg('platform_editor_blocks_patch_13')) {
37
+ return undefined;
38
+ }
39
+ if (!sourceAri || !isFieldAwareJiraLocation(getProductFromSourceAri(sourceAri))) {
40
+ return undefined;
41
+ }
42
+ var location = parseJiraFieldLocation({
43
+ ari: sourceAri
44
+ });
45
+ if (!location) {
46
+ return undefined;
47
+ }
48
+ return location.fieldId === JIRA_DESCRIPTION_FIELD_ID ? 'description' : 'custom-field';
24
49
  };
@@ -26,6 +26,7 @@ export declare const getJiraWorkItemIdFromAri: ({ ari }: {
26
26
  export declare const getJiraIssueAriFromSourceAri: ({ ari }: {
27
27
  ari: string;
28
28
  }) => string;
29
+ export declare const JIRA_DESCRIPTION_FIELD_ID = "description";
29
30
  /**
30
31
  * One synced block location on a Jira work item, parsed once from its document ARI.
31
32
  * Two locations name the same field when both members match, whichever of the two ARI
@@ -12,6 +12,8 @@ export type SyncBlockStatus = 'active' | 'deleted' | 'unpublished';
12
12
  * `same-parent-document` is another field of the host work item.
13
13
  */
14
14
  export type SyncBlockLocationScope = 'same-document' | 'same-parent-document' | 'elsewhere';
15
+ /** Which Jira work item field holds a source block. */
16
+ export type SyncBlockSourceLocation = 'description' | 'custom-field';
15
17
  export type SyncBlockAttrs = {
16
18
  localId: BlockInstanceId;
17
19
  resourceId: ResourceId;
@@ -49,6 +49,8 @@ export declare const writeDataBatch: (cloudId: string, parentAri: string | undef
49
49
  interface BlockServiceADFFetchProviderProps {
50
50
  cloudId: string;
51
51
  parentAri: string | undefined;
52
+ parentId?: string;
53
+ product?: SyncBlockProduct;
52
54
  }
53
55
  /**
54
56
  * ADFFetchProvider implementation that fetches synced block data from Block Service API
@@ -56,7 +58,10 @@ interface BlockServiceADFFetchProviderProps {
56
58
  declare class BlockServiceADFFetchProvider implements ADFFetchProvider {
57
59
  private cloudId;
58
60
  private parentAri;
59
- constructor({ cloudId, parentAri }: BlockServiceADFFetchProviderProps);
61
+ private parentId?;
62
+ private product?;
63
+ constructor({ cloudId, parentAri, parentId, product }: BlockServiceADFFetchProviderProps);
64
+ generateResourceIdForReference(sourceId: ResourceId): ResourceId;
60
65
  fetchData(resourceId: string): Promise<SyncBlockInstance>;
61
66
  fetchReferences(referenceResourceId: string): Promise<ReferenceSyncBlockData>;
62
67
  /**
@@ -116,11 +121,13 @@ export declare const useMemoizedBlockServiceAPIProviders: ({ cloudId, parentAri,
116
121
  interface BlockServiceFetchOnlyAPIProviderProps {
117
122
  cloudId: string;
118
123
  parentAri: string | undefined;
124
+ parentId?: string;
125
+ product?: SyncBlockProduct;
119
126
  }
120
127
  /**
121
128
  * If the parentAri is not a valid ARI, pass in an empty string.
122
129
  */
123
- export declare const useMemoizedBlockServiceFetchOnlyAPIProvider: ({ cloudId, parentAri, }: BlockServiceFetchOnlyAPIProviderProps) => {
130
+ export declare const useMemoizedBlockServiceFetchOnlyAPIProvider: ({ cloudId, parentAri, parentId, product, }: BlockServiceFetchOnlyAPIProviderProps) => {
124
131
  fetchProvider: BlockServiceADFFetchProvider;
125
132
  writeProvider: undefined;
126
133
  };
@@ -69,11 +69,11 @@ export declare class SyncedBlockProvider extends SyncBlockDataProviderInterface
69
69
  * @returns The source info
70
70
  */
71
71
  fetchSyncBlockSourceInfo(localId?: BlockInstanceId, sourceAri?: string, sourceProduct?: SyncBlockProduct, hasAccess?: boolean): Promise<SyncBlockSourceInfo | undefined>;
72
+ getParentAri(): string | undefined;
72
73
  generateResourceId(): {
73
74
  localId: BlockInstanceId;
74
75
  resourceId: ResourceId;
75
76
  };
76
- canGenerateResourceIdForReference(): boolean;
77
77
  generateResourceIdForReference(sourceId: ResourceId): ResourceId;
78
78
  /**
79
79
  * Get the synced block renderer provider options
@@ -151,6 +151,8 @@ export interface ADFFetchProvider {
151
151
  batchFetchData: (blockNodeIdentifiers: BlockNodeIdentifiers[], config?: BatchFetchConfig) => Promise<SyncBlockInstance[]>;
152
152
  fetchData: (resourceId: ResourceId) => Promise<SyncBlockInstance>;
153
153
  fetchReferences: (referenceResourceId: string) => Promise<ReferenceSyncBlockData>;
154
+ /** Returns an unscoped sourceId when the host document identity is unavailable. */
155
+ generateResourceIdForReference?: (sourceId: ResourceId) => ResourceId;
154
156
  /**
155
157
  * Subscribes to real-time updates for a specific block.
156
158
  */
@@ -205,6 +207,10 @@ export declare abstract class SyncBlockDataProviderInterface extends NodeDataPro
205
207
  abstract fetchSyncBlockSourceInfo(localId?: BlockInstanceId, sourceAri?: string, sourceProduct?: SyncBlockProduct, hasAccess?: boolean): Promise<SyncBlockSourceInfo | undefined>;
206
208
  abstract setProviderOptions(providerOptions: SyncedBlockRendererProviderOptions): void;
207
209
  abstract getSyncedBlockRendererProviderOptions(): SyncedBlockRendererProviderOptions;
210
+ /**
211
+ * ARI of the document that new source blocks are created in, when a write provider is set.
212
+ */
213
+ getParentAri?(): string | undefined;
208
214
  abstract retrieveSyncBlockParentInfo(sourceAri: string, sourceProduct: SyncBlockProduct): SyncBlockParentInfo | undefined;
209
215
  /**
210
216
  * Generates a resource ID for source synced block.
@@ -220,7 +226,6 @@ export declare abstract class SyncBlockDataProviderInterface extends NodeDataPro
220
226
  * @returns The generated resource ID
221
227
  */
222
228
  abstract generateResourceIdForReference(sourceId: ResourceId): ResourceId;
223
- canGenerateResourceIdForReference?(): boolean;
224
229
  abstract updateReferenceData(blocks: SyncBlockAttrs[], noContent?: boolean): Promise<UpdateReferenceSyncBlockResult>;
225
230
  abstract fetchReferences(resourceId: string, isSource: boolean): Promise<ReferenceSyncBlockData>;
226
231
  /**
@@ -144,6 +144,7 @@ export declare class SourceSyncBlockStoreManager {
144
144
  * first-content-added event.
145
145
  */
146
146
  createBodiedSyncBlockNode(attrs: SyncBlockAttrs, node: PMNode, onCompletion: OnCompletion, enrichment?: CreateSuccessEnrichment): void;
147
+ private getSourceLocation;
147
148
  private setPendingDeletion;
148
149
  /**
149
150
  * Drop dedupe entries older than {@link DELETE_DEDUPE_WINDOW_MS} so
@@ -3,7 +3,7 @@ import type { INPUT_METHOD } from '@atlaskit/editor-common/analytics/types/enums
3
3
  import type { RendererSyncBlockEventPayload, SyncBlockEventPayload } from '@atlaskit/editor-common/analytics/types/sync-block-events';
4
4
  import type { OperationalAEP } from '@atlaskit/editor-common/analytics/types/utils';
5
5
  import { SyncBlockError } from '../common/types';
6
- import type { DeletionMechanism, DeletionReason } from '../common/types';
6
+ import type { DeletionMechanism, DeletionReason, SyncBlockSourceLocation } from '../common/types';
7
7
  export declare const stringifyError: (error: unknown) => string | undefined;
8
8
  /**
9
9
  * PII-safe extraction of `message`/`name` from an unknown caught error, used to
@@ -134,27 +134,29 @@ export declare const buildFetchErrorAttribution: (error?: string, statusCode?: n
134
134
  * {@link SyncBlockErrorReason}, so write-path payloads never claim to carry fetch-only
135
135
  * buckets like `source_deleted` they never emit.
136
136
  */
137
- export declare function getErrorPayload<T extends ACTION_SUBJECT_ID>(actionSubjectId: T, error: string, resourceId: string | undefined, sourceProduct: string | undefined, attribution: FetchErrorAttributionAttributes): OperationalAEP<ACTION.ERROR, ACTION_SUBJECT.SYNCED_BLOCK, T, {
137
+ export declare function getErrorPayload<T extends ACTION_SUBJECT_ID>(actionSubjectId: T, error: string, resourceId: string | undefined, sourceProduct: string | undefined, attribution: FetchErrorAttributionAttributes, sourceLocation?: SyncBlockSourceLocation): OperationalAEP<ACTION.ERROR, ACTION_SUBJECT.SYNCED_BLOCK, T, {
138
138
  error: string;
139
139
  resourceId?: string;
140
140
  sourceProduct?: string;
141
+ sourceLocation?: SyncBlockSourceLocation;
141
142
  reason?: SyncBlockFetchErrorReason;
142
143
  statusCode?: number;
143
144
  benign?: boolean;
144
145
  deferred?: boolean;
145
146
  }>;
146
- export declare function getErrorPayload<T extends ACTION_SUBJECT_ID>(actionSubjectId: T, error: string, resourceId?: string, sourceProduct?: string, attribution?: ErrorAttributionAttributes): OperationalAEP<ACTION.ERROR, ACTION_SUBJECT.SYNCED_BLOCK, T, {
147
+ export declare function getErrorPayload<T extends ACTION_SUBJECT_ID>(actionSubjectId: T, error: string, resourceId?: string, sourceProduct?: string, attribution?: ErrorAttributionAttributes, sourceLocation?: SyncBlockSourceLocation): OperationalAEP<ACTION.ERROR, ACTION_SUBJECT.SYNCED_BLOCK, T, {
147
148
  error: string;
148
149
  resourceId?: string;
149
150
  sourceProduct?: string;
151
+ sourceLocation?: SyncBlockSourceLocation;
150
152
  reason?: SyncBlockErrorReason;
151
153
  statusCode?: number;
152
154
  }>;
153
155
  export declare const fetchErrorPayload: (error: string, resourceId?: string, sourceProduct?: string, attribution?: FetchErrorAttributionAttributes) => RendererSyncBlockEventPayload;
154
- export declare const getSourceInfoErrorPayload: (error: string, resourceId?: string, sourceProduct?: string) => RendererSyncBlockEventPayload;
156
+ export declare const getSourceInfoErrorPayload: (error: string, resourceId?: string, sourceProduct?: string, sourceLocation?: SyncBlockSourceLocation) => RendererSyncBlockEventPayload;
155
157
  export declare const updateErrorPayload: (error: string, resourceId?: string, sourceProduct?: string, attribution?: ErrorAttributionAttributes) => SyncBlockEventPayload;
156
158
  export declare const updateReferenceErrorPayload: (error: string, resourceId?: string, sourceProduct?: string, attribution?: ErrorAttributionAttributes) => RendererSyncBlockEventPayload;
157
- export declare const createErrorPayload: (error: string, resourceId?: string, sourceProduct?: string, attribution?: ErrorAttributionAttributes) => SyncBlockEventPayload;
159
+ export declare const createErrorPayload: (error: string, resourceId?: string, sourceProduct?: string, attribution?: ErrorAttributionAttributes, sourceLocation?: SyncBlockSourceLocation) => SyncBlockEventPayload;
158
160
  export declare const deleteErrorPayload: (error: string, resourceId?: string, sourceProduct?: string, attribution?: ErrorAttributionAttributes) => SyncBlockEventPayload;
159
161
  export declare const updateCacheErrorPayload: (error: string, resourceId?: string, sourceProduct?: string) => SyncBlockEventPayload;
160
162
  /**
@@ -173,7 +175,7 @@ export declare const sourceInfoOrphanedPayload: (resourceId?: string, sourceProd
173
175
  export declare const cacheDeletionForcedPayload: (rescheduleCount: number, resourceId?: string, sourceProduct?: string) => RendererSyncBlockEventPayload;
174
176
  export declare const fetchReferencesErrorPayload: (error: string, resourceId?: string, sourceProduct?: string) => SyncBlockEventPayload;
175
177
  export declare const fetchSuccessPayload: (resourceId: string, blockInstanceId?: string, sourceProduct?: string) => RendererSyncBlockEventPayload;
176
- export declare const createSuccessPayload: (resourceId: string, sourceProduct?: string) => SyncBlockEventPayload;
178
+ export declare const createSuccessPayload: (resourceId: string, sourceProduct?: string, sourceLocation?: SyncBlockSourceLocation) => SyncBlockEventPayload;
177
179
  /**
178
180
  * Optional enrichment for the `syncedBlockCreate` success event. All fields
179
181
  * optional so legacy payloads are unchanged. `inputMethod`: creating
@@ -190,7 +192,7 @@ export type CreateSuccessEnrichment = {
190
192
  * Operational `syncedBlockCreate` success event with the `blockInstanceId` join key and,
191
193
  * when available, the `inputMethod`, `createdEmpty`, and `nodeTypes` creation signals.
192
194
  */
193
- export declare const createSuccessOperationalPayload: (resourceId: string, blockInstanceId?: string, sourceProduct?: string, enrichment?: CreateSuccessEnrichment) => SyncBlockEventPayload;
195
+ export declare const createSuccessOperationalPayload: (resourceId: string, blockInstanceId?: string, sourceProduct?: string, enrichment?: CreateSuccessEnrichment, sourceLocation?: SyncBlockSourceLocation) => SyncBlockEventPayload;
194
196
  /**
195
197
  * Operational first-content-added event. Fired once when a block created empty first
196
198
  * gains user content. Join keys only (`resourceId` + `blockInstanceId`), no user
@@ -1,4 +1,4 @@
1
- import type { SyncBlockLocationScope, SyncBlockProduct } from '../common/types';
1
+ import type { SyncBlockLocationScope, SyncBlockProduct, SyncBlockSourceLocation } from '../common/types';
2
2
  /**
3
3
  * The product check runs first so a Confluence-only document never reads the experiment.
4
4
  */
@@ -14,3 +14,11 @@ export declare const getFieldAwareLocationScope: ({ documentAri, hostAri, produc
14
14
  }) => {
15
15
  locationScope: SyncBlockLocationScope;
16
16
  } | undefined;
17
+ /**
18
+ * Analytics `sourceLocation` for a source ARI: `undefined` for non-Jira sources and for the
19
+ * control cohort, so events outside the experiment keep their current shape.
20
+ *
21
+ * The `platform_editor_blocks_patch_13` gate runs first: with it off this returns `undefined`
22
+ * without the product check or the experiment read, so no new exposure is logged.
23
+ */
24
+ export declare const getSourceLocation: (sourceAri: string | undefined) => SyncBlockSourceLocation | undefined;
package/package.json CHANGED
@@ -33,7 +33,7 @@
33
33
  "uuid": "^11.1.1"
34
34
  },
35
35
  "peerDependencies": {
36
- "@atlaskit/editor-common": "^131.2.0",
36
+ "@atlaskit/editor-common": "^131.6.0",
37
37
  "react": "^18.2.0 || ^19.2.0"
38
38
  },
39
39
  "devDependencies": {
@@ -42,11 +42,16 @@
42
42
  "react-dom": "^19.2.0"
43
43
  },
44
44
  "name": "@atlaskit/editor-synced-block-provider",
45
- "version": "23.0.5",
45
+ "version": "23.1.1",
46
46
  "description": "Synced Block Provider for @atlaskit/editor-plugin-synced-block",
47
47
  "author": "Atlassian Pty Ltd",
48
48
  "license": "Apache-2.0",
49
49
  "publishConfig": {
50
50
  "registry": "https://registry.npmjs.org/"
51
+ },
52
+ "platform-feature-flags": {
53
+ "platform_editor_blocks_patch_13": {
54
+ "type": "boolean"
55
+ }
51
56
  }
52
57
  }