@atlaskit/editor-plugin-synced-block 8.3.1 → 8.3.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 +9 -0
- package/dist/cjs/nodeviews/syncedBlock.js +5 -2
- package/dist/cjs/pm-plugins/main.js +16 -9
- package/dist/cjs/pm-plugins/menu-and-toolbar-experiences.js +6 -2
- package/dist/cjs/syncedBlockPlugin.js +7 -2
- package/dist/es2019/nodeviews/syncedBlock.js +5 -2
- package/dist/es2019/pm-plugins/main.js +16 -9
- package/dist/es2019/pm-plugins/menu-and-toolbar-experiences.js +6 -2
- package/dist/es2019/syncedBlockPlugin.js +7 -2
- package/dist/esm/nodeviews/syncedBlock.js +5 -2
- package/dist/esm/pm-plugins/main.js +16 -9
- package/dist/esm/pm-plugins/menu-and-toolbar-experiences.js +6 -2
- package/dist/esm/syncedBlockPlugin.js +7 -2
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-synced-block
|
|
2
2
|
|
|
3
|
+
## 8.3.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`13169b42740a8`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/13169b42740a8) -
|
|
8
|
+
Cache experiment value at plugin creation to avoid redundant Statsig SDK evaluations on every
|
|
9
|
+
editor transaction
|
|
10
|
+
- Updated dependencies
|
|
11
|
+
|
|
3
12
|
## 8.3.1
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
|
@@ -17,7 +17,7 @@ var _analytics = require("@atlaskit/editor-common/analytics");
|
|
|
17
17
|
var _errorBoundary = require("@atlaskit/editor-common/error-boundary");
|
|
18
18
|
var _reactNodeView = _interopRequireDefault(require("@atlaskit/editor-common/react-node-view"));
|
|
19
19
|
var _syncBlock = require("@atlaskit/editor-common/sync-block");
|
|
20
|
-
var
|
|
20
|
+
var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
|
|
21
21
|
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
22
22
|
var _editorCommands = require("../editor-commands");
|
|
23
23
|
var _SyncBlockRendererWrapper = require("../ui/SyncBlockRendererWrapper");
|
|
@@ -95,7 +95,10 @@ var SyncBlock = exports.SyncBlock = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
95
95
|
if (!syncBlockStore) {
|
|
96
96
|
return null;
|
|
97
97
|
}
|
|
98
|
-
|
|
98
|
+
|
|
99
|
+
// Use expValEqualsNoExposure — the exposure is already fired once at plugin
|
|
100
|
+
// creation time in syncedBlockPlugin.tsx and main.ts createPlugin().
|
|
101
|
+
var isPerfEnabled = (0, _expValEqualsNoExposure.expValEqualsNoExposure)('editor_synced_block_perf', 'isEnabled', true);
|
|
99
102
|
|
|
100
103
|
// get document node from data provider
|
|
101
104
|
return /*#__PURE__*/_react.default.createElement(_errorBoundary.ErrorBoundary, {
|
|
@@ -41,13 +41,13 @@ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol
|
|
|
41
41
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
42
42
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
43
43
|
var syncedBlockPluginKey = exports.syncedBlockPluginKey = new _state.PluginKey('syncedBlockPlugin');
|
|
44
|
-
var mapRetryCreationPosMap = function mapRetryCreationPosMap(oldMap, newRetryCreationPos, mapPos) {
|
|
44
|
+
var mapRetryCreationPosMap = function mapRetryCreationPosMap(oldMap, newRetryCreationPos, mapPos, isPerfExperimentOn) {
|
|
45
45
|
var resourceId = newRetryCreationPos === null || newRetryCreationPos === void 0 ? void 0 : newRetryCreationPos.resourceId;
|
|
46
46
|
|
|
47
47
|
// Fast path: no new entry and nothing to remap — return the same reference.
|
|
48
48
|
// This is critical for PR-E (EDITOR-6929) which relies on reference equality
|
|
49
49
|
// to short-circuit SharedStateAPI deep-equality checks.
|
|
50
|
-
if (
|
|
50
|
+
if (isPerfExperimentOn && !resourceId && oldMap.size === 0) {
|
|
51
51
|
return oldMap;
|
|
52
52
|
}
|
|
53
53
|
var newMap = new Map(oldMap);
|
|
@@ -306,6 +306,12 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
306
306
|
var _ref6 = options || {},
|
|
307
307
|
_ref6$useLongPressSel = _ref6.useLongPressSelection,
|
|
308
308
|
useLongPressSelection = _ref6$useLongPressSel === void 0 ? false : _ref6$useLongPressSel;
|
|
309
|
+
|
|
310
|
+
// Cache the experiment value once at plugin creation time.
|
|
311
|
+
// This fires the exposure event exactly once (correct per Exposure Events 101)
|
|
312
|
+
// and avoids ~10 redundant Statsig SDK evaluations per keystroke in hot paths
|
|
313
|
+
// (apply, filterTransaction, appendTransaction, decorations).
|
|
314
|
+
var isPerfExperimentOn = (0, _expValEquals.expValEquals)('editor_synced_block_perf', 'isEnabled', true);
|
|
309
315
|
var ctx = new SyncedBlockPluginContext();
|
|
310
316
|
var confirmationTransactionRef = ctx.confirmationTransactionRef;
|
|
311
317
|
var unpublishedFlagShown = ctx.unpublishedFlagShown;
|
|
@@ -356,7 +362,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
356
362
|
// synced blocks, we skip the eager fetch + cache walks. They will be
|
|
357
363
|
// re-run lazily by `apply` the first time a synced block enters the
|
|
358
364
|
// document (paste, collab insert, or programmatic insert).
|
|
359
|
-
var docHasSyncedBlocks =
|
|
365
|
+
var docHasSyncedBlocks = isPerfExperimentOn ? (0, _hasSyncedBlocks.hasSyncedBlocks)(instance.doc) : true;
|
|
360
366
|
if (docHasSyncedBlocks) {
|
|
361
367
|
var syncBlockNodes = instance.doc.children.filter(syncBlockStore.referenceManager.isReferenceBlock);
|
|
362
368
|
syncBlockStore.referenceManager.fetchSyncBlocksData((0, _editorSyncedBlockProvider.convertPMNodesToSyncBlockNodes)(syncBlockNodes));
|
|
@@ -386,7 +392,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
386
392
|
// When the perf gate is ON and the doc has synced blocks we do a
|
|
387
393
|
// single traversal here; afterwards `apply()` will map or rebuild
|
|
388
394
|
// only when a status signal changes.
|
|
389
|
-
var initStatusDecorationSet = docHasSyncedBlocks &&
|
|
395
|
+
var initStatusDecorationSet = docHasSyncedBlocks && isPerfExperimentOn ? buildStatusDecorations(instance.doc, syncBlockStore, initIsOffline, initIsViewMode, initIsDragging) : _view.DecorationSet.empty;
|
|
390
396
|
return {
|
|
391
397
|
selectionDecorationSet: (0, _selectionDecorations.calculateDecorations)(instance.doc, instance.selection, instance.schema),
|
|
392
398
|
activeFlag: false,
|
|
@@ -403,7 +409,8 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
403
409
|
apply: function apply(tr, currentPluginState, oldEditorState) {
|
|
404
410
|
var _meta$activeFlag, _meta$bodiedSyncBlock;
|
|
405
411
|
var meta = tr.getMeta(syncedBlockPluginKey);
|
|
406
|
-
|
|
412
|
+
// isPerfExperimentOn is cached at createPlugin() level — see above
|
|
413
|
+
|
|
407
414
|
var activeFlag = currentPluginState.activeFlag,
|
|
408
415
|
selectionDecorationSet = currentPluginState.selectionDecorationSet,
|
|
409
416
|
bodiedSyncBlockDeletionStatus = currentPluginState.bodiedSyncBlockDeletionStatus,
|
|
@@ -481,7 +488,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
481
488
|
}
|
|
482
489
|
}
|
|
483
490
|
var newPosEntry = meta === null || meta === void 0 ? void 0 : meta.retryCreationPos;
|
|
484
|
-
var newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping));
|
|
491
|
+
var newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping), isPerfExperimentOn);
|
|
485
492
|
var nextActiveFlag = (_meta$activeFlag = meta === null || meta === void 0 ? void 0 : meta.activeFlag) !== null && _meta$activeFlag !== void 0 ? _meta$activeFlag : activeFlag;
|
|
486
493
|
var nextBodiedSyncBlockDeletionStatus = (_meta$bodiedSyncBlock = meta === null || meta === void 0 ? void 0 : meta.bodiedSyncBlockDeletionStatus) !== null && _meta$bodiedSyncBlock !== void 0 ? _meta$bodiedSyncBlock : bodiedSyncBlockDeletionStatus;
|
|
487
494
|
var nextHasUnsavedBodiedSyncBlockChanges = syncBlockStore.sourceManager.hasUnsavedChanges();
|
|
@@ -555,7 +562,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
555
562
|
// `apply()`. The `decorations` prop is now an O(1) merge of
|
|
556
563
|
// the two cached sets — no `doc.descendants()` walk, no
|
|
557
564
|
// shared-state reads.
|
|
558
|
-
if (
|
|
565
|
+
if (isPerfExperimentOn) {
|
|
559
566
|
var _api$focus$sharedStat, _api$focus;
|
|
560
567
|
if (!docHasSyncedBlocks) {
|
|
561
568
|
return selectionDecorationSet;
|
|
@@ -679,7 +686,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
679
686
|
// transaction does not insert one, all downstream filter logic is a
|
|
680
687
|
// no-op. Avoid both the shared-state reads and the `trackSyncBlocks`
|
|
681
688
|
// walks for the ~99.97% of pages that have no synced blocks.
|
|
682
|
-
if (
|
|
689
|
+
if (isPerfExperimentOn) {
|
|
683
690
|
var pluginState = syncedBlockPluginKey.getState(state);
|
|
684
691
|
if (pluginState && !pluginState.hasSyncedBlocks && !(0, _transactionInsertsSyncedBlock.transactionInsertsSyncedBlock)(tr)) {
|
|
685
692
|
return true;
|
|
@@ -769,7 +776,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
769
776
|
// synced block (and none of the dispatched transactions inserts one),
|
|
770
777
|
// skip all downstream work. This is the hot path on the ~99.97% of
|
|
771
778
|
// pages that don't use synced blocks (see EDITOR-6586).
|
|
772
|
-
if (
|
|
779
|
+
if (isPerfExperimentOn) {
|
|
773
780
|
var oldPluginState = syncedBlockPluginKey.getState(oldState);
|
|
774
781
|
var newPluginState = syncedBlockPluginKey.getState(newState);
|
|
775
782
|
var hadOrHasSyncedBlocks = !!(oldPluginState !== null && oldPluginState !== void 0 && oldPluginState.hasSyncedBlocks) || !!(newPluginState !== null && newPluginState !== void 0 && newPluginState.hasSyncedBlocks);
|
|
@@ -23,6 +23,10 @@ var targetEl;
|
|
|
23
23
|
var getMenuAndToolbarExperiencesPlugin = exports.getMenuAndToolbarExperiencesPlugin = function getMenuAndToolbarExperiencesPlugin(_ref) {
|
|
24
24
|
var refs = _ref.refs,
|
|
25
25
|
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
|
|
26
|
+
// Cache the experiment value once at plugin creation time.
|
|
27
|
+
// This fires the exposure event exactly once (correct per Exposure Events 101)
|
|
28
|
+
// and avoids redundant Statsig SDK evaluations in the view() and update() hooks.
|
|
29
|
+
var isPerfExperimentOn = (0, _expValEquals.expValEquals)('editor_synced_block_perf', 'isEnabled', true);
|
|
26
30
|
var popupsTargetEl;
|
|
27
31
|
var editorViewRef = {
|
|
28
32
|
current: undefined
|
|
@@ -185,13 +189,13 @@ var getMenuAndToolbarExperiencesPlugin = exports.getMenuAndToolbarExperiencesPlu
|
|
|
185
189
|
unbindClickListener = unbinders.unbindClickListener;
|
|
186
190
|
unbindKeydownListener = unbinders.unbindKeydownListener;
|
|
187
191
|
};
|
|
188
|
-
if ((_syncedBlockPluginKey = _main.syncedBlockPluginKey.getState(_view.state)) !== null && _syncedBlockPluginKey !== void 0 && _syncedBlockPluginKey.hasSyncedBlocks || !
|
|
192
|
+
if ((_syncedBlockPluginKey = _main.syncedBlockPluginKey.getState(_view.state)) !== null && _syncedBlockPluginKey !== void 0 && _syncedBlockPluginKey.hasSyncedBlocks || !isPerfExperimentOn) {
|
|
189
193
|
ensureListenersBound();
|
|
190
194
|
}
|
|
191
195
|
return {
|
|
192
196
|
update: function update(view, prevState) {
|
|
193
197
|
var _syncedBlockPluginKey2;
|
|
194
|
-
if (!listenersBound && view.state.doc !== prevState.doc && (_syncedBlockPluginKey2 = _main.syncedBlockPluginKey.getState(view.state)) !== null && _syncedBlockPluginKey2 !== void 0 && _syncedBlockPluginKey2.hasSyncedBlocks &&
|
|
198
|
+
if (!listenersBound && view.state.doc !== prevState.doc && (_syncedBlockPluginKey2 = _main.syncedBlockPluginKey.getState(view.state)) !== null && _syncedBlockPluginKey2 !== void 0 && _syncedBlockPluginKey2.hasSyncedBlocks && isPerfExperimentOn) {
|
|
195
199
|
// Bind listeners now that synced blocks are present.
|
|
196
200
|
ensureListenersBound();
|
|
197
201
|
}
|
|
@@ -10,6 +10,7 @@ var _adfSchema = require("@atlaskit/adf-schema");
|
|
|
10
10
|
var _hooks = require("@atlaskit/editor-common/hooks");
|
|
11
11
|
var _editorSyncedBlockProvider = require("@atlaskit/editor-synced-block-provider");
|
|
12
12
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
13
|
+
var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
|
|
13
14
|
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
14
15
|
var _editorActions = require("./editor-actions");
|
|
15
16
|
var _editorCommands = require("./editor-commands");
|
|
@@ -38,7 +39,11 @@ var LazySyncedBlockUI = function LazySyncedBlockUI(_ref) {
|
|
|
38
39
|
var _states$syncedBlockSt;
|
|
39
40
|
return (_states$syncedBlockSt = states.syncedBlockState) === null || _states$syncedBlockSt === void 0 ? void 0 : _states$syncedBlockSt.hasSyncedBlocks;
|
|
40
41
|
});
|
|
41
|
-
|
|
42
|
+
|
|
43
|
+
// Use expValEqualsNoExposure here because the exposure is already fired
|
|
44
|
+
// once at plugin creation time (see syncedBlockPlugin below).
|
|
45
|
+
// This component re-renders on every transaction — avoid redundant SDK evaluations.
|
|
46
|
+
if (!hasSyncBlocks && (0, _expValEqualsNoExposure.expValEqualsNoExposure)('editor_synced_block_perf', 'isEnabled', true)) {
|
|
42
47
|
return null;
|
|
43
48
|
}
|
|
44
49
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_SyncBlockRefresher.SyncBlockRefresher, {
|
|
@@ -175,7 +180,7 @@ var syncedBlockPlugin = exports.syncedBlockPlugin = function syncedBlockPlugin(_
|
|
|
175
180
|
|
|
176
181
|
// --- EDITOR-6929 / PR-F: return a stable reference when all
|
|
177
182
|
// fields are unchanged to prevent unnecessary React re-renders. ---
|
|
178
|
-
if (cachedSharedState !== undefined && cachedSharedState.activeFlag === activeFlag && cachedSharedState.syncBlockStore === currentSyncBlockStore && cachedSharedState.bodiedSyncBlockDeletionStatus === bodiedSyncBlockDeletionStatus && cachedSharedState.retryCreationPosMap === retryCreationPosMap && cachedSharedState.hasSyncedBlocks === hasSyncedBlocks && cachedSharedState.hasUnsavedBodiedSyncBlockChanges === hasUnsavedBodiedSyncBlockChanges &&
|
|
183
|
+
if (cachedSharedState !== undefined && cachedSharedState.activeFlag === activeFlag && cachedSharedState.syncBlockStore === currentSyncBlockStore && cachedSharedState.bodiedSyncBlockDeletionStatus === bodiedSyncBlockDeletionStatus && cachedSharedState.retryCreationPosMap === retryCreationPosMap && cachedSharedState.hasSyncedBlocks === hasSyncedBlocks && cachedSharedState.hasUnsavedBodiedSyncBlockChanges === hasUnsavedBodiedSyncBlockChanges && isPerfExperimentOn) {
|
|
179
184
|
return cachedSharedState;
|
|
180
185
|
}
|
|
181
186
|
var nextSharedState = {
|
|
@@ -4,7 +4,7 @@ import { ACTION_SUBJECT } from '@atlaskit/editor-common/analytics';
|
|
|
4
4
|
import { ErrorBoundary } from '@atlaskit/editor-common/error-boundary';
|
|
5
5
|
import ReactNodeView from '@atlaskit/editor-common/react-node-view';
|
|
6
6
|
import { SyncBlockSharedCssClassName, SyncBlockActionsProvider } from '@atlaskit/editor-common/sync-block';
|
|
7
|
-
import {
|
|
7
|
+
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
8
8
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
9
9
|
import { removeSyncedBlockAtPos } from '../editor-commands';
|
|
10
10
|
import { SyncBlockRendererWrapper } from '../ui/SyncBlockRendererWrapper';
|
|
@@ -64,7 +64,10 @@ export class SyncBlock extends ReactNodeView {
|
|
|
64
64
|
if (!syncBlockStore) {
|
|
65
65
|
return null;
|
|
66
66
|
}
|
|
67
|
-
|
|
67
|
+
|
|
68
|
+
// Use expValEqualsNoExposure — the exposure is already fired once at plugin
|
|
69
|
+
// creation time in syncedBlockPlugin.tsx and main.ts createPlugin().
|
|
70
|
+
const isPerfEnabled = expValEqualsNoExposure('editor_synced_block_perf', 'isEnabled', true);
|
|
68
71
|
|
|
69
72
|
// get document node from data provider
|
|
70
73
|
return /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
@@ -26,13 +26,13 @@ import { hasEditInSyncBlock, trackSyncBlocks } from './utils/track-sync-blocks';
|
|
|
26
26
|
import { transactionInsertsSyncedBlock } from './utils/transaction-inserts-synced-block';
|
|
27
27
|
import { deferDispatch, wasExtensionInsertedInBodiedSyncBlock, sliceFullyContainsNode } from './utils/utils';
|
|
28
28
|
export const syncedBlockPluginKey = new PluginKey('syncedBlockPlugin');
|
|
29
|
-
const mapRetryCreationPosMap = (oldMap, newRetryCreationPos, mapPos) => {
|
|
29
|
+
const mapRetryCreationPosMap = (oldMap, newRetryCreationPos, mapPos, isPerfExperimentOn) => {
|
|
30
30
|
const resourceId = newRetryCreationPos === null || newRetryCreationPos === void 0 ? void 0 : newRetryCreationPos.resourceId;
|
|
31
31
|
|
|
32
32
|
// Fast path: no new entry and nothing to remap — return the same reference.
|
|
33
33
|
// This is critical for PR-E (EDITOR-6929) which relies on reference equality
|
|
34
34
|
// to short-circuit SharedStateAPI deep-equality checks.
|
|
35
|
-
if (
|
|
35
|
+
if (isPerfExperimentOn && !resourceId && oldMap.size === 0) {
|
|
36
36
|
return oldMap;
|
|
37
37
|
}
|
|
38
38
|
const newMap = new Map(oldMap);
|
|
@@ -276,6 +276,12 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
276
276
|
const {
|
|
277
277
|
useLongPressSelection = false
|
|
278
278
|
} = options || {};
|
|
279
|
+
|
|
280
|
+
// Cache the experiment value once at plugin creation time.
|
|
281
|
+
// This fires the exposure event exactly once (correct per Exposure Events 101)
|
|
282
|
+
// and avoids ~10 redundant Statsig SDK evaluations per keystroke in hot paths
|
|
283
|
+
// (apply, filterTransaction, appendTransaction, decorations).
|
|
284
|
+
const isPerfExperimentOn = expValEquals('editor_synced_block_perf', 'isEnabled', true);
|
|
279
285
|
const ctx = new SyncedBlockPluginContext();
|
|
280
286
|
const confirmationTransactionRef = ctx.confirmationTransactionRef;
|
|
281
287
|
const unpublishedFlagShown = ctx.unpublishedFlagShown;
|
|
@@ -324,7 +330,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
324
330
|
// synced blocks, we skip the eager fetch + cache walks. They will be
|
|
325
331
|
// re-run lazily by `apply` the first time a synced block enters the
|
|
326
332
|
// document (paste, collab insert, or programmatic insert).
|
|
327
|
-
const docHasSyncedBlocks =
|
|
333
|
+
const docHasSyncedBlocks = isPerfExperimentOn ? hasSyncedBlocks(instance.doc) : true;
|
|
328
334
|
if (docHasSyncedBlocks) {
|
|
329
335
|
const syncBlockNodes = instance.doc.children.filter(syncBlockStore.referenceManager.isReferenceBlock);
|
|
330
336
|
syncBlockStore.referenceManager.fetchSyncBlocksData(convertPMNodesToSyncBlockNodes(syncBlockNodes));
|
|
@@ -354,7 +360,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
354
360
|
// When the perf gate is ON and the doc has synced blocks we do a
|
|
355
361
|
// single traversal here; afterwards `apply()` will map or rebuild
|
|
356
362
|
// only when a status signal changes.
|
|
357
|
-
const initStatusDecorationSet = docHasSyncedBlocks &&
|
|
363
|
+
const initStatusDecorationSet = docHasSyncedBlocks && isPerfExperimentOn ? buildStatusDecorations(instance.doc, syncBlockStore, initIsOffline, initIsViewMode, initIsDragging) : DecorationSet.empty;
|
|
358
364
|
return {
|
|
359
365
|
selectionDecorationSet: calculateDecorations(instance.doc, instance.selection, instance.schema),
|
|
360
366
|
activeFlag: false,
|
|
@@ -371,7 +377,8 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
371
377
|
apply: (tr, currentPluginState, oldEditorState) => {
|
|
372
378
|
var _meta$activeFlag, _meta$bodiedSyncBlock;
|
|
373
379
|
const meta = tr.getMeta(syncedBlockPluginKey);
|
|
374
|
-
|
|
380
|
+
// isPerfExperimentOn is cached at createPlugin() level — see above
|
|
381
|
+
|
|
375
382
|
const {
|
|
376
383
|
activeFlag,
|
|
377
384
|
selectionDecorationSet,
|
|
@@ -451,7 +458,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
451
458
|
}
|
|
452
459
|
}
|
|
453
460
|
const newPosEntry = meta === null || meta === void 0 ? void 0 : meta.retryCreationPos;
|
|
454
|
-
const newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping));
|
|
461
|
+
const newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping), isPerfExperimentOn);
|
|
455
462
|
const nextActiveFlag = (_meta$activeFlag = meta === null || meta === void 0 ? void 0 : meta.activeFlag) !== null && _meta$activeFlag !== void 0 ? _meta$activeFlag : activeFlag;
|
|
456
463
|
const nextBodiedSyncBlockDeletionStatus = (_meta$bodiedSyncBlock = meta === null || meta === void 0 ? void 0 : meta.bodiedSyncBlockDeletionStatus) !== null && _meta$bodiedSyncBlock !== void 0 ? _meta$bodiedSyncBlock : bodiedSyncBlockDeletionStatus;
|
|
457
464
|
const nextHasUnsavedBodiedSyncBlockChanges = syncBlockStore.sourceManager.hasUnsavedChanges();
|
|
@@ -524,7 +531,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
524
531
|
// `apply()`. The `decorations` prop is now an O(1) merge of
|
|
525
532
|
// the two cached sets — no `doc.descendants()` walk, no
|
|
526
533
|
// shared-state reads.
|
|
527
|
-
if (
|
|
534
|
+
if (isPerfExperimentOn) {
|
|
528
535
|
var _api$focus$sharedStat, _api$focus, _api$focus$sharedStat2, _api$focus$sharedStat3;
|
|
529
536
|
if (!docHasSyncedBlocks) {
|
|
530
537
|
return selectionDecorationSet;
|
|
@@ -652,7 +659,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
652
659
|
// transaction does not insert one, all downstream filter logic is a
|
|
653
660
|
// no-op. Avoid both the shared-state reads and the `trackSyncBlocks`
|
|
654
661
|
// walks for the ~99.97% of pages that have no synced blocks.
|
|
655
|
-
if (
|
|
662
|
+
if (isPerfExperimentOn) {
|
|
656
663
|
const pluginState = syncedBlockPluginKey.getState(state);
|
|
657
664
|
if (pluginState && !pluginState.hasSyncedBlocks && !transactionInsertsSyncedBlock(tr)) {
|
|
658
665
|
return true;
|
|
@@ -735,7 +742,7 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
735
742
|
// synced block (and none of the dispatched transactions inserts one),
|
|
736
743
|
// skip all downstream work. This is the hot path on the ~99.97% of
|
|
737
744
|
// pages that don't use synced blocks (see EDITOR-6586).
|
|
738
|
-
if (
|
|
745
|
+
if (isPerfExperimentOn) {
|
|
739
746
|
const oldPluginState = syncedBlockPluginKey.getState(oldState);
|
|
740
747
|
const newPluginState = syncedBlockPluginKey.getState(newState);
|
|
741
748
|
const hadOrHasSyncedBlocks = !!(oldPluginState !== null && oldPluginState !== void 0 && oldPluginState.hasSyncedBlocks) || !!(newPluginState !== null && newPluginState !== void 0 && newPluginState.hasSyncedBlocks);
|
|
@@ -16,6 +16,10 @@ export const getMenuAndToolbarExperiencesPlugin = ({
|
|
|
16
16
|
refs,
|
|
17
17
|
dispatchAnalyticsEvent
|
|
18
18
|
}) => {
|
|
19
|
+
// Cache the experiment value once at plugin creation time.
|
|
20
|
+
// This fires the exposure event exactly once (correct per Exposure Events 101)
|
|
21
|
+
// and avoids redundant Statsig SDK evaluations in the view() and update() hooks.
|
|
22
|
+
const isPerfExperimentOn = expValEquals('editor_synced_block_perf', 'isEnabled', true);
|
|
19
23
|
let popupsTargetEl;
|
|
20
24
|
const editorViewRef = {
|
|
21
25
|
current: undefined
|
|
@@ -178,13 +182,13 @@ export const getMenuAndToolbarExperiencesPlugin = ({
|
|
|
178
182
|
unbindClickListener = unbinders.unbindClickListener;
|
|
179
183
|
unbindKeydownListener = unbinders.unbindKeydownListener;
|
|
180
184
|
};
|
|
181
|
-
if ((_syncedBlockPluginKey = syncedBlockPluginKey.getState(view.state)) !== null && _syncedBlockPluginKey !== void 0 && _syncedBlockPluginKey.hasSyncedBlocks || !
|
|
185
|
+
if ((_syncedBlockPluginKey = syncedBlockPluginKey.getState(view.state)) !== null && _syncedBlockPluginKey !== void 0 && _syncedBlockPluginKey.hasSyncedBlocks || !isPerfExperimentOn) {
|
|
182
186
|
ensureListenersBound();
|
|
183
187
|
}
|
|
184
188
|
return {
|
|
185
189
|
update: (view, prevState) => {
|
|
186
190
|
var _syncedBlockPluginKey2;
|
|
187
|
-
if (!listenersBound && view.state.doc !== prevState.doc && (_syncedBlockPluginKey2 = syncedBlockPluginKey.getState(view.state)) !== null && _syncedBlockPluginKey2 !== void 0 && _syncedBlockPluginKey2.hasSyncedBlocks &&
|
|
191
|
+
if (!listenersBound && view.state.doc !== prevState.doc && (_syncedBlockPluginKey2 = syncedBlockPluginKey.getState(view.state)) !== null && _syncedBlockPluginKey2 !== void 0 && _syncedBlockPluginKey2.hasSyncedBlocks && isPerfExperimentOn) {
|
|
188
192
|
// Bind listeners now that synced blocks are present.
|
|
189
193
|
ensureListenersBound();
|
|
190
194
|
}
|
|
@@ -3,6 +3,7 @@ import { syncBlock, bodiedSyncBlock } from '@atlaskit/adf-schema';
|
|
|
3
3
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
4
4
|
import { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
|
|
5
5
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
6
|
+
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
6
7
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
7
8
|
import { flushBodiedSyncBlocks, flushSyncBlocks, discardUnpublishedSyncBlocks } from './editor-actions';
|
|
8
9
|
import { copySyncedBlockReferenceToClipboardEditorCommand, createSyncedBlock } from './editor-commands';
|
|
@@ -33,7 +34,11 @@ const LazySyncedBlockUI = ({
|
|
|
33
34
|
var _states$syncedBlockSt;
|
|
34
35
|
return (_states$syncedBlockSt = states.syncedBlockState) === null || _states$syncedBlockSt === void 0 ? void 0 : _states$syncedBlockSt.hasSyncedBlocks;
|
|
35
36
|
});
|
|
36
|
-
|
|
37
|
+
|
|
38
|
+
// Use expValEqualsNoExposure here because the exposure is already fired
|
|
39
|
+
// once at plugin creation time (see syncedBlockPlugin below).
|
|
40
|
+
// This component re-renders on every transaction — avoid redundant SDK evaluations.
|
|
41
|
+
if (!hasSyncBlocks && expValEqualsNoExposure('editor_synced_block_perf', 'isEnabled', true)) {
|
|
37
42
|
return null;
|
|
38
43
|
}
|
|
39
44
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SyncBlockRefresher, {
|
|
@@ -167,7 +172,7 @@ export const syncedBlockPlugin = ({
|
|
|
167
172
|
|
|
168
173
|
// --- EDITOR-6929 / PR-F: return a stable reference when all
|
|
169
174
|
// fields are unchanged to prevent unnecessary React re-renders. ---
|
|
170
|
-
if (cachedSharedState !== undefined && cachedSharedState.activeFlag === activeFlag && cachedSharedState.syncBlockStore === currentSyncBlockStore && cachedSharedState.bodiedSyncBlockDeletionStatus === bodiedSyncBlockDeletionStatus && cachedSharedState.retryCreationPosMap === retryCreationPosMap && cachedSharedState.hasSyncedBlocks === hasSyncedBlocks && cachedSharedState.hasUnsavedBodiedSyncBlockChanges === hasUnsavedBodiedSyncBlockChanges &&
|
|
175
|
+
if (cachedSharedState !== undefined && cachedSharedState.activeFlag === activeFlag && cachedSharedState.syncBlockStore === currentSyncBlockStore && cachedSharedState.bodiedSyncBlockDeletionStatus === bodiedSyncBlockDeletionStatus && cachedSharedState.retryCreationPosMap === retryCreationPosMap && cachedSharedState.hasSyncedBlocks === hasSyncedBlocks && cachedSharedState.hasUnsavedBodiedSyncBlockChanges === hasUnsavedBodiedSyncBlockChanges && isPerfExperimentOn) {
|
|
171
176
|
return cachedSharedState;
|
|
172
177
|
}
|
|
173
178
|
const nextSharedState = {
|
|
@@ -13,7 +13,7 @@ import { ACTION_SUBJECT } from '@atlaskit/editor-common/analytics';
|
|
|
13
13
|
import { ErrorBoundary } from '@atlaskit/editor-common/error-boundary';
|
|
14
14
|
import ReactNodeView from '@atlaskit/editor-common/react-node-view';
|
|
15
15
|
import { SyncBlockSharedCssClassName, SyncBlockActionsProvider } from '@atlaskit/editor-common/sync-block';
|
|
16
|
-
import {
|
|
16
|
+
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
17
17
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
18
18
|
import { removeSyncedBlockAtPos } from '../editor-commands';
|
|
19
19
|
import { SyncBlockRendererWrapper } from '../ui/SyncBlockRendererWrapper';
|
|
@@ -88,7 +88,10 @@ export var SyncBlock = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
88
88
|
if (!syncBlockStore) {
|
|
89
89
|
return null;
|
|
90
90
|
}
|
|
91
|
-
|
|
91
|
+
|
|
92
|
+
// Use expValEqualsNoExposure — the exposure is already fired once at plugin
|
|
93
|
+
// creation time in syncedBlockPlugin.tsx and main.ts createPlugin().
|
|
94
|
+
var isPerfEnabled = expValEqualsNoExposure('editor_synced_block_perf', 'isEnabled', true);
|
|
92
95
|
|
|
93
96
|
// get document node from data provider
|
|
94
97
|
return /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
@@ -34,13 +34,13 @@ import { hasEditInSyncBlock, trackSyncBlocks } from './utils/track-sync-blocks';
|
|
|
34
34
|
import { transactionInsertsSyncedBlock } from './utils/transaction-inserts-synced-block';
|
|
35
35
|
import { deferDispatch, wasExtensionInsertedInBodiedSyncBlock, sliceFullyContainsNode } from './utils/utils';
|
|
36
36
|
export var syncedBlockPluginKey = new PluginKey('syncedBlockPlugin');
|
|
37
|
-
var mapRetryCreationPosMap = function mapRetryCreationPosMap(oldMap, newRetryCreationPos, mapPos) {
|
|
37
|
+
var mapRetryCreationPosMap = function mapRetryCreationPosMap(oldMap, newRetryCreationPos, mapPos, isPerfExperimentOn) {
|
|
38
38
|
var resourceId = newRetryCreationPos === null || newRetryCreationPos === void 0 ? void 0 : newRetryCreationPos.resourceId;
|
|
39
39
|
|
|
40
40
|
// Fast path: no new entry and nothing to remap — return the same reference.
|
|
41
41
|
// This is critical for PR-E (EDITOR-6929) which relies on reference equality
|
|
42
42
|
// to short-circuit SharedStateAPI deep-equality checks.
|
|
43
|
-
if (
|
|
43
|
+
if (isPerfExperimentOn && !resourceId && oldMap.size === 0) {
|
|
44
44
|
return oldMap;
|
|
45
45
|
}
|
|
46
46
|
var newMap = new Map(oldMap);
|
|
@@ -299,6 +299,12 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
299
299
|
var _ref6 = options || {},
|
|
300
300
|
_ref6$useLongPressSel = _ref6.useLongPressSelection,
|
|
301
301
|
useLongPressSelection = _ref6$useLongPressSel === void 0 ? false : _ref6$useLongPressSel;
|
|
302
|
+
|
|
303
|
+
// Cache the experiment value once at plugin creation time.
|
|
304
|
+
// This fires the exposure event exactly once (correct per Exposure Events 101)
|
|
305
|
+
// and avoids ~10 redundant Statsig SDK evaluations per keystroke in hot paths
|
|
306
|
+
// (apply, filterTransaction, appendTransaction, decorations).
|
|
307
|
+
var isPerfExperimentOn = expValEquals('editor_synced_block_perf', 'isEnabled', true);
|
|
302
308
|
var ctx = new SyncedBlockPluginContext();
|
|
303
309
|
var confirmationTransactionRef = ctx.confirmationTransactionRef;
|
|
304
310
|
var unpublishedFlagShown = ctx.unpublishedFlagShown;
|
|
@@ -349,7 +355,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
349
355
|
// synced blocks, we skip the eager fetch + cache walks. They will be
|
|
350
356
|
// re-run lazily by `apply` the first time a synced block enters the
|
|
351
357
|
// document (paste, collab insert, or programmatic insert).
|
|
352
|
-
var docHasSyncedBlocks =
|
|
358
|
+
var docHasSyncedBlocks = isPerfExperimentOn ? hasSyncedBlocks(instance.doc) : true;
|
|
353
359
|
if (docHasSyncedBlocks) {
|
|
354
360
|
var syncBlockNodes = instance.doc.children.filter(syncBlockStore.referenceManager.isReferenceBlock);
|
|
355
361
|
syncBlockStore.referenceManager.fetchSyncBlocksData(convertPMNodesToSyncBlockNodes(syncBlockNodes));
|
|
@@ -379,7 +385,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
379
385
|
// When the perf gate is ON and the doc has synced blocks we do a
|
|
380
386
|
// single traversal here; afterwards `apply()` will map or rebuild
|
|
381
387
|
// only when a status signal changes.
|
|
382
|
-
var initStatusDecorationSet = docHasSyncedBlocks &&
|
|
388
|
+
var initStatusDecorationSet = docHasSyncedBlocks && isPerfExperimentOn ? buildStatusDecorations(instance.doc, syncBlockStore, initIsOffline, initIsViewMode, initIsDragging) : DecorationSet.empty;
|
|
383
389
|
return {
|
|
384
390
|
selectionDecorationSet: calculateDecorations(instance.doc, instance.selection, instance.schema),
|
|
385
391
|
activeFlag: false,
|
|
@@ -396,7 +402,8 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
396
402
|
apply: function apply(tr, currentPluginState, oldEditorState) {
|
|
397
403
|
var _meta$activeFlag, _meta$bodiedSyncBlock;
|
|
398
404
|
var meta = tr.getMeta(syncedBlockPluginKey);
|
|
399
|
-
|
|
405
|
+
// isPerfExperimentOn is cached at createPlugin() level — see above
|
|
406
|
+
|
|
400
407
|
var activeFlag = currentPluginState.activeFlag,
|
|
401
408
|
selectionDecorationSet = currentPluginState.selectionDecorationSet,
|
|
402
409
|
bodiedSyncBlockDeletionStatus = currentPluginState.bodiedSyncBlockDeletionStatus,
|
|
@@ -474,7 +481,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
474
481
|
}
|
|
475
482
|
}
|
|
476
483
|
var newPosEntry = meta === null || meta === void 0 ? void 0 : meta.retryCreationPos;
|
|
477
|
-
var newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping));
|
|
484
|
+
var newRetryCreationPosMap = mapRetryCreationPosMap(retryCreationPosMap, newPosEntry, tr.mapping.map.bind(tr.mapping), isPerfExperimentOn);
|
|
478
485
|
var nextActiveFlag = (_meta$activeFlag = meta === null || meta === void 0 ? void 0 : meta.activeFlag) !== null && _meta$activeFlag !== void 0 ? _meta$activeFlag : activeFlag;
|
|
479
486
|
var nextBodiedSyncBlockDeletionStatus = (_meta$bodiedSyncBlock = meta === null || meta === void 0 ? void 0 : meta.bodiedSyncBlockDeletionStatus) !== null && _meta$bodiedSyncBlock !== void 0 ? _meta$bodiedSyncBlock : bodiedSyncBlockDeletionStatus;
|
|
480
487
|
var nextHasUnsavedBodiedSyncBlockChanges = syncBlockStore.sourceManager.hasUnsavedChanges();
|
|
@@ -548,7 +555,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
548
555
|
// `apply()`. The `decorations` prop is now an O(1) merge of
|
|
549
556
|
// the two cached sets — no `doc.descendants()` walk, no
|
|
550
557
|
// shared-state reads.
|
|
551
|
-
if (
|
|
558
|
+
if (isPerfExperimentOn) {
|
|
552
559
|
var _api$focus$sharedStat, _api$focus;
|
|
553
560
|
if (!docHasSyncedBlocks) {
|
|
554
561
|
return selectionDecorationSet;
|
|
@@ -672,7 +679,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
672
679
|
// transaction does not insert one, all downstream filter logic is a
|
|
673
680
|
// no-op. Avoid both the shared-state reads and the `trackSyncBlocks`
|
|
674
681
|
// walks for the ~99.97% of pages that have no synced blocks.
|
|
675
|
-
if (
|
|
682
|
+
if (isPerfExperimentOn) {
|
|
676
683
|
var pluginState = syncedBlockPluginKey.getState(state);
|
|
677
684
|
if (pluginState && !pluginState.hasSyncedBlocks && !transactionInsertsSyncedBlock(tr)) {
|
|
678
685
|
return true;
|
|
@@ -762,7 +769,7 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
762
769
|
// synced block (and none of the dispatched transactions inserts one),
|
|
763
770
|
// skip all downstream work. This is the hot path on the ~99.97% of
|
|
764
771
|
// pages that don't use synced blocks (see EDITOR-6586).
|
|
765
|
-
if (
|
|
772
|
+
if (isPerfExperimentOn) {
|
|
766
773
|
var oldPluginState = syncedBlockPluginKey.getState(oldState);
|
|
767
774
|
var newPluginState = syncedBlockPluginKey.getState(newState);
|
|
768
775
|
var hadOrHasSyncedBlocks = !!(oldPluginState !== null && oldPluginState !== void 0 && oldPluginState.hasSyncedBlocks) || !!(newPluginState !== null && newPluginState !== void 0 && newPluginState.hasSyncedBlocks);
|
|
@@ -16,6 +16,10 @@ var targetEl;
|
|
|
16
16
|
export var getMenuAndToolbarExperiencesPlugin = function getMenuAndToolbarExperiencesPlugin(_ref) {
|
|
17
17
|
var refs = _ref.refs,
|
|
18
18
|
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
|
|
19
|
+
// Cache the experiment value once at plugin creation time.
|
|
20
|
+
// This fires the exposure event exactly once (correct per Exposure Events 101)
|
|
21
|
+
// and avoids redundant Statsig SDK evaluations in the view() and update() hooks.
|
|
22
|
+
var isPerfExperimentOn = expValEquals('editor_synced_block_perf', 'isEnabled', true);
|
|
19
23
|
var popupsTargetEl;
|
|
20
24
|
var editorViewRef = {
|
|
21
25
|
current: undefined
|
|
@@ -178,13 +182,13 @@ export var getMenuAndToolbarExperiencesPlugin = function getMenuAndToolbarExperi
|
|
|
178
182
|
unbindClickListener = unbinders.unbindClickListener;
|
|
179
183
|
unbindKeydownListener = unbinders.unbindKeydownListener;
|
|
180
184
|
};
|
|
181
|
-
if ((_syncedBlockPluginKey = syncedBlockPluginKey.getState(_view.state)) !== null && _syncedBlockPluginKey !== void 0 && _syncedBlockPluginKey.hasSyncedBlocks || !
|
|
185
|
+
if ((_syncedBlockPluginKey = syncedBlockPluginKey.getState(_view.state)) !== null && _syncedBlockPluginKey !== void 0 && _syncedBlockPluginKey.hasSyncedBlocks || !isPerfExperimentOn) {
|
|
182
186
|
ensureListenersBound();
|
|
183
187
|
}
|
|
184
188
|
return {
|
|
185
189
|
update: function update(view, prevState) {
|
|
186
190
|
var _syncedBlockPluginKey2;
|
|
187
|
-
if (!listenersBound && view.state.doc !== prevState.doc && (_syncedBlockPluginKey2 = syncedBlockPluginKey.getState(view.state)) !== null && _syncedBlockPluginKey2 !== void 0 && _syncedBlockPluginKey2.hasSyncedBlocks &&
|
|
191
|
+
if (!listenersBound && view.state.doc !== prevState.doc && (_syncedBlockPluginKey2 = syncedBlockPluginKey.getState(view.state)) !== null && _syncedBlockPluginKey2 !== void 0 && _syncedBlockPluginKey2.hasSyncedBlocks && isPerfExperimentOn) {
|
|
188
192
|
// Bind listeners now that synced blocks are present.
|
|
189
193
|
ensureListenersBound();
|
|
190
194
|
}
|
|
@@ -3,6 +3,7 @@ import { syncBlock, bodiedSyncBlock } from '@atlaskit/adf-schema';
|
|
|
3
3
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
4
4
|
import { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
|
|
5
5
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
6
|
+
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
6
7
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
7
8
|
import { flushBodiedSyncBlocks as _flushBodiedSyncBlocks, flushSyncBlocks, discardUnpublishedSyncBlocks as _discardUnpublishedSyncBlocks } from './editor-actions';
|
|
8
9
|
import { copySyncedBlockReferenceToClipboardEditorCommand, createSyncedBlock } from './editor-commands';
|
|
@@ -32,7 +33,11 @@ var LazySyncedBlockUI = function LazySyncedBlockUI(_ref) {
|
|
|
32
33
|
var _states$syncedBlockSt;
|
|
33
34
|
return (_states$syncedBlockSt = states.syncedBlockState) === null || _states$syncedBlockSt === void 0 ? void 0 : _states$syncedBlockSt.hasSyncedBlocks;
|
|
34
35
|
});
|
|
35
|
-
|
|
36
|
+
|
|
37
|
+
// Use expValEqualsNoExposure here because the exposure is already fired
|
|
38
|
+
// once at plugin creation time (see syncedBlockPlugin below).
|
|
39
|
+
// This component re-renders on every transaction — avoid redundant SDK evaluations.
|
|
40
|
+
if (!hasSyncBlocks && expValEqualsNoExposure('editor_synced_block_perf', 'isEnabled', true)) {
|
|
36
41
|
return null;
|
|
37
42
|
}
|
|
38
43
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SyncBlockRefresher, {
|
|
@@ -169,7 +174,7 @@ export var syncedBlockPlugin = function syncedBlockPlugin(_ref2) {
|
|
|
169
174
|
|
|
170
175
|
// --- EDITOR-6929 / PR-F: return a stable reference when all
|
|
171
176
|
// fields are unchanged to prevent unnecessary React re-renders. ---
|
|
172
|
-
if (cachedSharedState !== undefined && cachedSharedState.activeFlag === activeFlag && cachedSharedState.syncBlockStore === currentSyncBlockStore && cachedSharedState.bodiedSyncBlockDeletionStatus === bodiedSyncBlockDeletionStatus && cachedSharedState.retryCreationPosMap === retryCreationPosMap && cachedSharedState.hasSyncedBlocks === hasSyncedBlocks && cachedSharedState.hasUnsavedBodiedSyncBlockChanges === hasUnsavedBodiedSyncBlockChanges &&
|
|
177
|
+
if (cachedSharedState !== undefined && cachedSharedState.activeFlag === activeFlag && cachedSharedState.syncBlockStore === currentSyncBlockStore && cachedSharedState.bodiedSyncBlockDeletionStatus === bodiedSyncBlockDeletionStatus && cachedSharedState.retryCreationPosMap === retryCreationPosMap && cachedSharedState.hasSyncedBlocks === hasSyncedBlocks && cachedSharedState.hasUnsavedBodiedSyncBlockChanges === hasUnsavedBodiedSyncBlockChanges && isPerfExperimentOn) {
|
|
173
178
|
return cachedSharedState;
|
|
174
179
|
}
|
|
175
180
|
var nextSharedState = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-synced-block",
|
|
3
|
-
"version": "8.3.
|
|
3
|
+
"version": "8.3.2",
|
|
4
4
|
"description": "SyncedBlock plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"@atlaskit/editor-plugin-selection": "^10.1.0",
|
|
43
43
|
"@atlaskit/editor-plugin-user-intent": "^8.2.0",
|
|
44
44
|
"@atlaskit/editor-prosemirror": "^7.3.0",
|
|
45
|
-
"@atlaskit/editor-shared-styles": "^3.
|
|
46
|
-
"@atlaskit/editor-synced-block-provider": "^6.
|
|
47
|
-
"@atlaskit/editor-toolbar": "^1.
|
|
45
|
+
"@atlaskit/editor-shared-styles": "^3.11.0",
|
|
46
|
+
"@atlaskit/editor-synced-block-provider": "^6.6.0",
|
|
47
|
+
"@atlaskit/editor-toolbar": "^1.4.0",
|
|
48
48
|
"@atlaskit/flag": "^17.11.0",
|
|
49
49
|
"@atlaskit/icon": "34.5.0",
|
|
50
50
|
"@atlaskit/icon-lab": "^6.9.0",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
55
55
|
"@atlaskit/primitives": "^19.0.0",
|
|
56
56
|
"@atlaskit/spinner": "19.1.2",
|
|
57
|
-
"@atlaskit/tmp-editor-statsig": "^80.
|
|
57
|
+
"@atlaskit/tmp-editor-statsig": "^80.2.0",
|
|
58
58
|
"@atlaskit/tokens": "13.0.4",
|
|
59
59
|
"@atlaskit/tooltip": "^22.2.0",
|
|
60
60
|
"@atlaskit/visually-hidden": "^3.1.0",
|