@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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/editor-synced-block-provider
|
|
2
2
|
|
|
3
|
+
## 2.15.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`f14e76661c943`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f14e76661c943) -
|
|
8
|
+
[EDITOR-2844] Save reference synced block on document to BE when a page is saved
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 2.15.2
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [`70face9ce7f1b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/70face9ce7f1b) -
|
|
16
|
+
EDITOR-3778 optimise flush to only send to BE when sync block data changes
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
|
|
3
19
|
## 2.15.1
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.updateSyncedBlock = exports.isBlockContentResponse = exports.getSyncedBlockContent = exports.getReferenceSyncedBlocks = exports.deleteSyncedBlock = exports.createSyncedBlock = exports.BlockError = void 0;
|
|
7
|
+
exports.updateSyncedBlock = exports.updateReferenceSyncedBlockOnDocument = exports.isBlockContentResponse = exports.getSyncedBlockContent = exports.getReferenceSyncedBlocks = exports.deleteSyncedBlock = exports.createSyncedBlock = exports.BlockError = void 0;
|
|
8
8
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
9
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
10
10
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
@@ -247,4 +247,45 @@ var createSyncedBlock = exports.createSyncedBlock = /*#__PURE__*/function () {
|
|
|
247
247
|
return function createSyncedBlock(_x5) {
|
|
248
248
|
return _ref9.apply(this, arguments);
|
|
249
249
|
};
|
|
250
|
+
}();
|
|
251
|
+
var updateReferenceSyncedBlockOnDocument = exports.updateReferenceSyncedBlockOnDocument = /*#__PURE__*/function () {
|
|
252
|
+
var _ref1 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(_ref0) {
|
|
253
|
+
var documentAri, blocks, _ref0$noContent, noContent, response;
|
|
254
|
+
return _regenerator.default.wrap(function _callee6$(_context6) {
|
|
255
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
256
|
+
case 0:
|
|
257
|
+
documentAri = _ref0.documentAri, blocks = _ref0.blocks, _ref0$noContent = _ref0.noContent, noContent = _ref0$noContent === void 0 ? true : _ref0$noContent;
|
|
258
|
+
_context6.next = 3;
|
|
259
|
+
return (0, _retry.fetchWithRetry)("".concat(BLOCK_SERVICE_API_URL, "/block/document/").concat(encodeURIComponent(documentAri), "/references?noContent=").concat(noContent), {
|
|
260
|
+
method: 'PUT',
|
|
261
|
+
headers: COMMON_HEADERS,
|
|
262
|
+
body: JSON.stringify({
|
|
263
|
+
blocks: blocks
|
|
264
|
+
})
|
|
265
|
+
});
|
|
266
|
+
case 3:
|
|
267
|
+
response = _context6.sent;
|
|
268
|
+
if (response.ok) {
|
|
269
|
+
_context6.next = 6;
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
throw new BlockError(response.status);
|
|
273
|
+
case 6:
|
|
274
|
+
if (noContent) {
|
|
275
|
+
_context6.next = 10;
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
_context6.next = 9;
|
|
279
|
+
return response.json();
|
|
280
|
+
case 9:
|
|
281
|
+
return _context6.abrupt("return", _context6.sent);
|
|
282
|
+
case 10:
|
|
283
|
+
case "end":
|
|
284
|
+
return _context6.stop();
|
|
285
|
+
}
|
|
286
|
+
}, _callee6);
|
|
287
|
+
}));
|
|
288
|
+
return function updateReferenceSyncedBlockOnDocument(_x6) {
|
|
289
|
+
return _ref1.apply(this, arguments);
|
|
290
|
+
};
|
|
250
291
|
}();
|
|
@@ -325,21 +325,30 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
325
325
|
_context5.prev = 7;
|
|
326
326
|
_context5.t0 = _context5["catch"](1);
|
|
327
327
|
if (!(_context5.t0 instanceof _blockService.BlockError)) {
|
|
328
|
-
_context5.next =
|
|
328
|
+
_context5.next = 13;
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
if (!(_context5.t0.status === 404)) {
|
|
332
|
+
_context5.next = 12;
|
|
329
333
|
break;
|
|
330
334
|
}
|
|
335
|
+
return _context5.abrupt("return", {
|
|
336
|
+
resourceId: resourceId,
|
|
337
|
+
success: true
|
|
338
|
+
});
|
|
339
|
+
case 12:
|
|
331
340
|
return _context5.abrupt("return", {
|
|
332
341
|
resourceId: resourceId,
|
|
333
342
|
success: false,
|
|
334
343
|
error: mapBlockError(_context5.t0)
|
|
335
344
|
});
|
|
336
|
-
case
|
|
345
|
+
case 13:
|
|
337
346
|
return _context5.abrupt("return", {
|
|
338
347
|
resourceId: resourceId,
|
|
339
348
|
success: false,
|
|
340
349
|
error: (0, _errorHandling.stringifyError)(_context5.t0)
|
|
341
350
|
});
|
|
342
|
-
case
|
|
351
|
+
case 14:
|
|
343
352
|
case "end":
|
|
344
353
|
return _context5.stop();
|
|
345
354
|
}
|
|
@@ -360,6 +369,56 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
360
369
|
value: function generateResourceId() {
|
|
361
370
|
return crypto.randomUUID();
|
|
362
371
|
}
|
|
372
|
+
}, {
|
|
373
|
+
key: "updateReferenceData",
|
|
374
|
+
value: function () {
|
|
375
|
+
var _updateReferenceData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(blocks, noContent) {
|
|
376
|
+
var _this = this;
|
|
377
|
+
return _regenerator.default.wrap(function _callee6$(_context6) {
|
|
378
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
379
|
+
case 0:
|
|
380
|
+
_context6.prev = 0;
|
|
381
|
+
_context6.next = 3;
|
|
382
|
+
return (0, _blockService.updateReferenceSyncedBlockOnDocument)({
|
|
383
|
+
documentAri: this.sourceAri,
|
|
384
|
+
blocks: blocks.map(function (block) {
|
|
385
|
+
return {
|
|
386
|
+
blockAri: (0, _ari.generateBlockAriFromReference)(_this.sourceAri, block.resourceId),
|
|
387
|
+
blockInstanceId: block.localId
|
|
388
|
+
};
|
|
389
|
+
}, noContent)
|
|
390
|
+
});
|
|
391
|
+
case 3:
|
|
392
|
+
return _context6.abrupt("return", {
|
|
393
|
+
success: true
|
|
394
|
+
});
|
|
395
|
+
case 6:
|
|
396
|
+
_context6.prev = 6;
|
|
397
|
+
_context6.t0 = _context6["catch"](0);
|
|
398
|
+
if (!(_context6.t0 instanceof _blockService.BlockError)) {
|
|
399
|
+
_context6.next = 10;
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
return _context6.abrupt("return", {
|
|
403
|
+
success: false,
|
|
404
|
+
error: mapBlockError(_context6.t0)
|
|
405
|
+
});
|
|
406
|
+
case 10:
|
|
407
|
+
return _context6.abrupt("return", {
|
|
408
|
+
success: false,
|
|
409
|
+
error: (0, _errorHandling.stringifyError)(_context6.t0)
|
|
410
|
+
});
|
|
411
|
+
case 11:
|
|
412
|
+
case "end":
|
|
413
|
+
return _context6.stop();
|
|
414
|
+
}
|
|
415
|
+
}, _callee6, this, [[0, 6]]);
|
|
416
|
+
}));
|
|
417
|
+
function updateReferenceData(_x6, _x7) {
|
|
418
|
+
return _updateReferenceData.apply(this, arguments);
|
|
419
|
+
}
|
|
420
|
+
return updateReferenceData;
|
|
421
|
+
}()
|
|
363
422
|
}]);
|
|
364
423
|
}();
|
|
365
424
|
/**
|
|
@@ -409,6 +409,13 @@ var ConfluenceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
409
409
|
value: function generateResourceIdForReference(sourceId) {
|
|
410
410
|
return sourceId;
|
|
411
411
|
}
|
|
412
|
+
}, {
|
|
413
|
+
key: "updateReferenceData",
|
|
414
|
+
value: function updateReferenceData(_blocks, _noContent) {
|
|
415
|
+
return Promise.resolve({
|
|
416
|
+
success: true
|
|
417
|
+
});
|
|
418
|
+
}
|
|
412
419
|
}]);
|
|
413
420
|
}();
|
|
414
421
|
/**
|
|
@@ -296,6 +296,11 @@ var SyncBlockProvider = exports.SyncBlockProvider = /*#__PURE__*/function (_Sync
|
|
|
296
296
|
throw new Error("".concat(sourceProduct, " source product not supported"));
|
|
297
297
|
}
|
|
298
298
|
}
|
|
299
|
+
}, {
|
|
300
|
+
key: "updateReferenceData",
|
|
301
|
+
value: function updateReferenceData(blocks, noContent) {
|
|
302
|
+
return this.writeProvider.updateReferenceData(blocks, noContent);
|
|
303
|
+
}
|
|
299
304
|
}]);
|
|
300
305
|
}(_types2.SyncBlockDataProvider);
|
|
301
306
|
var useMemoizedSyncedBlockProvider = exports.useMemoizedSyncedBlockProvider = function useMemoizedSyncedBlockProvider(fetchProvider, writeProvider, sourceId, providerOptions, getSSRData) {
|
|
@@ -30,6 +30,10 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
30
30
|
var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
31
31
|
function ReferenceSyncBlockStoreManager(dataProvider, fireAnalyticsEvent) {
|
|
32
32
|
(0, _classCallCheck2.default)(this, ReferenceSyncBlockStoreManager);
|
|
33
|
+
// Keeps track of addition and deletion of reference synced blocks on the document
|
|
34
|
+
// This starts as true to always flush the cache when document is saved for the first time
|
|
35
|
+
// to cater the case when a editor seesion is closed without document being updated right after reference block is deleted
|
|
36
|
+
(0, _defineProperty2.default)(this, "isCacheDirty", true);
|
|
33
37
|
(0, _defineProperty2.default)(this, "isRefreshingSubscriptions", false);
|
|
34
38
|
this.syncBlockCache = new Map();
|
|
35
39
|
this.subscriptions = new Map();
|
|
@@ -327,6 +331,9 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
|
|
|
327
331
|
// add to subscriptions map
|
|
328
332
|
var resourceSubscriptions = this.subscriptions.get(resourceId) || {};
|
|
329
333
|
this.subscriptions.set(resourceId, _objectSpread(_objectSpread({}, resourceSubscriptions), {}, (0, _defineProperty2.default)({}, localId, callback)));
|
|
334
|
+
|
|
335
|
+
// New subscription means new reference synced block is added to the document
|
|
336
|
+
this.isCacheDirty = true;
|
|
330
337
|
var syncBlockNode = (0, _utils.createSyncBlockNode)(localId, resourceId);
|
|
331
338
|
|
|
332
339
|
// call the callback immediately if we have cached data
|
|
@@ -346,6 +353,8 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
|
|
|
346
353
|
return function () {
|
|
347
354
|
var resourceSubscriptions = _this3.subscriptions.get(resourceId);
|
|
348
355
|
if (resourceSubscriptions) {
|
|
356
|
+
// Unsubscription means a reference synced block is removed from the document
|
|
357
|
+
_this3.isCacheDirty = true;
|
|
349
358
|
delete resourceSubscriptions[localId];
|
|
350
359
|
if (Object.keys(resourceSubscriptions).length === 0) {
|
|
351
360
|
_this3.subscriptions.delete(resourceId);
|
|
@@ -515,6 +524,89 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
|
|
|
515
524
|
}
|
|
516
525
|
}
|
|
517
526
|
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Update reference synced blocks on the document with the BE
|
|
530
|
+
*
|
|
531
|
+
* @returns true if the reference synced blocks are updated successfully, false otherwise
|
|
532
|
+
*/
|
|
533
|
+
}, {
|
|
534
|
+
key: "flush",
|
|
535
|
+
value: (function () {
|
|
536
|
+
var _flush = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
|
|
537
|
+
var success, blocks, updateResult, _this$fireAnalyticsEv9, _this$fireAnalyticsEv0;
|
|
538
|
+
return _regenerator.default.wrap(function _callee3$(_context4) {
|
|
539
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
540
|
+
case 0:
|
|
541
|
+
if (this.isCacheDirty) {
|
|
542
|
+
_context4.next = 2;
|
|
543
|
+
break;
|
|
544
|
+
}
|
|
545
|
+
return _context4.abrupt("return", true);
|
|
546
|
+
case 2:
|
|
547
|
+
success = true;
|
|
548
|
+
_context4.prev = 3;
|
|
549
|
+
if (this.dataProvider) {
|
|
550
|
+
_context4.next = 6;
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
553
|
+
throw new Error('Data provider not set');
|
|
554
|
+
case 6:
|
|
555
|
+
blocks = []; // Collect all reference synced blocks on the current document
|
|
556
|
+
Array.from(this.subscriptions.entries()).forEach(function (_ref2) {
|
|
557
|
+
var _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
|
|
558
|
+
resourceId = _ref3[0],
|
|
559
|
+
callbacks = _ref3[1];
|
|
560
|
+
Object.keys(callbacks).forEach(function (localId) {
|
|
561
|
+
blocks.push({
|
|
562
|
+
resourceId: resourceId,
|
|
563
|
+
localId: localId
|
|
564
|
+
});
|
|
565
|
+
});
|
|
566
|
+
});
|
|
567
|
+
if (!(blocks.length === 0)) {
|
|
568
|
+
_context4.next = 10;
|
|
569
|
+
break;
|
|
570
|
+
}
|
|
571
|
+
return _context4.abrupt("return", true);
|
|
572
|
+
case 10:
|
|
573
|
+
_context4.next = 12;
|
|
574
|
+
return this.dataProvider.updateReferenceData(blocks);
|
|
575
|
+
case 12:
|
|
576
|
+
updateResult = _context4.sent;
|
|
577
|
+
if (!updateResult.success) {
|
|
578
|
+
success = false;
|
|
579
|
+
(_this$fireAnalyticsEv9 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv9 === void 0 || _this$fireAnalyticsEv9.call(this, (0, _errorHandling.updateReferenceErrorPayload)(updateResult.error || 'Failed to update reference synced blocks on the document'));
|
|
580
|
+
}
|
|
581
|
+
_context4.next = 21;
|
|
582
|
+
break;
|
|
583
|
+
case 16:
|
|
584
|
+
_context4.prev = 16;
|
|
585
|
+
_context4.t0 = _context4["catch"](3);
|
|
586
|
+
success = false;
|
|
587
|
+
(0, _monitoring.logException)(_context4.t0, {
|
|
588
|
+
location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
|
|
589
|
+
});
|
|
590
|
+
(_this$fireAnalyticsEv0 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv0 === void 0 || _this$fireAnalyticsEv0.call(this, (0, _errorHandling.updateReferenceErrorPayload)(_context4.t0.message));
|
|
591
|
+
case 21:
|
|
592
|
+
_context4.prev = 21;
|
|
593
|
+
if (success) {
|
|
594
|
+
this.isCacheDirty = false;
|
|
595
|
+
}
|
|
596
|
+
return _context4.finish(21);
|
|
597
|
+
case 24:
|
|
598
|
+
return _context4.abrupt("return", success);
|
|
599
|
+
case 25:
|
|
600
|
+
case "end":
|
|
601
|
+
return _context4.stop();
|
|
602
|
+
}
|
|
603
|
+
}, _callee3, this, [[3, 16, 21, 24]]);
|
|
604
|
+
}));
|
|
605
|
+
function flush() {
|
|
606
|
+
return _flush.apply(this, arguments);
|
|
607
|
+
}
|
|
608
|
+
return flush;
|
|
609
|
+
}())
|
|
518
610
|
}, {
|
|
519
611
|
key: "destroy",
|
|
520
612
|
value: function destroy() {
|
|
@@ -12,9 +12,11 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
|
|
|
12
12
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
13
13
|
var _uuid = _interopRequireDefault(require("uuid"));
|
|
14
14
|
var _monitoring = require("@atlaskit/editor-common/monitoring");
|
|
15
|
+
var _types = require("../common/types");
|
|
15
16
|
var _errorHandling = require("../utils/errorHandling");
|
|
16
17
|
var _utils = require("../utils/utils");
|
|
17
|
-
|
|
18
|
+
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; }
|
|
19
|
+
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) { (0, _defineProperty2.default)(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; } // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
18
20
|
// A store manager responsible for the lifecycle and state management of source sync blocks in an editor instance.
|
|
19
21
|
// Designed to manage local in-memory state and synchronize with an external data provider.
|
|
20
22
|
// Supports create, flush, and delete operations for source sync blocks.
|
|
@@ -58,7 +60,9 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
58
60
|
throw new Error('Local ID or resource ID is not set');
|
|
59
61
|
}
|
|
60
62
|
var syncBlockData = (0, _utils.convertSyncBlockPMNodeToSyncBlockData)(syncBlockNode);
|
|
61
|
-
this.syncBlockCache.set(resourceId, syncBlockData)
|
|
63
|
+
this.syncBlockCache.set(resourceId, _objectSpread(_objectSpread({}, syncBlockData), {}, {
|
|
64
|
+
isDirty: true
|
|
65
|
+
}));
|
|
62
66
|
return true;
|
|
63
67
|
} catch (error) {
|
|
64
68
|
var _this$fireAnalyticsEv;
|
|
@@ -95,7 +99,8 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
95
99
|
bodiedSyncBlockData = [];
|
|
96
100
|
Array.from(this.syncBlockCache.values()).forEach(function (syncBlockData) {
|
|
97
101
|
// Don't flush nodes that are waiting to be deleted to avoid nodes being re-created
|
|
98
|
-
|
|
102
|
+
// Don't flush nodes that haven't been updated since we last flushed
|
|
103
|
+
if (!syncBlockData.pendingDeletion && syncBlockData.isDirty) {
|
|
99
104
|
bodiedSyncBlockNodes.push({
|
|
100
105
|
type: 'bodiedSyncBlock',
|
|
101
106
|
attrs: {
|
|
@@ -116,37 +121,46 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
116
121
|
return this.dataProvider.writeNodesData(bodiedSyncBlockNodes, bodiedSyncBlockData);
|
|
117
122
|
case 10:
|
|
118
123
|
writeResults = _context.sent;
|
|
124
|
+
writeResults.forEach(function (result) {
|
|
125
|
+
// set isDirty to false on write success and unrecoverable errors like not found
|
|
126
|
+
if (result.resourceId && (result.error === _types.SyncBlockError.NotFound || !result.error)) {
|
|
127
|
+
var cachedData = _this2.syncBlockCache.get(result.resourceId);
|
|
128
|
+
if (cachedData) {
|
|
129
|
+
cachedData.isDirty = false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
119
133
|
if (!writeResults.every(function (result) {
|
|
120
|
-
return result.resourceId
|
|
134
|
+
return result.resourceId && !result.error;
|
|
121
135
|
})) {
|
|
122
|
-
_context.next =
|
|
136
|
+
_context.next = 16;
|
|
123
137
|
break;
|
|
124
138
|
}
|
|
125
139
|
return _context.abrupt("return", true);
|
|
126
|
-
case
|
|
140
|
+
case 16:
|
|
127
141
|
writeResults.filter(function (result) {
|
|
128
|
-
return result.resourceId
|
|
142
|
+
return !result.resourceId || result.error;
|
|
129
143
|
}).forEach(function (result) {
|
|
130
144
|
var _this2$fireAnalyticsE;
|
|
131
145
|
(_this2$fireAnalyticsE = _this2.fireAnalyticsEvent) === null || _this2$fireAnalyticsE === void 0 || _this2$fireAnalyticsE.call(_this2, (0, _errorHandling.updateErrorPayload)(result.error || 'Failed to write data'));
|
|
132
146
|
});
|
|
133
147
|
return _context.abrupt("return", false);
|
|
134
|
-
case
|
|
135
|
-
_context.next =
|
|
148
|
+
case 18:
|
|
149
|
+
_context.next = 25;
|
|
136
150
|
break;
|
|
137
|
-
case
|
|
138
|
-
_context.prev =
|
|
151
|
+
case 20:
|
|
152
|
+
_context.prev = 20;
|
|
139
153
|
_context.t0 = _context["catch"](0);
|
|
140
154
|
(0, _monitoring.logException)(_context.t0, {
|
|
141
155
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
142
156
|
});
|
|
143
157
|
(_this$fireAnalyticsEv2 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv2 === void 0 || _this$fireAnalyticsEv2.call(this, (0, _errorHandling.updateErrorPayload)(_context.t0.message));
|
|
144
158
|
return _context.abrupt("return", false);
|
|
145
|
-
case
|
|
159
|
+
case 25:
|
|
146
160
|
case "end":
|
|
147
161
|
return _context.stop();
|
|
148
162
|
}
|
|
149
|
-
}, _callee, this, [[0,
|
|
163
|
+
}, _callee, this, [[0, 20]]);
|
|
150
164
|
}));
|
|
151
165
|
function flush() {
|
|
152
166
|
return _flush.apply(this, arguments);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.updateErrorPayload = exports.updateCacheErrorPayload = exports.stringifyError = exports.getSourceInfoErrorPayload = exports.getErrorPayload = exports.fetchErrorPayload = exports.deleteErrorPayload = exports.createErrorPayload = void 0;
|
|
6
|
+
exports.updateReferenceErrorPayload = exports.updateErrorPayload = exports.updateCacheErrorPayload = exports.stringifyError = exports.getSourceInfoErrorPayload = exports.getErrorPayload = exports.fetchErrorPayload = exports.deleteErrorPayload = exports.createErrorPayload = void 0;
|
|
7
7
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
8
8
|
var stringifyError = exports.stringifyError = function stringifyError(error) {
|
|
9
9
|
try {
|
|
@@ -32,6 +32,9 @@ var getSourceInfoErrorPayload = exports.getSourceInfoErrorPayload = function get
|
|
|
32
32
|
var updateErrorPayload = exports.updateErrorPayload = function updateErrorPayload(error) {
|
|
33
33
|
return getErrorPayload(_analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_UPDATE, error);
|
|
34
34
|
};
|
|
35
|
+
var updateReferenceErrorPayload = exports.updateReferenceErrorPayload = function updateReferenceErrorPayload(error) {
|
|
36
|
+
return getErrorPayload(_analytics.ACTION_SUBJECT_ID.REFERENCE_SYNCED_BLOCK_UPDATE, error);
|
|
37
|
+
};
|
|
35
38
|
var createErrorPayload = exports.createErrorPayload = function createErrorPayload(error) {
|
|
36
39
|
return getErrorPayload(_analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_CREATE, error);
|
|
37
40
|
};
|
|
@@ -127,4 +127,23 @@ export const createSyncedBlock = async ({
|
|
|
127
127
|
throw new BlockError(response.status);
|
|
128
128
|
}
|
|
129
129
|
return await response.json();
|
|
130
|
+
};
|
|
131
|
+
export const updateReferenceSyncedBlockOnDocument = async ({
|
|
132
|
+
documentAri,
|
|
133
|
+
blocks,
|
|
134
|
+
noContent = true
|
|
135
|
+
}) => {
|
|
136
|
+
const response = await fetchWithRetry(`${BLOCK_SERVICE_API_URL}/block/document/${encodeURIComponent(documentAri)}/references?noContent=${noContent}`, {
|
|
137
|
+
method: 'PUT',
|
|
138
|
+
headers: COMMON_HEADERS,
|
|
139
|
+
body: JSON.stringify({
|
|
140
|
+
blocks
|
|
141
|
+
})
|
|
142
|
+
});
|
|
143
|
+
if (!response.ok) {
|
|
144
|
+
throw new BlockError(response.status);
|
|
145
|
+
}
|
|
146
|
+
if (!noContent) {
|
|
147
|
+
return await response.json();
|
|
148
|
+
}
|
|
130
149
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable require-unicode-regexp */
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import { generateBlockAri, generateBlockAriFromReference } from '../../clients/block-service/ari';
|
|
4
|
-
import { BlockError, createSyncedBlock, deleteSyncedBlock, getReferenceSyncedBlocks, getSyncedBlockContent, updateSyncedBlock } from '../../clients/block-service/blockService';
|
|
4
|
+
import { BlockError, createSyncedBlock, deleteSyncedBlock, getReferenceSyncedBlocks, getSyncedBlockContent, updateReferenceSyncedBlockOnDocument, updateSyncedBlock } from '../../clients/block-service/blockService';
|
|
5
5
|
import { SyncBlockError } from '../../common/types';
|
|
6
6
|
import { stringifyError } from '../../utils/errorHandling';
|
|
7
7
|
const mapBlockError = error => {
|
|
@@ -212,6 +212,14 @@ class BlockServiceADFWriteProvider {
|
|
|
212
212
|
};
|
|
213
213
|
} catch (error) {
|
|
214
214
|
if (error instanceof BlockError) {
|
|
215
|
+
if (error.status === 404) {
|
|
216
|
+
// User should not be blocked by not_found error when deleting,
|
|
217
|
+
// hence returns successful result for 404 error
|
|
218
|
+
return {
|
|
219
|
+
resourceId,
|
|
220
|
+
success: true
|
|
221
|
+
};
|
|
222
|
+
}
|
|
215
223
|
return {
|
|
216
224
|
resourceId,
|
|
217
225
|
success: false,
|
|
@@ -233,6 +241,31 @@ class BlockServiceADFWriteProvider {
|
|
|
233
241
|
generateResourceId() {
|
|
234
242
|
return crypto.randomUUID();
|
|
235
243
|
}
|
|
244
|
+
async updateReferenceData(blocks, noContent) {
|
|
245
|
+
try {
|
|
246
|
+
await updateReferenceSyncedBlockOnDocument({
|
|
247
|
+
documentAri: this.sourceAri,
|
|
248
|
+
blocks: blocks.map(block => ({
|
|
249
|
+
blockAri: generateBlockAriFromReference(this.sourceAri, block.resourceId),
|
|
250
|
+
blockInstanceId: block.localId
|
|
251
|
+
}), noContent)
|
|
252
|
+
});
|
|
253
|
+
return {
|
|
254
|
+
success: true
|
|
255
|
+
};
|
|
256
|
+
} catch (error) {
|
|
257
|
+
if (error instanceof BlockError) {
|
|
258
|
+
return {
|
|
259
|
+
success: false,
|
|
260
|
+
error: mapBlockError(error)
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
success: false,
|
|
265
|
+
error: stringifyError(error)
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
236
269
|
}
|
|
237
270
|
|
|
238
271
|
/**
|
|
@@ -200,6 +200,9 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
|
200
200
|
throw new Error(`${sourceProduct} source product not supported`);
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
|
+
updateReferenceData(blocks, noContent) {
|
|
204
|
+
return this.writeProvider.updateReferenceData(blocks, noContent);
|
|
205
|
+
}
|
|
203
206
|
}
|
|
204
207
|
export const useMemoizedSyncedBlockProvider = (fetchProvider, writeProvider, sourceId, providerOptions, getSSRData) => {
|
|
205
208
|
return useMemo(() => {
|
|
@@ -2,7 +2,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
2
2
|
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
3
3
|
import { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
|
|
4
4
|
import { SyncBlockError } from '../common/types';
|
|
5
|
-
import { fetchErrorPayload, getSourceInfoErrorPayload } from '../utils/errorHandling';
|
|
5
|
+
import { fetchErrorPayload, getSourceInfoErrorPayload, updateReferenceErrorPayload } from '../utils/errorHandling';
|
|
6
6
|
import { resolveSyncBlockInstance } from '../utils/resolveSyncBlockInstance';
|
|
7
7
|
import { createSyncBlockNode } from '../utils/utils';
|
|
8
8
|
|
|
@@ -13,6 +13,10 @@ import { createSyncBlockNode } from '../utils/utils';
|
|
|
13
13
|
// Can be used in both editor and renderer contexts.
|
|
14
14
|
export class ReferenceSyncBlockStoreManager {
|
|
15
15
|
constructor(dataProvider, fireAnalyticsEvent) {
|
|
16
|
+
// Keeps track of addition and deletion of reference synced blocks on the document
|
|
17
|
+
// This starts as true to always flush the cache when document is saved for the first time
|
|
18
|
+
// to cater the case when a editor seesion is closed without document being updated right after reference block is deleted
|
|
19
|
+
_defineProperty(this, "isCacheDirty", true);
|
|
16
20
|
_defineProperty(this, "isRefreshingSubscriptions", false);
|
|
17
21
|
this.syncBlockCache = new Map();
|
|
18
22
|
this.subscriptions = new Map();
|
|
@@ -212,6 +216,9 @@ export class ReferenceSyncBlockStoreManager {
|
|
|
212
216
|
...resourceSubscriptions,
|
|
213
217
|
[localId]: callback
|
|
214
218
|
});
|
|
219
|
+
|
|
220
|
+
// New subscription means new reference synced block is added to the document
|
|
221
|
+
this.isCacheDirty = true;
|
|
215
222
|
const syncBlockNode = createSyncBlockNode(localId, resourceId);
|
|
216
223
|
|
|
217
224
|
// call the callback immediately if we have cached data
|
|
@@ -231,6 +238,8 @@ export class ReferenceSyncBlockStoreManager {
|
|
|
231
238
|
return () => {
|
|
232
239
|
const resourceSubscriptions = this.subscriptions.get(resourceId);
|
|
233
240
|
if (resourceSubscriptions) {
|
|
241
|
+
// Unsubscription means a reference synced block is removed from the document
|
|
242
|
+
this.isCacheDirty = true;
|
|
234
243
|
delete resourceSubscriptions[localId];
|
|
235
244
|
if (Object.keys(resourceSubscriptions).length === 0) {
|
|
236
245
|
this.subscriptions.delete(resourceId);
|
|
@@ -397,6 +406,55 @@ export class ReferenceSyncBlockStoreManager {
|
|
|
397
406
|
}
|
|
398
407
|
}
|
|
399
408
|
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Update reference synced blocks on the document with the BE
|
|
412
|
+
*
|
|
413
|
+
* @returns true if the reference synced blocks are updated successfully, false otherwise
|
|
414
|
+
*/
|
|
415
|
+
async flush() {
|
|
416
|
+
if (!this.isCacheDirty) {
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
let success = true;
|
|
420
|
+
try {
|
|
421
|
+
if (!this.dataProvider) {
|
|
422
|
+
throw new Error('Data provider not set');
|
|
423
|
+
}
|
|
424
|
+
const blocks = [];
|
|
425
|
+
|
|
426
|
+
// Collect all reference synced blocks on the current document
|
|
427
|
+
Array.from(this.subscriptions.entries()).forEach(([resourceId, callbacks]) => {
|
|
428
|
+
Object.keys(callbacks).forEach(localId => {
|
|
429
|
+
blocks.push({
|
|
430
|
+
resourceId,
|
|
431
|
+
localId
|
|
432
|
+
});
|
|
433
|
+
});
|
|
434
|
+
});
|
|
435
|
+
if (blocks.length === 0) {
|
|
436
|
+
return true;
|
|
437
|
+
}
|
|
438
|
+
const updateResult = await this.dataProvider.updateReferenceData(blocks);
|
|
439
|
+
if (!updateResult.success) {
|
|
440
|
+
var _this$fireAnalyticsEv10;
|
|
441
|
+
success = false;
|
|
442
|
+
(_this$fireAnalyticsEv10 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv10 === void 0 ? void 0 : _this$fireAnalyticsEv10.call(this, updateReferenceErrorPayload(updateResult.error || 'Failed to update reference synced blocks on the document'));
|
|
443
|
+
}
|
|
444
|
+
} catch (error) {
|
|
445
|
+
var _this$fireAnalyticsEv11;
|
|
446
|
+
success = false;
|
|
447
|
+
logException(error, {
|
|
448
|
+
location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
|
|
449
|
+
});
|
|
450
|
+
(_this$fireAnalyticsEv11 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv11 === void 0 ? void 0 : _this$fireAnalyticsEv11.call(this, updateReferenceErrorPayload(error.message));
|
|
451
|
+
} finally {
|
|
452
|
+
if (success) {
|
|
453
|
+
this.isCacheDirty = false;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return success;
|
|
457
|
+
}
|
|
400
458
|
destroy() {
|
|
401
459
|
this.dataProvider = undefined;
|
|
402
460
|
this.syncBlockCache.clear();
|