@atlaskit/editor-synced-block-provider 2.10.6 → 2.11.1
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 +20 -0
- package/dist/cjs/clients/block-service/blockService.js +5 -4
- package/dist/cjs/clients/confluence/sourceInfo.js +18 -15
- package/dist/cjs/hooks/useFetchSyncBlockData.js +20 -11
- package/dist/cjs/hooks/useHandleContentChanges.js +1 -5
- package/dist/cjs/providers/block-service/blockServiceAPI.js +17 -12
- package/dist/cjs/providers/syncBlockProvider.js +4 -4
- package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +118 -66
- package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +112 -55
- package/dist/cjs/store-manager/syncBlockStoreManager.js +3 -3
- package/dist/cjs/utils/errorHandling.js +31 -1
- package/dist/es2019/clients/block-service/blockService.js +5 -4
- package/dist/es2019/clients/confluence/sourceInfo.js +13 -8
- package/dist/es2019/hooks/useFetchSyncBlockData.js +15 -7
- package/dist/es2019/hooks/useHandleContentChanges.js +1 -5
- package/dist/es2019/providers/block-service/blockServiceAPI.js +13 -8
- package/dist/es2019/providers/syncBlockProvider.js +4 -4
- package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +105 -51
- package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +73 -25
- package/dist/es2019/store-manager/syncBlockStoreManager.js +3 -3
- package/dist/es2019/utils/errorHandling.js +17 -1
- package/dist/esm/clients/block-service/blockService.js +5 -4
- package/dist/esm/clients/confluence/sourceInfo.js +18 -15
- package/dist/esm/hooks/useFetchSyncBlockData.js +20 -11
- package/dist/esm/hooks/useHandleContentChanges.js +1 -5
- package/dist/esm/providers/block-service/blockServiceAPI.js +17 -12
- package/dist/esm/providers/syncBlockProvider.js +4 -4
- package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +118 -66
- package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +110 -53
- package/dist/esm/store-manager/syncBlockStoreManager.js +3 -3
- package/dist/esm/utils/errorHandling.js +30 -0
- package/dist/types/clients/block-service/blockService.d.ts +0 -2
- package/dist/types/clients/confluence/sourceInfo.d.ts +2 -1
- package/dist/types/hooks/useFetchSyncBlockData.d.ts +2 -1
- package/dist/types/providers/block-service/blockServiceAPI.d.ts +6 -3
- package/dist/types/providers/syncBlockProvider.d.ts +2 -1
- package/dist/types/providers/types.d.ts +2 -1
- package/dist/types/store-manager/referenceSyncBlockStoreManager.d.ts +4 -1
- package/dist/types/store-manager/sourceSyncBlockStoreManager.d.ts +3 -1
- package/dist/types/store-manager/syncBlockStoreManager.d.ts +2 -1
- package/dist/types/utils/errorHandling.d.ts +10 -0
- package/dist/types-ts4.5/clients/block-service/blockService.d.ts +0 -2
- package/dist/types-ts4.5/clients/confluence/sourceInfo.d.ts +2 -1
- package/dist/types-ts4.5/hooks/useFetchSyncBlockData.d.ts +2 -1
- package/dist/types-ts4.5/providers/block-service/blockServiceAPI.d.ts +6 -3
- package/dist/types-ts4.5/providers/syncBlockProvider.d.ts +2 -1
- package/dist/types-ts4.5/providers/types.d.ts +2 -1
- package/dist/types-ts4.5/store-manager/referenceSyncBlockStoreManager.d.ts +4 -1
- package/dist/types-ts4.5/store-manager/sourceSyncBlockStoreManager.d.ts +3 -1
- package/dist/types-ts4.5/store-manager/syncBlockStoreManager.d.ts +2 -1
- package/dist/types-ts4.5/utils/errorHandling.d.ts +10 -0
- package/package.json +2 -8
|
@@ -11,8 +11,11 @@ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/cl
|
|
|
11
11
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
12
12
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
13
13
|
var _uuid = _interopRequireDefault(require("uuid"));
|
|
14
|
+
var _monitoring = require("@atlaskit/editor-common/monitoring");
|
|
15
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
14
16
|
var _rebaseTransaction2 = require("../common/rebase-transaction");
|
|
15
|
-
var
|
|
17
|
+
var _errorHandling = require("../utils/errorHandling");
|
|
18
|
+
var _utils2 = require("../utils/utils");
|
|
16
19
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
17
20
|
// A store manager responsible for the lifecycle and state management of source sync blocks in an editor instance.
|
|
18
21
|
// Designed to manage local in-memory state and synchronize with an external data provider.
|
|
@@ -20,7 +23,7 @@ var _utils = require("../utils/utils");
|
|
|
20
23
|
// Handles caching, debouncing updates, and publish/subscribe for local changes.
|
|
21
24
|
// Ensures consistency between local and remote state, and can be used in both editor and renderer contexts.
|
|
22
25
|
var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
23
|
-
function SourceSyncBlockStoreManager(dataProvider) {
|
|
26
|
+
function SourceSyncBlockStoreManager(dataProvider, fireAnalyticsEvent) {
|
|
24
27
|
var _this = this;
|
|
25
28
|
(0, _classCallCheck2.default)(this, SourceSyncBlockStoreManager);
|
|
26
29
|
(0, _defineProperty2.default)(this, "setPendingDeletion", function (Ids, value) {
|
|
@@ -31,6 +34,7 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
31
34
|
});
|
|
32
35
|
this.dataProvider = dataProvider;
|
|
33
36
|
this.syncBlockCache = new Map();
|
|
37
|
+
this.fireAnalyticsEvent = fireAnalyticsEvent;
|
|
34
38
|
}
|
|
35
39
|
return (0, _createClass2.default)(SourceSyncBlockStoreManager, [{
|
|
36
40
|
key: "isSourceBlock",
|
|
@@ -45,18 +49,27 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
45
49
|
}, {
|
|
46
50
|
key: "updateSyncBlockData",
|
|
47
51
|
value: function updateSyncBlockData(syncBlockNode) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
try {
|
|
53
|
+
if (!this.isSourceBlock(syncBlockNode)) {
|
|
54
|
+
throw new Error('Invalid sync block node type provided for updateSyncBlockData');
|
|
55
|
+
}
|
|
56
|
+
var _syncBlockNode$attrs = syncBlockNode.attrs,
|
|
57
|
+
localId = _syncBlockNode$attrs.localId,
|
|
58
|
+
resourceId = _syncBlockNode$attrs.resourceId;
|
|
59
|
+
if (!localId || !resourceId) {
|
|
60
|
+
throw new Error('Local ID or resource ID is not set');
|
|
61
|
+
}
|
|
62
|
+
var syncBlockData = (0, _utils2.convertSyncBlockPMNodeToSyncBlockData)(syncBlockNode);
|
|
63
|
+
this.syncBlockCache.set(resourceId, syncBlockData);
|
|
64
|
+
return true;
|
|
65
|
+
} catch (error) {
|
|
66
|
+
var _this$fireAnalyticsEv;
|
|
67
|
+
(0, _monitoring.logException)(error, {
|
|
68
|
+
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
69
|
+
});
|
|
70
|
+
(_this$fireAnalyticsEv = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv === void 0 || _this$fireAnalyticsEv.call(this, (0, _errorHandling.updateCacheErrorPayload)(error.message));
|
|
71
|
+
return false;
|
|
56
72
|
}
|
|
57
|
-
var syncBlockData = (0, _utils.convertSyncBlockPMNodeToSyncBlockData)(syncBlockNode);
|
|
58
|
-
this.syncBlockCache.set(resourceId, syncBlockData);
|
|
59
|
-
return true;
|
|
60
73
|
}
|
|
61
74
|
|
|
62
75
|
/**
|
|
@@ -68,7 +81,8 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
68
81
|
key: "flush",
|
|
69
82
|
value: (function () {
|
|
70
83
|
var _flush = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
|
|
71
|
-
var
|
|
84
|
+
var _this2 = this;
|
|
85
|
+
var bodiedSyncBlockNodes, bodiedSyncBlockData, writeResults, _this$fireAnalyticsEv2;
|
|
72
86
|
return _regenerator.default.wrap(function _callee$(_context) {
|
|
73
87
|
while (1) switch (_context.prev = _context.next) {
|
|
74
88
|
case 0:
|
|
@@ -104,18 +118,37 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
104
118
|
return this.dataProvider.writeNodesData(bodiedSyncBlockNodes, bodiedSyncBlockData);
|
|
105
119
|
case 10:
|
|
106
120
|
writeResults = _context.sent;
|
|
107
|
-
|
|
121
|
+
if (!writeResults.every(function (result) {
|
|
108
122
|
return result.resourceId !== undefined;
|
|
109
|
-
}))
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
123
|
+
})) {
|
|
124
|
+
_context.next = 15;
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
return _context.abrupt("return", true);
|
|
128
|
+
case 15:
|
|
129
|
+
writeResults.filter(function (result) {
|
|
130
|
+
return result.resourceId === undefined;
|
|
131
|
+
}).forEach(function (result) {
|
|
132
|
+
var _this2$fireAnalyticsE;
|
|
133
|
+
(_this2$fireAnalyticsE = _this2.fireAnalyticsEvent) === null || _this2$fireAnalyticsE === void 0 || _this2$fireAnalyticsE.call(_this2, (0, _errorHandling.updateErrorPayload)(result.error || 'Failed to write data'));
|
|
134
|
+
});
|
|
113
135
|
return _context.abrupt("return", false);
|
|
114
136
|
case 17:
|
|
137
|
+
_context.next = 24;
|
|
138
|
+
break;
|
|
139
|
+
case 19:
|
|
140
|
+
_context.prev = 19;
|
|
141
|
+
_context.t0 = _context["catch"](0);
|
|
142
|
+
(0, _monitoring.logException)(_context.t0, {
|
|
143
|
+
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
144
|
+
});
|
|
145
|
+
(_this$fireAnalyticsEv2 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv2 === void 0 || _this$fireAnalyticsEv2.call(this, (0, _errorHandling.updateErrorPayload)(_context.t0.message));
|
|
146
|
+
return _context.abrupt("return", false);
|
|
147
|
+
case 24:
|
|
115
148
|
case "end":
|
|
116
149
|
return _context.stop();
|
|
117
150
|
}
|
|
118
|
-
}, _callee, this, [[0,
|
|
151
|
+
}, _callee, this, [[0, 19]]);
|
|
119
152
|
}));
|
|
120
153
|
function flush() {
|
|
121
154
|
return _flush.apply(this, arguments);
|
|
@@ -168,10 +201,10 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
168
201
|
}, {
|
|
169
202
|
key: "registerConfirmationCallback",
|
|
170
203
|
value: function registerConfirmationCallback(callback) {
|
|
171
|
-
var
|
|
204
|
+
var _this3 = this;
|
|
172
205
|
this.confirmationCallback = callback;
|
|
173
206
|
return function () {
|
|
174
|
-
|
|
207
|
+
_this3.confirmationCallback = undefined;
|
|
175
208
|
};
|
|
176
209
|
}
|
|
177
210
|
}, {
|
|
@@ -191,7 +224,7 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
191
224
|
var localId = (0, _uuid.default)();
|
|
192
225
|
var sourceId = (_this$dataProvider = this.dataProvider) === null || _this$dataProvider === void 0 ? void 0 : _this$dataProvider.getSourceId();
|
|
193
226
|
if (!this.dataProvider || !sourceId) {
|
|
194
|
-
throw new Error('
|
|
227
|
+
throw new Error('Data provider not set or source id not set');
|
|
195
228
|
}
|
|
196
229
|
var resourceId = this.dataProvider.generateResourceId(sourceId, localId);
|
|
197
230
|
return {
|
|
@@ -207,14 +240,14 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
207
240
|
}, {
|
|
208
241
|
key: "createBodiedSyncBlockNode",
|
|
209
242
|
value: function createBodiedSyncBlockNode(attrs) {
|
|
210
|
-
var
|
|
243
|
+
var _this4 = this;
|
|
211
244
|
try {
|
|
212
245
|
if (!this.dataProvider) {
|
|
213
246
|
throw new Error('Data provider not set');
|
|
214
247
|
}
|
|
215
248
|
var resourceId = attrs.resourceId,
|
|
216
249
|
blockInstanceId = attrs.localId;
|
|
217
|
-
this.dataProvider.writeNodesData([(0,
|
|
250
|
+
this.dataProvider.writeNodesData([(0, _utils2.createBodiedSyncBlockNode)(blockInstanceId, resourceId)], [{
|
|
218
251
|
content: [],
|
|
219
252
|
blockInstanceId: blockInstanceId,
|
|
220
253
|
resourceId: resourceId
|
|
@@ -222,35 +255,44 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
222
255
|
results.forEach(function (result) {
|
|
223
256
|
var resourceId = result.resourceId;
|
|
224
257
|
if (resourceId) {
|
|
225
|
-
|
|
258
|
+
_this4.commitPendingCreation(true);
|
|
226
259
|
} else {
|
|
227
|
-
|
|
228
|
-
|
|
260
|
+
var _this4$fireAnalyticsE;
|
|
261
|
+
_this4.commitPendingCreation(false);
|
|
262
|
+
(_this4$fireAnalyticsE = _this4.fireAnalyticsEvent) === null || _this4$fireAnalyticsE === void 0 || _this4$fireAnalyticsE.call(_this4, (0, _errorHandling.createErrorPayload)(result.error || 'Failed to create bodied sync block'));
|
|
229
263
|
}
|
|
230
264
|
});
|
|
231
|
-
}).catch(function (
|
|
232
|
-
|
|
233
|
-
|
|
265
|
+
}).catch(function (error) {
|
|
266
|
+
var _this4$fireAnalyticsE2;
|
|
267
|
+
_this4.commitPendingCreation(false);
|
|
268
|
+
(0, _monitoring.logException)(error, {
|
|
269
|
+
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
270
|
+
});
|
|
271
|
+
(_this4$fireAnalyticsE2 = _this4.fireAnalyticsEvent) === null || _this4$fireAnalyticsE2 === void 0 || _this4$fireAnalyticsE2.call(_this4, (0, _errorHandling.createErrorPayload)(error.message));
|
|
234
272
|
});
|
|
235
273
|
this.registerPendingCreation(resourceId);
|
|
236
274
|
} catch (error) {
|
|
275
|
+
var _this$fireAnalyticsEv3;
|
|
237
276
|
if (this.hasPendingCreation()) {
|
|
238
277
|
this.commitPendingCreation(false);
|
|
239
278
|
}
|
|
240
|
-
|
|
279
|
+
(0, _monitoring.logException)(error, {
|
|
280
|
+
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
281
|
+
});
|
|
282
|
+
(_this$fireAnalyticsEv3 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv3 === void 0 || _this$fireAnalyticsEv3.call(this, (0, _errorHandling.createErrorPayload)(error.message));
|
|
241
283
|
}
|
|
242
284
|
}
|
|
243
285
|
}, {
|
|
244
286
|
key: "deleteSyncBlocksWithConfirmation",
|
|
245
287
|
value: function () {
|
|
246
288
|
var _deleteSyncBlocksWithConfirmation = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(tr, syncBlockIds) {
|
|
247
|
-
var
|
|
248
|
-
var confirmed, _this$editorView, results, callback;
|
|
289
|
+
var _this5 = this;
|
|
290
|
+
var confirmed, _this$editorView, trToDispatch, results, callback, _this$fireAnalyticsEv4;
|
|
249
291
|
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
250
292
|
while (1) switch (_context2.prev = _context2.next) {
|
|
251
293
|
case 0:
|
|
252
294
|
if (!this.confirmationCallback) {
|
|
253
|
-
_context2.next =
|
|
295
|
+
_context2.next = 26;
|
|
254
296
|
break;
|
|
255
297
|
}
|
|
256
298
|
this.confirmationTransaction = tr;
|
|
@@ -259,55 +301,69 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
259
301
|
case 4:
|
|
260
302
|
confirmed = _context2.sent;
|
|
261
303
|
if (!confirmed) {
|
|
262
|
-
_context2.next =
|
|
304
|
+
_context2.next = 25;
|
|
263
305
|
break;
|
|
264
306
|
}
|
|
265
|
-
|
|
266
|
-
|
|
307
|
+
trToDispatch = this.confirmationTransaction.setMeta('isConfirmedSyncBlockDeletion', true);
|
|
308
|
+
if (!trToDispatch.getMeta(_utils.pmHistoryPluginKey)) {
|
|
309
|
+
// bodiedSyncBlock deletion is expected to be permanent (cannot be undo)
|
|
310
|
+
// For a normal delete (not triggered by undo), remove it from history so that it cannot be undone
|
|
311
|
+
trToDispatch.setMeta('addToHistory', false);
|
|
312
|
+
}
|
|
313
|
+
(_this$editorView = this.editorView) === null || _this$editorView === void 0 || _this$editorView.dispatch(trToDispatch);
|
|
314
|
+
_context2.prev = 9;
|
|
267
315
|
if (this.dataProvider) {
|
|
268
|
-
_context2.next =
|
|
316
|
+
_context2.next = 12;
|
|
269
317
|
break;
|
|
270
318
|
}
|
|
271
319
|
throw new Error('Data provider not set');
|
|
272
|
-
case
|
|
320
|
+
case 12:
|
|
273
321
|
syncBlockIds.forEach(function (Ids) {
|
|
274
|
-
|
|
322
|
+
_this5.setPendingDeletion(Ids, true);
|
|
275
323
|
});
|
|
276
|
-
_context2.next =
|
|
324
|
+
_context2.next = 15;
|
|
277
325
|
return this.dataProvider.deleteNodesData(syncBlockIds.map(function (attrs) {
|
|
278
326
|
return attrs.resourceId;
|
|
279
327
|
}));
|
|
280
|
-
case
|
|
328
|
+
case 15:
|
|
281
329
|
results = _context2.sent;
|
|
282
330
|
if (results.every(function (result) {
|
|
283
331
|
return result.success;
|
|
284
332
|
})) {
|
|
285
333
|
callback = function callback(Ids) {
|
|
286
|
-
return
|
|
334
|
+
return _this5.syncBlockCache.delete(Ids.resourceId);
|
|
287
335
|
};
|
|
288
336
|
} else {
|
|
289
337
|
callback = function callback(Ids) {
|
|
290
|
-
|
|
338
|
+
_this5.setPendingDeletion(Ids, false);
|
|
291
339
|
};
|
|
292
|
-
|
|
340
|
+
results.filter(function (result) {
|
|
341
|
+
return result.resourceId === undefined;
|
|
342
|
+
}).forEach(function (result) {
|
|
343
|
+
var _this5$fireAnalyticsE;
|
|
344
|
+
(_this5$fireAnalyticsE = _this5.fireAnalyticsEvent) === null || _this5$fireAnalyticsE === void 0 || _this5$fireAnalyticsE.call(_this5, (0, _errorHandling.deleteErrorPayload)(result.error || 'Failed to delete synced block'));
|
|
345
|
+
});
|
|
293
346
|
}
|
|
294
347
|
syncBlockIds.forEach(callback);
|
|
295
|
-
_context2.next =
|
|
348
|
+
_context2.next = 25;
|
|
296
349
|
break;
|
|
297
|
-
case
|
|
298
|
-
_context2.prev =
|
|
299
|
-
_context2.t0 = _context2["catch"](
|
|
350
|
+
case 20:
|
|
351
|
+
_context2.prev = 20;
|
|
352
|
+
_context2.t0 = _context2["catch"](9);
|
|
300
353
|
syncBlockIds.forEach(function (Ids) {
|
|
301
|
-
|
|
354
|
+
_this5.setPendingDeletion(Ids, false);
|
|
355
|
+
});
|
|
356
|
+
(0, _monitoring.logException)(_context2.t0, {
|
|
357
|
+
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
302
358
|
});
|
|
303
|
-
|
|
304
|
-
case
|
|
359
|
+
(_this$fireAnalyticsEv4 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv4 === void 0 || _this$fireAnalyticsEv4.call(this, (0, _errorHandling.deleteErrorPayload)(_context2.t0.message));
|
|
360
|
+
case 25:
|
|
305
361
|
this.confirmationTransaction = undefined;
|
|
306
|
-
case
|
|
362
|
+
case 26:
|
|
307
363
|
case "end":
|
|
308
364
|
return _context2.stop();
|
|
309
365
|
}
|
|
310
|
-
}, _callee2, this, [[
|
|
366
|
+
}, _callee2, this, [[9, 20]]);
|
|
311
367
|
}));
|
|
312
368
|
function deleteSyncBlocksWithConfirmation(_x, _x2) {
|
|
313
369
|
return _deleteSyncBlocksWithConfirmation.apply(this, arguments);
|
|
@@ -332,6 +388,7 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
332
388
|
this.creationCallback = undefined;
|
|
333
389
|
this.dataProvider = undefined;
|
|
334
390
|
this.editorView = undefined;
|
|
391
|
+
this.fireAnalyticsEvent = undefined;
|
|
335
392
|
}
|
|
336
393
|
}]);
|
|
337
394
|
}();
|
|
@@ -15,12 +15,12 @@ var _sourceSyncBlockStoreManager = require("./sourceSyncBlockStoreManager");
|
|
|
15
15
|
// SourceSyncBlockStoreManager is responsible for the lifecycle and state management of source sync blocks in an editor instance.
|
|
16
16
|
// Can be used in both editor and renderer contexts.
|
|
17
17
|
var SyncBlockStoreManager = exports.SyncBlockStoreManager = /*#__PURE__*/function () {
|
|
18
|
-
function SyncBlockStoreManager(dataProvider) {
|
|
18
|
+
function SyncBlockStoreManager(dataProvider, fireAnalyticsEvent) {
|
|
19
19
|
(0, _classCallCheck2.default)(this, SyncBlockStoreManager);
|
|
20
20
|
// In future, if reference manager needs to reach to source manager and read it's current in memorey cache
|
|
21
21
|
// we can pass the source manager as a parameter to the reference manager constructor
|
|
22
|
-
this.sourceSyncBlockStoreManager = new _sourceSyncBlockStoreManager.SourceSyncBlockStoreManager(dataProvider);
|
|
23
|
-
this.referenceSyncBlockStoreManager = new _referenceSyncBlockStoreManager.ReferenceSyncBlockStoreManager(dataProvider);
|
|
22
|
+
this.sourceSyncBlockStoreManager = new _sourceSyncBlockStoreManager.SourceSyncBlockStoreManager(dataProvider, fireAnalyticsEvent);
|
|
23
|
+
this.referenceSyncBlockStoreManager = new _referenceSyncBlockStoreManager.ReferenceSyncBlockStoreManager(dataProvider, fireAnalyticsEvent);
|
|
24
24
|
}
|
|
25
25
|
return (0, _createClass2.default)(SyncBlockStoreManager, [{
|
|
26
26
|
key: "referenceManager",
|
|
@@ -3,11 +3,41 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.stringifyError = void 0;
|
|
6
|
+
exports.updateErrorPayload = exports.updateCacheErrorPayload = exports.stringifyError = exports.getSourceInfoErrorPayload = exports.getErrorPayload = exports.fetchErrorPayload = exports.deleteErrorPayload = exports.createErrorPayload = void 0;
|
|
7
|
+
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
7
8
|
var stringifyError = exports.stringifyError = function stringifyError(error) {
|
|
8
9
|
try {
|
|
9
10
|
return JSON.stringify(error);
|
|
10
11
|
} catch (_unused) {
|
|
11
12
|
return undefined;
|
|
12
13
|
}
|
|
14
|
+
};
|
|
15
|
+
var getErrorPayload = exports.getErrorPayload = function getErrorPayload(actionSubjectId, error) {
|
|
16
|
+
return {
|
|
17
|
+
action: _analytics.ACTION.ERROR,
|
|
18
|
+
actionSubject: _analytics.ACTION_SUBJECT.SYNCED_BLOCK,
|
|
19
|
+
actionSubjectId: actionSubjectId,
|
|
20
|
+
eventType: _analytics.EVENT_TYPE.OPERATIONAL,
|
|
21
|
+
attributes: {
|
|
22
|
+
error: error
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
var fetchErrorPayload = exports.fetchErrorPayload = function fetchErrorPayload(error) {
|
|
27
|
+
return getErrorPayload(_analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_FETCH, error);
|
|
28
|
+
};
|
|
29
|
+
var getSourceInfoErrorPayload = exports.getSourceInfoErrorPayload = function getSourceInfoErrorPayload(error) {
|
|
30
|
+
return getErrorPayload(_analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_GET_SOURCE_INFO, error);
|
|
31
|
+
};
|
|
32
|
+
var updateErrorPayload = exports.updateErrorPayload = function updateErrorPayload(error) {
|
|
33
|
+
return getErrorPayload(_analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_UPDATE, error);
|
|
34
|
+
};
|
|
35
|
+
var createErrorPayload = exports.createErrorPayload = function createErrorPayload(error) {
|
|
36
|
+
return getErrorPayload(_analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_CREATE, error);
|
|
37
|
+
};
|
|
38
|
+
var deleteErrorPayload = exports.deleteErrorPayload = function deleteErrorPayload(error) {
|
|
39
|
+
return getErrorPayload(_analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_DELETE, error);
|
|
40
|
+
};
|
|
41
|
+
var updateCacheErrorPayload = exports.updateCacheErrorPayload = function updateCacheErrorPayload(error) {
|
|
42
|
+
return getErrorPayload(_analytics.ACTION_SUBJECT_ID.SYNCED_BLOCK_UPDATE_CACHE, error);
|
|
13
43
|
};
|
|
@@ -12,7 +12,7 @@ export class BlockError extends Error {
|
|
|
12
12
|
export const getSyncedBlockContent = async ({
|
|
13
13
|
blockAri
|
|
14
14
|
}) => {
|
|
15
|
-
const response = await fetch(`${BLOCK_SERVICE_API_URL}/block/${blockAri}`, {
|
|
15
|
+
const response = await fetch(`${BLOCK_SERVICE_API_URL}/block/${encodeURIComponent(blockAri)}`, {
|
|
16
16
|
method: 'GET',
|
|
17
17
|
headers: COMMON_HEADERS
|
|
18
18
|
});
|
|
@@ -24,7 +24,7 @@ export const getSyncedBlockContent = async ({
|
|
|
24
24
|
export const deleteSyncedBlock = async ({
|
|
25
25
|
blockAri
|
|
26
26
|
}) => {
|
|
27
|
-
const response = await fetch(`${BLOCK_SERVICE_API_URL}/block/${blockAri}`, {
|
|
27
|
+
const response = await fetch(`${BLOCK_SERVICE_API_URL}/block/${encodeURIComponent(blockAri)}`, {
|
|
28
28
|
method: 'DELETE',
|
|
29
29
|
headers: COMMON_HEADERS
|
|
30
30
|
});
|
|
@@ -36,7 +36,7 @@ export const updateSyncedBlock = async ({
|
|
|
36
36
|
blockAri,
|
|
37
37
|
content
|
|
38
38
|
}) => {
|
|
39
|
-
const response = await fetch(`${BLOCK_SERVICE_API_URL}/block/${blockAri}`, {
|
|
39
|
+
const response = await fetch(`${BLOCK_SERVICE_API_URL}/block/${encodeURIComponent(blockAri)}`, {
|
|
40
40
|
method: 'PUT',
|
|
41
41
|
headers: COMMON_HEADERS,
|
|
42
42
|
body: JSON.stringify({
|
|
@@ -54,10 +54,11 @@ export const createSyncedBlock = async ({
|
|
|
54
54
|
product,
|
|
55
55
|
content
|
|
56
56
|
}) => {
|
|
57
|
-
const response = await fetch(`${BLOCK_SERVICE_API_URL}/block
|
|
57
|
+
const response = await fetch(`${BLOCK_SERVICE_API_URL}/block`, {
|
|
58
58
|
method: 'POST',
|
|
59
59
|
headers: COMMON_HEADERS,
|
|
60
60
|
body: JSON.stringify({
|
|
61
|
+
blockAri,
|
|
61
62
|
blockInstanceId,
|
|
62
63
|
sourceAri,
|
|
63
64
|
product,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/* eslint-disable require-unicode-regexp */
|
|
2
2
|
|
|
3
|
+
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
4
|
+
import { getSourceInfoErrorPayload } from '../../utils/errorHandling';
|
|
3
5
|
import { getPageIdAndTypeFromConfluencePageAri } from './ari';
|
|
4
6
|
import { isBlogPageType } from './utils';
|
|
5
7
|
const COMMON_HEADERS = {
|
|
@@ -52,7 +54,7 @@ const getConfluenceSourceInfo = async ari => {
|
|
|
52
54
|
}
|
|
53
55
|
return await response.json();
|
|
54
56
|
};
|
|
55
|
-
export const fetchConfluencePageInfo = async (pageAri, localId) => {
|
|
57
|
+
export const fetchConfluencePageInfo = async (pageAri, localId, fireAnalyticsEvent) => {
|
|
56
58
|
try {
|
|
57
59
|
var _response$data, _response$data$conten, _response$data$conten2, _contentData$space;
|
|
58
60
|
const {
|
|
@@ -60,15 +62,12 @@ export const fetchConfluencePageInfo = async (pageAri, localId) => {
|
|
|
60
62
|
} = getPageIdAndTypeFromConfluencePageAri(pageAri);
|
|
61
63
|
const response = await getConfluenceSourceInfo(pageAri);
|
|
62
64
|
const contentData = (_response$data = response.data) === null || _response$data === void 0 ? void 0 : (_response$data$conten = _response$data.content) === null || _response$data$conten === void 0 ? void 0 : (_response$data$conten2 = _response$data$conten.nodes) === null || _response$data$conten2 === void 0 ? void 0 : _response$data$conten2[0];
|
|
63
|
-
|
|
64
|
-
throw new Error(`Failed to get content data`);
|
|
65
|
-
}
|
|
66
|
-
const title = contentData.title;
|
|
65
|
+
const title = contentData === null || contentData === void 0 ? void 0 : contentData.title;
|
|
67
66
|
let url;
|
|
68
67
|
const {
|
|
69
68
|
base
|
|
70
|
-
} = contentData.links || {};
|
|
71
|
-
if (base && (_contentData$space = contentData.space) !== null && _contentData$space !== void 0 && _contentData$space.key && contentData.id) {
|
|
69
|
+
} = (contentData === null || contentData === void 0 ? void 0 : contentData.links) || {};
|
|
70
|
+
if (base && contentData !== null && contentData !== void 0 && (_contentData$space = contentData.space) !== null && _contentData$space !== void 0 && _contentData$space.key && contentData !== null && contentData !== void 0 && contentData.id) {
|
|
72
71
|
if (isBlogPageType(pageType)) {
|
|
73
72
|
url = `${base}/spaces/${contentData.space.key}/blog/edit-v2/${contentData.id}`;
|
|
74
73
|
} else if (contentData.subType === 'live') {
|
|
@@ -78,12 +77,18 @@ export const fetchConfluencePageInfo = async (pageAri, localId) => {
|
|
|
78
77
|
}
|
|
79
78
|
}
|
|
80
79
|
url = url && localId ? `${url}#block-${localId}` : url;
|
|
80
|
+
if (!title || !url) {
|
|
81
|
+
fireAnalyticsEvent === null || fireAnalyticsEvent === void 0 ? void 0 : fireAnalyticsEvent(getSourceInfoErrorPayload('Failed to get confluence page source info'));
|
|
82
|
+
}
|
|
81
83
|
return Promise.resolve({
|
|
82
84
|
title,
|
|
83
85
|
url
|
|
84
86
|
});
|
|
85
87
|
} catch (error) {
|
|
86
|
-
|
|
88
|
+
logException(error, {
|
|
89
|
+
location: 'editor-synced-block-provider/sourceInfo'
|
|
90
|
+
});
|
|
91
|
+
fireAnalyticsEvent === null || fireAnalyticsEvent === void 0 ? void 0 : fireAnalyticsEvent(getSourceInfoErrorPayload(error.message));
|
|
87
92
|
return Promise.resolve(undefined);
|
|
88
93
|
}
|
|
89
94
|
};
|
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
2
3
|
import { SyncBlockError } from '../common/types';
|
|
4
|
+
import { fetchErrorPayload } from '../utils/errorHandling';
|
|
3
5
|
import { createSyncBlockNode } from '../utils/utils';
|
|
4
|
-
export const useFetchSyncBlockData = (manager, resourceId, localId) => {
|
|
6
|
+
export const useFetchSyncBlockData = (manager, resourceId, localId, fireAnalyticsEvent) => {
|
|
5
7
|
const [syncBlockInstance, setSyncBlockInstance] = useState(null);
|
|
6
8
|
const [isLoading, setIsLoading] = useState(true);
|
|
7
9
|
const reloadData = useCallback(async () => {
|
|
8
10
|
if (isLoading) {
|
|
9
11
|
return;
|
|
10
12
|
}
|
|
11
|
-
const syncBlockNode = resourceId && localId ? createSyncBlockNode(localId, resourceId) : null;
|
|
12
|
-
if (!syncBlockNode) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
setIsLoading(true);
|
|
16
13
|
try {
|
|
14
|
+
const syncBlockNode = resourceId && localId ? createSyncBlockNode(localId, resourceId) : null;
|
|
15
|
+
if (!syncBlockNode) {
|
|
16
|
+
throw new Error('Failed to create sync block node from resourceid and localid');
|
|
17
|
+
}
|
|
18
|
+
setIsLoading(true);
|
|
19
|
+
|
|
17
20
|
// Fetch sync block data, the `subscribeToSyncBlock` will update the state once data is fetched
|
|
18
21
|
await manager.referenceManager.fetchSyncBlocksData([syncBlockNode]);
|
|
19
22
|
} catch (error) {
|
|
23
|
+
logException(error, {
|
|
24
|
+
location: 'editor-synced-block-provider/useFetchSyncBlockData'
|
|
25
|
+
});
|
|
26
|
+
fireAnalyticsEvent === null || fireAnalyticsEvent === void 0 ? void 0 : fireAnalyticsEvent(fetchErrorPayload(error.message));
|
|
27
|
+
|
|
20
28
|
// Set error state if fetching fails
|
|
21
29
|
setSyncBlockInstance({
|
|
22
30
|
resourceId: resourceId || '',
|
|
@@ -24,7 +32,7 @@ export const useFetchSyncBlockData = (manager, resourceId, localId) => {
|
|
|
24
32
|
});
|
|
25
33
|
}
|
|
26
34
|
setIsLoading(false);
|
|
27
|
-
}, [isLoading, localId, manager.referenceManager, resourceId]);
|
|
35
|
+
}, [isLoading, localId, manager.referenceManager, resourceId, fireAnalyticsEvent]);
|
|
28
36
|
useEffect(() => {
|
|
29
37
|
const unsubscribe = manager.referenceManager.subscribeToSyncBlock(resourceId || '', localId || '', data => {
|
|
30
38
|
setSyncBlockInstance(data);
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
export const useHandleContentChanges = (manager, syncBlockNode) => {
|
|
3
3
|
useEffect(() => {
|
|
4
|
-
|
|
5
|
-
manager.sourceManager.updateSyncBlockData(syncBlockNode);
|
|
6
|
-
} catch {
|
|
7
|
-
//TODO: EDITOR-1921 - add error analytics
|
|
8
|
-
}
|
|
4
|
+
manager.sourceManager.updateSyncBlockData(syncBlockNode);
|
|
9
5
|
}, [manager, syncBlockNode]);
|
|
10
6
|
};
|
|
@@ -62,6 +62,11 @@ class BlockServiceADFFetchProvider {
|
|
|
62
62
|
* ADFWriteProvider implementation that writes synced block data to Block Service API
|
|
63
63
|
*/
|
|
64
64
|
class BlockServiceADFWriteProvider {
|
|
65
|
+
constructor(sourceAri, product) {
|
|
66
|
+
this.sourceAri = sourceAri;
|
|
67
|
+
this.product = product;
|
|
68
|
+
}
|
|
69
|
+
|
|
65
70
|
// it will first try to update and if it can't (404) then it will try to create
|
|
66
71
|
async writeData(data) {
|
|
67
72
|
const {
|
|
@@ -83,8 +88,8 @@ class BlockServiceADFWriteProvider {
|
|
|
83
88
|
await createSyncedBlock({
|
|
84
89
|
blockAri: resourceId,
|
|
85
90
|
blockInstanceId: data.blockInstanceId,
|
|
86
|
-
sourceAri:
|
|
87
|
-
product:
|
|
91
|
+
sourceAri: this.sourceAri,
|
|
92
|
+
product: this.product,
|
|
88
93
|
content: JSON.stringify(data.content)
|
|
89
94
|
});
|
|
90
95
|
} else {
|
|
@@ -127,22 +132,22 @@ class BlockServiceADFWriteProvider {
|
|
|
127
132
|
};
|
|
128
133
|
}
|
|
129
134
|
}
|
|
130
|
-
generateResourceId(
|
|
131
|
-
return blockResourceIdFromSourceAndLocalId(
|
|
135
|
+
generateResourceId(sourceAri, localId) {
|
|
136
|
+
return blockResourceIdFromSourceAndLocalId(sourceAri, localId);
|
|
132
137
|
}
|
|
133
138
|
}
|
|
134
139
|
|
|
135
140
|
/**
|
|
136
141
|
* Factory function to create both providers with shared configuration
|
|
137
142
|
*/
|
|
138
|
-
const createBlockServiceAPIProviders = () => {
|
|
143
|
+
const createBlockServiceAPIProviders = (sourceAri, product) => {
|
|
139
144
|
const fetchProvider = new BlockServiceADFFetchProvider();
|
|
140
|
-
const writeProvider = new BlockServiceADFWriteProvider();
|
|
145
|
+
const writeProvider = new BlockServiceADFWriteProvider(sourceAri, product);
|
|
141
146
|
return {
|
|
142
147
|
fetchProvider,
|
|
143
148
|
writeProvider
|
|
144
149
|
};
|
|
145
150
|
};
|
|
146
|
-
export const useMemoizedBlockServiceAPIProviders = () => {
|
|
147
|
-
return useMemo(createBlockServiceAPIProviders, []);
|
|
151
|
+
export const useMemoizedBlockServiceAPIProviders = (sourceAri, product) => {
|
|
152
|
+
return useMemo(() => createBlockServiceAPIProviders(sourceAri, product), [sourceAri, product]);
|
|
148
153
|
};
|
|
@@ -61,7 +61,7 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
|
61
61
|
return data;
|
|
62
62
|
}, () => {
|
|
63
63
|
return {
|
|
64
|
-
|
|
64
|
+
error: SyncBlockError.Errored,
|
|
65
65
|
resourceId
|
|
66
66
|
};
|
|
67
67
|
});
|
|
@@ -139,13 +139,13 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
|
139
139
|
*
|
|
140
140
|
* @returns The source info
|
|
141
141
|
*/
|
|
142
|
-
fetchSyncBlockSourceInfo(localId, sourceAri, sourceProduct) {
|
|
142
|
+
fetchSyncBlockSourceInfo(localId, sourceAri, sourceProduct, fireAnalyticsEvent) {
|
|
143
143
|
if (!sourceAri || !sourceProduct) {
|
|
144
|
-
return Promise.
|
|
144
|
+
return Promise.reject(new Error('Source ari or source product is undefined'));
|
|
145
145
|
}
|
|
146
146
|
switch (sourceProduct) {
|
|
147
147
|
case 'confluence-page':
|
|
148
|
-
return fetchConfluencePageInfo(sourceAri, localId);
|
|
148
|
+
return fetchConfluencePageInfo(sourceAri, localId, fireAnalyticsEvent);
|
|
149
149
|
case 'jira-work-item':
|
|
150
150
|
return Promise.reject(new Error('Jira work item source product not supported'));
|
|
151
151
|
default:
|