@atlaskit/renderer 136.1.2 → 136.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/cjs/render-document.js +42 -1
- package/dist/cjs/ui/Renderer/index.js +1 -1
- package/dist/es2019/render-document.js +37 -1
- package/dist/es2019/ui/Renderer/index.js +1 -1
- package/dist/esm/render-document.js +42 -1
- package/dist/esm/ui/Renderer/index.js +1 -1
- package/dist/types/render-document.d.ts +4 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @atlaskit/renderer
|
|
2
2
|
|
|
3
|
+
## 136.1.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
|
|
9
|
+
## 136.1.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`07c45974a615f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/07c45974a615f) -
|
|
14
|
+
Reduce ADF validation cost on large documents, behind the new `platform_editor_adf_validator_perf`
|
|
15
|
+
experiment. The validator resolves the `platform_editor_fix_adf-validator_mutation_bug` gate once
|
|
16
|
+
per validator instead of once per node and per mark, and caches allowed-content lookups per node
|
|
17
|
+
type. The renderer compares `validationOverrides` by value so its validation memo stops missing on
|
|
18
|
+
every render, and compares ProseMirror documents with `Node.eq` rather than stringifying both. Its
|
|
19
|
+
memo comparator now runs the cheap checks before the document comparison. Behaviour is unchanged
|
|
20
|
+
in both cohorts.
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
|
|
3
23
|
## 136.1.2
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -11,6 +11,7 @@ var _transforms = require("@atlaskit/adf-utils/transforms");
|
|
|
11
11
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
12
12
|
var _utils = require("@atlaskit/editor-common/utils");
|
|
13
13
|
var _validator = require("@atlaskit/editor-common/validator");
|
|
14
|
+
var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
|
|
14
15
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
15
16
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
16
17
|
var _memoizeOne = _interopRequireDefault(require("memoize-one"));
|
|
@@ -31,6 +32,9 @@ var withStopwatch = function withStopwatch(cb) {
|
|
|
31
32
|
time: time
|
|
32
33
|
};
|
|
33
34
|
};
|
|
35
|
+
|
|
36
|
+
/** Schema-variant escape hatches handed to the ADF validator. */
|
|
37
|
+
|
|
34
38
|
var _validation = function _validation(doc, schema, adfStage, useSpecBasedValidator, dispatchAnalyticsEvent, skipValidation, validationOverrides) {
|
|
35
39
|
var result;
|
|
36
40
|
if (useSpecBasedValidator) {
|
|
@@ -160,7 +164,14 @@ var memoValidation = (0, _memoizeOne.default)(_validation, function (newArgs, la
|
|
|
160
164
|
oldUseSpecValidator = _lastArgs[3],
|
|
161
165
|
/* ignoring dispatchAnalyticsEvent */oldSkipValidation = _lastArgs[5],
|
|
162
166
|
oldValidationOverrides = _lastArgs[6];
|
|
163
|
-
|
|
167
|
+
|
|
168
|
+
// Reference-compared before, which never matched — see `areValidationOverridesEqual`.
|
|
169
|
+
var validationOverridesAreEqual = (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_adf_validator_perf') ? areValidationOverridesEqual(newValidationOverrides, oldValidationOverrides) : newValidationOverrides === oldValidationOverrides;
|
|
170
|
+
|
|
171
|
+
// `areDocsEqual` stringifies the whole document, so it goes last and only runs once everything
|
|
172
|
+
// cheaper has matched. Pure predicates, so ordering cannot change the result; the experiment is
|
|
173
|
+
// resolved above regardless, so exposure does not depend on reaching it.
|
|
174
|
+
return newSchema === oldSchema && newADFStage === oldADFStage && newUseSpecValidator === oldUseSpecValidator && newSkipValidation === oldSkipValidation && validationOverridesAreEqual && areDocsEqual(newDoc, oldDoc);
|
|
164
175
|
});
|
|
165
176
|
|
|
166
177
|
// Ignored via go/ees005
|
|
@@ -175,12 +186,42 @@ var areDocsEqual = function areDocsEqual(docA, docB) {
|
|
|
175
186
|
|
|
176
187
|
// PMNode
|
|
177
188
|
if (docA.type && docA.toJSON && docB.type && docB.toJSON) {
|
|
189
|
+
// `Node.eq` compares markup and content directly. The stringify path builds two JSON trees via
|
|
190
|
+
// `toJSON`, then two strings from them, and discards all four — ~14x slower on a 5k-node
|
|
191
|
+
// document. Same result either way; `Node.eq` is the comparison ProseMirror intends for this.
|
|
192
|
+
if (typeof docA.eq === 'function' && typeof docB.eq === 'function' && (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_adf_validator_perf')) {
|
|
193
|
+
return docA.eq(docB);
|
|
194
|
+
}
|
|
178
195
|
return JSON.stringify(docA.toJSON()) === JSON.stringify(docB.toJSON());
|
|
179
196
|
}
|
|
180
197
|
|
|
181
198
|
// Object
|
|
182
199
|
return JSON.stringify(docA) === JSON.stringify(docB);
|
|
183
200
|
};
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* `Renderer` rebuilds this object in its render body, so a reference check never matches and the memo
|
|
204
|
+
* re-validates (and re-transforms) an unchanged document every render. A flat bag of optional
|
|
205
|
+
* booleans, so a shallow key/value comparison is exact and free next to what it protects.
|
|
206
|
+
*/
|
|
207
|
+
var areValidationOverridesEqual = function areValidationOverridesEqual(a, b) {
|
|
208
|
+
if (a === b) {
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
if (!a || !b) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
var aEntries = Object.entries(a);
|
|
215
|
+
// Ignored via go/ees005
|
|
216
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
217
|
+
var bRecord = b;
|
|
218
|
+
return aEntries.length === Object.keys(b).length && aEntries.every(function (_ref) {
|
|
219
|
+
var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
|
|
220
|
+
key = _ref2[0],
|
|
221
|
+
value = _ref2[1];
|
|
222
|
+
return bRecord[key] === value;
|
|
223
|
+
});
|
|
224
|
+
};
|
|
184
225
|
var _serializeFragment = function _serializeFragment(serializer, doc) {
|
|
185
226
|
return serializer.serializeFragment(doc.content);
|
|
186
227
|
};
|
|
@@ -73,7 +73,7 @@ var DEGRADED_SEVERITY_THRESHOLD = exports.DEGRADED_SEVERITY_THRESHOLD = 3000;
|
|
|
73
73
|
var TABLE_INFO_TIMEOUT = 10000;
|
|
74
74
|
var RENDER_EVENT_SAMPLE_RATE = 0.1;
|
|
75
75
|
var packageName = "@atlaskit/renderer";
|
|
76
|
-
var packageVersion = "136.1.
|
|
76
|
+
var packageVersion = "136.1.3";
|
|
77
77
|
var setAsQueryContainerStyles = (0, _react2.css)({
|
|
78
78
|
containerName: 'ak-renderer-wrapper',
|
|
79
79
|
containerType: 'inline-size'
|
|
@@ -6,6 +6,7 @@ import { nativeEmbedsFallbackTransform, transformContainerNodes, transformMediaL
|
|
|
6
6
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
7
7
|
import { findAndTrackUnsupportedContentNodes, validateADFEntity } from '@atlaskit/editor-common/utils';
|
|
8
8
|
import { getValidDocument } from '@atlaskit/editor-common/validator';
|
|
9
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
9
10
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
10
11
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
11
12
|
import memoizeOne from 'memoize-one';
|
|
@@ -23,6 +24,9 @@ const withStopwatch = cb => {
|
|
|
23
24
|
time
|
|
24
25
|
};
|
|
25
26
|
};
|
|
27
|
+
|
|
28
|
+
/** Schema-variant escape hatches handed to the ADF validator. */
|
|
29
|
+
|
|
26
30
|
const _validation = (doc, schema, adfStage, useSpecBasedValidator, dispatchAnalyticsEvent, skipValidation, validationOverrides) => {
|
|
27
31
|
let result;
|
|
28
32
|
if (useSpecBasedValidator) {
|
|
@@ -144,7 +148,14 @@ const _validation = (doc, schema, adfStage, useSpecBasedValidator, dispatchAnaly
|
|
|
144
148
|
const memoValidation = memoizeOne(_validation, (newArgs, lastArgs) => {
|
|
145
149
|
const [newDoc, newSchema, newADFStage, newUseSpecValidator,, /* ignoring dispatchAnalyticsEvent */newSkipValidation, newValidationOverrides] = newArgs;
|
|
146
150
|
const [oldDoc, oldSchema, oldADFStage, oldUseSpecValidator,, /* ignoring dispatchAnalyticsEvent */oldSkipValidation, oldValidationOverrides] = lastArgs;
|
|
147
|
-
|
|
151
|
+
|
|
152
|
+
// Reference-compared before, which never matched — see `areValidationOverridesEqual`.
|
|
153
|
+
const validationOverridesAreEqual = isExperimentEnabled('platform_editor_adf_validator_perf') ? areValidationOverridesEqual(newValidationOverrides, oldValidationOverrides) : newValidationOverrides === oldValidationOverrides;
|
|
154
|
+
|
|
155
|
+
// `areDocsEqual` stringifies the whole document, so it goes last and only runs once everything
|
|
156
|
+
// cheaper has matched. Pure predicates, so ordering cannot change the result; the experiment is
|
|
157
|
+
// resolved above regardless, so exposure does not depend on reaching it.
|
|
158
|
+
return newSchema === oldSchema && newADFStage === oldADFStage && newUseSpecValidator === oldUseSpecValidator && newSkipValidation === oldSkipValidation && validationOverridesAreEqual && areDocsEqual(newDoc, oldDoc);
|
|
148
159
|
});
|
|
149
160
|
|
|
150
161
|
// Ignored via go/ees005
|
|
@@ -159,12 +170,37 @@ const areDocsEqual = (docA, docB) => {
|
|
|
159
170
|
|
|
160
171
|
// PMNode
|
|
161
172
|
if (docA.type && docA.toJSON && docB.type && docB.toJSON) {
|
|
173
|
+
// `Node.eq` compares markup and content directly. The stringify path builds two JSON trees via
|
|
174
|
+
// `toJSON`, then two strings from them, and discards all four — ~14x slower on a 5k-node
|
|
175
|
+
// document. Same result either way; `Node.eq` is the comparison ProseMirror intends for this.
|
|
176
|
+
if (typeof docA.eq === 'function' && typeof docB.eq === 'function' && isExperimentEnabled('platform_editor_adf_validator_perf')) {
|
|
177
|
+
return docA.eq(docB);
|
|
178
|
+
}
|
|
162
179
|
return JSON.stringify(docA.toJSON()) === JSON.stringify(docB.toJSON());
|
|
163
180
|
}
|
|
164
181
|
|
|
165
182
|
// Object
|
|
166
183
|
return JSON.stringify(docA) === JSON.stringify(docB);
|
|
167
184
|
};
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* `Renderer` rebuilds this object in its render body, so a reference check never matches and the memo
|
|
188
|
+
* re-validates (and re-transforms) an unchanged document every render. A flat bag of optional
|
|
189
|
+
* booleans, so a shallow key/value comparison is exact and free next to what it protects.
|
|
190
|
+
*/
|
|
191
|
+
const areValidationOverridesEqual = (a, b) => {
|
|
192
|
+
if (a === b) {
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
if (!a || !b) {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
const aEntries = Object.entries(a);
|
|
199
|
+
// Ignored via go/ees005
|
|
200
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
201
|
+
const bRecord = b;
|
|
202
|
+
return aEntries.length === Object.keys(b).length && aEntries.every(([key, value]) => bRecord[key] === value);
|
|
203
|
+
};
|
|
168
204
|
const _serializeFragment = (serializer, doc) => {
|
|
169
205
|
return serializer.serializeFragment(doc.content);
|
|
170
206
|
};
|
|
@@ -59,7 +59,7 @@ export const DEGRADED_SEVERITY_THRESHOLD = 3000;
|
|
|
59
59
|
const TABLE_INFO_TIMEOUT = 10000;
|
|
60
60
|
const RENDER_EVENT_SAMPLE_RATE = 0.1;
|
|
61
61
|
const packageName = "@atlaskit/renderer";
|
|
62
|
-
const packageVersion = "136.1.
|
|
62
|
+
const packageVersion = "136.1.3";
|
|
63
63
|
const setAsQueryContainerStyles = css({
|
|
64
64
|
containerName: 'ak-renderer-wrapper',
|
|
65
65
|
containerType: 'inline-size'
|
|
@@ -7,6 +7,7 @@ import { nativeEmbedsFallbackTransform, transformContainerNodes, transformMediaL
|
|
|
7
7
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
8
8
|
import { findAndTrackUnsupportedContentNodes, validateADFEntity } from '@atlaskit/editor-common/utils';
|
|
9
9
|
import { getValidDocument } from '@atlaskit/editor-common/validator';
|
|
10
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
10
11
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
11
12
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
12
13
|
import memoizeOne from 'memoize-one';
|
|
@@ -24,6 +25,9 @@ var withStopwatch = function withStopwatch(cb) {
|
|
|
24
25
|
time: time
|
|
25
26
|
};
|
|
26
27
|
};
|
|
28
|
+
|
|
29
|
+
/** Schema-variant escape hatches handed to the ADF validator. */
|
|
30
|
+
|
|
27
31
|
var _validation = function _validation(doc, schema, adfStage, useSpecBasedValidator, dispatchAnalyticsEvent, skipValidation, validationOverrides) {
|
|
28
32
|
var result;
|
|
29
33
|
if (useSpecBasedValidator) {
|
|
@@ -153,7 +157,14 @@ var memoValidation = memoizeOne(_validation, function (newArgs, lastArgs) {
|
|
|
153
157
|
oldUseSpecValidator = _lastArgs[3],
|
|
154
158
|
/* ignoring dispatchAnalyticsEvent */oldSkipValidation = _lastArgs[5],
|
|
155
159
|
oldValidationOverrides = _lastArgs[6];
|
|
156
|
-
|
|
160
|
+
|
|
161
|
+
// Reference-compared before, which never matched — see `areValidationOverridesEqual`.
|
|
162
|
+
var validationOverridesAreEqual = isExperimentEnabled('platform_editor_adf_validator_perf') ? areValidationOverridesEqual(newValidationOverrides, oldValidationOverrides) : newValidationOverrides === oldValidationOverrides;
|
|
163
|
+
|
|
164
|
+
// `areDocsEqual` stringifies the whole document, so it goes last and only runs once everything
|
|
165
|
+
// cheaper has matched. Pure predicates, so ordering cannot change the result; the experiment is
|
|
166
|
+
// resolved above regardless, so exposure does not depend on reaching it.
|
|
167
|
+
return newSchema === oldSchema && newADFStage === oldADFStage && newUseSpecValidator === oldUseSpecValidator && newSkipValidation === oldSkipValidation && validationOverridesAreEqual && areDocsEqual(newDoc, oldDoc);
|
|
157
168
|
});
|
|
158
169
|
|
|
159
170
|
// Ignored via go/ees005
|
|
@@ -168,12 +179,42 @@ var areDocsEqual = function areDocsEqual(docA, docB) {
|
|
|
168
179
|
|
|
169
180
|
// PMNode
|
|
170
181
|
if (docA.type && docA.toJSON && docB.type && docB.toJSON) {
|
|
182
|
+
// `Node.eq` compares markup and content directly. The stringify path builds two JSON trees via
|
|
183
|
+
// `toJSON`, then two strings from them, and discards all four — ~14x slower on a 5k-node
|
|
184
|
+
// document. Same result either way; `Node.eq` is the comparison ProseMirror intends for this.
|
|
185
|
+
if (typeof docA.eq === 'function' && typeof docB.eq === 'function' && isExperimentEnabled('platform_editor_adf_validator_perf')) {
|
|
186
|
+
return docA.eq(docB);
|
|
187
|
+
}
|
|
171
188
|
return JSON.stringify(docA.toJSON()) === JSON.stringify(docB.toJSON());
|
|
172
189
|
}
|
|
173
190
|
|
|
174
191
|
// Object
|
|
175
192
|
return JSON.stringify(docA) === JSON.stringify(docB);
|
|
176
193
|
};
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* `Renderer` rebuilds this object in its render body, so a reference check never matches and the memo
|
|
197
|
+
* re-validates (and re-transforms) an unchanged document every render. A flat bag of optional
|
|
198
|
+
* booleans, so a shallow key/value comparison is exact and free next to what it protects.
|
|
199
|
+
*/
|
|
200
|
+
var areValidationOverridesEqual = function areValidationOverridesEqual(a, b) {
|
|
201
|
+
if (a === b) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
if (!a || !b) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
var aEntries = Object.entries(a);
|
|
208
|
+
// Ignored via go/ees005
|
|
209
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
210
|
+
var bRecord = b;
|
|
211
|
+
return aEntries.length === Object.keys(b).length && aEntries.every(function (_ref) {
|
|
212
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
213
|
+
key = _ref2[0],
|
|
214
|
+
value = _ref2[1];
|
|
215
|
+
return bRecord[key] === value;
|
|
216
|
+
});
|
|
217
|
+
};
|
|
177
218
|
var _serializeFragment = function _serializeFragment(serializer, doc) {
|
|
178
219
|
return serializer.serializeFragment(doc.content);
|
|
179
220
|
};
|
|
@@ -64,7 +64,7 @@ export var DEGRADED_SEVERITY_THRESHOLD = 3000;
|
|
|
64
64
|
var TABLE_INFO_TIMEOUT = 10000;
|
|
65
65
|
var RENDER_EVENT_SAMPLE_RATE = 0.1;
|
|
66
66
|
var packageName = "@atlaskit/renderer";
|
|
67
|
-
var packageVersion = "136.1.
|
|
67
|
+
var packageVersion = "136.1.3";
|
|
68
68
|
var setAsQueryContainerStyles = css({
|
|
69
69
|
containerName: 'ak-renderer-wrapper',
|
|
70
70
|
containerType: 'inline-size'
|
|
@@ -20,8 +20,10 @@ export interface ResultWithTime<T> {
|
|
|
20
20
|
time: number;
|
|
21
21
|
}
|
|
22
22
|
type DispatchAnalyticsEvent = (event: AnalyticsEventPayload) => void;
|
|
23
|
-
|
|
23
|
+
/** Schema-variant escape hatches handed to the ADF validator. */
|
|
24
|
+
type ValidationOverrides = {
|
|
24
25
|
allowNestedTables?: boolean;
|
|
25
26
|
allowTableInPanel?: boolean;
|
|
26
|
-
}
|
|
27
|
+
};
|
|
28
|
+
export declare const renderDocument: <T>(doc: any, serializer: Serializer<T>, schema?: Schema, adfStage?: ADFStage, useSpecBasedValidator?: boolean, rendererId?: string, dispatchAnalyticsEvent?: DispatchAnalyticsEvent, unsupportedContentLevelsTracking?: UnsupportedContentLevelsTracking, appearance?: RendererAppearance, includeNodesCountInStats?: boolean, skipValidation?: boolean, validationOverrides?: ValidationOverrides) => RenderOutput<T | null>;
|
|
27
29
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/renderer",
|
|
3
|
-
"version": "136.1.
|
|
3
|
+
"version": "136.1.4",
|
|
4
4
|
"description": "Renderer component",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"@atlaskit/status": "^5.8.0",
|
|
70
70
|
"@atlaskit/task-decision": "^21.8.0",
|
|
71
71
|
"@atlaskit/theme": "^28.0.0",
|
|
72
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
72
|
+
"@atlaskit/tmp-editor-statsig": "^153.0.0",
|
|
73
73
|
"@atlaskit/tokens": "^16.7.0",
|
|
74
74
|
"@atlaskit/tooltip": "^24.0.0",
|
|
75
75
|
"@atlaskit/visually-hidden": "^4.2.0",
|