diff --git a/.gitignore b/.gitignore index 7e7e7a0..426843c 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,8 @@ dist-ssr *.sw? swagger.json + +# Agent skills (installed via skills.sh) +.claude/ +.agents/ +skills-lock.json diff --git a/package-lock.json b/package-lock.json index e81066c..22f3087 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,15 +14,15 @@ "@gravity-ui/icons": "2.9.1", "@gravity-ui/uikit": "6.9.0", "@spec-box/text-parser": "0.1.0", - "atomic-router": "0.10.1", - "atomic-router-react": "0.10.0", + "@virentia/core": "0.3.1", + "@virentia/react": "0.2.3", + "@virentia/router": "0.2.0", + "@virentia/router-react": "0.2.0", "bootstrap": "5.3.2", "chart.js": "4.4.0", "chartjs-adapter-date-fns": "3.0.0", "copy-to-clipboard": "3.3.3", "date-fns": "2.30.0", - "effector": "23.2.0", - "effector-react": "23.2.0", "history": "5.3.0", "react": "18.2.0", "react-chartjs-2": "5.2.0", @@ -524,6 +524,91 @@ "resolved": "https://registry.npmjs.org/@bem-react/classname/-/classname-1.6.0.tgz", "integrity": "sha512-SFBwUHMcb7TFFK5ld88+JhecoEun3/kHZ6KvLDjj3w5hv/tfRV8mtGHA8N42uMctXLF4bPEcr96xwXXcRFuweg==" }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/darwin-x64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", @@ -540,6 +625,295 @@ "node": ">=12" } }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -808,6 +1182,48 @@ } } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.1.tgz", + "integrity": "sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.1.tgz", + "integrity": "sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.1.tgz", + "integrity": "sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, "node_modules/@rollup/rollup-darwin-x64": { "version": "4.14.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.1.tgz", @@ -821,6 +1237,181 @@ "darwin" ] }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.1.tgz", + "integrity": "sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.1.tgz", + "integrity": "sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.1.tgz", + "integrity": "sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.1.tgz", + "integrity": "sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==", + "cpu": [ + "ppc64le" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.1.tgz", + "integrity": "sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.1.tgz", + "integrity": "sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.1.tgz", + "integrity": "sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.1.tgz", + "integrity": "sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.1.tgz", + "integrity": "sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.1.tgz", + "integrity": "sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.1.tgz", + "integrity": "sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@spec-box/text-parser": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@spec-box/text-parser/-/text-parser-0.1.0.tgz", @@ -1387,6 +1978,56 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@virentia/core": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@virentia/core/-/core-0.3.1.tgz", + "integrity": "sha512-WttI8vLxENAPsT+HBPTG5JTa7RbMuGDOhSFQZWvGZWWxyVLPl/FPCTzQXExl7gwiW+RKF7GWfPvhVRLB5tXAKQ==", + "license": "MIT" + }, + "node_modules/@virentia/react": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@virentia/react/-/react-0.2.3.tgz", + "integrity": "sha512-e9Kw10VXv0D1xuxSLafD3agSfN5OPm0TUvZXNq0z7GADRjyhgGA8AUQAHhfpH10GKIR38sQbtbFD3C3KEJb45g==", + "license": "MIT", + "dependencies": { + "@virentia/core": "0.3.1" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@virentia/router": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@virentia/router/-/router-0.2.0.tgz", + "integrity": "sha512-s0ZywxYMPt2AedQiVe/aEofnPzoHxtSxD4scf+fBGAD3TufRKZ3knCEywypbf0eykXSPDviUqZqIKtQEA2EL9g==", + "license": "MIT", + "dependencies": { + "@virentia/router-paths": "0.1.1", + "query-string": "^9.3.1" + }, + "peerDependencies": { + "@virentia/core": ">=0.3.0" + } + }, + "node_modules/@virentia/router-paths": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@virentia/router-paths/-/router-paths-0.1.1.tgz", + "integrity": "sha512-3JFsEjLIsQkHUvms9RzR1ByFq+Y+dZVCU7TJTgcSNU4M5/r4yZ7lPE2sSMqL6j5d5y9Y+GtwbAMAZ5yPgRlbrw==", + "license": "MIT" + }, + "node_modules/@virentia/router-react": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@virentia/router-react/-/router-react-0.2.0.tgz", + "integrity": "sha512-8UwF0L/LyHA+0RaSw3ChgmkRvy7+52yvcufQpcmNst62IQU5hTncmP49l4uPHkzGBnHyl6HYGd74si8F4oDtZQ==", + "license": "MIT", + "dependencies": { + "@virentia/router": "0.2.0" + }, + "peerDependencies": { + "@virentia/react": ">=0.2.2", + "react": ">=18" + } + }, "node_modules/@vitejs/plugin-react": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.0.tgz", @@ -1487,45 +2128,13 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "engines": { - "node": ">=8" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/atomic-router": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/atomic-router/-/atomic-router-0.10.1.tgz", - "integrity": "sha512-u7XV+gOBgIAO84T58eXBkL3J4ARaHsltW7GuG01307BjvFfFGdE0yAVGm/JmMhBbIGhwTLHkalPbf8mudJIV3A==", - "dependencies": { - "path-to-regexp": "^6.2.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "effector": "^22.8.8 || ^23", - "history": "^5.3.0" + "node": ">=8" } }, - "node_modules/atomic-router-react": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/atomic-router-react/-/atomic-router-react-0.10.0.tgz", - "integrity": "sha512-9EM3n1eLDbuYQjWijiHMjA2l5UPvM2pt4O7Z0TUupuDz6KF00HNMd/iBIUq7uCyDwmyctgqqR5bHIeqRlXVUAQ==", - "dependencies": { - "clsx": "^1.1.1" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "atomic-router": "^0.10.0", - "effector": "^22.8.8 || ^23", - "effector-react": "^22.1.0 || ^23", - "react": "^17 || ^18" - } + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/autorest": { "version": "3.7.1", @@ -1841,6 +2450,15 @@ } } }, + "node_modules/decode-uri-component": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.4.1.tgz", + "integrity": "sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==", + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -1898,49 +2516,6 @@ "tslib": "^2.0.3" } }, - "node_modules/effector": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/effector/-/effector-23.2.0.tgz", - "integrity": "sha512-TqR/e5BSfAk4ZkHOykmqPmT9Nn4fLE/BhuBiVmy2cb7Vp6in8N+xMDFhWWZAgOdQjehgt/dIVQyXuWpXh3EoZA==", - "funding": [ - { - "type": "patreon", - "url": "https://www.patreon.com/zero_bias" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/effector" - } - ], - "engines": { - "node": ">=11.0.0" - } - }, - "node_modules/effector-react": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/effector-react/-/effector-react-23.2.0.tgz", - "integrity": "sha512-e7tWJ+lpVKJpzS0UDR2Oi/0dAfvyDYyT44CWIFzBd8aJ7u4VXqP/3RJ4GCa3sH2g8Wffx6IA3BuTUGvgeH8ypg==", - "funding": [ - { - "type": "patreon", - "url": "https://www.patreon.com/zero_bias" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/effector" - } - ], - "dependencies": { - "use-sync-external-store": "^1.0.0" - }, - "engines": { - "node": ">=11.0.0" - }, - "peerDependencies": { - "effector": "^23.0.0", - "react": ">=16.8.0 <19.0.0" - } - }, "node_modules/electron-to-chromium": { "version": "1.4.783", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.783.tgz", @@ -2369,6 +2944,18 @@ "node": ">=8" } }, + "node_modules/filter-obj": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-5.1.0.tgz", + "integrity": "sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3067,11 +3654,6 @@ "node": ">=8" } }, - "node_modules/path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" - }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -3170,6 +3752,23 @@ "node": ">=6" } }, + "node_modules/query-string": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-9.4.1.tgz", + "integrity": "sha512-lSyJeN3RuaG7DZGWThtYRhk96+kEyZ/+doZpERuWbjeFL+Ok3vEat/swU498rAI0NcVt5/RJp8UDuLz7FckxrA==", + "license": "MIT", + "dependencies": { + "decode-uri-component": "^0.4.1", + "filter-obj": "^5.1.0", + "split-on-first": "^3.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -3609,6 +4208,18 @@ "node": ">=0.10.0" } }, + "node_modules/split-on-first": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-3.0.0.tgz", + "integrity": "sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -3828,14 +4439,6 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/vite": { "version": "5.2.11", "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", @@ -4311,6 +4914,41 @@ "resolved": "https://registry.npmjs.org/@bem-react/classname/-/classname-1.6.0.tgz", "integrity": "sha512-SFBwUHMcb7TFFK5ld88+JhecoEun3/kHZ6KvLDjj3w5hv/tfRV8mtGHA8N42uMctXLF4bPEcr96xwXXcRFuweg==" }, + "@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "dev": true, + "optional": true + }, "@esbuild/darwin-x64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", @@ -4318,6 +4956,125 @@ "dev": true, "optional": true }, + "@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "dev": true, + "optional": true + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -4510,6 +5267,27 @@ "picomatch": "^2.3.1" } }, + "@rollup/rollup-android-arm-eabi": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.1.tgz", + "integrity": "sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.1.tgz", + "integrity": "sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.1.tgz", + "integrity": "sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==", + "dev": true, + "optional": true + }, "@rollup/rollup-darwin-x64": { "version": "4.14.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.1.tgz", @@ -4517,6 +5295,83 @@ "dev": true, "optional": true }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.1.tgz", + "integrity": "sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.1.tgz", + "integrity": "sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.1.tgz", + "integrity": "sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.1.tgz", + "integrity": "sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.1.tgz", + "integrity": "sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-s390x-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.1.tgz", + "integrity": "sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.1.tgz", + "integrity": "sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.1.tgz", + "integrity": "sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.1.tgz", + "integrity": "sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.1.tgz", + "integrity": "sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-msvc": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.1.tgz", + "integrity": "sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==", + "dev": true, + "optional": true + }, "@spec-box/text-parser": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@spec-box/text-parser/-/text-parser-0.1.0.tgz", @@ -4881,6 +5736,41 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "@virentia/core": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@virentia/core/-/core-0.3.1.tgz", + "integrity": "sha512-WttI8vLxENAPsT+HBPTG5JTa7RbMuGDOhSFQZWvGZWWxyVLPl/FPCTzQXExl7gwiW+RKF7GWfPvhVRLB5tXAKQ==" + }, + "@virentia/react": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@virentia/react/-/react-0.2.3.tgz", + "integrity": "sha512-e9Kw10VXv0D1xuxSLafD3agSfN5OPm0TUvZXNq0z7GADRjyhgGA8AUQAHhfpH10GKIR38sQbtbFD3C3KEJb45g==", + "requires": { + "@virentia/core": "0.3.1" + } + }, + "@virentia/router": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@virentia/router/-/router-0.2.0.tgz", + "integrity": "sha512-s0ZywxYMPt2AedQiVe/aEofnPzoHxtSxD4scf+fBGAD3TufRKZ3knCEywypbf0eykXSPDviUqZqIKtQEA2EL9g==", + "requires": { + "@virentia/router-paths": "0.1.1", + "query-string": "^9.3.1" + } + }, + "@virentia/router-paths": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@virentia/router-paths/-/router-paths-0.1.1.tgz", + "integrity": "sha512-3JFsEjLIsQkHUvms9RzR1ByFq+Y+dZVCU7TJTgcSNU4M5/r4yZ7lPE2sSMqL6j5d5y9Y+GtwbAMAZ5yPgRlbrw==" + }, + "@virentia/router-react": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@virentia/router-react/-/router-react-0.2.0.tgz", + "integrity": "sha512-8UwF0L/LyHA+0RaSw3ChgmkRvy7+52yvcufQpcmNst62IQU5hTncmP49l4uPHkzGBnHyl6HYGd74si8F4oDtZQ==", + "requires": { + "@virentia/router": "0.2.0" + } + }, "@vitejs/plugin-react": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.0.tgz", @@ -4959,22 +5849,6 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "atomic-router": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/atomic-router/-/atomic-router-0.10.1.tgz", - "integrity": "sha512-u7XV+gOBgIAO84T58eXBkL3J4ARaHsltW7GuG01307BjvFfFGdE0yAVGm/JmMhBbIGhwTLHkalPbf8mudJIV3A==", - "requires": { - "path-to-regexp": "^6.2.0" - } - }, - "atomic-router-react": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/atomic-router-react/-/atomic-router-react-0.10.0.tgz", - "integrity": "sha512-9EM3n1eLDbuYQjWijiHMjA2l5UPvM2pt4O7Z0TUupuDz6KF00HNMd/iBIUq7uCyDwmyctgqqR5bHIeqRlXVUAQ==", - "requires": { - "clsx": "^1.1.1" - } - }, "autorest": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/autorest/-/autorest-3.7.1.tgz", @@ -5177,6 +6051,11 @@ "ms": "2.1.2" } }, + "decode-uri-component": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.4.1.tgz", + "integrity": "sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==" + }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -5225,19 +6104,6 @@ "tslib": "^2.0.3" } }, - "effector": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/effector/-/effector-23.2.0.tgz", - "integrity": "sha512-TqR/e5BSfAk4ZkHOykmqPmT9Nn4fLE/BhuBiVmy2cb7Vp6in8N+xMDFhWWZAgOdQjehgt/dIVQyXuWpXh3EoZA==" - }, - "effector-react": { - "version": "23.2.0", - "resolved": "https://registry.npmjs.org/effector-react/-/effector-react-23.2.0.tgz", - "integrity": "sha512-e7tWJ+lpVKJpzS0UDR2Oi/0dAfvyDYyT44CWIFzBd8aJ7u4VXqP/3RJ4GCa3sH2g8Wffx6IA3BuTUGvgeH8ypg==", - "requires": { - "use-sync-external-store": "^1.0.0" - } - }, "electron-to-chromium": { "version": "1.4.783", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.783.tgz", @@ -5560,6 +6426,11 @@ "to-regex-range": "^5.0.1" } }, + "filter-obj": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-5.1.0.tgz", + "integrity": "sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==" + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -6090,11 +6961,6 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, - "path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" - }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -6152,6 +7018,16 @@ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, + "query-string": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-9.4.1.tgz", + "integrity": "sha512-lSyJeN3RuaG7DZGWThtYRhk96+kEyZ/+doZpERuWbjeFL+Ok3vEat/swU498rAI0NcVt5/RJp8UDuLz7FckxrA==", + "requires": { + "decode-uri-component": "^0.4.1", + "filter-obj": "^5.1.0", + "split-on-first": "^3.0.0" + } + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -6458,6 +7334,11 @@ "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true }, + "split-on-first": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-3.0.0.tgz", + "integrity": "sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==" + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -6602,12 +7483,6 @@ "integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==", "requires": {} }, - "use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "requires": {} - }, "vite": { "version": "5.2.11", "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", diff --git a/package.json b/package.json index 2cd8516..b40ebfd 100644 --- a/package.json +++ b/package.json @@ -17,15 +17,15 @@ "@gravity-ui/icons": "2.9.1", "@gravity-ui/uikit": "6.9.0", "@spec-box/text-parser": "0.1.0", - "atomic-router": "0.10.1", - "atomic-router-react": "0.10.0", + "@virentia/core": "0.3.1", + "@virentia/react": "0.2.3", + "@virentia/router": "0.2.0", + "@virentia/router-react": "0.2.0", "bootstrap": "5.3.2", "chart.js": "4.4.0", "chartjs-adapter-date-fns": "3.0.0", "copy-to-clipboard": "3.3.3", "date-fns": "2.30.0", - "effector": "23.2.0", - "effector-react": "23.2.0", "history": "5.3.0", "react": "18.2.0", "react-chartjs-2": "5.2.0", diff --git a/src/Application.tsx b/src/Application.tsx index 8267d91..d18a883 100644 --- a/src/Application.tsx +++ b/src/Application.tsx @@ -1,4 +1,4 @@ -import { Route } from 'atomic-router-react'; +import { createRouteView, createRoutesView } from '@virentia/router-react'; import { FC } from 'react'; import { ApplicationLayout } from './components/ApplicationLayout/ApplicationLayout'; @@ -8,12 +8,18 @@ import { Home } from './pages/Home/Home'; import { Project } from './pages/Project/Project'; import { Stat } from './pages/Stat/Stat'; +const Routes = createRoutesView({ + routes: [ + createRouteView({ route: homeRoute, view: Home }), + createRouteView({ route: projectRoute, view: Project }), + createRouteView({ route: statRoute, view: Stat }), + ], +}); + export const Application: FC = () => { return ( - - - + ); diff --git a/src/components/ApplicationLayout/ApplicationLayout.tsx b/src/components/ApplicationLayout/ApplicationLayout.tsx index 0f51fd2..ebac64f 100644 --- a/src/components/ApplicationLayout/ApplicationLayout.tsx +++ b/src/components/ApplicationLayout/ApplicationLayout.tsx @@ -6,7 +6,7 @@ import '@gravity-ui/uikit/styles/styles.css'; import './ApplicationLayout.css'; import { $theme } from '@/model'; -import { useUnit } from 'effector-react'; +import { useUnit } from '@virentia/react'; const bem = cn('ApplicationLayout'); diff --git a/src/components/Chart/Chart.tsx b/src/components/Chart/Chart.tsx index b478ee0..7639929 100644 --- a/src/components/Chart/Chart.tsx +++ b/src/components/Chart/Chart.tsx @@ -15,7 +15,7 @@ import { startOfDay } from 'date-fns'; import { ru } from 'date-fns/locale'; import { FC, useMemo } from 'react'; import { Bar, Line } from 'react-chartjs-2'; -import { useUnit } from 'effector-react'; +import { useUnit } from '@virentia/react'; import { $theme } from '@/model'; import { StatAssertion, StatAutotestsItem, UiTheme } from '@/types'; diff --git a/src/components/FeatureCard/components/Header.tsx b/src/components/FeatureCard/components/Header.tsx index bf9061b..6709df6 100644 --- a/src/components/FeatureCard/components/Header.tsx +++ b/src/components/FeatureCard/components/Header.tsx @@ -1,4 +1,4 @@ -import { useUnit } from 'effector-react'; +import { useUnit } from '@virentia/react'; import { FC, useCallback, useMemo } from 'react'; import { FormattedText } from '@/components/FormattedText/FormattedText'; diff --git a/src/components/ProjectFeatures/components/FeatureItem.tsx b/src/components/ProjectFeatures/components/FeatureItem.tsx index 1ddc469..b107ecd 100644 --- a/src/components/ProjectFeatures/components/FeatureItem.tsx +++ b/src/components/ProjectFeatures/components/FeatureItem.tsx @@ -1,6 +1,6 @@ import { FC, ReactNode, useCallback } from 'react'; import { ArrowToggle } from '@gravity-ui/uikit'; -import { useUnit, useStoreMap } from 'effector-react'; +import { useUnit } from '@virentia/react'; import { FeatureTypeIcon } from '@/components/FeatureTypeIcon/FeatureTypeIcon'; import { ListItem, ListItemState } from '@/components/ListItem/ListItem'; @@ -21,7 +21,11 @@ interface FeatureGroupItemProps { children: ReactNode; } -const useIsOpen = (id: string) => useStoreMap($collapseState, (s) => Boolean(s[id])); +const useIsOpen = (id: string) => { + const collapseState = useUnit($collapseState); + + return Boolean(collapseState[id]); +}; export const FeatureGroupItem: FC = (props) => { const { diff --git a/src/components/ProjectLayout/ProjectLayout.tsx b/src/components/ProjectLayout/ProjectLayout.tsx index 5b7cd5d..59dcd9d 100644 --- a/src/components/ProjectLayout/ProjectLayout.tsx +++ b/src/components/ProjectLayout/ProjectLayout.tsx @@ -1,8 +1,8 @@ -import { RouteInstance } from 'atomic-router'; +import { Route } from '@virentia/router'; +import { useIsOpened } from '@virentia/router-react'; import { FC, ReactNode } from 'react'; import { cn } from '@bem-react/classname'; import { Skeleton } from '@gravity-ui/uikit'; -import { useUnit } from 'effector-react'; import { ProjectContext, @@ -25,13 +25,13 @@ type ProjectLayoutProps = { }; interface NavItemProps { - to: RouteInstance<{ project?: string }>; + to: Route<{ project?: string }>; text: string; project: string; } const NavItem: FC = ({ to, text, project }) => { - const isOpened = useUnit(to.$isOpened); + const isOpened = useIsOpened(to); if (!project) { return ; diff --git a/src/components/RouteLink/RouteLink.tsx b/src/components/RouteLink/RouteLink.tsx index 6375f6f..3be1375 100644 --- a/src/components/RouteLink/RouteLink.tsx +++ b/src/components/RouteLink/RouteLink.tsx @@ -1,5 +1,3 @@ -import { RouteParams } from 'atomic-router'; - import { cn } from '@bem-react/classname'; import { Link } from '@gravity-ui/uikit'; @@ -8,11 +6,11 @@ import { MouseEvent, ReactNode, useCallback } from 'react'; const bem = cn('RouteLink'); -export interface RouteLinkProps extends RouteLinkParams { +export interface RouteLinkProps extends RouteLinkParams { children?: ReactNode; } -export function RouteLink(props: RouteLinkProps) { +export function RouteLink(props: RouteLinkProps) { const { to, params, query, target, onPress, children } = props; const { href, handler } = useRouteLink({ diff --git a/src/components/RouteLinkButton/RouteLinkButton.tsx b/src/components/RouteLinkButton/RouteLinkButton.tsx index 72b9081..e1a3e78 100644 --- a/src/components/RouteLinkButton/RouteLinkButton.tsx +++ b/src/components/RouteLinkButton/RouteLinkButton.tsx @@ -1,6 +1,5 @@ import { ReactNode, ComponentProps, MouseEvent, useCallback } from 'react'; -import { RouteParams } from 'atomic-router'; import { cn } from '@bem-react/classname'; import { Button } from '@gravity-ui/uikit'; @@ -8,13 +7,13 @@ import { useRouteLink, RouteLinkParams } from '@/hooks/useRouteLink'; const bem = cn('RouteLink'); -export interface RouteLinkButtonProps +export interface RouteLinkButtonProps extends RouteLinkParams, Omit, 'href'> { children?: ReactNode; } -export function RouteLinkButton(props: RouteLinkButtonProps) { +export function RouteLinkButton(props: RouteLinkButtonProps) { const { className, to, params, query, target, onPress, children, ...buttonProps } = props; const { href, handler } = useRouteLink({ diff --git a/src/components/ThemeToggler/ThemeToggler.tsx b/src/components/ThemeToggler/ThemeToggler.tsx index 491402a..42f68fc 100644 --- a/src/components/ThemeToggler/ThemeToggler.tsx +++ b/src/components/ThemeToggler/ThemeToggler.tsx @@ -1,7 +1,7 @@ import { ReactNode } from 'react'; import { Button, Icon } from '@gravity-ui/uikit'; import { Moon, Sun } from '@gravity-ui/icons'; -import { useUnit } from 'effector-react'; +import { useUnit } from '@virentia/react'; import { $theme, toggleThemeEvent } from '@/model'; import { UiTheme } from '@/types'; @@ -11,7 +11,7 @@ export const ThemeToggler = () => { const toggleTheme = useUnit(toggleThemeEvent); return ( - ); diff --git a/src/hooks/useRouteLink.ts b/src/hooks/useRouteLink.ts index cdf2443..90157f2 100644 --- a/src/hooks/useRouteLink.ts +++ b/src/hooks/useRouteLink.ts @@ -1,22 +1,24 @@ -import { RouteInstance, RouteParams, RouteQuery } from 'atomic-router'; -import { useLink } from 'atomic-router-react'; +import { Query, Route } from '@virentia/router'; +import { useLink } from '@virentia/router-react'; import { useCallback } from 'react'; -import { useUnit } from 'effector-react'; import { PressEvent } from './usePress'; -export interface RouteLinkParams { - to: RouteInstance; +export interface RouteLinkParams { + to: Route; params: T; - query?: RouteQuery; + query?: Query; target?: string; onPress?: (e: PressEvent) => void; } -export const useRouteLink = (args: RouteLinkParams) => { +export const useRouteLink = (args: RouteLinkParams) => { const { to, params, query, target, onPress } = args; - const href = useLink(to, params, query); - const navigate = useUnit(to.navigate); + const link = useLink(to, params, query); + const href = link.path; + // useLink возвращает open с отложенным условным типом из-за дженерика T; + // на этом уровне payload всегда { params, query } + const open = link.open as (payload: { params: T; query?: Query }) => void; const handler = useCallback( (e: PressEvent) => { @@ -44,12 +46,12 @@ export const useRouteLink = (args: RouteLinkParams) => e.source.preventDefault(); - navigate({ - params: params || {}, + open({ + params, query: query || {}, }); }, - [navigate, params, query, target, onPress], + [open, params, query, target, onPress], ); return { href, handler }; diff --git a/src/main.tsx b/src/main.tsx index 8fb60dc..e1ced2b 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,7 +1,6 @@ -import { createHistoryRouter } from 'atomic-router'; -import { RouterProvider } from 'atomic-router-react'; -import { allSettled } from 'effector'; -import { Provider as ScopeProvider } from 'effector-react'; +import { historyAdapter } from '@virentia/router'; +import { RouterProvider } from '@virentia/router-react'; +import { ScopeProvider } from '@virentia/react'; import { createBrowserHistory } from 'history'; import React from 'react'; import ReactDOM from 'react-dom/client'; @@ -11,11 +10,8 @@ import { $theme, AnalyticsApi, SpecBoxLocalStorage, - controls, createScope, - homeRoute, - projectRoute, - statRoute, + router, } from '@/model'; import { UiTheme } from '@/types'; @@ -51,26 +47,16 @@ const ls: SpecBoxLocalStorage = { const scope = createScope({ api, analytics, ls }, [[$theme, ls.getTheme()]]); // router -const routes = [ - { path: '/', route: homeRoute }, - { path: '/project/:project', route: projectRoute }, - { path: '/project/:project/stat', route: statRoute }, -]; - -const router = createHistoryRouter({ routes, controls }); const history = createBrowserHistory(); history.listen(({ location: { pathname, search, hash } }) => analytics?.hit(pathname + search + hash), ); -// start -allSettled(router.setHistory, { scope, params: history }); - // render ReactDOM.createRoot(document.getElementById('root')!).render( - - + + diff --git a/src/model/common.ts b/src/model/common.ts index 5514d65..9225252 100644 --- a/src/model/common.ts +++ b/src/model/common.ts @@ -1,5 +1,5 @@ -import { createRouterControls } from 'atomic-router'; -import { createEvent, createStore, sample } from 'effector'; +import { createRouterControls } from '@virentia/router'; +import { event, reaction, store } from '@virentia/core'; import { UiTheme } from '@/types'; @@ -9,8 +9,8 @@ import { createSpecBoxEffect } from './scope'; export const controls = createRouterControls(); // theme -export const $theme = createStore('light'); -export const toggleThemeEvent = createEvent(); +export const $theme = store('light'); +export const toggleThemeEvent = event(); const saveThemeFx = createSpecBoxEffect(async (theme: UiTheme, { ls }) => { ls.setTheme(theme); @@ -21,14 +21,17 @@ const themeByPrevTheme: Record = { dark: 'light', }; -sample({ - source: $theme, - clock: toggleThemeEvent, - fn: (theme) => themeByPrevTheme[theme], - target: $theme, +reaction({ + on: toggleThemeEvent, + run() { + $theme.value = themeByPrevTheme[$theme.value]; + }, }); -sample({ - source: $theme, - target: saveThemeFx, +// сохраняем тему при каждом её изменении +reaction({ + on: $theme, + run(theme) { + saveThemeFx(theme); + }, }); diff --git a/src/model/index.ts b/src/model/index.ts index f033bfb..4b8a727 100644 --- a/src/model/index.ts +++ b/src/model/index.ts @@ -1,6 +1,8 @@ export * from './scope'; export * from './common'; +export { router } from './router'; + export { homeRoute } from './pages/home'; export { projectRoute } from './pages/project'; export { statRoute } from './pages/stat'; diff --git a/src/model/pages/home.ts b/src/model/pages/home.ts index c886a07..7801300 100644 --- a/src/model/pages/home.ts +++ b/src/model/pages/home.ts @@ -1,13 +1,14 @@ -import { createRoute } from 'atomic-router'; -import { restore, sample } from 'effector'; +import { createRoute } from '@virentia/router'; +import { reaction, store } from '@virentia/core'; import { mapProject } from '@/mappers'; +import { Project } from '@/types'; -import { createSpecBoxEffect } from '..'; +import { createSpecBoxEffect } from '../scope'; -export const homeRoute = createRoute(); +export const homeRoute = createRoute>(); -const loadProjectListFx = createSpecBoxEffect(async (_, { api }) => { +const loadProjectListFx = createSpecBoxEffect(async (_: void, { api }) => { try { const response = await api.projectsList(); @@ -18,10 +19,19 @@ const loadProjectListFx = createSpecBoxEffect(async (_, { api }) => { } }); -export const $projects = restore(loadProjectListFx.doneData, []); +export const $projects = store([]); export const $projectsIsLoading = loadProjectListFx.pending; -sample({ - clock: [homeRoute.opened], - target: loadProjectListFx, +reaction({ + on: loadProjectListFx.doneData, + run(projects) { + $projects.value = projects; + }, +}); + +reaction({ + on: homeRoute.opened, + run() { + loadProjectListFx(); + }, }); diff --git a/src/model/pages/project.ts b/src/model/pages/project.ts index 02f8a7a..aeff70e 100644 --- a/src/model/pages/project.ts +++ b/src/model/pages/project.ts @@ -1,6 +1,6 @@ -import { createRoute, querySync } from 'atomic-router'; +import { createRoute } from '@virentia/router'; import copy from 'copy-to-clipboard'; -import { combine, createEvent, createStore, merge, restore, sample, split } from 'effector'; +import { effect, event, reaction, store } from '@virentia/core'; import { toast } from 'react-toastify'; import { mapFeature, mapStructure } from '@/mappers'; @@ -16,6 +16,9 @@ const STRUCTURE_STUB: ProjectStructure = { export const projectRoute = createRoute<{ project?: string }>(); +// код проекта, дедуплицированный: меняется только при смене проекта, а не query +const $projectCode = projectRoute.params.map((params) => params.project ?? ''); + export interface LoadStructureFxParams { project: string; } @@ -36,21 +39,52 @@ export const loadStructureFx = createSpecBoxEffect( }, ); -export const $structure = restore(loadStructureFx.doneData, STRUCTURE_STUB); +export const $structure = store(STRUCTURE_STUB); export const $structureIsLoading = loadStructureFx.pending; -export const toggle = createEvent(); -export const expand = createEvent(); +reaction({ + on: loadStructureFx.doneData, + run(structure) { + $structure.value = structure; + }, +}); + +// структуру перезагружаем только когда реально сменился проект +reaction({ + on: $projectCode, + run(project) { + if (project) { + loadStructureFx({ project }); + } + }, +}); + +// collapse-state дерева +export const toggle = event(); +export const expand = event(); -export const $collapseState = createStore>({}) - .on(toggle, (state, id) => ({ ...state, [id]: !state[id] })) - .on(expand, (state, ids) => ids.reduce((s, id) => ((s[id] = true), s), { ...state })); +export const $collapseState = store>({}); + +reaction({ + on: toggle, + run(id) { + $collapseState.value = { ...$collapseState.value, [id]: !$collapseState.value[id] }; + }, +}); + +reaction({ + on: expand, + run(ids) { + $collapseState.value = ids.reduce((s, id) => ((s[id] = true), s), { ...$collapseState.value }); + }, +}); export interface CopyToClipboardParams { text: string; } -export const copyToClipboardFx = createSpecBoxEffect(async ({ text }: CopyToClipboardParams) => { +// копирование в буфер — обычный сайд-эффект, зависимости не нужны +export const copyToClipboard = effect(async ({ text }: CopyToClipboardParams) => { if (copy(text)) { toast('Скопировано'); } else { @@ -76,27 +110,58 @@ export const loadFeatureFx = createSpecBoxEffect( }, ); -export const loadFeature = createEvent(); -export const resetFeature = createEvent(); +// код выбранной фичи хранится в query (?feature=...) и синхронизируется с URL через trackQuery +const featureQuery = controls.trackQuery<{ feature: string }>({ + parameters: { + safeParse: (query) => { + const feature = query.feature; -// код выбранной фичи (появляется в момент выбора) -export const $featureCode = createStore('') - .on(loadFeatureFx, (_, { feature }) => feature) - .reset(resetFeature); + return typeof feature === 'string' && feature + ? { success: true, data: { feature } } + : { success: false }; + }, + }, +}); + +export const loadFeature = event(); + +// выбор фичи в UI — просто пишем её в URL, дальнейшее подхватит featureQuery.entered +reaction({ + on: loadFeature, + run({ feature }) { + featureQuery.enter({ feature }); + }, +}); // данные выбранной фичи (появляются после загрузки) -export const $feature = createStore(null).reset(resetFeature); +export const $feature = store(null); +// код выбранной фичи (появляется в момент выбора) +export const $featureCode = store(''); export const $featureIsPending = loadFeatureFx.pending; -querySync({ - source: { - feature: restore( - loadFeature.map(({ feature }) => feature), - null, - ), +// в URL появилась фича (или сменилась) — грузим её для текущего проекта +reaction({ + on: featureQuery.entered, + run({ feature }) { + $featureCode.value = feature; + loadFeatureFx({ project: projectRoute.params.value.project ?? '', feature }); + }, +}); + +// фича ушла из URL — сбрасываем выбор +reaction({ + on: featureQuery.exited, + run() { + $featureCode.value = ''; + $feature.value = null; + }, +}); + +reaction({ + on: loadFeatureFx.doneData, + run(feature) { + $feature.value = feature; }, - route: projectRoute, - controls, }); // при выборе активной фичи раскрываем всех её родителей @@ -128,43 +193,11 @@ const getExpandedIds = (args: { feature: Feature | null; tree: ProjectStructure return result; }; -sample({ - clock: combine({ - feature: $feature, - tree: $structure, - }), - fn: getExpandedIds, - target: expand, -}); +// как только доступны и фича, и структура — раскрываем ветку до выбранной фичи +reaction(() => { + const ids = getExpandedIds({ feature: $feature.value, tree: $structure.value }); -sample({ - clock: [projectRoute.opened], - fn: ({ params: { project = '' } }) => ({ project }), - target: loadStructureFx, -}); - -split({ - source: merge([projectRoute.opened, projectRoute.updated]).map( - ({ params: { project = '' }, query: { feature = '' } }): LoadFeatureFxParams => ({ - project, - feature, - }), - ), - match: ({ feature }: LoadFeatureFxParams) => (feature ? 'load' : 'reset'), - cases: { - load: loadFeatureFx, - reset: resetFeature, - }, -}); - -sample({ - clock: loadFeatureFx.doneData, - target: $feature, -}); - -export const copyToClipboard = createEvent(); - -sample({ - clock: copyToClipboard, - target: copyToClipboardFx, + if (ids.length) { + expand(ids); + } }); diff --git a/src/model/pages/stat.ts b/src/model/pages/stat.ts index 8475ca9..3ad79fa 100644 --- a/src/model/pages/stat.ts +++ b/src/model/pages/stat.ts @@ -1,11 +1,12 @@ -import { createRoute } from 'atomic-router'; -import { restore, sample } from 'effector'; +import { createRoute } from '@virentia/router'; +import { reaction, store } from '@virentia/core'; +import { parseISO } from 'date-fns'; import { mapProjectStat } from '@/mappers'; import { ProjectStat } from '@/types'; +import { controls } from '../common'; import { StoreDependencies, createSpecBoxEffect } from '../scope'; -import { parseISO } from 'date-fns'; const STUB: ProjectStat = { assertions: [], @@ -23,6 +24,10 @@ interface LoadStatFxParams { const getDate = (str?: string) => (str ? parseISO(str) : undefined); +// query-параметры приходят как string | null | string[]; берём только строковое значение +const single = (value: string | null | Array | undefined): string | undefined => + typeof value === 'string' ? value : undefined; + export const loadStatFx = createSpecBoxEffect( async ( { project, from, to }: LoadStatFxParams, @@ -42,11 +47,22 @@ export const loadStatFx = createSpecBoxEffect( }, ); -export const $stat = restore(loadStatFx.doneData, STUB); +export const $stat = store(STUB); export const $statIsLoading = loadStatFx.pending; -sample({ - clock: [statRoute.opened], - fn: ({ params: { project = '' }, query: { from, to } }) => ({ project, from, to }), - target: loadStatFx, +reaction({ + on: loadStatFx.doneData, + run(stat) { + $stat.value = stat; + }, +}); + +reaction({ + on: statRoute.opened, + run() { + const project = statRoute.params.value.project ?? ''; + const { from, to } = controls.query.value; + + loadStatFx({ project, from: single(from), to: single(to) }); + }, }); diff --git a/src/model/router.ts b/src/model/router.ts new file mode 100644 index 0000000..5376b10 --- /dev/null +++ b/src/model/router.ts @@ -0,0 +1,16 @@ +import { createRouter } from '@virentia/router'; + +import { controls } from './common'; +import { homeRoute } from './pages/home'; +import { projectRoute } from './pages/project'; +import { statRoute } from './pages/stat'; + +// сопоставление путей и роутов; сам history подключается в RouterProvider +export const router = createRouter({ + controls, + routes: [ + { path: '/', route: homeRoute }, + { path: '/project/:project', route: projectRoute }, + { path: '/project/:project/stat', route: statRoute }, + ], +}); diff --git a/src/model/scope.ts b/src/model/scope.ts index 036e80c..605bc04 100644 --- a/src/model/scope.ts +++ b/src/model/scope.ts @@ -1,9 +1,9 @@ -import { Effect, StorePair, attach, createEffect, createStore, fork } from 'effector'; +import { Effect, StoreWritable, attach, scope, store } from '@virentia/core'; import { SpecBoxWebApi } from '@/api'; import { UiTheme } from '@/types'; -export const $deps = createStore(null as unknown as StoreDependencies); +export const $deps = store(null as unknown as StoreDependencies); export interface AnalyticsApi { hit: (url: string) => void; @@ -21,26 +21,23 @@ export interface StoreDependencies { analytics?: AnalyticsApi; } -// в эффекторе кривые тайпинги +// пары [store, значение] для засева дополнительных значений в scope // eslint-disable-next-line @typescript-eslint/no-explicit-any -export type ExtraValues = StorePair[]; +export type ExtraValues = (readonly [StoreWritable, unknown])[]; export const createScope = (deps: StoreDependencies, extraValues: ExtraValues) => { - return fork({ + return scope({ values: [[$deps, deps], ...extraValues], }); }; +// фабрика эффектов, которым нужен доступ к зависимостям приложения (api/ls/analytics). +// deps подтягиваются из $deps через attach, поэтому хендлер остаётся чистой функцией. export const createSpecBoxEffect = ( handler: (params: Params, deps: StoreDependencies) => Promise, ): Effect => { - const requestFx = attach({ + return attach({ source: $deps, - mapParams: (params: Params, deps: StoreDependencies) => ({ params, deps }), - effect: createEffect<{ params: Params; deps: StoreDependencies }, Done, Fail>( - ({ params, deps }) => handler(params, deps), - ), + effect: (deps, params) => handler(params, deps), }); - - return requestFx; }; diff --git a/src/pages/Home/Home.tsx b/src/pages/Home/Home.tsx index bd53863..1c3c822 100644 --- a/src/pages/Home/Home.tsx +++ b/src/pages/Home/Home.tsx @@ -1,4 +1,4 @@ -import { useUnit } from 'effector-react'; +import { useUnit } from '@virentia/react'; import { FC } from 'react'; import { useTitle } from '@/hooks/useTitle'; diff --git a/src/pages/Project/Project.tsx b/src/pages/Project/Project.tsx index 20b4b31..cdb3c44 100644 --- a/src/pages/Project/Project.tsx +++ b/src/pages/Project/Project.tsx @@ -1,4 +1,4 @@ -import { useUnit } from 'effector-react'; +import { useUnit } from '@virentia/react'; import { FC, useCallback } from 'react'; import { FeatureCard } from '@/components/FeatureCard/FeatureCard'; diff --git a/src/pages/Stat/Stat.tsx b/src/pages/Stat/Stat.tsx index ee8d905..e732468 100644 --- a/src/pages/Stat/Stat.tsx +++ b/src/pages/Stat/Stat.tsx @@ -1,4 +1,4 @@ -import { useUnit } from 'effector-react'; +import { useUnit } from '@virentia/react'; import { FC } from 'react'; import { cn } from '@bem-react/classname';