+
{renderer(root, depth, index)}
{root.children.map((child, i) => {
return ;
diff --git a/apps/stress-test/src/shared/react/TestAdd.tsx b/apps/stress-test/src/shared/react/TestAdd.tsx
new file mode 100644
index 00000000000000..1996cc5ee11935
--- /dev/null
+++ b/apps/stress-test/src/shared/react/TestAdd.tsx
@@ -0,0 +1,29 @@
+import * as React from 'react';
+import { styleInjector } from '../css/injectStyles';
+import { performanceMeasure } from '../utils/performanceMeasure';
+import { ReactSelectorTree } from './ReactSelectorTree';
+import type { TestProps } from './types';
+
+export const TestAdd: React.FC = ({ tree, selectors, componentRenderer, testOptions }) => {
+ const [added, setAdded] = React.useState(false);
+
+ React.useEffect(() => {
+ if (testOptions.withStyles === 'true') {
+ styleInjector(selectors);
+ }
+ }, []);
+
+ React.useEffect(() => {
+ setTimeout(() => {
+ setAdded(true);
+ performanceMeasure();
+ }, 2000);
+ }, []);
+
+ return (
+ <>
+
+ {added && }
+ >
+ );
+};
diff --git a/apps/stress-test/src/shared/react/TestInjectStyles.tsx b/apps/stress-test/src/shared/react/TestInjectStyles.tsx
new file mode 100644
index 00000000000000..452c8bee884a7d
--- /dev/null
+++ b/apps/stress-test/src/shared/react/TestInjectStyles.tsx
@@ -0,0 +1,17 @@
+import * as React from 'react';
+import { styleInjector } from '../css/injectStyles';
+import { performanceMeasure } from '../utils/performanceMeasure';
+import { ReactSelectorTree } from './ReactSelectorTree';
+import type { TestProps } from './types';
+
+export const TestInjectStyles: React.FC = ({ tree, selectors, componentRenderer, testOptions }) => {
+ // eslint-disable-next-line no-restricted-properties
+ React.useLayoutEffect(() => {
+ setTimeout(() => {
+ styleInjector(selectors);
+ performanceMeasure();
+ }, 2000);
+ }, []);
+
+ return ;
+};
diff --git a/apps/stress-test/src/shared/react/TestMount.tsx b/apps/stress-test/src/shared/react/TestMount.tsx
new file mode 100644
index 00000000000000..d1e5836dc29a0a
--- /dev/null
+++ b/apps/stress-test/src/shared/react/TestMount.tsx
@@ -0,0 +1,48 @@
+import * as React from 'react';
+import { styleInjector } from '../css/injectStyles';
+// import { requestPostAnimationFrame } from '../utils/requestPostAnimationFrame';
+import { ReactSelectorTree } from './ReactSelectorTree';
+import type { TestProps } from './types';
+
+type DebouncedOnRender = () => React.ProfilerOnRenderCallback;
+
+const debouncedOnRender: DebouncedOnRender = () => {
+ let start: number;
+ let timeoutId: number;
+ return (_profilerId, _mode, _actualTime, _baseTime, startTime, commitTime) => {
+ if (!start) {
+ start = startTime;
+ }
+
+ if (timeoutId) {
+ clearTimeout(timeoutId);
+ }
+
+ timeoutId = setTimeout(() => {
+ requestAnimationFrame(() => {
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ performance.measure('stress', {
+ start,
+ end: performance.now(),
+ });
+ });
+ }, 250);
+ };
+};
+
+export const TestMount: React.FC = ({ tree, selectors, componentRenderer, testOptions }) => {
+ const ref = React.useRef(false);
+ if (!ref.current) {
+ ref.current = true;
+ if (testOptions.withStyles === 'true') {
+ styleInjector(selectors);
+ }
+ }
+
+ return (
+
+
+
+ );
+};
diff --git a/apps/stress-test/src/shared/react/TestReRenderAll.tsx b/apps/stress-test/src/shared/react/TestReRenderAll.tsx
new file mode 100644
index 00000000000000..2c2ab45af6d411
--- /dev/null
+++ b/apps/stress-test/src/shared/react/TestReRenderAll.tsx
@@ -0,0 +1,32 @@
+import * as React from 'react';
+import { styleInjector } from '../css/injectStyles';
+import { performanceMeasure } from '../utils/performanceMeasure';
+import { ReactSelectorTree } from './ReactSelectorTree';
+import type { TestProps } from './types';
+
+export const TestReRenderAll: React.FC = ({ tree, selectors, componentRenderer, testOptions }) => {
+ const [theTree, setTheTree] = React.useState();
+
+ React.useEffect(() => {
+ if (testOptions.withStyles === 'true') {
+ styleInjector(selectors);
+ }
+ }, []);
+
+ React.useEffect(() => {
+ if (theTree === undefined && tree) {
+ setTheTree(tree);
+
+ setTimeout(() => {
+ setTheTree(undefined);
+
+ setTimeout(() => {
+ setTheTree(tree);
+ performanceMeasure();
+ }, 2000);
+ }, 2000);
+ }
+ }, [tree]);
+
+ return ;
+};
diff --git a/apps/stress-test/src/shared/react/TestRemoveAll.tsx b/apps/stress-test/src/shared/react/TestRemoveAll.tsx
new file mode 100644
index 00000000000000..cdd4771ca58d2d
--- /dev/null
+++ b/apps/stress-test/src/shared/react/TestRemoveAll.tsx
@@ -0,0 +1,28 @@
+import * as React from 'react';
+import { styleInjector } from '../css/injectStyles';
+import { performanceMeasure } from '../utils/performanceMeasure';
+import { ReactSelectorTree } from './ReactSelectorTree';
+import type { TestProps } from './types';
+
+export const TestRemoveAll: React.FC = ({ tree, selectors, componentRenderer, testOptions }) => {
+ const [theTree, setTheTree] = React.useState();
+
+ React.useEffect(() => {
+ if (testOptions.withStyles === 'true') {
+ styleInjector(selectors);
+ }
+ }, []);
+
+ React.useEffect(() => {
+ if (theTree === undefined && tree) {
+ setTheTree(tree);
+
+ setTimeout(() => {
+ setTheTree(undefined);
+ performanceMeasure();
+ }, 2000);
+ }
+ }, [tree]);
+
+ return ;
+};
diff --git a/apps/stress-test/src/shared/react/onRender.ts b/apps/stress-test/src/shared/react/onRender.ts
new file mode 100644
index 00000000000000..a328c966e066c8
--- /dev/null
+++ b/apps/stress-test/src/shared/react/onRender.ts
@@ -0,0 +1,12 @@
+import * as React from 'react';
+
+export const onRenderLog: React.ProfilerOnRenderCallback = (
+ profilerId,
+ mode,
+ actualTime,
+ baseTime,
+ startTime,
+ commitTime,
+) => {
+ console.log({ profilerId, mode, actualTime, baseTime, startTime, commitTime });
+};
diff --git a/apps/stress-test/src/shared/react/types.ts b/apps/stress-test/src/shared/react/types.ts
index 96eab1e699dc30..2725dda0548cc0 100644
--- a/apps/stress-test/src/shared/react/types.ts
+++ b/apps/stress-test/src/shared/react/types.ts
@@ -1,6 +1,5 @@
+import { RandomSelectorTreeNode, SelectorTreeNode, TreeNode } from '../tree/types';
import { TestOptions } from '../utils/testOptions';
-import { RandomSelectorTreeNode, SelectorTreeNode } from '../tree/RandomSelectorTreeNode';
-import { TreeNode } from '../tree/RandomTree';
export type ReactSelectorTreeComponentRenderer = (node: SelectorTreeNode, depth: number, index: number) => JSX.Element;
diff --git a/apps/stress-test/src/shared/testParams.ts b/apps/stress-test/src/shared/testParams.ts
deleted file mode 100644
index 5effe504fe6f27..00000000000000
--- a/apps/stress-test/src/shared/testParams.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-const testTypes = ['manual', 'mount', 'inject-styles', 'prop-update', 'remove-node', 'add-node'];
-
-export type TestParams = {
- test: typeof testTypes[number];
- numStartNodes: number;
- numAddNodes: number;
- numRemoveNodes: number;
-};
-
-export type GetTestParamsFn = () => TestParams;
-
-let params: TestParams;
-export const getTestParams = () => {
- if (params) {
- return params;
- }
- params = {} as TestParams;
-
- if (typeof window === 'undefined') {
- return params;
- }
-
- const searchParams = new URLSearchParams(window.location.search);
-
- let test = searchParams.get('test');
- if (!test || !testTypes.includes(test as TestParams['test'])) {
- test = 'manual';
- }
-
- let numStartNodes = Number(searchParams.get('numStartNodes'));
- if (!numStartNodes || isNaN(numStartNodes)) {
- numStartNodes = 100;
- }
-
- let numAddNodes = Number(searchParams.get('numAddNodes'));
- if (!numAddNodes || isNaN(numAddNodes)) {
- numAddNodes = 100;
- }
-
- let numRemoveNodes = Number(searchParams.get('numRemoveNodes'));
- if (!numRemoveNodes || isNaN(numRemoveNodes)) {
- numRemoveNodes = 99;
- }
-
- params.test = test as TestParams['test'];
- params.numStartNodes = numStartNodes;
- params.numAddNodes = numAddNodes;
- params.numRemoveNodes = numRemoveNodes;
-
- return params;
-};
diff --git a/apps/stress-test/src/shared/tree/RandomSelectorTreeNode.ts b/apps/stress-test/src/shared/tree/RandomSelectorTreeNode.ts
deleted file mode 100644
index 89affde79593a0..00000000000000
--- a/apps/stress-test/src/shared/tree/RandomSelectorTreeNode.ts
+++ /dev/null
@@ -1,139 +0,0 @@
-import { RandomSelector } from '../css/RandomSelector.js';
-import { TreeNode, TreeNodeCreateCallback } from './RandomTree.js';
-import { random } from '../utils/random.js';
-
-export type Attribute = {
- key: string;
- value: string | undefined;
- selector: string;
-};
-
-export type RandomSelectorTreeNode = {
- name: string;
- classNames: string[];
- attributes: Attribute[];
- siblings: string[];
- pseudos: string[];
-};
-
-export type SelectorTreeNode = TreeNode;
-
-const { coin, choice } = random();
-const randomSelector = new RandomSelector();
-
-const chances: { [key: string]: number } = {
- not: 0.05,
- addClassName: 0.5,
- addAttribute: 0.25,
- buildDescendentSelector: 0.75,
- addSibling: 0.25,
- addPseudo: 0.25,
- useDescendantCombinator: 0.2,
-};
-
-const buildDescendentSelector = (
- node: TreeNode | null,
- selector: string = '',
-): string => {
- if (!node) {
- return selector;
- }
-
- selector = (
- maybeNot(choice(getSelectorsFromNode(node))) +
- (coin(chances.useDescendantCombinator) ? ' > ' : ' ') +
- selector
- ).trim();
-
- if (coin(chances.buildDescendentSelector)) {
- selector = buildDescendentSelector(node.parent, selector);
- }
-
- return selector;
-};
-
-const getNodeClassNames = () => {
- const nodeSelectors = [randomSelector.randomSelector(['class'])];
- if (coin(chances.addClassName)) {
- nodeSelectors.push(randomSelector.randomSelector(['class']));
- }
-
- return nodeSelectors;
-};
-
-const maybeNot = (selector: string): string => {
- if (coin(chances.not)) {
- return `:not(${selector})`;
- }
-
- return selector;
-};
-
-const getAttributes = () => {
- const attributes = [];
- if (coin(chances.addAttribute)) {
- const selector = randomSelector.randomSelector(['attribute-name', 'attribute-value']);
- const [key, value] = selector.replace(/(\[|\])/g, '').split('=');
- attributes.push({ key, value, selector });
- }
-
- return attributes;
-};
-
-const getSiblingSelectors = () => {
- const siblings = [];
-
- if (coin(chances.addSibling)) {
- siblings.push(randomSelector.randomSelector(['nth-child']));
- }
-
- return siblings;
-};
-
-const getPseudoSelectors = () => {
- const pseudo = [];
-
- if (coin(chances.addPsuedo)) {
- pseudo.push(randomSelector.randomSelector(['pseudo-element']));
- }
-
- return pseudo;
-};
-
-const getSelectorsFromNode = (node: TreeNode): string[] => {
- return [
- ...node.value.classNames,
- ...node.value.attributes.map(attr => attr.selector),
- ...node.value.siblings,
- ...node.value.pseudos,
- ];
-};
-
-export type RandomSelectorTreeCreator = (selectors: string[]) => TreeNodeCreateCallback;
-
-export const selectorTreeCreator: RandomSelectorTreeCreator = selectors => {
- const createSelectorTree: TreeNodeCreateCallback = (parent, depth, breadth) => {
- const node = {
- value: {
- name: `${depth}-${breadth}`,
- classNames: getNodeClassNames(),
- attributes: getAttributes(),
- siblings: getSiblingSelectors(),
- pseudos: getPseudoSelectors(),
- },
- children: [],
- parent,
- };
-
- if (coin(chances.buildDescendentSelector)) {
- const descendentSelector = buildDescendentSelector(node);
- selectors.push(descendentSelector);
- } else {
- selectors.push(...getSelectorsFromNode(node));
- }
-
- return node;
- };
-
- return createSelectorTree;
-};
diff --git a/apps/stress-test/src/shared/tree/RandomTree.ts b/apps/stress-test/src/shared/tree/RandomTree.ts
deleted file mode 100644
index 06d8705343f9b8..00000000000000
--- a/apps/stress-test/src/shared/tree/RandomTree.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import { random, Random } from '../utils/random.js';
-import { TestFixture } from '../utils/testUtils.js';
-
-type TreeParams = {
- minDepth?: number;
- maxDepth?: number;
- minBreadth?: number;
- maxBreadth?: number;
- seed?: number;
-};
-
-export type TreeNode = {
- value: T;
- children: TreeNode[];
- parent: TreeNode | null;
-};
-
-export type TreeNodeCreateCallback = (parent: TreeNode | null, depth: number, breath: number) => TreeNode;
-export type TreeNodeVisitCallback = (node: TreeNode) => void;
-
-/**
- * Exponential decay function.
- * See: https://www.cuemath.com/exponential-decay-formula/
- * @param a - Initial amount
- * @param r - Rate of decay
- * @param x - Decay interval
- * @returns Current amount after applying decay function.
- */
-const decay = (a: number, r: number, x: number): number => {
- return a * Math.pow(1 - r, x);
-};
-
-export class RandomTree {
- private numNodes: number;
- private minDepth: number;
- private maxDepth: number;
- private minBreadth: number;
- private maxBreadth: number;
-
- private rando: Random;
-
- constructor({ minDepth = 1, maxDepth = 15, minBreadth = 1, maxBreadth = 15, seed }: TreeParams = {}) {
- this.minDepth = minDepth;
- this.maxDepth = maxDepth;
- this.minBreadth = minBreadth;
- this.maxBreadth = maxBreadth;
-
- this.rando = random(seed);
- this.numNodes = 0;
- }
-
- public build = (createNode: TreeNodeCreateCallback): TreeNode => {
- this.numNodes = 1;
- const root = createNode(null, 0, 0);
- return this._doBuild(createNode, root, 1);
- };
-
- public fromFixture = (fixture: TestFixture['tree'], parent: TreeNode | null = null): TreeNode => {
- const root: TreeNode = {
- value: fixture.value as T,
- children: [],
- parent,
- };
-
- for (const child of fixture.children) {
- root.children.push(this.fromFixture(child, root));
- }
-
- return root;
- };
-
- private _randomDepth = (max?: number): number => {
- return this.rando.range(this.minDepth, max ?? this.maxDepth);
- };
-
- private _randomBreadth = (max?: number): number => {
- return this.rando.range(this.minBreadth, max ?? this.maxBreadth);
- };
-
- private _doBuild = (
- createNode: TreeNodeCreateCallback,
- parent: TreeNode,
- currentDepth: number,
- currentBreadth: number = this.maxBreadth,
- ): TreeNode => {
- const breadth = this._randomBreadth(currentBreadth);
- const depth = this._randomDepth(Math.max(this.maxDepth - currentDepth, this.minDepth));
-
- for (let i = 0; i < breadth; i++) {
- this.numNodes++;
- const node = createNode(parent, currentDepth, breadth);
-
- parent.children.push(node);
-
- if (currentDepth < depth) {
- this._doBuild(
- createNode,
- node,
- currentDepth + 1,
- Math.max(Math.ceil(decay(this.maxBreadth, 0.005, this.numNodes)), this.minBreadth),
- );
- }
- }
-
- return parent;
- };
-}
diff --git a/apps/stress-test/src/shared/tree/iterators/dfs.ts b/apps/stress-test/src/shared/tree/iterators/dfs.ts
new file mode 100644
index 00000000000000..b6f61f88a93e44
--- /dev/null
+++ b/apps/stress-test/src/shared/tree/iterators/dfs.ts
@@ -0,0 +1,28 @@
+import { TreeNode } from '../types';
+
+type TreeResult = {
+ node: T;
+ index: number;
+};
+
+export const dfsIterator = (tree: TreeNode): Iterable> => {
+ let index = 0;
+ return {
+ *[Symbol.iterator]() {
+ const stack = [tree];
+ while (stack.length) {
+ const item = stack.pop()!;
+ if (item.children.length) {
+ let i = item.children.length - 1;
+ while (i > -1) {
+ stack.push(item.children[i]);
+ i--;
+ }
+ }
+
+ yield { node: item.value, index };
+ index++;
+ }
+ },
+ };
+};
diff --git a/apps/stress-test/src/shared/tree/types.ts b/apps/stress-test/src/shared/tree/types.ts
new file mode 100644
index 00000000000000..10cc6114437bf7
--- /dev/null
+++ b/apps/stress-test/src/shared/tree/types.ts
@@ -0,0 +1,24 @@
+export type Attribute = {
+ key: string;
+ value: string | undefined;
+ selector: string;
+};
+
+export type RandomSelectorTreeNode = {
+ name: string;
+ classNames: string[];
+ attributes: Attribute[];
+ siblings: string[];
+ pseudos: string[];
+};
+
+export type SelectorTreeNode = TreeNode;
+
+export type TreeNode = {
+ value: T;
+ children: TreeNode[];
+ parent: TreeNode | null;
+};
+
+export type TreeNodeCreateCallback = (parent: TreeNode | null, depth: number, breath: number) => TreeNode;
+export type TreeNodeVisitCallback = (node: TreeNode) => void;
diff --git a/apps/stress-test/src/shared/utils/performanceMeasure.ts b/apps/stress-test/src/shared/utils/performanceMeasure.ts
new file mode 100644
index 00000000000000..43d7af07a3fff8
--- /dev/null
+++ b/apps/stress-test/src/shared/utils/performanceMeasure.ts
@@ -0,0 +1,11 @@
+import { requestPostAnimationFrame } from './requestPostAnimationFrame';
+
+export type PerformanceMeasureFn = (measureName?: string, startMark?: string) => void;
+
+export const performanceMeasure: PerformanceMeasureFn = (measureName = 'stress', startMark = 'start') => {
+ performance.mark(startMark);
+
+ requestPostAnimationFrame(() => {
+ performance.measure(measureName, startMark);
+ });
+};
diff --git a/apps/stress-test/src/shared/utils/requestPostAnimationFrame.ts b/apps/stress-test/src/shared/utils/requestPostAnimationFrame.ts
new file mode 100644
index 00000000000000..1380db348d6a4f
--- /dev/null
+++ b/apps/stress-test/src/shared/utils/requestPostAnimationFrame.ts
@@ -0,0 +1,6 @@
+export const requestPostAnimationFrame = (callback: Function): void => {
+ requestAnimationFrame(() => {
+ addEventListener('message', _ => callback(), { once: true });
+ postMessage('', '*');
+ });
+};
diff --git a/apps/stress-test/src/shared/utils/testUtils.ts b/apps/stress-test/src/shared/utils/testUtils.ts
index 83b5a13d36b97c..e1de92452ff3ad 100644
--- a/apps/stress-test/src/shared/utils/testUtils.ts
+++ b/apps/stress-test/src/shared/utils/testUtils.ts
@@ -1,9 +1,31 @@
-export type TestFixture = {
+export type TestTreeFixture = {
tree: {
value: unknown;
- children: TestFixture['tree'][];
+ children: TestTreeFixture['tree'][];
};
selectors: string[];
};
-export type TestRenderer = (node: unknown, depth: number, index: number) => unknown;
+export type TestReactRenderer = (node: unknown, depth: number, index: number) => JSX.Element;
+export type TestDOMRenderer = (node: unknown, depth: number, index: number) => HTMLElement;
+
+export type LoaderResult = {
+ fixture: TFixture;
+ renderer: TRenderer;
+};
+
+export const loadTestData = (
+ target: string,
+ fixtureName: string,
+ rendererName: string,
+): Promise> => {
+ return Promise.all([
+ import(`../../fixtures/${fixtureName}`),
+ import(`../../renderers/${target}/${rendererName}`),
+ ]).then(([fixtureResult, rendererResult]) => {
+ const { default: fixture } = fixtureResult;
+ const { default: renderer } = rendererResult;
+
+ return { fixture, renderer };
+ });
+};
diff --git a/apps/stress-test/src/shared/vanilla/TestAdd.ts b/apps/stress-test/src/shared/vanilla/TestAdd.ts
new file mode 100644
index 00000000000000..59506a6348961c
--- /dev/null
+++ b/apps/stress-test/src/shared/vanilla/TestAdd.ts
@@ -0,0 +1,27 @@
+import { styleInjector } from '../css/injectStyles';
+import { performanceMeasure } from '../utils/performanceMeasure';
+import { TestOptions } from '../utils/testOptions';
+import { SelectorTreeNode } from '../tree/types';
+import { DOMSelectorTreeComponentRenderer } from './types';
+import { renderVanillaSelectorTree } from './VanillaSelectorTree';
+
+export const testAdd = (
+ tree: SelectorTreeNode,
+ selectors: string[],
+ componentRenderer: DOMSelectorTreeComponentRenderer,
+ testOptions: TestOptions,
+): HTMLElement => {
+ if (testOptions.withStyles === 'true') {
+ styleInjector(selectors);
+ }
+
+ const wrapper = document.createElement('div');
+ wrapper.appendChild(renderVanillaSelectorTree(tree, selectors, componentRenderer, testOptions));
+
+ setTimeout(() => {
+ wrapper.appendChild(renderVanillaSelectorTree(tree, selectors, componentRenderer, testOptions));
+ performanceMeasure();
+ }, 2000);
+
+ return wrapper;
+};
diff --git a/apps/stress-test/src/shared/vanilla/TestInjectStyles.ts b/apps/stress-test/src/shared/vanilla/TestInjectStyles.ts
new file mode 100644
index 00000000000000..537eb2885ab8b9
--- /dev/null
+++ b/apps/stress-test/src/shared/vanilla/TestInjectStyles.ts
@@ -0,0 +1,22 @@
+import { styleInjector } from '../css/injectStyles';
+import { performanceMeasure } from '../utils/performanceMeasure';
+import { TestOptions } from '../utils/testOptions';
+import { SelectorTreeNode } from '../tree/types';
+import { DOMSelectorTreeComponentRenderer } from './types';
+import { renderVanillaSelectorTree } from './VanillaSelectorTree';
+
+export const testInjectStyles = (
+ tree: SelectorTreeNode,
+ selectors: string[],
+ componentRenderer: DOMSelectorTreeComponentRenderer,
+ testOptions: TestOptions,
+): HTMLElement => {
+ const vanillaTree = renderVanillaSelectorTree(tree, selectors, componentRenderer, testOptions);
+
+ setTimeout(() => {
+ styleInjector(selectors);
+ performanceMeasure();
+ }, 2000);
+
+ return vanillaTree;
+};
diff --git a/apps/stress-test/src/shared/vanilla/TestMount.ts b/apps/stress-test/src/shared/vanilla/TestMount.ts
new file mode 100644
index 00000000000000..bee5e4275ca689
--- /dev/null
+++ b/apps/stress-test/src/shared/vanilla/TestMount.ts
@@ -0,0 +1,26 @@
+import { TestOptions } from '../utils/testOptions';
+import { SelectorTreeNode } from '../tree/types';
+import { DOMSelectorTreeComponentRenderer } from './types';
+import { renderVanillaSelectorTree } from './VanillaSelectorTree';
+import { styleInjector } from '../css/injectStyles';
+import { requestPostAnimationFrame } from '../utils/requestPostAnimationFrame';
+
+export const testMount = (
+ tree: SelectorTreeNode,
+ selectors: string[],
+ componentRenderer: DOMSelectorTreeComponentRenderer,
+ testOptions: TestOptions,
+): HTMLElement => {
+ performance.mark('start');
+
+ if (testOptions.withStyles === 'true') {
+ styleInjector(selectors);
+ }
+
+ const vanillaTree = renderVanillaSelectorTree(tree, selectors, componentRenderer, testOptions);
+
+ requestPostAnimationFrame(() => {
+ performance.measure('stress', 'start');
+ });
+ return vanillaTree;
+};
diff --git a/apps/stress-test/src/shared/vanilla/TestReRenderAll.ts b/apps/stress-test/src/shared/vanilla/TestReRenderAll.ts
new file mode 100644
index 00000000000000..eba98a30ff3feb
--- /dev/null
+++ b/apps/stress-test/src/shared/vanilla/TestReRenderAll.ts
@@ -0,0 +1,33 @@
+import { styleInjector } from '../css/injectStyles';
+import { performanceMeasure } from '../utils/performanceMeasure';
+import { TestOptions } from '../utils/testOptions';
+import { SelectorTreeNode } from '../tree/types';
+import { DOMSelectorTreeComponentRenderer } from './types';
+import { renderVanillaSelectorTree } from './VanillaSelectorTree';
+
+export const testReRenderAll = (
+ tree: SelectorTreeNode,
+ selectors: string[],
+ componentRenderer: DOMSelectorTreeComponentRenderer,
+ testOptions: TestOptions,
+): HTMLElement => {
+ if (testOptions.withStyles === 'true') {
+ styleInjector(selectors);
+ }
+
+ const wrapper = document.createElement('div');
+ wrapper.appendChild(renderVanillaSelectorTree(tree, selectors, componentRenderer, testOptions));
+
+ setTimeout(() => {
+ while (wrapper.hasChildNodes()) {
+ wrapper.removeChild(wrapper.lastChild!);
+ }
+
+ setTimeout(() => {
+ wrapper.appendChild(renderVanillaSelectorTree(tree, selectors, componentRenderer, testOptions));
+ performanceMeasure();
+ }, 2000);
+ }, 2000);
+
+ return wrapper;
+};
diff --git a/apps/stress-test/src/shared/vanilla/TestRemoveAll.ts b/apps/stress-test/src/shared/vanilla/TestRemoveAll.ts
new file mode 100644
index 00000000000000..44c8fc4005e003
--- /dev/null
+++ b/apps/stress-test/src/shared/vanilla/TestRemoveAll.ts
@@ -0,0 +1,29 @@
+import { styleInjector } from '../css/injectStyles';
+import { performanceMeasure } from '../utils/performanceMeasure';
+import { TestOptions } from '../utils/testOptions';
+import { SelectorTreeNode } from '../tree/types';
+import { DOMSelectorTreeComponentRenderer } from './types';
+import { renderVanillaSelectorTree } from './VanillaSelectorTree';
+
+export const testRemoveAll = (
+ tree: SelectorTreeNode,
+ selectors: string[],
+ componentRenderer: DOMSelectorTreeComponentRenderer,
+ testOptions: TestOptions,
+): HTMLElement => {
+ if (testOptions.withStyles === 'true') {
+ styleInjector(selectors);
+ }
+
+ const wrapper = document.createElement('div');
+ wrapper.appendChild(renderVanillaSelectorTree(tree, selectors, componentRenderer, testOptions));
+
+ setTimeout(() => {
+ while (wrapper.hasChildNodes()) {
+ wrapper.removeChild(wrapper.lastChild!);
+ }
+ performanceMeasure();
+ }, 2000);
+
+ return wrapper;
+};
diff --git a/apps/stress-test/src/shared/vanilla/VanillaSelectorTree.ts b/apps/stress-test/src/shared/vanilla/VanillaSelectorTree.ts
index 308fbd70abe436..34122b11e6b2af 100644
--- a/apps/stress-test/src/shared/vanilla/VanillaSelectorTree.ts
+++ b/apps/stress-test/src/shared/vanilla/VanillaSelectorTree.ts
@@ -1,5 +1,5 @@
import { TestOptions } from '../utils/testOptions';
-import { SelectorTreeNode } from '../tree/RandomSelectorTreeNode';
+import { SelectorTreeNode } from '../tree/types';
import { DOMSelectorTreeComponentRenderer } from './types';
import { renderVanillaTree } from './VanillaTree';
diff --git a/apps/stress-test/src/shared/vanilla/VanillaTree.ts b/apps/stress-test/src/shared/vanilla/VanillaTree.ts
index eeb250045b43fd..e56d9750770f11 100644
--- a/apps/stress-test/src/shared/vanilla/VanillaTree.ts
+++ b/apps/stress-test/src/shared/vanilla/VanillaTree.ts
@@ -1,4 +1,4 @@
-import { TreeNode } from '../tree/RandomTree';
+import { TreeNode } from '../tree/types';
export type VanillaTreeItemRenderer = (node: T, depth: number, index: number) => HTMLElement;
@@ -11,6 +11,16 @@ export const renderVanillaTree = >(
const root = document.createElement('div');
root.classList.add('vanilla-tree-node');
+ const { value } = tree;
+
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
+ // @ts-ignore
+ root.classList.add(...value.classNames.map(cn => cn.substring(1)));
+ // @ts-ignore
+ value.attributes.forEach(attr => {
+ root.setAttribute(attr.key, attr.value ?? '');
+ });
+
root.appendChild(itemRenderer(tree, depth, index));
tree.children.forEach((child, i) => {
diff --git a/apps/stress-test/src/shared/vanilla/types.ts b/apps/stress-test/src/shared/vanilla/types.ts
index 3700ac33581877..fe46bf4ab53434 100644
--- a/apps/stress-test/src/shared/vanilla/types.ts
+++ b/apps/stress-test/src/shared/vanilla/types.ts
@@ -1,3 +1,3 @@
-import { SelectorTreeNode } from '../tree/RandomSelectorTreeNode';
+import { SelectorTreeNode } from '../tree/types';
export type DOMSelectorTreeComponentRenderer = (node: SelectorTreeNode, depth: number, index: number) => HTMLElement;
diff --git a/apps/stress-test/src/shared/wc/TestAdd.ts b/apps/stress-test/src/shared/wc/TestAdd.ts
new file mode 100644
index 00000000000000..66af63039550bd
--- /dev/null
+++ b/apps/stress-test/src/shared/wc/TestAdd.ts
@@ -0,0 +1,35 @@
+import { TestOptions } from '../utils/testOptions';
+import { WCSelectorTree } from './WCSelectorTree';
+import { WCTestTree } from './types';
+import { SelectorTreeNode } from '../tree/types';
+import { DOMSelectorTreeComponentRenderer } from '../vanilla/types';
+import { styleInjector } from '../css/injectStyles';
+import { performanceMeasure } from '../utils/performanceMeasure';
+
+export class TestAdd extends HTMLElement implements WCTestTree {
+ constructor(
+ tree: SelectorTreeNode,
+ selectors: string[],
+ componentRenderer: DOMSelectorTreeComponentRenderer,
+ testOptions: TestOptions,
+ ) {
+ super();
+
+ if (testOptions.withStyles === 'true') {
+ styleInjector(selectors);
+ }
+
+ const domTree = new WCSelectorTree(componentRenderer, testOptions);
+ domTree.tree = tree;
+ this.appendChild(domTree);
+
+ setTimeout(() => {
+ const addDomTree = new WCSelectorTree(componentRenderer, testOptions);
+ addDomTree.tree = tree;
+ this.appendChild(addDomTree);
+ requestAnimationFrame(() => performanceMeasure());
+ }, 2000);
+ }
+}
+
+window.customElements.define('wc-test-add', TestAdd);
diff --git a/apps/stress-test/src/shared/wc/TestInjectStyles.ts b/apps/stress-test/src/shared/wc/TestInjectStyles.ts
new file mode 100644
index 00000000000000..65851107fb7cf7
--- /dev/null
+++ b/apps/stress-test/src/shared/wc/TestInjectStyles.ts
@@ -0,0 +1,29 @@
+import { TestOptions } from '../utils/testOptions';
+import { WCSelectorTree } from './WCSelectorTree';
+import { WCTestTree } from './types';
+import { SelectorTreeNode } from '../tree/types';
+import { DOMSelectorTreeComponentRenderer } from '../vanilla/types';
+import { styleInjector } from '../css/injectStyles';
+import { performanceMeasure } from '../utils/performanceMeasure';
+
+export class TestInjectStyles extends HTMLElement implements WCTestTree {
+ constructor(
+ tree: SelectorTreeNode,
+ selectors: string[],
+ componentRenderer: DOMSelectorTreeComponentRenderer,
+ testOptions: TestOptions,
+ ) {
+ super();
+
+ const domTree = new WCSelectorTree(componentRenderer, testOptions);
+ domTree.tree = tree;
+ this.appendChild(domTree);
+
+ setTimeout(() => {
+ styleInjector(selectors);
+ performanceMeasure();
+ }, 2000);
+ }
+}
+
+window.customElements.define('wc-test-inject-styles', TestInjectStyles);
diff --git a/apps/stress-test/src/shared/wc/TestMount.ts b/apps/stress-test/src/shared/wc/TestMount.ts
new file mode 100644
index 00000000000000..90fb2309fffc6c
--- /dev/null
+++ b/apps/stress-test/src/shared/wc/TestMount.ts
@@ -0,0 +1,30 @@
+import { performanceMeasure } from '../utils/performanceMeasure';
+import { TestOptions } from '../utils/testOptions';
+import { SelectorTreeNode } from '../tree/types';
+import { DOMSelectorTreeComponentRenderer } from '../vanilla/types';
+import { WCTestTree } from './types';
+import { WCSelectorTree } from './WCSelectorTree';
+import { styleInjector } from '../css/injectStyles';
+
+export class TestMount extends HTMLElement implements WCTestTree {
+ constructor(
+ tree: SelectorTreeNode,
+ selectors: string[],
+ componentRenderer: DOMSelectorTreeComponentRenderer,
+ testOptions: TestOptions,
+ ) {
+ super();
+
+ if (testOptions.withStyles === 'true') {
+ styleInjector(selectors);
+ }
+
+ const domTree = new WCSelectorTree(componentRenderer, testOptions);
+ domTree.tree = tree;
+
+ this.appendChild(domTree);
+ requestAnimationFrame(() => performanceMeasure());
+ }
+}
+
+window.customElements.define('wc-test-mount', TestMount);
diff --git a/apps/stress-test/src/shared/wc/TestReRenderAll.ts b/apps/stress-test/src/shared/wc/TestReRenderAll.ts
new file mode 100644
index 00000000000000..388e807b1c7b35
--- /dev/null
+++ b/apps/stress-test/src/shared/wc/TestReRenderAll.ts
@@ -0,0 +1,37 @@
+import { TestOptions } from '../utils/testOptions';
+import { WCSelectorTree } from './WCSelectorTree';
+import { WCTestTree } from './types';
+import { SelectorTreeNode } from '../tree/types';
+import { DOMSelectorTreeComponentRenderer } from '../vanilla/types';
+import { styleInjector } from '../css/injectStyles';
+import { performanceMeasure } from '../utils/performanceMeasure';
+
+export class TestReRenderAll extends HTMLElement implements WCTestTree {
+ constructor(
+ tree: SelectorTreeNode,
+ selectors: string[],
+ componentRenderer: DOMSelectorTreeComponentRenderer,
+ testOptions: TestOptions,
+ ) {
+ super();
+
+ if (testOptions.withStyles === 'true') {
+ styleInjector(selectors);
+ }
+
+ const domTree = new WCSelectorTree(componentRenderer, testOptions);
+ domTree.tree = tree;
+ this.appendChild(domTree);
+
+ setTimeout(() => {
+ domTree.tree = null;
+
+ setTimeout(() => {
+ domTree.tree = tree;
+ requestAnimationFrame(() => performanceMeasure());
+ }, 2000);
+ }, 2000);
+ }
+}
+
+window.customElements.define('wc-test-re-render-all', TestReRenderAll);
diff --git a/apps/stress-test/src/shared/wc/TestRemoveAll.ts b/apps/stress-test/src/shared/wc/TestRemoveAll.ts
new file mode 100644
index 00000000000000..74b7c7a7de8580
--- /dev/null
+++ b/apps/stress-test/src/shared/wc/TestRemoveAll.ts
@@ -0,0 +1,33 @@
+import { TestOptions } from '../utils/testOptions';
+import { WCSelectorTree } from './WCSelectorTree';
+import { WCTestTree } from './types';
+import { SelectorTreeNode } from '../tree/types';
+import { DOMSelectorTreeComponentRenderer } from '../vanilla/types';
+import { styleInjector } from '../css/injectStyles';
+import { performanceMeasure } from '../utils/performanceMeasure';
+
+export class TestRemoveAll extends HTMLElement implements WCTestTree {
+ constructor(
+ tree: SelectorTreeNode,
+ selectors: string[],
+ componentRenderer: DOMSelectorTreeComponentRenderer,
+ testOptions: TestOptions,
+ ) {
+ super();
+
+ if (testOptions.withStyles === 'true') {
+ styleInjector(selectors);
+ }
+
+ const domTree = new WCSelectorTree(componentRenderer, testOptions);
+ domTree.tree = tree;
+ this.appendChild(domTree);
+
+ setTimeout(() => {
+ domTree.tree = null;
+ requestAnimationFrame(() => performanceMeasure());
+ }, 2000);
+ }
+}
+
+window.customElements.define('wc-test-remove-all', TestRemoveAll);
diff --git a/apps/stress-test/src/shared/wc/WCSelectorTree.ts b/apps/stress-test/src/shared/wc/WCSelectorTree.ts
index 957d862e5d6214..333d523a6296cf 100644
--- a/apps/stress-test/src/shared/wc/WCSelectorTree.ts
+++ b/apps/stress-test/src/shared/wc/WCSelectorTree.ts
@@ -1,5 +1,5 @@
import { TestOptions } from '../utils/testOptions';
-import { SelectorTreeNode } from '../tree/RandomSelectorTreeNode';
+import { SelectorTreeNode } from '../tree/types';
import { DOMSelectorTreeComponentRenderer } from '../vanilla/types';
import { WCTree } from './WCTree';
diff --git a/apps/stress-test/src/shared/wc/WCTest.ts b/apps/stress-test/src/shared/wc/WCTest.ts
new file mode 100644
index 00000000000000..eecbb65a2fd870
--- /dev/null
+++ b/apps/stress-test/src/shared/wc/WCTest.ts
@@ -0,0 +1,61 @@
+import { getTestOptions } from '../utils/testOptions';
+import { loadTestData, TestDOMRenderer, TestTreeFixture } from '../utils/testUtils';
+import { RandomSelectorTreeNode } from '../tree/types';
+import { RandomTree } from '../../../scripts/utils/tree/RandomTree';
+import { testInjectStyles } from '../vanilla/TestInjectStyles';
+import { testMount } from '../vanilla/TestMount';
+import { testRemoveAll } from '../vanilla/TestRemoveAll';
+import { testReRenderAll } from '../vanilla/TestReRenderAll';
+import { TestInjectStyles } from './TestInjectStyles';
+import { TestMount } from './TestMount';
+import { TestRemoveAll } from './TestRemoveAll';
+import { TestReRenderAll } from './TestReRenderAll';
+import { TestAdd } from './TestAdd';
+import { testAdd } from '../vanilla/TestAdd';
+
+export const wcTest = (): Promise => {
+ const testOptions = getTestOptions();
+ const { test, fixtureName, rendererName, r } = testOptions;
+
+ return loadTestData('wc', fixtureName, rendererName ?? r).then(
+ ({ fixture, renderer }) => {
+ const selectors: string[] = fixture.selectors;
+ const fixtureTree = fixture.tree;
+
+ const treeBuilder = new RandomTree();
+ const tree = treeBuilder.fromFixture(fixtureTree);
+ const { wcRenderer } = testOptions;
+
+ let testFn;
+
+ const isWC = wcRenderer === 'wc';
+
+ if (test === 'inject-styles') {
+ testFn = isWC ? TestInjectStyles : testInjectStyles;
+ } else if (test === 're-render-all') {
+ testFn = isWC ? TestReRenderAll : testReRenderAll;
+ } else if (test === 'remove-all') {
+ testFn = isWC ? TestRemoveAll : testRemoveAll;
+ } else if (test === 'add') {
+ testFn = isWC ? TestAdd : testAdd;
+ } /*if (test === 'mount')*/ else {
+ testFn = isWC ? TestMount : testMount;
+ }
+
+ if (testFn) {
+ if (isWC) {
+ /* eslint-disable */
+ // @ts-ignore
+ return new testFn(tree, selectors, renderer, testOptions);
+ /* eslint-enable */
+ } else {
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ return testFn(tree, selectors, renderer, testOptions);
+ }
+ }
+
+ return null;
+ },
+ );
+};
diff --git a/apps/stress-test/src/shared/wc/WCTree.ts b/apps/stress-test/src/shared/wc/WCTree.ts
index cd803d593e1209..49c52fc3202e70 100644
--- a/apps/stress-test/src/shared/wc/WCTree.ts
+++ b/apps/stress-test/src/shared/wc/WCTree.ts
@@ -1,4 +1,4 @@
-import { TreeNode } from '../tree/RandomTree';
+import { TreeNode } from '../tree/types';
export type WCTreeItemRenderer = (node: T, depth: number, index: number) => HTMLElement;
diff --git a/apps/stress-test/src/shared/wc/types.ts b/apps/stress-test/src/shared/wc/types.ts
new file mode 100644
index 00000000000000..48fbc32bde2cdf
--- /dev/null
+++ b/apps/stress-test/src/shared/wc/types.ts
@@ -0,0 +1,4 @@
+export interface WCTestTree {}
+export interface TestOptions {
+ [key: string]: string | number;
+}
diff --git a/apps/stress-test/tsconfig.json b/apps/stress-test/tsconfig.json
index d03eef02f54b59..84a9013ab71fc9 100644
--- a/apps/stress-test/tsconfig.json
+++ b/apps/stress-test/tsconfig.json
@@ -14,5 +14,5 @@
"outDir": "./dist"
},
"include": ["src"],
- "exclude": ["node_modules"]
+ "exclude": ["node_modules", "src/fixtures"]
}
diff --git a/apps/stress-test/webpack/webpack.config.ts b/apps/stress-test/webpack/webpack.config.ts
index 6c57826f433b2d..ed0d9dfe6f7260 100644
--- a/apps/stress-test/webpack/webpack.config.ts
+++ b/apps/stress-test/webpack/webpack.config.ts
@@ -7,6 +7,8 @@ import { configureGriffel } from './griffelConfig.js';
import * as WebpackDevServer from 'webpack-dev-server';
import { GriffelMode } from '../scripts/utils/types';
+const enabledReactProfiling = true;
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
type WebpackArgs = {
@@ -27,10 +29,14 @@ const createConfig: WebpackConfigurationCreator = (_env, argv) => {
output: {
filename: '[name].[contenthash].bundle.js',
sourceMapFilename: '[name].[contenthash].map',
- path: path.resolve(path.dirname(__dirname), 'dist'),
+ path: path.resolve(path.dirname(__dirname), !isProd ? 'dev-build' : 'dist'),
},
devtool: 'source-map',
resolve: {
+ alias: {
+ 'react-dom$': 'react-dom/profiling',
+ 'scheduler/tracing': 'scheduler/tracing-profiling',
+ },
extensions: ['.tsx', '.ts', '.js'],
plugins: [
new TsconfigPathsPlugin({
@@ -68,6 +74,14 @@ const createConfig: WebpackConfigurationCreator = (_env, argv) => {
},
};
+ if (enabledReactProfiling) {
+ config.resolve!.alias = {
+ ...config.resolve!.alias,
+ 'react-dom$': 'react-dom/profiling',
+ 'scheduler/tracing': 'scheduler/tracing-profiling',
+ };
+ }
+
if (!isProd) {
config.devServer = {
port: 9000,
diff --git a/package.json b/package.json
index cf21f08a591244..10839891eff121 100644
--- a/package.json
+++ b/package.json
@@ -179,7 +179,6 @@
"beachball": "2.31.0",
"chalk": "4.1.0",
"chrome-remote-interface": "0.28.2",
- "chromedriver": "104.0.0",
"ci-info": "3.2.0",
"circular-dependency-plugin": "5.2.2",
"clean-webpack-plugin": "4.0.0",
diff --git a/yarn.lock b/yarn.lock
index 0ffd9c3a0d8e15..9cde0a98991f34 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5117,11 +5117,6 @@
dependencies:
defer-to-connect "^2.0.1"
-"@testim/chrome-version@^1.1.2":
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/@testim/chrome-version/-/chrome-version-1.1.2.tgz#092005c5b77bd3bb6576a4677110a11485e11864"
- integrity sha512-1c4ZOETSRpI0iBfIFUqU4KqwBAB2lHUAlBjZz/YqOHqwM9dTTzjV6Km0ZkiEiSCx/tLr1BtESIKyWWMww+RUqw==
-
"@testing-library/dom@8.11.3", "@testing-library/dom@^8.0.0":
version "8.11.3"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.11.3.tgz#38fd63cbfe14557021e88982d931e33fb7c1a808"
@@ -7955,14 +7950,6 @@ axe-core@4.2.1, axe-core@^3.5.5, axe-core@^4.0.2, axe-core@^4.2.0:
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.2.1.tgz#2e50bcf10ee5b819014f6e342e41e45096239e34"
integrity sha512-evY7DN8qSIbsW2H/TWQ1bX3sXN1d4MNb5Vb4n7BzPuCwRHdkZ1H2eNLuSh73EoQqkGKUtju2G2HCcjCfhvZIAA==
-axios@^0.27.2:
- version "0.27.2"
- resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
- integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
- dependencies:
- follow-redirects "^1.14.9"
- form-data "^4.0.0"
-
axobject-query@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
@@ -9566,19 +9553,6 @@ chrome-trace-event@^1.0.2:
dependencies:
tslib "^1.9.0"
-chromedriver@104.0.0:
- version "104.0.0"
- resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-104.0.0.tgz#2f730f52a567280872567bf3497e1c673b6f4275"
- integrity sha512-zbHZutN2ATo19xA6nXwwLn+KueD/5w8ap5m4b6bCb8MIaRFnyDwMbFoy7oFAjlSMpCFL3KSaZRiWUwjj//N3yQ==
- dependencies:
- "@testim/chrome-version" "^1.1.2"
- axios "^0.27.2"
- del "^6.0.0"
- extract-zip "^2.0.1"
- https-proxy-agent "^5.0.0"
- proxy-from-env "^1.1.0"
- tcp-port-used "^1.0.1"
-
ci-info@3.2.0, ci-info@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6"
@@ -11204,13 +11178,6 @@ debug@4.1.1:
dependencies:
ms "^2.1.1"
-debug@4.3.1:
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
- integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
- dependencies:
- ms "2.1.2"
-
debuglog@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
@@ -13310,7 +13277,7 @@ extract-comments@1.1.0:
esprima-extract-comments "^1.1.0"
parse-code-context "^1.0.0"
-extract-zip@2.0.1, extract-zip@^2.0.1:
+extract-zip@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==
@@ -13954,11 +13921,6 @@ follow-redirects@^1.0.0:
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc"
integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==
-follow-redirects@^1.14.9:
- version "1.15.1"
- resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
- integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==
-
for-in@^1.0.1, for-in@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -16231,11 +16193,6 @@ invert-kv@^1.0.0:
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY=
-ip-regex@^4.1.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5"
- integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==
-
ip@1.1.5, ip@^1.1.0, ip@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
@@ -16832,11 +16789,6 @@ is-upper-case@^1.1.0:
dependencies:
upper-case "^1.1.0"
-is-url@^1.2.4:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52"
- integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==
-
is-utf8@^0.2.0, is-utf8@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
@@ -16886,15 +16838,6 @@ is-wsl@^2.1.0, is-wsl@^2.1.1, is-wsl@^2.2.0:
dependencies:
is-docker "^2.0.0"
-is2@^2.0.6:
- version "2.0.7"
- resolved "https://registry.yarnpkg.com/is2/-/is2-2.0.7.tgz#d084e10cab3bd45d6c9dfde7a48599fcbb93fcac"
- integrity sha512-4vBQoURAXC6hnLFxD4VW7uc04XiwTTl/8ydYJxKvPwkWQrSjInkuM5VZVg6BGr1/natq69zDuvO9lGpLClJqvA==
- dependencies:
- deep-is "^0.1.3"
- ip-regex "^4.1.0"
- is-url "^1.2.4"
-
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
@@ -22755,7 +22698,7 @@ proxy-from-env@1.0.0:
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee"
integrity sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=
-proxy-from-env@1.1.0, proxy-from-env@^1.0.0, proxy-from-env@^1.1.0:
+proxy-from-env@1.1.0, proxy-from-env@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
@@ -26251,14 +26194,6 @@ tar@^4, tar@^4.4.12:
safe-buffer "^5.2.1"
yallist "^3.1.1"
-tcp-port-used@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/tcp-port-used/-/tcp-port-used-1.0.2.tgz#9652b7436eb1f4cfae111c79b558a25769f6faea"
- integrity sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==
- dependencies:
- debug "4.3.1"
- is2 "^2.0.6"
-
telejson@^6.0.8:
version "6.0.8"
resolved "https://registry.yarnpkg.com/telejson/-/telejson-6.0.8.tgz#1c432db7e7a9212c1fbd941c3e5174ec385148f7"
@@ -26355,7 +26290,7 @@ terser@5.14.2, terser@^5.3.4, terser@^5.5.1, terser@^5.7.2:
source-map-support "~0.5.20"
terser@^4.1.2, terser@^4.3.9, terser@^4.6.12, terser@^4.6.2, terser@^4.6.3:
- version "4.8.1"
+ version "4.8.0"
resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17"
integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==
dependencies: