diff --git a/.eslintrc.js b/.eslintrc.js index f0692e11..3f20b668 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -45,6 +45,7 @@ module.exports = { }, globals: { isDev: true, + isTest: true, }, overrides: [ { diff --git a/.gitignore b/.gitignore index 070f36c2..7fa547da 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ build/ .vscode package-lock.json libs/**/dist +scripts/*.ejs diff --git a/CHANGELOG.md b/CHANGELOG.md index fb1f788c..e747500e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.0.10 (2022-07-14) +- **core**: #24 修复lazy包裹memo时,卸载错误 +- **core**: #21 修复异步更新时路径错误 + +## 0.0.9 (2022-07-12) +### Bug Fixes +- **horizonX**: 修复对store进行deepClone时循环克隆 + ## 0.0.8 (2022-07-08) ### Features - 增加HorizonX提供状态管理能力 diff --git a/babel.config.js b/babel.config.js index 37c7ac9e..8e19cfcb 100644 --- a/babel.config.js +++ b/babel.config.js @@ -6,7 +6,6 @@ module.exports = { ], plugins: [ ['@babel/plugin-proposal-class-properties', { loose: true }], - 'syntax-trailing-function-commas', [ '@babel/plugin-proposal-object-rest-spread', { loose: true, useBuiltIns: true }, @@ -34,6 +33,5 @@ module.exports = { pragma: 'Horizon.createElement', pragmaFrag: 'Horizon.Fragment' }], - '@babel/plugin-transform-flow-strip-types', ], }; diff --git a/jest.config.js b/jest.config.js index 665708c9..941aafa9 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,183 +1,18 @@ -// For a detailed explanation regarding each configuration property, visit: -// https://jestjs.io/docs/en/configuration.html - module.exports = { - // All imported modules in your tests should be mocked automatically - // automock: false, - - // Stop running tests after `n` failures - // bail: 0, - - // Respect "browser" field in package.json when resolving modules - // browser: false, - - // The directory where Jest should store its cached dependency information - // cacheDirectory: "", - - // Automatically clear mock calls and instances between every test - // clearMocks: false, - - // Indicates whether the coverage information should be collected while executing the test - // collectCoverage: false, - - // An array of glob patterns indicating a set of files for which coverage information should be collected - // collectCoverageFrom: undefined, - - // The directory where Jest should output its coverage files coverageDirectory: 'coverage', - - // An array of regexp pattern strings used to skip coverage collection - // coveragePathIgnorePatterns: [ - // "\\\\node_modules\\\\" - // ], - - // A list of reporter names that Jest uses when writing coverage reports - // coverageReporters: [ - // "json", - // "text", - // "lcov", - // "clover" - // ], - - // An object that configures minimum threshold enforcement for coverage results - // coverageThreshold: undefined, - - // A path to a custom dependency extractor - // dependencyExtractor: undefined, - - // Make calling deprecated APIs throw helpful error messages - // errorOnDeprecated: false, - - // Force coverage collection from ignored files using an array of glob patterns - // forceCoverageMatch: [], - - // A path to a module which exports an async function that is triggered once before all test suites - // globalSetup: undefined, - - // A path to a module which exports an async function that is triggered once after all test suites - // globalTeardown: undefined, - - // A set of global variables that need to be available in all test environments - // globals: {}, - - // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. - // maxWorkers: "50%", - - // An array of directory names to be searched recursively up from the requiring module's location - // moduleDirectories: [ - // "node_modules" - // ], - - // An array of file extensions your modules use - // moduleFileExtensions: [ - // 'js', - // 'ts' - // ], - - // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module - // moduleNameMapper: {}, - - // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader - // modulePathIgnorePatterns: [], - - // Activates notifications for test results - // notify: false, - - // An enum that specifies notification mode. Requires { notify: true } - // notifyMode: "failure-change", - - // A preset that is used as a base for Jest's configuration - // preset: undefined, - - // Run tests from one or more projects - // projects: undefined, - - // Use this configuration option to add custom reporters to Jest - // reporters: undefined, - - // Automatically reset mock state between every test - // resetMocks: false, - - // Reset the module registry before running each individual test resetModules: true, - // A path to a custom resolver - // resolver: undefined, - - // Automatically restore mock state between every test - // restoreMocks: false, - - // The root directory that Jest should scan for tests and modules within rootDir: process.cwd(), - // A list of paths to directories that Jest should use to search for files in - // roots: [ - // '/scripts' - // ], - - // Allows you to use a custom runner instead of Jest's default test runner - // runner: "jest-runner", - - // The paths to modules that run some code to configure or set up the testing environment before each test setupFiles: [require.resolve('./scripts/__tests__/jest/jestEnvironment.js')], - // A list of paths to modules that run some code to configure or set up the testing framework before each test setupFilesAfterEnv: [require.resolve('./scripts/__tests__/jest/jestSetting.js')], - // A list of paths to snapshot serializer modules Jest should use for snapshot testing - // snapshotSerializers: [], - - // The test environment that will be used for testing testEnvironment: 'jest-environment-jsdom-sixteen', - // Options that will be passed to the testEnvironment - // testEnvironmentOptions: {}, - - // Adds a location field to test results - // testLocationInResults: false, - - // The glob patterns Jest uses to detect test files testMatch: [ '/scripts/__tests__/**/*.test.js' ], - // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped - // testPathIgnorePatterns: [ - // "\\\\node_modules\\\\" - // ], - - // The regexp pattern or array of patterns that Jest uses to detect test files - //testRegex: ['/scripts/jest/dont-run-jest-directly\\.js$'], - - // This option allows the use of a custom results processor - // testResultsProcessor: undefined, - - // This option allows use of a custom test runner - // testRunner: "jasmine2", - - // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href - // testURL: "http://localhost", - - // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" timers: 'fake', - - // A map from regular expressions to paths to transformers - // transform: undefined, - - // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation - // transformIgnorePatterns: [ - // "\\\\node_modules\\\\" - // ], - - // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them - // unmockedModulePathPatterns: undefined, - - // Indicates whether each individual test should be reported during the run - // verbose: undefined, - - // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode - // watchPathIgnorePatterns: [], - - // Whether to use watchman for file crawling - // watchman: true, }; diff --git a/libs/horizon-jsx-transform-babel-plugin/package.json b/libs/horizon-jsx-transform-babel-plugin/package.json index bb9cb5f3..8a095acd 100644 --- a/libs/horizon-jsx-transform-babel-plugin/package.json +++ b/libs/horizon-jsx-transform-babel-plugin/package.json @@ -29,6 +29,7 @@ "@babel/plugin-syntax-import-meta": "^7.2.0", "@babel/plugin-syntax-jsx": "^7.2.0", "@babel/plugin-transform-modules-commonjs": "^7.2.0", + "@babel/traverse": "^7.11.0", "@babel/preset-env": "^7.16.11", "@babel/types": "^7.0.0", "babel-plugin-tester": "^10.1.0" diff --git a/libs/horizon/global.d.ts b/libs/horizon/global.d.ts index 0ebd7135..a3777f70 100644 --- a/libs/horizon/global.d.ts +++ b/libs/horizon/global.d.ts @@ -2,4 +2,5 @@ 区分是否开发者模式 */ declare var isDev: boolean; +declare var isTest: boolean; declare const __VERSION__: string; diff --git a/libs/horizon/package.json b/libs/horizon/package.json index 844a4ee5..6890c2cc 100644 --- a/libs/horizon/package.json +++ b/libs/horizon/package.json @@ -4,7 +4,7 @@ "keywords": [ "horizon" ], - "version": "0.0.8", + "version": "0.0.10", "homepage": "", "bugs": "", "main": "index.js", diff --git a/libs/horizon/src/horizonx/Constants.ts b/libs/horizon/src/horizonx/Constants.ts index 5967d853..334f0ef6 100644 --- a/libs/horizon/src/horizonx/Constants.ts +++ b/libs/horizon/src/horizonx/Constants.ts @@ -1,3 +1,5 @@ // The two constants must be the same as those in horizon. export const FunctionComponent = 'FunctionComponent'; export const ClassComponent = 'ClassComponent'; + +export const OBSERVER_KEY = Symbol('_horizonObserver'); diff --git a/libs/horizon/src/horizonx/proxy/HooklessObserver.ts b/libs/horizon/src/horizonx/proxy/HooklessObserver.ts index 9ea8937f..10fce509 100644 --- a/libs/horizon/src/horizonx/proxy/HooklessObserver.ts +++ b/libs/horizon/src/horizonx/proxy/HooklessObserver.ts @@ -10,7 +10,7 @@ export class HooklessObserver implements IObserver { listeners:(() => void)[] = []; - useProp(key: string): void { + useProp(key: string | symbol): void { } addListener(listener: () => void) { @@ -21,7 +21,7 @@ export class HooklessObserver implements IObserver { this.listeners = this.listeners.filter(item => item != listener); } - setProp(key: string): void { + setProp(key: string | symbol): void { this.triggerChangeListeners(); } diff --git a/libs/horizon/src/horizonx/proxy/Observer.ts b/libs/horizon/src/horizonx/proxy/Observer.ts index be24d1c2..1324c87a 100644 --- a/libs/horizon/src/horizonx/proxy/Observer.ts +++ b/libs/horizon/src/horizonx/proxy/Observer.ts @@ -16,7 +16,7 @@ export class Observer implements IObserver { listeners:(()=>void)[] = []; - useProp(key: string): void { + useProp(key: string | symbol): void { const processingVNode = getProcessingVNode(); if (processingVNode === null || !processingVNode.observers) { return; @@ -50,7 +50,7 @@ export class Observer implements IObserver { this.listeners = this.listeners.filter(item => item != listener); } - setProp(key: string): void { + setProp(key: string | symbol): void { const vNodes = this.keyVNodes.get(key); vNodes?.forEach((vNode: VNode) => { if (vNode.isStoreChange) { @@ -85,7 +85,7 @@ export class Observer implements IObserver { } } - clearByVNode(vNode: Vnode): void { + clearByVNode(vNode: VNode): void { const keys = this.vNodeKeys.get(vNode); if (keys) { keys.forEach((key: any) => { diff --git a/libs/horizon/src/horizonx/proxy/ProxyHandler.ts b/libs/horizon/src/horizonx/proxy/ProxyHandler.ts index f2051b9d..a540e199 100644 --- a/libs/horizon/src/horizonx/proxy/ProxyHandler.ts +++ b/libs/horizon/src/horizonx/proxy/ProxyHandler.ts @@ -1,12 +1,11 @@ -import {createObjectProxy} from './handlers/ObjectProxyHandler'; -import {Observer} from './Observer'; -import {HooklessObserver} from './HooklessObserver'; -import {isArray, isCollection, isObject} from '../CommonUtils'; -import {createArrayProxy} from './handlers/ArrayProxyHandler'; -import {createCollectionProxy} from './handlers/CollectionProxyHandler'; +import { createObjectProxy } from './handlers/ObjectProxyHandler'; +import { Observer } from './Observer'; +import { HooklessObserver } from './HooklessObserver'; +import { isArray, isCollection, isObject } from '../CommonUtils'; +import { createArrayProxy } from './handlers/ArrayProxyHandler'; +import { createCollectionProxy } from './handlers/CollectionProxyHandler'; import { IObserver } from '../types'; - -const OBSERVER_KEY = Symbol('_horizonObserver'); +import { OBSERVER_KEY } from '../Constants'; const proxyMap = new WeakMap(); @@ -29,7 +28,7 @@ export function createProxy(rawObj: any, hookObserver = true): any { } // 创建Observer - let observer:IObserver = getObserver(rawObj); + let observer: IObserver = getObserver(rawObj); if (!observer) { observer = hookObserver ? new Observer() : new HooklessObserver(); rawObj[OBSERVER_KEY] = observer; @@ -59,4 +58,3 @@ export function createProxy(rawObj: any, hookObserver = true): any { export function getObserver(rawObj: any): Observer { return rawObj[OBSERVER_KEY]; } - diff --git a/libs/horizon/src/horizonx/proxy/handlers/ArrayProxyHandler.ts b/libs/horizon/src/horizonx/proxy/handlers/ArrayProxyHandler.ts index 879dc088..a6812bde 100644 --- a/libs/horizon/src/horizonx/proxy/handlers/ArrayProxyHandler.ts +++ b/libs/horizon/src/horizonx/proxy/handlers/ArrayProxyHandler.ts @@ -26,14 +26,14 @@ function set(rawObj: any[], key: string, value: any, receiver: any) { const ret = Reflect.set(rawObj, key, newValue, receiver); const newLength = rawObj.length; - const tracker = getObserver(rawObj); + const observer = getObserver(rawObj); if (!isSame(newValue, oldValue)) { - tracker.setProp(key); + observer.setProp(key); } if (oldLength !== newLength) { - tracker.setProp('length'); + observer.setProp('length'); } return ret; diff --git a/libs/horizon/src/horizonx/proxy/handlers/CollectionProxyHandler.ts b/libs/horizon/src/horizonx/proxy/handlers/CollectionProxyHandler.ts index ec8214b3..bd044b44 100644 --- a/libs/horizon/src/horizonx/proxy/handlers/CollectionProxyHandler.ts +++ b/libs/horizon/src/horizonx/proxy/handlers/CollectionProxyHandler.ts @@ -40,8 +40,8 @@ function get(rawObj: { size: number }, key: any, receiver: any): any { } function getFun(rawObj: { get: (key: any) => any }, key: any) { - const tracker = getObserver(rawObj); - tracker.useProp(key); + const observer = getObserver(rawObj); + observer.useProp(key); const value = rawObj.get(key); // 对于value也需要进一步代理 @@ -60,14 +60,14 @@ function set( const newValue = value; rawObj.set(key, newValue); const valChange = !isSame(newValue, oldValue); - const tracker = getObserver(rawObj); + const observer = getObserver(rawObj); if (valChange || !rawObj.has(key)) { - tracker.setProp(COLLECTION_CHANGE); + observer.setProp(COLLECTION_CHANGE); } if (valChange) { - tracker.setProp(key); + observer.setProp(key); } return rawObj; @@ -78,17 +78,17 @@ function add(rawObj: { add: (any) => void; set: (string, any) => any; has: (any) if (!rawObj.has(value)) { rawObj.add(value); - const tracker = getObserver(rawObj); - tracker.setProp(value); - tracker.setProp(COLLECTION_CHANGE); + const observer = getObserver(rawObj); + observer.setProp(value); + observer.setProp(COLLECTION_CHANGE); } return rawObj; } function has(rawObj: { has: (string) => boolean }, key: any): boolean { - const tracker = getObserver(rawObj); - tracker.useProp(key); + const observer = getObserver(rawObj); + observer.useProp(key); return rawObj.has(key); } @@ -98,8 +98,8 @@ function clear(rawObj: { size: number; clear: () => void }) { rawObj.clear(); if (oldSize > 0) { - const tracker = getObserver(rawObj); - tracker.allChange(); + const observer = getObserver(rawObj); + observer.allChange(); } } @@ -107,9 +107,9 @@ function deleteFun(rawObj: { has: (key: any) => boolean; delete: (key: any) => v if (rawObj.has(key)) { rawObj.delete(key); - const tracker = getObserver(rawObj); - tracker.setProp(key); - tracker.setProp(COLLECTION_CHANGE); + const observer = getObserver(rawObj); + observer.setProp(key); + observer.setProp(COLLECTION_CHANGE); return true; } @@ -118,8 +118,8 @@ function deleteFun(rawObj: { has: (key: any) => boolean; delete: (key: any) => v } function size(rawObj: { size: number }) { - const tracker = getObserver(rawObj); - tracker.useProp(COLLECTION_CHANGE); + const observer = getObserver(rawObj); + observer.useProp(COLLECTION_CHANGE); return rawObj.size; } @@ -148,8 +148,8 @@ function forEach( rawObj: { forEach: (callback: (value: any, key: any) => void) => void }, callback: (valProxy: any, keyProxy: any, rawObj: any) => void ) { - const tracker = getObserver(rawObj); - tracker.useProp(COLLECTION_CHANGE); + const observer = getObserver(rawObj); + observer.useProp(COLLECTION_CHANGE); rawObj.forEach((value, key) => { const valProxy = createProxy(value, hookObserverMap.get(rawObj)); const keyProxy = createProxy(key, hookObserverMap.get(rawObj)); @@ -159,9 +159,9 @@ function forEach( } function wrapIterator(rawObj: Object, rawIt: { next: () => { value: any; done: boolean } }, isPair = false) { - const tracker = getObserver(rawObj); + const observer = getObserver(rawObj); const hookObserver = hookObserverMap.get(rawObj); - tracker.useProp(COLLECTION_CHANGE); + observer.useProp(COLLECTION_CHANGE); return { next() { @@ -170,7 +170,7 @@ function wrapIterator(rawObj: Object, rawIt: { next: () => { value: any; done: b return { value: createProxy(value, hookObserver), done }; } - tracker.useProp(COLLECTION_CHANGE); + observer.useProp(COLLECTION_CHANGE); let newVal; if (isPair) { diff --git a/libs/horizon/src/horizonx/proxy/handlers/ObjectProxyHandler.ts b/libs/horizon/src/horizonx/proxy/handlers/ObjectProxyHandler.ts index 709c68a9..28749a57 100644 --- a/libs/horizon/src/horizonx/proxy/handlers/ObjectProxyHandler.ts +++ b/libs/horizon/src/horizonx/proxy/handlers/ObjectProxyHandler.ts @@ -1,5 +1,6 @@ import { isSame } from '../../CommonUtils'; import { createProxy, getObserver, hookObserverMap } from '../ProxyHandler'; +import { OBSERVER_KEY } from '../../Constants'; export function createObjectProxy(rawObj: T): ProxyHandler { const proxy = new Proxy(rawObj, { @@ -10,7 +11,12 @@ export function createObjectProxy(rawObj: T): ProxyHandler return proxy; } -export function get(rawObj: object, key: string, receiver: any): any { +export function get(rawObj: object, key: string | symbol, receiver: any): any { + // The observer object of symbol ('_horizonObserver') cannot be accessed from Proxy to prevent errors caused by clonedeep. + if (key === OBSERVER_KEY) { + return undefined; + } + const observer = getObserver(rawObj); if (key === 'addListener') { @@ -25,10 +31,15 @@ export function get(rawObj: object, key: string, receiver: any): any { const value = Reflect.get(rawObj, key, receiver); - // 对于value也需要进一步代理 - const valProxy = createProxy(value, hookObserverMap.get(rawObj)); + // 对于prototype不做代理 + if (key !== 'prototype') { + // 对于value也需要进一步代理 + const valProxy = createProxy(value, hookObserverMap.get(rawObj)); - return valProxy; + return valProxy; + } + + return value; } export function set(rawObj: object, key: string, value: any, receiver: any): boolean { diff --git a/libs/horizon/src/horizonx/types.d.ts b/libs/horizon/src/horizonx/types.d.ts index 3fed3afe..9b54c139 100644 --- a/libs/horizon/src/horizonx/types.d.ts +++ b/libs/horizon/src/horizonx/types.d.ts @@ -1,23 +1,23 @@ export interface IObserver { - useProp: (key: string) => void; + useProp: (key: string | symbol) => void; addListener: (listener: () => void) => void; removeListener: (listener: () => void) => void; - setProp: (key: string) => void; + setProp: (key: string | symbol) => void; triggerChangeListeners: () => void; triggerUpdate: (vNode: any) => void; allChange: () => void; - + clearByVNode: (vNode: any) => void; } -type RemoveFirstFromTuple = +type RemoveFirstFromTuple = T['length'] extends 0 ? [] : (((...b: T) => void) extends (a, ...b: infer I) => void ? I : []) @@ -36,7 +36,7 @@ type ComputedValues> = { [K in type PostponedAction = (state: object, ...args: any[]) => Promise; type PostponedActions = { [key:string]: PostponedAction } -export type StoreHandler,C extends UserComputedValues> = +export type StoreHandler,C extends UserComputedValues> = {$subscribe: ((listener: () => void) => void), $unsubscribe: ((listener: () => void) => void), $state: S, @@ -78,4 +78,4 @@ type ReduxMiddleware = (store:ReduxStoreHandler, extraArgument?:any) => (action:( ReduxAction| ((dispatch:(action:ReduxAction)=>void,store:ReduxStoreHandler,extraArgument?:any)=>any) - )) => ReduxStoreHandler \ No newline at end of file + )) => ReduxStoreHandler diff --git a/libs/horizon/src/renderer/ErrorHandler.ts b/libs/horizon/src/renderer/ErrorHandler.ts index 8eaed4f8..1f629d97 100644 --- a/libs/horizon/src/renderer/ErrorHandler.ts +++ b/libs/horizon/src/renderer/ErrorHandler.ts @@ -15,7 +15,7 @@ import {updateShouldUpdateOfTree} from './vnode/VNodeShouldUpdate'; import {BuildErrored, setBuildResult} from './GlobalVar'; function consoleError(error: any): void { - if (isDev) { + if (isTest) { // 只打印message为了让测试用例能pass console['error']('The codes throw the error: ' + error.message); } else { diff --git a/libs/horizon/src/renderer/TreeBuilder.ts b/libs/horizon/src/renderer/TreeBuilder.ts index c8b81ae7..683c9bc3 100644 --- a/libs/horizon/src/renderer/TreeBuilder.ts +++ b/libs/horizon/src/renderer/TreeBuilder.ts @@ -199,6 +199,10 @@ export function calcStartUpdateVNode(treeRoot: VNode) { for (let i = 1; i < startNodePath.length; i++) { const pathIndex = Number(startNodePath[i]); node = getChildByIndex(node, pathIndex)!; + // 路径错误时,回退到从根更新 + if (node == null) { + return treeRoot; + } } return node; diff --git a/libs/horizon/src/renderer/render/LazyComponent.ts b/libs/horizon/src/renderer/render/LazyComponent.ts index 7f81ab2a..27feb0af 100644 --- a/libs/horizon/src/renderer/render/LazyComponent.ts +++ b/libs/horizon/src/renderer/render/LazyComponent.ts @@ -61,6 +61,7 @@ function captureLazyComponent( if (lazyRender) { if (lazyVNodeTag === MemoComponent) { // Memo要特殊处理 + processing.effectList = null; const memoVNodeProps = mergeDefaultProps(Component.type, lazyVNodeProps); // 需要整合defaultProps return lazyRender(processing, Component, memoVNodeProps, shouldUpdate); } else { diff --git a/package.json b/package.json index c31b27cf..ed675dbd 100644 --- a/package.json +++ b/package.json @@ -15,85 +15,49 @@ "watch-test": "yarn test --watch --dev" }, "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/code-frame": "^7.10.4", - "@babel/core": "^7.11.1", - "@babel/eslint-parser": "^7.11.4", - "@babel/helper-module-imports": "^7.10.4", - "@babel/parser": "^7.11.3", - "@babel/plugin-external-helpers": "^7.10.4", - "@babel/plugin-proposal-class-properties": "^7.14.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", - "@babel/plugin-proposal-object-rest-spread": "^7.11.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-jsx": "^7.10.4", - "@babel/plugin-transform-arrow-functions": "^7.10.4", - "@babel/plugin-transform-async-to-generator": "^7.10.4", - "@babel/plugin-transform-block-scoped-functions": "^7.10.4", - "@babel/plugin-transform-block-scoping": "^7.11.1", - "@babel/plugin-transform-classes": "^7.14.2", - "@babel/plugin-transform-computed-properties": "^7.10.4", - "@babel/plugin-transform-destructuring": "^7.10.4", - "@babel/plugin-transform-for-of": "^7.10.4", - "@babel/plugin-transform-literals": "^7.10.4", - "@babel/plugin-transform-modules-commonjs": "^7.10.4", - "@babel/plugin-transform-object-super": "^7.10.4", - "@babel/plugin-transform-parameters": "^7.10.5", - "@babel/plugin-transform-react-jsx-source": "^7.10.5", - "@babel/plugin-transform-runtime": "^7.14.5", - "@babel/plugin-transform-shorthand-properties": "^7.10.4", - "@babel/plugin-transform-spread": "^7.11.0", - "@babel/plugin-transform-template-literals": "^7.10.5", - "@babel/preset-env": "^7.16.11", - "@babel/preset-flow": "^7.10.4", - "@babel/preset-react": "^7.16.7", - "@babel/preset-typescript": "^7.16.7", - "@babel/register": "^7.14.5", - "@babel/traverse": "^7.11.0", - "@mattiasbuelens/web-streams-polyfill": "^0.3.2", + "@babel/core": "7.16.7", + "@babel/plugin-proposal-class-properties": "7.16.7", + "@babel/plugin-proposal-nullish-coalescing-operator": "7.16.7", + "@babel/plugin-proposal-object-rest-spread": "7.16.7", + "@babel/plugin-proposal-optional-chaining": "7.16.7", + "@babel/plugin-syntax-jsx": "7.16.7", + "@babel/plugin-transform-arrow-functions": "7.16.7", + "@babel/plugin-transform-block-scoped-functions": "7.16.7", + "@babel/plugin-transform-block-scoping": "7.16.7", + "@babel/plugin-transform-classes": "7.16.7", + "@babel/plugin-transform-computed-properties": "7.16.7", + "@babel/plugin-transform-destructuring": "7.16.7", + "@babel/plugin-transform-for-of": "7.16.7", + "@babel/plugin-transform-literals": "7.16.7", + "@babel/plugin-transform-object-super": "7.16.7", + "@babel/plugin-transform-parameters": "7.16.7", + "@babel/plugin-transform-runtime": "7.16.7", + "@babel/plugin-transform-shorthand-properties": "7.16.7", + "@babel/plugin-transform-spread": "7.16.7", + "@babel/plugin-transform-template-literals": "7.16.7", + "@babel/preset-env": "7.16.7", + "@babel/preset-react": "7.16.7", + "@babel/preset-typescript": "7.16.7", "@rollup/plugin-babel": "^5.3.1", "@rollup/plugin-node-resolve": "^13.3.0", "@rollup/plugin-replace": "^4.0.0", "@types/jest": "^26.0.24", "@types/node": "^17.0.18", - "@typescript-eslint/eslint-plugin": "^5.15.0", - "@typescript-eslint/parser": "^5.15.0", - "babel-core": "^6.26.3", - "babel-eslint": "^10.0.3", + "@typescript-eslint/eslint-plugin": "4.8.0", + "@typescript-eslint/parser": "4.8.0", "babel-jest": "^27.5.1", - "babel-plugin-syntax-trailing-function-commas": "^6.5.0", - "babel-preset-env": "^1.7.0", - "babel-preset-react": "^6.24.1", - "chalk": "^3.0.0", - "confusing-browser-globals": "^1.0.9", - "core-js": "^3.6.4", - "danger": "^9.2.10", - "ejs": "^3.1.6", - "error-stack-parser": "^2.0.6", - "eslint": "^7.32.0", + "eslint": "7.13.0", "eslint-config-prettier": "^6.9.0", - "eslint-plugin-babel": "^5.3.0", - "eslint-plugin-flowtype": "^2.25.0", "eslint-plugin-jest": "^22.15.0", "eslint-plugin-no-for-of-loops": "^1.0.0", "eslint-plugin-no-function-declare-after-return": "^1.0.0", - "eslint-plugin-react": "^6.7.1", + "eslint-plugin-react": "7.14.3", "jest": "^25.5.4", - "jest-cli": "^25.2.7", - "jest-diff": "^25.2.6", "jest-environment-jsdom-sixteen": "^1.0.3", - "jest-react": "^0.12.0", - "jest-snapshot-serializer-raw": "^1.1.0", - "minimist": "^1.2.3", - "object-assign": "^4.1.1", - "prettier": "1.19.1", - "react-lifecycles-compat": "^3.0.4", - "regenerator-runtime": "^0.13.9", - "rimraf": "^3.0.0", + "prettier": "2.6.2", "rollup": "^2.75.5", "rollup-plugin-terser": "^7.0.2", - "typescript": "^3.9.7" + "typescript": "4.2.3" }, "engines": { "node": ">=10.x", diff --git a/scripts/__tests__/ComponentTest/ForwardRef.test.js b/scripts/__tests__/ComponentTest/ForwardRef.test.js new file mode 100644 index 00000000..993d800a --- /dev/null +++ b/scripts/__tests__/ComponentTest/ForwardRef.test.js @@ -0,0 +1,45 @@ +import * as Horizon from '@cloudsop/horizon/index.ts'; +import { getLogUtils } from '../jest/testUtils'; + +describe('ForwardRef', () => { + const LogUtils = getLogUtils(); + it('ForwardRef包裹的函数组件应该正常触发effect', () => { + function App(props, ref) { + Horizon.useEffect(() => { + LogUtils.log('effect'); + return () => { + LogUtils.log('effect remove'); + }; + }); + return ; + } + + const Wrapper = Horizon.forwardRef(App); + + Horizon.act(() => { + Horizon.render(, container); + }); + expect(LogUtils.getAndClear()).toEqual(['effect']); + Horizon.act(() => { + Horizon.render(, container); + }); + expect(LogUtils.getAndClear()).toEqual(['effect remove', 'effect']); + }); + + it('memo组件包裹的类组件', () => { + class Component extends Horizon.Component { + render() { + return ; + } + } + + const Wrapper = Horizon.memo(Component); + + Horizon.act(() => { + Horizon.render(, container); + }); + Horizon.act(() => { + Horizon.render(, container); + }); + }); +}); diff --git a/scripts/__tests__/ComponentTest/LazyComponent.test.js b/scripts/__tests__/ComponentTest/LazyComponent.test.js index 704dca45..b59c7805 100755 --- a/scripts/__tests__/ComponentTest/LazyComponent.test.js +++ b/scripts/__tests__/ComponentTest/LazyComponent.test.js @@ -184,4 +184,30 @@ describe('LazyComponent Test', () => { container.querySelector('button').click(); expect(container.textContent).toBe('Error: num is 2'); }); + + it('#24 配合memo', async () => { + const fnComp = () => { + return

horizon

; + }; + const LazyApp = Horizon.lazy(() => ({ + then(cb) { + cb({ default: Horizon.memo(() => fnComp, false) }); + }, + })); + expect(() => { + Horizon.render( + Loading...}> + + , + container + ); + + Horizon.render( + Loading...}> + + , + container + ); + }).not.toThrow(); + }); }); diff --git a/scripts/__tests__/EventTest/EventMain.test.js b/scripts/__tests__/EventTest/EventMain.test.js index 2b3868ba..7f719e1d 100644 --- a/scripts/__tests__/EventTest/EventMain.test.js +++ b/scripts/__tests__/EventTest/EventMain.test.js @@ -10,14 +10,6 @@ function dispatchChangeEvent(input) { describe('事件', () => { const LogUtils = TestUtils.getLogUtils(); - it('根节点挂载全量事件', () => { - const App = () => { - return
; - }; - Horizon.render(, container); - console.log(TestUtils.getEventListeners(container)); - //expect(TestUtils.getEventListeners(container)).toBe(true); - }); it('事件捕获与冒泡', () => { const App = () => { diff --git a/scripts/__tests__/HorizonXText/StoreFunctionality/cloneDeep.test.js b/scripts/__tests__/HorizonXText/StoreFunctionality/cloneDeep.test.js new file mode 100644 index 00000000..9f0dd806 --- /dev/null +++ b/scripts/__tests__/HorizonXText/StoreFunctionality/cloneDeep.test.js @@ -0,0 +1,106 @@ +import * as Horizon from '@cloudsop/horizon/index.ts'; +import { clearStore, createStore, useStore } from '../../../../libs/horizon/src/horizonx/store/StoreHandler'; +import { OBSERVER_KEY } from '../../../../libs/horizon/src/horizonx/Constants'; +import { App, Text, triggerClickEvent } from '../../jest/commonComponents'; + +describe('测试对store.state对象进行深度克隆', () => { + const { unmountComponentAtNode } = Horizon; + let container = null; + beforeEach(() => { + // 创建一个 DOM 元素作为渲染目标 + container = document.createElement('div'); + document.body.appendChild(container); + + createStore({ + id: 'user', + state: { + type: 'bing dun dun', + persons: [ + { name: 'p1', age: 1 }, + { name: 'p2', age: 2 }, + ], + }, + actions: { + addOnePerson: (state, person) => { + state.persons.push(person); + }, + delOnePerson: state => { + state.persons.pop(); + }, + clearPersons: state => { + state.persons = null; + }, + }, + }); + }); + + afterEach(() => { + // 退出时进行清理 + unmountComponentAtNode(container); + container.remove(); + container = null; + + clearStore('user'); + }); + + const newPerson = { name: 'p3', age: 3 }; + + function Parent({ children }) { + const userStore = useStore('user'); + const addOnePerson = function() { + userStore.addOnePerson(newPerson); + }; + const delOnePerson = function() { + userStore.delOnePerson(); + }; + return ( +
+ + +
{children}
+
+ ); + } + + it('The observer object of symbol (\'_horizonObserver\') cannot be accessed to from Proxy', () => { + let userStore = null; + function Child(props) { + userStore = useStore('user'); + + return ( +
+ +
+ ); + } + + Horizon.render(, container); + + // The observer object of symbol ('_horizonObserver') cannot be accessed to from Proxy prevent errors caused by clonedeep. + expect(userStore.persons[0][OBSERVER_KEY]).toBe(undefined); + }); + + it('The observer object of symbol (\'_horizonObserver\') cannot be accessed to from Proxy', () => { + let userStore = null; + function Child(props) { + userStore = useStore('user'); + + return ( +
+ +
+ ); + } + + Horizon.render(, container); + + // NO throw this Exception, TypeError: 'get' on proxy: property 'prototype' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value + const proxyObj = userStore.persons[0].constructor; + expect(proxyObj.prototype !== undefined).toBeTruthy(); + }); + +}); diff --git a/scripts/__tests__/HorizonXText/adapters/ReduxAdapter.test.js b/scripts/__tests__/HorizonXText/adapters/ReduxAdapter.test.js index 2fa93598..3683a596 100644 --- a/scripts/__tests__/HorizonXText/adapters/ReduxAdapter.test.js +++ b/scripts/__tests__/HorizonXText/adapters/ReduxAdapter.test.js @@ -2,7 +2,7 @@ import { createStore, applyMiddleware, combineReducers, - bindActionCreators + bindActionCreators, } from '../../../../libs/horizon/src/horizonx/adapters/redux'; describe('Redux adapter', () => { @@ -12,21 +12,21 @@ describe('Redux adapter', () => { }, 0); expect(reduxStore.getState()).toBe(0); - }) + }); it('Should use default state, dispatch action and update state', async () => { const reduxStore = createStore((state, action) => { switch (action.type) { - case('ADD'): - return {counter: state.counter + 1} + case 'ADD': + return { counter: state.counter + 1 }; default: - return {counter: 0}; + return { counter: 0 }; } }); expect(reduxStore.getState().counter).toBe(0); - reduxStore.dispatch({type: 'ADD'}); + reduxStore.dispatch({ type: 'ADD' }); expect(reduxStore.getState().counter).toBe(1); }); @@ -35,37 +35,37 @@ describe('Redux adapter', () => { let counter = 0; const reduxStore = createStore((state = 0, action) => { switch (action.type) { - case('ADD'): - return state + 1 + case 'ADD': + return state + 1; default: return state; } }); - reduxStore.dispatch({type: 'ADD'}); + reduxStore.dispatch({ type: 'ADD' }); expect(counter).toBe(0); expect(reduxStore.getState()).toBe(1); const unsubscribe = reduxStore.subscribe(() => { counter++; }); - reduxStore.dispatch({type: 'ADD'}); - reduxStore.dispatch({type: 'ADD'}); + reduxStore.dispatch({ type: 'ADD' }); + reduxStore.dispatch({ type: 'ADD' }); expect(counter).toBe(2); expect(reduxStore.getState()).toBe(3); unsubscribe(); - reduxStore.dispatch({type: 'ADD'}); - reduxStore.dispatch({type: 'ADD'}); + reduxStore.dispatch({ type: 'ADD' }); + reduxStore.dispatch({ type: 'ADD' }); expect(counter).toBe(2); expect(reduxStore.getState()).toBe(5); }); it('Should bind action creators', async () => { - const addTodo = (text) => { + const addTodo = text => { return { type: 'ADD_TODO', - text - } - } + text, + }; + }; const reduxStore = createStore((state = [], action) => { if (action.type === 'ADD_TODO') { @@ -74,7 +74,7 @@ describe('Redux adapter', () => { return state; }); - const actions = bindActionCreators({addTodo}, reduxStore.dispatch); + const actions = bindActionCreators({ addTodo }, reduxStore.dispatch); actions.addTodo('todo'); @@ -84,57 +84,57 @@ describe('Redux adapter', () => { it('Should replace reducer', async () => { const reduxStore = createStore((state, action) => { switch (action.type) { - case('ADD'): - return {counter: state.counter + 1} + case 'ADD': + return { counter: state.counter + 1 }; default: - return {counter: 0}; + return { counter: 0 }; } }); - reduxStore.dispatch({type: 'ADD'}); + reduxStore.dispatch({ type: 'ADD' }); expect(reduxStore.getState().counter).toBe(1); reduxStore.replaceReducer((state, action) => { switch (action.type) { - case('SUB'): - return {counter: state.counter - 1} + case 'SUB': + return { counter: state.counter - 1 }; default: - return {counter: 0}; + return { counter: 0 }; } }); - reduxStore.dispatch({type: 'SUB'}); + reduxStore.dispatch({ type: 'SUB' }); expect(reduxStore.getState().counter).toBe(0); - }) + }); it('Should combine reducers', async () => { const booleanReducer = (state = false, action) => { switch (action.type) { - case('TOGGLE'): - return !state - default: - return state; - } - } - - const addReducer = (state = 0, action) => { - switch (action.type) { - case('ADD'): - return state + 1 + case 'TOGGLE': + return !state; default: return state; } }; - const reduxStore = createStore(combineReducers({check: booleanReducer, counter: addReducer})); + const addReducer = (state = 0, action) => { + switch (action.type) { + case 'ADD': + return state + 1; + default: + return state; + } + }; + + const reduxStore = createStore(combineReducers({ check: booleanReducer, counter: addReducer })); expect(reduxStore.getState().counter).toBe(0); expect(reduxStore.getState().check).toBe(false); - reduxStore.dispatch({type: 'ADD'}); - reduxStore.dispatch({type: 'TOGGLE'}); + reduxStore.dispatch({ type: 'ADD' }); + reduxStore.dispatch({ type: 'TOGGLE' }); expect(reduxStore.getState().counter).toBe(1); expect(reduxStore.getState().check).toBe(true); @@ -149,21 +149,25 @@ describe('Redux adapter', () => { counter++; let result = next(action); return result; - } + }; - const reduxStore = createStore((state, action) => { - switch (action.type) { - case('toggle'): - return { - check: !state.check - } - default: - return state; - } - }, {check: false}, applyMiddleware(callCounter)); + const reduxStore = createStore( + (state, action) => { + switch (action.type) { + case 'toggle': + return { + check: !state.check, + }; + default: + return state; + } + }, + { check: false }, + applyMiddleware(callCounter) + ); - reduxStore.dispatch({type: 'toggle'}); - reduxStore.dispatch({type: 'toggle'}); + reduxStore.dispatch({ type: 'toggle' }); + reduxStore.dispatch({ type: 'toggle' }); expect(counter).toBe(3); // NOTE: first action is always store initialization }); @@ -178,31 +182,35 @@ describe('Redux adapter', () => { counter++; let result = next(action); return result; - } + }; const lastFunctionStorage = store => next => action => { middlewareCallList.push('lastFunctionStorage'); lastAction = action.type; let result = next(action); return result; - } + }; - const reduxStore = createStore((state, action) => { - switch (action.type) { - case('toggle'): - return { - check: !state.check - } - default: - return state; - } - }, {check: false}, applyMiddleware(callCounter, lastFunctionStorage)); + const reduxStore = createStore( + (state, action) => { + switch (action.type) { + case 'toggle': + return { + check: !state.check, + }; + default: + return state; + } + }, + { check: false }, + applyMiddleware(callCounter, lastFunctionStorage) + ); - reduxStore.dispatch({type: 'toggle'}); + reduxStore.dispatch({ type: 'toggle' }); expect(counter).toBe(2); // NOTE: first action is always store initialization expect(lastAction).toBe('toggle'); - expect(middlewareCallList[0]).toBe("callCounter"); - expect(middlewareCallList[1]).toBe("lastFunctionStorage"); + expect(middlewareCallList[0]).toBe('callCounter'); + expect(middlewareCallList[1]).toBe('lastFunctionStorage'); }); }); diff --git a/scripts/__tests__/jest/jestSetting.js b/scripts/__tests__/jest/jestSetting.js index 2111a635..2b2f91e7 100644 --- a/scripts/__tests__/jest/jestSetting.js +++ b/scripts/__tests__/jest/jestSetting.js @@ -1,10 +1,9 @@ import { unmountComponentAtNode } from '../../../libs/horizon/src/dom/DOMExternal'; import { getLogUtils } from './testUtils'; -//import failOnConsole from 'jest-fail-on-console'; -//failOnConsole(); const LogUtils = getLogUtils(); global.isDev = process.env.NODE_ENV === 'development'; +global.isTest = true; global.container = null; global.beforeEach(() => { LogUtils.clear(); diff --git a/scripts/__tests__/jest/testUtils.js b/scripts/__tests__/jest/testUtils.js index 65cea65e..485702b7 100755 --- a/scripts/__tests__/jest/testUtils.js +++ b/scripts/__tests__/jest/testUtils.js @@ -1,68 +1,9 @@ -import { allDelegatedNativeEvents } from '@cloudsop/horizon/src/event/EventHub'; -//import * as LogUtils from './logUtils'; - export const stopBubbleOrCapture = (e, value) => { const LogUtils = getLogUtils(); LogUtils.log(value); e.stopPropagation(); }; -function listAllEventListeners() { - const allElements = Array.prototype.slice.call(document.querySelectorAll('*')); - allElements.push(document); - allElements.push(window); - - const types = []; - - for (let ev in window) { - if (/^on/.test(ev)) types[types.length] = ev; - } - - let elements = []; - for (let i = 0; i < allElements.length; i++) { - const currentElement = allElements[i]; - for (let j = 0; j < types.length; j++) { - if (typeof currentElement[types[j]] === 'function') { - elements.push({ - 'node': currentElement, - 'type': types[j], - 'func': currentElement[types[j]].toString(), - }); - } - } - } - - return elements.sort(function(a,b) { - return a.type.localeCompare(b.type); - }); -} - -export const getEventListeners = (dom) => { - console.table(listAllEventListeners()); - - - - // let ret = true; - // let keyArray = []; - // for (let key in dom) { - // if (/^on/.test(key)) keyArray.push(key); - // } - // console.log(getEventListeners); - // console.log('---------------------------------'); - // console.log(allDelegatedNativeEvents); - // try { - // allDelegatedNativeEvents.forEach(event => { - // if (!keyArray.includes(event)) { - // ret = false; - // throw new Error('没有挂载全量事件'); - // } - // }); - // } catch (error) { - // console.log(error); - // } - // return ret; -}; - export function triggerClickEvent(container, id) { const event = new MouseEvent('click', { bubbles: true, diff --git a/scripts/gen3rdLib.js b/scripts/gen3rdLib.js index f2953691..26a55887 100644 --- a/scripts/gen3rdLib.js +++ b/scripts/gen3rdLib.js @@ -10,6 +10,11 @@ const argv = require('minimist')(process.argv.slice(2)); const libPathPrefix = '../build'; const suffix = argv.dev ? 'development.js' : 'production.js'; const template = argv.type === 'horizon' ? 'horizon3rdTemplate.ejs' : 'template.ejs'; +const templatePath = path.resolve(__dirname, `./${template}`); +if (!fs.existsSync(templatePath)) { + console.log(chalk.yellow('Failed: Template file not exist')); + return; +} const readLib = lib => { const libName = lib.split('.')[0]; const libPath = path.resolve(__dirname, `${libPathPrefix}/${libName}/umd/${lib}`); diff --git a/scripts/horizon3rdTemplate.ejs b/scripts/horizon3rdTemplate.ejs deleted file mode 100644 index 889a6283..00000000 --- a/scripts/horizon3rdTemplate.ejs +++ /dev/null @@ -1,17568 +0,0 @@ -!function(t, r) { -"object" == typeof exports && "object" == typeof module ? module.exports = r() : "function" == typeof define && define.amd ? define([], r) : "object" == typeof exports ? exports.ie = r() : t.ie = r() -}(window, (function() { -return function(t) { -var r = {}; -function e(n) { -if (r[n]) -return r[n].exports; -var o = r[n] = { -i: n, -l: !1, -exports: {} -}; -return t[n].call(o.exports, o, o.exports, e), -o.l = !0, -o.exports -} -return e.m = t, -e.c = r, -e.d = function(t, r, n) { -e.o(t, r) || Object.defineProperty(t, r, { -enumerable: !0, -get: n -}) -} -, -e.r = function(t) { -"undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, { -value: "Module" -}), -Object.defineProperty(t, "__esModule", { -value: !0 -}) -} -, -e.t = function(t, r) { -if (1 & r && (t = e(t)), -8 & r) -return t; -if (4 & r && "object" == typeof t && t && t.__esModule) -return t; -var n = Object.create(null); -if (e.r(n), -Object.defineProperty(n, "default", { -enumerable: !0, -value: t -}), -2 & r && "string" != typeof t) -for (var o in t) -e.d(n, o, function(r) { -return t[r] -} -.bind(null, o)); -return n -} -, -e.n = function(t) { -var r = t && t.__esModule ? function() { -return t.default -} -: function() { -return t -} -; -return e.d(r, "a", r), -r -} -, -e.o = function(t, r) { -return Object.prototype.hasOwnProperty.call(t, r) -} -, -e.p = "", -e(e.s = 192) -}([function(t, r, e) { -var n = e(1) -, o = e(23).f -, i = e(25) -, a = e(17) -, u = e(114) -, c = e(90) -, s = e(73); -t.exports = function(t, r) { -var e, f, l, h, p, v = t.target, g = t.global, d = t.stat; -if (e = g ? n : d ? n[v] || u(v, {}) : (n[v] || {}).prototype) -for (f in r) { -if (h = r[f], -l = t.noTargetGet ? (p = o(e, f)) && p.value : e[f], -!s(g ? f : v + (d ? "." : "#") + f, t.forced) && void 0 !== l) { -if (typeof h == typeof l) -continue; -c(h, l) -} -(t.sham || l && l.sham) && i(h, "sham", !0), -a(e, f, h, t) -} -} -} -, function(t, r, e) { -(function(r) { -var e = function(t) { -return t && t.Math == Math && t -}; -t.exports = e("object" == typeof globalThis && globalThis) || e("object" == typeof window && window) || e("object" == typeof self && self) || e("object" == typeof r && r) || function() { -return this -}() || Function("return this")() -} -).call(this, e(195)) -} -, function(t, r) { -t.exports = function(t) { -try { -return !!t() -} catch (t) { -return !0 -} -} -} -, function(t, r, e) { -var n = e(68) -, o = Function.prototype -, i = o.bind -, a = o.call -, u = n && i.bind(a, a); -t.exports = n ? function(t) { -return t && u(t) -} -: function(t) { -return t && function() { -return a.apply(t, arguments) -} -} -} -, function(t, r, e) { -var n = e(1) -, o = e(6) -, i = n.String -, a = n.TypeError; -t.exports = function(t) { -if (o(t)) -return t; -throw a(i(t) + " is not an object") -} -} -, function(t, r, e) { -var n = e(2); -t.exports = !n((function() { -return 7 != Object.defineProperty({}, 1, { -get: function() { -return 7 -} -})[1] -} -)) -} -, function(t, r, e) { -var n = e(9); -t.exports = function(t) { -return "object" == typeof t ? null !== t : n(t) -} -} -, function(t, r, e) { -var n = e(1) -, o = e(86) -, i = e(12) -, a = e(60) -, u = e(112) -, c = e(142) -, s = o("wks") -, f = n.Symbol -, l = f && f.for -, h = c ? f : f && f.withoutSetter || a; -t.exports = function(t) { -if (!i(s, t) || !u && "string" != typeof s[t]) { -var r = "Symbol." + t; -u && i(f, t) ? s[t] = f[t] : s[t] = c && l ? l(r) : h(r) -} -return s[t] -} -} -, function(t, r, e) { -var n = e(1) -, o = e(52) -, i = n.String; -t.exports = function(t) { -if ("Symbol" === o(t)) -throw TypeError("Cannot convert a Symbol value to a string"); -return i(t) -} -} -, function(t, r) { -t.exports = function(t) { -return "function" == typeof t -} -} -, function(t, r, e) { -"use strict"; -var n, o, i, a = e(128), u = e(5), c = e(1), s = e(9), f = e(6), l = e(12), h = e(52), p = e(70), v = e(25), g = e(17), d = e(13).f, y = e(29), m = e(37), b = e(39), x = e(7), w = e(60), E = c.Int8Array, S = E && E.prototype, A = c.Uint8ClampedArray, O = A && A.prototype, R = E && m(E), T = S && m(S), I = Object.prototype, M = c.TypeError, j = x("toStringTag"), P = w("TYPED_ARRAY_TAG"), k = w("TYPED_ARRAY_CONSTRUCTOR"), _ = a && !!b && "Opera" !== h(c.opera), L = !1, N = { -Int8Array: 1, -Uint8Array: 1, -Uint8ClampedArray: 1, -Int16Array: 2, -Uint16Array: 2, -Int32Array: 4, -Uint32Array: 4, -Float32Array: 4, -Float64Array: 8 -}, D = { -BigInt64Array: 8, -BigUint64Array: 8 -}, U = function(t) { -if (!f(t)) -return !1; -var r = h(t); -return l(N, r) || l(D, r) -}; -for (n in N) -(i = (o = c[n]) && o.prototype) ? v(i, k, o) : _ = !1; -for (n in D) -(i = (o = c[n]) && o.prototype) && v(i, k, o); -if ((!_ || !s(R) || R === Function.prototype) && (R = function() { -throw M("Incorrect invocation") -} -, -_)) -for (n in N) -c[n] && b(c[n], R); -if ((!_ || !T || T === I) && (T = R.prototype, -_)) -for (n in N) -c[n] && b(c[n].prototype, T); -if (_ && m(O) !== T && b(O, T), -u && !l(T, j)) -for (n in L = !0, -d(T, j, { -get: function() { -return f(this) ? this[P] : void 0 -} -}), -N) -c[n] && v(c[n], P, n); -t.exports = { -NATIVE_ARRAY_BUFFER_VIEWS: _, -TYPED_ARRAY_CONSTRUCTOR: k, -TYPED_ARRAY_TAG: L && P, -aTypedArray: function(t) { -if (U(t)) -return t; -throw M("Target is not a typed array") -}, -aTypedArrayConstructor: function(t) { -if (s(t) && (!b || y(R, t))) -return t; -throw M(p(t) + " is not a typed array constructor") -}, -exportTypedArrayMethod: function(t, r, e, n) { -if (u) { -if (e) -for (var o in N) { -var i = c[o]; -if (i && l(i.prototype, t)) -try { -delete i.prototype[t] -} catch (e) { -try { -i.prototype[t] = r -} catch (t) {} -} -} -T[t] && !e || g(T, t, e ? r : _ && S[t] || r, n) -} -}, -exportTypedArrayStaticMethod: function(t, r, e) { -var n, o; -if (u) { -if (b) { -if (e) -for (n in N) -if ((o = c[n]) && l(o, t)) -try { -delete o[t] -} catch (t) {} -if (R[t] && !e) -return; -try { -return g(R, t, e ? r : _ && R[t] || r) -} catch (t) {} -} -for (n in N) -!(o = c[n]) || o[t] && !e || g(o, t, r) -} -}, -isView: function(t) { -if (!f(t)) -return !1; -var r = h(t); -return "DataView" === r || l(N, r) || l(D, r) -}, -isTypedArray: U, -TypedArray: R, -TypedArrayPrototype: T -} -} -, function(t, r, e) { -var n = e(68) -, o = Function.prototype.call; -t.exports = n ? o.bind(o) : function() { -return o.apply(o, arguments) -} -} -, function(t, r, e) { -var n = e(3) -, o = e(14) -, i = n({}.hasOwnProperty); -t.exports = Object.hasOwn || function(t, r) { -return i(o(t), r) -} -} -, function(t, r, e) { -var n = e(1) -, o = e(5) -, i = e(144) -, a = e(145) -, u = e(4) -, c = e(49) -, s = n.TypeError -, f = Object.defineProperty -, l = Object.getOwnPropertyDescriptor; -r.f = o ? a ? function(t, r, e) { -if (u(t), -r = c(r), -u(e), -"function" == typeof t && "prototype" === r && "value"in e && "writable"in e && !e.writable) { -var n = l(t, r); -n && n.writable && (t[r] = e.value, -e = { -configurable: "configurable"in e ? e.configurable : n.configurable, -enumerable: "enumerable"in e ? e.enumerable : n.enumerable, -writable: !1 -}) -} -return f(t, r, e) -} -: f : function(t, r, e) { -if (u(t), -r = c(r), -u(e), -i) -try { -return f(t, r, e) -} catch (t) {} -if ("get"in e || "set"in e) -throw s("Accessors not supported"); -return "value"in e && (t[r] = e.value), -t -} -} -, function(t, r, e) { -var n = e(1) -, o = e(18) -, i = n.Object; -t.exports = function(t) { -return i(o(t)) -} -} -, function(t, r, e) { -var n = e(30); -t.exports = function(t) { -return n(t.length) -} -} -, function(t, r, e) { -var n = e(1) -, o = e(9) -, i = function(t) { -return o(t) ? t : void 0 -}; -t.exports = function(t, r) { -return arguments.length < 2 ? i(n[t]) : n[t] && n[t][r] -} -} -, function(t, r, e) { -var n = e(1) -, o = e(9) -, i = e(12) -, a = e(25) -, u = e(114) -, c = e(88) -, s = e(19) -, f = e(61).CONFIGURABLE -, l = s.get -, h = s.enforce -, p = String(String).split("String"); -(t.exports = function(t, r, e, c) { -var s, l = !!c && !!c.unsafe, v = !!c && !!c.enumerable, g = !!c && !!c.noTargetGet, d = c && void 0 !== c.name ? c.name : r; -o(e) && ("Symbol(" === String(d).slice(0, 7) && (d = "[" + String(d).replace(/^Symbol\(([^)]*)\)/, "$1") + "]"), -(!i(e, "name") || f && e.name !== d) && a(e, "name", d), -(s = h(e)).source || (s.source = p.join("string" == typeof d ? d : ""))), -t !== n ? (l ? !g && t[r] && (v = !0) : delete t[r], -v ? t[r] = e : a(t, r, e)) : v ? t[r] = e : u(r, e) -} -)(Function.prototype, "toString", (function() { -return o(this) && l(this).source || c(this) -} -)) -} -, function(t, r, e) { -var n = e(1).TypeError; -t.exports = function(t) { -if (null == t) -throw n("Can't call method on " + t); -return t -} -} -, function(t, r, e) { -var n, o, i, a = e(146), u = e(1), c = e(3), s = e(6), f = e(25), l = e(12), h = e(113), p = e(89), v = e(71), g = u.TypeError, d = u.WeakMap; -if (a || h.state) { -var y = h.state || (h.state = new d) -, m = c(y.get) -, b = c(y.has) -, x = c(y.set); -n = function(t, r) { -if (b(y, t)) -throw new g("Object already initialized"); -return r.facade = t, -x(y, t, r), -r -} -, -o = function(t) { -return m(y, t) || {} -} -, -i = function(t) { -return b(y, t) -} -} else { -var w = p("state"); -v[w] = !0, -n = function(t, r) { -if (l(t, w)) -throw new g("Object already initialized"); -return r.facade = t, -f(t, w, r), -r -} -, -o = function(t) { -return l(t, w) ? t[w] : {} -} -, -i = function(t) { -return l(t, w) -} -} -t.exports = { -set: n, -get: o, -has: i, -enforce: function(t) { -return i(t) ? o(t) : n(t, {}) -}, -getterFor: function(t) { -return function(r) { -var e; -if (!s(r) || (e = o(r)).type !== t) -throw g("Incompatible receiver, " + t + " required"); -return e -} -} -} -} -, function(t, r) { -var e = Math.ceil -, n = Math.floor; -t.exports = function(t) { -var r = +t; -return r != r || 0 === r ? 0 : (r > 0 ? n : e)(r) -} -} -, function(t, r) { -t.exports = !1 -} -, function(t, r, e) { -var n = e(38) -, o = e(3) -, i = e(69) -, a = e(14) -, u = e(15) -, c = e(77) -, s = o([].push) -, f = function(t) { -var r = 1 == t -, e = 2 == t -, o = 3 == t -, f = 4 == t -, l = 6 == t -, h = 7 == t -, p = 5 == t || l; -return function(v, g, d, y) { -for (var m, b, x = a(v), w = i(x), E = n(g, d), S = u(w), A = 0, O = y || c, R = r ? O(v, S) : e || h ? O(v, 0) : void 0; S > A; A++) -if ((p || A in w) && (b = E(m = w[A], A, x), -t)) -if (r) -R[A] = b; -else if (b) -switch (t) { -case 3: -return !0; -case 5: -return m; -case 6: -return A; -case 2: -s(R, m) -} -else -switch (t) { -case 4: -return !1; -case 7: -s(R, m) -} -return l ? -1 : o || f ? f : R -} -}; -t.exports = { -forEach: f(0), -map: f(1), -filter: f(2), -some: f(3), -every: f(4), -find: f(5), -findIndex: f(6), -filterReject: f(7) -} -} -, function(t, r, e) { -var n = e(5) -, o = e(11) -, i = e(85) -, a = e(35) -, u = e(26) -, c = e(49) -, s = e(12) -, f = e(144) -, l = Object.getOwnPropertyDescriptor; -r.f = n ? l : function(t, r) { -if (t = u(t), -r = c(r), -f) -try { -return l(t, r) -} catch (t) {} -if (s(t, r)) -return a(!o(i.f, t, r), t[r]) -} -} -, function(t, r, e) { -var n = e(1) -, o = e(9) -, i = e(70) -, a = n.TypeError; -t.exports = function(t) { -if (o(t)) -return t; -throw a(i(t) + " is not a function") -} -} -, function(t, r, e) { -var n = e(5) -, o = e(13) -, i = e(35); -t.exports = n ? function(t, r, e) { -return o.f(t, r, i(1, e)) -} -: function(t, r, e) { -return t[r] = e, -t -} -} -, function(t, r, e) { -var n = e(69) -, o = e(18); -t.exports = function(t) { -return n(o(t)) -} -} -, function(t, r, e) { -var n = e(150) -, o = e(12) -, i = e(149) -, a = e(13).f; -t.exports = function(t) { -var r = n.Symbol || (n.Symbol = {}); -o(r, t) || a(r, t, { -value: i.f(t) -}) -} -} -, function(t, r, e) { -var n = e(3) -, o = n({}.toString) -, i = n("".slice); -t.exports = function(t) { -return i(o(t), 8, -1) -} -} -, function(t, r, e) { -var n = e(3); -t.exports = n({}.isPrototypeOf) -} -, function(t, r, e) { -var n = e(20) -, o = Math.min; -t.exports = function(t) { -return t > 0 ? o(n(t), 9007199254740991) : 0 -} -} -, function(t, r, e) { -var n = e(68) -, o = Function.prototype -, i = o.apply -, a = o.call; -t.exports = "object" == typeof Reflect && Reflect.apply || (n ? a.bind(i) : function() { -return a.apply(i, arguments) -} -) -} -, function(t, r, e) { -var n, o = e(4), i = e(74), a = e(116), u = e(71), c = e(148), s = e(87), f = e(89), l = f("IE_PROTO"), h = function() {}, p = function(t) { -return "