@atlaskit/editor-synced-block-provider 2.15.5 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/cjs/clients/block-service/blockService.js +33 -25
- package/dist/cjs/providers/block-service/blockServiceAPI.js +35 -30
- package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +23 -15
- package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +10 -3
- package/dist/es2019/clients/block-service/blockService.js +22 -12
- package/dist/es2019/providers/block-service/blockServiceAPI.js +12 -7
- package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +11 -2
- package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +10 -3
- package/dist/esm/clients/block-service/blockService.js +33 -25
- package/dist/esm/providers/block-service/blockServiceAPI.js +35 -30
- package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +23 -15
- package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +10 -3
- package/dist/types/clients/block-service/blockService.d.ts +4 -2
- package/dist/types/providers/block-service/blockServiceAPI.d.ts +3 -2
- package/dist/types-ts4.5/clients/block-service/blockService.d.ts +4 -2
- package/dist/types-ts4.5/providers/block-service/blockServiceAPI.d.ts +3 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @atlaskit/editor-synced-block-provider
|
|
2
2
|
|
|
3
|
+
## 2.16.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`1e626a0fb59a7`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/1e626a0fb59a7) -
|
|
8
|
+
Can pass in get NCS step version function
|
|
9
|
+
|
|
10
|
+
## 2.15.6
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- [`d40079fdeef5d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d40079fdeef5d) -
|
|
15
|
+
EDITOR-4044 Fix a race condition in source sync block dirty tracking logic
|
|
16
|
+
- [`267f0abf6b4cf`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/267f0abf6b4cf) -
|
|
17
|
+
EDITOR-4044 Fix a race condition in reference sync block dirty tracking logic
|
|
18
|
+
- Updated dependencies
|
|
19
|
+
|
|
3
20
|
## 2.15.5
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
@@ -177,27 +177,31 @@ var deleteSyncedBlock = exports.deleteSyncedBlock = /*#__PURE__*/function () {
|
|
|
177
177
|
}();
|
|
178
178
|
var updateSyncedBlock = exports.updateSyncedBlock = /*#__PURE__*/function () {
|
|
179
179
|
var _ref7 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(_ref6) {
|
|
180
|
-
var blockAri, content, response;
|
|
180
|
+
var blockAri, content, stepVersion, requestBody, response;
|
|
181
181
|
return _regenerator.default.wrap(function _callee4$(_context4) {
|
|
182
182
|
while (1) switch (_context4.prev = _context4.next) {
|
|
183
183
|
case 0:
|
|
184
|
-
blockAri = _ref6.blockAri, content = _ref6.content;
|
|
185
|
-
|
|
184
|
+
blockAri = _ref6.blockAri, content = _ref6.content, stepVersion = _ref6.stepVersion;
|
|
185
|
+
requestBody = {
|
|
186
|
+
content: content
|
|
187
|
+
};
|
|
188
|
+
if (stepVersion !== undefined) {
|
|
189
|
+
requestBody.stepVersion = stepVersion;
|
|
190
|
+
}
|
|
191
|
+
_context4.next = 5;
|
|
186
192
|
return (0, _retry.fetchWithRetry)("".concat(BLOCK_SERVICE_API_URL, "/block/").concat(encodeURIComponent(blockAri)), {
|
|
187
193
|
method: 'PUT',
|
|
188
194
|
headers: COMMON_HEADERS,
|
|
189
|
-
body: JSON.stringify(
|
|
190
|
-
content: content
|
|
191
|
-
})
|
|
195
|
+
body: JSON.stringify(requestBody)
|
|
192
196
|
});
|
|
193
|
-
case
|
|
197
|
+
case 5:
|
|
194
198
|
response = _context4.sent;
|
|
195
199
|
if (response.ok) {
|
|
196
|
-
_context4.next =
|
|
200
|
+
_context4.next = 8;
|
|
197
201
|
break;
|
|
198
202
|
}
|
|
199
203
|
throw new BlockError(response.status);
|
|
200
|
-
case
|
|
204
|
+
case 8:
|
|
201
205
|
case "end":
|
|
202
206
|
return _context4.stop();
|
|
203
207
|
}
|
|
@@ -209,36 +213,40 @@ var updateSyncedBlock = exports.updateSyncedBlock = /*#__PURE__*/function () {
|
|
|
209
213
|
}();
|
|
210
214
|
var createSyncedBlock = exports.createSyncedBlock = /*#__PURE__*/function () {
|
|
211
215
|
var _ref9 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(_ref8) {
|
|
212
|
-
var blockAri, blockInstanceId, sourceAri, product, content, response;
|
|
216
|
+
var blockAri, blockInstanceId, sourceAri, product, content, stepVersion, requestBody, response;
|
|
213
217
|
return _regenerator.default.wrap(function _callee5$(_context5) {
|
|
214
218
|
while (1) switch (_context5.prev = _context5.next) {
|
|
215
219
|
case 0:
|
|
216
|
-
blockAri = _ref8.blockAri, blockInstanceId = _ref8.blockInstanceId, sourceAri = _ref8.sourceAri, product = _ref8.product, content = _ref8.content;
|
|
217
|
-
|
|
220
|
+
blockAri = _ref8.blockAri, blockInstanceId = _ref8.blockInstanceId, sourceAri = _ref8.sourceAri, product = _ref8.product, content = _ref8.content, stepVersion = _ref8.stepVersion;
|
|
221
|
+
requestBody = {
|
|
222
|
+
blockAri: blockAri,
|
|
223
|
+
blockInstanceId: blockInstanceId,
|
|
224
|
+
sourceAri: sourceAri,
|
|
225
|
+
product: product,
|
|
226
|
+
content: content
|
|
227
|
+
};
|
|
228
|
+
if (stepVersion !== undefined) {
|
|
229
|
+
requestBody.stepVersion = stepVersion;
|
|
230
|
+
}
|
|
231
|
+
_context5.next = 5;
|
|
218
232
|
return (0, _retry.fetchWithRetry)("".concat(BLOCK_SERVICE_API_URL, "/block"), {
|
|
219
233
|
method: 'POST',
|
|
220
234
|
headers: COMMON_HEADERS,
|
|
221
|
-
body: JSON.stringify(
|
|
222
|
-
blockAri: blockAri,
|
|
223
|
-
blockInstanceId: blockInstanceId,
|
|
224
|
-
sourceAri: sourceAri,
|
|
225
|
-
product: product,
|
|
226
|
-
content: content
|
|
227
|
-
})
|
|
235
|
+
body: JSON.stringify(requestBody)
|
|
228
236
|
});
|
|
229
|
-
case
|
|
237
|
+
case 5:
|
|
230
238
|
response = _context5.sent;
|
|
231
239
|
if (response.ok) {
|
|
232
|
-
_context5.next =
|
|
240
|
+
_context5.next = 8;
|
|
233
241
|
break;
|
|
234
242
|
}
|
|
235
243
|
throw new BlockError(response.status);
|
|
236
|
-
case 6:
|
|
237
|
-
_context5.next = 8;
|
|
238
|
-
return response.json();
|
|
239
244
|
case 8:
|
|
245
|
+
_context5.next = 10;
|
|
246
|
+
return response.json();
|
|
247
|
+
case 10:
|
|
240
248
|
return _context5.abrupt("return", _context5.sent);
|
|
241
|
-
case
|
|
249
|
+
case 11:
|
|
242
250
|
case "end":
|
|
243
251
|
return _context5.stop();
|
|
244
252
|
}
|
|
@@ -196,11 +196,12 @@ var BlockServiceADFFetchProvider = /*#__PURE__*/function () {
|
|
|
196
196
|
* ADFWriteProvider implementation that writes synced block data to Block Service API
|
|
197
197
|
*/
|
|
198
198
|
var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
199
|
-
function BlockServiceADFWriteProvider(sourceAri, product, sourceDocumentId) {
|
|
199
|
+
function BlockServiceADFWriteProvider(sourceAri, product, sourceDocumentId, getVersion) {
|
|
200
200
|
(0, _classCallCheck2.default)(this, BlockServiceADFWriteProvider);
|
|
201
201
|
this.sourceAri = sourceAri;
|
|
202
202
|
this.product = product;
|
|
203
203
|
this.sourceDocumentId = sourceDocumentId;
|
|
204
|
+
this.getVersion = getVersion;
|
|
204
205
|
}
|
|
205
206
|
|
|
206
207
|
// it will first try to update and if it can't (404) then it will try to create
|
|
@@ -208,43 +209,45 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
208
209
|
key: "writeData",
|
|
209
210
|
value: function () {
|
|
210
211
|
var _writeData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(data) {
|
|
211
|
-
var resourceId, blockAri;
|
|
212
|
+
var resourceId, blockAri, stepVersion;
|
|
212
213
|
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
213
214
|
while (1) switch (_context3.prev = _context3.next) {
|
|
214
215
|
case 0:
|
|
215
216
|
resourceId = data.resourceId;
|
|
216
217
|
blockAri = (0, _ari.generateBlockAri)(this.sourceAri, resourceId, this.product);
|
|
217
|
-
|
|
218
|
-
_context3.
|
|
218
|
+
stepVersion = this.getVersion ? this.getVersion() : undefined;
|
|
219
|
+
_context3.prev = 3;
|
|
220
|
+
_context3.next = 6;
|
|
219
221
|
return (0, _blockService.updateSyncedBlock)({
|
|
220
222
|
blockAri: blockAri,
|
|
221
|
-
content: JSON.stringify(data.content)
|
|
223
|
+
content: JSON.stringify(data.content),
|
|
224
|
+
stepVersion: stepVersion
|
|
222
225
|
});
|
|
223
|
-
case
|
|
226
|
+
case 6:
|
|
224
227
|
return _context3.abrupt("return", {
|
|
225
228
|
resourceId: resourceId
|
|
226
229
|
});
|
|
227
|
-
case
|
|
228
|
-
_context3.prev =
|
|
229
|
-
_context3.t0 = _context3["catch"](
|
|
230
|
+
case 9:
|
|
231
|
+
_context3.prev = 9;
|
|
232
|
+
_context3.t0 = _context3["catch"](3);
|
|
230
233
|
if (!(_context3.t0 instanceof _blockService.BlockError)) {
|
|
231
|
-
_context3.next =
|
|
234
|
+
_context3.next = 13;
|
|
232
235
|
break;
|
|
233
236
|
}
|
|
234
237
|
return _context3.abrupt("return", {
|
|
235
238
|
error: mapBlockError(_context3.t0),
|
|
236
239
|
resourceId: resourceId
|
|
237
240
|
});
|
|
238
|
-
case
|
|
241
|
+
case 13:
|
|
239
242
|
return _context3.abrupt("return", {
|
|
240
243
|
error: (0, _errorHandling.stringifyError)(_context3.t0),
|
|
241
244
|
resourceId: resourceId
|
|
242
245
|
});
|
|
243
|
-
case
|
|
246
|
+
case 14:
|
|
244
247
|
case "end":
|
|
245
248
|
return _context3.stop();
|
|
246
249
|
}
|
|
247
|
-
}, _callee3, this, [[
|
|
250
|
+
}, _callee3, this, [[3, 9]]);
|
|
248
251
|
}));
|
|
249
252
|
function writeData(_x3) {
|
|
250
253
|
return _writeData.apply(this, arguments);
|
|
@@ -255,46 +258,48 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
255
258
|
key: "createData",
|
|
256
259
|
value: function () {
|
|
257
260
|
var _createData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(data) {
|
|
258
|
-
var resourceId, blockAri;
|
|
261
|
+
var resourceId, blockAri, stepVersion;
|
|
259
262
|
return _regenerator.default.wrap(function _callee4$(_context4) {
|
|
260
263
|
while (1) switch (_context4.prev = _context4.next) {
|
|
261
264
|
case 0:
|
|
262
265
|
resourceId = data.resourceId;
|
|
263
266
|
blockAri = (0, _ari.generateBlockAri)(this.sourceAri, resourceId, this.product);
|
|
264
|
-
|
|
265
|
-
_context4.
|
|
267
|
+
stepVersion = this.getVersion ? this.getVersion() : undefined;
|
|
268
|
+
_context4.prev = 3;
|
|
269
|
+
_context4.next = 6;
|
|
266
270
|
return (0, _blockService.createSyncedBlock)({
|
|
267
271
|
blockAri: blockAri,
|
|
268
272
|
blockInstanceId: data.blockInstanceId,
|
|
269
273
|
sourceAri: this.sourceAri,
|
|
270
274
|
product: this.product,
|
|
271
|
-
content: JSON.stringify(data.content)
|
|
275
|
+
content: JSON.stringify(data.content),
|
|
276
|
+
stepVersion: stepVersion
|
|
272
277
|
});
|
|
273
|
-
case
|
|
278
|
+
case 6:
|
|
274
279
|
return _context4.abrupt("return", {
|
|
275
280
|
resourceId: resourceId
|
|
276
281
|
});
|
|
277
|
-
case
|
|
278
|
-
_context4.prev =
|
|
279
|
-
_context4.t0 = _context4["catch"](
|
|
282
|
+
case 9:
|
|
283
|
+
_context4.prev = 9;
|
|
284
|
+
_context4.t0 = _context4["catch"](3);
|
|
280
285
|
if (!(_context4.t0 instanceof _blockService.BlockError)) {
|
|
281
|
-
_context4.next =
|
|
286
|
+
_context4.next = 13;
|
|
282
287
|
break;
|
|
283
288
|
}
|
|
284
289
|
return _context4.abrupt("return", {
|
|
285
290
|
error: mapBlockError(_context4.t0),
|
|
286
291
|
resourceId: resourceId
|
|
287
292
|
});
|
|
288
|
-
case
|
|
293
|
+
case 13:
|
|
289
294
|
return _context4.abrupt("return", {
|
|
290
295
|
error: (0, _errorHandling.stringifyError)(_context4.t0),
|
|
291
296
|
resourceId: resourceId
|
|
292
297
|
});
|
|
293
|
-
case
|
|
298
|
+
case 14:
|
|
294
299
|
case "end":
|
|
295
300
|
return _context4.stop();
|
|
296
301
|
}
|
|
297
|
-
}, _callee4, this, [[
|
|
302
|
+
}, _callee4, this, [[3, 9]]);
|
|
298
303
|
}));
|
|
299
304
|
function createData(_x4) {
|
|
300
305
|
return _createData.apply(this, arguments);
|
|
@@ -425,16 +430,16 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
425
430
|
/**
|
|
426
431
|
* Factory function to create both providers with shared configuration
|
|
427
432
|
*/
|
|
428
|
-
var createBlockServiceAPIProviders = function createBlockServiceAPIProviders(sourceAri, product, sourceDocumentId) {
|
|
433
|
+
var createBlockServiceAPIProviders = function createBlockServiceAPIProviders(sourceAri, product, sourceDocumentId, getVersion) {
|
|
429
434
|
var fetchProvider = new BlockServiceADFFetchProvider(sourceAri);
|
|
430
|
-
var writeProvider = new BlockServiceADFWriteProvider(sourceAri, product, sourceDocumentId);
|
|
435
|
+
var writeProvider = new BlockServiceADFWriteProvider(sourceAri, product, sourceDocumentId, getVersion);
|
|
431
436
|
return {
|
|
432
437
|
fetchProvider: fetchProvider,
|
|
433
438
|
writeProvider: writeProvider
|
|
434
439
|
};
|
|
435
440
|
};
|
|
436
|
-
var useMemoizedBlockServiceAPIProviders = exports.useMemoizedBlockServiceAPIProviders = function useMemoizedBlockServiceAPIProviders(sourceAri, product, sourceDocumentId) {
|
|
441
|
+
var useMemoizedBlockServiceAPIProviders = exports.useMemoizedBlockServiceAPIProviders = function useMemoizedBlockServiceAPIProviders(sourceAri, product, sourceDocumentId, getVersion) {
|
|
437
442
|
return (0, _react.useMemo)(function () {
|
|
438
|
-
return createBlockServiceAPIProviders(sourceAri, product, sourceDocumentId);
|
|
439
|
-
}, [sourceAri, product, sourceDocumentId]);
|
|
443
|
+
return createBlockServiceAPIProviders(sourceAri, product, sourceDocumentId, getVersion);
|
|
444
|
+
}, [sourceAri, product, sourceDocumentId, getVersion]);
|
|
440
445
|
};
|
|
@@ -574,42 +574,50 @@ var ReferenceSyncBlockStoreManager = exports.ReferenceSyncBlockStoreManager = /*
|
|
|
574
574
|
});
|
|
575
575
|
});
|
|
576
576
|
if (!(blocks.length === 0)) {
|
|
577
|
-
_context4.next =
|
|
577
|
+
_context4.next = 11;
|
|
578
578
|
break;
|
|
579
579
|
}
|
|
580
|
+
this.isCacheDirty = false;
|
|
580
581
|
return _context4.abrupt("return", true);
|
|
581
|
-
case
|
|
582
|
-
|
|
582
|
+
case 11:
|
|
583
|
+
// reset isCacheDirty early to prevent race condition
|
|
584
|
+
// There is a race condition where if a user makes changes (create/delete) to a reference sync block
|
|
585
|
+
// on a live page and the reference sync block is being saved while the user
|
|
586
|
+
// is still making changes, the new changes might not be saved if they all happen
|
|
587
|
+
// exactly at a time when the updateReferenceData is being executed asynchronously.
|
|
588
|
+
this.isCacheDirty = false;
|
|
589
|
+
_context4.next = 14;
|
|
583
590
|
return this.dataProvider.updateReferenceData(blocks);
|
|
584
|
-
case
|
|
591
|
+
case 14:
|
|
585
592
|
updateResult = _context4.sent;
|
|
586
593
|
if (!updateResult.success) {
|
|
587
594
|
success = false;
|
|
588
595
|
(_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'));
|
|
589
596
|
}
|
|
590
|
-
_context4.next =
|
|
597
|
+
_context4.next = 23;
|
|
591
598
|
break;
|
|
592
|
-
case
|
|
593
|
-
_context4.prev =
|
|
599
|
+
case 18:
|
|
600
|
+
_context4.prev = 18;
|
|
594
601
|
_context4.t0 = _context4["catch"](3);
|
|
595
602
|
success = false;
|
|
596
603
|
(0, _monitoring.logException)(_context4.t0, {
|
|
597
604
|
location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
|
|
598
605
|
});
|
|
599
606
|
(_this$fireAnalyticsEv0 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv0 === void 0 || _this$fireAnalyticsEv0.call(this, (0, _errorHandling.updateReferenceErrorPayload)(_context4.t0.message));
|
|
600
|
-
case
|
|
601
|
-
_context4.prev =
|
|
602
|
-
if (success) {
|
|
603
|
-
|
|
607
|
+
case 23:
|
|
608
|
+
_context4.prev = 23;
|
|
609
|
+
if (!success) {
|
|
610
|
+
// set isCacheDirty back to true for cases where it failed to update the reference synced blocks on the BE
|
|
611
|
+
this.isCacheDirty = true;
|
|
604
612
|
}
|
|
605
|
-
return _context4.finish(
|
|
606
|
-
case
|
|
613
|
+
return _context4.finish(23);
|
|
614
|
+
case 26:
|
|
607
615
|
return _context4.abrupt("return", success);
|
|
608
|
-
case
|
|
616
|
+
case 27:
|
|
609
617
|
case "end":
|
|
610
618
|
return _context4.stop();
|
|
611
619
|
}
|
|
612
|
-
}, _callee3, this, [[3,
|
|
620
|
+
}, _callee3, this, [[3, 18, 23, 26]]);
|
|
613
621
|
}));
|
|
614
622
|
function flush() {
|
|
615
623
|
return _flush.apply(this, arguments);
|
|
@@ -109,6 +109,13 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
109
109
|
}
|
|
110
110
|
});
|
|
111
111
|
bodiedSyncBlockData.push(syncBlockData);
|
|
112
|
+
|
|
113
|
+
// reset isDirty early to prevent race condition
|
|
114
|
+
// There is a race condition where if a user makes changes to a source sync block
|
|
115
|
+
// on a live page and the source sync block is being saved while the user
|
|
116
|
+
// is still making changes, the new changes might not be saved if they all happen
|
|
117
|
+
// exactly at a time when the writeNodesData is being executed asynchronously.
|
|
118
|
+
syncBlockData.isDirty = false;
|
|
112
119
|
}
|
|
113
120
|
});
|
|
114
121
|
if (!(bodiedSyncBlockNodes.length === 0)) {
|
|
@@ -122,11 +129,11 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
122
129
|
case 10:
|
|
123
130
|
writeResults = _context.sent;
|
|
124
131
|
writeResults.forEach(function (result) {
|
|
125
|
-
// set isDirty to
|
|
126
|
-
if (result.resourceId &&
|
|
132
|
+
// set isDirty to true for cases where it failed to save the sync block to the BE
|
|
133
|
+
if (result.resourceId && result.error && result.error !== _types.SyncBlockError.NotFound) {
|
|
127
134
|
var cachedData = _this2.syncBlockCache.get(result.resourceId);
|
|
128
135
|
if (cachedData) {
|
|
129
|
-
cachedData.isDirty =
|
|
136
|
+
cachedData.isDirty = true;
|
|
130
137
|
}
|
|
131
138
|
}
|
|
132
139
|
});
|
|
@@ -92,14 +92,19 @@ export const deleteSyncedBlock = async ({
|
|
|
92
92
|
};
|
|
93
93
|
export const updateSyncedBlock = async ({
|
|
94
94
|
blockAri,
|
|
95
|
-
content
|
|
95
|
+
content,
|
|
96
|
+
stepVersion
|
|
96
97
|
}) => {
|
|
98
|
+
const requestBody = {
|
|
99
|
+
content
|
|
100
|
+
};
|
|
101
|
+
if (stepVersion !== undefined) {
|
|
102
|
+
requestBody.stepVersion = stepVersion;
|
|
103
|
+
}
|
|
97
104
|
const response = await fetchWithRetry(`${BLOCK_SERVICE_API_URL}/block/${encodeURIComponent(blockAri)}`, {
|
|
98
105
|
method: 'PUT',
|
|
99
106
|
headers: COMMON_HEADERS,
|
|
100
|
-
body: JSON.stringify(
|
|
101
|
-
content
|
|
102
|
-
})
|
|
107
|
+
body: JSON.stringify(requestBody)
|
|
103
108
|
});
|
|
104
109
|
if (!response.ok) {
|
|
105
110
|
throw new BlockError(response.status);
|
|
@@ -110,18 +115,23 @@ export const createSyncedBlock = async ({
|
|
|
110
115
|
blockInstanceId,
|
|
111
116
|
sourceAri,
|
|
112
117
|
product,
|
|
113
|
-
content
|
|
118
|
+
content,
|
|
119
|
+
stepVersion
|
|
114
120
|
}) => {
|
|
121
|
+
const requestBody = {
|
|
122
|
+
blockAri,
|
|
123
|
+
blockInstanceId,
|
|
124
|
+
sourceAri,
|
|
125
|
+
product,
|
|
126
|
+
content
|
|
127
|
+
};
|
|
128
|
+
if (stepVersion !== undefined) {
|
|
129
|
+
requestBody.stepVersion = stepVersion;
|
|
130
|
+
}
|
|
115
131
|
const response = await fetchWithRetry(`${BLOCK_SERVICE_API_URL}/block`, {
|
|
116
132
|
method: 'POST',
|
|
117
133
|
headers: COMMON_HEADERS,
|
|
118
|
-
body: JSON.stringify(
|
|
119
|
-
blockAri,
|
|
120
|
-
blockInstanceId,
|
|
121
|
-
sourceAri,
|
|
122
|
-
product,
|
|
123
|
-
content
|
|
124
|
-
})
|
|
134
|
+
body: JSON.stringify(requestBody)
|
|
125
135
|
});
|
|
126
136
|
if (!response.ok) {
|
|
127
137
|
throw new BlockError(response.status);
|
|
@@ -134,10 +134,11 @@ class BlockServiceADFFetchProvider {
|
|
|
134
134
|
* ADFWriteProvider implementation that writes synced block data to Block Service API
|
|
135
135
|
*/
|
|
136
136
|
class BlockServiceADFWriteProvider {
|
|
137
|
-
constructor(sourceAri, product, sourceDocumentId) {
|
|
137
|
+
constructor(sourceAri, product, sourceDocumentId, getVersion) {
|
|
138
138
|
this.sourceAri = sourceAri;
|
|
139
139
|
this.product = product;
|
|
140
140
|
this.sourceDocumentId = sourceDocumentId;
|
|
141
|
+
this.getVersion = getVersion;
|
|
141
142
|
}
|
|
142
143
|
|
|
143
144
|
// it will first try to update and if it can't (404) then it will try to create
|
|
@@ -146,11 +147,13 @@ class BlockServiceADFWriteProvider {
|
|
|
146
147
|
resourceId
|
|
147
148
|
} = data;
|
|
148
149
|
const blockAri = generateBlockAri(this.sourceAri, resourceId, this.product);
|
|
150
|
+
const stepVersion = this.getVersion ? this.getVersion() : undefined;
|
|
149
151
|
try {
|
|
150
152
|
// Try update existing block's content
|
|
151
153
|
await updateSyncedBlock({
|
|
152
154
|
blockAri,
|
|
153
|
-
content: JSON.stringify(data.content)
|
|
155
|
+
content: JSON.stringify(data.content),
|
|
156
|
+
stepVersion
|
|
154
157
|
});
|
|
155
158
|
return {
|
|
156
159
|
resourceId
|
|
@@ -173,13 +176,15 @@ class BlockServiceADFWriteProvider {
|
|
|
173
176
|
resourceId
|
|
174
177
|
} = data;
|
|
175
178
|
const blockAri = generateBlockAri(this.sourceAri, resourceId, this.product);
|
|
179
|
+
const stepVersion = this.getVersion ? this.getVersion() : undefined;
|
|
176
180
|
try {
|
|
177
181
|
await createSyncedBlock({
|
|
178
182
|
blockAri,
|
|
179
183
|
blockInstanceId: data.blockInstanceId,
|
|
180
184
|
sourceAri: this.sourceAri,
|
|
181
185
|
product: this.product,
|
|
182
|
-
content: JSON.stringify(data.content)
|
|
186
|
+
content: JSON.stringify(data.content),
|
|
187
|
+
stepVersion
|
|
183
188
|
});
|
|
184
189
|
return {
|
|
185
190
|
resourceId
|
|
@@ -272,14 +277,14 @@ class BlockServiceADFWriteProvider {
|
|
|
272
277
|
/**
|
|
273
278
|
* Factory function to create both providers with shared configuration
|
|
274
279
|
*/
|
|
275
|
-
const createBlockServiceAPIProviders = (sourceAri, product, sourceDocumentId) => {
|
|
280
|
+
const createBlockServiceAPIProviders = (sourceAri, product, sourceDocumentId, getVersion) => {
|
|
276
281
|
const fetchProvider = new BlockServiceADFFetchProvider(sourceAri);
|
|
277
|
-
const writeProvider = new BlockServiceADFWriteProvider(sourceAri, product, sourceDocumentId);
|
|
282
|
+
const writeProvider = new BlockServiceADFWriteProvider(sourceAri, product, sourceDocumentId, getVersion);
|
|
278
283
|
return {
|
|
279
284
|
fetchProvider,
|
|
280
285
|
writeProvider
|
|
281
286
|
};
|
|
282
287
|
};
|
|
283
|
-
export const useMemoizedBlockServiceAPIProviders = (sourceAri, product, sourceDocumentId) => {
|
|
284
|
-
return useMemo(() => createBlockServiceAPIProviders(sourceAri, product, sourceDocumentId), [sourceAri, product, sourceDocumentId]);
|
|
288
|
+
export const useMemoizedBlockServiceAPIProviders = (sourceAri, product, sourceDocumentId, getVersion) => {
|
|
289
|
+
return useMemo(() => createBlockServiceAPIProviders(sourceAri, product, sourceDocumentId, getVersion), [sourceAri, product, sourceDocumentId, getVersion]);
|
|
285
290
|
};
|
|
@@ -441,8 +441,16 @@ export class ReferenceSyncBlockStoreManager {
|
|
|
441
441
|
});
|
|
442
442
|
});
|
|
443
443
|
if (blocks.length === 0) {
|
|
444
|
+
this.isCacheDirty = false;
|
|
444
445
|
return true;
|
|
445
446
|
}
|
|
447
|
+
|
|
448
|
+
// reset isCacheDirty early to prevent race condition
|
|
449
|
+
// There is a race condition where if a user makes changes (create/delete) to a reference sync block
|
|
450
|
+
// on a live page and the reference sync block is being saved while the user
|
|
451
|
+
// is still making changes, the new changes might not be saved if they all happen
|
|
452
|
+
// exactly at a time when the updateReferenceData is being executed asynchronously.
|
|
453
|
+
this.isCacheDirty = false;
|
|
446
454
|
const updateResult = await this.dataProvider.updateReferenceData(blocks);
|
|
447
455
|
if (!updateResult.success) {
|
|
448
456
|
var _this$fireAnalyticsEv10;
|
|
@@ -457,8 +465,9 @@ export class ReferenceSyncBlockStoreManager {
|
|
|
457
465
|
});
|
|
458
466
|
(_this$fireAnalyticsEv11 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv11 === void 0 ? void 0 : _this$fireAnalyticsEv11.call(this, updateReferenceErrorPayload(error.message));
|
|
459
467
|
} finally {
|
|
460
|
-
if (success) {
|
|
461
|
-
|
|
468
|
+
if (!success) {
|
|
469
|
+
// set isCacheDirty back to true for cases where it failed to update the reference synced blocks on the BE
|
|
470
|
+
this.isCacheDirty = true;
|
|
462
471
|
}
|
|
463
472
|
}
|
|
464
473
|
return success;
|
|
@@ -82,6 +82,13 @@ export class SourceSyncBlockStoreManager {
|
|
|
82
82
|
}
|
|
83
83
|
});
|
|
84
84
|
bodiedSyncBlockData.push(syncBlockData);
|
|
85
|
+
|
|
86
|
+
// reset isDirty early to prevent race condition
|
|
87
|
+
// There is a race condition where if a user makes changes to a source sync block
|
|
88
|
+
// on a live page and the source sync block is being saved while the user
|
|
89
|
+
// is still making changes, the new changes might not be saved if they all happen
|
|
90
|
+
// exactly at a time when the writeNodesData is being executed asynchronously.
|
|
91
|
+
syncBlockData.isDirty = false;
|
|
85
92
|
}
|
|
86
93
|
});
|
|
87
94
|
if (bodiedSyncBlockNodes.length === 0) {
|
|
@@ -89,11 +96,11 @@ export class SourceSyncBlockStoreManager {
|
|
|
89
96
|
}
|
|
90
97
|
const writeResults = await this.dataProvider.writeNodesData(bodiedSyncBlockNodes, bodiedSyncBlockData);
|
|
91
98
|
writeResults.forEach(result => {
|
|
92
|
-
// set isDirty to
|
|
93
|
-
if (result.resourceId &&
|
|
99
|
+
// set isDirty to true for cases where it failed to save the sync block to the BE
|
|
100
|
+
if (result.resourceId && result.error && result.error !== SyncBlockError.NotFound) {
|
|
94
101
|
const cachedData = this.syncBlockCache.get(result.resourceId);
|
|
95
102
|
if (cachedData) {
|
|
96
|
-
cachedData.isDirty =
|
|
103
|
+
cachedData.isDirty = true;
|
|
97
104
|
}
|
|
98
105
|
}
|
|
99
106
|
});
|
|
@@ -170,27 +170,31 @@ export var deleteSyncedBlock = /*#__PURE__*/function () {
|
|
|
170
170
|
}();
|
|
171
171
|
export var updateSyncedBlock = /*#__PURE__*/function () {
|
|
172
172
|
var _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(_ref6) {
|
|
173
|
-
var blockAri, content, response;
|
|
173
|
+
var blockAri, content, stepVersion, requestBody, response;
|
|
174
174
|
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
|
|
175
175
|
while (1) switch (_context4.prev = _context4.next) {
|
|
176
176
|
case 0:
|
|
177
|
-
blockAri = _ref6.blockAri, content = _ref6.content;
|
|
178
|
-
|
|
177
|
+
blockAri = _ref6.blockAri, content = _ref6.content, stepVersion = _ref6.stepVersion;
|
|
178
|
+
requestBody = {
|
|
179
|
+
content: content
|
|
180
|
+
};
|
|
181
|
+
if (stepVersion !== undefined) {
|
|
182
|
+
requestBody.stepVersion = stepVersion;
|
|
183
|
+
}
|
|
184
|
+
_context4.next = 5;
|
|
179
185
|
return fetchWithRetry("".concat(BLOCK_SERVICE_API_URL, "/block/").concat(encodeURIComponent(blockAri)), {
|
|
180
186
|
method: 'PUT',
|
|
181
187
|
headers: COMMON_HEADERS,
|
|
182
|
-
body: JSON.stringify(
|
|
183
|
-
content: content
|
|
184
|
-
})
|
|
188
|
+
body: JSON.stringify(requestBody)
|
|
185
189
|
});
|
|
186
|
-
case
|
|
190
|
+
case 5:
|
|
187
191
|
response = _context4.sent;
|
|
188
192
|
if (response.ok) {
|
|
189
|
-
_context4.next =
|
|
193
|
+
_context4.next = 8;
|
|
190
194
|
break;
|
|
191
195
|
}
|
|
192
196
|
throw new BlockError(response.status);
|
|
193
|
-
case
|
|
197
|
+
case 8:
|
|
194
198
|
case "end":
|
|
195
199
|
return _context4.stop();
|
|
196
200
|
}
|
|
@@ -202,36 +206,40 @@ export var updateSyncedBlock = /*#__PURE__*/function () {
|
|
|
202
206
|
}();
|
|
203
207
|
export var createSyncedBlock = /*#__PURE__*/function () {
|
|
204
208
|
var _ref9 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(_ref8) {
|
|
205
|
-
var blockAri, blockInstanceId, sourceAri, product, content, response;
|
|
209
|
+
var blockAri, blockInstanceId, sourceAri, product, content, stepVersion, requestBody, response;
|
|
206
210
|
return _regeneratorRuntime.wrap(function _callee5$(_context5) {
|
|
207
211
|
while (1) switch (_context5.prev = _context5.next) {
|
|
208
212
|
case 0:
|
|
209
|
-
blockAri = _ref8.blockAri, blockInstanceId = _ref8.blockInstanceId, sourceAri = _ref8.sourceAri, product = _ref8.product, content = _ref8.content;
|
|
210
|
-
|
|
213
|
+
blockAri = _ref8.blockAri, blockInstanceId = _ref8.blockInstanceId, sourceAri = _ref8.sourceAri, product = _ref8.product, content = _ref8.content, stepVersion = _ref8.stepVersion;
|
|
214
|
+
requestBody = {
|
|
215
|
+
blockAri: blockAri,
|
|
216
|
+
blockInstanceId: blockInstanceId,
|
|
217
|
+
sourceAri: sourceAri,
|
|
218
|
+
product: product,
|
|
219
|
+
content: content
|
|
220
|
+
};
|
|
221
|
+
if (stepVersion !== undefined) {
|
|
222
|
+
requestBody.stepVersion = stepVersion;
|
|
223
|
+
}
|
|
224
|
+
_context5.next = 5;
|
|
211
225
|
return fetchWithRetry("".concat(BLOCK_SERVICE_API_URL, "/block"), {
|
|
212
226
|
method: 'POST',
|
|
213
227
|
headers: COMMON_HEADERS,
|
|
214
|
-
body: JSON.stringify(
|
|
215
|
-
blockAri: blockAri,
|
|
216
|
-
blockInstanceId: blockInstanceId,
|
|
217
|
-
sourceAri: sourceAri,
|
|
218
|
-
product: product,
|
|
219
|
-
content: content
|
|
220
|
-
})
|
|
228
|
+
body: JSON.stringify(requestBody)
|
|
221
229
|
});
|
|
222
|
-
case
|
|
230
|
+
case 5:
|
|
223
231
|
response = _context5.sent;
|
|
224
232
|
if (response.ok) {
|
|
225
|
-
_context5.next =
|
|
233
|
+
_context5.next = 8;
|
|
226
234
|
break;
|
|
227
235
|
}
|
|
228
236
|
throw new BlockError(response.status);
|
|
229
|
-
case 6:
|
|
230
|
-
_context5.next = 8;
|
|
231
|
-
return response.json();
|
|
232
237
|
case 8:
|
|
238
|
+
_context5.next = 10;
|
|
239
|
+
return response.json();
|
|
240
|
+
case 10:
|
|
233
241
|
return _context5.abrupt("return", _context5.sent);
|
|
234
|
-
case
|
|
242
|
+
case 11:
|
|
235
243
|
case "end":
|
|
236
244
|
return _context5.stop();
|
|
237
245
|
}
|
|
@@ -188,11 +188,12 @@ var BlockServiceADFFetchProvider = /*#__PURE__*/function () {
|
|
|
188
188
|
* ADFWriteProvider implementation that writes synced block data to Block Service API
|
|
189
189
|
*/
|
|
190
190
|
var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
191
|
-
function BlockServiceADFWriteProvider(sourceAri, product, sourceDocumentId) {
|
|
191
|
+
function BlockServiceADFWriteProvider(sourceAri, product, sourceDocumentId, getVersion) {
|
|
192
192
|
_classCallCheck(this, BlockServiceADFWriteProvider);
|
|
193
193
|
this.sourceAri = sourceAri;
|
|
194
194
|
this.product = product;
|
|
195
195
|
this.sourceDocumentId = sourceDocumentId;
|
|
196
|
+
this.getVersion = getVersion;
|
|
196
197
|
}
|
|
197
198
|
|
|
198
199
|
// it will first try to update and if it can't (404) then it will try to create
|
|
@@ -200,43 +201,45 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
200
201
|
key: "writeData",
|
|
201
202
|
value: function () {
|
|
202
203
|
var _writeData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(data) {
|
|
203
|
-
var resourceId, blockAri;
|
|
204
|
+
var resourceId, blockAri, stepVersion;
|
|
204
205
|
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
205
206
|
while (1) switch (_context3.prev = _context3.next) {
|
|
206
207
|
case 0:
|
|
207
208
|
resourceId = data.resourceId;
|
|
208
209
|
blockAri = generateBlockAri(this.sourceAri, resourceId, this.product);
|
|
209
|
-
|
|
210
|
-
_context3.
|
|
210
|
+
stepVersion = this.getVersion ? this.getVersion() : undefined;
|
|
211
|
+
_context3.prev = 3;
|
|
212
|
+
_context3.next = 6;
|
|
211
213
|
return updateSyncedBlock({
|
|
212
214
|
blockAri: blockAri,
|
|
213
|
-
content: JSON.stringify(data.content)
|
|
215
|
+
content: JSON.stringify(data.content),
|
|
216
|
+
stepVersion: stepVersion
|
|
214
217
|
});
|
|
215
|
-
case
|
|
218
|
+
case 6:
|
|
216
219
|
return _context3.abrupt("return", {
|
|
217
220
|
resourceId: resourceId
|
|
218
221
|
});
|
|
219
|
-
case
|
|
220
|
-
_context3.prev =
|
|
221
|
-
_context3.t0 = _context3["catch"](
|
|
222
|
+
case 9:
|
|
223
|
+
_context3.prev = 9;
|
|
224
|
+
_context3.t0 = _context3["catch"](3);
|
|
222
225
|
if (!(_context3.t0 instanceof BlockError)) {
|
|
223
|
-
_context3.next =
|
|
226
|
+
_context3.next = 13;
|
|
224
227
|
break;
|
|
225
228
|
}
|
|
226
229
|
return _context3.abrupt("return", {
|
|
227
230
|
error: mapBlockError(_context3.t0),
|
|
228
231
|
resourceId: resourceId
|
|
229
232
|
});
|
|
230
|
-
case
|
|
233
|
+
case 13:
|
|
231
234
|
return _context3.abrupt("return", {
|
|
232
235
|
error: stringifyError(_context3.t0),
|
|
233
236
|
resourceId: resourceId
|
|
234
237
|
});
|
|
235
|
-
case
|
|
238
|
+
case 14:
|
|
236
239
|
case "end":
|
|
237
240
|
return _context3.stop();
|
|
238
241
|
}
|
|
239
|
-
}, _callee3, this, [[
|
|
242
|
+
}, _callee3, this, [[3, 9]]);
|
|
240
243
|
}));
|
|
241
244
|
function writeData(_x3) {
|
|
242
245
|
return _writeData.apply(this, arguments);
|
|
@@ -247,46 +250,48 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
247
250
|
key: "createData",
|
|
248
251
|
value: function () {
|
|
249
252
|
var _createData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(data) {
|
|
250
|
-
var resourceId, blockAri;
|
|
253
|
+
var resourceId, blockAri, stepVersion;
|
|
251
254
|
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
|
|
252
255
|
while (1) switch (_context4.prev = _context4.next) {
|
|
253
256
|
case 0:
|
|
254
257
|
resourceId = data.resourceId;
|
|
255
258
|
blockAri = generateBlockAri(this.sourceAri, resourceId, this.product);
|
|
256
|
-
|
|
257
|
-
_context4.
|
|
259
|
+
stepVersion = this.getVersion ? this.getVersion() : undefined;
|
|
260
|
+
_context4.prev = 3;
|
|
261
|
+
_context4.next = 6;
|
|
258
262
|
return createSyncedBlock({
|
|
259
263
|
blockAri: blockAri,
|
|
260
264
|
blockInstanceId: data.blockInstanceId,
|
|
261
265
|
sourceAri: this.sourceAri,
|
|
262
266
|
product: this.product,
|
|
263
|
-
content: JSON.stringify(data.content)
|
|
267
|
+
content: JSON.stringify(data.content),
|
|
268
|
+
stepVersion: stepVersion
|
|
264
269
|
});
|
|
265
|
-
case
|
|
270
|
+
case 6:
|
|
266
271
|
return _context4.abrupt("return", {
|
|
267
272
|
resourceId: resourceId
|
|
268
273
|
});
|
|
269
|
-
case
|
|
270
|
-
_context4.prev =
|
|
271
|
-
_context4.t0 = _context4["catch"](
|
|
274
|
+
case 9:
|
|
275
|
+
_context4.prev = 9;
|
|
276
|
+
_context4.t0 = _context4["catch"](3);
|
|
272
277
|
if (!(_context4.t0 instanceof BlockError)) {
|
|
273
|
-
_context4.next =
|
|
278
|
+
_context4.next = 13;
|
|
274
279
|
break;
|
|
275
280
|
}
|
|
276
281
|
return _context4.abrupt("return", {
|
|
277
282
|
error: mapBlockError(_context4.t0),
|
|
278
283
|
resourceId: resourceId
|
|
279
284
|
});
|
|
280
|
-
case
|
|
285
|
+
case 13:
|
|
281
286
|
return _context4.abrupt("return", {
|
|
282
287
|
error: stringifyError(_context4.t0),
|
|
283
288
|
resourceId: resourceId
|
|
284
289
|
});
|
|
285
|
-
case
|
|
290
|
+
case 14:
|
|
286
291
|
case "end":
|
|
287
292
|
return _context4.stop();
|
|
288
293
|
}
|
|
289
|
-
}, _callee4, this, [[
|
|
294
|
+
}, _callee4, this, [[3, 9]]);
|
|
290
295
|
}));
|
|
291
296
|
function createData(_x4) {
|
|
292
297
|
return _createData.apply(this, arguments);
|
|
@@ -417,16 +422,16 @@ var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
417
422
|
/**
|
|
418
423
|
* Factory function to create both providers with shared configuration
|
|
419
424
|
*/
|
|
420
|
-
var createBlockServiceAPIProviders = function createBlockServiceAPIProviders(sourceAri, product, sourceDocumentId) {
|
|
425
|
+
var createBlockServiceAPIProviders = function createBlockServiceAPIProviders(sourceAri, product, sourceDocumentId, getVersion) {
|
|
421
426
|
var fetchProvider = new BlockServiceADFFetchProvider(sourceAri);
|
|
422
|
-
var writeProvider = new BlockServiceADFWriteProvider(sourceAri, product, sourceDocumentId);
|
|
427
|
+
var writeProvider = new BlockServiceADFWriteProvider(sourceAri, product, sourceDocumentId, getVersion);
|
|
423
428
|
return {
|
|
424
429
|
fetchProvider: fetchProvider,
|
|
425
430
|
writeProvider: writeProvider
|
|
426
431
|
};
|
|
427
432
|
};
|
|
428
|
-
export var useMemoizedBlockServiceAPIProviders = function useMemoizedBlockServiceAPIProviders(sourceAri, product, sourceDocumentId) {
|
|
433
|
+
export var useMemoizedBlockServiceAPIProviders = function useMemoizedBlockServiceAPIProviders(sourceAri, product, sourceDocumentId, getVersion) {
|
|
429
434
|
return useMemo(function () {
|
|
430
|
-
return createBlockServiceAPIProviders(sourceAri, product, sourceDocumentId);
|
|
431
|
-
}, [sourceAri, product, sourceDocumentId]);
|
|
435
|
+
return createBlockServiceAPIProviders(sourceAri, product, sourceDocumentId, getVersion);
|
|
436
|
+
}, [sourceAri, product, sourceDocumentId, getVersion]);
|
|
432
437
|
};
|
|
@@ -568,42 +568,50 @@ export var ReferenceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
568
568
|
});
|
|
569
569
|
});
|
|
570
570
|
if (!(blocks.length === 0)) {
|
|
571
|
-
_context4.next =
|
|
571
|
+
_context4.next = 11;
|
|
572
572
|
break;
|
|
573
573
|
}
|
|
574
|
+
this.isCacheDirty = false;
|
|
574
575
|
return _context4.abrupt("return", true);
|
|
575
|
-
case
|
|
576
|
-
|
|
576
|
+
case 11:
|
|
577
|
+
// reset isCacheDirty early to prevent race condition
|
|
578
|
+
// There is a race condition where if a user makes changes (create/delete) to a reference sync block
|
|
579
|
+
// on a live page and the reference sync block is being saved while the user
|
|
580
|
+
// is still making changes, the new changes might not be saved if they all happen
|
|
581
|
+
// exactly at a time when the updateReferenceData is being executed asynchronously.
|
|
582
|
+
this.isCacheDirty = false;
|
|
583
|
+
_context4.next = 14;
|
|
577
584
|
return this.dataProvider.updateReferenceData(blocks);
|
|
578
|
-
case
|
|
585
|
+
case 14:
|
|
579
586
|
updateResult = _context4.sent;
|
|
580
587
|
if (!updateResult.success) {
|
|
581
588
|
success = false;
|
|
582
589
|
(_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'));
|
|
583
590
|
}
|
|
584
|
-
_context4.next =
|
|
591
|
+
_context4.next = 23;
|
|
585
592
|
break;
|
|
586
|
-
case
|
|
587
|
-
_context4.prev =
|
|
593
|
+
case 18:
|
|
594
|
+
_context4.prev = 18;
|
|
588
595
|
_context4.t0 = _context4["catch"](3);
|
|
589
596
|
success = false;
|
|
590
597
|
logException(_context4.t0, {
|
|
591
598
|
location: 'editor-synced-block-provider/referenceSyncBlockStoreManager'
|
|
592
599
|
});
|
|
593
600
|
(_this$fireAnalyticsEv0 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv0 === void 0 || _this$fireAnalyticsEv0.call(this, updateReferenceErrorPayload(_context4.t0.message));
|
|
594
|
-
case
|
|
595
|
-
_context4.prev =
|
|
596
|
-
if (success) {
|
|
597
|
-
|
|
601
|
+
case 23:
|
|
602
|
+
_context4.prev = 23;
|
|
603
|
+
if (!success) {
|
|
604
|
+
// set isCacheDirty back to true for cases where it failed to update the reference synced blocks on the BE
|
|
605
|
+
this.isCacheDirty = true;
|
|
598
606
|
}
|
|
599
|
-
return _context4.finish(
|
|
600
|
-
case
|
|
607
|
+
return _context4.finish(23);
|
|
608
|
+
case 26:
|
|
601
609
|
return _context4.abrupt("return", success);
|
|
602
|
-
case
|
|
610
|
+
case 27:
|
|
603
611
|
case "end":
|
|
604
612
|
return _context4.stop();
|
|
605
613
|
}
|
|
606
|
-
}, _callee3, this, [[3,
|
|
614
|
+
}, _callee3, this, [[3, 18, 23, 26]]);
|
|
607
615
|
}));
|
|
608
616
|
function flush() {
|
|
609
617
|
return _flush.apply(this, arguments);
|
|
@@ -103,6 +103,13 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
103
103
|
}
|
|
104
104
|
});
|
|
105
105
|
bodiedSyncBlockData.push(syncBlockData);
|
|
106
|
+
|
|
107
|
+
// reset isDirty early to prevent race condition
|
|
108
|
+
// There is a race condition where if a user makes changes to a source sync block
|
|
109
|
+
// on a live page and the source sync block is being saved while the user
|
|
110
|
+
// is still making changes, the new changes might not be saved if they all happen
|
|
111
|
+
// exactly at a time when the writeNodesData is being executed asynchronously.
|
|
112
|
+
syncBlockData.isDirty = false;
|
|
106
113
|
}
|
|
107
114
|
});
|
|
108
115
|
if (!(bodiedSyncBlockNodes.length === 0)) {
|
|
@@ -116,11 +123,11 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
116
123
|
case 10:
|
|
117
124
|
writeResults = _context.sent;
|
|
118
125
|
writeResults.forEach(function (result) {
|
|
119
|
-
// set isDirty to
|
|
120
|
-
if (result.resourceId &&
|
|
126
|
+
// set isDirty to true for cases where it failed to save the sync block to the BE
|
|
127
|
+
if (result.resourceId && result.error && result.error !== SyncBlockError.NotFound) {
|
|
121
128
|
var cachedData = _this2.syncBlockCache.get(result.resourceId);
|
|
122
129
|
if (cachedData) {
|
|
123
|
-
cachedData.isDirty =
|
|
130
|
+
cachedData.isDirty = true;
|
|
124
131
|
}
|
|
125
132
|
}
|
|
126
133
|
});
|
|
@@ -72,6 +72,7 @@ export type DeleteSyncedBlockRequest = {
|
|
|
72
72
|
export type UpdateSyncedBlockRequest = {
|
|
73
73
|
blockAri: string;
|
|
74
74
|
content: string;
|
|
75
|
+
stepVersion?: number;
|
|
75
76
|
};
|
|
76
77
|
export type CreateSyncedBlockRequest = {
|
|
77
78
|
blockAri: string;
|
|
@@ -79,6 +80,7 @@ export type CreateSyncedBlockRequest = {
|
|
|
79
80
|
content: string;
|
|
80
81
|
product: SyncBlockProduct;
|
|
81
82
|
sourceAri: string;
|
|
83
|
+
stepVersion?: number;
|
|
82
84
|
};
|
|
83
85
|
type ReferenceSyncedBlockIDs = {
|
|
84
86
|
blockAri: string;
|
|
@@ -95,7 +97,7 @@ export declare class BlockError extends Error {
|
|
|
95
97
|
}
|
|
96
98
|
export declare const getSyncedBlockContent: ({ blockAri, }: GetSyncedBlockContentRequest) => Promise<BlockContentResponse>;
|
|
97
99
|
export declare const deleteSyncedBlock: ({ blockAri }: DeleteSyncedBlockRequest) => Promise<void>;
|
|
98
|
-
export declare const updateSyncedBlock: ({ blockAri, content, }: UpdateSyncedBlockRequest) => Promise<void>;
|
|
99
|
-
export declare const createSyncedBlock: ({ blockAri, blockInstanceId, sourceAri, product, content, }: CreateSyncedBlockRequest) => Promise<BlockContentResponse>;
|
|
100
|
+
export declare const updateSyncedBlock: ({ blockAri, content, stepVersion, }: UpdateSyncedBlockRequest) => Promise<void>;
|
|
101
|
+
export declare const createSyncedBlock: ({ blockAri, blockInstanceId, sourceAri, product, content, stepVersion, }: CreateSyncedBlockRequest) => Promise<BlockContentResponse>;
|
|
100
102
|
export declare const updateReferenceSyncedBlockOnDocument: ({ documentAri, blocks, noContent, }: UpdateReferenceSyncedBlockOnDocumentRequest) => Promise<ReferenceSyncedBlockResponse | void>;
|
|
101
103
|
export {};
|
|
@@ -15,8 +15,9 @@ declare class BlockServiceADFFetchProvider implements ADFFetchProvider {
|
|
|
15
15
|
declare class BlockServiceADFWriteProvider implements ADFWriteProvider {
|
|
16
16
|
private sourceAri;
|
|
17
17
|
private sourceDocumentId;
|
|
18
|
+
private getVersion?;
|
|
18
19
|
product: SyncBlockProduct;
|
|
19
|
-
constructor(sourceAri: string, product: SyncBlockProduct, sourceDocumentId: string);
|
|
20
|
+
constructor(sourceAri: string, product: SyncBlockProduct, sourceDocumentId: string, getVersion?: () => number | undefined);
|
|
20
21
|
writeData(data: SyncBlockData): Promise<WriteSyncBlockResult>;
|
|
21
22
|
createData(data: SyncBlockData): Promise<WriteSyncBlockResult>;
|
|
22
23
|
deleteData(resourceId: string): Promise<DeleteSyncBlockResult>;
|
|
@@ -24,7 +25,7 @@ declare class BlockServiceADFWriteProvider implements ADFWriteProvider {
|
|
|
24
25
|
generateResourceId(): ResourceId;
|
|
25
26
|
updateReferenceData(blocks: SyncBlockAttrs[], noContent?: boolean): Promise<UpdateReferenceSyncBlockResult>;
|
|
26
27
|
}
|
|
27
|
-
export declare const useMemoizedBlockServiceAPIProviders: (sourceAri: string, product: SyncBlockProduct, sourceDocumentId: string) => {
|
|
28
|
+
export declare const useMemoizedBlockServiceAPIProviders: (sourceAri: string, product: SyncBlockProduct, sourceDocumentId: string, getVersion?: () => number | undefined) => {
|
|
28
29
|
fetchProvider: BlockServiceADFFetchProvider;
|
|
29
30
|
writeProvider: BlockServiceADFWriteProvider;
|
|
30
31
|
};
|
|
@@ -72,6 +72,7 @@ export type DeleteSyncedBlockRequest = {
|
|
|
72
72
|
export type UpdateSyncedBlockRequest = {
|
|
73
73
|
blockAri: string;
|
|
74
74
|
content: string;
|
|
75
|
+
stepVersion?: number;
|
|
75
76
|
};
|
|
76
77
|
export type CreateSyncedBlockRequest = {
|
|
77
78
|
blockAri: string;
|
|
@@ -79,6 +80,7 @@ export type CreateSyncedBlockRequest = {
|
|
|
79
80
|
content: string;
|
|
80
81
|
product: SyncBlockProduct;
|
|
81
82
|
sourceAri: string;
|
|
83
|
+
stepVersion?: number;
|
|
82
84
|
};
|
|
83
85
|
type ReferenceSyncedBlockIDs = {
|
|
84
86
|
blockAri: string;
|
|
@@ -95,7 +97,7 @@ export declare class BlockError extends Error {
|
|
|
95
97
|
}
|
|
96
98
|
export declare const getSyncedBlockContent: ({ blockAri, }: GetSyncedBlockContentRequest) => Promise<BlockContentResponse>;
|
|
97
99
|
export declare const deleteSyncedBlock: ({ blockAri }: DeleteSyncedBlockRequest) => Promise<void>;
|
|
98
|
-
export declare const updateSyncedBlock: ({ blockAri, content, }: UpdateSyncedBlockRequest) => Promise<void>;
|
|
99
|
-
export declare const createSyncedBlock: ({ blockAri, blockInstanceId, sourceAri, product, content, }: CreateSyncedBlockRequest) => Promise<BlockContentResponse>;
|
|
100
|
+
export declare const updateSyncedBlock: ({ blockAri, content, stepVersion, }: UpdateSyncedBlockRequest) => Promise<void>;
|
|
101
|
+
export declare const createSyncedBlock: ({ blockAri, blockInstanceId, sourceAri, product, content, stepVersion, }: CreateSyncedBlockRequest) => Promise<BlockContentResponse>;
|
|
100
102
|
export declare const updateReferenceSyncedBlockOnDocument: ({ documentAri, blocks, noContent, }: UpdateReferenceSyncedBlockOnDocumentRequest) => Promise<ReferenceSyncedBlockResponse | void>;
|
|
101
103
|
export {};
|
|
@@ -15,8 +15,9 @@ declare class BlockServiceADFFetchProvider implements ADFFetchProvider {
|
|
|
15
15
|
declare class BlockServiceADFWriteProvider implements ADFWriteProvider {
|
|
16
16
|
private sourceAri;
|
|
17
17
|
private sourceDocumentId;
|
|
18
|
+
private getVersion?;
|
|
18
19
|
product: SyncBlockProduct;
|
|
19
|
-
constructor(sourceAri: string, product: SyncBlockProduct, sourceDocumentId: string);
|
|
20
|
+
constructor(sourceAri: string, product: SyncBlockProduct, sourceDocumentId: string, getVersion?: () => number | undefined);
|
|
20
21
|
writeData(data: SyncBlockData): Promise<WriteSyncBlockResult>;
|
|
21
22
|
createData(data: SyncBlockData): Promise<WriteSyncBlockResult>;
|
|
22
23
|
deleteData(resourceId: string): Promise<DeleteSyncBlockResult>;
|
|
@@ -24,7 +25,7 @@ declare class BlockServiceADFWriteProvider implements ADFWriteProvider {
|
|
|
24
25
|
generateResourceId(): ResourceId;
|
|
25
26
|
updateReferenceData(blocks: SyncBlockAttrs[], noContent?: boolean): Promise<UpdateReferenceSyncBlockResult>;
|
|
26
27
|
}
|
|
27
|
-
export declare const useMemoizedBlockServiceAPIProviders: (sourceAri: string, product: SyncBlockProduct, sourceDocumentId: string) => {
|
|
28
|
+
export declare const useMemoizedBlockServiceAPIProviders: (sourceAri: string, product: SyncBlockProduct, sourceDocumentId: string, getVersion?: () => number | undefined) => {
|
|
28
29
|
fetchProvider: BlockServiceADFFetchProvider;
|
|
29
30
|
writeProvider: BlockServiceADFWriteProvider;
|
|
30
31
|
};
|
package/package.json
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"uuid": "^3.1.0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@atlaskit/editor-common": "^110.
|
|
36
|
+
"@atlaskit/editor-common": "^110.49.0",
|
|
37
37
|
"react": "^18.2.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
}
|
|
77
77
|
},
|
|
78
78
|
"name": "@atlaskit/editor-synced-block-provider",
|
|
79
|
-
"version": "2.
|
|
79
|
+
"version": "2.16.0",
|
|
80
80
|
"description": "Synced Block Provider for @atlaskit/editor-plugin-synced-block",
|
|
81
81
|
"author": "Atlassian Pty Ltd",
|
|
82
82
|
"license": "Apache-2.0",
|