@atlaskit/editor-synced-block-provider 2.10.1 → 2.10.3
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 +17 -0
- package/dist/cjs/{providers → clients}/block-service/ari.js +2 -2
- package/dist/cjs/{utils → clients/confluence}/ari.js +6 -6
- package/dist/cjs/{utils → clients/confluence}/sourceInfo.js +7 -7
- package/dist/cjs/clients/confluence/utils.js +9 -0
- package/dist/cjs/hooks/useFetchSyncBlockData.js +5 -6
- package/dist/cjs/hooks/useFetchSyncBlockTitle.js +1 -1
- package/dist/cjs/hooks/useHandleContentChanges.js +1 -1
- package/dist/cjs/index.js +27 -14
- package/dist/cjs/providers/block-service/blockServiceAPI.js +4 -4
- package/dist/cjs/providers/confluence/confluenceContentAPI.js +33 -26
- package/dist/cjs/providers/syncBlockProvider.js +38 -3
- package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +86 -19
- package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +52 -10
- package/dist/cjs/store-manager/syncBlockStoreManager.js +14 -157
- package/dist/cjs/utils/utils.js +8 -4
- package/dist/es2019/{providers → clients}/block-service/ari.js +1 -1
- package/dist/es2019/{utils → clients/confluence}/ari.js +5 -5
- package/dist/es2019/{utils → clients/confluence}/sourceInfo.js +5 -5
- package/dist/es2019/clients/confluence/utils.js +3 -0
- package/dist/es2019/hooks/useFetchSyncBlockData.js +5 -6
- package/dist/es2019/hooks/useFetchSyncBlockTitle.js +1 -1
- package/dist/es2019/hooks/useHandleContentChanges.js +1 -1
- package/dist/es2019/index.js +14 -4
- package/dist/es2019/providers/block-service/blockServiceAPI.js +4 -4
- package/dist/es2019/providers/confluence/confluenceContentAPI.js +19 -13
- package/dist/es2019/providers/syncBlockProvider.js +38 -3
- package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +75 -10
- package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +39 -1
- package/dist/es2019/store-manager/syncBlockStoreManager.js +12 -117
- package/dist/es2019/utils/utils.js +3 -3
- package/dist/esm/{providers → clients}/block-service/ari.js +1 -1
- package/dist/esm/{utils → clients/confluence}/ari.js +5 -5
- package/dist/esm/{utils → clients/confluence}/sourceInfo.js +7 -7
- package/dist/esm/clients/confluence/utils.js +3 -0
- package/dist/esm/hooks/useFetchSyncBlockData.js +5 -6
- package/dist/esm/hooks/useFetchSyncBlockTitle.js +1 -1
- package/dist/esm/hooks/useHandleContentChanges.js +1 -1
- package/dist/esm/index.js +14 -4
- package/dist/esm/providers/block-service/blockServiceAPI.js +4 -4
- package/dist/esm/providers/confluence/confluenceContentAPI.js +33 -26
- package/dist/esm/providers/syncBlockProvider.js +38 -3
- package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +87 -19
- package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +52 -10
- package/dist/esm/store-manager/syncBlockStoreManager.js +14 -157
- package/dist/esm/utils/utils.js +7 -3
- package/dist/types/{providers → clients}/block-service/ari.d.ts +1 -1
- package/dist/types/{utils → clients/block-service}/blockService.d.ts +3 -3
- package/dist/types/clients/confluence/ari.d.ts +9 -0
- package/dist/types/{utils → clients/confluence}/contentProperty.d.ts +1 -1
- package/dist/types/clients/confluence/sourceInfo.d.ts +2 -0
- package/dist/types/clients/confluence/utils.d.ts +2 -0
- package/dist/types/common/types.d.ts +3 -1
- package/dist/types/index.d.ts +5 -4
- package/dist/types/providers/syncBlockProvider.d.ts +10 -1
- package/dist/types/providers/types.d.ts +20 -8
- package/dist/types/store-manager/referenceSyncBlockStoreManager.d.ts +6 -0
- package/dist/types/store-manager/sourceSyncBlockStoreManager.d.ts +17 -1
- package/dist/types/store-manager/syncBlockStoreManager.d.ts +4 -59
- package/dist/types/utils/utils.d.ts +1 -2
- package/dist/types-ts4.5/{providers → clients}/block-service/ari.d.ts +1 -1
- package/dist/types-ts4.5/{utils → clients/block-service}/blockService.d.ts +3 -3
- package/dist/types-ts4.5/clients/confluence/ari.d.ts +9 -0
- package/dist/types-ts4.5/{utils → clients/confluence}/contentProperty.d.ts +1 -1
- package/dist/types-ts4.5/clients/confluence/sourceInfo.d.ts +2 -0
- package/dist/types-ts4.5/clients/confluence/utils.d.ts +2 -0
- package/dist/types-ts4.5/common/types.d.ts +3 -1
- package/dist/types-ts4.5/index.d.ts +5 -4
- package/dist/types-ts4.5/providers/syncBlockProvider.d.ts +10 -1
- package/dist/types-ts4.5/providers/types.d.ts +20 -8
- package/dist/types-ts4.5/store-manager/referenceSyncBlockStoreManager.d.ts +6 -0
- package/dist/types-ts4.5/store-manager/sourceSyncBlockStoreManager.d.ts +17 -1
- package/dist/types-ts4.5/store-manager/syncBlockStoreManager.d.ts +4 -59
- package/dist/types-ts4.5/utils/utils.d.ts +1 -2
- package/package.json +5 -5
- package/dist/types/utils/ari.d.ts +0 -9
- package/dist/types/utils/sourceInfo.d.ts +0 -2
- package/dist/types-ts4.5/utils/ari.d.ts +0 -9
- package/dist/types-ts4.5/utils/sourceInfo.d.ts +0 -2
- /package/dist/cjs/{utils → clients/block-service}/blockService.js +0 -0
- /package/dist/cjs/{utils → clients/confluence}/contentProperty.js +0 -0
- /package/dist/es2019/{utils → clients/block-service}/blockService.js +0 -0
- /package/dist/es2019/{utils → clients/confluence}/contentProperty.js +0 -0
- /package/dist/esm/{utils → clients/block-service}/blockService.js +0 -0
- /package/dist/esm/{utils → clients/confluence}/contentProperty.js +0 -0
|
@@ -2,7 +2,7 @@ import { useEffect, useState } from 'react';
|
|
|
2
2
|
export const useFetchSyncBlockTitle = (manager, syncBlockNode) => {
|
|
3
3
|
const [sourceTitle, setSourceTitle] = useState(undefined);
|
|
4
4
|
useEffect(() => {
|
|
5
|
-
const unsubscribe = manager.
|
|
5
|
+
const unsubscribe = manager.referenceManager.subscribeToSourceTitle(syncBlockNode, title => {
|
|
6
6
|
setSourceTitle(title);
|
|
7
7
|
});
|
|
8
8
|
return () => {
|
|
@@ -2,7 +2,7 @@ import { useEffect } from 'react';
|
|
|
2
2
|
export const useHandleContentChanges = (manager, syncBlockNode) => {
|
|
3
3
|
useEffect(() => {
|
|
4
4
|
try {
|
|
5
|
-
manager.updateSyncBlockData(syncBlockNode);
|
|
5
|
+
manager.sourceManager.updateSyncBlockData(syncBlockNode);
|
|
6
6
|
} catch {
|
|
7
7
|
//TODO: EDITOR-1921 - add error analytics
|
|
8
8
|
}
|
package/dist/es2019/index.js
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
/* eslint-disable @atlaskit/editor/no-re-export */
|
|
2
2
|
|
|
3
|
+
// common
|
|
3
4
|
export { rebaseTransaction } from './common/rebase-transaction';
|
|
4
5
|
export { SyncBlockError } from './common/types';
|
|
6
|
+
// hooks
|
|
5
7
|
export { useFetchSyncBlockData } from './hooks/useFetchSyncBlockData';
|
|
6
8
|
export { useFetchSyncBlockTitle } from './hooks/useFetchSyncBlockTitle';
|
|
7
9
|
export { useHandleContentChanges } from './hooks/useHandleContentChanges';
|
|
8
|
-
|
|
10
|
+
|
|
11
|
+
// clients
|
|
12
|
+
export { blockResourceIdFromSourceAndLocalId, getLocalIdFromBlockResourceId } from './clients/block-service/ari';
|
|
13
|
+
export { getConfluencePageAri, getLocalIdFromConfluencePageAri, getPageARIFromContentPropertyResourceId, getPageIdAndTypeFromConfluencePageAri, resourceIdFromConfluencePageSourceIdAndLocalId } from './clients/confluence/ari';
|
|
14
|
+
|
|
15
|
+
// providers
|
|
9
16
|
export { useMemoizedBlockServiceAPIProviders } from './providers/block-service/blockServiceAPI';
|
|
10
17
|
export { createContentAPIProvidersWithDefaultKey, useMemoizedContentAPIProviders } from './providers/confluence/confluenceContentAPI';
|
|
18
|
+
export { fetchConfluenceSourceInfo } from './clients/confluence/sourceInfo';
|
|
11
19
|
export { SyncBlockProvider as SyncedBlockProvider, useMemoizedSyncedBlockProvider } from './providers/syncBlockProvider';
|
|
20
|
+
// store managers
|
|
12
21
|
export { ReferenceSyncBlockStoreManager } from './store-manager/referenceSyncBlockStoreManager';
|
|
13
22
|
export { SyncBlockStoreManager } from './store-manager/syncBlockStoreManager';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export { resolveSyncBlockInstance } from './utils/resolveSyncBlockInstance';
|
|
23
|
+
|
|
24
|
+
// utils
|
|
25
|
+
export { resolveSyncBlockInstance } from './utils/resolveSyncBlockInstance';
|
|
26
|
+
export { createSyncBlockNode, convertSyncBlockPMNodeToSyncBlockData, convertSyncBlockJSONNodeToSyncBlockNode, convertPMNodesToSyncBlockNodes } from './utils/utils';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
+
import { blockResourceIdFromSourceAndLocalId, getLocalIdFromBlockResourceId } from '../../clients/block-service/ari';
|
|
3
|
+
import { BlockError, createSyncedBlock, deleteSyncedBlock, getSyncedBlockContent, updateSyncedBlock } from '../../clients/block-service/blockService';
|
|
2
4
|
import { SyncBlockError } from '../../common/types';
|
|
3
|
-
import { BlockError, createSyncedBlock, deleteSyncedBlock, getSyncedBlockContent, updateSyncedBlock } from '../../utils/blockService';
|
|
4
5
|
import { stringifyError } from '../../utils/errorHandling';
|
|
5
|
-
import { blockResourceIdFromSourceAndLocalId, getLocalIdFromResourceId } from './ari';
|
|
6
6
|
const mapBlockError = error => {
|
|
7
7
|
switch (error.status) {
|
|
8
8
|
case 403:
|
|
@@ -20,7 +20,7 @@ class BlockServiceADFFetchProvider {
|
|
|
20
20
|
// resourceId is the ARI of the block. E.G ari:cloud:blocks:site-123:synced-block/uuid-456
|
|
21
21
|
// in the content API provider, this was the concatenation of the source document's ARI and the local ID. E.G ari:cloud:confluence:site-123:page/pageId/uuid-456
|
|
22
22
|
async fetchData(resourceId) {
|
|
23
|
-
const localId =
|
|
23
|
+
const localId = getLocalIdFromBlockResourceId(resourceId);
|
|
24
24
|
try {
|
|
25
25
|
const blockContentResponse = await getSyncedBlockContent({
|
|
26
26
|
blockAri: resourceId
|
|
@@ -59,7 +59,7 @@ class BlockServiceADFFetchProvider {
|
|
|
59
59
|
retrieveSourceInfoFetchData(resourceId, pageARI) {
|
|
60
60
|
let sourceLocalId;
|
|
61
61
|
try {
|
|
62
|
-
sourceLocalId =
|
|
62
|
+
sourceLocalId = getLocalIdFromBlockResourceId(resourceId);
|
|
63
63
|
} catch (error) {
|
|
64
64
|
// EDITOR-1921: log analytic here, safe to continue
|
|
65
65
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
|
+
import { getConfluencePageAri, getPageARIFromContentPropertyResourceId, getLocalIdFromConfluencePageAri, getPageIdAndTypeFromConfluencePageAri, resourceIdFromConfluencePageSourceIdAndLocalId } from '../../clients/confluence/ari';
|
|
4
|
+
import { getContentProperty, createContentProperty, updateContentProperty, deleteContentProperty } from '../../clients/confluence/contentProperty';
|
|
5
|
+
import { isBlogPageType } from '../../clients/confluence/utils';
|
|
3
6
|
import { SyncBlockError } from '../../common/types';
|
|
4
|
-
import { getLocalIdFromAri, getPageARIFromResourceId, getPageIdAndTypeFromAri, resourceIdFromSourceAndLocalId } from '../../utils/ari';
|
|
5
|
-
import { getContentProperty, createContentProperty, updateContentProperty, deleteContentProperty } from '../../utils/contentProperty';
|
|
6
7
|
import { stringifyError } from '../../utils/errorHandling';
|
|
7
|
-
import { isBlogPageType } from '../../utils/utils';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Configuration for Content API providers
|
|
@@ -51,8 +51,8 @@ class ConfluenceADFFetchProvider {
|
|
|
51
51
|
const {
|
|
52
52
|
id: pageId,
|
|
53
53
|
type: pageType
|
|
54
|
-
} =
|
|
55
|
-
const localId =
|
|
54
|
+
} = getPageIdAndTypeFromConfluencePageAri(resourceId);
|
|
55
|
+
const localId = getLocalIdFromConfluencePageAri(resourceId);
|
|
56
56
|
try {
|
|
57
57
|
const key = getContentPropertyKey(this.config.contentPropertyKey, localId);
|
|
58
58
|
const options = {
|
|
@@ -99,10 +99,10 @@ class ConfluenceADFFetchProvider {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
retrieveSourceInfoFetchData(resourceId) {
|
|
102
|
-
const pageARI =
|
|
102
|
+
const pageARI = getPageARIFromContentPropertyResourceId(resourceId);
|
|
103
103
|
let sourceLocalId;
|
|
104
104
|
try {
|
|
105
|
-
sourceLocalId =
|
|
105
|
+
sourceLocalId = getLocalIdFromConfluencePageAri(resourceId);
|
|
106
106
|
} catch (error) {
|
|
107
107
|
// EDITOR-1921: log analytic here, safe to continue
|
|
108
108
|
}
|
|
@@ -152,7 +152,7 @@ class ConfluenceADFWriteProvider {
|
|
|
152
152
|
resourceId
|
|
153
153
|
} = data;
|
|
154
154
|
try {
|
|
155
|
-
match =
|
|
155
|
+
match = getPageIdAndTypeFromConfluencePageAri(data.resourceId);
|
|
156
156
|
} catch (error) {
|
|
157
157
|
return {
|
|
158
158
|
error: stringifyError(error)
|
|
@@ -164,12 +164,18 @@ class ConfluenceADFWriteProvider {
|
|
|
164
164
|
} = match;
|
|
165
165
|
try {
|
|
166
166
|
// Update existing content property
|
|
167
|
-
const localId =
|
|
167
|
+
const localId = getLocalIdFromConfluencePageAri(resourceId);
|
|
168
168
|
const key = getContentPropertyKey(this.config.contentPropertyKey, localId);
|
|
169
|
+
const sourceAri = getConfluencePageAri(pageId, this.config.cloudId, pageType);
|
|
170
|
+
const syncBlockDataWithSourceDocumentAri = {
|
|
171
|
+
...data,
|
|
172
|
+
product: 'confluence-page',
|
|
173
|
+
sourceAri
|
|
174
|
+
};
|
|
169
175
|
const options = {
|
|
170
176
|
pageId,
|
|
171
177
|
key,
|
|
172
|
-
value:
|
|
178
|
+
value: syncBlockDataWithSourceDocumentAri,
|
|
173
179
|
cloudId: this.config.cloudId,
|
|
174
180
|
pageType
|
|
175
181
|
};
|
|
@@ -203,7 +209,7 @@ class ConfluenceADFWriteProvider {
|
|
|
203
209
|
async deleteData(resourceId) {
|
|
204
210
|
let deletePayload, deleteResult, match;
|
|
205
211
|
try {
|
|
206
|
-
match =
|
|
212
|
+
match = getPageIdAndTypeFromConfluencePageAri(resourceId);
|
|
207
213
|
} catch (error) {
|
|
208
214
|
return {
|
|
209
215
|
resourceId,
|
|
@@ -216,7 +222,7 @@ class ConfluenceADFWriteProvider {
|
|
|
216
222
|
type: pageType
|
|
217
223
|
} = match;
|
|
218
224
|
try {
|
|
219
|
-
const localId =
|
|
225
|
+
const localId = getLocalIdFromConfluencePageAri(resourceId);
|
|
220
226
|
const key = getContentPropertyKey(this.config.contentPropertyKey, localId);
|
|
221
227
|
const options = {
|
|
222
228
|
pageId,
|
|
@@ -241,7 +247,7 @@ class ConfluenceADFWriteProvider {
|
|
|
241
247
|
};
|
|
242
248
|
}
|
|
243
249
|
generateResourceId(sourceId, localId) {
|
|
244
|
-
return
|
|
250
|
+
return resourceIdFromConfluencePageSourceIdAndLocalId(sourceId, localId);
|
|
245
251
|
}
|
|
246
252
|
}
|
|
247
253
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
|
+
import { getPageIdAndTypeFromConfluencePageAri } from '../clients/confluence/ari';
|
|
4
|
+
import { fetchConfluenceSourceInfo } from '../clients/confluence/sourceInfo';
|
|
3
5
|
import { SyncBlockError } from '../common/types';
|
|
4
6
|
import { SyncBlockDataProvider } from '../providers/types';
|
|
5
|
-
import { fetchSourceInfo } from '../utils/sourceInfo';
|
|
6
7
|
export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
7
8
|
// the source document ARI; that the source sync block is on.
|
|
8
9
|
|
|
@@ -137,7 +138,7 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
|
137
138
|
* @returns The source info
|
|
138
139
|
*/
|
|
139
140
|
retrieveSyncBlockSourceInfo(node) {
|
|
140
|
-
// with content API, this is the concatenation of the page ARI and the block's localId.
|
|
141
|
+
// with content API, this is the concatenation of the page ARI and the block's localId.
|
|
141
142
|
// with block service, this is the ARI of the block.
|
|
142
143
|
// this can be cleaned up from the specific providers and placed here after platform_synced_blocks_block_service_provider
|
|
143
144
|
const {
|
|
@@ -154,7 +155,10 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
|
154
155
|
return Promise.reject(error);
|
|
155
156
|
}
|
|
156
157
|
}
|
|
157
|
-
|
|
158
|
+
|
|
159
|
+
// TODO: EDITOR-3312 - based on the source sync block product,
|
|
160
|
+
// execute fetchConfluenceSourceInfo or fetchJiraItemSourceInfo or similar...
|
|
161
|
+
return pageARI ? fetchConfluenceSourceInfo(pageARI, sourceLocalId) : Promise.resolve(undefined);
|
|
158
162
|
}
|
|
159
163
|
generateResourceId(sourceId, localId) {
|
|
160
164
|
return this.writeProvider.generateResourceId(sourceId, localId);
|
|
@@ -168,6 +172,37 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
|
168
172
|
getSyncedBlockRendererProviderOptions() {
|
|
169
173
|
return this.providerOptions;
|
|
170
174
|
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Retrieve the parent info for the sync block
|
|
178
|
+
*
|
|
179
|
+
* @param resourceId
|
|
180
|
+
* @param syncBlockInstance
|
|
181
|
+
*
|
|
182
|
+
* @returns The parent info for the sync block
|
|
183
|
+
*/
|
|
184
|
+
retrieveSyncBlockParentInfo(syncBlockInstance) {
|
|
185
|
+
if (!syncBlockInstance || !syncBlockInstance.data) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
const {
|
|
189
|
+
sourceAri,
|
|
190
|
+
product
|
|
191
|
+
} = syncBlockInstance.data;
|
|
192
|
+
if (!sourceAri || !product) {
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// TODO: EDITOR-3312 - based on the source sync block product,
|
|
197
|
+
// execute getPageIdAndTypeFromConfluencePageAri or getJiraItemIdAndTypeFromJiraItemAri or similar...
|
|
198
|
+
const {
|
|
199
|
+
id: contentId
|
|
200
|
+
} = getPageIdAndTypeFromConfluencePageAri(sourceAri);
|
|
201
|
+
return {
|
|
202
|
+
contentId,
|
|
203
|
+
contentProduct: product
|
|
204
|
+
};
|
|
205
|
+
}
|
|
171
206
|
}
|
|
172
207
|
export const useMemoizedSyncedBlockProvider = (fetchProvider, writeProvider, sourceId, providerOptions) => {
|
|
173
208
|
return useMemo(() => {
|
|
@@ -3,6 +3,12 @@ import { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
|
|
|
3
3
|
import { SyncBlockError } from '../common/types';
|
|
4
4
|
import { resolveSyncBlockInstance } from '../utils/resolveSyncBlockInstance';
|
|
5
5
|
import { createSyncBlockNode } from '../utils/utils';
|
|
6
|
+
|
|
7
|
+
// A store manager responsible for the lifecycle and state management of reference sync blocks in an editor instance.
|
|
8
|
+
// Designed to manage local in-memory state and synchronize with an external data provider.
|
|
9
|
+
// Supports fetch, cache, and subscription for sync block data.
|
|
10
|
+
// Handles fetching source URL and title for sync blocks.
|
|
11
|
+
// Can be used in both editor and renderer contexts.
|
|
6
12
|
export class ReferenceSyncBlockStoreManager {
|
|
7
13
|
constructor(dataProvider) {
|
|
8
14
|
_defineProperty(this, "isRefreshingSubscriptions", false);
|
|
@@ -44,6 +50,8 @@ export class ReferenceSyncBlockStoreManager {
|
|
|
44
50
|
return;
|
|
45
51
|
}
|
|
46
52
|
|
|
53
|
+
// TODO: EDITOR-3312 - retrieve the source info based on the source sync block product
|
|
54
|
+
|
|
47
55
|
// if the sync block is a reference block, we need to fetch the URL to the source
|
|
48
56
|
// we could optimise this further by checking if the sync block is on the same page as the source
|
|
49
57
|
if (!this.syncBlockURLRequests.get(resourceId)) {
|
|
@@ -66,7 +74,16 @@ export class ReferenceSyncBlockStoreManager {
|
|
|
66
74
|
});
|
|
67
75
|
}
|
|
68
76
|
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Fetch sync block data for a given array of sync block nodes.
|
|
80
|
+
* @param syncBlockNodes - The array of sync block nodes to fetch data for
|
|
81
|
+
* @returns The fetched sync block data results
|
|
82
|
+
*/
|
|
69
83
|
async fetchSyncBlocksData(syncBlockNodes) {
|
|
84
|
+
if (syncBlockNodes.length === 0) {
|
|
85
|
+
return Promise.resolve([]);
|
|
86
|
+
}
|
|
70
87
|
if (!this.dataProvider) {
|
|
71
88
|
throw new Error('Data provider not set');
|
|
72
89
|
}
|
|
@@ -235,26 +252,74 @@ export class ReferenceSyncBlockStoreManager {
|
|
|
235
252
|
return undefined;
|
|
236
253
|
}
|
|
237
254
|
const {
|
|
238
|
-
parentDataProviders
|
|
255
|
+
parentDataProviders,
|
|
256
|
+
providerCreator
|
|
239
257
|
} = this.dataProvider.getSyncedBlockRendererProviderOptions();
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
// So we need to keep the reference to the Provider Factory so we can then set media & emoji providers later
|
|
244
|
-
this.providerFactories.set(resourceId, ProviderFactory.create({
|
|
245
|
-
emojiProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.emojiProvider,
|
|
246
|
-
mediaProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.mediaProvider,
|
|
258
|
+
let providerFactory = this.providerFactories.get(resourceId);
|
|
259
|
+
if (!providerFactory) {
|
|
260
|
+
providerFactory = ProviderFactory.create({
|
|
247
261
|
mentionProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.mentionProvider,
|
|
248
262
|
profilecardProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.profilecardProvider,
|
|
249
263
|
taskDecisionProvider: parentDataProviders === null || parentDataProviders === void 0 ? void 0 : parentDataProviders.taskDecisionProvider
|
|
250
|
-
})
|
|
264
|
+
});
|
|
265
|
+
this.providerFactories.set(resourceId, providerFactory);
|
|
266
|
+
}
|
|
267
|
+
if (providerCreator) {
|
|
268
|
+
this.retrieveDynamicProviders(resourceId, providerFactory, providerCreator);
|
|
269
|
+
}
|
|
270
|
+
return providerFactory;
|
|
271
|
+
}
|
|
272
|
+
retrieveDynamicProviders(resourceId, providerFactory, providerCreator) {
|
|
273
|
+
if (!this.dataProvider) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const hasMediaProvider = providerFactory.hasProvider('mediaProvider');
|
|
277
|
+
const hasEmojiProvider = providerFactory.hasProvider('emojiProvider');
|
|
278
|
+
if (hasMediaProvider && hasEmojiProvider) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const parentInfo = this.dataProvider.retrieveSyncBlockParentInfo(this.syncBlockCache.get(resourceId));
|
|
282
|
+
if (!parentInfo) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const {
|
|
286
|
+
contentId,
|
|
287
|
+
contentProduct
|
|
288
|
+
} = parentInfo;
|
|
289
|
+
if (!hasMediaProvider) {
|
|
290
|
+
if (providerCreator.createMediaProvider && contentId && contentProduct) {
|
|
291
|
+
const mediaProvider = providerCreator.createMediaProvider({
|
|
292
|
+
contentProduct,
|
|
293
|
+
contentId
|
|
294
|
+
});
|
|
295
|
+
if (mediaProvider) {
|
|
296
|
+
providerFactory.setProvider('mediaProvider', mediaProvider);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (!hasEmojiProvider) {
|
|
301
|
+
if (providerCreator.createEmojiProvider && contentId && contentProduct) {
|
|
302
|
+
const emojiProvider = providerCreator.createEmojiProvider({
|
|
303
|
+
contentProduct,
|
|
304
|
+
contentId
|
|
305
|
+
});
|
|
306
|
+
if (emojiProvider) {
|
|
307
|
+
providerFactory.setProvider('emojiProvider', emojiProvider);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
251
310
|
}
|
|
252
|
-
return this.providerFactories.get(resourceId);
|
|
253
311
|
}
|
|
254
312
|
destroy() {
|
|
313
|
+
this.dataProvider = undefined;
|
|
255
314
|
this.syncBlockCache.clear();
|
|
256
315
|
this.subscriptions.clear();
|
|
316
|
+
this.titleSubscriptions.clear();
|
|
257
317
|
this.syncBlockURLRequests.clear();
|
|
258
318
|
this.providerFactories.clear();
|
|
319
|
+
this.isRefreshingSubscriptions = false;
|
|
320
|
+
this.providerFactories.forEach(providerFactory => {
|
|
321
|
+
providerFactory.destroy();
|
|
322
|
+
});
|
|
323
|
+
this.providerFactories.clear();
|
|
259
324
|
}
|
|
260
325
|
}
|
|
@@ -3,6 +3,11 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
3
3
|
import uuid from 'uuid';
|
|
4
4
|
import { rebaseTransaction } from '../common/rebase-transaction';
|
|
5
5
|
import { convertSyncBlockPMNodeToSyncBlockData, createBodiedSyncBlockNode } from '../utils/utils';
|
|
6
|
+
// A store manager responsible for the lifecycle and state management of source sync blocks in an editor instance.
|
|
7
|
+
// Designed to manage local in-memory state and synchronize with an external data provider.
|
|
8
|
+
// Supports create, flush, and delete operations for source sync blocks.
|
|
9
|
+
// Handles caching, debouncing updates, and publish/subscribe for local changes.
|
|
10
|
+
// Ensures consistency between local and remote state, and can be used in both editor and renderer contexts.
|
|
6
11
|
export class SourceSyncBlockStoreManager {
|
|
7
12
|
constructor(dataProvider) {
|
|
8
13
|
_defineProperty(this, "setPendingDeletion", (Ids, value) => {
|
|
@@ -14,12 +19,18 @@ export class SourceSyncBlockStoreManager {
|
|
|
14
19
|
this.dataProvider = dataProvider;
|
|
15
20
|
this.syncBlockCache = new Map();
|
|
16
21
|
}
|
|
22
|
+
isSourceBlock(node) {
|
|
23
|
+
return node.type.name === 'bodiedSyncBlock';
|
|
24
|
+
}
|
|
17
25
|
|
|
18
26
|
/**
|
|
19
27
|
* Add/update a sync block node to/from the local cache
|
|
20
28
|
* @param syncBlockNode - The sync block node to update
|
|
21
29
|
*/
|
|
22
30
|
updateSyncBlockData(syncBlockNode) {
|
|
31
|
+
if (!this.isSourceBlock(syncBlockNode)) {
|
|
32
|
+
throw new Error('Invalid sync block node type provided for updateSyncBlockData');
|
|
33
|
+
}
|
|
23
34
|
const {
|
|
24
35
|
localId,
|
|
25
36
|
resourceId
|
|
@@ -37,7 +48,7 @@ export class SourceSyncBlockStoreManager {
|
|
|
37
48
|
*
|
|
38
49
|
* @returns true if saving all nodes successfully, false if fail to save some/all nodes
|
|
39
50
|
*/
|
|
40
|
-
async
|
|
51
|
+
async flush() {
|
|
41
52
|
try {
|
|
42
53
|
if (!this.dataProvider) {
|
|
43
54
|
throw new Error('Data provider not set');
|
|
@@ -73,6 +84,10 @@ export class SourceSyncBlockStoreManager {
|
|
|
73
84
|
registerPendingCreation(resourceId) {
|
|
74
85
|
this.pendingResourceId = resourceId;
|
|
75
86
|
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Register callback function (which inserts node, handles focus etc) to be used later when creation to backend succeed
|
|
90
|
+
*/
|
|
76
91
|
registerCreationCallback(callback) {
|
|
77
92
|
this.creationCallback = callback;
|
|
78
93
|
}
|
|
@@ -88,6 +103,11 @@ export class SourceSyncBlockStoreManager {
|
|
|
88
103
|
this.pendingResourceId = undefined;
|
|
89
104
|
this.creationCallback = undefined;
|
|
90
105
|
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
*
|
|
109
|
+
* @returns true if waiting for the result of saving new bodiedSyncBlock to backend
|
|
110
|
+
*/
|
|
91
111
|
hasPendingCreation() {
|
|
92
112
|
return !!this.pendingResourceId;
|
|
93
113
|
}
|
|
@@ -100,6 +120,10 @@ export class SourceSyncBlockStoreManager {
|
|
|
100
120
|
requireConfirmationBeforeDelete() {
|
|
101
121
|
return !!this.confirmationCallback;
|
|
102
122
|
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @returns attributes for a new bodiedSyncBlock node
|
|
126
|
+
*/
|
|
103
127
|
generateBodiedSyncBlockAttrs() {
|
|
104
128
|
var _this$dataProvider;
|
|
105
129
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
@@ -114,6 +138,11 @@ export class SourceSyncBlockStoreManager {
|
|
|
114
138
|
localId
|
|
115
139
|
};
|
|
116
140
|
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Create a bodiedSyncBlock node with empty content to backend
|
|
144
|
+
* @param attrs attributes Ids of the node
|
|
145
|
+
*/
|
|
117
146
|
createBodiedSyncBlockNode(attrs) {
|
|
118
147
|
try {
|
|
119
148
|
if (!this.dataProvider) {
|
|
@@ -190,4 +219,13 @@ export class SourceSyncBlockStoreManager {
|
|
|
190
219
|
}
|
|
191
220
|
this.confirmationTransaction = rebaseTransaction(this.confirmationTransaction, incomingTr, state);
|
|
192
221
|
}
|
|
222
|
+
destroy() {
|
|
223
|
+
this.syncBlockCache.clear();
|
|
224
|
+
this.confirmationCallback = undefined;
|
|
225
|
+
this.confirmationTransaction = undefined;
|
|
226
|
+
this.pendingResourceId = undefined;
|
|
227
|
+
this.creationCallback = undefined;
|
|
228
|
+
this.dataProvider = undefined;
|
|
229
|
+
this.editorView = undefined;
|
|
230
|
+
}
|
|
193
231
|
}
|
|
@@ -1,131 +1,26 @@
|
|
|
1
|
-
import { convertPMNodeToSyncBlockNode } from '../utils/utils';
|
|
2
1
|
import { ReferenceSyncBlockStoreManager } from './referenceSyncBlockStoreManager';
|
|
3
2
|
import { SourceSyncBlockStoreManager } from './sourceSyncBlockStoreManager';
|
|
4
3
|
|
|
5
|
-
// A store manager responsible for the lifecycle and state management of sync blocks in an editor instance.
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
4
|
+
// A parent store manager responsible for the lifecycle and state management of sync blocks in an editor instance.
|
|
5
|
+
// Contains two child store managers: ReferenceSyncBlockStoreManager and SourceSyncBlockStoreManager.
|
|
6
|
+
// ReferenceSyncBlockStoreManager is responsible for the lifecycle and state management of reference sync blocks in an editor instance.
|
|
7
|
+
// SourceSyncBlockStoreManager is responsible for the lifecycle and state management of source sync blocks in an editor instance.
|
|
8
|
+
// Can be used in both editor and renderer contexts.
|
|
10
9
|
export class SyncBlockStoreManager {
|
|
11
10
|
constructor(dataProvider) {
|
|
12
|
-
|
|
11
|
+
// In future, if reference manager needs to reach to source manager and read it's current in memorey cache
|
|
12
|
+
// we can pass the source manager as a parameter to the reference manager constructor
|
|
13
13
|
this.sourceSyncBlockStoreManager = new SourceSyncBlockStoreManager(dataProvider);
|
|
14
|
+
this.referenceSyncBlockStoreManager = new ReferenceSyncBlockStoreManager(dataProvider);
|
|
14
15
|
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Fetch sync block data for a given array of sync block nodes.
|
|
18
|
-
* @param nodes - The array of sync block nodes to fetch data for
|
|
19
|
-
* @returns The fetched sync block data results
|
|
20
|
-
*/
|
|
21
|
-
fetchSyncBlocksData(nodes) {
|
|
22
|
-
const syncBlockNodes = nodes.map(node => convertPMNodeToSyncBlockNode(node)).filter(node => node !== undefined) || [];
|
|
23
|
-
if (syncBlockNodes.length === 0) {
|
|
24
|
-
return Promise.resolve([]);
|
|
25
|
-
}
|
|
26
|
-
return this.referenceSyncBlockStoreManager.fetchSyncBlocksData(syncBlockNodes);
|
|
27
|
-
}
|
|
28
|
-
getReferenceSyncBlockStoreManager() {
|
|
16
|
+
get referenceManager() {
|
|
29
17
|
return this.referenceSyncBlockStoreManager;
|
|
30
18
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
* Add/update a sync block node to/from the local cache
|
|
34
|
-
* @param syncBlockNode - The sync block node to update
|
|
35
|
-
*/
|
|
36
|
-
updateSyncBlockData(syncBlockNode) {
|
|
37
|
-
if (this.isSourceBlock(syncBlockNode)) {
|
|
38
|
-
return this.sourceSyncBlockStoreManager.updateSyncBlockData(syncBlockNode);
|
|
39
|
-
} else {
|
|
40
|
-
throw new Error('Invalid sync block node type provided for updateSyncBlockData');
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Save content of bodiedSyncBlock nodes in local cache to backend
|
|
46
|
-
*
|
|
47
|
-
* @returns true if saving all nodes successfully, false if fail to save some/all nodes
|
|
48
|
-
*/
|
|
49
|
-
flushBodiedSyncBlocks() {
|
|
50
|
-
// only applicable to source sync block, for now (will be refactored further)
|
|
51
|
-
return this.sourceSyncBlockStoreManager.flushBodiedSyncBlocks();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Get the URL for a sync block.
|
|
56
|
-
* @param resourceId - The resource ID of the sync block to get the URL for
|
|
57
|
-
* @returns
|
|
58
|
-
*/
|
|
59
|
-
getSyncBlockURL(resourceId) {
|
|
60
|
-
// only applicable to reference sync block, for now (will be refactored further)
|
|
61
|
-
return this.referenceSyncBlockStoreManager.getSyncBlockURL(resourceId);
|
|
62
|
-
}
|
|
63
|
-
setEditorView(editorView) {
|
|
64
|
-
this.sourceSyncBlockStoreManager.setEditorView(editorView);
|
|
65
|
-
}
|
|
66
|
-
isSourceBlock(node) {
|
|
67
|
-
return node.type.name === 'bodiedSyncBlock';
|
|
68
|
-
}
|
|
69
|
-
registerConfirmationCallback(callback) {
|
|
70
|
-
// only applicable to source sync block, for now (will be refactored further)
|
|
71
|
-
return this.sourceSyncBlockStoreManager.registerConfirmationCallback(callback);
|
|
72
|
-
}
|
|
73
|
-
requireConfirmationBeforeDelete() {
|
|
74
|
-
// only applicable to source sync block, for now (will be refactored further)
|
|
75
|
-
return this.sourceSyncBlockStoreManager.requireConfirmationBeforeDelete();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Register callback function (which inserts node, handles focus etc) to be used later when creation to backend succeed
|
|
80
|
-
*/
|
|
81
|
-
registerCreationCallback(callback) {
|
|
82
|
-
this.sourceSyncBlockStoreManager.registerCreationCallback(callback);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
*
|
|
87
|
-
* @returns true if waiting for the result of saving new bodiedSyncBlock to backend
|
|
88
|
-
*/
|
|
89
|
-
hasPendingCreation() {
|
|
90
|
-
return this.sourceSyncBlockStoreManager.hasPendingCreation();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* @returns attributes for a new bodiedSyncBlock node
|
|
95
|
-
*/
|
|
96
|
-
generateBodiedSyncBlockAttrs() {
|
|
97
|
-
return this.sourceSyncBlockStoreManager.generateBodiedSyncBlockAttrs();
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Save bodiedSyncBlock with empty content to backend
|
|
102
|
-
* @param attrs attributes Ids of the node
|
|
103
|
-
*/
|
|
104
|
-
createBodiedSyncBlockNode(attrs) {
|
|
105
|
-
// only applicable to source sync block, for now (will be refactored further)
|
|
106
|
-
return this.sourceSyncBlockStoreManager.createBodiedSyncBlockNode(attrs);
|
|
107
|
-
}
|
|
108
|
-
subscribeToSyncBlockData(node, callback) {
|
|
109
|
-
return this.referenceSyncBlockStoreManager.subscribe(node, callback);
|
|
110
|
-
}
|
|
111
|
-
subscribeToSyncBlockSourceTitle(node, callback) {
|
|
112
|
-
return this.referenceSyncBlockStoreManager.subscribeToSourceTitle(node, callback);
|
|
113
|
-
}
|
|
114
|
-
refreshSubscriptions() {
|
|
115
|
-
this.referenceSyncBlockStoreManager.refreshSubscriptions();
|
|
116
|
-
}
|
|
117
|
-
deleteSyncBlocksWithConfirmation(tr, syncBlockIds) {
|
|
118
|
-
// only applicable to source sync block, for now (will be refactored further)
|
|
119
|
-
return this.sourceSyncBlockStoreManager.deleteSyncBlocksWithConfirmation(tr, syncBlockIds);
|
|
120
|
-
}
|
|
121
|
-
rebaseTransaction(incomingTr, state) {
|
|
122
|
-
// only applicable to source sync block, for now (will be refactored further)
|
|
123
|
-
this.sourceSyncBlockStoreManager.rebaseTransaction(incomingTr, state);
|
|
124
|
-
}
|
|
125
|
-
getReferenceSyncBlockProviderFactory(resourceId) {
|
|
126
|
-
return this.referenceSyncBlockStoreManager.getProviderFactory(resourceId);
|
|
19
|
+
get sourceManager() {
|
|
20
|
+
return this.sourceSyncBlockStoreManager;
|
|
127
21
|
}
|
|
128
22
|
destroy() {
|
|
129
23
|
this.referenceSyncBlockStoreManager.destroy();
|
|
24
|
+
this.sourceSyncBlockStoreManager.destroy();
|
|
130
25
|
}
|
|
131
26
|
}
|
|
@@ -5,9 +5,6 @@ export const convertSyncBlockPMNodeToSyncBlockData = node => {
|
|
|
5
5
|
resourceId: node.attrs.resourceId
|
|
6
6
|
};
|
|
7
7
|
};
|
|
8
|
-
export const isBlogPageType = pageType => {
|
|
9
|
-
return pageType === 'blogpost';
|
|
10
|
-
};
|
|
11
8
|
export const createSyncBlockNode = (localId, resourceId) => {
|
|
12
9
|
return {
|
|
13
10
|
type: 'syncBlock',
|
|
@@ -38,4 +35,7 @@ export const convertPMNodeToSyncBlockNode = node => {
|
|
|
38
35
|
return undefined;
|
|
39
36
|
}
|
|
40
37
|
return createSyncBlockNode(node.attrs.localId, node.attrs.resourceId);
|
|
38
|
+
};
|
|
39
|
+
export const convertPMNodesToSyncBlockNodes = nodes => {
|
|
40
|
+
return nodes.map(node => convertPMNodeToSyncBlockNode(node)).filter(node => node !== undefined) || [];
|
|
41
41
|
};
|
|
@@ -19,7 +19,7 @@ export var blockResourceIdFromSourceAndLocalId = function blockResourceIdFromSou
|
|
|
19
19
|
* @param ari - the block ARI. E.G ari:cloud:blocks:cloudId:synced-block/localId
|
|
20
20
|
* @returns the localId of the block node. A randomly generated UUID
|
|
21
21
|
*/
|
|
22
|
-
export var
|
|
22
|
+
export var getLocalIdFromBlockResourceId = function getLocalIdFromBlockResourceId(ari) {
|
|
23
23
|
var match = ari.match(/ari:cloud:blocks:[^:]+:synced-block\/([a-zA-Z0-9-]+)/);
|
|
24
24
|
if (match !== null && match !== void 0 && match[1]) {
|
|
25
25
|
return match[1];
|