diff --git a/package.json b/package.json index a2739d1..46e62f9 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "tailwind-merge": "^2.5.4", "trystero": "^0.20.0", "type-fest": "^4.26.1", - "unstorage": "1.12.0", + "unstorage": "^1.13.1", "valibot": "1.0.0-beta.0" }, "devDependencies": { @@ -102,8 +102,8 @@ "@semantic-release/exec": "^6.0.3", "@semantic-release/git": "^10.0.1", "@types/eslint": "^9.6.1", - "@types/eslint__js": "^8.42.3", "@types/eslint-plugin-tailwindcss": "^3.17.0", + "@types/eslint__js": "^8.42.3", "@types/node": "^22.8.7", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6ddfd3f..4d47e50 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -147,8 +147,8 @@ importers: specifier: ^4.26.1 version: 4.26.1 unstorage: - specifier: 1.12.0 - version: 1.12.0(idb-keyval@6.2.1) + specifier: ^1.13.1 + version: 1.13.1(idb-keyval@6.2.1) valibot: specifier: 1.0.0-beta.0 version: 1.0.0-beta.0(typescript@5.6.3) @@ -1126,86 +1126,92 @@ packages: '@octokit/types@13.6.1': resolution: {integrity: sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==} - '@parcel/watcher-android-arm64@2.4.1': - resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==} + '@parcel/watcher-android-arm64@2.5.0': + resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [android] - '@parcel/watcher-darwin-arm64@2.4.1': - resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==} + '@parcel/watcher-darwin-arm64@2.5.0': + resolution: {integrity: sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [darwin] - '@parcel/watcher-darwin-x64@2.4.1': - resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==} + '@parcel/watcher-darwin-x64@2.5.0': + resolution: {integrity: sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [darwin] - '@parcel/watcher-freebsd-x64@2.4.1': - resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==} + '@parcel/watcher-freebsd-x64@2.5.0': + resolution: {integrity: sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [freebsd] - '@parcel/watcher-linux-arm-glibc@2.4.1': - resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==} + '@parcel/watcher-linux-arm-glibc@2.5.0': + resolution: {integrity: sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] - '@parcel/watcher-linux-arm64-glibc@2.4.1': - resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==} + '@parcel/watcher-linux-arm-musl@2.5.0': + 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'} cpu: [arm64] os: [linux] - '@parcel/watcher-linux-arm64-musl@2.4.1': - resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==} + '@parcel/watcher-linux-arm64-musl@2.5.0': + resolution: {integrity: sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] - '@parcel/watcher-linux-x64-glibc@2.4.1': - resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==} + '@parcel/watcher-linux-x64-glibc@2.5.0': + resolution: {integrity: sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] - '@parcel/watcher-linux-x64-musl@2.4.1': - resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==} + '@parcel/watcher-linux-x64-musl@2.5.0': + resolution: {integrity: sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] - '@parcel/watcher-wasm@2.4.1': - resolution: {integrity: sha512-/ZR0RxqxU/xxDGzbzosMjh4W6NdYFMqq2nvo2b8SLi7rsl/4jkL8S5stIikorNkdR50oVDvqb/3JT05WM+CRRA==} + '@parcel/watcher-wasm@2.5.0': + resolution: {integrity: sha512-Z4ouuR8Pfggk1EYYbTaIoxc+Yv4o7cGQnH0Xy8+pQ+HbiW+ZnwhcD2LPf/prfq1nIWpAxjOkQ8uSMFWMtBLiVQ==} engines: {node: '>= 10.0.0'} bundledDependencies: - napi-wasm - '@parcel/watcher-win32-arm64@2.4.1': - resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==} + '@parcel/watcher-win32-arm64@2.5.0': + resolution: {integrity: sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [win32] - '@parcel/watcher-win32-ia32@2.4.1': - resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==} + '@parcel/watcher-win32-ia32@2.5.0': + resolution: {integrity: sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==} engines: {node: '>= 10.0.0'} cpu: [ia32] os: [win32] - '@parcel/watcher-win32-x64@2.4.1': - resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==} + '@parcel/watcher-win32-x64@2.5.0': + resolution: {integrity: sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [win32] - '@parcel/watcher@2.4.1': - resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==} + '@parcel/watcher@2.5.0': + resolution: {integrity: sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==} engines: {node: '>= 10.0.0'} '@perfsee/jsonr@1.13.0': @@ -2835,13 +2841,8 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} - crossws@0.2.4: - resolution: {integrity: sha512-DAxroI2uSOgUKLz00NX6A8U/8EE3SZHmIND+10jkVSaypvyt57J5JEOxAQOL6lQxyzi/wZbTIwssU1uy69h5Vg==} - peerDependencies: - uWebSockets.js: '*' - peerDependenciesMeta: - uWebSockets.js: - optional: true + crossws@0.3.1: + resolution: {integrity: sha512-HsZgeVYaG+b5zA+9PbIPGq4+J/CJynJuearykPsXx4V/eMhyQ5EDVg3Ak2FBZtVXCiOLu/U7IiwDHTr9MA+IKw==} crypto-random-string@4.0.0: resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} @@ -3663,8 +3664,8 @@ packages: growly@1.3.0: resolution: {integrity: sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==} - h3@1.12.0: - resolution: {integrity: sha512-Zi/CcNeWBXDrFNlV0hUBJQR9F7a96RjMeAZweW/ZWkR9fuXrMcvKnSA63f/zZ9l0GgQOZDVHGvXivNN9PWOwhA==} + h3@1.13.0: + resolution: {integrity: sha512-vFEAu/yf8UMUcB4s43OaDaigcqpQd14yanmOsn+NcRX3/guSKncyE2rOYhq8RIchgJrPSs/QiIddnTTR1ddiAg==} handlebars@4.7.8: resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} @@ -4334,8 +4335,8 @@ packages: engines: {node: '>=18.12.0'} hasBin: true - listhen@1.7.2: - resolution: {integrity: sha512-7/HamOm5YD9Wb7CFgAZkKgVPA96WwhcTQoqtm2VTZGVbVVn3IWKRBTgrU7cchA3Q8k9iCsG8Osoi9GX4JsGM9g==} + listhen@1.9.0: + resolution: {integrity: sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg==} hasBin: true listr2@8.2.4: @@ -4739,10 +4740,6 @@ packages: engines: {node: '>=16.0.0'} hasBin: true - mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} - ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -5012,6 +5009,9 @@ packages: ofetch@1.3.4: resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==} + ofetch@1.4.1: + resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + ohash@1.1.4: resolution: {integrity: sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==} @@ -6351,19 +6351,19 @@ packages: webpack-sources: optional: true - unstorage@1.12.0: - resolution: {integrity: sha512-ARZYTXiC+e8z3lRM7/qY9oyaOkaozCeNd2xoz7sYK9fv7OLGhVsf+BZbmASqiK/HTZ7T6eAlnVq9JynZppyk3w==} + unstorage@1.13.1: + resolution: {integrity: sha512-ELexQHUrG05QVIM/iUeQNdl9FXDZhqLJ4yP59fnmn2jGUh0TEulwOgov1ubOb3Gt2ZGK/VMchJwPDNVEGWQpRg==} peerDependencies: '@azure/app-configuration': ^1.7.0 '@azure/cosmos': ^4.1.1 '@azure/data-tables': ^13.2.2 - '@azure/identity': ^4.4.1 - '@azure/keyvault-secrets': ^4.8.0 - '@azure/storage-blob': ^12.24.0 + '@azure/identity': ^4.5.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.25.0 '@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 - '@upstash/redis': ^1.34.0 + '@upstash/redis': ^1.34.3 '@vercel/kv': ^1.0.1 idb-keyval: ^6.2.1 ioredis: ^5.4.1 @@ -7998,66 +7998,70 @@ snapshots: dependencies: '@octokit/openapi-types': 22.2.0 - '@parcel/watcher-android-arm64@2.4.1': + '@parcel/watcher-android-arm64@2.5.0': optional: true - '@parcel/watcher-darwin-arm64@2.4.1': + '@parcel/watcher-darwin-arm64@2.5.0': optional: true - '@parcel/watcher-darwin-x64@2.4.1': + '@parcel/watcher-darwin-x64@2.5.0': optional: true - '@parcel/watcher-freebsd-x64@2.4.1': + '@parcel/watcher-freebsd-x64@2.5.0': optional: true - '@parcel/watcher-linux-arm-glibc@2.4.1': + '@parcel/watcher-linux-arm-glibc@2.5.0': optional: true - '@parcel/watcher-linux-arm64-glibc@2.4.1': + '@parcel/watcher-linux-arm-musl@2.5.0': optional: true - '@parcel/watcher-linux-arm64-musl@2.4.1': + '@parcel/watcher-linux-arm64-glibc@2.5.0': optional: true - '@parcel/watcher-linux-x64-glibc@2.4.1': + '@parcel/watcher-linux-arm64-musl@2.5.0': optional: true - '@parcel/watcher-linux-x64-musl@2.4.1': + '@parcel/watcher-linux-x64-glibc@2.5.0': 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: is-glob: 4.0.3 micromatch: 4.0.8 - '@parcel/watcher-win32-arm64@2.4.1': + '@parcel/watcher-win32-arm64@2.5.0': optional: true - '@parcel/watcher-win32-ia32@2.4.1': + '@parcel/watcher-win32-ia32@2.5.0': optional: true - '@parcel/watcher-win32-x64@2.4.1': + '@parcel/watcher-win32-x64@2.5.0': optional: true - '@parcel/watcher@2.4.1': + '@parcel/watcher@2.5.0': dependencies: detect-libc: 1.0.3 is-glob: 4.0.3 micromatch: 4.0.8 node-addon-api: 7.1.1 optionalDependencies: - '@parcel/watcher-android-arm64': 2.4.1 - '@parcel/watcher-darwin-arm64': 2.4.1 - '@parcel/watcher-darwin-x64': 2.4.1 - '@parcel/watcher-freebsd-x64': 2.4.1 - '@parcel/watcher-linux-arm-glibc': 2.4.1 - '@parcel/watcher-linux-arm64-glibc': 2.4.1 - '@parcel/watcher-linux-arm64-musl': 2.4.1 - '@parcel/watcher-linux-x64-glibc': 2.4.1 - '@parcel/watcher-linux-x64-musl': 2.4.1 - '@parcel/watcher-win32-arm64': 2.4.1 - '@parcel/watcher-win32-ia32': 2.4.1 - '@parcel/watcher-win32-x64': 2.4.1 + '@parcel/watcher-android-arm64': 2.5.0 + '@parcel/watcher-darwin-arm64': 2.5.0 + '@parcel/watcher-darwin-x64': 2.5.0 + '@parcel/watcher-freebsd-x64': 2.5.0 + '@parcel/watcher-linux-arm-glibc': 2.5.0 + '@parcel/watcher-linux-arm-musl': 2.5.0 + '@parcel/watcher-linux-arm64-glibc': 2.5.0 + '@parcel/watcher-linux-arm64-musl': 2.5.0 + '@parcel/watcher-linux-x64-glibc': 2.5.0 + '@parcel/watcher-linux-x64-musl': 2.5.0 + '@parcel/watcher-win32-arm64': 2.5.0 + '@parcel/watcher-win32-ia32': 2.5.0 + '@parcel/watcher-win32-x64': 2.5.0 '@perfsee/jsonr@1.13.0': dependencies: @@ -9847,7 +9851,9 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - crossws@0.2.4: {} + crossws@0.3.1: + dependencies: + uncrypto: 0.1.3 crypto-random-string@4.0.0: dependencies: @@ -10890,10 +10896,10 @@ snapshots: growly@1.3.0: {} - h3@1.12.0: + h3@1.13.0: dependencies: cookie-es: 1.2.2 - crossws: 0.2.4 + crossws: 0.3.1 defu: 6.1.4 destr: 2.0.3 iron-webcrypto: 1.2.1 @@ -10902,8 +10908,6 @@ snapshots: ufo: 1.5.4 uncrypto: 0.1.3 unenv: 1.10.0 - transitivePeerDependencies: - - uWebSockets.js handlebars@4.7.8: dependencies: @@ -11559,19 +11563,19 @@ snapshots: transitivePeerDependencies: - supports-color - listhen@1.7.2: + listhen@1.9.0: dependencies: - '@parcel/watcher': 2.4.1 - '@parcel/watcher-wasm': 2.4.1 + '@parcel/watcher': 2.5.0 + '@parcel/watcher-wasm': 2.5.0 citty: 0.1.6 clipboardy: 4.0.0 consola: 3.2.3 - crossws: 0.2.4 + crossws: 0.3.1 defu: 6.1.4 get-port-please: 3.1.2 - h3: 1.12.0 + h3: 1.13.0 http-shutdown: 1.2.2 - jiti: 1.21.6 + jiti: 2.4.0 mlly: 1.7.1 node-forge: 1.3.1 pathe: 1.1.2 @@ -11579,8 +11583,6 @@ snapshots: ufo: 1.5.4 untun: 0.1.3 uqr: 0.1.2 - transitivePeerDependencies: - - uWebSockets.js listr2@8.2.4: dependencies: @@ -12192,8 +12194,6 @@ snapshots: - supports-color - utf-8-validate - mri@1.2.0: {} - ms@2.0.0: {} ms@2.1.3: {} @@ -12396,6 +12396,12 @@ snapshots: node-fetch-native: 1.6.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: {} once@1.4.0: @@ -13923,22 +13929,20 @@ snapshots: acorn: 8.12.1 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: anymatch: 3.1.3 chokidar: 3.6.0 + citty: 0.1.6 destr: 2.0.3 - h3: 1.12.0 - listhen: 1.7.2 + h3: 1.13.0 + listhen: 1.9.0 lru-cache: 10.4.3 - mri: 1.2.0 node-fetch-native: 1.6.4 - ofetch: 1.3.4 + ofetch: 1.4.1 ufo: 1.5.4 optionalDependencies: idb-keyval: 6.2.1 - transitivePeerDependencies: - - uWebSockets.js untildify@4.0.0: {} diff --git a/src/app/options/components/ProfileForm.tsx b/src/app/options/components/ProfileForm.tsx index b0dd482..f3bb1b0 100644 --- a/src/app/options/components/ProfileForm.tsx +++ b/src/app/options/components/ProfileForm.tsx @@ -32,9 +32,9 @@ const defaultUserInfo: UserInfo = { const formSchema = v.object({ id: v.string(), - createTime: v.number(), // Pure numeric strings will be converted to number // Issues: https://github.com/unjs/unstorage/issues/277 + createTime: v.number(), name: v.pipe( v.string(), v.trim(), diff --git a/src/domain/Room.ts b/src/domain/Room.ts index 5a17d97..421882b 100644 --- a/src/domain/Room.ts +++ b/src/domain/Room.ts @@ -281,7 +281,6 @@ const RoomDomain = Remesh.domain({ name: 'Room.SendSyncHistoryMessageCommand', impl: ({ get }, { peerId, lastMessageTime }: { peerId: string; lastMessageTime: number }) => { const self = get(SelfUserQuery()) - console.log('SendSyncHistoryMessageCommand', peerId, peerRoom.peerId) const historyMessages = get(messageListDomain.query.ListQuery()).filter( (message) => @@ -451,7 +450,6 @@ const RoomDomain = Remesh.domain({ } case SendType.SyncHistory: { - toast.success('Syncing history messages.') return of(...message.messages.map((message) => messageListDomain.command.UpsertItemCommand(message))) } diff --git a/src/domain/Toast.ts b/src/domain/Toast.ts index 47a0232..6ff3dc5 100644 --- a/src/domain/Toast.ts +++ b/src/domain/Toast.ts @@ -1,7 +1,7 @@ import { Remesh } from 'remesh' import ToastModule from './modules/Toast' -import RoomDomain from './Room' -import { map, merge } from 'rxjs' +import RoomDomain, { SendType } from './Room' +import { filter, map } from 'rxjs' const ToastDomain = Remesh.domain({ name: 'ToastDomain', @@ -11,17 +11,28 @@ const ToastDomain = Remesh.domain({ domain.effect({ name: 'Toast.OnRoomErrorEffect', impl: ({ fromEvent }) => { - const onRoomError$ = fromEvent(roomDomain.event.OnErrorEvent) - - const onError$ = merge(onRoomError$).pipe( + const onRoomError$ = fromEvent(roomDomain.event.OnErrorEvent).pipe( map((error) => { 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 } }) diff --git a/src/domain/impls/Storage.ts b/src/domain/impls/Storage.ts index b467c0f..feb14ca 100644 --- a/src/domain/impls/Storage.ts +++ b/src/domain/impls/Storage.ts @@ -7,7 +7,11 @@ import { webExtensionDriver } from '@/utils/webExtensionDriver' import { Storage } from '@/domain/externs/Storage' 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({ driver: localStorageDriver({ base: `${STORAGE_NAME}:` }) @@ -23,8 +27,8 @@ export const browserSyncStorage = createStorage({ export const LocalStorageImpl = LocalStorageExtern.impl({ name: STORAGE_NAME, - get: async (key) => JSONR.parse(await localStorage.getItem(key)), - set: (key, value) => localStorage.setItem(key, JSONR.stringify(value)!), + get: localStorage.getItem, + set: localStorage.setItem, remove: localStorage.removeItem, clear: localStorage.clear, watch: async (callback) => { @@ -46,8 +50,8 @@ export const LocalStorageImpl = LocalStorageExtern.impl({ export const IndexDBStorageImpl = IndexDBStorageExtern.impl({ name: STORAGE_NAME, - get: async (key) => JSONR.parse(await indexDBStorage.getItem(key)), - set: (key, value) => indexDBStorage.setItem(key, JSONR.stringify(value)), + get: indexDBStorage.getItem, + set: indexDBStorage.setItem, remove: indexDBStorage.removeItem, clear: indexDBStorage.clear, watch: indexDBStorage.watch as Storage['watch'], @@ -56,16 +60,8 @@ export const IndexDBStorageImpl = IndexDBStorageExtern.impl({ export const BrowserSyncStorageImpl = BrowserSyncStorageExtern.impl({ name: STORAGE_NAME, - get: async (key) => { - const value: any = await browserSyncStorage.getItem(key) - // Compatibility with old version data - try { - return JSONR.parse(value) - } catch { - return value - } - }, - set: (key, value) => browserSyncStorage.setItem(key, JSONR.stringify(value)), + get: browserSyncStorage.getItem, + set: browserSyncStorage.setItem, remove: browserSyncStorage.removeItem, clear: browserSyncStorage.clear, watch: browserSyncStorage.watch as Storage['watch'], diff --git a/src/utils/compressImage.ts b/src/utils/compressImage.ts index 39de7b0..7ea47c6 100644 --- a/src/utils/compressImage.ts +++ b/src/utils/compressImage.ts @@ -59,15 +59,21 @@ const compress = async ( const compressImage = async (options: Options) => { const { input, targetSize, toleranceSize = -1024 } = options + if (!['image/jpeg', 'image/png', 'image/webp'].includes(input.type)) { throw new Error('Only PNG, JPEG and WebP image are supported.') } - if (input.size <= targetSize) { - return input + if (toleranceSize % 1024 !== 0) { + throw new Error('Tolerance size must be a multiple of 1024.') } const outputType = options.outputType || (input.type as ImageType) + + if (input.size <= targetSize && input.type === outputType) { + return input + } + const imageBitmap = await createImageBitmap(input) // Initialize quality range diff --git a/src/utils/generateRandomAvatar.ts b/src/utils/generateRandomAvatar.ts index dbad10a..1add2b7 100644 --- a/src/utils/generateRandomAvatar.ts +++ b/src/utils/generateRandomAvatar.ts @@ -1,7 +1,7 @@ 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() // 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 ctx = canvas.getContext('2d') ctx?.drawImage(image, 0, 0) - const blob = await canvas.convertToBlob({ type: 'image/jpeg' }) + const blob = await canvas.convertToBlob({ type: outputType }) resolve(blob) } image.onerror = () => reject(new Error('Failed to load SVG')) 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((resolve, reject) => { const reader = new FileReader() reader.onload = (e) => resolve(e.target?.result as string)