@atlaskit/editor-synced-block-provider 3.12.1 → 3.13.0
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/CHANGELOG.md +16 -0
- package/dist/cjs/clients/block-service/blockSubscription.js +124 -0
- package/dist/cjs/clients/jira/sourceInfo.js +152 -0
- package/dist/cjs/providers/block-service/blockServiceAPI.js +43 -6
- package/dist/cjs/providers/syncBlockProvider.js +40 -8
- package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +347 -114
- package/dist/cjs/store-manager/syncBlockStoreManager.js +2 -2
- package/dist/cjs/utils/resolveSyncBlockInstance.js +1 -1
- package/dist/es2019/clients/block-service/blockSubscription.js +125 -0
- package/dist/es2019/clients/jira/sourceInfo.js +87 -0
- package/dist/es2019/providers/block-service/blockServiceAPI.js +40 -5
- package/dist/es2019/providers/syncBlockProvider.js +26 -2
- package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +233 -45
- package/dist/es2019/store-manager/syncBlockStoreManager.js +2 -2
- package/dist/es2019/utils/resolveSyncBlockInstance.js +1 -1
- package/dist/esm/clients/block-service/blockSubscription.js +118 -0
- package/dist/esm/clients/jira/sourceInfo.js +147 -0
- package/dist/esm/providers/block-service/blockServiceAPI.js +43 -6
- package/dist/esm/providers/syncBlockProvider.js +38 -6
- package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +347 -114
- package/dist/esm/store-manager/syncBlockStoreManager.js +2 -2
- package/dist/esm/utils/resolveSyncBlockInstance.js +1 -1
- package/dist/types/clients/block-service/blockService.d.ts +2 -2
- package/dist/types/clients/block-service/blockSubscription.d.ts +38 -0
- package/dist/types/clients/jira/sourceInfo.d.ts +2 -0
- package/dist/types/common/types.d.ts +4 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/providers/block-service/blockServiceAPI.d.ts +8 -0
- package/dist/types/providers/syncBlockProvider.d.ts +9 -1
- package/dist/types/providers/types.d.ts +22 -6
- package/dist/types/store-manager/referenceSyncBlockStoreManager.d.ts +59 -0
- package/dist/types-ts4.5/clients/block-service/blockService.d.ts +2 -2
- package/dist/types-ts4.5/clients/block-service/blockSubscription.d.ts +38 -0
- package/dist/types-ts4.5/clients/jira/sourceInfo.d.ts +2 -0
- package/dist/types-ts4.5/common/types.d.ts +4 -2
- package/dist/types-ts4.5/index.d.ts +2 -2
- package/dist/types-ts4.5/providers/block-service/blockServiceAPI.d.ts +8 -0
- package/dist/types-ts4.5/providers/syncBlockProvider.d.ts +9 -1
- package/dist/types-ts4.5/providers/types.d.ts +22 -6
- package/dist/types-ts4.5/store-manager/referenceSyncBlockStoreManager.d.ts +59 -0
- package/package.json +2 -1
|
@@ -89,7 +89,7 @@ var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/functio
|
|
|
89
89
|
return _context.abrupt("return", undefined);
|
|
90
90
|
case 5:
|
|
91
91
|
return _context.abrupt("return", _objectSpread(_objectSpread({}, sourceInfo), {}, {
|
|
92
|
-
|
|
92
|
+
onSameDocument: reference.onSameDocument,
|
|
93
93
|
hasAccess: reference.hasAccess,
|
|
94
94
|
productType: sourceInfo.productType
|
|
95
95
|
}));
|
|
@@ -113,7 +113,7 @@ var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/functio
|
|
|
113
113
|
sourceSyncBlockData = _context2.sent;
|
|
114
114
|
if (sourceSyncBlockData) {
|
|
115
115
|
sourceInfos.push(_objectSpread(_objectSpread({}, sourceSyncBlockData), {}, {
|
|
116
|
-
|
|
116
|
+
onSameDocument: Boolean(sourceSyncBlockData === null || sourceSyncBlockData === void 0 ? void 0 : sourceSyncBlockData.onSameDocument),
|
|
117
117
|
hasAccess: true,
|
|
118
118
|
isSource: true,
|
|
119
119
|
productType: sourceSyncBlockData === null || sourceSyncBlockData === void 0 ? void 0 : sourceSyncBlockData.productType
|
|
@@ -41,7 +41,7 @@ var resolveSyncBlockInstance = exports.resolveSyncBlockInstance = function resol
|
|
|
41
41
|
sourceTitle: ((_newResult$data2 = newResult.data) === null || _newResult$data2 === void 0 ? void 0 : _newResult$data2.sourceTitle) || ((_oldResult$data2 = oldResult.data) === null || _oldResult$data2 === void 0 ? void 0 : _oldResult$data2.sourceTitle) || undefined
|
|
42
42
|
}, (0, _platformFeatureFlags.fg)('platform_synced_block_dogfooding') && {
|
|
43
43
|
sourceSubType: ((_newResult$data3 = newResult.data) === null || _newResult$data3 === void 0 ? void 0 : _newResult$data3.sourceSubType) || ((_oldResult$data3 = oldResult.data) === null || _oldResult$data3 === void 0 ? void 0 : _oldResult$data3.sourceSubType) || undefined,
|
|
44
|
-
|
|
44
|
+
onSameDocument: ((_newResult$data4 = newResult.data) === null || _newResult$data4 === void 0 ? void 0 : _newResult$data4.onSameDocument) || ((_oldResult$data4 = oldResult.data) === null || _oldResult$data4 === void 0 ? void 0 : _oldResult$data4.onSameDocument) || undefined
|
|
45
45
|
})
|
|
46
46
|
});
|
|
47
47
|
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { createClient } from 'graphql-ws';
|
|
2
|
+
const GRAPHQL_WS_ENDPOINT = '/gateway/api/graphql/subscriptions';
|
|
3
|
+
let blockServiceClient = null;
|
|
4
|
+
const getBlockServiceClient = () => {
|
|
5
|
+
// Don't create client during SSR
|
|
6
|
+
if (typeof window === 'undefined') {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
if (!blockServiceClient) {
|
|
10
|
+
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
11
|
+
const wsUrl = `${protocol}//${window.location.host}${GRAPHQL_WS_ENDPOINT}`;
|
|
12
|
+
blockServiceClient = createClient({
|
|
13
|
+
url: wsUrl,
|
|
14
|
+
lazy: true,
|
|
15
|
+
retryAttempts: 3
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return blockServiceClient;
|
|
19
|
+
};
|
|
20
|
+
const SUBSCRIPTION_QUERY = `
|
|
21
|
+
subscription EDITOR_SYNCED_BLOCK_ON_BLOCK_UPDATED($resourceId: ID!) {
|
|
22
|
+
blockService_onBlockUpdated(resourceId: $resourceId) {
|
|
23
|
+
blockAri
|
|
24
|
+
blockInstanceId
|
|
25
|
+
content
|
|
26
|
+
contentUpdatedAt
|
|
27
|
+
createdAt
|
|
28
|
+
createdBy
|
|
29
|
+
deletionReason
|
|
30
|
+
product
|
|
31
|
+
sourceAri
|
|
32
|
+
status
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
/**
|
|
37
|
+
* Extracts the resourceId from a block ARI.
|
|
38
|
+
* Block ARI format: ari:cloud:blocks:<cloudId>:synced-block/<resourceId>
|
|
39
|
+
* @param blockAri - The block ARI string
|
|
40
|
+
* @returns The resourceId portion of the ARI
|
|
41
|
+
*/
|
|
42
|
+
const extractResourceIdFromBlockAri = blockAri => {
|
|
43
|
+
// eslint-disable-next-line require-unicode-regexp
|
|
44
|
+
const match = blockAri.match(/ari:cloud:blocks:[^:]+:synced-block\/(.+)$/);
|
|
45
|
+
return (match === null || match === void 0 ? void 0 : match[1]) || null;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Parses the subscription payload into a standardized format.
|
|
50
|
+
* @param payload - The raw subscription payload
|
|
51
|
+
* @returns Parsed block data or null if parsing fails
|
|
52
|
+
*/
|
|
53
|
+
const parseSubscriptionPayload = payload => {
|
|
54
|
+
try {
|
|
55
|
+
const resourceId = extractResourceIdFromBlockAri(payload.blockAri);
|
|
56
|
+
if (!resourceId) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
let createdAt;
|
|
60
|
+
if (payload.createdAt !== undefined && payload.createdAt !== null) {
|
|
61
|
+
try {
|
|
62
|
+
// BE returns microseconds, convert to milliseconds
|
|
63
|
+
createdAt = new Date(payload.createdAt / 1000).toISOString();
|
|
64
|
+
} catch {
|
|
65
|
+
createdAt = undefined;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
blockAri: payload.blockAri,
|
|
70
|
+
blockInstanceId: payload.blockInstanceId,
|
|
71
|
+
content: JSON.parse(payload.content),
|
|
72
|
+
createdAt,
|
|
73
|
+
createdBy: payload.createdBy,
|
|
74
|
+
product: payload.product,
|
|
75
|
+
resourceId,
|
|
76
|
+
sourceAri: payload.sourceAri,
|
|
77
|
+
status: payload.status
|
|
78
|
+
};
|
|
79
|
+
} catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Creates a GraphQL subscription to block updates using the shared graphql-ws client.
|
|
86
|
+
*
|
|
87
|
+
* @param blockAri - The full block ARI to subscribe to (ari:cloud:blocks:{cloudId}:synced-block/{resourceId})
|
|
88
|
+
* @param onData - Callback function invoked when block data is updated
|
|
89
|
+
* @param onError - Optional callback function invoked on subscription errors
|
|
90
|
+
* @returns Unsubscribe function to close the subscription
|
|
91
|
+
*/
|
|
92
|
+
export const subscribeToBlockUpdates = (blockAri, onData, onError) => {
|
|
93
|
+
const client = getBlockServiceClient();
|
|
94
|
+
if (!client) {
|
|
95
|
+
// Return a no-op unsubscribe if client is not available (e.g., SSR)
|
|
96
|
+
return () => {};
|
|
97
|
+
}
|
|
98
|
+
const unsubscribe = client.subscribe({
|
|
99
|
+
query: SUBSCRIPTION_QUERY,
|
|
100
|
+
variables: {
|
|
101
|
+
resourceId: blockAri
|
|
102
|
+
},
|
|
103
|
+
operationName: 'EDITOR_SYNCED_BLOCK_ON_BLOCK_UPDATED'
|
|
104
|
+
}, {
|
|
105
|
+
next: value => {
|
|
106
|
+
var _value$data;
|
|
107
|
+
if ((_value$data = value.data) !== null && _value$data !== void 0 && _value$data.blockService_onBlockUpdated) {
|
|
108
|
+
const parsed = parseSubscriptionPayload(value.data.blockService_onBlockUpdated);
|
|
109
|
+
if (parsed !== null) {
|
|
110
|
+
onData(parsed);
|
|
111
|
+
} else {
|
|
112
|
+
onError === null || onError === void 0 ? void 0 : onError(new Error('Failed to parse block subscription payload'));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
error: error => {
|
|
117
|
+
const errorMessage = error instanceof Error ? error.message : 'GraphQL subscription error';
|
|
118
|
+
onError === null || onError === void 0 ? void 0 : onError(new Error(errorMessage));
|
|
119
|
+
},
|
|
120
|
+
complete: () => {
|
|
121
|
+
// Subscription completed
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
return unsubscribe;
|
|
125
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/* eslint-disable require-unicode-regexp */
|
|
2
|
+
|
|
3
|
+
import { fetchWithRetry } from '../../utils/retry';
|
|
4
|
+
const COMMON_HEADERS = {
|
|
5
|
+
'Content-Type': 'application/json',
|
|
6
|
+
Accept: 'application/json'
|
|
7
|
+
};
|
|
8
|
+
const AGG_HEADERS = {
|
|
9
|
+
'X-ExperimentalApi': 'confluence-agg-beta'
|
|
10
|
+
};
|
|
11
|
+
const GRAPHQL_ENDPOINT = '/gateway/api/graphql';
|
|
12
|
+
const GET_SOURCE_INFO_OPERATION_NAME = 'EDITOR_SYNCED_BLOCK_GET_SOURCE_INFO';
|
|
13
|
+
/**
|
|
14
|
+
* Query to get the work item url by id
|
|
15
|
+
* @param id - the ID of the work item
|
|
16
|
+
* @returns url of the work item
|
|
17
|
+
*/
|
|
18
|
+
const GET_SOURCE_INFO_QUERY = `query ${GET_SOURCE_INFO_OPERATION_NAME} ($id: ID!) {
|
|
19
|
+
jira {
|
|
20
|
+
issueById(id: $id) {
|
|
21
|
+
id
|
|
22
|
+
webUrl
|
|
23
|
+
summary
|
|
24
|
+
}
|
|
25
|
+
}}`;
|
|
26
|
+
const getJiraWorkItemSourceInfo = async ari => {
|
|
27
|
+
const bodyData = {
|
|
28
|
+
query: GET_SOURCE_INFO_QUERY,
|
|
29
|
+
operationName: GET_SOURCE_INFO_OPERATION_NAME,
|
|
30
|
+
variables: {
|
|
31
|
+
id: ari
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const response = await fetchWithRetry(GRAPHQL_ENDPOINT, {
|
|
35
|
+
method: 'POST',
|
|
36
|
+
headers: {
|
|
37
|
+
...COMMON_HEADERS,
|
|
38
|
+
...AGG_HEADERS
|
|
39
|
+
},
|
|
40
|
+
body: JSON.stringify(bodyData)
|
|
41
|
+
});
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
throw new Error(`Failed to get url: ${response.statusText}`);
|
|
44
|
+
}
|
|
45
|
+
return await response.json();
|
|
46
|
+
};
|
|
47
|
+
const resolveNoAccessWorkItemInfo = async ari => {
|
|
48
|
+
const response = await fetch('/gateway/api/object-resolver/resolve/ari', {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
headers: {
|
|
51
|
+
'Content-Type': 'application/json',
|
|
52
|
+
Accept: 'application/json'
|
|
53
|
+
},
|
|
54
|
+
body: JSON.stringify({
|
|
55
|
+
ari
|
|
56
|
+
})
|
|
57
|
+
});
|
|
58
|
+
if (response.ok) {
|
|
59
|
+
var _payload$data, _payload$data2;
|
|
60
|
+
const payload = await response.json();
|
|
61
|
+
const url = payload === null || payload === void 0 ? void 0 : (_payload$data = payload.data) === null || _payload$data === void 0 ? void 0 : _payload$data.url;
|
|
62
|
+
const title = payload === null || payload === void 0 ? void 0 : (_payload$data2 = payload.data) === null || _payload$data2 === void 0 ? void 0 : _payload$data2.name;
|
|
63
|
+
return {
|
|
64
|
+
url: typeof url === 'string' ? url : undefined,
|
|
65
|
+
title: typeof title === 'string' ? title : undefined,
|
|
66
|
+
sourceAri: ari
|
|
67
|
+
};
|
|
68
|
+
} else {
|
|
69
|
+
throw new Error(`Failed to resolve ari: ${response.statusText}`);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
export const fetchJiraWorkItemInfo = async (workItemAri, hasAccess) => {
|
|
73
|
+
if (hasAccess) {
|
|
74
|
+
var _response$data, _response$data$jira;
|
|
75
|
+
const response = await getJiraWorkItemSourceInfo(workItemAri);
|
|
76
|
+
const contentData = (_response$data = response.data) === null || _response$data === void 0 ? void 0 : (_response$data$jira = _response$data.jira) === null || _response$data$jira === void 0 ? void 0 : _response$data$jira.issueById;
|
|
77
|
+
const webUrl = contentData === null || contentData === void 0 ? void 0 : contentData.webUrl;
|
|
78
|
+
const summary = contentData === null || contentData === void 0 ? void 0 : contentData.summary;
|
|
79
|
+
return Promise.resolve({
|
|
80
|
+
url: webUrl,
|
|
81
|
+
sourceAri: workItemAri,
|
|
82
|
+
title: summary
|
|
83
|
+
});
|
|
84
|
+
} else {
|
|
85
|
+
return await resolveNoAccessWorkItemInfo(workItemAri);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
@@ -3,6 +3,7 @@ import { useMemo } from 'react';
|
|
|
3
3
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
4
4
|
import { generateBlockAri, generateBlockAriFromReference } from '../../clients/block-service/ari';
|
|
5
5
|
import { batchRetrieveSyncedBlocks, BlockError, createSyncedBlock, deleteSyncedBlock, getReferenceSyncedBlocks, getReferenceSyncedBlocksByBlockAri, getSyncedBlockContent, updateReferenceSyncedBlockOnDocument, updateSyncedBlock } from '../../clients/block-service/blockService';
|
|
6
|
+
import { subscribeToBlockUpdates as subscribeToBlockUpdatesWS } from '../../clients/block-service/blockSubscription';
|
|
6
7
|
import { SyncBlockError } from '../../common/types';
|
|
7
8
|
import { stringifyError } from '../../utils/errorHandling';
|
|
8
9
|
import { createResourceIdForReference } from '../../utils/resourceId';
|
|
@@ -100,7 +101,8 @@ export const convertToSyncBlockData = (data, resourceId) => {
|
|
|
100
101
|
createdBy: data.createdBy,
|
|
101
102
|
product: data.product,
|
|
102
103
|
resourceId,
|
|
103
|
-
sourceAri: data.sourceAri
|
|
104
|
+
sourceAri: data.sourceAri,
|
|
105
|
+
status: data.status
|
|
104
106
|
};
|
|
105
107
|
};
|
|
106
108
|
export const fetchReferences = async documentAri => {
|
|
@@ -186,7 +188,8 @@ class BlockServiceADFFetchProvider {
|
|
|
186
188
|
blockInstanceId: blockContentResponse.blockInstanceId,
|
|
187
189
|
// this was the node's localId, but has become the resourceId.
|
|
188
190
|
sourceAri: blockContentResponse.sourceAri,
|
|
189
|
-
product: blockContentResponse.product
|
|
191
|
+
product: blockContentResponse.product,
|
|
192
|
+
status: blockContentResponse.status
|
|
190
193
|
},
|
|
191
194
|
resourceId
|
|
192
195
|
};
|
|
@@ -217,7 +220,7 @@ class BlockServiceADFFetchProvider {
|
|
|
217
220
|
references.push({
|
|
218
221
|
...reference,
|
|
219
222
|
hasAccess: true,
|
|
220
|
-
|
|
223
|
+
onSameDocument: this.parentAri === reference.documentAri
|
|
221
224
|
});
|
|
222
225
|
});
|
|
223
226
|
response.errors.forEach(reference => {
|
|
@@ -226,7 +229,7 @@ class BlockServiceADFFetchProvider {
|
|
|
226
229
|
blockAri: reference.blockAri,
|
|
227
230
|
documentAri: reference.documentAri,
|
|
228
231
|
hasAccess: false,
|
|
229
|
-
|
|
232
|
+
onSameDocument: false
|
|
230
233
|
});
|
|
231
234
|
}
|
|
232
235
|
});
|
|
@@ -311,7 +314,8 @@ class BlockServiceADFFetchProvider {
|
|
|
311
314
|
resourceId: blockContentResponse.blockAri,
|
|
312
315
|
blockInstanceId: blockContentResponse.blockInstanceId,
|
|
313
316
|
sourceAri: blockContentResponse.sourceAri,
|
|
314
|
-
product: blockContentResponse.product
|
|
317
|
+
product: blockContentResponse.product,
|
|
318
|
+
status: blockContentResponse.status
|
|
315
319
|
},
|
|
316
320
|
resourceId
|
|
317
321
|
});
|
|
@@ -358,6 +362,37 @@ class BlockServiceADFFetchProvider {
|
|
|
358
362
|
}));
|
|
359
363
|
}
|
|
360
364
|
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Subscribes to real-time updates for a specific block using GraphQL WebSocket subscriptions.
|
|
368
|
+
* @param resourceId - The resource ID of the block to subscribe to
|
|
369
|
+
* @param onUpdate - Callback function invoked when the block is updated
|
|
370
|
+
* @param onError - Optional callback function invoked on subscription errors
|
|
371
|
+
* @returns Unsubscribe function to stop receiving updates
|
|
372
|
+
*/
|
|
373
|
+
subscribeToBlockUpdates(resourceId, onUpdate, onError) {
|
|
374
|
+
const blockAri = generateBlockAriFromReference({
|
|
375
|
+
cloudId: this.cloudId,
|
|
376
|
+
resourceId
|
|
377
|
+
});
|
|
378
|
+
return subscribeToBlockUpdatesWS(blockAri, parsedData => {
|
|
379
|
+
// Convert ParsedBlockSubscriptionData to SyncBlockInstance
|
|
380
|
+
const syncBlockInstance = {
|
|
381
|
+
data: {
|
|
382
|
+
content: parsedData.content,
|
|
383
|
+
resourceId: parsedData.blockAri,
|
|
384
|
+
blockInstanceId: parsedData.blockInstanceId,
|
|
385
|
+
sourceAri: parsedData.sourceAri,
|
|
386
|
+
product: parsedData.product,
|
|
387
|
+
createdAt: parsedData.createdAt,
|
|
388
|
+
createdBy: parsedData.createdBy,
|
|
389
|
+
status: parsedData.status
|
|
390
|
+
},
|
|
391
|
+
resourceId: parsedData.resourceId
|
|
392
|
+
};
|
|
393
|
+
onUpdate(syncBlockInstance);
|
|
394
|
+
}, onError);
|
|
395
|
+
}
|
|
361
396
|
}
|
|
362
397
|
/**
|
|
363
398
|
* ADFWriteProvider implementation that writes synced block data to Block Service API
|
|
@@ -4,6 +4,7 @@ import { fg } from '@atlaskit/platform-feature-flags';
|
|
|
4
4
|
import { getProductFromSourceAri } from '../clients/block-service/ari';
|
|
5
5
|
import { getPageIdAndTypeFromConfluencePageAri } from '../clients/confluence/ari';
|
|
6
6
|
import { fetchConfluencePageInfo } from '../clients/confluence/sourceInfo';
|
|
7
|
+
import { fetchJiraWorkItemInfo } from '../clients/jira/sourceInfo';
|
|
7
8
|
import { SyncBlockError } from '../common/types';
|
|
8
9
|
import { SyncBlockDataProvider } from './types';
|
|
9
10
|
export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
@@ -204,7 +205,7 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
|
204
205
|
}
|
|
205
206
|
return {
|
|
206
207
|
...sourceInfo,
|
|
207
|
-
|
|
208
|
+
onSameDocument: ((_this$writeProvider3 = this.writeProvider) === null || _this$writeProvider3 === void 0 ? void 0 : _this$writeProvider3.parentAri) === ari,
|
|
208
209
|
productType: product
|
|
209
210
|
};
|
|
210
211
|
} else {
|
|
@@ -213,7 +214,16 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
|
213
214
|
}
|
|
214
215
|
case 'jira-work-item':
|
|
215
216
|
if (fg('platform_synced_block_dogfooding')) {
|
|
216
|
-
|
|
217
|
+
var _this$writeProvider4;
|
|
218
|
+
const sourceInfo = await fetchJiraWorkItemInfo(ari, hasAccess);
|
|
219
|
+
if (!sourceInfo) {
|
|
220
|
+
return Promise.resolve(undefined);
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
...sourceInfo,
|
|
224
|
+
onSameDocument: ((_this$writeProvider4 = this.writeProvider) === null || _this$writeProvider4 === void 0 ? void 0 : _this$writeProvider4.parentAri) === ari,
|
|
225
|
+
productType: product
|
|
226
|
+
};
|
|
217
227
|
}
|
|
218
228
|
return Promise.reject(new Error('Jira work item source product not supported'));
|
|
219
229
|
default:
|
|
@@ -282,6 +292,20 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
|
282
292
|
}
|
|
283
293
|
return this.fetchProvider.fetchReferences(isSource ? this.generateResourceIdForReference(resourceId) : resourceId);
|
|
284
294
|
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Subscribes to real-time updates for a specific block.
|
|
298
|
+
* @param resourceId - The resource ID of the block to subscribe to
|
|
299
|
+
* @param onUpdate - Callback function invoked when the block is updated
|
|
300
|
+
* @param onError - Optional callback function invoked on subscription errors
|
|
301
|
+
* @returns Unsubscribe function to stop receiving updates, or undefined if not supported
|
|
302
|
+
*/
|
|
303
|
+
subscribeToBlockUpdates(resourceId, onUpdate, onError) {
|
|
304
|
+
if (this.fetchProvider.subscribeToBlockUpdates) {
|
|
305
|
+
return this.fetchProvider.subscribeToBlockUpdates(resourceId, onUpdate, onError);
|
|
306
|
+
}
|
|
307
|
+
return undefined;
|
|
308
|
+
}
|
|
285
309
|
}
|
|
286
310
|
const createSyncedBlockProvider = ({
|
|
287
311
|
fetchProvider,
|