@atlaskit/editor-synced-block-provider 2.15.0 → 2.15.2

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 CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/editor-synced-block-provider
2
2
 
3
+ ## 2.15.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [`70face9ce7f1b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/70face9ce7f1b) -
8
+ EDITOR-3778 optimise flush to only send to BE when sync block data changes
9
+ - Updated dependencies
10
+
11
+ ## 2.15.1
12
+
13
+ ### Patch Changes
14
+
15
+ - [`bf478ab5eb042`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/bf478ab5eb042) -
16
+ Fix reference synced block displays error view after re-creation despite successful fetch from
17
+ backend
18
+
3
19
  ## 2.15.0
4
20
 
5
21
  ### Minor Changes
@@ -16,10 +16,8 @@ var _utils = require("../utils/utils");
16
16
  var useFetchSyncBlockData = exports.useFetchSyncBlockData = function useFetchSyncBlockData(manager, resourceId, localId, fireAnalyticsEvent) {
17
17
  var _useState = (0, _react.useState)(function () {
18
18
  if (resourceId) {
19
- var _manager$referenceMan;
20
- var _ref = (manager === null || manager === void 0 || (_manager$referenceMan = manager.referenceManager) === null || _manager$referenceMan === void 0 ? void 0 : _manager$referenceMan.getInitialSyncBlockData(resourceId)) || {},
21
- data = _ref.data;
22
- return data || null;
19
+ var _manager$referenceMan, _manager$referenceMan2;
20
+ return (_manager$referenceMan = manager === null || manager === void 0 || (_manager$referenceMan2 = manager.referenceManager) === null || _manager$referenceMan2 === void 0 ? void 0 : _manager$referenceMan2.getInitialSyncBlockData(resourceId)) !== null && _manager$referenceMan !== void 0 ? _manager$referenceMan : null;
23
21
  }
24
22
  return null;
25
23
  }),
@@ -12,9 +12,11 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
12
12
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
13
  var _uuid = _interopRequireDefault(require("uuid"));
14
14
  var _monitoring = require("@atlaskit/editor-common/monitoring");
15
+ var _types = require("../common/types");
15
16
  var _errorHandling = require("../utils/errorHandling");
16
17
  var _utils = require("../utils/utils");
17
- // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
18
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
19
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
18
20
  // A store manager responsible for the lifecycle and state management of source sync blocks in an editor instance.
19
21
  // Designed to manage local in-memory state and synchronize with an external data provider.
20
22
  // Supports create, flush, and delete operations for source sync blocks.
@@ -58,7 +60,9 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
58
60
  throw new Error('Local ID or resource ID is not set');
59
61
  }
60
62
  var syncBlockData = (0, _utils.convertSyncBlockPMNodeToSyncBlockData)(syncBlockNode);
61
- this.syncBlockCache.set(resourceId, syncBlockData);
63
+ this.syncBlockCache.set(resourceId, _objectSpread(_objectSpread({}, syncBlockData), {}, {
64
+ isDirty: true
65
+ }));
62
66
  return true;
63
67
  } catch (error) {
64
68
  var _this$fireAnalyticsEv;
@@ -95,7 +99,8 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
95
99
  bodiedSyncBlockData = [];
96
100
  Array.from(this.syncBlockCache.values()).forEach(function (syncBlockData) {
97
101
  // Don't flush nodes that are waiting to be deleted to avoid nodes being re-created
98
- if (!syncBlockData.pendingDeletion) {
102
+ // Don't flush nodes that haven't been updated since we last flushed
103
+ if (!syncBlockData.pendingDeletion && syncBlockData.isDirty) {
99
104
  bodiedSyncBlockNodes.push({
100
105
  type: 'bodiedSyncBlock',
101
106
  attrs: {
@@ -116,37 +121,46 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
116
121
  return this.dataProvider.writeNodesData(bodiedSyncBlockNodes, bodiedSyncBlockData);
117
122
  case 10:
118
123
  writeResults = _context.sent;
124
+ writeResults.forEach(function (result) {
125
+ // set isDirty to false on write success and unrecoverable errors like not found
126
+ if (result.resourceId && (result.error === _types.SyncBlockError.NotFound || !result.error)) {
127
+ var cachedData = _this2.syncBlockCache.get(result.resourceId);
128
+ if (cachedData) {
129
+ cachedData.isDirty = false;
130
+ }
131
+ }
132
+ });
119
133
  if (!writeResults.every(function (result) {
120
- return result.resourceId !== undefined;
134
+ return result.resourceId && !result.error;
121
135
  })) {
122
- _context.next = 15;
136
+ _context.next = 16;
123
137
  break;
124
138
  }
125
139
  return _context.abrupt("return", true);
126
- case 15:
140
+ case 16:
127
141
  writeResults.filter(function (result) {
128
- return result.resourceId === undefined;
142
+ return !result.resourceId || result.error;
129
143
  }).forEach(function (result) {
130
144
  var _this2$fireAnalyticsE;
131
145
  (_this2$fireAnalyticsE = _this2.fireAnalyticsEvent) === null || _this2$fireAnalyticsE === void 0 || _this2$fireAnalyticsE.call(_this2, (0, _errorHandling.updateErrorPayload)(result.error || 'Failed to write data'));
132
146
  });
133
147
  return _context.abrupt("return", false);
134
- case 17:
135
- _context.next = 24;
148
+ case 18:
149
+ _context.next = 25;
136
150
  break;
137
- case 19:
138
- _context.prev = 19;
151
+ case 20:
152
+ _context.prev = 20;
139
153
  _context.t0 = _context["catch"](0);
140
154
  (0, _monitoring.logException)(_context.t0, {
141
155
  location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
142
156
  });
143
157
  (_this$fireAnalyticsEv2 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv2 === void 0 || _this$fireAnalyticsEv2.call(this, (0, _errorHandling.updateErrorPayload)(_context.t0.message));
144
158
  return _context.abrupt("return", false);
145
- case 24:
159
+ case 25:
146
160
  case "end":
147
161
  return _context.stop();
148
162
  }
149
- }, _callee, this, [[0, 19]]);
163
+ }, _callee, this, [[0, 20]]);
150
164
  }));
151
165
  function flush() {
152
166
  return _flush.apply(this, arguments);
@@ -6,11 +6,8 @@ import { createSyncBlockNode } from '../utils/utils';
6
6
  export const useFetchSyncBlockData = (manager, resourceId, localId, fireAnalyticsEvent) => {
7
7
  const [syncBlockInstance, setSyncBlockInstance] = useState(() => {
8
8
  if (resourceId) {
9
- var _manager$referenceMan;
10
- const {
11
- data
12
- } = (manager === null || manager === void 0 ? void 0 : (_manager$referenceMan = manager.referenceManager) === null || _manager$referenceMan === void 0 ? void 0 : _manager$referenceMan.getInitialSyncBlockData(resourceId)) || {};
13
- return data || null;
9
+ var _manager$referenceMan, _manager$referenceMan2;
10
+ return (_manager$referenceMan = manager === null || manager === void 0 ? void 0 : (_manager$referenceMan2 = manager.referenceManager) === null || _manager$referenceMan2 === void 0 ? void 0 : _manager$referenceMan2.getInitialSyncBlockData(resourceId)) !== null && _manager$referenceMan !== void 0 ? _manager$referenceMan : null;
14
11
  }
15
12
  return null;
16
13
  });
@@ -2,6 +2,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
3
3
  import uuid from 'uuid';
4
4
  import { logException } from '@atlaskit/editor-common/monitoring';
5
+ import { SyncBlockError } from '../common/types';
5
6
  import { updateErrorPayload, createErrorPayload, deleteErrorPayload, updateCacheErrorPayload } from '../utils/errorHandling';
6
7
  import { convertSyncBlockPMNodeToSyncBlockData } from '../utils/utils';
7
8
  // A store manager responsible for the lifecycle and state management of source sync blocks in an editor instance.
@@ -42,7 +43,10 @@ export class SourceSyncBlockStoreManager {
42
43
  throw new Error('Local ID or resource ID is not set');
43
44
  }
44
45
  const syncBlockData = convertSyncBlockPMNodeToSyncBlockData(syncBlockNode);
45
- this.syncBlockCache.set(resourceId, syncBlockData);
46
+ this.syncBlockCache.set(resourceId, {
47
+ ...syncBlockData,
48
+ isDirty: true
49
+ });
46
50
  return true;
47
51
  } catch (error) {
48
52
  var _this$fireAnalyticsEv;
@@ -68,7 +72,8 @@ export class SourceSyncBlockStoreManager {
68
72
  const bodiedSyncBlockData = [];
69
73
  Array.from(this.syncBlockCache.values()).forEach(syncBlockData => {
70
74
  // Don't flush nodes that are waiting to be deleted to avoid nodes being re-created
71
- if (!syncBlockData.pendingDeletion) {
75
+ // Don't flush nodes that haven't been updated since we last flushed
76
+ if (!syncBlockData.pendingDeletion && syncBlockData.isDirty) {
72
77
  bodiedSyncBlockNodes.push({
73
78
  type: 'bodiedSyncBlock',
74
79
  attrs: {
@@ -83,10 +88,19 @@ export class SourceSyncBlockStoreManager {
83
88
  return Promise.resolve(true);
84
89
  }
85
90
  const writeResults = await this.dataProvider.writeNodesData(bodiedSyncBlockNodes, bodiedSyncBlockData);
86
- if (writeResults.every(result => result.resourceId !== undefined)) {
91
+ writeResults.forEach(result => {
92
+ // set isDirty to false on write success and unrecoverable errors like not found
93
+ if (result.resourceId && (result.error === SyncBlockError.NotFound || !result.error)) {
94
+ const cachedData = this.syncBlockCache.get(result.resourceId);
95
+ if (cachedData) {
96
+ cachedData.isDirty = false;
97
+ }
98
+ }
99
+ });
100
+ if (writeResults.every(result => result.resourceId && !result.error)) {
87
101
  return true;
88
102
  } else {
89
- writeResults.filter(result => result.resourceId === undefined).forEach(result => {
103
+ writeResults.filter(result => !result.resourceId || result.error).forEach(result => {
90
104
  var _this$fireAnalyticsEv2;
91
105
  (_this$fireAnalyticsEv2 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv2 === void 0 ? void 0 : _this$fireAnalyticsEv2.call(this, updateErrorPayload(result.error || 'Failed to write data'));
92
106
  });
@@ -9,10 +9,8 @@ import { createSyncBlockNode } from '../utils/utils';
9
9
  export var useFetchSyncBlockData = function useFetchSyncBlockData(manager, resourceId, localId, fireAnalyticsEvent) {
10
10
  var _useState = useState(function () {
11
11
  if (resourceId) {
12
- var _manager$referenceMan;
13
- var _ref = (manager === null || manager === void 0 || (_manager$referenceMan = manager.referenceManager) === null || _manager$referenceMan === void 0 ? void 0 : _manager$referenceMan.getInitialSyncBlockData(resourceId)) || {},
14
- data = _ref.data;
15
- return data || null;
12
+ var _manager$referenceMan, _manager$referenceMan2;
13
+ return (_manager$referenceMan = manager === null || manager === void 0 || (_manager$referenceMan2 = manager.referenceManager) === null || _manager$referenceMan2 === void 0 ? void 0 : _manager$referenceMan2.getInitialSyncBlockData(resourceId)) !== null && _manager$referenceMan !== void 0 ? _manager$referenceMan : null;
16
14
  }
17
15
  return null;
18
16
  }),
@@ -3,9 +3,12 @@ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
3
  import _createClass from "@babel/runtime/helpers/createClass";
4
4
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
5
  import _regeneratorRuntime from "@babel/runtime/regenerator";
6
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
7
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
6
8
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
7
9
  import uuid from 'uuid';
8
10
  import { logException } from '@atlaskit/editor-common/monitoring';
11
+ import { SyncBlockError } from '../common/types';
9
12
  import { updateErrorPayload, createErrorPayload, deleteErrorPayload, updateCacheErrorPayload } from '../utils/errorHandling';
10
13
  import { convertSyncBlockPMNodeToSyncBlockData } from '../utils/utils';
11
14
  // A store manager responsible for the lifecycle and state management of source sync blocks in an editor instance.
@@ -51,7 +54,9 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
51
54
  throw new Error('Local ID or resource ID is not set');
52
55
  }
53
56
  var syncBlockData = convertSyncBlockPMNodeToSyncBlockData(syncBlockNode);
54
- this.syncBlockCache.set(resourceId, syncBlockData);
57
+ this.syncBlockCache.set(resourceId, _objectSpread(_objectSpread({}, syncBlockData), {}, {
58
+ isDirty: true
59
+ }));
55
60
  return true;
56
61
  } catch (error) {
57
62
  var _this$fireAnalyticsEv;
@@ -88,7 +93,8 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
88
93
  bodiedSyncBlockData = [];
89
94
  Array.from(this.syncBlockCache.values()).forEach(function (syncBlockData) {
90
95
  // Don't flush nodes that are waiting to be deleted to avoid nodes being re-created
91
- if (!syncBlockData.pendingDeletion) {
96
+ // Don't flush nodes that haven't been updated since we last flushed
97
+ if (!syncBlockData.pendingDeletion && syncBlockData.isDirty) {
92
98
  bodiedSyncBlockNodes.push({
93
99
  type: 'bodiedSyncBlock',
94
100
  attrs: {
@@ -109,37 +115,46 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
109
115
  return this.dataProvider.writeNodesData(bodiedSyncBlockNodes, bodiedSyncBlockData);
110
116
  case 10:
111
117
  writeResults = _context.sent;
118
+ writeResults.forEach(function (result) {
119
+ // set isDirty to false on write success and unrecoverable errors like not found
120
+ if (result.resourceId && (result.error === SyncBlockError.NotFound || !result.error)) {
121
+ var cachedData = _this2.syncBlockCache.get(result.resourceId);
122
+ if (cachedData) {
123
+ cachedData.isDirty = false;
124
+ }
125
+ }
126
+ });
112
127
  if (!writeResults.every(function (result) {
113
- return result.resourceId !== undefined;
128
+ return result.resourceId && !result.error;
114
129
  })) {
115
- _context.next = 15;
130
+ _context.next = 16;
116
131
  break;
117
132
  }
118
133
  return _context.abrupt("return", true);
119
- case 15:
134
+ case 16:
120
135
  writeResults.filter(function (result) {
121
- return result.resourceId === undefined;
136
+ return !result.resourceId || result.error;
122
137
  }).forEach(function (result) {
123
138
  var _this2$fireAnalyticsE;
124
139
  (_this2$fireAnalyticsE = _this2.fireAnalyticsEvent) === null || _this2$fireAnalyticsE === void 0 || _this2$fireAnalyticsE.call(_this2, updateErrorPayload(result.error || 'Failed to write data'));
125
140
  });
126
141
  return _context.abrupt("return", false);
127
- case 17:
128
- _context.next = 24;
142
+ case 18:
143
+ _context.next = 25;
129
144
  break;
130
- case 19:
131
- _context.prev = 19;
145
+ case 20:
146
+ _context.prev = 20;
132
147
  _context.t0 = _context["catch"](0);
133
148
  logException(_context.t0, {
134
149
  location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
135
150
  });
136
151
  (_this$fireAnalyticsEv2 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv2 === void 0 || _this$fireAnalyticsEv2.call(this, updateErrorPayload(_context.t0.message));
137
152
  return _context.abrupt("return", false);
138
- case 24:
153
+ case 25:
139
154
  case "end":
140
155
  return _context.stop();
141
156
  }
142
- }, _callee, this, [[0, 19]]);
157
+ }, _callee, this, [[0, 20]]);
143
158
  }));
144
159
  function flush() {
145
160
  return _flush.apply(this, arguments);
@@ -1,6 +1,6 @@
1
1
  import { type SyncBlockEventPayload } from '@atlaskit/editor-common/analytics';
2
2
  import { type Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
- import type { ResourceId, SyncBlockAttrs } from '../common/types';
3
+ import { type ResourceId, type SyncBlockAttrs } from '../common/types';
4
4
  import type { SyncBlockDataProvider } from '../providers/types';
5
5
  export type ConfirmationCallback = (syncBlockCount: number) => Promise<boolean>;
6
6
  type OnDelete = () => void;
@@ -1,6 +1,6 @@
1
1
  import { type SyncBlockEventPayload } from '@atlaskit/editor-common/analytics';
2
2
  import { type Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
- import type { ResourceId, SyncBlockAttrs } from '../common/types';
3
+ import { type ResourceId, type SyncBlockAttrs } from '../common/types';
4
4
  import type { SyncBlockDataProvider } from '../providers/types';
5
5
  export type ConfirmationCallback = (syncBlockCount: number) => Promise<boolean>;
6
6
  type OnDelete = () => void;
package/package.json CHANGED
@@ -77,7 +77,7 @@
77
77
  }
78
78
  },
79
79
  "name": "@atlaskit/editor-synced-block-provider",
80
- "version": "2.15.0",
80
+ "version": "2.15.2",
81
81
  "description": "Synced Block Provider for @atlaskit/editor-plugin-synced-block",
82
82
  "author": "Atlassian Pty Ltd",
83
83
  "license": "Apache-2.0",