@atlaskit/editor-synced-block-provider 3.12.1 → 3.13.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 (41) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/cjs/clients/block-service/blockSubscription.js +124 -0
  3. package/dist/cjs/clients/jira/sourceInfo.js +152 -0
  4. package/dist/cjs/providers/block-service/blockServiceAPI.js +43 -6
  5. package/dist/cjs/providers/syncBlockProvider.js +40 -8
  6. package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +351 -118
  7. package/dist/cjs/store-manager/syncBlockStoreManager.js +2 -2
  8. package/dist/cjs/utils/resolveSyncBlockInstance.js +1 -1
  9. package/dist/es2019/clients/block-service/blockSubscription.js +125 -0
  10. package/dist/es2019/clients/jira/sourceInfo.js +87 -0
  11. package/dist/es2019/providers/block-service/blockServiceAPI.js +40 -5
  12. package/dist/es2019/providers/syncBlockProvider.js +26 -2
  13. package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +237 -49
  14. package/dist/es2019/store-manager/syncBlockStoreManager.js +2 -2
  15. package/dist/es2019/utils/resolveSyncBlockInstance.js +1 -1
  16. package/dist/esm/clients/block-service/blockSubscription.js +118 -0
  17. package/dist/esm/clients/jira/sourceInfo.js +147 -0
  18. package/dist/esm/providers/block-service/blockServiceAPI.js +43 -6
  19. package/dist/esm/providers/syncBlockProvider.js +38 -6
  20. package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +351 -118
  21. package/dist/esm/store-manager/syncBlockStoreManager.js +2 -2
  22. package/dist/esm/utils/resolveSyncBlockInstance.js +1 -1
  23. package/dist/types/clients/block-service/blockService.d.ts +2 -2
  24. package/dist/types/clients/block-service/blockSubscription.d.ts +38 -0
  25. package/dist/types/clients/jira/sourceInfo.d.ts +2 -0
  26. package/dist/types/common/types.d.ts +4 -2
  27. package/dist/types/index.d.ts +2 -2
  28. package/dist/types/providers/block-service/blockServiceAPI.d.ts +8 -0
  29. package/dist/types/providers/syncBlockProvider.d.ts +9 -1
  30. package/dist/types/providers/types.d.ts +22 -6
  31. package/dist/types/store-manager/referenceSyncBlockStoreManager.d.ts +59 -0
  32. package/dist/types-ts4.5/clients/block-service/blockService.d.ts +2 -2
  33. package/dist/types-ts4.5/clients/block-service/blockSubscription.d.ts +38 -0
  34. package/dist/types-ts4.5/clients/jira/sourceInfo.d.ts +2 -0
  35. package/dist/types-ts4.5/common/types.d.ts +4 -2
  36. package/dist/types-ts4.5/index.d.ts +2 -2
  37. package/dist/types-ts4.5/providers/block-service/blockServiceAPI.d.ts +8 -0
  38. package/dist/types-ts4.5/providers/syncBlockProvider.d.ts +9 -1
  39. package/dist/types-ts4.5/providers/types.d.ts +22 -6
  40. package/dist/types-ts4.5/store-manager/referenceSyncBlockStoreManager.d.ts +59 -0
  41. package/package.json +2 -1
@@ -0,0 +1,118 @@
1
+ import { createClient } from 'graphql-ws';
2
+ var GRAPHQL_WS_ENDPOINT = '/gateway/api/graphql/subscriptions';
3
+ var blockServiceClient = null;
4
+ var getBlockServiceClient = function getBlockServiceClient() {
5
+ // Don't create client during SSR
6
+ if (typeof window === 'undefined') {
7
+ return null;
8
+ }
9
+ if (!blockServiceClient) {
10
+ var protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
11
+ var wsUrl = "".concat(protocol, "//").concat(window.location.host).concat(GRAPHQL_WS_ENDPOINT);
12
+ blockServiceClient = createClient({
13
+ url: wsUrl,
14
+ lazy: true,
15
+ retryAttempts: 3
16
+ });
17
+ }
18
+ return blockServiceClient;
19
+ };
20
+ var SUBSCRIPTION_QUERY = "\nsubscription EDITOR_SYNCED_BLOCK_ON_BLOCK_UPDATED($resourceId: ID!) {\n\tblockService_onBlockUpdated(resourceId: $resourceId) {\n\t\tblockAri\n\t\tblockInstanceId\n\t\tcontent\n\t\tcontentUpdatedAt\n\t\tcreatedAt\n\t\tcreatedBy\n\t\tdeletionReason\n\t\tproduct\n\t\tsourceAri\n\t\tstatus\n\t}\n}\n";
21
+ /**
22
+ * Extracts the resourceId from a block ARI.
23
+ * Block ARI format: ari:cloud:blocks:<cloudId>:synced-block/<resourceId>
24
+ * @param blockAri - The block ARI string
25
+ * @returns The resourceId portion of the ARI
26
+ */
27
+ var extractResourceIdFromBlockAri = function extractResourceIdFromBlockAri(blockAri) {
28
+ // eslint-disable-next-line require-unicode-regexp
29
+ var match = blockAri.match(/ari:cloud:blocks:[^:]+:synced-block\/(.+)$/);
30
+ return (match === null || match === void 0 ? void 0 : match[1]) || null;
31
+ };
32
+
33
+ /**
34
+ * Parses the subscription payload into a standardized format.
35
+ * @param payload - The raw subscription payload
36
+ * @returns Parsed block data or null if parsing fails
37
+ */
38
+ var parseSubscriptionPayload = function parseSubscriptionPayload(payload) {
39
+ try {
40
+ var resourceId = extractResourceIdFromBlockAri(payload.blockAri);
41
+ if (!resourceId) {
42
+ return null;
43
+ }
44
+ var createdAt;
45
+ if (payload.createdAt !== undefined && payload.createdAt !== null) {
46
+ try {
47
+ // BE returns microseconds, convert to milliseconds
48
+ createdAt = new Date(payload.createdAt / 1000).toISOString();
49
+ } catch (_unused) {
50
+ createdAt = undefined;
51
+ }
52
+ }
53
+ return {
54
+ blockAri: payload.blockAri,
55
+ blockInstanceId: payload.blockInstanceId,
56
+ content: JSON.parse(payload.content),
57
+ createdAt: createdAt,
58
+ createdBy: payload.createdBy,
59
+ product: payload.product,
60
+ resourceId: resourceId,
61
+ sourceAri: payload.sourceAri,
62
+ status: payload.status
63
+ };
64
+ } catch (_unused2) {
65
+ return null;
66
+ }
67
+ };
68
+
69
+ /**
70
+ * Creates a GraphQL subscription to block updates using the shared graphql-ws client.
71
+ *
72
+ * @param blockAri - The full block ARI to subscribe to (ari:cloud:blocks:{cloudId}:synced-block/{resourceId})
73
+ * @param onData - Callback function invoked when block data is updated
74
+ * @param onError - Optional callback function invoked on subscription errors
75
+ * @returns Unsubscribe function to close the subscription
76
+ */
77
+ export var subscribeToBlockUpdates = function subscribeToBlockUpdates(blockAri, onData, onError) {
78
+ var client = getBlockServiceClient();
79
+ if (!client) {
80
+ // Return a no-op unsubscribe if client is not available (e.g., SSR)
81
+ return function () {};
82
+ }
83
+ var unsubscribe = client.subscribe({
84
+ query: SUBSCRIPTION_QUERY,
85
+ variables: {
86
+ resourceId: blockAri
87
+ },
88
+ operationName: 'EDITOR_SYNCED_BLOCK_ON_BLOCK_UPDATED'
89
+ }, {
90
+ next: function next(value) {
91
+ var _value$data;
92
+ if ((_value$data = value.data) !== null && _value$data !== void 0 && _value$data.blockService_onBlockUpdated) {
93
+ var parsed = parseSubscriptionPayload(value.data.blockService_onBlockUpdated);
94
+ if (parsed !== null) {
95
+ onData(parsed);
96
+ } else {
97
+ onError === null || onError === void 0 || onError(new Error('Failed to parse block subscription payload'));
98
+ }
99
+ }
100
+ },
101
+ error: function (_error) {
102
+ function error(_x) {
103
+ return _error.apply(this, arguments);
104
+ }
105
+ error.toString = function () {
106
+ return _error.toString();
107
+ };
108
+ return error;
109
+ }(function (error) {
110
+ var errorMessage = error instanceof Error ? error.message : 'GraphQL subscription error';
111
+ onError === null || onError === void 0 || onError(new Error(errorMessage));
112
+ }),
113
+ complete: function complete() {
114
+ // Subscription completed
115
+ }
116
+ });
117
+ return unsubscribe;
118
+ };
@@ -0,0 +1,147 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
4
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
6
+ /* eslint-disable require-unicode-regexp */
7
+
8
+ import { fetchWithRetry } from '../../utils/retry';
9
+ var COMMON_HEADERS = {
10
+ 'Content-Type': 'application/json',
11
+ Accept: 'application/json'
12
+ };
13
+ var AGG_HEADERS = {
14
+ 'X-ExperimentalApi': 'confluence-agg-beta'
15
+ };
16
+ var GRAPHQL_ENDPOINT = '/gateway/api/graphql';
17
+ var GET_SOURCE_INFO_OPERATION_NAME = 'EDITOR_SYNCED_BLOCK_GET_SOURCE_INFO';
18
+ /**
19
+ * Query to get the work item url by id
20
+ * @param id - the ID of the work item
21
+ * @returns url of the work item
22
+ */
23
+ var GET_SOURCE_INFO_QUERY = "query ".concat(GET_SOURCE_INFO_OPERATION_NAME, " ($id: ID!) {\n jira {\n issueById(id: $id) {\n id\n webUrl\n summary\n }\n }}");
24
+ var getJiraWorkItemSourceInfo = /*#__PURE__*/function () {
25
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(ari) {
26
+ var bodyData, response;
27
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
28
+ while (1) switch (_context.prev = _context.next) {
29
+ case 0:
30
+ bodyData = {
31
+ query: GET_SOURCE_INFO_QUERY,
32
+ operationName: GET_SOURCE_INFO_OPERATION_NAME,
33
+ variables: {
34
+ id: ari
35
+ }
36
+ };
37
+ _context.next = 3;
38
+ return fetchWithRetry(GRAPHQL_ENDPOINT, {
39
+ method: 'POST',
40
+ headers: _objectSpread(_objectSpread({}, COMMON_HEADERS), AGG_HEADERS),
41
+ body: JSON.stringify(bodyData)
42
+ });
43
+ case 3:
44
+ response = _context.sent;
45
+ if (response.ok) {
46
+ _context.next = 6;
47
+ break;
48
+ }
49
+ throw new Error("Failed to get url: ".concat(response.statusText));
50
+ case 6:
51
+ _context.next = 8;
52
+ return response.json();
53
+ case 8:
54
+ return _context.abrupt("return", _context.sent);
55
+ case 9:
56
+ case "end":
57
+ return _context.stop();
58
+ }
59
+ }, _callee);
60
+ }));
61
+ return function getJiraWorkItemSourceInfo(_x) {
62
+ return _ref.apply(this, arguments);
63
+ };
64
+ }();
65
+ var resolveNoAccessWorkItemInfo = /*#__PURE__*/function () {
66
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(ari) {
67
+ var response, _payload$data, _payload$data2, payload, url, title;
68
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
69
+ while (1) switch (_context2.prev = _context2.next) {
70
+ case 0:
71
+ _context2.next = 2;
72
+ return fetch('/gateway/api/object-resolver/resolve/ari', {
73
+ method: 'POST',
74
+ headers: {
75
+ 'Content-Type': 'application/json',
76
+ Accept: 'application/json'
77
+ },
78
+ body: JSON.stringify({
79
+ ari: ari
80
+ })
81
+ });
82
+ case 2:
83
+ response = _context2.sent;
84
+ if (!response.ok) {
85
+ _context2.next = 12;
86
+ break;
87
+ }
88
+ _context2.next = 6;
89
+ return response.json();
90
+ case 6:
91
+ payload = _context2.sent;
92
+ url = payload === null || payload === void 0 || (_payload$data = payload.data) === null || _payload$data === void 0 ? void 0 : _payload$data.url;
93
+ title = payload === null || payload === void 0 || (_payload$data2 = payload.data) === null || _payload$data2 === void 0 ? void 0 : _payload$data2.name;
94
+ return _context2.abrupt("return", {
95
+ url: typeof url === 'string' ? url : undefined,
96
+ title: typeof title === 'string' ? title : undefined,
97
+ sourceAri: ari
98
+ });
99
+ case 12:
100
+ throw new Error("Failed to resolve ari: ".concat(response.statusText));
101
+ case 13:
102
+ case "end":
103
+ return _context2.stop();
104
+ }
105
+ }, _callee2);
106
+ }));
107
+ return function resolveNoAccessWorkItemInfo(_x2) {
108
+ return _ref2.apply(this, arguments);
109
+ };
110
+ }();
111
+ export var fetchJiraWorkItemInfo = /*#__PURE__*/function () {
112
+ var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(workItemAri, hasAccess) {
113
+ var _response$data, response, contentData, webUrl, summary;
114
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
115
+ while (1) switch (_context3.prev = _context3.next) {
116
+ case 0:
117
+ if (!hasAccess) {
118
+ _context3.next = 10;
119
+ break;
120
+ }
121
+ _context3.next = 3;
122
+ return getJiraWorkItemSourceInfo(workItemAri);
123
+ case 3:
124
+ response = _context3.sent;
125
+ contentData = (_response$data = response.data) === null || _response$data === void 0 || (_response$data = _response$data.jira) === null || _response$data === void 0 ? void 0 : _response$data.issueById;
126
+ webUrl = contentData === null || contentData === void 0 ? void 0 : contentData.webUrl;
127
+ summary = contentData === null || contentData === void 0 ? void 0 : contentData.summary;
128
+ return _context3.abrupt("return", Promise.resolve({
129
+ url: webUrl,
130
+ sourceAri: workItemAri,
131
+ title: summary
132
+ }));
133
+ case 10:
134
+ _context3.next = 12;
135
+ return resolveNoAccessWorkItemInfo(workItemAri);
136
+ case 12:
137
+ return _context3.abrupt("return", _context3.sent);
138
+ case 13:
139
+ case "end":
140
+ return _context3.stop();
141
+ }
142
+ }, _callee3);
143
+ }));
144
+ return function fetchJiraWorkItemInfo(_x3, _x4) {
145
+ return _ref3.apply(this, arguments);
146
+ };
147
+ }();
@@ -14,6 +14,7 @@ import { useMemo } from 'react';
14
14
  import { fg } from '@atlaskit/platform-feature-flags';
15
15
  import { generateBlockAri, generateBlockAriFromReference } from '../../clients/block-service/ari';
16
16
  import { batchRetrieveSyncedBlocks, BlockError, createSyncedBlock, deleteSyncedBlock, getReferenceSyncedBlocks, getReferenceSyncedBlocksByBlockAri, getSyncedBlockContent, updateReferenceSyncedBlockOnDocument, updateSyncedBlock } from '../../clients/block-service/blockService';
17
+ import { subscribeToBlockUpdates as subscribeToBlockUpdatesWS } from '../../clients/block-service/blockSubscription';
17
18
  import { SyncBlockError } from '../../common/types';
18
19
  import { stringifyError } from '../../utils/errorHandling';
19
20
  import { createResourceIdForReference } from '../../utils/resourceId';
@@ -111,7 +112,8 @@ export var convertToSyncBlockData = function convertToSyncBlockData(data, resour
111
112
  createdBy: data.createdBy,
112
113
  product: data.product,
113
114
  resourceId: resourceId,
114
- sourceAri: data.sourceAri
115
+ sourceAri: data.sourceAri,
116
+ status: data.status
115
117
  };
116
118
  };
117
119
  export var fetchReferences = /*#__PURE__*/function () {
@@ -231,7 +233,8 @@ var BlockServiceADFFetchProvider = /*#__PURE__*/function () {
231
233
  blockInstanceId: blockContentResponse.blockInstanceId,
232
234
  // this was the node's localId, but has become the resourceId.
233
235
  sourceAri: blockContentResponse.sourceAri,
234
- product: blockContentResponse.product
236
+ product: blockContentResponse.product,
237
+ status: blockContentResponse.status
235
238
  },
236
239
  resourceId: resourceId
237
240
  });
@@ -286,7 +289,7 @@ var BlockServiceADFFetchProvider = /*#__PURE__*/function () {
286
289
  response.references.forEach(function (reference) {
287
290
  references.push(_objectSpread(_objectSpread({}, reference), {}, {
288
291
  hasAccess: true,
289
- onSamePage: _this.parentAri === reference.documentAri
292
+ onSameDocument: _this.parentAri === reference.documentAri
290
293
  }));
291
294
  });
292
295
  response.errors.forEach(function (reference) {
@@ -295,7 +298,7 @@ var BlockServiceADFFetchProvider = /*#__PURE__*/function () {
295
298
  blockAri: reference.blockAri,
296
299
  documentAri: reference.documentAri,
297
300
  hasAccess: false,
298
- onSamePage: false
301
+ onSameDocument: false
299
302
  });
300
303
  }
301
304
  });
@@ -426,7 +429,8 @@ var BlockServiceADFFetchProvider = /*#__PURE__*/function () {
426
429
  resourceId: blockContentResponse.blockAri,
427
430
  blockInstanceId: blockContentResponse.blockInstanceId,
428
431
  sourceAri: blockContentResponse.sourceAri,
429
- product: blockContentResponse.product
432
+ product: blockContentResponse.product,
433
+ status: blockContentResponse.status
430
434
  },
431
435
  resourceId: resourceId
432
436
  });
@@ -529,7 +533,40 @@ var BlockServiceADFFetchProvider = /*#__PURE__*/function () {
529
533
  return _batchFetchData.apply(this, arguments);
530
534
  }
531
535
  return batchFetchData;
532
- }())
536
+ }()
537
+ /**
538
+ * Subscribes to real-time updates for a specific block using GraphQL WebSocket subscriptions.
539
+ * @param resourceId - The resource ID of the block to subscribe to
540
+ * @param onUpdate - Callback function invoked when the block is updated
541
+ * @param onError - Optional callback function invoked on subscription errors
542
+ * @returns Unsubscribe function to stop receiving updates
543
+ */
544
+ )
545
+ }, {
546
+ key: "subscribeToBlockUpdates",
547
+ value: function subscribeToBlockUpdates(resourceId, onUpdate, onError) {
548
+ var blockAri = generateBlockAriFromReference({
549
+ cloudId: this.cloudId,
550
+ resourceId: resourceId
551
+ });
552
+ return subscribeToBlockUpdatesWS(blockAri, function (parsedData) {
553
+ // Convert ParsedBlockSubscriptionData to SyncBlockInstance
554
+ var syncBlockInstance = {
555
+ data: {
556
+ content: parsedData.content,
557
+ resourceId: parsedData.blockAri,
558
+ blockInstanceId: parsedData.blockInstanceId,
559
+ sourceAri: parsedData.sourceAri,
560
+ product: parsedData.product,
561
+ createdAt: parsedData.createdAt,
562
+ createdBy: parsedData.createdBy,
563
+ status: parsedData.status
564
+ },
565
+ resourceId: parsedData.resourceId
566
+ };
567
+ onUpdate(syncBlockInstance);
568
+ }, onError);
569
+ }
533
570
  }]);
534
571
  }();
535
572
  /**
@@ -15,6 +15,7 @@ import { fg } from '@atlaskit/platform-feature-flags';
15
15
  import { getProductFromSourceAri } from '../clients/block-service/ari';
16
16
  import { getPageIdAndTypeFromConfluencePageAri } from '../clients/confluence/ari';
17
17
  import { fetchConfluencePageInfo } from '../clients/confluence/sourceInfo';
18
+ import { fetchJiraWorkItemInfo } from '../clients/jira/sourceInfo';
18
19
  import { SyncBlockError } from '../common/types';
19
20
  import { SyncBlockDataProvider } from './types';
20
21
  export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
@@ -302,6 +303,8 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
302
303
  _this$writeProvider,
303
304
  sourceInfo,
304
305
  _this$writeProvider2,
306
+ _this$writeProvider3,
307
+ _sourceInfo,
305
308
  _args4 = arguments;
306
309
  return _regeneratorRuntime.wrap(function _callee4$(_context4) {
307
310
  while (1) switch (_context4.prev = _context4.next) {
@@ -320,7 +323,7 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
320
323
  return _context4.abrupt("return", Promise.reject(new Error('Source ari or source product is undefined')));
321
324
  case 6:
322
325
  _context4.t0 = product;
323
- _context4.next = _context4.t0 === 'confluence-page' ? 9 : _context4.t0 === 'jira-work-item' ? 19 : 22;
326
+ _context4.next = _context4.t0 === 'confluence-page' ? 9 : _context4.t0 === 'jira-work-item' ? 19 : 27;
324
327
  break;
325
328
  case 9:
326
329
  _context4.next = 11;
@@ -338,22 +341,35 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
338
341
  return _context4.abrupt("return", Promise.resolve(undefined));
339
342
  case 15:
340
343
  return _context4.abrupt("return", _objectSpread(_objectSpread({}, sourceInfo), {}, {
341
- onSamePage: ((_this$writeProvider2 = this.writeProvider) === null || _this$writeProvider2 === void 0 ? void 0 : _this$writeProvider2.parentAri) === ari,
344
+ onSameDocument: ((_this$writeProvider2 = this.writeProvider) === null || _this$writeProvider2 === void 0 ? void 0 : _this$writeProvider2.parentAri) === ari,
342
345
  productType: product
343
346
  }));
344
347
  case 18:
345
348
  return _context4.abrupt("return", sourceInfo);
346
349
  case 19:
347
350
  if (!fg('platform_synced_block_dogfooding')) {
348
- _context4.next = 21;
351
+ _context4.next = 26;
352
+ break;
353
+ }
354
+ _context4.next = 22;
355
+ return fetchJiraWorkItemInfo(ari, hasAccess);
356
+ case 22:
357
+ _sourceInfo = _context4.sent;
358
+ if (_sourceInfo) {
359
+ _context4.next = 25;
349
360
  break;
350
361
  }
351
362
  return _context4.abrupt("return", Promise.resolve(undefined));
352
- case 21:
363
+ case 25:
364
+ return _context4.abrupt("return", _objectSpread(_objectSpread({}, _sourceInfo), {}, {
365
+ onSameDocument: ((_this$writeProvider3 = this.writeProvider) === null || _this$writeProvider3 === void 0 ? void 0 : _this$writeProvider3.parentAri) === ari,
366
+ productType: product
367
+ }));
368
+ case 26:
353
369
  return _context4.abrupt("return", Promise.reject(new Error('Jira work item source product not supported')));
354
- case 22:
370
+ case 27:
355
371
  return _context4.abrupt("return", Promise.reject(new Error("".concat(product, " source product not supported"))));
356
- case 23:
372
+ case 28:
357
373
  case "end":
358
374
  return _context4.stop();
359
375
  }
@@ -438,6 +454,22 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
438
454
  }
439
455
  return this.fetchProvider.fetchReferences(isSource ? this.generateResourceIdForReference(resourceId) : resourceId);
440
456
  }
457
+
458
+ /**
459
+ * Subscribes to real-time updates for a specific block.
460
+ * @param resourceId - The resource ID of the block to subscribe to
461
+ * @param onUpdate - Callback function invoked when the block is updated
462
+ * @param onError - Optional callback function invoked on subscription errors
463
+ * @returns Unsubscribe function to stop receiving updates, or undefined if not supported
464
+ */
465
+ }, {
466
+ key: "subscribeToBlockUpdates",
467
+ value: function subscribeToBlockUpdates(resourceId, onUpdate, onError) {
468
+ if (this.fetchProvider.subscribeToBlockUpdates) {
469
+ return this.fetchProvider.subscribeToBlockUpdates(resourceId, onUpdate, onError);
470
+ }
471
+ return undefined;
472
+ }
441
473
  }]);
442
474
  }(SyncBlockDataProvider);
443
475
  var createSyncedBlockProvider = function createSyncedBlockProvider(_ref) {