@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.
Files changed (52) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/clients/block-service/blockService.js +5 -4
  3. package/dist/cjs/clients/confluence/sourceInfo.js +18 -15
  4. package/dist/cjs/hooks/useFetchSyncBlockData.js +20 -11
  5. package/dist/cjs/hooks/useHandleContentChanges.js +1 -5
  6. package/dist/cjs/providers/block-service/blockServiceAPI.js +17 -12
  7. package/dist/cjs/providers/syncBlockProvider.js +4 -4
  8. package/dist/cjs/store-manager/referenceSyncBlockStoreManager.js +118 -66
  9. package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +112 -55
  10. package/dist/cjs/store-manager/syncBlockStoreManager.js +3 -3
  11. package/dist/cjs/utils/errorHandling.js +31 -1
  12. package/dist/es2019/clients/block-service/blockService.js +5 -4
  13. package/dist/es2019/clients/confluence/sourceInfo.js +13 -8
  14. package/dist/es2019/hooks/useFetchSyncBlockData.js +15 -7
  15. package/dist/es2019/hooks/useHandleContentChanges.js +1 -5
  16. package/dist/es2019/providers/block-service/blockServiceAPI.js +13 -8
  17. package/dist/es2019/providers/syncBlockProvider.js +4 -4
  18. package/dist/es2019/store-manager/referenceSyncBlockStoreManager.js +105 -51
  19. package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +73 -25
  20. package/dist/es2019/store-manager/syncBlockStoreManager.js +3 -3
  21. package/dist/es2019/utils/errorHandling.js +17 -1
  22. package/dist/esm/clients/block-service/blockService.js +5 -4
  23. package/dist/esm/clients/confluence/sourceInfo.js +18 -15
  24. package/dist/esm/hooks/useFetchSyncBlockData.js +20 -11
  25. package/dist/esm/hooks/useHandleContentChanges.js +1 -5
  26. package/dist/esm/providers/block-service/blockServiceAPI.js +17 -12
  27. package/dist/esm/providers/syncBlockProvider.js +4 -4
  28. package/dist/esm/store-manager/referenceSyncBlockStoreManager.js +118 -66
  29. package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +110 -53
  30. package/dist/esm/store-manager/syncBlockStoreManager.js +3 -3
  31. package/dist/esm/utils/errorHandling.js +30 -0
  32. package/dist/types/clients/block-service/blockService.d.ts +0 -2
  33. package/dist/types/clients/confluence/sourceInfo.d.ts +2 -1
  34. package/dist/types/hooks/useFetchSyncBlockData.d.ts +2 -1
  35. package/dist/types/providers/block-service/blockServiceAPI.d.ts +6 -3
  36. package/dist/types/providers/syncBlockProvider.d.ts +2 -1
  37. package/dist/types/providers/types.d.ts +2 -1
  38. package/dist/types/store-manager/referenceSyncBlockStoreManager.d.ts +4 -1
  39. package/dist/types/store-manager/sourceSyncBlockStoreManager.d.ts +3 -1
  40. package/dist/types/store-manager/syncBlockStoreManager.d.ts +2 -1
  41. package/dist/types/utils/errorHandling.d.ts +10 -0
  42. package/dist/types-ts4.5/clients/block-service/blockService.d.ts +0 -2
  43. package/dist/types-ts4.5/clients/confluence/sourceInfo.d.ts +2 -1
  44. package/dist/types-ts4.5/hooks/useFetchSyncBlockData.d.ts +2 -1
  45. package/dist/types-ts4.5/providers/block-service/blockServiceAPI.d.ts +6 -3
  46. package/dist/types-ts4.5/providers/syncBlockProvider.d.ts +2 -1
  47. package/dist/types-ts4.5/providers/types.d.ts +2 -1
  48. package/dist/types-ts4.5/store-manager/referenceSyncBlockStoreManager.d.ts +4 -1
  49. package/dist/types-ts4.5/store-manager/sourceSyncBlockStoreManager.d.ts +3 -1
  50. package/dist/types-ts4.5/store-manager/syncBlockStoreManager.d.ts +2 -1
  51. package/dist/types-ts4.5/utils/errorHandling.d.ts +10 -0
  52. 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 _utils = require("../utils/utils");
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
- if (!this.isSourceBlock(syncBlockNode)) {
49
- throw new Error('Invalid sync block node type provided for updateSyncBlockData');
50
- }
51
- var _syncBlockNode$attrs = syncBlockNode.attrs,
52
- localId = _syncBlockNode$attrs.localId,
53
- resourceId = _syncBlockNode$attrs.resourceId;
54
- if (!localId || !resourceId) {
55
- throw new Error('Local ID or resource ID is not set');
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 bodiedSyncBlockNodes, bodiedSyncBlockData, writeResults;
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
- return _context.abrupt("return", writeResults.every(function (result) {
121
+ if (!writeResults.every(function (result) {
108
122
  return result.resourceId !== undefined;
109
- }));
110
- case 14:
111
- _context.prev = 14;
112
- _context.t0 = _context["catch"](0);
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, 14]]);
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 _this2 = this;
204
+ var _this3 = this;
172
205
  this.confirmationCallback = callback;
173
206
  return function () {
174
- _this2.confirmationCallback = undefined;
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('Provider of sync block plugin is not set');
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 _this3 = this;
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, _utils.createBodiedSyncBlockNode)(blockInstanceId, resourceId)], [{
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
- _this3.commitPendingCreation(true);
258
+ _this4.commitPendingCreation(true);
226
259
  } else {
227
- _this3.commitPendingCreation(false);
228
- // TODO: EDITOR-1921 - add error analytics
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 (_reason) {
232
- _this3.commitPendingCreation(false);
233
- // TODO: EDITOR-1921 - add error analytics
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
- // TODO: EDITOR-1921 - add error analytics
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 _this4 = this;
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 = 22;
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 = 21;
304
+ _context2.next = 25;
263
305
  break;
264
306
  }
265
- (_this$editorView = this.editorView) === null || _this$editorView === void 0 || _this$editorView.dispatch(this.confirmationTransaction.setMeta('isConfirmedSyncBlockDeletion', true));
266
- _context2.prev = 7;
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 = 10;
316
+ _context2.next = 12;
269
317
  break;
270
318
  }
271
319
  throw new Error('Data provider not set');
272
- case 10:
320
+ case 12:
273
321
  syncBlockIds.forEach(function (Ids) {
274
- _this4.setPendingDeletion(Ids, true);
322
+ _this5.setPendingDeletion(Ids, true);
275
323
  });
276
- _context2.next = 13;
324
+ _context2.next = 15;
277
325
  return this.dataProvider.deleteNodesData(syncBlockIds.map(function (attrs) {
278
326
  return attrs.resourceId;
279
327
  }));
280
- case 13:
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 _this4.syncBlockCache.delete(Ids.resourceId);
334
+ return _this5.syncBlockCache.delete(Ids.resourceId);
287
335
  };
288
336
  } else {
289
337
  callback = function callback(Ids) {
290
- _this4.setPendingDeletion(Ids, false);
338
+ _this5.setPendingDeletion(Ids, false);
291
339
  };
292
- // TODO: EDITOR-1921 - add error analytics
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 = 21;
348
+ _context2.next = 25;
296
349
  break;
297
- case 18:
298
- _context2.prev = 18;
299
- _context2.t0 = _context2["catch"](7);
350
+ case 20:
351
+ _context2.prev = 20;
352
+ _context2.t0 = _context2["catch"](9);
300
353
  syncBlockIds.forEach(function (Ids) {
301
- _this4.setPendingDeletion(Ids, false);
354
+ _this5.setPendingDeletion(Ids, false);
355
+ });
356
+ (0, _monitoring.logException)(_context2.t0, {
357
+ location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
302
358
  });
303
- // TODO: EDITOR-1921 - add error analytics
304
- case 21:
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 22:
362
+ case 26:
307
363
  case "end":
308
364
  return _context2.stop();
309
365
  }
310
- }, _callee2, this, [[7, 18]]);
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/${blockAri}`, {
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
- if (!contentData) {
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
- // TODO: EDITOR-1921 - add error analytics
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
- try {
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: resourceId,
87
- product: 'confluence-page',
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(sourceId, localId) {
131
- return blockResourceIdFromSourceAndLocalId(sourceId, localId);
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
- status: SyncBlockError.Errored,
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.resolve(undefined);
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: