test(runtime): add async merge state test

This commit is contained in:
Bowen Tan 2022-06-10 15:36:50 +08:00
parent 3381d0b412
commit 92bcbfbfe8
10 changed files with 225 additions and 83 deletions

View File

@ -9,4 +9,5 @@ module.exports = {
},
],
],
plugins: ['@babel/plugin-transform-runtime'],
};

View File

@ -8,38 +8,36 @@
"spec": {
"components": [
{
"id": "tester",
"type": "test/v1/tester",
"id": "text",
"type": "core/v1/text",
"properties": {
"testId": "tester",
"text": "{{input.value}}{{input2.value}}{{input3.value}}"
"value": {
"raw": "text",
"format": "plain"
}
},
"traits": []
"traits": [
{
"type": "test/v1/timeout",
"properties": {
"value": "{{input.value + Math.random()}}"
}
}
]
},
{
"id": "input",
"type": "test/v1/input",
"properties": {
"testId": "",
"defaultValue": "foo"
},
"traits": []
},
{
"id": "input2",
"type": "test/v1/input",
"id": "tester",
"type": "test/v1/tester",
"properties": {
"testId": "",
"defaultValue": "bar"
},
"traits": []
},
{
"id": "input3",
"type": "test/v1/input",
"properties": {
"testId": "",
"defaultValue": "baz"
"text": "{{text.result}}"
},
"traits": []
}

View File

@ -10,6 +10,7 @@ import {
ComponentSchemaChangeSchema,
HiddenTraitSchema,
MergeStateSchema,
AsyncMergeStateSchema,
} from './mockSchema.spec';
const SingleComponentRenderTimes = '2';
@ -29,8 +30,8 @@ describe('single component condition', () => {
const { unmount } = render(<App options={SingleComponentSchema} />);
// simple component will render 2 times, because it have to eval trait and properties twice
expect(screen.getByTestId('single')?.textContent).toEqual(SingleComponentRenderTimes);
expect(screen.getByTestId('single-destroy')?.textContent).toEqual('0');
expect(screen.getByTestId('single')).toHaveTextContent(SingleComponentRenderTimes);
expect(screen.getByTestId('single-destroy-times')).toHaveTextContent('0');
unmount();
clear();
});
@ -40,8 +41,8 @@ describe('after the schema changes', () => {
it('the component and its siblings will not unmount after schema changes', () => {
const { App } = initSunmaoUI();
const { rerender, unmount } = render(<App options={ComponentSchemaChangeSchema} />);
expect(screen.getByTestId('staticComponent-destroy')?.textContent).toEqual('0');
expect(screen.getByTestId('dynamicComponent-destroy')?.textContent).toEqual('0');
expect(screen.getByTestId('staticComponent-destroy-times')).toHaveTextContent('0');
expect(screen.getByTestId('dynamicComponent-destroy-times')).toHaveTextContent('0');
const newMockSchema = produce(ComponentSchemaChangeSchema, draft => {
const c = draft.spec.components.find(c => c.id === 'dynamicComponent');
@ -51,8 +52,8 @@ describe('after the schema changes', () => {
});
rerender(<App options={newMockSchema} />);
expect(screen.getByTestId('staticComponent-destroy')?.textContent).toEqual('0');
expect(screen.getByTestId('dynamicComponent-destroy')?.textContent).toEqual('0');
expect(screen.getByTestId('staticComponent-destroy-times')).toHaveTextContent('0');
expect(screen.getByTestId('dynamicComponent-destroy-times')).toHaveTextContent('0');
unmount();
clear();
});
@ -63,8 +64,8 @@ describe('hidden trait condition', () => {
const { App, stateManager } = initSunmaoUI();
stateManager.noConsoleError = true;
const { unmount } = render(<App options={HiddenTraitSchema} />);
expect(screen.getByTestId('tester')?.textContent).toEqual(SingleComponentRenderTimes);
expect(screen.getByTestId('tester-text')?.textContent).toEqual('');
expect(screen.getByTestId('tester')).toHaveTextContent(SingleComponentRenderTimes);
expect(screen.getByTestId('tester-text')).toHaveTextContent('');
expect(stateManager.store['input1']).toBeUndefined();
unmount();
@ -76,8 +77,8 @@ describe('when component merge state synchronously', () => {
it('it will not cause extra render', () => {
const { App, stateManager } = initSunmaoUI();
const { unmount } = render(<App options={MergeStateSchema} />);
expect(screen.getByTestId('tester')?.textContent).toEqual(SingleComponentRenderTimes);
expect(screen.getByTestId('tester-text')?.textContent).toEqual('foo-bar-baz');
expect(screen.getByTestId('tester')).toHaveTextContent(SingleComponentRenderTimes);
expect(screen.getByTestId('tester-text')).toHaveTextContent('foo-bar-baz');
expect(stateManager.store['input'].value).toBe('foo');
unmount();
@ -91,33 +92,47 @@ describe('when component merge state synchronously', () => {
draft.spec.components[1] = temp;
});
const { App, stateManager } = initSunmaoUI();
stateManager.noConsoleError = true;
const { unmount } = render(<App options={newMergeStateSchema} />);
expect(screen.getByTestId('tester')?.textContent).toEqual(SingleComponentRenderTimes);
expect(screen.getByTestId('tester-text')?.textContent).toEqual('foo-bar-baz');
expect(screen.getByTestId('tester')).toHaveTextContent(SingleComponentRenderTimes);
expect(screen.getByTestId('tester-text')).toHaveTextContent('foo-bar-baz');
expect(stateManager.store['input'].value).toBe('foo');
unmount();
clear();
});
});
// expect(screen.getByTestId('tester1-text')?.textContent).toEqual('0');
// expect(screen.getByTestId('tester1')?.textContent).toEqual('3');
// expect(screen.getByTestId('tester2')?.textContent).toEqual('2');
// expect(screen.getByTestId('tester1-text')?.textContent).toEqual('1');
describe('when component merge state asynchronously', () => {
const timeoutPromise = () =>
new Promise<any>(res => {
setTimeout(() => res(true), 30);
});
// rerender(<App options={newMockSchema} />);
it('it will cause extra render', async () => {
const { App, stateManager } = initSunmaoUI();
stateManager.noConsoleError = true;
const { unmount } = render(<App options={AsyncMergeStateSchema} />);
await waitFor(timeoutPromise);
expect(await screen.findByTestId('tester')).toHaveTextContent('4');
// expect(screen.getByTestId('tester1')?.textContent).toEqual('3');
// expect(screen.getByTestId('tester2')?.textContent).toEqual('3');
// expect(screen.getByTestId('tester1-text')?.textContent).toEqual('1');
unmount();
clear();
});
// waitFor(() => {
// });
it(`the components' order may cause extra render`, async () => {
const newMergeStateSchema = produce(AsyncMergeStateSchema, draft => {
const temp = draft.spec.components[0];
draft.spec.components[0] = draft.spec.components[1];
draft.spec.components[1] = temp;
});
const { App, stateManager } = initSunmaoUI();
stateManager.noConsoleError = true;
const { unmount } = render(<App options={newMergeStateSchema} />);
await waitFor(timeoutPromise);
expect(await screen.findByTestId('tester')).toHaveTextContent('5');
// // the queries can accept a regex to make your selectors more resilient to content tweaks and changes.
// fireEvent.click(screen.getByLabelText(/show/i));
// // .toBeInTheDocument() is an assertion that comes from jest-dom
// // otherwise you could use .toBeDefined()
// expect(screen.getByText(testMessage)).toBeInTheDocument();
unmount();
clear();
});
});

View File

@ -12,7 +12,6 @@ export const SingleComponentSchema: Application = {
id: 'single',
type: 'test/v1/tester',
properties: {
testId: 'single',
text: 'Hello, world!',
},
traits: [],
@ -34,7 +33,6 @@ export const ComponentSchemaChangeSchema: Application = {
id: 'staticComponent',
type: 'test/v1/tester',
properties: {
testId: 'staticComponent',
text: 'foo',
},
traits: [],
@ -43,7 +41,6 @@ export const ComponentSchemaChangeSchema: Application = {
id: 'dynamicComponent',
type: 'test/v1/tester',
properties: {
testId: 'dynamicComponent',
text: 'bar',
},
traits: [],
@ -64,7 +61,6 @@ export const HiddenTraitSchema: Application = {
id: 'input1',
type: 'test/v1/input',
properties: {
testId: '',
defaultValue: 'foo',
},
traits: [
@ -80,7 +76,6 @@ export const HiddenTraitSchema: Application = {
id: 'tester',
type: 'test/v1/tester',
properties: {
testId: 'tester',
text: '{{input1.value}}',
},
traits: [],
@ -101,7 +96,6 @@ export const MergeStateSchema: Application = {
id: 'tester',
type: 'test/v1/tester',
properties: {
testId: 'tester',
text: '{{input.value}}-{{input2.value}}-{{input3.value}}',
},
traits: [],
@ -110,7 +104,6 @@ export const MergeStateSchema: Application = {
id: 'input',
type: 'test/v1/input',
properties: {
testId: '',
defaultValue: 'foo',
},
traits: [],
@ -119,7 +112,6 @@ export const MergeStateSchema: Application = {
id: 'input2',
type: 'test/v1/input',
properties: {
testId: '',
defaultValue: 'bar',
},
traits: [],
@ -128,7 +120,6 @@ export const MergeStateSchema: Application = {
id: 'input3',
type: 'test/v1/input',
properties: {
testId: '',
defaultValue: 'baz',
},
traits: [],
@ -136,3 +127,49 @@ export const MergeStateSchema: Application = {
],
},
};
export const AsyncMergeStateSchema: Application = {
version: 'sunmao/v1',
kind: 'Application',
metadata: {
name: 'some App',
},
spec: {
components: [
{
id: 'input',
type: 'test/v1/input',
properties: {
defaultValue: 'foo',
},
traits: [],
},
{
id: 'text',
type: 'core/v1/text',
properties: {
value: {
raw: 'text',
format: 'plain',
},
},
traits: [
{
type: 'test/v1/timeout',
properties: {
value: '{{input.value + Math.random()}}',
},
},
],
},
{
id: 'tester',
type: 'test/v1/tester',
properties: {
text: '{{text.result}}',
},
traits: [],
},
],
},
};

View File

@ -29,6 +29,8 @@
"prepublish": "npm run build && npm run typings"
},
"dependencies": {
"@babel/plugin-transform-runtime": "^7.18.2",
"@babel/runtime": "^7.18.3",
"@emotion/css": "^11.7.1",
"@sinclair/typebox": "^0.21.2",
"@sunmao-ui/core": "^0.7.0",
@ -53,6 +55,7 @@
},
"devDependencies": {
"@babel/core": "^7.15.5",
"@babel/plugin-transform-runtime": "^7.18.2",
"@babel/preset-env": "^7.15.6",
"@babel/preset-react": "^7.14.5",
"@babel/preset-typescript": "^7.15.0",

View File

@ -16,22 +16,20 @@ export default implementRuntimeComponent({
},
},
spec: {
properties: Type.Object({
testId: Type.String(),
}),
properties: Type.Object({}),
state: Type.Object({}),
methods: {},
slots: {},
styleSlots: [],
events: ['click'],
},
})(({ callbackMap, testId }) => {
})(({ callbackMap, component, elementRef }) => {
const onClick = () => {
callbackMap?.click();
};
return (
<div>
<button onClick={onClick} data-testid={testId}>
<div ref={elementRef}>
<button onClick={onClick} data-testid={component.id}>
Test Button
</button>
</div>

View File

@ -18,7 +18,6 @@ export default implementRuntimeComponent({
},
spec: {
properties: Type.Object({
testId: Type.String(),
defaultValue: Type.String(),
}),
state: Type.Object({
@ -29,12 +28,17 @@ export default implementRuntimeComponent({
styleSlots: [],
events: [],
},
})(({ testId, defaultValue, mergeState }) => {
})(({ component, defaultValue, mergeState, elementRef }) => {
const [value, setValue] = useState(defaultValue || '');
useEffect(() => {
mergeState({ value });
}, [mergeState, value]);
return (
<input data-testid={testId} value={value} onChange={e => setValue(e.target.value)} />
<input
ref={elementRef}
data-testid={component.id}
value={value}
onChange={e => setValue(e.target.value)}
/>
);
});

View File

@ -2,10 +2,8 @@ import { implementRuntimeComponent } from '../../utils/buildKit';
import { Type } from '@sinclair/typebox';
import { useEffect } from 'react';
(window as any).renderTimesMap = {};
(window as any).destroyTimesMap = {};
export const renderTimesMap = (window as any).renderTimesMap;
export const destroyTimesMap = (window as any).destroyTimesMap;
export const renderTimesMap: Record<string, number> = {};
export const destroyTimesMap: Record<string, number> = {};
export default implementRuntimeComponent({
version: 'test/v1',
@ -23,7 +21,6 @@ export default implementRuntimeComponent({
},
spec: {
properties: Type.Object({
testId: Type.String(),
text: Type.String(),
}),
state: Type.Object({}),
@ -32,25 +29,26 @@ export default implementRuntimeComponent({
styleSlots: [],
events: [],
},
})(({ testId, text }) => {
renderTimesMap[testId] = (renderTimesMap[testId] || 0) + 1;
})(({ component, elementRef, text }) => {
const id = component.id;
renderTimesMap[id] = (renderTimesMap[id] || 0) + 1;
useEffect(() => {
return () => {
destroyTimesMap[testId] = (destroyTimesMap[testId] || 0) + 1;
destroyTimesMap[id] = (destroyTimesMap[id] || 0) + 1;
};
}, [testId]);
}, [id]);
return (
<div>
<div ref={elementRef}>
<p>
<span>RenderTimes:</span>
<span data-testid={testId}>{renderTimesMap[testId] || 0}</span>{' '}
<span data-testid={id}>{renderTimesMap[id] || 0}</span>{' '}
</p>
<p>
<span>DestroyTimes:</span>
<span data-testid={`${testId}-destroy`}>{destroyTimesMap[testId] || 0}</span>{' '}
<span data-testid={`${id}-destroy-times`}>{destroyTimesMap[id] || 0}</span>{' '}
</p>
<span data-testid={`${testId}-text`}>{text}</span>
<span data-testid={`${id}-text`}>{text}</span>
</div>
);
});

View File

@ -4,15 +4,14 @@ import { TraitImplFactory } from '../../types';
const TimeoutTraitPropertiesSpec = Type.Object({
value: Type.String(),
timeout: Type.Optional(Type.Number()),
});
const TimeoutTrait: TraitImplFactory<Static<typeof TimeoutTraitPropertiesSpec>> = () => {
// This trait will merge it property value in its state after 50ms
return ({ value, mergeState }) => {
return ({ value, mergeState, timeout }) => {
setTimeout(() => {
console.log('timeout: ', value);
mergeState({ result: value });
}, 50);
}, timeout || 0);
return {
props: null,

View File

@ -202,6 +202,20 @@
resolve "^1.14.2"
semver "^6.1.2"
"@babel/helper-define-polyfill-provider@^0.3.1":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665"
integrity sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==
dependencies:
"@babel/helper-compilation-targets" "^7.13.0"
"@babel/helper-module-imports" "^7.12.13"
"@babel/helper-plugin-utils" "^7.13.0"
"@babel/traverse" "^7.13.0"
debug "^4.1.1"
lodash.debounce "^4.0.8"
resolve "^1.14.2"
semver "^6.1.2"
"@babel/helper-environment-visitor@^7.16.7":
version "7.16.7"
resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz"
@ -328,6 +342,11 @@
resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz"
integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==
"@babel/helper-plugin-utils@^7.17.12":
version "7.17.12"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz#86c2347da5acbf5583ba0a10aed4c9bf9da9cf96"
integrity sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==
"@babel/helper-remap-async-to-generator@^7.16.0":
version "7.16.0"
resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.0.tgz"
@ -1011,6 +1030,18 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-transform-runtime@^7.18.2":
version "7.18.2"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.2.tgz#04637de1e45ae8847ff14b9beead09c33d34374d"
integrity sha512-mr1ufuRMfS52ttq+1G1PD8OJNqgcTFjq3hwn8SZ5n1x1pBhi0E36rYMdTK0TsKtApJ4lDEdfXJwtGobQMHSMPg==
dependencies:
"@babel/helper-module-imports" "^7.16.7"
"@babel/helper-plugin-utils" "^7.17.12"
babel-plugin-polyfill-corejs2 "^0.3.0"
babel-plugin-polyfill-corejs3 "^0.5.0"
babel-plugin-polyfill-regenerator "^0.3.0"
semver "^6.3.0"
"@babel/plugin-transform-shorthand-properties@^7.16.0":
version "7.16.0"
resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.0.tgz"
@ -1197,7 +1228,7 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.9.2":
"@babel/runtime@^7.18.3", "@babel/runtime@^7.9.2":
version "7.18.3"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4"
integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==
@ -4445,6 +4476,15 @@ babel-plugin-polyfill-corejs2@^0.2.3:
"@babel/helper-define-polyfill-provider" "^0.2.4"
semver "^6.1.1"
babel-plugin-polyfill-corejs2@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5"
integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==
dependencies:
"@babel/compat-data" "^7.13.11"
"@babel/helper-define-polyfill-provider" "^0.3.1"
semver "^6.1.1"
babel-plugin-polyfill-corejs3@^0.3.0:
version "0.3.0"
resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.3.0.tgz"
@ -4453,6 +4493,14 @@ babel-plugin-polyfill-corejs3@^0.3.0:
"@babel/helper-define-polyfill-provider" "^0.2.4"
core-js-compat "^3.18.0"
babel-plugin-polyfill-corejs3@^0.5.0:
version "0.5.2"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72"
integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==
dependencies:
"@babel/helper-define-polyfill-provider" "^0.3.1"
core-js-compat "^3.21.0"
babel-plugin-polyfill-regenerator@^0.2.3:
version "0.2.3"
resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.3.tgz"
@ -4460,6 +4508,13 @@ babel-plugin-polyfill-regenerator@^0.2.3:
dependencies:
"@babel/helper-define-polyfill-provider" "^0.2.4"
babel-plugin-polyfill-regenerator@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990"
integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==
dependencies:
"@babel/helper-define-polyfill-provider" "^0.3.1"
babel-preset-current-node-syntax@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz"
@ -4557,6 +4612,17 @@ browserslist@^4.16.6, browserslist@^4.17.5:
node-releases "^2.0.1"
picocolors "^1.0.0"
browserslist@^4.20.3:
version "4.20.4"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.4.tgz#98096c9042af689ee1e0271333dbc564b8ce4477"
integrity sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==
dependencies:
caniuse-lite "^1.0.30001349"
electron-to-chromium "^1.4.147"
escalade "^3.1.1"
node-releases "^2.0.5"
picocolors "^1.0.0"
bser@2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz"
@ -4691,6 +4757,11 @@ caniuse-lite@^1.0.30001271:
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001274.tgz"
integrity sha512-+Nkvv0fHyhISkiMIjnyjmf5YJcQ1IQHZN6U9TLUMroWR38FNwpsC51Gb68yueafX1V6ifOisInSgP9WJFS13ew==
caniuse-lite@^1.0.30001349:
version "1.0.30001352"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001352.tgz#cc6f5da3f983979ad1e2cdbae0505dccaa7c6a12"
integrity sha512-GUgH8w6YergqPQDGWhJGt8GDRnY0L/iJVQcU3eJ46GYf52R8tk0Wxp0PymuFVZboJYXGiCqwozAYZNRjVj6IcA==
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz"
@ -5172,6 +5243,14 @@ core-js-compat@^3.18.0, core-js-compat@^3.19.0:
browserslist "^4.17.5"
semver "7.0.0"
core-js-compat@^3.21.0:
version "3.22.8"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.8.tgz#46fa34ce1ddf742acd7f95f575f66bbb21e05d62"
integrity sha512-pQnwg4xtuvc2Bs/5zYQPaEYYSuTxsF7LBWF0SvnVhthZo/Qe+rJpcEekrdNK5DWwDJ0gv0oI9NNX5Mppdy0ctg==
dependencies:
browserslist "^4.20.3"
semver "7.0.0"
core-js@^2.4.0:
version "2.6.12"
resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz"
@ -5610,6 +5689,11 @@ electron-to-chromium@^1.3.878:
resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.885.tgz"
integrity sha512-JXKFJcVWrdHa09n4CNZYfYaK6EW5aAew7/wr3L1OnsD1L+JHL+RCtd7QgIsxUbFPeTwPlvnpqNNTOLkoefmtXg==
electron-to-chromium@^1.4.147:
version "1.4.151"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.151.tgz#d1c09dd3a06cb81ef03a3bbbff6905827c33ab4b"
integrity sha512-XaG2LpZi9fdiWYOqJh0dJy4SlVywCvpgYXhzOlZTp4JqSKqxn5URqOjbm9OMYB3aInA2GuHQiem1QUOc1yT0Pw==
emittery@^0.8.1:
version "0.8.1"
resolved "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz"
@ -9173,6 +9257,11 @@ node-releases@^2.0.1:
resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz"
integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==
node-releases@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.5.tgz#280ed5bc3eba0d96ce44897d8aee478bfb3d9666"
integrity sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==
nopt@^4.0.1:
version "4.0.3"
resolved "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz"