@atlaskit/editor-synced-block-provider 4.1.5 → 4.1.7

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.
package/AGENTS.md CHANGED
@@ -1,16 +1,17 @@
1
1
  # Synced Block Provider — Developer Agent Guide
2
2
 
3
- > **Package**: `@atlaskit/editor-synced-block-provider`
4
- > **Purpose**: Data layer for synced blocks — store managers, block service API client, ARI generation, permissions, media tokens.
5
- > **Full Knowledge Base**: [Synced Blocks — Comprehensive Knowledge Base](https://hello.atlassian.net/wiki/spaces/egcuc/pages/6679548384)
3
+ > **Package**: `@atlaskit/editor-synced-block-provider` **Purpose**: Data layer for synced blocks —
4
+ > store managers, block service API client, ARI generation, permissions, media tokens. **Full
5
+ > Knowledge Base**:
6
+ > [Synced Blocks — Comprehensive Knowledge Base](https://hello.atlassian.net/wiki/spaces/egcuc/pages/6679548384)
6
7
 
7
8
  ---
8
9
 
9
10
  ## Quick Context
10
11
 
11
12
  This package manages the lifecycle and state of synced blocks for both source and reference nodes.
12
- It provides the data fetching, caching, subscription, and persistence layer used by the editor plugin
13
- and the renderer across Confluence and Jira.
13
+ It provides the data fetching, caching, subscription, and persistence layer used by the editor
14
+ plugin and the renderer across Confluence and Jira.
14
15
 
15
16
  ---
16
17
 
@@ -62,17 +63,19 @@ SyncBlockStoreManager (parent coordinator)
62
63
 
63
64
  ### ARI Formats & Utilities
64
65
 
65
- | Function | ARI Pattern | Example |
66
- |----------|-------------|---------|
67
- | `generateBlockAri({cloudId, parentId, product, resourceId})` | Source block ARI | `ari:cloud:block::{cloudId}/confluence-page:{pageId}/{localId}` |
68
- | `generateBlockAriFromReference({cloudId, resourceId})` | Reference block ARI | — |
69
- | `getConfluencePageAri({pageId, cloudId, pageType})` | Confluence page | `ari:cloud:confluence::{cloudId}:page/{pageId}` |
70
- | `getJiraWorkItemAri({cloudId, workItemId})` | Jira issue | `ari:cloud:jira::{cloudId}:work-item/{issueId}` |
71
- | `getJiraWorkItemIdFromAri(ari)` | Extract issue ID from ARI | — |
66
+ | Function | ARI Pattern | Example |
67
+ | ------------------------------------------------------------ | ------------------------- | --------------------------------------------------------------- |
68
+ | `generateBlockAri({cloudId, parentId, product, resourceId})` | Source block ARI | `ari:cloud:block::{cloudId}/confluence-page:{pageId}/{localId}` |
69
+ | `generateBlockAriFromReference({cloudId, resourceId})` | Reference block ARI | — |
70
+ | `getConfluencePageAri({pageId, cloudId, pageType})` | Confluence page | `ari:cloud:confluence::{cloudId}:page/{pageId}` |
71
+ | `getJiraWorkItemAri({cloudId, workItemId})` | Jira issue | `ari:cloud:jira::{cloudId}:work-item/{issueId}` |
72
+ | `getJiraWorkItemIdFromAri(ari)` | Extract issue ID from ARI | — |
72
73
 
73
74
  ### Block Service API
74
75
 
75
- The client in `clients/block-service/blockService.ts` communicates via GraphQL at `/gateway/api/graphql`:
76
+ The client in `clients/block-service/blockService.ts` communicates via GraphQL at
77
+ `/gateway/api/graphql`:
78
+
76
79
  - **Fetch**: Single or batch block content retrieval
77
80
  - **Create**: Register new source block with content
78
81
  - **Update**: Push content changes (debounced 3s)
@@ -82,27 +85,33 @@ The client in `clients/block-service/blockService.ts` communicates via GraphQL a
82
85
 
83
86
  ### Media Token Fetching
84
87
 
85
- `fetchMediaToken(contentId)` → GraphQL `MediaUploadTokenQuery` → returns `{token, config: {clientId, fileStoreUrl}, collectionId}`
88
+ `fetchMediaToken(contentId)` → GraphQL `MediaUploadTokenQuery` → returns
89
+ `{token, config: {clientId, fileStoreUrl}, collectionId}`
86
90
 
87
- Used when synced blocks contain media (images, files) — the reference needs a valid token to render media from the source page.
91
+ Used when synced blocks contain media (images, files) — the reference needs a valid token to render
92
+ media from the source page.
88
93
 
89
94
  ---
90
95
 
91
96
  ## Common Tasks
92
97
 
93
98
  ### Adding a new API method
99
+
94
100
  1. Add the GraphQL query/mutation in `clients/block-service/blockService.ts`
95
101
  2. Expose it through the appropriate store manager
96
102
  3. Export from `src/index.ts` if needed by product integrations
97
103
  4. Add tests in `editor-synced-block-provider-tests`
98
104
 
99
105
  ### Debugging data issues
106
+
100
107
  1. Check `ReferenceSyncBlockStoreManager` cache state
101
108
  2. Verify ARI format matches expected pattern for the product
102
109
  3. Check Block Service API responses in network tab (look for `/gateway/api/graphql`)
103
- 4. Use analytics: [HOW-TO: Debug errors](https://hello.atlassian.net/wiki/spaces/egcuc/pages/6342760320)
110
+ 4. Use analytics:
111
+ [HOW-TO: Debug errors](https://hello.atlassian.net/wiki/spaces/egcuc/pages/6342760320)
104
112
 
105
113
  ### Adding support for a new product
114
+
106
115
  1. Create ARI utilities in `clients/{product}/ari.ts`
107
116
  2. Ensure `generateBlockAri` supports the new product type
108
117
  3. Add media token fetching if the product has media content
@@ -111,7 +120,10 @@ Used when synced blocks contain media (images, files) — the reference needs a
111
120
  ---
112
121
 
113
122
  ## Related Packages
123
+
114
124
  - **Plugin**: `platform/packages/editor/editor-plugin-synced-block/` — uses store managers
115
125
  - **Renderer**: `platform/packages/editor/editor-synced-block-renderer/` — uses fetch provider
116
- - **Confluence**: `confluence/next/packages/fabric-providers/src/SyncedBlockProvider.ts` — wraps this provider
117
- - **Jira**: `jira/src/packages/issue/issue-view-synced-block-provider/` — wraps this provider with Relay
126
+ - **Confluence**: `confluence/next/packages/fabric-providers/src/SyncedBlockProvider.ts` — wraps
127
+ this provider
128
+ - **Jira**: `jira/src/packages/issue/issue-view-synced-block-provider/` — wraps this provider with
129
+ Relay
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/editor-synced-block-provider
2
2
 
3
+ ## 4.1.7
4
+
5
+ ### Patch Changes
6
+
7
+ - [`612d18a57aabd`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/612d18a57aabd) -
8
+ 404s on updating a source synced block should be ignored
9
+ - Updated dependencies
10
+
11
+ ## 4.1.6
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies
16
+
3
17
  ## 4.1.5
4
18
 
5
19
  ### Patch Changes
@@ -12,6 +12,7 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
12
12
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
13
13
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
14
14
  var _react = require("react");
15
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
15
16
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
16
17
  var _ari = require("../../clients/block-service/ari");
17
18
  var _blockService = require("../../clients/block-service/blockService");
@@ -49,6 +50,8 @@ var mapErrorResponseCode = function mapErrorResponseCode(errorCode) {
49
50
  switch (errorCode) {
50
51
  case 'FORBIDDEN':
51
52
  return _types.SyncBlockError.Forbidden;
53
+ case 'RESOURCE_NOT_FOUND':
54
+ return (0, _platformFeatureFlags.fg)('block_service_source_repair') ? _types.SyncBlockError.NotFound : _types.SyncBlockError.Errored;
52
55
  case 'NOT_FOUND':
53
56
  return _types.SyncBlockError.NotFound;
54
57
  case 'INVALID_REQUEST':
@@ -832,8 +835,6 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
832
835
  this.product = product;
833
836
  this.getVersion = getVersion;
834
837
  }
835
-
836
- // it will first try to update and if it can't (404) then it will try to create
837
838
  return (0, _createClass2.default)(BlockServiceADFWriteProvider, [{
838
839
  key: "writeData",
839
840
  value: function () {
@@ -1241,10 +1242,19 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
1241
1242
  block = _step7.value;
1242
1243
  error = errorResourceIds.get(block.resourceId);
1243
1244
  if (error) {
1244
- results.push({
1245
- error: error,
1246
- resourceId: block.resourceId
1247
- });
1245
+ if ((0, _platformFeatureFlags.fg)('block_service_source_repair')) {
1246
+ if (error !== _types.SyncBlockError.NotFound) {
1247
+ results.push({
1248
+ error: error,
1249
+ resourceId: block.resourceId
1250
+ });
1251
+ }
1252
+ } else {
1253
+ results.push({
1254
+ error: error,
1255
+ resourceId: block.resourceId
1256
+ });
1257
+ }
1248
1258
  } else if (!results.some(function (r) {
1249
1259
  return r.resourceId === block.resourceId;
1250
1260
  })) {
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable require-unicode-regexp */
2
2
  import { useMemo } from 'react';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
3
4
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
4
5
  import { generateBlockAri, generateBlockAriFromReference } from '../../clients/block-service/ari';
5
6
  import { batchRetrieveSyncedBlocks, BlockError, BlockTimeoutError, createSyncedBlock, deleteSyncedBlock, getReferenceSyncedBlocks, getReferenceSyncedBlocksByBlockAri, getSyncedBlockContent, updateReferenceSyncedBlockOnDocument, updateSyncedBlock, updateSyncedBlocks } from '../../clients/block-service/blockService';
@@ -32,6 +33,8 @@ const mapErrorResponseCode = errorCode => {
32
33
  switch (errorCode) {
33
34
  case 'FORBIDDEN':
34
35
  return SyncBlockError.Forbidden;
36
+ case 'RESOURCE_NOT_FOUND':
37
+ return fg('block_service_source_repair') ? SyncBlockError.NotFound : SyncBlockError.Errored;
35
38
  case 'NOT_FOUND':
36
39
  return SyncBlockError.NotFound;
37
40
  case 'INVALID_REQUEST':
@@ -573,8 +576,6 @@ class BlockServiceADFWriteProvider {
573
576
  this.product = product;
574
577
  this.getVersion = getVersion;
575
578
  }
576
-
577
- // it will first try to update and if it can't (404) then it will try to create
578
579
  async writeData(data) {
579
580
  if (!this.parentAri || !this.parentId) {
580
581
  return {
@@ -802,10 +803,19 @@ class BlockServiceADFWriteProvider {
802
803
  for (const block of data) {
803
804
  const error = errorResourceIds.get(block.resourceId);
804
805
  if (error) {
805
- results.push({
806
- error,
807
- resourceId: block.resourceId
808
- });
806
+ if (fg('block_service_source_repair')) {
807
+ if (error !== SyncBlockError.NotFound) {
808
+ results.push({
809
+ error,
810
+ resourceId: block.resourceId
811
+ });
812
+ }
813
+ } else {
814
+ results.push({
815
+ error,
816
+ resourceId: block.resourceId
817
+ });
818
+ }
809
819
  } else if (!results.some(r => r.resourceId === block.resourceId)) {
810
820
  // If not in success or error lists, mark as errored
811
821
  results.push({
@@ -11,6 +11,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
11
11
  import _regeneratorRuntime from "@babel/runtime/regenerator";
12
12
  /* eslint-disable require-unicode-regexp */
13
13
  import { useMemo } from 'react';
14
+ import { fg } from '@atlaskit/platform-feature-flags';
14
15
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
15
16
  import { generateBlockAri as _generateBlockAri, generateBlockAriFromReference } from '../../clients/block-service/ari';
16
17
  import { batchRetrieveSyncedBlocks, BlockError, BlockTimeoutError, createSyncedBlock, deleteSyncedBlock, getReferenceSyncedBlocks, getReferenceSyncedBlocksByBlockAri, getSyncedBlockContent, updateReferenceSyncedBlockOnDocument, updateSyncedBlock, updateSyncedBlocks } from '../../clients/block-service/blockService';
@@ -43,6 +44,8 @@ var mapErrorResponseCode = function mapErrorResponseCode(errorCode) {
43
44
  switch (errorCode) {
44
45
  case 'FORBIDDEN':
45
46
  return SyncBlockError.Forbidden;
47
+ case 'RESOURCE_NOT_FOUND':
48
+ return fg('block_service_source_repair') ? SyncBlockError.NotFound : SyncBlockError.Errored;
46
49
  case 'NOT_FOUND':
47
50
  return SyncBlockError.NotFound;
48
51
  case 'INVALID_REQUEST':
@@ -827,8 +830,6 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
827
830
  this.product = product;
828
831
  this.getVersion = getVersion;
829
832
  }
830
-
831
- // it will first try to update and if it can't (404) then it will try to create
832
833
  return _createClass(BlockServiceADFWriteProvider, [{
833
834
  key: "writeData",
834
835
  value: function () {
@@ -1236,10 +1237,19 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
1236
1237
  block = _step7.value;
1237
1238
  error = errorResourceIds.get(block.resourceId);
1238
1239
  if (error) {
1239
- results.push({
1240
- error: error,
1241
- resourceId: block.resourceId
1242
- });
1240
+ if (fg('block_service_source_repair')) {
1241
+ if (error !== SyncBlockError.NotFound) {
1242
+ results.push({
1243
+ error: error,
1244
+ resourceId: block.resourceId
1245
+ });
1246
+ }
1247
+ } else {
1248
+ results.push({
1249
+ error: error,
1250
+ resourceId: block.resourceId
1251
+ });
1252
+ }
1243
1253
  } else if (!results.some(function (r) {
1244
1254
  return r.resourceId === block.resourceId;
1245
1255
  })) {
package/package.json CHANGED
@@ -29,7 +29,7 @@
29
29
  "@atlaskit/editor-prosemirror": "^7.3.0",
30
30
  "@atlaskit/node-data-provider": "^9.0.0",
31
31
  "@atlaskit/platform-feature-flags": "^1.1.0",
32
- "@atlaskit/tmp-editor-statsig": "^44.0.0",
32
+ "@atlaskit/tmp-editor-statsig": "^45.0.0",
33
33
  "@babel/runtime": "^7.0.0",
34
34
  "@compiled/react": "^0.20.0",
35
35
  "graphql-ws": "^5.14.2",
@@ -38,7 +38,7 @@
38
38
  "uuid": "^3.1.0"
39
39
  },
40
40
  "peerDependencies": {
41
- "@atlaskit/editor-common": "^112.7.0",
41
+ "@atlaskit/editor-common": "^112.8.0",
42
42
  "react": "^18.2.0"
43
43
  },
44
44
  "devDependencies": {
@@ -81,12 +81,16 @@
81
81
  }
82
82
  },
83
83
  "name": "@atlaskit/editor-synced-block-provider",
84
- "version": "4.1.5",
84
+ "version": "4.1.7",
85
85
  "description": "Synced Block Provider for @atlaskit/editor-plugin-synced-block",
86
86
  "author": "Atlassian Pty Ltd",
87
87
  "license": "Apache-2.0",
88
88
  "publishConfig": {
89
89
  "registry": "https://registry.npmjs.org/"
90
90
  },
91
- "platform-feature-flags": {}
91
+ "platform-feature-flags": {
92
+ "block_service_source_repair": {
93
+ "type": "boolean"
94
+ }
95
+ }
92
96
  }