Merge branch 'develop'

This commit is contained in:
molvqingtai 2024-11-06 18:18:32 +08:00
commit 7b1663fb9c
8 changed files with 147 additions and 132 deletions

View file

@ -90,7 +90,7 @@
"tailwind-merge": "^2.5.4", "tailwind-merge": "^2.5.4",
"trystero": "^0.20.0", "trystero": "^0.20.0",
"type-fest": "^4.26.1", "type-fest": "^4.26.1",
"unstorage": "1.12.0", "unstorage": "^1.13.1",
"valibot": "1.0.0-beta.0" "valibot": "1.0.0-beta.0"
}, },
"devDependencies": { "devDependencies": {
@ -102,8 +102,8 @@
"@semantic-release/exec": "^6.0.3", "@semantic-release/exec": "^6.0.3",
"@semantic-release/git": "^10.0.1", "@semantic-release/git": "^10.0.1",
"@types/eslint": "^9.6.1", "@types/eslint": "^9.6.1",
"@types/eslint__js": "^8.42.3",
"@types/eslint-plugin-tailwindcss": "^3.17.0", "@types/eslint-plugin-tailwindcss": "^3.17.0",
"@types/eslint__js": "^8.42.3",
"@types/node": "^22.8.7", "@types/node": "^22.8.7",
"@types/react": "^18.3.12", "@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1", "@types/react-dom": "^18.3.1",

View file

@ -147,8 +147,8 @@ importers:
specifier: ^4.26.1 specifier: ^4.26.1
version: 4.26.1 version: 4.26.1
unstorage: unstorage:
specifier: 1.12.0 specifier: ^1.13.1
version: 1.12.0(idb-keyval@6.2.1) version: 1.13.1(idb-keyval@6.2.1)
valibot: valibot:
specifier: 1.0.0-beta.0 specifier: 1.0.0-beta.0
version: 1.0.0-beta.0(typescript@5.6.3) version: 1.0.0-beta.0(typescript@5.6.3)
@ -1126,86 +1126,92 @@ packages:
'@octokit/types@13.6.1': '@octokit/types@13.6.1':
resolution: {integrity: sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==} resolution: {integrity: sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==}
'@parcel/watcher-android-arm64@2.4.1': '@parcel/watcher-android-arm64@2.5.0':
resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==} resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
'@parcel/watcher-darwin-arm64@2.4.1': '@parcel/watcher-darwin-arm64@2.5.0':
resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==} resolution: {integrity: sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@parcel/watcher-darwin-x64@2.4.1': '@parcel/watcher-darwin-x64@2.5.0':
resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==} resolution: {integrity: sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@parcel/watcher-freebsd-x64@2.4.1': '@parcel/watcher-freebsd-x64@2.5.0':
resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==} resolution: {integrity: sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
'@parcel/watcher-linux-arm-glibc@2.4.1': '@parcel/watcher-linux-arm-glibc@2.5.0':
resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==} resolution: {integrity: sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@parcel/watcher-linux-arm64-glibc@2.4.1': '@parcel/watcher-linux-arm-musl@2.5.0':
resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==} resolution: {integrity: sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==}
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
'@parcel/watcher-linux-arm64-glibc@2.5.0':
resolution: {integrity: sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@parcel/watcher-linux-arm64-musl@2.4.1': '@parcel/watcher-linux-arm64-musl@2.5.0':
resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==} resolution: {integrity: sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@parcel/watcher-linux-x64-glibc@2.4.1': '@parcel/watcher-linux-x64-glibc@2.5.0':
resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==} resolution: {integrity: sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@parcel/watcher-linux-x64-musl@2.4.1': '@parcel/watcher-linux-x64-musl@2.5.0':
resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==} resolution: {integrity: sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@parcel/watcher-wasm@2.4.1': '@parcel/watcher-wasm@2.5.0':
resolution: {integrity: sha512-/ZR0RxqxU/xxDGzbzosMjh4W6NdYFMqq2nvo2b8SLi7rsl/4jkL8S5stIikorNkdR50oVDvqb/3JT05WM+CRRA==} resolution: {integrity: sha512-Z4ouuR8Pfggk1EYYbTaIoxc+Yv4o7cGQnH0Xy8+pQ+HbiW+ZnwhcD2LPf/prfq1nIWpAxjOkQ8uSMFWMtBLiVQ==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
bundledDependencies: bundledDependencies:
- napi-wasm - napi-wasm
'@parcel/watcher-win32-arm64@2.4.1': '@parcel/watcher-win32-arm64@2.5.0':
resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==} resolution: {integrity: sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@parcel/watcher-win32-ia32@2.4.1': '@parcel/watcher-win32-ia32@2.5.0':
resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==} resolution: {integrity: sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
cpu: [ia32] cpu: [ia32]
os: [win32] os: [win32]
'@parcel/watcher-win32-x64@2.4.1': '@parcel/watcher-win32-x64@2.5.0':
resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==} resolution: {integrity: sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@parcel/watcher@2.4.1': '@parcel/watcher@2.5.0':
resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==} resolution: {integrity: sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==}
engines: {node: '>= 10.0.0'} engines: {node: '>= 10.0.0'}
'@perfsee/jsonr@1.13.0': '@perfsee/jsonr@1.13.0':
@ -2835,13 +2841,8 @@ packages:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
crossws@0.2.4: crossws@0.3.1:
resolution: {integrity: sha512-DAxroI2uSOgUKLz00NX6A8U/8EE3SZHmIND+10jkVSaypvyt57J5JEOxAQOL6lQxyzi/wZbTIwssU1uy69h5Vg==} resolution: {integrity: sha512-HsZgeVYaG+b5zA+9PbIPGq4+J/CJynJuearykPsXx4V/eMhyQ5EDVg3Ak2FBZtVXCiOLu/U7IiwDHTr9MA+IKw==}
peerDependencies:
uWebSockets.js: '*'
peerDependenciesMeta:
uWebSockets.js:
optional: true
crypto-random-string@4.0.0: crypto-random-string@4.0.0:
resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==}
@ -3663,8 +3664,8 @@ packages:
growly@1.3.0: growly@1.3.0:
resolution: {integrity: sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==} resolution: {integrity: sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==}
h3@1.12.0: h3@1.13.0:
resolution: {integrity: sha512-Zi/CcNeWBXDrFNlV0hUBJQR9F7a96RjMeAZweW/ZWkR9fuXrMcvKnSA63f/zZ9l0GgQOZDVHGvXivNN9PWOwhA==} resolution: {integrity: sha512-vFEAu/yf8UMUcB4s43OaDaigcqpQd14yanmOsn+NcRX3/guSKncyE2rOYhq8RIchgJrPSs/QiIddnTTR1ddiAg==}
handlebars@4.7.8: handlebars@4.7.8:
resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==}
@ -4334,8 +4335,8 @@ packages:
engines: {node: '>=18.12.0'} engines: {node: '>=18.12.0'}
hasBin: true hasBin: true
listhen@1.7.2: listhen@1.9.0:
resolution: {integrity: sha512-7/HamOm5YD9Wb7CFgAZkKgVPA96WwhcTQoqtm2VTZGVbVVn3IWKRBTgrU7cchA3Q8k9iCsG8Osoi9GX4JsGM9g==} resolution: {integrity: sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg==}
hasBin: true hasBin: true
listr2@8.2.4: listr2@8.2.4:
@ -4739,10 +4740,6 @@ packages:
engines: {node: '>=16.0.0'} engines: {node: '>=16.0.0'}
hasBin: true hasBin: true
mri@1.2.0:
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
engines: {node: '>=4'}
ms@2.0.0: ms@2.0.0:
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
@ -5012,6 +5009,9 @@ packages:
ofetch@1.3.4: ofetch@1.3.4:
resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==} resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==}
ofetch@1.4.1:
resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==}
ohash@1.1.4: ohash@1.1.4:
resolution: {integrity: sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==} resolution: {integrity: sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==}
@ -6351,19 +6351,19 @@ packages:
webpack-sources: webpack-sources:
optional: true optional: true
unstorage@1.12.0: unstorage@1.13.1:
resolution: {integrity: sha512-ARZYTXiC+e8z3lRM7/qY9oyaOkaozCeNd2xoz7sYK9fv7OLGhVsf+BZbmASqiK/HTZ7T6eAlnVq9JynZppyk3w==} resolution: {integrity: sha512-ELexQHUrG05QVIM/iUeQNdl9FXDZhqLJ4yP59fnmn2jGUh0TEulwOgov1ubOb3Gt2ZGK/VMchJwPDNVEGWQpRg==}
peerDependencies: peerDependencies:
'@azure/app-configuration': ^1.7.0 '@azure/app-configuration': ^1.7.0
'@azure/cosmos': ^4.1.1 '@azure/cosmos': ^4.1.1
'@azure/data-tables': ^13.2.2 '@azure/data-tables': ^13.2.2
'@azure/identity': ^4.4.1 '@azure/identity': ^4.5.0
'@azure/keyvault-secrets': ^4.8.0 '@azure/keyvault-secrets': ^4.9.0
'@azure/storage-blob': ^12.24.0 '@azure/storage-blob': ^12.25.0
'@capacitor/preferences': ^6.0.2 '@capacitor/preferences': ^6.0.2
'@netlify/blobs': ^6.5.0 || ^7.0.0 '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0
'@planetscale/database': ^1.19.0 '@planetscale/database': ^1.19.0
'@upstash/redis': ^1.34.0 '@upstash/redis': ^1.34.3
'@vercel/kv': ^1.0.1 '@vercel/kv': ^1.0.1
idb-keyval: ^6.2.1 idb-keyval: ^6.2.1
ioredis: ^5.4.1 ioredis: ^5.4.1
@ -7998,66 +7998,70 @@ snapshots:
dependencies: dependencies:
'@octokit/openapi-types': 22.2.0 '@octokit/openapi-types': 22.2.0
'@parcel/watcher-android-arm64@2.4.1': '@parcel/watcher-android-arm64@2.5.0':
optional: true optional: true
'@parcel/watcher-darwin-arm64@2.4.1': '@parcel/watcher-darwin-arm64@2.5.0':
optional: true optional: true
'@parcel/watcher-darwin-x64@2.4.1': '@parcel/watcher-darwin-x64@2.5.0':
optional: true optional: true
'@parcel/watcher-freebsd-x64@2.4.1': '@parcel/watcher-freebsd-x64@2.5.0':
optional: true optional: true
'@parcel/watcher-linux-arm-glibc@2.4.1': '@parcel/watcher-linux-arm-glibc@2.5.0':
optional: true optional: true
'@parcel/watcher-linux-arm64-glibc@2.4.1': '@parcel/watcher-linux-arm-musl@2.5.0':
optional: true optional: true
'@parcel/watcher-linux-arm64-musl@2.4.1': '@parcel/watcher-linux-arm64-glibc@2.5.0':
optional: true optional: true
'@parcel/watcher-linux-x64-glibc@2.4.1': '@parcel/watcher-linux-arm64-musl@2.5.0':
optional: true optional: true
'@parcel/watcher-linux-x64-musl@2.4.1': '@parcel/watcher-linux-x64-glibc@2.5.0':
optional: true optional: true
'@parcel/watcher-wasm@2.4.1': '@parcel/watcher-linux-x64-musl@2.5.0':
optional: true
'@parcel/watcher-wasm@2.5.0':
dependencies: dependencies:
is-glob: 4.0.3 is-glob: 4.0.3
micromatch: 4.0.8 micromatch: 4.0.8
'@parcel/watcher-win32-arm64@2.4.1': '@parcel/watcher-win32-arm64@2.5.0':
optional: true optional: true
'@parcel/watcher-win32-ia32@2.4.1': '@parcel/watcher-win32-ia32@2.5.0':
optional: true optional: true
'@parcel/watcher-win32-x64@2.4.1': '@parcel/watcher-win32-x64@2.5.0':
optional: true optional: true
'@parcel/watcher@2.4.1': '@parcel/watcher@2.5.0':
dependencies: dependencies:
detect-libc: 1.0.3 detect-libc: 1.0.3
is-glob: 4.0.3 is-glob: 4.0.3
micromatch: 4.0.8 micromatch: 4.0.8
node-addon-api: 7.1.1 node-addon-api: 7.1.1
optionalDependencies: optionalDependencies:
'@parcel/watcher-android-arm64': 2.4.1 '@parcel/watcher-android-arm64': 2.5.0
'@parcel/watcher-darwin-arm64': 2.4.1 '@parcel/watcher-darwin-arm64': 2.5.0
'@parcel/watcher-darwin-x64': 2.4.1 '@parcel/watcher-darwin-x64': 2.5.0
'@parcel/watcher-freebsd-x64': 2.4.1 '@parcel/watcher-freebsd-x64': 2.5.0
'@parcel/watcher-linux-arm-glibc': 2.4.1 '@parcel/watcher-linux-arm-glibc': 2.5.0
'@parcel/watcher-linux-arm64-glibc': 2.4.1 '@parcel/watcher-linux-arm-musl': 2.5.0
'@parcel/watcher-linux-arm64-musl': 2.4.1 '@parcel/watcher-linux-arm64-glibc': 2.5.0
'@parcel/watcher-linux-x64-glibc': 2.4.1 '@parcel/watcher-linux-arm64-musl': 2.5.0
'@parcel/watcher-linux-x64-musl': 2.4.1 '@parcel/watcher-linux-x64-glibc': 2.5.0
'@parcel/watcher-win32-arm64': 2.4.1 '@parcel/watcher-linux-x64-musl': 2.5.0
'@parcel/watcher-win32-ia32': 2.4.1 '@parcel/watcher-win32-arm64': 2.5.0
'@parcel/watcher-win32-x64': 2.4.1 '@parcel/watcher-win32-ia32': 2.5.0
'@parcel/watcher-win32-x64': 2.5.0
'@perfsee/jsonr@1.13.0': '@perfsee/jsonr@1.13.0':
dependencies: dependencies:
@ -9847,7 +9851,9 @@ snapshots:
shebang-command: 2.0.0 shebang-command: 2.0.0
which: 2.0.2 which: 2.0.2
crossws@0.2.4: {} crossws@0.3.1:
dependencies:
uncrypto: 0.1.3
crypto-random-string@4.0.0: crypto-random-string@4.0.0:
dependencies: dependencies:
@ -10890,10 +10896,10 @@ snapshots:
growly@1.3.0: {} growly@1.3.0: {}
h3@1.12.0: h3@1.13.0:
dependencies: dependencies:
cookie-es: 1.2.2 cookie-es: 1.2.2
crossws: 0.2.4 crossws: 0.3.1
defu: 6.1.4 defu: 6.1.4
destr: 2.0.3 destr: 2.0.3
iron-webcrypto: 1.2.1 iron-webcrypto: 1.2.1
@ -10902,8 +10908,6 @@ snapshots:
ufo: 1.5.4 ufo: 1.5.4
uncrypto: 0.1.3 uncrypto: 0.1.3
unenv: 1.10.0 unenv: 1.10.0
transitivePeerDependencies:
- uWebSockets.js
handlebars@4.7.8: handlebars@4.7.8:
dependencies: dependencies:
@ -11559,19 +11563,19 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
listhen@1.7.2: listhen@1.9.0:
dependencies: dependencies:
'@parcel/watcher': 2.4.1 '@parcel/watcher': 2.5.0
'@parcel/watcher-wasm': 2.4.1 '@parcel/watcher-wasm': 2.5.0
citty: 0.1.6 citty: 0.1.6
clipboardy: 4.0.0 clipboardy: 4.0.0
consola: 3.2.3 consola: 3.2.3
crossws: 0.2.4 crossws: 0.3.1
defu: 6.1.4 defu: 6.1.4
get-port-please: 3.1.2 get-port-please: 3.1.2
h3: 1.12.0 h3: 1.13.0
http-shutdown: 1.2.2 http-shutdown: 1.2.2
jiti: 1.21.6 jiti: 2.4.0
mlly: 1.7.1 mlly: 1.7.1
node-forge: 1.3.1 node-forge: 1.3.1
pathe: 1.1.2 pathe: 1.1.2
@ -11579,8 +11583,6 @@ snapshots:
ufo: 1.5.4 ufo: 1.5.4
untun: 0.1.3 untun: 0.1.3
uqr: 0.1.2 uqr: 0.1.2
transitivePeerDependencies:
- uWebSockets.js
listr2@8.2.4: listr2@8.2.4:
dependencies: dependencies:
@ -12192,8 +12194,6 @@ snapshots:
- supports-color - supports-color
- utf-8-validate - utf-8-validate
mri@1.2.0: {}
ms@2.0.0: {} ms@2.0.0: {}
ms@2.1.3: {} ms@2.1.3: {}
@ -12396,6 +12396,12 @@ snapshots:
node-fetch-native: 1.6.4 node-fetch-native: 1.6.4
ufo: 1.5.4 ufo: 1.5.4
ofetch@1.4.1:
dependencies:
destr: 2.0.3
node-fetch-native: 1.6.4
ufo: 1.5.4
ohash@1.1.4: {} ohash@1.1.4: {}
once@1.4.0: once@1.4.0:
@ -13923,22 +13929,20 @@ snapshots:
acorn: 8.12.1 acorn: 8.12.1
webpack-virtual-modules: 0.6.2 webpack-virtual-modules: 0.6.2
unstorage@1.12.0(idb-keyval@6.2.1): unstorage@1.13.1(idb-keyval@6.2.1):
dependencies: dependencies:
anymatch: 3.1.3 anymatch: 3.1.3
chokidar: 3.6.0 chokidar: 3.6.0
citty: 0.1.6
destr: 2.0.3 destr: 2.0.3
h3: 1.12.0 h3: 1.13.0
listhen: 1.7.2 listhen: 1.9.0
lru-cache: 10.4.3 lru-cache: 10.4.3
mri: 1.2.0
node-fetch-native: 1.6.4 node-fetch-native: 1.6.4
ofetch: 1.3.4 ofetch: 1.4.1
ufo: 1.5.4 ufo: 1.5.4
optionalDependencies: optionalDependencies:
idb-keyval: 6.2.1 idb-keyval: 6.2.1
transitivePeerDependencies:
- uWebSockets.js
untildify@4.0.0: {} untildify@4.0.0: {}

View file

@ -32,9 +32,9 @@ const defaultUserInfo: UserInfo = {
const formSchema = v.object({ const formSchema = v.object({
id: v.string(), id: v.string(),
createTime: v.number(),
// Pure numeric strings will be converted to number // Pure numeric strings will be converted to number
// Issues: https://github.com/unjs/unstorage/issues/277 // Issues: https://github.com/unjs/unstorage/issues/277
createTime: v.number(),
name: v.pipe( name: v.pipe(
v.string(), v.string(),
v.trim(), v.trim(),

View file

@ -281,7 +281,6 @@ const RoomDomain = Remesh.domain({
name: 'Room.SendSyncHistoryMessageCommand', name: 'Room.SendSyncHistoryMessageCommand',
impl: ({ get }, { peerId, lastMessageTime }: { peerId: string; lastMessageTime: number }) => { impl: ({ get }, { peerId, lastMessageTime }: { peerId: string; lastMessageTime: number }) => {
const self = get(SelfUserQuery()) const self = get(SelfUserQuery())
console.log('SendSyncHistoryMessageCommand', peerId, peerRoom.peerId)
const historyMessages = get(messageListDomain.query.ListQuery()).filter( const historyMessages = get(messageListDomain.query.ListQuery()).filter(
(message) => (message) =>
@ -451,7 +450,6 @@ const RoomDomain = Remesh.domain({
} }
case SendType.SyncHistory: { case SendType.SyncHistory: {
toast.success('Syncing history messages.')
return of(...message.messages.map((message) => messageListDomain.command.UpsertItemCommand(message))) return of(...message.messages.map((message) => messageListDomain.command.UpsertItemCommand(message)))
} }

View file

@ -1,7 +1,7 @@
import { Remesh } from 'remesh' import { Remesh } from 'remesh'
import ToastModule from './modules/Toast' import ToastModule from './modules/Toast'
import RoomDomain from './Room' import RoomDomain, { SendType } from './Room'
import { map, merge } from 'rxjs' import { filter, map } from 'rxjs'
const ToastDomain = Remesh.domain({ const ToastDomain = Remesh.domain({
name: 'ToastDomain', name: 'ToastDomain',
@ -11,17 +11,28 @@ const ToastDomain = Remesh.domain({
domain.effect({ domain.effect({
name: 'Toast.OnRoomErrorEffect', name: 'Toast.OnRoomErrorEffect',
impl: ({ fromEvent }) => { impl: ({ fromEvent }) => {
const onRoomError$ = fromEvent(roomDomain.event.OnErrorEvent) const onRoomError$ = fromEvent(roomDomain.event.OnErrorEvent).pipe(
const onError$ = merge(onRoomError$).pipe(
map((error) => { map((error) => {
return toastModule.command.ErrorCommand(error.message) return toastModule.command.ErrorCommand(error.message)
}) })
) )
return onError$ return onRoomError$
} }
}) })
domain.effect({
name: 'Toast.OnSyncHistoryEffect',
impl: ({ fromEvent }) => {
const onSyncHistory$ = fromEvent(roomDomain.event.OnMessageEvent).pipe(
filter((message) => message.type === SendType.SyncHistory),
map(() => toastModule.command.SuccessCommand('Syncing history messages.'))
)
return onSyncHistory$
}
})
return toastModule return toastModule
} }
}) })

View file

@ -7,7 +7,11 @@ import { webExtensionDriver } from '@/utils/webExtensionDriver'
import { Storage } from '@/domain/externs/Storage' import { Storage } from '@/domain/externs/Storage'
import { EVENT } from '@/constants/event' import { EVENT } from '@/constants/event'
import { JSONR } from '@/utils'
/**
* Waiting to be resolved
* @see https://github.com/unjs/unstorage/issues/277
* */
export const localStorage = createStorage({ export const localStorage = createStorage({
driver: localStorageDriver({ base: `${STORAGE_NAME}:` }) driver: localStorageDriver({ base: `${STORAGE_NAME}:` })
@ -23,8 +27,8 @@ export const browserSyncStorage = createStorage({
export const LocalStorageImpl = LocalStorageExtern.impl({ export const LocalStorageImpl = LocalStorageExtern.impl({
name: STORAGE_NAME, name: STORAGE_NAME,
get: async (key) => JSONR.parse(await localStorage.getItem(key)), get: localStorage.getItem,
set: (key, value) => localStorage.setItem(key, JSONR.stringify(value)!), set: localStorage.setItem,
remove: localStorage.removeItem, remove: localStorage.removeItem,
clear: localStorage.clear, clear: localStorage.clear,
watch: async (callback) => { watch: async (callback) => {
@ -46,8 +50,8 @@ export const LocalStorageImpl = LocalStorageExtern.impl({
export const IndexDBStorageImpl = IndexDBStorageExtern.impl({ export const IndexDBStorageImpl = IndexDBStorageExtern.impl({
name: STORAGE_NAME, name: STORAGE_NAME,
get: async (key) => JSONR.parse(await indexDBStorage.getItem(key)), get: indexDBStorage.getItem,
set: (key, value) => indexDBStorage.setItem(key, JSONR.stringify(value)), set: indexDBStorage.setItem,
remove: indexDBStorage.removeItem, remove: indexDBStorage.removeItem,
clear: indexDBStorage.clear, clear: indexDBStorage.clear,
watch: indexDBStorage.watch as Storage['watch'], watch: indexDBStorage.watch as Storage['watch'],
@ -56,16 +60,8 @@ export const IndexDBStorageImpl = IndexDBStorageExtern.impl({
export const BrowserSyncStorageImpl = BrowserSyncStorageExtern.impl({ export const BrowserSyncStorageImpl = BrowserSyncStorageExtern.impl({
name: STORAGE_NAME, name: STORAGE_NAME,
get: async (key) => { get: browserSyncStorage.getItem,
const value: any = await browserSyncStorage.getItem(key) set: browserSyncStorage.setItem,
// Compatibility with old version data
try {
return JSONR.parse(value)
} catch {
return value
}
},
set: (key, value) => browserSyncStorage.setItem(key, JSONR.stringify(value)),
remove: browserSyncStorage.removeItem, remove: browserSyncStorage.removeItem,
clear: browserSyncStorage.clear, clear: browserSyncStorage.clear,
watch: browserSyncStorage.watch as Storage['watch'], watch: browserSyncStorage.watch as Storage['watch'],

View file

@ -59,15 +59,21 @@ const compress = async (
const compressImage = async (options: Options) => { const compressImage = async (options: Options) => {
const { input, targetSize, toleranceSize = -1024 } = options const { input, targetSize, toleranceSize = -1024 } = options
if (!['image/jpeg', 'image/png', 'image/webp'].includes(input.type)) { if (!['image/jpeg', 'image/png', 'image/webp'].includes(input.type)) {
throw new Error('Only PNG, JPEG and WebP image are supported.') throw new Error('Only PNG, JPEG and WebP image are supported.')
} }
if (input.size <= targetSize) { if (toleranceSize % 1024 !== 0) {
return input throw new Error('Tolerance size must be a multiple of 1024.')
} }
const outputType = options.outputType || (input.type as ImageType) const outputType = options.outputType || (input.type as ImageType)
if (input.size <= targetSize && input.type === outputType) {
return input
}
const imageBitmap = await createImageBitmap(input) const imageBitmap = await createImageBitmap(input)
// Initialize quality range // Initialize quality range

View file

@ -1,7 +1,7 @@
import generateUglyAvatar from '@/lib/uglyAvatar' import generateUglyAvatar from '@/lib/uglyAvatar'
import compressImage from './compressImage' import compressImage, { ImageType } from './compressImage'
const generateRandomAvatar = async (targetSize: number) => { const generateRandomAvatar = async (targetSize: number, outputType: ImageType = 'image/webp') => {
const svgBlob = generateUglyAvatar() const svgBlob = generateUglyAvatar()
// compressImage can't directly compress svg, need to convert to jpeg first // compressImage can't directly compress svg, need to convert to jpeg first
@ -11,13 +11,13 @@ const generateRandomAvatar = async (targetSize: number) => {
const canvas = new OffscreenCanvas(image.width, image.height) const canvas = new OffscreenCanvas(image.width, image.height)
const ctx = canvas.getContext('2d') const ctx = canvas.getContext('2d')
ctx?.drawImage(image, 0, 0) ctx?.drawImage(image, 0, 0)
const blob = await canvas.convertToBlob({ type: 'image/jpeg' }) const blob = await canvas.convertToBlob({ type: outputType })
resolve(blob) resolve(blob)
} }
image.onerror = () => reject(new Error('Failed to load SVG')) image.onerror = () => reject(new Error('Failed to load SVG'))
image.src = URL.createObjectURL(svgBlob) image.src = URL.createObjectURL(svgBlob)
}) })
const miniAvatarBlob = await compressImage({ input: imageBlob, targetSize }) const miniAvatarBlob = await compressImage({ input: imageBlob, targetSize, outputType })
const miniAvatarBase64 = await new Promise<string>((resolve, reject) => { const miniAvatarBase64 = await new Promise<string>((resolve, reject) => {
const reader = new FileReader() const reader = new FileReader()
reader.onload = (e) => resolve(e.target?.result as string) reader.onload = (e) => resolve(e.target?.result as string)