@atlaskit/editor-synced-block-provider 4.2.8 → 4.2.9

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,19 @@
1
1
  # @atlaskit/editor-synced-block-provider
2
2
 
3
+ ## 4.2.9
4
+
5
+ ### Patch Changes
6
+
7
+ - [`827be3d512390`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/827be3d512390) -
8
+ Refactor source synced block cache update to use appendTransaction instead of nodeview update.
9
+ Behind fg('platform_synced_block_update_refactor'):
10
+ - Moves cache update from nodeview update() to PM plugin appendTransaction hook, filtering out
11
+ non-user changes (remote collab, table auto-scale, dirty transactions)
12
+ - Moves initial cache population from nodeview constructor to PM plugin state.init()
13
+ - Optimises updateSyncBlockData with Fragment.eq() for O(1) comparison instead of toJSON() +
14
+ lodash/isEqual
15
+ - Updated dependencies
16
+
3
17
  ## 4.2.8
4
18
 
5
19
  ### Patch Changes
@@ -83,14 +83,31 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
83
83
  if (!localId || !resourceId) {
84
84
  throw new Error('Local ID or resource ID is not set');
85
85
  }
86
- var syncBlockData = (0, _utils.convertSyncBlockPMNodeToSyncBlockData)(syncBlockNode);
87
86
  var cachedBlock = this.syncBlockCache.get(resourceId);
88
- if (cachedBlock && !(0, _isEqual.default)(syncBlockData.content, cachedBlock.content)) {
89
- this.hasReceivedContentChange = true;
87
+ if ((0, _platformFeatureFlags.fg)('platform_synced_block_update_refactor')) {
88
+ var _cachedBlock$contentF;
89
+ // Fast path: if the PM content fragment hasn't changed, skip serialization entirely
90
+ // Fragment.eq() leverages ProseMirror's structural sharing for O(1) comparison
91
+ if (cachedBlock !== null && cachedBlock !== void 0 && (_cachedBlock$contentF = cachedBlock.contentFragment) !== null && _cachedBlock$contentF !== void 0 && _cachedBlock$contentF.eq(syncBlockNode.content)) {
92
+ return true;
93
+ }
94
+ var syncBlockData = (0, _utils.convertSyncBlockPMNodeToSyncBlockData)(syncBlockNode);
95
+ if (cachedBlock) {
96
+ this.hasReceivedContentChange = true;
97
+ }
98
+ this.syncBlockCache.set(resourceId, _objectSpread(_objectSpread({}, syncBlockData), {}, {
99
+ isDirty: true,
100
+ contentFragment: syncBlockNode.content
101
+ }));
102
+ } else {
103
+ var _syncBlockData = (0, _utils.convertSyncBlockPMNodeToSyncBlockData)(syncBlockNode);
104
+ if (cachedBlock && !(0, _isEqual.default)(_syncBlockData.content, cachedBlock.content)) {
105
+ this.hasReceivedContentChange = true;
106
+ }
107
+ this.syncBlockCache.set(resourceId, _objectSpread(_objectSpread({}, _syncBlockData), {}, {
108
+ isDirty: true
109
+ }));
90
110
  }
91
- this.syncBlockCache.set(resourceId, _objectSpread(_objectSpread({}, syncBlockData), {}, {
92
- isDirty: true
93
- }));
94
111
  return true;
95
112
  } catch (error) {
96
113
  var _this$fireAnalyticsEv;
@@ -61,15 +61,33 @@ export class SourceSyncBlockStoreManager {
61
61
  if (!localId || !resourceId) {
62
62
  throw new Error('Local ID or resource ID is not set');
63
63
  }
64
- const syncBlockData = convertSyncBlockPMNodeToSyncBlockData(syncBlockNode);
65
64
  const cachedBlock = this.syncBlockCache.get(resourceId);
66
- if (cachedBlock && !isEqual(syncBlockData.content, cachedBlock.content)) {
67
- this.hasReceivedContentChange = true;
65
+ if (fg('platform_synced_block_update_refactor')) {
66
+ var _cachedBlock$contentF;
67
+ // Fast path: if the PM content fragment hasn't changed, skip serialization entirely
68
+ // Fragment.eq() leverages ProseMirror's structural sharing for O(1) comparison
69
+ if (cachedBlock !== null && cachedBlock !== void 0 && (_cachedBlock$contentF = cachedBlock.contentFragment) !== null && _cachedBlock$contentF !== void 0 && _cachedBlock$contentF.eq(syncBlockNode.content)) {
70
+ return true;
71
+ }
72
+ const syncBlockData = convertSyncBlockPMNodeToSyncBlockData(syncBlockNode);
73
+ if (cachedBlock) {
74
+ this.hasReceivedContentChange = true;
75
+ }
76
+ this.syncBlockCache.set(resourceId, {
77
+ ...syncBlockData,
78
+ isDirty: true,
79
+ contentFragment: syncBlockNode.content
80
+ });
81
+ } else {
82
+ const syncBlockData = convertSyncBlockPMNodeToSyncBlockData(syncBlockNode);
83
+ if (cachedBlock && !isEqual(syncBlockData.content, cachedBlock.content)) {
84
+ this.hasReceivedContentChange = true;
85
+ }
86
+ this.syncBlockCache.set(resourceId, {
87
+ ...syncBlockData,
88
+ isDirty: true
89
+ });
68
90
  }
69
- this.syncBlockCache.set(resourceId, {
70
- ...syncBlockData,
71
- isDirty: true
72
- });
73
91
  return true;
74
92
  } catch (error) {
75
93
  var _this$fireAnalyticsEv;
@@ -76,14 +76,31 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
76
76
  if (!localId || !resourceId) {
77
77
  throw new Error('Local ID or resource ID is not set');
78
78
  }
79
- var syncBlockData = convertSyncBlockPMNodeToSyncBlockData(syncBlockNode);
80
79
  var cachedBlock = this.syncBlockCache.get(resourceId);
81
- if (cachedBlock && !isEqual(syncBlockData.content, cachedBlock.content)) {
82
- this.hasReceivedContentChange = true;
80
+ if (fg('platform_synced_block_update_refactor')) {
81
+ var _cachedBlock$contentF;
82
+ // Fast path: if the PM content fragment hasn't changed, skip serialization entirely
83
+ // Fragment.eq() leverages ProseMirror's structural sharing for O(1) comparison
84
+ if (cachedBlock !== null && cachedBlock !== void 0 && (_cachedBlock$contentF = cachedBlock.contentFragment) !== null && _cachedBlock$contentF !== void 0 && _cachedBlock$contentF.eq(syncBlockNode.content)) {
85
+ return true;
86
+ }
87
+ var syncBlockData = convertSyncBlockPMNodeToSyncBlockData(syncBlockNode);
88
+ if (cachedBlock) {
89
+ this.hasReceivedContentChange = true;
90
+ }
91
+ this.syncBlockCache.set(resourceId, _objectSpread(_objectSpread({}, syncBlockData), {}, {
92
+ isDirty: true,
93
+ contentFragment: syncBlockNode.content
94
+ }));
95
+ } else {
96
+ var _syncBlockData = convertSyncBlockPMNodeToSyncBlockData(syncBlockNode);
97
+ if (cachedBlock && !isEqual(_syncBlockData.content, cachedBlock.content)) {
98
+ this.hasReceivedContentChange = true;
99
+ }
100
+ this.syncBlockCache.set(resourceId, _objectSpread(_objectSpread({}, _syncBlockData), {}, {
101
+ isDirty: true
102
+ }));
83
103
  }
84
- this.syncBlockCache.set(resourceId, _objectSpread(_objectSpread({}, syncBlockData), {}, {
85
- isDirty: true
86
- }));
87
104
  return true;
88
105
  } catch (error) {
89
106
  var _this$fireAnalyticsEv;
package/package.json CHANGED
@@ -29,7 +29,7 @@
29
29
  "@atlaskit/editor-prosemirror": "^7.3.0",
30
30
  "@atlaskit/node-data-provider": "^9.0.0",
31
31
  "@atlaskit/platform-feature-flags": "^1.1.0",
32
- "@atlaskit/tmp-editor-statsig": "^51.0.0",
32
+ "@atlaskit/tmp-editor-statsig": "^51.1.0",
33
33
  "@babel/runtime": "^7.0.0",
34
34
  "@compiled/react": "^0.20.0",
35
35
  "graphql-ws": "^5.14.2",
@@ -81,7 +81,7 @@
81
81
  }
82
82
  },
83
83
  "name": "@atlaskit/editor-synced-block-provider",
84
- "version": "4.2.8",
84
+ "version": "4.2.9",
85
85
  "description": "Synced Block Provider for @atlaskit/editor-plugin-synced-block",
86
86
  "author": "Atlassian Pty Ltd",
87
87
  "license": "Apache-2.0",
@@ -95,6 +95,9 @@
95
95
  "platform_synced_block_patch_7": {
96
96
  "type": "boolean"
97
97
  },
98
+ "platform_synced_block_update_refactor": {
99
+ "type": "boolean"
100
+ },
98
101
  "platform_synced_block_patch_8": {
99
102
  "type": "boolean"
100
103
  }