From 3727497193f34b0fdab97e9f2e3863aaf814843c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E8=8C=82=E5=B3=B0?= Date: Sat, 28 Aug 2021 14:55:18 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20:bug:=20=E8=A7=A3=E5=86=B3=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=EF=BC=8C=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E6=95=B0=E6=8D=AE=E4=B8=8D=E5=90=8C=E6=AD=A5=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintignore | 1 + .github/workflows/main.yml | 7 +- package.json | 15 ++- src/AsanyEditor.tsx | 2 + src/api/AsideHelper.ts | 17 +++- src/components/aside/Aside.tsx | 51 ++++++---- src/components/aside/PropertiesPanel.tsx | 2 +- .../scena/viewport/MoveableManager.tsx | 1 + src/properties/DynaActionForm.tsx | 33 ++++--- src/reducers/index.ts | 1 - src/reducers/plugin.reducer.ts | 1 - src/reducers/ui.reducer/aside.reducer.ts | 1 - src/style/asany-editor.less | 6 -- src/typings.ts | 19 +++- stories/Properties.stories.tsx | 92 +++++++++++++++---- stories/Sidebar.stories.tsx | 2 +- stories/editors/demo/index.tsx | 21 ++--- test/blah.test.tsx | 5 +- test/globals-test.ts | 6 ++ yarn.lock | 84 ++++++++++++++++- 20 files changed, 278 insertions(+), 89 deletions(-) create mode 100644 .eslintignore create mode 100644 test/globals-test.ts diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..67f71b2 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +stories/** \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e7f0626..40e78ca 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,7 +7,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - node: ['14.x'] + node: ["14.x"] os: [ubuntu-latest] steps: @@ -28,5 +28,10 @@ jobs: - name: Test run: yarn test --ci --coverage --maxWorkers=2 + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Build run: yarn build diff --git a/package.json b/package.json index 540d09b..99e3958 100644 --- a/package.json +++ b/package.json @@ -93,8 +93,10 @@ "conventional-changelog-cli": "^2.1.1", "cssnano": "^4.1.11", "eslint-plugin-prettier": "^3.4.0", + "fake-indexeddb": "^3.1.3", "graphql": "^15.5.1", "husky": "^7.0.0", + "identity-obj-proxy": "^3.0.0", "less": "^4.1.1", "less-loader": "^7.3.0", "lodash-es": "^4.17.21", @@ -109,7 +111,7 @@ "react-router-dom": "^5.2.0", "rollup-plugin-postcss": "^4.0.0", "size-limit": "^5.0.1", - "sunmao": "^0.2.4", + "sunmao": "^0.2.5", "tailwindcss": "npm:@tailwindcss/postcss7-compat", "tsdx": "^0.14.1", "tslib": "^2.3.0", @@ -118,5 +120,16 @@ "resolutions": { "**/@typescript-eslint/eslint-plugin": "^4.1.1", "**/@typescript-eslint/parser": "^4.1.1" + }, + "jest": { + "moduleNameMapper": { + "^lodash-es$": "lodash", + "^lodash-es/.*": "lodash", + "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/__mocks__/fileMock.js", + "\\.(css|less)$": "identity-obj-proxy" + }, + "setupFiles": [ + "/test/globals-test.ts" + ] } } diff --git a/src/AsanyEditor.tsx b/src/AsanyEditor.tsx index 23f4e90..25f0a95 100644 --- a/src/AsanyEditor.tsx +++ b/src/AsanyEditor.tsx @@ -3,6 +3,7 @@ import React, { ComponentType, useCallback, useEffect, useReducer } from 'react' import { isElement, isValidElementType } from 'react-is'; import classnames from 'classnames'; +import 'overlayscrollbars/css/OverlayScrollbars.css'; import { AsanyProvider } from './AsanyContext'; import Aside from './components/aside'; @@ -65,6 +66,7 @@ function Editor({ return; } dispatch({ type: ActionType.BindSave, payload: onSave }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [onSave]); const handleResize = useCallback((x) => { diff --git a/src/api/AsideHelper.ts b/src/api/AsideHelper.ts index 13eb8fc..d6e5c8a 100644 --- a/src/api/AsideHelper.ts +++ b/src/api/AsideHelper.ts @@ -3,7 +3,15 @@ import React from 'react'; import { TabPane } from '../components/aside/PropertiesPanel'; import { ActionType } from '../reducers/actions'; -import type { AsideHelper, AsideTabPane, IAsanyEditor, IUIAsideState, PanelOptions, UndoFunc } from '../typings'; +import type { + AsideHelper, + AsideTabPane, + IAsanyEditor, + IUIAsideState, + PanelOptions, + SunmaoCustomizer, + UndoFunc, +} from '../typings'; export default class AsideHelperImpl implements AsideHelper { private editor: IAsanyEditor; @@ -20,9 +28,16 @@ export default class AsideHelperImpl implements AsideHelper { } aside.control.current.next(title, React.createElement(body)); } + open(data: SunmaoCustomizer, options?: PanelOptions): void; open(tabs: AsideTabPane[], options?: PanelOptions): void | UndoFunc; open(title: string, body: ComponentType, options?: PanelOptions): void | UndoFunc; open(title: any, body?: any) { + if (typeof title !== 'string' && !title.hasOwnProperty('length')) { + return this.editor.store.dispatch({ + type: ActionType.OpenAside, + payload: { block: title, options: arguments[1] }, + }); + } let options; const tabs: TabPane[] = []; if (typeof title === 'string') { diff --git a/src/components/aside/Aside.tsx b/src/components/aside/Aside.tsx index 6a8f43b..c1da93b 100644 --- a/src/components/aside/Aside.tsx +++ b/src/components/aside/Aside.tsx @@ -1,11 +1,11 @@ -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react'; import { isEqual } from 'lodash-es'; import { useDispatch, useSelector } from '../../hooks'; import { UIActionType } from '../../reducers/actions'; import { visibleFilter } from '../../utils'; -import { DynaActionFormContext } from '../../utils/BlockAside'; +import { DynaActionFormContext, buildAside } from '../../utils/BlockAside'; import ConfigurationToolbar from './ConfigurationToolbar'; import PropertiesPanel, { IPropertiesPanel } from './PropertiesPanel'; @@ -22,26 +22,31 @@ function Aside(_: AsideProps) { const dispatch = useDispatch(); const [top, setTop] = useState(60); + const externalTabs = useSelector((state) => state.ui.aside.tabs); const width = useSelector((state) => state.ui.aside.options?.width || 240); - const initialValue = useSelector((state) => state.ui.aside.options?.value); - const handleChange = useSelector((state) => state.ui.aside.options?.update); - const watchValue = useSelector((state) => state.ui.aside.options?.watchValue, isEqual); const scenaToolbarVisible = useSelector((state) => state.ui.scena.toolbar.visible); - const [value, setValue] = useState(initialValue); + const customizer = useSelector((state) => state.ui.aside.block?.customizer); + const initialValue = useSelector((state) => state.ui.aside.block?.value); + const handleChange = useSelector((state) => state.ui.aside.block?.update); + const watchValue = useSelector((state) => state.ui.aside.block?.watchValue, isEqual); - useEffect(() => { - setValue(initialValue); - }, [initialValue]); + const cache = useRef({ value: initialValue }); + + const [, forceRender] = useReducer((s) => s + 1, 0); useEffect(() => { if (!watchValue) { return; } - return watchValue(setValue); + return watchValue((value) => { + cache.current = value; + forceRender(); + }); }, [watchValue]); + // eslint-disable-next-line react-hooks/exhaustive-deps const handleClose = useCallback(() => dispatch({ type: UIActionType.CloseAside }), []); const configuration = useRef(null); @@ -51,14 +56,26 @@ function Aside(_: AsideProps) { type: UIActionType.AsideRef, payload: configuration, }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const tabs = useMemo(() => { - return externalTabs.map((item) => ({ - ...item, - content: , - })); - }, [externalTabs]); + cache.current.value = initialValue; + if (customizer) { + return buildAside(customizer).map((item) => ({ + ...item, + content: , + })); + } + if (externalTabs) { + return externalTabs.map((item) => ({ + ...item, + content: , + })); + } + return []; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [externalTabs, customizer]); useEffect(() => { const { container } = configuration.current!; @@ -68,7 +85,7 @@ function Aside(_: AsideProps) { }, [scenaToolbarVisible]); return ( - + } onClose={handleClose} /> diff --git a/src/components/aside/PropertiesPanel.tsx b/src/components/aside/PropertiesPanel.tsx index d525134..fe8b34a 100644 --- a/src/components/aside/PropertiesPanel.tsx +++ b/src/components/aside/PropertiesPanel.tsx @@ -125,7 +125,7 @@ function PropertiesPanel(props: PropertiesPanelProps, ref: React.ForwardedRef
diff --git a/src/components/scena/viewport/MoveableManager.tsx b/src/components/scena/viewport/MoveableManager.tsx index f09404a..ee2c0b7 100644 --- a/src/components/scena/viewport/MoveableManager.tsx +++ b/src/components/scena/viewport/MoveableManager.tsx @@ -28,6 +28,7 @@ function MoveableManager(props: MoveableManagerProps) { return () => { window.removeEventListener('resize', handeWindowResize); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const elementGuidelines = Array.from(moveableData.getTargets()).filter((el) => { diff --git a/src/properties/DynaActionForm.tsx b/src/properties/DynaActionForm.tsx index eb2014d..119f698 100644 --- a/src/properties/DynaActionForm.tsx +++ b/src/properties/DynaActionForm.tsx @@ -1,6 +1,6 @@ -import React, { useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; -import { ComponentPropertyRendererSetting, ICustomizer, IField, IGroup, useSunmao } from 'sunmao'; +import { ComponentPropertyRendererSetting, ICustomizer, IField, IGroup, useDebugger, useSunmao } from 'sunmao'; import isEqual from 'lodash/isEqual'; import classnames from 'classnames'; @@ -109,16 +109,18 @@ PanelBody.defaultProps = { const DynaActionForm = ({ library = 'cn.asany.editor.form', ...props }: DynaActionFormProps): JSX.Element => { const { value = {}, onChange, customizer } = props; + const console = useDebugger(); const sunmao = useSunmao(); const [groups, setGroups] = useState([]); + const defaultValue = useRef({}); const [form, Form] = useFormState(); useEffect(() => { if (!customizer) { return; } - const defaultValue: { [key: string]: string } = {}; + defaultValue.current = {}; groups.length = 0; setGroups( customizer.fields @@ -142,7 +144,7 @@ const DynaActionForm = ({ library = 'cn.asany.editor.form', ...props }: DynaActi renderer: getRenderer(sunmao, library, definition), }); } - defaultValue[definition.name] = definition.defaultValue; + defaultValue.current[definition.name] = definition.defaultValue; return groups; }, []) .map((group) => { @@ -152,23 +154,28 @@ const DynaActionForm = ({ library = 'cn.asany.editor.form', ...props }: DynaActi return group; }) ); - form.setFieldsValue({ ...defaultValue, ...value }); + const fieldsValue = { ...defaultValue.current, ...value }; + form.setFieldsValue(fieldsValue); + console.log('表单配置:', customizer); + console.log('表单初始数据:', 'DefaultValue = ', defaultValue.current, 'FieldsValue = ', fieldsValue); return () => { form.resetFields(); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [customizer]); - const handleValuesChange = (_: any, allValues: any) => { - // console.log('blockProps????????表单回显', allValues); + const handleValuesChange = useCallback((_: any, allValues: any) => { + console.log('表单更新', allValues); onChange && onChange(allValues); - }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); - // useEffect(() => { - // if (value && !isEqual(form.getFieldsValue(), value)) { - // form.setFieldsValue({ ...defaultValue, ...value }); - // } - // }, [value]); + useEffect(() => { + if (value && !isEqual(form.getFieldsValue(), value)) { + form.setFieldsValue({ ...defaultValue.current, ...value }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [value]); return (
diff --git a/src/reducers/index.ts b/src/reducers/index.ts index b43ff88..99a1536 100644 --- a/src/reducers/index.ts +++ b/src/reducers/index.ts @@ -45,7 +45,6 @@ export const defaultValue = (mode: AsanyProviderMode, plugins: EditorPlugin[]): }; export default (state: IAsanyState, action: AsanyAction) => { - console.log('debug', action); if (action.type === ProjectActionType.ChangeCase) { const project = action.payload; let newState = reducers(state, action); diff --git a/src/reducers/plugin.reducer.ts b/src/reducers/plugin.reducer.ts index 49c9f38..f04951e 100644 --- a/src/reducers/plugin.reducer.ts +++ b/src/reducers/plugin.reducer.ts @@ -9,7 +9,6 @@ export default function reducer( action: AsanyAction ): IPluginState { if (GlobalAsanyAction.Init === action.type) { - console.log('GlobalAsanyAction', '--->', action); return { ...state, ...defaultState }; } return state; diff --git a/src/reducers/ui.reducer/aside.reducer.ts b/src/reducers/ui.reducer/aside.reducer.ts index 990abfc..971f037 100644 --- a/src/reducers/ui.reducer/aside.reducer.ts +++ b/src/reducers/ui.reducer/aside.reducer.ts @@ -3,7 +3,6 @@ import type { AsanyAction, IUIAsideState } from '../../typings'; const defaultState: IUIAsideState = { visible: false, - tabs: [], }; export default function reducer( diff --git a/src/style/asany-editor.less b/src/style/asany-editor.less index 4a646a0..2adfce8 100644 --- a/src/style/asany-editor.less +++ b/src/style/asany-editor.less @@ -109,12 +109,6 @@ ul, h1, p { opacity: 0; } } - - .handle { - z-index: 10; - width: 3px; - height: 100%; - } } .sidebar-panel { display: flex; diff --git a/src/typings.ts b/src/typings.ts index cefa006..5b35606 100644 --- a/src/typings.ts +++ b/src/typings.ts @@ -1,5 +1,7 @@ import { CSSProperties, ComponentType, ReactElement } from 'react'; +import { ICustomizer } from 'sunmao'; + import { DispatchWithoutAction, IAsanyStoreContext } from './AsanyContext'; import { Selector } from './hooks/useSelector'; import MoveableData from './utils/MoveableData'; @@ -370,13 +372,19 @@ export interface SidebarHelper { export interface PanelOptions { top?: number | 'auto'; width?: number; - value?: void; - watchValue?: (callback: (value: any) => void) => () => void; - update?: (value: any) => void; } +export type SunmaoCustomizer = { + id?: string; + customizer: ICustomizer; + value?: any; + watchValue?: (callback: (value: any) => void) => () => void; + update: (value: any) => void; +}; + export interface AsideHelper { state: IUIAsideState; + open(data: SunmaoCustomizer, options?: PanelOptions): void; open(tabs: AsideTabPane[], options?: PanelOptions): void; open(title: string, body: ComponentType, options?: PanelOptions): void; next(title: string, body: ComponentType): void; @@ -426,7 +434,7 @@ export interface IAsanyEditor { dispatch: DispatchWithoutAction; } -type AsanyProjectType = 'component'; +type AsanyProjectType = string; interface AsanyProject { id: string; @@ -594,7 +602,8 @@ export interface IUIState { export interface IUIAsideState { control?: React.RefObject; - tabs: AsideTabPane[]; + tabs?: AsideTabPane[]; + block?: SunmaoCustomizer; options?: PanelOptions; visible: boolean; } diff --git a/stories/Properties.stories.tsx b/stories/Properties.stories.tsx index 917a1a7..d59ccb6 100644 --- a/stories/Properties.stories.tsx +++ b/stories/Properties.stories.tsx @@ -1,12 +1,15 @@ -import React from 'react'; +import React, { useCallback, useEffect } from 'react'; import { Meta, Story } from '@storybook/react'; import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; -import AsanyEditor from '../src'; +import AsanyEditor, { useEditor, buildAside, libraries } from '../src'; +import Sunmao, { ICustomizer, SunmaoProvider, useSunmao } from 'sunmao'; import DemoPlugin from './editors/demo'; import 'antd/dist/antd.css'; +import { useMemo } from '@storybook/addons'; +import { cloneDeepWith } from 'lodash-es'; const meta: Meta = { title: '编辑器/属性面板', @@ -17,26 +20,77 @@ const meta: Meta = { export default meta; +const plugin = cloneDeepWith(DemoPlugin); + +const customizer: ICustomizer = { + fields: [ + { + name: 'title', + type: 'String', + }, + ], +}; +const custom1 = { ...customizer }; +const custom2 = { ...customizer }; + +plugin.scena.workspace = function () { + const editor = useEditor(); + const sunmao = useSunmao(); + + const hanndleOpen1 = useCallback((e: React.MouseEvent) => { + e.stopPropagation(); + const tabs = buildAside(custom1); + editor.aside.open({ + customizer: custom1, + value: { title: '面板1' }, + update: () => {}, + }); + }, []); + const hanndleOpen2 = useCallback((e: React.MouseEvent) => { + e.stopPropagation(); + editor.aside.open({ + customizer: custom2, + value: { title: '面板2' }, + update: () => {}, + }); + // const tabs = buildAside(custom2); + // editor.aside.open(tabs, { + // value: { title: '面板2' }, + // }); + }, []); + return ( +
+ 面板1 +
+ 面板2 +
+ ); +}; + const Template: Story = (_args) => { + const sunmao = useMemo(() => new Sunmao(), []); + + useEffect(() => { + sunmao.addLibrary(...libraries); + }, []); + return ( - console.log(data)} - project={{ - id: 'test', - name: ( -
- 项目名称展示区域 -
- ) as any, - type: 'demo', - data: { - id: '111', - props: [], - }, - }} - /> + + console.log(data)} + project={{ + id: 'test', + name: (
项目名称展示区域
) as any, + type: 'demo', + data: { + id: '111', + props: [], + }, + }} + /> +
); }; diff --git a/stories/Sidebar.stories.tsx b/stories/Sidebar.stories.tsx index 3a1f5da..fbd173c 100644 --- a/stories/Sidebar.stories.tsx +++ b/stories/Sidebar.stories.tsx @@ -27,7 +27,7 @@ const Template: Story = (_args) => { project={{ id: 'test', name: (
项目名称展示区域
) as any, - type: 'demo', + type: 'component', data: { id: '111', props: [], diff --git a/stories/editors/demo/index.tsx b/stories/editors/demo/index.tsx index f24c174..c7251ff 100644 --- a/stories/editors/demo/index.tsx +++ b/stories/editors/demo/index.tsx @@ -1,10 +1,7 @@ import React from 'react'; -import { useSelector } from '../../../src/hooks'; import { EditorPlugin } from '../../../src/typings'; -import reducer, { SketchActionType } from './reducer'; - -// import BlockLayers from '../../../sketch/components/BlockLayers'; +import reducer from './reducer'; export default { id: 'demo', @@ -47,9 +44,7 @@ export default { }} > 侧边面板 - - 右侧边缘可以调整面板宽度 - + 右侧边缘可以调整面板宽度
); @@ -112,9 +107,7 @@ export default { >
工作区 -
- 点击工作区,可以唤出属性配置面板 -
+
点击工作区,可以唤出属性配置面板
); @@ -123,15 +116,13 @@ export default { tools: [ { id: 'left', - name: ( -
二级菜单栏
- ), + name:
二级菜单栏
, mutex: 'left', style: { flex: 1, display: 'flex', justifyContent: 'center' }, }, ], }, - onClick: (editor) => { + /* onClick: (editor) => { editor.aside.open( '属性面板', () => { @@ -155,7 +146,7 @@ export default { width: 380, } ); - }, + }, */ }, features: [], } as EditorPlugin; diff --git a/test/blah.test.tsx b/test/blah.test.tsx index f3a70a2..fa11c1e 100644 --- a/test/blah.test.tsx +++ b/test/blah.test.tsx @@ -1,12 +1,13 @@ import React from 'react'; import * as ReactDOM from 'react-dom'; -// import { Default as Thing } from '../stories/Layout.stories'; + +import { Default as Layout } from '../stories/Layout.stories'; describe('Thing', () => { it('renders without crashing', () => { const div = document.createElement('div'); - ReactDOM.render(
, div); + ReactDOM.render(, div); ReactDOM.unmountComponentAtNode(div); }); }); diff --git a/test/globals-test.ts b/test/globals-test.ts new file mode 100644 index 0000000..c48a92a --- /dev/null +++ b/test/globals-test.ts @@ -0,0 +1,6 @@ +import Dexie from 'dexie'; + +Dexie.dependencies.indexedDB = require('fake-indexeddb'); +Dexie.dependencies.IDBKeyRange = require('fake-indexeddb/lib/FDBKeyRange'); + +require('moveable-helper').__esModule = true; diff --git a/yarn.lock b/yarn.lock index b360f5a..9fb24e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3850,6 +3850,11 @@ balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" +base64-arraybuffer-es6@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/base64-arraybuffer-es6/-/base64-arraybuffer-es6-0.7.0.tgz#dbe1e6c87b1bf1ca2875904461a7de40f21abc86" + integrity sha512-ESyU/U1CFZDJUdr+neHRhNozeCv72Y7Vm0m1DCbjX3KBjT6eYocvAJlSk6+8+HkVwXlT1FNxhGW6q3UKAlCvvw== + base64-js@^1.0.2: version "1.5.1" resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" @@ -4852,6 +4857,11 @@ core-js@^1.0.0: version "1.2.7" resolved "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" +core-js@^2.5.3: + version "2.6.12" + resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== + core-js@^3.0.1, core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: version "3.16.3" resolved "https://registry.npmjs.org/core-js/-/core-js-3.16.3.tgz#1f2d43c51a9ed014cc6c83440af14697ae4b75f2" @@ -6254,6 +6264,14 @@ extsprintf@^1.2.0: version "1.4.0" resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" +fake-indexeddb@^3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/fake-indexeddb/-/fake-indexeddb-3.1.3.tgz#76d59146a6b994b9bb50ac9949cbd96ad6cca760" + integrity sha512-kpWYPIUGmxW8Q7xG7ampGL63fU/kYNukrIyy9KFj3+KVlFbE/SmvWebzWXBiCMeR0cPK6ufDoGC7MFkPhPLH9w== + dependencies: + realistic-structured-clone "^2.0.1" + setimmediate "^1.0.5" + fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" @@ -7017,6 +7035,11 @@ hard-rejection@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" +harmony-reflect@^1.4.6: + version "1.6.2" + resolved "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz#31ecbd32e648a34d030d86adb67d4d47547fe710" + integrity sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g== + has-bigints@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" @@ -7362,6 +7385,13 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" +identity-obj-proxy@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz#94d2bda96084453ef36fbc5aaec37e0f79f1fc14" + integrity sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ= + dependencies: + harmony-reflect "^1.4.6" + ieee754@^1.1.4: version "1.2.1" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -8744,7 +8774,7 @@ lodash.uniq@4.5.0, lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5: +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5, lodash@^4.7.0: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -11625,6 +11655,16 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +realistic-structured-clone@^2.0.1: + version "2.0.3" + resolved "https://registry.npmjs.org/realistic-structured-clone/-/realistic-structured-clone-2.0.3.tgz#8a252a87db8278d92267ad7a168c4f43fa485795" + integrity sha512-XYTwWZi5+lU4Wf+rnsQ7pukN9hF2cbJJf/yruBr1w23WhGflM6WoTBkdMVAun+oHFW2mV7UquyYo5oOI7YLJrQ== + dependencies: + core-js "^2.5.3" + domexception "^1.0.1" + typeson "^6.1.0" + typeson-registry "^1.0.0-alpha.20" + realpath-native@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz#7377ac429b6e1fd599dc38d08ed942d0d7beb866" @@ -12916,9 +12956,10 @@ stylis@^4.0.6: version "4.0.10" resolved "https://registry.npmjs.org/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240" -sunmao@^0.2.4: - version "0.2.4" - resolved "https://registry.npmjs.org/sunmao/-/sunmao-0.2.4.tgz#d5b13a2257aab63a4ed8e2b91a7566da606b6973" +sunmao@^0.2.5: + version "0.2.5" + resolved "https://registry.npmjs.org/sunmao/-/sunmao-0.2.5.tgz#75657ecb6e2fb2fd37c64e0c64569b835586d8ae" + integrity sha512-mxuiQ3uNS2x/lwjZ649IQevSy/DLAP31dbuzL91Bghfap9/EfnHMK7naV+W1Xvp7qsFCwMBhPiexkEVPcS97Og== dependencies: lodash-es "^4.17.21" reflect-metadata "^0.1.13" @@ -13305,6 +13346,13 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== + dependencies: + punycode "^2.1.1" + trim-newlines@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" @@ -13527,6 +13575,20 @@ typescript@^4.3.5: version "4.3.5" resolved "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" +typeson-registry@^1.0.0-alpha.20: + version "1.0.0-alpha.39" + resolved "https://registry.npmjs.org/typeson-registry/-/typeson-registry-1.0.0-alpha.39.tgz#9e0f5aabd5eebfcffd65a796487541196f4b1211" + integrity sha512-NeGDEquhw+yfwNhguLPcZ9Oj0fzbADiX4R0WxvoY8nGhy98IbzQy1sezjoEFWOywOboj/DWehI+/aUlRVrJnnw== + dependencies: + base64-arraybuffer-es6 "^0.7.0" + typeson "^6.0.0" + whatwg-url "^8.4.0" + +typeson@^6.0.0, typeson@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/typeson/-/typeson-6.1.0.tgz#5b2a53705a5f58ff4d6f82f965917cabd0d7448b" + integrity sha512-6FTtyGr8ldU0pfbvW/eOZrEtEkczHRUtduBnA90Jh9kMPCiFNnXIon3vF41N0S4tV1HHQt4Hk1j4srpESziCaA== + ua-parser-js@^0.7.18: version "0.7.28" resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz#8ba04e653f35ce210239c64661685bf9121dec31" @@ -13921,6 +13983,11 @@ webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + webpack-bundle-analyzer@^4.4.2: version "4.4.2" resolved "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.4.2.tgz#39898cf6200178240910d629705f0f3493f7d666" @@ -14028,6 +14095,15 @@ whatwg-url@^7.0.0: tr46 "^1.0.1" webidl-conversions "^4.0.2" +whatwg-url@^8.4.0: + version "8.7.0" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== + dependencies: + lodash "^4.7.0" + tr46 "^2.1.0" + webidl-conversions "^6.1.0" + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"