@atlaskit/editor-synced-block-provider 2.15.1 → 2.15.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 +16 -0
- package/dist/cjs/clients/block-service/blockService.js +42 -1
- package/dist/cjs/providers/block-service/blockServiceAPI.js +62 -3
- package/dist/cjs/providers/confluence/confluenceContentAPI.js +7 -0
- package/dist/cjs/providers/syncBlockProvider.js +5 -0
- package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +92 -0
- package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +27 -13
- package/dist/cjs/utils/errorHandling.js +4 -1
- package/dist/es2019/clients/block-service/blockService.js +19 -0
- package/dist/es2019/providers/block-service/blockServiceAPI.js +34 -1
- package/dist/es2019/providers/confluence/confluenceContentAPI.js +5 -0
- package/dist/es2019/providers/syncBlockProvider.js +3 -0
- package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +59 -1
- package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +18 -4
- package/dist/es2019/utils/errorHandling.js +1 -0
- package/dist/esm/clients/block-service/blockService.js +41 -0
- package/dist/esm/providers/block-service/blockServiceAPI.js +63 -4
- package/dist/esm/providers/confluence/confluenceContentAPI.js +7 -0
- package/dist/esm/providers/syncBlockProvider.js +5 -0
- package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +93 -1
- package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +27 -12
- package/dist/esm/utils/errorHandling.js +3 -0
- package/dist/types/clients/block-service/blockService.d.ts +16 -4
- package/dist/types/providers/block-service/blockServiceAPI.d.ts +3 -2
- package/dist/types/providers/confluence/confluenceContentAPI.d.ts +3 -2
- package/dist/types/providers/syncBlockProvider.d.ts +3 -2
- package/dist/types/providers/types.d.ts +13 -1
- package/dist/types/store-manager/referenceSyncBlockStoreManager.d.ts +7 -0
- package/dist/types/store-manager/sourceSyncBlockStoreManager.d.ts +1 -1
- package/dist/types/utils/errorHandling.d.ts +1 -0
- package/dist/types-ts4.5/clients/block-service/blockService.d.ts +16 -4
- package/dist/types-ts4.5/providers/block-service/blockServiceAPI.d.ts +3 -2
- package/dist/types-ts4.5/providers/confluence/confluenceContentAPI.d.ts +3 -2
- package/dist/types-ts4.5/providers/syncBlockProvider.d.ts +3 -2
- package/dist/types-ts4.5/providers/types.d.ts +13 -1
- package/dist/types-ts4.5/store-manager/referenceSyncBlockStoreManager.d.ts +7 -0
- package/dist/types-ts4.5/store-manager/sourceSyncBlockStoreManager.d.ts +1 -1
- package/dist/types-ts4.5/utils/errorHandling.d.ts +1 -0
- package/package.json +2 -3
|
@@ -2,6 +2,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
2
2
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
3
3
|
import uuid from 'uuid';
|
|
4
4
|
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
5
|
+
import { SyncBlockError } from '../common/types';
|
|
5
6
|
import { updateErrorPayload, createErrorPayload, deleteErrorPayload, updateCacheErrorPayload } from '../utils/errorHandling';
|
|
6
7
|
import { convertSyncBlockPMNodeToSyncBlockData } from '../utils/utils';
|
|
7
8
|
// A store manager responsible for the lifecycle and state management of source sync blocks in an editor instance.
|
|
@@ -42,7 +43,10 @@ export class SourceSyncBlockStoreManager {
|
|
|
42
43
|
throw new Error('Local ID or resource ID is not set');
|
|
43
44
|
}
|
|
44
45
|
const syncBlockData = convertSyncBlockPMNodeToSyncBlockData(syncBlockNode);
|
|
45
|
-
this.syncBlockCache.set(resourceId,
|
|
46
|
+
this.syncBlockCache.set(resourceId, {
|
|
47
|
+
...syncBlockData,
|
|
48
|
+
isDirty: true
|
|
49
|
+
});
|
|
46
50
|
return true;
|
|
47
51
|
} catch (error) {
|
|
48
52
|
var _this$fireAnalyticsEv;
|
|
@@ -68,7 +72,8 @@ export class SourceSyncBlockStoreManager {
|
|
|
68
72
|
const bodiedSyncBlockData = [];
|
|
69
73
|
Array.from(this.syncBlockCache.values()).forEach(syncBlockData => {
|
|
70
74
|
// Don't flush nodes that are waiting to be deleted to avoid nodes being re-created
|
|
71
|
-
|
|
75
|
+
// Don't flush nodes that haven't been updated since we last flushed
|
|
76
|
+
if (!syncBlockData.pendingDeletion && syncBlockData.isDirty) {
|
|
72
77
|
bodiedSyncBlockNodes.push({
|
|
73
78
|
type: 'bodiedSyncBlock',
|
|
74
79
|
attrs: {
|
|
@@ -83,10 +88,19 @@ export class SourceSyncBlockStoreManager {
|
|
|
83
88
|
return Promise.resolve(true);
|
|
84
89
|
}
|
|
85
90
|
const writeResults = await this.dataProvider.writeNodesData(bodiedSyncBlockNodes, bodiedSyncBlockData);
|
|
86
|
-
|
|
91
|
+
writeResults.forEach(result => {
|
|
92
|
+
// set isDirty to false on write success and unrecoverable errors like not found
|
|
93
|
+
if (result.resourceId && (result.error === SyncBlockError.NotFound || !result.error)) {
|
|
94
|
+
const cachedData = this.syncBlockCache.get(result.resourceId);
|
|
95
|
+
if (cachedData) {
|
|
96
|
+
cachedData.isDirty = false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
if (writeResults.every(result => result.resourceId && !result.error)) {
|
|
87
101
|
return true;
|
|
88
102
|
} else {
|
|
89
|
-
writeResults.filter(result => result.resourceId
|
|
103
|
+
writeResults.filter(result => !result.resourceId || result.error).forEach(result => {
|
|
90
104
|
var _this$fireAnalyticsEv2;
|
|
91
105
|
(_this$fireAnalyticsEv2 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv2 === void 0 ? void 0 : _this$fireAnalyticsEv2.call(this, updateErrorPayload(result.error || 'Failed to write data'));
|
|
92
106
|
});
|
|
@@ -18,6 +18,7 @@ export const getErrorPayload = (actionSubjectId, error) => ({
|
|
|
18
18
|
export const fetchErrorPayload = error => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_FETCH, error);
|
|
19
19
|
export const getSourceInfoErrorPayload = error => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_GET_SOURCE_INFO, error);
|
|
20
20
|
export const updateErrorPayload = error => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_UPDATE, error);
|
|
21
|
+
export const updateReferenceErrorPayload = error => getErrorPayload(ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_UPDATE, error);
|
|
21
22
|
export const createErrorPayload = error => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_CREATE, error);
|
|
22
23
|
export const deleteErrorPayload = error => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_DELETE, error);
|
|
23
24
|
export const updateCacheErrorPayload = error => getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_UPDATE_CACHE, error);
|
|
@@ -240,4 +240,45 @@ export var createSyncedBlock = /*#__PURE__*/function () {
|
|
|
240
240
|
return function createSyncedBlock(_x5) {
|
|
241
241
|
return _ref9.apply(this, arguments);
|
|
242
242
|
};
|
|
243
|
+
}();
|
|
244
|
+
export var updateReferenceSyncedBlockOnDocument = /*#__PURE__*/function () {
|
|
245
|
+
var _ref1 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6(_ref0) {
|
|
246
|
+
var documentAri, blocks, _ref0$noContent, noContent, response;
|
|
247
|
+
return _regeneratorRuntime.wrap(function _callee6$(_context6) {
|
|
248
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
249
|
+
case 0:
|
|
250
|
+
documentAri = _ref0.documentAri, blocks = _ref0.blocks, _ref0$noContent = _ref0.noContent, noContent = _ref0$noContent === void 0 ? true : _ref0$noContent;
|
|
251
|
+
_context6.next = 3;
|
|
252
|
+
return fetchWithRetry("".concat(BLOCK_SERVICE_API_URL, "/block/document/").concat(encodeURIComponent(documentAri), "/references?noContent=").concat(noContent), {
|
|
253
|
+
method: 'PUT',
|
|
254
|
+
headers: COMMON_HEADERS,
|
|
255
|
+
body: JSON.stringify({
|
|
256
|
+
blocks: blocks
|
|
257
|
+
})
|
|
258
|
+
});
|
|
259
|
+
case 3:
|
|
260
|
+
response = _context6.sent;
|
|
261
|
+
if (response.ok) {
|
|
262
|
+
_context6.next = 6;
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
throw new BlockError(response.status);
|
|
266
|
+
case 6:
|
|
267
|
+
if (noContent) {
|
|
268
|
+
_context6.next = 10;
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
_context6.next = 9;
|
|
272
|
+
return response.json();
|
|
273
|
+
case 9:
|
|
274
|
+
return _context6.abrupt("return", _context6.sent);
|
|
275
|
+
case 10:
|
|
276
|
+
case "end":
|
|
277
|
+
return _context6.stop();
|
|
278
|
+
}
|
|
279
|
+
}, _callee6);
|
|
280
|
+
}));
|
|
281
|
+
return function updateReferenceSyncedBlockOnDocument(_x6) {
|
|
282
|
+
return _ref1.apply(this, arguments);
|
|
283
|
+
};
|
|
243
284
|
}();
|
|
@@ -6,7 +6,7 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
|
6
6
|
/* eslint-disable require-unicode-regexp */
|
|
7
7
|
import { useMemo } from 'react';
|
|
8
8
|
import { generateBlockAri, generateBlockAriFromReference } from '../../clients/block-service/ari';
|
|
9
|
-
import { BlockError, createSyncedBlock, deleteSyncedBlock, getReferenceSyncedBlocks, getSyncedBlockContent, updateSyncedBlock } from '../../clients/block-service/blockService';
|
|
9
|
+
import { BlockError, createSyncedBlock, deleteSyncedBlock, getReferenceSyncedBlocks, getSyncedBlockContent, updateReferenceSyncedBlockOnDocument, updateSyncedBlock } from '../../clients/block-service/blockService';
|
|
10
10
|
import { SyncBlockError } from '../../common/types';
|
|
11
11
|
import { stringifyError } from '../../utils/errorHandling';
|
|
12
12
|
var mapBlockError = function mapBlockError(error) {
|
|
@@ -317,21 +317,30 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
317
317
|
_context5.prev = 7;
|
|
318
318
|
_context5.t0 = _context5["catch"](1);
|
|
319
319
|
if (!(_context5.t0 instanceof BlockError)) {
|
|
320
|
-
_context5.next =
|
|
320
|
+
_context5.next = 13;
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
if (!(_context5.t0.status === 404)) {
|
|
324
|
+
_context5.next = 12;
|
|
321
325
|
break;
|
|
322
326
|
}
|
|
327
|
+
return _context5.abrupt("return", {
|
|
328
|
+
resourceId: resourceId,
|
|
329
|
+
success: true
|
|
330
|
+
});
|
|
331
|
+
case 12:
|
|
323
332
|
return _context5.abrupt("return", {
|
|
324
333
|
resourceId: resourceId,
|
|
325
334
|
success: false,
|
|
326
335
|
error: mapBlockError(_context5.t0)
|
|
327
336
|
});
|
|
328
|
-
case
|
|
337
|
+
case 13:
|
|
329
338
|
return _context5.abrupt("return", {
|
|
330
339
|
resourceId: resourceId,
|
|
331
340
|
success: false,
|
|
332
341
|
error: stringifyError(_context5.t0)
|
|
333
342
|
});
|
|
334
|
-
case
|
|
343
|
+
case 14:
|
|
335
344
|
case "end":
|
|
336
345
|
return _context5.stop();
|
|
337
346
|
}
|
|
@@ -352,6 +361,56 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
352
361
|
value: function generateResourceId() {
|
|
353
362
|
return crypto.randomUUID();
|
|
354
363
|
}
|
|
364
|
+
}, {
|
|
365
|
+
key: "updateReferenceData",
|
|
366
|
+
value: function () {
|
|
367
|
+
var _updateReferenceData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee6(blocks, noContent) {
|
|
368
|
+
var _this = this;
|
|
369
|
+
return _regeneratorRuntime.wrap(function _callee6$(_context6) {
|
|
370
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
371
|
+
case 0:
|
|
372
|
+
_context6.prev = 0;
|
|
373
|
+
_context6.next = 3;
|
|
374
|
+
return updateReferenceSyncedBlockOnDocument({
|
|
375
|
+
documentAri: this.sourceAri,
|
|
376
|
+
blocks: blocks.map(function (block) {
|
|
377
|
+
return {
|
|
378
|
+
blockAri: generateBlockAriFromReference(_this.sourceAri, block.resourceId),
|
|
379
|
+
blockInstanceId: block.localId
|
|
380
|
+
};
|
|
381
|
+
}, noContent)
|
|
382
|
+
});
|
|
383
|
+
case 3:
|
|
384
|
+
return _context6.abrupt("return", {
|
|
385
|
+
success: true
|
|
386
|
+
});
|
|
387
|
+
case 6:
|
|
388
|
+
_context6.prev = 6;
|
|
389
|
+
_context6.t0 = _context6["catch"](0);
|
|
390
|
+
if (!(_context6.t0 instanceof BlockError)) {
|
|
391
|
+
_context6.next = 10;
|
|
392
|
+
break;
|
|
393
|
+
}
|
|
394
|
+
return _context6.abrupt("return", {
|
|
395
|
+
success: false,
|
|
396
|
+
error: mapBlockError(_context6.t0)
|
|
397
|
+
});
|
|
398
|
+
case 10:
|
|
399
|
+
return _context6.abrupt("return", {
|
|
400
|
+
success: false,
|
|
401
|
+
error: stringifyError(_context6.t0)
|
|
402
|
+
});
|
|
403
|
+
case 11:
|
|
404
|
+
case "end":
|
|
405
|
+
return _context6.stop();
|
|
406
|
+
}
|
|
407
|
+
}, _callee6, this, [[0, 6]]);
|
|
408
|
+
}));
|
|
409
|
+
function updateReferenceData(_x6, _x7) {
|
|
410
|
+
return _updateReferenceData.apply(this, arguments);
|
|
411
|
+
}
|
|
412
|
+
return updateReferenceData;
|
|
413
|
+
}()
|
|
355
414
|
}]);
|
|
356
415
|
}();
|
|
357
416
|
/**
|
|
@@ -403,6 +403,13 @@ var ConfluenceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
403
403
|
value: function generateResourceIdForReference(sourceId) {
|
|
404
404
|
return sourceId;
|
|
405
405
|
}
|
|
406
|
+
}, {
|
|
407
|
+
key: "updateReferenceData",
|
|
408
|
+
value: function updateReferenceData(_blocks, _noContent) {
|
|
409
|
+
return Promise.resolve({
|
|
410
|
+
success: true
|
|
411
|
+
});
|
|
412
|
+
}
|
|
406
413
|
}]);
|
|
407
414
|
}();
|
|
408
415
|
/**
|
|
@@ -289,6 +289,11 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
|
|
|
289
289
|
throw new Error("".concat(sourceProduct, " source product not supported"));
|
|
290
290
|
}
|
|
291
291
|
}
|
|
292
|
+
}, {
|
|
293
|
+
key: "updateReferenceData",
|
|
294
|
+
value: function updateReferenceData(blocks, noContent) {
|
|
295
|
+
return this.writeProvider.updateReferenceData(blocks, noContent);
|
|
296
|
+
}
|
|
292
297
|
}]);
|
|
293
298
|
}(SyncBlockDataProvider);
|
|
294
299
|
export var useMemoizedSyncedBlockProvider = function useMemoizedSyncedBlockProvider(fetchProvider, writeProvider, sourceId, providerOptions, getSSRData) {
|
|
@@ -12,7 +12,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
12
12
|
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
13
13
|
import { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
|
|
14
14
|
import { SyncBlockError } from '../common/types';
|
|
15
|
-
import { fetchErrorPayload, getSourceInfoErrorPayload } from '../utils/errorHandling';
|
|
15
|
+
import { fetchErrorPayload, getSourceInfoErrorPayload, updateReferenceErrorPayload } from '../utils/errorHandling';
|
|
16
16
|
import { resolveSyncBlockInstance } from '../utils/resolveSyncBlockInstance';
|
|
17
17
|
import { createSyncBlockNode } from '../utils/utils';
|
|
18
18
|
|
|
@@ -24,6 +24,10 @@ import { createSyncBlockNode } from '../utils/utils';
|
|
|
24
24
|
export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
25
25
|
function ReferenceSyncBlockStoreManager(dataProvider, fireAnalyticsEvent) {
|
|
26
26
|
_classCallCheck(this, ReferenceSyncBlockStoreManager);
|
|
27
|
+
// Keeps track of addition and deletion of reference synced blocks on the document
|
|
28
|
+
// This starts as true to always flush the cache when document is saved for the first time
|
|
29
|
+
// to cater the case when a editor seesion is closed without document being updated right after reference block is deleted
|
|
30
|
+
_defineProperty(this, "isCacheDirty", true);
|
|
27
31
|
_defineProperty(this, "isRefreshingSubscriptions", false);
|
|
28
32
|
this.syncBlockCache = new Map();
|
|
29
33
|
this.subscriptions = new Map();
|
|
@@ -321,6 +325,9 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
321
325
|
// add to subscriptions map
|
|
322
326
|
var resourceSubscriptions = this.subscriptions.get(resourceId) || {};
|
|
323
327
|
this.subscriptions.set(resourceId, _objectSpread(_objectSpread({}, resourceSubscriptions), {}, _defineProperty({}, localId, callback)));
|
|
328
|
+
|
|
329
|
+
// New subscription means new reference synced block is added to the document
|
|
330
|
+
this.isCacheDirty = true;
|
|
324
331
|
var syncBlockNode = createSyncBlockNode(localId, resourceId);
|
|
325
332
|
|
|
326
333
|
// call the callback immediately if we have cached data
|
|
@@ -340,6 +347,8 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
340
347
|
return function () {
|
|
341
348
|
var resourceSubscriptions = _this3.subscriptions.get(resourceId);
|
|
342
349
|
if (resourceSubscriptions) {
|
|
350
|
+
// Unsubscription means a reference synced block is removed from the document
|
|
351
|
+
_this3.isCacheDirty = true;
|
|
343
352
|
delete resourceSubscriptions[localId];
|
|
344
353
|
if (Object.keys(resourceSubscriptions).length === 0) {
|
|
345
354
|
_this3.subscriptions.delete(resourceId);
|
|
@@ -509,6 +518,89 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
509
518
|
}
|
|
510
519
|
}
|
|
511
520
|
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Update reference synced blocks on the document with the BE
|
|
524
|
+
*
|
|
525
|
+
* @returns true if the reference synced blocks are updated successfully, false otherwise
|
|
526
|
+
*/
|
|
527
|
+
}, {
|
|
528
|
+
key: "flush",
|
|
529
|
+
value: (function () {
|
|
530
|
+
var _flush = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
|
|
531
|
+
var success, blocks, updateResult, _this$fireAnalyticsEv9, _this$fireAnalyticsEv0;
|
|
532
|
+
return _regeneratorRuntime.wrap(function _callee3$(_context4) {
|
|
533
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
534
|
+
case 0:
|
|
535
|
+
if (this.isCacheDirty) {
|
|
536
|
+
_context4.next = 2;
|
|
537
|
+
break;
|
|
538
|
+
}
|
|
539
|
+
return _context4.abrupt("return", true);
|
|
540
|
+
case 2:
|
|
541
|
+
success = true;
|
|
542
|
+
_context4.prev = 3;
|
|
543
|
+
if (this.dataProvider) {
|
|
544
|
+
_context4.next = 6;
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
throw new Error('Data provider not set');
|
|
548
|
+
case 6:
|
|
549
|
+
blocks = []; // Collect all reference synced blocks on the current document
|
|
550
|
+
Array.from(this.subscriptions.entries()).forEach(function (_ref2) {
|
|
551
|
+
var _ref3 = _slicedToArray(_ref2, 2),
|
|
552
|
+
resourceId = _ref3[0],
|
|
553
|
+
callbacks = _ref3[1];
|
|
554
|
+
Object.keys(callbacks).forEach(function (localId) {
|
|
555
|
+
blocks.push({
|
|
556
|
+
resourceId: resourceId,
|
|
557
|
+
localId: localId
|
|
558
|
+
});
|
|
559
|
+
});
|
|
560
|
+
});
|
|
561
|
+
if (!(blocks.length === 0)) {
|
|
562
|
+
_context4.next = 10;
|
|
563
|
+
break;
|
|
564
|
+
}
|
|
565
|
+
return _context4.abrupt("return", true);
|
|
566
|
+
case 10:
|
|
567
|
+
_context4.next = 12;
|
|
568
|
+
return this.dataProvider.updateReferenceData(blocks);
|
|
569
|
+
case 12:
|
|
570
|
+
updateResult = _context4.sent;
|
|
571
|
+
if (!updateResult.success) {
|
|
572
|
+
success = false;
|
|
573
|
+
(_this$fireAnalyticsEv9 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv9 === void 0 || _this$fireAnalyticsEv9.call(this, updateReferenceErrorPayload(updateResult.error || 'Failed to update reference synced blocks on the document'));
|
|
574
|
+
}
|
|
575
|
+
_context4.next = 21;
|
|
576
|
+
break;
|
|
577
|
+
case 16:
|
|
578
|
+
_context4.prev = 16;
|
|
579
|
+
_context4.t0 = _context4["catch"](3);
|
|
580
|
+
success = false;
|
|
581
|
+
logException(_context4.t0, {
|
|
582
|
+
location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
|
|
583
|
+
});
|
|
584
|
+
(_this$fireAnalyticsEv0 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv0 === void 0 || _this$fireAnalyticsEv0.call(this, updateReferenceErrorPayload(_context4.t0.message));
|
|
585
|
+
case 21:
|
|
586
|
+
_context4.prev = 21;
|
|
587
|
+
if (success) {
|
|
588
|
+
this.isCacheDirty = false;
|
|
589
|
+
}
|
|
590
|
+
return _context4.finish(21);
|
|
591
|
+
case 24:
|
|
592
|
+
return _context4.abrupt("return", success);
|
|
593
|
+
case 25:
|
|
594
|
+
case "end":
|
|
595
|
+
return _context4.stop();
|
|
596
|
+
}
|
|
597
|
+
}, _callee3, this, [[3, 16, 21, 24]]);
|
|
598
|
+
}));
|
|
599
|
+
function flush() {
|
|
600
|
+
return _flush.apply(this, arguments);
|
|
601
|
+
}
|
|
602
|
+
return flush;
|
|
603
|
+
}())
|
|
512
604
|
}, {
|
|
513
605
|
key: "destroy",
|
|
514
606
|
value: function destroy() {
|
|
@@ -3,9 +3,12 @@ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
|
3
3
|
import _createClass from "@babel/runtime/helpers/createClass";
|
|
4
4
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
5
5
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
6
|
+
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; }
|
|
7
|
+
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
8
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
7
9
|
import uuid from 'uuid';
|
|
8
10
|
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
11
|
+
import { SyncBlockError } from '../common/types';
|
|
9
12
|
import { updateErrorPayload, createErrorPayload, deleteErrorPayload, updateCacheErrorPayload } from '../utils/errorHandling';
|
|
10
13
|
import { convertSyncBlockPMNodeToSyncBlockData } from '../utils/utils';
|
|
11
14
|
// A store manager responsible for the lifecycle and state management of source sync blocks in an editor instance.
|
|
@@ -51,7 +54,9 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
51
54
|
throw new Error('Local ID or resource ID is not set');
|
|
52
55
|
}
|
|
53
56
|
var syncBlockData = convertSyncBlockPMNodeToSyncBlockData(syncBlockNode);
|
|
54
|
-
this.syncBlockCache.set(resourceId, syncBlockData)
|
|
57
|
+
this.syncBlockCache.set(resourceId, _objectSpread(_objectSpread({}, syncBlockData), {}, {
|
|
58
|
+
isDirty: true
|
|
59
|
+
}));
|
|
55
60
|
return true;
|
|
56
61
|
} catch (error) {
|
|
57
62
|
var _this$fireAnalyticsEv;
|
|
@@ -88,7 +93,8 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
88
93
|
bodiedSyncBlockData = [];
|
|
89
94
|
Array.from(this.syncBlockCache.values()).forEach(function (syncBlockData) {
|
|
90
95
|
// Don't flush nodes that are waiting to be deleted to avoid nodes being re-created
|
|
91
|
-
|
|
96
|
+
// Don't flush nodes that haven't been updated since we last flushed
|
|
97
|
+
if (!syncBlockData.pendingDeletion && syncBlockData.isDirty) {
|
|
92
98
|
bodiedSyncBlockNodes.push({
|
|
93
99
|
type: 'bodiedSyncBlock',
|
|
94
100
|
attrs: {
|
|
@@ -109,37 +115,46 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
109
115
|
return this.dataProvider.writeNodesData(bodiedSyncBlockNodes, bodiedSyncBlockData);
|
|
110
116
|
case 10:
|
|
111
117
|
writeResults = _context.sent;
|
|
118
|
+
writeResults.forEach(function (result) {
|
|
119
|
+
// set isDirty to false on write success and unrecoverable errors like not found
|
|
120
|
+
if (result.resourceId && (result.error === SyncBlockError.NotFound || !result.error)) {
|
|
121
|
+
var cachedData = _this2.syncBlockCache.get(result.resourceId);
|
|
122
|
+
if (cachedData) {
|
|
123
|
+
cachedData.isDirty = false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
});
|
|
112
127
|
if (!writeResults.every(function (result) {
|
|
113
|
-
return result.resourceId
|
|
128
|
+
return result.resourceId && !result.error;
|
|
114
129
|
})) {
|
|
115
|
-
_context.next =
|
|
130
|
+
_context.next = 16;
|
|
116
131
|
break;
|
|
117
132
|
}
|
|
118
133
|
return _context.abrupt("return", true);
|
|
119
|
-
case
|
|
134
|
+
case 16:
|
|
120
135
|
writeResults.filter(function (result) {
|
|
121
|
-
return result.resourceId
|
|
136
|
+
return !result.resourceId || result.error;
|
|
122
137
|
}).forEach(function (result) {
|
|
123
138
|
var _this2$fireAnalyticsE;
|
|
124
139
|
(_this2$fireAnalyticsE = _this2.fireAnalyticsEvent) === null || _this2$fireAnalyticsE === void 0 || _this2$fireAnalyticsE.call(_this2, updateErrorPayload(result.error || 'Failed to write data'));
|
|
125
140
|
});
|
|
126
141
|
return _context.abrupt("return", false);
|
|
127
|
-
case
|
|
128
|
-
_context.next =
|
|
142
|
+
case 18:
|
|
143
|
+
_context.next = 25;
|
|
129
144
|
break;
|
|
130
|
-
case
|
|
131
|
-
_context.prev =
|
|
145
|
+
case 20:
|
|
146
|
+
_context.prev = 20;
|
|
132
147
|
_context.t0 = _context["catch"](0);
|
|
133
148
|
logException(_context.t0, {
|
|
134
149
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
135
150
|
});
|
|
136
151
|
(_this$fireAnalyticsEv2 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv2 === void 0 || _this$fireAnalyticsEv2.call(this, updateErrorPayload(_context.t0.message));
|
|
137
152
|
return _context.abrupt("return", false);
|
|
138
|
-
case
|
|
153
|
+
case 25:
|
|
139
154
|
case "end":
|
|
140
155
|
return _context.stop();
|
|
141
156
|
}
|
|
142
|
-
}, _callee, this, [[0,
|
|
157
|
+
}, _callee, this, [[0, 20]]);
|
|
143
158
|
}));
|
|
144
159
|
function flush() {
|
|
145
160
|
return _flush.apply(this, arguments);
|
|
@@ -26,6 +26,9 @@ export var getSourceInfoErrorPayload = function getSourceInfoErrorPayload(error)
|
|
|
26
26
|
export var updateErrorPayload = function updateErrorPayload(error) {
|
|
27
27
|
return getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_UPDATE, error);
|
|
28
28
|
};
|
|
29
|
+
export var updateReferenceErrorPayload = function updateReferenceErrorPayload(error) {
|
|
30
|
+
return getErrorPayload(ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_UPDATE, error);
|
|
31
|
+
};
|
|
29
32
|
export var createErrorPayload = function createErrorPayload(error) {
|
|
30
33
|
return getErrorPayload(ACTION_SUBJECT_ID.SYNCED_BLOCK_CREATE, error);
|
|
31
34
|
};
|
|
@@ -15,6 +15,10 @@ export type BlockContentErrorResponse = {
|
|
|
15
15
|
code: string;
|
|
16
16
|
reason: string;
|
|
17
17
|
};
|
|
18
|
+
type ReferenceSyncedBlockResponse = {
|
|
19
|
+
blocks?: Array<BlockContentResponse>;
|
|
20
|
+
errors?: Array<BlockContentErrorResponse>;
|
|
21
|
+
};
|
|
18
22
|
export declare const isBlockContentResponse: (response: BlockContentResponse | BlockContentErrorResponse) => response is BlockContentResponse;
|
|
19
23
|
/**
|
|
20
24
|
* Retrieves all synced blocks referenced in a document.
|
|
@@ -58,10 +62,7 @@ export declare const isBlockContentResponse: (response: BlockContentResponse | B
|
|
|
58
62
|
* ```
|
|
59
63
|
* Check https://block-service.dev.atl-paas.net/ for latest API documentation.
|
|
60
64
|
*/
|
|
61
|
-
export declare const getReferenceSyncedBlocks: (documentAri: string) => Promise<
|
|
62
|
-
blocks?: Array<BlockContentResponse>;
|
|
63
|
-
errors?: Array<BlockContentErrorResponse>;
|
|
64
|
-
}>;
|
|
65
|
+
export declare const getReferenceSyncedBlocks: (documentAri: string) => Promise<ReferenceSyncedBlockResponse>;
|
|
65
66
|
export type GetSyncedBlockContentRequest = {
|
|
66
67
|
blockAri: string;
|
|
67
68
|
};
|
|
@@ -79,6 +80,15 @@ export type CreateSyncedBlockRequest = {
|
|
|
79
80
|
product: SyncBlockProduct;
|
|
80
81
|
sourceAri: string;
|
|
81
82
|
};
|
|
83
|
+
type ReferenceSyncedBlockIDs = {
|
|
84
|
+
blockAri: string;
|
|
85
|
+
blockInstanceId: string;
|
|
86
|
+
};
|
|
87
|
+
type UpdateReferenceSyncedBlockOnDocumentRequest = {
|
|
88
|
+
blocks: ReferenceSyncedBlockIDs[];
|
|
89
|
+
documentAri: string;
|
|
90
|
+
noContent?: boolean;
|
|
91
|
+
};
|
|
82
92
|
export declare class BlockError extends Error {
|
|
83
93
|
readonly status: number;
|
|
84
94
|
constructor(status: number);
|
|
@@ -87,3 +97,5 @@ export declare const getSyncedBlockContent: ({ blockAri, }: GetSyncedBlockConten
|
|
|
87
97
|
export declare const deleteSyncedBlock: ({ blockAri }: DeleteSyncedBlockRequest) => Promise<void>;
|
|
88
98
|
export declare const updateSyncedBlock: ({ blockAri, content, }: UpdateSyncedBlockRequest) => Promise<void>;
|
|
89
99
|
export declare const createSyncedBlock: ({ blockAri, blockInstanceId, sourceAri, product, content, }: CreateSyncedBlockRequest) => Promise<BlockContentResponse>;
|
|
100
|
+
export declare const updateReferenceSyncedBlockOnDocument: ({ documentAri, blocks, noContent, }: UpdateReferenceSyncedBlockOnDocumentRequest) => Promise<ReferenceSyncedBlockResponse | void>;
|
|
101
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SyncBlockError, type ResourceId, type SyncBlockData, type SyncBlockProduct } from '../../common/types';
|
|
2
|
-
import type { ADFFetchProvider, ADFWriteProvider, DeleteSyncBlockResult, SyncBlockInstance, WriteSyncBlockResult } from '../types';
|
|
1
|
+
import { SyncBlockError, type ResourceId, type SyncBlockAttrs, type SyncBlockData, type SyncBlockProduct } from '../../common/types';
|
|
2
|
+
import type { ADFFetchProvider, ADFWriteProvider, DeleteSyncBlockResult, SyncBlockInstance, UpdateReferenceSyncBlockResult, WriteSyncBlockResult } from '../types';
|
|
3
3
|
export declare const fetchReferences: (documentAri: string) => Promise<SyncBlockInstance[] | SyncBlockError>;
|
|
4
4
|
/**
|
|
5
5
|
* ADFFetchProvider implementation that fetches synced block data from Block Service API
|
|
@@ -22,6 +22,7 @@ declare class BlockServiceADFWriteProvider implements ADFWriteProvider {
|
|
|
22
22
|
deleteData(resourceId: string): Promise<DeleteSyncBlockResult>;
|
|
23
23
|
generateResourceIdForReference(sourceId: ResourceId): ResourceId;
|
|
24
24
|
generateResourceId(): ResourceId;
|
|
25
|
+
updateReferenceData(blocks: SyncBlockAttrs[], noContent?: boolean): Promise<UpdateReferenceSyncBlockResult>;
|
|
25
26
|
}
|
|
26
27
|
export declare const useMemoizedBlockServiceAPIProviders: (sourceAri: string, product: SyncBlockProduct, sourceDocumentId: string) => {
|
|
27
28
|
fetchProvider: BlockServiceADFFetchProvider;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type ResourceId, type SyncBlockData, type SyncBlockProduct } from '../../common/types';
|
|
2
|
-
import type { ADFFetchProvider, ADFWriteProvider, DeleteSyncBlockResult, SyncBlockInstance, WriteSyncBlockResult } from '../types';
|
|
1
|
+
import { type ResourceId, type SyncBlockAttrs, type SyncBlockData, type SyncBlockProduct } from '../../common/types';
|
|
2
|
+
import type { ADFFetchProvider, ADFWriteProvider, DeleteSyncBlockResult, SyncBlockInstance, UpdateReferenceSyncBlockResult, WriteSyncBlockResult } from '../types';
|
|
3
3
|
/**
|
|
4
4
|
* Configuration for Content API providers
|
|
5
5
|
*/
|
|
@@ -28,6 +28,7 @@ declare class ConfluenceADFWriteProvider implements ADFWriteProvider {
|
|
|
28
28
|
deleteData(resourceId: string): Promise<DeleteSyncBlockResult>;
|
|
29
29
|
generateResourceId(sourceId: string, localId: string): string;
|
|
30
30
|
generateResourceIdForReference(sourceId: ResourceId): ResourceId;
|
|
31
|
+
updateReferenceData(_blocks: SyncBlockAttrs[], _noContent?: boolean): Promise<UpdateReferenceSyncBlockResult>;
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
34
|
* Convenience function to create providers with default content property key
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { RendererSyncBlockEventPayload } from '@atlaskit/editor-common/analytics';
|
|
2
2
|
import type { JSONNode } from '@atlaskit/editor-json-transformer/types';
|
|
3
|
-
import { type BlockInstanceId, type ResourceId, type SyncBlockData, type SyncBlockNode, type SyncBlockProduct } from '../common/types';
|
|
4
|
-
import { SyncBlockDataProvider, type ADFFetchProvider, type ADFWriteProvider, type DeleteSyncBlockResult, type SyncBlockInstance, type SyncBlockParentInfo, type SyncBlockSourceInfo, type SyncedBlockRendererProviderOptions, type WriteSyncBlockResult } from '../providers/types';
|
|
3
|
+
import { type BlockInstanceId, type ResourceId, type SyncBlockAttrs, type SyncBlockData, type SyncBlockNode, type SyncBlockProduct } from '../common/types';
|
|
4
|
+
import { SyncBlockDataProvider, type ADFFetchProvider, type ADFWriteProvider, type DeleteSyncBlockResult, type SyncBlockInstance, type SyncBlockParentInfo, type SyncBlockSourceInfo, type SyncedBlockRendererProviderOptions, type UpdateReferenceSyncBlockResult, type WriteSyncBlockResult } from '../providers/types';
|
|
5
5
|
export declare class SyncBlockProvider extends SyncBlockDataProvider {
|
|
6
6
|
name: string;
|
|
7
7
|
private fetchProvider;
|
|
@@ -94,5 +94,6 @@ export declare class SyncBlockProvider extends SyncBlockDataProvider {
|
|
|
94
94
|
* @returns The parent info for the sync block
|
|
95
95
|
*/
|
|
96
96
|
retrieveSyncBlockParentInfo(sourceAri: string, sourceProduct: SyncBlockProduct): SyncBlockParentInfo | undefined;
|
|
97
|
+
updateReferenceData(blocks: SyncBlockAttrs[], noContent?: boolean): Promise<UpdateReferenceSyncBlockResult>;
|
|
97
98
|
}
|
|
98
99
|
export declare const useMemoizedSyncedBlockProvider: (fetchProvider: ADFFetchProvider, writeProvider: ADFWriteProvider, sourceId: string, providerOptions: SyncedBlockRendererProviderOptions, getSSRData?: () => Record<string, SyncBlockInstance> | undefined) => SyncBlockProvider;
|
|
@@ -4,7 +4,7 @@ import type { EmojiProvider } from '@atlaskit/emoji';
|
|
|
4
4
|
import type { MentionProvider } from '@atlaskit/mention/types';
|
|
5
5
|
import { NodeDataProvider } from '@atlaskit/node-data-provider';
|
|
6
6
|
import type { TaskDecisionProvider } from '@atlaskit/task-decision/types';
|
|
7
|
-
import type { SyncBlockData, ResourceId, SyncBlockError, SyncBlockNode, SyncBlockProduct, BlockInstanceId } from '../common/types';
|
|
7
|
+
import type { SyncBlockData, ResourceId, SyncBlockError, SyncBlockNode, SyncBlockProduct, BlockInstanceId, SyncBlockAttrs } from '../common/types';
|
|
8
8
|
/**
|
|
9
9
|
* The instance of a sync block, containing its data and metadata.
|
|
10
10
|
* Mainly used for representing the state of a sync block after fetching from a data provider.
|
|
@@ -39,15 +39,26 @@ export type SourceInfoFetchData = {
|
|
|
39
39
|
pageARI: string;
|
|
40
40
|
sourceLocalId?: string;
|
|
41
41
|
};
|
|
42
|
+
export type UpdateReferenceSyncBlockResult = {
|
|
43
|
+
error?: string;
|
|
44
|
+
success: boolean;
|
|
45
|
+
};
|
|
42
46
|
export interface ADFFetchProvider {
|
|
43
47
|
fetchData: (resourceId: ResourceId) => Promise<SyncBlockInstance>;
|
|
44
48
|
}
|
|
45
49
|
export interface ADFWriteProvider {
|
|
46
50
|
createData: (data: SyncBlockData) => Promise<WriteSyncBlockResult>;
|
|
51
|
+
/**
|
|
52
|
+
* Delete source block.
|
|
53
|
+
* @param resourceId the resourceId of the block to be deleted
|
|
54
|
+
* @returns Object representing the result of the deletion. {resourceId: string, success: boolean, error?: string}.
|
|
55
|
+
* User should not be blocked by not_found error when deleting, so successful result should be returned for 404 error
|
|
56
|
+
*/
|
|
47
57
|
deleteData: (resourceId: ResourceId) => Promise<DeleteSyncBlockResult>;
|
|
48
58
|
generateResourceId: (sourceId: string, localId: string) => ResourceId;
|
|
49
59
|
generateResourceIdForReference: (sourceId: ResourceId) => ResourceId;
|
|
50
60
|
product: SyncBlockProduct;
|
|
61
|
+
updateReferenceData: (blocks: SyncBlockAttrs[], noContent?: boolean) => Promise<UpdateReferenceSyncBlockResult>;
|
|
51
62
|
writeData: (data: SyncBlockData) => Promise<WriteSyncBlockResult>;
|
|
52
63
|
}
|
|
53
64
|
export type MediaEmojiProviderOptions = {
|
|
@@ -84,6 +95,7 @@ export declare abstract class SyncBlockDataProvider extends NodeDataProvider<Syn
|
|
|
84
95
|
*/
|
|
85
96
|
abstract generateResourceId(sourceId: ResourceId, localId: BlockInstanceId): ResourceId;
|
|
86
97
|
abstract generateResourceIdForReference(sourceId: ResourceId): ResourceId;
|
|
98
|
+
abstract updateReferenceData(blocks: SyncBlockAttrs[], noContent?: boolean): Promise<UpdateReferenceSyncBlockResult>;
|
|
87
99
|
}
|
|
88
100
|
export type SubscriptionCallback = (data: SyncBlockInstance) => void;
|
|
89
101
|
export type TitleSubscriptionCallback = (title: string) => void;
|
|
@@ -6,6 +6,7 @@ import type { SyncBlockInstance, SubscriptionCallback, SyncBlockDataProvider, Ti
|
|
|
6
6
|
export declare class ReferenceSyncBlockStoreManager {
|
|
7
7
|
private dataProvider?;
|
|
8
8
|
private syncBlockCache;
|
|
9
|
+
private isCacheDirty;
|
|
9
10
|
private subscriptions;
|
|
10
11
|
private titleSubscriptions;
|
|
11
12
|
private providerFactories;
|
|
@@ -44,5 +45,11 @@ export declare class ReferenceSyncBlockStoreManager {
|
|
|
44
45
|
getSyncBlockURL(resourceId: ResourceId): string | undefined;
|
|
45
46
|
getProviderFactory(resourceId: ResourceId): ProviderFactory | undefined;
|
|
46
47
|
private retrieveDynamicProviders;
|
|
48
|
+
/**
|
|
49
|
+
* Update reference synced blocks on the document with the BE
|
|
50
|
+
*
|
|
51
|
+
* @returns true if the reference synced blocks are updated successfully, false otherwise
|
|
52
|
+
*/
|
|
53
|
+
flush(): Promise<boolean>;
|
|
47
54
|
destroy(): void;
|
|
48
55
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type SyncBlockEventPayload } from '@atlaskit/editor-common/analytics';
|
|
2
2
|
import { type Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
-
import type
|
|
3
|
+
import { type ResourceId, type SyncBlockAttrs } from '../common/types';
|
|
4
4
|
import type { SyncBlockDataProvider } from '../providers/types';
|
|
5
5
|
export type ConfirmationCallback = (syncBlockCount: number) => Promise<boolean>;
|
|
6
6
|
type OnDelete = () => void;
|
|
@@ -6,6 +6,7 @@ export declare const getErrorPayload: <T extends ACTION_SUBJECT_ID>(actionSubjec
|
|
|
6
6
|
export declare const fetchErrorPayload: (error: string) => RendererSyncBlockEventPayload;
|
|
7
7
|
export declare const getSourceInfoErrorPayload: (error: string) => RendererSyncBlockEventPayload;
|
|
8
8
|
export declare const updateErrorPayload: (error: string) => SyncBlockEventPayload;
|
|
9
|
+
export declare const updateReferenceErrorPayload: (error: string) => RendererSyncBlockEventPayload;
|
|
9
10
|
export declare const createErrorPayload: (error: string) => SyncBlockEventPayload;
|
|
10
11
|
export declare const deleteErrorPayload: (error: string) => SyncBlockEventPayload;
|
|
11
12
|
export declare const updateCacheErrorPayload: (error: string) => SyncBlockEventPayload;
|