From e1224663a5dd634a4144afb669255ffe77f7cd9f Mon Sep 17 00:00:00 2001 From: Juliet Date: Sun, 23 Nov 2025 15:33:55 +0000 Subject: [PATCH] init --- package.json | 14 +- pnpm-lock.yaml | 379 +++++++++++++++++------------------- src/utils/types/lexicons.ts | 94 --------- src/views/record.tsx | 182 +++++++++++++---- 4 files changed, 329 insertions(+), 340 deletions(-) delete mode 100644 src/utils/types/lexicons.ts diff --git a/package.json b/package.json index cd61981..206af6d 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "serve": "vite preview" }, "devDependencies": { - "@iconify-json/lucide": "^1.2.73", + "@iconify-json/lucide": "^1.2.74", "@iconify/tailwind4": "^1.1.0", "@tailwindcss/vite": "^4.1.17", "prettier": "^3.6.2", @@ -17,7 +17,7 @@ "prettier-plugin-tailwindcss": "^0.7.1", "tailwindcss": "^4.1.17", "typescript": "^5.9.3", - "vite": "^7.2.2", + "vite": "^7.2.4", "vite-plugin-solid": "^2.11.10" }, "dependencies": { @@ -26,15 +26,13 @@ "@atcute/client": "^4.0.5", "@atcute/crypto": "^2.2.6", "@atcute/did-plc": "^0.2.0", - "@atcute/identity": "^1.1.2", + "@atcute/identity": "^1.1.3", "@atcute/identity-resolver": "^1.1.4", - "@atcute/leaflet": "^1.0.12", - "@atcute/lexicon-doc": "^1.3.0", - "@atcute/lexicon-resolver": "^0.1.3", - "@atcute/lexicons": "^1.2.3", + "@atcute/lexicon-doc": "^2.0.1", + "@atcute/lexicon-resolver": "^0.1.4", + "@atcute/lexicons": "^1.2.4", "@atcute/oauth-browser-client": "^2.0.1", "@atcute/repo": "^0.1.0", - "@atcute/tangled": "^1.0.12", "@atcute/tid": "^1.0.3", "@codemirror/commands": "^6.10.0", "@codemirror/lang-json": "^6.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 754c4f2..af63e94 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,32 +24,26 @@ importers: specifier: ^0.2.0 version: 0.2.0 '@atcute/identity': - specifier: ^1.1.2 - version: 1.1.2 + specifier: ^1.1.3 + version: 1.1.3 '@atcute/identity-resolver': specifier: ^1.1.4 - version: 1.1.4(@atcute/identity@1.1.2) - '@atcute/leaflet': - specifier: ^1.0.12 - version: 1.0.12 + version: 1.1.4(@atcute/identity@1.1.3) '@atcute/lexicon-doc': - specifier: ^1.3.0 - version: 1.3.0 + specifier: ^2.0.1 + version: 2.0.1 '@atcute/lexicon-resolver': - specifier: ^0.1.3 - version: 0.1.3(@atcute/identity-resolver@1.1.4(@atcute/identity@1.1.2))(@atcute/identity@1.1.2) + specifier: ^0.1.4 + version: 0.1.4(@atcute/identity-resolver@1.1.4(@atcute/identity@1.1.3))(@atcute/identity@1.1.3) '@atcute/lexicons': - specifier: ^1.2.3 - version: 1.2.3 + specifier: ^1.2.4 + version: 1.2.4 '@atcute/oauth-browser-client': specifier: ^2.0.1 version: 2.0.1 '@atcute/repo': specifier: ^0.1.0 version: 0.1.0 - '@atcute/tangled': - specifier: ^1.0.12 - version: 1.0.12 '@atcute/tid': specifier: ^1.0.3 version: 1.0.3 @@ -94,14 +88,14 @@ importers: version: 1.9.10 devDependencies: '@iconify-json/lucide': - specifier: ^1.2.73 - version: 1.2.73 + specifier: ^1.2.74 + version: 1.2.74 '@iconify/tailwind4': specifier: ^1.1.0 version: 1.1.0(tailwindcss@4.1.17) '@tailwindcss/vite': specifier: ^4.1.17 - version: 4.1.17(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)) + version: 4.1.17(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -118,11 +112,11 @@ importers: specifier: ^5.9.3 version: 5.9.3 vite: - specifier: ^7.2.2 - version: 7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2) + specifier: ^7.2.4 + version: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2) vite-plugin-solid: specifier: ^2.11.10 - version: 2.11.10(solid-js@1.9.10)(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)) + version: 2.11.10(solid-js@1.9.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)) packages: @@ -144,8 +138,8 @@ packages: '@atcute/car@5.0.0': resolution: {integrity: sha512-OIY2xTXv8lSpZsDSn/UYQtJSMvDw5Hi4Q+uyvmiqSM+fht08QRAEq/nxa5YFciPZ3nfDFnZ3//EgJw7QhkSXLQ==} - '@atcute/cbor@2.2.7': - resolution: {integrity: sha512-/mwAF0gnokOphceZqFq3uzMGdd8sbw5y6bxF8CRutRkCCUcpjjpJc5fkLwhxyGgOveF3mZuHE6p7t/+IAqb7Aw==} + '@atcute/cbor@2.2.8': + resolution: {integrity: sha512-UzOAN9BuN6JCXgn0ryV8qZuRJUDrNqrbLd6EFM8jc6RYssjRyGRxNy6RZ1NU/07Hd8Tq/0pz8+nQiMu5Zai5uw==} '@atcute/cid@2.2.6': resolution: {integrity: sha512-bTAHHbJ24p+E//V4KCS4xdmd39o211jJswvqQOevj7vk+5IYcgDLx1ryZWZ1sEPOo9x875li/kj5gpKL14RDwQ==} @@ -164,23 +158,20 @@ packages: peerDependencies: '@atcute/identity': ^1.0.0 - '@atcute/identity@1.1.2': - resolution: {integrity: sha512-vn0RN7SUF6N0sEPG9yyT6a0MzpfVS8BhsiLtB8OeS4qp2rLMQW33pelCpNitP1N+fq03MFlDGzs5p7K4qMs4cA==} + '@atcute/identity@1.1.3': + resolution: {integrity: sha512-oIqPoI8TwWeQxvcLmFEZLdN2XdWcaLVtlm8pNk0E72As9HNzzD9pwKPrLr3rmTLRIoULPPFmq9iFNsTeCIU9ng==} - '@atcute/leaflet@1.0.12': - resolution: {integrity: sha512-T5laBTl8vwzy0eZXBy07IQSjsLqhbZmRJsffnNQ6XMSc+lnCZ/NHfuKy8TNJbDU6dc26Z7o5l0ELfWz5QESo+w==} + '@atcute/lexicon-doc@2.0.1': + resolution: {integrity: sha512-yWgcBYkvifczVODZSgdVkIljzIfdh50t+QXjkDL/FSu2RP43NGBEZ5xfZqJcT68/UoyE+doSg0dhvOEIlVGU/A==} - '@atcute/lexicon-doc@1.3.0': - resolution: {integrity: sha512-92mW9mBVXMbchF+aZP9L/5aziE+wyzHKc8LJH8rp0vabwni+ajkKlCk0otrneCKUB21RsNIRMk0zTbTRKRBXrA==} - - '@atcute/lexicon-resolver@0.1.3': - resolution: {integrity: sha512-4AOS3KKm60GtBfl7ue/35xwZlylAuX5V2xmXnAmNoiN3vIauNkYawwRqgtni5q+EIV9R7p4D8tzkv58NaZ8fEQ==} + '@atcute/lexicon-resolver@0.1.4': + resolution: {integrity: sha512-8MAN3wrlP+PvyAbzHgzavaGeNNHq/r0LDEV4ABqDozHIZ2pcLR3O3J40UdiGW6ldeC/YciSkkmpl6f/zP3sXzw==} peerDependencies: '@atcute/identity': ^1.1.0 '@atcute/identity-resolver': ^1.1.3 - '@atcute/lexicons@1.2.3': - resolution: {integrity: sha512-ZNfNWS4jaR8VgWSSBaWRSSmwFeP134BmvpTt9JmM2x5vRoXeIFthxU9USY8ZV4vm0GPoxEMgkDin8HIlnFTg2w==} + '@atcute/lexicons@1.2.4': + resolution: {integrity: sha512-s6fl/SVjQMv7jiitLCcZ434X+VrTsJt7Fl9iJg8WXHJIELRz/U0sNUoP++oWd7bvPy1Vcd2Wnm+YtTm/Zn7AIQ==} '@atcute/mst@0.1.0': resolution: {integrity: sha512-h+iDToKEnBpigk2DOHjSqY63vJtjYKUIztqu1CZ0P+I54wV2SrgoqAXAT1xrW6A1Iup8cjTv+U2H5WVG4KxPLw==} @@ -194,9 +185,6 @@ packages: '@atcute/repo@0.1.0': resolution: {integrity: sha512-INiYAuma8dydBu7cqd2WVpcXh3mzhIepYBUqFWAK5MqMulPRLTRCc/9GW3G9pxYrOdlvLCVamG2Jf8XK0nuFEw==} - '@atcute/tangled@1.0.12': - resolution: {integrity: sha512-JKA5sOhd8SLhDFhY+PKHqLLytQBBKSiwcaEzfYUJBeyfvqXFPNNAwvRbe3VST4IQ3izoOu3O0R9/b1mjL45UzA==} - '@atcute/tid@1.0.3': resolution: {integrity: sha512-wfMJx1IMdnu0CZgWl0uR4JO2s6PGT1YPhpytD4ZHzEYKKQVuqV6Eb/7vieaVo1eYNMp2FrY67FZObeR7utRl2w==} @@ -294,8 +282,8 @@ packages: resolution: {integrity: sha512-4kdqcjyxo/8RQ8ayjms47HCWZIF5981oE5nIenbfThKDxWXtEHKipAOWlflpPJzZx9y/JWYQkp18Awr7VuepFg==} engines: {node: '>= 18'} - '@codemirror/autocomplete@6.19.1': - resolution: {integrity: sha512-q6NenYkEy2fn9+JyjIxMWcNjzTL/IhwqfzOut1/G3PrIFkrbl4AL7Wkse5tLrQUUyqGoAKU5+Pi5jnnXxH5HGw==} + '@codemirror/autocomplete@6.20.0': + resolution: {integrity: sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg==} '@codemirror/commands@6.10.0': resolution: {integrity: sha512-2xUIc5mHXQzT16JnyOFkh8PvfeXuIut3pslWGfsGOhxP/lpgRm9HOl/mpzLErgt5mXDovqA0d11P21gofRLb9w==} @@ -634,8 +622,8 @@ packages: '@codemirror/view': ^6.0.0 '@lezer/highlight': ^1.0.0 - '@iconify-json/lucide@1.2.73': - resolution: {integrity: sha512-++HFkqDNu4jqG5+vYT+OcVj9OiuPCw9wQuh8G5QWQnBRSJ9eKwSStiU8ORgOoK07xJsm/0VIHySMniXUUXP9Gw==} + '@iconify-json/lucide@1.2.74': + resolution: {integrity: sha512-vDoGHcDZdWgUbt9J3TCJlxFzX/Mw0vUIAoZdkfI2mINOi1/cgVZHivgZ8QtiGlepskTL3PcG8t93Ky/vtQgXGA==} '@iconify/tailwind4@1.1.0': resolution: {integrity: sha512-HqgAYtYk4eFtLvdYfhQrBRT9ohToh+VJJVhHtJ7B4Qhw+J+mRPvGC9Wr6Cgtb36YbIWqBxWuBaAUw9TE/8m2/w==} @@ -688,113 +676,113 @@ packages: '@noble/secp256k1@3.0.0': resolution: {integrity: sha512-NJBaR352KyIvj3t6sgT/+7xrNyF9Xk9QlLSIqUGVUYlsnDTAUqY8LOmwpcgEx4AMJXRITQ5XEVHD+mMaPfr3mg==} - '@rollup/rollup-android-arm-eabi@4.53.2': - resolution: {integrity: sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==} + '@rollup/rollup-android-arm-eabi@4.53.3': + resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.53.2': - resolution: {integrity: sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==} + '@rollup/rollup-android-arm64@4.53.3': + resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.53.2': - resolution: {integrity: sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==} + '@rollup/rollup-darwin-arm64@4.53.3': + resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.53.2': - resolution: {integrity: sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==} + '@rollup/rollup-darwin-x64@4.53.3': + resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.53.2': - resolution: {integrity: sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==} + '@rollup/rollup-freebsd-arm64@4.53.3': + resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.53.2': - resolution: {integrity: sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==} + '@rollup/rollup-freebsd-x64@4.53.3': + resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.53.2': - resolution: {integrity: sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==} + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': + resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.53.2': - resolution: {integrity: sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==} + '@rollup/rollup-linux-arm-musleabihf@4.53.3': + resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.53.2': - resolution: {integrity: sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==} + '@rollup/rollup-linux-arm64-gnu@4.53.3': + resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.53.2': - resolution: {integrity: sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==} + '@rollup/rollup-linux-arm64-musl@4.53.3': + resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.53.2': - resolution: {integrity: sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==} + '@rollup/rollup-linux-loong64-gnu@4.53.3': + resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.53.2': - resolution: {integrity: sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==} + '@rollup/rollup-linux-ppc64-gnu@4.53.3': + resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.53.2': - resolution: {integrity: sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==} + '@rollup/rollup-linux-riscv64-gnu@4.53.3': + resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.53.2': - resolution: {integrity: sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==} + '@rollup/rollup-linux-riscv64-musl@4.53.3': + resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.53.2': - resolution: {integrity: sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==} + '@rollup/rollup-linux-s390x-gnu@4.53.3': + resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.53.2': - resolution: {integrity: sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==} + '@rollup/rollup-linux-x64-gnu@4.53.3': + resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.53.2': - resolution: {integrity: sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==} + '@rollup/rollup-linux-x64-musl@4.53.3': + resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.53.2': - resolution: {integrity: sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==} + '@rollup/rollup-openharmony-arm64@4.53.3': + resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.53.2': - resolution: {integrity: sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==} + '@rollup/rollup-win32-arm64-msvc@4.53.3': + resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.53.2': - resolution: {integrity: sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==} + '@rollup/rollup-win32-ia32-msvc@4.53.3': + resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.53.2': - resolution: {integrity: sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==} + '@rollup/rollup-win32-x64-gnu@4.53.3': + resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.53.2': - resolution: {integrity: sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==} + '@rollup/rollup-win32-x64-msvc@4.53.3': + resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} cpu: [x64] os: [win32] @@ -957,8 +945,8 @@ packages: solid-js: optional: true - baseline-browser-mapping@2.8.28: - resolution: {integrity: sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==} + baseline-browser-mapping@2.8.30: + resolution: {integrity: sha512-aTUKW4ptQhS64+v2d6IkPzymEzzhw+G0bA1g3uBRV3+ntkH+svttKseW5IOR4Ed6NUVKqnY7qT3dKvzQ7io4AA==} hasBin: true boolbase@1.0.0: @@ -976,8 +964,8 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - caniuse-lite@1.0.30001755: - resolution: {integrity: sha512-44V+Jm6ctPj7R52Na4TLi3Zri4dWUljJd+RDm+j8LtNCc/ihLCT+X1TzoOAkRETEWqjuLnh9581Tl80FvK7jVA==} + caniuse-lite@1.0.30001756: + resolution: {integrity: sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A==} cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} @@ -1069,8 +1057,8 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - electron-to-chromium@1.5.254: - resolution: {integrity: sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg==} + electron-to-chromium@1.5.259: + resolution: {integrity: sha512-I+oLXgpEJzD6Cwuwt1gYjxsDmu/S/Kd41mmLA3O+/uH2pFRO/DvOjUyGozL8j3KeLV6WyZ7ssPwELMsXCcsJAQ==} encoding-sniffer@0.2.1: resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} @@ -1520,8 +1508,8 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - rollup@4.53.2: - resolution: {integrity: sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==} + rollup@4.53.3: + resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1617,8 +1605,8 @@ packages: '@testing-library/jest-dom': optional: true - vite@7.2.2: - resolution: {integrity: sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==} + vite@7.2.4: + resolution: {integrity: sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -1703,16 +1691,16 @@ snapshots: '@atcute/atproto@3.1.9': dependencies: - '@atcute/lexicons': 1.2.3 + '@atcute/lexicons': 1.2.4 '@atcute/bluesky@3.2.10': dependencies: '@atcute/atproto': 3.1.9 - '@atcute/lexicons': 1.2.3 + '@atcute/lexicons': 1.2.4 '@atcute/car@3.1.3': dependencies: - '@atcute/cbor': 2.2.7 + '@atcute/cbor': 2.2.8 '@atcute/cid': 2.2.6 '@atcute/uint8array': 1.0.5 '@atcute/varint': 1.0.3 @@ -1720,12 +1708,12 @@ snapshots: '@atcute/car@5.0.0': dependencies: - '@atcute/cbor': 2.2.7 + '@atcute/cbor': 2.2.8 '@atcute/cid': 2.2.6 '@atcute/uint8array': 1.0.5 '@atcute/varint': 1.0.3 - '@atcute/cbor@2.2.7': + '@atcute/cbor@2.2.8': dependencies: '@atcute/cid': 2.2.6 '@atcute/multibase': 1.1.6 @@ -1738,8 +1726,8 @@ snapshots: '@atcute/client@4.0.5': dependencies: - '@atcute/identity': 1.1.2 - '@atcute/lexicons': 1.2.3 + '@atcute/identity': 1.1.3 + '@atcute/lexicons': 1.2.4 '@atcute/crypto@2.2.6': dependencies: @@ -1749,60 +1737,52 @@ snapshots: '@atcute/did-plc@0.2.0': dependencies: - '@atcute/cbor': 2.2.7 + '@atcute/cbor': 2.2.8 '@atcute/cid': 2.2.6 '@atcute/crypto': 2.2.6 - '@atcute/identity': 1.1.2 - '@atcute/lexicons': 1.2.3 + '@atcute/identity': 1.1.3 + '@atcute/lexicons': 1.2.4 '@atcute/multibase': 1.1.6 '@atcute/uint8array': 1.0.5 '@badrap/valita': 0.4.6 - '@atcute/identity-resolver@1.1.4(@atcute/identity@1.1.2)': + '@atcute/identity-resolver@1.1.4(@atcute/identity@1.1.3)': dependencies: - '@atcute/identity': 1.1.2 - '@atcute/lexicons': 1.2.3 + '@atcute/identity': 1.1.3 + '@atcute/lexicons': 1.2.4 '@atcute/util-fetch': 1.0.3 '@badrap/valita': 0.4.6 - '@atcute/identity@1.1.2': + '@atcute/identity@1.1.3': dependencies: - '@atcute/lexicons': 1.2.3 + '@atcute/lexicons': 1.2.4 '@badrap/valita': 0.4.6 - '@atcute/leaflet@1.0.12': - dependencies: - '@atcute/atproto': 3.1.9 - '@atcute/lexicons': 1.2.3 - - '@atcute/lexicon-doc@1.3.0': + '@atcute/lexicon-doc@2.0.1': dependencies: - '@atcute/lexicons': 1.2.3 + '@atcute/identity': 1.1.3 + '@atcute/lexicons': 1.2.4 '@badrap/valita': 0.4.6 - '@atcute/lexicon-resolver@0.1.3(@atcute/identity-resolver@1.1.4(@atcute/identity@1.1.2))(@atcute/identity@1.1.2)': + '@atcute/lexicon-resolver@0.1.4(@atcute/identity-resolver@1.1.4(@atcute/identity@1.1.3))(@atcute/identity@1.1.3)': dependencies: - '@atcute/car': 5.0.0 - '@atcute/cbor': 2.2.7 - '@atcute/cid': 2.2.6 '@atcute/crypto': 2.2.6 - '@atcute/identity': 1.1.2 - '@atcute/identity-resolver': 1.1.4(@atcute/identity@1.1.2) - '@atcute/lexicon-doc': 1.3.0 - '@atcute/lexicons': 1.2.3 + '@atcute/identity': 1.1.3 + '@atcute/identity-resolver': 1.1.4(@atcute/identity@1.1.3) + '@atcute/lexicon-doc': 2.0.1 + '@atcute/lexicons': 1.2.4 '@atcute/repo': 0.1.0 - '@atcute/uint8array': 1.0.5 '@atcute/util-fetch': 1.0.3 '@badrap/valita': 0.4.6 - '@atcute/lexicons@1.2.3': + '@atcute/lexicons@1.2.4': dependencies: '@standard-schema/spec': 1.0.0 esm-env: 1.2.2 '@atcute/mst@0.1.0': dependencies: - '@atcute/cbor': 2.2.7 + '@atcute/cbor': 2.2.8 '@atcute/cid': 2.2.6 '@atcute/uint8array': 1.0.5 @@ -1813,9 +1793,9 @@ snapshots: '@atcute/oauth-browser-client@2.0.1': dependencies: '@atcute/client': 4.0.5 - '@atcute/identity': 1.1.2 - '@atcute/identity-resolver': 1.1.4(@atcute/identity@1.1.2) - '@atcute/lexicons': 1.2.3 + '@atcute/identity': 1.1.3 + '@atcute/identity-resolver': 1.1.4(@atcute/identity@1.1.3) + '@atcute/lexicons': 1.2.4 '@atcute/multibase': 1.1.6 '@atcute/uint8array': 1.0.5 nanoid: 5.1.6 @@ -1823,18 +1803,13 @@ snapshots: '@atcute/repo@0.1.0': dependencies: '@atcute/car': 5.0.0 - '@atcute/cbor': 2.2.7 + '@atcute/cbor': 2.2.8 '@atcute/cid': 2.2.6 '@atcute/crypto': 2.2.6 - '@atcute/lexicons': 1.2.3 + '@atcute/lexicons': 1.2.4 '@atcute/mst': 0.1.0 '@atcute/uint8array': 1.0.5 - '@atcute/tangled@1.0.12': - dependencies: - '@atcute/atproto': 3.1.9 - '@atcute/lexicons': 1.2.3 - '@atcute/tid@1.0.3': {} '@atcute/uint8array@1.0.5': {} @@ -1958,7 +1933,7 @@ snapshots: '@badrap/valita@0.4.6': {} - '@codemirror/autocomplete@6.19.1': + '@codemirror/autocomplete@6.20.0': dependencies: '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 @@ -2173,7 +2148,7 @@ snapshots: '@codemirror/view': 6.38.8 '@lezer/highlight': 1.2.3 - '@iconify-json/lucide@1.2.73': + '@iconify-json/lucide@1.2.74': dependencies: '@iconify/types': 2.0.0 @@ -2260,76 +2235,76 @@ snapshots: '@noble/secp256k1@3.0.0': {} - '@rollup/rollup-android-arm-eabi@4.53.2': + '@rollup/rollup-android-arm-eabi@4.53.3': optional: true - '@rollup/rollup-android-arm64@4.53.2': + '@rollup/rollup-android-arm64@4.53.3': optional: true - '@rollup/rollup-darwin-arm64@4.53.2': + '@rollup/rollup-darwin-arm64@4.53.3': optional: true - '@rollup/rollup-darwin-x64@4.53.2': + '@rollup/rollup-darwin-x64@4.53.3': optional: true - '@rollup/rollup-freebsd-arm64@4.53.2': + '@rollup/rollup-freebsd-arm64@4.53.3': optional: true - '@rollup/rollup-freebsd-x64@4.53.2': + '@rollup/rollup-freebsd-x64@4.53.3': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.53.2': + '@rollup/rollup-linux-arm-gnueabihf@4.53.3': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.53.2': + '@rollup/rollup-linux-arm-musleabihf@4.53.3': optional: true - '@rollup/rollup-linux-arm64-gnu@4.53.2': + '@rollup/rollup-linux-arm64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-arm64-musl@4.53.2': + '@rollup/rollup-linux-arm64-musl@4.53.3': optional: true - '@rollup/rollup-linux-loong64-gnu@4.53.2': + '@rollup/rollup-linux-loong64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.53.2': + '@rollup/rollup-linux-ppc64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.53.2': + '@rollup/rollup-linux-riscv64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-riscv64-musl@4.53.2': + '@rollup/rollup-linux-riscv64-musl@4.53.3': optional: true - '@rollup/rollup-linux-s390x-gnu@4.53.2': + '@rollup/rollup-linux-s390x-gnu@4.53.3': optional: true - '@rollup/rollup-linux-x64-gnu@4.53.2': + '@rollup/rollup-linux-x64-gnu@4.53.3': optional: true - '@rollup/rollup-linux-x64-musl@4.53.2': + '@rollup/rollup-linux-x64-musl@4.53.3': optional: true - '@rollup/rollup-openharmony-arm64@4.53.2': + '@rollup/rollup-openharmony-arm64@4.53.3': optional: true - '@rollup/rollup-win32-arm64-msvc@4.53.2': + '@rollup/rollup-win32-arm64-msvc@4.53.3': optional: true - '@rollup/rollup-win32-ia32-msvc@4.53.2': + '@rollup/rollup-win32-ia32-msvc@4.53.3': optional: true - '@rollup/rollup-win32-x64-gnu@4.53.2': + '@rollup/rollup-win32-x64-gnu@4.53.3': optional: true - '@rollup/rollup-win32-x64-msvc@4.53.2': + '@rollup/rollup-win32-x64-msvc@4.53.3': optional: true '@skyware/firehose@0.5.2': dependencies: '@atcute/car': 3.1.3 - '@atcute/cbor': 2.2.7 + '@atcute/cbor': 2.2.8 nanoevents: 9.1.0 '@solidjs/meta@0.29.4(solid-js@1.9.10)': @@ -2403,12 +2378,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.17 '@tailwindcss/oxide-win32-x64-msvc': 4.1.17 - '@tailwindcss/vite@4.1.17(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2))': + '@tailwindcss/vite@4.1.17(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2))': dependencies: '@tailwindcss/node': 4.1.17 '@tailwindcss/oxide': 4.1.17 tailwindcss: 4.1.17 - vite: 7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2) '@trysound/sax@0.2.0': {} @@ -2477,15 +2452,15 @@ snapshots: optionalDependencies: solid-js: 1.9.10 - baseline-browser-mapping@2.8.28: {} + baseline-browser-mapping@2.8.30: {} boolbase@1.0.0: {} browserslist@4.28.0: dependencies: - baseline-browser-mapping: 2.8.28 - caniuse-lite: 1.0.30001755 - electron-to-chromium: 1.5.254 + baseline-browser-mapping: 2.8.30 + caniuse-lite: 1.0.30001756 + electron-to-chromium: 1.5.259 node-releases: 2.0.27 update-browserslist-db: 1.1.4(browserslist@4.28.0) @@ -2496,7 +2471,7 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - caniuse-lite@1.0.30001755: {} + caniuse-lite@1.0.30001756: {} cheerio-select@2.1.0: dependencies: @@ -2525,7 +2500,7 @@ snapshots: codemirror@6.0.2: dependencies: - '@codemirror/autocomplete': 6.19.1 + '@codemirror/autocomplete': 6.20.0 '@codemirror/commands': 6.10.0 '@codemirror/language': 6.11.3 '@codemirror/lint': 6.9.2 @@ -2605,7 +2580,7 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - electron-to-chromium@1.5.254: {} + electron-to-chromium@1.5.259: {} encoding-sniffer@0.2.1: dependencies: @@ -3002,32 +2977,32 @@ snapshots: resolve-pkg-maps@1.0.0: optional: true - rollup@4.53.2: + rollup@4.53.3: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.53.2 - '@rollup/rollup-android-arm64': 4.53.2 - '@rollup/rollup-darwin-arm64': 4.53.2 - '@rollup/rollup-darwin-x64': 4.53.2 - '@rollup/rollup-freebsd-arm64': 4.53.2 - '@rollup/rollup-freebsd-x64': 4.53.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.53.2 - '@rollup/rollup-linux-arm-musleabihf': 4.53.2 - '@rollup/rollup-linux-arm64-gnu': 4.53.2 - '@rollup/rollup-linux-arm64-musl': 4.53.2 - '@rollup/rollup-linux-loong64-gnu': 4.53.2 - '@rollup/rollup-linux-ppc64-gnu': 4.53.2 - '@rollup/rollup-linux-riscv64-gnu': 4.53.2 - '@rollup/rollup-linux-riscv64-musl': 4.53.2 - '@rollup/rollup-linux-s390x-gnu': 4.53.2 - '@rollup/rollup-linux-x64-gnu': 4.53.2 - '@rollup/rollup-linux-x64-musl': 4.53.2 - '@rollup/rollup-openharmony-arm64': 4.53.2 - '@rollup/rollup-win32-arm64-msvc': 4.53.2 - '@rollup/rollup-win32-ia32-msvc': 4.53.2 - '@rollup/rollup-win32-x64-gnu': 4.53.2 - '@rollup/rollup-win32-x64-msvc': 4.53.2 + '@rollup/rollup-android-arm-eabi': 4.53.3 + '@rollup/rollup-android-arm64': 4.53.3 + '@rollup/rollup-darwin-arm64': 4.53.3 + '@rollup/rollup-darwin-x64': 4.53.3 + '@rollup/rollup-freebsd-arm64': 4.53.3 + '@rollup/rollup-freebsd-x64': 4.53.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.3 + '@rollup/rollup-linux-arm-musleabihf': 4.53.3 + '@rollup/rollup-linux-arm64-gnu': 4.53.3 + '@rollup/rollup-linux-arm64-musl': 4.53.3 + '@rollup/rollup-linux-loong64-gnu': 4.53.3 + '@rollup/rollup-linux-ppc64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-gnu': 4.53.3 + '@rollup/rollup-linux-riscv64-musl': 4.53.3 + '@rollup/rollup-linux-s390x-gnu': 4.53.3 + '@rollup/rollup-linux-x64-gnu': 4.53.3 + '@rollup/rollup-linux-x64-musl': 4.53.3 + '@rollup/rollup-openharmony-arm64': 4.53.3 + '@rollup/rollup-win32-arm64-msvc': 4.53.3 + '@rollup/rollup-win32-ia32-msvc': 4.53.3 + '@rollup/rollup-win32-x64-gnu': 4.53.3 + '@rollup/rollup-win32-x64-msvc': 4.53.3 fsevents: 2.3.3 safer-buffer@2.1.2: {} @@ -3111,7 +3086,7 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 - vite-plugin-solid@2.11.10(solid-js@1.9.10)(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)): + vite-plugin-solid@2.11.10(solid-js@1.9.10)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)): dependencies: '@babel/core': 7.28.5 '@types/babel__core': 7.20.5 @@ -3119,18 +3094,18 @@ snapshots: merge-anything: 5.1.7 solid-js: 1.9.10 solid-refresh: 0.6.3(solid-js@1.9.10) - vite: 7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2) - vitefu: 1.1.1(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2) + vitefu: 1.1.1(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)) transitivePeerDependencies: - supports-color - vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2): + vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.53.2 + rollup: 4.53.3 tinyglobby: 0.2.15 optionalDependencies: '@types/node': 24.10.1 @@ -3139,9 +3114,9 @@ snapshots: lightningcss: 1.30.2 tsx: 4.19.2 - vitefu@1.1.1(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)): + vitefu@1.1.1(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2)): optionalDependencies: - vite: 7.2.2(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.19.2) w3c-keyname@2.2.8: {} diff --git a/src/utils/types/lexicons.ts b/src/utils/types/lexicons.ts deleted file mode 100644 index 12b790b..0000000 --- a/src/utils/types/lexicons.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { - AppBskyActorProfile, - AppBskyActorStatus, - AppBskyFeedGenerator, - AppBskyFeedLike, - AppBskyFeedPost, - AppBskyFeedPostgate, - AppBskyFeedRepost, - AppBskyFeedThreadgate, - AppBskyGraphBlock, - AppBskyGraphFollow, - AppBskyGraphList, - AppBskyGraphListblock, - AppBskyGraphListitem, - AppBskyGraphStarterpack, - AppBskyGraphVerification, - AppBskyLabelerService, - ChatBskyActorDeclaration, -} from "@atcute/bluesky"; -import { - PubLeafletComment, - PubLeafletDocument, - PubLeafletGraphSubscription, - PubLeafletPublication, -} from "@atcute/leaflet"; -import { - ShTangledActorProfile, - ShTangledFeedStar, - ShTangledGraphFollow, - ShTangledKnot, - ShTangledKnotMember, - ShTangledPublicKey, - ShTangledRepo, - ShTangledRepoArtifact, - ShTangledRepoIssue, - ShTangledRepoIssueComment, - ShTangledRepoIssueState, - ShTangledRepoIssueStateClosed, - ShTangledRepoIssueStateOpen, - ShTangledRepoPull, - ShTangledRepoPullComment, - ShTangledRepoPullStatus, - ShTangledRepoPullStatusClosed, - ShTangledRepoPullStatusMerged, - ShTangledRepoPullStatusOpen, -} from "@atcute/tangled"; - -export const lexicons: Record = { - // Bluesky - "app.bsky.actor.profile": AppBskyActorProfile.mainSchema, - "app.bsky.actor.status": AppBskyActorStatus.mainSchema, - "app.bsky.feed.generator": AppBskyFeedGenerator.mainSchema, - "app.bsky.feed.like": AppBskyFeedLike.mainSchema, - "app.bsky.feed.post": AppBskyFeedPost.mainSchema, - "app.bsky.feed.postgate": AppBskyFeedPostgate.mainSchema, - "app.bsky.feed.repost": AppBskyFeedRepost.mainSchema, - "app.bsky.feed.threadgate": AppBskyFeedThreadgate.mainSchema, - "app.bsky.graph.block": AppBskyGraphBlock.mainSchema, - "app.bsky.graph.follow": AppBskyGraphFollow.mainSchema, - "app.bsky.graph.list": AppBskyGraphList.mainSchema, - "app.bsky.graph.listblock": AppBskyGraphListblock.mainSchema, - "app.bsky.graph.listitem": AppBskyGraphListitem.mainSchema, - "app.bsky.graph.starterpack": AppBskyGraphStarterpack.mainSchema, - "app.bsky.graph.verification": AppBskyGraphVerification.mainSchema, - "app.bsky.labeler.service": AppBskyLabelerService.mainSchema, - "chat.bsky.actor.declaration": ChatBskyActorDeclaration.mainSchema, - - // Tangled - "sh.tangled.actor.profile": ShTangledActorProfile.mainSchema, - "sh.tangled.feed.star": ShTangledFeedStar.mainSchema, - "sh.tangled.graph.follow": ShTangledGraphFollow.mainSchema, - "sh.tangled.knot.member": ShTangledKnotMember.mainSchema, - "sh.tangled.publicKey": ShTangledPublicKey.mainSchema, - "sh.tangled.repo": ShTangledRepo.mainSchema, - "sh.tangled.repo.artifact": ShTangledRepoArtifact.mainSchema, - "sh.tangled.repo.issue": ShTangledRepoIssue.mainSchema, - "sh.tangled.repo.issue.comment": ShTangledRepoIssueComment.mainSchema, - "sh.tangled.repo.issue.state": ShTangledRepoIssueState.mainSchema, - "sh.tangled.repo.issue.state.closed": ShTangledRepoIssueStateClosed.mainSchema, - "sh.tangled.repo.issue.state.open": ShTangledRepoIssueStateOpen.mainSchema, - "sh.tangled.repo.pull": ShTangledRepoPull.mainSchema, - "sh.tangled.repo.pull.comment": ShTangledRepoPullComment.mainSchema, - "sh.tangled.repo.pull.status": ShTangledRepoPullStatus.mainSchema, - "sh.tangled.repo.pull.status.closed": ShTangledRepoPullStatusClosed.mainSchema, - "sh.tangled.repo.pull.status.merged": ShTangledRepoPullStatusMerged.mainSchema, - "sh.tangled.repo.pull.status.open": ShTangledRepoPullStatusOpen.mainSchema, - "sh.tangled.knot": ShTangledKnot.mainSchema, - - // Leaflet - "pub.leaflet.comment": PubLeafletComment.mainSchema, - "pub.leaflet.document": PubLeafletDocument.mainSchema, - "pub.leaflet.graph.subscription": PubLeafletGraphSubscription.mainSchema, - "pub.leaflet.publication": PubLeafletPublication.mainSchema, -}; diff --git a/src/views/record.tsx b/src/views/record.tsx index dd01b23..d0a80c2 100644 --- a/src/views/record.tsx +++ b/src/views/record.tsx @@ -1,11 +1,19 @@ import { Client, CredentialManager } from "@atcute/client"; import { lexiconDoc } from "@atcute/lexicon-doc"; +import { RecordValidator } from "@atcute/lexicon-doc/validations"; import { ResolvedSchema } from "@atcute/lexicon-resolver"; -import { ActorIdentifier, is, Nsid, ResourceUri } from "@atcute/lexicons"; -import { AtprotoDid, Did } from "@atcute/lexicons/syntax"; +import { ActorIdentifier, Nsid } from "@atcute/lexicons"; +import { AtprotoDid, Did, isNsid } from "@atcute/lexicons/syntax"; import { verifyRecord } from "@atcute/repo"; import { A, useLocation, useNavigate, useParams } from "@solidjs/router"; -import { createResource, createSignal, ErrorBoundary, Show, Suspense } from "solid-js"; +import { + createEffect, + createResource, + createSignal, + ErrorBoundary, + Show, + Suspense, +} from "solid-js"; import { Backlinks } from "../components/backlinks.jsx"; import { Button } from "../components/button.jsx"; import { RecordEditor, setPlaceholder } from "../components/create.jsx"; @@ -25,14 +33,92 @@ import { addNotification, removeNotification } from "../components/notification. import Tooltip from "../components/tooltip.jsx"; import { resolveLexiconAuthority, resolveLexiconSchema, resolvePDS } from "../utils/api.js"; import { AtUri, uriTemplates } from "../utils/templates.js"; -import { lexicons } from "../utils/types/lexicons.js"; + +const extractRefs = (obj: any): Nsid[] => { + const refs: Set = new Set(); + + const traverse = (value: any) => { + if (!value || typeof value !== "object") return; + + if (value.type === "ref" && value.ref) { + const ref = value.ref; + if (!ref.startsWith("#")) { + const nsid = ref.split("#")[0]; + if (isNsid(nsid)) refs.add(nsid); + } + } + + if (value.type === "union" && Array.isArray(value.refs)) { + for (const ref of value.refs) { + if (!ref.startsWith("#")) { + const nsid = ref.split("#")[0]; + if (isNsid(nsid)) refs.add(nsid); + } + } + } + + if (Array.isArray(value)) value.forEach(traverse); + else Object.values(value).forEach(traverse); + }; + + traverse(obj); + return Array.from(refs) as Nsid[]; +}; + +const resolveAllLexicons = async ( + nsid: Nsid, + depth: number = 0, + resolved: Map = new Map(), + failed: Set = new Set(), + inFlight: Map> = new Map(), +): Promise<{ resolved: Map; failed: Set }> => { + if (depth >= 10) { + console.warn(`Maximum recursion depth reached for ${nsid}`); + return { resolved, failed }; + } + + if (resolved.has(nsid) || failed.has(nsid)) return { resolved, failed }; + + if (inFlight.has(nsid)) { + await inFlight.get(nsid); + return { resolved, failed }; + } + + const fetchPromise = (async () => { + try { + const authority = await resolveLexiconAuthority(nsid); + const schema = await resolveLexiconSchema(authority, nsid); + + resolved.set(nsid, schema.rawSchema); + + const refs = extractRefs(schema.rawSchema); + + if (refs.length > 0) { + await Promise.all( + refs.map((ref) => resolveAllLexicons(ref, depth + 1, resolved, failed, inFlight)), + ); + } + } catch (err) { + console.error(`Failed to resolve lexicon ${nsid}:`, err); + failed.add(nsid); + } finally { + inFlight.delete(nsid); + } + })(); + + inFlight.set(nsid, fetchPromise); + await fetchPromise; + + return { resolved, failed }; +}; export const RecordView = () => { const location = useLocation(); const navigate = useNavigate(); const params = useParams(); const [openDelete, setOpenDelete] = createSignal(false); - const [notice, setNotice] = createSignal(""); + const [verifyError, setVerifyError] = createSignal(""); + const [validationError, setValidationError] = createSignal(""); const [externalLink, setExternalLink] = createSignal< { label: string; link: string; icon?: string } | undefined >(); @@ -59,39 +145,55 @@ export const RecordView = () => { }); if (!res.ok) { setValidRecord(false); - setNotice(res.data.error); + setVerifyError(res.data.error); throw new Error(res.data.error); } setPlaceholder(res.data.value); setExternalLink(checkUri(res.data.uri, res.data.value)); resolveLexicon(params.collection as Nsid); - verify(res.data); return res.data; }; const [record, { refetch }] = createResource(fetchRecord); - const verify = async (record: { - uri: ResourceUri; - value: Record; - cid?: string | undefined; - }) => { + const validateSchema = async (record: Record) => { try { - if (params.collection && params.collection in lexicons) { - if (is(lexicons[params.collection], record.value)) setValidSchema(true); - else setValidSchema(false); - } else if (params.collection === "com.atproto.lexicon.schema") { + if (params.collection === "com.atproto.lexicon.schema") { setLexiconNotFound(false); - try { - lexiconDoc.parse(record.value, { mode: "passthrough" }); - setValidSchema(true); - } catch (e) { - console.error(e); + lexiconDoc.parse(record, { mode: "passthrough" }); + setValidSchema(true); + } else { + const { resolved, failed } = await resolveAllLexicons(params.collection as Nsid); + + if (failed.size > 0) { + console.error(`Failed to resolve ${failed.size} documents:`, Array.from(failed)); setValidSchema(false); + setValidationError( + `Unable to resolve lexicon documents: ${Array.from(failed).join(", ")}`, + ); + return; } + + const lexiconDocs = Object.fromEntries(resolved); + + const validator = new RecordValidator(lexiconDocs, params.collection as Nsid); + validator.parse({ + key: params.rkey ?? null, + object: record, + }); + + setValidSchema(true); } + } catch (err: any) { + console.error("Schema validation error:", err); + setValidSchema(false); + setValidationError(err.message || String(err)); + } + }; + const verifyRecordIntegrity = async () => { + try { const { ok, data } = await rpc.get("com.atproto.sync.getRecord", { params: { did: did as Did, @@ -111,12 +213,19 @@ export const RecordView = () => { setValidRecord(true); } catch (err: any) { - console.error(err); - setNotice(err.message); + console.error("Record verification error:", err); + setVerifyError(err.message); setValidRecord(false); } }; + createEffect(() => { + if (location.hash === "#info" && record()) { + if (validSchema() === undefined) validateSchema(record()!.value); + if (validRecord() === undefined) verifyRecordIntegrity(); + } + }); + const resolveLexicon = async (nsid: Nsid) => { try { const authority = await resolveLexiconAuthority(nsid); @@ -158,11 +267,7 @@ export const RecordView = () => { return template(parsedUri, record); }; - const RecordTab = (props: { - tab: "record" | "backlinks" | "info" | "schema"; - label: string; - error?: boolean; - }) => { + const RecordTab = (props: { tab: "record" | "backlinks" | "info" | "schema"; label: string }) => { const isActive = () => { if (!location.hash && props.tab === "record") return true; if (location.hash === `#${props.tab}`) return true; @@ -182,9 +287,6 @@ export const RecordView = () => { > {props.label} - - - ); }; @@ -197,7 +299,7 @@ export const RecordView = () => { - +
@@ -332,18 +434,26 @@ export const RecordView = () => { >
-
{notice()}
+
{verifyError()}
- +

Schema validation

- + +
{validationError()}
+
+
-- 2.49.1 From 38df6c0674f6e357d47673e34a0dd0c951dfe757 Mon Sep 17 00:00:00 2001 From: Juliet Date: Mon, 24 Nov 2025 01:55:19 +0000 Subject: [PATCH] revert local schema validation --- package.json | 2 + pnpm-lock.yaml | 22 +++++++++ src/utils/types/lexicons.ts | 94 +++++++++++++++++++++++++++++++++++++ src/views/record.tsx | 6 ++- 4 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 src/utils/types/lexicons.ts diff --git a/package.json b/package.json index 206af6d..be39515 100644 --- a/package.json +++ b/package.json @@ -28,11 +28,13 @@ "@atcute/did-plc": "^0.2.0", "@atcute/identity": "^1.1.3", "@atcute/identity-resolver": "^1.1.4", + "@atcute/leaflet": "^1.0.12", "@atcute/lexicon-doc": "^2.0.1", "@atcute/lexicon-resolver": "^0.1.4", "@atcute/lexicons": "^1.2.4", "@atcute/oauth-browser-client": "^2.0.1", "@atcute/repo": "^0.1.0", + "@atcute/tangled": "^1.0.12", "@atcute/tid": "^1.0.3", "@codemirror/commands": "^6.10.0", "@codemirror/lang-json": "^6.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index af63e94..6dc1e65 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,9 @@ importers: '@atcute/identity-resolver': specifier: ^1.1.4 version: 1.1.4(@atcute/identity@1.1.3) + '@atcute/leaflet': + specifier: ^1.0.12 + version: 1.0.12 '@atcute/lexicon-doc': specifier: ^2.0.1 version: 2.0.1 @@ -44,6 +47,9 @@ importers: '@atcute/repo': specifier: ^0.1.0 version: 0.1.0 + '@atcute/tangled': + specifier: ^1.0.12 + version: 1.0.12 '@atcute/tid': specifier: ^1.0.3 version: 1.0.3 @@ -161,6 +167,9 @@ packages: '@atcute/identity@1.1.3': resolution: {integrity: sha512-oIqPoI8TwWeQxvcLmFEZLdN2XdWcaLVtlm8pNk0E72As9HNzzD9pwKPrLr3rmTLRIoULPPFmq9iFNsTeCIU9ng==} + '@atcute/leaflet@1.0.12': + resolution: {integrity: sha512-T5laBTl8vwzy0eZXBy07IQSjsLqhbZmRJsffnNQ6XMSc+lnCZ/NHfuKy8TNJbDU6dc26Z7o5l0ELfWz5QESo+w==} + '@atcute/lexicon-doc@2.0.1': resolution: {integrity: sha512-yWgcBYkvifczVODZSgdVkIljzIfdh50t+QXjkDL/FSu2RP43NGBEZ5xfZqJcT68/UoyE+doSg0dhvOEIlVGU/A==} @@ -185,6 +194,9 @@ packages: '@atcute/repo@0.1.0': resolution: {integrity: sha512-INiYAuma8dydBu7cqd2WVpcXh3mzhIepYBUqFWAK5MqMulPRLTRCc/9GW3G9pxYrOdlvLCVamG2Jf8XK0nuFEw==} + '@atcute/tangled@1.0.12': + resolution: {integrity: sha512-JKA5sOhd8SLhDFhY+PKHqLLytQBBKSiwcaEzfYUJBeyfvqXFPNNAwvRbe3VST4IQ3izoOu3O0R9/b1mjL45UzA==} + '@atcute/tid@1.0.3': resolution: {integrity: sha512-wfMJx1IMdnu0CZgWl0uR4JO2s6PGT1YPhpytD4ZHzEYKKQVuqV6Eb/7vieaVo1eYNMp2FrY67FZObeR7utRl2w==} @@ -1758,6 +1770,11 @@ snapshots: '@atcute/lexicons': 1.2.4 '@badrap/valita': 0.4.6 + '@atcute/leaflet@1.0.12': + dependencies: + '@atcute/atproto': 3.1.9 + '@atcute/lexicons': 1.2.4 + '@atcute/lexicon-doc@2.0.1': dependencies: '@atcute/identity': 1.1.3 @@ -1810,6 +1827,11 @@ snapshots: '@atcute/mst': 0.1.0 '@atcute/uint8array': 1.0.5 + '@atcute/tangled@1.0.12': + dependencies: + '@atcute/atproto': 3.1.9 + '@atcute/lexicons': 1.2.4 + '@atcute/tid@1.0.3': {} '@atcute/uint8array@1.0.5': {} diff --git a/src/utils/types/lexicons.ts b/src/utils/types/lexicons.ts new file mode 100644 index 0000000..12b790b --- /dev/null +++ b/src/utils/types/lexicons.ts @@ -0,0 +1,94 @@ +import { + AppBskyActorProfile, + AppBskyActorStatus, + AppBskyFeedGenerator, + AppBskyFeedLike, + AppBskyFeedPost, + AppBskyFeedPostgate, + AppBskyFeedRepost, + AppBskyFeedThreadgate, + AppBskyGraphBlock, + AppBskyGraphFollow, + AppBskyGraphList, + AppBskyGraphListblock, + AppBskyGraphListitem, + AppBskyGraphStarterpack, + AppBskyGraphVerification, + AppBskyLabelerService, + ChatBskyActorDeclaration, +} from "@atcute/bluesky"; +import { + PubLeafletComment, + PubLeafletDocument, + PubLeafletGraphSubscription, + PubLeafletPublication, +} from "@atcute/leaflet"; +import { + ShTangledActorProfile, + ShTangledFeedStar, + ShTangledGraphFollow, + ShTangledKnot, + ShTangledKnotMember, + ShTangledPublicKey, + ShTangledRepo, + ShTangledRepoArtifact, + ShTangledRepoIssue, + ShTangledRepoIssueComment, + ShTangledRepoIssueState, + ShTangledRepoIssueStateClosed, + ShTangledRepoIssueStateOpen, + ShTangledRepoPull, + ShTangledRepoPullComment, + ShTangledRepoPullStatus, + ShTangledRepoPullStatusClosed, + ShTangledRepoPullStatusMerged, + ShTangledRepoPullStatusOpen, +} from "@atcute/tangled"; + +export const lexicons: Record = { + // Bluesky + "app.bsky.actor.profile": AppBskyActorProfile.mainSchema, + "app.bsky.actor.status": AppBskyActorStatus.mainSchema, + "app.bsky.feed.generator": AppBskyFeedGenerator.mainSchema, + "app.bsky.feed.like": AppBskyFeedLike.mainSchema, + "app.bsky.feed.post": AppBskyFeedPost.mainSchema, + "app.bsky.feed.postgate": AppBskyFeedPostgate.mainSchema, + "app.bsky.feed.repost": AppBskyFeedRepost.mainSchema, + "app.bsky.feed.threadgate": AppBskyFeedThreadgate.mainSchema, + "app.bsky.graph.block": AppBskyGraphBlock.mainSchema, + "app.bsky.graph.follow": AppBskyGraphFollow.mainSchema, + "app.bsky.graph.list": AppBskyGraphList.mainSchema, + "app.bsky.graph.listblock": AppBskyGraphListblock.mainSchema, + "app.bsky.graph.listitem": AppBskyGraphListitem.mainSchema, + "app.bsky.graph.starterpack": AppBskyGraphStarterpack.mainSchema, + "app.bsky.graph.verification": AppBskyGraphVerification.mainSchema, + "app.bsky.labeler.service": AppBskyLabelerService.mainSchema, + "chat.bsky.actor.declaration": ChatBskyActorDeclaration.mainSchema, + + // Tangled + "sh.tangled.actor.profile": ShTangledActorProfile.mainSchema, + "sh.tangled.feed.star": ShTangledFeedStar.mainSchema, + "sh.tangled.graph.follow": ShTangledGraphFollow.mainSchema, + "sh.tangled.knot.member": ShTangledKnotMember.mainSchema, + "sh.tangled.publicKey": ShTangledPublicKey.mainSchema, + "sh.tangled.repo": ShTangledRepo.mainSchema, + "sh.tangled.repo.artifact": ShTangledRepoArtifact.mainSchema, + "sh.tangled.repo.issue": ShTangledRepoIssue.mainSchema, + "sh.tangled.repo.issue.comment": ShTangledRepoIssueComment.mainSchema, + "sh.tangled.repo.issue.state": ShTangledRepoIssueState.mainSchema, + "sh.tangled.repo.issue.state.closed": ShTangledRepoIssueStateClosed.mainSchema, + "sh.tangled.repo.issue.state.open": ShTangledRepoIssueStateOpen.mainSchema, + "sh.tangled.repo.pull": ShTangledRepoPull.mainSchema, + "sh.tangled.repo.pull.comment": ShTangledRepoPullComment.mainSchema, + "sh.tangled.repo.pull.status": ShTangledRepoPullStatus.mainSchema, + "sh.tangled.repo.pull.status.closed": ShTangledRepoPullStatusClosed.mainSchema, + "sh.tangled.repo.pull.status.merged": ShTangledRepoPullStatusMerged.mainSchema, + "sh.tangled.repo.pull.status.open": ShTangledRepoPullStatusOpen.mainSchema, + "sh.tangled.knot": ShTangledKnot.mainSchema, + + // Leaflet + "pub.leaflet.comment": PubLeafletComment.mainSchema, + "pub.leaflet.document": PubLeafletDocument.mainSchema, + "pub.leaflet.graph.subscription": PubLeafletGraphSubscription.mainSchema, + "pub.leaflet.publication": PubLeafletPublication.mainSchema, +}; diff --git a/src/views/record.tsx b/src/views/record.tsx index d0a80c2..bdf9ef3 100644 --- a/src/views/record.tsx +++ b/src/views/record.tsx @@ -2,7 +2,7 @@ import { Client, CredentialManager } from "@atcute/client"; import { lexiconDoc } from "@atcute/lexicon-doc"; import { RecordValidator } from "@atcute/lexicon-doc/validations"; import { ResolvedSchema } from "@atcute/lexicon-resolver"; -import { ActorIdentifier, Nsid } from "@atcute/lexicons"; +import { ActorIdentifier, is, Nsid } from "@atcute/lexicons"; import { AtprotoDid, Did, isNsid } from "@atcute/lexicons/syntax"; import { verifyRecord } from "@atcute/repo"; import { A, useLocation, useNavigate, useParams } from "@solidjs/router"; @@ -33,6 +33,7 @@ import { addNotification, removeNotification } from "../components/notification. import Tooltip from "../components/tooltip.jsx"; import { resolveLexiconAuthority, resolveLexiconSchema, resolvePDS } from "../utils/api.js"; import { AtUri, uriTemplates } from "../utils/templates.js"; +import { lexicons } from "../utils/types/lexicons.js"; const extractRefs = (obj: any): Nsid[] => { const refs: Set = new Set(); @@ -163,6 +164,9 @@ export const RecordView = () => { setLexiconNotFound(false); lexiconDoc.parse(record, { mode: "passthrough" }); setValidSchema(true); + } else if (params.collection && params.collection in lexicons) { + if (is(lexicons[params.collection], record)) setValidSchema(true); + else setValidSchema(false); } else { const { resolved, failed } = await resolveAllLexicons(params.collection as Nsid); -- 2.49.1 From 381f3ed46c71a3cdf1b531471d51a48ae564ca19 Mon Sep 17 00:00:00 2001 From: Juliet Date: Mon, 24 Nov 2025 03:11:30 +0000 Subject: [PATCH] deduplicate lookups --- src/views/record.tsx | 91 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 6 deletions(-) diff --git a/src/views/record.tsx b/src/views/record.tsx index bdf9ef3..55d61db 100644 --- a/src/views/record.tsx +++ b/src/views/record.tsx @@ -1,7 +1,8 @@ import { Client, CredentialManager } from "@atcute/client"; +import { DidDocument, getPdsEndpoint } from "@atcute/identity"; import { lexiconDoc } from "@atcute/lexicon-doc"; import { RecordValidator } from "@atcute/lexicon-doc/validations"; -import { ResolvedSchema } from "@atcute/lexicon-resolver"; +import { FailedLexiconResolutionError, ResolvedSchema } from "@atcute/lexicon-resolver"; import { ActorIdentifier, is, Nsid } from "@atcute/lexicons"; import { AtprotoDid, Did, isNsid } from "@atcute/lexicons/syntax"; import { verifyRecord } from "@atcute/repo"; @@ -31,10 +32,75 @@ import { Modal } from "../components/modal.jsx"; import { pds } from "../components/navbar.jsx"; import { addNotification, removeNotification } from "../components/notification.jsx"; import Tooltip from "../components/tooltip.jsx"; -import { resolveLexiconAuthority, resolveLexiconSchema, resolvePDS } from "../utils/api.js"; +import { + didDocumentResolver, + resolveLexiconAuthority, + resolveLexiconSchema, + resolvePDS, +} from "../utils/api.js"; import { AtUri, uriTemplates } from "../utils/templates.js"; import { lexicons } from "../utils/types/lexicons.js"; +const authorityCache = new Map>(); +const documentCache = new Map>(); +const schemaCache = new Map>(); + +const getAuthoritySegment = (nsid: string): string => { + const segments = nsid.split("."); + return segments.slice(0, -1).join("."); +}; + +const resolveSchema = async (authority: AtprotoDid, nsid: Nsid): Promise => { + const cacheKey = `${authority}:${nsid}`; + + let cachedSchema = schemaCache.get(cacheKey); + if (cachedSchema) { + return cachedSchema; + } + + const schemaPromise = (async () => { + let didDocPromise = documentCache.get(authority); + if (!didDocPromise) { + didDocPromise = didDocumentResolver.resolve(authority); + documentCache.set(authority, didDocPromise); + } + + const didDocument = await didDocPromise; + + const pdsEndpoint = getPdsEndpoint(didDocument); + + if (!pdsEndpoint) { + throw new FailedLexiconResolutionError(nsid, { + cause: new TypeError(`no pds service in did document; did=${authority}`), + }); + } + + const rpc = new Client({ handler: new CredentialManager({ service: pdsEndpoint }) }); + const response = await rpc.get("com.atproto.repo.getRecord", { + params: { + repo: authority, + collection: "com.atproto.lexicon.schema", + rkey: nsid, + }, + }); + + if (!response.ok) { + throw new Error(`got http ${response.status}`); + } + + return response.data.value; + })(); + + schemaCache.set(cacheKey, schemaPromise); + + try { + return await schemaPromise; + } catch (err) { + schemaCache.delete(cacheKey); + throw err; + } +}; + const extractRefs = (obj: any): Nsid[] => { const refs: Set = new Set(); @@ -86,13 +152,21 @@ const resolveAllLexicons = async ( } const fetchPromise = (async () => { + let authority: AtprotoDid | undefined; + const authoritySegment = getAuthoritySegment(nsid); try { - const authority = await resolveLexiconAuthority(nsid); - const schema = await resolveLexiconSchema(authority, nsid); + let authorityPromise = authorityCache.get(authoritySegment); + if (!authorityPromise) { + authorityPromise = resolveLexiconAuthority(nsid); + authorityCache.set(authoritySegment, authorityPromise); + } + + authority = await authorityPromise; + const schema = await resolveSchema(authority, nsid); - resolved.set(nsid, schema.rawSchema); + resolved.set(nsid, schema); - const refs = extractRefs(schema.rawSchema); + const refs = extractRefs(schema); if (refs.length > 0) { await Promise.all( @@ -102,6 +176,10 @@ const resolveAllLexicons = async ( } catch (err) { console.error(`Failed to resolve lexicon ${nsid}:`, err); failed.add(nsid); + authorityCache.delete(authoritySegment); + if (authority) { + documentCache.delete(authority); + } } finally { inFlight.delete(nsid); } @@ -180,6 +258,7 @@ export const RecordView = () => { } const lexiconDocs = Object.fromEntries(resolved); + console.log(lexiconDocs); const validator = new RecordValidator(lexiconDocs, params.collection as Nsid); validator.parse({ -- 2.49.1 From 56735887bbdda40e700d10ac592ff78821e6d0f4 Mon Sep 17 00:00:00 2001 From: Juliet Date: Mon, 24 Nov 2025 13:23:28 +0000 Subject: [PATCH] update icons --- package.json | 2 +- pnpm-lock.yaml | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index be39515..4d00500 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "serve": "vite preview" }, "devDependencies": { - "@iconify-json/lucide": "^1.2.74", + "@iconify-json/lucide": "^1.2.75", "@iconify/tailwind4": "^1.1.0", "@tailwindcss/vite": "^4.1.17", "prettier": "^3.6.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6dc1e65..13dac1b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -94,8 +94,8 @@ importers: version: 1.9.10 devDependencies: '@iconify-json/lucide': - specifier: ^1.2.74 - version: 1.2.74 + specifier: ^1.2.75 + version: 1.2.75 '@iconify/tailwind4': specifier: ^1.1.0 version: 1.1.0(tailwindcss@4.1.17) @@ -634,8 +634,8 @@ packages: '@codemirror/view': ^6.0.0 '@lezer/highlight': ^1.0.0 - '@iconify-json/lucide@1.2.74': - resolution: {integrity: sha512-vDoGHcDZdWgUbt9J3TCJlxFzX/Mw0vUIAoZdkfI2mINOi1/cgVZHivgZ8QtiGlepskTL3PcG8t93Ky/vtQgXGA==} + '@iconify-json/lucide@1.2.75': + resolution: {integrity: sha512-sWBN0t/rTo1FxWG/46xKgkIcDerHpsjyNgMH48nvtC4/kUG88sFQXI+7mxX3SD8eSUaQQ2kS9C7ZKWm2DKgBlw==} '@iconify/tailwind4@1.1.0': resolution: {integrity: sha512-HqgAYtYk4eFtLvdYfhQrBRT9ohToh+VJJVhHtJ7B4Qhw+J+mRPvGC9Wr6Cgtb36YbIWqBxWuBaAUw9TE/8m2/w==} @@ -957,8 +957,8 @@ packages: solid-js: optional: true - baseline-browser-mapping@2.8.30: - resolution: {integrity: sha512-aTUKW4ptQhS64+v2d6IkPzymEzzhw+G0bA1g3uBRV3+ntkH+svttKseW5IOR4Ed6NUVKqnY7qT3dKvzQ7io4AA==} + baseline-browser-mapping@2.8.31: + resolution: {integrity: sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw==} hasBin: true boolbase@1.0.0: @@ -976,8 +976,8 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - caniuse-lite@1.0.30001756: - resolution: {integrity: sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A==} + caniuse-lite@1.0.30001757: + resolution: {integrity: sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==} cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} @@ -2170,7 +2170,7 @@ snapshots: '@codemirror/view': 6.38.8 '@lezer/highlight': 1.2.3 - '@iconify-json/lucide@1.2.74': + '@iconify-json/lucide@1.2.75': dependencies: '@iconify/types': 2.0.0 @@ -2474,14 +2474,14 @@ snapshots: optionalDependencies: solid-js: 1.9.10 - baseline-browser-mapping@2.8.30: {} + baseline-browser-mapping@2.8.31: {} boolbase@1.0.0: {} browserslist@4.28.0: dependencies: - baseline-browser-mapping: 2.8.30 - caniuse-lite: 1.0.30001756 + baseline-browser-mapping: 2.8.31 + caniuse-lite: 1.0.30001757 electron-to-chromium: 1.5.259 node-releases: 2.0.27 update-browserslist-db: 1.1.4(browserslist@4.28.0) @@ -2493,7 +2493,7 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 - caniuse-lite@1.0.30001756: {} + caniuse-lite@1.0.30001757: {} cheerio-select@2.1.0: dependencies: -- 2.49.1 From 80b949a44f6db976d018a7648e21f2070d0f441c Mon Sep 17 00:00:00 2001 From: Juliet Date: Mon, 24 Nov 2025 13:35:01 +0000 Subject: [PATCH] local validation --- src/views/record.tsx | 77 ++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/src/views/record.tsx b/src/views/record.tsx index 55d61db..d9a8a14 100644 --- a/src/views/record.tsx +++ b/src/views/record.tsx @@ -7,14 +7,7 @@ import { ActorIdentifier, is, Nsid } from "@atcute/lexicons"; import { AtprotoDid, Did, isNsid } from "@atcute/lexicons/syntax"; import { verifyRecord } from "@atcute/repo"; import { A, useLocation, useNavigate, useParams } from "@solidjs/router"; -import { - createEffect, - createResource, - createSignal, - ErrorBoundary, - Show, - Suspense, -} from "solid-js"; +import { createResource, createSignal, ErrorBoundary, Show, Suspense } from "solid-js"; import { Backlinks } from "../components/backlinks.jsx"; import { Button } from "../components/button.jsx"; import { RecordEditor, setPlaceholder } from "../components/create.jsx"; @@ -230,13 +223,15 @@ export const RecordView = () => { setPlaceholder(res.data.value); setExternalLink(checkUri(res.data.uri, res.data.value)); resolveLexicon(params.collection as Nsid); + verifyRecordIntegrity(); + validateLocalSchema(res.data.value); return res.data; }; const [record, { refetch }] = createResource(fetchRecord); - const validateSchema = async (record: Record) => { + const validateLocalSchema = async (record: Record) => { try { if (params.collection === "com.atproto.lexicon.schema") { setLexiconNotFound(false); @@ -245,29 +240,35 @@ export const RecordView = () => { } else if (params.collection && params.collection in lexicons) { if (is(lexicons[params.collection], record)) setValidSchema(true); else setValidSchema(false); - } else { - const { resolved, failed } = await resolveAllLexicons(params.collection as Nsid); - - if (failed.size > 0) { - console.error(`Failed to resolve ${failed.size} documents:`, Array.from(failed)); - setValidSchema(false); - setValidationError( - `Unable to resolve lexicon documents: ${Array.from(failed).join(", ")}`, - ); - return; - } - - const lexiconDocs = Object.fromEntries(resolved); - console.log(lexiconDocs); + } + } catch (err: any) { + console.error("Schema validation error:", err); + setValidSchema(false); + setValidationError(err.message || String(err)); + } + }; - const validator = new RecordValidator(lexiconDocs, params.collection as Nsid); - validator.parse({ - key: params.rkey ?? null, - object: record, - }); + const validateRemoteSchema = async (record: Record) => { + try { + const { resolved, failed } = await resolveAllLexicons(params.collection as Nsid); - setValidSchema(true); + if (failed.size > 0) { + console.error(`Failed to resolve ${failed.size} documents:`, Array.from(failed)); + setValidSchema(false); + setValidationError(`Unable to resolve lexicon documents: ${Array.from(failed).join(", ")}`); + return; } + + const lexiconDocs = Object.fromEntries(resolved); + console.log(lexiconDocs); + + const validator = new RecordValidator(lexiconDocs, params.collection as Nsid); + validator.parse({ + key: params.rkey ?? null, + object: record, + }); + + setValidSchema(true); } catch (err: any) { console.error("Schema validation error:", err); setValidSchema(false); @@ -302,13 +303,6 @@ export const RecordView = () => { } }; - createEffect(() => { - if (location.hash === "#info" && record()) { - if (validSchema() === undefined) validateSchema(record()!.value); - if (validRecord() === undefined) verifyRecordIntegrity(); - } - }); - const resolveLexicon = async (nsid: Nsid) => { try { const authority = await resolveLexiconAuthority(nsid); @@ -350,7 +344,11 @@ export const RecordView = () => { return template(parsedUri, record); }; - const RecordTab = (props: { tab: "record" | "backlinks" | "info" | "schema"; label: string }) => { + const RecordTab = (props: { + tab: "record" | "backlinks" | "info" | "schema"; + label: string; + error?: boolean; + }) => { const isActive = () => { if (!location.hash && props.tab === "record") return true; if (location.hash === `#${props.tab}`) return true; @@ -370,6 +368,9 @@ export const RecordView = () => { > {props.label} + + +
); }; @@ -382,7 +383,7 @@ export const RecordView = () => { - +
-- 2.49.1 From c08e4f19e3882e5d8433bb07a9b0f5f2965e8af3 Mon Sep 17 00:00:00 2001 From: Juliet Date: Mon, 24 Nov 2025 14:09:09 +0000 Subject: [PATCH] remote validation trigger --- src/views/record.tsx | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/views/record.tsx b/src/views/record.tsx index d9a8a14..8bd82bc 100644 --- a/src/views/record.tsx +++ b/src/views/record.tsx @@ -59,7 +59,6 @@ const resolveSchema = async (authority: AtprotoDid, nsid: Nsid): Promise { const [validSchema, setValidSchema] = createSignal(undefined); const [schema, setSchema] = createSignal(); const [lexiconNotFound, setLexiconNotFound] = createSignal(); + const [remoteValidation, setRemoteValidation] = createSignal(); const did = params.repo; let rpc: Client; @@ -250,6 +250,7 @@ export const RecordView = () => { const validateRemoteSchema = async (record: Record) => { try { + setRemoteValidation(true); const { resolved, failed } = await resolveAllLexicons(params.collection as Nsid); if (failed.size > 0) { @@ -274,6 +275,7 @@ export const RecordView = () => { setValidSchema(false); setValidationError(err.message || String(err)); } + setRemoteValidation(false); }; const verifyRecordIntegrity = async () => { @@ -518,7 +520,7 @@ export const RecordView = () => { >
-
{verifyError()}
+
{verifyError()}
@@ -530,12 +532,25 @@ export const RecordView = () => { "iconify lucide--check text-green-500 dark:text-green-400": validSchema() === true, "iconify lucide--x text-red-500 dark:text-red-400": validSchema() === false, - "iconify lucide--loader-circle animate-spin": validSchema() === undefined, + "iconify lucide--loader-circle animate-spin": + validSchema() === undefined && remoteValidation(), }} >
-
{validationError()}
+
{validationError()}
+
+ + -- 2.49.1