build(deps):增加一些基本的项目配置和基础代码结构。

This commit is contained in:
徐涛 2023-03-08 08:44:52 +08:00
parent 715da9c889
commit f63e4f1e6f
16 changed files with 880 additions and 123 deletions

20
.editorconfig Normal file
View File

@ -0,0 +1,20 @@
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
charset = utf-8
spaces_around_operators = true
[*.rs]
indent_size = 4
indent_style = space
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
charset = utf-8
spaces_around_operators = true

34
.eslintrc.js Normal file
View File

@ -0,0 +1,34 @@
module.exports = {
root: true,
env: {
node: true,
browser: true,
commonjs: true,
es6: true,
amd: true
},
parser: '@typescript-eslint/parser',
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.eslint.json']
},
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking'
],
overrides: [
{
files: ['**/*.tsx', '**/*.ts', '**/*.js'],
rules: {
'@typescript-eslint/no-misused-promises': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/restrict-template-expressions': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/ban-ts-comment': 'off'
}
}
]
};

18
.prettierignore Normal file
View File

@ -0,0 +1,18 @@
*.min.js
/node_modules
/dist
# OS
.DS_Store
.idea
.editorconfig
.npmrc
package-lock.json
# Ignored suffix
*.log
*.md
*.svg
*.png
*ignore
## Built-files
.cache
dist

18
.prettierrc.json Normal file
View File

@ -0,0 +1,18 @@
{
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"trailingComma": "none",
"bracketSpacing": true,
"jsxBracketSameLine": false,
"arrowParens": "avoid",
"requirePragma": false,
"insertPragma": false,
"proseWrap": "preserve",
"htmlWhitespaceSensitivity": "css",
"endOfLine": "lf"
}

View File

@ -7,7 +7,8 @@
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"tauri": "tauri"
"tauri": "tauri",
"tauri-dev": "tauri dev"
},
"dependencies": {
"@emotion/css": "^11.10.6",
@ -21,17 +22,26 @@
"@mantine/nprogress": "^6.0.0",
"@tabler/icons-react": "^2.8.0",
"@tauri-apps/api": "^1.2.0",
"@tanstack/react-virtual": "3.0.0-beta.35",
"framer-motion": "^8.1.1",
"immer": "^9.0.17",
"ramda": "^0.28.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.8.2"
"react-router-dom": "^6.8.2",
"react-use": "^17.4.0",
"use-immer": "^0.8.1",
"zustand": "^4.2.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@tauri-apps/cli": "^1.2.2",
"@types/node": "^18.7.10",
"@types/ramda": "^0.28.20",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"@vitejs/plugin-react": "^3.0.0",
"typescript": "^4.6.4",
"vite": "^4.0.0"
}
}
}

353
pnpm-lock.yaml generated
View File

@ -1,6 +1,7 @@
lockfileVersion: 5.4
specifiers:
'@babel/core': ^7.0.0
'@emotion/css': ^11.10.6
'@emotion/react': ^11.10.6
'@emotion/styled': ^11.10.6
@ -11,17 +12,25 @@ specifiers:
'@mantine/notifications': ^6.0.0
'@mantine/nprogress': ^6.0.0
'@tabler/icons-react': ^2.8.0
'@tanstack/react-virtual': 3.0.0-beta.35
'@tauri-apps/api': ^1.2.0
'@tauri-apps/cli': ^1.2.2
'@types/node': ^18.7.10
'@types/ramda': ^0.28.20
'@types/react': ^18.0.15
'@types/react-dom': ^18.0.6
'@vitejs/plugin-react': ^3.0.0
framer-motion: ^8.1.1
immer: ^9.0.17
ramda: ^0.28.0
react: ^18.2.0
react-dom: ^18.2.0
react-router-dom: ^6.8.2
react-use: ^17.4.0
typescript: ^4.6.4
use-immer: ^0.8.1
vite: ^4.0.0
zustand: ^4.2.0
dependencies:
'@emotion/css': 11.10.6
@ -34,14 +43,23 @@ dependencies:
'@mantine/notifications': 6.0.0_uziugpv5zwkk3pqsn64qbjkxrm
'@mantine/nprogress': 6.0.0_uziugpv5zwkk3pqsn64qbjkxrm
'@tabler/icons-react': 2.8.0_react@18.2.0
'@tanstack/react-virtual': 3.0.0-beta.35_react@18.2.0
'@tauri-apps/api': 1.2.0
framer-motion: 8.5.5_biqbaboplfbrettd7655fr4n2y
immer: 9.0.19
ramda: 0.28.0
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
react-router-dom: 6.8.2_biqbaboplfbrettd7655fr4n2y
react-use: 17.4.0_biqbaboplfbrettd7655fr4n2y
use-immer: 0.8.1_immer@9.0.19+react@18.2.0
zustand: 4.3.6_immer@9.0.19+react@18.2.0
devDependencies:
'@babel/core': 7.21.0
'@tauri-apps/cli': 1.2.3
'@types/node': 18.14.6
'@types/ramda': 0.28.23
'@types/react': 18.0.28
'@types/react-dom': 18.0.11
'@vitejs/plugin-react': 3.1.0_vite@4.1.4
@ -319,12 +337,25 @@ packages:
resolution: {integrity: sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==}
dev: false
/@emotion/is-prop-valid/0.8.8:
resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==}
requiresBuild: true
dependencies:
'@emotion/memoize': 0.7.4
dev: false
optional: true
/@emotion/is-prop-valid/1.2.0:
resolution: {integrity: sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==}
dependencies:
'@emotion/memoize': 0.8.0
dev: false
/@emotion/memoize/0.7.4:
resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==}
dev: false
optional: true
/@emotion/memoize/0.8.0:
resolution: {integrity: sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==}
dev: false
@ -782,6 +813,53 @@ packages:
react: 18.2.0
dev: false
/@motionone/animation/10.15.1:
resolution: {integrity: sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==}
dependencies:
'@motionone/easing': 10.15.1
'@motionone/types': 10.15.1
'@motionone/utils': 10.15.1
tslib: 2.5.0
dev: false
/@motionone/dom/10.15.5:
resolution: {integrity: sha512-Xc5avlgyh3xukU9tydh9+8mB8+2zAq+WlLsC3eEIp7Ax7DnXgY7Bj/iv0a4X2R9z9ZFZiaXK3BO0xMYHKbAAdA==}
dependencies:
'@motionone/animation': 10.15.1
'@motionone/generators': 10.15.1
'@motionone/types': 10.15.1
'@motionone/utils': 10.15.1
hey-listen: 1.0.8
tslib: 2.5.0
dev: false
/@motionone/easing/10.15.1:
resolution: {integrity: sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw==}
dependencies:
'@motionone/utils': 10.15.1
tslib: 2.5.0
dev: false
/@motionone/generators/10.15.1:
resolution: {integrity: sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ==}
dependencies:
'@motionone/types': 10.15.1
'@motionone/utils': 10.15.1
tslib: 2.5.0
dev: false
/@motionone/types/10.15.1:
resolution: {integrity: sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA==}
dev: false
/@motionone/utils/10.15.1:
resolution: {integrity: sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw==}
dependencies:
'@motionone/types': 10.15.1
hey-listen: 1.0.8
tslib: 2.5.0
dev: false
/@radix-ui/number/1.0.0:
resolution: {integrity: sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==}
dependencies:
@ -913,6 +991,19 @@ packages:
resolution: {integrity: sha512-8diABuB3J+NEUtdwIXJF0bJSE5VpnnyzWeiZGFq/XlcTYJNEF+36ijiPNUGpsV/QXY6syesJKmmPkUUwD+LxdA==}
dev: false
/@tanstack/react-virtual/3.0.0-beta.35_react@18.2.0:
resolution: {integrity: sha512-x4dicQTGao3p7wA1bGJyKsbtabO6UJKNUJdMWbxzrdc9CvpFl+ASOBtQHReDRjjAy7Z5/4loTLle8RtZu+2c2A==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
'@tanstack/virtual-core': 3.0.0-beta.35
react: 18.2.0
dev: false
/@tanstack/virtual-core/3.0.0-beta.35:
resolution: {integrity: sha512-p+dNBkN70nz3RzsfJImpmg1eoEHoX3X49lOk1N4I6jtUttKzZ/0U2+LqDmErNa5q/ksWD45zegOU4MnHwKRp2w==}
dev: false
/@tauri-apps/api/1.2.0:
resolution: {integrity: sha512-lsI54KI6HGf7VImuf/T9pnoejfgkNoXveP14pVV7XarrQ46rOejIVJLFqHI9sRReJMGdh2YuCoI3cc/yCWCsrw==}
engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'}
@ -1015,6 +1106,10 @@ packages:
'@tauri-apps/cli-win32-x64-msvc': 1.2.3
dev: true
/@types/js-cookie/2.2.7:
resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==}
dev: false
/@types/node/18.14.6:
resolution: {integrity: sha512-93+VvleD3mXwlLI/xASjw0FzKcwzl3OdTCzm1LaRfqgS21gfFtK3zDXM5Op9TeeMsJVOaJ2VRDpT9q4Y3d0AvA==}
dev: true
@ -1026,6 +1121,12 @@ packages:
/@types/prop-types/15.7.5:
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
/@types/ramda/0.28.23:
resolution: {integrity: sha512-9TYWiwkew+mCMsL7jZ+kkzy6QXn8PL5/SKmBPmjgUlTpkokZWTBr+OhiIUDztpAEbslWyt24NNfEmZUBFmnXig==}
dependencies:
ts-toolbelt: 6.15.5
dev: true
/@types/react-dom/18.0.11:
resolution: {integrity: sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==}
dependencies:
@ -1058,6 +1159,10 @@ packages:
- supports-color
dev: true
/@xobotyi/scrollbar-width/1.9.5:
resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==}
dev: false
/ansi-styles/3.2.1:
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
engines: {node: '>=4'}
@ -1124,6 +1229,12 @@ packages:
/convert-source-map/1.9.0:
resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
/copy-to-clipboard/3.3.3:
resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==}
dependencies:
toggle-selection: 1.0.6
dev: false
/cosmiconfig/7.1.0:
resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
engines: {node: '>=10'}
@ -1135,6 +1246,20 @@ packages:
yaml: 1.10.2
dev: false
/css-in-js-utils/3.1.0:
resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==}
dependencies:
hyphenate-style-name: 1.0.4
dev: false
/css-tree/1.1.3:
resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==}
engines: {node: '>=8.0.0'}
dependencies:
mdn-data: 2.0.14
source-map: 0.6.1
dev: false
/csstype/3.0.9:
resolution: {integrity: sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==}
dev: false
@ -1175,6 +1300,12 @@ packages:
is-arrayish: 0.2.1
dev: false
/error-stack-parser/2.1.4:
resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==}
dependencies:
stackframe: 1.3.4
dev: false
/esbuild/0.16.17:
resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==}
engines: {node: '>=12'}
@ -1223,10 +1354,37 @@ packages:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
dev: false
/fast-loops/1.1.3:
resolution: {integrity: sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g==}
dev: false
/fast-shallow-equal/1.0.0:
resolution: {integrity: sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==}
dev: false
/fastest-stable-stringify/2.0.2:
resolution: {integrity: sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==}
dev: false
/find-root/1.1.0:
resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==}
dev: false
/framer-motion/8.5.5_biqbaboplfbrettd7655fr4n2y:
resolution: {integrity: sha512-5IDx5bxkjWHWUF3CVJoSyUVOtrbAxtzYBBowRE2uYI/6VYhkEBD+rbTHEGuUmbGHRj6YqqSfoG7Aa1cLyWCrBA==}
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
dependencies:
'@motionone/dom': 10.15.5
hey-listen: 1.0.8
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
tslib: 2.5.0
optionalDependencies:
'@emotion/is-prop-valid': 0.8.8
dev: false
/fsevents/2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@ -1263,12 +1421,24 @@ packages:
dependencies:
function-bind: 1.1.1
/hey-listen/1.0.8:
resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==}
dev: false
/hoist-non-react-statics/3.3.2:
resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
dependencies:
react-is: 16.13.1
dev: false
/hyphenate-style-name/1.0.4:
resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==}
dev: false
/immer/9.0.19:
resolution: {integrity: sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ==}
dev: false
/import-fresh/3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'}
@ -1277,6 +1447,13 @@ packages:
resolve-from: 4.0.0
dev: false
/inline-style-prefixer/6.0.4:
resolution: {integrity: sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg==}
dependencies:
css-in-js-utils: 3.1.0
fast-loops: 1.1.3
dev: false
/invariant/2.2.4:
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
dependencies:
@ -1292,6 +1469,10 @@ packages:
dependencies:
has: 1.0.3
/js-cookie/2.2.1:
resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==}
dev: false
/js-tokens/4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@ -1340,10 +1521,32 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.14
dev: true
/mdn-data/2.0.14:
resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==}
dev: false
/ms/2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: true
/nano-css/5.3.5_biqbaboplfbrettd7655fr4n2y:
resolution: {integrity: sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg==}
peerDependencies:
react: '*'
react-dom: '*'
dependencies:
css-tree: 1.1.3
csstype: 3.1.1
fastest-stable-stringify: 2.0.2
inline-style-prefixer: 6.0.4
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
rtl-css-js: 1.16.1
sourcemap-codec: 1.4.8
stacktrace-js: 2.0.2
stylis: 4.1.3
dev: false
/nanoid/3.3.4:
resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@ -1405,6 +1608,10 @@ packages:
react-is: 16.13.1
dev: false
/ramda/0.28.0:
resolution: {integrity: sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==}
dev: false
/react-dom/18.2.0_react@18.2.0:
resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==}
peerDependencies:
@ -1527,6 +1734,40 @@ packages:
react-dom: 18.2.0_react@18.2.0
dev: false
/react-universal-interface/0.6.2_react@18.2.0+tslib@2.5.0:
resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==}
peerDependencies:
react: '*'
tslib: '*'
dependencies:
react: 18.2.0
tslib: 2.5.0
dev: false
/react-use/17.4.0_biqbaboplfbrettd7655fr4n2y:
resolution: {integrity: sha512-TgbNTCA33Wl7xzIJegn1HndB4qTS9u03QUwyNycUnXaweZkE4Kq2SB+Yoxx8qbshkZGYBDvUXbXWRUmQDcZZ/Q==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
'@types/js-cookie': 2.2.7
'@xobotyi/scrollbar-width': 1.9.5
copy-to-clipboard: 3.3.3
fast-deep-equal: 3.1.3
fast-shallow-equal: 1.0.0
js-cookie: 2.2.1
nano-css: 5.3.5_biqbaboplfbrettd7655fr4n2y
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
react-universal-interface: 0.6.2_react@18.2.0+tslib@2.5.0
resize-observer-polyfill: 1.5.1
screenfull: 5.2.0
set-harmonic-interval: 1.0.1
throttle-debounce: 3.0.1
ts-easing: 0.2.0
tslib: 2.5.0
dev: false
/react/18.2.0:
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
engines: {node: '>=0.10.0'}
@ -1538,6 +1779,10 @@ packages:
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
dev: false
/resize-observer-polyfill/1.5.1:
resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
dev: false
/resolve-from/4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
@ -1559,27 +1804,83 @@ packages:
fsevents: 2.3.2
dev: true
/rtl-css-js/1.16.1:
resolution: {integrity: sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==}
dependencies:
'@babel/runtime': 7.21.0
dev: false
/scheduler/0.23.0:
resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==}
dependencies:
loose-envify: 1.4.0
dev: false
/screenfull/5.2.0:
resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==}
engines: {node: '>=0.10.0'}
dev: false
/semver/6.3.0:
resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
hasBin: true
dev: true
/set-harmonic-interval/1.0.1:
resolution: {integrity: sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==}
engines: {node: '>=6.9'}
dev: false
/source-map-js/1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
dev: true
/source-map/0.5.6:
resolution: {integrity: sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==}
engines: {node: '>=0.10.0'}
dev: false
/source-map/0.5.7:
resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==}
engines: {node: '>=0.10.0'}
dev: false
/source-map/0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
dev: false
/sourcemap-codec/1.4.8:
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
deprecated: Please use @jridgewell/sourcemap-codec instead
dev: false
/stack-generator/2.0.10:
resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==}
dependencies:
stackframe: 1.3.4
dev: false
/stackframe/1.3.4:
resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==}
dev: false
/stacktrace-gps/3.1.2:
resolution: {integrity: sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==}
dependencies:
source-map: 0.5.6
stackframe: 1.3.4
dev: false
/stacktrace-js/2.0.2:
resolution: {integrity: sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==}
dependencies:
error-stack-parser: 2.1.4
stack-generator: 2.0.10
stacktrace-gps: 3.1.2
dev: false
/stylis/4.1.3:
resolution: {integrity: sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==}
dev: false
@ -1598,10 +1899,27 @@ packages:
resolution: {integrity: sha512-4kl5w+nCB44EVRdO0g/UGoOp3vlwgycUVtkk/7DPyeLZUCuNFFKCFG6/t/DgHLrUPHjrZg6s5tNm+56Q2B0xyg==}
dev: false
/throttle-debounce/3.0.1:
resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==}
engines: {node: '>=10'}
dev: false
/to-fast-properties/2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'}
/toggle-selection/1.0.6:
resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==}
dev: false
/ts-easing/0.2.0:
resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==}
dev: false
/ts-toolbelt/6.15.5:
resolution: {integrity: sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==}
dev: true
/tslib/2.5.0:
resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==}
dev: false
@ -1646,6 +1964,16 @@ packages:
react: 18.2.0
dev: false
/use-immer/0.8.1_immer@9.0.19+react@18.2.0:
resolution: {integrity: sha512-OfTFf1pL+ICjjcLPn9+ZnaJO/Yg4MBzYZtACEe2mZ/W2A5col28PNUnwowOAaBuOogACOK/37TU17KgsIhUpOw==}
peerDependencies:
immer: '>=2.0.0'
react: ^16.8.0 || ^17.0.1 || ^18.0.0
dependencies:
immer: 9.0.19
react: 18.2.0
dev: false
/use-isomorphic-layout-effect/1.1.2_pmekkgnqduwlme35zpnqhenc34:
resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==}
peerDependencies:
@ -1689,6 +2017,14 @@ packages:
tslib: 2.5.0
dev: false
/use-sync-external-store/1.2.0_react@18.2.0:
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
react: 18.2.0
dev: false
/vite/4.1.4_@types+node@18.14.6:
resolution: {integrity: sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==}
engines: {node: ^14.18.0 || >=16.0.0}
@ -1731,3 +2067,20 @@ packages:
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
engines: {node: '>= 6'}
dev: false
/zustand/4.3.6_immer@9.0.19+react@18.2.0:
resolution: {integrity: sha512-6J5zDxjxLE+yukC2XZWf/IyWVKnXT9b9HUv09VJ/bwGCpKNcaTqp7Ws28Xr8jnbvnZcdRaidztAPsXFBIqufiw==}
engines: {node: '>=12.7.0'}
peerDependencies:
immer: '>=9.0'
react: '>=16.8'
peerDependenciesMeta:
immer:
optional: true
react:
optional: true
dependencies:
immer: 9.0.19
react: 18.2.0
use-sync-external-store: 1.2.0_react@18.2.0
dev: false

View File

@ -1,7 +0,0 @@
.logo.vite:hover {
filter: drop-shadow(0 0 2em #747bff);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafb);
}

15
src/MainLayout.tsx Normal file
View File

@ -0,0 +1,15 @@
import { Box, Group } from "@mantine/core";
import { FC } from "react";
import { Outlet } from "react-router-dom";
import { NavMenu } from "./NavMenu";
export const MainLayout: FC = () => {
return (
<Group grow noWrap spacing={0} h="100%" w="100%">
<NavMenu />
<Box h="inherit" w="inherit" maw="100%" sx={{ flexGrow: 5 }}>
<Outlet />
</Box>
</Group>
);
};

32
src/NavMenu.tsx Normal file
View File

@ -0,0 +1,32 @@
import { Stack, useMantineTheme } from "@mantine/core";
import { ifElse, path, propEq } from "ramda";
import { FC, useMemo } from "react";
const bgSelectFn = ifElse(
propEq("colorScheme", "dark"),
path(["colors", "cbg", 2]),
path(["colors", "cbg", 7])
);
export const NavMenu: FC = () => {
const theme = useMantineTheme();
const normalColor = useMemo(() => path(["violet", 7])(theme.colors), [theme.colors]);
const activatedColor = useMemo(() => path<string>(["violet", 3])(theme.colors), [theme.colors]);
const disabledColor = useMemo(() => path<string>(["gray", 7])(theme.colors), [theme.colors]);
const navMenuBg = useMemo(() => bgSelectFn(theme), [theme, theme]);
return (
<Stack
spacing={24}
maw={64}
h="inherit"
sx={(theme) => ({
flexGrow: 1,
backgroundColor: navMenuBg,
})}
align="center"
px={16}
py={16}
></Stack>
);
};

View File

@ -1,10 +1,30 @@
import React from "react";
import { NotificationsProvider } from "@mantine/notifications";
import React, { FC, useState } from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./styles.css";
import { RouterProvider } from "react-router-dom";
import { appRouter } from "./router";
import { useAppTheme } from "./theme";
const AppMain: FC = () => {
const preferredColorScheme = useColorScheme();
const [colorScheme, setColorScheme] = useState<ColorScheme>(preferredColorScheme);
const theme = useAppTheme();
return (
<React.StrictMode>
<ColorSchemeProvider colorScheme={colorScheme} toggleColorScheme={setColorScheme}>
<MantineProvider theme={theme} withGlobalStyles withNormalizeCSS>
<NotificationsProvider position="bottom-right" limit={5} zIndex={999}>
<RouterProvider router={appRouter} />
</NotificationsProvider>
</MantineProvider>
</ColorSchemeProvider>
</React.StrictMode>
);
};
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<App />
<AppMain />
</React.StrictMode>
);

9
src/router.tsx Normal file
View File

@ -0,0 +1,9 @@
import { createBrowserRouter } from "react-router-dom";
import { MainLayout } from "./MainLayout";
export const appRouter = createBrowserRouter([
{
path: "/",
element: <MainLayout />,
},
]);

View File

@ -1,109 +0,0 @@
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: #0f0f0f;
background-color: #f6f6f6;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
.container {
margin: 0;
padding-top: 10vh;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: 0.75s;
}
.logo.tauri:hover {
filter: drop-shadow(0 0 2em #24c8db);
}
.row {
display: flex;
justify-content: center;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
h1 {
text-align: center;
}
input,
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
color: #0f0f0f;
background-color: #ffffff;
transition: border-color 0.25s;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
}
button {
cursor: pointer;
}
button:hover {
border-color: #396cd8;
}
button:active {
border-color: #396cd8;
background-color: #e8e8e8;
}
input,
button {
outline: none;
}
#greet-input {
margin-right: 5px;
}
@media (prefers-color-scheme: dark) {
:root {
color: #f6f6f6;
background-color: #2f2f2f;
}
a:hover {
color: #24c8db;
}
input,
button {
color: #ffffff;
background-color: #0f0f0f98;
}
button:active {
background-color: #0f0f0f69;
}
}

61
src/theme.ts Normal file
View File

@ -0,0 +1,61 @@
import { MantineTheme } from '@mantine/core';
import { useColorScheme } from '@mantine/hooks';
import { ifElse, path, propEq } from 'ramda';
const bgColorSelectFn = ifElse(
propEq('colorScheme', 'light'),
path(['colors', 'cbg', 8]),
path(['colors', 'cbg', 0])
);
const fgColorSelectFn = ifElse(
propEq('colorScheme', 'light'),
path(['colors', 'cfg', 0]),
path(['colors', 'cfg', 8])
);
export function useAppTheme(): Partial<MantineTheme> {
const colorScheme = useColorScheme();
return {
colorScheme,
focusRing: 'never',
defaultRadius: 'xs',
colors: {
cfg: [
'#0f0f0f',
'#151515',
'#262626',
'#414141',
'#626262',
'#878787',
'#acacac',
'#cecece',
'#e8e8e8',
'#f9f9f9'
],
cbg: [
'#1a202c',
'#1e2533',
'#2a3446',
'#3c4a65',
'#53678b',
'#7689ad',
'#a0adc6',
'#c6cedd',
'#e5e8ef',
'#f8f9fb'
]
},
primaryColor: 'violet',
globalStyles: theme => ({
'html, body': {
height: '100vh',
color: fgColorSelectFn(theme),
backgroundColor: bgColorSelectFn(theme)
},
'#root': {
height: '100%'
}
})
};
}

216
src/types.ts Normal file
View File

@ -0,0 +1,216 @@
/**
*
*/
export type Factory<T> = () => T;
/**
*
*/
export type MapFactory<T, P = unknown> = (obj: P) => T;
/**
* 使
*/
export type MaybeParamFactory<T, P = unknown> = (obj?: P) => T;
/**
*
*/
export type ParamFactory<T, P = unknown> = (...args: P[]) => T;
/**
*
*/
export type ObjectCallback<P = string, T = void> = (obj: P) => T | Promise<T>;
/**
*
*/
export type SyncObjectCallback<P = string, T = void> = (obj: P) => T;
/**
*
*/
export type AsyncObjectCallback<P = string, T = void> = (obj: P) => Promise<T>;
/**
*
*/
export type MaybeObjectCallback<P = string, T = void> = ObjectCallback<P | undefined, T>;
/**
*
*/
export type SyncMaybeObjectCallback<P = string, T = void> = SyncObjectCallback<P | undefined, T>;
/**
*
*/
export type AsyncMaybeObjectCallback<P = string, T = void> = AsyncObjectCallback<P | undefined, T>;
/**
*
*/
export type ObjectsCallback<P = string, T = void> = ObjectCallback<P[], T>;
/**
*
*/
export type SyncObjectsCallback<P = string, T = void> = SyncObjectCallback<P[], T>;
/**
*
*/
export type AsyncObjectsCallback<P = string, T = void> = AsyncObjectCallback<P[], T>;
/**
*
*/
export type MaybeObjectsCallback<P = string, T = void> = ObjectCallback<P[] | undefined, T>;
/**
*
*/
export type SyncMaybeObjectsCallback<P = string, T = void> = SyncObjectCallback<P[] | undefined, T>;
/**
*
*/
export type AsyncMaybeObjectsCallback<P = string, T = void> = AsyncObjectCallback<
P[] | undefined,
T
>;
/**
*
*/
export type ExtendParamCallback<P = unknown, T = void> = (...args: P[]) => T | Promise<T>;
/**
*
*/
export type SyncExtendParamCallback<P = unknown, T = void> = (...args: P[]) => T;
/**
*
*/
export type AsyncExtendParamCallback<P = unknown, T = void> = (...args: P[]) => Promise<T>;
/**
*
*/
export type Callback<T = void> = () => T | Promise<T>;
/**
*
*/
export type SyncCallback<T = void> = () => T;
/**
*
*/
export type AsyncCallback<T = void> = () => Promise<T>;
/**
* Store中定义状态操作Action的无参同步Action类型
*/
export type SyncAction = SyncCallback<void>;
/**
* Store中定义状态操作Action的无参可异步Action类型
*/
export type AsyncAction = Callback<void>;
/**
* Store中定义状态操作Action的单一参数同步Action类型
*/
export type SyncParamAction<T> = SyncObjectCallback<T, void>;
/**
* Store中定义状态操作Action的单一参数异步Action类型
*/
export type AsyncParamAction<T> = AsyncObjectCallback<T, void>;
/**
* Store中定义状态操作Action的不定参同步Action类型
*/
export type SyncMaybeAction<T> = SyncMaybeObjectCallback<T>;
/**
* Store中定义状态操作Action的不定参可异步Action类型
*/
export type AsyncMaybeAction<T> = AsyncMaybeObjectCallback<T>;
/**
* Store中定义状态操作Action的展开参同步Action类型
*/
export type SyncExtendParamAction<T> = SyncExtendParamCallback<T>;
/**
* Store中定义状态操作Action的展开参可异步Action类型
*/
export type AsyncExtendParamAction<T> = AsyncExtendParamCallback<T>;
/**
* Ref组件
*/
export interface Resetable {
/**
*
*/
reset: Callback;
}
/**
* Ref组件
*/
export interface Openable {
/**
*
*/
open: Callback;
}
/**
* Ref组件
*/
export interface Closeable {
/**
*
*/
close: Callback;
}
/**
* Ref组件
*
*/
export interface Actionable<T = unknown> {
/**
*
*/
action?: ExtendParamCallback<T>;
}
/**
*
*/
export interface DirtyableValue<T> {
/**
*
*/
value: T;
/**
*
*/
lastValues: T[];
/**
*
*/
dirty: boolean;
}
/**
*
*/
export type Dirtyable<T> = { [P in keyof T]: DirtyableValue<T[P]> };

View File

@ -0,0 +1,56 @@
//@ts-nocheck
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { create, State, StateCreator, StoreApi, UseBoundStore } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface EnhancedStoreType<StoreType> {
use: {
[key in keyof StoreType]: () => StoreType[key];
};
reset: () => void;
}
type CreateStoreHookOptions = {
debug?: boolean;
};
/**
* Store Hook创建快速访问其中状态和Action的选择器
*/
function createSelectors<StoreType extends State>(
store: UseBoundStore<StoreApi<StoreType>>,
debug?: boolean
): UseBoundStore<StoreApi<StoreType>> & EnhancedStoreType<StoreType> {
const initialState = store.getState();
(store as unknown).use = {};
Object.keys(store.getState()).forEach(key => {
const selector = (state: StoreType) => state[key as keyof StoreType];
(store as unknown).use[key] = () => store(selector);
});
(store as unknown).reset = () => store.setState(initialState, true);
if (debug ?? false) {
store.subscribe((current, previous) => {
console.log('[状态调试]Action应用前: ', previous);
console.log('[状态调试]Action应用后: ', current);
});
}
return store as UseBoundStore<StoreType> & EnhancedStoreType<StoreType>;
}
/**
* 使Devtools和Immer中间件的Zustand创建Store Hook的函数
* 访Action的选择器
*/
export const createStoreHook = <
T extends State,
Mps extends [StoreMutatorIdentifier, unknown][] = [],
Mcs extends [StoreMutatorIdentifier, unknown][] = []
>(
initializer: StateCreator<T, [...Mps, ['zustand/immer', never]], Mcs>,
options?: CreateStoreHookOptions
): UseBoundStore<StoreApi<T>> & EnhancedStoreType<T> =>
createSelectors(create<T>()(immer(initializer)), options?.debug ?? false);

11
tsconfig.eslint.json Normal file
View File

@ -0,0 +1,11 @@
{
"extends": "./tsconfig.json",
"include": [
"./src",
".eslintrc.js",
],
"exclude": [
"node_modules",
"dist"
]
}