From 3189eba4b09ebc635d4233b492f4c95118b36d55 Mon Sep 17 00:00:00 2001 From: Benno Kohrs Date: Sat, 3 Jul 2021 14:57:09 +0200 Subject: [PATCH 1/4] setup benchmark project --- benchmark/.env | 1 + .../react/counter/bench/agilets.tsx | 16 + benchmark/benchmarks/react/counter/index.ts | 63 ++ benchmark/lodash.ts | 4 + benchmark/package.json | 52 ++ benchmark/public/index.html | 16 + benchmark/run.ts | 89 +++ benchmark/tsconfig.json | 22 + benchmark/yarn.lock | 586 ++++++++++++++++++ package.json | 4 +- 10 files changed, 851 insertions(+), 2 deletions(-) create mode 100644 benchmark/.env create mode 100644 benchmark/benchmarks/react/counter/bench/agilets.tsx create mode 100644 benchmark/benchmarks/react/counter/index.ts create mode 100644 benchmark/lodash.ts create mode 100644 benchmark/package.json create mode 100644 benchmark/public/index.html create mode 100644 benchmark/run.ts create mode 100644 benchmark/tsconfig.json create mode 100644 benchmark/yarn.lock diff --git a/benchmark/.env b/benchmark/.env new file mode 100644 index 00000000..21903adb --- /dev/null +++ b/benchmark/.env @@ -0,0 +1 @@ +MANUAL_BENCHMARK=false diff --git a/benchmark/benchmarks/react/counter/bench/agilets.tsx b/benchmark/benchmarks/react/counter/bench/agilets.tsx new file mode 100644 index 00000000..0761a07a --- /dev/null +++ b/benchmark/benchmarks/react/counter/bench/agilets.tsx @@ -0,0 +1,16 @@ +import { Agile, Logger } from '@agile-ts/core'; +import { useAgile } from '@agile-ts/react'; +import React from 'react'; +import ReactDom from 'react-dom'; + +const AgileApp = new Agile({ logConfig: { level: Logger.level.ERROR } }); +const COUNT = AgileApp.createState(0); + +const App = () => { + const count = useAgile(COUNT); + return

COUNT.set((state) => state + 1)}>{count}

; +}; + +export default function (target: HTMLElement) { + ReactDom.render(, target); +} diff --git a/benchmark/benchmarks/react/counter/index.ts b/benchmark/benchmarks/react/counter/index.ts new file mode 100644 index 00000000..987cc3d9 --- /dev/null +++ b/benchmark/benchmarks/react/counter/index.ts @@ -0,0 +1,63 @@ +import Benchmark, { Suite, Options } from 'benchmark'; +import ReactDOM from 'react-dom'; + +// Files to run the Benchmark on +import agilets from './bench/agilets'; + +// @ts-ignore +// Benchmark.js requires an instance of itself globally +window.Benchmark = Benchmark; + +// Create new Benchmark test suite +const suite = new Suite('Count'); + +// Retrieve the Element to render the Benchmark in +const target = document.getElementById('bench')!; + +// Increment Element +let increment: HTMLHeadingElement; + +function configTest(renderElement: (target: HTMLElement) => void): Options { + return { + fn() { + increment.click(); + }, + onStart() { + // Render Benchmark Component in the target Element + renderElement(target); + + // Retrieve Increment Element + increment = target.querySelector('h1')!; + }, + onComplete() { + // Set 'output' in the Benchmark + (this as any).output = parseInt(target.innerText, 10); + + // Unmount Component + ReactDOM.unmountComponentAtNode(target); + target.innerHTML = ''; + }, + }; +} + +// Add Tests to Benchmark Suite +suite + .add('AgileTs', configTest(agilets)) + + // Add Listener + .on('start', function (this: any) { + console.log(`Starting ${this.name}`); + }) + .on('cycle', (event: any) => { + console.log(String(event.target)); + }) + .on('complete', function (this: any) { + console.log(`Fastest is ${this.filter('fastest').map('name')}`); + + // @ts-ignore + // Notify server to end the Benchmark + window.TEST.ended = true; + }) + + // Run Benchmark Suite + .run({ async: true }); diff --git a/benchmark/lodash.ts b/benchmark/lodash.ts new file mode 100644 index 00000000..104b3b1f --- /dev/null +++ b/benchmark/lodash.ts @@ -0,0 +1,4 @@ +import _ from 'lodash'; + +// Benchmark.js requires lodash globally +window._ = _; diff --git a/benchmark/package.json b/benchmark/package.json new file mode 100644 index 00000000..02877ecc --- /dev/null +++ b/benchmark/package.json @@ -0,0 +1,52 @@ +{ + "name": "benchmark", + "version": "0.1.0", + "private": true, + "author": "BennoDev", + "license": "MIT", + "homepage": "https://agile-ts.org/", + "description": "Benchmark Tests", + "scripts": { + "test": "node -r esbuild-register run.ts", + "test:counter": "yarn test ./benchmarks/react/counter", + "test:fields": "yarn test ./benchmarks/react/fields", + "install:local:agile": "yalc add @agile-ts/core @agile-ts/react", + "install:public:agile": "yarn add @agile-ts/core @agile-ts/react" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/agile-ts/agile.git" + }, + "dependencies": { + "benchmark": "^2.1.4", + "colorette": "^1.2.2", + "dotenv": "^10.0.0", + "esbuild": "^0.12.14", + "esbuild-register": "^2.6.0", + "lodash": "^4.17.21", + "playwright": "^1.12.3", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "typescript": "^4.3.5" + }, + "devDependencies": { + "@agile-ts/core": "file:.yalc/@agile-ts/core", + "@agile-ts/react": "file:.yalc/@agile-ts/react", + "@reduxjs/toolkit": "^1.5.1", + "@types/benchmark": "^2.1.0", + "@types/node": "^16.0.0", + "@types/react": "^17.0.13", + "@types/react-dom": "^17.0.8", + "jotai": "^0.16.0", + "mobx": "^6.2.0", + "mobx-react": "^7.1.0", + "pullstate": "^1.22.1", + "react-redux": "^7.2.3", + "recoil": "^0.2.0", + "redux": "^4.0.5", + "valtio": "^1.0.3" + }, + "bugs": { + "url": "https://github.com/agile-ts/agile/issues" + } +} diff --git a/benchmark/public/index.html b/benchmark/public/index.html new file mode 100644 index 00000000..93fc27b9 --- /dev/null +++ b/benchmark/public/index.html @@ -0,0 +1,16 @@ + + + + + Benchmark + + + +
+ + + diff --git a/benchmark/run.ts b/benchmark/run.ts new file mode 100644 index 00000000..a43c6329 --- /dev/null +++ b/benchmark/run.ts @@ -0,0 +1,89 @@ +import dotenv from 'dotenv'; +import esbuild from 'esbuild'; +import playwright from 'playwright'; + +// Loads environment variables from the '.env' file +dotenv.config(); + +// https://nodejs.org/docs/latest/api/process.html#process_process_argv +// Extract entry from the executed command +// yarn run ./path/to/entry -> './path/to/entry' is extracted +const entry = process.argv.slice(2)[0]; +if (entry == null) { + throw new Error( + "No valid entry was provided! Valid entry example: 'yarn run ./benchmarks/react/counter'" + ); +} + +const startBenchmark = async () => { + // Bundle Benchmark Test and launch the server on which they are executed + const server = await esbuild.serve( + { + servedir: 'public', + port: 3000, + host: '127.0.0.1', // localhost + }, + { + inject: ['./lodash.ts'], // https://esbuild.github.io/api/#inject + entryPoints: [entry], // https://esbuild.github.io/api/#entry-points + outfile: './public/bundle.js', + target: 'es2015', + format: 'cjs', // https://esbuild.github.io/api/#format-commonjs + platform: 'browser', + minify: true, // https://esbuild.github.io/api/#minify + bundle: true, // https://esbuild.github.io/api/#bundle + sourcemap: 'external', // https://esbuild.github.io/api/#sourcemap// https://github.com/evanw/esbuild/issues/69 + } + ); + const serverUrl = `http://${server.host}:${server.port}`; + + console.log(`Server is running at port: ${server.port}`); + + // Launch Chrome as browser to run the benchmarks in + const browser = await playwright.chromium.launch(); + const context = await browser.newContext(); + const page = await context.newPage(); + + // Option to open and test the benchmarks in the browser manually + if (process.env.MANUAL_BENCHMARK === 'true') { + console.log( + `Open the Browser at '${serverUrl}' to run the tests manually.` + ); + + await server.wait; + } + + // Setup 'pageerror' listener to throw occurring errors in the local console + // https://playwright.dev/docs/api/class-page/#page-event-page-error + page.on('pageerror', (error) => { + throw error; + }); + + // Setup 'console' listener to transfer the browser logs into the local console + // https://playwright.dev/docs/api/class-page/#page-event-console + page.on('console', (...message) => { + console.log(...message); + }); + + // Open url the server is running on + await page.goto(serverUrl); + + // Wait for tests to be executed (indicator is when 'window.TESTS.ended' is set to true) + // https://playwright.dev/docs/api/class-frame#frame-wait-for-function + await page.waitForFunction( + // @ts-ignore + () => window.TEST?.ended, + undefined, + { + timeout: 0, + polling: 100, + } + ); + + // Close Browser and stop server + await browser.close(); + server.stop(); +}; + +// Execute the Benchmark +startBenchmark(); diff --git a/benchmark/tsconfig.json b/benchmark/tsconfig.json new file mode 100644 index 00000000..b36827f2 --- /dev/null +++ b/benchmark/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react" + } +} diff --git a/benchmark/yarn.lock b/benchmark/yarn.lock new file mode 100644 index 00000000..a84f9339 --- /dev/null +++ b/benchmark/yarn.lock @@ -0,0 +1,586 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@agile-ts/core@file:.yalc/@agile-ts/core": + version "0.1.0" + dependencies: + "@agile-ts/logger" "^0.0.5" + "@agile-ts/utils" "^0.0.5" + +"@agile-ts/logger@^0.0.5": + version "0.0.5" + resolved "https://registry.yarnpkg.com/@agile-ts/logger/-/logger-0.0.5.tgz#bad39e1995a0c14e7f3f7c6e44c028f4d7a30f38" + integrity sha512-qBNUyPJGecOZOS9r8dyGF/VLBioEY5DYZn4Hoq+sEkpyvoi718c90i57B1M++I2MCCONVMGytG61Gs1sts73qw== + dependencies: + "@agile-ts/utils" "^0.0.5" + +"@agile-ts/react@file:.yalc/@agile-ts/react": + version "0.1.0" + +"@agile-ts/utils@^0.0.5": + version "0.0.5" + resolved "https://registry.yarnpkg.com/@agile-ts/utils/-/utils-0.0.5.tgz#23cc83e60eb6b15734247fac1d77f1fd629ffdb6" + integrity sha512-R86X9MjMty14eoQ4djulZSdHf9mIF9dPcj4g+SABqdA6AqbewS0/BQGNGR5p6gXhqc4+mT8rzkutywdPnMUNfA== + +"@babel/runtime@^7.12.1", "@babel/runtime@^7.9.2": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" + integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== + dependencies: + regenerator-runtime "^0.13.4" + +"@reduxjs/toolkit@^1.5.1": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.6.0.tgz#0a17c6941c57341f8b31e982352b495ab69d5add" + integrity sha512-eGL50G+Vj5AG5uD0lineb6rRtbs96M8+hxbcwkHpZ8LQcmt0Bm33WyBSnj5AweLkjQ7ZP+KFRDHiLMznljRQ3A== + dependencies: + immer "^9.0.1" + redux "^4.1.0" + redux-thunk "^2.3.0" + reselect "^4.0.0" + +"@types/benchmark@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/benchmark/-/benchmark-2.1.0.tgz#157e2ef22311d3140fb33e82a938a1beb26e78e0" + integrity sha512-wxT2/LZn4z0NvSfZirxmBx686CU7EXp299KHkIk79acXpQtgeYHrslFzDacPGXifC0Pe3CEaLup07bgY1PnuQw== + +"@types/hoist-non-react-statics@^3.3.0": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" + integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + +"@types/node@*", "@types/node@^16.0.0": + version "16.0.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.0.0.tgz#067a6c49dc7a5c2412a505628e26902ae967bf6f" + integrity sha512-TmCW5HoZ2o2/z2EYi109jLqIaPIi9y/lc2LmDCWzuCi35bcaQ+OtUh6nwBiFK7SOu25FAU5+YKdqFZUwtqGSdg== + +"@types/prop-types@*": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + +"@types/react-dom@^17.0.8": + version "17.0.8" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.8.tgz#3180de6d79bf53762001ad854e3ce49f36dd71fc" + integrity sha512-0ohAiJAx1DAUEcY9UopnfwCE9sSMDGnY/oXjWMax6g3RpzmTt2GMyMVAXcbn0mo8XAff0SbQJl2/SBU+hjSZ1A== + dependencies: + "@types/react" "*" + +"@types/react-redux@^7.1.16": + version "7.1.16" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.16.tgz#0fbd04c2500c12105494c83d4a3e45c084e3cb21" + integrity sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw== + dependencies: + "@types/hoist-non-react-statics" "^3.3.0" + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + redux "^4.0.0" + +"@types/react@*", "@types/react@^17.0.13": + version "17.0.13" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.13.tgz#6b7c9a8f2868586ad87d941c02337c6888fb874f" + integrity sha512-D/G3PiuqTfE3IMNjLn/DCp6umjVCSvtZTPdtAFy5+Ved6CsdRvivfKeCzw79W4AatShtU4nGqgvOv5Gro534vQ== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" + integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== + +"@types/yauzl@^2.9.1": + version "2.9.2" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.2.tgz#c48e5d56aff1444409e39fa164b0b4d4552a7b7a" + integrity sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA== + dependencies: + "@types/node" "*" + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +benchmark@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/benchmark/-/benchmark-2.1.4.tgz#09f3de31c916425d498cc2ee565a0ebf3c2a5629" + integrity sha1-CfPeMckWQl1JjMLuVloOvzwqVik= + dependencies: + lodash "^4.17.4" + platform "^1.3.3" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + +commander@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +csstype@^3.0.2: + version "3.0.8" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" + integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== + +debug@4, debug@^4.1.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + +dotenv@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" + integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +esbuild-register@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/esbuild-register/-/esbuild-register-2.6.0.tgz#9f19a54c82be751dd87673d6a66d7b9e1cdd8498" + integrity sha512-2u4AtnCXP5nivtIxZryiZOUcEQkOzFS7UhAqibUEmaTAThJ48gDLYTBF/Fsz+5r0hbV1jrFE6PQvPDUrKZNt/Q== + dependencies: + esbuild "^0.12.8" + jsonc-parser "^3.0.0" + +esbuild@^0.12.14, esbuild@^0.12.8: + version "0.12.14" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.14.tgz#43157dbd0b36d939247d4eb4909a4886ac40f82e" + integrity sha512-z8p+6FGiplR7a3pPonXREbm+8IeXjBGvDpVidZmGB/AJMsJSfGCU+n7KOMCazA9AwvagadRWBhiKorC0w9WJvw== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +extract-zip@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" + integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== + dependencies: + debug "^4.1.1" + get-stream "^5.1.0" + yauzl "^2.10.0" + optionalDependencies: + "@types/yauzl" "^2.9.1" + +fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= + dependencies: + pend "~1.2.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +glob@^7.1.3: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +graceful-fs@^4.2.4: + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== + +hamt_plus@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/hamt_plus/-/hamt_plus-1.0.2.tgz#e21c252968c7e33b20f6a1b094cd85787a265601" + integrity sha1-4hwlKWjH4zsg9qGwlM2FeHomVgE= + +hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +immer@^8.0.1: + version "8.0.4" + resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.4.tgz#3a21605a4e2dded852fb2afd208ad50969737b7a" + integrity sha512-jMfL18P+/6P6epANRvRk6q8t+3gGhqsJ9EuJ25AXE+9bNTYtssvzeYbEd0mXRYWCmmXSIbnlpz6vd6iJlmGGGQ== + +immer@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.3.tgz#146e2ba8b84d4b1b15378143c2345559915097f4" + integrity sha512-mONgeNSMuyjIe0lkQPa9YhdmTv8P19IeHV0biYhcXhbd5dhdB9HSK93zBpyKjp6wersSUgT5QyU0skmejUVP2A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +jotai@^0.16.0: + version "0.16.11" + resolved "https://registry.yarnpkg.com/jotai/-/jotai-0.16.11.tgz#efeaf0311513cf41d5c82b7009f8381d518cbc41" + integrity sha512-EPBeDSBc4FwbFRArRjcI6IsHrVkba771mSOFTN3M4r5rU3ZcZMDFLElZScZVr6w1kgrEXvaMm59VAyEB3QUEbA== + +jpeg-js@^0.4.2: + version "0.4.3" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.3.tgz#6158e09f1983ad773813704be80680550eff977b" + integrity sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q== + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +jsonc-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" + integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== + +lodash@^4.17.21, lodash@^4.17.4: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +mime@^2.4.6: + version "2.5.2" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" + integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +mobx-react-lite@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-3.2.0.tgz#331d7365a6b053378dfe9c087315b4e41c5df69f" + integrity sha512-q5+UHIqYCOpBoFm/PElDuOhbcatvTllgRp3M1s+Hp5j0Z6XNgDbgqxawJ0ZAUEyKM8X1zs70PCuhAIzX1f4Q/g== + +mobx-react@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-7.2.0.tgz#241e925e963bb83a31d269f65f9f379e37ecbaeb" + integrity sha512-KHUjZ3HBmZlNnPd1M82jcdVsQRDlfym38zJhZEs33VxyVQTvL77hODCArq6+C1P1k/6erEeo2R7rpE7ZeOL7dg== + dependencies: + mobx-react-lite "^3.2.0" + +mobx@^6.2.0: + version "6.3.2" + resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.3.2.tgz#125590961f702a572c139ab69392bea416d2e51b" + integrity sha512-xGPM9dIE1qkK9Nrhevp0gzpsmELKU4MFUJRORW/jqxVFIHHWIoQrjDjL8vkwoJYY3C2CeVJqgvl38hgKTalTWg== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +platform@^1.3.3: + version "1.3.6" + resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7" + integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg== + +playwright@^1.12.3: + version "1.12.3" + resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.12.3.tgz#113afa2cba10fb56e9a5b307377343e32a155a99" + integrity sha512-eyhHvZV7dMAUltqjQsgJ9CjZM8dznzN1+rcfCI6W6lfQ7IlPvTFGLuKOCcI4ETbjfbxqaS5FKIkb1WDDzq2Nww== + dependencies: + commander "^6.1.0" + debug "^4.1.1" + extract-zip "^2.0.1" + https-proxy-agent "^5.0.0" + jpeg-js "^0.4.2" + mime "^2.4.6" + pngjs "^5.0.0" + progress "^2.0.3" + proper-lockfile "^4.1.1" + proxy-from-env "^1.1.0" + rimraf "^3.0.2" + stack-utils "^2.0.3" + ws "^7.4.6" + yazl "^2.5.1" + +pngjs@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb" + integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw== + +progress@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +prop-types@^15.7.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + +proper-lockfile@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f" + integrity sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA== + dependencies: + graceful-fs "^4.2.4" + retry "^0.12.0" + signal-exit "^3.0.2" + +proxy-compare@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/proxy-compare/-/proxy-compare-2.0.0.tgz#36f41114a25fcf359037308d12529183a9dc182c" + integrity sha512-xhJF1+vPCnu93QYva3Weii5ho1AeX5dsR/P5O7pzy9QLxeOgMSQNC8zDo0bGg9vtn61Pu5Qn+5w/Y8OSU5k+8g== + +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +pullstate@^1.22.1: + version "1.22.1" + resolved "https://registry.yarnpkg.com/pullstate/-/pullstate-1.22.1.tgz#ffdde634e8c721907de8e6d37a85c6083137ee8a" + integrity sha512-Xu3umsGOG6qCQ4IWxKSEikQqdR7GDsTHQPE7wquzQENMRZbPeHURA9dZgH/9ktuhDh3D1qnIDI9PyPftabme0A== + dependencies: + fast-deep-equal "^3.1.3" + immer "^8.0.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +react-dom@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" + integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + scheduler "^0.20.2" + +react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-redux@^7.2.3: + version "7.2.4" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.4.tgz#1ebb474032b72d806de2e0519cd07761e222e225" + integrity sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA== + dependencies: + "@babel/runtime" "^7.12.1" + "@types/react-redux" "^7.1.16" + hoist-non-react-statics "^3.3.2" + loose-envify "^1.4.0" + prop-types "^15.7.2" + react-is "^16.13.1" + +react@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +recoil@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/recoil/-/recoil-0.2.0.tgz#69344b5bec3129272560d8d9d6001ada3ee4d80c" + integrity sha512-VOJfYVQ3VgmfS7L5tV9QdOR+AJhvll8yGr1+3nJPCqADulImuScGZ2sJtejPps3zfTu/o98y5kO4lje8Tx6XHw== + dependencies: + hamt_plus "1.0.2" + +redux-thunk@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" + integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== + +redux@^4.0.0, redux@^4.0.5, redux@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.0.tgz#eb049679f2f523c379f1aff345c8612f294c88d4" + integrity sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g== + dependencies: + "@babel/runtime" "^7.9.2" + +regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + +reselect@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7" + integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA== + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +scheduler@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +signal-exit@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +stack-utils@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" + integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== + dependencies: + escape-string-regexp "^2.0.0" + +typescript@^4.3.5: + version "4.3.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" + integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== + +valtio@^1.0.3: + version "1.0.6" + resolved "https://registry.yarnpkg.com/valtio/-/valtio-1.0.6.tgz#b316deea5537d254a141e2e5af1692d9eae2f60f" + integrity sha512-ylCis9IkcE7b92XjMb3ebdJgLvJEFJ2NjfuD01QNr98pVOhRa5WsW4LSykFgbO4W7ftrZtO8jN4svZL0XlD77w== + dependencies: + proxy-compare "2.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^7.4.6: + version "7.5.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.1.tgz#44fc000d87edb1d9c53e51fbc69a0ac1f6871d66" + integrity sha512-2c6faOUH/nhoQN6abwMloF7Iyl0ZS2E9HGtsiLrWn0zOOMWlhtDmdf/uihDt6jnuCxgtwGBNy6Onsoy2s2O2Ow== + +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +yazl@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35" + integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw== + dependencies: + buffer-crc32 "~0.2.3" diff --git a/package.json b/package.json index b4ed3355..2e7e2bce 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,5 @@ { + "name": "agile", "private": true, "author": "BennoDev", "license": "MIT", @@ -73,6 +74,5 @@ }, "workspaces": [ "packages/*" - ], - "name": "agile" + ] } From 8daec3a25bb313cebc88b289e534523ae3ce90ab Mon Sep 17 00:00:00 2001 From: Benno Kohrs Date: Sat, 3 Jul 2021 15:15:04 +0200 Subject: [PATCH 2/4] added some more state manager to tests --- .../react/counter/bench/agilets.tsx | 4 +- .../benchmarks/react/counter/bench/jotai.tsx | 14 +++++++ .../benchmarks/react/counter/bench/mobx.tsx | 19 +++++++++ .../benchmarks/react/counter/bench/recoil.tsx | 22 ++++++++++ .../react/counter/bench/redux-toolkit.tsx | 40 ++++++++++++++++++ .../benchmarks/react/counter/bench/redux.tsx | 41 +++++++++++++++++++ .../benchmarks/react/counter/bench/valtio.tsx | 14 +++++++ .../react/counter/bench/zustand.tsx | 19 +++++++++ benchmark/benchmarks/react/counter/index.ts | 15 +++++++ benchmark/package.json | 4 +- benchmark/yarn.lock | 23 +++-------- 11 files changed, 193 insertions(+), 22 deletions(-) create mode 100644 benchmark/benchmarks/react/counter/bench/jotai.tsx create mode 100644 benchmark/benchmarks/react/counter/bench/mobx.tsx create mode 100644 benchmark/benchmarks/react/counter/bench/recoil.tsx create mode 100644 benchmark/benchmarks/react/counter/bench/redux-toolkit.tsx create mode 100644 benchmark/benchmarks/react/counter/bench/redux.tsx create mode 100644 benchmark/benchmarks/react/counter/bench/valtio.tsx create mode 100644 benchmark/benchmarks/react/counter/bench/zustand.tsx diff --git a/benchmark/benchmarks/react/counter/bench/agilets.tsx b/benchmark/benchmarks/react/counter/bench/agilets.tsx index 0761a07a..300ff431 100644 --- a/benchmark/benchmarks/react/counter/bench/agilets.tsx +++ b/benchmark/benchmarks/react/counter/bench/agilets.tsx @@ -1,7 +1,7 @@ -import { Agile, Logger } from '@agile-ts/core'; -import { useAgile } from '@agile-ts/react'; import React from 'react'; import ReactDom from 'react-dom'; +import { Agile, Logger } from '@agile-ts/core'; +import { useAgile } from '@agile-ts/react'; const AgileApp = new Agile({ logConfig: { level: Logger.level.ERROR } }); const COUNT = AgileApp.createState(0); diff --git a/benchmark/benchmarks/react/counter/bench/jotai.tsx b/benchmark/benchmarks/react/counter/bench/jotai.tsx new file mode 100644 index 00000000..ca138586 --- /dev/null +++ b/benchmark/benchmarks/react/counter/bench/jotai.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import ReactDom from 'react-dom'; +import { atom, useAtom } from 'jotai'; + +const countAtom = atom(0); + +const App = () => { + const [count, setCount] = useAtom(countAtom); + return

setCount((state) => state + 1)}>{count}

; +}; + +export default function (target: HTMLElement) { + ReactDom.render(, target); +} diff --git a/benchmark/benchmarks/react/counter/bench/mobx.tsx b/benchmark/benchmarks/react/counter/bench/mobx.tsx new file mode 100644 index 00000000..c597bf9a --- /dev/null +++ b/benchmark/benchmarks/react/counter/bench/mobx.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import ReactDom from 'react-dom'; +import { action, observable } from 'mobx'; +import { observer } from 'mobx-react'; + +const appState = observable({ + count: 0, + increment: action(function () { + appState.count += 1; + }), +}); + +const App = observer(() => { + return

{appState.count}

; +}); + +export default function (target: HTMLElement) { + ReactDom.render(, target); +} diff --git a/benchmark/benchmarks/react/counter/bench/recoil.tsx b/benchmark/benchmarks/react/counter/bench/recoil.tsx new file mode 100644 index 00000000..d857e23d --- /dev/null +++ b/benchmark/benchmarks/react/counter/bench/recoil.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import ReactDom from 'react-dom'; +import { atom, RecoilRoot, useRecoilState } from 'recoil'; + +const counterState = atom({ + key: 'counterState', + default: 0, +}); + +const App = () => { + const [count, setCount] = useRecoilState(counterState); + return

setCount((v) => v + 1)}>{count}

; +}; + +export default function (target: HTMLElement) { + ReactDom.render( + + + , + target + ); +} diff --git a/benchmark/benchmarks/react/counter/bench/redux-toolkit.tsx b/benchmark/benchmarks/react/counter/bench/redux-toolkit.tsx new file mode 100644 index 00000000..1fbbedc6 --- /dev/null +++ b/benchmark/benchmarks/react/counter/bench/redux-toolkit.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import ReactDom from 'react-dom'; +import { configureStore, createSlice } from '@reduxjs/toolkit'; +import { Provider, useDispatch, useSelector } from 'react-redux'; + +const counterSlice = createSlice({ + name: 'counter', + initialState: { + count: 0, + }, + reducers: { + increment: (state) => { + state.count += 1; + }, + }, +}); + +const store = configureStore({ + reducer: { + counter: counterSlice.reducer, + }, +}); + +const App = () => { + const count = useSelector((state: any) => state.counter.count); + const dispatch = useDispatch(); + + return ( +

dispatch(counterSlice.actions.increment())}>{count}

+ ); +}; + +export default function (target: HTMLElement) { + ReactDom.render( + + + , + target + ); +} diff --git a/benchmark/benchmarks/react/counter/bench/redux.tsx b/benchmark/benchmarks/react/counter/bench/redux.tsx new file mode 100644 index 00000000..72b5c604 --- /dev/null +++ b/benchmark/benchmarks/react/counter/bench/redux.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import ReactDom from 'react-dom'; +import { combineReducers, createStore } from 'redux'; +import { Provider, useDispatch, useSelector } from 'react-redux'; + +const increment = () => { + return { + type: 'INCREMENT', + }; +}; + +const counter = (state = 0, action: any) => { + switch (action.type) { + case 'INCREMENT': + return state + 1; + default: + return state; + } +}; + +const rootReducer = combineReducers({ + counter, +}); + +const store = createStore(rootReducer); + +const App = () => { + const count = useSelector((state: any) => state.counter); + const dispatch = useDispatch(); + + return

dispatch(increment())}>{count}

; +}; + +export default function (target: HTMLElement) { + ReactDom.render( + + + , + target + ); +} diff --git a/benchmark/benchmarks/react/counter/bench/valtio.tsx b/benchmark/benchmarks/react/counter/bench/valtio.tsx new file mode 100644 index 00000000..682a3211 --- /dev/null +++ b/benchmark/benchmarks/react/counter/bench/valtio.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import ReactDom from 'react-dom'; +import { proxy, useSnapshot } from 'valtio'; + +const state = proxy({ count: 0 }); + +function App() { + const snapshot = useSnapshot(state, { sync: true }); + return

state.count++}>{snapshot.count}

; +} + +export default function (target: HTMLElement) { + ReactDom.render(, target); +} diff --git a/benchmark/benchmarks/react/counter/bench/zustand.tsx b/benchmark/benchmarks/react/counter/bench/zustand.tsx new file mode 100644 index 00000000..9c9bd62d --- /dev/null +++ b/benchmark/benchmarks/react/counter/bench/zustand.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import ReactDom from 'react-dom'; +import create from 'zustand'; + +const useStore = create((set) => ({ + count: 0, + increment: () => set((state) => ({ count: state.count + 1 })), +})); + +const App = () => { + const count = useStore((state) => state.count); + const increment = useStore((state) => state.increment); + + return

increment()}>{count}

; +}; + +export default function (target: HTMLElement) { + ReactDom.render(, target); +} diff --git a/benchmark/benchmarks/react/counter/index.ts b/benchmark/benchmarks/react/counter/index.ts index 987cc3d9..f0b4c3e7 100644 --- a/benchmark/benchmarks/react/counter/index.ts +++ b/benchmark/benchmarks/react/counter/index.ts @@ -3,6 +3,13 @@ import ReactDOM from 'react-dom'; // Files to run the Benchmark on import agilets from './bench/agilets'; +import jotai from './bench/jotai'; +import mobx from './bench/mobx'; +import recoil from './bench/recoil'; +import redux from './bench/redux'; +import reduxToolkit from './bench/redux-toolkit'; +import valtio from './bench/valtio'; +import zustand from './bench/zustand'; // @ts-ignore // Benchmark.js requires an instance of itself globally @@ -17,6 +24,7 @@ const target = document.getElementById('bench')!; // Increment Element let increment: HTMLHeadingElement; +// Configures a Benchmark test function configTest(renderElement: (target: HTMLElement) => void): Options { return { fn() { @@ -43,6 +51,13 @@ function configTest(renderElement: (target: HTMLElement) => void): Options { // Add Tests to Benchmark Suite suite .add('AgileTs', configTest(agilets)) + .add('Jotai', configTest(jotai)) + .add('Mobx', configTest(mobx)) + .add('Recoil', configTest(recoil)) + .add('Redux', configTest(redux)) + .add('Redux-Toolkit', configTest(reduxToolkit)) + .add('Valtio', configTest(valtio)) + .add('Zustand', configTest(zustand)) // Add Listener .on('start', function (this: any) { diff --git a/benchmark/package.json b/benchmark/package.json index 02877ecc..ba4931b7 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -40,11 +40,11 @@ "jotai": "^0.16.0", "mobx": "^6.2.0", "mobx-react": "^7.1.0", - "pullstate": "^1.22.1", "react-redux": "^7.2.3", "recoil": "^0.2.0", "redux": "^4.0.5", - "valtio": "^1.0.3" + "valtio": "^1.0.3", + "zustand": "^3.5.5" }, "bugs": { "url": "https://github.com/agile-ts/agile/issues" diff --git a/benchmark/yarn.lock b/benchmark/yarn.lock index a84f9339..77b49473 100644 --- a/benchmark/yarn.lock +++ b/benchmark/yarn.lock @@ -202,11 +202,6 @@ extract-zip@^2.0.1: optionalDependencies: "@types/yauzl" "^2.9.1" -fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - fd-slicer@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" @@ -263,11 +258,6 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" -immer@^8.0.1: - version "8.0.4" - resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.4.tgz#3a21605a4e2dded852fb2afd208ad50969737b7a" - integrity sha512-jMfL18P+/6P6epANRvRk6q8t+3gGhqsJ9EuJ25AXE+9bNTYtssvzeYbEd0mXRYWCmmXSIbnlpz6vd6iJlmGGGQ== - immer@^9.0.1: version "9.0.3" resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.3.tgz#146e2ba8b84d4b1b15378143c2345559915097f4" @@ -437,14 +427,6 @@ proxy-from-env@^1.1.0: resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -pullstate@^1.22.1: - version "1.22.1" - resolved "https://registry.yarnpkg.com/pullstate/-/pullstate-1.22.1.tgz#ffdde634e8c721907de8e6d37a85c6083137ee8a" - integrity sha512-Xu3umsGOG6qCQ4IWxKSEikQqdR7GDsTHQPE7wquzQENMRZbPeHURA9dZgH/9ktuhDh3D1qnIDI9PyPftabme0A== - dependencies: - fast-deep-equal "^3.1.3" - immer "^8.0.1" - pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -584,3 +566,8 @@ yazl@^2.5.1: integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw== dependencies: buffer-crc32 "~0.2.3" + +zustand@^3.5.5: + version "3.5.5" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-3.5.5.tgz#628458ad70621ddc2a17dbee49be963e5c0dccb5" + integrity sha512-iTiJoxzYFtiD7DhscgwK2P4Kft1JcZEI2U7mG8IxiOFM4KpBAiJZfFop3r/3wbCuyltXI6ph1Fx90e4j/S43XA== From 877ef4e5e467497b188aed52b6fe9b8a49f976cc Mon Sep 17 00:00:00 2001 From: Benno Kohrs Date: Sat, 3 Jul 2021 15:39:30 +0200 Subject: [PATCH 3/4] fixed some deps --- .../benchmarks/react/counter/bench/jotai.tsx | 9 ++++- .../react/counter/bench/zustand.tsx | 2 +- benchmark/package.json | 26 +++++++------- benchmark/yarn.lock | 36 ++++++++++--------- 4 files changed, 42 insertions(+), 31 deletions(-) diff --git a/benchmark/benchmarks/react/counter/bench/jotai.tsx b/benchmark/benchmarks/react/counter/bench/jotai.tsx index ca138586..31568aab 100644 --- a/benchmark/benchmarks/react/counter/bench/jotai.tsx +++ b/benchmark/benchmarks/react/counter/bench/jotai.tsx @@ -6,7 +6,14 @@ const countAtom = atom(0); const App = () => { const [count, setCount] = useAtom(countAtom); - return

setCount((state) => state + 1)}>{count}

; + return ( +

{ + setCount((v) => v + 1); + }}> + {count} +

+ ); }; export default function (target: HTMLElement) { diff --git a/benchmark/benchmarks/react/counter/bench/zustand.tsx b/benchmark/benchmarks/react/counter/bench/zustand.tsx index 9c9bd62d..ac73a2b5 100644 --- a/benchmark/benchmarks/react/counter/bench/zustand.tsx +++ b/benchmark/benchmarks/react/counter/bench/zustand.tsx @@ -11,7 +11,7 @@ const App = () => { const count = useStore((state) => state.count); const increment = useStore((state) => state.increment); - return

increment()}>{count}

; + return

{count}

; }; export default function (target: HTMLElement) { diff --git a/benchmark/package.json b/benchmark/package.json index ba4931b7..1856eb70 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -18,33 +18,33 @@ "url": "git+https://github.com/agile-ts/agile.git" }, "dependencies": { + "@agile-ts/core": "^0.1.0", + "@agile-ts/react": "^0.1.0", + "@reduxjs/toolkit": "^1.6.0", "benchmark": "^2.1.4", "colorette": "^1.2.2", "dotenv": "^10.0.0", "esbuild": "^0.12.14", "esbuild-register": "^2.6.0", + "jotai": "^1.1.2", "lodash": "^4.17.21", + "mobx": "^6.3.2", + "mobx-react": "^7.2.0", "playwright": "^1.12.3", "react": "^17.0.2", "react-dom": "^17.0.2", - "typescript": "^4.3.5" + "react-redux": "^7.2.4", + "recoil": "^0.3.1", + "redux": "^4.1.0", + "typescript": "^4.3.5", + "valtio": "^1.0.6", + "zustand": "^3.5.5" }, "devDependencies": { - "@agile-ts/core": "file:.yalc/@agile-ts/core", - "@agile-ts/react": "file:.yalc/@agile-ts/react", - "@reduxjs/toolkit": "^1.5.1", "@types/benchmark": "^2.1.0", "@types/node": "^16.0.0", "@types/react": "^17.0.13", - "@types/react-dom": "^17.0.8", - "jotai": "^0.16.0", - "mobx": "^6.2.0", - "mobx-react": "^7.1.0", - "react-redux": "^7.2.3", - "recoil": "^0.2.0", - "redux": "^4.0.5", - "valtio": "^1.0.3", - "zustand": "^3.5.5" + "@types/react-dom": "^17.0.8" }, "bugs": { "url": "https://github.com/agile-ts/agile/issues" diff --git a/benchmark/yarn.lock b/benchmark/yarn.lock index 77b49473..415c710a 100644 --- a/benchmark/yarn.lock +++ b/benchmark/yarn.lock @@ -2,8 +2,10 @@ # yarn lockfile v1 -"@agile-ts/core@file:.yalc/@agile-ts/core": +"@agile-ts/core@^0.1.0": version "0.1.0" + resolved "https://registry.yarnpkg.com/@agile-ts/core/-/core-0.1.0.tgz#11f048f06288b78a0f5841b4b8ee62c0f9863f75" + integrity sha512-+SeukkYXVwv9WFnk7/P/NCqNHFdywQNnSxGdcHAh1jSFeofofcP+aqp5oaEYf/4A73qe1yDF6vr7wMz0q0Zz4w== dependencies: "@agile-ts/logger" "^0.0.5" "@agile-ts/utils" "^0.0.5" @@ -15,8 +17,10 @@ dependencies: "@agile-ts/utils" "^0.0.5" -"@agile-ts/react@file:.yalc/@agile-ts/react": +"@agile-ts/react@^0.1.0": version "0.1.0" + resolved "https://registry.yarnpkg.com/@agile-ts/react/-/react-0.1.0.tgz#338ef6c562eae473f1328fb6727b4ae2aa9b4fc4" + integrity sha512-CzQE69LBIT8Ynk0M570TTKhA1KCQoR/RM/sNWh72De88W1yOw+BUtff5APsJPv+3we04zy7dz9KwIYjR4VbQLA== "@agile-ts/utils@^0.0.5": version "0.0.5" @@ -30,7 +34,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@reduxjs/toolkit@^1.5.1": +"@reduxjs/toolkit@^1.6.0": version "1.6.0" resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.6.0.tgz#0a17c6941c57341f8b31e982352b495ab69d5add" integrity sha512-eGL50G+Vj5AG5uD0lineb6rRtbs96M8+hxbcwkHpZ8LQcmt0Bm33WyBSnj5AweLkjQ7ZP+KFRDHiLMznljRQ3A== @@ -276,10 +280,10 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -jotai@^0.16.0: - version "0.16.11" - resolved "https://registry.yarnpkg.com/jotai/-/jotai-0.16.11.tgz#efeaf0311513cf41d5c82b7009f8381d518cbc41" - integrity sha512-EPBeDSBc4FwbFRArRjcI6IsHrVkba771mSOFTN3M4r5rU3ZcZMDFLElZScZVr6w1kgrEXvaMm59VAyEB3QUEbA== +jotai@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/jotai/-/jotai-1.1.2.tgz#3f211e0c03c74e95ea6fd7a69c1d2b65731009bf" + integrity sha512-dni4wtgYGG+s9YbOJN7lcfrrhxiD6bH1SN00Pnl0F2htgOXmjxqkGlFzw02OK0Rw35wGNzBfDTJVtbGD9wHOhg== jpeg-js@^0.4.2: version "0.4.3" @@ -325,14 +329,14 @@ mobx-react-lite@^3.2.0: resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-3.2.0.tgz#331d7365a6b053378dfe9c087315b4e41c5df69f" integrity sha512-q5+UHIqYCOpBoFm/PElDuOhbcatvTllgRp3M1s+Hp5j0Z6XNgDbgqxawJ0ZAUEyKM8X1zs70PCuhAIzX1f4Q/g== -mobx-react@^7.1.0: +mobx-react@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-7.2.0.tgz#241e925e963bb83a31d269f65f9f379e37ecbaeb" integrity sha512-KHUjZ3HBmZlNnPd1M82jcdVsQRDlfym38zJhZEs33VxyVQTvL77hODCArq6+C1P1k/6erEeo2R7rpE7ZeOL7dg== dependencies: mobx-react-lite "^3.2.0" -mobx@^6.2.0: +mobx@^6.3.2: version "6.3.2" resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.3.2.tgz#125590961f702a572c139ab69392bea416d2e51b" integrity sha512-xGPM9dIE1qkK9Nrhevp0gzpsmELKU4MFUJRORW/jqxVFIHHWIoQrjDjL8vkwoJYY3C2CeVJqgvl38hgKTalTWg== @@ -449,7 +453,7 @@ react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-redux@^7.2.3: +react-redux@^7.2.4: version "7.2.4" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.4.tgz#1ebb474032b72d806de2e0519cd07761e222e225" integrity sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA== @@ -469,10 +473,10 @@ react@^17.0.2: loose-envify "^1.1.0" object-assign "^4.1.1" -recoil@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/recoil/-/recoil-0.2.0.tgz#69344b5bec3129272560d8d9d6001ada3ee4d80c" - integrity sha512-VOJfYVQ3VgmfS7L5tV9QdOR+AJhvll8yGr1+3nJPCqADulImuScGZ2sJtejPps3zfTu/o98y5kO4lje8Tx6XHw== +recoil@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/recoil/-/recoil-0.3.1.tgz#40ef544160d19d76e25de8929d7e512eace13b90" + integrity sha512-KNA3DRqgxX4rRC8E7fc6uIw7BACmMPuraIYy+ejhE8tsw7w32CetMm8w7AMZa34wzanKKkev3vl3H7Z4s0QSiA== dependencies: hamt_plus "1.0.2" @@ -481,7 +485,7 @@ redux-thunk@^2.3.0: resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== -redux@^4.0.0, redux@^4.0.5, redux@^4.1.0: +redux@^4.0.0, redux@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.0.tgz#eb049679f2f523c379f1aff345c8612f294c88d4" integrity sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g== @@ -535,7 +539,7 @@ typescript@^4.3.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== -valtio@^1.0.3: +valtio@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/valtio/-/valtio-1.0.6.tgz#b316deea5537d254a141e2e5af1692d9eae2f60f" integrity sha512-ylCis9IkcE7b92XjMb3ebdJgLvJEFJ2NjfuD01QNr98pVOhRa5WsW4LSykFgbO4W7ftrZtO8jN4svZL0XlD77w== From 0a3a550c097960f4811318247d58de155fac5ab6 Mon Sep 17 00:00:00 2001 From: Benno Kohrs Date: Sat, 3 Jul 2021 16:26:40 +0200 Subject: [PATCH 4/4] added basic readme to benchmarks --- benchmark/README.md | 52 +++++++++++++++++++++ benchmark/benchmarks/react/counter/index.ts | 21 +++++---- benchmark/run.ts | 13 +++--- 3 files changed, 70 insertions(+), 16 deletions(-) create mode 100644 benchmark/README.md diff --git a/benchmark/README.md b/benchmark/README.md new file mode 100644 index 00000000..771c48de --- /dev/null +++ b/benchmark/README.md @@ -0,0 +1,52 @@ +# 🚀️ Benchmarks + +The `Benchmark Test Suites` are supposed to showcase where AgileTs is roughly located in terms of performance. +I know a counter doesn't really show real world app performance, +but it is better than nothing. + +## Counter Benchmark + +```ts +1. Zustand x 30,591 ops/sec ±1.15% (61 runs sampled) +2. Redux x 30,239 ops/sec ±1.64% (63 runs sampled) +3. Mobx x 29,032 ops/sec ±1.24% (64 runs sampled) +4. AgileTs x 28,327 ops/sec ±2.96% (60 runs sampled) +5. Redux-Toolkit x 22,808 ops/sec ±1.79% (65 runs sampled) +6. Jotai x 22,479 ops/sec ±5.79% (63 runs sampled) +7. Valtio x 20,784 ops/sec ±2.75% (63 runs sampled) +8. Recoil x 14,351 ops/sec ±1.55% (65 runs sampled) +``` + +## 🏃 Running Benchmarks + +The Benchmark tests run on top of the [`benchmark.js` library](https://github.com/bestiejs/benchmark.js/) +via [Playwright](https://github.com/microsoft/playwright) in the Chrome Browser. + +Before starting, make sure you are in the `/benchmark` directory. + +### 1️⃣ Install dependencies + +To prepare the dependencies, run: +```ts +yarn install +``` + +### 2️⃣ Run Benchmark Test Suite + +Execute the benchmark located in `./benchmarks/react/counter`. +```ts +yarn run test:counter +``` + +## ⭐️ Contribute + +Get a part of AgileTs and start contributing. We welcome any meaningful contribution. 😀 +To find out more about contributing, check out the [CONTRIBUTING.md](https://github.com/agile-ts/agile/blob/master/CONTRIBUTING.md). + + + Maintainability + + +## 🎉 Credits + +The Benchmark CLI is inspired by [`exome`](https://github.com/Marcisbee/exome). diff --git a/benchmark/benchmarks/react/counter/index.ts b/benchmark/benchmarks/react/counter/index.ts index f0b4c3e7..f7f573aa 100644 --- a/benchmark/benchmarks/react/counter/index.ts +++ b/benchmark/benchmarks/react/counter/index.ts @@ -15,40 +15,41 @@ import zustand from './bench/zustand'; // Benchmark.js requires an instance of itself globally window.Benchmark = Benchmark; -// Create new Benchmark test suite +// Create new Benchmark Test Suite const suite = new Suite('Count'); -// Retrieve the Element to render the Benchmark in +// Retrieve the Element to render the Benchmark Test Suite in const target = document.getElementById('bench')!; // Increment Element let increment: HTMLHeadingElement; -// Configures a Benchmark test +// Configures a single Benchmark Test function configTest(renderElement: (target: HTMLElement) => void): Options { return { fn() { + // Execute increment action increment.click(); }, onStart() { - // Render Benchmark Component in the target Element + // Render React Component in the target Element renderElement(target); - // Retrieve Increment Element + // Retrieve Element to execute the increment action on increment = target.querySelector('h1')!; }, onComplete() { - // Set 'output' in the Benchmark + // Set 'output' in the Benchmark itself to print it later (this as any).output = parseInt(target.innerText, 10); - // Unmount Component + // Unmount React Component ReactDOM.unmountComponentAtNode(target); target.innerHTML = ''; }, }; } -// Add Tests to Benchmark Suite +// Add Tests to the Benchmark Test Suite suite .add('AgileTs', configTest(agilets)) .add('Jotai', configTest(jotai)) @@ -70,9 +71,9 @@ suite console.log(`Fastest is ${this.filter('fastest').map('name')}`); // @ts-ignore - // Notify server to end the Benchmark + // Notify server that the Benchmark Test Suite has ended window.TEST.ended = true; }) - // Run Benchmark Suite + // Run Benchmark Test Suite .run({ async: true }); diff --git a/benchmark/run.ts b/benchmark/run.ts index a43c6329..7c233c47 100644 --- a/benchmark/run.ts +++ b/benchmark/run.ts @@ -6,7 +6,7 @@ import playwright from 'playwright'; dotenv.config(); // https://nodejs.org/docs/latest/api/process.html#process_process_argv -// Extract entry from the executed command +// Extract entry (at third parameter) from the executed command // yarn run ./path/to/entry -> './path/to/entry' is extracted const entry = process.argv.slice(2)[0]; if (entry == null) { @@ -16,7 +16,8 @@ if (entry == null) { } const startBenchmark = async () => { - // Bundle Benchmark Test and launch the server on which they are executed + // Bundle Benchmark Test Suite + // and launch the server on which the Test Suite is executed const server = await esbuild.serve( { servedir: 'public', @@ -39,12 +40,12 @@ const startBenchmark = async () => { console.log(`Server is running at port: ${server.port}`); - // Launch Chrome as browser to run the benchmarks in + // Launch Chrome as browser to run the Benchmark Test Suite in const browser = await playwright.chromium.launch(); const context = await browser.newContext(); const page = await context.newPage(); - // Option to open and test the benchmarks in the browser manually + // Option to open and test the Benchmark Test Suite in the browser manually if (process.env.MANUAL_BENCHMARK === 'true') { console.log( `Open the Browser at '${serverUrl}' to run the tests manually.` @@ -65,7 +66,7 @@ const startBenchmark = async () => { console.log(...message); }); - // Open url the server is running on + // Open the url the server is running on await page.goto(serverUrl); // Wait for tests to be executed (indicator is when 'window.TESTS.ended' is set to true) @@ -80,7 +81,7 @@ const startBenchmark = async () => { } ); - // Close Browser and stop server + // Close browser and stop server await browser.close(); server.stop(); };